JVM (Java Virtual Machine) programavimo kalbos Kotlin apžvalga ir palyginimas su Java.
Kotlin vs Java
Turinys
- Kotlin programavimo kalba
- Overloaded methods
- FIlter usage collections
Kotlin vaizdinė medžiaga internete
- [https://www.youtube.com/watch?v=H_oGi8uuDpA&t=2s]
- [https://www.youtube.com/watch?v=sZWMPYIkNd8&t=3417]
https://www.youtube.com/watch?v=pjC8C1xid3k
Kotlin in Android [https://www.youtube.com/watch?v=fPzxfeDJDzY&t=4s]
https://medium.com/@dime.kotevski/kotlin-syntax-sugar-tips-a560035dd92a
Kotlin programavimo kalba
Kotlin funkcija Kotlin nesudėtingos funkcijos aprašomos vienu sakiniu nereikia “{….}” pvz:
fun sudeti(a: Int, b: Int) = a + b
Kotlin funkcija, kuri nieko negrąžina aprašoma taip:
fun zinute(tekstas: String): Unit{ // Pagal nutylėjimą grąžina Unit tipą (Unit neprivaloma rašyti).
println("Sveikas: $tekstas")
}
Kotlin kintamieji Kotlin turi tik šiuos kintamųjų aprašymo būdus val arba var žemiau pateikiami skirtumai:
val skaicius = 50 // reikšmė, kurios negalime keisti (angl. immutable)
var vardas = "Petras" // Vardą galėsime pakeisti bet kada (angl. mutable)
Kotlin data class Kotlin turi galimybę įgyvendinti duomenų klases vadinamas data class žemiau matysite kaip nesudėtingai galima aprašyti senąsias JAVA bean klases (POJO / POCO):
data class Studentas(val vardas: String, var amzius: Int)
Pastaba. data class negali būti paskelbtos abstrakčiomis klasėmės, taip pat negali būti galutinės (angl. sealed) arba vidinės (angl. inner). Sukūrus data class yra sugeneruojami šie metodai: get/set, toString, hashCode, copy metodai. Norint nukopijuoti reikšmę iš sukurto objekto egzemplioriaus pvz:
val petriukas = Studentas("Petriukas", 22)
val kitasPetriukas = petriukas.copy(amzius = 25)
println(kitasPetriukas) // Studentas(vardas=Petriukas, amzius=25)
Data Classes and Destructuring Declarations
Component functions generated for data classes enable their use in destructuring declarations:
val jane = User("Jane", 35)
val (name, age) = jane
println("$name, $age years of age") // prints "Jane, 35 years of age"
Standard Data Classes
The standard library provides Pair and Triple. In most cases, though, named data classes are a better design choice, because they make the code more readable by providing meaningful names for properties.
Overloaded methods
Overloaded metodai Java kalboje aprašomi kiekvienam atvejui turi skirtis parametrų skaičius arba perduodamas tipas pvz: turime tokią aibę metodų:
void metodas(){}
void metodas(int a){}
void metodas(double c){}
void metodas(int a, double c){}
void metodas(double c, int a){}
Kotlin kalboje šiek tiek paprasčiau kadangi yra įvedami įvardintieji parametrai (angl. named parameters) ir funkcijų parametrai gali turėti reikšmę pagal nutylėjimą (angl. by default) kas įgalina paprastesnį ir lankstesnį overloaded metodų aprašymą. Apžvelkime prieš tai aprašytą Java metodą realizuojant analogiškus metodus naudojant Kotlin programavimo kalbą. Kadangi Kotlin neturi metodų turi funkcijas tada galima aprašyti funkciją atitinkančią prieš tai aprašytuosius metodus Java kalboje.
fun metodas(a: Int = 0, c: Double = 0.0) { // Žymiai paprasčiau nereikia aprašyti visų įmanomų atvejų!!!
metodas()
metodas(10)
metodas(c = 33.9)
metodas(55, 22.9)
metodas(c = 22.8, a = 2)
}
Dar vienas pavyzdys palyginimui Java vs Kotlin aprašant overloaded metodus
package overloadedMethods;
public class OverloadedMethodJava {
void printMessage(String message){
System.out.printf("Message: %s\n", message);
}
void printMessage(String message, String prefix){
System.out.printf("Message: %s, Prefix: %s\n", message, prefix);
}
void printMessage(String message, String prefix, String suffix){
System.out.printf("Message: %s, Prefix: %s, Suffix: %s\n", message, prefix, suffix);
}
public static void main(String[] args) {
new OverloadedMethodJava().printMessage("Hello");
new OverloadedMethodJava().printMessage("Hello", "WithPRefix");
new OverloadedMethodJava().printMessage("Hello", "WithPRefix", "AndSuffix");
}
}
//--------------------------------------------Java-----------------------------------------------//
package overloadedMethods
class OverloadedMethodKotlin {
fun printMessage(message: String, prefix: String = "", suffix: String = "") {
println("$message $prefix $suffix")
}
}
fun main(args: Array<String>) {
val overloaded = OverloadedMethodKotlin() // Immutable readonly
overloaded.printMessage("Hi im Kotlin")
overloaded.printMessage("Hi im Kotlin", "with prefix")
overloaded.printMessage("Hi im Kotlin", "with prefix", "AndSuffix")
// Bet kokia tvarka pagal vardą parametro
overloaded.printMessage(prefix = "Hello im Prefix", message = "im Kotlin", suffix = "And Suffix")
//--------------------------------------------Kotlin-----------------------------------------------//
Kotlin Pairs ir Triples
fun grazinaPora(): Pair<String, String>{
return Pair("Kaire", "Desine")
}
fun init(){
val pora = grazinaPora()
println("Pirmas narys: ${pora.first}, Antras narys: ${pora.second}")
}
Išvedamas tekstas į ekraną:
Pirmas narys: Kaire, Antras narys: Desine.
Aiškumui įvesti galima pakeisti first, second,…, ir t.t. į savo sugalvotus pavadinimus pvz:
fun init(){
val pora = grazinaPora()
val (kaire_ranka, desine_ranka) = grazinaPora()
println("Pirmas narys: "+ kaire_ranka + ", Antras narys:" + desine_ranka)
println("Pirmas narys: ${pora.first}, Antras narys: ${pora.second}")
}
Jeigu reikšmė yra nesvarbi naudojant reikšmių pervadinimą (angl. destructuring declarations) galima pavadinti naudojant underscore:
val (_, kita_reiksme) = grazinaPora()
TypeAlias Kotlin
Jeigu naudosime šį typealias mes pakeičiame String į Int, gali būti situacija, kai reikia modifikuoti atgyvenusį kodą (angl. deprecated), kadangi pakeitus visur kompiliatorius pažymės raudonai tada galie nesunkiai pašalinti šį kodą arba pakeisti.
typealias String = Int
Conditions kotlin<TODO ————-> https://www.youtube.com/watch?v=YbF8Q8LxAJs
Extension funkcijos
Šios extension funkcijos yra labai patogios jeigu nusprendėte aprašyti naują funkciją jau egzistuojančioje klasėje. Nereikia papildomai sukurti klasės tada paveldėti ją ir galiausiai papildyti nauju metodu. Kotlin naudoja šią paprastą konstrukciją:
// Duomenų klasė Studentas
data class Studentas(val vardas: String, var amzius: Int)
// Esamom klasėm "Bet kuriai egzistuojančiai" galima papildyti naujomis funkcijomis pvz:
fun Studentas.suteiktiStipendija(){
println("Studentui suteikta stipendija")
}
// Klasė Studentas papildyta nauja funkcija tikrinam naujai sukurtą metodą.
fun extensionFunkcijosTestas(){
val stud = Studentas("Joniukas", 15)
stud.suteiktiStipendija()
}
Į ekraną bus išvedamas šis tekstas:
Studentui suteikta stipendija
Taip pat dar vienas pavyzdys turime String klasę, kuria papildysime nauju metodu pvz:
fun String.pasisveikinimas(){
println("Sveiki aš esu simbolių eilutė: (angl. String)")
}
fun extensionStringTestas(){
val testas = String()
testas.pasisveikinimas()
"bet_kokia_simboliu_eilute".pasisveikinimas()
}
Į ekraną bus išvedamas šis tekstas:
Sveiki aš esu simbolių eilutė: (angl. String)
Sveiki aš esu simbolių eilutė: (angl. String)
Funkcija skaičiuojanti faktorialą naudojant rekursiją.
Operatorių perkrovimas
Operatorių pekrovimas yra tik Kotlin kalboje panašumai lyginant su C++ kalba, kurioje taip pat yra galimybė naudoti perkrautuosius operatorius. Žemiau yra pateikiamas pavyzdys kaip galima panaudoti (plus (+)) operatorių norint susumuoti keletą skirtingų objektų pagal svorį:
package overloadedoperators
enum class MatavimoVnt(val svoris: Int){
KILOGRAMAS (1000),
GRAMAS (1),
TONA (1_000_000)
}
interface VaisiausSvoris{
fun svoris(): Int
}
class Pintine {
private val sarasas : MutableList<Vaisius> = mutableListOf()
fun idetiIpintine(vaisius: Vaisius) = sarasas.add(vaisius)
fun pasverti(matas: MatavimoVnt = MatavimoVnt.GRAMAS):Int {
return sarasas.sumBy { it -> it.svoris } / matas.svoris
}
}
// Perkrauto operatoriaus (angl. overloaded operator) aprašymas
open class Vaisius(val pavadinimas: String, var svoris: Int){
operator fun plus(vaisius: Vaisius) : Vaisius{
return Vaisius(pavadinimas, svoris + vaisius.svoris)
}
}
class Slyva(pavadinimas:String, svoris: Int):
Vaisius(pavadinimas, svoris), VaisiausSvoris{
override fun svoris(): Int = svoris
}
class Kriause(pavadinimas:String, svoris: Int):
Vaisius(pavadinimas, svoris), VaisiausSvoris{
override fun svoris(): Int = svoris
}
class Obuolys(pavadinimas: String, svoris: Int):
Vaisius(pavadinimas, svoris), VaisiausSvoris{
override fun svoris(): Int = svoris
}
fun main(args: Array<String>) {
val slyva = Slyva("Anašpet", 100)
val obuolys = Obuolys("Auksis", 300)
val kriause = Kriause("Aluona ", 350)
var rezultatas = slyva + obuolys + kriause
val pintine = Pintine()
for (i in 1..20000) {
pintine.idetiIpintine(slyva)
pintine.idetiIpintine(obuolys)
pintine.idetiIpintine(kriause)
}
println("Viso vaisių idėtų į pintinę: ${pintine.pasverti()} g")
println("Viso vaisių idėtų į pintinę: ${pintine.pasverti(MatavimoVnt.KILOGRAMAS)} kg")
println("Viso vaisių idėtų į pintinę: ${pintine.pasverti(MatavimoVnt.TONA)} t")
println("Viso vaisių naudojant overloaded operatorių (plus (+)): ${rezultatas.svoris} g")
}
Įvykdžius programą į ekraną išvestas tekstas:
Viso vaisių idėtų į pintinę: 15000000 g
Viso vaisių idėtų į pintinę: 15000 kg
Viso vaisių idėtų į pintinę: 15 t
Viso vaisių naudojant overloaded operatorių (plus (+)): 750 g
Sekantis pavyzdys iliūstruoja situacija kada naudojant įprastinį aprašymą BigDecimal klasės kodo skaitomumas suprastėja, šiai problemai išspręsti galima naudoti overloaded operatorius.
package overloadedoperators
import java.math.BigDecimal
import java.math.BigDecimal.ONE
class Algoritmas {
fun faktorialas(n: BigDecimal): BigDecimal {
return if (n <= BigDecimal(1)) ONE else faktorialas(n - BigDecimal(1)) * n
}
}
fun main(args: Array<String>) {
val fakt = Algoritmas()
println(fakt.faktorialas(BigDecimal(30_000)))
}
Įvykdžius šį kodą gausime Runtime klaidą kadangi tokio dydžio skaičiui reikia padidinti steką:
Exception in thread "main" java.lang.StackOverflowError
at java.base/java.math.BigDecimal.valueOf(BigDecimal.java:1221)
at java.base/java.math.BigDecimal.add(BigDecimal.java:4783)
at java.base/java.math.BigDecimal.add(BigDecimal.java:4790)
at java.base/java.math.BigDecimal.subtract(BigDecimal.java:1460)
at overloadedoperators.Algoritmas.faktorialas(Faktorialas.kt:7)
Naudojant overloaded parametrus turėsime tokią realizaciją taip pat pakeisime taip kad ištaisyti prieš tai įvykusią klaidą kotlin kalboje yra naudojamas žodis tailrec:
package overloadedoperators
import java.math.BigDecimal
import java.math.BigDecimal.ONE
class Algoritmas {
tailrec fun faktorialas(n: BigDecimal, result: BigDecimal = ONE): BigDecimal {
return if (n <= 1) result else faktorialas(n - 1, result * n)
}
}
operator fun BigDecimal.minus(n: Int) = this.minus(BigDecimal(n))
operator fun BigDecimal.compareTo(n: Int) = this.compareTo(BigDecimal(n))
fun main(args: Array<String>) {
val fakt = Algoritmas()
println(fakt.faktorialas(BigDecimal(30_000)))
}
Įvykdžius programą bus paskaičiuojamas 30 000 faktorialas:
2759537246219384599379942166425462783980762044529330985529635036800075868850360565832972977651204254341650306308369180105720079889211173647623998433383137184967254285857311222411266513704623208566663513843971255845392867767001593521229857671767859088377853025833179203708263155369841605042154936042598909075856430852044551518050502194448043519497955816834830283123674559621734939901731624301201076127184975016435078582758140749216748647309179050590022964374055780248416842708846029319703126114712880745936613672988328046011830192791442058031755785367028960875244284379669425722672437661447890883333680653460187556607310620760624863831955643060449770964294419715973902971319723229304227589444780515214690449430950100540415742367996932424440431797586214739669452308287884619723637082329610767856083429122271762367853165638037792200424897744323469601725987168135183985312129576055394803329361269420158952420732363750350565539555718824295251390720211981861850219790186408414398334712674366220695210737360395998180284449600983365056185334936767602233897332076408280766279313350100807738919044653247478399468118224790726891451537615976475772226646069039773112582261913601947079094800564569740187199237911957973532450123384325709303156034819289852972208081076808918657891225667861778617600382296342453736215067534260599130323659891950344375618821990241869064188779262616618897782064326939394164504330784425477057703856113642494573055800701398998963778523174197971199802001249037862845401178063635289215790294053130363790762505449659923749717341726603207883570408989458595454461800686388080985559933787580708157025423840642139204538772016958960796958234948680981716072726490931388029167387628397174251392411795142081474113071696284333816435410069606648559380559361648810036548685048376296802200885869157913750102085298869283891622993227015769198610551499443896668787522586657638366361861185065868789860262650393693681559020363377099448893771462053316082728402453902883282097471269671927157268145627710601852207513482942097037750095540240118995336906169072282548843691352328081773632006593071031108160921467428980082168422596457430312078666404161659045242247266415626039075905434725695033681187235461441433272106383854253863921330561679790688161084346854227861628470199065806040528878416365147012553488001510947290931349328921338036774993216385381137132198182213822826706462523411701372200962231508830152422410991359005334780791972234455111707614330060647186198186705417071806224684561386445865470294716932664992238954997164980668517505737006150434299401990047422843039374747072802773381568745666324627336927864070406780670472221250161486534876753369449034210816591499706079873555318837759000601217565989591615830088848172766037509272260198212866122962773193040992732475668744290293441563775508225765896179094443465134127259097828816940310527711661703122856916077848492797522352501849699613771129344721487000451117900504500494349754823393926598683738801230822884516230905466215234586470092767967075006718049873843332035209870911769570510201554488746659767340370907522192102092895807808154965844350552675323445758606329395240663588723844072582572320031778556109916134399989631719361246116537770937994210535764127053708470431360308218050214557421716655342719329280026514618978851803167515926270028131927132527415110748252482496668082753626428950993460432257165678631797482334755340819646080918594425560027617623243974643352853639236275249869486113167465238304038661944671638842461233130879726475202620476130723649447508982890926697739262100733274509067594085211947714973215422291475490714916601455749839677025731012969708328677416181824880040728195306146916808977011533263938748090400501428506732032622152245349347098909008871938509618096541446720070078266026253379783424065642817755760294130292731164883321355194077644660177987107292741142416702974557004421915363167190797385176561862204121856517547221477304556927478122535180183286364291033462980899893621900027788623821795890592436107415415305373085880206326669477743466164130977923094852333326319682063089795528774550545505584791628853502429309208124825659949873391297734080143486316644717408772461437969995993835587464337955514558243435657482243716228991540517959712884874727902965789744097366018405325130174626204543754719224173973805234914672668169226668749635597156291025160963857373913185612670898882470532508097415996917818395396029829662032566977197341987430481602278634162890641525874265189583806703824630201662804577242778124075688331933374597736089949258477998952385806671076650244897747606660754747659479608096469466792754887728256064795544622758948349598302469084048767397595801258861751089595262045036818541310761667126275320778503327298374574489336987797983677667493907774661985914885182876149913043326798472889532631816523248356892754275136357341654851840630907499657587091416720515228213584780954574487763071837820166784854744725552714512978440560092178814033869496037535303356045595346377277177015741028136402584921342581495299917608353731999136623192384861471343498386069148680679254115584795198815722864836145042759167289141951990324053676673793510435821860722219436652666000172254940500972611968190253250821417018303478060746861776006128050655579295517099133358731649683823475476934684468514076679976649073433685764375709709622794176256189057638363966446857528130934087922765134298894856716917846359651896153459392531445858811695273947551047244573695114577428142149069509146712150572945627477931220655762221313696187023140684608642699985354793714520286209733420553328173887145025974816839881131240297521051158160567748938789788758802191455026181966011373225632658077328260646368617522211273044340849728191262689904210443050685246518161881354611266819529235483529434559664820320856983086401447007106350786637899904670329501969941534324210415944632660266464710126890340439260493925477373257800886864064766079048739244939764992287363044019376942024124519168603146274184122368178503728613847583022913591636733801767638661942068926255034595860661829001983639193951988578011781357582563594096892210948705220648124681498117639466260804215967227335897324091208237256609968880276645881789856042939488921187481124837310807143899246987582176938447411227997165140375424840996946300964402244009242526058781232284932370012164511231516067396889680176125580418173622376177785996947162482153165293376402302271420347055180335094407447873048686059015160426357880447350679938179199740580090456440213429977642222773094060569567199217828516824001277568454356890787288455562278512474152545148238839139764446839855053352949395051652363529328098463086571991361180883734715062509963494119661604168657243195142281209795853639391331162127257222017387126045704630915314148944244879192223292318051373390846420413066423694128229850953416749768560198103035606997015176797652610446388363526403223111037197720159901992145577044202898053165473361503302108448802593579157450954536592497616371569867181816844046653050574854017025169513119226089778719104160047637648736726327993147684410796366208717313476650003714337566259825501422654938230299980917331590085034007138170874237835271071635943992277598308121453421252376776384649309500993134942184002196806037759858729344038127504045786025509817903804238600858800790156763764485275734428215185111362823330793745547771206452888212147444008759991038667771775718269774221890895879572773716774106962133288736490064511177840954974998606471040305374534594725231213270134997187231427488632090317730111810010480810652455084971202554049671586863726425678898128503276574558351760964654484611660737164742502990345366126536815488223471212607045941742389344186626779728658447604257988064984655557642326458241752935530776596352103967089074369819398440203799593696114867790791311946530092563257032840251597684047607534358897929622425991749525165009478239916042202561210505859915558618533349717811688407377311417027283349800487859035260337831435238430690163301746276913178845343078402141465275336293744443768217157615249358113663127757649580944883286315545169772145205573291876312988939517067504290714508152842442862065995492424044291216038036745275500608507809109504221853305667104371658415174442201910136140122520825895616900052543814764854502151445422324277283111351571232946163407906558917558416730066882161686822334168531646944063567712870201071389740884508726701373359034939613896515662545142457610663248403964843575044099896921525697010610685790729977711241207776818776243600939456518045584414785134879887113116429451133939466907236800167365839661711005112302393659871844095497482017192949256329192117259793916668582476274987463498441803243429741282437915623833584378934785067510573512131379619919114558000121608504816718785985195615280015428914733353645346536743638194128534189666483589138748395287519928691873621777908530106254667991491428112844932153330266102923556133039298453418134600710924911355071983822154150442654455532800945860240243575523175481436145770676875031448526922412435022420228049218576227173768659352816205692361857505610389794412692854743141732031003269115737079232192473214969291861155306317584381440655650366340042885669189015645165901996036099236972419605502542394690593088432855390380812108475610230831010682342177392452613519700855529628610560254533611685422064855169055210868433101695363156895912925788676596821106947472657341361372046326179692815562498280584729011925936915225491569960621408889374016692647292671055384739385971465204147001700848293655167357770636548614594016098550048638216917223701260329366030011089147984705017640597137503114123688287629997150429744575662692569580187592483159213967229923961804306568620474724623109597195965598319735439124367590341139879346584587823300219156653757353929233809531732213144959282416639313991395337222826206119303994947170873990414105559885480293914184762446590390895844772911505986237541950291055518850779435640018165290792689416767943607934824193294085301354655465463266062515413695981709944310811894176914931532531250241486519889513515190368746365154212266832954534163415334943137431151011826501097080819338137621026198467066500482203018146746260316172570429613140622391528174733637508849469363485715563827598231697761689051918780482175981636882228294697450441186152186110899743107624043921251923306925532822246690131830061355676341402128253696011468886689249925118925683684613236638592631824281375238958471522696104420796328692419708142773750053435837660425247690732391747593512345343496002032417154533279243904877446254751989853847289397289422836940841053257165593607400282198117681187170762513159625154774903325173914592298036428472525310403631037807684550987167086158724629077662830798494409073903117355973887186927913065060551614141386038122713835671388628260249603713722461186677216678665968533498698534558678105489444185428397066557023714447042325434790336687777442890975993225288201666041199030760247322754243570419223271678468081262973792999339881578729975763148710256823847647237796047221627688928254546304206407437874000597890056265260148420765439715106346725760531098217621385715712851996685018943429638870424761277267802249299818225060878945849994264756810867569891556615433237740935715452894967506851398893834493126374373306235473744622569532319738741427567294471855973580841769412670448337935229067349892337130363738760177147127387902332293065828548159220457653333705901404830806050001089006807102663201918182006420280131805448022464557828315082835969778760978122234746756619930139181891549100886037666897639420494732724296959439188698165351804529173000599275819023938013628810303744261484259542490884016785478576807798792233765045100637777536569222241152076340251091111013594212631457394776999128210085560606926010838984031818809588854944113226345462798482146994062514651409287551514128254565220434816653736388479544986927868163894980599880131656641227559906513365522735739330564486725879568753401968137382402852592108139725989653856612136409553626538115532921965963501390097089325909877444251612951760113020888129373295950547319888201246177749340916466781234369459508497137444313547268006327918498701048218105399144077820044891656008052884310951562490017969306064809210008985756288997896191318471696128913008671654997688694770046450254730318149222683216984857185192642271675584316728049303448002707931633794637066841812408294360568174096172616810405896026261503681322998358438925009522327597740871535865817334210773930606100529815095736770222673635863599698919395808070281156709976756632100534520844873094840902210495293468481616349779636059739718728410646009855986962404275208171157390869350857908101863745425428846058522605294334725939382024390430125304265154976330234093703281300124510758767551839534039234888236166643830100110437593126998757422681032774414643540123367605482988942784776294889254980279417717385538069507257679524776163859117697135350613077849539980661488080381039653174672571520786567585996993722219893039224432200141775190201905960468017680468262617680969314702889512648874280417123352035427480904750708590616790274703272941102048381605063979777122931667018172536549147668978610939594396736112758798557241881949953753181664416196707496409809484986446952346636125966926993460271307200230698685547488097830375871920810493159684622943770140896189772131540921962247131942664669561134766571879031919541963307182718138591320645612440108688178833166166935006637195303296398745687745372835050820983209694222514735285290318326521213983198762735820868833617702983065714377829008220344522050799855212493924304271465377593310486841655869622933027594847618407294966030049510987948256080169814531156021972482465953507460978348639926716307626330476090516089019776359160754118726034290422470554038254530165173229142577494876503954060925228781356856071780060307805150399720282590270963175428688822023971795915384147745175271962941536850691377479154081931998843326853856300881836057595888773862431060968264468129211952296519341752446661411008215906150636321010699909679394212823880377875714796373569576577896511727870789881261791374172079498694234460975787523399892020532242894091935173833091452257854849191390199427277172030164046405679630844291044534867940076335102569077182642847507957880705020141551327956578983736892278447560367501788004374548560368898337448420921548051117772805611826965200389302255871625744404932119746310259644974622203763934911442710254076002936059614437297294295731643207134892859927571744925909957973279877369935088968166944300647071159848204874476950145941401335305735067306235761964676474443332275160309457486465978046136524535841401777369339142720227497558974896093608437545751852468146922217677615478392618774936019063178932428198439212500601155396847178452216575163209903695161970926264964813519333853867263659969475770131127452585145933021665198253432386350606739358875729457389298569483250975048261638005769893335048412511606462754375687493576968455943615201746171430726332019878603445090326963290404254950304125358328642436030553323845347571426149671533270399060132588042486475337397894960394227675894662890837447542279451007782394225716682807423400913766078884612967209804375724236023029617525218383448565657526159806791583553950282397226366004564279872529611492868363906014376469161160815786103124453897762232189443746726907736077641230258809288286355783979273156381358029047996317146312049414890889840908196289641795437282218275055313069060836787783169555480614681988605073988380827897058467334117147160649939354474763625723637892054689283775683548021716426125392627085206456940242114939664577251141953888593200211438383327344300245712458085091921497899216010164881556671416979927538770985251390937437741987544438193071286435637754439251264447963967088295334532916772985684520380559015745297576651298671287845637949305686558900993807151877131261194533475715837083887522103095921927751608278456109892771166180488857266282486328453316438362648274981995690442731974185679986260138214804516861416164094677781356507324201241846394212270437589845077622597368715489917850590916359522084026173918108029289810167244822325667491430114981909711503263317084902109298255679124059390252956720641418490140163606030037514524568137075529826195267109826685063773819684532340196135098369693670888855237984779679683387012929445853023450426194933139974812805374742531773834214009951590007488158554330686984724973591906495034573276417585711602801158220398748725481198144599922869689714362475960147412656681684261590409911631067324408562990947317471379536681534142962747210687025416603621391861771382201364968414373811666738333307935888760373363512107469396871290425002695732862058532602509622723582681215504099874433552932292452796024972043491472464483345697482318269872713748649634055146188004436380347648225352073166272467032164610081867098577473021897204142156024378134655105207135773410645637940843764162681393318254203312971481073879680796784325990081838163245986240877152674638898570655270729128033312980159634695524522510418489359809957956214964889181981072089019492460775310339528837638843968860284392514870398714367182444678394150595032264716881630211881261548836018381243806497480600976039311539680004947274378461603803327085115428880836358436393217208914661044646023261368624097791976217658049016038333847403443549639678882908802143303865166974362964835720868074600119792306331906630962168626512587528932198025007427493333517988574674170379448447226774355058277478583417074025746275640457936566586350336589958664125830350664468227480398662237658530367973802265608781093201881135569435202428161301957947445005313200464772429749913087135903330390577919078187732331301569512077638983173179757890466564455075054769903348485530855583359386029709001203135284837586115212766098529500418498312492786049068998057708883147136551830812328487350290685900511995115098126959731795823545431178368517761330620714508987580650343415391623796242525831923219746085757127312926911995398724328485577644284400913344593620717215909955973791106520251451657613049233857691383699000297616489834876688711243530051434051886364732028922669249490814716964037273255658535105311976509610286732855752569475995907620483340043041110417830393214415301981391216407329937641672446670291477018755885224453642032252619999952100868942437016632748350756958116405551271814010676815418136086249046045324376489057688205300639366611227445123852123391803936173775968706004999286104619101998929379351808642596155827480200590725351700750260125701557244967506026122102340504851840052032500842860951474603276301206797048630950702383825179889480301744025063799852157852472967582293324390095006915405373410125498744833002531794486848232110427481822008277628368812083921144000652558494610651472965202100144512297459992886612918146257203272990443328929184753429486816003058640696072803486150031481173594942128474682503690020268203055973594382432715576485402381833748705355606513626453045619977768264993024643753114279116974798858499226941623634309627339037345489333028482620901467000755432276596920703402108058527656195683693739015119132321824689773712871771881000848084113783802841558235877688821144900419843352163746487929591251215533217080032244905551100555448047080679821439117988307818235646078767264541516459459725854428438819237338338029360003258215438591446515713071476120671303760860635992385295473818260618969530220660002159649682406215852373864620944461384905312351037426140928838702871178191131753374002300205169495849707322582257458320278242351974186163145808551615193892064014547663080798779518680462327285792753482269888676526424582247248938143875369406346098267526112552994971492256976539995672972302393044002293997797510489362623556669170820904763462038196054408268267917087529025639162105591093304379846869564762213317956738396499708838763349771481968881085126891176224217713321959489482143709246112625350740196991293547847140773397051213473098555778851957506695520357316349559687987711866113588408328710137456950268705780490433407024553627926097975547785670377516546034469766802405552045948830061753002792173856763841883127742160755286343494773061600344068323573084778634676369296824333682641955607228186871229578212479613305121454245306559982729219831038227532374511342033056504293852396991557917650659288718736619503259447282143631326730180722086726669223494435435968625372268645377242597379979269387374781582809242024316711245288463247104525901517704021379158375018126326599172135644059985077340490509480519970499652048441641168880796915260888588391170214934196599198477314111269677619993563978216901847883791527461150500038791708040172670072466005353669729835381090310751848271355883169099547449253456919346841393184497062113165224982678982568714507371035266926121097745623324160543356703259304787979729447512079745972142927998016830786129393447107556232632073286431077467551738535496335049089884265673160065837236807450094394569685772414291808925861581132286389556636543967856899316540847339391522285252832932166172230147466758418613686422506980125096981854662014330718617700050100046813478999664091463670660631052556876432067177766863658672867585447809930136161646273907430969107660070886849923403756877909833953015940561959315480642148784153967923492861922107076212639455932563009810279241325306085076920043870988498271496909016109023309674032026788539471043130869345726458871247504225809171674018356104468442074703216333541604921650186438062346443651716009903345278008452323543279348681779018695005696701155320321689264068253767167489007669357128278434140173615359841618957802152895966957154299963034072410639717973216264805293461110538271280289670921182648552618266707597200181258431217218588162301908621731863248788794936889535069041557793291859563576121861752736898794647135034285952041606793521429547678384352965994137016057386564711632909187962934847602564616560708986296760216059126898882643064851935899412269546866952005902519317988311693265052737870856471432638145638317073344938927004333675858946918228751604101542701789994405940389513584944985801753743151782179114380956926908791444982558655305828139653201172099360496327964684465451976879122067689836568035531332173766048984893836234097505454211213815732936278167878458678004481064729836085053369201153743388421787526764529810624473466196564419624519911774824604945986161846294802621937454935023520384551143629383526329894619888067310553612709102054223338857342547416580928500120810912949320214333162138318780795532319439167569561362441757230861532980183691947233007133522685804529692566001996367271910704163979218653384143648081526571150726390098405121198067222751206346635588402479390687672696369807826000713046194388778739710591636615392805913158913659479381498997840269530431579487453129637395761459867093089587221732517049872479435125362582193572163991463446163307922955662658188163974916496261569542563655687161773332909144760110217022733920430230579159927608552099360452313867675084800424167238207122272905503959936170220143921516970577332545967834467320849863896694411144500084371520913196188903451808202882319928993456721610325881844178445904581960125687695614824123722261275359511637722511149705053818272754320622272640384473759364261333343726715781426613147932356174785767855668481632431626203629208318480116238481681127169957292677709895429059200493171340738391241067296292900721856666796973791847387543288094607162873614562115657952288758448229402843343461748519311147482197293021180769002457405208968766074678418024681923634078887875649673617897857030874488006491612611000558749117913817203491938615035194722708606804085288411419865302054984860366705401360054359327144603752585984061900439347917265097508997175278050755093537874622223319787412699552742654161683046290525439317972079936371679905472449608507532556855870754192049766485095869921289311399175269861857830420969430631947813343131839557786788480901118923913319556690565287537382542801435536619947213755217384669689097874633695614067588229730075794905528732328423750758561031983735896827891483137630931193174992254815237078114910663127333536486007886289547474733370606762858367410943987821873513658934670363955943940676966677808727859186004992463803156001619473922312489887206104441577823572701237195321535646747910474564247897916022556328259190489081576418528073928829518933368916657002127945285781385000102272862234526565094698710646662183041633714931665168849960776250676885875844164067168049408034831748079580825600771971642933404585153110637762303182183809443996840204238055591738337111500459049254855463877996877399900505041613670774047074032756117944961722247608019783670896160519115228091678560150908918027517143972429864186543895907271851099179255981925905884360794264222178497985049008823985759129272136956452492327723654592810246328759236420555723146691712379896904152190835964646391866963591075676038219608980657325481720491014393294778514959193627215054564830057174076554228406525644932084776809569757214894166798476905646596290489685162589335972538504712792718180358226800755176547584194710529336720308626888522672021395734185405111783614895812839947135871017700109974055282097703214267963374252561401495731606746358491573403843320259661409797760614716241404652464282706843636441760657131498490838165513159284274803505302250823136881665890545809780027822081010651507725057227626883182003106196692182790161142486925359320620238913379294382806717323390320340974241256382679277799545124341133492055119309978484612544802768383966638265626371108812508445455347783838203269615994695051169180231569845053398386698354856141960275574918592661477911181199898723791297196020410769345979644008728051735363413998611373645917298130971927828067296675838832687064709135326723487576489135058008869027598448916484226350321140257442019279783187313563115645037217515608718934749803346168790715339429215453492273263475181172058181631059293585187827624269517480560922402852251972194726172308179464022123534375564405741037277030858277115370749032936504725793669894393190873829739974367278697376222279098012898891675851784093265116829279587521550158074462985234710579067825033096370147971653939686196180843960955468488595991812444702218261909872459654277281611127223254124453436775483131278338772532059304966299488818989175770709885688271946348352904092982462171578445176078024656978930266246469733706005639003511517766707242819611134131741504927996474389076694627189456928331593583634523539693752121134742852584157879711422324060790114917217939368427334504059700543554294636869612333914925887943742478021189097827261331060108342136616136048770762744625661520223979198915466500635213267357787139244319853344566755768862996245555011339956340067516937767172775857554664551505128898659282865938057768792893079543488685616148423521222205067945695496210632958014036493347743781550014245515637619019759048706993255776973275952392944380481062822137590338168465081743359056805341534018824849251058124824948037219876751438110114213988781281988254683884402511066902206731573721590484775735351518921687125223944382361763720085946406777676006369719702563663301721514957648870615002975783391671025786690072596927387077516109364345477633302991531498501808162810701445549872920496921766933656105692690109787990295501468048752451404893594044095345826955999879667267878552164963481563431501642685433676848194285010745731700257733768843768469699608175745147358903353575588333111508352778882978285932791518014643581201214527335280909190403555915457775945919488946027965700644216699472190251136837121332226988132069440164589877599140378532109969582282637135393107136862803056023692224811183895882942009971556169624634380456841630542171086884620340369803064520667321234510081752519991430736021759089154739505140994753124779535707417719271094719851330097977152449175800805885455893461460749324179349982330573208926842820295767288852559458925080561352996445224222342137540225118777409218505014846318907813460171293663220927988210455487935727385495159485168196560846910328135705395172740280617389330400117694256763204979590449056531564994182144000790353946057320461519090200290302134434736294590553599549955507372483929497937058329020978125394115455063685181569985703484174135237157504722464652706376389820536784472084125831682938790341247895141151672727484116775162421127605725256363514592363037530427871476280785422663153021642770826649382569229104841190696089169905121216176048160601924130928900658521992894758809960683762097184185731432265517745433665786081083040786593989343878721542770489804439480992390164188750094711443138335987990045105919957281344897496480787142123377672708840151474003564837562002726368508101301049771906830634597161128939181464333840045027612587531067410089271137825718099548653534162885531889204385078973745669838185137100058544954159562661176026985171216313030396784820208340259978074022088037850806775270578245958440508763648862221578230647250732649780980748497062560230587508338961601379240570534493618876652528009881260930064083043787380694860732769596661809147983643568283229748199915323129911796781800605222099503652562333107725047897695987494537409670235444402573505332995458515506300466492705642952696418401529403063137963034641743102864356826962722259486207361721840644460311594561680847980838438097708683379120034286290634109210241436381837109822716920252168173032862139396378403629268827475931865095956016054610045612368159998500522607981825194191667504449585120092441584115198213350673623609093065346633295682100405322276122780676286719772909722668744315549743622107098120430198050945345091009966558993043609026500737985316712599195872422274792574125119871313530497060009720247521500755645262469238603148335907635687489255525818414848728258321530554996063755164776626110425936985311651832354671445003775939498332555880425392910630626936370226948189389863212412070037853301873013898682823149881519776114052536859404999018069456277538891734281324642755503819442753869817505227690332583324432329396406861576164000818143076707031138099160318343212824285141504087028040761368614167581886217448525091546398008169180795200794314907276412022460353677864669368794457977918449959127624393673764961045833487706566055088982052833978637251341102983411381973602960164296750830778973639458153808547420447579992247073781981324465298481215584812572110765992354386576867923942165095011493374982470889753948701631693891919331902833644967029606472878519547712235856647293098458333889027820379414490980108007305754622509849251261483634712815954299707663243194999155236784703261625570529477833484304247544727078725545857483181748846598428044333476317366583518494210726314203824314048684630874933555740442910178863815680419191103468445583067970018166938192813336518238381382985813817887441090414537594415262758948378469761375058929399226925003142855622353965065654759229551392015442680883091447408062639527131010882739640958534909970369958121212051751861365390425390977405141564545677001283129175612804100839420687230295967322810608840814480599385473132723340502046855432860619752484420157909017604601097374771522688338578193024531607985697261849417390202179698410913079789370901879494684158776399903442725053675489744723795863844104556914621343289102147659263700784445652183472406825225126582788405103602861992688926930928721679012916115029677504981270232539020119201670393695703566072315996099569598299404492058530442668750872828677511774070013077064900569191127878188760939704902825128023774668236474813808584822943585174548504982253707361586066114723799505503825998014875102939164339658578267902043226779708433462783491895954620955794345322053979211309094252962474863493830405354986889750396122392365432164978887472031863135391711850467309939702585573185129025811667204061696787784561083585429255550377622495421590247810452787588559106157609084047058310947621532417880715244565791227249649850183190649582111126919895071214333992636715538078270016263093365706751754338894605465049443552618875802308346713847139580209047907374031477527921477218968802737711071512672785937053155394063138472845360734661014620566749699959610546456720325747008737569748877573220494494188124900659245044646526532618463236680360590082076622053195291721278093015470926736485600367038430330852074572247846446160130750787138630788409660876254557284197115302817137335478010635991740831443115010112142107568300849468544040819320451469038192348845842173080111708840898614365811151975546170015653613277083005707757824426344629378195702795398804224006939629408425403943866813215187053883602773193666412429047480682917665809296259133533216573066569427778481866455940293836512026939535104104583207280322943188036533504980470901519020217325504855457213787014763984831212855981831555130037387117469756732821810245693235220821606258252836497037291124245633425044775809947957867688452077478306795118546474632736929022853091588931651897099222452485406097926805053086620561287753939469542010424290052534421090784991700149897870564979744878904465211051144709571787549710111540442601979343737134476260952792027826183509687141633947595938553164948979069169828248046429779458604563349537267825400708804300564817566744964501523715134377571371896238245852513640208638132642647859405722315997044952235488005544805539843879632747218297881041258120999173356383499932374197355243243185723044688739667746891668771835748001966643195851240258278546713130440373039958379386051214425440745832300139726938493436389393742311440334629564200218014947820632881319201406104516646317739454184623468626567631978825679227144983926608438947813884833259136274422620598898869968334451610152671898544630306302989131231337757421975534974206337980007217728187261405106016678858647692044744268970028978680190075061187893941030748571543523308976996596634364945692526464052066684129656838834382787158085764579506354947166999515819226618162610274511680826020769075719338786471669244390190963643524190008087571759444780549895609171173981155220358935976481712991113549976217853766710427753937765185282142353750073809844802799913337797640983827595050734161213869399407254855943402243287813661920021906455652943532051180969604772864272929244607697386248627259099419018619115513394480221710408186442586781449552370448328522957630679276000352866762630219215246873855010694786025872471765328587346851148136974023165442067940537031222371070455315022663069654266588864293355555737796229129255302204504387627402583858392061732642267010977919651077426876630953531742623591504785024069353238664086100535428919496140736477426023691625757844384724892488018236313782199864455416384179910240561427500503458968984265517378397002809686211166411633366321201154915765801011650996276615793344795550553409071079013871351086904929157430178315096635985935809256135967415019486663221984461899407534343722685164081950887987732915776820145590816236892300289755936188458915730098413870604589631780278394458026658042611499452014620047860068976623953642542835989391736361042374261911676639238523673315791854845166351802492471092061438063769878959403646335991502360951963307745003210931817514077362626733326631035456000229144483170563638387023880950611427998211968171346406214719926562489701640625274655100369777572218779929105843249760756744780199494729951703856485990502292209745604382501210345767784309307928316321660110943234549147589827552616803071969067709101696924122249497308744142588803951505163635895184007669498184852327914377085701496078465325069775767248003657865184307900134490993345524685637699636342470370788101590881713107623839734680398785947576572133764179393179452353413743488469543441709844227107224818270609839645031740351496694486207766638724627739295575919643900064146791296939101314338806407297657084596676275956638902494068316859582289282950462328646858217057683761294367461486851109184752101166831173551375159211018036025314125624284922411534564665535870313034831128759660456722903415076454419141810720132285825017543445358030078617297273699068680606665871841486205524804806439473524621777714872786019779647290218794940541698355659963865664142684073717311875616188818179751005455041549789947206922154893604476034468261937771471342635016321908741360919312425689246433700212499927651640890731198313475428379442534097319066116790868367206567827556876863593340507580361250590136726033221754712162518062661618146233055832116324094143317180406576819411332059354163322874513288540508800605968722762072856171965926005818546701565061440582522052576941132717641465246372106683108069455043109318239568101095317132826434489618963538264857650872007084019033468037566428371696745572913812484487531295943734309512927454684372565215187231419651421477535027175791172057976375861646644290240280667474452790970626404307162834692218485235385415226833737229171428186359744050575638350890195438507168073903603293776244881032784099626075908459322416934448076642961410789394043669969728642413298564358395224036145027731462156527664475399840392107084007413176304974948932506769017139423239413733933733911250451410422301399391245527669508240743379374168219821955635230732458993930776272469418351797331418612695336285016017976852710577194345436273383241443211087395544182917728999235937856166139520237997914183395571789834790030685861765259007593160049056621436457153339950028837594307817572967084362668607881279772290881212746038794017119034943462215238639059120723556052121231265192401268726363870351228479307112805137047223043209065205489364942294063747577022957444053616715156570941264686202891876944876166419554118548515340153064020563222601076883726057176352143782850005050791766058084876984856361228248103837078172259987764293715168443743187595405000564510643283319806602093017983168003954923975330054455468328390583535775336357191140087585821459774017500501368579621021805708585425717420300216667445353228014747826046300881765740157518913279182459505413105462171119956653900434920119404860091259924193719561440099337905217370977300697074744785978661177885451745999565793802855259229814021138750683072208740526449603556662312485509251956720156697963884710204948617040935064341980126271335415779268646474318943097199327323298449805827793640103289341482907714373187689522824036320257458955694596509424316802922727590901573280141863393679105900027389607555038985587198480992248429632908674058501421146543130473266048756245133261965754597568774962141135807811265751539225961490602592087722648062908017962199441957531984337527803291897194860575237385857939086916829871857657655998312073540350662528884249170049091740650222698078837619520587944686268541031690932296140324603689918830281210481244907838739200608047568303099315950591858339453513342115997208031290587455543435244893898240503833864996418302258899746287820949117074086311691019196505754073407748480281658517510442517230042930687283694291049161351467660029534193243547039335754633554880119422950586978671937001283327725130163444245803163002752959880240759630423820959427705350832383266578902174766409886504087084623011822010259159528017630247549377189698653619587916971814606595082042568419468195770004540314451839827107684331397405927845903077688708457005505412560759602979204862478250325187995310874410623989894183958129444091346778567874604899111610103402384821568563818400565958328946472268302376234715456995669012121517504706918373403722349994844502050132302802903826933302882919017549087193584369584647572576296660288925299292994766575412835444321800643963773814786039284535758698900238962117952249022488478333006010070241249541893018741655273854119158585343263973502250621437159370520787501447964074716990498779087822989672141252175085335597064256765892870829964826700313964895317459159523123478083433477997877690836182270058468224309478352421351456562801010055011744520426904515303102213043685128128894452343648320567709305060493515670098008525798967157464849881585080254770343932478013643628122257372070589505362186269683046161760830301966231505572440988954292917725479331138879512345479975678870014257652569425190749359870653174795875853965304499168928765522977578657292338942107621999898567213846113724350945989295553771121494637126712495766546687047003656755033119128225669916367497847469214252162291695731857659319039501182891533378789193884295008065447796523811346239196543140030954628667672709086981745754666292519554480015528862728103085766206716571250752419396906459974587586797145018210088497013758882916968624594981187672486155833880523514874995243382007729588538133914569701143356485769996316901436798855196272616540133388903228202309791482254610230608459927108351575900355252743662551541385329080838880864066429364561902452534927622460249057905579492425209435877804330280829725464731114199424914385081177514346752029148733044787258976796500211258924179928145880445234823722428191847457100342515784368794779519471177727881420221573843300797243327227427119477435084595595540256425465568135273430131662953774650949579565001607465763273922715497125987530055343647068344864949695277406040369063006127394159835246089580088336542372265776746119601651447614369400398195277696085254510788385366540445229412811732378793656397252181474701716462450304940890214887021753945400652423729600427455684035419477235334439986667529512498706486503943333688988419114039924292668989810386424934450175304244696090386316193143518367030841594222477210149755176978673728807040529782019315875389768067727396617402842101154814650035333029078653715094609788688245898318951125645622827534356344836858636730761641692429685750974122136033850886667968747164798363101989049818803984499343954678789842741360935540045199635314553589849665728764158884284726449339006267494677238095233211815133608432126971219882782010503805284486480870651466196616625193238642814127397783843907826254213124066404565214985098617090647564316101974529318929440187833208211145311176089622813996547411737489999366934666306137992499620819233267947269601277298952591891993409276585944081361493986111841370354008428925191762970657985393915272130094697270964536187404313025028263848724047647797827563406324472594860986515947597583278385992985678794403458467540916698715229012013614286726214297845855272647667042868672629326951020205738268814869050919229858650698465272637360153155060853971499928897759191617872921185565544064757221837862697019293012917906970371305045677449951082897972101854664759959746850223477263736988443078355947667345895968397714971479166818743803085740183706586628996430228807856585861274542969882521273584280213604781176989846739878145855121549581456788143718645729352352043554859973541277195898363287650526645091656025266038249074401428850247028113249264128543295611950417783304607090570685064648697424646582994000804639604188054460458187963653231187100866335835086192881187353708762111432153243413555486687509462045207248329395292683963508992032057922139713283408413122843143206942434171691823203494372950938152005329238650177666354169563865497717703132787831638034709915841384083992564355622871698748442529594682407884623983860291424093607716190034388553009874541537978289461434344008111521657928034141066143710449306531031190853065982031439445934322523637773581717884260744853063443373266567994436389657765290792671343381334335610490679265879369900565641409630733137683212045503690853213899207463967598646926556825556347792754591228072768138678765359349384737250355944952534042220306680515170310860894109083687962317268577535804607284684925182978814151886261343357032560134934115263688958737280221664689170239748669642378295907097532679326147627988713895601491298393410386685043625636832206087921502155801300983967441704863290987634291429858110863837967553288592585307907305987816937936250695140246591250031176936038285396097674364007748511804019693898273845301040953675088129886268757291196937886948685120777049543922990791196230035122762442572132049455285411672262131470723823926750711412480340118179798050776822428751445134893061844071872956803067330898227130833816778760043670977942519844020908793974826841197078911640537386208557718569224770596236927760062335591653032046833504312492928762918046538450166203017589196090510722274974294784689031290785302572468985681554358447306007012214561059050526530935429523696190922083977145851713971308422692167488091589867417285155152405782311430126500062280380908804631571147672870765818349089009341310819754566443986849064208415495520839083198704295206459402407160006852377469841662795846461222832122637444565551397301808489938070709125095066361607211947441285914601312454383114355665540496282350717736158801628763805112089306051231456838273919361480576211984316674792215319577102310078724404804192508275396921736113090961615497958039088438132812933410628028753091773893162541296255030469220896745445613057290706624954381249682028789624763254856238332480427051841790998554890818244124475254863108097025648856591155122612413358157741095540506791688726990709660340138605721705608100534335408359729530502282285854113883778820626771352864473491407877648593155149509685463678319971950982155659665820345850240470641327858743890688903505723946511251563052293915778026304281790699898847410306657730550744836576241368035274284092509799246868921443536849597961159836251521093336381629615584452002876952995053266592704279202011804544985815624521265629833204534352682760177250185398107276418909785962106257217527179570250628272696778145528650841513174261846003146085802234980734320775504407335229220195863406047117334789852801930733715964667468350402185100901354196461079632807415723456011429655828729361299357961405005019778465937175953087916443773473658980692730558357970966287863819778121758737741662644019636794261970451275203783854087131157228071931078578180857335739865162678719161795821306894273398699789603964510230438180328887843622285009074837566156909042900854897694187728854470640838147940645964041647367239868767650912838568101529220835905107936623966662394895210068778212095984567095745727790928102395318373172638277835313012135511541580692393633702068318142238723583660775440428402735226531435043795761723761243808411108108977500994621022906264353734853417791953526846098488817854571395623370989654661783479877789077132464325648789860463306938365698856318509870904871153036826710526813037625144546318842111326248172141375268165595647160543877908546577081135774654905608978158738783686113247578546408880408068620599019131327371378154518205435967708111562997746014197773568160365459298016337224447189988468709901425153122365427901015937578229997703521950231653805181093161325408143079423647098282285941228632669085465144541915993164711252146232902073232780473287772071146309582681808103736492630165064777027832622756805831556692365916317338439672896976280829969002234798637876470408934480652746921595837901182856713347039399553971831283264585028576304901542007011095134095508240402690002279509555873371507247266707972401550189438830234244874463302832982212094069845366629835278399642253985883400070115537094901072608499347470555233411565473431997859520317858328552675317141227249960885631269971066516260028962997069574094308757945384501650640012798639219708598647223149898365203672538623207914140676557571829074765379105979705237167665448469529913759113975753413746846870405298695147982754817629703421833833692261469951577016613178764746198087255556355637709732835602425634433113878415891861114348336135520280656996745854202758658077856339653365186065777171763759329476425221709518541807218358413974968470000382738136656930571368810231277276453173900768768110920677512539868625513773791989239736812690843508302026911596831926504662757519233741071722799104533625856981522246653587001260937937572795653106639817913175310376769329952795077669769450815366030652703602753892160848604165309934709754085882416822007438837807367824458938402492437808599436567990620528451900746809576922484979539008346170287567649634204941485731121020030571675056978252148978930248379460097628240973631343605808530593540778152642722545644065888559984096201239447783644706501971129756265147716086801981829000758412159896178106867727781480679402724917142203908381197412008417722779800559163123402750968239508480675984143394138372398650960820750788832671947771047778570890938575655252112389305998722813610506187669840906978032415912074836819530104958867555138283050339356368719907301472961910661668004488187294887341822346614396845133770913356917251871771119773993145630954719915989529178240227022246490406373928160440202936479402876215284499060869649683964720287958720714310444676296020480478130207788939134683098190908158014585553567607527162783508526920199156159686506518547571532299588981480622478381303593634882477196427424442544242952583661053190440068310038992177012695599141542773700359727960705665916526260485837401198871922756815069168864675027569740503524647271021860725058037397251073179982651313929845663685793977314216175622564632752467180408898686235828465574272133149888389761127281774527136629688405123194579963123739018458227217447597666716851407801710728915891438986072364087666560303131126460159103673825549893363576261966893581585137997131667778881850630632780887618948570294046569858708602196905152703466911288505521017813234031752999557749766760780514380505835668175780349437373089136926448024911014024414511890523121147295714459409283660935835253930238338312148508146655068482273480251816512457469251617559373612503621276930035443418425317544244566686413434672281096242363290464377508156310145235223298080694537778715146518290539392674514010861372829332134165027587589936463736154604389066041661314359446857226272980025089532089406422701316442106151293601287883051714155165478556647923344853407993932799001197268753201374671232120669103791902684366726077475449646065093880921716246648221840519571058783973344427161539094458892442275855688913121352445588052119609535132107134761597007535131508352037173492855220928265342066864067429291164593772773104719364746295709194960046732460440397375915175708073002803807275735367319384200183170013004431073339948651218650367795024990209700568152650488997074849006635363066716376608234184766711324553143772636612088286246358967590558526526346834713507179539806811641994569424124370606269356710430919969539815085174692539683766011996072167941584202429625135756086394461416689225236883578799597332547981029017651705470225304554966145666096170770249418965538092810014028589439704615497242731167142634589837912299374348038118750136003185105458487671568680441894727218172582030500398118328541561576181236948123266658011827599710632675816481573764593729894171588894976744827377719605050315085746183032256301921223868294256752139443018596668336898460799989301274748511633307843874113842698310475102130304349812626670766158832581744696270537237479810462531545150024632611058568174585735117944230886234572612648352927141552448529703280640470355749003507944061195759956456864961138883847790168863169524474085105489466780637424839221926144619478899163706028639113842539879110319516170271386889576566230241966849321961395002063686935552694076408346164758040111860715776470842210074759950677141500706311059535562477829523562417426173854284278148099367837126904410796780344783319719274576167413067870765780022962006075120241458207199499747742287260656727997262907739989377367352662643964444499217245714250016707047706300471245821125573467590405862226321117643312671363227869942796740516927045630982877738199501765078729609354055261377688803521487523588516144996426909491102475391270100914842472381358059701351136650566726110090791041044355671768400664969535621676552582430322398910377068958571710271765054459797206398308103268762259003130270065677522473964133328104704750482227822673712328708266842408154061663424251882389174386831702877109405201964039435789234310916389453924797753206971413489593725144323333884919000536752144621335846607345231584248445279647938876660557537889595474138571890596447322846805111274654041087439282197694218727884244294067351136760321387867402976294851374916227695536736570088143556638044187502662111917564819733186095102065271948621277988920110006857793913997011127932240534445050508359897489303619254349570975722672562859693274807010727904196123054914600857289523893588789842834882553970575476793895543899266361865056420262594589776986250983661522327604424224929672181535649772016023002317187650363109357573130456602604882053209689224368395026115783001523912514131838173870100410639789304135147622745923179892291849270515380616560071680270545049915394588803525245211914763922652787955027198214699475161174571193814447257901208591884789173820471264473173263468433924172610383723861272465802764064796348039124544189089106140216712445852819143676078563037601479790682007360853720993383520963791070710607020149986023837627202712849388361421594275203433472739337548507044864546851467448592085292830873209822657897587453688875619363942546175251367857885654700571117477791099194627607604046762309531427389746367163874992514269469913618990975435419383542196024754298826994648784178992258244860929561342443933062684932101456387786862100507712461599035177816119029516536067183486032121972125671232668068640346105837186699670523921881746036459219572895804074038435966375801650313532550173835837363877029207201353880134264983784662569070339498806676550150379371272847854962597184662431751870185545177715488554285277196874289433089603227523257060662725204386126863286622636348106147992490480651175146220829534605392598210398531314922680040810294190592522959848508366325283772349749786258351300822268770989215918657373684786486157256910543912675892868668757877518117025347252572992264072841426391684939377154174303087324878800958996968232812592441578966611839381564546608247609142209657236384081900349881967807611254001439631560664887937906095407097026859922479521881477238178907981499479985642595968810165905415466949099474824458107988466199130202667961704144498655730960396886855580289684919261286634326410698458421949152387929084474035263004627469190815336291264596508998299255723565616631872100243595353261151574669327312672549396413053808929483393725357914875062220468646898754873358604855543002727991716324108807820075198284030848568012531294120486903922745062721156088376078303259979865177064210134198212010274599808311285433139566864313339495082498281292318561474840149861363591058186119951346177044294215202691316470144167156818105069436733518358434124810474525889957272136474371857838917932860653520439122472486305256066945108720903542487076090571289186755693108967982164065689046599052104190657332332285787487445892615862615099097692679702155792486780638821553038458941317551139155347530838227780077440250855076683877097595176117551638507737535135343587394914241351328233482244892642907880268249009368301266302043950768688952374689249754617020152042421597299070116918677314828728447015265303054856738179257409913192855584753541395759968349863041058929621201304144071273516936134866427385452736359420985569419846028079934555590116328930340202550784249719606396930217126579966114691110686668599815990381622365019205677085387335937067951127468581751015723402079855039401326105991153107676154474907284318564633606167849428190800761776794877030931586702537250100798767057349824648585483854701984653712165137134693449241335486049173967973508529830017312757510851589621948616095222660917560346204668288109834765239379424670518525396366954635273294503135160446905971218803382616643138065892011264701521308708916460580455167103392951182309479890751697461308173952380287295047128596729164060066934917112031944383182291786033182775369569468449536498502642614499628766925457021487032048374490126217605729003296897811297819687303553519238098119769626540097208580725996042820729505662390490419194822747979527931378244767637999877067145099519274861161522103725465789495034484529088530337833505793152429969454913070739506510510834019220696092442934130204772019754973895798986779748552824028936058206642709350034312222109040207923971540393835409701732747897104750317341650740522312106650314643404373619944295608001873465655381726139557864749312970076505168484252552813318529675488931030370918576594466158666787120684154906176459006337700878864707094701335237252859892502310305289829946034017104225572882209582013825599231969915915324977483515892231482924085512015071324004355856722433017121071767527197628912756777674229869619512605693034897062703264720394161688545321676966438237716015407737778937989133063813530541748155783536155254043975792649373497762358248404785284471910766282518463931234302798260528297587057223098356920729428515324325963411661564796496688649277487844927095217490478282771816700360821867612675597113453131173790125575006223155988257600290321530965084162844523118148326236232454567885369350032035720971247697122937963755790374766898988424035702165787702761123972993358004465110375902160658893562797190889554524447384959707086992761241725253500565204558847217287875019854390947757882948657228287343015966006013457074723006427608724133984038505893795337253265086078824104676764120946933270658141496450404543448187116997690495758965735090897150128133727227678404976436918790021150547899486455469215178971164754969647561442652506470069774098929726623000050402080444038385691232027570409467068654822390294214382573528656035382145673768481926121722903949116333742343298435523433215528375203836771605742491507382222921210391798611901541341740260038157017998698361145337310792377831114491947815368056889146703896548803569564852850149806321240057867768072589430567451168492996685324494836078837130936569540678642136049057941422554833123480273414928425195583002215426624549744904391500597624276861834871953799240301698516730113083760666131685146762861858716168665143484003227637626613034725032616548707726165892549388276664406630058243285011517932329115396850551897554108932082955430437523403142868016895719165900056547765037395640725741066887053739203174500733288800008024032261829288483703169623383850819664153433345097169968766179445405717514465874911105031326574783842780063099797238772710220664477546430576808585723563648215520379249117072560891711362990051968047437042627691952067164754092710585696717549712236616887290440140721858824965513760345092661788727113595657714786116150790433572379501210511680929209657113901933753028897585383887829554113753786974838802847564643202207582860095848325164754009944046199569775235634522713060424629721615918498029059336466631768611905424187195505795371409833083586537338895423492219638311123047536355328239437083181237871404601358082550339667453579167344845533357475459087177418018361841744151304762131889371699017270045965882389298101849727102860253661374730469814181734531146085183858062609664923957631424658635693100160272957433203829344805635096422544398323328852856071275390378696547335582772551949204553364939270535231782443501112491842181170924544062982020583334870396495145295016542991528448731051199243579741850215920027442458567939769674536988440093139252001934451421041952218773377826492546979162673505274649565487768118363094232401332956323319141084143122587845131890398088808268434401004647501556009887752494670943431253275014577611399365899932192095391342893788887944665845424608996892476233630791276140568192052105864201810417923435111984233569260414280580798152296538349102923595269744042402660969317000673615517348624493332012920828483666379742707858002281460445401901639096797937587474873510294251331633811529186737672624726896456280222952708052063245163508040798397331165087270476961141756163970253666818368418830474346870697614031182797242275713093164581830860648151968103220545369300134243406749539684487220977007291553257621258322076401003428657268085739937187533795307721517686980450362300235805826575341448322411689007733258577525110515410332906773970362207388601750343394314200404464107643047766401592448159025726891208230980860069813994382825456007480334633433019053212439941492833942976996046213059890581392536320269154091377423022858353048571401606868662752578387455028317662453490434540135775445648620677055787918341893929611856949153868000709490334673682643593973812746410009817882663293135478135320794935924840884260512736144193799782647197422431017100698530608455745458300814287390436860194038972955196210980955636410427098977148917605975826341516690769918017847528612230258445458317175853189210295221023922652484333621635568633452642411957582296863666360554944111480618736721223222201309092114193191902272472272290184666900291366080961195838811351226350862344284789001122251537880027641795682399873516119340680801268591655418687482002205916176390138599743108789163477476771376513202425221090705471904631348309020688829619013848427237684412227473846627941978768651071901138206670779114200427703359652449686547053468758362349461380916409538691560928833095158078267863216731653032606356261679390455651713716216589413264551470846453363655828572935371032621811252576626348394641628733748202332738793754270456233541246601658348523285761775508054347284587163399896948614348151059901742178684229606410480739485620195952256195182956595345306047783500345588487207698997396167615641045988960204974497085623262923460978307907723910326047825596427545348279980353177988815927152594814969698697586542529820930212855150846965352136612495182763243846967040324284258211525766848958651919335489218658377131308569691428942847103239324459727440038514214980108810367810173486236907529496514263164738978341733898387807396022851977154639675434480519704226610604596362977657267238518687086652729560352347632741712142138911942348654051026074489766738258420042968573777017221780421748608645159860278601561117648170594536986222702387711431925530767937953932388886336013298962075353769233692648653419117893923950441207152591959841489734041309801045468969443706219061720351678142521691830595036365045398875558568539182541654293441282838649732909526762357640160033316592430089783176132228404651045059800278564357062370549716072686648704071934336436173779951615479733648019063620780338426339507011501714551785063708096898646430063602145219867202065930229183494188754299893417651299980674929421534837367320356272838407731802805496840714678333615174717268762351177254913193653660726590500185352888348407749460541469415140208996200205903358386977273276458949801698877079108111050461847143371482791490646835912174310620186417987898937111620320470125391856397712080842025067311661098323965868907521362555158100662673153344859816095397851904772588339979597123303426253544343348206644499434654347970768572602938711403239215583902293669975378431051724490105581633991079768819915243430963491442299323684465878192476876018436294824249649025935517097313851892988994948812039339034271393547724060770903719020689580036886043188148767306425179329697865384320733704078676490527345857573599994987488175301657640475320181582887134686734111554967891164356863479483970477101790868328788171655845091790520376772116968932870253592499749521323709193929648853600357424792967280726109980774598029634938639298464215540608812432510210546789974533988649503414651815754730334804177986511570119371037348396689061765850393531274247605826679531071760808621751274853426007350435217989903062577982243892681098935876536673788675944455325713498676605977383838068476764701711507276397842719816187410508115992695105149894743962378694757266308287887793747466795807293888679199652136819074523324833344120670054286776164718855442355241855373691929247413663261618161441221537742262022516376494622768061250227984981119486683105746625438191147967922793614464497962565321633728244662741480508298683152857222257434779012420713015011925210560896015291314674187202859741898613157151759277959844405110977747059405392576131576733272711043176900610380023128533085391845528165574101061187494085532030013185798909305733151847674078074659894443852655940238476844439760953597723675699561197582074594097228424734131388417742020560242555778370063466609660812127744410826471901688395603579707566105638692054279652699075100414790942745838848260111137723133512609192017471003099158360684179816358719393754867213926768756578173878544645247151773968374396780149972426356479712281577971822766669969496346471222834246720059958252636108954219742881282299062675104638727016794229931487505597892693269407055334232586238954994355754911829045085203630624577483488145306605673989915802677681384837914895723286785742841521061813485249422993637402376631713009815209055713970672278692298312401200441764598383691621863420449274107848798229253160586188772508078556108666566352681746132520548230708241927899489317711411257643373312415555034092949451579275419891120922730638483778581713515447410369364857021717996696092112953234985704034478033460846597067359489340967367389545347574768382499880618893331789879517102108998373153928087960157220940253569383111592355403569357906040304617816682864049614490678586961189028366735038247909742441077573833772165215984332037279888213032943427969251367146279685032333564740492857059487734074183101411881625596483271087009269167293887148641633311589865975696745734579149463786768235365586035295237282606887417697417401684735189952316640243568076109308684489800630833789037635603534075735671367957327015226944292418809080442954281066157612062549665808155217626945870167825647832717465635751242406123381923092699090076979028233785615369031326538949707081685252472844359378026095486084805143273965956366462001459065015092979234955670840904152041493913931385976351000143018519702693065368894237526428768257820896090560836613348250390180582332733164923251810618173772393316002792088606952877760791418312702293049941736670110102135168407702369972668880069144449001043386846518860629344711326173646026644706923406736924652274861981477441140756478999793995529990496597146139831954209555460760206005427059434922235386484619702808285168610979871071149126180288306815977899458023727469158874250665832777045086155506023462886659508810671851949595959125440119129335920586651440179942913319487034232736716049203071281273590270921712599324755669417358140823709787927871390779132848149458099622276496098990384676031263619037593700063214721959336645829316029882403750712406560728534114959544556611589219329521043679828054259203957846709070836738926968403728474455199352944276326582806273837944425517299990944615803661186017559304734312427663734613175927198242296416125148370294980618906010083268951285922623763531190037223518601155090565879621696830738175804598786522495713494700339738818377611017187912267969713210948104640354409383461033339597333404634323963243165821147158784810126373302137389323149458451063859129582296464182600477028562438961361190142695651798632555724020898709199966625379152565616990187252543958918281337063241028933107794175225451619355782173706501044396179471636678934179529099636070000695042750352345386086670040736818952942865383102417905750804619395100930920087486902967417190892252417059411696326687633681323365725608472849408862802717316173475675857733484084308912521808326899410634229992548890923010355240173917995257799257475656701052868479394040005750367211665549009822591480493776506007684609197330672228950801013922562588420787604708063315850353225798619039885343201370215012158942385330578732333284057184374766253972982216957103190970502346739562346602977513479958129498494612707210261961452220040884349085222475996050367489233674441020454959096224005675338268411246258222816603584136379120142552430194233511138900081530988456833861804126651686577015737486922856092519286000363670642476444231907186859367693130627140252557078753013315112430346029713082151311090606182605172908335452850556965459312073932696709080775638645503042703816634329828276877122759192872655808692255966946799596378018298026554118806564701985293279894902519631895806375221277783957138710671280555979309638769016053724885263501450980309090856144370788264892865754439078741853218792829215492421379891737003964433515715615495181534573238930677713863270173646915262353790458721272241366136624654289354544934388415032340739232459911758397794337647969616432145625441335676613048601410436821501350977597876655087620116752426981825194721070305786297975271977769168145183204075263748064160279297184992192154491294062241900655345212923375509079690463926802403826587434077954754591733916963213058738781529648984590505644358877912035735479202390534306635574828699910422691734582248809648541651697501239204240916976648998915242787390050566250502433836909875570949714375775494557255766549447814130243025351792347229014699943772161743257636827443156709690889199611114523192988860132157975547777693247916060238842099945204307809396660190938365317621452997663427123194815182347024133089063670454033557723815987066151330618010985084479418167630672306253370040673964711484326950983286184561493316617220193090204141671209178584412694360425568237096084083887993031294994841212574166649927748662241407836108584208071470898635387546502620847087261267867256864985741325467789217889778287059582935715816055713931931771108311003553493041426371411890611961771029370096337625347660840576865978928429298497816950591319457844029210797187930702405161764529313270281830093500527832773136996124777903309130809096699976954918797269907042252877153251707329564946075085149153446429016376804177557276167755814133753303154900149165181630150086763119175503769942146072716016489213153510841596617534569847997489711244779192803780862578603270290613965413881321648026352295634126468538189536826500053007339666143419250147514333789119267650032109465376801466674231719503900163911540104864680258579399002479186681644696627047391816116071124613934197283914916065477610994871753580605901139038517175945727176021245237337984089719076967638545793934959304983461607514666705423465440856249562216529984564326944721901523972491115777747021360345442571529151310781879581288802942900236176360008246762506270134995449838405536342158766068919236181027937548274330564064984756384143677885087111262725451043853337383821237970678884008832232251944967520923469091983544860204223377948682472846030132745724803234246409134004413939430371376937697421919262393132282333319348564449061707060777321001425424402380965891373550117720345256471220331838659788083150937467403446316356504011585859016984133251645760079671036831083865941784289208980971932634020486837836897457447333691031336318509778551007953374178207329205781082266971055746387391739625301459463801269902974447019163652448721751168743314232526683588811632914228903177415634076803374449932576750028886167289918250269700746681720443455268254303675838801662631152768650291014716140772063373260679419068506646381662365691525218630658026274203359988292359550701394835300595579127656244951177863108489960006414534109570189751040496461656420221356199346717292510884388366157484647007961805446809821587864600026358228270716575669173128500973695080438904824754547317287954308719919288335583736651320481687881801498284136202026311594884819834100034672476232694567411665124379579688133342241465958023998307713603588046073592399090176830470725279848255612771397380615100618737178397106574475082446452182795210684075636716915218006370984272387668423001702455623037652359045135717321597656056564535467028668881392605072041986974827353675894238014788169322235001792439325633856968980234617894487852190902065202641164022897241826396037868530043362233615934611835995094010264236790637621643781809536958536101356625871937929607843488917076706772265572091295039766582150351316334627155524158405699957465990535283723481606365310640154814573853488629050504897317700842546252684164835014666021149393469995106837768410217321250834186674881277937793125187135756618315855819392959347232926126262740249149680534706330318394940812248924371280911764518705755137941256625860328908200132407930657156287956847014125611986805720354798229233827781033932299761147029930913044563799100272840813584935740766795992872879493557688630924419892428766461782768937878352856280279021697084665077167905286083532485000344374465240540195260609154940941761024932868854651371672002832939345909003395064989141767528411440006737704165461896527780375043363576759719108017724451470769497668183936219015087250154832169278540212626144371015936853851550008470857825011452823603674605821556345768621877730946583172958358590490460502699288129156556834638063012448669096602665935453434707328813584070669221204891434237108101800282688905928201314865386298610566117076661004784354250262153498954489764349480578298660836934993094100900068701743495477047168293307943002961129954839471192805384794404801424101141265698889944055430978481412748624790190951017650722470639702017606107760530061188000577765669087383740897077180877160014915069540754669281264947943330878011558214869941010717663399342282741390132732167866540497555985649108985901356347971065800546507382769237966044359564988943233654152204852822433987761610949487326901704992809780083825965885651331940170092610713640628148798455617046459257718467997782821724044468520473122698308547152023395120534442478497976399469555585254926749274716781077689530760915762927922245249024712973775699402668545969692828306094773754275159648010606316768312868905512990767724420539840364352990590380076629507050106452688610160558111504383288190368818461596598467866554257912880487091150821522845068388497632144672986165500944124861778864328711802053964220603898621959705129937116448276067937920911746583284910984217251378738629810355840942663651109418068588149978759913135424443461912379319584923758816442372461321381375894923857780917193365109991778465414838370027771487258372864719573543870367598887446122942993636209143939717066915024332444242954596128269947567777691236431339757898520979701630553860332997394565917113815665714977883891927964632697287730089608491443976287753173237429284917333497099454931631945184025409357778699769781923636505211788101705341812948914871275908589767366150738758971503074212107088029087277607643171829416084815863418756673578123902379303268979708683231147163932184801145217946641104052512761236672284310587030434159220647546510254531857717786999127521730017275869168904261533243080219017611220052801551402222380062822557982360625284486984893528829301315642785600426370411854958140027052465230849094741081041920905447216465977576308866633643591108699583970891273335714498156573966338153737108569641898584998964353060599400150939176020621750073080706873934812337638069626058926551958151689133364618327207732132423717506436707682515113627973784488673603858092806211743589812289590401323780608341175663411401751212730200110388690641258181073434862223888282303582492737275018253885031452560689914856932563350342487489151179523510474031076890303757982171713757877445594467293184020856888385891804767795538615693474640699508183473044297205247733031853609751458417823732942079541616425567070534483204739014890133455013409929717273322661919898373365363700017215954541955801913454748887524824300789492449529186779916155531829303913743743416106254775562101294555909677342753142281023106779525065453338985980701935236057993734373876321499179225655636067023947478628829579789132523472174312697813620547673358762746932053087991451470584141833649408882188938719990179777562701258609080273910207924394872270739856053725335877190887367748996035520582827185068817385849642552920125313584100653863871291655268788462918188085687436983698214868623000167509020643876768271422284593028368700641141313426039976048947098202556305398033950212548027102901202244797587967966316063651350746779307525654015025392310927839845454677305764678747330039316229044148491198861443764662934424322094803632610479277668667339093739260093305509476737505346804819408113446127911931146903774332107487945917780528115915256411772888709894264662858950209189473905329050784745048004162256448117380038792596414964700563105864999382439118273145656309258117989076394838942409361826085829471890252254851088327612523382049460034023397186498236088760643763993466001684216707587149446312903468076340547992000166293248725401639811155226096624673420903177821013636410580205783868602763557774732561864179323959718097182029213858309568225234870337164037196358411943210381478180960399282519464626372115179234060308748483041678699768346433385003010442981440868438163294556378736543880061101721386455946278671028344169042041876923118652640212056900089974005549037251445687095324014110043033125077067401584544562346974533577430850532292152800895194349932867374754945107774479015940704106625784644571249115540342793790998613977267790388111655581032844638182912173376138360004428096278458521979435731432363809873030025192446313210025409249570688954998419931598403169729212948830288729812353340569989273900402453572173813745654833920866451818067197423716364362555812150851567040641209377911989058609936060519729893045137163479240042151830842582365940706824458250331831114659586059152853452810575442220330338431452925990836622860418629977400455148146691066471657075047179803560480651523791077643439279034375491776028236963345998205914395099344819471413542399520871341278182772306877796518416351199875651780352913962776651086401695997911344749946291772200142563239645795648534507716812129650705638380181951801799936679908005072682102503159445396915340778142043398184307275318564979084693953790466621242971640975860256090465090142027389828991350587107938072359288284132685677225649391750876880466283784710552444725695975961125269801421168019379699501118300815596276954204495068008486698203008235097975927126707449595430621900831377462425000372832168336245289436154495728598223805734198988197275143414746167669511345348133506870907537198006394274088481060796823781270373635521133526420425657091423722516660755116116171272907246339926237942311800844746019701238944999480476767427480073585157503444954644751542234390373613423604332758339526811943005732360492088477752400377997534100173258802781767590312619808236135329915661726758962045052372582618530870087603050700853682875936562036575379723958014339753615080007155136273073363211432708218894058648502613314869603688783337780255911244036152556144301343210076140618299072024381598274731394983454942786413564070546015440280219620609429472206863126800000373055559639409104778734054248461787537303473115336820224600718081531418037999703225295422796669573575335800570770169450028437798144612393269536658849161731969132175596193912236462038256223784048988234547401736388012252819526717292332464358005571598350288228996063867000617698620901588986147133532342250304580148346739328677758966322133203821988422413902674497750493194750019236720266075981155307962113652041704112927281543015116923048242851557642993689679770696822155232755767832990235622933011606957404207971238201220706375635255594211278486315773960416081762922122791553990231802165679015941177371124686005765106163741616167433134574322523140175571922916491507532118991746512004742352709873475300747207350691612595723403744147197317240891878184485728002326565686354971488628939469057756157632238359893323266170407982444869853959603128867414976403067100764029820357120232589739875210314239930347830378938084806741142843720310976271779011023352510150031692569160469825103921333132992101744473626774442673649689210588345188769392886588266832143118557849425278609822849219211620889619521577719314185352909713400216944919854715108378656706851376682091807912073166442442833462678052396836131636683028123910510431373069436262530814363519442452093288021397731096361435966487860599658317602029267091521078630176481400790141660837044118876666118504336407557353110058495257546238469419105869885007578329673078705095982833838480702005868025088607879432960984820875444682537278501857678985350382390069105275048792983831399150401101963591920279706435271743588635325646614430021996345537716794639176126481810435263834556722327620511426106405202330295523740952786486740068273563581808731328985323517161879411657779711544902550902562900959834025978615603957236122076858717532643704645353915944587248656865174613039884629571608763680981595930900835196053029648073347921586673726297280511485909651880775643770806819413140387425575333427604214400552452766453776818281733297438611850961735851998905154097147863259406262106992581406076589195580994481924381771416647035589288269994134077284946240539935477609954621757736408921630048424114142935593975134379670353224638163488320010862084479137466123464671241647477562820675048818968398482715807392690362604785825740348330466496800588037687963074594778034206395204732952409168343332385713771458046941427766481097013105938897756936954801038076777319390453690253451649931294000675211592210299330722520073933448459955205210169330840145665015447104150902522427827438353389192072294326050023253018469134215290639270186358499116497812298029519162736868808151702754775298433599193220947872488608202225431663855556975805934156805765622206156411361328355728042294019268116467675456954650149231820420063967053504444992335316483664717552310459252472384583836149378780277600456988754786631389302733162279729505128802651543932038925147614449163265722232450921462270577884174555783940150590785424373103842785486031730926799508826444136494898691511415267626670336536881713190242416758980375552503609735374009033071894232054983520576944854392669933317875782880067961231717647704141798391747272432869552967799067095094689021265304223638700909140604293879758076502736837963171760174906794624249115388991940371562913718850540687685879952772042044176229280985760252649774294237066028633684355136586069900110004302114835986477715696060617556584960104973389581191750030016382156845980438975731626667489194138523885285051184851341210530112627765308319391503277447504566680680656035773601626109897368211665706486369642856266029863456204679946734132150754056989596264577647191122340133974382632037673371628938058142850882729915067778122009124923172275910761602386295939718410722463293371993196494881470187475031298685344344196332746956295624216614010571248604859305346632087280382141247972219797850428004992171217965875008356165840587638566652006485076311779455833090758070393850911564387559366524137126511305181425441593379885844590883846147233598134692068621366828885455982582265464263289662041933550896906297271185615980947446152091077048352959473707694533507609312448780298395436740967722558545980675738380760874743970056853765916530640386286633139692769899967141699648282220006205444080299223211284007176362209521276460029201728265635313345212459067852282660615010518562841634786846696577689276934569357366035445675632487775689919786441998247000911769708643826813782379203756555610215049926970063805119776695099640675040906879139201726466841185638465496793370818370379029198024243455816400959416226289780095416121705475496021006875455313522210465806994221242178095786549275987980433021725854954047544368173296497608263149501071001217030488109183370330583347885224739564926349450505668719330320669982952159382661063354671591024210783024469499916815044168966809195017503444057319426923313399392626020260396960227742319606361939131362785978393759146418370503564099032136332741196531521366423763813760711383890703529957190208776491268823119285574742574265261130414294684898299477821434645304769257325221351552854595328668967627365460161869517601812730961665085440525817720403843187474655269390478108779314064301891917456606081644439630613930907501205607327438937089879680860004609782657518257345844801440877202670403118016741694470073168962719067805235566648234755458602045281708030043718536612135855346531460592261514926167536833099489360305122633448696963948151021843516260279566208728086370204277719266049731590941572632235658298322018094479748529805004110059762666552578285353831427303859568278172988343748498301469880773650957595820533685141563367144495467087138708840449985460582046200614615810566180504303879515914323048371087969634713803794902593177713307157265302612028545482254701851856606572100586813018452541711899898123351384932830442241974231527711408028192787177813398950661756257117611709150134198008233651886042996875734337255336500932887079017485354921939227149980720697184895976264867008051114430319066188923262993806957416675065845969003021053848885891607146749570715623866479954015407747038163567891604898057814604309266092794967835545599374727846576842731697228011306761923024553686065605840082434609685142154024657140020821138382657961063692071083264036328321729114019889273422879060113609548772954399302656094170970503323941068055978013191550524103937609077009985578300920749766702907092425257399042730305398451852733564587964299559016895006387185837670882864842958798446991503818756400763509984872632550555102848905159058398045281880199017429617340434192454607705416688433257206783935617973304496018651449399391525799366276369680124599296674502868788225829981253929363694060810306216269115296387539532624851032570773528515457927072020833925016585555102399301244117858670920799280971441725713606656295818677909331750100149928934269466582790646992939047856200819690704288629954935870705552471834958409060297788490685407077110144948294813169769762459022011745387728091622124081017417164579930807600158755007944283100640147903858474555398581491554643509761501852986791753174079826620497247792802854761836457139348469657625000259064073534900511116871898965260702810415421320825661874223529013501247876481213398976339729351736226348072205748970811978005046589962395471834043243998504971806216199984274910082693369166180123692081265106541692782005677667102938392813009204959078061187919238225284341440373370075011393543760206341024330706563126473865785655458135284092773408651536672475265654880734690001519644979444549626179223663981666289861083328454872053143571892205445051236884724152665071665997710533998362803236352789860090431362314889060202478380817621588109611938019154593950375584726744797574293827591026713645598250841019243826976683290600132386467018053285532567881380256021907348524003558117822373387815764957297774907403860335971078893412115180850449581593528294741307953188080976067467881584405139045168822139073170658307593552674232380266528110325814289717782184860630879649147743218731305371057044360419489969469853553741163892457746931440465429288855050238712362378713153481187800931124300385392164121259423221402168841507353243816218503951329576276799335007437105696361430149305202225563202129847998681399416448545776573011410099879722966192634924037185485351669522739136820957946764386903206772659292116183445716756223437596426087467416582673633668347571572871869495254200683005797759122290134810772989684906786545880088794035589892194528657225103188342050565336696080223626981470810119356075106270486754254200573933976770244055792937334787126457860937540951141901031374294930163113653781844152798832672379037144585133291043160426430758794108854362736575672663224170336345916288576704456603653462131207031276857016851995142702780346087244005984135461033440199386513939029745495443737799030353371029384449744599970413023451887395726261938726178231625299515371643088755402495277404460593738623371274035932852692938595307011147113148631792865021743728814486691734207796705538316894371692359255967067135031661933430573038565340535256719774074538371640611614420186079265273626198524537733472767275377323843948607816483832715973347189350307978369518342487452495769455319164380217955358246742246612013521139909213788272605757942712473089253384561466625556775642661824193459619464589953406092274244818553237351102989709592554732251322949781785742453341635306061538030078964758216604685870456563720973084396628016030674817162551268344454521782815486021332257338136218150205650361668420882870526383514503156294117810918600300669450664599228713624303126441909950540225548650058196573002758620595884947794548636402963631988353265278123040383313183541150032556912527159838960758673135683665349188671156374480418426172147749320449174018098964214504511230177269171906599884643151634467966734048763708098179224193791421624401214680535602124705516827328862690393497077833130690508621860105750648205580722080467571413604178786619480745377618632030880884264475134273273164279112838127551781324058742739878129453388907618187440289333228253985175639205430768021237930245389871659750840836929324125020159048229093496277070623011368961794475620032767454394438886885501255142249812184705817263905606353398639484459402666550178569207036339186953306559436608810105864197055544697105372259334126748279907647670073350844788151043503995209953723335316816749954867931761635059375986584813391571697347179754459096467059250949319713575413779341735500331968426431183959274171779689653499409153601889062177590976780156306154045730054480244789523866376024850426220986692186288256094022314071655782624488754452298360869672005404403687304618641075459820071983701299155197472388306412067664169399186917701301225499369702444671240329644376646640953121240680562777627552960388822134942640686161408782359905452134773697872253162370139936212716282576301015122701669416598472014652007284817614165100163209744784659203513791331731161333931257196060884989092052517330146776841106227543079115484641997515542420614670053513408559239311119567738446939009518575444120566535935522632125774332070729066231154206470845957108496218340910340978895199465553162120125832741641653101106249017213188960956323719370414052290730539941219385469645636850898780542479601417475681602981553970695551265584659001809412616579352023178185662543298233293056294209758225639195702758559708896300978376094046668805388192103259485372571280677581661791751059409351540733075678289958288799346451538942590521989179909906485971174096899675789225550362541138755529590908072176256234460529035997599837512022016877773105561231210003952914207068875421500573166841366470869978130068523622605631133817021883045544902968439198962510563885075092508443594647498615136632170272401507486669140540141315497347987695498467480864345040705063754882205445263737898828053471313368978287032649033957430710895533228808946907386243427667313744023578858925915687195010116654239490445107311045527529987903697061763694727510334800340600986424946524655562106079455051689423515822139118583584603889202788665408495044539467109845355057576559518818783453768938974807761089643490173241176310458367134475056673390126443802170173576628600661364484263002134702732252858781280409050314812872603362785585398276598436204438633247449419045649507445610946210708054297229831276444778184917434946422326068626962967878695181120525125437147812150648154580585867981800069574235339963482187808896481523330906831696972600940847249954107068146888718138212012061339308553634787008741627220602503873524568596159854818954975134517899730431209013088765999758075232574984791192468270354512060901389266048444094693150108879654562122249148366017277131921188600665196819414839943665103474682244441719964285325921825439725958297789616721730231246024065127339261248390222225664954147419934672115098209328137115723825551444132786651441189152728265049275479567930494093724620427118327450258630054495250039625797539088169980104068807850678549414649881858872614005844764611092562567724526124534194192319071630292117212578151510679149202543541583791970547930913171137788437911016104928715991267434060090130876662643238723609508354269254333888170596468341388080252036955780147118969457108273710804830202133963555633075722117183451382395391860938238926964858938856364979346644560080903095709512843934235121024088060890195617132357554433443564515275119890875352256979370495673655073445493741521769829361394430065947971378520231232651349762999355960118745998548374540736857757456410802963566741294280985001772310189103305617734684826616741146745721569978723545830537074281581073969138405639802098172884467985109140131488007125074256815514040395281970762532045472769975262921424220180817831143019768087838010289329360323988458249249571118509320090706911793400225190153246589689789786503598677618806025688759588405468460528431105232699246970608357081739573995357365301425499409488843631228950945553405006523629313449184215392127397937638339168407889429438092295014207917929418388498958596823181484213637508960999266103850899553559778880068629668427845682740930632704149410666669808399665820988291861461551932007700551946510874627294260927143077133844040676849671358048571706710298081044607992123068464525731374161474660158472204579687441312945386299520530744510172798766702816135567517562393750626443438786427356560841053455539585781968297286392775534379529781921697185714780093333412210085968490415294197753445148577687807181858996420826173558234058521449588727552322637552401265168921269594476836442920251625051282351017654741622913098174149156008590477137107432703384969286780965045513485821069306494142829151002657624300224063573225725531553868363533455233168201634650398797261409048465534999031260638550708138676915065333803208064703122745016533120464673785042898083005263492032897780616580511847050669910286608656031140895668681192346087976393360296850477436333322227705915740239426074200525082300260349709536257562082362720113433015255107710101452434797786202216523452357679419922560932771668539730260255432874196978923521434073861855106932143032472726437039294972648310875324574189534768579828223407066602884461015435513177368562524186581247977162668619221629703811901713022736996190549142982603867835195294102553186382020135662955800492737062073046287665553685834712095661846469813714173076831251511106521401785245256808803041321550527634873817362247640557506063498844638795184400335599423479152140064525342800169171421818548503032422939655254748846126267838891159674034467353341467305347214045143500918677288751826575510560338998239592521732947312935226560472893849782450188490834909288369258514459117610687357704114042372221729835473811902858155288530413856104649195231377371254387827851925105058120277771323257771610970629534375233205912299206610475675506546149263592404332023771564403511743759151113251682340803598639704693406373129709329945903877913507098987965260347507560623873208388623528840665706803052063633611623354684744746405147181817090489619166713135371707731573326672707530355112865438323923673579076917445840601022502976572241613450802158799005255725652310699994205484950488508114106705786598842937981003226971659652482577479434318780899064593958741182827809500176410432616018355498188170247515632473377488702292990106358215766852659017998904304612361096503965457868760361504158430860131661624058613140228809662313232862119792434941064154617643160286170058854058299757888528514706449426341580137687729427091853362293952478610554709917149735793656442175446562806206822387020964584336710269551774299720754132487072043834611872517695108884160216262076675715104417826956608232655920994063738074936288831768501335676911017627552944360027759659209152781587585289649646699736464229394145308706171331506396667093174343986152877206409007473699899766144283020922163907059033065134079469491998388224120626543980950894614951759000394186213586459391054650247150897332247770605052445706178780720093138873761842337012896955460750013016109585925543899920575400340715280850794030071274933141536398972219284919761827110224447507729060433318547147724598867663040682344451637900432249202448416609452898003903203129616055321401903182289839431939769073807391182599890176043645504106160907558414877042360484951904675658929504464579962063904754447010296551890804009900224741515990551172960772441515557781281467183046295309607957788536739571696415142926066070077784826750063923922756045993041249225481980190112256947429205285100758997656037465704166265989641223923802380078803410036822318535720262010762509381027150279519876733651166092856601282096718652333956364700983673134222641073527367567902518482838021541444687524732031971287711103530591743422685494567043411989272745347081815535338375340093264837297378354601678341623980245136165775279530166457607438289066137067361707285328119558165414350860561012481575441955565753384265530621109406910360077188439672248233009400652451601406877251871539349487997772466806921032782174380776616187691289641163408941901010174497830425124865152364579426953169197907949153284726526503410059098687916527024299283497373750239151890618634114676165709251456685400769584225363418838941275970446568158382789179704998434903474830304176190051670877057306163251073575278250799365556752342816061771336920037968739597347908144615950060009018640684623029788652023782038797841889082855212700546472491706198612693016716070311916152483853730569818296890880971723462682136664375628362724185526921575480388539464481069043901850127030341761336903842237633289550887888834142837579463503252559881262838785052146135448162721574472874578885463258268264396171344099023563448047354309664142676407934897064431360322285030778188787255970323616918121052071258268147731226050598648480427960740798569648913083101304342188137123254873971497221653703084061119860881254078189908753406911250435091195242497811610073554865920587119354643767056240608547069740037614530701070307573819577181863956617427529931630052012347590614066777731913936033366382151832469225664673219860493924244186967361060507562270377273105663348650170623750075423830748791494979887163648775860724700497884920015024910530251620331420768957554526536201462784394366334097811797286935451003288371268117393603985656179216730940910097174917760731666960337395009077296650120198803263423699146137535391331428026224792608694916388279707109796351093016353038334211401356384669426277210204498392526150363807598835549477536813748247870687129677799301611312165290130368957139395713507054774188180384931624408454081742027081649312961009374394386989870215524683993218724009121761187550709849272956421053484661290736479694017966799634160955028205593895244450115447237540742938676823988967216674102399001796747621679585443254833529131057802924262414729431114309419421479184691116968251839571182461435554435016002446983534326499277684430284962674606377163269730130557308449488785342619791225672670637315562878207700036832509614416575815506100518138453739266962176186933271423080152435380720304286532046211522334311149330604731607984124238515898640018167681346625266956936932859960154086461641625900298855888519914397442025677308588104103778643031103039515881664939518294244613481821289512408801137907817413514944544576647840512247245481737351362178022179767150544521410115493460214672937268825633525801093676086614563920902182584666061446737800948069543578373422402809906646667489440324991388773529078473576820792462964522361150332767779425543160625605334359272054071714684960844103378180564752492231904799651119852517973848180597809796494409766087319070360807544483458011268084065067565006722228982778039201096727322702535213605623661635795610243829962667050429159360031074582794197404552121690151272820344523199631636100717486587793628599654508391767343906365143502514440859223617725615670615735502323651970237129837926601236528654887640823333443098932013895683021293984798043107283235921380507298386944600936768560724933827532877695109196641342163825765660738698520150864478249768029927258585987331974079008789327161691906300084754676033950352025390261946888080343532093884844435675585584814911375582912192963283090858160403424109771626650789194178395277845665369580491924615229922518616162019730469689215218766809407034487448285139814701124619890863721262973662421081839316551253956161984039544159906041495082777581812951090253170900701949335444019932194819453649333329919153544723181968431537943274642634091148887774835981969784450457016373041403517852820012885337809438678826845391346232238953392401568399814669893679873206638466058346374682036005055070031988347963260621614974673412196638610588814997985049144819396429598614915434700720741906577575640172227452240740326023612572763025343473608821458369009043629040741408735351670323433429063233991796278333291941081306443841248380822347795955754121166357931627260243357439269297838484376117148877706677451104890234188167938267695847274587107047330473136334867256076025260459004570352779973157338275912495201161268323103912178471145950545500383852104623815124968764872728566158249881536846014477784707900599955142150578190785316504186753084732452523247757150147434506172548807746948042297368380115017056535719403550206934573968124088883607978260590701382755882367657554447642568481485810338909940901742709859930517987176235720193680583593641173288691001287872305212197316921276749140020933596009318910499913992788290414700825213568924385754659701805950378061213950224458200021701137825212089584391171765390796965299196381010279251175291808324879063504675451891227679040681398801427271206860575062714915013852923604697826559088712873908211084049524353962768413720171640426117615604583875180116670968193655613383478281988376415541487779085461901173492344295631380016982844313461984026641014343365356818241769753705119168217377438890448885877158650433052400186261713574880901703777953597905732528821999506667942783095896008739860914537449123748333835158696730213136534765687364787998187301432632020780296303170711681172475107761822020441125893683461328135379227893458218317922624284297458774013018661123189714388455271525359024741970586323242685891702668561642762885616616353932147411057940611519657876166147341553247780534280683907726666182655013861380631147820323359178433635786416783419673520043527616889728939066845183721685848121048445663382683025981969399957858636619439382901139872494457859693417424035461798216313579194118363218097735990080450782487715453622191102409176198649207525255823801416538595261306075470508770507398358672376126133369880359539729363295716072299309595571558588165723518823009128211622918642342013464333110236314134620750235744899118221004404663059728026045057737105731215124576075769828540583020370088181708779963229397019222635531237196189967724998772021186377089633947796572008599066593757984417881195491135702235472879115664680994787885416033609898004522711572878299918375216583049437598915264249884046834866668453782571488034825774926047845368487859193960348620019841495401649400472317547880798411120463260793845864303016860041834196104418307724212388694084033125493312597688755481544286461124938952587794556045189921448136293012126410265974607662754016241833887485350477487714342671357234408138935552436900164317775177038894531960873779960406877766821361520475147626416398867866008577091175605818476050919818353666175799345285427937473898667994664501117896326816545125048193028997561177946051468574649229179476154616029566933182735001177315118060595293262779164125010832617475033440975261042364337460942999951039602481934803801913250304038453887419917862548328607308900586636972310951323070844829272119572160805609092860244196706161296448942300608895704243661879064560186408149654165439800078755043385864819540164173080382412198504048034479871448375199771515977501644064834409894435887507427228162798349759421315961781362045730150772800807109356234170410472422694572708748236084730639525165184913889497745146379213561610861102984892836267849708956048198728204824068294997541262259769173232539030942789581571709604082619644982700749179749555477705812770658589677219402207081876329582205484904290294685678091947020761258323290034964636067976091376595035845547942610262824971338382505957614946024138852629606599191286903926473483806705435546329839778005071508227679367387175645333394357535188406428602218305670849978453648288274411292874201478704784492481182925952795033504733411243952225934739210340412005992244026386809106570497907593599847596547207412527215414172671855311220387828131175985283437620047589786103993879613183020536496230449591045632418644449552660662269750593341304684800416976292881665180780316530491237962132194127510697486648902275139902599250853189489354642779810532235851566133952381116946693187855272508912724885034389682342061537458127961386958328890377960659272472585232804622303190885733729071691856472867497819903454549719328200320403347490165038735338443069660646460547513772918500011095410677187045850227674317944404887261126630665797809289803693418432570594100714687993549832637401723000813590303142710332968732247524852708875228777567582363797853668071477439641015329523437060332146555475621753393951792169846393643557845229234687815389708457756221482942168637625461175594529258536848869022056692187899088860002271441401834240788894638812577930124754161152967820548455959602380829442182321172626199790353176888775032817029182893231372131893120140087112527269939739628854913655960240860641062471617761978320465052341241523904889855452678955539031069820707955880104759994134387550041019587018719117674411659587686944589002031374872700172582601131881742190956425238086118976093647657584472867049751368378596261507558396044307085119271997369914099570654215897069637706342355736705047066782561965673997651032610820852236747104268163433820898268777486876209122438616639717578480317601153776255866748015950790258175685237319770884814952572764834645775469087149100990314773240282623433345951681152640831869351400748023960206816611840974982128061377922001003166545157333083689502733471200152761373218721355421914662915247491262346706782879276463115110276971499118848692425732403124626721383720741655561546417787116970663447671526588412171614584240573683261778366151229451149103763929824126931041715209526597409659150717915450684523653767846054586230969005161490459643924765633911893509153567212221062243135802184564495983311806708961094920377377947231303063760428504510730791420721451472907526187389282223246450608282627165463201036833576409899959879075005138628096664766904281812308289685872364834335560778062555402083698257108447381186204533475910218748078982201447244415450453890882968517413742968631443839191505958152847179765524077674786671229269723903796838448851115005297211036515107985481435768458945361112597776941145394970263473074894035972262053570694768944125916650192518775081803588540507340854090966199176678794939784137650698027721568676736657039687424212565832868862023039929982001669610747788233090851099468253845078650923002911443606269978338075505883174081052189584360238386948492383311287174231857438165507018900524868244795112128651739019494529279482276302806185377118039323848078056059730981520275338207034920570311906186666054208044503056600198482505171371455637662755571683618397065490500629131746922361421662100675360311958660581562755863376075239003062141436836472609600610532724874662861345274721258474500692397288271757153584820616158317973564318395321964006276194847081586893815302457696049205578785287021588379284823093286168116724284068600750851467555588724569240768855515464179304471366701118062472743401965387315383583628532097490965508675758149399850370569326394360745482858751189773752388277465331637506943995641591917141984105179667603881499947768918188740452656819488152579147001694210842988135279974531939566361339179392469742130019277462758030024528064152081255009219806422573656860808882142140545277282966057344037995965489190466673930715068191322821815749296868255127539499457318619458386577673753442839525793895519833033324583893282481021344476615435747369721768746986018183518203154680709950401733622322293089371973322982991986732037499848060625183335693907901798617734925325951347586451575264756407087303919317589329642526579479075929356402939047773108497442036928879941957454748618211410938505767055009248994072976666433427371205595021134775911072251197445591112457298228101407246248649529994687958286260553256658185577920424860250818837862739303525136180839734377565016691448583799350298307978338764036880588595564786762137745693167727500639995512126343902258094227921736234787278547262191419392493413502364368053994035385126156914931194470069473454613028726836221794647542950899743938190007297671361661990342454209424357575570982484035158388871186004211199516540063134344282899054638312779032136166136938571158774470811197445252256561192678685632773229314026982448874217365104045987110782317470401028546862623513944443157478283421313226395936470108548614899438378428203629751753710206492119389497213311884759213450048652450666985234192144603509714115906949017358461769265213181669745658186583418323397428042441134659997108274717060300991682499056715938100409018061147764735178084181146796573565067780316131568311215656240205702937849575336339188585577413063111746476637348972031750598653814188911218644513516741844977321501033767854548122872488568689050409345398798997933030072176450482738388328780597571827461205791304421096184975393891847682846929469870098606589067475550164622280463160140566421181338112587257622784274732537180621695820992648311043933260156367903718300555335156564708354835090186997415731392721945899210106792241849220308284495443217093041641022998223067569299356806438465385774998674086669702041776711144751848569395172156520808052075790688934815387438624157030533549820777289408911491098056969583902031840259025910990218672924777198382666857397041131860758231781703505947135550787679793244219690866736001201374946591101752619153198204451744472545062907517896014434957056463202679872396848430409078566389105428168819636392193300552063072836628458716653086989049217534022873410720208701638538566670196796368419979497487282462156043727241989905855799207401367508105319325418041620136867127847977563169207815510432679989700331082248807921786260596608523894028175595655771000619205434265654027377029155626983252228946868436329455820816368324757981451880355877261601030252816298592823203327552503640227320924533555112770124719636877088917746951083352245466574467090473833110279004173126760948374614932202657791130873646538667783496116555196731270783463504392309012838730412735393649108138976859343324124569011278569225447726679369112142940336549581440875563395126819637557851970686505276520120785451606761024617175811975711735261685750515327956432364122592160318360738738549051691026835942956067924728714691174848473019422031151504513895929986212104063774196262653155238352219897062543796438297105771904359135904891083555452993443947553530184411884204799573850546162299616364872707474787072304618634153934653108360374257030491436969606463428587219497597007061601310185424172834582712597084162176193532510930564764756616280525593324915250740287820886494755143049913087291886512007403628609512526759949012227461095759983511471654170320073148790057738726216464987792221847662159820581932811381484244879303164861935227116443196476021437983361763386878171071330653827459874449278757749872428462653652305542476189425034084164910028252958371453075301537354756225814123069328085509592849013508639010660972292222214948173551018393854381770836119132409102736315745050984851750968933091964140050183100048308192101892419370172363558418496129094906181001946597417377712182449428203018149118908493710185557638271323116166154458176296960308171214423582118923276947290921505322042422541298163795427906052343794700258315681316838118379918678553630206063434474651121153711119036208339389365335472141018623302437663658104709054320490189181487339214729826066835837672049688100168408474347489703263501235673127650137912948504894587435037415744638678725164306514003095509145029061174208723701938913556931333725924652312488553146924759556045539908779571271038920369379384399226275809025810057074240882223697618322034007917699963844421114824476140411345590096545302240636377177187020358290303577276552322411454265182323794687185542074942022572266238370649012950413555989200718138365268683487097988644450658655181102491544545655042894667308802486563503778421424153005375584405596513291902302149845732903316701278638793581511177000236705781774659900564257925220959731403438340289827164715993443926003423394689057228702562373943457863087275863650819958255969762610914264517450971690855704016426257358314813664509857741415941316506128290611552276572088864088294053905547171732130263209749414669478625938708017562390064926056124056813410191671060764992770440267519764430639548489279262469728859167482294099806971062488069955917017177878610021596386778571854421530952314677584556101650369463348474437652986953294371782897732886620895393559913536745002378907107397623289330221020008637244254508818159417215831571008758688520134266731034388898776868430480925832465313433176860929624653011076627911512058846327191974265140054931635236810755219406792827757210626548006040197167789900943507990592696506513283997782321381240894429143168541984993168115285260800792413823169371882231051804024841938989833960652897051636467905557095565172761454445790417607331018135829897872568406944853233635371185772392451628592045564519227659306413721480278380881944769468709202961802139865880316717447765494758026725836681096869514455422541531667394878746835641804573829085813263746735476908575580541784339422862041959644795941308244098945400850648489081300388274612469186645875349411184108880263452786303336857661919069281591754354396601781947029122923556800479458515197142415737631078120466021355632883402746280536061536130214727672414352613883760168595497353655129862015548514838676853597174457366553025714435547168860134584506385115302761022384095650567743310346728437202934783107669319111788895980849725588720202551604578515451480175783843594978389555156508646634910071245536780497749735758360995656338768589738669901942679411158287255977963916180304218277847572280864132898230730059819320645099908971587650476165682204322695567194189487114714357543757177010177338378845374547428783436064507954173716820240603308588336862363678877246462282210693590507549209888250214358810775151395795071244868312324031645771302243770983831098326324093837607742513965021413766127093040332255115267166457119589304659292237802161811278512299745584721413077592771482070791136759621503851182734228195584983704927377119805618944043699293996788339209258903008175843923343147510457629824910950407592394366405319350407850063954198864766814533709525103269478298655339522636599821444352862621013335628919927569126285544910236191621081179819957541356303776993632332504216130373677013127080310420452083177106127834192744404709103368691192974925509382905831579762820631682611824464819558558241201740571264016642212709072086295903265781709129936433620146998826074724933660747588736388246708320552535353779752391961756074526759778577727779828634978756728129280688479272960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
https://www.programiz.com/kotlin-programming/operator-overloading
Filter usage collections
public class ListExamples {
public static void main(String[] args) {
List<Customer> customers = new ArrayList<>(List.of(
new Customer("Petras"),
new Customer("Ona"),
new Customer("Birute")
));
customers.add(new Customer("Petras"));
System.out.println("----------------------------");
customers.forEach(System.out::print);
IntStream intStream = IntStream.range(1, 100);
intStream.filter(v -> v < 100)
.mapToDouble(v -> v % 20)
.forEach(System.out::print);
}
}
//--------------------------------------------Java-----------------------------------------------//
package listOfNumbers
// In JAVA CUSTOMER CLASS AROUND 100 lines with basic methods:)
data class Customer(val name: String)
fun main(args: Array<String>) {
val customers = ArrayList<Customer>(listOf<Customer>(
Customer("Petras"),
Customer("Jonas"),
Customer("Jonas")
))
customers.add(Customer("Ona"))
println("--------------------------------")
customers.forEach { print(" " + it.name) }
// number 1 to 100 similar to IntStream in JAVA
val numbers = 1..100
numbers.filter { it < 100 }
.map { it % 20 }
.forEach { print(" " + it) }
}
//--------------------------------------------Kotlin-----------------------------------------------//
Singleton Design pattern
Klasikinis projektavimo šablonas Singleton naudojant java programavimo kalbą.
package singletonai;
public class Singleton {
private static Singleton instance = null;
protected Singleton() {
// Exists only to defeat instantiation.
}
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
//--------------------------------------------Java-----------------------------------------------//
To pačio projektavimo šablono aprašymas naudojant programavimo kalbą kotlin.
package singletonai
object SingletonObject{
val property = "kazkas"
}
//--------------------------------------------Kotlin-----------------------------------------------//
https://github.com/eif-courses/kotlin-spring-realworld-example-app