num-prime-0.4.4/.cargo_vcs_info.json0000644000000001360000000000100127520ustar { "git": { "sha1": "956da634ccbe1ffc8061e870667189448023bd77" }, "path_in_vcs": "" }num-prime-0.4.4/.gitignore000064400000000000000000000001050072674642500135560ustar 00000000000000/target Cargo.lock # generated profile stats profile_stats.csv num-prime-0.4.4/Cargo.lock0000644000000157140000000000100107350ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "ahash" version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", "version_check", "zerocopy", ] [[package]] name = "allocator-api2" version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "autocfg" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitvec" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ "funty", "radium", "tap", "wyz", ] [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "either" version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" [[package]] name = "funty" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "getrandom" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", "wasi", ] [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", "allocator-api2", ] [[package]] name = "libc" version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" [[package]] name = "lru" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" dependencies = [ "hashbrown", ] [[package]] name = "num-bigint" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", "num-traits", "rand", ] [[package]] name = "num-integer" version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ "num-traits", ] [[package]] name = "num-modular" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64a5fe11d4135c3bcdf3a95b18b194afa9608a5f6ff034f5d857bc9a27fb0119" dependencies = [ "num-bigint", "num-integer", "num-traits", ] [[package]] name = "num-prime" version = "0.4.4" dependencies = [ "bitvec", "either", "lru", "num-bigint", "num-integer", "num-modular", "num-traits", "rand", ] [[package]] name = "num-traits" version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "once_cell" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "ppv-lite86" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] [[package]] name = "radium" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", "rand_core", ] [[package]] name = "rand_chacha" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", "rand_core", ] [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] [[package]] name = "syn" version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "tap" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wyz" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" dependencies = [ "tap", ] [[package]] name = "zerocopy" version = "0.7.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "087eca3c1eaf8c47b94d02790dd086cd594b912d2043d4de4bfdd466b3befb7c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" version = "0.7.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f4b6c273f496d8fd4eaf18853e6b448760225dc030ff2c485a786859aea6393" dependencies = [ "proc-macro2", "quote", "syn", ] num-prime-0.4.4/Cargo.toml0000644000000030170000000000100107510ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "num-prime" version = "0.4.4" description = """ Generic and optimized primality test, factorization and various number theoretic functions with arbitrary precision based on `num`. """ documentation = "https://docs.rs/num-prime" readme = "README.md" keywords = [ "mathematics", "primes", "number-theory", "bigint", "num", ] categories = [ "cryptography", "science", "algorithms", ] license = "Apache-2.0" repository = "https://github.com/cmpute/num-prime" [package.metadata.docs.rs] all-features = true [dependencies.bitvec] version = "1.0.0" [dependencies.either] version = "1.6.1" [dependencies.lru] version = "0.12.2" [dependencies.num-bigint] version = "0.4.3" features = ["rand"] optional = true [dependencies.num-integer] version = "0.1.44" [dependencies.num-modular] version = "0.5.0" [dependencies.num-traits] version = "0.2.14" [dependencies.rand] version = "0.8.4" [features] big-int = [ "num-bigint", "num-modular/num-bigint", ] big-table = [] default = [ "big-table", "big-int", ] num-prime-0.4.4/Cargo.toml.orig000064400000000000000000000021410072674642500144570ustar 00000000000000[package] name = "num-prime" version = "0.4.4" edition = "2018" repository = "https://github.com/cmpute/num-prime" keywords = ["mathematics", "primes", "number-theory", "bigint", "num"] categories = ["cryptography", "science", "algorithms"] documentation = "https://docs.rs/num-prime" license = "Apache-2.0" description = """ Generic and optimized primality test, factorization and various number theoretic functions with arbitrary precision based on `num`. """ readme = "README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] num-integer = "0.1.44" num-traits = "0.2.14" num-modular = "0.5.0" bitvec = "1.0.0" rand = "0.8.4" lru = "0.12.2" either = "1.6.1" [dependencies.num-bigint] optional = true version = "0.4.3" features = ["rand"] [features] default = ['big-table', 'big-int'] big-table = [] # TODO: use the new cargo feature to override the num-bigint option big-int = ['num-bigint', 'num-modular/num-bigint'] [workspace] members = [ "bench", ] [package.metadata.docs.rs] all-features = true num-prime-0.4.4/LICENSE000064400000000000000000000254320072674642500126050ustar 00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [2021] [Jacob Zhong] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.num-prime-0.4.4/PERFORMANCE.md000064400000000000000000000122420072674642500136560ustar 00000000000000# Performance comparison The following benchmark results are produced by criterion (the code is under [`bench/`](./bench/)) on my Laptop (Ryzen 4700U). ```log primality check (u64)/num-prime (this crate) time: [750.96 us 756.01 us 763.51 us] primality check (u64)/number-theory time: [1.1550 ms 1.1586 ms 1.1624 ms] primality check (u64)/num-primes time: [429.79 ms 431.64 ms 434.03 ms] primality check (u64)/glass_pumpkin time: [108.30 ms 108.85 ms 109.42 ms] primality check (u64)/primal-check time: [17.693 ms 17.932 ms 18.215 ms] primality check (u256)/num-prime (this crate) time: [828.72 us 848.85 us 871.09 us] primality check (u256)/num-primes time: [1.0797 ms 1.0869 ms 1.0960 ms] primality check (u256)/glass_pumpkin time: [332.27 us 337.31 us 344.24 us] safe primality check (u256)/num-prime (this crate) time: [462.10 us 463.54 us 465.05 us] safe primality check (u256)/num-primes time: [796.00 us 798.52 us 801.12 us] safe primality check (u256)/glass_pumpkin time: [319.49 us 320.79 us 322.16 us] safe primality check (u256)/glass_pumpkin (BPSW) time: [315.92 us 317.33 us 318.77 us] primality check (u2048)/num-prime (this crate) time: [26.156 ms 26.424 ms 26.757 ms] primality check (u2048)/num-primes time: [22.424 ms 22.690 ms 23.073 ms] primality check (u2048)/glass_pumpkin time: [5.7849 ms 5.8078 ms 5.8308 ms] primality check (u2048)/glass_pumpkin (BPSW) time: [5.8614 ms 5.9120 ms 5.9677 ms] safe primality check (u2048)/num-prime (this crate) time: [15.183 ms 15.269 ms 15.358 ms] safe primality check (u2048)/num-primes time: [46.018 ms 47.346 ms 48.770 ms] safe primality check (u2048)/glass_pumpkin time: [5.7260 ms 5.7565 ms 5.7890 ms] safe primality check (u2048)/glass_pumpkin (BPSW) time: [5.6429 ms 5.6716 ms 5.7022 ms] factorize (u64)/num-prime (this crate) time: [9.8809 ms 9.9713 ms 10.071 ms] factorize (u64)/number-theory time: [38.202 ms 38.307 ms 38.417 ms] prime generation (256 bits)/num-prime (this crate) time: [1.5424 ms 1.5778 ms 1.6093 ms] prime generation (256 bits)/num-primes time: [6.0673 ms 6.4005 ms 6.7287 ms] prime generation (256 bits)/glass_pumpkin time: [2.3650 ms 2.4890 ms 2.6202 ms] safe prime generation (256 bits)/num-prime (this crate) time: [116.29 ms 168.60 ms 232.87 ms] safe prime generation (256 bits)/num-primes time: [1.1444 s 1.6604 s 2.1542 s] safe prime generation (256 bits)/glass_pumpkin time: [213.55 ms 432.20 ms 677.55 ms] ```num-prime-0.4.4/README.md000064400000000000000000000023530072674642500130540ustar 00000000000000# num-prime This crate provides utilities for prime number related functionalities: - Primality testing - Deterministic primality check of `u64` integers (using a very fast hashing algorithm) - Fermat probable prime test - Miller-rabin probable prime test - (strong/extra strong) Lucas probable prime test - Baillie-PSW test - Sophie Germain safe prime test - Primes generation and indexing - A naive implementation of the sieve of Eratosthenes - Unified API to support other prime generation backends - Generate random (safe) primes - Find previous/next prime - Integer factorization - Trial division - Pollard's rho algorithm - Shanks's square forms factorization (SQUFOF) - Fast factorization of `u64` and `u128` integers - Number theoretic functions - Prime Pi function (number of primes under limit), its estimation and its bounds - Nth prime, its estimation and its bounds - Moebius function - Divisor Sigma function *([in examples](./examples/divisor_sigma.rs))* - Prime Omega function *([in examples](./examples/prime_omega.rs))* It's based on the `num` creates and most functions are decently optimized with pre-computed tables (see **[benchmark results here](./PERFORMANCE.md)**). num-prime-0.4.4/ROADMAP.md000064400000000000000000000014160072674642500132010ustar 00000000000000# Roadmap for v0.next - Implement SIQS - Euler totient - support `primal` as backend # Roadmap for v1 - Support modular integer in a unified API - Stablize API, determine minimal verison for each dependency - Support no_std - Split the nt_funcs, factor and primality modules into sub files, and put the tables into the related files. # Undetermined - Use NumAssign as trait bounds and see if there's prominent performance improvement - Support `rug` and `ibig` as backend - Support `rug` & `primal` or `primesieve-sys` as PrimeBuffer backend - Support async and multi-thread - Implement factorization for Gaussian integers (and other quadratic integers?) # Not in plan - Support number field sieve factorization (this is efficient only for very larg numbers) num-prime-0.4.4/examples/divisor_sigma.rs000064400000000000000000000020300072674642500166100ustar 00000000000000use num_prime::nt_funcs::factorize64; /// Return all divisors of the target fn divisors(target: u64) -> Vec { let factors = factorize64(target); let mut result = Vec::with_capacity(factors.iter().map(|(_, e)| e + 1).product()); result.push(1); for (p, e) in factors { // the new results contain all previous divisors multiplied by p, p^2, .., p^e let mut new_result = Vec::with_capacity(result.len() * e); for i in 1..(e as u32 + 1) { new_result.extend(result.iter().map(|f| f * p.pow(i))); } result.append(&mut new_result); } result } /// Calculate the divisor sigma function σ_z(n) on the target /// Reference: fn divisor_sigma(target: u64, z: u32) -> u64 { divisors(target).into_iter().map(|d| d.pow(z)).sum() } fn main() { println!("Divisor sigma with z=1 of numbers from 10 to 99:"); for i in 10..100 { println!("{}: {:?}", i, divisor_sigma(i, 1)); } } num-prime-0.4.4/examples/find_lucky_primes.rs000064400000000000000000000016440072674642500174710ustar 00000000000000use num_prime::nt_funcs::is_prime64; /// Find all lucky numbers under limit /// Referece: fn list_lucky_numbers(limit: u64) -> Vec { let mut k = 1; let mut numbers: Vec<_> = (1..limit).step_by(2).collect(); while k < numbers.len() / 2 { let step = numbers[k] as usize; numbers = numbers .into_iter() .enumerate() .filter(|(i, _)| (i + 1) % step != 0) .map(|(_, n)| n) .collect(); k += 1; } numbers } /// Find all lucky primes under limit. /// Reference: fn list_lucky_primes(limit: u64) -> Vec { list_lucky_numbers(limit) .into_iter() .filter(|p| is_prime64(*p)) .collect() } fn main() { println!("Lucky primes under 256: {:?}", list_lucky_primes(256)); } num-prime-0.4.4/examples/find_mersenne_primes.rs000064400000000000000000000006550072674642500201570ustar 00000000000000use num_prime::nt_funcs::{is_prime, primes}; /// Find all mersenne primes 2^p-1 where p < 128, return a list of p fn list_mersenne() -> Vec { primes(128) .into_iter() .filter(|p| is_prime(&(2u128.pow(*p as u32) - 1), None).probably()) .collect() } fn main() { println!("Mersenne primes under 2^128:"); for p in list_mersenne() { println!("2^{} - 1", p); } } num-prime-0.4.4/examples/prime_omega.rs000064400000000000000000000012700072674642500162420ustar 00000000000000use num_prime::nt_funcs::factorize64; /// Calculate the (small) prime omega function ω(n) on the target /// Reference: fn prime_omega(target: u64) -> usize { factorize64(target).len() } /// Calculate the (big) prime omega function Ω(n) on the target /// Reference: #[allow(non_snake_case)] fn prime_Omega(target: u64) -> usize { factorize64(target).into_iter().map(|(_, e)| e).sum() } fn main() { println!("Prime omega of numbers from 10 to 99:"); for i in 10..100 { println!("{}: ω={}, Ω={}", i, prime_omega(i), prime_Omega(i)); } } num-prime-0.4.4/examples/profile_factorization.py000064400000000000000000000040520072674642500203570ustar 00000000000000# This script plot the result generated by profile_factorization.rs from re import A import pandas as pd import numpy as np from matplotlib import pyplot as plt def plot_n_stats(): table = pd.read_csv("profile_stats.csv") table.drop(columns=["n"], inplace=True) pollard_cols = list(k for k in table.columns if k.startswith("pollard")) squfof_cols = list(k for k in table.columns if k.startswith("squfof")) oneline_cols = list(k for k in table.columns if k.startswith("one_line")) # MAXITER = 1 << 20 # table[table >= MAXITER] = np.nan mean_table = table.groupby(table['n_bits'] // 4).agg(np.nanmean) fig, ax = plt.subplots() mean_table.plot("n_bits", pollard_cols, ax=ax) mean_table.plot("n_bits", squfof_cols, ax=ax) mean_table.plot("n_bits", oneline_cols, ax=ax) ax.set_yscale("log") min_table = table.groupby(table['n_bits'] // 4).agg(np.nanmin) fig, ax = plt.subplots() ax.plot(min_table["n_bits"], np.mean(min_table[pollard_cols], axis=1), label="pollard") ax.plot(min_table["n_bits"], np.mean(min_table[squfof_cols], axis=1), label="squfof") ax.plot(min_table["n_bits"], np.mean(min_table[oneline_cols], axis=1), label="one_line") ax.legend() ax.set_yscale("log") def plot_n_min_stats(): table = pd.read_csv("profile_stats.csv") table.drop(columns=["n"], inplace=True) for k in table.columns: # caculate average time if k.startswith("time_"): table[k] = table[k] / table[k[5:]] print(table[k]) min_table = table.groupby(table['n_bits'] // 4).agg(np.nanmean) # MAXITER = 1 << 24 # table[table >= MAXITER] = np.nan ax = min_table.plot("n_bits", ["pollard_rho", "squfof", "one_line"]) ax.set_yscale("log") ax.set_ylabel("min iters") ax = min_table.plot("n_bits", ["time_pollard_rho", "time_squfof", "time_one_line"]) ax.set_yscale("log") ax.set_ylabel("avg time per iter") if __name__ == "__main__": # plot_n_stats() plot_n_min_stats() plt.show() num-prime-0.4.4/examples/profile_factorization.rs000064400000000000000000000115340072674642500203560ustar 00000000000000use std::fs::File; use std::io::{Error, Write}; use std::time::Instant; use num_prime::factor::{one_line, pollard_rho, squfof, SQUFOF_MULTIPLIERS}; use num_prime::RandPrime; use rand::random; /// Collect the the iteration number of each factorization algorithm with different settings fn profile_n(n: u128) -> Vec<(String, usize)> { let k_squfof: Vec = SQUFOF_MULTIPLIERS.iter().take(10).cloned().collect(); let k_oneline: Vec = vec![1, 360, 480]; const MAXITER: usize = 1 << 20; const POLLARD_REPEATS: usize = 2; let mut n_stats = Vec::new(); // pollard rho for i in 0..POLLARD_REPEATS { n_stats.push(( format!("pollard_rho{}", i + 1), pollard_rho(&n, random(), random(), MAXITER).1, )); } // squfof for &k in &k_squfof { let key = format!("squfof_k{}", k); if let Some(kn) = n.checked_mul(k as u128) { let n = squfof(&n, kn, MAXITER).1; n_stats.push((key, n)); } else { n_stats.push((key, MAXITER)); }; } // one line for &k in &k_oneline { let key = format!("one_line_k{}", k); if let Some(kn) = n.checked_mul(k as u128) { let n = one_line(&n, kn, MAXITER).1; n_stats.push((key, n)); } else { n_stats.push((key, MAXITER)); }; } n_stats } /// Collect the best case of each factorization algorithm fn profile_n_min(n: u128) -> Vec<(String, usize)> { let k_squfof: Vec = SQUFOF_MULTIPLIERS.iter().cloned().collect(); let k_oneline: Vec = vec![1, 360, 480]; const MAXITER: usize = 1 << 24; const POLLARD_REPEATS: usize = 4; let mut n_stats = Vec::new(); // pollard rho let mut pollard_best = (MAXITER, u128::MAX); for _ in 0..POLLARD_REPEATS { let tstart = Instant::now(); let (result, iters) = pollard_rho(&n, random(), random(), pollard_best.0); if result.is_some() { pollard_best = pollard_best.min((iters, tstart.elapsed().as_micros())); } } n_stats.push(("pollard_rho".to_string(), pollard_best.0)); n_stats.push(("time_pollard_rho".to_string(), pollard_best.1 as usize)); // squfof let mut squfof_best = (MAXITER, u128::MAX); for &k in &k_squfof { if let Some(kn) = n.checked_mul(k as u128) { let tstart = Instant::now(); let (result, iters) = squfof(&n, kn, squfof_best.0); if result.is_some() { squfof_best = squfof_best.min((iters, tstart.elapsed().as_micros())); } } } n_stats.push(("squfof".to_string(), squfof_best.0)); n_stats.push(("time_squfof".to_string(), squfof_best.1 as usize)); // one line let mut oneline_best = (MAXITER, u128::MAX); for &k in &k_oneline { if let Some(kn) = n.checked_mul(k as u128) { let tstart = Instant::now(); let (result, iters) = one_line(&n, kn, oneline_best.0); if result.is_some() { oneline_best = oneline_best.min((iters, tstart.elapsed().as_micros())); } } } n_stats.push(("one_line".to_string(), oneline_best.0)); n_stats.push(("time_one_line".to_string(), squfof_best.1 as usize)); n_stats } /// This program try various factorization methods, and log down their iterations number into a csv file fn main() -> Result<(), Error> { let mut rng = rand::thread_rng(); const REPEATS: u32 = 4; let mut n_list = Vec::<(u128, f32)>::new(); // n and bits of n let mut stats: Vec> = Vec::new(); for total_bits in 20..120 { for _ in 0..REPEATS { let p1: u128 = rng.gen_prime(total_bits / 2, None); let p2: u128 = rng.gen_prime_exact(total_bits - (128 - p1.leading_zeros()) as usize, None); if p1 == p2 { continue; } let n = p1 * p2; n_list.push((n, (n as f64).log2() as f32)); println!("Semiprime ({}bits): {} = {} * {}", total_bits, n, p1, p2); // stats.push(profile_n(n)); stats.push(profile_n_min(n)); } } // Log into the CSV file let mut fout = File::create("profile_stats.csv")?; fout.write(b"n,n_bits")?; for k in stats[0].iter().map(|(k, _)| k) { fout.write(b",")?; fout.write(k.as_bytes())?; } for ((n, bits), n_stats) in n_list.iter().zip(stats) { fout.write(b"\n")?; fout.write(n.to_string().as_bytes())?; fout.write(b",")?; fout.write(bits.to_string().as_bytes())?; for (_, v) in n_stats { fout.write(b",")?; fout.write(v.to_string().as_bytes())?; } } Ok(()) } num-prime-0.4.4/src/buffer.rs000064400000000000000000000661360072674642500142140ustar 00000000000000//! Implementations and extensions for [PrimeBuffer], which represents a container of primes //! //! In `num-prime`, there is no global instance to store primes, the user has to generate //! and store the primes themselves. The trait [PrimeBuffer] defines a unified interface //! for a prime number container. Some methods that can take advantage of pre-generated //! primes will be implemented in the [PrimeBufferExt] trait. //! //! We also provide [NaiveBuffer] as a simple implementation of [PrimeBuffer] without any //! external dependencies. The performance of the [NaiveBuffer] will not be extremely optimized, //! but it will be efficient enough for most applications. //! use crate::factor::{pollard_rho, trial_division}; use crate::nt_funcs::{ factorize128, is_prime64, next_prime, nth_prime_bounds, nth_prime_est, prev_prime, }; use crate::primality::{PrimalityBase, PrimalityRefBase}; use crate::tables::{SMALL_PRIMES, SMALL_PRIMES_NEXT}; use crate::traits::{ FactorizationConfig, Primality, PrimalityTestConfig, PrimalityUtils, PrimeBuffer, }; use bitvec::{bitvec, prelude::Msb0}; use lru::LruCache; use num_integer::Roots; use rand::random; use std::collections::BTreeMap; use std::num::NonZeroUsize; /// Extension functions that can utilize pre-generated primes pub trait PrimeBufferExt: for<'a> PrimeBuffer<'a> { /// Test if an integer is a prime. /// /// For targets smaller than 2^64, the deterministic [is_prime64] will be used, otherwise /// the primality test algorithms can be specified by the `config` argument. /// /// The primality test can be either deterministic or probabilistic for large integers depending on the `config`. /// The return value is represented by the enum [Primality], which tells whether the primality test is deterministic /// or probabilistic. fn is_prime( &self, target: &T, config: Option, ) -> Primality where for<'r> &'r T: PrimalityRefBase, { // shortcuts if target.is_even() { return if target == &T::from_u8(2u8).unwrap() { Primality::Yes } else { Primality::No }; } // do deterministic test if target is under 2^64 if let Some(x) = target.to_u64() { return match is_prime64(x) { true => Primality::Yes, false => Primality::No, }; } let config = config.unwrap_or(PrimalityTestConfig::default()); let mut probability = 1.; // miller-rabin test let mut witness_list: Vec = Vec::new(); if config.sprp_trials > 0 { witness_list.extend(self.iter().take(config.sprp_trials)); probability *= 1. - 0.25f32.powi(config.sprp_trials as i32); } if config.sprp_random_trials > 0 { for _ in 0..config.sprp_random_trials { // we have ensured target is larger than 2^64 let mut w: u64 = rand::random(); while witness_list.iter().find(|&x| x == &w).is_some() { w = rand::random(); } witness_list.push(w); } probability *= 1. - 0.25f32.powi(config.sprp_random_trials as i32); } if !witness_list .into_iter() .all(|x| target.is_sprp(T::from_u64(x).unwrap())) { return Primality::No; } // lucas probable prime test if config.slprp_test { probability *= 1. - 4f32 / 15f32; if !target.is_slprp(None, None) { return Primality::No; } } if config.eslprp_test { probability *= 1. - 4f32 / 15f32; if !target.is_eslprp(None) { return Primality::No; } } Primality::Probable(probability) } /// Factorize an integer. /// /// For targets smaller than 2^64, the efficient [factorize64] will be used, otherwise /// the primality test and factorization algorithms can be specified by the `config` argument. /// /// The factorization result consists of two parts. The first is a map from prime factors to their exponents. /// If the factorization failed, the second part will be the remaining cofactors that are not factored, otherwise None /// is returned for the second part. It's ensured that the product of prime factors (and remaining cofactors if exist) /// is equal to the original target. fn factors( &self, target: T, config: Option, ) -> (BTreeMap, Option>) where for<'r> &'r T: PrimalityRefBase, { // shortcut if the target is in u128 range if let Some(x) = target.to_u128() { let factors = factorize128(x) .into_iter() .map(|(k, v)| (T::from_u128(k).unwrap(), v)) .collect(); return (factors, None); } let config = config.unwrap_or(FactorizationConfig::default()); // test the existing primes let (result, factored) = trial_division(self.iter().cloned(), target, config.td_limit); let mut result: BTreeMap = result .into_iter() .map(|(k, v)| (T::from_u64(k).unwrap(), v)) .collect(); // TODO: check is_perfect_power before other methods // find factors by dividing let mut failed = Vec::new(); let mut config = config; config.td_limit = Some(0); // disable trial division when finding divisor match factored { Ok(res) => { if !res.is_one() { result.insert(res, 1); } } Err(res) => { let mut todo = vec![res]; while let Some(target) = todo.pop() { if self .is_prime(&target, Some(config.primality_config)) .probably() { *result.entry(target).or_insert(0) += 1; } else { if let Some(divisor) = self.divisor(&target, &mut config) { todo.push(divisor.clone()); todo.push(target / divisor); } else { failed.push(target); } } } } }; if failed.is_empty() { (result, None) } else { (result, Some(failed)) } } /// Factorize an integer until all prime factors are found. /// /// This function will try to call [factors] function repeatedly until the target /// is fully factorized. fn factorize(&self, target: T) -> BTreeMap where for<'r> &'r T: PrimalityRefBase, { // TODO: prevent overhead of repeat trial division loop { let (result, remainder) = self.factors(target.clone(), None); if remainder.is_none() { break result; } } } /// Return a proper divisor of target (randomly), even works for very large numbers. /// Return `None` if no factor is found. /// /// Note: this method will not do a primality check fn divisor(&self, target: &T, config: &mut FactorizationConfig) -> Option where for<'r> &'r T: PrimalityRefBase, { if matches!(config.td_limit, Some(0)) { // try to get a factor by trial division let tsqrt: T = Roots::sqrt(target) + T::one(); let limit = if let Some(l) = config.td_limit { tsqrt.clone().min(T::from_u64(l).unwrap()) } else { tsqrt.clone() }; for p in self.iter().map(|p| T::from_u64(*p).unwrap()) { if &p > &tsqrt { return None; // the number is a prime } if &p > &limit { break; } if target.is_multiple_of(&p) { return Some(p); } } } // try to get a factor using pollard_rho with 4x4 trials let below64 = target.to_u64().is_some(); while config.rho_trials > 0 { let (start, offset) = if below64 { ( T::from_u8(random::()).unwrap() % target, T::from_u8(random::()).unwrap() % target, ) } else { ( T::from_u64(random::()).unwrap() % target, T::from_u64(random::()).unwrap() % target, ) }; config.rho_trials -= 1; // TODO: change to a reasonable pollard rho limit // TODO: add other factorization methods if let (Some(p), _) = pollard_rho(target, start, offset, 1048576) { return Some(p); } } None } } impl PrimeBufferExt for T where for<'a> T: PrimeBuffer<'a> {} /// NaiveBuffer implements a very simple Sieve of Eratosthenes pub struct NaiveBuffer { list: Vec, // list of found prime numbers next: u64, // all primes smaller than this value has to be in the prime list, should be an odd number } impl NaiveBuffer { #[inline] pub fn new() -> Self { let list = SMALL_PRIMES.iter().map(|&p| p as u64).collect(); NaiveBuffer { list, next: SMALL_PRIMES_NEXT, } } } impl<'a> PrimeBuffer<'a> for NaiveBuffer { type PrimeIter = std::slice::Iter<'a, u64>; fn contains(&self, num: u64) -> bool { self.list.binary_search(&num).is_ok() } fn clear(&mut self) { self.list.truncate(16); self.list.shrink_to_fit(); self.next = 55; // 16-th prime is 53 } fn iter(&'a self) -> Self::PrimeIter { self.list.iter() } fn bound(&self) -> u64 { *self.list.last().unwrap() } fn reserve(&mut self, limit: u64) { let sieve_limit = (limit | 1) + 2; // make sure sieving limit is odd and larger than limit let current = self.next; // prevent borrowing self debug_assert!(current % 2 == 1); if sieve_limit < current { return; } // create sieve and filter with existing primes let mut sieve = bitvec![usize, Msb0; 0; ((sieve_limit - current) / 2) as usize]; for p in self.list.iter().skip(1) { // skip pre-filtered 2 let start = if p * p < current { p * ((current / p) | 1) // start from an odd factor } else { p * p }; for multi in (start..sieve_limit).step_by(2 * (*p as usize)) { if multi >= current { sieve.set(((multi - current) / 2) as usize, true); } } } // sieve with new primes for p in (current..Roots::sqrt(&sieve_limit) + 1).step_by(2) { for multi in (p * p..sieve_limit).step_by(2 * (p as usize)) { if multi >= current { sieve.set(((multi - current) / 2) as usize, true); } } } // collect the sieve self.list .extend(sieve.iter_zeros().map(|x| (x as u64) * 2 + current)); self.next = sieve_limit; } } impl NaiveBuffer { // FIXME: These functions could be implemented in the trait, but only after // RFC 2071 and https://github.com/cramertj/impl-trait-goals/issues/3 /// Calculate the primorial function pub fn primorial(&mut self, n: usize) -> T { self.nprimes(n).map(|&p| T::from_u64(p).unwrap()).product() } /// Returns all primes ≤ `limit`. The primes are sorted. // TODO: let primes return &[u64] instead of iterator, and create a separate iterator // for endless prime iter. This can be a method in this trait, or standalone function, // or implement as IntoIter. We can try to implement PrimeBuffer on primal first and see // if it's reasonable to unifiy pub fn primes(&mut self, limit: u64) -> std::iter::Take<::PrimeIter> { self.reserve(limit); let position = match self.list.binary_search(&limit) { Ok(p) => p + 1, Err(p) => p, }; // into_ok_or_err() return self.list.iter().take(position); } /// Returns all primes ≤ `limit` and takes ownership. The primes are sorted. pub fn into_primes(mut self, limit: u64) -> std::vec::IntoIter { self.reserve(limit); let position = match self.list.binary_search(&limit) { Ok(p) => p + 1, Err(p) => p, }; // into_ok_or_err() self.list.truncate(position); return self.list.into_iter(); } /// Returns primes of certain amount counting from 2. The primes are sorted. pub fn nprimes(&mut self, count: usize) -> std::iter::Take<::PrimeIter> { let (_, bound) = nth_prime_bounds(&(count as u64)) .expect("Estimated size of the largest prime will be larger than u64 limit"); self.reserve(bound); debug_assert!(self.list.len() >= count); self.list.iter().take(count) } /// Returns primes of certain amount counting from 2 and takes ownership. The primes are sorted. pub fn into_nprimes(mut self, count: usize) -> std::vec::IntoIter { let (_, bound) = nth_prime_bounds(&(count as u64)) .expect("Estimated size of the largest prime will be larger than u64 limit"); self.reserve(bound); debug_assert!(self.list.len() >= count); self.list.truncate(count); return self.list.into_iter(); } /// Get the n-th prime (n counts from 1). /// /// Theoretically the result can be larger than 2^64, but it will takes forever to /// calculate that so we just return `u64` instead of `Option` here. pub fn nth_prime(&mut self, n: u64) -> u64 { if n < self.list.len() as u64 { return self.list[n as usize - 1]; } // Directly sieve if the limit is small const THRESHOLD_NTH_PRIME_SIEVE: u64 = 4096; if n <= THRESHOLD_NTH_PRIME_SIEVE { return *self.nprimes(n as usize).last().unwrap(); } // Check primes starting from estimation let mut x = prev_prime(&nth_prime_est(&n).unwrap(), None).unwrap(); let mut pi = self.prime_pi(x); while pi > n { x = prev_prime(&x, None).unwrap(); pi -= 1; } while pi < n { x = next_prime(&x, None).unwrap(); pi += 1; } x } /// Legendre's phi function, used as a helper function for [Self::prime_pi] pub fn prime_phi(&mut self, x: u64, a: usize, cache: &mut LruCache<(u64, usize), u64>) -> u64 { if a == 1 { return (x + 1) / 2; } if let Some(v) = cache.get(&(x, a)) { return *v; } let t1 = self.prime_phi(x, a - 1, cache); let pa = self.nth_prime(a as u64); let t2 = self.prime_phi(x / pa, a - 1, cache); let t = t1 - t2; cache.put((x, a), t); t } /// Calculate the prime π function, i.e. number of primes ≤ `limit`. /// /// Meissel-Lehmer method will be used if the input `limit` is large enough. pub fn prime_pi(&mut self, limit: u64) -> u64 { // Directly sieve if the limit is small const THRESHOLD_PRIME_PI_SIEVE: u64 = 38873; // 4096th prime if &limit <= self.list.last().unwrap() || limit <= THRESHOLD_PRIME_PI_SIEVE { self.reserve(limit); return match self.list.binary_search(&limit) { Ok(pos) => (pos + 1) as u64, Err(pos) => pos as u64, }; } // Then use Meissel-Lehmer method. let b = limit.sqrt(); let a = b.sqrt(); let c = limit.cbrt(); self.reserve(b); let a = self.prime_pi(a); let b = self.prime_pi(b); let c = self.prime_pi(c); let cache_cap = NonZeroUsize::new(a as usize).unwrap(); // a > 0 because limit > THRESHOLD_PRIME_PI_SIEVE let mut phi_cache = LruCache::new(cache_cap); let mut sum = self.prime_phi(limit, a as usize, &mut phi_cache) + (b + a - 2) * (b - a + 1) / 2; for i in a + 1..b + 1 { let w = limit / self.nth_prime(i); sum -= self.prime_pi(w); if i <= c { let l = self.prime_pi(w.sqrt()); sum += (l * (l - 1) - i * (i - 3)) / 2 - 1; for j in i..(l + 1) { let pj = self.nth_prime(j); sum -= self.prime_pi(w / pj); } } } return sum; } } #[cfg(test)] mod tests { use super::*; use crate::mint::SmallMint; #[cfg(feature = "num-bigint")] use core::str::FromStr; #[cfg(feature = "num-bigint")] use num_bigint::BigUint; use rand::random; #[test] fn prime_generation_test() { const PRIME50: [u64; 15] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]; const PRIME300: [u64; 62] = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, ]; let mut pb = NaiveBuffer::new(); assert_eq!(pb.primes(50).cloned().collect::>(), PRIME50); assert_eq!(pb.primes(300).cloned().collect::>(), PRIME300); // test when limit itself is a prime pb.clear(); assert_eq!(pb.primes(293).cloned().collect::>(), PRIME300); pb = NaiveBuffer::new(); assert_eq!(*pb.primes(257).last().unwrap(), 257); // boundary of small table pb = NaiveBuffer::new(); assert_eq!(*pb.primes(8167).last().unwrap(), 8167); // boundary of large table } #[test] fn nth_prime_test() { let mut pb = NaiveBuffer::new(); assert_eq!(pb.nth_prime(10000), 104729); assert_eq!(pb.nth_prime(20000), 224737); assert_eq!(pb.nth_prime(10000), 104729); // use existing primes // Riemann zeta based, test on OEIS:A006988 assert_eq!(pb.nth_prime(10u64.pow(4)), 104729); assert_eq!(pb.nth_prime(10u64.pow(5)), 1299709); assert_eq!(pb.nth_prime(10u64.pow(6)), 15485863); assert_eq!(pb.nth_prime(10u64.pow(7)), 179424673); } #[test] fn prime_pi_test() { let mut pb = NaiveBuffer::new(); assert_eq!(pb.prime_pi(8161), 1024); // 8161 is the 1024th prime assert_eq!(pb.prime_pi(10000), 1229); assert_eq!(pb.prime_pi(20000), 2262); assert_eq!(pb.prime_pi(38873), 4096); pb.clear(); // sieving from scratch assert_eq!(pb.prime_pi(8161), 1024); assert_eq!(pb.prime_pi(10000), 1229); assert_eq!(pb.prime_pi(20000), 2262); assert_eq!(pb.prime_pi(10000), 1229); // use existing primes // Meissel–Lehmer algorithm, test on OEIS:A006880 assert_eq!(pb.prime_pi(10u64.pow(5)), 9592); assert_eq!(pb.prime_pi(10u64.pow(6)), 78498); assert_eq!(pb.prime_pi(10u64.pow(7)), 664579); assert_eq!(pb.prime_pi(10u64.pow(8)), 5761455); } #[test] fn is_prime_test() { // test for is_prime let pb = NaiveBuffer::new(); // some mersenne numbers assert_eq!(pb.is_prime(&(2u32.pow(19) - 1), None), Primality::Yes); assert_eq!(pb.is_prime(&(2u32.pow(23) - 1), None), Primality::No); assert!(matches!( pb.is_prime(&(2u128.pow(89) - 1), None), Primality::Probable(_) )); assert!(matches!( pb.is_prime(&SmallMint::from(2u128.pow(89) - 1), None), Primality::Probable(_) )); // test against small prime assertion for _ in 0..100 { let target = random::(); assert_eq!( !is_prime64(target), matches!( pb.is_prime(&target, Some(PrimalityTestConfig::bpsw())), Primality::No ) ); } // test large numbers const P: u128 = 18699199384836356663; // https://golang.org/issue/638 assert!(matches!(pb.is_prime(&P, None), Primality::Probable(_))); assert!(matches!( pb.is_prime(&P, Some(PrimalityTestConfig::bpsw())), Primality::Probable(_) )); assert!(matches!( pb.is_prime(&SmallMint::from(P), None), Primality::Probable(_) )); assert!(matches!( pb.is_prime(&SmallMint::from(P), Some(PrimalityTestConfig::bpsw())), Primality::Probable(_) )); const P2: u128 = 2019922777445599503530083; assert!(matches!(pb.is_prime(&P2, None), Primality::Probable(_))); assert!(matches!( pb.is_prime(&P2, Some(PrimalityTestConfig::bpsw())), Primality::Probable(_) )); assert!(matches!( pb.is_prime(&SmallMint::from(P2), None), Primality::Probable(_) )); assert!(matches!( pb.is_prime(&SmallMint::from(P2), Some(PrimalityTestConfig::bpsw())), Primality::Probable(_) )); #[cfg(feature = "num-bigint")] { let large_primes = [ "98920366548084643601728869055592650835572950932266967461790948584315647051443", "94560208308847015747498523884063394671606671904944666360068158221458669711639", // http://primes.utm.edu/lists/small/small3.html "449417999055441493994709297093108513015373787049558499205492347871729927573118262811508386655998299074566974373711472560655026288668094291699357843464363003144674940345912431129144354948751003607115263071543163", "230975859993204150666423538988557839555560243929065415434980904258310530753006723857139742334640122533598517597674807096648905501653461687601339782814316124971547968912893214002992086353183070342498989426570593", "5521712099665906221540423207019333379125265462121169655563495403888449493493629943498064604536961775110765377745550377067893607246020694972959780839151452457728855382113555867743022746090187341871655890805971735385789993", "203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123", // ECC primes: http://tools.ietf.org/html/draft-ladd-safecurves-02 "3618502788666131106986593281521497120414687020801267626233049500247285301239", // Curve1174: 2^251-9 "57896044618658097711785492504343953926634992332820282019728792003956564819949", // Curve25519: 2^255-19 "9850501549098619803069760025035903451269934817616361666987073351061430442874302652853566563721228910201656997576599", // E-382: 2^382-105 "42307582002575910332922579714097346549017899709713998034217522897561970639123926132812109468141778230245837569601494931472367", // Curve41417: 2^414-17 "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", // E-521: 2^521-1 // https://github.com/AtropineTears/num-primes/issues/1#issuecomment-934629597 "169511182982703321453314585423962898651587669459838234386506572286328885534468792292646838949809616446341407457141008401355628947670484184607678853094537849610289912805960069455687743151708433319901176932959509872662610091644590437761688516626993416011399330087939042347256922771590903190536793274742859624657" ]; for pstr in large_primes { assert!( pb.is_prime(&BigUint::from_str(pstr).unwrap(), None) .probably(), "false negative prime {}", pstr ) } let large_composites = [ "21284175091214687912771199898307297748211672914763848041968395774954376176754", "6084766654921918907427900243509372380954290099172559290432744450051395395951", "84594350493221918389213352992032324280367711247940675652888030554255915464401", "82793403787388584738507275144194252681", // Arnault, "Rabin-Miller Primality Test: Composite Numbers Which Pass It", // Mathematics of Computation, 64(209) (January 1995), pp. 335-361. "1195068768795265792518361315725116351898245581", // strong pseudoprime to prime bases 2 through 29 // strong pseudoprime to all prime bases up to 200 "8038374574536394912570796143419421081388376882875581458374889175222974273765333652186502336163960045457915042023603208766569966760987284043965408232928738791850869166857328267761771029389697739470167082304286871099974399765441448453411558724506334092790222752962294149842306881685404326457534018329786111298960644845216191652872597534901", ]; for cstr in large_composites { assert!( !pb.is_prime( &BigUint::from_str(cstr).unwrap(), Some(PrimalityTestConfig::bpsw()) ) .probably(), "false positive prime {}", cstr ) } } } #[test] fn pb_factors_test() { let pb = NaiveBuffer::new(); #[cfg(feature = "num-bigint")] { let m131 = BigUint::from(2u8).pow(131) - 1u8; // m131/263 is a large prime let (fac, r) = pb.factors(m131, None); assert!(fac.len() == 2 && r.is_none()); } } } num-prime-0.4.4/src/factor.rs000064400000000000000000000320450072674642500142110ustar 00000000000000//! Implementations for various factorization algorithms. //! //! Note general prime number field sieve is not planned to be implemented, since it's too complex //! //! See //! for a detailed comparison between different factorization algorithms // XXX: make the factorization method resumable? Maybe let all of them returns a Future use crate::traits::ExactRoots; use num_integer::{Integer, Roots}; use num_modular::{ModularCoreOps, ModularUnaryOps}; use num_traits::{CheckedAdd, FromPrimitive, NumRef, RefNum}; use std::collections::BTreeMap; /// Find factors by trial division, returns a tuple of the found factors and the residual. /// /// The target is guaranteed fully factored only if bound * bound > target, where bound = max(primes). /// The parameter limit additionally sets the maximum of primes to be tried. /// The residual will be Ok(1) or Ok(p) if fully factored. /// /// TODO: implement fast check for small primes with BigInts in the precomputed table, and skip them in this function pub fn trial_division< I: Iterator, T: Integer + Clone + Roots + NumRef + FromPrimitive, >( primes: I, target: T, limit: Option, ) -> (BTreeMap, Result) where for<'r> &'r T: RefNum, { let tsqrt: T = Roots::sqrt(&target) + T::one(); let limit = if let Some(l) = limit { tsqrt.clone().min(T::from_u64(l).unwrap()) } else { tsqrt.clone() }; let mut residual = target; let mut result = BTreeMap::new(); let mut factored = false; for (p, pt) in primes.map(|p| (p, T::from_u64(p).unwrap())) { if &pt > &tsqrt { factored = true; } if &pt > &limit { break; } while residual.is_multiple_of(&pt) { residual = residual / &pt; *result.entry(p).or_insert(0) += 1; } if residual.is_one() { factored = true; break; } } if factored { (result, Ok(residual)) } else { (result, Err(residual)) } } /// Find factors using Pollard's rho algorithm with Brent's loop detection algorithm /// /// The returned values are the factor and the count of passed iterations. pub fn pollard_rho< T: Integer + FromPrimitive + NumRef + Clone + for<'r> ModularCoreOps<&'r T, &'r T, Output = T> + for<'r> ModularUnaryOps<&'r T, Output = T>, >( target: &T, start: T, offset: T, max_iter: usize, ) -> (Option, usize) where for<'r> &'r T: RefNum, { let mut a = start.clone(); let mut b = start.clone(); let mut z = T::one() % target; // accumulator for gcd // using Brent's loop detection, i = tortoise, j = hare let (mut i, mut j) = (0usize, 1usize); // backtracing states let mut s = start; let mut backtrace = false; while i < max_iter { i += 1; a = a.sqm(&target).addm(&offset, &target); if a == b { return (None, i); } // FIXME: optimize abs_diff for montgomery form if we are going to use the abs_diff in the std lib let diff = if b > a { &b - &a } else { &a - &b }; // abs_diff z = z.mulm(&diff, &target); if z.is_zero() { // the factor is missed by a combined GCD, do backtracing if backtrace { // ultimately failed return (None, i); } else { backtrace = true; a = std::mem::replace(&mut s, T::one()); // s is discarded z = T::one() % target; // clear gcd continue; } } // here we check gcd every 2^k steps or 128 steps // larger batch size leads to large overhead when backtracing. // reference: https://www.cnblogs.com/812-xiao-wen/p/10544546.html if i == j || i & 127 == 0 || backtrace { let d = z.gcd(target); if !d.is_one() && &d != target { return (Some(d), i); } // save state s = a.clone(); } // when tortoise catches up with hare, let hare jump to the next stop if i == j { b = a.clone(); j <<= 1; } } (None, i) } /// This function implements Shanks's square forms factorization (SQUFOF). /// /// The input is usually multiplied by a multiplier, and the multiplied integer should be put in /// the `mul_target` argument. The multiplier can be choosen from SQUFOF_MULTIPLIERS, or other square-free odd numbers. /// The returned values are the factor and the count of passed iterations. /// /// The max iteration can be choosed as 2*n^(1/4), based on Theorem 4.22 from [1]. /// /// Reference: Gower, J., & Wagstaff Jr, S. (2008). Square form factorization. /// In [1] [Mathematics of Computation](https://homes.cerias.purdue.edu/~ssw/gowerthesis804/wthe.pdf) /// or [2] [his thesis](https://homes.cerias.purdue.edu/~ssw/gowerthesis804/wthe.pdf) /// The code is from [3] [Rosetta code](https://rosettacode.org/wiki/Square_form_factorization) pub fn squfof( target: &T, mul_target: T, max_iter: usize, ) -> (Option, usize) where for<'r> &'r T: RefNum, { assert!( &mul_target.is_multiple_of(&target), "mul_target should be multiples of target" ); let rd = Roots::sqrt(&mul_target); // root of k*N /// Reduction operator for binary quadratic forms. It's equivalent to /// the one used in the `num-irrational` crate, in a little different form. /// /// This function reduces (a, b, c) = (qm1, p, q), updates qm1 and q, returns new p. #[inline] fn rho(rd: &T, p: &T, q: &mut T, qm1: &mut T) -> T where for<'r> &'r T: RefNum, { let b = (rd + p).div_floor(&*q); let new_p = &b * &*q - p; let new_q = if p > &new_p { &*qm1 + b * (p - &new_p) } else { &*qm1 - b * (&new_p - p) }; *qm1 = std::mem::replace(q, new_q); new_p } // forward loop, search principal cycle let (mut p, mut q, mut qm1) = (rd.clone(), &mul_target - &rd * &rd, T::one()); if q.is_zero() { // shortcut for perfect square return (Some(rd), 0); } for i in 1..max_iter { p = rho(&rd, &p, &mut q, &mut qm1); if i.is_odd() { if let Some(rq) = q.sqrt_exact() { let b = (&rd - &p) / &rq; let mut u = b * &rq + &p; let (mut v, mut vm1) = ((&mul_target - &u * &u) / &rq, rq); // backward loop, search ambiguous cycle loop { let new_u = rho(&rd, &u, &mut v, &mut vm1); if new_u == u { break; } else { u = new_u } } let d = target.gcd(&u); if d > T::one() && &d < target { return (Some(d), i); } } } } (None, max_iter) } /// Good squfof multipliers sorted by efficiency descendingly, from Dana Jacobsen. /// /// Note: square-free odd numbers are suitable as SQUFOF multipliers pub const SQUFOF_MULTIPLIERS: [u16; 38] = [ 3 * 5 * 7 * 11, 3 * 5 * 7, 3 * 5 * 7 * 11 * 13, 3 * 5 * 7 * 13, 3 * 5 * 7 * 11 * 17, 3 * 5 * 11, 3 * 5 * 7 * 17, 3 * 5, 3 * 5 * 7 * 11 * 19, 3 * 5 * 11 * 13, 3 * 5 * 7 * 19, 3 * 5 * 7 * 13 * 17, 3 * 5 * 13, 3 * 7 * 11, 3 * 7, 5 * 7 * 11, 3 * 7 * 13, 5 * 7, 3 * 5 * 17, 5 * 7 * 13, 3 * 5 * 19, 3 * 11, 3 * 7 * 17, 3, 3 * 11 * 13, 5 * 11, 3 * 7 * 19, 3 * 13, 5, 5 * 11 * 13, 5 * 7 * 19, 5 * 13, 7 * 11, 7, 3 * 17, 7 * 13, 11, 1, ]; /// William Hart's one line factorization algorithm for 64 bit integers. /// /// The number to be factored could be multiplied by a smooth number (coprime to the target) /// to speed up, put the multiplied number in the `mul_target` argument. A good multiplier given by Hart is 480. /// `iters` determine the range for iterating the inner multiplier itself. The returned values are the factor /// and the count of passed iterations. /// /// /// The one line factorization algorithm is especially good at factoring semiprimes with form pq, /// where p = next_prime(c^a+d1), p = next_prime(c^b+d2), a and b are close, and c, d1, d2 are small integers. /// /// Reference: Hart, W. B. (2012). A one line factoring algorithm. Journal of the Australian Mathematical Society, 92(1), 61-69. doi:10.1017/S1446788712000146 // TODO: add multipliers preset for one_line method? pub fn one_line( target: &T, mul_target: T, max_iter: usize, ) -> (Option, usize) where for<'r> &'r T: RefNum, { assert!( &mul_target.is_multiple_of(&target), "mul_target should be multiples of target" ); let mut ikn = mul_target.clone(); for i in 1..max_iter { let s = ikn.sqrt() + T::one(); // assuming target is not perfect square let m = &s * &s - &ikn; if let Some(t) = m.sqrt_exact() { let g = target.gcd(&(s - t)); if !g.is_one() && &g != target { return (Some(g), i); } } // prevent overflow ikn = if let Some(n) = (&ikn).checked_add(&mul_target) { n } else { return (None, i); } } return (None, max_iter); } // TODO: ECM, (self initialize) Quadratic sieve, Lehman's Fermat(https://en.wikipedia.org/wiki/Fermat%27s_factorization_method, n_factor_lehman) // REF: https://pypi.org/project/primefac/ // http://flintlib.org/doc/ulong_extras.html#factorisation // https://github.com/zademn/facto-rs/ // https://github.com/elmomoilanen/prime-factorization // https://cseweb.ucsd.edu/~ethome/teaching/2022-cse-291-14/ fn pollard_pp1() {} fn williams_pp1() {} #[cfg(test)] mod tests { use super::*; use crate::mint::SmallMint; use num_modular::MontgomeryInt; use rand::random; #[test] fn pollard_rho_test() { assert_eq!(pollard_rho(&8051u16, 2, 1, 100).0, Some(97)); assert!(matches!(pollard_rho(&8051u16, random(), 1, 100).0, Some(i) if i == 97 || i == 83)); assert_eq!(pollard_rho(&455459u32, 2, 1, 100).0, Some(743)); // Mint test for _ in 0..10 { let target = random::() | 1; let start = random::() % target; let offset = random::() % target; let expect = pollard_rho(&target, start, offset, 65536); let mint_result = pollard_rho( &SmallMint::from(target), MontgomeryInt::new(start, &target).into(), MontgomeryInt::new(offset, &target).into(), 65536, ); assert_eq!(expect.0, mint_result.0.map(|v| v.value())); } } #[test] fn squfof_test() { // case from wikipedia assert_eq!(squfof(&11111u32, 11111u32, 100).0, Some(41)); // cases from https://rosettacode.org/wiki/Square_form_factorization let cases: Vec = vec![ 2501, 12851, 13289, 75301, 120787, 967009, 997417, 7091569, 5214317, 20834839, 23515517, 33409583, 44524219, 13290059, 223553581, 2027651281, 11111111111, 100895598169, 60012462237239, 287129523414791, 9007199254740931, 11111111111111111, 314159265358979323, 384307168202281507, 419244183493398773, 658812288346769681, 922337203685477563, 1000000000000000127, 1152921505680588799, 1537228672809128917, // this case should success at step 276, from https://rosettacode.org/wiki/Talk:Square_form_factorization 4558849, ]; for n in cases { let d = squfof(&n, n, 40000) .0 .or(squfof(&n, 3 * n, 40000).0) .or(squfof(&n, 5 * n, 40000).0) .or(squfof(&n, 7 * n, 40000).0) .or(squfof(&n, 11 * n, 40000).0); assert!(matches!(d, Some(_)), "{}", n); } } #[test] fn one_line_test() { assert_eq!(one_line(&11111u32, 11111u32, 100).0, Some(271)); } } num-prime-0.4.4/src/integer.rs000064400000000000000000000200460072674642500143660ustar 00000000000000//! Backend implementations for integers use crate::tables::{CUBIC_MODULI, CUBIC_RESIDUAL, QUAD_MODULI, QUAD_RESIDUAL}; use crate::traits::{BitTest, ExactRoots}; #[cfg(feature = "num-bigint")] use num_bigint::{BigInt, BigUint, ToBigInt}; #[cfg(feature = "num-bigint")] use num_traits::{One, Signed, ToPrimitive, Zero}; macro_rules! impl_bittest_prim { ($($T:ty)*) => {$( impl BitTest for $T { #[inline] fn bits(&self) -> usize { (<$T>::BITS - self.leading_zeros()) as usize } #[inline] fn bit(&self, position: usize) -> bool { self & (1 << position) > 0 } #[inline] fn trailing_zeros(&self) -> usize { <$T>::trailing_zeros(*self) as usize } } )*} } impl_bittest_prim!(u8 u16 u32 u64 u128 usize); #[cfg(feature = "num-bigint")] impl BitTest for BigUint { fn bit(&self, position: usize) -> bool { self.bit(position as u64) } fn bits(&self) -> usize { BigUint::bits(&self) as usize } #[inline] fn trailing_zeros(&self) -> usize { match BigUint::trailing_zeros(&self) { Some(a) => a as usize, None => 0, } } } macro_rules! impl_exactroot_prim { ($($T:ty)*) => {$( impl ExactRoots for $T { fn sqrt_exact(&self) -> Option { if self < &0 { return None; } let shift = self.trailing_zeros(); // the general form of any square number is (2^(2m))(8N+1) if shift & 1 == 1 { return None; } if (self >> shift) & 7 != 1 { return None; } self.nth_root_exact(2) } } )*}; // TODO: it might worth use QUAD_RESIDUE and CUBIC_RESIDUE for large size // primitive integers, need benchmark } impl_exactroot_prim!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize); #[cfg(feature = "num-bigint")] impl ExactRoots for BigUint { fn sqrt_exact(&self) -> Option { // shortcuts if self.is_zero() { return Some(BigUint::zero()); } if let Some(v) = self.to_u64() { return v.sqrt_exact().map(BigUint::from); } // check mod 2 let shift = self.trailing_zeros().unwrap(); if shift & 1 == 1 { return None; } if !((self >> shift) & BigUint::from(7u8)).is_one() { return None; } // check other moduli #[cfg(not(feature = "big-table"))] for (m, res) in QUAD_MODULI.iter().zip(QUAD_RESIDUAL) { // need to &63 since we have 65 in QUAD_MODULI if (res >> ((self % m).to_u8().unwrap() & 63)) & 1 == 0 { return None; } } #[cfg(feature = "big-table")] for (m, res) in QUAD_MODULI.iter().zip(QUAD_RESIDUAL) { let rem = (self % m).to_u16().unwrap(); if (res[(rem / 64) as usize] >> (rem % 64)) & 1 == 0 { return None; } } self.nth_root_exact(2) } fn cbrt_exact(&self) -> Option { // shortcuts if self.is_zero() { return Some(BigUint::zero()); } if let Some(v) = self.to_u64() { return v.cbrt_exact().map(BigUint::from); } // check mod 2 let shift = self.trailing_zeros().unwrap(); if shift % 3 != 0 { return None; } // check other moduli #[cfg(not(feature = "big-table"))] for (m, res) in CUBIC_MODULI.iter().zip(CUBIC_RESIDUAL) { if (res >> (self % m).to_u8().unwrap()) & 1 == 0 { return None; } } #[cfg(feature = "big-table")] for (m, res) in CUBIC_MODULI.iter().zip(CUBIC_RESIDUAL) { let rem = (self % m).to_u16().unwrap(); if (res[(rem / 64) as usize] >> (rem % 64)) & 1 == 0 { return None; } } self.nth_root_exact(3) } } #[cfg(feature = "num-bigint")] impl ExactRoots for BigInt { fn sqrt_exact(&self) -> Option { self.to_biguint() .and_then(|u| u.sqrt_exact()) .and_then(|u| u.to_bigint()) } fn cbrt_exact(&self) -> Option { self.magnitude() .cbrt_exact() .and_then(|u| u.to_bigint()) .map(|v| if self.is_negative() { -v } else { v }) } } #[cfg(test)] mod tests { use super::*; use rand; #[test] fn exact_root_test() { // some simple tests assert!(matches!(ExactRoots::sqrt_exact(&3u8), None)); assert!(matches!(ExactRoots::sqrt_exact(&4u8), Some(2))); assert!(matches!(ExactRoots::sqrt_exact(&9u8), Some(3))); assert!(matches!(ExactRoots::sqrt_exact(&18u8), None)); assert!(matches!(ExactRoots::sqrt_exact(&3i8), None)); assert!(matches!(ExactRoots::sqrt_exact(&4i8), Some(2))); assert!(matches!(ExactRoots::sqrt_exact(&9i8), Some(3))); assert!(matches!(ExactRoots::sqrt_exact(&18i8), None)); // test fast implementations of sqrt against nth_root for _ in 0..100 { let x = rand::random::(); assert_eq!( ExactRoots::sqrt_exact(&x), ExactRoots::nth_root_exact(&x, 2) ); assert_eq!( ExactRoots::cbrt_exact(&x), ExactRoots::nth_root_exact(&x, 3) ); let x = rand::random::(); assert_eq!( ExactRoots::cbrt_exact(&x), ExactRoots::nth_root_exact(&x, 3) ); } // test perfect powers for _ in 0..100 { let x = rand::random::() as u64; assert!(matches!(ExactRoots::sqrt_exact(&(x * x)), Some(v) if v == x)); let x = rand::random::() as i64; assert!(matches!(ExactRoots::cbrt_exact(&(x * x * x)), Some(v) if v == x)); } // test non-perfect powers for _ in 0..100 { let x = rand::random::() as u64; let y = rand::random::() as u64; if x == y { continue; } assert!(ExactRoots::sqrt_exact(&(x * y)).is_none()); } #[cfg(feature = "num-bigint")] { use num_bigint::RandBigInt; let mut rng = rand::thread_rng(); // test fast implementations of sqrt against nth_root for _ in 0..10 { let x = rng.gen_biguint(150); assert_eq!( ExactRoots::sqrt_exact(&x), ExactRoots::nth_root_exact(&x, 2) ); assert_eq!( ExactRoots::cbrt_exact(&x), ExactRoots::nth_root_exact(&x, 3) ); let x = rng.gen_bigint(150); assert_eq!( ExactRoots::cbrt_exact(&x), ExactRoots::nth_root_exact(&x, 3) ); } // test perfect powers for _ in 0..10 { let x = rng.gen_biguint(150); assert!(matches!(ExactRoots::sqrt_exact(&(&x * &x)), Some(v) if v == x)); let x = rng.gen_biguint(150); assert!( matches!(ExactRoots::cbrt_exact(&(&x * &x * &x)), Some(v) if v == x), "failed at {}", x ); } // test non-perfect powers for _ in 0..10 { let x = rng.gen_biguint(150); let y = rng.gen_biguint(150); if x == y { continue; } assert!(ExactRoots::sqrt_exact(&(x * y)).is_none()); } } } } num-prime-0.4.4/src/lib.rs000064400000000000000000000106330072674642500135000ustar 00000000000000// #![doc = include_str!("../README.md")] //! This crate provides utilities for prime related functionalities and some basic number theoretic functions: //! - Primality testing //! - [Primality check][nt_funcs::is_prime] //! - [Deterministic primality check of `u64` integers][nt_funcs::is_prime64] (using a very fast hashing algorithm) //! - [Fermat probable prime test][PrimalityUtils::is_prp] //! - [Miller-rabin probable prime test][PrimalityUtils::is_sprp] //! - ([strong][PrimalityUtils::is_slprp]/[extra strong][PrimalityUtils::is_eslprp]) [Lucas probable prime test][PrimalityUtils::is_lprp] //! - [Baillie-PSW test][PrimalityTestConfig::bpsw] //! - [Sophie Germain safe prime test][nt_funcs::is_safe_prime] //! - Primes generation and indexing //! - [A naive implementation of the sieve of Eratosthenes][buffer::NaiveBuffer] //! - [Unified API to support other prime generation backends][PrimeBuffer] //! - [Generate random (safe) primes][traits::RandPrime] //! - Find [previous prime][nt_funcs::prev_prime] / [next prime][nt_funcs::next_prime] //! - [Integer factorization][nt_funcs::factors] //! - [Trial division][factor::trial_division] //! - [Pollard's rho algorithm][factor::pollard_rho] //! - [Shanks's square forms factorization (SQUFOF)][factor::squfof] //! - [Hart's one line algorithm][factor::one_line] //! - [Fast factorization of `u64` integers][nt_funcs::factorize64] //! - Number theoretic functions //! - [Prime Pi function][nt_funcs::prime_pi], its [estimation](nt_funcs::prime_pi_est), and its [bounds](nt_funcs::prime_pi_bounds) //! - [Nth Prime][nt_funcs::nth_prime], its [estimation](nt_funcs::nth_prime_est), and its [bounds](nt_funcs::nth_prime_bounds) //! - [Moebius function][nt_funcs::moebius] //! //! # Usage //! Most number theoretic functions can be found in [nt_funcs] module, while some //! of them are implemented as member function of [num_modular::ModularOps] or [PrimalityUtils]. //! //! Example code for primality testing and integer factorization: //! ```rust //! use num_prime::{PrimalityTestConfig, FactorizationConfig}; //! use num_prime::nt_funcs::{is_prime, factorize, factors}; //! //! let p = 2u128.pow(89) - 1; // a prime number //! assert!(is_prime(&p, None).probably()); // use default primality check config //! assert!(is_prime(&p, Some(PrimalityTestConfig::bpsw())).probably()); // BPSW test //! //! let c = 2u128.pow(83) - 1; // a composite number //! assert!(!is_prime(&c, None).probably()); //! let fac = factorize(c); // infallible factorization with default configuration //! assert_eq!(fac.len(), 2); // 2^83-1 = 167 * 57912614113275649087721 //! //! let config = FactorizationConfig::strict(); //! let (fac, rem) = factors(c, Some(config)); // fallible factorization with customized configuration //! assert!(fac.len() == 2 && rem.is_none()); //! ``` //! //! # Backends //! This crate is built with modular integer type and prime generation backends. //! Most functions support generic input types, and support for `num-bigint` is //! also available (it's an optional feature). To make a new integer type supported //! by this crate, the type has to implement [detail::PrimalityBase] and [detail::PrimalityRefBase]. //! For prime generation, there's a builtin implementation (see [buffer] module), //! but you can also use other backends (such as `primal`) as long as it implements [PrimeBuffer]. //! //! # Optional Features //! - `big-int` (default): Enable this feature to support `num-bigint::BigUint` as integer inputs. //! - `big-table` (default): Enable this feature to allow compiling large precomputed tables which //! could improve the speed of various functions with the cost of larger memory footprint. //! pub mod buffer; pub mod factor; pub mod nt_funcs; mod integer; mod mint; mod primality; mod rand; mod tables; mod traits; pub use traits::*; pub mod detail { //! Implementation details for this crate. //! //! The structs and traits in this module are exposed for public use, although they are no //! designed for such usage. User-friendly is not a goal and backward-compatilibity is not //! strictly maintained here. Some traits in this module can be used to extend `num-prime` //! with new backends. pub use super::mint::{Mint, SmallMint}; pub use super::primality::{LucasUtils, PrimalityBase, PrimalityRefBase}; pub use super::tables::SMALL_PRIMES; } num-prime-0.4.4/src/mint.rs000064400000000000000000000550260072674642500137060ustar 00000000000000//! Wrapper of integer to makes it efficient in modular arithmetics but still have the same //! API of normal integers. use core::ops::*; use either::*; use num_integer::{Integer, Roots}; use num_modular::{ ModularCoreOps, ModularInteger, ModularPow, ModularSymbols, ModularUnaryOps, Montgomery, ReducedInt, Reducer, }; use num_traits::{FromPrimitive, Num, One, Pow, ToPrimitive, Zero}; use crate::{BitTest, ExactRoots}; /// Integer with fast modular arithmetics support, based on [MontgomeryInt] under the hood /// /// This struct only designed to be working with this crate. Most binary operators assume that /// the modulus of two operands (when in montgomery form) are the same, and most implicit conversions /// between conventional form and montgomery form will be forbidden #[derive(Debug, Clone, Copy)] pub struct Mint>(Either>); impl> From for Mint { #[inline(always)] fn from(v: T) -> Self { Self(Left(v)) } } impl> From> for Mint { #[inline(always)] fn from(v: ReducedInt) -> Self { Self(Right(v)) } } #[inline(always)] fn left_only>(lhs: Mint, rhs: Mint) -> (T, T) { match (lhs.0, rhs.0) { (Left(v1), Left(v2)) => (v1, v2), (_, _) => unreachable!(), } } #[inline(always)] fn left_ref_only<'a, T: Integer, R: Reducer>( lhs: &'a Mint, rhs: &'a Mint, ) -> (&'a T, &'a T) { match (&lhs.0, &rhs.0) { (Left(v1), Left(v2)) => (v1, v2), (_, _) => unreachable!(), } } macro_rules! forward_binops_left_ref_only { ($method:ident) => { #[inline(always)] fn $method(&self, other: &Self) -> Self { let (v1, v2) = left_ref_only(self, other); Self(Left(v1.$method(v2))) } }; ($method:ident => $return:ty) => { #[inline(always)] fn $method(&self, other: &Self) -> $return { let (v1, v2) = left_ref_only(self, other); v1.$method(v2) } }; } macro_rules! forward_uops_ref { ($method:ident => $return:ty) => { #[inline(always)] fn $method(&self) -> $return { match &self.0 { Left(v) => v.$method(), Right(m) => m.residue().$method(), } } }; } impl> PartialEq for Mint { fn eq(&self, other: &Self) -> bool { match (&self.0, &other.0) { (Left(v1), Left(v2)) => v1 == v2, (Right(v1), Right(v2)) => v1 == v2, (_, _) => unreachable!(), // force optimization of equality test } } } impl> Eq for Mint {} impl + Clone> PartialOrd for Mint { fn partial_cmp(&self, other: &Self) -> Option { match (&self.0, &other.0) { (Left(v1), Left(v2)) => v1.partial_cmp(v2), (Left(v1), Right(v2)) => v1.partial_cmp(&v2.residue()), (Right(v1), Left(v2)) => v1.residue().partial_cmp(v2), (Right(v1), Right(v2)) => { debug_assert!(v1.modulus() == v2.modulus()); v1.residue().partial_cmp(&v2.residue()) } } } } impl + Clone> Ord for Mint { fn cmp(&self, other: &Self) -> std::cmp::Ordering { match (&self.0, &other.0) { (Left(v1), Left(v2)) => v1.cmp(v2), (Left(v1), Right(v2)) => v1.cmp(&v2.residue()), (Right(v1), Left(v2)) => v1.residue().cmp(v2), (Right(v1), Right(v2)) => v1.residue().cmp(&v2.residue()), } } } impl + Clone> Mint { #[inline(always)] pub fn value(&self) -> T { match &self.0 { Left(v) => v.clone(), Right(m) => m.residue(), } } } // forward binary operators by converting result to MontgomeryInt whenever possible macro_rules! forward_binops_right { (impl $imp:ident, $method:ident) => { impl + Clone> $imp for Mint { type Output = Self; #[inline] fn $method(self, rhs: Self) -> Self::Output { Self(match (self.0, rhs.0) { (Left(v1), Left(v2)) => Left(v1.$method(v2)), (Left(v1), Right(v2)) => Right(v2.convert(v1).$method(v2)), (Right(v1), Left(v2)) => { let v2 = v1.convert(v2); Right(v1.$method(v2)) } (Right(v1), Right(v2)) => Right(v1.$method(v2)), }) } } impl $imp<&'r T, Output = T>, R: Reducer + Clone> $imp<&Self> for Mint { type Output = Mint; #[inline] fn $method(self, rhs: &Self) -> Self::Output { Mint(match (self.0, &rhs.0) { (Left(v1), Left(v2)) => Left(v1.$method(v2)), (Left(v1), Right(v2)) => Right(v2.convert(v1).$method(v2)), (Right(v1), Left(v2)) => { let v2 = v1.convert(v2.clone()); Right(v1.$method(v2)) } (Right(v1), Right(v2)) => Right(v1.$method(v2)), }) } } impl + Clone> $imp> for &Mint { type Output = Mint; // FIXME: additional clone here due to https://github.com/rust-lang/rust/issues/39959 // (same for ref & ref operation below, and those for Div and Rem) #[inline] fn $method(self, rhs: Mint) -> Self::Output { Mint(match (&self.0, rhs.0) { (Left(v1), Left(v2)) => Left(v1.clone().$method(v2)), (Left(v1), Right(v2)) => Right(v2.convert(v1.clone()).$method(v2)), (Right(v1), Left(v2)) => { let v2 = v1.convert(v2); Right(v1.clone().$method(v2)) } (Right(v1), Right(v2)) => Right(v1.$method(v2)), }) } } impl< 'a, 'b, T: Integer + Clone + for<'r> $imp<&'r T, Output = T>, R: Reducer + Clone, > $imp<&'b Mint> for &'a Mint { type Output = Mint; #[inline] fn $method(self, rhs: &Mint) -> Self::Output { Mint(match (&self.0, &rhs.0) { (Left(v1), Left(v2)) => Left(v1.clone().$method(v2)), (Left(v1), Right(v2)) => Right(v2.convert(v1.clone()).$method(v2)), (Right(v1), Left(v2)) => { let v2 = v1.convert(v2.clone()); Right(v1.clone().$method(v2)) } (Right(v1), Right(v2)) => Right(v1.$method(v2)), }) } } }; } forward_binops_right!(impl Add, add); forward_binops_right!(impl Sub, sub); forward_binops_right!(impl Mul, mul); impl> Div for Mint { type Output = Self; #[inline] fn div(self, rhs: Self) -> Self::Output { let (v1, v2) = left_only(self, rhs); Self(Left(v1.div(v2))) } } impl Div<&'r T, Output = T>, R: Reducer> Div<&Self> for Mint { type Output = Self; #[inline] fn div(self, rhs: &Self) -> Self::Output { match (self.0, &rhs.0) { (Left(v1), Left(v2)) => Self(Left(v1.div(v2))), (_, _) => unreachable!(), } } } impl> Div> for &Mint { type Output = Mint; #[inline] fn div(self, rhs: Mint) -> Self::Output { match (&self.0, rhs.0) { (Left(v1), Left(v2)) => Mint(Left(v1.clone().div(v2))), (_, _) => unreachable!(), } } } impl<'a, 'b, T: Integer + Clone + for<'r> Div<&'r T, Output = T>, R: Reducer> Div<&'b Mint> for &'a Mint { type Output = Mint; #[inline] fn div(self, rhs: &Mint) -> Self::Output { match (&self.0, &rhs.0) { (Left(v1), Left(v2)) => Mint(Left(v1.clone().div(v2))), (_, _) => unreachable!(), } } } impl + Clone> Rem for Mint { type Output = Self; #[inline] fn rem(self, rhs: Self) -> Self::Output { match (self.0, rhs.0) { (Left(v1), Left(v2)) => Self(Right(ReducedInt::new(v1, &v2))), (Right(v1), Left(v2)) => { debug_assert!(v1.modulus() == v2); Self(Right(v1)) } (_, _) => unreachable!(), } } } impl + Clone> Rem<&Self> for Mint { type Output = Self; #[inline] fn rem(self, rhs: &Self) -> Self::Output { match (self.0, &rhs.0) { (Left(v1), Left(v2)) => Self(Right(ReducedInt::new(v1, v2))), (Right(v1), Left(v2)) => { debug_assert!(&v1.modulus() == v2); Self(Right(v1)) } (_, _) => unreachable!(), } } } impl + Clone> Rem> for &Mint { type Output = Mint; #[inline] fn rem(self, rhs: Mint) -> Self::Output { match (&self.0, rhs.0) { (Left(v1), Left(v2)) => Mint(Right(ReducedInt::new(v1.clone(), &v2))), (Right(v1), Left(v2)) => { debug_assert!(v1.modulus() == v2); Mint(Right(v1.clone())) } (_, _) => unreachable!(), } } } impl<'a, 'b, T: Integer + Clone, R: Reducer + Clone> Rem<&'b Mint> for &'a Mint { type Output = Mint; #[inline] fn rem(self, rhs: &Mint) -> Self::Output { match (&self.0, &rhs.0) { (Left(v1), Left(v2)) => Mint(Right(ReducedInt::new(v1.clone(), v2))), (Right(v1), Left(v2)) => { debug_assert!(&v1.modulus() == v2); Mint(Right(v1.clone())) } (_, _) => unreachable!(), } } } impl + Clone> Zero for Mint { #[inline(always)] fn zero() -> Self { Self(Left(T::zero())) } #[inline(always)] fn is_zero(&self) -> bool { match &self.0 { Left(v) => v.is_zero(), Right(m) => m.is_zero(), } } } impl + Clone> One for Mint { #[inline(always)] fn one() -> Self { Self(Left(T::one())) } forward_uops_ref!(is_one => bool); } impl + Clone> Num for Mint { type FromStrRadixErr = ::FromStrRadixErr; #[inline(always)] fn from_str_radix(str: &str, radix: u32) -> Result { T::from_str_radix(str, radix).map(|v| Self(Left(v))) } } impl + Clone> Integer for Mint { forward_binops_left_ref_only!(div_floor); forward_binops_left_ref_only!(mod_floor); forward_binops_left_ref_only!(lcm); forward_binops_left_ref_only!(divides => bool); forward_binops_left_ref_only!(is_multiple_of => bool); forward_uops_ref!(is_even => bool); forward_uops_ref!(is_odd => bool); #[inline(always)] fn div_rem(&self, other: &Self) -> (Self, Self) { let (v1, v2) = left_ref_only(self, other); let (q, r) = v1.div_rem(v2); (Self(Left(q)), Self(Left(r))) } #[inline(always)] fn gcd(&self, other: &Self) -> Self { Self(Left(match (&self.0, &other.0) { (Left(v1), Left(v2)) => v1.gcd(v2), (Right(v1), Left(v2)) => v1.residue().gcd(v2), (Left(v1), Right(v2)) => v1.gcd(&v2.residue()), (Right(v1), Right(v2)) => v1.residue().gcd(&v2.residue()), })) } } impl + Clone> Roots for Mint { #[inline] fn nth_root(&self, n: u32) -> Self { match &self.0 { Left(v) => Self(Left(v.nth_root(n))), Right(_) => unreachable!(), } } } impl> FromPrimitive for Mint { #[inline] fn from_f64(n: f64) -> Option { T::from_f64(n).map(|v| Self(Left(v))) } #[inline] fn from_i64(n: i64) -> Option { T::from_i64(n).map(|v| Self(Left(v))) } #[inline] fn from_u64(n: u64) -> Option { T::from_u64(n).map(|v| Self(Left(v))) } } impl + Clone> ToPrimitive for Mint { #[inline] fn to_f64(&self) -> Option { match &self.0 { Left(v) => v.to_f64(), Right(m) => m.residue().to_f64(), } } #[inline] fn to_i64(&self) -> Option { match &self.0 { Left(v) => v.to_i64(), Right(m) => m.residue().to_i64(), } } #[inline] fn to_u64(&self) -> Option { match &self.0 { Left(v) => v.to_u64(), Right(m) => m.residue().to_u64(), } } } impl, R: Reducer> Pow for Mint { type Output = Self; #[inline] fn pow(self, rhs: u32) -> Self::Output { match self.0 { Left(v) => Self(Left(v.pow(rhs))), Right(_) => unreachable!(), } } } impl + Clone> ExactRoots for Mint { #[inline] fn nth_root_exact(&self, n: u32) -> Option { match &self.0 { Left(v) => v.nth_root_exact(n).map(|v| Self(Left(v))), Right(_) => unreachable!(), } } } impl> BitTest for Mint { #[inline] fn bit(&self, position: usize) -> bool { match &self.0 { Left(v) => v.bit(position), Right(_) => unreachable!(), } } #[inline] fn bits(&self) -> usize { match &self.0 { Left(v) => v.bits(), Right(_) => unreachable!(), } } #[inline] fn trailing_zeros(&self) -> usize { match &self.0 { Left(v) => v.trailing_zeros(), Right(_) => unreachable!(), } } } impl, R: Reducer> Shr for Mint { type Output = Self; #[inline] fn shr(self, rhs: usize) -> Self::Output { match self.0 { Left(v) => Self(Left(v >> rhs)), Right(_) => unreachable!(), } } } impl, R: Reducer> Shr for &Mint { type Output = Mint; #[inline] fn shr(self, rhs: usize) -> Self::Output { match &self.0 { Left(v) => Mint(Left(v.clone() >> rhs)), Right(_) => unreachable!(), } } } impl + Clone> ModularCoreOps<&Self, &Self> for Mint { type Output = Self; #[inline] fn addm(self, rhs: &Self, m: &Self) -> Self::Output { match (self.0, &rhs.0, &m.0) { (Right(v1), Right(v2), Left(m)) => { debug_assert!(&v1.modulus() == m && &v2.modulus() == m); Self(Right(v1 + v2)) } (_, _, _) => unreachable!(), } } #[inline] fn subm(self, rhs: &Self, m: &Self) -> Self::Output { match (self.0, &rhs.0, &m.0) { (Right(v1), Right(v2), Left(m)) => { debug_assert!(&v1.modulus() == m && &v2.modulus() == m); Self(Right(v1 - v2)) } (_, _, _) => unreachable!(), } } #[inline] fn mulm(self, rhs: &Self, m: &Self) -> Self::Output { match (self.0, &rhs.0, &m.0) { (Right(v1), Right(v2), Left(m)) => { debug_assert!(&v1.modulus() == m && &v2.modulus() == m); Self(Right(v1 * v2)) } (_, _, _) => unreachable!(), } } } impl<'a, 'b, T: Integer + Clone, R: Reducer + Clone> ModularCoreOps<&'b Mint, &'b Mint> for &'a Mint { type Output = Mint; #[inline] fn addm(self, rhs: &Mint, m: &Mint) -> Self::Output { match (&self.0, &rhs.0, &m.0) { (Right(v1), Right(v2), Left(m)) => { debug_assert!(&v1.modulus() == m && &v2.modulus() == m); Mint(Right(v1 + v2)) } (_, _, _) => unreachable!(), } } #[inline] fn subm(self, rhs: &Mint, m: &Mint) -> Self::Output { match (&self.0, &rhs.0, &m.0) { (Right(v1), Right(v2), Left(m)) => { debug_assert!(&v1.modulus() == m && &v2.modulus() == m); Mint(Right(v1 - v2)) } (_, _, _) => unreachable!(), } } #[inline] fn mulm(self, rhs: &Mint, m: &Mint) -> Self::Output { match (&self.0, &rhs.0, &m.0) { (Right(v1), Right(v2), Left(m)) => { debug_assert!(&v1.modulus() == m && &v2.modulus() == m); Mint(Right(v1 * v2)) } (_, _, _) => unreachable!(), } } } impl + Clone> ModularUnaryOps<&Self> for Mint { type Output = Self; #[inline] fn negm(self, m: &Self) -> Self::Output { Self(Right(match (self.0, &m.0) { (Left(v), Left(m)) => ReducedInt::new(v, m).neg(), (Right(v), Left(m)) => { debug_assert!(&v.modulus() == m); v.neg() } (_, Right(_)) => unreachable!(), })) } fn invm(self, _: &Self) -> Option { unreachable!() // not used in this crate } #[inline] fn dblm(self, m: &Self) -> Self::Output { Self(Right(match (self.0, &m.0) { (Left(v), Left(m)) => ReducedInt::new(v, m).double(), (Right(v), Left(m)) => { debug_assert!(&v.modulus() == m); v.double() } (_, Right(_)) => unreachable!(), })) } #[inline] fn sqm(self, m: &Self) -> Self::Output { Self(Right(match (self.0, &m.0) { (Left(v), Left(m)) => ReducedInt::new(v, m).square(), (Right(v), Left(m)) => { debug_assert!(&v.modulus() == m); v.square() } (_, Right(_)) => unreachable!(), })) } } impl<'a, 'b, T: Integer + Clone, R: Reducer + Clone> ModularUnaryOps<&'b Mint> for &'a Mint { type Output = Mint; #[inline] fn negm(self, m: &Mint) -> Self::Output { Mint(Right(match (&self.0, &m.0) { (Left(v), Left(m)) => ReducedInt::new(v.clone(), m).neg(), (Right(v), Left(m)) => { debug_assert!(&v.modulus() == m); v.clone().neg() } (_, Right(_)) => unreachable!(), })) } fn invm(self, _: &Mint) -> Option { unreachable!() // not used in this crate } #[inline] fn dblm(self, m: &Mint) -> Self::Output { Mint(Right(match (&self.0, &m.0) { (Left(v), Left(m)) => ReducedInt::new(v.clone(), m).double(), (Right(v), Left(m)) => { debug_assert!(&v.modulus() == m); v.clone().double() } (_, Right(_)) => unreachable!(), })) } #[inline] fn sqm(self, m: &Mint) -> Self::Output { Mint(Right(match (&self.0, &m.0) { (Left(v), Left(m)) => ReducedInt::new(v.clone(), m).square(), (Right(v), Left(m)) => { debug_assert!(&v.modulus() == m); v.clone().square() } (_, Right(_)) => unreachable!(), })) } } impl ModularSymbols<&'r T>, R: Reducer + Clone> ModularSymbols<&Self> for Mint { #[inline] fn checked_jacobi(&self, n: &Self) -> Option { match (&self.0, &n.0) { (Left(a), Left(n)) => a.checked_jacobi(n), (Right(a), Left(n)) => a.residue().checked_jacobi(n), (_, Right(_)) => unreachable!(), } } #[inline] fn checked_legendre(&self, n: &Self) -> Option { match (&self.0, &n.0) { (Left(a), Left(n)) => a.checked_legendre(n), (Right(a), Left(n)) => a.residue().checked_legendre(n), (_, Right(_)) => unreachable!(), } } #[inline] fn kronecker(&self, n: &Self) -> i8 { match (&self.0, &n.0) { (Left(a), Left(n)) => a.kronecker(n), (Right(a), Left(n)) => a.residue().kronecker(n), (_, Right(_)) => unreachable!(), } } } impl + Clone> ModularPow<&Self, &Self> for Mint { type Output = Self; #[inline] fn powm(self, exp: &Self, m: &Self) -> Self::Output { Self(Right(match (self.0, &exp.0, &m.0) { (Left(v), Left(e), Left(m)) => ReducedInt::new(v, m).pow(e.clone()), (Right(v), Left(e), Left(m)) => { debug_assert!(&v.modulus() == m); v.pow(e.clone()) } (_, _, _) => unreachable!(), })) } } pub type SmallMint = Mint>; #[cfg(test)] mod tests { use super::*; #[test] fn test_basics() { let a: SmallMint = 19.into(); let b: SmallMint = 8.into(); assert_eq!(a + b, 27.into()); } } num-prime-0.4.4/src/nt_funcs.rs000064400000000000000000001365430072674642500145620ustar 00000000000000//! Standalone number theoretic functions //! //! The functions in this module can be called without an instance of [crate::traits::PrimeBuffer]. //! However, some functions do internally call the implementation on [PrimeBufferExt] //! (especially those dependent of integer factorization). For these functions, if you have //! to call them repeatedly, it's recommended to create a [crate::traits::PrimeBuffer] //! instance and use its associated methods for better performance. //! //! For number theoretic functions that depends on integer factorization, strongest primality //! check will be used in factorization, since for these functions we prefer correctness //! over speed. //! use crate::buffer::{NaiveBuffer, PrimeBufferExt}; use crate::factor::{one_line, pollard_rho, squfof, SQUFOF_MULTIPLIERS}; use crate::mint::SmallMint; use crate::primality::{PrimalityBase, PrimalityRefBase}; use crate::tables::{ MOEBIUS_ODD, SMALL_PRIMES, SMALL_PRIMES_NEXT, WHEEL_NEXT, WHEEL_PREV, WHEEL_SIZE, }; #[cfg(feature = "big-table")] use crate::tables::{SMALL_PRIMES_INV, ZETA_LOG_TABLE}; use crate::traits::{FactorizationConfig, Primality, PrimalityTestConfig, PrimalityUtils}; use crate::{BitTest, ExactRoots}; use num_integer::Roots; #[cfg(feature = "num-bigint")] use num_modular::DivExact; use num_modular::{ModularCoreOps, ModularInteger, MontgomeryInt}; use num_traits::{CheckedAdd, FromPrimitive, Num, RefNum, ToPrimitive}; use rand::random; use std::collections::BTreeMap; use std::convert::TryFrom; #[cfg(feature = "big-table")] use crate::tables::{MILLER_RABIN_BASE64, MILLER_RABIN_BASE32}; /// Fast primality test on a u64 integer. It's based on /// deterministic Miller-rabin tests. If target is larger than 2^64 or more /// controlled primality tests are desired, please use [is_prime()] #[cfg(not(feature = "big-table"))] pub fn is_prime64(target: u64) -> bool { // shortcuts if target < 2 { return false; } if target & 1 == 0 { return target == 2; } if let Ok(u) = u8::try_from(target) { // find in the prime list if the target is small enough return SMALL_PRIMES.binary_search(&u).is_ok(); } else { // check remainder against the wheel table // this step eliminates any number that is not coprime to WHEEL_SIZE let pos = (target % WHEEL_SIZE as u64) as usize; if pos == 0 || WHEEL_NEXT[pos] < WHEEL_NEXT[pos - 1] { return false; } } // Then do a deterministic Miller-rabin test is_prime64_miller(target) } /// Very fast primality test on a u64 integer is a prime number. It's based on /// deterministic Miller-rabin tests with hashing. if target is larger than 2^64 or more controlled /// primality tests are desired, please use [is_prime()] #[cfg(feature = "big-table")] pub fn is_prime64(target: u64) -> bool { // shortcuts if target < 2 { return false; } if target & 1 == 0 { return target == 2; } // remove small factors if target < SMALL_PRIMES_NEXT { // find in the prime list if the target is small enough return SMALL_PRIMES.binary_search(&(target as u16)).is_ok(); } else { // check remainder against the wheel table // this step eliminates any number that is not coprime to WHEEL_SIZE let pos = (target % WHEEL_SIZE as u64) as usize; if pos == 0 || WHEEL_NEXT[pos] < WHEEL_NEXT[pos - 1] { return false; } } // Then do a deterministic Miller-rabin test is_prime64_miller(target) } // Primality test for u64 with only miller-rabin tests, used during factorization. // It assumes the target is odd, not too small and cannot be divided small primes #[cfg(not(feature = "big-table"))] fn is_prime64_miller(target: u64) -> bool { // The collection of witnesses are from http://miller-rabin.appspot.com/ if let Ok(u) = u32::try_from(target) { const WITNESS32: [u32; 3] = [2, 7, 61]; let u = SmallMint::from(u); WITNESS32.iter().all(|&x| u.is_sprp(SmallMint::from(x))) } else { const WITNESS64: [u64; 7] = [2, 325, 9375, 28178, 450775, 9780504, 1795265022]; let u = SmallMint::from(target); WITNESS64.iter().all(|&x| u.is_sprp(SmallMint::from(x))) } } #[cfg(feature = "big-table")] fn is_prime32_miller(target: u32) -> bool { let h = target as u64; let h = ((h >> 16) ^ h).wrapping_mul(0x45d9f3b); let h = ((h >> 16) ^ h).wrapping_mul(0x45d9f3b); let h = ((h >> 16) ^ h) & 255; let u = SmallMint::from(target); return u.is_sprp(SmallMint::from(MILLER_RABIN_BASE32[h as usize] as u32)); } // Primality test for u64 with only miller-rabin tests, used during factorization. // It assumes the target is odd, not too small and cannot be divided small primes #[cfg(feature = "big-table")] fn is_prime64_miller(target: u64) -> bool { if let Ok(u) = u32::try_from(target) { return is_prime32_miller(u); } let u = SmallMint::from(target); if !u.is_sprp(2.into()) { return false; } let h = target; let h = ((h >> 32) ^ h).wrapping_mul(0x45d9f3b3335b369); let h = ((h >> 32) ^ h).wrapping_mul(0x3335b36945d9f3b); let h = ((h >> 32) ^ h) & 16383; let b = MILLER_RABIN_BASE64[h as usize]; return u.is_sprp((b as u64 & 4095).into()) && u.is_sprp((b as u64 >> 12).into()); } /// Fast integer factorization on a u64 target. It's based on a selection of factorization methods. /// if target is larger than 2^128 or more controlled primality tests are desired, please use [factors()][crate::buffer::PrimeBufferExt::factors]. /// /// The factorization can be quite faster under 2^64 because: 1) faster and deterministic primality check, /// 2) efficient montgomery multiplication implementation of u64 pub fn factorize64(target: u64) -> BTreeMap { // TODO: improve factorization performance // REF: http://flintlib.org/doc/ulong_extras.html#factorisation // https://mathoverflow.net/questions/114018/fastest-way-to-factor-integers-260 // https://hal.inria.fr/inria-00188645v3/document // https://github.com/coreutils/coreutils/blob/master/src/factor.c // https://github.com/uutils/coreutils/blob/master/src/uu/factor/src/cli.rs // https://github.com/elmomoilanen/prime-factorization // https://github.com/radii/msieve // https://github.com/zademn/facto-rs // Pari/GP: ifac_crack let mut result = BTreeMap::new(); // quick check on factors of 2 let f2 = target.trailing_zeros(); if f2 == 0 { if is_prime64(target) { result.insert(target, 1); return result; } } else { result.insert(2, f2 as usize); } // trial division using primes in the table let tsqrt = target.sqrt() + 1; let mut residual = target >> f2; let mut factored = false; #[cfg(not(feature = "big-table"))] for p in SMALL_PRIMES.iter().skip(1).map(|&v| v as u64) { if p > tsqrt { factored = true; break; } while residual % p == 0 { residual = residual / p; *result.entry(p).or_insert(0) += 1; } if residual == 1 { factored = true; break; } } #[cfg(feature = "big-table")] // divisibility check with pre-computed tables, see comments on SMALL_PRIMES_INV for reference for (p, &pinv) in SMALL_PRIMES .iter() .map(|&p| p as u64) .zip(SMALL_PRIMES_INV.iter()) .skip(1) { // only need to test primes up to sqrt(target) if p > tsqrt { factored = true; break; } let mut exp: usize = 0; while let Some(q) = residual.div_exact(p, &pinv) { exp += 1; residual = q; } if exp > 0 { result.insert(p, exp); } if residual == 1 { factored = true; break; } } if factored { if residual != 1 { result.insert(residual, 1); } return result; } // then try advanced methods to find a divisor util fully factored for (p, exp) in factorize64_advanced(&[(residual, 1usize)]).into_iter() { *result.entry(p).or_insert(0) += exp; } result } // This function factorize all cofactors after some trivial division steps pub(crate) fn factorize64_advanced(cofactors: &[(u64, usize)]) -> Vec<(u64, usize)> { let mut todo: Vec<_> = cofactors.iter().cloned().collect(); let mut factored: Vec<(u64, usize)> = Vec::new(); // prime factor, exponent while let Some((target, exp)) = todo.pop() { if is_prime64_miller(target) { factored.push((target, exp)); continue; } // check perfect powers before other methods, this is required for SQUFOF // it suffices to check square and cubic if big-table is enabled, since fifth power of // the smallest prime that haven't been checked is 8167^5 > 2^64 if let Some(d) = target.sqrt_exact() { todo.push((d, exp * 2)); continue; } if let Some(d) = target.cbrt_exact() { todo.push((d, exp * 3)); continue; } // try to find a divisor let mut i = 0usize; let mut max_iter_ratio = 1; // increase max_iter after factorization round let divisor = loop { // try various factorization method iteratively const NMETHODS: usize = 3; match i % NMETHODS { 0 => { // Pollard's rho (quick check) let start = MontgomeryInt::new(random::(), &target); let offset = start.convert(random::()); let max_iter = max_iter_ratio << (target.bits() / 6); // unoptimized heuristic if let (Some(p), _) = pollard_rho( &SmallMint::from(target), start.into(), offset.into(), max_iter, ) { break p.value(); } } 1 => { // Hart's one-line (quick check) let mul_target = target.checked_mul(480).unwrap_or(target); let max_iter = max_iter_ratio << (mul_target.bits() / 6); // unoptimized heuristic if let (Some(p), _) = one_line(&target, mul_target, max_iter) { break p; } } 2 => { // Shanks's squfof (main power) let mut d = None; for &k in SQUFOF_MULTIPLIERS.iter() { if let Some(mul_target) = target.checked_mul(k as u64) { let max_iter = max_iter_ratio * 2 * mul_target.sqrt().sqrt() as usize; if let (Some(p), _) = squfof(&target, mul_target, max_iter) { d = Some(p); break; } } } if let Some(p) = d { break p; } } _ => unreachable!(), } i += 1; // increase max iterations after trying all methods if i % NMETHODS == 0 { max_iter_ratio *= 2; } }; todo.push((divisor, exp)); todo.push((target / divisor, exp)); } factored } /// Fast integer factorization on a u128 target. It's based on a selection of factorization methods. /// if target is larger than 2^128 or more controlled primality tests are desired, please use [factors()][crate::buffer::PrimeBufferExt::factors]. pub fn factorize128(target: u128) -> BTreeMap { // shortcut for u64 if target < (1u128 << 64) { return factorize64(target as u64) .into_iter() .map(|(k, v)| (k as u128, v)) .collect(); } let mut result = BTreeMap::new(); // quick check on factors of 2 let f2 = target.trailing_zeros(); if f2 != 0 { result.insert(2, f2 as usize); } let mut residual = target >> f2; // trial division using primes in the table // note that p^2 is never larger than target (at least 64 bits), so we don't need to shortcut trial division #[cfg(not(feature = "big-table"))] for p in SMALL_PRIMES.iter().skip(1).map(|&v| v as u128) { while residual % p == 0 { residual = residual / p; *result.entry(p).or_insert(0) += 1; } if residual == 1 { return result; } } #[cfg(feature = "big-table")] // divisibility check with pre-computed tables, see comments on SMALL_PRIMES_INV for reference for (p, &pinv) in SMALL_PRIMES .iter() .map(|&p| p as u64) .zip(SMALL_PRIMES_INV.iter()) .skip(1) { let mut exp: usize = 0; while let Some(q) = residual.div_exact(p, &pinv) { exp += 1; residual = q; } if exp > 0 { result.insert(p as u128, exp); } if residual == 1 { return result; } } // then try advanced methods to find a divisor util fully factored for (p, exp) in factorize128_advanced(&[(residual, 1usize)]).into_iter() { *result.entry(p).or_insert(0) += exp; } result } pub(crate) fn factorize128_advanced(cofactors: &[(u128, usize)]) -> Vec<(u128, usize)> { let (mut todo128, mut todo64) = (Vec::new(), Vec::new()); // cofactors to be processed let mut factored: Vec<(u128, usize)> = Vec::new(); // prime factor, exponent for &(co, e) in cofactors.iter() { if let Ok(co64) = u64::try_from(co) { todo64.push((co64, e)); } else { todo128.push((co, e)); }; } while let Some((target, exp)) = todo128.pop() { if is_prime(&SmallMint::from(target), Some(PrimalityTestConfig::bpsw())).probably() { factored.push((target, exp)); continue; } // check perfect powers before other methods // it suffices to check 2, 3, 5, 7 power if big-table is enabled, since tenth power of // the smallest prime that haven't been checked is 8167^10 > 2^128 if let Some(d) = target.sqrt_exact() { if let Ok(d64) = u64::try_from(d) { todo64.push((d64, exp * 2)); } else { todo128.push((d, exp * 2)); } continue; } if let Some(d) = target.cbrt_exact() { if let Ok(d64) = u64::try_from(d) { todo64.push((d64, exp * 3)); } else { todo128.push((d, exp * 3)); } continue; } // TODO: check 5-th, 7-th power // try to find a divisor let mut i = 0usize; let mut max_iter_ratio = 1; let divisor = loop { // try various factorization method iteratively, sort by time per iteration const NMETHODS: usize = 3; match i % NMETHODS { 0 => { // Pollard's rho let start = MontgomeryInt::new(random::(), &target); let offset = start.convert(random::()); let max_iter = max_iter_ratio << (target.bits() / 6); // unoptimized heuristic if let (Some(p), _) = pollard_rho( &SmallMint::from(target), start.into(), offset.into(), max_iter, ) { break p.value(); } } 1 => { // Hart's one-line let mul_target = target.checked_mul(480).unwrap_or(target); let max_iter = max_iter_ratio << (mul_target.bits() / 6); // unoptimized heuristic if let (Some(p), _) = one_line(&target, mul_target, max_iter) { break p; } } 2 => { // Shanks's squfof, try all mutipliers let mut d = None; for &k in SQUFOF_MULTIPLIERS.iter() { if let Some(mul_target) = target.checked_mul(k as u128) { let max_iter = max_iter_ratio * 2 * mul_target.sqrt().sqrt() as usize; if let (Some(p), _) = squfof(&target, mul_target, max_iter) { d = Some(p); break; } } } if let Some(p) = d { break p; } } _ => unreachable!(), } i += 1; // increase max iterations after trying all methods if i % NMETHODS == 0 { max_iter_ratio *= 2; } }; if let Ok(d64) = u64::try_from(divisor) { todo64.push((d64, exp)); } else { todo128.push((divisor, exp)); } let co = target / divisor; if let Ok(d64) = u64::try_from(co) { todo64.push((d64, exp)); } else { todo128.push((co, exp)); } } // forward 64 bit cofactors factored.extend( factorize64_advanced(&todo64) .into_iter() .map(|(p, exp)| (p as u128, exp)), ); factored } /// Primality test /// /// This function re-exports [PrimeBufferExt::is_prime()][crate::buffer::PrimeBufferExt::is_prime()] with a new [NaiveBuffer] distance pub fn is_prime(target: &T, config: Option) -> Primality where for<'r> &'r T: PrimalityRefBase, { NaiveBuffer::new().is_prime(target, config) } /// Faillible factorization /// /// This function re-exports [PrimeBufferExt::factors()][crate::buffer::PrimeBufferExt::factors()] with a new [NaiveBuffer] instance pub fn factors( target: T, config: Option, ) -> (BTreeMap, Option>) where for<'r> &'r T: PrimalityRefBase, { NaiveBuffer::new().factors(target, config) } /// Infaillible factorization /// /// This function re-exports [PrimeBufferExt::factorize()][crate::buffer::PrimeBufferExt::factorize()] with a new [NaiveBuffer] instance pub fn factorize(target: T) -> BTreeMap where for<'r> &'r T: PrimalityRefBase, { NaiveBuffer::new().factorize(target) } /// Get a list of primes under a limit /// /// This function re-exports [NaiveBuffer::primes()] and collect result as a vector. pub fn primes(limit: u64) -> Vec { NaiveBuffer::new().into_primes(limit).collect() } /// Get the first n primes /// /// This function re-exports [NaiveBuffer::nprimes()] and collect result as a vector. pub fn nprimes(count: usize) -> Vec { NaiveBuffer::new().into_nprimes(count).collect() } /// Calculate and return the prime π function /// /// This function re-exports [NaiveBuffer::prime_pi()] pub fn prime_pi(limit: u64) -> u64 { NaiveBuffer::new().prime_pi(limit) } /// Get the n-th prime (n counts from 1). /// /// This function re-exports [NaiveBuffer::nth_prime()] pub fn nth_prime(n: u64) -> u64 { NaiveBuffer::new().nth_prime(n) } /// Calculate the primorial function pub fn primorial(n: usize) -> T { NaiveBuffer::new() .into_nprimes(n) .map(|p| T::from_u64(p).unwrap()) .product() } /// This function calculate the Möbius `μ(n)` function of the input integer `n` /// /// This function behaves like `moebius_factorized(factorize(target))`. /// If the input integer is very hard to factorize, it's better to use /// the [factors()] function to control how the factorization is done, and then call /// [moebius_factorized()]. /// /// # Panics /// if the factorization failed on target. pub fn moebius(target: &T) -> i8 where for<'r> &'r T: PrimalityRefBase, { // remove factor 2 if target.is_even() { let two = T::one() + T::one(); let four = &two + &two; if (target % four).is_zero() { return 0; } else { return -moebius(&(target / &two)); } } // look up tables when input is smaller than 256 if let Some(v) = (target - T::one()).to_u8() { let m = MOEBIUS_ODD[(v >> 6) as usize]; let m = m & (3 << (v & 63)); let m = m >> (v & 63); return m as i8 - 1; } // short cut for common primes let three_sq = T::from_u8(9).unwrap(); let five_sq = T::from_u8(25).unwrap(); let seven_sq = T::from_u8(49).unwrap(); if (target % three_sq).is_zero() || (target % five_sq).is_zero() || (target % seven_sq).is_zero() { return 0; } // then try complete factorization moebius_factorized(&factorize(target.clone())) } /// This function calculate the Möbius `μ(n)` function given the factorization /// result of `n` pub fn moebius_factorized(factors: &BTreeMap) -> i8 { if factors.values().any(|exp| exp > &1) { 0 } else if factors.len() % 2 == 0 { 1 } else { -1 } } /// Tests if the integer doesn't have any square number factor. /// /// # Panics /// if the factorization failed on target. pub fn is_square_free(target: &T) -> bool where for<'r> &'r T: PrimalityRefBase, { moebius(target) != 0 } /// Returns the estimated bounds (low, high) of prime π function, such that /// low <= π(target) <= high /// /// # Reference: /// - \[1] Dusart, Pierre. "Estimates of Some Functions Over Primes without R.H." /// [arxiv:1002.0442](http://arxiv.org/abs/1002.0442). 2010. /// - \[2] Dusart, Pierre. "Explicit estimates of some functions over primes." /// The Ramanujan Journal 45.1 (2018): 227-251. pub fn prime_pi_bounds(target: &T) -> (T, T) { if let Some(x) = target.to_u64() { // use existing primes and return exact value if x <= (*SMALL_PRIMES.last().unwrap()) as u64 { #[cfg(not(feature = "big-table"))] let pos = SMALL_PRIMES.binary_search(&(x as u8)); #[cfg(feature = "big-table")] let pos = SMALL_PRIMES.binary_search(&(x as u16)); let n = match pos { Ok(p) => p + 1, Err(p) => p, }; return (T::from_usize(n).unwrap(), T::from_usize(n).unwrap()); } // use function approximation let n = x as f64; let ln = n.ln(); let invln = ln.recip(); let lo = match () { // [2] Collary 5.3 _ if x >= 468049 => n / (ln - 1. - invln), // [2] Collary 5.2 _ if x >= 88789 => n * invln * (1. + invln * (1. + 2. * invln)), // [2] Collary 5.3 _ if x >= 5393 => n / (ln - 1.), // [2] Collary 5.2 _ if x >= 599 => n * invln * (1. + invln), // [2] Collary 5.2 _ => n * invln, }; let hi = match () { // [2] Theorem 5.1, valid for x > 4e9, intersects at 7.3986e9 _ if x >= 7398600000 => n * invln * (1. + invln * (1. + invln * (2. + invln * 7.59))), // [1] Theorem 6.9 _ if x >= 2953652287 => n * invln * (1. + invln * (1. + invln * 2.334)), // [2] Collary 5.3, valid for x > 5.6, intersects at 5668 _ if x >= 467345 => n / (ln - 1. - 1.2311 * invln), // [2] Collary 5.2, valid for x > 1, intersects at 29927 _ if x >= 29927 => n * invln * (1. + invln * (1. + invln * 2.53816)), // [2] Collary 5.3, valid for x > exp(1.112), intersects at 5668 _ if x >= 5668 => n / (ln - 1.112), // [2] Collary 5.2, valid for x > 1, intersects at 148 _ if x >= 148 => n * invln * (1. + invln * 1.2762), // [2] Collary 5.2, valid for x > 1 _ => 1.25506 * n * invln, }; (T::from_f64(lo).unwrap(), T::from_f64(hi).unwrap()) } else { let n = target.to_f64().unwrap(); let ln = n.ln(); let invln = ln.recip(); // best bounds so far let lo = n / (ln - 1. - invln); let hi = n * invln * (1. + invln * (1. + invln * (2. + invln * 7.59))); (T::from_f64(lo).unwrap(), T::from_f64(hi).unwrap()) } } /// Returns the estimated inclusive bounds (low, high) of the n-th prime. If the result /// is larger than maximum of `T`, [None] will be returned. /// /// # Reference: /// - \[1] Dusart, Pierre. "Estimates of Some Functions Over Primes without R.H." /// arXiv preprint [arXiv:1002.0442](https://arxiv.org/abs/1002.0442) (2010). /// - \[2] Rosser, J. Barkley, and Lowell Schoenfeld. "Approximate formulas for some /// functions of prime numbers." Illinois Journal of Mathematics 6.1 (1962): 64-94. /// - \[3] Dusart, Pierre. "The k th prime is greater than k (ln k+ ln ln k-1) for k≥ 2." /// Mathematics of computation (1999): 411-415. /// - \[4] Axler, Christian. ["New Estimates for the nth Prime Number."](https://www.emis.de/journals/JIS/VOL22/Axler/axler17.pdf) /// Journal of Integer Sequences 22.2 (2019): 3. /// - \[5] Axler, Christian. [Uber die Primzahl-Zählfunktion, die n-te Primzahl und verallgemeinerte Ramanujan-Primzahlen. Diss.](http://docserv.uniduesseldorf.de/servlets/DerivateServlet/Derivate-28284/pdfa-1b.pdf) /// PhD thesis, Düsseldorf, 2013. /// /// Note that some of the results might depend on the Riemann Hypothesis. If you find /// any prime that doesn't fall in the bound, then it might be a big discovery! pub fn nth_prime_bounds(target: &T) -> Option<(T, T)> { if let Some(x) = target.to_usize() { if x == 0 { return Some((T::from_u8(0).unwrap(), T::from_u8(0).unwrap())); } // use existing primes and return exact value if x <= SMALL_PRIMES.len() { let p = SMALL_PRIMES[x - 1]; #[cfg(not(feature = "big-table"))] return Some((T::from_u8(p).unwrap(), T::from_u8(p).unwrap())); #[cfg(feature = "big-table")] return Some((T::from_u16(p).unwrap(), T::from_u16(p).unwrap())); } // use function approximation let n = x as f64; let ln = n.ln(); let lnln = ln.ln(); let lo = match () { // [4] Theroem 4, valid for x >= 2, intersects as 3.172e5 _ if x >= 317200 => { n * (ln + lnln - 1. + (lnln - 2.) / ln - (lnln * lnln - 6. * lnln + 11.321) / (2. * ln * ln)) } // [1] Proposition 6.7, valid for x >= 3, intersects at 3520 _ if x >= 3520 => n * (ln + lnln - 1. + (lnln - 2.1) / ln), // [3] title _ => n * (ln + lnln - 1.), }; let hi = match () { // [4] Theroem 1, valid for x >= 46254381 _ if x >= 46254381 => { n * (ln + lnln - 1. + (lnln - 2.) / ln - (lnln * lnln - 6. * lnln + 10.667) / (2. * ln * ln)) } // [5] Korollar 2.11, valid for x >= 8009824 _ if x >= 8009824 => { n * (ln + lnln - 1. + (lnln - 2.) / ln - (lnln * lnln - 6. * lnln + 10.273) / (2. * ln * ln)) } // [1] Proposition 6.6 _ if x >= 688383 => n * (ln + lnln - 1. + (lnln - 2.) / ln), // [1] Lemma 6.5 _ if x >= 178974 => n * (ln + lnln - 1. + (lnln - 1.95) / ln), // [3] in "Further Results" _ if x >= 39017 => n * (ln + lnln - 0.9484), // [3] in "Further Results" _ if x >= 27076 => n * (ln + lnln - 1. + (lnln - 1.8) / ln), // [2] Theorem 3, valid for x >= 20 _ => n * (ln + lnln - 0.5), }; Some((T::from_f64(lo)?, T::from_f64(hi)?)) } else { let n = target.to_f64().unwrap(); let ln = n.ln(); let lnln = ln.ln(); // best bounds so far let lo = n * (ln + lnln - 1. + (lnln - 2.) / ln - (lnln * lnln - 6. * lnln + 11.321) / (2. * ln * ln)); let hi = n * (ln + lnln - 1. + (lnln - 2.) / ln - (lnln * lnln - 6. * lnln + 10.667) / (2. * ln * ln)); Some((T::from_f64(lo)?, T::from_f64(hi)?)) } } /// Test if the target is a safe prime under [Sophie German's definition](https://en.wikipedia.org/wiki/Safe_and_Sophie_Germain_primes). It will use the /// [strict primality test configuration][FactorizationConfig::strict()]. pub fn is_safe_prime(target: &T) -> Primality where for<'r> &'r T: PrimalityRefBase, { let buf = NaiveBuffer::new(); let config = Some(PrimalityTestConfig::strict()); // test (n-1)/2 first since its smaller let sophie_p = buf.is_prime(&(target >> 1), config); if matches!(sophie_p, Primality::No) { return sophie_p; } // and then test target itself let target_p = buf.is_prime(target, config); target_p & sophie_p } /// Find the first prime number larger than `target`. If the result causes an overflow, /// then [None] will be returned #[cfg(not(feature = "big-table"))] pub fn next_prime( target: &T, config: Option, ) -> Option where for<'r> &'r T: PrimalityRefBase, { // first search in small primes if let Some(x) = target.to_u8() { return match SMALL_PRIMES.binary_search(&x) { Ok(pos) => { if pos + 1 == SMALL_PRIMES.len() { T::from_u64(SMALL_PRIMES_NEXT) } else { T::from_u8(SMALL_PRIMES[pos + 1]) } } Err(pos) => T::from_u8(SMALL_PRIMES[pos]), }; } // then moving along the wheel let mut i = (target % T::from_u8(WHEEL_SIZE).unwrap()).to_u8().unwrap(); let mut t = target.clone(); loop { let offset = WHEEL_NEXT[i as usize]; t = t.checked_add(&T::from_u8(offset).unwrap())?; i = i.addm(offset, &WHEEL_SIZE); if is_prime(&t, config).probably() { break Some(t); } } } /// Find the first prime number larger than `target`. If the result causes an overflow, /// then [None] will be returned #[cfg(feature = "big-table")] pub fn next_prime( target: &T, config: Option, ) -> Option where for<'r> &'r T: PrimalityRefBase, { // first search in small primes if target <= &T::from_u8(255).unwrap() // shortcut for T=u8 || target < &T::from_u16(*SMALL_PRIMES.last().unwrap()).unwrap() { let next = match SMALL_PRIMES.binary_search(&target.to_u16().unwrap()) { Ok(pos) => SMALL_PRIMES[pos + 1], Err(pos) => SMALL_PRIMES[pos], }; return T::from_u16(next); } // then moving along the wheel let mut i = (target % T::from_u16(WHEEL_SIZE).unwrap()) .to_u16() .unwrap(); let mut t = target.clone(); loop { let offset = WHEEL_NEXT[i as usize]; t = t.checked_add(&T::from_u8(offset).unwrap())?; i = i.addm(offset as u16, &WHEEL_SIZE); if is_prime(&t, config).probably() { break Some(t); } } } /// Find the first prime number smaller than `target`. If target is less than 3, then [None] /// will be returned. #[cfg(not(feature = "big-table"))] pub fn prev_prime(target: &T, config: Option) -> Option where for<'r> &'r T: PrimalityRefBase, { if target <= &(T::one() + T::one()) { return None; } // first search in small primes if let Some(x) = target.to_u8() { let next = match SMALL_PRIMES.binary_search(&x) { Ok(pos) => SMALL_PRIMES[pos - 1], Err(pos) => SMALL_PRIMES[pos - 1], }; return Some(T::from_u8(next).unwrap()); } // then moving along the wheel let mut i = (target % T::from_u8(WHEEL_SIZE).unwrap()).to_u8().unwrap(); let mut t = target.clone(); loop { let offset = WHEEL_PREV[i as usize]; t = t - T::from_u8(offset).unwrap(); i = i.subm(offset, &WHEEL_SIZE); if is_prime(&t, config).probably() { break Some(t); } } } /// Find the first prime number smaller than `target`. If target is less than 3, then [None] /// will be returned. #[cfg(feature = "big-table")] pub fn prev_prime(target: &T, config: Option) -> Option where for<'r> &'r T: PrimalityRefBase, { if target <= &(T::one() + T::one()) { return None; } // first search in small primes if target <= &T::from_u8(255).unwrap() // shortcut for u8 || target < &T::from_u16(*SMALL_PRIMES.last().unwrap()).unwrap() { let next = match SMALL_PRIMES.binary_search(&target.to_u16().unwrap()) { Ok(pos) => SMALL_PRIMES[pos - 1], Err(pos) => SMALL_PRIMES[pos - 1], }; return Some(T::from_u16(next).unwrap()); } // then moving along the wheel let mut i = (target % T::from_u16(WHEEL_SIZE).unwrap()) .to_u16() .unwrap(); let mut t = target.clone(); loop { let offset = WHEEL_PREV[i as usize]; t = t - T::from_u8(offset).unwrap(); i = i.subm(offset as u16, &WHEEL_SIZE); if is_prime(&t, config).probably() { break Some(t); } } } /// Estimate the value of prime π() function by averaging the estimated bounds. #[cfg(not(feature = "big-table"))] pub fn prime_pi_est(target: &T) -> T { let (lo, hi) = prime_pi_bounds(target); (lo + hi) / T::from_u8(2).unwrap() } /// Estimate the value of prime π() function by Riemann's R function. The estimation /// error is roughly of scale O(sqrt(x)log(x)). /// /// Reference: #[cfg(feature = "big-table")] pub fn prime_pi_est(target: &T) -> T { // shortcut if let Some(x) = target.to_u16() { if x <= (*SMALL_PRIMES.last().unwrap()) as u16 { let (lo, hi) = prime_pi_bounds(&x); debug_assert_eq!(lo, hi); return T::from_u16(lo).unwrap(); } } // Gram expansion with logarithm arithmetics let lnln = target.to_f64().unwrap().ln().ln(); let mut total = 0f64; let mut lnp = 0f64; // k*ln(ln(x)) let mut lnfac = 0f64; // ln(k!) for k in 1usize..100 { lnp += lnln; let lnk = (k as f64).ln(); lnfac += lnk; let lnzeta = if k > 64 { 0f64 } else { ZETA_LOG_TABLE[k - 1] }; let t = lnp - lnk - lnfac - lnzeta; if t < -4. { // stop if the increment is too small break; } total += t.exp(); } T::from_f64(total + 1f64).unwrap() } /// Estimate the value of nth prime by bisecting on [prime_pi_est]. /// If the result is larger than maximum of `T`, [None] will be returned. pub fn nth_prime_est(target: &T) -> Option where for<'r> &'r T: RefNum, { let (mut lo, mut hi) = nth_prime_bounds(target)?; if lo == hi { return Some(lo); } while lo != &hi - T::from_u8(1).unwrap() { let x = (&lo + &hi) / T::from_u8(2).unwrap(); let mid = prime_pi_est(&x); if &mid < target { lo = x } else if &mid > target { hi = x } else { return Some(x); } } return Some(lo); } // TODO: More functions // REF: http://www.numbertheory.org/gnubc/bc_programs.html // REF: https://github.com/TilmanNeumann/java-math-library // - is_smooth: checks if the smoothness bound is at least b // - euler_phi: Euler's totient function // - jordan_tot: Jordan's totient function // Others include Louiville function, Mangoldt function, Dedekind psi function, Dickman rho function, etc.. #[cfg(test)] mod tests { use super::*; use rand::{prelude::SliceRandom, random}; use std::iter::FromIterator; #[test] fn is_prime64_test() { // test small primes for x in 2..100 { assert_eq!(SMALL_PRIMES.contains(&x), is_prime64(x as u64)); } assert!(is_prime64(677)); // from PR #7 assert!(!is_prime64(9773)); assert!(!is_prime64(13357)); assert!(!is_prime64(18769)); // some large primes assert!(is_prime64(6469693333)); assert!(is_prime64(13756265695458089029)); assert!(is_prime64(13496181268022124907)); assert!(is_prime64(10953742525620032441)); assert!(is_prime64(17908251027575790097)); // primes from examples in Bradley Berg's hash method assert!(is_prime64(480194653)); assert!(!is_prime64(20074069)); assert!(is_prime64(8718775377449)); assert!(is_prime64(3315293452192821991)); assert!(!is_prime64(8651776913431)); assert!(!is_prime64(1152965996591997761)); // false positives reported by JASory (#4) assert!(!is_prime64(600437059821397)); assert!(!is_prime64(3866032210719337)); assert!(!is_prime64(4100599722623587)); // ensure no factor for 100 random primes let mut rng = rand::thread_rng(); for _ in 0..100 { let x = random(); if !is_prime64(x) { continue; } assert_ne!(x % (*SMALL_PRIMES.choose(&mut rng).unwrap() as u64), 0); } // create random composites for _ in 0..100 { let x = random::() as u64; let y = random::() as u64; assert!(!is_prime64(x * y)); } } #[test] fn factorize64_test() { // some simple cases let fac4095 = BTreeMap::from_iter([(3, 2), (5, 1), (7, 1), (13, 1)]); let fac = factorize64(4095); assert_eq!(fac, fac4095); let fac123456789 = BTreeMap::from_iter([(3, 2), (3803, 1), (3607, 1)]); let fac = factorize64(123456789); assert_eq!(fac, fac123456789); let fac1_17 = BTreeMap::from_iter([(2071723, 1), (5363222357, 1)]); let fac = factorize64(11111111111111111); assert_eq!(fac, fac1_17); // perfect powers for exp in 2u32..5 { assert_eq!( factorize128(8167u128.pow(exp)), BTreeMap::from_iter([(8167, exp as usize)]) ); } // 100 random factorization tests for _ in 0..100 { let x = random(); let fac = factorize64(x); let mut prod = 1; for (p, exp) in fac { assert!( is_prime64(p), "factorization result should have prime factors! (get {})", p ); prod *= p.pow(exp as u32); } assert_eq!(x, prod, "factorization check failed! ({} != {})", x, prod); } } #[test] fn factorize128_test() { // some simple cases let fac_primorial19 = BTreeMap::from_iter(SMALL_PRIMES.iter().take(19).map(|&p| (p as u128, 1))); let fac = factorize128(7858321551080267055879090); assert_eq!(fac, fac_primorial19); let fac_smallbig = BTreeMap::from_iter([(167, 1), (2417851639229258349412369, 1)]); let fac = factorize128(403781223751286144351865623); assert_eq!(fac, fac_smallbig); // perfect powers for exp in 5u32..10 { // 2^64 < 8167^5 < 8167^9 < 2^128 assert_eq!( factorize128(8167u128.pow(exp)), BTreeMap::from_iter([(8167, exp as usize)]) ); } // random factorization tests for _ in 0..4 { let x = random::() >> 28; // test 100 bit numbers let fac = factorize128(x); let mut prod = 1; for (p, exp) in fac { assert!( is_prime(&p, None).probably(), "factorization result should have prime factors! (get {})", p ); prod *= p.pow(exp as u32); } assert_eq!(x, prod, "factorization check failed! ({} != {})", x, prod); } } #[test] fn is_safe_prime_test() { // OEIS:A005385 let safe_primes = [ 5u16, 7, 11, 23, 47, 59, 83, 107, 167, 179, 227, 263, 347, 359, 383, 467, 479, 503, 563, 587, 719, 839, 863, 887, 983, 1019, 1187, 1283, 1307, 1319, 1367, 1439, 1487, 1523, 1619, 1823, 1907, ]; for p in SMALL_PRIMES { let p = p as u16; if p > 1500 { break; } assert_eq!( is_safe_prime(&p).probably(), safe_primes.iter().find(|&v| &p == v).is_some() ); } } #[test] fn moebius_test() { // test small examples let mu20: [i8; 20] = [ 1, -1, -1, 0, -1, 1, -1, 0, 0, 1, -1, 0, -1, 1, 1, 0, -1, 0, -1, 0, ]; for i in 0..20 { assert_eq!(moebius(&(i + 1)), mu20[i], "moebius on {}", i); } // some square numbers assert_eq!(moebius(&1024u32), 0); assert_eq!(moebius(&(8081u32 * 8081)), 0); // sphenic numbers let sphenic3: [u8; 20] = [ 30, 42, 66, 70, 78, 102, 105, 110, 114, 130, 138, 154, 165, 170, 174, 182, 186, 190, 195, 222, ]; // OEIS:A007304 for i in 0..20 { assert_eq!(moebius(&sphenic3[i]), -1i8, "moebius on {}", sphenic3[i]); } let sphenic5: [u16; 23] = [ 2310, 2730, 3570, 3990, 4290, 4830, 5610, 6006, 6090, 6270, 6510, 6630, 7410, 7590, 7770, 7854, 8610, 8778, 8970, 9030, 9282, 9570, 9690, ]; // OEIS:A046387 for i in 0..20 { assert_eq!(moebius(&sphenic5[i]), -1i8, "moebius on {}", sphenic5[i]); } } #[test] fn prime_pi_bounds_test() { fn check(n: u64, pi: u64) { let (lo, hi) = prime_pi_bounds(&n); let est = prime_pi_est(&n); assert!( lo <= pi && pi <= hi, "fail to satisfy {} <= pi({}) = {} <= {}", lo, n, pi, hi ); assert!(lo <= est && est <= hi); } // test with sieved primes let mut pb = NaiveBuffer::new(); let mut last = 0; for (i, p) in pb.primes(100000).cloned().enumerate() { for j in last..p { check(j, i as u64); } last = p; } // test with some known cases with input as 10^n, OEIS:A006880 let pow10_values = [ 0, 4, 25, 168, 1229, 9592, 78498, 664579, 5761455, 50847534, 455052511, 4118054813, 37607912018, 346065536839, 3204941750802, 29844570422669, 279238341033925, 2623557157654233, ]; for (exponent, gt) in pow10_values.iter().enumerate() { let n = 10u64.pow(exponent as u32); check(n, *gt); } } #[test] fn nth_prime_bounds_test() { fn check(n: u64, p: u64) { let (lo, hi) = super::nth_prime_bounds(&n).unwrap(); assert!( lo <= p && p <= hi, "fail to satisfy: {} <= {}-th prime = {} <= {}", lo, n, p, hi ); let est = super::nth_prime_est(&n).unwrap(); assert!(lo <= est && est <= hi); } // test with sieved primes let mut pb = NaiveBuffer::new(); for (i, p) in pb.primes(100000).cloned().enumerate() { check(i as u64 + 1, p as u64); } // test with some known cases with input as 10^n, OEIS:A006988 let pow10_values = [ 2, 29, 541, 7919, 104729, 1299709, 15485863, 179424673, 2038074743, 22801763489, 252097800623, 2760727302517, 29996224275833, 323780508946331, 3475385758524527, 37124508045065437, ]; for (exponent, nth_prime) in pow10_values.iter().enumerate() { let n = 10u64.pow(exponent as u32); check(n, *nth_prime); } } #[test] fn prev_next_test() { assert_eq!(prev_prime(&2u32, None), None); // prime table boundary test assert_eq!(prev_prime(&257u16, None), Some(251)); assert_eq!(next_prime(&251u16, None), Some(257)); assert_eq!(next_prime(&251u8, None), None); assert_eq!(prev_prime(&8167u16, None), Some(8161)); assert_eq!(next_prime(&8161u16, None), Some(8167)); // OEIS:A077800 let twine_primes: [(u32, u32); 8] = [ (2, 3), // not exactly twine (3, 5), (5, 7), (11, 13), (17, 19), (29, 31), (41, 43), (617, 619), ]; for (p1, p2) in twine_primes { assert_eq!(prev_prime(&p2, None).unwrap(), p1); assert_eq!(next_prime(&p1, None).unwrap(), p2); } let adj10_primes: [(u32, u32); 7] = [ (7, 11), (97, 101), (997, 1009), (9973, 10007), (99991, 100003), (999983, 1000003), (9999991, 10000019), ]; for (i, (p1, p2)) in adj10_primes.iter().enumerate() { assert_eq!(prev_prime(p2, None).unwrap(), *p1); assert_eq!(next_prime(p1, None).unwrap(), *p2); let pow = 10u32.pow((i + 1) as u32); assert_eq!(prev_prime(&pow, None).unwrap(), *p1); assert_eq!(next_prime(&pow, None).unwrap(), *p2); } } } num-prime-0.4.4/src/primality.rs000064400000000000000000000464310072674642500147510ustar 00000000000000use crate::traits::{BitTest, ExactRoots, PrimalityUtils}; use either::Either; use num_integer::{Integer, Roots}; use num_modular::{ModularCoreOps, ModularRefOps, ModularUnaryOps}; use num_traits::{FromPrimitive, NumRef, RefNum, ToPrimitive}; /// Utilities for the Lucas pseudoprime test pub trait LucasUtils { /// Find Lucas sequence to n with modulo m, i.e. $U_{n+1}(P,Q)$ mod m and $V_{n+1}(P,Q)$ fn lucasm(p: usize, q: isize, m: Self, n: Self) -> (Self, Self) where Self: Sized; /// Find proper parameters P and Q of Lucas pseudoprime test for n, such that Jacobi(D|n) is -1, /// using Selfridge's method (referred as method A by Baillie). fn pq_selfridge(n: &Self) -> (usize, isize); /// Find proper parameters P of extra strong Lucas pseudoprime test for n, such that Jacobi(D|n) is -1, /// using brute-force searching (referred as method C by Baillie) fn p_bruteforce(n: &Self) -> usize; } impl LucasUtils for T where T: Integer + FromPrimitive + ToPrimitive + NumRef + BitTest + ExactRoots + Clone + ModularRefOps, for<'r> &'r T: RefNum + ModularUnaryOps<&'r T, Output = T> + ModularCoreOps<&'r T, &'r T, Output = T>, { fn lucasm(p: usize, q: isize, m: Self, n: Self) -> (Self, Self) { // Reference: // and Peter Hackman, "Elementary Number Theory", section "L.XVII Scalar" let p = T::from_usize(p).unwrap() % &m; let q = if q >= 0 { T::from_isize(q).unwrap() % &m } else { T::from_isize(-q).unwrap().negm(&m) }; let mut uk = T::zero() % &m; // U(k), mod m for montgomery form let mut uk1 = T::one() % &m; // U(k+1) for i in (0..n.bits()).rev() { if n.bit(i) { // k' = 2k+1 // U(k'+1) = U(2k+2) = PU(k+1)² - 2*QU(k+1)U(k) let uk1sq = (&uk1).sqm(&m); let t1 = (&p).mulm(&uk1sq, &m); let t2 = (&q).mulm(&uk1, &m).mulm(&uk, &m).dblm(&m); let new_uk1 = t1.subm(&t2, &m); // U(k') = U(2k+1) = U(k+1)² - QU(k)² let t1 = uk1sq; let t2 = (&q).mulm(&uk.sqm(&m), &m); let new_uk = t1.subm(&t2, &m); uk1 = new_uk1; uk = new_uk; } else { // k' = 2k // U(k'+1) = U(2k+1) = U(k+1)² - QU(k)² let uksq = (&uk).sqm(&m); let t1 = (&uk1).sqm(&m); let t2 = (&uksq).mulm(&q, &m); let new_uk1 = t1.subm(&t2, &m); // U(k') = U(2k) = 2U(k+1)U(k) - PU(k)² let t1 = uk1.mulm(&uk, &m).dblm(&m); let t2 = uksq.mulm(&p, &m); let new_uk = t1.subm(&t2, &m); uk1 = new_uk1; uk = new_uk; } } // V(k) = 2U(k+1) - PU(k) let vk = (&uk1).dblm(&m).subm(&p.mulm(&uk, &m), &m); (uk, vk) } fn pq_selfridge(n: &Self) -> (usize, isize) { let mut d = T::from_u8(5).unwrap(); let mut neg = false; loop { // check if n is a square number after several trials if &d == &T::from_u8(13).unwrap() && (*n).is_square() { break (0, 0); } let sd = if neg { (&d).negm(n) } else { d.clone() }; let j = sd.jacobi(n); if j == 0 && &d != n { break (0, 0); } // modification from Baillie, see https://oeis.org/A217120/a217120_1.txt if j == -1 { let d = if neg { -d.to_isize().unwrap() } else { d.to_isize().unwrap() }; break (1, (1 - d) / 4); } d = d + T::from_u8(2).unwrap(); neg = !neg; } } fn p_bruteforce(n: &Self) -> usize { let mut p: usize = 3; loop { // check if n is a square number after several trials if p == 10 && (*n).is_square() { break 0; } let d = T::from_usize(p * p - 4).unwrap(); let j = d.jacobi(n); if j == 0 && &d != n { break 0; } if j == -1 { break p; } p += 1; } } } impl PrimalityUtils for T where for<'r> &'r T: RefNum + std::ops::Shr + ModularUnaryOps<&'r T, Output = T>, { #[inline] fn is_prp(&self, base: Self) -> bool { if self < &Self::one() { return false; } let tm1 = self - Self::one(); base.powm(&tm1, self).is_one() } #[inline] fn is_sprp(&self, base: Self) -> bool { self.test_sprp(base).either(|v| v, |_| false) } fn test_sprp(&self, base: T) -> Either { if self < &Self::one() { return Either::Left(false); } // find 2^shift*u + 1 = n let tm1 = self - T::one(); let shift = tm1.trailing_zeros(); let u = &tm1 >> shift; // prevent reduction if the input is in montgomery form let m1 = T::one() % self; let mm1 = (&m1).negm(self); let mut x = base.powm(&u, self); if x == m1 || x == mm1 { return Either::Left(true); } for _ in 0..shift { let y = (&x).sqm(self); if y == m1 { return Either::Right(self.gcd(&(x - T::one()))); } if y == mm1 { return Either::Left(true); } x = y; } Either::Left(x == m1) } fn is_lprp(&self, p: Option, q: Option) -> bool { if self < &Self::one() { return false; } if self.is_even() { return false; } let (p, q) = match (p, q) { (Some(sp), Some(sq)) => (sp, sq), (_, _) => { let (sp, sq) = LucasUtils::pq_selfridge(self); if sp == 0 { return false; }; // is a perfect power (sp, sq) } }; let d = (p * p) as isize - 4 * q; let d = if d > 0 { Self::from_isize(d).unwrap() } else { Self::from_isize(-d).unwrap().negm(self) }; let delta = match d.jacobi(self) { 0 => self.clone(), -1 => self + Self::one(), 1 => self - Self::one(), _ => unreachable!(), }; let (u, _) = LucasUtils::lucasm(p, q, self.clone(), delta); u.is_zero() } fn is_slprp(&self, p: Option, q: Option) -> bool { if self < &Self::one() { return false; } if self.is_even() { return false; } let (p, q) = match (p, q) { (Some(sp), Some(sq)) => (sp, sq), (_, _) => { let (sp, sq) = LucasUtils::pq_selfridge(self); if sp == 0 { return false; }; // is a perfect power (sp, sq) } }; let d = (p * p) as isize - 4 * q; let d = if d > 0 { Self::from_isize(d).unwrap() } else { Self::from_isize(-d).unwrap().negm(self) }; let delta = match d.jacobi(self) { 0 => self.clone(), -1 => self + Self::one(), 1 => self - Self::one(), _ => unreachable!(), }; let shift = delta.trailing_zeros(); let base = &delta >> shift; let (ud, vd) = LucasUtils::lucasm(p, q, self.clone(), base.clone()); if ud.is_zero() || vd.is_zero() { return true; } // do first iteration to remove the sign on Q if shift == 0 { return false; } let mut qk = Self::from_isize(q.abs()).unwrap().powm(&base, self); // V(2k) = V(k)² - 2Q^k let mut vd = if q >= 0 { vd.sqm(self).subm(&(&qk).dblm(self), self) } else { vd.sqm(self).addm(&(&qk).dblm(self), self) }; if vd.is_zero() { return true; } for _ in 1..shift { // V(2k) = V(k)² - 2Q^k qk = qk.sqm(self); vd = vd.sqm(self).subm(&(&qk).dblm(self), self); if vd.is_zero() { return true; } } false } fn is_eslprp(&self, p: Option) -> bool { if self < &Self::one() { return false; } if self.is_even() { return false; } let p = match p { Some(sp) => sp, None => { let sp = LucasUtils::p_bruteforce(self); if sp == 0 { return false; }; // is a perfect power sp } }; let d = (p * p) as isize - 4; let d = if d > 0 { Self::from_isize(d).unwrap() } else { Self::from_isize(-d).unwrap().negm(self) }; let delta = match d.jacobi(self) { 0 => self.clone(), -1 => self + Self::one(), 1 => self - Self::one(), _ => unreachable!(), }; let shift = delta.trailing_zeros(); let base = &delta >> shift; let (ud, mut vd) = LucasUtils::lucasm(p, 1, self.clone(), base.clone()); let two = Self::from_u8(2).unwrap(); // U(d) = 0 or V(d) = ±2 if ud.is_zero() && (vd == two || vd == self - &two) { return true; } if vd.is_zero() { return true; } for _ in 1..(shift - 1) { // V(2k) = V(k)² - 2 vd = vd.sqm(self).subm(&two, self); if vd.is_zero() { return true; } } false } } /// A dummy trait for integer type. All types that implements this and [PrimalityRefBase] /// will be supported by most functions in `num-primes` pub trait PrimalityBase: Integer + Roots + NumRef + Clone + FromPrimitive + ToPrimitive + ExactRoots + BitTest + ModularRefOps { } impl< T: Integer + Roots + NumRef + Clone + FromPrimitive + ToPrimitive + ExactRoots + BitTest + ModularRefOps, > PrimalityBase for T { } /// A dummy trait for integer reference type. All types that implements this and [PrimalityBase] /// will be supported by most functions in `num-primes` pub trait PrimalityRefBase: RefNum + std::ops::Shr + for<'r> ModularUnaryOps<&'r Base, Output = Base> + for<'r> ModularCoreOps<&'r Base, &'r Base, Output = Base> { } impl PrimalityRefBase for T where T: RefNum + std::ops::Shr + for<'r> ModularUnaryOps<&'r Base, Output = Base> + for<'r> ModularCoreOps<&'r Base, &'r Base, Output = Base> { } #[cfg(test)] mod tests { use super::*; use crate::mint::SmallMint; use num_modular::{ModularAbs, ModularSymbols}; use rand::random; #[cfg(feature = "num-bigint")] use num_bigint::BigUint; #[test] fn fermat_prp_test() { // 341 is the smallest pseudoprime for base 2 assert!(341u16.is_prp(2)); assert!(!340u16.is_prp(2)); assert!(!105u16.is_prp(2)); // Carmichael number 561 = 3*11*17 is fermat pseudoprime for any base coprime to 561 for p in [2, 5, 7, 13, 19] { assert!(561u32.is_prp(p)); } } #[test] fn sprp_test() { // strong pseudoprimes of base 2 (OEIS:A001262) under 10000 let spsp: [u16; 5] = [2047, 3277, 4033, 4681, 8321]; for psp in spsp { assert!(psp.is_sprp(2)); assert!(SmallMint::from(psp).is_sprp(2.into())); // test Mint execution } // test cofactor return assert_eq!(341u16.test_sprp(2), Either::Right(31)); assert_eq!( SmallMint::from(341u16).test_sprp(2.into()), Either::Right(31.into()) ); } #[test] fn lucas_mod_test() { // OEIS:A006190 let p3qm1: [u64; 26] = [ 0, 1, 3, 10, 33, 109, 360, 1189, 3927, 12970, 42837, 141481, 467280, 1543321, 5097243, 16835050, 55602393, 183642229, 606529080, 2003229469, 6616217487, 21851881930, 72171863277, 238367471761, 787274278560, 2600190307441, ]; let m = random::(); for n in 2..p3qm1.len() { let (uk, _) = LucasUtils::lucasm(3, -1, m as u64, n as u64); assert_eq!(uk, p3qm1[n] % (m as u64)); #[cfg(feature = "num-bigint")] { let (uk, _) = LucasUtils::lucasm(3, -1, BigUint::from(m), BigUint::from(n)); assert_eq!(uk, BigUint::from(p3qm1[n] % (m as u64))); } } fn lucasm_naive(p: usize, q: isize, m: u16, n: u16) -> (u16, u16) { if n == 0 { return (0, 2); } let m = m as usize; let q = q.absm(&m); let (mut um1, mut u) = (0, 1); // U_{n-1}, U_{n} let (mut vm1, mut v) = (2, p % m); // V_{n-1}, V_{n} for _ in 1..n { let new_u = p.mulm(u, &m).subm(q.mulm(um1, &m), &m); um1 = u; u = new_u; let new_v = p.mulm(v, &m).subm(q.mulm(vm1, &m), &m); vm1 = v; v = new_v; } (u as u16, v as u16) } for _ in 0..10 { let n = random::() as u16; let m = random::(); let p = random::() as usize; let q = random::() as isize; assert_eq!( LucasUtils::lucasm(p, q, m, n), lucasm_naive(p, q, m, n), "failed with Lucas settings: p={}, q={}, m={}, n={}", p, q, m, n ); } } #[test] fn lucas_prp_test() { // Some known cases assert!(19u8.is_lprp(Some(3), Some(-1))); assert!(5u8.is_lprp(None, None)); assert!(7u8.is_lprp(None, None)); assert!(!9u8.is_lprp(None, None)); assert!(!5719u16.is_lprp(None, None)); assert!(!1239u16.is_eslprp(None)); // least lucas pseudo primes for Q=-1 and Jacobi(D/n) = -1 (from Wikipedia) let plimit: [u16; 5] = [323, 35, 119, 9, 9]; for (i, l) in plimit.iter().cloned().enumerate() { let p = i + 1; assert!(l.is_lprp(Some(p), Some(-1))); // test four random numbers under limit for _ in 0..10 { let n = random::() % l; if n <= 3 || n.is_sprp(2) { continue; } // skip real primes let d = (p * p + 4) as u16; if n.is_odd() && d.jacobi(&n) != -1 { continue; } assert!( !n.is_lprp(Some(p), Some(-1)), "lucas prp test on {} with p = {}", n, p ); } } // least strong lucas pseudoprimes for Q=-1 and Jacobi(D/n) = -1 (from Wikipedia) let plimit: [u16; 3] = [4181, 169, 119]; for (i, l) in plimit.iter().cloned().enumerate() { let p = i + 1; assert!(l.is_slprp(Some(p), Some(-1))); // test random numbers under limit for _ in 0..10 { let n = random::() % l; if n <= 3 || (n.is_sprp(2) && n.is_sprp(3)) { continue; } // skip real primes let d = (p * p + 4) as u16; if n.is_odd() && d.jacobi(&n) != -1 { continue; } assert!( !n.is_slprp(Some(p), Some(-1)), "strong lucas prp test on {} with p = {}", n, p ); } } // lucas pseudoprimes (OEIS:A217120) under 10000 let lpsp: [u16; 9] = [323, 377, 1159, 1829, 3827, 5459, 5777, 9071, 9179]; for psp in lpsp { assert!( psp.is_lprp(None, None), "lucas prp test on pseudoprime {}", psp ); } for _ in 0..50 { let n = random::() % 10000; if n <= 3 || (n.is_sprp(2) && n.is_sprp(3)) { continue; } // skip real primes if lpsp.iter().find(|&x| x == &n).is_some() { continue; } // skip pseudoprimes assert!(!n.is_lprp(None, None), "lucas prp test on {}", n); } // strong lucas pseudoprimes (OEIS:A217255) under 10000 let slpsp: [u16; 2] = [5459, 5777]; for psp in slpsp { assert!( psp.is_slprp(None, None), "strong lucas prp test on pseudoprime {}", psp ); } for _ in 0..50 { let n = random::() % 10000; if n <= 3 || (n.is_sprp(2) && n.is_sprp(3)) { continue; } // skip real primes if slpsp.iter().find(|&x| x == &n).is_some() { continue; } // skip pseudoprimes assert!(!n.is_slprp(None, None), "strong lucas prp test on {}", n); } // extra strong lucas pseudoprimes (OEIS:A217719) under 10000 let eslpsp: [u16; 3] = [989, 3239, 5777]; for psp in eslpsp { assert!( psp.is_eslprp(None), "extra strong lucas prp test on pseudoprime {}", psp ); } for _ in 0..50 { let n = random::() % 10000; if n <= 3 || (n.is_sprp(2) && n.is_sprp(3)) { continue; } // skip real primes if eslpsp.iter().find(|&x| x == &n).is_some() { continue; } // skip pseudoprimes assert!(!n.is_eslprp(None), "extra strong lucas prp test on {}", n); } } } num-prime-0.4.4/src/rand.rs000064400000000000000000000237350072674642500136650ustar 00000000000000use crate::mint::SmallMint; use crate::nt_funcs::{is_prime, is_prime64, next_prime}; use crate::{PrimalityTestConfig, RandPrime}; #[cfg(feature = "num-bigint")] use num_bigint::{BigUint, RandBigInt}; use rand::Rng; macro_rules! impl_randprime_prim { ($($T:ty)*) => {$( impl RandPrime<$T> for R { #[inline] fn gen_prime(&mut self, bit_size: usize, _: Option) -> $T { if bit_size > (<$T>::BITS as usize) { panic!("The given bit size limit exceeded the capacity of the integer type!") } loop { let t: $T = self.gen(); let t = (t >> (<$T>::BITS - bit_size as u32)) | 1; // filter even numbers if is_prime64(t as u64) { break t } else if let Some(p) = next_prime(&t, None) { // deterministic primality test will be used for integers under u64 break p } } } #[inline] fn gen_prime_exact(&mut self, bit_size: usize, _: Option) -> $T { if bit_size > (<$T>::BITS as usize) { panic!("The given bit size limit exceeded the capacity of the integer type!") } loop { let t: $T = self.gen(); let t = (t >> (<$T>::BITS - bit_size as u32)) | 1 | (1 << (bit_size - 1)); if is_prime64(t as u64) { break t } else if let Some(p) = next_prime(&t, None) { // deterministic primality test will be used for integers under u64 break p } } } #[inline] fn gen_safe_prime(&mut self, bit_size: usize) -> $T { loop { // deterministic primality test will be used for integers under u64 let p = self.gen_prime(bit_size, None); // test (p-1)/2 if is_prime64((p >> 1) as u64) { break p } // test 2p+1 if let Some(p2) = p.checked_mul(2).and_then(|v| v.checked_add(1)) { if is_prime64(p2 as u64) { break p2 } } } } #[inline] fn gen_safe_prime_exact(&mut self, bit_size: usize) -> $T { loop { // deterministic primality test will be used for integers under u64 let p: $T = self.gen_prime_exact(bit_size, None); // test (p-1)/2 if is_prime64((p >> 1) as u64) { break p } } } } )*} } impl_randprime_prim!(u8 u16 u32 u64); impl RandPrime for R { #[inline] fn gen_prime(&mut self, bit_size: usize, config: Option) -> u128 { if bit_size > (u128::BITS as usize) { panic!("The given bit size limit exceeded the capacity of the integer type!") } loop { let t: u128 = self.gen(); let t = (t >> (u128::BITS - bit_size as u32)) | 1; // filter even numbers if is_prime(&SmallMint::from(t), config).probably() { break t; } else if let Some(p) = next_prime(&t, None) { // deterministic primality test will be used for integers under u64 break p; } } } #[inline] fn gen_prime_exact(&mut self, bit_size: usize, config: Option) -> u128 { if bit_size > (u128::BITS as usize) { panic!("The given bit size limit exceeded the capacity of the integer type!") } loop { let t: u128 = self.gen(); let t = (t >> (u128::BITS - bit_size as u32)) | 1 | (1 << (bit_size - 1)); if is_prime(&SmallMint::from(t), config).probably() { break t; } else if let Some(p) = next_prime(&t, None) { // deterministic primality test will be used for integers under u64 break p; } } } #[inline] fn gen_safe_prime(&mut self, bit_size: usize) -> u128 { loop { let config = Some(PrimalityTestConfig::strict()); let p = self.gen_prime(bit_size, config); if is_prime(&SmallMint::from(p >> 1), config).probably() { break p; } if let Some(p2) = p.checked_mul(2).and_then(|v| v.checked_add(1)) { if is_prime(&p2, config).probably() { break p2; } } } } #[inline] fn gen_safe_prime_exact(&mut self, bit_size: usize) -> u128 { loop { let config = Some(PrimalityTestConfig::strict()); let p = self.gen_prime_exact(bit_size, config); if is_prime(&SmallMint::from(p >> 1), config).probably() { break p; } } } } #[cfg(feature = "num-bigint")] impl RandPrime for R { #[inline] fn gen_prime(&mut self, bit_size: usize, config: Option) -> BigUint { loop { let mut t = self.gen_biguint(bit_size as u64); t.set_bit(0, true); // filter even numbers if is_prime(&t, config).probably() { break t; } else if let Some(p) = next_prime(&t, config) { break p; } } } #[inline] fn gen_prime_exact(&mut self, bit_size: usize, config: Option) -> BigUint { loop { let mut t = self.gen_biguint(bit_size as u64); t.set_bit(0, true); // filter even numbers t.set_bit(bit_size as u64 - 1, true); if is_prime(&t, config).probably() { break t; } else if let Some(p) = next_prime(&t, config) { break p; } } } #[inline] fn gen_safe_prime(&mut self, bit_size: usize) -> BigUint { let config = Some(PrimalityTestConfig::strict()); let p = self.gen_prime(bit_size, config); if is_prime(&(&p >> 1u8), config).probably() { return p; } let p2 = (p << 1u8) + 1u8; if is_prime(&p2, config).probably() { return p2; } self.gen_safe_prime(bit_size) } #[inline] fn gen_safe_prime_exact(&mut self, bit_size: usize) -> BigUint { let config = Some(PrimalityTestConfig::strict()); loop { let p: BigUint = self.gen_prime_exact(bit_size, config); if is_prime(&(&p >> 1u8), config).probably() { return p; } } } } #[cfg(test)] mod tests { use super::*; use crate::nt_funcs::is_safe_prime; #[test] fn rand_prime() { let mut rng = rand::thread_rng(); // test random prime generation for each size let p: u8 = rng.gen_prime(8, None); assert!(is_prime64(p as u64)); let p: u16 = rng.gen_prime(16, None); assert!(is_prime64(p as u64)); let p: u32 = rng.gen_prime(32, None); assert!(is_prime64(p as u64)); let p: u64 = rng.gen_prime(64, None); assert!(is_prime64(p)); let p: u128 = rng.gen_prime(128, None); assert!(is_prime(&p, None).probably()); // test random safe prime generation let p: u8 = rng.gen_safe_prime(8); assert!(is_safe_prime(&p).probably()); let p: u32 = rng.gen_safe_prime(32); assert!(is_safe_prime(&p).probably()); let p: u128 = rng.gen_safe_prime(128); assert!(is_safe_prime(&p).probably()); #[cfg(feature = "num-bigint")] { let p: BigUint = rng.gen_prime(512, None); assert!(is_prime(&p, None).probably()); let p: BigUint = rng.gen_safe_prime(192); assert!(is_safe_prime(&p).probably()); } // test bit size limit let p: u16 = rng.gen_prime(12, None); assert!(p < (1 << 12)); let p: u32 = rng.gen_prime(24, None); assert!(p < (1 << 24)); } #[test] fn rand_prime_exact() { let mut rng = rand::thread_rng(); // test exact size prime generation let p: u8 = rng.gen_prime_exact(8, None); assert!(is_prime64(p as u64)); assert_eq!(p.leading_zeros(), 0); let p: u32 = rng.gen_prime_exact(32, None); assert!(is_prime64(p as u64)); assert_eq!(p.leading_zeros(), 0); let p: u128 = rng.gen_prime_exact(128, None); assert!(is_prime(&p, None).probably()); assert_eq!(p.leading_zeros(), 0); // test random safe prime generation let p: u8 = rng.gen_safe_prime_exact(8); assert!(is_safe_prime(&p).probably()); assert_eq!(p.leading_zeros(), 0); let p: u32 = rng.gen_safe_prime_exact(32); assert!(is_safe_prime(&p).probably()); assert_eq!(p.leading_zeros(), 0); let p: u128 = rng.gen_safe_prime_exact(128); assert!(is_safe_prime(&p).probably()); assert_eq!(p.leading_zeros(), 0); #[cfg(feature = "num-bigint")] { let p: BigUint = rng.gen_prime_exact(192, None); assert!(is_prime(&p, None).probably()); assert_eq!(p.bits(), 192); let p: BigUint = rng.gen_safe_prime_exact(192); assert!(is_safe_prime(&p).probably()); assert_eq!(p.bits(), 192); } } } num-prime-0.4.4/src/tables.rs000064400000000000000000010075140072674642500142110ustar 00000000000000//////////////////// Known small primes //////////////////// // The prime table here is used for prime buffer initialization, and also used // for trivial division in integer factorization and moebius mu function // only list primes to 256 if big-table feature is disabled /// A static table of small primes #[cfg(not(feature = "big-table"))] pub const SMALL_PRIMES: [u8; 54] = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, ]; /// Next prime of the last one in SMALL_PRIMES #[cfg(not(feature = "big-table"))] pub const SMALL_PRIMES_NEXT: u64 = 257; // list 1024 primes if big-table feature is enabled /// A static table of small primes #[cfg(feature = "big-table")] pub const SMALL_PRIMES: [u16; 1024] = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, // 8167, 8171, 8179, 8191 ]; /// Next prime of the last one in SMALL_PRIMES #[cfg(feature = "big-table")] pub const SMALL_PRIMES_NEXT: u64 = 8167; //////////////////// Pre-computed inversions for primes //////////////////// #[cfg(feature = "big-table")] type P64 = num_modular::PreInv; /// Precomputed modular inverse for fast divisibility check /// /// Note that the factor 2 should be eliminated before checking the primes #[rustfmt::skip] #[cfg(feature = "big-table")] pub const SMALL_PRIMES_INV: [P64; 1024] = [ // the first should be 2, but 2 has not modular inverse P64::new(0x0000000000000001, 0xffffffffffffffff), P64::new(0xaaaaaaaaaaaaaaab, 0x5555555555555555), P64::new(0xcccccccccccccccd, 0x3333333333333333), P64::new(0x6db6db6db6db6db7, 0x2492492492492492), P64::new(0x2e8ba2e8ba2e8ba3, 0x1745d1745d1745d1), P64::new(0x4ec4ec4ec4ec4ec5, 0x13b13b13b13b13b1), P64::new(0xf0f0f0f0f0f0f0f1, 0x0f0f0f0f0f0f0f0f), P64::new(0x86bca1af286bca1b, 0x0d79435e50d79435), P64::new(0xd37a6f4de9bd37a7, 0x0b21642c8590b216), P64::new(0x34f72c234f72c235, 0x08d3dcb08d3dcb08), P64::new(0xef7bdef7bdef7bdf, 0x0842108421084210), P64::new(0x14c1bacf914c1bad, 0x06eb3e45306eb3e4), P64::new(0x8f9c18f9c18f9c19, 0x063e7063e7063e70), P64::new(0x82fa0be82fa0be83, 0x05f417d05f417d05), P64::new(0x51b3bea3677d46cf, 0x0572620ae4c415c9), P64::new(0x21cfb2b78c13521d, 0x04d4873ecade304d), P64::new(0xcbeea4e1a08ad8f3, 0x0456c797dd49c341), P64::new(0x4fbcda3ac10c9715, 0x04325c53ef368eb0), P64::new(0xf0b7672a07a44c6b, 0x03d226357e16ece5), P64::new(0x193d4bb7e327a977, 0x039b0ad12073615a), P64::new(0x7e3f1f8fc7e3f1f9, 0x0381c0e070381c0e), P64::new(0x9b8b577e613716af, 0x033d91d2a2067b23), P64::new(0xa3784a062b2e43db, 0x03159721ed7e7534), P64::new(0xf47e8fd1fa3f47e9, 0x02e05c0b81702e05), P64::new(0xa3a0fd5c5f02a3a1, 0x02a3a0fd5c5f02a3), P64::new(0x3a4c0a237c32b16d, 0x0288df0cac5b3f5d), P64::new(0xdab7ec1dd3431b57, 0x027c45979c95204f), P64::new(0x77a04c8f8d28ac43, 0x02647c69456217ec), P64::new(0xa6c0964fda6c0965, 0x02593f69b02593f6), P64::new(0x90fdbc090fdbc091, 0x0243f6f0243f6f02), P64::new(0x7efdfbf7efdfbf7f, 0x0204081020408102), P64::new(0x03e88cb3c9484e2b, 0x01f44659e4a42715), P64::new(0xe21a291c077975b9, 0x01de5d6e3f8868a4), P64::new(0x3aef6ca970586723, 0x01d77b654b82c339), P64::new(0xdf5b0f768ce2cabd, 0x01b7d6c3dda338b2), P64::new(0x6fe4dfc9bf937f27, 0x01b2036406c80d90), P64::new(0x5b4fe5e92c0685b5, 0x01a16d3f97a4b01a), P64::new(0x1f693a1c451ab30b, 0x01920fb49d0e228d), P64::new(0x8d07aa27db35a717, 0x01886e5f0abb0499), P64::new(0x882383b30d516325, 0x017ad2208e0ecc35), P64::new(0xed6866f8d962ae7b, 0x016e1f76b4337c6c), P64::new(0x3454dca410f8ed9d, 0x016a13cd15372904), P64::new(0x1d7ca632ee936f3f, 0x01571ed3c506b39a), P64::new(0x70bf015390948f41, 0x015390948f40feac), P64::new(0xc96bdb9d3d137e0d, 0x014cab88725af6e7), P64::new(0x2697cc8aef46c0f7, 0x0149539e3b2d066e), P64::new(0xc0e8f2a76e68575b, 0x013698df3de07479), P64::new(0x687763dfdb43bb1f, 0x0125e22708092f11), P64::new(0x1b10ea929ba144cb, 0x0120b470c67c0d88), P64::new(0x1d10c4c0478bbced, 0x011e2ef3b3fb8744), P64::new(0x63fb9aeb1fdcd759, 0x0119453808ca29c0), P64::new(0x64afaa4f437b2e0f, 0x0112358e75d30336), P64::new(0xf010fef010fef011, 0x010fef010fef010f), P64::new(0x28cbfbeb9a020a33, 0x0105197f7d734041), P64::new(0xff00ff00ff00ff01, 0x00ff00ff00ff00ff), P64::new(0xd624fd1470e99cb7, 0x00f92fb2211855a8), P64::new(0x8fb3ddbd6205b5c5, 0x00f3a0d52cba8723), P64::new(0xd57da36ca27acdef, 0x00f1d48bcee0d399), P64::new(0xee70c03b25e4463d, 0x00ec979118f3fc4d), P64::new(0xc5b1a6b80749cb29, 0x00e939651fe2d8d3), P64::new(0x47768073c9b97113, 0x00e79372e225fe30), P64::new(0x2591e94884ce32ad, 0x00dfac1f74346c57), P64::new(0xf02806abc74be1fb, 0x00d578e97c3f5fe5), P64::new(0x7ec3e8f3a7198487, 0x00d2ba083b445250), P64::new(0x58550f8a39409d09, 0x00d161543e28e502), P64::new(0xec9e48ae6f71de15, 0x00cebcf8bb5b4169), P64::new(0x2ff3a018bfce8063, 0x00c5fe740317f9d0), P64::new(0x7f9ec3fcf61fe7b1, 0x00c2780613c0309e), P64::new(0x89f5abe570e046d3, 0x00bcdd535db1cc5b), P64::new(0xda971b23f1545af5, 0x00bbc8408cd63069), P64::new(0x79d5f00b9a7862a1, 0x00b9a7862a0ff465), P64::new(0x4dba1df32a128a57, 0x00b68d31340e4307), P64::new(0x87530217b7747d8f, 0x00b2927c29da5519), P64::new(0x30baae53bb5e06dd, 0x00afb321a1496fdf), P64::new(0xee70206c12e9b5b3, 0x00aceb0f891e6551), P64::new(0xcdde9462ec9dbe7f, 0x00ab1cbdd3e2970f), P64::new(0xafb64b05ec41cf4d, 0x00a87917088e262b), P64::new(0x02944ff5aec02945, 0x00a513fd6bb00a51), P64::new(0x2cb033128382df71, 0x00a36e71a2cb0331), P64::new(0x1ccacc0c84b1c2a9, 0x00a03c1688732b30), P64::new(0x19a93db575eb3a0b, 0x009c69169b30446d), P64::new(0xcebeef94fa86fe2d, 0x009baade8e4a2f6e), P64::new(0x6faa77fb3f8df54f, 0x00980e4156201301), P64::new(0x68a58af00975a751, 0x00975a750ff68a58), P64::new(0xd56e36d0c3efac07, 0x009548e4979e0829), P64::new(0xd8b44c47a8299b73, 0x0093efd1c50e726b), P64::new(0x02d9ccaf9ba70e41, 0x0091f5bcb8bb02d9), P64::new(0x0985e1c023d9e879, 0x008f67a1e3fdc261), P64::new(0x2a343316c494d305, 0x008e2917e0e702c6), P64::new(0x70cb7916ab67652f, 0x008d8be33f95d715), P64::new(0xd398f132fb10fe5b, 0x008c55841c815ed5), P64::new(0x6f2a38a6bf54fa1f, 0x0088d180cd3a4133), P64::new(0x211df689b98f81d7, 0x00869222b1acf1ce), P64::new(0x0e994983e90f1ec3, 0x0085797b917765ab), P64::new(0xad671e44bed87f3b, 0x008355ace3c897db), P64::new(0xf9623a0516e70fc7, 0x00824a4e60b3262b), P64::new(0x4b7129be9dece355, 0x0080c121b28bd1ba), P64::new(0x190f3b7473f62c39, 0x007dc9f3397d4c29), P64::new(0x63dacc9aad46f9a3, 0x007d4ece8fe88139), P64::new(0xc1108fda24e8d035, 0x0079237d65bcce50), P64::new(0xb77578472319bd8b, 0x0077cf53c5f7936c), P64::new(0x473d20a1c7ed9da5, 0x0075a8accfbdd11e), P64::new(0xfbe85af0fea2c8fb, 0x007467ac557c228e), P64::new(0x58a1f7e6ce0f4c09, 0x00732d70ed8db8e9), P64::new(0x1a00e58c544986f3, 0x0072c62a24c3797f), P64::new(0x7194a17f55a10dc1, 0x007194a17f55a10d), P64::new(0x7084944785e33763, 0x006fa549b41da7e7), P64::new(0xba10679bd84886b1, 0x006e8419e6f61221), P64::new(0xebe9c6bb31260967, 0x006d68b5356c207b), P64::new(0x97a3fe4bd1ff25e9, 0x006d0b803685c01b), P64::new(0x6c6388395b84d99f, 0x006bf790a8b2d207), P64::new(0x8c51da6a1335df6d, 0x006ae907ef4b96c2), P64::new(0x46f3234475d5add9, 0x006a37991a23aead), P64::new(0x905605ca3c619a43, 0x0069dfbdd4295b66), P64::new(0xcee8dff304767747, 0x0067dc4c45c8033e), P64::new(0xff99c27f00663d81, 0x00663d80ff99c27f), P64::new(0xacca407f671ddc2b, 0x0065ec17e3559948), P64::new(0xe71298bac1e12337, 0x00654ac835cfba5c), P64::new(0xfa1e94309cd09045, 0x00645c854ae10772), P64::new(0xbebccb8e91496b9b, 0x006372990e5f901f), P64::new(0x312fa30cc7d7b8bd, 0x006325913c07beef), P64::new(0x6160ff9e9f006161, 0x006160ff9e9f0061), P64::new(0x6b03673b5e28152d, 0x0060cdb520e5e88e), P64::new(0xfe802ffa00bfe803, 0x005ff4017fd005ff), P64::new(0xe66fe25c9e907c7b, 0x005ed79e31a4dccd), P64::new(0x3f8b236c76528895, 0x005d7d42d48ac5ef), P64::new(0xf6f923bf01ce2c0d, 0x005c6f35ccba5028), P64::new(0x6c3d3d98bed7c42f, 0x005b2618ec6ad0a5), P64::new(0x30981efcd4b010e7, 0x005a2553748e42e7), P64::new(0x6f691fc81ebbe575, 0x0059686cf744cd5b), P64::new(0xb10480ddb47b52cb, 0x0058ae97bab79976), P64::new(0x74cd59ed64f3f0d7, 0x0058345f1876865f), P64::new(0x0105cb81316d6c0f, 0x005743d5bb24795a), P64::new(0x9be64c6d91c1195d, 0x005692c4d1ab74ab), P64::new(0x71b3f945a27b1f49, 0x00561e46a4d5f337), P64::new(0x77d80d50e508fd01, 0x005538ed06533997), P64::new(0xa5eb778e133551cd, 0x0054c807f2c0bec2), P64::new(0x18657d3c2d8a3f1b, 0x005345efbc572d36), P64::new(0x2e40e220c34ad735, 0x00523a758f941345), P64::new(0xa76593c70a714919, 0x005102370f816c89), P64::new(0x1eef452124eea383, 0x0050cf129fb94acf), P64::new(0x38206dc242ba771d, 0x004fd31941cafdd1), P64::new(0x4cd4c35807772287, 0x004fa1704aa75945), P64::new(0x83de917d5e69ddf3, 0x004f3ed6d45a63ad), P64::new(0x882ef0403b4a6c15, 0x004f0de57154ebed), P64::new(0xf8fb6c51c606b677, 0x004e1cae8815f811), P64::new(0xb4abaac446d3e1fd, 0x004cd47ba5f6ff19), P64::new(0xa9f83bbe484a14e9, 0x004c78ae734df709), P64::new(0x0bebbc0d1ce874d3, 0x004c4b19ed85cfb8), P64::new(0xbd418eaf0473189f, 0x004bf093221d1218), P64::new(0x44e3af6f372b7e65, 0x004aba3c21dc633f), P64::new(0xc87fdace4f9e5d91, 0x004a6360c344de00), P64::new(0xec93479c446bd9bb, 0x004a383e9f74d68a), P64::new(0xdac4d592e777c647, 0x0049e28fbabb9940), P64::new(0xa63ea8c8f61f0c23, 0x0048417b57c78cd7), P64::new(0xe476062ea5cbbb6f, 0x0047f043713f3a2b), P64::new(0xdf68761c69daac27, 0x00474ff2a10281cf), P64::new(0xb813d737637aa061, 0x00468b6f9a978f91), P64::new(0xa3a77aac1fb15099, 0x0045f13f1caff2e2), P64::new(0x17f0c3e0712c5825, 0x0045a5228cec23e9), P64::new(0xfd912a70ff30637b, 0x0045342c556c66b9), P64::new(0xfbb3b5dc01131289, 0x0044c4a23feeced7), P64::new(0x856d560a0f5acdf7, 0x0043c5c20d3c9fe6), P64::new(0x96472f314d3f89e3, 0x00437e494b239798), P64::new(0xa76f5c7ed2253531, 0x0043142d118e47cb), P64::new(0x816eae7c7bf69fe7, 0x0042ab5c73a13458), P64::new(0xb6a2bea4cfb1781f, 0x004221950db0f3db), P64::new(0xa3900c53318e81ed, 0x0041bbb2f80a4553), P64::new(0x60aa7f5d9f148d11, 0x0040f391612c6680), P64::new(0x6be8c0102c7a505d, 0x0040b1e94173fefd), P64::new(0x8ff3f0ed28728f33, 0x004050647d9d0445), P64::new(0x680e0a87e5ec7155, 0x004030241b144f3b), P64::new(0xbbf70fa49fe829b7, 0x003f90c2ab542cb1), P64::new(0xd69d1e7b6a50ca39, 0x003f71412d59f597), P64::new(0x1a1e0f46b6d26aef, 0x003f137701b98841), P64::new(0x7429f9a7a8251829, 0x003e79886b60e278), P64::new(0xd9c2219d1b863613, 0x003e5b1916a7181d), P64::new(0x91406c1820d077ad, 0x003dc4a50968f524), P64::new(0x521f4ec02e3d2b97, 0x003da6e4c9550321), P64::new(0xbb8283b63dc8eba5, 0x003d4e4f06f1def3), P64::new(0x431eda153229ebbf, 0x003c4a6bdd24f9a4), P64::new(0xaf0bf78d7e01686b, 0x003c11d54b525c73), P64::new(0xa9ced0742c086e8d, 0x003bf5b1c5721065), P64::new(0xc26458ad9f632df9, 0x003bbdb9862f23b4), P64::new(0xbbff1255dff892af, 0x003b6a8801db5440), P64::new(0xcbd49a333f04d8fd, 0x003b183cf0fed886), P64::new(0xec84ed6f9cfdeff5, 0x003aabe394bdc3f4), P64::new(0x97980cc40bda9d4b, 0x003a5ba3e76156da), P64::new(0x777f34d524f5cbd9, 0x003a0c3e953378db), P64::new(0x2797051d94cbbb7f, 0x0038f03561320b1e), P64::new(0xea769051b4f43b81, 0x0038d6ecaef5908a), P64::new(0xce7910f3034d4323, 0x003859cf221e6069), P64::new(0x92791d1374f5b99b, 0x0037f7415dc9588a), P64::new(0x89a5645cc68ea1b5, 0x00377df0d3902626), P64::new(0x5f8aacf796c0cf0b, 0x00373622136907fa), P64::new(0xf2e90a15e33edf99, 0x0036ef0c3b39b92f), P64::new(0x8e99e5feb897c451, 0x0036915f47d55e6d), P64::new(0xaca2eda38fb91695, 0x0036072cf3f866fd), P64::new(0x5d9b737be5ea8b41, 0x0035d9b737be5ea8), P64::new(0x4aefe1db93fd7cf7, 0x0035961559cc81c7), P64::new(0xa0994ef20b3f8805, 0x0035531c897a4592), P64::new(0x103890bda912822f, 0x00353ceebd3e98a4), P64::new(0xb441659d13a9147d, 0x0034fad381585e5e), P64::new(0x1e2134440c4c3f21, 0x00347884d1103130), P64::new(0x263a27727a6883c3, 0x00340dd3ac39bf56), P64::new(0x78e221472ab33855, 0x003351fdfecc140c), P64::new(0x95eac88e82e6faff, 0x00333d72b089b524), P64::new(0xf66c258317be8dab, 0x0033148d44d6b261), P64::new(0x09ee202c7cb91939, 0x0032d7aef8412458), P64::new(0x8d2fca1042a09ea3, 0x0032c3850e79c0f1), P64::new(0x82779c856d8b8bf1, 0x00328766d59048a2), P64::new(0x3879361cba8a223d, 0x00325fa18cb11833), P64::new(0xf23f43639c3182a7, 0x00324bd659327e22), P64::new(0xa03868fc474bcd13, 0x0032246e784360f4), P64::new(0x651e78b8c5311a97, 0x0031afa5f1a33a08), P64::new(0x8ffce639c00c6719, 0x00319c63ff398e70), P64::new(0xf7b460754b0b61cf, 0x003162f7519a86a7), P64::new(0x7b03f3359b8e63b1, 0x0030271fc9d3fc3c), P64::new(0xa55c5326041eb667, 0x002ff104ae89750b), P64::new(0x647f88ab896a76f5, 0x002fbb62a236d133), P64::new(0x8fd971434a55a46d, 0x002f74997d2070b4), P64::new(0x9fbf969958046447, 0x002ed84aa8b6fce3), P64::new(0x9986feba69be3a81, 0x002e832df7a46dbd), P64::new(0xa668b3e6d053796f, 0x002e0e0846857cab), P64::new(0x97694e6589f4e09b, 0x002decfbdfb55ee6), P64::new(0x37890c00b7721dbd, 0x002ddc876f3ff488), P64::new(0x5ac094a235f37ea9, 0x002dbbc1d4c482c4), P64::new(0x31cff775f2d5d65f, 0x002d8af0e0de0556), P64::new(0xddad8e6b36505217, 0x002d4a7b7d14b30a), P64::new(0x5a27df897062cd03, 0x002d2a85073bcf4e), P64::new(0xe2396fe0fdb5a625, 0x002d1a9ab13e8be4), P64::new(0xb352a4957e82317b, 0x002ceb1eb4b9fd8b), P64::new(0xd8ab3f2c60c2ea3f, 0x002c8d503a79794c), P64::new(0x6893f702f0452479, 0x002c404d708784ed), P64::new(0x9686fdc182acf7e3, 0x002c31066315ec52), P64::new(0x6854037173dce12f, 0x002c1297d80f2664), P64::new(0x7f0ded1685c27331, 0x002c037044c55f6b), P64::new(0xeeda72e1fe490b7d, 0x002be5404cd13086), P64::new(0x9e7bfc959a8e6e53, 0x002bb845adaf0cce), P64::new(0x49b314d6d4753dd7, 0x002b5f62c639f16d), P64::new(0x2e8f8c5ac4aa1b3b, 0x002b07e6734f2b88), P64::new(0xb8ef723481163d33, 0x002ace569d8342b7), P64::new(0x6a2ec96a594287b7, 0x002a791d5dbd4dcf), P64::new(0xdba41c6d13aab8c5, 0x002a4eff8113017c), P64::new(0xc2adbe648dc3aaf1, 0x002a3319e156df32), P64::new(0x87a2bade565f91a7, 0x002a0986286526ea), P64::new(0x4d6fe8798c01f5df, 0x0029d29551d91e39), P64::new(0x3791310c8c23d98b, 0x0029b7529e109f0a), P64::new(0xf80e446b01228883, 0x00298137491ea465), P64::new(0x9aed1436fbf500cf, 0x0029665e1eb9f9da), P64::new(0x7839b54cc8b24115, 0x002909752e019a5e), P64::new(0xc128c646ad0309c1, 0x0028ef35e2e5efb0), P64::new(0x14de631624a3c377, 0x0028c815aa4b8278), P64::new(0x3f7b9fe68b0ecbf9, 0x0028bb1b867199da), P64::new(0x284ffd75ec00a285, 0x0028a13ff5d7b002), P64::new(0x37803cb80dea2ddb, 0x00287ab3f173e755), P64::new(0x86b63f7c9ac4c6fd, 0x00286dead67713bd), P64::new(0x8b6851d1bd99b9d3, 0x002847bfcda6503e), P64::new(0xb62fda77ca343b6d, 0x002808c1ea6b4777), P64::new(0x1f0dc009e34383c9, 0x00278d0e0f23ff61), P64::new(0x496dc21ddd35b97f, 0x002768863c093c7f), P64::new(0xb0e96ce17090f82b, 0x0027505115a73ca8), P64::new(0xaadf05acdd7d024d, 0x00274441a61dc1b9), P64::new(0xcb138196746eafb5, 0x0026b5c166113cf0), P64::new(0x347f523736755d61, 0x00269e65ad07b18e), P64::new(0xd14a48a051f7dd0b, 0x002692c25f877560), P64::new(0x474d71b1ce914d25, 0x002658fa7523cd11), P64::new(0x386063f5e28c1f89, 0x0026148710cf0f9e), P64::new(0x1db7325e32d04e73, 0x002609363b22524f), P64::new(0xfef748d3893b880d, 0x0025d1065a1c1122), P64::new(0x2f3351506e935605, 0x0025a48a382b863f), P64::new(0x7a3637fa2376415b, 0x0025837190eccdbc), P64::new(0x4ac525d2baa21969, 0x00256292e95d510c), P64::new(0x3a11c16b42cd351f, 0x002541eda98d068c), P64::new(0x6c7abde0049c2a11, 0x0024e15087fed8f5), P64::new(0x54dad0303e069ac7, 0x0024c18b20979e5d), P64::new(0xebf1ac9fdfe91433, 0x0024ac7b336de0c5), P64::new(0xfafdda8237cec655, 0x0024a1fc478c60bb), P64::new(0xdce3ff6e71ffb739, 0x002463801231c009), P64::new(0xbed5737d6286db1b, 0x0024300fd506ed33), P64::new(0xe479e431fe08b4df, 0x0023f314a494da81), P64::new(0x9dd9b0dd7742f897, 0x0023cadedd2fad3a), P64::new(0x8f09d7402c5a5e87, 0x00237b7ed2664a03), P64::new(0x9216d5c4d958738d, 0x0023372967dbaf1d), P64::new(0xb3139ba11d34ca63, 0x00231a308a371f20), P64::new(0x47d54f7ed644afaf, 0x002306fa63e1e600), P64::new(0x92a81d85cf11a1b1, 0x0022fd6731575684), P64::new(0x754b26533253bdfd, 0x0022ea507805749c), P64::new(0xbbe0efc980bfd467, 0x0022e0cce8b3d720), P64::new(0xc0d8d594f024dca1, 0x0022b1887857d161), P64::new(0x8238d43bcaac1a65, 0x00227977fcc49cc0), P64::new(0x27779c1fae6175bb, 0x00225db37b5e5f4f), P64::new(0xa746ca9af708b2c9, 0x0022421b91322ed6), P64::new(0x93f3cd9f389be823, 0x0021f05b35f52102), P64::new(0x5cb4a4c04c489345, 0x0021e75de5c70d60), P64::new(0xbf6047743e85b6b5, 0x0021a01d6c19be96), P64::new(0x61c147831563545f, 0x0021974a6615c81a), P64::new(0xedb47c0ae62dee9d, 0x00213767697cf36a), P64::new(0x0a3824386673a573, 0x00211d9f7fad35f1), P64::new(0xa4a77d19e575a0eb, 0x0020fb7d9dd36c18), P64::new(0xa2bee045e066c279, 0x0020e2123d661e0e), P64::new(0xc23618de8ab43d05, 0x0020d135b66ae990), P64::new(0x266b515216cb9f2f, 0x0020c8cded4d7a8e), P64::new(0xe279edd9e9c2e85b, 0x0020b80b3f43ddbf), P64::new(0xd0c591c221dc9c53, 0x002096b9180f46a6), P64::new(0x06da8ee9c9ee7c21, 0x00207de7e28de5da), P64::new(0x9dfebcaf4c27e8c3, 0x002054dec8cf1fb3), P64::new(0x49aeff9f19dd6de5, 0x00204cb630b3aab5), P64::new(0x86976a57a296e9c7, 0x00202428adc37beb), P64::new(0xa3b9abf4872b84cd, 0x001fec0c7834def4), P64::new(0x34fca6483895e6ef, 0x001fc46fae98a1d0), P64::new(0x34b5a333988f873d, 0x001facda430ff619), P64::new(0xd9dd4f19b5f17be1, 0x001f7e17dd8e15e5), P64::new(0xb935b507fd0ce78b, 0x001f765a3556a4ee), P64::new(0xb450f5540660e797, 0x001f66ea49d802f1), P64::new(0x63ff82831ffc1419, 0x001f5f3800faf9c0), P64::new(0x8992f718c22a32fb, 0x001f38f4e6c0f1f9), P64::new(0x5f3253ad0d37e7bf, 0x001f0b8546752578), P64::new(0x007c0ffe0fc007c1, 0x001f03ff83f001f0), P64::new(0x4d8ebadc0c0640b1, 0x001ec853b0a3883c), P64::new(0xe2729af831037bdb, 0x001ec0ee573723eb), P64::new(0xb8f64bf30feebfe9, 0x001eaad38e6f6894), P64::new(0xda93124b544c0bf5, 0x001e9c28a765fe53), P64::new(0x9cf7ff0b593c539f, 0x001e94d8758c2003), P64::new(0xd6bd8861fa0e07d9, 0x001e707ba8f65e68), P64::new(0x5cfe75c0bd8ab891, 0x001e53a2a68f574e), P64::new(0x43e808757c2e862b, 0x001e1380a56b438d), P64::new(0x90caa96d595c9d93, 0x001dbf9f513a3802), P64::new(0x8fd550625d07135f, 0x001db1d1d58bc600), P64::new(0x76b010a86e209f2d, 0x001d9d358f53de38), P64::new(0xecc0426447769b25, 0x001d81e6df6165c7), P64::new(0xe381339caabe3295, 0x001d4bdf7fd40e30), P64::new(0xd1b190a2d0c7673f, 0x001d452c7a1c958d), P64::new(0xc3bce3cf26b0e7eb, 0x001d37cf9b902659), P64::new(0x5f87e76f56c61ce3, 0x001d1d3a5791e97b), P64::new(0xc06c6857a124b353, 0x001ce89fe6b47416), P64::new(0x38c040fcba630f75, 0x001ce219f3235071), P64::new(0xd078bc4fbd533b21, 0x001cd516dcf92139), P64::new(0xde8e15c5dd354f59, 0x001cbb33bd1c2b8b), P64::new(0xca61d53d7414260f, 0x001ca7e7d2546688), P64::new(0xb56bf5ba8eae635d, 0x001c94b5c1b3dbd3), P64::new(0x44a72cb0fb6e3949, 0x001c87f7f9c241c1), P64::new(0x879839a714f45bcd, 0x001c6202706c35a9), P64::new(0x02a8994fde5314b7, 0x001c5bb8a9437632), P64::new(0xb971920cf2b90135, 0x001c174343b4111e), P64::new(0x8a8fd0b7df9a6e8b, 0x001c04d0d3e46b42), P64::new(0xb31f9a84c1c6eaad, 0x001bfeb00fbf4308), P64::new(0x92293b02823c6d83, 0x001bec5dce0b202d), P64::new(0xeee77ff20fe5ddcf, 0x001be03444620037), P64::new(0x0e1ea0f6c496c11d, 0x001bce09c66f6fc3), P64::new(0xfdf2d3d6f88ccb6b, 0x001ba40228d02b30), P64::new(0xfa9d74a3457738f9, 0x001b9225b1cf8919), P64::new(0xefc3ca3db71a5785, 0x001b864a2ff3f53f), P64::new(0x8e2071718d0d6daf, 0x001b80604150e49b), P64::new(0xbc0fdbfeb6cfabfd, 0x001b6eb1aaeaacf3), P64::new(0x1eeab613e5e5aee9, 0x001b62f48da3c8cc), P64::new(0x2d2388e90e9e929f, 0x001b516babe96092), P64::new(0x81dbafba588ddb43, 0x001b2e9cef1e0c87), P64::new(0x52eebc51c4799791, 0x001b1d56bedc849b), P64::new(0x1c6bc4693b45a047, 0x001b0c267546aec0), P64::new(0x06eee0974498874d, 0x001ae45f62024fa0), P64::new(0xd85b7377a9953cb9, 0x001ad917631b5f54), P64::new(0x4b6df412d4caf56f, 0x001ac83d18cb608f), P64::new(0x6b8afbbb4a053493, 0x001aa6c7ad8c063f), P64::new(0xcc5299c96ac7720b, 0x001a90a7b1228e2a), P64::new(0xadce84b5c710aa99, 0x001a8027c03ba059), P64::new(0x9d673f5aa3804225, 0x001a7533289deb89), P64::new(0xe6541268efbce7f7, 0x001a2ed7ce16b49f), P64::new(0xfcf41e76cf5be669, 0x0019fefc0a279a73), P64::new(0x5c3eb5dc31c383cb, 0x0019e4b0cd873b5f), P64::new(0x301832d11d8ad6c3, 0x0019cfcdfd60e514), P64::new(0x2e9c0942f1ce450f, 0x0019c56932d66c85), P64::new(0x97f3f2be37a39a5d, 0x0019b5e1ab6fc7c2), P64::new(0xe8b7d8a9654187c7, 0x0019b0b8a62f2a73), P64::new(0xb5d024d7da5b1b55, 0x0019a149fc98942c), P64::new(0xb8ba9d6e7ae3501b, 0x001969517ec25b85), P64::new(0xf50865f71b90f1df, 0x00194b3083360ba8), P64::new(0x739c1682847df9e1, 0x00194631f4bebdc1), P64::new(0xc470a4d842b90ed1, 0x00191e84127268fd), P64::new(0x1fb1be11698cc409, 0x00190adbb543984f), P64::new(0xd8d5512a7cd35d15, 0x001901130bd18200), P64::new(0xa5496821723e07f9, 0x0018e3e6b889ac94), P64::new(0xbcc8c6d7abaa8167, 0x0018c233420e1ec1), P64::new(0x52c396c95eb619a1, 0x0018aa5872d92bd6), P64::new(0x6eb7e380878ec74b, 0x0018a5989945ccf9), P64::new(0x3d5513b504537157, 0x00189c1e60b57f60), P64::new(0x314391f8862e948f, 0x0018893fbc8690b9), P64::new(0xdc0b17cfcd81f5dd, 0x00187b2bb3e1041c), P64::new(0x2f6bea3ec89044b3, 0x00186d27c9cdcfb8), P64::new(0xce13a05869f1b57f, 0x001863d8bf4f2c1c), P64::new(0x7593474e8ace3581, 0x00185f33e2ad7593), P64::new(0x07fc329295a05e4d, 0x001855ef75973e13), P64::new(0xb05377cba4908d23, 0x001848160153f134), P64::new(0xe7b2131a628aa39b, 0x001835b72e6f0656), P64::new(0x9031dbed7de01527, 0x00182c922d83eb39), P64::new(0x76844b1c670aa9a9, 0x0018280243c0365a), P64::new(0x6a03f4533b08915f, 0x00181a5cd5898e73), P64::new(0x1dbca579db0a3999, 0x001803c0961773aa), P64::new(0x002ffe800bffa003, 0x0017ff4005ffd001), P64::new(0x478ab1a3e936139d, 0x0017e8d670433edb), P64::new(0x66e722bc4c5cc095, 0x0017d7066cf4bb5d), P64::new(0x7a8f63c717278541, 0x0017ce285b806b1f), P64::new(0xdf6eee24d292bc2f, 0x0017af52cdf27e02), P64::new(0x9fc20d17237dd569, 0x0017997d47d01039), P64::new(0xcdf9932356bda2ed, 0x00177f7ec2c6d0ba), P64::new(0x97b5e332e80f68d7, 0x00177b2f3cd00756), P64::new(0x46eee26fd875e2e5, 0x00176e4a22f692a0), P64::new(0x3548a8e65157a611, 0x001765b94271e11b), P64::new(0xc288d03be9b71e3b, 0x001761732b044ae4), P64::new(0x8151186db38937ab, 0x00173f7a5300a2bc), P64::new(0x7800b910895a45f1, 0x001722112b48be1f), P64::new(0xaee0b024182eec3d, 0x001719b7a16eb843), P64::new(0x96323eda173b5713, 0x00170d3c99cc5052), P64::new(0x0ed0dbd03ae77c8b, 0x0016fcad7aed3bb6), P64::new(0xf73800b7828dc119, 0x0016f051b8231ffd), P64::new(0x1b61715ec22b7ca5, 0x0016e81beae20643), P64::new(0xa8533a991ead64bf, 0x0016c3721584c1d8), P64::new(0x7f6c7290e46c2e77, 0x0016b34c2ba09663), P64::new(0x6325e8d907b01db1, 0x00169f3ce292ddcd), P64::new(0x28909f70152a1067, 0x00169344b2220a0d), P64::new(0xea7077af0997a0f5, 0x001687592593c1b1), P64::new(0x7e605cad10c32e6d, 0x00167787f1418ec9), P64::new(0x471b33570635b38f, 0x001663e190395ff2), P64::new(0xab559fa997a61bb3, 0x00164c7a4b6eb5b3), P64::new(0xad4bdae562bddab9, 0x0016316a061182fd), P64::new(0x055e1b2f2ed62f45, 0x001629ba914584e4), P64::new(0x03cd328b1a2dca9b, 0x00161e3d57de21b2), P64::new(0xd28f4e08733218a9, 0x001612cc01b977f0), P64::new(0xb6800b077f186293, 0x00160efe30c525ff), P64::new(0x6fbd138c3fd9c207, 0x0015da45249ec5de), P64::new(0xb117ccd12ae88a89, 0x0015d68ab4acff92), P64::new(0x2f1a1a044046bceb, 0x0015c3f989d1eb15), P64::new(0x548aba0b060541e3, 0x0015b535ad11b8f0), P64::new(0xcf4e808cea111b2f, 0x0015addb3f424ec1), P64::new(0xdbec1b4fa855a475, 0x00159445cb91be6b), P64::new(0xe3f794eb600d7821, 0x00158d0199771e63), P64::new(0x34fae0d9a11f7c59, 0x00157e87d9b69e04), P64::new(0xf006b0ccbbac085d, 0x001568f58bc01ac3), P64::new(0x3f45076dc3114733, 0x00155e3c993fda9b), P64::new(0xeef49bfa58a1a1b7, 0x001548eacc5e1e6e), P64::new(0x12c4218bea691fa3, 0x001541d8f91ba6a7), P64::new(0xbc7504e3bd5e64f1, 0x00153747060cc340), P64::new(0x4ee21c292bb92fad, 0x001514569f93f7c4), P64::new(0x34338b7327a4bacf, 0x00150309705d3d79), P64::new(0x3fe5c0833d6fccd1, 0x0014ff97020cf5bf), P64::new(0xb1e70743535203c1, 0x0014e42c114cf47e), P64::new(0xefbb5dcdfb4e43d3, 0x0014b835bdcb6447), P64::new(0xca68467ca5394f9f, 0x0014b182b53a9ab7), P64::new(0x8c51c081408b97a1, 0x0014ae2ad094a3d3), P64::new(0x3275a899dfa5dd65, 0x00149a320ea59f96), P64::new(0x9e674cb62e1b78bb, 0x001490441de1a2fb), P64::new(0xa37ff5bb2a998d47, 0x001489aacce57200), P64::new(0x792a999db131a22b, 0x001475f82ad6ff99), P64::new(0x1b48841bc30d29b9, 0x00146c2cfe53204f), P64::new(0xf06721d2011d3471, 0x00145f2ca490d4a1), P64::new(0x93fd2386dff85ebd, 0x001458b2aae0ec87), P64::new(0x4ce72f54c07ed9b5, 0x00144bcb0a3a3150), P64::new(0xd6d0fd3e71dd827b, 0x001428a1e65441d4), P64::new(0x856405fb1eed819d, 0x00142575a6c210d7), P64::new(0x8ea8aceb7c443989, 0x00141f2025ba5c46), P64::new(0x34a13026f62e5873, 0x00141bf6e35420fd), P64::new(0x1eea0208ec0af4f7, 0x001409141d1d313a), P64::new(0x63679853cea598cb, 0x0013dd8bc19c3513), P64::new(0xc30b3ebd61f2d0ed, 0x0013da76f714dc8f), P64::new(0x7eb9037bc7f43bc3, 0x0013d13e50f8f49e), P64::new(0xa583e6f6ce016411, 0x0013c80e37ca3819), P64::new(0xf1938d895f1a74c7, 0x0013bee69fa99ccf), P64::new(0x80cf1491c1e81e33, 0x0013b8d0ede55835), P64::new(0x3c0f12886ba8f301, 0x0013afb7680bb054), P64::new(0x0e4b786e0dfcc5ab, 0x0013acb0c3841c96), P64::new(0x672684c93f2d41ef, 0x00139a9c5f434fde), P64::new(0xe00757badb35c51b, 0x0013949cf33a0d9d), P64::new(0xd6d84afe66472edf, 0x001382b4a00c31b0), P64::new(0xfbbc0eedcbbfb6e1, 0x00137fbbc0eedcbb), P64::new(0x250f43aa08a84983, 0x001370ecf047b069), P64::new(0x04400e927b1acaa5, 0x00136df9790e3155), P64::new(0x56572be34b9d3215, 0x0013567dd8defd5b), P64::new(0x87964ef7781c62bf, 0x0013539261fdbc34), P64::new(0x29ed84051c06e9af, 0x00133c564292d28a), P64::new(0xb00acd11ed3f87fd, 0x001333ae178d6388), P64::new(0x06307881744152d9, 0x0013170ad00d1fd7), P64::new(0x7a786459f5c1ccc9, 0x0013005f01db0947), P64::new(0x1308125d74563281, 0x0012f51d40342210), P64::new(0x395310a480b3e34d, 0x0012ef815e4ed950), P64::new(0x35985baa8b202837, 0x0012ecb4abccd827), P64::new(0x96304a6e052b3223, 0x0012e71dc1d3d820), P64::new(0xbd8265fc9af8fd45, 0x0012e45389a16495), P64::new(0x1b6d0b383ec58e0b, 0x0012c5d9226476cc), P64::new(0xc21a7c3b68b28503, 0x0012badc391156fd), P64::new(0x236fa180fbfd6007, 0x0012aa78e412f522), P64::new(0xc42accd440ed9595, 0x0012a251f5f47fd1), P64::new(0x7acf7128236ba3f7, 0x001294cb85c53534), P64::new(0xf909367a987b9c79, 0x0012921963beb65e), P64::new(0xb64efb252bfba705, 0x00128cb777c69ca8), P64::new(0x980d4f5a7e4cd25b, 0x001284aa6cf07294), P64::new(0xe1ecc4ef27b0c37d, 0x001281fcf6ac7f87), P64::new(0x9111aebb81d72653, 0x001279f937367db9), P64::new(0x8951f985cb2c67ed, 0x00126cad0488be94), P64::new(0xc439d4fc54e0b5d7, 0x00126a06794646a2), P64::new(0xe857bf31896d533b, 0x00125a2f2bcd3e95), P64::new(0xb614bb4cb5023755, 0x00124d108389e6b1), P64::new(0x938a89e5473bf1ff, 0x00124a73083771ac), P64::new(0xeac481aca34de039, 0x00123d6acda0620a), P64::new(0x14b961badf4809a7, 0x00122b4b2917eafd), P64::new(0x76784fecba352435, 0x00122391bfce1e2f), P64::new(0xefa689bb58aef5e1, 0x00121e6f1ea579f2), P64::new(0xb2b2c4db9c3a8197, 0x001216c09e471568), P64::new(0x2503bc992279f8cf, 0x00120c8cb9d93909), P64::new(0xd2ab9aec5ca1541d, 0x001204ed58e64ef9), P64::new(0x3e78ba1460f99af3, 0x0011fd546578f00c), P64::new(0x0a01426572cfcb63, 0x0011e9310b8b4c9c), P64::new(0xbea857968f3cbd67, 0x0011da3405db9911), P64::new(0x78db213eefe659e9, 0x0011d7b6f4eb055d), P64::new(0x963e8541a74d35f5, 0x0011d2bee748c145), P64::new(0x9e22d152776f2e43, 0x0011c1706ddce7a7), P64::new(0x05d10d39d1e1f291, 0x0011ba0fed2a4f14), P64::new(0x374468dccaced1dd, 0x0011b528538ed64a), P64::new(0x8d145c7d110c5ad5, 0x0011ab61404242ac), P64::new(0x3251a39f5acb5737, 0x00119f378ce81d2f), P64::new(0xa66e50171443506f, 0x001195889ece79da), P64::new(0x124f69ad91dd4cbd, 0x00118e4c65387077), P64::new(0xec24f8f2a61a2793, 0x001187161d70e725), P64::new(0xb472148e656b7a51, 0x00116cd6d1c85239), P64::new(0x0adf9570e1142f07, 0x001165bbe7ce86b1), P64::new(0x89bf33b065119789, 0x0011635ee344ce36), P64::new(0x8f0149803cb291eb, 0x0011579767b6d679), P64::new(0x8334b63afd190a31, 0x00114734711e2b54), P64::new(0x920908d50d6aba7d, 0x0011428b90147f05), P64::new(0x57d8b018c5a33d53, 0x00113b92f3021636), P64::new(0xea1773092dc27ee5, 0x001126cabc886884), P64::new(0xcae5f38b7bf2e00f, 0x0011247eb1b85976), P64::new(0x2bd02df34f695349, 0x0011190bb01efd65), P64::new(0xddfecd5be62e2eb7, 0x0011091de0fd679c), P64::new(0xdbf849ebec96c4a3, 0x001104963c7e4e0b), P64::new(0xda31d4d0187357c5, 0x00110253516420b0), P64::new(0xe34e21cc2d5418a7, 0x0010f70db7c41797), P64::new(0x68ca5137a9e574ad, 0x0010e75ee2bf9ecd), P64::new(0x3eaa0d0f804bfd19, 0x0010e2e91c6e0676), P64::new(0x554fb753cc20e9d1, 0x0010da049b9d428d), P64::new(0x797afcca1300756b, 0x0010c6248fe3b1a2), P64::new(0x8b8d950b52eeea77, 0x0010c1c03ed690eb), P64::new(0xfb6cd166acabc185, 0x0010bb2e1379e3a2), P64::new(0x4eb6c5ed9437a7af, 0x0010b8fe7f61228e), P64::new(0xd1eddbd91b790cdb, 0x0010b4a10d60a4f7), P64::new(0x93d714ea4d8948e9, 0x0010ae192681ec0f), P64::new(0x3ca13ed8145188d3, 0x0010abecfbe5b0ae), P64::new(0x829086016da89c57, 0x00109eefd568b96d), P64::new(0xd7da1f432124a543, 0x00109a9ff178b40c), P64::new(0x7ead5581632fb07f, 0x00108531e22f9ff9), P64::new(0x35443837f63ec3bd, 0x00106ddec1af4417), P64::new(0x89e2b200e5519461, 0x0010614174a4911d), P64::new(0xe9ae44f0b7289c0b, 0x00105f291f0448e7), P64::new(0x94387a277b9fa817, 0x00105afa0ef32891), P64::new(0xc84f1a58abfc2c25, 0x001054b777bd2530), P64::new(0x71101d8e3c83377b, 0x00104e79a97fb69e), P64::new(0xc024abe5c50ba69d, 0x00104c661eafd845), P64::new(0x15de4eb365a65d73, 0x0010462ea939c933), P64::new(0x09ed28a76bcca931, 0x00102f8baa442836), P64::new(0x816bffbf4a00205b, 0x00102d7ff7e94004), P64::new(0x1f5c71543d558069, 0x0010275ff9f13c02), P64::new(0xf25c64d0ec53b859, 0x001017213fcbb4d3), P64::new(0x96c02c2ef1e0ff0f, 0x00101112234579d1), P64::new(0x19a804816870a333, 0x00100501907d271c), P64::new(0x6de49add0971c555, 0x00100300901b0510), P64::new(0x528087e684c71aab, 0x000ffd008fe5050f), P64::new(0xa94152c269bcdeef, 0x000ff10e02dd5084), P64::new(0x0379450a3c2b6bdf, 0x000fe13b9c80c67f), P64::new(0xd2cd38bafe5373e1, 0x000fdf4384be37ad), P64::new(0xc29df2bea71d8bad, 0x000fdb54cbe8766e), P64::new(0xc15862775f302e83, 0x000fd5725ca6ff32), P64::new(0x1016af2fe55ede09, 0x000fc7c84684c6fb), P64::new(0x3d26dbd9d1910715, 0x000fc3e5265dbaa8), P64::new(0x621dab2dfaf3dfbf, 0x000fc1f44e0cae12), P64::new(0xb6f1d7ac287338b1, 0x000fb0921c50a7af), P64::new(0x8d9e9f0c3f9e7fd9, 0x000f999fd70cbc6b), P64::new(0x60a93f8762e914bb, 0x000f9023fd5339d0), P64::new(0xb14371f247c159c9, 0x000f8a78ce671475), P64::new(0x6dd3b484471d4eb3, 0x000f8895fee86574), P64::new(0xcd172f4701c1684d, 0x000f7f2ecb084b10), P64::new(0x0372e686ed8bb537, 0x000f7d4eb7d10c29), P64::new(0xbc07f7ca65c5b071, 0x000f73f52277a3c3), P64::new(0xab2b6170c3f78d9b, 0x000f7217c598961c), P64::new(0xf3d74f461fe6f5b5, 0x000f68cbb1448f42), P64::new(0xdbc13f4b31f3230b, 0x000f633d0276e4c5), P64::new(0xd1420716e3f1572d, 0x000f6163ac20ec79), P64::new(0xd5be2fd4d805464f, 0x000f582ba2bc16c6), P64::new(0xc68b97c136943851, 0x000f5654f43290a0), P64::new(0x9e27918af7cfb473, 0x000f4d2a23810bc6), P64::new(0x5ec8ab6c36ac7f41, 0x000f47af4d6a2f27), P64::new(0x964076331dd90979, 0x000f4066f2b6e652), P64::new(0x30198eff77b002d7, 0x000f2555048e3a92), P64::new(0x3af7cb9583ece011, 0x000f1c64588a5bf6), P64::new(0x34ce06f643d9883b, 0x000f1a9be09cb411), P64::new(0x79f767e528708c55, 0x000f11b7d5259d39), P64::new(0x185332d2ef2313cd, 0x000f0aa284e7f802), P64::new(0x43b611b84c8332a3, 0x000f0556e5e3b7f2), P64::new(0xc2e215e4f43bb63d, 0x000efc8bcbc808e5), P64::new(0xf94b9dd22ce44e97, 0x000eecd1a690efbb), P64::new(0xd895834a1db166a5, 0x000ee79aed6d65f2), P64::new(0x347d2f16d19b8d09, 0x000edd386114d83a), P64::new(0x1b54d4dc45b7d98d, 0x000ed2e44366e5e2), P64::new(0x117ac30d9a044877, 0x000ed12cf8e17f64), P64::new(0x0e10b78a67a526e9, 0x000ec1cd284b2b2d), P64::new(0x92da68a818688a9f, 0x000ebcb44cadda1e), P64::new(0xcf2b6c87f741f84b, 0x000eb9505943771d), P64::new(0xd264f9bd41e18ed9, 0x000eb43d57efeadc), P64::new(0x733cbeaa97166d8f, 0x000eaf2dd4c00b03), P64::new(0xc9f475b021d22e81, 0x000ea0141c1ba6a6), P64::new(0x731f76f2ec4c852b, 0x000e9e68805f05a7), P64::new(0xdaf6f0c978f69945, 0x000e96142b87e431), P64::new(0x749c8ad20c61ec93, 0x000e8a7acd811b8c), P64::new(0x09307ff8bd3c1261, 0x000e8587db3e001d), P64::new(0x334a69fb5a486e2d, 0x000e823d186d44dc), P64::new(0x1f36c7bf31578617, 0x000e8098463ee194), P64::new(0x31ebbcc279ea6103, 0x000e7d4fbfb3ee1d), P64::new(0x42e2aad119f466eb, 0x000e69bba6981ffa), P64::new(0x106ec05a0ab1450d, 0x000e681c5cf7d707), P64::new(0xb1b38db92a99e731, 0x000e5e684930e334), P64::new(0x784ae377e67071e7, 0x000e5993247dc92d), P64::new(0x3e9e1471ba6671d7, 0x000e4cbfee201016), P64::new(0x82c29b59d4d73d0f, 0x000e465ee7daf979), P64::new(0xc23dd07128b5525d, 0x000e4199de07af5c), P64::new(0x4d4e5ce0e9245133, 0x000e3cd8031d4f40), P64::new(0xc8fd1057c09f8cc5, 0x000e2ea56c157eb2), P64::new(0xea1516e94f394035, 0x000e221e5d4d3c73), P64::new(0xb5e3319c564ee9df, 0x000e208f09a841c7), P64::new(0x126a69f90d822d8b, 0x000e1d716a945161), P64::new(0x501ed6348857aa19, 0x000e18c78ec8fd4d), P64::new(0xde344a324eee1c83, 0x000e173a4a162079), P64::new(0x1dd9690cb2c406d1, 0x000e1294881bb494), P64::new(0x08d6c5178d5e4387, 0x000e0df1d5f24661), P64::new(0x4cea4050a3e8fdc1, 0x000e063ec7f50b1e), P64::new(0xc114a06acc83f777, 0x000e01a4313dc53d), P64::new(0x20b060ebc0ea01db, 0x000df8780f47c350), P64::new(0xfe50045acb78c99f, 0x000def57e8eb9666), P64::new(0x291a68705b196e91, 0x000de1bdf3f63d46), P64::new(0xc1042c724273e2bb, 0x000de03cb5099809), P64::new(0x2cee680bb165b7c9, 0x000ddbbaecc84bc9), P64::new(0xfd2ff9f12e0776d5, 0x000dd8bb5ca73db6), P64::new(0x166a5da63af2cc6f, 0x000dcb4d529a6e07), P64::new(0xedd16a5930408d27, 0x000dc55da73dea60), P64::new(0x2adf30c26528844f, 0x000db3ad2585011f), P64::new(0x9a48d6572b5eec7b, 0x000db0becf636a79), P64::new(0x6e8bf2877503cb9d, 0x000daf481ca6fefb), P64::new(0xea27a191a7045389, 0x000dac5ba7565dae), P64::new(0x6eb091f34dd45d3f, 0x000da7fb4e419d19), P64::new(0xdc8a6cabb2937d41, 0x000da6867a88d327), P64::new(0xbc2f04f254922a05, 0x000d9dd005f50b02), P64::new(0x41431f4d6eb38631, 0x000d9aeb01f763f7), P64::new(0x7bd717435a08291f, 0x000d90d31dd5804a), P64::new(0x4232df9c91fc1a55, 0x000d7b6453358f31), P64::new(0xa4651e1d5382eab7, 0x000d744e69d900e4), P64::new(0x7cfb5409de4cf3c5, 0x000d7011a317260e), P64::new(0xcdd636fb068b9929, 0x000d67a0126e7c19), P64::new(0xee8f95e740462c97, 0x000d5dd39e775bd7), P64::new(0x490f97b3a758b4a5, 0x000d59a4f2990168), P64::new(0x641431563c441287, 0x000d52b24cb6269d), P64::new(0xb743dad3ec45916b, 0x000d4a6571da4f04), P64::new(0x7b188be8f55c878d, 0x000d49044eac6581), P64::new(0xd805648b2ca54ef9, 0x000d4642e40d1129), P64::new(0x76dbe6eef60123af, 0x000d4222e81fe723), P64::new(0x3711525e6a9e8867, 0x000d3ca6e8c89f41), P64::new(0x85c2215cb383d8f5, 0x000d388ce29d4edc), P64::new(0xe58f554c89825857, 0x000d31bc7b7d8013), P64::new(0x8fbd3b17c01dacd9, 0x000d306071c13fd5), P64::new(0x4c8c39dc7aedee65, 0x000d2da935479b1a), P64::new(0x653ac6dda86cd3b3, 0x000d2430aa043597), P64::new(0x0d61c6791a9c2c81, 0x000d2025bc6c7db7), P64::new(0xb627a30090354237, 0x000d1c1d4ad1732b), P64::new(0x83a89a539c527c23, 0x000d196e5f46f8c8), P64::new(0x28c8c09330e90d71, 0x000d156a0c9293e8), P64::new(0xee1178d27b1f029b, 0x000d1413d26e0aee), P64::new(0xcecc740b37860ab5, 0x000d0d68c6a4128f), P64::new(0x79736fde910c485f, 0x000d0c142eaf3837), P64::new(0x6873d51f2487234f, 0x000d01792ab9d70d), P64::new(0x2a112180614fb973, 0x000cf990317775bc), P64::new(0xcb04cea98508f4eb, 0x000cf44f8c38790a), P64::new(0xc2fcd2c527e28d7d, 0x000ce88d96d10e45), P64::new(0x980203ee10393c69, 0x000ce5f39b07e906), P64::new(0x3fa90a1d7d75681f, 0x000ce20e98148847), P64::new(0xdbf3bfefef217cc3, 0x000cda4b9c30ccd7), P64::new(0x66a17fd3087b41e5, 0x000cd9015ae32495), P64::new(0x962195d496fbbd3b, 0x000cd524244aca36), P64::new(0xc705a86155443e49, 0x000cd14940099cf6), P64::new(0x3f298ee0be6febff, 0x000ccd70ac089a07), P64::new(0xaa99b084e62fa613, 0x000cbb9c535c4371), P64::new(0x1f000cb7d0b46fe1, 0x000cb7d0b46fe0ff), P64::new(0x9ed7858637c9b2cf, 0x000caefe5d7135f4), P64::new(0x4d871aaf27c106fb, 0x000cac7b5f00f0cd), P64::new(0x2e6a467cdc75a4f3, 0x000ca7785ceddbea), P64::new(0xe9d938fb696dde8d, 0x000ca13a2a86e1db), P64::new(0x40ec71b0b1554485, 0x000c9c4009753007), P64::new(0x3aae12f861e5f3e9, 0x000c94d02e64bfab), P64::new(0xa97565873959f843, 0x000c89b8c9c875ef), P64::new(0x0b5a960c09fbca8f, 0x000c87447737277e), P64::new(0x463fe3d268012c91, 0x000c860aaa2514e3), P64::new(0xe59a6bd5f5ee1bdd, 0x000c8397c813f1b9), P64::new(0x6542e84d7775ce45, 0x000c74fa805d6d56), P64::new(0x8b6eef58fd9effa9, 0x000c6db8a1f5cdfe), P64::new(0x58993dbb9f98075f, 0x000c6a1add9e2398), P64::new(0x2997955a810acf61, 0x000c68e6be826648), P64::new(0x76e3d2f5077db451, 0x000c5f4e25fc9df0), P64::new(0xb37c1d2867e30907, 0x000c5bb8bf2ad1cd), P64::new(0x53ce6e09bd8d8695, 0x000c58256b316ced), P64::new(0x39db291ea2a6b0e3, 0x000c4fd5ad917b5b), P64::new(0xddd265ab9c58847d, 0x000c49ecb3ea4d7a), P64::new(0x5beca8562dddd0cb, 0x000c41b00b7d950a), P64::new(0xb69031c153ddbed7, 0x000c3f57990b87a1), P64::new(0xd03c2271b42a6fcd, 0x000c2ddcb31250f8), P64::new(0xcd6fd19e63e40ea3, 0x000c2a63b3651432), P64::new(0xf7687aa8e4fd7bf1, 0x000c26ecae1db72e), P64::new(0x649dfda112a272a7, 0x000c2377a18c051e), P64::new(0xecf7866a56d526df, 0x000c1ede9efcec29), P64::new(0x72bbf1cfdaebfead, 0x000c1b6e258d13a0), P64::new(0x55f6a48df7055719, 0x000c19243f5399bb), P64::new(0x80060bffcfa00183, 0x000c17ff9f400305), P64::new(0x8a104f309919b087, 0x000c112865703b94), P64::new(0x98fa7db7652f6a15, 0x000c0dbfaea33225), P64::new(0x5d7d1b3df70f7ac1, 0x000c0b7af12ddfb9), P64::new(0x16ab7b5e04cc1f6b, 0x000c0a58e464462c), P64::new(0x78a5bfd2e5ececf9, 0x000c06f40512eef2), P64::new(0x6506392e171d869f, 0x000bfa9275a2b247), P64::new(0xc3fc12e221ef146d, 0x000bf7367402cdf0), P64::new(0xf8aa132822c33657, 0x000bf61833f4f921), P64::new(0x894496574f536f43, 0x000bf3dc543a74a1), P64::new(0x8b2546b08fb4cbd5, 0x000be9d9302a7115), P64::new(0x043bbb561bd1aa7f, 0x000be8bd6e051e01), P64::new(0x2412c7cc4ea7a12b, 0x000be6868804d5a6), P64::new(0x6f0bd406dd71696f, 0x000bdfe6c4359f0e), P64::new(0xad475c6988d54b71, 0x000bdeccdb0b5c3a), P64::new(0xd812e5d48dbbba27, 0x000bdb8058ee429a), P64::new(0x22aaca437ba04893, 0x000bd94e5c1b371f), P64::new(0xdba6ff1fecd5f09d, 0x000bcb1d293b1af3), P64::new(0x13016d3396286773, 0x000bc7db8db0c1a5), P64::new(0xc746494631bcfa41, 0x000bc49bbdfd2662), P64::new(0xd14888565bf6a10d, 0x000bc2723240f402), P64::new(0xc002ef885f0adf05, 0x000bbe217c2b7c13), P64::new(0xe5a04da7fee6ade7, 0x000bb8c10aab27b2), P64::new(0xc114ce5468593bc7, 0x000ba7ad528a7e79), P64::new(0x0bb6747dd7f577b7, 0x000b9f3611b48c5e), P64::new(0x395ce5a20f285839, 0x000b9e2806e5e7c4), P64::new(0x6eee8be66e8618ef, 0x000b9aff0c4913fe), P64::new(0x52acf64297f1241b, 0x000b98e4aedd581c), P64::new(0x361dcc48a364093d, 0x000b97d7c94b7dc2), P64::new(0x342d6f475d72e629, 0x000b95be902d9d9e), P64::new(0x5e978bd46410d413, 0x000b94b23c872b90), P64::new(0xcc3433d75ba015ad, 0x000b8f77714d15a1), P64::new(0x1c83b7628458d4fb, 0x000b882d0beff6a1), P64::new(0xf9ca45637e38f809, 0x000b850ff9852703), P64::new(0xcbed792ffaf6b115, 0x000b82fd86db8806), P64::new(0x9abd961d8c0e8c8d, 0x000b7edadd32f76c), P64::new(0xe69572fa659340af, 0x000b79b3b4df3b7b), P64::new(0x9187e7483a6436fd, 0x000b769e6d59833f), P64::new(0x1e9c726993bed9d9, 0x000b6c636b5141ff), P64::new(0x243554db91976365, 0x000b6a59ceae8801), P64::new(0x04d06ff994c0088f, 0x000b6955461e38f7), P64::new(0x25b76abcb74889dd, 0x000b6648c2dc6bc2), P64::new(0x3a409642893c779b, 0x000b572282260209), P64::new(0x8f8f620d8bc0c927, 0x000b552072bde889), P64::new(0x6f9f196b3369855f, 0x000b511e7552f9c4), P64::new(0x92a522bb0638ed99, 0x000b4c1ff34a5c0e), P64::new(0x96270f1efdd7004f, 0x000b4922f58d4aa2), P64::new(0xb4844b380fdaa79d, 0x000b46278c16b967), P64::new(0x108936aa5f9c1495, 0x000b42301cd99b49), P64::new(0x0b60f606f104c9eb, 0x000b3f385dd77e4e), P64::new(0xc663dfe8263b302f, 0x000b394d8ef8f0f6), P64::new(0xc91a280b9110b15b, 0x000b375601507c14), P64::new(0x0904287118d10969, 0x000b3463f76be376), P64::new(0x160d36a5d31bf553, 0x000b3368f6c4a07c), P64::new(0xe84f5fda3c67ad21, 0x000b3078fc1c25f0), P64::new(0xbd85701f72d4b6ed, 0x000b2e84854e93e5), P64::new(0x4c50cf5924dee1c3, 0x000b2b971aa909a4), P64::new(0x2455aaf1633bb6e5, 0x000b2a9da39d6bc8), P64::new(0xd775b39f549b8ac7, 0x000b25c0dc29a0fc), P64::new(0x87fcdda7a252cb49, 0x000b24c8698449a7), P64::new(0x53df2e3bd254a739, 0x000b1d0ae579aefe), P64::new(0x8915e69623a5f7ef, 0x000b1a2698ea2f9e), P64::new(0x1ef24c80742dd08b, 0x000b108dc4186078), P64::new(0xb4d87aaa6fb1e897, 0x000b0ea463b00212), P64::new(0x788573e8b92dbbfb, 0x000b08ec37007962), P64::new(0x02527b137b0878c1, 0x000b024778cc023c), P64::new(0x1870a7c8dee9f4f5, 0x000af515df36a88e), P64::new(0x39b99e40910a224b, 0x000af24635f6561e), P64::new(0x45821c0abd4df247, 0x000ae8f1b92baeaf), P64::new(0x10fe2b2f50e02fb3, 0x000ae715eee11f8e), P64::new(0x5762b90c043f0345, 0x000adec0b0a3bb36), P64::new(0x82a67b9193b27bbd, 0x000adb10aa4c956f), P64::new(0xa6e914e28ec37693, 0x000ad84e49752245), P64::new(0x835d9a4facaf445f, 0x000ad6782597f0c2), P64::new(0x48def8175884f82d, 0x000ad3b81a0d72fe), P64::new(0xae900e2d7c9a6f7b, 0x000acd52beced79e), P64::new(0x1c08431bdd18be89, 0x000aca9755063254), P64::new(0xb370a66d684fd83f, 0x000ac7dd4cafb12a), P64::new(0xb4be33e18f93b279, 0x000ac354f80dca44), P64::new(0x310c50872a7dd5e3, 0x000ac26d5c2b8ad2), P64::new(0x447ab1281276697d, 0x000abde997dabd3d), P64::new(0xc2f122216b2a6c21, 0x000ab883aa1100a0), P64::new(0xab99c8b5ae1c3059, 0x000ab4ed637f5a0b), P64::new(0xb78e17a2227d593b, 0x000ab074e9febf52), P64::new(0xabf97d03f7269c5d, 0x000aaf90778c2039), P64::new(0x867aefc9fdbfe7ff, 0x000aab1c7684f034), P64::new(0xf7f7ad182e47d5b7, 0x000aa78f20ebbb3e), P64::new(0x50dff95a9847721b, 0x000aa23f8dafd4cc), P64::new(0xe4cb8a0e83cb6a35, 0x000a9dd69cad5934), P64::new(0x8da72ecdf9247a1d, 0x000a935004a07302), P64::new(0xc5b04bfc87f31d87, 0x000a9270690f3d14), P64::new(0xe2dcf622ea2b00f3, 0x000a90b1a0aa5d30), P64::new(0xb9ce9f2e4972f46b, 0x000a8d35c9d731e9), P64::new(0x1ed785c911bf59f9, 0x000a8a9a6a51f16c), P64::new(0x4ddb8a4eed70e085, 0x000a88de370f596b), P64::new(0x81e93b4df68c24fd, 0x000a856786adae36), P64::new(0xee0d0812afcd8357, 0x000a7da4c77d3161), P64::new(0xf62e3ba72268a891, 0x000a7959f863d4a1), P64::new(0x3194d367c8154147, 0x000a76c85e80c195), P64::new(0xd096ede8e30c20d5, 0x000a743806dc44c4), P64::new(0xd68624d27b87a77f, 0x000a735d866dfa0a), P64::new(0xb728fcdc11c8204d, 0x000a70cedb02531e), P64::new(0x9d6b6038077e066f, 0x000a6c8e842c770f), P64::new(0xaa732d7a4a360d93, 0x000a67791215dd74), P64::new(0x36af98a423972db5, 0x000a66a0a51d363d), P64::new(0xc31d00da12940f17, 0x000a626893011861), P64::new(0xed85352107410b25, 0x000a5fe22c55c089), P64::new(0x829c85ee6db8567b, 0x000a5d5cffb77275), P64::new(0xef60258952cc6d89, 0x000a5ad90c4186e5), P64::new(0xcf28c2e0da787741, 0x000a578057e7c2eb), P64::new(0x57567d8494af28f7, 0x000a54ff3bb10e91), P64::new(0x2c7c98518f174031, 0x000a50d5683edc94), P64::new(0xb28b363a36825ae7, 0x000a4e57854b3df4), P64::new(0xed1ffeb64f9ae769, 0x000a4d8328c4b800), P64::new(0xcbbb0115e9b9a31f, 0x000a4b06e01d97b3), P64::new(0x8d3c5fecb7f9e4ed, 0x000a488bca2c4449), P64::new(0x816271698195cfc3, 0x000a4611e6132ed5), P64::new(0x9ac939d1c2b1d35d, 0x000a41f40f39e646), P64::new(0xdd9fb7017b0ec455, 0x000a3eab5c3e44e9), P64::new(0xc94cab1e57276e3d, 0x000a34ddd50561e0), P64::new(0x8b8806b117c79913, 0x000a326d60e94186), P64::new(0xa9e63292a3269fd1, 0x000a2985a81ce614), P64::new(0x76da5710f1e989fb, 0x000a28b72e26f82e), P64::new(0xdded6688d83a918d, 0x000a217aa3479693), P64::new(0x4e446b6a305428f9, 0x000a1fe05c62df4b), P64::new(0x4ddaca7a3696cfb1, 0x000a1cad538aebf9), P64::new(0x7eadc4eb87f26ed3, 0x000a18b05f490083), P64::new(0x76c13a0ff04c00c9, 0x000a0ccc4c28fc31), P64::new(0xcbf800504d2a2681, 0x000a09a544d01ffe), P64::new(0x0731dada6c4fec9b, 0x000a0294aa53e9a2), P64::new(0xbcb52a664e63f627, 0x000a01041a6aaed5), P64::new(0xf1f9abda071c2aa9, 0x000a003c01680870), P64::new(0xf262ffa620ffe20b, 0x0009fc5558a971c8), P64::new(0x93774a3d57199a99, 0x0009f9ff9c3c03e5), P64::new(0xfb3541cd467a1903, 0x0009f9389b864ab9), P64::new(0x6828cab6b4fe8f51, 0x0009f6e4534bdca8), P64::new(0x12ac03e3d624cc9d, 0x0009f557687235c2), P64::new(0x6363bd1e9bb7d7f7, 0x0009ee633c0391ab), P64::new(0x334cfd676a484d2f, 0x0009eb4f28e0bb39), P64::new(0xd511acd86f143a53, 0x0009e6b49e92e4bb), P64::new(0x73fc2490e0062be5, 0x0009dfd4ccbd0045), P64::new(0x10780dda36b78b55, 0x0009d9c0828536c1), P64::new(0xabf601274064e0ab, 0x0009d77ad449f777), P64::new(0x3ef3e4ca27e4a2cd, 0x0009d6b92b28ee48), P64::new(0x9216a26e690a16f1, 0x0009d231a476ed51), P64::new(0xbae4849e6034bda7, 0x0009cfef711bf120), P64::new(0xf943a0520e01e9e1, 0x0009cc2e1448b765), P64::new(0x7c89958f48f6658b, 0x0009cb6e26cbc64d), P64::new(0xe67128750e0545a5, 0x0009c7b03b4a9c67), P64::new(0xc6c9e1d414516ccf, 0x0009c6f0fd980ab1), P64::new(0x805307f996e9e81d, 0x0009c4b3f3a30c3f), P64::new(0x3eddd2cff46ad5bf, 0x0009c0fb29436687), P64::new(0x35582c1aeb5aae85, 0x0009bbca025b7aec), P64::new(0x4973c88573ef6eb1, 0x0009ba4f4421e52c), P64::new(0x3063f627c1e715d9, 0x0009b1783809ff03), P64::new(0x711ad679a8dcc243, 0x0009b0bc5b4d2eac), P64::new(0x51c224a17a3db4b3, 0x0009aae172fd8b9c), P64::new(0x612325ca50ddaed5, 0x0009aa26954607ed), P64::new(0x9929a7b6b7958b37, 0x0009a681e758a022), P64::new(0xa78d222e5a857bb9, 0x0009a5c7b284942e), P64::new(0x3ad0ffe3198d139b, 0x0009a2264ecc5558), P64::new(0x08b4659ac547ed17, 0x00099aebb39be56f), P64::new(0x1752e8904aff1003, 0x0009997ae1a9faac), P64::new(0x60745c37ee4e5925, 0x000998c2a22b6900), P64::new(0x29e2da1f6557ee51, 0x000997527603f8a8), P64::new(0x80d78c24ac49cb89, 0x00099473685e4d50), P64::new(0xc56c3b495c8d1f79, 0x00098eba72512a13), P64::new(0xcf5bdf9f5088ac2f, 0x00098c96d8dee9e1), P64::new(0x8a44800e4fae4e7d, 0x00098a743453554e), P64::new(0xdd76384277e578e7, 0x000989be33c9e6bd), P64::new(0x20b1562d2703facb, 0x0009857c692e9a59), P64::new(0xef56caf96e9d8e3b, 0x00097fd540c05c9e), P64::new(0xf54061416aede033, 0x00097d04302ed944), P64::new(0xe0bc78c21a26e4ff, 0x00097b9c48289935), P64::new(0x0524f92731a179cd, 0x0009798133ece717), P64::new(0x5d3b4ad7deafec8b, 0x00096f07c683689e), P64::new(0x508828f744da88ad, 0x00096e55d6393fc5), P64::new(0x6e82014031710bcf, 0x00096addad861696), P64::new(0xadf3b77a22595dd1, 0x00096a2c5a2cf0cf), P64::new(0x0d8f0c03f7ea8a87, 0x00096818fc825eba), P64::new(0x2c49e3483c3a05f3, 0x000966b74027f48a), P64::new(0xccecbc98c91274c1, 0x000964a56850b8ed), P64::new(0x273a08941bb71e77, 0x000962947990eb36), P64::new(0xdead5a1e3f341baf, 0x00095fd4a4c885e0), P64::new(0x83eee092593309fd, 0x00095dc5d3954fde), P64::new(0x4af5f1bd3ae87ce9, 0x00095c671ddfe516), P64::new(0x4ca85ad2301c9e6d, 0x0009584d6340ddf1), P64::new(0x1b19592cd31a3943, 0x00095641de84afcc), P64::new(0x3e7aa05e6dcd81bb, 0x000953893c386521), P64::new(0x86336cecb02ba47f, 0x00094f7740d87794), P64::new(0xa96b30d0c8a44b2b, 0x00094e1cb70c9ce0), P64::new(0xb7c63fa0cfca0571, 0x00094962ecbcc7ce), P64::new(0x8eaf59b405a642b5, 0x00094559c69059cf), P64::new(0xdf29e9cbb536dc17, 0x000941ff7e640716), P64::new(0xed14132c82c1d43f, 0x000939fd7a24b099), P64::new(0xaf68778e34caab0d, 0x000937ff22c014bd), P64::new(0xa4f04a3368941d31, 0x000934050872c09e), P64::new(0xe9960969357c07e7, 0x00093209446d56f6), P64::new(0xeb47b62b7360b469, 0x0009316033b5bd22), P64::new(0x64c653d779ae730f, 0x00092a22b9a79374), P64::new(0x479702d3319915c7, 0x000927838edba206), P64::new(0xef3c3eebc6803239, 0x000921a2e7112833), P64::new(0x93807b1a2e3c0e1b, 0x00091e623d5660d0), P64::new(0x8167e33e3f478029, 0x00091c6fc0cab8b6), P64::new(0x60cb76e38c339397, 0x000917e7d88028eb), P64::new(0xae34788ffe4bc283, 0x0009169d455585cd), P64::new(0x4b6246a0c6c093a5, 0x000915f81ef2d529), P64::new(0x872e594b12b03efb, 0x0009140938595d3a), P64::new(0xbc0ae83ce9045b15, 0x000910d2360a450e), P64::new(0x0ad30a3917e0968d, 0x00090e417104eabd), P64::new(0x124ef5a4e1c7cd63, 0x00090c55d0fdea28), P64::new(0x5b98fe0e9fe17aaf, 0x00090b0e84c04f20), P64::new(0x414306cfe45400fd, 0x000909243fac6b70), P64::new(0xa06d1b4fd391e8bb, 0x0008ff9d0440d137), P64::new(0x11939803a60c2381, 0x0008fb3192789d73), P64::new(0x668c11cc37ea6b23, 0x0008f80c0d5031e3), P64::new(0x83f9b2089dc10645, 0x0008f76b3664f164), P64::new(0x65dc8ae47af277a9, 0x0008f3a80550abc3), P64::new(0x6e2368b9c685770b, 0x0008f087c50e00c4), P64::new(0x3ea137aeba5a6b2d, 0x0008efe7fb408cc2), P64::new(0x735f57adca48f19d, 0x0008eaecce5c4fd7), P64::new(0x69a8de0ba1b18107, 0x0008ea4dccaaec0b), P64::new(0x8fb84bdf5822bd79, 0x0008e4ba9fbc2ff0), P64::new(0xb8fab3b748562721, 0x0008dd5688a3b7d6), P64::new(0xa6c658ea10a65c3b, 0x0008d7d3821fd94f), P64::new(0xe56381f33ab5e549, 0x0008d5feb03c31d7), P64::new(0xe3c224da14988139, 0x0008d12033cc9d30), P64::new(0x438c253e6d99f513, 0x0008cbac4dec6a82), P64::new(0xc1b99f8841a3a6e1, 0x0008c9dc80ab604b), P64::new(0x63fa18c79c54fa8b, 0x0008c942115dcc96), P64::new(0xe7f6f609619d0d1d, 0x0008c3d7df67b539), P64::new(0x7b39ef3b70afc109, 0x0008c2a4bc35cb3b), P64::new(0x73922c61ca7452bf, 0x0008c0d8a4f1f264), P64::new(0x28d96828332372c1, 0x0008c03f71cbf906), P64::new(0x6b6e92968c4e8463, 0x0008bd42abd9a107), P64::new(0x571861f084962edb, 0x0008bae051d7f6ff), P64::new(0xd935c64f140f1ef5, 0x0008b7e735068135), P64::new(0x96459f8fd72a4c4b, 0x0008b61f82c5fb08), P64::new(0x410ba9a2a18242d9, 0x0008b4588a74a05a), P64::new(0xcf90979f89870391, 0x0008b1fb0a7ed403), P64::new(0x10f94ff26bc00add, 0x0008b0ccc5d8f5c8), P64::new(0xa6619fbb9da139b3, 0x0008af07f8ac5146), P64::new(0x765a23334efb03d5, 0x0008ae71328ffd49), P64::new(0x6f2f613b5e631837, 0x0008ab8086624822), P64::new(0x666b99bfbcd368b9, 0x0008aaea3ab5ae89), P64::new(0x922b78eb01ed45bd, 0x0008a7661f7020fe), P64::new(0x7079a199c31de6a9, 0x0008a63ab88aa8dd), P64::new(0xa181abcda167be5f, 0x0008a47a35d020f3), P64::new(0x2f6dbbcab3a9822d, 0x0008a2ba68a3cebf), P64::new(0xc5a83ff0e43eba17, 0x0008a2254c852497), P64::new(0x28c68613dda7d97b, 0x00089ea849898bb3), P64::new(0x5cf33ed49efa5007, 0x00089d7f3e285109), P64::new(0x9125fdead661590d, 0x000899720af36739), P64::new(0xaee67f478c7325e7, 0x00089442160d11dc), P64::new(0x735b1274a0e89653, 0x0008931bd5875a22), P64::new(0x733b56eae1a4e621, 0x000891630877aedf), P64::new(0x1944ffb316ffe65d, 0x00088baaad83e38f), P64::new(0xf26bc3cfd2a01449, 0x00088a86b9090aa4), P64::new(0xb5827ba68b83e201, 0x0008883fb99bf244), P64::new(0xac139507e48eefb7, 0x0008868b45e727ee), P64::new(0xeb7676b25834fda3, 0x00088568aef30d47), P64::new(0xad898f4763da5c1b, 0x0008832468f0bcdd), P64::new(0xea906f224398f9a7, 0x00088202b9a4df76), P64::new(0xa8aff3caca28cdad, 0x00087e0f31872e9b), P64::new(0x46c53aa36b19b083, 0x00087c5ecd731f42), P64::new(0x9ada32b09603e8cf, 0x00087b3eea3bb388), P64::new(0xd31f842ef5d8e915, 0x00087751a6c67d78), P64::new(0x6124af44730a33f9, 0x000873f6e2f9d34a), P64::new(0x828ec4c2b6e64a85, 0x000872d938dcfc01), P64::new(0x3d6f49df999638af, 0x0008724a80151dba), P64::new(0x7641460a0ea89b65, 0x000869f677f6cc1a), P64::new(0x97703f98fb7fe291, 0x000868db701df58d), P64::new(0xd343c209e3e6b7b9, 0x0008623f563a7d6d), P64::new(0x4e5fc01f6a41406f, 0x00086099ef0c8886), P64::new(0xb78a05b08aa4bcbd, 0x00085ef52d38fe87), P64::new(0x3434a14919d34561, 0x00085bad981c7847), P64::new(0xccead7dee120f525, 0x0008586893de7cfc), P64::new(0xe1375a2bccd87673, 0x0008549b491e9efe), P64::new(0xf727d51420a57141, 0x000852fb3859bea4), P64::new(0x2c3b68cfbcebb00d, 0x000851e631fc08f8), P64::new(0xda91e2f3e17542f7, 0x0008515bc9cde5f1), P64::new(0xb55f6100ae95d6e3, 0x000850472f6185b3), P64::new(0x6a0c608e0bbaa975, 0x00084b6defbc166b), P64::new(0xac5f2fc151c016cb, 0x000849d17159854b), P64::new(0xb1e5af8146e4d00f, 0x0008469a54a20645), P64::new(0x6e283d3b112602c7, 0x00084476f9401ade), P64::new(0xf9a48bcb76c96e55, 0x000842dd2e2dc25d), P64::new(0xa776780ca4c0e101, 0x000841cc543f58cb), P64::new(0x8d40a2d47d99c7c5, 0x00083e9b6c3df688), P64::new(0x4ed9d8a7aedcefef, 0x00083e1382f22ff9), P64::new(0x55c5cf9586072313, 0x00083ae57a327933), P64::new(0x62c640e386ef1f09, 0x000832fd15e00939), P64::new(0xdb876e7feb8b02f9, 0x00082ecb9c6669ac), P64::new(0x5b85ac1558bdf263, 0x00082e45ba6652c4), P64::new(0xb2b13930c2a889b1, 0x00082cb47b00abaa), P64::new(0xdf53c897124f8c57, 0x000826fa5d0ce5aa), P64::new(0x68a69390fdce78dd, 0x000823598cfc6865), P64::new(0x5a1e8f0261e6e7b3, 0x000821cc79da73f1), P64::new(0xcce38a9ccaab014d, 0x00081f37ff3d12c0), P64::new(0xb0cd4811fe6a8171, 0x00081c21947b0acd), P64::new(0x911c24573e445027, 0x00081a97404af5f7), P64::new(0x9e86401e61cac4a9, 0x00081a13f02d110e), P64::new(0xfd2731405f265eb5, 0x0008190d81c9877b), P64::new(0x3f4c00205c05b02d, 0x000817016c0b3ffd), P64::new(0xe92e3d0a829a974f, 0x00081473c50ac33e), P64::new(0xdec216e5aa47169d, 0x000812ec59f2d11a), P64::new(0xa0397bf3448bcd73, 0x0008116582e237c8), P64::new(0x9ecf538d7efa905b, 0x00080b4fe85ec545), P64::new(0xb1037b5f84886421, 0x000807c7894d029a), ]; //////////////////// Tables for deterministic Miller-rabin bases of 32/64-bit integers based on hashing //////////////////// /* * Forišek, Michal, and Jakub Jancina. "Fast Primality Testing for Integers That Fit into a Machine Word." (2015). * http://ceur-ws.org/Vol-1326/020-Forisek.pdf * https://people.ksp.sk/~misof/primes/ */ #[cfg(feature = "big-table")] pub const MILLER_RABIN_BASE32: [u16; 256] = [ 0x3ce7, 0x07e2, 0x00a6, 0x1d05, 0x1f80, 0x3ead, 0x2907, 0x112f, 0x079d, 0x050f, 0x0ad8, 0x0e24, 0x0230, 0x0c38, 0x145c, 0x0a61, 0x08fc, 0x07e5, 0x122c, 0x05bf, 0x2478, 0x0fb2, 0x095e, 0x4fee, 0x2825, 0x1f5c, 0x08a5, 0x184b, 0x026c, 0x0eb3, 0x12f4, 0x1394, 0x0c71, 0x0535, 0x1853, 0x14b2, 0x0432, 0x0957, 0x13f9, 0x1b95, 0x0323, 0x04f5, 0x0f23, 0x01a6, 0x02ef, 0x0244, 0x1279, 0x27ff, 0x02ea, 0x0b87, 0x022c, 0x089e, 0x0ec2, 0x01e1, 0x05f2, 0x0d94, 0x01e1, 0x09b7, 0x0cc2, 0x1601, 0x01e8, 0x0d2d, 0x1929, 0x0d10, 0x0011, 0x3b01, 0x05d2, 0x103a, 0x07f4, 0x075a, 0x0715, 0x01d3, 0x0ceb, 0x36da, 0x18e3, 0x0292, 0x03ed, 0x0387, 0x02e1, 0x075f, 0x1d17, 0x0760, 0x0b20, 0x06f8, 0x1d87, 0x0d48, 0x03b7, 0x3691, 0x10d0, 0x00b1, 0x0029, 0x4da3, 0x0c26, 0x33a5, 0x2216, 0x023b, 0x1b83, 0x1b1f, 0x04af, 0x0160, 0x1923, 0x00a5, 0x0491, 0x0cf3, 0x03d2, 0x00e9, 0x0bbb, 0x0a02, 0x0bb2, 0x295b, 0x272e, 0x0949, 0x076e, 0x14ea, 0x115f, 0x0613, 0x0107, 0x6993, 0x08eb, 0x0131, 0x029d, 0x0778, 0x0259, 0x182a, 0x01ad, 0x078a, 0x3a19, 0x06f8, 0x067d, 0x020c, 0x0df9, 0x00ec, 0x0938, 0x1802, 0x0b22, 0xd955, 0x06d9, 0x1052, 0x2112, 0x00de, 0x0a13, 0x0ab7, 0x07ef, 0x08b2, 0x08e4, 0x0176, 0x0854, 0x032d, 0x5cec, 0x064a, 0x1146, 0x1427, 0x06bd, 0x0e0d, 0x0d26, 0x3800, 0x0243, 0x00a5, 0x055f, 0x2722, 0x3148, 0x2658, 0x055b, 0x0218, 0x074b, 0x2a70, 0x0359, 0x089e, 0x169c, 0x01b2, 0x1f95, 0x44d2, 0x02d7, 0x0e37, 0x063b, 0x1350, 0x0851, 0x07ed, 0x2003, 0x2098, 0x1858, 0x23df, 0x1fbe, 0x074e, 0x0ce0, 0x1d1f, 0x22f3, 0x61b9, 0x021d, 0x4aab, 0x0170, 0x0236, 0x162a, 0x019b, 0x020a, 0x0403, 0x2017, 0x0802, 0x1990, 0x2741, 0x0266, 0x0306, 0x091d, 0x0bbf, 0x8981, 0x1262, 0x0480, 0x06f9, 0x0404, 0x0604, 0x0e9f, 0x01ed, 0x117a, 0x09d9, 0x68dd, 0x20a2, 0x0360, 0x49e3, 0x1559, 0x098f, 0x002a, 0x119f, 0x067c, 0x00a6, 0x04e1, 0x1873, 0x09f9, 0x0130, 0x0110, 0x1c76, 0x0049, 0x199a, 0x0383, 0x0b00, 0x144d, 0x3412, 0x1b8e, 0x0b02, 0x0c7f, 0x032b, 0x039a, 0x015e, 0x1d5a, 0x1164, 0x0d79, 0x0a67, 0x1264, 0x01a2, 0x0655, 0x0493, 0x0d8f, 0x0058, 0x2c51, 0x019c, 0x0617, 0x00c2, ]; #[cfg(feature = "big-table")] pub const MILLER_RABIN_BASE64: [u32; 16384] = [ 0x24b047, 0x2e32a1, 0x38b06b, 0x31d047, 0x1850d3, 0x595115, 0x17b04f, 0x1cf1b1, 0x2c502b, 0x55732b, 0x14b137, 0x1f315b, 0x047005, 0x119005, 0x1910df, 0x2ef125, 0x0a3029, 0x28708b, 0x1250c7, 0x1a5005, 0x3f11eb, 0x449347, 0x11901d, 0x28d02f, 0x24b1a5, 0x0a3053, 0x03d029, 0x2c5017, 0x13304f, 0x13d10f, 0x0c703d, 0x03b005, 0x0f10c5, 0x1c11b7, 0x10d0ad, 0x02501d, 0x21d101, 0x32917b, 0x33b0e5, 0x16f151, 0x17f0fb, 0x28d0a3, 0x2511fd, 0x2ab2a1, 0x151005, 0x067043, 0x239017, 0x1a3115, 0x10d095, 0x2a1257, 0x125047, 0x33d03b, 0x0f1011, 0x13302f, 0x2cf23b, 0x1e7049, 0x19117f, 0x1a317f, 0x167049, 0x043029, 0x4cd259, 0x2951bb, 0x0b5065, 0x2bd25f, 0x04f03b, 0x101005, 0x16f119, 0x10f0c5, 0x3370e5, 0x0d3059, 0x4eb36d, 0x2b303d, 0x48118d, 0x1cf049, 0x35b0a7, 0x0df04f, 0x28d025, 0x1370e9, 0x161005, 0x061005, 0x28715d, 0x071059, 0x26b02f, 0x0c7043, 0x119011, 0x04901d, 0x199011, 0x1eb095, 0x137005, 0x22d10f, 0x047005, 0x41b35b, 0x17b095, 0x2cf0b5, 0x139089, 0x281025, 0x05301f, 0x0fb0b3, 0x15d125, 0x035005, 0x3f12d7, 0x10f011, 0x3012e7, 0x1d3115, 0x04300d, 0x32b0ad, 0x1e70fb, 0x175095, 0x0e90e3, 0x0ef07f, 0x06d01f, 0x1cf03d, 0x0f10bf, 0x191005, 0x3732ef, 0x0b308b, 0x0ef09d, 0x32920b, 0x13d047, 0x26b1b1, 0x19103b, 0x10102b, 0x33714b, 0x3e5125, 0x161035, 0x0bf059, 0x0ef067, 0x1250b3, 0x17502b, 0x1cd1c9, 0x1fd005, 0x097071, 0x17b0a7, 0x07f007, 0x1010c1, 0x0f1005, 0x17507f, 0x101007, 0x185017, 0x0fb0e3, 0x0c700d, 0x0df00d, 0x11b047, 0x161029, 0x27715d, 0x125107, 0x0e3067, 0x1c104f, 0x191059, 0x1cd007, 0x0ef07f, 0x059049, 0x07f06d, 0x3f1295, 0x47f16f, 0x359065, 0x35f259, 0x22d1cf, 0x0c1065, 0x1a517f, 0x3351cf, 0x3011cf, 0x14b035, 0x1f3035, 0x3df01d, 0x08b083, 0x1cd15b, 0x097083, 0x043035, 0x0fb089, 0x0a302f, 0x04301f, 0x18d0fb, 0x2f50e5, 0x25723b, 0x035029, 0x061017, 0x13d035, 0x0c5003, 0x10f047, 0x11906d, 0x191049, 0x3fd1fd, 0x065025, 0x1fd16f, 0x0fb0c1, 0x0f1095, 0x125089, 0x08b035, 0x06b03b, 0x1cf08b, 0x2ab175, 0x09700b, 0x0df0bf, 0x22d003, 0x1390ad, 0x35b0c5, 0x2dd101, 0x1cf005, 0x1cf0fb, 0x10d0a3, 0x3df07f, 0x1d30e3, 0x373185, 0x2571f7, 0x1250d3, 0x04903d, 0x28121d, 0x115013, 0x13703d, 0x17f101, 0x31d283, 0x35f33b, 0x119053, 0x355083, 0x3551c9, 0x0ef02b, 0x04900b, 0x2511e7, 0x0d30c5, 0x1b7067, 0x23b0f1, 0x04f017, 0x1f71b7, 0x685047, 0x1b1065, 0x0a3049, 0x1c11bb, 0x0ef005, 0x0a300d, 0x10d06d, 0x125029, 0x3b335f, 0x2231fd, 0x21d0f1, 0x29315b, 0x161125, 0x185035, 0x337071, 0x0a706b, 0x0a7029, 0x0c5025, 0x22d175, 0x0b3059, 0x161071, 0x097017, 0x1c107f, 0x28306d, 0x4071bb, 0x4191c1, 0x06b02b, 0x223137, 0x25103d, 0x071035, 0x09703b, 0x38b02f, 0x06b01f, 0x10703b, 0x0e5083, 0x0f1067, 0x0bf00d, 0x4bd283, 0x185071, 0x2331f3, 0x24b005, 0x19902f, 0x10d071, 0x3e5161, 0x0ad035, 0x2390bf, 0x12503b, 0x13300d, 0x0ef0b5, 0x043035, 0x1a5133, 0x2dd1a5, 0x13710f, 0x1f311b, 0x19900d, 0x25911b, 0x10d01f, 0x41b03d, 0x1af0bf, 0x2810f1, 0x1eb007, 0x1850d3, 0x0c100d, 0x0fb065, 0x0b5035, 0x07106d, 0x24b0df, 0x1fd071, 0x55135b, 0x0c109d, 0x10f0d3, 0x1250c7, 0x3b9071, 0x0c5043, 0x3552b3, 0x13d0ad, 0x22301d, 0x0c106b, 0x0b503b, 0x17507f, 0x44f0b3, 0x45542d, 0x209043, 0x1a500d, 0x19918d, 0x38f25f, 0x2b3119, 0x26503d, 0x1150b5, 0x1df1cd, 0x13d04f, 0x2e302f, 0x43f2dd, 0x26b1bb, 0x3fb1e7, 0x3f124b, 0x0fb0c5, 0x167137, 0x329133, 0x257013, 0x095053, 0x1cd061, 0x08907f, 0x26b259, 0x115017, 0x21d053, 0x0c1011, 0x13d011, 0x3d715b, 0x0bf06d, 0x1670fb, 0x23b0d3, 0x08b083, 0x0ad00b, 0x1eb167, 0x0a306d, 0x33d0f1, 0x1df0fb, 0x0c101f, 0x17f025, 0x0c70b5, 0x269067, 0x2dd1b7, 0x20b097, 0x18d0ad, 0x0f1029, 0x295071, 0x0c1005, 0x26b095, 0x071035, 0x17f0b5, 0x25f06b, 0x0b5083, 0x49d17b, 0x0e301d, 0x13311b, 0x2a1287, 0x089071, 0x125061, 0x065017, 0x17b01f, 0x25f067, 0x55d0c7, 0x1b71af, 0x33d191, 0x0e302b, 0x14b0e5, 0x0a7053, 0x04703b, 0x445185, 0x0a3043, 0x05901f, 0x44f0fb, 0x0d30c7, 0x0fb0c7, 0x1af025, 0x3591fd, 0x0fb013, 0x49314b, 0x15103b, 0x15b14b, 0x2cf185, 0x10f01d, 0x101011, 0x1a5191, 0x2330b5, 0x3a900b, 0x0f1025, 0x29317b, 0x025007, 0x1bb067, 0x2bd295, 0x0ad047, 0x0c70a7, 0x0ef065, 0x125065, 0x293119, 0x2e7071, 0x21d101, 0x3471eb, 0x3010c7, 0x33704f, 0x03d02b, 0x3fb3e5, 0x50315d, 0x3d721d, 0x1750c1, 0x09d02b, 0x11904f, 0x28126b, 0x47f1f7, 0x359167, 0x10f0b3, 0x2c5049, 0x02900d, 0x1750f1, 0x017011, 0x8412cf, 0x0df03b, 0x025017, 0x18d0b3, 0x1bb0f1, 0x28100d, 0x05300d, 0x03b02b, 0x28109d, 0x21d0e5, 0x26b0a7, 0x01f00d, 0x277071, 0x0fb09d, 0x5171b1, 0x15b07f, 0x089035, 0x2091e7, 0x1510e5, 0x101025, 0x5e7125, 0x3df26b, 0x26b1cf, 0x0d306d, 0x0a3049, 0x23b089, 0x3b3119, 0x233095, 0x1a3053, 0x25710d, 0x0c70b3, 0x10f0a3, 0x35532b, 0x295101, 0x2ef1f7, 0x09703d, 0x17b067, 0x26504f, 0x1bb191, 0x64d61f, 0x10d09d, 0x277259, 0x4ff33b, 0x16f0df, 0x03502f, 0x125095, 0x0a3003, 0x04703d, 0x25907f, 0x56500d, 0x0e307f, 0x2091df, 0x06d017, 0x2dd2c5, 0x15101f, 0x25f02b, 0x1910ad, 0x053029, 0x2bd137, 0x24b1b7, 0x18510d, 0x20b161, 0x1e71c1, 0x443329, 0x1cd0e9, 0x3fb337, 0x1eb0d3, 0x1eb067, 0x0df095, 0x1af07f, 0x34702b, 0x0fb0a3, 0x10d043, 0x4cd481, 0x1fd1df, 0x1bb0b5, 0x287283, 0x16f0b5, 0x35f0c1, 0x0c709d, 0x0c706b, 0x33d2f5, 0x03d00d, 0x04f011, 0x2090e3, 0x0a3005, 0x13d029, 0x08b003, 0x2a52a1, 0x0e90ad, 0x281139, 0x22d191, 0x37735f, 0x0b3047, 0x2f9151, 0x10f101, 0x035017, 0x0df0d3, 0x5273b9, 0x0d3029, 0x14b115, 0x26b1fd, 0x281239, 0x22d06d, 0x1af0a3, 0x24b10d, 0x1bb107, 0x3472d7, 0x10100b, 0x2770ef, 0x1150f1, 0x06704f, 0x0e30df, 0x115013, 0x283151, 0x043025, 0x02b00d, 0x2bd259, 0x24b0ad, 0x05304f, 0x14b047, 0x17b0df, 0x1850b5, 0x0d3043, 0x0c1043, 0x239107, 0x125035, 0x0bf0a7, 0x1250bf, 0x0a701d, 0x1eb0b3, 0x1370d3, 0x10f0bf, 0x061005, 0x139125, 0x15b029, 0x13906b, 0x0a3089, 0x13d00d, 0x19906b, 0x4cf065, 0x11900d, 0x0bf043, 0x1a501d, 0x07101d, 0x2cf25f, 0x10100d, 0x28d0e3, 0x0ef03b, 0x0a703b, 0x241089, 0x1b1025, 0x46335b, 0x3c72a1, 0x371089, 0x623397, 0x58f125, 0x2590ef, 0x191043, 0x0e906d, 0x0c70b5, 0x16f065, 0x08b089, 0x2931f3, 0x01300d, 0x11b0c7, 0x40708b, 0x1c10d3, 0x42d1df, 0x137017, 0x0d301d, 0x2a510d, 0x3d102f, 0x0e902b, 0x101089, 0x1af00b, 0x115005, 0x283101, 0x2dd02b, 0x29307f, 0x06b00d, 0x14b115, 0x16706d, 0x1c1175, 0x2770d3, 0x1d301f, 0x18d06d, 0x1a5191, 0x2f5043, 0x35f295, 0x0e30b3, 0x11b067, 0x067005, 0x26b0a7, 0x1e70ad, 0x2230df, 0x15b10d, 0x09d071, 0x067043, 0x1cf06d, 0x09d053, 0x16f03b, 0x2230c1, 0x25f0fb, 0x14b053, 0x17f15b, 0x16f097, 0x1cf083, 0x13906d, 0x1a30b5, 0x2ef1cf, 0x23b17f, 0x0fb00d, 0x1f30fb, 0x19117f, 0x09706d, 0x1cf151, 0x277185, 0x10108b, 0x17b03d, 0x09d061, 0x1e70ad, 0x07f005, 0x209139, 0x1b717f, 0x23308b, 0x1df18d, 0x17f095, 0x1bb011, 0x515301, 0x1510ef, 0x48131d, 0x16f09d, 0x33d259, 0x1990df, 0x5114c1, 0x0e506d, 0x0d3053, 0x265061, 0x1a30f1, 0x139049, 0x287097, 0x137101, 0x2a100b, 0x1a5005, 0x0c7083, 0x1af125, 0x1b1025, 0x35f167, 0x24b095, 0x3732a5, 0x1cf071, 0x11b065, 0x3470fb, 0x20b04f, 0x335265, 0x17b0b5, 0x51501f, 0x3a9161, 0x0df0c7, 0x3b331d, 0x10f0c1, 0x16106b, 0x3df281, 0x1e70fb, 0x19908b, 0x0a309d, 0x23901d, 0x2a1101, 0x0c70b5, 0x0bf029, 0x16101d, 0x10d061, 0x06500d, 0x161115, 0x39721d, 0x409305, 0x0df0a3, 0x21d06b, 0x28100d, 0x2771df, 0x1bb0b3, 0x1a314b, 0x233185, 0x137011, 0x241137, 0x3a12d7, 0x1010fb, 0x40f20b, 0x22d15d, 0x061011, 0x0d306d, 0x283139, 0x167119, 0x23b18d, 0x17b01d, 0x2bd295, 0x12500d, 0x43f233, 0x0df09d, 0x0c1067, 0x1f303d, 0x0fb053, 0x10d083, 0x33d06b, 0x3292cf, 0x4a940f, 0x199083, 0x0b5049, 0x15d09d, 0x13d01f, 0x08303d, 0x1c1017, 0x17f095, 0x06700d, 0x1cd15b, 0x2ab1a5, 0x0bf0b3, 0x09503d, 0x427017, 0x1d30ef, 0x25702b, 0x0fb04f, 0x0e507f, 0x1150e5, 0x061005, 0x19902f, 0x18d10d, 0x2230e9, 0x09501d, 0x1cd03b, 0x41936d, 0x199013, 0x17f125, 0x1a50e9, 0x15b0c5, 0x1b702f, 0x04703b, 0x061059, 0x061059, 0x2830fb, 0x1bb107, 0x31309d, 0x0c50a3, 0x2e3277, 0x1b10fb, 0x305029, 0x46340f, 0x0e9043, 0x2f900d, 0x1250e3, 0x2931f7, 0x10d025, 0x13d0ef, 0x06b01f, 0x32b24b, 0x185119, 0x0df049, 0x19907f, 0x3d7151, 0x1e714b, 0x0c1017, 0x19918d, 0x1af139, 0x125059, 0x20911b, 0x0b5067, 0x1fd0a3, 0x167125, 0x06b049, 0x1eb107, 0x241101, 0x0c7049, 0x2091c1, 0x2dd1cf, 0x1c101f, 0x18514b, 0x0df0b5, 0x11b013, 0x2411bb, 0x0b5005, 0x0fb095, 0x0b3029, 0x4fd22d, 0x0a3029, 0x0d300d, 0x03501d, 0x33b06d, 0x2930e9, 0x08b065, 0x06d065, 0x10102f, 0x083029, 0x08b089, 0x3ad337, 0x06b035, 0x1a3053, 0x01d013, 0x1990c7, 0x33d1df, 0x15d083, 0x4a93fb, 0x397005, 0x11900b, 0x0f106b, 0x33d06d, 0x0e9067, 0x04902b, 0x13d0a7, 0x15d151, 0x295259, 0x35917f, 0x2d7241, 0x04300b, 0x18d167, 0x22300d, 0x0b3005, 0x18d0a3, 0x2c525f, 0x51b3c7, 0x18500d, 0x101025, 0x3370c7, 0x065025, 0x23b09d, 0x0fb09d, 0x185107, 0x08b065, 0x0ef0e5, 0x10d01f, 0x4c1469, 0x133119, 0x02b00d, 0x3b31f3, 0x2651c1, 0x1150a7, 0x0c70a7, 0x0e501f, 0x2931b1, 0x1a5017, 0x1010c1, 0x15d139, 0x0d307f, 0x2ef2c5, 0x1330c1, 0x1d30d3, 0x1150c1, 0x0e506b, 0x0b3005, 0x1c115b, 0x00d003, 0x08307f, 0x23b1af, 0x4cf133, 0x4691fd, 0x313025, 0x1fd1cd, 0x07f065, 0x0c500d, 0x3050e9, 0x4630a7, 0x33b029, 0x0e90bf, 0x39735b, 0x11b115, 0x0fb01f, 0x09d013, 0x161005, 0x2e317b, 0x15b115, 0x3f10c1, 0x3730e9, 0x1f3125, 0x269061, 0x2f92b3, 0x3d7373, 0x4930e9, 0x1c10ad, 0x373295, 0x3c72a1, 0x101059, 0x335185, 0x01100b, 0x0ad067, 0x1e70fb, 0x1a314b, 0x2690ef, 0x4270b3, 0x0bf007, 0x089053, 0x13d0a3, 0x2bd049, 0x2871f3, 0x0df02f, 0x167035, 0x1010e5, 0x0c100d, 0x2c502b, 0x287035, 0x09d00d, 0x0c1003, 0x16f0e9, 0x15b13d, 0x1af089, 0x22d067, 0x2e308b, 0x04f02b, 0x67949d, 0x397059, 0x1f3119, 0x25114b, 0x19910f, 0x137115, 0x22d007, 0x241049, 0x19100d, 0x1190ef, 0x21d0c7, 0x2cf095, 0x16106d, 0x10107f, 0x26915d, 0x1c91c1, 0x18503d, 0x06704f, 0x1b7029, 0x0fb0e9, 0x035011, 0x0f10e5, 0x1eb139, 0x1990c5, 0x2391d3, 0x0e903d, 0x08902b, 0x0c7035, 0x0a306d, 0x097095, 0x0a3065, 0x185005, 0x265259, 0x23b1df, 0x1610c5, 0x095065, 0x18513d, 0x01d011, 0x2dd233, 0x259083, 0x0ef061, 0x515043, 0x1e70bf, 0x1af0e5, 0x2bd21d, 0x14b029, 0x2570df, 0x1cf1bb, 0x119097, 0x25f209, 0x17b0df, 0x097059, 0x36d04f, 0x02f005, 0x1250df, 0x599125, 0x26b0fb, 0x1510e5, 0x2dd1a5, 0x1b714b, 0x04300d, 0x265107, 0x071061, 0x199013, 0x409161, 0x2590c1, 0x0df083, 0x4b136d, 0x11b053, 0x4fd0df, 0x03d02f, 0x2e702f, 0x2e702f, 0x3292f9, 0x1c9059, 0x04703b, 0x2dd1f7, 0x101071, 0x2cf1bb, 0x1cf01f, 0x241025, 0x0e500d, 0x17f10d, 0x08b03d, 0x2dd1fd, 0x287107, 0x3e5043, 0x2e70ad, 0x16f161, 0x09d08b, 0x0fb067, 0x10f029, 0x251125, 0x0ef0c7, 0x2591bb, 0x22d047, 0x1af167, 0x2a50ef, 0x607493, 0x11510f, 0x3c7005, 0x305199, 0x08b005, 0x3710c1, 0x2f903b, 0x329287, 0x28d061, 0x2bd107, 0x17f04f, 0x1c9095, 0x19102b, 0x0df02b, 0x1f302b, 0x15b11b, 0x0a3067, 0x1cd095, 0x14b10d, 0x1d300d, 0x1c110f, 0x06b01d, 0x3f5265, 0x16f0c5, 0x17b119, 0x1750b5, 0x5030bf, 0x0d300d, 0x283241, 0x4d50c7, 0x3590c7, 0x22d1f7, 0x32b2e3, 0x28d005, 0x2691a5, 0x25f01f, 0x083067, 0x28d1bb, 0x26911b, 0x10f053, 0x223137, 0x0bf00d, 0x3352cf, 0x397035, 0x1a3101, 0x329175, 0x15d0ad, 0x33b0ad, 0x1390a7, 0x09d025, 0x2870c1, 0x2f5133, 0x48b06b, 0x0b3005, 0x0f1089, 0x2a5277, 0x191097, 0x1f70a3, 0x2d726b, 0x01f017, 0x185175, 0x09d02b, 0x31d1a3, 0x2570fb, 0x2770e3, 0x3131fd, 0x2a50e5, 0x1cf0ef, 0x40902f, 0x2390b3, 0x097095, 0x18d0ef, 0x26b067, 0x265241, 0x33d2e3, 0x22d167, 0x71f2b3, 0x19104f, 0x287003, 0x06504f, 0x175005, 0x1f30a7, 0x0c7089, 0x0bf065, 0x38f00d, 0x3fb2f5, 0x02f00d, 0x33b101, 0x097049, 0x0f102b, 0x4a333d, 0x11503b, 0x20b1eb, 0x16f0e3, 0x20b11b, 0x22d01f, 0x60d5b3, 0x377313, 0x0c7097, 0x29315d, 0x0ef065, 0x2a1293, 0x0c1043, 0x10f0e5, 0x2951c9, 0x0ef0df, 0x35521d, 0x6f1175, 0x2ef151, 0x28d047, 0x035017, 0x06b029, 0x12500d, 0x30110d, 0x02f005, 0x2f91bb, 0x10d0e5, 0x21d0ad, 0x0df0c7, 0x373115, 0x1a5043, 0x17b025, 0x175005, 0x1a5065, 0x0b5095, 0x0b3061, 0x0c5083, 0x083035, 0x1c107f, 0x25f107, 0x1d30ef, 0x1d3107, 0x059049, 0x1390bf, 0x1910c7, 0x5991cf, 0x029017, 0x16110d, 0x2830e9, 0x161139, 0x065061, 0x17b08b, 0x1f710f, 0x3c7005, 0x36d06d, 0x0df01f, 0x21d0bf, 0x0b5097, 0x4a9065, 0x01d017, 0x1f318d, 0x133059, 0x281259, 0x287029, 0x049025, 0x0c1083, 0x1330b5, 0x0c5029, 0x139125, 0x095003, 0x1fd167, 0x3550e5, 0x059017, 0x2dd007, 0x3590f1, 0x4ff301, 0x2bd08b, 0x3b331d, 0x1510b5, 0x0b306b, 0x2ab191, 0x287223, 0x11b08b, 0x097005, 0x0df09d, 0x1150d3, 0x1f700b, 0x1af061, 0x0e50d3, 0x1c9029, 0x26b241, 0x0df00b, 0x1cf185, 0x13d0e3, 0x125107, 0x1bb0e5, 0x1fd1a5, 0x287281, 0x1df167, 0x3a931d, 0x1fd005, 0x1b100d, 0x0a703b, 0x15d025, 0x2831e7, 0x1cd133, 0x08900b, 0x0b3029, 0x301259, 0x16f139, 0x1cd00d, 0x0fb095, 0x32b059, 0x5db33b, 0x25102f, 0x2a5293, 0x38f0bf, 0x01100d, 0x301185, 0x1af0ef, 0x3fb241, 0x17b15b, 0x089083, 0x0e30c5, 0x137047, 0x2d720b, 0x083005, 0x06d029, 0x0e90c1, 0x15b0ad, 0x0e5025, 0x13d01d, 0x10d0fb, 0x2dd1d3, 0x09d06b, 0x08900d, 0x3df005, 0x23b1e7, 0x02f00d, 0x3010c7, 0x3df1fd, 0x0b3013, 0x0c10b3, 0x22d049, 0x2b3293, 0x10700d, 0x25713d, 0x1fd191, 0x1cf0a3, 0x0c50ad, 0x46944f, 0x265043, 0x13d0ad, 0x16f0e9, 0x1150a7, 0x0b5065, 0x5d50c5, 0x02f025, 0x13910d, 0x3cb0c5, 0x06101f, 0x37136d, 0x1a504f, 0x08b00d, 0x15101f, 0x0c707f, 0x1d3137, 0x1af0e3, 0x269151, 0x1bb0c7, 0x06503b, 0x0b302b, 0x0ad07f, 0x3c7277, 0x0b3005, 0x07106d, 0x07f025, 0x0d306d, 0x06d005, 0x083025, 0x2a1013, 0x36d269, 0x09503d, 0x33b2e7, 0x01f007, 0x10706d, 0x2a100d, 0x1330f1, 0x5e73b3, 0x1b1043, 0x2e3119, 0x581025, 0x0fb01f, 0x823035, 0x257223, 0x0bf061, 0x2ef0c1, 0x359025, 0x17f125, 0x2a5251, 0x185083, 0x22d1c1, 0x2a11a5, 0x14b04f, 0x455283, 0x101053, 0x287005, 0x2410ad, 0x15d15b, 0x0f1065, 0x191097, 0x05303d, 0x4c733d, 0x3fd269, 0x409377, 0x0e3071, 0x0df00d, 0x18d059, 0x28d265, 0x10f0ef, 0x139115, 0x185083, 0x2511eb, 0x223025, 0x1b114b, 0x1a5043, 0x0a300b, 0x233005, 0x11b06b, 0x101035, 0x2f5035, 0x13900d, 0x251137, 0x2391cf, 0x3b3373, 0x2330bf, 0x0df02f, 0x2bd10f, 0x30517f, 0x0c10bf, 0x1af071, 0x3371bb, 0x2ab02b, 0x09500b, 0x239059, 0x2a1013, 0x41b33d, 0x26b0b3, 0x1c9029, 0x1eb185, 0x419373, 0x3df359, 0x18510f, 0x2bd175, 0x2e721d, 0x16f0e3, 0x06b01f, 0x101013, 0x3fb2ab, 0x23902f, 0x281047, 0x15b01d, 0x28d071, 0x2410c1, 0x1a315d, 0x22d15d, 0x5270b3, 0x26503b, 0x16f059, 0x293265, 0x43f0e3, 0x0e307f, 0x0e3005, 0x04700b, 0x0a3047, 0x1af03d, 0x0a7013, 0x08b071, 0x2511eb, 0x0df02b, 0x1a3067, 0x3010bf, 0x26b233, 0x0f1065, 0x02900d, 0x08b06d, 0x15d083, 0x40f33b, 0x1070d3, 0x18d0c1, 0x1af18d, 0x2570e5, 0x2230ad, 0x35b2d7, 0x0d3035, 0x06d005, 0x2cf11b, 0x0c104f, 0x2ef1b1, 0x25f101, 0x21d11b, 0x137125, 0x2591af, 0x0a7047, 0x293137, 0x2b3199, 0x21d00d, 0x2e3257, 0x0e30df, 0x1b1119, 0x0f1097, 0x509005, 0x13d139, 0x21d02f, 0x101025, 0x15d083, 0x42d199, 0x3290a3, 0x2c506b, 0x199137, 0x20b17b, 0x31d00b, 0x3e50bf, 0x059053, 0x17508b, 0x2e71cd, 0x059011, 0x0b5089, 0x14b035, 0x19903b, 0x0b5061, 0x06b005, 0x3711fd, 0x295047, 0x20b107, 0x18d083, 0x09d007, 0x11b0e9, 0x175049, 0x0b3053, 0x17b101, 0x2951bb, 0x3a12ef, 0x0e90a7, 0x0ef0e9, 0x1c1011, 0x199029, 0x23b125, 0x2810df, 0x3b9049, 0x0b301f, 0x3d114b, 0x2f9161, 0x1cd151, 0x0e30a7, 0x259137, 0x10f03d, 0x09d04f, 0x337003, 0x11b059, 0x38f23b, 0x1f317b, 0x17b013, 0x08300b, 0x185119, 0x2c50b3, 0x16101d, 0x445409, 0x2b3295, 0x4273e5, 0x029011, 0x1990b5, 0x06b067, 0x26503d, 0x3f1335, 0x4bd26b, 0x2591e7, 0x26b1a5, 0x42d08b, 0x17f017, 0x16f125, 0x33d013, 0x1eb005, 0x14b0d3, 0x4070bf, 0x0ef0c7, 0x0df08b, 0x1fd059, 0x17b139, 0x0a302f, 0x0e500b, 0x059005, 0x1cd107, 0x09d097, 0x41b1d3, 0x0b509d, 0x0b3095, 0x4fd1c9, 0x1c90df, 0x0a303b, 0x08b07f, 0x4193cb, 0x3d7269, 0x2a5259, 0x337013, 0x1cf0b5, 0x3712b3, 0x3372a1, 0x15d071, 0x10101f, 0x047043, 0x1e7025, 0x1cf1c9, 0x1610a7, 0x0a3071, 0x1e700d, 0x03b00b, 0x19902b, 0x1670f1, 0x09d04f, 0x11900d, 0x2a1095, 0x3472e3, 0x0c502b, 0x52936d, 0x01100b, 0x199137, 0x24110d, 0x1a303b, 0x23922d, 0x0df005, 0x617409, 0x4810e3, 0x1af03d, 0x2091f7, 0x1910ef, 0x1b100d, 0x0bf025, 0x0b508b, 0x191185, 0x31d265, 0x01700d, 0x1cd161, 0x03d035, 0x10f101, 0x25f06d, 0x0f1025, 0x08b03b, 0x011005, 0x22301d, 0x335287, 0x15d0ad, 0x20b16f, 0x0d3065, 0x24b0c7, 0x31318d, 0x223043, 0x2691c9, 0x1eb011, 0x293053, 0x115101, 0x17b02b, 0x0e90df, 0x3cb1eb, 0x2930c1, 0x4a3065, 0x33d175, 0x2571b7, 0x45d161, 0x0c500d, 0x29500b, 0x14b017, 0x133095, 0x089029, 0x2831df, 0x1d3175, 0x1d3067, 0x1bb15d, 0x371139, 0x24b095, 0x1b70e3, 0x18503d, 0x15111b, 0x1df01f, 0x18d02f, 0x1390d3, 0x059035, 0x16f137, 0x2d72cf, 0x1f3115, 0x4eb1df, 0x01d013, 0x1330e9, 0x15d071, 0x1e7185, 0x3b9175, 0x4e1185, 0x047043, 0x125011, 0x1bb013, 0x0fb043, 0x1c1175, 0x0f10bf, 0x2bd14b, 0x0b3049, 0x5032a5, 0x0e3035, 0x1fd101, 0x15b01d, 0x0a7047, 0x18d13d, 0x115003, 0x3b3059, 0x17500d, 0x0b5095, 0x0c509d, 0x4cd2e3, 0x359005, 0x2650d3, 0x223151, 0x37310d, 0x1b713d, 0x16f0d3, 0x20b0c7, 0x2b30b5, 0x065043, 0x49d257, 0x63d0e5, 0x1190c5, 0x10d07f, 0x03b01d, 0x2cf00b, 0x06101f, 0x19903b, 0x03b02f, 0x17f00d, 0x1330a3, 0x1f707f, 0x42706d, 0x1d30e5, 0x1250bf, 0x0c5067, 0x049025, 0x1510b3, 0x3e502f, 0x14b06d, 0x67933b, 0x0b3005, 0x07f00d, 0x1a30fb, 0x1eb061, 0x06b061, 0x4091a5, 0x125083, 0x13911b, 0x0b503b, 0x46300b, 0x2bd097, 0x04302f, 0x0a700d, 0x08b00d, 0x3f13a1, 0x593257, 0x2c5185, 0x2cf1f7, 0x1eb0b5, 0x191059, 0x347003, 0x2091c9, 0x25f02b, 0x359259, 0x1af0df, 0x5152a5, 0x223191, 0x4fd1b1, 0x20b151, 0x337241, 0x1bb029, 0x1390a7, 0x26b013, 0x161095, 0x18d03b, 0x167007, 0x1bb1b1, 0x3f5223, 0x09508b, 0x0fb095, 0x125065, 0x1af053, 0x07101f, 0x1d30e9, 0x1bb053, 0x01d00b, 0x3ad08b, 0x269005, 0x0a7013, 0x07f053, 0x209133, 0x0ad005, 0x09d06d, 0x06700d, 0x03b00d, 0x233059, 0x2871c9, 0x199083, 0x0a702b, 0x02f029, 0x3df1c9, 0x2231af, 0x059049, 0x13300b, 0x11b03d, 0x139061, 0x1610d3, 0x0c70a3, 0x119101, 0x4cd02f, 0x0e9059, 0x11500d, 0x01d00d, 0x16f053, 0x18d119, 0x0b3029, 0x1f3191, 0x33d2f5, 0x06d035, 0x2810e9, 0x4191c9, 0x1eb1cf, 0x107071, 0x2f9067, 0x13d0fb, 0x0df0b5, 0x0ad09d, 0x151049, 0x0a7029, 0x24109d, 0x1df00d, 0x283007, 0x0c5005, 0x23904f, 0x2a5251, 0x2b308b, 0x0bf017, 0x17514b, 0x20b0df, 0x2d7293, 0x09506b, 0x36d03d, 0x06703b, 0x097043, 0x3c7313, 0x1bb0bf, 0x38f2cf, 0x1f706d, 0x101071, 0x1af089, 0x0df053, 0x13d0f1, 0x0b3065, 0x42d233, 0x1af043, 0x10d0ad, 0x1e71a3, 0x161043, 0x26910d, 0x223115, 0x2e3095, 0x25f025, 0x2a1175, 0x1fd1df, 0x2a1067, 0x2b3011, 0x2ef2dd, 0x1b70c7, 0x1390ad, 0x13307f, 0x0c7029, 0x13700d, 0x4fd337, 0x0f1059, 0x1f3107, 0x13706b, 0x07103b, 0x24b02f, 0x1d3003, 0x463427, 0x19115d, 0x199175, 0x35b089, 0x0df0d3, 0x04f03b, 0x1cd013, 0x22d0c7, 0x01f007, 0x04f00b, 0x33715d, 0x2330ad, 0x5cf06b, 0x14b0a3, 0x19900d, 0x04f00d, 0x1b104f, 0x425233, 0x0b300d, 0x0ef0e5, 0x14b101, 0x199017, 0x06b005, 0x28d0c1, 0x1010a3, 0x0c10b3, 0x15b0d3, 0x10d0e9, 0x1f302f, 0x359191, 0x3b302b, 0x52f1e7, 0x2570f1, 0x35b28d, 0x2f9209, 0x061025, 0x25f251, 0x04702b, 0x1250b3, 0x061043, 0x223061, 0x287223, 0x1cd083, 0x0fb053, 0x1f7007, 0x16f06d, 0x5272cf, 0x1b1049, 0x427409, 0x20916f, 0x18d119, 0x35b18d, 0x0e500d, 0x25f11b, 0x19118d, 0x1b1125, 0x1250bf, 0x2bd06d, 0x24b191, 0x10101f, 0x02b00b, 0x223065, 0x2f9191, 0x5c952f, 0x1cd0ad, 0x1b7061, 0x0ad01d, 0x0e3005, 0x2f9191, 0x0a7011, 0x3df26b, 0x13d139, 0x065059, 0x35b2ef, 0x283071, 0x1fd133, 0x06d03d, 0x22d03d, 0x3a116f, 0x1c9125, 0x25909d, 0x101029, 0x2f52b3, 0x1cd0e3, 0x0c7095, 0x0df0c5, 0x06101f, 0x08b049, 0x0bf095, 0x0a708b, 0x19102f, 0x29501f, 0x3051f7, 0x22d175, 0x6110e5, 0x1b1119, 0x0bf013, 0x053029, 0x17b029, 0x0c70a3, 0x3b302b, 0x1bb185, 0x10f005, 0x07f00d, 0x251233, 0x2a120b, 0x4cf241, 0x00d007, 0x15109d, 0x0e3007, 0x2bd08b, 0x1b102f, 0x31d03b, 0x2411b7, 0x1bb199, 0x23b175, 0x1cf1a3, 0x2591c1, 0x0ef0c7, 0x1bb0c7, 0x455119, 0x0ad061, 0x1a518d, 0x1f7137, 0x1f318d, 0x04903b, 0x161053, 0x1750bf, 0x24122d, 0x23318d, 0x02900d, 0x407025, 0x5bf36d, 0x1f704f, 0x0ad025, 0x35921d, 0x1f7025, 0x24b065, 0x013005, 0x301097, 0x17b0fb, 0x251223, 0x18d07f, 0x2a503d, 0x2091f7, 0x1610ad, 0x10d0a7, 0x11500b, 0x08306d, 0x209013, 0x1a5053, 0x15d0e3, 0x133025, 0x09706b, 0x1fd00d, 0x0c503d, 0x25915b, 0x20b1b1, 0x02f029, 0x18d06b, 0x13309d, 0x23b1eb, 0x31d1f7, 0x40f209, 0x199167, 0x347083, 0x2230c7, 0x18d089, 0x0b5005, 0x2cf0e5, 0x1df1a3, 0x0d306d, 0x10f06d, 0x06b03b, 0x17515b, 0x0f10bf, 0x053011, 0x2e306b, 0x2e7269, 0x06500d, 0x2cf08b, 0x2a1281, 0x209097, 0x6c56a3, 0x5d143f, 0x1f3059, 0x0d303b, 0x5d1223, 0x0a7059, 0x16f065, 0x1cd053, 0x2b31bb, 0x15d0e3, 0x3e506b, 0x17b083, 0x0bf08b, 0x5f340f, 0x047011, 0x301167, 0x0ef025, 0x22d185, 0x2e3095, 0x053017, 0x0ad03d, 0x31d15b, 0x1a30c1, 0x3370bf, 0x0c5047, 0x31d269, 0x13701f, 0x2ef047, 0x3050c5, 0x13d049, 0x139083, 0x2e7043, 0x047011, 0x1e70b5, 0x40701d, 0x15d00d, 0x0a3005, 0x31300d, 0x125067, 0x3b3377, 0x097043, 0x1b10bf, 0x293241, 0x23b1d3, 0x1f71eb, 0x0c5025, 0x17b017, 0x15b065, 0x0a7089, 0x1a500d, 0x2cf23b, 0x1990e9, 0x0d3025, 0x18d167, 0x1f701f, 0x0d3053, 0x313295, 0x2090fb, 0x0ad017, 0x3131a5, 0x1c10c1, 0x18504f, 0x15b13d, 0x13302b, 0x3df2f9, 0x04701f, 0x0d30c7, 0x1a5185, 0x4d5139, 0x19102f, 0x1df053, 0x335293, 0x04f02b, 0x1750b3, 0x06d011, 0x59f043, 0x1f7139, 0x61f1c1, 0x16109d, 0x17f07f, 0x2bd125, 0x089029, 0x2ab119, 0x2c50a3, 0x1e7191, 0x0c106d, 0x0fb011, 0x1b1013, 0x1850e9, 0x3b903b, 0x1a303d, 0x2ef0a3, 0x19900d, 0x05300d, 0x185025, 0x0c5089, 0x1f70fb, 0x119115, 0x1cf1a5, 0x3ad32b, 0x097005, 0x1990c7, 0x32928d, 0x22309d, 0x0df003, 0x065043, 0x067011, 0x0df0c1, 0x251005, 0x133097, 0x2e31b7, 0x371301, 0x151083, 0x071017, 0x295185, 0x1d3137, 0x107047, 0x2871d3, 0x2231b1, 0x3e50df, 0x08b047, 0x15b0df, 0x31d029, 0x233161, 0x16f14b, 0x1f703d, 0x049047, 0x2770c5, 0x0c1095, 0x3b30e5, 0x1af067, 0x445047, 0x25f095, 0x071025, 0x0f1071, 0x0ad089, 0x2591b7, 0x04703b, 0x3590d3, 0x09d03b, 0x053005, 0x3551c9, 0x11b01f, 0x209043, 0x38b00d, 0x1af071, 0x151107, 0x115107, 0x4253fb, 0x1250e5, 0x49d0a7, 0x18d17b, 0x1c9065, 0x1cf0b5, 0x4091cd, 0x313095, 0x29523b, 0x0f10bf, 0x17501d, 0x1c1175, 0x1370ad, 0x1a50f1, 0x19115d, 0x1f717b, 0x06d005, 0x1df15d, 0x19117b, 0x49d24b, 0x19110f, 0x0f100d, 0x1cd0a3, 0x25f03d, 0x17b0f1, 0x45d3fd, 0x25f199, 0x251151, 0x15b03b, 0x2f906b, 0x2ef061, 0x11b00d, 0x1150b3, 0x03d029, 0x22d0f1, 0x007005, 0x07f071, 0x3352b3, 0x065011, 0x01d005, 0x095017, 0x0c106d, 0x43f11b, 0x09d00b, 0x31d18d, 0x42d21d, 0x01300d, 0x1c1191, 0x10106d, 0x2091df, 0x265133, 0x15b0b3, 0x1b10a7, 0x03d03b, 0x449373, 0x1a5125, 0x283209, 0x2bd1a5, 0x26514b, 0x1b703b, 0x20b02f, 0x41b16f, 0x2b308b, 0x0df097, 0x03d00b, 0x33b0e9, 0x1f303d, 0x2950c7, 0x03b01d, 0x0ef0bf, 0x1af0ef, 0x15b0ef, 0x01300d, 0x14b10d, 0x2ab1af, 0x25714b, 0x5f31d3, 0x2090ad, 0x059029, 0x20901d, 0x09d005, 0x1f7107, 0x11b047, 0x13902f, 0x63d03d, 0x191025, 0x0c100d, 0x2091a3, 0x09501d, 0x101007, 0x1df125, 0x04301f, 0x02901f, 0x053049, 0x09507f, 0x00d00b, 0x133065, 0x1bb0c5, 0x329089, 0x2390a3, 0x23b067, 0x32926b, 0x06d061, 0x18516f, 0x185139, 0x2f500d, 0x0c1025, 0x0c1049, 0x0c7005, 0x13d025, 0x0c706d, 0x15b013, 0x2dd01d, 0x649329, 0x0e9035, 0x067065, 0x24102f, 0x05300b, 0x2e700b, 0x0b306b, 0x295125, 0x1e714b, 0x1cd167, 0x0f1005, 0x0e3011, 0x175025, 0x0b5089, 0x21d1df, 0x359065, 0x07104f, 0x28124b, 0x0e3053, 0x03502f, 0x2e31b7, 0x12507f, 0x17f151, 0x20b125, 0x233223, 0x17f0ad, 0x16714b, 0x12510d, 0x059049, 0x24b1a5, 0x1af199, 0x095067, 0x33d283, 0x1a5125, 0x0fb097, 0x40f167, 0x0ef01f, 0x1f713d, 0x14b13d, 0x1cf005, 0x1c909d, 0x42733d, 0x101071, 0x11b043, 0x0f1005, 0x335265, 0x15b08b, 0x0f1007, 0x0c1053, 0x3051cd, 0x39709d, 0x18504f, 0x18d025, 0x0b3013, 0x04f01d, 0x1a5083, 0x3cb377, 0x0ad053, 0x1c1199, 0x33b1b1, 0x2511d3, 0x0a707f, 0x5e700b, 0x21d10f, 0x3471a3, 0x37322d, 0x1df071, 0x3ad017, 0x3f106d, 0x4a9419, 0x14b0fb, 0x2390c5, 0x37101f, 0x16707f, 0x445017, 0x28702b, 0x0c1025, 0x0e9035, 0x1910f1, 0x25f1bb, 0x1df1a3, 0x20b061, 0x3d12bd, 0x06b049, 0x2e303d, 0x199107, 0x35510d, 0x21d1c1, 0x1e702f, 0x0e300d, 0x455059, 0x45d2c5, 0x2590c5, 0x0b5035, 0x0fb03b, 0x647083, 0x175125, 0x095025, 0x6a100d, 0x15110d, 0x2810d3, 0x32914b, 0x1a51a3, 0x1390a3, 0x065059, 0x15d119, 0x6df371, 0x07f067, 0x0b5035, 0x09d065, 0x06d00d, 0x18d0fb, 0x04f043, 0x0c507f, 0x0fb0bf, 0x107095, 0x115047, 0x1c1035, 0x1c910f, 0x313025, 0x053035, 0x175029, 0x17f095, 0x08306b, 0x043005, 0x10f0c5, 0x2e31a5, 0x1df00d, 0x13706d, 0x0b50a3, 0x0fb02f, 0x1d3139, 0x14b06d, 0x58149d, 0x51b41b, 0x0df049, 0x10d03b, 0x0b3083, 0x281139, 0x1f3065, 0x04301d, 0x2b31bb, 0x2c5133, 0x107067, 0x17b097, 0x6bb0b5, 0x06d00b, 0x1cd18d, 0x0c7035, 0x0a3007, 0x28d029, 0x25f047, 0x4272e3, 0x1330b5, 0x1cf0ad, 0x0f1083, 0x24b1bb, 0x03d029, 0x3e5065, 0x23b167, 0x3df3d1, 0x0fb067, 0x2d71e7, 0x02f01d, 0x26b269, 0x0fb0a7, 0x167025, 0x26513d, 0x17f0e9, 0x21d1a5, 0x08b06b, 0x1c909d, 0x25f011, 0x2cf11b, 0x2f91a3, 0x13708b, 0x2f510f, 0x2f91cd, 0x18d06d, 0x17b017, 0x25f185, 0x25710d, 0x3a12a5, 0x3a9101, 0x1b70b5, 0x1150b3, 0x0fb07f, 0x259083, 0x293119, 0x049043, 0x065053, 0x26b241, 0x69d4d5, 0x125005, 0x14b119, 0x257139, 0x1a5199, 0x2650e5, 0x463137, 0x44521d, 0x025005, 0x3291eb, 0x1b1065, 0x11b097, 0x3fd185, 0x455277, 0x059005, 0x0f10b3, 0x17500b, 0x03d03b, 0x3970c1, 0x16f03d, 0x2b314b, 0x7eb425, 0x1fd107, 0x0e9049, 0x1af00d, 0x1cd00d, 0x16700d, 0x0e90ad, 0x4272d7, 0x35f1c1, 0x1b70ad, 0x0ad071, 0x0df06b, 0x02900d, 0x23315d, 0x065005, 0x09d029, 0x0a7067, 0x047005, 0x185107, 0x16f025, 0x27703d, 0x1b7029, 0x13d04f, 0x36d223, 0x0c109d, 0x269191, 0x06500d, 0x1df071, 0x06702b, 0x02f00d, 0x23b0e3, 0x089013, 0x04f035, 0x1f3175, 0x0d3025, 0x1df003, 0x2a5125, 0x1250e5, 0x241035, 0x0ef06b, 0x1bb0ad, 0x29320b, 0x025011, 0x0c1053, 0x21d17f, 0x3f51b1, 0x22d0c5, 0x2dd2a5, 0x3c715d, 0x62318d, 0x071059, 0x08b00d, 0x2411f3, 0x283281, 0x0ef049, 0x1f701d, 0x047025, 0x07f02b, 0x18d01d, 0x06502f, 0x679581, 0x1f3005, 0x0d3035, 0x1bb119, 0x3290e9, 0x3ad2a1, 0x1c1115, 0x0bf025, 0x16f03b, 0x11b059, 0x089049, 0x097059, 0x17f01d, 0x10f03b, 0x59f4bd, 0x06703b, 0x1df035, 0x24b071, 0x13d115, 0x25f097, 0x13d03d, 0x22d1b7, 0x481029, 0x10d097, 0x45d133, 0x23917b, 0x0ad06d, 0x1190b5, 0x0bf03b, 0x1c9065, 0x3130e9, 0x1d3151, 0x11501f, 0x1a3185, 0x14b0ef, 0x10f0c5, 0x1a3071, 0x16107f, 0x0e504f, 0x1fd17f, 0x043029, 0x11508b, 0x251107, 0x22d1df, 0x30523b, 0x5032b3, 0x2dd115, 0x335061, 0x06b029, 0x059049, 0x5810b5, 0x0df035, 0x0ad08b, 0x083013, 0x17f139, 0x3550e9, 0x37307f, 0x10d09d, 0x0f101f, 0x0f1059, 0x02500d, 0x287175, 0x047011, 0x14b06d, 0x09d025, 0x0f1067, 0x1af15d, 0x0e508b, 0x161137, 0x0e9029, 0x551175, 0x1c115b, 0x1d310f, 0x1a316f, 0x29520b, 0x125049, 0x295185, 0x0df02b, 0x21d035, 0x071059, 0x07f011, 0x0a306b, 0x20b097, 0x4250c1, 0x329251, 0x1670c5, 0x3f526b, 0x0fb00d, 0x06b059, 0x269259, 0x10f0c7, 0x3550df, 0x175115, 0x445407, 0x0b303d, 0x2e3095, 0x0fb0a7, 0x1c1059, 0x593125, 0x16114b, 0x283125, 0x251151, 0x10f0ef, 0x25f1af, 0x35f0e3, 0x43f04f, 0x1c900d, 0x42d17b, 0x191115, 0x1a3161, 0x125095, 0x3cb043, 0x1190c1, 0x16102f, 0x4932ef, 0x2a1083, 0x11910d, 0x25900d, 0x305191, 0x125025, 0x223101, 0x3ad0c5, 0x3b9049, 0x04901d, 0x35518d, 0x151097, 0x20b0c5, 0x13909d, 0x21d137, 0x0fb09d, 0x1510c5, 0x0c104f, 0x167161, 0x32b305, 0x27701d, 0x06b049, 0x08b01f, 0x0f100d, 0x15d03d, 0x223185, 0x1150ef, 0x33b10f, 0x42d1df, 0x09508b, 0x1cf175, 0x02500d, 0x08b007, 0x1b7115, 0x2bd119, 0x19101d, 0x1cd0e9, 0x08302f, 0x059049, 0x2a106b, 0x2dd005, 0x0b3049, 0x17511b, 0x0bf043, 0x08901d, 0x0ad03b, 0x18d175, 0x137005, 0x0bf00d, 0x20b13d, 0x259209, 0x13d01f, 0x2390d3, 0x067029, 0x2390a3, 0x139083, 0x1f30ad, 0x04f047, 0x1c114b, 0x0bf0a3, 0x23b03d, 0x1bb08b, 0x175095, 0x829649, 0x44f3d7, 0x43f061, 0x14b025, 0x27720b, 0x29301f, 0x1c1071, 0x1b70df, 0x02b013, 0x059043, 0x0c100d, 0x0fb0b3, 0x13903b, 0x03500d, 0x14b09d, 0x24b043, 0x071053, 0x1c90ef, 0x18d03b, 0x2ef1cf, 0x359089, 0x1cf0f1, 0x125011, 0x1190df, 0x20901f, 0x23b01d, 0x10d065, 0x2f500d, 0x10d0ad, 0x23b17b, 0x10f053, 0x09503d, 0x1750e5, 0x01300b, 0x07f059, 0x2bd09d, 0x33b22d, 0x185013, 0x0c507f, 0x083049, 0x295097, 0x1fd017, 0x239209, 0x6493e5, 0x1fd013, 0x0c506b, 0x1150a7, 0x097095, 0x31306b, 0x095003, 0x0ad043, 0x29525f, 0x25902f, 0x1af0f1, 0x48b38f, 0x175043, 0x1cf09d, 0x1d30ad, 0x38f0ef, 0x0f10b5, 0x1a5061, 0x185133, 0x2511eb, 0x191035, 0x16702b, 0x42510d, 0x1c9011, 0x11902b, 0x24115b, 0x06d053, 0x199035, 0x03b013, 0x125035, 0x06b01f, 0x2811eb, 0x089025, 0x25f0d3, 0x2391f3, 0x1b115d, 0x00d007, 0x1e70d3, 0x29522d, 0x10d071, 0x233083, 0x337209, 0x0bf061, 0x3cb0df, 0x08b01d, 0x049011, 0x1f30fb, 0x3d7295, 0x0f10e5, 0x06701d, 0x08b01f, 0x25f01f, 0x01300b, 0x2931df, 0x10103d, 0x07f005, 0x1750e3, 0x25f0a3, 0x065059, 0x1f300d, 0x0c102b, 0x065029, 0x16113d, 0x01d005, 0x24b151, 0x2d7083, 0x2ab167, 0x0df00d, 0x32b0df, 0x223125, 0x13902b, 0x4092ef, 0x15b02b, 0x1670a3, 0x2771d3, 0x1fd1f7, 0x0ef0e5, 0x2ef0ef, 0x0e5005, 0x24b059, 0x185005, 0x329269, 0x4bd06b, 0x06502b, 0x25f1b7, 0x3c7293, 0x35f2ab, 0x0e3005, 0x29320b, 0x2571b1, 0x24b10f, 0x1510ef, 0x125025, 0x12506d, 0x17501d, 0x2e314b, 0x4c7305, 0x2bd23b, 0x0df007, 0x0ad053, 0x185005, 0x335283, 0x03d005, 0x2410e5, 0x1cd011, 0x119061, 0x1a5097, 0x3d735b, 0x27715b, 0x287259, 0x3f13c7, 0x21d0df, 0x0e900d, 0x4812a5, 0x223065, 0x2651bb, 0x371281, 0x39722d, 0x2f5095, 0x125061, 0x3e53d7, 0x1c106b, 0x11500b, 0x0fb00d, 0x0bf07f, 0x0df035, 0x17501f, 0x1a30b3, 0x3a92ab, 0x0a7013, 0x21d0df, 0x33717b, 0x0c5065, 0x2dd139, 0x2a102f, 0x1fd067, 0x64722d, 0x18515b, 0x3d71bb, 0x2ab125, 0x1b115b, 0x1c9025, 0x1b1025, 0x11b0e3, 0x0df065, 0x0a308b, 0x0d30ad, 0x2e30d3, 0x3e5329, 0x1df0e9, 0x0ad01d, 0x25f1a5, 0x0f10c5, 0x0c502f, 0x33b1cd, 0x1eb17b, 0x1b7101, 0x1010e3, 0x1a3095, 0x6495cb, 0x33715d, 0x01d00d, 0x2b31c9, 0x1b70c7, 0x10f0c7, 0x43f313, 0x60d175, 0x17b167, 0x059007, 0x41b09d, 0x5d5287, 0x30115b, 0x13d02f, 0x11901d, 0x2330ef, 0x15d125, 0x33d18d, 0x04700d, 0x133083, 0x251083, 0x101017, 0x059005, 0x1bb0a3, 0x07f005, 0x223191, 0x3f51f3, 0x1510e9, 0x04303b, 0x1df0bf, 0x50332b, 0x4251cf, 0x1150c5, 0x2090a3, 0x2330f1, 0x4fd3b3, 0x3291b1, 0x2230c5, 0x0e3071, 0x0a7097, 0x1cd0fb, 0x2a5061, 0x0b30a3, 0x3a133b, 0x18500b, 0x3370e5, 0x0fb0a7, 0x17b011, 0x047017, 0x269049, 0x2651cd, 0x1a3097, 0x10f097, 0x0f108b, 0x09503b, 0x1d30df, 0x0c5089, 0x0a7061, 0x0c503d, 0x1d3005, 0x1070df, 0x0d30bf, 0x2870e5, 0x16f133, 0x0fb0c1, 0x0b5097, 0x0b5007, 0x1af0bf, 0x1610d3, 0x1fd199, 0x15b0a3, 0x17f029, 0x09d061, 0x191035, 0x1150e5, 0x305095, 0x07106b, 0x4bd15d, 0x371097, 0x161005, 0x3b3257, 0x40f185, 0x0e50c7, 0x32b04f, 0x1b70df, 0x175049, 0x26923b, 0x37702f, 0x0ef071, 0x31d151, 0x1eb11b, 0x0bf03d, 0x3131f3, 0x43f0b5, 0x0e5095, 0x35b089, 0x119089, 0x1510c5, 0x13d007, 0x08b061, 0x0b5053, 0x18d107, 0x0b306d, 0x1390df, 0x0c70bf, 0x25715b, 0x06501d, 0x175025, 0x065029, 0x1df0e3, 0x15b017, 0x0ef049, 0x0ad03d, 0x35506d, 0x265067, 0x0f100d, 0x1750a7, 0x1150a3, 0x281277, 0x335269, 0x06b00d, 0x31d119, 0x119017, 0x095049, 0x35b2c5, 0x0c702f, 0x16f065, 0x0c102b, 0x43f2cf, 0x21d059, 0x049005, 0x2590c5, 0x25100d, 0x32b199, 0x0e508b, 0x28703d, 0x02f005, 0x51143f, 0x08b017, 0x0c1007, 0x0e506d, 0x0c10ad, 0x11b0ad, 0x16f11b, 0x02900d, 0x0ad06b, 0x06b005, 0x1e7029, 0x2571f3, 0x065007, 0x035013, 0x33b2f5, 0x03d005, 0x1990c5, 0x2cf17f, 0x09d02f, 0x3472d7, 0x2cf07f, 0x38f33b, 0x1df139, 0x355005, 0x22d043, 0x0c1059, 0x1eb09d, 0x3cb061, 0x1cd199, 0x119013, 0x0ef061, 0x2ab16f, 0x16108b, 0x2c50ef, 0x11b04f, 0x41b0c5, 0x16107f, 0x089053, 0x3350c7, 0x355259, 0x2e71a3, 0x107047, 0x1e70c1, 0x4a902b, 0x0a3043, 0x1a30c7, 0x17f017, 0x0d3097, 0x335269, 0x1bb0bf, 0x10d059, 0x1f3005, 0x3a9119, 0x1fd133, 0x209137, 0x1c11bb, 0x21d01f, 0x1c9043, 0x16f03d, 0x1b71af, 0x61720b, 0x107035, 0x1250e3, 0x0e9067, 0x10d029, 0x059049, 0x1a5161, 0x03d01f, 0x287025, 0x0e90b5, 0x16710d, 0x36d251, 0x1cd115, 0x355259, 0x1cd035, 0x095049, 0x16111b, 0x1f31a5, 0x0b3097, 0x1e71a3, 0x097007, 0x08b03b, 0x36d035, 0x1cd0c1, 0x0b5071, 0x51b083, 0x137067, 0x1c1043, 0x2b3151, 0x049003, 0x0c1083, 0x611527, 0x259101, 0x00d007, 0x10d04f, 0x0ef04f, 0x06b065, 0x28d0b3, 0x02501d, 0x0b3089, 0x57710f, 0x17b07f, 0x151095, 0x2771c9, 0x1e7133, 0x06d065, 0x1a501d, 0x1b71b1, 0x257005, 0x25722d, 0x06d035, 0x119005, 0x13d025, 0x185119, 0x05900b, 0x3591b7, 0x2a5061, 0x10d043, 0x23909d, 0x2e70df, 0x20b097, 0x6470e3, 0x22d133, 0x287223, 0x3a1137, 0x1190c5, 0x1fd04f, 0x0df095, 0x5bf3a1, 0x067025, 0x23b185, 0x1750e9, 0x0ad01d, 0x0bf0b3, 0x1af167, 0x00d007, 0x4b116f, 0x33510d, 0x3ad1c1, 0x13d049, 0x15b005, 0x115013, 0x209139, 0x199013, 0x25f0b3, 0x469101, 0x05903d, 0x2ef241, 0x4d501d, 0x18d175, 0x1e70fb, 0x2e30b5, 0x097043, 0x007005, 0x01d013, 0x0f1047, 0x1eb005, 0x05302b, 0x1070c7, 0x0c709d, 0x10d01d, 0x1eb0a3, 0x96b005, 0x17b0ef, 0x0d3089, 0x21d133, 0x1e7061, 0x10703d, 0x15b01d, 0x251161, 0x185065, 0x1330f1, 0x133083, 0x25709d, 0x10d00d, 0x2a11af, 0x3d113d, 0x1070f1, 0x269199, 0x06b01d, 0x17f011, 0x1150e5, 0x347133, 0x059007, 0x0c507f, 0x12510d, 0x17502b, 0x0b306d, 0x38f257, 0x449355, 0x05901d, 0x1d30c1, 0x1b10c1, 0x04903d, 0x15d02f, 0x0ad095, 0x1250c5, 0x3b9281, 0x06100d, 0x21d107, 0x1eb07f, 0x175133, 0x4bd0a7, 0x13301d, 0x0a3043, 0x20b005, 0x13909d, 0x199007, 0x0c5029, 0x33d0f1, 0x3592a5, 0x2c51b1, 0x1af061, 0x28108b, 0x1f7025, 0x35b03b, 0x30106d, 0x1750c1, 0x0c103b, 0x2d7251, 0x17503d, 0x161005, 0x06b03d, 0x259241, 0x28324b, 0x14b029, 0x07100d, 0x0e303b, 0x1070ef, 0x18d161, 0x2a10bf, 0x03d01f, 0x17b025, 0x20b1fd, 0x17510f, 0x34701f, 0x15d10d, 0x1cf0ef, 0x06701d, 0x0f10e3, 0x0c101d, 0x28325f, 0x17508b, 0x03b029, 0x1a5047, 0x04f017, 0x517503, 0x33701f, 0x107101, 0x0ef07f, 0x455065, 0x12502b, 0x24b061, 0x335199, 0x1cf071, 0x3d11a5, 0x16f115, 0x115013, 0x13d0e9, 0x209043, 0x22306d, 0x259101, 0x0a3003, 0x2d7067, 0x15106d, 0x1df15b, 0x551029, 0x1c109d, 0x07f025, 0x31d0a3, 0x059047, 0x2b3101, 0x119053, 0x06501f, 0x22d16f, 0x44938f, 0x23916f, 0x32903d, 0x0c1017, 0x2571af, 0x6df067, 0x1370a3, 0x0d303b, 0x22311b, 0x04900d, 0x1f3065, 0x14b071, 0x2c511b, 0x1c117f, 0x25f029, 0x337029, 0x053013, 0x097061, 0x24b005, 0x4d528d, 0x0c700b, 0x1a5167, 0x2f506d, 0x5d1265, 0x33b0bf, 0x2dd107, 0x2390a3, 0x1f3089, 0x071005, 0x1f717b, 0x50925f, 0x5c90bf, 0x095065, 0x355137, 0x13906b, 0x0b5061, 0x239053, 0x3f53e5, 0x35b0a7, 0x4633a1, 0x2590c5, 0x2e3209, 0x2590d3, 0x175005, 0x287025, 0x1e7167, 0x0e30b5, 0x4d5223, 0x13703d, 0x337305, 0x35515b, 0x1b1043, 0x0ef04f, 0x281209, 0x0e3005, 0x1b711b, 0x1cf167, 0x11501d, 0x10d0c7, 0x2230f1, 0x0ad04f, 0x4bd013, 0x167097, 0x1eb1cd, 0x4090e3, 0x2870ad, 0x10f06d, 0x3050a3, 0x295005, 0x1c900d, 0x0fb08b, 0x09502b, 0x1d304f, 0x1330c1, 0x335053, 0x337101, 0x14b0ef, 0x1c9067, 0x15d02b, 0x42d2d7, 0x0c5053, 0x4a9277, 0x06b013, 0x15b013, 0x13d0ad, 0x0e3053, 0x0b3005, 0x1b10e3, 0x1d30b3, 0x22d00b, 0x0fb0a3, 0x425355, 0x2c501f, 0x13903d, 0x1d309d, 0x0b308b, 0x21d1cd, 0x17f097, 0x23306b, 0x13900d, 0x01f00d, 0x1250f1, 0x0a3095, 0x059049, 0x21d0e9, 0x0e306d, 0x03b013, 0x21d17b, 0x115097, 0x04901f, 0x1a5125, 0x40902b, 0x2f500d, 0x16115b, 0x0ef053, 0x10d013, 0x31d02b, 0x50b1bb, 0x22d083, 0x2ab28d, 0x28318d, 0x133043, 0x5cf067, 0x053029, 0x2510c1, 0x20b1b7, 0x07f067, 0x1c917f, 0x50b41b, 0x0c5053, 0x119089, 0x1510a3, 0x3f1115, 0x2091b1, 0x223133, 0x1f7011, 0x1cd097, 0x18d133, 0x0ef053, 0x10103b, 0x035007, 0x0df013, 0x17b059, 0x1670e3, 0x2b3259, 0x0c1017, 0x133071, 0x3d7209, 0x12510d, 0x16f00d, 0x0a709d, 0x17f061, 0x115083, 0x2951f3, 0x26518d, 0x0e307f, 0x30121d, 0x305067, 0x101035, 0x13d0d3, 0x251059, 0x1cf06b, 0x313175, 0x23922d, 0x283061, 0x00b003, 0x167107, 0x1f715b, 0x2dd0f1, 0x06b005, 0x09d02b, 0x4191e7, 0x0df095, 0x313013, 0x1b7083, 0x0ad03b, 0x0df071, 0x2cf01f, 0x1a5005, 0x10f06b, 0x0e3053, 0x0b303b, 0x1a30b5, 0x3c71cd, 0x16f043, 0x329017, 0x06b005, 0x06b005, 0x06700d, 0x17b097, 0x1fd1a5, 0x1b10b5, 0x1fd0bf, 0x185017, 0x4c14a3, 0x0f10c5, 0x0e508b, 0x1e717f, 0x14b133, 0x3e53c7, 0x06102f, 0x1b110f, 0x2dd23b, 0x0a3029, 0x067059, 0x067013, 0x0fb0e9, 0x0bf065, 0x10103d, 0x1330f1, 0x0ef025, 0x0e903d, 0x15b059, 0x25900d, 0x35b01d, 0x15b00d, 0x0a707f, 0x40f11b, 0x0c1029, 0x23b061, 0x0c7013, 0x3b3101, 0x1d315d, 0x16108b, 0x137003, 0x15b101, 0x31d24b, 0x1bb133, 0x03b005, 0x29503d, 0x1670e9, 0x13d0ef, 0x10d067, 0x2951b1, 0x2a5125, 0x33b287, 0x29317f, 0x10f0a7, 0x1fd06b, 0x2c50bf, 0x2cf1f7, 0x2ab089, 0x3a91d3, 0x185017, 0x10103d, 0x3292e7, 0x22d14b, 0x223119, 0x0d3013, 0x283265, 0x13d03d, 0x397161, 0x14b133, 0x125007, 0x08301d, 0x15d043, 0x0c10a3, 0x185065, 0x277013, 0x377335, 0x071025, 0x1150a7, 0x1e70f1, 0x16101d, 0x199065, 0x2f910f, 0x04900b, 0x0b3061, 0x1b70ad, 0x52f16f, 0x03d00d, 0x359139, 0x1c9137, 0x1190e3, 0x17b14b, 0x2ef097, 0x06b04f, 0x089071, 0x1510b5, 0x03d007, 0x269065, 0x4ff133, 0x1b709d, 0x469313, 0x3f5161, 0x08b089, 0x07f02f, 0x14b01d, 0x1bb025, 0x2090c1, 0x1a515b, 0x1c1029, 0x01300b, 0x31d2e3, 0x2b3283, 0x42526b, 0x25921d, 0x1c91c1, 0x175107, 0x347067, 0x14b0b3, 0x08300b, 0x1610b5, 0x10d005, 0x1010b5, 0x02b011, 0x45d0b5, 0x335071, 0x0ef0c5, 0x04303d, 0x15b043, 0x2bd007, 0x2e32d7, 0x23b15d, 0x0b3047, 0x3472e7, 0x043025, 0x0c5005, 0x32b0ad, 0x1750c5, 0x3731fd, 0x10d03b, 0x29317b, 0x08b02f, 0x2bd0fb, 0x1e7049, 0x06b025, 0x04901f, 0x151125, 0x191005, 0x11503b, 0x2b3115, 0x1370a7, 0x175061, 0x1150df, 0x1bb0e9, 0x15b049, 0x1610ef, 0x2e701f, 0x1cf06b, 0x1a30b3, 0x20b115, 0x551115, 0x2930fb, 0x42d199, 0x23b137, 0x1c10d3, 0x265241, 0x137049, 0x3cb119, 0x35f295, 0x0b5059, 0x1af18d, 0x01f017, 0x1f71c9, 0x1eb0ef, 0x15d013, 0x3b9167, 0x233151, 0x115029, 0x38b1bb, 0x08b053, 0x1cd047, 0x1150df, 0x283043, 0x13703b, 0x373167, 0x28325f, 0x08301d, 0x1fd0ad, 0x2951cd, 0x0a302f, 0x0e906b, 0x1250df, 0x1fd1f7, 0x2d7047, 0x13d00d, 0x151029, 0x071049, 0x139097, 0x0bf01f, 0x061059, 0x0f100d, 0x10d0c7, 0x047025, 0x1370d3, 0x059025, 0x17b00d, 0x10d01f, 0x241139, 0x1af06b, 0x13d053, 0x107005, 0x10f03d, 0x23b067, 0x08b089, 0x3472bd, 0x2ef0e3, 0x16f119, 0x1c109d, 0x1b7175, 0x115003, 0x2f52bd, 0x0df0c1, 0x2a1167, 0x0e5017, 0x2b30fb, 0x0c104f, 0x15110f, 0x10f06d, 0x07102b, 0x59f061, 0x06500d, 0x0ad02b, 0x0ef00d, 0x06500d, 0x0b5047, 0x17f0e5, 0x0ad053, 0x3470f1, 0x38b31d, 0x10f03d, 0x239137, 0x28100d, 0x3a1287, 0x0ad065, 0x1a314b, 0x0c1097, 0x0e3053, 0x06d067, 0x1cd067, 0x2651f7, 0x2cf17f, 0x2411af, 0x11b115, 0x27716f, 0x3011cd, 0x16108b, 0x36d0c1, 0x125043, 0x1eb133, 0x6cd683, 0x15d0e9, 0x1af017, 0x5934cf, 0x137005, 0x1d3005, 0x1250a7, 0x0fb04f, 0x42d059, 0x1fd06d, 0x335239, 0x6a335b, 0x1b1025, 0x119011, 0x16101f, 0x3a1137, 0x15b053, 0x257191, 0x13910d, 0x15103b, 0x17f17b, 0x11506d, 0x151139, 0x089067, 0x1f3119, 0x0b3011, 0x10d02f, 0x09d02f, 0x1cf01f, 0x1df191, 0x2b3137, 0x167071, 0x4b1133, 0x04700d, 0x1250ad, 0x133017, 0x13303d, 0x0f1053, 0x17f025, 0x1cf0d3, 0x44f089, 0x20b02b, 0x119007, 0x185047, 0x06b011, 0x0d304f, 0x16100b, 0x107011, 0x16708b, 0x043035, 0x2f5125, 0x115059, 0x1e70a3, 0x029005, 0x18d0df, 0x18509d, 0x16f15d, 0x3a10f1, 0x0fb043, 0x0b502f, 0x0e9005, 0x02900d, 0x017005, 0x167161, 0x0f103b, 0x06d03b, 0x27700b, 0x1cd04f, 0x40918d, 0x239047, 0x1cd059, 0x2770e5, 0x22d14b, 0x13702f, 0x0d303d, 0x0df06d, 0x31315b, 0x329301, 0x18d02b, 0x2b3115, 0x26b0e3, 0x133013, 0x04303b, 0x0bf007, 0x1250ad, 0x04701d, 0x22d0ef, 0x2d720b, 0x191133, 0x2a510f, 0x101059, 0x277107, 0x3df293, 0x03b01d, 0x14b0b5, 0x3291c9, 0x1a5011, 0x0c5067, 0x107013, 0x13301f, 0x0a300d, 0x00d005, 0x35b10f, 0x1cf199, 0x1f70bf, 0x11501f, 0x36d097, 0x101071, 0x0a7013, 0x161049, 0x17b047, 0x06d02b, 0x2411df, 0x17b025, 0x2c510f, 0x08b007, 0x1150a7, 0x0a707f, 0x1a514b, 0x06101d, 0x1f706d, 0x049025, 0x241151, 0x083013, 0x1e71bb, 0x2831c9, 0x22318d, 0x18502b, 0x1250c1, 0x2b3083, 0x24b053, 0x59f029, 0x067059, 0x17f0a3, 0x2c50a3, 0x2cf1cf, 0x139065, 0x09d025, 0x19109d, 0x1f71cd, 0x067029, 0x1370c1, 0x1250c7, 0x0ef067, 0x0a3011, 0x1910fb, 0x02f01d, 0x3590fb, 0x0e301d, 0x0e301d, 0x2a5151, 0x1d3005, 0x4451b7, 0x241089, 0x2e310f, 0x11900b, 0x1c1017, 0x1c1043, 0x0fb0e5, 0x27709d, 0x1a5035, 0x407049, 0x107005, 0x0b30ad, 0x13d00d, 0x26b083, 0x1eb029, 0x1cd167, 0x1e70e5, 0x35f2ab, 0x0e3043, 0x09d043, 0x053017, 0x161067, 0x1c9083, 0x14b025, 0x1cf119, 0x1af083, 0x4453fd, 0x42d3fd, 0x21d1a5, 0x3ad03d, 0x14b01f, 0x017013, 0x2bd1cf, 0x373083, 0x3df15b, 0x1cf02b, 0x059035, 0x265137, 0x10706d, 0x02901f, 0x161007, 0x4c732b, 0x4631af, 0x259191, 0x2ab133, 0x2dd053, 0x18d0d3, 0x1c1089, 0x0a3049, 0x17f14b, 0x3fb013, 0x32b269, 0x3fd10f, 0x419059, 0x0f1035, 0x24b11b, 0x16101d, 0x1e713d, 0x059005, 0x3b933b, 0x08307f, 0x15d151, 0x119059, 0x0ef025, 0x137013, 0x1c1059, 0x0b3053, 0x16f049, 0x4b1151, 0x4551eb, 0x11b03d, 0x4c103d, 0x10f005, 0x1cf0e5, 0x41918d, 0x223199, 0x0e50c1, 0x2ef0b3, 0x14b005, 0x0c101d, 0x11b095, 0x33520b, 0x0e906d, 0x15b0c7, 0x35523b, 0x35f115, 0x44f22d, 0x17b0e5, 0x1510c1, 0x08b061, 0x3351cd, 0x3f5137, 0x1eb175, 0x11b047, 0x24b167, 0x0d3013, 0x409005, 0x241151, 0x0fb005, 0x3b9293, 0x0a7049, 0x059005, 0x0c5005, 0x10f0a7, 0x1c9035, 0x3e535f, 0x0df07f, 0x09d059, 0x2b306b, 0x22d049, 0x1610e3, 0x2c510d, 0x5d502f, 0x11b03d, 0x1f31bb, 0x10d0fb, 0x09700d, 0x0e300d, 0x2a108b, 0x17f03b, 0x3370c1, 0x01d017, 0x16f08b, 0x1010e5, 0x6115f3, 0x1910e9, 0x3e5335, 0x095049, 0x191043, 0x3471b1, 0x28704f, 0x0e5095, 0x0b3007, 0x265239, 0x04f049, 0x0b5061, 0x26518d, 0x25f043, 0x1d303d, 0x0d3065, 0x1df0c5, 0x0e50a7, 0x17b15d, 0x115061, 0x1850a3, 0x04702f, 0x17b0e9, 0x3d7355, 0x28108b, 0x25f1d3, 0x1af005, 0x05900d, 0x03d00d, 0x13d025, 0x17f0e5, 0x22d01d, 0x24107f, 0x2f90df, 0x4811b1, 0x1370fb, 0x095035, 0x283017, 0x5772f9, 0x0a3071, 0x14b0a3, 0x11b04f, 0x2a5175, 0x137095, 0x28d083, 0x3050d3, 0x0e3095, 0x1eb0c7, 0x139107, 0x2331a5, 0x0a3005, 0x089025, 0x26515b, 0x4eb3e5, 0x265067, 0x1b10df, 0x0ef0bf, 0x1510d3, 0x0c708b, 0x1850b5, 0x3592a1, 0x199005, 0x025013, 0x11906b, 0x0d3071, 0x2cf13d, 0x06d061, 0x3ad01f, 0x301061, 0x3f501d, 0x035025, 0x1bb059, 0x257047, 0x239151, 0x2a1101, 0x1af137, 0x3971cd, 0x03b005, 0x2ef1b7, 0x241199, 0x02f01f, 0x0e9025, 0x0e901f, 0x371175, 0x1370d3, 0x2e32b3, 0x0a3025, 0x1b10ef, 0x07f02f, 0x1f3059, 0x0c5025, 0x1a5047, 0x0c501f, 0x35f329, 0x259257, 0x4c7053, 0x07f061, 0x1b700b, 0x1390c5, 0x1af191, 0x1f706b, 0x38b313, 0x359029, 0x2e7047, 0x3710a7, 0x2930b3, 0x28700d, 0x0a300d, 0x0a303d, 0x209011, 0x191175, 0x09d03d, 0x18d061, 0x17b0d3, 0x15b0e3, 0x2bd005, 0x26b0bf, 0x2c50e3, 0x0f1059, 0x13908b, 0x049025, 0x053029, 0x067043, 0x15d02b, 0x0fb06b, 0x08901f, 0x2ef017, 0x0d307f, 0x2a5125, 0x653427, 0x007005, 0x20915d, 0x301167, 0x7615a7, 0x0c102f, 0x301125, 0x409097, 0x377025, 0x06b00b, 0x01100b, 0x24b097, 0x1e70e5, 0x2a5067, 0x0a303b, 0x06103b, 0x2e7283, 0x347017, 0x0c7035, 0x0b3007, 0x36d1b7, 0x7bb6b9, 0x3590e9, 0x12510f, 0x329269, 0x07f043, 0x4191b7, 0x2811b1, 0x10102b, 0x287029, 0x18506b, 0x36d161, 0x3c7061, 0x36d035, 0x33d07f, 0x17b0e3, 0x3472dd, 0x16f059, 0x08300b, 0x0ef01d, 0x3012ab, 0x17500d, 0x03d005, 0x20918d, 0x18d03d, 0x04f02b, 0x13301d, 0x265047, 0x3fb313, 0x2cf0ad, 0x02b011, 0x083071, 0x3ad265, 0x2a1071, 0x1cf0f1, 0x2dd083, 0x1c1151, 0x013007, 0x21d1f7, 0x10d0a3, 0x2810a7, 0x3350df, 0x13d0fb, 0x24b0c5, 0x359029, 0x27710f, 0x0d3025, 0x0c503d, 0x2a11c9, 0x3f11b7, 0x0bf059, 0x1070c5, 0x25f199, 0x083049, 0x1df01d, 0x209035, 0x1a50ad, 0x18d10d, 0x2230c5, 0x281047, 0x2f91a5, 0x0ef06d, 0x071007, 0x1a3017, 0x0b509d, 0x119107, 0x049047, 0x24b15b, 0x02b003, 0x42d335, 0x061011, 0x1b1059, 0x1e704f, 0x1a317b, 0x3d71d3, 0x1bb15b, 0x1010df, 0x14b02b, 0x061005, 0x17f02f, 0x1c901d, 0x16f043, 0x13d0f1, 0x15d017, 0x23b239, 0x3051f7, 0x1af011, 0x1b1061, 0x101097, 0x01d00d, 0x4fd481, 0x13d0e3, 0x1b1151, 0x1af059, 0x06b025, 0x0f1097, 0x15b139, 0x24b09d, 0x35f20b, 0x23b1c1, 0x04900d, 0x101061, 0x1b70fb, 0x07f061, 0x4fd1df, 0x1150e5, 0x15101d, 0x1370ad, 0x17b0fb, 0x10f08b, 0x04f025, 0x0ad06d, 0x0bf071, 0x1df0f1, 0x62b26b, 0x1a3097, 0x115067, 0x0a3089, 0x04f007, 0x5d5277, 0x17b00d, 0x2e300d, 0x1a3101, 0x1d3097, 0x25f1b7, 0x09508b, 0x0f1047, 0x011005, 0x4190c1, 0x1a3115, 0x49d161, 0x0c50b5, 0x007005, 0x3f1035, 0x18d01d, 0x1fd0e9, 0x36d151, 0x0e300b, 0x21d119, 0x15d03d, 0x10104f, 0x3b32f5, 0x48b1bb, 0x44f097, 0x095005, 0x1cf10d, 0x191071, 0x2690b3, 0x37106b, 0x5151d3, 0x03b011, 0x139043, 0x089029, 0x2f90b5, 0x199025, 0x061005, 0x10d02b, 0x21d18d, 0x043005, 0x059049, 0x071059, 0x05901d, 0x23900d, 0x449175, 0x04f007, 0x28306b, 0x16103d, 0x0e9043, 0x04302b, 0x15d043, 0x1d31af, 0x17502b, 0x1a510f, 0x3f5359, 0x17b175, 0x2570a7, 0x1df199, 0x0bf049, 0x1750c5, 0x1c1107, 0x2dd1cf, 0x2d71b1, 0x1b71af, 0x06b01f, 0x059005, 0x11903d, 0x10d01d, 0x269029, 0x3ad083, 0x2090d3, 0x083047, 0x0b5003, 0x19110d, 0x059005, 0x13303b, 0x11b07f, 0x2f513d, 0x25f06b, 0x1bb053, 0x13300d, 0x1610e3, 0x0fb0a7, 0x089011, 0x1b71af, 0x1af17f, 0x04902b, 0x2d70e5, 0x02501d, 0x31d2dd, 0x07f035, 0x2810c7, 0x2690b3, 0x3b9335, 0x151035, 0x1a5185, 0x137067, 0x287097, 0x2b303b, 0x1bb107, 0x061043, 0x043005, 0x26911b, 0x3d71cf, 0x101005, 0x38f25f, 0x065025, 0x1bb097, 0x0ad02b, 0x371167, 0x0df035, 0x28113d, 0x1370c1, 0x1cf0df, 0x10f005, 0x175071, 0x18d01d, 0x09d00d, 0x3c70a7, 0x0c10b3, 0x0e308b, 0x25f167, 0x0a707f, 0x07f017, 0x13d00d, 0x1eb1d3, 0x2c51a3, 0x2cf083, 0x241095, 0x02f013, 0x1e7161, 0x2390f1, 0x09703d, 0x115061, 0x1b7119, 0x313209, 0x08306d, 0x0b5049, 0x5fb2c5, 0x1df139, 0x095047, 0x16f017, 0x23b1b1, 0x1df10f, 0x25f23b, 0x31d0ad, 0x1510d3, 0x15b061, 0x2e3283, 0x1f700d, 0x059029, 0x397107, 0x1cf0e9, 0x1610ef, 0x0fb059, 0x1fd15d, 0x14b0a3, 0x0fb071, 0x095065, 0x209199, 0x06503b, 0x25f02f, 0x0b3061, 0x4a30b3, 0x10d0f1, 0x0c7089, 0x419119, 0x133125, 0x2391fd, 0x1bb06b, 0x0ad0a7, 0x1070e5, 0x10f0f1, 0x1fd06d, 0x2f92dd, 0x24114b, 0x13300d, 0x3131c1, 0x1b109d, 0x3df0df, 0x0a3067, 0x3f138b, 0x1f3083, 0x08b025, 0x09d025, 0x185107, 0x1f3071, 0x2510a3, 0x3012e3, 0x04f003, 0x095071, 0x1f7061, 0x18d01d, 0x2770e9, 0x1bb191, 0x1d309d, 0x139071, 0x1cd011, 0x3cb139, 0x2c5005, 0x1f71df, 0x4eb1b1, 0x07100b, 0x0e309d, 0x08900d, 0x1070fb, 0x11900d, 0x5ad223, 0x06500d, 0x10703d, 0x0c703b, 0x269059, 0x49d31d, 0x1370c7, 0x3b32cf, 0x59300d, 0x25f1eb, 0x1cd0d3, 0x8db1f3, 0x23300d, 0x10d01d, 0x26b047, 0x18d005, 0x19115b, 0x24115d, 0x1cf017, 0x20b1f7, 0x2ab269, 0x05300d, 0x06d00d, 0x1cf185, 0x15b139, 0x2dd047, 0x295005, 0x0d309d, 0x29515d, 0x18d08b, 0x133067, 0x2cf053, 0x4cf0e3, 0x0fb025, 0x55d463, 0x28d029, 0x04f03d, 0x0b507f, 0x2e3053, 0x10d0f1, 0x1bb139, 0x4a90b5, 0x1a303d, 0x24b003, 0x1c101d, 0x2c506b, 0x0c5025, 0x08300d, 0x4ff133, 0x18d095, 0x0df07f, 0x301005, 0x1b101f, 0x12501f, 0x359337, 0x16f053, 0x2ef295, 0x28110f, 0x50915b, 0x11b095, 0x04701d, 0x05303d, 0x3e5167, 0x277259, 0x259071, 0x083035, 0x07104f, 0x1af10f, 0x139107, 0x17b013, 0x2c52a5, 0x277199, 0x3c7071, 0x10f02f, 0x1f30df, 0x16703b, 0x1af15b, 0x241065, 0x28300d, 0x0bf083, 0x0c502b, 0x053035, 0x191013, 0x0d30b5, 0x2ab14b, 0x2a51bb, 0x2f518d, 0x27710d, 0x1b715d, 0x2690a7, 0x02501f, 0x3b90f1, 0x277125, 0x095013, 0x053025, 0x2c521d, 0x16711b, 0x1a511b, 0x32b01d, 0x2f50ef, 0x3cb1f3, 0x1f3137, 0x0c701d, 0x0e90e3, 0x355025, 0x15b137, 0x0c1005, 0x1010d3, 0x1c110d, 0x20b199, 0x1a5167, 0x25f0e3, 0x0ad089, 0x09d00d, 0x09d07f, 0x32b107, 0x0a302b, 0x2a101d, 0x151083, 0x0c702f, 0x01100d, 0x25f199, 0x0e502b, 0x1150bf, 0x1cf00d, 0x57740f, 0x03d035, 0x1f71a5, 0x1330e3, 0x08902f, 0x443191, 0x16f0e9, 0x3f501d, 0x1b1005, 0x2bd0c7, 0x9fd949, 0x0df0ad, 0x2871fd, 0x0c100d, 0x0c700d, 0x3130ef, 0x1a50df, 0x5ab2a1, 0x161137, 0x17b06b, 0x08900d, 0x0ef0c7, 0x25700b, 0x08901f, 0x26502b, 0x0c50ad, 0x0df03d, 0x18507f, 0x2951df, 0x1250bf, 0x1f718d, 0x1df15d, 0x1850a3, 0x1f703b, 0x09500b, 0x37100d, 0x1eb1e7, 0x1e7167, 0x28111b, 0x133101, 0x3cb1e7, 0x02b007, 0x0a3089, 0x095013, 0x2a1067, 0x28317b, 0x1a5115, 0x17b013, 0x18d185, 0x0c50a7, 0x1370fb, 0x301293, 0x26916f, 0x44f2ef, 0x10f089, 0x1d30e9, 0x3ad0d3, 0x2f9035, 0x3fb18d, 0x1c1199, 0x08b025, 0x10101d, 0x29306b, 0x06b007, 0x0bf011, 0x1cd0e3, 0x26b083, 0x1fd017, 0x25f107, 0x19104f, 0x2a10c1, 0x1330e3, 0x5511e7, 0x11500d, 0x3d7397, 0x33501d, 0x0ad02f, 0x1bb059, 0x2571bb, 0x35f26b, 0x17f059, 0x0c7067, 0x259101, 0x511107, 0x17b0d3, 0x2f92c5, 0x175119, 0x049003, 0x1df137, 0x167059, 0x2090c5, 0x067043, 0x3010fb, 0x101011, 0x23b1cf, 0x32b287, 0x17f10f, 0x161053, 0x133029, 0x199115, 0x0b50b3, 0x0f1003, 0x3050e9, 0x1c10e3, 0x185101, 0x1850e9, 0x0fb011, 0x1a301d, 0x3fb329, 0x26525f, 0x2830ef, 0x0fb0ef, 0x76103d, 0x3972e3, 0x0a300b, 0x2c5053, 0x5fb10d, 0x42d3fd, 0x623005, 0x0fb06d, 0x15b02b, 0x0ef01d, 0x1f3167, 0x2cf16f, 0x3a915d, 0x241115, 0x0df065, 0x5113e5, 0x0c70c5, 0x083017, 0x0e30b5, 0x19103d, 0x1a30f1, 0x2690fb, 0x00d003, 0x17f17b, 0x20b1fd, 0x3052a5, 0x16706d, 0x371025, 0x21d1fd, 0x12502f, 0x1010df, 0x0f102b, 0x427013, 0x373257, 0x167029, 0x09d049, 0x5d10ef, 0x1cd10f, 0x2d7047, 0x0f100d, 0x1eb06b, 0x0c70c1, 0x295049, 0x029007, 0x1fd049, 0x287125, 0x1bb125, 0x1150fb, 0x25100d, 0x2ef083, 0x06503b, 0x50b313, 0x1a3059, 0x0e50e3, 0x13d02b, 0x02900d, 0x017013, 0x06b00b, 0x23b01d, 0x09503d, 0x2f515d, 0x03d00b, 0x28d1eb, 0x11908b, 0x1df061, 0x1910ef, 0x1010a7, 0x1c9185, 0x161133, 0x061043, 0x1b1005, 0x0a7089, 0x0e30b5, 0x0e3005, 0x1cf0c1, 0x06b067, 0x0bf07f, 0x0e906b, 0x8f95f3, 0x30510d, 0x0df01d, 0x10d029, 0x1d3029, 0x07f005, 0x21d07f, 0x23b223, 0x10107f, 0x10f0c1, 0x3fd0df, 0x301139, 0x20b095, 0x0a7011, 0x0e90c1, 0x1a3083, 0x20b0c7, 0x07f00d, 0x26b0e5, 0x083047, 0x269101, 0x053011, 0x06b053, 0x21d119, 0x1990ad, 0x2f52b3, 0x1b1083, 0x2bd083, 0x241209, 0x185167, 0x0e308b, 0x38f199, 0x07f00d, 0x3010b3, 0x0e50b5, 0x1e7029, 0x2390e9, 0x22d0c5, 0x26516f, 0x3b301f, 0x05902f, 0x19117f, 0x3a1281, 0x0d3043, 0x2dd0a3, 0x185007, 0x095005, 0x2690a7, 0x09700d, 0x0bf01f, 0x115029, 0x17b139, 0x2a113d, 0x1f709d, 0x15d10d, 0x1070df, 0x09503d, 0x1c10b3, 0x1eb005, 0x28d137, 0x02b029, 0x175071, 0x3291d3, 0x3b909d, 0x607293, 0x2dd11b, 0x251005, 0x259043, 0x1c107f, 0x115025, 0x2510c5, 0x4cf0a7, 0x1af0e5, 0x1a5007, 0x26510f, 0x22d1e7, 0x137049, 0x2410d3, 0x3fd335, 0x371049, 0x22d0c5, 0x1eb17f, 0x25f259, 0x3e5101, 0x3970e3, 0x24b025, 0x4e117b, 0x233191, 0x10f0e9, 0x11900b, 0x0a706b, 0x01f013, 0x0fb061, 0x28109d, 0x0c10a3, 0x35b067, 0x15d09d, 0x2650ad, 0x1b104f, 0x0bf01f, 0x52725f, 0x08b005, 0x07f02f, 0x337239, 0x10d061, 0x0a3005, 0x0e30c7, 0x025003, 0x0e50b3, 0x0fb02f, 0x371241, 0x15d0c5, 0x529377, 0x1f3025, 0x19900d, 0x223133, 0x3552d7, 0x18516f, 0x14b0a3, 0x1b10c1, 0x4190d3, 0x5ad3fd, 0x35f26b, 0x09706d, 0x06d005, 0x1070a3, 0x0c700b, 0x067005, 0x599005, 0x03d013, 0x089047, 0x4cd047, 0x0ad025, 0x3d71c9, 0x0c7049, 0x2ef0bf, 0x08902b, 0x2f9025, 0x191053, 0x071035, 0x1eb017, 0x08b061, 0x1f30a3, 0x1af0d3, 0x01d017, 0x0b500d, 0x01d005, 0x3c7083, 0x13d06d, 0x1b7095, 0x05900d, 0x089049, 0x1c90df, 0x04701f, 0x1a502b, 0x1c901d, 0x3052ef, 0x10d065, 0x02f007, 0x139119, 0x1330df, 0x15d0df, 0x3b3397, 0x38f0b5, 0x1eb15d, 0x10d08b, 0x1eb09d, 0x061053, 0x1850c7, 0x18d0a3, 0x5154cd, 0x01100d, 0x33d02b, 0x03d025, 0x1f314b, 0x2e3017, 0x4630bf, 0x1a3043, 0x2ab21d, 0x03d01d, 0x3ad24b, 0x0e3025, 0x36d10d, 0x101047, 0x1b715b, 0x2a1005, 0x427083, 0x1fd139, 0x2870c5, 0x1f310d, 0x049025, 0x2a500d, 0x2950b3, 0x0e908b, 0x11b0ef, 0x28d239, 0x48b101, 0x11b0b5, 0x17f133, 0x133089, 0x06100d, 0x13d047, 0x347065, 0x15d071, 0x17b0ef, 0x2f9283, 0x1a3029, 0x053049, 0x11b0ad, 0x28d0b5, 0x2b3095, 0x083061, 0x20b161, 0x125089, 0x2510e3, 0x19914b, 0x1b716f, 0x1e702b, 0x2ab25f, 0x1a5065, 0x1c1167, 0x0d306d, 0x24b005, 0x08b00d, 0x1a50ef, 0x7eb305, 0x35f2dd, 0x0e90ad, 0x1cd025, 0x05304f, 0x22306d, 0x185025, 0x1cd10f, 0x19904f, 0x07f01d, 0x35524b, 0x097095, 0x0bf08b, 0x06100d, 0x2c5241, 0x25f02b, 0x199071, 0x08b065, 0x1af065, 0x17f065, 0x3e517b, 0x04f03b, 0x1d30a3, 0x083071, 0x41b025, 0x14b10d, 0x22d03d, 0x449397, 0x18d065, 0x2c5029, 0x16f101, 0x10d097, 0x071053, 0x251049, 0x13900d, 0x0b50b3, 0x07104f, 0x09d089, 0x313029, 0x2a5277, 0x4a3071, 0x4a3259, 0x061003, 0x4193b3, 0x2810bf, 0x34713d, 0x551425, 0x41b175, 0x3b33a9, 0x37102b, 0x03502b, 0x6a31af, 0x0c501d, 0x06500b, 0x06b059, 0x1010e5, 0x2390e9, 0x4433d1, 0x23310f, 0x0ad097, 0x1cd0e5, 0x1a5013, 0x08303b, 0x11b115, 0x1070b5, 0x1b7107, 0x07f00d, 0x1b118d, 0x1b7191, 0x4070a3, 0x38b065, 0x025017, 0x1bb029, 0x2e323b, 0x1c114b, 0x1cd10f, 0x13903b, 0x2f910d, 0x4a9449, 0x139047, 0x167125, 0x10f011, 0x35f0a7, 0x3ad1a5, 0x0c10a3, 0x16f06d, 0x2230a7, 0x2ab107, 0x1fd1eb, 0x2e3089, 0x2651fd, 0x0d3065, 0x1c9139, 0x42701d, 0x305125, 0x1cd0c5, 0x043017, 0x047005, 0x2e7059, 0x26b0b5, 0x11b0e9, 0x05300d, 0x0ad095, 0x26b0bf, 0x2691f7, 0x23916f, 0x04f011, 0x37117f, 0x097065, 0x02b00b, 0x04302b, 0x10d005, 0x35f283, 0x0b501f, 0x107043, 0x2590fb, 0x191151, 0x8bf125, 0x0a703d, 0x0e90d3, 0x265061, 0x377241, 0x043005, 0x35b029, 0x0ef02f, 0x0fb013, 0x08903b, 0x03d029, 0x1670c7, 0x097095, 0x29509d, 0x3df0ef, 0x1d31cd, 0x1b10f1, 0x11b0ad, 0x29507f, 0x00d005, 0x17b15b, 0x03b01f, 0x13910d, 0x0a3083, 0x67f3fd, 0x25111b, 0x1f71bb, 0x1390bf, 0x0bf0b3, 0x1af107, 0x40f329, 0x49d38b, 0x0b306d, 0x32b2a5, 0x083017, 0x3f5013, 0x1b103b, 0x1a500d, 0x3d12a5, 0x2a5017, 0x17f15d, 0x0e3065, 0x23302f, 0x1a511b, 0x2f5059, 0x20b011, 0x3370d3, 0x049005, 0x2cf2c5, 0x84135b, 0x05903d, 0x16101d, 0x191167, 0x0a709d, 0x0ad0a3, 0x1cd011, 0x3ad1d3, 0x137005, 0x13d0f1, 0x13703d, 0x15b0e5, 0x17506b, 0x09500d, 0x02b00b, 0x27717b, 0x24b09d, 0x02f025, 0x199095, 0x0b507f, 0x25f133, 0x011005, 0x14b029, 0x0ad059, 0x493443, 0x23901d, 0x10d03b, 0x1c1175, 0x35903d, 0x28d257, 0x08b01d, 0x137007, 0x139101, 0x1c10ad, 0x18d025, 0x06d029, 0x1150bf, 0x02b013, 0x373065, 0x0c701d, 0x24107f, 0x1a5199, 0x46906d, 0x1b10e9, 0x25f21d, 0x17b061, 0x17f0a3, 0x13d0fb, 0x095025, 0x11503d, 0x12509d, 0x15b035, 0x1b103d, 0x24b1b1, 0x0c5097, 0x2a5191, 0x0b5011, 0x08b025, 0x1850c1, 0x137125, 0x64700d, 0x083017, 0x2a1007, 0x1b10c5, 0x1b1139, 0x115025, 0x2e31eb, 0x137005, 0x20b1a5, 0x0b3089, 0x18d15d, 0x0ef09d, 0x0c103b, 0x22d01f, 0x37306b, 0x2d707f, 0x05300b, 0x125097, 0x067053, 0x26b00b, 0x0e3043, 0x0ef005, 0x05903d, 0x33d0b3, 0x065043, 0x35b0ef, 0x11b0a3, 0x11b035, 0x3a9139, 0x1d3005, 0x1c1047, 0x36d22d, 0x2330c7, 0x0ef06d, 0x107025, 0x0f106d, 0x0ef03d, 0x0bf089, 0x1b1115, 0x22d119, 0x2c525f, 0x15b139, 0x20903d, 0x071067, 0x28d18d, 0x1a5035, 0x1f3061, 0x23b01d, 0x17b0df, 0x40f241, 0x089029, 0x13310f, 0x2f9191, 0x277025, 0x0b302f, 0x15111b, 0x23b059, 0x0b5003, 0x21d00d, 0x3b91f3, 0x0e90d3, 0x655151, 0x0d3059, 0x1cd0b5, 0x0fb09d, 0x115047, 0x0b303d, 0x241059, 0x0fb02f, 0x09d08b, 0x223067, 0x053017, 0x10f083, 0x4630e3, 0x2f5107, 0x09d03b, 0x15b0e3, 0x15101d, 0x17f13d, 0x24b0c5, 0x22d049, 0x1e70e3, 0x2a115b, 0x0e500d, 0x46932b, 0x125089, 0x095061, 0x06d00d, 0x1a517b, 0x2650a7, 0x059017, 0x0f10e3, 0x1a3049, 0x06d005, 0x18d02b, 0x133095, 0x4a3071, 0x17b049, 0x2c51d3, 0x4b11c9, 0x053017, 0x287209, 0x4b12e3, 0x1f700d, 0x33d0b5, 0x52710f, 0x07103b, 0x3ad223, 0x1eb18d, 0x2e7005, 0x13308b, 0x0e9035, 0x0d3095, 0x24b005, 0x2dd0a3, 0x2770fb, 0x0b3013, 0x0a7053, 0x3712d7, 0x13901f, 0x065017, 0x065035, 0x4bd25f, 0x0a303d, 0x175095, 0x1df0b5, 0x2ef1fd, 0x0f1025, 0x26b24b, 0x3f528d, 0x1e71d3, 0x199035, 0x07f00d, 0x3290d3, 0x335223, 0x2391c9, 0x1df043, 0x1150b5, 0x0f1059, 0x11b10d, 0x137095, 0x09504f, 0x1af003, 0x11b013, 0x10d0e5, 0x1cf139, 0x15d01d, 0x0d30a7, 0x31d005, 0x11500d, 0x2c5043, 0x083049, 0x25f1f7, 0x38b2cf, 0x09704f, 0x1af17b, 0x4091fd, 0x0a301f, 0x1df097, 0x3f517f, 0x3d7239, 0x1b1065, 0x2651e7, 0x22d1a5, 0x2c50e9, 0x059013, 0x2e3251, 0x115065, 0x06700d, 0x11b0e9, 0x1df0a3, 0x1cf02f, 0x16f02b, 0x15102b, 0x1d31a5, 0x16700d, 0x16f107, 0x199059, 0x125025, 0x38f1a3, 0x1a3139, 0x17500d, 0x337305, 0x40f3b3, 0x287005, 0x061035, 0x095025, 0x2f92a1, 0x09d095, 0x097047, 0x65b191, 0x011005, 0x1af0f1, 0x01f005, 0x4191fd, 0x16f095, 0x1c1035, 0x3d70b5, 0x13700d, 0x2571fd, 0x2c5199, 0x0e9059, 0x13d059, 0x09d03d, 0x25116f, 0x1b7107, 0x089017, 0x1010a7, 0x1cf071, 0x18d059, 0x15d09d, 0x4091c9, 0x4430fb, 0x455301, 0x1c1191, 0x2f506b, 0x4c70ef, 0x599265, 0x32915b, 0x05302f, 0x26910f, 0x097029, 0x089025, 0x13d067, 0x18d0c5, 0x10d029, 0x095067, 0x1c1067, 0x301233, 0x1c109d, 0x43f107, 0x0b3005, 0x2f5025, 0x0fb0e5, 0x5d53d7, 0x24b21d, 0x59f3f5, 0x209035, 0x16110f, 0x1b1011, 0x23b0c5, 0x25908b, 0x03b005, 0x6231af, 0x2ab139, 0x3d11c9, 0x04903d, 0x0ad08b, 0x257191, 0x3a124b, 0x2cf0ef, 0x1a30a7, 0x1910df, 0x1af0e5, 0x0f10ef, 0x20b005, 0x1f30ad, 0x151133, 0x2a5071, 0x251025, 0x257167, 0x0a303d, 0x1bb11b, 0x5ad00d, 0x2ef107, 0x2231a5, 0x17b089, 0x1370c5, 0x07f03b, 0x15d10d, 0x33d0ad, 0x13d047, 0x119059, 0x19904f, 0x18d167, 0x12500d, 0x03500d, 0x2f9283, 0x065035, 0x15d035, 0x0b5053, 0x137097, 0x23b0e5, 0x2ab04f, 0x04f049, 0x161059, 0x0c500d, 0x139083, 0x0a3071, 0x101043, 0x191017, 0x1c102b, 0x25f1b7, 0x2ef25f, 0x17f083, 0x2e309d, 0x11b04f, 0x133029, 0x199061, 0x2331e7, 0x1010a3, 0x1b702f, 0x45d0df, 0x06d00b, 0x2a51e7, 0x04f025, 0x0d3061, 0x1fd089, 0x31d293, 0x1a313d, 0x061049, 0x11903d, 0x125071, 0x38b04f, 0x21d0e9, 0x191025, 0x1c90d3, 0x03d035, 0x1a303b, 0x0f1013, 0x1af125, 0x1330a7, 0x17f0b5, 0x0c70c5, 0x1af067, 0x09d06b, 0x25114b, 0x13d0e5, 0x071005, 0x45d13d, 0x10d04f, 0x3010a7, 0x175083, 0x33703d, 0x059005, 0x07f043, 0x239043, 0x071047, 0x07103d, 0x25f115, 0x06d025, 0x0e501d, 0x1f70d3, 0x0c104f, 0x1f300d, 0x1e71b7, 0x3d1059, 0x26b0ef, 0x199071, 0x0b30ad, 0x167005, 0x11b00d, 0x06703d, 0x31d16f, 0x15b01d, 0x15d013, 0x125049, 0x25f00b, 0x1e716f, 0x277053, 0x14b02f, 0x0ad049, 0x15b101, 0x0e9047, 0x551101, 0x27706b, 0x08301f, 0x23314b, 0x0c1059, 0x029013, 0x1a517b, 0x0e50bf, 0x2dd1c1, 0x0c104f, 0x17b061, 0x23317b, 0x1e710f, 0x6a3083, 0x043017, 0x287209, 0x3a11eb, 0x17b065, 0x089067, 0x58f397, 0x0df0bf, 0x3ad33b, 0x2c5191, 0x095053, 0x2dd025, 0x0fb035, 0x1f7089, 0x06103d, 0x0c1047, 0x029011, 0x0ad061, 0x1cf1af, 0x0c109d, 0x0c101f, 0x0c5049, 0x269107, 0x25903b, 0x23914b, 0x02b01d, 0x0c1083, 0x10d0a7, 0x2a1101, 0x2650a7, 0x27715b, 0x2411df, 0x17f035, 0x0e9097, 0x04f02b, 0x14b10d, 0x31d2c5, 0x13d09d, 0x2b3161, 0x02900b, 0x1070b5, 0x2f9059, 0x1390ef, 0x0bf06b, 0x2511b7, 0x373025, 0x5d1107, 0x1bb1a3, 0x13307f, 0x1c9185, 0x419407, 0x1cf0ad, 0x3e516f, 0x04902b, 0x22d0f1, 0x16f107, 0x11901f, 0x0a700d, 0x05902f, 0x2e3175, 0x2e30f1, 0x25715d, 0x4ff029, 0x10f0ef, 0x1f306d, 0x0c50b3, 0x15b005, 0x071065, 0x107101, 0x17f167, 0x1a30b3, 0x18d059, 0x18d0ef, 0x0d3029, 0x3732ab, 0x1b70e9, 0x1cf0df, 0x1a5029, 0x0bf04f, 0x10708b, 0x1a30c5, 0x2931f3, 0x31d28d, 0x10d00b, 0x04702f, 0x1b7185, 0x28d035, 0x0e9095, 0x0e5053, 0x1df18d, 0x1850ef, 0x0f1017, 0x175053, 0x0c7005, 0x3711cf, 0x19117f, 0x04901f, 0x35903b, 0x02500d, 0x067029, 0x18d067, 0x13d115, 0x14b00d, 0x281137, 0x11b011, 0x1df005, 0x2cf295, 0x28d06d, 0x239223, 0x265007, 0x1cf089, 0x1b10ad, 0x28324b, 0x06d061, 0x0ef065, 0x0b3097, 0x28701f, 0x0b3003, 0x0b306d, 0x13d061, 0x257061, 0x2e31af, 0x1e7067, 0x24108b, 0x11b06b, 0x1af067, 0x0d3013, 0x0f1017, 0x25110d, 0x1070a3, 0x14b035, 0x071005, 0x17510d, 0x0f1083, 0x049035, 0x22d083, 0x167151, 0x0d3065, 0x4ff3c7, 0x23b15d, 0x1bb115, 0x0a3061, 0x4252b3, 0x06b011, 0x14b101, 0x31303b, 0x0e9053, 0x1010ad, 0x097007, 0x1e7089, 0x13d0a7, 0x07106b, 0x2571df, 0x139005, 0x33d2ef, 0x2f9025, 0x16f0b5, 0x18d17b, 0x0e90c1, 0x097025, 0x425347, 0x3a90c7, 0x35b259, 0x1af00d, 0x1bb199, 0x067017, 0x09d02b, 0x0e500d, 0x20b09d, 0x0c502b, 0x0fb065, 0x139065, 0x1b718d, 0x2691a3, 0x09d061, 0x1c1047, 0x017005, 0x18d14b, 0x3011c1, 0x15b00b, 0x1390b3, 0x0b5043, 0x06502f, 0x107101, 0x10d061, 0x167065, 0x0f106d, 0x0e5065, 0x1c9089, 0x43f407, 0x03b00d, 0x137035, 0x133013, 0x2b31b7, 0x043035, 0x083005, 0x10d025, 0x083035, 0x11b115, 0x5f3049, 0x0e302f, 0x15b0bf, 0x233199, 0x0e9035, 0x40911b, 0x2a1151, 0x06d01d, 0x31d239, 0x161119, 0x0c10ad, 0x0df067, 0x065029, 0x1c1139, 0x06700d, 0x059017, 0x41b061, 0x1a5013, 0x16f03d, 0x1f714b, 0x2c5139, 0x2811c9, 0x2e30fb, 0x11b035, 0x31323b, 0x1070e5, 0x05301d, 0x3010a3, 0x0b3047, 0x60d1fd, 0x1c903d, 0x10f047, 0x16703b, 0x053029, 0x0bf06b, 0x1d303b, 0x14b10d, 0x047043, 0x4b10c7, 0x15d139, 0x0f107f, 0x23902b, 0x19903b, 0x11b03d, 0x1b109d, 0x3b9089, 0x23906b, 0x16f107, 0x4a914b, 0x161097, 0x0e900d, 0x1f30ef, 0x1fd053, 0x1190b3, 0x1b102b, 0x2691d3, 0x08b049, 0x2a520b, 0x0c1017, 0x305065, 0x095089, 0x0fb02f, 0x28d0a3, 0x199089, 0x283059, 0x30516f, 0x20b01f, 0x0fb03b, 0x175067, 0x2e31cd, 0x0a3043, 0x2ef241, 0x0a70a3, 0x32b301, 0x36d17f, 0x1330ad, 0x3a12ef, 0x08b06d, 0x1cd0c1, 0x133049, 0x28d133, 0x133029, 0x13d00d, 0x23b0e3, 0x11509d, 0x2cf065, 0x1d30b3, 0x06d00b, 0x5ad3b9, 0x15d107, 0x0c7005, 0x1f31a3, 0x11b115, 0x2411c1, 0x0f10c5, 0x33d049, 0x28311b, 0x2771cd, 0x03d03b, 0x22d09d, 0x139025, 0x1750e9, 0x31d0c1, 0x199089, 0x08b025, 0x06d025, 0x329259, 0x2a10c7, 0x0c1097, 0x2a11cf, 0x10f00b, 0x2a110f, 0x2e317f, 0x3cb35b, 0x5930df, 0x59935b, 0x20b047, 0x21d133, 0x029011, 0x1af139, 0x3550df, 0x097043, 0x22d223, 0x29315b, 0x24b007, 0x209003, 0x15d017, 0x11506d, 0x0df047, 0x3a91bb, 0x21d133, 0x269025, 0x2570e3, 0x2391cf, 0x18d00d, 0x137005, 0x06b047, 0x1010ef, 0x15106d, 0x233035, 0x36d1c1, 0x0b3005, 0x2e7199, 0x3ad043, 0x1b70b3, 0x2c503b, 0x6554c7, 0x10d04f, 0x1f3199, 0x0f1071, 0x15d00d, 0x33b0a7, 0x25f1c9, 0x2811b7, 0x191049, 0x0a7053, 0x1c1053, 0x2f9029, 0x0e3067, 0x14b029, 0x3f10c1, 0x283277, 0x1f71bb, 0x17501f, 0x07f071, 0x107013, 0x2411bb, 0x15d151, 0x25906d, 0x2c50c1, 0x2ef295, 0x1c102b, 0x151067, 0x33b13d, 0x06b04f, 0x1f31c1, 0x25f151, 0x32b265, 0x281139, 0x10d0e3, 0x14b0f1, 0x20b0b5, 0x04301d, 0x50b469, 0x185089, 0x035003, 0x047017, 0x08906d, 0x25f1b7, 0x3fb043, 0x10f0b3, 0x11500d, 0x0bf0a7, 0x20b1d3, 0x115029, 0x1250e3, 0x3b30e9, 0x061011, 0x5b3185, 0x0df00d, 0x0d3043, 0x04303b, 0x2e309d, 0x3cb283, 0x133035, 0x1a50c5, 0x1b7025, 0x0a3071, 0x2d7061, 0x4431b7, 0x151005, 0x39710f, 0x11b0a3, 0x34733b, 0x5573fd, 0x4d5371, 0x08900d, 0x06b043, 0x5bf33b, 0x265175, 0x1bb125, 0x0c7005, 0x19914b, 0x233191, 0x269119, 0x07f059, 0x0ad06d, 0x2dd067, 0x1df137, 0x1b10bf, 0x1df11b, 0x2a1095, 0x11901d, 0x0f10a3, 0x5cf017, 0x125007, 0x1cd013, 0x09d011, 0x23b1a5, 0x089067, 0x1b100d, 0x0c502f, 0x3fb2a5, 0x1510f1, 0x43f0b5, 0x493455, 0x161035, 0x03502b, 0x08b07f, 0x16f00d, 0x2bd0b3, 0x09d061, 0x1c11b7, 0x257161, 0x2571bb, 0x1a515d, 0x049017, 0x3050c7, 0x119083, 0x42d0a3, 0x2ef281, 0x139095, 0x1370df, 0x2dd00d, 0x10104f, 0x139097, 0x23b1c9, 0x0c7005, 0x0e30b5, 0x1af00d, 0x1010e5, 0x185133, 0x0ef0bf, 0x14b097, 0x29502b, 0x09706b, 0x38b22d, 0x09700d, 0x28726b, 0x2f517f, 0x42524b, 0x0b3043, 0x2390e9, 0x0d302f, 0x10f071, 0x08903d, 0x2ef133, 0x22d01f, 0x2bd259, 0x32b281, 0x33d005, 0x6072bd, 0x199119, 0x1fd119, 0x3a110d, 0x1c1043, 0x06503b, 0x167035, 0x03d035, 0x1cf16f, 0x0ad089, 0x269233, 0x287061, 0x0d3005, 0x1e7107, 0x2a503b, 0x01d00b, 0x06501d, 0x09d043, 0x28117b, 0x08b07f, 0x03d01f, 0x2930a7, 0x10f0c7, 0x1c916f, 0x06d01f, 0x18d151, 0x15d0bf, 0x107049, 0x04f005, 0x28d1b7, 0x3290e5, 0x2f9277, 0x0b5047, 0x1df0e9, 0x071005, 0x50b1a5, 0x3472f5, 0x04903d, 0x1d302f, 0x175137, 0x2f906b, 0x0fb07f, 0x1fd043, 0x7276f7, 0x17b06b, 0x2e7257, 0x21d0e5, 0x18d04f, 0x0a301d, 0x2dd209, 0x0e508b, 0x17f14b, 0x15d115, 0x239071, 0x2871b7, 0x20b0b5, 0x17f0bf, 0x1fd0e5, 0x65510d, 0x1fd0e3, 0x4ff4a3, 0x2390ef, 0x36d1c1, 0x21d0c5, 0x1c10e3, 0x04701f, 0x31d1af, 0x51b161, 0x2a5119, 0x0a7089, 0x2a10d3, 0x04301d, 0x2691c9, 0x047035, 0x3710b3, 0x2771af, 0x05900d, 0x0a3061, 0x48b47f, 0x1f31b1, 0x18d03b, 0x31d011, 0x17b017, 0x78b337, 0x1bb00d, 0x1df133, 0x17b06b, 0x3d1011, 0x301191, 0x09d097, 0x09d071, 0x1bb175, 0x1cd03d, 0x1c907f, 0x191025, 0x25716f, 0x23903b, 0x595007, 0x17b0c7, 0x4cd0bf, 0x241071, 0x2ef1f7, 0x22d0a7, 0x083043, 0x60738b, 0x0b3025, 0x1f3097, 0x2091a5, 0x26b251, 0x0c701d, 0x37714b, 0x0e503b, 0x08b07f, 0x083035, 0x0b3011, 0x1af0df, 0x1070c7, 0x29517f, 0x305005, 0x11900d, 0x449337, 0x3d702b, 0x089025, 0x0d3043, 0x24b1c9, 0x33b00d, 0x13d06b, 0x0ad09d, 0x2f901d, 0x4093ad, 0x139095, 0x1d3059, 0x17f10d, 0x06700d, 0x0a3061, 0x20b133, 0x0e5089, 0x4eb1e7, 0x07f035, 0x1f31df, 0x15b0e3, 0x15d0a3, 0x1f30c1, 0x0d3097, 0x17f00b, 0x1a3101, 0x18d043, 0x2a503d, 0x4fd101, 0x21d0e9, 0x20b0f1, 0x167115, 0x2d7067, 0x1610e5, 0x1fd1c1, 0x36d241, 0x15b0ef, 0x14b005, 0x17b005, 0x1fd15d, 0x45d005, 0x2ab15b, 0x0bf059, 0x1f30fb, 0x1cd1b1, 0x0c104f, 0x29303b, 0x0b3067, 0x10103d, 0x5150a3, 0x2571eb, 0x0a3095, 0x0a3035, 0x18d133, 0x0df067, 0x13d0bf, 0x2510ad, 0x1bb161, 0x1b709d, 0x1af00d, 0x1d3013, 0x4a92dd, 0x0df0a7, 0x0e90a3, 0x3590fb, 0x3371eb, 0x2a11b7, 0x0f108b, 0x3b310f, 0x377167, 0x277167, 0x07f005, 0x3a102f, 0x1df10d, 0x05904f, 0x025013, 0x175167, 0x19118d, 0x3a115b, 0x359239, 0x0c704f, 0x0fb02f, 0x191151, 0x0a308b, 0x4430ad, 0x185115, 0x09508b, 0x3472dd, 0x17f15b, 0x10f047, 0x0e500d, 0x38f1cf, 0x0a3011, 0x1610b5, 0x27710d, 0x14b03d, 0x257003, 0x16700b, 0x0bf0ad, 0x329209, 0x3291a3, 0x209191, 0x1a503b, 0x151047, 0x05303d, 0x0e5071, 0x16102b, 0x0b5067, 0x4a9107, 0x1b116f, 0x175025, 0x089005, 0x25710d, 0x65343f, 0x3f11a5, 0x329133, 0x23b119, 0x1b101d, 0x1cd065, 0x0a7067, 0x185151, 0x1b1065, 0x27717b, 0x21d139, 0x3d733b, 0x23902f, 0x28717b, 0x1af0fb, 0x03b007, 0x1c1191, 0x0ad01f, 0x257239, 0x3e52cf, 0x4a92a1, 0x1bb137, 0x3a11cd, 0x06d017, 0x0e9005, 0x1a3139, 0x025013, 0x06b059, 0x025017, 0x1c915b, 0x10d097, 0x1af0a7, 0x0f103b, 0x52724b, 0x38f241, 0x22d10f, 0x2e701d, 0x1150c7, 0x7eb0ad, 0x0e50a3, 0x0e5089, 0x065047, 0x1cf065, 0x10d059, 0x1cf14b, 0x16f0e3, 0x071053, 0x24b1bb, 0x10d0e5, 0x23b00d, 0x06b005, 0x1750b5, 0x2f9293, 0x0fb06d, 0x0c7029, 0x26b059, 0x0f10df, 0x0c5089, 0x107049, 0x1d300b, 0x17b137, 0x14b035, 0x065059, 0x2a5251, 0x2411c1, 0x1df115, 0x053005, 0x281233, 0x0bf043, 0x1f7013, 0x3352a1, 0x1a301d, 0x281083, 0x2e7241, 0x22315b, 0x277013, 0x07f067, 0x24b241, 0x053025, 0x0c5059, 0x00d005, 0x161065, 0x287257, 0x00b007, 0x21d1bb, 0x083035, 0x10100b, 0x09d097, 0x1bb0ad, 0x24b005, 0x51101d, 0x1fd175, 0x20b011, 0x1c90ef, 0x2a523b, 0x03d025, 0x2f5049, 0x23b1b7, 0x1c90c7, 0x1910e5, 0x3b9083, 0x2a1043, 0x0e90c7, 0x097043, 0x1a315b, 0x8f55c9, 0x2570b3, 0x11b03b, 0x1370a3, 0x397137, 0x0df0a3, 0x01d00d, 0x223053, 0x0e9061, 0x1190a7, 0x08302b, 0x36d329, 0x06b01f, 0x2a101f, 0x1eb0a3, 0x02501f, 0x3d1005, 0x16f035, 0x0c5025, 0x269125, 0x025005, 0x071067, 0x251239, 0x5f3005, 0x2a522d, 0x1b1049, 0x1f71c9, 0x3fb137, 0x2dd16f, 0x067061, 0x1150b5, 0x0a306b, 0x14b00d, 0x09701f, 0x259185, 0x329013, 0x5ad035, 0x335025, 0x10d03d, 0x2ef115, 0x3970e3, 0x0f1013, 0x3b336d, 0x64162f, 0x15d0b5, 0x373359, 0x1b7029, 0x0d3067, 0x16f10d, 0x1b10b5, 0x08903b, 0x0c104f, 0x29300d, 0x15b035, 0x463281, 0x16f08b, 0x1070d3, 0x3e5133, 0x2dd20b, 0x1a302f, 0x1e70df, 0x06700b, 0x7bb04f, 0x20918d, 0x1910b5, 0x3d72dd, 0x4fd35f, 0x1bb137, 0x257241, 0x0ad049, 0x16110d, 0x15d115, 0x1cd02f, 0x15b0e9, 0x16708b, 0x14b04f, 0x1b10d3, 0x1bb16f, 0x0ef0b5, 0x23b09d, 0x4073b9, 0x1fd10d, 0x35b335, 0x287233, 0x125035, 0x4cf053, 0x22d01f, 0x0e9061, 0x1df005, 0x11900b, 0x407013, 0x0df06b, 0x31308b, 0x1010f1, 0x18d0e5, 0x22302f, 0x43f42d, 0x19100b, 0x0c503b, 0x239133, 0x10701f, 0x29322d, 0x0c1059, 0x4b1313, 0x1150d3, 0x0d3083, 0x1b710f, 0x0c507f, 0x133125, 0x04f029, 0x15b101, 0x1330e5, 0x0f10e9, 0x02f01d, 0x2d702b, 0x151007, 0x371003, 0x28d265, 0x23b0df, 0x0c5029, 0x22d059, 0x313293, 0x03d03b, 0x209119, 0x0df013, 0x239065, 0x26b265, 0x2cf251, 0x1cd15b, 0x2bd223, 0x3f5137, 0x37322d, 0x287185, 0x35f0df, 0x0df053, 0x1f3025, 0x06b025, 0x047043, 0x1b717b, 0x2c5259, 0x3292f5, 0x16710d, 0x2b30e5, 0x1e714b, 0x125061, 0x0c502f, 0x2bd071, 0x18d043, 0x2c5233, 0x1af0bf, 0x4a3119, 0x15b083, 0x08901f, 0x33703b, 0x24b061, 0x45d003, 0x11b03b, 0x1a30fb, 0x089035, 0x29507f, 0x233089, 0x1c9185, 0x0ad067, 0x2090e3, 0x13d0ef, 0x265139, 0x2a1233, 0x22d191, 0x0fb04f, 0x35f1bb, 0x1af09d, 0x1af0b5, 0x1c91b7, 0x1a50c7, 0x2b310d, 0x0e906d, 0x30521d, 0x38f32b, 0x04f02b, 0x08b01f, 0x2b316f, 0x24b125, 0x2090f1, 0x18d10d, 0x2d717b, 0x0e906d, 0x0b3005, 0x3051eb, 0x185061, 0x36d0d3, 0x133025, 0x1df0d3, 0x17f0b5, 0x0fb02b, 0x191035, 0x161083, 0x25713d, 0x1510ef, 0x01300d, 0x1330b3, 0x0e50bf, 0x23b22d, 0x0e304f, 0x0a708b, 0x43f33b, 0x07f071, 0x3a1251, 0x1b1133, 0x28111b, 0x18d107, 0x15d043, 0x2511cf, 0x265191, 0x33517f, 0x3df0b3, 0x16115b, 0x2930c7, 0x11b005, 0x11908b, 0x1250e9, 0x0e9053, 0x25f00b, 0x3471cf, 0x18d071, 0x03501d, 0x21d0a7, 0x125095, 0x16f0c1, 0x065005, 0x1a317b, 0x1750df, 0x2a1035, 0x2ab06d, 0x071013, 0x17f15b, 0x101029, 0x305115, 0x15b0c5, 0x0c70b3, 0x1850f1, 0x17b0e9, 0x2410fb, 0x3b903d, 0x04f049, 0x11503d, 0x0e300d, 0x47f199, 0x16f01d, 0x029007, 0x06d013, 0x06104f, 0x37706b, 0x1cf185, 0x1a310d, 0x2a1125, 0x18d007, 0x053025, 0x0a701d, 0x18d083, 0x1a30f1, 0x0b503d, 0x29310d, 0x2cf0b3, 0x02901d, 0x119005, 0x083049, 0x059029, 0x347119, 0x133071, 0x071043, 0x33d00b, 0x15b09d, 0x06b00d, 0x2a1265, 0x0e50a7, 0x20907f, 0x0e5013, 0x20b0df, 0x3df1f3, 0x139137, 0x28702b, 0x119053, 0x373329, 0x133083, 0x1cf167, 0x25100d, 0x3e53b3, 0x3131cf, 0x119101, 0x2dd281, 0x2d71d3, 0x089061, 0x1610a7, 0x1af0ad, 0x061005, 0x107025, 0x2d7185, 0x097089, 0x1c10d3, 0x2bd233, 0x50b1b7, 0x3ad265, 0x2091df, 0x18517f, 0x0fb0ef, 0x049005, 0x0ef007, 0x16f08b, 0x335065, 0x1150a7, 0x33b049, 0x09d013, 0x4493fd, 0x28d005, 0x23b09d, 0x3b91d3, 0x13d0c5, 0x09501d, 0x0ef01f, 0x23b03d, 0x15b115, 0x5c924b, 0x0a7083, 0x1cf199, 0x107025, 0x42d305, 0x0b3059, 0x0f10c7, 0x22310f, 0x161151, 0x1e711b, 0x13d00b, 0x0e3043, 0x0fb08b, 0x3b31c9, 0x51b40f, 0x19911b, 0x15d095, 0x0d3029, 0x0ad03b, 0x29315b, 0x251209, 0x1670ef, 0x0c506b, 0x03b005, 0x2570bf, 0x13d089, 0x3fd14b, 0x48140f, 0x1750e5, 0x2a5097, 0x2a51cf, 0x22303d, 0x185125, 0x25f251, 0x2931e7, 0x4693d7, 0x287223, 0x11501d, 0x1b10e9, 0x1b7005, 0x139097, 0x3b306b, 0x0c103d, 0x0b50a3, 0x259167, 0x151071, 0x13d0b3, 0x1bb043, 0x1f315d, 0x08b00d, 0x0df0b3, 0x1bb0b3, 0x2090d3, 0x3771cf, 0x151025, 0x1190c5, 0x15d115, 0x0c5061, 0x377161, 0x14b067, 0x21d08b, 0x23b17f, 0x239035, 0x3c707f, 0x63d23b, 0x20b0bf, 0x3550e5, 0x07f00d, 0x293251, 0x13306d, 0x42d3b3, 0x301061, 0x16f0e9, 0x24115d, 0x175101, 0x1e70ad, 0x0c70b5, 0x03b005, 0x0ef097, 0x17510f, 0x1d30e9, 0x04f03d, 0x0e908b, 0x0e3059, 0x151137, 0x1fd08b, 0x1f31b1, 0x4a903d, 0x4b1107, 0x3c72bd, 0x2e711b, 0x0b5025, 0x1b7125, 0x12504f, 0x0b307f, 0x0bf03b, 0x083065, 0x1190e5, 0x0ad0a3, 0x1af0e3, 0x41916f, 0x14b01f, 0x10f067, 0x071065, 0x065035, 0x35b011, 0x2ab139, 0x0e906b, 0x49d269, 0x31d17b, 0x25700d, 0x4d54cf, 0x283047, 0x1df107, 0x1b11a3, 0x199097, 0x3590ad, 0x277137, 0x08b06b, 0x371233, 0x265241, 0x13709d, 0x1cf119, 0x3df025, 0x1eb1c9, 0x1c10a7, 0x1b7029, 0x0e5065, 0x083007, 0x20b059, 0x12510f, 0x15d02f, 0x38f095, 0x305151, 0x065005, 0x22d06b, 0x0c501f, 0x13d017, 0x1a5007, 0x4c13cb, 0x18500d, 0x25f00b, 0x1eb1af, 0x35b28d, 0x1fd03d, 0x053013, 0x295199, 0x0a300b, 0x13303b, 0x0df017, 0x11502f, 0x42d2bd, 0x11910d, 0x3d136d, 0x161137, 0x209071, 0x20b161, 0x1d3029, 0x12510d, 0x20907f, 0x3b33a9, 0x2e30c5, 0x32926b, 0x565241, 0x0c500d, 0x0b3067, 0x2e700b, 0x0e30ad, 0x09708b, 0x02900d, 0x0b508b, 0x2a508b, 0x3cb283, 0x2e7251, 0x20b0c1, 0x37128d, 0x1250fb, 0x0fb029, 0x15b00d, 0x17f071, 0x1c1133, 0x13301f, 0x02b025, 0x18d067, 0x0d304f, 0x10f10d, 0x03d005, 0x2330e5, 0x223161, 0x0c1003, 0x257025, 0x19902f, 0x0a300b, 0x1010b3, 0x0df005, 0x13900b, 0x115083, 0x32b11b, 0x12502f, 0x3f1071, 0x1c117f, 0x26b107, 0x00d003, 0x35924b, 0x19102b, 0x2951f3, 0x3c7199, 0x2951e7, 0x15d15b, 0x0bf02f, 0x33b257, 0x06b00d, 0x089047, 0x0e30a3, 0x22d02b, 0x32922d, 0x185115, 0x1c1007, 0x083013, 0x2bd26b, 0x1e710d, 0x11b07f, 0x04301d, 0x0bf047, 0x03b01d, 0x1150b3, 0x28325f, 0x20b101, 0x269035, 0x11906d, 0x2330b5, 0x3f53c7, 0x0ad005, 0x1eb02f, 0x24b1f7, 0x0e9061, 0x3351b7, 0x14b0e3, 0x0e308b, 0x13302f, 0x107013, 0x15d01f, 0x20902b, 0x0f1059, 0x11b0a3, 0x09d04f, 0x0ef0d3, 0x095059, 0x2bd1c9, 0x1cf0d3, 0x01f011, 0x2091b1, 0x24103d, 0x1b70c7, 0x161061, 0x1a3049, 0x0c5053, 0x3f1313, 0x1cf13d, 0x15d01d, 0x35b02b, 0x08300d, 0x2f9175, 0x071053, 0x185065, 0x3372e7, 0x0a7053, 0x2a10c5, 0x20b067, 0x1eb053, 0x0fb00d, 0x17b0fb, 0x209115, 0x409083, 0x2f521d, 0x0b508b, 0x0fb095, 0x223125, 0x347191, 0x0e9029, 0x10103d, 0x0fb053, 0x371329, 0x31d00b, 0x33b22d, 0x1b1161, 0x08904f, 0x0ef049, 0x373335, 0x2811fd, 0x2e317b, 0x125115, 0x1e706b, 0x1510a7, 0x2f5259, 0x0e5059, 0x41b007, 0x09700d, 0x06702b, 0x16707f, 0x3ad10f, 0x21d061, 0x06500d, 0x0f1097, 0x083053, 0x13902b, 0x4452bd, 0x2951f3, 0x22d059, 0x0df0c1, 0x089011, 0x19900d, 0x24b02b, 0x0c502f, 0x1b71af, 0x18d01f, 0x61f00b, 0x08b029, 0x1df1bb, 0x09500b, 0x1c90e9, 0x18d0d3, 0x17f175, 0x0d30c1, 0x1e700d, 0x3131c1, 0x04303d, 0x10f005, 0x21d071, 0x137097, 0x0d303b, 0x03d01f, 0x1910e9, 0x18d0fb, 0x2391bb, 0x0b5005, 0x0ef061, 0x1b1065, 0x30101f, 0x1df11b, 0x17b00d, 0x4b1199, 0x283115, 0x2411a5, 0x28d0a7, 0x3051b7, 0x0b500d, 0x38b01d, 0x1e700b, 0x42d1f3, 0x10706d, 0x0e9059, 0x08b00d, 0x329295, 0x0b509d, 0x1390e3, 0x04f005, 0x06d00d, 0x32908b, 0x053011, 0x15d035, 0x1a517f, 0x20b097, 0x0c5025, 0x28d003, 0x02900b, 0x185119, 0x1bb06b, 0x0b5053, 0x22306b, 0x3730bf, 0x5cf42d, 0x301175, 0x1fd15b, 0x337025, 0x26510d, 0x167089, 0x31d28d, 0x4a32a5, 0x233133, 0x45d265, 0x071053, 0x137049, 0x1c115b, 0x0c503d, 0x15d0e9, 0x13d0e9, 0x049011, 0x2590e3, 0x0e9035, 0x409013, 0x0d304f, 0x1a304f, 0x39731d, 0x257067, 0x053047, 0x3f13cb, 0x6232f9, 0x1bb025, 0x1610a3, 0x06d00d, 0x2591df, 0x043005, 0x295071, 0x07f01d, 0x199049, 0x3ad15b, 0x0e3013, 0x1cf005, 0x0f1005, 0x15b053, 0x13d11b, 0x01f00d, 0x08b029, 0x20b025, 0x1eb095, 0x13d025, 0x2391cd, 0x455371, 0x3b903d, 0x08b067, 0x047043, 0x1750f1, 0x0e308b, 0x32b2c5, 0x0c1059, 0x1df071, 0x5091cd, 0x09502b, 0x029025, 0x0f100b, 0x13d10d, 0x1c90a3, 0x20900d, 0x0d303b, 0x1990fb, 0x11b01f, 0x04f049, 0x0e9095, 0x371049, 0x1330d3, 0x1a51a3, 0x17f059, 0x1cf175, 0x175115, 0x293059, 0x04903b, 0x38b265, 0x0e906b, 0x0bf0b3, 0x2dd1cf, 0x0c506b, 0x1bb00d, 0x58106b, 0x0fb003, 0x0d3035, 0x06b03d, 0x0e5029, 0x04700d, 0x10104f, 0x44f2b3, 0x061017, 0x119115, 0x419083, 0x31d0a7, 0x1cd025, 0x0ad00d, 0x035011, 0x06700d, 0x28d133, 0x1b70ad, 0x1b10a7, 0x1eb137, 0x049035, 0x10f029, 0x2b31af, 0x14b089, 0x2dd017, 0x17b013, 0x025011, 0x2e30a3, 0x15106d, 0x2ef239, 0x089005, 0x1eb017, 0x12500b, 0x0df03b, 0x36d00b, 0x15b00d, 0x1bb151, 0x0ef071, 0x14b065, 0x0e90e3, 0x1c9125, 0x3e508b, 0x295209, 0x13711b, 0x161083, 0x7d309d, 0x115017, 0x2410e5, 0x0b5017, 0x0b3061, 0x4553c7, 0x2771a3, 0x33d1b7, 0x03b00d, 0x22d00b, 0x1b103b, 0x28d151, 0x0df071, 0x0c7089, 0x10f06d, 0x371359, 0x23900d, 0x2930bf, 0x04f00d, 0x4a90b5, 0x067005, 0x4250e3, 0x1c91af, 0x3c72cf, 0x31300d, 0x679469, 0x11506d, 0x18510f, 0x17b101, 0x2330c7, 0x3012e3, 0x0df059, 0x33b1bb, 0x029025, 0x03b025, 0x239017, 0x15102b, 0x1b10fb, 0x04303b, 0x1370e9, 0x58f293, 0x3f5397, 0x2091cf, 0x17b00b, 0x2510e5, 0x20b011, 0x24103d, 0x24b241, 0x1fd00d, 0x38f17b, 0x07f043, 0x08301d, 0x0e302b, 0x25f24b, 0x233151, 0x0e902f, 0x0e904f, 0x2b3259, 0x23b02f, 0x0ad043, 0x1b10b3, 0x1cf137, 0x1cd161, 0x2d70ef, 0x10102f, 0x2411cd, 0x2650c5, 0x18514b, 0x2bd13d, 0x137025, 0x08b035, 0x16111b, 0x09502b, 0x1b7089, 0x11901f, 0x0c10a3, 0x05900d, 0x26521d, 0x60d305, 0x07f00b, 0x0bf049, 0x1af15d, 0x17f01f, 0x25f20b, 0x2e709d, 0x47f32b, 0x175035, 0x1bb15d, 0x1c9065, 0x3972a5, 0x2a50f1, 0x44f287, 0x20b0fb, 0x03b02f, 0x13900d, 0x15100d, 0x20b1a3, 0x1b1133, 0x17b167, 0x355133, 0x1eb1a3, 0x1eb1cd, 0x1fd01d, 0x065029, 0x2ef14b, 0x071053, 0x133053, 0x1c918d, 0x5cf0b3, 0x283167, 0x2bd1e7, 0x3b30b3, 0x16f025, 0x095061, 0x28124b, 0x0d30b5, 0x1fd175, 0x2d71eb, 0x0c1005, 0x043029, 0x13706d, 0x3df0ef, 0x11500d, 0x2ab0e5, 0x1eb03b, 0x17b0bf, 0x2f902b, 0x2a5067, 0x0c5083, 0x2651e7, 0x1250c1, 0x43f0ad, 0x269191, 0x139101, 0x13300b, 0x0b300d, 0x1b1167, 0x251049, 0x10109d, 0x2e71a3, 0x21d101, 0x01100d, 0x0d30c7, 0x269059, 0x1c118d, 0x2bd0b5, 0x21d013, 0x22d1e7, 0x14b0d3, 0x2b3049, 0x2e315d, 0x13d0fb, 0x1610c1, 0x2c510d, 0x239125, 0x6794b1, 0x241167, 0x0fb035, 0x0b5025, 0x25f161, 0x13d0e9, 0x2a5043, 0x1a518d, 0x17b15d, 0x26b115, 0x2ef1cf, 0x0a7043, 0x0c50b5, 0x371329, 0x4450f1, 0x09d005, 0x089047, 0x2510e5, 0x281199, 0x04302f, 0x3fd119, 0x1190ef, 0x3f51b7, 0x09708b, 0x20b0a7, 0x2b3241, 0x1250e9, 0x21d13d, 0x22d1b1, 0x259223, 0x35901f, 0x1a30e5, 0x28d06b, 0x0e50a3, 0x11b005, 0x233185, 0x277223, 0x1e708b, 0x1eb133, 0x2870f1, 0x4cf0b3, 0x0fb061, 0x11b0ad, 0x1370f1, 0x1cf049, 0x1f3083, 0x2c51a5, 0x1370b5, 0x0c502b, 0x4191af, 0x083067, 0x061043, 0x02f005, 0x2f9025, 0x0c7035, 0x1e7067, 0x175071, 0x407373, 0x3d70fb, 0x2bd1a3, 0x11510d, 0x11503d, 0x0a7059, 0x08901d, 0x191029, 0x25f251, 0x47f097, 0x1df059, 0x22314b, 0x22d1b7, 0x02b029, 0x25718d, 0x15b0df, 0x23916f, 0x1cd071, 0x3592a1, 0x2d71c1, 0x33b2c5, 0x293259, 0x18506b, 0x1850a3, 0x14b01d, 0x2cf175, 0x0b5013, 0x6d91af, 0x035007, 0x2a1097, 0x26b03b, 0x21d1c9, 0x1cf005, 0x20b089, 0x2230fb, 0xa3100d, 0x305151, 0x26b115, 0x0c70c5, 0x0ad0a7, 0x313223, 0x19114b, 0x0ef0df, 0x2a10c1, 0x10d017, 0x1990fb, 0x28d15d, 0x0a306b, 0x1eb043, 0x119043, 0x21d1fd, 0x1eb071, 0x03d005, 0x3ad00d, 0x0d3049, 0x10d017, 0x5813f1, 0x2e71f3, 0x2c51e7, 0x2a1011, 0x41b071, 0x185151, 0x0c7067, 0x06b03b, 0x125061, 0x2091a5, 0x0df06d, 0x713043, 0x1a315b, 0x19900b, 0x1e7185, 0x44533d, 0x3cb2a1, 0x04f017, 0x0e5047, 0x1e707f, 0x06d00d, 0x1b7089, 0x16101d, 0x15b03b, 0x049005, 0x2ab223, 0x0c703d, 0x2b3251, 0x0b3097, 0x1150e5, 0x24b1cd, 0x2091b7, 0x34700d, 0x1f706d, 0x10f035, 0x17f14b, 0x1c914b, 0x1af0bf, 0x0d3059, 0x10f0f1, 0x08300d, 0x0df00d, 0x03d00d, 0x3132e3, 0x31d2a1, 0x41b33b, 0x1b7115, 0x2c50d3, 0x1d310f, 0x32b24b, 0x05301f, 0x2a517b, 0x31d18d, 0x1af17b, 0x0ef01f, 0x1bb17b, 0x0b3053, 0x1af14b, 0x18d15b, 0x2ab00d, 0x1610a7, 0x1990ef, 0x03500d, 0x1510fb, 0x3a9175, 0x1190b5, 0x0a703b, 0x283259, 0x3c7277, 0x0d3043, 0x22d0b5, 0x13d005, 0x3e536d, 0x2dd005, 0x2230bf, 0x09702f, 0x0ad03d, 0x1910a3, 0x00d00b, 0x2650c7, 0x33d283, 0x259175, 0x0c703d, 0x1990b3, 0x10f0e3, 0x017013, 0x2f50d3, 0x1b702f, 0x0c5097, 0x03b005, 0x33b295, 0x25f0ad, 0x3a10fb, 0x1f71df, 0x0bf08b, 0x0a7013, 0x0e3071, 0x065025, 0x1150c1, 0x0e501d, 0x0a707f, 0x1cd0c5, 0x161107, 0x31d293, 0x01d00d, 0x137053, 0x16110d, 0x1d3161, 0x1af0bf, 0x1df16f, 0x115013, 0x137043, 0x44f11b, 0x0df06b, 0x065025, 0x13d0b5, 0x083029, 0x2dd0b5, 0x2c5293, 0x1cf03b, 0x48b33b, 0x1b7133, 0x2d71a3, 0x1df011, 0x02b029, 0x15d053, 0x1990a3, 0x33d2b3, 0x13904f, 0x3052e3, 0x0df095, 0x13908b, 0x2a1265, 0x3d10c5, 0x17b151, 0x3cb15b, 0x22d1a3, 0x2cf1c9, 0x1c90df, 0x18500d, 0x1cd1a3, 0x20b16f, 0x3ad28d, 0x17b133, 0x223137, 0x18d16f, 0x19901d, 0x20902b, 0x35500b, 0x0ad0a7, 0x26b005, 0x133025, 0x19100d, 0x2951cd, 0x25704f, 0x175005, 0x0ad06b, 0x48b133, 0x1150b3, 0x15b0a7, 0x0f106b, 0x137097, 0x10703b, 0x21d11b, 0x1eb115, 0x31d15d, 0x2b30ad, 0x2e702f, 0x2bd005, 0x293025, 0x10f083, 0x27710d, 0x1c1167, 0x0ef067, 0x17515d, 0x223013, 0x25904f, 0x265137, 0x239017, 0x3f522d, 0x1af005, 0x1a302b, 0x0bf049, 0x0e5047, 0x0c70b5, 0x3f501d, 0x0ef07f, 0x281161, 0x44910f, 0x15b029, 0x2a107f, 0x191095, 0x19100d, 0x61f107, 0x3f1371, 0x1010c5, 0x053043, 0x03b017, 0x1b1115, 0x18d0f1, 0x1a30df, 0x5bf55d, 0x3f50c1, 0x3290df, 0x305139, 0x1f7097, 0x08903d, 0x17b0a3, 0x277089, 0x11b02b, 0x0e9025, 0x223083, 0x0c70b3, 0x35b359, 0x223115, 0x64d191, 0x1e71d3, 0x43f175, 0x14b0ef, 0x0c7049, 0x50932b, 0x0bf065, 0x1f3083, 0x24b0a3, 0x02b011, 0x0df0c5, 0x19100d, 0x089061, 0x16109d, 0x071047, 0x4cf3e5, 0x167003, 0x4c13e5, 0x0c10ad, 0x07f03d, 0x09508b, 0x1c10a7, 0x1190a7, 0x223137, 0x03b025, 0x1cd03d, 0x23b17b, 0x08903d, 0x09d071, 0x35913d, 0x1df0a3, 0x06700d, 0x25f1a5, 0x2dd199, 0x1af0e5, 0x23b0bf, 0x0d3067, 0x2931e7, 0x60d2a1, 0x0e50e3, 0x1c118d, 0x481067, 0x15d065, 0x27700d, 0x3d118d, 0x257107, 0x23b0ad, 0x025011, 0x06d029, 0x125053, 0x1df175, 0x2ef02b, 0x26b199, 0x071049, 0x38f065, 0x15b02b, 0x11903b, 0x035029, 0x4433fd, 0x09d01d, 0x0e302b, 0x14b053, 0x36d1af, 0x071047, 0x37700d, 0x0b3047, 0x2ef125, 0x0d30bf, 0x097005, 0x0e3071, 0x0e9071, 0x18d0bf, 0x061017, 0x0f1005, 0x4a9241, 0x05302b, 0x1bb065, 0x15b115, 0x22d125, 0x1c1065, 0x3592bd, 0x2c52bd, 0x1370df, 0x2a5139, 0x0fb013, 0x2e701f, 0x04701d, 0x2ef2bd, 0x2bd083, 0x0a704f, 0xb1b5d1, 0x359295, 0x1cf0ef, 0x06d025, 0x115005, 0x2510b5, 0x14b049, 0x097047, 0x06b061, 0x1010ef, 0x0d303d, 0x2a10e9, 0x40718d, 0x137029, 0x1a30b5, 0x1f313d, 0x21d0df, 0x0a7097, 0x05300d, 0x13d00d, 0x33b119, 0x16f0c5, 0x0c1013, 0x0fb0a7, 0x223043, 0x00b005, 0x33718d, 0x1a3029, 0x0bf049, 0x0f1065, 0x107007, 0x15d097, 0x14b04f, 0x41b20b, 0x059029, 0x3010df, 0x36d02f, 0x08b06b, 0x0c5007, 0x0e9029, 0x1a30c7, 0x1fd0e9, 0x125095, 0x45508b, 0x2cf17f, 0x01700d, 0x151043, 0x0ad04f, 0x0bf0b5, 0x10f0a3, 0x11b04f, 0x20b209, 0x1b113d, 0x0d303b, 0x0d306b, 0x07f06b, 0x17b03d, 0x33b2b3, 0x25907f, 0x4fd18d, 0x10d0a7, 0x1df119, 0x0bf005, 0x17f0b3, 0x161071, 0x08b00d, 0x0ad071, 0x1cf0d3, 0x15d005, 0x25922d, 0x313209, 0x133025, 0x2231a3, 0x0fb007, 0x335139, 0x283013, 0x161005, 0x26b115, 0x2411a5, 0x0b302b, 0x2ef1c9, 0x209199, 0x13d089, 0x28120b, 0x16f065, 0x1a500d, 0x199101, 0x1150e5, 0x23922d, 0x3731eb, 0x10f065, 0x0e9017, 0x18d01d, 0x277053, 0x059047, 0x1b7097, 0x035013, 0x00d00b, 0x071061, 0x14b04f, 0x0c1025, 0x1f70fb, 0x26524b, 0x8291c1, 0x02f025, 0x4a91cd, 0x4a3095, 0x24b0ad, 0x6494a9, 0x161049, 0x15b0a7, 0x09d03d, 0x0b503b, 0x0f10bf, 0x1670a3, 0x07f013, 0x12508b, 0x11b0e5, 0x0c50b3, 0x2590ef, 0x1df10d, 0x1b1191, 0x0f101d, 0x0e9047, 0x233161, 0x463067, 0x4c14a3, 0x083025, 0x0ad065, 0x26b10f, 0x25f03d, 0x44540f, 0x06d03d, 0x18d061, 0x03b017, 0x02f01d, 0x11b035, 0x23300d, 0x1eb1e7, 0x0e9043, 0x17f107, 0x0c5043, 0x2ab21d, 0x125065, 0x17f089, 0x08301d, 0x04f02b, 0x1cf10d, 0x04301d, 0x2f90fb, 0x24b17b, 0x0b500d, 0x337053, 0x31d0df, 0x42d0df, 0x09706b, 0x03d00d, 0x25f185, 0x0ef0a3, 0x2c5101, 0x0b500d, 0x089005, 0x1b10d3, 0x07100d, 0x1b700d, 0x1190e3, 0x02500d, 0x1f301f, 0x0e5017, 0x2ab20b, 0x18d047, 0x1190b5, 0x1a518d, 0x24114b, 0x23b0ad, 0x09d065, 0x5990c1, 0x2590c7, 0x23b199, 0x26b1a5, 0x09d02b, 0x0c50c1, 0x2e7185, 0x1b107f, 0x257011, 0x0f1097, 0x08b043, 0x15d0c7, 0x049011, 0x0bf043, 0x21d03b, 0x2650f1, 0x1c10f1, 0x329161, 0x1e702b, 0x071007, 0x07102f, 0x04700b, 0x1b7095, 0x06b061, 0x2331af, 0x1b71a3, 0x251043, 0x1610e3, 0x0c70b3, 0x0df017, 0x2cf0a3, 0x2330b5, 0x21d14b, 0x151115, 0x22d21d, 0x1cf07f, 0x0b500d, 0x1bb025, 0x1510c7, 0x60d347, 0x373005, 0x02b00d, 0x10d097, 0x0a303b, 0x08906b, 0x2dd0b3, 0x38f1e7, 0x2770e9, 0x0b50a7, 0x1af065, 0x1b1053, 0x1c902f, 0x115013, 0x061013, 0x4490bf, 0x3f503b, 0x03b00d, 0x2e326b, 0x31d1af, 0x2830b5, 0x1e7175, 0x0e300b, 0x2c5133, 0x2d71eb, 0x239199, 0x061005, 0x1eb025, 0x0e90b3, 0x283133, 0x1750f1, 0x1fd191, 0x09d053, 0x1eb025, 0x2d71b7, 0x10d0b5, 0x0c702f, 0x44516f, 0x3f5043, 0x09702f, 0x199083, 0x089043, 0x0bf071, 0x16710f, 0x11501d, 0x1190ad, 0x2510fb, 0x1cf17f, 0x0fb0b3, 0x39731d, 0x2dd28d, 0x0fb003, 0x23907f, 0x16f119, 0x1af199, 0x1bb115, 0x1f3115, 0x29525f, 0x23b10d, 0x0a306d, 0x10d0e5, 0x09d097, 0x097025, 0x35b137, 0x20b17b, 0x22d00d, 0x04f013, 0x119011, 0x11b0e3, 0x17f151, 0x1c909d, 0x1c1107, 0x00b005, 0x329005, 0x11902f, 0x25f125, 0x2391df, 0x15d071, 0x16f067, 0x1df1b1, 0x1fd01f, 0x44f1a3, 0x2c5251, 0x26b101, 0x167067, 0x025005, 0x359119, 0x13d10f, 0x02b00d, 0x071053, 0x09d02b, 0x24b15d, 0x3d11e7, 0x09702f, 0x4451d3, 0x23313d, 0x0e906d, 0x265209, 0x56555d, 0x071067, 0x35520b, 0x0e909d, 0x16f0fb, 0x01f00d, 0x407047, 0x355251, 0x2330c5, 0x31d2a5, 0x11504f, 0x0c701d, 0x2cf003, 0x373071, 0x059013, 0x463449, 0x0ef065, 0x2dd233, 0x18d083, 0x1cf14b, 0x125061, 0x1510f1, 0x0b503d, 0x3cb24b, 0x1c904f, 0x0b301f, 0x3e511b, 0x20b025, 0x3132dd, 0x13901d, 0x2bd067, 0x25723b, 0x09508b, 0x0c500b, 0x33514b, 0x151065, 0x11901d, 0x1b10a3, 0x0c70a7, 0x5d5329, 0x2e304f, 0x0ef003, 0x0b5067, 0x175125, 0x3771b1, 0x0c103d, 0x25924b, 0x16700b, 0x4271cd, 0x10d02f, 0x25103d, 0x5150c7, 0x23310f, 0x1250b5, 0x22d133, 0x1330c1, 0x0bf0ad, 0x09500b, 0x043035, 0x2870fb, 0x22d0b5, 0x1fd139, 0x2e7101, 0x0e30b5, 0x05302f, 0x1f715d, 0x06101d, 0x0f1089, 0x1eb025, 0x0fb071, 0x1c1151, 0x17f0c5, 0x133059, 0x09d03d, 0x2691e7, 0x11b0df, 0x1e7035, 0x09d035, 0x3d72dd, 0x0d3061, 0x175061, 0x0e9089, 0x0a3061, 0x067053, 0x133029, 0x2cf1a5, 0x0a3065, 0x33717b, 0x167151, 0x119101, 0x335005, 0x059011, 0x185011, 0x2570e9, 0x2dd09d, 0x27715b, 0x0e5089, 0x233053, 0x0df04f, 0x33d2ef, 0x2e30c1, 0x0f1007, 0x64d5c9, 0x065059, 0x0ad059, 0x1d310f, 0x2e7049, 0x515493, 0x17f07f, 0x0b5059, 0x45523b, 0x1bb035, 0x02f017, 0x139083, 0x02900d, 0x1c109d, 0x4cd335, 0x199139, 0x2ef025, 0x32b059, 0x23b013, 0x2230fb, 0x3b311b, 0x007005, 0x22d0fb, 0x01d011, 0x1a3061, 0x01d00d, 0x49d42d, 0x2bd1af, 0x2e7223, 0x04302f, 0x347337, 0x1e70a7, 0x0df0ad, 0x1910c5, 0x2bd035, 0x17b089, 0x0e500d, 0x025013, 0x5d523b, 0x2e720b, 0x293185, 0x11b04f, 0x1f30df, 0x185061, 0x43f16f, 0x3f13c7, 0x175151, 0x0e30a7, 0x21d1bb, 0x2cf067, 0x1d3139, 0x4eb443, 0x0ef01f, 0x21d0ad, 0x2950b5, 0x1f70ad, 0x1d3061, 0x17b139, 0x191005, 0x301089, 0x7db209, 0x0ad017, 0x259029, 0x269035, 0x13d06d, 0x335083, 0x1cf0bf, 0x06d011, 0x1390d3, 0x63d44f, 0x1390a3, 0x529281, 0x42d0ef, 0x0c501d, 0x10d083, 0x115071, 0x1a511b, 0x281107, 0x24b1a3, 0x05901d, 0x18500d, 0x139059, 0x2390ad, 0x13d125, 0x3ad371, 0x0c7043, 0x41b0e9, 0x16703d, 0x13910f, 0x0bf043, 0x42d2dd, 0x3b3167, 0x2cf00d, 0x1c100d, 0x49d0e9, 0x083065, 0x24b0ef, 0x1cd00d, 0x2811af, 0x1df1c9, 0x139115, 0x1eb1af, 0x1cf175, 0x23317b, 0x2b31d3, 0x10f0a7, 0x0ef061, 0x029005, 0x19114b, 0x265043, 0x1f31d3, 0x0fb089, 0x11b089, 0x059013, 0x42d089, 0x31d011, 0x283095, 0x185137, 0x137035, 0x21d0ad, 0x0e5025, 0x0b3029, 0x29325f, 0x185089, 0x4253b3, 0x0b50a3, 0x313035, 0x0ad08b, 0x1190a7, 0x25f233, 0x265035, 0x1bb053, 0x1c9005, 0x071035, 0x16f10d, 0x0fb0e9, 0x0f10e5, 0x2410d3, 0x10d095, 0x10701f, 0x11506b, 0x1df04f, 0x0ef00b, 0x1910ef, 0x2a115d, 0x2cf18d, 0x0df025, 0x2650ef, 0x03d011, 0x5ad371, 0x18d053, 0x1b101d, 0x17f01f, 0x1fd137, 0x1eb161, 0x1670c5, 0x26b1cd, 0x24b0f1, 0x101067, 0x3351e7, 0x1f715b, 0x1fd137, 0x23b22d, 0x01300b, 0x25702b, 0x251083, 0x04900b, 0x0e3047, 0x27700d, 0x01d017, 0x1b70c5, 0x1b7161, 0x17b029, 0x0e9047, 0x2ab15d, 0x2cf175, 0x1d301f, 0x5b351b, 0x3b900d, 0x0c5053, 0x03d013, 0x43f043, 0x06b061, 0x10106b, 0x137011, 0x01700d, 0x133053, 0x1370fb, 0x653005, 0x15b0df, 0x1c1083, 0x1af125, 0x1f7167, 0x17f0b3, 0x17b011, 0x287137, 0x1af06d, 0x16f00b, 0x18507f, 0x15d0f1, 0x047017, 0x60d4cd, 0x2dd0e9, 0x511025, 0x2ef01f, 0x067053, 0x17f03b, 0x02501d, 0x0b500d, 0x067049, 0x36d233, 0x44911b, 0x029025, 0x2f50bf, 0x20b02b, 0x15108b, 0x2c51a3, 0x2e7097, 0x1cf047, 0x16106b, 0x4fd2c5, 0x137043, 0x301043, 0x36d2ef, 0x19106b, 0x5b3133, 0x167053, 0x287119, 0x2f503d, 0x2510d3, 0x373083, 0x2c5167, 0x15b049, 0x08b011, 0x047025, 0x0e5025, 0x06103d, 0x2f91e7, 0x17f133, 0x463449, 0x10f0b3, 0x329029, 0x48b35b, 0x35b0e9, 0x2a1125, 0x0ef061, 0x2c5053, 0x35b2dd, 0x0df0c5, 0x065011, 0x49d1fd, 0x41b397, 0x06103d, 0x1eb0e3, 0x2f913d, 0x119005, 0x0f102f, 0x31d239, 0x1150e3, 0x06703b, 0x137119, 0x11b043, 0x08306b, 0x2b30df, 0x065059, 0x24b0d3, 0x14b0df, 0x2ab223, 0x2810e3, 0x04f03d, 0x2391af, 0x0bf049, 0x17501f, 0x0b3059, 0x0ad097, 0x1b706d, 0x0b301d, 0x043017, 0x18d011, 0x62f0c1, 0x2571bb, 0x24117b, 0x12501f, 0x1e70d3, 0x1330bf, 0x0fb0b5, 0x373191, 0x10100d, 0x0f1053, 0x1af0fb, 0x0ad005, 0x2ef125, 0x37335f, 0x067025, 0x17b035, 0x2dd28d, 0x191101, 0x0ad047, 0x2a115d, 0x0df097, 0x3290ef, 0x30120b, 0x33b337, 0x0e90c5, 0x3470bf, 0x0bf0b5, 0x17f0b3, 0x13700d, 0x13d017, 0x17b167, 0x1610ef, 0x3a90f1, 0x0ad02f, 0x37124b, 0x1df1c1, 0x0ad01f, 0x31d18d, 0x09d047, 0x2871c1, 0x20b035, 0x1df0c5, 0x25904f, 0x1a504f, 0x21d0b3, 0x1bb0ad, 0x0e900b, 0x07f01d, 0x0e301f, 0x049005, 0x10706d, 0x21d17f, 0x08304f, 0x0c103b, 0x18517b, 0x1eb1cf, 0x01d005, 0x0c700b, 0x04f035, 0x01100d, 0x2810e9, 0x3132b3, 0x2d7239, 0x251061, 0x2a120b, 0x0bf00d, 0x1f310d, 0x23b0f1, 0x527025, 0x11910f, 0x419139, 0x20b095, 0x26910d, 0x38b359, 0x2cf1a5, 0x21d0b5, 0x25101d, 0x3ad0c1, 0x4cd2b3, 0x2a50bf, 0x04f025, 0x1f7089, 0x071049, 0x26b133, 0x2dd239, 0x2e3025, 0x4491a3, 0x2811cf, 0x31307f, 0x18d167, 0x09707f, 0x2570c5, 0x0bf00d, 0x32b2dd, 0x043025, 0x059025, 0x10f0a3, 0x09d067, 0x26524b, 0x19110f, 0x1b70a7, 0x17f107, 0x233139, 0x04900d, 0x5654cd, 0x2a522d, 0x1c1043, 0x551133, 0x1b7199, 0x043025, 0x1a317b, 0x049047, 0x15b0c5, 0x22313d, 0x1b1043, 0x1a300b, 0x161133, 0x23308b, 0x14b09d, 0x1190d3, 0x0c5029, 0x13d06d, 0x259035, 0x1bb047, 0x07f043, 0x1eb10d, 0x1bb09d, 0x0fb03b, 0x19100d, 0x1cf0c5, 0x05900b, 0x107035, 0x1d3005, 0x101025, 0x20b06d, 0x1eb1a3, 0x23308b, 0x18513d, 0x0c1059, 0x107025, 0x46302f, 0x0df061, 0x10f00d, 0x1f303b, 0x1190e3, 0x16f0c7, 0x2331e7, 0x1cf185, 0x1b7065, 0x13310f, 0x095053, 0x18d0e9, 0x09d013, 0x071059, 0x0fb0bf, 0x1af0e3, 0x14b013, 0x067047, 0x0c10b5, 0x3370a7, 0x06b01d, 0x8e1685, 0x11b03b, 0x5bf269, 0x2410c1, 0x335301, 0x199013, 0x03501f, 0x35925f, 0x337137, 0x2dd071, 0x359151, 0x6231b1, 0x4ff305, 0x00d005, 0x02500d, 0x2dd1f7, 0x2570e5, 0x28716f, 0x0b5011, 0x097059, 0x0ad09d, 0x33d0bf, 0x0e500b, 0x3051fd, 0x0fb011, 0x2e72bd, 0x1cd1c1, 0x0ef00d, 0x175017, 0x1d3191, 0x08300d, 0x199133, 0x08b029, 0x0c5005, 0x49d071, 0x223209, 0x0bf083, 0x07100d, 0x1bb125, 0x0a3095, 0x2331a3, 0x1c9005, 0x2f9025, 0x4bd481, 0x2770a3, 0x85f0ef, 0x095049, 0x1c90e3, 0x15d02b, 0x28d029, 0x3df08b, 0x119047, 0x4bd2ab, 0x36d08b, 0x199097, 0x0fb02f, 0x49306d, 0x1f3161, 0x1a3013, 0x0fb0df, 0x0e30a3, 0x2511fd, 0x26525f, 0x13910d, 0x4273ad, 0x133035, 0x1250d3, 0x52f38b, 0x2e7223, 0x0bf097, 0x13d0b3, 0x18d013, 0x2870b5, 0x21d16f, 0x577005, 0x06100d, 0x209089, 0x1370ad, 0x35515d, 0x13d0c7, 0x1af16f, 0x0b5035, 0x06d049, 0x2e71f3, 0x3012dd, 0x13d10d, 0x17f059, 0x06702b, 0x3c7137, 0x1bb00d, 0x053047, 0x2dd281, 0x2e32d7, 0x0bf03b, 0x13701d, 0x2f520b, 0x17f01d, 0x115089, 0x4c1191, 0x20b049, 0x06100b, 0x1cd101, 0x1af029, 0x443151, 0x04900d, 0x13703d, 0x1df139, 0x1b71a3, 0x025005, 0x15102f, 0x1a3133, 0x21d1e7, 0x15d09d, 0x33d06b, 0x1bb043, 0x18500d, 0x0a7047, 0x1e71d3, 0x1f7191, 0x1c9071, 0x0c702b, 0x15b095, 0x13d08b, 0x4eb005, 0x3df251, 0x0e302f, 0x0e3047, 0x04903b, 0x277043, 0x0f10e3, 0x0b5005, 0x38f31d, 0x565407, 0x2ef22d, 0x1d3107, 0x06d029, 0x31d25f, 0x1cf00d, 0x28d139, 0x1cd10f, 0x01f00d, 0x4632dd, 0x1250c5, 0x08b035, 0x13d0b5, 0x0b508b, 0x16f00d, 0x223061, 0x295107, 0x10d03d, 0x23b107, 0x1610e3, 0x1a3083, 0x15b0bf, 0x23b09d, 0x125043, 0x2571af, 0x2c503b, 0x3c7259, 0x1cf0b5, 0x1070ad, 0x2091f3, 0x17507f, 0x3010a7, 0x1c90bf, 0x2230e3, 0x251133, 0x2b310d, 0x13d00d, 0x0e309d, 0x2951f7, 0x0b300d, 0x1330b5, 0x24b061, 0x257053, 0x17b013, 0x4c732b, 0x24b00d, 0x13d02f, 0x24b151, 0x00b005, 0x04300d, 0x17b007, 0x151005, 0x26900b, 0x0c504f, 0x0bf06d, 0x4e149d, 0x1d302b, 0x38b029, 0x3710ad, 0x32b07f, 0x0bf0b5, 0x0e3005, 0x1510bf, 0x2a5139, 0x33707f, 0x5953e5, 0x1c911b, 0x259071, 0x3a1119, 0x09508b, 0x10f047, 0x3a1287, 0x2331af, 0x16100b, 0x2f91f3, 0x08304f, 0x1a50fb, 0x0ef0d3, 0x11500d, 0x125029, 0x0ef0c7, 0x1c91a5, 0x3c718d, 0x0e903d, 0x0ef08b, 0x283281, 0x1990b3, 0x17f083, 0x1f7003, 0x2931f7, 0x17516f, 0x0b5005, 0x1670c7, 0x3971eb, 0x29511b, 0x0b508b, 0x1f311b, 0x305161, 0x28d0df, 0x3e510f, 0x239083, 0x42d3fd, 0x14b013, 0x1390d3, 0x1df1bb, 0x09d03d, 0x2b3175, 0x2411c1, 0x15d01f, 0x16f03d, 0x0c507f, 0x097007, 0x2a502f, 0x3d71e7, 0x06d065, 0x2dd02b, 0x0a7013, 0x1cd06d, 0x18516f, 0x15d0e5, 0x14b13d, 0x1a50ef, 0x2870e3, 0x2091e7, 0x509043, 0x40708b, 0x0c50c1, 0x17516f, 0x13302f, 0x1b1071, 0x05301d, 0x1190a7, 0x1330ef, 0x0a7095, 0x30110f, 0x223185, 0x1cf089, 0x0b3059, 0x167151, 0x251095, 0x0fb04f, 0x053035, 0x1df1b7, 0x371283, 0x1c1107, 0x175043, 0x293053, 0x3cb32b, 0x14b02f, 0x1af107, 0x0e50ad, 0x175061, 0x28d0b3, 0x2c50b3, 0x17b0a3, 0x0e30a3, 0x15b011, 0x24113d, 0x21d03d, 0x3b3107, 0x35910f, 0x02f00d, 0x1eb0b3, 0x28d185, 0x0b500b, 0x1b702f, 0x0e9049, 0x3fd03d, 0x481017, 0x30511b, 0x1b1101, 0x1cd053, 0x0f10b3, 0x08900d, 0x0fb0c5, 0x13d0c1, 0x2f926b, 0x36d287, 0x33b2f5, 0x2ef1e7, 0x445133, 0x03b011, 0x679283, 0x10103d, 0x1150ad, 0x1af059, 0x089025, 0x281185, 0x1c9035, 0x239065, 0x07f01f, 0x3b92dd, 0x1910b5, 0x1eb1c1, 0x1cd1a3, 0x21d1d3, 0x07f06d, 0x00d00b, 0x2c51d3, 0x2f9025, 0x1cd007, 0x0c700d, 0x0c102f, 0x33d101, 0x15b02b, 0x1fd0e5, 0x03b01d, 0x151107, 0x2811af, 0x407241, 0x02b01d, 0x0a7029, 0x1df1c1, 0x05302f, 0x257007, 0x03b029, 0x17500d, 0x1a30b3, 0x3cb0d3, 0x2a510d, 0x15b125, 0x13d059, 0x1eb083, 0x0a707f, 0x2330ad, 0x18d035, 0x0b302b, 0x51508b, 0x161133, 0x0bf047, 0x15b107, 0x3972d7, 0x3f107f, 0x2411fd, 0x0bf025, 0x1f30a7, 0x0e507f, 0x3d1089, 0x15b10f, 0x1bb09d, 0x28100d, 0x3711a5, 0x0ef061, 0x17f083, 0x32b191, 0x2871af, 0x4bd14b, 0x15b08b, 0x13d03d, 0x20b1df, 0x0a7005, 0x1df0e9, 0x2ef175, 0x11900d, 0x13d10f, 0x0bf01f, 0x287239, 0x0ad0a3, 0x11903b, 0x3551f3, 0x0ef029, 0x095003, 0x09d025, 0x33d0ef, 0x3e5337, 0x1370f1, 0x1bb01d, 0x251035, 0x0c7061, 0x06b01f, 0x083013, 0x1cd10f, 0x0ef0a3, 0x11b0c7, 0x269043, 0x2e72a5, 0x751445, 0x2e7223, 0x3f1251, 0x03d03b, 0x257175, 0x17508b, 0x31d17f, 0x38f2cf, 0x15b0a3, 0x10f0c5, 0x48b0c1, 0x10f0e3, 0x035017, 0x305137, 0x2ab0bf, 0x0bf08b, 0x36d0ef, 0x0d30ad, 0x053017, 0x2a1137, 0x1910e9, 0x1c1199, 0x0c503d, 0x0bf067, 0x209175, 0x1f3083, 0x4b1449, 0x119043, 0x1d310f, 0x2771d3, 0x2e70ad, 0x2dd083, 0x29507f, 0x16709d, 0x17503d, 0x1d30fb, 0x1f70b3, 0x28115d, 0x1910a3, 0x02501d, 0x3cb2d7, 0x21d1a5, 0x3d715d, 0x15d049, 0x0d3071, 0x23b133, 0x4a3295, 0x1af0b3, 0x31d233, 0x1c9011, 0x2dd11b, 0x3d1025, 0x1cf1b1, 0x3e506b, 0x0e3095, 0x0a3053, 0x047043, 0x15d0ad, 0x3132c5, 0x13309d, 0x11b02f, 0x1a300d, 0x2511af, 0x25903b, 0x15d011, 0x1250e9, 0x0bf013, 0x1010ad, 0x42d2cf, 0x35928d, 0x17f13d, 0x1510fb, 0x15111b, 0x125047, 0x0e90c5, 0x2f901d, 0x1a3005, 0x22d209, 0x05902f, 0x2a50c7, 0x33b03d, 0x1cf0ef, 0x2230bf, 0x1330e3, 0x493251, 0x0b5067, 0x5fb4cd, 0x1910df, 0x28315b, 0x0f10e5, 0x16f15b, 0x19100d, 0x03d013, 0x1af059, 0x10d0b5, 0x0e9065, 0x269151, 0x0c504f, 0x28d0c1, 0x3ad329, 0x17f005, 0x14b101, 0x17b107, 0x11503d, 0x47f33b, 0x06b029, 0x175133, 0x1fd0e5, 0x1b1151, 0x0ad049, 0x3f1089, 0x11506d, 0x24b1cd, 0x119061, 0x31d02f, 0x25f03d, 0x043011, 0x2a516f, 0x1cd005, 0x3a9265, 0x167059, 0x16f167, 0x0c502b, 0x22300d, 0x0c5017, 0x32b265, 0x13907f, 0x053029, 0x19115d, 0x15b02f, 0x33728d, 0x1d3185, 0x293223, 0x10702f, 0x1f3005, 0x1c91c1, 0x11b0e5, 0x5d116f, 0x0e906b, 0x16f065, 0x2410fb, 0x11909d, 0x19100d, 0x2a106b, 0x06b047, 0x06d005, 0x0df02f, 0x2951b7, 0x4c7035, 0x2e717b, 0x3710c5, 0x15b03b, 0x1d310d, 0x1eb151, 0x065005, 0x1f302b, 0x209097, 0x0e30b3, 0x151065, 0x295257, 0x1b7005, 0x13902b, 0x1190c1, 0x4433f1, 0x293125, 0x3710c1, 0x10d0c5, 0x28d003, 0x0b3025, 0x35f25f, 0x11b00d, 0x0e5017, 0x01100d, 0x251133, 0x08b07f, 0x0b303d, 0x0ad007, 0x097029, 0x0c102b, 0x06b02b, 0x281209, 0x329265, 0x31d029, 0x097095, 0x0b5017, 0x22d0c1, 0x18d06b, 0x167071, 0x35f2b3, 0x10d007, 0x2410a3, 0x10f061, 0x06500d, 0x1e710f, 0x1cd107, 0x191137, 0x3b935b, 0x577175, 0x13d0e3, 0x095089, 0x199071, 0x2590b3, 0x06d017, 0x5cf067, 0x01d013, 0x1af0b5, 0x259011, 0x0e509d, 0x25f16f, 0x139107, 0x2d716f, 0x0e50d3, 0x11902b, 0x277257, 0x14b047, 0x0c1095, 0x0d3011, 0x0df0d3, 0x1b7061, 0x06b04f, 0x1cf14b, 0x2770bf, 0x49d281, 0x3d11a5, 0x10d0df, 0x161029, 0x1070a7, 0x0e900b, 0x557277, 0x4093f1, 0x1f311b, 0x74541b, 0x43f1eb, 0x06702b, 0x1f703b, 0x18d0e9, 0x09702b, 0x0f10ad, 0x2a128d, 0x13d00b, 0x1c9025, 0x20b11b, 0x2e7277, 0x13d0ad, 0x191005, 0x1e7185, 0x13d003, 0x185059, 0x2b318d, 0x11b0c7, 0x22d0ef, 0x0ad049, 0x5c9223, 0x36d095, 0x17b10d, 0x15b03b, 0x33b043, 0x4c700d, 0x2811fd, 0x06503d, 0x13d013, 0x1d3035, 0x38b0c1, 0x24b1e7, 0x0bf00b, 0x1e70c5, 0x1bb071, 0x0e3059, 0x0bf083, 0x15d107, 0x1fd1f7, 0x1cd119, 0x21d0bf, 0x1c9191, 0x1c10b5, 0x16f107, 0x5e7377, 0x17b107, 0x1a3083, 0x0a700d, 0x133053, 0x03500d, 0x2690c5, 0x287167, 0x0f106d, 0x1010e9, 0x2411b1, 0x1c9025, 0x16115b, 0x18d17f, 0x18d061, 0x0d300d, 0x22d137, 0x24b053, 0x11908b, 0x3552ab, 0x08904f, 0x083047, 0x28120b, 0x119053, 0x35533b, 0x1250c1, 0x1c903b, 0x0e9005, 0x0e50c5, 0x35b1a5, 0x1bb00d, 0x137047, 0x2b3115, 0x083059, 0x1fd029, 0x0f1005, 0x125013, 0x1b1011, 0x1f3175, 0x1af011, 0x089011, 0x35f1a3, 0x0fb011, 0x1990c1, 0x10d0c5, 0x239025, 0x167095, 0x133119, 0x15b00d, 0x337065, 0x2330e9, 0x067035, 0x00d003, 0x3b3337, 0x335133, 0x1af151, 0x1b10e3, 0x139083, 0x1c9025, 0x2330df, 0x0b3005, 0x1fd08b, 0x2771b7, 0x2c51f7, 0x0a7049, 0x1d31c1, 0x0ad061, 0x13d035, 0x1eb035, 0x2330a7, 0x07f02b, 0x1250a3, 0x35f1c9, 0x425095, 0x1d31c1, 0x199133, 0x1f700d, 0x0e50c5, 0x1af049, 0x1a508b, 0x2dd01f, 0x1910c1, 0x22d0ef, 0x257101, 0x283101, 0x0c7065, 0x0df017, 0x3051cf, 0x2570c5, 0x13901d, 0x09d035, 0x359005, 0x03b00b, 0x15d0e9, 0x17b03b, 0x2c5295, 0x50b1e7, 0x1a30d3, 0x0e303b, 0x26507f, 0x0b3005, 0x3131a5, 0x3b933d, 0x18d00d, 0x04901f, 0x1b10c1, 0x06100d, 0x33523b, 0x0e306d, 0x2a113d, 0x0fb0c7, 0x01100d, 0x301269, 0x26b14b, 0x0ef00d, 0x0c5049, 0x2950f1, 0x3731df, 0x2d71e7, 0x175097, 0x1c1191, 0x191047, 0x04301d, 0x373035, 0x08b017, 0x0b5061, 0x5510ef, 0x06103b, 0x2411f7, 0x115029, 0x6ad655, 0x28d065, 0x06104f, 0x1a5083, 0x03d035, 0x23906d, 0x1f717b, 0x2bd265, 0x1d31cd, 0x3f50c7, 0x0df007, 0x4c1377, 0x18d0f1, 0x42d01f, 0x3c703d, 0x2a506d, 0x6c538b, 0x02b029, 0x06d00d, 0x0b301f, 0x3590f1, 0x493133, 0x2831d3, 0x09d01f, 0x28d191, 0x3010ef, 0x1fd10d, 0x0b503b, 0x0ad071, 0x13306b, 0x2e70e5, 0x09d02f, 0x2931c9, 0x097035, 0x02b013, 0x265223, 0x11502b, 0x46940f, 0x09d01d, 0x3130c1, 0x0b5013, 0x3a1293, 0x167137, 0x2ab15d, 0x151035, 0x2ab02b, 0x33703b, 0x265017, 0x115003, 0x1df133, 0x0e5005, 0x0e901d, 0x48b049, 0x43f283, 0x0df025, 0x059025, 0x1150a3, 0x0e9017, 0x12500d, 0x2231a3, 0x3fb281, 0x01d013, 0x445281, 0x10f0b3, 0x2a1007, 0x10d0ef, 0x18d0ad, 0x07102f, 0x0c7089, 0x2dd1bb, 0x47f0df, 0x2650b5, 0x29316f, 0x5bf133, 0x1330c1, 0x17b017, 0x06b01f, 0x565233, 0x1df01f, 0x01f01d, 0x0a702f, 0x0b506d, 0x39703b, 0x23900d, 0x347233, 0x14b0e3, 0x10d005, 0x3fd1f7, 0x06702b, 0x0df097, 0x17b0e5, 0x3ad18d, 0x1cd053, 0x2771a5, 0x08b061, 0x175083, 0x119097, 0x233101, 0x18511b, 0x0e3035, 0x0e5043, 0x1df1b1, 0x133061, 0x33b2b3, 0x42d2a5, 0x02f02b, 0x265115, 0x16f067, 0x04303d, 0x2f91b7, 0x2a11b1, 0x11903b, 0x1cf02b, 0x3f5053, 0x06d035, 0x1c102f, 0x14b013, 0x17f095, 0x0e90a3, 0x1fd011, 0x15d101, 0x29515b, 0x4c7305, 0x083005, 0x2ab13d, 0x15b04f, 0x185161, 0x1990c7, 0x08901d, 0x58f2c5, 0x26b199, 0x33d083, 0x265049, 0x1cf191, 0x2a10f1, 0x1eb0c1, 0x32b04f, 0x08301d, 0x1c9083, 0x1f30e3, 0x0c10bf, 0x15d0d3, 0x17b0b5, 0x12503d, 0x1f30b5, 0x0fb09d, 0x33500b, 0x1a3043, 0x20b067, 0x3df007, 0x2f51e7, 0x17f14b, 0x6fb515, 0x223017, 0x0d307f, 0x233017, 0x20b0bf, 0x17b0bf, 0x06503d, 0x3cb101, 0x35b0c1, 0x2e717b, 0x185133, 0x1910f1, 0x3f5013, 0x13d035, 0x09d06b, 0x4070bf, 0x19100d, 0x3012dd, 0x20b0df, 0x17506d, 0x2e701d, 0x0e300d, 0x31d01f, 0x1610a7, 0x0d303d, 0x185053, 0x06700d, 0x14b013, 0x17f15b, 0x175125, 0x36d0c7, 0x223013, 0x185083, 0x17f107, 0x11b005, 0x1bb1a5, 0x1af02f, 0x10d0a7, 0x03501d, 0x0d306d, 0x3c72e7, 0x0f10b3, 0x13709d, 0x2931b1, 0x071067, 0x1c1125, 0x06103d, 0x0b5029, 0x25f1b1, 0x355043, 0x08b053, 0x107003, 0x04700d, 0x2b308b, 0x1af175, 0x10d061, 0x239005, 0x1a5013, 0x0d3089, 0x07f047, 0x2a5259, 0x2ef13d, 0x28d11b, 0x13703d, 0x0b30a3, 0x1b716f, 0x1a306d, 0x06b00b, 0x1eb065, 0x20b1d3, 0x1a3035, 0x337047, 0x1190ef, 0x08904f, 0x06d02b, 0x15102b, 0x19107f, 0x0a7083, 0x15d005, 0x32b2a1, 0x053047, 0x139137, 0x283025, 0x1cd17b, 0x16f101, 0x13901f, 0x35f1eb, 0x1a30c5, 0x23906d, 0x3051a3, 0x15d0c1, 0x133025, 0x233097, 0x32b0b3, 0x59f199, 0x0bf083, 0x0a702b, 0x06704f, 0x04f005, 0x065035, 0x22d0ef, 0x08b011, 0x0e3095, 0x22d1c1, 0x0b308b, 0x1e7097, 0x21d01f, 0x191005, 0x2ef10f, 0x097035, 0x35923b, 0x0bf047, 0x0bf049, 0x17503b, 0x455373, 0x2e326b, 0x3e5047, 0x119005, 0x107071, 0x14b035, 0x06503d, 0x0fb0ef, 0x15b0f1, 0x1df08b, 0x16702f, 0x13d047, 0x4073a9, 0x01300b, 0x1c117f, 0x1b1029, 0x2f90e5, 0x2651b7, 0x12508b, 0x03b02b, 0x16f005, 0x09700d, 0x0b5017, 0x15d06d, 0x283025, 0x20b1df, 0x0e90bf, 0x08b059, 0x1c902b, 0x065025, 0x08306d, 0x0d30b5, 0x3371eb, 0x1df133, 0x1df02b, 0x4432ab, 0x25f08b, 0x2cf089, 0x0e306d, 0x1c908b, 0x259233, 0x059005, 0x0c1067, 0x2950ef, 0x3970ef, 0x4690d3, 0x0c706b, 0x2410fb, 0x137005, 0x2410e5, 0x1750e5, 0x15100d, 0x21d1b1, 0x1d3107, 0x10101f, 0x3c71fd, 0x161107, 0x137029, 0x1af185, 0x03d011, 0x3f1301, 0x22d0a3, 0x0ef06d, 0x2cf17f, 0x21d08b, 0x2230b5, 0x0fb097, 0x16f053, 0x1a5095, 0x2391f3, 0x2dd18d, 0x10d08b, 0x10108b, 0x481013, 0x0b5029, 0x061047, 0x21d089, 0x15107f, 0x07103d, 0x39735f, 0x10d0a3, 0x1e7071, 0x1cf0c7, 0x053047, 0x01100d, 0x139005, 0x0bf00b, 0x1b1101, 0x37306d, 0x2ab0df, 0x2410bf, 0x137083, 0x3972c5, 0x16f0e9, 0x2f51bb, 0x3371b7, 0x2e72d7, 0x1df151, 0x0fb0a7, 0x295107, 0x1af125, 0x1f315d, 0x0a702f, 0x191119, 0x377371, 0x1510fb, 0x1c101f, 0x4690b5, 0x09d013, 0x25f035, 0x1a3029, 0x16100b, 0x20910f, 0x3c724b, 0x083053, 0x1bb09d, 0x2dd17f, 0x3e5347, 0x1910f1, 0x0fb005, 0x107097, 0x119005, 0x04f049, 0x083011, 0x06d02f, 0x10d06b, 0x1b1185, 0x1a501d, 0x1cd0c1, 0x1bb08b, 0x16f0d3, 0x2cf067, 0x13d00d, 0x13301f, 0x17f005, 0x101083, 0x1bb01d, 0x2c508b, 0x1610e3, 0x1370bf, 0x4931af, 0x0ef07f, 0x11b049, 0x067013, 0x08306d, 0x2a1043, 0x065059, 0x0c5089, 0x115067, 0x35b01f, 0x1df191, 0x259107, 0x1b7011, 0x2cf13d, 0x313011, 0x24b003, 0x21d065, 0x0f1061, 0x11b0e9, 0x1070c5, 0x233209, 0x059005, 0x3a1005, 0x21d17b, 0x1a310d, 0x19118d, 0x2bd005, 0x1cd061, 0x1150fb, 0x1070a3, 0x1b7139, 0x16f15d, 0x1eb133, 0x33d0fb, 0x0b302b, 0x133071, 0x3051c1, 0x0b3061, 0x17500d, 0x1190c7, 0x09700d, 0x1a314b, 0x36d1cf, 0x0fb0b3, 0x223199, 0x13d017, 0x15b09d, 0x1df00d, 0x04f035, 0x37126b, 0x31316f, 0x15b029, 0x11b065, 0x4072c5, 0x097065, 0x1a3175, 0x095083, 0x16f0b3, 0x0e5061, 0x1c115b, 0x15d011, 0x1f3139, 0x35b257, 0x043005, 0x16710d, 0x0f101f, 0x09506d, 0x44522d, 0x029025, 0x1f7005, 0x2231e7, 0x18507f, 0x15d005, 0x11902b, 0x175059, 0x2bd005, 0x2b32a1, 0x35f13d, 0x1250bf, 0x277241, 0x0c50b3, 0x2690b3, 0x151043, 0x0fb02b, 0x265061, 0x0f107f, 0x1cf14b, 0x0ad089, 0x0c100d, 0x089061, 0x19906d, 0x10d107, 0x011003, 0x209029, 0x2c5295, 0x24b14b, 0xaa99c7, 0x06700b, 0x16103d, 0x049005, 0x18d119, 0x0e9061, 0x4253d7, 0x14b02b, 0x17f013, 0x38f2ef, 0x2cf0a7, 0x03b025, 0x3f116f, 0x1e70ad, 0x13706d, 0x59f269, 0x11b011, 0x0c10b5, 0x16f089, 0x2c5161, 0x0c503d, 0x14b0c7, 0x025017, 0x1fd1b7, 0x097061, 0x1bb11b, 0x065005, 0x139137, 0x1b103b, 0x283017, 0x15b00d, 0x14b0c5, 0x0c700d, 0x15b02b, 0x13d013, 0x1f700d, 0x23902b, 0x0a701d, 0x3351f7, 0x2930c7, 0x24b241, 0x1b104f, 0x2870e3, 0x1d3011, 0x0c709d, 0x1e71d3, 0x2571f7, 0x10f03d, 0x1b110f, 0x4a90c5, 0x5ad557, 0x07100d, 0x2b30df, 0x2b300d, 0x40925f, 0x0e90c1, 0x3fb32b, 0x1330e5, 0x409251, 0x14b137, 0x083035, 0x0c7017, 0x005003, 0x139065, 0x2bd02f, 0x115029, 0x3130c7, 0x0c1013, 0x2d72a5, 0x08b06b, 0x13d0e5, 0x107013, 0x11b0fb, 0x74b005, 0x1eb06d, 0x26910d, 0x107047, 0x2bd00d, 0x35f2ef, 0x2e7125, 0x08b06d, 0x1910c7, 0x11902b, 0x10f00d, 0x03d025, 0x2c5053, 0x06d03b, 0x11b01f, 0x15100d, 0x2591a3, 0x15102b, 0x0bf017, 0x13910d, 0x199067, 0x21d06d, 0x09506b, 0x191175, 0x1a50e9, 0x09d029, 0x04703d, 0x26b11b, 0x04701d, 0x22d00d, 0x4cd071, 0x0e909d, 0x1af16f, 0x38f095, 0x1eb005, 0x0a306d, 0x139101, 0x1cf043, 0x059029, 0x03d017, 0x1e70f1, 0x1e706b, 0x11b017, 0x1670b3, 0x0f10c1, 0x08300d, 0x4a947f, 0x23310f, 0x053017, 0x1d315b, 0x10d011, 0x7732cf, 0x083049, 0x46900b, 0x287269, 0x065007, 0x28716f, 0x47f025, 0x397347, 0x3371b1, 0x23900b, 0x0c500d, 0x2f5281, 0x2411b7, 0x1af0d3, 0x0bf06b, 0x38f08b, 0x03d007, 0x3c7223, 0x17b119, 0x5a74eb, 0x0d30b3, 0x2e326b, 0x1f31cd, 0x0b500d, 0x15b06d, 0x23b1af, 0x1a301f, 0x1af0c5, 0x335313, 0x1c90c7, 0x36d025, 0x3a900d, 0x2f9089, 0x1b1065, 0x0ad07f, 0x259007, 0x0ef089, 0x46900d, 0x1190ef, 0x1a5013, 0x0c1065, 0x119071, 0x1b70a3, 0x377191, 0x32b0bf, 0x22d1a3, 0x28d223, 0x10d00d, 0x17b00b, 0x265025, 0x469029, 0x15d13d, 0x565101, 0x03502f, 0x1390ad, 0x101065, 0x1bb119, 0x11b0b3, 0x2f508b, 0x305017, 0x1c1025, 0x1df0fb, 0x60d06b, 0x58f1a5, 0x097053, 0x175029, 0x03b025, 0x28d1df, 0x2cf1e7, 0x16f06b, 0x239061, 0x5771df, 0x23b10f, 0x5033c7, 0x0c5067, 0x2a52a1, 0x133025, 0x09d02f, 0x3730d3, 0x33d00d, 0x07f011, 0x10d0d3, 0x18d00d, 0x17510f, 0x1b10a7, 0x1250e5, 0x1250d3, 0x0bf005, 0x14b03d, 0x37331d, 0x2591cf, 0x1df0c7, 0x41917f, 0x469359, 0x1750ef, 0x50b3a9, 0x5fb4e1, 0x0c7029, 0x2a108b, 0x2d7167, 0x1df199, 0x10f0ad, 0x14b119, 0x1fd191, 0x1f31a3, 0x04303d, 0x31d00d, 0x241209, 0x09d00d, 0x24b00d, 0x1c1049, 0x1bb01d, 0x301005, 0x29320b, 0x18515d, 0x07101d, 0x33b257, 0x1070f1, 0x10f053, 0x1330b5, 0x11b083, 0x17f065, 0x04f00b, 0x10f0ef, 0x0b50ad, 0x35b125, 0x09701d, 0x08303d, 0x11501f, 0x51b305, 0x62b407, 0x1b7199, 0x2c51fd, 0x581241, 0x2dd15b, 0x025013, 0x10d00b, 0x1cd0b3, 0x0c50b3, 0x2f50df, 0x64d1df, 0x1cd161, 0x115005, 0x1bb18d, 0x035005, 0x101083, 0x1e70a3, 0x30504f, 0x0e5083, 0x0bf06b, 0x139061, 0x2b3049, 0x0c5065, 0x49d481, 0x0f1005, 0x4c704f, 0x07102b, 0x191125, 0x0df047, 0x0a3095, 0x3011bb, 0x2b318d, 0x3d711b, 0x22310f, 0x281003, 0x15b0e3, 0x2bd053, 0x2d72a1, 0x0a303b, 0x2e32dd, 0x257239, 0x11b059, 0x0b50a3, 0x1f7025, 0x23908b, 0x151139, 0x20906d, 0x23b0f1, 0x40f095, 0x0c50a3, 0x08b01f, 0x0ad083, 0x0fb065, 0x4e142d, 0x24101d, 0x0b5005, 0x60d24b, 0x1a3047, 0x40f283, 0x28326b, 0x10d03b, 0x595409, 0x133065, 0x1fd0b5, 0x359065, 0x2091af, 0x0c10bf, 0x0bf049, 0x2cf287, 0x13700d, 0x17b0d3, 0x4bd017, 0x2c5083, 0x2dd1c1, 0x16f04f, 0x1e7089, 0x2651a3, 0x107011, 0x035011, 0x737493, 0x31d2bd, 0x257223, 0x2091a5, 0x50343f, 0x24100d, 0x18d0c5, 0x02b025, 0x16f0b5, 0x0ad03d, 0x1370ad, 0x1fd15b, 0x2e706d, 0x16f017, 0x097053, 0x071029, 0x059047, 0x0c10ad, 0x2391b1, 0x3f117f, 0x1f306b, 0x14b133, 0x223133, 0x28d0ad, 0x1c9003, 0x139043, 0x1a5185, 0x09702b, 0x025005, 0x3a9305, 0x02f00d, 0x269125, 0x18d17b, 0x2a503b, 0x10704f, 0x40900d, 0x2cf11b, 0x119101, 0x1f31d3, 0x3590df, 0x4c73df, 0x1df17b, 0x10d00d, 0x15d02b, 0x22d095, 0x11900d, 0x0e302b, 0x0e302f, 0x067059, 0x2cf1f7, 0x1cf13d, 0x24114b, 0x139083, 0x167151, 0x209011, 0x03b025, 0x251175, 0x199185, 0x04f00d, 0x1a5071, 0x0fb0c7, 0x29328d, 0x08306d, 0x1d3199, 0x04f017, 0x3972ef, 0x25901f, 0x15d0e5, 0x1df0d3, 0x49d119, 0x3b3089, 0x0e90d3, 0x01f00b, 0x139053, 0x25709d, 0x3c7175, 0x1190e3, 0x0df061, 0x133005, 0x2691f7, 0x223017, 0x02f00d, 0x283007, 0x03d005, 0x15b0a7, 0x10f107, 0x1df1b7, 0x1330a7, 0x04f00d, 0x28101f, 0x2a514b, 0x1c110d, 0x14b035, 0x1eb16f, 0x2ef2cf, 0x06500d, 0x4cd42d, 0x10f003, 0x0e3083, 0x095017, 0x0d3097, 0x251025, 0x06b005, 0x0e90ad, 0x33d1b7, 0x16f097, 0x0e3049, 0x17b161, 0x329007, 0x06100b, 0x11b061, 0x269119, 0x0f1065, 0x08b06b, 0x1df01d, 0x1d31a5, 0x33d15b, 0x15d10f, 0x09d035, 0x1a5035, 0x1b110f, 0x0e3049, 0x175095, 0x03d013, 0x1a304f, 0x115011, 0x20b17b, 0x4930df, 0x2591d3, 0x0c500d, 0x1a5161, 0x10f067, 0x2dd265, 0x3b914b, 0x1f31c9, 0x02f00d, 0x4cf2ef, 0x185175, 0x51702b, 0x1070df, 0x06d013, 0x1750df, 0x083013, 0x2f92ef, 0x1a3013, 0x125095, 0x0ad04f, 0x15b0ad, 0x013005, 0x02501f, 0x22302b, 0x25f01f, 0x175133, 0x04901d, 0x283151, 0x10103d, 0x33d00d, 0x3f52bd, 0x1c1005, 0x0ef043, 0x371175, 0x335089, 0x06103d, 0x15d0a3, 0x0a7089, 0x151003, 0x1a3115, 0x22d1cd, 0x0c1059, 0x3372a1, 0x4d5283, 0x04f02b, 0x1df00d, 0x06b01f, 0x21d059, 0x36d1b7, 0x1eb1a3, 0x02901f, 0x359071, 0x37706b, 0x095053, 0x7556c5, 0x12510f, 0x0fb047, 0x097061, 0x26b241, 0x1b70d3, 0x09d007, 0x23300d, 0x03d01f, 0x1c10d3, 0x3f53cb, 0x233185, 0x19900d, 0x2a5017, 0x18d0b5, 0x28d1bb, 0x067025, 0x167053, 0x089043, 0x0df043, 0x40f1fd, 0x185067, 0x0a70a3, 0x28723b, 0x1e711b, 0x25902b, 0x06700d, 0x33b175, 0x0e903b, 0x2b3017, 0x18d04f, 0x09d071, 0x1b1017, 0x13d0ad, 0x22d209, 0x1c9101, 0x2231d3, 0x23b233, 0x2f9281, 0x0b300b, 0x167095, 0x493481, 0x0fb02b, 0x5d52e7, 0x1af07f, 0x1d3065, 0x1c903d, 0x0fb0a3, 0x209095, 0x44942d, 0x04700d, 0x25701f, 0x37306d, 0x16103d, 0x2570fb, 0x2231c1, 0x08906b, 0x14b0b5, 0x3d1083, 0x21d14b, 0x23b1f7, 0x13301d, 0x10f005, 0x067017, 0x0c500d, 0x1d3067, 0x37700b, 0x11910d, 0x2cf277, 0x0e9059, 0x0c502b, 0x06500d, 0x13d061, 0x053049, 0x0fb0b5, 0x293107, 0x0b506d, 0x43f2dd, 0x2a524b, 0x3c7151, 0x05900d, 0x049011, 0x0b3005, 0x0bf0a3, 0x1d3137, 0x09d07f, 0x329305, 0x107025, 0x427167, 0x15101d, 0x29517b, 0x4a910f, 0x23b005, 0x06b007, 0x095025, 0x1010e9, 0x11908b, 0x0a3017, 0x1a3101, 0x3f138f, 0x18d14b, 0x1150e9, 0x14b0bf, 0x14b035, 0x167119, 0x0b307f, 0x1f3167, 0x0a7065, 0x30526b, 0x1610e5, 0x223209, 0x371277, 0x16f09d, 0x59549d, 0x06502f, 0x17f0b5, 0x24b047, 0x371089, 0x28715d, 0x31d0a7, 0x29322d, 0x2cf2c5, 0x0a3043, 0x0ef007, 0x1c90ad, 0x0e300d, 0x185097, 0x1af10d, 0x2c50a3, 0x0b5005, 0x1a310f, 0x05300d, 0x06102b, 0x047035, 0x3fd115, 0x09700d, 0x3d12f9, 0x137017, 0x107097, 0x0a3065, 0x2f91af, 0x23900d, 0x0b5097, 0x239035, 0x17f061, 0x04900d, 0x0b501d, 0x1f311b, 0x1cd14b, 0x511029, 0x18d0c1, 0x08b067, 0x29520b, 0x1a50bf, 0x17506b, 0x1a3151, 0x1bb1af, 0x28313d, 0x191053, 0x28d08b, 0x15d003, 0x05903d, 0x09d013, 0x20b095, 0x0c501f, 0x2f517b, 0x01300d, 0x0df07f, 0x0e308b, 0x599101, 0x089035, 0x0df005, 0x19115b, 0x257067, 0x44f359, 0x2a5209, 0x6832b3, 0x5cf0c7, 0x1390c5, 0x04301d, 0x0b309d, 0x2cf053, 0x2ab029, 0x49d313, 0x38b0d3, 0x0df06b, 0x0c7053, 0x043025, 0x06d059, 0x26b161, 0x0fb005, 0x31d115, 0x19910f, 0x40f035, 0x17b09d, 0x06501d, 0x287119, 0x1af101, 0x0a708b, 0x31d1fd, 0x25f15b, 0x0f10c1, 0x08b005, 0x1f3185, 0x5cf3ad, 0x09d07f, 0x18510d, 0x24120b, 0x2690c5, 0x241185, 0x2811cf, 0x1670c5, 0x1a5011, 0x223067, 0x11b083, 0x2dd139, 0x185061, 0x2b3107, 0x23b0a3, 0x28710d, 0x259065, 0x01d003, 0x2830a3, 0x223083, 0x02b029, 0x1bb059, 0x347301, 0x01d005, 0x529251, 0x0df025, 0x38b347, 0x2771af, 0x1df1a5, 0x0bf049, 0x21d0c1, 0x2771df, 0x2650f1, 0x283065, 0x049003, 0x059007, 0x1a508b, 0x1e71d3, 0x23900d, 0x51b1fd, 0x151035, 0x0a3005, 0x0c50bf, 0x13d061, 0x2bd1af, 0x24b0e3, 0x0e5047, 0x0c102b, 0x44f0e5, 0x32b22d, 0x12501d, 0x2331b1, 0x1b10bf, 0x047017, 0x26913d, 0x06500d, 0x1e7025, 0x0c506b, 0x16107f, 0x24118d, 0x1bb005, 0x1c9125, 0x18510d, 0x20b0ad, 0x1330b3, 0x4c70a3, 0x1850e3, 0x1eb00d, 0x1a3137, 0x2a111b, 0x1e701f, 0x2831fd, 0x1070e3, 0x065025, 0x1df061, 0x1c1139, 0x23b20b, 0x21d17f, 0x1b1083, 0x13d005, 0x1070e5, 0x1cd09d, 0x259017, 0x0bf005, 0x1510f1, 0x047013, 0x167017, 0x2690ef, 0x0b5047, 0x139025, 0x3cb047, 0x14b0d3, 0x2771cf, 0x1eb0b5, 0x1df025, 0x257241, 0x409239, 0x1bb0fb, 0x28d00b, 0x0a7083, 0x047025, 0x21d06b, 0x2f922d, 0x1c100b, 0x1cd1bb, 0x13703b, 0x1c90c7, 0x5951f3, 0x0b5005, 0x3b3269, 0x2cf28d, 0x31d25f, 0x18d0a3, 0x0c706b, 0x10109d, 0x2f90d3, 0x09503d, 0x0b500d, 0x28700d, 0x15d11b, 0x35502f, 0x03d035, 0x251043, 0x05301f, 0x3052a5, 0x2bd1af, 0x22321d, 0x09503d, 0x2810c1, 0x13706d, 0x059025, 0x33501f, 0x0d307f, 0x09d071, 0x79f611, 0x0c702f, 0x2f9277, 0x22301d, 0x04303b, 0x00b005, 0x5bf239, 0x0ad03b, 0x42528d, 0x2330c5, 0x61150b, 0x28113d, 0x1b716f, 0x04f043, 0x0a300d, 0x071025, 0x089035, 0x12501d, 0x31323b, 0x38f095, 0x3cb1c9, 0x0fb0d3, 0x2091a5, 0x23303d, 0x1eb067, 0x23904f, 0x35b043, 0x0fb0df, 0x15d0c1, 0x1330ef, 0x101017, 0x1f314b, 0x043005, 0x2511f3, 0x1d300d, 0x02b01f, 0x0c7053, 0x1190df, 0x2dd1a3, 0x2930c1, 0x1370b3, 0x08900b, 0x269059, 0x0c7017, 0x3f1011, 0x223107, 0x29504f, 0x17b005, 0x2bd25f, 0x083029, 0x20b01d, 0x1eb00b, 0x347313, 0x1b110d, 0x107059, 0x1b70e9, 0x26b269, 0x191119, 0x08903d, 0x1150e3, 0x239161, 0x0df011, 0x20b11b, 0x167047, 0x35514b, 0x0e9059, 0x0c5029, 0x10d0c1, 0x06700d, 0x259017, 0x08900d, 0x1e70fb, 0x3cb3b9, 0x11b053, 0x4cf4c1, 0x2c5257, 0x37110d, 0x09d047, 0x11510f, 0x23b0f1, 0x469161, 0x1f303b, 0x18506d, 0x14b061, 0x27717f, 0x0e3097, 0x089005, 0x1c110d, 0x277259, 0x0b50b3, 0x0df097, 0x097071, 0x139071, 0x0a306d, 0x1a3119, 0x175095, 0x26510d, 0x0e509d, 0x18506b, 0x0ef06b, 0x1b10a3, 0x0fb059, 0x10d047, 0x0bf00d, 0x13908b, 0x3a100b, 0x2090d3, 0x09d095, 0x0a7049, 0x2390ad, 0x0e900d, 0x35b065, 0x137101, 0x2e30e3, 0x07101f, 0x1c1097, 0x07101f, 0x08b083, 0x3c7049, 0x0a308b, 0x161049, 0x22d053, 0x3f1259, 0x17b047, 0x2231df, 0x31308b, 0x05300b, 0x13d071, 0x2091a3, 0x1fd053, 0x1c1029, 0x137025, 0x42d005, 0x2091a5, 0x3732b3, 0x083061, 0x22d07f, 0x32b10f, 0x17b005, 0x097017, 0x293053, 0x49347f, 0x3372cf, 0x0ad049, 0x15b095, 0x06b005, 0x03502b, 0x167083, 0x1c100b, 0x0df03d, 0x1c904f, 0x083017, 0x2e71e7, 0x0c1011, 0x1cf0c7, 0x1a303d, 0x2dd251, 0x191151, 0x33710f, 0x115095, 0x1910b5, 0x23b095, 0x233097, 0x28d017, 0x4cd281, 0x1fd0c7, 0x329017, 0x0a7025, 0x0b306d, 0x3772b3, 0x373011, 0x0f1043, 0x2c5251, 0x10f06d, 0x26902b, 0x095071, 0x125095, 0x18d0e9, 0x2a50fb, 0x1df0e3, 0x0c5025, 0x2871b7, 0x295047, 0x185053, 0x5510f1, 0x241115, 0x14b03d, 0x24b0a3, 0x1e71c1, 0x05904f, 0x115059, 0x38b005, 0x1850e3, 0x13d049, 0x01f005, 0x1d30a7, 0x50b32b, 0x125047, 0x3c71a3, 0x1af071, 0x0c5005, 0x03b00d, 0x2ef03b, 0x4bd0b5, 0x371089, 0x11500d, 0x06b01f, 0x4a92cf, 0x089071, 0x0a3007, 0x119043, 0x3a933b, 0x1330ef, 0x1bb02f, 0x0df005, 0x1a3167, 0x0df0b5, 0x167011, 0x2bd00d, 0x125067, 0x3f5377, 0x0e909d, 0x04900b, 0x11b0df, 0x13d0c1, 0x25909d, 0x22d1bb, 0x0e50a7, 0x10d067, 0x1af0b5, 0x2f5089, 0x3b3269, 0x40710d, 0x3b3305, 0x151137, 0x1a506d, 0x18513d, 0x22d10d, 0x35f175, 0x2d700d, 0x061013, 0x05903d, 0x19901d, 0x1cd0ef, 0x139065, 0x11b04f, 0x2a500d, 0x551065, 0x28324b, 0x1fd18d, 0x089083, 0x2bd139, 0x0e3053, 0x1670e3, 0x0e50c1, 0x32b2cf, 0x0fb0e9, 0x52710f, 0x083029, 0x4ff335, 0x52f1c9, 0x0ad04f, 0x17b0b3, 0x20b047, 0x3552a1, 0x0ad097, 0x18d095, 0x119089, 0x2bd1e7, 0x1a5071, 0x08900d, 0x0ef017, 0x083043, 0x577059, 0x293265, 0x14b0ef, 0x1cd175, 0x35b101, 0x26b15d, 0x1070fb, 0x3e51d3, 0x089013, 0x0b3005, 0x28d283, 0x241233, 0x397125, 0x1d3139, 0x0ef017, 0x15b043, 0x11b03d, 0x377287, 0x20b199, 0x1d303b, 0x1f704f, 0x11b03b, 0x23917b, 0x283089, 0x02900d, 0x2f9139, 0x047003, 0x5d5059, 0x1150a7, 0x329283, 0x13d035, 0x15b08b, 0x2c5115, 0x10d02f, 0x0ad0a3, 0x02500d, 0x463223, 0x27710f, 0x17f151, 0x15d151, 0x1df161, 0x22d083, 0x3b917f, 0x15d101, 0x13303b, 0x067049, 0x0b300b, 0x26506d, 0x1e7071, 0x1c9139, 0x20b089, 0x06703b, 0x1c906b, 0x1af115, 0x38b2c5, 0x21d0e3, 0x2231e7, 0x2e704f, 0x30502f, 0x0bf0a3, 0x5113e5, 0x1610e3, 0x277241, 0x0c1007, 0x191049, 0x2090e5, 0x1a308b, 0x1cd133, 0x3b902b, 0x25f137, 0x2870b5, 0x17b017, 0x2091af, 0x1190f1, 0x44f0fb, 0x1f30a3, 0x335035, 0x2bd029, 0x08300d, 0x19117b, 0x067007, 0x0fb061, 0x2f911b, 0x1a5059, 0x29306d, 0x4a3443, 0x38f239, 0x0c70a7, 0x1bb005, 0x185125, 0x0c5035, 0x293133, 0x1af0bf, 0x139043, 0x115017, 0x2391e7, 0x11b0f1, 0x233139, 0x32b281, 0x043035, 0x3e5239, 0x2e7061, 0x0fb005, 0x25f10d, 0x14b01d, 0x30503d, 0x3f5005, 0x38f005, 0x3291fd, 0x11510d, 0x449281, 0x04703b, 0x06d017, 0x17f03d, 0x2a51e7, 0x10703b, 0x36d15d, 0x33d17f, 0x1b7133, 0x40928d, 0x1f7017, 0x0c100d, 0x1eb017, 0x209161, 0x065049, 0x06d025, 0x3ad185, 0x1c104f, 0x0c7047, 0x1f718d, 0x175133, 0x09d013, 0x137065, 0x19103d, 0x1a515b, 0x0f1065, 0x329049, 0x0df011, 0x1b71af, 0x15b0f1, 0x133125, 0x13703d, 0x2bd175, 0x151119, 0x043011, 0x1cf125, 0x101029, 0x1fd04f, 0x2f90e3, 0x5db107, 0x337175, 0x107095, 0x089035, 0x07f003, 0x0c5035, 0x0df0c5, 0x3b3371, 0x257047, 0x199185, 0x1bb095, 0x09700d, 0x20b1b1, 0x26513d, 0x067061, 0x1a3053, 0x23b017, 0x10700d, 0x08b049, 0x1c106d, 0x067025, 0x13910f, 0x08b053, 0x463359, 0x15b101, 0x23b08b, 0x18d151, 0x1e710d, 0x277071, 0x0fb01d, 0x2c5257, 0x0a703d, 0x257101, 0x1a3035, 0x0e501d, 0x071059, 0x1eb005, 0x1150e5, 0x25f14b, 0x01f00d, 0x1fd0df, 0x2591d3, 0x0e301f, 0x2870b3, 0x31d06d, 0x1bb0a3, 0x3c717b, 0x3fd2f9, 0x13710d, 0x03d035, 0x0bf029, 0x16f0bf, 0x1a50b3, 0x06d017, 0x26910f, 0x04700d, 0x1f71eb, 0x15b017, 0x175139, 0x0fb071, 0x4fd013, 0x2ef281, 0x1bb0ef, 0x16f003, 0x125043, 0x2331b1, 0x16f10f, 0x119029, 0x1c90b5, 0x1c9119, 0x065061, 0x30104f, 0x1b1047, 0x1fd14b, 0x053005, 0x08b089, 0x3130df, 0x095007, 0x1bb035, 0x24b1f3, 0x1e71b1, 0x16f03d, 0x10d00d, 0x18d03d, 0x31d0c7, 0x2571df, 0x3371eb, 0x241095, 0x55d061, 0x053013, 0x10f043, 0x24b13d, 0x095049, 0x0df005, 0x3a9281, 0x1f71a5, 0x1fd00d, 0x047029, 0x2d71af, 0x28d281, 0x0df0bf, 0x11500b, 0x209089, 0x20b043, 0x0ef065, 0x3b3241, 0x1d30c5, 0x265191, 0x06d02b, 0x2590ef, 0x0a701d, 0x0f1067, 0x45d1b7, 0x1c100d, 0x1bb029, 0x20b00d, 0x083043, 0x1af007, 0x41b2cf, 0x28d1fd, 0x08b06d, 0x35f00d, 0x26b0e5, 0x043035, 0x2a503b, 0x1010bf, 0x33d1f7, 0x26b107, 0x3ad005, 0x1610bf, 0x31d2ef, 0x04f03d, 0x2e7101, 0x5813b3, 0x14b0b3, 0x10f013, 0x185043, 0x0e309d, 0x0df059, 0x31307f, 0x38f035, 0x4e1257, 0x21d1af, 0x1f315b, 0x0a3059, 0x33d2c5, 0x4fd02b, 0x17502b, 0x28110f, 0x233053, 0x0fb089, 0x1b700d, 0x10f029, 0x4452bd, 0x2b31cf, 0x6f1097, 0x281233, 0x22d035, 0x1990e3, 0x18d025, 0x3a1049, 0x1610df, 0x2c511b, 0x25118d, 0x2f924b, 0x017013, 0x01f00b, 0x04300d, 0x15b119, 0x18d049, 0x1a504f, 0x23b223, 0x26910d, 0x0ad08b, 0x0e9067, 0x293013, 0x233059, 0x2090f1, 0x26b0a3, 0x12510d, 0x32b313, 0x33d1a5, 0x1750ad, 0x1c10c7, 0x293101, 0x09d067, 0x2951eb, 0x199013, 0x1c107f, 0x239185, 0x095059, 0x32b1fd, 0x257199, 0x0c707f, 0x01d011, 0x0b300b, 0x0c1005, 0x20b10d, 0x16f15b, 0x0b507f, 0x3d1167, 0x0e902b, 0x06100d, 0x17f107, 0x15b0f1, 0x0d30ad, 0x01300d, 0x2ab0f1, 0x2651df, 0x17f06b, 0x23916f, 0x16f047, 0x293035, 0x06500d, 0x0b500d, 0x0e9049, 0x23916f, 0x335329, 0x3b32ef, 0x04f00d, 0x251071, 0x19902f, 0x13d06b, 0x10f071, 0x1d304f, 0x4253d1, 0x0e308b, 0x06102f, 0x0d3013, 0x15b029, 0x24b06b, 0x133059, 0x0e9011, 0x1a50b5, 0x14b101, 0x3292a1, 0x067059, 0x23b013, 0x37309d, 0x1a50fb, 0x0d3095, 0x23b06b, 0x1a3005, 0x30504f, 0x199167, 0x265003, 0x13d119, 0x21d17f, 0x09d071, 0x15b049, 0x47f16f, 0x3010a3, 0x33b2dd, 0x3f5305, 0x1fd043, 0x28d251, 0x1af1a3, 0x18d16f, 0x2f9125, 0x02f013, 0x20b00d, 0x23309d, 0x02f029, 0x1b70c7, 0x4630ef, 0x0d3035, 0x33d313, 0x151011, 0x02900d, 0x1e7119, 0x4cd2c5, 0x3c7265, 0x347059, 0x1c9119, 0x1cd137, 0x18d0ad, 0x35f0e5, 0x18d10f, 0x1c90ad, 0x1610bf, 0x2ab035, 0x3550e3, 0x1f307f, 0x17503b, 0x23b161, 0x71f6df, 0x1750f1, 0x13d139, 0x115065, 0x41b28d, 0x18d125, 0x2ef0b5, 0x0c5005, 0x21d161, 0x42d3df, 0x4071c1, 0x1cf00d, 0x04301f, 0x3130e3, 0x13304f, 0x0b300d, 0x26b10f, 0x137065, 0x0e50d3, 0x1b1065, 0x10f09d, 0x4491c9, 0x10d02b, 0x137005, 0x33d137, 0x1e7095, 0x23b035, 0x167133, 0x2811c9, 0x1fd133, 0x0b304f, 0x337305, 0x0b309d, 0x21d00b, 0x05304f, 0x0ad0a7, 0x161139, 0x10d0b3, 0x10d083, 0x02901d, 0x1c9097, 0x1b1175, 0x55d17f, 0x49d013, 0x1e7083, 0x2ef0c7, 0x3d715d, 0x101011, 0x09706d, 0x265139, 0x3590c5, 0x0c703b, 0x07f025, 0x0e5017, 0x1eb119, 0x083025, 0x05302b, 0x2d7053, 0x42d241, 0x2cf1a3, 0x4552b3, 0x151089, 0x25f067, 0x2dd003, 0x04f005, 0x0e3013, 0x10f083, 0x2b3003, 0x0d3035, 0x2c51b7, 0x049047, 0x1eb101, 0x1a510f, 0x24b0fb, 0x11b089, 0x1af059, 0x2a523b, 0x2f915b, 0x3291e7, 0x2e31c9, 0x4272a1, 0x1190c7, 0x17f00d, 0x0fb02b, 0x0fb0ef, 0x0fb07f, 0x30503d, 0x10f029, 0x277241, 0x233071, 0x035025, 0x0df0a7, 0x2ab01f, 0x137133, 0x2e306b, 0x175119, 0x23307f, 0x22d025, 0x04702b, 0x125003, 0x06b049, 0x00d005, 0x005003, 0x2091af, 0x373209, 0x1c10e3, 0x1f3095, 0x1250c1, 0x011005, 0x2571bb, 0x241101, 0x15b119, 0x0e902f, 0x17f029, 0x11b07f, 0x14b13d, 0x137061, 0x1a3125, 0x06b04f, 0x2231cf, 0x22d10f, 0x1af125, 0x40910d, 0x067029, 0x15d0c1, 0x0c5049, 0x047025, 0x277125, 0x07103d, 0x5c9005, 0x209101, 0x1a30b3, 0x1fd191, 0x0c70a7, 0x13d01d, 0x32b1fd, 0x0e30b3, 0x0f1053, 0x1b70e5, 0x24b071, 0x1c9097, 0x2b3025, 0x22302b, 0x185017, 0x24115d, 0x15d089, 0x0f102b, 0x47f26b, 0x6791df, 0x265067, 0x3472ab, 0x2bd0c7, 0x3c7137, 0x18510d, 0x0fb0ad, 0x3471eb, 0x16f07f, 0x0df0bf, 0x1850e3, 0x0ad049, 0x3471eb, 0x03b011, 0x239199, 0x35901f, 0x0d303b, 0x0b303b, 0x16101d, 0x06b043, 0x06100d, 0x01f005, 0x1f31b1, 0x287047, 0x13d0f1, 0x15d07f, 0x14b133, 0x11500d, 0x01d005, 0x19916f, 0x1d30f1, 0x1fd097, 0x1250a7, 0x061029, 0x15d003, 0x08b06d, 0x25106b, 0x08b02f, 0x26b239, 0x2ef1a3, 0x089025, 0x233053, 0x32b047, 0x22d061, 0x26b06d, 0x11b083, 0x2870a3, 0x4a91cd, 0x175053, 0x10107f, 0x1cf06d, 0x101011, 0x1cf00b, 0x3050bf, 0x23911b, 0x22d14b, 0x191107, 0x1f3089, 0x1c9035, 0x1eb047, 0x1a309d, 0x0fb0e3, 0x15b115, 0x15d089, 0x0b3095, 0x06500d, 0x33506b, 0x239047, 0x1e717b, 0x2e31b1, 0x1190d3, 0x06101d, 0x25920b, 0x0c708b, 0x0e308b, 0x2ab101, 0x42715d, 0x161029, 0x107035, 0x1c10d3, 0x24b00d, 0x41935b, 0x17b0bf, 0x3371c1, 0x2511cf, 0x17b0a3, 0x0c5003, 0x1a50b5, 0x2f9259, 0x1a513d, 0x1b101f, 0x3f10f1, 0x11b00b, 0x1070e5, 0x16711b, 0x1070c5, 0x1910d3, 0x0e907f, 0x0bf049, 0x281257, 0x03d01f, 0x06501f, 0x52f4c7, 0x0c1089, 0x259167, 0x107101, 0x10f025, 0x049005, 0x15d065, 0x0e9097, 0x1bb119, 0x083049, 0x1c1083, 0x0a3095, 0x1850e3, 0x06100d, 0x2e30e9, 0x1390e9, 0x02b005, 0x067053, 0x115059, 0x2811eb, 0x3ad011, 0x239139, 0x0c707f, 0x00d00b, 0x10f029, 0x08900d, 0x17f053, 0x1750c7, 0x1f70c1, 0x1910df, 0x2f508b, 0x0a3025, 0x06d03d, 0x0bf03d, 0x75726b, 0x2691b7, 0x251241, 0x2a517b, 0x125095, 0x0a700d, 0x3fd011, 0x083005, 0x2f9043, 0x03d02f, 0x28d22d, 0x08302f, 0x335011, 0x21d115, 0x4c7355, 0x0c10b5, 0x31d06b, 0x01700d, 0x04f00d, 0x3c71cd, 0x2f506d, 0x185013, 0x2a1281, 0x0a7061, 0x199059, 0x15b089, 0x083065, 0x1c110f, 0x0fb03d, 0x419067, 0x14b0ad, 0x1eb1d3, 0x1fd139, 0x20b053, 0x2091b1, 0x01f00d, 0x3f5119, 0x28d065, 0x13902f, 0x22d049, 0x2ab139, 0x26b119, 0x16f06d, 0x0bf0a3, 0x23916f, 0x0f1013, 0x17500b, 0x22d11b, 0x2b3259, 0x259059, 0x463269, 0x0df043, 0x3a1335, 0x06d06b, 0x1d300d, 0x061053, 0x083043, 0x01f005, 0x089061, 0x2bd293, 0x0ef0d3, 0x4fd45d, 0x09702b, 0x13d00b, 0x397005, 0x0ad089, 0x1e70ad, 0x06d04f, 0x151137, 0x07104f, 0x0df025, 0x22d18d, 0x13d013, 0x02f029, 0x071035, 0x2570e5, 0x043013, 0x06b00b, 0x03b005, 0x1b11a5, 0x1670b5, 0x2bd13d, 0x133029, 0x1990e9, 0x223083, 0x727641, 0x44507f, 0x20b199, 0x151095, 0x1c1065, 0x0fb0ef, 0x2cf1d3, 0x0c702b, 0x1c9011, 0x0e50ad, 0x1eb049, 0x083025, 0x55118d, 0x397337, 0x17b065, 0x337059, 0x22d0c5, 0x0fb065, 0x1a3035, 0x0a7095, 0x14b139, 0x17b007, 0x313061, 0x24b005, 0x0df0c7, 0x6114a3, 0x30500d, 0x1c115d, 0x27709d, 0x06102f, 0x1c1061, 0x09501f, 0x137107, 0x1a5175, 0x16709d, 0x125035, 0x167137, 0x06b02f, 0x1f7139, 0x409293, 0x1a501d, 0x0fb035, 0x13d0b3, 0x13d0bf, 0x18d0e5, 0x2e313d, 0x1df0c1, 0x2bd1cf, 0x40f097, 0x2d7025, 0x1e7029, 0x05900d, 0x191035, 0x2391d3, 0x08902b, 0x04f043, 0x167059, 0x0bf089, 0x259053, 0x199175, 0x07f06b, 0x38f067, 0x28d095, 0x1f70ad, 0x1fd1bb, 0x18506b, 0x1bb1b7, 0x1a500d, 0x1610a7, 0x5513b3, 0x067025, 0x04703d, 0x0fb06b, 0x1150a7, 0x0c10b5, 0x1af151, 0x0bf00d, 0x2691cd, 0x1c90e3, 0x1bb0ef, 0x10f08b, 0x0a703d, 0x08b043, 0x3f1067, 0x233097, 0x2b315b, 0x33b095, 0x03b013, 0x4ff40f, 0x20b0c1, 0x1a302b, 0x4a910f, 0x0c100b, 0x07f01f, 0x18d0c5, 0x0a3095, 0x115029, 0x2f9137, 0x15b13d, 0x13300d, 0x8e12cf, 0x269259, 0x31323b, 0x167107, 0x3f128d, 0x1390a3, 0x13900d, 0x2dd017, 0x0f1025, 0x19904f, 0x1af0c1, 0x22304f, 0x06d005, 0x1610e9, 0x557175, 0x33d1e7, 0x4430f1, 0x01f005, 0x17f15b, 0x10f047, 0x22d1a3, 0x33b161, 0x2c50a7, 0x251151, 0x2771af, 0x119029, 0x13307f, 0x11b0c5, 0x1bb061, 0x3770c5, 0x76d0e5, 0x20906b, 0x2090c5, 0x029025, 0x1fd0ef, 0x2650c5, 0x25f251, 0x251035, 0x03500d, 0x40f251, 0x40f3ad, 0x17b053, 0x0df0ad, 0x74f5ad, 0x2a51df, 0x7c34eb, 0x2411c9, 0x18d01d, 0x1a5071, 0x1af067, 0x445239, 0x31d2e3, 0x10f101, 0x14b0fb, 0x23304f, 0x09d013, 0x06b059, 0x09706b, 0x3fd251, 0x167011, 0x4492ab, 0x2e3259, 0x071011, 0x1f316f, 0x16711b, 0x37113d, 0x071025, 0x175095, 0x3b90e5, 0x257185, 0x0c503b, 0x4072bd, 0x2e3167, 0x191005, 0x0e50b5, 0x0ad035, 0x1010ad, 0x23b1df, 0x1e710f, 0x07f06d, 0x067059, 0x1af185, 0x17f02f, 0x0bf065, 0x293097, 0x065049, 0x10f067, 0x09d03d, 0x13d02b, 0x4cd3c7, 0x19916f, 0x1b10e9, 0x0b30ad, 0x1eb067, 0x0ef0e3, 0x2f92f5, 0x10d0df, 0x06500d, 0x06b067, 0x061005, 0x1c9029, 0x10101d, 0x24111b, 0x07f005, 0x355059, 0x107083, 0x0fb07f, 0x0df03d, 0x1f3003, 0x28d0b5, 0x1b1115, 0x097053, 0x3f11f3, 0x08904f, 0x1670d3, 0x04f03d, 0x14b071, 0x1c9029, 0x1cd00d, 0x40f3fb, 0x15b01d, 0x01f00d, 0x17f047, 0x1f7043, 0x269139, 0x2bd0e9, 0x1bb191, 0x10d03d, 0x46345d, 0x26504f, 0x09d00d, 0x1c1043, 0x293167, 0x5cf0e3, 0x1010a3, 0x0ef00d, 0x0b3089, 0x2ef071, 0x17f061, 0x17b071, 0x33d0ef, 0x1f7095, 0x15b115, 0x191125, 0x2411f7, 0x06b067, 0x22d0ad, 0x10d0a3, 0x0f103d, 0x0bf061, 0x065049, 0x18d08b, 0x1af00b, 0x1990a7, 0x1d30e3, 0x02b013, 0x1390e3, 0x1af14b, 0x4271eb, 0x1c90e3, 0x47f371, 0x13d101, 0x641151, 0x1d300d, 0x25704f, 0x15d107, 0x2ab013, 0x1510f1, 0x065029, 0x101005, 0x3131eb, 0x18d043, 0x1010fb, 0x0e300d, 0x09d035, 0x3ad25f, 0x071025, 0x593107, 0x1df071, 0x3471eb, 0x0b3005, 0x06d011, 0x15b067, 0x2411f7, 0x2411df, 0x1eb043, 0x2a10b3, 0x1cd16f, 0x2951a5, 0x05303b, 0x007005, 0x03b00d, 0x083035, 0x0f100d, 0x137115, 0x2830a3, 0x09d059, 0x239005, 0x2e31f7, 0x3b9095, 0x33b2d7, 0x31d025, 0x167043, 0x269071, 0x1f3065, 0x313119, 0x17f0e3, 0x1f7199, 0x14b03b, 0x11904f, 0x24b137, 0x0e9083, 0x2a102b, 0x22d0f1, 0x18d0d3, 0x137125, 0x2e70e9, 0x0c709d, 0x0df0a7, 0x2e3097, 0x3471f7, 0x0c7029, 0x06701d, 0x02b01f, 0x065035, 0x0e9065, 0x3552e7, 0x11503d, 0x35f071, 0x0b5005, 0x1bb10d, 0x15106b, 0x0e90b5, 0x15b03d, 0x41b2f9, 0x0e90c5, 0x107017, 0x18d03b, 0x01100d, 0x20b083, 0x2411fd, 0x07f029, 0x2f52cf, 0x2ef287, 0x137101, 0x133125, 0x3d1151, 0x251029, 0x00d003, 0x4a9005, 0x281209, 0x0c1043, 0x06d053, 0x2870c1, 0x1b706b, 0x1eb09d, 0x06d03d, 0x1070ef, 0x107061, 0x265259, 0x065043, 0x17b07f, 0x2231f3, 0x2ef1fd, 0x02b005, 0x0b5035, 0x185089, 0x0d307f, 0x2831cd, 0x05303b, 0x1c9011, 0x5934cf, 0x17b029, 0x33d13d, 0x13d0a7, 0x0c5035, 0x17b0fb, 0x2b3013, 0x25f0e9, 0x1a310f, 0x26b209, 0x13d0d3, 0x23b0c5, 0x2f925f, 0x1bb071, 0x065035, 0x293241, 0x15d0b5, 0x15b0e5, 0x0df08b, 0x2770fb, 0x02f005, 0x1b117f, 0x287049, 0x04701f, 0x4cf4c7, 0x133049, 0x295005, 0x61148b, 0x22d071, 0x44f005, 0x137059, 0x1af0fb, 0x32b02b, 0x33d18d, 0x115065, 0x0f1049, 0x209047, 0x043013, 0x0c7049, 0x1f7125, 0x06100d, 0x09d095, 0x16f06b, 0x199059, 0x0fb097, 0x02f003, 0x0d30bf, 0x1bb199, 0x11500d, 0x3fb241, 0x14b005, 0x313233, 0x0e30b5, 0x209185, 0x84124b, 0x577095, 0x18d107, 0x43f233, 0x64102b, 0x07102f, 0x28306d, 0x191137, 0x10d0d3, 0x09503b, 0x13300d, 0x2d7083, 0x503269, 0x40f287, 0x17b0c1, 0x40f33d, 0x3b300d, 0x107053, 0x21d0c5, 0x2a5151, 0x133067, 0x18d10d, 0x03b007, 0x071061, 0x1cd053, 0x0b3011, 0x1a50df, 0x0ad059, 0x2871bb, 0x1c101f, 0x1c1025, 0x1bb043, 0x7cd00d, 0x11910d, 0x47f133, 0x1a501d, 0x1990a3, 0x04901f, 0x449277, 0x0e501d, 0x06b01f, 0x2a1065, 0x18517f, 0x0bf01f, 0x0b5005, 0x5bf21d, 0x3592f5, 0x4c1065, 0x16f007, 0x31d2ef, 0x097005, 0x13310f, 0x0fb06d, 0x061013, 0x0d3049, 0x1a500b, 0x3b900d, 0x11902b, 0x01700b, 0x16f00d, 0x1250f1, 0x55d22d, 0x29318d, 0x32b137, 0x0ad095, 0x1d3151, 0x2811f7, 0x26b1f3, 0x1af11b, 0x2dd035, 0x0ad005, 0x16f025, 0x3df3cb, 0x2b3239, 0x2570e9, 0x2330a3, 0x10103b, 0x3c7013, 0x397137, 0x20b0e3, 0x0b301d, 0x06d065, 0x1fd00d, 0x1a30bf, 0x28d02b, 0x2a10c7, 0x17b115, 0x2331b7, 0x1a506d, 0x0f1059, 0x2c52b3, 0x095089, 0x05900d, 0x269043, 0x283119, 0x2390ef, 0x5654c1, 0x0a7061, 0x0a303b, 0x3551fd, 0x06103d, 0x1cd02b, 0x05302b, 0x15d067, 0x15b115, 0x10101d, 0x10d095, 0x18d0e3, 0x1510c7, 0x3fd0fb, 0x1eb0c1, 0x0e304f, 0x17b047, 0x0c1035, 0x1bb089, 0x329115, 0x2ef21d, 0x08b059, 0x23915b, 0x2f5281, 0x0c10a7, 0x20918d, 0x2510c5, 0x3472ab, 0x0e9053, 0x28d20b, 0x1a50a7, 0x15d0b5, 0x4a335b, 0x107007, 0x0fb0d3, 0x28d0ef, 0x5571cd, 0x33b265, 0x0b3043, 0x2bd1b1, 0x13907f, 0x2ef295, 0x17b0e9, 0x23916f, 0x2a52a1, 0x52940f, 0x1af0df, 0x1190ef, 0x1b709d, 0x025003, 0x3b9209, 0x2b3097, 0x0ad017, 0x15d06d, 0x3a9259, 0x10f00b, 0x0ef06d, 0x25924b, 0x2d723b, 0x1e70a3, 0x17f08b, 0x0e304f, 0x049043, 0x1b1101, 0x22302b, 0x07f005, 0x38f1c9, 0x2dd0bf, 0x25903d, 0x0f107f, 0x17f167, 0x17b0a3, 0x2bd095, 0x049005, 0x3472b3, 0x0c7083, 0x33b2c5, 0x07f03d, 0x1f30b5, 0x2870fb, 0x09d04f, 0x047043, 0x1cd151, 0x1fd107, 0x0c101d, 0x1df0b5, 0x18508b, 0x05304f, 0x3fd02b, 0x1c9139, 0x1d301f, 0x24b083, 0x13d089, 0x06100d, 0x1df10f, 0x21d1a5, 0x241005, 0x0c100d, 0x1a500d, 0x10d043, 0x15b059, 0x2cf06d, 0x3711f3, 0x4a3151, 0x2410a7, 0x17f10d, 0x17f15b, 0x01f00b, 0x13911b, 0x0b300d, 0x25f059, 0x1af0df, 0x13d0e9, 0x0f1043, 0x139007, 0x16f03b, 0x06d067, 0x2d7007, 0x20b03d, 0x0bf061, 0x2e32c5, 0x14b11b, 0x1b1175, 0x1a500d, 0x06b04f, 0x0fb0b3, 0x3470df, 0x2330c7, 0x11510f, 0x1eb049, 0x28d025, 0x427265, 0x1b1025, 0x137065, 0x03d003, 0x025011, 0x13d089, 0x293065, 0x30115b, 0x09d029, 0x1f7053, 0x1a50e3, 0x03502f, 0x1a5029, 0x15d137, 0x19918d, 0x0b3097, 0x1a50c7, 0x3470e5, 0x1f7191, 0x1f7095, 0x2a507f, 0x1c9151, 0x257139, 0x0b307f, 0x04f005, 0x17b0c5, 0x28704f, 0x3e53df, 0x329101, 0x22d1df, 0x11b0df, 0x101025, 0x1d3025, 0x0b5095, 0x1a300d, 0x15d0e5, 0x175151, 0x35b017, 0x20b1b1, 0x3f536d, 0x0df049, 0x047043, 0x13d0c5, 0x1610ad, 0x31d167, 0x24b0f1, 0x26516f, 0x16100b, 0x1a50c7, 0x37125f, 0x17502b, 0x2e303d, 0x03b00b, 0x0c5005, 0x133101, 0x2bd095, 0x301059, 0x233043, 0x097007, 0x2091a3, 0x199137, 0x0a3011, 0x1f7011, 0x071035, 0x337071, 0x083007, 0x18d137, 0x11b00d, 0x0b302b, 0x1eb0bf, 0x46923b, 0x161107, 0x08901d, 0x0ef0e3, 0x425089, 0x31d08b, 0x097047, 0x107025, 0x2bd0ef, 0x11b0df, 0x565335, 0x1df025, 0x05900b, 0x0c1059, 0x1b1095, 0x137005, 0x0e509d, 0x1b10c1, 0x2691eb, 0x39710d, 0x38b0ad, 0x02900d, 0x26917f, 0x03b007, 0x28316f, 0x1c10ef, 0x0d309d, 0x259167, 0x16f029, 0x17f14b, 0x295025, 0x0bf03d, 0x09502f, 0x2bd257, 0x125089, 0x13d107, 0x59538b, 0x15d0c7, 0x0f10ad, 0x22d1d3, 0x04900b, 0x27710f, 0x095043, 0x1cd18d, 0x1df0a3, 0x17b04f, 0x15106b, 0x5150f1, 0x1a5185, 0x2d70e9, 0x14b0d3, 0x065005, 0x19106b, 0x3291a3, 0x20b1a5, 0x1a30c1, 0x0c709d, 0x16101f, 0x22d00d, 0x16708b, 0x13d049, 0x3ad0f1, 0x20b017, 0x15b11b, 0x1b110d, 0x1cd005, 0x0e300d, 0x293283, 0x1a510d, 0x2f90ad, 0x24b119, 0x11900b, 0x0fb083, 0x22d083, 0x3010f1, 0x1b101d, 0x0c70b5, 0x15d0d3, 0x2b31fd, 0x25f223, 0x07f017, 0x1f7049, 0x1f71f3, 0x20b119, 0x06b043, 0x257089, 0x33d0b5, 0x1b702b, 0x2f92dd, 0x14b107, 0x067025, 0x0a301d, 0x11b003, 0x09706d, 0x133013, 0x12504f, 0x04900d, 0x1670bf, 0x137003, 0x0b306b, 0x0c10a7, 0x283265, 0x1b100d, 0x07f03d, 0x1a3017, 0x04f047, 0x2cf139, 0x01d00d, 0x0c703b, 0x2591c9, 0x1c90fb, 0x137119, 0x06d065, 0x2f9097, 0x151115, 0x0fb06d, 0x02900d, 0x13d013, 0x28d1f3, 0x17f007, 0x41b161, 0x25f125, 0x3e5133, 0x397025, 0x21d00d, 0x0e9083, 0x2bd233, 0x101095, 0x2230df, 0x45d2e7, 0x02901d, 0x5291c9, 0x10d059, 0x35506b, 0x1330e3, 0x26b175, 0x4e12f9, 0x277167, 0x047013, 0x137005, 0x05300d, 0x10d071, 0x03b005, 0x09d097, 0x2331a3, 0x02f029, 0x0c500d, 0x137119, 0x38f355, 0x259025, 0x03d029, 0x0ad0a7, 0x0d300b, 0x31d281, 0x1cd1c1, 0x1eb065, 0x13700d, 0x06704f, 0x277035, 0x1cd0a3, 0x493043, 0x2cf0fb, 0x35f06b, 0x25f21d, 0x4fd40f, 0x23b119, 0x137071, 0x0c70b5, 0x1070a7, 0x18d06d, 0x13d005, 0x191115, 0x1d306b, 0x0df065, 0x06d011, 0x18d01d, 0x407283, 0x053025, 0x04f043, 0x1070ef, 0x067043, 0x18503d, 0x1c1003, 0x26b0a3, 0x27704f, 0x38b301, 0x35b1a5, 0x1cd1af, 0x0bf011, 0x1a30df, 0x2f52e7, 0x2a5223, 0x35909d, 0x1c10b3, 0x1bb133, 0x283223, 0x2231c9, 0x03d003, 0x2e32b3, 0x1370e5, 0x10d01f, 0x11903b, 0x03d035, 0x257097, 0x40f32b, 0x1330fb, 0x1f7115, 0x14b03b, 0x26903b, 0x2570bf, 0x29301d, 0x1cf1c9, 0x1850df, 0x0e3025, 0x1190b5, 0x175115, 0x04f01d, 0x1eb0fb, 0x10701d, 0x095065, 0x4eb3b3, 0x3550c1, 0x191043, 0x1a3167, 0x23b053, 0x21d10f, 0x4a3005, 0x1330b5, 0x07102f, 0x10d0c1, 0x03b01f, 0x10f0b5, 0x2dd265, 0x083029, 0x6bb63d, 0x2090c5, 0x1cf0bf, 0x2930b5, 0x20906b, 0x3d107f, 0x22d0ad, 0x0e30bf, 0x427251, 0x22315d, 0x0c5013, 0x15d11b, 0x12504f, 0x1e70d3, 0x137005, 0x2ef1df, 0x1f308b, 0x3e523b, 0x199139, 0x1cf167, 0x16f01f, 0x0b503b, 0x0a7005, 0x06d06b, 0x21d0c5, 0x0df005, 0x4d50a3, 0x17507f, 0x2c510f, 0x2dd0b3, 0x06d061, 0x1d317f, 0x16710d, 0x277265, 0x0fb029, 0x2a5175, 0x1af00b, 0x337277, 0x1fd00b, 0x175059, 0x0ad06d, 0x1010f1, 0x3f11c9, 0x2950bf, 0x047005, 0x2931df, 0x16101d, 0x26b1b7, 0x239017, 0x15d00b, 0x1d314b, 0x0c103d, 0x08b02f, 0x3d715d, 0x10f035, 0x2f928d, 0x45d335, 0x257029, 0x1c106d, 0x0b5053, 0x29513d, 0x1f30d3, 0x0e3043, 0x33d185, 0x053013, 0x17b005, 0x313003, 0x03b01d, 0x0df047, 0x17b161, 0x3352dd, 0x1b703d, 0x02901d, 0x32b329, 0x3590fb, 0x3ad065, 0x101065, 0x0e300d, 0x445013, 0x36d1b7, 0x3fd3b3, 0x15b06d, 0x26b0bf, 0x2330c1, 0x2a5005, 0x0b303d, 0x259151, 0x0a700d, 0x1df15d, 0x301047, 0x329139, 0x08b01f, 0x1a51a3, 0x16f0b3, 0x1cf14b, 0x1e71b1, 0x017005, 0x0e3049, 0x119043, 0x16f0a3, 0x0e302f, 0x3d1137, 0x14b0df, 0x1390fb, 0x46921d, 0x3050e3, 0x28d0ad, 0x1e7151, 0x0e5049, 0x0c7053, 0x3cb191, 0x25706d, 0x0df043, 0x2c5065, 0x03d013, 0x257119, 0x3770d3, 0x1b1137, 0x0ad00d, 0x1f7053, 0x17515b, 0x313083, 0x20b119, 0x071005, 0x41940f, 0x1a5065, 0x071007, 0x3df03d, 0x10103d, 0x01d00d, 0x23b115, 0x161119, 0x10f067, 0x0d3071, 0x5d50a7, 0x23b00b, 0x02b01f, 0x3c7059, 0x04303d, 0x18d06d, 0x2cf059, 0x3f52ef, 0x1b703d, 0x409065, 0x24b15b, 0x1190b5, 0x139071, 0x06b04f, 0x13903b, 0x161101, 0x2f9101, 0x15d125, 0x035003, 0x2ab0ef, 0x3f10c1, 0x3590fb, 0x199007, 0x3b316f, 0x28d09d, 0x14b06d, 0x05300b, 0x2091c1, 0x09501f, 0x581337, 0x4090bf, 0x28115b, 0x14b089, 0x1f30ad, 0x05304f, 0x18516f, 0x31d167, 0x01d00b, 0x0c501d, 0x20b09d, 0x18d0c1, 0x21d065, 0x2cf23b, 0x1eb013, 0x02f00b, 0x25f06b, 0x1b1107, 0x1f30b3, 0x0ad007, 0x223049, 0x23b1d3, 0x22d035, 0x259095, 0x02b005, 0x1b10c7, 0x095047, 0x38f1b1, 0x1a307f, 0x1250fb, 0x19109d, 0x295139, 0x02501f, 0x18d005, 0x3a90fb, 0x167017, 0x26b01d, 0x1fd0df, 0x1df0c1, 0x1a507f, 0x0a700d, 0x03d00d, 0x1910b5, 0x2d7239, 0x38b00b, 0x1750c7, 0x1cd15d, 0x28d0fb, 0x15d00b, 0x0c700d, 0x08b03d, 0x1af15d, 0x0e506b, 0x03b00d, 0x15d09d, 0x15b005, 0x2dd191, 0x1bb03d, 0x0b500b, 0x1850c7, 0x02900d, 0x1f31e7, 0x05903b, 0x2ef0bf, 0x065061, 0x355239, 0x14b0c1, 0x1f3007, 0x29307f, 0x11b0a7, 0x1670bf, 0x15b133, 0x0a7097, 0x0c1035, 0x0ef003, 0x047035, 0x0bf01d, 0x107089, 0x26b047, 0x20b1a3, 0x0ad049, 0x15d02b, 0x0c7029, 0x31d03d, 0x10d00d, 0x083005, 0x3711b7, 0x16f025, 0x2f516f, 0x0e506b, 0x41b2f5, 0x0a3013, 0x2091c1, 0x15b059, 0x049007, 0x1750a3, 0x0fb0e3, 0x125065, 0x089005, 0x14b059, 0x1a3035, 0x2ab09d, 0x1b11af, 0x18d133, 0x24b1c9, 0x3e5175, 0x4252cf, 0x25110f, 0x1fd137, 0x43f083, 0x0a7035, 0x1a5125, 0x25923b, 0x0b3053, 0x13d02b, 0x2e708b, 0x355065, 0x28111b, 0x2ef20b, 0x2830b3, 0x0ef00d, 0x1b1185, 0x04f011, 0x16106b, 0x0bf025, 0x1af10f, 0x38f1c9, 0x02f01d, 0x25f0d3, 0x52f2e3, 0x10d09d, 0x0b507f, 0x3711af, 0x1b7175, 0x17f0b5, 0x2690d3, 0x1a311b, 0x1fd09d, 0x03b035, 0x0e5053, 0x611599, 0x17f0fb, 0x06d049, 0x3710c7, 0x13300d, 0x1df013, 0x09706d, 0x2dd1df, 0x18d029, 0x16110f, 0x19110f, 0x16713d, 0x443257, 0x17f02b, 0x4250ad, 0x2930b3, 0x44f2b3, 0x2bd1af, 0x0a703b, 0x2ef199, 0x0ef047, 0x133125, 0x04300b, 0x0a3065, 0x22d0c1, 0x33d313, 0x0b3011, 0x151107, 0x25f259, 0x1850c7, 0x0f107f, 0x06d02b, 0x24111b, 0x2e7097, 0x3e5337, 0x1150e9, 0x463097, 0x15d0bf, 0x107047, 0x0c70b5, 0x065011, 0x18502f, 0x04700d, 0x2d7257, 0x01300b, 0x49d2c5, 0x0b301d, 0x2b30c7, 0x0d3071, 0x11503d, 0x1b10f1, 0x23b08b, 0x35520b, 0x08b049, 0x3351b7, 0x065049, 0x0b504f, 0x359337, 0x011005, 0x07f03b, 0x0c503d, 0x1d314b, 0x517355, 0x3131a5, 0x0c5059, 0x199017, 0x13d09d, 0x33b17b, 0x407139, 0x1f706d, 0x1150e3, 0x209137, 0x10101d, 0x17b0e5, 0x18d11b, 0x2510b5, 0x01d00d, 0x0c5053, 0x3c71df, 0x095049, 0x15d00d, 0x1d3061, 0x15d10f, 0x167065, 0x48101d, 0x44316f, 0x38f33d, 0x115029, 0x17509d, 0x0c5065, 0x011007, 0x1f3083, 0x11b06d, 0x16109d, 0x25114b, 0x1bb01d, 0x2b30e5, 0x2f9133, 0x1df167, 0x2a1119, 0x2bd17b, 0x33b0c1, 0x05300b, 0x293005, 0x04f02f, 0x10f08b, 0x09703b, 0x14b005, 0x043005, 0x137083, 0x13d067, 0x2bd089, 0x21d1f7, 0x1a50e5, 0x0ef02b, 0x26b15b, 0x00b005, 0x00d005, 0x06d00d, 0x25f18d, 0x0df03b, 0x065061, 0x0e30bf, 0x17b15d, 0x03b02b, 0x3e5115, 0x35f095, 0x5db17f, 0x1b1005, 0x0b303b, 0x281269, 0x13901f, 0x107071, 0x26500d, 0x10f007, 0x067011, 0x2a507f, 0x10d011, 0x0f1095, 0x239223, 0x1b101d, 0x33b011, 0x3fd13d, 0x2dd137, 0x2bd20b, 0x18d071, 0x281047, 0x1a30a7, 0x33b20b, 0x2a513d, 0x2390d3, 0x1f30bf, 0x1e711b, 0x42d2d7, 0x305005, 0x3d12d7, 0x13704f, 0x3b3025, 0x1df0c7, 0x24110f, 0x257089, 0x043005, 0x151107, 0x1fd1f7, 0x38b2e7, 0x4eb0c7, 0x3f53b3, 0x18d119, 0x175053, 0x16f03b, 0x20b1a3, 0x3df0bf, 0x1b1013, 0x41b33b, 0x1990c1, 0x0e3089, 0x1f3029, 0x0df06b, 0x23b0f1, 0x083049, 0x2771e7, 0x09d043, 0x1eb089, 0x083005, 0x3ad295, 0x35f0ad, 0x16706b, 0x24b0fb, 0x241017, 0x161029, 0x21d04f, 0x31322d, 0x28d0e3, 0x265065, 0x0e908b, 0x1a5115, 0x2331e7, 0x0ef053, 0x28302f, 0x2e30b3, 0x07f035, 0x0a7005, 0x1af0bf, 0x1510fb, 0x58f397, 0x067059, 0x305017, 0x1cd14b, 0x2930d3, 0x15b0e3, 0x125065, 0x0e903b, 0x0a7025, 0x17b049, 0x269265, 0x20b0c7, 0x01d017, 0x2a108b, 0x0b308b, 0x445005, 0x13d119, 0x2cf097, 0x359003, 0x2830a7, 0x1fd0d3, 0x185137, 0x3d71c1, 0x097043, 0x065007, 0x35906b, 0x2e30fb, 0x0c106d, 0x2231bb, 0x293059, 0x1c9071, 0x2230a7, 0x4cf003, 0x2dd1bb, 0x1370e3, 0x0ef059, 0x17501d, 0x1f313d, 0x1c10b3, 0x0ad08b, 0x32b185, 0x13d0fb, 0x28d287, 0x0b5013, 0x3592bd, 0x0b302f, 0x1cf01d, 0x139013, 0x42d355, 0x31d0ef, 0x2f504f, 0x287119, 0x28715b, 0x10d03d, 0x3df06b, 0x1150c5, 0x1bb00d, 0x151035, 0x8715e7, 0x0d30c5, 0x0df0c7, 0x1750a3, 0x071017, 0x043003, 0x115005, 0x06502b, 0x107083, 0x19903b, 0x139035, 0x0c7025, 0x0b301d, 0x1b118d, 0x06100d, 0x01300b, 0x45d005, 0x1af017, 0x1910df, 0x03d025, 0x089029, 0x35b1a3, 0x33510d, 0x0fb0d3, 0x119101, 0x11909d, 0x137125, 0x10d0df, 0x03b025, 0x16103b, 0x06d01d, 0x2811a3, 0x10f043, 0x1cf053, 0x07f011, 0x33b2e3, 0x175025, 0x10f047, 0x1cf011, 0x017005, 0x0b306b, 0x0d30c1, 0x5934a9, 0x2391b1, 0x3ad115, 0x175071, 0x23b059, 0x2ef0bf, 0x0a307f, 0x0e90e5, 0x1d30e5, 0x1eb047, 0x035025, 0x1150e5, 0x191061, 0x0a7011, 0x0fb061, 0x3470a7, 0x257005, 0x13d053, 0x1a50f1, 0x14b08b, 0x167133, 0x10f0df, 0x5510e3, 0x16714b, 0x0a7053, 0x1610e3, 0x5bf1a3, 0x2a5269, 0x1cf1a3, 0x269115, 0x1d303b, 0x101049, 0x18d151, 0x35b1fd, 0x17b14b, 0x359083, 0x01100d, 0x287043, 0x2571bb, 0x15d02b, 0x119013, 0x09501d, 0x01f005, 0x13900d, 0x00d005, 0x17f08b, 0x1df089, 0x1c904f, 0x0c1083, 0x14b0fb, 0x2830fb, 0x2bd035, 0x46324b, 0x13311b, 0x1c1119, 0x043025, 0x0b50ad, 0x07f03d, 0x0ad043, 0x15b007, 0x0b303d, 0x32b061, 0x33d337, 0x071049, 0x049011, 0x1df13d, 0x5db16f, 0x3371e7, 0x0c5025, 0x17b15b, 0x2e32dd, 0x40f03d, 0x3e5133, 0x1b10a3, 0x2570e5, 0x1eb059, 0x09507f, 0x18d007, 0x1b7185, 0x161107, 0x6f72ef, 0x11b119, 0x089043, 0x1150df, 0x11b035, 0x095025, 0x269107, 0x2ef005, 0x16115b, 0x16f01d, 0x10100d, 0x4493d1, 0x19915b, 0x2dd185, 0x209043, 0x33d013, 0x3fd083, 0x295233, 0x107007, 0x151097, 0x175071, 0x3730fb, 0x1a306b, 0x2bd0bf, 0x38b01d, 0x43f139, 0x11b08b, 0x1010ad, 0x17f0ad, 0x35f161, 0x373277, 0x1a3043, 0x1850f1, 0x233071, 0x359233, 0x11906d, 0x1f70c5, 0x067005, 0x29514b, 0x35b083, 0x46913d, 0x1eb00d, 0x09d047, 0x17b02f, 0x13d003, 0x115067, 0x15d067, 0x2e72b3, 0x295185, 0x239005, 0x10f0b5, 0x7132f9, 0x1f701f, 0x1670e3, 0x1bb07f, 0x10d01d, 0x293283, 0x31d2b3, 0x0e303d, 0x0ef097, 0x23b005, 0x0e909d, 0x03b005, 0x21d15d, 0x16f005, 0x5173f1, 0x6075c9, 0x139125, 0x1150e9, 0x09700b, 0x0e9061, 0x18d09d, 0x10f071, 0x2a1097, 0x2810c5, 0x0fb0b3, 0x1b100d, 0x3350b3, 0x2ef1fd, 0x0bf067, 0x0c5059, 0x281191, 0x71f125, 0x0bf059, 0x133101, 0x08307f, 0x07102b, 0x301281, 0x30103d, 0x1f70d3, 0x04f043, 0x25923b, 0x38b233, 0x11500d, 0x1d300b, 0x119047, 0x223049, 0x125065, 0x13d097, 0x04f00d, 0x3290b5, 0x26914b, 0x599005, 0x03b00d, 0x08900d, 0x035029, 0x1cd061, 0x607355, 0x3fd32b, 0x35b2bd, 0x0d3071, 0x28d185, 0x25700d, 0x0c5065, 0x37702f, 0x28722d, 0x1af095, 0x0c501d, 0x119097, 0x2871cf, 0x1f3003, 0x2ab1a3, 0x2590ad, 0x1a5005, 0x1b1025, 0x1b1095, 0x13310f, 0x281239, 0x0b303b, 0x059047, 0x20b0a7, 0x1190e3, 0x0ad053, 0x301083, 0x3d1049, 0x05900d, 0x1eb005, 0x2950fb, 0x17b0e9, 0x07f065, 0x15d02b, 0x1a500d, 0x10702b, 0x089053, 0x287097, 0x0c1017, 0x1cf03b, 0x1610c5, 0x25f067, 0x1e70c7, 0x09d06d, 0x061059, 0x18d151, 0x2ab25f, 0x3c72d7, 0x2930b3, 0x0ad061, 0x071029, 0x4e1407, 0x10f011, 0x617599, 0x1df0fb, 0x00d005, 0x0b508b, 0x2b3283, 0x1af0ad, 0x191151, 0x15b065, 0x1d316f, 0x16f0df, 0x4e12dd, 0x053035, 0x223053, 0x1e71b1, 0x12500b, 0x23918d, 0x0df0c5, 0x2dd101, 0x3c7223, 0x25915d, 0x11b0e3, 0x13709d, 0x28d223, 0x301059, 0x08b06b, 0x10f065, 0x31d0f1, 0x061005, 0x2ab01d, 0x22d0bf, 0x13702b, 0x469223, 0x23b0ad, 0x16701d, 0x24b22d, 0x25f137, 0x1b715b, 0x2ab1cd, 0x0b503b, 0x151035, 0x26915b, 0x161061, 0x14b0c1, 0x1a500d, 0x1670fb, 0x3f5347, 0x16f065, 0x0c5065, 0x18d029, 0x0df00d, 0x407061, 0x0d30b5, 0x0e50c5, 0x1e70d3, 0x2510fb, 0x1e7119, 0x251065, 0x4191c9, 0x0d303d, 0x0a7005, 0x0e90e5, 0x04900b, 0x059049, 0x44f005, 0x01d00d, 0x059005, 0x2090e3, 0x1c10b5, 0x07f06d, 0x1df1cf, 0x5652a1, 0x1b11a5, 0x1fd119, 0x2b300b, 0x35b2f9, 0x175161, 0x283017, 0x02b00d, 0x139003, 0x15d08b, 0x283115, 0x15101d, 0x0e307f, 0x04903d, 0x2ef22d, 0x18500d, 0x1df00d, 0x2d7005, 0x0b306b, 0x1c906d, 0x17f14b, 0x0c7089, 0x049025, 0x2390b3, 0x4252dd, 0x11b0ef, 0x1b7083, 0x1390c1, 0x493053, 0x0f10ad, 0x25700d, 0x09502f, 0x2dd239, 0x1610b3, 0x1af15d, 0x32913d, 0x0bf06b, 0x0fb00d, 0x1f717b, 0x1df133, 0x2dd133, 0x139115, 0x20b15d, 0x42d083, 0x241089, 0x053017, 0x0d302f, 0x0bf061, 0x0ad011, 0x0e301f, 0x12510d, 0x0fb043, 0x11507f, 0x4c11c1, 0x1e70bf, 0x02901d, 0x0c70ad, 0x065047, 0x3a100d, 0x16715b, 0x09704f, 0x2f517f, 0x139047, 0x13d119, 0x1e70a7, 0x1370c7, 0x38b0c7, 0x5571b1, 0x10f049, 0x20903d, 0x17f0d3, 0x13711b, 0x0e9011, 0x0a7083, 0x1150e9, 0x15b025, 0x1a50e9, 0x2b323b, 0x01d00d, 0x1df1d3, 0x151047, 0x41b283, 0x35f185, 0x0c106b, 0x0b3071, 0x3550bf, 0x239071, 0x329283, 0x0e501d, 0x2f92e3, 0x35b2a5, 0x3fb15d, 0x0e306b, 0x1b1025, 0x20b005, 0x0a7017, 0x2f5167, 0x11b0e3, 0x16f0f1, 0x15b0f1, 0x107043, 0x1b10e5, 0x16f0bf, 0x1f706b, 0x1a5089, 0x1070ef, 0x0e502b, 0x1f711b, 0x16f0a3, 0x02500b, 0x0a3071, 0x1cd083, 0x029007, 0x06102b, 0x0b5061, 0x17b02b, 0x14b02f, 0x5cb0ef, 0x01300d, 0x13d01f, 0x14b107, 0x0a300d, 0x10f0e9, 0x0d30b5, 0x1150e9, 0x1390c5, 0x3b90e9, 0x0b3071, 0x5111fd, 0x1a3119, 0x2bd1f7, 0x1910e5, 0x0c107f, 0x14b029, 0x0e902b, 0x1af061, 0x43f251, 0x295137, 0x75707f, 0x23303d, 0x16f03b, 0x23b025, 0x1a5029, 0x1bb199, 0x33d1cd, 0x06d043, 0x49d1d3, 0x0c7017, 0x16113d, 0x10f07f, 0x1cd1a5, 0x095047, 0x17f139, 0x16714b, 0x3fd18d, 0x02501f, 0x25f0b3, 0x335101, 0x0fb02b, 0x2f5125, 0x1f7059, 0x0c70ad, 0x28102b, 0x2bd097, 0x313277, 0x0a7061, 0x061025, 0x095035, 0x0fb0a3, 0x139095, 0x11b08b, 0x34728d, 0x1b1161, 0x167137, 0x059025, 0x19916f, 0x28d1cd, 0x223049, 0x22d21d, 0x20b00b, 0x03b011, 0x0df095, 0x15b119, 0x08902f, 0x19100d, 0x059005, 0x4193b3, 0x09d049, 0x3132f9, 0x2ef277, 0x2a51eb, 0x2a10a3, 0x347025, 0x29526b, 0x1e7011, 0x31d17b, 0x1070ef, 0x03d003, 0x12500d, 0x5293b9, 0x0b50b3, 0x029025, 0x0ad061, 0x425293, 0x09d00d, 0x13706d, 0x09503b, 0x14b06d, 0x10f04f, 0x33b1fd, 0x059005, 0x18501f, 0x10f06b, 0x095005, 0x0e50c5, 0x0e50c1, 0x1a506d, 0x1330a7, 0x0c5043, 0x1a50a7, 0x18d17b, 0x35b1cd, 0x1c9017, 0x04702b, 0x1c91b7, 0x1330bf, 0x38f251, 0x0df0d3, 0x1fd0b5, 0x047035, 0x14b06d, 0x0e9047, 0x17b0e5, 0x13701d, 0x20b0fb, 0x139061, 0x06500b, 0x1f300d, 0x1f717f, 0x305161, 0x139067, 0x059013, 0x32b15d, 0x1910c5, 0x38f1b7, 0x3d7047, 0x427281, 0x3731b7, 0x049025, 0x067005, 0x1330fb, 0x0e909d, 0x1cd101, 0x2c5097, 0x24b01f, 0x06d005, 0x2691cf, 0x15b06d, 0x119017, 0x0ef03d, 0x31d2ef, 0x1f30c7, 0x2591b7, 0x223167, 0x097003, 0x24b0b3, 0x1b1185, 0x089017, 0x22308b, 0x397239, 0x2ef065, 0x03d00d, 0x20b02f, 0x185133, 0x2e3233, 0x33d1f7, 0x09d02b, 0x107089, 0x27701d, 0x08b067, 0x1010ef, 0x06b049, 0x20b0e5, 0x0e30a7, 0x0b5061, 0x37324b, 0x13d133, 0x47f02b, 0x0b3049, 0x2930bf, 0x4273cb, 0x0f1097, 0x09d005, 0x0ad071, 0x25910d, 0x1c102b, 0x2a115d, 0x10f0fb, 0x0fb0a7, 0x11500b, 0x101029, 0x223083, 0x2a108b, 0x36d005, 0x13302b, 0x095071, 0x293005, 0x0bf071, 0x10d0c7, 0x1a310f, 0x1a511b, 0x28d223, 0x4eb047, 0x21d02f, 0x24b035, 0x31d2bd, 0x17b175, 0x0e3043, 0x35b2ab, 0x03502b, 0x089005, 0x45d08b, 0x0a7035, 0x11b0fb, 0x355337, 0x16f0e3, 0x0c70ad, 0x17f03d, 0x0df03b, 0x065029, 0x269137, 0x1b1097, 0x15d0e9, 0x013005, 0x21d115, 0x1b108b, 0x4b1265, 0x185061, 0x1cf175, 0x095005, 0x17b00d, 0x23b049, 0x2f52ab, 0x1cd1a3, 0x0e9035, 0x1c908b, 0x21d065, 0x1f3071, 0x2650e5, 0x20b04f, 0x20b1b7, 0x1b113d, 0x0df0c5, 0x2a5095, 0x1c917f, 0x1b7151, 0x029013, 0x043035, 0x11908b, 0x2950ad, 0x0ef06b, 0x11901d, 0x38f241, 0x1d30b3, 0x049029, 0x283139, 0x1cf0c1, 0x09706d, 0x1390ef, 0x10704f, 0x02b013, 0x24b053, 0x0c101f, 0x26501d, 0x22300b, 0x191083, 0x09d071, 0x16f043, 0x223013, 0x119097, 0x17f01d, 0x3131cd, 0x259119, 0x137053, 0x089011, 0x277029, 0x05904f, 0x1e70ad, 0x139137, 0x0ad049, 0x28d1b7, 0x25f02f, 0x409167, 0x125005, 0x0c7029, 0x1a3035, 0x13d09d, 0x60d2c5, 0x329233, 0x08b005, 0x1cf061, 0x0b503b, 0x233095, 0x35b2bd, 0x0e3043, 0x1990c5, 0x15d0e5, 0x0c7035, 0x0ad06d, 0x1150bf, 0x1cd01d, 0x28701d, 0x3b90c7, 0x053005, 0x0e3053, 0x2cf005, 0x115097, 0x1f70b3, 0x223097, 0x38b2a1, 0x2e728d, 0x16711b, 0x2bd047, 0x24b17f, 0x10700d, 0x3fb16f, 0x4cd3fd, 0x14b083, 0x1e710d, 0x10f06d, 0x0c7097, 0x1e70b5, 0x2a111b, 0x059053, 0x1fd1e7, 0x059053, 0x0ef0c1, 0x2a5139, 0x10d09d, 0x1c9067, 0x08b04f, 0x01700d, 0x08900b, 0x03d035, 0x18d0ef, 0x0b5089, 0x1df1d3, 0x1150d3, 0x089053, 0x15b017, 0x5a70ad, 0x0f107f, 0x0e307f, 0x1e70c7, 0x1250b5, 0x2951b1, 0x15d025, 0x1a5089, 0x3292e7, 0x10f047, 0x13d053, 0x16f137, 0x33d269, 0x1f31af, 0x0e303b, 0x08307f, 0x35b32b, 0x11b03d, 0x3051df, 0x38f1eb, 0x0c100d, 0x09d06b, 0x515449, 0x2a1139, 0x0e3005, 0x49d00d, 0x28d0c7, 0x161097, 0x16f067, 0x0c7029, 0x0e3089, 0x133025, 0x1b7053, 0x0e500d, 0x1b700d, 0x1a50c7, 0x17f035, 0x2871d3, 0x15d097, 0x06d017, 0x257185, 0x09d089, 0x371293, 0x0f106d, 0x1fd0df, 0x09706d, 0x1fd071, 0x25f065, 0x32b03d, 0x4bd15b, 0x19107f, 0x06b005, 0x0bf04f, 0x05301f, 0x0c701f, 0x1af00d, 0x1bb137, 0x23b03d, 0x42d043, 0x24b097, 0x11b053, 0x59f47f, 0x02b029, 0x13d083, 0x37306b, 0x0ad09d, 0x01300d, 0x593053, 0x1750ad, 0x0a3053, 0x209089, 0x0f10b3, 0x10f0bf, 0x3590f1, 0x0e504f, 0x239185, 0x33b1cd, 0x1cf059, 0x17506b, 0x0e9061, 0x06702b, 0x08300d, 0x15d06d, 0x3fd059, 0x0fb00b, 0x209011, 0x2b3185, 0x2231c9, 0x13307f, 0x10103b, 0x15103d, 0x04f047, 0x40713d, 0x1af0ad, 0x1d3125, 0x1a50c7, 0x1c107f, 0x1fd14b, 0x04f049, 0x0b5061, 0x0c5043, 0x233089, 0x0c7067, 0x24b0c5, 0x23b007, 0x16f125, 0x185161, 0x5ad025, 0x27725f, 0x269049, 0x2c5043, 0x0d308b, 0x03500b, 0x22d06d, 0x3df013, 0x251199, 0x2d71a5, 0x07103b, 0x35f095, 0x0e501d, 0x1c10c5, 0x0df059, 0x305137, 0x0bf07f, 0x08900d, 0x0a3089, 0x1fd0b5, 0x17f10f, 0x2b321d, 0x1d30e9, 0x23303b, 0x15b09d, 0x3552a5, 0x33b0e3, 0x12511b, 0x1c9089, 0x3f1059, 0x09d02f, 0x3131a5, 0x0e5047, 0x11501f, 0x20b1df, 0x5ab2c5, 0x0df005, 0x4272bd, 0x36d2a5, 0x07f017, 0x1a501f, 0x0b5013, 0x101047, 0x2bd043, 0x0ad00b, 0x1af0b3, 0x01f00d, 0x025011, 0x3e53a9, 0x115011, 0x101025, 0x1a3025, 0x329065, 0x20b1a3, 0x23321d, 0x17f0ad, 0x03502b, 0x0b300d, 0x119003, 0x0a3083, 0x5ad373, 0x31d01f, 0x2951af, 0x19906d, 0x107005, 0x277209, 0x1a513d, 0x35b259, 0x3b31a5, 0x0bf013, 0x2c52a5, 0x14b0b5, 0x11508b, 0x083047, 0x00d00b, 0x1510fb, 0x11b035, 0x1cf199, 0x1f3125, 0x0c50a7, 0x233061, 0x1af095, 0x20b1c9, 0x10d09d, 0x03b00d, 0x3d7281, 0x32921d, 0x08303b, 0x0df007, 0x0c706d, 0x083007, 0x053005, 0x1cf119, 0x18d017, 0x4fd2b3, 0x3c700d, 0x2c5071, 0x1c9017, 0x239043, 0x1070c7, 0x22d191, 0x3a9005, 0x10f0fb, 0x1d30c5, 0x2511cd, 0x2b31a5, 0x283059, 0x199065, 0x10f097, 0x0df065, 0x0ad09d, 0x26521d, 0x0f10c5, 0x3b9071, 0x2a101f, 0x2ef00d, 0x21d17b, 0x0bf07f, 0x02b00b, 0x3f110d, 0x2e716f, 0x209005, 0x2ab06b, 0x40f409, 0x097013, 0x3f510d, 0x32b2f9, 0x12501f, 0x27713d, 0x0c7005, 0x1b710f, 0x1e7071, 0x23300b, 0x1af017, 0x059053, 0x11906b, 0x11b0ef, 0x16f059, 0x209137, 0x293097, 0x133125, 0x199035, 0x33d2bd, 0x1b715d, 0x24101f, 0x0f1035, 0x08900d, 0x14b0e3, 0x043005, 0x1750a7, 0x2bd2a1, 0x15d0a7, 0x06d00d, 0x08302f, 0x33d04f, 0x2091eb, 0x1df1af, 0x30500d, 0x19109d, 0x1e700d, 0x4a303b, 0x2cf067, 0x397059, 0x32921d, 0x1d3017, 0x1910a7, 0x053049, 0x065035, 0x167097, 0x0ad071, 0x3df35f, 0x241137, 0x1c91a5, 0x33508b, 0x20b07f, 0x2a106d, 0x09d053, 0x0ef083, 0x047035, 0x167089, 0x2c50a7, 0x3471c9, 0x2bd2ab, 0x10d095, 0x49d28d, 0x12501d, 0x11508b, 0x2691e7, 0x0ef09d, 0x28300d, 0x36d337, 0x4a3035, 0x15d139, 0x449025, 0x23908b, 0x18d0c5, 0x1bb0ad, 0x283097, 0x6550d3, 0x4633fd, 0x1cd013, 0x067035, 0x11506b, 0x09506d, 0x287115, 0x17f065, 0x259025, 0x40f1a5, 0x06d00d, 0x1d3049, 0x3e52ab, 0x16f161, 0x1d3185, 0x175133, 0x38b21d, 0x2691cf, 0x45d161, 0x1fd03b, 0x2f500d, 0x2bd0a7, 0x1d3053, 0x1c1013, 0x2e72bd, 0x3cb239, 0x1fd00d, 0x0a308b, 0x1bb11b, 0x59f0ad, 0x071017, 0x13d013, 0x0e300d, 0x0ad005, 0x1af049, 0x1fd14b, 0x09d049, 0x199061, 0x047017, 0x0a3071, 0x33d07f, 0x18d0e3, 0x06d03d, 0x44918d, 0x1af035, 0x37717f, 0x1f31b1, 0x25900d, 0x0bf00d, 0x1010c5, 0x115013, 0x329107, 0x0b3035, 0x0a302b, 0x28d0a3, 0x20918d, 0x35b2a1, 0x1a503d, 0x14b0e9, 0x09700d, 0x175025, 0x649013, 0x56522d, 0x241209, 0x06100b, 0x2d71c9, 0x17f0b3, 0x1750bf, 0x0ad013, 0x035013, 0x0c704f, 0x3a915d, 0x17f151, 0x503445, 0x24b101, 0x1df17f, 0x2091c1, 0x1610d3, 0x28116f, 0x10f00d, 0x14b035, 0x2ab065, 0x1330e5, 0x0ad0a3, 0x0b3059, 0x1eb04f, 0x119107, 0x1c902b, 0x1df13d, 0x09d06b, 0x18d067, 0x4b13df, 0x23b017, 0x18508b, 0x0ef00d, 0x4d535f, 0x2090c5, 0x185083, 0x2e706b, 0x0f1095, 0x29523b, 0x1150df, 0x2870e3, 0x3e5301, 0x1eb11b, 0x2ab0a3, 0x21d0ad, 0x1d30e5, 0x14b115, 0x1d31b7, 0x18d00d, 0x0a7029, 0x2cf269, 0x24b06b, 0x65510d, 0x30506d, 0x0ad011, 0x29503d, 0x04701d, 0x06d029, 0x0c50b5, 0x25f1bb, 0x42d35f, 0x1fd089, 0x2cf2a1, 0x06b029, 0x2f515d, 0x16f13d, 0x22300d, 0x15d0e9, 0x3d11f3, 0x21d0b5, 0x265223, 0x07100d, 0x0ef0a7, 0x175119, 0x06102b, 0x233223, 0x257071, 0x0e503b, 0x0c102b, 0x33b2bd, 0x17f151, 0x16700b, 0x175007, 0x2c516f, 0x1af059, 0x1b7151, 0x1e710d, 0x2b313d, 0x15d101, 0x101005, 0x239029, 0x089043, 0x27702b, 0x241095, 0x199061, 0x03b025, 0x23920b, 0x2090f1, 0x1010a7, 0x26b139, 0x773025, 0x13d137, 0x329251, 0x0fb065, 0x11900b, 0x20b1bb, 0x1fd06d, 0x1e715b, 0x3a12c5, 0x0d3005, 0x1eb007, 0x22d00d, 0x3d101f, 0x19910f, 0x25f1fd, 0x04f01f, 0x2c5013, 0x02f025, 0x0e500b, 0x3ad00d, 0x36d035, 0x4c11e7, 0x05304f, 0x0df097, 0x10d029, 0x01d005, 0x0c706d, 0x0c109d, 0x2cf257, 0x0fb083, 0x1d31c9, 0x1b7003, 0x26b241, 0x013005, 0x2390e9, 0x053025, 0x04f01d, 0x26b233, 0x329185, 0x16f133, 0x0c1089, 0x2410c1, 0x3711cd, 0x175101, 0x1bb09d, 0x1a3107, 0x0ef09d, 0x09d03d, 0x0a7047, 0x0e30df, 0x4cd2cf, 0x3350bf, 0x283025, 0x51b503, 0x10d0d3, 0x21d04f, 0x13903b, 0x0e508b, 0x06b01f, 0x16109d, 0x1cd0d3, 0x17b10d, 0x0a3025, 0x25110f, 0x1df14b, 0x1e71c9, 0x25100d, 0x125005, 0x2f907f, 0x18501d, 0x10d049, 0x4b1397, 0x09d03b, 0x3551bb, 0x19100d, 0x3d100d, 0x1b70f1, 0x35b287, 0x3d703d, 0x3050c7, 0x22d1f3, 0x4933b3, 0x2e72a1, 0x2bd293, 0x3d133b, 0x1610df, 0x1b1065, 0x1510c7, 0x2090c5, 0x19903d, 0x151013, 0x0ef02f, 0x1b1137, 0x35f125, 0x16711b, 0x04f011, 0x25f0ef, 0x1cd0e9, 0x0d306b, 0x257161, 0x1070d3, 0x42d059, 0x281025, 0x2b3017, 0x4c7175, 0x1f3167, 0x1c1137, 0x19915d, 0x0d306b, 0x0a300d, 0x13d11b, 0x0c7025, 0x03b017, 0x17b02b, 0x17f071, 0x01f017, 0x17f03d, 0x293223, 0x16f125, 0x097029, 0x35b0bf, 0x047005, 0x33b03b, 0x09501d, 0x2bd28d, 0x17f137, 0x191013, 0x1eb06d, 0x13d125, 0x061025, 0x5573df, 0x1af03b, 0x2411cf, 0x1bb17b, 0x19104f, 0x38b0ad, 0x1bb0e9, 0x1a3185, 0x32b08b, 0x2330a7, 0x04701f, 0x04f00b, 0x33b2f9, 0x0fb0b3, 0x0ef0d3, 0x097061, 0x1c102f, 0x04301f, 0x10d097, 0x28123b, 0x18515b, 0x1df01f, 0x329305, 0x0b3097, 0x0c7089, 0x0e309d, 0x1b1067, 0x16f0b3, 0x1eb0ef, 0x08b049, 0x26500b, 0x049007, 0x281097, 0x1bb191, 0x061011, 0x17b07f, 0x0e90c7, 0x005003, 0x3291df, 0x30514b, 0x38b035, 0x1a5161, 0x26b1eb, 0x137083, 0x12506b, 0x4c7061, 0x02500d, 0x337095, 0x2bd1df, 0x11b07f, 0x1f307f, 0x00d005, 0x10f06d, 0x1510f1, 0x0b309d, 0x06d029, 0x347119, 0x3051cd, 0x2a1067, 0x3772ab, 0x043013, 0x09d01f, 0x161139, 0x2a5293, 0x061047, 0x1cf03d, 0x0ef03d, 0x11b00d, 0x11b089, 0x097053, 0x06500b, 0x133059, 0x0ad011, 0x46941b, 0x1670c5, 0x07f00b, 0x083043, 0x2f52bd, 0x0ad097, 0x13d00d, 0x33b06b, 0x4cd35f, 0x1f7071, 0x2f9199, 0x185125, 0x577209, 0x15b133, 0x02b00d, 0x0ef0c5, 0x21d1af, 0x1df101, 0x359337, 0x199191, 0x01f013, 0x13306b, 0x1cd101, 0x11508b, 0x11900d, 0x0e3059, 0x083035, 0x493425, 0x25917f, 0x23903d, 0x1610c7, 0x0f1011, 0x00d007, 0x0ad04f, 0x0e30b3, 0x0e90c5, 0x0c503b, 0x17b0c1, 0x10f011, 0x17b139, 0x13d03d, 0x223119, 0x265097, 0x097089, 0x1df199, 0x06102b, 0x11b025, 0x22d053, 0x425281, 0x3c7049, 0x0c7011, 0x277089, 0x0a709d, 0x0d3003, 0x265151, 0x35f161, 0x28306d, 0x25700d, 0x011005, 0x23306b, 0x1af0d3, 0x1a50b3, 0x101025, 0x0b5043, 0x0e300b, 0x17f133, 0x18d005, 0x1fd067, 0x1250d3, 0x295007, 0x1bb095, 0x24b23b, 0x1f7083, 0x26b1c1, 0x36d20b, 0x29503d, 0x1750a3, 0x053025, 0x29315d, 0x02b00d, 0x23911b, 0x16f0df, 0x0e907f, 0x0e9097, 0x19101f, 0x5174cf, 0x095035, 0x1b10c5, 0x58f0c1, 0x20b0e5, 0x1250b5, 0x133053, 0x23310f, 0x335305, 0x2bd161, 0x13d003, 0x1390a7, 0x4cd02f, 0x259013, 0x191119, 0x0bf00b, 0x52707f, 0x17b0b5, 0x10d03d, 0x1f70ad, 0x007005, 0x1070e5, 0x1150f1, 0x1510b3, 0x1b7061, 0x3a9283, 0x22d0e3, 0x1e7125, 0x3a92a5, 0x1eb14b, 0x14b043, 0x18d10f, 0x21d1af, 0x10d011, 0x11507f, 0x03500b, 0x2231bb, 0x2f5167, 0x0c702b, 0x2771cf, 0x22d02b, 0x0ef083, 0x16f115, 0x17b083, 0x0ef0a7, 0x15100b, 0x08902b, 0x1c10c1, 0x20b0a3, 0x3b307f, 0x10702f, 0x15d06d, 0x0f1059, 0x1af00b, 0x16700d, 0x1b7043, 0x5fb0bf, 0x1cf043, 0x06d01d, 0x13d0ef, 0x2a5049, 0x2cf14b, 0x1c1043, 0x10f01d, 0x1c91a5, 0x13901d, 0x125067, 0x13908b, 0x07100d, 0x233185, 0x1cd013, 0x3fd043, 0x15b101, 0x0a700d, 0x32b281, 0x1af0e5, 0x281107, 0x16103b, 0x2390e9, 0x2e7161, 0x191047, 0x083011, 0x061025, 0x10d0f1, 0x313125, 0x4eb239, 0x2a503d, 0x0e50b5, 0x161047, 0x11b03d, 0x0e3035, 0x167095, 0x1330c5, 0x14b005, 0x40f397, 0x13d03b, 0x1c1115, 0x41931d, 0x10f059, 0x00b005, 0x1a5089, 0x035003, 0x0c70a3, 0x107083, 0x13d029, 0x04303b, 0x185161, 0x0df00d, 0x1c9133, 0x25f1c1, 0x1c9139, 0x16f025, 0x251061, 0x38b191, 0x4430a7, 0x5ad4e1, 0x133035, 0x1a3065, 0x0d301d, 0x0d3017, 0x0a301f, 0x26b14b, 0x10f0b3, 0x4813fd, 0x049035, 0x0a3097, 0x0b501f, 0x1eb119, 0x11b10f, 0x21d15d, 0x1190c5, 0x17b09d, 0x6a108b, 0x17508b, 0x08b083, 0x0f106d, 0x05901d, 0x1250bf, 0x1cf0c5, 0x223029, 0x08b02f, 0x10f10d, 0x0b500d, 0x1af06d, 0x1010b5, 0x0e3035, 0x04300d, 0x061005, 0x06b00d, 0x0ef03d, 0x0df089, 0x06101f, 0x0c5047, 0x0d306b, 0x0f10e9, 0x1f3047, 0x3df18d, 0x08904f, 0x2770b5, 0x1850f1, 0x175059, 0x2bd06b, 0x1750d3, 0x22d00d, 0x1f7003, 0x06700d, 0x13900d, 0x185107, 0x3551d3, 0x233047, 0x049005, 0x15d0a7, 0x305035, 0x17b119, 0x0a3013, 0x2bd241, 0x03b005, 0x2e72a1, 0x35b11b, 0x11b115, 0x2c506d, 0x0f100b, 0x1fd061, 0x1df17b, 0x18d0c5, 0x2d7061, 0x06102b, 0x0df0ad, 0x0c70a3, 0x107089, 0x257191, 0x27700d, 0x2dd161, 0x08b089, 0x1cd07f, 0x16702b, 0x3011b7, 0x337305, 0x1c91a3, 0x2ef20b, 0x13d04f, 0x23321d, 0x05301f, 0x28308b, 0x277065, 0x31d251, 0x175011, 0x151071, 0x2a11b1, 0x0d303b, 0x32904f, 0x23b0c5, 0x11b0e3, 0x06500b, 0x257089, 0x1fd14b, 0x259061, 0x1f310f, 0x595529, 0x4ff2f5, 0x03d035, 0x0ad00d, 0x10704f, 0x01100d, 0x151003, 0x265167, 0x0df013, 0x28324b, 0x095059, 0x28306b, 0x301097, 0x115101, 0x36d259, 0x15110d, 0x199071, 0x2390ef, 0x2e3175, 0x2ef277, 0x21d1cf, 0x0b5043, 0x06103b, 0x581061, 0x06103d, 0x38f251, 0x083059, 0x28113d, 0x0d3059, 0x185047, 0x3050c7, 0x16102f, 0x29515d, 0x1f30f1, 0x1df025, 0x2f9259, 0x13d11b, 0x28317f, 0x1a30ef, 0x17f061, 0x2f50a7, 0x15d0bf, 0x305151, 0x13303d, 0x0e9029, 0x3b322d, 0x00d005, 0x06d025, 0x17f167, 0x51b38f, 0x175005, 0x049011, 0x1d31cd, 0x065053, 0x0c70c1, 0x1d315b, 0x13d0c7, 0x35917b, 0x059053, 0x13910f, 0x0f10c7, 0x2dd15d, 0x1df097, 0x167061, 0x0fb059, 0x101049, 0x0e303d, 0x16f049, 0x24b1a5, 0x0fb0d3, 0x35b277, 0x06b047, 0x3c703d, 0x1e7199, 0x097047, 0x04903d, 0x33d1a5, 0x1c1185, 0x0b501f, 0x35b0e3, 0x1fd017, 0x03501d, 0x043017, 0x3d735b, 0x0ef00d, 0x08300d, 0x1b7059, 0x36d259, 0x51743f, 0x481469, 0x1d3107, 0x44f3df, 0x2cf22d, 0x097049, 0x1fd133, 0x2e30f1, 0x2dd16f, 0x0df00d, 0x44304f, 0x0ef061, 0x161025, 0x0fb013, 0x0fb0c1, 0x1f7167, 0x09700b, 0x13d11b, 0x049025, 0x199013, 0x25706b, 0x2330ad, 0x2c51a5, 0x5571eb, 0x115061, 0x00d007, 0x337251, 0x359065, 0x287137, 0x0d302f, 0x47f449, 0x0a300d, 0x1b718d, 0x08904f, 0x3e511b, 0x15b137, 0x0c7095, 0x347199, 0x0ef089, 0x0b503b, 0x161013, 0x3b9115, 0x2330e9, 0x06d02b, 0x15d061, 0x10f083, 0x42d377, 0x257223, 0x2f50e3, 0x2771a3, 0x28d03b, 0x1a508b, 0x0f10e9, 0x1eb097, 0x03d03b, 0x313295, 0x51103b, 0x44f0b3, 0x295137, 0x0ef07f, 0x06b01f, 0x355125, 0x0a3089, 0x1010bf, 0x1f30e5, 0x0b5005, 0x3351c1, 0x17509d, 0x09d071, 0x1a3007, 0x24115d, 0x07106d, 0x09d089, 0x08b02b, 0x2f901f, 0x265125, 0x1eb0e3, 0x18d15d, 0x10f00b, 0x1a517b, 0x04f02f, 0x1910e9, 0x265223, 0x08b01d, 0x3471cd, 0x07f035, 0x199005, 0x28d283, 0x10f01d, 0x11b119, 0x1f302f, 0x10f067, 0x0df017, 0x0b502b, 0x0b5029, 0x1190df, 0x11b01d, 0x161007, 0x0a309d, 0x0f10bf, 0x25121d, 0x167071, 0x40903d, 0x0a302f, 0x281233, 0x1d307f, 0x2b31a5, 0x241025, 0x359005, 0x0d307f, 0x08903d, 0x1eb0fb, 0x16703d, 0x133119, 0x1c1047, 0x34709d, 0x11b089, 0x083053, 0x0df049, 0x06501f, 0x2ef0ef, 0x1510e5, 0x04703b, 0x2e7119, 0x065043, 0x15b0b5, 0x17f0c7, 0x2cf241, 0x03d005, 0x2e30ef, 0x0e30c1, 0x199115, 0x17b053, 0x13d0e9, 0x17b14b, 0x4492b3, 0x065013, 0x18d02b, 0x0c50a3, 0x059053, 0x23b00d, 0x3051cf, 0x0e300d, 0x239151, 0x1eb10d, 0x26b161, 0x1330b5, 0x617265, 0x0e90d3, 0x18d00b, 0x167071, 0x377089, 0x2930df, 0x04902f, 0x3fb025, 0x355277, 0x1b7035, 0x63d371, 0x38f1f7, 0x17b07f, 0x12506b, 0x065007, 0x175005, 0x38b2f9, 0x1cf00d, 0x4072f9, 0x0fb0e5, 0x21d0d3, 0x24b1e7, 0x20b02b, 0x28107f, 0x1750e9, 0x1f717f, 0x1c10c7, 0x3f50bf, 0x23b03b, 0x33d17b, 0x21d1f7, 0x277097, 0x21d1b7, 0x2390df, 0x083029, 0x10700d, 0x17f03d, 0x10d0c1, 0x2cf043, 0x09701f, 0x053029, 0x1010e3, 0x5512dd, 0x18d013, 0x29509d, 0x13d083, 0x25f0c7, 0x3cb3b3, 0x0a703d, 0x17b13d, 0x347257, 0x1fd0c5, 0x0ad025, 0x25f089, 0x6ad425, 0x35b0c5, 0x12500b, 0x07100b, 0x2ef259, 0x32b28d, 0x04903d, 0x1a50e9, 0x1750a7, 0x44f335, 0x38b33d, 0x02b00d, 0x06500d, 0x3fb065, 0x30504f, 0x1330d3, 0x24b1af, 0x03d03b, 0x06d029, 0x2dd16f, 0x00b005, 0x1cd06b, 0x08b043, 0x287233, 0x25915d, 0x19106b, 0x5150ad, 0x20b095, 0x1d317f, 0x17f11b, 0x1bb0e5, 0x07100b, 0x09d03b, 0x133029, 0x1cd0b5, 0x1e70e9, 0x10709d, 0x26b0f1, 0x1cd115, 0x035005, 0x03500d, 0x16708b, 0x0a7061, 0x0b3053, 0x0e5071, 0x1eb14b, 0x07101f, 0x1f3003, 0x17b047, 0x28723b, 0x0f109d, 0x17b03b, 0x3b90f1, 0x0a3029, 0x0e302b, 0x0ad09d, 0x1d31b1, 0x1cf08b, 0x083049, 0x0c700b, 0x4811eb, 0x3d10e3, 0x0ad04f, 0x0c506d, 0x0e50bf, 0x38f061, 0x18517b, 0x137097, 0x035007, 0x0bf025, 0x1f71a5, 0x08903b, 0x0ef0c5, 0x329175, 0x16f10d, 0x25f043, 0x277017, 0x23b017, 0x28304f, 0x3372a5, 0x24b035, 0x1a3101, 0x19114b, 0x15d04f, 0x09d01d, 0x313097, 0x517011, 0x32b125, 0x107065, 0x10f08b, 0x295005, 0x2b324b, 0x1cd043, 0x1eb16f, 0x683577, 0x0bf005, 0x095005, 0x1bb025, 0x17b017, 0x26521d, 0x0f1053, 0x22301d, 0x23b011, 0x13d007, 0x3cb02f, 0x1af101, 0x24b191, 0x1bb06d, 0x16107f, 0x137029, 0x281035, 0x28d007, 0x1f31bb, 0x0e500b, 0x3ad01d, 0x1eb0b3, 0x161013, 0x175125, 0x25f241, 0x0c500d, 0x3370a3, 0x11b119, 0x239061, 0x5fb2ef, 0x3b3251, 0x2c5035, 0x10703d, 0x00d005, 0x33723b, 0x1df15d, 0x11901d, 0x241137, 0x095013, 0x281083, 0x1df137, 0x1370b5, 0x31d0b3, 0x10d00d, 0x1e70c5, 0x1c9191, 0x2a1191, 0x1e70fb, 0x23900b, 0x15b035, 0x0e906d, 0x1f714b, 0x0ad04f, 0x4250f1, 0x2f51e7, 0x25f1a5, 0x2e3281, 0x1c913d, 0x20b025, 0x21d017, 0x3ad1bb, 0x5512bd, 0x0c503d, 0x2411cd, 0x1c90bf, 0x7c922d, 0x1c107f, 0x3050b5, 0x2e7043, 0x07f03d, 0x1a51a3, 0x19111b, 0x0ad0a7, 0x2d7185, 0x02901d, 0x0c500b, 0x26900d, 0x18503d, 0x5b3287, 0x5bf359, 0x0c5097, 0x50923b, 0x2b323b, 0x04901f, 0x371233, 0x1c10fb, 0x02501f, 0x0ad08b, 0x3df301, 0x1eb007, 0x2811f3, 0x3ad059, 0x107011, 0x407251, 0x239097, 0x167151, 0x21d0b5, 0x22d1df, 0x167083, 0x08901f, 0x0c7013, 0x18d17b, 0x03b029, 0x1fd0e5, 0x35f0e5, 0x493125, 0x28d277, 0x33d199, 0x1df1bb, 0x06b047, 0x15d0e5, 0x0c504f, 0x2a117f, 0x0d308b, 0x41b1a5, 0x1eb06d, 0x17514b, 0x1250a7, 0x02f025, 0x1c116f, 0x65b4eb, 0x1cf151, 0x1d317b, 0x17b0e5, 0x1f714b, 0x24b1f7, 0x0e30b3, 0x26b185, 0x10700b, 0x283241, 0x17f10d, 0x38f06d, 0x0c502f, 0x29525f, 0x241047, 0x3a90c1, 0x28d0c1, 0x053047, 0x125083, 0x09d047, 0x259167, 0x137049, 0x07f04f, 0x0ef0a3, 0x1d30bf, 0x3131c1, 0x0e30c7, 0x133107, 0x293223, 0x29524b, 0x31d0c7, 0x17b139, 0x1190e5, 0x059025, 0x2950f1, 0x50b0b3, 0x1b1185, 0x139013, 0x09d01d, 0x07100d, 0x17b035, 0x49344f, 0x3b3139, 0x06b011, 0x2dd00d, 0x24b089, 0x1b7095, 0x137047, 0x2830fb, 0x029013, 0x11903d, 0x0d3025, 0x161151, 0x23301f, 0x27725f, 0x1c1151, 0x089053, 0x01100d, 0x2771b1, 0x1850c1, 0x2f91c1, 0x2f51fd, 0x0c5011, 0x10103b, 0x2c5283, 0x265067, 0x0bf03d, 0x2d700b, 0x15d125, 0x43f419, 0x3b3269, 0x1510b5, 0x13700d, 0x17f01d, 0x1cf185, 0x0a7059, 0x277191, 0x04303d, 0x2a1293, 0x1cd0d3, 0x1bb115, 0x125061, 0x23b22d, 0x151137, 0x101083, 0x1f30f1, 0x175053, 0x097025, 0x22d0b3, 0x23b13d, 0x02f011, 0x1a515d, 0x11b115, 0x11906b, 0x0e5005, 0x0e90b3, 0x4cd0fb, 0x2d7089, 0x1f71a3, 0x06b02f, 0x25901d, 0x24b0c7, 0x0e900b, 0x1b1139, 0x1f3107, 0x2ab083, 0x1f31df, 0x20906d, 0x251061, 0x31d137, 0x2590fb, 0x31d1bb, 0x1eb133, 0x199161, 0x1f71eb, 0x1e7007, 0x1eb089, 0x10f005, 0x0bf083, 0x101095, 0x36d335, 0x2e3223, 0x1e70ad, 0x1f303b, 0x2ef1a3, 0x06b01f, 0x2ab1cd, 0x0e9005, 0x4ff455, 0x0f10b3, 0x0b506b, 0x14b013, 0x137029, 0x33b119, 0x1a3025, 0x3ad061, 0x2810e9, 0x02b025, 0x1af125, 0x06b025, 0x0a306d, 0x0e3067, 0x1c11b7, 0x0b5059, 0x06b005, 0x257035, 0x23b059, 0x2090ad, 0x07f02f, 0x5e747f, 0x167035, 0x12506d, 0x2d715b, 0x1c9125, 0x2230b5, 0x09501f, 0x1990c5, 0x2f9049, 0x191175, 0x1c900b, 0x0ef013, 0x2090c1, 0x1b101d, 0x377251, 0x4d5301, 0x0c5047, 0x1a3025, 0x0ef061, 0x2ab23b, 0x15103b, 0x10f097, 0x0d3043, 0x0a702b, 0x5171bb, 0x33d32b, 0x10f0e9, 0x1070b5, 0x22309d, 0x2831b1, 0x03b035, 0x16f089, 0x2831c1, 0x00d005, 0x329005, 0x277083, 0x167005, 0x095007, 0x251199, 0x185101, 0x0c106d, 0x1390b5, 0x1750e3, 0x10f083, 0x1cf03d, 0x1f70df, 0x36d04f, 0x67f185, 0x25f047, 0x1bb065, 0x1d300d, 0x25f101, 0x0ad03d, 0x0b3095, 0x04f005, 0x1c90a3, 0x38f1fd, 0x34710d, 0x067017, 0x15d00d, 0x1330e5, 0x20b133, 0x2b31b7, 0x22d223, 0x2590d3, 0x50b035, 0x23b125, 0x125059, 0x0c703b, 0x0ad00b, 0x175005, 0x36d10d, 0x0ef095, 0x11b10d, 0x13300d, 0x11b043, 0x1df067, 0x13302b, 0x1fd029, 0x1a5013, 0x1cd04f, 0x05904f, 0x0bf061, 0x08b005, 0x0a306b, 0x1f7097, 0x1a317b, 0x2bd13d, 0x1df049, 0x00d005, 0x0ad00d, 0x2b3277, 0x1c100b, 0x3012f5, 0x0ad00d, 0x0a3059, 0x26520b, 0x29503d, 0x02500b, 0x0e501f, 0x2a50b5, 0x18504f, 0x1af08b, 0x199175, 0x4cd427, 0x16106d, 0x32b265, 0x1eb059, 0x133101, 0x09701d, 0x251119, 0x10d01d, 0x15d14b, 0x01300d, 0x2a1287, 0x161025, 0x3fd371, 0x19917f, 0x1af0f1, 0x24b00d, 0x199029, 0x35b007, 0x13d02b, 0x06d03d, 0x20b097, 0x64d01d, 0x241191, 0x1df18d, 0x2ef185, 0x0bf0b5, 0x25f07f, 0x16f0c7, 0x1f702b, 0x3f5139, 0x1cf0c1, 0x13908b, 0x0e500d, 0x0c7005, 0x67f31d, 0x36d2f5, 0x2331df, 0x097035, 0x25713d, 0x0c1083, 0x1330bf, 0x4c72ab, 0x0c100b, 0x251043, 0x2e3259, 0x37102b, 0x38b35f, 0x449277, 0x4491f7, 0x0b3053, 0x45d00b, 0x427359, 0x17515d, 0x26b0a3, 0x2d70e9, 0x1150e5, 0x1750c1, 0x3df09d, 0x17f03d, 0x0ef053, 0x0fb049, 0x209005, 0x2bd049, 0x45d005, 0x11b013, 0x02500d, 0x557529, 0x0c701d, 0x0b3017, 0x15d013, 0x24b061, 0x2a51cd, 0x241199, 0x0a7065, 0x38b33d, 0x0d3005, 0x1f70bf, 0x3fd2dd, 0x0c7071, 0x1670f1, 0x065013, 0x043017, 0x35f047, 0x1510ef, 0x23301d, 0x2590e3, 0x06d005, 0x6a1509, 0x04701f, 0x065035, 0x089067, 0x35f1e7, 0x3fb09d, 0x12509d, 0x2ef251, 0x2590bf, 0x313043, 0x09502b, 0x7b5445, 0x251191, 0x01300d, 0x61f295, 0x2871c9, 0x0c50bf, 0x10f03b, 0x0a3025, 0x21d025, 0x12500b, 0x0b506b, 0x1b7061, 0x065013, 0x2c5097, 0x3ad0fb, 0x3772f9, 0x1f71e7, 0x1e7003, 0x24b1b1, 0x07f029, 0x1af0df, 0x1a5095, 0x16f00d, 0x1cd09d, 0x265013, 0x3c7151, 0x17b101, 0x0ad047, 0x0b301f, 0x16f101, 0x15b061, 0x14b11b, 0x4a3115, 0x065005, 0x02500d, 0x047005, 0x1510b5, 0x0fb0c1, 0x38b2c5, 0x26909d, 0x025003, 0x0bf011, 0x0bf095, 0x0e9071, 0x16f161, 0x283013, 0x26b15b, 0x38f301, 0x15d0e9, 0x3b9035, 0x15b043, 0x4ff36d, 0x12511b, 0x07f029, 0x16702b, 0x257071, 0x25703d, 0x50b427, 0x2e315d, 0x1cd0a7, 0x2091af, 0x02501d, 0x257125, 0x09700d, 0x1b1067, 0x2591cf, 0x23b01d, 0x0c506b, 0x24b065, 0x2ef185, 0x1e7013, 0x049007, 0x239119, 0x2dd059, 0x4cd40f, 0x0f1029, 0x4cd287, 0x31d26b, 0x2f92a5, 0x2ef28d, 0x1670ef, 0x3e5329, 0x23b161, 0x3372dd, 0x17515d, 0x1df1a3, 0x16f047, 0x1250b3, 0x3a11d3, 0x1a306b, 0x02b00d, 0x1cf065, 0x1330b3, 0x1eb17b, 0x29526b, 0x257199, 0x13d005, 0x0bf00b, 0x223151, 0x233097, 0x1eb15b, 0x33d2ef, 0x10d0ef, 0x335095, 0x257095, 0x3e5053, 0x03d02b, 0x0e908b, 0x1d3047, 0x15b053, 0x2231f7, 0x119043, 0x3c7059, 0x5f31fd, 0x23b01d, 0x10f02f, 0x33b06d, 0x097005, 0x07f03b, 0x083035, 0x43f277, 0x10f017, 0x0a7083, 0x09d061, 0x33d035, 0x0c7061, 0x1750b5, 0x377305, 0x107061, 0x2330c7, 0x18510f, 0x26b0e5, 0x137089, 0x17507f, 0x33b049, 0x10f0df, 0x52706d, 0x241025, 0x0a7067, 0x23b119, 0x1c1125, 0x11502f, 0x3771a5, 0x313287, 0x419007, 0x09703d, 0x409397, 0x0d3049, 0x329097, 0x083005, 0x1a306d, 0x2e720b, 0x08b083, 0x15d0e3, 0x0e5071, 0x065059, 0x2f5151, 0x191101, 0x0a7095, 0x3470a3, 0x125107, 0x095011, 0x5db061, 0x1c1119, 0x33700d, 0x167125, 0x15d02b, 0x1c9043, 0x2f50e3, 0x1df0b5, 0x0fb011, 0x33d1c1, 0x29325f, 0x1fd00d, 0x0c50ad, 0x25900d, 0x12500b, 0x11504f, 0x05300d, 0x313241, 0x175003, 0x1f30e9, 0x15b025, 0x1cf007, 0x1fd18d, 0x2cf17b, 0x305043, 0x4073f1, 0x3b3241, 0x1670e3, 0x4ff089, 0x233043, 0x23b035, 0x2ef15b, 0x185101, 0x65b611, 0x2e326b, 0x2770fb, 0x17f005, 0x065025, 0x265137, 0x1150bf, 0x0f100d, 0x1b1061, 0x11b03d, 0x095049, 0x283059, 0x0a301d, 0x03d01f, 0x17f16f, 0x13710f, 0x01700d, 0x2870ad, 0x1a302b, 0x5031cf, 0x1610b3, 0x209089, 0x02501d, 0x059053, 0x11b0e3, 0x3372a1, 0x0c5005, 0x18d185, 0x1e70bf, 0x10103d, 0x0e50ad, 0x47f0bf, 0x15d14b, 0x2f9025, 0x11b0ef, 0x3771bb, 0x23315d, 0x11b0a3, 0x1f3005, 0x223071, 0x04f01d, 0x1fd005, 0x151043, 0x095007, 0x14b083, 0x36d06d, 0x11b0bf, 0x21d01f, 0x03d00b, 0x15b0b3, 0x02b01f, 0x07106b, 0x407397, 0x097035, 0x071049, 0x511269, 0x283161, 0x1df191, 0x3ad125, 0x5510c1, 0x161115, 0x2410fb, 0x2e7101, 0x14b01d, 0x31d209, 0x09d003, 0x0f1053, 0x08907f, 0x239095, 0x029005, 0x3a918d, 0x28d0c1, 0x02b01d, 0x36d071, 0x09503d, ]; //////////////////// Lookup tables for number theoretic functions // table for riemann zeta function. ZETA_LOG_TABLE[i] = ln(ζ(i-2)) #[cfg(feature = "big-table")] pub const ZETA_LOG_TABLE: [f64; 64] = [ 4.977003024707453704422733e-01, 1.840341753914914169065753e-01, 7.910987306733563428906564e-02, 3.626225964922791950018066e-02, 1.719438760265828980422498e-02, 8.314614969275204922616318e-03, 4.069066307412954990041509e-03, 2.006378701528290387640086e-03, 9.940808656690607904293788e-04, 4.940665331469770151992527e-04, 2.460562789788238511994034e-04, 1.227058189115578395490813e-04, 6.124625946826462580263595e-05, 3.058776849645994703411761e-05, 1.528214263611525392016002e-05, 7.637168474654366096660528e-06, 3.817285979154446217526640e-06, 1.908210895918369244355067e-06, 9.539615788513043827126850e-07, 4.769328730553057084173103e-07, 2.384504742984163710492051e-07, 1.192199188586162536606321e-07, 5.960818727469145156012688e-08, 2.980350307052787786014558e-08, 1.490155471733687385350177e-08, 7.450711762078876717827681e-09, 3.725334017849400424712395e-09, 1.862659721778298369227706e-09, 9.313274319859827471326702e-10, 4.656629063949574247211838e-10, 2.328311833405453758759852e-10, 1.164155017202289036848590e-10, 5.820772087733293568249733e-11, 2.910385044454747711695271e-11, 1.455192189093610577568052e-11, 7.275959835031012016668332e-12, 3.637979547372033417761987e-12, 1.818989650305411709490059e-12, 9.094947840259752504178820e-13, 4.547473783041120242576761e-13, 2.273736845824393946183985e-13, 1.136868407680163290842639e-13, 5.684341987627423858168184e-14, 2.842170976889261614354352e-14, 1.421085482803150734740459e-14, 7.105427395210827461615018e-15, 3.552713691337107622981434e-15, 1.776356843579118836645811e-15, 8.881784210930812248514214e-16, 4.440892103143812146018826e-16, 2.220446050798041906634718e-16, 1.110223025141066149019450e-16, 5.551115124845480986572498e-17, 2.775557562136123907111332e-17, 1.387778780972523194213624e-17, 6.938893904544153439927978e-18, 3.469446952165922542917276e-18, 1.734723476047576545776400e-18, 8.673617380119933001297893e-19, 4.336808690020650566764225e-19, 2.168404344997219811593044e-19, 1.084202172494241415200165e-19, 5.421010862456645841915045e-20, 2.710505431223468975644559e-20, ]; // tables for moebius function with small input pub const MOEBIUS_ODD: [u64; 4] = [ 0x4289108a05208102, 0x19988004a8a12422, 0x1a8245028906a062, 0x229428012aa26a00, ]; //////////////////// Prime gaps for prime indexing //////////////////// /* Code to generate wheel offsets: ```python import numpy as np wheel = [2,3,5] wheel_size = np.product(wheel) flags = np.ones(wheel_size, dtype=bool) tester = np.arange(wheel_size) for p in wheel: flags[tester % p == 0] = False flags = np.concatenate([flags, flags]) next_table = np.zeros(wheel_size, dtype=int) prev_table = np.zeros(wheel_size, dtype=int) for i in range(wheel_size): next_table[i] = np.argmax(flags[i:]) prev_table[i] = np.argmax(flags[:wheel_size+i+1][::-1]) next_zeros, = np.where(next_table == 0) next_table[next_zeros] = next_table[(next_zeros+1) % wheel_size]+1 prev_zeros, = np.where(prev_table == 0) prev_table[prev_zeros] = prev_table[(prev_zeros-1) % wheel_size]+1 print(next_table) print(prev_table) ``` */ // offset for moving to the prev/next prime candidate on wheel30 (2*3*5) #[cfg(not(feature = "big-table"))] pub const WHEEL_SIZE: u8 = 30; #[cfg(not(feature = "big-table"))] pub const WHEEL_NEXT: [u8; 30] = [ 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, ]; #[cfg(not(feature = "big-table"))] pub const WHEEL_PREV: [u8; 30] = [ 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, ]; // offset for moving to the prev/next prime candidate on wheel2310 (2*3*5*7*11) #[cfg(feature = "big-table")] pub const WHEEL_SIZE: u16 = 2310; #[cfg(feature = "big-table")] pub const WHEEL_NEXT: [u8; 2310] = [ 1, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2, 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, ]; #[cfg(feature = "big-table")] pub const WHEEL_PREV: [u8; 2310] = [ 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ]; //////////////////// Modulo tables for fast perfect power check //////////////////// /* Code to generate residuals: ```python import math import numpy as np N = 8 # number of modulus to be selected LIM = 1024 # limit of modulus fn = lambda x: x*x # power function # first select N modulus under LIM (assuming factor 2 is already considered) frequency = [(len(np.unique([fn(i)%L for i in range(L)]))/L, L) for L in range(1, LIM, 2)] selections = [] select_freq = 1 for (f, n) in sorted(frequency): for s in selections: if math.gcd(n, s) != 1: break else: selections.append(n) select_freq *= f if len(selections) >= N: break print("Moduli:", selections) print("Possibility", select_freq) # Then generate bit masks for the numbers for s in selections: bits = [0] * (s // 64 + 1) for i in range(s): ii = fn(i) % s bits[ii//64] |= 1 << (ii%64) print("Masks for", s, ":", ['0x%016x' % b for b in bits]) ``` */ #[cfg(not(feature = "big-table"))] pub const QUAD_MODULI: [u8; 4] = [63, 65, 61, 59]; // note that 0 and 64 are both square mod 65 #[cfg(not(feature = "big-table"))] pub const QUAD_RESIDUAL: [u64; 4] = [ 0x0402483012450293, 0x218a019866014613, 0x1713e6940a59f23b, 0x022b62183e7b92bb, ]; #[cfg(not(feature = "big-table"))] pub const CUBIC_MODULI: [u8; 4] = [63, 61, 43, 37]; #[cfg(not(feature = "big-table"))] pub const CUBIC_RESIDUAL: [u64; 4] = [ 0x4080001818000103, 0x1434026619900b0b, 0x0000068908610917, 0x00000010ac804d43, ]; #[cfg(feature = "big-table")] pub const QUAD_MODULI: [u16; 8] = [819, 935, 989, 899, 1007, 1021, 1019, 1013]; #[rustfmt::skip] #[cfg(feature = "big-table")] pub const QUAD_RESIDUAL: [[u64; 16]; 8] = [ [0x0002081002410213, 0xc200001009028001, 0x0000120000014024, 0x008048020208a050, 0x1800048200244029, 0x0420120180020014, 0x2600000080490408, 0x9100041060200800, 0x0904004800120100, 0x2402000400082201, 0x402100920c000040, 0x0820804002004880, 0x0000002403012000, 0, 0, 0], [0x1882001406018213, 0x0288c11002420065, 0x820846400c010180, 0x4841142230000010, 0x8004000e01100101, 0x00c0421801280810, 0x1304202104018060, 0xe400823014001088, 0x04228001100a4000, 0x00c23144008c0401, 0x0100011083204400, 0x100024108e001802, 0x2200c00208452040, 0x00310020080c0204, 0x0000000000140210, 0], [0x0c52821883812253, 0x9220403190824001, 0x1e0026b004455c20, 0xa040d1c209a58032, 0x298a68420480a049, 0x1003026612000074, 0x6b8048c400192281, 0x300102d8021420a0, 0x85211508223e0404, 0x220a810845800181, 0xcc50291070510060, 0x840513520a408200, 0xd0a6422048d38098, 0x00083c2112b00305, 0x990d8401510220b4, 0x0000000001400682], [0xc80a205a121102b3, 0x2201a89060874089, 0x4890e22001211412, 0x9120328e08001414, 0xcd400a825a001c43, 0x6330022830e08151, 0x169c90483ca12044, 0x0416201002620801, 0x4081490e008b8218, 0xc422404328122401, 0x711e881088340820, 0x094632241a034000, 0x020129c80021cb00, 0x204038620200e624, 0, 0], [0xc2429c5013030ad3, 0x0a890459a0062015, 0x18019308c361404c, 0x51002032052042b8, 0x00b2604604098505, 0x3614a6400cc04390, 0x022c03848101900d, 0x0220505212087021, 0x45804800ab0611a6, 0x110a08110156680b, 0x10a72415020038c8, 0xc06114642ac00401, 0x0180003498171808, 0x4c20010128908622, 0x0c58060200714052, 0x0000002500040682], [0x718bb6522e93da3b, 0x6a5e15181aebcef9, 0x5cb903b8072b20b4, 0xebb96e0b5e64f6b7, 0xf54a7312517f386d, 0x4c8fba9e7f589015, 0xe68bc3c5a26998c0, 0x0930ba16c101df98, 0xc67ee020da174324, 0x80c6659168f0f459, 0xea0246bf9e577c4c, 0xed873fa2923394ab, 0xbb5bc99eb41da775, 0x8b4135380770274e, 0xa7dcf5d6062a1e95, 0x1716f25d129b7463], [0x138b3c12ae9bda3b, 0xf65a353afaa7de71, 0x08311be00eab42d6, 0xa069e43b58ced0b3, 0xd589933aedfb2ceb, 0xfdbdfa54563a03dd, 0xe63f0f092c7538d8, 0x3b77e1b60b6ff8b2, 0x8b2e0092f9278112, 0x0e4e351cb6f0f039, 0x4443fa395d5a0424, 0xa28cb2048a3366e5, 0xf32f48ce523d869f, 0x094bd2a8ff82773e, 0x771841aa0a353a59, 0x023a4268ab7c32e3], [0x557a191c03a9ee53, 0xcee6c01b76bed685, 0x62e33aa92c63b5c4, 0x2d830be3875ffeba, 0x59a7c9d2ba4e854f, 0x49f183525a139bb6, 0x1762cc0a2801b21b, 0x73843dd8ff3029f2, 0xba13e5033fc6ef08, 0xe4b6136005140cd1, 0x669b76721692b063, 0x6d3ca85c9752e4f9, 0xd1975ffeb871f430, 0xdcc8eb718d255731, 0xaaa85adf5bb600d9, 0x00129de5700e2617], ]; #[cfg(feature = "big-table")] pub const CUBIC_MODULI: [u16; 8] = [819, 817, 925, 961, 1021, 1009, 997, 991]; #[rustfmt::skip] #[cfg(feature = "big-table")] pub const CUBIC_RESIDUAL: [[u64; 16]; 8] = [ [0x0000000008000103, 0x204000080c000001, 0x4020000200000000, 0x1000000001000000, 0x0008000080000010, 0x06000000c0800000, 0x0600000000000000, 0x0000000010300000, 0x0080800000100001, 0x4020000008000000, 0x2040000000040000, 0x0008000003010000, 0x0004080001000000, 0, 0, 0 ], [0x0000208008000903, 0x2202084041900803, 0x00801c1000821020, 0x4080100003000000, 0x010282202004040c, 0x0800010000c0000c, 0x0040640800004098, 0x0200c0000c000200, 0x0408c08080101105, 0x0400000003000020, 0x01101021040020e0, 0x0003004026080841, 0x0001024000400410, 0, 0, 0 ], [0x80098870ac804943, 0x26a180b201140e15, 0x850ac804d4384640, 0x2b001310e1590092, 0x800d43014402280c, 0x250a149009a870ac, 0x1856002621c2b201, 0x19001a860a880454, 0x024a1429201350e1, 0xa030ac004d438564, 0xc23200350c051008, 0xc804d428524026a1, 0x134061590098870a, 0x438464006a1c0a20, 0x0000000010a4804d, 0 ], [0xb440c08b68818117, 0x6d103022da206045, 0x5b440c08b6881811, 0x16d103022da20604, 0x45b440c08b688181, 0x116d103022da2060, 0x045b440c08b68818, 0x8116d103022da206, 0x6045b440c08b6881, 0x18116d103022da20, 0x06045b440c08b688, 0x818116d103022da2, 0x206045b440c08b68, 0x8818116d103022da, 0xa206045b440c08b6, 0x0000000000000001], [0x815304911d2573df, 0x602b11250832c381, 0xa8400704788f4809, 0xb4082c4d09210411, 0x9540c075104a8243, 0xc4e01080a2bd8818, 0x226b040380122321, 0xed1208408cd21071, 0x238212cc4084122d, 0xe131120070083591, 0x46046f51404201c8, 0x709054822b80c0aa, 0x620821242c8d040b, 0xa404bc4788380085, 0x6070d30429223501, 0x1ef3a92e224832a0], [0x7a049c880998630b, 0x60b3438000062731, 0x87da2e012960281a, 0x40cc00a04918b811, 0x1920480419089410, 0x15e806b391a91404, 0x803292a20091761c, 0x484b0505c1a2b3cc, 0x3004cf35160e8283, 0x5ea0e1ba24011525, 0x126080a256273580, 0xcc0820a442608048, 0x6f86207462481400, 0x341960501a5201d1, 0x817a33918000070b, 0x00014318664044e4], [0x50452131cb15977f, 0x3182b013240b0d09, 0x0e1000c7085100e1, 0x2789402665020ba7, 0x80c0190908a05403, 0x02d401a22088fa95, 0x1c9180248065e415, 0x84bf486910022614, 0x00624e0a19100225, 0x600ad02a09e98049, 0x2600c06a57c44111, 0x00a479300a814424, 0xc0021c3974102999, 0x03506321c0228438, 0x212882a42c340932, 0x0000001fba6a34e3], [0x300cd4682d12430b, 0x704fc6a280c6e183, 0x009000c122c0a750, 0x684c67a807a32039, 0x486185ba21680264, 0x059194950edba400, 0x440030c0c94d1004, 0x80a425018280082e, 0x030c002274100141, 0xa92989a02008b293, 0x5da186120025db70, 0x15e6321626401684, 0x830009009c04c5e0, 0x4563f20e0ae50344, 0x162b300cc1876301, 0x0000000050c248b4], ]; num-prime-0.4.4/src/traits.rs000064400000000000000000000252700072674642500142430ustar 00000000000000use core::default::Default; use std::ops::{BitAnd, BitOr}; use either::Either; use num_integer::{Integer, Roots}; use num_traits::Pow; /// This trait support unified bit testing for (unsigned) integers pub trait BitTest { /// Get the minimum required number of bits to represent this integer fn bits(&self) -> usize; /// Get the i-th bit of the integer, with i specified by `position` fn bit(&self, position: usize) -> bool; /// Get the number of trailing zeros in the integer fn trailing_zeros(&self) -> usize; } /// This enum describes the result of primality checks #[derive(Debug, Clone, Copy, PartialEq)] pub enum Primality { /// The number passes deterministic primality check. Yes, /// The number is a composite and failed at least one specific primality check. No, /// The number passes several probabilistic primality check. /// The associated float number carries the probability of the number being a prime /// (conditioned on that it's already a probable prime) Probable(f32), } impl Primality { /// Check whether the resule indicates that the number is /// (very) probably a prime. Return false only on [Primality::No] #[inline(always)] pub fn probably(self) -> bool { match self { Primality::No => false, _ => true, } } } impl BitAnd for Primality { type Output = Primality; /// Combine two primality results by ensuring both numbers are prime fn bitand(self, rhs: Primality) -> Self::Output { match self { Primality::No => Primality::No, Primality::Yes => rhs, Primality::Probable(p) => match rhs { Primality::No => Primality::No, Primality::Yes => Primality::Probable(p), Primality::Probable(p2) => Primality::Probable(p * p2), }, } } } impl BitOr for Primality { type Output = Primality; /// Combine two primality results by ensuring either numbers is prime fn bitor(self, rhs: Primality) -> Self::Output { match self { Primality::No => rhs, Primality::Yes => Primality::Yes, Primality::Probable(p) => match rhs { Primality::No => Primality::Probable(p), Primality::Yes => Primality::Yes, Primality::Probable(p2) => Primality::Probable(1. - (1. - p) * (1. - p2)), }, } } } /// Represents a configuration for a primality test #[derive(Debug, Clone, Copy)] #[non_exhaustive] pub struct PrimalityTestConfig { // TODO: add option to divides small primes in the table // and this option should be enabled if the probabilistic test is used for strict config /// Number of strong probable prime test, starting from base 2 pub sprp_trials: usize, /// Number of strong probable prime test with random bases pub sprp_random_trials: usize, /// Whether perform strong lucas probable prime test (with automatically selected parameters) pub slprp_test: bool, /// Whether perform extra strong lucas probable prime test (with automatically selected parameters) pub eslprp_test: bool, } impl Default for PrimalityTestConfig { /// Create a defalt primality testing configuration. This config will eliminate most /// composites with little computation fn default() -> Self { Self { sprp_trials: 2, // test base 2 and 3 sprp_random_trials: 3, // choose other 3 random bases slprp_test: false, eslprp_test: false, } } } impl PrimalityTestConfig { /// Create a configuration with a very strong primality check. It's based on /// the **strongest deterministic primality testing** and some SPRP tests with /// random bases. pub fn strict() -> Self { let mut config = Self::bpsw(); config.sprp_random_trials = 1; config } /// Create a configuration for Baillie-PSW test (base 2 SPRP test + SLPRP test) pub fn bpsw() -> Self { Self { sprp_trials: 1, sprp_random_trials: 0, slprp_test: true, eslprp_test: false, } } /// Create a configuration for PSW test (base 2 SPRP + Fibonacci test) fn psw() { todo!() // TODO: implement Fibonacci PRP } } /// Represents a configuration for integer factorization #[derive(Debug, Clone, Copy)] #[non_exhaustive] pub struct FactorizationConfig { /// Config for testing if a factor is prime pub primality_config: PrimalityTestConfig, /// Prime limit of trial division, you also need to reserve the primes in the buffer /// if all primes under the limit are to be tested. `None` means using all available primes. pub td_limit: Option, /// Number of trials with Pollard's rho method pub rho_trials: usize, /// Number of trials with Pollard's p-1 method pm1_trials: usize, /// Number of trials with William's p+1 method pp1_trials: usize, } impl Default for FactorizationConfig { /// Create a defalt primality testing configuration. This config will factorize /// most integers within decent time fn default() -> Self { const THRESHOLD_DEFAULT_TD: u64 = 1 << 14; Self { primality_config: PrimalityTestConfig::default(), td_limit: Some(THRESHOLD_DEFAULT_TD), rho_trials: 4, pm1_trials: 0, pp1_trials: 0, } } } impl FactorizationConfig { /// Same as the default configuration but with strict primality check pub fn strict() -> Self { let mut config = Self::default(); config.primality_config = PrimalityTestConfig::strict(); config } } // FIXME: backport to num_integer (see https://github.com/rust-num/num-traits/issues/233) /// Extension on [num_integer::Roots] to support perfect power check on integers pub trait ExactRoots: Roots + Pow + Clone { fn nth_root_exact(&self, n: u32) -> Option { let r = self.nth_root(n); if &r.clone().pow(n) == self { Some(r) } else { None } } fn sqrt_exact(&self) -> Option { self.nth_root_exact(2) } fn cbrt_exact(&self) -> Option { self.nth_root_exact(3) } fn is_nth_power(&self, n: u32) -> bool { self.nth_root_exact(n).is_some() } fn is_square(&self) -> bool { self.sqrt_exact().is_some() } fn is_cubic(&self) -> bool { self.cbrt_exact().is_some() } } // TODO: implement is_perfect_power, this could be used during factorization // to filter out perfect powers when factorize large integers // REF: PARI/GP `Z_ispowerall`, `is_357_power` // FLINT `n_is_perfect_power235`, `fmpz_is_perfect_power` // GMP `mpz_perfect_power_p` /// This trait represents a general data structure that stores primes. /// /// It's recommended to store at least a bunch of small primes in the buffer /// to make some of the algorithms more efficient. pub trait PrimeBuffer<'a> { type PrimeIter: Iterator; /// Directly return an iterator of existing primes fn iter(&'a self) -> Self::PrimeIter; /// Generate primes until the largest prime in the buffer is equal or larger than limit fn reserve(&mut self, limit: u64); /// Get the largest primes in the list fn bound(&self) -> u64; /// Test if the number is in the buffer. If a number is not in the buffer, /// then it's either a composite or large than [PrimeBuffer::bound()] fn contains(&self, num: u64) -> bool; /// clear the prime buffer to save memory fn clear(&mut self); } /// This trait implements various primality testing algorithms /// /// Reference: /// - pub trait PrimalityUtils: Integer + Clone { /// Test if the integer is a (Fermat) probable prime fn is_prp(&self, base: Self) -> bool; /// Test if the integer is a strong probable prime (based on Miller-Rabin test). fn is_sprp(&self, base: Self) -> bool; /// Do a Miller-Rabin test. The return value is a integer if it finds a factor of /// the integer, otherwise it reports the test result. fn test_sprp(&self, base: Self) -> Either; /// Test if the integer is a Lucas probable prime /// If either of p, q is not specified, then we will use Selfridge's Method A to choose p, q fn is_lprp(&self, p: Option, q: Option) -> bool; /// Test if the integer is a strong Lucas probable prime /// If either of p, q is not specified, then we will use Selfridge's Method A to choose p, q fn is_slprp(&self, p: Option, q: Option) -> bool; /// Test if the integer is an extra strong Lucas probable prime /// If p is not specified, then first p starting from 3 such that Jacobi symbol is -1 will be chosen, which is sometimes refered as "Method C" fn is_eslprp(&self, p: Option) -> bool; // TODO: implement ECPP test // https://en.wikipedia.org/wiki/Elliptic_curve_primality // TODO: implement is_vprp (Lucas-V probable prime test) // https://arxiv.org/pdf/2006.14425.pdf } /// Supports random generation of primes pub trait RandPrime { /// Generate a random prime within the given bit size limit /// /// # Panics /// if the bit_size is 0 or it's larger than the bit width of the integer fn gen_prime(&mut self, bit_size: usize, config: Option) -> T; /// Generate a random prime with **exact** the given bit size /// /// # Panics /// if the bit_size is 0 or it's larger than the bit width of the integer fn gen_prime_exact(&mut self, bit_size: usize, config: Option) -> T; /// Generate a random (Sophie German) safe prime within the given bit size limit. The generated prime /// is guaranteed to pass the [is_safe_prime][crate::nt_funcs::is_safe_prime] test /// /// # Panics /// if the bit_size is 0 or it's larger than the bit width of the integer fn gen_safe_prime(&mut self, bit_size: usize) -> T; /// Generate a random (Sophie German) safe prime with the **exact** given bit size. The generated prime /// is guaranteed to pass the [is_safe_prime][crate::nt_funcs::is_safe_prime] test /// /// # Panics /// if the bit_size is 0 or it's larger than the bit width of the integer fn gen_safe_prime_exact(&mut self, bit_size: usize) -> T; }