From: vishwakftw Date: Tue, 26 Mar 2019 14:49:58 +0000 (-0700) Subject: Introduce SobolEngine (#10505) X-Git-Tag: accepted/tizen/6.5/unified/20211028.231830~629 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5e462a3ed6ec88a022e1ab4d60f9e2282e96ec44;p=platform%2Fupstream%2Fpytorch.git Introduce SobolEngine (#10505) Summary: `SobolEngine` is a quasi-random sampler used to sample points evenly between [0,1]. Here we use direction numbers to generate these samples. The maximum supported dimension for the sampler is 1111. Documentation has been added, tests have been added based on Balandat 's references. The implementation is an optimized / tensor-ized implementation of Balandat 's implementation in Cython as provided in #9332. This closes #9332 . cc: soumith Balandat Pull Request resolved: https://github.com/pytorch/pytorch/pull/10505 Reviewed By: zou3519 Differential Revision: D9330179 Pulled By: ezyang fbshipit-source-id: 01d5588e765b33b06febe99348f14d1e7fe8e55d --- diff --git a/aten/src/ATen/native/SobolEngineOps.cpp b/aten/src/ATen/native/SobolEngineOps.cpp new file mode 100644 index 0000000..1e0af21 --- /dev/null +++ b/aten/src/ATen/native/SobolEngineOps.cpp @@ -0,0 +1,159 @@ +#include +#include +#include + +#include + +#include + +namespace at { +namespace native { + +/// This is the core function to draw samples from a `SobolEngine` given +/// its state variables (`sobolstate` and `quasi`). `dimension` can be +/// inferred from `sobolstate`, but choosing to pass it explicitly to avoid +/// an extra operation to obtain the size of the first dimension of +/// `sobolstate`. +std::tuple _sobol_engine_draw(const Tensor& quasi, int64_t n, const Tensor& sobolstate, + int64_t dimension, int64_t num_generated, optional dtype) { + AT_CHECK(sobolstate.dtype() == at::kLong, + "sobolstate needs to be of type ", at::kLong); + AT_CHECK(quasi.dtype() == at::kLong, + "quasi needs to be of type ", at::kLong); + + Tensor wquasi = quasi.clone(); + auto result_dtype = dtype.has_value() ? dtype.value() : at::kFloat; + Tensor result = at::empty({n, dimension}, sobolstate.options().dtype(result_dtype)); + + AT_DISPATCH_FLOATING_TYPES(result_dtype, "_sobol_engine_draw", [&]() -> void { + // We deal with `data` and `strides` due to performance issues. + int64_t l; + int64_t* wquasi_data = wquasi.data(); + int64_t* sobolstate_data = sobolstate.data(); + scalar_t* result_data = result.data(); + + int64_t wquasi_stride = wquasi.stride(0); + int64_t sobolstate_row_stride = sobolstate.stride(0), sobolstate_col_stride = sobolstate.stride(1); + int64_t result_row_stride = result.stride(0), result_col_stride = result.stride(1); + + for (int64_t i = 0; i < n; i++, num_generated++) { + l = rightmost_zero(num_generated); + for (int64_t j = 0; j < dimension; j++) { + wquasi_data[j * wquasi_stride] ^= sobolstate_data[j * sobolstate_row_stride + l * sobolstate_col_stride]; + result_data[i * result_row_stride + j * result_col_stride] = wquasi_data[j * wquasi_stride]; + } + } + }); + + result.mul_(RECIPD); + return std::tuple(result, wquasi); +} + +/// This is the core function to fast-forward a `SobolEngine` given +/// its state variables (`sobolstate` and `quasi`). `dimension` can be +/// inferred from `sobolstate`, but is passed as an argument for the same reasons +/// specified above. +Tensor& _sobol_engine_ff_(Tensor& quasi, int64_t n, const Tensor& sobolstate, + int64_t dimension, int64_t num_generated) { + AT_CHECK(sobolstate.dtype() == at::kLong, + "sobolstate needs to be of type ", at::kLong); + AT_CHECK(quasi.dtype() == at::kLong, + "quasi needs to be of type ", at::kLong); + + // We deal with `data` and `strides` due to performance issues. + int64_t l; + int64_t* quasi_data = quasi.data(); + int64_t* sobolstate_data = sobolstate.data(); + + int64_t quasi_stride = quasi.stride(0); + int64_t sobolstate_row_stride = sobolstate.stride(0), sobolstate_col_stride = sobolstate.stride(1); + + for (int64_t i = 0; i < n; i++, num_generated++) { + l = rightmost_zero(num_generated); + for (int64_t j = 0; j < dimension; j++) { + quasi_data[j * quasi_stride] ^= sobolstate_data[j * sobolstate_row_stride + l * sobolstate_col_stride]; + } + } + return quasi; +} + +/// This is an implicit function used for randomizing the state variables of the. +/// `SobolEngine`. Arguments are a randomized `sobolstate` state variables +/// and a list of random lower triangular matrices consisting of 0s and 1s. `dimension` is +/// passed explicitly again. +Tensor& _sobol_engine_scramble_(Tensor& sobolstate, const Tensor& ltm, int64_t dimension) { + AT_CHECK(sobolstate.dtype() == at::kLong, + "sobolstate needs to be of type ", at::kLong); + + /// Require a tensor accessor for `sobolstate` + auto ss_a = sobolstate.accessor(); + + /// For every tensor in the list of tensors, the diagonals are made 1 + /// Require a dot product of every row with a specific vector of each of the matrices in `ltm`. + /// Instead, we perform an element-wise product of all the matrices and sum over the last dimension. + /// The required product of the m^{th} row in the d^{th} square matrix in `ltm` can be accessed + /// using ltm_d_a[d][m] m and d are zero-indexed + Tensor diag_true = ltm.clone(); + diag_true.diagonal(0, -2, -1).fill_(1); + Tensor ltm_dots = cdot_pow2(diag_true); + auto ltm_d_a = ltm_dots.accessor(); + + /// Main scrambling loop + for (int64_t d = 0; d < dimension; ++d) { + for (int64_t j = 0; j < MAXBIT; ++j) { + int64_t vdj = ss_a[d][j], l = 1, t2 = 0; + for (int64_t p = MAXBIT - 1; p >= 0; --p) { + int64_t lsmdp = ltm_d_a[d][p]; + int64_t t1 = 0; + for (int64_t k = 0; k < MAXBIT; ++k) { + t1 += (bitsubseq(lsmdp, k, 1) * bitsubseq(vdj, k, 1)); + } + t1 = t1 % 2; + t2 = t2 + t1 * l; + l = l << 1; + } + ss_a[d][j] = t2; + } + } + return sobolstate; +} + +/// This is a core function to initialize the main state variable of a `SobolEngine`. +/// `dimension` is passed explicitly as well (see why above) +Tensor& _sobol_engine_initialize_state_(Tensor& sobolstate, int64_t dimension) { + AT_CHECK(sobolstate.dtype() == at::kLong, + "sobolstate needs to be of type ", at::kLong); + + /// First row of `sobolstate` is 1 + sobolstate.select(0, 0).fill_(1); + + /// Use a tensor accessor for `sobolstate` + auto ss_a = sobolstate.accessor(); + for (int64_t d = 0; d < dimension; ++d) { + int64_t p = poly[d]; + int64_t m = bit_length(p) - 1; + + for (int64_t i = 0; i < m; ++i) { + ss_a[d][i] = initsobolstate[d][i]; + } + + for (int64_t j = m; j < MAXBIT; ++j) { + int64_t newv = ss_a[d][j - m]; + int64_t pow2 = 1; + for (int64_t k = 0; k < m; ++k) { + pow2 <<= 1; + if ((p >> (m - 1 - k)) & 1) { + newv = newv ^ (pow2 * ss_a[d][j - k - 1]); + } + } + ss_a[d][j] = newv; + } + } + + Tensor pow2s = at::pow(2, at::native::arange((MAXBIT - 1), -1, -1, sobolstate.options())); + sobolstate.mul_(pow2s); + return sobolstate; +} + +} // namespace native +} // namespace at diff --git a/aten/src/ATen/native/SobolEngineOpsUtils.h b/aten/src/ATen/native/SobolEngineOpsUtils.h new file mode 100644 index 0000000..511df7c --- /dev/null +++ b/aten/src/ATen/native/SobolEngineOpsUtils.h @@ -0,0 +1,1265 @@ +/// This file contains some tensor-agnostic operations to be used in the +/// core functions of the `SobolEngine` +#include + +/// Function to return the minimum of number of bits to represent the integer `n` +static inline int64_t bit_length(const int64_t n) { + int64_t nbits, nloc; + for (nloc = n, nbits = 0; nloc > 0; nloc /= 2, nbits++); + return nbits; +} + +/// Function to get the position of the rightmost zero in the bit representation of an integer +/// This value is the zero-indexed position +static inline int64_t rightmost_zero(const int64_t n) { + int64_t z, i; + for (z = n, i = 0; z % 2 == 1; z /= 2, i++); + return i; +} + +/// Function to get a subsequence of bits in the representation of an integer starting from +/// `pos` and of length `length` +static inline int64_t bitsubseq(const int64_t n, const int64_t pos, const int64_t length) { + return (n >> pos) & ((1 << length) - 1); +} + +/// Function to perform the inner product between a batched square matrix and a power of 2 vector +static inline at::Tensor cdot_pow2(const at::Tensor& bmat) { + at::Tensor inter = at::arange(bmat.size(-1) - 1, -1, -1, bmat.options()); + inter = at::pow(2, inter).expand_as(bmat); + return at::mul(inter, bmat).sum(-1); +} + +/// All definitions below this point are data. These are constant, and should not be modified +/// without notice + +static constexpr int64_t MAXBIT = 30; +static constexpr int64_t LARGEST_NUMBER = 1 << 30; +static constexpr float RECIPD = 1.0 / LARGEST_NUMBER; + +static constexpr int64_t poly[1111] = { + 1, 3, 7, 11, 13, 19, 25, 37, 59, 47, 61, 55, 41, 67, 97, 91, 109, + 103, 115, 131, 193, 137, 145, 143, 241, 157, 185, 167, 229, 171, + 213, 191, 253, 203, 211, 239, 247, 285, 369, 299, 301, 333, 351, + 355, 357, 361, 391, 397, 425, 451, 463, 487, 501, 529, 539, 545, + 557, 563, 601, 607, 617, 623, 631, 637, 647, 661, 675, 677, 687, + 695, 701, 719, 721, 731, 757, 761, 787, 789, 799, 803, 817, 827, + 847, 859, 865, 875, 877, 883, 895, 901, 911, 949, 953, 967, 971, + 973, 981, 985, 995, 1001, 1019, 1033, 1051, 1063, 1069, 1125, 1135, + 1153, 1163, 1221, 1239, 1255, 1267, 1279, 1293, 1305, 1315, 1329, + 1341, 1347, 1367, 1387, 1413, 1423, 1431, 1441, 1479, 1509, 1527, + 1531, 1555, 1557, 1573, 1591, 1603, 1615, 1627, 1657, 1663, 1673, + 1717, 1729, 1747, 1759, 1789, 1815, 1821, 1825, 1849, 1863, 1869, + 1877, 1881, 1891, 1917, 1933, 1939, 1969, 2011, 2035, 2041, 2053, + 2071, 2091, 2093, 2119, 2147, 2149, 2161, 2171, 2189, 2197, 2207, + 2217, 2225, 2255, 2257, 2273, 2279, 2283, 2293, 2317, 2323, 2341, + 2345, 2363, 2365, 2373, 2377, 2385, 2395, 2419, 2421, 2431, 2435, + 2447, 2475, 2477, 2489, 2503, 2521, 2533, 2551, 2561, 2567, 2579, + 2581, 2601, 2633, 2657, 2669, 2681, 2687, 2693, 2705, 2717, 2727, + 2731, 2739, 2741, 2773, 2783, 2793, 2799, 2801, 2811, 2819, 2825, + 2833, 2867, 2879, 2881, 2891, 2905, 2911, 2917, 2927, 2941, 2951, + 2955, 2963, 2965, 2991, 2999, 3005, 3017, 3035, 3037, 3047, 3053, + 3083, 3085, 3097, 3103, 3159, 3169, 3179, 3187, 3205, 3209, 3223, + 3227, 3229, 3251, 3263, 3271, 3277, 3283, 3285, 3299, 3305, 3319, + 3331, 3343, 3357, 3367, 3373, 3393, 3399, 3413, 3417, 3427, 3439, + 3441, 3475, 3487, 3497, 3515, 3517, 3529, 3543, 3547, 3553, 3559, + 3573, 3589, 3613, 3617, 3623, 3627, 3635, 3641, 3655, 3659, 3669, + 3679, 3697, 3707, 3709, 3713, 3731, 3743, 3747, 3771, 3791, 3805, + 3827, 3833, 3851, 3865, 3889, 3895, 3933, 3947, 3949, 3957, 3971, + 3985, 3991, 3995, 4007, 4013, 4021, 4045, 4051, 4069, 4073, 4179, + 4201, 4219, 4221, 4249, 4305, 4331, 4359, 4383, 4387, 4411, 4431, + 4439, 4449, 4459, 4485, 4531, 4569, 4575, 4621, 4663, 4669, 4711, + 4723, 4735, 4793, 4801, 4811, 4879, 4893, 4897, 4921, 4927, 4941, + 4977, 5017, 5027, 5033, 5127, 5169, 5175, 5199, 5213, 5223, 5237, + 5287, 5293, 5331, 5391, 5405, 5453, 5523, 5573, 5591, 5597, 5611, + 5641, 5703, 5717, 5721, 5797, 5821, 5909, 5913, 5955, 5957, 6005, + 6025, 6061, 6067, 6079, 6081, 6231, 6237, 6289, 6295, 6329, 6383, + 6427, 6453, 6465, 6501, 6523, 6539, 6577, 6589, 6601, 6607, 6631, + 6683, 6699, 6707, 6761, 6795, 6865, 6881, 6901, 6923, 6931, 6943, + 6999, 7057, 7079, 7103, 7105, 7123, 7173, 7185, 7191, 7207, 7245, + 7303, 7327, 7333, 7355, 7365, 7369, 7375, 7411, 7431, 7459, 7491, + 7505, 7515, 7541, 7557, 7561, 7701, 7705, 7727, 7749, 7761, 7783, + 7795, 7823, 7907, 7953, 7963, 7975, 8049, 8089, 8123, 8125, 8137, + 8219, 8231, 8245, 8275, 8293, 8303, 8331, 8333, 8351, 8357, 8367, + 8379, 8381, 8387, 8393, 8417, 8435, 8461, 8469, 8489, 8495, 8507, + 8515, 8551, 8555, 8569, 8585, 8599, 8605, 8639, 8641, 8647, 8653, + 8671, 8675, 8689, 8699, 8729, 8741, 8759, 8765, 8771, 8795, 8797, + 8825, 8831, 8841, 8855, 8859, 8883, 8895, 8909, 8943, 8951, 8955, + 8965, 8999, 9003, 9031, 9045, 9049, 9071, 9073, 9085, 9095, 9101, + 9109, 9123, 9129, 9137, 9143, 9147, 9185, 9197, 9209, 9227, 9235, + 9247, 9253, 9257, 9277, 9297, 9303, 9313, 9325, 9343, 9347, 9371, + 9373, 9397, 9407, 9409, 9415, 9419, 9443, 9481, 9495, 9501, 9505, + 9517, 9529, 9555, 9557, 9571, 9585, 9591, 9607, 9611, 9621, 9625, + 9631, 9647, 9661, 9669, 9679, 9687, 9707, 9731, 9733, 9745, 9773, + 9791, 9803, 9811, 9817, 9833, 9847, 9851, 9863, 9875, 9881, 9905, + 9911, 9917, 9923, 9963, 9973, 10003, 10025, 10043, 10063, 10071, + 10077, 10091, 10099, 10105, 10115, 10129, 10145, 10169, 10183, + 10187, 10207, 10223, 10225, 10247, 10265, 10271, 10275, 10289, + 10299, 10301, 10309, 10343, 10357, 10373, 10411, 10413, 10431, + 10445, 10453, 10463, 10467, 10473, 10491, 10505, 10511, 10513, + 10523, 10539, 10549, 10559, 10561, 10571, 10581, 10615, 10621, + 10625, 10643, 10655, 10671, 10679, 10685, 10691, 10711, 10739, + 10741, 10755, 10767, 10781, 10785, 10803, 10805, 10829, 10857, + 10863, 10865, 10875, 10877, 10917, 10921, 10929, 10949, 10967, + 10971, 10987, 10995, 11009, 11029, 11043, 11045, 11055, 11063, + 11075, 11081, 11117, 11135, 11141, 11159, 11163, 11181, 11187, + 11225, 11237, 11261, 11279, 11297, 11307, 11309, 11327, 11329, + 11341, 11377, 11403, 11405, 11413, 11427, 11439, 11453, 11461, + 11473, 11479, 11489, 11495, 11499, 11533, 11545, 11561, 11567, + 11575, 11579, 11589, 11611, 11623, 11637, 11657, 11663, 11687, + 11691, 11701, 11747, 11761, 11773, 11783, 11795, 11797, 11817, + 11849, 11855, 11867, 11869, 11873, 11883, 11919, 11921, 11927, + 11933, 11947, 11955, 11961, 11999, 12027, 12029, 12037, 12041, + 12049, 12055, 12095, 12097, 12107, 12109, 12121, 12127, 12133, + 12137, 12181, 12197, 12207, 12209, 12239, 12253, 12263, 12269, + 12277, 12287, 12295, 12309, 12313, 12335, 12361, 12367, 12391, + 12409, 12415, 12433, 12449, 12469, 12479, 12481, 12499, 12505, + 12517, 12527, 12549, 12559, 12597, 12615, 12621, 12639, 12643, + 12657, 12667, 12707, 12713, 12727, 12741, 12745, 12763, 12769, + 12779, 12781, 12787, 12799, 12809, 12815, 12829, 12839, 12857, + 12875, 12883, 12889, 12901, 12929, 12947, 12953, 12959, 12969, + 12983, 12987, 12995, 13015, 13019, 13031, 13063, 13077, 13103, + 13137, 13149, 13173, 13207, 13211, 13227, 13241, 13249, 13255, + 13269, 13283, 13285, 13303, 13307, 13321, 13339, 13351, 13377, + 13389, 13407, 13417, 13431, 13435, 13447, 13459, 13465, 13477, + 13501, 13513, 13531, 13543, 13561, 13581, 13599, 13605, 13617, + 13623, 13637, 13647, 13661, 13677, 13683, 13695, 13725, 13729, + 13753, 13773, 13781, 13785, 13795, 13801, 13807, 13825, 13835, + 13855, 13861, 13871, 13883, 13897, 13905, 13915, 13939, 13941, + 13969, 13979, 13981, 13997, 14027, 14035, 14037, 14051, 14063, + 14085, 14095, 14107, 14113, 14125, 14137, 14145, 14151, 14163, + 14193, 14199, 14219, 14229, 14233, 14243, 14277, 14287, 14289, + 14295, 14301, 14305, 14323, 14339, 14341, 14359, 14365, 14375, + 14387, 14411, 14425, 14441, 14449, 14499, 14513, 14523, 14537, + 14543, 14561, 14579, 14585, 14593, 14599, 14603, 14611, 14641, + 14671, 14695, 14701, 14723, 14725, 14743, 14753, 14759, 14765, + 14795, 14797, 14803, 14831, 14839, 14845, 14855, 14889, 14895, + 14909, 14929, 14941, 14945, 14951, 14963, 14965, 14985, 15033, + 15039, 15053, 15059, 15061, 15071, 15077, 15081, 15099, 15121, + 15147, 15149, 15157, 15167, 15187, 15193, 15203, 15205, 15215, + 15217, 15223, 15243, 15257, 15269, 15273, 15287, 15291, 15313, + 15335, 15347, 15359, 15373, 15379, 15381, 15391, 15395, 15397, + 15419, 15439, 15453, 15469, 15491, 15503, 15517, 15527, 15531, + 15545, 15559, 15593, 15611, 15613, 15619, 15639, 15643, 15649, + 15661, 15667, 15669, 15681, 15693, 15717, 15721, 15741, 15745, + 15765, 15793, 15799, 15811, 15825, 15835, 15847, 15851, 15865, + 15877, 15881, 15887, 15899, 15915, 15935, 15937, 15955, 15973, + 15977, 16011, 16035, 16061, 16069, 16087, 16093, 16097, 16121, + 16141, 16153, 16159, 16165, 16183, 16189, 16195, 16197, 16201, + 16209, 16215, 16225, 16259, 16265, 16273, 16299, 16309, 16355, + 16375, 16381 +}; + +static constexpr int64_t initsobolstate[1111][13] = { + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 3, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 3, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 3, 3, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 3, 7, 13, 3, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 5, 11, 27, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 3, 5, 1, 15, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 7, 3, 29, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 3, 7, 7, 21, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 1, 9, 23, 37, 0, 0, 0, 0, 0, 0, 0}, + {1, 3, 3, 5, 19, 33, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 3, 13, 11, 7, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 7, 13, 25, 5, 0, 0, 0, 0, 0, 0, 0}, + {1, 3, 5, 11, 7, 11, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 1, 3, 13, 39, 0, 0, 0, 0, 0, 0, 0}, + {1, 3, 1, 15, 17, 63, 13, 0, 0, 0, 0, 0, 0}, + {1, 1, 5, 5, 1, 59, 33, 0, 0, 0, 0, 0, 0}, + {1, 3, 3, 3, 25, 17, 115, 0, 0, 0, 0, 0, 0}, + {1, 1, 7, 15, 29, 15, 41, 0, 0, 0, 0, 0, 0}, + {1, 3, 1, 7, 3, 23, 79, 0, 0, 0, 0, 0, 0}, + {1, 3, 7, 9, 31, 29, 17, 0, 0, 0, 0, 0, 0}, + {1, 1, 5, 13, 11, 3, 29, 0, 0, 0, 0, 0, 0}, + {1, 1, 1, 9, 5, 21, 119, 0, 0, 0, 0, 0, 0}, + {1, 1, 3, 1, 23, 13, 75, 0, 0, 0, 0, 0, 0}, + {1, 3, 7, 11, 27, 31, 73, 0, 0, 0, 0, 0, 0}, + {1, 1, 7, 7, 19, 25, 105, 0, 0, 0, 0, 0, 0}, + {1, 3, 1, 5, 21, 9, 7, 0, 0, 0, 0, 0, 0}, + {1, 1, 1, 15, 5, 49, 59, 0, 0, 0, 0, 0, 0}, + {1, 3, 1, 1, 1, 33, 65, 0, 0, 0, 0, 0, 0}, + {1, 3, 5, 15, 17, 19, 21, 0, 0, 0, 0, 0, 0}, + {1, 1, 7, 11, 13, 29, 3, 0, 0, 0, 0, 0, 0}, + {1, 3, 7, 5, 7, 11, 113, 0, 0, 0, 0, 0, 0}, + {1, 1, 5, 11, 15, 19, 61, 0, 0, 0, 0, 0, 0}, + {1, 1, 1, 1, 9, 27, 89, 7, 0, 0, 0, 0, 0}, + {1, 1, 3, 7, 31, 15, 45, 23, 0, 0, 0, 0, 0}, + {1, 3, 3, 9, 25, 25, 107, 39, 0, 0, 0, 0, 0}, + {1, 1, 7, 7, 3, 63, 21, 217, 0, 0, 0, 0, 0}, + {1, 3, 5, 7, 5, 55, 71, 141, 0, 0, 0, 0, 0}, + {1, 1, 5, 1, 23, 17, 79, 27, 0, 0, 0, 0, 0}, + {1, 1, 5, 15, 7, 63, 19, 53, 0, 0, 0, 0, 0}, + {1, 1, 3, 15, 3, 49, 71, 181, 0, 0, 0, 0, 0}, + {1, 3, 3, 15, 17, 19, 61, 169, 0, 0, 0, 0, 0}, + {1, 3, 3, 13, 23, 41, 41, 35, 0, 0, 0, 0, 0}, + {1, 1, 1, 3, 3, 59, 57, 15, 0, 0, 0, 0, 0}, + {1, 3, 1, 3, 3, 3, 121, 207, 0, 0, 0, 0, 0}, + {1, 3, 5, 15, 21, 57, 87, 45, 0, 0, 0, 0, 0}, + {1, 1, 1, 5, 25, 33, 119, 247, 0, 0, 0, 0, 0}, + {1, 1, 1, 9, 25, 49, 55, 185, 0, 0, 0, 0, 0}, + {1, 3, 5, 7, 23, 53, 85, 117, 0, 0, 0, 0, 0}, + {1, 3, 3, 13, 11, 57, 121, 41, 235, 0, 0, 0, 0}, + {1, 1, 3, 3, 19, 57, 119, 81, 307, 0, 0, 0, 0}, + {1, 3, 3, 7, 3, 39, 11, 223, 495, 0, 0, 0, 0}, + {1, 3, 3, 5, 11, 21, 23, 151, 417, 0, 0, 0, 0}, + {1, 3, 1, 11, 31, 7, 61, 81, 57, 0, 0, 0, 0}, + {1, 1, 3, 9, 7, 53, 11, 189, 151, 0, 0, 0, 0}, + {1, 3, 7, 1, 9, 9, 35, 61, 19, 0, 0, 0, 0}, + {1, 1, 5, 9, 5, 55, 33, 95, 119, 0, 0, 0, 0}, + {1, 3, 7, 1, 17, 15, 43, 185, 375, 0, 0, 0, 0}, + {1, 1, 3, 5, 23, 59, 107, 23, 451, 0, 0, 0, 0}, + {1, 1, 7, 7, 17, 19, 113, 73, 55, 0, 0, 0, 0}, + {1, 3, 1, 13, 17, 49, 101, 113, 449, 0, 0, 0, 0}, + {1, 3, 3, 9, 25, 31, 29, 239, 501, 0, 0, 0, 0}, + {1, 1, 3, 9, 13, 3, 87, 85, 53, 0, 0, 0, 0}, + {1, 1, 5, 1, 11, 39, 119, 9, 185, 0, 0, 0, 0}, + {1, 1, 1, 7, 31, 5, 97, 201, 317, 0, 0, 0, 0}, + {1, 1, 3, 3, 27, 5, 29, 83, 17, 0, 0, 0, 0}, + {1, 3, 5, 5, 19, 41, 17, 53, 21, 0, 0, 0, 0}, + {1, 1, 5, 1, 17, 9, 89, 183, 487, 0, 0, 0, 0}, + {1, 1, 7, 11, 23, 19, 5, 203, 13, 0, 0, 0, 0}, + {1, 3, 7, 11, 7, 9, 127, 91, 347, 0, 0, 0, 0}, + {1, 1, 7, 13, 5, 57, 89, 149, 393, 0, 0, 0, 0}, + {1, 1, 1, 7, 11, 25, 119, 101, 15, 0, 0, 0, 0}, + {1, 1, 1, 7, 19, 1, 117, 13, 391, 0, 0, 0, 0}, + {1, 3, 3, 9, 19, 15, 103, 111, 307, 0, 0, 0, 0}, + {1, 3, 3, 9, 7, 51, 105, 239, 189, 0, 0, 0, 0}, + {1, 1, 1, 1, 13, 11, 41, 3, 381, 0, 0, 0, 0}, + {1, 3, 1, 1, 21, 19, 83, 205, 71, 0, 0, 0, 0}, + {1, 3, 5, 3, 21, 61, 25, 253, 163, 0, 0, 0, 0}, + {1, 1, 1, 9, 7, 53, 41, 247, 99, 0, 0, 0, 0}, + {1, 3, 5, 15, 9, 29, 55, 121, 467, 0, 0, 0, 0}, + {1, 3, 7, 1, 11, 19, 69, 189, 167, 0, 0, 0, 0}, + {1, 3, 5, 5, 1, 11, 117, 169, 433, 0, 0, 0, 0}, + {1, 1, 1, 13, 5, 9, 49, 179, 337, 0, 0, 0, 0}, + {1, 3, 7, 1, 21, 21, 127, 197, 257, 0, 0, 0, 0}, + {1, 3, 5, 9, 11, 19, 29, 175, 179, 0, 0, 0, 0}, + {1, 3, 3, 9, 13, 43, 1, 217, 47, 0, 0, 0, 0}, + {1, 1, 3, 9, 25, 13, 99, 249, 385, 0, 0, 0, 0}, + {1, 3, 1, 9, 9, 13, 53, 195, 23, 0, 0, 0, 0}, + {1, 3, 5, 9, 7, 41, 83, 95, 117, 0, 0, 0, 0}, + {1, 1, 7, 13, 7, 25, 15, 63, 369, 0, 0, 0, 0}, + {1, 3, 1, 11, 27, 31, 31, 19, 425, 0, 0, 0, 0}, + {1, 3, 7, 3, 15, 9, 73, 7, 207, 0, 0, 0, 0}, + {1, 3, 5, 5, 25, 11, 115, 5, 433, 0, 0, 0, 0}, + {1, 1, 1, 11, 15, 19, 35, 75, 301, 0, 0, 0, 0}, + {1, 3, 7, 11, 21, 5, 21, 217, 147, 0, 0, 0, 0}, + {1, 1, 3, 13, 17, 53, 89, 245, 333, 0, 0, 0, 0}, + {1, 3, 1, 5, 19, 37, 5, 111, 85, 0, 0, 0, 0}, + {1, 1, 7, 3, 19, 7, 1, 189, 221, 519, 0, 0, 0}, + {1, 1, 1, 15, 21, 51, 91, 165, 423, 307, 0, 0, 0}, + {1, 3, 7, 1, 5, 45, 53, 169, 49, 931, 0, 0, 0}, + {1, 3, 3, 11, 11, 7, 35, 141, 3, 1023, 0, 0, 0}, + {1, 1, 3, 11, 3, 7, 95, 221, 43, 517, 0, 0, 0}, + {1, 3, 5, 7, 5, 61, 83, 249, 229, 771, 0, 0, 0}, + {1, 3, 7, 13, 29, 23, 19, 159, 227, 151, 0, 0, 0}, + {1, 1, 3, 15, 31, 45, 85, 253, 201, 1023, 0, 0, 0}, + {1, 1, 3, 11, 29, 7, 55, 207, 383, 539, 0, 0, 0}, + {1, 1, 5, 13, 5, 59, 51, 249, 281, 725, 0, 0, 0}, + {1, 3, 1, 9, 5, 41, 101, 219, 229, 45, 0, 0, 0}, + {1, 3, 3, 11, 1, 1, 33, 23, 207, 927, 0, 0, 0}, + {1, 1, 3, 15, 31, 29, 41, 49, 21, 707, 0, 0, 0}, + {1, 3, 1, 15, 27, 61, 55, 127, 343, 29, 0, 0, 0}, + {1, 3, 3, 13, 11, 37, 45, 237, 251, 125, 0, 0, 0}, + {1, 1, 5, 3, 13, 27, 95, 5, 397, 371, 0, 0, 0}, + {1, 3, 1, 15, 1, 47, 61, 25, 173, 275, 0, 0, 0}, + {1, 1, 3, 7, 3, 15, 27, 177, 507, 279, 0, 0, 0}, + {1, 1, 3, 9, 7, 31, 37, 37, 421, 817, 0, 0, 0}, + {1, 3, 3, 11, 11, 35, 89, 103, 443, 389, 0, 0, 0}, + {1, 3, 7, 13, 7, 31, 75, 65, 399, 453, 0, 0, 0}, + {1, 3, 1, 11, 3, 17, 57, 167, 53, 989, 0, 0, 0}, + {1, 1, 1, 9, 23, 51, 61, 81, 345, 1015, 0, 0, 0}, + {1, 1, 7, 9, 13, 13, 15, 87, 77, 29, 0, 0, 0}, + {1, 1, 3, 5, 31, 25, 117, 119, 385, 169, 0, 0, 0}, + {1, 3, 1, 13, 17, 45, 15, 45, 317, 743, 0, 0, 0}, + {1, 1, 3, 9, 1, 5, 21, 79, 155, 99, 0, 0, 0}, + {1, 1, 7, 1, 27, 5, 27, 143, 187, 923, 0, 0, 0}, + {1, 3, 5, 13, 11, 33, 25, 57, 269, 981, 0, 0, 0}, + {1, 1, 5, 7, 25, 39, 27, 79, 501, 181, 0, 0, 0}, + {1, 1, 7, 7, 1, 5, 123, 187, 19, 693, 0, 0, 0}, + {1, 3, 5, 7, 23, 47, 39, 143, 169, 309, 0, 0, 0}, + {1, 3, 5, 7, 29, 29, 109, 183, 235, 227, 0, 0, 0}, + {1, 1, 3, 7, 17, 35, 93, 75, 415, 111, 0, 0, 0}, + {1, 3, 1, 5, 25, 47, 51, 97, 61, 219, 0, 0, 0}, + {1, 1, 3, 9, 7, 63, 21, 211, 247, 897, 0, 0, 0}, + {1, 3, 3, 7, 25, 45, 91, 149, 183, 377, 0, 0, 0}, + {1, 3, 3, 13, 27, 37, 109, 175, 5, 425, 0, 0, 0}, + {1, 3, 1, 11, 17, 47, 107, 37, 257, 609, 0, 0, 0}, + {1, 3, 3, 9, 13, 59, 45, 135, 401, 227, 0, 0, 0}, + {1, 1, 3, 11, 17, 21, 15, 189, 451, 19, 0, 0, 0}, + {1, 1, 7, 15, 23, 59, 93, 225, 95, 221, 0, 0, 0}, + {1, 1, 3, 3, 5, 33, 127, 241, 455, 143, 0, 0, 0}, + {1, 3, 3, 13, 17, 51, 3, 63, 49, 581, 0, 0, 0}, + {1, 3, 1, 11, 5, 9, 53, 33, 489, 147, 0, 0, 0}, + {1, 1, 7, 1, 13, 27, 81, 43, 75, 919, 0, 0, 0}, + {1, 1, 5, 11, 11, 13, 79, 13, 459, 127, 0, 0, 0}, + {1, 3, 1, 3, 21, 25, 107, 73, 377, 725, 0, 0, 0}, + {1, 1, 7, 3, 5, 43, 79, 213, 87, 793, 0, 0, 0}, + {1, 1, 7, 9, 11, 3, 87, 57, 463, 289, 0, 0, 0}, + {1, 1, 5, 11, 5, 17, 35, 239, 155, 411, 0, 0, 0}, + {1, 1, 7, 1, 9, 21, 109, 183, 233, 835, 0, 0, 0}, + {1, 1, 5, 7, 31, 59, 73, 117, 115, 921, 0, 0, 0}, + {1, 1, 1, 1, 19, 61, 35, 21, 429, 957, 0, 0, 0}, + {1, 3, 3, 15, 17, 27, 83, 29, 211, 443, 0, 0, 0}, + {1, 1, 1, 15, 9, 47, 107, 115, 419, 349, 0, 0, 0}, + {1, 3, 7, 3, 9, 57, 1, 43, 143, 813, 0, 0, 0}, + {1, 1, 3, 1, 27, 11, 51, 205, 487, 5, 0, 0, 0}, + {1, 1, 7, 9, 21, 17, 7, 223, 195, 105, 0, 0, 0}, + {1, 1, 3, 1, 15, 39, 59, 15, 209, 457, 0, 0, 0}, + {1, 3, 5, 7, 15, 1, 33, 3, 461, 393, 7, 0, 0}, + {1, 1, 7, 13, 1, 63, 115, 159, 193, 539, 2011, 0, 0}, + {1, 3, 3, 11, 1, 21, 43, 51, 157, 101, 1001, 0, 0}, + {1, 1, 1, 3, 29, 59, 111, 101, 193, 197, 49, 0, 0}, + {1, 3, 3, 13, 5, 17, 45, 127, 363, 697, 825, 0, 0}, + {1, 3, 3, 11, 31, 13, 121, 99, 181, 27, 415, 0, 0}, + {1, 3, 3, 7, 11, 31, 105, 239, 271, 343, 1441, 0, 0}, + {1, 1, 1, 3, 17, 3, 125, 171, 445, 515, 383, 0, 0}, + {1, 1, 5, 3, 23, 31, 87, 113, 381, 69, 1581, 0, 0}, + {1, 3, 7, 5, 19, 7, 101, 171, 231, 485, 623, 0, 0}, + {1, 3, 3, 13, 21, 9, 41, 119, 135, 383, 1621, 0, 0}, + {1, 1, 3, 11, 25, 27, 95, 189, 327, 855, 1319, 0, 0}, + {1, 3, 7, 5, 15, 37, 75, 245, 403, 693, 1387, 0, 0}, + {1, 1, 7, 11, 11, 23, 1, 201, 171, 133, 619, 0, 0}, + {1, 3, 7, 1, 5, 31, 57, 27, 197, 87, 839, 0, 0}, + {1, 1, 5, 3, 5, 9, 117, 185, 181, 743, 217, 0, 0}, + {1, 1, 3, 9, 1, 45, 21, 229, 343, 747, 75, 0, 0}, + {1, 3, 1, 7, 19, 43, 27, 105, 113, 475, 1955, 0, 0}, + {1, 1, 7, 15, 19, 31, 67, 153, 313, 87, 505, 0, 0}, + {1, 3, 1, 7, 19, 63, 29, 189, 393, 469, 281, 0, 0}, + {1, 1, 3, 5, 7, 21, 53, 33, 311, 763, 1629, 0, 0}, + {1, 3, 7, 13, 13, 39, 117, 35, 415, 721, 1379, 0, 0}, + {1, 1, 5, 7, 21, 51, 63, 137, 267, 345, 53, 0, 0}, + {1, 3, 3, 9, 17, 27, 1, 77, 247, 479, 1111, 0, 0}, + {1, 1, 3, 13, 17, 7, 77, 97, 425, 965, 1399, 0, 0}, + {1, 1, 3, 15, 25, 53, 89, 17, 233, 527, 301, 0, 0}, + {1, 1, 7, 13, 23, 11, 115, 181, 289, 121, 209, 0, 0}, + {1, 3, 1, 9, 19, 1, 49, 55, 55, 271, 49, 0, 0}, + {1, 3, 1, 7, 23, 59, 127, 197, 39, 353, 155, 0, 0}, + {1, 1, 3, 15, 15, 39, 15, 201, 247, 467, 1647, 0, 0}, + {1, 3, 1, 7, 13, 23, 79, 155, 327, 177, 631, 0, 0}, + {1, 3, 5, 9, 5, 49, 81, 37, 141, 245, 129, 0, 0}, + {1, 1, 7, 5, 19, 23, 29, 197, 5, 627, 1569, 0, 0}, + {1, 3, 1, 11, 25, 7, 65, 137, 189, 113, 335, 0, 0}, + {1, 1, 3, 11, 9, 55, 103, 223, 183, 357, 67, 0, 0}, + {1, 1, 5, 13, 7, 59, 33, 25, 27, 7, 1955, 0, 0}, + {1, 1, 3, 13, 3, 3, 73, 179, 337, 691, 1611, 0, 0}, + {1, 3, 5, 9, 21, 19, 79, 91, 341, 725, 2021, 0, 0}, + {1, 1, 3, 3, 17, 35, 29, 23, 327, 355, 1305, 0, 0}, + {1, 3, 3, 5, 25, 13, 21, 235, 87, 889, 121, 0, 0}, + {1, 1, 7, 13, 1, 9, 113, 53, 429, 635, 37, 0, 0}, + {1, 1, 5, 9, 27, 13, 31, 253, 357, 737, 877, 0, 0}, + {1, 3, 5, 11, 25, 15, 33, 49, 265, 429, 835, 0, 0}, + {1, 1, 3, 15, 27, 23, 107, 181, 251, 545, 1457, 0, 0}, + {1, 1, 3, 11, 25, 9, 95, 249, 437, 925, 669, 0, 0}, + {1, 3, 1, 7, 9, 7, 111, 53, 201, 357, 1405, 0, 0}, + {1, 3, 3, 1, 13, 43, 59, 173, 29, 873, 935, 0, 0}, + {1, 1, 7, 7, 3, 55, 99, 97, 339, 187, 1735, 0, 0}, + {1, 1, 7, 13, 17, 3, 117, 247, 257, 351, 665, 0, 0}, + {1, 3, 7, 3, 25, 19, 63, 67, 377, 677, 551, 0, 0}, + {1, 3, 1, 13, 23, 9, 63, 115, 17, 999, 789, 0, 0}, + {1, 3, 5, 3, 9, 27, 99, 103, 53, 921, 1543, 0, 0}, + {1, 1, 7, 13, 25, 33, 39, 159, 327, 477, 1267, 0, 0}, + {1, 3, 1, 9, 9, 27, 9, 239, 47, 233, 1027, 0, 0}, + {1, 3, 3, 15, 13, 49, 35, 69, 375, 765, 1, 0, 0}, + {1, 3, 1, 7, 17, 23, 63, 173, 393, 495, 1911, 0, 0}, + {1, 1, 1, 13, 17, 47, 125, 217, 369, 81, 163, 0, 0}, + {1, 3, 7, 13, 3, 19, 99, 95, 403, 953, 1929, 0, 0}, + {1, 1, 1, 3, 15, 7, 45, 221, 125, 479, 67, 0, 0}, + {1, 3, 3, 13, 7, 11, 93, 247, 429, 89, 1975, 0, 0}, + {1, 1, 1, 15, 7, 55, 33, 97, 257, 173, 1681, 0, 0}, + {1, 1, 7, 15, 29, 27, 93, 91, 157, 473, 1413, 0, 0}, + {1, 1, 1, 11, 3, 35, 9, 123, 217, 131, 191, 0, 0}, + {1, 3, 5, 9, 19, 5, 105, 223, 85, 961, 1711, 0, 0}, + {1, 1, 3, 13, 29, 5, 75, 213, 267, 411, 1307, 0, 0}, + {1, 1, 5, 9, 29, 55, 51, 129, 117, 291, 401, 0, 0}, + {1, 1, 3, 15, 19, 35, 115, 181, 337, 967, 725, 0, 0}, + {1, 3, 1, 1, 29, 37, 11, 87, 447, 65, 1229, 0, 0}, + {1, 1, 1, 1, 13, 9, 37, 239, 219, 511, 1403, 0, 0}, + {1, 1, 5, 15, 15, 33, 17, 85, 501, 13, 1609, 0, 0}, + {1, 1, 5, 11, 25, 29, 41, 89, 41, 805, 2035, 0, 0}, + {1, 1, 3, 11, 27, 47, 21, 249, 41, 945, 917, 0, 0}, + {1, 1, 3, 7, 1, 25, 43, 141, 193, 369, 921, 0, 0}, + {1, 3, 5, 1, 3, 11, 73, 39, 509, 827, 1789, 0, 0}, + {1, 3, 7, 11, 9, 47, 19, 57, 131, 295, 41, 0, 0}, + {1, 3, 1, 13, 9, 53, 93, 249, 207, 163, 2003, 0, 0}, + {1, 1, 5, 9, 13, 61, 7, 71, 505, 835, 187, 0, 0}, + {1, 1, 3, 13, 31, 59, 95, 101, 421, 259, 67, 0, 0}, + {1, 1, 7, 3, 29, 3, 81, 159, 149, 207, 1635, 0, 0}, + {1, 1, 7, 5, 31, 53, 93, 33, 111, 331, 717, 0, 0}, + {1, 3, 3, 11, 5, 47, 79, 137, 177, 29, 1449, 0, 0}, + {1, 3, 5, 13, 15, 5, 81, 189, 167, 315, 277, 0, 0}, + {1, 3, 3, 9, 29, 19, 55, 71, 223, 999, 1903, 0, 0}, + {1, 1, 3, 9, 1, 59, 9, 253, 291, 133, 1179, 0, 0}, + {1, 3, 1, 13, 19, 5, 51, 205, 91, 967, 363, 0, 0}, + {1, 3, 7, 1, 5, 47, 63, 171, 29, 41, 1211, 0, 0}, + {1, 1, 3, 11, 9, 23, 45, 13, 305, 117, 1231, 0, 0}, + {1, 1, 1, 15, 19, 45, 89, 249, 151, 677, 647, 0, 0}, + {1, 1, 3, 13, 5, 53, 73, 109, 177, 471, 1261, 0, 0}, + {1, 1, 5, 3, 15, 3, 19, 131, 337, 717, 1029, 0, 0}, + {1, 3, 7, 13, 3, 49, 115, 199, 183, 881, 1485, 0, 0}, + {1, 1, 1, 7, 5, 61, 39, 189, 361, 755, 1309, 0, 0}, + {1, 1, 3, 15, 7, 47, 47, 179, 435, 351, 1149, 0, 0}, + {1, 3, 7, 1, 15, 39, 81, 31, 307, 723, 317, 0, 0}, + {1, 1, 1, 15, 17, 29, 39, 99, 507, 259, 1335, 0, 0}, + {1, 3, 5, 3, 17, 17, 5, 113, 77, 879, 171, 0, 0}, + {1, 3, 1, 3, 23, 57, 5, 41, 181, 455, 243, 0, 0}, + {1, 1, 3, 11, 11, 5, 45, 173, 507, 721, 271, 0, 0}, + {1, 1, 1, 7, 9, 17, 53, 23, 315, 289, 1055, 0, 0}, + {1, 3, 5, 13, 23, 31, 65, 189, 145, 149, 1601, 0, 0}, + {1, 3, 3, 7, 19, 23, 49, 197, 423, 199, 1129, 0, 0}, + {1, 1, 1, 7, 3, 41, 17, 3, 71, 805, 1653, 0, 0}, + {1, 1, 7, 9, 17, 39, 105, 135, 103, 987, 205, 0, 0}, + {1, 1, 1, 7, 1, 5, 13, 9, 493, 851, 1463, 0, 0}, + {1, 1, 5, 5, 27, 27, 107, 95, 271, 423, 1681, 0, 0}, + {1, 3, 5, 15, 9, 7, 5, 195, 469, 597, 1621, 0, 0}, + {1, 1, 5, 9, 9, 29, 5, 27, 339, 129, 197, 0, 0}, + {1, 3, 3, 5, 17, 29, 19, 183, 237, 11, 951, 0, 0}, + {1, 3, 7, 5, 13, 33, 73, 1, 437, 733, 573, 0, 0}, + {1, 1, 1, 7, 25, 31, 59, 123, 483, 549, 1697, 0, 0}, + {1, 3, 1, 15, 29, 41, 43, 73, 31, 153, 1265, 0, 0}, + {1, 3, 7, 13, 23, 31, 83, 53, 219, 285, 1321, 0, 0}, + {1, 1, 3, 15, 29, 29, 97, 99, 61, 451, 1805, 0, 0}, + {1, 1, 1, 5, 11, 17, 115, 197, 131, 559, 1235, 0, 0}, + {1, 1, 1, 15, 31, 29, 27, 59, 391, 377, 1853, 0, 0}, + {1, 3, 7, 5, 25, 29, 1, 27, 233, 109, 1307, 0, 0}, + {1, 3, 5, 3, 21, 9, 69, 101, 219, 357, 945, 0, 0}, + {1, 3, 7, 1, 29, 9, 103, 55, 69, 143, 1197, 0, 0}, + {1, 1, 5, 11, 19, 31, 3, 193, 57, 693, 1411, 0, 0}, + {1, 3, 7, 7, 27, 27, 99, 31, 459, 615, 833, 0, 0}, + {1, 3, 7, 1, 31, 53, 103, 61, 225, 677, 273, 0, 0}, + {1, 1, 3, 5, 3, 35, 63, 119, 421, 701, 1517, 0, 0}, + {1, 3, 7, 7, 5, 5, 67, 11, 7, 475, 1747, 0, 0}, + {1, 3, 1, 9, 3, 61, 25, 7, 461, 767, 1095, 0, 0}, + {1, 1, 3, 3, 3, 1, 121, 255, 111, 85, 1345, 0, 0}, + {1, 3, 7, 11, 13, 49, 97, 233, 451, 229, 869, 0, 0}, + {1, 1, 7, 1, 21, 13, 77, 53, 277, 509, 57, 0, 0}, + {1, 3, 3, 15, 9, 57, 13, 157, 185, 547, 1383, 0, 0}, + {1, 3, 5, 1, 29, 29, 83, 193, 193, 151, 221, 0, 0}, + {1, 3, 1, 3, 3, 5, 103, 97, 125, 389, 1713, 0, 0}, + {1, 1, 1, 15, 17, 21, 41, 83, 251, 711, 335, 0, 0}, + {1, 3, 7, 11, 11, 43, 11, 65, 199, 785, 1751, 0, 0}, + {1, 1, 1, 13, 11, 25, 27, 81, 73, 657, 1141, 0, 0}, + {1, 1, 5, 5, 9, 57, 81, 239, 71, 319, 839, 0, 0}, + {1, 3, 5, 13, 21, 49, 37, 167, 7, 509, 523, 0, 0}, + {1, 1, 5, 1, 19, 37, 33, 69, 409, 99, 1861, 0, 0}, + {1, 3, 1, 7, 7, 27, 125, 71, 417, 1007, 1105, 0, 0}, + {1, 1, 5, 1, 17, 11, 71, 109, 149, 775, 389, 0, 0}, + {1, 1, 1, 15, 31, 61, 41, 97, 193, 359, 1177, 0, 0}, + {1, 1, 7, 7, 25, 37, 41, 137, 53, 697, 1877, 0, 0}, + {1, 3, 5, 5, 1, 49, 59, 71, 437, 677, 805, 0, 0}, + {1, 3, 5, 1, 27, 5, 41, 193, 29, 85, 93, 0, 0}, + {1, 3, 7, 1, 5, 63, 87, 189, 467, 497, 1591, 0, 0}, + {1, 1, 1, 15, 15, 63, 123, 115, 229, 105, 423, 0, 0}, + {1, 1, 1, 13, 27, 3, 43, 79, 31, 615, 1835, 0, 0}, + {1, 3, 7, 11, 29, 45, 101, 205, 35, 891, 99, 0, 0}, + {1, 1, 1, 11, 29, 37, 63, 37, 75, 71, 1781, 0, 0}, + {1, 3, 7, 13, 29, 63, 45, 227, 105, 449, 1515, 0, 0}, + {1, 1, 7, 5, 25, 21, 39, 53, 503, 835, 1909, 0, 0}, + {1, 1, 1, 11, 27, 21, 21, 33, 75, 609, 1011, 0, 0}, + {1, 1, 1, 7, 25, 19, 97, 91, 317, 377, 303, 0, 0}, + {1, 1, 3, 9, 3, 27, 15, 229, 401, 693, 385, 0, 0}, + {1, 1, 3, 7, 21, 59, 97, 245, 367, 665, 1635, 0, 0}, + {1, 1, 3, 1, 17, 21, 111, 105, 131, 627, 357, 0, 0}, + {1, 3, 7, 5, 25, 45, 21, 77, 365, 215, 973, 0, 0}, + {1, 1, 7, 3, 13, 23, 49, 229, 441, 911, 1781, 0, 0}, + {1, 1, 5, 9, 15, 13, 13, 161, 433, 503, 1707, 0, 0}, + {1, 3, 3, 5, 17, 15, 17, 103, 93, 729, 1363, 0, 0}, + {1, 1, 7, 5, 13, 3, 79, 93, 377, 131, 1053, 0, 0}, + {1, 3, 3, 11, 23, 43, 91, 13, 405, 19, 649, 0, 0}, + {1, 3, 1, 5, 9, 63, 65, 161, 465, 895, 1469, 0, 0}, + {1, 1, 3, 1, 3, 39, 105, 229, 259, 199, 623, 0, 0}, + {1, 1, 7, 7, 11, 19, 75, 223, 283, 161, 1429, 0, 0}, + {1, 1, 5, 1, 7, 63, 1, 69, 443, 239, 1241, 0, 0}, + {1, 1, 3, 11, 9, 31, 45, 15, 143, 633, 1151, 0, 0}, + {1, 3, 3, 7, 9, 41, 67, 25, 445, 1013, 1055, 0, 0}, + {1, 1, 5, 9, 7, 41, 83, 23, 3, 537, 503, 0, 0}, + {1, 3, 7, 13, 17, 15, 107, 233, 461, 255, 921, 0, 0}, + {1, 1, 1, 15, 7, 43, 125, 93, 329, 23, 3, 0, 0}, + {1, 3, 1, 13, 1, 63, 87, 25, 309, 149, 349, 0, 0}, + {1, 1, 5, 3, 27, 53, 15, 217, 77, 679, 1149, 0, 0}, + {1, 1, 5, 1, 1, 1, 81, 247, 323, 1021, 293, 0, 0}, + {1, 1, 7, 11, 9, 63, 95, 61, 155, 595, 45, 0, 0}, + {1, 1, 7, 13, 5, 31, 105, 75, 347, 199, 303, 0, 0}, + {1, 3, 1, 15, 31, 7, 65, 27, 45, 557, 877, 0, 0}, + {1, 3, 1, 1, 21, 17, 45, 9, 381, 659, 1565, 0, 0}, + {1, 1, 1, 1, 25, 11, 59, 223, 315, 251, 1583, 3915, 0}, + {1, 1, 1, 11, 25, 61, 103, 213, 463, 829, 1001, 97, 0}, + {1, 1, 5, 9, 21, 31, 23, 55, 207, 727, 663, 3047, 0}, + {1, 1, 5, 13, 11, 51, 103, 197, 321, 439, 1535, 937, 0}, + {1, 1, 5, 3, 1, 37, 99, 145, 157, 495, 395, 2897, 0}, + {1, 3, 7, 13, 23, 29, 67, 89, 109, 647, 1141, 953, 0}, + {1, 3, 5, 11, 19, 59, 99, 199, 479, 223, 1481, 127, 0}, + {1, 3, 7, 15, 27, 25, 47, 41, 313, 949, 1797, 1201, 0}, + {1, 1, 1, 13, 15, 63, 117, 201, 345, 625, 643, 3819, 0}, + {1, 1, 1, 9, 3, 59, 71, 5, 167, 87, 1507, 193, 0}, + {1, 3, 3, 9, 5, 47, 89, 149, 439, 481, 465, 2053, 0}, + {1, 3, 5, 9, 23, 15, 35, 35, 307, 85, 2027, 3061, 0}, + {1, 3, 1, 5, 9, 27, 53, 119, 235, 799, 1695, 3759, 0}, + {1, 3, 3, 5, 25, 19, 73, 183, 473, 917, 367, 1553, 0}, + {1, 3, 3, 5, 7, 29, 9, 53, 79, 769, 937, 2007, 0}, + {1, 1, 7, 5, 29, 45, 115, 11, 101, 949, 719, 2493, 0}, + {1, 3, 3, 1, 11, 35, 49, 13, 245, 739, 545, 603, 0}, + {1, 3, 7, 15, 9, 55, 37, 3, 19, 115, 1991, 3343, 0}, + {1, 1, 5, 5, 13, 39, 1, 179, 381, 499, 83, 3751, 0}, + {1, 3, 3, 9, 5, 19, 35, 229, 251, 945, 819, 1059, 0}, + {1, 3, 5, 11, 11, 43, 9, 43, 35, 547, 239, 783, 0}, + {1, 3, 3, 7, 1, 21, 45, 55, 25, 225, 1791, 1789, 0}, + {1, 3, 1, 15, 3, 19, 81, 187, 107, 1015, 1461, 1589, 0}, + {1, 1, 7, 5, 31, 13, 19, 233, 187, 469, 1647, 283, 0}, + {1, 1, 1, 3, 27, 17, 127, 47, 115, 737, 1501, 1093, 0}, + {1, 1, 7, 13, 3, 51, 17, 133, 113, 495, 1161, 3919, 0}, + {1, 1, 7, 5, 17, 37, 17, 91, 321, 353, 1629, 2747, 0}, + {1, 1, 1, 3, 27, 5, 105, 47, 115, 103, 139, 277, 0}, + {1, 1, 1, 11, 11, 33, 89, 71, 445, 17, 1595, 2605, 0}, + {1, 3, 7, 5, 13, 35, 49, 93, 61, 665, 1921, 2169, 0}, + {1, 1, 7, 1, 15, 49, 101, 105, 77, 639, 1267, 2905, 0}, + {1, 1, 7, 11, 29, 25, 7, 145, 293, 525, 1415, 721, 0}, + {1, 3, 5, 13, 15, 45, 37, 45, 405, 75, 509, 4069, 0}, + {1, 1, 5, 9, 1, 1, 33, 255, 13, 447, 347, 233, 0}, + {1, 1, 1, 11, 15, 63, 11, 221, 53, 185, 777, 261, 0}, + {1, 1, 1, 3, 23, 47, 95, 115, 17, 43, 1083, 1137, 0}, + {1, 3, 7, 7, 25, 9, 95, 175, 171, 729, 363, 3993, 0}, + {1, 1, 5, 13, 13, 63, 17, 19, 299, 577, 269, 3619, 0}, + {1, 1, 5, 15, 21, 15, 111, 129, 41, 863, 1015, 2881, 0}, + {1, 1, 7, 1, 15, 25, 105, 5, 79, 735, 1809, 1275, 0}, + {1, 3, 5, 7, 3, 25, 41, 209, 3, 317, 1105, 3865, 0}, + {1, 3, 1, 11, 29, 15, 115, 197, 485, 99, 1429, 1299, 0}, + {1, 3, 1, 1, 29, 41, 5, 57, 331, 17, 1471, 3757, 0}, + {1, 1, 5, 13, 5, 13, 69, 177, 13, 477, 2019, 1193, 0}, + {1, 3, 5, 1, 25, 3, 101, 115, 257, 893, 381, 733, 0}, + {1, 1, 5, 15, 17, 19, 27, 187, 59, 537, 2025, 993, 0}, + {1, 1, 5, 1, 11, 51, 27, 119, 201, 519, 1223, 1153, 0}, + {1, 3, 5, 9, 7, 49, 101, 77, 497, 1017, 827, 2945, 0}, + {1, 3, 5, 7, 15, 37, 103, 211, 81, 375, 1733, 3163, 0}, + {1, 3, 1, 3, 5, 25, 53, 111, 451, 297, 887, 3179, 0}, + {1, 1, 3, 9, 21, 49, 9, 33, 199, 325, 1321, 437, 0}, + {1, 3, 1, 11, 7, 13, 21, 113, 171, 999, 803, 271, 0}, + {1, 3, 5, 1, 31, 53, 43, 23, 81, 353, 1951, 3493, 0}, + {1, 1, 7, 9, 13, 47, 79, 87, 253, 343, 1297, 3971, 0}, + {1, 3, 3, 13, 11, 23, 91, 137, 365, 729, 1995, 1005, 0}, + {1, 1, 3, 13, 23, 35, 65, 41, 75, 135, 833, 2615, 0}, + {1, 3, 5, 3, 5, 29, 117, 7, 451, 489, 1107, 2253, 0}, + {1, 3, 7, 11, 7, 33, 87, 83, 149, 859, 1135, 1131, 0}, + {1, 1, 3, 7, 23, 21, 125, 43, 483, 267, 1181, 585, 0}, + {1, 3, 7, 9, 27, 35, 55, 121, 81, 141, 1251, 2775, 0}, + {1, 3, 1, 1, 21, 23, 45, 145, 453, 831, 983, 2171, 0}, + {1, 3, 7, 7, 29, 3, 63, 5, 469, 141, 1389, 2383, 0}, + {1, 1, 7, 15, 15, 43, 85, 219, 485, 893, 1565, 2937, 0}, + {1, 1, 1, 9, 7, 31, 83, 27, 305, 249, 273, 2447, 0}, + {1, 3, 3, 1, 27, 63, 97, 11, 163, 807, 137, 1745, 0}, + {1, 3, 5, 5, 27, 9, 45, 111, 401, 53, 71, 663, 0}, + {1, 1, 1, 13, 19, 1, 83, 207, 15, 613, 735, 1515, 0}, + {1, 3, 5, 5, 7, 61, 87, 55, 91, 131, 1005, 3767, 0}, + {1, 1, 5, 11, 15, 43, 113, 97, 3, 547, 933, 2709, 0}, + {1, 3, 3, 3, 27, 3, 93, 63, 129, 977, 67, 1767, 0}, + {1, 1, 7, 9, 27, 11, 95, 229, 35, 131, 1471, 3185, 0}, + {1, 1, 3, 15, 19, 55, 5, 53, 239, 999, 551, 3017, 0}, + {1, 1, 7, 11, 19, 11, 17, 33, 355, 175, 457, 2815, 0}, + {1, 3, 7, 13, 9, 35, 77, 149, 211, 31, 1667, 1829, 0}, + {1, 3, 5, 5, 15, 1, 77, 23, 387, 341, 1729, 87, 0}, + {1, 3, 7, 1, 1, 63, 127, 187, 101, 739, 919, 3341, 0}, + {1, 3, 5, 7, 3, 35, 123, 153, 299, 467, 285, 793, 0}, + {1, 1, 7, 7, 29, 49, 45, 91, 67, 675, 1629, 2627, 0}, + {1, 3, 1, 5, 29, 19, 81, 193, 375, 241, 1815, 2169, 0}, + {1, 1, 1, 13, 5, 45, 85, 183, 405, 645, 653, 1875, 0}, + {1, 1, 5, 7, 27, 9, 121, 59, 357, 247, 1919, 3745, 0}, + {1, 3, 3, 7, 31, 57, 119, 211, 267, 391, 1039, 367, 0}, + {1, 1, 5, 9, 9, 51, 27, 93, 363, 583, 531, 3783, 0}, + {1, 3, 1, 5, 1, 1, 85, 139, 79, 183, 393, 783, 0}, + {1, 1, 5, 11, 7, 47, 41, 59, 83, 973, 1411, 827, 0}, + {1, 1, 3, 11, 3, 41, 49, 179, 437, 433, 359, 3253, 0}, + {1, 1, 7, 1, 19, 9, 15, 163, 457, 367, 221, 2639, 0}, + {1, 3, 1, 1, 19, 11, 107, 209, 39, 131, 699, 2955, 0}, + {1, 1, 5, 15, 29, 37, 21, 77, 97, 467, 1485, 3539, 0}, + {1, 3, 7, 3, 9, 19, 51, 39, 473, 571, 471, 1579, 0}, + {1, 1, 7, 13, 3, 55, 119, 111, 289, 309, 1357, 2109, 0}, + {1, 3, 3, 9, 21, 23, 11, 79, 179, 385, 1715, 379, 0}, + {1, 1, 5, 13, 31, 55, 87, 229, 57, 977, 595, 2939, 0}, + {1, 3, 1, 9, 29, 55, 101, 85, 23, 111, 1677, 3019, 0}, + {1, 3, 3, 9, 25, 13, 115, 237, 49, 917, 153, 1999, 0}, + {1, 3, 5, 11, 1, 7, 63, 199, 79, 935, 1903, 2253, 0}, + {1, 3, 1, 5, 3, 47, 63, 137, 71, 473, 1281, 2911, 0}, + {1, 3, 5, 5, 9, 37, 37, 147, 341, 345, 215, 3733, 0}, + {1, 3, 3, 13, 27, 11, 121, 25, 287, 411, 781, 481, 0}, + {1, 3, 3, 15, 5, 43, 109, 73, 95, 313, 543, 1767, 0}, + {1, 3, 3, 3, 27, 17, 7, 121, 229, 97, 293, 1055, 0}, + {1, 1, 7, 9, 25, 3, 43, 129, 271, 149, 1807, 4019, 0}, + {1, 3, 3, 15, 21, 25, 69, 83, 475, 959, 965, 4085, 0}, + {1, 3, 5, 3, 11, 19, 19, 87, 49, 841, 1695, 105, 0}, + {1, 3, 1, 11, 29, 55, 77, 93, 241, 839, 443, 1829, 0}, + {1, 3, 3, 11, 31, 59, 49, 205, 261, 669, 1985, 2097, 0}, + {1, 3, 7, 15, 27, 37, 71, 167, 495, 431, 321, 2379, 0}, + {1, 1, 7, 15, 21, 33, 59, 53, 353, 51, 879, 1567, 0}, + {1, 3, 3, 3, 29, 43, 35, 107, 381, 41, 1227, 2713, 0}, + {1, 1, 7, 11, 17, 1, 7, 229, 13, 301, 1915, 737, 0}, + {1, 3, 5, 15, 9, 5, 13, 213, 291, 247, 839, 3423, 0}, + {1, 3, 3, 15, 17, 21, 55, 95, 37, 1015, 1945, 3941, 0}, + {1, 3, 3, 3, 13, 5, 101, 219, 251, 377, 1993, 2659, 0}, + {1, 1, 1, 1, 11, 63, 127, 109, 105, 329, 1165, 3961, 0}, + {1, 3, 7, 3, 25, 49, 103, 175, 399, 945, 51, 1755, 0}, + {1, 1, 5, 1, 15, 61, 85, 13, 81, 269, 557, 3613, 0}, + {1, 3, 1, 3, 21, 21, 109, 209, 89, 67, 723, 1937, 0}, + {1, 1, 1, 3, 11, 51, 29, 97, 265, 979, 1491, 1559, 0}, + {1, 3, 3, 1, 19, 15, 61, 61, 507, 581, 817, 2287, 0}, + {1, 3, 7, 3, 31, 19, 67, 147, 205, 643, 1237, 2743, 0}, + {1, 1, 1, 13, 3, 43, 21, 19, 145, 823, 947, 67, 0}, + {1, 3, 7, 1, 19, 47, 111, 13, 331, 557, 1215, 2859, 0}, + {1, 3, 1, 11, 5, 17, 67, 123, 129, 91, 1911, 325, 0}, + {1, 3, 7, 5, 3, 9, 23, 73, 119, 405, 1225, 2601, 0}, + {1, 3, 3, 15, 3, 53, 57, 35, 503, 117, 1965, 1149, 0}, + {1, 3, 7, 7, 9, 45, 75, 141, 249, 801, 1889, 3259, 0}, + {1, 3, 3, 15, 13, 11, 71, 81, 1, 509, 1503, 2403, 0}, + {1, 3, 5, 9, 13, 51, 101, 19, 289, 347, 1177, 3947, 0}, + {1, 3, 7, 1, 3, 25, 123, 171, 463, 893, 73, 2011, 0}, + {1, 3, 3, 7, 29, 11, 41, 255, 163, 303, 1767, 175, 0}, + {1, 1, 5, 1, 7, 25, 107, 111, 443, 227, 303, 3389, 0}, + {1, 1, 3, 9, 5, 47, 101, 107, 63, 783, 177, 3915, 0}, + {1, 1, 1, 11, 9, 47, 107, 233, 123, 555, 1897, 1315, 0}, + {1, 1, 1, 15, 23, 1, 125, 113, 361, 867, 1401, 2447, 0}, + {1, 1, 1, 1, 13, 43, 27, 133, 261, 99, 321, 141, 0}, + {1, 1, 5, 13, 21, 29, 47, 89, 49, 703, 921, 359, 0}, + {1, 3, 7, 9, 23, 17, 119, 9, 429, 111, 217, 3609, 0}, + {1, 3, 7, 13, 21, 31, 41, 231, 137, 797, 1779, 3933, 0}, + {1, 1, 3, 11, 31, 15, 19, 95, 355, 873, 327, 729, 0}, + {1, 1, 3, 7, 11, 59, 127, 69, 175, 541, 1889, 2051, 0}, + {1, 3, 1, 3, 7, 27, 33, 33, 507, 919, 333, 1755, 0}, + {1, 3, 1, 7, 7, 63, 31, 1, 59, 513, 615, 2149, 0}, + {1, 1, 1, 3, 3, 11, 109, 253, 277, 343, 1665, 2107, 0}, + {1, 1, 5, 13, 23, 41, 7, 219, 391, 319, 1825, 1741, 0}, + {1, 1, 5, 7, 1, 51, 91, 253, 25, 517, 1639, 1051, 2319}, + {1, 3, 7, 9, 23, 29, 91, 247, 185, 135, 237, 3681, 653}, + {1, 3, 3, 7, 5, 7, 39, 129, 381, 871, 1205, 471, 1379}, + {1, 1, 1, 7, 9, 27, 125, 11, 197, 917, 361, 1055, 1675}, + {1, 1, 1, 3, 17, 63, 105, 251, 39, 285, 129, 845, 1951}, + {1, 3, 3, 3, 21, 31, 47, 221, 5, 663, 1655, 257, 7075}, + {1, 3, 3, 9, 1, 43, 125, 153, 429, 301, 983, 1559, 2087}, + {1, 3, 7, 9, 17, 3, 123, 35, 119, 15, 1089, 1061, 7147}, + {1, 3, 3, 7, 29, 29, 91, 103, 247, 763, 1171, 2803, 1427}, + {1, 1, 3, 5, 7, 39, 9, 239, 177, 89, 401, 2219, 893}, + {1, 1, 5, 11, 5, 3, 103, 7, 329, 323, 677, 1315, 171}, + {1, 3, 1, 13, 17, 59, 45, 27, 465, 757, 643, 1369, 2019}, + {1, 1, 3, 13, 13, 59, 23, 235, 421, 317, 749, 3211, 7235}, + {1, 3, 7, 7, 25, 1, 117, 181, 271, 807, 303, 4027, 5697}, + {1, 3, 3, 7, 17, 53, 9, 5, 467, 309, 1407, 105, 3615}, + {1, 1, 3, 15, 9, 63, 125, 207, 151, 1013, 1873, 11, 1961}, + {1, 3, 7, 9, 19, 23, 73, 53, 45, 345, 1579, 1077, 7517}, + {1, 3, 3, 5, 9, 63, 11, 149, 429, 499, 1491, 2857, 6849}, + {1, 1, 5, 5, 5, 47, 37, 155, 137, 279, 1393, 337, 2893}, + {1, 1, 7, 3, 7, 51, 61, 225, 471, 711, 1247, 3553, 1883}, + {1, 1, 5, 3, 21, 23, 79, 165, 11, 915, 789, 3503, 2863}, + {1, 3, 7, 13, 19, 61, 21, 137, 17, 411, 763, 3917, 2173}, + {1, 3, 7, 3, 13, 39, 5, 155, 409, 281, 49, 2665, 4543}, + {1, 3, 3, 9, 9, 47, 47, 201, 347, 193, 5, 3823, 73}, + {1, 1, 3, 3, 7, 21, 117, 97, 199, 739, 1607, 3403, 381}, + {1, 1, 5, 1, 3, 39, 67, 245, 463, 365, 1891, 3711, 3893}, + {1, 3, 1, 11, 9, 15, 53, 203, 177, 315, 735, 2085, 6045}, + {1, 3, 3, 1, 3, 3, 85, 47, 11, 375, 1557, 1103, 1643}, + {1, 3, 5, 3, 15, 9, 33, 39, 51, 809, 1909, 1641, 7669}, + {1, 3, 3, 11, 31, 57, 81, 35, 361, 469, 1765, 701, 1027}, + {1, 3, 1, 15, 29, 61, 121, 105, 95, 487, 1777, 4095, 1549}, + {1, 1, 3, 11, 29, 39, 47, 239, 497, 621, 1127, 2883, 3983}, + {1, 1, 5, 11, 25, 37, 61, 49, 163, 857, 813, 1435, 1985}, + {1, 1, 1, 11, 13, 21, 51, 15, 351, 975, 695, 653, 6589}, + {1, 3, 1, 9, 9, 51, 127, 253, 127, 537, 97, 2363, 7497}, + {1, 1, 3, 13, 21, 1, 29, 7, 395, 939, 731, 1597, 2745}, + {1, 3, 7, 7, 9, 23, 65, 237, 511, 585, 1503, 767, 2375}, + {1, 3, 7, 9, 31, 43, 45, 213, 327, 129, 1751, 869, 7047}, + {1, 1, 1, 15, 7, 27, 41, 55, 353, 625, 333, 1825, 1117}, + {1, 3, 5, 9, 15, 25, 95, 87, 49, 447, 769, 1117, 1171}, + {1, 3, 1, 11, 5, 11, 57, 199, 105, 129, 865, 1297, 1975}, + {1, 3, 3, 1, 31, 13, 73, 27, 151, 1017, 693, 501, 5199}, + {1, 3, 7, 3, 7, 21, 33, 175, 321, 133, 377, 505, 3915}, + {1, 1, 3, 3, 15, 43, 117, 49, 331, 83, 1919, 149, 3695}, + {1, 1, 7, 9, 27, 7, 61, 41, 329, 3, 957, 873, 8113}, + {1, 3, 3, 7, 25, 11, 111, 229, 509, 415, 1359, 2673, 4303}, + {1, 1, 5, 15, 19, 33, 59, 85, 107, 661, 1627, 551, 3773}, + {1, 1, 1, 13, 9, 55, 123, 3, 109, 53, 1039, 1499, 7705}, + {1, 3, 7, 13, 9, 1, 65, 149, 303, 115, 1783, 2793, 6855}, + {1, 1, 1, 7, 25, 37, 47, 179, 467, 903, 1065, 3277, 1675}, + {1, 3, 1, 15, 25, 35, 105, 129, 287, 49, 1665, 2143, 2245}, + {1, 1, 3, 9, 23, 27, 23, 185, 161, 79, 1917, 3663, 2817}, + {1, 3, 5, 13, 1, 61, 29, 249, 45, 55, 1947, 533, 1719}, + {1, 1, 3, 9, 9, 39, 107, 197, 385, 385, 991, 3991, 569}, + {1, 3, 7, 15, 7, 5, 37, 15, 289, 261, 1997, 575, 1021}, + {1, 3, 1, 13, 11, 19, 81, 97, 363, 345, 841, 1877, 2077}, + {1, 1, 5, 15, 15, 61, 67, 197, 331, 297, 459, 1009, 5945}, + {1, 1, 5, 9, 19, 61, 29, 139, 265, 199, 221, 3929, 1833}, + {1, 3, 1, 13, 15, 57, 115, 203, 407, 385, 327, 473, 2631}, + {1, 3, 1, 1, 27, 59, 119, 63, 37, 617, 1595, 3009, 4851}, + {1, 1, 3, 11, 17, 21, 75, 33, 433, 25, 1881, 2595, 6371}, + {1, 3, 1, 7, 11, 59, 73, 251, 315, 515, 1269, 3249, 833}, + {1, 3, 3, 11, 11, 61, 99, 217, 343, 275, 1007, 675, 7987}, + {1, 1, 3, 3, 31, 57, 103, 199, 63, 849, 129, 3593, 331}, + {1, 3, 7, 13, 13, 25, 7, 199, 51, 401, 1413, 2453, 1899}, + {1, 3, 1, 5, 25, 55, 57, 99, 185, 471, 475, 1567, 8093}, + {1, 1, 7, 1, 25, 27, 45, 249, 71, 377, 1105, 973, 6719}, + {1, 1, 3, 7, 9, 31, 61, 33, 27, 661, 791, 595, 6903}, + {1, 3, 1, 15, 7, 41, 95, 229, 267, 535, 1983, 1335, 5903}, + {1, 1, 7, 3, 13, 33, 49, 177, 503, 505, 1359, 1715, 5657}, + {1, 3, 3, 13, 29, 63, 101, 13, 239, 939, 503, 589, 5007}, + {1, 3, 1, 7, 19, 19, 101, 209, 293, 465, 691, 85, 2689}, + {1, 1, 7, 13, 5, 57, 35, 147, 245, 225, 659, 2265, 6637}, + {1, 1, 3, 13, 19, 35, 47, 97, 281, 929, 691, 3069, 2675}, + {1, 3, 5, 11, 31, 13, 119, 31, 297, 219, 343, 461, 1645}, + {1, 1, 3, 3, 25, 63, 39, 125, 75, 955, 1375, 1659, 1819}, + {1, 3, 5, 5, 13, 35, 67, 177, 461, 659, 1919, 2627, 689}, + {1, 1, 7, 3, 25, 17, 31, 137, 371, 441, 263, 1307, 6709}, + {1, 3, 3, 13, 15, 11, 103, 187, 129, 117, 1373, 1731, 7717}, + {1, 1, 3, 11, 5, 11, 7, 11, 189, 527, 603, 1501, 6295}, + {1, 1, 3, 9, 9, 49, 61, 91, 189, 427, 1383, 1699, 7013}, + {1, 3, 5, 9, 29, 41, 127, 223, 339, 515, 297, 3545, 7695}, + {1, 3, 1, 3, 31, 55, 87, 29, 287, 287, 781, 3803, 3705}, + {1, 1, 7, 11, 9, 5, 3, 169, 111, 191, 145, 2157, 7069}, + {1, 1, 7, 11, 29, 45, 35, 231, 111, 33, 285, 453, 2621}, + {1, 1, 1, 7, 27, 17, 29, 59, 379, 389, 767, 2813, 3631}, + {1, 3, 3, 9, 25, 35, 73, 31, 93, 197, 1739, 2047, 6571}, + {1, 3, 1, 13, 27, 5, 95, 163, 27, 825, 1715, 2999, 6259}, + {1, 1, 3, 11, 11, 31, 103, 41, 185, 63, 715, 3841, 7261}, + {1, 3, 7, 7, 17, 31, 71, 57, 347, 417, 317, 2361, 3397}, + {1, 1, 7, 15, 5, 37, 75, 87, 337, 949, 1333, 1079, 7645}, + {1, 1, 1, 13, 17, 17, 51, 247, 247, 35, 85, 573, 1115}, + {1, 3, 3, 7, 3, 45, 87, 25, 507, 571, 831, 69, 4753}, + {1, 3, 7, 5, 23, 51, 57, 127, 161, 9, 1615, 1363, 2047}, + {1, 1, 3, 3, 15, 1, 97, 101, 231, 131, 81, 1597, 7579}, + {1, 1, 1, 1, 9, 39, 11, 207, 43, 609, 1667, 3427, 2271}, + {1, 3, 5, 5, 9, 49, 105, 187, 499, 439, 1467, 2899, 5403}, + {1, 1, 3, 15, 17, 55, 87, 73, 73, 95, 1457, 2771, 4911}, + {1, 3, 1, 15, 17, 19, 41, 61, 327, 19, 1453, 1327, 7629}, + {1, 1, 1, 3, 31, 41, 73, 105, 263, 569, 1825, 1117, 4225}, + {1, 1, 1, 11, 11, 13, 109, 27, 331, 893, 109, 1523, 1209}, + {1, 1, 5, 1, 19, 5, 69, 91, 249, 451, 387, 3521, 6955}, + {1, 1, 3, 7, 25, 51, 35, 171, 493, 397, 1207, 2393, 6951}, + {1, 1, 3, 3, 13, 5, 121, 243, 37, 971, 2039, 2537, 1829}, + {1, 3, 7, 15, 23, 49, 39, 33, 25, 801, 213, 1979, 5579}, + {1, 1, 1, 11, 15, 1, 111, 3, 115, 125, 1351, 3179, 5231}, + {1, 1, 5, 5, 25, 21, 1, 1, 3, 471, 1329, 683, 1783}, + {1, 1, 3, 5, 21, 13, 77, 21, 167, 187, 1173, 2453, 4285}, + {1, 1, 5, 3, 31, 17, 39, 229, 197, 257, 57, 453, 7425}, + {1, 3, 1, 5, 19, 59, 47, 93, 127, 67, 1769, 1227, 599}, + {1, 1, 3, 5, 3, 51, 53, 71, 357, 949, 951, 779, 5785}, + {1, 3, 1, 1, 11, 11, 91, 61, 497, 621, 183, 671, 3275}, + {1, 1, 3, 15, 25, 3, 3, 37, 103, 453, 23, 3483, 5643}, + {1, 1, 1, 5, 7, 61, 17, 183, 125, 411, 451, 2135, 2263}, + {1, 3, 5, 1, 15, 1, 51, 65, 191, 621, 1155, 3139, 657}, + {1, 3, 7, 5, 19, 33, 83, 211, 165, 955, 1551, 3381, 6769}, + {1, 1, 7, 3, 7, 37, 39, 53, 55, 309, 2037, 3945, 6261}, + {1, 1, 1, 7, 5, 33, 125, 11, 101, 783, 811, 57, 1251}, + {1, 3, 1, 5, 3, 61, 85, 151, 95, 893, 635, 1541, 3249}, + {1, 1, 5, 11, 13, 25, 111, 165, 79, 597, 1671, 3405, 4447}, + {1, 3, 3, 3, 13, 27, 21, 47, 351, 377, 1451, 3381, 4111}, + {1, 1, 1, 13, 1, 59, 69, 5, 341, 753, 863, 2371, 3991}, + {1, 3, 5, 9, 23, 7, 85, 129, 43, 145, 1499, 2879, 1215}, + {1, 3, 1, 13, 5, 49, 29, 79, 125, 637, 1673, 1985, 131}, + {1, 3, 1, 15, 25, 13, 55, 101, 135, 941, 363, 987, 4397}, + {1, 1, 7, 5, 11, 63, 11, 147, 173, 593, 1029, 3017, 3487}, + {1, 3, 7, 3, 25, 3, 117, 169, 289, 317, 1077, 3031, 7585}, + {1, 3, 3, 5, 15, 33, 1, 181, 373, 555, 1525, 3839, 5565}, + {1, 3, 5, 9, 13, 3, 47, 19, 133, 375, 277, 1401, 7199}, + {1, 1, 5, 5, 21, 15, 17, 95, 421, 575, 1023, 3749, 3573}, + {1, 1, 1, 3, 11, 9, 65, 77, 241, 175, 655, 2977, 7105}, + {1, 3, 7, 11, 23, 13, 63, 139, 281, 403, 665, 681, 7409}, + {1, 3, 1, 1, 29, 35, 47, 197, 213, 571, 1869, 1175, 1671}, + {1, 3, 5, 13, 5, 39, 117, 219, 177, 555, 1255, 1519, 949}, + {1, 1, 1, 9, 17, 11, 17, 97, 363, 109, 965, 3355, 3889}, + {1, 1, 1, 15, 27, 59, 115, 239, 151, 377, 277, 907, 5971}, + {1, 1, 3, 3, 9, 59, 51, 183, 227, 931, 1601, 117, 3333}, + {1, 1, 1, 5, 19, 1, 25, 143, 145, 499, 329, 771, 225}, + {1, 3, 5, 11, 15, 57, 33, 9, 363, 649, 1603, 3741, 3647}, + {1, 1, 7, 9, 5, 11, 123, 13, 239, 653, 1901, 3337, 5403}, + {1, 3, 5, 1, 29, 5, 123, 209, 431, 329, 395, 1743, 3409}, + {1, 1, 7, 3, 23, 57, 83, 23, 81, 279, 65, 1227, 7459}, + {1, 3, 7, 15, 19, 13, 51, 215, 397, 271, 1307, 3335, 6879}, + {1, 1, 1, 9, 1, 31, 113, 53, 241, 647, 2029, 2755, 5789}, + {1, 1, 5, 9, 27, 13, 95, 137, 67, 721, 21, 1909, 6567}, + {1, 3, 1, 9, 3, 11, 121, 203, 291, 665, 1321, 3603, 5581}, + {1, 3, 1, 11, 23, 55, 51, 19, 255, 429, 543, 2397, 4919}, + {1, 1, 3, 7, 21, 45, 91, 151, 405, 957, 1569, 653, 1927}, + {1, 1, 5, 5, 19, 9, 109, 171, 421, 803, 1185, 87, 4407}, + {1, 1, 1, 13, 27, 55, 43, 133, 399, 767, 1905, 2025, 8085}, + {1, 3, 5, 1, 11, 55, 55, 219, 75, 425, 1701, 2617, 4691}, + {1, 3, 5, 15, 17, 19, 35, 231, 399, 477, 413, 3257, 611}, + {1, 1, 3, 3, 13, 25, 55, 3, 105, 995, 2041, 287, 3005}, + {1, 3, 1, 13, 27, 41, 87, 15, 329, 105, 1697, 3051, 591}, + {1, 1, 3, 9, 11, 23, 33, 253, 41, 495, 725, 3809, 753}, + {1, 3, 1, 13, 31, 45, 37, 225, 425, 575, 1417, 897, 589}, + {1, 1, 5, 5, 23, 29, 5, 33, 7, 687, 1847, 2215, 171}, + {1, 1, 5, 1, 5, 63, 3, 111, 283, 385, 411, 63, 5729}, + {1, 1, 3, 5, 9, 59, 45, 183, 375, 227, 211, 2043, 5891}, + {1, 1, 3, 1, 21, 27, 21, 213, 475, 923, 915, 1757, 1033}, + {1, 1, 3, 13, 31, 39, 105, 169, 427, 563, 1891, 3671, 3049}, + {1, 1, 3, 13, 29, 21, 127, 119, 277, 723, 17, 297, 6567}, + {1, 3, 1, 7, 11, 37, 35, 111, 209, 481, 1877, 3131, 5257}, + {1, 1, 1, 7, 21, 7, 17, 15, 411, 717, 1699, 1305, 8003}, + {1, 3, 3, 1, 17, 61, 35, 201, 3, 111, 687, 293, 1757}, + {1, 3, 1, 9, 15, 49, 37, 123, 137, 633, 1089, 3865, 4489}, + {1, 1, 3, 5, 7, 35, 97, 121, 195, 113, 1973, 3173, 4923}, + {1, 3, 5, 11, 15, 39, 97, 225, 289, 369, 1809, 3397, 6379}, + {1, 3, 5, 9, 7, 9, 21, 113, 509, 955, 851, 2269, 5171}, + {1, 3, 7, 11, 9, 29, 77, 113, 121, 253, 1495, 3673, 1757}, + {1, 1, 5, 13, 21, 7, 123, 225, 55, 321, 1257, 717, 689}, + {1, 3, 5, 3, 27, 25, 17, 161, 147, 409, 63, 3041, 3081}, + {1, 1, 7, 15, 25, 23, 89, 165, 275, 909, 1323, 3341, 1389}, + {1, 1, 5, 15, 29, 57, 53, 1, 251, 367, 1307, 3595, 4113}, + {1, 3, 7, 13, 11, 5, 105, 139, 19, 33, 609, 3819, 455}, + {1, 3, 1, 15, 3, 19, 75, 55, 129, 967, 881, 2871, 2761}, + {1, 1, 3, 7, 21, 15, 25, 3, 285, 453, 1543, 3973, 847}, + {1, 1, 7, 5, 13, 33, 125, 93, 415, 863, 177, 1129, 7575}, + {1, 3, 7, 7, 23, 49, 13, 217, 487, 449, 617, 513, 5829}, + {1, 3, 3, 9, 19, 37, 47, 193, 491, 539, 1505, 871, 633}, + {1, 1, 5, 7, 27, 25, 21, 97, 193, 781, 1747, 1485, 6629}, + {1, 1, 5, 9, 17, 17, 125, 29, 219, 911, 1537, 3977, 1103}, + {1, 1, 7, 9, 29, 45, 23, 69, 403, 113, 925, 2473, 7635}, + {1, 3, 5, 9, 25, 29, 55, 231, 23, 7, 183, 1171, 803}, + {1, 1, 5, 11, 17, 15, 63, 161, 97, 219, 77, 1143, 6175}, + {1, 3, 3, 9, 9, 25, 61, 93, 65, 725, 1723, 3063, 6587}, + {1, 3, 3, 3, 1, 3, 5, 69, 285, 1015, 1877, 3547, 2711}, + {1, 1, 3, 11, 19, 3, 17, 143, 75, 971, 1703, 2183, 3879}, + {1, 1, 1, 15, 23, 49, 93, 137, 21, 1021, 397, 3993, 67}, + {1, 3, 7, 13, 5, 11, 57, 9, 373, 525, 459, 133, 1179}, + {1, 1, 1, 13, 23, 39, 121, 87, 261, 785, 521, 2529, 4761}, + {1, 1, 5, 5, 1, 15, 69, 183, 339, 873, 257, 2699, 7281}, + {1, 3, 5, 9, 17, 19, 73, 113, 239, 191, 1177, 233, 1557}, + {1, 1, 5, 15, 17, 57, 93, 183, 495, 893, 389, 2355, 3379}, + {1, 3, 3, 1, 13, 39, 121, 73, 415, 297, 1947, 231, 2459}, + {1, 1, 3, 1, 27, 15, 105, 215, 333, 507, 1553, 3241, 4273}, + {1, 1, 5, 9, 23, 11, 75, 137, 107, 215, 1583, 611, 4127}, + {1, 1, 1, 5, 7, 3, 91, 89, 435, 21, 1831, 1309, 7147}, + {1, 3, 3, 13, 7, 57, 67, 251, 297, 153, 261, 3829, 35}, + {1, 3, 1, 3, 11, 31, 95, 163, 213, 645, 485, 1839, 3549}, + {1, 3, 3, 13, 13, 55, 75, 41, 149, 913, 289, 1495, 395}, + {1, 3, 3, 15, 17, 61, 9, 227, 463, 755, 1281, 301, 3735}, + {1, 1, 3, 3, 13, 19, 69, 145, 199, 371, 1543, 1169, 5787}, + {1, 1, 7, 1, 11, 5, 97, 57, 323, 881, 1591, 1613, 4179}, + {1, 3, 1, 3, 21, 41, 99, 81, 45, 113, 1123, 2673, 5889}, + {1, 3, 7, 11, 13, 35, 93, 57, 19, 903, 573, 243, 5057}, + {1, 1, 7, 13, 23, 59, 11, 11, 301, 225, 821, 3601, 7473}, + {1, 1, 3, 1, 1, 61, 53, 135, 121, 49, 1065, 3669, 4713}, + {1, 1, 7, 15, 27, 39, 19, 145, 499, 587, 1933, 2813, 2133}, + {1, 1, 1, 9, 13, 41, 73, 161, 187, 201, 1373, 2671, 2897}, + {1, 3, 1, 9, 9, 53, 5, 175, 229, 927, 2005, 2679, 1841}, + {1, 1, 5, 3, 7, 53, 33, 159, 63, 429, 905, 3463, 2125}, + {1, 1, 7, 1, 1, 63, 79, 25, 425, 599, 207, 2477, 1029}, + {1, 3, 1, 9, 27, 31, 107, 55, 99, 513, 173, 1795, 1695}, + {1, 3, 7, 1, 29, 9, 65, 167, 281, 97, 1573, 617, 6523}, + {1, 3, 1, 9, 5, 59, 69, 157, 35, 319, 1597, 2317, 1143}, + {1, 1, 7, 1, 13, 13, 79, 211, 125, 331, 573, 1855, 5105}, + {1, 1, 7, 13, 25, 35, 125, 97, 349, 833, 1883, 1057, 7133}, + {1, 3, 1, 11, 21, 55, 25, 247, 87, 325, 1795, 1703, 3351}, + {1, 3, 3, 15, 3, 41, 93, 249, 101, 887, 1499, 1761, 2775}, + {1, 1, 7, 7, 31, 49, 55, 23, 59, 139, 1743, 2515, 3971}, + {1, 3, 5, 11, 15, 5, 61, 129, 195, 927, 553, 801, 4503}, + {1, 3, 1, 15, 13, 41, 17, 159, 511, 399, 335, 1205, 7589}, + {1, 1, 3, 13, 3, 25, 117, 71, 355, 163, 333, 1311, 5155}, + {1, 1, 5, 15, 19, 27, 69, 197, 73, 307, 1645, 473, 4305}, + {1, 3, 5, 1, 13, 43, 97, 127, 263, 803, 791, 3963, 1641}, + {1, 3, 5, 9, 1, 5, 87, 141, 243, 169, 871, 697, 4717}, + {1, 3, 1, 9, 27, 5, 111, 219, 101, 1019, 1157, 1221, 2427}, + {1, 3, 1, 7, 15, 43, 37, 5, 165, 869, 969, 251, 5617}, + {1, 3, 7, 3, 17, 5, 93, 233, 141, 537, 557, 381, 1267}, + {1, 3, 1, 5, 1, 5, 59, 131, 11, 907, 141, 3887, 399}, + {1, 3, 7, 11, 3, 17, 79, 217, 389, 479, 223, 1761, 5831}, + {1, 1, 1, 7, 13, 5, 95, 101, 219, 335, 1129, 3093, 4305}, + {1, 3, 7, 3, 13, 15, 53, 131, 187, 697, 1685, 3721, 4241}, + {1, 3, 7, 9, 13, 27, 115, 33, 449, 479, 423, 2079, 3395}, + {1, 1, 3, 5, 31, 29, 53, 157, 447, 353, 1069, 4085, 3045}, + {1, 3, 1, 15, 29, 17, 85, 173, 393, 769, 391, 379, 4899}, + {1, 1, 1, 7, 27, 9, 85, 69, 477, 787, 99, 3601, 1713}, + {1, 3, 5, 5, 7, 3, 65, 207, 305, 1023, 95, 3845, 171}, + {1, 1, 1, 3, 7, 55, 59, 239, 221, 855, 1847, 433, 411}, + {1, 1, 5, 13, 21, 31, 23, 81, 51, 493, 531, 1781, 7099}, + {1, 3, 1, 7, 29, 1, 75, 205, 355, 883, 1859, 29, 5473}, + {1, 3, 5, 1, 15, 45, 21, 11, 209, 521, 1833, 1897, 5209}, + {1, 1, 3, 1, 17, 45, 67, 41, 499, 735, 1833, 1599, 1195}, + {1, 1, 5, 9, 17, 13, 27, 169, 479, 297, 341, 2163, 1077}, + {1, 1, 5, 15, 21, 57, 99, 65, 265, 1011, 237, 75, 1309}, + {1, 3, 5, 15, 19, 17, 79, 193, 377, 991, 1997, 3475, 2953}, + {1, 1, 5, 15, 17, 3, 27, 77, 145, 879, 1799, 3957, 7343}, + {1, 3, 5, 11, 3, 61, 3, 201, 411, 855, 409, 1641, 4887}, + {1, 3, 3, 3, 15, 15, 95, 173, 173, 591, 431, 3911, 3229}, + {1, 1, 3, 5, 5, 49, 27, 1, 11, 415, 1917, 2959, 6759}, + {1, 3, 7, 15, 27, 15, 69, 221, 433, 917, 363, 2833, 6721}, + {1, 3, 3, 13, 27, 47, 19, 157, 483, 375, 335, 1279, 6775}, + {1, 1, 3, 7, 3, 9, 75, 1, 135, 453, 1039, 1099, 675}, + {1, 3, 5, 15, 31, 37, 47, 15, 385, 553, 1085, 403, 4039}, + {1, 1, 5, 15, 31, 45, 59, 113, 341, 189, 1657, 799, 2493}, + {1, 1, 3, 11, 7, 9, 41, 147, 89, 841, 1975, 2183, 7511}, + {1, 3, 7, 11, 21, 51, 85, 137, 209, 339, 1527, 2699, 3269}, + {1, 3, 1, 9, 3, 61, 77, 205, 391, 211, 1111, 1711, 4199}, + {1, 3, 5, 5, 13, 21, 99, 225, 33, 601, 659, 2037, 6625}, + {1, 1, 7, 15, 11, 33, 55, 73, 395, 57, 389, 727, 7943}, + {1, 1, 5, 9, 17, 11, 49, 45, 319, 765, 899, 289, 2013}, + {1, 1, 1, 7, 27, 21, 93, 49, 451, 745, 595, 1785, 4145}, + {1, 3, 5, 3, 25, 63, 93, 149, 119, 621, 1439, 1575, 667}, + {1, 1, 5, 13, 1, 63, 119, 113, 341, 209, 1861, 3633, 513}, + {1, 1, 3, 1, 9, 47, 51, 253, 227, 875, 1979, 2367, 2303}, + {1, 1, 5, 1, 7, 57, 125, 99, 375, 639, 1569, 1261, 4591}, + {1, 3, 5, 5, 29, 61, 63, 17, 61, 7, 1087, 3953, 7941}, + {1, 3, 7, 1, 27, 49, 13, 119, 331, 595, 1009, 1735, 2741}, + {1, 3, 5, 3, 21, 9, 15, 105, 493, 971, 165, 171, 987}, + {1, 1, 3, 1, 23, 59, 45, 117, 411, 263, 1895, 1959, 8061}, + {1, 3, 5, 7, 13, 19, 61, 129, 293, 1009, 1481, 2867, 3161}, + {1, 3, 5, 1, 25, 29, 19, 243, 47, 201, 1583, 859, 5951}, + {1, 1, 5, 1, 29, 21, 105, 75, 203, 23, 29, 2951, 1431}, + {1, 3, 1, 5, 15, 23, 115, 203, 375, 77, 1193, 3211, 831}, + {1, 1, 5, 1, 17, 55, 17, 53, 167, 621, 1673, 15, 5559}, + {1, 1, 5, 11, 29, 23, 83, 29, 395, 33, 1075, 1279, 7405}, + {1, 3, 5, 11, 9, 43, 7, 247, 155, 535, 301, 1323, 1357}, + {1, 3, 5, 9, 15, 41, 7, 35, 5, 963, 1081, 599, 4319}, + {1, 3, 1, 9, 3, 57, 11, 247, 237, 661, 1377, 1651, 4235}, + {1, 1, 3, 5, 21, 9, 61, 171, 361, 523, 1747, 3951, 5421}, + {1, 3, 5, 13, 15, 39, 37, 31, 489, 263, 1497, 1011, 2559}, + {1, 3, 3, 7, 17, 27, 63, 199, 127, 917, 1103, 315, 4415}, + {1, 1, 1, 7, 17, 41, 89, 213, 21, 103, 1789, 3513, 2439}, + {1, 1, 7, 7, 31, 35, 95, 29, 345, 623, 887, 3351, 823}, + {1, 1, 5, 1, 9, 61, 119, 251, 101, 231, 739, 1725, 1725}, + {1, 3, 5, 1, 9, 29, 113, 7, 371, 47, 1577, 3793, 6219}, + {1, 1, 7, 9, 23, 57, 67, 251, 233, 301, 313, 2399, 4903}, + {1, 3, 1, 9, 19, 63, 123, 187, 431, 549, 1367, 287, 6699}, + {1, 3, 5, 11, 25, 21, 91, 91, 109, 337, 1299, 4017, 5451}, + {1, 3, 3, 11, 3, 31, 33, 11, 119, 675, 1801, 3571, 349}, + {1, 3, 3, 15, 1, 59, 37, 149, 277, 189, 1131, 1007, 7703}, + {1, 3, 1, 7, 11, 35, 99, 13, 125, 357, 1837, 541, 2927}, + {1, 3, 5, 5, 27, 49, 43, 205, 263, 1005, 73, 3115, 7809}, + {1, 3, 3, 5, 29, 3, 11, 37, 73, 789, 1865, 429, 6179}, + {1, 3, 7, 3, 1, 49, 33, 249, 135, 189, 1065, 1585, 1417}, + {1, 1, 1, 11, 31, 47, 65, 137, 123, 319, 843, 1285, 5987}, + {1, 3, 7, 1, 29, 49, 81, 139, 83, 721, 635, 755, 3017}, + {1, 3, 5, 3, 25, 33, 79, 9, 123, 1005, 55, 1211, 4983}, + {1, 1, 1, 7, 29, 21, 81, 7, 405, 525, 1655, 3047, 3479}, + {1, 3, 1, 13, 1, 19, 107, 113, 69, 675, 913, 915, 4525}, + {1, 1, 3, 7, 23, 21, 63, 183, 75, 539, 1037, 3611, 4643}, + {1, 1, 1, 7, 29, 35, 63, 205, 287, 191, 223, 2697, 4911}, + {1, 3, 1, 7, 25, 11, 55, 187, 401, 813, 1871, 2129, 227}, + {1, 3, 7, 3, 13, 17, 89, 39, 23, 917, 1161, 3669, 5475}, + {1, 3, 1, 15, 3, 37, 91, 3, 283, 51, 461, 81, 2287}, + {1, 1, 5, 15, 31, 23, 25, 79, 393, 167, 479, 3939, 5581}, + {1, 3, 5, 11, 25, 59, 93, 155, 41, 415, 511, 2437, 6817}, + {1, 3, 3, 9, 5, 13, 101, 227, 379, 579, 1721, 915, 1937}, + {1, 3, 7, 3, 5, 37, 27, 89, 431, 755, 1107, 779, 1421}, + {1, 3, 3, 9, 11, 35, 55, 185, 11, 605, 389, 3567, 4415}, + {1, 3, 7, 3, 3, 55, 75, 51, 475, 721, 151, 3701, 7977}, + {1, 1, 5, 15, 21, 57, 121, 127, 505, 837, 35, 2479, 1789}, + {1, 3, 3, 13, 9, 1, 79, 63, 19, 529, 375, 3807, 3907}, + {1, 3, 1, 5, 23, 29, 43, 83, 365, 31, 1099, 1893, 6815}, + {1, 3, 1, 3, 7, 45, 125, 41, 265, 327, 937, 3927, 6789}, + {1, 1, 3, 3, 11, 11, 73, 133, 271, 799, 1185, 2619, 6003}, + {1, 1, 1, 3, 23, 1, 27, 183, 499, 961, 1701, 2543, 5609}, + {1, 1, 3, 5, 11, 15, 109, 181, 489, 279, 769, 3633, 4507}, + {1, 3, 5, 9, 1, 9, 35, 127, 443, 409, 639, 2007, 337}, + {1, 3, 5, 15, 1, 33, 21, 19, 165, 847, 1633, 3857, 7427}, + {1, 1, 7, 9, 3, 19, 71, 255, 91, 649, 1609, 3837, 7943}, + {1, 3, 5, 9, 23, 53, 113, 219, 83, 241, 379, 487, 3075}, + {1, 3, 3, 1, 25, 43, 89, 59, 291, 285, 1613, 1769, 6427}, + {1, 1, 7, 5, 23, 39, 59, 251, 319, 545, 2031, 3759, 1019}, + {1, 3, 7, 9, 1, 23, 95, 3, 199, 407, 685, 3105, 7121}, + {1, 1, 7, 9, 23, 7, 41, 187, 107, 161, 289, 2727, 4763}, + {1, 3, 3, 15, 3, 13, 45, 57, 245, 591, 975, 3155, 81}, + {1, 1, 7, 5, 27, 13, 113, 217, 389, 73, 671, 2479, 3587}, + {1, 3, 3, 15, 9, 1, 119, 115, 143, 313, 1599, 1341, 2929}, + {1, 1, 7, 7, 27, 19, 113, 217, 137, 811, 1447, 1657, 1795}, + {1, 3, 1, 9, 3, 41, 39, 229, 89, 17, 871, 2767, 8067}, + {1, 3, 3, 1, 23, 55, 59, 181, 125, 663, 647, 2541, 2415}, + {1, 3, 1, 9, 25, 1, 73, 185, 281, 269, 99, 577, 1265}, + {1, 3, 7, 9, 19, 13, 15, 149, 381, 261, 139, 2105, 4025}, + {1, 3, 7, 5, 29, 15, 13, 83, 215, 37, 1427, 799, 5599}, + {1, 3, 1, 11, 29, 59, 59, 115, 131, 783, 959, 17, 4771}, + {1, 1, 7, 5, 13, 55, 67, 11, 299, 127, 89, 2871, 3025}, + {1, 1, 3, 15, 27, 15, 121, 123, 249, 917, 117, 3637, 2313}, + {1, 3, 7, 15, 5, 3, 27, 19, 375, 231, 841, 953, 6129}, + {1, 1, 3, 11, 9, 57, 7, 109, 455, 577, 891, 65, 7611}, + {1, 3, 7, 7, 29, 37, 105, 165, 43, 975, 1959, 69, 6881}, + {1, 1, 3, 7, 29, 31, 15, 103, 73, 793, 223, 2897, 5253}, + {1, 1, 7, 7, 13, 17, 59, 123, 281, 921, 1697, 3841, 4413}, + {1, 1, 3, 1, 17, 1, 59, 219, 217, 343, 1145, 3559, 7869}, + {1, 1, 5, 1, 3, 3, 35, 129, 297, 751, 499, 4067, 105}, + {1, 1, 1, 11, 23, 21, 91, 155, 229, 139, 1435, 2335, 3173}, + {1, 3, 1, 11, 19, 29, 89, 207, 431, 221, 1809, 3409, 1629}, + {1, 1, 7, 13, 7, 25, 23, 177, 357, 79, 1413, 1087, 2537}, + {1, 1, 3, 15, 13, 55, 125, 9, 81, 817, 1445, 425, 1023}, + {1, 1, 1, 3, 3, 9, 97, 49, 357, 393, 1675, 2813, 4409}, + {1, 3, 5, 13, 19, 37, 53, 181, 171, 545, 171, 1705, 7209}, + {1, 1, 5, 5, 23, 33, 41, 231, 451, 11, 1073, 1701, 4413}, + {1, 3, 7, 1, 5, 53, 91, 33, 481, 781, 1349, 1237, 7107}, + {1, 1, 1, 7, 29, 41, 111, 233, 13, 71, 1545, 821, 7469}, + {1, 1, 5, 1, 29, 51, 29, 67, 387, 1, 2039, 1375, 33}, + {1, 3, 5, 11, 13, 19, 31, 155, 491, 699, 1027, 3673, 1955}, + {1, 3, 5, 3, 13, 57, 3, 41, 489, 767, 1563, 2693, 2881}, + {1, 3, 7, 13, 5, 13, 103, 9, 439, 917, 859, 3925, 5167}, + {1, 1, 1, 15, 19, 63, 61, 95, 385, 9, 215, 1541, 6451}, + {1, 3, 5, 3, 5, 43, 71, 123, 487, 107, 1673, 1871, 4211}, + {1, 1, 5, 5, 17, 19, 35, 65, 177, 341, 1919, 2285, 179}, + {1, 3, 1, 3, 9, 7, 7, 117, 393, 587, 1633, 847, 5573}, + {1, 1, 5, 5, 11, 13, 119, 249, 33, 903, 779, 4035, 7879}, + {1, 1, 5, 7, 11, 37, 29, 85, 71, 965, 411, 1101, 3387}, + {1, 3, 3, 3, 29, 33, 45, 169, 375, 599, 1845, 2029, 7759}, + {1, 1, 1, 9, 27, 19, 49, 129, 443, 507, 1477, 855, 5455}, + {1, 3, 3, 9, 23, 15, 111, 241, 129, 843, 1489, 2733, 7157}, + {1, 3, 1, 5, 19, 63, 41, 173, 407, 739, 447, 2503, 1891}, + {1, 1, 7, 1, 17, 51, 109, 251, 395, 579, 1545, 121, 5683}, + {1, 3, 3, 7, 25, 11, 59, 225, 127, 397, 351, 2855, 5689}, + {1, 1, 1, 11, 13, 49, 125, 147, 65, 397, 1989, 1069, 6535}, + {1, 3, 3, 9, 1, 23, 13, 165, 333, 325, 495, 3463, 3109}, + {1, 3, 5, 3, 13, 57, 27, 69, 309, 775, 183, 3505, 6555}, + {1, 1, 7, 5, 3, 47, 19, 81, 119, 565, 1639, 1539, 6873}, + {1, 3, 7, 11, 11, 51, 79, 239, 197, 925, 1385, 607, 1249}, + {1, 3, 7, 13, 1, 15, 9, 95, 435, 75, 1805, 1349, 4251}, + {1, 1, 1, 13, 17, 53, 75, 23, 497, 55, 1097, 575, 6437}, + {1, 3, 1, 13, 29, 41, 83, 83, 373, 979, 1249, 2301, 49}, + {1, 3, 7, 9, 1, 1, 81, 227, 71, 931, 1431, 2321, 2745}, + {1, 3, 3, 15, 13, 15, 33, 249, 379, 93, 1571, 1101, 1201}, + {1, 3, 1, 5, 17, 37, 91, 143, 509, 957, 591, 333, 7327}, + {1, 3, 5, 7, 9, 61, 109, 171, 387, 857, 697, 291, 4179}, + {1, 3, 5, 1, 17, 11, 33, 193, 159, 753, 1509, 2171, 6783}, + {1, 1, 5, 15, 21, 35, 29, 9, 265, 965, 709, 4085, 623}, + {1, 3, 1, 11, 1, 29, 107, 21, 477, 795, 31, 2173, 2779}, + {1, 1, 1, 9, 11, 33, 111, 57, 463, 67, 1563, 2541, 5963}, + {1, 1, 1, 15, 1, 23, 101, 73, 449, 5, 165, 1195, 2585}, + {1, 3, 1, 15, 1, 55, 107, 97, 47, 87, 513, 925, 6927}, + {1, 3, 1, 13, 25, 11, 109, 57, 353, 909, 1425, 4039, 5333}, + {1, 3, 5, 13, 5, 59, 65, 29, 249, 97, 1299, 1379, 4033}, + {1, 1, 3, 13, 7, 19, 59, 239, 335, 995, 1081, 699, 285}, + {1, 1, 5, 1, 29, 61, 43, 151, 505, 271, 145, 1979, 7467}, + {1, 3, 1, 11, 29, 61, 37, 159, 89, 875, 1841, 275, 4443}, + {1, 3, 3, 9, 19, 45, 1, 191, 141, 671, 1211, 953, 4917}, + {1, 3, 5, 15, 19, 13, 9, 47, 55, 613, 941, 1755, 3}, + {1, 3, 3, 9, 1, 49, 15, 51, 235, 33, 609, 1643, 4319}, + {1, 3, 1, 5, 29, 13, 109, 1, 187, 351, 845, 325, 5517}, + {1, 3, 1, 15, 13, 63, 37, 223, 87, 69, 1169, 101, 3449}, + {1, 3, 1, 5, 3, 5, 111, 251, 363, 811, 1865, 2263, 813}, + {1, 1, 1, 7, 1, 61, 113, 251, 93, 669, 1593, 3329, 5499}, + {1, 3, 3, 3, 31, 5, 119, 151, 363, 729, 347, 3673, 2515}, + {1, 3, 7, 11, 15, 31, 79, 41, 101, 401, 293, 3413, 5771}, + {1, 3, 3, 3, 13, 17, 73, 119, 67, 647, 1277, 1977, 3357}, + {1, 3, 7, 15, 3, 61, 65, 127, 215, 241, 157, 2727, 2073}, + {1, 1, 5, 7, 1, 63, 71, 131, 321, 435, 211, 2313, 4395}, + {1, 3, 7, 13, 11, 13, 93, 33, 331, 447, 93, 1419, 4925}, + {1, 1, 1, 11, 19, 27, 17, 209, 305, 721, 1679, 887, 2643}, + {1, 3, 5, 7, 5, 57, 101, 123, 261, 271, 1799, 609, 7215}, + {1, 3, 5, 3, 29, 1, 87, 53, 411, 745, 527, 2475, 5817}, + {1, 3, 7, 7, 13, 21, 97, 241, 491, 53, 41, 591, 1199}, + {1, 1, 5, 13, 29, 5, 43, 25, 479, 775, 473, 2613, 1597}, + {1, 3, 3, 5, 23, 11, 23, 31, 65, 99, 563, 2081, 1619}, + {1, 1, 3, 13, 3, 39, 75, 183, 307, 343, 187, 3805, 7535}, + {1, 3, 7, 15, 1, 57, 109, 107, 469, 451, 1525, 3435, 4833}, + {1, 1, 5, 5, 31, 51, 41, 25, 415, 427, 575, 2409, 609}, + {1, 1, 3, 13, 13, 53, 49, 115, 131, 593, 1579, 111, 4797}, + {1, 1, 1, 9, 19, 39, 53, 39, 315, 339, 857, 3557, 8171}, + {1, 3, 1, 1, 17, 25, 31, 11, 487, 845, 703, 3607, 6847}, + {1, 3, 3, 15, 5, 41, 97, 213, 83, 243, 1211, 903, 793}, + {1, 1, 1, 11, 5, 39, 105, 239, 455, 345, 647, 231, 6757}, + {1, 3, 3, 5, 1, 37, 109, 219, 19, 17, 709, 3059, 8165}, + {1, 1, 1, 5, 29, 23, 119, 109, 113, 573, 981, 473, 3371}, + {1, 1, 1, 1, 23, 31, 51, 185, 163, 421, 285, 2959, 2431}, + {1, 3, 3, 11, 3, 25, 9, 35, 503, 517, 697, 2925, 5235}, + {1, 3, 7, 3, 19, 33, 53, 133, 99, 971, 163, 3861, 4739}, + {1, 1, 1, 3, 25, 17, 113, 123, 499, 499, 981, 2043, 7703}, + {1, 3, 7, 7, 19, 57, 97, 185, 251, 435, 153, 3887, 7223}, + {1, 1, 1, 1, 27, 29, 73, 27, 239, 769, 1515, 351, 6525}, + {1, 1, 1, 9, 9, 27, 89, 55, 81, 75, 47, 2865, 5891}, + {1, 1, 5, 7, 27, 23, 79, 245, 167, 203, 1553, 369, 5605}, + {1, 1, 1, 15, 13, 47, 49, 61, 391, 793, 599, 1377, 4433}, + {1, 3, 7, 9, 15, 41, 61, 75, 255, 985, 225, 2639, 3533}, + {1, 1, 5, 9, 29, 29, 105, 205, 317, 343, 1147, 1261, 5267}, + {1, 3, 3, 3, 23, 19, 13, 213, 363, 955, 381, 3625, 5125}, + {1, 1, 7, 11, 13, 47, 99, 169, 359, 735, 135, 3279, 5037}, + {1, 1, 3, 15, 25, 41, 53, 163, 395, 523, 821, 2201, 225}, + {1, 3, 5, 7, 25, 25, 71, 63, 419, 659, 1965, 2949, 6717}, + {1, 1, 3, 1, 17, 5, 7, 55, 307, 703, 609, 3049, 1121}, + {1, 3, 1, 3, 19, 51, 87, 49, 251, 303, 1033, 449, 5741}, + {1, 1, 1, 1, 17, 43, 21, 83, 267, 421, 983, 1297, 2013}, + {1, 3, 5, 1, 15, 39, 101, 195, 171, 951, 503, 897, 4327}, + {1, 3, 5, 1, 27, 29, 5, 51, 461, 405, 1117, 1891, 4839}, + {1, 3, 1, 9, 3, 7, 71, 31, 183, 631, 327, 411, 569}, + {1, 3, 7, 1, 25, 31, 31, 41, 465, 825, 453, 2773, 5227}, + {1, 3, 7, 5, 17, 45, 123, 15, 165, 735, 2005, 749, 7677}, + {1, 3, 3, 15, 27, 51, 121, 203, 163, 433, 1257, 2753, 4315}, + {1, 1, 7, 15, 3, 49, 121, 41, 293, 841, 343, 1825, 2391}, + {1, 3, 3, 7, 27, 55, 73, 63, 477, 485, 1649, 853, 5551}, + {1, 3, 7, 5, 31, 17, 79, 127, 223, 49, 1199, 2775, 859}, + {1, 3, 1, 5, 23, 43, 115, 161, 403, 749, 599, 3547, 3627}, + {1, 3, 5, 7, 13, 49, 13, 5, 389, 107, 1877, 3923, 6377}, + {1, 1, 1, 9, 31, 45, 39, 143, 97, 669, 569, 3923, 3903}, + {1, 3, 5, 7, 11, 9, 101, 7, 335, 211, 695, 987, 4311}, + {1, 3, 3, 15, 15, 29, 19, 199, 357, 497, 1587, 3723, 6527}, + {1, 1, 7, 13, 7, 3, 37, 251, 297, 143, 1475, 2189, 7573}, + {1, 3, 3, 13, 21, 5, 51, 95, 19, 99, 187, 3877, 4905}, + {1, 3, 5, 11, 19, 47, 83, 75, 469, 57, 973, 3577, 7731}, + {1, 3, 7, 1, 27, 9, 97, 101, 501, 277, 233, 297, 1909}, + {1, 3, 7, 9, 19, 15, 55, 15, 249, 969, 511, 2763, 1555}, + {1, 3, 7, 11, 21, 19, 81, 43, 85, 107, 51, 1845, 3279}, + {1, 1, 3, 1, 29, 51, 91, 237, 213, 397, 1083, 3083, 1949}, + {1, 1, 3, 13, 7, 45, 127, 197, 311, 563, 665, 2951, 1887}, + {1, 1, 1, 1, 31, 57, 105, 117, 265, 551, 1321, 483, 6675}, + {1, 1, 1, 7, 13, 63, 89, 167, 379, 447, 531, 2169, 5509}, + {1, 3, 5, 15, 9, 9, 63, 155, 297, 381, 1875, 3985, 2033}, + {1, 3, 5, 15, 9, 21, 47, 21, 283, 187, 1939, 245, 5473}, + {1, 3, 3, 5, 7, 59, 49, 83, 393, 57, 859, 3655, 3539}, + {1, 1, 7, 5, 21, 3, 75, 205, 449, 405, 1507, 3441, 5033}, + {1, 3, 1, 1, 13, 9, 37, 255, 463, 731, 1979, 1023, 5935}, + {1, 3, 1, 11, 11, 13, 77, 49, 289, 769, 1203, 235, 6095}, + {1, 1, 1, 3, 9, 45, 15, 101, 159, 923, 1965, 835, 4761}, + {1, 1, 3, 9, 11, 23, 49, 213, 289, 955, 737, 3693, 1771}, + {1, 3, 5, 11, 29, 15, 107, 237, 499, 915, 921, 3585, 1271}, + {1, 3, 3, 9, 19, 31, 23, 135, 407, 737, 1565, 327, 1717}, + {1, 1, 1, 9, 11, 21, 23, 135, 129, 595, 1943, 1003, 4415}, + {1, 1, 1, 9, 19, 15, 35, 21, 137, 341, 819, 543, 5083}, + {1, 3, 3, 1, 21, 51, 19, 73, 221, 253, 223, 3059, 6277}, + {1, 3, 3, 9, 5, 35, 69, 93, 43, 823, 365, 2637, 3147}, + {1, 1, 7, 3, 29, 9, 17, 115, 89, 197, 167, 2923, 7695}, + {1, 3, 5, 5, 13, 11, 59, 7, 403, 321, 1705, 87, 2461}, + {1, 1, 1, 15, 7, 61, 63, 85, 271, 315, 413, 3617, 4783}, + {1, 1, 1, 1, 19, 23, 73, 223, 75, 181, 1577, 1031, 4539}, + {1, 3, 3, 1, 19, 53, 29, 237, 83, 885, 745, 1043, 5833}, + {1, 1, 7, 9, 27, 29, 125, 79, 445, 497, 1573, 903, 5583}, + {1, 3, 1, 7, 23, 51, 61, 89, 453, 159, 655, 2913, 651}, + {1, 3, 5, 3, 31, 45, 65, 5, 389, 571, 1633, 2177, 1419}, + {1, 3, 7, 3, 1, 31, 95, 57, 149, 981, 1003, 2641, 2605}, + {1, 3, 3, 1, 27, 29, 101, 239, 143, 899, 91, 3279, 5511}, + {1, 3, 7, 9, 21, 5, 81, 67, 423, 785, 1123, 389, 3913}, + {1, 1, 5, 9, 7, 35, 57, 65, 499, 947, 477, 2009, 5795}, + {1, 3, 5, 11, 3, 29, 69, 201, 317, 217, 1741, 525, 2333}, + {1, 1, 7, 9, 7, 53, 83, 155, 445, 217, 1663, 4085, 2329}, + {1, 1, 3, 9, 11, 35, 37, 71, 157, 135, 35, 3299, 4431}, + {1, 3, 5, 13, 23, 17, 11, 85, 137, 753, 715, 987, 3725}, + {1, 3, 3, 13, 13, 59, 37, 195, 453, 623, 37, 2409, 6069}, + {1, 3, 1, 3, 29, 55, 95, 89, 163, 565, 1513, 813, 2699}, + {1, 3, 5, 13, 11, 27, 1, 181, 87, 717, 815, 2683, 7055}, + {1, 1, 3, 11, 31, 51, 73, 119, 23, 903, 941, 373, 6879}, + {1, 3, 1, 13, 19, 59, 27, 135, 391, 581, 1379, 2695, 1017}, + {1, 1, 1, 5, 1, 27, 29, 147, 119, 955, 263, 3775, 3121}, + {1, 1, 7, 1, 5, 47, 57, 237, 427, 621, 1831, 2375, 2547}, + {1, 3, 5, 5, 5, 15, 7, 173, 323, 361, 1735, 1119, 4603}, + {1, 3, 1, 5, 11, 29, 65, 41, 173, 869, 1111, 2791, 2385}, + {1, 3, 7, 9, 5, 37, 83, 155, 89, 87, 1449, 223, 6915}, + {1, 3, 3, 9, 3, 7, 99, 67, 259, 943, 353, 325, 6103}, + {1, 3, 7, 3, 27, 49, 69, 113, 377, 907, 1941, 587, 5669}, + {1, 3, 5, 13, 5, 55, 19, 111, 511, 853, 1655, 1379, 7833}, + {1, 1, 1, 13, 7, 5, 103, 21, 249, 353, 1349, 2877, 2001}, + {1, 1, 7, 9, 11, 19, 43, 183, 31, 335, 877, 2867, 4287}, + {1, 3, 1, 15, 31, 45, 95, 23, 363, 197, 285, 3793, 6619}, + {1, 1, 7, 9, 1, 29, 25, 103, 229, 771, 1723, 655, 955}, + {1, 3, 7, 11, 27, 19, 19, 207, 353, 433, 125, 831, 2761}, + {1, 1, 1, 7, 31, 57, 103, 253, 329, 743, 1753, 3425, 5711}, + {1, 1, 1, 11, 31, 33, 41, 69, 493, 195, 985, 1663, 6291}, + {1, 3, 7, 9, 23, 53, 125, 219, 427, 91, 723, 1681, 3415}, + {1, 1, 1, 13, 5, 45, 97, 205, 57, 1023, 175, 2657, 3909}, + {1, 1, 5, 9, 21, 21, 71, 195, 205, 63, 439, 1865, 2841}, + {1, 1, 5, 1, 27, 9, 105, 43, 389, 301, 791, 3943, 5627}, + {1, 1, 1, 15, 9, 3, 83, 197, 91, 647, 1051, 2977, 4939}, + {1, 3, 1, 9, 25, 35, 83, 229, 83, 205, 1261, 1979, 7671}, + {1, 3, 7, 7, 3, 29, 61, 139, 13, 485, 717, 2271, 6059}, + {1, 1, 5, 7, 15, 43, 39, 177, 219, 927, 1555, 3247, 6275}, + {1, 1, 7, 1, 19, 31, 9, 129, 439, 1003, 1757, 1267, 6517}, + {1, 3, 1, 7, 1, 39, 45, 69, 45, 987, 1777, 1747, 1931}, + {1, 1, 5, 9, 19, 3, 117, 97, 35, 359, 577, 811, 4583}, + {1, 1, 3, 9, 9, 45, 63, 201, 371, 577, 1583, 159, 7301}, + {1, 1, 5, 15, 5, 1, 31, 163, 441, 147, 1957, 429, 1267}, + {1, 3, 3, 1, 25, 41, 5, 189, 17, 141, 873, 2001, 7509}, + {1, 1, 3, 11, 21, 29, 117, 11, 267, 1017, 331, 1195, 1435}, + {1, 3, 7, 1, 15, 5, 67, 99, 501, 701, 1163, 3065, 2169}, + {1, 1, 1, 13, 25, 59, 125, 91, 53, 273, 313, 553, 6939}, + {1, 1, 5, 13, 29, 41, 41, 253, 25, 89, 1, 1499, 3515}, + {1, 3, 1, 15, 15, 33, 117, 239, 333, 589, 1963, 3529, 2985}, + {1, 3, 1, 9, 21, 35, 43, 91, 17, 487, 963, 1081, 2787}, + {1, 1, 5, 13, 11, 27, 77, 145, 201, 859, 1905, 2877, 2123}, + {1, 3, 5, 7, 19, 19, 97, 19, 475, 343, 821, 3077, 1969}, + {1, 1, 3, 15, 15, 13, 15, 179, 257, 91, 1677, 845, 3307}, + {1, 1, 3, 3, 3, 25, 29, 231, 417, 847, 185, 1793, 353}, + {1, 3, 7, 9, 7, 27, 5, 121, 345, 341, 709, 2409, 4359}, + {1, 3, 5, 3, 13, 43, 59, 7, 381, 173, 545, 3995, 7059}, + {1, 3, 5, 1, 11, 33, 25, 225, 377, 287, 1723, 2559, 5273}, + {1, 3, 1, 13, 25, 35, 63, 237, 55, 1003, 215, 4081, 5873}, + {1, 3, 1, 7, 17, 17, 87, 125, 403, 289, 1885, 1195, 6657}, + {1, 1, 1, 5, 1, 17, 39, 191, 77, 639, 1249, 2955, 6765}, + {1, 3, 3, 9, 5, 23, 39, 119, 389, 983, 583, 1117, 6229}, + {1, 1, 1, 3, 31, 7, 77, 59, 347, 685, 1803, 1409, 3179}, + {1, 1, 5, 1, 13, 35, 85, 175, 363, 697, 839, 785, 1583}, + {1, 1, 7, 7, 29, 15, 37, 237, 211, 35, 885, 287, 6237}, + {1, 3, 7, 1, 23, 61, 81, 131, 413, 701, 485, 1521, 2155}, + {1, 1, 1, 1, 9, 61, 73, 79, 419, 645, 413, 1607, 371}, + {1, 1, 7, 13, 5, 53, 89, 43, 5, 911, 1767, 85, 273}, + {1, 1, 5, 3, 29, 5, 29, 45, 167, 501, 425, 3055, 7491}, + {1, 3, 7, 3, 7, 15, 125, 205, 219, 705, 129, 3123, 3309}, + {1, 1, 3, 11, 17, 23, 109, 199, 201, 873, 1035, 2533, 6805}, + {1, 1, 7, 1, 27, 11, 21, 251, 285, 763, 329, 2329, 3015}, + {1, 3, 3, 7, 7, 13, 23, 153, 425, 745, 1263, 3477, 6831}, + {1, 1, 1, 13, 17, 43, 119, 207, 11, 657, 1881, 799, 7819}, + {1, 3, 3, 15, 31, 55, 105, 37, 77, 559, 1779, 3683, 713}, + {1, 3, 7, 15, 9, 47, 43, 179, 269, 699, 1565, 3715, 4747}, + {1, 3, 3, 5, 31, 25, 93, 113, 489, 315, 359, 337, 3935}, + {1, 3, 1, 7, 9, 43, 97, 255, 281, 347, 367, 3139, 4109}, + {1, 3, 5, 13, 9, 15, 15, 107, 403, 429, 453, 3311, 1311}, + {1, 1, 5, 13, 7, 57, 125, 217, 79, 197, 707, 431, 709}, + {1, 1, 3, 15, 21, 45, 29, 61, 425, 165, 1419, 3511, 3089}, + {1, 1, 5, 11, 3, 1, 51, 7, 125, 955, 831, 2299, 7059}, + {1, 3, 1, 13, 3, 49, 69, 181, 81, 859, 1889, 365, 4247}, + {1, 3, 3, 1, 3, 63, 37, 247, 331, 167, 887, 2941, 2989}, + {1, 3, 5, 13, 9, 57, 45, 31, 437, 303, 1871, 3067, 1509}, + {1, 3, 5, 13, 11, 15, 31, 13, 271, 833, 1869, 1331, 4919}, + {1, 1, 5, 3, 21, 31, 75, 113, 397, 531, 747, 1081, 1841}, + {1, 3, 1, 9, 11, 31, 109, 145, 299, 473, 223, 1097, 3045}, + {1, 3, 1, 15, 31, 7, 119, 107, 475, 635, 1547, 2853, 3821}, + {1, 3, 7, 15, 9, 53, 53, 233, 271, 641, 1799, 2299, 6929}, + {1, 3, 7, 11, 25, 27, 5, 233, 249, 195, 433, 495, 4655}, + {1, 1, 1, 15, 5, 15, 101, 43, 413, 589, 1441, 1745, 1333}, + {1, 1, 5, 9, 1, 47, 125, 79, 233, 821, 553, 749, 6429}, + {1, 3, 5, 15, 31, 23, 121, 23, 261, 205, 2021, 3819, 6649}, + {1, 3, 1, 1, 13, 7, 35, 169, 495, 3, 1303, 619, 2131}, + {1, 3, 3, 13, 29, 29, 29, 137, 171, 635, 1505, 1059, 5265}, + {1, 1, 5, 15, 9, 53, 7, 129, 69, 371, 1735, 3559, 1051}, + {1, 3, 1, 1, 29, 47, 63, 183, 27, 891, 1619, 183, 261}, + {1, 1, 5, 1, 1, 9, 17, 53, 409, 249, 1065, 3743, 8057}, + {1, 1, 3, 5, 11, 53, 63, 91, 21, 123, 1161, 723, 3379}, + {1, 3, 5, 11, 19, 3, 13, 55, 421, 77, 2047, 949, 2179}, + {1, 3, 3, 5, 7, 25, 69, 103, 367, 623, 347, 3501, 1993}, + {1, 1, 3, 1, 27, 55, 15, 223, 81, 993, 867, 733, 5655}, + {1, 3, 7, 11, 13, 45, 105, 87, 483, 401, 881, 2599, 3063}, + {1, 3, 5, 11, 31, 63, 51, 177, 255, 525, 1447, 3983, 6381}, + {1, 1, 7, 5, 7, 21, 127, 157, 15, 427, 329, 3961, 3587}, + {1, 1, 3, 3, 31, 17, 105, 79, 219, 71, 781, 911, 7417}, + {1, 1, 7, 9, 7, 23, 9, 213, 365, 655, 1065, 1899, 1579}, + {1, 1, 3, 1, 25, 31, 57, 139, 497, 951, 219, 985, 1541}, + {1, 1, 1, 3, 23, 27, 95, 183, 181, 357, 589, 2493, 2107}, + {1, 3, 3, 5, 21, 27, 59, 231, 75, 851, 645, 1795, 5085}, + {1, 1, 7, 13, 29, 43, 109, 205, 431, 899, 1257, 653, 2873}, + {1, 1, 7, 9, 11, 63, 35, 143, 99, 535, 1833, 157, 6141}, + {1, 3, 3, 7, 11, 55, 49, 129, 325, 493, 749, 433, 955}, + {1, 3, 3, 7, 13, 63, 23, 243, 407, 323, 1841, 2361, 3537}, + {1, 1, 1, 1, 11, 45, 33, 205, 229, 1003, 1733, 3093, 2157}, + {1, 1, 1, 9, 27, 51, 107, 93, 281, 343, 1179, 3119, 841}, + {1, 1, 3, 9, 1, 15, 55, 59, 63, 515, 1191, 3679, 1999}, + {1, 3, 3, 15, 23, 27, 33, 15, 83, 859, 1025, 2367, 1465}, + {1, 1, 3, 7, 31, 5, 57, 89, 493, 1017, 1639, 1701, 5171}, + {1, 1, 3, 5, 21, 37, 79, 9, 5, 5, 1955, 1445, 5651}, + {1, 3, 3, 5, 23, 43, 73, 11, 113, 423, 1423, 1321, 1535}, + {1, 3, 5, 15, 21, 11, 69, 47, 15, 315, 1685, 2397, 7235}, + {1, 1, 5, 13, 19, 27, 59, 133, 271, 1011, 1711, 1241, 4349}, + {1, 3, 3, 9, 31, 5, 107, 227, 37, 703, 493, 3305, 1263}, + {1, 3, 3, 7, 5, 27, 55, 75, 87, 41, 549, 3985, 1453}, + {1, 3, 3, 13, 31, 59, 11, 9, 451, 777, 783, 2349, 1005}, + {1, 3, 1, 3, 25, 21, 63, 91, 299, 163, 1653, 4067, 6893}, + {1, 3, 3, 13, 25, 7, 95, 19, 83, 95, 397, 3805, 2919}, + {1, 3, 5, 11, 19, 39, 103, 171, 451, 831, 895, 3073, 1947}, + {1, 3, 7, 13, 17, 27, 23, 163, 311, 79, 233, 2837, 1635}, + {1, 3, 7, 7, 11, 63, 125, 79, 441, 975, 759, 1567, 3963}, + {1, 1, 1, 9, 25, 35, 91, 7, 47, 235, 1505, 3783, 397}, + {1, 1, 5, 13, 7, 47, 31, 103, 455, 633, 677, 451, 969}, + {1, 3, 7, 13, 13, 55, 91, 5, 47, 723, 1449, 2441, 4569}, + {1, 3, 3, 13, 1, 17, 51, 119, 253, 297, 1573, 1181, 655}, + {1, 1, 7, 15, 29, 17, 65, 155, 13, 589, 1297, 487, 6737}, + {1, 1, 1, 9, 17, 17, 61, 75, 109, 317, 1821, 543, 2995}, + {1, 3, 1, 5, 23, 3, 75, 11, 369, 679, 1691, 1201, 7235}, + {1, 1, 3, 5, 15, 19, 69, 71, 347, 981, 791, 3735, 7713}, + {1, 3, 5, 3, 7, 21, 107, 95, 11, 195, 289, 2517, 973}, + {1, 3, 7, 3, 29, 13, 65, 17, 409, 399, 1187, 733, 4821}, + {1, 3, 5, 3, 17, 49, 101, 13, 275, 1003, 867, 1535, 2377}, + {1, 3, 3, 1, 13, 61, 59, 243, 63, 121, 1535, 2175, 1673}, + {1, 3, 3, 3, 3, 39, 35, 207, 441, 501, 575, 3613, 1}, + {1, 1, 3, 15, 17, 15, 15, 187, 15, 155, 183, 3019, 6541} +}; diff --git a/aten/src/ATen/native/native_functions.yaml b/aten/src/ATen/native/native_functions.yaml index bcdb704..0793434 100644 --- a/aten/src/ATen/native/native_functions.yaml +++ b/aten/src/ATen/native/native_functions.yaml @@ -76,6 +76,18 @@ dispatch: CUDA: masked_scale_cuda +- func: _sobol_engine_draw(Tensor quasi, int n, Tensor sobolstate, int dimension, int num_generated, ScalarType? dtype) -> (Tensor, Tensor) + matches_jit_signature: True + +- func: _sobol_engine_ff_(Tensor(a!) self, int n, Tensor sobolstate, int dimension, int num_generated) -> Tensor(a!) + matches_jit_signature: True + +- func: _sobol_engine_scramble_(Tensor(a!) self, Tensor ltm, int dimension) -> Tensor(a!) + matches_jit_signature: True + +- func: _sobol_engine_initialize_state_(Tensor(a!) self, int dimension) -> Tensor(a!) + matches_jit_signature: True + - func: _reshape_from_tensor(Tensor self, Tensor shape) -> Tensor matches_jit_signature: True diff --git a/docs/source/torch.rst b/docs/source/torch.rst index 782f58e..1013128 100644 --- a/docs/source/torch.rst +++ b/docs/source/torch.rst @@ -107,6 +107,13 @@ There are a few more in-place random sampling functions defined on Tensors as we - :func:`torch.Tensor.random_` - numbers sampled from the discrete uniform distribution - :func:`torch.Tensor.uniform_` - numbers sampled from the continuous uniform distribution +Quasi-random sampling +~~~~~~~~~~~~~~~~~~~~~ + +.. autoclass:: torch.quasirandom.SobolEngine + :members: + :exclude-members: MAXBIT, MAXDIM + :undoc-members: Serialization ---------------------------------- diff --git a/test/test_torch.py b/test/test_torch.py index e337797..6b6c2a2 100644 --- a/test/test_torch.py +++ b/test/test_torch.py @@ -8682,6 +8682,87 @@ class _TestTorchMixin(object): self.assertEqual(r[:, :50].std(), 4, 0.3) self.assertEqual(r[:, 50:].std(), 1, 0.2) + def test_sobolengine_unscrambled_lowdim(self): + engine_1d = torch.quasirandom.SobolEngine(1) + expected_1d = torch.tensor([0.5, 0.75, 0.25, 0.375, 0.875, 0.625, 0.125, 0.1875, 0.6875, 0.9375]) + actual_1d = engine_1d.draw(10) + self.assertEqual(actual_1d.view(-1), expected_1d) + self.assertEqual(actual_1d.size(), torch.Size([10, 1])) + + # Test out kwarg + engine_1d.reset() + actual_1d_out = torch.Tensor().float() + engine_1d.draw(10, out=actual_1d_out) + self.assertEqual(actual_1d.view(-1), expected_1d) + + engine_3d = torch.quasirandom.SobolEngine(3) + expected_3d = torch.tensor([0.5, 0.75, 0.25, 0.625, 0.125, 0.375, 0.875, 0.3125, 0.8125, 0.5625]) + actual_3d = engine_3d.draw(10) + self.assertEqual(actual_3d[:, 2], expected_3d) + self.assertEqual(actual_3d[:, 0], expected_1d) + self.assertEqual(actual_3d.size(), torch.Size([10, 3])) + + engine_3d = torch.quasirandom.SobolEngine(3) + draws = torch.cat([engine_3d.draw() for _ in range(0, 10)]) + self.assertEqual(draws, actual_3d) + + engine_3d = torch.quasirandom.SobolEngine(3).fast_forward(5) + draws = engine_3d.draw(5) + self.assertEqual(draws, actual_3d[5:]) + engine_3d.reset() + self.assertEqual(engine_3d.draw(3), actual_3d[:3]) + engine_3d.fast_forward(2) + self.assertEqual(engine_3d.draw(5), actual_3d[5:]) + + def test_sobolengine_unscrambled_highdim(self): + from collections import Counter + engine = torch.quasirandom.SobolEngine(1111) + count1 = dict(Counter(engine.draw().view(-1).tolist())) + count2 = dict(Counter(engine.draw().view(-1).tolist())) + count3 = dict(Counter(engine.draw().view(-1).tolist())) + self.assertTrue(count1 == {0.5: 1111}) + self.assertTrue(count2 == {0.25: 580, 0.75: 531}) + self.assertTrue(count3 == {0.25: 531, 0.75: 580}) + + engine = torch.quasirandom.SobolEngine(1111) + draws = engine.draw(1000) + self.assertTrue(torch.all(draws <= 1)) + self.assertTrue(torch.all(draws >= 0)) + + def test_sobolengine_scrambled_lowdim(self): + engine_1d = torch.quasirandom.SobolEngine(1, scramble=True, seed=1729) + expected_1d = [0.16478512, 0.43221009, 0.84261382, 0.99750268, 0.27460563, + 0.01084163, 0.73373985, 0.65039611, 0.12329865, 0.35587373] + actual_1d = engine_1d.draw(10) + self.assertEqual(actual_1d.flatten(), torch.tensor(expected_1d)) + self.assertEqual(actual_1d.size(), torch.Size([10, 1])) + + engine_3d = torch.quasirandom.SobolEngine(3, scramble=True, seed=1729) + expected_3d = [0.32642800, 0.17881306, 0.68837059, 0.46492538, 0.91789097, + 0.58075899, 0.03642474, 0.68229187, 0.20051685, 0.30083340] + actual_3d = engine_3d.draw(10) + self.assertEqual(actual_3d[:, 2], torch.tensor(expected_3d)) + self.assertEqual(actual_3d.size(), torch.Size([10, 3])) + + engine_3d = torch.quasirandom.SobolEngine(3, scramble=True, seed=1729) + draws = torch.cat([engine_3d.draw() for _ in range(0, 10)]) + self.assertEqual(draws, actual_3d) + + engine_3d = torch.quasirandom.SobolEngine(3, scramble=True, seed=1729) + engine_3d.fast_forward(5) + draws = engine_3d.draw(5) + self.assertEqual(draws, actual_3d[5:]) + engine_3d.reset() + self.assertEqual(engine_3d.draw(3), actual_3d[:3]) + engine_3d.fast_forward(2) + self.assertEqual(engine_3d.draw(5), actual_3d[5:]) + + def test_sobolengine_scrambled_highdim(self): + engine = torch.quasirandom.SobolEngine(1111, scramble=True) + draws = engine.draw(1000) + self.assertTrue(torch.all(draws <= 1)) + self.assertTrue(torch.all(draws >= 0)) + def test_parsing_int64(self): # accepts integer arguments x = torch.cumsum(torch.ones(5, 5), 0) diff --git a/tools/autograd/gen_variable_type.py b/tools/autograd/gen_variable_type.py index 2cd53a6..777c9c0 100644 --- a/tools/autograd/gen_variable_type.py +++ b/tools/autograd/gen_variable_type.py @@ -75,6 +75,9 @@ DONT_REQUIRE_DERIVATIVE = { # These are only implemented on integral types '__and__', '__iand__', '__ilshift__', '__ior__', '__irshift__', '__ixor__', '__lshift__', '__or__', '__rshift__', '__xor__', + # These work on integral data types, and hence don't require derivative + '_sobol_engine_draw', '_sobol_engine_ff', '_sobol_engine_scramble_', + '_sobol_engine_initialize_state_', # This is an unsafe method that is meant to be out of reach of autograd. '_coalesced_', } diff --git a/torch/__init__.py b/torch/__init__.py index a7503b9..b4c50e9 100644 --- a/torch/__init__.py +++ b/torch/__init__.py @@ -310,3 +310,6 @@ def compiled_with_cxx11_abi(): # Import the ops "namespace" from torch._ops import ops + +# Import the quasi random sampler +import torch.quasirandom diff --git a/torch/quasirandom.py b/torch/quasirandom.py new file mode 100644 index 0000000..615d79d --- /dev/null +++ b/torch/quasirandom.py @@ -0,0 +1,122 @@ +import torch + + +class SobolEngine(object): + r""" + The :class:`torch.quasirandom.SobolEngine` is an engine for generating + (scrambled) Sobol sequences. Sobol sequences are an example of low + discrepancy quasi-random sequences. + + This implementation of an engine for Sobol sequences is capable of + sampling sequences up to a maximum dimension of 1111. It uses direction + numbers to generate these sequences, and these numbers have been adapted + from `here `_. + + References: + - Art B. Owen. Scrambling Sobol and Niederreiter-Xing points. + Journal of Complexity, 14(4):466-489, December 1998. + + - I. M. Sobol. The distribution of points in a cube and the accurate + evaluation of integrals. + Zh. Vychisl. Mat. i Mat. Phys., 7:784-802, 1967. + + Args: + dimension (Int): The dimensionality of the sequence to be drawn + scramble (bool, optional): Setting this to ``True`` will produce + scrambled Sobol sequences. Scrambling is + capable of producing better Sobol + sequences. Default: ``False``. + seed (Int, optional): This is the seed for the scrambling. The seed + of the random number generator is set to this, + if specified. Default: ``None`` + + Examples:: + + >>> soboleng = torch.quasirandom.SobolEngine(dimension=5) + >>> soboleng.draw(3) + tensor([[0.5000, 0.5000, 0.5000, 0.5000, 0.5000], + [0.7500, 0.2500, 0.7500, 0.2500, 0.7500], + [0.2500, 0.7500, 0.2500, 0.7500, 0.2500]]) + """ + MAXBIT = 30 + MAXDIM = 1111 + + def __init__(self, dimension, scramble=False, seed=None): + if dimension > self.MAXDIM or dimension < 1: + raise ValueError("Supported range of dimensionality " + "for SobolEngine is [1, {}]".format(self.MAXDIM)) + + self.seed = seed + self.scramble = scramble + self.dimension = dimension + + self.sobolstate = torch.zeros(dimension, self.MAXBIT, dtype=torch.long) + torch._sobol_engine_initialize_state_(self.sobolstate, self.dimension) + + if self.scramble: + g = torch.Generator() + if self.seed is not None: + g.manual_seed(self.seed) + + self.shift = torch.mv(torch.randint(2, (self.dimension, self.MAXBIT), generator=g), + torch.pow(2, torch.arange(0, self.MAXBIT))) + + ltm = torch.randint(2, (self.dimension, self.MAXBIT, self.MAXBIT), generator=g).tril() + + torch._sobol_engine_scramble_(self.sobolstate, ltm, self.dimension) + else: + self.shift = torch.zeros(self.dimension, dtype=torch.long) + + self.quasi = self.shift.clone() + self.num_generated = 0 + + def draw(self, n=1, out=None, dtype=torch.float32): + r""" + Function to draw a sequence of :attr:`n` points from a Sobol sequence. + Note that the samples are dependent on the previous samples. The size + of the result is :math:`(n, dimension)`. + + Args: + n (Int, optional): The length of sequence of points to draw. + Default: 1 + out (Tensor, optional): The output tensor + dtype (:class:`torch.dtype`, optional): the desired data type of the + returned tensor. + Default: ``torch.float32`` + """ + result, self.quasi = torch._sobol_engine_draw(self.quasi, n, self.sobolstate, + self.dimension, self.num_generated, dtype=dtype) + self.num_generated += n + if out is not None: + out.resize_as_(result).copy_(result) + return out + return result + + def reset(self): + r""" + Function to reset the ``SobolEngine`` to base state. + """ + self.quasi.copy_(self.shift) + self.num_generated = 0 + return self + + def fast_forward(self, n): + r""" + Function to fast-forward the state of the ``SobolEngine`` by + :attr:`n` steps. This is equivalent to drawing :attr:`n` samples + without using the samples. + + Args: + n (Int): The number of steps to fast-forward by. + """ + torch._sobol_engine_ff_(self.quasi, n, self.sobolstate, self.dimension, self.num_generated) + self.num_generated += n + return self + + def __repr__(self): + fmt_string = ['dimension={}'.format(self.dimension)] + if self.scramble: + fmt_string += ['scramble=True'] + if self.seed is not None: + fmt_string += ['seed={}'.format(self.seed)] + return self.__class__.__name__ + '(' + ', '.join(fmt_string) + ')'