diff --git a/circuits/.yarn/install-state.gz b/circuits/.yarn/install-state.gz index f2622c32..76cf7b67 100644 Binary files a/circuits/.yarn/install-state.gz and b/circuits/.yarn/install-state.gz differ diff --git a/circuits/circuits/dsc/instances/dsc_rsa_sha256_65537_4096.circom b/circuits/circuits/dsc/instances/dsc_rsa_sha256_65537_4096.circom index 7c97beb1..728c2b93 100644 --- a/circuits/circuits/dsc/instances/dsc_rsa_sha256_65537_4096.circom +++ b/circuits/circuits/dsc/instances/dsc_rsa_sha256_65537_4096.circom @@ -2,4 +2,4 @@ pragma circom 2.1.9; include "../openpassport_dsc.circom"; -component main { public [ merkle_root ] } = OPENPASSPORT_DSC(10, 64, 32, 64, 64, 1664, 256, 12); \ No newline at end of file +component main { public [ merkle_root ] } = OPENPASSPORT_DSC(10, 64, 32, 120, 35, 1664, 256, 12); \ No newline at end of file diff --git a/circuits/circuits/tests/utils/rsa/test_rsa_sha1_65537_2048.circom b/circuits/circuits/tests/utils/rsa/test_rsa_sha1_65537_2048.circom index 17070da2..ed6026ea 100644 --- a/circuits/circuits/tests/utils/rsa/test_rsa_sha1_65537_2048.circom +++ b/circuits/circuits/tests/utils/rsa/test_rsa_sha1_65537_2048.circom @@ -1,14 +1,13 @@ pragma circom 2.1.9; -include "../../../utils/circomlib/signature/rsa/verifyRsaPkcs1v1_5.circom"; +include "../../../utils/circomlib/signature/rsa/verifyRsa65537Pkcs1v1_5.circom"; template VerifyRsaPkcs1v1_5Tester() { signal input signature[32]; signal input modulus[32]; signal input message[32]; - - VerifyRsaPkcs1v1_5(3, 64, 32, 65537, 160)(signature, modulus, message); + VerifyRsa65537Pkcs1v1_5(64, 32, 160)(signature, modulus, message); } component main = VerifyRsaPkcs1v1_5Tester(); \ No newline at end of file diff --git a/circuits/circuits/tests/utils/rsa/test_rsa_sha256_3_2048.circom b/circuits/circuits/tests/utils/rsa/test_rsa_sha256_3_2048.circom index 4ef66d72..d5a08d08 100644 --- a/circuits/circuits/tests/utils/rsa/test_rsa_sha256_3_2048.circom +++ b/circuits/circuits/tests/utils/rsa/test_rsa_sha256_3_2048.circom @@ -1,14 +1,13 @@ pragma circom 2.1.9; -include "../../../utils/circomlib/signature/rsa/verifyRsaPkcs1v1_5.circom"; +include "../../../utils/circomlib/signature/rsa/verifyRsa3Pkcs1v1_5.circom"; template VerifyRsaPkcs1v1_5Tester() { signal input signature[32]; signal input modulus[32]; signal input message[32]; - - VerifyRsaPkcs1v1_5(13, 64, 32, 3, 256)(signature, modulus, message); + VerifyRsa3Pkcs1v1_5(64, 32, 256)(signature, modulus, message); } component main = VerifyRsaPkcs1v1_5Tester(); \ No newline at end of file diff --git a/circuits/circuits/tests/utils/rsa/test_rsa_sha256_65537_2048.circom b/circuits/circuits/tests/utils/rsa/test_rsa_sha256_65537_2048.circom index 871207e0..b24e420a 100644 --- a/circuits/circuits/tests/utils/rsa/test_rsa_sha256_65537_2048.circom +++ b/circuits/circuits/tests/utils/rsa/test_rsa_sha256_65537_2048.circom @@ -1,6 +1,6 @@ pragma circom 2.1.9; -include "../../../utils/circomlib/signature/rsa/verifyRsaPkcs1v1_5.circom"; +include "../../../utils/circomlib/signature/rsa/verifyRsa65537Pkcs1v1_5.circom"; template VerifyRsaPkcs1v1_5Tester() { signal input signature[32]; @@ -8,7 +8,7 @@ template VerifyRsaPkcs1v1_5Tester() { signal input message[32]; - VerifyRsaPkcs1v1_5(1, 64, 32, 65537, 256)(signature, modulus, message); + VerifyRsa65537Pkcs1v1_5(64, 32, 256)(signature, modulus, message); } component main = VerifyRsaPkcs1v1_5Tester(); \ No newline at end of file diff --git a/circuits/circuits/tests/utils/rsa/test_rsa_sha256_65537_3072.circom b/circuits/circuits/tests/utils/rsa/test_rsa_sha256_65537_3072.circom index 7fc6015a..63a6a228 100644 --- a/circuits/circuits/tests/utils/rsa/test_rsa_sha256_65537_3072.circom +++ b/circuits/circuits/tests/utils/rsa/test_rsa_sha256_65537_3072.circom @@ -1,14 +1,13 @@ pragma circom 2.1.9; -include "../../../utils/circomlib/signature/rsa/verifyRsaPkcs1v1_5.circom"; +include "../../../utils/circomlib/signature/rsa/verifyRsa65537Pkcs1v1_5.circom"; template VerifyRsaPkcs1v1_5Tester() { signal input signature[32]; signal input modulus[32]; signal input message[32]; - - VerifyRsaPkcs1v1_5(14, 96, 32, 65537, 256)(signature, modulus, message); + VerifyRsa65537Pkcs1v1_5(96, 32, 256)(signature, modulus, message); } component main = VerifyRsaPkcs1v1_5Tester(); \ No newline at end of file diff --git a/circuits/circuits/tests/utils/rsa/test_rsa_sha256_65537_4096.circom b/circuits/circuits/tests/utils/rsa/test_rsa_sha256_65537_4096.circom index 78210acf..a147474d 100644 --- a/circuits/circuits/tests/utils/rsa/test_rsa_sha256_65537_4096.circom +++ b/circuits/circuits/tests/utils/rsa/test_rsa_sha256_65537_4096.circom @@ -1,14 +1,13 @@ pragma circom 2.1.9; -include "../../../utils/circomlib/signature/rsa/verifyRsaPkcs1v1_5.circom"; +include "../../../utils/circomlib/signature/rsa/verifyRsa65537Pkcs1v1_5.circom"; template VerifyRsaPkcs1v1_5Tester() { - signal input signature[64]; - signal input modulus[64]; - signal input message[64]; + signal input signature[35]; + signal input modulus[35]; + signal input message[35]; - - VerifyRsaPkcs1v1_5(10, 64, 64, 65537, 256)(signature, modulus, message); + VerifyRsa65537Pkcs1v1_5(120, 35, 256)(signature, modulus, message); } component main = VerifyRsaPkcs1v1_5Tester(); \ No newline at end of file diff --git a/circuits/circuits/tests/utils/rsa/test_rsa_sha512_65537_4096.circom b/circuits/circuits/tests/utils/rsa/test_rsa_sha512_65537_4096.circom index c7ccc324..6bcb5eec 100644 --- a/circuits/circuits/tests/utils/rsa/test_rsa_sha512_65537_4096.circom +++ b/circuits/circuits/tests/utils/rsa/test_rsa_sha512_65537_4096.circom @@ -1,14 +1,13 @@ pragma circom 2.1.9; -include "../../../utils/circomlib/signature/rsa/verifyRsaPkcs1v1_5.circom"; +include "../../../utils/circomlib/signature/rsa/verifyRsa65537Pkcs1v1_5.circom"; template VerifyRsaPkcs1v1_5Tester() { - signal input signature[64]; - signal input modulus[64]; - signal input message[64]; + signal input signature[35]; + signal input modulus[35]; + signal input message[35]; - - VerifyRsaPkcs1v1_5(15, 64, 64, 65537, 512)(signature, modulus, message); + VerifyRsa65537Pkcs1v1_5(120, 35, 512)(signature, modulus, message); } component main = VerifyRsaPkcs1v1_5Tester(); diff --git a/circuits/circuits/utils/circomlib/bigInt/bigInt.circom b/circuits/circuits/utils/circomlib/bigInt/bigInt.circom index 57cd600a..f52da7fc 100644 --- a/circuits/circuits/utils/circomlib/bigInt/bigInt.circom +++ b/circuits/circuits/utils/circomlib/bigInt/bigInt.circom @@ -236,7 +236,7 @@ template BigMod(CHUNK_SIZE, CHUNK_NUMBER){ signal input base[CHUNK_NUMBER * 2]; signal input modulus[CHUNK_NUMBER]; - var long_division[2][200] = long_div(CHUNK_SIZE, CHUNK_NUMBER, CHUNK_NUMBER, base, modulus); + var long_division[2][200] = long_div_dl(CHUNK_SIZE, CHUNK_NUMBER, CHUNK_NUMBER, base, modulus); signal output div[CHUNK_NUMBER + 1]; signal output mod[CHUNK_NUMBER]; @@ -366,7 +366,7 @@ template PowerMod(CHUNK_SIZE, CHUNK_NUMBER, EXP) { signal output out[CHUNK_NUMBER]; - var exp_process[256] = exp_to_bits(EXP); + var exp_process[256] = exp_to_bits_dl(EXP); component muls[exp_process[0]]; component resultMuls[exp_process[1] - 1]; @@ -422,7 +422,7 @@ template BigModInvOptimised(CHUNK_SIZE, CHUNK_NUMBER) { signal output out[CHUNK_NUMBER]; - var inv[200] = mod_inv(CHUNK_SIZE, CHUNK_NUMBER, in, modulus); + var inv[200] = mod_inv_dl(CHUNK_SIZE, CHUNK_NUMBER, in, modulus); for (var i = 0; i < CHUNK_NUMBER; i++) { out[i] <-- inv[i]; } @@ -642,7 +642,7 @@ template BigModNonEqual(CHUNK_SIZE, CHUNK_NUMBER_BASE, CHUNK_NUMBER_MODULUS){ signal input base[CHUNK_NUMBER_BASE]; signal input modulus[CHUNK_NUMBER_MODULUS]; - var long_division[2][200] = long_div(CHUNK_SIZE, CHUNK_NUMBER_MODULUS, CHUNK_NUMBER_DIV - 1, base, modulus); + var long_division[2][200] = long_div_dl(CHUNK_SIZE, CHUNK_NUMBER_MODULUS, CHUNK_NUMBER_DIV - 1, base, modulus); signal output div[CHUNK_NUMBER_DIV]; signal output mod[CHUNK_NUMBER_MODULUS]; @@ -759,7 +759,7 @@ template PowerModNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, EXP) { signal output out[CHUNK_NUMBER]; - var exp_process[256] = exp_to_bits(EXP); + var exp_process[256] = exp_to_bits_dl(EXP); component muls[exp_process[0]]; component resultMuls[exp_process[1] - 1]; @@ -814,7 +814,7 @@ template PowerModNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, EXP) { // those are very "expensive" by constraints operations, try to reduse num of usage if these if u can // in[0] < in[1] -template BigLessThan(CHUNK_SIZE, CHUNK_NUMBER){ +template BigLessThan_dl(CHUNK_SIZE, CHUNK_NUMBER){ signal input in[2][CHUNK_NUMBER]; signal output out; @@ -892,7 +892,7 @@ template BigGreaterEqThan(CHUNK_SIZE, CHUNK_NUMBER){ signal output out; - component lessThan = BigLessThan(CHUNK_SIZE, CHUNK_NUMBER); + component lessThan = BigLessThan_dl(CHUNK_SIZE, CHUNK_NUMBER); lessThan.in <== in; out <== 1 - lessThan.out; } diff --git a/circuits/circuits/utils/circomlib/bigInt/bigIntFunc.circom b/circuits/circuits/utils/circomlib/bigInt/bigIntFunc.circom index 704f3209..c10702ee 100644 --- a/circuits/circuits/utils/circomlib/bigInt/bigIntFunc.circom +++ b/circuits/circuits/utils/circomlib/bigInt/bigIntFunc.circom @@ -2,7 +2,7 @@ pragma circom 2.1.6; // @zkemail -function div_ceil(m, n) { +function div_ceil_dl(m, n) { var ret = 0; if (m % n == 0) { ret = m \ n; @@ -12,7 +12,7 @@ function div_ceil(m, n) { return ret; } -function log_ceil(n) { +function log_ceil_dl(n) { var n_temp = n; for (var i = 0; i < 254; i++) { if (n_temp == 0) { @@ -24,7 +24,7 @@ function log_ceil(n) { } // 1 if true, 0 if false -function long_gt(n, k, a, b) { +function long_gt_dl(n, k, a, b) { for (var i = k - 1; i >= 0; i--) { if (a[i] > b[i]) { return 1; @@ -40,7 +40,7 @@ function long_gt(n, k, a, b) { // a has k registers // b has k registers // a >= b -function long_sub(n, k, a, b) { +function long_sub_dl(n, k, a, b) { var diff[200]; var borrow[200]; for (var i = 0; i < k; i++) { @@ -67,7 +67,7 @@ function long_sub(n, k, a, b) { // a is a n-bit scalar // b has k registers -function long_scalar_mult(n, k, a, b) { +function long_scalar_mult_dl(n, k, a, b) { var out[200]; for (var i = 0; i < 200; i++) { out[i] = 0; @@ -85,16 +85,16 @@ function long_scalar_mult(n, k, a, b) { // b has k registers // assumes leading digit of b is at least 2 ** (n - 1) // 0 <= a < (2**n) * b -function short_div_norm(n, k, a, b) { +function short_div_norm_dl(n, k, a, b) { var qhat = (a[k] * (1 << n) + a[k - 1]) \ b[k - 1]; if (qhat > (1 << n) - 1) { qhat = (1 << n) - 1; } - var mult[200] = long_scalar_mult(n, k, qhat, b); - if (long_gt(n, k + 1, mult, a) == 1) { - mult = long_sub(n, k + 1, mult, b); - if (long_gt(n, k + 1, mult, a) == 1) { + var mult[200] = long_scalar_mult_dl(n, k, qhat, b); + if (long_gt_dl(n, k + 1, mult, a) == 1) { + mult = long_sub_dl(n, k + 1, mult, b); + if (long_gt_dl(n, k + 1, mult, a) == 1) { return qhat - 2; } else { return qhat - 1; @@ -109,19 +109,19 @@ function short_div_norm(n, k, a, b) { // b has k registers // assumes leading digit of b is non-zero // 0 <= a < (2**n) * b -function short_div(n, k, a, b) { +function short_div_dl(n, k, a, b) { var scale = (1 << n) \ (1 + b[k - 1]); // k + 2 registers now - var norm_a[200] = long_scalar_mult(n, k + 1, scale, a); + var norm_a[200] = long_scalar_mult_dl(n, k + 1, scale, a); // k + 1 registers now - var norm_b[200] = long_scalar_mult(n, k, scale, b); + var norm_b[200] = long_scalar_mult_dl(n, k, scale, b); var ret; if (norm_b[k] != 0) { - ret = short_div_norm(n, k + 1, norm_a, norm_b); + ret = short_div_norm_dl(n, k + 1, norm_a, norm_b); } else { - ret = short_div_norm(n, k, norm_a, norm_b); + ret = short_div_norm_dl(n, k, norm_a, norm_b); } return ret; } @@ -129,24 +129,24 @@ function short_div(n, k, a, b) { // beginning of the UNAUDITED section -function SplitFn(in, n, m) { +function SplitFn_dl(in, n, m) { return [in % (1 << n), (in \ (1 << n)) % (1 << m)]; } -function SplitThreeFn(in, n, m, k) { +function SplitThreeFn_dl(in, n, m, k) { return [in % (1 << n), (in \ (1 << n)) % (1 << m), (in \ (1 << n + m)) % (1 << k)]; } // in is an m bit number // split into ceil(m/n) n-bit registers -function splitOverflowedRegister(m, n, in) { +function splitOverflowedRegister_dl(m, n, in) { var out[200]; for (var i = 0; i < 200; i++) { out[i] = 0; } - var nRegisters = div_ceil(m, n); + var nRegisters = div_ceil_dl(m, n); var running = in; for (var i = 0; i < nRegisters; i++) { out[i] = running % (1 << n); @@ -163,7 +163,7 @@ function splitOverflowedRegister(m, n, in) { // all others are positive // - 1 since the last register is included in the last ceil(m/n) array // + 1 since the carries from previous registers could push you over -function getProperRepresentation(m, n, k, in) { +function getProperRepresentation_dl(m, n, k, in) { var ceilMN = 0; if (m % n == 0) { ceilMN = m \ n; @@ -176,13 +176,13 @@ function getProperRepresentation(m, n, k, in) { for (var j = 0; j < 200; j++) { pieces[i][j] = 0; } - if (isNegative(in[i]) == 1) { - var negPieces[200] = splitOverflowedRegister(m, n, - 1 * in[i]); + if (isNegative_dl(in[i]) == 1) { + var negPieces[200] = splitOverflowedRegister_dl(m, n, - 1 * in[i]); for (var j = 0; j < ceilMN; j++) { pieces[i][j] = - 1 * negPieces[j]; } } else { - pieces[i] = splitOverflowedRegister(m, n, in[i]); + pieces[i] = splitOverflowedRegister_dl(m, n, in[i]); } } @@ -210,7 +210,7 @@ function getProperRepresentation(m, n, k, in) { } } - if (isNegative(thisRegisterValue) == 1) { + if (isNegative_dl(thisRegisterValue) == 1) { var thisRegisterAbs = - 1 * thisRegisterValue; out[registerIdx] = (1 << n) - (thisRegisterAbs % (1 << n)); carries[registerIdx] = - 1 * (thisRegisterAbs >> n) - 1; @@ -231,7 +231,7 @@ function getProperRepresentation(m, n, k, in) { // out[1] has length k -- remainder // implements algorithm of https://people.eecs.berkeley.edu/~fateman/282/F%20Wright%20notes/week4.pdf // b[k-1] must be nonzero! -function long_div(n, k, m, a, b){ +function long_div_dl(n, k, m, a, b){ var out[2][200]; var remainder[200]; @@ -253,9 +253,9 @@ function long_div(n, k, m, a, b){ } } - out[0][i] = short_div(n, k, dividend, b); + out[0][i] = short_div_dl(n, k, dividend, b); - var mult_shift[200] = long_scalar_mult(n, k, out[0][i], b); + var mult_shift[200] = long_scalar_mult_dl(n, k, out[0][i], b); var subtrahend[200]; for (var j = 0; j < m + k; j++) { subtrahend[j] = 0; @@ -265,7 +265,7 @@ function long_div(n, k, m, a, b){ subtrahend[i + j] = mult_shift[j]; } } - remainder = long_sub(n, m + k, remainder, subtrahend); + remainder = long_sub_dl(n, m + k, remainder, subtrahend); } for (var i = 0; i < k; i++) { out[1][i] = remainder[i]; @@ -281,7 +281,7 @@ function long_div(n, k, m, a, b){ // a and b both have k registers // out[0] has length 2 * k // adapted from BigMulShortLong and LongToShortNoEndCarry2 witness computation -function prod(n, k, a, b) { +function prod_dl(n, k, a, b) { // first compute the intermediate values. taken from BigMulShortLong var prod_val[200]; for (var i = 0; i < 2 * k - 1; i++) { @@ -302,20 +302,20 @@ function prod(n, k, a, b) { var split[200][3]; for (var i = 0; i < 2 * k - 1; i++) { - split[i] = SplitThreeFn(prod_val[i], n, n, n); + split[i] = SplitThreeFn_dl(prod_val[i], n, n, n); } var carry[200]; carry[0] = 0; out[0] = split[0][0]; if (2 * k - 1 > 1) { - var sumAndCarry[2] = SplitFn(split[0][1] + split[1][0], n, n); + var sumAndCarry[2] = SplitFn_dl(split[0][1] + split[1][0], n, n); out[1] = sumAndCarry[0]; carry[1] = sumAndCarry[1]; } if (2 * k - 1 > 2) { for (var i = 2; i < 2 * k - 1; i++) { - var sumAndCarry[2] = SplitFn(split[i][0] + split[i - 1][1] + split[i - 2][2] + carry[i - 1], n, n); + var sumAndCarry[2] = SplitFn_dl(split[i][0] + split[i - 1][1] + split[i - 2][2] + carry[i - 1], n, n); out[i] = sumAndCarry[0]; carry[i] = sumAndCarry[1]; } @@ -331,7 +331,7 @@ function prod(n, k, a, b) { // k * n <= 500 // p is a prime // computes a^e mod p -function mod_exp(n, k, a, p, e) { +function mod_exp_dl(n, k, a, p, e) { var eBits[500]; for (var i = 0; i < k; i++) { for (var j = 0; j < n; j++) { @@ -350,18 +350,18 @@ function mod_exp(n, k, a, p, e) { // multiply by a if bit is 0 if (eBits[i] == 1) { var temp[200]; - temp = prod(n, k, out, a); + temp = prod_dl(n, k, out, a); var temp2[2][200]; - temp2 = long_div(n, k, k, temp, p); + temp2 = long_div_dl(n, k, k, temp, p); out = temp2[1]; } // square, unless we're at the end if (i > 0) { var temp[200]; - temp = prod(n, k, out, out); + temp = prod_dl(n, k, out, out); var temp2[2][200]; - temp2 = long_div(n, k, k, temp, p); + temp2 = long_div_dl(n, k, k, temp, p); out = temp2[1]; } @@ -376,7 +376,7 @@ function mod_exp(n, k, a, p, e) { // p is a prime // if a == 0 mod p, returns 0 // else computes inv = a^(p-2) mod p -function mod_inv(n, k, a, p) { +function mod_inv_dl(n, k, a, p) { var isZero = 1; for (var i = 0; i < k; i++) { if (a[i] != 0) { @@ -407,53 +407,53 @@ function mod_inv(n, k, a, p) { two[0] = 2; var pMinusTwo[200]; - pMinusTwo = long_sub(n, k, pCopy, two); + pMinusTwo = long_sub_dl(n, k, pCopy, two); var out[200]; - out = mod_exp(n, k, a, pCopy, pMinusTwo); + out = mod_exp_dl(n, k, a, pCopy, pMinusTwo); return out; } // a, b and out are all n bits k registers -function long_sub_mod_p(n, k, a, b, p){ - var gt = long_gt(n, k, a, b); +function long_sub_mod_p_dl(n, k, a, b, p){ + var gt = long_gt_dl(n, k, a, b); var tmp[200]; if (gt){ - tmp = long_sub(n, k, a, b); + tmp = long_sub_dl(n, k, a, b); } else { - tmp = long_sub(n, k, b, a); + tmp = long_sub_dl(n, k, b, a); } var out[2][200]; for (var i = k; i < 2 * k; i++){ tmp[i] = 0; } - out = long_div(n, k, k, tmp, p); + out = long_div_dl(n, k, k, tmp, p); if (gt == 0){ - tmp = long_sub(n, k, p, out[1]); + tmp = long_sub_dl(n, k, p, out[1]); } return tmp; } // a, b, p and out are all n bits k registers -function prod_mod_p(n, k, a, b, p){ +function prod_mod_p_dl(n, k, a, b, p){ var tmp[200]; var result[2][200]; - tmp = prod(n, k, a, b); - result = long_div(n, k, k, tmp, p); + tmp = prod_dl(n, k, a, b); + result = long_div_dl(n, k, k, tmp, p); return result[1]; } -function long_add_mod(CHUNK_SIZE, CHUNK_NUMBER, A, B, P) { - var sum[200] = long_add(CHUNK_SIZE,CHUNK_NUMBER,A,B); - var temp[2][200] = long_div2(CHUNK_SIZE,CHUNK_NUMBER,1,sum,P); +function long_add_mod_dl(CHUNK_SIZE, CHUNK_NUMBER, A, B, P) { + var sum[200] = long_add_dl(CHUNK_SIZE,CHUNK_NUMBER,A,B); + var temp[2][200] = long_div2_dl(CHUNK_SIZE,CHUNK_NUMBER,1,sum,P); return temp[1]; } -function long_add(CHUNK_SIZE, CHUNK_NUMBER, A, B){ +function long_add_dl(CHUNK_SIZE, CHUNK_NUMBER, A, B){ var carry = 0; var sum[200]; for(var i=0; i 10944121435919637611123202872628637544274182200208017171849102093287904247808 ? 1 : 0; } \ No newline at end of file diff --git a/circuits/circuits/utils/circomlib/bigInt/bigIntOverflow.circom b/circuits/circuits/utils/circomlib/bigInt/bigIntOverflow.circom index aa0a8632..5f453b08 100644 --- a/circuits/circuits/utils/circomlib/bigInt/bigIntOverflow.circom +++ b/circuits/circuits/utils/circomlib/bigInt/bigIntOverflow.circom @@ -229,12 +229,12 @@ template BigModInvOverflow(CHUNK_SIZE, CHUNK_NUMBER_BASE, CHUNK_NUMBER) { component reduce = RemoveOverflow(CHUNK_SIZE, CHUNK_NUMBER_BASE, CHUNK_NUMBER_BASE + 1); reduce.in <== in; - var div_res[2][200] = long_div(CHUNK_SIZE, CHUNK_NUMBER, (CHUNK_NUMBER_BASE + 1 - CHUNK_NUMBER), reduce.out, modulus); + var div_res[2][200] = long_div_dl(CHUNK_SIZE, CHUNK_NUMBER, (CHUNK_NUMBER_BASE + 1 - CHUNK_NUMBER), reduce.out, modulus); var mod[CHUNK_NUMBER]; for (var i = 0; i < CHUNK_NUMBER; i++){ mod[i] = div_res[1][i]; } - var inv[200] = mod_inv(CHUNK_SIZE, CHUNK_NUMBER, mod, modulus); + var inv[200] = mod_inv_dl(CHUNK_SIZE, CHUNK_NUMBER, mod, modulus); for (var i = 0; i < CHUNK_NUMBER; i++) { out[i] <-- inv[i]; diff --git a/circuits/circuits/utils/circomlib/signature/rsa/pkcs1v1_5Padding.circom b/circuits/circuits/utils/circomlib/signature/rsa/pkcs1v1_5Padding.circom new file mode 100644 index 00000000..67026719 --- /dev/null +++ b/circuits/circuits/utils/circomlib/signature/rsa/pkcs1v1_5Padding.circom @@ -0,0 +1,121 @@ +pragma circom 2.1.9; + +include "../../bitify/bitify.circom"; + +// PKCS1v1.5 Padding Scheme +// 0x00 || 0x01 || PS || 0x00 || OID || Hash +// PS is a sequence of 0xFF bytes that is padded so that the data to be signed matches the length of the key. +// OID is the object identifier for the hash function used. +// For SHA1, the OID is 0x3021300906052b0e03021a05000414 +// For SHA256, the OID is 0x3031300d060960864801650304020105000420 +// For SHA384, the OID is 0x3041300d060960864801650304020205000430 +// For SHA512, the OID is 0x3051300d060960864801650304020305000440 + +template Pkcs1v1_5Padding(CHUNK_SIZE, CHUNK_NUMBER, HASH_SIZE) { + signal input modulus[CHUNK_NUMBER]; + signal input message[CHUNK_NUMBER]; + + signal output out[CHUNK_NUMBER]; + + var OID_SIZE = getOIDSize(HASH_SIZE); + + signal paddedMessageBits[CHUNK_SIZE * CHUNK_NUMBER]; + + component modulusN2B[CHUNK_NUMBER]; + component messageN2B[CHUNK_NUMBER]; + signal modulusBits[CHUNK_SIZE * CHUNK_NUMBER]; + signal messageBits[CHUNK_SIZE * CHUNK_NUMBER]; + + for (var i = 0; i < CHUNK_NUMBER; i++) { + messageN2B[i] = Num2Bits(CHUNK_SIZE); + messageN2B[i].in <== message[i]; + for (var j = 0; j < CHUNK_SIZE; j++) { + messageBits[i*CHUNK_SIZE+j] <== messageN2B[i].out[j]; + } + modulusN2B[i] = Num2Bits(CHUNK_SIZE); + modulusN2B[i].in <== modulus[i]; + for (var j = 0; j < CHUNK_SIZE; j++) { + modulusBits[i*CHUNK_SIZE+j] <== modulusN2B[i].out[j]; + } + } + + for (var i = 0; i < HASH_SIZE; i++) { + paddedMessageBits[i] <== messageBits[i]; + } + + for (var i = 0; i < 8; i++) { + paddedMessageBits[HASH_SIZE + OID_SIZE + i] <== 0; + } + + var OID = getOID(HASH_SIZE); + for (var i = HASH_SIZE; i < HASH_SIZE + OID_SIZE; i++) { + paddedMessageBits[i] <== (OID >> (i - HASH_SIZE)) & 1; + } + + component modulusZero[(CHUNK_SIZE * CHUNK_NUMBER + 7 - (HASH_SIZE + OID_SIZE)) \ 8]; + { + var modulusPrefix = 0; + for (var i = CHUNK_SIZE * CHUNK_NUMBER - 1; i >= (HASH_SIZE + OID_SIZE) + 8; i--) { + if (i + 8 < CHUNK_SIZE * CHUNK_NUMBER) { + modulusPrefix += modulusBits[i+8]; + if (i % 8 == 0) { + var idx = (i - (HASH_SIZE + OID_SIZE)) \ 8; + modulusZero[idx] = IsZero(); + modulusZero[idx].in <== modulusPrefix; + paddedMessageBits[i] <== 1-modulusZero[idx].out; + } else { + paddedMessageBits[i] <== paddedMessageBits[i+1]; + } + } else { + paddedMessageBits[i] <== 0; + } + } + } + + assert(HASH_SIZE + OID_SIZE + 8 + 65 < CHUNK_SIZE * CHUNK_NUMBER); + + for (var i = HASH_SIZE + OID_SIZE + 8; i < HASH_SIZE + OID_SIZE + 8 + 65; i++) { + paddedMessageBits[i] === 1; + } + + component passedMessageB2N[CHUNK_NUMBER]; + for (var i = 0; i < CHUNK_NUMBER; i++) { + passedMessageB2N[i] = Bits2Num(CHUNK_SIZE); + for (var j = 0; j < CHUNK_SIZE; j++) { + passedMessageB2N[i].in[j] <== paddedMessageBits[i*CHUNK_SIZE+j]; + } + out[i] <== passedMessageB2N[i].out; + } +} + +function getOID(HASH_SIZE) { + if (HASH_SIZE == 160) { + return 0x3021300906052b0e03021a05000414; + } + if (HASH_SIZE == 256) { + return 0x3031300d060960864801650304020105000420; + } + if (HASH_SIZE == 384) { + return 0x3041300d060960864801650304020205000430; + } + if (HASH_SIZE == 512) { + return 0x3051300d060960864801650304020305000440; + } + return 0; +} + +function getOIDSize(HASH_SIZE) { + if (HASH_SIZE == 160) { + return 120; + } + if (HASH_SIZE == 256) { + return 152; + } + if (HASH_SIZE == 384) { + return 152; + } + if (HASH_SIZE == 512) { + return 152; + } + return 0; +} \ No newline at end of file diff --git a/circuits/circuits/utils/circomlib/signature/rsa/verifyRsa3Pkcs1v1_5.circom b/circuits/circuits/utils/circomlib/signature/rsa/verifyRsa3Pkcs1v1_5.circom new file mode 100644 index 00000000..c6fb9c94 --- /dev/null +++ b/circuits/circuits/utils/circomlib/signature/rsa/verifyRsa3Pkcs1v1_5.circom @@ -0,0 +1,82 @@ +pragma circom 2.1.9; + +include "../../../zkemail/lib/fp.circom"; +include "./pkcs1v1_5Padding.circom"; +include "../../bitify/bitify.circom"; + +// For 2048bits RSA, CHUNK_SIZE = 64, CHUNK_NUMBER = 32 +// For 3072bits RSA, CHUNK_SIZE = 64, CHUNK_NUMBER = 48 +// For 4096bits RSA, CHUNK_SIZE = 64, CHUNK_NUMBER = 64 + +// HASH_SIZE is the size of the hash in bits + +template VerifyRsa3Pkcs1v1_5(CHUNK_SIZE, CHUNK_NUMBER, HASH_SIZE) { + signal input signature[CHUNK_NUMBER]; + signal input modulus[CHUNK_NUMBER]; + + signal input message[CHUNK_NUMBER]; + + // 1. Add padding to the hashed message + component padder = Pkcs1v1_5Padding(CHUNK_SIZE, CHUNK_NUMBER, HASH_SIZE); + for (var i = 0; i < CHUNK_NUMBER; i++) { + padder.modulus[i] <== modulus[i]; + padder.message[i] <== message[i]; + } + + // 2. Check that the signature is in proper form and reduced mod modulus. + component signatureRangeCheck[CHUNK_NUMBER]; + component bigLessThan = BigLessThan(CHUNK_SIZE, CHUNK_NUMBER); + for (var i = 0; i < CHUNK_NUMBER; i++) { + signatureRangeCheck[i] = Num2Bits(CHUNK_SIZE); + signatureRangeCheck[i].in <== signature[i]; + bigLessThan.a[i] <== signature[i]; + bigLessThan.b[i] <== modulus[i]; + } + bigLessThan.out === 1; + + // 3. Compute the signature^exponent mod modulus + component bigPow = FpPow3Mod(CHUNK_SIZE, CHUNK_NUMBER); + for (var i = 0; i < CHUNK_NUMBER; i++) { + bigPow.base[i] <== signature[i]; + bigPow.modulus[i] <== modulus[i]; + } + + // 4. Check that the computed value is equal to the padded message + for (var i = 0; i < CHUNK_NUMBER; i++) { + bigPow.out[i] === padder.out[i]; + } +} + +/// @title FpPow3Mod +/// @notice Computes base^3 mod modulus +/// @dev Does not necessarily reduce fully mod modulus (the answer could be too big by a multiple of modulus) +/// @param n Number of bits per chunk the modulus is split into. +/// @param k Number of chunks the modulus is split into. +/// @input base The base to exponentiate; assumes to consist of `k` chunks, each of which must fit in `n` bits +/// @input modulus The modulus; assumes to consist of `k` chunks, each of which must fit in `n` bits +/// @output out The result of the exponentiation. +template FpPow3Mod(n, k) { + signal input base[k]; + signal input modulus[k]; + + signal output out[k]; + + component doublers = FpMul(n, k); + component adder = FpMul(n, k); + + for (var j = 0; j < k; j++) { + adder.p[j] <== modulus[j]; + doublers.p[j] <== modulus[j]; + } + for (var j = 0; j < k; j++) { + doublers.a[j] <== base[j]; + doublers.b[j] <== base[j]; + } + for (var j = 0; j < k; j++) { + adder.a[j] <== base[j]; + adder.b[j] <== doublers.out[j]; + } + for (var j = 0; j < k; j++) { + out[j] <== adder.out[j]; + } +} diff --git a/circuits/circuits/utils/circomlib/signature/rsa/verifyRsa65537Pkcs1v1_5.circom b/circuits/circuits/utils/circomlib/signature/rsa/verifyRsa65537Pkcs1v1_5.circom new file mode 100644 index 00000000..ef94753d --- /dev/null +++ b/circuits/circuits/utils/circomlib/signature/rsa/verifyRsa65537Pkcs1v1_5.circom @@ -0,0 +1,93 @@ +pragma circom 2.1.9; + +include "../../../zkemail/lib/fp.circom"; +include "./pkcs1v1_5Padding.circom"; +include "../../bitify/bitify.circom"; + +// For 2048bits RSA, CHUNK_SIZE = 64, CHUNK_NUMBER = 32 +// For 3072bits RSA, CHUNK_SIZE = 64, CHUNK_NUMBER = 48 +// For 4096bits RSA, CHUNK_SIZE = 64, CHUNK_NUMBER = 64 + +// HASH_SIZE is the size of the hash in bits + +template VerifyRsa65537Pkcs1v1_5(CHUNK_SIZE, CHUNK_NUMBER, HASH_SIZE) { + signal input signature[CHUNK_NUMBER]; + signal input modulus[CHUNK_NUMBER]; + + signal input message[CHUNK_NUMBER]; + + // 1. Add padding to the hashed message + component padder = Pkcs1v1_5Padding(CHUNK_SIZE, CHUNK_NUMBER, HASH_SIZE); + for (var i = 0; i < CHUNK_NUMBER; i++) { + padder.modulus[i] <== modulus[i]; + padder.message[i] <== message[i]; + } + + // 2. Check that the signature is in proper form and reduced mod modulus. + component signatureRangeCheck[CHUNK_NUMBER]; + component bigLessThan = BigLessThan(CHUNK_SIZE, CHUNK_NUMBER); + for (var i = 0; i < CHUNK_NUMBER; i++) { + signatureRangeCheck[i] = Num2Bits(CHUNK_SIZE); + signatureRangeCheck[i].in <== signature[i]; + bigLessThan.a[i] <== signature[i]; + bigLessThan.b[i] <== modulus[i]; + } + bigLessThan.out === 1; + + // 3. Compute the signature^exponent mod modulus + component bigPow = FpPow65537Mod(CHUNK_SIZE, CHUNK_NUMBER); + for (var i = 0; i < CHUNK_NUMBER; i++) { + bigPow.base[i] <== signature[i]; + bigPow.modulus[i] <== modulus[i]; + } + + // 4. Check that the computed value is equal to the padded message + for (var i = 0; i < CHUNK_NUMBER; i++) { + bigPow.out[i] === padder.out[i]; + } +} + +/// @title FpPow65537Mod +/// @notice Computes base^65537 mod modulus +/// @dev Does not necessarily reduce fully mod modulus (the answer could be too big by a multiple of modulus) +/// @param n Number of bits per chunk the modulus is split into. +/// @param k Number of chunks the modulus is split into. +/// @input base The base to exponentiate; assumes to consist of `k` chunks, each of which must fit in `n` bits +/// @input modulus The modulus; assumes to consist of `k` chunks, each of which must fit in `n` bits +/// @output out The result of the exponentiation. +template FpPow65537Mod(n, k) { + signal input base[k]; + signal input modulus[k]; + + signal output out[k]; + + component doublers[16]; + component adder = FpMul(n, k); + for (var i = 0; i < 16; i++) { + doublers[i] = FpMul(n, k); + } + + for (var j = 0; j < k; j++) { + adder.p[j] <== modulus[j]; + for (var i = 0; i < 16; i++) { + doublers[i].p[j] <== modulus[j]; + } + } + for (var j = 0; j < k; j++) { + doublers[0].a[j] <== base[j]; + doublers[0].b[j] <== base[j]; + } + for (var i = 0; i + 1 < 16; i++) { + for (var j = 0; j < k; j++) { + doublers[i + 1].a[j] <== doublers[i].out[j]; + doublers[i + 1].b[j] <== doublers[i].out[j]; + } + } + for (var j = 0; j < k; j++) { + adder.a[j] <== base[j]; + adder.b[j] <== doublers[15].out[j]; + } + for (var j = 0; j < k; j++) { + out[j] <== adder.out[j]; + } +} diff --git a/circuits/circuits/utils/circomlib/signature/rsa/verifyRsaPkcs1v1_5.circom b/circuits/circuits/utils/circomlib/signature/rsa/verifyRsaPkcs1v1_5.circom deleted file mode 100644 index 4b99fd35..00000000 --- a/circuits/circuits/utils/circomlib/signature/rsa/verifyRsaPkcs1v1_5.circom +++ /dev/null @@ -1,131 +0,0 @@ -pragma circom 2.1.9; - -include "../../bitify/bitify.circom"; -include "../../bigInt/bigInt.circom"; -include "../../../passport/signatureAlgorithm.circom"; -include "../../int/arithmetic.circom"; - -// For exponent is 3, use E_BITS = 2 -// For exponent is 65537, use E_BITS = 17 - -// For 2048bits RSA, CHUNK_SIZE = 64, CHUNK_NUMBER = 32 -// For 3072bits RSA, CHUNK_SIZE = 96, CHUNK_NUMBER = 32 -// For 4096bits RSA, CHUNK_SIZE = 64, CHUNK_NUMBER = 64 - -// HASH_SIZE is the size of the hash in bits - -template VerifyRsaPkcs1v1_5(signatureAlgorithm, CHUNK_SIZE, CHUNK_NUMBER, E_BITS, HASH_SIZE) { - signal input signature[CHUNK_NUMBER]; - signal input modulus[CHUNK_NUMBER]; - - signal input message[CHUNK_NUMBER]; - - - // Range check which is came from old openpassport impl - component signatureRangeCheck[CHUNK_NUMBER]; - component bigLessThan = BigLessThan(CHUNK_SIZE, CHUNK_NUMBER); - for (var i = 0; i < CHUNK_NUMBER; i++) { - signatureRangeCheck[i] = Num2Bits(CHUNK_SIZE); - signatureRangeCheck[i].in <== signature[i]; - bigLessThan.in[0][i] <== signature[i]; - bigLessThan.in[1][i] <== modulus[i]; - } - bigLessThan.out === 1; - - // Calc Power Mod - component bigPow = PowerMod(CHUNK_SIZE, CHUNK_NUMBER, E_BITS); - for (var i = 0; i < CHUNK_NUMBER; i++) { - bigPow.base[i] <== signature[i]; - bigPow.modulus[i] <== modulus[i]; - } - - var padding[5] = getPadding(signatureAlgorithm); - - // Verify Padding and Hashed Message - if (signatureAlgorithm == 3) { - for (var i = 0; i < 2; i++) { - bigPow.out[i] === message[i]; - } - component getBits = GetLastNBits(32); - getBits.in <== bigPow.out[2]; - component bitsToNum = Bits2Num(32); - bitsToNum.in <== getBits.out; - bitsToNum.out === message[2]; - - getBits.div === padding[0]; - bigPow.out[3] === padding[1]; - bigPow.out[4] === padding[2]; - for (var i = 5; i < CHUNK_NUMBER - 1; i++) { - bigPow.out[i] === padding[3]; - } - bigPow.out[CHUNK_NUMBER - 1] === padding[4]; - } else if (signatureAlgorithm == 10) { - for (var i = 0; i < 4; i++) { - bigPow.out[i] === message[i]; - } - bigPow.out[4] === padding[0]; - bigPow.out[5] === padding[1]; - bigPow.out[6] === padding[2]; - for (var i = 7; i < CHUNK_NUMBER - 1; i++) { - bigPow.out[i] === padding[3]; - } - bigPow.out[CHUNK_NUMBER - 1] === padding[4]; - } else if (signatureAlgorithm == 11) { - for (var i = 0; i < 2; i++) { - bigPow.out[i] === message[i]; - } - component getBits = GetLastNBits(32); - getBits.in <== bigPow.out[2]; - component bitsToNum = Bits2Num(32); - bitsToNum.in <== getBits.out; - bitsToNum.out === message[2]; - - getBits.div === padding[0]; - bigPow.out[3] === padding[1]; - bigPow.out[4] === padding[2]; - for (var i = 5; i < CHUNK_NUMBER - 1; i++) { - bigPow.out[i] === padding[3]; - } - bigPow.out[CHUNK_NUMBER - 1] === padding[4]; - } else if (signatureAlgorithm == 14) { - for (var i = 0; i < 2; i++) { - bigPow.out[i] === message[i]; - } - component getBits = GetLastNBits(64); - getBits.in <== bigPow.out[2]; - component bitsToNum = Bits2Num(64); - bitsToNum.in <== getBits.out; - bitsToNum.out === message[2]; - - getBits.div === padding[0]; - bigPow.out[3] === padding[1]; - bigPow.out[4] === padding[2]; - for (var i = 5; i < CHUNK_NUMBER - 1; i++) { - bigPow.out[i] === padding[3]; - } - bigPow.out[CHUNK_NUMBER - 1] === padding[4]; - } else if (signatureAlgorithm == 15) { - for (var i = 0; i < 8; i++) { - bigPow.out[i] === message[i]; - } - bigPow.out[8] === padding[0]; - bigPow.out[9] === padding[1]; - bigPow.out[10] === padding[2]; - for (var i = 11; i < CHUNK_NUMBER - 1; i++) { - bigPow.out[i] === padding[3]; - } - bigPow.out[CHUNK_NUMBER - 1] === padding[4]; - } else { - for (var i = 0; i < 4; i++) { - bigPow.out[i] === message[i]; - } - bigPow.out[4] === padding[0]; - bigPow.out[5] === padding[1]; - bigPow.out[6] === padding[2]; - for (var i = 7; i < CHUNK_NUMBER - 1; i++) { - bigPow.out[i] === padding[3]; - } - bigPow.out[CHUNK_NUMBER - 1] === padding[4]; - } - -} diff --git a/circuits/circuits/utils/circomlib/utils/compconstant.circom b/circuits/circuits/utils/circomlib/utils/compconstant.circom new file mode 100644 index 00000000..075442f5 --- /dev/null +++ b/circuits/circuits/utils/circomlib/utils/compconstant.circom @@ -0,0 +1,74 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "../bitify/bitify.circom"; + +// Returns 1 if in (in binary) > ct + +template CompConstant(ct) { + signal input in[254]; + signal output out; + + signal parts[127]; + signal sout; + + var clsb; + var cmsb; + var slsb; + var smsb; + + var sum=0; + + var b = (1 << 128) -1; + var a = 1; + var e = 1; + var i; + + for (i=0;i<127; i++) { + clsb = (ct >> (i*2)) & 1; + cmsb = (ct >> (i*2+1)) & 1; + slsb = in[i*2]; + smsb = in[i*2+1]; + + if ((cmsb==0)&&(clsb==0)) { + parts[i] <== -b*smsb*slsb + b*smsb + b*slsb; + } else if ((cmsb==0)&&(clsb==1)) { + parts[i] <== a*smsb*slsb - a*slsb + b*smsb - a*smsb + a; + } else if ((cmsb==1)&&(clsb==0)) { + parts[i] <== b*smsb*slsb - a*smsb + a; + } else { + parts[i] <== -a*smsb*slsb + a; + } + + sum = sum + parts[i]; + + b = b -e; + a = a +e; + e = e*2; + } + + sout <== sum; + + component num2bits = Num2Bits(135); + + num2bits.in <== sout; + + out <== num2bits.out[127]; +} \ No newline at end of file diff --git a/circuits/circuits/utils/circomlib/utils/sign.circom b/circuits/circuits/utils/circomlib/utils/sign.circom new file mode 100644 index 00000000..d5e2b07e --- /dev/null +++ b/circuits/circuits/utils/circomlib/utils/sign.circom @@ -0,0 +1,36 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "compconstant.circom"; + +template Sign() { + signal input in[254]; + signal output sign; + + component comp = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808); + + var i; + + for (i=0; i<254; i++) { + comp.in[i] <== in[i]; + } + + sign <== comp.out; +} \ No newline at end of file diff --git a/circuits/circuits/utils/passport/customHashers.circom b/circuits/circuits/utils/passport/customHashers.circom index 553cec34..ddba1ac7 100644 --- a/circuits/circuits/utils/passport/customHashers.circom +++ b/circuits/circuits/utils/passport/customHashers.circom @@ -4,7 +4,7 @@ include "../circomlib/hasher/hash.circom"; template CustomHasher(k) { signal input in[k]; - var rounds = div_ceil(k, 16); + var rounds = div_ceil_dl(k, 16); assert(rounds < 17); component hash[rounds]; diff --git a/circuits/circuits/utils/passport/signatureVerifier.circom b/circuits/circuits/utils/passport/signatureVerifier.circom index a4aedb4e..5c99da2b 100644 --- a/circuits/circuits/utils/passport/signatureVerifier.circom +++ b/circuits/circuits/utils/passport/signatureVerifier.circom @@ -6,7 +6,9 @@ include "../circomlib/signature/rsapss/rsapss.circom"; include "secp256r1Verifier.circom"; // include "../rsapss/rsapss.circom"; // include "../rsa/rsa.circom"; -include "../circomlib/signature/rsa/verifyRsaPkcs1v1_5.circom"; +// include "../circomlib/signature/rsa/verifyLargeRsaPkcs1v1_5.circom"; +include "../circomlib/signature/rsa/verifyRsa3Pkcs1v1_5.circom"; +include "../circomlib/signature/rsa/verifyRsa65537Pkcs1v1_5.circom"; include "../circomlib/utils/bytes.circom"; template SignatureVerifier(signatureAlgorithm, n, k) { @@ -25,7 +27,7 @@ template SignatureVerifier(signatureAlgorithm, n, k) { signal hashParsed[msg_len] <== HashParser(signatureAlgorithm, n, k)(hash); if (signatureAlgorithm == 1) { - component rsa = VerifyRsaPkcs1v1_5(signatureAlgorithm, n, k, 65537, 256); + component rsa = VerifyRsa65537Pkcs1v1_5(n, k, 256); for (var i = 0; i < msg_len; i++) { rsa.message[i] <== hashParsed[i]; } @@ -37,7 +39,7 @@ template SignatureVerifier(signatureAlgorithm, n, k) { } if (signatureAlgorithm == 3) { - component rsa = VerifyRsaPkcs1v1_5(signatureAlgorithm, n, k, 65537, 160); + component rsa = VerifyRsa65537Pkcs1v1_5(n, k, 160); for (var i = 0; i < msg_len; i++) { rsa.message[i] <== hashParsed[i]; } @@ -81,7 +83,7 @@ template SignatureVerifier(signatureAlgorithm, n, k) { if (signatureAlgorithm == 9) { } if (signatureAlgorithm == 10) { - component rsa = VerifyRsaPkcs1v1_5(signatureAlgorithm, n, k, 65537, 256); + component rsa = VerifyRsa65537Pkcs1v1_5(n, k, 256); for (var i = 0; i < msg_len; i++) { rsa.message[i] <== hashParsed[i]; } @@ -92,7 +94,7 @@ template SignatureVerifier(signatureAlgorithm, n, k) { rsa.signature <== signature; } if (signatureAlgorithm == 11) { - component rsa = VerifyRsaPkcs1v1_5(signatureAlgorithm, n, k, 65537, 160); + component rsa = VerifyRsa65537Pkcs1v1_5(n, k, 160); for (var i = 0; i < msg_len; i++) { rsa.message[i] <== hashParsed[i]; } @@ -106,7 +108,7 @@ template SignatureVerifier(signatureAlgorithm, n, k) { } if (signatureAlgorithm == 13) { - component rsa = VerifyRsaPkcs1v1_5(signatureAlgorithm, n, k, 3, 256); + component rsa = VerifyRsa3Pkcs1v1_5(n, k, 256); for (var i = 0; i < msg_len; i++) { rsa.message[i] <== hashParsed[i]; } @@ -117,7 +119,7 @@ template SignatureVerifier(signatureAlgorithm, n, k) { rsa.signature <== signature; } if (signatureAlgorithm == 14) { - component rsa = VerifyRsaPkcs1v1_5(signatureAlgorithm, n, k, 65537, 256); + component rsa = VerifyRsa65537Pkcs1v1_5(n, k, 256); for (var i = 0; i < msg_len; i++) { rsa.message[i] <== hashParsed[i]; } diff --git a/circuits/circuits/utils/zkemail/lib/base64.circom b/circuits/circuits/utils/zkemail/lib/base64.circom new file mode 100644 index 00000000..77dc745c --- /dev/null +++ b/circuits/circuits/utils/zkemail/lib/base64.circom @@ -0,0 +1,128 @@ +pragma circom 2.1.6; + +include "circomlib/circuits/comparators.circom"; + + +/// @title Base64Decode +/// @notice Decodes a Base64 encoded string to array of bytes. +/// @notice Only support inputs with length = `byteLength` (no 0 padding). +/// @notice It is known that padding char '=' can be replaed with `A` to produce the same output +/// as Base64Lookup returns `0` for both, but a pracical attack from this is unlikely. +/// @param byteLength Byte length of the encoded value - length of the output array. +/// @input in Base64 encoded string; assumes elements to be valid Base64 characters. +/// @output out Decoded array of bytes. +template Base64Decode_ZK_EMAIL(byteLength) { + var charLength = 4 * ((byteLength + 2) \ 3); // 4 chars encode 3 bytes + + signal input in[charLength]; + signal output out[byteLength]; + + component bitsIn[charLength\4][4]; + component bitsOut[charLength\4][3]; + component translate[charLength\4][4]; + + var idx = 0; + for (var i = 0; i < charLength; i += 4) { + for (var j = 0; j < 3; j++) { + bitsOut[i\4][j] = Bits2Num(8); + } + + for (var j = 0; j < 4; j++) { + bitsIn[i\4][j] = Num2Bits(6); + translate[i\4][j] = Base64Lookup(); + translate[i\4][j].in <== in[i+j]; + translate[i\4][j].out ==> bitsIn[i\4][j].in; + } + + // Do the re-packing from four 6-bit words to three 8-bit words. + for (var j = 0; j < 6; j++) { + bitsOut[i\4][0].in[j+2] <== bitsIn[i\4][0].out[j]; + } + bitsOut[i\4][0].in[0] <== bitsIn[i\4][1].out[4]; + bitsOut[i\4][0].in[1] <== bitsIn[i\4][1].out[5]; + + for (var j = 0; j < 4; j++) { + bitsOut[i\4][1].in[j+4] <== bitsIn[i\4][1].out[j]; + } + for (var j = 0; j < 4; j++) { + bitsOut[i\4][1].in[j] <== bitsIn[i\4][2].out[j+2]; + } + + bitsOut[i\4][2].in[6] <== bitsIn[i\4][2].out[0]; + bitsOut[i\4][2].in[7] <== bitsIn[i\4][2].out[1]; + for (var j = 0; j < 6; j++) { + bitsOut[i\4][2].in[j] <== bitsIn[i\4][3].out[j]; + } + + for (var j = 0; j < 3; j++) { + if (idx+j < byteLength) { + out[idx+j] <== bitsOut[i\4][j].out; + } + } + idx += 3; + } +} + + +/// @title Base64Lookup +/// @notice http://0x80.pl/notesen/2016-01-17-sse-base64-decoding.html#vector-lookup-base +/// @input in input character; assumes input to be valid Base64 character (though constrained implicitly). +/// @output out output bit value. +template Base64Lookup_ZK_EMAIL() { + signal input in; + signal output out; + + // ['A', 'Z'] + component le_Z = LessThan(8); + le_Z.in[0] <== in; + le_Z.in[1] <== 90+1; + + component ge_A = GreaterThan(8); + ge_A.in[0] <== in; + ge_A.in[1] <== 65-1; + + signal range_AZ <== ge_A.out * le_Z.out; + signal sum_AZ <== range_AZ * (in - 65); + + // ['a', 'z'] + component le_z = LessThan(8); + le_z.in[0] <== in; + le_z.in[1] <== 122+1; + + component ge_a = GreaterThan(8); + ge_a.in[0] <== in; + ge_a.in[1] <== 97-1; + + signal range_az <== ge_a.out * le_z.out; + signal sum_az <== sum_AZ + range_az * (in - 71); + + // ['0', '9'] + component le_9 = LessThan(8); + le_9.in[0] <== in; + le_9.in[1] <== 57+1; + + component ge_0 = GreaterThan(8); + ge_0.in[0] <== in; + ge_0.in[1] <== 48-1; + + signal range_09 <== ge_0.out * le_9.out; + signal sum_09 <== sum_az + range_09 * (in + 4); + + // '+' + component equal_plus = IsZero(); + equal_plus.in <== in - 43; + signal sum_plus <== sum_09 + equal_plus.out * (in + 19); + + // '/' + component equal_slash = IsZero(); + equal_slash.in <== in - 47; + signal sum_slash <== sum_plus + equal_slash.out * (in + 16); + + out <== sum_slash; + + // '=' + component equal_eqsign = IsZero(); + equal_eqsign.in <== in - 61; + + 1 === range_AZ + range_az + range_09 + equal_plus.out + equal_slash.out + equal_eqsign.out; +} diff --git a/circuits/circuits/utils/zkemail/lib/bigint-func.circom b/circuits/circuits/utils/zkemail/lib/bigint-func.circom new file mode 100644 index 00000000..bcd0d09b --- /dev/null +++ b/circuits/circuits/utils/zkemail/lib/bigint-func.circom @@ -0,0 +1,264 @@ +pragma circom 2.1.6; + + +function div_ceil(m, n) { + var ret = 0; + if (m % n == 0) { + ret = m \ n; + } else { + ret = m \ n + 1; + } + return ret; +} + +function log_ceil(n) { + var n_temp = n; + for (var i = 0; i < 254; i++) { + if (n_temp == 0) { + return i; + } + n_temp = n_temp \ 2; + } + return 254; +} + +// m bits per overflowed register (values are potentially negative) +// n bits per properly-sized register +// in has k registers +// out has k + ceil(m/n) - 1 + 1 registers. highest-order potentially negative, +// all others are positive +// - 1 since the last register is included in the last ceil(m/n) array +// + 1 since the carries from previous registers could push you over +function getProperRepresentation(m, n, k, in) { + var ceilMN = div_ceil(m, n); + + var out[100]; // should be out[k + ceilMN] + assert(k + ceilMN < 100); + for (var i = 0; i < k; i++) { + out[i] = in[i]; + } + for (var i = k; i < 100; i++) { + out[i] = 0; + } + assert(n <= m); + for (var i = 0; i+1 < k + ceilMN; i++) { + assert((1 << m) >= out[i] && out[i] >= -(1 << m)); + var shifted_val = out[i] + (1 << m); + assert(0 <= shifted_val && shifted_val <= (1 << (m+1))); + out[i] = shifted_val & ((1 << n) - 1); + out[i+1] += (shifted_val >> n) - (1 << (m - n)); + } + + return out; +} + +// Evaluate polynomial a at point x +function poly_eval(len, a, x) { + var v = 0; + for (var i = 0; i < len; i++) { + v += a[i] * (x ** i); + } + return v; +} + +// Interpolate a degree len-1 polynomial given its evaluations at 0..len-1 +function poly_interp(len, v) { + assert(len <= 200); + var out[200]; + for (var i = 0; i < len; i++) { + out[i] = 0; + } + + // Product_{i=0..len-1} (x-i) + var full_poly[201]; + full_poly[0] = 1; + for (var i = 0; i < len; i++) { + full_poly[i+1] = 0; + for (var j = i; j >= 0; j--) { + full_poly[j+1] += full_poly[j]; + full_poly[j] *= -i; + } + } + + for (var i = 0; i < len; i++) { + var cur_v = 1; + for (var j = 0; j < len; j++) { + if (i == j) { + // do nothing + } else { + cur_v *= i-j; + } + } + cur_v = v[i] / cur_v; + + var cur_rem = full_poly[len]; + for (var j = len-1; j >= 0; j--) { + out[j] += cur_v * cur_rem; + cur_rem = full_poly[j] + i * cur_rem; + } + assert(cur_rem == 0); + } + + return out; +} + +// 1 if true, 0 if false +function long_gt(n, k, a, b) { + for (var i = k - 1; i >= 0; i--) { + if (a[i] > b[i]) { + return 1; + } + if (a[i] < b[i]) { + return 0; + } + } + return 0; +} + +// n bits per register +// a has k registers +// b has k registers +// a >= b +function long_sub(n, k, a, b) { + var diff[100]; + var borrow[100]; + for (var i = 0; i < k; i++) { + if (i == 0) { + if (a[i] >= b[i]) { + diff[i] = a[i] - b[i]; + borrow[i] = 0; + } else { + diff[i] = a[i] - b[i] + (1 << n); + borrow[i] = 1; + } + } else { + if (a[i] >= b[i] + borrow[i - 1]) { + diff[i] = a[i] - b[i] - borrow[i - 1]; + borrow[i] = 0; + } else { + diff[i] = (1 << n) + a[i] - b[i] - borrow[i - 1]; + borrow[i] = 1; + } + } + } + return diff; +} + +// a is a n-bit scalar +// b has k registers +function long_scalar_mult(n, k, a, b) { + var out[100]; + for (var i = 0; i < 100; i++) { + out[i] = 0; + } + for (var i = 0; i < k; i++) { + var temp = out[i] + (a * b[i]); + out[i] = temp % (1 << n); + out[i + 1] = out[i + 1] + temp \ (1 << n); + } + return out; +} + + +// n bits per register +// a has k + m registers +// b has k registers +// out[0] has length m + 1 -- quotient +// out[1] has length k -- remainder +// implements algorithm of https://people.eecs.berkeley.edu/~fateman/282/F%20Wright%20notes/week4.pdf +function long_div(n, k, m, a, b){ + var out[2][100]; + m += k; + while (b[k-1] == 0) { + out[1][k] = 0; + k--; + assert(k > 0); + } + m -= k; + + var remainder[100]; + for (var i = 0; i < m + k; i++) { + remainder[i] = a[i]; + } + + var mult[200]; + var dividend[200]; + for (var i = m; i >= 0; i--) { + if (i == m) { + dividend[k] = 0; + for (var j = k - 1; j >= 0; j--) { + dividend[j] = remainder[j + m]; + } + } else { + for (var j = k; j >= 0; j--) { + dividend[j] = remainder[j + i]; + } + } + + out[0][i] = short_div(n, k, dividend, b); + + var mult_shift[100] = long_scalar_mult(n, k, out[0][i], b); + var subtrahend[200]; + for (var j = 0; j < m + k; j++) { + subtrahend[j] = 0; + } + for (var j = 0; j <= k; j++) { + if (i + j < m + k) { + subtrahend[i + j] = mult_shift[j]; + } + } + remainder = long_sub(n, m + k, remainder, subtrahend); + } + for (var i = 0; i < k; i++) { + out[1][i] = remainder[i]; + } + out[1][k] = 0; + + return out; +} + +// n bits per register +// a has k + 1 registers +// b has k registers +// assumes leading digit of b is at least 2 ** (n - 1) +// 0 <= a < (2**n) * b +function short_div_norm(n, k, a, b) { + var qhat = (a[k] * (1 << n) + a[k - 1]) \ b[k - 1]; + if (qhat > (1 << n) - 1) { + qhat = (1 << n) - 1; + } + + var mult[100] = long_scalar_mult(n, k, qhat, b); + if (long_gt(n, k + 1, mult, a) == 1) { + mult = long_sub(n, k + 1, mult, b); + if (long_gt(n, k + 1, mult, a) == 1) { + return qhat - 2; + } else { + return qhat - 1; + } + } else { + return qhat; + } +} + +// n bits per register +// a has k + 1 registers +// b has k registers +// assumes leading digit of b is non-zero +// 0 <= a < (2**n) * b +function short_div(n, k, a, b) { + var scale = (1 << n) \ (1 + b[k - 1]); + + // k + 2 registers now + var norm_a[100] = long_scalar_mult(n, k + 1, scale, a); + // k + 1 registers now + var norm_b[100] = long_scalar_mult(n, k, scale, b); + + var ret; + if (norm_b[k] != 0) { + ret = short_div_norm(n, k + 1, norm_a, norm_b); + } else { + ret = short_div_norm(n, k, norm_a, norm_b); + } + return ret; +} diff --git a/circuits/circuits/utils/zkemail/lib/bigint.circom b/circuits/circuits/utils/zkemail/lib/bigint.circom new file mode 100644 index 00000000..3ad7bfd6 --- /dev/null +++ b/circuits/circuits/utils/zkemail/lib/bigint.circom @@ -0,0 +1,94 @@ +pragma circom 2.1.6; + +include "../../circomlib/bitify/comparators.circom"; +include "../../circomlib/bitify/bitify.circom"; +include "../../circomlib/bitify/gates.circom"; +include "./bigint-func.circom"; + + +/// @template BigLessThan +/// @notice Less than comparison for big integers +/// @param n The number of bits in each chunk +/// @param k The number of chunks +/// @param a The first bigint; assumes to consist of `k` chunks, each of which must fit in `n` bits +/// @param b The second bigint; assumes to consist of `k` chunks, each of which must fit in `n` bits +/// @param out The output of the comparison +template BigLessThan(n, k){ + signal input a[k]; + signal input b[k]; + signal output out; + + component lt[k]; + component eq[k]; + for (var i = 0; i < k; i++) { + lt[i] = LessThan(n); + lt[i].in[0] <== a[i]; + lt[i].in[1] <== b[i]; + eq[i] = IsEqual(); + eq[i].in[0] <== a[i]; + eq[i].in[1] <== b[i]; + } + + // ors[i] holds (lt[k - 1] || (eq[k - 1] && lt[k - 2]) .. || (eq[k - 1] && .. && lt[i])) + // ands[i] holds (eq[k - 1] && .. && lt[i]) + // eq_ands[i] holds (eq[k - 1] && .. && eq[i]) + component ors[k - 1]; + component ands[k - 1]; + component eq_ands[k - 1]; + for (var i = k - 2; i >= 0; i--) { + ands[i] = AND(); + eq_ands[i] = AND(); + ors[i] = OR(); + + if (i == k - 2) { + ands[i].a <== eq[k - 1].out; + ands[i].b <== lt[k - 2].out; + eq_ands[i].a <== eq[k - 1].out; + eq_ands[i].b <== eq[k - 2].out; + ors[i].a <== lt[k - 1].out; + ors[i].b <== ands[i].out; + } else { + ands[i].a <== eq_ands[i + 1].out; + ands[i].b <== lt[i].out; + eq_ands[i].a <== eq_ands[i + 1].out; + eq_ands[i].b <== eq[i].out; + ors[i].a <== ors[i + 1].out; + ors[i].b <== ands[i].out; + } + } + out <== ors[0].out; +} + + +/// @template CheckCarryToZero +/// @notice Check that in[] as a big integer is zero +/// @param n The number of bits in each chunk +/// @param m +/// @param k The number of chunks +/// @input in The input big integer; assumes elements to be in the range -2^(m-1) to 2^(m-1) +template CheckCarryToZero(n, m, k) { + assert(k >= 2); + + var EPSILON = 3; + + assert(m + EPSILON <= 253); + + signal input in[k]; + + signal carry[k]; + component carryRangeChecks[k]; + for (var i = 0; i < k-1; i++){ + carryRangeChecks[i] = Num2Bits(m + EPSILON - n); + if( i == 0 ){ + carry[i] <-- in[i] / (1<> (i - msgLen)) & 1; + } + + component modulusZero[(n*k + 7 - (baseLen + 8))\8]; + { + var modulusPrefix = 0; + for (var i = n*k - 1; i >= baseLen + 8; i--) { + if (i+8 < n*k) { + modulusPrefix += modulusBits[i+8]; + if (i % 8 == 0) { + var idx = (i - (baseLen + 8)) \ 8; + modulusZero[idx] = IsZero(); + modulusZero[idx].in <== modulusPrefix; + paddedMessageBits[i] <== 1-modulusZero[idx].out; + } else { + paddedMessageBits[i] <== paddedMessageBits[i+1]; + } + } else { + paddedMessageBits[i] <== 0; + } + } + } + + // The RFC guarantees at least 8 octets of 0xff padding. + assert(baseLen + 8 + 65 <= n * k); + + for (var i = baseLen + 8; i < baseLen + 8 + 65; i++) { + paddedMessageBits[i] === 1; + } + + component passedMessageB2N[k]; + for (var i = 0; i < k; i++) { + passedMessageB2N[i] = Bits2Num(n); + for (var j = 0; j < n; j++) { + passedMessageB2N[i].in[j] <== paddedMessageBits[i*n+j]; + } + out[i] <== passedMessageB2N[i].out; + } +} diff --git a/circuits/circuits/utils/zkemail/lib/sha.circom b/circuits/circuits/utils/zkemail/lib/sha.circom new file mode 100644 index 00000000..5ed154ea --- /dev/null +++ b/circuits/circuits/utils/zkemail/lib/sha.circom @@ -0,0 +1,292 @@ +pragma circom 2.1.6; + +include "circomlib/circuits/bitify.circom"; +include "circomlib/circuits/sha256/constants.circom"; +include "circomlib/circuits/sha256/sha256compression.circom"; +include "circomlib/circuits/comparators.circom"; +include "./fp.circom"; +include "../utils/array.circom"; +include "../utils/functions.circom"; + + +/// @title Sha256Bytes +/// @notice Computes the SHA256 hash of input bytes +/// @input paddedIn Message to hash, padded as per the SHA256 specification; assumes to consist of bytes +/// @input paddedInLength Length of the padded message; assumes to be in `ceil(log2(8 * maxByteLength))` bits +/// @output out The 256-bit hash of the input message +template Sha256Bytes(maxByteLength) { + signal input paddedIn[maxByteLength]; + signal input paddedInLength; + signal output out[256]; + + var maxBits = maxByteLength * 8; + component sha = Sha256General(maxBits); + + component bytes[maxByteLength]; + for (var i = 0; i < maxByteLength; i++) { + bytes[i] = Num2Bits(8); + bytes[i].in <== paddedIn[i]; + for (var j = 0; j < 8; j++) { + sha.paddedIn[i*8+j] <== bytes[i].out[7-j]; + } + } + sha.paddedInLength <== paddedInLength * 8; + + for (var i = 0; i < 256; i++) { + out[i] <== sha.out[i]; + } +} + + +/// @title Sha256BytesPartial +/// @notice Computes the SHA256 hash of input bytes with a precomputed state +/// @input paddedIn Message to hash padded as per the SHA256 specification; assumes to consist of bytes +/// @input paddedInLength Length of the padded message; assumes to be in `ceil(log2(8 * maxByteLength))` bits +/// @input preHash The precomputed state of the hash +/// @output out SHA hash the input message with the precomputed state +template Sha256BytesPartial(maxByteLength) { + assert(maxByteLength % 32 == 0); + + signal input paddedIn[maxByteLength]; + signal input paddedInLength; + signal input preHash[32]; + signal output out[256]; + + var maxBits = maxByteLength * 8; + component sha = Sha256Partial(maxBits); + + component bytes[maxByteLength]; + for (var i = 0; i < maxByteLength; i++) { + bytes[i] = Num2Bits(8); + bytes[i].in <== paddedIn[i]; + for (var j = 0; j < 8; j++) { + sha.paddedIn[i*8+j] <== bytes[i].out[7-j]; + } + } + sha.paddedInLength <== paddedInLength * 8; + + component states[32]; + for (var i = 0; i < 32; i++) { + states[i] = Num2Bits(8); + states[i].in <== preHash[i]; + for (var j = 0; j < 8; j++) { + sha.preHash[8*i+j] <== states[i].out[7-j]; + } + } + + for (var i = 0; i < 256; i++) { + out[i] <== sha.out[i]; + } +} + + +/// @title Sha256General +/// @notice A modified version of the SHA256 circuit that allows specified length messages up to a +/// max to all work via array indexing on the SHA256 compression circuit. +/// @input paddedIn Message to hash padded as per the SHA256 specification; assumes to consist of bits +/// @input paddedInLength Length of the padded message; assumes to be in `ceil(log2(maxBitLength))` bits +/// @output out The 256-bit hash of the input message +template Sha256General(maxBitLength) { + // maxBitLength must be a multiple of 512 + // the bit circuits in this file are limited to 15 so must be raised if the message is longer. + assert(maxBitLength % 512 == 0); + + var maxBitsPaddedBits = log2Ceil(maxBitLength); + + // Note that maxBitLength = maxBits + 64 + signal input paddedIn[maxBitLength]; + signal input paddedInLength; + + signal output out[256]; + + signal inBlockIndex; + + var i; + var k; + var j; + var maxBlocks; + var bitsLastBlock; + maxBlocks = (maxBitLength\512); + + inBlockIndex <-- (paddedInLength >> 9); + paddedInLength === inBlockIndex * 512; + + // These verify the unconstrained floor calculation is the uniquely correct integer that represents the floor + // component floorVerifierUnder = LessEqThan(maxBitsPaddedBits); // todo verify the length passed in is less than nbits. note that maxBitsPaddedBits can likely be lowered or made it a fn of maxbits + // floorVerifierUnder.in[0] <== (inBlockIndex)*512; + // floorVerifierUnder.in[1] <== paddedInLength; + // floorVerifierUnder.out === 1; + + // component floorVerifierOver = GreaterThan(maxBitsPaddedBits); + // floorVerifierOver.in[0] <== (inBlockIndex+1)*512; + // floorVerifierOver.in[1] <== paddedInLength; + // floorVerifierOver.out === 1; + + // These verify we pass in a valid number of bits to the SHA256 compression circuit. + component bitLengthVerifier = LessEqThan(maxBitsPaddedBits); // todo verify the length passed in is less than nbits. note that maxBitsPaddedBits can likely be lowered or made it a fn of maxbits + bitLengthVerifier.in[0] <== paddedInLength; + bitLengthVerifier.in[1] <== maxBitLength; + bitLengthVerifier.out === 1; + + // Note that we can no longer do padded verification efficiently inside the SHA because it requires non deterministic array indexing. + // We can do it if we add a constraint, but since guessing a valid SHA2 preimage is hard anyways, we'll just do it outside the circuit. + + // signal paddedIn[maxBlocks*512]; + // for (k=0; k> k)&1; + // } + + component ha0 = H(0); + component hb0 = H(1); + component hc0 = H(2); + component hd0 = H(3); + component he0 = H(4); + component hf0 = H(5); + component hg0 = H(6); + component hh0 = H(7); + + component sha256compression[maxBlocks]; + + for (i=0; i> 9); + paddedInLength === inBlockIndex * 512; + + // These verify we pass in a valid number of bits to the SHA256 compression circuit. + component bitLengthVerifier = LessEqThan(maxBitsPaddedBits); // todo verify the length passed in is less than nbits. note that maxBitsPaddedBits can likely be lowered or made it a fn of maxbits + bitLengthVerifier.in[0] <== paddedInLength; + bitLengthVerifier.in[1] <== maxBitLength; + bitLengthVerifier.out === 1; + + component sha256compression[maxBlocks]; + + for (i=0; i= end); + assert(start >= 0); + assert(end >= start); + + signal input in[n]; + signal output out[end - start]; + + for (var i = start; i < end; i++) { + out[i - start] <== in[i]; + } +} + +/// @title CheckSubstringMatch +/// @notice Check if a substring matches the input array +/// @param maxSubstringLen The maximum length of the substring +/// @input input The portion of the input array to check +/// @input substring The substring pattern to match +/// @output isMatch 1 if the substring matches, 0 otherwise +template CheckSubstringMatch(maxSubstringLen) { + signal input in[maxSubstringLen]; + signal input substring[maxSubstringLen]; + signal output isMatch; + + // Ensure the first element of the pattern is non-zero + signal firstElementNonZero; + firstElementNonZero <== IsZero()(substring[0]); + firstElementNonZero === 0; + + signal matchAccumulator[maxSubstringLen + 1]; + signal difference[maxSubstringLen]; + signal isZeroDifference[maxSubstringLen]; + + matchAccumulator[0] <== 1; + + for (var i = 0; i < maxSubstringLen; i++) { + difference[i] <== (in[i] - substring[i]) * substring[i]; + isZeroDifference[i] <== IsZero()(difference[i]); + matchAccumulator[i + 1] <== matchAccumulator[i] * isZeroDifference[i]; + } + + isMatch <== matchAccumulator[maxSubstringLen]; +} + +/// @title CountSubstringOccurrences +/// @notice Count the number of times a substring occurs in the input array +/// @param maxLen The maximum length of the input array +/// @param maxSubstringLen The maximum length of the substring +/// @input in The input array to search in +/// @input substring The substring to search for +/// @output count The number of occurrences of the substring in the input +template CountSubstringOccurrences(maxLen, maxSubstringLen) { + assert(maxLen >= maxSubstringLen); + + signal input in[maxLen]; + signal input substring[maxSubstringLen]; + signal output count; + + // Check for matches at each possible starting position + component matches[maxLen]; + for (var i = 0; i < maxLen; i++) { + matches[i] = CheckSubstringMatch(maxSubstringLen); + for (var j = 0; j < maxSubstringLen; j++) { + if (i + j < maxLen) { + matches[i].in[j] <== in[i + j]; + } else { + matches[i].in[j] <== 0; + } + } + matches[i].substring <== substring; + } + + // Sum up all matches to get the total count + component summer = CalculateTotal(maxLen); + for (var i = 0; i < maxLen; i++) { + summer.nums[i] <== matches[i].isMatch; + } + + count <== summer.sum; +} \ No newline at end of file diff --git a/circuits/circuits/utils/zkemail/utils/bytes.circom b/circuits/circuits/utils/zkemail/utils/bytes.circom new file mode 100644 index 00000000..2bc0c1cf --- /dev/null +++ b/circuits/circuits/utils/zkemail/utils/bytes.circom @@ -0,0 +1,185 @@ +pragma circom 2.1.6; + +include "circomlib/circuits/bitify.circom"; +include "circomlib/circuits/comparators.circom"; +include "./array.circom"; +include "./constants.circom"; +include "./functions.circom"; + + +function computeIntChunkLength(byteLength) { + var packSize = MAX_BYTES_IN_FIELD(); + + var remain = byteLength % packSize; + var numChunks = (byteLength - remain) / packSize; + if (remain > 0) { + numChunks += 1; + } + + return numChunks; +} + + +/// @title PackBytes +/// @notice Pack an array of bytes to numbers that fit in the field +/// @param maxBytes the maximum number of bytes in the input array +/// @input in the input byte array; assumes elements to be bytes +/// @output out the output integer array +template PackBytes(maxBytes) { + var packSize = MAX_BYTES_IN_FIELD(); + var maxInts = computeIntChunkLength(maxBytes); + + signal input in[maxBytes]; + signal output out[maxInts]; + + signal intSums[maxInts][packSize]; + + for (var i = 0; i < maxInts; i++) { + for(var j=0; j < packSize; j++) { + var idx = packSize * i + j; + + // Copy the previous value if we are out of bounds - we take last item as final result + if(idx >= maxBytes) { + intSums[i][j] <== intSums[i][j-1]; + } + // First item of each chunk is the byte itself + else if (j == 0){ + intSums[i][j] <== in[idx]; + } + // Every other item is 256^j * byte + else { + intSums[i][j] <== intSums[i][j-1] + (1 << (8*j)) * in[idx]; + } + } + } + + // Last item of each chunk is the final sum + for (var i = 0; i < maxInts; i++) { + out[i] <== intSums[i][packSize-1]; + } +} + + +/// @title PackByteSubArray +/// @notice Select sub array from the input array and pack it to numbers that fit in the field +/// @notice This is not used in ZK-Email circuits anywhere +/// @param maxArrayLen the maximum number of elements in the input array +/// @param maxSubArrayLen the maximum number of elements in the sub array +/// @input in the input byte array; assumes elements to be bytes +/// @input startIndex the start index of the sub array; assumes to be a valid index +/// @input length the length of the sub array; assumes to fit in `ceil(log2(maxSubArrayLen))` bits +/// @output out the output integer array +template PackByteSubArray(maxArrayLen, maxSubArrayLen) { + assert(maxSubArrayLen < maxArrayLen); + var chunkLength = computeIntChunkLength(maxSubArrayLen); + + signal input in[maxArrayLen]; + signal input startIndex; + signal input length; + + signal output out[chunkLength]; + + component SelectSubArray = SelectSubArray(maxArrayLen, maxSubArrayLen); + SelectSubArray.in <== in; + SelectSubArray.startIndex <== startIndex; + SelectSubArray.length <== length; + + component packer = PackBytes(maxSubArrayLen); + packer.in <== SelectSubArray.out; + + out <== packer.out; +} + + +/// @title DigitBytesToInt +/// @notice Converts a byte array representing digits to an integer +/// @notice Assumes the output number fits in the field +/// @param n The number of bytes in the input array +/// @input in The input byte array; assumes elements are between 48 and 57 (ASCII numbers) +/// @output out The output integer; assumes to fit in the field +template DigitBytesToInt(n) { + signal input in[n]; + + signal output out; + + signal sums[n+1]; + sums[0] <== 0; + + for(var i = 0; i < n; i++) { + sums[i + 1] <== 10 * sums[i] + (in[i] - 48); + } + + out <== sums[n]; +} + + +// NOTE: this circuit is unaudited and should not be used in production +/// @title SplitBytesToWords +/// @notice split an array of bytes into an array of words +/// @notice useful for casting a message or modulus before RSA verification +/// @param l: number of bytes in the input array +/// @param n: number of bits in a word +/// @param k: number of words +/// @input in: array of bytes +/// @output out: array of words +template SplitBytesToWords (l,n,k) { + signal input in[l]; + signal output out[k]; + + component num2bits[l]; + for (var i = 0 ; i < l ; i++){ + num2bits[i] = Num2Bits(8); + num2bits[i].in <== in[i]; + } + component bits2num[k]; + for (var i = 0 ; i < k ; i++){ + bits2num[i] = Bits2Num(n); + for(var j = 0 ; j < n ; j++){ + if(i*n + j >= 8 * l){ + bits2num[i].in[j] <== 0; + } + else{ + bits2num[i].in[j] <== num2bits[l - (( i * n + j) \ 8) - 1].out[ ((i * n + j) % 8)]; + } + } + } + for( var i = 0 ; i< k ; i++){ + out[i] <== bits2num[i].out; + } +} + +// Asserts that a given input is binary. +// +// Inputs: +// - in: an input signal, expected to be 0 or 1. +template AssertBit() { + signal input in; + in * (in - 1) === 0; +} + +// The ByteMask template masks an input array using a binary mask array. +// Each element in the input array is multiplied by the corresponding element in the mask array. +// The mask array is validated to ensure all elements are binary (0 or 1). +// +// Parameters: +// - maxLength: The maximum length of the input and mask arrays. +// +// Inputs: +// - body: An array of signals representing the body to be masked. +// - mask: An array of signals representing the binary mask. +// +// Outputs: +// - out: An array of signals representing the masked input. +template ByteMask(maxLength) { + signal input in[maxLength]; + signal input mask[maxLength]; + signal output out[maxLength]; + + component bit_check[maxLength]; + + for (var i = 0; i < maxLength; i++) { + bit_check[i] = AssertBit(); + bit_check[i].in <== mask[i]; + out[i] <== in[i] * mask[i]; + } +} \ No newline at end of file diff --git a/circuits/circuits/utils/zkemail/utils/constants.circom b/circuits/circuits/utils/zkemail/utils/constants.circom new file mode 100644 index 00000000..69b0c993 --- /dev/null +++ b/circuits/circuits/utils/zkemail/utils/constants.circom @@ -0,0 +1,15 @@ +pragma circom 2.1.6; + + +function EMAIL_ADDR_MAX_BYTES() { + return 256; +} + +function DOMAIN_MAX_BYTES() { + return 255; +} + +// Field support maximum of ~253 bit +function MAX_BYTES_IN_FIELD() { + return 31; +} diff --git a/circuits/circuits/utils/zkemail/utils/functions.circom b/circuits/circuits/utils/zkemail/utils/functions.circom new file mode 100644 index 00000000..7c76024f --- /dev/null +++ b/circuits/circuits/utils/zkemail/utils/functions.circom @@ -0,0 +1,17 @@ +pragma circom 2.1.6; + +/// @function log2Ceil +/// @notice Calculate log2 of a number and round it up +/// @param a The input value +/// @return The result of the log2Ceil +function log2Ceil(a) { + var n = a - 1; + var r = 0; + + while (n > 0) { + r++; + n \= 2; + } + + return r; +} diff --git a/circuits/scripts/get_description_tree.sh b/circuits/scripts/print_circom_tree.sh similarity index 96% rename from circuits/scripts/get_description_tree.sh rename to circuits/scripts/print_circom_tree.sh index 6336139d..8cdfe23b 100755 --- a/circuits/scripts/get_description_tree.sh +++ b/circuits/scripts/print_circom_tree.sh @@ -86,7 +86,8 @@ circuits/utils/circomlib/mux/mux1.circom:green:"circomlib" circuits/utils/circomlib/hasher/poseidon/poseidon.circom:green:"circomlib" circuits/utils/circomlib/hasher/poseidon/poseidonConstants.circom:green:"circomlib" circuits/utils/circomlib/merkle-trees/binary-merkle-root.circom:green:"@zk-kit" -circuits/utils/circomlib/hasher/sha2:purple:"@zkemail" +circuits/utils/circomlib/hasher/sha2/sha256_temp:green:"circomlib" +circuits/utils/circomlib/hasher/sha2:purple:"circomlib" circuits/utils/circomlib/hasher/sha1/t.circom:purple:"circomlib" circuits/utils/circomlib/hasher/sha1/xor4.circom:purple:"circomlib" circuits/utils/circomlib/signature/rsa/verifyRsaPkcs1v1_5.circom:purple:"@zkemail" \ No newline at end of file diff --git a/circuits/tests/prove.test.ts b/circuits/tests/prove.test.ts index 341eadd5..16505e11 100644 --- a/circuits/tests/prove.test.ts +++ b/circuits/tests/prove.test.ts @@ -32,6 +32,7 @@ const fullSigAlgs = [ ]; const testSuite = process.env.FULL_TEST_SUITE === 'true' ? fullSigAlgs : sigAlgs; +// const testSuite = fullSigAlgs; testSuite.forEach(({ sigAlg, hashFunction, domainParameter, keyLength }) => { describe(`Prove - ${hashFunction.toUpperCase()} ${sigAlg.toUpperCase()} ${domainParameter} ${keyLength}`, function () { diff --git a/circuits/tests/utils/rsaPkcs1v1_5.test.ts b/circuits/tests/utils/rsaPkcs1v1_5.test.ts index 9411e674..5ecf4eee 100644 --- a/circuits/tests/utils/rsaPkcs1v1_5.test.ts +++ b/circuits/tests/utils/rsaPkcs1v1_5.test.ts @@ -8,11 +8,11 @@ describe('VerifyRsaPkcs1v1_5 Circuit Test', function () { this.timeout(0); /** Some tests are disabled to avoid overloading the CI/CD pipeline - the commented rsa verifications will however be tested in prove.test.ts and dsc.test.ts **/ const rsaAlgorithms: SignatureAlgorithm[] = [ - // 'rsa_sha1_65537_2048', - // 'rsa_sha256_65537_2048', + 'rsa_sha1_65537_2048', + 'rsa_sha256_65537_2048', 'rsa_sha256_3_2048', - // 'rsa_sha256_65537_3072', - // 'rsa_sha256_65537_4096', + 'rsa_sha256_65537_3072', + 'rsa_sha256_65537_4096', 'rsa_sha512_65537_4096', ]; diff --git a/circuits/yarn.lock b/circuits/yarn.lock index 68e9749b..4c44bd8f 100644 --- a/circuits/yarn.lock +++ b/circuits/yarn.lock @@ -4201,7 +4201,7 @@ __metadata: "typescript@patch:typescript@npm%3A^5.3.3#optional!builtin": version: 5.7.2 - resolution: "typescript@patch:typescript@npm%3A5.7.2#optional!builtin::version=5.7.2&hash=cef18b" + resolution: "typescript@patch:typescript@npm%3A5.7.2#optional!builtin::version=5.7.2&hash=8c6c40" bin: tsc: bin/tsc tsserver: bin/tsserver diff --git a/common/pubkeys/serialized_csca_tree.json b/common/pubkeys/serialized_csca_tree.json index 71409515..0b2f61a3 100644 --- a/common/pubkeys/serialized_csca_tree.json +++ b/common/pubkeys/serialized_csca_tree.json @@ -1 +1 @@ -[["18871857950874854657946759947173958535807446890011181348195267677920480754395","11156435013531908654639190892115092728335551234708805315487558056971764291948","17233249885835201128091787447928528987433597827434283233453544321927732151682","12880246921382128468495594122300999732304604277752631469876119605813044386484","4345865012300113780023115661070600377397578665737945037487473194565302055151","1026061344167229557530280237821161161892591142813273843769502549447660133566","6318665075946194493459655890331592579446130571387311970988366413606513309666","214315323819057312983317374041305201494892368555098687059514331685205473409","12880246921382128468495594122300999732304604277752631469876119605813044386484","4345865012300113780023115661070600377397578665737945037487473194565302055151","1026061344167229557530280237821161161892591142813273843769502549447660133566","16302943973192121937016650211653994395718070596375664106667990668687838453153","6742340340486138517895715495173923350670637330946604847347750370613811676641","7726792286473802857280466567840606186420831161587091626690384923672197163758","414376870353557956557410073611570035767149620606037626284506478934856934950","3211042168604779967884960563496543020838019199076905676204211041950279066160","15618704577094537211117942495330534996697879125403937074624030451849733511428","2082198709204553956196180197968070198531678808304059894038068876628063276452","20656407170301550737698921276078630269108794924656235576678360422623873054093","414376870353557956557410073611570035767149620606037626284506478934856934950","3211042168604779967884960563496543020838019199076905676204211041950279066160","15618704577094537211117942495330534996697879125403937074624030451849733511428","20855779558597092220421729043644421097567882416299330232034216564564950526636","6519425079251913392051942045477282225299671892088164438023219439721605388642","20855779558597092220421729043644421097567882416299330232034216564564950526636","6519425079251913392051942045477282225299671892088164438023219439721605388642","8783837757901443860992261731203352166088680998518358305889719217260481461755","3296439400080798469610507453190656735952953927715554951702367922805326006682","583825254917597650927671352843678736525108920225675575425786867634093046416","17053357643220384323863710618652377443193111556152926540382649656188531651363","18528578169592378552651152420890220187617132219150655543330876586098830163526","18528578169592378552651152420890220187617132219150655543330876586098830163526","15785174747872746802288701423021739827908926154732666358720472515606879619785","15976973745276982491090131793983128558702344526856265786725361435152736388487","15169851245221723110413033675112725827577768456369678500275170154941572815406","3315675409423943436311174482542795246165004444973576014673381147894352289560","13622731684237220471619929520269786825614321230062107415308319064813879976389","17667684225599541111471793231938849776968609286947879961504369551547590171984","20832159304281027117249863261987571284656897912031431885179846108337033579904","14463975229722029585351890196826970295720479391261271305643473201523245931387","9087960164408380074410718694096936308281839474236602989806568788043248036299","15169851245221723110413033675112725827577768456369678500275170154941572815406","4300572350692716926322064338442794706334296033420754501878900068315852013960","3315675409423943436311174482542795246165004444973576014673381147894352289560","13622731684237220471619929520269786825614321230062107415308319064813879976389","14723012190838600704321114257017887508085514222821981650487668468568161086913","12761298740118924812401960925411884563203910087633016384644650504209063420281","20815500981396964492857170694973157464236940453516355670308305132258324401423","4976613522806647398026972387903928579728932795346667708988426569113965838965","2850678529905758702184575770319417913773028434924673327153113907385911409071","15387686124135221134486675453972273239730903910439876604091952948828254572598","14610106937584944087914864488719605543415898929054092876437314909607409210820","2850678529905758702184575770319417913773028434924673327153113907385911409071","9973458468387742966944365205118428130802544598240430678025450792134388838556","15387686124135221134486675453972273239730903910439876604091952948828254572598","14610106937584944087914864488719605543415898929054092876437314909607409210820","16013972392770159522133916741376898032816805289132574238798412330632864681129","21109182447439763748189842114557145106726457504927027017001372829889038302403","2893956372856267233242113397492658778760771343541089433222819969947208285528","16013972392770159522133916741376898032816805289132574238798412330632864681129","21109182447439763748189842114557145106726457504927027017001372829889038302403","2893956372856267233242113397492658778760771343541089433222819969947208285528","14833791801447742371089688372397149326498315673747152083585462558961363955500","1749691857304370727198921487893387575984972572879480241513500474624572581295","6277915737565979329901249799473448999117568070992493130903564420884605477028","2612366146044524739177510256430522280450514706502013381760259490157404613704","485531284742124041748460430940382009694511083490418424583711935764860048840","6277915737565979329901249799473448999117568070992493130903564420884605477028","2612366146044524739177510256430522280450514706502013381760259490157404613704","10166967167519182007613128920926264515517129726670752743178060204550840172776","4265555671444175757529482628830512609686327342791491810898222144687171194775","10166967167519182007613128920926264515517129726670752743178060204550840172776","4349768184462841638851161244764505889977275635441081027987340139695929029984","19239534311620013106127163621527680922085830290877862104777654805209132068182","3602466916977702327662415305437531470391540030846271364896738609496435212400","19239534311620013106127163621527680922085830290877862104777654805209132068182","3602466916977702327662415305437531470391540030846271364896738609496435212400","10266175146101788235157737786856978373305305343870783516378190969835661421971","5779710446659075272341598503122238578148682479940822628096964854152935294411","10137074125767793191207913880828550578074507713842892753482885851281927274820","5779710446659075272341598503122238578148682479940822628096964854152935294411","10137074125767793191207913880828550578074507713842892753482885851281927274820","8495003466391501170012679313712016626582613790426809841930663899089273201181","12016696236825932234238810162669357948731483507717359462938646786379501467391","8218298151696725451829307160154686631223585040581270038842101562339218635658","14437293270777048249933559294802781696914284557257175872940330198976977275754","8294854552282071481128991888469153958278739050102269732778168512448618523473","14190888046768023004341935510446818526729986309091573556028642549211108365824","8218298151696725451829307160154686631223585040581270038842101562339218635658","1313494680900921016459265335558756716260254604407355519714600613303774117500","14437293270777048249933559294802781696914284557257175872940330198976977275754","11734593136683071684073205958882287196823364755791157238707241094309722608488","14747075813566974410311801029300973569177203074981266923496523232582328329492","7145432108608263361185454679454370340269206854359653961160265595063411701384","1577725188729263170060471380915259312960524889238351517098879614160989585084","4827132347829351965864332267602843356443286457942507078091043622646485167572","7145432108608263361185454679454370340269206854359653961160265595063411701384","1577725188729263170060471380915259312960524889238351517098879614160989585084","17661319510819438844516869338048261923105278999423144324866807682346704952734","3346901092797475025200864543324438649688188514323178532199273203808374929525","3991047616598241960744891843931044330692168731445129106865978394145354135687","10168095168090215824475118373437805202579375931371951693352649442371518409475","3346901092797475025200864543324438649688188514323178532199273203808374929525","3991047616598241960744891843931044330692168731445129106865978394145354135687","10464342387038248766710395014962663129656061630972051928473112152595305965313","10168095168090215824475118373437805202579375931371951693352649442371518409475","5968420644188904023180125014424163141905701075262532557962027610549304626982","2687543920121075745891586296819026477012556580174631099287874015206551945967","18070483626358388534994130981820879996444690011520031379149277783672915479252","19236069063061463537762876295670374868022003856936463313981279505640586608380","12446412306022476708942695418525732550264120330433687859871272826637141375648","10299983979722566739742233566040465677897294744137653012376580698840229405925","5968420644188904023180125014424163141905701075262532557962027610549304626982","2687543920121075745891586296819026477012556580174631099287874015206551945967","3405372863932487504751161258694044838689498597316580397388137677698631425910","13777860459426627943098436380378991745857519136849469968869398033828335336952","5156455482645620106919259520331322129605828471632457541444733603752057477684","18070483626358388534994130981820879996444690011520031379149277783672915479252","19236069063061463537762876295670374868022003856936463313981279505640586608380","11933406800407534146329328854752424088280885666820895312390170032553947029523","2671832336841576043004586482469938518737627293097010738414946812786622316634","3641322670245513772855762854787513253270679890115094543306691997977752446890","9880089708318309535773731932845988001605364562226481150212588261316560475992","15236676205631938382611156707865975370236102186374560024375160162199128496229","9880089708318309535773731932845988001605364562226481150212588261316560475992","15236676205631938382611156707865975370236102186374560024375160162199128496229","6208140861294537492301424103210355369832454234656273448944756443143797989655","11084791678652830048526146011902866629344826421164227239523413673883078482595","8710062150590115017536438587791719366578768813882761730172242970397605020532","986713989537569974692415941758674111901974530735638195707815388988769301082","21429393425995626024964537635050881735060537743266932525508328048270284407453","17602786934805945210101383665803030884362186803461201376220478881207312003401","17602786934805945210101383665803030884362186803461201376220478881207312003401","11839884666554288831622085554459572544294146341498980087741736014222005199961","13807826242072114652022881279278285534024981890948244607227886228671675535283","17005961325288594821569725942325981756375822072385588932979688595068357929481","4328330877349443194280535910664876736588609546304829363134530055582931555037","13807826242072114652022881279278285534024981890948244607227886228671675535283","17005961325288594821569725942325981756375822072385588932979688595068357929481","16689943949757273903351770088231413875729377765157450140101786933261491117219","21040245212581049676173618117306157193463508228119465577167747570070556117628","14929794629876028258582212406618118657528097267207594416385399498678655206551","5687982649709812581207429481813399922850505309659920547066715509032564215009","14929794629876028258582212406618118657528097267207594416385399498678655206551","5687982649709812581207429481813399922850505309659920547066715509032564215009","11933355021978082561269509548200179821472269006399858477296553222860845472479","5687982649709812581207429481813399922850505309659920547066715509032564215009","21040245212581049676173618117306157193463508228119465577167747570070556117628","14929794629876028258582212406618118657528097267207594416385399498678655206551","1211113335510895176441943282678959951000819217780145736950594654694674988239","4005604374527294489017393630720286881063393747359376214051555863842515177643","5928873990813908182895868821339804230994678645526849334684757789958558949738","21874891259053908365457783998334704478849200653384762278284159069213474310807","4005604374527294489017393630720286881063393747359376214051555863842515177643","10512388925676122078131027148724248123300507887905953914451646225580572889508","9763929448645163703075516285425174955982372831881058230734571789129857423940","9763929448645163703075516285425174955982372831881058230734571789129857423940","21229769008637357043275411627820366081540620848184463633808231621143222921899","20549773302381451532641764862840593130883522377857553061376350423820449057682","3647550682935496309308420004668635495088046823879152705545211791612724242158","3647550682935496309308420004668635495088046823879152705545211791612724242158","18182408627263272488791887066895952326698352062545744311242080437142057742925","8957028887841476827041425125746777155319910301544712091747719274605055737567","6237484950196408339346471368810924339085923344713660766441640499317591847254","10445362319944202443593046602370236376026565776039928626665110263266562963162","10445362319944202443593046602370236376026565776039928626665110263266562963162","714954023233617394257367784032120255164577716210678921244029185452871508526","20092498348483189069142096440029018599535629220013417373293886262676026232815","12483826500427227586609239390350609100850411225416610182437644201569751746592","3713815995754322882282546050268352812618595958166593451735236328407633812044","17296446835517969052143640464527823799987189000191956738187566544803975310011","6237484950196408339346471368810924339085923344713660766441640499317591847254","10445362319944202443593046602370236376026565776039928626665110263266562963162","714954023233617394257367784032120255164577716210678921244029185452871508526","4900638262509265659730166831460795819574151688750290380981772946051850711136","4900638262509265659730166831460795819574151688750290380981772946051850711136","15749240562958458240841866346182509560242016912523335462176548208024073653291","13398483778722170431628384087238223466188984839965162480295830658313043181452","7158818216693538357020756750495829013670671131695122613113493917212690160328","1158993837023855632712901892447954066141578734969108370984881563670594994498","16736559686738862217701874638259524347052591090043996826254519412578549055718","12820672475462497590503607323761853574154978460834058090763684445316127553417","16736559686738862217701874638259524347052591090043996826254519412578549055718","8124695956861117225317000773399538276421821112139371581010899988172935617337","12728280492756018517659258892772102645982304589372574277678178372493875053635","1403594668435162976760065863483379326186288409352462683752678706747846795700","20952351657393936145175721238995377596389655474094063456433118449662241184378","18797898200143337475342695660148912517935329859333665444745973684855377618499","4679753400849503248459095913219175706534627669304406601965831279894710367849","18797898200143337475342695660148912517935329859333665444745973684855377618499","12728280492756018517659258892772102645982304589372574277678178372493875053635","21000990465915047080427382990508129513491810059224879506174138911392340073285","6961316387981410954925847270628607178608128955997195733957585423743180498374","20952351657393936145175721238995377596389655474094063456433118449662241184378","5569473010804589455002364381689836614542929090091237404014272058253614739721","16603467537823048184916055464707571134842381817130307508067063566639210384941","324999046926740269926604754682209700762309894742374787463664361674485918931","16603467537823048184916055464707571134842381817130307508067063566639210384941","6524031643544699616792536140593132890963737360413661091152719115216761630450","469936633297472295114595813959125863116547049490895697354864350874487399725","21840676750858901736878853929819813679140895612579424308659587997940092827574","15936955748068996049737627493855587155756090720495273197609155091656505447171","11215448521755844319745344813689298495884609017113490841611411740736873595533","12903165589007832351674907655140968781008183448569658155665665821395752711065","469936633297472295114595813959125863116547049490895697354864350874487399725","21840676750858901736878853929819813679140895612579424308659587997940092827574","15936955748068996049737627493855587155756090720495273197609155091656505447171","6711149758042155914121707002966282169246659337034766143647833225833495365665","18722197525998380658561282128784256180313429131975539868068042267641696495279","13326618896945634896954506376200174300839604963537602244450129531442525434152","21492021844702296452834238833187728691838554451763294681428930188042382532589","14650588262448818488808559624349249571574381037098098157226633440667226691502","21305523869981231485427126985378100035732312441743529521519472979795060478158","21526789486389391135958837193481950312067058874020749210727242866858108419445","13717077264629786122830673304454167175227219110142343431306537208805175734740","21158155532425471696207847541235796602520806573855323167795583471104572727695","2197676654167290320414066336707807362572143871102417065681358137460610178176","8468194510381160979666542298694068064904907911239384394933535824262497506549","11306247346588852714325527487357500699090032151443836570348863218046171903508","17260933835635105491671489363942014656372334513178341388779030305888046160504","4148504680896221026110361448532794582016345748525207564671903838604515877640","1179136415439801860745718538803483101160740233841330166488521085274337891241","7481246930859578261727088637864822364456845800818786080525096339079309059688","17762390131126106318354596686456049753617708904281725254125144990908594992871","18867540740018444677320985357129407777551210578108581316650236575958241759316","4148504680896221026110361448532794582016345748525207564671903838604515877640","18867540740018444677320985357129407777551210578108581316650236575958241759316","1179136415439801860745718538803483101160740233841330166488521085274337891241","7481246930859578261727088637864822364456845800818786080525096339079309059688","17762390131126106318354596686456049753617708904281725254125144990908594992871","11470810587005325546917975208221639406835127441178579492999304375136890904512","5532043165016181116318960584738816722236636266776992166891663858991677404753","13433096062810382138961538832424918051435182863844640107482674451655696373484","17774965647771973872549011097210629013082531304056503607173821916899273605387","11470810587005325546917975208221639406835127441178579492999304375136890904512","5532043165016181116318960584738816722236636266776992166891663858991677404753","1159464358521348195944007674782836339101342173906724943330346036376777666149","17774965647771973872549011097210629013082531304056503607173821916899273605387","8379370382455568097070109119753155225895472366883035993816406147467052995263","17166720277322135135596534441782198375393651669362133012265647637183110604439","2314564072114705798741734290412040763161415142512744680352681481284026001139","7008234203610765895829950936901588685803443905459862271194259617513217336713","7038465039033234941089886770696047347570826812239511438128404899294902173156","14691616534236177529219273071670447640188689722434612699278560562717040347762","1345950765930232323746053203023439272701461370137684391092951531732027691652","13318731889771395205366790902540375412605853148017549104858505786143973827210","7038465039033234941089886770696047347570826812239511438128404899294902173156","8876494411507537568990933110054668762933574582557442894595301886817082064105","21152377500001782274122330265999023127417677621819182954285385752898815966281","1345950765930232323746053203023439272701461370137684391092951531732027691652","13318731889771395205366790902540375412605853148017549104858505786143973827210","10509454627809127746418837009254963231248830082091203670023094742103303164951","21195232262166189686278587398223643468918650618276278829091496429923602044287","15402621928200741381262061017849499133421266682872140789631662278785132678371","3643334039014435780290652600735389536337959943340000442227756934776600913804","2720027746403097687091832985908286933615138476096898443441522183426308965676","21449422350449624955916507731438690265650451160747016706913840686788874439165","8655266815572873806523305018387968081530351318367886178554365057421523209442","2720027746403097687091832985908286933615138476096898443441522183426308965676","21449422350449624955916507731438690265650451160747016706913840686788874439165","16696172076894472932133731843878056523085227043714616195934761171322168193569","8655266815572873806523305018387968081530351318367886178554365057421523209442","16857079459733443989263776605936166708896418212790539086244209496286682268538","19578685594798735789139904200355657795730519165099953078075278009506478180875","4260532707016214524932180376411336362439469810511228048470363945793959216113","17424133031122072652875411073023004164268028863964428381806504964220552803813","16857079459733443989263776605936166708896418212790539086244209496286682268538","6248832255628132632252872026663853109004533483251757038981686654509205338281","19389172666549916781030176824886257222727573299690761242722158273625625444898","9528981216337453682457936544315870171184755132944613913459967937528385736347","8558906862942018617212238846470802929486472683559398440021906000152650901718","19389172666549916781030176824886257222727573299690761242722158273625625444898","10564800431700923255310506585247312219759552781817889665564198355028474163171","3604947704752784945356671967100621025097946939874312208206089040905324856228","8558906862942018617212238846470802929486472683559398440021906000152650901718","6428971680009699468643739436558632034866707301235638859550834653096215606767","516043008342215817136478593555377650232620038572181684375423959229181887613","16453526853698853851702744707013440931180327404716062491874747564109210609142","4108120583560231201707992713271973547996332660439868049157295367800113066064","12778268703230965783853860438250842225114777776720508446365055060929697691554","4108120583560231201707992713271973547996332660439868049157295367800113066064","13662414773203964936182372108654543836693920733303092996385768505049810447934","15489924324647949873104312626440688394871314026376798543896742022067814585335","19777890693283216566031679483185089267663134142114892519341952598646727534453","3850140338912390441359629231848679437475967351840215821017886110316614364631","13423092212596344567096389329420147798194268490827942268545749370206221248011","7571188409731705895759684443912315107950063720703844243586865899077288286542","13423092212596344567096389329420147798194268490827942268545749370206221248011","7571188409731705895759684443912315107950063720703844243586865899077288286542","20770397947032821092417508731447785495579357430428300854425593489746755744214","496122310891804593465601697597405700922825724376838750146652581797655181432","14377847246135930901520257047309181674854761250236413731499354313765911135623","7387968641554545312271427138663212917211832969824335412654477592286998838501","13236017248774671381090819409676649295884433371310832975038943525531785721122","496122310891804593465601697597405700922825724376838750146652581797655181432","3996127688940615912132515447755042932091415591985840592023478275377394228506","881390952520597768656421031278601185054033099037943941912906675865662485105","3554962622726433031313758999911360324222548606229054909929021431219199358836","881390952520597768656421031278601185054033099037943941912906675865662485105","10666739185778907331279945146717732424049136291271082516399349534079143021031","17762390131126106318354596686456049753617708904281725254125144990908594992871","516043008342215817136478593555377650232620038572181684375423959229181887613","6277915737565979329901249799473448999117568070992493130903564420884605477028","11734593136683071684073205958882287196823364755791157238707241094309722608488","6208140861294537492301424103210355369832454234656273448944756443143797989655","9880089708318309535773731932845988001605364562226481150212588261316560475992","15236676205631938382611156707865975370236102186374560024375160162199128496229","11215448521755844319745344813689298495884609017113490841611411740736873595533","469936633297472295114595813959125863116547049490895697354864350874487399725","4148504680896221026110361448532794582016345748525207564671903838604515877640","17005961325288594821569725942325981756375822072385588932979688595068357929481","3996127688940615912132515447755042932091415591985840592023478275377394228506","14377847246135930901520257047309181674854761250236413731499354313765911135623","7387968641554545312271427138663212917211832969824335412654477592286998838501","7038465039033234941089886770696047347570826812239511438128404899294902173156","8876494411507537568990933110054668762933574582557442894595301886817082064105","4394523597815741176184429346029872426573465305146918935614534250320004925022","15976973745276982491090131793983128558702344526856265786725361435152736388487","3646338192331068927987760816768960751428354429547935553137786759643406164188","14463975229722029585351890196826970295720479391261271305643473201523245931387","20832159304281027117249863261987571284656897912031431885179846108337033579904","4976613522806647398026972387903928579728932795346667708988426569113965838965","11470810587005325546917975208221639406835127441178579492999304375136890904512","11933406800407534146329328854752424088280885666820895312390170032553947029523","4005604374527294489017393630720286881063393747359376214051555863842515177643","2612366146044524739177510256430522280450514706502013381760259490157404613704","5928873990813908182895868821339804230994678645526849334684757789958558949738","14929794629876028258582212406618118657528097267207594416385399498678655206551","17667684225599541111471793231938849776968609286947879961504369551547590171984","10360361317773174330609182687165497568974066020350179444918980867813184165772","414376870353557956557410073611570035767149620606037626284506478934856934950","2082198709204553956196180197968070198531678808304059894038068876628063276452","20656407170301550737698921276078630269108794924656235576678360422623873054093","12761298740118924812401960925411884563203910087633016384644650504209063420281","9087960164408380074410718694096936308281839474236602989806568788043248036299","3554962622726433031313758999911360324222548606229054909929021431219199358836","20335260146178674389103551046698495925066195667221545379041016416396476420437","4448809397468725058232173764984943290899016438744183560624382545872203198874","20952351657393936145175721238995377596389655474094063456433118449662241184378","3277930968333006226994847738933990737680775891955222168407716460748300707158","4679753400849503248459095913219175706534627669304406601965831279894710367849","12728280492756018517659258892772102645982304589372574277678178372493875053635","21000990465915047080427382990508129513491810059224879506174138911392340073285","819452702753981081689185761349208570618201235951568805131055583784722655971","6961316387981410954925847270628607178608128955997195733957585423743180498374","7571188409731705895759684443912315107950063720703844243586865899077288286542","9973458468387742966944365205118428130802544598240430678025450792134388838556","15713307113278415371010868232537615201250755088837294269604774217739372010113","1577725188729263170060471380915259312960524889238351517098879614160989585084","1796957178734482015506867047302475274666398525243702983442198711287391956289","16278169846291832591805126166569561888248726635057139721318669759273740399252","14676343103153240585706964450506962525086882358169959280626081129707121953716","9763929448645163703075516285425174955982372831881058230734571789129857423940","15936955748068996049737627493855587155756090720495273197609155091656505447171","16736559686738862217701874638259524347052591090043996826254519412578549055718","8597344610347921072150719301389985265870490344277768698655211343733413940106","15387686124135221134486675453972273239730903910439876604091952948828254572598","16222698142027065811167390241750753175579907013568549983876951514005846421095","17536425941289720974075831261344431974606164971374420796902324640542282148630","3850140338912390441359629231848679437475967351840215821017886110316614364631","3893697165891991063779051056328319531986137474524413386839530965272458053622","15022075699156825769107820827421099389029532163560314923653419344816089612754","15618704577094537211117942495330534996697879125403937074624030451849733511428","1345950765930232323746053203023439272701461370137684391092951531732027691652","21580028205680906361118993236600963344267403037726984304307464793067294355729","1211113335510895176441943282678959951000819217780145736950594654694674988239","14610106937584944087914864488719605543415898929054092876437314909607409210820","4523810781915842047076535306645431742720352627377904433199873900489914621383","10137074125767793191207913880828550578074507713842892753482885851281927274820","12778268703230965783853860438250842225114777776720508446365055060929697691554","4108120583560231201707992713271973547996332660439868049157295367800113066064","4033047260904480687204595546699259158166619861427665067518166271447391319942","15175516717719684822963819968624494260929148159674850407752893930198906885135","15785174747872746802288701423021739827908926154732666358720472515606879619785","13318731889771395205366790902540375412605853148017549104858505786143973827210","10166967167519182007613128920926264515517129726670752743178060204550840172776","4406080051384460089705531758621172664443830175063289268103825864171858609265","17774965647771973872549011097210629013082531304056503607173821916899273605387","8218298151696725451829307160154686631223585040581270038842101562339218635658","8957028887841476827041425125746777155319910301544712091747719274605055737567","7984676778317857222661965281535282801145319516927617697518763614880794377643","3211042168604779967884960563496543020838019199076905676204211041950279066160","8379370382455568097070109119753155225895472366883035993816406147467052995263","4349144950613433996177130888728677722537174742649722313120149478315866151584","881390952520597768656421031278601185054033099037943941912906675865662485105","19239534311620013106127163621527680922085830290877862104777654805209132068182","3602466916977702327662415305437531470391540030846271364896738609496435212400","18917596795505756870449968581803126293454890656759307670277029832148833419968","15506700250182067920710015238905217087220925399501249779325982853643399991213","3620835158769768807844342318006999432108401441279035780613891462931678937586","3991047616598241960744891843931044330692168731445129106865978394145354135687","496122310891804593465601697597405700922825724376838750146652581797655181432","714954023233617394257367784032120255164577716210678921244029185452871508526","6519425079251913392051942045477282225299671892088164438023219439721605388642","11306247346588852714325527487357500699090032151443836570348863218046171903508","3647550682935496309308420004668635495088046823879152705545211791612724242158","17602786934805945210101383665803030884362186803461201376220478881207312003401","18528578169592378552651152420890220187617132219150655543330876586098830163526","4091374269735928088984434925139578019042456334252238080767424696286159266206","3604947704752784945356671967100621025097946939874312208206089040905324856228","7913877485184319926526109781232126173378890461283675426684516109426023323425","14747075813566974410311801029300973569177203074981266923496523232582328329492","3346901092797475025200864543324438649688188514323178532199273203808374929525","17885146251437424691325742316730119640879313676136548328826378418708611705444","17260933835635105491671489363942014656372334513178341388779030305888046160504","19763508703433324186810614383831636069637659978730401892067849105738461208697","17767549241598520620639909654917084757165711422841767036110821106222818602846","8655266815572873806523305018387968081530351318367886178554365057421523209442","16566925439259090889559377979720612778996548701288310072864747272852918324526","21040245212581049676173618117306157193463508228119465577167747570070556117628","10445362319944202443593046602370236376026565776039928626665110263266562963162","1026061344167229557530280237821161161892591142813273843769502549447660133566","23359677666362742165865492301907590646033560607404072297051567228192705866","15169851245221723110413033675112725827577768456369678500275170154941572815406","13622731684237220471619929520269786825614321230062107415308319064813879976389","21204573358727202056523206487171135477180384483659853057348449256700166055201","3315675409423943436311174482542795246165004444973576014673381147894352289560","20258911148557107507482478471794950611997282070284146817830384759162894019333","21204670842347111148234027527394563833644546399150026122862702499480712250795","17424133031122072652875411073023004164268028863964428381806504964220552803813","16857079459733443989263776605936166708896418212790539086244209496286682268538","13326618896945634896954506376200174300839604963537602244450129531442525434152","12483826500427227586609239390350609100850411225416610182437644201569751746592","6237484950196408339346471368810924339085923344713660766441640499317591847254","4345865012300113780023115661070600377397578665737945037487473194565302055151","7145432108608263361185454679454370340269206854359653961160265595063411701384","3043704851478274488864992049689320140096539776364694886103508818509066041618","214315323819057312983317374041305201494892368555098687059514331685205473409","965120183901982214132822702955424351463204860150394249799605972844930682282","12880246921382128468495594122300999732304604277752631469876119605813044386484","4827132347829351965864332267602843356443286457942507078091043622646485167572","6910720958939230045781950666462557637024502053503211049133328071734623368998","3713815995754322882282546050268352812618595958166593451735236328407633812044","20092498348483189069142096440029018599535629220013417373293886262676026232815","20243592237779768385633180828747562911013942619597535676704306178417638676735","8783837757901443860992261731203352166088680998518358305889719217260481461755","5968420644188904023180125014424163141905701075262532557962027610549304626982","1749691857304370727198921487893387575984972572879480241513500474624572581295","2893956372856267233242113397492658778760771343541089433222819969947208285528","7481246930859578261727088637864822364456845800818786080525096339079309059688","5863066218446268953003799713454410507966032909447176862161847722734248823219","1179136415439801860745718538803483101160740233841330166488521085274337891241","11156435013531908654639190892115092728335551234708805315487558056971764291948","4328330877349443194280535910664876736588609546304829363134530055582931555037","10512388925676122078131027148724248123300507887905953914451646225580572889508","21874891259053908365457783998334704478849200653384762278284159069213474310807","21195232262166189686278587398223643468918650618276278829091496429923602044287","10509454627809127746418837009254963231248830082091203670023094742103303164951","3643334039014435780290652600735389536337959943340000442227756934776600913804","20855779558597092220421729043644421097567882416299330232034216564564950526636","21109182447439763748189842114557145106726457504927027017001372829889038302403","18168744163424016335206427335988097612909912457508366312463021028976120115992","4265555671444175757529482628830512609686327342791491810898222144687171194775","17157073891307130997081716052218616890370492463575509762538311686836597765749","18182408627263272488791887066895952326698352062545744311242080437142057742925","21152377500001782274122330265999023127417677621819182954285385752898815966281","14650588262448818488808559624349249571574381037098098157226633440667226691502","15566924557101820668621745814533207678594196467973154086441485832643667260065","9919062896982845139836050062235212874134726053358031048240308503371076736202","6495001369153806233149360210213506139429938273921172760613507373934794009267","5968420644188904023180125014424163141905701075262532557962027610549304626982","13777860459426627943098436380378991745857519136849469968869398033828335336952","3405372863932487504751161258694044838689498597316580397388137677698631425910","4349768184462841638851161244764505889977275635441081027987340139695929029984","7008234203610765895829950936901588685803443905459862271194259617513217336713","14968706338272118024318941851938453335065446453407012752047893638591148228190","18357101115986091017858932645933192184388969541140787722944950516891498537522","21590437603227450350896974812668257293344109399089672260050985953754817498509","1158993837023855632712901892447954066141578734969108370984881563670594994498","7158818216693538357020756750495829013670671131695122613113493917212690160328","16603467537823048184916055464707571134842381817130307508067063566639210384941","5156455482645620106919259520331322129605828471632457541444733603752057477684","16689943949757273903351770088231413875729377765157450140101786933261491117219","2671832336841576043004586482469938518737627293097010738414946812786622316634","16689943949757273903351770088231413875729377765157450140101786933261491117219","8558906862942018617212238846470802929486472683559398440021906000152650901718","19259464281379536898098596227245023985381466360162258498700407301057497236237","20493267855144070358195638415398934378215145744769249913176749097323547605781","2574782088973261153507384481892857330991594704377254630554468420785000111151","7266226068479050483596757429526140620733503942326350022983657473316552489020","18617274746629671393653978658133948251308816979070995942621676351843802249592","19259464281379536898098596227245023985381466360162258498700407301057497236237","485531284742124041748460430940382009694511083490418424583711935764860048840","14437293270777048249933559294802781696914284557257175872940330198976977275754","11933355021978082561269509548200179821472269006399858477296553222860845472479","5687982649709812581207429481813399922850505309659920547066715509032564215009","20952351657393936145175721238995377596389655474094063456433118449662241184378","4679753400849503248459095913219175706534627669304406601965831279894710367849","14140202980699856368259208442069851567782944491376906601766971253633303671451","6318665075946194493459655890331592579446130571387311970988366413606513309666","6005403742689638655620405649580760986236367850990690162391254488154117234798","14344638515639235090103311854983149159811950562417604236417118564333967228937","2671832336841576043004586482469938518737627293097010738414946812786622316634","6005403742689638655620405649580760986236367850990690162391254488154117234798","7145432108608263361185454679454370340269206854359653961160265595063411701384","17661319510819438844516869338048261923105278999423144324866807682346704952734","8279825353047494318783037001377251303760615169230439387753982716513625908687","15387686124135221134486675453972273239730903910439876604091952948828254572598","5156455482645620106919259520331322129605828471632457541444733603752057477684","1313494680900921016459265335558756716260254604407355519714600613303774117500","4300572350692716926322064338442794706334296033420754501878900068315852013960","20198069270767154959332371503075291405283865644171881146662811612509310416148","15250118708059186722535006350549112049546058570630526911964606021686849478532","17027113931861622850159556967682809217465015923214421487888561514025113184847","10666739185778907331279945146717732424049136291271082516399349534079143021031","15756336906489319637145132659446194580646683774419080032096163982053369688475","10564800431700923255310506585247312219759552781817889665564198355028474163171","20787800617848718687038293526894262560387945185119615793461461441224112565181","3786201425960476069693538028353723102692351180358735597793563648058153004843","4958504168564817189540141047070913434865581542601332277438161408667819346759","17301669269848779952066601523784579541383931503742032895653034834739898765225","17218221380970374884949419711825983624038044917128561657254116913876948067001","13055296958068478164428841582662055656217220837751683797828993143295551077738","15749240562958458240841866346182509560242016912523335462176548208024073653291","4597458322184902056270303124598074887925246394563304797626410619341840027487","10491650337094546480533868931057278488290537217135545426947222084556247420757","8558906862942018617212238846470802929486472683559398440021906000152650901718","19355741033906370113440221517455176128679440843374751751036940483172148604648","21541759225339649747231262974974118143002421328093705664986988600406768821920","7344190232084649119572947040765063791118140776620579670615768309555511246518","6884075464604312492173488084188283921727182284614451612836421476613656956499","8570379430442361003281814054322251185015164526672015239927739289873065945423","6318665075946194493459655890331592579446130571387311970988366413606513309666","20817254064066459283482375098057401691813782156305850021432668272160048911569","21413882171498010258649496020634791409885166660173858123386655742825206921978","6747494411033088688551122586451739534002780294408025960289031829911891743270","12202874191839586286098351834111344593674295075294868127002123245046259381570","20809759278883015025959616255569110837491516632479521280268753583795105395521","18648171460878272692685121226165242598515726204792844296253321720387600528575","10266175146101788235157737786856978373305305343870783516378190969835661421971","324999046926740269926604754682209700762309894742374787463664361674485918931","6524031643544699616792536140593132890963737360413661091152719115216761630450","9695096278639932953551411692799281586571206774256251347108368176089307962131","19578685594798735789139904200355657795730519165099953078075278009506478180875","17167861709022493790715742055500284043623842348728963940210937409194295541448","11084791678652830048526146011902866629344826421164227239523413673883078482595","11839884666554288831622085554459572544294146341498980087741736014222005199961","21492021844702296452834238833187728691838554451763294681428930188042382532589","3602466916977702327662415305437531470391540030846271364896738609496435212400","5458078752534629863150376441977934705670924234857598478571356404874122529274","14610106937584944087914864488719605543415898929054092876437314909607409210820","12476354133768184089123277840955435934210129919118647812157740052884815889605","12202874191839586286098351834111344593674295075294868127002123245046259381570","7038465039033234941089886770696047347570826812239511438128404899294902173156","13933699382737047289158702974718649407716930085885355266090438884507096945210","6249392517363253167779616348905959483446066045691516614606832981076584752208","10148209845659871484513821698269951081443261221517982094874643676821531595521","5321117970386033821609764827223803970785728861777270687453169822327594589129","20770397947032821092417508731447785495579357430428300854425593489746755744214","13318731889771395205366790902540375412605853148017549104858505786143973827210","5968420644188904023180125014424163141905701075262532557962027610549304626982","2308004867169977960145746239684043327551343201554676435259716827646912324708","17166720277322135135596534441782198375393651669362133012265647637183110604439","16603467537823048184916055464707571134842381817130307508067063566639210384941","7374116963404369208201867494748485754208122585231599951214000563819243700937","6519425079251913392051942045477282225299671892088164438023219439721605388642","10491650337094546480533868931057278488290537217135545426947222084556247420757","21305523869981231485427126985378100035732312441743529521519472979795060478158","11215448521755844319745344813689298495884609017113490841611411740736873595533","2687543920121075745891586296819026477012556580174631099287874015206551945967","20531567482650659149562495538742686303399905267566477050925523359575081285407","3671401356592811213817020202477677079097246476002573845174251219123880069605","370724463901971790508498324710584598609994022751767726217271516297761092210","17859075345886143972481888544155581675756404028011950483439401219576934127477","19236069063061463537762876295670374868022003856936463313981279505640586608380","7300914418786862392955059361376468982352883488957061438990732012589515848887","18366823355942360112802764932497116141643175464429853053384857320000579142693","21511609857245550884675342004405514602220962465050811399674566575623610922036","10600751707779883427770404817757210009105229880596864346536264436480867194465","14691616534236177529219273071670447640188689722434612699278560562717040347762","12917841815297098239286122365946643421792747074102708194854298545960292794221","8025800536169977653904884790681397639022870667510972231021398045625978056243","21526789486389391135958837193481950312067058874020749210727242866858108419445","19069881331998668546877128394973563789293293922733497677453463523696775545344","16902519183246183043912896657829262931188924467519711950631169513234864878692","1345950765930232323746053203023439272701461370137684391092951531732027691652","4005604374527294489017393630720286881063393747359376214051555863842515177643","6248832255628132632252872026663853109004533483251757038981686654509205338281","21204573358727202056523206487171135477180384483659853057348449256700166055201","10464342387038248766710395014962663129656061630972051928473112152595305965313","17602786934805945210101383665803030884362186803461201376220478881207312003401","469936633297472295114595813959125863116547049490895697354864350874487399725","14929794629876028258582212406618118657528097267207594416385399498678655206551","14463975229722029585351890196826970295720479391261271305643473201523245931387","2755559194434906017746744022882352726926151903345593007930152736736342706273","17754149174168474811415362410589473479738992892340958664939964650074463465353","14697292947487306866716163814882600766835755193334844439948446067319846550351","258543196243020620165454518675080430109472516494419776866513528402275970609","10168095168090215824475118373437805202579375931371951693352649442371518409475","6711149758042155914121707002966282169246659337034766143647833225833495365665","13423092212596344567096389329420147798194268490827942268545749370206221248011","7571188409731705895759684443912315107950063720703844243586865899077288286542","15140587659541893631614393054606825008610793314581094358226050617520199277479","10360361317773174330609182687165497568974066020350179444918980867813184165772","18048811994743295626787578191894763929517689087463996234052185555823148986775","9848112197036668436206256445357463656561660127687812363925793467115559632574","18048811994743295626787578191894763929517689087463996234052185555823148986775","9848112197036668436206256445357463656561660127687812363925793467115559632574","12016696236825932234238810162669357948731483507717359462938646786379501467391","16278169846291832591805126166569561888248726635057139721318669759273740399252","7051702148943106215662907092512860029252750203190881142196097475724191547008","2850678529905758702184575770319417913773028434924673327153113907385911409071","4448809397468725058232173764984943290899016438744183560624382545872203198874","3620835158769768807844342318006999432108401441279035780613891462931678937586","21366556183092180597593404040344305829971639266129160807007460967113399900600","17027113931861622850159556967682809217465015923214421487888561514025113184847","7051702148943106215662907092512860029252750203190881142196097475724191547008","21580028205680906361118993236600963344267403037726984304307464793067294355729","881390952520597768656421031278601185054033099037943941912906675865662485105","8495003466391501170012679313712016626582613790426809841930663899089273201181","10137074125767793191207913880828550578074507713842892753482885851281927274820","5779710446659075272341598503122238578148682479940822628096964854152935294411","15756336906489319637145132659446194580646683774419080032096163982053369688475","3647550682935496309308420004668635495088046823879152705545211791612724242158","485531284742124041748460430940382009694511083490418424583711935764860048840","4406080051384460089705531758621172664443830175063289268103825864171858609265","10166967167519182007613128920926264515517129726670752743178060204550840172776","17218221380970374884949419711825983624038044917128561657254116913876948067001","4523810781915842047076535306645431742720352627377904433199873900489914621383","4260532707016214524932180376411336362439469810511228048470363945793959216113","4958504168564817189540141047070913434865581542601332277438161408667819346759","3786201425960476069693538028353723102692351180358735597793563648058153004843","13055296958068478164428841582662055656217220837751683797828993143295551077738","4900638262509265659730166831460795819574151688750290380981772946051850711136","6428971680009699468643739436558632034866707301235638859550834653096215606767","17881911232050902476787432073414396640768751225834381803302132390954321261765","15936955748068996049737627493855587155756090720495273197609155091656505447171","17301669269848779952066601523784579541383931503742032895653034834739898765225","11995110279269743520619405429490183298492145615015808343279904162767490935917","19173727814007526369475658695800333995431630659179829874925231476263443680836","20157794112729442197272015708837539559433678935376552756733479541306727404798","3647550682935496309308420004668635495088046823879152705545211791612724242158","3647550682935496309308420004668635495088046823879152705545211791612724242158","13236017248774671381090819409676649295884433371310832975038943525531785721122","20157794112729442197272015708837539559433678935376552756733479541306727404798","8655266815572873806523305018387968081530351318367886178554365057421523209442","6742340340486138517895715495173923350670637330946604847347750370613811676641","2107234666111114662116528760102466740619937500370692000054256661195233855790","18528578169592378552651152420890220187617132219150655543330876586098830163526","4091374269735928088984434925139578019042456334252238080767424696286159266206","7286267794329676130056177250143876094096845713766208146913412228310830485638","20549773302381451532641764862840593130883522377857553061376350423820449057682","10268871991793671998060621744998223092545732009516241433892379776841437193714","7913877485184319926526109781232126173378890461283675426684516109426023323425","9880089708318309535773731932845988001605364562226481150212588261316560475992","15236676205631938382611156707865975370236102186374560024375160162199128496229","2107234666111114662116528760102466740619937500370692000054256661195233855790","6671278482098995862309619506762101787864599647242706871984427874206562934651","13266933730564879929094432282203503421879260785977452203840137924355696723373","21449422350449624955916507731438690265650451160747016706913840686788874439165","17885146251437424691325742316730119640879313676136548328826378418708611705444","19763508703433324186810614383831636069637659978730401892067849105738461208697","14437293270777048249933559294802781696914284557257175872940330198976977275754","714954023233617394257367784032120255164577716210678921244029185452871508526","7344190232084649119572947040765063791118140776620579670615768309555511246518","4108120583560231201707992713271973547996332660439868049157295367800113066064","21040245212581049676173618117306157193463508228119465577167747570070556117628","6884075464604312492173488084188283921727182284614451612836421476613656956499","10445362319944202443593046602370236376026565776039928626665110263266562963162","16566925439259090889559377979720612778996548701288310072864747272852918324526","16857079459733443989263776605936166708896418212790539086244209496286682268538","23359677666362742165865492301907590646033560607404072297051567228192705866","16696172076894472932133731843878056523085227043714616195934761171322168193569","1026061344167229557530280237821161161892591142813273843769502549447660133566","3315675409423943436311174482542795246165004444973576014673381147894352289560","13622731684237220471619929520269786825614321230062107415308319064813879976389","20258911148557107507482478471794950611997282070284146817830384759162894019333","20817254064066459283482375098057401691813782156305850021432668272160048911569","4345865012300113780023115661070600377397578665737945037487473194565302055151","21658287553238324508726963229884488979848799405033447152726597360070893647103","12880246921382128468495594122300999732304604277752631469876119605813044386484","20593609336545582585516607350021226611828027937493904817740624555078806393815","6516407508203833987214521679015161382976142645596925368306496632940263530054","7286267794329676130056177250143876094096845713766208146913412228310830485638","8785578159009271607111203917917967155859009349378752418760742237587259562001","17233249885835201128091787447928528987433597827434283233453544321927732151682","20815500981396964492857170694973157464236940453516355670308305132258324401423","7057205765487545351568626407787993065840241149856637257364771643976880915796","15169851245221723110413033675112725827577768456369678500275170154941572815406","6910720958939230045781950666462557637024502053503211049133328071734623368998","5532043165016181116318960584738816722236636266776992166891663858991677404753","11839884666554288831622085554459572544294146341498980087741736014222005199961","11933355021978082561269509548200179821472269006399858477296553222860845472479","11156435013531908654639190892115092728335551234708805315487558056971764291948","15402621928200741381262061017849499133421266682872140789631662278785132678371","3719149845596930873853864239236007518103274499007787468563615245536107561467","5458078752534629863150376441977934705670924234857598478571356404874122529274","16013972392770159522133916741376898032816805289132574238798412330632864681129","5687982649709812581207429481813399922850505309659920547066715509032564215009","21840676750858901736878853929819813679140895612579424308659587997940092827574","18070483626358388534994130981820879996444690011520031379149277783672915479252","12903165589007832351674907655140968781008183448569658155665665821395752711065","5968420644188904023180125014424163141905701075262532557962027610549304626982","21590437603227450350896974812668257293344109399089672260050985953754817498509","13777860459426627943098436380378991745857519136849469968869398033828335336952","20855779558597092220421729043644421097567882416299330232034216564564950526636","12446412306022476708942695418525732550264120330433687859871272826637141375648","1159464358521348195944007674782836339101342173906724943330346036376777666149","1218670090910086107298418643927909512264005016215730157829360975549302053822","7726792286473802857280466567840606186420831161587091626690384923672197163758","414376870353557956557410073611570035767149620606037626284506478934856934950","13398483778722170431628384087238223466188984839965162480295830658313043181452","10168095168090215824475118373437805202579375931371951693352649442371518409475","6277915737565979329901249799473448999117568070992493130903564420884605477028","17005961325288594821569725942325981756375822072385588932979688595068357929481","2590711105529079928997585398804115834624626142955460287952856556665915535771","14723012190838600704321114257017887508085514222821981650487668468568161086913","2720027746403097687091832985908286933615138476096898443441522183426308965676","5687982649709812581207429481813399922850505309659920547066715509032564215009","5532043165016181116318960584738816722236636266776992166891663858991677404753","1218670090910086107298418643927909512264005016215730157829360975549302053822","18797898200143337475342695660148912517935329859333665444745973684855377618499","3277930968333006226994847738933990737680775891955222168407716460748300707158","4394523597815741176184429346029872426573465305146918935614534250320004925022","20593609336545582585516607350021226611828027937493904817740624555078806393815","13807826242072114652022881279278285534024981890948244607227886228671675535283","2850678529905758702184575770319417913773028434924673327153113907385911409071","20593609336545582585516607350021226611828027937493904817740624555078806393815","3646338192331068927987760816768960751428354429547935553137786759643406164188","7205078877874692762658377924753593251222887253955205326355691460857991852413","7205078877874692762658377924753593251222887253955205326355691460857991852413","17774965647771973872549011097210629013082531304056503607173821916899273605387","8218298151696725451829307160154686631223585040581270038842101562339218635658","3211042168604779967884960563496543020838019199076905676204211041950279066160","10166967167519182007613128920926264515517129726670752743178060204550840172776","13423092212596344567096389329420147798194268490827942268545749370206221248011","19239534311620013106127163621527680922085830290877862104777654805209132068182","19389172666549916781030176824886257222727573299690761242722158273625625444898","8046445762844817721900991450492979786512696272411046971227782243837978513718","2590711105529079928997585398804115834624626142955460287952856556665915535771","14929794629876028258582212406618118657528097267207594416385399498678655206551","8649059366217618400937620154735241039812173976487644012884025150717308261619","496122310891804593465601697597405700922825724376838750146652581797655181432","8978280865886639509278001260471033159857304570194032467981298496681997702746","8649059366217618400937620154735241039812173976487644012884025150717308261619","19941844271627511273130969337829221561447757515842720279505811118403543705107","19941844271627511273130969337829221561447757515842720279505811118403543705107","8283552763944976109733812222757518983099907486799759852949564415768745888517","1577725188729263170060471380915259312960524889238351517098879614160989585084","12099148004409851257403032698517570792005129666747871644640037957919947193125","12099148004409851257403032698517570792005129666747871644640037957919947193125","8283552763944976109733812222757518983099907486799759852949564415768745888517","16013972392770159522133916741376898032816805289132574238798412330632864681129","18168744163424016335206427335988097612909912457508366312463021028976120115992","3886595464395668046809959888373210111097350914489337221148440355605809749337","16302943973192121937016650211653994395718070596375664106667990668687838453153","14582264268232397011887253167149494860956785201240512685641738448237231828736","21762504892378019106601699047999443634797454499478732426757693616571346077673","18925796450678100586324028452383387960952136093365191750994987333520560513325","7830501195460460735156250974424901899267553772579768295064574198503836226095","17459618280586217139079882008504689252456724660699657609025751475166618477629","15489924324647949873104312626440688394871314026376798543896742022067814585335","739617424967684945039289223892970067007580501918307209971562881004858314006","1427181454007951447518808395283625346345538230275885566108016232335116334362","2197676654167290320414066336707807362572143871102417065681358137460610178176","5779710446659075272341598503122238578148682479940822628096964854152935294411","1330356694053572109622274721044207364701652930019035301529439790768699789569","14190888046768023004341935510446818526729986309091573556028642549211108365824","986713989537569974692415941758674111901974530735638195707815388988769301082","21429393425995626024964537635050881735060537743266932525508328048270284407453","5368588078284603073748144362332842841822995653024975981683751920339816769012","3296439400080798469610507453190656735952953927715554951702367922805326006682","3947864640489471418895982036934201452345860011397861716300443804550428167832","15932432347284281687951151509643659962057401544253189045048518758873171461549","18722197525998380658561282128784256180313429131975539868068042267641696495279","10774259477721477870205124946879057926250931659988920167480022788843171119577","5739938844776624344588520573092114131804626813850271764512401508049501761035","15685542543524369200367213924254041726039990145599010079578158309164790431204","14768237462094083403730774215097603653346981332332504836841836851582942009574","8468194510381160979666542298694068064904907911239384394933535824262497506549","1391081092351829830157951197965398149209228110464739632012647043060266683696","2910817174979798622184406487425724377397777238421720370863070507924183171096","3851748667462911078898928476271530585249968830768997448877629962274598495519","6723449119930035775131344265006189431412054913412835771153873629642496678609","13807826242072114652022881279278285534024981890948244607227886228671675535283","325991708739059781514846994809054515231253935617859353408252645765199812621","13662414773203964936182372108654543836693920733303092996385768505049810447934","3838338563610348959872621837116961520453881158698181795249894747196287399881","485449072408353529257445546540662598767064911978993580812114639644631047670","2893956372856267233242113397492658778760771343541089433222819969947208285528","17157073891307130997081716052218616890370492463575509762538311686836597765749","15566924557101820668621745814533207678594196467973154086441485832643667260065","21815990225775308168088770998997015149665476147769091395143276168154070668299","18357101115986091017858932645933192184388969541140787722944950516891498537522","8710062150590115017536438587791719366578768813882761730172242970397605020532","5739938844776624344588520573092114131804626813850271764512401508049501761035","8597344610347921072150719301389985265870490344277768698655211343733413940106","16222698142027065811167390241750753175579907013568549983876951514005846421095","12728280492756018517659258892772102645982304589372574277678178372493875053635","1403594668435162976760065863483379326186288409352462683752678706747846795700","2612366146044524739177510256430522280450514706502013381760259490157404613704","14676343103153240585706964450506962525086882358169959280626081129707121953716","4260532707016214524932180376411336362439469810511228048470363945793959216113","7984676778317857222661965281535282801145319516927617697518763614880794377643","16736559686738862217701874638259524347052591090043996826254519412578549055718","9763929448645163703075516285425174955982372831881058230734571789129857423940","10666739185778907331279945146717732424049136291271082516399349534079143021031","9528981216337453682457936544315870171184755132944613913459967937528385736347","15680308324134021973947407330098752918534040050104998684860299606519393207045","10774259477721477870205124946879057926250931659988920167480022788843171119577","15713307113278415371010868232537615201250755088837294269604774217739372010113","19389172666549916781030176824886257222727573299690761242722158273625625444898","15932432347284281687951151509643659962057401544253189045048518758873171461549","10774259477721477870205124946879057926250931659988920167480022788843171119577","4349144950613433996177130888728677722537174742649722313120149478315866151584","15339822455575865138018914373056099843448631074081487735198611538711312978110","3947864640489471418895982036934201452345860011397861716300443804550428167832","15618704577094537211117942495330534996697879125403937074624030451849733511428","3991047616598241960744891843931044330692168731445129106865978394145354135687","15685542543524369200367213924254041726039990145599010079578158309164790431204","3346901092797475025200864543324438649688188514323178532199273203808374929525","8468194510381160979666542298694068064904907911239384394933535824262497506549","2720027746403097687091832985908286933615138476096898443441522183426308965676","14768237462094083403730774215097603653346981332332504836841836851582942009574","10445362319944202443593046602370236376026565776039928626665110263266562963162","10445362319944202443593046602370236376026565776039928626665110263266562963162","6237484950196408339346471368810924339085923344713660766441640499317591847254","3043704851478274488864992049689320140096539776364694886103508818509066041618","20243592237779768385633180828747562911013942619597535676704306178417638676735","5863066218446268953003799713454410507966032909447176862161847722734248823219","7481246930859578261727088637864822364456845800818786080525096339079309059688","4148504680896221026110361448532794582016345748525207564671903838604515877640","1179136415439801860745718538803483101160740233841330166488521085274337891241","9065928810899903981493325940105651473648677578071983791322134635623139849104","13932855697897704656797188338920078372198054516118094966286690158582527883905","14055827036852058942347487798060011497595819874114571421164990914644489736002","1097718518573731395300512063109911037315085442418628683867570171547838280080","21449422350449624955916507731438690265650451160747016706913840686788874439165","6961316387981410954925847270628607178608128955997195733957585423743180498374","20268171494440778801968914233377579144397909978049414828141862884696193550722","12113733876701405449541215811682496011485853756763997728213007173776163072540","20268171494440778801968914233377579144397909978049414828141862884696193550722","12113733876701405449541215811682496011485853756763997728213007173776163072540","13892395401696891012653583636153728426102536082667229256168313299828018284644","20953786706755900531913881532310703087240894788457196727707487312483178986526","6299457617252667252725411554239000705097295823886178091677767894868259324355","15713307113278415371010868232537615201250755088837294269604774217739372010113","9520768094866881003865566678778475627344081048036032602396439668044528914523","13717077264629786122830673304454167175227219110142343431306537208805175734740","8294854552282071481128991888469153958278739050102269732778168512448618523473","5569473010804589455002364381689836614542929090091237404014272058253614739721","17661319510819438844516869338048261923105278999423144324866807682346704952734","4900638262509265659730166831460795819574151688750290380981772946051850711136","20157794112729442197272015708837539559433678935376552756733479541306727404798","17296446835517969052143640464527823799987189000191956738187566544803975310011","8124695956861117225317000773399538276421821112139371581010899988172935617337","18871857950874854657946759947173958535807446890011181348195267677920480754395","3043704851478274488864992049689320140096539776364694886103508818509066041618","10120344897179186426325491323478480292903123736266975279639165364786937485547","583825254917597650927671352843678736525108920225675575425786867634093046416","17053357643220384323863710618652377443193111556152926540382649656188531651363","5070494676496361097311561999283728407890326346671833687673434981486457432082","10299983979722566739742233566040465677897294744137653012376580698840229405925","18070483626358388534994130981820879996444690011520031379149277783672915479252","21229769008637357043275411627820366081540620848184463633808231621143222921899","18867540740018444677320985357129407777551210578108581316650236575958241759316","3641322670245513772855762854787513253270679890115094543306691997977752446890","2687543920121075745891586296819026477012556580174631099287874015206551945967","19236069063061463537762876295670374868022003856936463313981279505640586608380","19777890693283216566031679483185089267663134142114892519341952598646727534453","12820672475462497590503607323761853574154978460834058090763684445316127553417","6248832255628132632252872026663853109004533483251757038981686654509205338281","14476033592177093344545373136310321277118707585608044649230045922320721823593","2314564072114705798741734290412040763161415142512744680352681481284026001139","16453526853698853851702744707013440931180327404716062491874747564109210609142","4394523597815741176184429346029872426573465305146918935614534250320004925022","20593609336545582585516607350021226611828027937493904817740624555078806393815","3646338192331068927987760816768960751428354429547935553137786759643406164188","20593609336545582585516607350021226611828027937493904817740624555078806393815","16566925439259090889559377979720612778996548701288310072864747272852918324526","3646338192331068927987760816768960751428354429547935553137786759643406164188","4394523597815741176184429346029872426573465305146918935614534250320004925022","16566925439259090889559377979720612778996548701288310072864747272852918324526","20593609336545582585516607350021226611828027937493904817740624555078806393815","15566924557101820668621745814533207678594196467973154086441485832643667260065","15566924557101820668621745814533207678594196467973154086441485832643667260065","9919062896982845139836050062235212874134726053358031048240308503371076736202","6495001369153806233149360210213506139429938273921172760613507373934794009267","21590437603227450350896974812668257293344109399089672260050985953754817498509","21590437603227450350896974812668257293344109399089672260050985953754817498509","11236819801893191163878089091025997010361868848067235992700543536934884914789","20809759278883015025959616255569110837491516632479521280268753583795105395521","10612986271375749634981997680304094180302709926978855498161756872508244243431","12285921680541051164247278003545252031379653586861552394602573908856910898850","18507107644989988939582116050872554367281205272495212838646250939077818075264"],["1523418523985169752953144638340721896537193411967779339528200867138321993466","3437777706875739220006989891495131142416962035607112852776740625989260948496","5359566837331741256563877798889262031044581417244423268916638098221201003647","1595828563436961435769889178477383140296491992800133227187293188589877240462","19733122500948636319991630240156286299741015655585385135225726114230581981075","9542180153769579044160345255809660387105590623984316769827290731393564055351","17423489953855317221964335451165204715931028814931016201794187369797334956550","8058132439518803687962490648284069274368688027746481391395420460763368281051","4023263561463714956540491064313300162796881053348346686330152579635632530785","3068359063788312382191553727915990376759827905146659444553176949107885790216","13958665070939158509834253454375430195527928213344954943713072066690744152528","3329760090437659195120866713298845084431904803777873060503726526298209123384","3329760090437659195120866713298845084431904803777873060503726526298209123384","7995577226931293054204723697312945299926625492926001476729507923373714684742","20597216143528666792006515560978783206116150692369956845021439806174058674930","15449080558579984990169793069986607425057008168159235258878678587523646617481","17512469922602089763460558435606518806172558265136052795706787752455084446136","15946897114952197148657845544704582329662385023340803278517455609937255035751","717518930840405111250324613968655129932846249886183609803075876314255663533","1154288757851890345138928625178276316960136985740394647507145879788640423119","18515354429387480293242336970824180114824478822061548107494370085180814957296","21525561374253387569561870836181108628580738553515351381062568046292433376583","13277202357269210495513217288735097524676494775847346852020162610918309951267","17297045303956599084009954011649207674844848875565682402846944668324423636974","2265513382613787327986953844964609998459907982827855254483145370869850882037","6748347790285549101050627012914047337973995867168420486746577708898807606407","20773257964154453551437355758898004653001124416336418211424345293331345293748","6748347790285549101050627012914047337973995867168420486746577708898807606407","10328642932868002765788275779003806325053576717750970210588873819704794380677","10103943768892946165217086617526861160879887909627422340617140457826770087097","6637018963403386900148265447348324977210076403026112532709528596014831536395","13243206064066667710054904727474571094119133586632808210426626507637496776079","6253404101617579321206241999045236723497379166697600678761075723756224924583","20853343014791417955843167465120501572595226373439914879046050319123009383469","21069549017993352518759652337220646123846257280734349910563260216878025759907","1266889234038486352252486823300403952960316899505256386508634828731871675439","18896459322155626937044007043600255291158826052109367851169979339695147573375","20086796820628156682596737756089687403653423892668151467153155882673867968900","19771773942558336309560677748671562277520713044050614553149087329343622942331","1089897852592638462936700597255362495123872825775869161775580335340845524518","1089897852592638462936700597255362495123872825775869161775580335340845524518","2271485963285799827951276095580310343080006366285596698810603590753458966900","8143635807035426369303881921773197139644669914726936993869747754214854004663","11820855252401179062670450729491648368454136185689425480282352836439977823859","13871816218980656188068989184962488665168261787248582858928988877856268351602","9078519568637394789339788910281297988545308652962077176327625362337838449254","1133679478449477823142730865186670728479909485074314262516859933758306434348","8603101695784872745006753941307955308467605446473965309837093565928996164514","6951891108044389472115097415914695084262857519571857473523900296471499470199","2200187567132990305464465681763958011750353015937419128561692893396971597068","18780940559854290923853321265514579958858070994912003642101159441424449927352","15893588484356096338209058785662923050108166297166890693207909414608535113100","13986731894298386614816831472113730974679940777803771758638547389936506492058","4081404803192578084802278206750423895755781299730097121362545942254986039742","21778331516289998372218342000359253558836282793369008192959798920911309473791","4851221501424524554430058939556522753223611658612372315464147958101862816496","4081404803192578084802278206750423895755781299730097121362545942254986039742","1010045980703874506032743499887271996205342552399888351654373482677797336897","11805302245146223550624519018333100743073973381603235192360245055944509442197","21012603263441706866259609347174406430448373883441489529414788921168142326830","15392195897783419378292501247030586809093431522388055690448429407206818971717","9222035731794441398155382224196752876469337201385227306834267783255168001435","9222035731794441398155382224196752876469337201385227306834267783255168001435","15256952399830881442658621443396410087998630780890577765769644550173957522405","11099115522831222844998795809629645927931998745661296855322490957908946881083","20269473192997675276490257442935772389102939096731952117285167157476426385669","21082012176806357933876658857670352272778359779676773544576232993151155984192","19674363364086300200575868029285615343556558597412166033691178122660337772097","18384487862838501599381106921088128810390948647517366636681850320504679930432","18731901893048717698592681634018130648770674016793198076132078927792368287372","15420290090943066193377369854068593546406003505815537531489781385365053070215","17208332629382959961827534403973210364660477340383508816560039542015777412559","16414943024014139954553074471804929323179814763697504543493350643247948743722","11030851533601812784292367379021017679081185064559811953578398489385466089825","20240093813993263632325868234418345316501349323616118505181658895251563201845","13423835311299296617959558603604654863536744349561655277614028813199904612947","3554355878618892155785856495332105767837876138778961308534711718160755349564","279812214418828507528169748758692172272917992673282714809931114022546012108","9696048682707911800074595364214334747923903987807108248557240501252836866667","7313910676743933493500337763159442248998987808256469937988650086259796753021","2568956863210452480758124760311487854925159396131134245671898282251805147113","2305312906293253119737839662240808619744298964913034991924327404380664567231","18002672520019792917900519598890148564016032004086759532882782420885369412998","16966809372012194595301416411299965280350466866952356483520862901754962712251","18288281016540572347747528405540822179159595826352099539582053847061042983849","21706680924625454615982650714313044004987168477537184712465202935788946595361","1430408238071363474057528366498275548758973976156783294913558539040699965524","21580995841026612058466637138109369774016496544667007986175342631979035207008","14803192838315990572939733120964985501711106415116474325751317600793629780889","2282793792506798344935315592918376075659324223013826676417109212938813142826","19714518347391013760360101018670091556616364347007521220774765827292222580060","17637125652292695232445557215624392246643124099154031349425884761277605541854","12399346035103222244816737919157630270839392366666408538176524744224215863042","13461124197841482259562975569836476094278688681617006816097480822830580418373","5211662289220209142345442246772152048846765988016070674869550266866472554643","3743614060480556328490140961171084212362879089795828790881401826913997814164","19131208723397294793497088616053494395974294670803256886199244462415989406489","10145183024684066607510896503254038956377038385775172937093985100925310861753","11781391815406799852122448244076420916627601538253043488627828242841920255913","18547456490010075520893235545243568278638669454790362288508635920003347365127","12928569211960807947663949337060521244341086447251394972605619175062679428965","1482321616584819453187537387680445138570778309008240407500209514794402214944","15507740347652719426202648619694400397521747822440391628556615319905119309783","11237590282572457844459519571177518573047508052192780595705743614256171960400","16463796188299430217646216191413613639665315370493606701218293972964605631270","20537966518350117045227966014418085507021450554362171672687262095953709521592","4301265128048216474793932699547744340656943382590093194767577366192951511761","322809184697256989188176109249511259764903638567271692887851597855284752949","21672704499656755579374443692432837645196296440246560173616443531805399228754","6626451819363208244815898699093485436845826527108817697863305294278462528466","9166986899787867909528179699008487500772265589040069471768637850802432399831","15745466683656969628899641914679978380579425265589175083945685965309505713550","18567884237538678764527928078427473273317159772646813069662164037876196004060","10814765283408733294049189136362537206048374528556026749234723266751952047086","15745466683656969628899641914679978380579425265589175083945685965309505713550","7260015463110405553042656092469529977442575647180026454128680740397448874024","15352328013329640554032219175904560321542196623971229766992480038821912795595","7260015463110405553042656092469529977442575647180026454128680740397448874024","15069641830971941648361901495507643164748559812574023058503117207818420366793","12902495621345219311048348555197601943579684185079168477022659046602156743161","2243358246022894525185084977412946902375990029813872607528574361101336619218","1431397212054905058954699699634082791457515127392451116814033415023280196068","5856065021888014695185723551755139678265462354167224018078403275020781285379","11020669056585801795270781681571816880903602999270494374694929897883728833480","8429514885886810634217035958755432505763270206685671739392226809673161727842","8329437422466547712783012626442369266072948105339225503656995074559428529712","14849002069212811199105971133533791017592405271965199535695971936679390098968","12243358596385156747613040560476760787555807057382515031516174175199174243866","6492244700195303860143364093378496744625051887284410947436212473398062181311","76599051389407198772294924458742116910539711839821842536413204132041445782","9977149848555292922406232870966218747279481395413026006372412138360480503599","18542850188160113326984391636675192448347034992890916489748171833100862741265","15805059776949863896613734174084160755604440827262164690255667628766801590428","16333340937781570332687444467700112227199161574414055985161227250493222619301","5936238503609243153639024223915429418332580657435965758261325268451755243822","11685771757482958796187464851060814385746993270571657850346322166601383635902","11462447811924980700708129105814889690399134918048090456356215987026315748665","13289255228406345597681937878022653500891847106510714894729698219837596228434","18863663057305225227335203096183128701630155608553283796544491074127809459089","11510126651986022559776523531301728875340006505475720275504229543276483139503","4101089288807920259595782947810951572696755936041378381815869635342838209361","5047347049152595905017424378830837796408202926368890107567233931655721194443","3268904049669055370548779472422785934208856368773897617463334434694724444822","9764565618745225121846673679425704482468612900617861794654417148920178034594","21660029250266174803001997509634552441523970125751456161265943650939601009669","19903700148179139155487253166817554118104745032180531403645751776770761213928","12824920846824246703248934503673734456995271488536074377156792476946030436775","21022301896312564585551736446690577028026228004555300132181385058954342071014","4042678707259077726377599383387251015137590546835689115938293920772425028349","5307523722410981502196751643257677255427669617131576077166074347380752790818","3042130522517571032568625514476567775012773180116756906642145488248578460074","2704116756723921254768528802838947162236806727246823433238254846471824316760","11894702122441113009229765868940882184588970578780906380337631194596851254882","15186502468747737945581960231338499299768459279028473451670377210805239879131","4244023840698457048259010601915383968954826650706715886100506032888432075010","13616525264844970700931065801255889877787531651412716914728997864820351114510","18887349097710695233959754483350645180174828714771157648528022331850695477243","11020669056585801795270781681571816880903602999270494374694929897883728833480","681432622151144829403373847979595275289699031089634755001372828515243429471","9127492458555031897167223544897508507703224858303802072714673415694519402390","1412262851008873372602973618212497480456748400604308877039897427797089451364","5948891427063406438491515001136165242832432827357506360882482239685431661917","12271613616747712445772546949299951359571484691187777056332645597765729904310","9017985731125595375775741500659650460764772714399557556963186032845233120862","6497846799924871791138106638502783755124379204714417310900063436162742993490","58769276791890344040912859501768644711860718201532014650449460805292794423","12161097350494576609970619980234955004126407270593546304738538188947266233501","10122507211728202784599854549150531484200821933481018211305524535323222545322","7789927828563889936103805678694053980847344056779130918482990995795055956979","16049213069902712913561995016291101867148639873559770106518530101405857691058","11083943036191586540807440149683228313911222825200462031359109949203788742913","12682325713907109472262431634739048900374312386959361520986117536401531904709","18259408807635993803644695929776645554762212750141244936417639126028695588673","11029499285692738131769571861176951121498166058245364629700629708989821247262","18884232718775426158159726231021824027617061577214926198573183574962113494029","9245430421672104704526526975491647053405610075251673990062378335042398772543","1593341402439150504297623761984489072801291021486007150488662139760161144312","17572015207855857938185687266012536648152277417701717691543666967910899560151","9144416932774731377616925329148710073270883011202096172608146527702825323774","12650635575829452746706627423553577380001389369169608989457158100926298686924","896717573253375814799257332960862646139764259660379463447001821907176641497","1215844830910119763089871198483041834177176500598325936564623781026654931385","20369591477976447334523767072549593939402319658231372720230994286786182163544","18696710514182295347064863885222894812648590863566226932457758565069830711744","2630331146377400653553952557751006757654416294466182369427310631623154395439","7678778630069711693276427097973096188633196313487790773843474516069218184894","21694019746434373287352944847091474432408983137709216852427376757826834200757","2021365653166870723490436064527981161267233795468739030083619447743801911188","21087537439283387351734186423921920118632790722684633938505252169394659729460","14531476530872404349584992955905197573348220274190645652595335789561670583908","4641104207960994673573554513621663186362106202313074444057170440503822081635","7682037159388839353157040925150065764868669394369712391801817027452853921604","10307589277096421028782109853145955224891303538590994740187273644507329692411","2819956484982564493957420981153888416487278311691591785413849964866379867057","21373560026842696898894181853160452740626386987340963566090948075583531640005","7286075655250206164198583179668017116279067465492842488737692929113947639989","12539410494510751627243267366483644213541490124810536147404344347312500936391","20667916523972762060278925606446274044347633801734658896777670151223601809503","5161643857559199617345306512405313632470656453295960219210580672191623208665","8561833599856936546572216449315144342673722762986446830388693782558895240715","9359109369672397950861448189407782995428137511677380687309368232402669648342","2585078121331996468385531988551246329325641418933909633103835215536066689596","18437611718439262560237374776119348923449836754023288435915545282160808492505","5438206537539449387778961282935493861157773931558951170353650911668560755035","12358700711717649589630973978011351705361238054886114223531244112564802374418","19136494797589881880200810408175898310008974638080121769982834226967165823585","9051344162791499236991303438021405778157420388236398029589559263727037938437","13636976012267076357416024240608884118774344245546954365946003826219508434146","3095554854473696242177300283330289526145483865938756248030815055868506724995","13226213568670815011975364826255657832203389857345656142386795329411025814565","13629769160579201080671210360801805258840067409548168971994124303287671146306","9680112936017720737484327175556091523691249353292681945692370582089957522372","14799043535053731033705004303723104372024623405934072957333675231819332168419","19945377166250228338282218341993479823698307355234365880464708348543632849008","17832922933793758471901712578653240498699832465322290552091336433864265853060","1995891154137238853989117539443026656709284479309382978677790035883272967014","987581437385504800160141958203501862846907882356194707344878767119422940666","17785440825999868171715560766768758930911379930368624409642631952472424430227","18718823916337607721384231580575161169526060478218746327707179175870373721250","18137645754298296017183130586245737605670694345433205894917951032502556371425","4133810451207545694879948992004057202030407404239995864788476033439427683578","18181824085151038424246910457497499868810643523687246503679950925223272251714","10807933920302302679680700187202259460809094194979202436483696710500005163551","4514662690721288169761607694966571626459501704078375153496199806698101914931","5765978036646849783854109611321112523091512485276831375310528435509997668172","7158553137641026383075716376195357839682762575830779934484386170501498495231","13200435558542690113676256816718516374961541165064100216528067073854659738566","1491346995491858397390652971587247251666961676429673690765681262415647999343","8308528129541541553611712144625839193590510562723348269137376165497130202801","21454721500701023383426597501781347548462571399792067769431541766574022325886","17702896922906153633656713995825228132556380044382413010767020944727817118256","4519735538545183819799534802098706674885108118190735044232104957767996604166","3195983083670157820439341570102117798019270675845301201370481693276575025358","6559852769743843665212260833548236199956051268945935563472585918031817360863","9805061015371650036076563196997277190069451428569588834534535094479371314361","10815455270695379728993230615246958582017045686252315835558804958204420821502","12636902096419900175093281219415278698828377907071292007210357709985087103872","100919838727299049290593364772113020262998906638964627797311602651197382551","10219324899787873734968933699461153992207219351241860762701123992617569425625","8001705578687837575864130624039320588265926235748838242188598266543531362700","18745439159714809973530943822072250108245057197412649735707849146175181004631","17080354495849413292338307787056319106848483155004884272302533988511948312287","7523091381327406225848056095192152901041983283516021621589483477235775018986","15636566861255496294287183689424642527729499176792582369321327630658309376395","13817609380534744190347321700459132209156771507164674048957289713106841753153","5880317587986084569162246885684228674429208467781275152390100869912730300625","11965533390582843012305420071017310406497963827538760728077216895779033157461","13032322778082418153202582231537199481819753334590905776191134173403516133573","17532844662890511978002256002459950467580046318857946883322077165656979096332","20932124839535506630447178332144187452005853379457125294082985142660621147391","14089675675750289191646239370036944120353684450536824669597978786368005465433","18859882773399798357683526049210338920928846962532394870941330307706122133453","15782270433692564405821676485550476125925767281021610856345889600676854004671","4817589748580255501899136041923383445813746148641065063576252260290416636585","988489227269641971590848512665856630879381057479574315432733748926029422808","10171978635059519470298173282356739756045091998326551149016668675170691563974","9838683429779205117137440928982883366081393731296161418668087050093090216806","17423014031450904034347852484523824954978354538194329658252307007357802466017","11941321577022120359794957213400217733687357702845468590490508966668760062496","20987746675174159012721340222429720561339130632895715954808055491884741126882","1757832904064740702665855915077777804785170479484759402685368307908387675276","1287467784030315802307968333698548107674587402892295727510544024371607175150","444455072867094135608333718617992411498590944622091199301648678197519074644","2928218479688308019960632499573416774601774548287668583242844831380484271329","19942692009097935323450360613655482830345639417106504669747105033854651618211","13305590938685978056811524916107292108926370705073571294479467589148993918613","12226001555682202988816339555681906378106014420170347733584375486000910216492","15949231579215794568028538578481116542968943469863885776352515353230455490021","9830277286549243917816520829969891659830363256146194611509033377109892084469","1933580571872710634090749070228596596596474075317450192643474920171362737414","12851173873307832458870659454175105224228882802845986117961717014328859807622","9924386087694608858232551752638556580425416580613349047562974852406088636158","16983217767710394435238463637544997496886187746952720024561660797275424440325","13047788068076845562638091492721786318637781300204598295018661667080758936055","1569647133797086829919749199424408927340757236466606665815692247270019883721","14926640876176998506528810376743920146272444215340258848804291386395886537640","17233442586788711142583885713990895723256150060840591900565141095684114491304","10461573334400858565113021496937363718244447351194122916744795528171766740149","3197558854792885989245443723205323180083113243583551835270612475973312293942","15385102291596316464535075807231083259879620828874676418685801308814230084746","12988633550479361882377452990513496335311402557364333735061364809290249677666","7464844108176181760553416914094049869048294631793504915028640999175303484962","21027657356173185160064951399717882220484774918680749147004962438332291763454","6065254582163924714757075019425128656666516172492681952010956876717146661106","17043401104866114082068971384449803107363830521018870259028244056376050515869","13322687869355827249090180984939209515114265538566948054517958624347579001440","11596559216176458829761383973316501012392740078610353709081534105556629319331","1147636587944742829556195334604975279166877770168255549761141574649937484630","17485841496108812799627882929860350030920504503023823687215043151425187633085","11028946481670907613455421600451586152797741717076837275767807720393009390554","47969833713619890299755458653246922927649550342951317543116445892224600611","21680604271035850235953056079100143963005708002650771994166147758885689878019","7284547340642617172940467611018689808227051608386214560441078677962373489457","14401922004812893952574303844266837413759948929925453414101503036118937888487","1091903959773871230045761144155015074739238127602574086542369307359655368835","8844803602097802847901757543517452901618931878509210023558206636972433837810","3378140609320633941600603480695148200663144456827623708717483300362627690112","18302708843510979458672230444474381843133547180810464787148614544422594999246","18302708843510979458672230444474381843133547180810464787148614544422594999246","863653876838039655154168721951312503016098426342385208069852597044392929427","17513048157164067192448719631546641335470413687055811349090632947638582267120","3843738863710715450522568350092142386021661379051848456419889201535060727764","17595816979509794306777957133996395047331855651615755292114182204925675386458","11603827381756186449253131193575308918838128932200595998598982481124698720266","10478909404741035531794586351393737682426780738038299020725026724617670899396","15402664387962969755268117101863037219089451728859697297272838382303707938090","6606337938342253713312564795196272334927264995225239942540218544575358929357","19129134009323615045943623303890811099415141258422391904731341109218099704072","5245579295806751324120579366779648193696306686493704011781029728014416135884","8356084682901589105382978886641592596559895346976233992666291755767208230482","19391030795518694625074179061303829601793142672575117114831083995919396266292","17170162374979706635204850520256192972411185216052035488285750506437768185576","6559051766555012135526995660863683369193461739036254458450572732900682201874","503868826251996664682539159658440396315222105665773725200272821309863047903","479685335312530730789741152221908053862852918883595089187811801347956686966","17885230000829851354325631535166378022075348706544817301571293765262704063741","17266732477938813352456479007217902132155814973425862368241048232032552645105","5288393442243047549659217248599731071976700568969391977388322948194668010792","9621032645616961372767777826537280810020259482196460620677089101571040208432","6925812767411630972003385619329084955311033264571466861263842499040930135776","8467870315539854012783775939068631773095469137585529284259815571363370893501","13391570611216561944695020617430464790242353275255237845663677348216094546186","9222035731794441398155382224196752876469337201385227306834267783255168001435","7859393988197228167570035538568252042567870315202124537537733331160089108483","17842128091869861069593624184985258498290791814783639856658503926842767309213","3205604138400835187289399914949473993719079702474732914642821530259882294541","3810197230759717492555010740717529068047004258419698832084600173381624232675","13038310538600126293189950056278379154149992691125034953540239611566698846629","3035276887451513604991665184179659812135282528787543185170697071088950275119","21572278334805016338149238132030518302739939580035611528482541203332051580535","9941543387477193718821801678801813096047701928240947942370198162841768012419","12458609331877709591163716044051570809745041774730638204235323114605251967502","18035163886094664877843105997247142757055171614345847374139460247810151012215","18514937419257683707636986263370492893518712262136311716801970142733889051778","5130038064331953045138935799314190608701734749392116739850095840629381036185","650103320761181567163700289061058678264835941230728551077095707357950958144","18185193927553332180712316616588649159107701719445761533426325567855732591210","18115854242757502999827038086232309159347670355894278013439830626496989347728","14797629330176189639476577024466233984462957609890179477680265486417528623259","4944165504336443389804033241938332394569687172651513454300548425581959395538","2600745553991301162521138305321588619965913838750390926455556481617318786003","18520745729539014059350642929591089448429787083605697740004952879504091643961","439461148750932145640352784883517833467442334214601783047830956380973795794","12418502810130272809913144276789492722654821073244899755770102912192286264971","12224830620230659108771735830038130072429046647711105883931067015510794881148","12657139275032012112159120053136500035434114637570663553379378020228811336052","2172621164874735121660315913575617996632010938542446726820596095004802518588","2745796883132309380838125965907281920333170155916704846911695260144153491329","12476762218470004246831596766957678922622203637389811724730103784888364468882","19241695918466143753513415737686531868254823021837976545849328163406715721331","20043156547449372035736619283887192805265120044760311900845467297851334397512","14589841425267082649743023094154009028145966599173611336978904230078062309709","6238083838689738769271060745841255439996756295434355035503083152604022141825","12772317622756072640970163077957495973555125815001512900838377107144922790976","3739071916949124303441570954550272666261636415967236297897116978929130487001","17858771563845293406307171750634640498064407335521333429632123178847251121776","10831230808000822788354292184519257709275622202584632666611693213100206078725","1408012402137866880449053700611815808935150534698437806556313513198551506074","7550934022286474387471975986577799661021205701211756968787512353726397399689","7690546164812650216986834327599121558113325384961267906444787594136785763529","20798321731564340588589053756300016301176120492032630793373822235837658786065","10964883476485795201958109208283563041388486595606226608369142070952076206610","9771973097717662119110033424114439644346898547896362930660872844260866301246","13736121399009885205864056114852593193356210899472862204078631020418036015774","20373520385143948858239892628265804313194894903625021059384543370467862585238","1440300215212506112600936782107871583419057667680047292965895979490702561539","15595692560777743981884301314310966849253657449042009771221692822530754286863","11255793137348984144564098781609762458267158067190502448740940194965092401568","6585630158796427634231159045438646088912148251956733043048546649607132022829","18692588960404147857188339647147602913989478617667090920847425450069800751720","7284368238045876827245057322092488283920148309575573572767741142853806910917","8641013457210812025256378392473781065598619322430748207661326591318725559699","1372208179215621774171373756090860161225527892196245772763662542381531659214","16003828596500299083109132288943282981415228083531228069493710405753001969165","17987753254177082833422069684075205589049435586887750964191209736969428207787","2282654295598976418393126640456191215079670369203216010883231298286129384949","2610109487663290594418557093612092217425598610642392879493839933004673494657","6897130808557356739487896569094770914884335762034016522557873029186548201714","7002584785913475941349542574253956181867234224768063320625073595608959202267","18658114749587810859363735156637927327719045597669037826719265538335887349264","13707368511944902614468459628605671470206136083169659640664550996912064283992","3612082346451146150697888328361662712563890166558010519368059743231481233617","10778460281342755684762601886838258916318215272922267960931126113012195771257","21147971905370271485240674104493079874754872114134381880327194912488739071373","6955741151366541798893598083452041196684357292427943686184986799231475096232","11239488258429053411029052750408807842929686148126044221449010564697840004477","19515513979743823471843231292140116229991246056543138736995559512896802666378","9739290420024773375566113669952250867366060243336451045115406807224468648199","12776727615712020973190508247001369873091131460519909492449289737719915472775","3966732568285829482940093845638732218351669230393083184126104110116624589702","5494759928519459360746204483997618791596472771028404056346835382354533383893","16493604452092481912977675867340411830489933193317348778171223387934697806695","17736988301314434575657926988819765971538803725654587180986719420876689197812","849277518303930297053731419547140583879050057476468271158357005119366475579","12399346035103222244816737919157630270839392366666408538176524744224215863042","4823744762695622941953820074263888376393405396835100550987566420820889686816","19169224376655907070168209409738106163149713907224225839189820877782164704854","7986689943980088269974200654190038330186867729924766350760694732721560061259","14255970043318714933234030857726611508714347096570417292132577706409847666279","2189429260622343004891436231633704087677779505642809809484527402134310982022","9283915139749603864912458256090794112509664955983317985608712437070610649337","4230541052638061599452740939726439478725026768249411055356349602327931649076","2033711243881076252421093658428215828150702128013468858088309753644316977939","19914582994094960607153624517702582751517294949712102068707252998010531631348","20747940604991587655225276162836314784508248831366649097310472896848672652804","2035338329502421486757289151777763565166032354718211754364528183996109192984","21280997694944260660141948899795910462849557964171375211630820523174926515514","18002672520019792917900519598890148564016032004086759532882782420885369412998","20188014652559202060360172441815456925121371167933169395503182567597255370671","6960855941060051296314890020547303321395767077302957823074884341304000635755","19851289961594349996221658554136721294403034017178788894224349895416524861041","12860551341728616100222371983454904278818072308540251902946004695803397608854","14332746182386137586485234399560384658810907953120547736909140324731783030789","14991304663999391060406100943669741451218470161355227814888520067079630535232","9640798879474376374791087493856800112512415149197217056237753047447567258145","2319241035405999674632606454188735772641938762126610347099601345772395010823","12606596816052994125015995566530705501933763144498322527929211960877610321614","3578300590782605112698649928008821110970828139242358857560775317951181621279","19857919224776353165782890677964922277155649803136318763043106564216150154114","1370081517030411566722301905584095712005230727329612323481836873529734446187","19023851616753590109890903977201978346066560489788788762441037067577741044288","3042991755671601114333408073474752414253082272101422710204021849074580741059","3053886764058971863178173493035234787705966604717849694585499895554995211018","17300611140014193808700865063269690451396769310838745564236389931752475606191","4451892138006570928922548264090862043716174859506681892746639067257318482473","10066739674411283242026741799586472449160079549294779753911651964251104921311","19543955117970303737106482984797404833775457753228726479067937880652415891095","10377347731174900548824657492757856412677120514558547978681935745934685875641","10673021422379362937961661351274044667933370753095010254670821161356620890620","8207846916393047692543374207908337927267641600465644899845221792743418997362","4422490958332744212338723155435912324337175866034191623284594193119009101352","5730557459079965104699126110631120788836065315106791386585436472923263493439","19809200179705840614187634091638010484723356730716662219581299069759755924698","16647918676277185264541465160421647420413791581688859673389570190071522089643","20791868864426021424330964965198342289963244379279041926241057405654188847724","14348227019702272548475946340059685651489816288910941552077088737381531321816","6826443663872799017797954440648469544489340588139231799162461974401038343385","4514540032254349321715606206923899862331099476585107055444089379298122162580","21454721500701023383426597501781347548462571399792067769431541766574022325886","2787228790742265305731761549702583597232834003669672218158763299248297468680","21877472359379912919121980714026711772688792291290109609860530061891174362636","9556722486841036151963750821277876739894071762334384995008674291508461574112","10227652744956152501829148341847468147302354450650565025552578514301866228290"],["12640901880130827384263783351634671548220633810626768805372281352127789782827","19114701029399673102629166977919766861635670947714866116496904352415863877692","2161482691217084873481841649965129813830194724964288493454055889893483467560","12952778851074473315894738609365324776363352129051859025806637625377707875147","11692979541091076764169103854411665624239128778927904511204813933637193501687","1123952754086258492830855570826248820032408099859360056499488141217966514672","10863480197999760069329712142621595855509968840652605870345035553225155258218","10936215808313295027648613914689469940773185266493314886757239558318829001216","19812657010822465368405496290387317111163097393473225230019844769364083100863","13392980855120639604414088837457915882443539280893976784428767463391928379334","18071061533445939287464727327416987116569823781741473658967098980439877388551","12619847985675467105765191435172530150369235136874152896849686953658241072657","3180141704045744177304392322879517069785908156804631119512754908554878173368","10506241748045037876923008834049366155348513814023962002325655558810632305704","14128895983102311426159614294702331226027823743958463063783124163555788472028","1296655780016288424091068418044730056478305583876396127714516457737761213074","18540010664387706083330522984392115070507271225307001290855498115665720036953","2378379963761231122497238731457043377141605865074276924286945910099104671344","9227353738248315997324680558500559726523572247742117372969602831617217096241","17456377326769535417844493636355581364364274422022773716259529425889408737513","10068918628542478469672020943786841621281054390103883807929252653503347408672","10406648981218561169320474876975202607659199965507118967786490321001493925513","17378523345829135116741908981922914823977544427852268977494670279509533776222","16689061168910952678499727237657951462283771772576609747658313908534083005284","8520797765156077382623821707520886269721758250675400555329774500993801823170","15152769102978586469203780409703455850551545395426439004119593378024907110836","1137701939547990949461625459145761235610977854412759573500341679646119461446","20060539144831852913653536466279105367327433146764955280417273203225782193527","14608995712055466255137570060874465892889158395910755339506161623025165303062","12408672515696016846214691357691780908908008661673986198331826454598938377760","9793875543739760889518869340591628204640210597960033003789193758604441213183","3705758417462723763768966157438710729304177261302312917738737924694558703245","17327376799366668134136418640036826246505200532796001440827855439586442399482","6256727409531612113020691273650067820605594907368097529114031344697238514270","9505273951515078748234935196094928184107361638939948377835368810522199942814","11136795060436279525171394133744585407557054895963342773670652419574616317089","21135207498662233465794505136946070516202149084481973842260589125117030402101","14253758549559699419487185774286288739980875732017900869832862911855997697442","2382564054762455087804862197545946248417447932402818809444014295749680062879","36605161140215712597539628707023848223860325523088237948945868258983384017","15441519984470700065638658810586970203440580011491311096775696939880367544183","1093527624402235559068768191857144239724306307326625771151619068083882214922","10675183613901392265788404100025101343046212004403658694615192904423093934850","2484316598724121534806449223788613204501601741751464167030982923713995111636","1299502079351937721285093305957485486654056443672644887712185438500580684733","6426281758841855798386247590616948215865134035914077366457339571833804337796","12881828407742223470164703229156553274794840572975888116636763390789693674816","17252321590444971997534843886117548613379681890261134448114402345126040523061","20664959265421947799668874713427860983987938625964859636170255889844143495167","15029582587296049498863112962336502460007789281047001875470429914745984368033","17180020849729565796756349251807197605733215036088775728140729995383920606573","3973830347478354813652171717511074125517547970808502657347317849322321096384","12189448097881916728024262357320111431950879887419584644267815359767991940938","14896655949068434682574290072035907451384500699488526121883764313122020976506","1616410205918652778314987132972527618417392020389195979487546438215062574864","15483759605276911599387293547860115650492051189645952206775666901586700999394","7501523045383897989654337924408041695517889016721142176740319046259174106013","10921475198888832983350564028143948153469701916096351777194327736175907630865","4580015060803363747738488399040429324602194229251548413565540376888321710538","18183753702376937726694113799869834019333135838990043168537005614129851943339","16283415555833930881173718631259047579907870129304078245710410222440293557246","15231305899876693253108352686434909474580165075209041962690297369952085624534","11642285662679603297097599004327086914710393938959659573365138195216194906990","20325332432992097290390621658384302935134803098992746205079071254066238600085","12888490484666400116284990808604093131693066011113646234223997409739085901269","9284491750089442824762105651700094126030788658819045415009932617994799907299","19362346036311714257995024639601135903403344675165901273335610934895502358898","18705001584645524917513596594153018347691430365137001780527235555707861726855","9331315780202926906629771300879067459144967944128311187509106037102997291125","15885983443826502262810901059539836952906534633655970215458868611116526701666","15939222355277494519055970529501197745193566415263493601503690432638029748605","4019676143029382516227340827668745467257194373849687068738917492722360568123","2825494364891258431077488921924204426034288405006345129607279137912333411177","14675092392106820340326879415401706087239121203463201540615317447468010349306","19722351447368469875813758825930338192231564264301186370624523224408335341316","14219137076778083196066944276660426745073944287632683482310592447898818182744","17137600882444755601558539841427497694941554305718901113991256887426892750088","588919069573442765483932215173103310176945363649166277111220184096079136907","16288536130361714871135140922335435559544534923533098589330503251263010932193","14946817699990931114402325464341994101635700689297407850111885799145127491099","17810043136139687958731601812498616645827037061584607753915420380147116743302","374527010582909265435132328682676370103623219590095323290355798919570014344","18058933334111339904193052735477817862572525479300583743400189443363526069689","21350029496256781952710556980234332576596526402200282333746065399001734365096","10912763912185468547173234767596339104024697197507228465463706299460246753379","12311014972309180613142987793667279364439169912418141050630632446142678894396","608654495714323951753942390524216654420298953345083963535604507153807098081","9486411001801948351335558449971817390026779816226391531508588046375770998060","17604090611506079790167027998876298840402096075784629800629329419519359030027","19091602703648807366118362745606675614552772171560491189547324036914326185727","11848395610804922933100325433562912534728864276849403986967869846439372956092","8991698334531878897973677047967200401769405278012627901651425617144797375629","5769272825644778843612203298773252525211259617666651351653239840753678227061","11315946914124337654394172735583659731242443359511786387265458583737166137542","14260622437976189502693300253800114928574165306982371201290355072325142391340","9342119937007443554822547548636188950506679369226558092518812902690970376946","8864221643108782917852631169301944956702742428383954588987929708564177860567","6922611356488621463947606147408008436214092364549792964927491268502111968911","4824089042558541027059023468663373692267821529547131520133919779778565971389","13316446040009205198124819193206294657179343829045021267357056030837490822287","8464422716993731938406876943218845754249152282807001103380141672092521223890","13261574174487975181424876595930127577989883562953629109742441210428172387775","9686598991119560185580342793941466952027663067086241051159288442904573281594","4314735206355859965706748268404460463359346662654911040939760597035307918557","14646444769522678346142065633998698964464240642351793593006745443088132378550","16646124987247272721930354815021078924638996509164287346042264831709192159136","5897021900563780842086073361801162349456620584090929383680949001701108660209","476763424260232617976228277855920705414471797888860310932776262430403370156","409242130688762055397997960489004438786103475750434111043946569866724001795","12342115020701776042779484726711403085153508216502730327799217408673728291436","12086605584047619622249772858602939350281370455340107206411555448307620129469","8251518705140857096390269484030594364653202943568751404391601762955296076106","16075142805062534665255310267520623296450120392267911768953409261636493227769","16097105236885923862863681753512338999175141001958938257636465882617379042352","18854264053755060347691133697220659102244739231813620503609695146252152956357","17699111162092520337135240071509341185380586550381458294668421307165847190662","1777349120955810210994176182796894758921244717071463943209369201148744796537","10853977646275572361450036497758510066307707253905833266402628645213645758258","10949359725274717599582662465177982903035914995341338349926580076598610540692","2569008276341026283727590232926602091897600731414620626392076084105370478125","9334982110131672424966572812636569937464144297566721510287844518343651850098","6296292709508190038788736829530817052412041140921060145972150203380771177878","16537606982911136867485090207511654793373968147055313242721685110420986701047","18567310605326974738494087432056556128348858537383448372914962499722207299951","14828676970364688873326127463620837607501634015835084307750389567657959335808","6937602063548739969738948753578791426512096482491471763242509993991627772955","5955202148615230113172514270934228978786548130630453864214787235899214501059","12870143559485601554076387775391607046558955751813121013105178476769932342096","305263216365483814069367846010614760716728195035299940172990716986698725843","1298675166378793447453656054189390756532661067065086710777485404445782232845","4165295325182886044620934543954680744644232520732158313195619311943128636162","1521939069247142429978947594939326343522962514073181257419886000856473335472","19472198355006267455005421101408349958107231829156720833873242953173856766568","21063823909900161710597211203050934004837327568496851633743863721768868737258","19510458840191956152680952477176776902551331131669450421051226760647890590644","9985954510179341517916241220639789496443791059383558463636601275682437828823","582646244918351418958815393930522508655762891293727212636286358426261942955","1290943907283209809935810600623208343125695521455470253209694687593168905776","6372265249993873669133278996872346191906324919465975194587566493460455742459","9645278300919797018918463326465838849869579411106292173289269342398059450755","12041529931196248236595975462782125967951738798405454567311308076761347438894","6745370243069508055547121384869768586337525537956740102802535413082054478880","12488251413203079186884709705975686039323936366039402419157395672609920687712","18102545629005522729879829876402036151368234866656900605530532743353005606609","20335896519326918038173498677847147711775111680715250632010853487185343937969","19413599210821685600074954984443306090122952063048460827168761104376094351327","16901608887540064438966018268347486849353139221895654409252829913629357073473","16474911644230521035699244985739577229394741753742267159336981772251460889278","14129455744794753900129415728224840516968770415282780469793148776510682707187","6714646871070636959326868495957561929699835609547074250116665887679339436961","19971038223544686032024497166082644983723201982529230104146424058998912325755","7812839114154500954389329612545344144593428513256344021660929490017331259670","3582845834317010110053010769180391431484523429361590311648019285934562563013","1221666511524277240421396894301932106354244741752173984429742712591843104345","12635421274552771635400546189504293348616094227068069582954433706589413084683","3354106385140321513881556080502591606987662340122877369683483146897853485409","16644499957257857744701809159062734039492529406675716160080397998320944838847","4937721035154655597593563718644324702617342006981483705863274932119436506718","1785136203993045573911858075037988221737747771859301109216442588693415785994","19521611578902132268353263453425002024277248789887996748667218373851677976738","2339619337251962000570691342189631007725240961953784004197357238102691919370","7180772405671455869845546909487568523006298130677726412344820608728421700932","12064464443742166500952736309660099654063173827296887185023031690728943742444","20910932739518681687768367668625363615904363974608028071117432914486267313492","12433424422050663597978057803247465391105063426555007214091706304808720852544","16300796326842498115336164229675206678563275946495257732593555911801135200086","2436546406598600197763180068909949750031590726179083137720104092119553409128","11039864441225787145009446609634300600074444608208763284935191913125005965862","3267695123815460965382527224293675248738795947040141992357438728242758643148","8359933275052717786993338561590839899688202094867253240436092127901266815408","5909480705816088023903877211135363394819409978221647541093044346771654353172","16880755676243420855419311762829274602337868510651510079060107355139709262460","6455173355948511593452811383322686779458891739988624762114631780874831315519","8056680312876214964984441218023565534673785058165104240523164083911498286846","5686969064565422894290822405063092365050311634055097121939379919791586063858","14464782099286628133566050375666896114540303324395887653223711824753670530448","21433593592396077950453375026437766205563107397300074006073901519391467104498","1315641543948212600937915097321176406126728100896589027789227535526435214143","865834073779917129130617316805689486468095179058722952535424668064231988820","5712963156994884644361392829758015603933316649949632579435651256452433197416","8103546549299666605493867165847123569421833658212697433619586410606533420185","6386396864174300610124172134816491480183304284022078465808985726042550599731","17249236929176617893896310498263807512632437602407838030397005173768135917647","907582820276254022802984900084720847737943955327272057576367144468225870197","11165295965903017418923221711002449900691586278730154480657677036784208809662","13487921359551465246437358159872136445008195488689212397101782421631930949206","10991299280173435148547037101912602757662898975622746145639758902114326739796","4061194580432714678454380209812694938987680149963358063211412062279928762594","12613346677165001150572139358395888375295889391253871464397850783274285532210","8126633930019304696167216150886364381390008335903994912218283338476450784083","16232644693522048901784978600367120670377393671838061795359446680268838091995","20254922906099433652658409931171105476306156283793142736368898448996428373094","21405897404315176953683504518320080597605464758727673669018710444195606448939","12000160731577544929971753874815486915631910446734612216511996730736830119248","3578388009633318231534757009030398794831109395159632295398464532717191179282","7142016622836321980692880132855414557639714358023467939231823765915900050370","19088096079359223069795762486634328410304241027923037949554008838761825952078","13238003754664007658157511747734982479547683573255413894698853200444921672994","20288636894693636179539075302054200486435845117456277257989241258653637138074","6077926281637018721913902572998968346023046984613844978880849985655125646488","18268098243449078602549573978158733738649540280485163156425841679484205360939","4571102543213031542693127793413075971453577235089381893847655209678482721193","18502205140032265364457935216873592545254694626322521235950713380297971266865","15159664968796617661050634790727270001454828462332150614316662365729804745645","5589439928923714806743506223927081485303750412356843878894453909311452585824","13333874095363750228189569744235839541364698366834850798904501086739415855884","2418223141844872061704374676509112174823919153788243883647833996162807066074","19392203983413987076531857239636018069421073807653036241751260704427992297596","12954405162284473085107994358946090651313097804995674434352643768539879397486","9070152043787274347808086957289387644274104064084346544089369225708745852657","512798751529769036584014205551661097584042570450378293405117024480686379793","19882970428142130888588941480970766542257554853280750243377541609609411409512","1588223101794439094086711809596737650398683029436595601687111768852320063579","2750341327151358297671921187303559520908690381862472880977053725929553211372","7927466657124523030871898711941651988353614328146228391206765401480578353726","11190325251565051439299896031474663536301288041990452411436158720371253300257","16137435627706571997752313567925516719343961327447652711067563549818003179630","10264524509595331799511123108087912506912913369070598851350018911738313431062","20075935424085288284392010392988287404219853362393549280833661096024227937734","10635533435113072872359851399730660113218118268040816317271851800184642117077","511285570376663444552548853839234959947653536713856660325837341256805840899","4004485274099086124030181509130593369140115419725956915988725979707332020508"],["11752830776630286600799367835000149721626807274520266458205795457527328593570","11951229484605697090885868690414538442703202422195461316866896620736313951618","18416112677432687408042574231806924059387348609278229547455991480252570937189","11447227474697427194354572162726583344626887120416613485625639211637103473819","6997767260581773620429213001633436163412926237811309057930758147729975513673","17980405884678761948281959035098332314548007787047420710087827386503247454279","2365313391166270135022513019239459261362603615183090251324691987157886835162","4683618699708287915897904337758871670143204865177287683832709850995801940109","19945392624503047947151658589782442729486169012571988358332360691598549698497","9350873894683376889089076039909731402794168624809037799576031768972717294625","8852312103885041834454533436955843197303166347715422480260717253113225411181","14440874917269148513224783860723979892479976003315930669134841551788165260368","17551045591030925943001112103330311227383730832334252298721608294058367061889","267569248499493516250825265180534326931860073222008225012008290166701023491","184143169944060367114254294655712470175419067267813124926092200150664447751","3760857941953833775724776268053947678858699176896054491025578323490199005998","15467976306238028972002139890309734623719986359179811504746907903644634511566","18297891389266150772791287351136675667420108607599582385578577330593921671224","6634112814675960191370197169014483307563179854632305038546525517894457175901","10593952150631677561582082595231379391951682430428601387746093496275329570172","18696842958259331242551243394181989267162098775416122881589259256868474021594","14548748880460317744648708149744117868611422428824357562096063444079897099075","10317685546031983586379091901135051703503573378275246806326410202149902557992","18789662829643378347224334129016895363509070780808091349958307380255053668639","822967356340409712812169279896835120415013537024977141399037967371872724670","17030814940076113525066476040395044818526632331401232148287944969960674192878","21283095511167469578715105517836222388596462659829263838848703821454316567211","14378750959453889603353678523004349231369375716245409997716817896974005363032","12691823249515461172281409170582964049452265179097739756623749104483459297033","6534010924781248077957898360611227308558899221874164480895059667903601453537","4759029937191533030812674748063938919006553150971871644846569536158851865051","10783459048728450744593008388519149178764429516619166984093308892486303404590","17579384781695456278519143407655006608792500946289653310465460096341632931084","3193623494446214779688030090955583662699734738664864744262702534944500943951","15406273849769144415973332305159183922928834960497366733233371744969860237756","16280396274751742095368577804679996771621646839742687043364963326009087545985","4446192005889555290910327981884953891156146228877026403078066514979005131105","2919287915199220665174828347653072890663669786133879894659603264975321454575","4076442496393709653480826460227537688486940117681197869245232231212477980867","10139704531573547273839277843450133762328274051380112648603794617373637831537","7551713258094098967817166733938464267445443393549408284611235882390699448892","15545052585088027777567943253191466515163509984587720801444291448893288681353","17639569314189204222727683229447376333697170609685974649076741453399581769667","18891599614689914208504035120072089807272837181185754193505356729866575777653","3575678000706322853330201658542210115694110980744646248335489287651263527406","21477111824280960500333838538156009456741856614575587745794174327616346561108","16316468086742095984340126448427966441504366452187363980522520103867826830213","4807881671485383089783235270484073932303931160410045722943471497802364909916","11488017096099174097008130156843220234497743653323146732627796995896780975806","2466299796700586144590776693302984350505190168972805981720766353311077436029","11508262847137650165549942299597454342255712711151940100364670009471896245821","14721314736274891931618493701646237635836039366924002631317646009737553094759","8538332457607741538579296447126705543340458990964904936899987767468097960782","17161299654309558751758435294735289564572424257063185538146749785558186725387","18905218887544706975508814241100986956719749813220572933203974007194699681371","11328866376772526264277210104797352475245237293072185147791615790637700886365","16003123387028660861145330041885142462006818538873726153479269549735122027604","15729332933489647459111698163253533136306048494703902549337539169101365301112","10528377273694894776281811137171495683377620408348730396824826690339209879847","15475074287871002707576667730926547175621818756979704838728619504290604683122","7640001990325255202086396084115613446767795549954061478023303515252663191633","16508166029475768104102037175684327443768861162026299995696848543444691449559","11127210040929895380167969633908849251391682334507520788887636300618229180174","12667652312397031331404796654831812256443463704905635756666987387058416254918","15134019620800145728009567380672151875530970595527181725676929187363607916974","20640395358002704628163392434397471238313455865102487944687583118224703258679","6988798546067323571798263139665287902081247358852784576904664381982858611192","18502339419743141422643621491206710062712843262248888316418236953013506143802","4076088898342762619635893093179364806972010581016951722606294610007853206625","7115713085824709069283103325514883944264054914309788800903355859853574150719","15629297781709888573193910776384501209578086911887644651988354530115667794399","18384452058093572210445681439416164501545504676053393768441315152230290192153","9550121896048364399926917956864463119320969708342893638580542447307337960454","3951917698947943434192326629124700637463169276983181640636279824142845100172","10366539009764502044163363549747811580426447338778004241642255854545934940570","18470298470629583746124489710646725721597327626610506768632309512728924852880","4197256437613043175882989261335160715544642274735258465220738142454922044339","18487635897588002527768148576950640057795883384482813891489092502520053282022","17650137000747352854514007030213537219736885219238401062627443698108426574497","16630595821357336815663434171003799165238512093476265065246639434465576087674","11073199897081405373216081247392442714428402335592800069299077004049121879863","9197360287698675118613552592581952958944723024117536939229069783580737516087","13492865781995123100761809961322020265610917674244549251980644597729138367292","7777863978546274551676445894775785230488012378824907985137084508657402603018","16159038752883468718550164079862946098025028825521629296391685273186819101908","13129176449508441266525865192332689374377653677379978276461611510916720107656","15267429430745413646907262080528724207595512995150088300673448006401707602956","16399185795282169258819861672055964800223221467756078352423927042392456927033","8713579182946844938121307851749689989383453915434248506873108142811439891734","17205797175019354271404045460062519232068594866557185374437096233449984331436","20342103671678219790968066132865624619146038439315618056197058450709343047198","8331850868000692082571707787298288088420090069557264475918590051883894689577","8754148672741085282128647707683527447249199775815310385908971773637733662691","13981807470347280064014830048567636461110408555800414603266910079603370173971","21444254422594736950241370538303936153473840994545276138848639094051716155055","1584693334854394369856951168985686933120676146004835230597061060993664976480","14376504389826022311565498524730446004894389523870555986345861811364661127864","605532012833206712713049349563363011506087050739760470734156159420898062114","16940833802292609544058496924069179515932898591907488750714304235660953014990","16894186256118247047974545854969305857917788390464366494165804567017944304923","4747132340463958411880304199150961640764241553264015343982959767610490883181","11326157463061825506677431636683621223219028441914648189766021129175496486442","17680268451392039073983170201241506220320867376980492661757092619611653796189","10251245713612804238573635037332111994009874707549946675361680511918617713459","3103440819781759096308586732699083465259819172605089850384796604816485913288","12980182416125592825587594375217104179607378167676222277058034127932750092863","12627328924153370369072115479143559228751642017548103716773530322537155381554","13717457044492822726138408239721621811110447410325611747629304067433292817307","13445295491616822005422413371480545852650695160059467303843610730841462348817","16801211328414101343865626956114114224579353172922878059860547437408124074440","3662034090400014446643753843908821629505765609222229256876796271221010068286"],["10195892973903341421019070662373852854581733676987586360739312582369931495706","9983184956862852658057475171761645071922741027719810220851572222048459448678","10962323798647160380107172832917793754268876982959214406847675093021748588842","9660180467181127986415753940158831224283905116915939071428325922554084939144","1530685299003810389933719698027209441838030618477282173369258344649624220746","1780722983538221440675440792420010486367166640851502554072458148555202010516","9356197479346903774761959366321445013255098276092645467706632195448268857132","1457107624663501807937029277093598669220715316536215137437739118103162289884","2166248493574885351078514492559046738462791533980337674484786079968735543061","19678727417989188079942394639469391386666033647897704960548179734690803056057","4448234306553441329062102819369010311869900607603136390511725287566601388186","11135364308412157530945164182428148945152232443681745654292893108400303547342","10037725764322243164423170642361597779163660867913164026112932862991956106154","20881392189810632224872299422014534273587307373335817972705017965394550454932","522839179452997987074008871035365820299485580459980353835300260532770420470","15058969554184100642328481466469023333000991917979953652924004822112889839914","1931744234274594902026399350291685776578581064959049028921149029212072932114","4591584438327609249101295865541258118651201229784676767342579747625745832075","10286503940176616362041713968374337539107262653897250790561557394825527085064","5074052457558496566954331244232897634436620871598357731297895026233346897246","18136386619519577525692318738377298316535208147704719643540597680620087236936","4679172230637604156795937318042022923864154854442691651938994247460269907229","1335882522463553746494078522785986591315614291705829934292101976725373368456","11065273620272604365009355514189340264713621758293691226155292153430983777516","19797610913282481594364322721844477477194459892882493363050392090926410940231","340555595464576722552954065704546837246952635943129978702944548844061428008","1742274589348536403131422599750045799452335806605168562448209357194327089937","8004634555932780212105622687962138654837033759304744814047517008068597236367","21259792836471302650230386909011571036377910531286921052806306539827613257871","1572148203840302296172692987899087662991083645970020213981199456203227311557","17366059685217430838202658583531877133238988411186601920884788277789927797167","1667374854993270611186966899388364429272871276798798609368189232804195354548","11243122370259166937341976021554185874590900358539075213659201542806859562247","4625203485221283951352332459611071126180842519850354168649002699100298134164","19310193963788276325410606954197859585228809564565018659518573314566860513793","18404222578690766596537709646618669372381646203170894751882794336449192466794","20158241107274074003439398839360878783835281462919203193587994556070240642984","8125833602149066677920405899834138418803371990348257662222829272757583100886","9508932168014115650195837751034580405545805289117591333651882151226415376878","6540314526944510876745740412130536793773837522850379385820150926985892352285","15628691979293024015883109622988270654795374631665440008948198217633691358326","15176634126607768919287934026926096790564295569914803731516431791003627595889","7361229611764709926405584694991119612162735025902256739653120138645143569183","40593538786532265356854601897399429062309868189548114927900232825436409901","9181413504492753497750716776765754449161667575301120369237844519114656807918","1452190686514972724040766143298438717679802740561135629161412801669669015351","17913118796887030034121460693213048325590194589545489980583164752813086700665","8112298632892562277468071334101335538956144529240336952347088676326121150729","9665169240186479412203173696300806866691467507755689254784140993603734194593","6514283970142834699562218700617030545884351087446532822769927556364648440014","15436954899973704975944072452682932913377049721247029677476722535220053514739","12815315879077799272835474546280154054456650824687865523866464840620279148199","18311084338580438835535273240216243147945264712487665680678201354829914279713","20500911011034442024567282117177705497583241187435785920903753811573134405358","1747267706190804051777398318256066325516465696260199626829640323085239020385","15409075097998249983601659118301486683152601343243238586104888206624108736988"],["13567336202907073061436863703639370132841904165474431829027645845408607983911","2710695392452811856773357817983139967995715015594105899698552396753015770949","1804168555154471293845964482461571104367245287887347196820586181503703213261","17020378209841702353033394800062743217872589730692299868226704875546102210295","9018179614417965815822479717025982614114331247526081710799882543052558816016","15051563350429268391762013549829392345607452474174131893900617297388743903201","20126984586446593420826568111404510909041756789687233795921721768176426086846","12310725535372824898043505356776162144284861682755156745707736725675623970285","2440735907703091712826640105716090543559523533939524214356440683582052679996","16956694567912575079435642309134053606692746710682877735238625000541375462908","8911493087445969561336193800498692029963381570106621692107277542615712411988","957085824451958898899758424983844013679507347236884227083831981845335335528","9522852102525255036850603031764525259140186079318490872296003485553549519991","11015958331880740948642632155521749483222854212243957721423734666043723989276","11679410477077750470882108552811533070948301665912643665554261610109765317582","13984233649315987399738172506915478616773463942264346021907679865798299231865","15737627978978776368517635168869537228463876458758458917822472800328777299911","852708658782435248196415784589792125442850791915150719316858669786708069275","18045224495064386167155825524142060423214077631814321997525935404020191322189","13085827548519891276502623171524388188974254548619508563851382643218587973584","14463417641859750065386447130705001060695926813809723741377444829792892416466","7838878019320608724061179606066501381541827220754110933146735435818942704470","16644130146241126754409270964503741466146369221259050855436013513083243275976","10425450501063654849226486183792940017942633722012511029472166976892677433417","18183561184024093811051000342113618222397784720640107032156188565299314096285","5656592990892736652291063196811672836500852003364167146525874150969343489357","1555154620778696158976796063239629385105819788410146482723932942397222703671","4689143519529861935954947953779198505485313714032761512230890016527658389001"],["8653191897121654994046767123967504171432943084708847032424822553490374887486","5991899286503863266289916917346540315606487548265607888049866824167387057777","14712091350090440181680610088863361962514641112819034582877242669261883513741","16244589614167252289376453569013570988817062440115882364811483605656291659019","714367939813286827938877586147849419823324815733712013980619904435700404218","16644807494019883347267691971453543957719841316620503307762377792703380042573","4799879816851212319307917177749725686076131748621170540558691350092037438558","8013344000461884730895827216306454957179529929815200596989651689156555471651","10037073164668425378265947294584223329910265210740232513235826816651585576187","10449199499885277996948075244919002607278793626345715974195760635050631598707","9603670492004128798265853015533551700807056038608722702954122350271707388550","2578318487949067253175995440554172234111251371374426245036365946385516909127","8504148655425479342930624074756642725039607586931714677625300353814989745917","4839214827856596566040094330650940163414410353950379525408671000673278518447"],["19080079582803177283974734532771794373202350007929131183412286346313750672991","35946758944264662274520974148966293549562991009831873239988781162661123162","1591868453067062497534263902256196580051679960816779455201537655688240605644","5057544455583738518712418667227473396313650628619911184146365792731254277935","13451766620987506975067680300189795793558833956477379031391480111452950006674","4237697322147759561645822722316886683758889986203041886126713758433018761531","17388313193732638232156064107232954059739788079476678051632551900034680173591"],["13790068893341340654804274832614103401128214657682205750954302901815148117342","5775139322556765517380626707395745496220499860227897544755784161919364920968","4444616093993141250377779401172163977081219884171317806391990122535486474396","682135713915796770202549682456531122512303840116859081481971149948639625"],["10920616625100445532847035698774961541478968137765981219609119518062520817205","1934504349695351928293977609630374142504024075045082445583433669667010825766"],["2370585063199683457180669055524320207002653992623937683062832529991016184121"],["14039556905858470719315379022485357461691218064346796652238250635619754265952"],["19836797415830423976868384498458380816895372249326253107604084555475776302139"]] \ No newline at end of file +[["7545513665204778934119579937931337658034843334245089303733370588230123155016","19585917515800360817881561079463956928885330676318873113818737600568710039879","9765660942218343950861963466096481739694594820162128292865481912189376943231","926742712462849709662698440169391170468371485712380830395485755398570267511","20823790633066962159762767257071309884061556518147106793845560864937072027058","11138977103314849062185150683360632466650767494989831991107584033224070757169","4266736524921843192806375844771519440830775051964898341400028593663517504103","9765660942218343950861963466096481739694594820162128292865481912189376943231","926742712462849709662698440169391170468371485712380830395485755398570267511","20823790633066962159762767257071309884061556518147106793845560864937072027058","10758342370258994902973924498271763657264440740983762804549073950817004310048","10527598776820142330627180831925014598922360422140869195914844911499078855957","16138733977084662531533702170218033448869985197730328788614520712953469557164","15434346572973455077666533703377942564951632392768372571926984107385732383247","6064072848892734739825173600686111624462724540445225119098337725978251588622","1237417001024586291861611186489669176090872746723563256005790119457209738409","5020346731871096933960209893528188538946781938995422511875278230663865559674","3657513404517270973899741111041197021595111471263993304958554732703420643089","15434346572973455077666533703377942564951632392768372571926984107385732383247","6064072848892734739825173600686111624462724540445225119098337725978251588622","1237417001024586291861611186489669176090872746723563256005790119457209738409","6409804201479915779847342726301864875073457932807495705932934220743481384212","15950128514242567078618070168118709261591503102062685676745963647468620390191","6409804201479915779847342726301864875073457932807495705932934220743481384212","15950128514242567078618070168118709261591503102062685676745963647468620390191","1768611527163259662335037001842361103707430630823777549248495333388570436131","13343351410920743449291972260891276885234460144340441314908456044982814077774","15549141277677387172209441572872330225965420758075450560620324149917093523811","4897502275158978322828068505045583447273375128802717246997184303345296231057","15351953542011010793580128414673353431550840598539779418061379480276710674105","15351953542011010793580128414673353431550840598539779418061379480276710674105","12969222133060409072206103974158916680107806063669810328356902011201955925648","13875836835391599822127355278814509682851830085787338085318856800279934472724","6275541422255182056450006664308396679160159969898420367128043976527500351600","16046938330608339247716039290029033717843387433793891346726153257003796783854","1777591431970340000287147368810487196049877163880967624390712715178045073319","13875836835391599822127355278814509682851830085787338085318856800279934472724","6275541422255182056450006664308396679160159969898420367128043976527500351600","760496886461128300484752740052883353982606719416869583865550880610976295632","6943221579602743797982517064651342662484906698096420197120570141838851120267","12770728713932516808737943449600529810294790017781390009163427193726528364958","3875617379012003404154714307489161077134802309119229689262899852949161178087","3899311379605633165705785284537258749901869467765414694089543000885711618614","12770728713932516808737943449600529810294790017781390009163427193726528364958","3875617379012003404154714307489161077134802309119229689262899852949161178087","5008770122203555064158571549260616528507467639397651663781865493465364347657","2094335335123512346920253719414278751576174816493571421798094366783997484650","5008770122203555064158571549260616528507467639397651663781865493465364347657","17242422918123154688053153449885436764498389667521901119083514726219321226558","19569242828296378604062816188593042610867360054283688388198232459970836352270","2711495691562323483287564813839775988914295887300361478408732552930236767607","19569242828296378604062816188593042610867360054283688388198232459970836352270","2711495691562323483287564813839775988914295887300361478408732552930236767607","4717074991566350442296205895522241279514871627508224000562967691249197202287","20824486663040893916492978123182789435039618540889656718868409834095383546721","295287476871927943313586244030210736637257312119008178514474209194205476044","20824486663040893916492978123182789435039618540889656718868409834095383546721","295287476871927943313586244030210736637257312119008178514474209194205476044","5785208753645037544560594604597966536026655646978682733279923416322788942804","12622447269936186721327456865589673140242313135550206402224189387137424403293","7017990230101942922046932799238262874911489184467579816277845836739784806324","19841806050269951191223750609047749163829069441644956600756382989298611619163","7949066247702004569754056081041906609455496159054984574104729447791145397544","4099422096204847461550569154712881183468662583337874014378233101295116651238","7017990230101942922046932799238262874911489184467579816277845836739784806324","10094451256185324463938542812874090292338553041273705886508299668732338031950","19841806050269951191223750609047749163829069441644956600756382989298611619163","10084814829272923323289009175488200442576520131057456863925963580559201557549","8273998485425135363543067959447331147023625151384775651035050595795583054934","10482530158386482902842800129718049296599067740726194117119162504076602493277","21108409944333648157154559478842008802098282385756176018528776111079749772261","17961426625527395470170490420374506407393880262363740901226738333796157487523","10482530158386482902842800129718049296599067740726194117119162504076602493277","21108409944333648157154559478842008802098282385756176018528776111079749772261","15116402110432078055146752021879232331766409670564868314300045810344023725988","18297565077601301121968803420909787999567680660131631867519061973110803920724","246017008040700840651675025578057843454031025232405202947595612021759107206","17217731040241981472457431014892782292300981485753420457818326542748238917776","18297565077601301121968803420909787999567680660131631867519061973110803920724","246017008040700840651675025578057843454031025232405202947595612021759107206","4539597987538143693712569915957037385385966498438068697790906674062383819364","17217731040241981472457431014892782292300981485753420457818326542748238917776","13599136330051204937660632212223902336062675446221140437986682963181435570232","7570909737956673485546679119196908397396800186406942183165769008371389009829","18968340747680237301886542478716130021561751137858906182504978003254163567787","9761904222330241711439825921000566295346550608809343644252337218588990520702","21340695348662868415286190018646396345444495289139377733553661356735872405739","18878065040735449907024089176417186463591600871110326907403879557293677224470","13599136330051204937660632212223902336062675446221140437986682963181435570232","7570909737956673485546679119196908397396800186406942183165769008371389009829","12397263246517322729476408521488966062840893854371683024854796754164420929057","2860878526347838014476384053846005538671911964382195947732997419039477050139","4352253485726936037599445044774150816007324915229731946433928073125235988192","18968340747680237301886542478716130021561751137858906182504978003254163567787","9761904222330241711439825921000566295346550608809343644252337218588990520702","1333646719105530579488570539548663994726629608887761233619309263694142978550","13128735710199531285310902568474005324715330482917419484972814942725433723987","9034074759514178946411189547844656024629274521416157134830732661164478063746","10995935858940238874038348262168932605353052163827018600181294929053242784414","11044474718248749374089171092152309996122404511223491139111311583323522074191","10995935858940238874038348262168932605353052163827018600181294929053242784414","11044474718248749374089171092152309996122404511223491139111311583323522074191","17575294883585821698706159563354735829387129547855866256538793306432332376398","4244889878152775931731392924983066509481812837709233742183358630871249918203","19052069645349967969037041186716386223062972287992649495946542374871875145517","16303259261428386797549765573062444119142258834891297802294293378556802530681","14932008654096761798565103480930001039780661747345319616066831775345017618224","7456416410901867572528365454686325575726166794230807950172037673422212348410","1761380860632394307923341341502751500152800598340198554914094532068653248564","9319547832118156914162835917629926184130951688224186661787930742684367556191","14135519850017336935221971315529629556224784741042204451839364338267213123382","1761380860632394307923341341502751500152800598340198554914094532068653248564","9319547832118156914162835917629926184130951688224186661787930742684367556191","13443959010611476580635370505406840895849752794355780586971696096249072081828","748242504546048031763303447433125218245891652221248512945958633418424197744","6847035271131215384224084702748199403431692305386410965388937248152848714984","5459356157764074777126451457893732400671263988274267484631443876110456759100","6847035271131215384224084702748199403431692305386410965388937248152848714984","5459356157764074777126451457893732400671263988274267484631443876110456759100","13609793155856329945061146720676570511433630159757604106977603919055081562051","5459356157764074777126451457893732400671263988274267484631443876110456759100","748242504546048031763303447433125218245891652221248512945958633418424197744","6847035271131215384224084702748199403431692305386410965388937248152848714984","8683596458518965205105630419726249690338640772370279961592164315962472993831","8243122541545775432634349652641858600033039702562011633143136291459904148635","8243122541545775432634349652641858600033039702562011633143136291459904148635","15200076125964164997915247243678824082207774924943152057908156277284752623299","11130794590376767265093946348794823080370676666510155710852037965055115543867","20578762386496183343655436429385786214502170723560010762397878950088994494577","20578762386496183343655436429385786214502170723560010762397878950088994494577","9140409583038829003132910079638410788016554172772221893979311217986734151516","2475186346601644222680416951850997480798225996886346673374824694378098371554","2475186346601644222680416951850997480798225996886346673374824694378098371554","17631647791982642734352175184436927698800269130591642381438200125261663611504","11754281877121280089697577947748442218242939674592522293272390438520194835742","10720892039938581299556212432912637930330408813991319597511529294574677114426","14903647747224825841372374123884728533333731887832195884927387659082961665060","7838763884896886040987570208220497725156733176082557316654239393507506602524","9140409583038829003132910079638410788016554172772221893979311217986734151516","2475186346601644222680416951850997480798225996886346673374824694378098371554","17631647791982642734352175184436927698800269130591642381438200125261663611504","1530289048398066655574087861935611840874150582543500407956083126001278758264","1530289048398066655574087861935611840874150582543500407956083126001278758264","16136056940366399523435148014876467808856102155455908562222530491709516028147","16376194709471000311648429869188151295241808464211150100799298953600058529849","15793766401507815044103474338124896664059763206719794269792944102468626700233","2982174036355567780333061510725391337887981766309558828247307731047705843798","14030082703988303971232666609091671314095464063858317702865842051075915730334","8919773119195608740047341615127889316170471718810585196984957847849075533529","14030082703988303971232666609091671314095464063858317702865842051075915730334","15291116065258154111409027765298168104556676059569662278259529571622596764857","6875401864395966163086302157078759524588955677043449349219026762955903914206","5095931690722060786318665874006098481795321570507488299638491217059000248848","9380284601646238029939121673448226840826564473678361999377470283009586303083","2743397452050478411017269067930224517450337309891471738060967996801797144768","9380284601646238029939121673448226840826564473678361999377470283009586303083","15291116065258154111409027765298168104556676059569662278259529571622596764857","804036418260069472123268953851829016456646611641096968121272390377609901924","9873572286640548058085538409892808976430458576418083750656661779175873424261","5095931690722060786318665874006098481795321570507488299638491217059000248848","20470775335873221199373651227532410144014713578523919781166528630182925453446","1170685286341059352326927448875351524097517437747738201876949516241697840038","9295999385463191276176781035461531188797273683652144958566177563247087683861","16428829498569941559417418645501012433085771838958036962530487938389877741162","1170685286341059352326927448875351524097517437747738201876949516241697840038","9295999385463191276176781035461531188797273683652144958566177563247087683861","8552226814177781837201473595362586720286315554889694080217269726053421748718","1819862310740274731869533573887623069322780260431237880381117766305092022341","5211739273564141017230187562348980714006753203838499546143338957012181339326","21003303554927099168037815632285306264172578941372047536946358610348372877175","6666118803111656791409768305838898573330958900158460098627035845882296763822","18711655788055484135860952926320463711485833200044891994538447395940789649611","2283864355697245672767850851697988502827516822770602840729561903099639539321","21621294160165445140090678961497679782321912856231392535175646140774919324539","13494059916404350447381273436985999956602873304987168590093032636551660723231","18605462664483663601442969032728347514971120868133290370471343345284109885107","19666066119632595452162581424320848471786165329993739257085503275244157900906","3438001309498655844725700770655839439037334616140994763339893179644277717385","4657588831297540580761825043089906062736951006857893289321311017586696975681","16748383274471189422166535106537869113814581956070997597483909959547658598524","13103114974306702000902207179478099850294067104168067226680921215987548394709","1938677203812984586292416098261578783715997244578190173548548555163996612138","1712856054382561256876009280520146404040173405115930983706993670655112549673","16748383274471189422166535106537869113814581956070997597483909959547658598524","13103114974306702000902207179478099850294067104168067226680921215987548394709","6743117350305657733750766872094179950919206135990613668778890659570856843463","1712856054382561256876009280520146404040173405115930983706993670655112549673","20473354391265371100796759353610455712373085548312105123240749059790955977397","17325005331498606686523060308502041998874249065365377291048515477038398642504","581583400595965954448518734239211477782535397806368789691005112239401996782","18708875018819765443552572175772423195874740794417331529732563170186026562689","14814532008720180899410894797928748104806408726679018165692550951548094273901","12304557403652564317405325005801735215375768131634737900381202211472854215302","15866392312479117462644923696210142708054503327678476876754260538038212778388","14663842244367073508740698122140162207105114154731500716147633126910154451659","14814532008720180899410894797928748104806408726679018165692550951548094273901","7013540700974558820462607698396750849394976239252107247637511394084098704192","4051436449862481433565845699031860717747846263610878586747286777075863978617","15866392312479117462644923696210142708054503327678476876754260538038212778388","14663842244367073508740698122140162207105114154731500716147633126910154451659","3300997195062734931445267956226521235811697507277645506051435709475147953622","17681219118469031504275843962216575889405814601918857029882925383476187560517","221579138514265075965801481003636088305707834706196688540398147777465836446","3300997195062734931445267956226521235811697507277645506051435709475147953622","17681219118469031504275843962216575889405814601918857029882925383476187560517","15454401903742554462612857131739227720656116757069879307159611546474650083059","221579138514265075965801481003636088305707834706196688540398147777465836446","17690257276606134502150745117877085180586870358214997894856148424251982569953","14028882947752968516140358422785274838006253385433251105799327186772468459943","16367561808119423461759835765335744200194010661712433395500358865835104416736","19038170307785075908771874025720818601267600479253706987062726896051368889758","17690257276606134502150745117877085180586870358214997894856148424251982569953","14234865987232099770353669057958910208353037531762075918233528402000261487629","18017763953163230484787496619098275100697725101397445733457273824832974093770","7317982926649007812104755989986892347850909582228978673593667327465732456669","11850860322545159240132628656206925609343109228721869992918966076745597525246","18017763953163230484787496619098275100697725101397445733457273824832974093770","13256421313147725243395827115140384499105813013022855127885819413701885999283","2634396206482502764594423962429425719111631515576017920143439971723713144631","11850860322545159240132628656206925609343109228721869992918966076745597525246","8037903959367167256769130883870176483688860685264353361922472848979131718165","13764391857417159273003395886929163780103760207039181171574972648099033175865","13299827233248581777172487328404882732139488366769580639143531379825292904589","2733662062406213819716176871158957276807195480146594182421060227039865478080","5509367124469571124317738686567335091193489133971054459773190929467634765622","2733662062406213819716176871158957276807195480146594182421060227039865478080","8961414565926544099205356497581288212625809041394116526575913229479703555449","20819271248337129619498144731441800909275898285878362161169915669683474918227","2006850180463826223852282260898508367602987405462566534907215784204463585303","9792842929514694082593276709767883876982349062013750673044701158232405982121","2006850180463826223852282260898508367602987405462566534907215784204463585303","9792842929514694082593276709767883876982349062013750673044701158232405982121","12232528025451428302803545986690863470045450983339511131031578015773334973023","9132687731383167642675732303118110886700485483620950075155177074442879963350","2641846462881188748796225779249406327677092487689305542395461496228421386373","19613125415063238747119105266390028295012583030017421029797443106800921231547","16676737333911287697702542044117233404972541552113319846622948677886641766467","9132687731383167642675732303118110886700485483620950075155177074442879963350","4836561138591069314581809200885585106054248491118940999011213532147044732404","9100687758133421694057684467069779101967156914794244151324845393952456861346","403406968023485795511687748010577913056365396048942436809136003862954225252","9100687758133421694057684467069779101967156914794244151324845393952456861346","13764391857417159273003395886929163780103760207039181171574972648099033175865","12770728713932516808737943449600529810294790017781390009163427193726528364958","10084814829272923323289009175488200442576520131057456863925963580559201557549","17575294883585821698706159563354735829387129547855866256538793306432332376398","10995935858940238874038348262168932605353052163827018600181294929053242784414","11044474718248749374089171092152309996122404511223491139111311583323522074191","16428829498569941559417418645501012433085771838958036962530487938389877741162","1170685286341059352326927448875351524097517437747738201876949516241697840038","9319547832118156914162835917629926184130951688224186661787930742684367556191","4836561138591069314581809200885585106054248491118940999011213532147044732404","2641846462881188748796225779249406327677092487689305542395461496228421386373","19613125415063238747119105266390028295012583030017421029797443106800921231547","14814532008720180899410894797928748104806408726679018165692550951548094273901","7013540700974558820462607698396750849394976239252107247637511394084098704192","8384062539908915944022947800178840181050762969622974725255522072093500158767","3494797244908300460305378858370473489306692924748418454077559598659211986306","1777591431970340000287147368810487196049877163880967624390712715178045073319","16046938330608339247716039290029033717843387433793891346726153257003796783854","6943221579602743797982517064651342662484906698096420197120570141838851120267","16748383274471189422166535106537869113814581956070997597483909959547658598524","1333646719105530579488570539548663994726629608887761233619309263694142978550","3875617379012003404154714307489161077134802309119229689262899852949161178087","6847035271131215384224084702748199403431692305386410965388937248152848714984","14744567337336193894294580681889120364531710302323252899181650040769110924552","15434346572973455077666533703377942564951632392768372571926984107385732383247","5020346731871096933960209893528188538946781938995422511875278230663865559674","3657513404517270973899741111041197021595111471263993304958554732703420643089","403406968023485795511687748010577913056365396048942436809136003862954225252","5095931690722060786318665874006098481795321570507488299638491217059000248848","882264742732300525282055972057127387292645391728148827563533775212806682105","2743397452050478411017269067930224517450337309891471738060967996801797144768","15291116065258154111409027765298168104556676059569662278259529571622596764857","804036418260069472123268953851829016456646611641096968121272390377609901924","5844364026616244131283595465105760283508601723675112565531256006878681193396","9873572286640548058085538409892808976430458576418083750656661779175873424261","9792842929514694082593276709767883876982349062013750673044701158232405982121","7414844280715453303881033992807659157223447055173254736786963917653102498959","21108409944333648157154559478842008802098282385756176018528776111079749772261","3742591250530334674877473560846678731472964363591618541737848896403172629698","8425397865477671225176655542535046946999157376164237502993432608601946106895","8811188635063054096479459519079819415698086355667008655513961733231728343207","8243122541545775432634349652641858600033039702562011633143136291459904148635","9295999385463191276176781035461531188797273683652144958566177563247087683861","14030082703988303971232666609091671314095464063858317702865842051075915730334","5002410368449115881500339697696503965900281914341125463866991956460269402234","1768216918003348522472312194683727294629858749445970701750333864972223351849","13297848246062435343909829464804616166875240061719053260441840491668576272403","20819271248337129619498144731441800909275898285878362161169915669683474918227","6556693601992995719622087340125141698229691211178443781141444536216197842967","18460722210944486605037463862182989660686349567958871663132766642844916834717","1237417001024586291861611186489669176090872746723563256005790119457209738409","15866392312479117462644923696210142708054503327678476876754260538038212778388","14782435175471784172510622373998992455377089048331797201555379024109452363621","8683596458518965205105630419726249690338640772370279961592164315962472993831","21726146673740323220900872527757782084104678085773200029322260308882040907056","295287476871927943313586244030210736637257312119008178514474209194205476044","5509367124469571124317738686567335091193489133971054459773190929467634765622","2733662062406213819716176871158957276807195480146594182421060227039865478080","6177809281448024023402995215371492617968707601844198597737617137801294941868","15137604245835758995999805425459824278317735474662041375329277223315203016990","12969222133060409072206103974158916680107806063669810328356902011201955925648","14663842244367073508740698122140162207105114154731500716147633126910154451659","5008770122203555064158571549260616528507467639397651663781865493465364347657","17508201928974511571005573827054461353711612525195214982011840169845089150448","1712856054382561256876009280520146404040173405115930983706993670655112549673","7017990230101942922046932799238262874911489184467579816277845836739784806324","560238348327812164910399733286031507613805383142047184365445888677643974823","6064072848892734739825173600686111624462724540445225119098337725978251588622","20473354391265371100796759353610455712373085548312105123240749059790955977397","9100687758133421694057684467069779101967156914794244151324845393952456861346","19569242828296378604062816188593042610867360054283688388198232459970836352270","2711495691562323483287564813839775988914295887300361478408732552930236767607","19656831033694833239912207790670456760224437243904397785346314495419974538457","246017008040700840651675025578057843454031025232405202947595612021759107206","9132687731383167642675732303118110886700485483620950075155177074442879963350","17631647791982642734352175184436927698800269130591642381438200125261663611504","15950128514242567078618070168118709261591503102062685676745963647468620390191","3438001309498655844725700770655839439037334616140994763339893179644277717385","20578762386496183343655436429385786214502170723560010762397878950088994494577","15351953542011010793580128414673353431550840598539779418061379480276710674105","19201682783551485583038872553543602114066313754681934256939507949353212818240","2634396206482502764594423962429425719111631515576017920143439971723713144631","16208605384154008021838451543122153409010372137069331353708419489592288464258","8273998485425135363543067959447331147023625151384775651035050595795583054934","18297565077601301121968803420909787999567680660131631867519061973110803920724","19777524202697558032910183884161018338429578966070241763715789133879529233748","4657588831297540580761825043089906062736951006857893289321311017586696975681","5043219963983785615642200211458142932602051386962779979530853680229678729250","1758469570873479859654848618390853130652834643685603268682705348361999935622","221579138514265075965801481003636088305707834706196688540398147777465836446","14863197331234981197564870097102941283436248045424027191515289897039004816056","748242504546048031763303447433125218245891652221248512945958633418424197744","2475186346601644222680416951850997480798225996886346673374824694378098371554","20823790633066962159762767257071309884061556518147106793845560864937072027058","4559891820758930973641609834061124429608343056135452005192199753109509837904","6275541422255182056450006664308396679160159969898420367128043976527500351600","17934932161127322668904071953728883624170338217697472030241732386938838637920","13875836835391599822127355278814509682851830085787338085318856800279934472724","3451109862994643648688440784951652442136026374861510414549619598290573157426","2440349363078734022847909594245962229017282317516742138917409303830541476560","19038170307785075908771874025720818601267600479253706987062726896051368889758","17690257276606134502150745117877085180586870358214997894856148424251982569953","5211739273564141017230187562348980714006753203838499546143338957012181339326","10720892039938581299556212432912637930330408813991319597511529294574677114426","9140409583038829003132910079638410788016554172772221893979311217986734151516","926742712462849709662698440169391170468371485712380830395485755398570267511","10482530158386482902842800129718049296599067740726194117119162504076602493277","17830626286252994358021517730187459911437127362195413138642174981503420226897","4266736524921843192806375844771519440830775051964898341400028593663517504103","7802341166893412118154653065923227214372634853803472887096760799252665673436","9765660942218343950861963466096481739694594820162128292865481912189376943231","17961426625527395470170490420374506407393880262363740901226738333796157487523","18837695853267906668018794451596360585592472890613988691006516476125380233270","14903647747224825841372374123884728533333731887832195884927387659082961665060","11754281877121280089697577947748442218242939674592522293272390438520194835742","1480133563549178442753614164920808594391633250872284715688231726449945938993","1768611527163259662335037001842361103707430630823777549248495333388570436131","13599136330051204937660632212223902336062675446221140437986682963181435570232","14135519850017336935221971315529629556224784741042204451839364338267213123382","6409804201479915779847342726301864875073457932807495705932934220743481384212","2094335335123512346920253719414278751576174816493571421798094366783997484650","4051436449862481433565845699031860717747846263610878586747286777075863978617","6666118803111656791409768305838898573330958900158460098627035845882296763822","21514262377244088249371067947474465713690135535574849762059383639118338292112","6683517783593343339348692344876397332598081400376387653080810411442127355336","15102076605742283425124324842017318219912681161720665390327337228304360038287","13599136330051204937660632212223902336062675446221140437986682963181435570232","2860878526347838014476384053846005538671911964382195947732997419039477050139","12397263246517322729476408521488966062840893854371683024854796754164420929057","17242422918123154688053153449885436764498389667521901119083514726219321226558","18708875018819765443552572175772423195874740794417331529732563170186026562689","3739680096675663097679166032209866403782564552088042042817858323092774345680","12517791173181809924390368638722485126198198467803444038079663678657941781229","14083955460283340099581981224537178400807166795382447529358365552937588159464","2982174036355567780333061510725391337887981766309558828247307731047705843798","15793766401507815044103474338124896664059763206719794269792944102468626700233","4352253485726936037599445044774150816007324915229731946433928073125235988192","13443959010611476580635370505406840895849752794355780586971696096249072081828","13128735710199531285310902568474005324715330482917419484972814942725433723987","13443959010611476580635370505406840895849752794355780586971696096249072081828","11850860322545159240132628656206925609343109228721869992918966076745597525246","3138064552983687106873013609879596382388385905584970412906962704788770126364","6540769617029109885796694709580876545736960191825862943951222466407417429888","3564296203435751413790668882227371254256123932305287650316219972985939163116","367649049536936808750291083058330318935467068855620422078450013873060777794","14866923877290766501844024405041107837055619398984009124628895337190631750037","3138064552983687106873013609879596382388385905584970412906962704788770126364","3899311379605633165705785284537258749901869467765414694089543000885711618614","19841806050269951191223750609047749163829069441644956600756382989298611619163","13609793155856329945061146720676570511433630159757604106977603919055081562051","5459356157764074777126451457893732400671263988274267484631443876110456759100","5095931690722060786318665874006098481795321570507488299638491217059000248848","2743397452050478411017269067930224517450337309891471738060967996801797144768","14127913900294160784966101869979466903955716423950321921365178663512474391974","11138977103314849062185150683360632466650767494989831991107584033224070757169","4057869120791333231764334075051333236988675750843298138540375068119954248807","13619200238846047752817122761482805227839886683919335698286252460262577182329","13128735710199531285310902568474005324715330482917419484972814942725433723987","4057869120791333231764334075051333236988675750843298138540375068119954248807","10482530158386482902842800129718049296599067740726194117119162504076602493277","15116402110432078055146752021879232331766409670564868314300045810344023725988","13064640458922805030841204349004756656227831120289033173617711540821029453990","4352253485726936037599445044774150816007324915229731946433928073125235988192","10094451256185324463938542812874090292338553041273705886508299668732338031950","12172166189307891302818618757060033061332629980026171197975991554774751476453","13256421313147725243395827115140384499105813013022855127885819413701885999283","1573667568002545327171486141307611553615853440410844691633690870863655293319","857473870857284264596881638672193466852131495786367461633039372200362215842","7624233529636712957260225243277217437029285776695456519227191366086024359294","7701577445884811644915171107920479557210910950646439988584215073012797073372","8522081595859024002605143731791503145633572840109807700765675834715814536942","13985957629276907683378717751630481564826907698663120998083131647495539320584","16136056940366399523435148014876467808856102155455908562222530491709516028147","9903040728368126595774478648223333601321958114333123056344777747131819311536","11850860322545159240132628656206925609343109228721869992918966076745597525246","20836394993632333178267425502999840897759529214605159702290926713946858720667","17821453092966044227297534562861299407119366979285835652170909177797536665597","17042742099181805739068031017013547212018937842625418102556479120051739566068","21429949120079165505315359431967053687487549244847776997176528865459654908558","5957443011889753555135936681872888891045070598365834308318500428514626535147","11138977103314849062185150683360632466650767494989831991107584033224070757169","5365729002668974569482726927224509899190941066947032676387945779281837917677","1546700280421666453711388780779510853511574762805881222636906597251317813974","21277607853750483499566974872383473298719714148247045093430156086409548187765","18594557186236757152739692658153687629812068422339688647257256262836714835702","4717074991566350442296205895522241279514871627508224000562967691249197202287","18316531767983289417995809826068757234240267564422464329427374602538214683959","14028882947752968516140358422785274838006253385433251105799327186772468459943","16021909971170328828934252943019419628560391036972314828345932551224568638470","4244889878152775931731392924983066509481812837709233742183358630871249918203","7456416410901867572528365454686325575726166794230807950172037673422212348410","21003303554927099168037815632285306264172578941372047536946358610348372877175","2711495691562323483287564813839775988914295887300361478408732552930236767607","3859281426803674628501369664467063890695820623561849556038355710838082808115","14814532008720180899410894797928748104806408726679018165692550951548094273901","4976599850581663342926141387010875949132066366354505477429501678692463644985","19676087152809156419842493943502179230952426429629012884637263946755477423004","12114414016653090409406221134564667850845499287069713235231061229461614867396","12232528025451428302803545986690863470045450983339511131031578015773334973023","14663842244367073508740698122140162207105114154731500716147633126910154451659","13599136330051204937660632212223902336062675446221140437986682963181435570232","21163394280557998571697330647864872028388232956862903089600467011608810708409","17325005331498606686523060308502041998874249065365377291048515477038398642504","17550827945668577790165231801226951492858622309347609933644598474684727962533","15950128514242567078618070168118709261591503102062685676745963647468620390191","9903040728368126595774478648223333601321958114333123056344777747131819311536","18711655788055484135860952926320463711485833200044891994538447395940789649611","16428829498569941559417418645501012433085771838958036962530487938389877741162","7570909737956673485546679119196908397396800186406942183165769008371389009829","16672768401548620695880571975143326624025608520963680880206152407746412481018","7177797141449348102252072434317801234665727548109244404793341197356578133440","18698874964731494012030224341478894927632990719020546489540371336994590532475","15193139609036993903985058593394392338047360851299948147559709929852496975231","9761904222330241711439825921000566295346550608809343644252337218588990520702","19483837651479321736302742289249370944897077639190358118567409670556418580958","9302253318678709320220824180958227581066631404025342032312081800403066408850","7060710356214345904169727589611074541770760626094723751422704595391569313623","12304557403652564317405325005801735215375768131634737900381202211472854215302","7009314085251158111809750383518669123393580401568741062754730433280706787183","3508485914680778327798782388148464883696571973519643631899250366201272125015","2283864355697245672767850851697988502827516822770602840729561903099639539321","19350020816886738246126301835194005513454931001609989413817735725019099368659","15866392312479117462644923696210142708054503327678476876754260538038212778388","14234865987232099770353669057958910208353037531762075918233528402000261487629","17934932161127322668904071953728883624170338217697472030241732386938838637920","4539597987538143693712569915957037385385966498438068697790906674062383819364","1170685286341059352326927448875351524097517437747738201876949516241697840038","6847035271131215384224084702748199403431692305386410965388937248152848714984","1777591431970340000287147368810487196049877163880967624390712715178045073319","18226655766844663132988970122229661231752571424447667758542810294663399940759","2364789189738914986238949881134463507774700359870226841539179693783222560334","17217731040241981472457431014892782292300981485753420457818326542748238917776","8552226814177781837201473595362586720286315554889694080217269726053421748718","2006850180463826223852282260898508367602987405462566534907215784204463585303","9792842929514694082593276709767883876982349062013750673044701158232405982121","11639213210002182447589915543342471270996105971970183505504663388847338819553","14744567337336193894294580681889120364531710302323252899181650040769110924552","9746116370353073579392113846809135533254667736880679137897314847608250417861","7948272832666027245094475239179406958318217144504241242156520748838392374437","9746116370353073579392113846809135533254667736880679137897314847608250417861","7948272832666027245094475239179406958318217144504241242156520748838392374437","12622447269936186721327456865589673140242313135550206402224189387137424403293","8425397865477671225176655542535046946999157376164237502993432608601946106895","19656831033694833239912207790670456760224437243904397785346314495419974538457","19950971209750256650428124886760343100788205392906978830444423756873330773871","14782435175471784172510622373998992455377089048331797201555379024109452363621","9100687758133421694057684467069779101967156914794244151324845393952456861346","5785208753645037544560594604597966536026655646978682733279923416322788942804","295287476871927943313586244030210736637257312119008178514474209194205476044","20824486663040893916492978123182789435039618540889656718868409834095383546721","20578762386496183343655436429385786214502170723560010762397878950088994494577","3899311379605633165705785284537258749901869467765414694089543000885711618614","17508201928974511571005573827054461353711612525195214982011840169845089150448","5008770122203555064158571549260616528507467639397651663781865493465364347657","8522081595859024002605143731791503145633572840109807700765675834715814536942","21726146673740323220900872527757782084104678085773200029322260308882040907056","16367561808119423461759835765335744200194010661712433395500358865835104416736","7624233529636712957260225243277217437029285776695456519227191366086024359294","857473870857284264596881638672193466852131495786367461633039372200362215842","13985957629276907683378717751630481564826907698663120998083131647495539320584","1530289048398066655574087861935611840874150582543500407956083126001278758264","8037903959367167256769130883870176483688860685264353361922472848979131718165","12101588765123482595247263890106766698718153799355148550822821714716885577044","9295999385463191276176781035461531188797273683652144958566177563247087683861","7701577445884811644915171107920479557210910950646439988584215073012797073372","20024906171954396923165244183469357190404524205780988170007189310403645813686","16551788798398168685581609395227493267550344840937528782604561422855100820111","8604568529290264588828050780698498293310498688464896629946556577424676849339","20578762386496183343655436429385786214502170723560010762397878950088994494577","20578762386496183343655436429385786214502170723560010762397878950088994494577","16676737333911287697702542044117233404972541552113319846622948677886641766467","8604568529290264588828050780698498293310498688464896629946556577424676849339","221579138514265075965801481003636088305707834706196688540398147777465836446","10527598776820142330627180831925014598922360422140869195914844911499078855957","20734308610592487113169757667242222112420104925970775271984424782741913190289","15351953542011010793580128414673353431550840598539779418061379480276710674105","19201682783551485583038872553543602114066313754681934256939507949353212818240","10219429240592164007579283290907650649439236137135526233263120027946178711823","11130794590376767265093946348794823080370676666510155710852037965055115543867","6858187439282460928294438746100083713898576826242912501712322172927350361818","16208605384154008021838451543122153409010372137069331353708419489592288464258","10995935858940238874038348262168932605353052163827018600181294929053242784414","11044474718248749374089171092152309996122404511223491139111311583323522074191","20734308610592487113169757667242222112420104925970775271984424782741913190289","4598522599722636038915737956257769917494518864237921012015433340555488402255","8746883098315210954148764703020462487100836419098119268723563180862668140190","17681219118469031504275843962216575889405814601918857029882925383476187560517","19777524202697558032910183884161018338429578966070241763715789133879529233748","5043219963983785615642200211458142932602051386962779979530853680229678729250","19841806050269951191223750609047749163829069441644956600756382989298611619163","17631647791982642734352175184436927698800269130591642381438200125261663611504","17042742099181805739068031017013547212018937842625418102556479120051739566068","2733662062406213819716176871158957276807195480146594182421060227039865478080","748242504546048031763303447433125218245891652221248512945958633418424197744","21429949120079165505315359431967053687487549244847776997176528865459654908558","2475186346601644222680416951850997480798225996886346673374824694378098371554","14863197331234981197564870097102941283436248045424027191515289897039004816056","17690257276606134502150745117877085180586870358214997894856148424251982569953","4559891820758930973641609834061124429608343056135452005192199753109509837904","15454401903742554462612857131739227720656116757069879307159611546474650083059","20823790633066962159762767257071309884061556518147106793845560864937072027058","13875836835391599822127355278814509682851830085787338085318856800279934472724","6275541422255182056450006664308396679160159969898420367128043976527500351600","3451109862994643648688440784951652442136026374861510414549619598290573157426","5365729002668974569482726927224509899190941066947032676387945779281837917677","926742712462849709662698440169391170468371485712380830395485755398570267511","9765660942218343950861963466096481739694594820162128292865481912189376943231","6796377608560847314002684835667843049358542045358091970488845411586870633226","19987450951662944045566008674292969613743481809231055934467403434784231084488","10219429240592164007579283290907650649439236137135526233263120027946178711823","15008208149634837312133023713529752285094145759476671710017991585949908787429","19585917515800360817881561079463956928885330676318873113818737600568710039879","760496886461128300484752740052883353982606719416869583865550880610976295632","5338297453230925767968809474204487076962589085958616090224672294777919041552","18837695853267906668018794451596360585592472890613988691006516476125380233270","13103114974306702000902207179478099850294067104168067226680921215987548394709","7456416410901867572528365454686325575726166794230807950172037673422212348410","13609793155856329945061146720676570511433630159757604106977603919055081562051","5459356157764074777126451457893732400671263988274267484631443876110456759100","18968340747680237301886542478716130021561751137858906182504978003254163567787","13599136330051204937660632212223902336062675446221140437986682963181435570232","14083955460283340099581981224537178400807166795382447529358365552937588159464","2860878526347838014476384053846005538671911964382195947732997419039477050139","6409804201479915779847342726301864875073457932807495705932934220743481384212","21340695348662868415286190018646396345444495289139377733553661356735872405739","6743117350305657733750766872094179950919206135990613668778890659570856843463","16138733977084662531533702170218033448869985197730328788614520712953469557164","15434346572973455077666533703377942564951632392768372571926984107385732383247","16376194709471000311648429869188151295241808464211150100799298953600058529849","17217731040241981472457431014892782292300981485753420457818326542748238917776","12770728713932516808737943449600529810294790017781390009163427193726528364958","9319547832118156914162835917629926184130951688224186661787930742684367556191","3300997195062734931445267956226521235811697507277645506051435709475147953622","5459356157764074777126451457893732400671263988274267484631443876110456759100","13103114974306702000902207179478099850294067104168067226680921215987548394709","9380284601646238029939121673448226840826564473678361999377470283009586303083","882264742732300525282055972057127387292645391728148827563533775212806682105","8384062539908915944022947800178840181050762969622974725255522072093500158767","6796377608560847314002684835667843049358542045358091970488845411586870633226","1761380860632394307923341341502751500152800598340198554914094532068653248564","6796377608560847314002684835667843049358542045358091970488845411586870633226","3494797244908300460305378858370473489306692924748418454077559598659211986306","14290847842905127474046197333942662016255466222141145063879602495382605601511","14290847842905127474046197333942662016255466222141145063879602495382605601511","1712856054382561256876009280520146404040173405115930983706993670655112549673","7017990230101942922046932799238262874911489184467579816277845836739784806324","6064072848892734739825173600686111624462724540445225119098337725978251588622","5008770122203555064158571549260616528507467639397651663781865493465364347657","2006850180463826223852282260898508367602987405462566534907215784204463585303","19569242828296378604062816188593042610867360054283688388198232459970836352270","18017763953163230484787496619098275100697725101397445733457273824832974093770","6847035271131215384224084702748199403431692305386410965388937248152848714984","20852822982836370270428336208130774694452706012353006468776180294908441194649","9132687731383167642675732303118110886700485483620950075155177074442879963350","17576428881902561216499172298311238443609998004779163679274310558626914248195","20852822982836370270428336208130774694452706012353006468776180294908441194649","4995625210030681114338482771208461813113511487120049035926399088923012862463","4995625210030681114338482771208461813113511487120049035926399088923012862463","21108409944333648157154559478842008802098282385756176018528776111079749772261","11991743352357984080542620812725930476070375974777272133699061067557358162634","11991743352357984080542620812725930476070375974777272133699061067557358162634","10758342370258994902973924498271763657264440740983762804549073950817004310048","11303906169575534045772742339926157411040543882105589848444877254993390759965","15209110374271276284416010091589742404103245501690927180810222936212489154248","13847425116823355837856900231529413868308426220020314025299759700434329820119","15359439551337222813250243660672340422839325353747399177520260873287865444269","19550359830055229605480401045520162124032745374759178128337002259976080207733","5478768972105287908917558952005522342329511279361606822132059018900647442213","9178922630857327419493545919748952621590886087752397897513378167142987596503","18605462664483663601442969032728347514971120868133290370471343345284109885107","20824486663040893916492978123182789435039618540889656718868409834095383546721","10566839905565475639554084209281738316683926772441604201622141043846053836435","4099422096204847461550569154712881183468662583337874014378233101295116651238","16303259261428386797549765573062444119142258834891297802294293378556802530681","14932008654096761798565103480930001039780661747345319616066831775345017618224","13401265523174350207399614948582718281068786011606407313908084629997064024082","13343351410920743449291972260891276885234460144340441314908456044982814077774","6711831470502915734571635592340410723031997135642685270964534669832587914910","10167923572811924795963029757516787891657646374572690934680479122259594378653","1819862310740274731869533573887623069322780260431237880381117766305092022341","2298149851199208408479642123950743164481822651418202356156434069263700082386","863484343969259908235561165599153577959991888413699221341286527557412447294","19666066119632595452162581424320848471786165329993739257085503275244157900906","8247607028653399079967515444168342735382757818040462611305232733794911570529","11889333174693715634696230227665725421548562994321832613983903863941723495406","1925555192244259738968997504189473112770712882563314425439578655531186450917","1761380860632394307923341341502751500152800598340198554914094532068653248564","15090385730795082275918673033294417314826868498794525399868451135519815091865","21514262377244088249371067947474465713690135535574849762059383639118338292112","13103210030006379508710327991596203595117685887272306710281866879129282889522","12517791173181809924390368638722485126198198467803444038079663678657941781229","19052069645349967969037041186716386223062972287992649495946542374871875145517","5002410368449115881500339697696503965900281914341125463866991956460269402234","1768216918003348522472312194683727294629858749445970701750333864972223351849","15291116065258154111409027765298168104556676059569662278259529571622596764857","6875401864395966163086302157078759524588955677043449349219026762955903914206","3875617379012003404154714307489161077134802309119229689262899852949161178087","8811188635063054096479459519079819415698086355667008655513961733231728343207","16367561808119423461759835765335744200194010661712433395500358865835104416736","560238348327812164910399733286031507613805383142047184365445888677643974823","14030082703988303971232666609091671314095464063858317702865842051075915730334","8243122541545775432634349652641858600033039702562011633143136291459904148635","7317982926649007812104755989986892347850909582228978673593667327465732456669","16053223144051776210021121522311364045105840123241693146516567172706097940456","7414844280715453303881033992807659157223447055173254736786963917653102498959","18017763953163230484787496619098275100697725101397445733457273824832974093770","10167923572811924795963029757516787891657646374572690934680479122259594378653","4241690178334943774846705019028501269273892416694670671794589672803576152003","6711831470502915734571635592340410723031997135642685270964534669832587914910","1237417001024586291861611186489669176090872746723563256005790119457209738409","246017008040700840651675025578057843454031025232405202947595612021759107206","2298149851199208408479642123950743164481822651418202356156434069263700082386","18297565077601301121968803420909787999567680660131631867519061973110803920724","19666066119632595452162581424320848471786165329993739257085503275244157900906","3300997195062734931445267956226521235811697507277645506051435709475147953622","863484343969259908235561165599153577959991888413699221341286527557412447294","2475186346601644222680416951850997480798225996886346673374824694378098371554","2475186346601644222680416951850997480798225996886346673374824694378098371554","9140409583038829003132910079638410788016554172772221893979311217986734151516","17830626286252994358021517730187459911437127362195413138642174981503420226897","1480133563549178442753614164920808594391633250872284715688231726449945938993","3466862489091862890795993808258326750826384147592275668387476845543398227719","5164114872848982667261217351533427763411796364093095238653229703398665292539","11412752821347216826535801398419920482771697763992364968446350650382447860269","20933867936697484275751601875969890671976413989244023450867604066732796912311","17681219118469031504275843962216575889405814601918857029882925383476187560517","9873572286640548058085538409892808976430458576418083750656661779175873424261","16579855004672155110256909868106572004567364528894426089363103570950923706178","9863436358398866308277815611043964864113095632273854636835960432894830546329","16579855004672155110256909868106572004567364528894426089363103570950923706178","9863436358398866308277815611043964864113095632273854636835960432894830546329","7714522387938613761777356926030778323332286658158305558158073336459768759004","3145424438976626802464323100030866968989785360248902574070867232159665311296","18739879347955359773956418472577734770861305252157992280705792499489419269275","7414844280715453303881033992807659157223447055173254736786963917653102498959","3159583498534012190330375550662507188341730415740096677739645644205631521549","21621294160165445140090678961497679782321912856231392535175646140774919324539","7949066247702004569754056081041906609455496159054984574104729447791145397544","20470775335873221199373651227532410144014713578523919781166528630182925453446","15116402110432078055146752021879232331766409670564868314300045810344023725988","1530289048398066655574087861935611840874150582543500407956083126001278758264","8604568529290264588828050780698498293310498688464896629946556577424676849339","7838763884896886040987570208220497725156733176082557316654239393507506602524","7545513665204778934119579937931337658034843334245089303733370588230123155016","17830626286252994358021517730187459911437127362195413138642174981503420226897","15549141277677387172209441572872330225965420758075450560620324149917093523811","4897502275158978322828068505045583447273375128802717246997184303345296231057","8414880864523282453940949872754793534626295109619691838762572162637337897465","18878065040735449907024089176417186463591600871110326907403879557293677224470","18968340747680237301886542478716130021561751137858906182504978003254163567787","15200076125964164997915247243678824082207774924943152057908156277284752623299","9034074759514178946411189547844656024629274521416157134830732661164478063746","7570909737956673485546679119196908397396800186406942183165769008371389009829","9761904222330241711439825921000566295346550608809343644252337218588990520702","8961414565926544099205356497581288212625809041394116526575913229479703555449","8919773119195608740047341615127889316170471718810585196984957847849075533529","14234865987232099770353669057958910208353037531762075918233528402000261487629","19136512789261496605492599684817671516432480462677305224225714629577887500628","581583400595965954448518734239211477782535397806368789691005112239401996782","13299827233248581777172487328404882732139488366769580639143531379825292904589","8384062539908915944022947800178840181050762969622974725255522072093500158767","6796377608560847314002684835667843049358542045358091970488845411586870633226","3494797244908300460305378858370473489306692924748418454077559598659211986306","6796377608560847314002684835667843049358542045358091970488845411586870633226","14863197331234981197564870097102941283436248045424027191515289897039004816056","3494797244908300460305378858370473489306692924748418454077559598659211986306","8384062539908915944022947800178840181050762969622974725255522072093500158767","14863197331234981197564870097102941283436248045424027191515289897039004816056","6796377608560847314002684835667843049358542045358091970488845411586870633226","21514262377244088249371067947474465713690135535574849762059383639118338292112","21514262377244088249371067947474465713690135535574849762059383639118338292112","6683517783593343339348692344876397332598081400376387653080810411442127355336","15102076605742283425124324842017318219912681161720665390327337228304360038287","14083955460283340099581981224537178400807166795382447529358365552937588159464","14083955460283340099581981224537178400807166795382447529358365552937588159464","3072363808626123104135925263732757024577019217365775437960336669287589130147","4377638632519605930071082139861588118558175699360749942602119950697098360678","20699157141669045943703180799190706161802312722866093672976989823452603746642"],["1382909300314684550514660104659990042039734290499402990328260059588896778917","16865453046454133130213589881274909494317023225365314090028842120075142616013","10528072213133322078790761107455354183323708288826290762990009372159713490250","3791168934124450089958690858913747300785341259292505845464091936679695132613","11145851836999276840477610966711948807176809878116430074325456032555568700770","14091468439137298875943111575441426049096412018623797180672864404054730042116","15344540738518528261251951716327105458369098229491816053580834352777716512655","15456830545363564100716183749803456569254500620577068454688360720716691110573","11340332089884283387834511422487103288926129640362642416708613676470520129098","7133619027761886046668887389507722858862660470856964701531813278560527160355","688430954961269668573891969665681419375692824582035113001760758188376803686","4426171947370343694822603567835720871959849639283544096931180997860202769489","6755597710133788757647895901538913904147948679287724305763709915357297241626","2847747194952974862085256925367617446223928724501591897277752044259668288555","7755224389760079374568895190237456877255432622247470615526024421775572855524","7328033403433696459162970888547161104216725122853016227231191050969822708063","4749398752715904105106172015438552774723609282950204174839927643361860567867","6789085992950463632268739842413711905278637341646242343309005288865287309272","4749398752715904105106172015438552774723609282950204174839927643361860567867","4156215788425759636747093326742434863185810160993903661062668474344380513075","763859577462605504386124578834556898775858384927612389627206124729510813082","3408351553220939590633577513767492409851341625763939129907145711457105147012","17156473813426332014406670777115079300425790585145946937875386851318666910766","12621532611642082606741950149448256230534900313511006071783344067228986541724","10513451104708434901459580099679585119902450963579522982849436661849543829902","13269310519429728523382692609240205042239165708947385940732513075102155702970","15983486456745198806877792842179902920274042838215859665077069048371520160801","12069103818056543880626968989746407514889251571696305134943933249502543804380","12069103818056543880626968989746407514889251571696305134943933249502543804380","8687658261529728009348064344850086483368983139999203006711873707032573521883","10821349636064773479739038238930853309148307765729340732480011072305624518648","1056641302763002188633346646887070648272321054044722682877671414544319191630","7819079110343798768837901478684492693942068156643453618690368706593602225946","18084893077625907503208023226492226349110493037511972173609241238582248341155","8091707324417171427329803504193731610332325890243579351477464182819992350682","21186074069579536274756404554022076420131660617457138398798163103920911706609","9503633369864144294537462525644044371267021413431952446618185122608821948992","17143382338783304824138336013195521956117589869665457096967798690554608144036","12846037066123748622600064339364825300961473822007048991887768804600996039742","11453385855999936693629329483728393357100304576133451562829068762804123715512","15176001317399650922776300680173967458930254759764973297650128598695713939049","6863764350067192643202230285819928486118441535816314381762689196594823896537","4481995453096285376340503528306199992586641269212825065430915839338530665162","17639525704709249515090413808713677981469932456741209293598189092216730618469","6863764350067192643202230285819928486118441535816314381762689196594823896537","2386277249810614501433183390005663837452755084482754002122189704249901613277","14597899301964249686250580386973487211422233499253195925513462267696612291751","12235444417005300214408559793116870414815991266800673021408529576680106827198","18664875200921663892832880295169707535831965580537400723339199514344973115299","10861433415390800371506928808938773808159223228361105127820384836202865224266","10861433415390800371506928808938773808159223228361105127820384836202865224266","14108512565695973999963458079278494788596956332272287477034902481993057299537","10601069608413835400822530462467408803585144782669721665922701221278255521313","10266724176965463538869156444420447541760225570502770959314115011972730188421","5626784144974866016438553079765668557568264407618443414485682981361811484607","20693717249925849315368435818693936899160462550771190540749666593985066730418","8867966729144845809850406933457984653246679979817002152246414298237926407716","21534806985386793842023973103289830492212587346684463427801290582809904322697","10237026706521522322843015640985258845063928640313195874634325604855243606779","19798552242875728087873390879228599169638765149223008811289958047000795425095","9979643901746614104533108863718863074438210323579031214280950793121324434863","6136734499962095182320437693299152285388190193079489690559209112830712912693","12360548352388267755306950524182000545879587858339038791985718079843372725745","16102278812653310466818999488946563273070468614490653719942608893229489367622","19253524386145901306382960508889529970679399812325647824421336312798859845187","21190171797815263925997505043423146285804835259697892323333504052978670215969","10238915334856490922059474430388510592216397088079441120780415057051519967748","1454370170716995025255238269923291910892115617854952391988567090841068881780","733959713156387473465377906451058734288220195890065483992701039148271538962","21190171797815263925997505043423146285804835259697892323333504052978670215969","21655040333409722474997111053312894478829575765713063661893506161674599741082","3450309260291653746309626198630685957999915157553521878184135420334319586774","10359391781217902007387387304791580699322025175541035954511910916335133329823","5212079736853461071930598638963822543101894916384769164530722040665293247014","1377581865467092849224465078717319951426885557704111298610566823367127915582","20889351762651757933257384308016651358122840744392615098579933504457876153152","3501942169217925128441908353226834503017782422464482528037020982637624251822","21433128401751455950077965651657526858596299936342788915590384505555625942337","12732560438748573079628093946370974805198356307312416865022422736717545361111","5808487802111630579120238000845215403475436326635542495958697683387327951675","13425441703633475616822514038433641800347889877286992133656462255249467830228","4751241191209241872118264514012405104350829200987040531764547182613834758610","6628097757656907665171290526368273454201711535398855790696775091964759165942","18760560019756635910515679013611307934403839739098670676436218042102963113805","15505650577802622777515704388619439661141076709489624713708127996196445513968","9091142139128901931048121930916633588835175176241920069129168903321079818836","13431464579038703899378495484665510639681486012066762113930840147952599472410","18294580249324305590253525040751836931939010985881374830363452735239078170094","3597790066034385147484872348259089014899193713641824149061073912085150483336","1775198991323843889073389807739411775482951320440242913420282718534907656268","2344678746329379299186736143728488839519663014489927494884169134127458566908","12746266786755374481977748527667478394035642967841606586774511941577021210637","5303191581414482872517298756458087252939593820564322286869180875443279582512","1005686735638838519459669201999607139496220560031428928223895588676042294312","20113910125118340926446383758716000426552005743186565647779465894281446386316","8427444425724108238803436070582668841926443760797326035136803747988135740563","20422210503573898081342736980100714602228711099519617661912274240473991225251","1322549267532569574688825813719912153059663092083297976712506389513815543652","6635951099145765283015964769692458841156488256611299819902739785529635499110","110012403651438826064163598331799098208826708626786207438273638682874496489","8230799014373800810294578749363853509098233862121474465628382397606395788883","7594686154310956884266746722581750659155617370886011171176733517902736727772","15058400429358468698324130855227043765888561337669159719566364313104840847484","19794033084053205950058550088507562536356452640567314450055320120949428421506","7758524137675453575286562857349394837516867716189815874534219290504545591862","16360394743166872481256451535971926511615110714580970354378222008183414983636","17034134847958118323459666855449988016028692382671003978174023675052069306802","15507335676394646400179189777699089078187057049481889388152930940727475117515","7565407244255166988499865080482197390354202176604423550994921436346621087567","7507089064581600269321920720674664898656091075356421753391704232677606461943","1536057984976291336724090177717571562149579287573818080678995768767862752759","5345707772733497967777950211916888704112676285018397984265380656534422481275","13775969522216753878117459953075356739963935206730914359751999125092247189618","784654183148324458077426062589182691461220285872319800168040100335725513704","20391383847419438840305433356618403957460367067527677530315104679525511316765","20391383847419438840305433356618403957460367067527677530315104679525511316765","12197588197968062737934059900571455783148553277916620146032171914429343310997","7700514229425661099384358994355637202100568182348855652967093742281740591651","14569768734530138372656308050595283416858810110015753041631657526272921272995","17969969746762679591721568589719186532890097333831113791770718775503674503276","21529114470819260629370473525908950422769629616183178518500705979382403609900","4335249490277807702159935523147272012652946826221553917127997832458798952506","7379129310516287636723823227837718553927512032954769623150792141556157137720","10861433415390800371506928808938773808159223228361105127820384836202865224266","19080309321767631415212017285167895894391800922995706861234930299975331504664","18733857421066453792415792046939003214785169838244873880779778826595084773476","7700514229425661099384358994355637202100568182348855652967093742281740591651","19364394916116155273426351410713528141735838983370878871637911760144241284051","8018971593182372943656484160482411357075730264772848961381643379651012844197","8691263349124722917145787689906164720422310309021276988527993307282532003534","3464668806764089375933401869365259300871009129454617381873230484450518228629","8428102076146088838437926540718176063241919984830545855524407549408264104980","19094213774374045790752335766064033697562921339225293193479854819279667976307","7890106720594927686649203805811027677033287950540354829926082102352128914447","14766829588815453588070055376804779477064498430747158775956763327900314220126","14757449327222155578455865755740170328279995234546066558665551937515720242230","12088243484484025990016786578437135345413689777599367373327384108488360766493","13051884772647224562301859846470628220725101982073884883844809385638103723143","7701235197702445861371199013932024727924139502848975979703304975896905453675","7635583466289988511199217549197269355506881084962404811230315189745848064619","16587019259891873754291714147514223590805001346966059832770991319167806640452","13047950049176094252215579967607614277142630343514783912012459243059699127729","3193116390170560161280254172295648867519671670691016936529665293155437388684","21316922518223062438241673717155890298709144549357487419606273338177541467176","4242274122296820486537608264314557836868637820245612247417895536112425278020","8273334388397183385158806940256417205313576389785805861716592025828958554916","11085276488715607002776440105045852255487159269686753989994534486501731425466","19712202486128076286797935931435185287015515749525871438104059132578795560481","19563394914833756990780435223254539829356100487238729674481079075120738916629","13775969522216753878117459953075356739963935206730914359751999125092247189618","842487660430118925929615457693301702865224237172370538583219347865379963153","16763046173828169201823006127648681477023335040520400592875792821177208377711","11140962441905913160319673406233783897727818930888688442634493886400329285549","18596408336915067676549116580766017746312205745605592687494145305208277724046","9185909761202119152958791333307300206010362861322444861710382056005421226979","2881804091249727215515456290876600950779468778708891030824276710365835830096","6338000241851297105020915475267471304657221884206500246308309136269391119092","7603067037105113037598904718908405320901979261870464691292286260893289977105","8493847076963447084211225972833480177159829124340651040069690763188550133818","1334489536693666664491824849753265006597208266478995249916138642910424832603","6984045404319035193995818022020461968345422449132327024218065439955060877344","20866593637127553451854082009411668241477984334166937476940320661518082903389","20881506106193145464662428466397852226917852724231232712491011035390777328289","14165780409927906515496256036019286381659924109393989904119432722661548771918","10905721262229539961123436788711254501640462068181036539647878108871905247435","20651350962129244782320168669924704997903617274251494283373145712627094825963","19452144104366591263188957016270811402926694482881731956881538567791431138500","4586691607186162657886202200934402294840355519755156340015460829346837479398","14061568194216626916122236702169777854156857311664175811516852174438940778743","19016042048447299171479853963221434265301666240170004002078393647979417370858","16835161056956487532065579593899045611249456386745698981418769328924233551871","16360394743166872481256451535971926511615110714580970354378222008183414983636","6765311266549513295335624464730559037411778262501350160205007052021160626028","19557770562683732087658567651481980734935595839102375901990848353352949054242","20540993068416129100386123693128081770742447713995694780619553029256787813827","19496734920314504359460591734706683685252839185002918920436394696698282793630","20282507657938188888139592885033224700127586591292922011130841143996911442615","2374569433528928739428835017029462139250540145375188842943277101227965338869","1499717328552894014438572297151732555848559760134612260409596992726557586099","8579078495782028646840475748633822035147077956436213321383540847226879239219","14406939183904011335010448437184937705168482073537273941019178679124644909670","6734502895131062227901645320269259880352920627233331930750408634762329597090","21335127243772181200900913979569440509947387712082158248998838032384410963716","8047737160953999489314020358800934040144512945490453008372229902992019256395","2586003640514844258041069592730332843944570559730610174027005959493874315395","13224549943522612112504257563238501993050197936473752741166169912466660914495","2619799657314651908331713031892073674134180039524647519822100930722177176268","18390191986864970628072071944166852718462497717063963828161208464381754069126","9401181095266598803347327636826117215055175961317257109910114816780119744646","7167834213858711868948369362568207394339067596188321279772508541553646665359","1184587384508135055738864356925652901018181437347967034104459999963911651193","429734307913705101748980431684500455695511778217837998765943565858022679300","19441277911239746250996721302521192146756389563985340639903822232415370177375","11208255825801525732412549293378671402780297179286107422385735623692189411649","10478955559310866616631659371703888105388775582150710413366693116978148848759","6485040206360178335556675351411058703506394415417193134399503047250557387638","18016719133588619900900871858238251150989927756432638440653227177709859025765","16814583295041980390217126110316189797325954153317770111592434297864290547837","9319389139015825033508509590600667848546727671157311193104910851200991185695","2450184547202206275046984674497007069294944076857722008951011061138132844469","21550588892261275689735801823527671608270863768453624325761422767385352721005","1044242614966334892410255201306052914997700179636829376879374940255408379731","6677468102572250777202214649133820055329960804135431896906169606179785400565","8746613889542744235970975460826530811155204274216970065454003166563700193287","4424635417831837361177025667095425151366922282181145214671327385738118210664","13432348698352174723290376556408894288486115525748664584331637425366805211685","17655662539269557138359202959715749224637177881304681211103168052209216686051","7611548627189350862472214802493459532363412736087188380165372283687235261846","10666842238305701497852160122252869236584057454580281100029330236554118565144","3248816695351530114676351741009851932494569110112879241162357111263809648159","3073099917157959938373085432172374243639266196692196690798502707158186328293","12529450374892232006582280547415540632037989311938942655209018216305343999010","19012024833812359260582972336395773624868921646797534748374147831290302049759","5288115485564563447123366736739514323032752450325685792194182675774332161719","10056936170032353973350185323292775344278856322905786221898418606673763871558","8003015342825436273061895236160251322865838011366713617494954706168277448523","1829787021882844414553409771267621205008066788492609265112925974403107146920","21321021786772087594760075080469214882590705514153669252815221458837727334220","8073219804820624771227069543367981820248740318635946600621201323707974808865","1814213926686728929681767361819171366512369936700423811755679525612387175034","3897216778361661746343499734744252759462703248465598321065890405754069292975","3887510547961364520943912242793537711281846344361921784351526480928666925476","12116263584843130075102006940722960831739067658492723699395497912594738156624","10616915521861402857123502764666981037697960315625131778844073105307577145446","5611950706516226905072057025467362883487754917983508237519214114394017034333","4583573965091669578697467571957192789036977293522008113497733144609672197575","2239227008301676887963698793394960288426723825252208732096815173283298894578","12120020354469771062285113226968645130202756821901307319393832736961787731961","7655501015553462191559608370747577321509921557118994610461636848063736153564","13551975197478948299965856238988128473816041982439454652156549841574359020345","15294998768487201578152285270888103148903347371076242362567304461971316463560","14712562992261420683972725514848021103245106364414633508541244148752152307429","4818033287079051846056937680884519832472266996229660822880063568503353775536","15979858630136663602832743242688707081281113754057206223398119753168394893494","902800743938591513429383952377362828666185232071262274285027354175899841643","19493607751317534660462627393934046987545632857407686950149093821933421053326","2184792572119005735071785579944955128293660082100069748259639753519378171786","7367125626397132614413676026832068193704828461955950293571565202286310159411","19983670578153845232002898622856875080853749002069746366306607383003483134120","18755543005634632690643175075431932801297037030587968099305668097423439114175","20168676120841270265784930710964604593207117442194812546956701789058378983045","15737501633370717627322566627715893955366822889266357634579639107174209579479","15648081025463068619960153848782785053847443979691651007257684102886590737813","2726816514719377964241192802164898030812579474932909231375091000484044920015","11940384422772788913895896953581558640329102405731680494132195849092673683575","5792454328670871646178251744757582802464063466579998628203811049394998444858","5690381624420623704026586060561513617259936701711360031155891288354403534938","6536191390600577081191252720748470160536266645432103949153838404275955481874","4029209877900819022718278098859600250672982750788097050081860324776458316626","8987544202971942616709404582422439359722869124311165367076477234623983702103","4431353864123846048464243648431814976882090639438066732217138169733343779784","8848620016756482665985922589061924137764995351915360087767950623666558407361","7392743747020885839682337849401713058176251928147266910865472853157887401683","21574252723913918658935129023290342258707552917069952740469991242764552905727","20574829202822309070930891520921215254246417379815583321438907927579802070213","19253524386145901306382960508889529970679399812325647824421336312798859845187","10404884026041592645419433645759124442328021287777942786756199893816761693232","3068781801471335275865627778476584063890415754739795620016342735838806111692","21573886605023598622586147005405125246752701434853256546002635744999285974286","15084322672425344148979449354439710436859819176604521523105547521090291514340","3034444925972414056250697077298642685468362894226859264283958706830256290152","18510122895499560577484520811942139880407015219930734249122338767084735025889","4789183684394553328681475811278928149270575346493444288616730079943445910843","446279489260433195287234627132416935077314633200421129375861901583549808117","7273755687784011205754658383950319890744036557507116563512465041691210213374","17367177540462025887845334579171755780309525024654982142492028110441359529251","8755159098462183647212099687992271788306481989091871265584834029979501089158","15799711910949113577018163075863673599182201409648074310375897150424523333507","18972272856253425355785173449518375488167114587722913280981039998324616986834","13427998023655236140171307935240311969309940771224307570813732942556836469936","6844940444332228101982909362465720934195641525692100700480890636202283327209","827144581169991586144502626093310652991649777241790090374179747391037947648","7833881139213869089717535963001219184869839181052340311928170786067270728256","7630550688247435766689683822009645097325047500643625418478408624454899250225","9854542602731857930188782654959516918488049639743228030564878321270925914757","3316316261774047102127270891529930443633776759500032776964247529470178920473","293219090847332584999033042299115672733744917520315832079027912960576204015","2784752188600607018284679849979947346270850482547305914105303272955483964053","1760115433826629060080039085764265592288638575108531878685708598713079401738","6517689595862844215143773944429046196852840476486830843286317056392178362079","9561806873475459575519609688391350415738725000394111602987658636279761210293","10036727053186227877808643200052618590162585643650854185596744122116500996167","4382282946657833550169380567410340742964883787028600827332177590619598238135","21835017368008491901032474562173952272668565639866388026854702882162032802448","15344540738518528261251951716327105458369098229491816053580834352777716512655","21404678866894007357850105480965838927229065425672158221956134805147520731379","7883782001959912190798385747879806907692000937010527580001090437923288278535","1226916723778166043905363433591882216298047196862425479646391803511317874691","19716235393212191379811181228040888376550715482608359324958105769509089835133","20846656120345425082178006402525054413979990684854892442647685113448656911348","4080986431421031958014228930834804728895618580533534117090233204581602630815","6045412305567530468583226481448277742357214921719215191390004949814580018776","6693008821864650840343011311612097411185304069662961023037781456903161491041","18596408336915067676549116580766017746312205745605592687494145305208277724046","11230481360519503672537143713093131212812982937706801703329835734274579996107","7643321554075203473621904165907367698422661001854376633261977249943346036640","3663593785101027693667704015087939516357628854407362757549659973641482457097","20354883550643909897833045650839122941680631394821194671465457225398347308405","12400561027666741413257732922783561881991936779689388475137488752228531147000","20470775227781408139476602918486573618876787923655098109262926325253864075952","5941665261426117070191783565129372194295491085927268813960445264911938226270","14876384651277926605236816593490150131042586363933713873358941864738299600284","17954840592186723432940942008617591488252936660692730916385385538624936334568","9462748242891416597524164574813163662469757435244487383062231354512353615314","6717409207007869946825061782562927057730288994682165283370077370310617292230","11229510654390863688703180497268342272420662608939050914046021327826617666702","4003385736357850866138274270606257584139890361791534512037420150590533822727","15382952795392352678587637926840915460680254264401134745595830677369266766825","5525822255633530881277775558027056536545359014436357570987907491370469847924","12752347891217525183763887717525040743786381498972396894094945613446189522711","768185845756901846510524400240203726770925221052420132645787952472279890992","4815284876881087809266815198451488963906489449708621192558819277679803561086","2820856753521497979886679601699484232471684577369922382381703805153259074856","84936924484458032312976710089266793972819869282325928390432560188848079384","18317472050147505533118235803591342619533895728415135311865977705801397727626","4144142040285992734934865018631294241718776952852871406436834020215626068417","19230122765848242560473528642479049852814222277445342387911976647610202983698","21316922518223062438241673717155890298709144549357487419606273338177541467176","20889351762651757933257384308016651358122840744392615098579933504457876153152","520272136526015843892981133255974050318199656825888157141153867620833814327","14710849532427398462627087503437013363896843763814052744644905290246436691635","20357509721583585960792787335660059651957084639079599353306526228060760272143","2049563345401975671874858481770386007746145843178850198001380660584941981012","18040166687806335928430420743431822157843386703166768910022683666850905844393","4521333817412359123195688219298975442044629660876654242453558351136165623290","20486294011883974522252344687453164682658466333527439432097585769579170313607","12848486620531703674340734119316015089519737328910829756575728273417994431864","1557329560179278933103354466862064505180160194072566691709213360314881660158","7530023922070118192366091402595906656429595917187092175776976025884888191683","4213956357719193247955211556926324711378461127603645683976278994357916657040","11575920739677172187722313889288612403827570198538707757106813300705935659310","1006624615698116452104636027011737811416025828576816498998991720217956601659","10685908445599553931612819748089921558028123157386889026166604932199913261181","14002556860189898824243437147657146116950269507124177898366127398062256906995","5012559730949824532344170609670312796597763087497534968398792233890777394204","13139328334133582075878400251828233322926618256655164951574499261082650515297","6073592560011640885570142415814061704538358579398924846259015492162514954077","7936025115775828711924721814383242023589490090204037913586772030672619638340","19060639160059520908777232412112364725680228768757659624622156149186720911649","8882584160887267024111211852504670848213334687882388364659444145767609968005","11926272482342288955078909284302819038126779300615955410866015296101286617579","7235871700407120472705160344898959149952435849925583726225791019506133488677","1684458755764517563142680967777736447703086359060040897711922653591520828013","10191866543587021378023321400874942527791899378379063698309954676788730516981","14087164218961687089850174568463507683699722385223254212146145501554265601033","7235337360939836124386640208063087857566514765622308040469392368414787129699","4203950811107956867353452693332135139254705389955331880243317889277411835142","18855693667250539722712921391175098248903062316425167488525881614803141035093","17438599543456557336570153621107573392696765098999362930574405279734463579549","6967130176160687583989105133894407708771938687936386098272698981930647987992","3333424401697717570405896203613131167988025281015844326579828668597721966280","9242926362373149448563759381405677174177438930289940512392011096099645832216","13323844345003724686536425406591379073705371033708501568312286495913527963192","8597447858476207344743975443056105985149218690210170804807772199058129822494","13654105543076104093933588626469478479071231731579775565848565509678357253511","16814177045169878820937055682078679039627903311486293907818659970715251112443","8128093998682262379382394455040288264726824532854319429591960481110025029365","5609407497344131732298641258350391227377693340676055106802964044788941074065","17341443014645205928540709222003365783460686769783909650004087411896409735685","15516131541833762342004326781349748154842853504647908367232191250295622907302"],["18384032038292150077043079812759802184445840660168092802003360821404564896274","16325882574385924781495629428377624196386630340779401255119848914519930943732","13416366930622199851439037946639090540575533814312274849798418114370699044542","15058086162823469682116762250372415103215206021417652887231180616939113009221","7923617720219524770449631379288334321512664029066135545873333783379508378850","8024924939070771215620155928849078253635865943602490253459125559637323602483","13266018768768611023881533592573714095676161199540489525952373209974357063756","18326590944021661474615546938995000138039145949346782032708031583307470697235","10002310535577049902588329701221234979696292413827210092465015147561937833624","14855442070085102148200337039488440345046255314661129749221833009541975455388","14519680339916248619274972947470611884417356845443004804481629643518482844660","16821634940549496291396403064444379331840575914165330590921127701207416677793","14441640212183109756400805052850326531435616155349441110109726915503816069913","5795785987239598339193800784862032870112858979685701482034764844198903373932","12155258418702501460394135554845638082567730184080505045904154928142559042805","16470938625498195099245127182115513505542673242065191727011341533551589932120","6552485115415139991780737147533488714420399911498522851243544690287568050854","3499501536132367486979225185265103378327341337846288170460666099900974964000","9770716999366241099159089645959997952954598064128528446693737636859504751016","19876352100531213713544522543679582200497927745460418464286172609083646582341","10532722989371014908077632637279512400957014112515377562683268815622398375436","11917260139803353116385985587728375546514953002209742236265241937334108262545","13384104269737410331772563190580099096203271549612196330873385418846206110270","14260280837288626694499442913438841241535343297672602001491326280205082389946","7330306258955750126796806132743064359693656869945256503428053776674980632245","9264532752338037754930840153552682128062711711806380472480921196264152720944","3138126445419179378377839182802386134441847521872742588830098964309706344534","4405181389859697930777966176000681729547326095195284728224597222651357206416","10324316528666105900749217560339220933945442075154488347649461550626045154329","16374807748849963415787185300356345071013261043884012189729907803234186353844","11709205410140661045764743844620328841132600407789695282959912302647013414938","14601851501799208669011093217659794094660922535576106557310721848925230824876","5867436775637977628041284466487782378842964431752987221151837124780626434439","10766878702503811477530878606368110214218572098530047472839365958505472365383","8057200332098947089752368327316089733126809323927322932785761174677646898383","18208221044214436954131874887061831272511079186985447727588930670426908892795","18528522789503193107205556307830846783900703305947426131143149791759676406655","18873369675845033562284195967941755033899167002834629241626114164382941288663","17616349284102443234542780093544052162646402852139142458635416104588989890866","13424904079054277064712241317835866410239308877862362175537571385990741882411","20179165101842273384425822216667176798563313446567963380770489413607439092386","9427815937537279662397774604846902854274989069553263582149403702487462958300","19061685898155117592080712889129273883994531745596834439977710132631239723841","16218724317721373050219374149020092405445680979103810950755574064655949239051","5403972728585442118666196832549680876294442998423301660497812960121420313183","16829104519293805516537107005510779568457609726698917067540513510626384406596","10104030006645721507095246205718494065645254962641990587594807108526084948055","13298465221336901638521338523951279119132444872593133865208129007393673600801","10652619884570376392196985970354132875411351116305121902400559642615564625991","5208806579327576311931664205858344579600458926480138273261568256398399294134","3007138054035796541849269720744095652066974534800018385309717159558949332587","12432842778981495179718257006383042651081685881785736279108604866228249760401","2668118905120918036753350101769544778699775175033777540668640190958303542138","18319012442941527298831481807544132305811672211908374769784639450675803894830","20953944559860739843433263040653481667200521100146477903323736396069161785012","12325703224780857205890017187303606721181336676832447743060830051562165273939","17437143219637216176538010357356008827372303914003543608791309919842075506135","14760028880083887999375686477572239002214449525245574148206566606816447827816","13741552358591019167895655670956902381867810292512003600604023883051115945421","9230335158272215920455097001284945878911541675175967480967639981693682602246","9783214687942085433351875353082959692077550390160440743303231840921787344002","10986858647908792329441551774746335911126389073360236036656339560202405831118","8208008680735509417236855599439006360754473382362775108148469874728843967527","12646740905789121643778993480930012806528791550532566322872551336244896817931","3979888817646524834873790814704132285199214691217215475648512054098415563776","7527865720847030223471941917779407843617854470750730748673321366823835225846","4838404308941283873638424501524343682283119567018269066688901040497763949981","9853897427495169847924268149735903779398426247559251475807073361967839094151","14739856449980291300825509951707163416133512274432094217812660371746519712600","4546100539902846936728765257693891065740788680828543483216583685415743828962","2136460200336936983117355754239255978870565858402539940350546486275644268456","1008112715846859724518708276303354671794718321191327567994690064187501161356","15765308926278609172584330609507393830638124917415800304736898299260562152864","3018720362996847550702266698932247086668073727985640512853521670723705359949","8723172838229612819388086818096920212909282527742863252240380541492928174902","7457949172183459588013562825321127540937577076723570765619539232461295338736","3381431725816742737615107066100819852162947649712462351092730400590890624290","49144348904366909592701486426686961049327398558465706724593331648478698053","14639712910812705795970520675611363850780096565001104429636304938634856036847","2601519403313770180318105620248150411780859889886974354927432426275210880095","21254586116845877015535165569052908202054466762190305551654696792544707133525","16967017416839287841232060612111303743192906273165853308987692097726045455505","8190066270860398937263370732652489059569519190125350556713497852791974525532","5592293430236174364643553475569702365795345043310633591962604933425408999460","19601437190468004106730947681747085027690493864893190458981733233927057690805","6620018289808350327303731192825679260379214786891234062432290320682927345661","1780222248649115664018219448468728983969642678381269593772010730578328677193","15380493049946421225502136172274578140501433487849916454671419736137410231028","12103892658187084215790091286416424813690935257608728680621415102995134060115","10558417632996594946816675174595536967833565216701337725998908796240567714712","2134008593159414265057092241480666663811142692170192390104958476838747307993","4089491030743108022423697251878450787267866898437511079898929685081330075857","474842523391530027517304577292394062295591974088904680434939180702762867081","14452760512439157106414202939699908128658735188698359512006961019905017303459","13223319127828660252332142774746345011495946998138174657797707291757423705569","9457789233665205732571935484275188426754140621151181997242793587502910648627","20848046269460145063875767690814244080952745011280004026656585246114900785324","19256126083028190953702604245883359187321336872868567645006990589004824363520","9226069499318872418902722338506406516747365737616643680963562974842201151529","16033229560294034852675287481690972597942932781321447921785602687969449970492","6130378426207134229087801512130083435977907404961421040611831844088974017928","16104117786239846811883533806186798263220919875925721975035743655501499791621","8825748403416377673087183179532034314124491385515691111830087422061399276160","13263985747598815694084258815109721543894287523724370006203206984256488355059","3585217303845020318509747636569576103673388781605749257157545035392053526863","5938687707979782528878913909067026826858175776649790189121315129948371639570","3323263177006417005845961752458498086037113986026637926633026730393183345857","20270406634272270936776711127703930477091501397256225393370840232060130302545","6543429523032456378585178569874581565099744282616928821457420584194169803419","3233281004879158251311577968180184655619246635054449383647259345177712497988","363565590753963667209249407165447454908673901377295746492250939931100313315","7506253673747665029661083455386128881649663169214338117881665129161275977472","21501416647259433612904250026131872816756552641528241450544572991305775465077","17895466608996124829093706345177152831539318075612517818909877837550123414568","11706345156711469440514332252133949588293758413665684503365711677827546899384","21646338016928453265433097417574905318028705529333672542449188607326513597551","2689104638494668934585838991135719332967195890709797676820705849669757648003","16485392636929490766185641715629823413447036038073162457648778917841038859821","13782651643019363494667775649301536573507910420065962322411846208355600799679","5195012591304124285901135231774748360027420593162488905374878491031324176319","7118767702043285212291495163196889014521721655954221865388364725680113095254","18670112287793884237359689840825778925230528198624475823861335053115750615572","14359715931740481308091353128013725596040416546422732610756973486160386858747","3628572300914164447620668972833537682928927543353213786463936727033410420447","7947262094870320527558883059188914096345832732113391742537615634285431351580","21513989914278359943955181047660381959548808231770390037115619536785603764813","5274991987793145661340456560833083078151822667538287540881513163864602830824","15952442208511247731939760640664847924025437355449585144407947110938036031224","8054355825251675596128613105994435299170405607654040479208209273583830334615","4141291648952488846855669827222412820905487704035649033611808235001918239066","2689741920903523375222731031969155524411288268704612339949332466071129794650","8086151006240637465173649751984841388014752198789633468224719735747637973496","9597357294614791996963716784980063275166351555205511764659979558219033844951","455728372548615725117581818479577437366893008905682821849695802826327817136","4518227905939152051851931692474300566313723931916408242758915166643824301721","5347562222438219277689117821474326629446605611209079051698252183001230082845","341305939794696338199472144714919453881506186578486117160183665785781815596","14022990240210962138750526862341090680818919836109554981300822385989587968625","19890389029298661828627014014352271527716811030108238468628236499594914351864","12535394257071218822931052158791181886996817055470535346191920674455184099959","3288183093560533276923586884406146232604228753772007292522576198300435028053","18058420529079911649974865887220955010646357204370123589257769735406809403871","6215342907235484630780194529641761066097927261623458820400359964650182306142","20013410979010188775474974001270192502182566826138213084778656382211144659395","738331644220692613128292872827919008177478305457718481241107999170945982637","11198044889868190411836703889269053826586176665718226871536894099131802218440","10250768597155281656742522476648741106895077479095354016327517384866840787238","12908325472650869505247620098125628274463366124860601318018187413793783634030","19365978351181800595017340731689353207632851633188653214392806423983262181249","16195373166980530927149471555277210932433796816068912042180466378776046482481","4597536171261156422733865589134101402145652037131585973320419279659113898917","8155412211220688777314240062201052596969850884196104955999807193131312562550","9658737950685283138514841347340207925087629190823191299092635311684388721054","11371403928899847156874417284224369063676528407634222575043749730331054163660","18430554412462372425706816737183354543344289846327879673783830485039791439640","15533818957130870262746117602759610630790500979594961683703765232076592161911","12439459027637579441970707614776192307788221084262876607008705183622082840669","2229865678106983000702208407760796526933685566992480293944610515861880757054","8505031917454026396607372046063671635221360948238988435124339553817016289904","15463310343885191782900375919854553857191277641175750014158939916134118790616","179676189564162313155654624581858557630757650695956792963101983875692347734","8443128047628545047154983586330476562670943862721545392245241438315883500116","610960284254024364572653418311804805594631005025565649370457915577656991151","218287346026329766516240293068796451059652400837126266113580115509890877649","2906996416207967374989020633296836792559663376245811771556829684200290385382","19757853649794230508560408683375818801490911907828251932461286957620446303419","2276922224980026170767449957587563332111349997749009769765830146283987011972","12837448335884946100072770099662774960754768340806388679295836038501164621237","12656965682932778834962863095985778968224768726495677200957580652526959932181","12186153456138841848291500311013408644078475678038087848950015649806005411750","10946554504905859453162779105357303956219573771252934688374370789243663713337","21447953102956131056155859412709906739482075457284667312365536072239937053008","7145784142079955619668047044439186889741046024672876193495080485538608342115","19372619369667956985453522400459440869817251406556548704525881633977903414264","6423007082192922385628784876189035184770751533619928392210795966275060115249","21751053701945701703445759488960377015111518935503177857617917473694884334768","19202849108183913555467651329891608290530211192255054815989689706835310213532","13997837036678319179984929630922439182411647532495204418671186170902279331118","16829097896096304949699436007150626648006684412208553824901796324209424485605","20621795603248217280600380486257719077088234877880264211050164963331488959250"],["6756114585610354761994934123573590576031323775210670465921545589395692279716","685191805930054500210841971125967995877979358720331850626217363072910756238","9485662350160415224025363220111439348217095388873727340068428730377533770959","8115934108672428538235894491316073779388187915976804800386071626580618070915","1282508149730804358259895843758618366334960451924642746120418205193280714282","14179929979396096962395240181765026599552585980602337930539087878482563881187","4630422650153373691911867673260637173668211109639293196215264833825729016660","10664506554530343425557903484323865229404997105188758567904028571047793109248","12569438343158704372525852505429455301932541035205922269054663733092483725621","18075860840134992364887712277090525249125713130048026670551667857590168044150","6154991657198404258201588923691634848774295729280659387098858590789010236064","14267908181765464619205083271860485800477876457408395390823122500237409911737","1102237330720002658746639905876906968800131682764009204285626254596891383598","3547513439323180749941893576961937199337710223298003162954767555412201105289","17706829367463425674365471065546223022066926421732799330617953029040009197574","14405032177257175965480008310933238307085070634890282839670257486387454638605","16150459780007919237643438892079052117763088991594286968912778217743749808724","2041308333839704877999861231353793715663233333148936348109644601796263051936","10654557998403524327322658542343205170576622485966722206668986107340289125553","15683345341223077004250466708177856656605869466419149111318066499485004515039","4851847053678110074411475159892125366925656125386711725559823281575831998113","18468500486206418044567068425481273509318951875399172221446094558099724378229","17781216556850064574572992323382751246594282925932203203966506418741013828433","9215399204052643176708395537776458573497981057708371425080636733118487394766","10352889153408692659497401017062727478300472546379169920987419166613028928401","16544364189783571168353046347334355504283451801394748031957552329067069885451","19513626346064415270953530785284640989160185636547088851444186393536505956312","21507789966598090728129644266951402899183665545376746784680322546289064408616","3777804281092943005032440075760528256147946773339033228254443365126142848562","10034317871377674726894524743197379547884742384429651862887716826064149312613","18652802413339511201490496342756311260043848093866374322617093089214261852450","88491666381245276840478840222868477550275567272781244591188834546520629627","1837932609622673736634628901940252182624661465000166397967561746138352623495","16516366185503776777940711260237238136458003480516798314997133506063998837111","16899609976636187174992898619878846185197383397828911518858667987132204639099","4186285980460190597450013609340096545201499190740171026141389796508417050424","21295162547103756171238117597387318409890542008978911074437257458735931383796","20723397660109909759042149741566330304393031705439793412647416993880040354920","7231866950204206960643050602520483342924652214000921537045914300685454680510","3760367901906958741846998063936997993497919841116582222041657691009610308522","21272553511847456527390995915929270080804300991687252088083217041772303457586","223237306077976162665730232209562439022889369156897703167612669100979874781","19628152733376574321793493284716541207663030370528428079187599342408584237192","13389987443808046793436430491567860935193509236695022762073582676216463554308","20360812436001559907815520397353643874559607440966576854756414267324078761037","15764819614547669146707355992729826377312128051301306106121037886033568183838","16835075289920998810430426808456760333446952739301425141083773401515217532573","13912890945390552574396850085878260976858591710885633113444908468936710991007","3850620678967898589201560992311719484024187266294906542073936013250724028096","19853371021394313509499830210672521966725323412870396472054324737749910207443","11509853509628594777439786332061286841028434645754675732122543253477477055296","17515822441017561568820747229557791712361972423438421729429247961554778670562","1210125116291243217712379936619824242165056827587223502824653537675654869390","909650008326137352515749482999054968607700881621835246824178441637383491816","10647553605168383420665946502370697150842138719420648352515809831449000197561","14764198424882276086028846685114284931456180610295007906614574313245680130542","10116477001565822169361919501941057608221929354578980975301498956624792029478","3964423669613819656260197337633994400192254312384970939923716745271807937544","5598482843782625471816274821456366597935221934401595126755148817161765161175","17493745343176744217837696499235497049262623813671047624759094328393853441068","4006835118446300700946092814622697753260928289052061092598601676597752550098","11938307456721015004183095076201563029810330352254231898731325062643433735448","1925515057079562420247762166659644013982556650430554914025921604194611316743","6779742589079560513449237259609895653061404119973688943293267221248242230452","10722131070799688224747057607024789566204303157768342262589908692685202069649","889093799700285251267346726461032208181788268649681273496088259134885694729","9240394747451885131248401610748434840814449491707697525262413356015165745733","2297215971919575895468640126325400543944089305711976684633626196706221640537","6236769500636403719285983002400940040500429703077351533992378525735951931020","15258316635161904779871049636948950620087009567741990433563557658928635645358","13291753096753699715216601612962869714044130162352331162153336136407418418781","19161728207054244981211252063287219352618863551880810806761867024228422426040","10877442832509123955563284194460473415229089143061993788351408998368066310817","19960704352098851578795906897214223128575953737466324084647573491402086746789","12755962008331072277402540243767149411866842102200186746357676045182982402980","14985095391897672417562163964533149738636373339868161057918780719047354333899","8307331788952511669335326696241965168168509613121554960714843860160766043960","19873272963237015189166680262603989144445259644678228670214998706360475857499","3079013875932985903113922322719671338817143568956981241203729763662183356826","9754597481956551670311450377239180092924054222127588590405698617629988725462","18451426140986419722975298625822096261792440604420291947697287288831849140214","6824138091930367441155411707904584130554412122966950035350189242759120955099","16016939788531971692256077055785793668857676188147968523985994765440603189270","15616157455822099597198469152885184272886809581087964248375694768806525246193","1492225973446126497877107879518778332534564801831881469724932844954744356801","7834919872630768323517082525598572486635886706587960474883056897603323224534","10318006338377576657566017561585099599119266726228507980922072334750592897924","17397010582793628775343634023832627132936580606676401668158874890206422969719","200578453217739826947942162540369310405531669234082931261810840192703265389","14714355164542725609896331053934773110812186296614906037432861262123940112031"],["17827633571109569967775499210514690659277484023823691263273779279684768456528","2563605807293253518346650080134711177642026228384442720436530504312444442085","15482914276295460587126253799274168210112767020512554885602160649059017798904","18837539802427918025916913400427445965450628436038763148320136593202231548045","19692806483217534756251487603737509111672972578157429708350628863638099796673","15232424111483870181301575712432512895338847871052747179516732164790804965002","14998282717802988553910391897550216264062258184411977568460566222614218997150","5663662771858440666331734403945661270410321085684118379146932308968759495242","395522778123506133789876136432747277274384149272696963353232675185483844096","12318672477572207655048490218550991674814591812149313800868456883454718051367","16538699449567321405284247733926255556898981929799649219582772086617933112066","18122470362843548120999236080375647215009075099540978219668094830100393815637","11337105103106851807357350667201187361532365241489997721531901295557578024393","16282443095350890748643674435165702579022932755225361838248903702964648691977","21432590535213580890814537665214255792392339432585171678757934450691655530344","18334365960628687555458386553005156185366628370295393310232735350003844912114","12567253753335859808702843492397797739364492810403345067785232575822995520318","17829276260692821281472107340135517420678366621986429906640643456703298175679","9768396440049498160863586957006249097053393587267195596145625976572627620193","4982005008617813627756274776734956519917828384044773981246694967469248238192","10270666958505465739145760070231304367957650983691933410688259120696007405169","1156722246444992850890909171089904173836516424637972542857987142445352866311","8937409857590388700173226067264590075482046909037264985485570640946648025605","20215648907120535783800996566504354659423661069734351949929880138209130719535","2053647660997537606889633375563186563496877058453246217363404836792554331932","19289310232147597998893477571249345925615191655772642449111808331202278985163","10678569019513338569661517696488498851504085786602818290662279573166611328642","8509181421630262598061386673724261194143830216031954747177853456047926865427","21385417481935151101806521352817190341276744113588804740429890839081824850925","9523124565982940197060708786199918383843772051999820137534246430047363579402","10891610312738486546159687201961250165148811617104967778915787556793612269414","9545401729281049029927962550789413593721509126531981032153077306820702902365","10674272906056676744732639184022232386846796378044543075778863830989437365521","11205154865282062873295328588599915602011505288434165564114092926030607714934","18322500364502348232400650886167167798638507754195403166115296043906784536934","14231496365073456594114713737890332228029969732219095490560427316359369280944","2888047037468598660371056478074693829877909182765224115125156184568666210498","7163013250514362467393319873323546352275910589930937235699092227656044868961","1593207912361988299050006994150494232024738257671390780460997598539464318353","13808781783035822229735983289694154498964482059618886179620405409710989418069","2437054867506332789089292166868242367084736959262955104198886152793773359384","7069525825482271036029370799629059680123165849421292807642118009516436614035","19933365432684182676548786913460179079372672793617974098669668894257667487522","8923743917291280452636740975413705158495915517046457788296426616256590611853","13407409818930759215375135429865673116224062164789562023529225992389928131334"],["4349651554659314350557007739141733916947588605575081028775988755625575820448","5730490506571511878663916234098745643248581723305574947202193759976328865864","4084853101362693778722181243065503055163858779980362242589509281305151188458","11417859344088594278487324574956963201127156654900353789529354422518156015551","15287670059434452022476809921492512551073374335852064416656578823294505404114","8764079452866898429966808314931563970636386655421968393988002044172819834839","1334938584524992735936541904834563879690496455303393989043655073331201660312","4967891983826992726060385606061809825544451715035430120054810298381873010679","4390214269477270870946780513192175690419339382841054131166162227716960621816","14855055515856458753048222950354515646347032381911916925871439011642042466988","2786263645858265160825962235413908944162239371234480849052420616636609451574","11647322075319860288284084201143951417296866214783564756116156419047403259772","7985635234262780253759524136671108435477787540895600957214766832959740161516","91099139798114198526124310949032729897839308956443131818219781407352838697","1566633110456135216172743910336712698479507033592430962397668903430098732806","8302446159081153644080301809261122148761621217477482390012716370590776302369","6144986359439165004920957805632735515690678653178570150966983723380880550093","6207972168913321711138708030927581551648422663701064210875919038459874189295","334735597781062478333243793954370236912894625263014929659966481505637466493","5227827248339109599518011176916875007306081135902721792155441873510379786961","10157874106687354840076781820183016144923679181688908618509364616980383583322","9939824194882814927366009549474526935733744513575447578209714642137125695580","14135596781652702873643994368842704265751754002201740220407579301679860045391"],["2489137073047841221028453992902882278466490530428462498844984793962057603682","7961663283643806968573894688281333105896941161374635862250453484546999045532","10902039708828631085175169457843022572142797721993788685123723176032387976262","18789238561149372226932556500112346977254135090735982558822578929242625727298","5598652880754413764975842064968382265897861229695650388794537610707407243812","8746126366119358728462744568513704788151273183338794905587358690555086852145","19471191820073583237924434491737432279499603093210421912688437818081179057030","10679333379123331968739184662657624670854306741822868872277551048053654876484","5568989700275538741003489202268015747329596471433121629555697906553156448990","3771165620807304809316809935468171197098997594980139350840469091432429414181","9967386820007714076193345803593646460449560328161535748979491510203911402353","18823150653751325274074213652964451315088900018625505074964907991328989941695"],["12625854858591244015703410082258181194465150277707030047831761078054354835742","13986003123484105601188074828925938211590248429518403103955275271837674593039","3558888383317394732201652780333465283108168659641175250257219411606657767946","7700786125650112764182113532122537174173073521111117563950452052490265627960","7579515344887337441074186906508200066208505318921088212490643859904780290518","9892768514825076234919699074918396299621160467708043207918213591851329761254"],["14210396003944592838505840727936498996774563492885655129744037203711071519842","2343555844248207151804287265535675004312305658635500826654212476062778011969","8751500204006532900295191989057368833262701815879890267175442971128121712698"],["20780680337852547311701282554071370452317057141013761689548839991734323516","20789533753311768133313005352607515650095008797140565961764339383448909259213"],["14372655903209583494481911339418746339944939756718595536206203655907521070372"],["4859151098366534854131598791869577323397252056347166579016991027044914938660"],["15919709321603172098065421884373763810486807864115065485593064241236655294707"]] \ No newline at end of file diff --git a/common/src/constants/constants.ts b/common/src/constants/constants.ts index aa2f0d23..b419eca0 100644 --- a/common/src/constants/constants.ts +++ b/common/src/constants/constants.ts @@ -121,12 +121,12 @@ export const circuitToSelectorMode = { export const MAX_DATAHASHES_LEN = 320; // max formatted and concatenated datagroup hashes length in bytes export const n_dsc = 64; export const n_dsc_3072 = 96; -export const n_dsc_4096 = 64; +export const n_dsc_4096 = 120; export const k_dsc = 32; export const k_dsc_3072 = 32; //48; -export const k_dsc_4096 = 64; -export const n_csca = 64; -export const k_csca = 64; +export const k_dsc_4096 = 35; +export const n_csca = 120; +export const k_csca = 35; export const n_dsc_ecdsa = 64; export const k_dsc_ecdsa = 4; export const max_cert_bytes = 1664; diff --git a/common/src/utils/csca.ts b/common/src/utils/csca.ts index 8f894983..fef45c5b 100644 --- a/common/src/utils/csca.ts +++ b/common/src/utils/csca.ts @@ -76,6 +76,7 @@ export function generateCircuitInputsDSC( let dsc_messagePaddedLen; [dsc_message_padded, dsc_messagePaddedLen] = shaPad(dscTbsCertUint8Array, max_cert_bytes); + console.log("signatureAlgorithm: ", signatureAlgorithm); const { n, k } = getNAndK(signatureAlgorithm); const dscSignature = dscCert.signature; const encryptedDigest = Array.from(forge.util.createBuffer(dscSignature).getBytes(), (char) =>