[python 3.8][1], <sup><strike>161</strike></sup>169+1+<sup><strike>287</strike></sup>289+<sup><strike>267</strike></sup>193+6985=<sup><strike>7702</strike></sup> 7637 === ``` lang-python from zlib import decompress as D from itertools import product as P from functools import reduce as R x=289 c='AGCU' d=open('f','rb').read() print(eval(D(d[:x]))(d[x:])) ``` where `D(d[:x])` is ``` lang-python (lambda f, rest_len=[265,7,8,24,50,10,6,134,14,24,229], genes_len=[7097,1274,276,76,223,62,122,122,420,39], cut=lambda s,x:R( lambda acc,n:[acc[0][n:],acc[1]+[acc[0][:n]]], x,[s,[]])[1], cut_out=lambda x,n:x[:n]+x[n+1:], C=[''.join(i) for i in P(c,repeat=3)]: cut_out(''.join(i+''.join(j) for i,j in zip( cut(''.join(c[(i//r)%4] for i in f[:193] for r in [1,4,16,64]),rest_len), cut([C[i-32] for i in D(f[193:])],genes_len)+[[]]) ),13468) ) ``` and the file `f` is [here][8] (produced with decode_1.py). [Try it online!][9] Posted here only to show grouping [nucleotides][2] approach as the decoder overhead is very large. So let's start with the explanations. As can be seen form [MN908947][3], the virus [mRNA][4] contains "head" (265 nucleotides), "tail" (229 nucleotides) and [translated][5] parts with some non-translated parts between them. So, we have 10 genes, named orf1ab, S, ORF3a, E, M, ORF6, ORF7a, ORF8, N, ORF10 in [the link][3] above. It comes out we could use [codon usage bias][6] as the picture of frequency codon (=nucleotide triples) usage is very impressive, e.g. for `orf1ab`: <img src="https://svgur.com/i/Mk0.svg" /> or for `S` (looks very similar): <img src="https://svgur.com/i/M40.svg" /> and for `N` (looks different): <img src="https://svgur.com/i/M3e.svg" /> More precisely, here's the table of normed [covariance][7] of the codon usage distributions: ``` orf1ab S ORF3a E M ORF6 ORF7a ORF8 N ORF10 orf1ab 1.0000 0.9243 0.7458 0.4237 0.4813 0.5143 0.6391 0.6897 0.5035 0.3201 S 0.9243 1.0000 0.7077 0.3834 0.4596 0.5266 0.6513 0.6451 0.5371 0.3519 ORF3a 0.7458 0.7077 1.0000 0.4683 0.5483 0.4119 0.5713 0.5957 0.3464 0.2862 E 0.4237 0.3834 0.4683 1.0000 0.2966 0.2057 0.4727 0.2994 0.0318 0.2621 M 0.4813 0.4596 0.5483 0.2966 1.0000 0.2495 0.3799 0.3432 0.2975 0.1776 ORF6 0.5143 0.5266 0.4119 0.2057 0.2495 1.0000 0.3737 0.3459 0.1980 0.3125 ORF7a 0.6391 0.6513 0.5713 0.4727 0.3799 0.3737 1.0000 0.5232 0.3223 0.2362 ORF8 0.6897 0.6451 0.5957 0.2994 0.3432 0.3459 0.5232 1.0000 0.2049 0.0902 N 0.5035 0.5371 0.3464 0.0318 0.2975 0.1980 0.3223 0.2049 1.0000 -0.0203 ORF10 0.3201 0.3519 0.2862 0.2621 0.1776 0.3125 0.2362 0.0902 -0.0203 1.0000 ``` So we want to compress these genes. Here's the comparison of compression approaches: ``` arithm .lzma .xz zlib a.ovh len 0:orf1ab 4925.7 5261 5308 5083 86.5 7097 1:S 879.5 1047 1092 940 59.1 1274 2:ORF3a 191.4 276 324 237 37.4 276 3:E 47.8 100 132 84 18.6 76 4:M 155.4 232 280 200 35.1 223 5:ORF6 36.9 86 120 70 15.4 62 6:ORF7a 81.2 143 184 124 25.2 122 7:ORF8 80.2 144 184 122 24.2 122 8:N 289.9 393 440 338 44.1 420 9:ORF10 22.5 64 96 47 11.6 39 ``` where `arithm` is arithmetical encoding and `a.ovh` is frequences compressed with fibonacci (+1 ending bit for each) -- the arithmetical encoding overhead. We see the comparison makes zlib a perfect candidate, as even if we compress all with arithmetical encoding, we would have left something like 193 bytes for writing the decoding overhead (versus zlib), which is highly unlikely to fit in there. Answering on [stux][10]'s comments: > However it looks like you need auxiliary tables to do so? Almost no. I can number out nucleotide triplets just like numbers at base \$4\$ of length \$3\$. `itertools.product` does the job well. But yes, we have to know what nucleotides do encode peptid amino-acids and which do not, for this we need [the first link][3]. However, it's rather tricky to get the right sequence for `orf1ab` because of it's code consists of \$2\$ overlapping sequences, which is rather rare in the real world, IMHO. They do overlap on the nucleotide at position \$13468\$ (see `join(266..13468,13468..21555)` in the above link), so we double this nucleotide, compress, and then cut it out after de-compression (with `cut_out`). Then we compress joined sequences of triplets (not separately because orf1ab+S is rather large compared to other parts and the encoding table (frequences) will not differ much for orf1ab+S compared to all peptid-coding parts joined). Also we compress the non-peptid-encoding parts because we also need them in the output. Joined too. Then we have to `cut` both sequences into apropriate pieces (pieces lengths are `genes_len` and `rest_len`) and interleave (with `for i,j in zip(cut(...,rest_len),cut(...,genes_len))`). \$269\$ is compressed non-peptid-encoding nucleotides length and \$6985\$ is compressed triplets length. Looking back at the comments it's left only to explain how `cut` works. The python `reduce` function takes \$3\$ argumets: function(accumulator,item), the sequence and the optional accumulator initial value. Then accumulator on the next step = function(accumulator on the previous step,item from sequence). In other words, `reduce` feeds the sequence into the function and returns the accumulator when the sequence runs out. E.g. a way to replace `math.prod`: `lambda z:reduce(lambda x,y:x*y,z,1)`. So the accumulator in this particular case is chosen to contain [the sequence to cut,array ot already cut pieces] and `acc[0]` is the sequence to cut, `acc[1]` is already cut pieces, so `acc[0][n:],acc[1]+[acc[0][:n]]` makes perfect sense now, doesn't it? And we need only the `reduce` return value at index \$1\$ (i.e. the pieces sequence). Did I answer all the questions?) [1]: https:// [2]: https://en.wikipedia.org/wiki/Nucleotide [3]: https://www.ncbi.nlm.nih.gov/nuccore/MN908947 [4]: https://en.wikipedia.org/wiki/RNA [5]: https://en.wikipedia.org/wiki/Translation_(biology) [6]: https://en.wikipedia.org/wiki/Codon_usage_bias [7]: https://en.wikipedia.org/wiki/Covariance [8]: https://drive.google.com/drive/folders/19-l1Tbg44H0Bc1TFXXPwfvS1HSuSESPO?usp=sharing [9]: https://tio.run/##dXxnW9xMEu33/RUkEwwGtaRRIGODAZtkg8HgwUYtdRtskochh7@@V6fqaLn3w919/AIzCq2Kp05V6/K@e3xxHmWXnf/@13cuznoeTk9sz8nZ5UWn21O58uLssuOurnqKq57F/8gBJ13X6V5cnF41R112LqrrsotDtvQQf31e/j@HdFx9hMMRX/9zNxNm@X/KmaGF5Q/fhv5Tzdihu/ZdXn6r/2Pad5X5077LoqB9Z@L6l6R95/xz@/ziY/1B1L7zZfvOpvWhxXH9m7H1J/WhRfFYH1v/YnEF@2G4fVe6@sy8/jTrnuCq7bvAVZv1EX7xL46pv2nV/2L95z2WgJ9T9Wn1waa8qS@Lm7m52fq3@nibLdUnxvXNy3ohrnV52m6vfj3bOqovXX@d4/w8el8fHG/VFwj2cUt9qCCtTy2L@o9qob5JfcOqhQvirln9S329zHb35uuD6j/LsP4zbZ/X5@Go@qCi/lnWly/wrPXZeb0Il@B29ecWotpXQVTxnH7rw4P6/BLH11es/L7K09vrbxBXfdlCpVvhWeKJT@1OfoZV16c7LGEAS@LdID1Tf2rCsf7jelVQTg4xPD/pao3buNXncpkp8RQbHzv1BXKqJzj@Vd8prDXrW/gF14R4IbF6DSUeBx9AX/7s9FD1XCZ/9KJl/Z3N8f041lafkVU/a2E5np/bsfrLWk6Z27xuD9X/l8dz9a09Tq3v6SATLAdfQPgBxIpzoZXsEOfXNuShMDyyfVSp4/IW@sqc6qkKoM76VlBr/FSL27R2zjM@SHKFpffzGWGC5dVgfYhIAXcs39RHeTVIiB8WXNWPESSqrdrGa70VlRpGUU5D8atn9/WP@ELV4TKs/kjFksWD01v1IooIN/gK11FPyEL9B/OBV3i7rgKz1dSRygYisMGtGgycymaw6/rCEFTerf8IrT5KUOrhuLpYfwRjkftl@jC4oE1URs6v3tdOUyUXtav5dLU@tFBDzUMxDuol2b09nm93ip76gPoyPlOTyQM1CTE7fm4yPFTpp/VU5/UnHAQ680Ht2lXRu/J/Xcng4aef9C@Egwon5XMaFxysASqp/Nw07SNSCaWQS6X2b/zd@zF95sC86GcSVgK9A@4WQAayPLs63AcDGtALBf7zLWQ2DSPRgGM8nGyk/qNQI8/sxxH/@qxiD9WK2lgZ5nomYkiR1msw6WJ96eIyVWspo7l1XTtCFQKMqRDEYPj57NIl1qb@@v//d6eRz1QPCItw@WhM1@GcWiKiTpV9Uu3DUE28fFqHuNJkv2AKCDuILeVn9QKx7XwYqldhGviL3Z@B7S6oy2V0a29PNYzBF6v6ca09X37R701e@3iV7uK88Fkd00rU@3Wv2ioy@ERrFPFuD1/Iig9phQWu@tDufKdZpWrLVbLzFasvnnewlhs1jCLJmTQgvEQPx2n4Eo5hkGMqxB@74@eul1SXFrquKnFPo64N80VwLqpfuOzFJ31iuFBGv7b1ZYJQA55vvYOacoQTtRGHtGH8pjojPsENIHwELnwGKZRldIif4lqFKrEIm@xlNVLB@2tXaiMYnWswlSTrQjUVkzDBFO2u6irPVYmyEKOxI4/7R2GAX35vYt2dZ3jOucaXIMIxtbd7o64oayjaQ7cD6sWlUWuS8Jc2nvYRqlezLWDTSAVIRTB7W53Fd2lXvRxP4bJhuN@jOgPMFsrJvSZYcXY7jqV0NdjjyhAN/CBvqWiCaA12ig8HT2j7CEbVpyZhaiyDT1buIGIq9tfq2j7WnIfUid@LfA/HrjDgtjSzAQcU6Z2mN/iSZPjai7vjWOcqNPkV1qzmAAcz2dYLhHSn4oYr@Gp3awX6yLJ9ZIk/mv2QaPE0FZTfUkPCTaEhGBQkJRk07Y7eXvZBGx8zhTY41cV646zonCBT4tlXVGWIVWV0pLfJMwEuEIkZJxiJJwp9FjgC3DAQQ5yA5Qk0@QBzP4EUt3og67M7LHxRxSr5zbQ7Jze6UIAMK/5qFYmVsYoOT1WGiJJAWRA7LACmIb8XqraswLKLg6w737dFTRr9aXl4HlwiHSBEtzTvZ/ny2ds9ZlZE1SAFZPI/me1gvAVlDLBXMKVB2FU5nTGh2pWtzm88/v6UBhnvFjUzluGi@rlxQKZQfhn01r9AtnYSVr0GF//HVVbn6h6SbCwX6TTT2GgUaoXJxQAAyNFYFOJjUZ7QbZl0fDh5NakhwOdrGrMQSWBcuDlQiBxvtjT@@fC9RgEv2GYH4nuzoAchbkj0qcZhUDDp@FwDuLd9qk4nD5JN6G3EP0WhH3D6SEehXJlet4EAi2dNdVm4hP/sLY6Mq1Yz39X1ZcSwQTAMvfhkdJhxGkcJRkrcDhx6SpNeXu63vsMTURKU271q9Sa7UVVWpkcXbEK1blwLKVuCU/Ab1tGPsLmG@y7t9a9p5EEcFT8OuprygnT4voVf56FLmAv0A5vNYgTIYnNBbbsMopsd2IKsCLAtI16Hzbj0xqwQRaXLiiYFeOf/9qttqXgG1Xqd/4Nz0z/wgOLlE4xqTIXjEmSg1rGamABnGEOZSMi8IcRD0sn3IapSnwfRNE/Mp5HfilykzBEwffod54TqDBJ4sjAZUeUDYOfVJD0@WFcUUVQf9QJBuTQCObwrx3bb53XOL9wO3CiRuDEF8czQFYwaWp7vKEK14f4nArjiZVJDmABqwc7jmjdxe4TmrLr6vqlGVgZva1DfUUiO74K4JaGz/w2kMb61oc/rY9RZxn1rt8c0xELpyLpwrzx8u5qq@2XV4tF3PcJIiVOqN0JIUJDEHdyi9UejS@GI/Zz7gcfcUiXCAWE8eTmssSWLvosNnGt@RWQtYL2Vu4bR1p5@jrWW9KmcYTymYeGU@CsAmBWgeNoeGj3QpQXBkx5symON1IilCB1SSyULa0zGXnIwwovr6@@HQZcE8IJqjmjq0T9NJ2KPuHeAKioIfsN9klWY0qJq3vs7At2YSwEUMZdaNCDM5gFFGKjb1do90tAetP5q4nTpwJyCxZIoUiA0jNgMtDu/v2puzQAiM7vUr6kQFiQBImChi5SdxIrPETphDNYsq8eaHPnArXc0kItXA0K4f5pfJMZCu1IvWj27io8h6bEeCpRFCBw7SwnZynTuEfErH4dD4EvmQs8qEhEIJoIckhVfVaNB63RSgUgt36E@nDGApbVWbyHDQVZh8cALcMFHPFq0BAMYhNsKRYE85ln9uuJK6AxFJgjvEDvuKLVz2CUEQMzKv/w64Aqt@rdgG78G5Z@x9PPvtIapbwhVXlfgLsJNmpGE0jtoUXSFGqZ4WNbyE@HUln@gu1@qTCslB@SXvD9DuKvu36tlBq4PpjgvINQC1pTp5TQzbPTwm5ZTKKJHBHctqDFdgaLOEIWO9bsMVlnBIkWJxfSAPpqLVAwFPE5qifQv1LCGjyZpsunpzS7MeRDBuJSKhsm2pbjUlD2/tcDGZerVDemZvhqMCIXDExALfRMKYrWqxlcX2/h8F37zk@ENKdDR1XKSTDApQWAVyapceBqCouxZsXLVOofkgajyAToRgXGWftGrANWYyGtqLQqibC/r/gBd7kAipxPE1ALTdyjgksLKl5QSgr0A/th4CjdHzYIkgPuaaFEfxUhcrvRSQNUuTAlHiFkDd8dDEdLcxgnZnxgOknU0iCpO@Kwh3rUgDjMPi5DAItzE7iE9xm3As17g5S9a@JQIulLfQkdlTvgAw85hflm6rRFJyBaIzQB8hOk8HvAcy1rVEi8TlcO1ggM1ZizAZyuziLDTg@Dhorv3auuivWBB1HCjGcq0Lhf0Cxdj1cEjQziLbRdfUmMw6yqeJ5uDW6db7Y5nRrVaImfRgqYDmz0UunyE67w8IopI1JOQkKpy7hl6@4v7n5DBCJtS4gqePQnUikWHd0iZ1m/gQR7Jb4h8@jQ2iI6xqHJRBYOoGpQChABdsydcNKC/wFfKAYh4SQtdSZKowEWeoZqld9da1tWZFxEpGdMoiUyYiTMsPN9/vYF4YKn2ywEsKe7vgSLmx69Z3BIUOKXE6kR1TSgBk0RGgOFlIUmnLOhRxCFYPtQ7VdmMLklyQaxYABbfYCVBHsCCRXyDGP1Hc4ytHmG95vFcnywPAmJ1xUqL8/2K7IT2kloCtFP@KEZ@rgsW43c/Tu/oHgjmyaDaLxxJ4kmglX2N@37pX2X0Bdrgc8PSzNYZb@L1mzx6i@cFeEn@6YIz84P5IAf4qOJHvVomReGZXG0Ihw30atFio1utyQVaSrK5gEimBcMM9YoChy4Q1BZ@aIJzUfIOVryJNb3TZzCgFIALhJTJdjSOSlb2Zy/qPbWsJeSXM19PX2CnkR8BAIoRJsz11ZHXCkVil1M0YpEJYdg23WMLIHvFNlIKR6pRIXOzpesNUiOwZXerGQFoAtjEoJgSwE2@AYZc5YOskooDEr3pXKXmIjV02dQNT4hrtqsxq4qh2mxdLyJlHcRXa7e9p@FICFqwnBlpj6x8S6trdRE0sjty2papFAbQWvuL5YyB54BFwIIQ5wt/SZxpNYUEFlVW2nenS/TlJ/0FPlv6YS2aqvQR65qPBy5RW99DkGdYMkqDEKVTOMjasbxWqYFHEIKg9fUSUjhC@oleHk81JuR0OGgdss/9yryaJGAXCBhLgkAiebE4qfIqxR@kCpXS9YcyB8Jg@PWNbebEvPsFDxOWGlOEFAIvaCPcExWNL1cdalRXaCjNswF8eKlOHQTjehYAmwRirwqQmkPUfrnEW7ekrqqasko9BRjA2JtKMTzoCFix3AzeEZ06HpPmE8hnCGzm6NcjewstmLhgaSk1QEagGs6j2Q3I4QPJA9RXSL1I92DxhAdlI8rFn/FA9zA2XA00FEJmvYZzXVGVKuDLENby/INE14zcMFRoP6oX@CoFvZm/0xACyjKPjo6XNcc4VA9FzvCQx2l7aB/lMHjMvPU717zl3SfGqJJVZPUGjgq0Df@Am0qvS7j6SFci/CXAanghDtKBMrLbvyi0/apRBUgSztnF89o3GdKFS62f/SRfly1MqK6FyzQqjqopeewtPDEqWLHGV7oEhF1peOGL@H5BrbpwZx9V7DBR11q2TX2Fm86eqRd6nFQCdsKYhekKp6cn1BsN4F3BbITYBGAnPSkyrTCWqjpWISPjCBUsHRXBK5YNlOQBN63vMPQd3jpC9jm@pZYzkN9ChBdMOInq2Iad/kXc00yvqx1V/hcbP8lHfXyL0IxCUtpWaAtY9EVcfKBhTRgt1x5KtQT1EWwBCRtwJCdHLqRtpYLNWtOCaqMvCAjWrJE2RtEB5kugrBSQM7hR8uezFAW53g6AxbIyqsz2r0F2CwAejaCI8B8iRev5HdgkZx/nuvrgRiqxlzGNFYWApBOGqVRRdBWicxCuke6NH9E1TC8UMkksS07VrvIINXfR2nyiuISfKjfUAFBiumRNncWH7xfIg6Neyi@NWqNzC2CFLBJtKkR3R3FE6T/uoMXkpjfPVeS4ZhVofqrIb/mGagcCS86XG6zOrkCpfubMX01zWTQSjI9rCsvjXkYD@Hg@qmaCFAmzyvxbvWPAJRsPghGAO/PrM1BDsUXevXo6YDeB/KR0IiyxqPSkzakaBgrMrJwAvqz@aDiVR2uAkyPSQrYs90H@2BPy44gQLp/bJMCottViFIvssQ63KLbBRGTRzDSJyIKOhpTmW8RNTb9TKhrUOAXTh7Rf3cAHGBJCT4K@dLmmJu6kRQ6TQj2NpICkWhXCea1p0Cr8y0LOMqhAa1W6gwFrAgigAkCFbWUpCUX3WdWgnDg85ulEWqdrLIlbmyQjq8vexy8qjar8ilMnt@80cJTsKUntVey8QRRc5nWlu3E/8MNoIhQGJCVQjWmhuSIZREPjdMk2nerFJxE7S/ZaOtBHioWN1VTt/Aq7RxVZ8ugRNyrWh6U2Dxr6a@wQRkbiy7bmkIHkQlyClUILFhh9//4Zer9uktrd@EcNhTZn/x@GaVp7QgYL28cw5LIHZBWMDdj5SqNOwb4NkJdNDgnDWvQOWFF6RWrdnzCdCSwf/LqBy6@kmrSKIr5@p4aTiUzEHSAsnG9k3MBrRrWtQCOdsDjV3pVaeY1OHvrBchZojyefCEOjZ/xnnCxR9MTsK3a0@wUJDRVrhURfFH2s1TPFQhbIDwIWZjQnqpeW5tTDijp@EUvzTlK@1RCS8fGrcJ@AEaeUq6x@W4SiBRiP/FKjP3xJQk74r@9Q/5RmVjm93FEHl/Ikdepg1r5ZpUTAN2cpeKHqB2wrbFgK9hUT9QhEDOsHSWJWRyz9IbhycFQKOjcejsCsoC1HJt40rc@Iqd@x7LFqa7DnwkwAm05xKqEkTI865Jlac181GCECVPHn71imjPRUmvbL9O2txgnjvgCpp9e8I1g/icrhjcSc8yt9Miu9wIDNebk/Ul@IggbVhPhLfqiYAbYpX9vJTUSC@UfgpnVNGp70SFFN7r/htAM1LmLMdGESkVo7Eki6v2h7WbAPIFTEvARk476MPNMLJJMIqVr0oz7@ePgCF0bEkcyPaFqkC2@ZBqR2WSVhnnT7VDY2nL5TN5OqXmrhFYg6foCHfLpWi3QkjK22cpWFTZhVy3JeT/VZn4rEp8HqR5jM1rXq0ac7LOM5zQGjNJwaCoI59poIbMraad5CILMkGaR3L3UyklsC5iLfmYSYBjau1AnwdZXsNlMAqw0SeW46b@uKUcvgBncGJ2IcgA6oCFiK5BHbNw536Fc/Er6f9zfly4FZJ71FwPG/aZr8YG9Ok1bZOoXB3TB0ukxtHEFHtMAurZOrcvILykfAEdYSAk4GyBOZ15BlgMyCuiAaWp4vFGELLeT61WsqTi6V6W67vSVPPbqpUb1k1SINcClF9uCH0meFUwtRE/1UbUpWEVQLH5YOTPiLkyoFp2ayqWaowWn6lvBStO723qzgcnNku8NtUgWC2f8JE3rIAS2kn/z@8SdLW3R4UNrqxMMP@La9O/qjRVTWAJB0WsWXoUsrbQY8TtKL45CChHyNSeDBXDNE7PSuUKv1ZgkK26bCYR/hN46FeJqZefVbYZ6thnbhFcTGhZYeAysjLDU8sXh4wGOMA@PIjEU6p9hE2G7OLglPmZ29@6UKL8KFjWZiaV8BROMfVYuTBwVnGSSjZ7sad1xTU8d3GkOEmwW1p3E8wORFCmNOl2aRIZKTGRIM@cM2@xdYnBDQ4Vs@r@A7RBP/gPUOY5VovLhpTbiipUqNpeSglLC3iGYu72FjCPAmB6qrossjlpq5iliyG8JhYZ@Y2b1yplX2bh6BHD6Z3KxiRR84ZpMO6K0EgEuTzRqtP6WMo7aEDDbKP0v@zZgEORXlUJgiRhsabI6rOE40lfYTiiIxnnz9e7vtdHk5i6IcLIXMnpYih67XGkyYlUhXoh0FLZMqN3Z3p/RD03IVNywn40P8OYfYgHEE8BjGzUCgMoe6o0@ECGaLm1M8R84i2Gg0KpgznVunq4ZMUiFnkoQDOuOkatbQzMsUdDM2WT425eGkhkVfqQAQhqEoqd4BNFxvii5vds4efMEB21LIXOdntQjOggktSrzp/n33Ful/VPVg4o0GKjxJrCZHYPzgLfFwrm0EmS7zqkHBFWiDA0oJTQOVR5c4o/y5z3yDhVaYKAwxPBGwEBF2Ih4nIi45VCVjdCgGzRWJqdbs7Ds1bCfju@/Z5c@@PZ7PkDwXYGqJ4a1eLgDnF/hFTc1ZBaQlXR0h90Z2VYJFFGrUQqkluR5sqgz6xCQJ4tvBq15aNC4nIxjZ5D3hFBRm7xFo/iEZh18Abh84alPS8SUJo4dovvReHpJbDjmuKL3Vy9lfr/xoEI7J1Gf/dvbzGqnht/9Ixitgd4NwBv2uZHWCrpAcPJHBdM@cQJAi2/28YFc0J@GGQjfv2yFISuMzdZKi4RN1nDFoukb6nLBrMTfbM/akSQPOVnCCSgIOxmma3mVgp2ni8eaJHpvpgFD7O8JOMXGsUUFCl38LB3aDmrFlBiECGVHAHaMo/eY5AyB1PFiYKL4/ZY/Vaw4qq47M3UwoxM0bEAvvqDHp0AJTNRKK5AiLKa4AZigkUMDRYZP/RpxMj98R7ziOJqc6m1gL6RuO6pLvJfzIpXWWtTsY08CHniQC/KIWE/6nwSdjVkhofdBesCEMomSP42S0CRsxqT3E/0JGLA8lufwVZLu5u76qca9CuMiT/Z12e1sfvUhnNZEIOPV2hbVcipHUKjIy4hxxMJaNFhmSw@paPxtwzI6dsO2eAMRj3L/gCF1mf3dIieJ5UGjVuGB8m7xfqqYhvZ1Eo3uVyfimkMGkfaT7IqNfsOZyibOx5tOm5lzxcRk0NWQjAiXrjIxUrLJVlUiw@aAxWmiIBrjY9tDBAB7p9xYkiZyejmJ8wbxRpJOb3ypJCRHEgc6cYBUA2jI2VXxjv6y641ibUd0HJafmBYfmG5yFR5/NNlEwf51XrIqfiKOR2q0hnVQZ@rcP0ljBj48QCvxuqYivTJqpii9Y8Tpqj9r6h6ZTNUXJx5IOXx7J5iXExyS4srSjUpGCVpzqeach62gvVh0QmSi3C26vX1pnn6dAB0hTR/D/KMvdUlF14Bgf6kucD2x@O0qavQXQLAcwZdg5YxHDlokUs6VaUJmSjYYSPKaXdeqFZLGzE@9fCxzrsC/DtU4YSb00paPPRAQyEFCeIwbsyiTVhaasID1We8qKMXLI2DZiZOC2jP5QLJI/ECIN@FuMCORMFjmUZ4L4lPxEYCdI9lYaYx2Z5SLdQNvCHwLApNgWgcQqKVzs7w0xK@RuHnCrAzz5G2TxEVF0VxcjFSqwpMF/PEOeZQSWgIm078362A05gYz6LriW0ggjVBSqax/NcIIz1jnjuYfB53@9Grml5xboA1sZeO5/OIZs7bJZnme7z6nxC@5PNFtLV7pguwRJNKkmWIBEuxr2pB8iBNXo3p8Onh0tvboeGlrjF9k5J3JLzYhlhq551KPrRnAKwmsi1gxzKOH5mBqW5SaILDoUkubvp9cWorGnb9mboXXJDpiCw8meZJsUjpnepiTklkqyWmY3OhffaNNIDF0uZmsCozo2P3waazq1FQfaRIGE5i77p7FRtpvEahE6Vr9PusGl2IohE6aM0LWrwdfNAIG6/dHi3HF4dAYP/MuSCtEp2d8j@Rcxd0fsWeKugJ4ZWzQ@GF@a6Tt/agZIexebmY4@Fv4yI1Q2f2jeNwJcMXcRLnAOJxrW5KfTOUKdvCGvYGZUdsKn5bdSMN@rgKAyi2GzenFtUtPQor3huluz@2nPCGdPStZ68djtRKCpJbAPZKGxCAhBZ6RZ03j7IjxBuf2X7XnPmgHN1JztPIs22f9YIEeqPHrtcefYRGZJwtqU3IB7bdWZ1jM1ngC@2kNCw5SrzqtLakvb1N1W@R56jubY8vQdS@Y1fJ1Lw888nt8R1kTGVJqhNc/5T8FZ2sRDMzN5UHpKoavjyKIkRmzUE2@EEtwfjvwEW384Vkb8Ag27goDDhBMsB1s0RNeUofE7BmyMUDoyKWX2psOB6Lz4v2qVAt1pP4Pse08WlRN4cM8iaLaBjTLcC@Y5HdMmjuwpSYanWGa72bP76THNpoInMCgktSWgbPGU8WJpM04hu9PQha71NsQeqGSbGxKqhYpKqKCCVFrFoVYtwbsao32TqAqS3az0RXYCqzucARLHMqQMsSKzcqvRogBfViT33E8YB8OcMHIcYyhoXLGGUxffYMzPnYm7dtVaBJc5XaIoL52SfYfm/Q3326gdt3EroBrzpJYndXYuO8kS9t0N5xVdur7BrqAwGTkDoIxZ9Q1SVcVmsvZEBsR@lcceUocKmvkntEJzTjSa/zUF2WuwflmXbisxyB/svBqNRgKO09F1BTtNNAikpCS@LKqmsJ@H/r6roxYYVBfoHhN1hNccPhdY65c31aSlURG/xcMtiyaHVA7WkhkJkvmGB5KNY98@tbtTmOxt9REfe4EOpyqogmsEnJeoGM993g5Isaf/INcJtt0SnRuT/XeyuUJGD@4lXy0vgw2sLjGkD0czIEdlW2fRD4wjA/MWkztCoYDwty4J/7bQD62w7TMAcC6l6tyFMNFSDt4dAyvmiE04prCfufkEtw9AxCatpXN6XfANPGM5@1uPEWoJGTlzW5s9374gzqbx987r7jJpO8ccWA3lb0zcFAO8SdMsDRm4UOX4JQ0ABvsSsmYvkTQm2p21/qaIUodAMNKm20IvLcD0954xm5ANkX2CZu4Ft7a7nKfHNizE65wNfFuOwstnDmSVGNVMZzS0VU4LkConAxyQj2ltz3LfXDbP0Bxwr4GUbiRDApBvEJPMhojMYtzAufe0AnbDsmxgRXXqmERqOQCRJRgMwDCaRCAA@1II9UImI0BORXPP3yhyBuIAA@uyww/lS9OhKQQwZzI2VOxdfiI45xC5kS4VBiXSiwlErX1VYZFiKLzidEQlNboMEaxxu5bsSckmP9DDEPmkcVxph8Y0e7bjRQTuEh04GPz/2k5u7JULR@iStBZtfGYfW3oRN2xj2iWwgBW6/EaUiTKmHCRV3EyxV09qYnlT4Eit1f/AFgMyFipoab5Dx9KwJCMvKZxcRFktTxDmIutXCF1Vz@sOuFwb/ISu7ll/8WbYbOAiSGsYV7BublHmwbgSRn3L1oN0wDFoWMlcg@EuednyWjSDxdi4LlclhpNxOsP6xHM2pOD0pAy@csihCrOpvhN2DjKFfAIBMFXh2SMVUrHpVuREJrYJZrRtIV4D5n9JhQXzqwsZXJB9ShQ@MrncwmBpFSSpep3JpihzJztMJK5Kg95yc5fh/mpZuzSE73fp5naZcJr7ulyzrTbio4XiMN3xt7IFSErVXc2Vxt5gehBzNTLYBM8EESU5JHoDjjbvzs7uNnuaOMUMWgVQQSwqpU5iTJOjRVxU3S8cSE4W077@9L2eiqv7Kp/ceD7itE/Zt3fGDmOWPxEkS58dECRbYXoruS3NtTtP31hkYwTBpNjWgEkI2RdqHre9VlMF31lgA@mKYi4e9JjsBE0l/n/9bUjoChqZ7uEgbxVsn6hqDdp@rrU9KNkTg3wSwKIBomGhv7MG5B7fXuhiJVz4oy45XOnrsDtQgfWSuEbUIpRESzgnwJ/0WaO@VN/VQbszx9cveBaJ3qy2O9s7TSP/FafKFFxKXF28BfxLLfsoTSsThuHIvUowIqMkOBjVowyG8ELSAIXhR@/YtOLsv@GEg3By9V/3nE/NjecsTEW0Zj5M9k@2h46/s5UACF8V3wePh2leMWc94lUS6OjRlangh0XCOFwML7EQH4GkJN1ie451DTXU9/qHIx8t1bs0U8llShVGMlYm0LFw35LNH1ao/gIXbYY@pH2SXyptmUm0kWGKX9eMtWDli6Ymz9vtQW5HFvi@x1kX93WNc3Bl2lmldkyXQ34xu6GxcGWz8Y@H9rnEZviV/TRDgIxuSIqmuHUfXnFzyV0WFpPQeUBihwOrMsIZ9pEKDhUZG60HhjTbunSXpH8yDIxhYu6YiploZPcT54jkdHilnbhlEDAzdz/@t2@Em75IZATxyt6ark76gtgXX/jhTa4N24gdoHsKgWfAsjLaBHwlu8GA8mXUVzYgGLJteAr0S5BVfM70qLsfcY@Lp9kcl5y8OH7L@qxc@faWYz@W@KRkpAqvt2Zl/u2t4v0cxFeRNWzic9NLWFRhaUX4Uw/JitFDjfVF9Z0EVNI@3/3EBBd8@MwhYbITwrgWtwN/x7hJsHTAg9WJDDJgL2bw8XXSTCbL/Rc8wwl5VAi1CqUR9fZzHzbEmKuBpBlWYjtbJtr@NiAd4XVr9LUoR8DKk77hde6fkLBtbsgJ@Asl@/GHTLtxF5Vsn7PyWpindgcMZoBEIR0L4YX3H3ZfdyoLU8YXfIjUZIx6FPWmub5pfb1QtzQ5BhuEljTDHOMzfyUWjUMYyeoCB51zs8mpgcJ9/MOWQIvNI6STMjyahmYf1a8Dt8bxEzkStJl0Kuj2ZTE50D7fUo9I/czR4ARliLIWOx6yOu0Mc1eezFTgCSpsoQmm1ZJkZwZqgipYhXHkF6PqRhW3@OVmp3kfjaRE7F1x@QtnegSbnKKQMA@zRARCqiCKOvi3ANQAo9v2dI7tUom2p7cn3Vl5k8Yl93em82ibyQt3sqYNTC1Infe5IVP7ue0yIjdnVS4yt@Gp8gzsfFl8@tsrQ6XjP2kzJb3G9SBF490AMgrsJqTthL82ZolQq98cKaxgKWVGalkGE6pegOJhVjay30NY6Jj2KBvI0G8tD1@Zi6a2z8OB52ZQ5qV5ZcU93n8kOzIDTvoEn4/1XMHJEuev9Y@SMpHWH7WYlX/ZnJEuz5s7Gm25OKxpsczljQ1P3IafceNDss2dQXKebDF8RjVY2b8YHEZvo@SOF@E8q7XRXSy1BP@PaXeISLh/2Y4qHIBs8INOZQoa3ujDgyV6bsb3NInxf9O3JKSTTXVPFtkz/3lagmxQ4N40nzY2hJs@KCSxPv7APgtYZNPA@PRg6h37o8ksI5Jd1IuUoFhdhGxcPf6afX25hUyxCsZMmPud4g6ZLMlXUWfjZTyyl67Z2IKZuzzE2CaIvAaqV9zKZCtONJSY6aow9IyQAZssOIAooRS@jykU35i/o6h0vvkZycbhVRkCMOyTTFOurhy9vgQBziN7H/DmIRmWI2IrWy21hLzs6CcmhDKkPi57JGSCJWrJtP41Jw@at@pEz5NsV2X6IDIkBIRXuVmUrr77E9Ev2yKUDDktk7H5ajS1SS7nWzr0hSeYPio2mk2NJNsz7JQvZT/uLlNP8XHxH@k47u0WsBJys4i8Wuw366G46UfPc2zEs/bXl0d02SJsqf4qS5ctiG3TUY46QCcu5PRMznZU/DpVVnEPgpM@4ChYIn@1omBIrN3qUxj7m6Ubd406O4CJdnSdrLl9/7VJi/Nqt7I/GMbcup9Urr@/V5N0Vbz7joOzZls1CrBmqUXey8l/yXi/hAnk653KVOa5gPazXr5ZJTy5grk1s36Z/pONjK2DR12@WAws2cr@iRHU0jKFAk5MyCNSuxhT0541jBqca6n7J7vCCyZm4u/l2frvC0juWOkLJ5OokJq7QtQK385gI3hy1sNtnhFdNmL3L097OPsCe0mx0xk7arOmV@rXiexTAqqItHPKSlj2CkMieFudECb2fyXxkdYdQEfCrMVqXdBtyqq7LrjaeGWaDLJGvV8O1ScCTAYLtg@4tdnRjBM3y1kkQ5rCkkGWzRqVmqQH0eDzA3YIMm5sYToVBgZbkSU2OU4XVej0gEkw0oac4raRHJ2YNB15N0X/8dw1TKBhtHo5R1NF0IRY7hJWWYIJcnscchdwj2aoEMjBL40u8pW8c2t0izuAPAuBFt8m0LiE7KA5wwYqwWIGCD1Imk4IMV7zcqmC@L8OpV0E5ACUHEY7CreSYxTU9/@Dc75wpl62PcpWp5EjFlB1Or/im0BklIVvkwlqUIzxd8jLiq4WfirzkEf7u9no@BRekhAd7X3lcIek4@H3ApyurvbQRgla7NXKcKDQlAWLM6/GVmRj2IknCU/ajH8PkfbMHqGsb1qFHi9xERcHJyOTUo5wueAmXMEKeDVPhRaxvPUDXoVXj7jmpWruZvKRc3XCey1waqqU/QuXelqgvf4uudv8nZoAQK3n/gUpxzhGIfNYHPvJ2PY14bJm3UrKWOmvrKqyK76cryymHuhx0aiMCs8jpAPzF3HT7iSHLgP/ort/7K7IXoqJr0pNWbz9Q8Y0EG9D2S62yckUIZVln9p@M0PJUAN7CLbfqfRTvFevCtRMLPkQGRyWcjBie7hkLzflIKS8ScoM7zZvyuEUBGdlg6DbPk@/CyW7c/obbnrX1CuoSlooliSjCatwBIoxx/sbchDgsv8cm9Vl9LFcbkaRrGC7j9hAJqMJ8p4uzF/IcGuLLzcBvynlFx1ZXuAi0eFCRgKqof9cdk7Ou8PupjgdXhyufkzeHY6M1D/vJuuf/PLUnQ9XI6Nm1CT5yH//@38A [10]: https://codegolf.stackexchange.com/users/95705/stux