From b541e793e20fa3c991e0328ec2ff7926bdcdfd45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Fri, 10 May 2024 13:05:02 +0200 Subject: [PATCH 01/61] fix: Ignore no_predicates in brillig functions (#5012) # Description ## Problem\* Resolves https://github.com/noir-lang/noir/issues/5010 ## Summary\* Ignores no predicates for brillig functions to avoid trying to convert to brillig flattened functions. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_evaluator/src/ssa/opt/inlining.rs | 7 ++++--- .../no_predicates_brillig/Nargo.toml | 7 +++++++ .../no_predicates_brillig/Prover.toml | 2 ++ .../no_predicates_brillig/src/main.nr | 12 ++++++++++++ 4 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 test_programs/execution_success/no_predicates_brillig/Nargo.toml create mode 100644 test_programs/execution_success/no_predicates_brillig/Prover.toml create mode 100644 test_programs/execution_success/no_predicates_brillig/src/main.nr diff --git a/compiler/noirc_evaluator/src/ssa/opt/inlining.rs b/compiler/noirc_evaluator/src/ssa/opt/inlining.rs index bddfb25f26c..77b9e545e03 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/inlining.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/inlining.rs @@ -11,7 +11,7 @@ use crate::ssa::{ ir::{ basic_block::BasicBlockId, dfg::{CallStack, InsertInstructionResult}, - function::{Function, FunctionId}, + function::{Function, FunctionId, RuntimeType}, instruction::{Instruction, InstructionId, TerminatorInstruction}, value::{Value, ValueId}, }, @@ -392,10 +392,11 @@ impl<'function> PerFunctionContext<'function> { Some(func_id) => { let function = &ssa.functions[&func_id]; // If we have not already finished the flattening pass, functions marked - // to not have predicates should be marked as entry points. + // to not have predicates should be marked as entry points unless we are inlining into brillig. let no_predicates_is_entry_point = self.context.no_predicates_is_entry_point - && function.is_no_predicates(); + && function.is_no_predicates() + && !matches!(self.source_function.runtime(), RuntimeType::Brillig); if function.runtime().is_entry_point() || no_predicates_is_entry_point { self.push_instruction(*id); } else { diff --git a/test_programs/execution_success/no_predicates_brillig/Nargo.toml b/test_programs/execution_success/no_predicates_brillig/Nargo.toml new file mode 100644 index 00000000000..328d78c8f99 --- /dev/null +++ b/test_programs/execution_success/no_predicates_brillig/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "no_predicates_brillig" +type = "bin" +authors = [""] +compiler_version = ">=0.27.0" + +[dependencies] diff --git a/test_programs/execution_success/no_predicates_brillig/Prover.toml b/test_programs/execution_success/no_predicates_brillig/Prover.toml new file mode 100644 index 00000000000..93a825f609f --- /dev/null +++ b/test_programs/execution_success/no_predicates_brillig/Prover.toml @@ -0,0 +1,2 @@ +x = "10" +y = "20" diff --git a/test_programs/execution_success/no_predicates_brillig/src/main.nr b/test_programs/execution_success/no_predicates_brillig/src/main.nr new file mode 100644 index 00000000000..1d088473aa7 --- /dev/null +++ b/test_programs/execution_success/no_predicates_brillig/src/main.nr @@ -0,0 +1,12 @@ +unconstrained fn main(x: u32, y: pub u32) { + basic_checks(x, y); +} + +#[no_predicates] +fn basic_checks(x: u32, y: u32) { + if x > y { + assert(x == 10); + } else { + assert(y == 20); + } +} From 7280baddedca8e08f7d4a30c80e1b0233dff09a2 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Fri, 10 May 2024 14:12:46 +0100 Subject: [PATCH 02/61] chore: add script to print lines of code (#4991) # Description ## Problem\* Resolves ## Summary\* This PR adds a small script to print out the LOC for various sections of the codebase. Adding weightings will come in a later PR. Note that this PR relies on my fork of tokei which has support for Noir source code. cc @rumata888 ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .tokeignore | 12 ++++++++++++ scripts/count_loc.sh | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 .tokeignore create mode 100755 scripts/count_loc.sh diff --git a/.tokeignore b/.tokeignore new file mode 100644 index 00000000000..55f24e41dbd --- /dev/null +++ b/.tokeignore @@ -0,0 +1,12 @@ +docs +scripts + +# aztec_macros is explicitly considered OOS for Noir audit +aztec_macros + +# config files +*.toml +*.md +*.json +*.txt +*.config.mjs diff --git a/scripts/count_loc.sh b/scripts/count_loc.sh new file mode 100755 index 00000000000..91565aa6c4a --- /dev/null +++ b/scripts/count_loc.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -eu + +# Run relative to repo root +cd $(dirname "$0")/../ + +if ! command -v "tokei" >/dev/null 2>&1; then + echo "Error: tokei is required but not installed." >&2 + echo "Error: Run \`cargo install --git https://github.com/TomAFrench/tokei --branch tf/add-noir-support tokei\`" >&2 + + exit 1 +fi + +echo "" +echo "Total:" + +tokei ./ --sort code + +echo "" +echo "ACIR/ACVM:" +tokei ./acvm-repo --sort code + +echo "" +echo "Compiler:" +tokei ./compiler --sort code + +echo "" +echo "Tooling:" +tokei ./tooling --sort code + +echo "" +echo "Standard Library:" +tokei ./noir_stdlib --sort code From 9c6de4b25d318c6d211361dd62a112a9d2432c56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Fri, 10 May 2024 18:20:03 +0200 Subject: [PATCH 03/61] fix: Fix no predicates for brillig with intermediate functions (#5015) # Description ## Problem\* Fixes https://github.com/noir-lang/noir/pull/5012 using the entry point instead of the source function, to consider intermediate functions. ## Summary\* ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_evaluator/src/ssa/opt/inlining.rs | 3 ++- .../execution_success/no_predicates_brillig/src/main.nr | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/noirc_evaluator/src/ssa/opt/inlining.rs b/compiler/noirc_evaluator/src/ssa/opt/inlining.rs index 77b9e545e03..73dc3888184 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/inlining.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/inlining.rs @@ -393,10 +393,11 @@ impl<'function> PerFunctionContext<'function> { let function = &ssa.functions[&func_id]; // If we have not already finished the flattening pass, functions marked // to not have predicates should be marked as entry points unless we are inlining into brillig. + let entry_point = &ssa.functions[&self.context.entry_point]; let no_predicates_is_entry_point = self.context.no_predicates_is_entry_point && function.is_no_predicates() - && !matches!(self.source_function.runtime(), RuntimeType::Brillig); + && !matches!(entry_point.runtime(), RuntimeType::Brillig); if function.runtime().is_entry_point() || no_predicates_is_entry_point { self.push_instruction(*id); } else { diff --git a/test_programs/execution_success/no_predicates_brillig/src/main.nr b/test_programs/execution_success/no_predicates_brillig/src/main.nr index 1d088473aa7..65e2e5d61fe 100644 --- a/test_programs/execution_success/no_predicates_brillig/src/main.nr +++ b/test_programs/execution_success/no_predicates_brillig/src/main.nr @@ -1,4 +1,8 @@ unconstrained fn main(x: u32, y: pub u32) { + intermediate_function(x, y); +} + +fn intermediate_function(x: u32, y: u32) { basic_checks(x, y); } From e5ab24d6a4154d11b3c8ae08f4431b7b93c76f23 Mon Sep 17 00:00:00 2001 From: Innokentii Sennovskii Date: Tue, 14 May 2024 15:06:21 +0100 Subject: [PATCH 04/61] fix: Fixed several vulnerabilities in U128, added some tests (#5024) # Description ## Summary\* I added the tests for construction and depedent functions, unconstrained division and wrapping multiplication, fixing several bugs. I also added a directory with the bugs so that it's easier to dive into what sort of issues we come across in the future. ## Documentation\* Check one: - [ ] No documentation needed. - [x] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- noir_stdlib/src/uint128.nr | 244 ++++++++++++++++++++++++++-- security/insectarium/noir_stdlib.md | 61 +++++++ 2 files changed, 290 insertions(+), 15 deletions(-) create mode 100644 security/insectarium/noir_stdlib.md diff --git a/noir_stdlib/src/uint128.nr b/noir_stdlib/src/uint128.nr index 9c61fc801f3..173fa54863a 100644 --- a/noir_stdlib/src/uint128.nr +++ b/noir_stdlib/src/uint128.nr @@ -1,8 +1,9 @@ use crate::ops::{Add, Sub, Mul, Div, Rem, Not, BitOr, BitAnd, BitXor, Shl, Shr}; use crate::cmp::{Eq, Ord, Ordering}; +use crate::println; global pow64 : Field = 18446744073709551616; //2^64; - +global pow63 : Field = 9223372036854775808; // 2^63; struct U128 { lo: Field, hi: Field, @@ -20,6 +21,13 @@ impl U128 { U128::from_u64s_le(lo, hi) } + pub fn zero() -> U128 { + U128 { lo: 0, hi: 0 } + } + + pub fn one() -> U128 { + U128 { lo: 1, hi: 0 } + } pub fn from_le_bytes(bytes: [u8; 16]) -> U128 { let mut lo = 0; let mut base = 1; @@ -87,27 +95,44 @@ impl U128 { U128 { lo: lo as Field, hi: hi as Field } } + unconstrained fn uconstrained_check_is_upper_ascii(ascii: u8) -> bool { + ((ascii >= 65) & (ascii <= 90)) // Between 'A' and 'Z' + } + fn decode_ascii(ascii: u8) -> Field { if ascii < 58 { ascii - 48 - } else if ascii < 71 { - ascii - 55 } else { + let ascii = ascii + 32 * (U128::uconstrained_check_is_upper_ascii(ascii) as u8); + assert(ascii >= 97); // enforce >= 'a' + assert(ascii <= 102); // enforce <= 'f' ascii - 87 } as Field } + // TODO: Replace with a faster version. + // A circuit that uses this function can be slow to compute + // (we're doing up to 127 calls to compute the quotient) unconstrained fn unconstrained_div(self: Self, b: U128) -> (U128, U128) { - if self < b { - (U128::from_u64s_le(0, 0), self) + if b == U128::zero() { + // Return 0,0 to avoid eternal loop + (U128::zero(), U128::zero()) + } else if self < b { + (U128::zero(), self) + } else if self == b { + (U128::one(), U128::zero()) } else { - //TODO check if this can overflow? - let (q,r) = self.unconstrained_div(b * U128::from_u64s_le(2, 0)); + let (q,r) = if b.hi as u64 >= pow63 as u64 { + // The result of multiplication by 2 would overflow + (U128::zero(), self) + } else { + self.unconstrained_div(b * U128::from_u64s_le(2, 0)) + }; let q_mul_2 = q * U128::from_u64s_le(2, 0); if r < b { (q_mul_2, r) } else { - (q_mul_2 + U128::from_u64s_le(1, 0), r - b) + (q_mul_2 + U128::one(), r - b) } } } @@ -129,11 +154,7 @@ impl U128 { let low = self.lo * b.lo; let lo = low as u64 as Field; let carry = (low - lo) / pow64; - let high = if crate::field::modulus_num_bits() as u32 > 196 { - (self.lo + self.hi) * (b.lo + b.hi) - low + carry - } else { - self.lo * b.hi + self.hi * b.lo + carry - }; + let high = self.lo * b.hi + self.hi * b.lo + carry; let hi = high as u64 as Field; U128 { lo, hi } } @@ -294,8 +315,8 @@ impl Shr for U128 { } } -mod test { - use crate::uint128::{U128, pow64}; +mod tests { + use crate::uint128::{U128, pow64, pow63}; #[test] fn test_not() { @@ -309,4 +330,197 @@ mod test { let not_not_num = not_num.not(); assert_eq(num, not_not_num); } + #[test] + fn test_construction() { + // Check little-endian u64 is inversed with big-endian u64 construction + let a = U128::from_u64s_le(2, 1); + let b = U128::from_u64s_be(1, 2); + assert_eq(a, b); + // Check byte construction is equivalent + let c = U128::from_le_bytes([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); + let d = U128::from_u64s_le(0x0706050403020100, 0x0f0e0d0c0b0a0908); + assert_eq(c, d); + } + #[test] + fn test_byte_decomposition() { + let a = U128::from_u64s_le(0x0706050403020100, 0x0f0e0d0c0b0a0908); + // Get big-endian and little-endian byte decompostions + let le_bytes_a= a.to_le_bytes(); + let be_bytes_a= a.to_be_bytes(); + + // Check equivalence + for i in 0..16 { + assert_eq(le_bytes_a[i], be_bytes_a[15 - i]); + } + // Reconstruct U128 from byte decomposition + let b= U128::from_le_bytes(le_bytes_a); + // Check that it's the same element + assert_eq(a, b); + } + #[test] + fn test_hex_constuction() { + let a = U128::from_u64s_le(0x1, 0x2); + let b = U128::from_hex("0x20000000000000001"); + assert_eq(a, b); + + let c= U128::from_hex("0xffffffffffffffffffffffffffffffff"); + let d= U128::from_u64s_le(0xffffffffffffffff, 0xffffffffffffffff); + assert_eq(c, d); + + let e= U128::from_hex("0x00000000000000000000000000000000"); + let f= U128::from_u64s_le(0, 0); + assert_eq(e, f); + } + + // Ascii decode tests + + #[test] + fn test_ascii_decode_correct_range() { + // '0'..'9' range + for i in 0..10 { + let decoded= U128::decode_ascii(48 + i); + assert_eq(decoded, i as Field); + } + // 'A'..'F' range + for i in 0..6 { + let decoded = U128::decode_ascii(65 + i); + assert_eq(decoded, (i + 10) as Field); + } + // 'a'..'f' range + for i in 0..6 { + let decoded = U128::decode_ascii(97 + i); + assert_eq(decoded, (i + 10) as Field); + } + } + + #[test(should_fail)] + fn test_ascii_decode_range_less_than_48_fails_0() { + crate::println(U128::decode_ascii(0)); + } + #[test(should_fail)] + fn test_ascii_decode_range_less_than_48_fails_1() { + crate::println(U128::decode_ascii(47)); + } + + #[test(should_fail)] + fn test_ascii_decode_range_58_64_fails_0() { + let _ = U128::decode_ascii(58); + } + #[test(should_fail)] + fn test_ascii_decode_range_58_64_fails_1() { + let _ = U128::decode_ascii(64); + } + #[test(should_fail)] + fn test_ascii_decode_range_71_96_fails_0() { + let _ = U128::decode_ascii(71); + } + #[test(should_fail)] + fn test_ascii_decode_range_71_96_fails_1() { + let _ = U128::decode_ascii(96); + } + #[test(should_fail)] + fn test_ascii_decode_range_greater_than_102_fails() { + let _ = U128::decode_ascii(103); + } + + #[test(should_fail)] + fn test_ascii_decode_regression() { + // This code will actually fail because of ascii_decode, + // but in the past it was possible to create a value > (1<<128) + let a = U128::from_hex("0x~fffffffffffffffffffffffffffffff"); + let b:Field= a.to_integer(); + let c= b.to_le_bytes(17); + assert(c[16] != 0); + } + + #[test] + fn test_unconstrained_div() { + // Test the potential overflow case + let a= U128::from_u64s_le(0x0, 0xffffffffffffffff); + let b= U128::from_u64s_le(0x0, 0xfffffffffffffffe); + let c= U128::one(); + let d= U128::from_u64s_le(0x0, 0x1); + let (q,r) = a.unconstrained_div(b); + assert_eq(q, c); + assert_eq(r, d); + + let a = U128::from_u64s_le(2, 0); + let b = U128::one(); + // Check the case where a is a multiple of b + let (c,d ) = a.unconstrained_div(b); + assert_eq((c, d), (a, U128::zero())); + + // Check where b is a multiple of a + let (c,d) = b.unconstrained_div(a); + assert_eq((c, d), (U128::zero(), b)); + + // Dividing by zero returns 0,0 + let a = U128::from_u64s_le(0x1, 0x0); + let b = U128::zero(); + let (c,d)= a.unconstrained_div(b); + assert_eq((c, d), (U128::zero(), U128::zero())); + + // Dividing 1<<127 by 1<<127 (special case) + let a = U128::from_u64s_le(0x0, pow63 as u64); + let b = U128::from_u64s_le(0x0, pow63 as u64); + let (c,d )= a.unconstrained_div(b); + assert_eq((c, d), (U128::one(), U128::zero())); + } + + #[test] + fn integer_conversions() { + // Maximum + let start:Field = 0xffffffffffffffffffffffffffffffff; + let a = U128::from_integer(start); + let end = a.to_integer(); + assert_eq(start, end); + + // Minimum + let start:Field = 0x0; + let a = U128::from_integer(start); + let end = a.to_integer(); + assert_eq(start, end); + + // Low limb + let start:Field = 0xffffffffffffffff; + let a = U128::from_integer(start); + let end = a.to_integer(); + assert_eq(start, end); + + // High limb + let start:Field = 0xffffffffffffffff0000000000000000; + let a = U128::from_integer(start); + let end = a.to_integer(); + assert_eq(start, end); + } + #[test] + fn test_wrapping_mul() { + // 1*0==0 + assert_eq(U128::zero(), U128::zero().wrapping_mul(U128::one())); + + // 0*1==0 + assert_eq(U128::zero(), U128::one().wrapping_mul(U128::zero())); + + // 1*1==1 + assert_eq(U128::one(), U128::one().wrapping_mul(U128::one())); + + // 0 * ( 1 << 64 ) == 0 + assert_eq(U128::zero(), U128::zero().wrapping_mul(U128::from_u64s_le(0, 1))); + + // ( 1 << 64 ) * 0 == 0 + assert_eq(U128::zero(), U128::from_u64s_le(0, 1).wrapping_mul(U128::zero())); + + // 1 * ( 1 << 64 ) == 1 << 64 + assert_eq(U128::from_u64s_le(0, 1), U128::from_u64s_le(0, 1).wrapping_mul(U128::one())); + + // ( 1 << 64 ) * 1 == 1 << 64 + assert_eq(U128::from_u64s_le(0, 1), U128::one().wrapping_mul(U128::from_u64s_le(0, 1))); + + // ( 1 << 64 ) * ( 1 << 64 ) == 1 << 64 + assert_eq(U128::zero(), U128::from_u64s_le(0, 1).wrapping_mul(U128::from_u64s_le(0, 1))); + // -1 * -1 == 1 + assert_eq( + U128::one(), U128::from_u64s_le(0xffffffffffffffff, 0xffffffffffffffff).wrapping_mul(U128::from_u64s_le(0xffffffffffffffff, 0xffffffffffffffff)) + ); + } } diff --git a/security/insectarium/noir_stdlib.md b/security/insectarium/noir_stdlib.md new file mode 100644 index 00000000000..5ec4eb5f6cd --- /dev/null +++ b/security/insectarium/noir_stdlib.md @@ -0,0 +1,61 @@ +# Bugs found in Noir stdlib + +## U128 + +### decode_ascii +Old **decode_ascii** function didn't check that the values of individual bytes in the string were just in the range of [0-9a-f-A-F]. +```rust +fn decode_ascii(ascii: u8) -> Field { + if ascii < 58 { + ascii - 48 + } else if ascii < 71 { + ascii - 55 + } else { + ascii - 87 + } as Field +} +``` +Since the function used the assumption that decode_ascii returns values in range [0,15] to construct **lo** and **hi** it was possible to overflow these 64-bit limbs. + +### unconstrained_div +```rust + unconstrained fn unconstrained_div(self: Self, b: U128) -> (U128, U128) { + if self < b { + (U128::from_u64s_le(0, 0), self) + } else { + //TODO check if this can overflow? + let (q,r) = self.unconstrained_div(b * U128::from_u64s_le(2, 0)); + let q_mul_2 = q * U128::from_u64s_le(2, 0); + if r < b { + (q_mul_2, r) + } else { + (q_mul_2 + U128::from_u64s_le(1, 0), r - b) + } + } + } +``` +There were 2 issues in unconstrained_div: +1) Attempting to divide by zero resulted in an infinite loop, because there was no check. +2) $a >= 2^{127}$ cause the function to multiply b to such power of 2 that the result would be more than $2^{128}$ and lead to assertion failure even though it was a legitimate input + +N.B. initial fix by Rumata888 also had an edgecase missing for when a==b and b >= (1<<127). + +### wrapping_mul +```rust +fn wrapping_mul(self: Self, b: U128) -> U128 { + let low = self.lo * b.lo; + let lo = low as u64 as Field; + let carry = (low - lo) / pow64; + let high = if crate::field::modulus_num_bits() as u32 > 196 { + (self.lo + self.hi) * (b.lo + b.hi) - low + carry // Bug + } else { + self.lo * b.hi + self.hi * b.lo + carry + }; + let hi = high as u64 as Field; + U128 { lo, hi } + } +``` +Wrapping mul had the code copied from regular mul barring the assertion that the product of high limbs is zero. Because that check was removed, the optimized path for moduli > 196 bits was incorrect, since it included their product (as at least one of them was supposed to be zero originally, but not for wrapping multiplication) + + + From a5b7df12faf9d71ff24f8c5cde5e78da44558caf Mon Sep 17 00:00:00 2001 From: guipublic <47281315+guipublic@users.noreply.github.com> Date: Tue, 14 May 2024 19:31:46 +0200 Subject: [PATCH 05/61] feat: do not return databus returndata, keep it private. (#5023) # Description ## Problem\* Related to #4974 ## Summary\* Very small PR which avoids returning databus objects, because they need to be handled as private inputs. This is incremental work, so it cannot be tested yet. The PR only impact databus use case. ## Additional Context ## Documentation\* Check one: - [X] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [X] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../noirc_evaluator/src/ssa/acir_gen/mod.rs | 21 +++++++++++++++---- tooling/noirc_abi/src/lib.rs | 10 ++++++++- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index dea7e2fa13b..05d2e3e3e6a 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -1729,13 +1729,16 @@ impl<'a> Context<'a> { // will expand the array if there is one. let return_acir_vars = self.flatten_value_list(return_values, dfg)?; let mut warnings = Vec::new(); - for acir_var in return_acir_vars { + for (acir_var, is_databus) in return_acir_vars { if self.acir_context.is_constant(&acir_var) { warnings.push(SsaReport::Warning(InternalWarning::ReturnConstant { call_stack: call_stack.clone(), })); } - self.acir_context.return_var(acir_var)?; + if !is_databus { + // We do not return value for the data bus. + self.acir_context.return_var(acir_var)?; + } } Ok(warnings) } @@ -2659,12 +2662,22 @@ impl<'a> Context<'a> { &mut self, arguments: &[ValueId], dfg: &DataFlowGraph, - ) -> Result, InternalError> { + ) -> Result, InternalError> { let mut acir_vars = Vec::with_capacity(arguments.len()); for value_id in arguments { + let is_databus = if let Some(return_databus) = self.data_bus.return_data { + dfg[*value_id] == dfg[return_databus] + } else { + false + }; let value = self.convert_value(*value_id, dfg); acir_vars.append( - &mut self.acir_context.flatten(value)?.iter().map(|(var, _)| *var).collect(), + &mut self + .acir_context + .flatten(value)? + .iter() + .map(|(var, _)| (*var, is_databus)) + .collect(), ); } Ok(acir_vars) diff --git a/tooling/noirc_abi/src/lib.rs b/tooling/noirc_abi/src/lib.rs index 7e89a102a98..7a1d1787ca5 100644 --- a/tooling/noirc_abi/src/lib.rs +++ b/tooling/noirc_abi/src/lib.rs @@ -471,7 +471,15 @@ impl Abi { .copied() }) { - Some(decode_value(&mut return_witness_values.into_iter(), &return_type.abi_type)?) + // We do not return value for the data bus. + if return_type.visibility == AbiVisibility::DataBus { + None + } else { + Some(decode_value( + &mut return_witness_values.into_iter(), + &return_type.abi_type, + )?) + } } else { // Unlike for the circuit inputs, we tolerate not being able to find the witness values for the return value. // This is because the user may be decoding a partial witness map for which is hasn't been calculated yet. From abe49df24fb024414f00c9650c5a39ec6444b1a7 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 20 May 2024 01:24:09 +0100 Subject: [PATCH 06/61] chore: add benchmarks for pedersen and schnorr verification (#5056) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description ## Problem\* Resolves ## Summary\* This PR adds benchmarks for pedersen commitments/hashes as well as schnorr signature verification. ``` pedersen_commitment time: [542.17 µs 543.27 µs 544.40 µs] pedersen_hash time: [850.69 µs 852.11 µs 853.68 µs] schnorr_verify time: [1.5978 ms 1.5997 ms 1.6018 ms] ``` ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../benches/criterion.rs | 53 ++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/acvm-repo/bn254_blackbox_solver/benches/criterion.rs b/acvm-repo/bn254_blackbox_solver/benches/criterion.rs index eb529ed2c11..a8fa7d8aae4 100644 --- a/acvm-repo/bn254_blackbox_solver/benches/criterion.rs +++ b/acvm-repo/bn254_blackbox_solver/benches/criterion.rs @@ -2,7 +2,8 @@ use criterion::{criterion_group, criterion_main, Criterion}; use std::{hint::black_box, time::Duration}; use acir::FieldElement; -use bn254_blackbox_solver::poseidon2_permutation; +use acvm_blackbox_solver::BlackBoxFunctionSolver; +use bn254_blackbox_solver::{poseidon2_permutation, Bn254BlackBoxSolver}; use pprof::criterion::{Output, PProfProfiler}; @@ -12,10 +13,58 @@ fn bench_poseidon2(c: &mut Criterion) { c.bench_function("poseidon2", |b| b.iter(|| poseidon2_permutation(black_box(&inputs), 4))); } +fn bench_pedersen_commitment(c: &mut Criterion) { + let inputs = [FieldElement::one(); 2]; + let solver = Bn254BlackBoxSolver::new(); + + c.bench_function("pedersen_commitment", |b| { + b.iter(|| solver.pedersen_commitment(black_box(&inputs), 0)) + }); +} + +fn bench_pedersen_hash(c: &mut Criterion) { + let inputs = [FieldElement::one(); 2]; + let solver = Bn254BlackBoxSolver::new(); + + c.bench_function("pedersen_hash", |b| b.iter(|| solver.pedersen_hash(black_box(&inputs), 0))); +} + +fn bench_schnorr_verify(c: &mut Criterion) { + let solver = Bn254BlackBoxSolver::new(); + + let pub_key_x = FieldElement::from_hex( + "0x04b260954662e97f00cab9adb773a259097f7a274b83b113532bce27fa3fb96a", + ) + .unwrap(); + let pub_key_y = FieldElement::from_hex( + "0x2fd51571db6c08666b0edfbfbc57d432068bccd0110a39b166ab243da0037197", + ) + .unwrap(); + let sig_bytes: [u8; 64] = [ + 1, 13, 119, 112, 212, 39, 233, 41, 84, 235, 255, 93, 245, 172, 186, 83, 157, 253, 76, 77, + 33, 128, 178, 15, 214, 67, 105, 107, 177, 234, 77, 48, 27, 237, 155, 84, 39, 84, 247, 27, + 22, 8, 176, 230, 24, 115, 145, 220, 254, 122, 135, 179, 171, 4, 214, 202, 64, 199, 19, 84, + 239, 138, 124, 12, + ]; + + let message: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + + c.bench_function("schnorr_verify", |b| { + b.iter(|| { + solver.schnorr_verify( + black_box(&pub_key_x), + black_box(&pub_key_y), + black_box(&sig_bytes), + black_box(message), + ) + }) + }); +} + criterion_group!( name = benches; config = Criterion::default().sample_size(40).measurement_time(Duration::from_secs(20)).with_profiler(PProfProfiler::new(100, Output::Flamegraph(None))); - targets = bench_poseidon2 + targets = bench_poseidon2, bench_pedersen_commitment, bench_pedersen_hash, bench_schnorr_verify ); criterion_main!(benches); From fb039f74df23aea39bc0593a5d538d82b4efadf0 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 20 May 2024 16:42:29 +0100 Subject: [PATCH 07/61] feat: add native rust implementations of pedersen functions (#4871) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description ## Problem\* Resolves #4863 ## Summary\* This PR pulls in the relevant code from [Barustenberg](https://github.com/laudiacay/barustenberg) for performing pedersen commitments + hashes. Tests are currently failing (seems like Barustenberg is failing its own CI) however it's a good starting point for a working implementation. In order for this PR to be merged we should have tests in barretenberg which shows expected outputs for all of these added functions and this code should replicate those. Benchmarks relative to #5056 ``` pedersen_commitment time: [3.5018 µs 3.5059 µs 3.5102 µs] change: [-99.357% -99.356% -99.354%] (p = 0.00 < 0.05) Performance has improved. Found 1 outliers among 40 measurements (2.50%) 1 (2.50%) low mild pedersen_hash time: [6.9828 µs 6.9920 µs 7.0021 µs] change: [-99.181% -99.180% -99.178%] (p = 0.00 < 0.05) Performance has improved. Found 2 outliers among 40 measurements (5.00%) 2 (5.00%) high mild ``` ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- Cargo.lock | 1 + acvm-repo/bn254_blackbox_solver/Cargo.toml | 1 + .../src/generator/generators.rs | 184 ++++++++++++++++++ .../src/generator/hash_to_curve.rs | 135 +++++++++++++ .../src/generator/mod.rs | 8 + acvm-repo/bn254_blackbox_solver/src/lib.rs | 24 ++- .../src/pedersen/commitment.rs | 76 ++++++++ .../src/pedersen/hash.rs | 68 +++++++ .../bn254_blackbox_solver/src/pedersen/mod.rs | 2 + .../src/wasm/barretenberg_structures.rs | 25 --- .../bn254_blackbox_solver/src/wasm/mod.rs | 20 -- .../src/wasm/pedersen.rs | 73 ------- cspell.json | 1 + 13 files changed, 491 insertions(+), 127 deletions(-) create mode 100644 acvm-repo/bn254_blackbox_solver/src/generator/generators.rs create mode 100644 acvm-repo/bn254_blackbox_solver/src/generator/hash_to_curve.rs create mode 100644 acvm-repo/bn254_blackbox_solver/src/generator/mod.rs create mode 100644 acvm-repo/bn254_blackbox_solver/src/pedersen/commitment.rs create mode 100644 acvm-repo/bn254_blackbox_solver/src/pedersen/hash.rs create mode 100644 acvm-repo/bn254_blackbox_solver/src/pedersen/mod.rs delete mode 100644 acvm-repo/bn254_blackbox_solver/src/wasm/barretenberg_structures.rs delete mode 100644 acvm-repo/bn254_blackbox_solver/src/wasm/pedersen.rs diff --git a/Cargo.lock b/Cargo.lock index a8c63c032aa..2e8eeb10a58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -614,6 +614,7 @@ dependencies = [ "acvm_blackbox_solver", "ark-ec", "ark-ff", + "ark-std", "cfg-if 1.0.0", "criterion", "getrandom 0.2.10", diff --git a/acvm-repo/bn254_blackbox_solver/Cargo.toml b/acvm-repo/bn254_blackbox_solver/Cargo.toml index 3a6c9b1d55b..b261be65735 100644 --- a/acvm-repo/bn254_blackbox_solver/Cargo.toml +++ b/acvm-repo/bn254_blackbox_solver/Cargo.toml @@ -40,6 +40,7 @@ getrandom.workspace = true wasmer = "4.2.6" [dev-dependencies] +ark-std = { version = "^0.4.0", default-features = false } criterion = "0.5.0" pprof = { version = "0.12", features = [ "flamegraph", diff --git a/acvm-repo/bn254_blackbox_solver/src/generator/generators.rs b/acvm-repo/bn254_blackbox_solver/src/generator/generators.rs new file mode 100644 index 00000000000..f89d582d167 --- /dev/null +++ b/acvm-repo/bn254_blackbox_solver/src/generator/generators.rs @@ -0,0 +1,184 @@ +// Adapted from https://github.com/laudiacay/barustenberg/blob/df6bc6f095fe7f288bf6a12e7317fd8eb33d68ae/barustenberg/src/ecc/groups/affine_element.rshttps://github.com/laudiacay/barustenberg/blob/df6bc6f095fe7f288bf6a12e7317fd8eb33d68ae/barustenberg/src/ecc/groups/group.rs +//! +//! Code is used under the MIT license + +use std::sync::OnceLock; + +use ark_ec::short_weierstrass::Affine; + +use acvm_blackbox_solver::blake3; +use grumpkin::GrumpkinParameters; + +use super::hash_to_curve::hash_to_curve; + +pub(crate) const DEFAULT_DOMAIN_SEPARATOR: &[u8] = "DEFAULT_DOMAIN_SEPARATOR".as_bytes(); +const NUM_DEFAULT_GENERATORS: usize = 8; + +fn default_generators() -> &'static [Affine; NUM_DEFAULT_GENERATORS] { + static INSTANCE: OnceLock<[Affine; NUM_DEFAULT_GENERATORS]> = + OnceLock::new(); + INSTANCE.get_or_init(|| { + _derive_generators(DEFAULT_DOMAIN_SEPARATOR, NUM_DEFAULT_GENERATORS as u32, 0) + .try_into() + .expect("Should generate `NUM_DEFAULT_GENERATORS`") + }) +} + +/// Derives generator points via [hash-to-curve][hash_to_curve]. +/// +/// # ALGORITHM DESCRIPTION +/// +/// 1. Each generator has an associated "generator index" described by its location in the vector +/// 2. a 64-byte preimage buffer is generated with the following structure: +/// - bytes 0-31: BLAKE3 hash of domain_separator +/// - bytes 32-63: generator index in big-endian form +/// 3. The [hash-to-curve algorithm][hash_to_curve] is used to hash the above into a curve point. +/// +/// NOTE: The domain separator is included to ensure that it is possible to derive independent sets of +/// index-addressable generators. +/// +/// [hash_to_curve]: super::hash_to_curve::hash_to_curve +pub(crate) fn derive_generators( + domain_separator_bytes: &[u8], + num_generators: u32, + starting_index: u32, +) -> Vec> { + // We cache a small number of the default generators so we can reuse them without needing to repeatedly recalculate them. + if domain_separator_bytes == DEFAULT_DOMAIN_SEPARATOR + && starting_index + num_generators <= NUM_DEFAULT_GENERATORS as u32 + { + let start_index = starting_index as usize; + let end_index = (starting_index + num_generators) as usize; + default_generators()[start_index..end_index].to_vec() + } else { + _derive_generators(domain_separator_bytes, num_generators, starting_index) + } +} + +fn _derive_generators( + domain_separator_bytes: &[u8], + num_generators: u32, + starting_index: u32, +) -> Vec> { + let mut generator_preimage = [0u8; 64]; + let domain_hash = blake3(domain_separator_bytes).expect("hash should succeed"); + //1st 32 bytes are blake3 domain_hash + generator_preimage[..32].copy_from_slice(&domain_hash); + + // Convert generator index in big-endian form + let mut res = Vec::with_capacity(num_generators as usize); + for i in starting_index..(starting_index + num_generators) { + let generator_be_bytes: [u8; 4] = i.to_be_bytes(); + generator_preimage[32] = generator_be_bytes[0]; + generator_preimage[33] = generator_be_bytes[1]; + generator_preimage[34] = generator_be_bytes[2]; + generator_preimage[35] = generator_be_bytes[3]; + let generator = hash_to_curve(&generator_preimage, 0); + res.push(generator); + } + res +} + +#[cfg(test)] +mod test { + + use ark_ec::AffineRepr; + use ark_ff::{BigInteger, PrimeField}; + + use super::*; + + #[test] + fn test_derive_generators() { + let res = derive_generators("test domain".as_bytes(), 128, 0); + + let is_unique = |y: Affine, j: usize| -> bool { + for (i, res) in res.iter().enumerate() { + if i != j && *res == y { + return false; + } + } + true + }; + + for (i, res) in res.iter().enumerate() { + assert!(is_unique(*res, i)); + assert!(res.is_on_curve()); + } + } + + #[test] + fn derive_length_generator() { + let domain_separator = "pedersen_hash_length"; + let length_generator = derive_generators(domain_separator.as_bytes(), 1, 0)[0]; + + let expected_generator = ( + "2df8b940e5890e4e1377e05373fae69a1d754f6935e6a780b666947431f2cdcd", + "2ecd88d15967bc53b885912e0d16866154acb6aac2d3f85e27ca7eefb2c19083", + ); + assert_eq!( + hex::encode(length_generator.x().unwrap().into_bigint().to_bytes_be()), + expected_generator.0, + "Failed on x component" + ); + assert_eq!( + hex::encode(length_generator.y().unwrap().into_bigint().to_bytes_be()), + expected_generator.1, + "Failed on y component" + ); + } + + #[test] + fn derives_default_generators() { + const DEFAULT_GENERATORS: &[[&str; 2]] = &[ + [ + "083e7911d835097629f0067531fc15cafd79a89beecb39903f69572c636f4a5a", + "1a7f5efaad7f315c25a918f30cc8d7333fccab7ad7c90f14de81bcc528f9935d", + ], + [ + "054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402", + "209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126", + ], + [ + "1c44f2a5207c81c28a8321a5815ce8b1311024bbed131819bbdaf5a2ada84748", + "03aaee36e6422a1d0191632ac6599ae9eba5ac2c17a8c920aa3caf8b89c5f8a8", + ], + [ + "26d8b1160c6821a30c65f6cb47124afe01c29f4338f44d4a12c9fccf22fb6fb2", + "05c70c3b9c0d25a4c100e3a27bf3cc375f8af8cdd9498ec4089a823d7464caff", + ], + [ + "20ed9c6a1d27271c4498bfce0578d59db1adbeaa8734f7facc097b9b994fcf6e", + "29cd7d370938b358c62c4a00f73a0d10aba7e5aaa04704a0713f891ebeb92371", + ], + [ + "0224a8abc6c8b8d50373d64cd2a1ab1567bf372b3b1f7b861d7f01257052d383", + "2358629b90eafb299d6650a311e79914b0215eb0a790810b26da5a826726d711", + ], + [ + "0f106f6d46bc904a5290542490b2f238775ff3c445b2f8f704c466655f460a2a", + "29ab84d472f1d33f42fe09c47b8f7710f01920d6155250126731e486877bcf27", + ], + [ + "0298f2e42249f0519c8a8abd91567ebe016e480f219b8c19461d6a595cc33696", + "035bec4b8520a4ece27bd5aafabee3dfe1390d7439c419a8c55aceb207aac83b", + ], + ]; + + let generated_generators = + derive_generators(DEFAULT_DOMAIN_SEPARATOR, DEFAULT_GENERATORS.len() as u32, 0); + for (i, (generator, expected_generator)) in + generated_generators.iter().zip(DEFAULT_GENERATORS).enumerate() + { + assert_eq!( + hex::encode(generator.x().unwrap().into_bigint().to_bytes_be()), + expected_generator[0], + "Failed on x component of generator {i}" + ); + assert_eq!( + hex::encode(generator.y().unwrap().into_bigint().to_bytes_be()), + expected_generator[1], + "Failed on y component of generator {i}" + ); + } + } +} diff --git a/acvm-repo/bn254_blackbox_solver/src/generator/hash_to_curve.rs b/acvm-repo/bn254_blackbox_solver/src/generator/hash_to_curve.rs new file mode 100644 index 00000000000..c0197883442 --- /dev/null +++ b/acvm-repo/bn254_blackbox_solver/src/generator/hash_to_curve.rs @@ -0,0 +1,135 @@ +// Adapted from https://github.com/laudiacay/barustenberg/blob/df6bc6f095fe7f288bf6a12e7317fd8eb33d68ae/barustenberg/src/ecc/groups/affine_element.rs +//! +//! Code is used under the MIT license + +use acvm_blackbox_solver::blake3; + +use ark_ec::{short_weierstrass::Affine, AffineRepr, CurveConfig}; +use ark_ff::Field; +use ark_ff::{BigInteger, PrimeField}; +use grumpkin::GrumpkinParameters; + +/// Hash a seed buffer into a point +/// +/// # ALGORITHM DESCRIPTION +/// +/// 1. Initialize unsigned integer `attempt_count = 0` +/// 2. Copy seed into a buffer whose size is 2 bytes greater than `seed` (initialized to `0`) +/// 3. Interpret `attempt_count` as a byte and write into buffer at `[buffer.size() - 2]` +/// 4. Compute Blake3 hash of buffer +/// 5. Set the end byte of the buffer to `1` +/// 6. Compute Blake3 hash of buffer +/// 7. Interpret the two hash outputs as the high / low 256 bits of a 512-bit integer (big-endian) +/// 8. Derive x-coordinate of point by reducing the 512-bit integer modulo the curve's field modulus (Fq) +/// 9. Compute `y^2` from the curve formula `y^2 = x^3 + ax + b` (`a`, `b` are curve params. for BN254, `a = 0`, `b = 3`) +/// 10. IF `y^2` IS NOT A QUADRATIC RESIDUE: +/// +/// a. increment `attempt_count` by 1 and go to step 2 +/// +/// 11. IF `y^2` IS A QUADRATIC RESIDUE: +/// +/// a. derive y coordinate via `y = sqrt(y)` +/// +/// b. Interpret most significant bit of 512-bit integer as a 'parity' bit +/// +/// c. If parity bit is set AND `y`'s most significant bit is not set, invert `y` +/// +/// d. If parity bit is not set AND `y`'s most significant bit is set, invert `y` +/// +/// e. return (x, y) +/// +/// N.B. steps c. and e. are because the `sqrt()` algorithm can return 2 values, +/// we need to a way to canonically distinguish between these 2 values and select a "preferred" one +pub(crate) fn hash_to_curve(seed: &[u8], attempt_count: u8) -> Affine { + let seed_size = seed.len(); + // expand by 2 bytes to cover incremental hash attempts + let mut target_seed = seed.to_vec(); + target_seed.extend_from_slice(&[0u8; 2]); + + target_seed[seed_size] = attempt_count; + target_seed[seed_size + 1] = 0; + let hash_hi = blake3(&target_seed).expect("hash should succeed"); + target_seed[seed_size + 1] = 1; + let hash_lo = blake3(&target_seed).expect("hash should succeed"); + + let mut hash = hash_hi.to_vec(); + hash.extend_from_slice(&hash_lo); + + // Here we reduce the 512 bit number modulo the base field modulus to calculate `x` + let x = <::BaseField as Field>::BasePrimeField::from_be_bytes_mod_order(&hash); + let x = ::BaseField::from_base_prime_field(x); + + if let Some(point) = Affine::::get_point_from_x_unchecked(x, false) { + let parity_bit = hash_hi[0] > 127; + let y_bit_set = point.y().unwrap().into_bigint().get_bit(0); + if (parity_bit && !y_bit_set) || (!parity_bit && y_bit_set) { + -point + } else { + point + } + } else { + hash_to_curve(seed, attempt_count + 1) + } +} + +#[cfg(test)] +mod test { + + use ark_ec::AffineRepr; + use ark_ff::{BigInteger, PrimeField}; + + use super::hash_to_curve; + + #[test] + fn smoke_test() { + let test_cases: [(&[u8], u8, (&str, &str)); 4] = [ + ( + &[], + 0, + ( + "24c4cb9c1206ab5470592f237f1698abe684dadf0ab4d7a132c32b2134e2c12e", + "0668b8d61a317fb34ccad55c930b3554f1828a0e5530479ecab4defe6bbc0b2e", + ), + ), + ( + &[], + 1, + ( + "24c4cb9c1206ab5470592f237f1698abe684dadf0ab4d7a132c32b2134e2c12e", + "0668b8d61a317fb34ccad55c930b3554f1828a0e5530479ecab4defe6bbc0b2e", + ), + ), + ( + &[1], + 0, + ( + "107f1b633c6113f3222f39f6256f0546b41a4880918c86864b06471afb410454", + "050cd3823d0c01590b6a50adcc85d2ee4098668fd28805578aa05a423ea938c6", + ), + ), + ( + &[0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64], + 0, + ( + "037c5c229ae495f6e8d1b4bf7723fafb2b198b51e27602feb8a4d1053d685093", + "10cf9596c5b2515692d930efa2cf3817607e4796856a79f6af40c949b066969f", + ), + ), + ]; + + for (seed, attempt_count, expected_point) in test_cases { + let point = hash_to_curve(seed, attempt_count); + assert!(point.is_on_curve()); + assert_eq!( + hex::encode(point.x().unwrap().into_bigint().to_bytes_be()), + expected_point.0, + "Failed on x component with seed {seed:?}, attempt_count {attempt_count}" + ); + assert_eq!( + hex::encode(point.y().unwrap().into_bigint().to_bytes_be()), + expected_point.1, + "Failed on y component with seed {seed:?}, attempt_count {attempt_count}" + ); + } + } +} diff --git a/acvm-repo/bn254_blackbox_solver/src/generator/mod.rs b/acvm-repo/bn254_blackbox_solver/src/generator/mod.rs new file mode 100644 index 00000000000..0f62642516a --- /dev/null +++ b/acvm-repo/bn254_blackbox_solver/src/generator/mod.rs @@ -0,0 +1,8 @@ +//! This module is adapted from the [Barustenberg][barustenberg] Rust implementation of the Barretenberg library. +//! +//! Code is used under the MIT license +//! +//! [barustenberg]: https://github.com/laudiacay/barustenberg/blob/df6bc6f095fe7f288bf6a12e7317fd8eb33d68ae/ + +pub(crate) mod generators; +mod hash_to_curve; diff --git a/acvm-repo/bn254_blackbox_solver/src/lib.rs b/acvm-repo/bn254_blackbox_solver/src/lib.rs index 4cb51b59755..ae6fb7999a0 100644 --- a/acvm-repo/bn254_blackbox_solver/src/lib.rs +++ b/acvm-repo/bn254_blackbox_solver/src/lib.rs @@ -6,14 +6,17 @@ use acir::{BlackBoxFunc, FieldElement}; use acvm_blackbox_solver::{BlackBoxFunctionSolver, BlackBoxResolutionError}; mod embedded_curve_ops; +mod generator; +mod pedersen; mod poseidon2; mod wasm; +use ark_ec::AffineRepr; pub use embedded_curve_ops::{embedded_curve_add, multi_scalar_mul}; pub use poseidon2::poseidon2_permutation; use wasm::Barretenberg; -use self::wasm::{Pedersen, SchnorrSig}; +use self::wasm::SchnorrSig; pub struct Bn254BlackBoxSolver { blackbox_vendor: Barretenberg, @@ -72,10 +75,13 @@ impl BlackBoxFunctionSolver for Bn254BlackBoxSolver { inputs: &[FieldElement], domain_separator: u32, ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { - #[allow(deprecated)] - self.blackbox_vendor.encrypt(inputs.to_vec(), domain_separator).map_err(|err| { - BlackBoxResolutionError::Failed(BlackBoxFunc::PedersenCommitment, err.to_string()) - }) + let inputs: Vec = inputs.iter().map(|input| input.into_repr()).collect(); + let result = pedersen::commitment::commit_native_with_index(&inputs, domain_separator); + let res_x = + FieldElement::from_repr(*result.x().expect("should not commit to point at infinity")); + let res_y = + FieldElement::from_repr(*result.y().expect("should not commit to point at infinity")); + Ok((res_x, res_y)) } fn pedersen_hash( @@ -83,10 +89,10 @@ impl BlackBoxFunctionSolver for Bn254BlackBoxSolver { inputs: &[FieldElement], domain_separator: u32, ) -> Result { - #[allow(deprecated)] - self.blackbox_vendor.hash(inputs.to_vec(), domain_separator).map_err(|err| { - BlackBoxResolutionError::Failed(BlackBoxFunc::PedersenCommitment, err.to_string()) - }) + let inputs: Vec = inputs.iter().map(|input| input.into_repr()).collect(); + let result = pedersen::hash::hash_with_index(&inputs, domain_separator); + let result = FieldElement::from_repr(result); + Ok(result) } fn multi_scalar_mul( diff --git a/acvm-repo/bn254_blackbox_solver/src/pedersen/commitment.rs b/acvm-repo/bn254_blackbox_solver/src/pedersen/commitment.rs new file mode 100644 index 00000000000..6769150508a --- /dev/null +++ b/acvm-repo/bn254_blackbox_solver/src/pedersen/commitment.rs @@ -0,0 +1,76 @@ +// Taken from: https://github.com/laudiacay/barustenberg/blob/df6bc6f095fe7f288bf6a12e7317fd8eb33d68ae/barustenberg/src/crypto/pedersen/pederson.rs + +use ark_ec::{short_weierstrass::Affine, AffineRepr, CurveGroup}; +use ark_ff::{MontConfig, PrimeField}; +use grumpkin::{Fq, FqConfig, Fr, FrConfig, GrumpkinParameters}; + +use crate::generator::generators::{derive_generators, DEFAULT_DOMAIN_SEPARATOR}; + +/// Given a vector of fields, generate a pedersen commitment using the indexed generators. +pub(crate) fn commit_native_with_index( + inputs: &[Fq], + starting_index: u32, +) -> Affine { + let generators = + derive_generators(DEFAULT_DOMAIN_SEPARATOR, inputs.len() as u32, starting_index); + + // As |F_r| > |F_q|, we can safely convert any `F_q` into an `F_r` uniquely. + assert!(FrConfig::MODULUS > FqConfig::MODULUS); + + inputs.iter().enumerate().fold(Affine::zero(), |mut acc, (i, input)| { + acc = (acc + (generators[i] * Fr::from_bigint(input.into_bigint()).unwrap()).into_affine()) + .into_affine(); + acc + }) +} + +#[cfg(test)] +mod test { + + use acir::FieldElement; + use ark_ec::short_weierstrass::Affine; + use ark_std::{One, Zero}; + use grumpkin::Fq; + + use crate::pedersen::commitment::commit_native_with_index; + + #[test] + fn commitment() { + // https://github.com/AztecProtocol/aztec-packages/blob/72931bdb8202c34042cdfb8cee2ef44b75939879/barretenberg/cpp/src/barretenberg/crypto/pedersen_commitment/pedersen.test.cpp#L10-L18 + let res = commit_native_with_index(&[Fq::one(), Fq::one()], 0); + let expected = Affine::new( + FieldElement::from_hex( + "0x2f7a8f9a6c96926682205fb73ee43215bf13523c19d7afe36f12760266cdfe15", + ) + .unwrap() + .into_repr(), + FieldElement::from_hex( + "0x01916b316adbbf0e10e39b18c1d24b33ec84b46daddf72f43878bcc92b6057e6", + ) + .unwrap() + .into_repr(), + ); + + assert_eq!(res, expected); + } + + #[test] + fn commitment_with_zero() { + // https://github.com/AztecProtocol/aztec-packages/blob/72931bdb8202c34042cdfb8cee2ef44b75939879/barretenberg/cpp/src/barretenberg/crypto/pedersen_commitment/pedersen.test.cpp#L20-L29 + let res = commit_native_with_index(&[Fq::zero(), Fq::one()], 0); + let expected = Affine::new( + FieldElement::from_hex( + "0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402", + ) + .unwrap() + .into_repr(), + FieldElement::from_hex( + "0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126", + ) + .unwrap() + .into_repr(), + ); + + assert_eq!(res, expected); + } +} diff --git a/acvm-repo/bn254_blackbox_solver/src/pedersen/hash.rs b/acvm-repo/bn254_blackbox_solver/src/pedersen/hash.rs new file mode 100644 index 00000000000..28bf354edc9 --- /dev/null +++ b/acvm-repo/bn254_blackbox_solver/src/pedersen/hash.rs @@ -0,0 +1,68 @@ +// Taken from: https://github.com/laudiacay/barustenberg/blob/df6bc6f095fe7f288bf6a12e7317fd8eb33d68ae/barustenberg/src/crypto/pedersen/pederson_hash.rs + +use std::sync::OnceLock; + +use ark_ec::{short_weierstrass::Affine, CurveConfig, CurveGroup}; +use grumpkin::GrumpkinParameters; + +use crate::generator::generators::derive_generators; + +use super::commitment::commit_native_with_index; + +/// Given a vector of fields, generate a pedersen hash using the indexed generators. +pub(crate) fn hash_with_index( + inputs: &[grumpkin::Fq], + starting_index: u32, +) -> ::BaseField { + let length_as_scalar: ::ScalarField = + (inputs.len() as u64).into(); + let length_prefix = *length_generator() * length_as_scalar; + let result = length_prefix + commit_native_with_index(inputs, starting_index); + result.into_affine().x +} + +fn length_generator() -> &'static Affine { + static INSTANCE: OnceLock> = OnceLock::new(); + INSTANCE.get_or_init(|| derive_generators("pedersen_hash_length".as_bytes(), 1, 0)[0]) +} + +#[cfg(test)] +pub(crate) mod test { + + use super::*; + + use acir::FieldElement; + use ark_std::One; + use grumpkin::Fq; + + //reference: https://github.com/AztecProtocol/barretenberg/blob/master/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.test.cpp + #[test] + fn hash_one() { + // https://github.com/AztecProtocol/aztec-packages/blob/72931bdb8202c34042cdfb8cee2ef44b75939879/barretenberg/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.test.cpp#L21-L26 + let res = hash_with_index(&[Fq::one(), Fq::one()], 0); + + assert_eq!( + res, + FieldElement::from_hex( + "0x07ebfbf4df29888c6cd6dca13d4bb9d1a923013ddbbcbdc3378ab8845463297b", + ) + .unwrap() + .into_repr(), + ); + } + + #[test] + fn test_hash_with_index() { + // https://github.com/AztecProtocol/aztec-packages/blob/72931bdb8202c34042cdfb8cee2ef44b75939879/barretenberg/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.test.cpp#L28-L33 + let res = hash_with_index(&[Fq::one(), Fq::one()], 5); + + assert_eq!( + res, + FieldElement::from_hex( + "0x1c446df60816b897cda124524e6b03f36df0cec333fad87617aab70d7861daa6", + ) + .unwrap() + .into_repr(), + ); + } +} diff --git a/acvm-repo/bn254_blackbox_solver/src/pedersen/mod.rs b/acvm-repo/bn254_blackbox_solver/src/pedersen/mod.rs new file mode 100644 index 00000000000..c3c4ed56450 --- /dev/null +++ b/acvm-repo/bn254_blackbox_solver/src/pedersen/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod commitment; +pub(crate) mod hash; diff --git a/acvm-repo/bn254_blackbox_solver/src/wasm/barretenberg_structures.rs b/acvm-repo/bn254_blackbox_solver/src/wasm/barretenberg_structures.rs deleted file mode 100644 index 302ffa8af9b..00000000000 --- a/acvm-repo/bn254_blackbox_solver/src/wasm/barretenberg_structures.rs +++ /dev/null @@ -1,25 +0,0 @@ -use acir::FieldElement; - -#[derive(Debug, Default)] -pub(crate) struct Assignments(Vec); - -impl Assignments { - pub(crate) fn to_bytes(&self) -> Vec { - let mut buffer = Vec::new(); - - let witness_len = self.0.len() as u32; - buffer.extend_from_slice(&witness_len.to_be_bytes()); - - for assignment in self.0.iter() { - buffer.extend_from_slice(&assignment.to_be_bytes()); - } - - buffer - } -} - -impl From> for Assignments { - fn from(w: Vec) -> Assignments { - Assignments(w) - } -} diff --git a/acvm-repo/bn254_blackbox_solver/src/wasm/mod.rs b/acvm-repo/bn254_blackbox_solver/src/wasm/mod.rs index f4f6f56aa99..e0a5c4c9069 100644 --- a/acvm-repo/bn254_blackbox_solver/src/wasm/mod.rs +++ b/acvm-repo/bn254_blackbox_solver/src/wasm/mod.rs @@ -4,13 +4,8 @@ //! //! As [`acvm`] includes rust implementations for these opcodes, this module can be removed. -mod barretenberg_structures; -mod pedersen; mod schnorr; -use barretenberg_structures::Assignments; - -pub(crate) use pedersen::Pedersen; pub(crate) use schnorr::SchnorrSig; /// The number of bytes necessary to store a `FieldElement`. @@ -208,10 +203,6 @@ impl Barretenberg { buf } - pub(crate) fn call(&self, name: &str, param: &WASMValue) -> Result { - self.call_multiple(name, vec![param]) - } - pub(crate) fn call_multiple( &self, name: &str, @@ -236,17 +227,6 @@ impl Barretenberg { Ok(WASMValue(option_value)) } - - /// Creates a pointer and allocates the bytes that the pointer references to, to the heap - pub(crate) fn allocate(&self, bytes: &[u8]) -> Result { - let ptr: i32 = self.call("bbmalloc", &bytes.len().into())?.try_into()?; - - let i32_bytes = ptr.to_be_bytes(); - let u32_bytes = u32::from_be_bytes(i32_bytes); - - self.transfer_to_heap(bytes, u32_bytes as usize); - Ok(ptr.into()) - } } fn init_memory_and_state() -> (Memory, Store, Imports) { diff --git a/acvm-repo/bn254_blackbox_solver/src/wasm/pedersen.rs b/acvm-repo/bn254_blackbox_solver/src/wasm/pedersen.rs deleted file mode 100644 index c816e5b4d1b..00000000000 --- a/acvm-repo/bn254_blackbox_solver/src/wasm/pedersen.rs +++ /dev/null @@ -1,73 +0,0 @@ -use acir::FieldElement; - -use super::{Assignments, Barretenberg, Error, FIELD_BYTES}; - -pub(crate) trait Pedersen { - fn encrypt( - &self, - inputs: Vec, - hash_index: u32, - ) -> Result<(FieldElement, FieldElement), Error>; - - fn hash(&self, inputs: Vec, hash_index: u32) -> Result; -} - -impl Pedersen for Barretenberg { - fn encrypt( - &self, - inputs: Vec, - hash_index: u32, - ) -> Result<(FieldElement, FieldElement), Error> { - let input_buf = Assignments::from(inputs).to_bytes(); - let input_ptr = self.allocate(&input_buf)?; - let result_ptr: usize = 0; - - self.call_multiple( - "pedersen_plookup_commit_with_hash_index", - vec![&input_ptr, &result_ptr.into(), &hash_index.into()], - )?; - - let result_bytes: [u8; 2 * FIELD_BYTES] = self.read_memory(result_ptr); - let (point_x_bytes, point_y_bytes) = result_bytes.split_at(FIELD_BYTES); - - let point_x = FieldElement::from_be_bytes_reduce(point_x_bytes); - let point_y = FieldElement::from_be_bytes_reduce(point_y_bytes); - - Ok((point_x, point_y)) - } - - fn hash(&self, inputs: Vec, hash_index: u32) -> Result { - let input_buf = Assignments::from(inputs).to_bytes(); - let input_ptr = self.allocate(&input_buf)?; - let result_ptr: usize = 0; - - self.call_multiple( - "pedersen_plookup_compress_with_hash_index", - vec![&input_ptr, &result_ptr.into(), &hash_index.into()], - )?; - - let result_bytes: [u8; FIELD_BYTES] = self.read_memory(result_ptr); - - let hash = FieldElement::from_be_bytes_reduce(&result_bytes); - - Ok(hash) - } -} - -#[test] -fn pedersen_hash_to_point() -> Result<(), Error> { - let barretenberg = Barretenberg::new(); - let (x, y) = barretenberg.encrypt(vec![FieldElement::one(), FieldElement::one()], 1)?; - let expected_x = FieldElement::from_hex( - "0x12afb43195f5c621d1d2cabb5f629707095c5307fd4185a663d4e80bb083e878", - ) - .unwrap(); - let expected_y = FieldElement::from_hex( - "0x25793f5b5e62beb92fd18a66050293a9fd554a2ff13bceba0339cae1a038d7c1", - ) - .unwrap(); - - assert_eq!(expected_x.to_hex(), x.to_hex()); - assert_eq!(expected_y.to_hex(), y.to_hex()); - Ok(()) -} diff --git a/cspell.json b/cspell.json index bf3040265c2..1fbbe5c428d 100644 --- a/cspell.json +++ b/cspell.json @@ -18,6 +18,7 @@ "Backpropagation", "barebones", "barretenberg", + "barustenberg", "bincode", "bindgen", "bitand", From af57471035e4fa7eaffa71693219df6d029dbcde Mon Sep 17 00:00:00 2001 From: kevaundray Date: Tue, 21 May 2024 17:17:52 +0300 Subject: [PATCH 08/61] chore: Release Noir(0.30.0) (#4981) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit :robot: I have created a release *beep* *boop* ---
0.30.0 ## [0.30.0](https://github.com/noir-lang/noir/compare/v0.29.0...v0.30.0) (2024-05-20) ### ⚠ BREAKING CHANGES * remove `Opcode::Brillig` from ACIR (https://github.com/AztecProtocol/aztec-packages/pull/5995) * AES blackbox (https://github.com/AztecProtocol/aztec-packages/pull/6016) ### Features * `multi_scalar_mul` blackbox func (https://github.com/AztecProtocol/aztec-packages/pull/6097) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) * `variable_base_scalar_mul` blackbox func (https://github.com/AztecProtocol/aztec-packages/pull/6039) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) * Add `Not` trait to stdlib ([#4999](https://github.com/noir-lang/noir/issues/4999)) ([95d4d13](https://github.com/noir-lang/noir/commit/95d4d133d1eb5e0eb44cd928d8183d890e970a13)) * Add `std::ops::Neg` trait to stdlib ([07930d4](https://github.com/noir-lang/noir/commit/07930d4373a393146210efae69e6ec40171f047b)) * Add native rust implementations of pedersen functions ([#4871](https://github.com/noir-lang/noir/issues/4871)) ([fb039f7](https://github.com/noir-lang/noir/commit/fb039f74df23aea39bc0593a5d538d82b4efadf0)) * Add support for u16/i16 ([#4985](https://github.com/noir-lang/noir/issues/4985)) ([e43661d](https://github.com/noir-lang/noir/commit/e43661d16c1cd07e2af2392b88d29c689889ff9a)) * AES blackbox (https://github.com/AztecProtocol/aztec-packages/pull/6016) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) * Do not return databus returndata, keep it private. ([#5023](https://github.com/noir-lang/noir/issues/5023)) ([a5b7df1](https://github.com/noir-lang/noir/commit/a5b7df12faf9d71ff24f8c5cde5e78da44558caf)) * Dynamic assertion payloads v2 (https://github.com/AztecProtocol/aztec-packages/pull/5949) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) * Implement `From` array trait for `BoundedVec` ([#4927](https://github.com/noir-lang/noir/issues/4927)) ([bf491dc](https://github.com/noir-lang/noir/commit/bf491dce9595d0e37057ae6d6721eb7a83cec0e2)) * Implement `ops` traits on `u16`/`i16` ([#4996](https://github.com/noir-lang/noir/issues/4996)) ([8b65663](https://github.com/noir-lang/noir/commit/8b65663f9e836c11a87e458bd7c6a52920448d5c)) * Implement `std::ops::Sub` on `EmbeddedCurvePoint` ([07930d4](https://github.com/noir-lang/noir/commit/07930d4373a393146210efae69e6ec40171f047b)) * Increase default expression width to 4 ([#4995](https://github.com/noir-lang/noir/issues/4995)) ([f01d309](https://github.com/noir-lang/noir/commit/f01d3090759a5ff0f1f83c5616d22890c6bd76be)) * Parsing non-string assertion payloads in noir js (https://github.com/AztecProtocol/aztec-packages/pull/6079) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) * Remove query to backend to get expression width ([#4975](https://github.com/noir-lang/noir/issues/4975)) ([e5f356b](https://github.com/noir-lang/noir/commit/e5f356b063fe4facbd14320b7eafed664d0bb027)) * Set aztec private functions to be recursive (https://github.com/AztecProtocol/aztec-packages/pull/6192) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) ### Bug Fixes * Compute the correct slice length when coercing from a literal array of complex types ([#4986](https://github.com/noir-lang/noir/issues/4986)) ([f3f1150](https://github.com/noir-lang/noir/commit/f3f11507983009771656811f9570bdbe6849c7ef)) * Defer overflow checks for unsigned integers to acir-gen ([#4832](https://github.com/noir-lang/noir/issues/4832)) ([b577761](https://github.com/noir-lang/noir/commit/b5777613c51f26fb4f580b9168c4190b1f4bd8f7)) * Fix no predicates for brillig with intermediate functions ([#5015](https://github.com/noir-lang/noir/issues/5015)) ([9c6de4b](https://github.com/noir-lang/noir/commit/9c6de4b25d318c6d211361dd62a112a9d2432c56)) * Fixed several vulnerabilities in U128, added some tests ([#5024](https://github.com/noir-lang/noir/issues/5024)) ([e5ab24d](https://github.com/noir-lang/noir/commit/e5ab24d6a4154d11b3c8ae08f4431b7b93c76f23)) * Ignore no_predicates in brillig functions ([#5012](https://github.com/noir-lang/noir/issues/5012)) ([b541e79](https://github.com/noir-lang/noir/commit/b541e793e20fa3c991e0328ec2ff7926bdcdfd45)) * Set index and value to 0 for array_get with predicate ([#4971](https://github.com/noir-lang/noir/issues/4971)) ([c49d3a9](https://github.com/noir-lang/noir/commit/c49d3a9ded819b828cffdfc031e86614da21e329)) ### Miscellaneous Chores * Remove `Opcode::Brillig` from ACIR (https://github.com/AztecProtocol/aztec-packages/pull/5995) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a))
0.46.0 ## [0.46.0](https://github.com/noir-lang/noir/compare/v0.45.0...v0.46.0) (2024-05-20) ### ⚠ BREAKING CHANGES * remove `Opcode::Brillig` from ACIR (https://github.com/AztecProtocol/aztec-packages/pull/5995) * AES blackbox (https://github.com/AztecProtocol/aztec-packages/pull/6016) * Bit shift is restricted to u8 right operand ([#4907](https://github.com/noir-lang/noir/issues/4907)) * contract interfaces and better function calls (https://github.com/AztecProtocol/aztec-packages/pull/5687) * change backend width to 4 (https://github.com/AztecProtocol/aztec-packages/pull/5374) * Use fixed size arrays in black box functions where sizes are known (https://github.com/AztecProtocol/aztec-packages/pull/5620) * trap with revert data (https://github.com/AztecProtocol/aztec-packages/pull/5732) * **acir:** BrilligCall opcode (https://github.com/AztecProtocol/aztec-packages/pull/5709) * remove fixed-length keccak256 (https://github.com/AztecProtocol/aztec-packages/pull/5617) * storage_layout and `#[aztec(storage)]` (https://github.com/AztecProtocol/aztec-packages/pull/5387) * **acir:** Add predicate to call opcode (https://github.com/AztecProtocol/aztec-packages/pull/5616) * contract_abi-exports (https://github.com/AztecProtocol/aztec-packages/pull/5386) * Brillig typed memory (https://github.com/AztecProtocol/aztec-packages/pull/5395) * **acir:** Program and witness stack structure (https://github.com/AztecProtocol/aztec-packages/pull/5149) * automatic NoteInterface and NoteGetterOptions auto select (https://github.com/AztecProtocol/aztec-packages/pull/4508) * Acir call opcode (https://github.com/AztecProtocol/aztec-packages/pull/4773) * Support contracts with no constructor (https://github.com/AztecProtocol/aztec-packages/pull/5175) * Internal as a macro (https://github.com/AztecProtocol/aztec-packages/pull/4898) * move noir out of yarn-project (https://github.com/AztecProtocol/aztec-packages/pull/4479) * note type ids (https://github.com/AztecProtocol/aztec-packages/pull/4500) * rename bigint_neg into bigint_sub (https://github.com/AztecProtocol/aztec-packages/pull/4420) * Add expression width into acir (https://github.com/AztecProtocol/aztec-packages/pull/4014) * init storage macro (https://github.com/AztecProtocol/aztec-packages/pull/4200) * **acir:** Move `is_recursive` flag to be part of the circuit definition (https://github.com/AztecProtocol/aztec-packages/pull/4221) * Sync commits from `aztec-packages` ([#4144](https://github.com/noir-lang/noir/issues/4144)) ### Features * `multi_scalar_mul` blackbox func (https://github.com/AztecProtocol/aztec-packages/pull/6097) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) * `variable_base_scalar_mul` blackbox func (https://github.com/AztecProtocol/aztec-packages/pull/6039) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) * Acir call opcode (https://github.com/AztecProtocol/aztec-packages/pull/4773) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) * **acir_gen:** Brillig stdlib ([#4848](https://github.com/noir-lang/noir/issues/4848)) ([0c8175c](https://github.com/noir-lang/noir/commit/0c8175cb539efd9427c73ae5af0d48abe688ebab)) * **acir_gen:** Fold attribute at compile-time and initial non inlined ACIR (https://github.com/AztecProtocol/aztec-packages/pull/5341) ([a0f7474](https://github.com/noir-lang/noir/commit/a0f7474ae6bd74132efdb945d2eb2383f3913cce)) * **acir:** Add predicate to call opcode (https://github.com/AztecProtocol/aztec-packages/pull/5616) ([2bd006a](https://github.com/noir-lang/noir/commit/2bd006ae07499e8702b0fa9565855f0a5ef1a589)) * **acir:** BrilligCall opcode (https://github.com/AztecProtocol/aztec-packages/pull/5709) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) * **acir:** Program and witness stack structure (https://github.com/AztecProtocol/aztec-packages/pull/5149) ([13eb71b](https://github.com/noir-lang/noir/commit/13eb71b8de44eb6aad9c37943ad06fc73db589f5)) * **acvm_js:** Execute program ([#4694](https://github.com/noir-lang/noir/issues/4694)) ([386f6d0](https://github.com/noir-lang/noir/commit/386f6d0a5822912db878285cb001032a7c0ff622)) * **acvm:** Execute multiple circuits (https://github.com/AztecProtocol/aztec-packages/pull/5380) ([a0f7474](https://github.com/noir-lang/noir/commit/a0f7474ae6bd74132efdb945d2eb2383f3913cce)) * Add bit size to const opcode (https://github.com/AztecProtocol/aztec-packages/pull/4385) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc)) * Add CMOV instruction to brillig and brillig gen (https://github.com/AztecProtocol/aztec-packages/pull/5308) ([13eb71b](https://github.com/noir-lang/noir/commit/13eb71b8de44eb6aad9c37943ad06fc73db589f5)) * Add expression width into acir (https://github.com/AztecProtocol/aztec-packages/pull/4014) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc)) * Add instrumentation for tracking variables in debugging ([#4122](https://github.com/noir-lang/noir/issues/4122)) ([c58d691](https://github.com/noir-lang/noir/commit/c58d69141b54a918cd1675400c00bfd48720f896)) * Add native rust implementations of pedersen functions ([#4871](https://github.com/noir-lang/noir/issues/4871)) ([fb039f7](https://github.com/noir-lang/noir/commit/fb039f74df23aea39bc0593a5d538d82b4efadf0)) * Add poseidon2 opcode implementation for acvm/brillig, and Noir ([#4398](https://github.com/noir-lang/noir/issues/4398)) ([10e8292](https://github.com/noir-lang/noir/commit/10e82920798380f50046e52db4a20ca205191ab7)) * Add return values to aztec fns (https://github.com/AztecProtocol/aztec-packages/pull/5389) ([2bd006a](https://github.com/noir-lang/noir/commit/2bd006ae07499e8702b0fa9565855f0a5ef1a589)) * Add support for overriding expression width ([#4117](https://github.com/noir-lang/noir/issues/4117)) ([c8026d5](https://github.com/noir-lang/noir/commit/c8026d557d535b10fe455165d6445076df7a03de)) * Added cast opcode and cast calldata (https://github.com/AztecProtocol/aztec-packages/pull/4423) ([78ef013](https://github.com/noir-lang/noir/commit/78ef0134b82e76a73dadb6c7975def22290e3a1a)) * AES blackbox (https://github.com/AztecProtocol/aztec-packages/pull/6016) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) * Allow brillig to read arrays directly from memory (https://github.com/AztecProtocol/aztec-packages/pull/4460) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc)) * Allow nested arrays and vectors in Brillig foreign calls (https://github.com/AztecProtocol/aztec-packages/pull/4478) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc)) * Allow variables and stack trace inspection in the debugger ([#4184](https://github.com/noir-lang/noir/issues/4184)) ([bf263fc](https://github.com/noir-lang/noir/commit/bf263fc8d843940f328a90f6366edd2671fb2682)) * Automatic NoteInterface and NoteGetterOptions auto select (https://github.com/AztecProtocol/aztec-packages/pull/4508) ([13eb71b](https://github.com/noir-lang/noir/commit/13eb71b8de44eb6aad9c37943ad06fc73db589f5)) * **avm:** Back in avm context with macro - refactor context (https://github.com/AztecProtocol/aztec-packages/pull/4438) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc)) * **avm:** Brillig CONST of size > u128 (https://github.com/AztecProtocol/aztec-packages/pull/5217) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) * **avm:** Integrate AVM with initializers (https://github.com/AztecProtocol/aztec-packages/pull/5469) ([2bd006a](https://github.com/noir-lang/noir/commit/2bd006ae07499e8702b0fa9565855f0a5ef1a589)) * **aztec-nr:** Initial work for aztec public vm macro (https://github.com/AztecProtocol/aztec-packages/pull/4400) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc)) * Backpropagate constants in ACIR during optimization ([#3926](https://github.com/noir-lang/noir/issues/3926)) ([aad0da0](https://github.com/noir-lang/noir/commit/aad0da024c69663f42e6913e674682d5864b26ae)) * Bit shift is restricted to u8 right operand ([#4907](https://github.com/noir-lang/noir/issues/4907)) ([c4b0369](https://github.com/noir-lang/noir/commit/c4b03691feca17ef268acab523292f3051f672ea)) * Brillig heterogeneous memory cells (https://github.com/AztecProtocol/aztec-packages/pull/5608) ([305bcdc](https://github.com/noir-lang/noir/commit/305bcdcbd01cb84dbaac900f14cb6cf867f83bda)) * Brillig IR refactor (https://github.com/AztecProtocol/aztec-packages/pull/5233) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) * Brillig pointer codegen and execution (https://github.com/AztecProtocol/aztec-packages/pull/5737) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) * Brillig typed memory (https://github.com/AztecProtocol/aztec-packages/pull/5395) ([0bc18c4](https://github.com/noir-lang/noir/commit/0bc18c4f78171590dd58bded959f68f53a44cc8c)) * Change backend width to 4 (https://github.com/AztecProtocol/aztec-packages/pull/5374) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) * Check initializer msg.sender matches deployer from address preimage (https://github.com/AztecProtocol/aztec-packages/pull/5222) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) * Contract interfaces and better function calls (https://github.com/AztecProtocol/aztec-packages/pull/5687) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) * Contract_abi-exports (https://github.com/AztecProtocol/aztec-packages/pull/5386) ([2bd006a](https://github.com/noir-lang/noir/commit/2bd006ae07499e8702b0fa9565855f0a5ef1a589)) * Dynamic assertion payloads v2 (https://github.com/AztecProtocol/aztec-packages/pull/5949) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) * Evaluation of dynamic assert messages ([#4101](https://github.com/noir-lang/noir/issues/4101)) ([c284e01](https://github.com/noir-lang/noir/commit/c284e01bfe20ceae4414dc123624b5cbb8b66d09)) * Handle `BrilligCall` opcodes in the debugger ([#4897](https://github.com/noir-lang/noir/issues/4897)) ([b380dc4](https://github.com/noir-lang/noir/commit/b380dc44de5c9f8de278ece3d531ebbc2c9238ba)) * Impl of missing functionality in new key store (https://github.com/AztecProtocol/aztec-packages/pull/5750) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) * Increase default expression width to 4 ([#4995](https://github.com/noir-lang/noir/issues/4995)) ([f01d309](https://github.com/noir-lang/noir/commit/f01d3090759a5ff0f1f83c5616d22890c6bd76be)) * Init storage macro (https://github.com/AztecProtocol/aztec-packages/pull/4200) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc)) * Initial Earthly CI (https://github.com/AztecProtocol/aztec-packages/pull/5069) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) * Internal as a macro (https://github.com/AztecProtocol/aztec-packages/pull/4898) ([5f57ebb](https://github.com/noir-lang/noir/commit/5f57ebb7ff4b810802f90699a10f4325ef904f2e)) * **nargo:** Handle call stacks for multiple Acir calls ([#4711](https://github.com/noir-lang/noir/issues/4711)) ([5b23171](https://github.com/noir-lang/noir/commit/5b231714740447d82cde7cdbe65d4a8b46a31df4)) * New brillig field operations and refactor of binary operations (https://github.com/AztecProtocol/aztec-packages/pull/5208) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) * Note type ids (https://github.com/AztecProtocol/aztec-packages/pull/4500) ([78ef013](https://github.com/noir-lang/noir/commit/78ef0134b82e76a73dadb6c7975def22290e3a1a)) * Parsing non-string assertion payloads in noir js (https://github.com/AztecProtocol/aztec-packages/pull/6079) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) * Remove replacement of boolean range opcodes with `AssertZero` opcodes ([#4107](https://github.com/noir-lang/noir/issues/4107)) ([dac0e87](https://github.com/noir-lang/noir/commit/dac0e87ee3be3446b92bbb12ef4832fd493fcee3)) * Restore hashing args via slice for performance (https://github.com/AztecProtocol/aztec-packages/pull/5539) ([2bd006a](https://github.com/noir-lang/noir/commit/2bd006ae07499e8702b0fa9565855f0a5ef1a589)) * Set aztec private functions to be recursive (https://github.com/AztecProtocol/aztec-packages/pull/6192) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) * Signed integer division and modulus in brillig gen (https://github.com/AztecProtocol/aztec-packages/pull/5279) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) * **simulator:** Fetch return values at circuit execution (https://github.com/AztecProtocol/aztec-packages/pull/5642) ([305bcdc](https://github.com/noir-lang/noir/commit/305bcdcbd01cb84dbaac900f14cb6cf867f83bda)) * Storage_layout and `#[aztec(storage)]` (https://github.com/AztecProtocol/aztec-packages/pull/5387) ([2bd006a](https://github.com/noir-lang/noir/commit/2bd006ae07499e8702b0fa9565855f0a5ef1a589)) * Support contracts with no constructor (https://github.com/AztecProtocol/aztec-packages/pull/5175) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) * Sync `aztec-packages` ([#4011](https://github.com/noir-lang/noir/issues/4011)) ([fee2452](https://github.com/noir-lang/noir/commit/fee24523c427c27f0bdaf98ea09a852a2da3e94c)) * Sync commits from `aztec-packages` ([#4068](https://github.com/noir-lang/noir/issues/4068)) ([7a8f3a3](https://github.com/noir-lang/noir/commit/7a8f3a33b57875e681e3d81e667e3570a1cdbdcc)) * Sync commits from `aztec-packages` ([#4144](https://github.com/noir-lang/noir/issues/4144)) ([0205d3b](https://github.com/noir-lang/noir/commit/0205d3b4ad0cf5ffd775a43eb5af273a772cf138)) * Sync from aztec-packages ([#4483](https://github.com/noir-lang/noir/issues/4483)) ([fe8f277](https://github.com/noir-lang/noir/commit/fe8f2776ccfde29209a2c3fc162311c99e4f59be)) * Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5234) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) * Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5286) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) * Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5572) ([2bd006a](https://github.com/noir-lang/noir/commit/2bd006ae07499e8702b0fa9565855f0a5ef1a589)) * Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5619) ([2bd006a](https://github.com/noir-lang/noir/commit/2bd006ae07499e8702b0fa9565855f0a5ef1a589)) * Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5697) ([305bcdc](https://github.com/noir-lang/noir/commit/305bcdcbd01cb84dbaac900f14cb6cf867f83bda)) * Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5794) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) * Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5814) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) * Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5935) ([1b867b1](https://github.com/noir-lang/noir/commit/1b867b121fba5db3087ca845b4934e6732b23fd1)) * Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5955) ([1b867b1](https://github.com/noir-lang/noir/commit/1b867b121fba5db3087ca845b4934e6732b23fd1)) * Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5999) ([1b867b1](https://github.com/noir-lang/noir/commit/1b867b121fba5db3087ca845b4934e6732b23fd1)) * Trap with revert data (https://github.com/AztecProtocol/aztec-packages/pull/5732) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) * Use fixed size arrays in black box functions where sizes are known (https://github.com/AztecProtocol/aztec-packages/pull/5620) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) * Variable length returns (https://github.com/AztecProtocol/aztec-packages/pull/5633) ([305bcdc](https://github.com/noir-lang/noir/commit/305bcdcbd01cb84dbaac900f14cb6cf867f83bda)) ### Bug Fixes * **acvm:** Mark outputs of Opcode::Call solvable ([#4708](https://github.com/noir-lang/noir/issues/4708)) ([8fea405](https://github.com/noir-lang/noir/commit/8fea40576f262bd5bb588923c0660d8967404e56)) * Avoid huge unrolling in hash_args (https://github.com/AztecProtocol/aztec-packages/pull/5703) ([305bcdc](https://github.com/noir-lang/noir/commit/305bcdcbd01cb84dbaac900f14cb6cf867f83bda)) * Catch panics from EC point creation (e.g. the point is at infinity) ([#4790](https://github.com/noir-lang/noir/issues/4790)) ([645dba1](https://github.com/noir-lang/noir/commit/645dba192f16ef34018828186ffb297422a8dc73)) * Don't reuse brillig with slice arguments (https://github.com/AztecProtocol/aztec-packages/pull/5800) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) * Issue 4682 and add solver for unconstrained bigintegers ([#4729](https://github.com/noir-lang/noir/issues/4729)) ([e4d33c1](https://github.com/noir-lang/noir/commit/e4d33c126a2795d9aaa6048d4e91b64cb4bbe4f2)) * Noir test incorrect reporting (https://github.com/AztecProtocol/aztec-packages/pull/4925) ([5f57ebb](https://github.com/noir-lang/noir/commit/5f57ebb7ff4b810802f90699a10f4325ef904f2e)) * Proper field inversion for bigints ([#4802](https://github.com/noir-lang/noir/issues/4802)) ([b46d0e3](https://github.com/noir-lang/noir/commit/b46d0e39f4252f8bbaa987f88d112e4c233b3d61)) * Remove panic from `init_log_level` in `acvm_js` ([#4195](https://github.com/noir-lang/noir/issues/4195)) ([2e26530](https://github.com/noir-lang/noir/commit/2e26530bf53006c1ed4fee310bcaa905c95dd95b)) ### Miscellaneous Chores * **acir:** Move `is_recursive` flag to be part of the circuit definition (https://github.com/AztecProtocol/aztec-packages/pull/4221) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc)) * Move noir out of yarn-project (https://github.com/AztecProtocol/aztec-packages/pull/4479) ([78ef013](https://github.com/noir-lang/noir/commit/78ef0134b82e76a73dadb6c7975def22290e3a1a)) * Remove `Opcode::Brillig` from ACIR (https://github.com/AztecProtocol/aztec-packages/pull/5995) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) * Remove fixed-length keccak256 (https://github.com/AztecProtocol/aztec-packages/pull/5617) ([305bcdc](https://github.com/noir-lang/noir/commit/305bcdcbd01cb84dbaac900f14cb6cf867f83bda)) * Rename bigint_neg into bigint_sub (https://github.com/AztecProtocol/aztec-packages/pull/4420) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc))
--- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --- .release-please-manifest.json | 4 +- CHANGELOG.md | 42 ++ Cargo.lock | 54 +- Cargo.toml | 16 +- acvm-repo/CHANGELOG.md | 129 ++++ acvm-repo/acir/Cargo.toml | 2 +- acvm-repo/acir_field/Cargo.toml | 2 +- acvm-repo/acvm/Cargo.toml | 2 +- acvm-repo/acvm_js/Cargo.toml | 2 +- acvm-repo/acvm_js/package.json | 2 +- acvm-repo/blackbox_solver/Cargo.toml | 2 +- acvm-repo/bn254_blackbox_solver/Cargo.toml | 2 +- acvm-repo/brillig/Cargo.toml | 2 +- acvm-repo/brillig_vm/Cargo.toml | 2 +- compiler/wasm/package.json | 2 +- .../explainers/explainer-oracle.md | 57 ++ .../explainers/explainer-recursion.md | 176 ++++++ .../getting_started/_category_.json | 5 + .../hello_noir/_category_.json | 5 + .../getting_started/hello_noir/index.md | 142 +++++ .../hello_noir/project_breakdown.md | 199 ++++++ .../installation/_category_.json | 6 + .../getting_started/installation/index.md | 48 ++ .../installation/other_install_methods.md | 102 ++++ .../getting_started/tooling/noir_codegen.md | 113 ++++ .../version-v0.30.0/how_to/_category_.json | 5 + .../how_to/debugger/_category_.json | 6 + .../debugger/debugging_with_the_repl.md | 164 +++++ .../how_to/debugger/debugging_with_vs_code.md | 68 +++ .../version-v0.30.0/how_to/how-to-oracles.md | 276 +++++++++ .../how_to/how-to-recursion.md | 179 ++++++ .../how_to/how-to-solidity-verifier.md | 231 +++++++ .../version-v0.30.0/how_to/merkle-proof.mdx | 49 ++ .../how_to/using-devcontainers.mdx | 110 ++++ docs/versioned_docs/version-v0.30.0/index.mdx | 67 ++ .../version-v0.30.0/migration_notes.md | 105 ++++ .../noir/concepts/_category_.json | 6 + .../version-v0.30.0/noir/concepts/assert.md | 45 ++ .../version-v0.30.0/noir/concepts/comments.md | 33 + .../noir/concepts/control_flow.md | 77 +++ .../version-v0.30.0/noir/concepts/data_bus.md | 21 + .../noir/concepts/data_types/_category_.json | 5 + .../noir/concepts/data_types/arrays.md | 251 ++++++++ .../noir/concepts/data_types/booleans.md | 31 + .../noir/concepts/data_types/fields.md | 192 ++++++ .../concepts/data_types/function_types.md | 26 + .../noir/concepts/data_types/index.md | 110 ++++ .../noir/concepts/data_types/integers.md | 157 +++++ .../noir/concepts/data_types/references.md | 23 + .../noir/concepts/data_types/slices.mdx | 195 ++++++ .../noir/concepts/data_types/strings.md | 80 +++ .../noir/concepts/data_types/structs.md | 70 +++ .../noir/concepts/data_types/tuples.md | 48 ++ .../noir/concepts/functions.md | 226 +++++++ .../version-v0.30.0/noir/concepts/generics.md | 106 ++++ .../version-v0.30.0/noir/concepts/globals.md | 72 +++ .../version-v0.30.0/noir/concepts/lambdas.md | 81 +++ .../noir/concepts/mutability.md | 121 ++++ .../version-v0.30.0/noir/concepts/ops.md | 98 +++ .../version-v0.30.0/noir/concepts/oracles.md | 31 + .../noir/concepts/shadowing.md | 44 ++ .../version-v0.30.0/noir/concepts/traits.md | 389 ++++++++++++ .../noir/concepts/unconstrained.md | 99 +++ .../modules_packages_crates/_category_.json | 6 + .../crates_and_packages.md | 43 ++ .../modules_packages_crates/dependencies.md | 124 ++++ .../noir/modules_packages_crates/modules.md | 105 ++++ .../modules_packages_crates/workspaces.md | 42 ++ .../noir/standard_library/_category_.json | 6 + .../noir/standard_library/bigint.md | 122 ++++ .../noir/standard_library/black_box_fns.md | 32 + .../noir/standard_library/bn254.md | 46 ++ .../standard_library/containers/boundedvec.md | 340 +++++++++++ .../standard_library/containers/hashmap.md | 570 ++++++++++++++++++ .../noir/standard_library/containers/index.md | 5 + .../noir/standard_library/containers/vec.mdx | 151 +++++ .../cryptographic_primitives/_category_.json | 5 + .../cryptographic_primitives/ciphers.mdx | 32 + .../cryptographic_primitives/ec_primitives.md | 102 ++++ .../ecdsa_sig_verification.mdx | 98 +++ .../cryptographic_primitives/eddsa.mdx | 37 ++ .../embedded_curve_ops.mdx | 98 +++ .../cryptographic_primitives/hashes.mdx | 257 ++++++++ .../cryptographic_primitives/index.md | 14 + .../cryptographic_primitives/schnorr.mdx | 64 ++ .../noir/standard_library/logging.md | 78 +++ .../noir/standard_library/merkle_trees.md | 58 ++ .../noir/standard_library/options.md | 101 ++++ .../noir/standard_library/recursion.md | 88 +++ .../noir/standard_library/traits.md | 464 ++++++++++++++ .../noir/standard_library/zeroed.md | 26 + .../NoirJS/backend_barretenberg/.nojekyll | 1 + .../classes/BarretenbergBackend.md | 160 +++++ .../classes/BarretenbergVerifier.md | 58 ++ .../NoirJS/backend_barretenberg/index.md | 59 ++ .../type-aliases/BackendOptions.md | 21 + .../backend_barretenberg/typedoc-sidebar.cjs | 4 + .../reference/NoirJS/noir_js/.nojekyll | 1 + .../reference/NoirJS/noir_js/classes/Noir.md | 132 ++++ .../reference/NoirJS/noir_js/functions/and.md | 22 + .../NoirJS/noir_js/functions/blake2s256.md | 21 + .../functions/ecdsa_secp256k1_verify.md | 28 + .../functions/ecdsa_secp256r1_verify.md | 28 + .../NoirJS/noir_js/functions/keccak256.md | 21 + .../NoirJS/noir_js/functions/sha256.md | 21 + .../reference/NoirJS/noir_js/functions/xor.md | 22 + .../reference/NoirJS/noir_js/index.md | 55 ++ .../noir_js/type-aliases/ErrorWithPayload.md | 15 + .../type-aliases/ForeignCallHandler.md | 24 + .../noir_js/type-aliases/ForeignCallInput.md | 9 + .../noir_js/type-aliases/ForeignCallOutput.md | 9 + .../NoirJS/noir_js/type-aliases/WitnessMap.md | 9 + .../NoirJS/noir_js/typedoc-sidebar.cjs | 4 + .../reference/NoirJS/noir_wasm/.nojekyll | 1 + .../NoirJS/noir_wasm/functions/compile.md | 51 ++ .../noir_wasm/functions/compile_contract.md | 51 ++ .../noir_wasm/functions/createFileManager.md | 21 + .../functions/inflateDebugSymbols.md | 21 + .../reference/NoirJS/noir_wasm/index.md | 49 ++ .../NoirJS/noir_wasm/typedoc-sidebar.cjs | 4 + .../version-v0.30.0/reference/_category_.json | 5 + .../reference/debugger/_category_.json | 6 + .../debugger/debugger_known_limitations.md | 59 ++ .../reference/debugger/debugger_repl.md | 360 +++++++++++ .../reference/debugger/debugger_vscode.md | 82 +++ .../reference/nargo_commands.md | 397 ++++++++++++ .../version-v0.30.0/tooling/debugger.md | 27 + .../tooling/language_server.md | 43 ++ .../version-v0.30.0/tooling/testing.md | 62 ++ .../version-v0.30.0/tutorials/noirjs_app.md | 326 ++++++++++ .../version-v0.30.0-sidebars.json | 93 +++ tooling/noir_codegen/package.json | 2 +- tooling/noir_js/package.json | 2 +- .../noir_js_backend_barretenberg/package.json | 2 +- tooling/noir_js_types/package.json | 2 +- tooling/noirc_abi_wasm/package.json | 2 +- 136 files changed, 10469 insertions(+), 52 deletions(-) create mode 100644 docs/versioned_docs/version-v0.30.0/explainers/explainer-oracle.md create mode 100644 docs/versioned_docs/version-v0.30.0/explainers/explainer-recursion.md create mode 100644 docs/versioned_docs/version-v0.30.0/getting_started/_category_.json create mode 100644 docs/versioned_docs/version-v0.30.0/getting_started/hello_noir/_category_.json create mode 100644 docs/versioned_docs/version-v0.30.0/getting_started/hello_noir/index.md create mode 100644 docs/versioned_docs/version-v0.30.0/getting_started/hello_noir/project_breakdown.md create mode 100644 docs/versioned_docs/version-v0.30.0/getting_started/installation/_category_.json create mode 100644 docs/versioned_docs/version-v0.30.0/getting_started/installation/index.md create mode 100644 docs/versioned_docs/version-v0.30.0/getting_started/installation/other_install_methods.md create mode 100644 docs/versioned_docs/version-v0.30.0/getting_started/tooling/noir_codegen.md create mode 100644 docs/versioned_docs/version-v0.30.0/how_to/_category_.json create mode 100644 docs/versioned_docs/version-v0.30.0/how_to/debugger/_category_.json create mode 100644 docs/versioned_docs/version-v0.30.0/how_to/debugger/debugging_with_the_repl.md create mode 100644 docs/versioned_docs/version-v0.30.0/how_to/debugger/debugging_with_vs_code.md create mode 100644 docs/versioned_docs/version-v0.30.0/how_to/how-to-oracles.md create mode 100644 docs/versioned_docs/version-v0.30.0/how_to/how-to-recursion.md create mode 100644 docs/versioned_docs/version-v0.30.0/how_to/how-to-solidity-verifier.md create mode 100644 docs/versioned_docs/version-v0.30.0/how_to/merkle-proof.mdx create mode 100644 docs/versioned_docs/version-v0.30.0/how_to/using-devcontainers.mdx create mode 100644 docs/versioned_docs/version-v0.30.0/index.mdx create mode 100644 docs/versioned_docs/version-v0.30.0/migration_notes.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/_category_.json create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/assert.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/comments.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/control_flow.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/data_bus.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/_category_.json create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/arrays.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/booleans.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/fields.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/function_types.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/index.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/integers.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/references.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/slices.mdx create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/strings.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/structs.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/tuples.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/functions.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/generics.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/globals.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/lambdas.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/mutability.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/ops.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/oracles.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/shadowing.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/traits.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/concepts/unconstrained.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/_category_.json create mode 100644 docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/crates_and_packages.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/dependencies.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/modules.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/workspaces.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/_category_.json create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/bigint.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/black_box_fns.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/bn254.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/containers/boundedvec.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/containers/hashmap.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/containers/index.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/containers/vec.mdx create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/_category_.json create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/ciphers.mdx create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/ec_primitives.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/ecdsa_sig_verification.mdx create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/eddsa.mdx create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/embedded_curve_ops.mdx create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/hashes.mdx create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/index.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/schnorr.mdx create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/logging.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/merkle_trees.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/options.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/recursion.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/traits.md create mode 100644 docs/versioned_docs/version-v0.30.0/noir/standard_library/zeroed.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/.nojekyll create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergVerifier.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/index.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/typedoc-sidebar.cjs create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/.nojekyll create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/classes/Noir.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/and.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/blake2s256.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/keccak256.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/sha256.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/xor.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/index.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/ErrorWithPayload.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/ForeignCallInput.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/WitnessMap.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/typedoc-sidebar.cjs create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/.nojekyll create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/functions/compile.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/functions/compile_contract.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/functions/createFileManager.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/functions/inflateDebugSymbols.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/index.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/typedoc-sidebar.cjs create mode 100644 docs/versioned_docs/version-v0.30.0/reference/_category_.json create mode 100644 docs/versioned_docs/version-v0.30.0/reference/debugger/_category_.json create mode 100644 docs/versioned_docs/version-v0.30.0/reference/debugger/debugger_known_limitations.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/debugger/debugger_repl.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/debugger/debugger_vscode.md create mode 100644 docs/versioned_docs/version-v0.30.0/reference/nargo_commands.md create mode 100644 docs/versioned_docs/version-v0.30.0/tooling/debugger.md create mode 100644 docs/versioned_docs/version-v0.30.0/tooling/language_server.md create mode 100644 docs/versioned_docs/version-v0.30.0/tooling/testing.md create mode 100644 docs/versioned_docs/version-v0.30.0/tutorials/noirjs_app.md create mode 100644 docs/versioned_sidebars/version-v0.30.0-sidebars.json diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 447e12155b8..83338327d88 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,4 +1,4 @@ { - ".": "0.29.0", - "acvm-repo": "0.45.0" + ".": "0.30.0", + "acvm-repo": "0.46.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 7be8c387026..db4ec8f4567 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,47 @@ # Changelog +## [0.30.0](https://github.com/noir-lang/noir/compare/v0.29.0...v0.30.0) (2024-05-20) + + +### ⚠ BREAKING CHANGES + +* remove `Opcode::Brillig` from ACIR (https://github.com/AztecProtocol/aztec-packages/pull/5995) +* AES blackbox (https://github.com/AztecProtocol/aztec-packages/pull/6016) + +### Features + +* `multi_scalar_mul` blackbox func (https://github.com/AztecProtocol/aztec-packages/pull/6097) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) +* `variable_base_scalar_mul` blackbox func (https://github.com/AztecProtocol/aztec-packages/pull/6039) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) +* Add `Not` trait to stdlib ([#4999](https://github.com/noir-lang/noir/issues/4999)) ([95d4d13](https://github.com/noir-lang/noir/commit/95d4d133d1eb5e0eb44cd928d8183d890e970a13)) +* Add `std::ops::Neg` trait to stdlib ([07930d4](https://github.com/noir-lang/noir/commit/07930d4373a393146210efae69e6ec40171f047b)) +* Add native rust implementations of pedersen functions ([#4871](https://github.com/noir-lang/noir/issues/4871)) ([fb039f7](https://github.com/noir-lang/noir/commit/fb039f74df23aea39bc0593a5d538d82b4efadf0)) +* Add support for u16/i16 ([#4985](https://github.com/noir-lang/noir/issues/4985)) ([e43661d](https://github.com/noir-lang/noir/commit/e43661d16c1cd07e2af2392b88d29c689889ff9a)) +* AES blackbox (https://github.com/AztecProtocol/aztec-packages/pull/6016) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) +* Do not return databus returndata, keep it private. ([#5023](https://github.com/noir-lang/noir/issues/5023)) ([a5b7df1](https://github.com/noir-lang/noir/commit/a5b7df12faf9d71ff24f8c5cde5e78da44558caf)) +* Dynamic assertion payloads v2 (https://github.com/AztecProtocol/aztec-packages/pull/5949) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) +* Implement `From` array trait for `BoundedVec` ([#4927](https://github.com/noir-lang/noir/issues/4927)) ([bf491dc](https://github.com/noir-lang/noir/commit/bf491dce9595d0e37057ae6d6721eb7a83cec0e2)) +* Implement `ops` traits on `u16`/`i16` ([#4996](https://github.com/noir-lang/noir/issues/4996)) ([8b65663](https://github.com/noir-lang/noir/commit/8b65663f9e836c11a87e458bd7c6a52920448d5c)) +* Implement `std::ops::Sub` on `EmbeddedCurvePoint` ([07930d4](https://github.com/noir-lang/noir/commit/07930d4373a393146210efae69e6ec40171f047b)) +* Increase default expression width to 4 ([#4995](https://github.com/noir-lang/noir/issues/4995)) ([f01d309](https://github.com/noir-lang/noir/commit/f01d3090759a5ff0f1f83c5616d22890c6bd76be)) +* Parsing non-string assertion payloads in noir js (https://github.com/AztecProtocol/aztec-packages/pull/6079) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) +* Remove query to backend to get expression width ([#4975](https://github.com/noir-lang/noir/issues/4975)) ([e5f356b](https://github.com/noir-lang/noir/commit/e5f356b063fe4facbd14320b7eafed664d0bb027)) +* Set aztec private functions to be recursive (https://github.com/AztecProtocol/aztec-packages/pull/6192) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) + + +### Bug Fixes + +* Compute the correct slice length when coercing from a literal array of complex types ([#4986](https://github.com/noir-lang/noir/issues/4986)) ([f3f1150](https://github.com/noir-lang/noir/commit/f3f11507983009771656811f9570bdbe6849c7ef)) +* Defer overflow checks for unsigned integers to acir-gen ([#4832](https://github.com/noir-lang/noir/issues/4832)) ([b577761](https://github.com/noir-lang/noir/commit/b5777613c51f26fb4f580b9168c4190b1f4bd8f7)) +* Fix no predicates for brillig with intermediate functions ([#5015](https://github.com/noir-lang/noir/issues/5015)) ([9c6de4b](https://github.com/noir-lang/noir/commit/9c6de4b25d318c6d211361dd62a112a9d2432c56)) +* Fixed several vulnerabilities in U128, added some tests ([#5024](https://github.com/noir-lang/noir/issues/5024)) ([e5ab24d](https://github.com/noir-lang/noir/commit/e5ab24d6a4154d11b3c8ae08f4431b7b93c76f23)) +* Ignore no_predicates in brillig functions ([#5012](https://github.com/noir-lang/noir/issues/5012)) ([b541e79](https://github.com/noir-lang/noir/commit/b541e793e20fa3c991e0328ec2ff7926bdcdfd45)) +* Set index and value to 0 for array_get with predicate ([#4971](https://github.com/noir-lang/noir/issues/4971)) ([c49d3a9](https://github.com/noir-lang/noir/commit/c49d3a9ded819b828cffdfc031e86614da21e329)) + + +### Miscellaneous Chores + +* Remove `Opcode::Brillig` from ACIR (https://github.com/AztecProtocol/aztec-packages/pull/5995) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) + ## [0.29.0](https://github.com/noir-lang/noir/compare/v0.28.0...v0.29.0) (2024-05-03) diff --git a/Cargo.lock b/Cargo.lock index 2e8eeb10a58..be7f781f96d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 3 [[package]] name = "acir" -version = "0.45.0" +version = "0.46.0" dependencies = [ "acir_field", "base64 0.21.2", @@ -26,7 +26,7 @@ dependencies = [ [[package]] name = "acir_field" -version = "0.45.0" +version = "0.46.0" dependencies = [ "ark-bls12-381", "ark-bn254", @@ -40,7 +40,7 @@ dependencies = [ [[package]] name = "acvm" -version = "0.45.0" +version = "0.46.0" dependencies = [ "acir", "acvm_blackbox_solver", @@ -56,7 +56,7 @@ dependencies = [ [[package]] name = "acvm_blackbox_solver" -version = "0.45.0" +version = "0.46.0" dependencies = [ "acir", "blake2", @@ -93,7 +93,7 @@ dependencies = [ [[package]] name = "acvm_js" -version = "0.45.0" +version = "0.46.0" dependencies = [ "acvm", "bn254_blackbox_solver", @@ -442,7 +442,7 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "aztec_macros" -version = "0.29.0" +version = "0.30.0" dependencies = [ "convert_case 0.6.0", "iter-extended", @@ -453,7 +453,7 @@ dependencies = [ [[package]] name = "backend-interface" -version = "0.29.0" +version = "0.30.0" dependencies = [ "acvm", "bb_abstraction_leaks", @@ -608,7 +608,7 @@ dependencies = [ [[package]] name = "bn254_blackbox_solver" -version = "0.45.0" +version = "0.46.0" dependencies = [ "acir", "acvm_blackbox_solver", @@ -631,7 +631,7 @@ dependencies = [ [[package]] name = "brillig" -version = "0.45.0" +version = "0.46.0" dependencies = [ "acir_field", "serde", @@ -639,7 +639,7 @@ dependencies = [ [[package]] name = "brillig_vm" -version = "0.45.0" +version = "0.46.0" dependencies = [ "acir", "acvm_blackbox_solver", @@ -1763,7 +1763,7 @@ dependencies = [ [[package]] name = "fm" -version = "0.29.0" +version = "0.30.0" dependencies = [ "codespan-reporting", "iter-extended", @@ -2384,7 +2384,7 @@ dependencies = [ [[package]] name = "iter-extended" -version = "0.29.0" +version = "0.30.0" [[package]] name = "itertools" @@ -2815,7 +2815,7 @@ checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" [[package]] name = "nargo" -version = "0.29.0" +version = "0.30.0" dependencies = [ "acvm", "codespan-reporting", @@ -2841,7 +2841,7 @@ dependencies = [ [[package]] name = "nargo_cli" -version = "0.29.0" +version = "0.30.0" dependencies = [ "acvm", "assert_cmd", @@ -2895,7 +2895,7 @@ dependencies = [ [[package]] name = "nargo_fmt" -version = "0.29.0" +version = "0.30.0" dependencies = [ "bytecount", "noirc_frontend", @@ -2907,7 +2907,7 @@ dependencies = [ [[package]] name = "nargo_toml" -version = "0.29.0" +version = "0.30.0" dependencies = [ "dirs", "fm", @@ -2986,7 +2986,7 @@ dependencies = [ [[package]] name = "noir_debugger" -version = "0.29.0" +version = "0.30.0" dependencies = [ "acvm", "assert_cmd", @@ -3021,7 +3021,7 @@ dependencies = [ [[package]] name = "noir_lsp" -version = "0.29.0" +version = "0.30.0" dependencies = [ "acvm", "async-lsp", @@ -3047,7 +3047,7 @@ dependencies = [ [[package]] name = "noir_wasm" -version = "0.29.0" +version = "0.30.0" dependencies = [ "acvm", "build-data", @@ -3070,7 +3070,7 @@ dependencies = [ [[package]] name = "noirc_abi" -version = "0.29.0" +version = "0.30.0" dependencies = [ "acvm", "iter-extended", @@ -3088,7 +3088,7 @@ dependencies = [ [[package]] name = "noirc_abi_wasm" -version = "0.29.0" +version = "0.30.0" dependencies = [ "acvm", "build-data", @@ -3105,11 +3105,11 @@ dependencies = [ [[package]] name = "noirc_arena" -version = "0.29.0" +version = "0.30.0" [[package]] name = "noirc_driver" -version = "0.29.0" +version = "0.30.0" dependencies = [ "acvm", "aztec_macros", @@ -3130,7 +3130,7 @@ dependencies = [ [[package]] name = "noirc_errors" -version = "0.29.0" +version = "0.30.0" dependencies = [ "acvm", "base64 0.21.2", @@ -3148,7 +3148,7 @@ dependencies = [ [[package]] name = "noirc_evaluator" -version = "0.29.0" +version = "0.30.0" dependencies = [ "acvm", "chrono", @@ -3165,7 +3165,7 @@ dependencies = [ [[package]] name = "noirc_frontend" -version = "0.29.0" +version = "0.30.0" dependencies = [ "acvm", "base64 0.21.2", @@ -3194,7 +3194,7 @@ dependencies = [ [[package]] name = "noirc_printable_type" -version = "0.29.0" +version = "0.30.0" dependencies = [ "acvm", "iter-extended", diff --git a/Cargo.toml b/Cargo.toml index f744d6d0cf5..670ae36dd4b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ resolver = "2" [workspace.package] # x-release-please-start-version -version = "0.29.0" +version = "0.30.0" # x-release-please-end authors = ["The Noir Team "] edition = "2021" @@ -52,13 +52,13 @@ repository = "https://github.com/noir-lang/noir/" [workspace.dependencies] # ACVM workspace dependencies -acir_field = { version = "0.45.0", path = "acvm-repo/acir_field", default-features = false } -acir = { version = "0.45.0", path = "acvm-repo/acir", default-features = false } -acvm = { version = "0.45.0", path = "acvm-repo/acvm" } -brillig = { version = "0.45.0", path = "acvm-repo/brillig", default-features = false } -brillig_vm = { version = "0.45.0", path = "acvm-repo/brillig_vm", default-features = false } -acvm_blackbox_solver = { version = "0.45.0", path = "acvm-repo/blackbox_solver", default-features = false } -bn254_blackbox_solver = { version = "0.45.0", path = "acvm-repo/bn254_blackbox_solver", default-features = false } +acir_field = { version = "0.46.0", path = "acvm-repo/acir_field", default-features = false } +acir = { version = "0.46.0", path = "acvm-repo/acir", default-features = false } +acvm = { version = "0.46.0", path = "acvm-repo/acvm" } +brillig = { version = "0.46.0", path = "acvm-repo/brillig", default-features = false } +brillig_vm = { version = "0.46.0", path = "acvm-repo/brillig_vm", default-features = false } +acvm_blackbox_solver = { version = "0.46.0", path = "acvm-repo/blackbox_solver", default-features = false } +bn254_blackbox_solver = { version = "0.46.0", path = "acvm-repo/bn254_blackbox_solver", default-features = false } # Noir compiler workspace dependencies fm = { path = "compiler/fm" } diff --git a/acvm-repo/CHANGELOG.md b/acvm-repo/CHANGELOG.md index 6ac04f6f83f..c9bb0d610eb 100644 --- a/acvm-repo/CHANGELOG.md +++ b/acvm-repo/CHANGELOG.md @@ -5,6 +5,135 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.46.0](https://github.com/noir-lang/noir/compare/v0.45.0...v0.46.0) (2024-05-20) + + +### ⚠ BREAKING CHANGES + +* remove `Opcode::Brillig` from ACIR (https://github.com/AztecProtocol/aztec-packages/pull/5995) +* AES blackbox (https://github.com/AztecProtocol/aztec-packages/pull/6016) +* Bit shift is restricted to u8 right operand ([#4907](https://github.com/noir-lang/noir/issues/4907)) +* contract interfaces and better function calls (https://github.com/AztecProtocol/aztec-packages/pull/5687) +* change backend width to 4 (https://github.com/AztecProtocol/aztec-packages/pull/5374) +* Use fixed size arrays in black box functions where sizes are known (https://github.com/AztecProtocol/aztec-packages/pull/5620) +* trap with revert data (https://github.com/AztecProtocol/aztec-packages/pull/5732) +* **acir:** BrilligCall opcode (https://github.com/AztecProtocol/aztec-packages/pull/5709) +* remove fixed-length keccak256 (https://github.com/AztecProtocol/aztec-packages/pull/5617) +* storage_layout and `#[aztec(storage)]` (https://github.com/AztecProtocol/aztec-packages/pull/5387) +* **acir:** Add predicate to call opcode (https://github.com/AztecProtocol/aztec-packages/pull/5616) +* contract_abi-exports (https://github.com/AztecProtocol/aztec-packages/pull/5386) +* Brillig typed memory (https://github.com/AztecProtocol/aztec-packages/pull/5395) +* **acir:** Program and witness stack structure (https://github.com/AztecProtocol/aztec-packages/pull/5149) +* automatic NoteInterface and NoteGetterOptions auto select (https://github.com/AztecProtocol/aztec-packages/pull/4508) +* Acir call opcode (https://github.com/AztecProtocol/aztec-packages/pull/4773) +* Support contracts with no constructor (https://github.com/AztecProtocol/aztec-packages/pull/5175) +* Internal as a macro (https://github.com/AztecProtocol/aztec-packages/pull/4898) +* move noir out of yarn-project (https://github.com/AztecProtocol/aztec-packages/pull/4479) +* note type ids (https://github.com/AztecProtocol/aztec-packages/pull/4500) +* rename bigint_neg into bigint_sub (https://github.com/AztecProtocol/aztec-packages/pull/4420) +* Add expression width into acir (https://github.com/AztecProtocol/aztec-packages/pull/4014) +* init storage macro (https://github.com/AztecProtocol/aztec-packages/pull/4200) +* **acir:** Move `is_recursive` flag to be part of the circuit definition (https://github.com/AztecProtocol/aztec-packages/pull/4221) +* Sync commits from `aztec-packages` ([#4144](https://github.com/noir-lang/noir/issues/4144)) + +### Features + +* `multi_scalar_mul` blackbox func (https://github.com/AztecProtocol/aztec-packages/pull/6097) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) +* `variable_base_scalar_mul` blackbox func (https://github.com/AztecProtocol/aztec-packages/pull/6039) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) +* Acir call opcode (https://github.com/AztecProtocol/aztec-packages/pull/4773) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) +* **acir_gen:** Brillig stdlib ([#4848](https://github.com/noir-lang/noir/issues/4848)) ([0c8175c](https://github.com/noir-lang/noir/commit/0c8175cb539efd9427c73ae5af0d48abe688ebab)) +* **acir_gen:** Fold attribute at compile-time and initial non inlined ACIR (https://github.com/AztecProtocol/aztec-packages/pull/5341) ([a0f7474](https://github.com/noir-lang/noir/commit/a0f7474ae6bd74132efdb945d2eb2383f3913cce)) +* **acir:** Add predicate to call opcode (https://github.com/AztecProtocol/aztec-packages/pull/5616) ([2bd006a](https://github.com/noir-lang/noir/commit/2bd006ae07499e8702b0fa9565855f0a5ef1a589)) +* **acir:** BrilligCall opcode (https://github.com/AztecProtocol/aztec-packages/pull/5709) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) +* **acir:** Program and witness stack structure (https://github.com/AztecProtocol/aztec-packages/pull/5149) ([13eb71b](https://github.com/noir-lang/noir/commit/13eb71b8de44eb6aad9c37943ad06fc73db589f5)) +* **acvm_js:** Execute program ([#4694](https://github.com/noir-lang/noir/issues/4694)) ([386f6d0](https://github.com/noir-lang/noir/commit/386f6d0a5822912db878285cb001032a7c0ff622)) +* **acvm:** Execute multiple circuits (https://github.com/AztecProtocol/aztec-packages/pull/5380) ([a0f7474](https://github.com/noir-lang/noir/commit/a0f7474ae6bd74132efdb945d2eb2383f3913cce)) +* Add bit size to const opcode (https://github.com/AztecProtocol/aztec-packages/pull/4385) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc)) +* Add CMOV instruction to brillig and brillig gen (https://github.com/AztecProtocol/aztec-packages/pull/5308) ([13eb71b](https://github.com/noir-lang/noir/commit/13eb71b8de44eb6aad9c37943ad06fc73db589f5)) +* Add expression width into acir (https://github.com/AztecProtocol/aztec-packages/pull/4014) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc)) +* Add instrumentation for tracking variables in debugging ([#4122](https://github.com/noir-lang/noir/issues/4122)) ([c58d691](https://github.com/noir-lang/noir/commit/c58d69141b54a918cd1675400c00bfd48720f896)) +* Add native rust implementations of pedersen functions ([#4871](https://github.com/noir-lang/noir/issues/4871)) ([fb039f7](https://github.com/noir-lang/noir/commit/fb039f74df23aea39bc0593a5d538d82b4efadf0)) +* Add poseidon2 opcode implementation for acvm/brillig, and Noir ([#4398](https://github.com/noir-lang/noir/issues/4398)) ([10e8292](https://github.com/noir-lang/noir/commit/10e82920798380f50046e52db4a20ca205191ab7)) +* Add return values to aztec fns (https://github.com/AztecProtocol/aztec-packages/pull/5389) ([2bd006a](https://github.com/noir-lang/noir/commit/2bd006ae07499e8702b0fa9565855f0a5ef1a589)) +* Add support for overriding expression width ([#4117](https://github.com/noir-lang/noir/issues/4117)) ([c8026d5](https://github.com/noir-lang/noir/commit/c8026d557d535b10fe455165d6445076df7a03de)) +* Added cast opcode and cast calldata (https://github.com/AztecProtocol/aztec-packages/pull/4423) ([78ef013](https://github.com/noir-lang/noir/commit/78ef0134b82e76a73dadb6c7975def22290e3a1a)) +* AES blackbox (https://github.com/AztecProtocol/aztec-packages/pull/6016) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) +* Allow brillig to read arrays directly from memory (https://github.com/AztecProtocol/aztec-packages/pull/4460) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc)) +* Allow nested arrays and vectors in Brillig foreign calls (https://github.com/AztecProtocol/aztec-packages/pull/4478) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc)) +* Allow variables and stack trace inspection in the debugger ([#4184](https://github.com/noir-lang/noir/issues/4184)) ([bf263fc](https://github.com/noir-lang/noir/commit/bf263fc8d843940f328a90f6366edd2671fb2682)) +* Automatic NoteInterface and NoteGetterOptions auto select (https://github.com/AztecProtocol/aztec-packages/pull/4508) ([13eb71b](https://github.com/noir-lang/noir/commit/13eb71b8de44eb6aad9c37943ad06fc73db589f5)) +* **avm:** Back in avm context with macro - refactor context (https://github.com/AztecProtocol/aztec-packages/pull/4438) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc)) +* **avm:** Brillig CONST of size > u128 (https://github.com/AztecProtocol/aztec-packages/pull/5217) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) +* **avm:** Integrate AVM with initializers (https://github.com/AztecProtocol/aztec-packages/pull/5469) ([2bd006a](https://github.com/noir-lang/noir/commit/2bd006ae07499e8702b0fa9565855f0a5ef1a589)) +* **aztec-nr:** Initial work for aztec public vm macro (https://github.com/AztecProtocol/aztec-packages/pull/4400) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc)) +* Backpropagate constants in ACIR during optimization ([#3926](https://github.com/noir-lang/noir/issues/3926)) ([aad0da0](https://github.com/noir-lang/noir/commit/aad0da024c69663f42e6913e674682d5864b26ae)) +* Bit shift is restricted to u8 right operand ([#4907](https://github.com/noir-lang/noir/issues/4907)) ([c4b0369](https://github.com/noir-lang/noir/commit/c4b03691feca17ef268acab523292f3051f672ea)) +* Brillig heterogeneous memory cells (https://github.com/AztecProtocol/aztec-packages/pull/5608) ([305bcdc](https://github.com/noir-lang/noir/commit/305bcdcbd01cb84dbaac900f14cb6cf867f83bda)) +* Brillig IR refactor (https://github.com/AztecProtocol/aztec-packages/pull/5233) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) +* Brillig pointer codegen and execution (https://github.com/AztecProtocol/aztec-packages/pull/5737) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) +* Brillig typed memory (https://github.com/AztecProtocol/aztec-packages/pull/5395) ([0bc18c4](https://github.com/noir-lang/noir/commit/0bc18c4f78171590dd58bded959f68f53a44cc8c)) +* Change backend width to 4 (https://github.com/AztecProtocol/aztec-packages/pull/5374) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) +* Check initializer msg.sender matches deployer from address preimage (https://github.com/AztecProtocol/aztec-packages/pull/5222) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) +* Contract interfaces and better function calls (https://github.com/AztecProtocol/aztec-packages/pull/5687) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) +* Contract_abi-exports (https://github.com/AztecProtocol/aztec-packages/pull/5386) ([2bd006a](https://github.com/noir-lang/noir/commit/2bd006ae07499e8702b0fa9565855f0a5ef1a589)) +* Dynamic assertion payloads v2 (https://github.com/AztecProtocol/aztec-packages/pull/5949) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) +* Evaluation of dynamic assert messages ([#4101](https://github.com/noir-lang/noir/issues/4101)) ([c284e01](https://github.com/noir-lang/noir/commit/c284e01bfe20ceae4414dc123624b5cbb8b66d09)) +* Handle `BrilligCall` opcodes in the debugger ([#4897](https://github.com/noir-lang/noir/issues/4897)) ([b380dc4](https://github.com/noir-lang/noir/commit/b380dc44de5c9f8de278ece3d531ebbc2c9238ba)) +* Impl of missing functionality in new key store (https://github.com/AztecProtocol/aztec-packages/pull/5750) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) +* Increase default expression width to 4 ([#4995](https://github.com/noir-lang/noir/issues/4995)) ([f01d309](https://github.com/noir-lang/noir/commit/f01d3090759a5ff0f1f83c5616d22890c6bd76be)) +* Init storage macro (https://github.com/AztecProtocol/aztec-packages/pull/4200) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc)) +* Initial Earthly CI (https://github.com/AztecProtocol/aztec-packages/pull/5069) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) +* Internal as a macro (https://github.com/AztecProtocol/aztec-packages/pull/4898) ([5f57ebb](https://github.com/noir-lang/noir/commit/5f57ebb7ff4b810802f90699a10f4325ef904f2e)) +* **nargo:** Handle call stacks for multiple Acir calls ([#4711](https://github.com/noir-lang/noir/issues/4711)) ([5b23171](https://github.com/noir-lang/noir/commit/5b231714740447d82cde7cdbe65d4a8b46a31df4)) +* New brillig field operations and refactor of binary operations (https://github.com/AztecProtocol/aztec-packages/pull/5208) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) +* Note type ids (https://github.com/AztecProtocol/aztec-packages/pull/4500) ([78ef013](https://github.com/noir-lang/noir/commit/78ef0134b82e76a73dadb6c7975def22290e3a1a)) +* Parsing non-string assertion payloads in noir js (https://github.com/AztecProtocol/aztec-packages/pull/6079) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) +* Remove replacement of boolean range opcodes with `AssertZero` opcodes ([#4107](https://github.com/noir-lang/noir/issues/4107)) ([dac0e87](https://github.com/noir-lang/noir/commit/dac0e87ee3be3446b92bbb12ef4832fd493fcee3)) +* Restore hashing args via slice for performance (https://github.com/AztecProtocol/aztec-packages/pull/5539) ([2bd006a](https://github.com/noir-lang/noir/commit/2bd006ae07499e8702b0fa9565855f0a5ef1a589)) +* Set aztec private functions to be recursive (https://github.com/AztecProtocol/aztec-packages/pull/6192) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) +* Signed integer division and modulus in brillig gen (https://github.com/AztecProtocol/aztec-packages/pull/5279) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) +* **simulator:** Fetch return values at circuit execution (https://github.com/AztecProtocol/aztec-packages/pull/5642) ([305bcdc](https://github.com/noir-lang/noir/commit/305bcdcbd01cb84dbaac900f14cb6cf867f83bda)) +* Storage_layout and `#[aztec(storage)]` (https://github.com/AztecProtocol/aztec-packages/pull/5387) ([2bd006a](https://github.com/noir-lang/noir/commit/2bd006ae07499e8702b0fa9565855f0a5ef1a589)) +* Support contracts with no constructor (https://github.com/AztecProtocol/aztec-packages/pull/5175) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) +* Sync `aztec-packages` ([#4011](https://github.com/noir-lang/noir/issues/4011)) ([fee2452](https://github.com/noir-lang/noir/commit/fee24523c427c27f0bdaf98ea09a852a2da3e94c)) +* Sync commits from `aztec-packages` ([#4068](https://github.com/noir-lang/noir/issues/4068)) ([7a8f3a3](https://github.com/noir-lang/noir/commit/7a8f3a33b57875e681e3d81e667e3570a1cdbdcc)) +* Sync commits from `aztec-packages` ([#4144](https://github.com/noir-lang/noir/issues/4144)) ([0205d3b](https://github.com/noir-lang/noir/commit/0205d3b4ad0cf5ffd775a43eb5af273a772cf138)) +* Sync from aztec-packages ([#4483](https://github.com/noir-lang/noir/issues/4483)) ([fe8f277](https://github.com/noir-lang/noir/commit/fe8f2776ccfde29209a2c3fc162311c99e4f59be)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5234) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5286) ([c3c9e19](https://github.com/noir-lang/noir/commit/c3c9e19a20d61272a04b95fd6c7d34cc4cb96e45)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5572) ([2bd006a](https://github.com/noir-lang/noir/commit/2bd006ae07499e8702b0fa9565855f0a5ef1a589)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5619) ([2bd006a](https://github.com/noir-lang/noir/commit/2bd006ae07499e8702b0fa9565855f0a5ef1a589)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5697) ([305bcdc](https://github.com/noir-lang/noir/commit/305bcdcbd01cb84dbaac900f14cb6cf867f83bda)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5794) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5814) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5935) ([1b867b1](https://github.com/noir-lang/noir/commit/1b867b121fba5db3087ca845b4934e6732b23fd1)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5955) ([1b867b1](https://github.com/noir-lang/noir/commit/1b867b121fba5db3087ca845b4934e6732b23fd1)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/5999) ([1b867b1](https://github.com/noir-lang/noir/commit/1b867b121fba5db3087ca845b4934e6732b23fd1)) +* Trap with revert data (https://github.com/AztecProtocol/aztec-packages/pull/5732) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) +* Use fixed size arrays in black box functions where sizes are known (https://github.com/AztecProtocol/aztec-packages/pull/5620) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) +* Variable length returns (https://github.com/AztecProtocol/aztec-packages/pull/5633) ([305bcdc](https://github.com/noir-lang/noir/commit/305bcdcbd01cb84dbaac900f14cb6cf867f83bda)) + + +### Bug Fixes + +* **acvm:** Mark outputs of Opcode::Call solvable ([#4708](https://github.com/noir-lang/noir/issues/4708)) ([8fea405](https://github.com/noir-lang/noir/commit/8fea40576f262bd5bb588923c0660d8967404e56)) +* Avoid huge unrolling in hash_args (https://github.com/AztecProtocol/aztec-packages/pull/5703) ([305bcdc](https://github.com/noir-lang/noir/commit/305bcdcbd01cb84dbaac900f14cb6cf867f83bda)) +* Catch panics from EC point creation (e.g. the point is at infinity) ([#4790](https://github.com/noir-lang/noir/issues/4790)) ([645dba1](https://github.com/noir-lang/noir/commit/645dba192f16ef34018828186ffb297422a8dc73)) +* Don't reuse brillig with slice arguments (https://github.com/AztecProtocol/aztec-packages/pull/5800) ([0f9ae0a](https://github.com/noir-lang/noir/commit/0f9ae0ac1d68714b56ba4524aedcc67212494f1b)) +* Issue 4682 and add solver for unconstrained bigintegers ([#4729](https://github.com/noir-lang/noir/issues/4729)) ([e4d33c1](https://github.com/noir-lang/noir/commit/e4d33c126a2795d9aaa6048d4e91b64cb4bbe4f2)) +* Noir test incorrect reporting (https://github.com/AztecProtocol/aztec-packages/pull/4925) ([5f57ebb](https://github.com/noir-lang/noir/commit/5f57ebb7ff4b810802f90699a10f4325ef904f2e)) +* Proper field inversion for bigints ([#4802](https://github.com/noir-lang/noir/issues/4802)) ([b46d0e3](https://github.com/noir-lang/noir/commit/b46d0e39f4252f8bbaa987f88d112e4c233b3d61)) +* Remove panic from `init_log_level` in `acvm_js` ([#4195](https://github.com/noir-lang/noir/issues/4195)) ([2e26530](https://github.com/noir-lang/noir/commit/2e26530bf53006c1ed4fee310bcaa905c95dd95b)) + + +### Miscellaneous Chores + +* **acir:** Move `is_recursive` flag to be part of the circuit definition (https://github.com/AztecProtocol/aztec-packages/pull/4221) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc)) +* Move noir out of yarn-project (https://github.com/AztecProtocol/aztec-packages/pull/4479) ([78ef013](https://github.com/noir-lang/noir/commit/78ef0134b82e76a73dadb6c7975def22290e3a1a)) +* Remove `Opcode::Brillig` from ACIR (https://github.com/AztecProtocol/aztec-packages/pull/5995) ([73a635e](https://github.com/noir-lang/noir/commit/73a635e5086cf3407f9846ce39807cd15b4e485a)) +* Remove fixed-length keccak256 (https://github.com/AztecProtocol/aztec-packages/pull/5617) ([305bcdc](https://github.com/noir-lang/noir/commit/305bcdcbd01cb84dbaac900f14cb6cf867f83bda)) +* Rename bigint_neg into bigint_sub (https://github.com/AztecProtocol/aztec-packages/pull/4420) ([158c8ce](https://github.com/noir-lang/noir/commit/158c8cec7f0dc698042e9512001dd2c9d6b40bcc)) + ## [0.45.0](https://github.com/noir-lang/noir/compare/v0.44.0...v0.45.0) (2024-05-03) diff --git a/acvm-repo/acir/Cargo.toml b/acvm-repo/acir/Cargo.toml index 9e1a2f940c4..32a9bbe8303 100644 --- a/acvm-repo/acir/Cargo.toml +++ b/acvm-repo/acir/Cargo.toml @@ -2,7 +2,7 @@ name = "acir" description = "ACIR is the IR that the VM processes, it is analogous to LLVM IR" # x-release-please-start-version -version = "0.45.0" +version = "0.46.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/acir_field/Cargo.toml b/acvm-repo/acir_field/Cargo.toml index 89ee161206e..dd4b7af9ffc 100644 --- a/acvm-repo/acir_field/Cargo.toml +++ b/acvm-repo/acir_field/Cargo.toml @@ -2,7 +2,7 @@ name = "acir_field" description = "The field implementation being used by ACIR." # x-release-please-start-version -version = "0.45.0" +version = "0.46.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/acvm/Cargo.toml b/acvm-repo/acvm/Cargo.toml index 1b671d49366..74aed429f9a 100644 --- a/acvm-repo/acvm/Cargo.toml +++ b/acvm-repo/acvm/Cargo.toml @@ -2,7 +2,7 @@ name = "acvm" description = "The virtual machine that processes ACIR given a backend/proof system." # x-release-please-start-version -version = "0.45.0" +version = "0.46.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/acvm_js/Cargo.toml b/acvm-repo/acvm_js/Cargo.toml index 1675d601351..ec63649947e 100644 --- a/acvm-repo/acvm_js/Cargo.toml +++ b/acvm-repo/acvm_js/Cargo.toml @@ -2,7 +2,7 @@ name = "acvm_js" description = "Typescript wrapper around the ACVM allowing execution of ACIR code" # x-release-please-start-version -version = "0.45.0" +version = "0.46.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/acvm_js/package.json b/acvm-repo/acvm_js/package.json index 5be2f164ac4..48c5b2a8644 100644 --- a/acvm-repo/acvm_js/package.json +++ b/acvm-repo/acvm_js/package.json @@ -1,6 +1,6 @@ { "name": "@noir-lang/acvm_js", - "version": "0.45.0", + "version": "0.46.0", "publishConfig": { "access": "public" }, diff --git a/acvm-repo/blackbox_solver/Cargo.toml b/acvm-repo/blackbox_solver/Cargo.toml index f40046acad6..6c1cd190254 100644 --- a/acvm-repo/blackbox_solver/Cargo.toml +++ b/acvm-repo/blackbox_solver/Cargo.toml @@ -2,7 +2,7 @@ name = "acvm_blackbox_solver" description = "A solver for the blackbox functions found in ACIR and Brillig" # x-release-please-start-version -version = "0.45.0" +version = "0.46.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/bn254_blackbox_solver/Cargo.toml b/acvm-repo/bn254_blackbox_solver/Cargo.toml index b261be65735..49448d58fe6 100644 --- a/acvm-repo/bn254_blackbox_solver/Cargo.toml +++ b/acvm-repo/bn254_blackbox_solver/Cargo.toml @@ -2,7 +2,7 @@ name = "bn254_blackbox_solver" description = "Solvers for black box functions which are specific for the bn254 curve" # x-release-please-start-version -version = "0.45.0" +version = "0.46.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/brillig/Cargo.toml b/acvm-repo/brillig/Cargo.toml index 081abe022ae..f60bde6f074 100644 --- a/acvm-repo/brillig/Cargo.toml +++ b/acvm-repo/brillig/Cargo.toml @@ -2,7 +2,7 @@ name = "brillig" description = "Brillig is the bytecode ACIR uses for non-determinism." # x-release-please-start-version -version = "0.45.0" +version = "0.46.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/brillig_vm/Cargo.toml b/acvm-repo/brillig_vm/Cargo.toml index 57cf3be974a..7dd11912449 100644 --- a/acvm-repo/brillig_vm/Cargo.toml +++ b/acvm-repo/brillig_vm/Cargo.toml @@ -2,7 +2,7 @@ name = "brillig_vm" description = "The virtual machine that processes Brillig bytecode, used to introduce non-determinism to the ACVM" # x-release-please-start-version -version = "0.45.0" +version = "0.46.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/compiler/wasm/package.json b/compiler/wasm/package.json index bccf937219e..0bb9b803ee0 100644 --- a/compiler/wasm/package.json +++ b/compiler/wasm/package.json @@ -3,7 +3,7 @@ "contributors": [ "The Noir Team " ], - "version": "0.29.0", + "version": "0.30.0", "license": "(MIT OR Apache-2.0)", "main": "dist/main.js", "types": "./dist/types/src/index.d.cts", diff --git a/docs/versioned_docs/version-v0.30.0/explainers/explainer-oracle.md b/docs/versioned_docs/version-v0.30.0/explainers/explainer-oracle.md new file mode 100644 index 00000000000..b84ca5dd986 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/explainers/explainer-oracle.md @@ -0,0 +1,57 @@ +--- +title: Oracles +description: This guide provides an in-depth understanding of how Oracles work in Noir programming. Learn how to use outside calculations in your programs, constrain oracles, and understand their uses and limitations. +keywords: + - Noir Programming + - Oracles + - JSON-RPC + - Foreign Call Handlers + - Constrained Functions + - Blockchain Programming +sidebar_position: 1 +--- + +If you've seen "The Matrix" you may recall "The Oracle" as Gloria Foster smoking cigarettes and baking cookies. While she appears to "know things", she is actually providing a calculation of a pre-determined future. Noir Oracles are similar, in a way. They don't calculate the future (yet), but they allow you to use outside calculations in your programs. + +![matrix oracle prediction](@site/static/img/memes/matrix_oracle.jpeg) + +A Noir program is usually self-contained. You can pass certain inputs to it, and it will generate a deterministic output for those inputs. But what if you wanted to defer some calculation to an outside process or source? + +Oracles are functions that provide this feature. + +## Use cases + +An example usage for Oracles is proving something on-chain. For example, proving that the ETH-USDC quote was below a certain target at a certain block time. Or even making more complex proofs like proving the ownership of an NFT as an anonymous login method. + +Another interesting use case is to defer expensive calculations to be made outside of the Noir program, and then constraining the result; similar to the use of [unconstrained functions](../noir/concepts//unconstrained.md). + +In short, anything that can be constrained in a Noir program but needs to be fetched from an external source is a great candidate to be used in oracles. + +## Constraining oracles + +Just like in The Matrix, Oracles are powerful. But with great power, comes great responsibility. Just because you're using them in a Noir program doesn't mean they're true. Noir has no superpowers. If you want to prove that Portugal won the Euro Cup 2016, you're still relying on potentially untrusted information. + +To give a concrete example, Alice wants to login to the [NounsDAO](https://nouns.wtf/) forum with her username "noir_nouner" by proving she owns a noun without revealing her ethereum address. Her Noir program could have a oracle call like this: + +```rust +#[oracle(getNoun)] +unconstrained fn get_noun(address: Field) -> Field +``` + +This oracle could naively resolve with the number of Nouns she possesses. However, it is useless as a trusted source, as the oracle could resolve to anything Alice wants. In order to make this oracle call actually useful, Alice would need to constrain the response from the oracle, by proving her address and the noun count belongs to the state tree of the contract. + +In short, **Oracles don't prove anything. Your Noir program does.** + +:::danger + +If you don't constrain the return of your oracle, you could be clearly opening an attack vector on your Noir program. Make double-triple sure that the return of an oracle call is constrained! + +::: + +## How to use Oracles + +On CLI, Nargo resolves oracles by making JSON RPC calls, which means it would require an RPC node to be running. + +In JavaScript, NoirJS accepts and resolves arbitrary call handlers (that is, not limited to JSON) as long as they matches the expected types the developer defines. Refer to [Foreign Call Handler](../reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md) to learn more about NoirJS's call handling. + +If you want to build using oracles, follow through to the [oracle guide](../how_to/how-to-oracles.md) for a simple example on how to do that. diff --git a/docs/versioned_docs/version-v0.30.0/explainers/explainer-recursion.md b/docs/versioned_docs/version-v0.30.0/explainers/explainer-recursion.md new file mode 100644 index 00000000000..18846176ca7 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/explainers/explainer-recursion.md @@ -0,0 +1,176 @@ +--- +title: Recursive proofs +description: Explore the concept of recursive proofs in Zero-Knowledge programming. Understand how recursion works in Noir, a language for writing smart contracts on the EVM blockchain. Learn through practical examples like Alice and Bob's guessing game, Charlie's recursive merkle tree, and Daniel's reusable components. Discover how to use recursive proofs to optimize computational resources and improve efficiency. + +keywords: + [ + "Recursive Proofs", + "Zero-Knowledge Programming", + "Noir", + "EVM Blockchain", + "Smart Contracts", + "Recursion in Noir", + "Alice and Bob Guessing Game", + "Recursive Merkle Tree", + "Reusable Components", + "Optimizing Computational Resources", + "Improving Efficiency", + "Verification Key", + "Aggregation", + "Recursive zkSNARK schemes", + "PLONK", + "Proving and Verification Keys" + ] +sidebar_position: 1 +pagination_next: how_to/how-to-recursion +--- + +In programming, we tend to think of recursion as something calling itself. A classic example would be the calculation of the factorial of a number: + +```js +function factorial(n) { + if (n === 0 || n === 1) { + return 1; + } else { + return n * factorial(n - 1); + } +} +``` + +In this case, while `n` is not `1`, this function will keep calling itself until it hits the base case, bubbling up the result on the call stack: + +```md + Is `n` 1? <--------- + /\ / + / \ n = n -1 + / \ / + Yes No -------- +``` + +In Zero-Knowledge, recursion has some similarities. + +It is not a Noir function calling itself, but a proof being used as an input to another circuit. In short, you verify one proof *inside* another proof, returning the proof that both proofs are valid. + +This means that, given enough computational resources, you can prove the correctness of any arbitrary number of proofs in a single proof. This could be useful to design state channels (for which a common example would be [Bitcoin's Lightning Network](https://en.wikipedia.org/wiki/Lightning_Network)), to save on gas costs by settling one proof on-chain, or simply to make business logic less dependent on a consensus mechanism. + +## Examples + +Let us look at some of these examples + +### Alice and Bob - Guessing game + +Alice and Bob are friends, and they like guessing games. They want to play a guessing game online, but for that, they need a trusted third-party that knows both of their secrets and finishes the game once someone wins. + +So, they use zero-knowledge proofs. Alice tries to guess Bob's number, and Bob will generate a ZK proof stating whether she succeeded or failed. + +This ZK proof can go on a smart contract, revealing the winner and even giving prizes. However, this means every turn needs to be verified on-chain. This incurs some cost and waiting time that may simply make the game too expensive or time-consuming to be worth it. + +As a solution, Alice proposes the following: "what if Bob generates his proof, and instead of sending it on-chain, I verify it *within* my own proof before playing my own turn?". + +She can then generate a proof that she verified his proof, and so on. + +```md + Did you fail? <-------------------------- + / \ / + / \ n = n -1 + / \ / + Yes No / + | | / + | | / + | You win / + | / + | / +Generate proof of that / + + / + my own guess ---------------- +``` + +### Charlie - Recursive merkle tree + +Charlie is a concerned citizen, and wants to be sure his vote in an election is accounted for. He votes with a ZK proof, but he has no way of knowing that his ZK proof was included in the total vote count! + +If the vote collector puts all of the votes into a [Merkle tree](https://en.wikipedia.org/wiki/Merkle_tree), everyone can prove the verification of two proofs within one proof, as such: + +```md + abcd + __________|______________ + | | + ab cd + _____|_____ ______|______ + | | | | + alice bob charlie daniel +``` + +Doing this recursively allows us to arrive on a final proof `abcd` which if true, verifies the correctness of all the votes. + +### Daniel - Reusable components + +Daniel has a big circuit and a big headache. A part of his circuit is a setup phase that finishes with some assertions that need to be made. But that section alone takes most of the proving time, and is largely independent of the rest of the circuit. + +He might find it more efficient to generate a proof for that setup phase separately, and verify that proof recursively in the actual business logic section of his circuit. This will allow for parallelization of both proofs, which results in a considerable speedup. + +## What params do I need + +As you can see in the [recursion reference](noir/standard_library/recursion.md), a simple recursive proof requires: + +- The proof to verify +- The Verification Key of the circuit that generated the proof +- A hash of this verification key, as it's needed for some backends +- The public inputs for the proof + +:::info + +Recursive zkSNARK schemes do not necessarily "verify a proof" in the sense that you expect a true or false to be spit out by the verifier. Rather an aggregation object is built over the public inputs. + +So, taking the example of Alice and Bob and their guessing game: + +- Alice makes her guess. Her proof is *not* recursive: it doesn't verify any proof within it! It's just a standard `assert(x != y)` circuit +- Bob verifies Alice's proof and makes his own guess. In this circuit, he doesn't exactly *prove* the verification of Alice's proof. Instead, he *aggregates* his proof to Alice's proof. The actual verification is done when the full proof is verified, for example when using `nargo verify` or through the verifier smart contract. + +We can imagine recursive proofs a [relay race](https://en.wikipedia.org/wiki/Relay_race). The first runner doesn't have to receive the baton from anyone else, as he/she already starts with it. But when his/her turn is over, the next runner needs to receive it, run a bit more, and pass it along. Even though every runner could theoretically verify the baton mid-run (why not? 🏃🔍), only at the end of the race does the referee verify that the whole race is valid. + +::: + +## Some architecture + +As with everything in computer science, there's no one-size-fits all. But there are some patterns that could help understanding and implementing them. To give three examples: + +### Adding some logic to a proof verification + +This would be an approach for something like our guessing game, where proofs are sent back and forth and are verified by each opponent. This circuit would be divided in two sections: + +- A `recursive verification` section, which would be just the call to `std::verify_proof`, and that would be skipped on the first move (since there's no proof to verify) +- A `guessing` section, which is basically the logic part where the actual guessing happens + +In such a situation, and assuming Alice is first, she would skip the first part and try to guess Bob's number. Bob would then verify her proof on the first section of his run, and try to guess Alice's number on the second part, and so on. + +### Aggregating proofs + +In some one-way interaction situations, recursion would allow for aggregation of simple proofs that don't need to be immediately verified on-chain or elsewhere. + +To give a practical example, a barman wouldn't need to verify a "proof-of-age" on-chain every time he serves alcohol to a customer. Instead, the architecture would comprise two circuits: + +- A `main`, non-recursive circuit with some logic +- A `recursive` circuit meant to verify two proofs in one proof + +The customer's proofs would be intermediate, and made on their phones, and the barman could just verify them locally. He would then aggregate them into a final proof sent on-chain (or elsewhere) at the end of the day. + +### Recursively verifying different circuits + +Nothing prevents you from verifying different circuits in a recursive proof, for example: + +- A `circuit1` circuit +- A `circuit2` circuit +- A `recursive` circuit + +In this example, a regulator could verify that taxes were paid for a specific purchase by aggregating both a `payer` circuit (proving that a purchase was made and taxes were paid), and a `receipt` circuit (proving that the payment was received) + +## How fast is it + +At the time of writing, verifying recursive proofs is surprisingly fast. This is because most of the time is spent on generating the verification key that will be used to generate the next proof. So you are able to cache the verification key and reuse it later. + +Currently, Noir JS packages don't expose the functionality of loading proving and verification keys, but that feature exists in the underlying `bb.js` package. + +## How can I try it + +Learn more about using recursion in Nargo and NoirJS in the [how-to guide](../how_to/how-to-recursion.md) and see a full example in [noir-examples](https://github.com/noir-lang/noir-examples). diff --git a/docs/versioned_docs/version-v0.30.0/getting_started/_category_.json b/docs/versioned_docs/version-v0.30.0/getting_started/_category_.json new file mode 100644 index 00000000000..5d694210bbf --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/getting_started/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 0, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.30.0/getting_started/hello_noir/_category_.json b/docs/versioned_docs/version-v0.30.0/getting_started/hello_noir/_category_.json new file mode 100644 index 00000000000..23b560f610b --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/getting_started/hello_noir/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 1, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.30.0/getting_started/hello_noir/index.md b/docs/versioned_docs/version-v0.30.0/getting_started/hello_noir/index.md new file mode 100644 index 00000000000..743c4d8d634 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/getting_started/hello_noir/index.md @@ -0,0 +1,142 @@ +--- +title: Creating a Project +description: + Learn how to create and verify your first Noir program using Nargo, a programming language for + zero-knowledge proofs. +keywords: + [ + Nargo, + Noir, + zero-knowledge proofs, + programming language, + create Noir program, + verify Noir program, + step-by-step guide, + ] +sidebar_position: 1 + +--- + +Now that we have installed Nargo, it is time to make our first hello world program! + +## Create a Project Directory + +Noir code can live anywhere on your computer. Let us create a _projects_ folder in the home +directory to house our Noir programs. + +For Linux, macOS, and Windows PowerShell, create the directory and change directory into it by +running: + +```sh +mkdir ~/projects +cd ~/projects +``` + +## Create Our First Nargo Project + +Now that we are in the projects directory, create a new Nargo project by running: + +```sh +nargo new hello_world +``` + +> **Note:** `hello_world` can be any arbitrary project name, we are simply using `hello_world` for +> demonstration. +> +> In production, the common practice is to name the project folder as `circuits` for better +> identifiability when sitting alongside other folders in the codebase (e.g. `contracts`, `scripts`, +> `test`). + +A `hello_world` folder would be created. Similar to Rust, the folder houses _src/main.nr_ and +_Nargo.toml_ which contain the source code and environmental options of your Noir program +respectively. + +### Intro to Noir Syntax + +Let us take a closer look at _main.nr_. The default _main.nr_ generated should look like this: + +```rust +fn main(x : Field, y : pub Field) { + assert(x != y); +} +``` + +The first line of the program specifies the program's inputs: + +```rust +x : Field, y : pub Field +``` + +Program inputs in Noir are private by default (e.g. `x`), but can be labeled public using the +keyword `pub` (e.g. `y`). To learn more about private and public values, check the +[Data Types](../../noir/concepts/data_types/index.md) section. + +The next line of the program specifies its body: + +```rust +assert(x != y); +``` + +The Noir syntax `assert` can be interpreted as something similar to constraints in other zk-contract languages. + +For more Noir syntax, check the [Language Concepts](../../noir/concepts/comments.md) chapter. + +## Build In/Output Files + +Change directory into _hello_world_ and build in/output files for your Noir program by running: + +```sh +cd hello_world +nargo check +``` + +Two additional files would be generated in your project directory: + +_Prover.toml_ houses input values, and _Verifier.toml_ houses public values. + +## Prove Our Noir Program + +Now that the project is set up, we can create a proof of correct execution of our Noir program. + +Fill in input values for execution in the _Prover.toml_ file. For example: + +```toml +x = "1" +y = "2" +``` + +Prove the valid execution of your Noir program: + +```sh +nargo prove +``` + +A new folder _proofs_ would then be generated in your project directory, containing the proof file +`.proof`, where the project name is defined in Nargo.toml. + +The _Verifier.toml_ file would also be updated with the public values computed from program +execution (in this case the value of `y`): + +```toml +y = "0x0000000000000000000000000000000000000000000000000000000000000002" +``` + +> **Note:** Values in _Verifier.toml_ are computed as 32-byte hex values. + +## Verify Our Noir Program + +Once a proof is generated, we can verify correct execution of our Noir program by verifying the +proof file. + +Verify your proof by running: + +```sh +nargo verify +``` + +The verification will complete in silence if it is successful. If it fails, it will log the +corresponding error instead. + +Congratulations, you have now created and verified a proof for your very first Noir program! + +In the [next section](./project_breakdown.md), we will go into more detail on each step performed. diff --git a/docs/versioned_docs/version-v0.30.0/getting_started/hello_noir/project_breakdown.md b/docs/versioned_docs/version-v0.30.0/getting_started/hello_noir/project_breakdown.md new file mode 100644 index 00000000000..6160a102c6c --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/getting_started/hello_noir/project_breakdown.md @@ -0,0 +1,199 @@ +--- +title: Project Breakdown +description: + Learn about the anatomy of a Nargo project, including the purpose of the Prover and Verifier TOML + files, and how to prove and verify your program. +keywords: + [Nargo, Nargo project, Prover.toml, Verifier.toml, proof verification, private asset transfer] +sidebar_position: 2 +--- + +This section breaks down our hello world program from the previous section. We elaborate on the project +structure and what the `prove` and `verify` commands did. + +## Anatomy of a Nargo Project + +Upon creating a new project with `nargo new` and building the in/output files with `nargo check` +commands, you would get a minimal Nargo project of the following structure: + + - src + - Prover.toml + - Verifier.toml + - Nargo.toml + +The source directory _src_ holds the source code for your Noir program. By default only a _main.nr_ +file will be generated within it. + +### Prover.toml + +_Prover.toml_ is used for specifying the input values for executing and proving the program. You can specify `toml` files with different names by using the `--prover-name` or `-p` flags, see the [Prover](#provertoml) section below. Optionally you may specify expected output values for prove-time checking as well. + +### Verifier.toml + +_Verifier.toml_ contains public in/output values computed when executing the Noir program. + +### Nargo.toml + +_Nargo.toml_ contains the environmental options of your project. It contains a "package" section and a "dependencies" section. + +Example Nargo.toml: + +```toml +[package] +name = "noir_starter" +type = "bin" +authors = ["Alice"] +compiler_version = "0.9.0" +description = "Getting started with Noir" +entry = "circuit/main.nr" +license = "MIT" + +[dependencies] +ecrecover = {tag = "v0.9.0", git = "https://github.com/colinnielsen/ecrecover-noir.git"} +``` + +Nargo.toml for a [workspace](../../noir/modules_packages_crates/workspaces.md) will look a bit different. For example: + +```toml +[workspace] +members = ["crates/a", "crates/b"] +default-member = "crates/a" +``` + +#### Package section + +The package section defines a number of fields including: + +- `name` (**required**) - the name of the package +- `type` (**required**) - can be "bin", "lib", or "contract" to specify whether its a binary, library or Aztec contract +- `authors` (optional) - authors of the project +- `compiler_version` - specifies the version of the compiler to use. This is enforced by the compiler and follow's [Rust's versioning](https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field), so a `compiler_version = 0.18.0` will enforce Nargo version 0.18.0, `compiler_version = ^0.18.0` will enforce anything above 0.18.0 but below 0.19.0, etc. For more information, see how [Rust handles these operators](https://docs.rs/semver/latest/semver/enum.Op.html) +- `description` (optional) +- `entry` (optional) - a relative filepath to use as the entry point into your package (overrides the default of `src/lib.nr` or `src/main.nr`) +- `backend` (optional) +- `license` (optional) + +#### Dependencies section + +This is where you will specify any dependencies for your project. See the [Dependencies page](../../noir/modules_packages_crates/dependencies.md) for more info. + +`./proofs/` and `./contract/` directories will not be immediately visible until you create a proof or +verifier contract respectively. + +### main.nr + +The _main.nr_ file contains a `main` method, this method is the entry point into your Noir program. + +In our sample program, _main.nr_ looks like this: + +```rust +fn main(x : Field, y : Field) { + assert(x != y); +} +``` + +The parameters `x` and `y` can be seen as the API for the program and must be supplied by the +prover. Since neither `x` nor `y` is marked as public, the verifier does not supply any inputs, when +verifying the proof. + +The prover supplies the values for `x` and `y` in the _Prover.toml_ file. + +As for the program body, `assert` ensures that the condition to be satisfied (e.g. `x != y`) is +constrained by the proof of the execution of said program (i.e. if the condition was not met, the +verifier would reject the proof as an invalid proof). + +### Prover.toml + +The _Prover.toml_ file is a file which the prover uses to supply his witness values(both private and +public). + +In our hello world program the _Prover.toml_ file looks like this: + +```toml +x = "1" +y = "2" +``` + +When the command `nargo prove` is executed, two processes happen: + +1. Noir creates a proof that `x`, which holds the value of `1`, and `y`, which holds the value of `2`, + is not equal. This inequality constraint is due to the line `assert(x != y)`. + +2. Noir creates and stores the proof of this statement in the _proofs_ directory in a file called your-project.proof. So if your project is named "private_voting" (defined in the project Nargo.toml), the proof will be saved at `./proofs/private_voting.proof`. Opening this file will display the proof in hex format. + +#### Arrays of Structs + +The following code shows how to pass an array of structs to a Noir program to generate a proof. + +```rust +// main.nr +struct Foo { + bar: Field, + baz: Field, +} + +fn main(foos: [Foo; 3]) -> pub Field { + foos[2].bar + foos[2].baz +} +``` + +Prover.toml: + +```toml +[[foos]] # foos[0] +bar = 0 +baz = 0 + +[[foos]] # foos[1] +bar = 0 +baz = 0 + +[[foos]] # foos[2] +bar = 1 +baz = 2 +``` + +#### Custom toml files + +You can specify a `toml` file with a different name to use for proving by using the `--prover-name` or `-p` flags. + +This command looks for proof inputs in the default **Prover.toml** and generates the proof and saves it at `./proofs/.proof`: + +```bash +nargo prove +``` + +This command looks for proof inputs in the custom **OtherProver.toml** and generates proof and saves it at `./proofs/.proof`: + +```bash +nargo prove -p OtherProver +``` + +## Verifying a Proof + +When the command `nargo verify` is executed, two processes happen: + +1. Noir checks in the _proofs_ directory for a proof file with the project name (eg. test_project.proof) + +2. If that file is found, the proof's validity is checked + +> **Note:** The validity of the proof is linked to the current Noir program; if the program is +> changed and the verifier verifies the proof, it will fail because the proof is not valid for the +> _modified_ Noir program. + +In production, the prover and the verifier are usually two separate entities. A prover would +retrieve the necessary inputs, execute the Noir program, generate a proof and pass it to the +verifier. The verifier would then retrieve the public inputs, usually from external sources, and +verify the validity of the proof against it. + +Take a private asset transfer as an example: + +A person using a browser as the prover would retrieve private inputs locally (e.g. the user's private key) and +public inputs (e.g. the user's encrypted balance on-chain), compute the transfer, generate a proof +and submit it to the verifier smart contract. + +The verifier contract would then draw the user's encrypted balance directly from the blockchain and +verify the proof submitted against it. If the verification passes, additional functions in the +verifier contract could trigger (e.g. approve the asset transfer). + +Now that you understand the concepts, you'll probably want some editor feedback while you are writing more complex code. diff --git a/docs/versioned_docs/version-v0.30.0/getting_started/installation/_category_.json b/docs/versioned_docs/version-v0.30.0/getting_started/installation/_category_.json new file mode 100644 index 00000000000..0c02fb5d4d7 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/getting_started/installation/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 0, + "label": "Install Nargo", + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.30.0/getting_started/installation/index.md b/docs/versioned_docs/version-v0.30.0/getting_started/installation/index.md new file mode 100644 index 00000000000..4ef86aa5914 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/getting_started/installation/index.md @@ -0,0 +1,48 @@ +--- +title: Nargo Installation +description: + nargo is a command line tool for interacting with Noir programs. This page is a quick guide on how to install Nargo through the most common and easy method, noirup +keywords: [ + Nargo + Noir + Rust + Cargo + Noirup + Installation + Terminal Commands + Version Check + Nightlies + Specific Versions + Branches + Noirup Repository +] +pagination_next: getting_started/hello_noir/index +--- + +`nargo` is the one-stop-shop for almost everything related with Noir. The name comes from our love for Rust and its package manager `cargo`. + +With `nargo`, you can start new projects, compile, execute, prove, verify, test, generate solidity contracts, and do pretty much all that is available in Noir. + +Similarly to `rustup`, we also maintain an easy installation method that covers most machines: `noirup`. + +## Installing Noirup + +Open a terminal on your machine, and write: + +```bash +curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash +``` + +Close the terminal, open another one, and run + +```bash +noirup +``` + +Done. That's it. You should have the latest version working. You can check with `nargo --version`. + +You can also install nightlies, specific versions +or branches. Check out the [noirup repository](https://github.com/noir-lang/noirup) for more +information. + +Now we're ready to start working on [our first Noir program!](../hello_noir/index.md) diff --git a/docs/versioned_docs/version-v0.30.0/getting_started/installation/other_install_methods.md b/docs/versioned_docs/version-v0.30.0/getting_started/installation/other_install_methods.md new file mode 100644 index 00000000000..3634723562b --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/getting_started/installation/other_install_methods.md @@ -0,0 +1,102 @@ +--- +title: Alternative Installations +description: There are different ways to install Nargo, the one-stop shop and command-line tool for developing Noir programs. This guide explains how to specify which version to install when using noirup, and using WSL for windows. +keywords: [ + Installation + Nargo + Noirup + Binaries + Compiling from Source + WSL for Windows + macOS + Linux + Nix + Direnv + Uninstalling Nargo + ] +sidebar_position: 1 +--- + +## Encouraged Installation Method: Noirup + +Noirup is the endorsed method for installing Nargo, streamlining the process of fetching binaries or compiling from source. It supports a range of options to cater to your specific needs, from nightly builds and specific versions to compiling from various sources. + +### Installing Noirup + +First, ensure you have `noirup` installed: + +```sh +curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash +``` + +### Fetching Binaries + +With `noirup`, you can easily switch between different Nargo versions, including nightly builds: + +- **Nightly Version**: Install the latest nightly build. + + ```sh + noirup --version nightly + ``` + +- **Specific Version**: Install a specific version of Nargo. + ```sh + noirup --version + ``` + +### Compiling from Source + +`noirup` also enables compiling Nargo from various sources: + +- **From a Specific Branch**: Install from the latest commit on a branch. + + ```sh + noirup --branch + ``` + +- **From a Fork**: Install from the main branch of a fork. + + ```sh + noirup --repo + ``` + +- **From a Specific Branch in a Fork**: Install from a specific branch in a fork. + + ```sh + noirup --repo --branch + ``` + +- **From a Specific Pull Request**: Install from a specific PR. + + ```sh + noirup --pr + ``` + +- **From a Specific Commit**: Install from a specific commit. + + ```sh + noirup -C + ``` + +- **From Local Source**: Compile and install from a local directory. + ```sh + noirup --path ./path/to/local/source + ``` + +## Installation on Windows + +The default backend for Noir (Barretenberg) doesn't provide Windows binaries at this time. For that reason, Noir cannot be installed natively. However, it is available by using Windows Subsystem for Linux (WSL). + +Step 1: Follow the instructions [here](https://learn.microsoft.com/en-us/windows/wsl/install) to install and run WSL. + +step 2: Follow the [Noirup instructions](#encouraged-installation-method-noirup). + +## Uninstalling Nargo + +If you installed Nargo with `noirup`, you can uninstall Nargo by removing the files in `~/.nargo`, `~/nargo`, and `~/noir_cache`. This ensures that all installed binaries, configurations, and cache related to Nargo are fully removed from your system. + +```bash +rm -r ~/.nargo +rm -r ~/nargo +rm -r ~/noir_cache +``` diff --git a/docs/versioned_docs/version-v0.30.0/getting_started/tooling/noir_codegen.md b/docs/versioned_docs/version-v0.30.0/getting_started/tooling/noir_codegen.md new file mode 100644 index 00000000000..d65151da0ab --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/getting_started/tooling/noir_codegen.md @@ -0,0 +1,113 @@ +--- +title: Noir Codegen for TypeScript +description: Learn how to use Noir codegen to generate TypeScript bindings +keywords: [Nargo, Noir, compile, TypeScript] +sidebar_position: 2 +--- + +When using TypeScript, it is extra work to interpret Noir program outputs in a type-safe way. Third party libraries may exist for popular Noir programs, but they are either hard to find or unmaintained. + +Now you can generate TypeScript bindings for your Noir programs in two steps: +1. Exporting Noir functions using `nargo export` +2. Using the TypeScript module `noir_codegen` to generate TypeScript binding + +**Note:** you can only export functions from a Noir *library* (not binary or contract program types). + +## Installation + +### Your TypeScript project + +If you don't already have a TypeScript project you can add the module with `yarn` (or `npm`), then initialize it: + +```bash +yarn add typescript -D +npx tsc --init +``` + +### Add TypeScript module - `noir_codegen` + +The following command will add the module to your project's devDependencies: + +```bash +yarn add @noir-lang/noir_codegen -D +``` + +### Nargo library +Make sure you have Nargo, v0.25.0 or greater, installed. If you don't, follow the [installation guide](../installation/index.md). + +If you're in a new project, make a `circuits` folder and create a new Noir library: + +```bash +mkdir circuits && cd circuits +nargo new --lib myNoirLib +``` + +## Usage + +### Export ABI of specified functions + +First go to the `.nr` files in your Noir library, and add the `#[export]` macro to each function that you want to use in TypeScript. + +```rust +#[export] +fn your_function(... +``` + +From your Noir library (where `Nargo.toml` is), run the following command: + +```bash +nargo export +``` + +You will now have an `export` directory with a .json file per exported function. + +You can also specify the directory of Noir programs using `--program-dir`, for example: + +```bash +nargo export --program-dir=./circuits/myNoirLib +``` + +### Generate TypeScript bindings from exported functions + +To use the `noir-codegen` package we added to the TypeScript project: + +```bash +yarn noir-codegen ./export/your_function.json +``` + +This creates an `exports` directory with an `index.ts` file containing all exported functions. + +**Note:** adding `--out-dir` allows you to specify an output dir for your TypeScript bindings to go. Eg: + +```bash +yarn noir-codegen ./export/*.json --out-dir ./path/to/output/dir +``` + +## Example .nr function to .ts output + +Consider a Noir library with this function: + +```rust +#[export] +fn not_equal(x: Field, y: Field) -> bool { + x != y +} +``` + +After the export and codegen steps, you should have an `index.ts` like: + +```typescript +export type Field = string; + + +export const is_equal_circuit: CompiledCircuit = {"abi":{"parameters":[{"name":"x","type":{"kind":"field"},"visibility":"private"},{"name":"y","type":{"kind":"field"},"visibility":"private"}],"param_witnesses":{"x":[{"start":0,"end":1}],"y":[{"start":1,"end":2}]},"return_type":{"abi_type":{"kind":"boolean"},"visibility":"private"},"return_witnesses":[4]},"bytecode":"H4sIAAAAAAAA/7WUMQ7DIAxFQ0Krrr2JjSGYLVcpKrn/CaqqDQN12WK+hPBgmWd/wEyHbF1SS923uhOs3pfoChI+wKXMAXzIKyNj4PB0TFTYc0w5RUjoqeAeEu1wqK0F54RGkWvW44LPzExnlkbMEs4JNZmN8PxS42uHv82T8a3Jeyn2Ks+VLPcO558HmyLMCDOXAXXtpPt4R/Rt9T36ss6dS9HGPx/eG17nGegKBQAA"}; + +export async function is_equal(x: Field, y: Field, foreignCallHandler?: ForeignCallHandler): Promise { + const program = new Noir(is_equal_circuit); + const args: InputMap = { x, y }; + const { returnValue } = await program.execute(args, foreignCallHandler); + return returnValue as boolean; +} +``` + +Now the `is_equal()` function and relevant types are readily available for use in TypeScript. diff --git a/docs/versioned_docs/version-v0.30.0/how_to/_category_.json b/docs/versioned_docs/version-v0.30.0/how_to/_category_.json new file mode 100644 index 00000000000..23b560f610b --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/how_to/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 1, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.30.0/how_to/debugger/_category_.json b/docs/versioned_docs/version-v0.30.0/how_to/debugger/_category_.json new file mode 100644 index 00000000000..cc2cbb1c253 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/how_to/debugger/_category_.json @@ -0,0 +1,6 @@ +{ + "label": "Debugging", + "position": 5, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.30.0/how_to/debugger/debugging_with_the_repl.md b/docs/versioned_docs/version-v0.30.0/how_to/debugger/debugging_with_the_repl.md new file mode 100644 index 00000000000..09e5bae68ad --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/how_to/debugger/debugging_with_the_repl.md @@ -0,0 +1,164 @@ +--- +title: Using the REPL Debugger +description: + Step by step guide on how to debug your Noir circuits with the REPL Debugger. +keywords: + [ + Nargo, + Noir CLI, + Noir Debugger, + REPL, + ] +sidebar_position: 1 +--- + +#### Pre-requisites + +In order to use the REPL debugger, first you need to install recent enough versions of Nargo and vscode-noir. + +## Debugging a simple circuit + +Let's debug a simple circuit: + +```rust +fn main(x : Field, y : pub Field) { + assert(x != y); +} +``` + +To start the REPL debugger, using a terminal, go to a Noir circuit's home directory. Then: + +`$ nargo debug` + +You should be seeing this in your terminal: + +``` +[main] Starting debugger +At ~/noir-examples/recursion/circuits/main/src/main.nr:1:9 + 1 -> fn main(x : Field, y : pub Field) { + 2 assert(x != y); + 3 } +> +``` + +The debugger displays the current Noir code location, and it is now waiting for us to drive it. + +Let's first take a look at the available commands. For that we'll use the `help` command. + +``` +> help +Available commands: + + opcodes display ACIR opcodes + into step into to the next opcode + next step until a new source location is reached + out step until a new source location is reached + and the current stack frame is finished + break LOCATION:OpcodeLocation add a breakpoint at an opcode location + over step until a new source location is reached + without diving into function calls + restart restart the debugging session + delete LOCATION:OpcodeLocation delete breakpoint at an opcode location + witness show witness map + witness index:u32 display a single witness from the witness map + witness index:u32 value:String update a witness with the given value + memset index:usize value:String update a memory cell with the given + value + continue continue execution until the end of the + program + vars show variable values available at this point + in execution + stacktrace display the current stack trace + memory show memory (valid when executing unconstrained code) + step step to the next ACIR opcode + +Other commands: + + help Show this help message + quit Quit repl + +``` + +Some commands operate only for unconstrained functions, such as `memory` and `memset`. If you try to use them while execution is paused at an ACIR opcode, the debugger will simply inform you that you are not executing unconstrained code: + +``` +> memory +Unconstrained VM memory not available +> +``` + +Before continuing, we can take a look at the initial witness map: + +``` +> witness +_0 = 1 +_1 = 2 +> +``` + +Cool, since `x==1`, `y==2`, and we want to check that `x != y`, our circuit should succeed. At this point we could intervene and use the witness setter command to change one of the witnesses. Let's set `y=3`, then back to 2, so we don't affect the expected result: + +``` +> witness +_0 = 1 +_1 = 2 +> witness 1 3 +_1 = 3 +> witness +_0 = 1 +_1 = 3 +> witness 1 2 +_1 = 2 +> witness +_0 = 1 +_1 = 2 +> +``` + +Now we can inspect the current state of local variables. For that we use the `vars` command. + +``` +> vars +> +``` + +We currently have no vars in context, since we are at the entry point of the program. Let's use `next` to execute until the next point in the program. + +``` +> vars +> next +At ~/noir-examples/recursion/circuits/main/src/main.nr:1:20 + 1 -> fn main(x : Field, y : pub Field) { + 2 assert(x != y); + 3 } +> vars +x:Field = 0x01 +``` + +As a result of stepping, the variable `x`, whose initial value comes from the witness map, is now in context and returned by `vars`. + +``` +> next + 1 fn main(x : Field, y : pub Field) { + 2 -> assert(x != y); + 3 } +> vars +y:Field = 0x02 +x:Field = 0x01 +``` + +Stepping again we can finally see both variables and their values. And now we can see that the next assertion should succeed. + +Let's continue to the end: + +``` +> continue +(Continuing execution...) +Finished execution +> q +[main] Circuit witness successfully solved +``` + +Upon quitting the debugger after a solved circuit, the resulting circuit witness gets saved, equivalent to what would happen if we had run the same circuit with `nargo execute`. + +We just went through the basics of debugging using Noir REPL debugger. For a comprehensive reference, check out [the reference page](../../reference/debugger/debugger_repl.md). diff --git a/docs/versioned_docs/version-v0.30.0/how_to/debugger/debugging_with_vs_code.md b/docs/versioned_docs/version-v0.30.0/how_to/debugger/debugging_with_vs_code.md new file mode 100644 index 00000000000..a5858c1a5eb --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/how_to/debugger/debugging_with_vs_code.md @@ -0,0 +1,68 @@ +--- +title: Using the VS Code Debugger +description: + Step by step guide on how to debug your Noir circuits with the VS Code Debugger configuration and features. +keywords: + [ + Nargo, + Noir CLI, + Noir Debugger, + VS Code, + IDE, + ] +sidebar_position: 0 +--- + +This guide will show you how to use VS Code with the vscode-noir extension to debug a Noir project. + +#### Pre-requisites + +- Nargo +- vscode-noir +- A Noir project with a `Nargo.toml`, `Prover.toml` and at least one Noir (`.nr`) containing an entry point function (typically `main`). + +## Running the debugger + +The easiest way to start debugging is to open the file you want to debug, and press `F5`. This will cause the debugger to launch, using your `Prover.toml` file as input. + +You should see something like this: + +![Debugger launched](@site/static/img/debugger/1-started.png) + +Let's inspect the state of the program. For that, we open VS Code's _Debug pane_. Look for this icon: + +![Debug pane icon](@site/static/img/debugger/2-icon.png) + +You will now see two categories of variables: Locals and Witness Map. + +![Debug pane expanded](@site/static/img/debugger/3-debug-pane.png) + +1. **Locals**: variables of your program. At this point in execution this section is empty, but as we step through the code it will get populated by `x`, `result`, `digest`, etc. + +2. **Witness map**: these are initially populated from your project's `Prover.toml` file. In this example, they will be used to populate `x` and `result` at the beginning of the `main` function. + +Most of the time you will probably be focusing mostly on locals, as they represent the high level state of your program. + +You might be interested in inspecting the witness map in case you are trying to solve a really low level issue in the compiler or runtime itself, so this concerns mostly advanced or niche users. + +Let's step through the program, by using the debugger buttons or their corresponding keyboard shortcuts. + +![Debugger buttons](@site/static/img/debugger/4-debugger-buttons.png) + +Now we can see in the variables pane that there's values for `digest`, `result` and `x`. + +![Inspecting locals](@site/static/img/debugger/5-assert.png) + +We can also inspect the values of variables by directly hovering on them on the code. + +![Hover locals](@site/static/img/debugger/6-hover.png) + +Let's set a break point at the `keccak256` function, so we can continue execution up to the point when it's first invoked without having to go one step at a time. + +We just need to click the to the right of the line number 18. Once the breakpoint appears, we can click the `continue` button or use its corresponding keyboard shortcut (`F5` by default). + +![Breakpoint](@site/static/img/debugger/7-break.png) + +Now we are debugging the `keccak256` function, notice the _Call Stack pane_ at the lower right. This lets us inspect the current call stack of our process. + +That covers most of the current debugger functionalities. Check out [the reference](../../reference/debugger/debugger_vscode.md) for more details on how to configure the debugger. \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.30.0/how_to/how-to-oracles.md b/docs/versioned_docs/version-v0.30.0/how_to/how-to-oracles.md new file mode 100644 index 00000000000..8cf8035a5c4 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/how_to/how-to-oracles.md @@ -0,0 +1,276 @@ +--- +title: How to use Oracles +description: Learn how to use oracles in your Noir program with examples in both Nargo and NoirJS. This guide also covers writing a JSON RPC server and providing custom foreign call handlers for NoirJS. +keywords: + - Noir Programming + - Oracles + - Nargo + - NoirJS + - JSON RPC Server + - Foreign Call Handlers +sidebar_position: 1 +--- + +This guide shows you how to use oracles in your Noir program. For the sake of clarity, it assumes that: + +- You have read the [explainer on Oracles](../explainers/explainer-oracle.md) and are comfortable with the concept. +- You have a Noir program to add oracles to. You can create one using the [vite-hardhat starter](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat) as a boilerplate. +- You understand the concept of a JSON-RPC server. Visit the [JSON-RPC website](https://www.jsonrpc.org/) if you need a refresher. +- You are comfortable with server-side JavaScript (e.g. Node.js, managing packages, etc.). + +For reference, you can find the snippets used in this tutorial on the [Aztec DevRel Repository](https://github.com/AztecProtocol/dev-rel/tree/main/code-snippets/how-to-oracles). + +## Rundown + +This guide has 3 major steps: + +1. How to modify our Noir program to make use of oracle calls as unconstrained functions +2. How to write a JSON RPC Server to resolve these oracle calls with Nargo +3. How to use them in Nargo and how to provide a custom resolver in NoirJS + +## Step 1 - Modify your Noir program + +An oracle is defined in a Noir program by defining two methods: + +- An unconstrained method - This tells the compiler that it is executing an [unconstrained functions](../noir/concepts//unconstrained.md). +- A decorated oracle method - This tells the compiler that this method is an RPC call. + +An example of an oracle that returns a `Field` would be: + +```rust +#[oracle(getSqrt)] +unconstrained fn sqrt(number: Field) -> Field { } + +unconstrained fn get_sqrt(number: Field) -> Field { + sqrt(number) +} +``` + +In this example, we're wrapping our oracle function in a unconstrained method, and decorating it with `oracle(getSqrt)`. We can then call the unconstrained function as we would call any other function: + +```rust +fn main(input: Field) { + let sqrt = get_sqrt(input); +} +``` + +In the next section, we will make this `getSqrt` (defined on the `sqrt` decorator) be a method of the RPC server Noir will use. + +:::danger + +As explained in the [Oracle Explainer](../explainers/explainer-oracle.md), this `main` function is unsafe unless you constrain its return value. For example: + +```rust +fn main(input: Field) { + let sqrt = get_sqrt(input); + assert(sqrt.pow_32(2) as u64 == input as u64); // <---- constrain the return of an oracle! +} +``` + +::: + +:::info + +Currently, oracles only work with single params or array params. For example: + +```rust +#[oracle(getSqrt)] +unconstrained fn sqrt([Field; 2]) -> [Field; 2] { } +``` + +::: + +## Step 2 - Write an RPC server + +Brillig will call *one* RPC server. Most likely you will have to write your own, and you can do it in whatever language you prefer. In this guide, we will do it in Javascript. + +Let's use the above example of an oracle that consumes an array with two `Field` and returns their square roots: + +```rust +#[oracle(getSqrt)] +unconstrained fn sqrt(input: [Field; 2]) -> [Field; 2] { } + +unconstrained fn get_sqrt(input: [Field; 2]) -> [Field; 2] { + sqrt(input) +} + +fn main(input: [Field; 2]) { + let sqrt = get_sqrt(input); + assert(sqrt[0].pow_32(2) as u64 == input[0] as u64); + assert(sqrt[1].pow_32(2) as u64 == input[1] as u64); +} +``` + +:::info + +Why square root? + +In general, computing square roots is computationally more expensive than multiplications, which takes a toll when speaking about ZK applications. In this case, instead of calculating the square root in Noir, we are using our oracle to offload that computation to be made in plain. In our circuit we can simply multiply the two values. + +::: + +Now, we should write the correspondent RPC server, starting with the [default JSON-RPC 2.0 boilerplate](https://www.npmjs.com/package/json-rpc-2.0#example): + +```js +import { JSONRPCServer } from "json-rpc-2.0"; +import express from "express"; +import bodyParser from "body-parser"; + +const app = express(); +app.use(bodyParser.json()); + +const server = new JSONRPCServer(); +app.post("/", (req, res) => { + const jsonRPCRequest = req.body; + server.receive(jsonRPCRequest).then((jsonRPCResponse) => { + if (jsonRPCResponse) { + res.json(jsonRPCResponse); + } else { + res.sendStatus(204); + } + }); +}); + +app.listen(5555); +``` + +Now, we will add our `getSqrt` method, as expected by the `#[oracle(getSqrt)]` decorator in our Noir code. It maps through the params array and returns their square roots: + +```js +server.addMethod("getSqrt", async (params) => { + const values = params[0].Array.map((field) => { + return `${Math.sqrt(parseInt(field, 16))}`; + }); + return { values: [{ Array: values }] }; +}); +``` + +:::tip + +Brillig expects an object with an array of values. Each value is an object declaring to be `Single` or `Array` and returning a field element *as a string*. For example: + +```json +{ "values": [{ "Array": ["1", "2"] }]} +{ "values": [{ "Single": "1" }]} +{ "values": [{ "Single": "1" }, { "Array": ["1", "2"] }]} +``` + +If you're using Typescript, the following types may be helpful in understanding the expected return value and making sure they're easy to follow: + +```js +interface SingleForeignCallParam { + Single: string, +} + +interface ArrayForeignCallParam { + Array: string[], +} + +type ForeignCallParam = SingleForeignCallParam | ArrayForeignCallParam; + +interface ForeignCallResult { + values: ForeignCallParam[], +} +``` + +::: + +## Step 3 - Usage with Nargo + +Using the [`nargo` CLI tool](../getting_started/installation/index.md), you can use oracles in the `nargo test`, `nargo execute` and `nargo prove` commands by passing a value to `--oracle-resolver`. For example: + +```bash +nargo test --oracle-resolver http://localhost:5555 +``` + +This tells `nargo` to use your RPC Server URL whenever it finds an oracle decorator. + +## Step 4 - Usage with NoirJS + +In a JS environment, an RPC server is not strictly necessary, as you may want to resolve your oracles without needing any JSON call at all. NoirJS simply expects that you pass a callback function when you generate proofs, and that callback function can be anything. + +For example, if your Noir program expects the host machine to provide CPU pseudo-randomness, you could simply pass it as the `foreignCallHandler`. You don't strictly need to create an RPC server to serve pseudo-randomness, as you may as well get it directly in your app: + +```js +const foreignCallHandler = (name, inputs) => crypto.randomBytes(16) // etc + +await noir.generateProof(inputs, foreignCallHandler) +``` + +As one can see, in NoirJS, the [`foreignCallHandler`](../reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md) function simply means "a callback function that returns a value of type [`ForeignCallOutput`](../reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md). It doesn't have to be an RPC call like in the case for Nargo. + +:::tip + +Does this mean you don't have to write an RPC server like in [Step #2](#step-2---write-an-rpc-server)? + +You don't technically have to, but then how would you run `nargo test` or `nargo prove`? To use both `Nargo` and `NoirJS` in your development flow, you will have to write a JSON RPC server. + +::: + +In this case, let's make `foreignCallHandler` call the JSON RPC Server we created in [Step #2](#step-2---write-an-rpc-server), by making it a JSON RPC Client. + +For example, using the same `getSqrt` program in [Step #1](#step-1---modify-your-noir-program) (comments in the code): + +```js +import { JSONRPCClient } from "json-rpc-2.0"; + +// declaring the JSONRPCClient +const client = new JSONRPCClient((jsonRPCRequest) => { +// hitting the same JSON RPC Server we coded above + return fetch("http://localhost:5555", { + method: "POST", + headers: { + "content-type": "application/json", + }, + body: JSON.stringify(jsonRPCRequest), + }).then((response) => { + if (response.status === 200) { + return response + .json() + .then((jsonRPCResponse) => client.receive(jsonRPCResponse)); + } else if (jsonRPCRequest.id !== undefined) { + return Promise.reject(new Error(response.statusText)); + } + }); +}); + +// declaring a function that takes the name of the foreign call (getSqrt) and the inputs +const foreignCallHandler = async (name, input) => { + // notice that the "inputs" parameter contains *all* the inputs + // in this case we to make the RPC request with the first parameter "numbers", which would be input[0] + const oracleReturn = await client.request(name, [ + { Array: input[0].map((i) => i.toString("hex")) }, + ]); + return [oracleReturn.values[0].Array]; +}; + +// the rest of your NoirJS code +const input = { input: [4, 16] }; +const { witness } = await noir.execute(numbers, foreignCallHandler); +``` + +:::tip + +If you're in a NoirJS environment running your RPC server together with a frontend app, you'll probably hit a familiar problem in full-stack development: requests being blocked by [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) policy. For development only, you can simply install and use the [`cors` npm package](https://www.npmjs.com/package/cors) to get around the problem: + +```bash +yarn add cors +``` + +and use it as a middleware: + +```js +import cors from "cors"; + +const app = express(); +app.use(cors()) +``` + +::: + +## Conclusion + +Hopefully by the end of this guide, you should be able to: + +- Write your own logic around Oracles and how to write a JSON RPC server to make them work with your Nargo commands. +- Provide custom foreign call handlers for NoirJS. diff --git a/docs/versioned_docs/version-v0.30.0/how_to/how-to-recursion.md b/docs/versioned_docs/version-v0.30.0/how_to/how-to-recursion.md new file mode 100644 index 00000000000..4c45bb87ae2 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/how_to/how-to-recursion.md @@ -0,0 +1,179 @@ +--- +title: How to use recursion on NoirJS +description: Learn how to implement recursion with NoirJS, a powerful tool for creating smart contracts on the EVM blockchain. This guide assumes familiarity with NoirJS, solidity verifiers, and the Barretenberg proving backend. Discover how to generate both final and intermediate proofs using `noir_js` and `backend_barretenberg`. +keywords: + [ + "NoirJS", + "EVM blockchain", + "smart contracts", + "recursion", + "solidity verifiers", + "Barretenberg backend", + "noir_js", + "backend_barretenberg", + "intermediate proofs", + "final proofs", + "nargo compile", + "json import", + "recursive circuit", + "recursive app" + ] +sidebar_position: 1 +--- + +This guide shows you how to use recursive proofs in your NoirJS app. For the sake of clarity, it is assumed that: + +- You already have a NoirJS app. If you don't, please visit the [NoirJS tutorial](../tutorials/noirjs_app.md) and the [reference](../reference/NoirJS/noir_js/index.md). +- You are familiar with what are recursive proofs and you have read the [recursion explainer](../explainers/explainer-recursion.md) +- You already built a recursive circuit following [the reference](../noir/standard_library/recursion.md), and understand how it works. + +It is also assumed that you're not using `noir_wasm` for compilation, and instead you've used [`nargo compile`](../reference/nargo_commands.md) to generate the `json` you're now importing into your project. However, the guide should work just the same if you're using `noir_wasm`. + +:::info + +As you've read in the [explainer](../explainers/explainer-recursion.md), a recursive proof is an intermediate proof. This means that it doesn't necessarily generate the final step that makes it verifiable in a smart contract. However, it is easy to verify within another circuit. + +While "standard" usage of NoirJS packages abstracts final proofs, it currently lacks the necessary interface to abstract away intermediate proofs. This means that these proofs need to be created by using the backend directly. + +In short: + +- `noir_js` generates *only* final proofs +- `backend_barretenberg` generates both types of proofs + +::: + +In a standard recursive app, you're also dealing with at least two circuits. For the purpose of this guide, we will assume the following: + +- `main`: a circuit of type `assert(x != y)`, where `main` is marked with a `#[recursive]` attribute. This attribute states that the backend should generate proofs that are friendly for verification within another circuit. +- `recursive`: a circuit that verifies `main` + +For a full example on how recursive proofs work, please refer to the [noir-examples](https://github.com/noir-lang/noir-examples) repository. We will *not* be using it as a reference for this guide. + +## Step 1: Setup + +In a common NoirJS app, you need to instantiate a backend with something like `const backend = new Backend(circuit)`. Then you feed it to the `noir_js` interface. + +For recursion, this doesn't happen, and the only need for `noir_js` is only to `execute` a circuit and get its witness and return value. Everything else is not interfaced, so it needs to happen on the `backend` object. + +It is also recommended that you instantiate the backend with as many threads as possible, to allow for maximum concurrency: + +```js +const backend = new Backend(circuit, { threads: 8 }) +``` + +:::tip +You can use the [`os.cpus()`](https://nodejs.org/api/os.html#oscpus) object in `nodejs` or [`navigator.hardwareConcurrency`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/hardwareConcurrency) on the browser to make the most out of those glorious cpu cores +::: + +## Step 2: Generating the witness and the proof for `main` + +After instantiating the backend, you should also instantiate `noir_js`. We will use it to execute the circuit and get the witness. + +```js +const noir = new Noir(circuit, backend) +const { witness } = noir.execute(input) +``` + +With this witness, you are now able to generate the intermediate proof for the main circuit: + +```js +const { proof, publicInputs } = await backend.generateProof(witness) +``` + +:::warning + +Always keep in mind what is actually happening on your development process, otherwise you'll quickly become confused about what circuit we are actually running and why! + +In this case, you can imagine that Alice (running the `main` circuit) is proving something to Bob (running the `recursive` circuit), and Bob is verifying her proof within his proof. + +With this in mind, it becomes clear that our intermediate proof is the one *meant to be verified within another circuit*, so it must be Alice's. Actually, the only final proof in this theoretical scenario would be the last one, sent on-chain. + +::: + +## Step 3 - Verification and proof artifacts + +Optionally, you are able to verify the intermediate proof: + +```js +const verified = await backend.verifyProof({ proof, publicInputs }) +``` + +This can be useful to make sure our intermediate proof was correctly generated. But the real goal is to do it within another circuit. For that, we need to generate recursive proof artifacts that will be passed to the circuit that is verifying the proof we just generated. Instead of passing the proof and verification key as a byte array, we pass them as fields which makes it cheaper to verify in a circuit: + +```js +const { proofAsFields, vkAsFields, vkHash } = await backend.generateRecursiveProofArtifacts( { publicInputs, proof }, publicInputsCount) +``` + +This call takes the public inputs and the proof, but also the public inputs count. While this is easily retrievable by simply counting the `publicInputs` length, the backend interface doesn't currently abstract it away. + +:::info + +The `proofAsFields` has a constant size `[Field; 93]` and verification keys in Barretenberg are always `[Field; 114]`. + +::: + +:::warning + +One common mistake is to forget *who* makes this call. + +In a situation where Alice is generating the `main` proof, if she generates the proof artifacts and sends them to Bob, which gladly takes them as true, this would mean Alice could prove anything! + +Instead, Bob needs to make sure *he* extracts the proof artifacts, using his own instance of the `main` circuit backend. This way, Alice has to provide a valid proof for the correct `main` circuit. + +::: + +## Step 4 - Recursive proof generation + +With the artifacts, generating a recursive proof is no different from a normal proof. You simply use the `backend` (with the recursive circuit) to generate it: + +```js +const recursiveInputs = { + verification_key: vkAsFields, // array of length 114 + proof: proofAsFields, // array of length 93 + size of public inputs + publicInputs: [mainInput.y], // using the example above, where `y` is the only public input + key_hash: vkHash, +} + +const { witness, returnValue } = noir.execute(recursiveInputs) // we're executing the recursive circuit now! +const { proof, publicInputs } = backend.generateProof(witness) +const verified = backend.verifyProof({ proof, publicInputs }) +``` + +You can obviously chain this proof into another proof. In fact, if you're using recursive proofs, you're probably interested of using them this way! + +:::tip + +Managing circuits and "who does what" can be confusing. To make sure your naming is consistent, you can keep them in an object. For example: + +```js +const circuits = { + main: mainJSON, + recursive: recursiveJSON +} +const backends = { + main: new BarretenbergBackend(circuits.main), + recursive: new BarretenbergBackend(circuits.recursive) +} +const noir_programs = { + main: new Noir(circuits.main, backends.main), + recursive: new Noir(circuits.recursive, backends.recursive) +} +``` + +This allows you to neatly call exactly the method you want without conflicting names: + +```js +// Alice runs this 👇 +const { witness: mainWitness } = await noir_programs.main.execute(input) +const proof = await backends.main.generateProof(mainWitness) + +// Bob runs this 👇 +const verified = await backends.main.verifyProof(proof) +const { proofAsFields, vkAsFields, vkHash } = await backends.main.generateRecursiveProofArtifacts( + proof, + numPublicInputs, +); +const recursiveProof = await noir_programs.recursive.generateProof(recursiveInputs) +``` + +::: diff --git a/docs/versioned_docs/version-v0.30.0/how_to/how-to-solidity-verifier.md b/docs/versioned_docs/version-v0.30.0/how_to/how-to-solidity-verifier.md new file mode 100644 index 00000000000..e3c7c1065da --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/how_to/how-to-solidity-verifier.md @@ -0,0 +1,231 @@ +--- +title: Generate a Solidity Verifier +description: + Learn how to run the verifier as a smart contract on the blockchain. Compile a Solidity verifier + contract for your Noir program and deploy it on any EVM blockchain acting as a verifier smart + contract. Read more to find out +keywords: + [ + solidity verifier, + smart contract, + blockchain, + compiler, + plonk_vk.sol, + EVM blockchain, + verifying Noir programs, + proving backend, + Barretenberg, + ] +sidebar_position: 0 +pagination_next: tutorials/noirjs_app +--- + +Noir has the ability to generate a verifier contract in Solidity, which can be deployed in many EVM-compatible blockchains such as Ethereum. + +This allows for a powerful feature set, as one can make use of the conciseness and the privacy provided by Noir in an immutable ledger. Applications can range from simple P2P guessing games, to complex private DeFi interactions. + +This guide shows you how to generate a Solidity Verifier and deploy it on the [Remix IDE](https://remix.ethereum.org/). It is assumed that: + +- You are comfortable with the Solidity programming language and understand how contracts are deployed on the Ethereum network +- You have Noir installed and you have a Noir program. If you don't, [get started](../getting_started/installation/index.md) with Nargo and the example Hello Noir circuit +- You are comfortable navigating RemixIDE. If you aren't or you need a refresher, you can find some video tutorials [here](https://www.youtube.com/channel/UCjTUPyFEr2xDGN6Cg8nKDaA) that could help you. + +## Rundown + +Generating a Solidity Verifier contract is actually a one-command process. However, compiling it and deploying it can have some caveats. Here's the rundown of this guide: + +1. How to generate a solidity smart contract +2. How to compile the smart contract in the RemixIDE +3. How to deploy it to a testnet + +## Step 1 - Generate a contract + +This is by far the most straight-forward step. Just run: + +```sh +nargo codegen-verifier +``` + +A new `contract` folder would then be generated in your project directory, containing the Solidity +file `plonk_vk.sol`. It can be deployed to any EVM blockchain acting as a verifier smart contract. + +:::info + +It is possible to generate verifier contracts of Noir programs for other smart contract platforms as long as the proving backend supplies an implementation. + +Barretenberg, the default proving backend for Nargo, supports generation of verifier contracts, for the time being these are only in Solidity. +::: + +## Step 2 - Compiling + +We will mostly skip the details of RemixIDE, as the UI can change from version to version. For now, we can just open +Remix and create a blank workspace. + +![Create Workspace](@site/static/img/how-tos/solidity_verifier_1.png) + +We will create a new file to contain the contract Nargo generated, and copy-paste its content. + +:::warning + +You'll likely see a warning advising you to not trust pasted code. While it is an important warning, it is irrelevant in the context of this guide and can be ignored. We will not be deploying anywhere near a mainnet. + +::: + +To compile our the verifier, we can navigate to the compilation tab: + +![Compilation Tab](@site/static/img/how-tos/solidity_verifier_2.png) + +Remix should automatically match a suitable compiler version. However, hitting the "Compile" button will most likely generate a "Stack too deep" error: + +![Stack too deep](@site/static/img/how-tos/solidity_verifier_3.png) + +This is due to the verify function needing to put many variables on the stack, but enabling the optimizer resolves the issue. To do this, let's open the "Advanced Configurations" tab and enable optimization. The default 200 runs will suffice. + +:::info + +This time we will see a warning about an unused function parameter. This is expected, as the `verify` function doesn't use the `_proof` parameter inside a solidity block, it is loaded from calldata and used in assembly. + +::: + +![Compilation success](@site/static/img/how-tos/solidity_verifier_4.png) + +## Step 3 - Deploying + +At this point we should have a compiled contract read to deploy. If we navigate to the deploy section in Remix, we will see many different environments we can deploy to. The steps to deploy on each environment would be out-of-scope for this guide, so we will just use the default Remix VM. + +Looking closely, we will notice that our "Solidity Verifier" is actually three contracts working together: + +- An `UltraVerificationKey` library which simply stores the verification key for our circuit. +- An abstract contract `BaseUltraVerifier` containing most of the verifying logic. +- A main `UltraVerifier` contract that inherits from the Base and uses the Key contract. + +Remix will take care of the dependencies for us so we can simply deploy the UltraVerifier contract by selecting it and hitting "deploy": + +![Deploying UltraVerifier](@site/static/img/how-tos/solidity_verifier_5.png) + +A contract will show up in the "Deployed Contracts" section, where we can retrieve the Verification Key Hash. This is particularly useful for double-checking the deployer contract is the correct one. + +:::note + +Why "UltraVerifier"? + +To be precise, the Noir compiler (`nargo`) doesn't generate the verifier contract directly. It compiles the Noir code into an intermediate language (ACIR), which is then executed by the backend. So it is the backend that returns the verifier smart contract, not Noir. + +In this case, the Barretenberg Backend uses the UltraPlonk proving system, hence the "UltraVerifier" name. + +::: + +## Step 4 - Verifying + +To verify a proof using the Solidity verifier contract, we call the `verify` function in this extended contract: + +```solidity +function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external view returns (bool) +``` + +When using the default example in the [Hello Noir](../getting_started/hello_noir/index.md) guide, the easiest way to confirm that the verifier contract is doing its job is by calling the `verify` function via remix with the required parameters. For `_proof`, run `nargo prove` and use the string in `proof/.proof` (adding the hex `0x` prefix). We can also copy the public input from `Verifier.toml`, as it will be properly formatted as 32-byte strings: + +``` +0x...... , [0x0000.....02] +``` + +A programmatic example of how the `verify` function is called can be seen in the example zk voting application [here](https://github.com/noir-lang/noir-examples/blob/33e598c257e2402ea3a6b68dd4c5ad492bce1b0a/foundry-voting/src/zkVote.sol#L35): + +```solidity +function castVote(bytes calldata proof, uint proposalId, uint vote, bytes32 nullifierHash) public returns (bool) { + // ... + bytes32[] memory publicInputs = new bytes32[](4); + publicInputs[0] = merkleRoot; + publicInputs[1] = bytes32(proposalId); + publicInputs[2] = bytes32(vote); + publicInputs[3] = nullifierHash; + require(verifier.verify(proof, publicInputs), "Invalid proof"); +``` + +:::info[Return Values] + +A circuit doesn't have the concept of a return value. Return values are just syntactic sugar in +Noir. + +Under the hood, the return value is passed as an input to the circuit and is checked at the end of +the circuit program. + +For example, if you have Noir program like this: + +```rust +fn main( + // Public inputs + pubkey_x: pub Field, + pubkey_y: pub Field, + // Private inputs + priv_key: Field, +) -> pub Field +``` + +the `verify` function will expect the public inputs array (second function parameter) to be of length 3, the two inputs and the return value. Like before, these values are populated in Verifier.toml after running `nargo prove`. + +Passing only two inputs will result in an error such as `PUBLIC_INPUT_COUNT_INVALID(3, 2)`. + +In this case, the inputs parameter to `verify` would be an array ordered as `[pubkey_x, pubkey_y, return]`. + +::: + +:::tip[Structs] + +You can pass structs to the verifier contract. They will be flattened so that the array of inputs is 1-dimensional array. + +For example, consider the following program: + +```rust +struct Type1 { + val1: Field, + val2: Field, +} + +struct Nested { + t1: Type1, + is_true: bool, +} + +fn main(x: pub Field, nested: pub Nested, y: pub Field) { + //... +} +``` + +The order of these inputs would be flattened to: `[x, nested.t1.val1, nested.t1.val2, nested.is_true, y]` + +::: + +The other function you can call is our entrypoint `verify` function, as defined above. + +:::tip + +It's worth noticing that the `verify` function is actually a `view` function. A `view` function does not alter the blockchain state, so it doesn't need to be distributed (i.e. it will run only on the executing node), and therefore doesn't cost any gas. + +This can be particularly useful in some situations. If Alice generated a proof and wants Bob to verify its correctness, Bob doesn't need to run Nargo, NoirJS, or any Noir specific infrastructure. He can simply make a call to the blockchain with the proof and verify it is correct without paying any gas. + +It would be incorrect to say that a Noir proof verification costs any gas at all. However, most of the time the result of `verify` is used to modify state (for example, to update a balance, a game state, etc). In that case the whole network needs to execute it, which does incur gas costs (calldata and execution, but not storage). + +::: + +## A Note on EVM chains + +ZK-SNARK verification depends on some precompiled cryptographic primitives such as Elliptic Curve Pairings (if you like complex math, you can read about EC Pairings [here](https://medium.com/@VitalikButerin/exploring-elliptic-curve-pairings-c73c1864e627)). Not all EVM chains support EC Pairings, notably some of the ZK-EVMs. This means that you won't be able to use the verifier contract in all of them. + +For example, chains like `zkSync ERA` and `Polygon zkEVM` do not currently support these precompiles, so proof verification via Solidity verifier contracts won't work. Here's a quick list of EVM chains that have been tested and are known to work: + +- Optimism +- Arbitrum +- Polygon PoS +- Scroll +- Celo + +If you test any other chains, please open a PR on this page to update the list. See [this doc](https://github.com/noir-lang/noir-starter/tree/main/with-foundry#testing-on-chain) for more info about testing verifier contracts on different EVM chains. + +## What's next + +Now that you know how to call a Noir Solidity Verifier on a smart contract using Remix, you should be comfortable with using it with some programmatic frameworks, such as [hardhat](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat) and [foundry](https://github.com/noir-lang/noir-starter/tree/main/with-foundry). + +You can find other tools, examples, boilerplates and libraries in the [awesome-noir](https://github.com/noir-lang/awesome-noir) repository. + +You should also be ready to write and deploy your first NoirJS app and start generating proofs on websites, phones, and NodeJS environments! Head on to the [NoirJS tutorial](../tutorials/noirjs_app.md) to learn how to do that. diff --git a/docs/versioned_docs/version-v0.30.0/how_to/merkle-proof.mdx b/docs/versioned_docs/version-v0.30.0/how_to/merkle-proof.mdx new file mode 100644 index 00000000000..16c425bed76 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/how_to/merkle-proof.mdx @@ -0,0 +1,49 @@ +--- +title: Prove Merkle Tree Membership +description: + Learn how to use merkle membership proof in Noir to prove that a given leaf is a member of a + merkle tree with a specified root, at a given index. +keywords: + [merkle proof, merkle membership proof, Noir, rust, hash function, Pedersen, sha256, merkle tree] +sidebar_position: 4 +--- + +Let's walk through an example of a merkle membership proof in Noir that proves that a given leaf is +in a merkle tree. + +```rust +use dep::std; + +fn main(message : [Field; 62], index : Field, hashpath : [Field; 40], root : Field) { + let leaf = std::hash::hash_to_field(message.as_slice()); + let merkle_root = std::merkle::compute_merkle_root(leaf, index, hashpath); + assert(merkle_root == root); +} + +``` + +The message is hashed using `hash_to_field`. The specific hash function that is being used is chosen +by the backend. The only requirement is that this hash function can heuristically be used as a +random oracle. If only collision resistance is needed, then one can call `std::hash::pedersen_hash` +instead. + +```rust +let leaf = std::hash::hash_to_field(message.as_slice()); +``` + +The leaf is then passed to a compute_merkle_root function with the root, index and hashpath. The returned root can then be asserted to be the same as the provided root. + +```rust +let merkle_root = std::merkle::compute_merkle_root(leaf, index, hashpath); +assert (merkle_root == root); +``` + +> **Note:** It is possible to re-implement the merkle tree implementation without standard library. +> However, for most usecases, it is enough. In general, the standard library will always opt to be +> as conservative as possible, while striking a balance with efficiency. + +An example, the merkle membership proof, only requires a hash function that has collision +resistance, hence a hash function like Pedersen is allowed, which in most cases is more efficient +than the even more conservative sha256. + +[View an example on the starter repo](https://github.com/noir-lang/noir-examples/blob/3ea09545cabfa464124ec2f3ea8e60c608abe6df/stealthdrop/circuits/src/main.nr#L20) diff --git a/docs/versioned_docs/version-v0.30.0/how_to/using-devcontainers.mdx b/docs/versioned_docs/version-v0.30.0/how_to/using-devcontainers.mdx new file mode 100644 index 00000000000..727ec6ca667 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/how_to/using-devcontainers.mdx @@ -0,0 +1,110 @@ +--- +title: Developer Containers and Codespaces +description: "Learn how to set up a devcontainer in your GitHub repository for a seamless coding experience with Codespaces. Follow our easy 8-step guide to create your own Noir environment without installing Nargo locally." +keywords: ["Devcontainer", "Codespaces", "GitHub", "Noir Environment", "Docker Image", "Development Environment", "Remote Coding", "GitHub Codespaces", "Noir Programming", "Nargo", "VSCode Extensions", "Noirup"] +sidebar_position: 1 +--- + +Adding a developer container configuration file to your Noir project is one of the easiest way to unlock coding in browser. + +## What's a devcontainer after all? + +A [Developer Container](https://containers.dev/) (devcontainer for short) is a Docker image that comes preloaded with tools, extensions, and other tools you need to quickly get started or continue a project, without having to install Nargo locally. Think of it as a development environment in a box. + +There are many advantages to this: + +- It's platform and architecture agnostic +- You don't need to have an IDE installed, or Nargo, or use a terminal at all +- It's safer for using on a public machine or public network + +One of the best ways of using devcontainers is... not using your machine at all, for maximum control, performance, and ease of use. +Enter Codespaces. + +## Codespaces + +If a devcontainer is just a Docker image, then what stops you from provisioning a `p3dn.24xlarge` AWS EC2 instance with 92 vCPUs and 768 GiB RAM and using it to prove your 10-gate SNARK proof? + +Nothing! Except perhaps the 30-40$ per hour it will cost you. + +The problem is that provisioning takes time, and I bet you don't want to see the AWS console every time you want to code something real quick. + +Fortunately, there's an easy and free way to get a decent remote machine ready and loaded in less than 2 minutes: Codespaces. [Codespaces is a Github feature](https://github.com/features/codespaces) that allows you to code in a remote machine by using devcontainers, and it's pretty cool: + +- You can start coding Noir in less than a minute +- It uses the resources of a remote machine, so you can code on your grandma's phone if needed be +- It makes it easy to share work with your frens +- It's fully reusable, you can stop and restart whenever you need to + +:::info + +Don't take out your wallet just yet. Free GitHub accounts get about [15-60 hours of coding](https://github.com/features/codespaces) for free per month, depending on the size of your provisioned machine. + +::: + +## Tell me it's _actually_ easy + +It is! + +Github comes with a default codespace and you can use it to code your own devcontainer. That's exactly what we will be doing in this guide. + + + +8 simple steps: + +#### 1. Create a new repository on GitHub. + +#### 2. Click "Start coding with Codespaces". This will use the default image. + +#### 3. Create a folder called `.devcontainer` in the root of your repository. + +#### 4. Create a Dockerfile in that folder, and paste the following code: + +```docker +FROM --platform=linux/amd64 node:lts-bookworm-slim +SHELL ["/bin/bash", "-c"] +RUN apt update && apt install -y curl bash git tar gzip libc++-dev +RUN curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash +ENV PATH="/root/.nargo/bin:$PATH" +RUN noirup +ENTRYPOINT ["nargo"] +``` +#### 5. Create a file called `devcontainer.json` in the same folder, and paste the following code: + +```json +{ + "name": "Noir on Codespaces", + "build": { + "context": ".", + "dockerfile": "Dockerfile" + }, + "customizations": { + "vscode": { + "extensions": ["noir-lang.vscode-noir"] + } + } +} +``` +#### 6. Commit and push your changes + +This will pull the new image and build it, so it could take a minute or so + +#### 8. Done! +Just wait for the build to finish, and there's your easy Noir environment. + + +Refer to [noir-starter](https://github.com/noir-lang/noir-starter/) as an example of how devcontainers can be used together with codespaces. + + + +## How do I use it? + +Using the codespace is obviously much easier than setting it up. +Just navigate to your repository and click "Code" -> "Open with Codespaces". It should take a few seconds to load, and you're ready to go. + +:::info + +If you really like the experience, you can add a badge to your readme, links to existing codespaces, and more. +Check out the [official docs](https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/setting-up-your-repository/facilitating-quick-creation-and-resumption-of-codespaces) for more info. diff --git a/docs/versioned_docs/version-v0.30.0/index.mdx b/docs/versioned_docs/version-v0.30.0/index.mdx new file mode 100644 index 00000000000..75086ddcdde --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/index.mdx @@ -0,0 +1,67 @@ +--- +title: Noir Lang +hide_title: true +description: + Learn about the public alpha release of Noir, a domain specific language heavily influenced by Rust that compiles to + an intermediate language which can be compiled to an arithmetic circuit or a rank-1 constraint system. +keywords: + [Noir, + Domain Specific Language, + Rust, + Intermediate Language, + Arithmetic Circuit, + Rank-1 Constraint System, + Ethereum Developers, + Protocol Developers, + Blockchain Developers, + Proving System, + Smart Contract Language] +sidebar_position: 0 +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +Noir Logo + +Noir is a Domain-Specific Language for SNARK proving systems developed by [Aztec Labs](https://aztec.network/). It allows you to generate complex Zero-Knowledge Programs (ZKP) by using simple and flexible syntax, requiring no previous knowledge on the underlying mathematics or cryptography. + +ZK programs are programs that can generate short proofs of a certain statement without revealing some details about it. You can read more about ZKPs [here](https://dev.to/spalladino/a-beginners-intro-to-coding-zero-knowledge-proofs-c56). + +## What's new about Noir? + +Noir works differently from most ZK languages by taking a two-pronged path. First, it compiles the program to an adaptable intermediate language known as ACIR. From there, depending on a given project's needs, ACIR can be further compiled into an arithmetic circuit for integration with the proving backend. + +:::info + +Noir is backend agnostic, which means it makes no assumptions on which proving backend powers the ZK proof. Being the language that powers [Aztec Contracts](https://docs.aztec.network/developers/contracts/main), it defaults to Aztec's Barretenberg proving backend. + +However, the ACIR output can be transformed to be compatible with other PLONK-based backends, or into a [rank-1 constraint system](https://www.rareskills.io/post/rank-1-constraint-system) suitable for backends such as Arkwork's Marlin. + +::: + +## Who is Noir for? + +Noir can be used both in complex cloud-based backends and in user's smartphones, requiring no knowledge on the underlying math or cryptography. From authorization systems that keep a password in the user's device, to complex on-chain verification of recursive proofs, Noir is designed to abstract away complexity without any significant overhead. Here are some examples of situations where Noir can be used: + + + + Noir Logo + + Aztec Contracts leverage Noir to allow for the storage and execution of private information. Writing an Aztec Contract is as easy as writing Noir, and Aztec developers can easily interact with the network storage and execution through the [Aztec.nr](https://docs.aztec.network/developers/contracts/main) library. + + + Soliditry Verifier Example + Noir can auto-generate Solidity verifier contracts that verify Noir proofs. This allows for non-interactive verification of proofs containing private information in an immutable system. This feature powers a multitude of use-case scenarios, from P2P chess tournaments, to [Aztec Layer-2 Blockchain](https://docs.aztec.network/) + + + Aztec Labs developed NoirJS, an easy interface to generate and verify Noir proofs in a Javascript environment. This allows for Noir to be used in webpages, mobile apps, games, and any other environment supporting JS execution in a standalone manner. + + + + +## Libraries + +Noir is meant to be easy to extend by simply importing Noir libraries just like in Rust. +The [awesome-noir repo](https://github.com/noir-lang/awesome-noir#libraries) is a collection of libraries developed by the Noir community. +Writing a new library is easy and makes code be composable and easy to reuse. See the section on [dependencies](noir/modules_packages_crates/dependencies.md) for more information. diff --git a/docs/versioned_docs/version-v0.30.0/migration_notes.md b/docs/versioned_docs/version-v0.30.0/migration_notes.md new file mode 100644 index 00000000000..6bd740024e5 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/migration_notes.md @@ -0,0 +1,105 @@ +--- +title: Migration notes +description: Read about migration notes from previous versions, which could solve problems while updating +keywords: [Noir, notes, migration, updating, upgrading] +--- + +Noir is in full-speed development. Things break fast, wild, and often. This page attempts to leave some notes on errors you might encounter when upgrading and how to resolve them until proper patches are built. + +### `backend encountered an error: libc++.so.1` + +Depending on your OS, you may encounter the following error when running `nargo prove` for the first time: + +```text +The backend encountered an error: "/home/codespace/.nargo/backends/acvm-backend-barretenberg/backend_binary: error while loading shared libraries: libc++.so.1: cannot open shared object file: No such file or directory\n" +``` + +Install the `libc++-dev` library with: + +```bash +sudo apt install libc++-dev +``` + +## ≥0.19 + +### Enforcing `compiler_version` + +From this version on, the compiler will check for the `compiler_version` field in `Nargo.toml`, and will error if it doesn't match the current Nargo version in use. + +To update, please make sure this field in `Nargo.toml` matches the output of `nargo --version`. + +## ≥0.14 + +The index of the [for loops](noir/concepts/control_flow.md#loops) is now of type `u64` instead of `Field`. An example refactor would be: + +```rust +for i in 0..10 { + let i = i as Field; +} +``` + +## ≥v0.11.0 and Nargo backend + +From this version onwards, Nargo starts managing backends through the `nargo backend` command. Upgrading to the versions per usual steps might lead to: + +### `backend encountered an error` + +This is likely due to the existing locally installed version of proving backend (e.g. barretenberg) is incompatible with the version of Nargo in use. + +To fix the issue: + +1. Uninstall the existing backend + +```bash +nargo backend uninstall acvm-backend-barretenberg +``` + +You may replace _acvm-backend-barretenberg_ with the name of your backend listed in `nargo backend ls` or in ~/.nargo/backends. + +2. Reinstall a compatible version of the proving backend. + +If you are using the default barretenberg backend, simply run: + +``` +nargo prove +``` + +with your Noir program. + +This will trigger the download and installation of the latest version of barretenberg compatible with your Nargo in use. + +### `backend encountered an error: illegal instruction` + +On certain Intel-based systems, an `illegal instruction` error may arise due to incompatibility of barretenberg with certain CPU instructions. + +To fix the issue: + +1. Uninstall the existing backend + +```bash +nargo backend uninstall acvm-backend-barretenberg +``` + +You may replace _acvm-backend-barretenberg_ with the name of your backend listed in `nargo backend ls` or in ~/.nargo/backends. + +2. Reinstall a compatible version of the proving backend. + +If you are using the default barretenberg backend, simply run: + +``` +nargo backend install acvm-backend-barretenberg https://github.com/noir-lang/barretenberg-js-binary/raw/master/run-bb.tar.gz +``` + +This downloads and installs a specific bb.js based version of barretenberg binary from GitHub. + +The gzipped file is running [this bash script](https://github.com/noir-lang/barretenberg-js-binary/blob/master/run-bb-js.sh), where we need to gzip it as the Nargo currently expect the backend to be zipped up. + +Then run: + +``` +DESIRED_BINARY_VERSION=0.8.1 nargo info +``` + +This overrides the bb native binary with a bb.js node application instead, which should be compatible with most if not all hardware. This does come with the drawback of being generally slower than native binary. + +0.8.1 indicates bb.js version 0.8.1, so if you change that it will update to a different version or the default version in the script if none was supplied. diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/_category_.json b/docs/versioned_docs/version-v0.30.0/noir/concepts/_category_.json new file mode 100644 index 00000000000..7da08f8a8c5 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/_category_.json @@ -0,0 +1,6 @@ +{ + "label": "Concepts", + "position": 0, + "collapsible": true, + "collapsed": true +} \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/assert.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/assert.md new file mode 100644 index 00000000000..bcff613a695 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/assert.md @@ -0,0 +1,45 @@ +--- +title: Assert Function +description: + Learn about the assert function in Noir, which can be used to explicitly constrain the predicate or + comparison expression that follows to be true, and what happens if the expression is false at + runtime. +keywords: [Noir programming language, assert statement, predicate expression, comparison expression] +sidebar_position: 4 +--- + +Noir includes a special `assert` function which will explicitly constrain the predicate/comparison +expression that follows to be true. If this expression is false at runtime, the program will fail to +be proven. Example: + +```rust +fn main(x : Field, y : Field) { + assert(x == y); +} +``` + +> Assertions only work for predicate operations, such as `==`. If there's any ambiguity on the operation, the program will fail to compile. For example, it is unclear if `assert(x + y)` would check for `x + y == 0` or simply would return `true`. + +You can optionally provide a message to be logged when the assertion fails: + +```rust +assert(x == y, "x and y are not equal"); +``` + +Aside string literals, the optional message can be a format string or any other type supported as input for Noir's [print](../standard_library/logging.md) functions. This feature lets you incorporate runtime variables into your failed assertion logs: + +```rust +assert(x == y, f"Expected x == y, but got {x} == {y}"); +``` + +Using a variable as an assertion message directly: + +```rust +struct myStruct { + myField: Field +} + +let s = myStruct { myField: y }; +assert(s.myField == x, s); +``` + diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/comments.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/comments.md new file mode 100644 index 00000000000..b51a85f5c94 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/comments.md @@ -0,0 +1,33 @@ +--- +title: Comments +description: + Learn how to write comments in Noir programming language. A comment is a line of code that is + ignored by the compiler, but it can be read by programmers. Single-line and multi-line comments + are supported in Noir. +keywords: [Noir programming language, comments, single-line comments, multi-line comments] +sidebar_position: 10 +--- + +A comment is a line in your codebase which the compiler ignores, however it can be read by +programmers. + +Here is a single line comment: + +```rust +// This is a comment and is ignored +``` + +`//` is used to tell the compiler to ignore the rest of the line. + +Noir also supports multi-line block comments. Start a block comment with `/*` and end the block with `*/`. + +Noir does not natively support doc comments. You may be able to use [Rust doc comments](https://doc.rust-lang.org/reference/comments.html) in your code to leverage some Rust documentation build tools with Noir code. + +```rust +/* + This is a block comment describing a complex function. +*/ +fn main(x : Field, y : pub Field) { + assert(x != y); +} +``` diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/control_flow.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/control_flow.md new file mode 100644 index 00000000000..045d3c3a5f5 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/control_flow.md @@ -0,0 +1,77 @@ +--- +title: Control Flow +description: + Learn how to use loops and if expressions in the Noir programming language. Discover the syntax + and examples for for loops and if-else statements. +keywords: [Noir programming language, loops, for loop, if-else statements, Rust syntax] +sidebar_position: 2 +--- + +## If Expressions + +Noir supports `if-else` statements. The syntax is most similar to Rust's where it is not required +for the statement's conditional to be surrounded by parentheses. + +```rust +let a = 0; +let mut x: u32 = 0; + +if a == 0 { + if a != 0 { + x = 6; + } else { + x = 2; + } +} else { + x = 5; + assert(x == 5); +} +assert(x == 2); +``` + +## Loops + +Noir has one kind of loop: the `for` loop. `for` loops allow you to repeat a block of code multiple +times. + +The following block of code between the braces is run 10 times. + +```rust +for i in 0..10 { + // do something +} +``` + +The index for loops is of type `u64`. + +### Break and Continue + +In unconstrained code, `break` and `continue` are also allowed in `for` loops. These are only allowed +in unconstrained code since normal constrained code requires that Noir knows exactly how many iterations +a loop may have. `break` and `continue` can be used like so: + +```rust +for i in 0 .. 10 { + println("Iteration start") + + if i == 2 { + continue; + } + + if i == 5 { + break; + } + + println(i); +} +println("Loop end") +``` + +When used, `break` will end the current loop early and jump to the statement after the for loop. In the example +above, the `break` will stop the loop and jump to the `println("Loop end")`. + +`continue` will stop the current iteration of the loop, and jump to the start of the next iteration. In the example +above, `continue` will jump to `println("Iteration start")` when used. Note that the loop continues as normal after this. +The iteration variable `i` is still increased by one as normal when `continue` is used. + +`break` and `continue` cannot currently be used to jump out of more than a single loop at a time. diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/data_bus.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_bus.md new file mode 100644 index 00000000000..e54fc861257 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_bus.md @@ -0,0 +1,21 @@ +--- +title: Data Bus +sidebar_position: 13 +--- +**Disclaimer** this feature is experimental, do not use it! + +The data bus is an optimization that the backend can use to make recursion more efficient. +In order to use it, you must define some inputs of the program entry points (usually the `main()` +function) with the `call_data` modifier, and the return values with the `return_data` modifier. +These modifiers are incompatible with `pub` and `mut` modifiers. + +## Example + +```rust +fn main(mut x: u32, y: call_data u32, z: call_data [u32;4] ) -> return_data u32 { + let a = z[x]; + a+y +} +``` + +As a result, both call_data and return_data will be treated as private inputs and encapsulated into a read-only array each, for the backend to process. diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/_category_.json b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/_category_.json new file mode 100644 index 00000000000..5d694210bbf --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 0, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/arrays.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/arrays.md new file mode 100644 index 00000000000..efce3e95d32 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/arrays.md @@ -0,0 +1,251 @@ +--- +title: Arrays +description: + Dive into the Array data type in Noir. Grasp its methods, practical examples, and best practices for efficiently using Arrays in your Noir code. +keywords: + [ + noir, + array type, + methods, + examples, + indexing, + ] +sidebar_position: 4 +--- + +An array is one way of grouping together values into one compound type. Array types can be inferred +or explicitly specified via the syntax `[; ]`: + +```rust +fn main(x : Field, y : Field) { + let my_arr = [x, y]; + let your_arr: [Field; 2] = [x, y]; +} +``` + +Here, both `my_arr` and `your_arr` are instantiated as an array containing two `Field` elements. + +Array elements can be accessed using indexing: + +```rust +fn main() { + let a = [1, 2, 3, 4, 5]; + + let first = a[0]; + let second = a[1]; +} +``` + +All elements in an array must be of the same type (i.e. homogeneous). That is, an array cannot group +a `Field` value and a `u8` value together for example. + +You can write mutable arrays, like: + +```rust +fn main() { + let mut arr = [1, 2, 3, 4, 5]; + assert(arr[0] == 1); + + arr[0] = 42; + assert(arr[0] == 42); +} +``` + +You can instantiate a new array of a fixed size with the same value repeated for each element. The following example instantiates an array of length 32 where each element is of type Field and has the value 0. + +```rust +let array: [Field; 32] = [0; 32]; +``` + +Like in Rust, arrays in Noir are a fixed size. However, if you wish to convert an array to a [slice](./slices), you can just call `as_slice` on your array: + +```rust +let array: [Field; 32] = [0; 32]; +let sl = array.as_slice() +``` + +You can define multidimensional arrays: + +```rust +let array : [[Field; 2]; 2]; +let element = array[0][0]; +``` +However, multidimensional slices are not supported. For example, the following code will error at compile time: +```rust +let slice : [[Field]] = &[]; +``` + +## Types + +You can create arrays of primitive types or structs. There is not yet support for nested arrays +(arrays of arrays) or arrays of structs that contain arrays. + +## Methods + +For convenience, the STD provides some ready-to-use, common methods for arrays. +Each of these functions are located within the generic impl `impl [T; N] {`. +So anywhere `self` appears, it refers to the variable `self: [T; N]`. + +### len + +Returns the length of an array + +```rust +fn len(self) -> Field +``` + +example + +```rust +fn main() { + let array = [42, 42]; + assert(array.len() == 2); +} +``` + +### sort + +Returns a new sorted array. The original array remains untouched. Notice that this function will +only work for arrays of fields or integers, not for any arbitrary type. This is because the sorting +logic it uses internally is optimized specifically for these values. If you need a sort function to +sort any type, you should use the function `sort_via` described below. + +```rust +fn sort(self) -> [T; N] +``` + +example + +```rust +fn main() { + let arr = [42, 32]; + let sorted = arr.sort(); + assert(sorted == [32, 42]); +} +``` + +### sort_via + +Sorts the array with a custom comparison function + +```rust +fn sort_via(self, ordering: fn(T, T) -> bool) -> [T; N] +``` + +example + +```rust +fn main() { + let arr = [42, 32] + let sorted_ascending = arr.sort_via(|a, b| a < b); + assert(sorted_ascending == [32, 42]); // verifies + + let sorted_descending = arr.sort_via(|a, b| a > b); + assert(sorted_descending == [32, 42]); // does not verify +} +``` + +### map + +Applies a function to each element of the array, returning a new array containing the mapped elements. + +```rust +fn map(self, f: fn(T) -> U) -> [U; N] +``` + +example + +```rust +let a = [1, 2, 3]; +let b = a.map(|a| a * 2); // b is now [2, 4, 6] +``` + +### fold + +Applies a function to each element of the array, returning the final accumulated value. The first +parameter is the initial value. + +```rust +fn fold(self, mut accumulator: U, f: fn(U, T) -> U) -> U +``` + +This is a left fold, so the given function will be applied to the accumulator and first element of +the array, then the second, and so on. For a given call the expected result would be equivalent to: + +```rust +let a1 = [1]; +let a2 = [1, 2]; +let a3 = [1, 2, 3]; + +let f = |a, b| a - b; +a1.fold(10, f) //=> f(10, 1) +a2.fold(10, f) //=> f(f(10, 1), 2) +a3.fold(10, f) //=> f(f(f(10, 1), 2), 3) +``` + +example: + +```rust + +fn main() { + let arr = [2, 2, 2, 2, 2]; + let folded = arr.fold(0, |a, b| a + b); + assert(folded == 10); +} + +``` + +### reduce + +Same as fold, but uses the first element as starting element. + +```rust +fn reduce(self, f: fn(T, T) -> T) -> T +``` + +example: + +```rust +fn main() { + let arr = [2, 2, 2, 2, 2]; + let reduced = arr.reduce(|a, b| a + b); + assert(reduced == 10); +} +``` + +### all + +Returns true if all the elements satisfy the given predicate + +```rust +fn all(self, predicate: fn(T) -> bool) -> bool +``` + +example: + +```rust +fn main() { + let arr = [2, 2, 2, 2, 2]; + let all = arr.all(|a| a == 2); + assert(all); +} +``` + +### any + +Returns true if any of the elements satisfy the given predicate + +```rust +fn any(self, predicate: fn(T) -> bool) -> bool +``` + +example: + +```rust +fn main() { + let arr = [2, 2, 2, 2, 5]; + let any = arr.any(|a| a == 5); + assert(any); +} + +``` diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/booleans.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/booleans.md new file mode 100644 index 00000000000..69826fcd724 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/booleans.md @@ -0,0 +1,31 @@ +--- +title: Booleans +description: + Delve into the Boolean data type in Noir. Understand its methods, practical examples, and best practices for using Booleans in your Noir programs. +keywords: + [ + noir, + boolean type, + methods, + examples, + logical operations, + ] +sidebar_position: 2 +--- + + +The `bool` type in Noir has two possible values: `true` and `false`: + +```rust +fn main() { + let t = true; + let f: bool = false; +} +``` + +> **Note:** When returning a boolean value, it will show up as a value of 1 for `true` and 0 for +> `false` in _Verifier.toml_. + +The boolean type is most commonly used in conditionals like `if` expressions and `assert` +statements. More about conditionals is covered in the [Control Flow](../control_flow) and +[Assert Function](../assert) sections. diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/fields.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/fields.md new file mode 100644 index 00000000000..a10a4810788 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/fields.md @@ -0,0 +1,192 @@ +--- +title: Fields +description: + Dive deep into the Field data type in Noir. Understand its methods, practical examples, and best practices to effectively use Fields in your Noir programs. +keywords: + [ + noir, + field type, + methods, + examples, + best practices, + ] +sidebar_position: 0 +--- + +The field type corresponds to the native field type of the proving backend. + +The size of a Noir field depends on the elliptic curve's finite field for the proving backend +adopted. For example, a field would be a 254-bit integer when paired with the default backend that +spans the Grumpkin curve. + +Fields support integer arithmetic and are often used as the default numeric type in Noir: + +```rust +fn main(x : Field, y : Field) { + let z = x + y; +} +``` + +`x`, `y` and `z` are all private fields in this example. Using the `let` keyword we defined a new +private value `z` constrained to be equal to `x + y`. + +If proving efficiency is of priority, fields should be used as a default for solving problems. +Smaller integer types (e.g. `u64`) incur extra range constraints. + +## Methods + +After declaring a Field, you can use these common methods on it: + +### to_le_bits + +Transforms the field into an array of bits, Little Endian. + +```rust +fn to_le_bits(_x : Field, _bit_size: u32) -> [u1] +``` + +example: + +```rust +fn main() { + let field = 2; + let bits = field.to_le_bits(32); +} +``` + +### to_be_bits + +Transforms the field into an array of bits, Big Endian. + +```rust +fn to_be_bits(_x : Field, _bit_size: u32) -> [u1] +``` + +example: + +```rust +fn main() { + let field = 2; + let bits = field.to_be_bits(32); +} +``` + +### to_le_bytes + +Transforms into an array of bytes, Little Endian + +```rust +fn to_le_bytes(_x : Field, byte_size: u32) -> [u8] +``` + +example: + +```rust +fn main() { + let field = 2; + let bytes = field.to_le_bytes(4); +} +``` + +### to_be_bytes + +Transforms into an array of bytes, Big Endian + +```rust +fn to_be_bytes(_x : Field, byte_size: u32) -> [u8] +``` + +example: + +```rust +fn main() { + let field = 2; + let bytes = field.to_be_bytes(4); +} +``` + +### to_le_radix + +Decomposes into a vector over the specified base, Little Endian + +```rust +fn to_le_radix(_x : Field, _radix: u32, _result_len: u32) -> [u8] +``` + +example: + +```rust +fn main() { + let field = 2; + let radix = field.to_le_radix(256, 4); +} +``` + +### to_be_radix + +Decomposes into a vector over the specified base, Big Endian + +```rust +fn to_be_radix(_x : Field, _radix: u32, _result_len: u32) -> [u8] +``` + +example: + +```rust +fn main() { + let field = 2; + let radix = field.to_be_radix(256, 4); +} +``` + +### pow_32 + +Returns the value to the power of the specified exponent + +```rust +fn pow_32(self, exponent: Field) -> Field +``` + +example: + +```rust +fn main() { + let field = 2 + let pow = field.pow_32(4); + assert(pow == 16); +} +``` + +### assert_max_bit_size + +Adds a constraint to specify that the field can be represented with `bit_size` number of bits + +```rust +fn assert_max_bit_size(self, bit_size: u32) +``` + +example: + +```rust +fn main() { + let field = 2 + field.assert_max_bit_size(32); +} +``` + +### sgn0 + +Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x ∈ \{0, ..., p-1\} is even, otherwise sgn0(x mod p) = 1. + +```rust +fn sgn0(self) -> u1 +``` + + +### lt + +Returns true if the field is less than the other field + +```rust +pub fn lt(self, another: Field) -> bool +``` diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/function_types.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/function_types.md new file mode 100644 index 00000000000..f6121af17e2 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/function_types.md @@ -0,0 +1,26 @@ +--- +title: Function types +sidebar_position: 10 +--- + +Noir supports higher-order functions. The syntax for a function type is as follows: + +```rust +fn(arg1_type, arg2_type, ...) -> return_type +``` + +Example: + +```rust +fn assert_returns_100(f: fn() -> Field) { // f takes no args and returns a Field + assert(f() == 100); +} + +fn main() { + assert_returns_100(|| 100); // ok + assert_returns_100(|| 150); // fails +} +``` + +A function type also has an optional capture environment - this is necessary to support closures. +See [Lambdas](../lambdas.md) for more details. diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/index.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/index.md new file mode 100644 index 00000000000..357813c147a --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/index.md @@ -0,0 +1,110 @@ +--- +title: Data Types +description: + Get a clear understanding of the two categories of Noir data types - primitive types and compound + types. Learn about their characteristics, differences, and how to use them in your Noir + programming. +keywords: + [ + noir, + data types, + primitive types, + compound types, + private types, + public types, + ] +--- + +Every value in Noir has a type, which determines which operations are valid for it. + +All values in Noir are fundamentally composed of `Field` elements. For a more approachable +developing experience, abstractions are added on top to introduce different data types in Noir. + +Noir has two category of data types: primitive types (e.g. `Field`, integers, `bool`) and compound +types that group primitive types (e.g. arrays, tuples, structs). Each value can either be private or +public. + +## Private & Public Types + +A **private value** is known only to the Prover, while a **public value** is known by both the +Prover and Verifier. Mark values as `private` when the value should only be known to the prover. All +primitive types (including individual fields of compound types) in Noir are private by default, and +can be marked public when certain values are intended to be revealed to the Verifier. + +> **Note:** For public values defined in Noir programs paired with smart contract verifiers, once +> the proofs are verified on-chain the values can be considered known to everyone that has access to +> that blockchain. + +Public data types are treated no differently to private types apart from the fact that their values +will be revealed in proofs generated. Simply changing the value of a public type will not change the +circuit (where the same goes for changing values of private types as well). + +_Private values_ are also referred to as _witnesses_ sometimes. + +> **Note:** The terms private and public when applied to a type (e.g. `pub Field`) have a different +> meaning than when applied to a function (e.g. `pub fn foo() {}`). +> +> The former is a visibility modifier for the Prover to interpret if a value should be made known to +> the Verifier, while the latter is a visibility modifier for the compiler to interpret if a +> function should be made accessible to external Noir programs like in other languages. + +### pub Modifier + +All data types in Noir are private by default. Types are explicitly declared as public using the +`pub` modifier: + +```rust +fn main(x : Field, y : pub Field) -> pub Field { + x + y +} +``` + +In this example, `x` is **private** while `y` and `x + y` (the return value) are **public**. Note +that visibility is handled **per variable**, so it is perfectly valid to have one input that is +private and another that is public. + +> **Note:** Public types can only be declared through parameters on `main`. + +## Type Aliases + +A type alias is a new name for an existing type. Type aliases are declared with the keyword `type`: + +```rust +type Id = u8; + +fn main() { + let id: Id = 1; + let zero: u8 = 0; + assert(zero + 1 == id); +} +``` + +Type aliases can also be used with [generics](../generics.md): + +```rust +type Id = Size; + +fn main() { + let id: Id = 1; + let zero: u32 = 0; + assert(zero + 1 == id); +} +``` + +Type aliases can even refer to other aliases. An error will be issued if they form a cycle: + +```rust +// Ok! +type A = B; +type B = Field; + +type Bad1 = Bad2; + +// error: Dependency cycle found +type Bad2 = Bad1; +// ^^^^^^^^^^^ 'Bad2' recursively depends on itself: Bad2 -> Bad1 -> Bad2 +``` + +### BigInt + +You can achieve BigInt functionality using the [Noir BigInt](https://github.com/shuklaayush/noir-bigint) library. diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/integers.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/integers.md new file mode 100644 index 00000000000..6b2d3773912 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/integers.md @@ -0,0 +1,157 @@ +--- +title: Integers +description: Explore the Integer data type in Noir. Learn about its methods, see real-world examples, and grasp how to efficiently use Integers in your Noir code. +keywords: [noir, integer types, methods, examples, arithmetic] +sidebar_position: 1 +--- + +An integer type is a range constrained field type. +The Noir frontend supports both unsigned and signed integer types. +The allowed sizes are 1, 8, 16, 32 and 64 bits. + +:::info + +When an integer is defined in Noir without a specific type, it will default to `Field`. + +The one exception is for loop indices which default to `u64` since comparisons on `Field`s are not possible. + +::: + +## Unsigned Integers + +An unsigned integer type is specified first with the letter `u` (indicating its unsigned nature) followed by its bit size (e.g. `8`): + +```rust +fn main() { + let x: u8 = 1; + let y: u8 = 1; + let z = x + y; + assert (z == 2); +} +``` + +The bit size determines the maximum value the integer type can store. For example, a `u8` variable can store a value in the range of 0 to 255 (i.e. $\\2^{8}-1\\$). + +## Signed Integers + +A signed integer type is specified first with the letter `i` (which stands for integer) followed by its bit size (e.g. `8`): + +```rust +fn main() { + let x: i8 = -1; + let y: i8 = -1; + let z = x + y; + assert (z == -2); +} +``` + +The bit size determines the maximum and minimum range of value the integer type can store. For example, an `i8` variable can store a value in the range of -128 to 127 (i.e. $\\-2^{7}\\$ to $\\2^{7}-1\\$). + +## 128 bits Unsigned Integers + +The built-in structure `U128` allows you to use 128-bit unsigned integers almost like a native integer type. However, there are some differences to keep in mind: +- You cannot cast between a native integer and `U128` +- There is a higher performance cost when using `U128`, compared to a native type. + +Conversion between unsigned integer types and U128 are done through the use of `from_integer` and `to_integer` functions. `from_integer` also accepts the `Field` type as input. + +```rust +fn main() { + let x = U128::from_integer(23); + let y = U128::from_hex("0x7"); + let z = x + y; + assert(z.to_integer() == 30); +} +``` + +`U128` is implemented with two 64 bits limbs, representing the low and high bits, which explains the performance cost. You should expect `U128` to be twice more costly for addition and four times more costly for multiplication. +You can construct a U128 from its limbs: +```rust +fn main(x: u64, y: u64) { + let x = U128::from_u64s_be(x,y); + assert(z.hi == x as Field); + assert(z.lo == y as Field); +} +``` + +Note that the limbs are stored as Field elements in order to avoid unnecessary conversions. +Apart from this, most operations will work as usual: + +```rust +fn main(x: U128, y: U128) { + // multiplication + let c = x * y; + // addition and subtraction + let c = c - x + y; + // division + let c = x / y; + // bit operation; + let c = x & y | y; + // bit shift + let c = x << y; + // comparisons; + let c = x < y; + let c = x == y; +} +``` + +## Overflows + +Computations that exceed the type boundaries will result in overflow errors. This happens with both signed and unsigned integers. For example, attempting to prove: + +```rust +fn main(x: u8, y: u8) { + let z = x + y; +} +``` + +With: + +```toml +x = "255" +y = "1" +``` + +Would result in: + +``` +$ nargo prove +error: Assertion failed: 'attempt to add with overflow' +┌─ ~/src/main.nr:9:13 +│ +│ let z = x + y; +│ ----- +│ += Call stack: + ... +``` + +A similar error would happen with signed integers: + +```rust +fn main() { + let x: i8 = -118; + let y: i8 = -11; + let z = x + y; +} +``` + +### Wrapping methods + +Although integer overflow is expected to error, some use-cases rely on wrapping. For these use-cases, the standard library provides `wrapping` variants of certain common operations: + +```rust +fn wrapping_add(x: T, y: T) -> T; +fn wrapping_sub(x: T, y: T) -> T; +fn wrapping_mul(x: T, y: T) -> T; +``` + +Example of how it is used: + +```rust +use dep::std; + +fn main(x: u8, y: u8) -> pub u8 { + std::wrapping_add(x, y) +} +``` diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/references.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/references.md new file mode 100644 index 00000000000..a5293d11cfb --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/references.md @@ -0,0 +1,23 @@ +--- +title: References +sidebar_position: 9 +--- + +Noir supports first-class references. References are a bit like pointers: they point to a specific address that can be followed to access the data stored at that address. You can use Rust-like syntax to use pointers in Noir: the `&` operator references the variable, the `*` operator dereferences it. + +Example: + +```rust +fn main() { + let mut x = 2; + + // you can reference x as &mut and pass it to multiplyBy2 + multiplyBy2(&mut x); +} + +// you can access &mut here +fn multiplyBy2(x: &mut Field) { + // and dereference it with * + *x = *x * 2; +} +``` diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/slices.mdx b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/slices.mdx new file mode 100644 index 00000000000..4eccc677b80 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/slices.mdx @@ -0,0 +1,195 @@ +--- +title: Slices +description: Explore the Slice data type in Noir. Understand its methods, see real-world examples, and learn how to effectively use Slices in your Noir programs. +keywords: [noir, slice type, methods, examples, subarrays] +sidebar_position: 5 +--- + +import Experimental from '@site/src/components/Notes/_experimental.mdx'; + + + +A slice is a dynamically-sized view into a sequence of elements. They can be resized at runtime, but because they don't own the data, they cannot be returned from a circuit. You can treat slices as arrays without a constrained size. + +```rust +use dep::std::slice; + +fn main() -> pub Field { + let mut slice: [Field] = &[0; 2]; + + let mut new_slice = slice.push_back(6); + new_slice.len() +} +``` + +To write a slice literal, use a preceeding ampersand as in: `&[0; 2]` or +`&[1, 2, 3]`. + +It is important to note that slices are not references to arrays. In Noir, +`&[..]` is more similar to an immutable, growable vector. + +View the corresponding test file [here][test-file]. + +[test-file]: https://github.com/noir-lang/noir/blob/f387ec1475129732f72ba294877efdf6857135ac/crates/nargo_cli/tests/test_data_ssa_refactor/slices/src/main.nr + +## Methods + +For convenience, the STD provides some ready-to-use, common methods for slices: + +### push_back + +Pushes a new element to the end of the slice, returning a new slice with a length one greater than the original unmodified slice. + +```rust +fn push_back(_self: [T], _elem: T) -> [T] +``` + +example: + +```rust +fn main() -> pub Field { + let mut slice: [Field] = &[0; 2]; + + let mut new_slice = slice.push_back(6); + new_slice.len() +} +``` + +View the corresponding test file [here][test-file]. + +### push_front + +Returns a new array with the specified element inserted at index 0. The existing elements indexes are incremented by 1. + +```rust +fn push_front(_self: Self, _elem: T) -> Self +``` + +Example: + +```rust +let mut new_slice: [Field] = &[]; +new_slice = new_slice.push_front(20); +assert(new_slice[0] == 20); // returns true +``` + +View the corresponding test file [here][test-file]. + +### pop_front + +Returns a tuple of two items, the first element of the array and the rest of the array. + +```rust +fn pop_front(_self: Self) -> (T, Self) +``` + +Example: + +```rust +let (first_elem, rest_of_slice) = slice.pop_front(); +``` + +View the corresponding test file [here][test-file]. + +### pop_back + +Returns a tuple of two items, the beginning of the array with the last element omitted and the last element. + +```rust +fn pop_back(_self: Self) -> (Self, T) +``` + +Example: + +```rust +let (popped_slice, last_elem) = slice.pop_back(); +``` + +View the corresponding test file [here][test-file]. + +### append + +Loops over a slice and adds it to the end of another. + +```rust +fn append(mut self, other: Self) -> Self +``` + +Example: + +```rust +let append = &[1, 2].append(&[3, 4, 5]); +``` + +### insert + +Inserts an element at a specified index and shifts all following elements by 1. + +```rust +fn insert(_self: Self, _index: Field, _elem: T) -> Self +``` + +Example: + +```rust +new_slice = rest_of_slice.insert(2, 100); +assert(new_slice[2] == 100); +``` + +View the corresponding test file [here][test-file]. + +### remove + +Remove an element at a specified index, shifting all elements after it to the left, returning the altered slice and the removed element. + +```rust +fn remove(_self: Self, _index: Field) -> (Self, T) +``` + +Example: + +```rust +let (remove_slice, removed_elem) = slice.remove(3); +``` + +### len + +Returns the length of a slice + +```rust +fn len(self) -> Field +``` + +Example: + +```rust +fn main() { + let slice = &[42, 42]; + assert(slice.len() == 2); +} +``` + +### as_array + +Converts this slice into an array. + +Make sure to specify the size of the resulting array. +Panics if the resulting array length is different than the slice's length. + +```rust +fn as_array(self) -> [T; N] +``` + +Example: + +```rust +fn main() { + let slice = &[5, 6]; + + // Always specify the length of the resulting array! + let array: [Field; 2] = slice.as_array(); + + assert(array[0] == slice[0]); + assert(array[1] == slice[1]); +} +``` diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/strings.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/strings.md new file mode 100644 index 00000000000..311dfd64416 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/strings.md @@ -0,0 +1,80 @@ +--- +title: Strings +description: + Discover the String data type in Noir. Learn about its methods, see real-world examples, and understand how to effectively manipulate and use Strings in Noir. +keywords: + [ + noir, + string type, + methods, + examples, + concatenation, + ] +sidebar_position: 3 +--- + + +The string type is a fixed length value defined with `str`. + +You can use strings in `assert()` functions or print them with +`println()`. See more about [Logging](../../standard_library/logging). + +```rust +use dep::std; + +fn main(message : pub str<11>, hex_as_string : str<4>) { + println(message); + assert(message == "hello world"); + assert(hex_as_string == "0x41"); +} +``` + +You can convert a `str` to a byte array by calling `as_bytes()` +or a vector by calling `as_bytes_vec()`. + +```rust +fn main() { + let message = "hello world"; + let message_bytes = message.as_bytes(); + let mut message_vec = message.as_bytes_vec(); + assert(message_bytes.len() == 11); + assert(message_bytes[0] == 104); + assert(message_bytes[0] == message_vec.get(0)); +} +``` + +## Escape characters + +You can use escape characters for your strings: + +| Escape Sequence | Description | +|-----------------|-----------------| +| `\r` | Carriage Return | +| `\n` | Newline | +| `\t` | Tab | +| `\0` | Null Character | +| `\"` | Double Quote | +| `\\` | Backslash | + +Example: + +```rust +let s = "Hello \"world" // prints "Hello "world" +let s = "hey \tyou"; // prints "hey you" +``` + +## Raw strings + +A raw string begins with the letter `r` and is optionally delimited by a number of hashes `#`. + +Escape characters are *not* processed within raw strings. All contents are interpreted literally. + +Example: + +```rust +let s = r"Hello world"; +let s = r#"Simon says "hello world""#; + +// Any number of hashes may be used (>= 1) as long as the string also terminates with the same number of hashes +let s = r#####"One "#, Two "##, Three "###, Four "####, Five will end the string."#####; +``` diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/structs.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/structs.md new file mode 100644 index 00000000000..dbf68c99813 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/structs.md @@ -0,0 +1,70 @@ +--- +title: Structs +description: + Explore the Struct data type in Noir. Learn about its methods, see real-world examples, and grasp how to effectively define and use Structs in your Noir programs. +keywords: + [ + noir, + struct type, + methods, + examples, + data structures, + ] +sidebar_position: 8 +--- + +A struct also allows for grouping multiple values of different types. Unlike tuples, we can also +name each field. + +> **Note:** The usage of _field_ here refers to each element of the struct and is unrelated to the +> field type of Noir. + +Defining a struct requires giving it a name and listing each field within as `: ` pairs: + +```rust +struct Animal { + hands: Field, + legs: Field, + eyes: u8, +} +``` + +An instance of a struct can then be created with actual values in `: ` pairs in any +order. Struct fields are accessible using their given names: + +```rust +fn main() { + let legs = 4; + + let dog = Animal { + eyes: 2, + hands: 0, + legs, + }; + + let zero = dog.hands; +} +``` + +Structs can also be destructured in a pattern, binding each field to a new variable: + +```rust +fn main() { + let Animal { hands, legs: feet, eyes } = get_octopus(); + + let ten = hands + feet + eyes as u8; +} + +fn get_octopus() -> Animal { + let octopus = Animal { + hands: 0, + legs: 8, + eyes: 2, + }; + + octopus +} +``` + +The new variables can be bound with names different from the original struct field names, as +showcased in the `legs --> feet` binding in the example above. diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/tuples.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/tuples.md new file mode 100644 index 00000000000..2ec5c9c4113 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/data_types/tuples.md @@ -0,0 +1,48 @@ +--- +title: Tuples +description: + Dive into the Tuple data type in Noir. Understand its methods, practical examples, and best practices for efficiently using Tuples in your Noir code. +keywords: + [ + noir, + tuple type, + methods, + examples, + multi-value containers, + ] +sidebar_position: 7 +--- + +A tuple collects multiple values like an array, but with the added ability to collect values of +different types: + +```rust +fn main() { + let tup: (u8, u64, Field) = (255, 500, 1000); +} +``` + +One way to access tuple elements is via destructuring using pattern matching: + +```rust +fn main() { + let tup = (1, 2); + + let (one, two) = tup; + + let three = one + two; +} +``` + +Another way to access tuple elements is via direct member access, using a period (`.`) followed by +the index of the element we want to access. Index `0` corresponds to the first tuple element, `1` to +the second and so on: + +```rust +fn main() { + let tup = (5, 6, 7, 8); + + let five = tup.0; + let eight = tup.3; +} +``` diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/functions.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/functions.md new file mode 100644 index 00000000000..f656cdfd97a --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/functions.md @@ -0,0 +1,226 @@ +--- +title: Functions +description: + Learn how to declare functions and methods in Noir, a programming language with Rust semantics. + This guide covers parameter declaration, return types, call expressions, and more. +keywords: [Noir, Rust, functions, methods, parameter declaration, return types, call expressions] +sidebar_position: 1 +--- + +Functions in Noir follow the same semantics of Rust, though Noir does not support early returns. + +To declare a function the `fn` keyword is used. + +```rust +fn foo() {} +``` + +By default, functions are visible only within the package they are defined. To make them visible outside of that package (for example, as part of a [library](../modules_packages_crates/crates_and_packages.md#libraries)), you should mark them as `pub`: + +```rust +pub fn foo() {} +``` + +You can also restrict the visibility of the function to only the crate it was defined in, by specifying `pub(crate)`: + +```rust +pub(crate) fn foo() {} //foo can only be called within its crate +``` + +All parameters in a function must have a type and all types are known at compile time. The parameter +is pre-pended with a colon and the parameter type. Multiple parameters are separated using a comma. + +```rust +fn foo(x : Field, y : Field){} +``` + +The return type of a function can be stated by using the `->` arrow notation. The function below +states that the foo function must return a `Field`. If the function returns no value, then the arrow +is omitted. + +```rust +fn foo(x : Field, y : Field) -> Field { + x + y +} +``` + +Note that a `return` keyword is unneeded in this case - the last expression in a function's body is +returned. + +## Main function + +If you're writing a binary, the `main` function is the starting point of your program. You can pass all types of expressions to it, as long as they have a fixed size at compile time: + +```rust +fn main(x : Field) // this is fine: passing a Field +fn main(x : [Field; 2]) // this is also fine: passing a Field with known size at compile-time +fn main(x : (Field, bool)) // 👌: passing a (Field, bool) tuple means size 2 +fn main(x : str<5>) // this is fine, as long as you pass a string of size 5 + +fn main(x : Vec) // can't compile, has variable size +fn main(x : [Field]) // can't compile, has variable size +fn main(....// i think you got it by now +``` + +Keep in mind [tests](../../tooling/testing.md) don't differentiate between `main` and any other function. The following snippet passes tests, but won't compile or prove: + +```rust +fn main(x : [Field]) { + assert(x[0] == 1); +} + +#[test] +fn test_one() { + main(&[1, 2]); +} +``` + +```bash +$ nargo test +[testing] Running 1 test functions +[testing] Testing test_one... ok +[testing] All tests passed + +$ nargo check +The application panicked (crashed). +Message: Cannot have variable sized arrays as a parameter to main +``` + +## Call Expressions + +Calling a function in Noir is executed by using the function name and passing in the necessary +arguments. + +Below we show how to call the `foo` function from the `main` function using a call expression: + +```rust +fn main(x : Field, y : Field) { + let z = foo(x); +} + +fn foo(x : Field) -> Field { + x + x +} +``` + +## Methods + +You can define methods in Noir on any struct type in scope. + +```rust +struct MyStruct { + foo: Field, + bar: Field, +} + +impl MyStruct { + fn new(foo: Field) -> MyStruct { + MyStruct { + foo, + bar: 2, + } + } + + fn sum(self) -> Field { + self.foo + self.bar + } +} + +fn main() { + let s = MyStruct::new(40); + assert(s.sum() == 42); +} +``` + +Methods are just syntactic sugar for functions, so if we wanted to we could also call `sum` as +follows: + +```rust +assert(MyStruct::sum(s) == 42); +``` + +It is also possible to specialize which method is chosen depending on the [generic](./generics.md) type that is used. In this example, the `foo` function returns different values depending on its type: + +```rust +struct Foo {} + +impl Foo { + fn foo(self) -> Field { 1 } +} + +impl Foo { + fn foo(self) -> Field { 2 } +} + +fn main() { + let f1: Foo = Foo{}; + let f2: Foo = Foo{}; + assert(f1.foo() + f2.foo() == 3); +} +``` + +Also note that impls with the same method name defined in them cannot overlap. For example, if we already have `foo` defined for `Foo` and `Foo` like we do above, we cannot also define `foo` in an `impl Foo` since it would be ambiguous which version of `foo` to choose. + +```rust +// Including this impl in the same project as the above snippet would +// cause an overlapping impls error +impl Foo { + fn foo(self) -> Field { 3 } +} +``` + +## Lambdas + +Lambdas are anonymous functions. They follow the syntax of Rust - `|arg1, arg2, ..., argN| return_expression`. + +```rust +let add_50 = |val| val + 50; +assert(add_50(100) == 150); +``` + +See [Lambdas](./lambdas.md) for more details. + +## Attributes + +Attributes are metadata that can be applied to a function, using the following syntax: `#[attribute(value)]`. + +Supported attributes include: + +- **builtin**: the function is implemented by the compiler, for efficiency purposes. +- **deprecated**: mark the function as _deprecated_. Calling the function will generate a warning: `warning: use of deprecated function` +- **field**: Used to enable conditional compilation of code depending on the field size. See below for more details +- **oracle**: mark the function as _oracle_; meaning it is an external unconstrained function, implemented in noir_js. See [Unconstrained](./unconstrained.md) and [NoirJS](../../reference/NoirJS/noir_js/index.md) for more details. +- **test**: mark the function as unit tests. See [Tests](../../tooling/testing.md) for more details + +### Field Attribute + +The field attribute defines which field the function is compatible for. The function is conditionally compiled, under the condition that the field attribute matches the Noir native field. +The field can be defined implicitly, by using the name of the elliptic curve usually associated to it - for instance bn254, bls12_381 - or explicitly by using the field (prime) order, in decimal or hexadecimal form. +As a result, it is possible to define multiple versions of a function with each version specialized for a different field attribute. This can be useful when a function requires different parameters depending on the underlying elliptic curve. + +Example: we define the function `foo()` three times below. Once for the default Noir bn254 curve, once for the field $\mathbb F_{23}$, which will normally never be used by Noir, and once again for the bls12_381 curve. + +```rust +#[field(bn254)] +fn foo() -> u32 { + 1 +} + +#[field(23)] +fn foo() -> u32 { + 2 +} + +// This commented code would not compile as foo would be defined twice because it is the same field as bn254 +// #[field(21888242871839275222246405745257275088548364400416034343698204186575808495617)] +// fn foo() -> u32 { +// 2 +// } + +#[field(bls12_381)] +fn foo() -> u32 { + 3 +} +``` + +If the field name is not known to Noir, it will discard the function. Field names are case insensitive. diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/generics.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/generics.md new file mode 100644 index 00000000000..ddd42bf1f9b --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/generics.md @@ -0,0 +1,106 @@ +--- +title: Generics +description: Learn how to use Generics in Noir +keywords: [Noir, Rust, generics, functions, structs] +sidebar_position: 7 +--- + +Generics allow you to use the same functions with multiple different concrete data types. You can +read more about the concept of generics in the Rust documentation +[here](https://doc.rust-lang.org/book/ch10-01-syntax.html). + +Here is a trivial example showing the identity function that supports any type. In Rust, it is +common to refer to the most general type as `T`. We follow the same convention in Noir. + +```rust +fn id(x: T) -> T { + x +} +``` + +## In Structs + +Generics are useful for specifying types in structs. For example, we can specify that a field in a +struct will be of a certain generic type. In this case `value` is of type `T`. + +```rust +struct RepeatedValue { + value: T, + count: Field, +} + +impl RepeatedValue { + fn print(self) { + for _i in 0 .. self.count { + println(self.value); + } + } +} + +fn main() { + let repeated = RepeatedValue { value: "Hello!", count: 2 }; + repeated.print(); +} +``` + +The `print` function will print `Hello!` an arbitrary number of times, twice in this case. + +If we want to be generic over array lengths (which are type-level integers), we can use numeric +generics. Using these looks just like using regular generics, but these generics can resolve to +integers at compile-time, rather than resolving to types. Here's an example of a struct that is +generic over the size of the array it contains internally: + +```rust +struct BigInt { + limbs: [u32; N], +} + +impl BigInt { + // `N` is in scope of all methods in the impl + fn first(first: BigInt, second: BigInt) -> Self { + assert(first.limbs != second.limbs); + first + + fn second(first: BigInt, second: Self) -> Self { + assert(first.limbs != second.limbs); + second + } +} +``` + +## Calling functions on generic parameters + +Since a generic type `T` can represent any type, how can we call functions on the underlying type? +In other words, how can we go from "any type `T`" to "any type `T` that has certain methods available?" + +This is what [traits](../concepts/traits) are for in Noir. Here's an example of a function generic over +any type `T` that implements the `Eq` trait for equality: + +```rust +fn first_element_is_equal(array1: [T; N], array2: [T; N]) -> bool + where T: Eq +{ + if (array1.len() == 0) | (array2.len() == 0) { + true + } else { + array1[0] == array2[0] + } +} + +fn main() { + assert(first_element_is_equal([1, 2, 3], [1, 5, 6])); + + // We can use first_element_is_equal for arrays of any type + // as long as we have an Eq impl for the types we pass in + let array = [MyStruct::new(), MyStruct::new()]; + assert(array_eq(array, array, MyStruct::eq)); +} + +impl Eq for MyStruct { + fn eq(self, other: MyStruct) -> bool { + self.foo == other.foo + } +} +``` + +You can find more details on traits and trait implementations on the [traits page](../concepts/traits). diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/globals.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/globals.md new file mode 100644 index 00000000000..063a3d89248 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/globals.md @@ -0,0 +1,72 @@ +--- +title: Global Variables +description: + Learn about global variables in Noir. Discover how + to declare, modify, and use them in your programs. +keywords: [noir programming language, globals, global variables, constants] +sidebar_position: 8 +--- + +## Globals + + +Noir supports global variables. The global's type can be inferred by the compiler entirely: + +```rust +global N = 5; // Same as `global N: Field = 5` + +global TUPLE = (3, 2); + +fn main() { + assert(N == 5); + assert(N == TUPLE.0 + TUPLE.1); +} +``` + +:::info + +Globals can be defined as any expression, so long as they don't depend on themselves - otherwise there would be a dependency cycle! For example: + +```rust +global T = foo(T); // dependency error +``` + +::: + + +If they are initialized to a literal integer, globals can be used to specify an array's length: + +```rust +global N: Field = 2; + +fn main(y : [Field; N]) { + assert(y[0] == y[1]) +} +``` + +A global from another module can be imported or referenced externally like any other name: + +```rust +global N = 20; + +fn main() { + assert(my_submodule::N != N); +} + +mod my_submodule { + global N: Field = 10; +} +``` + +When a global is used, Noir replaces the name with its definition on each occurrence. +This means globals defined using function calls will repeat the call each time they're used: + +```rust +global RESULT = foo(); + +fn foo() -> [Field; 100] { ... } +``` + +This is usually fine since Noir will generally optimize any function call that does not +refer to a program input into a constant. It should be kept in mind however, if the called +function performs side-effects like `println`, as these will still occur on each use. diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/lambdas.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/lambdas.md new file mode 100644 index 00000000000..be3c7e0b5ca --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/lambdas.md @@ -0,0 +1,81 @@ +--- +title: Lambdas +description: Learn how to use anonymous functions in Noir programming language. +keywords: [Noir programming language, lambda, closure, function, anonymous function] +sidebar_position: 9 +--- + +## Introduction + +Lambdas are anonymous functions. The syntax is `|arg1, arg2, ..., argN| return_expression`. + +```rust +let add_50 = |val| val + 50; +assert(add_50(100) == 150); +``` + +A block can be used as the body of a lambda, allowing you to declare local variables inside it: + +```rust +let cool = || { + let x = 100; + let y = 100; + x + y +} + +assert(cool() == 200); +``` + +## Closures + +Inside the body of a lambda, you can use variables defined in the enclosing function. Such lambdas are called **closures**. In this example `x` is defined inside `main` and is accessed from within the lambda: + +```rust +fn main() { + let x = 100; + let closure = || x + 150; + assert(closure() == 250); +} +``` + +## Passing closures to higher-order functions + +It may catch you by surprise that the following code fails to compile: + +```rust +fn foo(f: fn () -> Field) -> Field { + f() +} + +fn main() { + let (x, y) = (50, 50); + assert(foo(|| x + y) == 100); // error :( +} +``` + +The reason is that the closure's capture environment affects its type - we have a closure that captures two Fields and `foo` +expects a regular function as an argument - those are incompatible. +:::note + +Variables contained within the `||` are the closure's parameters, and the expression that follows it is the closure's body. The capture environment is comprised of any variables used in the closure's body that are not parameters. + +E.g. in |x| x + y, y would be a captured variable, but x would not be, since it is a parameter of the closure. + +::: +The syntax for the type of a closure is `fn[env](args) -> ret_type`, where `env` is the capture environment of the closure - +in this example that's `(Field, Field)`. + +The best solution in our case is to make `foo` generic over the environment type of its parameter, so that it can be called +with closures with any environment, as well as with regular functions: + +```rust +fn foo(f: fn[Env]() -> Field) -> Field { + f() +} + +fn main() { + let (x, y) = (50, 50); + assert(foo(|| x + y) == 100); // compiles fine + assert(foo(|| 60) == 60); // compiles fine +} +``` diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/mutability.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/mutability.md new file mode 100644 index 00000000000..fdeef6a87c5 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/mutability.md @@ -0,0 +1,121 @@ +--- +title: Mutability +description: + Learn about mutable variables in Noir. Discover how + to declare, modify, and use them in your programs. +keywords: [noir programming language, mutability in noir, mutable variables] +sidebar_position: 8 +--- + +Variables in noir can be declared mutable via the `mut` keyword. Mutable variables can be reassigned +to via an assignment expression. + +```rust +let x = 2; +x = 3; // error: x must be mutable to be assigned to + +let mut y = 3; +let y = 4; // OK +``` + +The `mut` modifier can also apply to patterns: + +```rust +let (a, mut b) = (1, 2); +a = 11; // error: a must be mutable to be assigned to +b = 12; // OK + +let mut (c, d) = (3, 4); +c = 13; // OK +d = 14; // OK + +// etc. +let MyStruct { x: mut y } = MyStruct { x: a }; +// y is now in scope +``` + +Note that mutability in noir is local and everything is passed by value, so if a called function +mutates its parameters then the parent function will keep the old value of the parameters. + +```rust +fn main() -> pub Field { + let x = 3; + helper(x); + x // x is still 3 +} + +fn helper(mut x: i32) { + x = 4; +} +``` + +## Non-local mutability + +Non-local mutability can be achieved through the mutable reference type `&mut T`: + +```rust +fn set_to_zero(x: &mut Field) { + *x = 0; +} + +fn main() { + let mut y = 42; + set_to_zero(&mut y); + assert(*y == 0); +} +``` + +When creating a mutable reference, the original variable being referred to (`y` in this +example) must also be mutable. Since mutable references are a reference type, they must +be explicitly dereferenced via `*` to retrieve the underlying value. Note that this yields +a copy of the value, so mutating this copy will not change the original value behind the +reference: + +```rust +fn main() { + let mut x = 1; + let x_ref = &mut x; + + let mut y = *x_ref; + let y_ref = &mut y; + + x = 2; + *x_ref = 3; + + y = 4; + *y_ref = 5; + + assert(x == 3); + assert(*x_ref == 3); + assert(y == 5); + assert(*y_ref == 5); +} +``` + +Note that types in Noir are actually deeply immutable so the copy that occurs when +dereferencing is only a conceptual copy - no additional constraints will occur. + +Mutable references can also be stored within structs. Note that there is also +no lifetime parameter on these unlike rust. This is because the allocated memory +always lasts the entire program - as if it were an array of one element. + +```rust +struct Foo { + x: &mut Field +} + +impl Foo { + fn incr(mut self) { + *self.x += 1; + } +} + +fn main() { + let foo = Foo { x: &mut 0 }; + foo.incr(); + assert(*foo.x == 1); +} +``` + +In general, you should avoid non-local & shared mutability unless it is needed. Sticking +to only local mutability will improve readability and potentially improve compiler optimizations as well. diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/ops.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/ops.md new file mode 100644 index 00000000000..c35c36c38a9 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/ops.md @@ -0,0 +1,98 @@ +--- +title: Logical Operations +description: + Learn about the supported arithmetic and logical operations in the Noir programming language. + Discover how to perform operations on private input types, integers, and booleans. +keywords: + [ + Noir programming language, + supported operations, + arithmetic operations, + logical operations, + predicate operators, + bitwise operations, + short-circuiting, + backend, + ] +sidebar_position: 3 +--- + +# Operations + +## Table of Supported Operations + +| Operation | Description | Requirements | +| :-------- | :------------------------------------------------------------: | -------------------------------------: | +| + | Adds two private input types together | Types must be private input | +| - | Subtracts two private input types together | Types must be private input | +| \* | Multiplies two private input types together | Types must be private input | +| / | Divides two private input types together | Types must be private input | +| ^ | XOR two private input types together | Types must be integer | +| & | AND two private input types together | Types must be integer | +| \| | OR two private input types together | Types must be integer | +| \<\< | Left shift an integer by another integer amount | Types must be integer, shift must be u8 | +| >> | Right shift an integer by another integer amount | Types must be integer, shift must be u8 | +| ! | Bitwise not of a value | Type must be integer or boolean | +| \< | returns a bool if one value is less than the other | Upper bound must have a known bit size | +| \<= | returns a bool if one value is less than or equal to the other | Upper bound must have a known bit size | +| > | returns a bool if one value is more than the other | Upper bound must have a known bit size | +| >= | returns a bool if one value is more than or equal to the other | Upper bound must have a known bit size | +| == | returns a bool if one value is equal to the other | Both types must not be constants | +| != | returns a bool if one value is not equal to the other | Both types must not be constants | + +### Predicate Operators + +`<,<=, !=, == , >, >=` are known as predicate/comparison operations because they compare two values. +This differs from the operations such as `+` where the operands are used in _computation_. + +### Bitwise Operations Example + +```rust +fn main(x : Field) { + let y = x as u32; + let z = y & y; +} +``` + +`z` is implicitly constrained to be the result of `y & y`. The `&` operand is used to denote bitwise +`&`. + +> `x & x` would not compile as `x` is a `Field` and not an integer type. + +### Logical Operators + +Noir has no support for the logical operators `||` and `&&`. This is because encoding the +short-circuiting that these operators require can be inefficient for Noir's backend. Instead you can +use the bitwise operators `|` and `&` which operate identically for booleans, just without the +short-circuiting. + +```rust +let my_val = 5; + +let mut flag = 1; +if (my_val > 6) | (my_val == 0) { + flag = 0; +} +assert(flag == 1); + +if (my_val != 10) & (my_val < 50) { + flag = 0; +} +assert(flag == 0); +``` + +### Shorthand operators + +Noir shorthand operators for most of the above operators, namely `+=, -=, *=, /=, %=, &=, |=, ^=, <<=`, and `>>=`. These allow for more concise syntax. For example: + +```rust +let mut i = 0; +i = i + 1; +``` + +could be written as: + +```rust +let mut i = 0; +i += 1; +``` diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/oracles.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/oracles.md new file mode 100644 index 00000000000..aa380b5f7b8 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/oracles.md @@ -0,0 +1,31 @@ +--- +title: Oracles +description: Dive into how Noir supports Oracles via RPC calls, and learn how to declare an Oracle in Noir with our comprehensive guide. +keywords: + - Noir + - Oracles + - RPC Calls + - Unconstrained Functions + - Programming + - Blockchain +sidebar_position: 6 +--- + +:::note + +This is an experimental feature that is not fully documented. If you notice any outdated information or potential improvements to this page, pull request contributions are very welcome: https://github.com/noir-lang/noir + +::: + +Noir has support for Oracles via RPC calls. This means Noir will make an RPC call and use the return value for proof generation. + +Since Oracles are not resolved by Noir, they are [`unconstrained` functions](./unconstrained.md) + +You can declare an Oracle through the `#[oracle()]` flag. Example: + +```rust +#[oracle(get_number_sequence)] +unconstrained fn get_number_sequence(_size: Field) -> [Field] {} +``` + +The timeout for when using an external RPC oracle resolver can be set with the `NARGO_FOREIGN_CALL_TIMEOUT` environment variable. This timeout is in units of milliseconds. diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/shadowing.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/shadowing.md new file mode 100644 index 00000000000..5ce6130d201 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/shadowing.md @@ -0,0 +1,44 @@ +--- +title: Shadowing +sidebar_position: 12 +--- + +Noir allows for inheriting variables' values and re-declaring them with the same name similar to Rust, known as shadowing. + +For example, the following function is valid in Noir: + +```rust +fn main() { + let x = 5; + + { + let x = x * 2; + assert (x == 10); + } + + assert (x == 5); +} +``` + +In this example, a variable x is first defined with the value 5. + +The local scope that follows shadows the original x, i.e. creates a local mutable x based on the value of the original x. It is given a value of 2 times the original x. + +When we return to the main scope, x once again refers to just the original x, which stays at the value of 5. + +## Temporal mutability + +One way that shadowing is useful, in addition to ergonomics across scopes, is for temporarily mutating variables. + +```rust +fn main() { + let age = 30; + // age = age + 5; // Would error as `age` is immutable by default. + + let mut age = age + 5; // Temporarily mutates `age` with a new value. + + let age = age; // Locks `age`'s mutability again. + + assert (age == 35); +} +``` diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/traits.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/traits.md new file mode 100644 index 00000000000..ef1445a5907 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/traits.md @@ -0,0 +1,389 @@ +--- +title: Traits +description: + Traits in Noir can be used to abstract out a common interface for functions across + several data types. +keywords: [noir programming language, traits, interfaces, generic, protocol] +sidebar_position: 14 +--- + +## Overview + +Traits in Noir are a useful abstraction similar to interfaces or protocols in other languages. Each trait defines +the interface of several methods contained within the trait. Types can then implement this trait by providing +implementations for these methods. For example in the program: + +```rust +struct Rectangle { + width: Field, + height: Field, +} + +impl Rectangle { + fn area(self) -> Field { + self.width * self.height + } +} + +fn log_area(r: Rectangle) { + println(r.area()); +} +``` + +We have a function `log_area` to log the area of a `Rectangle`. Now how should we change the program if we want this +function to work on `Triangle`s as well?: + +```rust +struct Triangle { + width: Field, + height: Field, +} + +impl Triangle { + fn area(self) -> Field { + self.width * self.height / 2 + } +} +``` + +Making `log_area` generic over all types `T` would be invalid since not all types have an `area` method. Instead, we can +introduce a new `Area` trait and make `log_area` generic over all types `T` that implement `Area`: + +```rust +trait Area { + fn area(self) -> Field; +} + +fn log_area(shape: T) where T: Area { + println(shape.area()); +} +``` + +We also need to explicitly implement `Area` for `Rectangle` and `Triangle`. We can do that by changing their existing +impls slightly. Note that the parameter types and return type of each of our `area` methods must match those defined +by the `Area` trait. + +```rust +impl Area for Rectangle { + fn area(self) -> Field { + self.width * self.height + } +} + +impl Area for Triangle { + fn area(self) -> Field { + self.width * self.height / 2 + } +} +``` + +Now we have a working program that is generic over any type of Shape that is used! Others can even use this program +as a library with their own types - such as `Circle` - as long as they also implement `Area` for these types. + +## Where Clauses + +As seen in `log_area` above, when we want to create a function or method that is generic over any type that implements +a trait, we can add a where clause to the generic function. + +```rust +fn log_area(shape: T) where T: Area { + println(shape.area()); +} +``` + +It is also possible to apply multiple trait constraints on the same variable at once by combining traits with the `+` +operator. Similarly, we can have multiple trait constraints by separating each with a comma: + +```rust +fn foo(elements: [T], thing: U) where + T: Default + Add + Eq, + U: Bar, +{ + let mut sum = T::default(); + + for element in elements { + sum += element; + } + + if sum == T::default() { + thing.bar(); + } +} +``` + +## Generic Implementations + +You can add generics to a trait implementation by adding the generic list after the `impl` keyword: + +```rust +trait Second { + fn second(self) -> Field; +} + +impl Second for (T, Field) { + fn second(self) -> Field { + self.1 + } +} +``` + +You can also implement a trait for every type this way: + +```rust +trait Debug { + fn debug(self); +} + +impl Debug for T { + fn debug(self) { + println(self); + } +} + +fn main() { + 1.debug(); +} +``` + +### Generic Trait Implementations With Where Clauses + +Where clauses can also be placed on trait implementations themselves to restrict generics in a similar way. +For example, while `impl Foo for T` implements the trait `Foo` for every type, `impl Foo for T where T: Bar` +will implement `Foo` only for types that also implement `Bar`. This is often used for implementing generic types. +For example, here is the implementation for array equality: + +```rust +impl Eq for [T; N] where T: Eq { + // Test if two arrays have the same elements. + // Because both arrays must have length N, we know their lengths already match. + fn eq(self, other: Self) -> bool { + let mut result = true; + + for i in 0 .. self.len() { + // The T: Eq constraint is needed to call == on the array elements here + result &= self[i] == other[i]; + } + + result + } +} +``` + +## Generic Traits + +Traits themselves can also be generic by placing the generic arguments after the trait name. These generics are in +scope of every item within the trait. + +```rust +trait Into { + // Convert `self` to type `T` + fn into(self) -> T; +} +``` + +When implementing generic traits the generic arguments of the trait must be specified. This is also true anytime +when referencing a generic trait (e.g. in a `where` clause). + +```rust +struct MyStruct { + array: [Field; 2], +} + +impl Into<[Field; 2]> for MyStruct { + fn into(self) -> [Field; 2] { + self.array + } +} + +fn as_array(x: T) -> [Field; 2] + where T: Into<[Field; 2]> +{ + x.into() +} + +fn main() { + let array = [1, 2]; + let my_struct = MyStruct { array }; + + assert_eq(as_array(my_struct), array); +} +``` + +## Trait Methods With No `self` + +A trait can contain any number of methods, each of which have access to the `Self` type which represents each type +that eventually implements the trait. Similarly, the `self` variable is available as well but is not required to be used. +For example, we can define a trait to create a default value for a type. This trait will need to return the `Self` type +but doesn't need to take any parameters: + +```rust +trait Default { + fn default() -> Self; +} +``` + +Implementing this trait can be done similarly to any other trait: + +```rust +impl Default for Field { + fn default() -> Field { + 0 + } +} + +struct MyType {} + +impl Default for MyType { + fn default() -> Field { + MyType {} + } +} +``` + +However, since there is no `self` parameter, we cannot call it via the method call syntax `object.method()`. +Instead, we'll need to refer to the function directly. This can be done either by referring to the +specific impl `MyType::default()` or referring to the trait itself `Default::default()`. In the later +case, type inference determines the impl that is selected. + +```rust +let my_struct = MyStruct::default(); + +let x: Field = Default::default(); +let result = x + Default::default(); +``` + +:::warning + +```rust +let _ = Default::default(); +``` + +If type inference cannot select which impl to use because of an ambiguous `Self` type, an impl will be +arbitrarily selected. This occurs most often when the result of a trait function call with no parameters +is unused. To avoid this, when calling a trait function with no `self` or `Self` parameters or return type, +always refer to it via the implementation type's namespace - e.g. `MyType::default()`. +This is set to change to an error in future Noir versions. + +::: + +## Default Method Implementations + +A trait can also have default implementations of its methods by giving a body to the desired functions. +Note that this body must be valid for all types that may implement the trait. As a result, the only +valid operations on `self` will be operations valid for any type or other operations on the trait itself. + +```rust +trait Numeric { + fn add(self, other: Self) -> Self; + + // Default implementation of double is (self + self) + fn double(self) -> Self { + self.add(self) + } +} +``` + +When implementing a trait with default functions, a type may choose to implement only the required functions: + +```rust +impl Numeric for Field { + fn add(self, other: Field) -> Field { + self + other + } +} +``` + +Or it may implement the optional methods as well: + +```rust +impl Numeric for u32 { + fn add(self, other: u32) -> u32 { + self + other + } + + fn double(self) -> u32 { + self * 2 + } +} +``` + +## Impl Specialization + +When implementing traits for a generic type it is possible to implement the trait for only a certain combination +of generics. This can be either as an optimization or because those specific generics are required to implement the trait. + +```rust +trait Sub { + fn sub(self, other: Self) -> Self; +} + +struct NonZero { + value: T, +} + +impl Sub for NonZero { + fn sub(self, other: Self) -> Self { + let value = self.value - other.value; + assert(value != 0); + NonZero { value } + } +} +``` + +## Overlapping Implementations + +Overlapping implementations are disallowed by Noir to ensure Noir's decision on which impl to select is never ambiguous. +This means if a trait `Foo` is already implemented +by a type `Bar` for all `T`, then we cannot also have a separate impl for `Bar` (or any other +type argument). Similarly, if there is an impl for all `T` such as `impl Debug for T`, we cannot create +any more impls to `Debug` for other types since it would be ambiguous which impl to choose for any given +method call. + +```rust +trait Trait {} + +// Previous impl defined here +impl Trait for (A, B) {} + +// error: Impl for type `(Field, Field)` overlaps with existing impl +impl Trait for (Field, Field) {} +``` + +## Trait Coherence + +Another restriction on trait implementations is coherence. This restriction ensures other crates cannot create +impls that may overlap with other impls, even if several unrelated crates are used as dependencies in the same +program. + +The coherence restriction is: to implement a trait, either the trait itself or the object type must be declared +in the crate the impl is in. + +In practice this often comes up when using types provided by libraries. If a library provides a type `Foo` that does +not implement a trait in the standard library such as `Default`, you may not `impl Default for Foo` in your own crate. +While restrictive, this prevents later issues or silent changes in the program if the `Foo` library later added its +own impl for `Default`. If you are a user of the `Foo` library in this scenario and need a trait not implemented by the +library your choices are to either submit a patch to the library or use the newtype pattern. + +### The Newtype Pattern + +The newtype pattern gets around the coherence restriction by creating a new wrapper type around the library type +that we cannot create `impl`s for. Since the new wrapper type is defined in our current crate, we can create +impls for any trait we need on it. + +```rust +struct Wrapper { + foo: dep::some_library::Foo, +} + +impl Default for Wrapper { + fn default() -> Wrapper { + Wrapper { + foo: dep::some_library::Foo::new(), + } + } +} +``` + +Since we have an impl for our own type, the behavior of this code will not change even if `some_library` is updated +to provide its own `impl Default for Foo`. The downside of this pattern is that it requires extra wrapping and +unwrapping of values when converting to and from the `Wrapper` and `Foo` types. diff --git a/docs/versioned_docs/version-v0.30.0/noir/concepts/unconstrained.md b/docs/versioned_docs/version-v0.30.0/noir/concepts/unconstrained.md new file mode 100644 index 00000000000..b8e71fe65f0 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/concepts/unconstrained.md @@ -0,0 +1,99 @@ +--- +title: Unconstrained Functions +description: "Learn about what unconstrained functions in Noir are, how to use them and when you'd want to." + +keywords: [Noir programming language, unconstrained, open] +sidebar_position: 5 +--- + +Unconstrained functions are functions which do not constrain any of the included computation and allow for non-deterministic computation. + +## Why? + +Zero-knowledge (ZK) domain-specific languages (DSL) enable developers to generate ZK proofs from their programs by compiling code down to the constraints of an NP complete language (such as R1CS or PLONKish languages). However, the hard bounds of a constraint system can be very limiting to the functionality of a ZK DSL. + +Enabling a circuit language to perform unconstrained execution is a powerful tool. Said another way, unconstrained execution lets developers generate witnesses from code that does not generate any constraints. Being able to execute logic outside of a circuit is critical for both circuit performance and constructing proofs on information that is external to a circuit. + +Fetching information from somewhere external to a circuit can also be used to enable developers to improve circuit efficiency. + +A ZK DSL does not just prove computation, but proves that some computation was handled correctly. Thus, it is necessary that when we switch from performing some operation directly inside of a circuit to inside of an unconstrained environment that the appropriate constraints are still laid down elsewhere in the circuit. + +## Example + +An in depth example might help drive the point home. This example comes from the excellent [post](https://discord.com/channels/1113924620781883405/1124022445054111926/1128747641853972590) by Tom in the Noir Discord. + +Let's look at how we can optimize a function to turn a `u72` into an array of `u8`s. + +```rust +fn main(num: u72) -> pub [u8; 8] { + let mut out: [u8; 8] = [0; 8]; + for i in 0..8 { + out[i] = (num >> (56 - (i * 8)) as u72 & 0xff) as u8; + } + + out +} +``` + +``` +Total ACIR opcodes generated for language PLONKCSat { width: 3 }: 91 +Backend circuit size: 3619 +``` + +A lot of the operations in this function are optimized away by the compiler (all the bit-shifts turn into divisions by constants). However we can save a bunch of gates by casting to u8 a bit earlier. This automatically truncates the bit-shifted value to fit in a u8 which allows us to remove the AND against 0xff. This saves us ~480 gates in total. + +```rust +fn main(num: u72) -> pub [u8; 8] { + let mut out: [u8; 8] = [0; 8]; + for i in 0..8 { + out[i] = (num >> (56 - (i * 8)) as u8; + } + + out +} +``` + +``` +Total ACIR opcodes generated for language PLONKCSat { width: 3 }: 75 +Backend circuit size: 3143 +``` + +Those are some nice savings already but we can do better. This code is all constrained so we're proving every step of calculating out using num, but we don't actually care about how we calculate this, just that it's correct. This is where brillig comes in. + +It turns out that truncating a u72 into a u8 is hard to do inside a snark, each time we do as u8 we lay down 4 ACIR opcodes which get converted into multiple gates. It's actually much easier to calculate num from out than the other way around. All we need to do is multiply each element of out by a constant and add them all together, both relatively easy operations inside a snark. + +We can then run u72_to_u8 as unconstrained brillig code in order to calculate out, then use that result in our constrained function and assert that if we were to do the reverse calculation we'd get back num. This looks a little like the below: + +```rust +fn main(num: u72) -> pub [u8; 8] { + let out = u72_to_u8(num); + + let mut reconstructed_num: u72 = 0; + for i in 0..8 { + reconstructed_num += (out[i] as u72 << (56 - (8 * i))); + } + assert(num == reconstructed_num); + out +} + +unconstrained fn u72_to_u8(num: u72) -> [u8; 8] { + let mut out: [u8; 8] = [0; 8]; + for i in 0..8 { + out[i] = (num >> (56 - (i * 8))) as u8; + } + out +} +``` + +``` +Total ACIR opcodes generated for language PLONKCSat { width: 3 }: 78 +Backend circuit size: 2902 +``` + +This ends up taking off another ~250 gates from our circuit! We've ended up with more ACIR opcodes than before but they're easier for the backend to prove (resulting in fewer gates). + +Generally we want to use brillig whenever there's something that's easy to verify but hard to compute within the circuit. For example, if you wanted to calculate a square root of a number it'll be a much better idea to calculate this in brillig and then assert that if you square the result you get back your number. + +## Break and Continue + +In addition to loops over runtime bounds, `break` and `continue` are also available in unconstrained code. See [break and continue](../concepts/control_flow/#break-and-continue) diff --git a/docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/_category_.json b/docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/_category_.json new file mode 100644 index 00000000000..1debcfe7675 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/_category_.json @@ -0,0 +1,6 @@ +{ + "label": "Modules, Packages and Crates", + "position": 2, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/crates_and_packages.md b/docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/crates_and_packages.md new file mode 100644 index 00000000000..95ee9f52ab2 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/crates_and_packages.md @@ -0,0 +1,43 @@ +--- +title: Crates and Packages +description: Learn how to use Crates and Packages in your Noir project +keywords: [Nargo, dependencies, package management, crates, package] +sidebar_position: 0 +--- + +## Crates + +A crate is the smallest amount of code that the Noir compiler considers at a time. +Crates can contain modules, and the modules may be defined in other files that get compiled with the crate, as we’ll see in the coming sections. + +### Crate Types + +A Noir crate can come in several forms: binaries, libraries or contracts. + +#### Binaries + +_Binary crates_ are programs which you can compile to an ACIR circuit which you can then create proofs against. Each must have a function called `main` that defines the ACIR circuit which is to be proved. + +#### Libraries + +_Library crates_ don't have a `main` function and they don't compile down to ACIR. Instead they define functionality intended to be shared with multiple projects, and eventually included in a binary crate. + +#### Contracts + +Contract crates are similar to binary crates in that they compile to ACIR which you can create proofs against. They are different in that they do not have a single `main` function, but are a collection of functions to be deployed to the [Aztec network](https://aztec.network). You can learn more about the technical details of Aztec in the [monorepo](https://github.com/AztecProtocol/aztec-packages) or contract [examples](https://github.com/AztecProtocol/aztec-packages/tree/master/noir-projects/noir-contracts/contracts). + +### Crate Root + +Every crate has a root, which is the source file that the compiler starts, this is also known as the root module. The Noir compiler does not enforce any conditions on the name of the file which is the crate root, however if you are compiling via Nargo the crate root must be called `lib.nr` or `main.nr` for library or binary crates respectively. + +## Packages + +A Nargo _package_ is a collection of one of more crates that provides a set of functionality. A package must include a Nargo.toml file. + +A package _must_ contain either a library or a binary crate, but not both. + +### Differences from Cargo Packages + +One notable difference between Rust's Cargo and Noir's Nargo is that while Cargo allows a package to contain an unlimited number of binary crates and a single library crate, Nargo currently only allows a package to contain a single crate. + +In future this restriction may be lifted to allow a Nargo package to contain both a binary and library crate or multiple binary crates. diff --git a/docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/dependencies.md b/docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/dependencies.md new file mode 100644 index 00000000000..04c1703d929 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/dependencies.md @@ -0,0 +1,124 @@ +--- +title: Dependencies +description: + Learn how to specify and manage dependencies in Nargo, allowing you to upload packages to GitHub + and use them easily in your project. +keywords: [Nargo, dependencies, GitHub, package management, versioning] +sidebar_position: 1 +--- + +Nargo allows you to upload packages to GitHub and use them as dependencies. + +## Specifying a dependency + +Specifying a dependency requires a tag to a specific commit and the git url to the url containing +the package. + +Currently, there are no requirements on the tag contents. If requirements are added, it would follow +semver 2.0 guidelines. + +> Note: Without a `tag` , there would be no versioning and dependencies would change each time you +> compile your project. + +For example, to add the [ecrecover-noir library](https://github.com/colinnielsen/ecrecover-noir) to your project, add it to `Nargo.toml`: + +```toml +# Nargo.toml + +[dependencies] +ecrecover = {tag = "v0.8.0", git = "https://github.com/colinnielsen/ecrecover-noir"} +``` + +If the module is in a subdirectory, you can define a subdirectory in your git repository, for example: + +```toml +# Nargo.toml + +[dependencies] +easy_private_token_contract = {tag ="v0.1.0-alpha62", git = "https://github.com/AztecProtocol/aztec-packages", directory = "noir-contracts/contracts/easy_private_token_contract"} +``` + +## Specifying a local dependency + +You can also specify dependencies that are local to your machine. + +For example, this file structure has a library and binary crate + +```tree +├── binary_crate +│   ├── Nargo.toml +│   └── src +│   └── main.nr +└── lib_a + ├── Nargo.toml + └── src + └── lib.nr +``` + +Inside of the binary crate, you can specify: + +```toml +# Nargo.toml + +[dependencies] +lib_a = { path = "../lib_a" } +``` + +## Importing dependencies + +You can import a dependency to a Noir file using the following syntax. For example, to import the +ecrecover-noir library and local lib_a referenced above: + +```rust +use dep::ecrecover; +use dep::lib_a; +``` + +You can also import only the specific parts of dependency that you want to use, like so: + +```rust +use dep::std::hash::sha256; +use dep::std::scalar_mul::fixed_base_embedded_curve; +``` + +Lastly, as demonstrated in the +[elliptic curve example](../standard_library/cryptographic_primitives/ec_primitives#examples), you +can import multiple items in the same line by enclosing them in curly braces: + +```rust +use dep::std::ec::tecurve::affine::{Curve, Point}; +``` + +We don't have a way to consume libraries from inside a [workspace](./workspaces) as external dependencies right now. + +Inside a workspace, these are consumed as `{ path = "../to_lib" }` dependencies in Nargo.toml. + +## Dependencies of Dependencies + +Note that when you import a dependency, you also get access to all of the dependencies of that package. + +For example, the [phy_vector](https://github.com/resurgencelabs/phy_vector) library imports an [fraction](https://github.com/resurgencelabs/fraction) library. If you're importing the phy_vector library, then you can access the functions in fractions library like so: + +```rust +use dep::phy_vector; + +fn main(x : Field, y : pub Field) { + //... + let f = phy_vector::fraction::toFraction(true, 2, 1); + //... +} +``` + +## Available Libraries + +Noir does not currently have an official package manager. You can find a list of available Noir libraries in the [awesome-noir repo here](https://github.com/noir-lang/awesome-noir#libraries). + +Some libraries that are available today include: + +- [Standard Library](https://github.com/noir-lang/noir/tree/master/noir_stdlib) - the Noir Standard Library +- [Ethereum Storage Proof Verification](https://github.com/aragonzkresearch/noir-trie-proofs) - a library that contains the primitives necessary for RLP decoding (in the form of look-up table construction) and Ethereum state and storage proof verification (or verification of any trie proof involving 32-byte long keys) +- [BigInt](https://github.com/shuklaayush/noir-bigint) - a library that provides a custom BigUint56 data type, allowing for computations on large unsigned integers +- [ECrecover](https://github.com/colinnielsen/ecrecover-noir/tree/main) - a library to verify an ECDSA signature and return the source Ethereum address +- [Sparse Merkle Tree Verifier](https://github.com/vocdoni/smtverifier-noir/tree/main) - a library for verification of sparse Merkle trees +- [Signed Int](https://github.com/resurgencelabs/signed_int) - a library for accessing a custom Signed Integer data type, allowing access to negative numbers on Noir +- [Fraction](https://github.com/resurgencelabs/fraction) - a library for accessing fractional number data type in Noir, allowing results that aren't whole numbers diff --git a/docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/modules.md b/docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/modules.md new file mode 100644 index 00000000000..ae822a1cff4 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/modules.md @@ -0,0 +1,105 @@ +--- +title: Modules +description: + Learn how to organize your files using modules in Noir, following the same convention as Rust's + module system. Examples included. +keywords: [Noir, Rust, modules, organizing files, sub-modules] +sidebar_position: 2 +--- + +Noir's module system follows the same convention as the _newer_ version of Rust's module system. + +## Purpose of Modules + +Modules are used to organize files. Without modules all of your code would need to live in a single +file. In Noir, the compiler does not automatically scan all of your files to detect modules. This +must be done explicitly by the developer. + +## Examples + +### Importing a module in the crate root + +Filename : `src/main.nr` + +```rust +mod foo; + +fn main() { + foo::hello_world(); +} +``` + +Filename : `src/foo.nr` + +```rust +fn from_foo() {} +``` + +In the above snippet, the crate root is the `src/main.nr` file. The compiler sees the module +declaration `mod foo` which prompts it to look for a foo.nr file. + +Visually this module hierarchy looks like the following : + +``` +crate + ├── main + │ + └── foo + └── from_foo + +``` + +### Importing a module throughout the tree + +All modules are accessible from the `crate::` namespace. + +``` +crate + ├── bar + ├── foo + └── main + +``` + +In the above snippet, if `bar` would like to use functions in `foo`, it can do so by `use crate::foo::function_name`. + +### Sub-modules + +Filename : `src/main.nr` + +```rust +mod foo; + +fn main() { + foo::from_foo(); +} +``` + +Filename : `src/foo.nr` + +```rust +mod bar; +fn from_foo() {} +``` + +Filename : `src/foo/bar.nr` + +```rust +fn from_bar() {} +``` + +In the above snippet, we have added an extra module to the module tree; `bar`. `bar` is a submodule +of `foo` hence we declare bar in `foo.nr` with `mod bar`. Since `foo` is not the crate root, the +compiler looks for the file associated with the `bar` module in `src/foo/bar.nr` + +Visually the module hierarchy looks as follows: + +``` +crate + ├── main + │ + └── foo + ├── from_foo + └── bar + └── from_bar +``` diff --git a/docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/workspaces.md b/docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/workspaces.md new file mode 100644 index 00000000000..513497f12bf --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/modules_packages_crates/workspaces.md @@ -0,0 +1,42 @@ +--- +title: Workspaces +sidebar_position: 3 +--- + +Workspaces are a feature of nargo that allow you to manage multiple related Noir packages in a single repository. A workspace is essentially a group of related projects that share common build output directories and configurations. + +Each Noir project (with it's own Nargo.toml file) can be thought of as a package. Each package is expected to contain exactly one "named circuit", being the "name" defined in Nargo.toml with the program logic defined in `./src/main.nr`. + +For a project with the following structure: + +```tree +├── crates +│ ├── a +│ │ ├── Nargo.toml +│ │ └── Prover.toml +│ │ └── src +│ │ └── main.nr +│ └── b +│ ├── Nargo.toml +│ └── Prover.toml +│ └── src +│ └── main.nr +│ +└── Nargo.toml +``` + +You can define a workspace in Nargo.toml like so: + +```toml +[workspace] +members = ["crates/a", "crates/b"] +default-member = "crates/a" +``` + +`members` indicates which packages are included in the workspace. As such, all member packages of a workspace will be processed when the `--workspace` flag is used with various commands or if a `default-member` is not specified. + +`default-member` indicates which package various commands process by default. + +Libraries can be defined in a workspace. Inside a workspace, these are consumed as `{ path = "../to_lib" }` dependencies in Nargo.toml. + +Inside a workspace, these are consumed as `{ path = "../to_lib" }` dependencies in Nargo.toml. diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/_category_.json b/docs/versioned_docs/version-v0.30.0/noir/standard_library/_category_.json new file mode 100644 index 00000000000..af04c0933fd --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/_category_.json @@ -0,0 +1,6 @@ +{ + "label": "Standard Library", + "position": 1, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/bigint.md b/docs/versioned_docs/version-v0.30.0/noir/standard_library/bigint.md new file mode 100644 index 00000000000..2bfdeec6631 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/bigint.md @@ -0,0 +1,122 @@ +--- +title: Big Integers +description: How to use big integers from Noir standard library +keywords: + [ + Big Integer, + Noir programming language, + Noir libraries, + ] +--- + +The BigInt module in the standard library exposes some class of integers which do not fit (well) into a Noir native field. It implements modulo arithmetic, modulo a 'big' prime number. + +:::note + +The module can currently be considered as `Field`s with fixed modulo sizes used by a set of elliptic curves, in addition to just the native curve. [More work](https://github.com/noir-lang/noir/issues/510) is needed to achieve arbitrarily sized big integers. + +::: + +Currently 6 classes of integers (i.e 'big' prime numbers) are available in the module, namely: + +- BN254 Fq: Bn254Fq +- BN254 Fr: Bn254Fr +- Secp256k1 Fq: Secpk1Fq +- Secp256k1 Fr: Secpk1Fr +- Secp256r1 Fr: Secpr1Fr +- Secp256r1 Fq: Secpr1Fq + +Where XXX Fq and XXX Fr denote respectively the order of the base and scalar field of the (usual) elliptic curve XXX. +For instance the big integer 'Secpk1Fq' in the standard library refers to integers modulo $2^{256}-2^{32}-977$. + +Feel free to explore the source code for the other primes: + +```rust title="big_int_definition" showLineNumbers +struct BigInt { + pointer: u32, + modulus: u32, +} +``` +> Source code: noir_stdlib/src/bigint.nr#L14-L19 + + +## Example usage + +A common use-case is when constructing a big integer from its bytes representation, and performing arithmetic operations on it: + +```rust title="big_int_example" showLineNumbers +fn big_int_example(x: u8, y: u8) { + let a = Secpk1Fq::from_le_bytes(&[x, y, 0, 45, 2]); + let b = Secpk1Fq::from_le_bytes(&[y, x, 9]); + let c = (a + b) * b / a; + let d = c.to_le_bytes(); + println(d[0]); +} +``` +> Source code: test_programs/execution_success/bigint/src/main.nr#L70-L78 + + +## Methods + +The available operations for each big integer are: + +### from_le_bytes + +Construct a big integer from its little-endian bytes representation. Example: + +```rust + // Construct a big integer from a slice of bytes + let a = Secpk1Fq::from_le_bytes(&[x, y, 0, 45, 2]); + // Construct a big integer from an array of 32 bytes + let a = Secpk1Fq::from_le_bytes_32([1;32]); + ``` + +Sure, here's the formatted version of the remaining methods: + +### to_le_bytes + +Return the little-endian bytes representation of a big integer. Example: + +```rust +let bytes = a.to_le_bytes(); +``` + +### add + +Add two big integers. Example: + +```rust +let sum = a + b; +``` + +### sub + +Subtract two big integers. Example: + +```rust +let difference = a - b; +``` + +### mul + +Multiply two big integers. Example: + +```rust +let product = a * b; +``` + +### div + +Divide two big integers. Note that division is field division and not euclidean division. Example: + +```rust +let quotient = a / b; +``` + +### eq + +Compare two big integers. Example: + +```rust +let are_equal = a == b; +``` diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/black_box_fns.md b/docs/versioned_docs/version-v0.30.0/noir/standard_library/black_box_fns.md new file mode 100644 index 00000000000..eeead580969 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/black_box_fns.md @@ -0,0 +1,32 @@ +--- +title: Black Box Functions +description: Black box functions are functions in Noir that rely on backends implementing support for specialized constraints. +keywords: [noir, black box functions] +--- + +Black box functions are functions in Noir that rely on backends implementing support for specialized constraints. This makes certain zk-snark unfriendly computations cheaper than if they were implemented in Noir. + +The ACVM spec defines a set of blackbox functions which backends will be expected to implement. This allows backends to use optimized implementations of these constraints if they have them, however they may also fallback to less efficient naive implementations if not. + +## Function list + +Here is a list of the current black box functions: + +- [AES128](./cryptographic_primitives/ciphers.mdx#aes128) +- [SHA256](./cryptographic_primitives/hashes.mdx#sha256) +- [Schnorr signature verification](./cryptographic_primitives/schnorr.mdx) +- [Blake2s](./cryptographic_primitives/hashes.mdx#blake2s) +- [Blake3](./cryptographic_primitives/hashes.mdx#blake3) +- [Pedersen Hash](./cryptographic_primitives/hashes.mdx#pedersen_hash) +- [Pedersen Commitment](./cryptographic_primitives/hashes.mdx#pedersen_commitment) +- [ECDSA signature verification](./cryptographic_primitives/ecdsa_sig_verification.mdx) +- [Embedded curve operations (MSM, addition, ...)](./cryptographic_primitives/embedded_curve_ops.mdx) +- AND +- XOR +- RANGE +- [Keccak256](./cryptographic_primitives/hashes.mdx#keccak256) +- [Recursive proof verification](./recursion) + +Most black box functions are included as part of the Noir standard library, however `AND`, `XOR` and `RANGE` are used as part of the Noir language syntax. For instance, using the bitwise operator `&` will invoke the `AND` black box function. + +You can view the black box functions defined in the ACVM code [here](https://github.com/noir-lang/noir/blob/master/acvm-repo/acir/src/circuit/black_box_functions.rs). diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/bn254.md b/docs/versioned_docs/version-v0.30.0/noir/standard_library/bn254.md new file mode 100644 index 00000000000..3294f005dbb --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/bn254.md @@ -0,0 +1,46 @@ +--- +title: Bn254 Field Library +--- + +Noir provides a module in standard library with some optimized functions for bn254 Fr in `std::field::bn254`. + +## decompose + +```rust +fn decompose(x: Field) -> (Field, Field) {} +``` + +Decomposes a single field into two fields, low and high. The low field contains the lower 16 bytes of the input field and the high field contains the upper 16 bytes of the input field. Both field results are range checked to 128 bits. + + +## assert_gt + +```rust +fn assert_gt(a: Field, b: Field) {} +``` + +Asserts that a > b. This will generate less constraints than using `assert(gt(a, b))`. + +## assert_lt + +```rust +fn assert_lt(a: Field, b: Field) {} +``` + +Asserts that a < b. This will generate less constraints than using `assert(lt(a, b))`. + +## gt + +```rust +fn gt(a: Field, b: Field) -> bool {} +``` + +Returns true if a > b. + +## lt + +```rust +fn lt(a: Field, b: Field) -> bool {} +``` + +Returns true if a < b. \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/containers/boundedvec.md b/docs/versioned_docs/version-v0.30.0/noir/standard_library/containers/boundedvec.md new file mode 100644 index 00000000000..c22fe8c5045 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/containers/boundedvec.md @@ -0,0 +1,340 @@ +--- +title: Bounded Vectors +keywords: [noir, vector, bounded vector, slice] +sidebar_position: 1 +--- + +A `BoundedVec` is a growable storage similar to a `Vec` except that it +is bounded with a maximum possible length. Unlike `Vec`, `BoundedVec` is not implemented +via slices and thus is not subject to the same restrictions slices are (notably, nested +slices - and thus nested vectors as well - are disallowed). + +Since a BoundedVec is backed by a normal array under the hood, growing the BoundedVec by +pushing an additional element is also more efficient - the length only needs to be increased +by one. + +For these reasons `BoundedVec` should generally be preferred over `Vec` when there +is a reasonable maximum bound that can be placed on the vector. + +Example: + +```rust +let mut vector: BoundedVec = BoundedVec::new(); +for i in 0..5 { + vector.push(i); +} +assert(vector.len() == 5); +assert(vector.max_len() == 10); +``` + +## Methods + +### new + +```rust +pub fn new() -> Self +``` + +Creates a new, empty vector of length zero. + +Since this container is backed by an array internally, it still needs an initial value +to give each element. To resolve this, each element is zeroed internally. This value +is guaranteed to be inaccessible unless `get_unchecked` is used. + +Example: + +```rust +let empty_vector: BoundedVec = BoundedVec::new(); +assert(empty_vector.len() == 0); +``` + +Note that whenever calling `new` the maximum length of the vector should always be specified +via a type signature: + +```rust title="new_example" showLineNumbers +fn foo() -> BoundedVec { + // Ok! MaxLen is specified with a type annotation + let v1: BoundedVec = BoundedVec::new(); + let v2 = BoundedVec::new(); + + // Ok! MaxLen is known from the type of foo's return value + v2 +} + +fn bad() { + let mut v3 = BoundedVec::new(); + + // Not Ok! We don't know if v3's MaxLen is at least 1, and the compiler often infers 0 by default. + v3.push(5); +} +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L11-L27 + + +This defaulting of `MaxLen` (and numeric generics in general) to zero may change in future noir versions +but for now make sure to use type annotations when using bounded vectors. Otherwise, you will receive a constraint failure at runtime when the vec is pushed to. + +### get + +```rust +pub fn get(mut self: Self, index: u64) -> T { +``` + +Retrieves an element from the vector at the given index, starting from zero. + +If the given index is equal to or greater than the length of the vector, this +will issue a constraint failure. + +Example: + +```rust +fn foo(v: BoundedVec) { + let first = v.get(0); + let last = v.get(v.len() - 1); + assert(first != last); +} +``` + +### get_unchecked + +```rust +pub fn get_unchecked(mut self: Self, index: u64) -> T { +``` + +Retrieves an element from the vector at the given index, starting from zero, without +performing a bounds check. + +Since this function does not perform a bounds check on length before accessing the element, +it is unsafe! Use at your own risk! + +Example: + +```rust title="get_unchecked_example" showLineNumbers +fn sum_of_first_three(v: BoundedVec) -> u32 { + // Always ensure the length is larger than the largest + // index passed to get_unchecked + assert(v.len() > 2); + let first = v.get_unchecked(0); + let second = v.get_unchecked(1); + let third = v.get_unchecked(2); + first + second + third +} +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L54-L64 + + + +### push + +```rust +pub fn push(&mut self, elem: T) { +``` + +Pushes an element to the end of the vector. This increases the length +of the vector by one. + +Panics if the new length of the vector will be greater than the max length. + +Example: + +```rust title="bounded-vec-push-example" showLineNumbers +let mut v: BoundedVec = BoundedVec::new(); + + v.push(1); + v.push(2); + + // Panics with failed assertion "push out of bounds" + v.push(3); +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L68-L76 + + +### pop + +```rust +pub fn pop(&mut self) -> T +``` + +Pops the element at the end of the vector. This will decrease the length +of the vector by one. + +Panics if the vector is empty. + +Example: + +```rust title="bounded-vec-pop-example" showLineNumbers +let mut v: BoundedVec = BoundedVec::new(); + v.push(1); + v.push(2); + + let two = v.pop(); + let one = v.pop(); + + assert(two == 2); + assert(one == 1); + // error: cannot pop from an empty vector + // let _ = v.pop(); +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L81-L93 + + +### len + +```rust +pub fn len(self) -> u64 { +``` + +Returns the current length of this vector + +Example: + +```rust title="bounded-vec-len-example" showLineNumbers +let mut v: BoundedVec = BoundedVec::new(); + assert(v.len() == 0); + + v.push(100); + assert(v.len() == 1); + + v.push(200); + v.push(300); + v.push(400); + assert(v.len() == 4); + + let _ = v.pop(); + let _ = v.pop(); + assert(v.len() == 2); +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L98-L113 + + +### max_len + +```rust +pub fn max_len(_self: BoundedVec) -> u64 { +``` + +Returns the maximum length of this vector. This is always +equal to the `MaxLen` parameter this vector was initialized with. + +Example: + +```rust title="bounded-vec-max-len-example" showLineNumbers +let mut v: BoundedVec = BoundedVec::new(); + + assert(v.max_len() == 5); + v.push(10); + assert(v.max_len() == 5); +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L118-L124 + + +### storage + +```rust +pub fn storage(self) -> [T; MaxLen] { +``` + +Returns the internal array within this vector. +Since arrays in Noir are immutable, mutating the returned storage array will not mutate +the storage held internally by this vector. + +Note that uninitialized elements may be zeroed out! + +Example: + +```rust title="bounded-vec-storage-example" showLineNumbers +let mut v: BoundedVec = BoundedVec::new(); + + assert(v.storage() == [0, 0, 0, 0, 0]); + + v.push(57); + assert(v.storage() == [57, 0, 0, 0, 0]); +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L129-L136 + + +### extend_from_array + +```rust +pub fn extend_from_array(&mut self, array: [T; Len]) +``` + +Pushes each element from the given array to this vector. + +Panics if pushing each element would cause the length of this vector +to exceed the maximum length. + +Example: + +```rust title="bounded-vec-extend-from-array-example" showLineNumbers +let mut vec: BoundedVec = BoundedVec::new(); + vec.extend_from_array([2, 4]); + + assert(vec.len == 2); + assert(vec.get(0) == 2); + assert(vec.get(1) == 4); +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L141-L148 + + +### extend_from_bounded_vec + +```rust +pub fn extend_from_bounded_vec(&mut self, vec: BoundedVec) +``` + +Pushes each element from the other vector to this vector. The length of +the other vector is left unchanged. + +Panics if pushing each element would cause the length of this vector +to exceed the maximum length. + +Example: + +```rust title="bounded-vec-extend-from-bounded-vec-example" showLineNumbers +let mut v1: BoundedVec = BoundedVec::new(); + let mut v2: BoundedVec = BoundedVec::new(); + + v2.extend_from_array([1, 2, 3]); + v1.extend_from_bounded_vec(v2); + + assert(v1.storage() == [1, 2, 3, 0, 0]); + assert(v2.storage() == [1, 2, 3, 0, 0, 0, 0]); +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L153-L162 + + +### from_array + +```rust +pub fn from_array(array: [T; Len]) -> Self +``` + +Creates a new vector, populating it with values derived from an array input. +The maximum length of the vector is determined based on the type signature. + +Example: +```rust +let bounded_vec: BoundedVec = BoundedVec::from_array([1, 2, 3]) +``` + +### any + +```rust +pub fn any(self, predicate: fn[Env](T) -> bool) -> bool +``` + +Returns true if the given predicate returns true for any element +in this vector. + +Example: + +```rust title="bounded-vec-any-example" showLineNumbers +let mut v: BoundedVec = BoundedVec::new(); + v.extend_from_array([2, 4, 6]); + + let all_even = !v.any(|elem: u32| elem % 2 != 0); + assert(all_even); +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L229-L235 + diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/containers/hashmap.md b/docs/versioned_docs/version-v0.30.0/noir/standard_library/containers/hashmap.md new file mode 100644 index 00000000000..47faa99aba6 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/containers/hashmap.md @@ -0,0 +1,570 @@ +--- +title: HashMap +keywords: [noir, map, hash, hashmap] +sidebar_position: 1 +--- + +`HashMap` is used to efficiently store and look up key-value pairs. + +`HashMap` is a bounded type which can store anywhere from zero to `MaxLen` total elements. +Note that due to hash collisions, the actual maximum number of elements stored by any particular +hashmap is likely lower than `MaxLen`. This is true even with cryptographic hash functions since +every hash value will be performed modulo `MaxLen`. + +When creating `HashMap`s, the `MaxLen` generic should always be specified if it is not already +known. Otherwise, the compiler may infer a different value for `MaxLen` (such as zero), which +will likely change the result of the program. This behavior is set to become an error in future +versions instead. + +Example: + +```rust +// Create a mapping from Fields to u32s with a maximum length of 12 +// using a poseidon2 hasher +use dep::std::hash::poseidon2::Poseidon2Hasher; +let mut map: HashMap> = HashMap::default(); + +map.insert(1, 2); +map.insert(3, 4); + +let two = map.get(1).unwrap(); +``` + +## Methods + +### default + +```rust title="default" showLineNumbers +impl Default for HashMap +where + B: BuildHasher + Default, + H: Hasher + Default +{ + fn default() -> Self { +``` +> Source code: noir_stdlib/src/collections/map.nr#L462-L469 + + +Creates a fresh, empty HashMap. + +When using this function, always make sure to specify the maximum size of the hash map. + +This is the same `default` from the `Default` implementation given further below. It is +repeated here for convenience since it is the recommended way to create a hashmap. + +Example: + +```rust title="default_example" showLineNumbers +let hashmap: HashMap> = HashMap::default(); + assert(hashmap.is_empty()); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L202-L205 + + +Because `HashMap` has so many generic arguments that are likely to be the same throughout +your program, it may be helpful to create a type alias: + +```rust title="type_alias" showLineNumbers +type MyMap = HashMap>; +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L196-L198 + + +### with_hasher + +```rust title="with_hasher" showLineNumbers +pub fn with_hasher(_build_hasher: B) -> Self + where + B: BuildHasher { +``` +> Source code: noir_stdlib/src/collections/map.nr#L82-L86 + + +Creates a hashmap with an existing `BuildHasher`. This can be used to ensure multiple +hashmaps are created with the same hasher instance. + +Example: + +```rust title="with_hasher_example" showLineNumbers +let my_hasher: BuildHasherDefault = Default::default(); + let hashmap: HashMap> = HashMap::with_hasher(my_hasher); + assert(hashmap.is_empty()); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L207-L211 + + +### get + +```rust title="get" showLineNumbers +pub fn get( + self, + key: K + ) -> Option + where + K: Eq + Hash, + B: BuildHasher, + H: Hasher { +``` +> Source code: noir_stdlib/src/collections/map.nr#L278-L287 + + +Retrieves a value from the hashmap, returning `Option::none()` if it was not found. + +Example: + +```rust title="get_example" showLineNumbers +fn get_example(map: HashMap>) { + let x = map.get(12); + + if x.is_some() { + assert(x.unwrap() == 42); + } +} +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L299-L307 + + +### insert + +```rust title="insert" showLineNumbers +pub fn insert( + &mut self, + key: K, + value: V + ) + where + K: Eq + Hash, + B: BuildHasher, + H: Hasher { +``` +> Source code: noir_stdlib/src/collections/map.nr#L313-L323 + + +Inserts a new key-value pair into the map. If the key was already in the map, its +previous value will be overridden with the newly provided one. + +Example: + +```rust title="insert_example" showLineNumbers +let mut map: HashMap> = HashMap::default(); + map.insert(12, 42); + assert(map.len() == 1); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L213-L217 + + +### remove + +```rust title="remove" showLineNumbers +pub fn remove( + &mut self, + key: K + ) + where + K: Eq + Hash, + B: BuildHasher, + H: Hasher { +``` +> Source code: noir_stdlib/src/collections/map.nr#L356-L365 + + +Removes the given key-value pair from the map. If the key was not already present +in the map, this does nothing. + +Example: + +```rust title="remove_example" showLineNumbers +map.remove(12); + assert(map.is_empty()); + + // If a key was not present in the map, remove does nothing + map.remove(12); + assert(map.is_empty()); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L221-L228 + + +### is_empty + +```rust title="is_empty" showLineNumbers +pub fn is_empty(self) -> bool { +``` +> Source code: noir_stdlib/src/collections/map.nr#L115-L117 + + +True if the length of the hash map is empty. + +Example: + +```rust title="is_empty_example" showLineNumbers +assert(map.is_empty()); + + map.insert(1, 2); + assert(!map.is_empty()); + + map.remove(1); + assert(map.is_empty()); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L230-L238 + + +### len + +```rust title="len" showLineNumbers +pub fn len(self) -> u64 { +``` +> Source code: noir_stdlib/src/collections/map.nr#L264-L266 + + +Returns the current length of this hash map. + +Example: + +```rust title="len_example" showLineNumbers +// This is equivalent to checking map.is_empty() + assert(map.len() == 0); + + map.insert(1, 2); + map.insert(3, 4); + map.insert(5, 6); + assert(map.len() == 3); + + // 3 was already present as a key in the hash map, so the length is unchanged + map.insert(3, 7); + assert(map.len() == 3); + + map.remove(1); + assert(map.len() == 2); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L240-L255 + + +### capacity + +```rust title="capacity" showLineNumbers +pub fn capacity(_self: Self) -> u64 { +``` +> Source code: noir_stdlib/src/collections/map.nr#L271-L273 + + +Returns the maximum capacity of this hashmap. This is always equal to the capacity +specified in the hashmap's type. + +Unlike hashmaps in general purpose programming languages, hashmaps in Noir have a +static capacity that does not increase as the map grows larger. Thus, this capacity +is also the maximum possible element count that can be inserted into the hashmap. +Due to hash collisions (modulo the hashmap length), it is likely the actual maximum +element count will be lower than the full capacity. + +Example: + +```rust title="capacity_example" showLineNumbers +let empty_map: HashMap> = HashMap::default(); + assert(empty_map.len() == 0); + assert(empty_map.capacity() == 42); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L257-L261 + + +### clear + +```rust title="clear" showLineNumbers +pub fn clear(&mut self) { +``` +> Source code: noir_stdlib/src/collections/map.nr#L93-L95 + + +Clears the hashmap, removing all key-value pairs from it. + +Example: + +```rust title="clear_example" showLineNumbers +assert(!map.is_empty()); + map.clear(); + assert(map.is_empty()); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L263-L267 + + +### contains_key + +```rust title="contains_key" showLineNumbers +pub fn contains_key( + self, + key: K + ) -> bool + where + K: Hash + Eq, + B: BuildHasher, + H: Hasher { +``` +> Source code: noir_stdlib/src/collections/map.nr#L101-L110 + + +True if the hashmap contains the given key. Unlike `get`, this will not also return +the value associated with the key. + +Example: + +```rust title="contains_key_example" showLineNumbers +if map.contains_key(7) { + let value = map.get(7); + assert(value.is_some()); + } else { + println("No value for key 7!"); + } +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L269-L276 + + +### entries + +```rust title="entries" showLineNumbers +pub fn entries(self) -> BoundedVec<(K, V), N> { +``` +> Source code: noir_stdlib/src/collections/map.nr#L123-L125 + + +Returns a vector of each key-value pair present in the hashmap. + +The length of the returned vector is always equal to the length of the hashmap. + +Example: + +```rust title="entries_example" showLineNumbers +let entries = map.entries(); + + // The length of a hashmap may not be compile-time known, so we + // need to loop over its capacity instead + for i in 0..map.capacity() { + if i < entries.len() { + let (key, value) = entries.get(i); + println(f"{key} -> {value}"); + } + } +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L310-L321 + + +### keys + +```rust title="keys" showLineNumbers +pub fn keys(self) -> BoundedVec { +``` +> Source code: noir_stdlib/src/collections/map.nr#L144-L146 + + +Returns a vector of each key present in the hashmap. + +The length of the returned vector is always equal to the length of the hashmap. + +Example: + +```rust title="keys_example" showLineNumbers +let keys = map.keys(); + + for i in 0..keys.max_len() { + if i < keys.len() { + let key = keys.get_unchecked(i); + let value = map.get(key).unwrap_unchecked(); + println(f"{key} -> {value}"); + } + } +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L323-L333 + + +### values + +```rust title="values" showLineNumbers +pub fn values(self) -> BoundedVec { +``` +> Source code: noir_stdlib/src/collections/map.nr#L164-L166 + + +Returns a vector of each value present in the hashmap. + +The length of the returned vector is always equal to the length of the hashmap. + +Example: + +```rust title="values_example" showLineNumbers +let values = map.values(); + + for i in 0..values.max_len() { + if i < values.len() { + let value = values.get_unchecked(i); + println(f"Found value {value}"); + } + } +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L335-L344 + + +### iter_mut + +```rust title="iter_mut" showLineNumbers +pub fn iter_mut( + &mut self, + f: fn(K, V) -> (K, V) + ) + where + K: Eq + Hash, + B: BuildHasher, + H: Hasher { +``` +> Source code: noir_stdlib/src/collections/map.nr#L183-L192 + + +Iterates through each key-value pair of the HashMap, setting each key-value pair to the +result returned from the given function. + +Note that since keys can be mutated, the HashMap needs to be rebuilt as it is iterated +through. If this is not desired, use `iter_values_mut` if only values need to be mutated, +or `entries` if neither keys nor values need to be mutated. + +The iteration order is left unspecified. As a result, if two keys are mutated to become +equal, which of the two values that will be present for the key in the resulting map is also unspecified. + +Example: + +```rust title="iter_mut_example" showLineNumbers +// Add 1 to each key in the map, and double the value associated with that key. + map.iter_mut(|k, v| (k + 1, v * 2)); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L348-L351 + + +### iter_keys_mut + +```rust title="iter_keys_mut" showLineNumbers +pub fn iter_keys_mut( + &mut self, + f: fn(K) -> K + ) + where + K: Eq + Hash, + B: BuildHasher, + H: Hasher { +``` +> Source code: noir_stdlib/src/collections/map.nr#L208-L217 + + +Iterates through the HashMap, mutating each key to the result returned from +the given function. + +Note that since keys can be mutated, the HashMap needs to be rebuilt as it is iterated +through. If only iteration is desired and the keys are not intended to be mutated, +prefer using `entries` instead. + +The iteration order is left unspecified. As a result, if two keys are mutated to become +equal, which of the two values that will be present for the key in the resulting map is also unspecified. + +Example: + +```rust title="iter_keys_mut_example" showLineNumbers +// Double each key, leaving the value associated with that key untouched + map.iter_keys_mut(|k| k * 2); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L353-L356 + + +### iter_values_mut + +```rust title="iter_values_mut" showLineNumbers +pub fn iter_values_mut(&mut self, f: fn(V) -> V) { +``` +> Source code: noir_stdlib/src/collections/map.nr#L233-L235 + + +Iterates through the HashMap, applying the given function to each value and mutating the +value to equal the result. This function is more efficient than `iter_mut` and `iter_keys_mut` +because the keys are untouched and the underlying hashmap thus does not need to be reordered. + +Example: + +```rust title="iter_values_mut_example" showLineNumbers +// Halve each value + map.iter_values_mut(|v| v / 2); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L358-L361 + + +### retain + +```rust title="retain" showLineNumbers +pub fn retain(&mut self, f: fn(K, V) -> bool) { +``` +> Source code: noir_stdlib/src/collections/map.nr#L247-L249 + + +Retains only the key-value pairs for which the given function returns true. +Any key-value pairs for which the function returns false will be removed from the map. + +Example: + +```rust title="retain_example" showLineNumbers +map.retain(|k, v| (k != 0) & (v != 0)); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L281-L283 + + +## Trait Implementations + +### default + +```rust title="default" showLineNumbers +impl Default for HashMap +where + B: BuildHasher + Default, + H: Hasher + Default +{ + fn default() -> Self { +``` +> Source code: noir_stdlib/src/collections/map.nr#L462-L469 + + +Constructs an empty HashMap. + +Example: + +```rust title="default_example" showLineNumbers +let hashmap: HashMap> = HashMap::default(); + assert(hashmap.is_empty()); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L202-L205 + + +### eq + +```rust title="eq" showLineNumbers +impl Eq for HashMap +where + K: Eq + Hash, + V: Eq, + B: BuildHasher, + H: Hasher +{ + fn eq(self, other: HashMap) -> bool { +``` +> Source code: noir_stdlib/src/collections/map.nr#L426-L435 + + +Checks if two HashMaps are equal. + +Example: + +```rust title="eq_example" showLineNumbers +let mut map1: HashMap> = HashMap::default(); + let mut map2: HashMap> = HashMap::default(); + + map1.insert(1, 2); + map1.insert(3, 4); + + map2.insert(3, 4); + map2.insert(1, 2); + + assert(map1 == map2); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L285-L296 + diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/containers/index.md b/docs/versioned_docs/version-v0.30.0/noir/standard_library/containers/index.md new file mode 100644 index 00000000000..ea84c6d5c21 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/containers/index.md @@ -0,0 +1,5 @@ +--- +title: Containers +description: Container types provided by Noir's standard library for storing and retrieving data +keywords: [containers, data types, vec, hashmap] +--- diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/containers/vec.mdx b/docs/versioned_docs/version-v0.30.0/noir/standard_library/containers/vec.mdx new file mode 100644 index 00000000000..fcfd7e07aa0 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/containers/vec.mdx @@ -0,0 +1,151 @@ +--- +title: Vectors +description: Delve into the Vec data type in Noir. Learn about its methods, practical examples, and best practices for using Vectors in your Noir code. +keywords: [noir, vector type, methods, examples, dynamic arrays] +sidebar_position: 6 +--- + +import Experimental from '@site/src/components/Notes/_experimental.mdx'; + + + +A vector is a collection type similar to Rust's `Vec` type. In Noir, it is a convenient way to use slices as mutable arrays. + +Example: + +```rust +let mut vector: Vec = Vec::new(); +for i in 0..5 { + vector.push(i); +} +assert(vector.len() == 5); +``` + +## Methods + +### new + +Creates a new, empty vector. + +```rust +pub fn new() -> Self +``` + +Example: + +```rust +let empty_vector: Vec = Vec::new(); +assert(empty_vector.len() == 0); +``` + +### from_slice + +Creates a vector containing each element from a given slice. Mutations to the resulting vector will not affect the original slice. + +```rust +pub fn from_slice(slice: [T]) -> Self +``` + +Example: + +```rust +let slice: [Field] = &[1, 2, 3]; +let vector_from_slice = Vec::from_slice(slice); +assert(vector_from_slice.len() == 3); +``` + +### len + +Returns the number of elements in the vector. + +```rust +pub fn len(self) -> Field +``` + +Example: + +```rust +let empty_vector: Vec = Vec::new(); +assert(empty_vector.len() == 0); +``` + +### get + +Retrieves an element from the vector at a given index. Panics if the index points beyond the vector's end. + +```rust +pub fn get(self, index: Field) -> T +``` + +Example: + +```rust +let vector: Vec = Vec::from_slice(&[10, 20, 30]); +assert(vector.get(1) == 20); +``` + +### push + +Adds a new element to the vector's end, returning a new vector with a length one greater than the original unmodified vector. + +```rust +pub fn push(&mut self, elem: T) +``` + +Example: + +```rust +let mut vector: Vec = Vec::new(); +vector.push(10); +assert(vector.len() == 1); +``` + +### pop + +Removes an element from the vector's end, returning a new vector with a length one less than the original vector, along with the removed element. Panics if the vector's length is zero. + +```rust +pub fn pop(&mut self) -> T +``` + +Example: + +```rust +let mut vector = Vec::from_slice(&[10, 20]); +let popped_elem = vector.pop(); +assert(popped_elem == 20); +assert(vector.len() == 1); +``` + +### insert + +Inserts an element at a specified index, shifting subsequent elements to the right. + +```rust +pub fn insert(&mut self, index: Field, elem: T) +``` + +Example: + +```rust +let mut vector = Vec::from_slice(&[10, 30]); +vector.insert(1, 20); +assert(vector.get(1) == 20); +``` + +### remove + +Removes an element at a specified index, shifting subsequent elements to the left, and returns the removed element. + +```rust +pub fn remove(&mut self, index: Field) -> T +``` + +Example: + +```rust +let mut vector = Vec::from_slice(&[10, 20, 30]); +let removed_elem = vector.remove(1); +assert(removed_elem == 20); +assert(vector.len() == 2); +``` diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/_category_.json b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/_category_.json new file mode 100644 index 00000000000..5d694210bbf --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 0, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/ciphers.mdx b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/ciphers.mdx new file mode 100644 index 00000000000..e83e26efb97 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/ciphers.mdx @@ -0,0 +1,32 @@ +--- +title: Ciphers +description: + Learn about the implemented ciphers ready to use for any Noir project +keywords: + [ciphers, Noir project, aes128, encrypt] +sidebar_position: 0 +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox.mdx'; + +## aes128 + +Given a plaintext as an array of bytes, returns the corresponding aes128 ciphertext (CBC mode). Input padding is automatically performed using PKCS#7, so that the output length is `input.len() + (16 - input.len() % 16)`. + +```rust title="aes128" showLineNumbers +pub fn aes128_encrypt(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8] {} +``` +> Source code: noir_stdlib/src/aes128.nr#L2-L4 + + +```rust +fn main() { + let input: [u8; 4] = [0, 12, 3, 15] // Random bytes, will be padded to 16 bytes. + let iv: [u8; 16] = [0; 16]; // Initialisation vector + let key: [u8; 16] = [0; 16] // AES key + let ciphertext = std::aes128::aes128_encrypt(inputs.as_bytes(), iv.as_bytes(), key.as_bytes()); // In this case, the output length will be 16 bytes. +} +``` + + + \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/ec_primitives.md b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/ec_primitives.md new file mode 100644 index 00000000000..d2b42d67b7c --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/ec_primitives.md @@ -0,0 +1,102 @@ +--- +title: Elliptic Curve Primitives +keywords: [cryptographic primitives, Noir project] +sidebar_position: 4 +--- + +Data structures and methods on them that allow you to carry out computations involving elliptic +curves over the (mathematical) field corresponding to `Field`. For the field currently at our +disposal, applications would involve a curve embedded in BN254, e.g. the +[Baby Jubjub curve](https://eips.ethereum.org/EIPS/eip-2494). + +## Data structures + +### Elliptic curve configurations + +(`std::ec::{tecurve,montcurve,swcurve}::{affine,curvegroup}::Curve`), i.e. the specific elliptic +curve you want to use, which would be specified using any one of the methods +`std::ec::{tecurve,montcurve,swcurve}::{affine,curvegroup}::new` which take the coefficients in the +defining equation together with a generator point as parameters. You can find more detail in the +comments in +[`noir_stdlib/src/ec.nr`](https://github.com/noir-lang/noir/blob/master/noir_stdlib/src/ec.nr), but +the gist of it is that the elliptic curves of interest are usually expressed in one of the standard +forms implemented here (Twisted Edwards, Montgomery and Short Weierstraß), and in addition to that, +you could choose to use `affine` coordinates (Cartesian coordinates - the usual (x,y) - possibly +together with a point at infinity) or `curvegroup` coordinates (some form of projective coordinates +requiring more coordinates but allowing for more efficient implementations of elliptic curve +operations). Conversions between all of these forms are provided, and under the hood these +conversions are done whenever an operation is more efficient in a different representation (or a +mixed coordinate representation is employed). + +### Points + +(`std::ec::{tecurve,montcurve,swcurve}::{affine,curvegroup}::Point`), i.e. points lying on the +elliptic curve. For a curve configuration `c` and a point `p`, it may be checked that `p` +does indeed lie on `c` by calling `c.contains(p1)`. + +## Methods + +(given a choice of curve representation, e.g. use `std::ec::tecurve::affine::Curve` and use +`std::ec::tecurve::affine::Point`) + +- The **zero element** is given by `Point::zero()`, and we can verify whether a point `p: Point` is + zero by calling `p.is_zero()`. +- **Equality**: Points `p1: Point` and `p2: Point` may be checked for equality by calling + `p1.eq(p2)`. +- **Addition**: For `c: Curve` and points `p1: Point` and `p2: Point` on the curve, adding these two + points is accomplished by calling `c.add(p1,p2)`. +- **Negation**: For a point `p: Point`, `p.negate()` is its negation. +- **Subtraction**: For `c` and `p1`, `p2` as above, subtracting `p2` from `p1` is accomplished by + calling `c.subtract(p1,p2)`. +- **Scalar multiplication**: For `c` as above, `p: Point` a point on the curve and `n: Field`, + scalar multiplication is given by `c.mul(n,p)`. If instead `n :: [u1; N]`, i.e. `n` is a bit + array, the `bit_mul` method may be used instead: `c.bit_mul(n,p)` +- **Multi-scalar multiplication**: For `c` as above and arrays `n: [Field; N]` and `p: [Point; N]`, + multi-scalar multiplication is given by `c.msm(n,p)`. +- **Coordinate representation conversions**: The `into_group` method converts a point or curve + configuration in the affine representation to one in the CurveGroup representation, and + `into_affine` goes in the other direction. +- **Curve representation conversions**: `tecurve` and `montcurve` curves and points are equivalent + and may be converted between one another by calling `into_montcurve` or `into_tecurve` on their + configurations or points. `swcurve` is more general and a curve c of one of the other two types + may be converted to this representation by calling `c.into_swcurve()`, whereas a point `p` lying + on the curve given by `c` may be mapped to its corresponding `swcurve` point by calling + `c.map_into_swcurve(p)`. +- **Map-to-curve methods**: The Elligator 2 method of mapping a field element `n: Field` into a + `tecurve` or `montcurve` with configuration `c` may be called as `c.elligator2_map(n)`. For all of + the curve configurations, the SWU map-to-curve method may be called as `c.swu_map(z,n)`, where + `z: Field` depends on `Field` and `c` and must be chosen by the user (the conditions it needs to + satisfy are specified in the comments + [here](https://github.com/noir-lang/noir/blob/master/noir_stdlib/src/ec.nr)). + +## Examples + +The +[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr) +illustrates all of the above primitives on various forms of the Baby Jubjub curve. A couple of more +interesting examples in Noir would be: + +Public-key cryptography: Given an elliptic curve and a 'base point' on it, determine the public key +from the private key. This is a matter of using scalar multiplication. In the case of Baby Jubjub, +for example, this code would do: + +```rust +use dep::std::ec::tecurve::affine::{Curve, Point}; + +fn bjj_pub_key(priv_key: Field) -> Point +{ + + let bjj = Curve::new(168700, 168696, G::new(995203441582195749578291179787384436505546430278305826713579947235728471134,5472060717959818805561601436314318772137091100104008585924551046643952123905)); + + let base_pt = Point::new(5299619240641551281634865583518297030282874472190772894086521144482721001553, 16950150798460657717958625567821834550301663161624707787222815936182638968203); + + bjj.mul(priv_key,base_pt) +} +``` + +This would come in handy in a Merkle proof. + +- EdDSA signature verification: This is a matter of combining these primitives with a suitable hash + function. See + [feat(stdlib): EdDSA sig verification noir#1136](https://github.com/noir-lang/noir/pull/1136) for + the case of Baby Jubjub and the Poseidon hash function. diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/ecdsa_sig_verification.mdx b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/ecdsa_sig_verification.mdx new file mode 100644 index 00000000000..4394b48f907 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/ecdsa_sig_verification.mdx @@ -0,0 +1,98 @@ +--- +title: ECDSA Signature Verification +description: Learn about the cryptographic primitives regarding ECDSA over the secp256k1 and secp256r1 curves +keywords: [cryptographic primitives, Noir project, ecdsa, secp256k1, secp256r1, signatures] +sidebar_position: 3 +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox.mdx'; + +Noir supports ECDSA signatures verification over the secp256k1 and secp256r1 curves. + +## ecdsa_secp256k1::verify_signature + +Verifier for ECDSA Secp256k1 signatures. +See ecdsa_secp256k1::verify_signature_slice for a version that accepts slices directly. + +```rust title="ecdsa_secp256k1" showLineNumbers +pub fn verify_signature( + public_key_x: [u8; 32], + public_key_y: [u8; 32], + signature: [u8; 64], + message_hash: [u8; N] +) -> bool +``` +> Source code: noir_stdlib/src/ecdsa_secp256k1.nr#L2-L9 + + +example: + +```rust +fn main(hashed_message : [u8;32], pub_key_x : [u8;32], pub_key_y : [u8;32], signature : [u8;64]) { + let valid_signature = std::ecdsa_secp256k1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); + assert(valid_signature); +} +``` + + + +## ecdsa_secp256k1::verify_signature_slice + +Verifier for ECDSA Secp256k1 signatures where the message is a slice. + +```rust title="ecdsa_secp256k1_slice" showLineNumbers +pub fn verify_signature_slice( + public_key_x: [u8; 32], + public_key_y: [u8; 32], + signature: [u8; 64], + message_hash: [u8] +) -> bool +``` +> Source code: noir_stdlib/src/ecdsa_secp256k1.nr#L13-L20 + + + + +## ecdsa_secp256r1::verify_signature + +Verifier for ECDSA Secp256r1 signatures. +See ecdsa_secp256r1::verify_signature_slice for a version that accepts slices directly. + +```rust title="ecdsa_secp256r1" showLineNumbers +pub fn verify_signature( + public_key_x: [u8; 32], + public_key_y: [u8; 32], + signature: [u8; 64], + message_hash: [u8; N] +) -> bool +``` +> Source code: noir_stdlib/src/ecdsa_secp256r1.nr#L2-L9 + + +example: + +```rust +fn main(hashed_message : [u8;32], pub_key_x : [u8;32], pub_key_y : [u8;32], signature : [u8;64]) { + let valid_signature = std::ecdsa_secp256r1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); + assert(valid_signature); +} +``` + + + +## ecdsa_secp256r1::verify_signature + +Verifier for ECDSA Secp256r1 signatures where the message is a slice. + +```rust title="ecdsa_secp256r1_slice" showLineNumbers +pub fn verify_signature_slice( + public_key_x: [u8; 32], + public_key_y: [u8; 32], + signature: [u8; 64], + message_hash: [u8] +) -> bool +``` +> Source code: noir_stdlib/src/ecdsa_secp256r1.nr#L13-L20 + + + diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/eddsa.mdx b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/eddsa.mdx new file mode 100644 index 00000000000..c2c0624dfad --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/eddsa.mdx @@ -0,0 +1,37 @@ +--- +title: EdDSA Verification +description: Learn about the cryptographic primitives regarding EdDSA +keywords: [cryptographic primitives, Noir project, eddsa, signatures] +sidebar_position: 5 +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox.mdx'; + +## eddsa::eddsa_poseidon_verify + +Verifier for EdDSA signatures + +```rust +fn eddsa_poseidon_verify(public_key_x : Field, public_key_y : Field, signature_s: Field, signature_r8_x: Field, signature_r8_y: Field, message: Field) -> bool +``` + +It is also possible to specify the hash algorithm used for the signature by using the `eddsa_verify_with_hasher` function with a parameter implementing the Hasher trait. For instance, if you want to use Poseidon2 instead, you can do the following: +```rust +use dep::std::hash::poseidon2::Poseidon2Hasher; + +let mut hasher = Poseidon2Hasher::default(); +eddsa_verify_with_hasher(pub_key_a.x, pub_key_a.y, s_a, r8_a.x, r8_a.y, msg, &mut hasher); +``` + + + +## eddsa::eddsa_to_pub + +Private to public key conversion. + +Returns `(pub_key_x, pub_key_y)` + +```rust +fn eddsa_to_pub(secret : Field) -> (Field, Field) +``` + diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/embedded_curve_ops.mdx b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/embedded_curve_ops.mdx new file mode 100644 index 00000000000..9dab7dd1047 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/embedded_curve_ops.mdx @@ -0,0 +1,98 @@ +--- +title: Scalar multiplication +description: See how you can perform scalar multiplication in Noir +keywords: [cryptographic primitives, Noir project, scalar multiplication] +sidebar_position: 1 +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox.mdx'; + +The following functions perform operations over the embedded curve whose coordinates are defined by the configured noir field. +For the BN254 scalar field, this is BabyJubJub or Grumpkin. + +:::note +Suffixes `_low` and `_high` denote low and high limbs of a scalar. +::: + +## embedded_curve_ops::multi_scalar_mul + +Performs multi scalar multiplication over the embedded curve. +The function accepts arbitrary amount of point-scalar pairs on the input, it multiplies the individual pairs over +the curve and returns a sum of the resulting points. + +Points represented as x and y coordinates [x1, y1, x2, y2, ...], scalars as low and high limbs [low1, high1, low2, high2, ...]. + +```rust title="multi_scalar_mul" showLineNumbers +pub fn multi_scalar_mul( + points: [Field; N], // points represented as x and y coordinates [x1, y1, x2, y2, ...] + scalars: [Field; N] // scalars represented as low and high limbs [low1, high1, low2, high2, ...] +) -> [Field; 2] +``` +> Source code: noir_stdlib/src/embedded_curve_ops.nr#L43-L48 + + +example + +```rust +fn main(point_x: Field, point_y: Field, scalar_low: Field, scalar_high: Field) { + let point = std::embedded_curve_ops::multi_scalar_mul([point_x, point_y], [scalar_low, scalar_high]); + println(point); +} +``` + +## embedded_curve_ops::fixed_base_scalar_mul + +Performs fixed base scalar multiplication over the embedded curve (multiplies input scalar with a generator point). +The function accepts a single scalar on the input represented as 2 fields. + +```rust title="fixed_base_scalar_mul" showLineNumbers +pub fn fixed_base_scalar_mul( + scalar_low: Field, + scalar_high: Field +) -> [Field; 2] +``` +> Source code: noir_stdlib/src/embedded_curve_ops.nr#L51-L56 + + +example + +```rust +fn main(scalar_low: Field, scalar_high: Field) { + let point = std::embedded_curve_ops::fixed_base_scalar_mul(scalar_low, scalar_high); + println(point); +} +``` + +## embedded_curve_ops::embedded_curve_add + +Adds two points on the embedded curve. +This function takes two `EmbeddedCurvePoint` structures as parameters, representing points on the curve, and returns a new `EmbeddedCurvePoint` structure that represents their sum. + +### Parameters: +- `point1` (`EmbeddedCurvePoint`): The first point to add. +- `point2` (`EmbeddedCurvePoint`): The second point to add. + +### Returns: +- `EmbeddedCurvePoint`: The resulting point after the addition of `point1` and `point2`. + +```rust title="embedded_curve_add" showLineNumbers +fn embedded_curve_add( + point1: EmbeddedCurvePoint, + point2: EmbeddedCurvePoint +) -> EmbeddedCurvePoint +``` +> Source code: noir_stdlib/src/embedded_curve_ops.nr#L65-L70 + + +example + +```rust +fn main() { + let point1 = EmbeddedCurvePoint { x: 1, y: 2 }; + let point2 = EmbeddedCurvePoint { x: 3, y: 4 }; + let result = std::embedded_curve_ops::embedded_curve_add(point1, point2); + println!("Resulting Point: ({}, {})", result.x, result.y); +} +``` + + diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/hashes.mdx b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/hashes.mdx new file mode 100644 index 00000000000..3b83d9ec31a --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/hashes.mdx @@ -0,0 +1,257 @@ +--- +title: Hash methods +description: + Learn about the cryptographic primitives ready to use for any Noir project, including sha256, + blake2s, pedersen, mimc_bn254 and mimc +keywords: + [cryptographic primitives, Noir project, sha256, blake2s, pedersen, mimc_bn254, mimc, hash] +sidebar_position: 0 +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox.mdx'; + +## sha256 + +Given an array of bytes, returns the resulting sha256 hash. +Specify a message_size to hash only the first `message_size` bytes of the input. + +```rust title="sha256" showLineNumbers +pub fn sha256(input: [u8; N]) -> [u8; 32] +``` +> Source code: noir_stdlib/src/hash.nr#L10-L12 + + +example: +```rust title="sha256_var" showLineNumbers +let digest = std::hash::sha256_var([x as u8], 1); +``` +> Source code: test_programs/execution_success/sha256/src/main.nr#L17-L19 + + +```rust +fn main() { + let x = [163, 117, 178, 149]; // some random bytes + let hash = std::sha256::sha256_var(x, 4); +} +``` + + + + +## blake2s + +Given an array of bytes, returns an array with the Blake2 hash + +```rust title="blake2s" showLineNumbers +pub fn blake2s(input: [u8; N]) -> [u8; 32] +``` +> Source code: noir_stdlib/src/hash.nr#L16-L18 + + +example: + +```rust +fn main() { + let x = [163, 117, 178, 149]; // some random bytes + let hash = std::hash::blake2s(x); +} +``` + + + +## blake3 + +Given an array of bytes, returns an array with the Blake3 hash + +```rust title="blake3" showLineNumbers +pub fn blake3(input: [u8; N]) -> [u8; 32] +``` +> Source code: noir_stdlib/src/hash.nr#L22-L24 + + +example: + +```rust +fn main() { + let x = [163, 117, 178, 149]; // some random bytes + let hash = std::hash::blake3(x); +} +``` + + + +## pedersen_hash + +Given an array of Fields, returns the Pedersen hash. + +```rust title="pedersen_hash" showLineNumbers +pub fn pedersen_hash(input: [Field; N]) -> Field +``` +> Source code: noir_stdlib/src/hash.nr#L46-L48 + + +example: + +```rust title="pedersen-hash" showLineNumbers +use dep::std; + +fn main(x: Field, y: Field, expected_hash: Field) { + let hash = std::hash::pedersen_hash([x, y]); + assert_eq(hash, expected_hash); +} +``` +> Source code: test_programs/execution_success/pedersen_hash/src/main.nr#L1-L8 + + + + +## pedersen_commitment + +Given an array of Fields, returns the Pedersen commitment. + +```rust title="pedersen_commitment" showLineNumbers +struct PedersenPoint { + x : Field, + y : Field, +} + +pub fn pedersen_commitment(input: [Field; N]) -> PedersenPoint { +``` +> Source code: noir_stdlib/src/hash.nr#L27-L34 + + +example: + +```rust title="pedersen-commitment" showLineNumbers +use dep::std; + +fn main(x: Field, y: Field, expected_commitment: std::hash::PedersenPoint) { + let commitment = std::hash::pedersen_commitment([x, y]); + assert_eq(commitment.x, expected_commitment.x); + assert_eq(commitment.y, expected_commitment.y); +} +``` +> Source code: test_programs/execution_success/pedersen_commitment/src/main.nr#L1-L9 + + + + +## keccak256 + +Given an array of bytes (`u8`), returns the resulting keccak hash as an array of +32 bytes (`[u8; 32]`). Specify a message_size to hash only the first +`message_size` bytes of the input. + +```rust title="keccak256" showLineNumbers +pub fn keccak256(input: [u8; N], message_size: u32) -> [u8; 32] +``` +> Source code: noir_stdlib/src/hash.nr#L68-L70 + + +example: + +```rust title="keccak256" showLineNumbers +use dep::std; + +fn main(x: Field, result: [u8; 32]) { + // We use the `as` keyword here to denote the fact that we want to take just the first byte from the x Field + // The padding is taken care of by the program + let digest = std::hash::keccak256([x as u8], 1); + assert(digest == result); + + //#1399: variable message size + let message_size = 4; + let hash_a = std::hash::keccak256([1, 2, 3, 4], message_size); + let hash_b = std::hash::keccak256([1, 2, 3, 4, 0, 0, 0, 0], message_size); + + assert(hash_a == hash_b); + + let message_size_big = 8; + let hash_c = std::hash::keccak256([1, 2, 3, 4, 0, 0, 0, 0], message_size_big); + + assert(hash_a != hash_c); +} +``` +> Source code: test_programs/execution_success/keccak256/src/main.nr#L1-L22 + + + + +## poseidon + +Given an array of Fields, returns a new Field with the Poseidon Hash. Mind that you need to specify +how many inputs are there to your Poseidon function. + +```rust +// example for hash_1, hash_2 accepts an array of length 2, etc +fn hash_1(input: [Field; 1]) -> Field +``` + +example: + +```rust title="poseidon" showLineNumbers +use dep::std::hash::poseidon; +use dep::std::hash::poseidon2; + +fn main(x1: [Field; 2], y1: pub Field, x2: [Field; 4], y2: pub Field, x3: [Field; 4], y3: Field) { + let hash1 = poseidon::bn254::hash_2(x1); + assert(hash1 == y1); + + let hash2 = poseidon::bn254::hash_4(x2); + assert(hash2 == y2); + + let hash3 = poseidon2::Poseidon2::hash(x3, x3.len()); + assert(hash3 == y3); +} +``` +> Source code: test_programs/execution_success/poseidon_bn254_hash/src/main.nr#L1-L15 + + +## poseidon 2 + +Given an array of Fields, returns a new Field with the Poseidon2 Hash. Contrary to the Poseidon +function, there is only one hash and you can specify a message_size to hash only the first +`message_size` bytes of the input, + +```rust +// example for hashing the first three elements of the input +Poseidon2::hash(input, 3); +``` + +The above example for Poseidon also includes Poseidon2. + +## mimc_bn254 and mimc + +`mimc_bn254` is `mimc`, but with hardcoded parameters for the BN254 curve. You can use it by +providing an array of Fields, and it returns a Field with the hash. You can use the `mimc` method if +you're willing to input your own constants: + +```rust +fn mimc(x: Field, k: Field, constants: [Field; N], exp : Field) -> Field +``` + +otherwise, use the `mimc_bn254` method: + +```rust +fn mimc_bn254(array: [Field; N]) -> Field +``` + +example: + +```rust + +fn main() { + let x = [163, 117, 178, 149]; // some random bytes + let hash = std::hash::mimc::mimc_bn254(x); +} +``` + +## hash_to_field + +```rust +fn hash_to_field(_input : [Field]) -> Field {} +``` + +Calculates the `blake2s` hash of the inputs and returns the hash modulo the field modulus to return +a value which can be represented as a `Field`. + diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/index.md b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/index.md new file mode 100644 index 00000000000..650f30165d5 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/index.md @@ -0,0 +1,14 @@ +--- +title: Cryptographic Primitives +description: + Learn about the cryptographic primitives ready to use for any Noir project +keywords: + [ + cryptographic primitives, + Noir project, + ] +--- + +The Noir team is progressively adding new cryptographic primitives to the standard library. Reach out for news or if you would be interested in adding more of these calculations in Noir. + +Some methods are available thanks to the Aztec backend, not being performed using Noir. When using other backends, these methods may or may not be supplied. diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/schnorr.mdx b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/schnorr.mdx new file mode 100644 index 00000000000..b59e69c8f07 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/cryptographic_primitives/schnorr.mdx @@ -0,0 +1,64 @@ +--- +title: Schnorr Signatures +description: Learn how you can verify Schnorr signatures using Noir +keywords: [cryptographic primitives, Noir project, schnorr, signatures] +sidebar_position: 2 +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox.mdx'; + +## schnorr::verify_signature + +Verifier for Schnorr signatures over the embedded curve (for BN254 it is Grumpkin). +See schnorr::verify_signature_slice for a version that works directly on slices. + +```rust title="schnorr_verify" showLineNumbers +pub fn verify_signature( + public_key_x: Field, + public_key_y: Field, + signature: [u8; 64], + message: [u8; N] +) -> bool +``` +> Source code: noir_stdlib/src/schnorr.nr#L2-L9 + + +where `_signature` can be generated like so using the npm package +[@noir-lang/barretenberg](https://www.npmjs.com/package/@noir-lang/barretenberg) + +```js +const { BarretenbergWasm } = require('@noir-lang/barretenberg/dest/wasm'); +const { Schnorr } = require('@noir-lang/barretenberg/dest/crypto/schnorr'); + +... + +const barretenberg = await BarretenbergWasm.new(); +const schnorr = new Schnorr(barretenberg); +const pubKey = schnorr.computePublicKey(privateKey); +const message = ... +const signature = Array.from( + schnorr.constructSignature(hash, privateKey).toBuffer() +); + +... +``` + + + +## schnorr::verify_signature_slice + +Verifier for Schnorr signatures over the embedded curve (for BN254 it is Grumpkin) +where the message is a slice. + +```rust title="schnorr_verify_slice" showLineNumbers +pub fn verify_signature_slice( + public_key_x: Field, + public_key_y: Field, + signature: [u8; 64], + message: [u8] +) -> bool +``` +> Source code: noir_stdlib/src/schnorr.nr#L13-L20 + + + diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/logging.md b/docs/versioned_docs/version-v0.30.0/noir/standard_library/logging.md new file mode 100644 index 00000000000..db75ef9f86f --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/logging.md @@ -0,0 +1,78 @@ +--- +title: Logging +description: + Learn how to use the println statement for debugging in Noir with this tutorial. Understand the + basics of logging in Noir and how to implement it in your code. +keywords: + [ + noir logging, + println statement, + print statement, + debugging in noir, + noir std library, + logging tutorial, + basic logging in noir, + noir logging implementation, + noir debugging techniques, + rust, + ] +--- + +The standard library provides two familiar statements you can use: `println` and `print`. Despite being a limited implementation of rust's `println!` and `print!` macros, these constructs can be useful for debugging. + +You can print the output of both statements in your Noir code by using the `nargo execute` command or the `--show-output` flag when using `nargo test` (provided there are print statements in your tests). + +It is recommended to use `nargo execute` if you want to debug failing constraints with `println` or `print` statements. This is due to every input in a test being a constant rather than a witness, so we issue an error during compilation while we only print during execution (which comes after compilation). Neither `println`, nor `print` are callable for failed constraints caught at compile time. + +Both `print` and `println` are generic functions which can work on integers, fields, strings, and even structs or expressions. Note however, that slices are currently unsupported. For example: + +```rust +struct Person { + age: Field, + height: Field, +} + +fn main(age: Field, height: Field) { + let person = Person { + age: age, + height: height, + }; + println(person); + println(age + height); + println("Hello world!"); +} +``` + +You can print different types in the same statement (including strings) with a type called `fmtstr`. It can be specified in the same way as a normal string, just prepended with an "f" character: + +```rust + let fmt_str = f"i: {i}, j: {j}"; + println(fmt_str); + + let s = myStruct { y: x, x: y }; + println(s); + + println(f"i: {i}, s: {s}"); + + println(x); + println([x, y]); + + let foo = fooStruct { my_struct: s, foo: 15 }; + println(f"s: {s}, foo: {foo}"); + + println(15); // prints 0x0f, implicit Field + println(-1 as u8); // prints 255 + println(-1 as i8); // prints -1 +``` + +Examples shown above are interchangeable between the two `print` statements: + +```rust +let person = Person { age : age, height : height }; + +println(person); +print(person); + +println("Hello world!"); // Prints with a newline at the end of the input +print("Hello world!"); // Prints the input and keeps cursor on the same line +``` diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/merkle_trees.md b/docs/versioned_docs/version-v0.30.0/noir/standard_library/merkle_trees.md new file mode 100644 index 00000000000..6a9ebf72ada --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/merkle_trees.md @@ -0,0 +1,58 @@ +--- +title: Merkle Trees +description: Learn about Merkle Trees in Noir with this tutorial. Explore the basics of computing a merkle root using a proof, with examples. +keywords: + [ + Merkle trees in Noir, + Noir programming language, + check membership, + computing root from leaf, + Noir Merkle tree implementation, + Merkle tree tutorial, + Merkle tree code examples, + Noir libraries, + pedersen hash., + ] +--- + +## compute_merkle_root + +Returns the root of the tree from the provided leaf and its hash path, using a [Pedersen hash](./cryptographic_primitives/hashes.mdx#pedersen_hash). + +```rust +fn compute_merkle_root(leaf : Field, index : Field, hash_path: [Field]) -> Field +``` + +example: + +```rust +/** + // these values are for this example only + index = "0" + priv_key = "0x000000000000000000000000000000000000000000000000000000616c696365" + secret = "0x1929ea3ab8d9106a899386883d9428f8256cfedb3c4f6b66bf4aa4d28a79988f" + note_hash_path = [ + "0x1e61bdae0f027b1b2159e1f9d3f8d00fa668a952dddd822fda80dc745d6f65cc", + "0x0e4223f3925f98934393c74975142bd73079ab0621f4ee133cee050a3c194f1a", + "0x2fd7bb412155bf8693a3bd2a3e7581a679c95c68a052f835dddca85fa1569a40" + ] + */ +fn main(index: Field, priv_key: Field, secret: Field, note_hash_path: [Field; 3]) { + + let pubkey = std::scalar_mul::fixed_base_embedded_curve(priv_key); + let pubkey_x = pubkey[0]; + let pubkey_y = pubkey[1]; + let note_commitment = std::hash::pedersen(&[pubkey_x, pubkey_y, secret]); + + let root = std::merkle::compute_merkle_root(note_commitment[0], index, note_hash_path.as_slice()); + println(root); +} +``` + +To check merkle tree membership: + +1. Include a merkle root as a program input. +2. Compute the merkle root of a given leaf, index and hash path. +3. Assert the merkle roots are equal. + +For more info about merkle trees, see the Wikipedia [page](https://en.wikipedia.org/wiki/Merkle_tree). diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/options.md b/docs/versioned_docs/version-v0.30.0/noir/standard_library/options.md new file mode 100644 index 00000000000..a1bd4e1de5f --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/options.md @@ -0,0 +1,101 @@ +--- +title: Option Type +--- + +The `Option` type is a way to express that a value might be present (`Some(T))` or absent (`None`). It's a safer way to handle potential absence of values, compared to using nulls in many other languages. + +```rust +struct Option { + None, + Some(T), +} +``` + +The `Option` type, already imported into your Noir program, can be used directly: + +```rust +fn main() { + let none = Option::none(); + let some = Option::some(3); +} +``` + +See [this test](https://github.com/noir-lang/noir/blob/5cbfb9c4a06c8865c98ff2b594464b037d821a5c/crates/nargo_cli/tests/test_data/option/src/main.nr) for a more comprehensive set of examples of each of the methods described below. + +## Methods + +### none + +Constructs a none value. + +### some + +Constructs a some wrapper around a given value. + +### is_none + +Returns true if the Option is None. + +### is_some + +Returns true of the Option is Some. + +### unwrap + +Asserts `self.is_some()` and returns the wrapped value. + +### unwrap_unchecked + +Returns the inner value without asserting `self.is_some()`. This method can be useful within an if condition when we already know that `option.is_some()`. If the option is None, there is no guarantee what value will be returned, only that it will be of type T for an `Option`. + +### unwrap_or + +Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value. + +### unwrap_or_else + +Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return a default value. + +### expect + +Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value. The custom message is expected to be a format string. + +### map + +If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`. + +### map_or + +If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value. + +### map_or_else + +If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`. + +### and + +Returns None if self is None. Otherwise, this returns `other`. + +### and_then + +If self is None, this returns None. Otherwise, this calls the given function with the Some value contained within self, and returns the result of that call. In some languages this function is called `flat_map` or `bind`. + +### or + +If self is Some, return self. Otherwise, return `other`. + +### or_else + +If self is Some, return self. Otherwise, return `default()`. + +### xor + +If only one of the two Options is Some, return that option. Otherwise, if both options are Some or both are None, None is returned. + +### filter + +Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true. Otherwise, this returns `None`. + +### flatten + +Flattens an `Option>` into a `Option`. This returns `None` if the outer Option is None. Otherwise, this returns the inner Option. diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/recursion.md b/docs/versioned_docs/version-v0.30.0/noir/standard_library/recursion.md new file mode 100644 index 00000000000..a93894043dc --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/recursion.md @@ -0,0 +1,88 @@ +--- +title: Recursive Proofs +description: Learn about how to write recursive proofs in Noir. +keywords: [recursion, recursive proofs, verification_key, verify_proof] +--- + +Noir supports recursively verifying proofs, meaning you verify the proof of a Noir program in another Noir program. This enables creating proofs of arbitrary size by doing step-wise verification of smaller components of a large proof. + +Read [the explainer on recursion](../../explainers/explainer-recursion.md) to know more about this function and the [guide on how to use it.](../../how_to/how-to-recursion.md) + +## The `#[recursive]` Attribute + +In Noir, the `#[recursive]` attribute is used to indicate that a circuit is designed for recursive proof generation. When applied, it informs the compiler and the tooling that the circuit should be compiled in a way that makes its proofs suitable for recursive verification. This attribute eliminates the need for manual flagging of recursion at the tooling level, streamlining the proof generation process for recursive circuits. + +### Example usage with `#[recursive]` + +```rust +#[recursive] +fn main(x: Field, y: pub Field) { + assert(x == y, "x and y are not equal"); +} + +// This marks the circuit as recursion-friendly and indicates that proofs generated from this circuit +// are intended for recursive verification. +``` + +By incorporating this attribute directly in the circuit's definition, tooling like Nargo and NoirJS can automatically execute recursive-specific duties for Noir programs (e.g. recursive-friendly proof artifact generation) without additional flags or configurations. + +## Verifying Recursive Proofs + +```rust +#[foreign(recursive_aggregation)] +pub fn verify_proof(verification_key: [Field], proof: [Field], public_inputs: [Field], key_hash: Field) {} +``` + +:::info + +This is a black box function. Read [this section](./black_box_fns) to learn more about black box functions in Noir. + +::: + +## Example usage + +```rust +use dep::std; + +fn main( + verification_key : [Field; 114], + proof : [Field; 93], + public_inputs : [Field; 1], + key_hash : Field, + proof_b : [Field; 93], +) { + std::verify_proof( + verification_key.as_slice(), + proof.as_slice(), + public_inputs.as_slice(), + key_hash + ); + + std::verify_proof( + verification_key.as_slice(), + proof_b.as_slice(), + public_inputs.as_slice(), + key_hash + ); +} +``` + +You can see a full example of recursive proofs in [this example recursion demo repo](https://github.com/noir-lang/noir-examples/tree/master/recursion). + +## Parameters + +### `verification_key` + +The verification key for the zk program that is being verified. + +### `proof` + +The proof for the zk program that is being verified. + +### `public_inputs` + +These represent the public inputs of the proof we are verifying. + +### `key_hash` + +A key hash is used to check the validity of the verification key. The circuit implementing this opcode can use this hash to ensure that the key provided to the circuit matches the key produced by the circuit creator. diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/traits.md b/docs/versioned_docs/version-v0.30.0/noir/standard_library/traits.md new file mode 100644 index 00000000000..a14312d2792 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/traits.md @@ -0,0 +1,464 @@ +--- +title: Traits +description: Noir's stdlib provides a few commonly used traits. +keywords: [traits, trait, interface, protocol, default, add, eq] +--- + +## `std::default` + +### `std::default::Default` + +```rust title="default-trait" showLineNumbers +trait Default { + fn default() -> Self; +} +``` +> Source code: noir_stdlib/src/default.nr#L1-L5 + + +Constructs a default value of a type. + +Implementations: +```rust +impl Default for Field { .. } + +impl Default for i8 { .. } +impl Default for i16 { .. } +impl Default for i32 { .. } +impl Default for i64 { .. } + +impl Default for u8 { .. } +impl Default for u16 { .. } +impl Default for u32 { .. } +impl Default for u64 { .. } + +impl Default for () { .. } +impl Default for bool { .. } + +impl Default for [T; N] + where T: Default { .. } + +impl Default for [T] { .. } + +impl Default for (A, B) + where A: Default, B: Default { .. } + +impl Default for (A, B, C) + where A: Default, B: Default, C: Default { .. } + +impl Default for (A, B, C, D) + where A: Default, B: Default, C: Default, D: Default { .. } + +impl Default for (A, B, C, D, E) + where A: Default, B: Default, C: Default, D: Default, E: Default { .. } +``` + +For primitive integer types, the return value of `default` is `0`. Container +types such as arrays are filled with default values of their element type, +except slices whose length is unknown and thus defaulted to zero. + + +## `std::convert` + +### `std::convert::From` + +```rust title="from-trait" showLineNumbers +trait From { + fn from(input: T) -> Self; +} +``` +> Source code: noir_stdlib/src/convert.nr#L1-L5 + + +The `From` trait defines how to convert from a given type `T` to the type on which the trait is implemented. + +The Noir standard library provides a number of implementations of `From` between primitive types. +```rust title="from-impls" showLineNumbers +// Unsigned integers + +impl From for u32 { fn from(value: u8) -> u32 { value as u32 } } + +impl From for u64 { fn from(value: u8) -> u64 { value as u64 } } +impl From for u64 { fn from(value: u32) -> u64 { value as u64 } } + +impl From for Field { fn from(value: u8) -> Field { value as Field } } +impl From for Field { fn from(value: u32) -> Field { value as Field } } +impl From for Field { fn from(value: u64) -> Field { value as Field } } + +// Signed integers + +impl From for i32 { fn from(value: i8) -> i32 { value as i32 } } + +impl From for i64 { fn from(value: i8) -> i64 { value as i64 } } +impl From for i64 { fn from(value: i32) -> i64 { value as i64 } } + +// Booleans +impl From for u8 { fn from(value: bool) -> u8 { value as u8 } } +impl From for u32 { fn from(value: bool) -> u32 { value as u32 } } +impl From for u64 { fn from(value: bool) -> u64 { value as u64 } } +impl From for i8 { fn from(value: bool) -> i8 { value as i8 } } +impl From for i32 { fn from(value: bool) -> i32 { value as i32 } } +impl From for i64 { fn from(value: bool) -> i64 { value as i64 } } +impl From for Field { fn from(value: bool) -> Field { value as Field } } +``` +> Source code: noir_stdlib/src/convert.nr#L25-L52 + + +#### When to implement `From` + +As a general rule of thumb, `From` may be implemented in the [situations where it would be suitable in Rust](https://doc.rust-lang.org/std/convert/trait.From.html#when-to-implement-from): + +- The conversion is *infallible*: Noir does not provide an equivalent to Rust's `TryFrom`, if the conversion can fail then provide a named method instead. +- The conversion is *lossless*: semantically, it should not lose or discard information. For example, `u32: From` can losslessly convert any `u16` into a valid `u32` such that the original `u16` can be recovered. On the other hand, `u16: From` should not be implemented as `2**16` is a `u32` which cannot be losslessly converted into a `u16`. +- The conversion is *value-preserving*: the conceptual kind and meaning of the resulting value is the same, even though the Noir type and technical representation might be different. While it's possible to infallibly and losslessly convert a `u8` into a `str<2>` hex representation, `4u8` and `"04"` are too different for `str<2>: From` to be implemented. +- The conversion is *obvious*: it's the only reasonable conversion between the two types. If there's ambiguity on how to convert between them such that the same input could potentially map to two different values then a named method should be used. For instance rather than implementing `U128: From<[u8; 16]>`, the methods `U128::from_le_bytes` and `U128::from_be_bytes` are used as otherwise the endianness of the array would be ambiguous, resulting in two potential values of `U128` from the same byte array. + +One additional recommendation specific to Noir is: +- The conversion is *efficient*: it's relatively cheap to convert between the two types. Due to being a ZK DSL, it's more important to avoid unnecessary computation compared to Rust. If the implementation of `From` would encourage users to perform unnecessary conversion, resulting in additional proving time, then it may be preferable to expose functionality such that this conversion may be avoided. + +### `std::convert::Into` + +The `Into` trait is defined as the reciprocal of `From`. It should be easy to convince yourself that if we can convert to type `A` from type `B`, then it's possible to convert type `B` into type `A`. + +For this reason, implementing `From` on a type will automatically generate a matching `Into` implementation. One should always prefer implementing `From` over `Into` as implementing `Into` will not generate a matching `From` implementation. + +```rust title="into-trait" showLineNumbers +trait Into { + fn into(self) -> T; +} + +impl Into for U where T: From { + fn into(self) -> T { + T::from(self) + } +} +``` +> Source code: noir_stdlib/src/convert.nr#L13-L23 + + +`Into` is most useful when passing function arguments where the types don't quite match up with what the function expects. In this case, the compiler has enough type information to perform the necessary conversion by just appending `.into()` onto the arguments in question. + + +## `std::cmp` + +### `std::cmp::Eq` + +```rust title="eq-trait" showLineNumbers +trait Eq { + fn eq(self, other: Self) -> bool; +} +``` +> Source code: noir_stdlib/src/cmp.nr#L1-L5 + + +Returns `true` if `self` is equal to `other`. Implementing this trait on a type +allows the type to be used with `==` and `!=`. + +Implementations: +```rust +impl Eq for Field { .. } + +impl Eq for i8 { .. } +impl Eq for i16 { .. } +impl Eq for i32 { .. } +impl Eq for i64 { .. } + +impl Eq for u8 { .. } +impl Eq for u16 { .. } +impl Eq for u32 { .. } +impl Eq for u64 { .. } + +impl Eq for () { .. } +impl Eq for bool { .. } + +impl Eq for [T; N] + where T: Eq { .. } + +impl Eq for [T] + where T: Eq { .. } + +impl Eq for (A, B) + where A: Eq, B: Eq { .. } + +impl Eq for (A, B, C) + where A: Eq, B: Eq, C: Eq { .. } + +impl Eq for (A, B, C, D) + where A: Eq, B: Eq, C: Eq, D: Eq { .. } + +impl Eq for (A, B, C, D, E) + where A: Eq, B: Eq, C: Eq, D: Eq, E: Eq { .. } +``` + +### `std::cmp::Ord` + +```rust title="ord-trait" showLineNumbers +trait Ord { + fn cmp(self, other: Self) -> Ordering; +} +``` +> Source code: noir_stdlib/src/cmp.nr#L102-L106 + + +`a.cmp(b)` compares two values returning `Ordering::less()` if `a < b`, +`Ordering::equal()` if `a == b`, or `Ordering::greater()` if `a > b`. +Implementing this trait on a type allows `<`, `<=`, `>`, and `>=` to be +used on values of the type. + +`std::cmp` also provides `max` and `min` functions for any type which implements the `Ord` trait. + +Implementations: + +```rust +impl Ord for u8 { .. } +impl Ord for u16 { .. } +impl Ord for u32 { .. } +impl Ord for u64 { .. } + +impl Ord for i8 { .. } +impl Ord for i16 { .. } +impl Ord for i32 { .. } + +impl Ord for i64 { .. } + +impl Ord for () { .. } +impl Ord for bool { .. } + +impl Ord for [T; N] + where T: Ord { .. } + +impl Ord for [T] + where T: Ord { .. } + +impl Ord for (A, B) + where A: Ord, B: Ord { .. } + +impl Ord for (A, B, C) + where A: Ord, B: Ord, C: Ord { .. } + +impl Ord for (A, B, C, D) + where A: Ord, B: Ord, C: Ord, D: Ord { .. } + +impl Ord for (A, B, C, D, E) + where A: Ord, B: Ord, C: Ord, D: Ord, E: Ord { .. } +``` + +## `std::ops` + +### `std::ops::Add`, `std::ops::Sub`, `std::ops::Mul`, and `std::ops::Div` + +These traits abstract over addition, subtraction, multiplication, and division respectively. +Implementing these traits for a given type will also allow that type to be used with the corresponding operator +for that trait (`+` for Add, etc) in addition to the normal method names. + +```rust title="add-trait" showLineNumbers +trait Add { + fn add(self, other: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/arith.nr#L1-L5 + +```rust title="sub-trait" showLineNumbers +trait Sub { + fn sub(self, other: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/arith.nr#L19-L23 + +```rust title="mul-trait" showLineNumbers +trait Mul { + fn mul(self, other: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/arith.nr#L37-L41 + +```rust title="div-trait" showLineNumbers +trait Div { + fn div(self, other: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/arith.nr#L55-L59 + + +The implementations block below is given for the `Add` trait, but the same types that implement +`Add` also implement `Sub`, `Mul`, and `Div`. + +Implementations: +```rust +impl Add for Field { .. } + +impl Add for i8 { .. } +impl Add for i16 { .. } +impl Add for i32 { .. } +impl Add for i64 { .. } + +impl Add for u8 { .. } +impl Add for u16 { .. } +impl Add for u32 { .. } +impl Add for u64 { .. } +``` + +### `std::ops::Rem` + +```rust title="rem-trait" showLineNumbers +trait Rem{ + fn rem(self, other: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/arith.nr#L73-L77 + + +`Rem::rem(a, b)` is the remainder function returning the result of what is +left after dividing `a` and `b`. Implementing `Rem` allows the `%` operator +to be used with the implementation type. + +Unlike other numeric traits, `Rem` is not implemented for `Field`. + +Implementations: +```rust +impl Rem for u8 { fn rem(self, other: u8) -> u8 { self % other } } +impl Rem for u16 { fn rem(self, other: u16) -> u16 { self % other } } +impl Rem for u32 { fn rem(self, other: u32) -> u32 { self % other } } +impl Rem for u64 { fn rem(self, other: u64) -> u64 { self % other } } + +impl Rem for i8 { fn rem(self, other: i8) -> i8 { self % other } } +impl Rem for i16 { fn rem(self, other: i16) -> i16 { self % other } } +impl Rem for i32 { fn rem(self, other: i32) -> i32 { self % other } } +impl Rem for i64 { fn rem(self, other: i64) -> i64 { self % other } } +``` + +### `std::ops::Neg` + +```rust title="neg-trait" showLineNumbers +trait Neg { + fn neg(self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/arith.nr#L89-L93 + + +`Neg::neg` is equivalent to the unary negation operator `-`. + +Implementations: +```rust title="neg-trait-impls" showLineNumbers +impl Neg for Field { fn neg(self) -> Field { -self } } + +impl Neg for i8 { fn neg(self) -> i8 { -self } } +impl Neg for i16 { fn neg(self) -> i16 { -self } } +impl Neg for i32 { fn neg(self) -> i32 { -self } } +impl Neg for i64 { fn neg(self) -> i64 { -self } } +``` +> Source code: noir_stdlib/src/ops/arith.nr#L95-L102 + + +### `std::ops::Not` + +```rust title="not-trait" showLineNumbers +trait Not { + fn not(self: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/bit.nr#L1-L5 + + +`Not::not` is equivalent to the unary bitwise NOT operator `!`. + +Implementations: +```rust title="not-trait-impls" showLineNumbers +impl Not for bool { fn not(self) -> bool { !self } } + +impl Not for u64 { fn not(self) -> u64 { !self } } +impl Not for u32 { fn not(self) -> u32 { !self } } +impl Not for u16 { fn not(self) -> u16 { !self } } +impl Not for u8 { fn not(self) -> u8 { !self } } +impl Not for u1 { fn not(self) -> u1 { !self } } + +impl Not for i8 { fn not(self) -> i8 { !self } } +impl Not for i16 { fn not(self) -> i16 { !self } } +impl Not for i32 { fn not(self) -> i32 { !self } } +impl Not for i64 { fn not(self) -> i64 { !self } } +``` +> Source code: noir_stdlib/src/ops/bit.nr#L7-L20 + + +### `std::ops::{ BitOr, BitAnd, BitXor }` + +```rust title="bitor-trait" showLineNumbers +trait BitOr { + fn bitor(self, other: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/bit.nr#L22-L26 + +```rust title="bitand-trait" showLineNumbers +trait BitAnd { + fn bitand(self, other: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/bit.nr#L40-L44 + +```rust title="bitxor-trait" showLineNumbers +trait BitXor { + fn bitxor(self, other: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/bit.nr#L58-L62 + + +Traits for the bitwise operations `|`, `&`, and `^`. + +Implementing `BitOr`, `BitAnd` or `BitXor` for a type allows the `|`, `&`, or `^` operator respectively +to be used with the type. + +The implementations block below is given for the `BitOr` trait, but the same types that implement +`BitOr` also implement `BitAnd` and `BitXor`. + +Implementations: +```rust +impl BitOr for bool { fn bitor(self, other: bool) -> bool { self | other } } + +impl BitOr for u8 { fn bitor(self, other: u8) -> u8 { self | other } } +impl BitOr for u16 { fn bitor(self, other: u16) -> u16 { self | other } } +impl BitOr for u32 { fn bitor(self, other: u32) -> u32 { self | other } } +impl BitOr for u64 { fn bitor(self, other: u64) -> u64 { self | other } } + +impl BitOr for i8 { fn bitor(self, other: i8) -> i8 { self | other } } +impl BitOr for i16 { fn bitor(self, other: i16) -> i16 { self | other } } +impl BitOr for i32 { fn bitor(self, other: i32) -> i32 { self | other } } +impl BitOr for i64 { fn bitor(self, other: i64) -> i64 { self | other } } +``` + +### `std::ops::{ Shl, Shr }` + +```rust title="shl-trait" showLineNumbers +trait Shl { + fn shl(self, other: u8) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/bit.nr#L76-L80 + +```rust title="shr-trait" showLineNumbers +trait Shr { + fn shr(self, other: u8) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/bit.nr#L93-L97 + + +Traits for a bit shift left and bit shift right. + +Implementing `Shl` for a type allows the left shift operator (`<<`) to be used with the implementation type. +Similarly, implementing `Shr` allows the right shift operator (`>>`) to be used with the type. + +Note that bit shifting is not currently implemented for signed types. + +The implementations block below is given for the `Shl` trait, but the same types that implement +`Shl` also implement `Shr`. + +Implementations: +```rust +impl Shl for u8 { fn shl(self, other: u8) -> u8 { self << other } } +impl Shl for u16 { fn shl(self, other: u16) -> u16 { self << other } } +impl Shl for u32 { fn shl(self, other: u32) -> u32 { self << other } } +impl Shl for u64 { fn shl(self, other: u64) -> u64 { self << other } } +``` diff --git a/docs/versioned_docs/version-v0.30.0/noir/standard_library/zeroed.md b/docs/versioned_docs/version-v0.30.0/noir/standard_library/zeroed.md new file mode 100644 index 00000000000..f450fecdd36 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/noir/standard_library/zeroed.md @@ -0,0 +1,26 @@ +--- +title: Zeroed Function +description: + The zeroed function returns a zeroed value of any type. +keywords: + [ + zeroed + ] +--- + +Implements `fn zeroed() -> T` to return a zeroed value of any type. This function is generally unsafe to use as the zeroed bit pattern is not guaranteed to be valid for all types. It can however, be useful in cases when the value is guaranteed not to be used such as in a BoundedVec library implementing a growable vector, up to a certain length, backed by an array. The array can be initialized with zeroed values which are guaranteed to be inaccessible until the vector is pushed to. Similarly, enumerations in noir can be implemented using this method by providing zeroed values for the unused variants. + +You can access the function at `std::unsafe::zeroed`. + +This function currently supports the following types: + +- Field +- Bool +- Uint +- Array +- Slice +- String +- Tuple +- Function + +Using it on other types could result in unexpected behavior. diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/.nojekyll b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/.nojekyll new file mode 100644 index 00000000000..e2ac6616add --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/.nojekyll @@ -0,0 +1 @@ +TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md new file mode 100644 index 00000000000..d7249d24330 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md @@ -0,0 +1,160 @@ +# BarretenbergBackend + +## Extends + +- `BarretenbergVerifierBackend` + +## Implements + +- [`Backend`](../index.md#backend) + +## Constructors + +### new BarretenbergBackend(acirCircuit, options) + +```ts +new BarretenbergBackend(acirCircuit, options): BarretenbergBackend +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `acirCircuit` | `CompiledCircuit` | +| `options` | [`BackendOptions`](../type-aliases/BackendOptions.md) | + +#### Returns + +[`BarretenbergBackend`](BarretenbergBackend.md) + +#### Inherited from + +BarretenbergVerifierBackend.constructor + +## Properties + +| Property | Type | Description | Inheritance | +| :------ | :------ | :------ | :------ | +| `acirComposer` | `any` | - | BarretenbergVerifierBackend.acirComposer | +| `acirUncompressedBytecode` | `Uint8Array` | - | BarretenbergVerifierBackend.acirUncompressedBytecode | +| `api` | `Barretenberg` | - | BarretenbergVerifierBackend.api | +| `options` | [`BackendOptions`](../type-aliases/BackendOptions.md) | - | BarretenbergVerifierBackend.options | + +## Methods + +### destroy() + +```ts +destroy(): Promise +``` + +#### Returns + +`Promise`\<`void`\> + +#### Inherited from + +BarretenbergVerifierBackend.destroy + +*** + +### generateProof() + +```ts +generateProof(compressedWitness): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `compressedWitness` | `Uint8Array` | + +#### Returns + +`Promise`\<`ProofData`\> + +#### Description + +Generates a proof + +*** + +### generateRecursiveProofArtifacts() + +```ts +generateRecursiveProofArtifacts(proofData, numOfPublicInputs): Promise +``` + +Generates artifacts that will be passed to a circuit that will verify this proof. + +Instead of passing the proof and verification key as a byte array, we pass them +as fields which makes it cheaper to verify in a circuit. + +The proof that is passed here will have been created using a circuit +that has the #[recursive] attribute on its `main` method. + +The number of public inputs denotes how many public inputs are in the inner proof. + +#### Parameters + +| Parameter | Type | Default value | +| :------ | :------ | :------ | +| `proofData` | `ProofData` | `undefined` | +| `numOfPublicInputs` | `number` | `0` | + +#### Returns + +`Promise`\<`object`\> + +#### Example + +```typescript +const artifacts = await backend.generateRecursiveProofArtifacts(proof, numOfPublicInputs); +``` + +*** + +### getVerificationKey() + +```ts +getVerificationKey(): Promise +``` + +#### Returns + +`Promise`\<`Uint8Array`\> + +#### Inherited from + +BarretenbergVerifierBackend.getVerificationKey + +*** + +### verifyProof() + +```ts +verifyProof(proofData): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | `ProofData` | + +#### Returns + +`Promise`\<`boolean`\> + +#### Inherited from + +BarretenbergVerifierBackend.verifyProof + +#### Description + +Verifies a proof + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergVerifier.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergVerifier.md new file mode 100644 index 00000000000..500276ea748 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergVerifier.md @@ -0,0 +1,58 @@ +# BarretenbergVerifier + +## Constructors + +### new BarretenbergVerifier(options) + +```ts +new BarretenbergVerifier(options): BarretenbergVerifier +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `options` | [`BackendOptions`](../type-aliases/BackendOptions.md) | + +#### Returns + +[`BarretenbergVerifier`](BarretenbergVerifier.md) + +## Methods + +### destroy() + +```ts +destroy(): Promise +``` + +#### Returns + +`Promise`\<`void`\> + +*** + +### verifyProof() + +```ts +verifyProof(proofData, verificationKey): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | `ProofData` | +| `verificationKey` | `Uint8Array` | + +#### Returns + +`Promise`\<`boolean`\> + +#### Description + +Verifies a proof + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/index.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/index.md new file mode 100644 index 00000000000..64971973196 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/index.md @@ -0,0 +1,59 @@ +# backend_barretenberg + +## Exports + +### Classes + +| Class | Description | +| :------ | :------ | +| [BarretenbergBackend](classes/BarretenbergBackend.md) | - | +| [BarretenbergVerifier](classes/BarretenbergVerifier.md) | - | + +### Type Aliases + +| Type alias | Description | +| :------ | :------ | +| [BackendOptions](type-aliases/BackendOptions.md) | - | + +## References + +### CompiledCircuit + +Renames and re-exports [Backend](index.md#backend) + +*** + +### ProofData + +Renames and re-exports [Backend](index.md#backend) + +## Variables + +### Backend + +```ts +Backend: any; +``` + +## Functions + +### publicInputsToWitnessMap() + +```ts +publicInputsToWitnessMap(publicInputs, abi): Backend +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `publicInputs` | `string`[] | +| `abi` | `Abi` | + +#### Returns + +[`Backend`](index.md#backend) + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions.md new file mode 100644 index 00000000000..b49a479f4f4 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions.md @@ -0,0 +1,21 @@ +# BackendOptions + +```ts +type BackendOptions: object; +``` + +## Description + +An options object, currently only used to specify the number of threads to use. + +## Type declaration + +| Member | Type | Description | +| :------ | :------ | :------ | +| `memory` | `object` | - | +| `memory.maximum` | `number` | - | +| `threads` | `number` | **Description**

Number of threads | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/typedoc-sidebar.cjs b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/typedoc-sidebar.cjs new file mode 100644 index 00000000000..d7d5128f9e3 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/backend_barretenberg/typedoc-sidebar.cjs @@ -0,0 +1,4 @@ +// @ts-check +/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ +const typedocSidebar = { items: [{"type":"category","label":"Classes","items":[{"type":"doc","id":"reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend","label":"BarretenbergBackend"},{"type":"doc","id":"reference/NoirJS/backend_barretenberg/classes/BarretenbergVerifier","label":"BarretenbergVerifier"}]},{"type":"category","label":"Type Aliases","items":[{"type":"doc","id":"reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions","label":"BackendOptions"}]}]}; +module.exports = typedocSidebar.items; \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/.nojekyll b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/.nojekyll new file mode 100644 index 00000000000..e2ac6616add --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/.nojekyll @@ -0,0 +1 @@ +TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/classes/Noir.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/classes/Noir.md new file mode 100644 index 00000000000..45dd62ee57e --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/classes/Noir.md @@ -0,0 +1,132 @@ +# Noir + +## Constructors + +### new Noir(circuit, backend) + +```ts +new Noir(circuit, backend?): Noir +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `circuit` | `CompiledCircuit` | +| `backend`? | `any` | + +#### Returns + +[`Noir`](Noir.md) + +## Methods + +### destroy() + +```ts +destroy(): Promise +``` + +#### Returns + +`Promise`\<`void`\> + +#### Description + +Destroys the underlying backend instance. + +#### Example + +```typescript +await noir.destroy(); +``` + +*** + +### execute() + +```ts +execute(inputs, foreignCallHandler?): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `inputs` | `InputMap` | +| `foreignCallHandler`? | [`ForeignCallHandler`](../type-aliases/ForeignCallHandler.md) | + +#### Returns + +`Promise`\<`object`\> + +#### Description + +Allows to execute a circuit to get its witness and return value. + +#### Example + +```typescript +async execute(inputs) +``` + +*** + +### generateProof() + +```ts +generateProof(inputs, foreignCallHandler?): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `inputs` | `InputMap` | +| `foreignCallHandler`? | [`ForeignCallHandler`](../type-aliases/ForeignCallHandler.md) | + +#### Returns + +`Promise`\<`ProofData`\> + +#### Description + +Generates a witness and a proof given an object as input. + +#### Example + +```typescript +async generateProof(input) +``` + +*** + +### verifyProof() + +```ts +verifyProof(proofData): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | `ProofData` | + +#### Returns + +`Promise`\<`boolean`\> + +#### Description + +Instantiates the verification key and verifies a proof. + +#### Example + +```typescript +async verifyProof(proof) +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/and.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/and.md new file mode 100644 index 00000000000..c783283e396 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/and.md @@ -0,0 +1,22 @@ +# and() + +```ts +and(lhs, rhs): string +``` + +Performs a bitwise AND operation between `lhs` and `rhs` + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `lhs` | `string` | | +| `rhs` | `string` | | + +## Returns + +`string` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/blake2s256.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/blake2s256.md new file mode 100644 index 00000000000..7882d0da8d5 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/blake2s256.md @@ -0,0 +1,21 @@ +# blake2s256() + +```ts +blake2s256(inputs): Uint8Array +``` + +Calculates the Blake2s256 hash of the input bytes + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `inputs` | `Uint8Array` | | + +## Returns + +`Uint8Array` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify.md new file mode 100644 index 00000000000..5e3cd53e9d3 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify.md @@ -0,0 +1,28 @@ +# ecdsa\_secp256k1\_verify() + +```ts +ecdsa_secp256k1_verify( + hashed_msg, + public_key_x_bytes, + public_key_y_bytes, + signature): boolean +``` + +Verifies a ECDSA signature over the secp256k1 curve. + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `hashed_msg` | `Uint8Array` | | +| `public_key_x_bytes` | `Uint8Array` | | +| `public_key_y_bytes` | `Uint8Array` | | +| `signature` | `Uint8Array` | | + +## Returns + +`boolean` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify.md new file mode 100644 index 00000000000..0b20ff68957 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify.md @@ -0,0 +1,28 @@ +# ecdsa\_secp256r1\_verify() + +```ts +ecdsa_secp256r1_verify( + hashed_msg, + public_key_x_bytes, + public_key_y_bytes, + signature): boolean +``` + +Verifies a ECDSA signature over the secp256r1 curve. + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `hashed_msg` | `Uint8Array` | | +| `public_key_x_bytes` | `Uint8Array` | | +| `public_key_y_bytes` | `Uint8Array` | | +| `signature` | `Uint8Array` | | + +## Returns + +`boolean` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/keccak256.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/keccak256.md new file mode 100644 index 00000000000..d10f155ce86 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/keccak256.md @@ -0,0 +1,21 @@ +# keccak256() + +```ts +keccak256(inputs): Uint8Array +``` + +Calculates the Keccak256 hash of the input bytes + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `inputs` | `Uint8Array` | | + +## Returns + +`Uint8Array` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/sha256.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/sha256.md new file mode 100644 index 00000000000..6ba4ecac022 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/sha256.md @@ -0,0 +1,21 @@ +# sha256() + +```ts +sha256(inputs): Uint8Array +``` + +Calculates the SHA256 hash of the input bytes + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `inputs` | `Uint8Array` | | + +## Returns + +`Uint8Array` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/xor.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/xor.md new file mode 100644 index 00000000000..8d762b895d3 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/functions/xor.md @@ -0,0 +1,22 @@ +# xor() + +```ts +xor(lhs, rhs): string +``` + +Performs a bitwise XOR operation between `lhs` and `rhs` + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `lhs` | `string` | | +| `rhs` | `string` | | + +## Returns + +`string` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/index.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/index.md new file mode 100644 index 00000000000..40bef8393fc --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/index.md @@ -0,0 +1,55 @@ +# noir_js + +## Exports + +### Classes + +| Class | Description | +| :------ | :------ | +| [Noir](classes/Noir.md) | - | + +### Type Aliases + +| Type alias | Description | +| :------ | :------ | +| [ErrorWithPayload](type-aliases/ErrorWithPayload.md) | - | +| [ForeignCallHandler](type-aliases/ForeignCallHandler.md) | A callback which performs an foreign call and returns the response. | +| [ForeignCallInput](type-aliases/ForeignCallInput.md) | - | +| [ForeignCallOutput](type-aliases/ForeignCallOutput.md) | - | +| [WitnessMap](type-aliases/WitnessMap.md) | - | + +### Functions + +| Function | Description | +| :------ | :------ | +| [and](functions/and.md) | Performs a bitwise AND operation between `lhs` and `rhs` | +| [blake2s256](functions/blake2s256.md) | Calculates the Blake2s256 hash of the input bytes | +| [ecdsa\_secp256k1\_verify](functions/ecdsa_secp256k1_verify.md) | Verifies a ECDSA signature over the secp256k1 curve. | +| [ecdsa\_secp256r1\_verify](functions/ecdsa_secp256r1_verify.md) | Verifies a ECDSA signature over the secp256r1 curve. | +| [keccak256](functions/keccak256.md) | Calculates the Keccak256 hash of the input bytes | +| [sha256](functions/sha256.md) | Calculates the SHA256 hash of the input bytes | +| [xor](functions/xor.md) | Performs a bitwise XOR operation between `lhs` and `rhs` | + +## References + +### CompiledCircuit + +Renames and re-exports [InputMap](index.md#inputmap) + +*** + +### ProofData + +Renames and re-exports [InputMap](index.md#inputmap) + +## Variables + +### InputMap + +```ts +InputMap: any; +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/ErrorWithPayload.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/ErrorWithPayload.md new file mode 100644 index 00000000000..e8c2f4aef3d --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/ErrorWithPayload.md @@ -0,0 +1,15 @@ +# ErrorWithPayload + +```ts +type ErrorWithPayload: ExecutionError & object; +``` + +## Type declaration + +| Member | Type | Description | +| :------ | :------ | :------ | +| `decodedAssertionPayload` | `any` | - | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md new file mode 100644 index 00000000000..812b8b16481 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md @@ -0,0 +1,24 @@ +# ForeignCallHandler + +```ts +type ForeignCallHandler: (name, inputs) => Promise; +``` + +A callback which performs an foreign call and returns the response. + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `name` | `string` | The identifier for the type of foreign call being performed. | +| `inputs` | [`ForeignCallInput`](ForeignCallInput.md)[] | An array of hex encoded inputs to the foreign call. | + +## Returns + +`Promise`\<[`ForeignCallOutput`](ForeignCallOutput.md)[]\> + +outputs - An array of hex encoded outputs containing the results of the foreign call. + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/ForeignCallInput.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/ForeignCallInput.md new file mode 100644 index 00000000000..dd95809186a --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/ForeignCallInput.md @@ -0,0 +1,9 @@ +# ForeignCallInput + +```ts +type ForeignCallInput: string[]; +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md new file mode 100644 index 00000000000..b71fb78a946 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md @@ -0,0 +1,9 @@ +# ForeignCallOutput + +```ts +type ForeignCallOutput: string | string[]; +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/WitnessMap.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/WitnessMap.md new file mode 100644 index 00000000000..258c46f9d0c --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/type-aliases/WitnessMap.md @@ -0,0 +1,9 @@ +# WitnessMap + +```ts +type WitnessMap: Map; +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/typedoc-sidebar.cjs b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/typedoc-sidebar.cjs new file mode 100644 index 00000000000..b3156097df6 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_js/typedoc-sidebar.cjs @@ -0,0 +1,4 @@ +// @ts-check +/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ +const typedocSidebar = { items: [{"type":"category","label":"Classes","items":[{"type":"doc","id":"reference/NoirJS/noir_js/classes/Noir","label":"Noir"}]},{"type":"category","label":"Type Aliases","items":[{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/ErrorWithPayload","label":"ErrorWithPayload"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/ForeignCallHandler","label":"ForeignCallHandler"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/ForeignCallInput","label":"ForeignCallInput"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/ForeignCallOutput","label":"ForeignCallOutput"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/WitnessMap","label":"WitnessMap"}]},{"type":"category","label":"Functions","items":[{"type":"doc","id":"reference/NoirJS/noir_js/functions/and","label":"and"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/blake2s256","label":"blake2s256"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify","label":"ecdsa_secp256k1_verify"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify","label":"ecdsa_secp256r1_verify"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/keccak256","label":"keccak256"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/sha256","label":"sha256"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/xor","label":"xor"}]}]}; +module.exports = typedocSidebar.items; \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/.nojekyll b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/.nojekyll new file mode 100644 index 00000000000..e2ac6616add --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/.nojekyll @@ -0,0 +1 @@ +TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/functions/compile.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/functions/compile.md new file mode 100644 index 00000000000..6faf763b37f --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/functions/compile.md @@ -0,0 +1,51 @@ +# compile() + +```ts +compile( + fileManager, + projectPath?, + logFn?, +debugLogFn?): Promise +``` + +Compiles a Noir project + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `fileManager` | `FileManager` | The file manager to use | +| `projectPath`? | `string` | The path to the project inside the file manager. Defaults to the root of the file manager | +| `logFn`? | `LogFn` | A logging function. If not provided, console.log will be used | +| `debugLogFn`? | `LogFn` | A debug logging function. If not provided, logFn will be used | + +## Returns + +`Promise`\<[`ProgramCompilationArtifacts`](../index.md#programcompilationartifacts)\> + +## Example + +```typescript +// Node.js + +import { compile_program, createFileManager } from '@noir-lang/noir_wasm'; + +const fm = createFileManager(myProjectPath); +const myCompiledCode = await compile_program(fm); +``` + +```typescript +// Browser + +import { compile_program, createFileManager } from '@noir-lang/noir_wasm'; + +const fm = createFileManager('/'); +for (const path of files) { + await fm.writeFile(path, await getFileAsStream(path)); +} +const myCompiledCode = await compile_program(fm); +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/functions/compile_contract.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/functions/compile_contract.md new file mode 100644 index 00000000000..7d0b39a43ef --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/functions/compile_contract.md @@ -0,0 +1,51 @@ +# compile\_contract() + +```ts +compile_contract( + fileManager, + projectPath?, + logFn?, +debugLogFn?): Promise +``` + +Compiles a Noir project + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `fileManager` | `FileManager` | The file manager to use | +| `projectPath`? | `string` | The path to the project inside the file manager. Defaults to the root of the file manager | +| `logFn`? | `LogFn` | A logging function. If not provided, console.log will be used | +| `debugLogFn`? | `LogFn` | A debug logging function. If not provided, logFn will be used | + +## Returns + +`Promise`\<[`ContractCompilationArtifacts`](../index.md#contractcompilationartifacts)\> + +## Example + +```typescript +// Node.js + +import { compile_contract, createFileManager } from '@noir-lang/noir_wasm'; + +const fm = createFileManager(myProjectPath); +const myCompiledCode = await compile_contract(fm); +``` + +```typescript +// Browser + +import { compile_contract, createFileManager } from '@noir-lang/noir_wasm'; + +const fm = createFileManager('/'); +for (const path of files) { + await fm.writeFile(path, await getFileAsStream(path)); +} +const myCompiledCode = await compile_contract(fm); +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/functions/createFileManager.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/functions/createFileManager.md new file mode 100644 index 00000000000..7e65c1d69c7 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/functions/createFileManager.md @@ -0,0 +1,21 @@ +# createFileManager() + +```ts +createFileManager(dataDir): FileManager +``` + +Creates a new FileManager instance based on fs in node and memfs in the browser (via webpack alias) + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `dataDir` | `string` | root of the file system | + +## Returns + +`FileManager` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/functions/inflateDebugSymbols.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/functions/inflateDebugSymbols.md new file mode 100644 index 00000000000..fcea9275341 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/functions/inflateDebugSymbols.md @@ -0,0 +1,21 @@ +# inflateDebugSymbols() + +```ts +inflateDebugSymbols(debugSymbols): any +``` + +Decompresses and decodes the debug symbols + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `debugSymbols` | `string` | The base64 encoded debug symbols | + +## Returns + +`any` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/index.md b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/index.md new file mode 100644 index 00000000000..b6e0f9d1bc0 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/index.md @@ -0,0 +1,49 @@ +# noir_wasm + +## Exports + +### Functions + +| Function | Description | +| :------ | :------ | +| [compile](functions/compile.md) | Compiles a Noir project | +| [compile\_contract](functions/compile_contract.md) | Compiles a Noir project | +| [createFileManager](functions/createFileManager.md) | Creates a new FileManager instance based on fs in node and memfs in the browser (via webpack alias) | +| [inflateDebugSymbols](functions/inflateDebugSymbols.md) | Decompresses and decodes the debug symbols | + +## References + +### compile\_program + +Renames and re-exports [compile](functions/compile.md) + +## Interfaces + +### ContractCompilationArtifacts + +The compilation artifacts of a given contract. + +#### Properties + +| Property | Type | Description | +| :------ | :------ | :------ | +| `contract` | `ContractArtifact` | The compiled contract. | +| `warnings` | `unknown`[] | Compilation warnings. | + +*** + +### ProgramCompilationArtifacts + +The compilation artifacts of a given program. + +#### Properties + +| Property | Type | Description | +| :------ | :------ | :------ | +| `name` | `string` | not part of the compilation output, injected later | +| `program` | `ProgramArtifact` | The compiled contract. | +| `warnings` | `unknown`[] | Compilation warnings. | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/typedoc-sidebar.cjs b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/typedoc-sidebar.cjs new file mode 100644 index 00000000000..e0870710349 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/NoirJS/noir_wasm/typedoc-sidebar.cjs @@ -0,0 +1,4 @@ +// @ts-check +/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ +const typedocSidebar = { items: [{"type":"doc","id":"reference/NoirJS/noir_wasm/index","label":"API"},{"type":"category","label":"Functions","items":[{"type":"doc","id":"reference/NoirJS/noir_wasm/functions/compile","label":"compile"},{"type":"doc","id":"reference/NoirJS/noir_wasm/functions/compile_contract","label":"compile_contract"},{"type":"doc","id":"reference/NoirJS/noir_wasm/functions/createFileManager","label":"createFileManager"},{"type":"doc","id":"reference/NoirJS/noir_wasm/functions/inflateDebugSymbols","label":"inflateDebugSymbols"}]}]}; +module.exports = typedocSidebar.items; \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.30.0/reference/_category_.json b/docs/versioned_docs/version-v0.30.0/reference/_category_.json new file mode 100644 index 00000000000..5b6a20a609a --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 4, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.30.0/reference/debugger/_category_.json b/docs/versioned_docs/version-v0.30.0/reference/debugger/_category_.json new file mode 100644 index 00000000000..27869205ad3 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/debugger/_category_.json @@ -0,0 +1,6 @@ +{ + "label": "Debugger", + "position": 1, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.30.0/reference/debugger/debugger_known_limitations.md b/docs/versioned_docs/version-v0.30.0/reference/debugger/debugger_known_limitations.md new file mode 100644 index 00000000000..936d416ac4b --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/debugger/debugger_known_limitations.md @@ -0,0 +1,59 @@ +--- +title: Known limitations +description: + An overview of known limitations of the current version of the Noir debugger +keywords: + [ + Nargo, + Noir Debugger, + VS Code, + ] +sidebar_position: 2 +--- + +# Debugger Known Limitations + +There are currently some limits to what the debugger can observe. + +## Mutable references + +The debugger is currently blind to any state mutated via a mutable reference. For example, in: + +``` +let mut x = 1; +let y = &mut x; +*y = 2; +``` + +The update on `x` will not be observed by the debugger. That means, when running `vars` from the debugger REPL, or inspecting the _local variables_ pane in the VS Code debugger, `x` will appear with value 1 despite having executed `*y = 2;`. + +## Variables of type function or mutable references are opaque + +When inspecting variables, any variable of type `Function` or `MutableReference` will render its value as `<>` or `<>`. + +## Debugger instrumentation affects resulting ACIR + +In order to make the state of local variables observable, the debugger compiles Noir circuits interleaving foreign calls that track any mutations to them. While this works (except in the cases described above) and doesn't introduce any behavior changes, it does as a side effect produce bigger bytecode. In particular, when running the command `opcodes` on the REPL debugger, you will notice Unconstrained VM blocks that look like this: + +``` +... +5 BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [], q_c: 2 }), Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(2))], q_c: 0 })] + | outputs=[] + 5.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 5.1 | Mov { destination: RegisterIndex(3), source: RegisterIndex(1) } + 5.2 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 5.3 | Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 5.4 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 5.5 | Mov { destination: RegisterIndex(3), source: RegisterIndex(3) } + 5.6 | Call { location: 8 } + 5.7 | Stop + 5.8 | ForeignCall { function: "__debug_var_assign", destinations: [], inputs: [RegisterIndex(RegisterIndex(2)), RegisterIndex(RegisterIndex(3))] } +... +``` + +If you are interested in debugging/inspecting compiled ACIR without these synthetic changes, you can invoke the REPL debugger with the `--skip-instrumentation` flag or launch the VS Code debugger with the `skipConfiguration` property set to true in its launch configuration. You can find more details about those in the [Debugger REPL reference](debugger_repl.md) and the [VS Code Debugger reference](debugger_vscode.md). + +:::note +Skipping debugger instrumentation means you won't be able to inspect values of local variables. +::: + diff --git a/docs/versioned_docs/version-v0.30.0/reference/debugger/debugger_repl.md b/docs/versioned_docs/version-v0.30.0/reference/debugger/debugger_repl.md new file mode 100644 index 00000000000..46e2011304e --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/debugger/debugger_repl.md @@ -0,0 +1,360 @@ +--- +title: REPL Debugger +description: + Noir Debugger REPL options and commands. +keywords: + [ + Nargo, + Noir CLI, + Noir Debugger, + REPL, + ] +sidebar_position: 1 +--- + +## Running the REPL debugger + +`nargo debug [OPTIONS] [WITNESS_NAME]` + +Runs the Noir REPL debugger. If a `WITNESS_NAME` is provided the debugger writes the resulting execution witness to a `WITNESS_NAME` file. + +### Options + +| Option | Description | +| --------------------- | ------------------------------------------------------------ | +| `-p, --prover-name ` | The name of the toml file which contains the inputs for the prover [default: Prover]| +| `--package ` | The name of the package to debug | +| `--print-acir` | Display the ACIR for compiled circuit | +| `--deny-warnings` | Treat all warnings as errors | +| `--silence-warnings` | Suppress warnings | +| `-h, --help` | Print help | + +None of these options are required. + +:::note +Since the debugger starts by compiling the target package, all Noir compiler options are also available. Check out the [compiler reference](../nargo_commands.md#nargo-compile) to learn more about the compiler options. +::: + +## REPL commands + +Once the debugger is running, it accepts the following commands. + +#### `help` (h) + +Displays the menu of available commands. + +``` +> help +Available commands: + + opcodes display ACIR opcodes + into step into to the next opcode + next step until a new source location is reached + out step until a new source location is reached + and the current stack frame is finished + break LOCATION:OpcodeLocation add a breakpoint at an opcode location + over step until a new source location is reached + without diving into function calls + restart restart the debugging session + delete LOCATION:OpcodeLocation delete breakpoint at an opcode location + witness show witness map + witness index:u32 display a single witness from the witness map + witness index:u32 value:String update a witness with the given value + memset index:usize value:String update a memory cell with the given + value + continue continue execution until the end of the + program + vars show variable values available at this point + in execution + stacktrace display the current stack trace + memory show memory (valid when executing unconstrained code) value + step step to the next ACIR opcode + +Other commands: + + help Show this help message + quit Quit repl + +``` + +### Stepping through programs + +#### `next` (n) + +Step until the next Noir source code location. While other commands, such as [`into`](#into-i) and [`step`](#step-s), allow for finer grained control of the program's execution at the opcode level, `next` is source code centric. For example: + +``` +3 ... +4 fn main(x: u32) { +5 assert(entry_point(x) == 2); +6 swap_entry_point(x, x + 1); +7 -> assert(deep_entry_point(x) == 4); +8 multiple_values_entry_point(x); +9 } +``` + + +Using `next` here would cause the debugger to jump to the definition of `deep_entry_point` (if available). + +If you want to step over `deep_entry_point` and go straight to line 8, use [the `over` command](#over) instead. + +#### `over` + +Step until the next source code location, without diving into function calls. For example: + +``` +3 ... +4 fn main(x: u32) { +5 assert(entry_point(x) == 2); +6 swap_entry_point(x, x + 1); +7 -> assert(deep_entry_point(x) == 4); +8 multiple_values_entry_point(x); +9 } +``` + + +Using `over` here would cause the debugger to execute until line 8 (`multiple_values_entry_point(x);`). + +If you want to step into `deep_entry_point` instead, use [the `next` command](#next-n). + +#### `out` + +Step until the end of the current function call. For example: + +``` + 3 ... + 4 fn main(x: u32) { + 5 assert(entry_point(x) == 2); + 6 swap_entry_point(x, x + 1); + 7 -> assert(deep_entry_point(x) == 4); + 8 multiple_values_entry_point(x); + 9 } + 10 + 11 unconstrained fn returns_multiple_values(x: u32) -> (u32, u32, u32, u32) { + 12 ... + ... + 55 + 56 unconstrained fn deep_entry_point(x: u32) -> u32 { + 57 -> level_1(x + 1) + 58 } + +``` + +Running `out` here will resume execution until line 8. + +#### `step` (s) + +Skips to the next ACIR code. A compiled Noir program is a sequence of ACIR opcodes. However, an unconstrained VM opcode denotes the start of an unconstrained code block, to be executed by the unconstrained VM. For example (redacted for brevity): + +``` +0 BLACKBOX::RANGE [(_0, num_bits: 32)] [ ] +1 -> BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })] outputs=[Simple(Witness(1))] + 1.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 1.1 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 1.2 | Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 1.3 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 1.4 | Call { location: 7 } + ... + 1.43 | Return +2 EXPR [ (1, _1) -2 ] +``` + +The `->` here shows the debugger paused at an ACIR opcode: `BRILLIG`, at index 1, which denotes an unconstrained code block is about to start. + +Using the `step` command at this point would result in the debugger stopping at ACIR opcode 2, `EXPR`, skipping unconstrained computation steps. + +Use [the `into` command](#into-i) instead if you want to follow unconstrained computation step by step. + +#### `into` (i) + +Steps into the next opcode. A compiled Noir program is a sequence of ACIR opcodes. However, a BRILLIG opcode denotes the start of an unconstrained code block, to be executed by the unconstrained VM. For example (redacted for brevity): + +``` +0 BLACKBOX::RANGE [(_0, num_bits: 32)] [ ] +1 -> BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })] outputs=[Simple(Witness(1))] + 1.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 1.1 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 1.2 | Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 1.3 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 1.4 | Call { location: 7 } + ... + 1.43 | Return +2 EXPR [ (1, _1) -2 ] +``` + +The `->` here shows the debugger paused at an ACIR opcode: `BRILLIG`, at index 1, which denotes an unconstrained code block is about to start. + +Using the `into` command at this point would result in the debugger stopping at opcode 1.0, `Mov ...`, allowing the debugger user to follow unconstrained computation step by step. + +Use [the `step` command](#step-s) instead if you want to skip to the next ACIR code directly. + +#### `continue` (c) + +Continues execution until the next breakpoint, or the end of the program. + +#### `restart` (res) + +Interrupts execution, and restarts a new debugging session from scratch. + +#### `opcodes` (o) + +Display the program's ACIR opcode sequence. For example: + +``` +0 BLACKBOX::RANGE [(_0, num_bits: 32)] [ ] +1 -> BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })] outputs=[Simple(Witness(1))] + 1.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 1.1 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 1.2 | Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 1.3 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 1.4 | Call { location: 7 } + ... + 1.43 | Return +2 EXPR [ (1, _1) -2 ] +``` + +### Breakpoints + +#### `break [Opcode]` (or shorthand `b [Opcode]`) + +Sets a breakpoint on the specified opcode index. To get a list of the program opcode numbers, see [the `opcode` command](#opcodes-o). For example: + +``` +0 BLACKBOX::RANGE [(_0, num_bits: 32)] [ ] +1 -> BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })] outputs=[Simple(Witness(1))] + 1.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 1.1 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 1.2 | Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 1.3 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 1.4 | Call { location: 7 } + ... + 1.43 | Return +2 EXPR [ (1, _1) -2 ] +``` + +In this example, issuing a `break 1.2` command adds break on opcode 1.2, as denoted by the `*` character: + +``` +0 BLACKBOX::RANGE [(_0, num_bits: 32)] [ ] +1 -> BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })] outputs=[Simple(Witness(1))] + 1.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 1.1 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 1.2 | * Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 1.3 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 1.4 | Call { location: 7 } + ... + 1.43 | Return +2 EXPR [ (1, _1) -2 ] +``` + +Running [the `continue` command](#continue-c) at this point would cause the debugger to execute the program until opcode 1.2. + +#### `delete [Opcode]` (or shorthand `d [Opcode]`) + +Deletes a breakpoint at an opcode location. Usage is analogous to [the `break` command](#). + +### Variable inspection + +#### vars + +Show variable values available at this point in execution. + +:::note +The ability to inspect variable values from the debugger depends on compilation to be run in a special debug instrumentation mode. This instrumentation weaves variable tracing code with the original source code. + +So variable value inspection comes at the expense of making the resulting ACIR bytecode bigger and harder to understand and optimize. + +If you find this compromise unacceptable, you can run the debugger with the flag `--skip-debug-instrumentation`. This will compile your circuit without any additional debug information, so the resulting ACIR bytecode will be identical to the one produced by standard Noir compilation. However, if you opt for this, the `vars` command will not be available while debugging. +::: + + +### Stacktrace + +#### `stacktrace` + +Displays the current stack trace. + + +### Witness map + +#### `witness` (w) + +Show witness map. For example: + +``` +_0 = 0 +_1 = 2 +_2 = 1 +``` + +#### `witness [Witness Index]` + +Display a single witness from the witness map. For example: + +``` +> witness 1 +_1 = 2 +``` + +#### `witness [Witness Index] [New value]` + +Overwrite the given index with a new value. For example: + +``` +> witness 1 3 +_1 = 3 +``` + + +### Unconstrained VM memory + +#### `memory` + +Show unconstrained VM memory state. For example: + +``` +> memory +At opcode 1.13: Store { destination_pointer: RegisterIndex(0), source: RegisterIndex(3) } +... +> registers +0 = 0 +1 = 10 +2 = 0 +3 = 1 +4 = 1 +5 = 2³² +6 = 1 +> into +At opcode 1.14: Const { destination: RegisterIndex(5), value: Value { inner: 1 } } +... +> memory +0 = 1 +> +``` + +In the example above: we start with clean memory, then step through a `Store` opcode which stores the value of register 3 (1) into the memory address stored in register 0 (0). Thus now `memory` shows memory address 0 contains value 1. + +:::note +This command is only functional while the debugger is executing unconstrained code. +::: + +#### `memset [Memory address] [New value]` + +Update a memory cell with the given value. For example: + +``` +> memory +0 = 1 +> memset 0 2 +> memory +0 = 2 +> memset 1 4 +> memory +0 = 2 +1 = 4 +> +``` + +:::note +This command is only functional while the debugger is executing unconstrained code. +::: \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.30.0/reference/debugger/debugger_vscode.md b/docs/versioned_docs/version-v0.30.0/reference/debugger/debugger_vscode.md new file mode 100644 index 00000000000..c027332b3b0 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/debugger/debugger_vscode.md @@ -0,0 +1,82 @@ +--- +title: VS Code Debugger +description: + VS Code Debugger configuration and features. +keywords: + [ + Nargo, + Noir CLI, + Noir Debugger, + VS Code, + IDE, + ] +sidebar_position: 0 +--- + +# VS Code Noir Debugger Reference + +The Noir debugger enabled by the vscode-noir extension ships with default settings such that the most common scenario should run without any additional configuration steps. + +These defaults can nevertheless be overridden by defining a launch configuration file. This page provides a reference for the properties you can override via a launch configuration file, as well as documenting the Nargo `dap` command, which is a dependency of the VS Code Noir debugger. + + +## Creating and editing launch configuration files + +To create a launch configuration file from VS Code, open the _debug pane_, and click on _create a launch.json file_. + +![Creating a launch configuration file](@site/static/img/debugger/ref1-create-launch.png) + +A `launch.json` file will be created, populated with basic defaults. + +### Noir Debugger launch.json properties + +#### projectFolder + +_String, optional._ + +Absolute path to the Nargo project to debug. By default, it is dynamically determined by looking for the nearest `Nargo.toml` file to the active file at the moment of launching the debugger. + +#### proverName + +_String, optional._ + +Name of the prover input to use. Defaults to `Prover`, which looks for a file named `Prover.toml` at the `projectFolder`. + +#### generateAcir + +_Boolean, optional._ + +If true, generate ACIR opcodes instead of unconstrained opcodes which will be closer to release binaries but less convenient for debugging. Defaults to `false`. + +#### skipInstrumentation + +_Boolean, optional._ + +Skips variables debugging instrumentation of code, making debugging less convenient but the resulting binary smaller and closer to production. Defaults to `false`. + +:::note +Skipping instrumentation causes the debugger to be unable to inspect local variables. +::: + +## `nargo dap [OPTIONS]` + +When run without any option flags, it starts the Nargo Debug Adapter Protocol server, which acts as the debugging backend for the VS Code Noir Debugger. + +All option flags are related to preflight checks. The Debug Adapter Protocol specifies how errors are to be informed from a running DAP server, but it doesn't specify mechanisms to communicate server initialization errors between the DAP server and its client IDE. + +Thus `nargo dap` ships with a _preflight check_ mode. If flag `--preflight-check` and the rest of the `--preflight-*` flags are provided, Nargo will run the same initialization routine except it will not start the DAP server. + +`vscode-noir` will then run `nargo dap` in preflight check mode first before a debugging session starts. If the preflight check ends in error, vscode-noir will present stderr and stdout output from this process through its own Output pane in VS Code. This makes it possible for users to diagnose what pieces of configuration might be wrong or missing in case of initialization errors. + +If the preflight check succeeds, `vscode-noir` proceeds to start the DAP server normally but running `nargo dap` without any additional flags. + +### Options + +| Option | Description | +| --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | +| `--preflight-check` | If present, dap runs in preflight check mode. | +| `--preflight-project-folder ` | Absolute path to the project to debug for preflight check. | +| `--preflight-prover-name ` | Name of prover file to use for preflight check | +| `--preflight-generate-acir` | Optional. If present, compile in ACIR mode while running preflight check. | +| `--preflight-skip-instrumentation` | Optional. If present, compile without introducing debug instrumentation while running preflight check. | +| `-h, --help` | Print help. | diff --git a/docs/versioned_docs/version-v0.30.0/reference/nargo_commands.md b/docs/versioned_docs/version-v0.30.0/reference/nargo_commands.md new file mode 100644 index 00000000000..519e3dbddc2 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/reference/nargo_commands.md @@ -0,0 +1,397 @@ +--- +title: Nargo +description: + Noir CLI Commands for Noir Prover and Verifier to create, execute, prove and verify programs, + generate Solidity verifier smart contract and compile into JSON file containing ACIR + representation and ABI of circuit. +keywords: + [ + Nargo, + Noir CLI, + Noir Prover, + Noir Verifier, + generate Solidity verifier, + compile JSON file, + ACIR representation, + ABI of circuit, + TypeScript, + ] +sidebar_position: 0 +--- + +# Command-Line Help for `nargo` + +This document contains the help content for the `nargo` command-line program. + +**Command Overview:** + +* [`nargo`↴](#nargo) +* [`nargo backend`↴](#nargo-backend) +* [`nargo backend current`↴](#nargo-backend-current) +* [`nargo backend ls`↴](#nargo-backend-ls) +* [`nargo backend use`↴](#nargo-backend-use) +* [`nargo backend install`↴](#nargo-backend-install) +* [`nargo backend uninstall`↴](#nargo-backend-uninstall) +* [`nargo check`↴](#nargo-check) +* [`nargo fmt`↴](#nargo-fmt) +* [`nargo codegen-verifier`↴](#nargo-codegen-verifier) +* [`nargo compile`↴](#nargo-compile) +* [`nargo new`↴](#nargo-new) +* [`nargo init`↴](#nargo-init) +* [`nargo execute`↴](#nargo-execute) +* [`nargo prove`↴](#nargo-prove) +* [`nargo verify`↴](#nargo-verify) +* [`nargo test`↴](#nargo-test) +* [`nargo info`↴](#nargo-info) +* [`nargo lsp`↴](#nargo-lsp) + +## `nargo` + +Noir's package manager + +**Usage:** `nargo ` + +###### **Subcommands:** + +* `backend` — Install and select custom backends used to generate and verify proofs +* `check` — Checks the constraint system for errors +* `fmt` — Format the Noir files in a workspace +* `codegen-verifier` — Generates a Solidity verifier smart contract for the program +* `compile` — Compile the program and its secret execution trace into ACIR format +* `new` — Create a Noir project in a new directory +* `init` — Create a Noir project in the current directory +* `execute` — Executes a circuit to calculate its return value +* `prove` — Create proof for this program. The proof is returned as a hex encoded string +* `verify` — Given a proof and a program, verify whether the proof is valid +* `test` — Run the tests for this program +* `info` — Provides detailed information on each of a program's function (represented by a single circuit) +* `lsp` — Starts the Noir LSP server + +###### **Options:** + + + + +## `nargo backend` + +Install and select custom backends used to generate and verify proofs + +**Usage:** `nargo backend ` + +###### **Subcommands:** + +* `current` — Prints the name of the currently active backend +* `ls` — Prints the list of currently installed backends +* `use` — Select the backend to use +* `install` — Install a new backend from a URL +* `uninstall` — Uninstalls a backend + + + +## `nargo backend current` + +Prints the name of the currently active backend + +**Usage:** `nargo backend current` + + + +## `nargo backend ls` + +Prints the list of currently installed backends + +**Usage:** `nargo backend ls` + + + +## `nargo backend use` + +Select the backend to use + +**Usage:** `nargo backend use ` + +###### **Arguments:** + +* `` + + + +## `nargo backend install` + +Install a new backend from a URL + +**Usage:** `nargo backend install ` + +###### **Arguments:** + +* `` — The name of the backend to install +* `` — The URL from which to download the backend + + + +## `nargo backend uninstall` + +Uninstalls a backend + +**Usage:** `nargo backend uninstall ` + +###### **Arguments:** + +* `` — The name of the backend to uninstall + + + +## `nargo check` + +Checks the constraint system for errors + +**Usage:** `nargo check [OPTIONS]` + +###### **Options:** + +* `--package ` — The name of the package to check +* `--workspace` — Check all packages in the workspace +* `--overwrite` — Force overwrite of existing files +* `--expression-width ` — Override the expression width requested by the backend + + Default value: `4` +* `--force` — Force a full recompilation +* `--print-acir` — Display the ACIR for compiled circuit +* `--deny-warnings` — Treat all warnings as errors +* `--silence-warnings` — Suppress warnings + + + +## `nargo fmt` + +Format the Noir files in a workspace + +**Usage:** `nargo fmt [OPTIONS]` + +###### **Options:** + +* `--check` — Run noirfmt in check mode + + + +## `nargo codegen-verifier` + +Generates a Solidity verifier smart contract for the program + +**Usage:** `nargo codegen-verifier [OPTIONS]` + +###### **Options:** + +* `--package ` — The name of the package to codegen +* `--workspace` — Codegen all packages in the workspace +* `--expression-width ` — Override the expression width requested by the backend + + Default value: `4` +* `--force` — Force a full recompilation +* `--print-acir` — Display the ACIR for compiled circuit +* `--deny-warnings` — Treat all warnings as errors +* `--silence-warnings` — Suppress warnings + + + +## `nargo compile` + +Compile the program and its secret execution trace into ACIR format + +**Usage:** `nargo compile [OPTIONS]` + +###### **Options:** + +* `--package ` — The name of the package to compile +* `--workspace` — Compile all packages in the workspace +* `--expression-width ` — Override the expression width requested by the backend + + Default value: `4` +* `--force` — Force a full recompilation +* `--print-acir` — Display the ACIR for compiled circuit +* `--deny-warnings` — Treat all warnings as errors +* `--silence-warnings` — Suppress warnings + + + +## `nargo new` + +Create a Noir project in a new directory + +**Usage:** `nargo new [OPTIONS] ` + +###### **Arguments:** + +* `` — The path to save the new project + +###### **Options:** + +* `--name ` — Name of the package [default: package directory name] +* `--lib` — Use a library template +* `--bin` — Use a binary template [default] +* `--contract` — Use a contract template + + + +## `nargo init` + +Create a Noir project in the current directory + +**Usage:** `nargo init [OPTIONS]` + +###### **Options:** + +* `--name ` — Name of the package [default: current directory name] +* `--lib` — Use a library template +* `--bin` — Use a binary template [default] +* `--contract` — Use a contract template + + + +## `nargo execute` + +Executes a circuit to calculate its return value + +**Usage:** `nargo execute [OPTIONS] [WITNESS_NAME]` + +###### **Arguments:** + +* `` — Write the execution witness to named file + +###### **Options:** + +* `-p`, `--prover-name ` — The name of the toml file which contains the inputs for the prover + + Default value: `Prover` +* `--package ` — The name of the package to execute +* `--workspace` — Execute all packages in the workspace +* `--expression-width ` — Override the expression width requested by the backend + + Default value: `4` +* `--force` — Force a full recompilation +* `--print-acir` — Display the ACIR for compiled circuit +* `--deny-warnings` — Treat all warnings as errors +* `--silence-warnings` — Suppress warnings +* `--oracle-resolver ` — JSON RPC url to solve oracle calls + + + +## `nargo prove` + +Create proof for this program. The proof is returned as a hex encoded string + +**Usage:** `nargo prove [OPTIONS]` + +###### **Options:** + +* `-p`, `--prover-name ` — The name of the toml file which contains the inputs for the prover + + Default value: `Prover` +* `-v`, `--verifier-name ` — The name of the toml file which contains the inputs for the verifier + + Default value: `Verifier` +* `--verify` — Verify proof after proving +* `--package ` — The name of the package to prove +* `--workspace` — Prove all packages in the workspace +* `--expression-width ` — Override the expression width requested by the backend + + Default value: `4` +* `--force` — Force a full recompilation +* `--print-acir` — Display the ACIR for compiled circuit +* `--deny-warnings` — Treat all warnings as errors +* `--silence-warnings` — Suppress warnings +* `--oracle-resolver ` — JSON RPC url to solve oracle calls + + + +## `nargo verify` + +Given a proof and a program, verify whether the proof is valid + +**Usage:** `nargo verify [OPTIONS]` + +###### **Options:** + +* `-v`, `--verifier-name ` — The name of the toml file which contains the inputs for the verifier + + Default value: `Verifier` +* `--package ` — The name of the package verify +* `--workspace` — Verify all packages in the workspace +* `--expression-width ` — Override the expression width requested by the backend + + Default value: `4` +* `--force` — Force a full recompilation +* `--print-acir` — Display the ACIR for compiled circuit +* `--deny-warnings` — Treat all warnings as errors +* `--silence-warnings` — Suppress warnings + + + +## `nargo test` + +Run the tests for this program + +**Usage:** `nargo test [OPTIONS] [TEST_NAME]` + +###### **Arguments:** + +* `` — If given, only tests with names containing this string will be run + +###### **Options:** + +* `--show-output` — Display output of `println` statements +* `--exact` — Only run tests that match exactly +* `--package ` — The name of the package to test +* `--workspace` — Test all packages in the workspace +* `--expression-width ` — Override the expression width requested by the backend + + Default value: `4` +* `--force` — Force a full recompilation +* `--print-acir` — Display the ACIR for compiled circuit +* `--deny-warnings` — Treat all warnings as errors +* `--silence-warnings` — Suppress warnings +* `--oracle-resolver ` — JSON RPC url to solve oracle calls + + + +## `nargo info` + +Provides detailed information on each of a program's function (represented by a single circuit) + +Current information provided per circuit: 1. The number of ACIR opcodes 2. Counts the final number gates in the circuit used by a backend + +**Usage:** `nargo info [OPTIONS]` + +###### **Options:** + +* `--package ` — The name of the package to detail +* `--workspace` — Detail all packages in the workspace +* `--expression-width ` — Override the expression width requested by the backend + + Default value: `4` +* `--force` — Force a full recompilation +* `--print-acir` — Display the ACIR for compiled circuit +* `--deny-warnings` — Treat all warnings as errors +* `--silence-warnings` — Suppress warnings + + + +## `nargo lsp` + +Starts the Noir LSP server + +Starts an LSP server which allows IDEs such as VS Code to display diagnostics in Noir source. + +VS Code Noir Language Support: https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir + +**Usage:** `nargo lsp` + + + +
+ + + This document was generated automatically by + clap-markdown. + + diff --git a/docs/versioned_docs/version-v0.30.0/tooling/debugger.md b/docs/versioned_docs/version-v0.30.0/tooling/debugger.md new file mode 100644 index 00000000000..184c436068f --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/tooling/debugger.md @@ -0,0 +1,27 @@ +--- +title: Debugger +description: Learn about the Noir Debugger, in its REPL or VS Code versions. +keywords: [Nargo, VSCode, Visual Studio Code, REPL, Debugger] +sidebar_position: 2 +--- + +# Noir Debugger + +There are currently two ways of debugging Noir programs: + +1. From VS Code, via the [vscode-noir](https://github.com/noir-lang/vscode-noir) extension. You can install it via the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir). +2. Via the REPL debugger, which ships with Nargo. + +In order to use either version of the debugger, you will need to install recent enough versions of Noir, [Nargo](../getting_started/installation) and vscode-noir: + +- Noir 0.xx +- Nargo 0.xx +- vscode-noir 0.xx + +:::info +At the moment, the debugger supports debugging binary projects, but not contracts. +::: + +We cover the VS Code Noir debugger more in depth in [its VS Code debugger how-to guide](../how_to/debugger/debugging_with_vs_code.md) and [the reference](../reference/debugger/debugger_vscode.md). + +The REPL debugger is discussed at length in [the REPL debugger how-to guide](../how_to/debugger/debugging_with_the_repl.md) and [the reference](../reference/debugger/debugger_repl.md). diff --git a/docs/versioned_docs/version-v0.30.0/tooling/language_server.md b/docs/versioned_docs/version-v0.30.0/tooling/language_server.md new file mode 100644 index 00000000000..81e0356ef8a --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/tooling/language_server.md @@ -0,0 +1,43 @@ +--- +title: Language Server +description: Learn about the Noir Language Server, how to install the components, and configuration that may be required. +keywords: [Nargo, Language Server, LSP, VSCode, Visual Studio Code] +sidebar_position: 0 +--- + +This section helps you install and configure the Noir Language Server. + +The Language Server Protocol (LSP) has two components, the [Server](#language-server) and the [Client](#language-client). Below we describe each in the context of Noir. + +## Language Server + +The Server component is provided by the Nargo command line tool that you installed at the beginning of this guide. +As long as Nargo is installed and you've used it to run other commands in this guide, it should be good to go! + +If you'd like to verify that the `nargo lsp` command is available, you can run `nargo --help` and look for `lsp` in the list of commands. If you see it, you're using a version of Noir with LSP support. + +## Language Client + +The Client component is usually an editor plugin that launches the Server. It communicates LSP messages between the editor and the Server. For example, when you save a file, the Client will alert the Server, so it can try to compile the project and report any errors. + +Currently, Noir provides a Language Client for Visual Studio Code via the [vscode-noir](https://github.com/noir-lang/vscode-noir) extension. You can install it via the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir). + +> **Note:** Noir's Language Server Protocol support currently assumes users' VSCode workspace root to be the same as users' Noir project root (i.e. where Nargo.toml lies). +> +> If LSP features seem to be missing / malfunctioning, make sure you are opening your Noir project directly (instead of as a sub-folder) in your VSCode instance. + +When your language server is running correctly and the VSCode plugin is installed, you should see handy codelens buttons for compilation, measuring circuit size, execution, and tests: + +![Compile and Execute](@site/static/img/codelens_compile_execute.png) +![Run test](@site/static/img/codelens_run_test.png) + +You should also see your tests in the `testing` panel: + +![Testing panel](@site/static/img/codelens_testing_panel.png) + +### Configuration + +- **Noir: Enable LSP** - If checked, the extension will launch the Language Server via `nargo lsp` and communicate with it. +- **Noir: Nargo Flags** - Additional flags may be specified if you require them to be added when the extension calls `nargo lsp`. +- **Noir: Nargo Path** - An absolute path to a Nargo binary with the `lsp` command. This may be useful if Nargo is not within the `PATH` of your editor. +- **Noir > Trace: Server** - Setting this to `"messages"` or `"verbose"` will log LSP messages between the Client and Server. Useful for debugging. diff --git a/docs/versioned_docs/version-v0.30.0/tooling/testing.md b/docs/versioned_docs/version-v0.30.0/tooling/testing.md new file mode 100644 index 00000000000..d3e0c522473 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/tooling/testing.md @@ -0,0 +1,62 @@ +--- +title: Testing in Noir +description: Learn how to use Nargo to test your Noir program in a quick and easy way +keywords: [Nargo, testing, Noir, compile, test] +sidebar_position: 1 +--- + +You can test your Noir programs using Noir circuits. + +Nargo will automatically compile and run any functions which have the decorator `#[test]` on them if +you run `nargo test`. + +For example if you have a program like: + +```rust +fn add(x: u64, y: u64) -> u64 { + x + y +} +#[test] +fn test_add() { + assert(add(2,2) == 4); + assert(add(0,1) == 1); + assert(add(1,0) == 1); +} +``` + +Running `nargo test` will test that the `test_add` function can be executed while satisfying all +the constraints which allows you to test that add returns the expected values. Test functions can't +have any arguments currently. + +### Test fail + +You can write tests that are expected to fail by using the decorator `#[test(should_fail)]`. For example: + +```rust +fn add(x: u64, y: u64) -> u64 { + x + y +} +#[test(should_fail)] +fn test_add() { + assert(add(2,2) == 5); +} +``` + +You can be more specific and make it fail with a specific reason by using `should_fail_with = "`: + +```rust +fn main(african_swallow_avg_speed : Field) { + assert(african_swallow_avg_speed == 65, "What is the airspeed velocity of an unladen swallow"); +} + +#[test] +fn test_king_arthur() { + main(65); +} + +#[test(should_fail_with = "What is the airspeed velocity of an unladen swallow")] +fn test_bridgekeeper() { + main(32); +} + +``` diff --git a/docs/versioned_docs/version-v0.30.0/tutorials/noirjs_app.md b/docs/versioned_docs/version-v0.30.0/tutorials/noirjs_app.md new file mode 100644 index 00000000000..3dd9fe7d2b0 --- /dev/null +++ b/docs/versioned_docs/version-v0.30.0/tutorials/noirjs_app.md @@ -0,0 +1,326 @@ +--- +title: Building a web app with NoirJS +description: Learn how to setup a new app that uses Noir to generate and verify zero-knowledge SNARK proofs in a typescript or javascript environment. +keywords: [how to, guide, javascript, typescript, noir, barretenberg, zero-knowledge, proofs, app] +sidebar_position: 0 +pagination_next: noir/concepts/data_types/index +--- + +NoirJS is a set of packages meant to work both in a browser and a server environment. In this tutorial, we will build a simple web app using them. From here, you should get an idea on how to proceed with your own Noir projects! + +You can find the complete app code for this guide [here](https://github.com/noir-lang/tiny-noirjs-app). + +## Setup + +:::note + +Feel free to use whatever versions, just keep in mind that Nargo and the NoirJS packages are meant to be in sync. For example, Nargo 0.27.x matches `noir_js@0.27.x`, etc. + +In this guide, we will be pinned to 0.27.0. + +::: + +Before we start, we want to make sure we have Node and Nargo installed. + +We start by opening a terminal and executing `node --version`. If we don't get an output like `v20.10.0`, that means node is not installed. Let's do that by following the handy [nvm guide](https://github.com/nvm-sh/nvm?tab=readme-ov-file#install--update-script). + +As for `Nargo`, we can follow the [Nargo guide](../getting_started/installation/index.md) to install it. If you're lazy, just paste this on a terminal and run `noirup`: + +```sh +curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash +``` + +Easy enough. Onwards! + +## Our project + +ZK is a powerful technology. An app that doesn't reveal one of the inputs to _anyone_ is almost unbelievable, yet Noir makes it as easy as a single line of code. + +In fact, it's so simple that it comes nicely packaged in `nargo`. Let's do that! + +### Nargo + +Run: + +`nargo new circuit` + +And... That's about it. Your program is ready to be compiled and run. + +To compile, let's `cd` into the `circuit` folder to enter our project, and call: + +`nargo compile` + +This compiles our circuit into `json` format and add it to a new `target` folder. + +:::info + +At this point in the tutorial, your folder structure should look like this: + +```tree +. +└── circuit <---- our working directory + ├── Nargo.toml + ├── src + │ └── main.nr + └── target + └── circuit.json +``` + +::: + +### Node and Vite + +If you want to explore Nargo, feel free to go on a side-quest now and follow the steps in the +[getting started](../getting_started/hello_noir/index.md) guide. However, we want our app to run on the browser, so we need Vite. + +Vite is a powerful tool to generate static websites. While it provides all kinds of features, let's just go barebones with some good old vanilla JS. + +To do this this, go back to the previous folder (`cd ..`) and create a new vite project by running `npm create vite` and choosing "Vanilla" and "Javascript". + +A wild `vite-project` directory should now appear in your root folder! Let's not waste any time and dive right in: + +```bash +cd vite-project +``` + +### Setting Up Vite and Configuring the Project + +Before we proceed with any coding, let's get our environment tailored for Noir. We'll start by laying down the foundations with a `vite.config.js` file. This little piece of configuration is our secret sauce for making sure everything meshes well with the NoirJS libraries and other special setups we might need, like handling WebAssembly modules. Here’s how you get that going: + +#### Creating the vite.config.js + +In your freshly minted `vite-project` folder, create a new file named `vite.config.js` and open it in your code editor. Paste the following to set the stage: + +```javascript +import { defineConfig } from "vite"; +import copy from "rollup-plugin-copy"; + +export default defineConfig({ + esbuild: { + target: "esnext", + }, + optimizeDeps: { + esbuildOptions: { + target: "esnext", + }, + }, + plugins: [ + copy({ + targets: [ + { src: "node_modules/**/*.wasm", dest: "node_modules/.vite/dist" }, + ], + copySync: true, + hook: "buildStart", + }), + ], + server: { + port: 3000, + }, +}); +``` + +#### Install Dependencies + +Now that our stage is set, install the necessary NoirJS packages along with our other dependencies: + +```bash +npm install && npm install @noir-lang/backend_barretenberg@0.27.0 @noir-lang/noir_js@0.27.0 +npm install rollup-plugin-copy --save-dev +``` + +:::info + +At this point in the tutorial, your folder structure should look like this: + +```tree +. +└── circuit + └── ...etc... +└── vite-project <---- our working directory + └── ...etc... +``` + +::: + +#### Some cleanup + +`npx create vite` is amazing but it creates a bunch of files we don't really need for our simple example. Actually, let's just delete everything except for `vite.config.js`, `index.html`, `main.js` and `package.json`. I feel lighter already. + +![my heart is ready for you, noir.js](@site/static/img/memes/titanic.jpeg) + +## HTML + +Our app won't run like this, of course. We need some working HTML, at least. Let's open our broken-hearted `index.html` and replace everything with this code snippet: + +```html + + + + + + +

Noir app

+
+ + +
+
+

Logs

+

Proof

+
+ + +``` + +It _could_ be a beautiful UI... Depending on which universe you live in. + +## Some good old vanilla Javascript + +Our love for Noir needs undivided attention, so let's just open `main.js` and delete everything (this is where the romantic scenery becomes a bit creepy). + +Start by pasting in this boilerplate code: + +```js +const setup = async () => { + await Promise.all([ + import('@noir-lang/noirc_abi').then((module) => + module.default(new URL('@noir-lang/noirc_abi/web/noirc_abi_wasm_bg.wasm', import.meta.url).toString()), + ), + import('@noir-lang/acvm_js').then((module) => + module.default(new URL('@noir-lang/acvm_js/web/acvm_js_bg.wasm', import.meta.url).toString()), + ), + ]); +}; + +function display(container, msg) { + const c = document.getElementById(container); + const p = document.createElement('p'); + p.textContent = msg; + c.appendChild(p); +} + +document.getElementById('submitGuess').addEventListener('click', async () => { + try { + // here's where love happens + } catch (err) { + display('logs', 'Oh 💔 Wrong guess'); + } +}); +``` + +The display function doesn't do much. We're simply manipulating our website to see stuff happening. For example, if the proof fails, it will simply log a broken heart 😢 + +As for the `setup` function, it's just a sad reminder that dealing with `wasm` on the browser is not as easy as it should. Just copy, paste, and forget. + +:::info + +At this point in the tutorial, your folder structure should look like this: + +```tree +. +└── circuit + └── ...same as above +└── vite-project + ├── vite.config.js + ├── main.js + ├── package.json + └── index.html +``` + +You'll see other files and folders showing up (like `package-lock.json`, `node_modules`) but you shouldn't have to care about those. + +::: + +## Some NoirJS + +We're starting with the good stuff now. If you've compiled the circuit as described above, you should have a `json` file we want to import at the very top of our `main.js` file: + +```ts +import circuit from '../circuit/target/circuit.json'; +``` + +[Noir is backend-agnostic](../index.mdx#whats-new-about-noir). We write Noir, but we also need a proving backend. That's why we need to import and instantiate the two dependencies we installed above: `BarretenbergBackend` and `Noir`. Let's import them right below: + +```js +import { BarretenbergBackend, BarretenbergVerifier as Verifier } from '@noir-lang/backend_barretenberg'; +import { Noir } from '@noir-lang/noir_js'; +``` + +And instantiate them inside our try-catch block: + +```ts +// try { +const backend = new BarretenbergBackend(circuit); +const noir = new Noir(circuit, backend); +// } +``` + +:::note + +For the remainder of the tutorial, everything will be happening inside the `try` block + +::: + +## Our app + +Now for the app itself. We're capturing whatever is in the input when people press the submit button. Just add this: + +```js +const x = parseInt(document.getElementById('guessInput').value); +const input = { x, y: 2 }; +``` + +Now we're ready to prove stuff! Let's feed some inputs to our circuit and calculate the proof: + +```js +await setup(); // let's squeeze our wasm inits here + +display('logs', 'Generating proof... ⌛'); +const proof = await noir.generateProof(input); +display('logs', 'Generating proof... ✅'); +display('results', proof.proof); +``` + +You're probably eager to see stuff happening, so go and run your app now! + +From your terminal, run `npm run dev`. If it doesn't open a browser for you, just visit `localhost:5173`. You should now see the worst UI ever, with an ugly input. + +![Getting Started 0](@site/static/img/noir_getting_started_1.png) + +Now, our circuit says `fn main(x: Field, y: pub Field)`. This means only the `y` value is public, and it's hardcoded above: `input = { x, y: 2 }`. In other words, you won't need to send your secret`x` to the verifier! + +By inputting any number other than 2 in the input box and clicking "submit", you should get a valid proof. Otherwise the proof won't even generate correctly. By the way, if you're human, you shouldn't be able to understand anything on the "proof" box. That's OK. We like you, human ❤️. + +## Verifying + +Time to celebrate, yes! But we shouldn't trust machines so blindly. Let's add these lines to see our proof being verified: + +```js +display('logs', 'Verifying proof... ⌛'); +const verificationKey = await backend.getVerificationKey(); +const verifier = new Verifier(); +const isValid = await verifier.verifyProof(proof, verificationKey); +if (isValid) display('logs', 'Verifying proof... ✅'); +``` + +You have successfully generated a client-side Noir web app! + +![coded app without math knowledge](@site/static/img/memes/flextape.jpeg) + +## Further Reading + +You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. + +You should also check out the more advanced examples in the [noir-examples repo](https://github.com/noir-lang/noir-examples), where you'll find reference usage for some cool apps. diff --git a/docs/versioned_sidebars/version-v0.30.0-sidebars.json b/docs/versioned_sidebars/version-v0.30.0-sidebars.json new file mode 100644 index 00000000000..b9ad026f69f --- /dev/null +++ b/docs/versioned_sidebars/version-v0.30.0-sidebars.json @@ -0,0 +1,93 @@ +{ + "sidebar": [ + { + "type": "doc", + "id": "index" + }, + { + "type": "category", + "label": "Getting Started", + "items": [ + { + "type": "autogenerated", + "dirName": "getting_started" + } + ] + }, + { + "type": "category", + "label": "The Noir Language", + "items": [ + { + "type": "autogenerated", + "dirName": "noir" + } + ] + }, + { + "type": "html", + "value": "
", + "defaultStyle": true + }, + { + "type": "category", + "label": "How To Guides", + "items": [ + { + "type": "autogenerated", + "dirName": "how_to" + } + ] + }, + { + "type": "category", + "label": "Explainers", + "items": [ + { + "type": "autogenerated", + "dirName": "explainers" + } + ] + }, + { + "type": "category", + "label": "Tutorials", + "items": [ + { + "type": "autogenerated", + "dirName": "tutorials" + } + ] + }, + { + "type": "category", + "label": "Reference", + "items": [ + { + "type": "autogenerated", + "dirName": "reference" + } + ] + }, + { + "type": "category", + "label": "Tooling", + "items": [ + { + "type": "autogenerated", + "dirName": "tooling" + } + ] + }, + { + "type": "html", + "value": "
", + "defaultStyle": true + }, + { + "type": "doc", + "id": "migration_notes", + "label": "Migration notes" + } + ] +} diff --git a/tooling/noir_codegen/package.json b/tooling/noir_codegen/package.json index fa3df8ce101..5d3a7d6315e 100644 --- a/tooling/noir_codegen/package.json +++ b/tooling/noir_codegen/package.json @@ -3,7 +3,7 @@ "contributors": [ "The Noir Team " ], - "version": "0.29.0", + "version": "0.30.0", "packageManager": "yarn@3.5.1", "license": "(MIT OR Apache-2.0)", "type": "module", diff --git a/tooling/noir_js/package.json b/tooling/noir_js/package.json index 325ba0fb9a7..eca3f29957f 100644 --- a/tooling/noir_js/package.json +++ b/tooling/noir_js/package.json @@ -3,7 +3,7 @@ "contributors": [ "The Noir Team " ], - "version": "0.29.0", + "version": "0.30.0", "packageManager": "yarn@3.5.1", "license": "(MIT OR Apache-2.0)", "type": "module", diff --git a/tooling/noir_js_backend_barretenberg/package.json b/tooling/noir_js_backend_barretenberg/package.json index 3368dcd8a09..6adf8749aba 100644 --- a/tooling/noir_js_backend_barretenberg/package.json +++ b/tooling/noir_js_backend_barretenberg/package.json @@ -3,7 +3,7 @@ "contributors": [ "The Noir Team " ], - "version": "0.29.0", + "version": "0.30.0", "packageManager": "yarn@3.5.1", "license": "(MIT OR Apache-2.0)", "type": "module", diff --git a/tooling/noir_js_types/package.json b/tooling/noir_js_types/package.json index 5332ce20cc7..b2b84b640a5 100644 --- a/tooling/noir_js_types/package.json +++ b/tooling/noir_js_types/package.json @@ -4,7 +4,7 @@ "The Noir Team " ], "packageManager": "yarn@3.5.1", - "version": "0.29.0", + "version": "0.30.0", "license": "(MIT OR Apache-2.0)", "homepage": "https://noir-lang.org/", "repository": { diff --git a/tooling/noirc_abi_wasm/package.json b/tooling/noirc_abi_wasm/package.json index ac7d1606298..399a333f157 100644 --- a/tooling/noirc_abi_wasm/package.json +++ b/tooling/noirc_abi_wasm/package.json @@ -3,7 +3,7 @@ "contributors": [ "The Noir Team " ], - "version": "0.29.0", + "version": "0.30.0", "license": "(MIT OR Apache-2.0)", "homepage": "https://noir-lang.org/", "repository": { From fab1c3567d731ea7902635a7a020a8d14f94fd27 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 21 May 2024 16:34:09 +0100 Subject: [PATCH 09/61] feat: add native rust implementation of schnorr signature verification (#5053) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description ## Problem\* Resolves ## Summary\* This PR replaces the final wasm calls to barretenberg with a native implementation of schnorr signature verification. This allows us to remove the entire `acvm_backend.wasm`. This schnorr implementation is something this I've slapped together in an afternoon so be warned of potential bugs, there doesn't seem to be any off-the-shelf rust implementations of schnorr using grumpkin however. Now we don't need to do wasm initialisation for acvm_js, we can stop caching a solver object to pass into acvm_js, I've maintained the interface for now however but the external solver is ignored. Benchmarks relative to https://github.com/noir-lang/noir/pull/5056 ``` schnorr_verify time: [526.91 µs 527.81 µs 528.91 µs] change: [-67.185% -67.081% -66.993%] (p = 0.00 < 0.05) Performance has improved. ``` ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Maxim Vezenov --- Cargo.lock | 794 ++---------------- acvm-repo/acvm_js/Cargo.toml | 4 + acvm-repo/acvm_js/src/lib.rs | 3 + acvm-repo/bn254_blackbox_solver/Cargo.toml | 15 - acvm-repo/bn254_blackbox_solver/src/lib.rs | 40 +- .../bn254_blackbox_solver/src/schnorr/mod.rs | 146 ++++ .../src/wasm/acvm_backend.wasm | Bin 756082 -> 0 bytes .../bn254_blackbox_solver/src/wasm/mod.rs | 332 -------- .../bn254_blackbox_solver/src/wasm/schnorr.rs | 104 --- 9 files changed, 236 insertions(+), 1202 deletions(-) create mode 100644 acvm-repo/bn254_blackbox_solver/src/schnorr/mod.rs delete mode 100755 acvm-repo/bn254_blackbox_solver/src/wasm/acvm_backend.wasm delete mode 100644 acvm-repo/bn254_blackbox_solver/src/wasm/mod.rs delete mode 100644 acvm-repo/bn254_blackbox_solver/src/wasm/schnorr.rs diff --git a/Cargo.lock b/Cargo.lock index be7f781f96d..b5dc6f9bfdf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -100,6 +100,7 @@ dependencies = [ "build-data", "console_error_panic_hook", "const-str", + "getrandom 0.2.15", "gloo-utils", "js-sys", "pkg-config", @@ -117,7 +118,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" dependencies = [ - "gimli 0.27.3", + "gimli", ] [[package]] @@ -132,7 +133,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.15", "once_cell", "version_check", ] @@ -144,7 +145,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if 1.0.0", - "getrandom 0.2.10", + "getrandom 0.2.15", "once_cell", "version_check", "zerocopy", @@ -563,18 +564,6 @@ dependencies = [ "typenum", ] -[[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 = "blake2" version = "0.10.6" @@ -615,18 +604,12 @@ dependencies = [ "ark-ec", "ark-ff", "ark-std", - "cfg-if 1.0.0", "criterion", - "getrandom 0.2.10", "hex", - "js-sys", "lazy_static", "noir_grumpkin", "num-bigint", "pprof 0.12.1", - "thiserror", - "wasm-bindgen-futures", - "wasmer", ] [[package]] @@ -693,28 +676,6 @@ version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" -[[package]] -name = "bytecheck" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" -dependencies = [ - "bytecheck_derive", - "ptr_meta", - "simdutf8", -] - -[[package]] -name = "bytecheck_derive" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "bytecount" version = "0.6.3" @@ -850,9 +811,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.7" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" dependencies = [ "clap_builder", "clap_derive", @@ -868,9 +829,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.7" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" dependencies = [ "anstream", "anstyle", @@ -887,7 +848,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.64", ] [[package]] @@ -925,7 +886,7 @@ checksum = "fc4159b76af02757139baf42c0c971c6dc155330999fbfd8eddb29b97fb2db68" dependencies = [ "codespan-reporting", "lsp-types 0.88.0", - "url 2.4.0", + "url 2.5.0", ] [[package]] @@ -1059,19 +1020,6 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" -[[package]] -name = "corosensei" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80128832c58ea9cbd041d2a759ec449224487b2c1e400453d99d244eead87a8e" -dependencies = [ - "autocfg", - "cfg-if 1.0.0", - "libc", - "scopeguard", - "windows-sys 0.33.0", -] - [[package]] name = "cpp_demangle" version = "0.4.2" @@ -1090,89 +1038,6 @@ dependencies = [ "libc", ] -[[package]] -name = "cranelift-bforest" -version = "0.91.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" -dependencies = [ - "cranelift-entity", -] - -[[package]] -name = "cranelift-codegen" -version = "0.91.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" -dependencies = [ - "arrayvec", - "bumpalo", - "cranelift-bforest", - "cranelift-codegen-meta", - "cranelift-codegen-shared", - "cranelift-egraph", - "cranelift-entity", - "cranelift-isle", - "gimli 0.26.2", - "log", - "regalloc2", - "smallvec", - "target-lexicon", -] - -[[package]] -name = "cranelift-codegen-meta" -version = "0.91.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" -dependencies = [ - "cranelift-codegen-shared", -] - -[[package]] -name = "cranelift-codegen-shared" -version = "0.91.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" - -[[package]] -name = "cranelift-egraph" -version = "0.91.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" -dependencies = [ - "cranelift-entity", - "fxhash", - "hashbrown 0.12.3", - "indexmap 1.9.3", - "log", - "smallvec", -] - -[[package]] -name = "cranelift-entity" -version = "0.91.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" - -[[package]] -name = "cranelift-frontend" -version = "0.91.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" -dependencies = [ - "cranelift-codegen", - "log", - "smallvec", - "target-lexicon", -] - -[[package]] -name = "cranelift-isle" -version = "0.91.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" - [[package]] name = "crc32fast" version = "1.3.2" @@ -1252,24 +1117,11 @@ dependencies = [ "scopeguard", ] -[[package]] -name = "crossbeam-queue" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" -version = "0.8.17" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crunchy" @@ -1352,7 +1204,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.32", + "syn 2.0.64", ] [[package]] @@ -1363,20 +1215,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.32", -] - -[[package]] -name = "dashmap" -version = "5.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" -dependencies = [ - "cfg-if 1.0.0", - "hashbrown 0.14.0", - "lock_api", - "once_cell", - "parking_lot_core 0.9.8", + "syn 2.0.64", ] [[package]] @@ -1584,47 +1423,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "enum-iterator" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eeac5c5edb79e4e39fe8439ef35207780a11f69c52cbe424ce3dfad4cb78de6" -dependencies = [ - "enum-iterator-derive", -] - -[[package]] -name = "enum-iterator-derive" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "enumset" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e875f1719c16de097dee81ed675e2d9bb63096823ed3f0ca827b7dea3028bbbb" -dependencies = [ - "enumset_derive", -] - -[[package]] -name = "enumset_derive" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.32", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -1661,12 +1459,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "fallible-iterator" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" - [[package]] name = "fastrand" version = "2.0.1" @@ -1779,11 +1571,11 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ - "percent-encoding 2.3.0", + "percent-encoding 2.3.1", ] [[package]] @@ -1795,12 +1587,6 @@ dependencies = [ "libc", ] -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - [[package]] name = "futures" version = "0.1.31" @@ -1864,7 +1650,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.64", ] [[package]] @@ -1930,9 +1716,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -1941,17 +1727,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "gimli" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" -dependencies = [ - "fallible-iterator", - "indexmap 1.9.3", - "stable_deref_trait", -] - [[package]] name = "gimli" version = "0.27.3" @@ -2024,7 +1799,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.0.0", + "indexmap 2.2.6", "slab", "tokio", "tokio-util 0.7.10", @@ -2051,9 +1826,6 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash 0.7.8", -] [[package]] name = "hashbrown" @@ -2066,9 +1838,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" @@ -2226,9 +1998,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -2309,12 +2081,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.5", "serde", ] @@ -2611,12 +2383,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "leb128" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" - [[package]] name = "libaes" version = "0.7.0" @@ -2625,9 +2391,9 @@ checksum = "82903360c009b816f5ab72a9b68158c27c301ee2c3f20655b55c5e589e7d3bb7" [[package]] name = "libc" -version = "0.2.151" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libm" @@ -2687,7 +2453,7 @@ dependencies = [ "serde", "serde_json", "serde_repr", - "url 2.4.0", + "url 2.5.0", ] [[package]] @@ -2700,16 +2466,7 @@ dependencies = [ "serde", "serde_json", "serde_repr", - "url 2.4.0", -] - -[[package]] -name = "mach" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" -dependencies = [ - "libc", + "url 2.5.0", ] [[package]] @@ -2742,15 +2499,6 @@ dependencies = [ "libc", ] -[[package]] -name = "memmap2" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d28bba84adfe6646737845bc5ebbfa2c08424eb1c37e94a1fd2a82adb56a872" -dependencies = [ - "libc", -] - [[package]] name = "memoffset" version = "0.6.5" @@ -2807,12 +2555,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "more-asserts" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" - [[package]] name = "nargo" version = "0.30.0" @@ -2917,7 +2659,7 @@ dependencies = [ "serde", "thiserror", "toml 0.7.6", - "url 2.4.0", + "url 2.5.0", ] [[package]] @@ -3053,7 +2795,7 @@ dependencies = [ "build-data", "console_error_panic_hook", "fm", - "getrandom 0.2.10", + "getrandom 0.2.15", "gloo-utils", "js-sys", "nargo", @@ -3093,7 +2835,7 @@ dependencies = [ "acvm", "build-data", "console_error_panic_hook", - "getrandom 0.2.10", + "getrandom 0.2.15", "gloo-utils", "iter-extended", "js-sys", @@ -3417,9 +3159,9 @@ checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "petgraph" @@ -3428,7 +3170,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.0.0", + "indexmap 2.2.6", ] [[package]] @@ -3658,30 +3400,6 @@ dependencies = [ "toml 0.5.11", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro-hack" version = "0.5.20+deprecated" @@ -3690,9 +3408,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -3717,26 +3435,6 @@ dependencies = [ "unarray", ] -[[package]] -name = "ptr_meta" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" -dependencies = [ - "ptr_meta_derive", -] - -[[package]] -name = "ptr_meta_derive" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "quick-error" version = "1.2.3" @@ -3754,19 +3452,13 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.31" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" +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 = "radix_trie" version = "0.2.1" @@ -3836,7 +3528,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.15", ] [[package]] @@ -3925,23 +3617,11 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.15", "redox_syscall 0.2.16", "thiserror", ] -[[package]] -name = "regalloc2" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" -dependencies = [ - "fxhash", - "log", - "slice-group-by", - "smallvec", -] - [[package]] name = "regex" version = "1.10.3" @@ -3998,27 +3678,6 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" -[[package]] -name = "region" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" -dependencies = [ - "bitflags 1.3.2", - "libc", - "mach", - "winapi", -] - -[[package]] -name = "rend" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" -dependencies = [ - "bytecheck", -] - [[package]] name = "reqwest" version = "0.11.20" @@ -4040,7 +3699,7 @@ dependencies = [ "log", "mime", "once_cell", - "percent-encoding 2.3.0", + "percent-encoding 2.3.1", "pin-project-lite", "rustls", "rustls-pemfile", @@ -4050,7 +3709,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "url 2.4.0", + "url 2.5.0", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -4114,42 +3773,13 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if 1.0.0", - "getrandom 0.2.10", + "getrandom 0.2.15", "libc", "spin 0.9.8", "untrusted 0.9.0", "windows-sys 0.52.0", ] -[[package]] -name = "rkyv" -version = "0.7.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" -dependencies = [ - "bitvec", - "bytecheck", - "hashbrown 0.12.3", - "indexmap 1.9.3", - "ptr_meta", - "rend", - "rkyv_derive", - "seahash", - "tinyvec", - "uuid", -] - -[[package]] -name = "rkyv_derive" -version = "0.7.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "rust-embed" version = "6.8.1" @@ -4170,7 +3800,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.32", + "syn 2.0.64", "walkdir", ] @@ -4391,12 +4021,6 @@ dependencies = [ "untrusted 0.7.1", ] -[[package]] -name = "seahash" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" - [[package]] name = "sec1" version = "0.3.0" @@ -4411,12 +4035,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "self_cell" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e388332cd64eb80cd595a00941baf513caffae8dce9cfd0467fc9c66397dade6" - [[package]] name = "semver" version = "1.0.20" @@ -4428,9 +4046,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.179" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a5bf42b8d227d4abf38a1ddb08602e229108a517cd4e5bb28f9c7eaafdce5c0" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" dependencies = [ "serde_derive", ] @@ -4469,26 +4087,15 @@ dependencies = [ "thiserror", ] -[[package]] -name = "serde-wasm-bindgen" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" -dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", -] - [[package]] name = "serde_derive" -version = "1.0.179" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "741e124f5485c7e60c03b043f79f320bff3527f4bbf12cf3831750dc46a0ec2c" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.64", ] [[package]] @@ -4510,7 +4117,7 @@ checksum = "1d89a8107374290037607734c0b73a85db7ed80cae314b3c5791f192a496e731" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.64", ] [[package]] @@ -4544,7 +4151,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.0.0", + "indexmap 2.2.6", "serde", "serde_json", "serde_with_macros", @@ -4560,7 +4167,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.64", ] [[package]] @@ -4593,16 +4200,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "shared-buffer" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6c99835bad52957e7aa241d3975ed17c1e5f8c92026377d117a606f36b84b16" -dependencies = [ - "bytes", - "memmap2 0.6.2", -] - [[package]] name = "shell-words" version = "1.1.0" @@ -4619,12 +4216,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "simdutf8" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" - [[package]] name = "similar" version = "2.3.0" @@ -4670,12 +4261,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "slice-group-by" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" - [[package]] name = "small-ord-set" version = "0.1.3" @@ -4807,7 +4392,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "167a4ffd7c35c143fd1030aa3c2caf76ba42220bd5a6b5f4781896434723b8c3" dependencies = [ "debugid", - "memmap2 0.5.10", + "memmap2", "stable_deref_trait", "uuid", ] @@ -4836,21 +4421,15 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.32" +version = "2.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" +checksum = "7ad3dee41f36859875573074334c200d1add8e4a87bb37113ebd31d926b7b11f" 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 = "tar" version = "0.4.40" @@ -4862,12 +4441,6 @@ dependencies = [ "xattr", ] -[[package]] -name = "target-lexicon" -version = "0.12.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" - [[package]] name = "tempfile" version = "3.8.0" @@ -4970,7 +4543,7 @@ checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.64", ] [[package]] @@ -5070,7 +4643,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.64", ] [[package]] @@ -5159,7 +4732,7 @@ version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", @@ -5221,7 +4794,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.64", ] [[package]] @@ -5392,13 +4965,13 @@ dependencies = [ [[package]] name = "url" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", - "idna 0.4.0", - "percent-encoding 2.3.0", + "idna 0.5.0", + "percent-encoding 2.3.1", "serde", ] @@ -5499,7 +5072,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.64", "wasm-bindgen-shared", ] @@ -5533,7 +5106,7 @@ checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.64", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5568,179 +5141,6 @@ dependencies = [ "quote", ] -[[package]] -name = "wasm-encoder" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba64e81215916eaeb48fee292f29401d69235d62d8b8fd92a7b2844ec5ae5f7" -dependencies = [ - "leb128", -] - -[[package]] -name = "wasmer" -version = "4.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c15724dc25d1ee57962334aea8e41ade2675e5ea2ac6b8d42da6051b0face66" -dependencies = [ - "bytes", - "cfg-if 1.0.0", - "derivative", - "indexmap 1.9.3", - "js-sys", - "more-asserts", - "rustc-demangle", - "serde", - "serde-wasm-bindgen", - "shared-buffer", - "target-lexicon", - "thiserror", - "tracing", - "wasm-bindgen", - "wasmer-compiler", - "wasmer-compiler-cranelift", - "wasmer-derive", - "wasmer-types", - "wasmer-vm", - "wasmparser", - "wat", - "winapi", -] - -[[package]] -name = "wasmer-compiler" -version = "4.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55a7f3b3a96f8d844c25e2c032af9572306dd63fa93dc17bcca4c5458ac569bd" -dependencies = [ - "backtrace", - "bytes", - "cfg-if 1.0.0", - "enum-iterator", - "enumset", - "lazy_static", - "leb128", - "memmap2 0.5.10", - "more-asserts", - "region", - "rkyv", - "self_cell", - "shared-buffer", - "smallvec", - "thiserror", - "wasmer-types", - "wasmer-vm", - "wasmparser", - "winapi", -] - -[[package]] -name = "wasmer-compiler-cranelift" -version = "4.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "102e2c5bacac69495c4025767e2fa26797ffb27f242dccb7cf57d9cefd944386" -dependencies = [ - "cranelift-codegen", - "cranelift-entity", - "cranelift-frontend", - "gimli 0.26.2", - "more-asserts", - "rayon", - "smallvec", - "target-lexicon", - "tracing", - "wasmer-compiler", - "wasmer-types", -] - -[[package]] -name = "wasmer-derive" -version = "4.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea737fa08f95d6abc4459f42a70a9833e8974b814e74971d77ef473814f4d4c" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "wasmer-types" -version = "4.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0689110e291b0f07fc665f2824e5ff81df120848e8a9acfbf1a9bf7990773f9" -dependencies = [ - "bytecheck", - "enum-iterator", - "enumset", - "indexmap 1.9.3", - "more-asserts", - "rkyv", - "target-lexicon", - "thiserror", -] - -[[package]] -name = "wasmer-vm" -version = "4.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd41f822a1ac4242d478754e8ceba2806a00ea5072803622e1fe91e8e28b2a1" -dependencies = [ - "backtrace", - "cc", - "cfg-if 1.0.0", - "corosensei", - "crossbeam-queue", - "dashmap", - "derivative", - "enum-iterator", - "fnv", - "indexmap 1.9.3", - "lazy_static", - "libc", - "mach", - "memoffset 0.9.0", - "more-asserts", - "region", - "scopeguard", - "thiserror", - "wasmer-types", - "winapi", -] - -[[package]] -name = "wasmparser" -version = "0.121.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" -dependencies = [ - "bitflags 2.5.0", - "indexmap 2.0.0", - "semver", -] - -[[package]] -name = "wast" -version = "64.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a259b226fd6910225aa7baeba82f9d9933b6d00f2ce1b49b80fa4214328237cc" -dependencies = [ - "leb128", - "memchr", - "unicode-width", - "wasm-encoder", -] - -[[package]] -name = "wat" -version = "1.0.71" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53253d920ab413fca1c7dc2161d601c79b4fdf631d0ba51dd4343bf9b556c3f6" -dependencies = [ - "wast", -] - [[package]] name = "web-sys" version = "0.3.63" @@ -5797,19 +5197,6 @@ dependencies = [ "windows-targets 0.48.1", ] -[[package]] -name = "windows-sys" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" -dependencies = [ - "windows_aarch64_msvc 0.33.0", - "windows_i686_gnu 0.33.0", - "windows_i686_msvc 0.33.0", - "windows_x86_64_gnu 0.33.0", - "windows_x86_64_msvc 0.33.0", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -5870,12 +5257,6 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" -[[package]] -name = "windows_aarch64_msvc" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" - [[package]] name = "windows_aarch64_msvc" version = "0.48.0" @@ -5888,12 +5269,6 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" -[[package]] -name = "windows_i686_gnu" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" - [[package]] name = "windows_i686_gnu" version = "0.48.0" @@ -5906,12 +5281,6 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" -[[package]] -name = "windows_i686_msvc" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" - [[package]] name = "windows_i686_msvc" version = "0.48.0" @@ -5924,12 +5293,6 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" -[[package]] -name = "windows_x86_64_gnu" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" - [[package]] name = "windows_x86_64_gnu" version = "0.48.0" @@ -5954,12 +5317,6 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" -[[package]] -name = "windows_x86_64_msvc" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" - [[package]] name = "windows_x86_64_msvc" version = "0.48.0" @@ -5991,15 +5348,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - [[package]] name = "xattr" version = "1.0.1" @@ -6026,7 +5374,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.64", ] [[package]] @@ -6046,5 +5394,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.64", ] diff --git a/acvm-repo/acvm_js/Cargo.toml b/acvm-repo/acvm_js/Cargo.toml index ec63649947e..63f64e97729 100644 --- a/acvm-repo/acvm_js/Cargo.toml +++ b/acvm-repo/acvm_js/Cargo.toml @@ -29,6 +29,10 @@ tracing-web.workspace = true const-str = "0.5.5" +# This is an unused dependency, we are adding it +# so that we can enable the js feature in getrandom. +getrandom = { workspace = true, features = ["js"] } + [build-dependencies] build-data.workspace = true pkg-config = "0.3" diff --git a/acvm-repo/acvm_js/src/lib.rs b/acvm-repo/acvm_js/src/lib.rs index 66a4388b132..3b8210f4875 100644 --- a/acvm-repo/acvm_js/src/lib.rs +++ b/acvm-repo/acvm_js/src/lib.rs @@ -2,6 +2,9 @@ #![warn(clippy::semicolon_if_nothing_returned)] #![cfg_attr(not(test), warn(unused_crate_dependencies, unused_extern_crates))] +// See Cargo.toml for explanation. +use getrandom as _; + mod black_box_solvers; mod build_info; mod compression; diff --git a/acvm-repo/bn254_blackbox_solver/Cargo.toml b/acvm-repo/bn254_blackbox_solver/Cargo.toml index 49448d58fe6..132dddd50e5 100644 --- a/acvm-repo/bn254_blackbox_solver/Cargo.toml +++ b/acvm-repo/bn254_blackbox_solver/Cargo.toml @@ -15,8 +15,6 @@ repository.workspace = true [dependencies] acir.workspace = true acvm_blackbox_solver.workspace = true -thiserror.workspace = true -cfg-if = "1.0.0" hex.workspace = true lazy_static = "1.4" @@ -26,19 +24,6 @@ ark-ec = { version = "^0.4.0", default-features = false } ark-ff = { version = "^0.4.0", default-features = false } num-bigint.workspace = true -[target.'cfg(target_arch = "wasm32")'.dependencies] -wasmer = { version = "4.2.6", default-features = false, features = [ - "js-default", -] } - -getrandom = { workspace = true, features = ["js"] } -wasm-bindgen-futures.workspace = true -js-sys.workspace = true - -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -getrandom.workspace = true -wasmer = "4.2.6" - [dev-dependencies] ark-std = { version = "^0.4.0", default-features = false } criterion = "0.5.0" diff --git a/acvm-repo/bn254_blackbox_solver/src/lib.rs b/acvm-repo/bn254_blackbox_solver/src/lib.rs index ae6fb7999a0..eebc65db141 100644 --- a/acvm-repo/bn254_blackbox_solver/src/lib.rs +++ b/acvm-repo/bn254_blackbox_solver/src/lib.rs @@ -2,44 +2,29 @@ #![warn(clippy::semicolon_if_nothing_returned)] #![cfg_attr(not(test), warn(unused_crate_dependencies, unused_extern_crates))] -use acir::{BlackBoxFunc, FieldElement}; +use acir::FieldElement; use acvm_blackbox_solver::{BlackBoxFunctionSolver, BlackBoxResolutionError}; mod embedded_curve_ops; mod generator; mod pedersen; mod poseidon2; -mod wasm; +mod schnorr; use ark_ec::AffineRepr; pub use embedded_curve_ops::{embedded_curve_add, multi_scalar_mul}; pub use poseidon2::poseidon2_permutation; -use wasm::Barretenberg; -use self::wasm::SchnorrSig; - -pub struct Bn254BlackBoxSolver { - blackbox_vendor: Barretenberg, -} +pub struct Bn254BlackBoxSolver; impl Bn254BlackBoxSolver { pub async fn initialize() -> Bn254BlackBoxSolver { - // We fallback to the sync initialization of barretenberg on non-wasm targets. - // This ensures that wasm packages consuming this still build on the default target (useful for linting, etc.) - cfg_if::cfg_if! { - if #[cfg(target_arch = "wasm32")] { - let blackbox_vendor = Barretenberg::initialize().await; - Bn254BlackBoxSolver { blackbox_vendor } - } else { - Bn254BlackBoxSolver::new() - } - } + Bn254BlackBoxSolver } #[cfg(not(target_arch = "wasm32"))] pub fn new() -> Bn254BlackBoxSolver { - let blackbox_vendor = Barretenberg::new(); - Bn254BlackBoxSolver { blackbox_vendor } + Bn254BlackBoxSolver } } @@ -58,16 +43,15 @@ impl BlackBoxFunctionSolver for Bn254BlackBoxSolver { signature: &[u8; 64], message: &[u8], ) -> Result { - let pub_key_bytes: Vec = - public_key_x.to_be_bytes().iter().copied().chain(public_key_y.to_be_bytes()).collect(); - - let pub_key: [u8; 64] = pub_key_bytes.try_into().unwrap(); let sig_s: [u8; 32] = signature[0..32].try_into().unwrap(); let sig_e: [u8; 32] = signature[32..64].try_into().unwrap(); - - self.blackbox_vendor.verify_signature(pub_key, sig_s, sig_e, message).map_err(|err| { - BlackBoxResolutionError::Failed(BlackBoxFunc::SchnorrVerify, err.to_string()) - }) + Ok(schnorr::verify_signature( + public_key_x.into_repr(), + public_key_y.into_repr(), + sig_s, + sig_e, + message, + )) } fn pedersen_commitment( diff --git a/acvm-repo/bn254_blackbox_solver/src/schnorr/mod.rs b/acvm-repo/bn254_blackbox_solver/src/schnorr/mod.rs new file mode 100644 index 00000000000..cb213726973 --- /dev/null +++ b/acvm-repo/bn254_blackbox_solver/src/schnorr/mod.rs @@ -0,0 +1,146 @@ +use acvm_blackbox_solver::blake2s; +use ark_ec::{ + short_weierstrass::{Affine, SWCurveConfig}, + AffineRepr, CurveConfig, CurveGroup, +}; +use ark_ff::{BigInteger, PrimeField, Zero}; +use grumpkin::{Fq, GrumpkinParameters}; + +pub(crate) fn verify_signature( + pub_key_x: Fq, + pub_key_y: Fq, + sig_s_bytes: [u8; 32], + sig_e_bytes: [u8; 32], + message: &[u8], +) -> bool { + let pub_key = Affine::::new_unchecked(pub_key_x, pub_key_y); + + if !pub_key.is_on_curve() + || !pub_key.is_in_correct_subgroup_assuming_on_curve() + || pub_key.is_zero() + { + return false; + } + + let sig_s = + ::ScalarField::from_be_bytes_mod_order(&sig_s_bytes); + let sig_e = + ::ScalarField::from_be_bytes_mod_order(&sig_e_bytes); + + if sig_s.is_zero() || sig_e.is_zero() { + return false; + } + + // R = g^{sig.s} • pub^{sig.e} + let r = GrumpkinParameters::GENERATOR * sig_s + pub_key * sig_e; + if r.is_zero() { + // this result implies k == 0, which would be catastrophic for the prover. + // it is a cheap check that ensures this doesn't happen. + return false; + } + + // compare the _hashes_ rather than field elements modulo r + // e = H(pedersen(r, pk.x, pk.y), m), where r = R.x + let target_e_bytes = schnorr_generate_challenge(message, pub_key_x, pub_key_y, r.into_affine()); + + sig_e_bytes == target_e_bytes +} + +fn schnorr_generate_challenge( + message: &[u8], + pub_key_x: Fq, + pub_key_y: Fq, + r: Affine, +) -> [u8; 32] { + // create challenge message pedersen_commitment(R.x, pubkey) + + let r_x = *r.x().expect("r has been checked to be non-zero"); + let pedersen_hash = crate::pedersen::hash::hash_with_index(&[r_x, pub_key_x, pub_key_y], 0); + + let mut hash_input: Vec = pedersen_hash.into_bigint().to_bytes_be(); + hash_input.extend(message); + + blake2s(&hash_input).unwrap() +} + +#[cfg(test)] +mod schnorr_tests { + use acir::FieldElement; + + use super::verify_signature; + + #[test] + fn verifies_valid_signature() { + let pub_key_x: grumpkin::Fq = FieldElement::from_hex( + "0x04b260954662e97f00cab9adb773a259097f7a274b83b113532bce27fa3fb96a", + ) + .unwrap() + .into_repr(); + let pub_key_y: grumpkin::Fq = FieldElement::from_hex( + "0x2fd51571db6c08666b0edfbfbc57d432068bccd0110a39b166ab243da0037197", + ) + .unwrap() + .into_repr(); + let sig_s_bytes: [u8; 32] = [ + 1, 13, 119, 112, 212, 39, 233, 41, 84, 235, 255, 93, 245, 172, 186, 83, 157, 253, 76, + 77, 33, 128, 178, 15, 214, 67, 105, 107, 177, 234, 77, 48, + ]; + let sig_e_bytes: [u8; 32] = [ + 27, 237, 155, 84, 39, 84, 247, 27, 22, 8, 176, 230, 24, 115, 145, 220, 254, 122, 135, + 179, 171, 4, 214, 202, 64, 199, 19, 84, 239, 138, 124, 12, + ]; + let message: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + + assert!(verify_signature(pub_key_x, pub_key_y, sig_s_bytes, sig_e_bytes, message)); + } + + #[test] + fn rejects_zero_e() { + let pub_key_x: grumpkin::Fq = FieldElement::from_hex( + "0x04b260954662e97f00cab9adb773a259097f7a274b83b113532bce27fa3fb96a", + ) + .unwrap() + .into_repr(); + let pub_key_y: grumpkin::Fq = FieldElement::from_hex( + "0x2fd51571db6c08666b0edfbfbc57d432068bccd0110a39b166ab243da0037197", + ) + .unwrap() + .into_repr(); + let sig_s_bytes: [u8; 32] = [ + 1, 13, 119, 112, 212, 39, 233, 41, 84, 235, 255, 93, 245, 172, 186, 83, 157, 253, 76, + 77, 33, 128, 178, 15, 214, 67, 105, 107, 177, 234, 77, 48, + ]; + let sig_e_bytes: [u8; 32] = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, + ]; + let message: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + + assert!(!verify_signature(pub_key_x, pub_key_y, sig_s_bytes, sig_e_bytes, message)); + } + + #[test] + fn rejects_zero_s() { + let pub_key_x: grumpkin::Fq = FieldElement::from_hex( + "0x04b260954662e97f00cab9adb773a259097f7a274b83b113532bce27fa3fb96a", + ) + .unwrap() + .into_repr(); + let pub_key_y: grumpkin::Fq = FieldElement::from_hex( + "0x2fd51571db6c08666b0edfbfbc57d432068bccd0110a39b166ab243da0037197", + ) + .unwrap() + .into_repr(); + let sig_s_bytes: [u8; 32] = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, + ]; + let sig_e_bytes: [u8; 32] = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, + ]; + let message: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + + assert!(!verify_signature(pub_key_x, pub_key_y, sig_s_bytes, sig_e_bytes, message)); + } +} diff --git a/acvm-repo/bn254_blackbox_solver/src/wasm/acvm_backend.wasm b/acvm-repo/bn254_blackbox_solver/src/wasm/acvm_backend.wasm deleted file mode 100755 index bcf3bbf27ee6f7331f0ab8c776fef80ff023e3d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 756082 zcmce<3xE{Wl`wp}ZoePnXiQ=>kAY-&&2t&vB-!0eVwn&V!-AXL&HsJdX?l8~abB6} znSuQiMMXs&5d{Sl6%86xKu}av)Dck!ML|VHMMXt}ii(Pgiu#>%@2TqQs$137-J>%w zr>gEfk9*F!=RWG*TP)Mv7GR78ZsOzr7&tj_@*lO6PiFWBE(37IPZpO5*dK%N7ZXAV z@ggiP@G2^=#8Z)t8HtRtvp+KS#|UKu3MMYu~A>5GyJZTCUcPZ$8)880+ln$fk2M^9AOX zCEk^3Z|-PIPs@8=OZvl3-C~=@d(HPD1i{%17(c|kQn|5fYa$&~0Kp+ud z@lahL2}A*1U;{-+4#N|`35Fwypca=9&^4eH2U7L*ffP^=1wu^n5uySj2nG)WS}+t3 z1mP001`c6Cq!t9-fHI)aObbUC!cedQY8Lze5l|ruL22MJ%(OTIjcCCz3xmMn`j8e1 zX<9fO0WAjsKuLq4U^o~I1cSj)Sc`-qH5!PAv}h3Y#6X-tB!cu&u_4G2N3KXMTW9R7#C9Qg8Z5S@SfI{-r8{!R#R zStzM#Ar=e*V4zpdLvb`B{CpFP1jIoo{0RZ=5DOgwt^j{Psel8e4Ki>SKplxsgLoGT z90FKCQ}_hx6M1rW2o@S37#jWvMWe>Q_T{+nOH?If=J1Dsiw04-@B=s+i)#2Q|H*6d z7gPoOLAxM1VvW+`+L7NvB8bGa2>fc=5l8&PSN`#zfE8FA?F-2$1+p_3B0Et`SyWM8 zU`*rzC!k5P3aU_rkarv%3wS`q0N&cyfJPt$CJTY0P#AQ7#$uYrV?pg}aTWn5MOOo9 zBryJhZ-8rXtR3Lxpe&Ra(D5<+1#a>hd^N-)@gV#M(?mhZb-**qf}x|s@#xp1Vfg)e zH2K}p(eFj$(fA?Yhdj#az+pm1NAV~5UHB7+f(PJ#1c+;qcqCYVSmdy;1jF@5MMB{J zk@_g!!(AW{3o<}R;BO?B5I;%$n~Vk3&+F zMT_uQBm%|`13>li82rE`rwafPR{Ss0WEOg80=N+W&~32>30DdPpb!j9ihLo$NbdN2k{gfld&W?JNTf$LpqQQ zUK;rN*O9{^Dg4Ej1>INt6ZEhY_#+?6Yy1le3GK$i9jOg5Pg32-gg(1kv+H!AK~S3J1T; z#{6jP_r?XGL5u_;bRK$WF!-h5;fDqRiXUVGL_h(NU?k8P*dE><4qy4b<)M=UO|xeY zu*Au%Y46<L{Phy<*}PGt@7^fkhPx$Px$185e9o;B&b>{-m2^M2SmLk0PQt-; z67D0ogW$lm^7$r$`w8wKc#z;?qO*BQg8K;` zAb61AY@$Dh;9P?J1m_c6NN_R1r39A|TuyKW!IcEp5L`!aJ;4nG2MBH=xR>A#g3GAf z2MF%EN$O+%&7_w>si*C9zmMRKTV(n!^0T?*cbh2xHoD(u_~BhL|KL3m9^541;`=0A zNqFlB_TMI-uP1pn(fuB}@4ub!NuK2!5jNlG}3rU`x1osoaO(e%`;3%!G-S0t%gXB)wOdfrdd*t(7lzxExVA%uo`~k^-1>Nr_yYD49hw>k!`?))0{+-WAxRjnRCpeqv z%qKXP;9`RPL~kL%r39A~+(LA=6WmE~H^G&ZZymuo7s`0Dm*Dn`7-#Px{+MaNSdspWxzm>%_TeUqk1)$?7f4Y zzeaF2Jzq+Gu!HVDBDj#A&nLgwOZRigUv|;+19ZQg;9l~dL4y4+N_lq?+(2+I!GV`# z`ci^h2rk<#pC6?Am2^Lw^stle`{{n^D>DBEy5B)?1wB7Na0kITf0y~U6I@4dmvO&G zrq3rhKycx!^7%fxUq<))32q}e`!%9Za1Fs-1lPSz^a&0ST)3C$)BQ5K-%oHG!P##R zeS&KU?jpGEO`=b5H^JHD&kG5zBsfTLC&B#$SCId0BY1$|Qu4b2f_n+BqmIlHiBy?u56$ts}UN;2wgzDSi(U+(Ges1HmoS z&aELhNbTKnf@`SV>nFIF+Q0pDKbzWto%DP@wFfKc`I`ji((`rHPHdt33+R3&!5!3o z?4$dejrN4#!Skt|Aow)F{RX6VWCOuR2<|1gh1!>O1Xoh~+)wZT!5sv5QGa0_!9nUb zEG4*x`VVsmE~b9OUb>%6{fX`Ld=K4kAULo=_OCV&oV|nkTYr`1+)wZTjiZ)bC7&;) z`*j3&5*#GBhu|E_-+#5l+fMh3>3$F0e@JjSJ>N!fJ;9v>=g_!pAKlNV`}G8u6Wl~_ z?h46w2i@->xR9Q2Ah?3yAi;eEcM?2EaQ-z!kKlfS%L#5GxQ^f!g1ZSWzn1hsaL#q| ze%C4q*U|kRg3DLR=d&sQ8iKnB&Zm3>1oso%KzKU{E+zW=>3)U5kKlTOvu~ID2I+na z!JP#65Zp`fAi+7SCEh}UiwQ0xxSZfRg6jzm65K*?JHZ_U_YmAm@F2n2*GqnL3HB3Q zN^lv$H3ZiY+(2-E;5LHW3GODihu}Vf`w7ljLwpG?Cb*Q~a)K)et|z#G;1+`02<{-b zli*&0`v}fnEBVbK*iUdi!DR%O6I@4dJ;4Ejn+R?vxP#yxf_n+>CwPG1+#4kSeu7I0 zE+e>t;7WoU2o4b3MsPd9odkCg+(&Rf!8tdQehJPexRBs-f-4BFC%A#&CW35ANU(pMj@4L+(vL0!QBM+ z65K~{_AO*jf{O_*CAgg63WDni4iMZ%aQ=EpXD{6^rTg^+4-ni=@Zha7|8{~qXx?%S z!QBLxV!VsIz9;l@o$)%7{UZH`?DR}m zy3m!$7rG~Abse5f$h5Y0WHW`1E_|RLGg9wmFKNfsNM>w0oo~+<^hw8M+t{nMlgo5= z=GvPjxp%dRAl-3P$}!ebPVH&&ThLLU7bxl*;a?YvIziIvkSc?}xlEg1ddD;ZwHQct z!tV_O)Iv_@0i<=p(9qI`s*va%i65C7qY~yjz?)S5CEaO3XpD)`ShN=?*VSJ7FObuc zkZ#py5fvQT71im}I_F240*nV?(_rV^Xz8H6?8D%{n5m7UiZ0-4e0^+puD#GT>lcms zRJOJ(`&j!r5Tm+b7IiEvTYyRq8r>H>++;Qu>wRlZ z2yu1%E9Ubt*}|;O97KbW`DUF5|Di~bFedbL=h7{iY_6bBK7PuGH0EQkMie?8lWomq zy7U=rfACn7zQqM9v!jSjhm9%{@?|W6^`Ta|3kt+Vp-TC+cI$a|Fq9AhFrR77|8I_c zDU|+0dtVzHNQKjXXl|X<%kD{~i{+>)QjZ)XV{AIx(K#!fg#ZpqSPHqW_Drjcldoxq zm@GzTb6s6Jw^l@7${W?$Q_!>QtnfIKl)ox6rlqx~dpdaB+R$NzTz3JQq2`Vr0YDNq z%qki@*LnEJY)4yLN4rp4y1O+qHEp&`YN}>)BS)muh3Q=#ed+F5-Gy9R8f56`((}+fv0dol5VRX1 zPj=?a%+!2uW8*luZq0Oer?D!4NG%;YkAByYZ)9US-P@LT=8YZg%nS5k^^t>Y98@u- zFaa#rmT%7#a=q+8vI?JTW1obEn+0y10L-AR&o!s}a+wpsM|#=|!l74daS(0Fq+@$0 z_3At^!W*S=bUNLYgGvlF9tnX#Z_vJ0#2J}Rw}aQgQmTAgPH$sZX~Tf}L?fK3q|kX1 zV-y9vQM9nC8J1#Yb0X^h+BI2(s#V&5dZ14}4%?xsDwNJ%47#$;wnEW&2M^6*H)b2^*v%J$?7c-;ea zhBc2Y#R41lWOHL0N2a04YssmR@(|V`z}V}+{i(x{Sa&YlIdaU{6Tw?i;&TI|ZBPA4 zHZLFwWTECuw(|p#sjZn4b0fRiC4qXnOcy%RE%{t)GrK%+sQp=*T^TqG!T|)IT)MMo zYAbYOPt46?D*}hM=cYj&u|B*e@TF`=J9O51vJhUN{$~n3T{(7bpuRWPm2a74dA26- zZ76>s54qA==-dGz^WMT{UEl}iV~8dBX3Pld|DYDNP0hFG1Vu0epnz1}?54nX%=`*b z(p^ybn$wN!c3=5MvJHWwEcA*jMZvn+rofTi+3D>aU0o=UQ%7GjQdPP-%1BfQ%H9ne zVI(_r_g>)pMp{ugFCC6{WcQ=X_X9t0;3-74=(LjjBiRRmZ!73KbbKK2rOsS)t_wPP z>FJs7>9VP19|h{n$KpBrIPlHVC+WU?VYRfzvQI3eugO(j*7v z`C73gMmu3f*z>hRifl#y3aomh}j}X0+#!)6py0g$Fx?XcbN2$`F(=++FDQR|=Iyo~% zCZBC2k8OwkG<57t2BOz=4l+LB_aK-fou?oP62@hFy1HQGTEy&S{Vww2Y=$YXgQ6(T zJXe8^83EYmxhEs>d7INQ` zqOc2uq9&>s^E%Yw6lKyOWIKm0K!#p+4#{UsyivE?u>5LGVk?qSRoA;GBk|SRx1_3^ z=%f3lX9|#IjrI-US|SJZ*{Sbe?Dntn%78Mg)xIPsOfXd^jJ!%KH>i-vI7>iXdR3=? zG|V;N;Nd0>=UR-pJ5|m`C<1mzn_<)eVd8q)cpm~0MP9La}yXcsNCN;?b(j~VC^cIDE&`L04w zrj>n!1DzA5759MyB8JuYKDzQ6mgFV5rlY?r6{E^vS<(o74*<&nY9*I(sTY zQOOvZqeQ}Ly-Z7DbspE=A;JJZQjYi<8(TZ3!B9X9-bK_jRO=Y;jZn>XkFZa6>+IGb z2mw^=q;X$iwxS}2bDdb{RVg#A-F2B$8@#8*hb7U zwz0BJeQi^fp~mLhyK`LyaIY+TS({X&UZGtf*8+n0!(P#9ecuR?C(HI|daYU< z3EiMJ_ImBUXlP8-$2YY9s8z7WQ5N%>e)DF{f?Av$jQf^#QnV^p!6|Q;@W%P`($@(4 zwBOh0H!h^v+u}uTEs+D10RG*JGtcj6wFcv{viR8J9Fqp;-Y=?OO?7)TzMIh}VOV>w zX8Ghe5k&(DN2l5Q+OKML&e0-{L&Nh??XT!96^9+vPN-G1#*xL4YgU_2w9L@?VtWU4 zH}je9iNBdT0#-gu2CIuo|LNz%q|wUcvziq?p%Y%P!JBLtS7q63Uh_+2T4Djgyv!4wp3*$uvh}?`4Zvdwe$=Oaj~rwt@$PH6}wNA$+|SI&%QJc9_SXePC5=2 zb1dbqgEgNN%MI50*fNjc;gg9uSnGrE_BTOKsaT)njKxN%f;M&ycO9(xq*tm{wu-wC z)_hV_4%SfE>$&S_#V2VoCAyZokNJGkQIGjh#v9#ZiBH<5=ePB-b=-B#=aZUq%y(1G zT7)rQAG<|F_M!4bww}ALr}9}+@AXtr-*4saqg1~*19 zy|Ly-%|7V8N5mg>hs$SiY0!%fbZ^b_*$2J%arZ&5U-`tK7qoYO&6YJ9L-6gv+AV9T z)NC_%A3^&pr(*<-7I}cXj-dULEmlG02pSao;OE4oID!TyTWVIgWdz;F9;)3Lj1hDn zdsq;wsTNVU4GOw-2qdEsbRXO1J`nI}|8gVfM{2I~#%Rdsx<6WbC)gadLARAX<}rfy zsRWZAj-bIt+eM*kGI%LT_JsQg+NX?iO8iMtO=^QbFIlG9 zM|T%G^5WgKT>_sJ^+|1cw#O3BkYa1i6!%(eGX^O3)K2mZ8_Cw%Nxo?rJB}4n)=qPu zWx4=$*;1n}+1oaP&9xGI$6{@?O>4~*-?dP5_eh_WQh4Nk8%4EUDxvtk&3#-vvJ#RX z*hso~WF;gI`1Ht1XntgKAhk#Or^r6G5mft61q2UTtnJ~E6;S+y!}wnWV)dDFo#~d;%3PCXva{TV#%?zB(btE^rf|g)IoyJWGjd0@rdEbvCm_Zp?FRaS-RYl(TX^ z+sx7JogLjeKgyMkPe&y>U$6CboLnMoeQWMY(Whi~iuZBr>QJ#b5!O5wa?{{^a9Ts_ zkwGq>9Rpf7`skxeNsJuToNLLzwk5fU5Ek0EH|KFFI#k&Eg8$}@*f=8hr=C1)x`8F% zdR}gf8$+~B8f-B5W1l1>g%JjY<{SvHIcO;wY%^|$Emv8y^x%dMS+~@Uq1~5;b|C#x z>;B?KyLjW;V4p{3S`IR94>nljv`A5s=S0Y3c&~MeJD6_IR+xg&oXV zAzh1mJsD&0b3s^BFZN_uS1$8!;*x3DsbN_% z{VixlMaI%ay}W^zCzn1JqMemOpD3=`w#u&aVYrhOB8qL5u(4m@1+g^UTzhV}A0J-2 z9=HOQ4T5rRpJ-VeU-|hI{LD7pV%1cH62h;`b&nPW4|3}x_);QF)&9y=~IhCnU zP6V$C)o8?Nn^Hfw3gybMOoejAg9?S7N5Q3ZcQ-YLxI4gT>q;|>!(%mY#au6YIcRxR zRGLe)zcqyI7lYp{N;nRV0}C6jN3?H%HcMD^^QEf9MR8&Na5 zI~eNxpGKMjJ5oU$u$6-9>y~0Vu!Jf0dgj3R_J(H;3~_sdBb>4|LUSv2ec&Hlq1Fu* zbVPbgt{1x^?9JdmI&sG2;WQZ7B7*z(>6{Ury+zwIFgnvi+4~xiW>>{!Y_z1wZ48k1 zw|H^Cm09+&GsW%_5c+LPuf9UlpKY z_4L3!J@gMw+(zh;wrAxEKscZz-=R-sXN0ge8ttlC0;Brt{Cma5&rF>#wWFgo)7m*b zqx0_<2VQ16^x?BQ|AE|4RO&b_`I$L5XXl41tm(O#I{%SEpX2lG;7oYb3;*Y0H89zY zZq2p8nJObxG&{18(x{T8D-T;;bv_bz8`^xJaYT1E50y9Hl817PQb`1#RO-WXm2^H@ zr65f1>;SQKK1NYF$H{aUIgVA-y|LXV<~#c!ahwXZ2llDM7G9l?S26B^<(OSrA=m_k zcf+AE%`9e7nw%QPC4e_~HL@Y+~^6K{;Ts}fgPOBi-FG|%$ijGq%@4!3qzG)V8mWv35jKSSR*-{TXtax23lr|VmX$}^JF%i|9XsBEWb!% zNBH7U6^K~KMWG25bA)~ov{z8di>pAE9SK0bB=nPtIgh5c4$zn40e0l{epRLH2n}jK zt(Xv;QYXUVq--m@G-O#+Ts%k5)6nC(bGZ{cT3Ym(&?Pggrg++%$3xvN3r(q5D1nYM zgg|q23tUXZEy8V6y9;>8PC*B<%PcPKS81cM9S2XjBJ?j6i!=e7p0-T;EJ>gWMbGSp z9qa9|&!?4LS&aa2JW#F++K@gd!82OrzCNahkgu+WdnfkLv6+GH=ZY!_jGfsHhY&&W zkAw1G6RKQ)<6-ZGEItb0Jo^kf&h961$|EK})G9{9z;bN};(GCrO*#_Ko1e~)gP3qa z?}&6eoXKTWZeOTkZsfYkONdRwN{mF+aYgi1p?@t_3}3<;hg?D&g)lmmtqxfx&V5nn z>eeUWK-n2@@Bjdv-BGnn(7=;SmZ?I&GEJV!2C(I;$aGMa$=&Rps_+Wz-m38O?Eb3o zX0XAk@LJgeRpG&czpC(NvWKd|o5i+Ph1bF!sS2-|JysQ7jy-Pe@%Z*nI3D!LiV;Ua z69o1ADQn~Di=#k|ySJ&2p`I_H1Zuh4p-NCvw=717{*Y8~A+1MIMj1-5qd*CgQ(PagoPC z157(XU$jiG7)P~wH)vye+NJNjQn|LM+x7R#nHF-bt$s4HaL%MxJ-lzxUO6qOkovIKZBXY7I8ur z+nSzDO**cZogQ}f_{(~#XOI7k z@Q+O=HX0{yievh^V3)BRTb>=Z^x8*LVE0BBZ%+EFz{3cBF6z5DI`qd;=f}eU{)Fl6 zUMa2+4KU}5IheKVdbo+aygdqMTtr(cwIc8QZRn9T|Rg(~|x)AN>F(s=;)%owL;D>6t&>9>33X0lUSOp?X$@a2~ z(9@2m-kDF1=3MTgDv*87<*GI7doEXvUd3Flnvgk{+gENbSB+oeT&@SvTIO=qWc|(M zs&Olr%T*JA$xJzy3yNMG_L@vq}WUc^AJxm*`Cj7XP+z2Pj;W|CtC#R=ZRIO%Xdiru}Z_GA#r7kK?Gf!pLR)yEiR#t^qV5_Ra%d^#0;mu&z zSB2Ng)>MVp#@1GaHCYbVaPf5PFEt& z_vvYMd@!b`@2FUhG(8Q?`kfUQ*)ly1_;*!YWOI7Dj}0hV9&ZOQr>F0(Tw63fy|Hqp z#`N?(iaC%n@|KyN-V}D9o>m*3CcIsyr|(ttL5xWeH9gl}Rv9$xW!wS}ryGGpcpgnK>QTnr@D(i7inmWyml zPmasNXbq0ThV?{mSzV)AJ|z=4`-X&~byDW-u;swaYGt%evb-CfTDx+~P7m(4y2N<- z>P2qP_j(Zywa#`LjNxMMS=CU>cd`wF?<)vmKMkr=brODHt=z^Nm=-Tu`sfb$NIAZ$ zn!!F)^pRWgtvPr{t3Ei#iu{q)q?NFCs~%1}z%tv96$R|@UBFKiGWx=~<9OnnxEtQ58}iSqSOD`y6s%L59|^%%hcj*L(jXp5 zUx_4T8=MOw&dDBc)%e(1upm-tg*4tpEsR(WW%1>v%2$6EMPPJRTv1R%L#p%NL-(;r z%Gmo;O_Qhd|AZ=Eq~)*4(fNO=u*x(7I{$Cm02N-h(K;rYSMk4&=?@B0a;&Q&VjTw%&gE46|KK|(dqZQ)4=E24(RKcR5y|95-c%0he^i`|fsY%fw2D(X zq(7or%`zFzP!21DSZ1O8VoimYHYfbT2pvALM!?FNw0-s%hXJ75Y&8UNsg6m|ET|;d z?ClsXPQ`O7a~U>vLuyf(s~pla6(^$*Zk(p8IF&=n!)CUkiK`vF=zNBXxp#2a`H65Q zhv}6@w1e$qZm!>o`3-;ck-rV|8yiu5k3JgY2KPL(9fquOyeh3>g=%2IC~uzUdIP zsEnVCT|Co}6qL{*E1uQR`RqW6DQhBD(f}J3gc{&e0w}au{+jskQw1@zRv2NqIt`pA zh}qSNL7@tD&QYqfI$|a2G=dbV^K_*;tK-AZ2q?RD-jhB$KU1KYiZkkPIkdR}WnZie znwK)p5`vh%#p?N&R=!tL`jv#z@#4TC8R9~glnb@PUc(BX-z#-<7 z(J(JKP3PxZAN7e`7X;w+LMrB%KG;45htDi1eFmrf>3m`7GePdcfSX8S+SWs2d?UU} z`;N&Oznmscg-Vxv<{T&A+21t9L~fsIBKM*|@$4j+@@;K}GbkozcPJc4)1f9#nE9@eSA z7zr4Ku1tG(OGj55792f#X9RWR%smb=!xZ&&Bj2+s8T*WqE98eXEZcJ~cSjRl?I##nf{2>);ynOV#9$unS? z=I+SXOhbWGG|>139dKxS^Q)SagJ-sPj{2k-lcyYm-}YtuB59Mm zIHYiTE_)(=)V!w?`hfEALEFbFlr5f;$&~RRD0}CN@xGbt-7khwfxQ=L0i_u+#dH%? z{sii+`kJ!!u1}yn_Q4lZq_!`L(Jc1i7gM4Z_Hm@i^z71l1$R^{#VK{FdI_~Gi>pWu zMrH?mQjzs@^3=&$tfHgS*_vyp4z&jeu}{7jl{K@^z8FS1c1rY%s6dn9-R)`7;t7Y1 zwzgml_(2z(#J4zbm}z4?r?s^M&%HW5s%ox8$6Hy+)m?I3_pap7Xr3KaHJY@CV~MiS z9C9gI*}Nz=n$E@#dn@jZUmrU!T6|+`sb+vyzVYj0^P|ef&w(u}SD)GV^(og(RM`0S zvGcze6VGH9d@+m)Y=N?34Yj*q%e3%|DN@@P#b_40@QW!?3%e+)Y?;96{j^Mdll!n` zS`zzUjQ+Ff`bL`$ z^2qTW=m3ZRnF0>E;P5CIBxu8scO9c6qvjRQM4%6V40Gt=CR1D{FRDUI+QK4?;k zLtM5p`dgC<)j4tIjE<8pVsI$V=@z3WVh>|A`42~JFlHAd&C}dheeT+t$yR^vJm5R> zpF59PY|ZD+qnWLZ7SHZ?coy^?$+N_;LHgDVc0;td)T`7f;8b(FQy7@uZn5rjFKUk6 z6vb82)-h~#$0xZ51KgW%v$7-^C$J;xttg&OFrYU;d7UHCcE=<=K&v?|J-@ZVgsK$k7jmv6yD6ylwqlT%T{6+ z3vc|~rOvT?ly!J0YZunxO;J2qo+8EgLcT3m<@B-Gd<<2=(Qkm>7+#*+x!fqXMUz(N6ba|O|TeNM6%1Lis1VfJ^J`$ZV zGz`5b-LPtAv+S{<3T)6~pcS!_coc5?P-}B~M^Bd*!^fkYL!-?`Xauo*ybAl|(A5r0o%G_kBib=UMTIe|hywZc9tiFpF7(up1s)^LPRG43 z-JS3n9}bXriLy@*wQ4hPR;#BmpBZY^cIWUTv0kd(InfU1&OpT}}d#ql)$3EyizO3#&R>8NT-s3CkAYKJqzr9B+?B9pnm&)}X z_o(|jRg}|5?-7gms=D`BIYVE)$Jd7{u$AvUV&V1(!vb%R*BHhuOUk>{K0 z-eVO!E9gBU0Ci_0@YsmTwPP;4$KCx!xmkeP^gu>)Crmj_(e& zYQ1}p$a4QsSC%rpN96h5P%GB6_lO+dA2N=9dXLEQgXnbo7^}M16yks)oI@&kqX%yX zixZCrqSJS~EYXxx6(6bfAfrVk zFH+Qc=p#LdF7!dQ9xCVMst3sq^zexfJ-`c;q8>htHd+-2^JckOw8;23Q%C4}Bl3iU zO5iIbt!epj-Cj03<^!n!?O`{3Ww{$Zo!kj?#j|5S@a7~s@y0sYUUo_hUrN&~dE*GD zWY{6b&!nWgXSGf3XayFh_>l`v6VDg&y)a0Jk2v{7YR^r}SdmWkBV0>YCYx@~Ps|H? zrXgGf)w2&-8<2x8|9yb(1*xwkGAT#G01E__wA7$!^WL zu65HQoL_4aio=>`xmweLQDV)ry$oY`rajVnTGK$P$eM^$i8V2Qh1N9Ws>qrKQbpD@ zgsZ@sh~lv3IbPN@FiNc19~*Cp=HrU3Q+nzwoFL)dDZ!N9G?84QUlcLv0)${7sA%ACQ{blIKZ1##xOhwEB! z?auI`ILNR(uFV-PDp${lrPCP}mGgRwuy$uyQUR{r87{6s;!xVFidK z&al)+ISr?;#u*IUYMcRat8fNHtIin=VXJWl1GgGyFeI+r84$B7XD|?L&S05)nIO6h z_?o(kqv=ZL)2Eis!N97X9J@4jBs79_RDfK@-riA|E>>d09&v4nWfxv8lF0cLD24ID za%#!C%o(_g*|x|CrEMJ1)1LoRPcGeA=$e?FbZqaWUifn8WLPBr+cdi@c1ck>aX2c@ zN=Q|KJzzdKQ<$FXf(79%9eOE0Nm~{OcPEeQ%oGZ_F4$w7#l5r0xw;L$Q;to`f0Og< z^4NTok3#L|YDk5^u=*9A+BYDxt72;Bs(k*tymPIJsoke?UX{8JOkq0Qr?2Qfeds=` zV{6^q2ex!n={|k6xeo|EAw3cF(*%EY_^|XZ1l08@zfQwHaH{LwoT_rAmNTH!sqj#P zQl|nTVYYZ}%(B_jHU$SEP8?NyalkzfOdyIpm$>DD2G^jo)FY2U=h6V2uVt%v)lFZc zj%Z5R7Cy5%c8k@&ivdV*a(d7g8iBx5ZjD{3@^2{}R4BQp0(Mi-4w)Ia4tR`QFJD~h zDW#@)Rk72@jFq)*w4U;tH2ll6+hXTBqvVhqOSCQanC|dqSlSBSd`C>}J+g*XGU@N` zJ$*TLXY6`6`zYd%U+?)G0}%MsU9nr;Ww!VfygLxPuE3{o)11pL_WHR zpT|=C{FMrsMq0=|9_HP~u3Z`(lb?qwMGZi=6ThC%?4u z*rfZ#6sBJcJWT06FAV!(Rzj*lmHf(_n`8d~M>HCzD#9sLFt~+p9oX~g{IY*iUT8#qzWRu5JtkTjMTm%RTnD6@K( z!GVHh*y33R2Z}6%bu*|#Q^)j_eh7oA%+V@CDD!R&Rz@F-@ldQXobu(!D`mScrYeUz zuXj0|I9QH{J!AMQp`$Pasr*sFIOL2C%W^?EQjn78a$VaCqb6CV#?Fq1nL!m z;=F{}8HK|HCmq)|wT(R*R|H6V6oA}q?4!7!3MyD$8Bk@ld#K3z*MQ1O-FAzLyvvn& z9hw$-uL`J6q{-@{C=Vu7iG4D0OXAn2|JO9rAmq3@prls$5K~b5o0D2~{d+-eg_>IB zT{uDQ8a&jN8s}QJSPEj-Dv4F8wd)+jYEarrC9x`Xw#w?ImOiV{!D?k99jbJ_rB+iw z7?*9$ba&_R;HOVw|HrgNBXpF+A(&=I3H`j5?r9slHSR%Q)T7$y-xdEuQT~zH!mQ5R z5K8~7JM|%u{pC0g4yf-l2DW^O#a%-we!`2v5R~Ah1fJ(_bS2S$L|@V@g01VL^EH9* znngDIZjMG|B%V{+#?Fs>Qn#b&d@XiZ-NkWq_;h|l84P<%r1KjC(Ao3iVQ-LhzOD?4 zqg~SZO#x_Zi(Fh61?c?d0507lCvwdE>4D)_Ezok57$XBGipe$wi z3QyiMG%2#>Fo^r|oXUq6)fihx4-L6sWMPxz9XXDKtkf|44PC#m+c5KRjMMpq-NN)T4Ym9FN-Cn$ALn$8+JK2*<-8 zdDyq!%C3)p!(NuLWI<_>HBOnJQwB$CijdpOZiwR$qEx2bpCl`GW4t)zBBAJ*aU3|V zb4|q|;%W_#2A7e)1Q(As?r2Z{Z?3B&-90_im1~CFH^skc&kbVY@h`cVaC}&^&IbbD zHgl-Dg48PC691O9aya{pI=?&M(dnx>qGG4g@>LccPE1{ zeMY4xwXyrf?2Db5P*8U^(=J%b%xo}@Q!0+ExbR41g;gm!oKz$*f(O{NAkS)OZ z>993k?_&?dVQSe)5RGGGngsh{`q+bB)LJ|G1hp+*)MO?}?I97{?B&4s0rC+0EPGf< zs+a@n6l$-JZ57UFCp7^`wP(7zI{Ng!EZe5kuqBUF861tx9Lox)hb!`xI#m=OyYb=_JkKTX_YK{(u*3I z4o|COI~1nNidQ*arnBZC(`DIH3e#nEi&xjm?jC;h^1L zX6a8a_@Qq2)r)?pTm9=LcPkbf)7@TH#HRFKcPkD-L;AA21*p+^#WM$5@$a5F(2B3b zE#HQ*S+P$qHb#5m*sWAs+sr2;9JDsC#_`>kTW)2m^I9BV>$svQTc6iGoP=6`qk-vT zdp(@QmRYtRZ}_1uy{eDB>4!SGplIvf5-(2N%3ExM;QJ(=q>DMt*6JN=1MaY?CG$S4biem~<&=FPJe-)c;Yt*jN8q=mB;b)eGqT*K}9$Q1+Jz=2M^0(F89RJ3Jlu6sV#ZJV-UuGvPBSO;x4gwefE&g&!Lgg~i6@+q_=O)jYF7Yy6oBR?{?!i| z4`(EQGXRpX$* zQ@h4beF^UH4WWfLc6P$DiPhp9c3U{ZMZYoz*k8N}=a}a&t4Fx7leM`<-ms|I(Kt^X zF6?wl9K-Bs9FsR3?0j{&u#<7Rg{7}y*<4&yu!DlF@o)(j4m7n-D8q#v*WnUa{x-Hi z9WLzHDu+;o3&%@R;Sm=q!-X@iN4RigcJqm1xHwN8E*z9fyuuPLEN-C;7Y;&BzbG3n zoHQJsp$r#JJhf{m!-WIc;Tse#7O2C817GDGmY|O>aEvtvJ%yI>uz$z2Ude(*9Mjl) z0vB1WsGww6&qm0s-DbaVQNl79Q4lJ%UMV?C{k9&#<1Cjm+FQ^0QRG*f&C-KaNNP1# zshnb)N*i08upWD(;Oc1nmn42wY*-vDkLh+bn4<4?apITWw91*R*ic`Runa3yV)-UMtE}CYCalvmDnT8FyVTood3VD(ThYtB4VRbGPcTwf zIGyOe7hBTHy$zR_^V;Tky_BG(ws{&3s5qjfr{Msh3d7~a?6fgdFBO$4+%j*&0bhsV zu1FkbsU@)T*AgKc$4-=sYy5}FE5#~TWBSU4T)B#8#>(XhYxs7d=Ckfu1E3ovhZ!y1 z)J8WXwJEIu!v(W!J-j+$>BYJ7cbIfVS(C!5CjTbArmRVUoNtp}SJtFJZHP>YlqxnU zB2{Nnz$|OhRb@?z{1qnstye8Qrdym*WMz*0gJ_GhnV{oVL9oQP#HL6BXF@#`3lWg8ps0 zuDos0Y4Htl`IfY-ZIM*vwneNeZ40PnZF^IB+oA-HdRxx6dGC7b>>J%&#Z3_hb+xGVI zwne8Mih3){T4}u{tSW5_vX`~(hVr&W6)0?LX&y(yDa4ju@%S`M9$?ql)wa&rgFCEU zGFN)#Ol$Uw@3LCfm0abPbtmOjYu&NRTGkb{tYz=ETGo|})3Qqv#}_+3E_jvAGiy)rN9jA$}@MGeN zW+d+QW8zBYCGPWMV&Ah9K1{5dqwry3*O>|*CiXF3;mgG8S&QP@0bIZ?ms`TJQH;&w zC;q0bajdS>wsSu@@%8fk2|qdU-GKG<2POAWBmHt0Ig$HdIqo8-FQ`x6y8@>l8`Hn#v3~!<>sq4_Fw|`!vF**>J)_Du_IA9hPbO{y`Cwc|=mNJMjOb4x_B zTN9Q=c~%W5zX5P=Oqm)tlHX3>xZ96l{zFa2s`{z9MSX{yTLK!_`jo<94N9g<0mMzrdi=KKMf;GP{d6u5y z#qM&MP>(N{%Y=H|jT^O%>V-Woa~EpXvegxv9{8FZei7pp9|&-MR1sm1_06Cw2iX1y z2Y?o)Ba7F4V8E$P7K}H12nEM@rPK1ONxkeX9|)op2EyA3%TjmOQouQtGob+Q`pDd; zQ|9-4WX@vd{{qS%_{c0MW9AQiWEPb1yoZl{WEPag;SfGD3(EMt@y~o@7L+mbDaoUX zVZ`E&Vrxv6ot8YoExDErq-;*I*v&A%L<9%qil}vZ@+U>6>b>BwT{6?2X`S`IIXx=` zDel=}XOu(l)7{V^I|4S=%~)R86Xy(+M7Pk^+;`3E&+S z9ZIlWO{$u+2p$iVY`3-@^b3dY>ih}MEHE3Y^C#W27>9D~@XR8pJcTD3nch&-kyko@ z+KpH>wtGfJtXk{sbR$-c{hkfL`X^IowH$Y)^XE!Jfou0f=g+$^twy!G{4m8p^@4(F zwI+Dcg;q5dcnMF-D_X!f%tHj^-7aZZo|gl|i!HLV-a%_zXw~^E9=V{>P_DnbPsn-Tg3jOZ z&VsgkH-J0tsW&x(js?qf=f-q*X0jmMez)|_E-#M zfSxBZ8VpRWJ2TGL;MAKFjErDl>{`BB`R2y~IUQMb?Xj;ml+F+}^(E z{E`w^P`)U^*EBj`TH*>G880o*8ebB?VbtYW%Z!(oXDu@>6IwS*?fTwD=U0?i(*0eE z&aW)7q*uA&_&UF?G@>f=tQ2`%WfF8&mEn~KUaQOS!aUcP;e~nDXz(V$ z?0q^H5gNmx|%JUWZZYs}L!X^Pr{~rBsD{)oH+`T9UvMiACcfw_PqmX;FFDIoEvenA@(5xe z^23>)0!yvv#t&eIZ=3Z6nqZ(4Lx#Qq1_ihG$b7T5TMXW4b>OG!1_k8kz?*I3L#Z3zt`{Fo9Uo^jY6^ z!{niDvZuHj1SSpzc~cGQH@G@KSVmjb*z}V!+Ny@;r{%SU#{aB*sWIDZ?u->8E>>}F z`6+^y;TtkmR7>krjZ}bp7fEOc#rsrdmC6UgU?S;J(NYO_6hPS(=7kmXxJwRLEFnzhIWDrlQS}${zs$|s?yV|8>f*wfzH zYTi+XhZEyYj$h&OD2MZP>|FxIqaaR{fiheauTt+W!$pCzkrxm9rK=^i3XpYHMa?uqysC+y2;W4Bm7mEriN3M@m$ua!c!JKc|c zFVfoSo~cM_w>TSIt|W4OeQB^gU!1Y-zB|Uq_e8mEEmVvb5-!W+MY{Vk`5K+Xb(uVF zB{{v^VsJyjY+f>Lt^snHr~rl3;#Tl+wK8ki4MW1p^fJPToHYrvD6X&;^eUv)nd@To z8g<~h7#*#35w299QfM6Aoh!guF1eYVxojcVJn7ipUY)(2JOWf3%Rbge0!#llX&mK3U`5LJ~z=eaah^|Xk!qqJ=bR>NW}fgLnWdmh2P6z z9TaaY-B6JcjRf;U9 zrDUh1v9YydT0Wc3!N-rfgdNUMrl9)gDpQc*87YVg!kMk)3}wGyR)emdcJU%YazmPD zr;O@Tnub)*O34+?xcjy(lW(^Od5$^>DfX+Akl;Bf8NeII=G%KSt$Cy--S9l7vL(nbMXdl@f$6Wu!Y=(p{PMX*pq|V)09okl=YH!IC6N z(6G6nWD)SWpehB)%{Ogs#X)M%1?675#?c+Uxvmyi_*_EJB@tGQ|1E@F5n zCBI#afH6WioQ^*(N6yN$C*;Uknf7E+WUJTk9Yv8#oW241O_;cd1P`LH+^F>8jAMYv##*$FLU%>H`Fp$mD_=_S18Q4=^5-Dg5 zd&+JO)l^WkI~adiBq2FR(kmhf={b`Aj>Q3oogltVo^NmI5LI-Q(fSr2ql+#yTHoSh z^vzY;VS>nbjQ!b6H*Rq3Wf!Ink+PbP`5tb|D44Cbql=EtMJan;WVIS!FJr7Wi5hWw zQA+OFXcX-{3Yc#eax6wdLT8o~{wf*_YpUfTNux->!Y@%U5UuuVe1k9A4+||rtc!&f zz$~V~{58~qsLGc7{B_ZSf*Tf1!S{-1fNXj8hS}1ZM&NI9R5cj5$mA`-1Z{3*vd?Y+ z(VSkWD49rDoWkXy6OYH2cG;OTGgI@ujksJIJ~z~sHrc})doFi0l;ndY%i3d7P-wxH*Gg8Ug-?VQeqUA#pYrd6wo3Djgi{5;9L+Fk z+7913wp!#fk-gOYJhIOYB6XYS?$l2ShA?|CKQ)M+HDyvSKTTXsgsVA0^s!P&8?9<6 zYWMVDM4%tn%g+#(6DPstnUW~D>s(5Q%d;pQF3%1|B^F$tBd!4ruKT4_Q~9~#V&YUj zkHnkG&m-}s^7#hOsr-C{=Tv@y#O>n?ByJyHNVt9cLc;Ci7a6#He360M#}`Z7EMFpV zv;1Ph&GJhKH_MkAxLJOwft%%*N!;oDa)~>gFC*OP{0hRI&aX6Zr}MuWxYPM^iJRe9 zN!$#-ns77xZ-krSD-7HWzsA7L@M|S*H@{BecJq~l+s#)IZZ}_T;CA!t4cu4?}=J_oWH_z7-Zl2#txOsk?ft%;I8@PGCLE_Hf zcSzhB{7%B1!S5p68GOLNox$%maA)w161SD#BXL{#Ccw3f;WlpwP|FH7IoRc_xK!ex6C8o6jc-d44`o$ny&f3VFW3ppfSaO$vE_p-Can zFA8B_#1{0Sk%n(8!=#a=zq3eWENz%@JC!5jVv(`5Nm6E962gv3DQmYT`r?q>v{Tam zfnHe-7fM^CyhP-)NvX)UROGV>smOP!kg=2=%GjNEcJwY2c}r=!<-I%v#~Rr?Ua**< zw@pEKnaFG-?3Vco7lS%FQ&)zt?`KoLwYgXIdj1-Mu~U0r8@!(?On|SEPlqpXrwiSZTZ-PIG$(*dF=^X1Z8J} zjq*c+GM3j);9;0>qjv(?OwY9Gh2nfRJ2Mmw@Ysc^0BZ^)9t$7-qaXd_Kdsg#{P-t7 zo$xRJ`qQ5uqaXXrUrqe!U3K>dR%@%Ywc1C?wc5?v_1YTkNo@sxNxPwLZQYu>>+4q5 zt*TpHcU#@9b?fVHuDh}BCb&DlZY^I}_i*sB;B&#P!54xL2JZ_F1~&({h`VjUN8sxD z;0sBl`)Y7+@B{JumEhllZv+nn=Z5Bm&I+9uS`bL7!h93y;4_zMqG<8~J zacEGxG;~>LS?CJ*y)yKSc6De)=oPY+c{H*; z^0>Hu0-iq^*%8?adbv8jRl6@X7`u;tAB}$$e=xBnaYOvp_+9a5<1fdbO}v!2Jiaw{ zRs3LVaePVqlK9Q>)!J?Gf%w+oWAW$WuK?T}Lt6N2(0M4aHSt_xcjE7fR}*^^ZzlF7 z-bw6Fyq`Fb_$YBO@o8dq^3>$A_)YQK;~V04#Gj4a9p4zgC;n1od;IbE6Y(eGJK_(= zpNc;ne1wE;(w3tiN6|uE&h6ZZ~Tq;oAI~e`{M7!-;KW)|2Tdy{%L%6 z;*`V{q04`HEa}x*R=m}>h`V;5c?&l@WOPo*X z3n2YM+x`8C!Nlgo1Bt=drOAsDizw&f#FE5)vCEPdCoZ8UOB0uhCzmBIrzgu2R|u>t z6U*tz)rl42$u)`V=*cR0f^@D=tf41s6E}z_HzwB6lbh(t&52v+$@;{tBF}A!+v&*$ zc!Cn%k+_SV+)WbRo4AjjYyx?Z*T%#>mM2d~o{8*?JQsOBvJ1TFh2ZYU-pIR=_aYy_ z?}w3(BcDZ1iJlh4l(VDrq8CILL>I#Eh0%+mOQIJ?FA*urqt`@NN3V~riLQ;_6untI zTOYkWdS~>m=s@)D=snR*(aV#|lAEIsL?4W9i9Q_N7JV%GO5*jzTZxYopC#T+e2|do zFGgRA?vB0^-4lI1x+n2Q;_bvIiBppAB|c1Ck-Reb*W~i#RmrQ9e@m`NUX#2wd0ld4 za#eD5^7`bOp1#Z#2*(%4mk>#EpV0dI-jA>f^{jRM{i+Y}qrFy}q7d*KSL zj{onEJrH{^wk7sZ?BUpX$(NJoCtpb(NJ8*l4ZmB1r=(6z%}Je}I+*+<`DyaAa`a}cPX3(ifwkUTrppE@@+FLhpOe(L!8|1X2<%Tw2+?n-S)txPRT-I=;QwJLQ*>WHPxRuJn$U`7xM!r4%fcJ8nmY9jQYrM-oWakM>Yf+cvEmj{Tty1ULQLW z66XhIK&HUa8vJPp{D38z*sqSNZ)gbAzobF-rg}(Dd^Zp{xuKZrhb%Fi4M4`>+EIua zgf#7_`ggS>6Vpm00sbUO5SRo@B;ml~U?Po$eV54_K!$Uu0Oc!)4A`a(AYeyjA25rW04FKE+o7M#W)YNe7 zQK&>PXsW)>j@A^aKP1r*s^1TMgF8-6;+X}?Mg6QqvTeltAKbn>ympFw`s)KFiKs{c)*Auy2G5eQ1>G~6>H zip%ui&ys;eLlF24i$VdwU1Lq`*MdZ#A=ZFpKUy1cXpl9;ewl)tQ79v13ZK}-8o~|H zUmXQ3Mg9nABUJyf*2IQ|fqw)L8zK!6@*GGkk^)W<>DUcXL6kRWP+X^+VuhS0jld@y75pQ0fdJIICY2N-PVQtQaB+{HAsH0^;3~ zBb#mu)W4OI5n>&L2{309LgAuKB5jj-yTQEL0#{97*Ml4pf=FUJKH33)@CiamB7|uN z;1(RUDexz-q_}Ge{21N8<7wl30wM0G02^tU;<5j3+i3un;P>zB>iOK`6 z{Yznf;S5^+5mLQDz|!jPtOLg%s|6E)`4dt1&0vRmMKS@RYp<_4$O27p$zzFxG zz!im(65m6I1%v-8_%jByK%RjVRss>jgySPS;1o@afK=&@q6C;3>RkQT1gYT=J7&~> z6^M&Ci7XO-4TKF>r)bGnlISfjL4ppF_!tn6h5M76AX`IV;!(r2 z1cW*W2pZa+L4<+FV5ALoiJ!ogsCmar)qPhJwq;-&kV6-WyaA10N)s9cQAo^HJgZyJJ7W>K9%)L|Njx*_T_MC@WEhot((;w@sBbskFzuGJLm8XiKA6IJ$bcp7X9 z6(DK^p!pOL68%q9jqf%kP|slBra-}-WEiT6x4I^24y@q@LGDPxn1#BiAI70@ydfmo zA`k{V8;xE+J_!Mu4GUoE(NKK?zXhk_^+ylmNewF!JcPD9DT*%(@IBELXh5pT`tPGl zfsbM+{{a?h#;`#B51|2L;uq9;1Uvz7_zaRjxNiW((144ET;Nf({*e@*2O)D28G}3Y zvQ{2mUo@=k>MwBrm%vFf=Eb2-$3c=|5qTeidnf~nj|M{%OVfcwAqZ3WAPfb^m+dB0v$tgJ8|yr4a3K&@JFVnJAda zzzZ!Z=o`qxn`2pM(cq2ZJwd!lJ4JQaT+ zNf48Q!QC*fVJHg>4@=fjpcV!`I>;BUKbjt5-vLD$9u*-C1j2p?SX0K4CJ4rLKt)87 z=17ryb^EHSp&?IR;WXWMk$Qnj<0l?4{!(zw8 zHPD145u!wY3)0!}SOZ+6Q$a>#gOVdsuptISWGawu2m|pSGo%j9Lqqu3qlR%XQA4un zGiZ9DzsK=UUGQgMU}!{=!!%Th@U`K{M@S^{0#$HaBo%IA0@QyKaw1jXtQwLQsu~s$ zP9PltWeuZdfjDRuLNE#{;-`258iDo{=mB3rDJu2HrH)Xh6m**;>m-J7fiFm*;>1N* z3ML6bqx>yd0L+Sw4V8yOb`+e;+?oWu{+m#_q3)qV6omv@Mj=6NqmW=wRHH08U>Tyw zXF*$$rNSUH6b^)FVo39sN2Q?k7D6OLAVBbBgNi6)s38n}LX_7m7U)}$0G;|M*0+*e zXv=Ko0>`2cA#xyzfu{kS8R#cOZLA*&O$u~F>VF9R1`+R%z`l)${m^x7T7S_1wumxx z2O*E_96>#9kdYeWJ2n=O3Edp4`!LXJu<2Vut&ygNhG6~oo3#3W#tH;H>bIquc>O;^ zRzSs=)DRbSD%iw~_9y|56A-L$c!ljo0&)%u%dmyLP$dnlDZil!3u#0(A!7z4vV3~ z94F#34h}Fw0FdE2I6MILLj%VZj?)nR6FIG*3^opRf|~#g{xStB0Su_pzf9pM8FbKe zI4Bt6g4TrnX{@>64x%!nS%A4zF$5#v3jeUWgDYST7?REqyN?-^u2XgDar#}|)sJ;{ z64FUb(g8xZJfy1}5nq>xd|GtwC^PrttK(dgfLzDvR2r(%G>RH<9K&NYqav9ZqX<_% zal}hRh3GgMQSNXria`;PQN$6w`7j9g`}_ab+I#JDPE~hf8ed66oxRt7t+oE|$NI1K zm)xP#m)udzFhNUU;Rn8_Sop$5xKWIo}yerLt*AiWHm{dlPiFK zdL7fn+3<}m&0(521Q2d@c-(qu_#NQF?UT~c6QYFnX`fy> zIZUL01hD(A0Z5?lebE9uR9vO6H#;^lOMTFssTlRunNH}dtF+xV>JQ47_k~~))O3dX zQQr--X6c4tT)>Nwa(aD}*Uvgq&6G&h0bQAOUhBLk^nnD^+j>dSO`kb!B1lidrwvuS zQ+R9)g*1hcE<#tlz+3BWCOU0iM?K>d;udzxY9mgeP1Ime0zBfDJ{*Z{)X^J6WVAui z@$5F3g62-WZl=$wBhVE$N*_m1F_yd zno$S3VMef-5oOL)u$d8TjQDhu-f4aS%^xNfryLCoe-jczYPzaxvcep1TEmm8&B4bR8w~*v&6Bx-RrKLK*dWgqah2e2)%k4;><;bQL+e|_FO1)!8iY1;e*hwF<@^?! zVje{fX5wl(dFIQEIE^Z}K@wPGS4bZLx=o=9B1yrucS|uNX%hM$?DE+ie)#=SX1^;hIB&-d^&<9VgTv z{!54KRmQRHWu2-gFiq=;(J4$u>@ry^ZuYvuX9|7;v!gNJ z-oh>$RF*J(9Nsi|R`gB?i<_=)7wUe|6n5eS(T71-V`ic8#h8x_CE!Q_?FMgaW>!1+ zi>=; zhAn#zTV#&B=RpdS)TFYLF3DqGI}97llx3-2fwR>RJ6Md~`=<9f4$RrR#>TyLJ`GW4 z>V*whc++BDu5X}B7&Z)_49s*a)I?1;rq3j8KO0vx7#ZkvTad$J_+Hd&7}@GQKkyLE z!>0-lB4(B>YIR=FYP%}vmX`Fug!pa~8ye7Cy4Fv?Gi_0qB^QKPCPYM@35FaR#a$)J zipH~3mOFQh#~PAj)emNP3o>Bv`P{8hFj7-s=^Mu~s{Z5$AF@}srJ3rh_Hp5+Ow|-O z5dPcDsZ)>wOh9xk>Z8|gqgai1zbxedO4`oxIz+SXhhE_C^27O*7wdWFpQ-A$g2dBOz zatbM-V$e1avoPTPl0t^6ExO$n2N?o^)|Y9DAPpbrLQ@tP@>c4%XvME|iZ5yr>Mro2b; z(%!@8c+ZjT-*eceGrl|^-8CLiSt21c=@ytDY$_u83=SIlYaYO=NbmL~Vc}s~1PI4f zf{HfW;faW(bG&KzlX74UzNHqzYr?acPjkLxI#Tkrlr_gk?LmtPt>FOH{t*4tmqh`9S! z5ueaiJ~jaC{{;P87u&67L;j5G8?ddHga(h;8KX{T3=w5Dz1&o&)rFUGYx;U?b?K#{ zrH_d#Y0?KzDdEXfMgbuZ(hKMIHl4@#ltyB_W`K&)P^jyyh9{d(FY~YJiu>gTi=3_GU`}{L)c_sgrw19|U1OBxg)EEi^qqY@J!) zjZ?pQW3&FvY5fuwX~d~t+#~mJt?$>g>-VgB-?^`7qk*ix=yp#LpqnCb{Ng*Bz)_Eh z{d3Sadn9y@!_UE#!AW6_z9EcnYJNh~LQe|TafJOc^rQGBZ4EtaQ^X58%-7(UaV_5D z*$R4K^_MpvY7F-jt>N#3e-M6^e!v6Y6dwTn&bDq{J$ZYjJUu4U0`&cqej%w(NPl5c z`1`5m>EW02`)EUFk8$=D+>@@-I{aTa`-JWtJ}(f4A6)GS5VbIHnOPB)nljTE-jaZJ zf&0EP-S?EL-w!oyzKz_xN6g>z8R%CreCy-z1=fdeoIo%b6+FVH%k51BHYx8}0AZ+!AEe(+a5 z_TS#!ID?Cy?+h=;cV^c9$44K0`yW5>#&>*#@AUMY<;(G%{@S}f`4_+Vr!W7}d!Bjf zfiuNi=)K^9FtheOKk)8f{I~DG zAJWY06`i%_ohWpGW_Ar7;?APIu}NbF9YP#hoW1K(%3C;33iJCMMLVY=@vJ~|a>A-2*-BMhC^9>*Rz1j8n zRxnvmTv+FVcLn-=JJ0EypZ@v(_4`lbY(9PuPVztA z@am2B`WcRd(TnS0F7<_`w|)07ymPP)O2qEbBy#AlgXdM#tKWO~+h^Cy8P>Z*OTBdv zx4P@!-uvoHG;pYu9YlK3E@P9NN5Y8TD5CBRM5n@dcx~aypR{ zX&!Ofr7w(T%3csUNmzg?kVZfx1&49tIqtk0oOWJq6BT+Ii%(&g)v?cR=;+udKJ<0$ zFbOj{c5sERjvbPrtz(CEn7f$KI{XASpC<JIUk4%=_a!z7twB&rao#vm5j&aY!+Rrn3R#>{1kU zZk!(GB1Kc@aFUrZ9*+JvxC?bb3Z^NO^6H`dEDHgpTuQUyd{~{wY@>8tPln@dconId z+a}sE9KcJCWf%jM;*}$ke$A9jABNo|8d5T5Voft8 z;{@3gDZ*|NQNz1ha2}adX_}-o_wY;!RB#ZRSvZWd{+Zb8UhM8{>?a(>NU9h>SiB1A zN^E0t&Jx>5gA0Rr?-`zqY$J70O%wb+O<_4W-8I2B5*W&f(Or>kq-k@u;Y?q$&4-s* zpX6B_7~EP`C<#aMdJbq%(zZPnr-AA6I#?3dZ3i6*>N5*7X~zs zX;A}dQN+DA=o4x`N;%rY9HfBzhWLzlhbe$P$ibW744q(V)A9C4ylGtF(>t(LA0_nF z0#g`K=xxH|Zjr?DNi|*e`MA|`Emr5ftlK)Dt9TlxI0~r;`z4~TrI!5k9+4P__ zoj6@Al}!&@6JITMmTiw%8=o(RW!w9#jeZn6QX3y65V6Nj?-f%LlP&hz`8|G)<+;z! z&)c~jo{fj$c>BJ1c=CArAr4p1_D&C9CKLVq476)^Yb5t@Rt@4_&Z_?3&so*;H*;3? z`9aRA-g-xknR*|Mk$U%x<+=cQwCbL*Qd;TWeQ?p$hgzpci~Qcl?~;CJP7|f2+x+fW z#hU`mo2&O(dLjIW;0%Aw*}&h`;T`xdUZmS-CMD|k;_nCa>$jb4>5<>V7xB*#cD%TC zdbNKC2OqE|tYDKjOnV&%4AWNM{JMu4an5A(uil@Z-Pdl z`H9o3@2k!kHQp@E!dZTo+9IW<)IMm4VSpd%IJ~z=@)$>nO(D7_z2fG6lAm%m7}CUE zD^HU1QgXLe!AlzWTiyXy(!$@e1)QXXzhw*5^q#Zd^Zmc`hBtla(ZMp)X`lYkCqMX#yH2eXid~y_ zP;_3f0)L9SK{3l2;UU)yin%-UZ#F^?tFmaWoXNk5x}ry5Wp^T+WH_J6J`T^b%VY^~ zc_!)^4MS9{o$`(`&c@nQ)i07Ew@Y4d-VtZ@V~y|m7jd= zQM2(0A@bRoj7dh*Uut2u;+5*vf_OX8JGYP*;PcY&Fap6mapetW1xD^oC}a#)O@r9P zIqZLK?PX z{dl^1w04y*=-J28)f2U=#~A2;{fWQ$seWl&bgYw0vejJWrw?!atyewLSqHJA5g<*Y zyY_*9_rpIti+*H=YIp6AUjF{yp5fGN&+gire)b(7)u~yg-L>!f=pVmIcB`49-L>nR&eVw|?R;|FFsFLegYP?JLS$EY)PiW|~W`%tXy4S7si5 zx(lWjZZqNV@oWH1WlNg_y)+}6BQOT2|kCiR6B8cWs!E`%*&eXM4-rO z?L>Hmc^x|_Wwmx9u*1Oh&t!`W$WxRv17PM-@Ih9V>J-4`PGMI@z3gs#vn?)a?gI01)`<`aeBwys99TPuX zmUQY%I%S_n{BQ;L&z)dvE`H`hUs49PE{1RNOtMI_%`VL3;-}9n)y22oy47hl5Jt6E83wIU5#ZweXCfZ#8NG_4>*|zHxe;-BCML^O;lA^bn zLxje2I0c;Zqi)IV;mm)RPWqgP|D%}5X^IGt7o}1*%@%sLGG%s>1C#P3Y(atS+7_7( z_+CuObzM_r%kW`04q0iV>-s&&E^i%+lU(*;GjbD2+W$l~jPTK~p6iplrC0 zhU7kI*~CdDC@*W`q!N@3nmDNhv7sre)^k<{VK;dIZ#s0?e7*AcPWSpw^8}~1yYT;Z zMn}kudbDBwUs4N%H+XE<8efHAXpoL}7t*&w?As1I){#J-G45w&LB@{t%wVc|-a{wi zdO5V7302v3XK@rQOJa3US@0o%1EikwnxchbR?I7GXAOM|AQejr^|4kV>dOTR&@sP( zbTmD&<9PeI`3<||?y@&5`wcsfw_ljwu={wM{D|~E()ZW7PkLUZ-?oyDnLcZ7Xly~O z7q^STkVBC+a#&$Kw}-+m4&4?CJ2;fpzzw@O9Qff*4j1FM=|mDXWuz`KVFhWT8lB9g zEZ|dV)~&S(`-d2i+drjY$Gf5$Z85o0Dx~<1TLI3fG8e6NKlXf)?w=WfthPWi%^u;o zq^pl=F}dlU@idarLg}H#g6hfsF~28R7J5P{95*}H!y+SQ?yy<--LWovsKpEuZQ~aM zK+!wkV9`22W05+bNo39d@1ROzW%{@>U`*n`=NdR^DjC)^{JV5$F|`O3tw#{KCA2FJ zIzbFX2c59s^n*uRWP@@ja>KX~mCcA6+k!<~fM^Q}ZGoVz`GON)xgODa3K69b zyP>vMm{jbuzsvS_zx_R6e^>19o^2>(C0^4kMG85PHAO>nf7TQ!WI1b!6tXXCiWFjq z9`>dS#+A+#7w&Y}qn?lUj8n*B`L5C4kiIwC7gBFV%OUl3v_GVgj1Gh}&e6)&6tYJY z0AN=13v3SP7x3)YFA!SRFF@L-U*NP?zfj1c@LpiJ@VL$tB`_S0Ie;f9Bz2naTn^xr zV5umij$Eya994o=okHX$Hh{Yj;X)n-tRT{a*25wF;%HP_2+$0>lXGpm5jk)K7wH`21CBe_rf3BfBucVM zW-`34+qsBJu?>GdSMA2=YjGWAO(U!5tDVMI%33-B@b*F-rp>j&J`PQr zYlUSFO`B_l{T!M$*9r$XG;OXGRyaK9Z%ACSkP4ViP+JqBd3GU$b}-QZ7bBrnN?$v{ zGO0>uxGTc4Qu^8nmPyUhT@jY1%V94?h(r(q`gdJfg7PImlm%@-E?yBZXYC>p*Vh zTlqPGFf+bomg_opomu8G#yMx=xLN*(5Du?3zDCQT>bBk>9Kle1s)4ZYj`TOJPeK@ z%V?k03S2sQD}N|a_T_Szv*w-=oxF9#%j_XtAAU9K@LMMdj;j@mWVrfv%gAR@|LM_w zdeR*QmY$!Tv7U6*6FpokYnc~+Fr|Cn4h40U_P~-0<-~_3oonHXp)dGchp%Yb&w1=% zLbt`}X|11-k9+6STKDUhf&ExKzfZsFN71_m?L_2l{#zW|Qco22F#j$YDv_wn&1;ua zTGsu<06E8aS{8GcUuFttwo1#YvCWhZ6m8;^F%)@b$|;K6G=+d7pG|p5F*ukq zmm-rby|9*+)x$DLAI8i~d=Tc5C`*3w#8Uc|Ixt@`ngwGtwX`fi2%ea|spx=aR*9U( z@KYLAKX!LM_H)5I7?rVFTGr&8CDxw?S1KoRicT2!X@bh`>#m7x&NRv8&~;bL=1dc# zrkIwMrp-Bs$p#ys10~4ZzMM6p3L7N-@jQ^AQX*&l@Yv((@O>63t_2SxXAtlTffhpWtbpmW3@#_791| zghf!p`(#=5AqQ`=OsyR>DFEV4gjVMA9L|`Qb+*?!*)nT*6F+NMn3|TA_x|~$VdWX8 zI$x+_J)920erE*xoe^}!tO&>0FX0&bJsW>Tpt>%))h`rjzarEcbG^3-Y2e>QKM_ZQ zO?`FPDZaMTJiG8P#z__s&O2Ou!*?tm;Qk(m&w&qhSMTYPur&N<#Q~VsX!mO1?w!su z<&NP&+^4&TU$@#E?c%vzt9{Xry^oW5BBFb##yMJ^d{8N1dTH3ppW)YYHy-9)suHAz zVqk2tSk&uC89rUGw&vDiH^+;li0Rl9q>xJrhwiETjJx5%oR=Qb-H15OOF!eF^sXuq z8P{obMNekFRh9C|T&t3n2m)o!NG#a&!JCx^#@|PA1KVF^PW6T_;)JZJulJv?D{l}# z>8}1B>$UzlV=;gzXR5pU0c+ZClYLl|y+UKS0~u{ozn|GXxZ2Wm98?$=$;+#vNX1@Sj#VwB-7V8{BDHjR+TzbMhN(oK0b=8eUkpY) z{_$rLh_7iME#@rb%;7PMM9-`BM6ocI`-C)jLD3rzKKE9Nd5V}Rx;z`^CxXvhCO{kJ zCUc*-GN<74QZ4wrpk+G>J}dVLm#9vVQ-~M8P)miML#*X|REn`&GG-|QKTyF79-J}NuzmK44Lz!(Y#ORl}7VO zyqq)|k|guXkH*VMqam|0zf5-J%vSkONkSt3V?IGEq0CgADf6Msbu$xld7{r|rp$**UO~n?p)yo9eW@~327IY9RCY)wS&PXhVp_y_ zJfKXgk+O59(j`otOn!5_W~T6@o`5G)$^y|Ziw7h?;Z#ZU`8QY8x~mVtd_5je=0xF& zDRZJMh#UjZ7MP9!Xv>3&0cgvciUDZi24zl^D+B*7hP`blPu`6H_L57s2R*8uHWrI~3;sUfUu_V!>6RHC1 z1R>1{K|Y-z!Nn4E(hR$JovhR4@Xs=zz!k0i)D+o z_oQYi*6uo#ME>yW=p?FzmpQX{&fF4~B^vSjy9Dp#!h3Ykl>@0>QS^5$w|-Z!_kDff zgJ=geP2k|;Ao9_}#zel9fV#++5-=(9_dg-zP5M6}XBins2HD1**=;6|AqD z6QeZVbB70SW)@ns z)(E~&wbquNu-434+sD+G*4jV@xjgf-)&_2%DMOe-=I(=+f!625thFUh#JWn`C>$8R z@PHd3#je%gR*tDy?eK+!v9u`_ak8CZmuk$afc@?<2QCcB9JrVXr2{t^X7b&Jy%qD6 z@0RnDxypCTdBvf0f0prT9IfWI<^J5QTRMCdc^koh6UU6+<U>KFmnBrX~#2BqUf`q#iI^++oaRm>Hm9VpDQq7uTQ*w-ZR&H3KnwjqE z>rcmTRpDSv?csNsd1~(PT}*-Ar8i-O55LuJubS}VpB{cqL8<6IA8MKl86!E$R+4go zepn%5@Q@+~l5eVfu8Cb#B$L+ni0XQPv#CO1MAHSwwq{?oGN~tb_H3}7NG!kK?;@euz@x>{z@o{FHZ`Ly zo6#jE>_?lFc;ltKP1_ym&6;6b!ECaBa)q*ux1_9=&qqmF_GFOrRSVYgnQAF{JDVvj zSj%Us!4oG{J5`Ww(9!?ZdUaqhSgVzQYXV&6z{1^p+@?W)TJ*cEl6NZk08;%@xyu#x zO1|96A}TgEPb{7xSV>T6dClRiu_Uw=3B@zr5^5FPz$7cn&M}SWV)fa<_qAe&LX&9| zCfm$el|UNejyE04HYQ_BmE6eguclMwjLUQNg$|YHpjVq=mFH-I?F#*DQri{!*`&5B zw~0+^yKF6qkX_M`0Zu|Veq^Igq79LCxw^x zfbbYe0-LEd@eV`nw%AOLwMM1cG>&7fQE3SV@WyaY<%H{4If=DnSZ&MZh3}vT^wl2z zQ~GWj7*XjLRorIKqp?CaW_S2X(3hX@5}pqpd`>8nRg|=nud%4oSUjD@&+|L%i7OgK ze>9@tcwAp$CGS`7eSIvBu*{Wv(#epM^Xa6|$=P($0Ad17*e`D1XAGgQbrak~;6)PO zj*dy(+tE?UdOL#N8LPlLH`-4?2FUL>BGMuh%MH^4i=$kiA+ET<`FetelzddMe&U$l zkgvGNZrCH1ZEuJxE?9!`!u$>O6&DMnR2Gxj_R)i#J}VD)Ao5Q(o${GD)Y1ugv^mt` z3tN!B5cY5=4>zq^abZ!K1zT}pA(;hRl95uk!j!bGq}D1GD>~^bUwfI>RXWzWD>~_` zh0A4bWr~AjXD;nbU!=J5iJ*2 zgaA(yYqcPX66uzStePgS^=(5=z=3m?MMtRCQ|h$7%}7@dhrN1yP9`(uh={#-^7*sR zt6u1DmqkTXud*Aj%QV;Z-rCQV{RF( z`RlnmJFPIK=X>@x&=iK`=-|mAN7EK>gJSb)Ub5zn)^U@CO^`YZypsUSRaPSbvd~u0 z9pWJ7O=^RO<5l;-tB>?*6Q<1le1fRbKQ=AxZRWyOfVaozg7Odg^!Qv@^%ID*DgvXq zu<}yStg6Z3u(`9Kn5ZKNU1MRmBJqwRtk~8$0eG?ZIVOSgR&5gOS=&{`kxqCcW5+nX z^Lb94&)2!U^LQ>gk5}Gx#o?X5bJ6*Gox3aP8abq3nDZKtEOD!%mFi$tandpcyCgnw zZ!y7QDYO!g=Z$@EH@=abLlc`9pDcFTxk&(S9D>U6#vOLSIKP-E=_`8B_$fDvdg6_{ z?1G}$N_Rbve@!>0%aCAVMP=T0iqb3BdO}W=dD|7kD)Y9}DD+^=!B1>C%iFf3U8ceN zcj=r5-_GYqP9PslP9QH#P9PslP9QH-TT}AE&_v8hLS+D<6L)# z74MrF=en$Xgc*->T`P@@9NB>9QW#lXtxAZTL6mq_*U|>eERnRBnIFT{ug1wcT2Pj1LmOd^n6<0T;^@(bVYH%7+#@^D}#*DoQ3D1=4AD>`v zHCZE|RRZ#JZ=)o%xh!h10tYC!uJ)2ksS{UwNj9w1UTGU#akY29T+{odMYm73PNM73 zaBHz&{F=+!HgUR|29V}|TB1&4dLR&coZgo3j~Ji6onIc-M{kho#S0g^PxI6%%i zVz$~73XW6(G5CLMhVWv}0obpy;sA>|2cVE=#Q{n`RaA6BspuRk6`jMb=p0Fkj$9C# zqSLZdxw4Wuk|{cVQASR6QOv~@9lt0=r@DAc2+~dtO;L2Zv~ub26h)^Kj!aW@4(t9S z7gThtzU34}M;gt9qO;2k-f>08cCm3cgQMjTbBkK|r9n*`p zP;_=(SkXyp3K%tE$6cJFldCXWD>}(ud^{8#tA9a~6zgA3kBEpqVa`buT^670-#L9p zDhxG2_~}y*L`n(;K%|b41Z-g*a{{j51eBvi>?yhJY1rOvZ>~adMlY09IdzKYw&#W? z-1crZ3EiT$q8WR_ZU2u_TUmQ~=@!R35RDfWiAB9d<*nUp!8Z^!7ChAlCDIR=NblA> z%oL2!rDeO+skuRBFoakNS zA&Xn4>_lA8zu=ByPUT_;VFxSeteW0p)^k3{WwMjP0+-u*RBn4JmJ(Lvo841v&n5qk z;!Ih&bbE}-u~wU$Ei^jvlG4-oxg$aH3G9Uv|wZ3X6W(-@rziMLidq;XcMAZ|w{ zi^g?GCD>6 zd^o6SobBg*d zP`F451S#lCVHGR1LO~S^=2B3_oc1{R&54hb-<lPKALL>R{`JGRHtM>p7_nto_^|c8Um&+h!~y%vkZh0fsJm%z7ErvvZ4K_qk3b zUv!9E*YFK98W2H^Vl<@lKoJcfW< z5#{KC6&@gtuc@WPKsJr`CFvoDL_58)!MoE-;@SL&eE?RaOv6l_a$`B1Y*dhkRKMpsb0>UD0`!Mxh5|5<;c6 zlq<@m(w!+MF3ET4RVj!q9PvR*1=X>Q%W4I%4r*4;EA5gpOU_yXEXznrJq7xVqepwm z7MG;{p|YfYAz0JcaEr~RoHgU%v!?~@Hg)?{CAh5|HF6THNGu`0;;3fj@r3I zy} zWi%oLm_~$v(ufcs8W93QBSL^jqL2|IwuKSn6GT{X&XNdOMO6_YtCn=)L>TwE)J70} zs3{}DeTtaxD$ zd$tnDE`ZIOVFG#o1qE_4wLhl<`676jqZI}FB#^c6vnG%~Ybl&$n~D0EL|zlf@B&Ko ze3pXwAGAQe1fb2zpWp&{pO@iTgyNU+{FygeIWj{|z;v(4)8~ZO%dsGfrWY`5M2yH~ z31sB51Tu12G>cq5!H=!#=mq5RQMZj!ZS`U#Ey)b1RHC{#9Gm*2Zbyl`5}O)SAdgM^ zX^IkaiWp9!)Etm1I8?Bp4#KwDLteXFRm+P*)~Z9*QHJPMQ@SXu)yhj3SEyB$>x(O` zHT4_@lN9DMYxj!SIVn(4VNRn`Q}pwtdd+Hz%2*nxnxev7mE10sF(b3Gym%7Q)@nuC z)9`#aD$pJavRmPO+by6*n0qk}Hhro&xKQhaRp7Mk*v>w(<@ z$O~1Oa(;_-ZO+sVhppT>J|8Q0j>T$a&M|eZ@^YKP*X$YqRMm6&inkh(14}y!ct_$u zazvN_PCo5h11F7Akk}eH2@7>s)RfcwsVVA$X?Al>`NCr}WMgj!rnV$Z$VwEq+Xxe? z(upc851}nk`kWP6mXPN4=fd7dm`Pj|QDwFbHjwHrZi#n@G})L#gi5_Uk?o?0xFbsk z+gX3u#{u(Lf7rNKQFf{{Q4y8y{ zIg}#c3?ii$yG~US&Rbz(tYOY7=(@PulT%d!0maSJr$-k-U|ZUsMoj?5s0rAxc>tlR zNKHV9O#|?HMX?B+sBwVXO4JysYP%6Rx5x_0I|6S@RhJn!Y5oM&3sTi~V@uG=sfv|* zB9~pb#oYo`HF~Pcd1Q};e>zu2deCr?+4CyYm>Gu_~iPRT!M?Z90$NkkWhj5DCMLdBSGR69(fj&%5P^ z9AR+vIcNrzXO+)sQFZh1QR%18s8mG{KPXG3G!KLo;3gJr#Ob0b7{t)y;wg=m&?8>J zMf{;{2F_MN6K>P!MpS@LZqr3`XKUc{f-2yE&qZxxZc`qEml17d)Y#)1xE_!b5$N%k z%>>2%>=`#x%n`?pnS=3w*)Nqnv+{S-p3!vI z9gO3ALsFDb8-cbuXIBDgRD7~cmx)@WR+X`gH}orhKU1n~L`#jcFOc1!&`@$L`o zpNfOaPLY4nj25p`v*6~8Y#aF(&Crq6LuukVPfHma;&wvzErLWaxO#YGd0Kd6d0Kd6 zIfY-G-=}C1+)16O0%ycDVBA$~r0XS~Eo)_8|fP3oT?K3uC%P(@YKQ5j2}b|2McsQ$1sG&GHaywE?D9mH@51pUS*|KbOKoHlOc=r8t7}wJeE?35z6Tn z zYN~oRlbRC4R%he8^3KMlaxN~avp$t{?%zE6b06-|&0ahz(`Gb*ez6o2n!wnU_bE2z zeTq$ki=4pNo1T*Y*h4JM0X?7rdm(*|@6&)kEq#j_p#eeTJD#(7n3hZy1A~|*BK^PI zV-&~A@4xBcAD>+>6g9z2{m8HW+OKO1Iom95HjQsC&9t!bj0{*Xpfc7R<_UaEBOj%< zn=}v!G9M2+n#Gr+#QR4}4~2g(`ab5;SM4)EKyN8uKC72g{B7*zd&-yZNiQ!A9loqr z?BTDy4I#rjC=WjNj=kkO_NI4~E(m+tH$=3@7*-n1V!Ao`Hj?l*9~7%l;snS|aBdSd zId#lj1e?Tv_s7+t<|f!AK)i!4{^Ywp@i4VB=GNZxM=yT|hU08H=%<5TI_Rc@nRL)e z2km%ZGvGUEY97+oj;1$7AKMXY5Bkf;;^#xgW@6KkvZ~)37RV7P=Gq1lEO*w{Dp=s@CS*G_vLMePKYdZy)<%mw&p#`QA z5GKh*eTe;txQqkwN8bL?8D$QDRPD9@{{Ow}9+6G?Axm1c3iRrK>I-7apR<64%4zuf zSPvshYbNZLan)J-)LTFJm-q~DXl=gjlRX{879YI-t!B6rzh911GokPLjY->ON)Rn& zXL+l4rg|(sV7X^$D5Ryu>@ti!ZRr;KMDBoh&TuGx&@|hsyJ>y}4fUslCh2bF(0lfJ z%s}<7GiJ`oNJjNJjEUJ`Z;mRj3Ax``!I&gd4(pJ9VLqihhCE@S#PyfjWby^C|DelQqH(+SdJz3FG>GZF-3LgIV-u-qq_DoYO z-UFf^{F)gXr(P+(a3F( zo&*2FIv_bz7VsJ250}aR?Xr6_f&u2J)$h2&4#R+@h#(8C12%Bz%4SZiWysTVp{cN z&@H%DwQXFTRb>`s&Y;M3D_JeQN{p#u>vtMw$~mvi31XGe)$Gi*yY9x09@_-T8~b$| z)0V&B9ozsIw&aEV-vq)YpYM(FMZ44(yr(>vyfWam&*ijkUug3OBBG)*8dj zW@z2iXq*{!S1H`M)*N+2@3)YQ(Nu}c#v0V7yP%@G?&fhg>k)E1fLrI>ophyrC#~nr z`_W{0O}KG`vg@lMbl!C9YUd?-1xtA!&?{!*D|-HlUVKHbdIiJWgom_NJF17N(kFD3 zx3bxv5O?saow;gE)lmS68J&<>wH*0;S+&s$b!sT(^?KDtZ6o?P?Doay1Gru#2A`6j zJl1$ETI~AO=Iog9yBW?@67+`|)FTuPEA@oBbH^?-Z&E+9P5>XS z;4dTxI?H61cE=hkk-B8N{OO!9-y&VR(9U%YRcgyENbE@eC(k#4* zvYK(}mz5p^8#qV#=v(;5`wK(W?P2h&R26qfv10P|oAr9IEfxtB4d?*MQ6W?68)xNU z2ftF48!cKmr&eEdd-axQUcsXxG1~-|D-GV?(1tv#_rLv}jo~+P@{z`AZJ4O`k5`9} zm4~|cB8aEdyOb!=$mUGJ)-w@$%)#?~Gkeo4fX7Cy}GBtC)sq zCQDSLrcBsG(!vxKCG}2f#S|4KCM_h*PItxFcN({vV(dH3ikhYX%ZKO#tSe!zc-g=p z5;1GrvWiN!wls&0hy&HGMUgc=G{@YcdGraQ*7y;&lG-~mFJ8m`amHx0zQXjD)+VUS zGTF3Mp?HdUac3&pF|NeYJ=jmaH>x#bxJ+^-bNRw6H{eOJR)uE3IgEV1t+f*>HFoyX zc!iIi+tlINPt9zsEnDl^vyUxpto6@r>O%j#x<>=Y%R1&hwIAh}$2mH2esdF+rFA=I zOL+yY%kc@Snez!2zL2|dnMUC{OIM$e0oT?u#VYM6=m~i4V52|C_X&^36l+FU%pn_Yl?drx+2FK|q19e}sAWy!*X`A_ zE$xi^knN1yI!U*!Y4|S@Q0(x^$9 zpMIOi+h<$MP4)?d#s7{FDZ8LAHQBk`zOM%wbfd2>K4x9ibtZTCZLxpWabBSJ#BSyz z;!_`KN^d)w^tATs$F0FsCY!?5$E?A$CToZ~-$T-Y5j%k9;dlth9*Kv5@_q3TNIc4+ z#IW`4Hu`_toyGj{b{dbCb9SseLNjEFn0@`QB1}KZ4dzFN3qOG$8$4)sE8XyS=>vd| zO5@-5MP9^Q8x7irhj;LcFur58X*>^5+MRUe#dZ%*#XDcjh6CWjOhn+0VFtCf9Z^hU zvE6>{d0A~5STQ^N*G%K14J{q~c6P54FOBhHj&#unV?U6)4~7MS4``$mSqDT$CfwRV zMb*r{P?tJruR6KKPgKGDn)Y+;L`Nqz866#chvv$TZqszx(Kl$LdC@~W`xc^ zzjz?b*wDrYn(0*PkRhWD^W?3J@(k$bVQ>u#_o+S|%I+BbS)0+M9i1pUW{~Rub3Fv! zRHFlPbmHR%cc%4KxQziMk~E^=P_PECTLZRD@*SDOfH8_FAeuPLIheqAFV2tYT8e*~ zzQx`2hMFn*svV05-TU*lDghgr3wkG=y84Fsod9tF(aR%jtZNDLQ0xAVq5@O+W^>G(BpH)=rwd8r+gYb^?#x zA=|Q1U3hHrstSjuuZR=a;g@xqWVuy*S74^|Td( zbQVA1hcV|6hR`$y37b>#cW022r|7uugfWkcb}EXz#hfyx15f1=2)V)QI&Bkv(ttaw zkGf)G>aJWazms&e_Ui8-UZnw)J`=RV3NW^4n~k46Ox@*<=)A>kMBqYN1LDZtc1n zEV~$>5{S^VW&z9AvDbBnFV%ba+tynwN+I}d0aP6D!*9om;`M81TW3aX6c}FB9(%Kh@#=9O{GD zFg`wFubX%|<0lj`@qzE~+n4>PGNjcPppx*F?XT1o+0$zBDg0ObYC`z%Eq=H0=xCe5 zv&|O0O}{4x!jZ%)Aep1M7lCQ-7Fpp0x!iZbowpgv1`I2Js%V#Sex}bG`fA{#u|big zk-0s1^t??8)GR8A&oW!}XPHfJK>dc~KhvHSa@#+*`W*l2hHn!eGWu9%nei>q z%zi<$W<;|!4ilQ8R5-Zp=N3PEE4U-+P;nuBiYU&w2Y%g*teXWRWOb_w=n}HB+s*29mavJBdma=?FxpS zHfgNwx@QPf1|H?(kShVE9(^2x1Muh7rmzzp@@??w7KzFn{>#DOSzH1~6{9r*em=}m zIm|lg#}i~0tU8`Br|2bL>Adr{p0Ts&NbvV8<15iE#mw_NCx!C7j>wF?qv)IhjxgW! z8Eg*Dm|Te!AEgekZB-O+EUC_Du4OxW@$FM_`-9)=B*{4=jenXPT#&DV(t6 zA!#ri4a=kDTg3Ytq6lUac%`FZdDQnKW0cl^&5z%&qpd_Fooui5&W~mp9=nDR6*pPL zbc|+fhDF3YE^6U@HXmFJ?Q?b&TlFD09_yJf1hn$Y+u24as6}fry+!+LtA&gTS_Y%u znuQh9IAZS^TQ#CIN}{yx?_vz{!db3AW+8L2#!8Yq`7VnB-n80&388k}Rt?F6F!Pn{ za>_Ikwhx^|1jhO3uj24+OXnZF?(YM1`s2_UIz0Mt41q;97*L7O(I!q0IaCZv9J-k% zx*?l|3>j;I4EVJtty$1f%V5;5aBX|Y*or{|i68?=@UQcsXykN-&tWd2Uho->OQq_p(<-vY zMYtFj`+kv?A$HNas#TJ93(iz-Nh+@m;LdbgPs<54j5WQ#9Gk`8oWJO!L(cWQzGt1_ zT%T0uY_d6T4Bj;ykE};;FLx4xY7_%RAdyaY>yqA}p*{Wv8+Z&at(-o`y+5aIY5aXM>qAW1S4}kyValkg=QcpplC>P z*-GXT_9@?DOhVCtN$9lgc7*@M`^nRL<#FV>AKY8vpjsDi$D;xdfX^Jy{YwoBmvrF)jmj3FxpM2amo;>F^H20JD@RPG8lZ=x?FdZtMG7gl&k1)a+IquadMQK1KnZb z4s-{XJJ21H(;em8jkd}U@?pk7ZtEz|p)`@XTn0GO3}^%qa53hBxosZ2 zGY&k^Ef)ybrFn!Ar7ys8QZKO4QXer{68X7<$Qe;H%*#rnQ`<-Ej6t~saOM*kkuj)C zV?-9fwBT!EKAz7f=6g9Jc4-DOMwI49O_33$+54L@qUmFs8nJsElE$})`B`j_^_X9KOkH&ibexr$VF!YZsjDcL#^K7yS((;h>S`V&Q`SEz9#Z_~vRrc# z-sL4TmZl_+E?MrR>wR=y8rseQqPOIecCW>>SObGImYU0SJZO*2=U!LXztSLr{w+PqMS zC=fB-i}9Eaafl|hd0bjiU@QrImr8DwcpgcVRwkjMv|No|HxoV-=~@ZeRu4=0~!{EbUo z>?}W)gKqqv;?YZ^BVj2f8q8kVXq}V-EyvShZimG1%Ah7SEEdbI4>=e1xBzNfCQjhF zwrG;Y%ypiNd}6`|lQLVZc(KlN&BX-w-(VJ}txWLXi1PZ78}Q$BPAwQ5($)E*&M{Ry zgrd@p@@rWAA9fmxT$)L?3KXLqWo3!cPFrv~+Qm<_ymzZa(s^o9rmVXWTf3-*J(SWt z%d3yRj!4-{)A_J#zC>6gb7|b!w#qqRZhSn*i&T2mltyEHvi-Y#bvfJ7KL+@1Ii^J+b z>OPv!U>&xj0q3Uo6!RBd2QCIw%qzZ^r6@$q0$HGL zjB^8%DJ;i|Tp`&lkvlMHCM%TP;WRoN-c8m|6B1f*3Zy)vh>r-RXpYd5))QJyNwy9% z3NNutBy9EgZKn*|HpBMNunje=h<7`%BUn2ur)=UWgji0GA?fx|^;$oPWdW`USSIYt zV3~tAQdth(=toOo(h=Wu!7`ay2Sjz?g{~8BIGKYL#4Uy$ITy zLS^i3AvG>gPSB_-ZNo;nL8B@!KiIOWz`9RB(l6V%EhJTKyWu1%OS2tEkwbR^GC3Hw zP6f`vaEU40K4XI4HdJ;IpfV(bk=3XykyWI!L{^c?jI7YuB9-xxa{-bRmAQvhN=a?) z1t~EK#Er*dEOc7SAGSy)A=WXa#A_^!Cl9+RI}tTnn5NuOKCIllQxg`~Nur{#G95=k z%-C>6kGN4fH$@NQHl3RWAKqLyQ!w*N&mZ$ z4mhq8Uhv%9u_|{Wc^;nAX)kdcQy)Dz7j)4yHP{GxLOSW zTdeWwNUDV;Y}yUO;ws%hseEzLtI`b=%MT${$D*v)?sarcVQob>&4jy2i!opBfLom` z!_W>zo7A>dt3)65z;r0yN!=nHny+)o4o%3<*aqI%MzZ*u%bA}yLaXZZS?)1*ssmjX5jD}8T!Ld~F_G~)}R4p%&Mr80p-#ZE_+HC%+5q@GaY(bSV>m@~Dc8HkS*TFnOI9O)N^8uUw@wH5uc z#ld0yqL%E{FN}5P#SBM<>NMmM5|aqc1$-NX;q9NX-e*NX-e*u+#}qhD{{ERK1f)od9UEc{Jk_lJIhoniJVLdHHU+Y-OmP ztFq`Bwq^lE&yB7RBmFFEd#!V$8>~3t=qUP2jSO+wCW^!|O^3DBO-a`pQOGFW&@Z>% z!b+GzhL9awLK)d%B^cSE#~9h6rxYzGM;$~uf)@mejrkLLKaE%@u z9b${pusOPx%6LaNN7o^CAf0QFN&I{slE-YXNg~==5k@FK4&|i|jt+*@{m~U64Q{lb z`k*dOM^{cGBDP?mv?Z&^*Ta?i1$_JU3k0vwFF-t~U*JetF_zdw8ApO9vdp)f2?mjT z0*p!2rXj&3ZY`7JzyuMcaqztazcflUMe{5%Pc=pOrLFqZ6yaB57EKX;RW;I*h?1mr z{ByMA844;SIAC7=KQo7Lz z@}L&+LfsTgN9IM?6f&&prD;Yj)3NFWVVaam7WM1M)6{wKx#(EIio_*%~=UQvHg3t{G#m;^GZjc`c??9C5CZ z_*ikZGZW8CvuIdLw_PUJ>eQ8xO&Io(Im|GgsV6-VZJ9^&7leNJ>dw4Cd~I>54(imF**AZ z^Q03K7=4+=g63>eZ`P1pHA!y0N@I>aPf`Fx7W0Aeo*Uf=qv7XRfUM7rZVHFP4V$Aw z+sO1xp9X6aw|P>fPiN63HdanI5R#o#tzkzd)A2Q!%syhCy(SQlN3aP{!jtrS)O-<5 zK<6qpzKVYoGF^)11)*7EM~&6@*+M9)Rih0*V#iR-v(GE=oHLhwAgaDLB1jp49n zk!3s7#i#W39@9W7)?-f}uooZLh6`P-Vvq;MxzJVGmLA;r&t-{8<3dNmKAQVuTxg%T z5Ta@WJDJ@QD3J#fkbPda&Yc4x+DPFHS80-}yAtA0PzE?qN zJ0Y=C;F%B-g~bCWgoJOZFurp;mD|;e<`}C6RDHlEP^nCHpN-C$bmRQZu#@JUR>HXz z_MD>C1V=Lzv=^zgvr-G#ZHT7kSOQ8rP*xhHg#yn=x(ti>=*)_wY$z-Zr8$v?!e#1a zg`He(*3(e9Ld|IKE6Qg9h3EN><(n7;{8)73B(BXsshos9igUdO-1G!Pb z4XusQQP@2F9IYK;T&>!Wo8ekrTCq#xh#dM{i9Qx6<&e%W<+Y59J?R!WpXb>q=>^3cMjF2sZHl{O%8GyBhr;^=AtL?uZ+)y zt8A@t@OKz1)Wo8nLu2z{%NWe`0Q@5Wt9}DzBtaN~3$=j?FOG0SZv)e1!7i~4y{u_; zr>JKMU1-dF>)v8|mJIOdDUnScl`EO)QMr=k9+fK@^HD{SeeZ?_z1qcLsb@_I?38*u z(;F?n#K-0G-#W09^j6&!Er+DZsA-GvsT&Fxt!M4rMv2NcnaY%?y`Pm5g=2&b0?jdE z*o{BZ93j3jy*WnAA8FxI?!%vHN*DggOH!iJY%@XQiuUJP15O47!@jU%WLqW5UCETW zul$pgJC_9Sk>d73QYoT{w<@mY@glFrYPh-@(Beb^gF~VrY(BG2@TAD0QraiDR1`R{ zpaStyc~Z)t0-hB)SXT7>wefk}EK*9!=h<0T2@Mu=V9(t?HV6#+D)bI<)59h}>KunC zxh^eB*EyU%{^f0$(xRBs@;FmkvV}{{ai%l}Q)-2| zDNKpHPbAD$q&*o^LW`j0IlPB$<}@Mg8dHM%!mY|^NgKCCtUNTu>MLW5sDZppep~H1 z#Nkd3l~cl@_6Sh21Ba?bW!p5t6*;ucY@kgJZ5JkZDu-!15rVgprn=dM{??j?Ms)OH&IiHtumtpGLSu`fbN`h>}3(u5dzYt zU=zze#jaup>|`l4PlYAtVQ`fpyVRi$lNx5~u$R!tNF8eCvM@@UmTIxjF6lpnwmm0! zfKD_BJJdGFSb;yr+Qx8z$99o0Aht%zqva%nQSb+L&>d6u(eUwGc~Gc6342i2SNM2w zib0Z%r9q}mMh|OnY%;JtY^-~zl9kw^ z$4%dvG*`rYprke0_Nx?9lTdKBpICY_MU`Rc;~!4!$Lb^ZXLE5PVRE&&^!}+D`4zf! z&@Ro@82&s)Dhz*VO!d4{_XoRwunof>is6$mS=Y#SX!BXP_n0L=KUE_)e_~Ub=R8w{ zKM{tmkE4@_@9#jlo;Sh6-gTLY%QyTkavxh^Sl%_LjZQ1ImNsBvxfLUQT}Ii&p#6>Z zvH5KVZBlN2e9(KtP#8WwXtsQ|xu|buf#E0j1tX;31&CD*+J>{29?n@mMzui?BoZ|> zB!IfH;&<(>4Vro0X3${_(*8#K*uiZEeOQn_I6mn82I;-ygLZRM6h9iXH&*T}7B@yk zDJYnPDe}6s9+DV})O^r^AI zcq{BrjuNiqJWV>&Nu%&EE@=Vgg?d-9~0 z4#S_%CHLz4vqS-C@mPSj5F?<)BL%c*LkEUtowg(EgbFd)7}6D0Udu}1soD_dW%nCa zv8(Fzg=!EsS@bdbd}?v~Olk_5NlobAYHw`FmRYGKA7}5taPAlYmikAj5EYix}M;3(u1n3ZcyQ=W`wb2BYCE`mY%u|B7J#iH^mT; zoFJZjnB8PqQ+ktQg1^ZYVPrS4fZ`aK9^czX?sA{bDx14pcAh?OGQ3}{n&_L`&#FEU zJwYx@IO2x)63=!hU!USDv})bOzz?;6B4sqti6q0zCFPaeEtiy69>8+vluBTyoo7(4 zd_an$Mw2crgi}*A>CAOhI^{fUoMNnL8MSO~_15){GZvZBF0JH#>||<%<54iDNzB)f z&$BqjdotQxc8Ub3G%(EXq^DqLC#Mm?+nHo@6IivJx3<<%;0Pp$u^v88zc>bMBY7Nw z*xCe5ERnITM8@4ZXFY{&Fi#Q)1*6RXi3Z|(GoLA*X2;T* z!!aG=Ika5G!qg`c8o*fsPMf2(aVos3gbA*e^tsVfDPfKKq>opxdZ5kC` zyUuotP#3uhPtz~C414r@<$5@#-z(OYCWLo$Jv>#vxT-!(+soRZmIf{l6R zrI4!f)Jh?ha`-ff(J{P|QB|augnPQ{BIsqiPFpzP3{gIW)w$6Z$?JG-^c*IZ2m=|- zq1YUK;W*8(JxD_SqM`#O1VE*y?^q12(iCrq8sYU83T}t%qNWJ_ky~$?q-loGA363$kL2SS{T)j5 zw%y3q{ z$!zD9D0;pK*6PXn*QvEoYhkU|#||*J6L7sQUd!N`2A09~aCTROYZ|ETig2x*u_atZ zOJ~Z!WdfrM1G{EX-!vTCF5OqQT(1YoeF9U@jgFg|IC`=xjVHiY8lR4qaMR}KpNtbF z8&k#JQUWYZsuqW))>?2h^%?svjhmtiQ;4##yjJELkK*HkqVh(zFmUq#@HZELZ3ui@d2%#y}*!Be97J zB&q2jO;M;$p~jNm(Q~K9!2O9DMP~$zjKb9Fh>NT^FG+D85v^8VkRhGa7HSnYS?kTQ z1JkH6DQW^jj)N(BCth8lUad_)OMUJb4omJrth4IePjyQ7ZoJprD>e>KQSUG&*o2 zjS9a^0xs5K(z{t)GleK`vc;Y4fW$P-6Nzco9TL-gEg8|Wkj99XO%7SswjP#}q|7}i zIU$-LiR>v&@5K;hLNLvHgkci2YKkyS)1jsa!^Er96k(VP&j`bubhnX|7Xeg5T7X(3 z%1flhs{#h~RkEh9k|}*97*1X_e@6Pl>YH_38qnFKMnARhIV{}1Hdh@&Q>f@;N|VVf zO-QqRR=3ttruaT`N5|H4?+(Wj0@3$z;ZBq6Df&5tAqL?*%azLOoSMEsd_;>k2jLkC z7IwokmD|}5C&=&}CnH6jA{k|iH~N(ma=vnkEL6g8P*I=KRwfiqV92^NbBdU=14x=o z!zp44Cr%MlIB|-Y!U<>I!FaP_uGD_e$YR!)0+pXPvBeJvK$emEv6--VDAG_j}TBjN{AG%n}H-y3<+u ziadBM@v>I8n?$6R7F8Uy*3|!LB$^Xnglig@Ahxw3kp`N_w{WB!fYdf9MQ&{kEoz{acu^0r}oD0w1WJNWe&2ytK87IoDpx=%%8bKyx>I5ab zQs2=sQ=bVPq;cD##R;NBMjaKAp;#v3v^W98YViSx(>#|DYw}nc@j|SFX+*ho)WGNJ zVq{zDv0xB^m&TI;FIOcaQKkvVfS0C6O(pOm*l3z6AM)&OkA*nHnSiG0)j%^N%3a}R zR#}A*ZU{%rn-&Jt^i-H0{Xs!^IoiTL@_j5a-wELqwcC(6=fdukme&nOb$*D&Mq|Np z*zpVGw%lUT3(Em48;?3c1n27!eOvUxeguT($7-)~rB7#PxpIR?`fsYQXn^}t&xtpV zZfu>bzjZMj*KnV#^-SUE%E5y(XqfxM7iiqdz3YT0YmC>~i8{{+mcz4n&QlC2_HG}a z?AB~}dbpl$9n`iBcv-{2P3{e36EG09Quqvqse0gj( zJ-4pdw4J988ZLOTo99#aDwuX;)nIjc#CV2pOsVsts^rJ1!q+!oCn8Q+?q%=0VeEZ3 z)!%nw?0q-Z-^WH%FKgx@=kSzk6q^q$=p%molsw{2{P-zVLV?APpHd|pTw(;DP&~|O zdVHJj69%7lvFhAK1ivr7^OOpamqa;mM=WElQ%jEny1EqXQn!{9H;3Puj6dJUp~`Cy zy8ocvKf6ux+q{zBW;0B;g+~jP*WMjZegl2MuFhEEo25CD?c(Kh7oh^n@k68$FjSZ? zv9E%Fq5MQzhXbZ+*|d0$mPyNRl*DHdLx!rY$!%!|i-Mq`EZ6cjf`;-e;TGROG~`)g z>VP;~fh(#H>+^LwxLekIiS;}!o4!#Pbiy#`cnujl zv~uYtyL4R*8J`?(5HenG9HBzSn{@vTcK^-WAma@}#+%2H@uu)(ux4x&kvRAa8261E;rel08DVmV8#YGI8dpSWMd*@vrObU2 zzLe2QxQ#z73GPwNNj)=Z9iUK<{BI#qvj$K&%o;!eF;5o?37d78^#P+6I z2U{s3CGuT_b#R%Hu|&h|6_HE8&P)*z--Os>45)N2U+>(;RuSFcEGC65i<{hJP%yK2 zvh$S`04tvEd`02Tg3WWa2U?1R6~%gVNKaA!O9!sVzZ(k3{|X)U?Qo>SSvyqeG&Eq{ zaHS6C?eJP1F4*BUI!w?*7to!l>rCK;X?IQ1&bj!u@BW2%vh?lRtSOoRS7uF7i%f;v zGA(kH-4(S+bB&j!SP~~OHc@C;XRH{Us@CYZ3Kk=?WTjsjZVbma@HyWYZr&K(I8J1{ z%8`z)AgS6F*3q?PQMu8G(lW92n#z53bqSQwlct&AxRWXQq9sorQ)QXp)jFSB57+3I z`~%9GSxog>{dTP+3}Q^~X!y2<;xPdM@l0)?g4&rv0L$Rw@XGOG0!}$lBAjxdL^$O@ ziEv8OLPwJ)>xyY`n$Y$W5=p3i7J#b}S@Na2P$#YE zGsw@+7kK@#laL-~tI*H0@MMkC&w+}5vK4L1WhYq1mO5$<=SWJ!%2ll8pcB?IP_vu_ z=*K+2(2sd~p&!dlfPPrnX7pp8V(7<&8uWAEVn%$1Ivc{t1duq2904ZiCx=u7UJj`U zyc|*ycxeJM;FU0{fR{U(ry`$p%8MDBMJEK!8vQ(jrwhDO(siE^F{EI3O%aX>Db|OH zdJ?Bsbxo1cv-KQ4u0F@dab~(|8}n9ElBEiN9}7>yB!@3zQSaO=j!Wqp+CrysV?rL% zu(Da)tXr1smby`~6L4_Lfz9F>(&vU_`W&dtV%yE)nRYlX9SA#R ztB&h+JEs~M%hKiG&Ksa@BP^SdaVA_N)0+p}pg6Fx30CQ?XTr7Nq+hXu@hq`Ln@1;K zRTUEwZL~UR%wm8&`qH)|Rx_$=@8Kb^*_{lBxnqgLcxj8U|u%94dY;zQ*A!hl+V|s1-{V!Bc9QN55!Qit}Y*&^bZJ zh(k`$kwLpvRLYddpsh6u{hUo#(Ywf?SH`(7bw!eLau6s)=88m1hoNG`ixtZqR?)eo zY223#G2^mis3b0H+!wBETox{DnPYHe3yQ;~ja$Qomy@s3b(rbHNx{ex5*J}2Bu*_R zdP$=5;vkbIPp`kAuX4MwB~azucdYo0!bZM|*f`;$xB|AoIn_3jw(s0+7*4u3vm-a( z5fRjvrb0d))#T}fFECFZa`zOA(vZ&^;xJ3@>_Y^HllbRQkyucXkvi0jBXY<)RhNg% z28spY;X|V$VnOS&dHq;(DUGdS1?e%q>RvxGY_tlL)lTO5(;`iJGS%~ETSoNC8j7yM z;T@3*7u_$oQzVJ-(MSm4Y?182gVTp?9!=s36LpvJNq4Dky6PM!+6ST zJ{BhjMlltjTLCdwxYL(GiV1Zf*NP)T=34RAy4=MfEt zMwd&4VoOf2#26xfxT0JoN^VTaKt>g-KoF#RudcYpR7DMtSXcw7n4$(?%+LWg#xekp z89G47@@%N%Ozq3I>Nb}l`y3KJG#`}nKN}CWtam>4cUwg*K`mnyQxvrv3{g=lZD{6d zYbKuNW=mFa(V#L^tA{mu^;P%B!_DED;XrtXueyKcDNuabsD4Md`4mXMVki5;@l#=6 zIOwFmJ3PY{{VR@VirWPB@6~G{V^SAcuMedwBJZS^(iWToxdG}X;4F5qdx9OXUM8&Y zo*kZS>DpzA>pDgA1~|hGy+J*k${!Toai&l`d#nt7(@S&&U(NvBqvEh5QT4vqA|sQY zN=MMZIaHk^4GgnSHIbBWfbpk8OKI)f;gx=`bOiH(_&zep<|ne02!BT^)Lz-qJCY=- z?CAfWy>|h!>pJUv&$G|zKK(d)w7S)j>~*#zyJbnXoH(+Q80d4z!x=J#ow!`CTihzw zOzuo>i>gV8XUMH9+X~(7SVIO9AS6H-OeQ25z$B9}5Fo)y7?N;-Auy9ma(S5vGlWn~ zX=ri*^b{6r95-?dY`#YfvO6|IP zM9f^!aR?Yi^D)%GBFBq zDYvMahtu{C`PQMd38lQsiSSH915@WqG%yWKMUgwDfvYG2X_^)lMH-kUO+^t%)0C=c zEO(t`Jcflv{DIn%vN|FzfuZKeZCjvP*rk+lV7R4Zv9qj9aGFt?2q|gP5|74RQjHuOxM4)=B>haAxMX{@w~I@1 zlCHYAM8l`-1tn(M(NQW&XnTzBVl+g6+(itBX{GE4xK9Q5k|yE~;@a=V7? z$nBbBI!;E5dZUyg>o1``)br~hdeBA*E~m@Wk>Fa=!hh1(0maRO*BC|dOM38>DRFuP zz3oU(+#2q|<48}P&dGE!R_SpY&}?(oDJd9)#kV}0H8Bz|W zjNKP!>^h2sY-5t_Y5qTU_zwC1IABJSsH7`Tgrn>D9;X~gE|nCf(?;aoi%%>m@^&?5 z3~nHoFT!l}Z4+N(TD}D9KgOUeB-(B z3PcLR4PSCDyo@1-mk5H7TEdrI;Tv^x0!mAj6S}@_2%MLo@nvv6L0rx-I3L{socD`k z9UTSdQ~D6?7TS<;tP^morEmg#zHJ1gPdu0{ks~CW5UV;tt{v)~f+L;67JXua9+j;> zOFTGDh5Z}7{i6#0Tn>9Mq~ykekLB*brNSLpij>z;eGZuT3&(IQq;um$NbBa~LwYx# zpLXp*(q$GmPG&wo?%A4RoD6AxZjyC&I4yzbcFcITK{id^B{|j=!*GdXjY#c4`6HpN zcpVVnkOjj>5_tfRDiL+2v;(Wb*jvN^iG7ISlyfmnlGDpX`J7t9 z2f>hr2W}7=Rl)~rLs`ZAUD4s<-BURv!?kd4`YILLohP)Ft0uy;N%{3~2Kr|~5%usQ zE{$x~!}GW_vRMzea%mJt(d3bA*276IMS_@^<6I`e1|&=1*ho@-qOLkNII8yrQT5YX zk@FIosa6!Al22YmQGiObt)eJEnXfq?{1s48Qv`aQXNgdxy=o^Tp&&Bf2nCV)Mkt;a z3B`+|CGbon6h!JjM<^1rD-nuPZj(IFjEucbFI?n_B*UehNHtv0iG)LP&GvLKqsdQ3 z)5%;>Fq?AJyzrRf;Pfdauz6uQ&`mjRURaKVQyLr+Z=_T!Q+C2|=hv$>(hEI&xRN#c zPgc(M?|*$(=iuS`Na~t8sdiFSw2YN?<=ZJGW~nRp3I#=$ox1YtP*P;ssaq#gZWU`q z!mtI>nGhXBr|fD?gW@U;XxVPM-glWr^DH~cuUHSY?sp({9;tNht5zRYq#!vnVe5mb zN8gv#`}GI(;-E6PSPA47-*_<8?mFlz2;BTwWLaU+DJ(N{?HHtzi zs&x-p!CR|mGkPC5Uv|CQqQ^h_eHSa;wo<;)R)J|49S@UAQa%VPmK!rG*!qkE8 z%nDNhSk?QD_3ocRwY$?RH1pQ#y1uzu!}@DUicVAx@a}0;8YAei{{wnsGsukT- zI=9*=`)C#yE8pB$t5_bS?srzR+G)N>M^4il^{3izKCphe*6w_ZflsK=qs)u5>Uyuv z@>MxDux95RvwxEqN?T_odrDXBctsb^_E<4Rf!AiMP0c=^>vTG|8IPP>!*$E$8rO5u*x%t7K8JDQ{Nb@KC-FH^IvIg43@3*{Q0LAHU{lSHua$W zsIn+g!1c1Osi*Q)u6doSGmma=Zb~!&)YWdIXqU^>t}csq8>My|rFI*6yENtPnxjDN za*Af^uMX6V{k5|-^ZwRL?bb`}*7J7jsa<(2YHF7w!&AFDJv_E+2Z`tH)=KTxO6}J2 zc4^A{Tj{*{Kjt~oii~BREp2-?GcPadjXOAV+*|&}_9v;O^d$a5NMGJRUpw1hdwmu_ zED-K=?WroimD9Da=ocLN%c>KGiZCyP{#UB&K-B5ltQXfP2B7-0!Z0s#5)%67tLxbk zrOfG)!5{f9AsX2?f`1skYPw#gtw2Gg`#qc%p_?ULi4dq^|A8=ZH{6Y6)J|pwCYmL}1acB?bUq&p4zC1Fi*TX|<-* z->CuvxJ($J%K~GkN*FLz!hoq9186E@0Bic#4?)YmTeLP_zm+g?aa9(CAEQN1nScP+ z$>|4n7aOc}68a`y{8eqr3=(crOG-pE#YJ5P{v4GHv;DD5t|e)~T#5D(O%AQQN733H~58%@BS-n%u|D>zWf(| zQL!*y4`nS>k=F2AiXQoIKlcltwU2+|@!xu^W%9jrC+St`<0Ee=AB}lm^sP^R_fP*m z25hte>0wgAF7Xx-tp12N58nHuKmCKB#>{}TP)eJ^H7@ZUN1qRV`DcIdyOOi%Qm?yv8E^riQAWBZ^Jr zPb|Ho4BUkLAhMGJbnwJqzxQuG^iyB_{)-i@T15`i8pJTG~GIWO+q( z289;&*MIXJfAYk`G68U`5cX+X$1lC>XMg+WA2zjLwq=(6A-kEuh%|WkRR^~CX7Ta{ zt7Qm=>OEC@e7k9Rd2T>9 zQ9zYO4TtrP28(WwB^4!pP(5c@eg(9F6Hg*-Skn2HT`XM~Zrl7AZRi-`cZQKw`xmRG zCm8oKMlow#OuR`nUxT%cHl<9TVmB;Ll;HK8y)jy@RA1b}tUe=YuTz)f$Oe^dOM;omO)5f;{4grzO@z7ghm-UqS7(3Wfv z^E~SGj)hL-b{cfYIiU^9OsATZV)LO!3VT!%phS?$54--b8y~I?y&3%Ba(sAZ=;0}m zs}iXqjk{(_$LRphm!eRznTUiXWXejm(hK zD(KreAsSR7uZu?|(I8>8ycz|)8mZf&uJu=x$E-#8sS^p=*0Q!;(;z9X64?~l7->?u z>!@VMbNW;im2%24W7G;V6laTWXbk#`hcU0l3EBls(f%tY3YyZ`MpG7@rWhr$BL~b7 zVD?4kz^IF+upkSfDKvNQ5KV|Qg2 z*_BZ!yIPZlLRG_ZGE%4yP`TxT%FT+(Ef-X7RN2${cDqZDhR-kUJbg6lZvvqZ|v3+)jXFtxCsF%LE zW-5qc9DAqD!HxGD;<#wrqt3=Q7=`BsinoVwEI+y zKmQzomY|WXBND(oxH}(}l}?z~I^(1wBS=?V{@;D+``$KJQdFYUZ&^NDNl8gMh?Epz zAYPhWJ}`!t0#3*glrv(4NhM{)>*xY`!Mr`vCFhPUD&j@hre7e2(3cakR;+sAQwbYba2Y8YXxUpE)nGIB$9fF?%^MJ%0q4*nTKrO2owB3RpI zMB=^D*N*_xssmG^`d;Z9Mu3R`-BXb7y#!;qGgHoIuBLR%qj@k8Pa1?eNI==lT8@R1 zOHciW=wM-;2#;SwiiKgMAQ2sy z<>9XdW{n`lUWWg5W3Z$Deh7$f1@SYGj2YK*EAkR`3m4=am z_^Sdb5ckSRvBr~(?Y1I`Yfcsr2|ubcLGFmNZ?p1pNyZur?9&a}Jlx2A6^U z+b#$FeTV)*8Twx!=s)wcp&yp8GxQVnsK{>SNn2J6{cvZNFarIsgv&!e32em@w(*Wj zKtC*DQtkmun3Q|K5+>yyu!Nj@6oCB{>;6P_jWyPWMJ`kMh2E#p}$v$3;^!skwL5gu$>ecK(I-X0Ti1Q86XamA_HXN zSwIFR-WfrPe|9!-(#pjIPDWsGNl5#iodKk+XiolD!oF}wz$m^nEc$$vNdMyHu;-*> z4}N_ND^c*-C+sUnug4S9`20y$JUPr0(+&N}k>bfw(|f)6hNAe!Yl>1= z&tE1&De;%*P-;ZFIs*n|Bv_DibtWQ@q$WvM13i0zOIL&R?1he6eLZ`TBUe8?d$FU} zE)L^hgE$pPr6|ej_Edqyz^+$3%gpH&mqV{Zj$ZrA==BeTUMK7%6wvBa90O=|3qylB z-I7WUldZ^@)2*rGDEWwtIo+H}ZiM8pld^a7HN~Xom{StJaz#mc{7CU%O z*)FpKQyV(kTxF_3GZ|p8=IbPBX|RcI%cJZXvANz%BhKwKZU<^b>kn?acr_h}Wiuyt zVbGB*?OY_83!H}}JCK~$3xYgJ)DAOr^D04N*gd|H6vbAhVI2rv7F}C6ju{D3g zoLf|nE-DjwwuyomREaD+#y*{!&-I?qomtFXJQ|X;qHW!u3`tti3hz&bBrTb%y|^rC z!6$A7#g0F16njpI!N(d^LfM1Awv?FT;g)l~MciQf$-SQ}NY4IK2wpWU$RK{ZFuHWo7wzJGXp4G`E<5pa#$hJFZxRP7F8F^u`2df!^ z8yezjvL%`2nXNPW5T93@9I30WcpsDzmnZ?-W!Y;gCG83u+)sK^-rWz9>GS!R56Q2g ziCVFVY9QOuhkZ63t?+!!+G0NNc6s1)+d@!-%cxioQM9xEK=isRvaIk_;e&_ya= z=hJX87QGweV!Wc>jyiCMT#Q;kJ79iFX-zqKV~Q>LI9_x^5@&9DD>VWNRq99CAL2&m z{jQMv$NeTmRUG8Toacu6a@ODy)()uvd}?s4N0X1%=|x-p zS{c0iyU(8wIvi4QhI#u9HAX#P*nB)t8~S%nuTiL?yB|N-A$z(d8(y`suzgxXxXEr> z{4%g+=rFY7D)(f?Z03qXOLS7`&3N-qGa=`26N2GvGp5^o+J*)NQDH2y4zm5(sict# zh+&U+m?|R{%``O1nex2-y4t56@3v!OR>W%*>603o2^?|*OXW=>ho>bLI-(Ba{gpV9 z*ppHiOCXV}RC$Rd+$7&nhSOK#jVx52X?WPzE6t%5WrWd)wV?=%u|6+kgqVtJM#!y~mvIE6OI~|N@Num=K43x8 z@hHqF1+6qo%jSpcSCEuv^TYKkNLtlt(q0Rao+U>w z;utK31>e!fYm8cKzhvqJ%fzlJaqlo=!6uWC44aJb1e;85{5)(})jN_SRPU(aAP$3s ze!XjJ)qKtt^VPG(ECLOVJt+l>{6EmkWLfz*CZI zuUz8e%_K2)dQFs{R(PQlwPtvMvX^M=7*VCewc_p!q|tq5o5J5mF`Q1S9egdk7|(h{g7EO`uy zdj~Y`T}kK_jVVQPnYgUQ>Nr3_#V`= zDEQ`C@T1_XA7_EvegArPG`+qo9G5$!_~J4qww7Hn)i3jK`MF2h)} zYXSb+3K1#Yh-j(>0Nw8aOLoUS8RUB5ysBs$V$)YkX&q%0YZ5Q%S|&J;QB1}y*@oiA zEwhc$jvdjYv0?wALuU9w6NP}xxKT{{`T^O7c!pVPCASTcjLeK;4b<)_H1T@xpio|u zNL5a{bs-yz7zc4m6JwVUlv~0!p*f;ooFC42c)*PgkdkMpw?Z(olJhU~gNLij4?#%m zsR)E5RUin;M(*-g%0<4j{PjYsFRkT;5wu_ z?#UHxlD{Pv zL2cxNhDgMA)1E|)5mA8p6edwXDK*_R*y-(qj-SG?c&n`D7#&5pID?L6_v_%jQ)V@9 zVpQjbw6;`gaO@rJujE$qD2g~`Y=>LJAt)nMT~rB@Zc>#|M$zbl`bu&aP)d=x3zXYx zrR*-?87&s>f@y@fsh$nFa23p0^X@8;h0mxW*}h~rw-k%aLy0QFfJ7CW+C9T|H4(tE zfn}7-)aMFlGW5COM&?0RK$CUC3E)`w=yRsOzpoO|*M#&#DrfEEaAD)=OFu5~KprIh zxG01PUDD64OG`idE+PF03lYa?&7>cbi71LVPLomknG=dSj<<4`U<025I4)biDSEl| zGh;%O(lW3M2$BJwi^iF$(WD=on&3GEz@(pu=XFUx;Q1MT*c;2PD{V_%<%iw(fhA-c z&z(qC`1kLWEN8oV>b6rX*)a7P8qO`9RJn^O=Z(9}uWAn&8EHWo%`?(7w@=b^ znaft$H)3icH8q$r!;x>q-7)w^dTq^FTN%)7vhL!C8NAcyY)u4>c^d>$hE9h*i9z9X zeG&RymUwVlX+-ttOd$U)6R_Kgr@|R8zFm1lDdyT}vKm(=H-{6=C9NqtVD(`Efe&-skd2uPI$%4=>x(4->%vJVrpIMezlTB@rQo_C&SW2)n5Muz)D3RRZEQmJFY^O3S9d zop-*l)$i(6S~e_BrqX`>|Og zr{O@wxW6&U7EsC^;y@u9iU?(ABv@OpK`+b5P)}~qaEB$tn5}fU{>CE}2`v0mnxGkQZi!!|2~ye%1z#xj#XkOBe^^=Y zj`87`AGH=UmsFHWBb%pRJ^{*M!rij|5Rpr23njKtY3NtF-&ZA(dW}d_zxG5)fqWc9 zK$Q|DEh!~PDN)jrGFOxmB`qnB0*RUYlhRX{7`Z1`SYlG_3Xz6RcY4_3Vltx&$vfyB z6Okc+S{69+Y0yt;sCI>1r(CL(Rn%&we=*N27q6A+#gbi;p_4Zevn<)A<-An-7baBN zul>-d?r2dzmugN4U=SI3m9J`|Jb$LHtnsd{>}$(+bFMs4pw25l*0NudT1f-2^0rPB zX!~_VpeTVF`ynCXNjTVR(gHCDxwz277DJtkpJ-z|tf1&edq?<*B}e;DYAXIkx?ioW z)z$6Q_w_5UM4sGX-1cUubRT#rVRkjrRL!Dy5H0m!Z=s|kG=l6DlK~_v30{X^g&J8hEPnU%?;!tH z_;-MRhrr-Y%sGJ##BxrMSzL$Bp>z!AoR~^ko*Dsbsx&Y@4ik+NrTh(&q_^dqNP#PC zdy8FsD1$bT1YDs;niaI8yb*=GKw8r5i$#;^n%s1fxQpC$V&ocpsj7Tt*i}h2=b7nJ z7{QpTc-hG|9`>KJEvi_|o>pD~+!USq26rz$~MnC0apE2Pw-Y7TY> zZN`&)UTJM0(@wr6I*H0h^fTc}Po>rsTO!-W2862^ zJI(H<98+{9h8PQ}9bHyQP9%JB1d)oaD@Tt4IfhZAK#XCuD3D?pC9W1B2zb~TA&7>% zdW7&KEE6CE&caC%f+)F35rQbWNfCm>Dken;&Z~G1A&91!1R)H)jVXVvuxzmR^2}On zyXK5vqD{I&PBCFX;*4F93+G5h_LoZkVo_A51MeZzDSd@@zEqLxlCDOdFTmdiWT~t|$T(E}B7M3C- zT(OwjsS!r#2OGiXh}Jgk$Qe=c4u~;EMwr;xNG3*7+WP<>f=o98ZadT=xf!sR#gQk* znDYY}1o2U#;dn-+JR>6Nku&1Fs`P5ShNNiqG)XBAPMXw6Rry*tX@=-nh0U?UA%1>L zRh&$m)hoRTCq7m4nA`2Gl1YTaehHh2$(Pb{7Okd!AQU03ATGEi4UDyI=pCBS# zP@KO-fQ_Ko-?9)SUfC6SsbLPe#fHEd!Sb%C=HzM*Ggel4r0#Tg0DZ!qb_RV|o-bC4 zX}&z@%NuIEJqLZP3kr`$E4&owO9lk=x8X{bc6iWd8NwEab&#`0& z&{w`4Pq9=~vWZBm4svLEBj}T*HwS${L5gVB#7VzL#`CnUtUxmS+jOxUR4v)Y%59nPllrdsDF(Bpd^Fh(B}$5?08xFNxX_1C%NPfC_wEbWB5THP?&@rpJ-Dd+n=% zeJpD`!#+l_>#rL25uz>+``0rAh)|QlK7#6`u#dPmDeT+!)X6x6Cs=Y0QGj*gJ2_-u zHS7nI7lx&U2>UTjijZqqScu>s6Ri02vaH}Vc0O(x_UC1q3Pm-ZW6>%*AOYlTI9lcE zkl?1vA;BI;g1u!VV50>mPMgxq2Ct-Ev;RxFF`9Uana3%%sFFiPmZnAao3+Dn>2sQc z9(r}80vv|thO?)|QJ~8^V-?i+Ym=iO22P4q2!xYj)z=nB2?4Q&1A_trN}C_#mI^;N zh3mp9>b~^skQ4Yk7*mFaa+(3K0`F{O4G2|{HNckLf~hct>5_RlxmjllKHwFRwMfpv zCuI;Vm_R-3ina$jC)+7prJ(#0rrpR~HzTv^U~h$Ym?7HT_j%6z3P&xQ>sR_q#<|7e zhKOl9OXQTr?`aG8tBBt zbC?UpJ^Ls{oZs^Om=ATetgCpEiyz?7M>gq5GUk(&Y)Znx$`r5LSxt~> z2MriaN-lnTmt`jJvLB_ew%Pa83X?O$snR`=O z-Kb1+TCi!-^+7yy1*hxii3YWF=1M)Cxq`6cYDMZOXDb`{aOO(tqifXZL`a+yH3K-# zT&brsR}j}-RZdFnIi2cJ2`Wp~s~&SKt-1_FmG_w|xyiS~_!uja#mzr<|S~dpA0yT~v=}uAqK< z?%Jds71h&<;w{l~>g3*{lJzIAv5$UJL)FefteVn6nr5g1JB+|1`463sfMOn&O8WO6 zowQ;+VRkc{)jV;Mz4%1EL=(gq(0A|UYX#x3fP$$ot5XyF%$2U|=@_WXFT*TAe$fd{ zZSnp_HamPiLXF5CJ5hDPNl7g%z!~r-N!XcXJe-@3I5}rH3G8qdynvSHV6Gja9BP2Y1m_^>*hXXWE&a5C7k&r^kSv0*#fhkX z!XtJ(o!&N6oZiM|I=xMo#p!J`rPJGHN~gEYSHwC%>+3c9NEv47d9ySNPT$F%egx-1~^w#^i z&RSkSku%l*6;s57)(#zQpviDIuwF z$?}*6L+DRZmD2D~-b}V*3rAA;6fvWDD7=DjYbkSO0dPzu;`UXkQ|NeOD$SVA6lM!$ zZA>NhKB%RV3|Ul4^W2*?|0cp?oOoLcNv}v~oPrihapRPZn`il?-C`iFCx?b&H0ND7 zGt)9^QqvEh=V-a;U$N*N_bdN1H=-5MJ5$N8;&D8t9GPJY8EnP?ofUC6id<=IFt*?v z;eo~N@RXw`ZJ$d_SVD{@Jk;oZaFjOID379knun_Fw}E2Y9h#6k>NhBd*h=0Yn44s;!|oRqjlI zd~NhmtB}8gka3pWhc<6|RFDhZNsZ?RG`xcGLu$n6F(xU7&t?E4o0>-c@CCAGS52j! zwGYLB3b!4d0gw`Tc;;zXHPSE+B6S)DG+iqimUKX)VL0d943%`#AsQw{utc8ZpM+lQ zOvBh)rAlZqIa%CJ=qxDva)ge}bZY786S|x@<%Dhw4Vx=yn47G7Rnsy7-ccGRpYEK~ zFbL-(p(7e*p%!-PRN)91qG7E_x$qCfs~C$oM8m)o31EqaL9=XgpYTZ-gvG?o`=VjE z+M){pLqx zL`ylBRmG}7S?^KeRGxOT87@sySqwv8J8Kw-QM~PfO;-Lfk9KsYZ0o!s(Ls zm`d!Ry*y=Zxd^&5x9B*x7%QjdlU1NruZ5M#)@UUG{$U57=|vEkALF~Y!udlPLZ5PE5g+1uVXk||Xw)1br1cZ@zD;ip z)ooUIMURFt0lZ_X;$IBxTHKZzcT82x-8#GkC#I91T&LaM0l_LkFP-G5Og83L*Y&P>682?p6)y|=P&dDh-XX2UxRNzI26Rl}#L~v5!z7m6`tPb!Zn8@n@ zFM^3m44kq$z>Q!kuLIl&rYbRb%IW|=g2}uN@N)`ou;98aB&Mb*!g9UI@=7Nr138iu z*#=BME`^L>Qiucw$636Bxg@Q*8fua1;6;HZ#3;fVGLxbRZ>G#Qub_VBN;myVO7aaJ zhI?bEB2UqnWUZq#)7u9V)8;@lboXuZE1OEn-mDnp+3_d=2q1>-fD#^d?I@8L*X2r_CPFh z>`A~=^fd=~utxw7;VCK!_?dJkSRhRaB{0_HD8aJL1DTwgVvtr#Kp{8TtZOl*v7o!) zY7%4`^HX$dXejzM!j9M=CY1=0C?fG{%AwR;VhPArg?{Wt5c;hqlFH@-pP2Hh|v36C%t^yY4dLxrCY3aFe;Z>-IOD^l(yd z*eOUer1*?<-u6`N3r9K9b$g>khjeE`7S~wVvA=q-T$0`^fRz;*SAev@>Og98dhnt8mQYD4@O@*6OJjHg& zlPJroK&&7b-U=r{T&3Vih%a9-H-%^`wm~!qrLBn4RTXJ_0pBbaL1UZ%Ad4xCY^ujQ zcp^x{BNerlGPUvqZkKX1U zFm*Ea2cAyK{-7w6Vm~xxQuYTmoD}<^i`N+YFN^uk7M~T&hkZJhmSiu(d?W!L2>RO~ z|Bd0e@cL-DLC6nlDv;kJ)rn0$f%z{X|8zK^I@8dEgJuvjdm6~!A$Q>j@?+Zs>~qxY z=$o=5Rzs(Z=^O$wiv05>($ESGOPi^xCEH}p|Qe#R}) z3FnNWrmGJUqNcn!xP;x$s)-!$SA90WYo5yS-zcS9Cl2~C|fX9 z*$PKrB~c@kD^)FXqqmh}2+D06#<81Hp=LpOBG58(_BiH8nKL0_Iy+~HUv8>)L-ZOq z9LDt!E0%I?lJK?`Q*16qNe(;bGCLab88_;U5I`T6_3 zHG-|GihL9~Urgkjaypr}Z;e@KUCtfop9M_vNwGy%w8MU;ed_g%HkLZS+}vO{WDd~4 zY7A_TO82RhS=ti^mUAkxpc1fJQZ#kB5Izl*kU&*f9+-t~sDOdB0M;gxGzG9)s<;xL zBA%fbm`xn@Xf7oQup(ZgNb;@?tO}@-Cqb}P6N=&{6I5{`Hp`2_USI^=XafkoMLc%~ zT{sn0%qRgeWr(9#utU};N6~JvoO^N9<(cD;knk^^& z;^34jzC$vqYeBndLFMcmT~KOLn%KQ9s1mN{3)7iTYq4G zaS=qKi>owAa4EzO*Nc+yf#`vX)`;SVMU`{EP4ku-cS-GgXM+^l_thJu(7v}x72C9L zsnlrSlgbom-;>G|Xy22{6k|_o+OB=eAcgjQjSW&P+d@Fm2H&J$B+>@H<`$if)DSF0 z)!ae^4N_TChUqf>%gIt%4>udpkoHZ=sWrX{n=|8(h@+k3fc^MR%8ld*u|>7`iS{Bn z=oHwe3eYghU43q(c+>kx%>;rk8@BJ`mzzbqS>YFgz6Z?SuhJzW=m)s*WYBvG(zXJX zA0=)3_~ObiY18?I`^rTkZRwDR2FgKATWH8>X`E_LB5agzBW%>uSYl&PBTQXo!q#Dj zASpGa7DU5x+Ao+4%i4&L49jWnLKY3nIxQ?2mQ$Rxj+2n8pln=A=^i>UD zduLSxh`xGN1H7C})c`BE5rx8fmDDnePJ@0-N*16Xlad82kCT!GsNgkLHEL`I65e7p zL&}Txwo(j$thgfEj$)sAa0lv0pnsWQd5ZgFc8cpa*%*X@_qV=Y~>`Eh~05gbUn-KOccx z7KA+r+_p(k%7~<)=>39R>D*AHViUMM5KGba5FiOrb~c1RgBnG<1y4=ju49Rq#%R&# zO^cT+fXoGM)25=pt=U7;me|FJ?9>Q({3Uv!sW80QBNMnGjbhCe?V^)IpYSg^^dXxS zj%a{>9XF~*+AQ51wVNitkhm%&?x0Ff7>VPk%1Gj>iNq;KV6`A|reIBJR&xc*tQ^vZ zD2&T&Vk}W~F2o|e%_4wI5t-8gcjh(hY9euzZ&R5MSAAu>ro-B?3j>EDMj1J4jIy|f>t~0E98WIMlSq%#hNHJG73qF=1 zVSZ>VyqV^r!z7i)63-{_vFx^y^tuem&L*|7Bcr3Q*}!sXTW1lJr0u9Fv9&DEvTWU| z2QuvCxtOg;BQ=Sffi-)?av%mjR8VrJTzIMXrq zN+g7yETc*;N+m`(kV?GY)H+hoqT87kj6x@sc-qjF(+h;5&0HmpXM}<>U??fmLkkQA z@x=K%rmwONx={wp>8KKeM^>sLSBa%ci$I~78;%)upl3_1H(}5Q%kzKRANxv#poI=bl9`zVz=USUF=TIQLitnpo`s!`8X?f z@m)5*LVQnb_-TmT&-s9%DADosHRl5cZIbxRZbm4C2O#GtSaPN&(OcVLvn3_+G`BooD@$`8CbbUNQNJs&syZ;vkVT`LXT znvEC~?OXh{#SINh6u@_MIfRO>W6x7ai9giF(?a{!rZOHD+d|6^gFh^`g_a*`TWA$k zs}%0#`$El4JDgCoh!3HE2+gdT_pamyPkp*{WQa^Ayw2RFK(B2oxJ9cD$KA3vqKm9V z!r8bBfu+jheYaP_{Hl*Z^7F8c?UiDfZ#kH3d!;d374k}H(1ZekjpgVrEfzq;Uv?Gb z)ewc`+V_f;A0WH;XS%S+y=)Arc6X!lvuDZ$17w=T@5ML z`Nr#XKCtmX)0+iwwzVLb-Ylq3(l?83(V?oK=v^^r{Y4s=)GcA8kkm z?fB_}dHiU<4?jd2f+)60s~R_HDX8RHY{ioB^2~3UvW;)oV9S)dHtBDz*owtv+KQ#i zVk_1aZ84lbQtAB0)ZEyZIE#uqT!9v49R<%R_?DkMJ*4(+rn0y*Lpg50txp6|_lbG( z69eNQCx2u%gf#F+F`8f}e*oD>$vDyO&4|_{6b8)FrFdLq#(-eDR6?~_DlIc!3iIP7 zG3!LPy&UNk)H9Q9b@2cG;(s}9dUAE}BVT&*v$Lk(^UaU_Xa5!Jzk|M3&=YU09hR2C5uT5F&p zg8HkWiW2Fs23saLgA1Sff%nWm6#I;<{O9j_+eZB%HT-Wce)7UR`hR?;qM!NBkAH&x zq|vJA_ddAw7LwGZxlqyDKD+hNX+~Ch@n60DQ@=FDph`vG|IY9D!@5#z_;l&TPyN+j z{1QVn=k&%+ur{XFGfG7xM>q>Jy8=F%+#Ug2D9oc ze`C|NXK65yv9|7|MoWF+ep>g^ry0ct1JR^ehaSW?#3S62mb5-pIv;r5i-r)&!%MaA zX*<)ubjf73OSKMHvgzLKVLD~KpFUElt?56>0m~?epoDE=BJ}OmWNSusk^3S8G?lcK z-Ffh!=;gRhh2)P~rtrE5DvEp}c?XrEgG4zW6@RcwVM-tA>0VVS`cw|9lBIl|4u?}q zSR_w{EZr@K<%a+X0c3#^^}(B?RkKl5Vw;a825bM&SsF%YEmnKf^ zwNharuN|V)5#Z`%)(7AFr*HldsEv^b_SHoE8zLMUSRxrtK0Gc^$@ol;IM?BQ@K4*NXL~y`jWoJn0rsNVsOLS1kntfAV)ov*taCjfQE+gM2QA%XH8& z+CQKZJfO`ueo~pa~J!8_q@_WWq_1Vw| z70S%L&6nTP|Ek9>`@K4p2%49u(}{X{2}7bJADC1?-@GU5jIJC@MXm_nrYnZ7PAs`? zvrpA6Gt)U9Ig#XHH$D`3Oh~3VNGOXe-Fzr>uS`Mr+6m~AyGHC7%xgfk14`$)41Sq#EL)(gmk3}xCxGol07Ifpj6V{nj zUno7Py0ix5mg1KjW~2qvN-4{~7Ek^ht+$MY^gkB~cN%c%PzztX0!qfPt<+<_lU6N_ zM@4bf(r8r_S1rwjisGuJnNm?)wKR_^iexbXlnab5Do(JBb_fT{Sj2LhfYR&fr`v;^ zNh7>LKb78%AWxJYOlX)^a!X+p=U@kZqKpzn6Nxc{cYoqnf9Siv=Py6}88j9@L1Sr? zlYA_Zcz2Vy7E5Gi>67TK?Q`7~Zj@mQ)vRIzt)vpD$qKm3>P{LG)d`!iow z�{k-9YV*!b7=1f94wx4*t{mfAzh;`>yx>(UV^997lh1EEGI-UVk{467H)%Gx{^D zKg3GGarqM^n=+(~U9HQnQwjQ>eP}Zj$#FOF+{<@b>uofG$l=Z2Nv7n)X7A?bsKSQO zHq!FHGgM)k)lB?X+?cRvvEhAA0N5lU0>I7(DJg_HOE+nYHP_+}rseoH!G&ngwYc{w zNx__TYNe}^Fi_L|O9Zy56mccbQiopInN&ZKJP3K{z+qi9G)=_p9bGGRbAZY7k{6*% zs_UYob^#K9LMg|9QFdPDJ$A{8=18Zvx}Fq{Km^ESbx0ijAP5t zK%zv5{ft@*!QBLB5OQPo9`Zg$?S;T~l0ie3qqc$}1>5!{+KSPo;)sn2w3XCj&G$9X zCZD#pvTfxAlUlhFTc*g^qnw{yS>TqWu7LH~wlO>sNOXgJMd-p#4RO#JanLBIXUAi> z1?P$4jfe<%!U|`&clGDg2*aBRr|yyMPVU|V=e99TJ{(TKGyxpA>M*y5r?PD#93RV@ z(S^fJJc+(xy!6JK)e8M4rggy_JK9Ks^_e){HNba8&-R49n;gisd6#zU?ltk}i4Xnt zmw$;9@D$!FG9x>{wbAGR#WnWt|}k>hbo0ZkY} zM0d=YDWk}L&c!~(M3AvF7Z)ES!DqwZ#D&d!vpMvh-~ZT8|IwHK>^pz$0}l^=FTX^t zL{Yr!^^a4bkc7=X$`P0PbP1!ZcwVs*(Az@ll!0`&45YZBHn0^{O9@=~E=p#+WEUlDN4}F1d{`UwSs7a2^g~2wz+yl6VzWwuolSazXFxKx5Z zv!6>do$g`>rp}jw&2y?dm+9LKahrfr7CnB({TIpTC|0=5e~}9)iSese6i~{B)gb{T z$qPwAa2D<|)_7B+L5bKL3}&PE!coCQfp}5EC`lv0aw;7!n9LRi)v0lU2?B@-CP^Sc zK*5O=&7}PL8DwToB|_EAsV1Nxs9-OcL@@cgZARU3#Z2ZJ7EF-$MF=njh=3$(g?tZE z5G+6$qk#xWvUey5TIzy1HV9-E0m&U3kSr09Rkcaxgy?rd+__ELPMhI2u=psX1IY&; z`->p#CIvM%vy<%Ulq3=brCY+yk{50fZ9i-~SULJsH-x^b9$Tr-Wj7CzB-!oDgr0!Y z5kh}>2f8yax^sAx?syDbW0dYFf(>aJE5pqrbZ1KBz4u~~zz0d2&=7U+Kwe$|EFRsU zMn*eiBTGibV2Lrbvt;9UG-WL|r6$qe#|BkcJeY)J>v=(jagR zr6C% VuY)e`58StD`Y7&RJo?qpG2BKn;0_qw*c7&Ss|YELq_&yGKpl?4)iO)jtg{djWmiSR3A~%kTK5@;d38EGYWB0c8g-0 zZCFQoi-MYyR};-%BzbCfa6R%=V~7sc!)ZxhZ0h3}{t?O`gbH+!h}aq$65sGzGpaR3 ztr@Gu!8#?$UONmBm1l=&EFWNg81yJJm{E%!^*y@-Uod%ewges~=>t3_=@)irE9NKw zid!Rt=1U5kBwUOLOv_4G?jik~xBG<+8NE3QGLe2elVKxv97jn!b9}={zvv-`w_S!i$431n!(qMCy?OVch7ySvsGcwzTbUjkaTNk*2kqX(SOSDLAh8I_ zku%ZRJ@#0}Ii`{7i*}#L&^T67HnBt!l|C-Aa%odr8j)&6R+4D7iXtm9+g~m}j+11q zhH=K^JF?N5H5`g`EWB{DcX*VC6saZ3K>%0HLvZvP55e(oJOs&=t%fGaT7UqOt(n|B zSBsh6Owxsi5KK9_B%3eDc9CKm4@taGlNuMO%(CMGmDeot`Y{WXYZS!-mDm5WJj5m0 z%dA+5hfD{^qJ&tKSjn!COo^?LfI?0ss6t#NpF(QMbsXf*&EUhPLOdYMVuvB8 zubVVxK4jK1?HZ@OMAnnvN=8yRyMQi#jD#UpsWlD2FPKmvUiiv463-y(;kuv z*p{U#9K6+&7_etV_F-Y!rM#Kl;NpP9sn!nSz@lWJ)~GmeKo&{5G9nJ_H5q7SL>xdG zkqor5fdz$)2POlNwl3VbiL;vlNyIs@v8gCb**PV-`V$k87WD+1S2(r_$HmaGf%&ei zR3h+5YF(6knne?-*-LF-6?mlwHxA7rn@ESI4B2;Nma-kDWRIpK8=Vrc*5tpDDN$}! zI)Vs&$wkTn%B7+v&Aq7Lfh+bbru3mD z98add5{{>Huv8Sqox}lDG^9Bv+Bi&^9hr>;+i-j&aS-lVJTxlj94J%Y)GWj`eVR@6 zsbkRO)NKfH8q|2|i!1REy_RLps4tc{qq@j3Ms2a^ah4z36k}u$a*yfCL;_)dcj~*- zaC|vRD=`7}9pm#&gU|#=o|%TIqDXzy1gPlJE0ZQqwJuA2cN$xC0v{?<-w|Dz#WWI0 zL}{dCi?Z#ThAis`R|iBsj!IX?_ARyex{z&%e)t}4wtXrh=dkI@#M#^{XG^$oBdl&_ z2V7S^gyZF?lwrmCvAeb$7lf{?ov$lA7Cky7@-<`%rz0ya}!l`gOn2!S1CNG#EhhdfxX?4 z9;OD0gv%S)1Jn1)(cu^Y;%JEjPr3~RGmQX?;uvX^RW!Yi^)o$>)iY_7bu)c0*%VnX zvmLTprWc|oj)YcRZav~kOh6CI%Me#44MK|*S0;^CMR8@)w5TYqOqxFx#g$2OqoT3& z&`08Nk2@}v)O8tshx9(}o^ZrZdnX+Kr9L?cNXnH{0;zp2gWdo^AYReAf7Bl1l8T`0 z9`ra962XuV0~0=X4~b1=%~b_?I|)OG=Ccullq$@s!ZxE@Lyu(E+C(>!*tus18LJ@~ zi!3%d;WcxUQ5!ljB4gE|l|9 z>@5^zh3LkBE@Z5z^181V6V*&CF&RtYL($wM_8uJ-vSdU@h2n^!qk^-{xinLiM1^RE zk~L(AvnQI;ND`z#YRaXR7@WIPh4 z=&ey1tK=0O3fD?V1JOynfYPKsmbaOVr70;~3mMC33Nn__5@al+A;?%}J3_`XZ)i!z z8u5ybA5KBz|L)KfrzR6DmD7}=aIFy;iyC$|tRfq@YAOo=6IG7h;)tJFscU)Q7IO23 zB(JIHkFdb4MZ3WtelHxDF!~KCw=HC>=>uw#4ff!Rh}VdW#bae_nc^{+io^mgQ*RZK z36r<^BkY9O5q|`)A$5dB$sJ&yNSa>I?qb9q=mR|&k#nZqAE90MiW>L59hVCY8i`nX z`hind95h5XW2{vt+|CZ%kDWZs=D=s*KX&V$ub$OWtJ)f--CT_|cJtTmE@)3I`)k+v ze0_bj#-XWP^c(BFy6xKJK(N)?OIRv?zJ=2&_<5t{JmBIrSmpV7Wk#Za)!LmbJ3o8T z_4#S6uV+&<+CQR3!_*u4Z~4u)fA0TyL%;j&*;N03zWWc~(>ROn-+n`X@3&{|bzp)j z%im78U2C1F70UO2yM^u1)|xlj)kbz2qvaMYuhv3ny`lfN@A#P%4Zv(iG4^w&&uK+)@v^TAup0J)yzoGvFKe+J+-sE)u zlW)KH+2&as1P86jxpg!Is?byZG8T?eU#;EaE!{<)8Sa+xKJe3~-9_u?YFKQPcm@d*InpaY*`$p9oR*z-QM|n8Ru+@(Kd++IY>@qE* zcCLqm22RC7Fd3LG@*(9dGYTu$dvS3Cgw}dty*#oWKsZ~D73<}kMr?qwujne~XPZX; zGLQh~6mtd4G2b8!D;sCZdYexYx~jd5s>&z?-g!rlut2OEtG(X=ni-&5*J(Xgw1`k> z<~VrQ0FK2tM?AbPZ`KA$72aG~XWg^IT1}QZt|oZTB9lYPy2rL64Ujp{7m|(%l&yyP zV)e4pEWrqv@ww0x*iO2d^av=Sr*wy7+tARD*iZu);FDmh0-!J}Jok2I1$jiTq_tcO zv-TFxW4XNrA^>1VNQezk?xXEuNwI?n!+fxsrwDO?qv+|J<{=+tfNw4c#A%fcMC;)I z&6S~^zUK2Jm`!WR6!QO}wZ!8PS2Od~jB64a2^D0o@Q$&TMC;ffS&5arSsNr(=nma& z3O7N*#iEaFPF0Vp>kJ+2034YDMhtlch;pF2E+>@07nL$57(1UejDvTbp=QuMp3JJR z*p{p>pzpdU-f}+c0xpqS`owC|*Tb6lDJ)58J(ot-v&WokJ%MFwKCK(CgM-)QEvIr{ z&mdS2r9J}6!gA5E#js>;u|>_6yVPF|nun~XSJ5`Gw3;2m%zc_$IwHc$xZ(_f0z!Oy z$jkT>c{sG5VRSX)s?aNS;vkR$C%_+Rtphd(;~X(AcH~)~4rmAm1=$Qzf!D%2rVdDR zh%Y~b7VCeT7O!0mPhEe1~djcQ@O9^iczpqFUfu(Dyd=( z7lud*9qTMG-qT>btC;n?8}@7uGX;C4&D~lsuov6RI)zLxOL{?b?L$pVr ze>;NwjM`;=d+HO<=_|(|A#a!n^BU9ucJQpT3NACCb?d_{9{qhrvc?Y6^F~Ita6@q!lfE>)H-f^CXy0z)(q6`X3J*ezS z%n8jiVYG^&Q6d%84d;wCMz(V;5A#I#Xp)E4&Td<_^^8_|zze{&bBgKHwNsMfS=y|A z8o^k}*QvJu+fUb&0G;Ks7I=1t)ngL5UbSmq-0JDtUT(?Nj=ay?OAN4M-BDa3J2P(sZ{oU%2lJT@j=Fql?J&wQ2g)zli%LWv`+0O`5iw+pNc=f?;;}< zf2**aIi~+C7d7ah*3w~!?M;we#}VrlM1%S)H1&ZSK`$p{&?kppY8KFIz5f<{WG||w zEl)AdHyT2**#wx&SJ+__7;)HSi2y*srUA+8)D*{dqww0~8>~_E62XC2Sv4pD%ci`F z_cB7mpc=0MV@S4bof0ST$uUBxuP|5#f6`Rh3>qP@6>z|V zv@N;9dKa@d6&Z#)}agRfamQd>~-z(z6_1mb^NM*If0(ipPK=p>nMCD zb2Cr7wp0#xhA_aLqwp@9S3WAd7Kj!2oI@S7k5vU&Xk2gytVL{4j}7YD3F;ufIn>3$ zie?(ry-|Y`)OC1|hcs&CuVIpeR#3eH>Uhp1(yl`t?MA4x{(q~QT86S{1(^t%vc-NS zODh7)Q=pEeWl03%K3C9!2z8ig1atNQnVhGMIrIcLgL=-|wBka$D);-k!H zj;(Rtc<$hA&k{H@#}STsQ;bQ|XWw#|vjITtm@Xzxc%pT2>&RU&$%riC%xcHUoxpNMfT@V=(LBy3I&*bCL3_cWf}1yW|_AWOOI02G7tEYv5r?V9ZtF>H~5!I z5NVe=`_*??9DqU%+lXk}DFi^t^^mkCX3TdC*&onVm*HsbG#qQ$!P71QPp4|}BeTOF z(Gr5E_K_oYokYT6^RFzwLMi<;WUa08=M5z446=y6VbmhrKVMxxQUSBcTE#1T0>g1- z#BkhsUvsK#ye^E;T!ph)o#c`A{@!(RMVi6+;CkO%PytZZufC{K=jVLw#T7o#4=<|l zf*vwRl1YB0LN-YbAb(ihd|BgRM%1Xo+WKbDHZ)KSeM3D9Q)w6t8Mc+vSLfu^PpZ=o z^cjlk^X|nTzF0{%@S-X{MrMNkGA+OoZDsYdSrxmvlHnRuWSEE>-_&?mT{|rxVOP5} z0VxQL?#Jd=m|WH}WKHJGR=m&J5#vQ;q1k`p;cr@Zpr7jgKvipYwx{)$6`ny=`ya1- zvzh6K+fb87^4GP(b$gxUoO)du;i3^Az-@*mn7K~JXt-MR3AVtuU)L!w3wyB5T~cSm zcD&LL*lu^VwNQDfPFaNB_ro{&)vA7ckOrHtljZ{82PT8DPT3+bv}PRY$;ulwr2dKZ z{=wwTAFBdPXoeeSl{u8wn+(t9!xmX^M}xJrVpT1!=gJjq1sh|XCPM#7 z7M7{r)u^nn!{1l4=5XA3Q?*)sn9-jy7YScs1y9fgeqeMOu!e8~Cc%5%ckw~L`oXI0 zR_DeyxK{uWZE#OJ$?aZ}UEDISdv_;sWo_X-VW7BrUgbUL#vbU?vq6<+*SkMl)oZvZ zy8oIh!HY)XCBMk5llINq9-ctakPvvVwjI5ILyYnpT9Y)qYh_Tbdn_ePzpQhQhU9-FROG}YSE%o>)pq6 zRqOsJo$W3KCZ^LLUb_H6pJm!u%c@9*Eh6);6|J(Ky!W8N2@eG+v~Xlh3-%gy|F=}> zHL1Jx)Lr~}4y>?vLCk%@fb}l!ewXgoGzbG%p}gNQ4gs%^1Kyx<_!CSO^yGGWLgy-X zHr7DMw9=KcS*2fnAQLm8{wogjua+HA*^;U&NcfLPUG-0 zV=guEK}|{>Ff<4k1Fm%5UadP68i^IC3Stcw8oe3|k6`mMrP*M)0ZjTVeA*4_1k~ z;P?Gi(uni>Se3vne&1PT^C!P=trGvm@1s?++3|b6iXn#IH3{q zX0=HNy)`&;ft-R5Z*6ShSYb`Kc!EA~9oq!-L2LzEgZ&p^(iv<|C4{AJ4W=$+d;O)1 z_UP~6-~~Q{Wp`^(zks#3!G{NXFOVw3nm)P(!8our`1%WYJTO#k4Q{-Ev9ZQr2e)4! zP|9lEutf`u^*{*B5pT4&2FEXCg30Br!HEmmvenzlZuIfe(!$oDeF592tY-6DgWVU{ z3ubL8l45FWaPk5?SBGHEZVkTf0wG)W@R&Zdv^6+(0sgAf!sfOHwF}I#J-tao>TC@b zFW@pFhMJii%wHht+MXWQQ1)#N7A`Oq*HiP**5J&AtmaQoY-NYEOys^HirQYFCEh;B zl+F`VMiEoW=J-W2JL{&sh4osYvQ4jkGYdOqPo}q+tiybv?oV#n;(r+@vat#}3X+3T z{Q=`-a)|JyQF8ctA+fW-Mwqdt=C?BLcC)DZdQ-x1$E!@FzhfNMl{zf&`F-z}9bydEe(B5^n_3K^=As`224{9I#MX+e=$e zh%O4;l2?aO2p*E}bV!3*Aza#5XSSeOwQ#~~;21 zxPFU_jR8j33(&UOdavhqrFx|%w$2Q!>4>@`6mv13-hDN{=j}PN^F7==Wj7Rczu82NR}^y1#p>`! zm@50oNA(d@&07DXy!J{8b=&<%{Cq^M#g^VtPfbnr&)2P~CjD(n3it}TL;oVOX0!j5 zn)=yPue_u7fR0jR71TG5qv?N|wwtg@rbIg0XZ-f9@%D3m`_6d#q~AUkZ@=ib?~k`% z_S+A}Tg?G2f5dNf`8h6Gd33a6_0Mq4>f80FxdsC4`XbjrfnA^H`Xbj7?T|ydf1>d* zMOI*A>;8m4?tY;r{S_B?Gi5Zcz+fb;F(x~`_I4{k9%sx&fx5D$N9e}K>i64~g!X3t zi+QDnH}mCEfqm$yykH8ca-*|%M@gn6>5`P^&7cO0jokVdx$T@9uiL#;|6OS-bLMmanetcPZ!*PA6^S-L}-c?f-4-X501wA}%Fe7Y3R z^XY|Ir4Au5r$ND!plX$@X>;jN#wOvCo2-5!!5n z1pYeceXzH*i)4Oh)zBuPMPrLc9_#{F$;g@Ok&cl zWVHjxHN*mV@G@T>{NRs&*P9=I&%b}uE%bw@N;Ik1Wkf5FU4}QeL4Hat6xk9-mbak# zYi4ZcH4;9-w!8KM=M>W=CEvhjG7`I7^VsEODptB5sG?q<5fzI$>7mM&w9pI{#|Uk< zf>qThD7Z}<6g-4o5aIV#6L+kl^kTS#+1~$pw^0}`eE&y3QR)5@o zJznbPexx8BNn;r&E&ZRtlP9>eTrs6%SS;C$!H6A=VmWH~4t$os(B*#`#KJyZ#llBN z-&~Kj0C)kc*}I9M1(OkDGa%83;mHj%)70QWd4Uo&CVQOKU@#O|HeY{*AyJSY5YXr| zFbXW`sMTN&W5UWaEUFl#wSLNOV)DyX-B@wp$}>))Ke8~VgFY(t9RdwMud^mczUh-k9oqI zbVl{*i8!6T)cw_}j2KL7sGh8Jvf4##I$2#O=1rM(gI4QA^XQH4uK`_tg?Y$I2(V%y z#+s!h*I|^Dpl7zLqdVBHE{YXftfi6l~bl{q&$LPH~+&29W-{Y7Y)C)0qS+ z#F|j&+`h#q*px(=u_hZ#IVRfdqu1vfXC+G`+SJy7`wvxRN@s%thw;3cD}))$+BH@t zTQZTQe^K{-DXHfj*lcQRybA<=uFgKA(qT#*IkLUSwLW4rP@1u@We4$BIFdlMDEK>G&=Kp8Z5V>3)K zSgaMLenUO|XpC~V+4ZW!G`d5*=D->d50*L9X|#QM*B$NjjE+Ob^q@_DrL&(FZ7lP{ zou2m0M$HYliTIfx<3y)9DwYjpuVQI9l8Pa5FzzPk+@&H%;>HKFda&CbEa(B*h5U_< z9_+CP^LjuUfV;`~%Q7Rm#kXk zO@l34Nm8xpfv;p=#}LA%^_Er>c|s3uHEVG-g}M-#YWG!+#HOE^F3e)rU0nfzed+PQ zY@j9d&x72q&7i+vsI4a|pqe7!Rz-@8yhU=jO7-FIMM%MiAqB`w>Rc!6gCg?gncVq76QoH1knsl6vt4($?PRC1?)>f(m6?8}rC(P+m$Kj-8Jd85wIr*u3b8+CM zQ}>ekP&#$5kff{IH)e7WpP&7ev=O}+w-jr}qzU=pIZ;;kQ7I^I^VS%W=3_m#)Jwfx z=s8{ZSXv&0iqsZ*PWm3+lqAFh$*Hd>H)$l8;?g)VEq0ThgEVY94q-TUd`(ry*v!#; z={Rim#u{(BPF1=M8#OV{TG9)Qil*ZLz@_sLUDMfVP^FdF4gk;g%A|SJV#UqgW#GH= zrD9&uak{4Ca7sm7az`(Wfx;@xdBO}#fTg?-B%u)guJRgdboUSdbP4>)M`iGIxy2C7rR*W&kRuI3a}@X6Cpc13+;5+tOhs|OeS$$1MdU~j zs-lP-1~EAlrx~wZ7DX@y)AJsi>xYqpXt_A+PajXlBZnact71su1^`12LkgCMOfZHV z>|!?L;8b8kj$P@n(7&I^F~L$f9TU+hAqTu7Sb9SxbT;ndYMgT%Eb3w~iRLM5yfGNp z?7R-va$!s1)kPmUeOa)1 zF%>HVCJ6M1_E7`H@BQTGfARxg`VsQ_!cLv8TmU-+e;{kL!Z#3z2QqNb}usjLw02k%X7J&5;6Bq^o- zml0%q>i;gOhjuIHLUT0df(!4}(VPoKCVKkw!@u%7A9~Aw{n5G@&+u6Qr2njKz$#)& z(CP+c2hj+Yf}M*r41>?nz4!ml5B}euCCfjjp~7~cP#c(cQwoD@7TPr-pJ(?bT)GZY z%l*rxr8{Ad4wtg`QL6k3W&oWnQqs>B>7m)`M}?FDin-m!O;R2nEpa4eMNWpClqDOX zYDH3(jHD`xq%4h5MMHc(rG^_OWg1w@L1X4i8%azZVY#m?sml+DwDOAvlJVkx+r8E^Mi_WS+>KX2ZnKW(gOnI@OcJ3{}}Y>-xp!X`~D` zM2bO2_nn5LQzSIld?hB}^VfJ~(&TBecHr}uADhxuSyGpRlp&mVQPv5d-3W7=U{Oi! zts;n(HC|;nKmmnnGzZ_4&W};5tEmCFbl#7b5f#Co02RTWo+=p?*=30kI-}|?K2R!` zj)+kUByzE{mp9OGXO%yyeB#W5XgGP|>T-wKfh4k~lYWLePVl+P>&pK-)N!WF@)g!c z27njB6u034SVlj9c0^yF(ouOpZEkVY0PHjj1RYTtt(i}btPGr&L82F_d6<^)`J?M? zLV8fxlwvSGK$Dv_{SQe>529j-OIr`n26;nNOc|Q*?sYl$uXAs-penYjiLzA<71Xg% zJ4-%=`WkCY(aW+r->ndu6cnHIa&BrC0EfYrNHvdEs`nbipPFebG&;ZDT`IZ9%Gz0R zU0k8BVM*GJ-gtJ{Ba2tmJhJkRq8swpJ)JeP?k1P4dCe%Y3RvCDCo4}Urc3v95)bCL z?&+-c<>}<9dpc|VC;iqvowdF^oji37-}5r_-*Zr_-*Zr_-*Z zr_-*Zr;}@qBSR`!lMPiyUZxa#FRa`P@Mu<&N7HI3!Z6vxRlptkxz!IefVsSqe3@2X z#y^?7^A<6=S7aad0;XM2RT!>)>Z^c24UHT~qz56ikSlZr03wB?tJQc#$Co{Vs*6^} zT^oMLPX)aTK*~q*IYrqOW{7CWd_{G#8c(R|r&(^#J3 z);y?qRjZm5_k?@dt0}@ZGcV{%7P@nUU|xfOvLCf(PASoQJVg`++Hw zsgnOBzljgX(Q3D=(eL_3Zj)LnN2@(N6(3?MFF!r6Tbeo(ALD2(KbE64@<5_$l9G|l zE3MP0gDg6!5=)HM16c#??AvG-NGeFCbWY|qg#@UMaymtWLQDAtZO(6{&M`w_W<)&ThNZbJdDY)v^mPy6sH3$Y*Le z3zYho3=bM=GB)TPJA%-isuhe4Y1Sp}B_RZtSh_@2O_xKdpVA5e^l2RsO%&viy!@7FG2#42??)xzxJ{SGZ0ivWs(9YZwFv^ zO~3We38duJ*-U}_w9XzPyl_;L1P0usX!VBIE^SSy_gfFJ-OF|m)FCsP@cug=yD09P zM2G%c%lGZ|{-fpl^W~ehvwaaP-;&aQGWo?3g^Ek~t_uKwQgL}^z5kJNOQ+WRA1vRm zuJ_+xzJDy;gn$=--4p^Qq@c8&g8dG0JH-^x78L8Iz*%r;egu9`Kq zsY0$~pO=Q{`QMj$v7KE+@3V0d@UdBQAc9i~pyGCdj`$52sR|i>7Xt*jhnbb={+Cl6 zbj%|FbT6b7VyF6uJ9RKIzelF5m!l03DYb1Re=gEgiZzfw2a2*TaMC8R)ZcmxgMqeb zy|q0#4gxq2+MB>qryUOsC=2&-a|5p!wrR6MEVs=KR<4X2nigxI`}r!nW$FD9@dwaf z8-5Ik1Q^g6U`uWVa4xikPEKna#z-{LoBIFRdlzWSuCmT|?X~wgXV=;1RIPgEBvql- z-l@O|RB5R()TMLn+BF1YD{Y`1T<*QzzKrhMLq?UihY1h4-61KcN=)Px6%~+2fQAif@o8Zz1Ey-uDRypd(Urv zGjLq05DT7sHPWIF&|kHJOQM$=HPK5oc24)&lBZ2fMRlcjhMAZW87`L_C`a=FZU zA{YGNG&%E{oS>DSoMn+lPs@_;@T4UJN=C)>O#PJq1hn!A47_P%(z`Ypk>Cwd%VGnE zs4oQcWs6(ZA!@D77$^dBu+}-WsAG)|CK`4>lv8MbUq_?XL%>rRE3xoqxt?uKI9iG>BTb6r;u1-&oHFWIGO)sX?)tAtu6@l5AQ#&)$l-l6y754`Xc^E$rQ+zb4u?u4dQZ>GJxRA_$~ za2(sjOfReR4B(pa>OAZ*bG!^Q8{f!Al!Th)_zp5|ZfD?IJbp<#<8Cr;Z)cz=kMC$_ zpem2=Y-ik$C$ztS-oh;B6lx3XBBxM!=uA!>SL%4KX{~f1;@rz!-z|B>cP7l&jS1ZT>CBC;DUD0w- zA#pG3(>*jgRh|sz7@v}vU0As)>Lzzo>3h{l&O=@(a&;0^#x2^9srAs3=$v3r*fLkYqOlsqw^ zx)^+}voKAPgMi{LNIf0Uf7l`CW>~qI5ra@INF=QK@_m2BO^hmcosqvjuSOKZg015? zOt5vFA}>oty20Is3oSybt>@Y~(;II&3cXwe7&5_R^8aq`0tT8kTgk$O5n4)xIO%;J zVpwgu0GPO0`{mV9_I>Gbxxd(rL*8!AYEs%BWgSRYX?iz!X-C^I)mBE8OJ4&;KNB3- z^wm05+f|A;H_w5Aju>eYZ}q0(rW8P=Q`iLtC1^~#kx%3XN!rU}1`|q1-RZG`mdU7o zXz-ur<|Y#%J~+h#r+0?%7&$puWQYDg5Q`HIceAD`van213k1McsT%=MdUl0c+R+#* zb!DVp5~(M()z@G8r&Gj6uvoXECe%;)V%Y2L^;NXXRJQM<~A*<}BKn z2la*>6P}RidMLjZ?mF6+16VTkp`J#Kd`<*H8-bdy7(B>>h>jXXTjHDcOlL)#?@Jt# z8J8@_spv`t_FcJF8HN-L-q_9B@B(PNfE(5^No-O}A^4Y-cj7)I)&8xzA{PIeuE;KT z=!yvYdaicSS{T0-=J0q`0gtye-4B3Cvcy010JvNj->4KY25d+|yE&4wbu0OjNNU56 zl4d;sLQ38qPd}ZKcSQ2Ol)N*N_eWA6c?qYOd{EX{?r-M)o^*dB_jjlJb$E@R6& zE+Ue4`298dgyv5(oV%fRe0V6umReY}HBKrk#37Di$XEy5j0#WO3>Vjk2T$bg|$g z$T=;Y*W9F~^O~CoZ8P^!%Z2bw8XnQoVa-EYI<9$4O9w6mFqh%HlMY4mMyJf-w%m9W}v2GeDoe?$T305AF+n$hHm+YItM+SH7+->L9 zspZf$?ygOQgh^Rsk^b;uDEr5Q0YGoc!#0KZi^n`s`YDcqB;$`g2Z@muN)E5%Vqtu) zx~ub8&D-pQzSWJMY^VJL#qshqg+yj4;lgv(J9G zhaH3ApUQ^9yqGbXU%Sp0e&X8KmRCIZZr*t~&)S!kEmY<0m^X5jJ8C`gYTJOvinmEx zw<>u@2S?rX@tuC6V=m;4rA>+|X>V9cVh701FN99i6CL6y--H`SD^BOfj8a~CTd?ZM zs?p?x%7yIylfQcn<ici z*9^Dd$*34OdGIlb<(VE5UM&p}TkrE1hD7trxx^62w?yO4x3XcS?To-A!o{3uC!2)g z3>KnFdI@e`u0AZW&CB(NZHS(4+_QQS1-8e~Wdr>vOmwOtCoCiy$X zw9=F5rMLNJcINZ!OvZhF?d;6w*~#6cHEU;QKF>}bB9&^^MWZRoN=t8fcw^};7DR<3 z8~4r7#&j{ZEWKH67S^uFHil4-L6b{CTF){pcjo80c=C z76Z7(X`APJrwyQ`)j0Oo$koxli@T@JlUn4}x33nN7^x4|vLBtJubz)eH

dkm%X3=UgWNSw$!dVTVkgzREa8n zlh%Ec*4fP<6MRvz#EHJ%v<`!!g{BsMfuk323~;^oB#w)F2ucM0)h7`oE^G)4M?O6p z60_||U}vU5mAwo&ruIoFubEhFO2~S! za3wvINBiXA!MdE`u8ng^_8$&ksKg4xhnEThfU-wZVyAh7Rbsfo?I|4o(s_4PV%j0( z@HELO;kRBsgZ<6?eGqT4M=b-S# z;wf0c68gv6BIHR@OsL+zsCmM1dn zgktr?OXyEI_9`R>`8}N^{+FM<^R1tG!)xFE>4FiJ!`lsYd6Kc7+H{IPnEAB2_Ol=O z@Ts4>F0pUNIq)ai>ktHi_CSjpN zLIP2@9->d+TE!=DFXp_uhv*aXP+|dApTKPyYQR8sCj-T89w^;T2CCZ{sBUYZy3IgQ zRSZ-yxV^W&iH;R*jA+=hhu!ipii-4m{Qz@e@ror%T1c>AiXDp;N>aFb(h~`(T(CE&)k5GWv3R?!^66e+Zl(?s0f@B-i`cyM=VB#?)9GWHIVDPrJE3cy-UIN&av7`||#>T+0mNB%D zTRm~8g#mbZEWj&IwLTF{?AU=tYd9`C0!MIM=*hT_>o)CBIInv#(6Tb4z46%3m1IqY zC3jUA&+w!H(jgjJcaKa210`6D)apBJ3llu+)vqZdK8cow7xJPH{uW;JdA_cgXK^iA z@B-Sx`1!0$ctJ$QWR`MBdO<`s>xJ=2lJC|_Om(b=Xd$F|Io_dY^&Sf46_6{v0s?Q* zie3TcXz^Yyuu!u|do?8t!y1Zc4!Yg1eVsRhBEVoTB;Lq55RY1mO+&1R`nut}+ z&|n0wzF+{A>zF4vyN<>3x||c`k5!9gPiBj%L>~t~O-zGn3vc6mb&*`JmNnC1$4#p? z8Kz9pIb%s_nY)#iJ@-w|o!E0>Om?r3>j$k7aRO#pe;z zAjW!|EH6tSMB!2)BuE()fA9DUe)^*?zwHzEvPD+nY1_;sGeFzSgzwvgk1U&=xD z!#$pyzUP1(cA*Vgit@9m3)`EfCa}X!H*!xO>@3D#diy)Hu?%?rGc~3D+@C5Tqz*0xxK?9jmSR~^z&>FGn zwxayTBVrAq&a~AQBt$)GD-?W$AaT=53?zi6_N||_dVtAvy&mBFN_H$GG)hcYu)%^k zO{521Z%LdUVxphaJ?$`Ld*VzF7I_4)fQ~$xR=gDdfgXgBI#eR|K(5mRMe~W}h*l49 z2wkrS5hrP84pI-813`Dw1DT}{5qdalsFK~}(dMpb#HEdD=lx`7kepmpgu#d|MUj=M zB9)7**R`;CAh;g+otJ;&Pc~hfwDeKTB1=u#)`7xv(_jDc%jd484au5MTX_7D`+xPN zlYlTs{>OC2lx?5F|NU#%f1n^~BLP*v?e%Y)M9e($s?Xm0 z`%64cMuRW@#>Xxrm6siWtZXSL*IEk7Y$=%7{f-)~$Oe_UuwiM(+XG49q6lg4E z?n@nJRAdaWIm1(ttsLrX+en}-IxH(~nzhI*Hp40AoT^3P$X}3`W6njY$+uH>n#MTO z;piF@p(7qBts<3a2(_6DlZHoEt4C!Tcx~!p2s|eWC{w2CQv8fE&7?M-W25n0D}d&i zdn?AF{%5ldot$2AT4&ddf;Bo;;o*3=lHPps)Wa(ircR<|l}Da~g-3fLQ}wp-mMIoRGKm7Q zj!KniUzy@rB-)ojJQ2!Fy#keJwm7yzX8}4llFT;VGEtQLVQ5Fjk>M1T$Y_GfmQfAO zGGhvKrXeGFh%6N`Rge_Ofyvt%vu-x~A~Fi)XUx2&j%h^J8MCt?-noIo+e8C$^OcoC zg5=IAD}@AU6OR-UBoB;AtutTI#WvN>Cf}fD8u@F6=w=hd7s#{_KG}8Iv$<&s;YGwj zY}1EUzy=X?vU`#`0H0RG348^N!qWj8kZQ@@w7yw4Af%CqQkA`ClW zkb-c|M;et9+X}+7?0@L1NZj)Org`{(SHI1dWL~hhHv&BVU$90wK1&a>c~7d1c0=@~ zHz)5Zl+h)*qFcY+4r!5=?4OUMH)L42XjzeO$B*r3H3+8Nu zoX0TNl?4(*S290Byk$OXF1AF%*<_mQVvy_EB$PV$)F#TY!ih|r#RP-`;`*UXShq7fs-}mJ>A)J_!t0yTo8zbk+-nK4SRg|9*kse zh{gi%;Syu^-STO*ZJ>uWj6>*TPzOI?!8&8EBvW{TRno`Vi7%k$qg#aa$*UKTZq;zxfo6pbImN$2Bz$JWSOuOm~nr_w%l` zV#;X7x;)4t}~O z022F#$ez*9dtqVdA}Y68;}Isw)&@9ctG!H|+B+Q>8d|LOF1OojPXcJdOnbN5_OU$E zUiQz@ur*PkBUto|MWnCx+GsNsYKr#uv7$v>CQhG{3e&4@^;-FsJcg zNe|Et;=!EWsQdsi0Uwfhki+~fwnu^aWz9qLF&%h|*-RT5d+o94YVK-uC6SIv^eqk` zpx2z2Fcp0Z8G+n2(YH7|iR{H``&Oy3V5fJY6lDWgG z!!g`3FPy9)vz=zL)D&CK(@f$=s0W%!$$mUwCZ90eKB%`3eyhEbnCXEiO;8x&z63D_ z2z~}pZ~$ZYoZ_@=*<{E}di%MTp0qd%@6hfw{`7*JS~Ssm6-;p4c_xs`N)r2Or9c>>hY}Ms4&KNM(K}?kr zLTPiQdji`f&0wY>G^IBck9==waCugH+y+;mw!m*xu$V~9!X&;gF)BVzL#%z5lFpb6 zGc(Ja=017&q2tw9o4;sN43*m$W78k}-sbh44v?L&j&~1_;pxX%OlBGCm^DXOvNn&w z8WzjL-NR+`x2CrY6B9QYY@VN=FFIuxh9}%gM`Y<+KVLv)J&5k z=K?*Yv&%>nD$SxHWi?T-QxqFConnA2P7equLxT|F>w@OE3NPuVR+Va%fiqx@N++%A z1&m1aQSsCwk1h;S(*#`7uKCmy4^y-xq8m(F!f2s1Xq}2#`5wF+d|`g`%+6h*)`2uk zG01gH*i7Q-^oMcjBG1!MK^M%Z`ZI0b=JR-G%lo10-nu5Cwg#ZfOLQ!WxwO1B=IC|d zjG>-rjKTT1K=kT@+GPx4Bx9ErpEbo$m3;1BXnagQu(PSDP$IhFQ2}6>%+&nh5-)7h z8LW%r&eeeVCc1+l>^b5MqSSNT+-Q>^s6X7KWjW|MJ@iIQetHb+XmPj9E4)L~xF=*h z=m-%pcfTuL4bC_N^SWa5uYouI0tm#l2W1wfo0CSpZO+z8xKmYj06umJB zpfFE_2}mozTld63I|2EnZxog8b0c;an;G zsVCnsdi2<3&c`t?LgjElbrfRDWh@4vXSp&L*7uD|dZNOV;v!t~Bgli0U`<^Sm7sa2 z`G6ZIif3-;rl?M3M^khejLShj6pOkA7(JLca7OEhG@f6(1cz+|Z+&J=^edpp+Q-AwSZ z`crHu08iL_qB_N~;7*Lp`O!i*6mJZkLDG&k8iKQ~wOkj)y=%zen;S`HaQQt(U< zbb1MyqM7_a#V2Cenn%-e*z98%TV@eUVRh)r(dlu^WqFu^GX-cdG?NS%EK*X)Uzo&t z67;kMmvPdBh$21X-wmC8OnDrw${L!r=$c-?VE(3y4;+VkOIw{4^8NdgTw|^Qf>8tgzCO4~Chxf-upt zDlAN?qX4q33jMY&nyes$8BLlvU#OS;8C^6q>DY1ET15m_DLi8ZnU^Nb7@VlfBapuE z6jAibmhA%xTCJR)YNfT~{%En?N}~J9Hn4f7mD}rOtMJnrb9jTq&cjwKaqFOPgmZ1y zK6ZqyriTL%t=xef1V@QYPZ;SSK)Hy7pAgV6e*&^1hmiRvUB$uB6~f2D6RsL@ZkX0Y z=Ijt6vW}|EDU+02q}+KRQN^_F67|Q$L)tWS{{+T}mT`eGI?0=a!QMQTO;esU+$M=} z>krmDuddI#8aBDjvit+6Lf=fErpZcCpDx)BGc_Zy`DDqM1|8rjSu&=e#}HLxvyr~u zw!>(sXQ7AVW650uJ;2D?c_}q7&{3=n%nP;`&kH0YtS?hbY0|92`Z5hjQZr){_7p5R zqH2w8ZMx0dwa=(tTm$h-vJW-3&{tg^iY;FoHk`mU=R@Aj!g{ zzzGAEUO@?pzHxN!3#5u_9uqKeucx#_*YP96CeR7pN5N9JS{ep~N9QKLc-H8*8M& ziDS)6*O`~{Bp#SnJ|M(aau)E|Hbtd_+@q4`r4dN5No=sm&^)?z&rxecY8jP(A$S!R zCtfIu7Gik*Ci){%uf7Q!&o^NLxsa3=1QA3*@Ph9Q{sC+mpP~g1z?Sjp z)7mmVv#~AXv**B;@hQo)5*{p)KL}gKrydGhM!QvKZ_9|LeBEprpL?*j4EIj*m4$oB zSRt%T*)l%&4P(pr)HjYTLzsmoU~ugohM=9jEd$^!w()m z5Z7jn8o>Kx?dh}Z_?)(u*ya&TV`H0#+JmSpF#h}4JTmb+M>Y@fDQq4Ot(JlKv9Xq+ zPMu>dgKwTe%g}_hwG15QOcBFSb_~g&@h4=#Qs7!-U84I9!VR+W<{7@R&lmAcgzu_IT1>Go*R z89=9`gaS3KgXcGE>V(~UOygK}st8wr+&MH+#FZJ(s(%g!-J3kC9)Ehzs_J=g4VmPU z42|NdFSh-t+<+yu#;e|gcXyIcpk`-woxe0=?nTH8O$QbLT@*Y@{%YD>M^1Q+IgKAe znY_xJMhGk!@+fb9ZaaH2q{1P>F@Q00bJPT7(iS@gINx*L&-r!?a6UE=H(K!YU1xL$ zquFw844DED85Nq8acyU?7kB;sMG7u_id96ywE}s_)x2`2)@_#Bq-dNFtNk$~# z-uRYCDp)V=P~><$jWE7FM^YsjF@AgFJL72t0LFzh4o-VA?dJAoHsj%{uiG2By&`UP z#F-QaauufdxYqV__h|1gGs2o&9e|+8DC+>*mm z6=~ODi&mul4I93cb_?vWI*0e+3uo>2;it-@x&S>9F@(E-2{AT= z$!tOm7KGRC%K@8VS%UEd8Ng`8g$Oq?0NrO4^Llu1yeRs@oIl2kYBX)j)wYXQr2C`ss5Ixx%+l6 zK94Slh|qTXaQ|tnjRB>Eeh(FE`}4 z8%OYfH`#sG+3qubQ-i-~y4aQco4bkQyvV1!358cTG44T1d=y~Uons4qSAB6FJENK4 zE@3f6)``B#NAIb~0Bru2u;wlb_8N9QhJPWv35Z;;KzfG`cbyyB6>aea5 z$uH>&?Y>V}pzU+I!hJs7^?u={t!L zo#RN~!F`S+eLMGff;)EfE!>|<_cL*%@1p|_n;=rTF#a6LRvhUsk^Bt}K&^){DD<9t zL2r&l&8rF?jgge7(P$vVEbw@->HHL8DwxGN1(>AAD%g%4?J5nmM0FjUD&ffxo?CD^ zUI0{~DVLQ5hw#k3Tvul9#kw+cHwWl4)o#wq11}ehriAJy>0U)MUrf@yB65}P95hF@AG&{wX$Ppphqo(Hk+h|;j9&L>qn(oo_$TEWeE3|w+x?*vKxH9b7j(gDX zOUj1OLk*iXO~w$qEE3QB47x>U@Vp7-V2Y1vBV4n=;fEk_;Lww6%Xf-G{80wYF`%oj zh|^7kJWlDNB(z#w1Hvx&iD1!^W2)cmjEd^V5m6-Cve6?7bgElbOLP}nHTc(SH(ID# z$z6`&@`?_!3z}hyS)seyF)P%ReW-BsoIzk!wt6=7VkTzA;HR3t_Hti?Lh_9tqP+Xs zRS&KtrM^1SwfZVTK8o5y6n9tF+i|GR#(UT;+Fka8QeBQ(|E&qxi86~&vYEC74@mqPk5sYLQj!`dRMasC6m&yC=+!eKUY%^Rs6z9;uMghFzpIwfdf^^5+4AsS&lj1oHkZtfY< zbLJ6-=8jhX4nUWF#Mc^W$F+(eKq7(h4r7JsICyYvSq>5d7u0?c-EHE|1PTWvpm zt%)NeV%&gvi9P{b|0W@rHL#=?H(Fz;#OTdx)bZnJm0ARiLE%R8WZjw(2o1O+RkdSP zwPXOKsuqK%Shu9G{B6;}G@-Oels}K)12_ampBL)oqg<{p2d~WPW{BzF3!H= zkJf!!#E0!dB0jjoi1^@3Wfo*0o)Dk3BcmZcwv@Dp4=xB|P6CKvPTVEp6DR4EL42gB z1@RF%3*uAiBGDv>Psyhf@yVc=h|m0b#OHShTkM(@>}YyZn(}ngdo?}6SN)W<#d*CXpsmq?Bgsy7tOXBBiA8COJ~dAfDz( zDJe8cj+ElS{gX&3j>g|@BBdyNJvFCDDLEWD9#VO;eRK46j%TeCtpD@#?s~`I+9p*(toYeiWp;KpQUeRK5nBocBj2i)+U`8r1cnT{F~`{^A>12-c@3Q-@^nFNZ(e$5a+ z<>3~w+8pwP)9>;vJJ|Cr(a7`dA`V!XF}}9t#E?A;`L;ia#lKW<0gYstApEe1Boh{a zQkE6?HDb;96zm)*MJHhAKq-Xc=X~i1l%f-|bD$KRhMfbY5HuwR#ZhQ}1)-RPLec$f zXXDI)R%rgSI2Ah|D4=hpd7DhqMzL`7@aV-9C?yY`vL5`Y*r%DuI7wldQOD(ci|vmb z$E=74OSn+AT?TQtQ?|~(p7I*R#ZCE+r_c_RvJ5PczZr+T=}=Oe?K`+>Z73;ioLsY6 zuy2R2rRmLr-ssuYmbm^AD5ag$BFI=*j#>5>v{?<}NFW6}c8Mxs@sXe4Vk>%Xjo+5U zhj}=jlw(;<$ER+Al+RWFQraO#RA&;g5zUoS5Ptq z#zIP_TT;4}=~mnlH?m@!o%r+M$gXdw=A6Vm)RK3bkl}*h_Zjal40``9N=opKS&Oi;v=ln7VaQ zL>exbxOF+qByFY=CsyK8#YF*NQ5qzCqU1_6uY1*x0mT@uInFLw&N<318O~Q5yLqjt zSFeag@NGrGksGdlH7*C^a)_F?2wLPsNEbFE(75&65a={CLFaQRR3SS zBq$i*_^fs<2?$8|JiaBt013BvNq6+Fs5y9DM}E;4f!0&&tpLKHWX~3iS`h-1{7wkK z^n&0OM+QqZsz4x1x{;I}>l4544FB4=W%(VVg?DAYx*lnV%31DQ9Pd4fR>r&?V_un_ zW9ifpHb&9}me;U8^2<^iy6QiVr8-YPK=47y%R=obeOez$Vmzao1bEIWNuv932XAT_ zBsspS1DI`{(cnEsU1v0i->r8%x(n8I>+O&3-mEM0a-*)H)ErN@OzSP&N-Fz3Wm&Jk zti&YAeV81qF9=d>4R{|N<4%@ucV$k>pHySZTpgPRi1mS}4|%l&CEc4qwdHUT2wI#P zA}h~Q*bp>5S2PRx*T)^FxswRG0`55J4oOfQEj#UwiBgP$V9`O1B<*SDQsYUwnQM(I z=>`_u_5G8cuSUlKd=0aEeK1TW;Hjlsbz7ZgH`pcJC##%KnYq%CrMxS2$J?ftxN3Q1 z<|KdvRX`2f3W1^6MPSh2k%(DiI{9kbs>h;Q%c>+Z3EWzgEeMMFs>F#0a zf|A={7yDYeLUljom%%B5xzK}#l)8wGd5wK9szZHmH|+T(=cP`Fsq8lsYRZZs%3QMJ zlxpD}q}9aRxk^ps7eEfp{@_tP5jj7U1$|}6oWY>GAit~bNC!^H#3mRk4eKh#nU_%` z_9&W}j8HFZH&RQHZe%EIn5StZFvYT_z&IM|aio!5H`3S^19>y8#qvq>#a|LQ2p7BJ z!>quUSVd`DYt)2?DoER!7DtUSmj59SUqj5JWqjd>coDV?=)gaYR=bA!WLAD!);f)o zkc(+m32Q+}3qLV6p<(=l!2Ubyg__2nX{PQ0!;}a=hOnW=sDUm9Q{P_)x~Aw`6tStW zHBJK77?EFSHEU|J7?QJ}tlUDiC{3GTQE6jwGi@eY8%$dZD+I04$jR7sGZRiigw5*$ zsAO!%%B~5z0?-U&I~HFpy|(mNsE;5I;E$;+HHM`RpG`_F9D?a=04NTvRWaKaRU-$s zGo^1`s!l7jSgF@mo*HV|oF<8#j%64Jk{^kCjTtNS5DC z?Gm=(K9^C8ZoP}X$G%R|C=_rdq6WLdQnBaOmI z8qi}=3|STdE*pjAK}+=Jv#qyXYpqS9k}}q-x9+j2`Z2|lcA-I2h(cVeGqj0CAm*-k zY`vfm29|KJehJj24&-%>(E_cKFf${35{R_A34^J|6g>vnX4r>2!~I_yDl%O(hn1%> z4AYC;A$>`1BHb`l$xWmihT9K<(Acc|B9)?-O?~306P2Yem8EsYsnC@+^>qoa6^{){ z|EN2tUQ%-I{7VVgs~BWmuc?{6mX1jk!&EO3LlQ8R`3-jKZS!6CZ-JpgGl3D)hqAiB zP`_z6qKbAq^I+3%0r~NBxiU9MG}!X$?8s+Xv&K zdYSgnFobD#lmdcePZhz2M-r+5UwC0CBJdbzN1R0a@eCZt)p zF~W>J9I8skjj|(KhVS^^s3&$u;tFY%)oB*|29%i_?eD|;)AA?uKjhA$p z+2JO^M(y}7ENtkU`j{n+6QB#BW_pYxj5gqavgUw%8a1`t0r^sNJ_E8ktC7ZOYjeF# zuVddqFq)T}nA&=8p%>@Ix8tjL<13QCf-*QZd3jN988_mFW%JA+m6 z@ty6A`(K{E@De=Q#`opa%}RYbr*2g0-kdtF)bU)&ElS;zQ>PFthKu|!88;Zy#C%wn zVRya-)t}c{=DZ0mrFU_q`awy7P*blQ;_QhF1VIp=2%)1WVue^7j_cLWO5j!vdSE46 zk1L|b{VR+upbc@=ficl*Nt!ARH2QP#V)a}bl?Pv%U!2*k>bAdDr)YsIg+YQ%bGl_<6(}Zs?)M24_VE$p>CZ>s@d>26G>Igp#p6VU6@2e zjWD21VATi|+Js#VD_Ij~HAhmNi>hWLspbz0DY6w2>rB1{-}5b8A>S&#jR;?D`11nv=JUM4+-O@Ke&>g!k=BB5HT z zOo9V6&5eSDZ{oxFDx%ohOMSg03CiA8M%6e)C7t?Is84Z zj6P{XJ5naqB8U?`(GftW3N37F%Py<2r)U)|;P@=&3fcQLM8Z*2*g2xY%0{OZ#BrUW zq7e$_soGKAWVNDI2v2qg7;0-aU$mKrWfvA&7?nj0$g(b$9+q`tw|znv>*dLS5NCw} zai}Tkvs8hpO@PI*F`7|J71($zRY+Z+5pAi0Nt!dL7=FSm$Jb*BBnL7nT+*ayVjojb zLu*oE++@17KpVP(-of||bNvOB1`U=o+#HP;QWL#TwV`{Ebf?fCh<3$T&MU&MB;sgq zOg9Y!U+{4nY0-e7cXq?)PBFcx?Mi@u<>~xzYTi}j{?o7Kw*O40^yHaWUwv6ogHY}r z66PyQY7`AQC(a9^KiyhJ+|ovliR4~tu_0~C&!!vFjm=T`f0#vZD>T4g^+QO?j7N&| zg{bHjqq=g&l!2LB*~Gxm!Qk70`Jh=D^e5C!qhkHYpw5uH;NVAWO954g%pnx?7<8?$ zIouIY!7#I}0L<)$v=5L-i}dn&cR6-YCrtp!K2?<}B0vaDmTC{E3~uQU)>pNGoO{@& zk;uqnir-Z1q~f1-?$%Y&5NQV31Z~&EYZ1s%$a>C3QsA?oGZq1Zq{b^Ej0iYbsSnu? ziw&BYRQ6GdG80j8+;t;NR~5X&6!o8VPNi?72GC=fd!ilX_%3a`5Lu!qzju|7#VLa> zAn}D|Kt%l%C|=z{U7`@R$;Z<)3Qq4c*&r>l&+}FN^hu*L>UO_=mPjkm61R9mV>Teo zqKR%V)z1#n7`AnLNIxs2aYxqe<@(t}dJlBTD`%jcTFTHohKry~QmuWy8t({7oGS6g z8VR*%IatN;X%r>x;}$LfqI@k@!Q4DNt)BL+HwY++0GO=4yrv#hc;bdLa1M z#5V`HxJShXFaE{Ocdn;TrM!sy6Y+oA_ia~{u-U0h{LRmDI=@E=goa(iZ>@KYPsNUi z3z*mo#&-}oV^@&TT_Hg*lD&~-nqu?_c|YtT(9I)`RcsJphOrE)!0@7amo5(n607I)Rdf0u-&U0Sxg zs7B!2RX>7{Go~uSGa4N^@zMnvcxTXZO7?h1l8#=gcOA8@hYzr*8io9FuioWC7g#6u z)9O_v#XwkosWFn6qb^`w8DCiq7%Yv{%_)T`iquOYrCYhwQcSmU+3m-z+;ywCm8X-8FgJ*sfxHeE;{i~(3h%~ z-l9fS6YWOLs{mtKQ&m6AJXWkv;f2ytt-8v)5*@649t|gTvuH&irj}B*puEGQtuq?c zHpf@qJo%>2aU+}`8r7PEXxJ!B_Dpc5oe@H+C*`Q9cSaDP`F0z3f|zqBpxvAvJkwIN z2ZdDXDOmAzd$;jq>xp`6Yw(_3qnxej!AiZ2M$Psh`n9G93-wM4&rfEcIWZZsbVBMv z@(@AwY>l#-=^m(=(_^i6x(6$>Jy5sLvIlC^Y!7z2Uu$|09Xo9gwzYd8L(j7So2=k# zZP7eiBfisJQIV&TnXMgK%Fa`#=6i9V|h1eCr+g_^*EPWjZEDUSxpYoBsO#SIuQR zQSZq0&-ubDl$2G1r*FIAbsy`K+!o2#-t^`#%c!(7y?g6NDpD)ydl)&grKLHSd}nS8 z50fv}wpP}fL#w*k(vpW*j#tUjl701*l`Jh9%xjqG)M4A=vRj#-x!2LzeDavPwxSn@ z+wh?iHO|%eH+@X{hRL zYI+PJmM!jMe08o^Hw}HgRrfI~xX5uI6Q*;>x@j(T_E_C&0y;VeSn!bY^H`G3dtVQBEH$d4tMM@G^|s#gOh>l;V&A}!A7+Zj`beLk6tJQF%B^vWnuMS&%ew^o5=5jfYN zu#8lR7tOQU1@Nxi__P>^#K9R11F>ZcVY~YMqT}dW5eex28oz zBIH&`&1>7al_iy1owAr+VQIt~7|-Tu!DWK+OwC#_p0P$*3C7#VaeDG(;BAOUw)@)c z)4iFXB@pc9r$7MV(_s3<%$PPYnfc(en5j%@H9s*m?QXT^A^@xn z0$=aB$sH%=7~WMdRDUmoTX5l_$WS;zpMBCqt8TUSTM^HjNbmoKmV>z{raDL{5ziXhMHAV@=ppxPUUO`LuY1pjUjN3=zG{Ss z8r+#hu)&en!d^b~_Rqd|B=v)Nuuk%Y554(yzkAQm-1~o-3xhX0u$xnpKK{=C@{2dW z;~jtG1G{@i-twnE@sfK!|LS}0BTXE-Bd^PKJsTfyG?Ub6Z!OGrg?yySqnT{f__o^Dp|TFa7F0g}=HboihFF%}1P_^}%0y z#rr<;E6@M4TUqv;pE=EYd&GiGO4N3rNu=FH@LmZ7?9h-vaFDbGg!!50LX zK|el7({KOC%l_c^3(n)!vlG|;iJ;KM{;Hu?HGQ0y#u>|Rq;i{gvIfl zx1}}zCzH4%C$1!Mdrn+I;+C8^O#S%Le9H*Mc*Tr+xO>8|_DWwSng*yl95PTL5DfPz zTW3CzT{rt{U}R($qbQR-a#C;YMv{;Yn>o4N#j<40!(# zGC!AtLo8|Rh99zk!A!6TqTkSL<{lCrHOiao_&s$NKf}T z;tDO-(+kBtbe|qROl*Yi=-K(=C3#>*TVNc>Un;i_SIA`18sV1ue54{t)b*D7VHS{l zdtnxvw$yvL)#@|_&g0e^(`E}(gUFSLm0LyI*YNK4PMSoV&Q5n|Q?K51Tbx{qTaDAflCI}nTWg;bBWwk*zVKQrf6PM&Ugsx4OkzOh9HIPd z+`DEn*22Kodvcm-VZJut92@tiJzESdg4GTyc8rB~N1=xUiBj-DKhl z+XxIzu3}H(6k@TkkTIlXPg!cd08P!UXrmkFcIVgTPlH&@iZ&%`Vq`th+*pHQdaS`P zLqczjY!s>iHCsdHITG1Vx7fo3A>oBHex{;Z>Z;m zSVkhy39%v}TiQ)H0I`IG@LO?5bnKRC#U}C!WxH)xv5mYBuW1=o2Iiv7z_djLze|L+ zxf#3pc8gDI4s<>*ozpON44{u*Kqx$cJ%xi81bQMr=`6z&C&lLrgd}W;PTDX21_~6RzQ5 z!j}9+WhGKJA$W6HxtyR`fD2kzCKq}!kup=-hPq6Xvb9uL9ZuV;ck7nzSTiz$eCvV~ zAOYsF9qw(ufaK7K3w^j#Dmy=s5r(HBW$=6%gCzqDbLqmu17@3EUu9gW7d=${X_2lpX z{vLR*OAzRt9Bo4=5Fj8ZjC4#rK<}UgTan`clpE^hlcSa4CMo6BYj6?5z>GIP@`5L< zx|X|5ZK0tLxo*n~II^@w1y+e?q=e1MoT8EW@teN<(p6hi_N>3UexXl;-ZZ^7Z7BhF zoD*r}CPy73GjLe2^!R6i3{#>Fc|SUHRy8{ah{^(WXo)u4mG>0XI)}!LlAaj1!KvduJrsrl?2k%E@jthYlV(gMqNXnwMBY`3|?HjeE!cL;0PZ6g~;##tJ%hGMso_aTt> zH8>Jy5~8oOv>h~SR&fzhBEJwBVA{sfQpJ{=YTKgBmWe3C(p#q0Z2Zc%n@%IYKv%PE z!*n&vE#j&WDADCDx` zZPkRt2GL|JotQ*}kVvi(k$EaZcK)^b&4z7eMh(f=F!eKq*>b{!WckPoZhGtA$RkFi zj4CvI@}@CCSw8Z)Ti^V1N(u{kssU}hX_k+?;bX7SL(`UJ4e?e|CNIlJ?ta7Xyh*Co zHynvkM{`i7S>lpfe;N|gGVySd?1XG&6}WBUft%$5T6762hu|kODo0v|#E{LXX|POY zVi+yi#rTFNO^kea(!``#c}nwTfiF#Ec+$jVPXxd-_qsJzYnjm3n>#do0nW660C?tJ zWp&BtEmCA*p%Y6^u+hdx>=R65Z@2cEyM%irLHLlDLItdyMZoJd+oLRW<{4 zMwSt_wSUZO8ygAK51R3%>6A8UZDDM4*yrXq&7)G%JZ` zW&|4W_0-n~jbgb|Nw(C+ooVx7OMRVMnnyj&jLr-$n+=&KGeo)OW%J>g`}IGE^e6^r zd;(+6&!$4WfXv{~Wr^3A7~Bv8p*B-ZjDz^iv~7Vb)wXSGEVs{?)mV_hthRGz#gLeb zIKH;5cLbrUd-#^Eam!|tE$^>PTiS5M?w&B(V{y~j)er-1?Vu9QD`#~Sh4n|#_S!AQ z3?@_He7m`X-CfTV$jUe0#EosreyKy)DgG=}!&bww($t%1_?kEjdmO`cFx~J?I%?i7 z5HuVomJ?F8WZ?55?ZbJ-Sw7{AV#|Pt8T2G(KT1v671dQ42)ESRPhytuW7c(To0XXk z;qKKd8We1d>?_3F$ofeb4{b1B;kB(8i+5tP*f#7JFV9T#AW!r5cEe#i z^?+$!V+pS7^QdI|^fV9T2Z$AApoVK1n+1{qu76a5<#)L3X{H}jYv1YQgM>SQCgNE-Y@D&B9tq3Y~!Mt}w>6TK77duiB4QMfGzlBX3x0 zY~&3qjg7oo>Y;#kLWOz8_TI3~*wZcZ$Mtw;<|!@SnftG-#5=R@rL45NlPw|2N~=5B zPNJ-|y7Lg4ejhX&T~|`oBB_-^c;(a*8$ynGCUTCI!Iml5CSZ8yH)YXvWYMbW1bF-@G&f zK7SK0123n%509Q`KmJR48XYzLpk(Fe^i zvy5px*}qw&=d`66Su-jZncws zU)*YIt6am#)z(&hjazMPRf8HU)9B*5OI~g>tUcRt&bM9w%;aWY!^339$t_k^l0~x< zm9mm7x-T(tWhGfO(+p)LS=0_;EC_`lo*l;|Vq|AA^)tE{y-OYQ-b1#*$Q&^I4%-5} z5tS72jg63Pnz%ez%1RTLhf-NdPs*ZGcr41p=4^VUt@K#rwoc>PBgssv z-y>6}6RthVPptMms(E7Ja=)KQ<=fvpkivJs`AlqV~(Wm zS%s75Y=c$W!gO&I&=w|RmA2trGgA9_P3}GVFt^$zo;v|(=9y|dm2<0Fp31prEl=eM zA~v4N7pLy1RGO*DtT&#@UStPBrcq29Y~B|dgfCo4)v44U&A~Nz>S=rA@Bp~M<&hu` zm;Im;m&;JtS0ttM>hC-`9L^%#6m!eNim4~J1^3L{UUZS%8}KdnbtuQd^?Wj6ZjS=; z80GNIgizH=!`#f|U~W^!)zdRKkB)bv<^5cNh%p)sWn60<$kVtH!nKj)?{D!=6F5P* zXjHh8WYT#S^BSb{QEi0VS06YD`P?f%pRM&a`T6X`MswLo$m5{?4vVDqrIJDc?;Gli zBcM`S**_R0Rl&T$+@F?PsUvqJr0t#5X<_=s_$cLMr_2YNoxv6xDe^P zc@AVsQUmM=ge2VOF1@uG#67!pk>s~03ktVF?3STNAq*94;XJ}Pcq6cjwQKH<2kjC~k4L9mo^eKm02-@IIL{OWZ zVEI(k2u>YH1Bo>@gCw4R`O{!|ZWyqYn+?KeZl>M13Co$Fqrd}utYMkn1D{zYtksy! z-gvWGOgzSLD1l8rPy#QTKnYf|K)z9LCJ_q)2vR2|{NU?9F?sAXeTk*!k!`co!0?Uw zW=ZuLFnAI&qCAZ07Wnh7_|0ttG17{%30kvl${wAJLp=qvX_=%&(<#29xLVVebUZ*Y zC~r07O`NBf?NYtX@8XcGInj&O;|LjzePl0YWbz7ybAu? zHv0FK$;kojc5hN1u{&oP9V;fY5vp0>pes9P8_ik`*)vNzw($e)7_Vm<%_=}Lfjh7m zp=IcTqN>3)*&rtScUNmB1e);!mVvxJ5D$pLgF~htuoN<%y{a#%(bMbtk_f?fiOz07 zS1-sQkRIBBr?H~ zTbtMgtuO}lF0F8Mk31J(N|6wDvof|z2V9LFt|^=Q!QD8g@6zc?BbGyo(SVGF`Xb#f zJ-hu`tsX7?;OL^=*R(%N&?1#*8RXfJHi6?ct?vU|ehggmxYue&JRu0I0yTUUD)F43 zzy6i?6U6~18-;p6d?7V z|90dH`Hn{6%@Q#mM9L=!l|w#Ao@gNyXQ9!WnK*On2YFyMkYCkr$m(X$N^I z9OQvTw}?*>TNqN1ho=k(Zm0lHf;7S$`c5$yIbdUzpZtV~zoeTpN-n^ypLBCZ$pwN@ zQKzOn&|9_31J_kkACd&05D4q@kA6&XxISoDB@~rlRhKx8gGP;jC^yfi8}4ce@Lv{#xfM0zwb!M-W^2 zTOC;Wr#tz`scwpi;ggGmek*mUOBEO5%?D0)h;_Phb@dC1vCF^_)jcKXfMUtU6NbFh zo%>lr8Z{^GBnhA2=N^(kgyM+~`t`tcY1S`x<1FyQIqYz`T14z_zR)}B1VEzCMS{&V zB$gtvedqYqz9XXfQsl+?lzL-_!Xf+ViUJ|~ zZjVABL!>V&4{@QU%ZZTvsrTP@&mY|L=fC=v>mFSKDM$YDlW+O>FWmNbx4oA1Drutr zyP+;k0Og{(RgEGfdcNT#uE^=;n_j+|%Qy47nZrkqsd}TQl_1;W{+Lj`^tJc&Q8_;T zx>JRM;f~9vD=f7iJZCzudbOaVGoBl78WYl&H=jFQzZ+3x`(*>M& z{d8Wu)EzI32V>4qPv^x;1m45d?eSAZ zbsIxP(|q`Wzq6mO`#T@#{QJwm{zxfnmFD~iq4;aQrB9Ae{gS^+@SoR#y5t-im(RGY z+!yccW2&7Sn4I3{D5gUU2KWmh(ym9t^pC~}hMZ8{( z7pa+W*G-8H>uR-eZB6Alt4XKF{nKsJ{5N3l&Rv_nId?{-8H`?wE$42;&mG>KyEc6z zLcup;@6KJD`sa+Qd?U`?KkYW1ySY1e@O17*{M@za+)=uJ+Pyn>BYy5`I(H-fO(^(! zOBnyO=kDCW(>d0qr0?mhHT1T9QoGS6_o3<@d|XyFSIM=Ct3!?UHAPRSwk{Rg=uK^x z4^jVY$KvG6=kFG+6X=E}@ z8txw6rw1$f1V&qJ_2QDwD^p{!AaG9`t6wZBjGdNasG@S6=FQ9f-r?ve>NP3X?AOMf zXUa0^5y#HRTe*)6OMHnw>PvjE{iR>hIbrdg=prv#0}s9X?R5sb{LiHOJO5 z#<}6T>s7zZ3eQzd2hicWr1Q+{biXi3Vb+VmQ&-$zfC3|j4vdVRU?c78D0WZ%9vgvt z^kT_e%BI8Uq*JIngPmc3rkRZy2dMduCN~Dbu)*L>55nt9z$y(xF?hnp@AQYAm;+v+ z-^n0svzQELKnkaHm(OU|cyyy0RZG8m17qQV?D;6|-bNqkjXcl(mhH9rcr<_Tt<9%^ zR?Rp-r_TCBSB`q)TWTd&u%P(f!Jei(Kpqg12dCd2(|9Q07_2t0Oh#JMw=^o~#s%P~ z;i(urYJ-CRiGl@(zoycIt%V2GpBex8b59k63ARk@nRLT8j_L4y1-C-&|&Qf2!c#o`GxZZG3-px6tFD*AAYz*5QRl>QD^rnU{u z=dV9p<6`g|vQ!6MH5uL$WOyaW@D48SKrcD~0P=)J(i)jmeH!ZyH%)|_CtPHq>>Ojz ze0%IFVTqqb0my})_(v6~*vhe{Iw*)w2;|$w)hIU#I8a`p8tAMZ58gT#?LT-d9iGW3 zX#ok0@S>6ou&m&UYOxTj$-&IN%GhvOp$A;{T)=uRko{(+n8hpjpMG{=^d7RBxqxWz#>FSOhRS#9@ZKX*E%W0{=ih!y8 z4L{*aEWZJ4(MngfqDGPDclXf(TCbm#>Nj9W>7(hPpZcwKM$aX|s$7e^6^%W1w0b)o z*uP{eZmv7M{dlanQ&~HX{=jk(eRUhAKBXf*-J@up-mH&-5i%<`pKf)aj%KNt9`B>5 zrjJ`UZI51UrE3O<2Lj3(NXW(79i3{9N~q^iHWgE5YxK@ACSKv?4bP?<<&mRTs%Pn# zekai5uSe6XQ%sG>&3-p@zhI9AO&DP@_^t*oJ9!~vsk|;z=DWm{8OWk~N2zgx_?81+ zZ>aT!>%2aG-}R?rq2ju{PSVH$G(z%3<`$B#fZo0d7=;?a3Q8c9DQJplvB|T!WXK6> z52~2HJTsih!S=FIN~XX}(6cb+Z;?u%;naR;dWtEgu6eovjgr3n|x_vsv;_;01E zl^#<47Pm^k7ngMP&yI>=DyrXhvCH*Y9za!fT}{`^t9x+5Amh^M=aLv(bt*pcnKV6KyE@zOiHSc zas=@}=e4zH$0Ii=Ej(xy{gw@is^YH|SG9|O+XlrMrLo*C7pC6WxGhDy@{Niz@$I7D z*R*4eBEjfNL;~jT$~4xLkij-pi^PYSt|X(MH>oS=NKnziBi7G%?XKj2&nh0AOk!4B z*8x#AJ$<0P`Up7HqgAAPF+g6ij&ub;E~#CeL<__s4is5M(<{|6Ki92M5oB7j3MMhI z;TPwWBbXEx4~Qc?cfC=FUiZfXuOyEbqpw+C(*W7>N|0PT29p_EizV%`nsBcm;ARC@$;1kv&gf~Hygy>*#440flM?-3YN z81R;O(Pub?Wsn~|A`z_d|7|sO4Q3i?(u<=Gua02ciDY;X#`2wf)>T)FM*BH~FBl1` z5>NdweeHoYQs=Qt6(0P>{CqZ4=^EhJqnp-}))=cSE?Fa??b1=0MJ|12uBiUN#t-xh zWDI3uXW`PrRHKqM)wIo8@;w8nWZkmvg}kVN<p_-VkQXK=>L7zQ zl;}{3KCN=8k5UbDf4NLb@~oNH+`i3$t}+0=nXA^Lzu$gqu2DXNz$u0i*3 z*CpcZTms=k#Z-iIws@D%YJm9Jk8w>`d(-SAQN0XubCv8D(G1g`{ZyUE&wfLwUfBm- z=pI&!loF9rFTi9a-MXlu>3}GniiksS5$U5OLK5?+FGPA$$`!4y(+QEnb|?DnPV|~i zEK`5$3xh#2-iFndxvFg%lrLg!poCS?9f62~?{YOWNPzS`${Jsnl)cttNcJ8B-kxEH z64S=O(=&GK%b-=m#tu&CP7T0q5llX&*jyv!Y#FbNil^7bGnCjoUeWF22KObtgOQ*? z;r(DTG<}r|kh6~qBV7w4{j=Zl@I>;ZyLwc8sF4>)?yEiwMuXw+p$ejvsdkI_7Ng>-x+_WVc;~9CA0xBA2s0ozmw0?d5Ao8(<%*6EQ(|{q|>E|W0Ml;Z?f3`a}q2Fhu z-i$4z#v`8=9c+Rsjt0eEyYwKhVCGz;8n7|ZHBdK1b;tCYfu)CR$rtGi3w)4Ao%}~9 zdf8|ngOd=SvLXY}Mc|cgQsmDbSIyKmn79Em70}zFX#DZ~6xF?Db!TbVPe$wSX~FaiU=2eIOAIUo6v56rH&1}2 zp(}4Gr){VuVG&o`8+J%MX6Q+p53J$mdXy+Iuu>lG`rRPRR!8CLLncJP zBPzoUtO(FCWI;o_)yGOWK|FD7BG|So2RWam-JSL%+?w||$c*0DJP>0=Wd&BCOHm#c z81=+7yS6BcnUTW+jV{IhLJs^Y@<8n{Z`rKAS$2z0BH~bw)Sr-$p$SiHV6TA^p_b4| z%bg6fED9~1P|}C z2KIvA>&E<^inA^G)^3a~67>Rd8Wtjn>kC4^LtGf3OSypU2f0AT_j7?^ta5>2?Bl{N zg3B%TNDv}Hc}YY39BSJDso6HbJ@o>H2t9SVi4D*-IrCCLZb#I7$Tq;LUO;i-hn17I z4NxBn8{i5LWpWnok-L%vDA#EPn@qOciHP4V!~|nW>}L}7K++OdOHInQNzU)mYfZWf zGxZEm&}}aHt^G6%K=5x_!aOl8<&7FQPVu2Emkz z+DY~R=|%JyGtn~(5(jLj3Tl`bOd^dowP=Cgx!|b0u2KotMp}~68lJ%WL)<<7S z&_W3CIf;f17+kt>O-tBj{F=tMdFiJUB|QU|O6uZ%UWG>2v_vEvi;o!623(7$Ep}Dw ztv0(#RZ%J}6rYZ3F`N3JeiCc>UNrBitUX$z4c_AKcwN=Z$jS8Dy6mo1ZBwULY0atp z`UB%s>+nxjgVgzB`fc;iXe$e+E%x^3-ETbMoEd=Vw#0J)P{*5vB;*cjZdFE_B-bQ} zq4$wk$JW+%QfryHAlkBR!Kb0t;~{up`5x+R+tdz8ZXMBaObm&-hqmYkltQpJnNQdL zRyo2n4qj|{-Lo`@V(Bs#^m@qsaZJMyb|t z=t(@@&=~am2?ox=_z*cIuh^?&l?xw|cL1_X&83G!3>Vhlv$*JmcM8(+773fU6G--B zt)6vwxgfMGsj4-wvtn*}pZbMj{NVLLb!)sh><-`pwZ^*r4Zq5l>~0`to9pvCk}`AM z?To(N6arcDXWa^SYG1e;RCYI*bTb+tsZ;GwQYRV^6{Nb;$K^HDk~)i~MAYt5$By9! z0#R$c6yCWGgAo&jm%=|a8!#y|E*NQcfq_jR)-Y~f(3ns&FKqb7ytk6$2iTyZ&aLc& zVq==vljtY_qsLL5?~duWH+D9$ck{B)n-=RG{p=Iw zIQW3MzOu!nS&lbJK)#Vlo@}H=fP7UD+u`eo?XzVyAyHNa2e+EZdF(ReouW3eyKdw+ zH!@mxR|$o3i>XyU2P;urLK3g7=&H^p(E(fJc|p>08%!Ga=`ri>>e+!}S1Qpo(J~md z)mmmR+#Dpdz&>Y75S5a_x5Ki^%z1(6L>T~e1_9GB2xu~xK;(*6@~BUfC7g-L(qe_c zw*llOE3V4YYm{nS#>g|4umYs&{F())rh+9XH5^IlC8>{-H->;rh>*Im2$_^x${2x+ zVW?+H8^xTl6nN(5t(Yly!**W`{%}GW8fzJhJfv(J)+M|EsMfSK7M31X45K!&S_D~Y zQE3STlFGOu^`hwNE{d9#+QLpCgtYpVeV5k3N_{t(Sp$n0OyQ%}CM(Bt(F4suNRNJ|&(ZGNwwG$8yVL?F3$lWj8z!FDwS8?vHN z10Q=AY~=mCH2CC33bvLhroY=>nCaz2E`DpvlVv;+AtPtZT-Sr z2Hk)No?-@*7rE~yqB-l|XJ^v=&>286WJG2~aQH4k7u_To+)mvT*hv6MTx*9|F$L^) z$F;@egl&3N^r$OVCXu6?EJTK5t*VN9tIl^&XA&Jb_Q3osK8jDHd0cPocMK`(akmei zP1mxRIXF$vgiuY-gkU~WdR(`*}lL%a$rx-uu?RxHm>i(6?-0*o~n|37>00%zG(*ZJ=A zsOm~ib!WGhQj+rXIaQWYkZSFj+lD5#GqrO=h)%}Q8E0;s%e@!o#9d*)ui;5hf9 z-8|HYfN_8T4h(?+;gRr=08yee0WmTt83zF`%otw2KtW|jREFH|@AqGO?R`$2Q?IVh z3;J>P-fOStfBj$UzyANV&Cz7sHTu-LU$D_my@e1X?>dBZ@kbXh=LM2r1|z4Ji?OD6wQ1>@EIk{p-{G&eK84>MU4VXeT@Zr2~Leo zzAH1DEXL}+S5N8(wn1bw=)}dK(}c+CB7LK?Y3(6lTO+O%6zOn1X|b{l*IF!Gw3SJ> z3uFyZtco=(b>A3lmYbe~AItPH^hlg+*eu8zp=DE$<@1}-+*d0O$;+`-NBI}hDY8ob zce8GixoO)Gk~ytTiwTAGS~|&3_b8tY&d*Bhm=%6j>DNQ0pJ49NY8tJ4of^0-0aq?V zKqT9b=1m)+B!vOYQAcDWWX-0@Rzy?SkC>o{XtFJ=iD=R)!pjj=<%Po#-JS`bkpsWO zo=W0Yy}X!*ilb4lBbG$FGtzABr9cIdtmVZ_1wqbBxgdF7W2iSU_s2EFkkxc~4RS6! z3C|vxqiuH*e#PPkpUKw5eysn%Gg^z|1&8%&uUUV9pJv9+AdV;dM{1e=s%i=Pd3iN;u&g!NtpNspL z=#uk{8J<_dI22?}-~E;U5@%2!oKYo zN%i58rbqHok-~7Er(~=XV)9B^*Uy@hhrM)qX_PB3R?XpWh^d4oN;p>@nN z$myGGq?!ZW3N>rP&aj_&B+UjpYWW`_S3`o*G7Sor30}1)k^lfqRUdb@f9MLf>4oGW zgM0Wct=g7aS?avG5v6;>pTHPN9AgXkMb}y;Bp%xcCiG%1gkHo<2f{_c1UN5ChqFS2 z*#ta0`sI24K*IQpk$_Lg2YA33`A%FCShvo!KOf8=>Jj;3#42Av%Br$kO3Gdm8k*!K z;IyK?6zdc{R-F}VVr0Y|UKLC<>l78L-FoVkX5OeZ%13_2Wc@|%MU=O)vwAYEJkyh2 zXafXc*kqxvm&EqI2$LS@9TC+&f`PiVPVxb(8dW&`7S3X8FTK;iLpu{i(e?6$q?po< zH^fs6j%O<9)Y}Rmv)SPacqhg0MXpMWj)K`w^3l2AWOYa6A#I1NV(l}+J$7?BZG13^ zA{t6Sbf$~0P=M#6d~wv&u4STYGkFL9e9|UO(*V^2P1Rc4jMcR`>x01wX24OnEP1CN z)1L;?ZhpNPgz#=e&jW1AuCfKfpcwo}&YU?Ynr$>@e8tyCQzSMeIw}Gat;ZLpB)yHt zQ_}elWV_kZdk>Fo3S}sNfpCRbqO{^>C(jN|8D9Yg!*++IVb{FzriLqIU37c%G7z$X zc)`Q)j;A+F=UVIleNXH_+MxIV*HR4B<)Vb;wL67Y$QH*;HjsxAFPoM>|A316e;HUK zbA<+|pP_!N7cXquFZMv4VXsmDIulq8q|o($kI)s0@S`(i{c5qk8BHG6$^BBLnEtw? z)$`~(hXA~s@k~4fK;<`|1EAE=qW~r}D+9S_I=Zcvho@9BDRFgA@)(?N7#&q+50Kn! zb?Y{&Nfks=>c6y~_Q?RFo!JR!Vr?>7t_AIF;3lnEJv0KiPloOe4hp!@lLG9$HuCze zUK=&hh@F~OPdq3fV(Gi%vGh;xw0Pr0R%AVdPD7w#D9|OB-Fjg&9p^V7Uh}OU%6D9R zg7ecQ;L~F7#{CY6f29aPQP}rYK>STT@pKwo$8t3gvTqKEe-)p`QI;ZDQiQ<+})?--BR!@7f?eejPuDa52L(Ox}t;3}o#uIEq z?V+=vt5{tUo3jFP3lJ%oJUy6~#7gV7oiZNlI1_@OHKTR>bMU5q@Fte1Y0xtCNTu?U zFZzY%rkx-3FgoL_6*~X;_${k<<*PZltBx6ABzfz(@fF&VS9-AKljSegY-sQ|Uu}WI zra2?qh(Du~XPF`vYoUmOAydPLSHx($TH35}`KkyXeihD8?eJk87^dLfWS5#AKFnc! zVn13(pciFora+2+7T22;K3umD)ZgTCMSBY$_8<>@_Qy?uJr_r0-#xnPnYWd;h)Y#BP!$lQ zT=xHv2N0~bLF^*zQ*JIeQ+|KLxlrm#3|SY&uR0^|hEGSxmHn;Wy#OEAGs@3y-7e^XPX96yVv2>mk zM~d*>YaFSTt~-t+H4@O3Kmu-ZG->^2t-dL|C?*T>qj^!R5;>+c7R4m>V^PfAZevQ# zgT=gRy2HLCUhFRJXP&b@j5Kmb=JN8<#$pdNa-MC%Msh zXGg9-V+tdZZ=t0y`f*E_+l4YKjNT&Hhk#NPM%oRp8uI~`>$Rms^R8j{yr;T{n9^Dq z*8Z5Ch~YkIl(K2*mN#vv&=%V~O-$*2k5}rph8!b07f+CPO7F~=uohoTBai<#Cbg!CitO%|6@4N-N zjXRz;d}>|Odp>JQ*;DkXi1<83pL$CwR1bQWw*yC$LuujtoOIQstn%pnTyMj9fLlkR zqP2o%wWCBk5>+!J*tn)8X{}?sWf99t5bDdtb+dQidnU+VJT|nzMCQsMjbM|QA+V&Z zcVv0AeR|sfA+EJ-7EN{|itj}0(_@~6&@vafE zvx^|qwv_E!Q^HseP<9xEdXvqIh%hZYUe?=15USw5ijEhHu3>kB)*=73tod~IB?uKg zKJ-W}a(p*E2(`}3zRr0LLPgiuDhL%lUeMUrAk?2p%i(R5(iEgH7KCa>BeeGlSq==K zzx7wEh&u>EH7$$eT++%`u48H(s%1{v!7~@OddK3 z&4Ej@^r)S44ICYjMIYPA=tQW(Gik2y2KB+nU5CVOA2_bYyThH#$dFVjVjw z25-y9Xzb|27+g0W&e4^}3bCJXV)exFL3&8Bqwz+uqpTTZ;nPnUKH0jf?6B(8h?MJ; zEH%1v9C%n0J1QrcR+Cg8v7_^W`|?~--7*l3hmTIkk|Idi>EtZkY&Z1wxiN{>ZFb~+ z*wDIRajH+9-kEY%N05$bWkLya zfK`5ON+c~0K?$%|e2Ge@Qu(L?o-;uM3n_Pq*Z1&%MD6L?9}LE$*g8*gCx12!&p{Il}h$Z2zw{KrQG)d);}2Evq>d+H-`h zh7S8s7rmU0-7KEG*KFb0PUnkK_IeP>Vi8cWkx*M{Bwgwp>cptzQ)^|}URCPp=4jh{ z0K#$AG!kvwI1A=gbK8%0z8y3Rvu%sQ2`;!zSgTgD+Fq4T-4)66T$G<+Q7lVNOEqi- z$#05%S%C^D<}!jHWHC6EsV?hHsMDkCIE_+HI6H`4m0tc^BQdL=viV+0%${OaQRf-3 zi@&BJwXF4SZ*vAXHW}|SX4S;C)38SEST1WZ8~*~X6r4j$)>m6HaWdQa4PRkV){?r9f~o*XGINihsX`KdUhN1S`Gno*~dqZO^O5b;%iY<}>j zZXJ`zVkM*4YJg)H;1CC)Q>!ZgYMsHw84%E@jg-zImb|F z7t|lF@|hCgyU({(rqFrRf{LeO@Z-TJAKJh}@5daJV|ZSNvkzpmV$#d>VMwd?R??kB+6>F{3ET?x*JNHug>u2$G%U} zUQhlA|({L8P#4AtH`zTb@Y`TrRs|x zyOXAPQ~EY$J?NXaoH&(z4i5LpHSb)!;lQKUd()__-djj@B;UGw&W$}Cd~}^t-@t;5 zo7Ko=M}^2CJ!12LM&CJ+3`_{sPyG}#bciH$kXVc+&M_W19CE3L}mY!4%Pf`;H?+ zv73H=@_hC4TS4&c`uQqv9R7sA3%cb*i5Oovofy+MTH3_88KP_+PKM~Wm7nj)GuJ|J z6EypSk9pRA0!9BmB(B5av*&}jI0lH1-X(va*}<-+;LoNb%ehU#Bet1>4|T%|_2cRM zc#tKlf6bD~}hD}=Y;n=6I2tso46+zkwu0STa zy?{fk!gW{^>-lO;OFCq_s$)f_rJL9&n_>+c?YG#d^XM&Sa*(?`{Po3gJ|H2MOCp;d za8T0wiGy+*yq_BzDdxmiohlB>jqJp_=qGXn2kktni`k4iV?!YjTLU+P>_&2bP($@; z+d}naKNZ|;f1nB(WvH$LIiGfAsIJoIM=IRGP)&|TA)J7F1J#9bsOs&Kp*lRgP&}q4 zoerz*1l5HGsv(yINC9p!L3O=MP?cOFoxapL5>zjNbOcqY5jDHm4AnRG^vPqGn*S!Y z5sDcs9)(ca!5VyK@nrSd1Xn32p;@fer)DPzC5r->9HO6YO_q@n`^zaPA>5)Al z7O#Aom^Lc=kM4!4K+aVIo6M^T*xa7562J|uqG$-%P8G1Z(IE=D=qGXnuxX$au+`F{ zR8ADbNB8JKoLSb1jxA+srs}8kQ@)aHtzN1DM;cgrjl2&ieeja_=*&ChNAm(rX*~=e(-R>oc@ktrk$Bv=SItN#^DPmIT^xlcrqW+tZ@YX;`?* zGg9TfKuYHC-)UQS@)nt#->rM2PO4fq33L!K7Z#Sf#3$-=Pi*>gPjrk7ns{0p>N^~) z4ZB`j;8^s12kA^&yOoL!>G*M_>(iw8_(OH%vZ9EUE4~dFfubt(rFC{Bv?8 z&Q!iR4=a4h2g!4u4rc4{CKpl0v?4>2P7~HL@v{Pz%$@pKDBr{a*>+UJYw)A3$;owk zQ$rfMb?*)x&&v@e$0rs&x~ByQA3a3Trxku^Ppbwg`A5rV&`L^Uw3?r!?1#J8;1k=< z4@;4e`QgJ&T1II7pVypB!fH&+Pzdwr-eQJvUTM%B77B7FWqGl9dGSLrSCqr7o#$#b z&DARX9GNTHj1`OOx%~7`Ufy{cwWYa=N>p)K-mbawYBJ5$`9S+;39MV7{db3X75tcr z^Oz&G6c)}KOqazNOq3ykMYC>5WF=m{gBL^Hg6}DCyyLGIfZj^Y z!3egNY1c+|I{4g?d#2Kk4jFXr9E{*+pT9&pMmRBwyC|usn%R%(xy|UA z+~t)w_jkQWrnGL_B9390A!>xmY@ZhO%hm&zl}SVP0h?l8fq5kvXzp{4#hiD;Jdrro zeL&8e@a(=J$W23iL-#>L*cyXZ>a+qg@;jX+=QWw4^6e0C2@m=UCNa`}MnR%M9IUk;-UingxYY|B-JoLTfJ8Aw|(icCNP@(nn`h3SL^5~PjiiuCy*tyo&NsOwq zE-9;U6XsL?oY2ACeQbxO7Ri%!8*NV?K;B+27O0cesgsJ>DrQ(Zx;l=#OIyXFPBt|k zllRCnB-`2&_lVR=yU)e7!{VvsOGG9v`P9uN1tgdXt-6?Yjb$&VivCJRA0p63il$Nf zzG=%>FUvR5WpAJ7<3yqqe8J?((U7UtOLMDv*UbiOydYfbuwxx0Dx=!8sdwuHEQ1|p zB}CTM&SQE*P^DI7glL!ahC4*G$Mj^=ROy6h3%x0bw!p-XAlfCp#YuQ3Edt>1iLQ)i zK5~{c&&oo^v-vij&4Y^>&uA;~Y$4&9QF0QVu?-vB!os`3-4notRu*!eSv?`FeROY) zOGjUqXhJZ78mbde(`9X0JEUXY7NSzTEvnC&O673jnt;E*Q{lQ+W?ICG{5tNPClf0t zwu_qsL+rEIf0r+i;RIowI-s1)s>&j zEN&lGKzFeqYUvYu;6uWMX?$oiCT!1#YD_pEe5i#8+wq|(hyc|DBAg>10&3gwA%G`7 z^iq@2?)VTeypQ-$Ky*iZC_{7;9}+|pA4=;VGzbt=;u*dxEf}14Kn8SxB!vZX_BZd5 z*Lq+9$3uVcPcjK*$vL5hxg$kZ7+l)VQXlj*f0(W7&XetbB1M9;1AZh|o9Vq)C1Q;o z+5p`}Cd#3yDiw!kEyMmUp>IfB7UfGxNnwpV&y_FJb7&E?8N7ft|A)EVNtvcqPk15Csg`-tC2;oJgFk>!!+g=xTJ?RRHckW7K z7E=-Sj@2WKWJq6jTK)O0*icpyU(q>)2bFG}SbqhyBhN4SEtIcRZ@sRS&lftz#LvZy zOu@33e_^m=OyQ;DF@clN(=$tfe(9$RsHSmRE~^D}w`e#tecL&0ri%dOH(%GV>ZM~#`Q%Ck_umK2~C>kw0taZ>_kShEMC zXi%!MhC9sQZTA_0*>FBiV|YG~lUX>6Yms$dQQB*#QQA|^2c-cA`+HBOx9R+tqe5Ez zxXQ%T4WZ{{s!&qc2<_B}X|(jSB@Q{jPq1aMl`HA%o^^JLE9ox$&E>(5Te(o~n4Qnp zLA#0m=EryEZ=U?hk4|toS7ZC)Z{8RYLV8HCs6O{bI|OSUM0fLc8Y3Qx(*4seFO z(?WRFL#GV`d`(Zay_4G^Ep6r1ZkB6%r<8l06A>qs!8CZr-l;lD`>mJ1#gm?G@8k;8 z6%WGR=~`^>^quXUsphbEk}-OAr6Xfg*|qXFQk84TzUlh4B94AI#wL!o0Dmr0JLxlZ z$#3aJ2|NhOuuAa>wDcdG|HrB7KVI-Jt9i~eN423IXYw87UA-9lPbzQQ z+^(8v4fbtrSN2a0_RO6h`Hl>@Gq--SzlUBh4^1z4cvAVcZF}+d(O$gZvmfv6p=I^H zXRl|~bI2Q2dRV9qp2TV)k+uH52EAQk9npub1d)$ZwmW|tq`@q@lL;jRlt>E4&)kgb~~D%4wyDn_6%MHO#EsK zy#GrEZ-$>xO)@_Km%jJ7WGw>PpQfFvwXM$Sk z#z?h`Xavw;J(=owZ6!>ZLN6Kv2S=_R2vDiRg41c>R24q{Lcn{^L49;9us!S|jAf_O zd)IczZBs4d*tV^WC=7(m!F++($ez3m+GO*Q z6@&uz;*u#v*bI^=W`pE~Eb?Thwar9yZn4K!$ugKnW}W81b&hMC%@tJPkb0-z(7SS3 zig!$Lr?&nktI9Q*{&F{ED~0|5h0W5m)}DMZ zsBXFA&dIUbep7ysuOp@v?OGnm*fJSb*@`wTM*IHT7$yeIu>;X}z$)k>$+4em^w^dA zEo`I9|Gnw*rRuVtQ}rVsR|WJdMj>kxJT5v`D5jw{woOJ~ ziL(zU4%{t2qB}sGTiu=rl_xWUwEWVidVV&qYEG5CL@l5qnDL$XC+UF47` zcdh(p?VHL%>a_BAq?S5z={+D&4q?i!Bt>=On*|aGT2<738DSiN@$RZ^#klWd+v&^; zraU8!9mK4|RJYu4)=~9Rj5NV9R6Ug%s&C}P(DlaqlyP>ggD}pU5_=r?Yk)wGhc)C_ zSVN9V8$SWa`x+_tyq1*?4lSv#hohPVSrJkmlB07n80_%~i&(~x-5%#KxOJAN^p)?k@G zbFk(B;K3yg!J2Pmq9x;h(FbbLPilU#l=Ei%teM)@6^WO(D|%v7G=}JsdDfkc?{KB+ z*I?o0r~3BWma^Fev#Mvk;H)|5V)>a~weB=68Sd$8K~$sno!RM`Y014Mw;EY6%^p^6$sr^0QPWQA0eqE+5S)>o#(?v5#lDLCUy;eDCb;U{z z7ai6cTC+Jm)6}eSl`rasX3$N3n1g4J>a%UxS4qVgsw3J4TJBcgyj*lQ#O3=dz3NQ& z@8Nlkj$3v(6QlR!mEs@_n5Cw}RK=Hz>NFjL<-(c~%_)$zdM4sN0Lcp--;-JLH?*{Z zD~j}IRNnrs*hE=9^O4I;#?TD$YJP~OZF zYIgaj(nL`AEXvnh*qp?=<+)hu@SNL|Qla6xq10!oI@Ou8AfbL3%zWe_3G=a+>>{*fxXDbwaG(aN_g9gQXWx!^EdN4wB68CNaUe{AHbVas zwhOO=)1myG@}lZl>WfvIuJ5%WqN98~4984G9aMBIc24VA9I5-{KR}iAXj5fzAD>4G z?=|%TJwbIB)iDL5poIJfQfd8ItE)Z~mu}c75L!%H^&~`VOMnJGKFEhXjRclOKX+`Z zR$qYGwE+@2ywf;`Po>6_=e-PWl%LS<|2ZAOV-AeqIt{x9TWOAD7{Ad;)yKrKZq_+G2|dmM1+Lfv1&9dR0tK#Xp@8nkP=Lbf@(KNHY({}x_l{BEia>#l zQzIw<_CzzDEFb7LVJiMQ=}nVYIMSPNOBF%0I)~>3p#+ulye=5|waH{Xkx5St50$G$ zCOkD{q8=+j(H+ih?JVbpWkBbm0I0dVDCLF(SEC$wzitc|s-^gv6(#Vbg%-s1+NriF zIz8`JT1E{1_l$;ZsZOWiA$PyEUY``=U>!OlmKQsRVqP9%`5zCuy>vaAt|xTe5$pfU zG1mXuG#zD2U#hh`+f#N`SuOMJPUaVN@p?SX*aJw>alj|b=AuGgrmj~92XU;tNh zxtskPJ$|4#S^kaeo}`25_$52}M3ahki0b9k^(J+R)M2F34QgQM}sMz`as%&~TpV&j?w^;_@D zT*1+HgRbC;RKZ5O0x(L4@7o`*)?1gWpk2uLHR1R=S>Qz{V@N{yj`hzgBRJrD)x*KagD)#yZq=W)^V zCc$E=a0BC+Xdw}GohcF|q}Qyl@P1?}cn;e0B)FR(b?VHq5R&TVvFIk!(Qx!Ms;ug_ zG)^y?gmw>(nfo29doVJWRA8zXpqMoQ3JOZqZCu(Fk2XC;4>syI2~dqNNH3a%b`Lh( zgN>xL(aya>Y|zYC@YPo#x^M0&q_!tx3M?gS+hev(bL!>L{%fC#(Jg=0Hwn$mU&JF} zi6E3tPPH#64}CqPRaUIL25F5snVo5<@LD`-JVu5>g>*wHVj~8hlw0DR?H(El!{V^F z-9l+SGL4BxwV1q?TPvuIiMef{};Rz&LQ)hsy-hA3SPmF7|zH z?Y4XLg`}iT29W_|xU{LB9gl|Uc`(%*I6Sa9RtDzrups$u#FJtt_|}>a-wud+yCQ&ZVHM5b@)ng&x zoU_6juX=$~v7a#*`8^uAp9$OdbDZE+Gh{G4lBG(xlca$A2o{eH?8y#}QYNKcvr`*n!JyNuWL+OV7vC^YQe2B0VE~oj=6i9AYq@-x~sS zj^nVLBZ2SgjN5rpC6NQYB3;zte5}v7ar>4w>IgPbtqJjtZM2A$Tp469*(DSCN+H(5 zcYg5SDhFF;={w8ub}d?IcB+=)HyB`W>~)`cK7h6o@N$Zbc)le zK~>$|?icl?>KM&d){^Iuv2Dg|2Re+6-F#LKoaN7_BOXPGT0P!`y1gI^Be#mI7$#WH3nToUw*wK37`D26s zn@-!aezJ%UywqyTRz9G?f+m(<tv8fh?u2DF&>mVh zZL_;Nv&<%l`RcG!s}Aj1h)q6GH4gW-XVx=;q1#^hnu>7OQAf=X5pHq@WjmrQzeq}| zKiD_cB-?R|!IZ#-g)Ncp%-dSTAWpO+xW8x&?*Ch!{q|rD>1w0}t(Z(jC>27B`M4mV z^^|3^pNMv;hxTu`Uk8q~6PzCMmJP0E5xde665C-3t(9ePu_Y`QHS~+Ybvx)&OKytS z*A?w^PhPaUo>;oFNv1)Gur2Lmv(odXe=XMF-!K(E>$SlRe@> zU^TmTl*HhY1Eh3LJpsskT{}FV9Uuk5TzcA{V7*DV-P(Dt82`FZOZGT?_P@{aLMGv!Uv|80xXBGWZf zh^2b+LwD@-n%0L=ou9RRBxH8ZSIx+TNZTsSzqP|fp^v(W=uTgG(2Jj?^3~#J(i5bw=HUF$sleib~^4?Z8nUk)ut9G>OSg+V+oSq zl6tKXC=ua9Hgmxa?I-?N4AwLHH7HWIyb`pi@^+M);?cJlXDkfT?g zzF8e#v8CNI?I8(6wO64&)`%LL6d6%L6Egdgyq@LgbQw)QT3a35){DNiIg^MT5{7pSyO$N;65w82VY=5D92ixAvdqBh zipP*^ebWqTteDc~S8tw~mR`OEjaT&@DZYi`?Cnk{eiLy8!zc5pH_#1Lvicc)xB%z=_&&BPP%M8`5 z5n6U!dzJ}*JNLPn0fQbIF5fAv@u50x;5VW06Agy)!eyT4mnE&Bh65S%e)nKN5^fdA zu3F|_F$~JgJsEo(2*j$}SQ2u89&fecQ%CP;bE$97L)u~*%8P2H>=8Np7zE09jqopR zB?oQ-Od+Pk)e%G--P?{|!Nn1VZ6HqATxtZUaE00PM~!LB*cbAYc12($rpD9!OcS9` zX*vzTQ4DzxlhR6SMO92_Mw(A*#w}~ROA^e|TI1cO$(JS_5z(9B&oV)r7$alI+-_@i z6WTHO*(u-1Gzv3odZecmV58Su4%x?CH{u2Ie5Vu#<>A=K?AL266T8~je&U!R$x!7% zeXAC)trnkJ{wic0`QeiuB^y7C5j|_X2~f)nk{8}_Ots6hv>@Ti$f$dviiFYfeq+Yh zwUQ2xn6x&LVGMopKn&Lt6AFh9l&62)HWl5B-GxqK8b$9&6QvBx%&y)rJxTpw!lk9s z!4|pIm?D6HkeLxoVX2FQpYQHUZAAd*y@7Rl#G(R?T=Tukg&i!qxQ>xQbFJrku6aNr z>g5=RL?Y@{`EKdn;$qGu5oiTPW~d=AAQ$~uGa9Rcj2KIKxmMn3cI*1mChexYlCP3g z>WW*mtm?F3)hNQ!O$e%_Nf?tTt24Nt5TKlb01qj8e%}ZJ>|%C0ZF;_+W@vHB41MXVfkgQx+%zKP z6-x04ncjQvfoX)wtH`a{N7TRpc-|YSKBQ>lHy+Hiu{4D?9#S(jD!%s0y&h5^`M`r2 zX@_48Nc&q4<{4V}YM7zBAIvkf`qeN)zx`mIp|!7u8T!zJd4|@%8fNIj59S#<`qeN) zAAK;-(6K2qbZg^WGG_d<(GQy&CPSLI~Hcv2Z zwq|>4a;}=i-aIFBGsa!=*$~x~w?W@lOOAJf?R!O|a#7 zS@HGqr&9P=U!7-TAjaVE@!B@;!0@zJMo%fg3FoZKZJuZ0ZJ#V6zfS1`P!nwFGS@p# zdw@lHTvvx%5WyQm^{Uzx41a>Uh z0ezpKP($B4z6tty#ncsGJ+lH<4>W9OUdvJ!w zas;PnxM4+VSA1v!m8dmd2)+%Y9jB7<)?A?7+Bi6=Zw#$palT|lFw)7ALX1=&&ue4P zboub^)Wvg}a?P^bQL-DwXzMU00oy)I3*|i)0^-x2J~O)*duEg#K!zvcJpjk zvx*Ru>^*6e9}y_Km^Vw%)XbI>r>Qs8)BJs*+l%Ah+iKz}hnW=vK z$(q~5f=2Njxb(|U<2K7{>t2F!gP&tlGJ%;3sOz|)q$8ICvl2@6y;mO~_N+PVcix!1 zt~2PE6qF!235M2U_~VJiOSa$B9IiLp_nuZ2k;kcVx8)VdJZg&N{3RET>h$9d)(6)z zzmSZNilVldt10IcTR2YOPP`qJ9WN4a_ z=LNi@I;|(FY)zIS?a88~CJQ{tF07s`yg*~JDDTNiI=m*!I(&K-l}zK*%_RIFKJPVL`Jwzh-11 zRv)@0!jO{$xRE~FskwCR_>$d%Ky}=LluP`JVc@wC9_`vWr{HFPAaTH^qnzD&`^@DU z?jOkqLdULT=Zz3XD95l5e-m$_&Yy4L``ty$5$bA&KnJd#jPO^rs6d!b&a2GD6nmcL z6<860H*Hpzk;5zUs2ZNs`D6VW1OU#!81fo$Q#Cm_l|Dg;PCZhG9sx8(se{u)K2jGP zqn;DeH8JJqlCPu(a+NvGRpaW0J1!?0ht*rRd~W-&rwr-!05M-_v$qYsW6g)R4{Z&5 zb?+FD`{@s~^1(JwC@AN_>Jy1`$6EB}Pi zi_!ea%nyLZ$(dtHP!Wd^4?dE}bnH`d`pnx=0aQ-MmX0ST&;8oi+`~!MH1|DCR6X~4 z$a60yGg`=s7M~jyGg}u`^kVXyvzKSi-B|O?t&Pu|o3*QM?J%^JulV(EKU@2X6I^sI zzT%%B5jpZBro2h%4T^GO3LBket!A?uKT5yusUNI7WN3AP;%4Bw-yIfXW0#Sk53~7BO z{IK<$v0EnwjbS&QfIdg)zsVEOcMcVnrr(kz3XidOU?V9wf_U5paFBDs1x=mIeWbXA z73A^(`k9wO9F0N@h^m%|XY#d{z$Arl^YFlB1rB>jEz=DWuTW;)b0e7`T~BV#v(%jU z)%@WDmU6uJIc1C%&Il~jlv(RvCf3S4G+KBylYlJf;BZb>aWKqE)7=p7*zAV*O?j2n zY224-=dpvgwS?8CdHSx-qiArec^aD}(CPgJig`o^j=l5@B16&)a+hb&F1msXD*NW? z>y1@(P~T?);7p+)5A%=chVE%7gT$rkY#kxJRLwn3-{S7I!GzLiv!;A$~sa|`>(FgIM#SQmHm>=I>@9Vt!*J%9*l1b7y7It-=1*$(Tr$jQRqnAwcu7Ic^P8@hiya!SS~S$dqA+*$>KPgU3IYqiXNoTPfPY$>ZrZ4Fh&NG1(M zmuY0c|SIvJt}0812kNo$EDQN+3v`7(^- zF+`87G&OOEB5?<=JGt=|8$0>B^Ue_fUQ3EBNoy)ri=sU*I&bLabDWsDNm}Iog5kUi#k_MgZ1rx3Und7f$7MsEA5CCrD``WoW$F*4cAt#Y!e*AnFeZsU zkTP|R(VN=cISrFn3pE%r^ljfXmh-m!SsP&%d}`ICIdX-;9L{;C_~_V9@#CgUq>Ty8 z_)4MiY1&u(X>p&Y0h(eZ)on~3CY-H|s~?ha^*OT&ljRhm5#ws}W%v$w)Dgms9mG-1 zohqL@i{Q?idAmHkW3=#A2HEGTi!Fofw`JJm&PA}i`gA?l*) zCcc|SWQq~g4KcKoCyir!}@CGGlPqxXX$)4gJ{f5$}a zcKl$Y=^IV={KlQ*=UwdAAx3X$4l(lWmCWyyLyV@Lr!D^Tnh~P9I&;-5z$9P5dRV}g z&Vuu(fZ8UMXtOKUmgmr_<(oAHb>9CqH=MPihMh~eNEFKLh*7qwb}qgU5Wj4e5veQGVHQocsUShFG9K-DzL=?Kd)guY`MF$ z1AcDpmal`JcX+f9^JB>iX!ql2pP$~stsn-<-o11newOmlKD4bx7is)!AL+vjVZ7ex zNS~0D=<`w~VhvjhbwD_8m?yM6PXXbYyh7{VdIh=Ni9K%+OMalA*mK+Ft@879M9zH= zzX#0`IS(m}-JdgQ&eI_<4=g17YB~hwzK1;P(sF+efq6*L=L7oGmHP)v_UF`e=MO7@T*J5QN)@F$9Fki+NF- z+YV}veQy#-D9bD0mr>zAhvVH#BtYzpkS<3EewPABynHHqm1c6t7T`{&b(bx8Jr~$B( zpNMus$6A8L?*GQ!*FWm_sg7!EaH7$bY2Vo1#}_UTZA^K}40bpAnk0Ks_=&=+i^ zL}$q>KYZ(@M{?{{Z+8{aN>oNgOA?Akuc*Xxj>4`|=qj_Wx(de`yozd1`dg;b)k0QccZ@g+>sXkp zy`H?f?RfFVt)hd+Bk4C|#2ByGQ6zoBl@#@3%ggQ}=|L16bkM6L@r4Py4x#@bsI;@d zsPUMIe;sQDaB`~zv|C>($_FDgu)ppFCD%c@ zcPiKt8@GqkeU6QCE7&_WJ{U){pam9h4HZXpoE=;#l!u>yE2`l0+ZZbSUk*z zfI0ZjF5==tMXPf0u~%rpNTE(IubrXIm|!+8z?ITUO?WNrZ*k}|3{nn;7&u}HSV2;z=Kk| z4S{E*dyRotpbU7pix7APvBlYu=P?5Qo=u?Mq~hM!O2zn|U!Yf7oT5(bBm_RKOeKgd zbua|$2B{-9V6(90Q7v_}3J5d*zK6g+FYR&c8m_TRvDXmzcBGQ612=`8AVqDL|9MjA zJ5fvKrr5!`5!c-R(Dxt6u_t*YMa+g{YGTA*d$*$6nfcas_JpYRXQxn#$sr~(t1%FT zjt5tS(bcBYdu_;QqR&{WJ1A~3hA%Q&EVsWgzLHio1$PKy3 zuughcPSODfZtGLItwn9@#chE15ZcjKx)%g@BgYf$|q>bcPJbh?|BCZuULW1|}XH&3Vi$ zdGL=?8s*BtMy?3EN^E6KiS5%aA+cCuQ=o=q2~{n%4%M6x2ktra5l4#(Tpk?Ftz`VW4F0fVjq0VSlf06*3JKUjvI*XPuVW~_p{S}fg=r*A(9Q802|+XwC&;G@D5?uIO_ml9(7llm>LzQv z4jyofq=ebW%isY@;>=-J1v^oV!?;-YKi=X2y00rHYg8OOK($aTl7a^)iBrcT4ayB3 za6IvVV~Gba--!o!l%qW0Sa(A;9&HhI&{{AJy$gom)HQJdI~7$0)5TwLg{We6yb3-) zPidFqtK~Ic7{V7?HISaT#A2IExYS~B3F8!l;(VnV)~(rMVsbMsbu6)rR&rt)kT{NEx?rZ+0>PSoPtmfYKAw4i2Ch+W9xo1~n``Qx{$Nb__s8YxxLoBdExfuW z;nfc^v1EIgJg<& zK)R_ble{g;W+UUoSOfweLm;5z+A=#Z~e7 zl;SNPjg@}+?rvf^{qlo+n}XE2Ce2SuHanXu?_#N6e!R;{&2PAy1%Ko(r0pkdMzP97 zi*i&$<(-03cWE{40>!mkb=N?_ZR<)_Je)*fA zsrvex-STtw=A%HAF*V5f`&;D9xS}a_qTvS{ z4L_iC<_5>x+`x?;4rHobL|$Vr?FhkszsCT)y(5DAQ%eF@H0O$765e*?i!7T9P&^fgn$j?W zM1wvxgiN9$UFx1I|56;`gZg=+YPIggXr%xSt_f&CiE;8DkeKkLKrO&gwpe`G16}u} ztJR&q(6CUx2_;UggwOThbG?2oE25(lX9LZS!7ygeO!62Du7mQYyh$tPc*iC{ea z_;{4=AYf*rH^O#WjLBJGH7Jts9+*O3e1w@c&yXv9Fok)sFJ{I0KWz5UFMp|9-Yd7L z`QGH0U-3))e^r!x=796f*$;B9gZ~RjJhy2DM)l@2ztm--cwh6K<_flmi9}K3S1uxC zZAt(#x!zL=AdK>Nbj#|oswHEMt~Uyf__l5aS<^H#h9 zIDd{fo2Os(C`&8ns)8>tR*TnGi%<0c+h2^519f}wBh^O9$qMf8MFn-z? zITzy5nH}bdv9oM*wuV=x;Qssott}s2@+TAQUD7px8!CqEcLjsv2E8{NEVTR(lkr4- zVivR+@`Pq0bwo#Bc)k-PtR9KBRKj^~n4ts<0)vu7KZov)j5^cXgyxAXw363aj;<`k zPfcLPb|q;oZpen(q-C6REVt}$iQ+q8Or{M4gM+H;)lQ?74YK^nOf=rrX2sUPd@_!b3VjL9ce~sdNh2%LXsu3+i&TSfETjZ{f{3t zf3v?q7R)GBL3cVH5kH@r6}ENUkDJ9ChlTIUm-9iS_*(Q&*_NCKlWBjIz;A< z{p_IyY3^aD7ZRGR3EV?ehk4H3qoc{4m+v_-q|v1Etq0I3+`ZiUuz<|TBr?+bCw0?@ zX8>*H^^j}zu}p{c=c0^{I+&b)PUb0|0TRV}Ko zEU(}bjq9>spiwo6CpFrreemR5_XI4lfecIsPozQ7KVgi1&}yDi{cR?nxT zbF9pv^KeMWd${v#6F>xl{!+Tb(&`=EjbGhx$3w8KN&A;e^V5_20^qFJ9s1O!p~TqEvrbTzN5h$u3y$$gBLKdLIa_A2&&R4x_Pp%xMsg;A}dk(D}7!LkE-vTGs0cjdh zt3UE{!SLYlKzYZZgPq|)wfuF%1Iv9{=Sx{+bZ6j}!>>D;IwD=RGrT~L9Mr3x4Lg!1 z7Yz?;9Y~Y?^(??d@@IdR zxx3(E)qCLprhUk~g8_FKNMEbuG?A)T)2MO+Z~8D5++UP}g@ZZ$Lg&f4l&7k1`cW(- z7yNw+cZRdqa{r8(Cm-atx`0dSsZc}x)S3^@_2Gjnumul7#umTg`+$oN2X^l{^ziBv z&pum}eTLgX^sh3;Wy%I?pnWj$D#2;F3rZ&2O`pD<4(t?Sf>={fv#7o_SKfVarH9a! z(YmO-j0!<<02HvqZh$R0Ru4a{xV-pBnkT)qb%f-i z`oHx6SkS|$r2S+p#c4nJ zqj^7>1hOt5iv{Mt4RGr|JAj2um-$Ht`AHR;8sqb$1nMJD?mKqNCslww4gxY}vdTa;jb?m$-+bNmLC4dtEGla+UD2L0& zE{@Bxgj7){YYVCFN$esqk&|1GO{E2`ydjp{sn0~8os5-gVyDK74x{n0qPF=lPSJGa z&|P4R?gBq_cg*E=7m(4N_vKs`z}j{YnV3&~q02iqP7i>HKg4H%;T8gg>hR`+?;fAh z#4F zwcm3G%@@VwSj_)TKahPL`8%6QxqVVl#uKLMYAL(48JGY>B>MqdE&ufxVF65sy zvB#WC&9_sJDle5)v2S{uYs~KP)YaqZ`9ykV57)E5amv-OofgmU70=SxxQP^VH>Ge> z{`3LbFke#&H<9wux)e82>f?0^H<5Brox)9do$C2Sox)9|e6mjAh7?V`HZc;gC9yD3 z%Q~y%+TiZpmw1NRWWb~JF+m;;$-1p&M-qZ2kyK@4!GH!+D%1@D-ZGFj`Te$u+&?uRo3=^ON@fmEZuTnh5tQQ<8IFdJ?IrV z9@&$kJow%%YhWF0Z3WX|8oQRpPIA4}bEF7ewivu5X_0WpEbxv4e>g6Vqc97t#l4qy zLYxedQ$9P&KH7Mr*AfbsVh*n!9Y0`&a$^2?wB+CEs=%;CZl=jtR(1cCme#ngi5xqc zrH+{8JL#`>7mo7CB7Bu@B-H%OjCCs`gsP!;M^E{;{MADbSH2^KR5bOq)llRUuTd)4 zq;j^~55*HU%4Z+)OBjKN;XJL3ty@YCh3>AY*=tSbn3 zIroS<9oToengd8UYq-*(`4xRfO4Vc0Dy*qNR#qS_CyGwBkU;3=nR$v;kC+w}AiP~U{X->rPcnm=%fC|DwpBzC%!_g!44`QSS9+IS`bEm}uF999Denyyh z&%eS5^>_fv2Jb}%j#k1KL0w0Ri@^7``uLNbydIoGQv-&=1C&>3jL^JL#g?X$3zRp{ z#rrOEGXM2?V#X*3exMO?p%e^RKa>zB;b%@i^(a&!m%8a!HkmAur`wy`^`olJvXp}`?QEr7r0M~@3Ud*6jrgH2Bh+Xo;{6a4=ZMt1Gx=z^EzoE@jvf0KE zb9~I>6J8e;LKUO$XUtQO2i2TCap)%aT6yFC-v;_WxK&tjecJwcxUwC)4c zHt>TQx?%_B&Px{?B;~STU>_@A216Z+Jh45P`ngY*G_i1-KzSt^s4E76+2b&>awF4i z`SS;0smLNDx!Q882!?9zds^)?w`%{1sUhCGeI?WW6OFCpu=PxrI)A-=1D8JC5^ZfX zY;BF3Yvir*wD^~x01Wh6Yu3aDOtClFD%_-$A$J4lJZHrl_j7ZVLn zok48C-lP%2?5Df8B$j05?+QL$mAz0T!8Zgc?I>5p)pSArB9|BcP@8z*h~<>*AK_6| z`-lk2@mD36vJZ~C#&Z#?Qd8R^q`lQyzD@Cn#e=yZ9vGl^4@KyLD{9tY8CU3kGo_q*&>* z115|~p3i-T#WOKP40PB(b<5MVOGIvbO$6E6I@;4oDRNz5eNk`1Gt^K4dBMU%yKKoh z<@Jpm?=wSv&5&F*h|2!!i`b$ZjIui*(Y_>Gy_wub^0Z?l{cZJ2s$Nym6VS8-p>RxLuUd$JoQjD|HF zX2VMxwDgbV$%*;?V1Tsj==Bx!t*svqm55O6$gTH<2*qRM14c)cE)livo63p4w}>Lg zx*E+5sLZjdgE<9E)@`@dJ}63U8|A%W!*ic{LH(hdswO&?4Bv=^X@-#H&^j5ZyBV98$n@LIYmKWw&o z%7%RS+Iv4%PQx)*eWr(Q-+eiy@ytUu;yqTiA113d{o8;%mG{R{yG+MvUgXSiqp9tiax+ ze9gXCZC0qW1ocdi(_m18f80GG%Z*`pXe61fTu;&PE`+BAG40sh5{q$&{BLMpx6Tf4Kz2@8?_L@CG?B;WY*o)t{dx*h% zra|lvcLTB4pBuzpzbA;jAw#SQjz=SsGDEzP*sS$o`yScIh8`mZebwL}Y~~pA-3_ZQ zE0PassaTZnBpNjZU`YB&&p>%}mNpmp`?x(M{~H zeIWME<|=NKk|h0VuC)<9)os6quaS;d2^lqb{()XBNsz*9-~{iUBe3mq)v50Obx{r6)&kr+7`j72)@};R0BxY4=(Dpt?8vQ& zj27>VPNxWTlk<}-KcOUeAk}luM(dr_4#o5-t2pi|wGW(}|G z@mW)yp`o^>Q%Q4a*2c@ktc|5M1?r{Gk7vrw^f-aD3S#;7){ARM)*-UGQqT zrm)17ps>V{F3rPYdDh0n#K_mWSGkJBF0L}Oc=+H6EgN9N$$}v;CVHg0uuZ84*v2IS z;07Kf$gM}OB=kigcd!qhlO^-Oor7B>LPPJL3hsC99^60FK!pX_7-TZIArUY(kqBM5 zeJZ%2jRfyTbT?r0$U&U1z%<3(EZ8xIBW-WIMNVtxwlc+#w2+d5{C(6~S#oGPxkTMUA0b3a zN*jd#D9=lVUcL08K=l&1#t}@lgeJUL4CHMG9$x)Qr~Lduzmb7EOkwi~`n(>TD3V?L ztd#3mGp}uKIQqx5*&i?DRWaCV_4=MMt?{4dN=MbGaTP-@#j8O>t2V4*^b-YTHu0T$ zTCe7?s#Py~`q`qqS!!FtxJTwzGR&gu7*&6LL=pYnv{`v~(b}zq;_+meR;w9S`rEHEnac$#qBKu48^@n~e_A>F=yN zO=pi^Ry=|psX0Mz?UC}Ek!4Uob&4x>KkDj{1Kd7BKl0Jjm(k^>uqca>{wnh#+hz4u zfa;a;xx}*PimJI*-?c}phGKAVV^Do$aIuLiz@)*==fMGf%$movw~!z~v>3yVadGR8 z$n2}3r@8TlxBCHh1)S%?3~PYR(Q}<=1yiQMVdrG{KSUQ_c!*G{gD8UL6f#|FIvLe^ z@rd$fjH*Z7e*JW{yKpr$)|L4f23icJBVlI@3E$HVe1)lGs=z`kQD+-1zMKJUPC{$8 z`vWOskbo7eWY1c?=P)MaI{hQI1=c7@$jg$)Fow+RnPZ$x6H4if3&O4n#)8Q5`E0|BR9AuUpuWYz2F<%Mpu0vb0W1#0_0q*m#9D(=}`$_d?F&#e& z=|GTD(3xqC#PF7jZ?{%fzPX|KVP>V(-EXz182rQhHbYoFj_J2_(>VCI$%vb|P>N>| z@p%vU-D$_CEeeA3Yq}VBM^z?pil@R@?RUiTKwBJeB(Zy#Iq&Q$*SEte$pG?uVO z3OI~-ppOt;pr53dbw3kw^~BTWdmB;8+Y06PX<4nz3k`uWy0ksSOIL_z0=OgfQaSyw z0JbWSQ?o0YXB7sd?ym|_rk%0CE4hkXR$NR!n}Kz!ivd3aOR&dR zqUOBoZ~zgHaD0h=LYCZJ>>e8@qxB zjE+$_d4j2$sT~_}^C;C}m20_q&{x{En}==~A32J8kbY>5Gu%9=z}?YXboBVRsA+nA zK6!K~i}z}7N`3z-Q6tt1 zHj-8$gdS)n4BCYnVXS|Esu3|R%M|pPeNZEAO`6V#P`kRNMu=eamAz0S>ZjeR5u-?W z|Eduh4L%zB+vb45_Z~cI#NHHz5k51nD4dIwwPkyEQWoZ}vzwvLZKbTvzdFBCR#?G$ zVMNOEeSRs&xdAmX%&?{F5wYvm!UiR0mFI!61!FD^sgw zaqh|Co*!6|dH*A}rng+$e-QgsJ8W@Cg zWA687Za+~UsxMop zkeu(Mn3ss|UZK-no%<$opDbTR3wp-)IX2?-u%OduJ%FY1x6|E1`Jd9=u>6o0{bY=u z1-=3Um0c@ek*ZuXE7yofUh;$b(OTr0%xFh`G%96QH@Nvc5tC@vLxrgJMnpok77=|c zEl$s1WtxRYv#oe(_eorU_`l%7@P3#JJn;!!SY$n(3x=g@hO=wkA6_n)H*TI#@0nh3R>fNC$b9uY2Am44e&R$l$Rad<0m2Zt)ciFIMB%XnJXk3$fP35 zc%u9=#@&=lOpivz^qhiA<1p^dGOQ)$ixNxG$#<}GffvwYwaSpc9A3lZIg`-$lBvcrEyx}_+DLE3_Ai)O=+gL0$c{L*vANf z1vb}epwdY_i~#jW@r?;uYoKWPb~et)!pt)-7_2hZjDke#0CEtBmq4NcC7^T_KChSU zkwnta3@&=Xtb+petm{BWv6b--)&meYnEgNm^|YCPTSjT`woanus;hIe(#X~Co>W|N z)Fg$Kq3Nw3;;s8&`qWt3sMjj1*=jeYJ!LhfEX&j@ZhEhd1G_shtjBD@gWy0?w#LFTf_BIg%x;Mbylzo!eU*+`60m(z#@(7F3q-&nA><&W zM;E!^b6LU#pUa}pmwR)!KJJO8Zp7{^mil5{Y4ZiT(%SX9(%f@&g^OOtb&a<)+|k|j zcrKItERw5-U)udLiGrYBka7>~D}BN%neLOFXQN^jyM{m1a@|+8|98vy_mXdo+h_5I-??@vZxcHGGAyOHSg^% z{8G2-T&u&h+lgEEOASbex*bmKp1?EHQO~>)d{PH)7Z|iN#pcm71th~o(qBH;%J%V2 z`Go`OxCSJ4B9iq0$x7$bpxA+-)Tyfb)M`z;6qKB+r$v5TUOvdsY2r%F*Rarhs$1os zNq^y%iB-mt{y-6W^_*_`=bEb#@S0`#CA1^)U$YE@`bJRdwHln}SIUTo8Fy>EQJdA9 zyHZDt;>U%S$4Q+<5R+I8{+~?p9iBld;kE0YlT!Kqf~8?!KmqL4SswrhRJCBz1SrwF zw}7aXrp2c*CUWU0KMvv~_q;ol%;AkkMqa{9vPMYXp3_gie1!lXMhCinGP=Iys!H=s z(M4&SS{;B1r6>k=-I z$to9SVaNpnTH*pZFLJRczfdtXB~Nbj!Xc2Gecv}_bIcf?ygsQ~Z3DZSHil$TUTHfKnMue_Lnsx5gM6#x+|w9wF?J$7C$ipJ@J zE;>v*x+f_wN*L{#0(GKWdc_2#LCgo8Xwj`2)tDRRz~QE0QH&dQb9KWy0yMP@gecwj zPxbJVytsrDTmT%2-lF0L^ThY56|Hxow>B#CX0@6-b?AbkTXgkD3l?S9&uXhg#B{l$ zZ{*O;vAK|_Pno=G0%+=#?Ye$NE-oLRe%wxRjU_FXm6sElupeRU4 z;h?{+&ZAvtiZ4XGo5XMLX5`JLskMkbT;*cqg*rf9fWQiucYsRx*7rfCv;aoO!K}s* z+pfr^y?(MTl|MOGetw=q#M=d&sShWJ!%)eGjSB69n}wzU(B7*=N_y^fczE=p&(S`b z1p*f5E|-z&#}usTr+fKx;D3^JkIL%u%2xbiciQiT6;RHEYOorU#4|hbLmlCbiV_Y;fbgov%8NYrO%J%^#-7WcZfC|#&fs0c7 z!HV=gne<3^j)kg!iZ3KYL-TBs6Ol_qYhOvNP(AIPsyaAD zrN)gwaA-HAKqS~x5{AkvTtifv%C6&MKsdt})~S zyA}(AT`vX&@=nTwIiF4|H@jXKXV>J?*vPuLLw1b=Rj_M+l_(m3MDqkx;hXo~OZJa8Dzm-em|ii@mCDL8_ST;6f4L@t)SQW}U~ zqEM`$&#mbJ-$v=jVp3Vv`>xKnTODik%S{Z6vWa0?zx=}X`sFCY3I%p^qro(#U7BTz z``mkP@0u}fl8Q0*Be0PWA>|&Vav<&DwI^9#>rR4=<=3d!HRnm$H|8`z~N9Wty zTIJVR($`qh{mPQQ)M80mIJRwL_owc2zp|uyg?OK`q-b;^OS<>oi#9POn>t#{SeVc# zOG5XPeZ(xudY~*LqpX)EowD9$Nncx#ea%3AKO4yZ`T@Ei`)_$chNU7e$c`cOS&$v& z!h&p_3kx#2RiNhZj_?|57k;cYrALIO^oX{mbS!B~Q6_6j>#bGR@i9$lIKH%_tU?B8 zbWKY;X-X{F8a`&*(tO(zH~jzEd-o{2uKLdN+(%X2ddNO*6s#udaH~+7aww&hjsuEu z_tME2P&dws|M1N6%&=B_*2?tIa%MG5L&B^@;|g(N0V0SXKqLkPHdqit)L;^kIFm9l zAcBcS><|G01Q_fj3Q>Xs3UOdQ-|ugqbI*O$)3PlRtL(ea*=O(H{_Wp>{a$}^ofh0|m>8RWZPF3__wOqmQJ?kglvnvL`S*($XdXUymN?dI)b@h+ zQA`ozkK8aPE`T{Oe$hj2$S|k7oJJYu3U-M#igBw}Y#p?5ZXx>;hNgw=i!u-nSm$iG zDN6cU%HGr zzo^+uQ%yBlA@q}h9Ol6M6RA$IB zm5qgN_qQj)+Q4i%1EMoBl|7q)+452XX3HG}%$5rTOgQrdn980`fJ@Q8CIFEx0j9F8 z1enUU5KPGjcBVUxHH~=*C*NmRW-?x$9>ys7r{JV;sU2Q?l(9XPFV_sJ`0(lAX**34~9rn>*XNsw*b!^H z7N^-nl{m;oRVub?v7=t)`!jTWaFB97(a$F^Qh?q|^O^GIf4)h0?65s8MfmVxfeRAP z*GU|vE*eg~Fx5z{D+5~4x*xT(7V~Skoj@C*>Szb-ar&nH7JJ`^@JW5DhTsF6=s3!+ zuI;DPY^nFTmqqPsO*_zpvep1&EgeaQlQmI;(OEn>S}pZF7ctjoB@CLG0GF#Cr6a)2 z=5w^#V(qF7@}u{8+GegcZ`HVr8e1ZZd*$&X8>B`*GXd#4ED;=g0je}EL1(rJ(}Lpy z2k6{(fljbw`X&oE_3dOnsue&SeWzk$WWaZ~=E3d(n~jjVwAq-}|CI4>Cw|Lx59O3S zQ7D%wylM1DniLbR&1HPI%1MeJ!Iwu^_?U%u#gx4K38rL(dl1X`6HH0+8#<><$zrEx ztoq6G$XNB8o-;HUFjiG_#x@48jaA-T^aoArR~HpaY@Gs@1webB6x?q>Wq7-J3VU)Z}^N8Lf_zu#f;M znV|Y|^Whm-qBM8d4Wm7M=?!4jFG^>TcXTggU~|u4WVVaiMwh@I8TQTR`?5jv@_R)lIALFhBW^KYeSYuWo=5g zEO`D|Ei$O!tCH$v6fEbtiagfYToc{Hb!pQWuw>I;Pp2Tsp?Mq{jcb-?UKp29$6R3# zQyiM@MU7vw-KcSZwIB6fLivc|p*t=H8PR{-J%y=bT>B&BnTnS)ewuzQg;hG5JOIb7 z3qV?pkKQU&pheKkGp>jDO*4;n{1BIB9=5C4dHZ(IJ>q9rO!1>2QaUw{+v|3G$f+5m zlto_jsf0Auq#_uy5}WHNRJxOTWK1>7;iUrPbajNO#+Z1ji336PO+-s59C1~V?8mo5 z!;rtoqe(4oZPFenQ_IfH0WLW=^TDL*Rq8r%PeER!%{wtk0 z)bX1z9c`nn3>=;E*j^Y^|ZNmM^-FxN*h9^2HG7w7O#BuQkFlYyXgJN+kdA0 z30YzKg)8|M7Z3l^5v=P6;@qA+DePE$V87wJIEIR+)%F{MfX2A#cJg_ZznBHDOYB$yO#Bi~jwFZ6gT00R)-a9ktwkL)zbqGQiK*{f7UpT3<%5 zO04ZHPF5GP#ORoGrpap0;p-p2J$;L<+Md2M5|`me9#lvdzh5Ct(kX?A)7;H%ary+| zJYT7U1*TK6r|&+ZwWsfHCF9e)Gn#{Y9pmpLY0ci1AC4n9?$>#MOTqru?RGthmXC@3 zmBCF=SKiZi#*+4fz%J*FB!52Ud-}j6zZuzLzA4HK?dF?r9v8vH@P@Z`Z#UoTJF)>5 z0>EGu^TXH+dGy@u=2J@wt!g(PO-h5S&>lXT4oP(~Nzi?SEhXraBPHlFaFb_MIkjv^ z(10x^=(8a~FSeu}x2!e1o9``+a+|9dO45yDD$O9ydgB|~cfGY|+ada9WT7@@?Zn$k zML2AH(n0FD^o8R2q zttXlXFFb0u-fPBUUO_22MTMr+M)L&JYx&)JS_r4syIW7o0o%loJ+74^g2(dxXJuuI zJ$b#zYtO|#yaaA@+I03P?!4pX4|b8w@5$eqw%)M^R+RUqxhHntu{ufcG0ULscJwk_ z>mbeo{l40L_lCz)?fb+!m1fgW)6|#BN=;LbTzUP}v@SJGxVU^jtW)JKC)TN?={-Nz zsV7*sbLax!$6;9HdxCYdCQ6)dc@RUzx|REJ#JVlBALnsl-JTc{PYel(G}YN8kDWAA z?gu&Fq?spJrzb>wB+18TP?Y--&NtTS#>dkyet%u>wTS6ldatvnEF@w-q!4X^^fa3hh0GG2S!IB`8=u2=PB%;h;5bL~bV zKqFkx(3$Yz?67hR+b&39+l>NiZX`lSLW6WWJ&bBXLoae=G*y87;$_=y6kuZIR^21s z#UD|vbtaX5PY5Bql=Qm4Y>aWz*TGP82~=Ipr85RA2NJaAr2`4tD4_J*mw~_X`BlQl z7Gi!+H!F{Lnz0ie@jc9vu8UOm7U`pNsp~pDQrERe$Jt8bP;?*bY{BC_zxWtD(YB`tq zcMiG4>xS%AT;ipx!e|%1@Qfn)!h?@|;cDZ|J^u6w(T|eDPj@ir%r4xKY(I;JztyaQv*vdb;R&sKD zUqi{tl-m!eh6B_hI{CLRGU8@*04>@r#cG5|Vpr1N_xIloVc+VbyASGHE}@5I<0 z{v5f#PXuu{RrtXAHc|7@1k(x+R?YWQ@YAIs{mKc4#PLv{Xgf8sC2CWybhK_UF5 z`A+!DhZBD({W6_eI zVGLGtQ-)6g@Lm|Q0pqD4_y}MZ3wu@_h^q3%U&>9H=lCV28VJ3}mC;lIa%WsJe+eeR zU)CIyRVA4emGZO^dQdT@n7E!n2j#?H3RIoHBz=#+d}I#F!pP?o^ZW3CgYwyt4$3`b zlY=tZ%yRaTzGOKc9?5dU=eBT0n0$P zRTlHVJzz2a+XEKOqdi~|B<%rDA`^aS4R7xt}Aa*By1I*J~>8no(W=qg_kIZp$Hnu;xrE zmR?8sCTG&#G2xY4s9hf9iz|yL%=ATaNevfOOLFPR-_>*G%j8_gJqMd>_Z&QJMH<+T zVfx3aG%Ho7UX9grs2cSgUv5Srx5b(7G&p7D4;6?3t1=*`TRJ zh)ul<`C*Tqi;(CVx{4hh>N}#@18cL00yZd@mEFQrxP%{%9{ALG`wX-9%FuGq$gD+HD}^ zO}baqTwfZDsfMb;f=_Rr%ktlE;_5;a9x8YdGCRB(j8PXQWeBBu81_2oXpgiw{{C<$ zTq`NR@$!E%A83_T!=t6@JzdB`K{^D0-m`^( z-g7YlEK)9l=@wK|uIt87O`D3}!k(8gZgXIB8gKdRIKDsob<44d2CPMvXMuh>0aSV! z0X^~;2vA47hz0cRzr4ifpW|uq<~y@XGEVTgmX|N%F9Jb-uJH2yGWu-(UTNfTDSv@> z7N|}5{vvDDh`%S>Q*5G1P-`h?{+slg-I0bspP6^AP=ub9l@~5q$!{a!ETLc>&yEbV4o?Fd4&Cd0LMk2bZHyKfjKnFsJ}F0HGqxC{Hg)|%jvxPCr`g+3vCvF? z#*Hv9O3o8IRvsOEPa5#}Vc|2S{s2}gg&hn!xFdEjPzz19#bO?Z=joXv*9#6>$Cb^W z^lHz4-26+eo)6h$whb?T*n?-V5#6Uc0jlkzSCqM);%Q3Ja&hP}GRC5TaH))e;J_7w zGJ!^osyQE;$SpOw(pC7xIq)i>`0Mn&tVy6N@UGXQhrLsta7vwCrF>^=`J!TxXNLP< zqQpq|cY2c!;Kea`*qpvDZJ(~tWmksB0Yin}?@q6unf$HZn!zJmUuZg1er(Mcqy0S> zysFoPl`Eb0chHQqo(5f}(@&|nT$?pRA8EW8dggKk%Zl!EH#OoE9X^ZZjj18xXgHsypviE_~8B*xF^h*K+4aq>WNpb;W1>Xo}>51Ha;TDmWtNvk4vpbtYb~5ADnFHoNP#a(lV8yicRgS?+ zb>=`OGmZY+6f)osE9B&!TNSpS)jCL695jP)K#zM%4q>m}UKMJH1B@%JtcM#FlfcIO z8yXdta0zg{kCr^AU=y}z1QvUh+ib!MD2)6B`bBGhr(rXVtqoDP8M0?yvgApo;QbY{$k#|Nn$AT=0Szbn{QUw{>j!} zO+mN4NrDyIy&J`$vIWmFsqp^yF>~tMJef6ben3+7W!bm&`G@ekh=h3fvYDvC`UA`I zZ6;dD1LV1zsYvr{3E<1)I{Tp8cm_ptmI;qw)g{P^AM$*7RwZh=kz97HAr`S8OqqAb zP^KMaCiy%7R-Txe1Pl6KaR*9QZhHjQu}1N)xP_z-)wBe-j-Uv(WigV_#B?jBxEtgI z%t+=REHSJWkf;^f^})0f{35xl0}9u(2qQgJI`X?4zFU%jH(+*l= zQ>*$rV1Cl@-2Q$!H+)=mtjd+<>M_E|I1YonefOidH4P2PV;YinzTI z?Z>)8Snk$C|r}jKM|6L5hdanIxzgcxDoJgJwPuA-4XhQ;=SIS@en4xh?;vKzpcv~qEHD}|i;GF! zF-I>(L^Cq_*;-e4M3wvghw35V=*j$su>&mjVO5#bLk9vj*twUq2EQv>IB+vR4(N`EV zXk6*fKlD+<&TmXq|R_OYh)q@+=?6^v-?QA6H0WM-@`q5yIkc zUL`*IHa#9L`RGGR&?w%ajqY4D&KrzfosWLIlEX)vGq)EBKFke>2p|1+x@_X3Pd93O zGysB+zJ!9o9p?fuU6+7P90RuNIw6%&G&t88<+$ZFG0G2?+;t7OUh@%sW{-79iaochtmXkH>W23;$I&s?%*17Fep^Dp%ia>#?B3Suq^}x82>OnKB zI*mdOHY&kbn5T9%639XHyMeysjDf702E~yZ|9OHQM@}WwOs8uc`DyYi5gq&lkMUW* zdUK14Bfrm|WTN3tWu8SA%vr@^qRPY2EMySDlgCiSl2d+S$(4~4uNoy&PUeUxxpK9Z zV(v>^`H94p?`zPTEe|A=Dz;qFXU&#B zzWn3n%U>AjUieI(i=eN{eL{U1e1k8CjEOHl5r+tzTIm?RFExYlIfUA;vNrB#kZJgV zitUZ)6>M<4QK6i&2n%jtdU-Uz?JbM&d@_)YNkS+#(`|KdR(C9E@SNra@s(z}rc5a@ zn-{#m8_$cFfYx_j($|!HtK&GH&e}hJ3^S3E^^8g)$@c62S!EU8yen$cih@okd>;7=GYP{}N7Du^h;Z={EldSl#>{1U;(A(R_cLnrt=q0-0j$ zUhv~WYbE!BdD4Ni4jbTSr+&z~J^OLy!BK7nUDJH01W*~!@SS&+d8!&{o2VWTMDo<8 z+bXw$Xya{p=~jTCF1G@4EYO_f`G*+hGCON5J5GFp?4Dr5j#hk>o`2=B?jf14hURO_eS-VsyaZOoCX z%h8_x9u>w-J^j6W#>#c#b%I(oFwWI(jEJ(nhyund=(FeU5zGm}9zbrOr zV1JShMBOJ+(B%w+A{0+gta~)l#&<~XL0HYNOCHDus!z(Hfy~dAfT`cx8~N{3_Aw_r z=CY-_SzeES^Eon-zJpePWfbRlsrR5Pm~9UB^H8S=BdQTLC^=lI1m^yB=|C2-sQNM6 z>gX%6L%sw;KbD5l4~#OD_U#ayovY#{(yeYNT@{SwkKoyB0@}^=D`dRKz)(t$ zo*fp?>J3n#QObGiGnB4Mf#}FfK4VJ>|rDIK*^h6^uq;VuLf zri9B0;GH;DNfYCxl3p|tSxCYs4sm4{ydV*JN*;B7AuY=(Jk$;78tTm69 zZTgwlh1>oXuUxgUP5j2V`oT6rCGwe02~t-P-6C^7jbvWIk+}RdPTUpK>g)-ykwRWn zqHQUoCQ7~PXCZ%6JK!iEQ{rbVgl$Xkd}rn$JQ6}1dx-cG?jg>q(;)$g_>QAX!rpY) z8Fc9C>j3ty-Ky9l`mthW%8#@-1K$XNbQG05OLcP#7e6rP>y?4Tca~*vQF;-;wU=)o z9>Ow_ce8abvTHGtYmu!R$?L+ZgitNAk}}no4lATP+@cUUN+M=yB-i87a*^Guw^xOT zdH|VI3(;WXd#qzb}*z&^1$MkMsnr$A}cvi07`j~xnDw3q}B($8Gb1; zS(Nc2izp*hVvz*{FR~OuD=2;qi|i4G605697`4cXB=Zo&i>!qAfiuF#L_ag1eSUT4 zJG-=0w&WqvxyLS{^=AkJmSbEy->T=sOfjgi*-sdb>hQ>4yoEDg72b9xq!`yMK6pi?(Yq z_wdG~)2f-$->l@Q0KN4L1&(|rPd8aHQ31ZW)l&hYMbRuAvsNpq0K1sd54T2|(hqur z7)-nMbWN@L6n(k}rp#N{5JsjQWu{WOr|B2{O+h~_P9k}R8tcJk&6J){O$&wV*fXUI zMa|1h&wv2PX%-9tb9teO6Nc3?6SWFcdS6;G5LVn_ouoRTP?^#}FlyK{rJpvn*j*Ib zsram4>8gyQS0P@&1$EdergVW*1NHQF&7!pyQ@W_G0`K#V02M#NluoZ;#S6>fC{y}J zw4}jZ)MQFJ;x6GXMvb2VQ@Z*nGG)ul-R?-Yn_YYEk?e&d_c3+8Q^2$>9SSC$-LaMs zE{=Pr&@#*7Z=54zEi7x1h%tI1XoRX|T?Wfl`))MtS`C(i5^>~S zpUu*zmr$KPn`OTe!0lAXT(Whf&2o*kT8qtcxR)fGW$Gm{u-9$2Twdm1v*l7}uB^{; ziCjIxaJkqny;fLc&uEH=TRE+eY5qZl?0vXjA%@En3Xutq6DGsu-FiGxaxJk&6n6&K zqHnCVb*|+PlpLz@JqzYBMO;m)8 zmq0;RBn+2jJ&<4r4VU|n&DFLbV5?a08xHofWlt5g5grFr9vM{ zJP@0aja|Rt64F*o&?v*DnIJf|9usti{(Y?oHLqaUaH+n}5%|Fcy)Y8KFbxqtDEnDe zYq7LkLdV1foi)mAZ<9u6Tm#C=q@7e`yu8EobTWf2qKm04m$=26X*#Wt@%W%Z3c6n* z3cgc>vRs}_)(hMBPT6`Pv(plal>yTwrV}SpsPD8WR+N-jmNLD`MqN6GmbNZpAgE1Q z@6g3CeyZ$an0Hv50%QqAU5xn>*kz2@(&E$@+QTgjak5~!ahb~*GWETdtF&gGu@S^@ zWg-g$UeB5-GSO6F1Uc)Mvkl|CXyb7YwS_sq=|KEJ=?dh2D!x=O_w^$ykX(2WmF64unIjk{HGPdK%yK4C&#a zzVz_;X3Eis&ML(qPDEO+F?7jmotC_m&e_pkb)I)SZDzZ1AJsm3jl_@&0b!y3m*qn z&I4<_G(QFcdMJKaL$u@4=sR;%bsHU6<@$rrGDy}#r&&P+S#AEtF}ShnXxTiOz*d7L+!9KUB6!EqOGpBlJ@?Ec~hCYR!~?Xe_mKy>Vz7 z4eSz3z5UBul>lpS@-DcYg9)P5`@!j3x_qx!0opBPG5UY$v)4GaK>&N$^?h^yNWcck zqAbyIn23b5;SYD$xy*zv(xsgyE^W74`DHHYROXWZRJkow4l0@zIayP?gxSA7<;f9% zExCu6r%v!PHPE8%%BPkBs_n!VWS(<1x@U^!^i7Q@Z_uxhIY7oVQi&~R4(JjvK(-Pv z2W*kSXB%+Gi(mZYQXE5ouVFG9F+b>OUR@FxdM1jFrk}2U03!ia#w>oAD?SeYHOy3e zbi>#Q{x*EmaaYmO#^TPYAd+-T922(SXwBdWlfmLGm<>m=wNHpQ-qu&#R8UU zW%o*EHtaI^&Eps|x*G4>a5YLIhaIu2snrHRO|5>=)M^7NH3M%*sV{nV&9so~ZaYP| zo+kX}{8Ooku<;F3{kIdkXq3ZDOY_gG%F!8^I%z|#66y@}3EEM8BGI;w>Y1r-GHKUq z53zc;@aMcZjD<_2j*4XYgLtK47{9KV`M<>(@H|sopi?M$awnQ8CjKj3Og2&3HKrd! zGUsa}^F5CdncM3i^C8s3tC4w2KbdD9FEVdl8<{`75}A*0xHoG$Sgy~~=jp0NJO2|V zE_dK9%x^{e#j(Afk2$w#n~X}C7soGz9m``OD!;P(!H-|f{-Yk_<@5zg7=8rq=6P}Y z0wj)JKmSZ`^HwEkakPfUr`*&Sn4CeQIeUhH@!4VVPT~zSZOKIuQ=QK_{{LvI9us3$ zx?yVeyM0W@rI2u@SmN{cjMXyvS9;x-Lq;7;dlVRua7MY`2U~_4ez0Xk>`={&oz`mb z1s=|Y#NvBcWYC`o31)$Lx&Av<_8+Np+OOq|Ys6R}T~l~H=gW$zpHt+DsP0(_S12yT_1fE0P>&2vgtSHu@)b~;8ro@n8VDG?^OuaoWy9Jd{H5di{8du zIhqVc0XtF^;+y|1LR|S;P>}H9rkQT|42(dEShRk@uZd6B*>e@6eg?za`v1C}1JhBFP@yfc;@0w z7f)Y&@kRe)^Tn`N(%Hl+XC`Vd-TV~dt9W^7WR!q+S6RPjnyhs*RYuR-RYt5|eHnSL zXS}B~^JMYaH7-JjtKs1;8k16|8Xil}LS)JL7h5dBh66J}Xax@;ch{MnC?EBWxL_y} z=Pqbiq$FF{Sqe5_xInp=?{CfgKuL!g&5u=ejt*3ZcYvvbm=5=KX1GwaQ@pBV*zlC8 zs&Obis~QLO>~5o2?FQDbI$R0uEHSz>n%|>z8*x2{m5Bt01H~t)q}P`v?N1*?u*LMO zlF)6Wk`xQ6Ot_(v_PeBmsieInfGFu-l*H)t5d+mzU)%Ctp--py)6UFAqcfs>>C4D_ zJ>zFOGkKYDYhQ_{1~T$q&-iDZnG4H|1Kn^Svx|O!*8&ko1%j{9`WTI4k@V%(N z*SttjtD$$YGt&{W?=KynOC zkGuOZ+ueuR7dkWJWK*1)Xjc!Joh35F$v1KsnNS^UzNo{Lc(4_4YIEfl&y`XkCE)Wt z;N1W>dZN6vnkV(7l$Z9;k^q`V1n8e5cLa1K8oGw`DJF$ENMj%Z`zRa8mlldGN>nw{ zr#qbcH8NY?PrXL-9@`{M{3z2JJyI02f z;`L#AUQl;teK^18(d-ee6??>AHP?sghaOE-)e$T$hIK6`zb z-kJ!^p0*GN;freGAWPPOIM@@c_%KSavc)M6#cJkl)6&ycq88LF6|0h(dO%8Zg`^}!qx|4hx^qLR%DHj|8K2WTO3l^d*x4>$UuSz%F>S0k z@r-| zRW&lrc%=Lq&DBJ(%owJi7{s3*4<&^*@l;9*v5m|+W*Hx;)e!4E+_t8rN*nRW%!b?x z;Yz{lB^zI5&Jr`WO#@V>l7_85Umj&JY_Hj1I0$TGroxrVTh3HCqU6L_A`8KYs;-Zc zkx-WAVIv_3<+qfyH>K?ku+7VlMXx@)Z)qNkY(r+jvJ4%h+%pN6cYcKFxH1XeJWk0q z5VGE-`!r&Th8A=xMU(WkrcIdtRQhW>mC27xLAh;#yGBgakA_Wt^{!S<^{bow{?}zp zerh(G{3a@sp9VXoKIviIT`ff*A6+!s*jLUwr>Y%ya06GNX=bqQCO~kzg1~~GO*xnI zhAGE3p(_}N;~Z0uc%9*xC25{TOwKC29#5}&KBi|Gfp}ihGfSza!K+jOKkb&17c-S& ziGs-b*`*&!^v=7m1mfCu3T4tYio6EZ<+z-(tsFg;rqJ~pDg~>Lc{q2bK>0ncU=37N zOv*k_srPTVCd*j^J!L);bKuufJDtzwzo5mCmULdDJ@A3Yh|Z719yp55E7}7e zOFFO7Ao%Ai(fLs}2>u0w{xLQP{(q0iAXqM1Vj{~$YZ-&!&G>!!aEmYq;uRPx{8|lx zWH750LS?X8{YF47xHge3X9TRR_+ovF5k|lju@o1~vbR;bzCq*PX!QCFe}nkJ5SRx~ zCdyH?EQR2*WT)>l{GGih8UAn-ta$4Ec+qK{-m4IdZ&1iey{J%zKN$d7t8v<;w`2HI zD8nBihQD?){Ix2>Ul_+0+u@)0Al|)+)z)LhYoBRJld|4FTmD*)y5+A`xBNkaQ#zSP z(!%~WT5&9YuDd8BhvxiimE}+FPZBHiVJ{hR{O`-iJ721d4=ii>Bb`$22gb4VEO<-K zzt~n8f|D$NE&PahzpqtkwEdXk*xC~OL$ZVjpthq?qtf^%4uZ`IF7r5zzrS4?|61Hu zU$4>8fg15{O!NyWPAB8vVR`t^;jn);7&t4L<-mU?z3cfwJs(uDyqwaDti(bC4Hb=;dQjaOR;!``&UD!53l1kEV7f)cpXasjxp*WbTTaJ2&g)t zv6}XE9a&LJpb+}6D#PMn#=`>{d9P>uMrBxR6*a>ml{qw!k@tGWzpf06gT4IVKt|r{ z8P8OP#TL>{y^h#x`|8MhJ>%ch42$5mSE;Kp$Xh+_-&TgjL3%6>6vBHw<2RFGkyEDC zGdOweZUk8s#EEh0083?0;XpdQA1&W?R08iu(z~7y>sfYHy&TfZ@iZH_=hS9~qk49a zUgF973HTlEIkpczjD1i&TE`(UWV9th}{IqAX4(9U?@!C-N)%qFW%KRpHJezq zY?skwlpK^6lVvmMhx;s=Nk42`N?1c`!dzuHDTTQ(hI~I-H2d{CF*SbQSu|JbWapPf zb0tjAFN>xztu2(vjNVn$kVW$k*E=-nXi_jOKe9$xG;basr7c>;miaC$7_uHNKYA-$ z=HgiBU9c&{&5E$iI{g!E%K`yn;5>m3Rrk$`UEa{RaE699K>B=*1=K7PvR!b*!@M*r zda*~fAEZ`c`!dufPR2VP5F`WcF6X} zqZ$hae}X+n6{&UZbeNC#;!Ro6C3aKv(D9+LvIR|Gd9+pQfw6XN7q?FRt~w%OpL-$) z3b-pG0J<;Us1SyFQ6U>Nt|vhK_X^?083F)zAJpy-BcfYfvCqQkYcm{)h)+)fu^<2o z*(>tzP*pw(0QFT3^`LXN9g}%?IIcUfwHwtseonKH9c zT$u@!*;oBIvv!QnqBIo@Z8h&5(arGPjrtc1t{?yivlCm4HAN9I&t<1?vz}Xx#p~sO zwX%43xKiv1fKtiMq2>foE)*n^IEEMe|T!d*difhEWRBg`ApH^)n;S z486n%_GZZUL0I}?vE`+@mOJeW()lpt(A4(6X57s^$!ocR@(jh>rD3|9T*b+@2(X~dD zjXH)tqMw=TcZ+*ZLL|9o<+hC`+vvpLZyv(_Xo;l7a)hM$Pb&A|ML}u>gSlyCWBsB}xstJ+Y|7%q)N1M`KZmFFnOPJQ*V>aD<9{k^PuE3npd-Qc11aj%#D-l;>Rgbm5RvkAKR`VMa7 z8;d1BoBp9{k!!G?H?+=EEh?}rE54UaKfU@K?4duKFJzL)F=fZ$J<~tFQo5p1Y_B#L z{|?Ke!B79o47Mu2&WsZ?&g(z5l+9<^Gg&tWzPxeSFTcL*m$&u4%vQLKsN(m&_q~bf zXH+Rh)Kb`U#QQQ>-`p!_0P9I!PkwN+q~&`XUV1h^dLd3$zmQ#_Tk z+$@)oi9*f}MDRJI5fe~8_`b1;;)78Hr^%K0EJe&6jr?ts;od$`y#Cc`W_-KSy_&a6 zGM226$DH?|Yw=G1{wi4Nic6AeIYTd{i`t|d$Wd$%NQ9!Uc%-Ca=_S_{U-6X~N;LEd zH;Ut%ICRk*TP7lqUq0`!>L}ntF8rA7? z!VdI}Z9Hljosrn4)cK8M;Qp|wJt0%87~l6B?SNT@tgg9a0rcPq* zpgNe&StQGY?iV^)+cNX9G$J@~aBi9yCNz5U7@>NzLXLyFS0N2|w?caLF@^N%yA;x^ zmlSeN+Z_sFGma{pq<1Qu;?Ait=8tK7lz1;rjPcEMO9Yc<>4cpRWw zbeL!ddH5nJmo2BP*3=(#Qc!(rRw|=nZJVt+i4el>?>)OX&utjAp06KlR6u* zS9;W{zbdMRYd9LIs;0oiHDeetA_oxT6tvc~D(Y_i;ifL~jry=X>3eECeL!*g>K21j zd*tG)4u9cki6S)s%j`wt`7CJaMdVW3Rp8Y-MuO+VO5iz2P2eMY4?ORE;3=*IpVFq9 ztVZ?mdhJ!clzmesMM(MfoalNCPR;kAq&?)*&FiCU9BORJo)VAr!sdVAO~ldjbJbo8 z**`S6JzdSCo+ur#Tl&}-XSBw>>aS26Y|mc7XR!o40{g|!(Q$;r;sn*x1%EH%S$ASi z`$U0vPAZoQa%JOjk46|hI@&=W%NXr(Y-m4D3GrRbFE6Yha#BIMD6rPWR2nx10#Aqa z6jC0^R*3PV(Lp2qv`CWPguzw*JlhDSH`7$gR}MUu z?=rHB#yWp?_VomPUH(R(BB-!-%r6G9Lx+l;YSZV588P1e824ah$LVBm$j4N5GxDp;Hc#1W0lY0+OzT zV7Bjgw!-`%zK&J4yqHljkQpFi_w*z(J*uh!ay*6W-y+aFA`pL1?z)^O?i`Ig4K(rY!x$F1SA)6&oB#8gpEk+-O9 zfKr?v7MpW%7%m;kh2kCwYHRBasg$+#2yoXq zY`3_%drj0|ocXBK|5hVUyBymrWa@x7>E>;NJJe7Q_FZ>Dw;9#xP=nbWrhjb>rS!@* zlb^<}lKEo1HMAKFyiwpTJy3GFeRb{Yjk48w40i|^BmC59 zak143#keU#E8AC_tor62;^|lwrwJ+IG*IJ7T(+bUM*NpFNoeF1r^Z5(_+BzFEuk)* zVnLjeIP?b%LP|WUkd*}qk+Wre3+LwB!N(h;msXkN|FR*o{}Vix^+sD#K8s) zG{toXw5sN&sqU2Art^364c+CGd0L_lH1b;~^-TrYvYdg58O!*3*k1+Kj==Yirw3JV zN(_p!0p)=SJqQhREl#Hck(|yc-qxY|q&dLJR8c}VHL?y?yZQ{pHhogR8+zh^SaM(ox+rwO&B$a|s4mE_bt^^|sHA3b)X(c~Lz zqCeG$u``uJ80fG7I!%obtX;;LFrji~K7tBY=EFpQcQCXX30U9^jW9|?Z{#$!>eJJm zhOjDepzhSXKvA(RoBn@W;pUK-5V~N=h-gKG^wM&&Ik+nZ%#@P@VUnGF3X-4aoeIq!L@$fgr)0@B&@HOeVl1qG=Dzzf*uir zywtR$<1mG5AA`tWn}~j^yU8nU=@Lplby-#eYfGgs)IhWLGFAg?OPM0AEoBM}ZRsIB zNC&iykeNyLYkpAaCrv3Q^o4qni3TOtZN7*@T0v$P)TF+A3SJkmd_4*vRCCf2(tjd( z(vc>WCzAy|+u0fIq!32MlMGw1j6&D1TYJh;t{enlOh0w=j^`Y7>djqfyzgwrn90;f zCDE`34X0OE3g)XyL$fFGKZM-pUF3gGH3fZ)g-@y}VQ++^e#j_#*9SsgWZZS`$59QPx z^B--ev+7A^rz_nn;#mP^p zEv}O;sL^{jDtr8XofG&6|CKENI&HvWkpI4gY3a9-y7W1!B0i26rX^zBvVJuYiFCAI z=1oy0r7i$gKh?vN+}g&atJHMmk4MLFUj1yNc+5557#GT_cLs6uZ^FxDS}a{R-qIhvo+3kkOm7MG@v(-6j7$~Mc}y=<3)?`4FCIGfku3l7 z2~w9=r%VqTYuuFd5swd5hyNBXYE*0AGb`Z3tERJc67sZLE!&S(*#>Z`Qg6E`%j$?N zUyIYjwRrk+;Pb_?I?(4=>4vdSRVL`<-)+mB;YY9Fvuesko7XE!d^Opgj-aKlX46Al zl+BIQ3rU;ruVCjC1OkzXZ(9VtbUqN7su$( zCzSw6Km&Z=m|c$}f^FTH2lSQhdM}|;9F(Dp=k1^XB_dCnSPzXE2%po;DyXDo_nxr1 zH_9-?KHqF#95s_1l5D32mN*$xi7Fj)$zk^r z>5)8_yy0;%MU_=pUW{jYM$DDb_K};S=+$9wI$l07El13e^5IZ=7;TDrh#r6@-M<~S^z%)cc6;{oiD%>S7xY+~nvPQ?nM-6CLQBK13`3=<=|Ioaq?5e+O-;R+ zK2wt*ei)we+6v++AcpCq)}5>zdXw5+hrtzD)uX^7|J|OcsYEbrJ%Qp0l6(oIUm()) zqcK3kl%^)XfdK{~KF>Bnt|(1SsCOhZ!(D0C=C5vQIt5fj7}f_d6E#y4W~;IsAVX5# zO4N3$oU6z{unSIK>XnINnSJz_8K#}pzg3BFSsdJ4mHI>ttJ_%Gg>2x($s(xjs^C!dm@3-FAfOUTI2g2*Nl^&%BaM19Wn1X*EAcZ_tEC8ARu+eq$J z4GYQCqwehFbu&}!lSl)>v`%XF!17d@?VNMQW+ri3fH|`+Gt-QwIAvST%*53Oe5G;H zCSO&!PqClOOyB?{!O`z3#;p}fb#YiZMwpq*)7T_m^%m}eU7LxC7OqT8)I@#OUID8V zQ#Gu6XEg3wj7t=^M&nZI1BSo0ejpPNYEP8?eGOy6Rb6h)#w9SVj7uzCT3`=U#-)Rm zaj6{?!`(>!)Xe9@#-)+X6MR}b|2+@sHIlA0ETyYThw9na|0=^0-LGI+40O-#bh0XC z%$Fd)8fP$MRl32mf|jlS(UMi^NcFT-J!$@luNs%q>Bks3zpP5PKSHb0hcGhPyrinG zU{!KDaSBdntI|7bRwb?MSVXW!-CVOOIrfoTm0b4mzOn}_E1Ey2gaCH7-`=oQ$>r=! zRg~Cj8&AJg$!S5P35Ben_bEhabFV^_HeCN64#Nu3vD`&y*>gz`E2+Sj z_T^hre!yBtThp%tKVcRTRn5IE7B=K}(wBb1Evsr^AYriso)s*|guya8 z@JdI+yaB*<>%hgYO2bW)yaT7C5jt?&$Vh>8D5Y3V2QHF@4*UZXNN+Xm_Xn^n;{;1J z=xn33-|b5KO;ZX=yQcj%qrsrC_M2LoD33(@{Z`tbU;F(YdPYtA4f8JD@du;;({j$+ z##GfGlCynJRgJZVzOsV0S`=1kTt29T@iOn1L2b3ne9~6KNRrDKca7+>+UgHZDp{qi z{s?nqrlH@btv;nrSe)QAKd+Wlp4K>4o&1!JNU?5B($0hGo5R}b2i>`gGigWHwX3LP z842D}4s+hdmXNSSHEUaf!XDnD;ZM&pMaF2SXEt6ueN7ZlZ9->&Z;jpO+KW!(YA-tI zdM`RUK`s)<>Wz?+v&RA|^F%`Eo_~eeLEA9eu=3cpm)B6=@QEQk`}>A3Zm(>|zUNn? z4K_o}B|%)=4$hUjd@~IMviSdj%3R%M^(mPcKB}L)n)$owRip_2LHz!z-C^ti3j+=A zV>6g!2x4=*oCDGIl`esr;6hB3-A1$Lr{DrPcYyJj>FVgj?}-{{kc+ z@Jn`nZwJVSCtW2tEcxS@?w1qny3SO;Jcy1vhH0YT+Z*@`)?cqH8ZQZuND--scv9j$ zNFd_SVwVS((?lhlGQKzW;Ls7fx9KFZYpQsau(NCf$C%`xh_jG=HGs(@pDtCQGPJu9 zZiY@sf^O&d<+4OYsU><;LcK4u@dHFIWM5B22F@{4#`F<-`R|%OxLCpT%!^dAoAP5s zF4YsKW^cFK8qHnucDqMCk9IQ`ek{D*4ySK_Tz<3a z9H#nk>H4P9B!@2Fz*H= z9k~JN0YLE0#-wx$qsHL|=h)IOjQU5c)U+u_c!r50*4-MYl(=fysRCVTN*CT?qL?D1 za6LGkODS1-x!|!RRALMSlyltGLE9ev7@~rGb@G&pT3;2^W4!oNjdpZEBS% zI}KqX)YbU_oh0%gp2KY1Hx(mdKYjZ``u2sQN2Q(VV9ZdX9+kE=2`-L#a=+b5Wl8-A?Jz%k{R2Y z?F;qzbF>=YdAeF#FXGAE=#{NqiYAVkLkbRmy9(dj%d+Q}`=%6jFI>o;f5BMRhz(OD zS4C7-Fb=xSaVSzTFDbfs&AI$p5T#E72Q_i2a0D%RSA` z9HBVhyfy%!A>?JTp{+Jj7rIv0+QdP!NT}TcJN4*{esX2j<sHH^S~6-Y+e3xPYB@DiU8r?uTLj&xR-T5lmua38&2(|cO=W83QfzxZQnChih25#!Y>DQ@0Eou0aymMqt?i;LL}p^0E?xy!5a z&qI|EQl7n>XLyr-L16rpdv=rL#ylc02)`2N(m`n<$AN|p5@7z97J&I*Zp}z?2ID7# zA*Pc=JmeVOW_(tfu8azv3jo)2IsZ)4J4ca-Wo}4;TnHli)j&gUOz-PsZ`lp}A}cYpw*G2I1Vtg)69-%0-B zR3`be84_cb1V_YT=Gc~f>$=(Wfy4|hax_4k6a!t(P!CPOrxmh^`Y#o-VBW6~iSVlm zsqjfc2_iax<$n9E>cAMWvdB93DG?uVgZgljnbVKuvZA;9bRr18o@{&V$u>A-jhjJ6 zwi)+64?i3PrXIF~i$oe8?4(qdZytTT__%N>KIY$}{ypqpvJ;QJT(XUD+`%|qAf!?p zvj%Ajoo~b06UdX}aafJ<7M=$z-IO(n7z;S#h0v1N5}5i)=}Q5pOfdZ20*=p0+mZwv zAtBgXl7J&DyP@g>Q5rf4IC|t0$I!*$cBVW6PT+?h<-kKiO0ChOnIswx?)f;83)#mK z$pcG%O)b?!l8)Q(44op~8RT<#jFHcK^C5le7Yp9N`L$)u_{G+9$s?3dU@uiU4QNfTAYYxGDP-k^|iu&5AK#aW5^ zNc?9At*SV!2s8&B+Wldkcs?cl;7Ln{4^L1!T7$EkrKoS0ka0Ct#R*Ar6n(eCfwn{RZw0^ z(R@iMDGP}KZG~c_L_P`Yh&&pZZkQ~+B#E%z{dN}@zoMGT3GgoEWIH)28l_TQ@i0Pf zpSt3MA_O_ZY6a^`I^)f!pKSp6%kMKO-f+J7JuV1iRNM8`wHp`bggAOkPpF2WM4&N zK|?U0p?37n_@&>VwpFa!qem-K372+fIFv{oCP>;C+LhgYmAVTwi;B+l-FoM!Npn$lBfRz_L!)OJ>Rea|YZ0MEg$qI)wOuYe(QEvJCEQ!|yz^C(-30z$~FT>*hKlI{d7bt6067?lFz>Y}HBKxMRM z1q4PN<^>cGl6O|2S&(5>1;huE0)ho2x=N{lVCmRE5%bL#u9j;#1;iRU(P#xkQc6|Q zJ_BbR3JA0at6{vn0^(Y+3OxlxRq~($qWX|@B0UAf`kQnG1;ocn1;mwBKwMcWAg%$; zngZgQK?TGqc-*9bASvT!qyl1a+#t_F=*4rTfOtZofT;h76bkQNPNDG0A%()>N2E|V zm=p?2^xjILa0Fpc6Y6aWQ7HVTLOK>)D+&e9Oi+kI;U>c3ApAWd;Vm|vN(?5#;s^#c zOQScn>9e6xxT#&P6UuU+jYi=E6FqGLrt5J@3f3JIr^<)p>0vvFByGYQ;votz_6mjK z2LDRjFc5x$z%SYPy&E8i9zt*p+63b)9PhU9!9y)3X%mE2XcL5K65J^!$saD5=)j}? zeFbeoPyP_1$mNnhR#7NG`A{f;Vki{q4@?&lL`-h!6iUjOW-uU-oROahAGq>sn%Pwg zLBy?igmzy+r=YGO6RQQ0qXGx=Rw{^0V#M4W>FEq{pS-8 zUT2pwp9KcjOp%-+o=D!(?I5VXk9;8rU%9|VwoxSfv!POp{T0UFadq`R8s!s1nMa^} zXiX^J^~C{{BiksHKf9Jv53i}z+fEIX8repb`nk1~dSp$d9{tilsgZ3|sh?jY*gHn|!8HHu>mT&+d5ES{-G;I?-a-0pj50Jq4n zZrpC)0B-wN!R_$325^fE>&ESl4d8Zg72Nip9l$LztQ)txR>Q401SZkbA5y#Pb#!0- z(okP54p({qPI>h@I`66Byhp0M-%?(^j?Vk#;k-wyyx&${y^hZNm7%;N`tXvoFFU@{ zB6HxicT$Kk3zw)+FHupzs7QJ`lW$#Bjc!YzdlrMafnia z&fgKO^g5bW4-Dr$T;=@-<<;xxybn&YLn4W9|E0XW z0)#sS>~c`htu64DP6CT2g0HJdsx3Sr?*!j1MDo|m@rJ6U>kX+jDI$vFu#g%A1V^74 zNf(Qp++5C=CQnlvO|tw(G)DldsDMllB}h5v>?I{q)e|FPN`SVce3G$)h0;_CnG^A~ zRRzG?B)a+`|8u0Uc=`*@=~WT=Uvec0ju*P@V}~UCe?L-+jY{J=iKz^=K>k+(WD0zP zClwThPCu*4UNwNmQrX%(tI2QbEyS^ctTEp$8_f4$Zvt9Zd8am*@5~1Co!wx*#XqW+ z(RI~t{|58z-C(|h8_aiTgZU0`FrQBt3$|ok^z`{^8_4H9O&iGPeP$cTclQRz(R~}t zcXEUI?%!a(+cr3kZXe2b{mS!M(!#JuZbo}~viy%{P$FR+%kPP)EPuM^* zOq@JLanJRZ)r4IJH=o~^@?=lvHTv_j>7Dr~I&eM&_QF!uVWrA@x}(@z`q zNvHZoU3C=N^pEt?c#W$-fWNG}`DdX))cZeGNk^|EbL>@}5#74{&m%v7He>a@->7e= z_oj7AZ~2LeuAgg;m-jC#WXXoY)rL&mcjcTbZ&KsfD!%3w45!{pS~$?zl~>NUT6AX{ zksGxfxXbO*1k@#7EX>}BD^h{d);U@w+C*Uv{@!cK^JX=@b*W+>>ia%*;c5WJI~Ew6 zFH>AEbu=$q?Dz|}6a0s0C+>#Lo#K1oKNfKNBbc{mZ^aeyRgI2EZ}eXw!{te^A>lmR zjzBxV-5&a+qIv1;DZbgrKg;nT^6!=PL2L&soM;sh)4#I$f;w#npMyP$dyPz8U(8(94i1pJ=Jh?AXMOyP`sK4GZAXT?6Mwc=P#6AKH_EC7x%r(upw3{ZH zIk=9_S>~HL%=UGr4^*E42&7RXVg$iHOqLlnT$Axxjv@7B#cmN6O+V#-F)5ECvNE)^ zqnN=*nf|sXKZ%33-)F}avw2p`b=BW&rfjLnIA&OdazwL^SJ$p!`q!2@qUez7iD`#$ z;>}}g?>PHsm6+QeX&t2*Q*LkYotg6m)#6jTlZQhW~Rx@*wCZ7y1`~H4}x6dY7X3G@FK8n%U?F@3-un)Pl24eH-NZQE_D;p zucUg6JLn*{c~RX-=f2UZ z9`w{;D(l=yQ=%)|u>*?_42w<+F-&8~qHZPQn4UzsR4>vo%%VbcqXjBNz2;Sk1v=3e zqleHBTJmUT+_^dIJ7kT=LDc_ zg}EBskW81^iJ-?Mh(dZ{h-@ef@xK&alU>e7H(q`+UVdV)0$GF_jV6E-3bNTw0F15= zq7S+>Lpt}j8=1_<7=*-gOJ*18EWoe-$K?2;9# ziwbc?ds%pvvhfm+H9MIu@_4O$N?!;Nf@=+gVch`+7BQjIQC3~A&e>;RK&U5{XHuwE zn-pZT7euXM7AFUDxBT9^1e(1C!cV#Hp4YJjM4RS*;xGU@8IIsSXRocErFA90Ylcu# zUAGf+v%HDVaCxG7>~7VfcqqN?iaNbaZSLCbFidtTYey$|Qo-F(&t0<@=xyh04%UO! z1#4B88mg|zce&l#MN)=uRFEr5J!7>&OAA(54_Vh#s}AAwC?QG87hryCkIu~q%)c^I zODakVCN=*GH8+tdD*x)tQzDiJb2U(1G;+#6oFVkWTinD9 z@T!Ts)RG2MOVg4xNnc~DpSg)ULrtu3|Oik=w5{(_?_=x8ZFXEf3=2V&UDskR5 zb{o69&R6XS^`ZaCR15WL>Omxx$^}zfv2^ANKP;(`0ateIiDGRqxXB3QT(LDMu~TDu zr$#vL-X!$Yvr{w2PA0Uei1Y;B^=wE>YN7*4O-Eu#^~{`_zgIdJmLtE@TzVG+tap|R zy*rzJm<836v7nkWmbxLf`9!aZ>B=L((^6-SnRh0>#T2P`;fX3KX41BoV0vWC)XYp; zZM~vUrj~00CWio0OKe=a!c zNvI9&G~GixO0i%7;|$j3ir+DXXI|pFt@$!*m48olBe^W~wV3>EQ}AS*kUiVz z`xMg4bpBR2wJ87DtMc%{c-mj!P@mmydR=*!`tug+DA)Fkthni9pDu9&5N`ODJDF5z zh^YGpARN5$kwVzF_mM(ad{rNW|6|RRjDeyaAs!U|n~qqVITX;c;>6zveY0Zkcl3nZ z5p;TlB^-E1S;DD*C`;J?a9;@Uz~Cwf7YKNe`Q3U7)bp~5&hYL=o=#Xa|6-89MPX2i2jv`KFNKnHB6}S7w}t9 zjlVEiZ0-N@)%4|ylU(go`;^}pu)Z`Hzc=DfO%`|erGHh#e|a$e)e--d$pU}DUNhvc ziTJM$#_x;x`v=JO+KB$zK=iLh^w$Rn@w$k9U?6&bL}T5d$Aoeu3H)ztB-2ZAHwv`v zS%yTJCIptIMsXLh^rnc)h|0p(>xe8$C=h1yd*mNi=v{LIQF8WDf7Q}9>$QrmtocVZ*D0@ksX1=a>Z*6mVgy2F6U3@aKc{9+tlFaNSgyK7c9SRW6tjj1v}g=) zGn&(HZq#@2(=|ru7*qX3lWaD5*}aE;V42-&H}VAvc;iXoL|aJV1TR^)5w z9(3@1Z@e>+(;VCLS6XlD7zN|>p1>x5y(ZD(p?+A8TO~_xzN(TZ-_%#h#|^R4;jcpM zt~Z|_h?PEp6=Js?JU{SIuj zJp8?~;t`+7I6xQ860kO`de_{>LRxU|DhSyLze^`*niGb*BgV%`u;S zuLQlcs47;VZ`#=Oz0tWFiAF0+Cx0WNb*pmxsm8=jH$(%ZKKl4#SGosP*zN!2KJ0#K zeJzfc5F@r1a???P~8sLHigZxb)JFlXj$n+2gHsaN|l zlwdx82t`;hjIv@>s&nlykcPeZt=BC9Ln^_eocgD!=2r15p+4d~jt`~_a?z$&Ou*&A ze(Y2~zZ_n(i6%_XJM$BAnqhkSjP_KiK(%>%qQEBVmg3(16sTwwsF)}aor^NQPyAK> zSvESuqNro>E{jn8>*uuPK)~Uq@TBg&K5dQ5zr}=Tgs5*_2Ttlb% zjdb$Qe)PiCRI?8bURoedAf}7&)3&~5p?#UW?QO?=!)txQ(N4|y>M4i)f#sZ|y_KGH zv}e%MoMs(m?@c==TMUSpcTO^aYU1f7I8~o{Zj?5>H=8K6rk)j2OSnt(p;CMDY5r99 ztQIq=P*x;{p-c6~K;nnPZ1t4i$UxHt*mdyV!w9!S*>?E&;^M70GRsu8Qg(f^U3Y-eTXi*t3J=|N^_P{^i6d0dy3TR{r&pe@X&<`{E6N6KO6BF8FJUB-# zCu+57Jy~{e_AMyq@!;%R#J+z9rx!o9L~Z@lYi$A5Yifmo!C7VQTRN4#wsz_@EuJe6 z&R=hqT0iV3)zYa+&Gr+oEwHjlDJ!$c4M=Lbm1Hi{L5s7k7RkaO&iJqgA z8RJp~a#f(Tu{p)CiOtc&7B)u@8`vCO+1FArO%;>Oe@ZaY`joeFKrlG6<+F!nnl;z zb=Bv&jy}O{?4hed?B2disU3IS>!d3hFe#&G9Fga zoHk6r^lc*m>264Ky5$kRtGDI9Uz%$dKUDeOZwndCG8Z>%@&>=`Z4{gL4xeDD&-q|jBq8}R8B!MHgijv;EIV0~+39Y)NF+baL z%mWQ{r|(+H98X{rEZT$-i0y{G~};$A>sDyLTQ&= z_gk6+o@CYdkt=tB#wgZx10G3zj`zJ7JKh_pwmkyGx&gc8%1Bw) zFsT=+*wP+8!=AtR9wSEa)^=#{xp!-0ntFL08A0v6A3-r3^$=eo1yS*Ck3hz{2|-CQ zI@f(N;@hS2s-5BZGpqF3a;`Xr+K-GnkV5kjD0Z}c*iY@8Qz=rj|1ZnKD>4R)GU|s; zP8CvH=rKULEsE@Uv&=~Wkv8K}+5g=t$>PL-zbhlDI8I#tkCXYktjyD!dw@qm>XXHN z@>^xV;Tg|U@>^9Tbu zv^Se9ytMVbvkJ##PEI;UMI>J3 zWi1T7P-jACkX~ti$)^9yxhN(Tm*sC+p`?FXl{7q(s$QJGe@eSA(k$~Yt1K*)8tzQn zGukjQ{fg?#+NeW&iXLUZrY{YX={G9mwJ@20A|wNgHy%o^gvI$A6P*$J@A12;?uB0H zj;XEKNXz6R7K$4HFUy_=Shlro^DL$Zz0K#hQnL1r$G7*f1CW>Ch`y=|Ss8|kvC~Wp zPoNu)(&ji&OI^ocXU|@97j8U9K zXuDgn|9v0HE@|Oxz&_++Z~4OZN z3hJ$?i7TWSCEK&?2f0eT0ABvhO><%nHZ@8JuqfBfP4*ygtIP%6$poPl5LzV!?u`IXun z4+8Te7LgtVj-+PeZGyn;CJ5V z+&u7u*Aq)Q`@{4k*3WG$9@Hx@l+nq--R2Ln3Gxpwm~9uQl#sbB;rwjTO?*wHYyIF{ zOX)P(eVLT(HN}EP^_n>P6;90dmXvrhC1$o#rCTM?GNm>O2iVRkDJQCw6U(J+Md?0D z!&Peh;9NUUb;kjTz|&npz1ya~u~?$UG>bp2JGMQ08q>7BsdOm#G{a6z|Mcb6bTd46 ziObOhsKrT#E?V5uV$Jx0PtK;dSD6PGkK&}cl>AQZHz|4F2b!f>cGM1vq7iHWd{tQ{ zVLG>j1GJ}VvxXL&>osL6UMqPl40@4qkm;h5P;@^cy#pCdGu;->ijPe;ys+0rw%-po z?aV0ZJvF9BC;SWvXCl{T&VH9<>-alqatYOjM*@o0Po8gmP5@}}jdvyC+d>uz32Vi) z#v*_2n@>SRX_L$rFQqxJIh|q9GspK-!tL2pDSoy=j9a;(>sJSP&1WpvEOT)Xd7XXk ztz836IOnar!i)dfh&GaFEW^CEInlpFgrpF*YA| z8yf=qC=eDeIFW!D7`Yv^JZgJ5GjVjjW(hUAtz}X5*HYSxa~bG<>{BOtZj6B@(5yF9 zN1LvB16bpwoJOKhJ<4%yrQ;NwX^C^%>t2b3UO3e8BQivo=~p&_+-vns=9u!VIP|oNM@!_PEnoo^bn=Js4uHvu27OuNX4q7@b+8J# zwdWN2v*#4ncFuV>>zwt03T$Da9^qMC1lk&QU!zOV0>MhRO3UJ971~3cuSX%F`!|~q z-PU}}|L=<3sfmbxm0Ad&?TU-p*)?`q!fGO7<|OVr}&$m5HrCUzDHa^{t*ss(3U&WL;c-M3uDFgxJMH}V4t89pL7$S zUiUVFzh<#zJF+f?AOSfemH_ZUe`GK?KiAEj@CI6hEZ5om8P@j;*`aB(BpNF!Wh%VDjs8g7#L&kd!%CwdaX3ZzReiR-^8rF?AZGDrqN>y zY(vRr$JI2pR^kXWt=4DD7gUpSwHov`Kx_7Bb1SgclKiuqn6kX8a7+9CdzO53jMtYJ zqj8Y>M7&8_Wf-ie!6q28B%J<@L_gSqYK|JM1fV}ipw&+s4vMn%N<6fDVv!$n+ZMsf+6)Z*}~P%ZvFa zZqqs2Mke&L%1}q`oh{5yPTnMO@dg+?_ zf6ethS*x$_$$j+e8%0+2b*USx@3v~#!@r1aX0_MZ0_ZiS%l$0VFRBtTH7U_3wH+Yp!?luLk-<^i7iC z4he1&eN8gl%7Ze_=OJZ+wjr(Y4b9Q0(Zf!Q65!A^ECn$b7)10QwL3eXu%;{JxA7hh zpQ|s`=^OA(MFIIW6?}u7XS3{pj1QydlW2J%Ob`~|CgQUFp zgE=X+8(#bQ#E>|1BvD6mj6%20lWMdZn4puhD3D9K0=uZE+N>t}ok$}3ta~fQ$ zHUt7h8m<=G1ga5T<76pm#m~%=Wef~!6rBRqv165D>!g0#xC-1Yp#~Z?o}ME9EpS!w zzl4_nR|9_=#ML#4u1=NBsY`4`20Kn`g0Afo;0b zW1MZK&gQ0TY)*7k@A-FCOysnfT$6O`%#JUsF*`MS9n9|40nW7zDd?Zf)LL!O9cvsV z@RutvAUKR7eUG;p_X_c}xTd|3_IN+GhBf8Cc(1H&4~cMW9S28J1)HFhUOT+{6pSLN zp)xp{QA8{;n8a4U`|z_vymQj>Z=CZbtl19mFU>{bgQ$|^R({#ht4L{4{Z?YjhZ&N{4Xnyj}kSrHpm-K z)OW8z)EhKyjDnEpxd}z-6`vYCr#8~84I25rI7H8{3kNf-HENAB!miGDVzZ;QAi!<1 z07I%Gz@DMGcn}@@a&cctNr%W`lj^oIKUn7bhtht2LfX#3vNN3aa}(0e9xP{v)Bf#* zw8g=)7*2a~LfZbpvOk>muP3Bk$qtq)*>LL5Oh~=lI#@2ZhExB|q|_j8c?5G`oRk{W zEgSCKn(94Me0EH7?;-2hu*>bniWrjIEbl&(>&*nZl@KOS_Hmih23$(wvwpV9%HY8y z))Q?hw-HlU<$W?&E_VJTl}4#dIjWHo^rBSrCNE!k)K0EmP>!>r@t+g9(_Kpa7<5u}k{pydES z{4PEr^JbOe^D+?BQiwY=Q+#eHg?K_U#orF45GQD+Ftbao7LEUAioYHz!$*BH&1Z(v z_*ieI`J3T1Ho}`}zBru5#PxzL}H)_ z{;Qj*#TPs>zea~IX4jKiZgz#x;E2rb|FIfHH_$epAwF>_OnDvh{^JN!!A)(uMJ!*3 z1axK(S1W`Z4omFh^=Q*n+KEYxi9AXfla#|B}~=-ZYr; zB09e-J#AxF%#Ex*{iiflo1uOO_avCm24Tq$0X?)n?1pRZC^N`@bc~Rn$%(Vl+i78)J}F!1PIP-b?65sRMO5CMARn?K(XLT2>S zF6rj&eocfOn+dgauGlWFn8`WZT|&h!2Gc!`ch2RqRJLEh2<1AcE9bBn;t2|o$v;&t zek_dBLUzV1nwuD&9Kt^ZaPNrUk( zsAi7|hkGK`Btqd<7JBTmUb}0#WF%o)sA9$x2fzWEexy(3-6fU>Ink?h2oV>LfzgV$ z3Oin*6880@GM98Xcc@<9tuT00n^>CUPOv-XHNj|}2h(OQhR|5( z0usw>9)ot!zJd!;p|m;AlPr*bqXW=jq&UmUNQ(`@SI9AKmGM>2U6+GaYxQLVBBI|> z#URssKS}47?}+*TAU{BpB-0S(XDd`rnRXiyw3bx3U*0@?{oWJ8uJGEdu`9Dq%eTbo*qQ}qU$jLVghHC)EJp} zSQ8(##b7{;_>n?zQL{fFMlL#La&iIUlsHgGfm@%dn-QNC$ZhTq)VKb$LARNdNX9S* zW4N92=&YPhfo>xl*GN!53v^OoVHJnl~Y>5#Y+3w?FyWVToVsdjS=Hixi-pa&C ztxV%Wdjex!uqflk&Tm;NR-LtIW4c`UXt|B4?}5kdv2^0XkXYUOrkUFctMi%2(8DBC zXY#Qy<*~aw4XmooW4U_uc|ma491|G4VZ#a&gZ7%7yT_Vr?lB&i7_YNvYpV*J$ap8P zl7J@9dWwwqCpIjZivLO+mHvi&iX1HdD@j#91w&yV=@hXBCY-zx-kN(wEYKwpc!9A= zhqK*Bl473+0=ndCga<2eK_!LK`|2QchjOcCR$_NnGb=Y=z&ccW(m4tZ+9~zJF1W5T z>T3&O+N5gxanM1$O}XYj8xvCt)ZO+%=~2s%C~fqN%}!G;5*@JFmR8`z^Tj@9ee|KE z=Y%Sa@gqk84X`i^s$u53+RwW8#2ZcAb3N(HNJ$8m^Cn$}tqCnTPpBAOk1BfM0kR}r znr>6wqDtp5R!AoF@w2t~mpO@&p8aWk9EFi4fh|;6@Y2@R}jrrLXD#Bx~ zS~+_a$a-ot+yIayNZY-(NT&v(JNN`>j8sat1SS=goE0FUgjc~g{Bqn4k_g=(prAfI zAceN~n)S{V?wQ|LU`G`B)t^j_^O`FZ-_Mpn4R1S{G{Mzuyel+Q+eDir5rVZL#L&%D zAVSJC7Ua>-SSU$qWeMTDZJp1{M?QBC*|%#*h&+5qWG(|6%_sh;+MRp0S{d_#(c4xd zD0vYHTnqFyY4}G`HXOz&Qz=BUA+hP6eZu{a06HY(ChnA-Z$qT`tg+n)XhwzLGSCHM zMdpijEgld1i2k>hS5gr*Ow!?LOzAmVb?CVa5*53+O`uS=?7*xdKEX&h?KGU|z z0R0rulWx%RMg%*^FyD1H<^>j`1?Dw$OnZUl^bvN?9$KSZhw(XDv|KA`9fUjDqcGIF zM6!+=-#b#CT(e+Lx^m$`fxI>xrwH<~2r^?0f-@?D-s_l?;1)k#)XJaTB6Lw}wp@O+ z4T6rfO@#Ex*JZpKL3V0A;2#-!Lcz+6wTn|vio*%?&4(GCD*Ex6gNugBda>|uv7`*S z(}u)QL9)qW1)eGMBjqFOz^;=}8L5(rdv*CndtaGp zzVqVrWDYQct0p3aw_Snd98u9GshE&@@e`gy~3;^I3F1U=kTa*zzLhH!WjH;{q#Qv?qq9e%a$y!{cA}S5W71` z({8CZjr;oQ-x|%{WY-Z`z7dqnYAo;0rbm(G>byQhWSw`g?7`wyKb#M|fj9)Mi}ce( zoHIA?bv_Rx&WNvuxPKmlxZ(MxLKGd0fxilaIPCsa7~lO?6OoUA$SENb{Ao1p&e~jL z%_^L~-rahE)Fo5@clEjvlWjV5h=A-?M9(yW$xU{Z4Q1y6mu4Z~owZ`HR>#QfI%c8< zqpGP}GQU36(B2l>dzx8QiFJX!w|F0&WYd^a0qoqgR_|e&JaPzyn(ix??`Sh!3K{fl ze%Rjg(vw)133%`PTuGGWSo_epxzQ(bWYcH2Yz-#O@Nr=_Vs|>uDO)28h@*%Oh<&K% z&MT_vQmu2p`lx)){il0o@Nc{ zNA4^mr6-L~LiPYN_Uul*1Yp(05*7dsb#(d%T;>Jq-)A zoML;Cu!5;1wBM|@45C0gqjr=;4Wy6=yCpL-o>{=kPIt8x^ zi+N!3+`|J)FE(Xaw-9x2Rz0HHCFo2<(UwA_*we9b$rz7($ht zm?EO6m?EOIsE8;-kJ0Ac+lHEgHor4y^9xa4jD}t%G>LJ$Sk&%pdsN$b6_ovC^}Vbo zTP`x86~*V!umnb3o8Mm7<}YJvkEJJVzJ`NJo4>3VwRwjNW$yw(bwMR2xGE77>XYjz z+k@a~26&0eL%{o}jd+lYpLIgSVbnt+oJpIn!C7hZm-Spf_FhCN*7hP(U>t5l)u$#= z)v!8VROQq8HBmJzK__kAztyz)%X&$hKYtV@L7RW-=$EL?KQ$rC#Zs$3h^4mLVyh|5 zUUzLiB2FF)4a7CI`R!%W=4*(nxaVcPXoXH495la#ILtRzfe|Kh?4~9nN45EGrOkJ- zbyd^pWtBEB^GrjVzf5{Sv^*slG!j?R=A&#MwE0Z|wH)*)wh3d14U&W$2{EbcU7}Fg zO|_QQ$*d+}dCIIN_0i>4frw|gOcT$MUB_yZD!nt3a7Yhba`b`a0 z`cEr~@0?eqVF~CPNqesJY8IkR-SQRRq{f}HDs9S7P_m=?DCy?#p`_<*-M9k1B`Jk) zrMWbitV!d!5}&rzxYDq?mlSAEw1xt`rN)hhO9~3~Tuf3^pyxE24928DZ;2ylqY8A; ziDA;1BSHXN1nm&x1zcvxvM|JD0HjxG%e}~DhTD_0WUsAJk$A;M6y%L)xyyMaNnx-vjqg-^1^fgqn+(p5 z%YarPd-^GgGpp~Oix@bw()1xGfeqMfp=H@(ZFsI`x~+9ubIQ5ItCTmBXUEu83*-+J&!ne^2?QYL*(9w{W~OUdAA9x3*w823mK zl;(Q!i2N4Zn4$=!FHHKwwLoy1F~yUbF@^877MU?6vE!UGhD~tDcT0vBXvUOg zfu_cU0?{@sT`;DsUalvFVau4ZdQy>ZvsP0|n$3vjlhupzT2~}sxM5;F$=3xWc2{8R zN6+7=S`ix!4f>8^Y%=f}@zeUJ*(c4Mqfu<$PK6KVb&O*3D65ZR$oJGov5=d52Y5H1 z+kP0uEE5r>5L$om9Y_(;+K?imwLuZFJ8Ra4Sd^Z&EXC6n9(m$7;Cr>OG}P-v?$Q93 zSmMi3dQ}0o^d3g8#$zms&svTooIpsH1}nz>20~7=G+4A-8pu{_|L_pCQVkafhcJ-Z zVvfLeHlnfYpAbo{XpI^78(@$l-!y?&`UrgR8>j;xheO1ITN;{h)(18Ex3@mRIa3cK z$5ws=q21&B2KZF>8wgEvQ9gZhQ9gWgOM`u@0uCTUwPi4sPz+`9AxipE&gG+$&b3t38?qjcVewGG(aLXuT>g zYs0kGD@iNTmM*H%7HAG;7T0Y>IszW(6D3I{T4BL?!7}@BmG%=V5~0}Aw|#zuWmm&^ z4MhbiM*mG#xR>)M z%~UN}d$LEl5Ms=|_wQLf3>Y|<)WZPsI@QBOtz*^0bBbDnG2_=JE{vVZ;{DBGmSYM6 zvA+0a^UvAc0#Pjrt-1x`8whTu5Rcs;@wmROy2$~d>eQC!$1P>oVfMu`6!0U1)%QM# z39VxpU&$scNc)C!N-39@ALBf?;z+~A&pybE2E5$-%{TDO zmTs$!Bd&y6ccIIo^ZB_rK7W1U_?#?-PF}b^5stn)8{<>mn^Z~OZAH7!m@xs&#+^b^ zCBKoJ%w136c$?^#j>U?p6a_)eo8Wa0#jels+y+yubXHmz3x;M63fow0sjg-Ks(lQO zH?kGcn7XgGkJjk2yg4ksCE_#4CCM~#P_1j)u0AtWJ7{(WiNEHhLCHt$h#9ll#)q#y zGLF106L!@c;@my6nb=Pqe&4n1@Z;n<48JW68uZEWc4)Owuv+VCj<-*U5%=AVb;I|B z)7~IvTQ}T=MVQG(p13GG_(e+D!5vaw7}|6!@4c|^I5}7lM|!wrAX2?n6zZW?AWtiS z6F#BLZHUt5bi36zMdU2|iRJRM5U7*a;DQTq+7pqyZmGa`7ONub@2ATB^{J`9Id4P- zR#8riick%GsX=vML~N?rU|1^g1f_fnuv`_MfwFJ}zNl5Cn%MlSl!_8PS(OcXvKUnH z%`6GY985L#0}QbabD-Q77s%53rh#M_*|pT2DE=pVdnNwY?Cs|w!@g}I!~W(Is7z!M zCm1VGnYi_DDp0K{l1SWHQ|Jo3{LBedYl5{-p-Y&ziJ&1+ote_VX$7j=Cyvi^SfHxp zryx*O64n_NsA^JN%crgQMCA7O3n*5gHLF>)%MAx+xf1zU7IqswYBy4Q~}s1UC$2l4I=9iKd@I zG7OQxR3DzF>1!Yzx8`0@2eXa3AQcs{#O(7EJq#?_nrUh)p{|(5JA;E=M378e=sJ~C zQ2tvmF+52q^U1op&YF~2Iz&*?1AW4#Gdv>doQh~HS-MF?y{3eE?hFbiuWPKQVK7hsDf;2 z>*z9PcG~-Lx{Y}Ka5srr!+5nt@~tClsw&Qss}h?YVJsZ#QpQf#`KF3cqJk~J4tJ>4 z103!J2!07=ta-=M##Z=*66sPcNnUYLB>%Dr$40` z4Op>fZAv?*%+JA*;moe*pNkkcvn!@&cU>!VT60}%;$lhiJ~{UnOG3lX>|)8eNUdkq z9Q}k)Ytv|WP9YtY3>ByNuM^h*PGybm9cS@uKNLL{d7ixIz9RKUrwRdDcQddZHSSQc zj^jzt0tT!5KA}1a8&VgR*Ks_F(yjA&5+!Agd)>#A7zp1a=f28UXz09Fb!4B8#h?(6 zI~=!iGIBCq-NVH{o`G{;&GkgP{Dt)7n((c2Uv<)gP_oX`Zw!0#ZC~HHGD^O#5fRVm zOWsd4SD|y=^=@V2EO9C;#osys7G=%63PvXhZT;~LUa%f_Oe1R8F)i)nQbF}IW8_e$ zsX@`c`GaB_?uWMCYgQ>8?GhOr)`PQl0_-sGzWCx(nBYuj#?;`f&WzcW&WsTwHaP#i zoB%tFxVV!mc5pf~riQrTnWxdg-*hLyj+wHNyqx^gaWYTj39!~>GR3iph(VaIaRRJQ z>9%fSzNsT~NA%4|$JRXQ98sHR!JbnpP|&>3?9~_NA_mUv0q;+U=6&vy-I>+A&qcC3 zvr^@1XYKsq(0#5?hP3~4I(Q}Bg4NTZAX+2Wl~XLN^YFWD%as!=EO%q*FTelN48B$F z(iz5?t|mL$>8GoyHdN+ARhhOfU*i0NRY+Gn)ysT#g0sc3L@b{xmCk_ShOi1O0Qo|$ zOLO1H@4D_v`dGJl$L?zNRG(l3A@vCGYSa-KMVGp&lhAKirP><#yjX*gkD5-q$XU5mS7e%O360tTn3s zmyN)Aa}&<15(e7zD7C6bxi3vrz}>joEW=SQB0wIU;!lLY@-E6S3RL85@t53+YprHS z$8xnbIW_z;Z}?s{T(_U{*jxVeYr)q&TTnrAE`+nV;)Kw*XR-JceiaApE=WTW$-Nu; zi{*!Ze#J3Y9NTQzDc-FMcZDf3zL%o2;?w9zB3>>jBdq&3>t8=(yH0$0zj*y7h7i6u zB{yPvT8*GoQX}opk#>{PauKJeoh|+Pp>J-J=#+Wmoq(S(4;SXN%{NS_k|1F<|a zWvLGWhAg;$*~Itr&fQT=e;?o9Ceku_L?woH#3XcBo9} z6}Pl5C*g0dWS3hvD{6X>hA19r~$HR`vr1Y_s8Omc|~n>HE@j0R9Lo~SV`pf z*+J7#g*=g5*s}%K;vdARoO(lV{NQMBaE`6m9G4PW8BmnyN3`}2bAAX`WOUvCm~y91 z+3e-!T<+k~Z14v#rL`6Tu#o=NTZ8ke4 zO4(X`WD7A6uhE4r2+f=hE7HiySJ(xMHBt)nf;Uv8!Lfb6L4I}I_|=0=e)TsseswaS z0l&;NT+bxG`o__f)8tnttqFRt0`51nyMe@mG1#D+;{-dJh~|;A@(Esq};bzjlKM z9#r6suk^qp3cNiedrX1PhA(%}I0GG`x0Z(1C?4hl&r6uRbPNwL1Prn^tf=fQ&1WtR zS%K^umPet9BI6NzSB2PPf0_{cT0^WN0w_m8dimA2emE<>)GcpT;OH-T;8q204}m)s zI35BkmL~*`D{#{t+!+E7DsUnM9#P<-5O_?1M?>HS0dvF6Ucj3axG4l~QQ+1P zxLtu`A#hBH73e~&S{hoT_=R;KRtTsg_P5%aBvfD>v1fE1TCpnZQrIvL{c7-dY7U5d ztA0Cqf9ki_S-&YFv~)%2cugST;|eT?zzGHJ4&?Zt0>2yrk0|i*knAx9Uiq_5!Z&=J zz|V&-Z&KhxfrM{S;Jz?AZdc&^D3cMi%KB>UR0t71} z79sDFJS&Ckh)-S@)yCaRz20bDtB3%~BZBw7KW{FN|N6nJL{+@io;A#l3_$3x(l0w+V@UIo4y0{1I$^jE#K2NXCK0uL#0 zA_Tswz+)k>{O1I2d7J0CQGq)`;3frDLg1YW+#dpWC=g-0OM#Q&%Y6zw5(1x8VEGm= z`lJF!L*QWrZV7=$6}Te=t{2u;Lf}62rjU0@PV=j-Rs4FoR$Wlu->)HL7-@k z+D}$pd#vi(*E_eZy7m^me&IDv^0zB+G6e1yy!tHQRazhh#jgi=)mjJM=~4x*4g3QY z@F&O+Nc86nctyk^qSyNavX3k9KnR==yeq^Ac$F4%D1JS_tCBkKj(HVW2mXq2Q{=-H z>?c+6C&a|Q?Sk?R2ED#IEMc-Nm8iROTuJ(3Gi;bv$5!_ki2{BeQQ6mjhUz}S@%mPs zzBa2W&gKzB+wbvvs$VC{%Zg%6?mD-5aeseQj2!MB}T|mo-~=7l}f3cc|>+p>=Pv z>h!f)of3_&PG8n+-Ek6y>Q+?tKWU<(@7`?H>1(q(B^qCyzO3202S^mEyI*DB@>foo zZ?Wq1wOO4Kjjv8$>aF_;A1!-o%J?p~_$){-*@f+h$3if9XuwO2l;O+c&BC^AvAoSy zB@7*A+S#@kOgorkFimCM|K#Bzyl&66l`OupB^n^^Z!OJt0Inmu+3^-nj12eb$uWl?)e~#O3eN>%F-mmGW35GL&15O> zs9tZaUT>*hZ%VJqa#Y!$eMxT5XI+xNN#UnmlHa7~g_qxt#-7Cqk%9PiW%KC!pz z`7oxu+x2qYCHWnCe%GQ5EP?}9wH-X3erd*|-`Ne|muBCoS8!uL#jATfcPMbQg;7cf z`Qt6x-{pz4#fvwo@XCW9NWlxmb3P^Z2b370FR8B{E6@c3LT2sqE+5blMEz2bry>o zuxRsKDtrGI)0MttS>BMRwA$TPaw0^YSYqo1tb}Q%FlyC)$h3q;3`j+!6%t8*NvsTjhge z+Rm3o+rz#op&k4_qDFeDhTb+d*IFG$RJ2x=rsg@d6$A3=yPf}@7)Zx<0bz94DBa3K z{V&>OGrR13xemG4A^5PbZIFSUTXi-T&te|4mq=rp1AzD<>e?YX0BN2YW-EU@Lfle8 zie1@^Q@U}#S_z$TB~UvV=&So?%Wa3tZ7<{4daH=SW7X#Q;}y=*Nx;f*3AO9F^>Xf^ z=E-Sq|DhTt>jY34txb@$Wy#9TFHz(OWQ*$pO(Rm-Cn7Qz8e&}_(^BuC=W=7w@z#~* zv)`W2%V{x{yqw`mAs*fRoCB4Yz5R2_`n3Jrh?18V?w{lMtMXa<=cai)d;c6AQ~u!o zIhNO8jr->|@qB%;e{M7P9YJb=;=X1h3=40H`Dcq^mu8CjBa5l$`ijMDuBExpVr=ao zl>DH@*vdnQ`IyD%{N`BuCoD!sVaJ%STZ~Tjjxk@d7*6X*F`u@WwhkDA#43HHH*1S=dA_MAZ&Vu0(R(UMK_S= z9xnbeu6psIZ^D@Pi3I>S^AdE9nw75)JFQE0hKhHvUZdTNRucsf=-a3>Shjh!$2EB? z?|oE#on98o?DC2`SY}IP{Of7`>D?eU^rC$f+IMA7E51B)Y4$W>0Mvi`xP}&9W1&i{ zp?c|4Y}pctSz-2Z8xxY%cHX4g&a>LilRG1IlMDc?455k2;ij5>c(U(%(Y^?WYoINm zS2J1zy$oju&rk}G26`Q(yR&b1p@lk+x8^fj4YCA=T?l~gVd_l8(^%2Uo-=f{=^F9>W-4+1%nLBQ6r)QG@{tt3I+ z4iu{KCup@VUX`dPVVwjNyjM$=VURXK@UJ1SI(~s68!={+pHca}tpP=8?e%fSo-+!h z{&$=gh3)03ny~#CJW0&qQ9bGBuj$Dse#CgyqdKObQ$EyLjKcQG>h(nRdVlqLUwT!R z6^fCtZBK;ldlg35zE4kt?c;iOFUjxMQ^NKq^@6Z{LQe_X59kG9`=p+K+J>IlrfMUX+`o^NPdBrri8 zJet&w2yeL`M`l7i*9f_eE-!!O)hn5+Krx>_<+_#_NnOyM->-ysiVgD!&qrWXR+pf9 zCv25_+nF)?g&JWWOpe+GjXOj^6dBE0@tt};5or>h%@GB7q8!OWm_R{-tPAhzcIkAl ztqbo~W~UO~KNf`dPFV@>AFG7-k453Vr+xZSdGPuvy{fn&yfHw}Lzc(QpC%=z^W;4gRBflHPA-^-o zg8XhV$nV4i`Q2iW--!wGyTu^C6BFcji$Q)TCdls=gZxfRkl!r^`JI>`zgrCQJ263i zw;1GiVuJi`G05-41o_=!kl%@k@;i1HhJ*AQ8yNCs;r3O$OJx+L! zb2(xX=dJXor`)@oM<;RK##}5qee81BG`tTf>wL{r=O=L<%d|c$Pf48rmiV6Uc(RG_ z#vQhf7pUQ=#p`853F7;g?sgd~p5YL7D;TEEQ&L*`*7uWOh1oqLk z%;dQgf%tk~^}3Q?^$`<5E)nth^b6%ZznuADo24y)l&;VBXRJ5q7rD56^=pwda#`cu zjZd<5CW+E=BWQ)B=HJ=K`HL(g?(hbIk6Pi zvAmbAD8C?A!`9(`>tzD!p;qy;Jz`}m&da@v#e=fm@zm;dUM?udKayiO{UersA*AQ& z>9;BUqhr!PX6adQvhsO)de#YWa~PBU1`&$X4NK3{(?4Rit*>+=#h*lBO-_XmV1E?F zpWwNWKQLt!fB#gX`1__3nXgo@$Ew#m(yJ)`R*KPJxg}8k%`K;@o4KR4BCDI#kurQr ziL~Du@!v{;S|T&W(h6f~36gzA`)JDx_AHm=H(Ily7cecop~Xe-HEmP2Su04NT;IIC1)hEE0lt%UNOF6tc)e^`PX?B3GD z?mhhoyN~G;ySMbPdryDTbf0_kWjJTZArh|N{i-E{4ORf zrT!49xsyd-ynD0{z4nU=-;{Ewm zsCxEp(Z$2LmPxkF=ZE_oQ1Emum$dAQX`>w*UG)gD0{?54vWrqaoh@w{WbO1Xk8iE` z!ZTyY*9$x|5Y}6$_4RrUlfZota5uN|@GrxlUe9$l;G+B*Zkq`7Zm?ZUtm(@7(9)`J z4+EW8Rz2g{0Ik{WlR^7R0L@N?=6YtWL!52c)<&CCZ$MiO#p}h?YQ(=fX^p{@754Sa zjG`KJ&4K1U{Au{VdezR<#=Z&~pB%mHm<+vqRx#P^RoK)hSK1IJnS6WLrLjmE>kB89 z8z;0~D_QsVHjVmFZj@hskZBU*)8QPLn@w0G=i(jDzI# z_~8aXnal^hkkjUW8-Qhz-4Zyk19y?1|YWC5%VYC*O z*5+Gh%7OirXVrn-OGgcw;K2UevCLQ9GCPl`iefEW-_Ok2ys6i?b-m8QU;RBZnCokQ z$m6$QxSv6_osl|&m-&ozGQ7@lp}aKvMLpY>W^d6GKbAM^Idy4%piCmh!zLjL-nO)Sl zCC^%jN920F<=UqrEZ-ZE>~63UQ}E^bi1l}|Y!`3l^K$k1*Rfn)tDHBq2E;D#4Too* z*V+LBYzjQiIjR(WAUS&$g}QSipf;;i_|RBx2atUIC1;Tse(ogOxN8uz$m6RO+y`z&sC18F_73pLbe-*#oW&mMA=zJ=eQyk_DsCUs#b?$V_C^oc)iebS;KS@-R*!73iNe{p z;x4CFDtCJe0n`0WYP~JTQB3pzRQFokHWkQ1p$gP$=3tW^*`VtM&H^p2w*qrkCG~mW zEyi7$I)l#&^y3y)puJgvd@Cr4$Lzq)gvbn8#*e+LrvU5y{va zn8anq7Q65qAd=oI{?ObAuBK>$FQjNoN>4A46hoYR%KDr7!~ZzXT@z$@BOrD30>s2BP|KF}B4tO4>L-fYCQ|A{wLG>N zMcoh8dapyStZb{V_JZm@mnJ)<0g5b7Y)wh@q$4=hVHE|@Tb{|gXI4o&>Tp9i)(7FB zbk~ig;>*MeRfS{?*pqf#^d7*u;ia5X}|$O&+tk{c;P+krgy8hKh1 zoi@$A6xwv6^oE78Lv?*diBWkREMeI6t&M7>5hc$wY&Q9@IrpgC>3T2+Ca~u8=wi{O zJSls;frVKf466t%)FV*o4t=WE6Xe)vM?O`o5`e~-ja&2Fwx{C zY%liHv#8>~%AHfAk4x?JgDLSHe0PIj&mX5c2&aAgO&)||owP%wwbKXT0lA7?#2A@o zz-bUNi5rVMU~#O0lis*{9EHZVWesLj!Ars!IWTb2iDqoL%{m`+kYYwWyY2{uACP&H7DW~M{{S$iKN7OpoX zhW9R;gs&q&uTBw6KCaFw0@oqE`|2xQ8p}J3!-V0ioiakJO*1yXFe^9#`}|@c*u)~{ zioKIwo8_nY7p4>^AQ1xnCh&@P!?~2|-LqzO+-$KPbuYJ-c85U`}8Gq}&)^Uy5sX`QozW8C)+L1q}P6?cslbc0Z8Vy4=0RPF*{NMTfg zcwzmlGT2BnY0wssgj>mT2x)kfNSq><%a#VyUI~_aC13hXY2x`c-6$%Xl!&N_^^(Gc|F;wEVS>Mq`$7{Ds1?4u*n@HDAqpfrL35^}kXMo1>L zAyhJ)6ZcZb3FX8hY2=zMqo+!Qe}18(s$mDLVSBr>flHB!v=AG%R+rVlgP3x8zj_%p z#Op(9ZX}r@#4i9C66lOZRR!H1gRU>=La~$;TkT}J79~uX)pw*_l(V4@O90dwte#Bm zn$(T*^*yByD?kRkX+|?jg^_KB5gT7>nCLD3X#lP|#A_7exQm_L7~-?p?0SYc17X|{ zXOOLm*C7~eAQ%`!A4c&S_zU~1#}ZkiGa``{Z|xanry)zKNZA{p0CA40(i#OcSW2RR z8l;JANEzvN>}WMeq17}70WU(jQJkhqH-ghdrnP}P8K*3#h)813tryav(OZp;+K0*L zN%U6h0WyvmgS8&8<%$tNYxNBc1zIJCHXIWEv=vu>k^kI@&lJI2MlhC_WdLDS-{uWA z5i>FC6h4Vp5?swp(uv1UwrrZWe7H`Sq%5tH$zJ*bKPu?`xwZ;s#Ru2~o$pgD+s7o$ znlwFI{E}}}N_jfP^$>Pg`&a#lo50j@sY$Qf;IcW=lEj7X?osPtJh_)jv9q<7s3Mft z{o2!K>qbDmBhkqan0Du42(;a~7y@z1G(#Y}bIlNlC~by7ly@@(B81wp6>PILgP(20 z#o#wBVdM3Bk{=(#X&C}vr}9umq9G9Jcf=6*+E!wF>;z4QKytk{7y?Z*CZDGDWh*fm z0;|3dMM={#)%mjGxMSW_E4UAe z&R8>`BtAHkx~nn+;t@As`5>49>1Gm0xl!D{C1ayRMgxS2>FVgyG6Q%g_ide|OF>}i+;*B+2FJ{Bhr$Y2r_nI)4Tbh8V~ zhN+Dhml!0*?qm|2k z8F*`$1c4Q!{pp$n0|$a*$|NXW=O#fL*U=aV5=`76@68wJQ-+5Mt)Elrnn!S2V~(N=LMuH3=y=S3js+u}jZifEEwDADbHo^%KX z+5N_TkWygc{VD*2oTkO5LXhEWih&?UF^V$36ojkMJhT+fp(Aehn?~s(`-_TShI$S} zyI(3Wwv0wr=8iEfGfmZVNtu?pBSJE%4WR+UIWerIa!fM;ucj);@?xJ1wQMhKLe!p? zK!q78v}>QWYfm)$jkGKF|D+zPK?e%VIO1j0@U9Q3wG*K00~p3_tx?pVTQKOhnc2^a zrL5R!r_!|u!Oean?b>L6VM_5bY7JILrgly0MVU4{C&?q|>*+5Rdt^tLmK~w$ufi~r z$>ug<_FHR&*8p(bHO+p3YTfJ?iD_c9-0YV+C5{6|@T%ir2nHJm(RdWGGrnVmMc50+ zqsRj171xNY(HW7*ikp+!FZDr$bORJXqiU30qX2yvrGOfwiEL_|ZEWWoq;B>*ZJee` zhmgH0q=`(|g;O{Cjo@^x-X9vh)!3+gn2a9GeqLj(2gta35183+1khT2LqmZ&PTTA! z;q)w+{k||__WQH(W#Yf_S zyxo6pO;yIqu<&e_1q8RS@~kakgO-15^Ub#Bu`|myWzE}Wt-RD`F5k$lojhSncY4z< zFptxQF|7g*T5XxKxOt;xU+`zRT+6|EsZD1c+jKTD2^-fswsCDzisENzrnZi0o0B`( z7izhj3}`{tU9Gd;K7^w0o74f|rTB&302^~Gc3YLyP2I9j^RfFKV?S_$!h|pE`ke5E zeRLDPfcObt=$r{(-o%&5?VDXH-q~p1s!4x+{Yl@o{-p0-f6`mmpY%QJPkLJ;>6sia zz7tmC#ox3=(%&>*{B7KL(U&#GOEby1@zO|fTI1!nH!@z{*udr*yzMPk^13fV{M{iy zR@?ijv}xF`#tnXdsL=nV8p&{yRyEAo2m966#0{0$8pZE2tU=)ggMr7S3m!k-StkhZ z-v9^?y!Nbs@WBm$aPR9P2p2mQXR=&~-ZHG!;RUm{p`%zg7Cy8A5N^NmtblO$5C}iw zw7?=~TBQsweFbJ@pE02k);44h;m@qk^7Z45ICHJlN@L5-N?A9Qh^0B5eIkc)7CeJD zd0*BVTTsGoV{51K(qh4K*1Xym^twQaxvvmp-D-%Xxm%m7nYP&!Y;&Z|<2Xo#sj|B- zQMm2FR%+_kgij{+h})8@WwPebEZi>@#^8t4kafQ&p(WSw5WH4^fo;v!0&Dl}^;O~o zoGxLco`MHOS|jZZj2gJJEGzOMGf(7%d2)bEtw4khu#7FkJwDlzWh`K&*c*p~6V29R zNg?urMu2&%T*%D8*S1HOO%q}HHZ5dV4GIg{>T2tNK}(OGt#^_l9uRiv;B5Ui=KN6wA4L4Do$SIN-&n)hxPXq*X5)}VPoY!y1 zqLo1o`pLFSe@?3@3r$l?g3y;*5}M$PCho zALn1YMtkB35Us_t2B0yA`-Kg_4?=bja7CZrnRrp6_g?wfPp|mtyDyjw7gR6`mw_bu zfHX(P!Uq%D8D5E=6SEZGbKb*7Bw9Fz_vm0<@dsb0XYkH*fWfl7D&}Yt=UkNEbtP}P z%#X{AS}{7i_rPwbH93b8gbW?haXUmIC8 z_ejHC2B5DT^!7eOfqpvsWrE}aZ1tf{x!lYFLEA`USKE8@;xl&cDadlPVR`YMJCIN` zramwnnSFgipvk&xJDedB3c9TmVW+9-jvt+}ZOx@ZHJ4sib8S6JcX}f~6vZb*Zw5QT zZ4f?>aD=g+U|io(c$wOu%?ON#OY)0(u%4=IhM;AS*7aryGzPNx>HF3X>gs3DXm8^(-#Sx}%qyI8>Pzbx?Sj)A9cY9d(JCDUHEUhS`2hV*(`ffXesS27df9*m zYIh^dje#f6kEu`wk_g~iIVw(KBX}AzxCLSmT1Z1r1td71S0KoDfm$5Pdy$*G15~#K z_Sia}3H@K*WFQGLcR?`%pu>y5z>mXatY50`QchGSVHbF}I{k8ga`7>yPm^?}s;yGIOzS=WUajpv+yLmk^nl;N(e%q|HfZ za#G~(x3ue}et+UZphws?N{m9MlchKs-@s4(nzcG#7y3|4Y%^I>Nk*~7o^BhD&Hz_4 z1n6|By5)4Wv^qPfp7xEcO3qGl1Mo{=fX;)?61PY))I>-;xO>T&iW3rCt5PPQA8FJ< z?$!QCBN?bYh?!!_rpy?-8`U+xx59JNk}=dDA8Z0YJV-~?QJZvay3l~itPOi=gJA(k zVKIFNc)pGpjTyyVusnTtb3Ut3b~*3-gVP)y^WbIheu> z2X%%Z#gi6Um+=mo*hXdDY0#S>^#o82?sOZZnkO|id~OYDINM$L`Qa`+Aezwu&h&kf zgXF?!G-GlQv!PQ0(<@)Z^!e!&cWfERJw}w!pX#1QLBH83=m*n)s5C0Enx3RaZofk? z=yl7LyY6vWsQAYQ$FFiXh7;p02uT`KHk&dA)gB*H7Rb6)?y+@$-Rr(=ZKOh(itDp#qk*^m3>98Fxx(_!Uyn9n zB#u|lQIgP|TKeMAtkJS2Nkdx6-Q4A%BSM&E#IIM3yTfH5t_1J5Ms#$G;L?9*PtXAmjh6;VMr~T{@6|DyE>7;$p zC_(kghu>$Hc9++`c_rhB*&8^<0LdTuA$~EM(a&sg)0PWjZ26wI#PqB4fME`@=7_)k zJ!fjf-}}n-aG0CUSbeXD?XEhghS|kx9eu8){ln96C^=JjI2{W2MhN;gAqWThDwah@Z9=Ix!k8iukx?gBJf_02olFNV8JJ@sM_l|$xhX7Bu%RKspg3n76ncCZnq&wQ%)oQsV$0Vv; zc9Wo#UJGG7Rb<~EJN>cXk6r%QqsOJ$#r}AvKkP^=AqWs(Sfc=B8R3}Nec;$2c&s#4pUTv>P(nn`L4g8boyaWja}v6qhl~I`Nc`?r*iyC}OA^ddKKpUKxuH zh3K0?T>p|SA_mB7d-rCAvz-izDv#21?A#nO3R8Iu=!-H&WO0z7(7MykuHI>7>ww)@ z@TJ)$G~&l9h*A4ifm->o{#!BBTPtL#BytHw4qtR;OG^<$q7?- zNgeRO3IWTI&iDd{i|{`yE|+LeOd+PHgQIN-7^?}E>Zhm98B%^VJxI}&4Zr)+!DXz?rC+6f0zEXvqOz}PG*7x2kq*n z>$XouTkDh2^}jJR88OdOLYj;&)X5J%A=e95oK1UF?-jTdacOp;O$isqDZxynS@#!b z;)JR>A+_N}-i8-?8?IK>FB)WmTI}@Xdkr=dPoN&+t`?IHv(S&*sIZjwsrW64F(DnK z65i~a5u36CoMte~8_@B>`4&lAJ~!VvjE?6k|ML?%JR^XtQUU2fl?~YPx|bd-XACIK z9S*WSs!-um-%n;E37DiU0jpAuS2ZR9&VcHbw+|u5`<6oCDx?mw#zVvHkqATC2N0hU z5>(!*NI>9W>Qbo=bHKAVDbj}}QvJp6s3TS>|DCrF(VX?|zBS6XL{|Qtj$W9gUDy#2+^IKc1P-x9T9Szr4Hu>>DP|mk z?PEl+o{^I@v-8E)ef1ol!g>Qui>96D#1q`ivhJ&bm=EnFjy^Ig83_S8M80*1qa($J zj;!H-h-1-Mau($s@C?XWG-csq9u8#g)M9nm=V~rUw3H^l8n++8vGHBA)wdG~Q(do) z;Tk_rM5;=aXqcbJ1YYh?FH}`nFL)8D7u4_y_&{IGwZk*(+p7V*w%3cDoT^fvsW*IK z=$#;8>s4ParmsBOhO%B2MtSh$3YfELm%v$v=L7w@tdwoDXpljlI3G! z6YLd;jzSxhI}k zLHsT}ix|`kJdnq9+Ka8ivdRQE^Oo-dNFZBKVVo;#VkCV zS-eb3O^JoTjJXMKwOdA1lB@B&p&+8-+F4!-SvAsmF{fObeV2md<9=l;NpasvBZeem zohhIw1kd(9hk%oa={H?2WOb15;`C;8W(ll11C~BYO?m&EB~8MxO4yw}6U3-BqQ~#_ zN{GF<78{|JjbhGBNchPeeBPXINz+KgFg2H>x7x{`TanL!7=#*G?asb4lqIClO}oTb z40=pcyOe8p_FXE%aq6&3)>ay)G>}P=QvDTYlo#lo0E%i1s14|zR>3eb<&5UY^vz&a zlzyB95|%yymK5ESnn54RX@g*anqigz2;Z6?pbfyZx@`x}u^ZZAHC3I_A72UdjPmD| zNEHdB=!gx38-KiBV1&f|Gmxk_2n5LP_(m7%~ z*p&{pb(l3Hn!BMjqICkU*)Qz~F}7!F6DV3{)R}|&Yy@oI5Ee9Zc|zOm+cBM)?W1JM zP?;%!IvBG0p?r#J>dnN+r%-zH^zN(+VFvx#Oi0tNBi>oHz|YYUuYzu@1tTtyD2Gl{ zHPGE3DvS&v+134yC*(o*8|b=R-a#kIrw9Akgqm+r+h;gQcnDC-h6UcG8g?J6WQg@a z?UW|9UUdVJ2v~(TIcWt|(d49LA!{>>m+5@0;-oR0I4OQ_ams3NQmYH0yYHNIOMtA- zNsY~M?P1`J_V!F6Q8t|h61O^cG;|5c^n&b!O4DSFUSyLkZi)OYsKUxs=WpBOND%nj z7H}4Lf+H*NH~awwScAWTG`MzPX*Rh>{$?^m;BVua1B(lN?~PI4+o-eNe^*U-kt2re zh^x}GiKf9jG+21pU{S_{~&)Xt;KL*yJAshRO|7BYrgscA^DNmDeUI4+cp>0l|g{fyq&Gn?wk^ zCe+gfImA9ic|u?QE!$;=K{b(1bL@zx#ITS8rgdt75zcMZr0@h1PGAHMRD-f&Puu+A ztS!O%lcz@GYWt~Bc&hg&l6ugB2eo`HL+ga%j^;tyLy}@BwKRYAiu>n+sTbj+ReT*~ z2!}IB?s*FH#NUa@+DzP1?vtBGwJMto0hlE;KVuJ&VH10R*(!<^yR-q}vP1r)Zm&Q8 zufXNaxX{S|-ILl`{8>7%;QLaVF)*s}xKD*$2$PGeT&&hC?hjINf7dcMGG9X;U%C1N zbA*-~gs0h3qnsF8JL^59*g?yXIN}p3c^3H%A;-qLetL_XEo(14rMnAlig&w&%R}Z2 zPq`9f`PS(ce=$cL;&YG-{U>T58@-Q-iL`HqnQ>v#)qmyCZyTcmMpNZgtE@{mrSlyEDu8l{e$O2(IU6 z<`jD1uRN4@_LV37{Q`;j5Aps(*FB5*OtC+-ynOxg^72Zi2xaMandi!D50)ox`-|JA zUaIp!IN+8KMk?h>e8aI|FjKC)p~X=ipU$qp1M@!RR*#qWD$&X#_dvE;`6jtk#=xxv zr0TGEplG}WvNmk5Tp=Wn@H_RiIz{*8?G|KAiOC(aG$C+b$Z%Jc!f09v?+@SZwQs78 z!a}~|_RZp2Okne^ayh>ouhDXrS3$Wr&y{SrIh1=br}jDY8UB2TBFbCHSw2k5K(WF{ z32QKAhW9=@A*sfTC^5Ttumg3TEF{X0FndY^WZ6z~3zoOs%N%)Ov$F{W^`;q{* zn>1z@#l;v~6vq!O)ZD<~F77;UZSM3)+9_`gfNpvL%lOzf1yDafT$1uIFoJ}oLkGjl z!D|4HB2(7^yY;CcWa>g0X+W6&U#x=iB{7081t+n-^R5x=AJ|WaWa@4%)Knv^jRT zH9u7)WU|reJM7j#Pq=xy$n*Kr1PR^EM`w#SN?ssGx8bVCg<8CX%{a~jUy zbqX^0;2al}7xKz3;~BE+Ua0R8wvYV8d~4~5C?E1ayj1>Ai`{wce5z2|R%d1dZMxEf zj9K{|^mOaU62BMj-+p+IMKnirVrY>av5jy3^n4E2%D`%yGIX$1>IDRTX3DJm&Ld^# z;3CZyuG;&zlVo~3HDy3VC$vF=vP~UwNTwJQo6?x*&oU~6RUacwdKjpe)z{!!BAt`Q zJm6hH!94nz_ct2rc7P>KG2fQ28t+ak?1;7cr%Vut!xS6`L+LiU(2aWYSuou;=>jSe zq0<})T}MyWx?42q9jz94&pTaUv6`3K+3r@uvKp$e4~<>ul+whutv4mvad5fH zX$zFxS&4IV(>{WP! z2<}Eso6>h@8I(TP(a`MAP`0M$k6%(|LcYvDMd2=Qi&{o%$E*A6Al=p(i&u{D5uo&It?dI;iC;9p7hg8e7Zna!;n-pTs}7iR{`HsWaN?Q z^gobvIjaUPM@g6hxn)N)k%nJD10032MA3TCN`c#Qs0sC3S1ANO;TO6^kBPZ!*or6v zG+FVp@|f4qZ$a%AFo`9ICP`qFh?qK@;%$5w(&nc?8{;l^HNHA=Vxe<0gJrvzpJp4I z7mXFWEU1ay%Jm5|NqnWGz&Ku%=6;|wmeB^!|Ms#V_mV77LAiK%I*w6Ux=8wL4>#MSfXKJj{OJ5X$Cu7?xFvK<1Jr zU7}9qx?$=MLJwp@9OBP-AjCkOn@L`wwwV9~#1e#qeunN@>pNh9sM~=U#0=seJwvmB zLZlzap+$32do-6-L}Vnxlqs%Z`QY!2;KVoJ##tAVhlm9m)XWI=#*D?jS{_+&8$`7O zqI6b`5Vfe0AZCt)(bCYAlqr446%ujs$oczpq{as6U9|6Ll!lqfGb-R2CHtnCbtEHj z!wprK#0RWI9XLk&pd0b&&x3&LY zhvdi^ZRo9@)FeVUxQQQ{+gZw`yC0RW#k^gwTz zz`Tj6pY-7U6=r=&eO3_wgy3D&s#FLRhu9Aqa3qleVGA0rKrj=T0%6u%DPPEAQDu<5 zh~m{%s)dkf>_Wj~a<0gsRYoy4cQF?M#KhbIh_Sr5jN_oMMko9-Hls+L0Tc?DsWgy< zDc<@9rlwr85yjvas!xJO>Wt_VzKxhnZHURai^&idv@ysSl_()Am)U? zODeGK0`WY;Axe!=gw;(2Rds5$Y8Ahm#7wy%UCb15HZfCy?mSB5UOuZf%%7zJzkRWM zj&h)=LBVLsQ{{J0WPdjQ84EDgTq10FoQdWcoZG?ZpE71;fmw?uMoaj?jxjWMr5TD; zJ0U0#)hexAoqHq^5>Bo`IwdK?r0!0jHv`vBI}i`1*XSH6OHOfMCn~M2A&Se4;<8F* zWg4-LwNoaqT(esMw1(QiY7Q>6ERy-n;d*1q8Nc3XR)A@n1EOp z$aBf3GtOKYV-4o2`4?_7< zCBj&x0}9d7BIr1Hs|Hg13~YIMo`{Jts5Vy`8F~ifA>LsWt|^KIeHm$B9!B%p4)6LK zagk?-aiG~U7;lEhfhJ6>Kh-#(ONPgRO$!A%7z7w*^hk8XiR8Gv80m0BrOcd@VAvQDe}N4=T4CBJnYEwx1*QkvGx={JTJhQ@rh zIGEx)Tv3{XEW=V z6=49w2<_DH*tFEW0Pu@3buoabNO7` z05Cb;BJJ(GN(a&m<1}mqH*}!Uf*Fc7PTYOrovo}KpA9JSauK|1&)Bzpv}h3)$+?8wDWzir}jJn z(~po=TTnc6HPq(Ps#etN`jHk0Bq@oZFn6U2C8G-ss!)#K^8q;qXifCAS;b@%Fg-Z@*ji*M94ejL5duLZ*KEhx#|X zdpkB|b2V{Eud}o}qaVd=gaj;|cW=1>d~}b^PFQuSc43Fkrh4BDB?q;y^JNe+_%*alw>%LLQ`{@Pmk94a*k z^(vYvAuI=z6!V;VTQfq?^oBWWSWgW_)5?6GT4CU;DMJ;B4LJB-p6t%Rq)N%g%oG$& z(GoYeYQc=9VsE*ng-DZB&NPequXU0k8O4gzc?WQnj;2zH8Aj${V3Qjvc`Oa2p0HSF z7A?}6q9s|PSC=J_6en4cHbsobtLJA#vh!ihBXr!n&*2yp>| z#<>mE8YLSlX{2`r8!BN@S(v5tP1Fkw26HyjtCkvq0o6qZ;}-}H8U%E!^E$}HX1Qql zw6W>MOcGr++?t|mw6dpCLG>w!u2yhEbRAPLv}R2Z;1XQ}=|zh@D3ItnN@%uIVZ6mY z=t>~4feLYFikl$1u0eUm-z0;GNjZOup^EZ4P+snOQ~XH3!ru@|5`U{vUIyg>(J18^ ze_NCC)-SrsdOt*Y)Elh#!;}YA#!ji|s!jnxbQR&zYl$kyWs^SQ6V(K}zC>3k!b5g_ z7hM~6eW*z?8xL8RG-0ViLMFPxvyyRXRkOZjO~$2aVySt`w1Fv^^|2Fce3)533a(5# znmQPE4vatp6JxFVB7_mS6}vuFxZDZ{mR)~>+^Wi{sH#t`R<+be(VF{JJJ}UUFYyp$ zWQh3bc0bUr-B2dBX^S5wG~%1p5_pQ$|5vigN<;7tFu{@)b8L70LC)-*GZh%9pk1bR zm|ID{r6HM9832*u+ClJan@b(*uN-NNU$vHuIN22oi%&9C);Hb+B<6*NvoA{w8f(+0 z%p#_dMujdNG`oymAqC>jyOMQB;KBN`#3-8%QmnNflt}C%rPdTQ`iU0Dh30}_sw5bz zSShhsL{;sBLiZJyaE z-OM>uuUpBAPS$-c`RLK-&@YG2Gq@QpZAq9UJYbLF$Uc^n@N=M|o88UA=xjTPiOI?;rN}eTq-39_=ILh4QVOJyNcG@Wa{S?kp>(4j)PZ zKFu7Irq@p?uU~&06t%B7 z#L=UKTE&;qCob>)?+Sdwo zA2jLba^4?PHP_>+d&NQ75nEmGnGNUzZz&tyVP&bM%b%&WGzLiGEoJ8JcF(5sZoS+KI(V2n+ii$b~mZ{qCYc7cELJ%E2v3lE)N;YAE>Yw^fjH{AYHKI+~@UYr8u@&jI+o+|FKkRmVpW>*G1 z#h>H2Mg1U<3l-Dzo1TcAVz0h0t?>k%STE_4@ zF3Ym4o8`~eMNpc{ZHM_;{sx0<_V6KIVGRoD%aKEeBrs+3o667r`q5ke^M0@_twgML zy3CK5`=}W%fq`=HAdlt9Yt_r)i^?G<%iNTjA7)YsInnsml@pm;Ij}q&VrJ1BwGXtm z$D@abtAjV#48pXIDwkEsLl7X2FznAfJin!nd!Z0_9@w&uU%TebIH1ekao+mV;}y%o zr<~H-fZJKrfFqz8h_ia{*<$@|@OArJ93a-T44`#%Mr`Q(6ygCEAkCN36W8oT(lauc zpRYn66e3vx5`eh@xP4&m3E)fe5VCWBW(n+M2j*Myyq)T^WeLw)_fs-ahcMo_-R}RW zA(DwDKl&T@WS47dIeL3|xs`EbF)Q|h=qrV|+kI_&^Dtp5T;9u3)ilQ@KHtmH(iSmO zWaVlPKUI z!?Q7ED{`r;VzBmMAR}S|t;{)(3}hUD-{O&C6;+GQ^T_iWk=&`FGU1}N zluz-XA=vM4s=F=QkpCK@nw!<&*%@w|V5ZHBx@NM}B)F@@WH%ExE{afYXf= zgHx7KSEu}bc^ixWKvH@WJwQ2jfC}}}5~wVEytpzP$Gv7 z*sD#+nyQttPl7{ifROZgyghm+3fv$o{s}D$b&z3|yPGu{U5ZAFj*+O-A+0>z%pn_P zJVkO*P>e)V3MpBziIK2kMIr*AP+O$2WBNz!viEXZahI@Z>^XiAt4<$IfIj*JE>enf zmsxrHTUJ!AB$C?|!%n6u<_^WM`>Kk$Q!(v&%rV7u>M?gIW~v^eYIST&R%)8Cs_8@t zGxi=qHIQN(lrny>T=By;b#B-TW2e)AfoHU5<>V$^5Oi!?d`8=x-sCPzxCmi&t2S}> z+ueW6kq<>b#YdPO@Cr7{rMq8>>=BqD{MpRyTGAGc@>ML7!#ELm)RC=}kKc_{tV+Pvc15vc0l5c#@kE~H zP3rpU=k9@UwwqIuj5xVT*)|_zt`={4g{Y!+LCy>f1z{PN8N{c>mHBp={V=gK8ptph zVO1dNanVo@{5t6IPc+iOv zs6%3%TBTxbXo(CLybRB@L#6hcd7>%F8<>Qk12&~$6Ka>!hYwMM0Xc0*3$V(*4t^0U zrNM-1$m*gBYMCn4T)%=wx{PosQt=Ypvhf{i#dTeBBeCoK72U7R)@@{>(*cXwwLfs{ zfAUKK8=_=MT{bm<+P3*UI+zM+oYoL2G`8r67IeYJI}^#|ZoiA+C`Xq%g6VJ@0f^4D zWPVz^W6?IJ7ikkmi9<$ecfg20rir0e>nv?@;rfg%bYu(Zxy>{MG-a#nzMi6w4qPC0 z#&oSSB(n*5h?tTc*_T{sV6lTyIUJvo6iJ1_P1|u;s1&k2b$`vo?ZvLl;mXbr;MvNc z;4vSj$WtV?mfz6c2#IYHS4|L}cCLZ5Yv3E{J7mL(HHDfjk6l3$m*Q3W-iU1}Ij*;=%QfRWd5Ye}Q6127Cxfv7}f`U;Td6#{{Savw7R z(Kg9gfyfLWhIx#uV2W`^y@vLP1VJ{SM-4b_FU#D6Fi@irhIgH|Fn|~o%}9+?hNCI5 zgFr$WhIOt$j~a5UQu)0FRv^N;;APGVC{TDsaN+N|{w$z~6HFT?VB5nFixOu6TG5p8 z95Ejwz*!}xMzM@Z3Bz~e3{HljfuYO2of;};{uGlCJfia{#t_ikh8d6QPpj%W{=^C( zkjA(amukbMY9)#fMAWfsH(W!&+#+rZ&o(BWKTm9t(&sxH;nQ~M;Y2lHs-PfWJ4I#Ar)wv${Q@0 zN%lG>guCUiR`rOOOO-=~n0GZ%<#RNBa4?aEU8|hNc&$)qV7a`H&np;)Dff={RkmVM z&n2GD&FDwUla?!%kqRxX)$$6$cKY~p)D!jWpor{GJyJe0HhU_)DzAYYXbV$RxBK1V z02s*_Gto%)|Ficd@O4(z-v4ukB%v+=|jCbi@LMR>d)-X-YFR zX_It7+Y&}WQBhG5Q3|L9Er^Q3Rk#$KPytc#iuXFeE7yxxR8+h#UeW%)zqOy|oRc)^ z0C)KOKcDxsE6=p|+H0@9_S$Rjz4qQ-VUUb343cGb6s-y`dqBNIA~66`=g|uKGS3;B zSG&Q>#=P~+bvuUxW8ob)wmygknez~M5nTPG*)AI4(5*>@1zauH1RIW_P?LR`+v0JJ z15nZg-E+UiD&C0{YU4fkMeoBq-qQ)vr!b*B6%VBeC1dqxqFN}Ao`mJXuS=peC_=s> zBwU!V(S?4t1vE=yUtl4Qubbe>fS4 zz5u=^Twf@bS&L=NSR9#SEY38d>VnGv#(VH88Z`6;n|aBtm%D6mJbj43HX;yK8<%DZ zOyL|-FQa)Aw)viHgM7y`n-h|8anY!@Px&MtFEVHEI0`Y+6{6EM)>W)JcGM-HZZQSU zw9qbD2MIcQ&LB&e=pdA+a`dP5d?3Y!T(iGck4wJjC`H;A=~sG*i7aD!*KJviIothu4T%;`Sh!KoGN5}HX2I&AWr4aa3Q0@ASi7j%WX+W_5v`+@X>PKYF`gtz zPiW|pT-*6>5LH^e6q>@8r(i&n9Iym~9*2!GC%Ys-Nzh^uG5Y^nSq_Y*r+I_9@Z=hF2X?X+F`{U^2kbW|oXe#&qRFljmH}BcuRb zI^CMVkql*}0)Qd0%%j5vri|C2Ck|sGM9SOzyWLOM?ka3xsr=BpGUr5esss^sVH`SE zvvV6VmxwRU{1srW^u2m)Jm$YhdrV}px? z3#myu8{BZ|9xXx2qHh&NWz3*Fn8Hsss8AG(DRJ2EC*>Z=*r#5FOvA_|KS&0qc9+$1 zalr5-u;%ntLV=)5RyD+BT@_G2(>|)Jcu5kVYthrl^Hxy8fKRz`x4R8ZmMbGzL9WQG00A;r3$*3ajK%b<*Hl0vbXwl*p4G$TCBA%4&4Vh)9l{7|)R zTLgy|B~hUqrd`&+JvN6HVhB%4M-@pzuO;{TWMa=>HVzO2=nP^sBA4)?!G>pIJ(<(3 zsylrbGc_5HBbihO6$w?c778Rlst``1u?T8&*!6DK4RvvXNttw*g-nIU7c`oFB2T2| zW#3m*a(Fvt0ED65s+0;vlE{8slO$oQnJ76r(QRx;yFt+4H<#~MF@9RUxb&Y~n=uPg zgYVK5_@bTkg8iOmlp%XT_7cm9_F`KswMw+?@txe!uI@mwGWyOwHk`K#qp@1&#aD0{M3K$m`hBQib8zlnP^-DhZU@DQMraG? zbc%M*tD_b`7K_dkA4J$ac!Q=y+W6%syGT)tmF2F}>Qw+Cc$RKSTg8 zaBg5;?=yJ6tk4iBVwb(O2G+Z|&!ELdJ8%L$C;|;a7>aTV{4HidNF^tEXpp>#S`|RZ z5{~kMBM2irPQJE5l?uKj6e4U|lbH=BZgAG5ES&3*G-9| z3je0#Mc$A=*eX%-oMNEnB_PzV^iRL+1?xim( z-};)TCfQR9qF!x4UX?(~}>@*`?i!lV~dvM^a)Y~=Cp6=o78npumh z-#Z5{x|A&l?f2Yim)(yHWin5dh~8srO<<52f)6W)`(t4tCxUy5w|5q9Ro=G}P}e9>U=lmmdl~5$s{K{G-KUSGz#lsiq*ZM9N(0+o(vK+|wW%7eK%!*YI_#CXgDjOHH8})BY^MIeGpEu}i%N&&G~k6<5T+{C zMsmug&7WZ|scbEtG`$QGs%TLjp)7dJQO??;JTnQH!;3AzBmE+v0Np(V=RLgIED3}f&BB-nH#GBrT_d&^j*HJ zFb-N~W3D{I@oB6S@MHOMH#V)A)oIerWv=JQprLknV(>XmBSOyr2P7mU6-?8hzKS^J z+RaMTVS$o-`5DePQznh+T3@PG#CqBHXh~IBbrp37+$hIfy|QwW7t5#ds>`Q>w9QFq z{OWk?T?R~fp<_?-5;+>R+!Q~Rt5?Tb_EFmUsKHdC1Tig5j|EqKpXKS|h47~m;Px3c zV5gOQ*-5Y=jN!{y#|0^kXjWS~m_aLO-Cm-^L{-dDB}O=^kS+%EI)h5pZJh8(%4o9) zi2=Eq;{u10TbQ)dYR*l8K6E5@ziQTrjgV}Fz74yaM{EjmC?jf`x7COX^hBVDxP;@D&j7LCWzJ44mcXiv3M+( z<|~(4Kc?D;1f~7jQo*d1V8;CFPPvyA1v9PuSBbz_uG&u%Un!t&Qhv3vSBXVVCqeimi2CGGsz7# z+0C_7&|21OghTEEi3K(`En$&B*Jx@6d7v|a^y-r^m>UZ90KTz*WQGjAV@tl)*DY0c zOG9pq5|%P4{2h8HvSdKI47F?le;GUd1lnwq>@?)Z$(y)lLAJiSKAX+f7k^c{O+?Sx z`c#>|m+>MUOUCQ#E9*UdS7}uH6(=MXE&jcQUJ! zw;Dv^P%5wLn9_$S(ZfCr&8mjz=~XeW3f1l+VR=dh83Xz}bgHR$pCn z?dvI&y5{7SxjLE~#ym)bb|C?d7LqY|!|MT7ZX@*(PU1?-la|d~LWt=CK{b~)VRd&$<#wQjRNSPkRG?bIG zs-3Up(&`G4X^1N!JvNzuHU(}=$ErdiU&Ejj zSzJMx`l;-PYhWxswy+Uu(tcSN#tYpa^fM!=s`4;~iB+TqB~lG3P`U!;0tzH#e{zdO zE%R%bjs>ZDf4)yMO&66uCYT1}EAy!a>wM~vS;z>DFdo7PgbPhE1y{@iF~}grqP=FQ zH6~&<8>vf3;6*tIE3I`PU!}RyvTO_;O$rZ5P}z=>t5iN^36@)OU^P7{L+^h&N8*_h zrHYnm@86Fd1)q>_p={e;@R)Hi`rBulVw1b!weO$jZ2gliZ|(sm#&3|5D%cPBP%QQ`lJ9_XGgDt_| z^`@-B&-&SQ4MCzPF-~5UCl&Djc%Dd5iJsvK*bI7=>9dS>e5581wR`f}upm5dohpZ_ zeK%~-cuu!6*_WRbJY{?AvR72$c^SGwA*t=Ev!(}S6v@Tm7#bx-jxgUD+>Fc=f@NeR zvFk3)7fN7i1GY!rceS!JUvHJGTmlyfNYGZe_q+`nj?I47EUZl4_LmA32fLizbCbns zf8>$i=F)tb?W5#0xj;wHugC8nV!5a$2geAg1eM4i*pL=q29sZTd+yj~FIPt(wWQLe zwU_#3bK{=irnb!vpJ{moAkgZc1g_paCQjos=D1uHi)G|twvU|jGL-HRz83ogah z<7L`@+5$^SYAna}KU`J&X)MG&M|9J(<(v3LjH+N#XOQlZ^*J8%5;CQ|*s?gVww63V zK3yQQS#69pFe?4@wp=a!qVxb(ERBnY7D_pGJ1tGiw2gKF3NhZQxA?V`uBm0|G#QW~ zM%x*IM4-?zOG{E9oDB$!@OtHNsmw|;Jt_DV^FLr2@9a$CmUjj5t^RlkrsYc+gd(YU zQ4jOMpfEwYo7PX}H!YhC;DD9|24XCC@<9Y*O|ylxI3xv@36tyM`fuK{e6`*#-vW=o zTpywg(p_RDs-I2@h|`<$+E+e*B61iDzU}!=ET?vM2G=lffyHjhiPjK$x(HiAk;s1Q z%8zF`9ehg5%&ySn)Ogll=F*S|_6L7_O1B!dfZe>X0aS?2&JfjBwzA;#fsET~n@VM= zCqKzAS2|1SInX~E&&n|d5C}8L`9XwrWAW*zXp)f-YJq;ruT`&}I9)S6#se_-Vwoi| zQ?v@pDop!5d0JGtqMH{^gFEAwHH7bZlt8hJh-%h+z$)N-}5g>K$jWF*)6tPL$t8c*Sx* zt}{2zqUFaUOWSQ0Mac-i#69hd4GhGfa&tlMrJ1QSDjmuFW&)XNu$qEc!=7;rSq9(K z<`LAW@jmBP$}Yi%LfLp{h@>*VikhchY#5^4&(IQ%7)Z71Z)iT8^7I#U|cX@uQ7@~S8jj3_DG#sF2Ds?Oko7b~dI}Lg2mGO*^Q@7^J`Z40j zoxL~Vpn6yV$r^_b1#4VgAC-=ba&?wjs%4C5KpO@z)ARle?h(GA5!pPU(`{wM>b)*n zn{nzQA>UoW%-}>3wxU6A8Yp|%QzTs5Bl?qMr%x_qh9=IR+?lH;$DuVkhEl5@Zmv{= zsc5d0J8M)+p2(M{Dr5$Q+P#-(t`u<;OqI|=9%T2EVH7oD2>f?bG*v?i=%AEe&no_m zbYR%CmV1PTUjx_P*yu1a2_p~cW~oq+VJld*Pc#p%nxg~cj>)*P21Ai34P#K8tR-Ag zt^K=sNU^blExazeym0VvjummD)uTX>0Hur^~W%vmCg}I zRSJ^@qtVZ-XvkMFx)te(BvQ(=N;;)(2}Q$5dJ+!T2G;MZh0lB`?e}3WC~p}2`m-`W z#?`bjBh@rIip7qBf-B~T9RtK6>i0zjtJ0~bo)>z9(Bx{`5Q-Yf-cX9F9Yty;4yyYv zi6Zy`?}|)lglROsB}~Y;B&B5kYmzKw0xf+cBPtg92IN?UqKf1?Zni{ zz=H|YBsoQBpwxQUwOA=UnBvh&6sLAvGip^y#~(bQn(p*YX=N(aJ6LIj%A}f2jq2op zvrg6CNS&~jffP_PHkw+fa_)wj7Ah61Y3`+~{UxfOraa=K2Fplt{8G~nHZAW|&v0#G zT8JuGiiXnHVMR3Q5jtLUQAa~96;@rwcU+aN3hFz9da7)Mg)I8k_C@in6E1_&S~U%E zsFBhb%YShj5~7A%R;$F|W3VG8%f%^3b3lxS`qDuLQ!lrtruVS4k z7ZX{|{)C(MU_Og{Gnyydge`5obnAs@Bz!U`i>47;wIIn%oJNvdI#5|E$)zo5L6T|f z3X*)bKOITNx{3E8FyZJj)0|zHz2op}kyRvQe=#SSp}*PGTFM`Dp=*R zjQUeU``MS*_@ue-`LQ{1rt9QlGju*(pBS$i z?bDIR3TOhgx0DU{dqQgygd?XoD>iD1vq%5b=#3hyY3Qe;B4$|j4;%Ne0U}?8qhtHQ zXirRd3sq#<8*03f%8gEw1Sm5YlTVhGBgkM)951C9^W&;+2`mk6wf8&qO@CIhRSlh& z95d_(=_3|J6lOgXR?!Z&e!&-2sRV(L+DrrM(?6s>ja^vT89c-mA=&rVO!hLLh!vd# z<(TK37I9Q!g(36*)QNfV%~S%tL2A_DDu?Fsm8=yQ&^zZQ$Z9WnAM)aR@=^40tCKA` zFTTWX59oHfGH!#Q#rma|j9RC5Dhc5Ud1=E{0m8>nA9$#YTEYPuFRNpxk z<93Uy6kd#UTIG3#SEx+B5+_kmlRDhiH-e(=@UJt+RxM9rI-GxsUPg5MVmP|3;9yGg z$y$Jt*kuf?%azvA42AfNX}@6k{c~ZZQct))0jbsnF21Z)ZOF z2Di)#N7Q`6l$oWD)2Y(W!E7BIEN4nBQdr9c$45U#ROm7%>tu6mr<~F(xT92-a+tD_ zo7~0vC;V=@_Pvp33ceobIh+Qi?p4?!8$agYH6C=^`vU_SW$Y#1rOJj*f z2*0bQCKfOJytv0iC8K(ZJ#$$@j#w(I(a^G*GenH{r|6SRYYks^xeWhg&?vj-C}?A} z?+F|2%jP(~;?RjlNh?oJg&qUiF}tkUt-w$*HG6L~UbtMqb8{xuRHvwm>rv-u#^vsT z?_u`F8oK*_j1~VWTz`=5SWu~oj|wWJ0q2#1i9soThdshmGJt?R2O9b2!4N5`G!lUI z8%r!kc=^;Vw;{Z}9*(U%noNhd;4}%`F0li(CTz=a6TlNAetT$Or+3$#Xt%Of3jVlb7h&38N;l0RV=tdqB=F`)q z39lj_^A+wKM=uwL5j^03&jOL)Tfh9nf}`R?RQQI_xIxb020b$E`~_fU*qwg3zbr+5@ z_!`mQDd8(J#q5Lew2F=4`dH>g$Ayg+k4Cr(Ocgd`YDLIY9q-u8qyR#2C4G*vwdQRS zH@?E<@+&TT$qWTG((9)rSt`F`rbv?v9eFX8*49uuziv}A>MAFiS&u2@mM~pCOizUM z7-hx=bgwr>nb^w&6bdcF7=}r@!v&sQNIUXP$Tto7rs~8X=DvL5az8;JO?kTIW|>=K z9=I`JQnq7A*dc%NqMLKl=m%;wbHo*AW2-veumFFXz}LS`SkVyty;ea;C>C72Lw(99 z==lkU>z>V8gu^5t3qma5@Bq(k^`J8b_ETv(!DQVQSh*5$$YJiRukxE6ld%fv*arjI{7AP<1j;>cQfgs z6wk5MDG>rx6^DOe@S!0SxK~w?h^bl1KS9~>GHxmJ(!_*mPOOI8uMj6HtmbH{rr?L4 zx(s)8P-;jTlnAI$augvg11L2jz)PBX_tH=@?!b78L+NVhK`3o|!ZU;-E-hZZODNaC z3>HK;dpJv#=2ILX0b6s2(TKEATnGqqaYV5dsF1VQ!^60>yrmqmH3xL5*OD3IkB*CU z12qXo9Fn`qVi+d1%TK6;FC*KIcUOvY;nzXdFkE(j=6xqkq~tG(IhT3oDzCqh3%z?& z`n*$CJq9JlO7NTAxByPnK#2bNv6@88!?Xw<-Ol^D=5|9*(qpXC?F<7K!`42gM&B$L zd1cFjL5^mYS}^KMMixwLR0~Eejw~2P24%sFhBmBYm_}AZf>^F5GGtn`f9bbnjT|v; znyq|P4kkwxSFy-ls+J1X8$=#Lm8ra{to$buf_ zGcFy6`dm@`Y&CvJ@-<&L-SY-7y7sFKl0#?WB?!a=N5!IIK^}#mPS=z=>pcKXGlnYp z1y<@CXQj%t2)W2t@^W;Q^Z}0za9r)j>NS5ChK?rF^PpxvrH@>HL6K^tZ8E+dn)PJr z0L7|{s8Y*z0)&=OCzg&{^iq>3M>QU$Q7{Fq;i%w}kPWJ>&2upt0}l;4vIwA?7{66H zsBwo{(q*+gWR_wsohOX?4+I3|8pG{DNyNnjoed$A=LHx`zNlBCFQiq998oWJVM>dl z#M+J$l^=q0ONV8RN2{`|%f;$LS{0Zg#>7={Lg}<8^oB}VHOqA?6GN18A~?AVC9nSD z5l7Mv)27E7)nNq#iW7OXZ7xh{kCv=#t}^S-n)QXPNHp!{$Az^>P=6G3tBZ;l)XA2s zJF19?t|c6m+H2*pH*mShu4#Ot=4M>JFZM&qp;XCo3`!M&KMLXqdXd640T^jO{{H>oiVjyOJ-`9qN*8B z3+rk{@S=GR)%%&f;va^3Jp&)w0#Jv;RpGaedXiDc;23EmG8r04M;ML;w9PW`)62BG zIVxXU9=QED!39mYo=%THhYn)ZFqfZdmFZD&M2=e}Idsd_s20qyv(q}-qE=RBOe*6W zX00uzs>h`?+-e?E92cn@h&f8nko7r{RzSIw*j1<~zYhH?=7>q)#1n)%Jz8+Bly~B; z%|{{wK&r-#UlP?8beM%vs!y$1fbvXp8jY&Fh&(0^{Oq=+eQvLZn!A1Po||0*G9I7V z+x^s^U#KIEeXG_%du^?{)=p zBN$u|adix-fs&3K>_olVNn~LprOI;G~itkPmNPD~n3CY{+_j2$32l)>Iy z8rIYYX*3`{LG^ORNe6WrRl!eMZ33(jUyVC(8$W0fU3eQ15RYum-1rh>as<5l7IH|y zEJ1f6#O$LK3yxhyI9EJ=Y+D1^9mfen)Q2>jr>J2G7CSnkx3MZtT$2Jo0kmmtWkPh2%PSuywh?LH796WJnOlxuen}B-h?69$dBD5 zWq`F_ne(_}vw;Df;^FQ#wkOZRJ~k|oBvK4^EDYjZfpYhg%eLez*cL*h;IF_=QjAGk zmmiY{_p`CxUGmG78nBlc(N_V1?6S4+f2 z=J;%{!(g^folI&o1j(S75^+RRZc@Y8GsY%m z-|*nJ!z4zSlJQQuR?M}eYwZ>5FPvJ3CK2RelgCApF-gVEIX7@t{Wo{#CNx4MaMP8Lm#k6He-`UErAAOD=mfkWok-@oU0Iv z&4|S6Q{LJAmcruQgwgn00k_8w;U-bzAulOw*^m6y)>a{7=~cijx4UY+U$3~fb%q2( zRU#@cGGRKU%Qf&}wg{d>u)KS)4#{#9+KghVonwoNxFjxin3-9&R;ff_?%9KK%a6Oc z#6|>bJeVuLs4-p0lO)O6m9#-CP!?#&IcFw!hE^MPiNou734SaQF6P6t|pVEH87{y&_E+W#3X4q&<3mwEREgGEB03ck5ao88B>NXy{ozg{o z&D2)YNJuLWQA5XtOE`C-=&A$JFj>;PFA~w*1?YtpR73=GvZO;wROX0?EIXC&)9Kpt z{d_;Yb0_^XhDF>46v_`<{!ou+da*qBT{Y#Nd^utWz9W%5i#u%bqagw0<|Wfz}o5E#~M3Jo1WOeb72087E#N&%~}6S9Q)5NpXI zk6K8l{Z1&pj17fWhCC!9wMl!Uh!p6Mt))u>G7tsVQOy}0w8e%YAJ0*ZOKM>v_$`JN zyIA4pW$RtM<>Wk0`Q;M4sq*7WmjOcrGVbPioB$WaH+X;zL>478{7WWj(=!SE$?)v{ z*wuYaCcR`?CguVrktbejBLX@UIw_}uWZ7hnUOZcE1-mh;xG}Gn(g4p!0TKauQ2-50 zaABN)>^UaTNkQ8ZAg0Vv8-r7{>51(Ba1PK4ivtyz(&ZGn;9tnZ*hJ`fWJ2riCAuDX z0IWbecbuIH=+L--eiqV^@>o1xp1_R6spC}I7#b?>ULEt)i{_4{%Nm2>PP>{EYQxK` z0g}t3s;P*w@9oQ1<5fiNN2@k4(CUl2{p6@r5tLMvfODdZ1!2`MFr>odVL@3soh~cW z-yy$bI_=quva}c1_k=yg?0r0)PHHC#h^q*GNrB*>JM^cf+BE3_Tnys22?c|Mi##p7 z{}aO=ERVx{jIqL*TI0L`?R%5Fs1(ti@APv-XgGqn$slr$dzH%?vXAuh*eMB$vo4pa z77u>L6cKNOSU(CtXzgCd^t?u_D?av68|hjEoctx(QX+I7ZY(~c}chYNK=*d-ixoMpyVzfQOwn3c>6nMn*G_E;Sb-B|dYLKiN^Z!M)wav z#B0b+`5sH6*~pI#NZg}KE6sSp^UVIjdK@~AJ$rO z;zU6@_IlzekbsM{l&ZhTPpQ5{AZ#RG6;Ae&k&pGXGe2%Mx~h(T&A4;=mU1iZmlehU ze`&MOHWUfR5CH2FGb-qY&uoJYoyuq$4%{OfDB4_)CFD4eptX>jm?=Mo$YbaS69{C- ztyG8KVP>#*bS7TF-h82$rF5)Al@7r~dhV3Zy0865&4rwMFY^ZHQXP{?jte*xdn7m* zXM9mRBcbcMlyf<);=AX^SqdCCCvHR?(a^^1OAul%2rNMouCHe2fKHEZ)L^SSV$K~p z7oD9oFTN4_*-q32Ao{79%=M+Gp<}UU&Acxh%xgYZ2OrFfQe|Jna9`3G`_pDDhF)%@ z+Qk>^A4J#*B;4_yN2{xNy5n%oi>y5wr_Iyc&hAD(IwBHq3Zrb1S8J#go}K&6?qV-m z_H<>xYKO*1VZUmjvmIp}`o#{tJQ9SSaXc!N+7pWo&uyP%@M`yGH+GIrwSAJqt?lDE zQ%Xu&^g=dmWVk7|_Kk|G!B+w4qaRl?ro^PFyg~p9QZGdEduk|4n;GB;GaL0$RL||S z9&%87vJgX_hM7-IIOIXXFzQLFO9h;&!0Ecvc1U`hYn@m|HDxA=trXNIl>W0c^W_K$ z8%8P=;q+9lt_U7ywwoI}!Ppp}y^3~;(&)P#24C23l)wl*<2Y=Nf+wl=+tVfs`T8@e zD?zK_Y@ZfFMZro~5-d;f7KOlyscIBCxrbG^u`iH}cI{0N87X1zE`S1wJW4`BrJ5uS@sg?!|+%6G1+T4*~FCGy1*rv+}>f9 z2(1R+8T&^w6?ZiShmByktO%vc2Q~*=3Pih_a&}HG+Z7`CfvEiIrWj!tk|uT~jU zOBJrd5|5EC-og*)&g99E+trkr7Dl0iLG5a)t^E`e5<~u)sD!(krb{=E)Fv2sle2k( ziq4h2Z6PQMZT^jss}v={a({8%b~Po@71dR;%Umc570EERm4w4nIxKb*Ib0@Wi})Va zP_4_Jwmn70q|0r$0?OI8G)N$(G!4Z)O-+Y!9*4@(jtwb(ta35&B6c6y)3o@Jb6}K` zPF%B?e(A@t?qgZ>kv&a|F(45DWtc~a?;%c@g$+_CY;F;}fs!jW}XRUTIVv?G&rGSKw z7dlY9xRa^muu#MFxyp6UhlphgRYd{wHN{4qG)2K+VWZtz2HjJXhANNgg2GOwp(uu8 z$SyRtld1dwh+wr1H%`c8?YKyAyAbn?`j8IbZOPucZu1#hchp@tw%U&r(lA#=GKi#k z4pGUrrC64{hA$=CmMU#{T5j8x{$8_rC@X@X;cVMdR7c;Db z$7svaC!8x(B(O*{n%cIav`tGfOu?ba;^KU;DlB?4HcV?H=~5kz;NjbnmTR%+*XaK> z#VdyX5h$;%F<-OyRhTp-PjEPVvTZ~)F5!Y| z^HJs1J*nNr5uqd^mTGB4I$x%HwzzGF0!<+?ctEkoSLVx6s%1chomZ=6dKJishKe`S z-2d>B{rbe>yzG_Q%G%IoU(m)FYE{sQbpEt4q>jj)7hhk9e10)9Tk|Wj`hboq#iib) zR223G?t08jn}Un37-gyKH*1&)!4;M5!;n4A7BUj1&AcQ+$OOez4O-1jp&^;F#c-9D zwL!~>sLL38QFO927%P&+nn97J2_nS4&}xz+u)6$Nt7y(RXjfWI2u4nbzyz!{lcrZ;SvqJ>iC1LWY-9 zPpj!Rr0F663_V4xcE`L&%)ZOzu^MLIS&~P#>vsZFP2p9Wnd0by#n3}bPbTjrg2aj~ zW3)jArln&$sj8ERp4Tial3b zkl#`yyqajQGWO~}+^eznDq*j#xY|N#fM`EcjoIK|ue2(b?aaO(X{_+mE)}}hxC!`d z&G|%ZA&Z_=4T<1akV&czxnvVW1;sTk_*}Tm$)ei+Mn^*YDkEzM@hj}r5aO5Et0BZM zE)f5HNBrWhBJquchxj>M*ctZ;mbES@5+5|GkZjWrL~kifhjA@$keM zIuEK15-l>#rQ3QEzYDq|7-KnNp-n=E8dR6K&cESnd#!_|Go9R- zUYZJ`W{1IbVHL1D&A}pv{S-{;^VNUVVi8RSxx-!vJsmrf3k#pMc$(Ag+!RYZK%zBp z#(+A)3{SL~IiaS<&!=0Y$q~t|y4+}S_4>Y?X*s$C7&SPm1Ty8G4Z^i5nP^fg>~Ja{ z^gE5eE*}Y(56vCL+z2ECR$)$5XyO_<;ct|aM3|Fgrt|1iC_1cau=B{1+HmwqsXePb zs#Ny6^I(pSXUb9PD3iG(<`(ix%I-wqt#ptiJH>|%z6nc^#1+~^P0k$1UvR36$pUT|+ zzrg6QzPlbHF#qFf}gtn6%T6-6i) z7H)}uaJ^@$(dxac@+w)olVrq0$%s42NI;w#EP*9~I*<;0(j^VWSkdY9$qCN(x`tcVl zq0csdQV^v{2IErf3C@e73&lPCBrVG?V+Iv=^Q3J&vev&siJ!o(R1}@vrRLLeXawFG zUM`YWI#lq z#VUuL#mWoBN;Z7K8c^;J4s!S zAmWJZM8bvG1vf^6aS&wuDHCPomVJS$CE4)wgLDkwJ zk<=(&taG{t67@bp%0_AF;VG-wwhQ^{_~xd=Nwt0yPUWrreSSctwa7Flh9jQ3Vwp zFT@)APMPXE7yE8S%ZspRDQowgi+xwof;Ot2)P&5f>EZP`Cy}R$u5s8D~zUmp6YGER%@$!d(~M5-trG0yaQ$t&t0ih>?fM2V2QWet%!C$!T?s<5cL zFmO>;G;mQ}C~%}FEHJubSYXo_p;~twg(x}!T162@2WY^Fax64ZpfsxU z;H4GB4iCkQljKZ8B%Id3L(v7LAv)5av_nT4l=cU&F7#QLylS{LGuAXQp2+x2r&Jne zAWKr5>Quf^NXVTg8Ew>Gy23In$w&3G#*2mq4+`lowsvyG!=>CJvLAcGO;KtnfxA%M zxQP@bw(v|68gh)DZ6wkqX6iI-(U1pJyXpLVnUNX^giBG217(^=To#QeM-8&)DH}+& zd|Pc8l1Ig%4@NghehMhkLP4pKAy&jWlQ*7YQ4%mUEK-~Y9YajM9Dl7rX6nTF%W@@_ zpu?DiO%Eu0p$y6I(Ar|LT-ep9irlhb3Y;Ah#Ufkx%@ez*{*{Y|ZvASn>REyxI(B)PcO{&r!oipiIkkdtnT9;$sU0U<$Pl;A2?k-7gvPquBgHN`wvT3Z zNMBQ%!_PEYg@7Er90pX+Fj;t?w)X+wx>TR20J2lCz?>}?t~sGPv5mw|_L-Ed5nD=~ za2A`~t4!@;%|`e+&d$G4z)4ERLSP8!rH*#yVg`cbfOe-4ZEWFgV&QH|go-Kt-^Vk%Epw8sB55TY6p%iAX@dv0>TFfvLj#S9 z2$>a2t-?{EsCm#R4rxA50;_Cl4g(FBd8@|j7$fF;E-vyEkQRo5!r@wSOZ1!~$&?43 z3t0#!VoCxi7H$@x#?0(uoW!B`axp8qs5_=qj2O{|Dm5!YnB7abfAC8LSFm3+W;Qab#UW+IQYTd-n4ENFmW1>&RDQ!>9)N5MCVlU4!4E&aoMkQeubMjqdqnL&J0@uUoP>yw(4N>o&Ap{Am*HP(U( zAMf#TWGl@~=JrIzko6Lb?FThr2|mIkOz@|x_7fbu+7t_iqytz~GFq}*Z3awlCTLYE ztMm?7LCZbD%@rb^_^4e17MDRyT1q%d{}C8#z08Z1$MK&I_A``ZZA0u#j+8jA4Oha=vh6vpIN*iFgOZwf%#&Tr%uaAkf)%?I53E#=IQUHs3)CooUS5;foFmQP zX^-P`Ko!pfb6sx?Tz?AF1DO|>Auew-&VjG(@{#-CgMYxOiurIAktv2}YtTYUEkxN{ z9kZ2HxV5@0|7pyGf`pc?;&GEy+LtuC3#Y9ZP8}rcb;o;%LU`yscEd!sP$eOMQqyE* zIEf)5@~DQiO6)=PpqNY63XH&GX=lt_JS&{YDpCxaa%NXeG8TtZGL~%1Aeky%8#S0L5aIVz9txtF%)o8@<8y> z!NIs`vlNSmQm~1$hn8!%>v3U`m9fsht0v>cqMv-@$3Zzo3r@U;I3P{^MaGTk+$Hgm zsmM(tPZcodF;c5yTeKfCd5M+X@mG|W%}B*(WM<5$s+p0W zF)dp^cE-fXQ;waH34Z(T{jf?^Ar){4Dznt%|GZHXBVb|>-B9ay^uNavCYrc>}-D8!|$u=xD4WuV;+?ERk<{BP@$A>XWEu& z{xE!gjACegKVk^2Q&@fy*V_Ft&A;J2rzm88E)&runyuW8X3e8cWcn zso19i-|i$Y#&aUu@@n5tL(0Wr(!LRbt76r$xP}vm)Ka)sjBkcG-dXC1%s#>=AeEDN z34t@b-stdMvXSJD4Dk|kF}O`Cyn;``uV@#@(*#u$t&OA0G@dB}F@!~KyP*dMzcTya z63%kUa+Pdj7KR2@n~?S@j$zBFtEO`pv;%-Pd&fb4Yv(?{ekVI*`1Q^4UCmdY7thSqQgSV8i@xkCf zeeRbPo%>W}>tWU|whX9mz9w-I<#G*c>Xpvat^Sz3cus?(LIjpIP*k)z^wmOIo$s25 z=*VZpin1(tD5m_C1^eP$;V1-g-$maH?(5;9SeI!E^d<%CNansPqn;v+gbnU{d|OVs zg$(jZc6xoYGO?TGU=zD>xOmFzh7<_v+Sg33Sk^iCnXh~;v6BOQ;Vu@$HME=R*`iwb zPCzZ&uF|2;_@3ZSQmv9k@>O6dR)M&Z*2P2G#-lhW%n3S_XWve8&Ti2z9R%^3DZ6(f zW~c7nxl`ef-({;{6fs>jz91=|b&`U7e8ox17!$6E2s@q%4g1uVOZfF?V%T7@F>V#5 zUU)sEHPgpBK2kY!%fWagK9NmfU}HrU_S0>HXfV7egU{Fv9$N&6YUjl|6sh^NcjnWV z`{`Z8$F$Vvs4|kTPoAc&MW{M#=?(P~SO7 zv6@EJ!z`RIJ|B-Kv)4@7gu}zr9`Z+9e$ABbt_OlsH$A|lCJSpE_Pz4zs0z%hBf>87 zM#1hrO&0^hT6x*kRx9yJE8mw-H&^XKJup5(F{g0@3-%7Cf=>_Pk|nRk%o)_{n(RYt zygtOcWh?H-WB@)inuqIEnKo(R*r1 z%XNBT%yEw+P+k7+b=)(Tn<#&nGRETRTyX#Jqp)9cVf|80Q&BA}ds4Z5I6}O4SlD8b z5KPWE2yO+YpBCx)W2GQyXLs5rWv(IfQ?AL?>hGARMqB|@@AyEw3DLBoEYILAf}b%v z*V=L0J{&tv=g3pBZ22X*4a3WlrKRP)>$%kVOw8`2R?FxFD_ei?5%W=F%M~Yio)DM= zC!5~Lqi!r`EMZ*OUK0$Gj}5NfB8N)omgy$x@2Z>DWJW!m~vrd{aGJkj_4#`79?crzQ%JF)RR z?q@dcII(eu&#RV}p7tFBEt~r~Hnsb`+uHj!boXxe&g$K!#J#OO{aZJ0?(G|BU+;JK zwzYP*`x|=u{QiMfQtMmqcl2!DI^YFcFWA~Y;PnrzU$kgl>-v_qR-QJs5UOv$JG*Vb zgIMp(t=$71{T&zhn>zY8wGOmx^!s`ty``z8r?;oAz266=&-b48zJ70I&$ia?j`e=e z)=lf$`~2PwF7PaWQ+t1Z>jmwjhG;5=m^PyylKMJ&E@;`-(Y}4rqW-Pxc=kl$_V(7U zmd!i_oBOstHU7cFY*Zg1`L&IAbNOGj)sdnl=XeWu*Ko>pQ5r>t+^cFNX17}>kY>%Xuc zO1vm1pzht;O(Na8vp-wAyS=bbK}d$TwyB)AcMNQV@qARkZn3DN+e5JQ++pl%?dxm3 z5W(5r(%s&3!N5l4scoa=fY1FMZ4|xu?rm)8YrjCzHh3L98@y>JH?HEZV1q|;?UHM6 zLu+?`yK>*|E%JM}4p?co_FT|TbQ29BSdTol_pCRP)_c<$XLNUSvA-uy)BW1M3rW!* z=tU;s&4B;*_CDSF0~?Xqj&_0+B(U{@3!saV^*3)_*WJe;FK_0kp zb34x=lX`jw{6cl`2HN{Jb@YIwWg`slMoP)S4kQR3c3(&p==A<_rA|tsUJUqV9XsPCR)If8RKB+NPP)N(gQ3hDPs#b}COtn}_Im z)22=9kN(X#dB(K1X(PPzwy*R0)_Eu&uXUZb{Y0LCR$v;p+grV9t)Bl@@6BBOY3uxH z>-}jfBB6bwxBBcgE6?+yH{Oz^%YxUfTHCVZ>@$OvXSJ+Zx;i*FSbO%l-dVv}-s&^G z;7k|RTXlL%uxgbTtT}ziI{JEhtmdg0IyPjnK(l3{^1 zw+?J<>D}DkbMPnP_qVrqjrgIhySKl6#4nrs+AYoX9epi5ttiifk_0b01SK|{mYJ{` zPQz$#hBsYR?F4W73EnjCIInGyzpBt zHuv?Sulc_j*7ZwCMHQ6L!Z=L_kl8e)FQ>m!UDC46KthZ0?q@Q@GF z`#au_G|(n&=s#g}I$Q(bhYf)0TA{V^(a%_6i+m}&?R_0IU5HSrb+&;vf~fs%eI1*z zW?aZnEy`Z8R{hWsx;xgPZCclL5E&!Mw?;)3S>*F>T7M;mikX8Zvsi){asz61yL9v@?YVTXQdfS`MYMRxueAU^_!K#*)vs#*(X0PdPT^FbcZH0BSVb{`4OJ^V7(sT5OCL;OW%ez{xeD&&pdSDDN78nPN2hN&L#g)-8&q-g?taHtLT-tL%M^F3G zgTBv;J`ne6(!Gu}l>QD~0q>O9g2smUsSBG50|#sj7N$1MpU?i(Md#L>bM?lukA3zhmrkAZ$dhlLFsxK#;qxVf?&e+Y zI_T-2=MBEwJ$r<+yNkp3Y4?8cT?EqaN_X*iKd4*kzg>y%u6oJ4s|MXQ5nkir)m^;7 z%J3$PKNzJq7>0}JNIATNUrT1aiC*zH8h?*eK1Yimrf}Hu`RMoZSI+<0@1L!F;;xSG zJb&#g>-`U19o(9|FLBF($4~#`hRQQv{hrIp?w#`5@t^tD!?#te>Rt1@Zyi_t{bkS8 z&bWHjq|a4Mdh~;z`0bnQu`)JZq|^!8~_yz`r1soVSO-Tmiem;COT zyH;$vaoU@H{mHSDPX7D5AG|$&LGt>~{mYE(eLp|t!~cHihwu5(qIPe3SNlI+@}a*Z zx6XTH=CS)~KR@?FZ}0zV(>+UW|MlbRAGv$abuUzX;IegB##e9s`%}v|wbiCie*A5B z{HX86&pdQy?z0bG_3syr`PmCyUwrQGA8J`rKl{DSwKpA@zvBnXRy}z7{o7)%S@wm$ zfANp=Z+Nuz#BUD#>|1a7&8_njC#@W_{^?hL^8ZeKi+9!O&-bteE#3Bz3!Z^ zzG2OQeBJCfUGuhgJn*sKf9md2-sRu;)N7|a{JZBbc=xg2UG%o5nfHIA><2X;TlB9# zO5O6Y?Grz7(u_*)XX)?!@R;|0>CRivxnaigfm5H{mAh-nbD!P*j)A9s@t1wyTz2KB zn*QVLFP`|>g$GXl*_}VRVO;q~(r5hU;hKFnu6}yYn^vv=D$#Lk#`{du2w9B&TvUE*tDv_+@+=hypa(33r)TUyU z6;0m0R8?)PI^k8u%aawES|;Jssq&gi zrq`1dYIcYGsNc^Ws(rX|U+vU)UH08aPH(<3`1OO8Rd>z2^6 z0A+w|61DM4NNum$UFpDMfT_SV0B=+8MBo%)F7PVg)xhb%a$qHJHn0YGBhU)80~Y{Y zz$Rb|a1n4Ra24=w;6uPifR6*W0DFPkfiD7I0`3PM0KNfy3-}?RJp515dm(8Jr}=%n z8;S1Qcwb8US9u;z|Mz(p{RXgsCiBn$OaVf>s%cKa7Hp&EIj~gWWxt$9c>QEM$(B_4 zDBiK*HHyEm5Z{Il3rMnW#Rdv-h=)o)`n|~gBp#*$J`mxWRXPF*C9*BX(|MVuVgWvq*?)NB>2YUZ_#c^EU_0}Cr+el>n-Yr zx{q-BRUMP{UeC1^SO>HLs!#2Jbj}69MxX=e1l0C)1DgQxRKF$Q=;7K6ynqrD=-pm&2%9e-@r+s1V}ARNN4cRRRO zd-6Qb0=;`X&+h<^C;pw_{5tRi@GP*3cMAah_7nEaTz3MyfZc%Fr9t3g;1b|c;4X^6>U=- zeK+v_{k;1C5S7aZxxW@DEf=+$DwhufDi^i=`rUh6);pgot%3JZ;CkR=zzu+GgQ#3T z!M)<&2q^v@K);8f<8@qb0zz3`=%#lN*OhIIMKm>OxU6NMueD=BK{U97OiiOx+BG_)E%c`$1*4 zy`;?668Dg0HhOd`v#W_86S?gGa|p4S2!ft|oL zz+&Je;HP|l2v|&5{YrISlt!t}i_$37d5bOPP#KNFmCC5_=~pVF4?(X$?;<@MmFI#& z{e^#rsz4*N(Auc$$fIbD(!MsA^=^ZP&j3-{diPnL_W>^uzLDo8KotUBNe;r;4^zL&!-wEs^{L{b-z_LxkOPA~SG|!*s`UT)x=oRRl`h#}?=W~A@un!mjqIjh=NAX6YInrMn4kZ_i zoQt1#fnPW_lCFM(v{7H;`eooc=o0AN-8|m|yh!*tJg)$beE*_ zEcf5#{lmZ`z-TtoqkQ`w@EGt;;7TA$r!+6LHHf@;`!(S^mG3Fx{rZx7*{_Q8Mqp-m zudva*!s`1eK3X-h6Bdt`i6}Q33hw;oYCPP72>m=Gp*E3BNzX_y6GgG2!=PxlRRqfd7Sbl(y3K zfyKZe5Cu4&+b02g=8{@~PUe~ef#}Es#{tI!(|}h1uLM{g@0|cBABTf7GF(QuQaD_k zBmJHL_a)$dsnARwjsy;ce+D>41n8RaUkIboFpKm@1k#@MUkJm~R~h}k-~Z#l5_HC2 zV1w#_bjFFmNx)3tWMH_?5XZWS^PgN#;k)8A0!@JAcs4Kxm*<;DjTeqG7^`jY!Y;qeKlxN4L2)BVx3ztahSf+B{$)XDVS zxj#3|e`vSNbFQUxH?+3lbi#MpEYHov4iD!Mt|Z?7<^7s4-de7&16~ij0XPqMBk(5R z&A?lLw*qeiT7WQ}x#kJAQif4vF*SzHQFtbku*L&BNlX3l^SJ642Sm57gW*;0r<{`Y z{>t@y@T<&QfptI|upVd!HUJj@VQTY3H@KB;ZB3YJ1qZnjdS(?o=F zIF;rWpbzK=27s-=Hefq&aGFcD4(Eh;|KwrP+(DWLNOK1`mF9)O+ktlgJAqxmZr~!| zpfo#1&gWWi>Ni?GpVfEp4FXE@V&D?sQs6S+a^MQ!oxs6qj-1bj4wL5jO<6AnzAFKx zc?9LzG>^3mc&7JmZyD%q**dUc!OB&en&uUKwoV17D~i2fC=MyJt6-0a(y3g4e);81HcD?Yk{!LHOCs&VdH*@wkg#A?FWmX)wL%` zTfdQHP_*64ceRW9?SQrqk?w~9$;L;3>wu2}*8?8|ZU8ObKxCb~C{-zTA zn@jLN&;36T_bY(#e-*eFxDWV8;C^5~@BlC>{w4i|45(Zm182nhwR5xHgT(zBApBnk zz5#p__!jUG@NM8bz#;L684&(Pa7Os=;{LnDeHak_M}S9x?*Wei-v@pG{16x&f5#B| zuK{ONzGLTQy~m0BBS8573HUMa1n?8!pMie?ehM5Ce+m81mEa!$|Idi~b3pii0Xzvj z1^gf2m%!7&zXBnC`M{ReNof@ckqM~yvl^U{{5;P6uZa6^fbc&9{2KUo;5Wdtz;A)y z0f)xF#A<->-wDo$KXd5U|DL$d0mAIFnnZB zF{8R^b7W5~CXDQuFig{&p%Fx-O3 zeLqBHH180uk-|7M7UqVbVVdSfh(c%lQhfUftG-G^+d*MV@IFg8^;h&0&wtGI1>{0< z^B3ShfhmA~;^h-u|H`wzzX<#d@B#f!T7;d({Q*GV#n>3Y`b$saEJ;9PIpshFkOI;` zB@ogoFKI14a&vPFJKRV&z*t}$Fdmoy z49~Mox{a9UQKsXHxhu)DD_qh3SV-saJY5~WhlE0&o+-)GGvsL^A149I(`2p>_^=JomNI%^;13{3h(uPZFmofg?v61 zzEk)+PtAIHJ{|`spT~2Z2D}1zB`_Ue4^(dka3U}~pRT+{%IA@mm-1OGuR-Y1Z+JdV z4c|jTAs^R;?-c&dS2M54$C-fgaWdCafJUGRm<7xR*jvHoPZfSH_bj5<2Cp7xae51Z zMZl|oFrN!-snpA@jE00s&Gx0%_w69<5Wm{YD2Wy=W$o=_#c`;})K9*Quqwynx$2hy zqJHvD-a)E&tG;P~n%@ntVIGi|uLi^i4m$Nt0~P}T&@Uj{4(Rsbu3 zGl16u2l3%$RM1f}YlW}8Zh;o%^(3zPjg;4G^)1Zn!>2K43XNw1%IjHNM=SHQ`L-H3 z2RIj41IP*Qb%6LFT(9T;4ZwN88-X_gZwB51gnVe4TPQ8Jc81rGg!&N`Xw0fZHe!Z*GTWrF`S?{g9d>bG>wQwCxCeG(uE3gh| z1J(oWzy?5k60Qrl-w1R7oj@1R4Qv7;(huU(%aEH9`Bc(=-v&()FW$nvevo2yLDz@% zF66~Pz}z@5djaucGuI(9{xX$!Q&eW)iOTGCq^WYsa@9{XMRmAa??QQgp8G9)>F+yC`a7E$3nb00VfrP!3FY1zA6tg{k{USZknEnMbV6F5<9-|IZ4c8d z$@9T!zQnvM%{`3AY5#Tytq%@;p0;PE> zIQ1jwi1~b&?;qvk^?=g+7}pzsj{~0oZUpuKHvu;Tw*aH0S;*&|he>nA(yaGM@O%nT znxE#n7q}I;4fqW3SzsSCwEaF;dMeuTaL^c2(?Wp1mEVZY_ z#r@-a{1G4;|B365fiS-%G`^gMPSX_y8Vh#O2S{5qt_tZP*#eFGN@zT91$|RK{sa(> z|IGDYfT1+L+y<^dqamV$Vs^jSzD2(mx&J9N{Vb&M=Ujg=B8@La*+d{ou7_dYX|OrB)IGm%H83W&rIf{37K!c!nTqC^Bm!Xz`0fng?QW`GoB z2Bp4g)mE#$_gdh#_GN9WEw|TOX&FshZLcl1^>u5niH}=o>jSH;Sdnx8|Gm$dIcG9M zu(kbu-}n1=vd&&>?X}ik`*|L-&pwD5U?!b!2t3jZPXhlR5WfX5-@}NH0DcD;kgsw5 zL%aJ2v3vFskN7=o`~i@sJPqe&TsO||Y*}@_E`vVngkd}I*I?&$!&VL-2ime+tF4AU z%gN9W`~}2s7`A*Ub332|;0FW%8vq*tW)-GY)Qmod_)R09 z3t{gfKqH_DFb6OfFb|L~pIpBsa9$n*+vYRP2Z8@L@;Pecb1J{XWS1w`?}N-|H*A~F zmaCR}#EZ!1EhC>E`2BIf4!|{lYXLg}2|&K`%+K-r9P@b%`Iyg8lgOtJ`TWty=W5vN z21EfdKpe0YunmwmpXk8fByM6Sy8BTlaGC0tTP@#B<5fPA7o2 zxaJ|3%t9kAh&VeR`cI#^X2P_QOU5iC#BAjvZ7mCFtM6vI=_6^YKcuZbkX{0yPb@d{ zCC;*$^-6u#N4vq#CBwQm^|-E-`7_J`bOC6O^}+QZ45qx92YoQh%)A&(9(7DP+M^uT zsxoH%vo0A}F6uHr@`!V72>m8b9~f2u=p$v=U$WDe8~m+^^Vyhhq|r`38Ed^lOtu4M znID5$2c}=vx?;LnezpsPNt<d-bBEVw654wfzy*N3 z`B~0=t;mCGwkD_|{oP`k-+n31ODM|;fDT~T2i^z7@nB5@Fz`L#zkr98x55cn8JjiW z-Mul8VOWd!eaN~Xhd1B(z8{vY+h6wM+`b5Mv}d2SfE&<3cMoFLjjb7f77r#A-4HaFNTuQ5Q=QXo`Lec zQmWCX_Y9wi9|6w%7+Me)!_Kgby&1-~eQmz(jo8a3ET<6a&4jF}w;Ol~bcSd2rm4LP z?fG_DbRGs?3i%Nh9jumbi)?7aW;xiO5P|vJXVEEYMV^o!31A(tcv3i1+;h6|0y=m5 zG7Bur2peo4;?Dy&-+P@6d)UK3jLO)XZtl`)8lcW3$eB7_z=uG-Dx-5Qc3V?hdm2jA zS!>aG9{6dH9|IT*V0Z_-(ZI(6Y7E{F!K()D1)wjU#~ce^Cj$D$26HYNRdaL%NRb+p+u9)&{P$iFO9Jw5833x{9xy<@i_iWC%CFBUkDsxO?W3$3w0{TWcW2w@Lv?e{J*xuhh&riU zc}%nB!MCxwov2-zy6+hIvA!Ab_?OGUWEpGGCT9cc08;>Cn1FEaDi6LTf#>j+w5h;t zbutZaY{O?iwzI=7d?9Pj%r^!btVfguQDA3b&djOI6_{tPx4%=l@58lCZbLicr75PGafj@81kBIVO1_;Pj0=Ue8e{$#f9ZxfM9WZt|LglD7{yb;#RxG2pd;pw1-V z3|{h@w@BV>Lx;TWhE5C9K~QHcaE4a$nzu_{7jXJU9_DkLaz^OwXPlnVn2*#>|)Cr<-zn|B*7wWQ4eZqEnj)BqQn*s_u5qgLu0`LrUQ z09|~8Eba45;Ijbd11UvKD(soId9I!W{rLdX_5$Dx`;m4Q@P(GNi;cAL z=mV31FS4X9Hqxj&v~t++5hF)cRi8F`%-C@?-j7wDe#ZF92@}tpbk^kBvn%VS)O$Qr zJt|;>W6$(+J)X*ZVMe}$znXs@HD^}NI{$*%7hd!stTY-f=Z`9z=2Xt*yOb9%TD+vP zdFis{D_Sn`T)MLLvQ?L_UUS8jYp?RGYg^B<;>F918T#PQkP@q`3}kTzl9iPkHhMgr z!8~QyR9U%spi&M_WoS#98%|?(B+_+tx5u~R z^n>5!73Pg}M|T_IC-hzelhK%Mx%WL?|KLZj>|K+5@R08Gym2GxExk8ZJJzN2M)Af$lIv*B-y{*{a9&-p9x8!d?t`&fNC_qj#;$im-k{$k z-E>GVRJ5)i?z`$}66wcZ(-Wwn_v;hMHtge2Cgk3p3Ekc3MTH|g`>w8kOV=-G^XhMt zW_2+|ZUS0!LPwFPf)cBsN|<<$2}WpSe9$W?STn+fi3=qrk0cUif)T6Q<5j=O(DlYf z>0gF%a%``3&TLOze_Yq}z6#hgps(DpeMr}}q(_z5;yJi7gS3T4$|v*+T}v^cu}0}v z0CyVNFwP`|#0gXj`AM^K5UZp&^*1Zh^1A-E;vNJ`VF{tXBC$rpgTvCqixKv(oPp^{ z=7&0>0FL)FBChLwZNI5GRH4`WCf!cbo^T}Lk&UP5!-`C&npJ(_g$A^;6e@v-t z*e@6omZL<~p=NuTOgH)hHb9_!LL`hpDVYcO`9ePuPB<^B$@GIne+Jjz?Uz|uI0@;K znrD=E${E|SF`b=_J%BLEXXU4BPcj?z8pIW5JsiE=DymAClzTv>`55jD*GLbN`au%F z8L57%uzES_jvtYf?2m5B)Tq>Vbu>OlTtd<4KaHe0wq-~Z;IW~u&lWp(?nHe{9+XsK z`skK6(xi!Sv?RCyE7P}CQlpBDqns}i;#j}_L89%20ZGb$!A6Cf0)~sS{H!@^=re`P z7`3fC(Yo^7kutd~=<(z7F@XN2tb~6@`H@E^7emzO2PPlp1_{usQMzg%5SMemniF_z zB(FlhNLnJE6=X{oRj1|#qwHCQwdkY$;J%*2w?<6wm`y(|(=m2HBup_~KTqjlHp=j% zHz|{j9DNhjC##0KH3X*V;1ZG2%v%EcSlW~{q0(_Q<^@H|z6jKaWnY!z0}c?XNlNPj zlE9VaktXRO&u2#OKyF}bX8(L#?;@>VERV#-34IhTs;hy$O~e@z-^Y+rv$)h(=UbjX zclGD5e_emXtzS=l+GhApo-(P_#soy^vMHaaG~|tRc+OOrei&C6_DWSrW;#`Dv#zp% zqf;a;qG{BaP>!Dlj*>kLf6`iB3L2D#YXgJ?ex9WdtX;qfy01dweVM-hKaqZrvWXpO z-%Xi(v9U|N;o;NiYLAUoQQ%Z{X&gB%-?4ryNd0s0UD5{L*i!^A^~5fZxo-V5nj z+Ul9YrBF?>(eCv?xonQq!!?(Ta~x_61vBaPB75&J?Xe#2KJjkJ?%&^i|K0DtyH0;! zuXqDsrmGl2%t?YhWvD0X{@LR>{S41|;|AJucHNZ9%6fIvXKv+FX}<%rP%|y~M~Key z$lK?^?}>Bd*_4Av)*O##t_Qcz9^5~B7JEEPcn9slEp+A%+Ozhmb#0Vg&x0lSEcmIT zybJdaexrTr20a^c$ZqTmZt{3Ghbk+L`|NN;N_AcB@pMOHp7_>nXwB_CAK!6};(x5*Q(On2ou<|63WWeG>IHJ!lhevQZ?C+h%WD z@^MN178ee>Xj&|ZD$Gdo6*W>?dQ&)==IPhQiS_zHN#HJ9#kS+IL$82#3a^~Lm)p{? zP~EL^BpVNi$BC)(Zd6KvW_&y%DVa{J$sj3D)Y;D?fu&XA4ydG)xR-ycDPNUVm`RLf=t{E`G8K*|>X}#G6RTZgNQ0dw#q9uD?i2|I zP4w?&oM_CpiZzSs;soVGD3eFDX4z4NC6B2%V@v0`@MCx6?XAo^A^I^+a)y2A8T?zH z#7W<{o=WuTZzbp%b=6T5JDg8F`mMR5tmc5xhC`TY4^WZ)JHu^MneuYW7I@NYv~hBJ zXE6J3baERGOVE-QLZZ@Gf=87CywP{=fy{jj(u38|Qw47Ux8ND`bB9RbN)n)DNM(^rpYgec;$#%+CN$V1U zgv>E3+oTf8Q8Px0O3ywf;RC@u%5=;NsoTktROWzktHEcmZp3vjGwe4&Hq82C2_so< zcSGBRags7qP9A5@P*i4T92ok^OraeHCS^FO#^bylF+11^r#F*^6#(*kS9qk8X1>%Y zj_`S-3hSY231)xEjD;%Ug%35RyhYYP=O0Tihm@S914XQyB+6=|hk#1ElRb2bEN3^X zRtBf~z;N6>kZ0lG8J7{NRL4+MUkudnVf~i8VV;A7(m-7Vy0FZPg==A;5DNz>5fwL`2}&FcN`T>>D{%h+~)&vqECv z43j01lRTQgGbOX8iY|Bdpvh&?tjL;lqQS{keQBBei1GVFMW&Wzouk3{C!Yz{Fbx(s z(~V&a(#Spq)OZ4jUr3zky-}_CQ9E})->6Cd_GXA!+Z!`BI$HYI6<&)nu*EE;<@4W6 z*dZtV!;gb=IKx#KY&TZ8-C16G;cPLW1W*p(GaFuhegeR5qX8TMC%^?L02Bg>0L6e3 zz$Cy~fHnYbQdB_CTZP^_%OI_h<^|P{q8uEnUcAAY9LIR%1$h<^N4bv&ZyvN+psNt$ zL@b_0&+J9oF9AOX{0y)H@KXRbGu944(TDg~0B$_|Ma0h_z7FxTfL{at3-AJXIF-ox z;vv}H3&2L@j!AF=A??RG$a5mnb^>ZA3+*bzlP2TIC-4h_FM#aDP^bZK3}75!3UsCc zW&q9wtoRZZRs$ML&0}cb92i|1BBcRU&{0CqHU<7zW zzl6F{XD7{zyit#7e_P=X)`e*k0TTdC0QQw%L-z&1OMn#MQRtw3#ACqGSHv#>KLy}k zK;Tz2@gRV+ja^I>es=+zGfB@Oi*}0EU^6cL9DoB<+Xf{|Ncb zd0BUiypDtd7TGAJo5~m5)P{I=p19(L*V@z;2_`)z_Wlq z09g0mNBl%w*`C^|i}lBqeJ{+S&1hVkgv0X&-UK{l;9lUSj1@l}{1J|t0* z^z5p;hLxv>7Csf`Uy4fCeWKWD-8mUAzeap`$0 zXSU8-bN-bVtex$6CbKSSrJ=XT* z`k(oJ?mN`}RL3v;&jg;`@Z83uoo@yIxasZ9?}Yxe<-PC+btmfdx|ZN2!ApZHgRQ~K zf~$g;2UiEz1g{8Q8C)B@D!4A#7Q7BSmhZ;wcmsArzX@N6NyQIsP2Rlgmg_$GiCb^@ zRM+RP{`}TG+xBeV+q3uM`*!TR=3lS<*YAAcdtZFyiwExe!Iyf!@Z^2J{_+c7{+~_1 z|H>b}@>=-qFC6>odtd#_*WUly@%tt|IQgO4Z!iDO?xObZbv)uf5cvLvA8a`oPDLK= zdTeKJqW9WEpL*)9Uwr+S5B%yIPe1s~L(hKuxgS3NqyPHxuiZt(C8cGB=}=x+IK(6> zJe5NWhnZAi;qVa|{2z;r9EJR<{tkIo)8=W0;n9{1##r!=4juc^nfkDn#^qMPsQgEU z@wGn6T-h1Da(qjJW9<&}Z+MTy>S`A|7df}D-7#F;U82=aDl8O} z3nx#mbwBcNwc|uBoT}B#qU4M72~4&r{A}URYQ=^je_gR^)!DU)RjX#z)}k9`=w0WiBoR9lQvfF#H zdnc^ePkWkM$;!3(D(9>f={d}t%MjPq*7gi%+%tLYnTmg(DA`YJg)>KOpRB}-(z)kQ zG`&g7qBw^(G3AWTz#RWMD-SWTXW$=r{_GMS`LLr`@K(+|cOnZYru73qU~GGw(T z@xcw{ld#lt#_C{Y6MvnS#Rp5hT55IBd@UAEf)<{6NrW$B8Q~iIoMqzI-}ae%QA`W;rP}3Jf=6F?AYIflR4c<^-L(D6E z*cwDBR>VPV@ZwcX+D9=W@oq@9$D=)BaTxo;cE`KmlUIG(*4u%Xt}{}6@f{mWb_YW} z-gwxz6`ymJgI(&-6bNh<^SUF^Xq`X6?7X31cr)~U{<=sQO0tB?G~QA&N-1jt zmQiQ(BH=KK&MIP^#?S<)r$D!*>i8D2--}n8?ZO-4QPkw3NHpdRM&Vp{z=zL#vPI_j z{je4F2E$&+h`HU7&4IADD~L*3T))C-PqPUOw^5ZorIv02l>(COn`xoNQ5)GB*d9}* zlr_3wd!U02v&9!PGBT?w{oeN+;{|Y36?~V?83}I`D|@!IM?%34S%cnCB+@0=_+h;2 znh|P6<8SeWd%Te@6p589i)mCa$|URCABc8z2fNUr;A^_g=KB2E$t-I}XE5aVn*EJJ zW<@ajOm`FMyxGK2s^YUCo2@ydJC`5r&qVLGNF2r^9Ubv*ym0Nq=u!iygKvk+#%k$C zzlp@7-pICafFr>+Y&v`xh#{~R#>1+YP#?QyhXQ;9SPdm(10wcvlpLMRuSUdTjKWxO zLl9=W(fhYTdMRA@cKV{;_5kWH8h{tzwsc2g5$vgLv>5BauxYe@6lDp-#C&|BI2cv~ z+NdO0zB<4ELPm+wW5J%s@<41`qQI9nm1XegRfd_FEqx)3W`7Sya94L^BS*7kLa=htsnAJfukZAQ{TTh1 z#3PszxfMmg&t}1_9qf#Bd3~69G39_Y&)0<)_(Q>1P>!A`+zxgG(N}Pih&z^JNBoyv z|KY0AZYy}*G1B!%agS4T&Mf$rcAd7uS??Mro-X(Tc8VD1d`x@MStK4P5SridmKG?O z?zq))$WiB9>UyPMuj80&OhHk>LyqQx5svNHId-=5E$6GE*Lkh$NpZikr(nDztZi|g z?)tiGKK2Cvrnug@9(&@uU3a`zdrSO|j3imiETt%kvxIcwbq$&YJ0mA^OkJJdjNB|a< zr0@hNRSm!z?bK)ho^7P?Yfow%pauX3zk{2VUgY14{CkmqFY@n2{=LY*7y0)h|6b(Z zi~M_$e=qX?74q*z{=N8>>Jd$pLB9<8Wza8sVbLDErwo|7H&e&e_+_iQ8lK>%D<0IZ zUGirxNmYx=5~Mpz+(H{&Tne{~3z1)`D5Q>|DJ6|V`Z5}p%b5-+m^6t;!#^p~1ORmEOBa%ZO7s$CW{AXIw1o4vLk&m_VA}*TZB+kccvdR9InDNK%!i+x13yfV*9-fGmQL~Gd*B<}xb4;FU`v(6rE$xQ zvGT*hG%8O?hIK~=kOG&Jmw*cZ+6o8v*e>w6xLve!SRHuL4{LSoaS+U6ppIVL*iA^InPcE95oB6pFCI}kdDNnY+|D&zw{=kTxNScnx~ zXq$56Rd|Hlkwb}om8hz3=Y7E04;*GcaDErm; zbF>z*dDu*jRifx^#7Bu=j_Y727x8oUa7=I(BFldUs(sqQ)gc8%C2Zaj>fx$Y1^4T4 z6uY}~3uWgdW>G$+4nU zF-;Wh!NJycMGu0r6yT_qW9SP&owpYK7?EmGwA!U5Y*D&`7A;|mzD#_rC`F5w$N`7E z(4r-5(XqtYqDAyWb;_cVK-or4vr`svTTRv6McfUO&FwUsyNt~(UP1%Av;ywtsPF=AGGw6TX^8?hx}%Ct7d}k1`gEdlW;l)8 zfEKd64ljKyZ%UPN|B#6{M^iYfk!d6W1+ue7DO#90e3HrT-8isl&Xyuov|>u&I~T)Bj7uausb<$AlnI^$ z?ksv;IB=vG!>Ok_rLHTF?nzS}g1Yi(&96vW4R@dgBE2Lnq?vVx`QP$ zrP5qc3U0Pdq~`I%O-q8uY@J+w6ldi~dY~VYD@tEx*{JY>w&NQtD>2rxac z>ziEZf8LRjX#=}FTgBwi?nf=BdX+U7wsFoLnX`xFF6&@ij!PtMMm>iBdo-IteNX{yQ^c8vT8AL`}%_Wno-g5V#oZPH>D;rP?`Fmu} z*1=iEEPLKwo7E2gH}$>TW9byeZ&sNH>w6rWXmJtifjY~MWd3}^UfOXDb#)`_& zCf|%@`ko@wkgvTR3lg+SZNiXY10+vlNZE{il-o#p@mIV_sp%%SZJ)q{Z;|) zUo$pJK~`nRvawpju**iRE?rZ4IkGFKa0BcOp%{^h>0(Sd5f6|OB9+q(8S!^2*eI>E zR8>b&ISRaZ7>Swiu6S5F1nR+f(BNjhc6q?V|vG^(Q3AC0=t`yZY?foI; zcxO(&-G)50ZN6wQ>fd~Ref`#HQ>RR=k9K#|heBJo)L|jZCaiR;?}%*a!osTVy6#wg zDA-=#9uH!LN;rzI6@_DR-|Og&&_x&#M7(36P zjxZm8Ju)>mBwA0reFvy;0cO(*nTt_JG57f5@vGDM3C=>GH>O`YR z))M089tDa8&p`o!i=W6!?LDQkoO-2ZyZ$%Sg78H<4S$UWv6ReGP8NobNL=dq$)FAM zf2J_jra*Dx{@~Uv5r4YBWtHbzSsp%c9lWERdU<57ss|V~iUFZIf0ldrWM-lHxF#CI zkEPp%`F$CD>?0V)7bOSuQq|O!;U;2n{2Ue&eig;=0wgGG_b!<#iie}YjbW@HB=2f0 zC6nvIumBBRRl3_SZDxDVjOnq+jOqTs1|Qk@2+W3<= zOYQt^av*{7XDF2t6{z}PG}0}wND*Hg!WVFe3ABI+MYiGdDqDQf&7w27u~VeI3vodq z4}x}4fHrAYn!>6_|A5LkA$XlHRrsB22q9-E<+Fa>)Ly?0;ykU=*_B#aTR*3Z9{-79|BQlZN-+j gToYfnF%)U{g`%~k?eWm&I<@q?wumFE4$Gzg7kbE=qyPW_ diff --git a/acvm-repo/bn254_blackbox_solver/src/wasm/mod.rs b/acvm-repo/bn254_blackbox_solver/src/wasm/mod.rs deleted file mode 100644 index e0a5c4c9069..00000000000 --- a/acvm-repo/bn254_blackbox_solver/src/wasm/mod.rs +++ /dev/null @@ -1,332 +0,0 @@ -//! ACVM execution is independent of the proving backend against which the ACIR code is being proven. -//! However there are currently a few opcodes for which there is currently no rust implementation so we must -//! use the C++ implementations included in Aztec Lab's Barretenberg library. -//! -//! As [`acvm`] includes rust implementations for these opcodes, this module can be removed. - -mod schnorr; - -pub(crate) use schnorr::SchnorrSig; - -/// The number of bytes necessary to store a `FieldElement`. -const FIELD_BYTES: usize = 32; - -#[derive(Debug, thiserror::Error)] -pub(crate) enum Error { - #[error(transparent)] - FromFeature(#[from] FeatureError), -} - -#[derive(Debug, thiserror::Error)] -pub(crate) enum FeatureError { - #[error("Trying to call {name} resulted in an error")] - FunctionCallFailed { name: String, source: wasmer::RuntimeError }, - #[error("Could not find function export named {name}")] - InvalidExport { name: String, source: wasmer::ExportError }, - #[error("No value available when value was expected")] - NoValue, - #[error("Value expected to be i32")] - InvalidI32, - #[error("Could not convert value {value} from i32 to u32")] - InvalidU32 { value: i32, source: std::num::TryFromIntError }, - #[error("Could not convert value {value} from i32 to usize")] - InvalidUsize { value: i32, source: std::num::TryFromIntError }, - #[error("Value expected to be 0 or 1 representing a boolean")] - InvalidBool, -} -#[derive(Debug, thiserror::Error)] -#[error(transparent)] -pub(crate) struct BackendError(#[from] Error); - -impl From for BackendError { - fn from(value: FeatureError) -> Self { - BackendError(Error::FromFeature(value)) - } -} - -#[derive(Debug)] -pub(crate) struct Barretenberg { - store: std::cell::RefCell, - memory: wasmer::Memory, - instance: wasmer::Instance, -} - -use std::cell::RefCell; - -use wasmer::{ - imports, Function, FunctionEnv, FunctionEnvMut, Imports, Instance, Memory, MemoryType, Store, - Value, WasmPtr, -}; - -/// The number of bytes necessary to represent a pointer to memory inside the wasm. -// pub(super) const POINTER_BYTES: usize = 4; - -/// The Barretenberg WASM gives us 1024 bytes of scratch space which we can use without -/// needing to allocate/free it ourselves. This can be useful for when we need to pass in several small variables -/// when calling functions on the wasm, however it's important to not overrun this scratch space as otherwise -/// the written data will begin to corrupt the stack. -/// -/// Using this scratch space isn't particularly safe if we have multiple threads interacting with the wasm however, -/// each thread could write to the same pointer address simultaneously. -pub(super) const WASM_SCRATCH_BYTES: usize = 1024; - -/// Embed the Barretenberg WASM file -const WASM_BIN: &[u8] = include_bytes!("./acvm_backend.wasm"); - -impl Barretenberg { - #[cfg(not(target_arch = "wasm32"))] - pub(crate) fn new() -> Barretenberg { - let (instance, memory, store) = instance_load(); - let barretenberg = Barretenberg { memory, instance, store: RefCell::new(store) }; - barretenberg.call_wasi_initialize(); - barretenberg - } - - #[cfg(target_arch = "wasm32")] - pub(crate) async fn initialize() -> Barretenberg { - let (instance, memory, store) = instance_load().await; - let barretenberg = Barretenberg { memory, instance, store: RefCell::new(store) }; - barretenberg.call_wasi_initialize(); - barretenberg - } - /// Call initialization function for WASI, to initialize all of the appropriate - /// globals. - fn call_wasi_initialize(&self) { - self.call_multiple("_initialize", vec![]) - .expect("expected call to WASI initialization function to not fail"); - } -} - -/// A wrapper around the arguments or return value from a WASM call. -/// Notice, `Option` is used because not every call returns a value, -/// some calls are simply made to free a pointer or manipulate the heap. -#[derive(Debug, Clone)] -pub(crate) struct WASMValue(Option); - -impl From for WASMValue { - fn from(value: usize) -> Self { - WASMValue(Some(Value::I32(value as i32))) - } -} - -impl From for WASMValue { - fn from(value: u32) -> Self { - WASMValue(Some(Value::I32(value as i32))) - } -} - -impl From for WASMValue { - fn from(value: i32) -> Self { - WASMValue(Some(Value::I32(value))) - } -} - -impl From for WASMValue { - fn from(value: Value) -> Self { - WASMValue(Some(value)) - } -} - -impl TryFrom for bool { - type Error = FeatureError; - - fn try_from(value: WASMValue) -> Result { - match value.try_into()? { - 0 => Ok(false), - 1 => Ok(true), - _ => Err(FeatureError::InvalidBool), - } - } -} - -impl TryFrom for usize { - type Error = FeatureError; - - fn try_from(value: WASMValue) -> Result { - let value: i32 = value.try_into()?; - value.try_into().map_err(|source| FeatureError::InvalidUsize { value, source }) - } -} - -impl TryFrom for u32 { - type Error = FeatureError; - - fn try_from(value: WASMValue) -> Result { - let value = value.try_into()?; - u32::try_from(value).map_err(|source| FeatureError::InvalidU32 { value, source }) - } -} - -impl TryFrom for i32 { - type Error = FeatureError; - - fn try_from(value: WASMValue) -> Result { - value.0.map_or(Err(FeatureError::NoValue), |val| val.i32().ok_or(FeatureError::InvalidI32)) - } -} - -impl TryFrom for Value { - type Error = FeatureError; - - fn try_from(value: WASMValue) -> Result { - value.0.ok_or(FeatureError::NoValue) - } -} - -impl Barretenberg { - /// Transfer bytes to WASM heap - // TODO: Consider making this Result-returning - pub(crate) fn transfer_to_heap(&self, data: &[u8], offset: usize) { - let memory = &self.memory; - let store = self.store.borrow(); - let memory_view = memory.view(&store); - - memory_view.write(offset as u64, data).unwrap(); - } - - // TODO: Consider making this Result-returning - pub(crate) fn read_memory(&self, start: usize) -> [u8; SIZE] { - self.read_memory_variable_length(start, SIZE) - .try_into() - .expect("Read memory should be of the specified length") - } - - // TODO: Consider making this Result-returning - pub(crate) fn read_memory_variable_length(&self, offset: usize, length: usize) -> Vec { - let memory = &self.memory; - let store = &self.store.borrow(); - let memory_view = memory.view(&store); - - let mut buf = vec![0; length]; - - memory_view.read(offset as u64, &mut buf).unwrap(); - buf - } - - pub(crate) fn call_multiple( - &self, - name: &str, - params: Vec<&WASMValue>, - ) -> Result { - // We take in a reference to values, since they do not implement Copy. - // We then clone them inside of this function, so that the API does not have a bunch of Clones everywhere - - let mut args: Vec = vec![]; - for param in params.into_iter().cloned() { - args.push(param.try_into()?); - } - let func = self - .instance - .exports - .get_function(name) - .map_err(|source| FeatureError::InvalidExport { name: name.to_string(), source })?; - let boxed_value = func.call(&mut self.store.borrow_mut(), &args).map_err(|source| { - FeatureError::FunctionCallFailed { name: name.to_string(), source } - })?; - let option_value = boxed_value.first().cloned(); - - Ok(WASMValue(option_value)) - } -} - -fn init_memory_and_state() -> (Memory, Store, Imports) { - let mut store = Store::default(); - - let mem_type = MemoryType::new(18, Some(65536), false); - let memory = Memory::new(&mut store, mem_type).unwrap(); - - let function_env = FunctionEnv::new(&mut store, memory.clone()); - let custom_imports = imports! { - "env" => { - "logstr" => Function::new_typed_with_env( - &mut store, - &function_env, - logstr, - ), - "memory" => memory.clone(), - }, - "wasi_snapshot_preview1" => { - "proc_exit" => Function::new_typed(&mut store, proc_exit), - "random_get" => Function::new_typed_with_env( - &mut store, - &function_env, - random_get - ), - }, - }; - - (memory, store, custom_imports) -} - -#[cfg(not(target_arch = "wasm32"))] -fn instance_load() -> (Instance, Memory, Store) { - use wasmer::Module; - - let (memory, mut store, custom_imports) = init_memory_and_state(); - - let module = Module::new(&store, WASM_BIN).unwrap(); - - (Instance::new(&mut store, &module, &custom_imports).unwrap(), memory, store) -} - -#[cfg(target_arch = "wasm32")] -async fn instance_load() -> (Instance, Memory, Store) { - use js_sys::WebAssembly::{self}; - use wasmer::AsJs; - - let (memory, mut store, custom_imports) = init_memory_and_state(); - - let js_bytes = unsafe { js_sys::Uint8Array::view(&WASM_BIN) }; - let js_module_promise = WebAssembly::compile(&js_bytes); - let js_module: js_sys::WebAssembly::Module = - wasm_bindgen_futures::JsFuture::from(js_module_promise).await.unwrap().into(); - - let js_instance_promise = - WebAssembly::instantiate_module(&js_module, &custom_imports.as_jsvalue(&store).into()); - let js_instance = wasm_bindgen_futures::JsFuture::from(js_instance_promise).await.unwrap(); - let module = wasmer::Module::from((js_module, WASM_BIN)); - let instance: wasmer::Instance = Instance::from_jsvalue(&mut store, &module, &js_instance) - .map_err(|_| "Error while creating BlackBox Functions vendor instance") - .unwrap(); - - (instance, memory, store) -} - -fn logstr(mut env: FunctionEnvMut, ptr: i32) { - let (memory, store) = env.data_and_store_mut(); - let memory_view = memory.view(&store); - - let log_str_wasm_ptr: WasmPtr = WasmPtr::new(ptr as u32); - - match log_str_wasm_ptr.read_utf8_string_with_nul(&memory_view) { - Ok(log_string) => println!("{log_string}"), - Err(err) => println!("Error while reading log string from memory: {err}"), - }; -} - -// Based on https://github.com/wasmerio/wasmer/blob/2.3.0/lib/wasi/src/syscalls/mod.rs#L2537 -fn random_get(mut env: FunctionEnvMut, buf_ptr: i32, buf_len: i32) -> i32 { - let mut u8_buffer = vec![0; buf_len as usize]; - let res = getrandom::getrandom(&mut u8_buffer); - match res { - Ok(()) => { - let (memory, store) = env.data_and_store_mut(); - let memory_view = memory.view(&store); - match memory_view.write(buf_ptr as u64, u8_buffer.as_mut_slice()) { - Ok(_) => { - 0_i32 // __WASI_ESUCCESS - } - Err(_) => { - 29_i32 // __WASI_EIO - } - } - } - Err(_) => { - 29_i32 // __WASI_EIO - } - } -} - -fn proc_exit(_: i32) { - unimplemented!("proc_exit is not implemented") -} diff --git a/acvm-repo/bn254_blackbox_solver/src/wasm/schnorr.rs b/acvm-repo/bn254_blackbox_solver/src/wasm/schnorr.rs deleted file mode 100644 index 18c4f04ef64..00000000000 --- a/acvm-repo/bn254_blackbox_solver/src/wasm/schnorr.rs +++ /dev/null @@ -1,104 +0,0 @@ -use super::{Barretenberg, Error, FIELD_BYTES, WASM_SCRATCH_BYTES}; - -pub(crate) trait SchnorrSig { - fn construct_signature( - &self, - message: &[u8], - private_key: [u8; 32], - ) -> Result<([u8; 32], [u8; 32]), Error>; - fn construct_public_key(&self, private_key: [u8; 32]) -> Result<[u8; 64], Error>; - fn verify_signature( - &self, - pub_key: [u8; 64], - sig_s: [u8; 32], - sig_e: [u8; 32], - message: &[u8], - ) -> Result; -} - -impl SchnorrSig for Barretenberg { - fn construct_signature( - &self, - message: &[u8], - private_key: [u8; 32], - ) -> Result<([u8; 32], [u8; 32]), Error> { - let sig_s_ptr: usize = 0; - let sig_e_ptr: usize = sig_s_ptr + FIELD_BYTES; - let private_key_ptr: usize = sig_e_ptr + FIELD_BYTES; - let message_ptr: usize = private_key_ptr + private_key.len(); - assert!( - message_ptr + message.len() < WASM_SCRATCH_BYTES, - "Message overran wasm scratch space" - ); - - self.transfer_to_heap(&private_key, private_key_ptr); - self.transfer_to_heap(message, message_ptr); - self.call_multiple( - "construct_signature", - vec![ - &message_ptr.into(), - &message.len().into(), - &private_key_ptr.into(), - &sig_s_ptr.into(), - &sig_e_ptr.into(), - ], - )?; - - let sig_s: [u8; FIELD_BYTES] = self.read_memory(sig_s_ptr); - let sig_e: [u8; FIELD_BYTES] = self.read_memory(sig_e_ptr); - - Ok((sig_s, sig_e)) - } - - #[allow(dead_code)] - fn construct_public_key(&self, private_key: [u8; 32]) -> Result<[u8; 64], Error> { - let private_key_ptr: usize = 0; - let result_ptr: usize = private_key_ptr + FIELD_BYTES; - - self.transfer_to_heap(&private_key, private_key_ptr); - - self.call_multiple( - "compute_public_key", - vec![&private_key_ptr.into(), &result_ptr.into()], - )?; - - Ok(self.read_memory(result_ptr)) - } - - fn verify_signature( - &self, - pub_key: [u8; 64], - sig_s: [u8; 32], - sig_e: [u8; 32], - message: &[u8], - ) -> Result { - let public_key_ptr: usize = 0; - let sig_s_ptr: usize = public_key_ptr + pub_key.len(); - let sig_e_ptr: usize = sig_s_ptr + sig_s.len(); - let message_ptr: usize = sig_e_ptr + sig_e.len(); - assert!( - message_ptr + message.len() < WASM_SCRATCH_BYTES, - "Message overran wasm scratch space" - ); - - self.transfer_to_heap(&pub_key, public_key_ptr); - self.transfer_to_heap(&sig_s, sig_s_ptr); - self.transfer_to_heap(&sig_e, sig_e_ptr); - self.transfer_to_heap(message, message_ptr); - - let verified = self.call_multiple( - "verify_signature", - vec![ - &message_ptr.into(), - &message.len().into(), - &public_key_ptr.into(), - &sig_s_ptr.into(), - &sig_e_ptr.into(), - ], - )?; - - // Note, currently for Barretenberg plonk, if the signature fails - // then the whole circuit fails. - Ok(verified.try_into()?) - } -} From aea60c0ca75a5b7d66085e40bfbe481f016114f2 Mon Sep 17 00:00:00 2001 From: jfecher Date: Tue, 21 May 2024 10:45:07 -0500 Subject: [PATCH 10/61] chore(experimental): Elaborate impls & non-trait impls (#5007) # Description ## Problem\* Working towards #4594 ## Summary\* Adds support for impls and trait impls to the elaborator. This was somewhat satisfying to add since the existing code for this in `dc_crate.rs` is very messy & long winded due to our current design of creating a new `NameResolver` for every resolution. Keeping everything in the same elaborator and not needing to keep setting the interner, def maps, current crate, module, generics, append errors, etc saved many lines. I think this implementation is roughly half the size as a result. ## Additional Context Still need types, type aliases, and globals after this. The pass is testable after that but is expected to fail the comptime tests at least. So I'll need to inline the comptime scanning pass in the elaborator as well. After that the pass is theoretically done but realistically there will be bugs to fix before we can make it the default. ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_frontend/src/elaborator/mod.rs | 355 +++++++++++++++++- .../src/hir/def_collector/dc_crate.rs | 4 + 2 files changed, 342 insertions(+), 17 deletions(-) diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index 446e5b62ead..0f9d22ca9b5 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -4,14 +4,13 @@ use std::{ rc::Rc, }; -use crate::hir::def_map::CrateDefMap; use crate::{ ast::{ ArrayLiteral, ConstructorExpression, FunctionKind, IfExpression, InfixExpression, Lambda, UnresolvedTraitConstraint, UnresolvedTypeExpression, }, hir::{ - def_collector::dc_crate::CompilationError, + def_collector::{dc_crate::CompilationError, errors::DuplicateType}, resolution::{errors::ResolverError, path_resolver::PathResolver, resolver::LambdaContext}, scope::ScopeForest as GenericScopeForest, type_check::TypeCheckError, @@ -56,6 +55,14 @@ use crate::{ token::FunctionAttribute, Generics, }; +use crate::{ + hir::{ + def_collector::dc_crate::{UnresolvedFunctions, UnresolvedTraitImpl}, + def_map::{CrateDefMap, ModuleData}, + }, + hir_def::traits::TraitImpl, + macros_api::ItemVisibility, +}; mod expressions; mod patterns; @@ -86,7 +93,7 @@ pub struct Elaborator<'context> { interner: &'context mut NodeInterner, - def_maps: &'context BTreeMap, + def_maps: &'context mut BTreeMap, file: FileId, @@ -168,7 +175,7 @@ impl<'context> Elaborator<'context> { scopes: ScopeForest::default(), errors: Vec::new(), interner: &mut context.def_interner, - def_maps: &context.def_maps, + def_maps: &mut context.def_maps, file: FileId::dummy(), in_unconstrained_fn: false, nested_loops: 0, @@ -192,7 +199,7 @@ impl<'context> Elaborator<'context> { pub fn elaborate( context: &'context mut Context, crate_id: CrateId, - items: CollectedItems, + mut items: CollectedItems, ) -> Vec<(CompilationError, FileId)> { let mut this = Self::new(context, crate_id); @@ -205,28 +212,27 @@ impl<'context> Elaborator<'context> { for struct_ in items.types {} - for trait_impl in &items.trait_impls { - // only collect now + for trait_impl in &mut items.trait_impls { + this.collect_trait_impl(trait_impl); } - for impl_ in &items.impls { - // only collect now + for ((typ, module), impls) in &items.impls { + this.collect_impls(typ, *module, impls); } // resolver resolves non-literal globals here for functions in items.functions { - this.file = functions.file_id; - this.trait_id = functions.trait_id; // TODO: Resolve? - for (local_module, id, func) in functions.functions { - this.local_module = local_module; - this.elaborate_function(func, id); - } + this.elaborate_functions(functions); } - for impl_ in items.impls {} + for ((typ, module), impls) in items.impls { + this.elaborate_impls(typ, module, impls); + } - for trait_impl in items.trait_impls {} + for trait_impl in items.trait_impls { + this.elaborate_trait_impl(trait_impl); + } let cycle_errors = this.interner.check_for_dependency_cycles(); this.errors.extend(cycle_errors); @@ -234,6 +240,17 @@ impl<'context> Elaborator<'context> { this.errors } + fn elaborate_functions(&mut self, functions: UnresolvedFunctions) { + self.file = functions.file_id; + self.trait_id = functions.trait_id; // TODO: Resolve? + for (local_module, id, func) in functions.functions { + self.local_module = local_module; + let generics_count = self.generics.len(); + self.elaborate_function(func, id); + self.generics.truncate(generics_count); + } + } + fn elaborate_function(&mut self, mut function: NoirFunction, id: FuncId) { self.current_function = Some(id); self.resolve_where_clause(&mut function.def.where_clause); @@ -779,4 +796,308 @@ impl<'context> Elaborator<'context> { } } } + + fn elaborate_impls( + &mut self, + typ: UnresolvedType, + module: LocalModuleId, + impls: Vec<(Vec, Span, UnresolvedFunctions)>, + ) { + self.generics.clear(); + + for (generics, _, functions) in impls { + self.file = functions.file_id; + self.add_generics(&generics); + let self_type = self.resolve_type(typ.clone()); + self.self_type = Some(self_type.clone()); + + let function_ids = vecmap(&functions.functions, |(_, id, _)| *id); + self.elaborate_functions(functions); + + if self_type != Type::Error { + for method_id in function_ids { + let method_name = self.interner.function_name(&method_id).to_owned(); + + if let Some(first_fn) = + self.interner.add_method(&self_type, method_name.clone(), method_id, false) + { + let error = ResolverError::DuplicateDefinition { + name: method_name, + first_span: self.interner.function_ident(&first_fn).span(), + second_span: self.interner.function_ident(&method_id).span(), + }; + self.push_err(error); + } + } + } + } + } + + fn elaborate_trait_impl(&mut self, trait_impl: UnresolvedTraitImpl) { + self.file = trait_impl.file_id; + self.local_module = trait_impl.module_id; + + let unresolved_type = trait_impl.object_type; + let self_type_span = unresolved_type.span; + self.add_generics(&trait_impl.generics); + + let trait_generics = + vecmap(&trait_impl.trait_generics, |generic| self.resolve_type(generic.clone())); + + let self_type = self.resolve_type(unresolved_type.clone()); + let impl_id = self.interner.next_trait_impl_id(); + + self.self_type = Some(self_type.clone()); + self.current_trait_impl = Some(impl_id); + + let mut methods = trait_impl.methods.function_ids(); + + self.elaborate_functions(trait_impl.methods); + + if matches!(self_type, Type::MutableReference(_)) { + let span = self_type_span.unwrap_or_else(|| trait_impl.trait_path.span()); + self.push_err(DefCollectorErrorKind::MutableReferenceInTraitImpl { span }); + } + + if let Some(trait_id) = trait_impl.trait_id { + for func_id in &methods { + self.interner.set_function_trait(*func_id, self_type.clone(), trait_id); + } + + let where_clause = trait_impl + .where_clause + .into_iter() + .flat_map(|item| self.resolve_trait_constraint(item)) + .collect(); + + let resolved_trait_impl = Shared::new(TraitImpl { + ident: trait_impl.trait_path.last_segment().clone(), + typ: self_type.clone(), + trait_id, + trait_generics: trait_generics.clone(), + file: trait_impl.file_id, + where_clause, + methods, + }); + + let generics = vecmap(&self.generics, |(_, type_variable, _)| type_variable.clone()); + + if let Err((prev_span, prev_file)) = self.interner.add_trait_implementation( + self_type.clone(), + trait_id, + trait_generics, + impl_id, + generics, + resolved_trait_impl, + ) { + self.push_err(DefCollectorErrorKind::OverlappingImpl { + typ: self_type.clone(), + span: self_type_span.unwrap_or_else(|| trait_impl.trait_path.span()), + }); + + // The 'previous impl defined here' note must be a separate error currently + // since it may be in a different file and all errors have the same file id. + self.file = prev_file; + self.push_err(DefCollectorErrorKind::OverlappingImplNote { span: prev_span }); + self.file = trait_impl.file_id; + } + } + + self.self_type = None; + self.current_trait_impl = None; + self.generics.clear(); + } + + fn collect_impls( + &mut self, + self_type: &UnresolvedType, + module: LocalModuleId, + impls: &[(Vec, Span, UnresolvedFunctions)], + ) { + self.local_module = module; + + for (generics, span, unresolved) in impls { + self.file = unresolved.file_id; + self.declare_method_on_struct(self_type, generics, false, unresolved, *span); + } + } + + fn collect_trait_impl(&mut self, trait_impl: &mut UnresolvedTraitImpl) { + self.local_module = trait_impl.module_id; + self.file = trait_impl.file_id; + trait_impl.trait_id = self.resolve_trait_by_path(trait_impl.trait_path.clone()); + + if let Some(trait_id) = trait_impl.trait_id { + self.collect_trait_impl_methods(trait_id, trait_impl); + + let span = trait_impl.object_type.span.expect("All trait self types should have spans"); + let object_type = &trait_impl.object_type; + let generics = &trait_impl.generics; + self.declare_method_on_struct(object_type, generics, true, &trait_impl.methods, span); + } + } + + fn get_module_mut(&mut self, module: ModuleId) -> &mut ModuleData { + let message = "A crate should always be present for a given crate id"; + &mut self.def_maps.get_mut(&module.krate).expect(message).modules[module.local_id.0] + } + + fn declare_method_on_struct( + &mut self, + self_type: &UnresolvedType, + generics: &UnresolvedGenerics, + is_trait_impl: bool, + functions: &UnresolvedFunctions, + span: Span, + ) { + let generic_count = self.generics.len(); + self.add_generics(generics); + let typ = self.resolve_type(self_type.clone()); + + if let Type::Struct(struct_type, _generics) = typ { + let struct_type = struct_type.borrow(); + + // `impl`s are only allowed on types defined within the current crate + if !is_trait_impl && struct_type.id.krate() != self.crate_id { + let type_name = struct_type.name.to_string(); + self.push_err(DefCollectorErrorKind::ForeignImpl { span, type_name }); + self.generics.truncate(generic_count); + return; + } + + // Grab the module defined by the struct type. Note that impls are a case + // where the module the methods are added to is not the same as the module + // they are resolved in. + let module = self.get_module_mut(struct_type.id.module_id()); + + for (_, method_id, method) in &functions.functions { + // If this method was already declared, remove it from the module so it cannot + // be accessed with the `TypeName::method` syntax. We'll check later whether the + // object types in each method overlap or not. If they do, we issue an error. + // If not, that is specialization which is allowed. + let name = method.name_ident().clone(); + if module.declare_function(name, ItemVisibility::Public, *method_id).is_err() { + module.remove_function(method.name_ident()); + } + } + // Prohibit defining impls for primitive types if we're not in the stdlib + } else if !is_trait_impl && typ != Type::Error && !self.crate_id.is_stdlib() { + self.push_err(DefCollectorErrorKind::NonStructTypeInImpl { span }); + } + self.generics.truncate(generic_count); + } + + fn collect_trait_impl_methods( + &mut self, + trait_id: TraitId, + trait_impl: &mut UnresolvedTraitImpl, + ) { + self.local_module = trait_impl.module_id; + self.file = trait_impl.file_id; + + // In this Vec methods[i] corresponds to trait.methods[i]. If the impl has no implementation + // for a particular method, the default implementation will be added at that slot. + let mut ordered_methods = Vec::new(); + + // check whether the trait implementation is in the same crate as either the trait or the type + self.check_trait_impl_crate_coherence(trait_id, trait_impl); + + // set of function ids that have a corresponding method in the trait + let mut func_ids_in_trait = HashSet::default(); + + // Temporarily take ownership of the trait's methods so we can iterate over them + // while also mutating the interner + let the_trait = self.interner.get_trait_mut(trait_id); + let methods = std::mem::take(&mut the_trait.methods); + + for method in &methods { + let overrides: Vec<_> = trait_impl + .methods + .functions + .iter() + .filter(|(_, _, f)| f.name() == method.name.0.contents) + .collect(); + + if overrides.is_empty() { + if let Some(default_impl) = &method.default_impl { + // copy 'where' clause from unresolved trait impl + let mut default_impl_clone = default_impl.clone(); + default_impl_clone.def.where_clause.extend(trait_impl.where_clause.clone()); + + let func_id = self.interner.push_empty_fn(); + let module = self.module_id(); + let location = Location::new(default_impl.def.span, trait_impl.file_id); + self.interner.push_function(func_id, &default_impl.def, module, location); + func_ids_in_trait.insert(func_id); + ordered_methods.push(( + method.default_impl_module_id, + func_id, + *default_impl_clone, + )); + } else { + self.push_err(DefCollectorErrorKind::TraitMissingMethod { + trait_name: self.interner.get_trait(trait_id).name.clone(), + method_name: method.name.clone(), + trait_impl_span: trait_impl + .object_type + .span + .expect("type must have a span"), + }); + } + } else { + for (_, func_id, _) in &overrides { + func_ids_in_trait.insert(*func_id); + } + + if overrides.len() > 1 { + self.push_err(DefCollectorErrorKind::Duplicate { + typ: DuplicateType::TraitAssociatedFunction, + first_def: overrides[0].2.name_ident().clone(), + second_def: overrides[1].2.name_ident().clone(), + }); + } + + ordered_methods.push(overrides[0].clone()); + } + } + + // Restore the methods that were taken before the for loop + let the_trait = self.interner.get_trait_mut(trait_id); + the_trait.set_methods(methods); + + // Emit MethodNotInTrait error for methods in the impl block that + // don't have a corresponding method signature defined in the trait + for (_, func_id, func) in &trait_impl.methods.functions { + if !func_ids_in_trait.contains(func_id) { + let trait_name = the_trait.name.clone(); + let impl_method = func.name_ident().clone(); + let error = DefCollectorErrorKind::MethodNotInTrait { trait_name, impl_method }; + self.errors.push((error.into(), self.file)); + } + } + + trait_impl.methods.functions = ordered_methods; + trait_impl.methods.trait_id = Some(trait_id); + } + + fn check_trait_impl_crate_coherence( + &mut self, + trait_id: TraitId, + trait_impl: &UnresolvedTraitImpl, + ) { + self.local_module = trait_impl.module_id; + self.file = trait_impl.file_id; + + let object_crate = match self.resolve_type(trait_impl.object_type.clone()) { + Type::Struct(struct_type, _) => struct_type.borrow().id.krate(), + _ => CrateId::Dummy, + }; + + let the_trait = self.interner.get_trait(trait_id); + if self.crate_id != the_trait.crate_id && self.crate_id != object_crate { + self.push_err(DefCollectorErrorKind::TraitImplOrphaned { + span: trait_impl.object_type.span.expect("object type must have a span"), + }); + } + } } diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index 4aac0fec9c3..d2eaf79b0f0 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -54,6 +54,10 @@ impl UnresolvedFunctions { self.functions.push((mod_id, func_id, func)); } + pub fn function_ids(&self) -> Vec { + vecmap(&self.functions, |(_, id, _)| *id) + } + pub fn resolve_trait_bounds_trait_ids( &mut self, def_maps: &BTreeMap, From faf5bd8ed80fb89b4bb6a2536b9bfa9649579da7 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 21 May 2024 17:12:07 +0100 Subject: [PATCH 11/61] feat: add `as_witness` builtin function in order to constrain a witness to be equal to a variable (#4641) # Description ## Problem\* Quick fix to #4629 ## Summary\* This PR adds a `as_witness` function which takes a `Field` and instructs the compiler to lay down an opcode which constrains a witness to be equal to this value. This prevents the issue in #4629 where we collect ever growing expressions which need to be broken down multiple times while reshaping the circuit. Doing this during acirgen instead allows us to avoid this repetition. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [x] **[For Experimental Features]** Documentation to be submitted in a separate PR. Feature is experimental # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../src/ssa/acir_gen/acir_ir/acir_variable.rs | 5 ++++- compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs | 9 +++++++++ compiler/noirc_evaluator/src/ssa/ir/instruction.rs | 7 ++++++- compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs | 1 + .../src/ssa/opt/remove_enable_side_effects.rs | 3 ++- compiler/noirc_evaluator/src/ssa/opt/remove_if_else.rs | 3 ++- noir_stdlib/src/lib.nr | 3 +++ 7 files changed, 27 insertions(+), 4 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index 407cdf0a17f..5f180edd05c 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -236,7 +236,10 @@ impl AcirContext { self.acir_ir.call_stack = call_stack; } - fn get_or_create_witness_var(&mut self, var: AcirVar) -> Result { + pub(crate) fn get_or_create_witness_var( + &mut self, + var: AcirVar, + ) -> Result { if self.var_to_expression(var)?.to_witness().is_some() { // If called with a variable which is already a witness then return the same variable. return Ok(var); diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index 05d2e3e3e6a..2430a00fd4c 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -2605,6 +2605,15 @@ impl<'a> Context<'a> { Ok(result) } + + Intrinsic::AsWitness => { + let arg = arguments[0]; + let input = self.convert_value(arg, dfg).into_var()?; + Ok(self + .acir_context + .get_or_create_witness_var(input) + .map(|val| self.convert_vars_to_values(vec![val], dfg, result_ids))?) + } _ => todo!("expected a black box function"), } } diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs index 7cc19e9f2b8..f136d3c5fb2 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -64,6 +64,7 @@ pub(crate) enum Intrinsic { BlackBox(BlackBoxFunc), FromField, AsField, + AsWitness, } impl std::fmt::Display for Intrinsic { @@ -87,6 +88,7 @@ impl std::fmt::Display for Intrinsic { Intrinsic::BlackBox(function) => write!(f, "{function}"), Intrinsic::FromField => write!(f, "from_field"), Intrinsic::AsField => write!(f, "as_field"), + Intrinsic::AsWitness => write!(f, "as_witness"), } } } @@ -97,7 +99,9 @@ impl Intrinsic { /// If there are no side effects then the `Intrinsic` can be removed if the result is unused. pub(crate) fn has_side_effects(&self) -> bool { match self { - Intrinsic::AssertConstant | Intrinsic::ApplyRangeConstraint => true, + Intrinsic::AssertConstant | Intrinsic::ApplyRangeConstraint | Intrinsic::AsWitness => { + true + } // These apply a constraint that the input must fit into a specified number of limbs. Intrinsic::ToBits(_) | Intrinsic::ToRadix(_) => true, @@ -140,6 +144,7 @@ impl Intrinsic { "to_be_bits" => Some(Intrinsic::ToBits(Endian::Big)), "from_field" => Some(Intrinsic::FromField), "as_field" => Some(Intrinsic::AsField), + "as_witness" => Some(Intrinsic::AsWitness), other => BlackBoxFunc::lookup(other).map(Intrinsic::BlackBox), } } diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs index 7ad6a625f9c..8e320de9337 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs @@ -293,6 +293,7 @@ pub(super) fn simplify_call( let instruction = Instruction::Cast(truncated_value, target_type); SimplifyResult::SimplifiedToInstruction(instruction) } + Intrinsic::AsWitness => SimplifyResult::None, } } diff --git a/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs b/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs index ea37d857e58..9309652d508 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs @@ -157,7 +157,8 @@ impl Context { | Intrinsic::BlackBox(_) | Intrinsic::FromField | Intrinsic::AsField - | Intrinsic::AsSlice => false, + | Intrinsic::AsSlice + | Intrinsic::AsWitness => false, }, // We must assume that functions contain a side effect as we cannot inspect more deeply. diff --git a/compiler/noirc_evaluator/src/ssa/opt/remove_if_else.rs b/compiler/noirc_evaluator/src/ssa/opt/remove_if_else.rs index fc915756110..3d2b5142219 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/remove_if_else.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/remove_if_else.rs @@ -231,6 +231,7 @@ fn slice_capacity_change( | Intrinsic::StrAsBytes | Intrinsic::BlackBox(_) | Intrinsic::FromField - | Intrinsic::AsField => SizeChange::None, + | Intrinsic::AsField + | Intrinsic::AsWitness => SizeChange::None, } } diff --git a/noir_stdlib/src/lib.nr b/noir_stdlib/src/lib.nr index 33504be0b9a..4e83fc59276 100644 --- a/noir_stdlib/src/lib.nr +++ b/noir_stdlib/src/lib.nr @@ -67,3 +67,6 @@ pub fn wrapping_sub(x: T, y: T) -> T { pub fn wrapping_mul(x: T, y: T) -> T { crate::from_field(crate::as_field(x) * crate::as_field(y)) } + +#[builtin(as_witness)] +pub fn as_witness(x: Field) {} \ No newline at end of file From 226724e3b54c2e0d9ba005661c76b40a87d9295a Mon Sep 17 00:00:00 2001 From: jfecher Date: Tue, 21 May 2024 12:30:36 -0500 Subject: [PATCH 12/61] feat: Implement turbofish operator (#3542) # Description ## Problem\* Resolves #3413 ## Summary\* Adds the turbofish operator `::<>` to variables and method calls in Noir. ## Additional Context I'm publishing this as a draft because I'm shelving this work for now after implementing the majority of it. The work that remains to be done is handling the special case of method calls on generic impls. A generic impl will implicitly add the impl generics to each method - which means the generic count on a method itself as seen by the turbofish operator will not match the actual generics on the function internally. We'll likely need to separate out these implicit generics internally. Such that `expected_generic_count = function_generics - impl_generics`. I've added this as a test case to the `generics` test to ensure it works when this is merged. ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [x] **[Exceptional Case]** Documentation to be submitted in a separate PR. - [x] No documentation is in this PR yet since it is still a draft. # PR Checklist\* - [x] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Tom French Co-authored-by: Maxim Vezenov --- aztec_macros/src/transforms/functions.rs | 2 +- aztec_macros/src/utils/ast_utils.rs | 7 +- compiler/noirc_frontend/src/ast/expression.rs | 34 ++++++--- compiler/noirc_frontend/src/ast/mod.rs | 6 +- compiler/noirc_frontend/src/ast/statement.rs | 30 ++++---- compiler/noirc_frontend/src/debug/mod.rs | 74 +++++++++++-------- .../src/elaborator/expressions.rs | 15 +++- .../noirc_frontend/src/elaborator/patterns.rs | 8 +- .../noirc_frontend/src/elaborator/types.rs | 6 +- .../src/hir/comptime/hir_to_ast.rs | 10 ++- .../src/hir/comptime/interpreter.rs | 2 +- .../noirc_frontend/src/hir/comptime/scan.rs | 2 +- .../noirc_frontend/src/hir/comptime/value.rs | 2 +- .../src/hir/def_collector/dc_mod.rs | 1 + .../src/hir/resolution/resolver.rs | 36 ++++++--- .../src/hir/type_check/errors.rs | 10 +++ .../noirc_frontend/src/hir/type_check/expr.rs | 56 ++++++++++++-- .../noirc_frontend/src/hir/type_check/mod.rs | 5 +- compiler/noirc_frontend/src/hir_def/expr.rs | 8 +- compiler/noirc_frontend/src/hir_def/types.rs | 39 +++++++++- .../src/monomorphization/mod.rs | 4 +- compiler/noirc_frontend/src/node_interner.rs | 4 + compiler/noirc_frontend/src/parser/parser.rs | 56 ++++++++------ .../src/parser/parser/primitives.rs | 15 +++- .../noirc_frontend/src/resolve_locations.rs | 2 +- compiler/noirc_frontend/src/tests.rs | 65 ++++++++++++++++ cspell.json | 1 + .../turbofish_generic_count/Nargo.toml | 7 ++ .../turbofish_generic_count/src/main.nr | 22 ++++++ .../execution_success/generics/src/main.nr | 15 ++++ tooling/nargo_fmt/src/rewrite/expr.rs | 35 ++++++++- .../tests/expected/turbofish_call.nr | 8 ++ .../tests/expected/turbofish_method_call.nr | 12 +++ .../nargo_fmt/tests/input/turbofish_call.nr | 7 ++ .../tests/input/turbofish_method_call.nr | 5 ++ 35 files changed, 486 insertions(+), 125 deletions(-) create mode 100644 test_programs/compile_failure/turbofish_generic_count/Nargo.toml create mode 100644 test_programs/compile_failure/turbofish_generic_count/src/main.nr create mode 100644 tooling/nargo_fmt/tests/expected/turbofish_call.nr create mode 100644 tooling/nargo_fmt/tests/expected/turbofish_method_call.nr create mode 100644 tooling/nargo_fmt/tests/input/turbofish_call.nr create mode 100644 tooling/nargo_fmt/tests/input/turbofish_method_call.nr diff --git a/aztec_macros/src/transforms/functions.rs b/aztec_macros/src/transforms/functions.rs index 90563c6085c..39d709ef520 100644 --- a/aztec_macros/src/transforms/functions.rs +++ b/aztec_macros/src/transforms/functions.rs @@ -680,7 +680,7 @@ fn add_struct_to_hasher(identifier: &Ident, hasher_name: &str) -> Statement { fn str_to_bytes(identifier: &Ident) -> (Statement, Ident) { // let identifier_as_bytes = identifier.as_bytes(); let var = variable_ident(identifier.clone()); - let contents = if let ExpressionKind::Variable(p) = &var.kind { + let contents = if let ExpressionKind::Variable(p, _) = &var.kind { p.segments.first().cloned().unwrap_or_else(|| panic!("No segments")).0.contents } else { panic!("Unexpected identifier type") diff --git a/aztec_macros/src/utils/ast_utils.rs b/aztec_macros/src/utils/ast_utils.rs index ebb4854f86e..ba51090c2be 100644 --- a/aztec_macros/src/utils/ast_utils.rs +++ b/aztec_macros/src/utils/ast_utils.rs @@ -27,15 +27,15 @@ pub fn expression(kind: ExpressionKind) -> Expression { } pub fn variable(name: &str) -> Expression { - expression(ExpressionKind::Variable(ident_path(name))) + expression(ExpressionKind::Variable(ident_path(name), None)) } pub fn variable_ident(identifier: Ident) -> Expression { - expression(ExpressionKind::Variable(path(identifier))) + expression(ExpressionKind::Variable(path(identifier), None)) } pub fn variable_path(path: Path) -> Expression { - expression(ExpressionKind::Variable(path)) + expression(ExpressionKind::Variable(path, None)) } pub fn method_call( @@ -47,6 +47,7 @@ pub fn method_call( object, method_name: ident(method_name), arguments, + generics: None, }))) } diff --git a/compiler/noirc_frontend/src/ast/expression.rs b/compiler/noirc_frontend/src/ast/expression.rs index 59c04218e2e..0173b17d28f 100644 --- a/compiler/noirc_frontend/src/ast/expression.rs +++ b/compiler/noirc_frontend/src/ast/expression.rs @@ -10,6 +10,8 @@ use acvm::FieldElement; use iter_extended::vecmap; use noirc_errors::{Span, Spanned}; +use super::UnaryRhsMemberAccess; + #[derive(Debug, PartialEq, Eq, Clone)] pub enum ExpressionKind { Literal(Literal), @@ -23,7 +25,9 @@ pub enum ExpressionKind { Cast(Box), Infix(Box), If(Box), - Variable(Path), + // The optional vec here is the optional list of generics + // provided by the turbofish operator, if used + Variable(Path, Option>), Tuple(Vec), Lambda(Box), Parenthesized(Box), @@ -39,7 +43,7 @@ pub type UnresolvedGenerics = Vec; impl ExpressionKind { pub fn into_path(self) -> Option { match self { - ExpressionKind::Variable(path) => Some(path), + ExpressionKind::Variable(path, _) => Some(path), _ => None, } } @@ -164,16 +168,19 @@ impl Expression { pub fn member_access_or_method_call( lhs: Expression, - (rhs, args): (Ident, Option>), + (rhs, args): UnaryRhsMemberAccess, span: Span, ) -> Expression { let kind = match args { None => ExpressionKind::MemberAccess(Box::new(MemberAccessExpression { lhs, rhs })), - Some(arguments) => ExpressionKind::MethodCall(Box::new(MethodCallExpression { - object: lhs, - method_name: rhs, - arguments, - })), + Some((generics, arguments)) => { + ExpressionKind::MethodCall(Box::new(MethodCallExpression { + object: lhs, + method_name: rhs, + generics, + arguments, + })) + } }; Expression::new(kind, span) } @@ -435,6 +442,8 @@ pub struct CallExpression { pub struct MethodCallExpression { pub object: Expression, pub method_name: Ident, + /// Method calls have an optional list of generics if the turbofish operator was used + pub generics: Option>, pub arguments: Vec, } @@ -494,7 +503,14 @@ impl Display for ExpressionKind { Cast(cast) => cast.fmt(f), Infix(infix) => infix.fmt(f), If(if_expr) => if_expr.fmt(f), - Variable(path) => path.fmt(f), + Variable(path, generics) => { + if let Some(generics) = generics { + let generics = vecmap(generics, ToString::to_string); + write!(f, "{path}::<{}>", generics.join(", ")) + } else { + path.fmt(f) + } + } Constructor(constructor) => constructor.fmt(f), MemberAccess(access) => access.fmt(f), Tuple(elements) => { diff --git a/compiler/noirc_frontend/src/ast/mod.rs b/compiler/noirc_frontend/src/ast/mod.rs index 1c5a5c610aa..c3556dac6af 100644 --- a/compiler/noirc_frontend/src/ast/mod.rs +++ b/compiler/noirc_frontend/src/ast/mod.rs @@ -132,6 +132,10 @@ pub struct UnresolvedType { pub span: Option, } +/// Type wrapper for a member access +pub(crate) type UnaryRhsMemberAccess = + (Ident, Option<(Option>, Vec)>); + /// The precursor to TypeExpression, this is the type that the parser allows /// to be used in the length position of an array type. Only constants, variables, /// and numeric binary operators are allowed here. @@ -310,7 +314,7 @@ impl UnresolvedTypeExpression { None => Err(expr), } } - ExpressionKind::Variable(path) => Ok(UnresolvedTypeExpression::Variable(path)), + ExpressionKind::Variable(path, _) => Ok(UnresolvedTypeExpression::Variable(path)), ExpressionKind::Prefix(prefix) if prefix.operator == UnaryOp::Minus => { let lhs = Box::new(UnresolvedTypeExpression::Constant(0, expr.span)); let rhs = Box::new(UnresolvedTypeExpression::from_expr_helper(prefix.rhs)?); diff --git a/compiler/noirc_frontend/src/ast/statement.rs b/compiler/noirc_frontend/src/ast/statement.rs index 94b5841e52c..863615da53d 100644 --- a/compiler/noirc_frontend/src/ast/statement.rs +++ b/compiler/noirc_frontend/src/ast/statement.rs @@ -228,11 +228,10 @@ impl From for Expression { fn from(i: Ident) -> Expression { Expression { span: i.0.span(), - kind: ExpressionKind::Variable(Path { - span: i.span(), - segments: vec![i], - kind: PathKind::Plain, - }), + kind: ExpressionKind::Variable( + Path { span: i.span(), segments: vec![i], kind: PathKind::Plain }, + None, + ), } } } @@ -509,7 +508,7 @@ impl Recoverable for Pattern { impl LValue { fn as_expression(&self) -> Expression { let kind = match self { - LValue::Ident(ident) => ExpressionKind::Variable(Path::from_ident(ident.clone())), + LValue::Ident(ident) => ExpressionKind::Variable(Path::from_ident(ident.clone()), None), LValue::MemberAccess { object, field_name, span: _ } => { ExpressionKind::MemberAccess(Box::new(MemberAccessExpression { lhs: object.as_expression(), @@ -599,15 +598,15 @@ impl ForRange { // array.len() let segments = vec![array_ident]; - let array_ident = ExpressionKind::Variable(Path { - segments, - kind: PathKind::Plain, - span: array_span, - }); + let array_ident = ExpressionKind::Variable( + Path { segments, kind: PathKind::Plain, span: array_span }, + None, + ); let end_range = ExpressionKind::MethodCall(Box::new(MethodCallExpression { object: Expression::new(array_ident.clone(), array_span), method_name: Ident::new("len".to_string(), array_span), + generics: None, arguments: vec![], })); let end_range = Expression::new(end_range, array_span); @@ -618,11 +617,10 @@ impl ForRange { // array[i] let segments = vec![Ident::new(index_name, array_span)]; - let index_ident = ExpressionKind::Variable(Path { - segments, - kind: PathKind::Plain, - span: array_span, - }); + let index_ident = ExpressionKind::Variable( + Path { segments, kind: PathKind::Plain, span: array_span }, + None, + ); let loop_element = ExpressionKind::Index(Box::new(IndexExpression { collection: Expression::new(array_ident, array_span), diff --git a/compiler/noirc_frontend/src/debug/mod.rs b/compiler/noirc_frontend/src/debug/mod.rs index 3e7d123398b..c222e08e77a 100644 --- a/compiler/noirc_frontend/src/debug/mod.rs +++ b/compiler/noirc_frontend/src/debug/mod.rs @@ -171,11 +171,14 @@ impl DebugInstrumenter { let last_stmt = if has_ret_expr { ast::Statement { kind: ast::StatementKind::Expression(ast::Expression { - kind: ast::ExpressionKind::Variable(ast::Path { - segments: vec![ident("__debug_expr", span)], - kind: PathKind::Plain, - span, - }), + kind: ast::ExpressionKind::Variable( + ast::Path { + segments: vec![ident("__debug_expr", span)], + kind: PathKind::Plain, + span, + }, + None, + ), span, }), span, @@ -568,11 +571,14 @@ fn build_assign_var_stmt(var_id: SourceVarId, expr: ast::Expression) -> ast::Sta let span = expr.span; let kind = ast::ExpressionKind::Call(Box::new(ast::CallExpression { func: Box::new(ast::Expression { - kind: ast::ExpressionKind::Variable(ast::Path { - segments: vec![ident("__debug_var_assign", span)], - kind: PathKind::Plain, - span, - }), + kind: ast::ExpressionKind::Variable( + ast::Path { + segments: vec![ident("__debug_var_assign", span)], + kind: PathKind::Plain, + span, + }, + None, + ), span, }), arguments: vec![uint_expr(var_id.0 as u128, span), expr], @@ -583,11 +589,14 @@ fn build_assign_var_stmt(var_id: SourceVarId, expr: ast::Expression) -> ast::Sta fn build_drop_var_stmt(var_id: SourceVarId, span: Span) -> ast::Statement { let kind = ast::ExpressionKind::Call(Box::new(ast::CallExpression { func: Box::new(ast::Expression { - kind: ast::ExpressionKind::Variable(ast::Path { - segments: vec![ident("__debug_var_drop", span)], - kind: PathKind::Plain, - span, - }), + kind: ast::ExpressionKind::Variable( + ast::Path { + segments: vec![ident("__debug_var_drop", span)], + kind: PathKind::Plain, + span, + }, + None, + ), span, }), arguments: vec![uint_expr(var_id.0 as u128, span)], @@ -607,11 +616,14 @@ fn build_assign_member_stmt( let span = expr.span; let kind = ast::ExpressionKind::Call(Box::new(ast::CallExpression { func: Box::new(ast::Expression { - kind: ast::ExpressionKind::Variable(ast::Path { - segments: vec![ident(&format!["__debug_member_assign_{arity}"], span)], - kind: PathKind::Plain, - span, - }), + kind: ast::ExpressionKind::Variable( + ast::Path { + segments: vec![ident(&format!["__debug_member_assign_{arity}"], span)], + kind: PathKind::Plain, + span, + }, + None, + ), span, }), arguments: [ @@ -627,11 +639,14 @@ fn build_assign_member_stmt( fn build_debug_call_stmt(fname: &str, fn_id: DebugFnId, span: Span) -> ast::Statement { let kind = ast::ExpressionKind::Call(Box::new(ast::CallExpression { func: Box::new(ast::Expression { - kind: ast::ExpressionKind::Variable(ast::Path { - segments: vec![ident(&format!["__debug_fn_{fname}"], span)], - kind: PathKind::Plain, - span, - }), + kind: ast::ExpressionKind::Variable( + ast::Path { + segments: vec![ident(&format!["__debug_fn_{fname}"], span)], + kind: PathKind::Plain, + span, + }, + None, + ), span, }), arguments: vec![uint_expr(fn_id.0 as u128, span)], @@ -693,11 +708,10 @@ fn ident(s: &str, span: Span) -> ast::Ident { fn id_expr(id: &ast::Ident) -> ast::Expression { ast::Expression { - kind: ast::ExpressionKind::Variable(Path { - segments: vec![id.clone()], - kind: PathKind::Plain, - span: id.span(), - }), + kind: ast::ExpressionKind::Variable( + Path { segments: vec![id.clone()], kind: PathKind::Plain, span: id.span() }, + None, + ), span: id.span(), } } diff --git a/compiler/noirc_frontend/src/elaborator/expressions.rs b/compiler/noirc_frontend/src/elaborator/expressions.rs index ed8ed5305d1..75c95c06d09 100644 --- a/compiler/noirc_frontend/src/elaborator/expressions.rs +++ b/compiler/noirc_frontend/src/elaborator/expressions.rs @@ -48,7 +48,12 @@ impl<'context> Elaborator<'context> { ExpressionKind::Cast(cast) => self.elaborate_cast(*cast, expr.span), ExpressionKind::Infix(infix) => return self.elaborate_infix(*infix, expr.span), ExpressionKind::If(if_) => self.elaborate_if(*if_), - ExpressionKind::Variable(variable) => return self.elaborate_variable(variable), + ExpressionKind::Variable(variable, generics) => { + let generics = generics.map(|option_inner| { + option_inner.into_iter().map(|generic| self.resolve_type(generic)).collect() + }); + return self.elaborate_variable(variable, generics); + } ExpressionKind::Tuple(tuple) => self.elaborate_tuple(tuple), ExpressionKind::Lambda(lambda) => self.elaborate_lambda(*lambda), ExpressionKind::Parenthesized(expr) => return self.elaborate_expression(*expr), @@ -185,7 +190,7 @@ impl<'context> Elaborator<'context> { let variable = scope_tree.find(ident_name); if let Some((old_value, _)) = variable { old_value.num_times_used += 1; - let ident = HirExpression::Ident(old_value.ident.clone()); + let ident = HirExpression::Ident(old_value.ident.clone(), None); let expr_id = self.interner.push_expr(ident); self.interner.push_expr_location(expr_id, call_expr_span, self.file); let ident = old_value.ident.clone(); @@ -314,7 +319,11 @@ impl<'context> Elaborator<'context> { let location = Location::new(span, self.file); let method = method_call.method_name; - let method_call = HirMethodCallExpression { method, object, arguments, location }; + let generics = method_call.generics.map(|option_inner| { + option_inner.into_iter().map(|generic| self.resolve_type(generic)).collect() + }); + let method_call = + HirMethodCallExpression { method, object, arguments, location, generics }; // Desugar the method call into a normal, resolved function call // so that the backend doesn't need to worry about methods diff --git a/compiler/noirc_frontend/src/elaborator/patterns.rs b/compiler/noirc_frontend/src/elaborator/patterns.rs index 195d37878f1..810e1b90743 100644 --- a/compiler/noirc_frontend/src/elaborator/patterns.rs +++ b/compiler/noirc_frontend/src/elaborator/patterns.rs @@ -323,10 +323,14 @@ impl<'context> Elaborator<'context> { } } - pub(super) fn elaborate_variable(&mut self, variable: Path) -> (ExprId, Type) { + pub(super) fn elaborate_variable( + &mut self, + variable: Path, + generics: Option>, + ) -> (ExprId, Type) { let span = variable.span; let expr = self.resolve_variable(variable); - let id = self.interner.push_expr(HirExpression::Ident(expr.clone())); + let id = self.interner.push_expr(HirExpression::Ident(expr.clone(), generics)); self.interner.push_expr_location(id, span, self.file); let typ = self.type_check_variable(expr, id); self.interner.push_expr_type(id, typ.clone()); diff --git a/compiler/noirc_frontend/src/elaborator/types.rs b/compiler/noirc_frontend/src/elaborator/types.rs index 4c8364b6dda..54920d5738b 100644 --- a/compiler/noirc_frontend/src/elaborator/types.rs +++ b/compiler/noirc_frontend/src/elaborator/types.rs @@ -494,7 +494,7 @@ impl<'context> Elaborator<'context> { HirExpression::Literal(HirLiteral::Integer(int, false)) => { int.try_into_u128().ok_or(Some(ResolverError::IntegerTooLarge { span })) } - HirExpression::Ident(ident) => { + HirExpression::Ident(ident, _) => { let definition = self.interner.definition(ident.id); match definition.kind { DefinitionKind::Global(global_id) => { @@ -1249,7 +1249,7 @@ impl<'context> Elaborator<'context> { } fn check_if_deprecated(&mut self, expr: ExprId) { - if let HirExpression::Ident(HirIdent { location, id, impl_kind: _ }) = + if let HirExpression::Ident(HirIdent { location, id, impl_kind: _ }, _) = self.interner.expression(&expr) { if let Some(DefinitionKind::Function(func_id)) = @@ -1268,7 +1268,7 @@ impl<'context> Elaborator<'context> { } fn is_unconstrained_call(&self, expr: ExprId) -> bool { - if let HirExpression::Ident(HirIdent { id, .. }) = self.interner.expression(&expr) { + if let HirExpression::Ident(HirIdent { id, .. }, _) = self.interner.expression(&expr) { if let Some(DefinitionKind::Function(func_id)) = self.interner.try_definition(id).map(|def| &def.kind) { diff --git a/compiler/noirc_frontend/src/hir/comptime/hir_to_ast.rs b/compiler/noirc_frontend/src/hir/comptime/hir_to_ast.rs index 1ab9c13ea25..e0fdd91adb4 100644 --- a/compiler/noirc_frontend/src/hir/comptime/hir_to_ast.rs +++ b/compiler/noirc_frontend/src/hir/comptime/hir_to_ast.rs @@ -82,9 +82,12 @@ impl ExprId { let span = interner.expr_span(&self); let kind = match expression { - HirExpression::Ident(ident) => { + HirExpression::Ident(ident, generics) => { let path = Path::from_ident(ident.to_ast(interner)); - ExpressionKind::Variable(path) + ExpressionKind::Variable( + path, + generics.map(|option| option.iter().map(|generic| generic.to_ast()).collect()), + ) } HirExpression::Literal(HirLiteral::Array(array)) => { let array = array.into_ast(interner, span); @@ -146,6 +149,9 @@ impl ExprId { object: method_call.object.to_ast(interner), method_name: method_call.method, arguments: vecmap(method_call.arguments, |arg| arg.to_ast(interner)), + generics: method_call + .generics + .map(|option| option.iter().map(|generic| generic.to_ast()).collect()), })) } HirExpression::Cast(cast) => { diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs index 84df3a0a244..5984e454f7a 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs @@ -296,7 +296,7 @@ impl<'a> Interpreter<'a> { /// Evaluate an expression and return the result pub(super) fn evaluate(&mut self, id: ExprId) -> IResult { match self.interner.expression(&id) { - HirExpression::Ident(ident) => self.evaluate_ident(ident, id), + HirExpression::Ident(ident, _) => self.evaluate_ident(ident, id), HirExpression::Literal(literal) => self.evaluate_literal(literal, id), HirExpression::Block(block) => self.evaluate_block(block), HirExpression::Prefix(prefix) => self.evaluate_prefix(prefix, id), diff --git a/compiler/noirc_frontend/src/hir/comptime/scan.rs b/compiler/noirc_frontend/src/hir/comptime/scan.rs index 7101a158ddb..cc6b9aa7e9c 100644 --- a/compiler/noirc_frontend/src/hir/comptime/scan.rs +++ b/compiler/noirc_frontend/src/hir/comptime/scan.rs @@ -65,7 +65,7 @@ impl<'interner> Interpreter<'interner> { fn scan_expression(&mut self, expr: ExprId) -> IResult<()> { match self.interner.expression(&expr) { - HirExpression::Ident(ident) => self.scan_ident(ident, expr), + HirExpression::Ident(ident, _) => self.scan_ident(ident, expr), HirExpression::Literal(literal) => self.scan_literal(literal), HirExpression::Block(block) => self.scan_block(block), HirExpression::Prefix(prefix) => self.scan_expression(prefix.rhs), diff --git a/compiler/noirc_frontend/src/hir/comptime/value.rs b/compiler/noirc_frontend/src/hir/comptime/value.rs index 4e4a260871a..3c8b6e92445 100644 --- a/compiler/noirc_frontend/src/hir/comptime/value.rs +++ b/compiler/noirc_frontend/src/hir/comptime/value.rs @@ -125,7 +125,7 @@ impl Value { Value::Function(id, _typ) => { let id = interner.function_definition_id(id); let impl_kind = ImplKind::NotATraitMethod; - HirExpression::Ident(HirIdent { location, id, impl_kind }) + HirExpression::Ident(HirIdent { location, id, impl_kind }, None) } Value::Closure(_lambda, _env, _typ) => { // TODO: How should a closure's environment be inlined? diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index e688f192d3d..3d0ffdb0155 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -420,6 +420,7 @@ impl<'a> ModCollector<'a> { // TODO(Maddiaa): Investigate trait implementations with attributes see: https://github.com/noir-lang/noir/issues/2629 attributes: crate::token::Attributes::empty(), is_unconstrained: false, + generic_count: generics.len(), is_comptime: false, }; diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index 7dc307fe716..1f006697359 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -1475,14 +1475,20 @@ impl<'a> Resolver<'a> { Literal::FmtStr(str) => self.resolve_fmt_str_literal(str, expr.span), Literal::Unit => HirLiteral::Unit, }), - ExpressionKind::Variable(path) => { + ExpressionKind::Variable(path, generics) => { + let generics = + generics.map(|generics| vecmap(generics, |typ| self.resolve_type(typ))); + if let Some((method, constraint, assumed)) = self.resolve_trait_generic_path(&path) { - HirExpression::Ident(HirIdent { - location: Location::new(expr.span, self.file), - id: self.interner.trait_method_id(method), - impl_kind: ImplKind::TraitMethod(method, constraint, assumed), - }) + HirExpression::Ident( + HirIdent { + location: Location::new(expr.span, self.file), + id: self.interner.trait_method_id(method), + impl_kind: ImplKind::TraitMethod(method, constraint, assumed), + }, + generics, + ) } else { // If the Path is being used as an Expression, then it is referring to a global from a separate module // Otherwise, then it is referring to an Identifier @@ -1519,7 +1525,7 @@ impl<'a> Resolver<'a> { } } - HirExpression::Ident(hir_ident) + HirExpression::Ident(hir_ident, generics) } } ExpressionKind::Prefix(prefix) => { @@ -1557,12 +1563,20 @@ impl<'a> Resolver<'a> { ExpressionKind::MethodCall(call_expr) => { let method = call_expr.method_name; let object = self.resolve_expression(call_expr.object); + + // Cannot verify the generic count here equals the expected count since we don't + // know which definition `method` refers to until it is resolved during type checking. + let generics = call_expr + .generics + .map(|generics| vecmap(generics, |typ| self.resolve_type(typ))); + let arguments = vecmap(call_expr.arguments, |arg| self.resolve_expression(arg)); let location = Location::new(expr.span, self.file); HirExpression::MethodCall(HirMethodCallExpression { - arguments, method, object, + generics, + arguments, location, }) } @@ -2038,7 +2052,7 @@ impl<'a> Resolver<'a> { HirExpression::Literal(HirLiteral::Integer(int, false)) => { int.try_into_u128().ok_or(Some(ResolverError::IntegerTooLarge { span })) } - HirExpression::Ident(ident) => { + HirExpression::Ident(ident, _) => { let definition = self.interner.definition(ident.id); match definition.kind { DefinitionKind::Global(global_id) => { @@ -2092,7 +2106,7 @@ impl<'a> Resolver<'a> { let variable = scope_tree.find(ident_name); if let Some((old_value, _)) = variable { old_value.num_times_used += 1; - let ident = HirExpression::Ident(old_value.ident.clone()); + let ident = HirExpression::Ident(old_value.ident.clone(), None); let expr_id = self.interner.push_expr(ident); self.interner.push_expr_location(expr_id, call_expr_span, self.file); fmt_str_idents.push(expr_id); @@ -2132,7 +2146,7 @@ pub fn verify_mutable_reference(interner: &NodeInterner, rhs: ExprId) -> Result< let span = interner.expr_span(&rhs); Err(ResolverError::MutableReferenceToArrayElement { span }) } - HirExpression::Ident(ident) => { + HirExpression::Ident(ident, _) => { if let Some(definition) = interner.try_definition(ident.id) { if !definition.mutable { return Err(ResolverError::MutableReferenceToImmutableVariable { diff --git a/compiler/noirc_frontend/src/hir/type_check/errors.rs b/compiler/noirc_frontend/src/hir/type_check/errors.rs index b81727a27f5..549d8138f1d 100644 --- a/compiler/noirc_frontend/src/hir/type_check/errors.rs +++ b/compiler/noirc_frontend/src/hir/type_check/errors.rs @@ -115,6 +115,10 @@ pub enum TypeCheckError { NoMatchingImplFound { constraints: Vec<(Type, String)>, span: Span }, #[error("Constraint for `{typ}: {trait_name}` is not needed, another matching impl is already in scope")] UnneededTraitConstraint { trait_name: String, typ: Type, span: Span }, + #[error( + "Expected {expected_count} generic(s) from this function, but {actual_count} were provided" + )] + IncorrectTurbofishGenericCount { expected_count: usize, actual_count: usize, span: Span }, #[error( "Cannot pass a mutable reference from a constrained runtime to an unconstrained runtime" )] @@ -325,6 +329,12 @@ impl<'a> From<&'a TypeCheckError> for Diagnostic { "`{trait_name}::{method_name}` expects {expected_num_parameters} parameter{plural}, but this method has {actual_num_parameters}"); Diagnostic::simple_error(primary_message, "".to_string(), *span) } + TypeCheckError::IncorrectTurbofishGenericCount { expected_count, actual_count, span } => { + let expected_plural = if *expected_count == 1 { "" } else { "s" }; + let actual_plural = if *actual_count == 1 { "was" } else { "were" }; + let msg = format!("Expected {expected_count} generic{expected_plural} from this function, but {actual_count} {actual_plural} provided"); + Diagnostic::simple_error(msg, "".into(), *span) + }, } } } diff --git a/compiler/noirc_frontend/src/hir/type_check/expr.rs b/compiler/noirc_frontend/src/hir/type_check/expr.rs index 48598109829..c4f80591bf8 100644 --- a/compiler/noirc_frontend/src/hir/type_check/expr.rs +++ b/compiler/noirc_frontend/src/hir/type_check/expr.rs @@ -20,7 +20,7 @@ use super::{errors::TypeCheckError, TypeChecker}; impl<'interner> TypeChecker<'interner> { fn check_if_deprecated(&mut self, expr: &ExprId) { - if let HirExpression::Ident(expr::HirIdent { location, id, impl_kind: _ }) = + if let HirExpression::Ident(expr::HirIdent { location, id, impl_kind: _ }, _) = self.interner.expression(expr) { if let Some(DefinitionKind::Function(func_id)) = @@ -39,7 +39,7 @@ impl<'interner> TypeChecker<'interner> { } fn is_unconstrained_call(&self, expr: &ExprId) -> bool { - if let HirExpression::Ident(expr::HirIdent { id, .. }) = self.interner.expression(expr) { + if let HirExpression::Ident(expr::HirIdent { id, .. }, _) = self.interner.expression(expr) { if let Some(DefinitionKind::Function(func_id)) = self.interner.try_definition(id).map(|def| &def.kind) { @@ -103,7 +103,7 @@ impl<'interner> TypeChecker<'interner> { /// function `foo` to refer to. pub(crate) fn check_expression(&mut self, expr_id: &ExprId) -> Type { let typ = match self.interner.expression(expr_id) { - HirExpression::Ident(ident) => self.check_ident(ident, expr_id), + HirExpression::Ident(ident, generics) => self.check_ident(ident, expr_id, generics), HirExpression::Literal(literal) => match literal { HirLiteral::Array(hir_array_literal) => { let (length, elem_type) = self.check_hir_array_literal(hir_array_literal); @@ -349,7 +349,12 @@ impl<'interner> TypeChecker<'interner> { } /// Returns the type of the given identifier - fn check_ident(&mut self, ident: HirIdent, expr_id: &ExprId) -> Type { + fn check_ident( + &mut self, + ident: HirIdent, + expr_id: &ExprId, + generics: Option>, + ) -> Type { let mut bindings = TypeBindings::new(); // Add type bindings from any constraints that were used. @@ -374,10 +379,20 @@ impl<'interner> TypeChecker<'interner> { // variable to handle generic functions. let t = self.interner.id_type_substitute_trait_as_type(ident.id); + let span = self.interner.expr_span(expr_id); + + let definition = self.interner.try_definition(ident.id); + let function_generic_count = definition.map_or(0, |definition| match &definition.kind { + DefinitionKind::Function(function) => { + self.interner.function_modifiers(function).generic_count + } + _ => 0, + }); + // This instantiates a trait's generics as well which need to be set // when the constraint below is later solved for when the function is // finished. How to link the two? - let (typ, bindings) = t.instantiate_with_bindings(bindings, self.interner); + let (typ, bindings) = self.instantiate(t, bindings, generics, function_generic_count, span); // Push any trait constraints required by this definition to the context // to be checked later when the type of this variable is further constrained. @@ -412,6 +427,37 @@ impl<'interner> TypeChecker<'interner> { typ } + fn instantiate( + &mut self, + typ: Type, + bindings: TypeBindings, + turbofish_generics: Option>, + function_generic_count: usize, + span: Span, + ) -> (Type, TypeBindings) { + match turbofish_generics { + Some(turbofish_generics) => { + if turbofish_generics.len() != function_generic_count { + self.errors.push(TypeCheckError::IncorrectTurbofishGenericCount { + expected_count: function_generic_count, + actual_count: turbofish_generics.len(), + span, + }); + typ.instantiate_with_bindings(bindings, self.interner) + } else { + // Fetch the count of any implicit generics on the function, such as + // for a method within a generic impl. + let implicit_generic_count = match &typ { + Type::Forall(generics, _) => generics.len() - function_generic_count, + _ => 0, + }; + typ.instantiate_with(turbofish_generics, self.interner, implicit_generic_count) + } + } + None => typ.instantiate_with_bindings(bindings, self.interner), + } + } + pub fn verify_trait_constraint( &mut self, object_type: &Type, diff --git a/compiler/noirc_frontend/src/hir/type_check/mod.rs b/compiler/noirc_frontend/src/hir/type_check/mod.rs index 2e448858d9e..9335b8297fe 100644 --- a/compiler/noirc_frontend/src/hir/type_check/mod.rs +++ b/compiler/noirc_frontend/src/hir/type_check/mod.rs @@ -89,7 +89,6 @@ pub fn type_check_func(interner: &mut NodeInterner, func_id: FuncId) -> Vec>), Literal(HirLiteral), Block(HirBlockExpression), Prefix(HirPrefixExpression), @@ -181,6 +183,8 @@ pub struct HirCallExpression { pub struct HirMethodCallExpression { pub method: Ident, pub object: ExprId, + /// Method calls have an optional list of generics provided by the turbofish operator + pub generics: Option>, pub arguments: Vec, pub location: Location, } @@ -227,7 +231,7 @@ impl HirMethodCallExpression { } }; let func_var = HirIdent { location, id, impl_kind }; - let func = interner.push_expr(HirExpression::Ident(func_var.clone())); + let func = interner.push_expr(HirExpression::Ident(func_var.clone(), self.generics)); interner.push_expr_location(func, location.span, location.file); let expr = HirCallExpression { func, arguments, location }; ((func, func_var), expr) diff --git a/compiler/noirc_frontend/src/hir_def/types.rs b/compiler/noirc_frontend/src/hir_def/types.rs index f31aeea0552..cf9aafbb308 100644 --- a/compiler/noirc_frontend/src/hir_def/types.rs +++ b/compiler/noirc_frontend/src/hir_def/types.rs @@ -1478,6 +1478,43 @@ impl Type { } } + /// Instantiates a type with the given types. + /// This differs from substitute in that only the quantified type variables + /// are matched against the type list and are eligible for substitution - similar + /// to normal instantiation. This function is used when the turbofish operator + /// is used and generic substitutions are provided manually by users. + /// + /// Expects the given type vector to be the same length as the Forall type variables. + pub fn instantiate_with( + &self, + types: Vec, + interner: &NodeInterner, + implicit_generic_count: usize, + ) -> (Type, TypeBindings) { + match self { + Type::Forall(typevars, typ) => { + assert_eq!(types.len() + implicit_generic_count, typevars.len(), "Turbofish operator used with incorrect generic count which was not caught by name resolution"); + + let replacements = typevars + .iter() + .enumerate() + .map(|(i, var)| { + let binding = if i < implicit_generic_count { + interner.next_type_variable() + } else { + types[i - implicit_generic_count].clone() + }; + (var.id(), (var.clone(), binding)) + }) + .collect(); + + let instantiated = typ.substitute(&replacements); + (instantiated, replacements) + } + other => (other.clone(), HashMap::new()), + } + } + /// Substitute any type variables found within this type with the /// given bindings if found. If a type variable is not found within /// the given TypeBindings, it is unchanged. @@ -1727,7 +1764,7 @@ fn convert_array_expression_to_slice( let as_slice_id = interner.function_definition_id(as_slice_method); let location = interner.expr_location(&expression); - let as_slice = HirExpression::Ident(HirIdent::non_trait_method(as_slice_id, location)); + let as_slice = HirExpression::Ident(HirIdent::non_trait_method(as_slice_id, location), None); let func = interner.push_expr(as_slice); // Copy the expression and give it a new ExprId. The old one diff --git a/compiler/noirc_frontend/src/monomorphization/mod.rs b/compiler/noirc_frontend/src/monomorphization/mod.rs index f918610af2c..9a20d0dd537 100644 --- a/compiler/noirc_frontend/src/monomorphization/mod.rs +++ b/compiler/noirc_frontend/src/monomorphization/mod.rs @@ -393,7 +393,7 @@ impl<'interner> Monomorphizer<'interner> { use ast::Literal::*; let expr = match self.interner.expression(&expr) { - HirExpression::Ident(ident) => self.ident(ident, expr)?, + HirExpression::Ident(ident, _) => self.ident(ident, expr)?, HirExpression::Literal(HirLiteral::Str(contents)) => Literal(Str(contents)), HirExpression::Literal(HirLiteral::FmtStr(contents, idents)) => { let fields = try_vecmap(idents, |ident| self.expr(ident))?; @@ -1172,7 +1172,7 @@ impl<'interner> Monomorphizer<'interner> { arguments: &mut Vec, ) { match hir_argument { - HirExpression::Ident(ident) => { + HirExpression::Ident(ident, _) => { let typ = self.interner.definition_type(ident.id); let typ: Type = typ.follow_bindings(); let is_fmt_str = match typ { diff --git a/compiler/noirc_frontend/src/node_interner.rs b/compiler/noirc_frontend/src/node_interner.rs index faf89016f96..7f1b67abfbd 100644 --- a/compiler/noirc_frontend/src/node_interner.rs +++ b/compiler/noirc_frontend/src/node_interner.rs @@ -244,6 +244,8 @@ pub struct FunctionModifiers { pub is_unconstrained: bool, + pub generic_count: usize, + pub is_comptime: bool, } @@ -257,6 +259,7 @@ impl FunctionModifiers { visibility: ItemVisibility::Public, attributes: Attributes::empty(), is_unconstrained: false, + generic_count: 0, is_comptime: false, } } @@ -775,6 +778,7 @@ impl NodeInterner { visibility: function.visibility, attributes: function.attributes.clone(), is_unconstrained: function.is_unconstrained, + generic_count: function.generics.len(), is_comptime: function.is_comptime, }; self.push_function_definition(id, modifiers, module, location) diff --git a/compiler/noirc_frontend/src/parser/parser.rs b/compiler/noirc_frontend/src/parser/parser.rs index b527284d1a9..890ab795e00 100644 --- a/compiler/noirc_frontend/src/parser/parser.rs +++ b/compiler/noirc_frontend/src/parser/parser.rs @@ -35,7 +35,7 @@ use super::{spanned, Item, ItemKind}; use crate::ast::{ BinaryOp, BinaryOpKind, BlockExpression, ForLoopStatement, ForRange, Ident, IfExpression, InfixExpression, LValue, Literal, ModuleDeclaration, NoirTypeAlias, Param, Path, Pattern, - Recoverable, Statement, TraitBound, TypeImpl, UnresolvedTraitConstraint, + Recoverable, Statement, TraitBound, TypeImpl, UnaryRhsMemberAccess, UnresolvedTraitConstraint, UnresolvedTypeExpression, UseTree, UseTreeKind, Visibility, }; use crate::ast::{ @@ -676,9 +676,9 @@ fn parse_type<'a>() -> impl NoirParser + 'a { recursive(parse_type_inner) } -fn parse_type_inner( - recursive_type_parser: impl NoirParser, -) -> impl NoirParser { +fn parse_type_inner<'a>( + recursive_type_parser: impl NoirParser + 'a, +) -> impl NoirParser + 'a { choice(( field_type(), int_type(), @@ -751,9 +751,9 @@ fn string_type() -> impl NoirParser { .map_with_span(|expr, span| UnresolvedTypeData::String(expr).with_span(span)) } -fn format_string_type( - type_parser: impl NoirParser, -) -> impl NoirParser { +fn format_string_type<'a>( + type_parser: impl NoirParser + 'a, +) -> impl NoirParser + 'a { keyword(Keyword::FormatString) .ignore_then( type_expression() @@ -783,22 +783,27 @@ fn int_type() -> impl NoirParser { }) } -fn named_type(type_parser: impl NoirParser) -> impl NoirParser { +fn named_type<'a>( + type_parser: impl NoirParser + 'a, +) -> impl NoirParser + 'a { path().then(generic_type_args(type_parser)).map_with_span(|(path, args), span| { UnresolvedTypeData::Named(path, args, false).with_span(span) }) } -fn named_trait(type_parser: impl NoirParser) -> impl NoirParser { +fn named_trait<'a>( + type_parser: impl NoirParser + 'a, +) -> impl NoirParser + 'a { keyword(Keyword::Impl).ignore_then(path()).then(generic_type_args(type_parser)).map_with_span( |(path, args), span| UnresolvedTypeData::TraitAsType(path, args).with_span(span), ) } -fn generic_type_args( - type_parser: impl NoirParser, -) -> impl NoirParser> { +fn generic_type_args<'a>( + type_parser: impl NoirParser + 'a, +) -> impl NoirParser> + 'a { type_parser + .clone() // Without checking for a terminating ',' or '>' here we may incorrectly // parse a generic `N * 2` as just the type `N` then fail when there is no // separator afterward. Failing early here ensures we try the `type_expression` @@ -814,7 +819,9 @@ fn generic_type_args( .map(Option::unwrap_or_default) } -fn array_type(type_parser: impl NoirParser) -> impl NoirParser { +fn array_type<'a>( + type_parser: impl NoirParser + 'a, +) -> impl NoirParser + 'a { just(Token::LeftBracket) .ignore_then(type_parser) .then(just(Token::Semicolon).ignore_then(type_expression())) @@ -1037,6 +1044,7 @@ where expr_no_constructors, statement, allow_constructors, + parse_type(), )) }) } @@ -1057,6 +1065,7 @@ fn atom_or_right_unary<'a, P, P2, S>( expr_no_constructors: P2, statement: S, allow_constructors: bool, + type_parser: impl NoirParser + 'a, ) -> impl NoirParser + 'a where P: ExprParser + 'a, @@ -1067,7 +1076,7 @@ where Call(Vec), ArrayIndex(Expression), Cast(UnresolvedType), - MemberAccess((Ident, Option>)), + MemberAccess(UnaryRhsMemberAccess), } // `(arg1, ..., argN)` in `my_func(arg1, ..., argN)` @@ -1081,14 +1090,17 @@ where // `as Type` in `atom as Type` let cast_rhs = keyword(Keyword::As) - .ignore_then(parse_type()) + .ignore_then(type_parser.clone()) .map(UnaryRhs::Cast) .labelled(ParsingRuleLabel::Cast); + // A turbofish operator is optional in a method call to specify generic types + let turbofish = primitives::turbofish(type_parser); + // `.foo` or `.foo(args)` in `atom.foo` or `atom.foo(args)` let member_rhs = just(Token::Dot) .ignore_then(field_name()) - .then(parenthesized(expression_list(expr_parser.clone())).or_not()) + .then(turbofish.then(parenthesized(expression_list(expr_parser.clone()))).or_not()) .map(UnaryRhs::MemberAccess) .labelled(ParsingRuleLabel::FieldAccess); @@ -1277,7 +1289,7 @@ fn type_expression_atom<'a, P>(expr_parser: P) -> impl NoirParser + where P: ExprParser + 'a, { - variable() + primitives::variable_no_turbofish() .or(literal()) .map_with_span(Expression::new) .or(parenthesized(expr_parser)) @@ -1367,22 +1379,19 @@ mod test { #[test] fn parse_cast() { + let expression_nc = expression_no_constructors(expression()); parse_all( atom_or_right_unary( expression(), expression_no_constructors(expression()), fresh_statement(), true, + parse_type(), ), vec!["x as u8", "x as u16", "0 as Field", "(x + 3) as [Field; 8]"], ); parse_all_failing( - atom_or_right_unary( - expression(), - expression_no_constructors(expression()), - fresh_statement(), - true, - ), + atom_or_right_unary(expression(), expression_nc, fresh_statement(), true, parse_type()), vec!["x as pub u8"], ); } @@ -1402,6 +1411,7 @@ mod test { expression_no_constructors(expression()), fresh_statement(), true, + parse_type(), ), valid, ); diff --git a/compiler/noirc_frontend/src/parser/parser/primitives.rs b/compiler/noirc_frontend/src/parser/parser/primitives.rs index 8413f14ae4d..9da19c0a185 100644 --- a/compiler/noirc_frontend/src/parser/parser/primitives.rs +++ b/compiler/noirc_frontend/src/parser/parser/primitives.rs @@ -1,6 +1,7 @@ use chumsky::prelude::*; use crate::ast::{ExpressionKind, Ident, UnaryOp}; +use crate::macros_api::UnresolvedType; use crate::{ parser::{labels::ParsingRuleLabel, ExprParser, NoirParser, ParserError}, token::{Keyword, Token, TokenKind}, @@ -77,8 +78,20 @@ where .map(|rhs| ExpressionKind::prefix(UnaryOp::Dereference { implicitly_added: false }, rhs)) } +pub(super) fn turbofish<'a>( + type_parser: impl NoirParser + 'a, +) -> impl NoirParser>> + 'a { + just(Token::DoubleColon).ignore_then(super::generic_type_args(type_parser)).or_not() +} + pub(super) fn variable() -> impl NoirParser { - path().map(ExpressionKind::Variable) + path() + .then(turbofish(super::parse_type())) + .map(|(path, generics)| ExpressionKind::Variable(path, generics)) +} + +pub(super) fn variable_no_turbofish() -> impl NoirParser { + path().map(|path| ExpressionKind::Variable(path, None)) } #[cfg(test)] diff --git a/compiler/noirc_frontend/src/resolve_locations.rs b/compiler/noirc_frontend/src/resolve_locations.rs index ac8c96a092e..2fa7c8adbf8 100644 --- a/compiler/noirc_frontend/src/resolve_locations.rs +++ b/compiler/noirc_frontend/src/resolve_locations.rs @@ -97,7 +97,7 @@ impl NodeInterner { return_type_location_instead: bool, ) -> Option { match expression { - HirExpression::Ident(ident) => { + HirExpression::Ident(ident, _) => { let definition_info = self.definition(ident.id); match definition_info.kind { DefinitionKind::Function(func_id) => { diff --git a/compiler/noirc_frontend/src/tests.rs b/compiler/noirc_frontend/src/tests.rs index fb80a7d8018..7bf5655486b 100644 --- a/compiler/noirc_frontend/src/tests.rs +++ b/compiler/noirc_frontend/src/tests.rs @@ -1378,3 +1378,68 @@ fn deny_fold_attribute_on_unconstrained() { CompilationError::ResolverError(ResolverError::FoldAttributeOnUnconstrained { .. }) )); } + +#[test] +fn specify_function_types_with_turbofish() { + let src = r#" + trait Default { + fn default() -> Self; + } + + impl Default for Field { + fn default() -> Self { 0 } + } + + impl Default for u64 { + fn default() -> Self { 0 } + } + + // Need the above as we don't have access to the stdlib here. + // We also need to construct a concrete value of `U` without giving away its type + // as otherwise the unspecified type is ignored. + + fn generic_func() -> (T, U) where T: Default, U: Default { + (T::default(), U::default()) + } + + fn main() { + let _ = generic_func::(); + } + "#; + let errors = get_program_errors(src); + assert_eq!(errors.len(), 0); +} + +#[test] +fn specify_method_types_with_turbofish() { + let src = r#" + trait Default { + fn default() -> Self; + } + + impl Default for Field { + fn default() -> Self { 0 } + } + + // Need the above as we don't have access to the stdlib here. + // We also need to construct a concrete value of `U` without giving away its type + // as otherwise the unspecified type is ignored. + + struct Foo { + inner: T + } + + impl Foo { + fn generic_method(_self: Self) where U: Default { + U::default() + } + } + + fn main() { + let foo: Foo = Foo { inner: 1 }; + foo.generic_method::(); + } + "#; + let errors = get_program_errors(src); + assert_eq!(errors.len(), 0); +} diff --git a/cspell.json b/cspell.json index 1fbbe5c428d..eaf3fcd1b00 100644 --- a/cspell.json +++ b/cspell.json @@ -180,6 +180,7 @@ "termcolor", "thiserror", "tslog", + "turbofish", "typecheck", "typechecked", "typevar", diff --git a/test_programs/compile_failure/turbofish_generic_count/Nargo.toml b/test_programs/compile_failure/turbofish_generic_count/Nargo.toml new file mode 100644 index 00000000000..92be7dcb749 --- /dev/null +++ b/test_programs/compile_failure/turbofish_generic_count/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "turbofish_generic_count" +type = "bin" +authors = [""] +compiler_version = ">=0.29.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/compile_failure/turbofish_generic_count/src/main.nr b/test_programs/compile_failure/turbofish_generic_count/src/main.nr new file mode 100644 index 00000000000..a360641fa15 --- /dev/null +++ b/test_programs/compile_failure/turbofish_generic_count/src/main.nr @@ -0,0 +1,22 @@ + +struct Bar { + one: Field, + two: Field, + other: T, +} + +impl Bar { + fn zeroed(_self: Self) -> A { + dep::std::unsafe::zeroed() + } +} + +fn foo(bar: Bar) { + assert(bar.one == bar.two); +} + +fn main(x: Field, y: pub Field) { + let bar1: Bar = Bar { one: x, two: y, other: 0 }; + + assert(bar1.zeroed::() == 0); +} diff --git a/test_programs/execution_success/generics/src/main.nr b/test_programs/execution_success/generics/src/main.nr index 3edce1ed8e7..c8616960559 100644 --- a/test_programs/execution_success/generics/src/main.nr +++ b/test_programs/execution_success/generics/src/main.nr @@ -31,6 +31,13 @@ impl Bar { } } +impl Bar { + // This is to test that we can use turbofish on methods as well + fn zeroed(_self: Self) -> A { + dep::std::unsafe::zeroed() + } +} + fn main(x: Field, y: Field) { let bar1: Bar = Bar { one: x, two: y, other: 0 }; let bar2 = Bar { one: x, two: y, other: [0] }; @@ -51,6 +58,14 @@ fn main(x: Field, y: Field) { let nested_generics: Bar> = Bar { one, two, other: Bar { one, two, other: 0 } }; assert(nested_generics.other.other == bar1.get_other()); + // Test turbofish operator + foo::(bar1); + + // Test that turbofish works on methods and that it uses the generics on the methods + // While still handling the generic on the impl (T in this case) that is implicitly added + // to the method. + assert(bar1.zeroed::() == 0); + let _ = regression_2055([1, 2, 3]); } diff --git a/tooling/nargo_fmt/src/rewrite/expr.rs b/tooling/nargo_fmt/src/rewrite/expr.rs index 6b7dca6c5c7..e5b30f99b7b 100644 --- a/tooling/nargo_fmt/src/rewrite/expr.rs +++ b/tooling/nargo_fmt/src/rewrite/expr.rs @@ -1,8 +1,9 @@ use noirc_frontend::ast::{ - ArrayLiteral, BlockExpression, Expression, ExpressionKind, Literal, UnaryOp, + ArrayLiteral, BlockExpression, Expression, ExpressionKind, Literal, UnaryOp, UnresolvedType, }; use noirc_frontend::{macros_api::Span, token::Token}; +use crate::rewrite; use crate::visitor::{ expr::{format_brackets, format_parens, NewlineMode}, ExpressionType, FmtVisitor, Indent, Shape, @@ -72,6 +73,7 @@ pub(crate) fn rewrite( let object = rewrite_sub_expr(visitor, shape, method_call_expr.object); let method = method_call_expr.method_name.to_string(); + let turbofish = rewrite_turbofish(visitor, shape, method_call_expr.generics); let args = format_parens( visitor.config.fn_call_width.into(), visitor.fork(), @@ -83,7 +85,7 @@ pub(crate) fn rewrite( NewlineMode::IfContainsNewLineAndWidth, ); - format!("{object}.{method}{args}") + format!("{object}.{method}{turbofish}{args}") } ExpressionKind::MemberAccess(member_access_expr) => { let lhs_str = rewrite_sub_expr(visitor, shape, member_access_expr.lhs); @@ -157,7 +159,13 @@ pub(crate) fn rewrite( visitor.format_if(*if_expr) } - ExpressionKind::Lambda(_) | ExpressionKind::Variable(_) => visitor.slice(span).to_string(), + ExpressionKind::Variable(path, generics) => { + let path_string = visitor.slice(path.span); + + let turbofish = rewrite_turbofish(visitor, shape, generics); + format!("{path_string}{turbofish}") + } + ExpressionKind::Lambda(_) => visitor.slice(span).to_string(), ExpressionKind::Quote(block) => format!("quote {}", rewrite_block(visitor, block, span)), ExpressionKind::Comptime(block) => { format!("comptime {}", rewrite_block(visitor, block, span)) @@ -171,3 +179,24 @@ fn rewrite_block(visitor: &FmtVisitor, block: BlockExpression, span: Span) -> St visitor.visit_block(block, span); visitor.finish() } + +fn rewrite_turbofish( + visitor: &FmtVisitor, + shape: Shape, + generics: Option>, +) -> String { + if let Some(generics) = generics { + let mut turbofish = "".to_owned(); + for (i, generic) in generics.into_iter().enumerate() { + let generic = rewrite::typ(visitor, shape, generic); + turbofish = if i == 0 { + format!("::<{}", generic) + } else { + format!("{turbofish}, {}", generic) + }; + } + format!("{turbofish}>") + } else { + "".to_owned() + } +} diff --git a/tooling/nargo_fmt/tests/expected/turbofish_call.nr b/tooling/nargo_fmt/tests/expected/turbofish_call.nr new file mode 100644 index 00000000000..bcf0df9a969 --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/turbofish_call.nr @@ -0,0 +1,8 @@ +fn foo() { + my_function::(10, some_value, another_func(20, 30)); + + outer_function::( + some_function(), // Original inner function call + another_function() // Original inner function call + ); +} diff --git a/tooling/nargo_fmt/tests/expected/turbofish_method_call.nr b/tooling/nargo_fmt/tests/expected/turbofish_method_call.nr new file mode 100644 index 00000000000..52fa3db2ac9 --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/turbofish_method_call.nr @@ -0,0 +1,12 @@ +fn foo() { + my_object.some_method::(10, var_value, inner_method::(20, 30)); + + assert( + p4_affine.eq::( + Gaffine::new::( + 6890855772600357754907169075114257697580319025794532037257385534741338397365, + 4338620300185947561074059802482547481416142213883829469920100239455078257889 + ) + ) + ); +} diff --git a/tooling/nargo_fmt/tests/input/turbofish_call.nr b/tooling/nargo_fmt/tests/input/turbofish_call.nr new file mode 100644 index 00000000000..03abde789fe --- /dev/null +++ b/tooling/nargo_fmt/tests/input/turbofish_call.nr @@ -0,0 +1,7 @@ +fn foo() { + my_function :: ( 10,some_value,another_func( 20 , 30) ); + + outer_function :: (some_function(), // Original inner function call + another_function(), // Original inner function call + ); +} \ No newline at end of file diff --git a/tooling/nargo_fmt/tests/input/turbofish_method_call.nr b/tooling/nargo_fmt/tests/input/turbofish_method_call.nr new file mode 100644 index 00000000000..aa7ae87f23a --- /dev/null +++ b/tooling/nargo_fmt/tests/input/turbofish_method_call.nr @@ -0,0 +1,5 @@ +fn foo() { + my_object . some_method :: ( 10,var_value,inner_method:: ( 20 , 30) ); + + assert(p4_affine.eq::(Gaffine::new::(6890855772600357754907169075114257697580319025794532037257385534741338397365, 4338620300185947561074059802482547481416142213883829469920100239455078257889))); +} \ No newline at end of file From 89846cfbc4961c5258d91b5973f027be80885a20 Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Tue, 21 May 2024 19:29:31 +0100 Subject: [PATCH 13/61] fix(frontend): Call trait method with mut self from generic definition (#5041) # Description ## Problem\* Resolves Not sure if there is another issue for this I will have to look again, but I found this bug when trying to implement https://github.com/noir-lang/noir/issues/4514 ## Summary\* When type checking a `MethodCall` from the HIR now we also add a mutable reference to the object type when we have a `HirMethodReference::TraitMethodId`. We were previously only doing this for a `HirMethodReference::FuncId`. For example that meant this program would fail with the following errors laid out in the comments: ```rust fn hash_simple_array(input: [Field; 2]) -> Field where H: Hasher + Default { // Check that we can a trait method to instead a trait implementation let mut hasher: H = H::default(); // Regression that the object is converted to a mutable reference type `&mut _`. // Otherwise will see `Expected type &mut _, found type H`. // Then we need to make sure to also auto dereference later in the type checking process // when searching for a matching impl or else we will get `No matching impl found for `&mut H: Hasher` hasher.write(input[0]); hasher.write(input[1]); hasher.finish() } ``` I also had to add auto dereferencing when verifying the trait constraints later inside of `type_check_func`. So first we add a mutable reference to the method call's object type to avoid a mismatched type error, and then we later dereference it to find the appropriate trait implementation. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Jake Fecher Co-authored-by: Jake Fecher Co-authored-by: Tom French --- .../noirc_frontend/src/hir/type_check/expr.rs | 32 +++++--- .../noirc_frontend/src/hir/type_check/mod.rs | 9 ++- noir_stdlib/src/lib.nr | 2 +- .../trait_method_mut_self/Nargo.toml | 7 ++ .../trait_method_mut_self/Prover.toml | 2 + .../trait_method_mut_self/src/main.nr | 74 +++++++++++++++++++ 6 files changed, 113 insertions(+), 13 deletions(-) create mode 100644 test_programs/execution_success/trait_method_mut_self/Nargo.toml create mode 100644 test_programs/execution_success/trait_method_mut_self/Prover.toml create mode 100644 test_programs/execution_success/trait_method_mut_self/src/main.nr diff --git a/compiler/noirc_frontend/src/hir/type_check/expr.rs b/compiler/noirc_frontend/src/hir/type_check/expr.rs index c4f80591bf8..abff466e1d5 100644 --- a/compiler/noirc_frontend/src/hir/type_check/expr.rs +++ b/compiler/noirc_frontend/src/hir/type_check/expr.rs @@ -236,17 +236,27 @@ impl<'interner> TypeChecker<'interner> { // Automatically add `&mut` if the method expects a mutable reference and // the object is not already one. - if let HirMethodReference::FuncId(func_id) = &method_ref { - if *func_id != FuncId::dummy_id() { - let function_type = - self.interner.function_meta(func_id).typ.clone(); - - self.try_add_mutable_reference_to_object( - &mut method_call, - &function_type, - &mut object_type, - ); + let func_id = match &method_ref { + HirMethodReference::FuncId(func_id) => *func_id, + HirMethodReference::TraitMethodId(method_id, _) => { + let id = self.interner.trait_method_id(*method_id); + let definition = self.interner.definition(id); + let DefinitionKind::Function(func_id) = definition.kind else { + unreachable!( + "Expected trait function to be a DefinitionKind::Function" + ) + }; + func_id } + }; + + if func_id != FuncId::dummy_id() { + let function_type = self.interner.function_meta(&func_id).typ.clone(); + self.try_add_mutable_reference_to_object( + &mut method_call, + &function_type, + &mut object_type, + ); } // TODO: update object_type here? @@ -567,7 +577,7 @@ impl<'interner> TypeChecker<'interner> { /// Insert as many dereference operations as necessary to automatically dereference a method /// call object to its base value type T. - fn insert_auto_dereferences(&mut self, object: ExprId, typ: Type) -> (ExprId, Type) { + pub(crate) fn insert_auto_dereferences(&mut self, object: ExprId, typ: Type) -> (ExprId, Type) { if let Type::MutableReference(element) = typ { let location = self.interner.id_location(object); diff --git a/compiler/noirc_frontend/src/hir/type_check/mod.rs b/compiler/noirc_frontend/src/hir/type_check/mod.rs index 9335b8297fe..b2a76828c88 100644 --- a/compiler/noirc_frontend/src/hir/type_check/mod.rs +++ b/compiler/noirc_frontend/src/hir/type_check/mod.rs @@ -141,8 +141,15 @@ pub fn type_check_func(interner: &mut NodeInterner, func_id: FuncId) -> Vec(x: T, y: T) -> T { } #[builtin(as_witness)] -pub fn as_witness(x: Field) {} \ No newline at end of file +pub fn as_witness(x: Field) {} diff --git a/test_programs/execution_success/trait_method_mut_self/Nargo.toml b/test_programs/execution_success/trait_method_mut_self/Nargo.toml new file mode 100644 index 00000000000..d2fe9e8e137 --- /dev/null +++ b/test_programs/execution_success/trait_method_mut_self/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "trait_method_mut_self" +type = "bin" +authors = [""] +compiler_version = ">=0.29.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/execution_success/trait_method_mut_self/Prover.toml b/test_programs/execution_success/trait_method_mut_self/Prover.toml new file mode 100644 index 00000000000..f28f2f8cc48 --- /dev/null +++ b/test_programs/execution_success/trait_method_mut_self/Prover.toml @@ -0,0 +1,2 @@ +x = "5" +y = "10" diff --git a/test_programs/execution_success/trait_method_mut_self/src/main.nr b/test_programs/execution_success/trait_method_mut_self/src/main.nr new file mode 100644 index 00000000000..fa47fd5d881 --- /dev/null +++ b/test_programs/execution_success/trait_method_mut_self/src/main.nr @@ -0,0 +1,74 @@ +use dep::std::hash::Hasher; +use dep::std::hash::poseidon2::Poseidon2Hasher; + +fn main(x: Field, y: pub Field) { + let mut a_mut_ref = AType { x }; + + pass_trait_by_value(a_mut_ref, y); + assert(a_mut_ref.x == x); + + pass_trait_by_value_impl_param(a_mut_ref, y); + assert(a_mut_ref.x == x); + + pass_trait_by_mut_ref(&mut a_mut_ref, y); + assert(a_mut_ref.x == y); + + let mut hasher = Poseidon2Hasher::default(); + hasher.write(x); + hasher.write(y); + let expected_hash = hasher.finish(); + // Check that we get the same result when using the hasher in a + // method that purely uses trait methods without a supplied implementation. + assert(hash_simple_array::([x, y]) == expected_hash); +} + +trait SomeTrait { + fn set_value(&mut self, new_value: Field) -> (); + + fn get_value(self) -> Field; +} + +struct AType { + x: Field +} + +impl SomeTrait for AType { + fn set_value(&mut self, new_value: Field) -> () { + self.x = new_value; + } + + fn get_value(self) -> Field { + self.x + } +} + +fn pass_trait_by_value_impl_param(mut a_mut_ref: impl SomeTrait, value: Field) { + // We auto add a mutable reference to the object type if the method call expects a mutable self + a_mut_ref.set_value(value); + assert(a_mut_ref.get_value() == value); +} + +fn pass_trait_by_value(mut a_mut_ref: T, value: Field) where T: SomeTrait { + // We auto add a mutable reference to the object type if the method call expects a mutable self + a_mut_ref.set_value(value); + assert(a_mut_ref.get_value() == value); +} + +fn pass_trait_by_mut_ref(a_mut_ref: &mut T, value: Field) where T: SomeTrait { + // We auto add a mutable reference to the object type if the method call expects a mutable self + a_mut_ref.set_value(value); +} + +fn hash_simple_array(input: [Field; 2]) -> Field where H: Hasher + Default { + // Check that we can call a trait method instead of a trait implementation + // TODO: Need to remove the need for this type annotation + // TODO: Curently, without the annotation we will get `Expression type is ambiguous` when trying to use the `hasher` + let mut hasher: H = H::default(); + // Regression that the object is converted to a mutable reference type `&mut _`. + // Otherwise will see `Expected type &mut _, found type H`. + // Then we need to make sure to also auto dereference later in the type checking process + // when searching for a matching impl or else we will get `No matching impl found for `&mut H: Hasher` + hasher.write(input[0]); + hasher.write(input[1]); + hasher.finish() +} From fd772e7a764004373f5a41a54eb6847f4decda77 Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Tue, 21 May 2024 20:17:08 +0100 Subject: [PATCH 14/61] fix(frontend): Correctly monomorphize turbofish functions (#5049) # Description ## Problem\* Resolves Working towards https://github.com/noir-lang/noir/issues/4514 and fully resolving https://github.com/noir-lang/noir/issues/4710 ## Summary\* We need to accurately monomorphize functions with turbofish operators where no function parameters or the return type using the specified generic. Without this change the following would pass: ``` fn main(x: Field, y: pub Field) { let mut hasher = PoseidonHasher::default(); hasher.write(x); hasher.write(y); let poseidon_expected_hash = hasher.finish(); assert(hash_simple_array::([x, y]) == poseidon_expected_hash); let mut hasher = Poseidon2Hasher::default(); hasher.write(x); hasher.write(y); let poseidon2_expected_hash = hasher.finish(); assert(hash_simple_array::([x, y]) == poseidon_expected_hash); assert(hash_simple_array::([x, y]) != poseidon2_expected_hash); } fn hash_simple_array(input: [Field; 2]) -> Field where H: Hasher + Default { let mut hasher: H = H::default(); hasher.write(input[0]); hasher.write(input[1]); hasher.finish() } ``` Essentially any future invocations of `hash_simple_array` would use the `PoseidonHasher`. We now correctly monomorphize the functions to use the correct type. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Jake Fecher Co-authored-by: Jake Fecher Co-authored-by: Tom French --- .../src/monomorphization/mod.rs | 48 ++++++++++++++----- .../trait_method_mut_self/src/main.nr | 22 --------- .../turbofish_call_func_diff_types/Nargo.toml | 7 +++ .../Prover.toml | 2 + .../src/main.nr | 36 ++++++++++++++ 5 files changed, 81 insertions(+), 34 deletions(-) create mode 100644 test_programs/execution_success/turbofish_call_func_diff_types/Nargo.toml create mode 100644 test_programs/execution_success/turbofish_call_func_diff_types/Prover.toml create mode 100644 test_programs/execution_success/turbofish_call_func_diff_types/src/main.nr diff --git a/compiler/noirc_frontend/src/monomorphization/mod.rs b/compiler/noirc_frontend/src/monomorphization/mod.rs index 9a20d0dd537..54a6af97744 100644 --- a/compiler/noirc_frontend/src/monomorphization/mod.rs +++ b/compiler/noirc_frontend/src/monomorphization/mod.rs @@ -55,9 +55,12 @@ struct LambdaContext { struct Monomorphizer<'interner> { /// Functions are keyed by their unique ID and expected type so that we can monomorphize /// a new version of the function for each type. + /// We also key by any turbofish generics that are specified. + /// This is necessary for a case where we may have a trait generic that can be instantiated + /// outside of a function parameter or return value. /// /// Using nested HashMaps here lets us avoid cloning HirTypes when calling .get() - functions: HashMap>, + functions: HashMap), FuncId>>, /// Unlike functions, locals are only keyed by their unique ID because they are never /// duplicated during monomorphization. Doing so would allow them to be used polymorphically @@ -198,10 +201,15 @@ impl<'interner> Monomorphizer<'interner> { id: node_interner::FuncId, expr_id: node_interner::ExprId, typ: &HirType, + turbofish_generics: Vec, trait_method: Option, ) -> Definition { let typ = typ.follow_bindings(); - match self.functions.get(&id).and_then(|inner_map| inner_map.get(&typ)) { + match self + .functions + .get(&id) + .and_then(|inner_map| inner_map.get(&(typ.clone(), turbofish_generics.clone()))) + { Some(id) => Definition::Function(*id), None => { // Function has not been monomorphized yet @@ -222,7 +230,8 @@ impl<'interner> Monomorphizer<'interner> { Definition::Builtin(opcode) } FunctionKind::Normal => { - let id = self.queue_function(id, expr_id, typ, trait_method); + let id = + self.queue_function(id, expr_id, typ, turbofish_generics, trait_method); Definition::Function(id) } FunctionKind::Oracle => { @@ -249,8 +258,14 @@ impl<'interner> Monomorphizer<'interner> { } /// Prerequisite: typ = typ.follow_bindings() - fn define_function(&mut self, id: node_interner::FuncId, typ: HirType, new_id: FuncId) { - self.functions.entry(id).or_default().insert(typ, new_id); + fn define_function( + &mut self, + id: node_interner::FuncId, + typ: HirType, + turbofish_generics: Vec, + new_id: FuncId, + ) { + self.functions.entry(id).or_default().insert((typ, turbofish_generics), new_id); } fn compile_main( @@ -393,7 +408,7 @@ impl<'interner> Monomorphizer<'interner> { use ast::Literal::*; let expr = match self.interner.expression(&expr) { - HirExpression::Ident(ident, _) => self.ident(ident, expr)?, + HirExpression::Ident(ident, generics) => self.ident(ident, expr, generics)?, HirExpression::Literal(HirLiteral::Str(contents)) => Literal(Str(contents)), HirExpression::Literal(HirLiteral::FmtStr(contents, idents)) => { let fields = try_vecmap(idents, |ident| self.expr(ident))?; @@ -825,6 +840,7 @@ impl<'interner> Monomorphizer<'interner> { &mut self, ident: HirIdent, expr_id: node_interner::ExprId, + generics: Option>, ) -> Result { let typ = self.interner.id_type(expr_id); @@ -838,7 +854,13 @@ impl<'interner> Monomorphizer<'interner> { let mutable = definition.mutable; let location = Some(ident.location); let name = definition.name.clone(); - let definition = self.lookup_function(*func_id, expr_id, &typ, None); + let definition = self.lookup_function( + *func_id, + expr_id, + &typ, + generics.unwrap_or_default(), + None, + ); let typ = Self::convert_type(&typ, ident.location)?; let ident = ast::Ident { location, mutable, definition, name, typ: typ.clone() }; let ident_expression = ast::Expression::Ident(ident); @@ -1063,10 +1085,11 @@ impl<'interner> Monomorphizer<'interner> { } }; - let func_id = match self.lookup_function(func_id, expr_id, &function_type, Some(method)) { - Definition::Function(func_id) => func_id, - _ => unreachable!(), - }; + let func_id = + match self.lookup_function(func_id, expr_id, &function_type, vec![], Some(method)) { + Definition::Function(func_id) => func_id, + _ => unreachable!(), + }; let the_trait = self.interner.get_trait(method.trait_id); let location = self.interner.expr_location(&expr_id); @@ -1292,10 +1315,11 @@ impl<'interner> Monomorphizer<'interner> { id: node_interner::FuncId, expr_id: node_interner::ExprId, function_type: HirType, + turbofish_generics: Vec, trait_method: Option, ) -> FuncId { let new_id = self.next_function_id(); - self.define_function(id, function_type.clone(), new_id); + self.define_function(id, function_type.clone(), turbofish_generics, new_id); let bindings = self.interner.get_instantiation_bindings(expr_id); let bindings = self.follow_bindings(bindings); diff --git a/test_programs/execution_success/trait_method_mut_self/src/main.nr b/test_programs/execution_success/trait_method_mut_self/src/main.nr index fa47fd5d881..0e736c2f098 100644 --- a/test_programs/execution_success/trait_method_mut_self/src/main.nr +++ b/test_programs/execution_success/trait_method_mut_self/src/main.nr @@ -12,14 +12,6 @@ fn main(x: Field, y: pub Field) { pass_trait_by_mut_ref(&mut a_mut_ref, y); assert(a_mut_ref.x == y); - - let mut hasher = Poseidon2Hasher::default(); - hasher.write(x); - hasher.write(y); - let expected_hash = hasher.finish(); - // Check that we get the same result when using the hasher in a - // method that purely uses trait methods without a supplied implementation. - assert(hash_simple_array::([x, y]) == expected_hash); } trait SomeTrait { @@ -58,17 +50,3 @@ fn pass_trait_by_mut_ref(a_mut_ref: &mut T, value: Field) where T: SomeTrait // We auto add a mutable reference to the object type if the method call expects a mutable self a_mut_ref.set_value(value); } - -fn hash_simple_array(input: [Field; 2]) -> Field where H: Hasher + Default { - // Check that we can call a trait method instead of a trait implementation - // TODO: Need to remove the need for this type annotation - // TODO: Curently, without the annotation we will get `Expression type is ambiguous` when trying to use the `hasher` - let mut hasher: H = H::default(); - // Regression that the object is converted to a mutable reference type `&mut _`. - // Otherwise will see `Expected type &mut _, found type H`. - // Then we need to make sure to also auto dereference later in the type checking process - // when searching for a matching impl or else we will get `No matching impl found for `&mut H: Hasher` - hasher.write(input[0]); - hasher.write(input[1]); - hasher.finish() -} diff --git a/test_programs/execution_success/turbofish_call_func_diff_types/Nargo.toml b/test_programs/execution_success/turbofish_call_func_diff_types/Nargo.toml new file mode 100644 index 00000000000..8624cda646b --- /dev/null +++ b/test_programs/execution_success/turbofish_call_func_diff_types/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "turbofish_call_func_diff_types" +type = "bin" +authors = [""] +compiler_version = ">=0.29.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/execution_success/turbofish_call_func_diff_types/Prover.toml b/test_programs/execution_success/turbofish_call_func_diff_types/Prover.toml new file mode 100644 index 00000000000..f28f2f8cc48 --- /dev/null +++ b/test_programs/execution_success/turbofish_call_func_diff_types/Prover.toml @@ -0,0 +1,2 @@ +x = "5" +y = "10" diff --git a/test_programs/execution_success/turbofish_call_func_diff_types/src/main.nr b/test_programs/execution_success/turbofish_call_func_diff_types/src/main.nr new file mode 100644 index 00000000000..709a694e77b --- /dev/null +++ b/test_programs/execution_success/turbofish_call_func_diff_types/src/main.nr @@ -0,0 +1,36 @@ +use dep::std::hash::Hasher; +use dep::std::hash::poseidon2::Poseidon2Hasher; +use dep::std::hash::poseidon::PoseidonHasher; + +fn main(x: Field, y: pub Field) { + let mut hasher = PoseidonHasher::default(); + hasher.write(x); + hasher.write(y); + let poseidon_expected_hash = hasher.finish(); + // Check that we get the same result when using the hasher in a + // method that purely uses trait methods without a supplied implementation. + assert(hash_simple_array::([x, y]) == poseidon_expected_hash); + + // Now let's do the same logic but with a different `Hasher` supplied to the turbofish operator + // We want to make sure that we have correctly monomorphized a function with a trait generic + // where the generic is not used on any function parameters or the return value. + let mut hasher = Poseidon2Hasher::default(); + hasher.write(x); + hasher.write(y); + let poseidon2_expected_hash = hasher.finish(); + assert(hash_simple_array::([x, y]) == poseidon2_expected_hash); +} + +fn hash_simple_array(input: [Field; 2]) -> Field where H: Hasher + Default { + // Check that we can call a trait method instead of a trait implementation + // TODO(https://github.com/noir-lang/noir/issues/5063): Need to remove the need for this type annotation + // Curently, without the annotation we will get `Expression type is ambiguous` when trying to use the `hasher` + let mut hasher: H = H::default(); + // Regression that the object is converted to a mutable reference type `&mut _`. + // Otherwise will see `Expected type &mut _, found type H`. + // Then we need to make sure to also auto dereference later in the type checking process + // when searching for a matching impl or else we will get `No matching impl found for `&mut H: Hasher` + hasher.write(input[0]); + hasher.write(input[1]); + hasher.finish() +} From 79362629ed8cf42b6601e9a551ed8f9fe03e0112 Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Tue, 21 May 2024 20:46:09 +0100 Subject: [PATCH 15/61] feat(stdlib)!: eddsa function using turbofish (#5050) # Description ## Problem\* Resolves #4514 ## Summary\* This updates `eddsa_verify_with_hasher` to have the following signature now that we support the turbofish operator: ```rust pub fn eddsa_verify_with_hasher( pub_key_x: Field, pub_key_y: Field, signature_s: Field, signature_r8_x: Field, signature_r8_y: Field, message: Field ) -> bool where H: Hasher + Default { [function body ...] } ``` This re-work was only possible with further bug fixes from https://github.com/noir-lang/noir/pull/5049 and https://github.com/noir-lang/noir/pull/5041. The original turbofish PR can be found here (https://github.com/noir-lang/noir/pull/3542). ## Additional Context This PR can most likely be merged into its parent #5049 but I just made this separate PR to separate the bug fix and the stdlib library breaking change. ## Documentation\* Check one: - [ ] No documentation needed. - [x] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Jake Fecher Co-authored-by: Jake Fecher Co-authored-by: Tom French --- .../cryptographic_primitives/eddsa.mdx | 6 ++--- noir_stdlib/src/eddsa.nr | 27 +++++++++---------- .../execution_success/eddsa/src/main.nr | 5 ++-- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/docs/docs/noir/standard_library/cryptographic_primitives/eddsa.mdx b/docs/docs/noir/standard_library/cryptographic_primitives/eddsa.mdx index c2c0624dfad..789d26ce426 100644 --- a/docs/docs/noir/standard_library/cryptographic_primitives/eddsa.mdx +++ b/docs/docs/noir/standard_library/cryptographic_primitives/eddsa.mdx @@ -15,12 +15,12 @@ Verifier for EdDSA signatures fn eddsa_poseidon_verify(public_key_x : Field, public_key_y : Field, signature_s: Field, signature_r8_x: Field, signature_r8_y: Field, message: Field) -> bool ``` -It is also possible to specify the hash algorithm used for the signature by using the `eddsa_verify_with_hasher` function with a parameter implementing the Hasher trait. For instance, if you want to use Poseidon2 instead, you can do the following: +It is also possible to specify the hash algorithm used for the signature by using the `eddsa_verify` function by passing a type implementing the Hasher trait with the turbofish operator. +For instance, if you want to use Poseidon2 instead, you can do the following: ```rust use dep::std::hash::poseidon2::Poseidon2Hasher; -let mut hasher = Poseidon2Hasher::default(); -eddsa_verify_with_hasher(pub_key_a.x, pub_key_a.y, s_a, r8_a.x, r8_a.y, msg, &mut hasher); +eddsa_verify::(pub_key_a.x, pub_key_a.y, s_a, r8_a.x, r8_a.y, msg); ``` diff --git a/noir_stdlib/src/eddsa.nr b/noir_stdlib/src/eddsa.nr index 3aff6043ffd..1ab0158af8f 100644 --- a/noir_stdlib/src/eddsa.nr +++ b/noir_stdlib/src/eddsa.nr @@ -3,6 +3,7 @@ use crate::ec::consts::te::baby_jubjub; use crate::ec::tecurve::affine::Point as TEPoint; use crate::hash::{Hash, Hasher, BuildHasher, BuildHasherDefault}; use crate::hash::poseidon::PoseidonHasher; +use crate::default::Default; // Returns true if signature is valid pub fn eddsa_poseidon_verify( @@ -13,28 +14,25 @@ pub fn eddsa_poseidon_verify( signature_r8_y: Field, message: Field ) -> bool { - let mut hasher = PoseidonHasher::default(); - eddsa_verify_with_hasher( + eddsa_verify::( pub_key_x, pub_key_y, signature_s, signature_r8_x, signature_r8_y, - message, - &mut hasher + message ) } -pub fn eddsa_verify_with_hasher( +pub fn eddsa_verify( pub_key_x: Field, pub_key_y: Field, signature_s: Field, signature_r8_x: Field, signature_r8_y: Field, - message: Field, - hasher: &mut H + message: Field ) -> bool -where H: Hasher { +where H: Hasher + Default { // Verifies by testing: // S * B8 = R8 + H(R8, A, m) * A8 let bjj = baby_jubjub(); @@ -47,12 +45,13 @@ where H: Hasher { // Ensure S < Subgroup Order assert(signature_s.lt(bjj.suborder)); // Calculate the h = H(R, A, msg) - signature_r8_x.hash(hasher); - signature_r8_y.hash(hasher); - pub_key_x.hash(hasher); - pub_key_y.hash(hasher); - message.hash(hasher); - let hash: Field = (*hasher).finish(); + let mut hasher: H = H::default(); + hasher.write(signature_r8_x); + hasher.write(signature_r8_y); + hasher.write(pub_key_x); + hasher.write(pub_key_y); + hasher.write(message); + let hash: Field = hasher.finish(); // Calculate second part of the right side: right2 = h*8*A // Multiply by 8 by doubling 3 times. This also ensures that the result is in the subgroup. let pub_key_mul_2 = bjj.curve.add(pub_key, pub_key); diff --git a/test_programs/execution_success/eddsa/src/main.nr b/test_programs/execution_success/eddsa/src/main.nr index 012c8466f2f..ada15d5405c 100644 --- a/test_programs/execution_success/eddsa/src/main.nr +++ b/test_programs/execution_success/eddsa/src/main.nr @@ -2,7 +2,7 @@ use dep::std::compat; use dep::std::ec::consts::te::baby_jubjub; use dep::std::ec::tecurve::affine::Point as TEPoint; use dep::std::hash; -use dep::std::eddsa::{eddsa_to_pub, eddsa_poseidon_verify, eddsa_verify_with_hasher}; +use dep::std::eddsa::{eddsa_to_pub, eddsa_poseidon_verify, eddsa_verify}; use dep::std::hash::poseidon2::Poseidon2Hasher; fn main(msg: pub Field, _priv_key_a: Field, _priv_key_b: Field) { @@ -50,7 +50,6 @@ fn main(msg: pub Field, _priv_key_a: Field, _priv_key_b: Field) { // User A's signature over the message can't be used with another message assert(!eddsa_poseidon_verify(pub_key_a.x, pub_key_a.y, s_a, r8_a.x, r8_a.y, msg + 1)); // Using a different hash should fail - let mut hasher = Poseidon2Hasher::default(); - assert(!eddsa_verify_with_hasher(pub_key_a.x, pub_key_a.y, s_a, r8_a.x, r8_a.y, msg, &mut hasher)); + assert(!eddsa_verify::(pub_key_a.x, pub_key_a.y, s_a, r8_a.x, r8_a.y, msg)); } } From d8e96ef86e3e246e8dbba48e1054e58ceeae9305 Mon Sep 17 00:00:00 2001 From: 0xsisyfos <107465625+0xsisyfos@users.noreply.github.com> Date: Wed, 22 May 2024 13:27:16 +0200 Subject: [PATCH 16/61] chore: update docs to represent zksync supporting necessary precompiles (#5071) Since its latest v24 upgrade, zkSync supports ecMul, ecAdd, and ecPairing. The verifier compiles and deploys on zkSync Sepolia Testnet # Description ## Problem\* Resolves ## Summary\* ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../version-v0.29.0/how_to/how-to-solidity-verifier.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/versioned_docs/version-v0.29.0/how_to/how-to-solidity-verifier.md b/docs/versioned_docs/version-v0.29.0/how_to/how-to-solidity-verifier.md index e3c7c1065da..e5ce3b7bc22 100644 --- a/docs/versioned_docs/version-v0.29.0/how_to/how-to-solidity-verifier.md +++ b/docs/versioned_docs/version-v0.29.0/how_to/how-to-solidity-verifier.md @@ -212,13 +212,14 @@ It would be incorrect to say that a Noir proof verification costs any gas at all ZK-SNARK verification depends on some precompiled cryptographic primitives such as Elliptic Curve Pairings (if you like complex math, you can read about EC Pairings [here](https://medium.com/@VitalikButerin/exploring-elliptic-curve-pairings-c73c1864e627)). Not all EVM chains support EC Pairings, notably some of the ZK-EVMs. This means that you won't be able to use the verifier contract in all of them. -For example, chains like `zkSync ERA` and `Polygon zkEVM` do not currently support these precompiles, so proof verification via Solidity verifier contracts won't work. Here's a quick list of EVM chains that have been tested and are known to work: +For example, `Polygon zkEVM` does not currently support these precompiles, so proof verification via Solidity verifier contracts won't work. Here's a quick list of EVM chains that have been tested and are known to work: - Optimism - Arbitrum - Polygon PoS - Scroll - Celo +- zkSync If you test any other chains, please open a PR on this page to update the list. See [this doc](https://github.com/noir-lang/noir-starter/tree/main/with-foundry#testing-on-chain) for more info about testing verifier contracts on different EVM chains. From 436bbdaadb2a294b94f93e53d7d3cad3859c7e46 Mon Sep 17 00:00:00 2001 From: Aztec Bot <49558828+AztecBot@users.noreply.github.com> Date: Wed, 22 May 2024 07:47:09 -0400 Subject: [PATCH 17/61] feat: Sync from aztec-packages (#5070) Automated pull of Noir development from [aztec-packages](https://github.com/AztecProtocol/aztec-packages). BEGIN_COMMIT_OVERRIDE feat: Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/6573) feat!: compile-time incorrect exec environment errors (https://github.com/AztecProtocol/aztec-packages/pull/6442) feat: Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/6555) feat: View functions with static context enforcing (https://github.com/AztecProtocol/aztec-packages/pull/6338) feat!: add is_infinite to curve addition opcode (https://github.com/AztecProtocol/aztec-packages/pull/6384) feat: Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/6500) chore!: remove backend interactions from `nargo` (https://github.com/AztecProtocol/aztec-packages/pull/6320) fix: removed plain from path in array args of contract interfaces (https://github.com/AztecProtocol/aztec-packages/pull/6497) chore: bump maximum nullifier read requests (necessary for e2e tests in AVM) (https://github.com/AztecProtocol/aztec-packages/pull/6495) Revert "chore: bump maximum nullifier read requests (necessary for e2e tests in AVM)" (https://github.com/AztecProtocol/aztec-packages/pull/6483) chore: bump maximum nullifier read requests (necessary for e2e tests in AVM) (https://github.com/AztecProtocol/aztec-packages/pull/6462) fix: Check for public args in aztec functions (https://github.com/AztecProtocol/aztec-packages/pull/6355) feat: Move abi demonomorphizer to noir_codegen and use noir_codegen in protocol types (https://github.com/AztecProtocol/aztec-packages/pull/6302) feat!: switch `bb` over to read ACIR from nargo artifacts (https://github.com/AztecProtocol/aztec-packages/pull/6283) feat: ToRadix BB + avm transpiler support (https://github.com/AztecProtocol/aztec-packages/pull/6330) feat: Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/6332) fix: temporarily revert to_radix blackbox (https://github.com/AztecProtocol/aztec-packages/pull/6304) feat: move to_radix to a blackbox (https://github.com/AztecProtocol/aztec-packages/pull/6294) chore: skip formatting informattable comments (https://github.com/AztecProtocol/aztec-packages/pull/6288) chore(dsl): Update backend gateCount command to query a Program in a single request (https://github.com/AztecProtocol/aztec-packages/pull/6228) feat: Private Kernel Recursion (https://github.com/AztecProtocol/aztec-packages/pull/6278) feat: Proper padding in ts AES and constrained AES in body and header computations (https://github.com/AztecProtocol/aztec-packages/pull/6269) chore: simplify nargo CLI to read from artifacts (https://github.com/AztecProtocol/aztec-packages/pull/6279) feat: Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/6280) chore: enforce formatting of noir code (https://github.com/AztecProtocol/aztec-packages/pull/6271) feat!: specify databus arrays for BB (https://github.com/AztecProtocol/aztec-packages/pull/6239) END_COMMIT_OVERRIDE --------- Co-authored-by: TomAFrench --- .aztec-sync-commit | 2 +- .github/workflows/test-js-packages.yml | 50 ++- Cargo.lock | 284 --------------- Cargo.toml | 2 - acvm-repo/acir/codegen/acir.cpp | 270 ++++++++++++++- acvm-repo/acir/src/circuit/opcodes.rs | 16 +- .../opcodes/black_box_function_call.rs | 22 +- acvm-repo/acir/src/lib.rs | 3 +- .../acir/tests/test_program_serialization.rs | 41 ++- .../src/pwg/blackbox/embedded_curve_ops.rs | 41 ++- acvm-repo/acvm/src/pwg/blackbox/mod.rs | 12 +- acvm-repo/acvm/src/pwg/mod.rs | 2 +- acvm-repo/acvm/tests/solver.rs | 8 +- acvm-repo/acvm_js/build.sh | 2 +- acvm-repo/acvm_js/test/shared/memory_op.ts | 8 +- .../acvm_js/test/shared/multi_scalar_mul.ts | 21 +- .../src/curve_specific_solver.rs | 18 +- .../src/embedded_curve_ops.rs | 104 ++++-- acvm-repo/bn254_blackbox_solver/src/lib.rs | 16 +- acvm-repo/brillig/src/black_box.rs | 7 + acvm-repo/brillig_vm/src/black_box.rs | 78 ++++- aztec_macros/src/lib.rs | 42 ++- .../src/transforms/contract_interface.rs | 50 ++- aztec_macros/src/transforms/functions.rs | 78 ++++- aztec_macros/src/transforms/storage.rs | 114 ++++-- aztec_macros/src/utils/ast_utils.rs | 13 +- aztec_macros/src/utils/errors.rs | 12 + .../scripts/codegen-verifiers.sh | 36 +- compiler/noirc_driver/src/lib.rs | 4 - .../brillig/brillig_gen/brillig_black_box.rs | 8 +- .../src/brillig/brillig_gen/brillig_block.rs | 38 +- .../noirc_evaluator/src/brillig/brillig_ir.rs | 11 +- .../brillig/brillig_ir/codegen_intrinsic.rs | 62 ++-- .../src/brillig/brillig_ir/debug_show.rs | 13 +- .../src/brillig/brillig_ir/entry_point.rs | 2 +- .../src/ssa/acir_gen/acir_ir/acir_variable.rs | 9 +- .../ssa/acir_gen/acir_ir/generated_acir.rs | 17 +- .../noirc_evaluator/src/ssa/acir_gen/mod.rs | 14 +- cspell.json | 6 + .../barretenberg/_category_.json | 6 + .../getting_started/barretenberg/index.md | 53 +++ .../hello_noir/_category_.json | 2 +- docs/docs/getting_started/hello_noir/index.md | 41 ++- .../hello_noir/project_breakdown.md | 66 +--- .../getting_started/tooling/noir_codegen.md | 2 +- docs/docs/how_to/how-to-oracles.md | 4 +- docs/docs/how_to/how-to-solidity-verifier.md | 44 ++- .../docs/noir/concepts/data_types/booleans.md | 3 - .../docs/noir/concepts/data_types/integers.md | 2 +- examples/codegen_verifier/.gitignore | 4 + examples/codegen_verifier/Nargo.toml | 7 + examples/codegen_verifier/Prover.toml | 2 + examples/codegen_verifier/codegen_verifier.sh | 38 ++ examples/codegen_verifier/foundry.toml | 6 + examples/codegen_verifier/src/main.nr | 3 + examples/codegen_verifier/test.sh | 15 + examples/prove_and_verify/Nargo.toml | 7 + examples/prove_and_verify/Prover.toml | 2 + examples/prove_and_verify/proofs/proof | Bin 0 -> 2176 bytes examples/prove_and_verify/prove_and_verify.sh | 14 + examples/prove_and_verify/src/main.nr | 3 + examples/prove_and_verify/test.sh | 10 + noir_stdlib/src/aes128.nr | 3 + noir_stdlib/src/embedded_curve_ops.nr | 39 ++- noir_stdlib/src/field/bn254.nr | 57 +-- scripts/install_bb.sh | 9 + .../intrinsic_die/src/main.nr | 4 +- .../brillig_embedded_curve/src/main.nr | 10 +- .../embedded_curve_ops/src/main.nr | 10 +- .../trait_method_mut_self/src/main.nr | 22 ++ .../execution_success/unit_value/Nargo.toml | 4 +- .../embedded_curve_ops/Nargo.toml | 7 + .../embedded_curve_ops/src/main.nr | 37 ++ test_programs/rebuild.sh | 5 +- tooling/backend_interface/CHANGELOG.md | 233 ------------- tooling/backend_interface/Cargo.toml | 35 -- tooling/backend_interface/src/cli/contract.rs | 71 ---- tooling/backend_interface/src/cli/gates.rs | 64 ---- tooling/backend_interface/src/cli/mod.rs | 39 --- .../src/cli/proof_as_fields.rs | 38 -- tooling/backend_interface/src/cli/prove.rs | 66 ---- tooling/backend_interface/src/cli/verify.rs | 74 ---- tooling/backend_interface/src/cli/version.rs | 29 -- .../backend_interface/src/cli/vk_as_fields.rs | 39 --- tooling/backend_interface/src/cli/write_vk.rs | 58 ---- tooling/backend_interface/src/download.rs | 58 ---- tooling/backend_interface/src/lib.rs | 150 -------- tooling/backend_interface/src/proof_system.rs | 169 --------- .../backend_interface/src/smart_contract.rs | 70 ---- .../test-binaries/mock_backend/Cargo.lock | 223 ------------ .../test-binaries/mock_backend/Cargo.toml | 11 - .../mock_backend/src/contract_cmd.rs | 21 -- .../mock_backend/src/gates_cmd.rs | 18 - .../test-binaries/mock_backend/src/main.rs | 41 --- .../mock_backend/src/prove_cmd.rs | 25 -- .../mock_backend/src/verify_cmd.rs | 24 -- .../mock_backend/src/write_vk_cmd.rs | 20 -- tooling/bb_abstraction_leaks/Cargo.toml | 17 - tooling/bb_abstraction_leaks/build.rs | 58 ---- tooling/bb_abstraction_leaks/src/lib.rs | 26 -- tooling/debugger/src/context.rs | 6 +- tooling/debugger/tests/debug.rs | 6 - tooling/lsp/src/solver.rs | 19 +- tooling/nargo/src/artifacts/contract.rs | 6 +- tooling/nargo/src/artifacts/debug.rs | 27 ++ tooling/nargo/src/artifacts/program.rs | 2 +- tooling/nargo/src/constants.rs | 2 - tooling/nargo/src/package.rs | 7 +- tooling/nargo_cli/Cargo.toml | 6 +- tooling/nargo_cli/build.rs | 7 - tooling/nargo_cli/src/backends.rs | 39 --- .../src/cli/backend_cmd/current_cmd.rs | 13 - .../src/cli/backend_cmd/install_cmd.rs | 30 -- .../nargo_cli/src/cli/backend_cmd/ls_cmd.rs | 34 -- tooling/nargo_cli/src/cli/backend_cmd/mod.rs | 41 --- .../src/cli/backend_cmd/uninstall_cmd.rs | 59 ---- .../nargo_cli/src/cli/backend_cmd/use_cmd.rs | 26 -- tooling/nargo_cli/src/cli/check_cmd.rs | 18 +- .../nargo_cli/src/cli/codegen_verifier_cmd.rs | 83 ----- tooling/nargo_cli/src/cli/compile_cmd.rs | 21 +- tooling/nargo_cli/src/cli/execute_cmd.rs | 35 +- tooling/nargo_cli/src/cli/fs/inputs.rs | 98 ------ tooling/nargo_cli/src/cli/fs/mod.rs | 12 - tooling/nargo_cli/src/cli/fs/program.rs | 11 - tooling/nargo_cli/src/cli/fs/proof.rs | 20 -- tooling/nargo_cli/src/cli/info_cmd.rs | 159 ++------- tooling/nargo_cli/src/cli/mod.rs | 25 +- tooling/nargo_cli/src/cli/prove_cmd.rs | 154 --------- tooling/nargo_cli/src/cli/verify_cmd.rs | 109 ------ tooling/nargo_cli/src/errors.rs | 27 +- tooling/nargo_cli/src/main.rs | 1 - tooling/nargo_cli/tests/codegen-verifier.rs | 37 -- tooling/nargo_cli/tests/hello_world.rs | 15 +- tooling/nargo_fmt/src/config.rs | 2 +- tooling/noir_codegen/src/index.ts | 79 +---- tooling/noir_codegen/src/main.ts | 2 +- tooling/noir_codegen/src/noir_types.ts | 187 ---------- tooling/noir_codegen/src/parseArgs.ts | 17 + .../src/utils/abi_type_with_generics.ts | 139 ++++++++ .../noir_codegen/src/utils/demonomorphizer.ts | 284 +++++++++++++++ .../src/utils/typings_generator.ts | 324 ++++++++++++++++++ tooling/noir_codegen/test/index.test.ts | 18 +- tooling/noir_codegen/test/test_lib/src/lib.nr | 22 +- .../noir_js_backend_barretenberg/package.json | 2 +- yarn.lock | 10 +- 145 files changed, 2262 insertions(+), 3733 deletions(-) create mode 100644 docs/docs/getting_started/barretenberg/_category_.json create mode 100644 docs/docs/getting_started/barretenberg/index.md create mode 100644 examples/codegen_verifier/.gitignore create mode 100644 examples/codegen_verifier/Nargo.toml create mode 100644 examples/codegen_verifier/Prover.toml create mode 100755 examples/codegen_verifier/codegen_verifier.sh create mode 100644 examples/codegen_verifier/foundry.toml create mode 100644 examples/codegen_verifier/src/main.nr create mode 100755 examples/codegen_verifier/test.sh create mode 100644 examples/prove_and_verify/Nargo.toml create mode 100644 examples/prove_and_verify/Prover.toml create mode 100644 examples/prove_and_verify/proofs/proof create mode 100755 examples/prove_and_verify/prove_and_verify.sh create mode 100644 examples/prove_and_verify/src/main.nr create mode 100755 examples/prove_and_verify/test.sh create mode 100755 scripts/install_bb.sh create mode 100644 test_programs/noir_test_success/embedded_curve_ops/Nargo.toml create mode 100644 test_programs/noir_test_success/embedded_curve_ops/src/main.nr delete mode 100644 tooling/backend_interface/CHANGELOG.md delete mode 100644 tooling/backend_interface/Cargo.toml delete mode 100644 tooling/backend_interface/src/cli/contract.rs delete mode 100644 tooling/backend_interface/src/cli/gates.rs delete mode 100644 tooling/backend_interface/src/cli/mod.rs delete mode 100644 tooling/backend_interface/src/cli/proof_as_fields.rs delete mode 100644 tooling/backend_interface/src/cli/prove.rs delete mode 100644 tooling/backend_interface/src/cli/verify.rs delete mode 100644 tooling/backend_interface/src/cli/version.rs delete mode 100644 tooling/backend_interface/src/cli/vk_as_fields.rs delete mode 100644 tooling/backend_interface/src/cli/write_vk.rs delete mode 100644 tooling/backend_interface/src/download.rs delete mode 100644 tooling/backend_interface/src/lib.rs delete mode 100644 tooling/backend_interface/src/proof_system.rs delete mode 100644 tooling/backend_interface/src/smart_contract.rs delete mode 100644 tooling/backend_interface/test-binaries/mock_backend/Cargo.lock delete mode 100644 tooling/backend_interface/test-binaries/mock_backend/Cargo.toml delete mode 100644 tooling/backend_interface/test-binaries/mock_backend/src/contract_cmd.rs delete mode 100644 tooling/backend_interface/test-binaries/mock_backend/src/gates_cmd.rs delete mode 100644 tooling/backend_interface/test-binaries/mock_backend/src/main.rs delete mode 100644 tooling/backend_interface/test-binaries/mock_backend/src/prove_cmd.rs delete mode 100644 tooling/backend_interface/test-binaries/mock_backend/src/verify_cmd.rs delete mode 100644 tooling/backend_interface/test-binaries/mock_backend/src/write_vk_cmd.rs delete mode 100644 tooling/bb_abstraction_leaks/Cargo.toml delete mode 100644 tooling/bb_abstraction_leaks/build.rs delete mode 100644 tooling/bb_abstraction_leaks/src/lib.rs delete mode 100644 tooling/nargo_cli/src/backends.rs delete mode 100644 tooling/nargo_cli/src/cli/backend_cmd/current_cmd.rs delete mode 100644 tooling/nargo_cli/src/cli/backend_cmd/install_cmd.rs delete mode 100644 tooling/nargo_cli/src/cli/backend_cmd/ls_cmd.rs delete mode 100644 tooling/nargo_cli/src/cli/backend_cmd/mod.rs delete mode 100644 tooling/nargo_cli/src/cli/backend_cmd/uninstall_cmd.rs delete mode 100644 tooling/nargo_cli/src/cli/backend_cmd/use_cmd.rs delete mode 100644 tooling/nargo_cli/src/cli/codegen_verifier_cmd.rs delete mode 100644 tooling/nargo_cli/src/cli/fs/proof.rs delete mode 100644 tooling/nargo_cli/src/cli/prove_cmd.rs delete mode 100644 tooling/nargo_cli/src/cli/verify_cmd.rs delete mode 100644 tooling/nargo_cli/tests/codegen-verifier.rs delete mode 100644 tooling/noir_codegen/src/noir_types.ts create mode 100644 tooling/noir_codegen/src/utils/abi_type_with_generics.ts create mode 100644 tooling/noir_codegen/src/utils/demonomorphizer.ts create mode 100644 tooling/noir_codegen/src/utils/typings_generator.ts diff --git a/.aztec-sync-commit b/.aztec-sync-commit index b9e87cffedc..82e81e9d74c 100644 --- a/.aztec-sync-commit +++ b/.aztec-sync-commit @@ -1 +1 @@ -1c74387e56b49102043fc6701735325a891e6c65 +221e2479622aef8e70120dc0a9f91ffcbc99efba diff --git a/.github/workflows/test-js-packages.yml b/.github/workflows/test-js-packages.yml index e6098dd269c..9668e3f629f 100644 --- a/.github/workflows/test-js-packages.yml +++ b/.github/workflows/test-js-packages.yml @@ -399,6 +399,12 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Install `bb` + run: | + ./scripts/install_bb.sh + echo "$HOME/.barretenberg/" >> $GITHUB_PATH + export PATH="$PATH:$HOME/.barretenberg/" + - name: Download nargo binary uses: actions/download-artifact@v4 with: @@ -448,7 +454,7 @@ jobs: test-integration-browser: name: Integration Tests (Browser) runs-on: ubuntu-latest - needs: [build-acvm-js, build-noir-wasm, build-nargo, build-noirc-abi] + needs: [build-acvm-js, build-noir-wasm, build-noirc-abi] timeout-minutes: 30 steps: @@ -490,6 +496,47 @@ jobs: run: | yarn test:browser + test-examples: + name: Example scripts + runs-on: ubuntu-latest + needs: [build-nargo] + timeout-minutes: 30 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1.2.0 + + - name: Install `bb` + run: | + ./scripts/install_bb.sh + echo "$HOME/.barretenberg/" >> $GITHUB_PATH + export PATH="$PATH:$HOME/.barretenberg/" + + - name: Download nargo binary + uses: actions/download-artifact@v4 + with: + name: nargo + path: ./nargo + + - name: Set nargo on PATH + run: | + nargo_binary="${{ github.workspace }}/nargo/nargo" + chmod +x $nargo_binary + echo "$(dirname $nargo_binary)" >> $GITHUB_PATH + export PATH="$PATH:$(dirname $nargo_binary)" + nargo -V + + - name: Run `prove_and_verify` + working-directory: ./examples/prove_and_verify + run: ./test.sh + + - name: Run `codegen_verifier` + working-directory: ./examples/codegen_verifier + run: ./test.sh + # This is a job which depends on all test jobs and reports the overall status. # This allows us to add/remove test jobs without having to update the required workflows. tests-end: @@ -507,6 +554,7 @@ jobs: - test-noir-codegen - test-integration-node - test-integration-browser + - test-examples steps: - name: Report overall success diff --git a/Cargo.lock b/Cargo.lock index b5dc6f9bfdf..bfc012d23f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -452,25 +452,6 @@ dependencies = [ "regex", ] -[[package]] -name = "backend-interface" -version = "0.30.0" -dependencies = [ - "acvm", - "bb_abstraction_leaks", - "build-target", - "const_format", - "dirs", - "flate2", - "reqwest", - "serde_json", - "tar", - "tempfile", - "test-binary", - "thiserror", - "tracing", -] - [[package]] name = "backtrace" version = "0.3.68" @@ -510,15 +491,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "bb_abstraction_leaks" -version = "0.11.0" -dependencies = [ - "acvm", - "build-target", - "const_format", -] - [[package]] name = "bincode" version = "1.3.3" @@ -664,12 +636,6 @@ dependencies = [ "safe-regex", ] -[[package]] -name = "build-target" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "832133bbabbbaa9fbdba793456a2827627a7d2b8fb96032fa1e7666d7895832b" - [[package]] name = "bumpalo" version = "3.13.0" @@ -1408,15 +1374,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" -[[package]] -name = "encoding_rs" -version = "0.8.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" -dependencies = [ - "cfg-if 1.0.0", -] - [[package]] name = "endian-type" version = "0.1.2" @@ -1787,25 +1744,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 2.2.6", - "slab", - "tokio", - "tokio-util 0.7.10", - "tracing", -] - [[package]] name = "half" version = "1.8.2" @@ -1922,7 +1860,6 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", "http", "http-body", "httparse", @@ -1936,20 +1873,6 @@ dependencies = [ "want", ] -[[package]] -name = "hyper-rustls" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" -dependencies = [ - "futures-util", - "http", - "hyper", - "rustls", - "tokio", - "tokio-rustls", -] - [[package]] name = "iai" version = "0.1.1" @@ -2137,12 +2060,6 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "ipnet" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" - [[package]] name = "is-terminal" version = "0.4.9" @@ -2517,12 +2434,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - [[package]] name = "miniz_oxide" version = "0.7.1" @@ -2589,7 +2500,6 @@ dependencies = [ "assert_cmd", "assert_fs", "async-lsp", - "backend-interface", "bn254_blackbox_solver", "build-data", "clap", @@ -2600,7 +2510,6 @@ dependencies = [ "dap", "dirs", "fm", - "hex", "iai", "iter-extended", "nargo", @@ -3678,45 +3587,6 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" -[[package]] -name = "reqwest" -version = "0.11.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" -dependencies = [ - "base64 0.21.2", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-rustls", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding 2.3.1", - "pin-project-lite", - "rustls", - "rustls-pemfile", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-rustls", - "tower-service", - "url 2.5.0", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots", - "winreg", -] - [[package]] name = "rexpect" version = "0.5.0" @@ -3750,36 +3620,6 @@ dependencies = [ "bytemuck", ] -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin 0.5.2", - "untrusted 0.7.1", - "web-sys", - "winapi", -] - -[[package]] -name = "ring" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" -dependencies = [ - "cc", - "cfg-if 1.0.0", - "getrandom 0.2.15", - "libc", - "spin 0.9.8", - "untrusted 0.9.0", - "windows-sys 0.52.0", -] - [[package]] name = "rust-embed" version = "6.8.1" @@ -3848,37 +3688,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "rustls" -version = "0.21.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" -dependencies = [ - "log", - "ring 0.17.8", - "rustls-webpki", - "sct", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" -dependencies = [ - "base64 0.21.2", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", -] - [[package]] name = "rustversion" version = "1.0.14" @@ -4011,16 +3820,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" -dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", -] - [[package]] name = "sec1" version = "0.3.0" @@ -4129,18 +3928,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - [[package]] name = "serde_with" version = "3.2.0" @@ -4301,18 +4088,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - [[package]] name = "spki" version = "0.6.0" @@ -4430,17 +4205,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tar" -version = "0.4.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" -dependencies = [ - "filetime", - "libc", - "xattr", -] - [[package]] name = "tempfile" version = "3.8.0" @@ -4646,16 +4410,6 @@ dependencies = [ "syn 2.0.64", ] -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls", - "tokio", -] - [[package]] name = "tokio-stream" version = "0.1.15" @@ -4693,7 +4447,6 @@ dependencies = [ "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -4940,18 +4693,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - [[package]] name = "url" version = "1.7.2" @@ -5151,12 +4892,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki-roots" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" - [[package]] name = "winapi" version = "0.3.9" @@ -5338,25 +5073,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if 1.0.0", - "windows-sys 0.48.0", -] - -[[package]] -name = "xattr" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" -dependencies = [ - "libc", -] - [[package]] name = "zerocopy" version = "0.7.32" diff --git a/Cargo.toml b/Cargo.toml index 670ae36dd4b..182580f8d67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,8 +13,6 @@ members = [ "compiler/fm", "compiler/wasm", # Crates related to tooling built on top of the Noir compiler - "tooling/backend_interface", - "tooling/bb_abstraction_leaks", "tooling/lsp", "tooling/debugger", "tooling/nargo", diff --git a/acvm-repo/acir/codegen/acir.cpp b/acvm-repo/acir/codegen/acir.cpp index b7e75c4320d..47e184a6332 100644 --- a/acvm-repo/acir/codegen/acir.cpp +++ b/acvm-repo/acir/codegen/acir.cpp @@ -149,7 +149,7 @@ namespace Program { struct MultiScalarMul { std::vector points; std::vector scalars; - std::array outputs; + std::array outputs; friend bool operator==(const MultiScalarMul&, const MultiScalarMul&); std::vector bincodeSerialize() const; @@ -157,11 +157,9 @@ namespace Program { }; struct EmbeddedCurveAdd { - Program::FunctionInput input1_x; - Program::FunctionInput input1_y; - Program::FunctionInput input2_x; - Program::FunctionInput input2_y; - std::array outputs; + std::array input1; + std::array input2; + std::array outputs; friend bool operator==(const EmbeddedCurveAdd&, const EmbeddedCurveAdd&); std::vector bincodeSerialize() const; @@ -292,6 +290,33 @@ namespace Program { static BlockId bincodeDeserialize(std::vector); }; + struct BlockType { + + struct Memory { + friend bool operator==(const Memory&, const Memory&); + std::vector bincodeSerialize() const; + static Memory bincodeDeserialize(std::vector); + }; + + struct CallData { + friend bool operator==(const CallData&, const CallData&); + std::vector bincodeSerialize() const; + static CallData bincodeDeserialize(std::vector); + }; + + struct ReturnData { + friend bool operator==(const ReturnData&, const ReturnData&); + std::vector bincodeSerialize() const; + static ReturnData bincodeDeserialize(std::vector); + }; + + std::variant value; + + friend bool operator==(const BlockType&, const BlockType&); + std::vector bincodeSerialize() const; + static BlockType bincodeDeserialize(std::vector); + }; + struct Expression { std::vector> mul_terms; std::vector> linear_combinations; @@ -428,6 +453,7 @@ namespace Program { struct MemoryInit { Program::BlockId block_id; std::vector init; + Program::BlockType block_type; friend bool operator==(const MemoryInit&, const MemoryInit&); std::vector bincodeSerialize() const; @@ -754,8 +780,10 @@ namespace Program { struct EmbeddedCurveAdd { Program::MemoryAddress input1_x; Program::MemoryAddress input1_y; + Program::MemoryAddress input1_infinite; Program::MemoryAddress input2_x; Program::MemoryAddress input2_y; + Program::MemoryAddress input2_infinite; Program::HeapArray result; friend bool operator==(const EmbeddedCurveAdd&, const EmbeddedCurveAdd&); @@ -842,7 +870,17 @@ namespace Program { static Sha256Compression bincodeDeserialize(std::vector); }; - std::variant value; + struct ToRadix { + Program::MemoryAddress input; + uint32_t radix; + Program::HeapArray output; + + friend bool operator==(const ToRadix&, const ToRadix&); + std::vector bincodeSerialize() const; + static ToRadix bincodeDeserialize(std::vector); + }; + + std::variant value; friend bool operator==(const BlackBoxOp&, const BlackBoxOp&); std::vector bincodeSerialize() const; @@ -2762,10 +2800,8 @@ Program::BlackBoxFuncCall::MultiScalarMul serde::Deserializable template void serde::Serializable::serialize(const Program::BlackBoxFuncCall::EmbeddedCurveAdd &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.input1_x, serializer); - serde::Serializable::serialize(obj.input1_y, serializer); - serde::Serializable::serialize(obj.input2_x, serializer); - serde::Serializable::serialize(obj.input2_y, serializer); + serde::Serializable::serialize(obj.input1, serializer); + serde::Serializable::serialize(obj.input2, serializer); serde::Serializable::serialize(obj.outputs, serializer); } @@ -2801,10 +2835,8 @@ template <> template Program::BlackBoxFuncCall::EmbeddedCurveAdd serde::Deserializable::deserialize(Deserializer &deserializer) { Program::BlackBoxFuncCall::EmbeddedCurveAdd obj; - obj.input1_x = serde::Deserializable::deserialize(deserializer); - obj.input1_y = serde::Deserializable::deserialize(deserializer); - obj.input2_x = serde::Deserializable::deserialize(deserializer); - obj.input2_y = serde::Deserializable::deserialize(deserializer); + obj.input1 = serde::Deserializable::deserialize(deserializer); + obj.input2 = serde::Deserializable::deserialize(deserializer); obj.outputs = serde::Deserializable::deserialize(deserializer); return obj; } @@ -3871,8 +3903,10 @@ namespace Program { inline bool operator==(const BlackBoxOp::EmbeddedCurveAdd &lhs, const BlackBoxOp::EmbeddedCurveAdd &rhs) { if (!(lhs.input1_x == rhs.input1_x)) { return false; } if (!(lhs.input1_y == rhs.input1_y)) { return false; } + if (!(lhs.input1_infinite == rhs.input1_infinite)) { return false; } if (!(lhs.input2_x == rhs.input2_x)) { return false; } if (!(lhs.input2_y == rhs.input2_y)) { return false; } + if (!(lhs.input2_infinite == rhs.input2_infinite)) { return false; } if (!(lhs.result == rhs.result)) { return false; } return true; } @@ -3899,8 +3933,10 @@ template void serde::Serializable::serialize(const Program::BlackBoxOp::EmbeddedCurveAdd &obj, Serializer &serializer) { serde::Serializable::serialize(obj.input1_x, serializer); serde::Serializable::serialize(obj.input1_y, serializer); + serde::Serializable::serialize(obj.input1_infinite, serializer); serde::Serializable::serialize(obj.input2_x, serializer); serde::Serializable::serialize(obj.input2_y, serializer); + serde::Serializable::serialize(obj.input2_infinite, serializer); serde::Serializable::serialize(obj.result, serializer); } @@ -3910,8 +3946,10 @@ Program::BlackBoxOp::EmbeddedCurveAdd serde::Deserializable::deserialize(deserializer); obj.input1_y = serde::Deserializable::deserialize(deserializer); + obj.input1_infinite = serde::Deserializable::deserialize(deserializer); obj.input2_x = serde::Deserializable::deserialize(deserializer); obj.input2_y = serde::Deserializable::deserialize(deserializer); + obj.input2_infinite = serde::Deserializable::deserialize(deserializer); obj.result = serde::Deserializable::deserialize(deserializer); return obj; } @@ -4265,6 +4303,50 @@ Program::BlackBoxOp::Sha256Compression serde::Deserializable BlackBoxOp::ToRadix::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::ToRadix BlackBoxOp::ToRadix::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Program + +template <> +template +void serde::Serializable::serialize(const Program::BlackBoxOp::ToRadix &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.input, serializer); + serde::Serializable::serialize(obj.radix, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Program::BlackBoxOp::ToRadix serde::Deserializable::deserialize(Deserializer &deserializer) { + Program::BlackBoxOp::ToRadix obj; + obj.input = serde::Deserializable::deserialize(deserializer); + obj.radix = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + namespace Program { inline bool operator==(const BlockId &lhs, const BlockId &rhs) { @@ -4307,6 +4389,153 @@ Program::BlockId serde::Deserializable::deserialize(Deserializ return obj; } +namespace Program { + + inline bool operator==(const BlockType &lhs, const BlockType &rhs) { + if (!(lhs.value == rhs.value)) { return false; } + return true; + } + + inline std::vector BlockType::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlockType BlockType::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Program + +template <> +template +void serde::Serializable::serialize(const Program::BlockType &obj, Serializer &serializer) { + serializer.increase_container_depth(); + serde::Serializable::serialize(obj.value, serializer); + serializer.decrease_container_depth(); +} + +template <> +template +Program::BlockType serde::Deserializable::deserialize(Deserializer &deserializer) { + deserializer.increase_container_depth(); + Program::BlockType obj; + obj.value = serde::Deserializable::deserialize(deserializer); + deserializer.decrease_container_depth(); + return obj; +} + +namespace Program { + + inline bool operator==(const BlockType::Memory &lhs, const BlockType::Memory &rhs) { + return true; + } + + inline std::vector BlockType::Memory::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlockType::Memory BlockType::Memory::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Program + +template <> +template +void serde::Serializable::serialize(const Program::BlockType::Memory &obj, Serializer &serializer) { +} + +template <> +template +Program::BlockType::Memory serde::Deserializable::deserialize(Deserializer &deserializer) { + Program::BlockType::Memory obj; + return obj; +} + +namespace Program { + + inline bool operator==(const BlockType::CallData &lhs, const BlockType::CallData &rhs) { + return true; + } + + inline std::vector BlockType::CallData::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlockType::CallData BlockType::CallData::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Program + +template <> +template +void serde::Serializable::serialize(const Program::BlockType::CallData &obj, Serializer &serializer) { +} + +template <> +template +Program::BlockType::CallData serde::Deserializable::deserialize(Deserializer &deserializer) { + Program::BlockType::CallData obj; + return obj; +} + +namespace Program { + + inline bool operator==(const BlockType::ReturnData &lhs, const BlockType::ReturnData &rhs) { + return true; + } + + inline std::vector BlockType::ReturnData::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlockType::ReturnData BlockType::ReturnData::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Program + +template <> +template +void serde::Serializable::serialize(const Program::BlockType::ReturnData &obj, Serializer &serializer) { +} + +template <> +template +Program::BlockType::ReturnData serde::Deserializable::deserialize(Deserializer &deserializer) { + Program::BlockType::ReturnData obj; + return obj; +} + namespace Program { inline bool operator==(const BrilligBytecode &lhs, const BrilligBytecode &rhs) { @@ -6443,6 +6672,7 @@ namespace Program { inline bool operator==(const Opcode::MemoryInit &lhs, const Opcode::MemoryInit &rhs) { if (!(lhs.block_id == rhs.block_id)) { return false; } if (!(lhs.init == rhs.init)) { return false; } + if (!(lhs.block_type == rhs.block_type)) { return false; } return true; } @@ -6468,6 +6698,7 @@ template void serde::Serializable::serialize(const Program::Opcode::MemoryInit &obj, Serializer &serializer) { serde::Serializable::serialize(obj.block_id, serializer); serde::Serializable::serialize(obj.init, serializer); + serde::Serializable::serialize(obj.block_type, serializer); } template <> @@ -6476,6 +6707,7 @@ Program::Opcode::MemoryInit serde::Deserializable:: Program::Opcode::MemoryInit obj; obj.block_id = serde::Deserializable::deserialize(deserializer); obj.init = serde::Deserializable::deserialize(deserializer); + obj.block_type = serde::Deserializable::deserialize(deserializer); return obj; } diff --git a/acvm-repo/acir/src/circuit/opcodes.rs b/acvm-repo/acir/src/circuit/opcodes.rs index 7db317c41ab..e6dc11dac78 100644 --- a/acvm-repo/acir/src/circuit/opcodes.rs +++ b/acvm-repo/acir/src/circuit/opcodes.rs @@ -11,6 +11,13 @@ mod memory_operation; pub use black_box_function_call::{BlackBoxFuncCall, FunctionInput}; pub use memory_operation::{BlockId, MemOp}; +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum BlockType { + Memory, + CallData, + ReturnData, +} + #[allow(clippy::large_enum_variant)] #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum Opcode { @@ -30,6 +37,7 @@ pub enum Opcode { MemoryInit { block_id: BlockId, init: Vec, + block_type: BlockType, }, /// Calls to unconstrained functions BrilligCall { @@ -103,8 +111,12 @@ impl std::fmt::Display for Opcode { write!(f, "(id: {}, op {} at: {}) ", block_id.0, op.operation, op.index) } } - Opcode::MemoryInit { block_id, init } => { - write!(f, "INIT ")?; + Opcode::MemoryInit { block_id, init, block_type: databus } => { + match databus { + BlockType::Memory => write!(f, "INIT ")?, + BlockType::CallData => write!(f, "INIT CALLDATA ")?, + BlockType::ReturnData => write!(f, "INIT RETURNDATA ")?, + } write!(f, "(id: {}, len: {}) ", block_id.0, init.len()) } // We keep the display for a BrilligCall and circuit Call separate as they diff --git a/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs b/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs index 115a33c1c9d..b0e77b15c2c 100644 --- a/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs +++ b/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs @@ -89,14 +89,12 @@ pub enum BlackBoxFuncCall { MultiScalarMul { points: Vec, scalars: Vec, - outputs: (Witness, Witness), + outputs: (Witness, Witness, Witness), }, EmbeddedCurveAdd { - input1_x: FunctionInput, - input1_y: FunctionInput, - input2_x: FunctionInput, - input2_y: FunctionInput, - outputs: (Witness, Witness), + input1: Box<[FunctionInput; 3]>, + input2: Box<[FunctionInput; 3]>, + outputs: (Witness, Witness, Witness), }, Keccak256 { inputs: Vec, @@ -245,9 +243,9 @@ impl BlackBoxFuncCall { inputs.extend(scalars.iter().copied()); inputs } - BlackBoxFuncCall::EmbeddedCurveAdd { - input1_x, input1_y, input2_x, input2_y, .. - } => vec![*input1_x, *input1_y, *input2_x, *input2_y], + BlackBoxFuncCall::EmbeddedCurveAdd { input1, input2, .. } => { + vec![input1[0], input1[1], input2[0], input2[1]] + } BlackBoxFuncCall::RANGE { input } => vec![*input], BlackBoxFuncCall::SchnorrVerify { public_key_x, @@ -343,9 +341,11 @@ impl BlackBoxFuncCall { | BlackBoxFuncCall::EcdsaSecp256k1 { output, .. } | BlackBoxFuncCall::PedersenHash { output, .. } | BlackBoxFuncCall::EcdsaSecp256r1 { output, .. } => vec![*output], + BlackBoxFuncCall::PedersenCommitment { outputs, .. } => vec![outputs.0, outputs.1], BlackBoxFuncCall::MultiScalarMul { outputs, .. } - | BlackBoxFuncCall::PedersenCommitment { outputs, .. } - | BlackBoxFuncCall::EmbeddedCurveAdd { outputs, .. } => vec![outputs.0, outputs.1], + | BlackBoxFuncCall::EmbeddedCurveAdd { outputs, .. } => { + vec![outputs.0, outputs.1, outputs.2] + } BlackBoxFuncCall::RANGE { .. } | BlackBoxFuncCall::RecursiveAggregation { .. } | BlackBoxFuncCall::BigIntFromLeBytes { .. } diff --git a/acvm-repo/acir/src/lib.rs b/acvm-repo/acir/src/lib.rs index 24f27aae06f..f60f1b46b6a 100644 --- a/acvm-repo/acir/src/lib.rs +++ b/acvm-repo/acir/src/lib.rs @@ -41,7 +41,7 @@ mod reflection { circuit::{ brillig::{BrilligInputs, BrilligOutputs}, directives::Directive, - opcodes::BlackBoxFuncCall, + opcodes::{BlackBoxFuncCall, BlockType}, AssertionPayload, Circuit, ExpressionOrMemory, ExpressionWidth, Opcode, OpcodeLocation, Program, }, @@ -60,6 +60,7 @@ mod reflection { }; let mut tracer = Tracer::new(TracerConfig::default()); + tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); diff --git a/acvm-repo/acir/tests/test_program_serialization.rs b/acvm-repo/acir/tests/test_program_serialization.rs index d9327f784e6..19e4beb6158 100644 --- a/acvm-repo/acir/tests/test_program_serialization.rs +++ b/acvm-repo/acir/tests/test_program_serialization.rs @@ -63,19 +63,26 @@ fn multi_scalar_mul_circuit() { points: vec![ FunctionInput { witness: Witness(1), num_bits: 128 }, FunctionInput { witness: Witness(2), num_bits: 128 }, + FunctionInput { witness: Witness(3), num_bits: 1 }, ], scalars: vec![ - FunctionInput { witness: Witness(3), num_bits: 128 }, FunctionInput { witness: Witness(4), num_bits: 128 }, + FunctionInput { witness: Witness(5), num_bits: 128 }, ], - outputs: (Witness(5), Witness(6)), + outputs: (Witness(6), Witness(7), Witness(8)), }); let circuit = Circuit { - current_witness_index: 7, + current_witness_index: 9, opcodes: vec![multi_scalar_mul], - private_parameters: BTreeSet::from([Witness(1), Witness(2), Witness(3), Witness(4)]), - return_values: PublicInputs(BTreeSet::from_iter(vec![Witness(5), Witness(6)])), + private_parameters: BTreeSet::from([ + Witness(1), + Witness(2), + Witness(3), + Witness(4), + Witness(5), + ]), + return_values: PublicInputs(BTreeSet::from_iter(vec![Witness(6), Witness(7), Witness(8)])), ..Circuit::default() }; let program = Program { functions: vec![circuit], unconstrained_functions: vec![] }; @@ -83,10 +90,10 @@ fn multi_scalar_mul_circuit() { let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 85, 76, 65, 14, 0, 32, 8, 82, 179, 186, 244, 104, 159, - 30, 45, 218, 136, 141, 33, 40, 186, 93, 76, 208, 57, 31, 93, 96, 136, 47, 250, 146, 188, - 209, 39, 181, 131, 131, 187, 148, 110, 240, 246, 101, 38, 63, 180, 243, 97, 3, 125, 173, - 118, 131, 153, 0, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 141, 219, 10, 0, 32, 8, 67, 243, 214, 5, 250, 232, + 62, 189, 69, 123, 176, 132, 195, 116, 50, 149, 114, 107, 0, 97, 127, 116, 2, 75, 243, 2, + 74, 53, 122, 202, 189, 211, 15, 106, 5, 13, 116, 238, 35, 221, 81, 230, 61, 249, 37, 253, + 250, 179, 79, 109, 218, 22, 67, 227, 173, 0, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -347,7 +354,11 @@ fn complex_brillig_foreign_call() { fn memory_op_circuit() { let init = vec![Witness(1), Witness(2)]; - let memory_init = Opcode::MemoryInit { block_id: BlockId(0), init }; + let memory_init = Opcode::MemoryInit { + block_id: BlockId(0), + init, + block_type: acir::circuit::opcodes::BlockType::Memory, + }; let write = Opcode::MemoryOp { block_id: BlockId(0), op: MemOp::write_to_mem_index(FieldElement::from(1u128).into(), Witness(3).into()), @@ -371,11 +382,11 @@ fn memory_op_circuit() { let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 82, 65, 10, 0, 32, 8, 203, 180, 255, 216, 15, 250, - 255, 171, 10, 154, 16, 210, 45, 61, 52, 144, 13, 132, 49, 135, 84, 54, 218, 26, 134, 22, - 112, 5, 19, 180, 237, 61, 6, 88, 223, 208, 179, 125, 41, 216, 151, 227, 188, 52, 187, 92, - 253, 173, 92, 137, 190, 157, 143, 160, 254, 155, 45, 188, 148, 11, 38, 213, 237, 188, 16, - 35, 3, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 82, 65, 10, 0, 32, 8, 211, 180, 255, 216, 15, 250, + 255, 171, 10, 82, 176, 232, 150, 30, 26, 200, 118, 144, 49, 135, 8, 11, 117, 14, 169, 102, + 229, 162, 140, 78, 219, 206, 137, 174, 44, 111, 104, 217, 190, 24, 236, 75, 113, 94, 146, + 93, 174, 252, 86, 46, 71, 223, 78, 46, 104, 129, 253, 155, 45, 60, 195, 5, 3, 89, 11, 161, + 73, 39, 3, 0, 0, ]; assert_eq!(bytes, expected_serialization) diff --git a/acvm-repo/acvm/src/pwg/blackbox/embedded_curve_ops.rs b/acvm-repo/acvm/src/pwg/blackbox/embedded_curve_ops.rs index ee35385fa81..0b52ae295a2 100644 --- a/acvm-repo/acvm/src/pwg/blackbox/embedded_curve_ops.rs +++ b/acvm-repo/acvm/src/pwg/blackbox/embedded_curve_ops.rs @@ -11,7 +11,7 @@ pub(super) fn multi_scalar_mul( initial_witness: &mut WitnessMap, points: &[FunctionInput], scalars: &[FunctionInput], - outputs: (Witness, Witness), + outputs: (Witness, Witness, Witness), ) -> Result<(), OpcodeResolutionError> { let points: Result, _> = points.iter().map(|input| witness_to_value(initial_witness, input.witness)).collect(); @@ -19,35 +19,44 @@ pub(super) fn multi_scalar_mul( let scalars: Result, _> = scalars.iter().map(|input| witness_to_value(initial_witness, input.witness)).collect(); - let scalars: Vec<_> = scalars?.into_iter().cloned().collect(); - + let mut scalars_lo = Vec::new(); + let mut scalars_hi = Vec::new(); + for (i, scalar) in scalars?.into_iter().enumerate() { + if i % 2 == 0 { + scalars_lo.push(*scalar); + } else { + scalars_hi.push(*scalar); + } + } // Call the backend's multi-scalar multiplication function - let (res_x, res_y) = backend.multi_scalar_mul(&points, &scalars)?; + let (res_x, res_y, is_infinite) = + backend.multi_scalar_mul(&points, &scalars_lo, &scalars_hi)?; // Insert the resulting point into the witness map insert_value(&outputs.0, res_x, initial_witness)?; insert_value(&outputs.1, res_y, initial_witness)?; - + insert_value(&outputs.2, is_infinite, initial_witness)?; Ok(()) } pub(super) fn embedded_curve_add( backend: &impl BlackBoxFunctionSolver, initial_witness: &mut WitnessMap, - input1_x: FunctionInput, - input1_y: FunctionInput, - input2_x: FunctionInput, - input2_y: FunctionInput, - outputs: (Witness, Witness), + input1: [FunctionInput; 3], + input2: [FunctionInput; 3], + outputs: (Witness, Witness, Witness), ) -> Result<(), OpcodeResolutionError> { - let input1_x = witness_to_value(initial_witness, input1_x.witness)?; - let input1_y = witness_to_value(initial_witness, input1_y.witness)?; - let input2_x = witness_to_value(initial_witness, input2_x.witness)?; - let input2_y = witness_to_value(initial_witness, input2_y.witness)?; - let (res_x, res_y) = backend.ec_add(input1_x, input1_y, input2_x, input2_y)?; + let input1_x = witness_to_value(initial_witness, input1[0].witness)?; + let input1_y = witness_to_value(initial_witness, input1[1].witness)?; + let input1_infinite = witness_to_value(initial_witness, input1[2].witness)?; + let input2_x = witness_to_value(initial_witness, input2[0].witness)?; + let input2_y = witness_to_value(initial_witness, input2[1].witness)?; + let input2_infinite = witness_to_value(initial_witness, input2[2].witness)?; + let (res_x, res_y, res_infinite) = + backend.ec_add(input1_x, input1_y, input1_infinite, input2_x, input2_y, input2_infinite)?; insert_value(&outputs.0, res_x, initial_witness)?; insert_value(&outputs.1, res_y, initial_witness)?; - + insert_value(&outputs.2, res_infinite, initial_witness)?; Ok(()) } diff --git a/acvm-repo/acvm/src/pwg/blackbox/mod.rs b/acvm-repo/acvm/src/pwg/blackbox/mod.rs index a74f44b79dc..99ed09a52e4 100644 --- a/acvm-repo/acvm/src/pwg/blackbox/mod.rs +++ b/acvm-repo/acvm/src/pwg/blackbox/mod.rs @@ -164,16 +164,8 @@ pub(crate) fn solve( BlackBoxFuncCall::MultiScalarMul { points, scalars, outputs } => { multi_scalar_mul(backend, initial_witness, points, scalars, *outputs) } - BlackBoxFuncCall::EmbeddedCurveAdd { input1_x, input1_y, input2_x, input2_y, outputs } => { - embedded_curve_add( - backend, - initial_witness, - *input1_x, - *input1_y, - *input2_x, - *input2_y, - *outputs, - ) + BlackBoxFuncCall::EmbeddedCurveAdd { input1, input2, outputs } => { + embedded_curve_add(backend, initial_witness, **input1, **input2, *outputs) } // Recursive aggregation will be entirely handled by the backend and is not solved by the ACVM BlackBoxFuncCall::RecursiveAggregation { .. } => Ok(()), diff --git a/acvm-repo/acvm/src/pwg/mod.rs b/acvm-repo/acvm/src/pwg/mod.rs index a4219adbfa6..f2649b93991 100644 --- a/acvm-repo/acvm/src/pwg/mod.rs +++ b/acvm-repo/acvm/src/pwg/mod.rs @@ -335,7 +335,7 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { &mut self.bigint_solver, ), Opcode::Directive(directive) => solve_directives(&mut self.witness_map, directive), - Opcode::MemoryInit { block_id, init } => { + Opcode::MemoryInit { block_id, init, .. } => { let solver = self.block_solvers.entry(*block_id).or_default(); solver.init(init, &self.witness_map) } diff --git a/acvm-repo/acvm/tests/solver.rs b/acvm-repo/acvm/tests/solver.rs index df61083eee4..495389d7b3e 100644 --- a/acvm-repo/acvm/tests/solver.rs +++ b/acvm-repo/acvm/tests/solver.rs @@ -4,7 +4,7 @@ use acir::{ brillig::{BinaryFieldOp, HeapArray, MemoryAddress, Opcode as BrilligOpcode, ValueOrArray}, circuit::{ brillig::{BrilligBytecode, BrilligInputs, BrilligOutputs}, - opcodes::{BlockId, MemOp}, + opcodes::{BlockId, BlockType, MemOp}, Opcode, OpcodeLocation, }, native_types::{Expression, Witness, WitnessMap}, @@ -658,7 +658,11 @@ fn memory_operations() { let block_id = BlockId(0); - let init = Opcode::MemoryInit { block_id, init: (1..6).map(Witness).collect() }; + let init = Opcode::MemoryInit { + block_id, + init: (1..6).map(Witness).collect(), + block_type: BlockType::Memory, + }; let read_op = Opcode::MemoryOp { block_id, diff --git a/acvm-repo/acvm_js/build.sh b/acvm-repo/acvm_js/build.sh index 16fb26e55db..ee93413ab85 100755 --- a/acvm-repo/acvm_js/build.sh +++ b/acvm-repo/acvm_js/build.sh @@ -25,7 +25,7 @@ function run_if_available { require_command jq require_command cargo require_command wasm-bindgen -require_command wasm-opt +# require_command wasm-opt self_path=$(dirname "$(readlink -f "$0")") pname=$(cargo read-manifest | jq -r '.name') diff --git a/acvm-repo/acvm_js/test/shared/memory_op.ts b/acvm-repo/acvm_js/test/shared/memory_op.ts index 20ea88c7130..f7443c2258b 100644 --- a/acvm-repo/acvm_js/test/shared/memory_op.ts +++ b/acvm-repo/acvm_js/test/shared/memory_op.ts @@ -1,9 +1,9 @@ // See `memory_op_circuit` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 82, 65, 10, 0, 32, 8, 203, 180, 255, 216, 15, 250, 255, 171, 10, 154, 16, 210, - 45, 61, 52, 144, 13, 132, 49, 135, 84, 54, 218, 26, 134, 22, 112, 5, 19, 180, 237, 61, 6, 88, 223, 208, 179, 125, 41, - 216, 151, 227, 188, 52, 187, 92, 253, 173, 92, 137, 190, 157, 143, 160, 254, 155, 45, 188, 148, 11, 38, 213, 237, 188, - 16, 35, 3, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 82, 65, 10, 0, 32, 8, 211, 180, 255, 216, 15, 250, 255, 171, 10, 82, 176, 232, + 150, 30, 26, 200, 118, 144, 49, 135, 8, 11, 117, 14, 169, 102, 229, 162, 140, 78, 219, 206, 137, 174, 44, 111, 104, + 217, 190, 24, 236, 75, 113, 94, 146, 93, 174, 252, 86, 46, 71, 223, 78, 46, 104, 129, 253, 155, 45, 60, 195, 5, 3, 89, + 11, 161, 73, 39, 3, 0, 0, ]); export const initialWitnessMap = new Map([ diff --git a/acvm-repo/acvm_js/test/shared/multi_scalar_mul.ts b/acvm-repo/acvm_js/test/shared/multi_scalar_mul.ts index 8ee0a067a3a..5401da76974 100644 --- a/acvm-repo/acvm_js/test/shared/multi_scalar_mul.ts +++ b/acvm-repo/acvm_js/test/shared/multi_scalar_mul.ts @@ -1,21 +1,24 @@ // See `multi_scalar_mul_circuit` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 85, 76, 65, 14, 0, 32, 8, 82, 179, 186, 244, 104, 159, 30, 45, 218, 136, 141, 33, - 40, 186, 93, 76, 208, 57, 31, 93, 96, 136, 47, 250, 146, 188, 209, 39, 181, 131, 131, 187, 148, 110, 240, 246, 101, - 38, 63, 180, 243, 97, 3, 125, 173, 118, 131, 153, 0, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 141, 219, 10, 0, 32, 8, 67, 243, 214, 5, 250, 232, 62, 189, 69, 123, 176, 132, + 195, 116, 50, 149, 114, 107, 0, 97, 127, 116, 2, 75, 243, 2, 74, 53, 122, 202, 189, 211, 15, 106, 5, 13, 116, 238, 35, + 221, 81, 230, 61, 249, 37, 253, 250, 179, 79, 109, 218, 22, 67, 227, 173, 0, 0, 0, ]); export const initialWitnessMap = new Map([ [1, '0x0000000000000000000000000000000000000000000000000000000000000001'], [2, '0x0000000000000002cf135e7506a45d632d270d45f1181294833fc48d823f272c'], - [3, '0x0000000000000000000000000000000000000000000000000000000000000001'], - [4, '0x0000000000000000000000000000000000000000000000000000000000000000'], + [3, '0x0000000000000000000000000000000000000000000000000000000000000000'], + [4, '0x0000000000000000000000000000000000000000000000000000000000000001'], + [5, '0x0000000000000000000000000000000000000000000000000000000000000000'], ]); export const expectedWitnessMap = new Map([ [1, '0x0000000000000000000000000000000000000000000000000000000000000001'], [2, '0x0000000000000002cf135e7506a45d632d270d45f1181294833fc48d823f272c'], - [3, '0x0000000000000000000000000000000000000000000000000000000000000001'], - [4, '0x0000000000000000000000000000000000000000000000000000000000000000'], - [5, '0x0000000000000000000000000000000000000000000000000000000000000001'], - [6, '0x0000000000000002cf135e7506a45d632d270d45f1181294833fc48d823f272c'], + [3, '0x0000000000000000000000000000000000000000000000000000000000000000'], + [4, '0x0000000000000000000000000000000000000000000000000000000000000001'], + [5, '0x0000000000000000000000000000000000000000000000000000000000000000'], + [6, '0x0000000000000000000000000000000000000000000000000000000000000001'], + [7, '0x0000000000000002cf135e7506a45d632d270d45f1181294833fc48d823f272c'], + [8, '0x0000000000000000000000000000000000000000000000000000000000000000'], ]); diff --git a/acvm-repo/blackbox_solver/src/curve_specific_solver.rs b/acvm-repo/blackbox_solver/src/curve_specific_solver.rs index 3403b0fe232..73f64d3d9d1 100644 --- a/acvm-repo/blackbox_solver/src/curve_specific_solver.rs +++ b/acvm-repo/blackbox_solver/src/curve_specific_solver.rs @@ -27,15 +27,18 @@ pub trait BlackBoxFunctionSolver { fn multi_scalar_mul( &self, points: &[FieldElement], - scalars: &[FieldElement], - ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError>; + scalars_lo: &[FieldElement], + scalars_hi: &[FieldElement], + ) -> Result<(FieldElement, FieldElement, FieldElement), BlackBoxResolutionError>; fn ec_add( &self, input1_x: &FieldElement, input1_y: &FieldElement, + input1_infinite: &FieldElement, input2_x: &FieldElement, input2_y: &FieldElement, - ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError>; + input2_infinite: &FieldElement, + ) -> Result<(FieldElement, FieldElement, FieldElement), BlackBoxResolutionError>; fn poseidon2_permutation( &self, _inputs: &[FieldElement], @@ -81,17 +84,20 @@ impl BlackBoxFunctionSolver for StubbedBlackBoxSolver { fn multi_scalar_mul( &self, _points: &[FieldElement], - _scalars: &[FieldElement], - ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { + _scalars_lo: &[FieldElement], + _scalars_hi: &[FieldElement], + ) -> Result<(FieldElement, FieldElement, FieldElement), BlackBoxResolutionError> { Err(Self::fail(BlackBoxFunc::MultiScalarMul)) } fn ec_add( &self, _input1_x: &FieldElement, _input1_y: &FieldElement, + _input1_infinite: &FieldElement, _input2_x: &FieldElement, _input2_y: &FieldElement, - ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { + _input2_infinite: &FieldElement, + ) -> Result<(FieldElement, FieldElement, FieldElement), BlackBoxResolutionError> { Err(Self::fail(BlackBoxFunc::EmbeddedCurveAdd)) } fn poseidon2_permutation( diff --git a/acvm-repo/bn254_blackbox_solver/src/embedded_curve_ops.rs b/acvm-repo/bn254_blackbox_solver/src/embedded_curve_ops.rs index 3f6d2ac86c1..901eb9d5a0f 100644 --- a/acvm-repo/bn254_blackbox_solver/src/embedded_curve_ops.rs +++ b/acvm-repo/bn254_blackbox_solver/src/embedded_curve_ops.rs @@ -10,9 +10,11 @@ use crate::BlackBoxResolutionError; /// Performs multi scalar multiplication of points with scalars. pub fn multi_scalar_mul( points: &[FieldElement], - scalars: &[FieldElement], -) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { - if points.len() != scalars.len() { + scalars_lo: &[FieldElement], + scalars_hi: &[FieldElement], +) -> Result<(FieldElement, FieldElement, FieldElement), BlackBoxResolutionError> { + if points.len() != 3 * scalars_lo.len() || scalars_lo.len() != scalars_hi.len() { + dbg!(&points.len(), &scalars_lo.len(), &scalars_hi.len()); return Err(BlackBoxResolutionError::Failed( BlackBoxFunc::MultiScalarMul, "Points and scalars must have the same length".to_string(), @@ -21,21 +23,22 @@ pub fn multi_scalar_mul( let mut output_point = grumpkin::SWAffine::zero(); - for i in (0..points.len()).step_by(2) { - let point = create_point(points[i], points[i + 1]) - .map_err(|e| BlackBoxResolutionError::Failed(BlackBoxFunc::MultiScalarMul, e))?; + for i in (0..points.len()).step_by(3) { + let point = + create_point(points[i], points[i + 1], points[i + 2] == FieldElement::from(1_u128)) + .map_err(|e| BlackBoxResolutionError::Failed(BlackBoxFunc::MultiScalarMul, e))?; - let scalar_low: u128 = scalars[i].try_into_u128().ok_or_else(|| { + let scalar_low: u128 = scalars_lo[i / 3].try_into_u128().ok_or_else(|| { BlackBoxResolutionError::Failed( BlackBoxFunc::MultiScalarMul, - format!("Limb {} is not less than 2^128", scalars[i].to_hex()), + format!("Limb {} is not less than 2^128", scalars_lo[i].to_hex()), ) })?; - let scalar_high: u128 = scalars[i + 1].try_into_u128().ok_or_else(|| { + let scalar_high: u128 = scalars_hi[i / 3].try_into_u128().ok_or_else(|| { BlackBoxResolutionError::Failed( BlackBoxFunc::MultiScalarMul, - format!("Limb {} is not less than 2^128", scalars[i + 1].to_hex()), + format!("Limb {} is not less than 2^128", scalars_hi[i].to_hex()), ) })?; @@ -59,25 +62,33 @@ pub fn multi_scalar_mul( } if let Some((out_x, out_y)) = output_point.xy() { - Ok((FieldElement::from_repr(*out_x), FieldElement::from_repr(*out_y))) + Ok(( + FieldElement::from_repr(*out_x), + FieldElement::from_repr(*out_y), + FieldElement::from(output_point.is_zero() as u128), + )) } else { - Ok((FieldElement::zero(), FieldElement::zero())) + Ok((FieldElement::from(0_u128), FieldElement::from(0_u128), FieldElement::from(1_u128))) } } pub fn embedded_curve_add( - input1_x: FieldElement, - input1_y: FieldElement, - input2_x: FieldElement, - input2_y: FieldElement, -) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { - let point1 = create_point(input1_x, input1_y) + input1: [FieldElement; 3], + input2: [FieldElement; 3], +) -> Result<(FieldElement, FieldElement, FieldElement), BlackBoxResolutionError> { + let point1 = create_point(input1[0], input1[1], input1[2] == FieldElement::one()) .map_err(|e| BlackBoxResolutionError::Failed(BlackBoxFunc::EmbeddedCurveAdd, e))?; - let point2 = create_point(input2_x, input2_y) + let point2 = create_point(input2[0], input2[1], input2[2] == FieldElement::one()) .map_err(|e| BlackBoxResolutionError::Failed(BlackBoxFunc::EmbeddedCurveAdd, e))?; let res = grumpkin::SWAffine::from(point1 + point2); if let Some((res_x, res_y)) = res.xy() { - Ok((FieldElement::from_repr(*res_x), FieldElement::from_repr(*res_y))) + Ok(( + FieldElement::from_repr(*res_x), + FieldElement::from_repr(*res_y), + FieldElement::from(res.is_zero() as u128), + )) + } else if res.is_zero() { + Ok((FieldElement::from(0_u128), FieldElement::from(0_u128), FieldElement::from(1_u128))) } else { Err(BlackBoxResolutionError::Failed( BlackBoxFunc::EmbeddedCurveAdd, @@ -86,7 +97,14 @@ pub fn embedded_curve_add( } } -fn create_point(x: FieldElement, y: FieldElement) -> Result { +fn create_point( + x: FieldElement, + y: FieldElement, + is_infinite: bool, +) -> Result { + if is_infinite { + return Ok(grumpkin::SWAffine::zero()); + } let point = grumpkin::SWAffine::new_unchecked(x.into_repr(), y.into_repr()); if !point.is_on_curve() { return Err(format!("Point ({}, {}) is not on curve", x.to_hex(), y.to_hex())); @@ -103,11 +121,11 @@ mod tests { use super::*; - fn get_generator() -> [FieldElement; 2] { + fn get_generator() -> [FieldElement; 3] { let generator = grumpkin::SWAffine::generator(); let generator_x = FieldElement::from_repr(*generator.x().unwrap()); let generator_y = FieldElement::from_repr(*generator.y().unwrap()); - [generator_x, generator_y] + [generator_x, generator_y, FieldElement::zero()] } #[test] @@ -115,7 +133,7 @@ mod tests { // We check that multiplying 1 by generator results in the generator let generator = get_generator(); - let res = multi_scalar_mul(&generator, &[FieldElement::one(), FieldElement::zero()])?; + let res = multi_scalar_mul(&generator, &[FieldElement::one()], &[FieldElement::zero()])?; assert_eq!(generator[0], res.0); assert_eq!(generator[1], res.1); @@ -125,9 +143,10 @@ mod tests { #[test] fn low_high_smoke_test() -> Result<(), BlackBoxResolutionError> { let points = get_generator(); - let scalars = [FieldElement::one(), FieldElement::from(2u128)]; + let scalars_lo = [FieldElement::one()]; + let scalars_hi = [FieldElement::from(2u128)]; - let res = multi_scalar_mul(&points, &scalars)?; + let res = multi_scalar_mul(&points, &scalars_lo, &scalars_hi)?; let x = "0702ab9c7038eeecc179b4f209991bcb68c7cb05bf4c532d804ccac36199c9a9"; let y = "23f10e9e43a3ae8d75d24154e796aae12ae7af546716e8f81a2564f1b5814130"; @@ -148,10 +167,10 @@ mod tests { "Limb 0000000000000000000000000000000100000000000000000000000000000000 is not less than 2^128".into(), )); - let res = multi_scalar_mul(&points, &[FieldElement::one(), invalid_limb]); + let res = multi_scalar_mul(&points, &[FieldElement::one()], &[invalid_limb]); assert_eq!(res, expected_error); - let res = multi_scalar_mul(&points, &[invalid_limb, FieldElement::one()]); + let res = multi_scalar_mul(&points, &[invalid_limb], &[FieldElement::one()]); assert_eq!(res, expected_error); } @@ -162,7 +181,7 @@ mod tests { let low = FieldElement::from_be_bytes_reduce(&x[16..32]); let high = FieldElement::from_be_bytes_reduce(&x[0..16]); - let res = multi_scalar_mul(&get_generator(), &[low, high]); + let res = multi_scalar_mul(&get_generator(), &[low], &[high]); assert_eq!( res, @@ -181,8 +200,9 @@ mod tests { let valid_scalar_high = FieldElement::zero(); let res = multi_scalar_mul( - &[invalid_point_x, invalid_point_y], - &[valid_scalar_low, valid_scalar_high], + &[invalid_point_x, invalid_point_y, FieldElement::zero()], + &[valid_scalar_low], + &[valid_scalar_high], ); assert_eq!( @@ -197,9 +217,10 @@ mod tests { #[test] fn throws_on_args_length_mismatch() { let points = get_generator(); - let scalars = [FieldElement::from(2u128)]; + let scalars_lo = [FieldElement::from(2u128)]; + let scalars_hi = []; - let res = multi_scalar_mul(&points, &scalars); + let res = multi_scalar_mul(&points, &scalars_lo, &scalars_hi); assert_eq!( res, @@ -215,7 +236,10 @@ mod tests { let x = FieldElement::from(1u128); let y = FieldElement::from(2u128); - let res = embedded_curve_add(x, y, x, y); + let res = embedded_curve_add( + [x, y, FieldElement::from(0u128)], + [x, y, FieldElement::from(0u128)], + ); assert_eq!( res, @@ -229,10 +253,14 @@ mod tests { #[test] fn output_of_msm_matches_add() -> Result<(), BlackBoxResolutionError> { let points = get_generator(); - let scalars = [FieldElement::from(2u128), FieldElement::zero()]; - - let msm_res = multi_scalar_mul(&points, &scalars)?; - let add_res = embedded_curve_add(points[0], points[1], points[0], points[1])?; + let scalars_lo = [FieldElement::from(2u128)]; + let scalars_hi = [FieldElement::zero()]; + + let msm_res = multi_scalar_mul(&points, &scalars_lo, &scalars_hi)?; + let add_res = embedded_curve_add( + [points[0], points[1], FieldElement::from(0u128)], + [points[0], points[1], FieldElement::from(0u128)], + )?; assert_eq!(msm_res.0, add_res.0); assert_eq!(msm_res.1, add_res.1); diff --git a/acvm-repo/bn254_blackbox_solver/src/lib.rs b/acvm-repo/bn254_blackbox_solver/src/lib.rs index eebc65db141..43b86e083d5 100644 --- a/acvm-repo/bn254_blackbox_solver/src/lib.rs +++ b/acvm-repo/bn254_blackbox_solver/src/lib.rs @@ -82,19 +82,25 @@ impl BlackBoxFunctionSolver for Bn254BlackBoxSolver { fn multi_scalar_mul( &self, points: &[FieldElement], - scalars: &[FieldElement], - ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { - multi_scalar_mul(points, scalars) + scalars_lo: &[FieldElement], + scalars_hi: &[FieldElement], + ) -> Result<(FieldElement, FieldElement, FieldElement), BlackBoxResolutionError> { + multi_scalar_mul(points, scalars_lo, scalars_hi) } fn ec_add( &self, input1_x: &FieldElement, input1_y: &FieldElement, + input1_infinite: &FieldElement, input2_x: &FieldElement, input2_y: &FieldElement, - ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { - embedded_curve_add(*input1_x, *input1_y, *input2_x, *input2_y) + input2_infinite: &FieldElement, + ) -> Result<(FieldElement, FieldElement, FieldElement), BlackBoxResolutionError> { + embedded_curve_add( + [*input1_x, *input1_y, *input1_infinite], + [*input2_x, *input2_y, *input2_infinite], + ) } fn poseidon2_permutation( diff --git a/acvm-repo/brillig/src/black_box.rs b/acvm-repo/brillig/src/black_box.rs index 15abc19ed90..3887092a8c2 100644 --- a/acvm-repo/brillig/src/black_box.rs +++ b/acvm-repo/brillig/src/black_box.rs @@ -83,8 +83,10 @@ pub enum BlackBoxOp { EmbeddedCurveAdd { input1_x: MemoryAddress, input1_y: MemoryAddress, + input1_infinite: MemoryAddress, input2_x: MemoryAddress, input2_y: MemoryAddress, + input2_infinite: MemoryAddress, result: HeapArray, }, BigIntAdd { @@ -126,4 +128,9 @@ pub enum BlackBoxOp { hash_values: HeapVector, output: HeapArray, }, + ToRadix { + input: MemoryAddress, + radix: u32, + output: HeapArray, + }, } diff --git a/acvm-repo/brillig_vm/src/black_box.rs b/acvm-repo/brillig_vm/src/black_box.rs index c999b5bf330..ebaa6976283 100644 --- a/acvm-repo/brillig_vm/src/black_box.rs +++ b/acvm-repo/brillig_vm/src/black_box.rs @@ -5,6 +5,7 @@ use acvm_blackbox_solver::{ aes128_encrypt, blake2s, blake3, ecdsa_secp256k1_verify, ecdsa_secp256r1_verify, keccak256, keccakf1600, sha256, sha256compression, BlackBoxFunctionSolver, BlackBoxResolutionError, }; +use num_bigint::BigUint; use crate::memory::MemoryValue; use crate::Memory; @@ -156,22 +157,63 @@ pub(crate) fn evaluate_black_box( Ok(()) } BlackBoxOp::MultiScalarMul { points, scalars, outputs: result } => { - let points: Vec = - read_heap_vector(memory, points).iter().map(|x| x.try_into().unwrap()).collect(); + let points: Vec = read_heap_vector(memory, points) + .iter() + .enumerate() + .map(|(i, x)| { + if i % 3 == 2 { + let is_infinite: bool = x.try_into().unwrap(); + FieldElement::from(is_infinite as u128) + } else { + x.try_into().unwrap() + } + }) + .collect(); let scalars: Vec = read_heap_vector(memory, scalars).iter().map(|x| x.try_into().unwrap()).collect(); - - let (x, y) = solver.multi_scalar_mul(&points, &scalars)?; - memory.write_slice(memory.read_ref(result.pointer), &[x.into(), y.into()]); + let mut scalars_lo = Vec::with_capacity(scalars.len() / 2); + let mut scalars_hi = Vec::with_capacity(scalars.len() / 2); + for (i, scalar) in scalars.iter().enumerate() { + if i % 2 == 0 { + scalars_lo.push(*scalar); + } else { + scalars_hi.push(*scalar); + } + } + let (x, y, is_infinite) = solver.multi_scalar_mul(&points, &scalars_lo, &scalars_hi)?; + memory.write_slice( + memory.read_ref(result.pointer), + &[x.into(), y.into(), is_infinite.into()], + ); Ok(()) } - BlackBoxOp::EmbeddedCurveAdd { input1_x, input1_y, input2_x, input2_y, result } => { + BlackBoxOp::EmbeddedCurveAdd { + input1_x, + input1_y, + input2_x, + input2_y, + result, + input1_infinite, + input2_infinite, + } => { let input1_x = memory.read(*input1_x).try_into().unwrap(); let input1_y = memory.read(*input1_y).try_into().unwrap(); + let input1_infinite: bool = memory.read(*input1_infinite).try_into().unwrap(); let input2_x = memory.read(*input2_x).try_into().unwrap(); let input2_y = memory.read(*input2_y).try_into().unwrap(); - let (x, y) = solver.ec_add(&input1_x, &input1_y, &input2_x, &input2_y)?; - memory.write_slice(memory.read_ref(result.pointer), &[x.into(), y.into()]); + let input2_infinite: bool = memory.read(*input2_infinite).try_into().unwrap(); + let (x, y, infinite) = solver.ec_add( + &input1_x, + &input1_y, + &input1_infinite.into(), + &input2_x, + &input2_y, + &input2_infinite.into(), + )?; + memory.write_slice( + memory.read_ref(result.pointer), + &[x.into(), y.into(), infinite.into()], + ); Ok(()) } BlackBoxOp::PedersenCommitment { inputs, domain_separator, output } => { @@ -295,6 +337,25 @@ pub(crate) fn evaluate_black_box( memory.write_slice(memory.read_ref(output.pointer), &state); Ok(()) } + BlackBoxOp::ToRadix { input, radix, output } => { + let input: FieldElement = + memory.read(*input).try_into().expect("ToRadix input not a field"); + + let mut input = BigUint::from_bytes_be(&input.to_be_bytes()); + let radix = BigUint::from(*radix); + + let mut limbs: Vec = Vec::with_capacity(output.size); + + for _ in 0..output.size { + let limb = &input % &radix; + limbs.push(FieldElement::from_be_bytes_reduce(&limb.to_bytes_be()).into()); + input /= &radix; + } + + memory.write_slice(memory.read_ref(output.pointer), &limbs); + + Ok(()) + } } } @@ -321,6 +382,7 @@ fn black_box_function_from_op(op: &BlackBoxOp) -> BlackBoxFunc { BlackBoxOp::BigIntToLeBytes { .. } => BlackBoxFunc::BigIntToLeBytes, BlackBoxOp::Poseidon2Permutation { .. } => BlackBoxFunc::Poseidon2Permutation, BlackBoxOp::Sha256Compression { .. } => BlackBoxFunc::Sha256Compression, + BlackBoxOp::ToRadix { .. } => unreachable!("ToRadix is not an ACIR BlackBoxFunc"), } } diff --git a/aztec_macros/src/lib.rs b/aztec_macros/src/lib.rs index 17ae999fb8f..5326920511b 100644 --- a/aztec_macros/src/lib.rs +++ b/aztec_macros/src/lib.rs @@ -1,17 +1,20 @@ mod transforms; mod utils; +use noirc_errors::Location; use transforms::{ compute_note_hash_and_nullifier::inject_compute_note_hash_and_nullifier, contract_interface::{ generate_contract_interface, stub_function, update_fn_signatures_in_contract_interface, }, events::{generate_selector_impl, transform_events}, - functions::{export_fn_abi, transform_function, transform_unconstrained}, + functions::{ + check_for_public_args, export_fn_abi, transform_function, transform_unconstrained, + }, note_interface::{generate_note_interface_impl, inject_note_exports}, storage::{ assign_storage_slots, check_for_storage_definition, check_for_storage_implementation, - generate_storage_implementation, generate_storage_layout, + generate_storage_implementation, generate_storage_layout, inject_context_in_storage, }, }; @@ -64,6 +67,7 @@ fn transform( for submodule in ast.submodules.iter_mut().filter(|submodule| submodule.is_contract) { if transform_module( crate_id, + &file_id, context, &mut submodule.contents, submodule.name.0.contents.as_str(), @@ -84,6 +88,7 @@ fn transform( /// Returns true if an annotated node is found, false otherwise fn transform_module( crate_id: &CrateId, + file_id: &FileId, context: &HirContext, module: &mut SortedModule, module_name: &str, @@ -97,6 +102,7 @@ fn transform_module( let storage_defined = maybe_storage_struct_name.is_some(); if let Some(ref storage_struct_name) = maybe_storage_struct_name { + inject_context_in_storage(module)?; if !check_for_storage_implementation(module, storage_struct_name) { generate_storage_implementation(module, storage_struct_name)?; } @@ -132,6 +138,7 @@ fn transform_module( let mut is_initializer = false; let mut is_internal = false; let mut insert_init_check = has_initializer; + let mut is_static = false; for secondary_attribute in func.def.attributes.secondary.clone() { if is_custom_attribute(&secondary_attribute, "aztec(private)") { @@ -148,6 +155,9 @@ fn transform_module( } else if is_custom_attribute(&secondary_attribute, "aztec(public-vm)") { is_public_vm = true; } + if is_custom_attribute(&secondary_attribute, "aztec(view)") { + is_static = true; + } } // Apply transformations to the function based on collected attributes @@ -159,7 +169,8 @@ fn transform_module( } else { "Public" }; - stubs.push(stub_function(fn_type, func)); + let stub_src = stub_function(fn_type, func, is_static); + stubs.push((stub_src, Location { file: *file_id, span: func.name_ident().span() })); export_fn_abi(&mut module.types, func)?; transform_function( @@ -169,6 +180,7 @@ fn transform_module( is_initializer, insert_init_check, is_internal, + is_static, )?; has_transformed_module = true; } else if storage_defined && func.def.is_unconstrained { @@ -180,7 +192,7 @@ fn transform_module( if has_transformed_module { // We only want to run these checks if the macro processor has found the module to be an Aztec contract. - let private_functions_count = module + let private_functions: Vec<_> = module .functions .iter() .filter(|func| { @@ -190,9 +202,27 @@ fn transform_module( .iter() .any(|attr| is_custom_attribute(attr, "aztec(private)")) }) - .count(); + .collect(); + + let public_functions: Vec<_> = module + .functions + .iter() + .filter(|func| { + func.def + .attributes + .secondary + .iter() + .any(|attr| is_custom_attribute(attr, "aztec(public)")) + }) + .collect(); + + let private_function_count = private_functions.len(); + + check_for_public_args(&private_functions)?; + + check_for_public_args(&public_functions)?; - if private_functions_count > MAX_CONTRACT_PRIVATE_FUNCTIONS { + if private_function_count > MAX_CONTRACT_PRIVATE_FUNCTIONS { return Err(AztecMacroError::ContractHasTooManyPrivateFunctions { span: Span::default(), }); diff --git a/aztec_macros/src/transforms/contract_interface.rs b/aztec_macros/src/transforms/contract_interface.rs index 1afe0a30068..bb63357d251 100644 --- a/aztec_macros/src/transforms/contract_interface.rs +++ b/aztec_macros/src/transforms/contract_interface.rs @@ -1,4 +1,5 @@ -use noirc_frontend::ast::{NoirFunction, UnresolvedTypeData}; +use noirc_errors::Location; +use noirc_frontend::ast::{Ident, NoirFunction, UnresolvedTypeData}; use noirc_frontend::{ graph::CrateId, macros_api::{FileId, HirContext, HirExpression, HirLiteral, HirStatement}, @@ -39,7 +40,7 @@ use crate::utils::{ // } // // The selector placeholder has to be replaced with the actual function signature after type checking in the next macro pass -pub fn stub_function(aztec_visibility: &str, func: &NoirFunction) -> String { +pub fn stub_function(aztec_visibility: &str, func: &NoirFunction, is_static_call: bool) -> String { let fn_name = func.name().to_string(); let fn_parameters = func .parameters() @@ -59,6 +60,7 @@ pub fn stub_function(aztec_visibility: &str, func: &NoirFunction) -> String { let parameters = func.parameters(); let is_void = if matches!(fn_return_type.typ, UnresolvedTypeData::Unit) { "Void" } else { "" }; + let is_static = if is_static_call { "Static" } else { "" }; let return_type_hint = if is_void == "Void" { "".to_string() } else { @@ -75,7 +77,8 @@ pub fn stub_function(aztec_visibility: &str, func: &NoirFunction) -> String { for i in 0..{0}.len() {{ args_acc = args_acc.append(hash_{0}[i].as_slice()); }}\n", - param_name, typ.typ + param_name, + typ.typ.to_string().replace("plain::", "") ) } _ => { @@ -100,18 +103,18 @@ pub fn stub_function(aztec_visibility: &str, func: &NoirFunction) -> String { let fn_body = format!( "{} - dep::aztec::context::{}{}CallInterface {{ + dep::aztec::context::{}{}{}CallInterface {{ target_contract: self.target_contract, selector: {}, args_hash, }}", - args_hash, aztec_visibility, is_void, fn_selector, + args_hash, aztec_visibility, is_static, is_void, fn_selector, ); format!( - "pub fn {}(self, {}) -> dep::aztec::context::{}{}CallInterface{} {{ + "pub fn {}(self, {}) -> dep::aztec::context::{}{}{}CallInterface{} {{ {} }}", - fn_name, fn_parameters, aztec_visibility, is_void, return_type_hint, fn_body + fn_name, fn_parameters, aztec_visibility, is_static, is_void, return_type_hint, fn_body ) } else { let args = format!( @@ -122,19 +125,19 @@ pub fn stub_function(aztec_visibility: &str, func: &NoirFunction) -> String { ); let fn_body = format!( "{} - dep::aztec::context::Avm{}CallInterface {{ + dep::aztec::context::Avm{}{}CallInterface {{ target_contract: self.target_contract, selector: {}, args: args_acc, gas_opts: dep::aztec::context::gas::GasOpts::default(), }}", - args, is_void, fn_selector, + args, is_static, is_void, fn_selector, ); format!( - "pub fn {}(self, {}) -> dep::aztec::context::Avm{}CallInterface{} {{ + "pub fn {}(self, {}) -> dep::aztec::context::Avm{}{}CallInterface{} {{ {} }}", - fn_name, fn_parameters, is_void, return_type_hint, fn_body + fn_name, fn_parameters, is_static, is_void, return_type_hint, fn_body ) } } @@ -145,7 +148,7 @@ pub fn stub_function(aztec_visibility: &str, func: &NoirFunction) -> String { pub fn generate_contract_interface( module: &mut SortedModule, module_name: &str, - stubs: &[String], + stubs: &[(String, Location)], ) -> Result<(), AztecMacroError> { let contract_interface = format!( " @@ -171,7 +174,7 @@ pub fn generate_contract_interface( }} ", module_name, - stubs.join("\n"), + stubs.iter().map(|(src, _)| src.to_owned()).collect::>().join("\n"), ); let (contract_interface_ast, errors) = parse_program(&contract_interface); @@ -181,8 +184,27 @@ pub fn generate_contract_interface( } let mut contract_interface_ast = contract_interface_ast.into_sorted(); + let mut impl_with_locations = contract_interface_ast.impls.pop().unwrap(); + + impl_with_locations.methods = impl_with_locations + .methods + .iter() + .enumerate() + .map(|(i, (method, orig_span))| { + if method.name() == "at" { + (method.clone(), *orig_span) + } else { + let (_, new_location) = stubs[i]; + let mut modified_method = method.clone(); + modified_method.def.name = + Ident::new(modified_method.name().to_string(), new_location.span); + (modified_method, *orig_span) + } + }) + .collect(); + module.types.push(contract_interface_ast.types.pop().unwrap()); - module.impls.push(contract_interface_ast.impls.pop().unwrap()); + module.impls.push(impl_with_locations); module.functions.push(contract_interface_ast.functions.pop().unwrap()); Ok(()) diff --git a/aztec_macros/src/transforms/functions.rs b/aztec_macros/src/transforms/functions.rs index 39d709ef520..00e9c444421 100644 --- a/aztec_macros/src/transforms/functions.rs +++ b/aztec_macros/src/transforms/functions.rs @@ -10,6 +10,7 @@ use noirc_frontend::ast::{ use noirc_frontend::{macros_api::FieldElement, parse_program}; +use crate::utils::ast_utils::member_access; use crate::{ chained_dep, chained_path, utils::{ @@ -33,6 +34,7 @@ pub fn transform_function( is_initializer: bool, insert_init_check: bool, is_internal: bool, + is_static: bool, ) -> Result<(), AztecMacroError> { let context_name = format!("{}Context", ty); let inputs_name = format!("{}ContextInputs", ty); @@ -40,6 +42,12 @@ pub fn transform_function( let is_avm = ty == "Avm"; let is_private = ty == "Private"; + // Force a static context if the function is static + if is_static { + let is_static_check = create_static_check(func.name(), is_avm); + func.def.body.statements.insert(0, is_static_check); + } + // Add check that msg sender equals this address and flag function as internal if is_internal { let is_internal_check = create_internal_check(func.name()); @@ -59,7 +67,7 @@ pub fn transform_function( // Add access to the storage struct if let Some(storage_struct_name) = storage_struct_name { - let storage_def = abstract_storage(storage_struct_name, &ty.to_lowercase(), false); + let storage_def = abstract_storage(storage_struct_name, false); func.def.body.statements.insert(0, storage_def); } @@ -213,10 +221,7 @@ pub fn export_fn_abi( /// /// This will allow developers to access their contract' storage struct in unconstrained functions pub fn transform_unconstrained(func: &mut NoirFunction, storage_struct_name: String) { - func.def - .body - .statements - .insert(0, abstract_storage(storage_struct_name, "Unconstrained", true)); + func.def.body.statements.insert(0, abstract_storage(storage_struct_name, true)); } /// Helper function that returns what the private context would look like in the ast @@ -275,6 +280,31 @@ fn create_mark_as_initialized(ty: &str) -> Statement { ))) } +/// Forces a static context for a function, ensuring that no state modifications are allowed +/// +/// ```noir +/// assert(context.inputs.call_context.is_static_call == true, "Function can only be called statically") +/// ``` +fn create_static_check(fname: &str, is_avm: bool) -> Statement { + let is_static_call_expr = if !is_avm { + ["inputs", "call_context", "is_static_call"] + .iter() + .fold(variable("context"), |acc, member| member_access(acc, member)) + } else { + ["inputs", "is_static_call"] + .iter() + .fold(variable("context"), |acc, member| member_access(acc, member)) + }; + make_statement(StatementKind::Constrain(ConstrainStatement( + make_eq(is_static_call_expr, expression(ExpressionKind::Literal(Literal::Bool(true)))), + Some(expression(ExpressionKind::Literal(Literal::Str(format!( + "Function {} can only be called statically", + fname + ))))), + ConstrainKind::Assert, + ))) +} + /// Creates a check for internal functions ensuring that the caller is self. /// /// ```noir @@ -564,7 +594,7 @@ fn abstract_return_values(func: &NoirFunction) -> Result>, /// ```noir /// #[aztec(private)] /// fn lol() { -/// let storage = Storage::init(Context::private(context)); +/// let storage = Storage::init(context); /// } /// ``` /// @@ -572,33 +602,28 @@ fn abstract_return_values(func: &NoirFunction) -> Result>, /// ```noir /// #[aztec(public)] /// fn lol() { -/// let storage = Storage::init(Context::public(context)); +/// let storage = Storage::init(context); /// } /// ``` /// /// For unconstrained functions: /// ```noir /// unconstrained fn lol() { -/// let storage = Storage::init(Context::none()); +/// let storage = Storage::init(()); /// } -fn abstract_storage(storage_struct_name: String, typ: &str, unconstrained: bool) -> Statement { - let init_context_call = if unconstrained { - call( - variable_path(chained_dep!("aztec", "context", "Context", "none")), // Path - vec![], // args - ) +fn abstract_storage(storage_struct_name: String, unconstrained: bool) -> Statement { + let context_expr = if unconstrained { + // Note that the literal unit type (i.e. '()') is not the same as a tuple with zero elements + expression(ExpressionKind::Literal(Literal::Unit)) } else { - call( - variable_path(chained_dep!("aztec", "context", "Context", typ)), // Path - vec![mutable_reference("context")], // args - ) + mutable_reference("context") }; assignment( "storage", // Assigned to call( variable_path(chained_path!(storage_struct_name.as_str(), "init")), // Path - vec![init_context_call], // args + vec![context_expr], // args ), ) } @@ -792,3 +817,18 @@ fn add_cast_to_hasher(identifier: &Ident, hasher_name: &str) -> Statement { vec![cast_operation], // args ))) } + +/** + * Takes a vector of functions and checks for the presence of arguments with Public visibility + * Returns AztecMAcroError::PublicArgsDisallowed if found + */ +pub fn check_for_public_args(functions: &[&NoirFunction]) -> Result<(), AztecMacroError> { + for func in functions { + for param in &func.def.parameters { + if param.visibility == Visibility::Public { + return Err(AztecMacroError::PublicArgsDisallowed { span: func.span() }); + } + } + } + Ok(()) +} diff --git a/aztec_macros/src/transforms/storage.rs b/aztec_macros/src/transforms/storage.rs index 1e3cc011715..0a210934827 100644 --- a/aztec_macros/src/transforms/storage.rs +++ b/aztec_macros/src/transforms/storage.rs @@ -1,7 +1,7 @@ use noirc_errors::Span; use noirc_frontend::ast::{ BlockExpression, Expression, ExpressionKind, FunctionDefinition, Ident, Literal, NoirFunction, - NoirStruct, PathKind, Pattern, StatementKind, TypeImpl, UnresolvedType, UnresolvedTypeData, + NoirStruct, Pattern, StatementKind, TypeImpl, UnresolvedType, UnresolvedTypeData, }; use noirc_frontend::{ graph::CrateId, @@ -16,7 +16,7 @@ use noirc_frontend::{ }; use crate::{ - chained_dep, chained_path, + chained_path, utils::{ ast_utils::{ call, expression, ident, ident_path, is_custom_attribute, lambda, make_statement, @@ -48,7 +48,58 @@ pub fn check_for_storage_definition( Ok(result.iter().map(|&r#struct| r#struct.name.0.contents.clone()).next()) } -// Check to see if the user has defined a storage struct +// Injects the Context generic in each of the Storage struct fields to avoid boilerplate, +// taking maps into account (including nested maps) +fn inject_context_in_storage_field(field: &mut UnresolvedType) -> Result<(), AztecMacroError> { + match &mut field.typ { + UnresolvedTypeData::Named(path, generics, _) => { + generics.push(make_type(UnresolvedTypeData::Named( + ident_path("Context"), + vec![], + false, + ))); + match path.segments.last().unwrap().0.contents.as_str() { + "Map" => inject_context_in_storage_field(&mut generics[1]), + _ => Ok(()), + } + } + _ => Err(AztecMacroError::CouldNotInjectContextGenericInStorage { + secondary_message: Some(format!("Unsupported type: {:?}", field.typ)), + }), + } +} + +// Injects the Context generic in the storage struct to avoid boilerplate +// Transforms this: +// struct Storage { +// a_var: SomeStoragePrimitive, +// a_map: Map>, +// } +// +// Into this: +// +// struct Storage { +// a_var: SomeStoragePrimitive, +// a_map: Map, Context>, +// } +pub fn inject_context_in_storage(module: &mut SortedModule) -> Result<(), AztecMacroError> { + let storage_struct = module + .types + .iter_mut() + .find(|r#struct| { + r#struct.attributes.iter().any(|attr| is_custom_attribute(attr, "aztec(storage)")) + }) + .unwrap(); + storage_struct.generics.push(ident("Context")); + storage_struct + .fields + .iter_mut() + .map(|(_, field)| inject_context_in_storage_field(field)) + .collect::, _>>()?; + Ok(()) +} + +// Check to see if the user has defined an impl for the storage struct pub fn check_for_storage_implementation( module: &SortedModule, storage_struct_name: &String, @@ -79,22 +130,22 @@ pub fn generate_storage_field_constructor( variable("context"), slot, lambda( + // This lambda will be equivalent to the following + // | context, slot | { T::new(context, slot) } + // Since the `new` function has type bindings for its arguments, we don't specify the types + // of either context nor slot, and avoid that way having to deal with the generic context + // type. vec![ - ( - pattern("context"), - make_type(UnresolvedTypeData::Named( - chained_dep!("aztec", "context", "Context"), - vec![], - true, - )), - ), + (pattern("context"), make_type(UnresolvedTypeData::Unspecified)), ( Pattern::Identifier(ident("slot")), - make_type(UnresolvedTypeData::FieldElement), + make_type(UnresolvedTypeData::Unspecified), ), ], generate_storage_field_constructor( - &(type_ident.clone(), generics.iter().last().unwrap().clone()), + // Map is expected to have three generic parameters: key, value and context (i.e. + // Map. Here `get(1)` fetches the value type. + &(type_ident.clone(), generics.get(1).unwrap().clone()), variable("slot"), )?, ), @@ -113,15 +164,15 @@ pub fn generate_storage_field_constructor( // Generates the Storage implementation block from the Storage struct definition if it does not exist /// From: /// -/// struct Storage { -/// a_map: Map>, -/// a_nested_map: Map>>, -/// a_field: SomeStoragePrimitive, +/// struct Storage { +/// a_map: Map, Context>, +/// a_nested_map: Map, Context>, Context>, +/// a_field: SomeStoragePrimitive, /// } /// /// To: /// -/// impl Storage { +/// impl Storage { /// fn init(context: Context) -> Self { /// Storage { /// a_map: Map::new(context, 0, |context, slot| { @@ -167,17 +218,15 @@ pub fn generate_storage_implementation( ExpressionKind::constructor((chained_path!(storage_struct_name), field_constructors)), ))); + // This is the type over which the impl is generic. + let generic_context_ident = ident("Context"); + let generic_context_type = + make_type(UnresolvedTypeData::Named(ident_path("Context"), vec![], true)); + let init = NoirFunction::normal(FunctionDefinition::normal( &ident("init"), &vec![], - &[( - ident("context"), - make_type(UnresolvedTypeData::Named( - chained_dep!("aztec", "context", "Context"), - vec![], - true, - )), - )], + &[(ident("context"), generic_context_type.clone())], &BlockExpression { statements: vec![storage_constructor_statement] }, &[], &return_type(chained_path!("Self")), @@ -185,11 +234,16 @@ pub fn generate_storage_implementation( let storage_impl = TypeImpl { object_type: UnresolvedType { - typ: UnresolvedTypeData::Named(chained_path!(storage_struct_name), vec![], true), + typ: UnresolvedTypeData::Named( + chained_path!(storage_struct_name), + vec![generic_context_type.clone()], + true, + ), span: Some(Span::default()), }, type_span: Span::default(), - generics: vec![], + generics: vec![generic_context_ident], + methods: vec![(init, Span::default())], }; module.impls.push(storage_impl); @@ -341,7 +395,9 @@ pub fn assign_storage_slots( let mut storage_slot: u64 = 1; for (index, (_, expr_id)) in storage_constructor_expression.fields.iter().enumerate() { - let fields = storage_struct.borrow().get_fields(&[]); + let fields = storage_struct + .borrow() + .get_fields(&storage_constructor_expression.struct_generics); let (field_name, field_type) = fields.get(index).unwrap(); let new_call_expression = match context.def_interner.expression(expr_id) { HirExpression::Call(hir_call_expression) => Ok(hir_call_expression), diff --git a/aztec_macros/src/utils/ast_utils.rs b/aztec_macros/src/utils/ast_utils.rs index ba51090c2be..4706be2df25 100644 --- a/aztec_macros/src/utils/ast_utils.rs +++ b/aztec_macros/src/utils/ast_utils.rs @@ -1,9 +1,9 @@ use noirc_errors::{Span, Spanned}; use noirc_frontend::ast::{ BinaryOpKind, CallExpression, CastExpression, Expression, ExpressionKind, FunctionReturnType, - Ident, IndexExpression, InfixExpression, Lambda, LetStatement, MethodCallExpression, - NoirTraitImpl, Path, Pattern, PrefixExpression, Statement, StatementKind, TraitImplItem, - UnaryOp, UnresolvedType, UnresolvedTypeData, + Ident, IndexExpression, InfixExpression, Lambda, LetStatement, MemberAccessExpression, + MethodCallExpression, NoirTraitImpl, Path, Pattern, PrefixExpression, Statement, StatementKind, + TraitImplItem, UnaryOp, UnresolvedType, UnresolvedTypeData, }; use noirc_frontend::token::SecondaryAttribute; @@ -126,6 +126,13 @@ pub fn make_statement(kind: StatementKind) -> Statement { Statement { span: Span::default(), kind } } +pub fn member_access(lhs: Expression, member: &str) -> Expression { + expression(ExpressionKind::MemberAccess(Box::new(MemberAccessExpression { + lhs, + rhs: ident(member), + }))) +} + #[macro_export] macro_rules! chained_path { ( $base:expr ) => { diff --git a/aztec_macros/src/utils/errors.rs b/aztec_macros/src/utils/errors.rs index db86012a007..51aea3d052f 100644 --- a/aztec_macros/src/utils/errors.rs +++ b/aztec_macros/src/utils/errors.rs @@ -16,10 +16,12 @@ pub enum AztecMacroError { CouldNotImplementNoteInterface { span: Option, secondary_message: Option }, MultipleStorageDefinitions { span: Option }, CouldNotExportStorageLayout { span: Option, secondary_message: Option }, + CouldNotInjectContextGenericInStorage { secondary_message: Option }, CouldNotExportFunctionAbi { span: Option, secondary_message: Option }, CouldNotGenerateContractInterface { secondary_message: Option }, EventError { span: Span, message: String }, UnsupportedAttributes { span: Span, secondary_message: Option }, + PublicArgsDisallowed { span: Span }, } impl From for MacroError { @@ -75,6 +77,11 @@ impl From for MacroError { secondary_message, span, }, + AztecMacroError::CouldNotInjectContextGenericInStorage { secondary_message } => MacroError { + primary_message: "Could not inject context generic in storage".to_string(), + secondary_message, + span: None + }, AztecMacroError::CouldNotExportFunctionAbi { secondary_message, span } => MacroError { primary_message: "Could not generate and export function abi".to_string(), secondary_message, @@ -95,6 +102,11 @@ impl From for MacroError { secondary_message, span: Some(span), }, + AztecMacroError::PublicArgsDisallowed { span } => MacroError { + primary_message: "Aztec functions can't have public arguments".to_string(), + secondary_message: None, + span: Some(span), + }, } } } diff --git a/compiler/integration-tests/scripts/codegen-verifiers.sh b/compiler/integration-tests/scripts/codegen-verifiers.sh index e377a3ee3f8..abc26c4c465 100644 --- a/compiler/integration-tests/scripts/codegen-verifiers.sh +++ b/compiler/integration-tests/scripts/codegen-verifiers.sh @@ -1,26 +1,34 @@ #!/usr/bin/env bash +NARGO_BACKEND_PATH=${NARGO_BACKEND_PATH:-bb} + self_path=$(dirname "$(readlink -f "$0")") repo_root=$self_path/../../.. -# Run codegen-verifier for 1_mul +# We want to move all the contracts to the root of compiler/integration-tests +contracts_dir=$self_path/../contracts +rm -rf $contracts_dir +mkdir $contracts_dir + +KEYS=$(mktemp -d) + +# Codegen verifier contract for 1_mul mul_dir=$repo_root/test_programs/execution_success/1_mul -nargo --program-dir $mul_dir codegen-verifier +nargo --program-dir $mul_dir compile +$NARGO_BACKEND_PATH write_vk -b $mul_dir/target/1_mul.json -o $KEYS/1_mul +$NARGO_BACKEND_PATH contract -k $KEYS/1_mul -o $contracts_dir/1_mul.sol -# Run codegen-verifier for assert_statement +# Codegen verifier contract for assert_statement assert_statement_dir=$repo_root/test_programs/execution_success/assert_statement -nargo --program-dir $assert_statement_dir codegen-verifier +nargo --program-dir $assert_statement_dir compile +$NARGO_BACKEND_PATH write_vk -b $assert_statement_dir/target/assert_statement.json -o $KEYS/assert_statement +$NARGO_BACKEND_PATH contract -k $KEYS/assert_statement -o $contracts_dir/assert_statement.sol -# Run codegen-verifier for recursion +# Codegen verifier contract for recursion recursion_dir=$repo_root/compiler/integration-tests/circuits/recursion -nargo --program-dir $recursion_dir codegen-verifier - -# Copy compiled contracts from the root of compiler/integration-tests -contracts_dir=$self_path/../contracts -rm -rf $contracts_dir -mkdir $contracts_dir +nargo --program-dir $recursion_dir compile +$NARGO_BACKEND_PATH write_vk -b $recursion_dir/target/recursion.json -o $KEYS/recursion +$NARGO_BACKEND_PATH contract -k $KEYS/recursion ./ -o $contracts_dir/recursion.sol -cp $mul_dir/contract/1_mul/plonk_vk.sol $contracts_dir/1_mul.sol -cp $assert_statement_dir/contract/assert_statement/plonk_vk.sol $contracts_dir/assert_statement.sol -cp $recursion_dir/contract/recursion/plonk_vk.sol $contracts_dir/recursion.sol +rm -rf $KEYS \ No newline at end of file diff --git a/compiler/noirc_driver/src/lib.rs b/compiler/noirc_driver/src/lib.rs index 801c0b685a9..d7368f299b8 100644 --- a/compiler/noirc_driver/src/lib.rs +++ b/compiler/noirc_driver/src/lib.rs @@ -84,10 +84,6 @@ pub struct CompileOptions { #[arg(long, conflicts_with = "deny_warnings")] pub silence_warnings: bool, - /// Output ACIR gzipped bytecode instead of the JSON artefact - #[arg(long, hide = true)] - pub only_acir: bool, - /// Disables the builtin Aztec macros being used in the compiler #[arg(long, hide = true)] pub disable_macros: bool, diff --git a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs index d982d864d06..f56c5daf315 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs @@ -207,15 +207,17 @@ pub(crate) fn convert_black_box_call( } BlackBoxFunc::EmbeddedCurveAdd => { if let ( - [BrilligVariable::SingleAddr(input1_x), BrilligVariable::SingleAddr(input1_y), BrilligVariable::SingleAddr(input2_x), BrilligVariable::SingleAddr(input2_y)], + [BrilligVariable::SingleAddr(input1_x), BrilligVariable::SingleAddr(input1_y), BrilligVariable::SingleAddr(input1_infinite), BrilligVariable::SingleAddr(input2_x), BrilligVariable::SingleAddr(input2_y), BrilligVariable::SingleAddr(input2_infinite)], [BrilligVariable::BrilligArray(result_array)], ) = (function_arguments, function_results) { brillig_context.black_box_op_instruction(BlackBoxOp::EmbeddedCurveAdd { input1_x: input1_x.address, input1_y: input1_y.address, + input1_infinite: input1_infinite.address, input2_x: input2_x.address, input2_y: input2_y.address, + input2_infinite: input2_infinite.address, result: result_array.to_heap_array(), }); } else { @@ -233,9 +235,7 @@ pub(crate) fn convert_black_box_call( BlackBoxFunc::RANGE => unreachable!( "ICE: `BlackBoxFunc::RANGE` calls should be transformed into a `Instruction::Cast`" ), - BlackBoxFunc::RecursiveAggregation => unimplemented!( - "ICE: `BlackBoxFunc::RecursiveAggregation` is not implemented by the Brillig VM" - ), + BlackBoxFunc::RecursiveAggregation => {} BlackBoxFunc::BigIntAdd => { if let ( [BrilligVariable::SingleAddr(lhs), BrilligVariable::SingleAddr(lhs_modulus), BrilligVariable::SingleAddr(rhs), BrilligVariable::SingleAddr(rhs_modulus)], diff --git a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs index f660c8e0b7a..6a4f9f5cc0e 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs @@ -488,8 +488,22 @@ impl<'block> BrilligBlock<'block> { } Value::Intrinsic(Intrinsic::ToRadix(endianness)) => { let source = self.convert_ssa_single_addr_value(arguments[0], dfg); - let radix = self.convert_ssa_single_addr_value(arguments[1], dfg); - let limb_count = self.convert_ssa_single_addr_value(arguments[2], dfg); + + let radix: u32 = dfg + .get_numeric_constant(arguments[1]) + .expect("Radix should be known") + .try_to_u64() + .expect("Radix should fit in u64") + .try_into() + .expect("Radix should be u32"); + + let limb_count: usize = dfg + .get_numeric_constant(arguments[2]) + .expect("Limb count should be known") + .try_to_u64() + .expect("Limb count should fit in u64") + .try_into() + .expect("Limb count should fit in usize"); let results = dfg.instruction_results(instruction_id); @@ -511,7 +525,8 @@ impl<'block> BrilligBlock<'block> { .extract_vector(); // Update the user-facing slice length - self.brillig_context.cast_instruction(target_len, limb_count); + self.brillig_context + .usize_const_instruction(target_len.address, limb_count.into()); self.brillig_context.codegen_to_radix( source, @@ -524,7 +539,13 @@ impl<'block> BrilligBlock<'block> { } Value::Intrinsic(Intrinsic::ToBits(endianness)) => { let source = self.convert_ssa_single_addr_value(arguments[0], dfg); - let limb_count = self.convert_ssa_single_addr_value(arguments[1], dfg); + let limb_count: usize = dfg + .get_numeric_constant(arguments[1]) + .expect("Limb count should be known") + .try_to_u64() + .expect("Limb count should fit in u64") + .try_into() + .expect("Limb count should fit in usize"); let results = dfg.instruction_results(instruction_id); @@ -549,21 +570,18 @@ impl<'block> BrilligBlock<'block> { BrilligVariable::SingleAddr(..) => unreachable!("ICE: ToBits on non-array"), }; - let radix = self.brillig_context.make_constant_instruction(2_usize.into(), 32); - // Update the user-facing slice length - self.brillig_context.cast_instruction(target_len, limb_count); + self.brillig_context + .usize_const_instruction(target_len.address, limb_count.into()); self.brillig_context.codegen_to_radix( source, target_vector, - radix, + 2, limb_count, matches!(endianness, Endian::Big), 1, ); - - self.brillig_context.deallocate_single_addr(radix); } _ => { unreachable!("unsupported function call type {:?}", dfg[*func]) diff --git a/compiler/noirc_evaluator/src/brillig/brillig_ir.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir.rs index fadcdb22c15..2bd57dc9486 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir.rs @@ -170,18 +170,21 @@ pub(crate) mod tests { fn multi_scalar_mul( &self, _points: &[FieldElement], - _scalars: &[FieldElement], - ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { - Ok((4_u128.into(), 5_u128.into())) + _scalars_lo: &[FieldElement], + _scalars_hi: &[FieldElement], + ) -> Result<(FieldElement, FieldElement, FieldElement), BlackBoxResolutionError> { + Ok((4_u128.into(), 5_u128.into(), 0_u128.into())) } fn ec_add( &self, _input1_x: &FieldElement, _input1_y: &FieldElement, + _input1_infinite: &FieldElement, _input2_x: &FieldElement, _input2_y: &FieldElement, - ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { + _input2_infinite: &FieldElement, + ) -> Result<(FieldElement, FieldElement, FieldElement), BlackBoxResolutionError> { panic!("Path not trodden by this test") } diff --git a/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs index ab756217bcd..58166554e1d 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs @@ -1,6 +1,7 @@ -use acvm::FieldElement; - -use crate::brillig::brillig_ir::BrilligBinaryOp; +use acvm::{ + acir::brillig::{BlackBoxOp, HeapArray}, + FieldElement, +}; use super::{ brillig_variable::{BrilligVector, SingleAddrVariable}, @@ -36,57 +37,46 @@ impl BrilligContext { &mut self, source_field: SingleAddrVariable, target_vector: BrilligVector, - radix: SingleAddrVariable, - limb_count: SingleAddrVariable, + radix: u32, + limb_count: usize, big_endian: bool, limb_bit_size: u32, ) { assert!(source_field.bit_size == FieldElement::max_num_bits()); - assert!(radix.bit_size == 32); - assert!(limb_count.bit_size == 32); - let radix_as_field = - SingleAddrVariable::new(self.allocate_register(), FieldElement::max_num_bits()); - self.cast_instruction(radix_as_field, radix); - self.cast_instruction(SingleAddrVariable::new_usize(target_vector.size), limb_count); + self.usize_const_instruction(target_vector.size, limb_count.into()); self.usize_const_instruction(target_vector.rc, 1_usize.into()); self.codegen_allocate_array(target_vector.pointer, target_vector.size); - let shifted_field = - SingleAddrVariable::new(self.allocate_register(), FieldElement::max_num_bits()); - self.mov_instruction(shifted_field.address, source_field.address); + self.black_box_op_instruction(BlackBoxOp::ToRadix { + input: source_field.address, + radix, + output: HeapArray { pointer: target_vector.pointer, size: limb_count }, + }); let limb_field = SingleAddrVariable::new(self.allocate_register(), FieldElement::max_num_bits()); let limb_casted = SingleAddrVariable::new(self.allocate_register(), limb_bit_size); - self.codegen_loop(target_vector.size, |ctx, iterator_register| { - // Compute the modulus - ctx.binary_instruction( - shifted_field, - radix_as_field, - limb_field, - BrilligBinaryOp::Modulo, - ); - // Cast it - ctx.cast_instruction(limb_casted, limb_field); - // Write it - ctx.codegen_array_set(target_vector.pointer, iterator_register, limb_casted.address); - // Integer div the field - ctx.binary_instruction( - shifted_field, - radix_as_field, - shifted_field, - BrilligBinaryOp::UnsignedDiv, - ); - }); + if limb_bit_size != FieldElement::max_num_bits() { + self.codegen_loop(target_vector.size, |ctx, iterator_register| { + // Read the limb + ctx.codegen_array_get(target_vector.pointer, iterator_register, limb_field.address); + // Cast it + ctx.cast_instruction(limb_casted, limb_field); + // Write it + ctx.codegen_array_set( + target_vector.pointer, + iterator_register, + limb_casted.address, + ); + }); + } // Deallocate our temporary registers - self.deallocate_single_addr(shifted_field); self.deallocate_single_addr(limb_field); self.deallocate_single_addr(limb_casted); - self.deallocate_single_addr(radix_as_field); if big_endian { self.codegen_reverse_vector_in_place(target_vector); diff --git a/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs index 667ccf6ddbe..def91f82bfd 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs @@ -334,7 +334,9 @@ impl DebugShow { outputs ); } - BlackBoxOp::EmbeddedCurveAdd { input1_x, input1_y, input2_x, input2_y, result } => { + BlackBoxOp::EmbeddedCurveAdd { + input1_x, input1_y, input2_x, input2_y, result, .. + } => { debug_println!( self.enable_debug_trace, " EMBEDDED_CURVE_ADD ({} {}) ({} {}) -> {}", @@ -451,6 +453,15 @@ impl DebugShow { output ); } + BlackBoxOp::ToRadix { input, radix, output } => { + debug_println!( + self.enable_debug_trace, + " TO_RADIX {} {} -> {}", + input, + radix, + output + ); + } } } diff --git a/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs index 732bd3cbc59..38e9bdfa8b8 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs @@ -7,7 +7,7 @@ use super::{ }; use acvm::{acir::brillig::MemoryAddress, FieldElement}; -pub(crate) const MAX_STACK_SIZE: usize = 1024; +pub(crate) const MAX_STACK_SIZE: usize = 2048; impl BrilligContext { /// Creates an entry point artifact that will jump to the function label provided. diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index 5f180edd05c..90cdbb650c2 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -8,7 +8,7 @@ use crate::ssa::ir::dfg::CallStack; use crate::ssa::ir::types::Type as SsaType; use crate::ssa::ir::{instruction::Endian, types::NumericType}; use acvm::acir::circuit::brillig::{BrilligInputs, BrilligOutputs}; -use acvm::acir::circuit::opcodes::{BlockId, MemOp}; +use acvm::acir::circuit::opcodes::{BlockId, BlockType, MemOp}; use acvm::acir::circuit::{AssertionPayload, ExpressionOrMemory, Opcode}; use acvm::blackbox_solver; use acvm::brillig_vm::{MemoryValue, VMStatus, VM}; @@ -1776,6 +1776,7 @@ impl AcirContext { block_id: BlockId, len: usize, optional_value: Option, + databus: BlockType, ) -> Result<(), InternalError> { let initialized_values = match optional_value { None => { @@ -1790,7 +1791,11 @@ impl AcirContext { } }; - self.acir_ir.push_opcode(Opcode::MemoryInit { block_id, init: initialized_values }); + self.acir_ir.push_opcode(Opcode::MemoryInit { + block_id, + init: initialized_values, + block_type: databus, + }); Ok(()) } diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index c1249ae41c8..d23f4abe5f5 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -293,14 +293,13 @@ impl GeneratedAcir { BlackBoxFunc::MultiScalarMul => BlackBoxFuncCall::MultiScalarMul { points: inputs[0].clone(), scalars: inputs[1].clone(), - outputs: (outputs[0], outputs[1]), + outputs: (outputs[0], outputs[1], outputs[2]), }, + BlackBoxFunc::EmbeddedCurveAdd => BlackBoxFuncCall::EmbeddedCurveAdd { - input1_x: inputs[0][0], - input1_y: inputs[1][0], - input2_x: inputs[2][0], - input2_y: inputs[3][0], - outputs: (outputs[0], outputs[1]), + input1: Box::new([inputs[0][0], inputs[1][0], inputs[2][0]]), + input2: Box::new([inputs[3][0], inputs[4][0], inputs[5][0]]), + outputs: (outputs[0], outputs[1], outputs[2]), }, BlackBoxFunc::Keccak256 => { let var_message_size = match inputs.to_vec().pop() { @@ -684,8 +683,8 @@ fn black_box_func_expected_input_size(name: BlackBoxFunc) -> Option { // Recursive aggregation has a variable number of inputs BlackBoxFunc::RecursiveAggregation => None, - // Addition over the embedded curve: input are coordinates (x1,y1) and (x2,y2) of the Grumpkin points - BlackBoxFunc::EmbeddedCurveAdd => Some(4), + // Addition over the embedded curve: input are coordinates (x1,y1,infinite1) and (x2,y2,infinite2) of the Grumpkin points + BlackBoxFunc::EmbeddedCurveAdd => Some(6), // Big integer operations take in 0 inputs. They use constants for their inputs. BlackBoxFunc::BigIntAdd @@ -735,7 +734,7 @@ fn black_box_expected_output_size(name: BlackBoxFunc) -> Option { // Output of operations over the embedded curve // will be 2 field elements representing the point. - BlackBoxFunc::MultiScalarMul | BlackBoxFunc::EmbeddedCurveAdd => Some(2), + BlackBoxFunc::MultiScalarMul | BlackBoxFunc::EmbeddedCurveAdd => Some(3), // Big integer operations return a big integer BlackBoxFunc::BigIntAdd diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index 2430a00fd4c..fefe5f6f8e6 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -29,6 +29,7 @@ use crate::brillig::brillig_ir::BrilligContext; use crate::brillig::{brillig_gen::brillig_fn::FunctionContext as BrilligFunctionContext, Brillig}; use crate::errors::{InternalError, InternalWarning, RuntimeError, SsaReport}; pub(crate) use acir_ir::generated_acir::GeneratedAcir; +use acvm::acir::circuit::opcodes::BlockType; use noirc_frontend::monomorphization::ast::InlineType; use acvm::acir::circuit::brillig::BrilligBytecode; @@ -1683,7 +1684,18 @@ impl<'a> Context<'a> { len: usize, value: Option, ) -> Result<(), InternalError> { - self.acir_context.initialize_array(array, len, value)?; + let databus = if self.data_bus.call_data.is_some() + && self.block_id(&self.data_bus.call_data.unwrap()) == array + { + BlockType::CallData + } else if self.data_bus.return_data.is_some() + && self.block_id(&self.data_bus.return_data.unwrap()) == array + { + BlockType::ReturnData + } else { + BlockType::Memory + }; + self.acir_context.initialize_array(array, len, value, databus)?; self.initialized_arrays.insert(array); Ok(()) } diff --git a/cspell.json b/cspell.json index eaf3fcd1b00..b4f214c2f27 100644 --- a/cspell.json +++ b/cspell.json @@ -63,6 +63,12 @@ "defunctionalization", "defunctionalize", "defunctionalized", + "demonomorphization", + "demonomorphize", + "demonomorphized", + "demonomorphizer", + "demonomorphizes", + "demonomorphizing", "deque", "desugared", "devcontainer", diff --git a/docs/docs/getting_started/barretenberg/_category_.json b/docs/docs/getting_started/barretenberg/_category_.json new file mode 100644 index 00000000000..27a8e89228d --- /dev/null +++ b/docs/docs/getting_started/barretenberg/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 1, + "label": "Install Barretenberg", + "collapsible": true, + "collapsed": true +} diff --git a/docs/docs/getting_started/barretenberg/index.md b/docs/docs/getting_started/barretenberg/index.md new file mode 100644 index 00000000000..048ba39f046 --- /dev/null +++ b/docs/docs/getting_started/barretenberg/index.md @@ -0,0 +1,53 @@ +--- +title: Barretenberg Installation +description: bb is a command line tool for interacting with Aztec's proving backend Barretenberg. This page is a quick guide on how to install `bb` +keywords: [ + Barretenberg + bb + Installation + Terminal Commands + Version Check + Nightlies + Specific Versions + Branches +] +pagination_next: getting_started/hello_noir/index +--- + +`bb` is the CLI tool for generating and verifying proofs for Noir programs using the Barretenberg proving library. It also allows generating solidity verifier contracts for which you can verify contracts which were constructed using `bb`. + +## Installing `bb` + +Open a terminal on your machine, and write: + +##### macOS (Apple Silicon) + +```bash +mkdir -p $HOME/.barretenberg && \ +curl -o ./barretenberg-aarch64-apple-darwin.tar.gz -L https://github.com/AztecProtocol/aztec-packages/releases/download/aztec-packages-v0.38.0/barretenberg-aarch64-apple-darwin.tar.gz && \ +tar -xvf ./barretenberg-aarch64-apple-darwin.tar.gz -C $HOME/.barretenberg/ && \ +echo 'export PATH=$PATH:$HOME/.barretenberg/' >> ~/.zshrc && \ +source ~/.zshrc +``` + +##### macOS (Intel) + +```bash +mkdir -p $HOME/.barretenberg && \ +curl -o ./barretenberg-x86_64-apple-darwin.tar.gz -L https://github.com/AztecProtocol/aztec-packages/releases/download/aztec-packages-v0.38.0/barretenberg-x86_64-apple-darwin.tar.gz && \ +tar -xvf ./barretenberg-x86_64-apple-darwin.tar.gz -C $HOME/.barretenberg/ && \ +echo 'export PATH=$PATH:$HOME/.barretenberg/' >> ~/.zshrc && \ +source ~/.zshrc +``` + +##### Linux (Bash) + +```bash +mkdir -p $HOME/.barretenberg && \ +curl -o ./barretenberg-x86_64-linux-gnu.tar.gz -L https://github.com/AztecProtocol/aztec-packages/releases/download/aztec-packages-v0.38.0/barretenberg-x86_64-linux-gnu.tar.gz && \ +tar -xvf ./barretenberg-x86_64-linux-gnu.tar.gz -C $HOME/.barretenberg/ && \ +echo -e 'export PATH=$PATH:$HOME/.barretenberg/' >> ~/.bashrc && \ +source ~/.bashrc +``` + +Now we're ready to start working on [our first Noir program!](../hello_noir/index.md) diff --git a/docs/docs/getting_started/hello_noir/_category_.json b/docs/docs/getting_started/hello_noir/_category_.json index 23b560f610b..976a2325de0 100644 --- a/docs/docs/getting_started/hello_noir/_category_.json +++ b/docs/docs/getting_started/hello_noir/_category_.json @@ -1,5 +1,5 @@ { - "position": 1, + "position": 2, "collapsible": true, "collapsed": true } diff --git a/docs/docs/getting_started/hello_noir/index.md b/docs/docs/getting_started/hello_noir/index.md index 743c4d8d634..1ade3f09ae3 100644 --- a/docs/docs/getting_started/hello_noir/index.md +++ b/docs/docs/getting_started/hello_noir/index.md @@ -90,13 +90,11 @@ cd hello_world nargo check ``` -Two additional files would be generated in your project directory: +A _Prover.toml_ file will be generated in your project directory, to allow specifying input values to the program. -_Prover.toml_ houses input values, and _Verifier.toml_ houses public values. +## Execute Our Noir Program -## Prove Our Noir Program - -Now that the project is set up, we can create a proof of correct execution of our Noir program. +Now that the project is set up, we can execute our Noir program. Fill in input values for execution in the _Prover.toml_ file. For example: @@ -105,37 +103,42 @@ x = "1" y = "2" ``` -Prove the valid execution of your Noir program: +Execute your Noir program: ```sh -nargo prove +nargo execute witness-name ``` -A new folder _proofs_ would then be generated in your project directory, containing the proof file -`.proof`, where the project name is defined in Nargo.toml. +The witness corresponding to this execution will then be written to the file `./target/witness-name.gz`. -The _Verifier.toml_ file would also be updated with the public values computed from program -execution (in this case the value of `y`): +## Prove Our Noir Program -```toml -y = "0x0000000000000000000000000000000000000000000000000000000000000002" +:::info + +Nargo no longer handles communicating with backends in order to generate proofs. In order to prove/verify your Noir programs, you'll need an installation of [bb](../barretenberg/index.md). + +::: + +Prove the valid execution of your Noir program using `bb`: + +```sh +bb prove -b ./target/hello_world.json -w ./target/witness-name.gz -o ./proof ``` -> **Note:** Values in _Verifier.toml_ are computed as 32-byte hex values. +A new file called `proof` will be generated in your project directory, containing the generated proof for your program. ## Verify Our Noir Program -Once a proof is generated, we can verify correct execution of our Noir program by verifying the -proof file. +Once a proof is generated, we can verify correct execution of our Noir program by verifying the proof file. Verify your proof by running: ```sh -nargo verify +bb write_vk -b ./target/hello_world.json -o ./target/vk +bb verify -k ./target/vk -p ./proof ``` -The verification will complete in silence if it is successful. If it fails, it will log the -corresponding error instead. +The verification will complete in silence if it is successful. If it fails, it will log the corresponding error instead. Congratulations, you have now created and verified a proof for your very first Noir program! diff --git a/docs/docs/getting_started/hello_noir/project_breakdown.md b/docs/docs/getting_started/hello_noir/project_breakdown.md index 6160a102c6c..29688df148f 100644 --- a/docs/docs/getting_started/hello_noir/project_breakdown.md +++ b/docs/docs/getting_started/hello_noir/project_breakdown.md @@ -1,10 +1,10 @@ --- title: Project Breakdown description: - Learn about the anatomy of a Nargo project, including the purpose of the Prover and Verifier TOML - files, and how to prove and verify your program. + Learn about the anatomy of a Nargo project, including the purpose of the Prover TOML + file, and how to prove and verify your program. keywords: - [Nargo, Nargo project, Prover.toml, Verifier.toml, proof verification, private asset transfer] + [Nargo, Nargo project, Prover.toml, proof verification, private asset transfer] sidebar_position: 2 --- @@ -18,7 +18,6 @@ commands, you would get a minimal Nargo project of the following structure: - src - Prover.toml - - Verifier.toml - Nargo.toml The source directory _src_ holds the source code for your Noir program. By default only a _main.nr_ @@ -28,10 +27,6 @@ file will be generated within it. _Prover.toml_ is used for specifying the input values for executing and proving the program. You can specify `toml` files with different names by using the `--prover-name` or `-p` flags, see the [Prover](#provertoml) section below. Optionally you may specify expected output values for prove-time checking as well. -### Verifier.toml - -_Verifier.toml_ contains public in/output values computed when executing the Noir program. - ### Nargo.toml _Nargo.toml_ contains the environmental options of your project. It contains a "package" section and a "dependencies" section. @@ -92,20 +87,15 @@ fn main(x : Field, y : Field) { } ``` -The parameters `x` and `y` can be seen as the API for the program and must be supplied by the -prover. Since neither `x` nor `y` is marked as public, the verifier does not supply any inputs, when -verifying the proof. +The parameters `x` and `y` can be seen as the API for the program and must be supplied by the prover. Since neither `x` nor `y` is marked as public, the verifier does not supply any inputs, when verifying the proof. The prover supplies the values for `x` and `y` in the _Prover.toml_ file. -As for the program body, `assert` ensures that the condition to be satisfied (e.g. `x != y`) is -constrained by the proof of the execution of said program (i.e. if the condition was not met, the -verifier would reject the proof as an invalid proof). +As for the program body, `assert` ensures that the condition to be satisfied (e.g. `x != y`) is constrained by the proof of the execution of said program (i.e. if the condition was not met, the verifier would reject the proof as an invalid proof). ### Prover.toml -The _Prover.toml_ file is a file which the prover uses to supply his witness values(both private and -public). +The _Prover.toml_ file is a file which the prover uses to supply the inputs to the Noir program (both private and public). In our hello world program the _Prover.toml_ file looks like this: @@ -114,12 +104,9 @@ x = "1" y = "2" ``` -When the command `nargo prove` is executed, two processes happen: - -1. Noir creates a proof that `x`, which holds the value of `1`, and `y`, which holds the value of `2`, - is not equal. This inequality constraint is due to the line `assert(x != y)`. +When the command `nargo execute` is executed, nargo will execute the Noir program using the inputs specified in `Prover.toml`, aborting if it finds that these do not satisfy the constraints defined by `main`. In this example, `x` and `y` must satisfy the inequality constraint `assert(x != y)`. -2. Noir creates and stores the proof of this statement in the _proofs_ directory in a file called your-project.proof. So if your project is named "private_voting" (defined in the project Nargo.toml), the proof will be saved at `./proofs/private_voting.proof`. Opening this file will display the proof in hex format. +If an output name is specified such as `nargo execute foo`, the witness generated by this execution will be written to `./target/foo.gz`. This can then be used to generate a proof of the execution. #### Arrays of Structs @@ -155,45 +142,18 @@ baz = 2 #### Custom toml files -You can specify a `toml` file with a different name to use for proving by using the `--prover-name` or `-p` flags. +You can specify a `toml` file with a different name to use for execution by using the `--prover-name` or `-p` flags. -This command looks for proof inputs in the default **Prover.toml** and generates the proof and saves it at `./proofs/.proof`: +This command looks for proof inputs in the default **Prover.toml** and generates the witness and saves it at `./target/foo.gz`: ```bash -nargo prove +nargo execute foo ``` -This command looks for proof inputs in the custom **OtherProver.toml** and generates proof and saves it at `./proofs/.proof`: +This command looks for proof inputs in the custom **OtherProver.toml** and generates the witness and saves it at `./target/bar.gz`: ```bash -nargo prove -p OtherProver +nargo execute -p OtherProver bar ``` -## Verifying a Proof - -When the command `nargo verify` is executed, two processes happen: - -1. Noir checks in the _proofs_ directory for a proof file with the project name (eg. test_project.proof) - -2. If that file is found, the proof's validity is checked - -> **Note:** The validity of the proof is linked to the current Noir program; if the program is -> changed and the verifier verifies the proof, it will fail because the proof is not valid for the -> _modified_ Noir program. - -In production, the prover and the verifier are usually two separate entities. A prover would -retrieve the necessary inputs, execute the Noir program, generate a proof and pass it to the -verifier. The verifier would then retrieve the public inputs, usually from external sources, and -verify the validity of the proof against it. - -Take a private asset transfer as an example: - -A person using a browser as the prover would retrieve private inputs locally (e.g. the user's private key) and -public inputs (e.g. the user's encrypted balance on-chain), compute the transfer, generate a proof -and submit it to the verifier smart contract. - -The verifier contract would then draw the user's encrypted balance directly from the blockchain and -verify the proof submitted against it. If the verification passes, additional functions in the -verifier contract could trigger (e.g. approve the asset transfer). - Now that you understand the concepts, you'll probably want some editor feedback while you are writing more complex code. diff --git a/docs/docs/getting_started/tooling/noir_codegen.md b/docs/docs/getting_started/tooling/noir_codegen.md index d65151da0ab..1c040585340 100644 --- a/docs/docs/getting_started/tooling/noir_codegen.md +++ b/docs/docs/getting_started/tooling/noir_codegen.md @@ -2,7 +2,7 @@ title: Noir Codegen for TypeScript description: Learn how to use Noir codegen to generate TypeScript bindings keywords: [Nargo, Noir, compile, TypeScript] -sidebar_position: 2 +sidebar_position: 3 --- When using TypeScript, it is extra work to interpret Noir program outputs in a type-safe way. Third party libraries may exist for popular Noir programs, but they are either hard to find or unmaintained. diff --git a/docs/docs/how_to/how-to-oracles.md b/docs/docs/how_to/how-to-oracles.md index 8cf8035a5c4..5f427f1e23f 100644 --- a/docs/docs/how_to/how-to-oracles.md +++ b/docs/docs/how_to/how-to-oracles.md @@ -177,7 +177,7 @@ interface ForeignCallResult { ## Step 3 - Usage with Nargo -Using the [`nargo` CLI tool](../getting_started/installation/index.md), you can use oracles in the `nargo test`, `nargo execute` and `nargo prove` commands by passing a value to `--oracle-resolver`. For example: +Using the [`nargo` CLI tool](../getting_started/installation/index.md), you can use oracles in the `nargo test` and `nargo execute` commands by passing a value to `--oracle-resolver`. For example: ```bash nargo test --oracle-resolver http://localhost:5555 @@ -203,7 +203,7 @@ As one can see, in NoirJS, the [`foreignCallHandler`](../reference/NoirJS/noir_j Does this mean you don't have to write an RPC server like in [Step #2](#step-2---write-an-rpc-server)? -You don't technically have to, but then how would you run `nargo test` or `nargo prove`? To use both `Nargo` and `NoirJS` in your development flow, you will have to write a JSON RPC server. +You don't technically have to, but then how would you run `nargo test`? To use both `Nargo` and `NoirJS` in your development flow, you will have to write a JSON RPC server. ::: diff --git a/docs/docs/how_to/how-to-solidity-verifier.md b/docs/docs/how_to/how-to-solidity-verifier.md index e3c7c1065da..7c96e22b8d5 100644 --- a/docs/docs/how_to/how-to-solidity-verifier.md +++ b/docs/docs/how_to/how-to-solidity-verifier.md @@ -43,11 +43,19 @@ Generating a Solidity Verifier contract is actually a one-command process. Howev This is by far the most straight-forward step. Just run: ```sh -nargo codegen-verifier +nargo compile ``` -A new `contract` folder would then be generated in your project directory, containing the Solidity -file `plonk_vk.sol`. It can be deployed to any EVM blockchain acting as a verifier smart contract. +This will compile your source code into a Noir build artifact to be stored in the `./target` directory, you can then generate the smart contract using the commands: + +```sh +# Here we pass the path to the newly generated Noir artifact. +bb write_vk -b ./target/.json +bb contract +``` + +replacing `` with the name of your Noir project. A new `contract` folder would then be generated in your project directory, containing the Solidity +file `contract.sol`. It can be deployed to any EVM blockchain acting as a verifier smart contract. :::info @@ -123,11 +131,25 @@ To verify a proof using the Solidity verifier contract, we call the `verify` fun function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external view returns (bool) ``` -When using the default example in the [Hello Noir](../getting_started/hello_noir/index.md) guide, the easiest way to confirm that the verifier contract is doing its job is by calling the `verify` function via remix with the required parameters. For `_proof`, run `nargo prove` and use the string in `proof/.proof` (adding the hex `0x` prefix). We can also copy the public input from `Verifier.toml`, as it will be properly formatted as 32-byte strings: +When using the default example in the [Hello Noir](../getting_started/hello_noir/index.md) guide, the easiest way to confirm that the verifier contract is doing its job is by calling the `verify` function via remix with the required parameters. Note that the public inputs must be passed in separately to the rest of the proof so we must split the proof as returned from `bb`. +First generate a proof with `bb` at the location `./proof` using the steps in [get started](../getting_started/hello_noir/index.md), this proof is in a binary format but we want to convert it into a hex string to pass into Remix, this can be done with the + +```bash +# This value must be changed to match the number of public inputs (including return values!) in your program. +NUM_PUBLIC_INPUTS=1 +PUBLIC_INPUT_BYTES=32*NUM_PUBLIC_INPUTS +HEX_PUBLIC_INPUTS=$(head -c $PUBLIC_INPUT_BYTES ./proof | od -An -v -t x1 | tr -d $' \n') +HEX_PROOF=$(tail -c +$(($PUBLIC_INPUT_BYTES + 1)) ./proof | od -An -v -t x1 | tr -d $' \n') + +echo "Public inputs:" +echo $HEX_PUBLIC_INPUTS + +echo "Proof:" +echo "0x$HEX_PROOF" ``` -0x...... , [0x0000.....02] -``` + +Remix expects that the public inputs will be split into an array of `bytes32` values so `HEX_PUBLIC_INPUTS` needs to be split up into 32 byte chunks which are prefixed with `0x` accordingly. A programmatic example of how the `verify` function is called can be seen in the example zk voting application [here](https://github.com/noir-lang/noir-examples/blob/33e598c257e2402ea3a6b68dd4c5ad492bce1b0a/foundry-voting/src/zkVote.sol#L35): @@ -144,11 +166,9 @@ function castVote(bytes calldata proof, uint proposalId, uint vote, bytes32 null :::info[Return Values] -A circuit doesn't have the concept of a return value. Return values are just syntactic sugar in -Noir. +A circuit doesn't have the concept of a return value. Return values are just syntactic sugar in Noir. -Under the hood, the return value is passed as an input to the circuit and is checked at the end of -the circuit program. +Under the hood, the return value is passed as an input to the circuit and is checked at the end of the circuit program. For example, if you have Noir program like this: @@ -162,11 +182,11 @@ fn main( ) -> pub Field ``` -the `verify` function will expect the public inputs array (second function parameter) to be of length 3, the two inputs and the return value. Like before, these values are populated in Verifier.toml after running `nargo prove`. +the `verify` function will expect the public inputs array (second function parameter) to be of length 3, the two inputs and the return value. Passing only two inputs will result in an error such as `PUBLIC_INPUT_COUNT_INVALID(3, 2)`. -In this case, the inputs parameter to `verify` would be an array ordered as `[pubkey_x, pubkey_y, return]`. +In this case, the inputs parameter to `verify` would be an array ordered as `[pubkey_x, pubkey_y, return`. ::: diff --git a/docs/docs/noir/concepts/data_types/booleans.md b/docs/docs/noir/concepts/data_types/booleans.md index 69826fcd724..3dcfa836814 100644 --- a/docs/docs/noir/concepts/data_types/booleans.md +++ b/docs/docs/noir/concepts/data_types/booleans.md @@ -23,9 +23,6 @@ fn main() { } ``` -> **Note:** When returning a boolean value, it will show up as a value of 1 for `true` and 0 for -> `false` in _Verifier.toml_. - The boolean type is most commonly used in conditionals like `if` expressions and `assert` statements. More about conditionals is covered in the [Control Flow](../control_flow) and [Assert Function](../assert) sections. diff --git a/docs/docs/noir/concepts/data_types/integers.md b/docs/docs/noir/concepts/data_types/integers.md index 6b2d3773912..c14fffa7174 100644 --- a/docs/docs/noir/concepts/data_types/integers.md +++ b/docs/docs/noir/concepts/data_types/integers.md @@ -115,7 +115,7 @@ y = "1" Would result in: ``` -$ nargo prove +$ nargo execute error: Assertion failed: 'attempt to add with overflow' ┌─ ~/src/main.nr:9:13 │ diff --git a/examples/codegen_verifier/.gitignore b/examples/codegen_verifier/.gitignore new file mode 100644 index 00000000000..c0d62c447d3 --- /dev/null +++ b/examples/codegen_verifier/.gitignore @@ -0,0 +1,4 @@ +out +cache +target +src/contract.sol \ No newline at end of file diff --git a/examples/codegen_verifier/Nargo.toml b/examples/codegen_verifier/Nargo.toml new file mode 100644 index 00000000000..2b367f30dbc --- /dev/null +++ b/examples/codegen_verifier/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello_world" +type = "bin" +authors = [""] +compiler_version = ">=0.29.0" + +[dependencies] \ No newline at end of file diff --git a/examples/codegen_verifier/Prover.toml b/examples/codegen_verifier/Prover.toml new file mode 100644 index 00000000000..2c1854573a4 --- /dev/null +++ b/examples/codegen_verifier/Prover.toml @@ -0,0 +1,2 @@ +x = 1 +y = 2 diff --git a/examples/codegen_verifier/codegen_verifier.sh b/examples/codegen_verifier/codegen_verifier.sh new file mode 100755 index 00000000000..fabd6235a67 --- /dev/null +++ b/examples/codegen_verifier/codegen_verifier.sh @@ -0,0 +1,38 @@ +#!/bin/bash +set -eu + +BACKEND=${BACKEND:-bb} + +nargo compile + +# TODO: backend should automatically generate vk if necessary. +$BACKEND write_vk -b ./target/hello_world.json +$BACKEND contract -o ./src/contract.sol + +# We now generate a proof and check whether the verifier contract will verify it. + +nargo execute witness + +PROOF_PATH=./target/proof +$BACKEND prove -b ./target/hello_world.json -w ./target/witness.gz -o $PROOF_PATH + +NUM_PUBLIC_INPUTS=1 +PUBLIC_INPUT_BYTES=$((32 * $NUM_PUBLIC_INPUTS)) +HEX_PUBLIC_INPUTS=$(head -c $PUBLIC_INPUT_BYTES $PROOF_PATH | od -An -v -t x1 | tr -d $' \n') +HEX_PROOF=$(tail -c +$(($PUBLIC_INPUT_BYTES + 1)) $PROOF_PATH | od -An -v -t x1 | tr -d $' \n') + +# Spin up an anvil node to deploy the contract to +anvil & + +DEPLOY_INFO=$(forge create UltraVerifier \ + --rpc-url "127.0.0.1:8545" \ + --private-key "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" \ + --json) +VERIFIER_ADDRESS=$(echo $DEPLOY_INFO | jq -r '.deployedTo') + +# Call the verifier contract with our proof. +# Note that we haven't needed to split up `HEX_PUBLIC_INPUTS` as there's only a single public input +cast call $VERIFIER_ADDRESS "verify(bytes, bytes32[])(bool)" "0x$HEX_PROOF" "[0x$HEX_PUBLIC_INPUTS]" + +# Stop anvil node again +kill %- \ No newline at end of file diff --git a/examples/codegen_verifier/foundry.toml b/examples/codegen_verifier/foundry.toml new file mode 100644 index 00000000000..25b918f9c9a --- /dev/null +++ b/examples/codegen_verifier/foundry.toml @@ -0,0 +1,6 @@ +[profile.default] +src = "src" +out = "out" +libs = ["lib"] + +# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/examples/codegen_verifier/src/main.nr b/examples/codegen_verifier/src/main.nr new file mode 100644 index 00000000000..baef0c3786a --- /dev/null +++ b/examples/codegen_verifier/src/main.nr @@ -0,0 +1,3 @@ +fn main(x: Field, y: pub Field) { + assert(x != y); +} \ No newline at end of file diff --git a/examples/codegen_verifier/test.sh b/examples/codegen_verifier/test.sh new file mode 100755 index 00000000000..93c2f6edf51 --- /dev/null +++ b/examples/codegen_verifier/test.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -eu + +# This file is used for Noir CI and is not required. + +BACKEND=${BACKEND:-bb} + +rm -f ./src/contract.sol + +./codegen_verifier.sh + +if ! [ -f ./src/contract.sol ]; then + printf '%s\n' "Contract not written to file" >&2 + exit 1 +fi \ No newline at end of file diff --git a/examples/prove_and_verify/Nargo.toml b/examples/prove_and_verify/Nargo.toml new file mode 100644 index 00000000000..2b367f30dbc --- /dev/null +++ b/examples/prove_and_verify/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello_world" +type = "bin" +authors = [""] +compiler_version = ">=0.29.0" + +[dependencies] \ No newline at end of file diff --git a/examples/prove_and_verify/Prover.toml b/examples/prove_and_verify/Prover.toml new file mode 100644 index 00000000000..8c12ebba6cf --- /dev/null +++ b/examples/prove_and_verify/Prover.toml @@ -0,0 +1,2 @@ +x = "1" +y = "2" diff --git a/examples/prove_and_verify/proofs/proof b/examples/prove_and_verify/proofs/proof new file mode 100644 index 0000000000000000000000000000000000000000..01d5ad276865ced1d94c7e1be9a84e09e0d6cb50 GIT binary patch literal 2176 zcmV-`2!Hng000000000000000000000000000000000000006J0S8cdAa>aDI1er` zD|x|5vMZ?MQTBMo$;s!NqkKRF(GdPwXbO6bcBHP4(CLcGZ{3r7QLt zaWO0Zhf%!!=``aT_Ngbft_>T+6XBD6%_RL2=Nb|XZKh8$=o?+MNSMEld2+}qL|YqH zLv37TBiqvfn7o4__bhJ|M<8>FmMP<3Sen_18u;RyI*DdwZ_hvTws2jpcP8bGBZ^e3)Jn6=g9>4a&jMY3YvROW7@1uygo z;5@Y@!u0*#UO#;c$)lIBLj70Kdl)i$`9uWor`4HW4^9?RD2x4cYsS-=KY2m(_GRbXxLd`oyO*Z)%l*L|x zv-CZ8>9svulPJHe7Fxx>8C!H#UbE;2(0fM-gegT@y=e-H?)xt_#D9X$wMVOf>DFaK z0%FYk?xNKLWKuV8By z9xl$MPJ!&4KjFIO(;;Z(vbJ*pWgkp2C< &3u_voM;b zOtM%%_fQ{^&wAJfZ;GiN0p9qKBout>sXkPL)2W#Jx`<}s)UUqDwXxO`peHgLbtXEi zA}QV2A5Y-kA}enoMoM3VRp`w6Y)0a8ZZH@O!Ts}z*}woW#imU_!aB{?Y1w4 zd~iKsf)fzvxs8$Gq6iEr7lL!+cc7iQiE*bBVf0JiH2S;)RXw_%l4}P~Q)PHJu_p4{*Ru_1m9Dp8)*zYD$!A&?i2~NJxFh-eka_ z5&@JLG^IL)kaSba{Rl?wehG5T^4158geGzaxi$V!E+Cd58w*SZEJDPnAuDv|2SQ2v zD6U)1Jf#xchKQNmnPi0fe{GsY(T|4-SxmAGRYR z!;|O<+&dyFTcx>!{NBfR7#ofvKxi;V`O!!mxJ=Y6>I+}AZGrHbn%qc>U|YtSq617FqhC6+)VddC>J;Cq)J1og5Luo@<-Q12xSbLa zp4H7G58tL4;|ZpwE*GX6ePf%~(6m1I<@^({r+s^J%rvkGB@5*3ayuiQ!Fasr&xbP) zK^aV+8fDOXvjj{o^OVgaZxq-wLO0uf;Uit)e{PD7iO70nerlMaHatF2o1>d1co%5j zw_sTKrNcmFmNe2Vd}^mZ>`6X298oXo2{Ic8E_?0a`h_++3wIRNg(+kP zb-A39b^ZaJVA~p0gnqqRfL<9O+WIHv)7i5Wx6|)VbSDHDJAecE!UA?Iom+~24j~r_ z0o~7H^Q};cpVA~TpTksRgysp2c=}a06gZg`WJGKS3~JRg-RURs=LMFuX7>T#u|qq@ zqW7q6c{6l)ehj4=`-R~qJstJS6W?>-Ks(wKT*z4TN_7gwYUa}5Y-@}e^2-u#-0`N8 zhrUI9DFl3KIvt{UlC9G^Sb2>`aAU|Hah48r%uVBMRlEXl>FO?W8eBWSIGd$9k32Gi zv#M(<)#fWe=Xb3LG@0zy4oWefBzX1!I!VPV*gt~=P#t9w^~deLGAGQZA07Pf|Mif} zddk93$K#e}$j;HZ1L|la>frfIP|MwU9zkTl7mWdCoVt=%Lg1jKVgDRgntNg{1!LxB z5V7Ku@3Sc}26&B|D4S8BB)h7jOK-f&6j@IS-K*efFN6G$90iBbvClb1UX_J6;X{d) z4b5cs8uKU`K;Eh0C;UB?yTPS{8b-r#20xH2mHtQTX?08lgJ97bm3F-#stFrS(n0h9 z4CA}n2txgxH+HlnLO#AneCmV&#-b9mZ@nAn!i#}(}^jL#=8#xmc C5)-Ka literal 0 HcmV?d00001 diff --git a/examples/prove_and_verify/prove_and_verify.sh b/examples/prove_and_verify/prove_and_verify.sh new file mode 100755 index 00000000000..01ee6c70738 --- /dev/null +++ b/examples/prove_and_verify/prove_and_verify.sh @@ -0,0 +1,14 @@ +#!/bin/bash +set -eu + +BACKEND=${BACKEND:-bb} + +nargo execute witness + +# TODO: `bb` should create `proofs` directory if it doesn't exist. +mkdir -p proofs +$BACKEND prove -b ./target/hello_world.json -w ./target/witness.gz + +# TODO: backend should automatically generate vk if necessary. +$BACKEND write_vk -b ./target/hello_world.json +$BACKEND verify -v ./target/vk -p ./proofs/proof \ No newline at end of file diff --git a/examples/prove_and_verify/src/main.nr b/examples/prove_and_verify/src/main.nr new file mode 100644 index 00000000000..baef0c3786a --- /dev/null +++ b/examples/prove_and_verify/src/main.nr @@ -0,0 +1,3 @@ +fn main(x: Field, y: pub Field) { + assert(x != y); +} \ No newline at end of file diff --git a/examples/prove_and_verify/test.sh b/examples/prove_and_verify/test.sh new file mode 100755 index 00000000000..a8ae3cca132 --- /dev/null +++ b/examples/prove_and_verify/test.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -eu + +# This file is used for Noir CI and is not required. + +BACKEND=${BACKEND:-bb} + +rm -rf ./target ./proofs + +./prove_and_verify.sh \ No newline at end of file diff --git a/noir_stdlib/src/aes128.nr b/noir_stdlib/src/aes128.nr index e6e2a5e4997..cd61021a953 100644 --- a/noir_stdlib/src/aes128.nr +++ b/noir_stdlib/src/aes128.nr @@ -2,3 +2,6 @@ // docs:start:aes128 pub fn aes128_encrypt(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8] {} // docs:end:aes128 + +#[foreign(aes128_encrypt)] +pub fn aes128_encrypt_slice(input: [u8], iv: [u8; 16], key: [u8; 16]) -> [u8] {} diff --git a/noir_stdlib/src/embedded_curve_ops.nr b/noir_stdlib/src/embedded_curve_ops.nr index 21d658db615..cd8c421e136 100644 --- a/noir_stdlib/src/embedded_curve_ops.nr +++ b/noir_stdlib/src/embedded_curve_ops.nr @@ -1,15 +1,21 @@ use crate::ops::arith::{Add, Sub, Neg}; +use crate::cmp::Eq; // TODO(https://github.com/noir-lang/noir/issues/4931) struct EmbeddedCurvePoint { x: Field, y: Field, + is_infinite: bool } impl EmbeddedCurvePoint { fn double(self) -> EmbeddedCurvePoint { embedded_curve_add(self, self) } + + fn point_at_infinity() -> EmbeddedCurvePoint { + EmbeddedCurvePoint { x: 0, y: 0, is_infinite: true } + } } impl Add for EmbeddedCurvePoint { @@ -28,11 +34,24 @@ impl Neg for EmbeddedCurvePoint { fn neg(self) -> EmbeddedCurvePoint { EmbeddedCurvePoint { x: self.x, - y: -self.y + y: -self.y, + is_infinite: self.is_infinite } } } +impl Eq for EmbeddedCurvePoint { + fn eq(self: Self, b: EmbeddedCurvePoint) -> bool { + (self.is_infinite & b.is_infinite) | ((self.is_infinite == b.is_infinite) & (self.x == b.x) & (self.y == b.y)) + } +} + +// Scalar represented as low and high limbs +struct EmbeddedCurveScalar { + lo: Field, + hi: Field, +} + // Computes a multi scalar multiplication over the embedded curve. // For bn254, We have Grumpkin and Baby JubJub. // For bls12-381, we have JubJub and Bandersnatch. @@ -42,9 +61,9 @@ impl Neg for EmbeddedCurvePoint { #[foreign(multi_scalar_mul)] // docs:start:multi_scalar_mul pub fn multi_scalar_mul( - points: [Field; N], // points represented as x and y coordinates [x1, y1, x2, y2, ...] - scalars: [Field; N] // scalars represented as low and high limbs [low1, high1, low2, high2, ...] -) -> [Field; 2] + points: [EmbeddedCurvePoint; N], + scalars: [EmbeddedCurveScalar; N] +) -> [Field; 3] // docs:end:multi_scalar_mul {} @@ -52,12 +71,12 @@ pub fn multi_scalar_mul( pub fn fixed_base_scalar_mul( scalar_low: Field, scalar_high: Field -) -> [Field; 2] +) -> [Field; 3] // docs:end:fixed_base_scalar_mul { - let g1_x = 1; - let g1_y = 17631683881184975370165255887551781615748388533673675138860; - multi_scalar_mul([g1_x, g1_y], [scalar_low, scalar_high]) + let g1 = EmbeddedCurvePoint { x: 1, y: 17631683881184975370165255887551781615748388533673675138860, is_infinite: false }; + let scalar = EmbeddedCurveScalar { lo: scalar_low, hi: scalar_high }; + multi_scalar_mul([g1], [scalar]) } // This is a hack as returning an `EmbeddedCurvePoint` from a foreign function in brillig returns a [BrilligVariable::SingleAddr; 2] rather than BrilligVariable::BrilligArray @@ -72,8 +91,8 @@ fn embedded_curve_add( let point_array = embedded_curve_add_array_return(point1, point2); let x = point_array[0]; let y = point_array[1]; - EmbeddedCurvePoint { x, y } + EmbeddedCurvePoint { x, y, is_infinite: point_array[2] == 1 } } #[foreign(embedded_curve_add)] -fn embedded_curve_add_array_return(_point1: EmbeddedCurvePoint, _point2: EmbeddedCurvePoint) -> [Field; 2] {} +fn embedded_curve_add_array_return(_point1: EmbeddedCurvePoint, _point2: EmbeddedCurvePoint) -> [Field; 3] {} diff --git a/noir_stdlib/src/field/bn254.nr b/noir_stdlib/src/field/bn254.nr index d70310be391..2e82d9e7c23 100644 --- a/noir_stdlib/src/field/bn254.nr +++ b/noir_stdlib/src/field/bn254.nr @@ -25,7 +25,7 @@ unconstrained fn decompose_unsafe(x: Field) -> (Field, Field) { fn assert_gt_limbs(a: (Field, Field), b: (Field, Field)) { let (alo, ahi) = a; let (blo, bhi) = b; - let borrow = lte_unsafe(alo, blo, 16); + let borrow = lte_unsafe_16(alo, blo); let rlo = alo - blo - 1 + (borrow as Field) * TWO_POW_128; let rhi = ahi - bhi - (borrow as Field); @@ -51,9 +51,9 @@ pub fn decompose(x: Field) -> (Field, Field) { (xlo, xhi) } -unconstrained fn lt_unsafe(x: Field, y: Field, num_bytes: u32) -> bool { - let x_bytes = x.__to_le_radix(256, num_bytes); - let y_bytes = y.__to_le_radix(256, num_bytes); +fn lt_unsafe_internal(x: Field, y: Field, num_bytes: u32) -> bool { + let x_bytes = x.to_le_radix(256, num_bytes); + let y_bytes = y.to_le_radix(256, num_bytes); let mut x_is_lt = false; let mut done = false; for i in 0..num_bytes { @@ -70,8 +70,20 @@ unconstrained fn lt_unsafe(x: Field, y: Field, num_bytes: u32) -> bool { x_is_lt } -unconstrained fn lte_unsafe(x: Field, y: Field, num_bytes: u32) -> bool { - lt_unsafe(x, y, num_bytes) | (x == y) +fn lte_unsafe_internal(x: Field, y: Field, num_bytes: u32) -> bool { + if x == y { + true + } else { + lt_unsafe_internal(x, y, num_bytes) + } +} + +unconstrained fn lt_unsafe_32(x: Field, y: Field) -> bool { + lt_unsafe_internal(x, y, 32) +} + +unconstrained fn lte_unsafe_16(x: Field, y: Field) -> bool { + lte_unsafe_internal(x, y, 16) } pub fn assert_gt(a: Field, b: Field) { @@ -90,7 +102,7 @@ pub fn assert_lt(a: Field, b: Field) { pub fn gt(a: Field, b: Field) -> bool { if a == b { false - } else if lt_unsafe(a, b, 32) { + } else if lt_unsafe_32(a, b) { assert_gt(b, a); false } else { @@ -105,7 +117,10 @@ pub fn lt(a: Field, b: Field) -> bool { mod tests { // TODO: Allow imports from "super" - use crate::field::bn254::{decompose_unsafe, decompose, lt_unsafe, assert_gt, gt, lt, TWO_POW_128, lte_unsafe, PLO, PHI}; + use crate::field::bn254::{ + decompose_unsafe, decompose, lt_unsafe_internal, assert_gt, gt, lt, TWO_POW_128, + lte_unsafe_internal, PLO, PHI + }; #[test] fn check_decompose_unsafe() { @@ -123,23 +138,23 @@ mod tests { #[test] fn check_lt_unsafe() { - assert(lt_unsafe(0, 1, 16)); - assert(lt_unsafe(0, 0x100, 16)); - assert(lt_unsafe(0x100, TWO_POW_128 - 1, 16)); - assert(!lt_unsafe(0, TWO_POW_128, 16)); + assert(lt_unsafe_internal(0, 1, 16)); + assert(lt_unsafe_internal(0, 0x100, 16)); + assert(lt_unsafe_internal(0x100, TWO_POW_128 - 1, 16)); + assert(!lt_unsafe_internal(0, TWO_POW_128, 16)); } #[test] fn check_lte_unsafe() { - assert(lte_unsafe(0, 1, 16)); - assert(lte_unsafe(0, 0x100, 16)); - assert(lte_unsafe(0x100, TWO_POW_128 - 1, 16)); - assert(!lte_unsafe(0, TWO_POW_128, 16)); - - assert(lte_unsafe(0, 0, 16)); - assert(lte_unsafe(0x100, 0x100, 16)); - assert(lte_unsafe(TWO_POW_128 - 1, TWO_POW_128 - 1, 16)); - assert(lte_unsafe(TWO_POW_128, TWO_POW_128, 16)); + assert(lte_unsafe_internal(0, 1, 16)); + assert(lte_unsafe_internal(0, 0x100, 16)); + assert(lte_unsafe_internal(0x100, TWO_POW_128 - 1, 16)); + assert(!lte_unsafe_internal(0, TWO_POW_128, 16)); + + assert(lte_unsafe_internal(0, 0, 16)); + assert(lte_unsafe_internal(0x100, 0x100, 16)); + assert(lte_unsafe_internal(TWO_POW_128 - 1, TWO_POW_128 - 1, 16)); + assert(lte_unsafe_internal(TWO_POW_128, TWO_POW_128, 16)); } #[test] diff --git a/scripts/install_bb.sh b/scripts/install_bb.sh new file mode 100755 index 00000000000..519ffe6cb03 --- /dev/null +++ b/scripts/install_bb.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# We use this script just for CI so we assume we're running on x86 linux + +mkdir -p $HOME/.barretenberg +curl -o ./barretenberg-x86_64-linux-gnu.tar.gz -L https://github.com/AztecProtocol/aztec-packages/releases/download/aztec-packages-v0.41.0/barretenberg-x86_64-linux-gnu.tar.gz +tar -xvf ./barretenberg-x86_64-linux-gnu.tar.gz -C $HOME/.barretenberg/ +echo 'export PATH=$PATH:$HOME/.barretenberg/' >> ~/.bashrc +source ~/.bashrc diff --git a/test_programs/compile_success_empty/intrinsic_die/src/main.nr b/test_programs/compile_success_empty/intrinsic_die/src/main.nr index 9ce17f72c0d..a6c6d3df9a1 100644 --- a/test_programs/compile_success_empty/intrinsic_die/src/main.nr +++ b/test_programs/compile_success_empty/intrinsic_die/src/main.nr @@ -4,5 +4,7 @@ fn main(x: Field) { let hash = std::hash::pedersen_commitment([x]); let g1_x = 0x0000000000000000000000000000000000000000000000000000000000000001; let g1_y = 0x0000000000000002cf135e7506a45d632d270d45f1181294833fc48d823f272c; - let _p1 = std::embedded_curve_ops::multi_scalar_mul([g1_x, g1_y], [x, 0]); + let g1 = std::embedded_curve_ops::EmbeddedCurvePoint { x: g1_x, y: g1_y, is_infinite: false }; + let scalar = std::embedded_curve_ops::EmbeddedCurveScalar { lo: x, hi: 0 }; + let _p1 = std::embedded_curve_ops::multi_scalar_mul([g1], [scalar]); } diff --git a/test_programs/execution_success/brillig_embedded_curve/src/main.nr b/test_programs/execution_success/brillig_embedded_curve/src/main.nr index 8a1a7f08975..89a699448dc 100644 --- a/test_programs/execution_success/brillig_embedded_curve/src/main.nr +++ b/test_programs/execution_success/brillig_embedded_curve/src/main.nr @@ -2,22 +2,22 @@ use dep::std; unconstrained fn main(priv_key: Field, pub_x: pub Field, pub_y: pub Field) { let g1_y = 17631683881184975370165255887551781615748388533673675138860; - let g1 = std::embedded_curve_ops::EmbeddedCurvePoint { x: 1, y: g1_y }; - + let g1 = std::embedded_curve_ops::EmbeddedCurvePoint { x: 1, y: g1_y, is_infinite: false }; + let scalar = std::embedded_curve_ops::EmbeddedCurveScalar { lo: priv_key, hi: 0 }; // Test that multi_scalar_mul correctly derives the public key - let res = std::embedded_curve_ops::multi_scalar_mul([g1.x, g1.y], [priv_key, 0]); + let res = std::embedded_curve_ops::multi_scalar_mul([g1], [scalar]); assert(res[0] == pub_x); assert(res[1] == pub_y); // Test that double function calling embedded_curve_add works as expected - let pub_point = std::embedded_curve_ops::EmbeddedCurvePoint { x: pub_x, y: pub_y }; + let pub_point = std::embedded_curve_ops::EmbeddedCurvePoint { x: pub_x, y: pub_y, is_infinite: false }; let res = pub_point.double(); let double = g1.add(g1); assert(double.x == res.x); // Test calling multi_scalar_mul with multiple points and scalars - let res = std::embedded_curve_ops::multi_scalar_mul([g1.x, g1.y, g1.x, g1.y], [priv_key, 0, priv_key, 0]); + let res = std::embedded_curve_ops::multi_scalar_mul([g1, g1], [scalar, scalar]); // The results should be double the g1 point because the scalars are 1 and we pass in g1 twice assert(double.x == res[0]); diff --git a/test_programs/execution_success/embedded_curve_ops/src/main.nr b/test_programs/execution_success/embedded_curve_ops/src/main.nr index 3cb27d8c181..46f919e947a 100644 --- a/test_programs/execution_success/embedded_curve_ops/src/main.nr +++ b/test_programs/execution_success/embedded_curve_ops/src/main.nr @@ -2,22 +2,22 @@ use dep::std; fn main(priv_key: Field, pub_x: pub Field, pub_y: pub Field) { let g1_y = 17631683881184975370165255887551781615748388533673675138860; - let g1 = std::embedded_curve_ops::EmbeddedCurvePoint { x: 1, y: g1_y }; - + let g1 = std::embedded_curve_ops::EmbeddedCurvePoint { x: 1, y: g1_y, is_infinite: false }; + let scalar = std::embedded_curve_ops::EmbeddedCurveScalar { lo: priv_key, hi: 0 }; // Test that multi_scalar_mul correctly derives the public key - let res = std::embedded_curve_ops::multi_scalar_mul([g1.x, g1.y], [priv_key, 0]); + let res = std::embedded_curve_ops::multi_scalar_mul([g1], [scalar]); assert(res[0] == pub_x); assert(res[1] == pub_y); // Test that double function calling embedded_curve_add works as expected - let pub_point = std::embedded_curve_ops::EmbeddedCurvePoint { x: pub_x, y: pub_y }; + let pub_point = std::embedded_curve_ops::EmbeddedCurvePoint { x: pub_x, y: pub_y, is_infinite: false }; let res = pub_point.double(); let double = g1.add(g1); assert(double.x == res.x); // Test calling multi_scalar_mul with multiple points and scalars - let res = std::embedded_curve_ops::multi_scalar_mul([g1.x, g1.y, g1.x, g1.y], [priv_key, 0, priv_key, 0]); + let res = std::embedded_curve_ops::multi_scalar_mul([g1, g1], [scalar, scalar]); // The results should be double the g1 point because the scalars are 1 and we pass in g1 twice assert(double.x == res[0]); diff --git a/test_programs/execution_success/trait_method_mut_self/src/main.nr b/test_programs/execution_success/trait_method_mut_self/src/main.nr index 0e736c2f098..fa47fd5d881 100644 --- a/test_programs/execution_success/trait_method_mut_self/src/main.nr +++ b/test_programs/execution_success/trait_method_mut_self/src/main.nr @@ -12,6 +12,14 @@ fn main(x: Field, y: pub Field) { pass_trait_by_mut_ref(&mut a_mut_ref, y); assert(a_mut_ref.x == y); + + let mut hasher = Poseidon2Hasher::default(); + hasher.write(x); + hasher.write(y); + let expected_hash = hasher.finish(); + // Check that we get the same result when using the hasher in a + // method that purely uses trait methods without a supplied implementation. + assert(hash_simple_array::([x, y]) == expected_hash); } trait SomeTrait { @@ -50,3 +58,17 @@ fn pass_trait_by_mut_ref(a_mut_ref: &mut T, value: Field) where T: SomeTrait // We auto add a mutable reference to the object type if the method call expects a mutable self a_mut_ref.set_value(value); } + +fn hash_simple_array(input: [Field; 2]) -> Field where H: Hasher + Default { + // Check that we can call a trait method instead of a trait implementation + // TODO: Need to remove the need for this type annotation + // TODO: Curently, without the annotation we will get `Expression type is ambiguous` when trying to use the `hasher` + let mut hasher: H = H::default(); + // Regression that the object is converted to a mutable reference type `&mut _`. + // Otherwise will see `Expected type &mut _, found type H`. + // Then we need to make sure to also auto dereference later in the type checking process + // when searching for a matching impl or else we will get `No matching impl found for `&mut H: Hasher` + hasher.write(input[0]); + hasher.write(input[1]); + hasher.finish() +} diff --git a/test_programs/execution_success/unit_value/Nargo.toml b/test_programs/execution_success/unit_value/Nargo.toml index f7e3697a7c1..1f9c4524ec5 100644 --- a/test_programs/execution_success/unit_value/Nargo.toml +++ b/test_programs/execution_success/unit_value/Nargo.toml @@ -1,7 +1,7 @@ [package] -name = "short" +name = "unit_value" type = "bin" authors = [""] compiler_version = ">=0.23.0" -[dependencies] \ No newline at end of file +[dependencies] diff --git a/test_programs/noir_test_success/embedded_curve_ops/Nargo.toml b/test_programs/noir_test_success/embedded_curve_ops/Nargo.toml new file mode 100644 index 00000000000..65e6efea538 --- /dev/null +++ b/test_programs/noir_test_success/embedded_curve_ops/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "embedded_curve_ops" +type = "bin" +authors = [""] +compiler_version = ">=0.23.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/noir_test_success/embedded_curve_ops/src/main.nr b/test_programs/noir_test_success/embedded_curve_ops/src/main.nr new file mode 100644 index 00000000000..9e3c5d87874 --- /dev/null +++ b/test_programs/noir_test_success/embedded_curve_ops/src/main.nr @@ -0,0 +1,37 @@ +use dep::std::embedded_curve_ops::{EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul}; + +#[test] + + fn test_infinite_point() { + let zero = EmbeddedCurvePoint::point_at_infinity(); + let zero = EmbeddedCurvePoint { x: 0, y: 0, is_infinite: true }; + let g1 = EmbeddedCurvePoint { x: 1, y: 17631683881184975370165255887551781615748388533673675138860, is_infinite: false }; + let g2 = g1 + g1; + + let s1 = EmbeddedCurveScalar { lo: 1, hi: 0 }; + let a = multi_scalar_mul([g1], [s1]); + assert(a[2] == 0); + assert(g1 + zero == g1); + assert(g1 - g1 == zero); + assert(g1 - zero == g1); + assert(zero + zero == zero); + assert( + multi_scalar_mul([g1], [s1]) + == [1, 17631683881184975370165255887551781615748388533673675138860, 0] + ); + assert(multi_scalar_mul([g1, g1], [s1, s1]) == [g2.x, g2.y, 0]); + assert( + multi_scalar_mul( + [g1, zero], + [EmbeddedCurveScalar { lo: 2, hi: 0 }, EmbeddedCurveScalar { lo: 42, hi: 25 }] + ) + == [g2.x, g2.y, 0] + ); + assert( + multi_scalar_mul( + [g1, g1, zero], + [s1, s1, EmbeddedCurveScalar { lo: 42, hi: 25 }] + ) + == [g2.x, g2.y, 0] + ); +} diff --git a/test_programs/rebuild.sh b/test_programs/rebuild.sh index 51e97278281..4733bad10c3 100755 --- a/test_programs/rebuild.sh +++ b/test_programs/rebuild.sh @@ -16,13 +16,14 @@ process_dir() { if [ -d ./target/ ]; then rm -r ./target/ fi - nargo compile --only-acir && nargo execute witness + nargo execute witness if [ -d "$current_dir/acir_artifacts/$dir_name/target" ]; then rm -r "$current_dir/acir_artifacts/$dir_name/target" fi mkdir $current_dir/acir_artifacts/$dir_name/target + mv ./target/$dir_name.json $current_dir/acir_artifacts/$dir_name/target/program.json mv ./target/*.gz $current_dir/acir_artifacts/$dir_name/target/ cd $current_dir @@ -70,4 +71,4 @@ if [ ! -z "$exit_status" ]; then echo "Rebuild failed!" exit $exit_status fi -echo "Rebuild Succeeded!" \ No newline at end of file +echo "Rebuild Succeeded!" diff --git a/tooling/backend_interface/CHANGELOG.md b/tooling/backend_interface/CHANGELOG.md deleted file mode 100644 index 9ebde989add..00000000000 --- a/tooling/backend_interface/CHANGELOG.md +++ /dev/null @@ -1,233 +0,0 @@ -# Changelog - -## [0.11.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.10.1...v0.11.0) (2023-08-18) - - -### ⚠ BREAKING CHANGES - -* Update `acvm` to 0.22.0 ([#240](https://github.com/noir-lang/acvm-backend-barretenberg/issues/240)) - -### Features - -* Update `acvm` to 0.22.0 ([#240](https://github.com/noir-lang/acvm-backend-barretenberg/issues/240)) ([d8342fd](https://github.com/noir-lang/acvm-backend-barretenberg/commit/d8342fd6da605ac3bbd889edf89cd122bc4689ce)) - -## [0.10.1](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.10.0...v0.10.1) (2023-08-18) - - -### Features - -* Migrate to `wasmer` 3.3.0 ([#236](https://github.com/noir-lang/acvm-backend-barretenberg/issues/236)) ([e115e38](https://github.com/noir-lang/acvm-backend-barretenberg/commit/e115e38856887c6b1eeead3534534ac7e6327ea9)) - -## [0.10.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.9.1...v0.10.0) (2023-07-26) - - -### ⚠ BREAKING CHANGES - -* Migrate to ACVM 0.21.0 ([#234](https://github.com/noir-lang/acvm-backend-barretenberg/issues/234)) - -### Features - -* Migrate to ACVM 0.21.0 ([#234](https://github.com/noir-lang/acvm-backend-barretenberg/issues/234)) ([15c8676](https://github.com/noir-lang/acvm-backend-barretenberg/commit/15c86768685d2946a767c350f6ef5972c86677eb)) - -## [0.9.1](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.9.0...v0.9.1) (2023-07-21) - - -### Features - -* add support for atomic memory opcodes ([#232](https://github.com/noir-lang/acvm-backend-barretenberg/issues/232)) ([a7aa6e9](https://github.com/noir-lang/acvm-backend-barretenberg/commit/a7aa6e9505bb402c1b3db0a990845ed26928e7aa)) - -## [0.9.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.8.0...v0.9.0) (2023-07-17) - - -### ⚠ BREAKING CHANGES - -* update to ACVM 0.19.0 ([#230](https://github.com/noir-lang/acvm-backend-barretenberg/issues/230)) - -### Miscellaneous Chores - -* update to ACVM 0.19.0 ([#230](https://github.com/noir-lang/acvm-backend-barretenberg/issues/230)) ([3f1d967](https://github.com/noir-lang/acvm-backend-barretenberg/commit/3f1d9674b904acb02c2a3e52481be8a6104c3a9d)) - -## [0.8.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.7.0...v0.8.0) (2023-07-12) - - -### ⚠ BREAKING CHANGES - -* Update to acvm 0.18.1 ([#228](https://github.com/noir-lang/acvm-backend-barretenberg/issues/228)) - -### Features - -* Update to acvm 0.18.1 ([#228](https://github.com/noir-lang/acvm-backend-barretenberg/issues/228)) ([397098b](https://github.com/noir-lang/acvm-backend-barretenberg/commit/397098b239efbe16785b1c9af108ca9fc4e24497)) - -## [0.7.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.6.1...v0.7.0) (2023-07-08) - - -### ⚠ BREAKING CHANGES - -* **bberg:** add secp256r1 builtin to barretenberg ([#223](https://github.com/noir-lang/acvm-backend-barretenberg/issues/223)) - -### Features - -* **bberg:** add secp256r1 builtin to barretenberg ([#223](https://github.com/noir-lang/acvm-backend-barretenberg/issues/223)) ([ceb4770](https://github.com/noir-lang/acvm-backend-barretenberg/commit/ceb47705a492fcdcea1f3c098aaab42ea8edbf2e)) - -## [0.6.1](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.6.0...v0.6.1) (2023-07-06) - - -### Features - -* switch RecursiveAggregation support to true ([#225](https://github.com/noir-lang/acvm-backend-barretenberg/issues/225)) ([e9462ae](https://github.com/noir-lang/acvm-backend-barretenberg/commit/e9462ae015ec0dfb0a23ccbb89562071f87940f5)) - -## [0.6.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.5.1...v0.6.0) (2023-07-06) - - -### ⚠ BREAKING CHANGES - -* Update to ACVM 0.16.0 ([#221](https://github.com/noir-lang/acvm-backend-barretenberg/issues/221)) - -### Features - -* Update to ACVM 0.16.0 ([#221](https://github.com/noir-lang/acvm-backend-barretenberg/issues/221)) ([062d5ed](https://github.com/noir-lang/acvm-backend-barretenberg/commit/062d5ed9b476fab8ac8d3ca13371699fb2aac332)) - -## [0.5.1](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.5.0...v0.5.1) (2023-06-20) - - -### Bug Fixes - -* Remove wasm32 target ([#219](https://github.com/noir-lang/acvm-backend-barretenberg/issues/219)) ([e4cbb6d](https://github.com/noir-lang/acvm-backend-barretenberg/commit/e4cbb6d476e8746de33c38506e2fcb970f1c866a)) - -## [0.5.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.4.0...v0.5.0) (2023-06-15) - - -### ⚠ BREAKING CHANGES - -* Update to target ACVM 0.15.0 ([#217](https://github.com/noir-lang/acvm-backend-barretenberg/issues/217)) - -### Features - -* Update to target ACVM 0.15.0 ([#217](https://github.com/noir-lang/acvm-backend-barretenberg/issues/217)) ([9331898](https://github.com/noir-lang/acvm-backend-barretenberg/commit/9331898f161321c8b6a82d5ea850f197952b2ed2)) - -## [0.4.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.3.0...v0.4.0) (2023-06-07) - - -### ⚠ BREAKING CHANGES - -* Recursion ([#207](https://github.com/noir-lang/acvm-backend-barretenberg/issues/207)) - -### Features - -* Recursion ([#207](https://github.com/noir-lang/acvm-backend-barretenberg/issues/207)) ([6fc479b](https://github.com/noir-lang/acvm-backend-barretenberg/commit/6fc479b9ae99d59bbfeb1b895d63cdbea469dcaa)) - -## [0.3.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.2.0...v0.3.0) (2023-06-01) - - -### ⚠ BREAKING CHANGES - -* Update to ACVM 0.13.0 ([#205](https://github.com/noir-lang/acvm-backend-barretenberg/issues/205)) -* added keccakvar constraints ([#213](https://github.com/noir-lang/acvm-backend-barretenberg/issues/213)) -* update pedersen hashes for new implementation ([#212](https://github.com/noir-lang/acvm-backend-barretenberg/issues/212)) - -### Features - -* added keccakvar constraints ([91ea65f](https://github.com/noir-lang/acvm-backend-barretenberg/commit/91ea65f6af7039095c7a3af7bc1e4ce302a68a8d)) -* added keccakvar constraints ([#213](https://github.com/noir-lang/acvm-backend-barretenberg/issues/213)) ([91ea65f](https://github.com/noir-lang/acvm-backend-barretenberg/commit/91ea65f6af7039095c7a3af7bc1e4ce302a68a8d)) -* Update to ACVM 0.13.0 ([#205](https://github.com/noir-lang/acvm-backend-barretenberg/issues/205)) ([298446e](https://github.com/noir-lang/acvm-backend-barretenberg/commit/298446ef8b69f528b6e2fd2abb2298d7b0a8118e)) - - -### Bug Fixes - -* Add or cleanup implementations for JS target ([#199](https://github.com/noir-lang/acvm-backend-barretenberg/issues/199)) ([f6134b7](https://github.com/noir-lang/acvm-backend-barretenberg/commit/f6134b7b502cb74882300b0046ab91ab000daf3c)) -* update pedersen hashes for new impl ([9a233ce](https://github.com/noir-lang/acvm-backend-barretenberg/commit/9a233ce8db9984b29b9cce0603f758d5281c89c9)) -* update pedersen hashes for new implementation ([#212](https://github.com/noir-lang/acvm-backend-barretenberg/issues/212)) ([9a233ce](https://github.com/noir-lang/acvm-backend-barretenberg/commit/9a233ce8db9984b29b9cce0603f758d5281c89c9)) - -## [0.2.0](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.1.2...v0.2.0) (2023-05-22) - - -### ⚠ BREAKING CHANGES - -* Update to acvm 0.12.0 ([#165](https://github.com/noir-lang/acvm-backend-barretenberg/issues/165)) -* Add serialization logic for RAM and ROM opcodes ([#153](https://github.com/noir-lang/acvm-backend-barretenberg/issues/153)) - -### Features - -* Add serde to `ConstraintSystem` types ([#196](https://github.com/noir-lang/acvm-backend-barretenberg/issues/196)) ([4c04a79](https://github.com/noir-lang/acvm-backend-barretenberg/commit/4c04a79e6d2b0115f3b4526c60f9f7dae8b464ae)) -* Add serialization logic for RAM and ROM opcodes ([#153](https://github.com/noir-lang/acvm-backend-barretenberg/issues/153)) ([3d3847d](https://github.com/noir-lang/acvm-backend-barretenberg/commit/3d3847de70e74a8f65c64e165ad15ae3d31f5350)) -* Update to acvm 0.12.0 ([#165](https://github.com/noir-lang/acvm-backend-barretenberg/issues/165)) ([d613c79](https://github.com/noir-lang/acvm-backend-barretenberg/commit/d613c79584a599f4adbd11d2ce3b61403c185b73)) - -## [0.1.2](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.1.1...v0.1.2) (2023-05-11) - - -### Bug Fixes - -* Remove star dependencies to allow publishing ([#182](https://github.com/noir-lang/acvm-backend-barretenberg/issues/182)) ([1727a79](https://github.com/noir-lang/acvm-backend-barretenberg/commit/1727a79ce7e66d95528f70c445cb4ec1b1ece636)) - -## [0.1.1](https://github.com/noir-lang/acvm-backend-barretenberg/compare/v0.1.0...v0.1.1) (2023-05-11) - - -### Bug Fixes - -* Add description so crate can be published ([#180](https://github.com/noir-lang/acvm-backend-barretenberg/issues/180)) ([caabf94](https://github.com/noir-lang/acvm-backend-barretenberg/commit/caabf9434031c6023a5e3a436c87fba0a1072539)) - -## 0.1.0 (2023-05-10) - - -### ⚠ BREAKING CHANGES - -* Update to ACVM v0.11.0 ([#151](https://github.com/noir-lang/acvm-backend-barretenberg/issues/151)) -* Add Keccak constraints ([#150](https://github.com/noir-lang/acvm-backend-barretenberg/issues/150)) -* migrate to ACVM 0.10.3 ([#148](https://github.com/noir-lang/acvm-backend-barretenberg/issues/148)) -* remove all crates other than `acvm-backend-barretenberg` and remove workspace ([#147](https://github.com/noir-lang/acvm-backend-barretenberg/issues/147)) -* merge `barretenberg_static_lib` and `barretenberg_wasm` ([#117](https://github.com/noir-lang/acvm-backend-barretenberg/issues/117)) -* remove dead blake2 code ([#137](https://github.com/noir-lang/acvm-backend-barretenberg/issues/137)) -* Implement pseudo-builder pattern for ConstraintSystem & hide struct fields ([#120](https://github.com/noir-lang/acvm-backend-barretenberg/issues/120)) -* return boolean rather than `FieldElement` from `verify_signature` ([#123](https://github.com/noir-lang/acvm-backend-barretenberg/issues/123)) -* avoid exposing internals of Assignments type ([#119](https://github.com/noir-lang/acvm-backend-barretenberg/issues/119)) -* update to acvm 0.9.0 ([#106](https://github.com/noir-lang/acvm-backend-barretenberg/issues/106)) -* Depend upon upstream barretenberg & switch to UltraPlonk ([#84](https://github.com/noir-lang/acvm-backend-barretenberg/issues/84)) -* update to ACVM 0.7.0 ([#90](https://github.com/noir-lang/acvm-backend-barretenberg/issues/90)) -* Remove create_proof and verify functions ([#82](https://github.com/noir-lang/acvm-backend-barretenberg/issues/82)) -* update to acvm v0.5.0 ([#60](https://github.com/noir-lang/acvm-backend-barretenberg/issues/60)) - -### Features - -* **acvm_interop:** Updates to reflect new acvm methods using pk/vk ([#50](https://github.com/noir-lang/acvm-backend-barretenberg/issues/50)) ([cff757d](https://github.com/noir-lang/acvm-backend-barretenberg/commit/cff757dca7971161e4bd25e7a744d910c37c22be)) -* Add Keccak constraints ([#150](https://github.com/noir-lang/acvm-backend-barretenberg/issues/150)) ([ce2b9ed](https://github.com/noir-lang/acvm-backend-barretenberg/commit/ce2b9ed456bd8d2ad8357c15736d62c2a5812add)) -* allow overriding transcript location with BARRETENBERG_TRANSCRIPT env var ([#86](https://github.com/noir-lang/acvm-backend-barretenberg/issues/86)) ([af92b99](https://github.com/noir-lang/acvm-backend-barretenberg/commit/af92b99c7b5f37e9659931af378a851b3658a80b)) -* **ci:** add concurrency group for rust workflow ([#63](https://github.com/noir-lang/acvm-backend-barretenberg/issues/63)) ([5c936bc](https://github.com/noir-lang/acvm-backend-barretenberg/commit/5c936bc63cc3adcf9d43c9c4ce69053566089ad9)) -* Depend upon upstream barretenberg & switch to UltraPlonk ([#84](https://github.com/noir-lang/acvm-backend-barretenberg/issues/84)) ([8437bf7](https://github.com/noir-lang/acvm-backend-barretenberg/commit/8437bf7e08acadf43b55b307545336596a9fe766)) -* Implement pseudo-builder pattern for ConstraintSystem & hide struct fields ([#120](https://github.com/noir-lang/acvm-backend-barretenberg/issues/120)) ([8ed67d6](https://github.com/noir-lang/acvm-backend-barretenberg/commit/8ed67d68c71d655e1a6a5c38fa9ea1c3566f771d)) -* Leverage rustls when using downloader crate ([#46](https://github.com/noir-lang/acvm-backend-barretenberg/issues/46)) ([9de36b6](https://github.com/noir-lang/acvm-backend-barretenberg/commit/9de36b642d125d1fb4facd1bf60db67946be70ae)) -* merge `barretenberg_static_lib` and `barretenberg_wasm` ([#117](https://github.com/noir-lang/acvm-backend-barretenberg/issues/117)) ([ba1d0d6](https://github.com/noir-lang/acvm-backend-barretenberg/commit/ba1d0d61b94de91b15044d97608907c21bfb5299)) -* migrate to ACVM 0.10.3 ([#148](https://github.com/noir-lang/acvm-backend-barretenberg/issues/148)) ([c9fb9e8](https://github.com/noir-lang/acvm-backend-barretenberg/commit/c9fb9e806f1400a2ff7594a0669bec56025220bb)) -* remove all crates other than `acvm-backend-barretenberg` and remove workspace ([#147](https://github.com/noir-lang/acvm-backend-barretenberg/issues/147)) ([8fe7111](https://github.com/noir-lang/acvm-backend-barretenberg/commit/8fe7111ebdcb043764a83436744662e8c3ca5abc)) -* remove dead blake2 code ([#137](https://github.com/noir-lang/acvm-backend-barretenberg/issues/137)) ([14d8a5b](https://github.com/noir-lang/acvm-backend-barretenberg/commit/14d8a5b893eb1cb91d5bde908643b487b41809d6)) -* replace `downloader` dependency with `reqwest` ([#114](https://github.com/noir-lang/acvm-backend-barretenberg/issues/114)) ([dd62231](https://github.com/noir-lang/acvm-backend-barretenberg/commit/dd62231b8bfcee32e1029d31a07895b16159339c)) -* return boolean from `verify_signature` ([e560602](https://github.com/noir-lang/acvm-backend-barretenberg/commit/e560602ebbd547386ca4cab35735ffa92e98ac4b)) -* return boolean rather than `FieldElement` from `check_membership` ([#124](https://github.com/noir-lang/acvm-backend-barretenberg/issues/124)) ([a0a338e](https://github.com/noir-lang/acvm-backend-barretenberg/commit/a0a338e2295635a07f6b9e497c029160a5f323bc)) -* return boolean rather than `FieldElement` from `verify_signature` ([#123](https://github.com/noir-lang/acvm-backend-barretenberg/issues/123)) ([e560602](https://github.com/noir-lang/acvm-backend-barretenberg/commit/e560602ebbd547386ca4cab35735ffa92e98ac4b)) -* store transcript in `.nargo/backends` directory ([#91](https://github.com/noir-lang/acvm-backend-barretenberg/issues/91)) ([c6b5023](https://github.com/noir-lang/acvm-backend-barretenberg/commit/c6b50231da065e7550bfe8bddf8e46f4cd8002d7)) -* update `aztec_backend_wasm` to use new serialization ([#94](https://github.com/noir-lang/acvm-backend-barretenberg/issues/94)) ([28014d8](https://github.com/noir-lang/acvm-backend-barretenberg/commit/28014d803d052a7f459e03dbd7b5b9210449b1d0)) -* update to acvm 0.9.0 ([#106](https://github.com/noir-lang/acvm-backend-barretenberg/issues/106)) ([ff350fb](https://github.com/noir-lang/acvm-backend-barretenberg/commit/ff350fb111043964b8a14fc0df62508c87506423)) -* Update to ACVM v0.11.0 ([#151](https://github.com/noir-lang/acvm-backend-barretenberg/issues/151)) ([9202415](https://github.com/noir-lang/acvm-backend-barretenberg/commit/92024155532e15f25acb2f3ed8d5ca78da0fddd9)) -* update to acvm v0.5.0 ([#60](https://github.com/noir-lang/acvm-backend-barretenberg/issues/60)) ([74b4d8d](https://github.com/noir-lang/acvm-backend-barretenberg/commit/74b4d8d8b118e4477880c04149e5e9d93d388384)) - - -### Bug Fixes - -* Avoid exposing internals of Assignments type ([614c81b](https://github.com/noir-lang/acvm-backend-barretenberg/commit/614c81b0ea5e110bbf5a61a526bb0173f4fe377a)) -* avoid exposing internals of Assignments type ([#119](https://github.com/noir-lang/acvm-backend-barretenberg/issues/119)) ([614c81b](https://github.com/noir-lang/acvm-backend-barretenberg/commit/614c81b0ea5e110bbf5a61a526bb0173f4fe377a)) -* fix serialization of arithmetic expressions ([#145](https://github.com/noir-lang/acvm-backend-barretenberg/issues/145)) ([7f42535](https://github.com/noir-lang/acvm-backend-barretenberg/commit/7f4253570257d9dedcfa8c8fb96b9d097ef06419)) -* Implement random_get for wasm backend ([#102](https://github.com/noir-lang/acvm-backend-barretenberg/issues/102)) ([9c0f06e](https://github.com/noir-lang/acvm-backend-barretenberg/commit/9c0f06ef56f23e2b5794e810f433e36ff2c5d6b5)) -* rename gates to opcodes ([#59](https://github.com/noir-lang/acvm-backend-barretenberg/issues/59)) ([6e05307](https://github.com/noir-lang/acvm-backend-barretenberg/commit/6e053072d8b9c5d93c296f10782251ccb597f902)) -* reorganize and ensure contracts can be compiled in Remix ([#112](https://github.com/noir-lang/acvm-backend-barretenberg/issues/112)) ([7ec5693](https://github.com/noir-lang/acvm-backend-barretenberg/commit/7ec5693f194a79c379ae2952bc17a31ee63a42b9)) -* replace `serialize_circuit` function with `from<&Circuit>` ([#118](https://github.com/noir-lang/acvm-backend-barretenberg/issues/118)) ([94f83a7](https://github.com/noir-lang/acvm-backend-barretenberg/commit/94f83a78e32d91dfb7ae9824923695d9b4c425b0)) -* Replace serialize_circuit function with `from<&Circuit>` ([94f83a7](https://github.com/noir-lang/acvm-backend-barretenberg/commit/94f83a78e32d91dfb7ae9824923695d9b4c425b0)) -* Update bb-sys to resolve bugs in some environments ([#129](https://github.com/noir-lang/acvm-backend-barretenberg/issues/129)) ([e3d4504](https://github.com/noir-lang/acvm-backend-barretenberg/commit/e3d4504f15e1295e637c4da80b1d08c87c267c45)) -* Update dependency containing pk write fix for large general circuits ([#78](https://github.com/noir-lang/acvm-backend-barretenberg/issues/78)) ([2cb523d](https://github.com/noir-lang/acvm-backend-barretenberg/commit/2cb523d2ab95249157b22e198d9dcd6841c3eed8)) -* Update to bb-sys 0.1.1 and update bb in lockfile ([00bb157](https://github.com/noir-lang/acvm-backend-barretenberg/commit/00bb15779dfb64539eeb3f3bb4c4deeba106f2fe)) -* update to bb-sys 0.1.1 and update bb in lockfile ([#111](https://github.com/noir-lang/acvm-backend-barretenberg/issues/111)) ([00bb157](https://github.com/noir-lang/acvm-backend-barretenberg/commit/00bb15779dfb64539eeb3f3bb4c4deeba106f2fe)) -* use `Barretenberg.call` to query circuit size from wasm ([#121](https://github.com/noir-lang/acvm-backend-barretenberg/issues/121)) ([a775af1](https://github.com/noir-lang/acvm-backend-barretenberg/commit/a775af14137cc7bc2e9d8a063fa718a5a9abe6cb)) - - -### Miscellaneous Chores - -* Remove create_proof and verify functions ([#82](https://github.com/noir-lang/acvm-backend-barretenberg/issues/82)) ([ad0c422](https://github.com/noir-lang/acvm-backend-barretenberg/commit/ad0c4228488457bd155ff381186ecf583f18bfac)) -* update to ACVM 0.7.0 ([#90](https://github.com/noir-lang/acvm-backend-barretenberg/issues/90)) ([6c03687](https://github.com/noir-lang/acvm-backend-barretenberg/commit/6c036870a6a8e26612ab8b4f90a162f7540b42e2)) diff --git a/tooling/backend_interface/Cargo.toml b/tooling/backend_interface/Cargo.toml deleted file mode 100644 index f6b5d5d0132..00000000000 --- a/tooling/backend_interface/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -name = "backend-interface" -description = "The definition of the backend CLI interface which Nargo uses for proving/verifying ACIR circuits." -version.workspace = true -authors.workspace = true -edition.workspace = true -rust-version.workspace = true -license.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -acvm.workspace = true -dirs.workspace = true -thiserror.workspace = true -serde_json.workspace = true -bb_abstraction_leaks.workspace = true -tracing.workspace = true - -tempfile.workspace = true - -## bb binary downloading -tar = "~0.4.15" -flate2 = "~1.0.1" -reqwest = { version = "0.11.20", default-features = false, features = [ - "rustls-tls", - "blocking", -] } - -[dev-dependencies] -test-binary = "3.0.1" - -[build-dependencies] -build-target = "0.4.0" -const_format.workspace = true diff --git a/tooling/backend_interface/src/cli/contract.rs b/tooling/backend_interface/src/cli/contract.rs deleted file mode 100644 index e83fc1909b6..00000000000 --- a/tooling/backend_interface/src/cli/contract.rs +++ /dev/null @@ -1,71 +0,0 @@ -use std::path::{Path, PathBuf}; - -use crate::BackendError; - -use super::string_from_stderr; - -/// VerifyCommand will call the barretenberg binary -/// to return a solidity library with the verification key -/// that can be used to verify proofs on-chain. -/// -/// This does not return a Solidity file that is able -/// to verify a proof. See acvm_interop/contract.sol for the -/// remaining logic that is missing. -pub(crate) struct ContractCommand { - pub(crate) crs_path: PathBuf, - pub(crate) vk_path: PathBuf, -} - -impl ContractCommand { - pub(crate) fn run(self, binary_path: &Path) -> Result { - let mut command = std::process::Command::new(binary_path); - - command - .arg("contract") - .arg("-c") - .arg(self.crs_path) - .arg("-k") - .arg(self.vk_path) - .arg("-o") - .arg("-"); - - let output = command.output()?; - - if output.status.success() { - String::from_utf8(output.stdout) - .map_err(|error| BackendError::InvalidUTF8Vector(error.into_bytes())) - } else { - Err(BackendError::CommandFailed(string_from_stderr(&output.stderr))) - } - } -} - -#[test] -fn contract_command() -> Result<(), BackendError> { - use tempfile::tempdir; - - let backend = crate::get_mock_backend()?; - - let temp_directory = tempdir().expect("could not create a temporary directory"); - let temp_directory_path = temp_directory.path(); - let bytecode_path = temp_directory_path.join("acir.gz"); - let vk_path = temp_directory_path.join("vk"); - - let crs_path = backend.backend_directory(); - - std::fs::File::create(&bytecode_path).expect("file should be created"); - - let write_vk_command = super::WriteVkCommand { - bytecode_path, - vk_path_output: vk_path.clone(), - crs_path: crs_path.clone(), - }; - write_vk_command.run(backend.binary_path())?; - - let contract_command = ContractCommand { vk_path, crs_path }; - contract_command.run(backend.binary_path())?; - - drop(temp_directory); - - Ok(()) -} diff --git a/tooling/backend_interface/src/cli/gates.rs b/tooling/backend_interface/src/cli/gates.rs deleted file mode 100644 index aca05f0232a..00000000000 --- a/tooling/backend_interface/src/cli/gates.rs +++ /dev/null @@ -1,64 +0,0 @@ -use std::path::{Path, PathBuf}; - -use crate::BackendError; - -use super::string_from_stderr; - -/// GatesCommand will call the barretenberg binary -/// to return the number of gates needed to create a proof -/// for the given bytecode. -pub(crate) struct GatesCommand { - pub(crate) crs_path: PathBuf, - pub(crate) bytecode_path: PathBuf, -} - -impl GatesCommand { - pub(crate) fn run(self, binary_path: &Path) -> Result { - let output = std::process::Command::new(binary_path) - .arg("gates") - .arg("-c") - .arg(self.crs_path) - .arg("-b") - .arg(self.bytecode_path) - .output()?; - - if !output.status.success() { - return Err(BackendError::CommandFailed(string_from_stderr(&output.stderr))); - } - // Note: barretenberg includes the newline, so that subsequent prints to stdout - // are not on the same line as the gates output. - - const EXPECTED_BYTES: usize = 8; - let gates_bytes: [u8; EXPECTED_BYTES] = - output.stdout.as_slice().try_into().map_err(|_| { - BackendError::UnexpectedNumberOfBytes(EXPECTED_BYTES, output.stdout.clone()) - })?; - - // Convert bytes to u64 in little-endian format - let value = u64::from_le_bytes(gates_bytes); - - Ok(value as u32) - } -} - -#[test] -fn gate_command() -> Result<(), BackendError> { - use tempfile::tempdir; - - let backend = crate::get_mock_backend()?; - - let temp_directory = tempdir().expect("could not create a temporary directory"); - let temp_directory_path = temp_directory.path(); - let bytecode_path = temp_directory_path.join("acir.gz"); - let crs_path = backend.backend_directory(); - - std::fs::File::create(&bytecode_path).expect("file should be created"); - - let gate_command = GatesCommand { crs_path, bytecode_path }; - - let output = gate_command.run(backend.binary_path())?; - // Mock backend always returns zero gates. - assert_eq!(output, 0); - - Ok(()) -} diff --git a/tooling/backend_interface/src/cli/mod.rs b/tooling/backend_interface/src/cli/mod.rs deleted file mode 100644 index df43bd5cc2f..00000000000 --- a/tooling/backend_interface/src/cli/mod.rs +++ /dev/null @@ -1,39 +0,0 @@ -// Reference: https://github.com/AztecProtocol/aztec-packages/blob/master/barretenberg/cpp/src/barretenberg/bb/main.cpp - -mod contract; -mod gates; -mod proof_as_fields; -mod prove; -mod verify; -mod version; -mod vk_as_fields; -mod write_vk; - -pub(crate) use contract::ContractCommand; -pub(crate) use gates::GatesCommand; -pub(crate) use proof_as_fields::ProofAsFieldsCommand; -pub(crate) use prove::ProveCommand; -pub(crate) use verify::VerifyCommand; -pub(crate) use version::VersionCommand; -pub(crate) use vk_as_fields::VkAsFieldsCommand; -pub(crate) use write_vk::WriteVkCommand; - -#[test] -fn no_command_provided_works() -> Result<(), crate::BackendError> { - // This is a simple test to check that the binaries work - - let backend = crate::get_mock_backend()?; - - let output = std::process::Command::new(backend.binary_path()).output()?; - - let stderr = string_from_stderr(&output.stderr); - // Assert help message is printed due to no command being provided. - assert!(stderr.contains("Usage: mock_backend ")); - - Ok(()) -} - -// Converts a stderr byte array to a string (including invalid characters) -fn string_from_stderr(stderr: &[u8]) -> String { - String::from_utf8_lossy(stderr).to_string() -} diff --git a/tooling/backend_interface/src/cli/proof_as_fields.rs b/tooling/backend_interface/src/cli/proof_as_fields.rs deleted file mode 100644 index 7eb1c1ef35c..00000000000 --- a/tooling/backend_interface/src/cli/proof_as_fields.rs +++ /dev/null @@ -1,38 +0,0 @@ -use std::path::{Path, PathBuf}; - -use acvm::FieldElement; - -use crate::BackendError; - -use super::string_from_stderr; - -/// `ProofAsFieldsCommand` will call the barretenberg binary -/// to split a proof into a representation as [`FieldElement`]s. -pub(crate) struct ProofAsFieldsCommand { - pub(crate) proof_path: PathBuf, - pub(crate) vk_path: PathBuf, -} - -impl ProofAsFieldsCommand { - pub(crate) fn run(self, binary_path: &Path) -> Result, BackendError> { - let mut command = std::process::Command::new(binary_path); - - command - .arg("proof_as_fields") - .arg("-p") - .arg(self.proof_path) - .arg("-k") - .arg(self.vk_path) - .arg("-o") - .arg("-"); - - let output = command.output()?; - if output.status.success() { - let string_output = String::from_utf8(output.stdout).unwrap(); - serde_json::from_str(&string_output) - .map_err(|err| BackendError::CommandFailed(err.to_string())) - } else { - Err(BackendError::CommandFailed(string_from_stderr(&output.stderr))) - } - } -} diff --git a/tooling/backend_interface/src/cli/prove.rs b/tooling/backend_interface/src/cli/prove.rs deleted file mode 100644 index c63d8afab54..00000000000 --- a/tooling/backend_interface/src/cli/prove.rs +++ /dev/null @@ -1,66 +0,0 @@ -use std::path::{Path, PathBuf}; - -use crate::BackendError; - -use super::string_from_stderr; - -/// ProveCommand will call the barretenberg binary -/// to create a proof, given the witness and the bytecode. -/// -/// Note:Internally barretenberg will create and discard the -/// proving key, so this is not returned. -/// -/// The proof will be written to the specified output file. -pub(crate) struct ProveCommand { - pub(crate) crs_path: PathBuf, - pub(crate) bytecode_path: PathBuf, - pub(crate) witness_path: PathBuf, -} - -impl ProveCommand { - pub(crate) fn run(self, binary_path: &Path) -> Result, BackendError> { - let mut command = std::process::Command::new(binary_path); - - command - .arg("prove") - .arg("-c") - .arg(self.crs_path) - .arg("-b") - .arg(self.bytecode_path) - .arg("-w") - .arg(self.witness_path) - .arg("-o") - .arg("-"); - - let output = command.output()?; - if output.status.success() { - Ok(output.stdout) - } else { - Err(BackendError::CommandFailed(string_from_stderr(&output.stderr))) - } - } -} - -#[test] -fn prove_command() -> Result<(), BackendError> { - use tempfile::tempdir; - - let backend = crate::get_mock_backend()?; - - let temp_directory = tempdir().expect("could not create a temporary directory"); - let temp_directory_path = temp_directory.path(); - let bytecode_path = temp_directory_path.join("acir.gz"); - let witness_path = temp_directory_path.join("witness.tr"); - - std::fs::File::create(&bytecode_path).expect("file should be created"); - std::fs::File::create(&witness_path).expect("file should be created"); - - let crs_path = backend.backend_directory(); - let prove_command = ProveCommand { crs_path, bytecode_path, witness_path }; - - let proof = prove_command.run(backend.binary_path())?; - assert_eq!(proof, "proof".as_bytes()); - drop(temp_directory); - - Ok(()) -} diff --git a/tooling/backend_interface/src/cli/verify.rs b/tooling/backend_interface/src/cli/verify.rs deleted file mode 100644 index 1a4ba50b7de..00000000000 --- a/tooling/backend_interface/src/cli/verify.rs +++ /dev/null @@ -1,74 +0,0 @@ -use std::path::{Path, PathBuf}; - -use crate::BackendError; - -/// VerifyCommand will call the barretenberg binary -/// to verify a proof -pub(crate) struct VerifyCommand { - pub(crate) crs_path: PathBuf, - pub(crate) proof_path: PathBuf, - pub(crate) vk_path: PathBuf, -} - -impl VerifyCommand { - pub(crate) fn run(self, binary_path: &Path) -> Result { - let mut command = std::process::Command::new(binary_path); - - command - .arg("verify") - .arg("-c") - .arg(self.crs_path) - .arg("-p") - .arg(self.proof_path) - .arg("-k") - .arg(self.vk_path); - - let output = command.output()?; - - // We currently do not distinguish between an invalid proof and an error inside the backend. - Ok(output.status.success()) - } -} - -#[test] -fn verify_command() -> Result<(), BackendError> { - use tempfile::tempdir; - - use super::{ProveCommand, WriteVkCommand}; - use crate::proof_system::write_to_file; - - let backend = crate::get_mock_backend()?; - - let temp_directory = tempdir().expect("could not create a temporary directory"); - let temp_directory_path = temp_directory.path(); - let bytecode_path = temp_directory_path.join("acir.gz"); - let witness_path = temp_directory_path.join("witness.tr"); - let proof_path = temp_directory_path.join("1_mul.proof"); - let vk_path_output = temp_directory_path.join("vk"); - - let crs_path = backend.backend_directory(); - - std::fs::File::create(&bytecode_path).expect("file should be created"); - std::fs::File::create(&witness_path).expect("file should be created"); - - let write_vk_command = WriteVkCommand { - bytecode_path: bytecode_path.clone(), - crs_path: crs_path.clone(), - vk_path_output: vk_path_output.clone(), - }; - - write_vk_command.run(backend.binary_path())?; - - let prove_command = ProveCommand { crs_path: crs_path.clone(), bytecode_path, witness_path }; - let proof = prove_command.run(backend.binary_path())?; - - write_to_file(&proof, &proof_path); - - let verify_command = VerifyCommand { crs_path, proof_path, vk_path: vk_path_output }; - - let verified = verify_command.run(backend.binary_path())?; - assert!(verified); - - drop(temp_directory); - Ok(()) -} diff --git a/tooling/backend_interface/src/cli/version.rs b/tooling/backend_interface/src/cli/version.rs deleted file mode 100644 index 83ab72a870e..00000000000 --- a/tooling/backend_interface/src/cli/version.rs +++ /dev/null @@ -1,29 +0,0 @@ -use std::path::Path; - -use crate::BackendError; - -use super::string_from_stderr; - -/// VersionCommand will call the backend binary -/// to query installed version. -pub(crate) struct VersionCommand; - -impl VersionCommand { - pub(crate) fn run(self, binary_path: &Path) -> Result { - let mut command = std::process::Command::new(binary_path); - - command.arg("--version"); - - let output = command.output()?; - if output.status.success() { - match String::from_utf8(output.stdout) { - Ok(result) => Ok(result), - Err(_) => Err(BackendError::CommandFailed( - "Unexpected output from --version check.".to_owned(), - )), - } - } else { - Err(BackendError::CommandFailed(string_from_stderr(&output.stderr))) - } - } -} diff --git a/tooling/backend_interface/src/cli/vk_as_fields.rs b/tooling/backend_interface/src/cli/vk_as_fields.rs deleted file mode 100644 index 1b0212241c4..00000000000 --- a/tooling/backend_interface/src/cli/vk_as_fields.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::path::{Path, PathBuf}; - -use acvm::FieldElement; - -use crate::BackendError; - -use super::string_from_stderr; - -/// VkAsFieldsCommand will call the barretenberg binary -/// to split a verification key into a representation as [`FieldElement`]s. -/// -/// The hash of the verification key will also be returned. -pub(crate) struct VkAsFieldsCommand { - pub(crate) vk_path: PathBuf, -} - -impl VkAsFieldsCommand { - pub(crate) fn run( - self, - binary_path: &Path, - ) -> Result<(FieldElement, Vec), BackendError> { - let mut command = std::process::Command::new(binary_path); - - command.arg("vk_as_fields").arg("-k").arg(self.vk_path).arg("-o").arg("-"); - - let output = command.output()?; - if output.status.success() { - let string_output = String::from_utf8(output.stdout).unwrap(); - let mut fields: Vec = serde_json::from_str(&string_output) - .map_err(|err| BackendError::CommandFailed(err.to_string()))?; - - // The first element of this vector is the hash of the verification key, we want to split that off. - let hash = fields.remove(0); - Ok((hash, fields)) - } else { - Err(BackendError::CommandFailed(string_from_stderr(&output.stderr))) - } - } -} diff --git a/tooling/backend_interface/src/cli/write_vk.rs b/tooling/backend_interface/src/cli/write_vk.rs deleted file mode 100644 index da9fc04cbef..00000000000 --- a/tooling/backend_interface/src/cli/write_vk.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::path::{Path, PathBuf}; - -use super::string_from_stderr; -use crate::BackendError; - -/// WriteCommand will call the barretenberg binary -/// to write a verification key to a file -pub(crate) struct WriteVkCommand { - pub(crate) crs_path: PathBuf, - pub(crate) bytecode_path: PathBuf, - pub(crate) vk_path_output: PathBuf, -} - -impl WriteVkCommand { - #[tracing::instrument(level = "trace", name = "vk_generation", skip_all)] - pub(crate) fn run(self, binary_path: &Path) -> Result<(), BackendError> { - let mut command = std::process::Command::new(binary_path); - - command - .arg("write_vk") - .arg("-c") - .arg(self.crs_path) - .arg("-b") - .arg(self.bytecode_path) - .arg("-o") - .arg(self.vk_path_output); - - let output = command.output()?; - if output.status.success() { - Ok(()) - } else { - Err(BackendError::CommandFailed(string_from_stderr(&output.stderr))) - } - } -} - -#[test] -fn write_vk_command() -> Result<(), BackendError> { - use tempfile::tempdir; - - let backend = crate::get_mock_backend()?; - - let temp_directory = tempdir().expect("could not create a temporary directory"); - let temp_directory_path = temp_directory.path(); - let bytecode_path = temp_directory_path.join("acir.gz"); - let vk_path_output = temp_directory.path().join("vk"); - - let crs_path = backend.backend_directory(); - - std::fs::File::create(&bytecode_path).expect("file should be created"); - - let write_vk_command = WriteVkCommand { bytecode_path, crs_path, vk_path_output }; - - write_vk_command.run(backend.binary_path())?; - drop(temp_directory); - - Ok(()) -} diff --git a/tooling/backend_interface/src/download.rs b/tooling/backend_interface/src/download.rs deleted file mode 100644 index 60ecb14e642..00000000000 --- a/tooling/backend_interface/src/download.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::{ - io::{Cursor, ErrorKind}, - path::Path, -}; - -/// Downloads a zipped archive and unpacks the backend binary to `destination_path`. -/// -/// # Backend Requirements -/// -/// In order for a backend to be compatible with this function: -/// - `backend_url` must serve a gzipped tarball. -/// - The tarball must only contain the backend's binary. -/// - The binary file must be located at the archive root. -pub fn download_backend(backend_url: &str, destination_path: &Path) -> std::io::Result<()> { - use flate2::read::GzDecoder; - use tar::Archive; - use tempfile::tempdir; - - // Download sources - let compressed_file: Cursor> = download_binary_from_url(backend_url).map_err(|_| { - std::io::Error::new( - ErrorKind::Other, - format!("Could not download backend from install url: {backend_url}"), - ) - })?; - - // Unpack the tarball - let gz_decoder = GzDecoder::new(compressed_file); - let mut archive = Archive::new(gz_decoder); - - let temp_directory = tempdir()?; - archive.unpack(&temp_directory)?; - - // Assume that the archive contains a single file which is the backend binary. - let mut archive_files = std::fs::read_dir(&temp_directory)?; - let temp_binary_path = archive_files.next().unwrap()?.path(); - - // Create directory to place binary in. - std::fs::create_dir_all(destination_path.parent().unwrap())?; - - // Rename the binary to the desired name - std::fs::copy(temp_binary_path, destination_path)?; - - drop(temp_directory); - - Ok(()) -} - -/// Try to download the specified URL into a buffer which is returned. -fn download_binary_from_url(url: &str) -> Result>, reqwest::Error> { - let response = reqwest::blocking::get(url)?; - - let bytes = response.bytes()?; - - // TODO: Check SHA of downloaded binary - - Ok(Cursor::new(bytes.to_vec())) -} diff --git a/tooling/backend_interface/src/lib.rs b/tooling/backend_interface/src/lib.rs deleted file mode 100644 index eab98852555..00000000000 --- a/tooling/backend_interface/src/lib.rs +++ /dev/null @@ -1,150 +0,0 @@ -#![warn(unused_crate_dependencies, unused_extern_crates)] -#![warn(unreachable_pub)] - -use std::path::PathBuf; - -mod cli; -mod download; -mod proof_system; -mod smart_contract; - -pub use bb_abstraction_leaks::ACVM_BACKEND_BARRETENBERG; -use bb_abstraction_leaks::BB_VERSION; -use cli::VersionCommand; -pub use download::download_backend; -use tracing::warn; - -const BACKENDS_DIR: &str = ".nargo/backends"; - -pub fn backends_directory() -> PathBuf { - let home_directory = dirs::home_dir().unwrap(); - home_directory.join(BACKENDS_DIR) -} - -#[cfg(test)] -test_binary::build_test_binary_once!(mock_backend, "test-binaries"); - -#[cfg(test)] -fn get_mock_backend() -> Result { - std::env::set_var("NARGO_BACKEND_PATH", path_to_mock_backend()); - - let mock_backend = Backend::new("mock_backend".to_string()); - mock_backend.assert_binary_exists()?; - - Ok(mock_backend) -} - -#[derive(Debug, thiserror::Error)] -pub enum BackendError { - #[error(transparent)] - IoError(#[from] std::io::Error), - - #[error("Backend binary does not exist")] - MissingBinary, - - #[error("The backend responded with a malformed UTF8 byte vector: {0:?}")] - InvalidUTF8Vector(Vec), - - #[error( - "The backend responded with a unexpected number of bytes. Expected: {0} but got {} ({1:?})", .1.len() - )] - UnexpectedNumberOfBytes(usize, Vec), - - #[error("The backend encountered an error: {0:?}")] - CommandFailed(String), -} - -#[derive(Debug)] -pub struct Backend { - name: String, - binary_path: PathBuf, -} - -impl Backend { - pub fn new(name: String) -> Backend { - let binary_path = if let Some(binary_path) = std::env::var_os("NARGO_BACKEND_PATH") { - PathBuf::from(binary_path) - } else { - const BINARY_NAME: &str = "backend_binary"; - - backends_directory().join(&name).join(BINARY_NAME) - }; - Backend { name, binary_path } - } - - pub fn name(&self) -> &str { - &self.name - } - - fn binary_path(&self) -> &PathBuf { - &self.binary_path - } - - fn assert_binary_exists(&self) -> Result<&PathBuf, BackendError> { - let binary_path = self.binary_path(); - if binary_path.is_file() { - Ok(binary_path) - } else { - if self.name == ACVM_BACKEND_BARRETENBERG { - // If we're trying to use barretenberg, automatically go and install it. - let bb_url = std::env::var("BB_BINARY_URL") - .unwrap_or_else(|_| bb_abstraction_leaks::BB_DOWNLOAD_URL.to_owned()); - download_backend(&bb_url, binary_path)?; - return Ok(binary_path); - } - Err(BackendError::MissingBinary) - } - } - - fn backend_directory(&self) -> PathBuf { - self.binary_path() - .parent() - .expect("backend binary should have a parent directory") - .to_path_buf() - } - - fn crs_directory(&self) -> PathBuf { - self.backend_directory().join("crs") - } - - fn assert_correct_version(&self) -> Result<&PathBuf, BackendError> { - let binary_path = self.binary_path(); - if binary_path.to_string_lossy().contains(ACVM_BACKEND_BARRETENBERG) { - match VersionCommand.run(binary_path) { - // If version matches then do nothing. - Ok(version_string) if version_string == BB_VERSION => (), - - // If version doesn't match then download the correct version. - Ok(version_string) => { - warn!("`{ACVM_BACKEND_BARRETENBERG}` version `{version_string}` is different from expected `{BB_VERSION}`. Downloading expected version..."); - let bb_url = std::env::var("BB_BINARY_URL") - .unwrap_or_else(|_| bb_abstraction_leaks::BB_DOWNLOAD_URL.to_owned()); - download_backend(&bb_url, binary_path)?; - } - - // If `bb` fails to report its version, then attempt to fix it by re-downloading the binary. - Err(_) => { - warn!("Could not determine version of `{ACVM_BACKEND_BARRETENBERG}`. Downloading expected version..."); - let bb_url = std::env::var("BB_BINARY_URL") - .unwrap_or_else(|_| bb_abstraction_leaks::BB_DOWNLOAD_URL.to_owned()); - download_backend(&bb_url, binary_path)?; - } - } - } - Ok(binary_path) - } -} - -#[cfg(test)] -mod backend { - use crate::{Backend, BackendError}; - - #[test] - fn raises_error_on_missing_binary() { - let bad_backend = Backend::new("i_don't_exist".to_string()); - - let binary_path = bad_backend.assert_binary_exists(); - - assert!(matches!(binary_path, Err(BackendError::MissingBinary))); - } -} diff --git a/tooling/backend_interface/src/proof_system.rs b/tooling/backend_interface/src/proof_system.rs deleted file mode 100644 index 20a6dcf70f1..00000000000 --- a/tooling/backend_interface/src/proof_system.rs +++ /dev/null @@ -1,169 +0,0 @@ -use std::fs::File; -use std::io::Write; -use std::path::Path; - -use acvm::acir::{ - circuit::Program, - native_types::{WitnessMap, WitnessStack}, -}; -use acvm::FieldElement; -use tempfile::tempdir; -use tracing::warn; - -use crate::cli::{ - GatesCommand, ProofAsFieldsCommand, ProveCommand, VerifyCommand, VkAsFieldsCommand, - WriteVkCommand, -}; -use crate::{Backend, BackendError}; - -impl Backend { - pub fn get_exact_circuit_size(&self, program: &Program) -> Result { - let binary_path = self.assert_binary_exists()?; - self.assert_correct_version()?; - - let temp_directory = tempdir().expect("could not create a temporary directory"); - let temp_directory = temp_directory.path().to_path_buf(); - - // Create a temporary file for the circuit - let circuit_path = temp_directory.join("circuit").with_extension("bytecode"); - let serialized_program = Program::serialize_program(program); - write_to_file(&serialized_program, &circuit_path); - - GatesCommand { crs_path: self.crs_directory(), bytecode_path: circuit_path } - .run(binary_path) - } - - #[tracing::instrument(level = "trace", skip_all)] - pub fn prove( - &self, - program: &Program, - witness_stack: WitnessStack, - ) -> Result, BackendError> { - let binary_path = self.assert_binary_exists()?; - self.assert_correct_version()?; - - let temp_directory = tempdir().expect("could not create a temporary directory"); - let temp_directory = temp_directory.path().to_path_buf(); - - // Create a temporary file for the witness - let serialized_witnesses: Vec = - witness_stack.try_into().expect("could not serialize witness map"); - let witness_path = temp_directory.join("witness").with_extension("tr"); - write_to_file(&serialized_witnesses, &witness_path); - - // Create a temporary file for the circuit - // - let bytecode_path = temp_directory.join("program").with_extension("bytecode"); - let serialized_program = Program::serialize_program(program); - write_to_file(&serialized_program, &bytecode_path); - - // Create proof and store it in the specified path - let proof_with_public_inputs = - ProveCommand { crs_path: self.crs_directory(), bytecode_path, witness_path } - .run(binary_path)?; - - let proof = bb_abstraction_leaks::remove_public_inputs( - // TODO(https://github.com/noir-lang/noir/issues/4428) - program.functions[0].public_inputs().0.len(), - &proof_with_public_inputs, - ); - Ok(proof) - } - - #[tracing::instrument(level = "trace", skip_all)] - pub fn verify( - &self, - proof: &[u8], - public_inputs: WitnessMap, - program: &Program, - ) -> Result { - let binary_path = self.assert_binary_exists()?; - self.assert_correct_version()?; - - let temp_directory = tempdir().expect("could not create a temporary directory"); - let temp_directory = temp_directory.path().to_path_buf(); - - // Create a temporary file for the proof - let proof_with_public_inputs = - bb_abstraction_leaks::prepend_public_inputs(proof.to_vec(), public_inputs); - let proof_path = temp_directory.join("proof").with_extension("proof"); - write_to_file(&proof_with_public_inputs, &proof_path); - - // Create a temporary file for the circuit - let bytecode_path = temp_directory.join("program").with_extension("bytecode"); - let serialized_program = Program::serialize_program(program); - write_to_file(&serialized_program, &bytecode_path); - - // Create the verification key and write it to the specified path - let vk_path = temp_directory.join("vk"); - - WriteVkCommand { - crs_path: self.crs_directory(), - bytecode_path, - vk_path_output: vk_path.clone(), - } - .run(binary_path)?; - - // Verify the proof - VerifyCommand { crs_path: self.crs_directory(), proof_path, vk_path }.run(binary_path) - } - - pub fn get_intermediate_proof_artifacts( - &self, - program: &Program, - proof: &[u8], - public_inputs: WitnessMap, - ) -> Result<(Vec, FieldElement, Vec), BackendError> { - let binary_path = self.assert_binary_exists()?; - self.assert_correct_version()?; - - let temp_directory = tempdir().expect("could not create a temporary directory"); - let temp_directory = temp_directory.path().to_path_buf(); - - // Create a temporary file for the circuit - // - let bytecode_path = temp_directory.join("program").with_extension("bytecode"); - let serialized_program = Program::serialize_program(program); - write_to_file(&serialized_program, &bytecode_path); - - // Create the verification key and write it to the specified path - let vk_path = temp_directory.join("vk"); - - WriteVkCommand { - crs_path: self.crs_directory(), - bytecode_path, - vk_path_output: vk_path.clone(), - } - .run(binary_path)?; - - // Create a temporary file for the proof - - let proof_with_public_inputs = - bb_abstraction_leaks::prepend_public_inputs(proof.to_vec(), public_inputs); - let proof_path = temp_directory.join("proof").with_extension("proof"); - write_to_file(&proof_with_public_inputs, &proof_path); - - // Now ready to generate intermediate artifacts. - - let proof_as_fields = - ProofAsFieldsCommand { proof_path, vk_path: vk_path.clone() }.run(binary_path)?; - - let (vk_hash, vk_as_fields) = VkAsFieldsCommand { vk_path }.run(binary_path)?; - - Ok((proof_as_fields, vk_hash, vk_as_fields)) - } -} - -pub(super) fn write_to_file(bytes: &[u8], path: &Path) -> String { - let display = path.display(); - - let mut file = match File::create(path) { - Err(why) => panic!("couldn't create {display}: {why}"), - Ok(file) => file, - }; - - match file.write_all(bytes) { - Err(why) => panic!("couldn't write to {display}: {why}"), - Ok(_) => display.to_string(), - } -} diff --git a/tooling/backend_interface/src/smart_contract.rs b/tooling/backend_interface/src/smart_contract.rs deleted file mode 100644 index 153ab52c83f..00000000000 --- a/tooling/backend_interface/src/smart_contract.rs +++ /dev/null @@ -1,70 +0,0 @@ -use super::proof_system::write_to_file; -use crate::{ - cli::{ContractCommand, WriteVkCommand}, - Backend, BackendError, -}; -use acvm::acir::circuit::Program; -use tempfile::tempdir; - -impl Backend { - pub fn eth_contract(&self, program: &Program) -> Result { - let binary_path = self.assert_binary_exists()?; - self.assert_correct_version()?; - - let temp_directory = tempdir().expect("could not create a temporary directory"); - let temp_directory_path = temp_directory.path().to_path_buf(); - - // Create a temporary file for the circuit - let bytecode_path = temp_directory_path.join("program").with_extension("bytecode"); - let serialized_program = Program::serialize_program(program); - write_to_file(&serialized_program, &bytecode_path); - - // Create the verification key and write it to the specified path - let vk_path = temp_directory_path.join("vk"); - - WriteVkCommand { - crs_path: self.crs_directory(), - bytecode_path, - vk_path_output: vk_path.clone(), - } - .run(binary_path)?; - - ContractCommand { crs_path: self.crs_directory(), vk_path }.run(binary_path) - } -} - -#[cfg(test)] -mod tests { - use std::collections::BTreeSet; - - use acvm::acir::{ - circuit::{Circuit, ExpressionWidth, Opcode, Program, PublicInputs}, - native_types::{Expression, Witness}, - }; - - use crate::{get_mock_backend, BackendError}; - - #[test] - fn test_smart_contract() -> Result<(), BackendError> { - let expression = &(Witness(1) + Witness(2)) - &Expression::from(Witness(3)); - let constraint = Opcode::AssertZero(expression); - - let circuit = Circuit { - current_witness_index: 4, - expression_width: ExpressionWidth::Bounded { width: 4 }, - opcodes: vec![constraint], - private_parameters: BTreeSet::from([Witness(1), Witness(2)]), - public_parameters: PublicInputs::default(), - return_values: PublicInputs::default(), - assert_messages: Default::default(), - recursive: false, - }; - let program = Program { functions: vec![circuit], unconstrained_functions: Vec::new() }; - - let contract = get_mock_backend()?.eth_contract(&program)?; - - assert!(contract.contains("contract VerifierContract")); - - Ok(()) - } -} diff --git a/tooling/backend_interface/test-binaries/mock_backend/Cargo.lock b/tooling/backend_interface/test-binaries/mock_backend/Cargo.lock deleted file mode 100644 index 3c14a936907..00000000000 --- a/tooling/backend_interface/test-binaries/mock_backend/Cargo.lock +++ /dev/null @@ -1,223 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "anstream" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" - -[[package]] -name = "anstyle-parse" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" -dependencies = [ - "anstyle", - "windows-sys", -] - -[[package]] -name = "clap" -version = "4.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" - -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "mock_backend" -version = "0.1.0" -dependencies = [ - "clap", -] - -[[package]] -name = "proc-macro2" -version = "1.0.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "syn" -version = "2.0.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" diff --git a/tooling/backend_interface/test-binaries/mock_backend/Cargo.toml b/tooling/backend_interface/test-binaries/mock_backend/Cargo.toml deleted file mode 100644 index f527b03a7b9..00000000000 --- a/tooling/backend_interface/test-binaries/mock_backend/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[workspace] - -[package] -name = "mock_backend" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -clap = { version = "4.3.19", features = ["derive"] } diff --git a/tooling/backend_interface/test-binaries/mock_backend/src/contract_cmd.rs b/tooling/backend_interface/test-binaries/mock_backend/src/contract_cmd.rs deleted file mode 100644 index 7ee41121d61..00000000000 --- a/tooling/backend_interface/test-binaries/mock_backend/src/contract_cmd.rs +++ /dev/null @@ -1,21 +0,0 @@ -use clap::Args; -use std::io::Write; -use std::path::PathBuf; - -#[derive(Debug, Clone, Args)] -pub(crate) struct ContractCommand { - #[clap(short = 'c')] - pub(crate) crs_path: Option, - - #[clap(short = 'k')] - pub(crate) vk_path: PathBuf, - - #[clap(short = 'o')] - pub(crate) contract_path: PathBuf, -} - -pub(crate) fn run(args: ContractCommand) { - assert!(args.vk_path.is_file(), "Could not find vk file at provided path"); - - std::io::stdout().write_all(b"contract VerifierContract {}").unwrap(); -} diff --git a/tooling/backend_interface/test-binaries/mock_backend/src/gates_cmd.rs b/tooling/backend_interface/test-binaries/mock_backend/src/gates_cmd.rs deleted file mode 100644 index 3cc397d3292..00000000000 --- a/tooling/backend_interface/test-binaries/mock_backend/src/gates_cmd.rs +++ /dev/null @@ -1,18 +0,0 @@ -use clap::Args; -use std::io::Write; -use std::path::PathBuf; - -#[derive(Debug, Clone, Args)] -pub(crate) struct GatesCommand { - #[clap(short = 'c')] - pub(crate) crs_path: Option, - - #[clap(short = 'b')] - pub(crate) bytecode_path: PathBuf, -} - -pub(crate) fn run(args: GatesCommand) { - assert!(args.bytecode_path.is_file(), "Could not find bytecode file at provided path"); - - std::io::stdout().write_all(&0u64.to_le_bytes()).unwrap(); -} diff --git a/tooling/backend_interface/test-binaries/mock_backend/src/main.rs b/tooling/backend_interface/test-binaries/mock_backend/src/main.rs deleted file mode 100644 index 74ea82d28f8..00000000000 --- a/tooling/backend_interface/test-binaries/mock_backend/src/main.rs +++ /dev/null @@ -1,41 +0,0 @@ -#![forbid(unsafe_code)] -#![warn(unreachable_pub)] -#![warn(clippy::semicolon_if_nothing_returned)] -#![cfg_attr(not(test), warn(unused_crate_dependencies, unused_extern_crates))] - -use clap::{Parser, Subcommand}; - -mod contract_cmd; -mod gates_cmd; -mod prove_cmd; -mod verify_cmd; -mod write_vk_cmd; - -#[derive(Parser, Debug)] -#[command(name = "mock_backend")] -struct BackendCli { - #[command(subcommand)] - command: BackendCommand, -} - -#[derive(Subcommand, Clone, Debug)] -enum BackendCommand { - Contract(contract_cmd::ContractCommand), - Gates(gates_cmd::GatesCommand), - Prove(prove_cmd::ProveCommand), - Verify(verify_cmd::VerifyCommand), - #[command(name = "write_vk")] - WriteVk(write_vk_cmd::WriteVkCommand), -} - -fn main() { - let BackendCli { command } = BackendCli::parse(); - - match command { - BackendCommand::Contract(args) => contract_cmd::run(args), - BackendCommand::Gates(args) => gates_cmd::run(args), - BackendCommand::Prove(args) => prove_cmd::run(args), - BackendCommand::Verify(args) => verify_cmd::run(args), - BackendCommand::WriteVk(args) => write_vk_cmd::run(args), - }; -} diff --git a/tooling/backend_interface/test-binaries/mock_backend/src/prove_cmd.rs b/tooling/backend_interface/test-binaries/mock_backend/src/prove_cmd.rs deleted file mode 100644 index 3967778d4e8..00000000000 --- a/tooling/backend_interface/test-binaries/mock_backend/src/prove_cmd.rs +++ /dev/null @@ -1,25 +0,0 @@ -use clap::Args; -use std::io::Write; -use std::path::PathBuf; - -#[derive(Debug, Clone, Args)] -pub(crate) struct ProveCommand { - #[clap(short = 'c')] - pub(crate) crs_path: Option, - - #[clap(short = 'b')] - pub(crate) bytecode_path: PathBuf, - - #[clap(short = 'w')] - pub(crate) witness_path: PathBuf, - - #[clap(short = 'o')] - pub(crate) proof_path: PathBuf, -} - -pub(crate) fn run(args: ProveCommand) { - assert!(args.bytecode_path.is_file(), "Could not find bytecode file at provided path"); - assert!(args.witness_path.is_file(), "Could not find witness file at provided path"); - - std::io::stdout().write_all(b"proof").unwrap(); -} diff --git a/tooling/backend_interface/test-binaries/mock_backend/src/verify_cmd.rs b/tooling/backend_interface/test-binaries/mock_backend/src/verify_cmd.rs deleted file mode 100644 index 1a715eea880..00000000000 --- a/tooling/backend_interface/test-binaries/mock_backend/src/verify_cmd.rs +++ /dev/null @@ -1,24 +0,0 @@ -use clap::Args; -use std::path::PathBuf; - -#[derive(Debug, Clone, Args)] -pub(crate) struct VerifyCommand { - #[clap(short = 'c')] - pub(crate) crs_path: Option, - - #[clap(short = 'p')] - pub(crate) proof_path: PathBuf, - - #[clap(short = 'k')] - pub(crate) vk_path: PathBuf, - - #[clap(short = 'r')] - pub(crate) is_recursive: bool, -} - -pub(crate) fn run(args: VerifyCommand) { - assert!(args.vk_path.is_file(), "Could not find verification key file at provided path"); - assert!(args.proof_path.is_file(), "Could not find proof file at provided path"); - - std::fs::write(args.proof_path, "proof").unwrap(); -} diff --git a/tooling/backend_interface/test-binaries/mock_backend/src/write_vk_cmd.rs b/tooling/backend_interface/test-binaries/mock_backend/src/write_vk_cmd.rs deleted file mode 100644 index fcee224e85b..00000000000 --- a/tooling/backend_interface/test-binaries/mock_backend/src/write_vk_cmd.rs +++ /dev/null @@ -1,20 +0,0 @@ -use clap::Args; -use std::path::PathBuf; - -#[derive(Debug, Clone, Args)] -pub(crate) struct WriteVkCommand { - #[clap(short = 'c')] - pub(crate) crs_path: Option, - - #[clap(short = 'b')] - pub(crate) bytecode_path: PathBuf, - - #[clap(short = 'o')] - pub(crate) vk_path: PathBuf, -} - -pub(crate) fn run(args: WriteVkCommand) { - assert!(args.bytecode_path.is_file(), "Could not find bytecode file at provided path"); - - std::fs::write(args.vk_path, "vk").unwrap(); -} diff --git a/tooling/bb_abstraction_leaks/Cargo.toml b/tooling/bb_abstraction_leaks/Cargo.toml deleted file mode 100644 index 972c78831a7..00000000000 --- a/tooling/bb_abstraction_leaks/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "bb_abstraction_leaks" -description = "A crate which encapsulates knowledge about Barretenberg which is currently leaking into Nargo" -version = "0.11.0" -authors.workspace = true -edition.workspace = true -rust-version.workspace = true -license.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -acvm.workspace = true - -[build-dependencies] -build-target = "0.4.0" -const_format.workspace = true diff --git a/tooling/bb_abstraction_leaks/build.rs b/tooling/bb_abstraction_leaks/build.rs deleted file mode 100644 index 45da7f9d00c..00000000000 --- a/tooling/bb_abstraction_leaks/build.rs +++ /dev/null @@ -1,58 +0,0 @@ -use build_target::{Arch, Os}; -use const_format::formatcp; - -// Useful for printing debugging messages during the build -// macro_rules! p { -// ($($tokens: tt)*) => { -// println!("cargo:warning={}", format!($($tokens)*)) -// } -// } - -const USERNAME: &str = "AztecProtocol"; -const REPO: &str = "aztec-packages"; -const VERSION: &str = "0.38.0"; -const TAG: &str = formatcp!("aztec-packages-v{}", VERSION); - -const API_URL: &str = - formatcp!("https://github.com/{}/{}/releases/download/{}", USERNAME, REPO, TAG); - -fn main() -> Result<(), String> { - // We need to inject which OS we're building for so that we can download the correct barretenberg binary. - let os = match build_target::target_os().unwrap() { - os @ (Os::Linux | Os::MacOs) => os, - Os::Windows => todo!("Windows is not currently supported"), - os_name => panic!("Unsupported OS {os_name}"), - }; - - let arch = match build_target::target_arch().unwrap() { - arch @ (Arch::X86_64 | Arch::AARCH64) => arch, - arch_name => panic!("Unsupported Architecture {arch_name}"), - }; - - // Arm builds of linux are not supported - // We do not panic because we allow users to run nargo without a backend. - if let (Os::Linux, Arch::AARCH64) = (&os, &arch) { - println!( - "cargo:warning=ARM64 builds of linux are not supported for the barretenberg binary" - ); - }; - - println!("cargo:rustc-env=BB_BINARY_URL={}", get_bb_download_url(arch, os)); - println!("cargo:rustc-env=BB_VERSION={}", VERSION); - - Ok(()) -} - -fn get_bb_download_url(target_arch: Arch, target_os: Os) -> String { - let archive_name = match target_os { - Os::Linux => "barretenberg-x86_64-linux-gnu.tar.gz", - Os::MacOs => match target_arch { - Arch::AARCH64 => "barretenberg-aarch64-apple-darwin.tar.gz", - Arch::X86_64 => "barretenberg-x86_64-apple-darwin.tar.gz", - arch => panic!("unsupported arch {arch}"), - }, - os => panic!("Unsupported OS {os}"), - }; - - format!("{API_URL}/{archive_name}") -} diff --git a/tooling/bb_abstraction_leaks/src/lib.rs b/tooling/bb_abstraction_leaks/src/lib.rs deleted file mode 100644 index 56a4f58cd21..00000000000 --- a/tooling/bb_abstraction_leaks/src/lib.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![warn(unused_crate_dependencies, unused_extern_crates)] -#![warn(unreachable_pub)] - -use acvm::{acir::native_types::WitnessMap, FieldElement}; - -pub const ACVM_BACKEND_BARRETENBERG: &str = "acvm-backend-barretenberg"; -pub const BB_DOWNLOAD_URL: &str = env!("BB_BINARY_URL"); -pub const BB_VERSION: &str = env!("BB_VERSION"); - -/// Removes the public inputs which are prepended to a proof by Barretenberg. -pub fn remove_public_inputs(num_pub_inputs: usize, proof: &[u8]) -> Vec { - // Barretenberg prepends the public inputs onto the proof so we need to remove - // the first `num_pub_inputs` field elements. - let num_bytes_to_remove = num_pub_inputs * (FieldElement::max_num_bytes() as usize); - proof[num_bytes_to_remove..].to_vec() -} - -/// Prepends a set of public inputs to a proof. -pub fn prepend_public_inputs(proof: Vec, public_inputs: WitnessMap) -> Vec { - // We omit any unassigned witnesses. - // Witness values should be ordered by their index but we skip over any indices without an assignment. - let public_inputs_bytes = - public_inputs.into_iter().flat_map(|(_, assignment)| assignment.to_be_bytes()); - - public_inputs_bytes.chain(proof).collect() -} diff --git a/tooling/debugger/src/context.rs b/tooling/debugger/src/context.rs index ea32c864a0b..646beaf0096 100644 --- a/tooling/debugger/src/context.rs +++ b/tooling/debugger/src/context.rs @@ -862,7 +862,11 @@ mod tests { let opcodes = vec![ Opcode::BrilligCall { id: 0, inputs: vec![], outputs: vec![], predicate: None }, - Opcode::MemoryInit { block_id: BlockId(0), init: vec![] }, + Opcode::MemoryInit { + block_id: BlockId(0), + init: vec![], + block_type: acvm::acir::circuit::opcodes::BlockType::Memory, + }, Opcode::BrilligCall { id: 0, inputs: vec![], outputs: vec![], predicate: None }, Opcode::AssertZero(Expression::default()), ]; diff --git a/tooling/debugger/tests/debug.rs b/tooling/debugger/tests/debug.rs index b104a2c84ac..313b6b30591 100644 --- a/tooling/debugger/tests/debug.rs +++ b/tooling/debugger/tests/debug.rs @@ -16,12 +16,6 @@ mod tests { let mut dbg_session = spawn_bash(Some(timeout_seconds * 1000)).expect("Could not start bash session"); - // Set backend to `/dev/null` to force an error if nargo tries to speak to a backend. - dbg_session - .send_line("export NARGO_BACKEND_PATH=/dev/null") - .expect("Could not export NARGO_BACKEND_PATH."); - dbg_session.wait_for_prompt().expect("Could not export NARGO_BACKEND_PATH."); - // Start debugger and test that it loads for the given program. dbg_session .execute( diff --git a/tooling/lsp/src/solver.rs b/tooling/lsp/src/solver.rs index 249406effaf..87327b01e36 100644 --- a/tooling/lsp/src/solver.rs +++ b/tooling/lsp/src/solver.rs @@ -27,9 +27,13 @@ impl BlackBoxFunctionSolver for WrapperSolver { fn multi_scalar_mul( &self, points: &[acvm::FieldElement], - scalars: &[acvm::FieldElement], - ) -> Result<(acvm::FieldElement, acvm::FieldElement), acvm::BlackBoxResolutionError> { - self.0.multi_scalar_mul(points, scalars) + scalars_lo: &[acvm::FieldElement], + scalars_hi: &[acvm::FieldElement], + ) -> Result< + (acvm::FieldElement, acvm::FieldElement, acvm::FieldElement), + acvm::BlackBoxResolutionError, + > { + self.0.multi_scalar_mul(points, scalars_lo, scalars_hi) } fn pedersen_hash( @@ -44,10 +48,15 @@ impl BlackBoxFunctionSolver for WrapperSolver { &self, input1_x: &acvm::FieldElement, input1_y: &acvm::FieldElement, + input1_infinite: &acvm::FieldElement, input2_x: &acvm::FieldElement, input2_y: &acvm::FieldElement, - ) -> Result<(acvm::FieldElement, acvm::FieldElement), acvm::BlackBoxResolutionError> { - self.0.ec_add(input1_x, input1_y, input2_x, input2_y) + input2_infinite: &acvm::FieldElement, + ) -> Result< + (acvm::FieldElement, acvm::FieldElement, acvm::FieldElement), + acvm::BlackBoxResolutionError, + > { + self.0.ec_add(input1_x, input1_y, input1_infinite, input2_x, input2_y, input2_infinite) } fn poseidon2_permutation( diff --git a/tooling/nargo/src/artifacts/contract.rs b/tooling/nargo/src/artifacts/contract.rs index 83bb4b94f82..a864da7c33c 100644 --- a/tooling/nargo/src/artifacts/contract.rs +++ b/tooling/nargo/src/artifacts/contract.rs @@ -9,7 +9,7 @@ use std::collections::{BTreeMap, HashMap}; use fm::FileId; -#[derive(Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] pub struct ContractOutputsArtifact { pub structs: HashMap>, pub globals: HashMap>, @@ -21,7 +21,7 @@ impl From for ContractOutputsArtifact { } } -#[derive(Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] pub struct ContractArtifact { /// Version of noir used to compile this contract pub noir_version: String, @@ -51,7 +51,7 @@ impl From for ContractArtifact { /// /// A contract function unlike a regular Noir program however can have additional properties. /// One of these being a function type. -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ContractFunctionArtifact { pub name: String, diff --git a/tooling/nargo/src/artifacts/debug.rs b/tooling/nargo/src/artifacts/debug.rs index 496896468cc..2570c3f5c9f 100644 --- a/tooling/nargo/src/artifacts/debug.rs +++ b/tooling/nargo/src/artifacts/debug.rs @@ -9,6 +9,7 @@ use std::{ }; pub use super::debug_vars::{DebugVars, StackFrame}; +use super::{contract::ContractArtifact, program::ProgramArtifact}; use fm::{FileId, FileManager, PathString}; /// A Debug Artifact stores, for a given program, the debug info for every function @@ -128,6 +129,16 @@ impl From for DebugArtifact { } } +impl From for DebugArtifact { + fn from(program_artifact: ProgramArtifact) -> Self { + DebugArtifact { + debug_symbols: program_artifact.debug_symbols.debug_infos, + file_map: program_artifact.file_map, + warnings: Vec::new(), + } + } +} + impl From for DebugArtifact { fn from(compiled_artifact: CompiledContract) -> Self { let all_functions_debug: Vec = compiled_artifact @@ -144,6 +155,22 @@ impl From for DebugArtifact { } } +impl From for DebugArtifact { + fn from(compiled_artifact: ContractArtifact) -> Self { + let all_functions_debug: Vec = compiled_artifact + .functions + .into_iter() + .flat_map(|contract_function| contract_function.debug_symbols.debug_infos) + .collect(); + + DebugArtifact { + debug_symbols: all_functions_debug, + file_map: compiled_artifact.file_map, + warnings: Vec::new(), + } + } +} + impl<'a> Files<'a> for DebugArtifact { type FileId = FileId; type Name = PathString; diff --git a/tooling/nargo/src/artifacts/program.rs b/tooling/nargo/src/artifacts/program.rs index 67ac9f53ec8..3c25b9e3345 100644 --- a/tooling/nargo/src/artifacts/program.rs +++ b/tooling/nargo/src/artifacts/program.rs @@ -8,7 +8,7 @@ use noirc_driver::DebugFile; use noirc_errors::debug_info::ProgramDebugInfo; use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize, Debug)] +#[derive(Clone, Serialize, Deserialize, Debug)] pub struct ProgramArtifact { pub noir_version: String, diff --git a/tooling/nargo/src/constants.rs b/tooling/nargo/src/constants.rs index 0b50d61fe37..1048d86fcd7 100644 --- a/tooling/nargo/src/constants.rs +++ b/tooling/nargo/src/constants.rs @@ -13,8 +13,6 @@ pub const EXPORT_DIR: &str = "export"; // Files /// The file from which Nargo pulls prover inputs pub const PROVER_INPUT_FILE: &str = "Prover"; -/// The file from which Nargo pulls verifier inputs -pub const VERIFIER_INPUT_FILE: &str = "Verifier"; /// The package definition file for a Noir project. pub const PKG_FILE: &str = "Nargo.toml"; diff --git a/tooling/nargo/src/package.rs b/tooling/nargo/src/package.rs index ecbf3585210..44f0a3504f7 100644 --- a/tooling/nargo/src/package.rs +++ b/tooling/nargo/src/package.rs @@ -2,7 +2,7 @@ use std::{collections::BTreeMap, fmt::Display, path::PathBuf}; use noirc_frontend::graph::CrateName; -use crate::constants::{PROVER_INPUT_FILE, VERIFIER_INPUT_FILE}; +use crate::constants::PROVER_INPUT_FILE; #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum PackageType { @@ -59,11 +59,6 @@ impl Package { // For now it is hard-coded to be toml. self.root_dir.join(format!("{PROVER_INPUT_FILE}.toml")) } - pub fn verifier_input_path(&self) -> PathBuf { - // TODO: This should be configurable, such as if we are looking for .json or .toml or custom paths - // For now it is hard-coded to be toml. - self.root_dir.join(format!("{VERIFIER_INPUT_FILE}.toml")) - } pub fn is_binary(&self) -> bool { self.package_type == PackageType::Binary diff --git a/tooling/nargo_cli/Cargo.toml b/tooling/nargo_cli/Cargo.toml index c20be037e62..d10dd6a22ff 100644 --- a/tooling/nargo_cli/Cargo.toml +++ b/tooling/nargo_cli/Cargo.toml @@ -43,11 +43,10 @@ thiserror.workspace = true tower.workspace = true async-lsp = { workspace = true, features = ["client-monitor", "stdio", "tracing", "tokio"] } const_format.workspace = true -hex.workspace = true similar-asserts.workspace = true termcolor = "1.1.2" color-eyre = "0.6.2" -tokio = { version = "1.0", features = ["io-std"] } +tokio = { version = "1.0", features = ["io-std", "rt"] } dap.workspace = true clap-markdown = { git = "https://github.com/noir-lang/clap-markdown", rev = "450d759532c88f0dba70891ceecdbc9ff8f25d2b", optional = true } @@ -55,9 +54,6 @@ notify = "6.1.1" notify-debouncer-full = "0.3.1" termion = "3.0.0" -# Backends -backend-interface = { path = "../backend_interface" } - # Logs tracing-subscriber.workspace = true tracing-appender = "0.2.3" diff --git a/tooling/nargo_cli/build.rs b/tooling/nargo_cli/build.rs index 0ed2d4c07f7..74042cf4e40 100644 --- a/tooling/nargo_cli/build.rs +++ b/tooling/nargo_cli/build.rs @@ -63,7 +63,6 @@ fn execution_success_{test_name}() {{ let test_program_dir = PathBuf::from("{test_dir}"); let mut cmd = Command::cargo_bin("nargo").unwrap(); - cmd.env("NARGO_BACKEND_PATH", path_to_mock_backend()); cmd.arg("--program-dir").arg(test_program_dir); cmd.arg("execute").arg("--force"); @@ -101,7 +100,6 @@ fn execution_failure_{test_name}() {{ let test_program_dir = PathBuf::from("{test_dir}"); let mut cmd = Command::cargo_bin("nargo").unwrap(); - cmd.env("NARGO_BACKEND_PATH", path_to_mock_backend()); cmd.arg("--program-dir").arg(test_program_dir); cmd.arg("execute").arg("--force"); @@ -139,7 +137,6 @@ fn noir_test_success_{test_name}() {{ let test_program_dir = PathBuf::from("{test_dir}"); let mut cmd = Command::cargo_bin("nargo").unwrap(); - cmd.env("NARGO_BACKEND_PATH", path_to_mock_backend()); cmd.arg("--program-dir").arg(test_program_dir); cmd.arg("test"); @@ -177,7 +174,6 @@ fn noir_test_failure_{test_name}() {{ let test_program_dir = PathBuf::from("{test_dir}"); let mut cmd = Command::cargo_bin("nargo").unwrap(); - cmd.env("NARGO_BACKEND_PATH", path_to_mock_backend()); cmd.arg("--program-dir").arg(test_program_dir); cmd.arg("test"); @@ -218,7 +214,6 @@ fn compile_success_empty_{test_name}() {{ let test_program_dir = PathBuf::from("{test_dir}"); let mut cmd = Command::cargo_bin("nargo").unwrap(); - cmd.env("NARGO_BACKEND_PATH", path_to_mock_backend()); cmd.arg("--program-dir").arg(test_program_dir); cmd.arg("info"); cmd.arg("--json"); @@ -269,7 +264,6 @@ fn compile_success_contract_{test_name}() {{ let test_program_dir = PathBuf::from("{test_dir}"); let mut cmd = Command::cargo_bin("nargo").unwrap(); - cmd.env("NARGO_BACKEND_PATH", path_to_mock_backend()); cmd.arg("--program-dir").arg(test_program_dir); cmd.arg("compile").arg("--force"); @@ -307,7 +301,6 @@ fn compile_failure_{test_name}() {{ let test_program_dir = PathBuf::from("{test_dir}"); let mut cmd = Command::cargo_bin("nargo").unwrap(); - cmd.env("NARGO_BACKEND_PATH", path_to_mock_backend()); cmd.arg("--program-dir").arg(test_program_dir); cmd.arg("compile").arg("--force"); diff --git a/tooling/nargo_cli/src/backends.rs b/tooling/nargo_cli/src/backends.rs deleted file mode 100644 index 2b3e9d8861f..00000000000 --- a/tooling/nargo_cli/src/backends.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::path::PathBuf; - -use backend_interface::backends_directory; -pub(crate) use backend_interface::Backend; - -fn active_backend_file_path() -> PathBuf { - backends_directory().join(".selected_backend") -} - -pub(crate) use backend_interface::ACVM_BACKEND_BARRETENBERG; - -pub(crate) fn clear_active_backend() { - let active_backend_file = active_backend_file_path(); - if active_backend_file.is_file() { - std::fs::remove_file(active_backend_file_path()) - .expect("should delete active backend file"); - } -} - -pub(crate) fn set_active_backend(backend_name: &str) { - let active_backend_file = active_backend_file_path(); - let backends_directory = - active_backend_file.parent().expect("active backend file should have parent"); - - std::fs::create_dir_all(backends_directory).expect("Could not create backends directory"); - std::fs::write(active_backend_file, backend_name.as_bytes()) - .expect("Could not write to active backend file"); -} - -pub(crate) fn get_active_backend() -> String { - let active_backend_file = active_backend_file_path(); - - if !active_backend_file.is_file() { - set_active_backend(ACVM_BACKEND_BARRETENBERG); - return ACVM_BACKEND_BARRETENBERG.to_string(); - } - - std::fs::read_to_string(active_backend_file).expect("Could not read active backend file") -} diff --git a/tooling/nargo_cli/src/cli/backend_cmd/current_cmd.rs b/tooling/nargo_cli/src/cli/backend_cmd/current_cmd.rs deleted file mode 100644 index 5aba00764d3..00000000000 --- a/tooling/nargo_cli/src/cli/backend_cmd/current_cmd.rs +++ /dev/null @@ -1,13 +0,0 @@ -use clap::Args; - -use crate::{backends::get_active_backend, errors::CliError}; - -/// Prints the name of the currently active backend -#[derive(Debug, Clone, Args)] -pub(crate) struct CurrentCommand; - -pub(crate) fn run(_args: CurrentCommand) -> Result<(), CliError> { - println!("{}", get_active_backend()); - - Ok(()) -} diff --git a/tooling/nargo_cli/src/cli/backend_cmd/install_cmd.rs b/tooling/nargo_cli/src/cli/backend_cmd/install_cmd.rs deleted file mode 100644 index 974db9ff7f5..00000000000 --- a/tooling/nargo_cli/src/cli/backend_cmd/install_cmd.rs +++ /dev/null @@ -1,30 +0,0 @@ -use clap::Args; - -use backend_interface::{backends_directory, download_backend}; - -use crate::errors::{BackendError, CliError}; - -use super::ls_cmd::get_available_backends; - -/// Install a new backend from a URL. -#[derive(Debug, Clone, Args)] -pub(crate) struct InstallCommand { - /// The name of the backend to install. - backend: String, - - /// The URL from which to download the backend. - url: String, -} - -pub(crate) fn run(args: InstallCommand) -> Result<(), CliError> { - let installed_backends = get_available_backends(); - - if installed_backends.contains(&args.backend) { - return Err(BackendError::AlreadyInstalled(args.backend).into()); - } - - download_backend(&args.url, &backends_directory().join(args.backend).join("backend_binary")) - .map_err(BackendError::from)?; - - Ok(()) -} diff --git a/tooling/nargo_cli/src/cli/backend_cmd/ls_cmd.rs b/tooling/nargo_cli/src/cli/backend_cmd/ls_cmd.rs deleted file mode 100644 index da37b104d65..00000000000 --- a/tooling/nargo_cli/src/cli/backend_cmd/ls_cmd.rs +++ /dev/null @@ -1,34 +0,0 @@ -use backend_interface::backends_directory; -use clap::Args; - -use crate::errors::CliError; - -/// Prints the list of currently installed backends -#[derive(Debug, Clone, Args)] -pub(crate) struct LsCommand; - -pub(crate) fn run(_args: LsCommand) -> Result<(), CliError> { - for backend in get_available_backends() { - println!("{backend}"); - } - - Ok(()) -} - -pub(super) fn get_available_backends() -> Vec { - let backend_directory_contents = std::fs::read_dir(backends_directory()) - .expect("Could not read backends directory contents"); - - // TODO: Highlight the currently active backend. - backend_directory_contents - .into_iter() - .filter_map(|entry| { - let path = entry.ok()?.path(); - if path.is_dir() { - path.file_name().map(|name| name.to_string_lossy().to_string()) - } else { - None - } - }) - .collect() -} diff --git a/tooling/nargo_cli/src/cli/backend_cmd/mod.rs b/tooling/nargo_cli/src/cli/backend_cmd/mod.rs deleted file mode 100644 index 985dbbdb934..00000000000 --- a/tooling/nargo_cli/src/cli/backend_cmd/mod.rs +++ /dev/null @@ -1,41 +0,0 @@ -use clap::{Args, Subcommand}; - -use crate::errors::CliError; - -mod current_cmd; -mod install_cmd; -mod ls_cmd; -mod uninstall_cmd; -mod use_cmd; - -#[non_exhaustive] -#[derive(Args, Clone, Debug)] -/// Install and select custom backends used to generate and verify proofs. -pub(crate) struct BackendCommand { - #[command(subcommand)] - command: BackendCommands, -} - -#[non_exhaustive] -#[derive(Subcommand, Clone, Debug)] -pub(crate) enum BackendCommands { - Current(current_cmd::CurrentCommand), - Ls(ls_cmd::LsCommand), - Use(use_cmd::UseCommand), - Install(install_cmd::InstallCommand), - Uninstall(uninstall_cmd::UninstallCommand), -} - -pub(crate) fn run(cmd: BackendCommand) -> Result<(), CliError> { - let BackendCommand { command } = cmd; - - match command { - BackendCommands::Current(args) => current_cmd::run(args), - BackendCommands::Ls(args) => ls_cmd::run(args), - BackendCommands::Use(args) => use_cmd::run(args), - BackendCommands::Install(args) => install_cmd::run(args), - BackendCommands::Uninstall(args) => uninstall_cmd::run(args), - }?; - - Ok(()) -} diff --git a/tooling/nargo_cli/src/cli/backend_cmd/uninstall_cmd.rs b/tooling/nargo_cli/src/cli/backend_cmd/uninstall_cmd.rs deleted file mode 100644 index 7497f1bc2f6..00000000000 --- a/tooling/nargo_cli/src/cli/backend_cmd/uninstall_cmd.rs +++ /dev/null @@ -1,59 +0,0 @@ -use clap::Args; - -use backend_interface::backends_directory; - -use crate::{ - backends::{ - clear_active_backend, get_active_backend, set_active_backend, ACVM_BACKEND_BARRETENBERG, - }, - errors::{BackendError, CliError}, -}; - -use super::ls_cmd::get_available_backends; - -/// Uninstalls a backend -#[derive(Debug, Clone, Args)] -pub(crate) struct UninstallCommand { - /// The name of the backend to uninstall. - backend: String, -} - -pub(crate) fn run(args: UninstallCommand) -> Result<(), CliError> { - let installed_backends = get_available_backends(); - - if !installed_backends.contains(&args.backend) { - return Err(BackendError::UnknownBackend(args.backend).into()); - } - - let active_backend = get_active_backend(); - - // Handle the case where we're uninstalling the currently active backend. - if active_backend == args.backend { - let barretenberg_is_installed = - installed_backends.iter().any(|backend_name| backend_name == ACVM_BACKEND_BARRETENBERG); - - let new_active_backend = - if args.backend != ACVM_BACKEND_BARRETENBERG && barretenberg_is_installed { - // Prefer switching to barretenberg if possible. - Some(ACVM_BACKEND_BARRETENBERG) - } else { - // Otherwise pick the first backend which isn't being uninstalled. - installed_backends - .iter() - .find(|&backend_name| backend_name != &args.backend) - .map(|name| name.as_str()) - }; - - if let Some(backend) = new_active_backend { - set_active_backend(backend); - } else { - // We've deleted the last backend. Clear the active backend file to be recreated once we install a new one. - clear_active_backend(); - } - } - - std::fs::remove_dir_all(backends_directory().join(args.backend)) - .expect("backend directory should be deleted"); - - Ok(()) -} diff --git a/tooling/nargo_cli/src/cli/backend_cmd/use_cmd.rs b/tooling/nargo_cli/src/cli/backend_cmd/use_cmd.rs deleted file mode 100644 index 66a129c2148..00000000000 --- a/tooling/nargo_cli/src/cli/backend_cmd/use_cmd.rs +++ /dev/null @@ -1,26 +0,0 @@ -use clap::Args; - -use crate::{ - backends::set_active_backend, - errors::{BackendError, CliError}, -}; - -use super::ls_cmd::get_available_backends; - -/// Select the backend to use -#[derive(Debug, Clone, Args)] -pub(crate) struct UseCommand { - backend: String, -} - -pub(crate) fn run(args: UseCommand) -> Result<(), CliError> { - let backends = get_available_backends(); - - if !backends.contains(&args.backend) { - return Err(BackendError::UnknownBackend(args.backend).into()); - } - - set_active_backend(&args.backend); - - Ok(()) -} diff --git a/tooling/nargo_cli/src/cli/check_cmd.rs b/tooling/nargo_cli/src/cli/check_cmd.rs index d5313d96076..e2e1f147b90 100644 --- a/tooling/nargo_cli/src/cli/check_cmd.rs +++ b/tooling/nargo_cli/src/cli/check_cmd.rs @@ -95,13 +95,11 @@ fn check_package( Ok(false) } else { // XXX: We can have a --overwrite flag to determine if you want to overwrite the Prover/Verifier.toml files - if let Some((parameters, return_type)) = compute_function_abi(&context, &crate_id) { + if let Some((parameters, _)) = compute_function_abi(&context, &crate_id) { let path_to_prover_input = package.prover_input_path(); - let path_to_verifier_input = package.verifier_input_path(); // Before writing the file, check if it exists and whether overwrite is set let should_write_prover = !path_to_prover_input.exists() || allow_overwrite; - let should_write_verifier = !path_to_verifier_input.exists() || allow_overwrite; if should_write_prover { let prover_toml = create_input_toml_template(parameters.clone(), None); @@ -110,19 +108,7 @@ fn check_package( eprintln!("Note: Prover.toml already exists. Use --overwrite to force overwrite."); } - if should_write_verifier { - let public_inputs = - parameters.into_iter().filter(|param| param.is_public()).collect(); - - let verifier_toml = create_input_toml_template(public_inputs, return_type); - write_to_file(verifier_toml.as_bytes(), &path_to_verifier_input); - } else { - eprintln!( - "Note: Verifier.toml already exists. Use --overwrite to force overwrite." - ); - } - - let any_file_written = should_write_prover || should_write_verifier; + let any_file_written = should_write_prover; Ok(any_file_written) } else { diff --git a/tooling/nargo_cli/src/cli/codegen_verifier_cmd.rs b/tooling/nargo_cli/src/cli/codegen_verifier_cmd.rs deleted file mode 100644 index 8c64d9cd935..00000000000 --- a/tooling/nargo_cli/src/cli/codegen_verifier_cmd.rs +++ /dev/null @@ -1,83 +0,0 @@ -use super::fs::{create_named_dir, write_to_file}; -use super::NargoConfig; -use crate::backends::Backend; -use crate::errors::CliError; - -use clap::Args; -use nargo::ops::{compile_program, report_errors}; -use nargo::{insert_all_files_for_workspace_into_file_manager, parse_all}; -use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; -use noirc_driver::{file_manager_with_stdlib, CompileOptions, NOIR_ARTIFACT_VERSION_STRING}; -use noirc_frontend::graph::CrateName; - -/// Generates a Solidity verifier smart contract for the program -#[derive(Debug, Clone, Args)] -pub(crate) struct CodegenVerifierCommand { - /// The name of the package to codegen - #[clap(long, conflicts_with = "workspace")] - package: Option, - - /// Codegen all packages in the workspace - #[clap(long, conflicts_with = "package")] - workspace: bool, - - #[clap(flatten)] - compile_options: CompileOptions, -} - -pub(crate) fn run( - backend: &Backend, - args: CodegenVerifierCommand, - config: NargoConfig, -) -> Result<(), CliError> { - let toml_path = get_package_manifest(&config.program_dir)?; - let default_selection = - if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; - let selection = args.package.map_or(default_selection, PackageSelection::Selected); - let workspace = resolve_workspace_from_toml( - &toml_path, - selection, - Some(NOIR_ARTIFACT_VERSION_STRING.to_string()), - )?; - - let mut workspace_file_manager = file_manager_with_stdlib(&workspace.root_dir); - insert_all_files_for_workspace_into_file_manager(&workspace, &mut workspace_file_manager); - let parsed_files = parse_all(&workspace_file_manager); - - let binary_packages = workspace.into_iter().filter(|package| package.is_binary()); - for package in binary_packages { - let compilation_result = compile_program( - &workspace_file_manager, - &parsed_files, - package, - &args.compile_options, - None, - ); - - let program = report_errors( - compilation_result, - &workspace_file_manager, - args.compile_options.deny_warnings, - args.compile_options.silence_warnings, - )?; - - let program = nargo::ops::transform_program(program, args.compile_options.expression_width); - - // TODO(https://github.com/noir-lang/noir/issues/4428): - // We do not expect to have a smart contract verifier for a foldable program with multiple circuits. - // However, in the future we can expect to possibly have non-inlined ACIR functions during compilation - // that will be inlined at a later step such as by the ACVM compiler or by the backend. - // Add appropriate handling here once the compiler enables multiple ACIR functions. - assert_eq!(program.program.functions.len(), 1); - let smart_contract_string = backend.eth_contract(&program.program)?; - - let contract_dir = workspace.contracts_directory_path(package); - create_named_dir(&contract_dir, "contract"); - let contract_path = contract_dir.join("plonk_vk").with_extension("sol"); - - let path = write_to_file(smart_contract_string.as_bytes(), &contract_path); - println!("[{}] Contract successfully created and located at {path}", package.name); - } - - Ok(()) -} diff --git a/tooling/nargo_cli/src/cli/compile_cmd.rs b/tooling/nargo_cli/src/cli/compile_cmd.rs index 2f878406939..ecf2e2e9f53 100644 --- a/tooling/nargo_cli/src/cli/compile_cmd.rs +++ b/tooling/nargo_cli/src/cli/compile_cmd.rs @@ -22,7 +22,6 @@ use notify_debouncer_full::new_debouncer; use crate::errors::CliError; -use super::fs::program::only_acir; use super::fs::program::{read_program_from_file, save_contract_to_file, save_program_to_file}; use super::NargoConfig; use rayon::prelude::*; @@ -111,7 +110,7 @@ fn watch_workspace(workspace: &Workspace, compile_options: &CompileOptions) -> n Ok(()) } -fn compile_workspace_full( +pub(super) fn compile_workspace_full( workspace: &Workspace, compile_options: &CompileOptions, ) -> Result<(), CliError> { @@ -136,10 +135,9 @@ fn compile_workspace_full( .partition(|package| package.is_binary()); // Save build artifacts to disk. - let only_acir = compile_options.only_acir; for (package, program) in binary_packages.into_iter().zip(compiled_programs) { let program = nargo::ops::transform_program(program, compile_options.expression_width); - save_program(program.clone(), &package, &workspace.target_directory_path(), only_acir); + save_program(program.clone(), &package, &workspace.target_directory_path()); } let circuit_dir = workspace.target_directory_path(); for (package, contract) in contract_packages.into_iter().zip(compiled_contracts) { @@ -197,18 +195,9 @@ pub(super) fn compile_workspace( } } -pub(super) fn save_program( - program: CompiledProgram, - package: &Package, - circuit_dir: &Path, - only_acir_opt: bool, -) { - if only_acir_opt { - only_acir(program.program, circuit_dir); - } else { - let program_artifact = ProgramArtifact::from(program.clone()); - save_program_to_file(&program_artifact, &package.name, circuit_dir); - } +pub(super) fn save_program(program: CompiledProgram, package: &Package, circuit_dir: &Path) { + let program_artifact = ProgramArtifact::from(program.clone()); + save_program_to_file(&program_artifact, &package.name, circuit_dir); } fn save_contract(contract: CompiledContract, package: &Package, circuit_dir: &Path) { diff --git a/tooling/nargo_cli/src/cli/execute_cmd.rs b/tooling/nargo_cli/src/cli/execute_cmd.rs index 68f902dfe33..862a46884ef 100644 --- a/tooling/nargo_cli/src/cli/execute_cmd.rs +++ b/tooling/nargo_cli/src/cli/execute_cmd.rs @@ -5,19 +5,18 @@ use clap::Args; use nargo::artifacts::debug::DebugArtifact; use nargo::constants::PROVER_INPUT_FILE; use nargo::errors::try_to_diagnose_runtime_error; -use nargo::ops::{compile_program, report_errors, DefaultForeignCallExecutor}; +use nargo::ops::DefaultForeignCallExecutor; use nargo::package::Package; -use nargo::{insert_all_files_for_workspace_into_file_manager, parse_all}; use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; use noirc_abi::input_parser::{Format, InputValue}; use noirc_abi::InputMap; -use noirc_driver::{ - file_manager_with_stdlib, CompileOptions, CompiledProgram, NOIR_ARTIFACT_VERSION_STRING, -}; +use noirc_driver::{CompileOptions, CompiledProgram, NOIR_ARTIFACT_VERSION_STRING}; use noirc_frontend::graph::CrateName; +use super::compile_cmd::compile_workspace_full; use super::fs::{inputs::read_inputs_from_file, witness::save_witness_to_dir}; use super::NargoConfig; +use crate::cli::fs::program::read_program_from_file; use crate::errors::CliError; /// Executes a circuit to calculate its return value @@ -59,32 +58,16 @@ pub(crate) fn run(args: ExecuteCommand, config: NargoConfig) -> Result<(), CliEr )?; let target_dir = &workspace.target_directory_path(); - let mut workspace_file_manager = file_manager_with_stdlib(&workspace.root_dir); - insert_all_files_for_workspace_into_file_manager(&workspace, &mut workspace_file_manager); - let parsed_files = parse_all(&workspace_file_manager); + // Compile the full workspace in order to generate any build artifacts. + compile_workspace_full(&workspace, &args.compile_options)?; let binary_packages = workspace.into_iter().filter(|package| package.is_binary()); for package in binary_packages { - let compilation_result = compile_program( - &workspace_file_manager, - &parsed_files, - package, - &args.compile_options, - None, - ); - - let compiled_program = report_errors( - compilation_result, - &workspace_file_manager, - args.compile_options.deny_warnings, - args.compile_options.silence_warnings, - )?; - - let compiled_program = - nargo::ops::transform_program(compiled_program, args.compile_options.expression_width); + let program_artifact_path = workspace.package_build_path(package); + let program: CompiledProgram = read_program_from_file(program_artifact_path)?.into(); let (return_value, witness_stack) = execute_program_and_decode( - compiled_program, + program, package, &args.prover_name, args.oracle_resolver.as_deref(), diff --git a/tooling/nargo_cli/src/cli/fs/inputs.rs b/tooling/nargo_cli/src/cli/fs/inputs.rs index bd038c51ad5..dee9a00507c 100644 --- a/tooling/nargo_cli/src/cli/fs/inputs.rs +++ b/tooling/nargo_cli/src/cli/fs/inputs.rs @@ -6,8 +6,6 @@ use std::{collections::BTreeMap, path::Path}; use crate::errors::FilesystemError; -use super::write_to_file; - /// Returns the circuit's parameters and its return value, if one exists. /// # Examples /// @@ -36,99 +34,3 @@ pub(crate) fn read_inputs_from_file>( Ok((input_map, return_value)) } - -pub(crate) fn write_inputs_to_file>( - input_map: &InputMap, - return_value: &Option, - abi: &Abi, - path: P, - file_name: &str, - format: Format, -) -> Result<(), FilesystemError> { - let file_path = path.as_ref().join(file_name).with_extension(format.ext()); - - // We must insert the return value into the `InputMap` in order for it to be written to file. - let serialized_output = match return_value { - // Parameters and return values are kept separate except for when they're being written to file. - // As a result, we don't want to modify the original map and must clone it before insertion. - Some(return_value) => { - let mut input_map = input_map.clone(); - input_map.insert(MAIN_RETURN_NAME.to_owned(), return_value.clone()); - format.serialize(&input_map, abi)? - } - // If no return value exists, then we can serialize the original map directly. - None => format.serialize(input_map, abi)?, - }; - - write_to_file(serialized_output.as_bytes(), &file_path); - - Ok(()) -} - -#[cfg(test)] -mod tests { - use std::{collections::BTreeMap, vec}; - - use acvm::FieldElement; - use nargo::constants::VERIFIER_INPUT_FILE; - use noirc_abi::{ - input_parser::{Format, InputValue}, - Abi, AbiParameter, AbiReturnType, AbiType, AbiVisibility, - }; - use tempfile::TempDir; - - use super::{read_inputs_from_file, write_inputs_to_file}; - - #[test] - fn write_and_read_recovers_inputs_and_return_value() { - let input_dir = TempDir::new().unwrap().into_path(); - - // We purposefully test a simple ABI here as we're focussing on `fs`. - // Tests for serializing complex types should exist in `noirc_abi`. - let abi = Abi { - parameters: vec![ - AbiParameter { - name: "foo".into(), - typ: AbiType::Field, - visibility: AbiVisibility::Public, - }, - AbiParameter { - name: "bar".into(), - typ: AbiType::String { length: 11 }, - visibility: AbiVisibility::Private, - }, - ], - return_type: Some(AbiReturnType { - abi_type: AbiType::Field, - visibility: AbiVisibility::Public, - }), - - // Input serialization is only dependent on types, not position in witness map. - // Neither of these should be relevant so we leave them empty. - param_witnesses: BTreeMap::new(), - return_witnesses: Vec::new(), - error_types: BTreeMap::new(), - }; - let input_map = BTreeMap::from([ - ("foo".to_owned(), InputValue::Field(42u128.into())), - ("bar".to_owned(), InputValue::String("hello world".to_owned())), - ]); - let return_value = Some(InputValue::Field(FieldElement::zero())); - - write_inputs_to_file( - &input_map, - &return_value, - &abi, - &input_dir, - VERIFIER_INPUT_FILE, - Format::Toml, - ) - .unwrap(); - - let (loaded_inputs, loaded_return_value) = - read_inputs_from_file(input_dir, VERIFIER_INPUT_FILE, Format::Toml, &abi).unwrap(); - - assert_eq!(loaded_inputs, input_map); - assert_eq!(loaded_return_value, return_value); - } -} diff --git a/tooling/nargo_cli/src/cli/fs/mod.rs b/tooling/nargo_cli/src/cli/fs/mod.rs index 4ebce3b3325..8658bd5b248 100644 --- a/tooling/nargo_cli/src/cli/fs/mod.rs +++ b/tooling/nargo_cli/src/cli/fs/mod.rs @@ -4,11 +4,8 @@ use std::{ path::{Path, PathBuf}, }; -use crate::errors::FilesystemError; - pub(super) mod inputs; pub(super) mod program; -pub(super) mod proof; pub(super) mod witness; pub(super) fn create_named_dir(named_dir: &Path, name: &str) -> PathBuf { @@ -31,12 +28,3 @@ pub(super) fn write_to_file(bytes: &[u8], path: &Path) -> String { Ok(_) => display.to_string(), } } - -pub(super) fn load_hex_data>(path: P) -> Result, FilesystemError> { - let hex_data: Vec<_> = std::fs::read(&path) - .map_err(|_| FilesystemError::PathNotValid(path.as_ref().to_path_buf()))?; - - let raw_bytes = hex::decode(hex_data).map_err(FilesystemError::HexArtifactNotValid)?; - - Ok(raw_bytes) -} diff --git a/tooling/nargo_cli/src/cli/fs/program.rs b/tooling/nargo_cli/src/cli/fs/program.rs index 77005e8d5af..ba017651667 100644 --- a/tooling/nargo_cli/src/cli/fs/program.rs +++ b/tooling/nargo_cli/src/cli/fs/program.rs @@ -1,6 +1,5 @@ use std::path::{Path, PathBuf}; -use acvm::acir::circuit::Program; use nargo::artifacts::{contract::ContractArtifact, program::ProgramArtifact}; use noirc_frontend::graph::CrateName; @@ -17,16 +16,6 @@ pub(crate) fn save_program_to_file>( save_build_artifact_to_file(program_artifact, &circuit_name, circuit_dir) } -/// Writes the bytecode as acir.gz -pub(crate) fn only_acir>(program: Program, circuit_dir: P) -> PathBuf { - create_named_dir(circuit_dir.as_ref(), "target"); - let circuit_path = circuit_dir.as_ref().join("acir").with_extension("gz"); - let bytes = Program::serialize_program(&program); - write_to_file(&bytes, &circuit_path); - - circuit_path -} - pub(crate) fn save_contract_to_file>( compiled_contract: &ContractArtifact, circuit_name: &str, diff --git a/tooling/nargo_cli/src/cli/fs/proof.rs b/tooling/nargo_cli/src/cli/fs/proof.rs deleted file mode 100644 index d2b3050708b..00000000000 --- a/tooling/nargo_cli/src/cli/fs/proof.rs +++ /dev/null @@ -1,20 +0,0 @@ -use std::path::{Path, PathBuf}; - -use nargo::constants::PROOF_EXT; - -use crate::errors::FilesystemError; - -use super::{create_named_dir, write_to_file}; - -pub(crate) fn save_proof_to_dir>( - proof: &[u8], - proof_name: &str, - proof_dir: P, -) -> Result { - create_named_dir(proof_dir.as_ref(), "proof"); - let proof_path = proof_dir.as_ref().join(proof_name).with_extension(PROOF_EXT); - - write_to_file(hex::encode(proof).as_bytes(), &proof_path); - - Ok(proof_path) -} diff --git a/tooling/nargo_cli/src/cli/info_cmd.rs b/tooling/nargo_cli/src/cli/info_cmd.rs index cac3c36f904..11cf6e22ab5 100644 --- a/tooling/nargo_cli/src/cli/info_cmd.rs +++ b/tooling/nargo_cli/src/cli/info_cmd.rs @@ -1,28 +1,25 @@ use std::collections::HashMap; -use acvm::acir::circuit::{ExpressionWidth, Program}; -use backend_interface::BackendError; +use acvm::acir::circuit::ExpressionWidth; use clap::Args; use iter_extended::vecmap; use nargo::{ - artifacts::debug::DebugArtifact, insert_all_files_for_workspace_into_file_manager, - ops::report_errors, package::Package, parse_all, + artifacts::{debug::DebugArtifact, program::ProgramArtifact}, + package::Package, }; use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; -use noirc_driver::{ - file_manager_with_stdlib, CompileOptions, CompiledContract, CompiledProgram, - NOIR_ARTIFACT_VERSION_STRING, -}; +use noirc_driver::{CompileOptions, NOIR_ARTIFACT_VERSION_STRING}; use noirc_errors::{debug_info::OpCodesCount, Location}; use noirc_frontend::graph::CrateName; use prettytable::{row, table, Row}; use rayon::prelude::*; use serde::Serialize; -use crate::backends::Backend; use crate::errors::CliError; -use super::{compile_cmd::compile_workspace, NargoConfig}; +use super::{ + compile_cmd::compile_workspace_full, fs::program::read_program_from_file, NargoConfig, +}; /// Provides detailed information on each of a program's function (represented by a single circuit) /// @@ -51,11 +48,7 @@ pub(crate) struct InfoCommand { compile_options: CompileOptions, } -pub(crate) fn run( - backend: &Backend, - args: InfoCommand, - config: NargoConfig, -) -> Result<(), CliError> { +pub(crate) fn run(args: InfoCommand, config: NargoConfig) -> Result<(), CliError> { let toml_path = get_package_manifest(&config.program_dir)?; let default_selection = if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; @@ -66,79 +59,42 @@ pub(crate) fn run( Some(NOIR_ARTIFACT_VERSION_STRING.to_string()), )?; - let mut workspace_file_manager = file_manager_with_stdlib(&workspace.root_dir); - insert_all_files_for_workspace_into_file_manager(&workspace, &mut workspace_file_manager); - let parsed_files = parse_all(&workspace_file_manager); - - let compiled_workspace = compile_workspace( - &workspace_file_manager, - &parsed_files, - &workspace, - &args.compile_options, - ); - - let (compiled_programs, compiled_contracts) = report_errors( - compiled_workspace, - &workspace_file_manager, - args.compile_options.deny_warnings, - args.compile_options.silence_warnings, - )?; + // Compile the full workspace in order to generate any build artifacts. + compile_workspace_full(&workspace, &args.compile_options)?; - let compiled_programs = vecmap(compiled_programs, |program| { - nargo::ops::transform_program(program, args.compile_options.expression_width) - }); - let compiled_contracts = vecmap(compiled_contracts, |contract| { - nargo::ops::transform_contract(contract, args.compile_options.expression_width) - }); + let binary_packages: Vec<(Package, ProgramArtifact)> = workspace + .into_iter() + .filter(|package| package.is_binary()) + .map(|package| -> Result<(Package, ProgramArtifact), CliError> { + let program_artifact_path = workspace.package_build_path(package); + let program = read_program_from_file(program_artifact_path)?; + Ok((package.clone(), program)) + }) + .collect::>()?; if args.profile_info { - for compiled_program in &compiled_programs { + for (_, compiled_program) in &binary_packages { let debug_artifact = DebugArtifact::from(compiled_program.clone()); - for function_debug in compiled_program.debug.iter() { + for function_debug in compiled_program.debug_symbols.debug_infos.iter() { let span_opcodes = function_debug.count_span_opcodes(); print_span_opcodes(span_opcodes, &debug_artifact); } } - - for compiled_contract in &compiled_contracts { - let debug_artifact = DebugArtifact::from(compiled_contract.clone()); - let functions = &compiled_contract.functions; - for contract_function in functions { - for function_debug in contract_function.debug.iter() { - let span_opcodes = function_debug.count_span_opcodes(); - print_span_opcodes(span_opcodes, &debug_artifact); - } - } - } } - let binary_packages = - workspace.into_iter().filter(|package| package.is_binary()).zip(compiled_programs); - let program_info = binary_packages + .into_iter() .par_bridge() .map(|(package, program)| { count_opcodes_and_gates_in_program( - backend, program, - package, - args.compile_options.expression_width, - ) - }) - .collect::>()?; - - let contract_info = compiled_contracts - .into_par_iter() - .map(|contract| { - count_opcodes_and_gates_in_contract( - backend, - contract, + &package, args.compile_options.expression_width, ) }) - .collect::>()?; + .collect(); - let info_report = InfoReport { programs: program_info, contracts: contract_info }; + let info_report = InfoReport { programs: program_info, contracts: Vec::new() }; if args.json { // Expose machine-readable JSON data. @@ -156,23 +112,6 @@ pub(crate) fn run( } program_table.printstd(); } - if !info_report.contracts.is_empty() { - let mut contract_table = table!([ - Fm->"Contract", - Fm->"Function", - Fm->"Expression Width", - Fm->"ACIR Opcodes", - Fm->"Backend Circuit Size" - ]); - for contract_info in info_report.contracts { - let contract_rows: Vec = contract_info.into(); - for row in contract_rows { - contract_table.add_row(row); - } - } - - contract_table.printstd(); - } } Ok(()) @@ -249,7 +188,6 @@ impl From for Vec { Fc->format!("{}", function.name), format!("{:?}", program_info.expression_width), Fc->format!("{}", function.acir_opcodes), - Fc->format!("{}", function.circuit_size), ] }) } @@ -268,7 +206,6 @@ struct ContractInfo { struct FunctionInfo { name: String, acir_opcodes: usize, - circuit_size: u32, } impl From for Vec { @@ -279,56 +216,26 @@ impl From for Vec { Fc->format!("{}", function.name), format!("{:?}", contract_info.expression_width), Fc->format!("{}", function.acir_opcodes), - Fc->format!("{}", function.circuit_size), ] }) } } fn count_opcodes_and_gates_in_program( - backend: &Backend, - compiled_program: CompiledProgram, + compiled_program: ProgramArtifact, package: &Package, expression_width: ExpressionWidth, -) -> Result { +) -> ProgramInfo { let functions = compiled_program - .program + .bytecode .functions .into_par_iter() .enumerate() - .map(|(i, function)| -> Result<_, BackendError> { - Ok(FunctionInfo { - name: compiled_program.names[i].clone(), - acir_opcodes: function.opcodes.len(), - // Unconstrained functions do not matter to a backend circuit count so we pass nothing here - circuit_size: backend.get_exact_circuit_size(&Program { - functions: vec![function], - unconstrained_functions: Vec::new(), - })?, - }) - }) - .collect::>()?; - - Ok(ProgramInfo { package_name: package.name.to_string(), expression_width, functions }) -} - -fn count_opcodes_and_gates_in_contract( - backend: &Backend, - contract: CompiledContract, - expression_width: ExpressionWidth, -) -> Result { - let functions = contract - .functions - .into_par_iter() - .map(|function| -> Result<_, BackendError> { - Ok(FunctionInfo { - name: function.name, - // TODO(https://github.com/noir-lang/noir/issues/4720) - acir_opcodes: function.bytecode.functions[0].opcodes.len(), - circuit_size: backend.get_exact_circuit_size(&function.bytecode)?, - }) + .map(|(i, function)| FunctionInfo { + name: compiled_program.names[i].clone(), + acir_opcodes: function.opcodes.len(), }) - .collect::>()?; + .collect(); - Ok(ContractInfo { name: contract.name, expression_width, functions }) + ProgramInfo { package_name: package.name.to_string(), expression_width, functions } } diff --git a/tooling/nargo_cli/src/cli/mod.rs b/tooling/nargo_cli/src/cli/mod.rs index ad778549ac0..485ccc7abaf 100644 --- a/tooling/nargo_cli/src/cli/mod.rs +++ b/tooling/nargo_cli/src/cli/mod.rs @@ -6,13 +6,9 @@ use std::path::PathBuf; use color_eyre::eyre; -use crate::backends::get_active_backend; - mod fs; -mod backend_cmd; mod check_cmd; -mod codegen_verifier_cmd; mod compile_cmd; mod dap_cmd; mod debug_cmd; @@ -23,9 +19,7 @@ mod info_cmd; mod init_cmd; mod lsp_cmd; mod new_cmd; -mod prove_cmd; mod test_cmd; -mod verify_cmd; const GIT_HASH: &str = env!("GIT_COMMIT"); const IS_DIRTY: &str = env!("GIT_DIRTY"); @@ -60,10 +54,8 @@ pub(crate) struct NargoConfig { #[non_exhaustive] #[derive(Subcommand, Clone, Debug)] enum NargoCommand { - Backend(backend_cmd::BackendCommand), Check(check_cmd::CheckCommand), Fmt(fmt_cmd::FormatCommand), - CodegenVerifier(codegen_verifier_cmd::CodegenVerifierCommand), #[command(alias = "build")] Compile(compile_cmd::CompileCommand), New(new_cmd::NewCommand), @@ -73,8 +65,6 @@ enum NargoCommand { Export(export_cmd::ExportCommand), #[command(hide = true)] // Hidden while the feature is being built out Debug(debug_cmd::DebugCommand), - Prove(prove_cmd::ProveCommand), - Verify(verify_cmd::VerifyCommand), Test(test_cmd::TestCommand), Info(info_cmd::InfoCommand), Lsp(lsp_cmd::LspCommand), @@ -94,18 +84,11 @@ pub(crate) fn start_cli() -> eyre::Result<()> { // Search through parent directories to find package root if necessary. if !matches!( command, - NargoCommand::New(_) - | NargoCommand::Init(_) - | NargoCommand::Lsp(_) - | NargoCommand::Backend(_) - | NargoCommand::Dap(_) + NargoCommand::New(_) | NargoCommand::Init(_) | NargoCommand::Lsp(_) | NargoCommand::Dap(_) ) { config.program_dir = find_package_root(&config.program_dir)?; } - let active_backend = get_active_backend(); - let backend = crate::backends::Backend::new(active_backend); - match command { NargoCommand::New(args) => new_cmd::run(args, config), NargoCommand::Init(args) => init_cmd::run(args, config), @@ -114,12 +97,8 @@ pub(crate) fn start_cli() -> eyre::Result<()> { NargoCommand::Debug(args) => debug_cmd::run(args, config), NargoCommand::Execute(args) => execute_cmd::run(args, config), NargoCommand::Export(args) => export_cmd::run(args, config), - NargoCommand::Prove(args) => prove_cmd::run(&backend, args, config), - NargoCommand::Verify(args) => verify_cmd::run(&backend, args, config), NargoCommand::Test(args) => test_cmd::run(args, config), - NargoCommand::Info(args) => info_cmd::run(&backend, args, config), - NargoCommand::CodegenVerifier(args) => codegen_verifier_cmd::run(&backend, args, config), - NargoCommand::Backend(args) => backend_cmd::run(args), + NargoCommand::Info(args) => info_cmd::run(args, config), NargoCommand::Lsp(args) => lsp_cmd::run(args, config), NargoCommand::Dap(args) => dap_cmd::run(args, config), NargoCommand::Fmt(args) => fmt_cmd::run(args, config), diff --git a/tooling/nargo_cli/src/cli/prove_cmd.rs b/tooling/nargo_cli/src/cli/prove_cmd.rs deleted file mode 100644 index 47c71527fd8..00000000000 --- a/tooling/nargo_cli/src/cli/prove_cmd.rs +++ /dev/null @@ -1,154 +0,0 @@ -use clap::Args; -use nargo::constants::{PROVER_INPUT_FILE, VERIFIER_INPUT_FILE}; -use nargo::ops::{compile_program, report_errors}; -use nargo::package::Package; -use nargo::workspace::Workspace; -use nargo::{insert_all_files_for_workspace_into_file_manager, parse_all}; -use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; -use noirc_abi::input_parser::Format; -use noirc_driver::{ - file_manager_with_stdlib, CompileOptions, CompiledProgram, NOIR_ARTIFACT_VERSION_STRING, -}; -use noirc_frontend::graph::CrateName; - -use super::fs::{ - inputs::{read_inputs_from_file, write_inputs_to_file}, - proof::save_proof_to_dir, -}; -use super::NargoConfig; -use crate::{backends::Backend, cli::execute_cmd::execute_program, errors::CliError}; - -/// Create proof for this program. The proof is returned as a hex encoded string. -#[derive(Debug, Clone, Args)] -#[clap(visible_alias = "p")] -pub(crate) struct ProveCommand { - /// The name of the toml file which contains the inputs for the prover - #[clap(long, short, default_value = PROVER_INPUT_FILE)] - prover_name: String, - - /// The name of the toml file which contains the inputs for the verifier - #[clap(long, short, default_value = VERIFIER_INPUT_FILE)] - verifier_name: String, - - /// Verify proof after proving - #[arg(long)] - verify: bool, - - /// The name of the package to prove - #[clap(long, conflicts_with = "workspace")] - package: Option, - - /// Prove all packages in the workspace - #[clap(long, conflicts_with = "package")] - workspace: bool, - - #[clap(flatten)] - compile_options: CompileOptions, - - /// JSON RPC url to solve oracle calls - #[clap(long)] - oracle_resolver: Option, -} - -pub(crate) fn run( - backend: &Backend, - args: ProveCommand, - config: NargoConfig, -) -> Result<(), CliError> { - let toml_path = get_package_manifest(&config.program_dir)?; - let default_selection = - if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; - let selection = args.package.map_or(default_selection, PackageSelection::Selected); - let workspace = resolve_workspace_from_toml( - &toml_path, - selection, - Some(NOIR_ARTIFACT_VERSION_STRING.to_string()), - )?; - - let mut workspace_file_manager = file_manager_with_stdlib(&workspace.root_dir); - insert_all_files_for_workspace_into_file_manager(&workspace, &mut workspace_file_manager); - let parsed_files = parse_all(&workspace_file_manager); - - let binary_packages = workspace.into_iter().filter(|package| package.is_binary()); - for package in binary_packages { - let compilation_result = compile_program( - &workspace_file_manager, - &parsed_files, - package, - &args.compile_options, - None, - ); - - let compiled_program = report_errors( - compilation_result, - &workspace_file_manager, - args.compile_options.deny_warnings, - args.compile_options.silence_warnings, - )?; - - let compiled_program = - nargo::ops::transform_program(compiled_program, args.compile_options.expression_width); - - prove_package( - backend, - &workspace, - package, - compiled_program, - &args.prover_name, - &args.verifier_name, - args.verify, - args.oracle_resolver.as_deref(), - )?; - } - - Ok(()) -} - -#[allow(clippy::too_many_arguments)] -pub(crate) fn prove_package( - backend: &Backend, - workspace: &Workspace, - package: &Package, - compiled_program: CompiledProgram, - prover_name: &str, - verifier_name: &str, - check_proof: bool, - foreign_call_resolver_url: Option<&str>, -) -> Result<(), CliError> { - // Parse the initial witness values from Prover.toml - let (inputs_map, _) = - read_inputs_from_file(&package.root_dir, prover_name, Format::Toml, &compiled_program.abi)?; - - let witness_stack = execute_program(&compiled_program, &inputs_map, foreign_call_resolver_url)?; - - // Write public inputs into Verifier.toml - let public_abi = compiled_program.abi.public_abi(); - // Get the entry point witness for the ABI - let main_witness = - &witness_stack.peek().expect("Should have at least one witness on the stack").witness; - let (public_inputs, return_value) = public_abi.decode(main_witness)?; - - write_inputs_to_file( - &public_inputs, - &return_value, - &public_abi, - &package.root_dir, - verifier_name, - Format::Toml, - )?; - - let proof = backend.prove(&compiled_program.program, witness_stack)?; - - if check_proof { - let public_inputs = public_abi.encode(&public_inputs, return_value)?; - let valid_proof = backend.verify(&proof, public_inputs, &compiled_program.program)?; - - if !valid_proof { - return Err(CliError::InvalidProof("".into())); - } - } - - save_proof_to_dir(&proof, &String::from(&package.name), workspace.proofs_directory_path())?; - - Ok(()) -} diff --git a/tooling/nargo_cli/src/cli/verify_cmd.rs b/tooling/nargo_cli/src/cli/verify_cmd.rs deleted file mode 100644 index a6078f6c1d3..00000000000 --- a/tooling/nargo_cli/src/cli/verify_cmd.rs +++ /dev/null @@ -1,109 +0,0 @@ -use super::fs::{inputs::read_inputs_from_file, load_hex_data}; -use super::NargoConfig; -use crate::{backends::Backend, errors::CliError}; - -use clap::Args; -use nargo::constants::{PROOF_EXT, VERIFIER_INPUT_FILE}; -use nargo::ops::{compile_program, report_errors}; -use nargo::package::Package; -use nargo::workspace::Workspace; -use nargo::{insert_all_files_for_workspace_into_file_manager, parse_all}; -use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; -use noirc_abi::input_parser::Format; -use noirc_driver::{ - file_manager_with_stdlib, CompileOptions, CompiledProgram, NOIR_ARTIFACT_VERSION_STRING, -}; -use noirc_frontend::graph::CrateName; - -/// Given a proof and a program, verify whether the proof is valid -#[derive(Debug, Clone, Args)] -#[clap(visible_alias = "v")] -pub(crate) struct VerifyCommand { - /// The name of the toml file which contains the inputs for the verifier - #[clap(long, short, default_value = VERIFIER_INPUT_FILE)] - verifier_name: String, - - /// The name of the package verify - #[clap(long, conflicts_with = "workspace")] - package: Option, - - /// Verify all packages in the workspace - #[clap(long, conflicts_with = "package")] - workspace: bool, - - #[clap(flatten)] - compile_options: CompileOptions, -} - -pub(crate) fn run( - backend: &Backend, - args: VerifyCommand, - config: NargoConfig, -) -> Result<(), CliError> { - let toml_path = get_package_manifest(&config.program_dir)?; - let default_selection = - if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; - let selection = args.package.map_or(default_selection, PackageSelection::Selected); - let workspace = resolve_workspace_from_toml( - &toml_path, - selection, - Some(NOIR_ARTIFACT_VERSION_STRING.to_string()), - )?; - - let mut workspace_file_manager = file_manager_with_stdlib(&workspace.root_dir); - insert_all_files_for_workspace_into_file_manager(&workspace, &mut workspace_file_manager); - let parsed_files = parse_all(&workspace_file_manager); - - let binary_packages = workspace.into_iter().filter(|package| package.is_binary()); - for package in binary_packages { - let compilation_result = compile_program( - &workspace_file_manager, - &parsed_files, - package, - &args.compile_options, - None, - ); - - let compiled_program = report_errors( - compilation_result, - &workspace_file_manager, - args.compile_options.deny_warnings, - args.compile_options.silence_warnings, - )?; - - let compiled_program = - nargo::ops::transform_program(compiled_program, args.compile_options.expression_width); - - verify_package(backend, &workspace, package, compiled_program, &args.verifier_name)?; - } - - Ok(()) -} - -fn verify_package( - backend: &Backend, - workspace: &Workspace, - package: &Package, - compiled_program: CompiledProgram, - verifier_name: &str, -) -> Result<(), CliError> { - // Load public inputs (if any) from `verifier_name`. - let public_abi = compiled_program.abi.public_abi(); - let (public_inputs_map, return_value) = - read_inputs_from_file(&package.root_dir, verifier_name, Format::Toml, &public_abi)?; - - let public_inputs = public_abi.encode(&public_inputs_map, return_value)?; - - let proof_path = - workspace.proofs_directory_path().join(package.name.to_string()).with_extension(PROOF_EXT); - - let proof = load_hex_data(&proof_path)?; - - let valid_proof = backend.verify(&proof, public_inputs, &compiled_program.program)?; - - if valid_proof { - Ok(()) - } else { - Err(CliError::InvalidProof(proof_path)) - } -} diff --git a/tooling/nargo_cli/src/errors.rs b/tooling/nargo_cli/src/errors.rs index 40fb7886405..3e0b13a9cbc 100644 --- a/tooling/nargo_cli/src/errors.rs +++ b/tooling/nargo_cli/src/errors.rs @@ -1,5 +1,4 @@ use acvm::acir::native_types::WitnessStackError; -use hex::FromHexError; use nargo::{errors::CompileError, NargoError}; use nargo_toml::ManifestError; use noir_debugger::errors::DapError; @@ -11,8 +10,7 @@ use thiserror::Error; pub(crate) enum FilesystemError { #[error("Error: {} is not a valid path\nRun either `nargo compile` to generate missing build artifacts or `nargo prove` to construct a proof", .0.display())] PathNotValid(PathBuf), - #[error("Error: could not parse hex build artifact (proof, proving and/or verification keys, ACIR checksum) ({0})")] - HexArtifactNotValid(FromHexError), + #[error( " Error: cannot find {0}.toml file.\n Expected location: {1:?} \n Please generate this file at the expected location." )] @@ -37,9 +35,6 @@ pub(crate) enum CliError { #[error("Error: destination {} already exists", .0.display())] DestinationAlreadyExists(PathBuf), - #[error("Failed to verify proof {}", .0.display())] - InvalidProof(PathBuf), - #[error("Invalid package name {0}. Did you mean to use `--name`?")] InvalidPackageName(String), @@ -68,24 +63,4 @@ pub(crate) enum CliError { /// Error from the compilation pipeline #[error(transparent)] CompileError(#[from] CompileError), - - /// Error related to backend selection/installation. - #[error(transparent)] - BackendError(#[from] BackendError), - - /// Error related to communication with backend. - #[error(transparent)] - BackendCommunicationError(#[from] backend_interface::BackendError), -} - -#[derive(Debug, thiserror::Error)] -pub(crate) enum BackendError { - #[error("No backend is installed with the name {0}")] - UnknownBackend(String), - - #[error("The backend {0} is already installed")] - AlreadyInstalled(String), - - #[error("Backend installation failed: {0}")] - InstallationError(#[from] std::io::Error), } diff --git a/tooling/nargo_cli/src/main.rs b/tooling/nargo_cli/src/main.rs index 6e2b7069bc4..a407d467ced 100644 --- a/tooling/nargo_cli/src/main.rs +++ b/tooling/nargo_cli/src/main.rs @@ -7,7 +7,6 @@ //! This name was used because it sounds like `cargo` and //! Noir Package Manager abbreviated is npm, which is already taken. -mod backends; mod cli; mod errors; diff --git a/tooling/nargo_cli/tests/codegen-verifier.rs b/tooling/nargo_cli/tests/codegen-verifier.rs deleted file mode 100644 index f991f72b108..00000000000 --- a/tooling/nargo_cli/tests/codegen-verifier.rs +++ /dev/null @@ -1,37 +0,0 @@ -//! This integration test aims to check that the `nargo codegen-verifier` will successfully create a -//! file containing a verifier for a simple program. - -use assert_cmd::prelude::*; -use predicates::prelude::*; -use std::process::Command; - -use assert_fs::prelude::{PathAssert, PathChild}; - -#[test] -fn simple_verifier_codegen() { - let test_dir = assert_fs::TempDir::new().unwrap(); - std::env::set_current_dir(&test_dir).unwrap(); - - // Create trivial program - let project_name = "hello_world"; - let project_dir = test_dir.child(project_name); - - let mut cmd = Command::cargo_bin("nargo").unwrap(); - cmd.arg("new").arg(project_name); - cmd.assert().success(); - - std::env::set_current_dir(&project_dir).unwrap(); - - // Run `nargo codegen-verifier` - let mut cmd = Command::cargo_bin("nargo").unwrap(); - cmd.arg("codegen-verifier"); - cmd.assert() - .success() - .stdout(predicate::str::contains("Contract successfully created and located at")); - - project_dir - .child("contract") - .child("hello_world") - .child("plonk_vk.sol") - .assert(predicate::path::is_file()); -} diff --git a/tooling/nargo_cli/tests/hello_world.rs b/tooling/nargo_cli/tests/hello_world.rs index 9fcb0c873e1..6b6931542b5 100644 --- a/tooling/nargo_cli/tests/hello_world.rs +++ b/tooling/nargo_cli/tests/hello_world.rs @@ -34,22 +34,11 @@ fn hello_world_example() { .stdout(predicate::str::contains("Constraint system successfully built!")); project_dir.child("Prover.toml").assert(predicate::path::is_file()); - project_dir.child("Verifier.toml").assert(predicate::path::is_file()); - // `nargo prove` + // `nargo execute` project_dir.child("Prover.toml").write_str("x = 1\ny = 2").unwrap(); let mut cmd = Command::cargo_bin("nargo").unwrap(); - cmd.arg("prove"); - cmd.assert().success(); - - project_dir - .child("proofs") - .child(format!("{project_name}.proof")) - .assert(predicate::path::is_file()); - - // `nargo verify p` - let mut cmd = Command::cargo_bin("nargo").unwrap(); - cmd.arg("verify"); + cmd.arg("execute"); cmd.assert().success(); } diff --git a/tooling/nargo_fmt/src/config.rs b/tooling/nargo_fmt/src/config.rs index 2bb5d97c0af..5e38dc7d8b0 100644 --- a/tooling/nargo_fmt/src/config.rs +++ b/tooling/nargo_fmt/src/config.rs @@ -45,7 +45,7 @@ config! { max_width: usize, 100, "Maximum width of each line"; tab_spaces: usize, 4, "Number of spaces per tab"; remove_nested_parens: bool, true, "Remove nested parens"; - error_on_lost_comment: bool, true, "Error if unable to get comments"; + error_on_lost_comment: bool, false, "Error if unable to get comments"; short_array_element_width_threshold: usize, 10, "Width threshold for an array element to be considered short"; array_width: usize, 100, "Maximum width of an array literal before falling back to vertical formatting"; fn_call_width: usize, 60, "Maximum width of the args of a function call before falling back to vertical formatting"; diff --git a/tooling/noir_codegen/src/index.ts b/tooling/noir_codegen/src/index.ts index fbbab07bcfe..d00990f01bc 100644 --- a/tooling/noir_codegen/src/index.ts +++ b/tooling/noir_codegen/src/index.ts @@ -1,66 +1,17 @@ -import { AbiType } from '@noir-lang/noirc_abi'; import { CompiledCircuit } from '@noir-lang/types'; -import { PrimitiveTypesUsed, generateTsInterface, codegenStructDefinitions } from './noir_types.js'; - -// TODO: reenable this. See `abiTypeToTs` for reasoning. -// export type FixedLengthArray = L extends 0 ? never[]: T[] & { length: L }; - -const codegenPrelude = `/* Autogenerated file, do not edit! */ - -/* eslint-disable */ - -import { Noir, InputMap, CompiledCircuit, ForeignCallHandler } from "@noir-lang/noir_js" - -export { ForeignCallHandler } from "@noir-lang/noir_js" -`; - -const codegenFunction = ( - name: string, - compiled_program: CompiledCircuit, - function_signature: { inputs: [string, string][]; returnValue: string | null }, -) => { - const args = function_signature.inputs.map(([name]) => `${name}`).join(', '); - const args_with_types = function_signature.inputs.map(([name, type]) => `${name}: ${type}`).join(', '); - - return `export const ${name}_circuit: CompiledCircuit = ${JSON.stringify(compiled_program)}; - -export async function ${name}(${args_with_types}, foreignCallHandler?: ForeignCallHandler): Promise<${ - function_signature.returnValue - }> { - const program = new Noir(${name}_circuit); - const args: InputMap = { ${args} }; - const { returnValue } = await program.execute(args, foreignCallHandler); - return returnValue as ${function_signature.returnValue}; -} -`; +import { TypingsGenerator } from './utils/typings_generator.js'; + +export const codegen = ( + programs: [string, CompiledCircuit][], + embedArtifact: boolean, + useFixedLengthArrays: boolean, +): string => { + return new TypingsGenerator( + programs.map((program) => ({ + circuitName: program[0], + artifact: embedArtifact ? program[1] : undefined, + abi: structuredClone(program[1].abi), // We'll mutate the ABI types when doing typescript codegen, so we clone it to avoid mutating the artifact. + })), + useFixedLengthArrays, + ).codegen(); }; - -export const codegen = (programs: [string, CompiledCircuit][]): string => { - let results = [codegenPrelude]; - const primitiveTypeMap = new Map(); - const structTypeMap = new Map(); - - const functions: string[] = []; - for (const [name, program] of programs) { - const function_sig = generateTsInterface(program.abi, structTypeMap, primitiveTypeMap); - functions.push(codegenFunction(name, stripUnwantedFields(program), function_sig)); - } - - const structTypeDefinitions: string = codegenStructDefinitions(structTypeMap, primitiveTypeMap); - - // Add the primitive Noir types that do not have a 1-1 mapping to TypeScript. - const primitiveTypeAliases: string[] = []; - for (const value of primitiveTypeMap.values()) { - primitiveTypeAliases.push(`export type ${value.aliasName} = ${value.tsType};`); - } - - results = results.concat(...primitiveTypeAliases, '', structTypeDefinitions, ...functions); - - return results.join('\n'); -}; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function stripUnwantedFields(value: any): CompiledCircuit { - const { abi, bytecode } = value; - return { abi, bytecode }; -} diff --git a/tooling/noir_codegen/src/main.ts b/tooling/noir_codegen/src/main.ts index 591e7420dba..835b24a9e48 100644 --- a/tooling/noir_codegen/src/main.ts +++ b/tooling/noir_codegen/src/main.ts @@ -24,7 +24,7 @@ function main() { return [program_name, { abi, bytecode }]; }); - const result = codegen(programs); + const result = codegen(programs, !cliConfig.externalArtifact, cliConfig.useFixedLengthArrays); const outputDir = path.resolve(cliConfig.outDir ?? './codegen'); const outputFile = path.join(outputDir, 'index.ts'); diff --git a/tooling/noir_codegen/src/noir_types.ts b/tooling/noir_codegen/src/noir_types.ts deleted file mode 100644 index 0c0e2b7c60f..00000000000 --- a/tooling/noir_codegen/src/noir_types.ts +++ /dev/null @@ -1,187 +0,0 @@ -import { AbiType, Abi } from '@noir-lang/noirc_abi'; - -/** - * Keep track off all of the Noir primitive types that were used. - * Most of these will not have a 1-1 definition in TypeScript, - * so we will need to generate type aliases for them. - * - * We want to generate type aliases - * for specific types that are used in the ABI. - * - * For example: - * - If `Field` is used we want to alias that - * with `number`. - * - If `u32` is used we want to alias that with `number` too. - */ -export type PrimitiveTypesUsed = { - /** - * The name of the type alias that we will generate. - */ - aliasName: string; - /** - * The TypeScript type that we will alias to. - */ - tsType: string; -}; - -/** - * Typescript does not allow us to check for equality of non-primitive types - * easily, so we create a addIfUnique function that will only add an item - * to the map if it is not already there by using JSON.stringify. - * @param item - The item to add to the map. - */ -function addIfUnique(primitiveTypeMap: Map, item: PrimitiveTypesUsed) { - const key = JSON.stringify(item); - if (!primitiveTypeMap.has(key)) { - primitiveTypeMap.set(key, item); - } -} - -/** - * Converts an ABI type to a TypeScript type. - * @param type - The ABI type to convert. - * @returns The typescript code to define the type. - */ -function abiTypeToTs(type: AbiType, primitiveTypeMap: Map): string { - switch (type.kind) { - case 'field': - addIfUnique(primitiveTypeMap, { aliasName: 'Field', tsType: 'string' }); - return 'Field'; - case 'integer': { - const typeName = type.sign === 'signed' ? `i${type.width}` : `u${type.width}`; - // Javascript cannot safely represent the full range of Noir's integer types as numbers. - // `Number.MAX_SAFE_INTEGER == 2**53 - 1` so we disallow passing numbers to types which may exceed this. - // 52 has been chosen as the cutoff rather than 53 for safety. - const tsType = type.width <= 52 ? `string | number` : `string`; - - addIfUnique(primitiveTypeMap, { aliasName: typeName, tsType }); - return typeName; - } - case 'boolean': - return `boolean`; - case 'array': - // We can't force the usage of fixed length arrays as this currently throws errors in TS. - // The array would need to be `as const` to support this whereas that's unlikely to happen in user code. - // return `FixedLengthArray<${abiTypeToTs(type.type, primitiveTypeMap)}, ${type.length}>`; - return `${abiTypeToTs(type.type, primitiveTypeMap)}[]`; - case 'string': - // We could enforce that literals are the correct length but not generally. - // This would run into similar problems to above. - return `string`; - case 'struct': - return getLastComponentOfPath(type.path); - case 'tuple': { - const field_types = type.fields.map((field) => abiTypeToTs(field, primitiveTypeMap)); - return `[${field_types.join(', ')}]`; - } - default: - throw new Error(`Unknown ABI type ${JSON.stringify(type)}`); - } -} - -/** - * Returns the last component of a path, e.g. "foo::bar::baz" -\> "baz" - * Note: that if we have a path such as "Baz", we will return "Baz". - * - * Since these paths corresponds to structs, we can assume that we - * cannot have "foo::bar::". - * - * We also make the assumption that since these paths are coming from - * Noir, then we will not have two paths that look like this: - * - foo::bar::Baz - * - cat::dog::Baz - * ie the last component of the path (struct name) is enough to uniquely identify - * the whole path. - * - * TODO: We should double check this assumption when we use type aliases, - * I expect that `foo::bar::Baz as Dog` would effectively give `foo::bar::Dog` - * @param str - The path to get the last component of. - * @returns The last component of the path. - */ -function getLastComponentOfPath(str: string): string { - const parts = str.split('::'); - const lastPart = parts[parts.length - 1]; - return lastPart; -} - -/** - * Generates TypeScript interfaces for the structs used in the ABI. - * @param type - The ABI type to generate the interface for. - * @param output - The set of structs that we have already generated bindings for. - * @returns The TypeScript code to define the struct. - */ -function generateStructInterfaces( - type: AbiType, - structsEncountered: Map, - primitiveTypeMap: Map, -) { - // Edge case to handle the array of structs case. - if ( - type.kind === 'array' && - type.type.kind === 'struct' && - !structsEncountered.has(getLastComponentOfPath(type.type.path)) - ) { - generateStructInterfaces(type.type, structsEncountered, primitiveTypeMap); - } - if (type.kind !== 'struct') return; - - const structName = getLastComponentOfPath(type.path); - if (!structsEncountered.has(structName)) { - for (const field of type.fields) { - generateStructInterfaces(field.type, structsEncountered, primitiveTypeMap); - } - structsEncountered.set(structName, type.fields); - } -} - -/** - * Generates a TypeScript interface for the ABI. - * @param abiObj - The ABI to generate the interface for. - * @returns The TypeScript code to define the interface. - */ -export function generateTsInterface( - abiObj: Abi, - structsEncountered: Map, - primitiveTypeMap: Map, -): { inputs: [string, string][]; returnValue: string | null } { - // Define structs for composite types - for (const param of abiObj.parameters) { - generateStructInterfaces(param.type, structsEncountered, primitiveTypeMap); - } - - // Generating Return type, if it exists - if (abiObj.return_type != null) { - generateStructInterfaces(abiObj.return_type.abi_type, structsEncountered, primitiveTypeMap); - } - - return getTsFunctionSignature(abiObj, primitiveTypeMap); -} - -export function codegenStructDefinitions( - structsEncountered: Map, - primitiveTypeMap: Map, -): string { - let codeGeneratedStruct = ''; - - for (const [structName, structFields] of structsEncountered) { - codeGeneratedStruct += `export type ${structName} = {\n`; - for (const field of structFields) { - codeGeneratedStruct += ` ${field.name}: ${abiTypeToTs(field.type, primitiveTypeMap)};\n`; - } - codeGeneratedStruct += `};\n\n`; - } - - return codeGeneratedStruct; -} - -function getTsFunctionSignature( - abi: Abi, - primitiveTypeMap: Map, -): { inputs: [string, string][]; returnValue: string | null } { - const inputs: [string, string][] = abi.parameters.map((param) => [ - param.name, - abiTypeToTs(param.type, primitiveTypeMap), - ]); - const returnValue = abi.return_type ? abiTypeToTs(abi.return_type.abi_type, primitiveTypeMap) : null; - return { inputs, returnValue }; -} diff --git a/tooling/noir_codegen/src/parseArgs.ts b/tooling/noir_codegen/src/parseArgs.ts index 58468c1b8f8..83b6c8bcdb2 100644 --- a/tooling/noir_codegen/src/parseArgs.ts +++ b/tooling/noir_codegen/src/parseArgs.ts @@ -6,6 +6,8 @@ export interface ParsedArgs { files: string[]; outDir?: string | undefined; inputDir?: string | undefined; + externalArtifact: boolean; + useFixedLengthArrays: boolean; } export function parseArgs(): ParsedArgs { @@ -27,6 +29,17 @@ export function parseArgs(): ParsedArgs { 'Directory containing program artifact files. Inferred as lowest common path of all files if not specified.', }, help: { type: Boolean, defaultValue: false, alias: 'h', description: 'Prints this message.' }, + 'external-artifact': { + type: Boolean, + defaultValue: false, + description: + 'Does not embed the circuit artifact in the code, instead requiring passing the circuit artifact as an argument to the generated functions.', + }, + 'fixed-length-arrays': { + type: Boolean, + defaultValue: false, + description: 'Use fixed-length arrays for inputs and outputs.', + }, }, { helpArg: 'help', @@ -53,6 +66,8 @@ export function parseArgs(): ParsedArgs { files: rawOptions.glob, outDir: rawOptions['out-dir'], inputDir: rawOptions['input-dir'], + externalArtifact: rawOptions['external-artifact'], + useFixedLengthArrays: rawOptions['fixed-length-arrays'], }; } @@ -61,4 +76,6 @@ interface CommandLineArgs { 'out-dir'?: string; 'input-dir'?: string; help: boolean; + 'external-artifact': boolean; + 'fixed-length-arrays': boolean; } diff --git a/tooling/noir_codegen/src/utils/abi_type_with_generics.ts b/tooling/noir_codegen/src/utils/abi_type_with_generics.ts new file mode 100644 index 00000000000..844e116f444 --- /dev/null +++ b/tooling/noir_codegen/src/utils/abi_type_with_generics.ts @@ -0,0 +1,139 @@ +import { AbiType } from '@noir-lang/noirc_abi'; + +/** + * Represents a binding to a generic. + */ +export class BindingId { + constructor( + public id: number, + public isNumeric: boolean, + ) {} +} + +export type StructType = { + path: string; + fields: { name: string; type: AbiTypeWithGenerics }[]; + /** The generics of the struct, bound to the fields */ + generics: BindingId[]; +}; + +export type StringType = { + kind: 'string'; + length: number | BindingId | null; +}; + +export type Constant = { + kind: 'constant'; + value: number; +}; + +export type ArrayType = { + kind: 'array'; + length: number | BindingId | null; + type: AbiTypeWithGenerics; +}; + +export type Tuple = { + kind: 'tuple'; + fields: AbiTypeWithGenerics[]; +}; + +export type Struct = { + kind: 'struct'; + structType: StructType; + /** The arguments are the concrete instantiation of the generics in the struct type. */ + args: AbiTypeWithGenerics[]; +}; + +export type AbiTypeWithGenerics = + | { kind: 'field' } + | { kind: 'boolean' } + | { kind: 'integer'; sign: string; width: number } + | { kind: 'binding'; id: BindingId } + | { kind: 'constant'; value: number } + | StringType + | ArrayType + | Tuple + | Struct; + +/** + * Maps an ABI type to an ABI type with generics. + * This performs pure type conversion, and does not generate any bindings. + */ +export function mapAbiTypeToAbiTypeWithGenerics(abiType: AbiType): AbiTypeWithGenerics { + switch (abiType.kind) { + case 'field': + case 'boolean': + case 'string': + case 'integer': + return abiType; + case 'array': + return { + kind: 'array', + length: abiType.length, + type: mapAbiTypeToAbiTypeWithGenerics(abiType.type), + }; + case 'struct': { + const structType = { + path: abiType.path, + fields: abiType.fields.map((field) => ({ + name: field.name, + type: mapAbiTypeToAbiTypeWithGenerics(field.type), + })), + generics: [], + }; + return { + kind: 'struct', + structType, + args: [], + }; + } + case 'tuple': + return { + kind: 'tuple', + fields: abiType.fields.map(mapAbiTypeToAbiTypeWithGenerics), + }; + default: { + const exhaustiveCheck: never = abiType; + throw new Error(`Unhandled abi type: ${exhaustiveCheck}`); + } + } +} + +/** + * Finds the structs in an ABI type. + * This won't explore nested structs. + */ +export function findStructsInType(abiType: AbiTypeWithGenerics): Struct[] { + switch (abiType.kind) { + case 'field': + case 'boolean': + case 'string': + case 'integer': + return []; + case 'array': + return findStructsInType(abiType.type); + case 'tuple': + return abiType.fields.flatMap(findStructsInType); + case 'struct': + return [abiType]; + default: { + return []; + } + } +} + +/** + * Finds all the structs in an ABI type, including nested structs. + */ +export function findAllStructsInType(abiType: AbiTypeWithGenerics): Struct[] { + let allStructs: Struct[] = []; + let lastStructs = findStructsInType(abiType); + while (lastStructs.length > 0) { + allStructs = allStructs.concat(lastStructs); + lastStructs = lastStructs.flatMap((struct) => + struct.structType.fields.flatMap((field) => findStructsInType(field.type)), + ); + } + return allStructs; +} diff --git a/tooling/noir_codegen/src/utils/demonomorphizer.ts b/tooling/noir_codegen/src/utils/demonomorphizer.ts new file mode 100644 index 00000000000..2b33b574557 --- /dev/null +++ b/tooling/noir_codegen/src/utils/demonomorphizer.ts @@ -0,0 +1,284 @@ +import { + type AbiTypeWithGenerics, + type ArrayType, + BindingId, + type Constant, + type StringType, + type Struct, + type StructType, + type Tuple, + findAllStructsInType, + findStructsInType, +} from './abi_type_with_generics.js'; + +export interface DemonomorphizerConfig { + leaveArrayLengthsUnbounded: boolean; + leaveStringLengthsUnbounded: boolean; +} + +/** + * Demonomorphizes a list of ABI types adding generics to structs. + * Since monomorphization of the generics destroys information, this process is not guaranteed to return the original structure. + * However, it should successfully unify all struct types that share the same name and field names. + */ +export class Demonomorphizer { + private variantsMap: Map; + private visitedStructs: Map; + private lastBindingId = 0; + + /** + * Demonomorphizes the passed in ABI types, mutating them. + */ + public static demonomorphize(abiTypes: AbiTypeWithGenerics[], config: DemonomorphizerConfig) { + new Demonomorphizer(abiTypes, config); + } + + private constructor( + private types: AbiTypeWithGenerics[], + private config: DemonomorphizerConfig, + ) { + this.variantsMap = new Map(); + this.fillVariantsMap(); + + this.visitedStructs = new Map(); + this.demonomorphizeStructs(); + } + + /** + * Finds all the variants of the structs in the types. + * A variant is every use of a struct with the same name and fields. + */ + private fillVariantsMap() { + const allStructs = this.types.flatMap(findAllStructsInType); + for (const struct of allStructs) { + const id = Demonomorphizer.buildIdForStruct(struct.structType); + const variants = this.variantsMap.get(id) ?? []; + variants.push(struct); + this.variantsMap.set(id, variants); + } + } + + private demonomorphizeStructs() { + for (const type of this.types) { + const topLevelStructs = findStructsInType(type); + for (const struct of topLevelStructs) { + this.demonomorphizeStruct(struct); + } + } + } + + /** + * Demonomorphizes a struct, by demonomorphizing its dependencies first. + * Then it'll unify the types of the variants generating a unique generic type. + * It'll also generate args that instantiate the generic type with the concrete arguments for each variant. + */ + private demonomorphizeStruct(struct: Struct) { + const id = Demonomorphizer.buildIdForStruct(struct.structType); + if (this.visitedStructs.has(id)) { + return; + } + const dependencies = struct.structType.fields.flatMap((field) => findStructsInType(field.type)); + for (const dependency of dependencies) { + this.demonomorphizeStruct(dependency); + } + if (this.visitedStructs.has(id)) { + throw new Error('Circular dependency detected'); + } + + const variants = this.variantsMap.get(id)!; + const mappedStructType = struct.structType; + + for (let i = 0; i < struct.structType.fields.length; i++) { + const variantTypes = variants.map((variant) => variant.structType.fields[i].type); + const mappedType = this.unifyTypes(variantTypes, mappedStructType.generics, variants); + mappedStructType.fields[i].type = mappedType; + } + + // Mutate variants setting the new struct type + variants.forEach((variant) => (variant.structType = mappedStructType)); + + this.visitedStructs.set(id, mappedStructType); + } + + /** + * Tries to unify the types of a set of variants recursively. + * Unification will imply replacing some properties with bindings and pushing bindings to the generics of the struct. + */ + private unifyTypes( + types: AbiTypeWithGenerics[], + generics: BindingId[], // Mutates generics adding new bindings + variants: Struct[], // mutates variants adding different args to the variants + ): AbiTypeWithGenerics { + const kinds = new Set(types.map((type) => type.kind)); + if (kinds.size > 1) { + return this.buildBindingAndPushToVariants(types, generics, variants); + } + switch (types[0].kind) { + case 'field': + case 'boolean': + case 'binding': + return types[0]; + case 'integer': { + if (allDeepEqual(types)) { + return types[0]; + } else { + return this.buildBindingAndPushToVariants(types, generics, variants); + } + } + case 'string': { + const strings = types as StringType[]; + const unifiedStringType = strings[0]; + if (strings.every((string) => string.length === unifiedStringType.length)) { + return unifiedStringType; + } else if (!this.config.leaveStringLengthsUnbounded) { + unifiedStringType.length = this.buildNumericBindingAndPushToVariants( + strings.map((string) => { + if (typeof string.length !== 'number') { + throw new Error('Trying to unify strings with bindings'); + } + return string.length; + }), + generics, + variants, + ); + return unifiedStringType; + } else { + unifiedStringType.length = null; + return unifiedStringType; + } + } + case 'array': { + const arrays = types as ArrayType[]; + const unifiedArrayType: ArrayType = arrays[0]; + if (!arrays.every((array) => array.length === unifiedArrayType.length)) { + if (!this.config.leaveArrayLengthsUnbounded) { + unifiedArrayType.length = this.buildNumericBindingAndPushToVariants( + arrays.map((array) => { + if (typeof array.length !== 'number') { + throw new Error('Trying to unify arrays with bindings'); + } + return array.length; + }), + generics, + variants, + ); + } else { + unifiedArrayType.length = null; + } + } + + unifiedArrayType.type = this.unifyTypes( + arrays.map((array) => array.type), + generics, + variants, + ); + return unifiedArrayType; + } + case 'tuple': { + const tuples = types as Tuple[]; + const unifiedTupleType: Tuple = tuples[0]; + for (let i = 0; i < unifiedTupleType.fields.length; i++) { + unifiedTupleType.fields[i] = this.unifyTypes( + tuples.map((tuple) => tuple.fields[i]), + generics, + variants, + ); + } + return unifiedTupleType; + } + case 'struct': { + const structs = types as Struct[]; + const ids = new Set(structs.map((struct) => Demonomorphizer.buildIdForStruct(struct.structType))); + if (ids.size > 1) { + // If the types are different structs, we can only unify them by creating a new binding. + // For example, if we have a struct A { x: u32 } and a struct A { x: Field }, the only possible unification is A { x: T } + return this.buildBindingAndPushToVariants(types, generics, variants); + } else { + // If the types are the same struct, we must unify the arguments to the struct. + // For example, if we have A and A, we need to unify to A and push T to the generics of the struct type. + const unifiedStruct = structs[0]; + + if (!structs.every((struct) => struct.args.length === unifiedStruct.args.length)) { + throw new Error('Same struct with different number of args encountered'); + } + for (let i = 0; i < unifiedStruct.args.length; i++) { + const argTypes = structs.map((struct) => struct.args[i]); + unifiedStruct.args[i] = this.unifyTypes(argTypes, generics, variants); + } + return unifiedStruct; + } + } + + case 'constant': { + const constants = types as Constant[]; + if (constants.every((constant) => constant.value === constants[0].value)) { + return constants[0]; + } else { + return this.buildBindingAndPushToVariants(types, generics, variants, true); + } + } + + default: { + const exhaustiveCheck: never = types[0]; + throw new Error(`Unhandled abi type: ${exhaustiveCheck}`); + } + } + } + + /** + * We consider a struct to be the same if it has the same name and field names. + * Structs with the same id will be unified into a single type by the demonomorphizer. + */ + public static buildIdForStruct(struct: StructType): string { + const name = struct.path.split('::').pop()!; + const fields = struct.fields.map((field) => field.name).join(','); + return `${name}(${fields})`; + } + + private buildBindingAndPushToVariants( + concreteTypes: AbiTypeWithGenerics[], + generics: BindingId[], + variants: Struct[], + isNumeric = false, + ): AbiTypeWithGenerics { + const bindingId = new BindingId(this.lastBindingId++, isNumeric); + + for (let i = 0; i < variants.length; i++) { + const variant = variants[i]; + const concreteType = concreteTypes[i]; + variant.args.push(concreteType); + } + + generics.push(bindingId); + return { kind: 'binding', id: bindingId }; + } + + private buildNumericBindingAndPushToVariants( + concreteNumbers: number[], + generics: BindingId[], + variants: Struct[], + ): BindingId { + const bindingId = new BindingId(this.lastBindingId++, true); + + for (let i = 0; i < variants.length; i++) { + const variant = variants[i]; + variant.args.push({ kind: 'constant', value: concreteNumbers[i] }); + } + + generics.push(bindingId); + return bindingId; + } +} + +function allDeepEqual(arr: T[]): boolean { + if (arr.length === 0) { + return true; + } + const first = JSON.stringify(arr[0]); + for (let i = 0; i < arr.length; i++) { + if (JSON.stringify(arr[i]) !== first) { + return false; + } + } + return true; +} diff --git a/tooling/noir_codegen/src/utils/typings_generator.ts b/tooling/noir_codegen/src/utils/typings_generator.ts new file mode 100644 index 00000000000..36d2de140f0 --- /dev/null +++ b/tooling/noir_codegen/src/utils/typings_generator.ts @@ -0,0 +1,324 @@ +import { CompiledCircuit } from '@noir-lang/types'; +import { + AbiTypeWithGenerics, + BindingId, + StructType, + findAllStructsInType, + mapAbiTypeToAbiTypeWithGenerics, +} from './abi_type_with_generics.js'; +import { Demonomorphizer } from './demonomorphizer.js'; +import { Abi } from '@noir-lang/noirc_abi'; + +const codegenPrelude = `/* Autogenerated file, do not edit! */ + +/* eslint-disable */ + +import { Noir, InputMap, CompiledCircuit, ForeignCallHandler } from "@noir-lang/noir_js" + +export { ForeignCallHandler } from "@noir-lang/noir_js" +`; +/** + * Keep track off all of the Noir primitive types that were used. + * Most of these will not have a 1-1 definition in TypeScript, + * so we will need to generate type aliases for them. + * + * We want to generate type aliases + * for specific types that are used in the ABI. + * + * For example: + * - If `Field` is used we want to alias that + * with `number`. + * - If `u32` is used we want to alias that with `number` too. + */ +type PrimitiveTypesUsed = { + /** + * The name of the type alias that we will generate. + */ + aliasName: string; + /** + * The TypeScript type that we will alias to. + */ + tsType: string; +}; + +/** + * Returns the last component of a path, e.g. "foo::bar::baz" -\> "baz" + * Note: that if we have a path such as "Baz", we will return "Baz". + * + * Since these paths corresponds to structs, we can assume that we + * cannot have "foo::bar::". + * + * We also make the assumption that since these paths are coming from + * Noir, then we will not have two paths that look like this: + * - foo::bar::Baz + * - cat::dog::Baz + * ie the last component of the path (struct name) is enough to uniquely identify + * the whole path. + * + * TODO: We should double check this assumption when we use type aliases, + * I expect that `foo::bar::Baz as Dog` would effectively give `foo::bar::Dog` + * @param str - The path to get the last component of. + * @returns The last component of the path. + */ +function getLastComponentOfPath(str: string): string { + const parts = str.split('::'); + const lastPart = parts[parts.length - 1]; + return lastPart; +} + +/** + * Replaces a numeric binding with the corresponding generics name or the actual value. + */ +function replaceNumericBinding(id: number | BindingId, genericsNameMap: Map): string { + if (typeof id === 'number') { + return id.toString(); + } else { + return genericsNameMap.get(id.id) ?? 'unknown'; + } +} + +export class TypingsGenerator { + /** All the types in the ABIs */ + private allTypes: AbiTypeWithGenerics[] = []; + /** The demonomorphized ABIs of the circuits */ + private demonomorphizedAbis: { + circuitName: string; + params: { name: string; type: AbiTypeWithGenerics }[]; + returnType?: AbiTypeWithGenerics; + artifact?: CompiledCircuit; + }[] = []; + /** Maps struct id to name for structs with the same name and different field sets */ + private structIdToTsName = new Map(); + /** Collect all the primitives used in the types to add them to the codegen */ + private primitiveTypesUsed = new Map(); + + constructor( + circuits: { abi: Abi; circuitName: string; artifact?: CompiledCircuit }[], + private useFixedLengthArrays: boolean, + ) { + // Map all the types used in the ABIs to the demonomorphized types + for (const { abi, circuitName, artifact } of circuits) { + const params = abi.parameters.map((param) => { + const type = mapAbiTypeToAbiTypeWithGenerics(param.type); + this.allTypes.push(type); + return { name: param.name, type }; + }); + if (abi.return_type) { + const returnType = mapAbiTypeToAbiTypeWithGenerics(abi.return_type.abi_type); + this.allTypes.push(returnType); + this.demonomorphizedAbis.push({ circuitName, params, returnType, artifact }); + } else { + this.demonomorphizedAbis.push({ circuitName, params, artifact }); + } + } + // Demonomorphize the types + Demonomorphizer.demonomorphize(this.allTypes, { + leaveArrayLengthsUnbounded: !useFixedLengthArrays, + leaveStringLengthsUnbounded: true, + }); + } + + public codegen(): string { + this.primitiveTypesUsed = new Map(); + const structsCode = this.codegenAllStructs(); + const interfacesCode = this.codegenAllInterfaces(); + const primitivesCode = this.codegenAllPrimitives(); + + return ` +${codegenPrelude} +${primitivesCode} +${structsCode} +${interfacesCode}`; + } + + private codegenAllStructs(): string { + const allStructs = this.allTypes.flatMap(findAllStructsInType); + // First, deduplicate the structs used + const structTypesToExport = new Map(); + for (const struct of allStructs) { + const id = Demonomorphizer.buildIdForStruct(struct.structType); + if (structTypesToExport.has(id)) { + continue; + } + structTypesToExport.set(id, struct.structType); + } + + // Then, we have to consider the case where we have struct with the same name but different fields. + // For those, we'll naively append a number to the name. + const idsPerName = new Map(); + for (const [id, structType] of structTypesToExport.entries()) { + const name = getLastComponentOfPath(structType.path); + const ids = idsPerName.get(name) ?? []; + ids.push(id); + idsPerName.set(name, ids); + } + + this.structIdToTsName = new Map(); + for (const [name, ids] of idsPerName.entries()) { + if (ids.length !== 1) { + ids.forEach((id, index) => { + this.structIdToTsName.set(id, `${name}${index + 1}`); + }); + } + } + // Now we can just generate the code for the structs + let resultCode = ''; + + for (const structType of structTypesToExport.values()) { + resultCode += this.codegenStructType(structType); + } + + return resultCode; + } + + private getStructName(structType: StructType): string { + return ( + this.structIdToTsName.get(Demonomorphizer.buildIdForStruct(structType)) || getLastComponentOfPath(structType.path) + ); + } + + private codegenStructType(structType: StructType): string { + // Generate names for the generic bindings. + const genericsNameMap = new Map(); + structType.generics.forEach((generic, index) => { + genericsNameMap.set(generic.id, String.fromCharCode('A'.charCodeAt(0) + index)); + }); + + const name = this.getStructName(structType); + const generics = structType.generics.length + ? `<${structType.generics + .map((generic) => `${genericsNameMap.get(generic.id)}${generic.isNumeric ? ' extends number' : ''}`) + .join(', ')}>` + : ''; + + let resultCode = `export type ${name}${generics} = {\n`; + + for (const field of structType.fields) { + resultCode += ` ${field.name}: ${this.codegenType(field.type, genericsNameMap)};\n`; + } + + resultCode += '}\n\n'; + + return resultCode; + } + + private codegenType(type: AbiTypeWithGenerics, genericsNameMap: Map): string { + switch (type.kind) { + case 'field': + this.addIfUnique({ aliasName: 'Field', tsType: 'string' }); + return 'Field'; + case 'boolean': + return 'boolean'; + case 'integer': { + const typeName = type.sign === 'signed' ? `i${type.width}` : `u${type.width}`; + // Even though noir accepts numbers or strings for integers, it always returns strings + // So we must use string as the type here. + this.addIfUnique({ aliasName: typeName, tsType: 'string' }); + return typeName; + } + case 'binding': + return genericsNameMap.get(type.id.id) ?? 'unknown'; + case 'constant': + return type.value.toString(); + case 'string': + return `string`; + case 'array': + if (this.useFixedLengthArrays) { + if (type.length === null) { + throw new Error('Got unbounded array with fixed length arrays enabled'); + } + return `FixedLengthArray<${this.codegenType(type.type, genericsNameMap)}, ${replaceNumericBinding( + type.length, + genericsNameMap, + )}>`; + } else { + return `${this.codegenType(type.type, genericsNameMap)}[]`; + } + case 'tuple': { + const fieldTypes = type.fields.map((field) => this.codegenType(field, genericsNameMap)); + return `[${fieldTypes.join(', ')}]`; + } + case 'struct': { + const name = this.getStructName(type.structType); + if (type.args.length) { + const args = type.args.map((arg) => this.codegenType(arg, genericsNameMap)).join(', '); + return `${name}<${args}>`; + } else { + return name; + } + } + } + } + + /** + * Typescript does not allow us to check for equality of non-primitive types + * easily, so we create a addIfUnique function that will only add an item + * to the map if it is not already there by using JSON.stringify. + * @param item - The item to add to the map. + */ + private addIfUnique(item: PrimitiveTypesUsed) { + const key = JSON.stringify(item); + if (!this.primitiveTypesUsed.has(key)) { + this.primitiveTypesUsed.set(key, item); + } + } + + /** + * Codegen all the interfaces for the circuits. + * For a circuit named Foo, we'll codegen FooInputType and FooReturnType. + */ + private codegenAllInterfaces(): string { + let resultCode = ''; + for (const { circuitName, params, returnType, artifact } of this.demonomorphizedAbis) { + const functionSignature = { + inputs: params.map((param): [string, string] => [param.name, this.codegenType(param.type, new Map())]), + returnValue: returnType ? this.codegenType(returnType, new Map()) : null, + }; + resultCode += this.codegenStructType({ + path: `${circuitName}InputType`, + fields: params, + generics: [], + }); + + if (returnType) { + resultCode += `export type ${circuitName}ReturnType = ${this.codegenType(returnType, new Map())};\n`; + } + + resultCode += codegenFunction(circuitName, functionSignature, artifact); + } + return resultCode; + } + + private codegenAllPrimitives(): string { + let primitiveTypeAliases = this.useFixedLengthArrays + ? 'export type FixedLengthArray = L extends 0 ? never[]: T[] & { length: L }\n' + : ''; + for (const [, value] of this.primitiveTypesUsed) { + primitiveTypeAliases += `export type ${value.aliasName} = ${value.tsType};\n`; + } + return primitiveTypeAliases; + } +} + +const codegenFunction = ( + name: string, + function_signature: { inputs: [string, string][]; returnValue: string | null }, + compiled_program?: CompiledCircuit, +): string => { + const args = function_signature.inputs.map(([name]) => `${name}`).join(', '); + const args_with_types = function_signature.inputs.map(([name, type]) => `${name}: ${type}`).join(', '); + + const artifact = compiled_program + ? `export const ${name}_circuit: CompiledCircuit = ${JSON.stringify(compiled_program)};` + : ''; + + return `${artifact} + +export async function ${name}(${args_with_types}${compiled_program ? '' : `, ${name}_circuit: CompiledCircuit`}, foreignCallHandler?: ForeignCallHandler): Promise<${function_signature.returnValue}> { + const program = new Noir(${name}_circuit); + const args: InputMap = { ${args} }; + const { returnValue } = await program.execute(args, foreignCallHandler); + return returnValue as ${function_signature.returnValue}; +} +`; +}; diff --git a/tooling/noir_codegen/test/index.test.ts b/tooling/noir_codegen/test/index.test.ts index 03fb680a537..afc7769ed9e 100644 --- a/tooling/noir_codegen/test/index.test.ts +++ b/tooling/noir_codegen/test/index.test.ts @@ -1,18 +1,18 @@ import { expect } from 'chai'; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore File is codegenned at test time. -import { exported_function_foo, MyStruct, u64, ForeignCallHandler } from './codegen/index.js'; +import { exported_function_foo, MyStruct, u64, u32, ForeignCallHandler } from './codegen/index.js'; it('codegens a callable function', async () => { - const my_struct = { foo: true, bar: ['12345', '12345', '12345'], baz: '0x00' }; + const my_struct = { foo: true, bar: ['123', '123', '123', '123'], baz: '0x00' }; - const [sum, constant, struct]: [u64, u64, MyStruct] = await exported_function_foo( + const [sum, constant, struct]: [u64, u32, MyStruct] = await exported_function_foo( '2', '3', - [0, 0, 0, 0, 0], + ['0x00', '0x00', '0x00', '0x00', '0x00'], { foo: my_struct, - bar: [my_struct, my_struct, my_struct], + bar: [my_struct, my_struct], baz: '64', }, '12345', @@ -35,15 +35,15 @@ it('allows passing a custom foreign call handler', async () => { return []; }; - const my_struct = { foo: true, bar: ['12345', '12345', '12345'], baz: '0x00' }; + const my_struct = { foo: true, bar: ['123', '123', '123', '123'], baz: '0x00' }; - const [sum, constant, struct]: [u64, u64, MyStruct] = await exported_function_foo( + const [sum, constant, struct]: [u64, u32, MyStruct] = await exported_function_foo( '2', '3', - [0, 0, 0, 0, 0], + ['0x00', '0x00', '0x00', '0x00', '0x00'], { foo: my_struct, - bar: [my_struct, my_struct, my_struct], + bar: [my_struct, my_struct], baz: '64', }, '12345', diff --git a/tooling/noir_codegen/test/test_lib/src/lib.nr b/tooling/noir_codegen/test/test_lib/src/lib.nr index 23607c6f65f..4915b0a2c49 100644 --- a/tooling/noir_codegen/test/test_lib/src/lib.nr +++ b/tooling/noir_codegen/test/test_lib/src/lib.nr @@ -1,17 +1,23 @@ -struct MyStruct { +struct MyStruct { foo: bool, - bar: [str<5>; 3], + bar: [str; BAR_SIZE], baz: Field } -struct NestedStruct { - foo: MyStruct, - bar: [MyStruct; 3], - baz: u64 +struct NestedStruct { + foo: MyStruct, + bar: [MyStruct; BAR_SIZE], + baz: BAZ_TYP } #[export] -fn exported_function_foo(x: u64, y: u64, array: [u8; 5], my_struct: NestedStruct, string: str<5>) -> (u64, u64, MyStruct) { +fn exported_function_foo( + x: u64, + y: u64, + array: [u8; 5], + my_struct: NestedStruct<2,3,4, Field>, + string: str<5> +) -> (u64, u32, MyStruct<3, 4>) { assert(array.len() == 5); assert(my_struct.foo.foo); assert(string == "12345"); @@ -22,6 +28,6 @@ fn exported_function_foo(x: u64, y: u64, array: [u8; 5], my_struct: NestedStruct } #[export] -fn exported_function_bar(my_struct: NestedStruct) -> (u64) { +fn exported_function_bar(my_struct: NestedStruct<1,2,3, u64>) -> (u64) { my_struct.baz } diff --git a/tooling/noir_js_backend_barretenberg/package.json b/tooling/noir_js_backend_barretenberg/package.json index 6adf8749aba..10fd14a0090 100644 --- a/tooling/noir_js_backend_barretenberg/package.json +++ b/tooling/noir_js_backend_barretenberg/package.json @@ -42,7 +42,7 @@ "lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0" }, "dependencies": { - "@aztec/bb.js": "0.38.0", + "@aztec/bb.js": "0.41.0", "@noir-lang/types": "workspace:*", "fflate": "^0.8.0" }, diff --git a/yarn.lock b/yarn.lock index 85966ce3392..8fb574afa30 100644 --- a/yarn.lock +++ b/yarn.lock @@ -221,9 +221,9 @@ __metadata: languageName: node linkType: hard -"@aztec/bb.js@npm:0.38.0": - version: 0.38.0 - resolution: "@aztec/bb.js@npm:0.38.0" +"@aztec/bb.js@npm:0.41.0": + version: 0.41.0 + resolution: "@aztec/bb.js@npm:0.41.0" dependencies: comlink: ^4.4.1 commander: ^10.0.1 @@ -231,7 +231,7 @@ __metadata: tslib: ^2.4.0 bin: bb.js: dest/node/main.js - checksum: 5ebc2850f37993db1d0fe4306ec612e9df14c5d227e1451f1b2f96e63e61c64225c46b32d1e1d2a1a0c37795e50b2875362520e9eb49324312516ec9fd6de2c7 + checksum: e5e0095eaff3de45726366726337b131bb6ff7cf2cb53be705572c7d6715dae4c948bf86a03cfad68bc98c0c2d83e64cbe3723cc72260c8dbfa262af8cb81f9b languageName: node linkType: hard @@ -4396,7 +4396,7 @@ __metadata: version: 0.0.0-use.local resolution: "@noir-lang/backend_barretenberg@workspace:tooling/noir_js_backend_barretenberg" dependencies: - "@aztec/bb.js": 0.38.0 + "@aztec/bb.js": 0.41.0 "@noir-lang/types": "workspace:*" "@types/node": ^20.6.2 "@types/prettier": ^3 From 533d10eec83711f19a39848f86b10a18f480506d Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Wed, 22 May 2024 14:23:55 +0100 Subject: [PATCH 18/61] chore: use `bbup` to install `bb` (#5073) # Description ## Problem\* Resolves ## Summary\* `bbup` is now in master so we can use it to install `bb` ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .github/workflows/test-js-packages.yml | 6 ++---- cspell.json | 1 + .../docs/getting_started/barretenberg/index.md | 18 ++++++------------ scripts/install_bb.sh | 14 ++++++++------ 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/.github/workflows/test-js-packages.yml b/.github/workflows/test-js-packages.yml index 9668e3f629f..db162e21269 100644 --- a/.github/workflows/test-js-packages.yml +++ b/.github/workflows/test-js-packages.yml @@ -402,8 +402,7 @@ jobs: - name: Install `bb` run: | ./scripts/install_bb.sh - echo "$HOME/.barretenberg/" >> $GITHUB_PATH - export PATH="$PATH:$HOME/.barretenberg/" + echo "$HOME/.bb/" >> $GITHUB_PATH - name: Download nargo binary uses: actions/download-artifact@v4 @@ -512,8 +511,7 @@ jobs: - name: Install `bb` run: | ./scripts/install_bb.sh - echo "$HOME/.barretenberg/" >> $GITHUB_PATH - export PATH="$PATH:$HOME/.barretenberg/" + echo "$HOME/.bb/" >> $GITHUB_PATH - name: Download nargo binary uses: actions/download-artifact@v4 diff --git a/cspell.json b/cspell.json index b4f214c2f27..4497d0bf9da 100644 --- a/cspell.json +++ b/cspell.json @@ -19,6 +19,7 @@ "barebones", "barretenberg", "barustenberg", + "bbup", "bincode", "bindgen", "bitand", diff --git a/docs/docs/getting_started/barretenberg/index.md b/docs/docs/getting_started/barretenberg/index.md index 048ba39f046..0102c86770b 100644 --- a/docs/docs/getting_started/barretenberg/index.md +++ b/docs/docs/getting_started/barretenberg/index.md @@ -23,31 +23,25 @@ Open a terminal on your machine, and write: ##### macOS (Apple Silicon) ```bash -mkdir -p $HOME/.barretenberg && \ -curl -o ./barretenberg-aarch64-apple-darwin.tar.gz -L https://github.com/AztecProtocol/aztec-packages/releases/download/aztec-packages-v0.38.0/barretenberg-aarch64-apple-darwin.tar.gz && \ -tar -xvf ./barretenberg-aarch64-apple-darwin.tar.gz -C $HOME/.barretenberg/ && \ -echo 'export PATH=$PATH:$HOME/.barretenberg/' >> ~/.zshrc && \ +curl -L https://raw.githubusercontent.com/AztecProtocol/aztec-packages/master/barretenberg/cpp/installation/install | bash source ~/.zshrc +bbup -v 0.41.0 ``` ##### macOS (Intel) ```bash -mkdir -p $HOME/.barretenberg && \ -curl -o ./barretenberg-x86_64-apple-darwin.tar.gz -L https://github.com/AztecProtocol/aztec-packages/releases/download/aztec-packages-v0.38.0/barretenberg-x86_64-apple-darwin.tar.gz && \ -tar -xvf ./barretenberg-x86_64-apple-darwin.tar.gz -C $HOME/.barretenberg/ && \ -echo 'export PATH=$PATH:$HOME/.barretenberg/' >> ~/.zshrc && \ +curl -L https://raw.githubusercontent.com/AztecProtocol/aztec-packages/master/barretenberg/cpp/installation/install | bash source ~/.zshrc +bbup -v 0.41.0 ``` ##### Linux (Bash) ```bash -mkdir -p $HOME/.barretenberg && \ -curl -o ./barretenberg-x86_64-linux-gnu.tar.gz -L https://github.com/AztecProtocol/aztec-packages/releases/download/aztec-packages-v0.38.0/barretenberg-x86_64-linux-gnu.tar.gz && \ -tar -xvf ./barretenberg-x86_64-linux-gnu.tar.gz -C $HOME/.barretenberg/ && \ -echo -e 'export PATH=$PATH:$HOME/.barretenberg/' >> ~/.bashrc && \ +curl -L https://raw.githubusercontent.com/AztecProtocol/aztec-packages/master/barretenberg/cpp/installation/install | bash source ~/.bashrc +bbup -v 0.41.0 ``` Now we're ready to start working on [our first Noir program!](../hello_noir/index.md) diff --git a/scripts/install_bb.sh b/scripts/install_bb.sh index 519ffe6cb03..c3ed476200a 100755 --- a/scripts/install_bb.sh +++ b/scripts/install_bb.sh @@ -1,9 +1,11 @@ #!/bin/bash -# We use this script just for CI so we assume we're running on x86 linux +VERSION="0.41.0" -mkdir -p $HOME/.barretenberg -curl -o ./barretenberg-x86_64-linux-gnu.tar.gz -L https://github.com/AztecProtocol/aztec-packages/releases/download/aztec-packages-v0.41.0/barretenberg-x86_64-linux-gnu.tar.gz -tar -xvf ./barretenberg-x86_64-linux-gnu.tar.gz -C $HOME/.barretenberg/ -echo 'export PATH=$PATH:$HOME/.barretenberg/' >> ~/.bashrc -source ~/.bashrc +BBUP_PATH=~/.bb/bbup + +if ! [ -f $BBUP_PATH ]; then + curl -L https://raw.githubusercontent.com/AztecProtocol/aztec-packages/master/barretenberg/cpp/installation/install | bash +fi + +$BBUP_PATH -v $VERSION From 9420d7c2ba6bbbf5ecb9a066837c505310955b6c Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Wed, 22 May 2024 14:55:28 +0100 Subject: [PATCH 19/61] feat: remove conditional compilation of `bn254_blackbox_solver` (#5058) # Description ## Problem\* Resolves ## Summary\* This PR removes the conditional compilation on `Bn254BlackBoxSolver` as it's no longer necessary. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- acvm-repo/acvm_js/src/execute.rs | 57 ++++++------------- .../benches/criterion.rs | 12 ++-- acvm-repo/bn254_blackbox_solver/src/lib.rs | 19 +------ tooling/acvm_cli/src/cli/execute_cmd.rs | 3 +- tooling/nargo_cli/src/cli/dap_cmd.rs | 5 +- tooling/nargo_cli/src/cli/debug_cmd.rs | 4 +- tooling/nargo_cli/src/cli/execute_cmd.rs | 4 +- tooling/nargo_cli/src/cli/lsp_cmd.rs | 3 +- 8 files changed, 30 insertions(+), 77 deletions(-) diff --git a/acvm-repo/acvm_js/src/execute.rs b/acvm-repo/acvm_js/src/execute.rs index 338511874c9..9f2b07b31fc 100644 --- a/acvm-repo/acvm_js/src/execute.rs +++ b/acvm-repo/acvm_js/src/execute.rs @@ -20,11 +20,11 @@ use crate::{ }; #[wasm_bindgen] -pub struct WasmBlackBoxFunctionSolver(Bn254BlackBoxSolver); +pub struct WasmBlackBoxFunctionSolver; impl WasmBlackBoxFunctionSolver { async fn initialize() -> WasmBlackBoxFunctionSolver { - WasmBlackBoxFunctionSolver(Bn254BlackBoxSolver::initialize().await) + WasmBlackBoxFunctionSolver } } @@ -47,15 +47,9 @@ pub async fn execute_circuit( ) -> Result { console_error_panic_hook::set_once(); - let solver = WasmBlackBoxFunctionSolver::initialize().await; - - let mut witness_stack = execute_program_with_native_type_return( - &solver, - program, - initial_witness, - &foreign_call_handler, - ) - .await?; + let mut witness_stack = + execute_program_with_native_type_return(program, initial_witness, &foreign_call_handler) + .await?; let witness_map = witness_stack.pop().expect("Should have at least one witness on the stack").witness; Ok(witness_map.into()) @@ -71,7 +65,7 @@ pub async fn execute_circuit( /// @returns {SolvedAndReturnWitness} The solved witness calculated by executing the circuit on the provided inputs, as well as the return witness indices as specified by the circuit. #[wasm_bindgen(js_name = executeCircuitWithReturnWitness, skip_jsdoc)] pub async fn execute_circuit_with_return_witness( - solver: &WasmBlackBoxFunctionSolver, + _solver: &WasmBlackBoxFunctionSolver, program: Vec, initial_witness: JsWitnessMap, foreign_call_handler: ForeignCallHandler, @@ -82,7 +76,6 @@ pub async fn execute_circuit_with_return_witness( .map_err(|_| JsExecutionError::new("Failed to deserialize circuit. This is likely due to differing serialization formats between ACVM_JS and your compiler".to_string(), None, None))?; let mut witness_stack = execute_program_with_native_program_and_return( - solver, &program, initial_witness, &foreign_call_handler, @@ -108,20 +101,16 @@ pub async fn execute_circuit_with_return_witness( /// @returns {WitnessMap} The solved witness calculated by executing the circuit on the provided inputs. #[wasm_bindgen(js_name = executeCircuitWithBlackBoxSolver, skip_jsdoc)] pub async fn execute_circuit_with_black_box_solver( - solver: &WasmBlackBoxFunctionSolver, + _solver: &WasmBlackBoxFunctionSolver, program: Vec, initial_witness: JsWitnessMap, foreign_call_handler: ForeignCallHandler, ) -> Result { console_error_panic_hook::set_once(); - let mut witness_stack = execute_program_with_native_type_return( - solver, - program, - initial_witness, - &foreign_call_handler, - ) - .await?; + let mut witness_stack = + execute_program_with_native_type_return(program, initial_witness, &foreign_call_handler) + .await?; let witness_map = witness_stack.pop().expect("Should have at least one witness on the stack").witness; Ok(witness_map.into()) @@ -143,24 +132,19 @@ pub async fn execute_program( #[wasm_bindgen(js_name = executeProgramWithBlackBoxSolver, skip_jsdoc)] pub async fn execute_program_with_black_box_solver( - solver: &WasmBlackBoxFunctionSolver, + _solver: &WasmBlackBoxFunctionSolver, program: Vec, initial_witness: JsWitnessMap, foreign_call_executor: &ForeignCallHandler, ) -> Result { - let witness_stack = execute_program_with_native_type_return( - solver, - program, - initial_witness, - foreign_call_executor, - ) - .await?; + let witness_stack = + execute_program_with_native_type_return(program, initial_witness, foreign_call_executor) + .await?; Ok(witness_stack.into()) } async fn execute_program_with_native_type_return( - solver: &WasmBlackBoxFunctionSolver, program: Vec, initial_witness: JsWitnessMap, foreign_call_executor: &ForeignCallHandler, @@ -171,25 +155,20 @@ async fn execute_program_with_native_type_return( None, None))?; - execute_program_with_native_program_and_return( - solver, - &program, - initial_witness, - foreign_call_executor, - ) - .await + execute_program_with_native_program_and_return(&program, initial_witness, foreign_call_executor) + .await } async fn execute_program_with_native_program_and_return( - solver: &WasmBlackBoxFunctionSolver, program: &Program, initial_witness: JsWitnessMap, foreign_call_executor: &ForeignCallHandler, ) -> Result { + let blackbox_solver = Bn254BlackBoxSolver; let executor = ProgramExecutor::new( &program.functions, &program.unconstrained_functions, - &solver.0, + &blackbox_solver, foreign_call_executor, ); let witness_stack = executor.execute(initial_witness.into()).await?; diff --git a/acvm-repo/bn254_blackbox_solver/benches/criterion.rs b/acvm-repo/bn254_blackbox_solver/benches/criterion.rs index a8fa7d8aae4..b86414423cf 100644 --- a/acvm-repo/bn254_blackbox_solver/benches/criterion.rs +++ b/acvm-repo/bn254_blackbox_solver/benches/criterion.rs @@ -15,23 +15,21 @@ fn bench_poseidon2(c: &mut Criterion) { fn bench_pedersen_commitment(c: &mut Criterion) { let inputs = [FieldElement::one(); 2]; - let solver = Bn254BlackBoxSolver::new(); c.bench_function("pedersen_commitment", |b| { - b.iter(|| solver.pedersen_commitment(black_box(&inputs), 0)) + b.iter(|| Bn254BlackBoxSolver.pedersen_commitment(black_box(&inputs), 0)) }); } fn bench_pedersen_hash(c: &mut Criterion) { let inputs = [FieldElement::one(); 2]; - let solver = Bn254BlackBoxSolver::new(); - c.bench_function("pedersen_hash", |b| b.iter(|| solver.pedersen_hash(black_box(&inputs), 0))); + c.bench_function("pedersen_hash", |b| { + b.iter(|| Bn254BlackBoxSolver.pedersen_hash(black_box(&inputs), 0)) + }); } fn bench_schnorr_verify(c: &mut Criterion) { - let solver = Bn254BlackBoxSolver::new(); - let pub_key_x = FieldElement::from_hex( "0x04b260954662e97f00cab9adb773a259097f7a274b83b113532bce27fa3fb96a", ) @@ -51,7 +49,7 @@ fn bench_schnorr_verify(c: &mut Criterion) { c.bench_function("schnorr_verify", |b| { b.iter(|| { - solver.schnorr_verify( + Bn254BlackBoxSolver.schnorr_verify( black_box(&pub_key_x), black_box(&pub_key_y), black_box(&sig_bytes), diff --git a/acvm-repo/bn254_blackbox_solver/src/lib.rs b/acvm-repo/bn254_blackbox_solver/src/lib.rs index 43b86e083d5..ae5a1c3db6d 100644 --- a/acvm-repo/bn254_blackbox_solver/src/lib.rs +++ b/acvm-repo/bn254_blackbox_solver/src/lib.rs @@ -15,26 +15,9 @@ use ark_ec::AffineRepr; pub use embedded_curve_ops::{embedded_curve_add, multi_scalar_mul}; pub use poseidon2::poseidon2_permutation; +#[derive(Default)] pub struct Bn254BlackBoxSolver; -impl Bn254BlackBoxSolver { - pub async fn initialize() -> Bn254BlackBoxSolver { - Bn254BlackBoxSolver - } - - #[cfg(not(target_arch = "wasm32"))] - pub fn new() -> Bn254BlackBoxSolver { - Bn254BlackBoxSolver - } -} - -#[cfg(not(target_arch = "wasm32"))] -impl Default for Bn254BlackBoxSolver { - fn default() -> Self { - Self::new() - } -} - impl BlackBoxFunctionSolver for Bn254BlackBoxSolver { fn schnorr_verify( &self, diff --git a/tooling/acvm_cli/src/cli/execute_cmd.rs b/tooling/acvm_cli/src/cli/execute_cmd.rs index 4e36dbd1f22..5f9651c9138 100644 --- a/tooling/acvm_cli/src/cli/execute_cmd.rs +++ b/tooling/acvm_cli/src/cli/execute_cmd.rs @@ -67,13 +67,12 @@ pub(crate) fn execute_program_from_witness( bytecode: &[u8], foreign_call_resolver_url: Option<&str>, ) -> Result { - let blackbox_solver = Bn254BlackBoxSolver::new(); let program: Program = Program::deserialize_program(bytecode) .map_err(|_| CliError::CircuitDeserializationError())?; execute_program( &program, inputs_map, - &blackbox_solver, + &Bn254BlackBoxSolver, &mut DefaultForeignCallExecutor::new(true, foreign_call_resolver_url), ) .map_err(CliError::CircuitExecutionError) diff --git a/tooling/nargo_cli/src/cli/dap_cmd.rs b/tooling/nargo_cli/src/cli/dap_cmd.rs index 124e30069ae..eded2bfd8d2 100644 --- a/tooling/nargo_cli/src/cli/dap_cmd.rs +++ b/tooling/nargo_cli/src/cli/dap_cmd.rs @@ -1,5 +1,6 @@ use acvm::acir::circuit::ExpressionWidth; use acvm::acir::native_types::WitnessMap; +use bn254_blackbox_solver::Bn254BlackBoxSolver; use clap::Args; use nargo::constants::PROVER_INPUT_FILE; use nargo::workspace::Workspace; @@ -193,11 +194,9 @@ fn loop_uninitialized_dap( Ok((compiled_program, initial_witness)) => { server.respond(req.ack()?)?; - let blackbox_solver = bn254_blackbox_solver::Bn254BlackBoxSolver::new(); - noir_debugger::run_dap_loop( server, - &blackbox_solver, + &Bn254BlackBoxSolver, compiled_program, initial_witness, )?; diff --git a/tooling/nargo_cli/src/cli/debug_cmd.rs b/tooling/nargo_cli/src/cli/debug_cmd.rs index f950cd0405c..7865b608261 100644 --- a/tooling/nargo_cli/src/cli/debug_cmd.rs +++ b/tooling/nargo_cli/src/cli/debug_cmd.rs @@ -219,8 +219,6 @@ pub(crate) fn debug_program( compiled_program: &CompiledProgram, inputs_map: &InputMap, ) -> Result, CliError> { - let blackbox_solver = Bn254BlackBoxSolver::new(); - let initial_witness = compiled_program.abi.encode(inputs_map, None)?; let debug_artifact = DebugArtifact { @@ -230,7 +228,7 @@ pub(crate) fn debug_program( }; noir_debugger::debug_circuit( - &blackbox_solver, + &Bn254BlackBoxSolver, &compiled_program.program.functions[0], debug_artifact, initial_witness, diff --git a/tooling/nargo_cli/src/cli/execute_cmd.rs b/tooling/nargo_cli/src/cli/execute_cmd.rs index 862a46884ef..3fcedbb8f54 100644 --- a/tooling/nargo_cli/src/cli/execute_cmd.rs +++ b/tooling/nargo_cli/src/cli/execute_cmd.rs @@ -110,14 +110,12 @@ pub(crate) fn execute_program( inputs_map: &InputMap, foreign_call_resolver_url: Option<&str>, ) -> Result { - let blackbox_solver = Bn254BlackBoxSolver::new(); - let initial_witness = compiled_program.abi.encode(inputs_map, None)?; let solved_witness_stack_err = nargo::ops::execute_program( &compiled_program.program, initial_witness, - &blackbox_solver, + &Bn254BlackBoxSolver, &mut DefaultForeignCallExecutor::new(true, foreign_call_resolver_url), ); match solved_witness_stack_err { diff --git a/tooling/nargo_cli/src/cli/lsp_cmd.rs b/tooling/nargo_cli/src/cli/lsp_cmd.rs index 45ac02ea552..9ff7a42e5f5 100644 --- a/tooling/nargo_cli/src/cli/lsp_cmd.rs +++ b/tooling/nargo_cli/src/cli/lsp_cmd.rs @@ -25,8 +25,7 @@ pub(crate) fn run(_args: LspCommand, _config: NargoConfig) -> Result<(), CliErro runtime.block_on(async { let (server, _) = async_lsp::MainLoop::new_server(|client| { - let blackbox_solver = Bn254BlackBoxSolver::new(); - let router = NargoLspService::new(&client, blackbox_solver); + let router = NargoLspService::new(&client, Bn254BlackBoxSolver); ServiceBuilder::new() .layer(TracingLayer::default()) From 904f5eba2cb3e47f2148d5f2441c8e5107a5e705 Mon Sep 17 00:00:00 2001 From: jfecher Date: Wed, 22 May 2024 10:03:45 -0500 Subject: [PATCH 20/61] chore(experimental): Add types and traits to the elaborator (#5066) # Description ## Problem\* Working towards #4594 ## Summary\* Adds support for resolving top-level traits and type definitions to the elaborator. ## Additional Context After this PR only globals will need to be resolved in the elaborator. ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_frontend/src/elaborator/mod.rs | 87 +++++++- .../noirc_frontend/src/elaborator/traits.rs | 196 ++++++++++++++++++ .../noirc_frontend/src/elaborator/types.rs | 33 ++- 3 files changed, 307 insertions(+), 9 deletions(-) create mode 100644 compiler/noirc_frontend/src/elaborator/traits.rs diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index 0f9d22ca9b5..50b39757fda 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -10,7 +10,10 @@ use crate::{ UnresolvedTraitConstraint, UnresolvedTypeExpression, }, hir::{ - def_collector::{dc_crate::CompilationError, errors::DuplicateType}, + def_collector::{ + dc_crate::{CompilationError, UnresolvedStruct, UnresolvedTrait, UnresolvedTypeAlias}, + errors::DuplicateType, + }, resolution::{errors::ResolverError, path_resolver::PathResolver, resolver::LambdaContext}, scope::ScopeForest as GenericScopeForest, type_check::TypeCheckError, @@ -27,10 +30,10 @@ use crate::{ macros_api::{ BlockExpression, CallExpression, CastExpression, Expression, ExpressionKind, HirExpression, HirLiteral, HirStatement, Ident, IndexExpression, Literal, MemberAccessExpression, - MethodCallExpression, NodeInterner, NoirFunction, PrefixExpression, Statement, + MethodCallExpression, NodeInterner, NoirFunction, NoirStruct, PrefixExpression, Statement, StatementKind, StructId, }, - node_interner::{DefinitionKind, DependencyId, ExprId, FuncId, StmtId, TraitId}, + node_interner::{DefinitionKind, DependencyId, ExprId, FuncId, StmtId, TraitId, TypeAliasId}, Shared, StructType, Type, TypeVariable, }; use crate::{ @@ -68,6 +71,7 @@ mod expressions; mod patterns; mod scope; mod statements; +mod traits; mod types; use fm::FileId; @@ -206,11 +210,12 @@ impl<'context> Elaborator<'context> { // the resolver filters literal globals first for global in items.globals {} - for alias in items.type_aliases {} - - for trait_ in items.traits {} + for (alias_id, alias) in items.type_aliases { + this.define_type_alias(alias_id, alias); + } - for struct_ in items.types {} + this.collect_traits(items.traits); + this.collect_struct_definitions(items.types); for trait_impl in &mut items.trait_impls { this.collect_trait_impl(trait_impl); @@ -1100,4 +1105,72 @@ impl<'context> Elaborator<'context> { }); } } + + fn define_type_alias(&mut self, alias_id: TypeAliasId, alias: UnresolvedTypeAlias) { + self.file = alias.file_id; + self.local_module = alias.module_id; + + let generics = self.add_generics(&alias.type_alias_def.generics); + self.resolve_local_globals(); + self.current_item = Some(DependencyId::Alias(alias_id)); + let typ = self.resolve_type(alias.type_alias_def.typ); + self.interner.set_type_alias(alias_id, typ, generics); + } + + fn collect_struct_definitions(&mut self, structs: BTreeMap) { + // This is necessary to avoid cloning the entire struct map + // when adding checks after each struct field is resolved. + let struct_ids = structs.keys().copied().collect::>(); + + // Resolve each field in each struct. + // Each struct should already be present in the NodeInterner after def collection. + for (type_id, typ) in structs { + self.file = typ.file_id; + self.local_module = typ.module_id; + let (generics, fields) = self.resolve_struct_fields(typ.struct_def, type_id); + + self.interner.update_struct(type_id, |struct_def| { + struct_def.set_fields(fields); + struct_def.generics = generics; + }); + } + + // Check whether the struct fields have nested slices + // We need to check after all structs are resolved to + // make sure every struct's fields is accurately set. + for id in struct_ids { + let struct_type = self.interner.get_struct(id); + // Only handle structs without generics as any generics args will be checked + // after monomorphization when performing SSA codegen + if struct_type.borrow().generics.is_empty() { + let fields = struct_type.borrow().get_fields(&[]); + for (_, field_type) in fields.iter() { + if field_type.is_nested_slice() { + let location = struct_type.borrow().location; + self.file = location.file; + self.push_err(ResolverError::NestedSlices { span: location.span }); + } + } + } + } + } + + pub fn resolve_struct_fields( + &mut self, + unresolved: NoirStruct, + struct_id: StructId, + ) -> (Generics, Vec<(Ident, Type)>) { + let generics = self.add_generics(&unresolved.generics); + + // Check whether the struct definition has globals in the local module and add them to the scope + self.resolve_local_globals(); + + self.current_item = Some(DependencyId::Struct(struct_id)); + + self.resolving_ids.insert(struct_id); + let fields = vecmap(unresolved.fields, |(ident, typ)| (ident, self.resolve_type(typ))); + self.resolving_ids.remove(&struct_id); + + (generics, fields) + } } diff --git a/compiler/noirc_frontend/src/elaborator/traits.rs b/compiler/noirc_frontend/src/elaborator/traits.rs new file mode 100644 index 00000000000..e7018d900d8 --- /dev/null +++ b/compiler/noirc_frontend/src/elaborator/traits.rs @@ -0,0 +1,196 @@ +use std::collections::BTreeMap; + +use iter_extended::vecmap; +use noirc_errors::Location; + +use crate::{ + ast::{FunctionKind, TraitItem, UnresolvedGenerics, UnresolvedTraitConstraint}, + hir::{ + def_collector::dc_crate::UnresolvedTrait, def_map::ModuleId, + resolution::path_resolver::StandardPathResolver, + }, + hir_def::{ + function::{FuncMeta, HirFunction}, + traits::{TraitConstant, TraitFunction, TraitType}, + }, + macros_api::{ + BlockExpression, FunctionDefinition, FunctionReturnType, Ident, ItemVisibility, + NoirFunction, Param, Pattern, UnresolvedType, Visibility, + }, + node_interner::{FuncId, TraitId}, + token::Attributes, + Generics, Type, TypeVariable, TypeVariableKind, +}; + +use super::Elaborator; + +impl<'context> Elaborator<'context> { + pub fn collect_traits(&mut self, traits: BTreeMap) { + for (trait_id, unresolved_trait) in &traits { + self.interner.push_empty_trait(*trait_id, unresolved_trait); + } + + for (trait_id, unresolved_trait) in traits { + let generics = vecmap(&unresolved_trait.trait_def.generics, |_| { + TypeVariable::unbound(self.interner.next_type_variable_id()) + }); + + // Resolve order + // 1. Trait Types ( Trait constants can have a trait type, therefore types before constants) + let _ = self.resolve_trait_types(&unresolved_trait); + // 2. Trait Constants ( Trait's methods can use trait types & constants, therefore they should be after) + let _ = self.resolve_trait_constants(&unresolved_trait); + // 3. Trait Methods + let methods = self.resolve_trait_methods(trait_id, &unresolved_trait, &generics); + + self.interner.update_trait(trait_id, |trait_def| { + trait_def.set_methods(methods); + trait_def.generics = generics; + }); + + // This check needs to be after the trait's methods are set since + // the interner may set `interner.ordering_type` based on the result type + // of the Cmp trait, if this is it. + if self.crate_id.is_stdlib() { + self.interner.try_add_operator_trait(trait_id); + } + } + } + + fn resolve_trait_types(&mut self, _unresolved_trait: &UnresolvedTrait) -> Vec { + // TODO + vec![] + } + + fn resolve_trait_constants( + &mut self, + _unresolved_trait: &UnresolvedTrait, + ) -> Vec { + // TODO + vec![] + } + + fn resolve_trait_methods( + &mut self, + trait_id: TraitId, + unresolved_trait: &UnresolvedTrait, + trait_generics: &Generics, + ) -> Vec { + self.local_module = unresolved_trait.module_id; + self.file = self.def_maps[&self.crate_id].file_id(unresolved_trait.module_id); + + let mut functions = vec![]; + + for item in &unresolved_trait.trait_def.items { + if let TraitItem::Function { + name, + generics, + parameters, + return_type, + where_clause, + body: _, + } = item + { + let old_generic_count = self.generics.len(); + + let the_trait = self.interner.get_trait(trait_id); + let self_typevar = the_trait.self_type_typevar.clone(); + let self_type = Type::TypeVariable(self_typevar.clone(), TypeVariableKind::Normal); + let name_span = the_trait.name.span(); + + self.add_generics(generics); + self.add_existing_generics(&unresolved_trait.trait_def.generics, trait_generics); + self.add_existing_generic("Self", name_span, self_typevar); + self.self_type = Some(self_type.clone()); + + let func_id = unresolved_trait.method_ids[&name.0.contents]; + self.resolve_trait_function( + name, + generics, + parameters, + return_type, + where_clause, + func_id, + ); + + let arguments = vecmap(parameters, |param| self.resolve_type(param.1.clone())); + let return_type = self.resolve_type(return_type.get_type().into_owned()); + + let generics = vecmap(&self.generics, |(_, type_var, _)| type_var.clone()); + + let default_impl_list: Vec<_> = unresolved_trait + .fns_with_default_impl + .functions + .iter() + .filter(|(_, _, q)| q.name() == name.0.contents) + .collect(); + + let default_impl = if default_impl_list.len() == 1 { + Some(Box::new(default_impl_list[0].2.clone())) + } else { + None + }; + + let no_environment = Box::new(Type::Unit); + let function_type = + Type::Function(arguments, Box::new(return_type), no_environment); + + functions.push(TraitFunction { + name: name.clone(), + typ: Type::Forall(generics, Box::new(function_type)), + location: Location::new(name.span(), unresolved_trait.file_id), + default_impl, + default_impl_module_id: unresolved_trait.module_id, + }); + + self.generics.truncate(old_generic_count); + } + } + functions + } + + pub fn resolve_trait_function( + &mut self, + name: &Ident, + generics: &UnresolvedGenerics, + parameters: &[(Ident, UnresolvedType)], + return_type: &FunctionReturnType, + where_clause: &[UnresolvedTraitConstraint], + func_id: FuncId, + ) { + let old_generic_count = self.generics.len(); + self.scopes.start_function(); + + // Check whether the function has globals in the local module and add them to the scope + self.resolve_local_globals(); + + self.trait_bounds = where_clause.to_vec(); + + let kind = FunctionKind::Normal; + let def = FunctionDefinition { + name: name.clone(), + attributes: Attributes::empty(), + is_unconstrained: false, + is_comptime: false, + visibility: ItemVisibility::Public, // Trait functions are always public + generics: generics.clone(), + parameters: vecmap(parameters, |(name, typ)| Param { + visibility: Visibility::Private, + pattern: Pattern::Identifier(name.clone()), + typ: typ.clone(), + span: name.span(), + }), + body: BlockExpression { statements: Vec::new() }, + span: name.span(), + where_clause: where_clause.to_vec(), + return_type: return_type.clone(), + return_visibility: Visibility::Private, + }; + + self.elaborate_function(NoirFunction { kind, def }, func_id); + let _ = self.scopes.end_function(); + // Don't check the scope tree for unused variables, they can't be used in a declaration anyway. + self.trait_bounds.clear(); + self.generics.truncate(old_generic_count); + } +} diff --git a/compiler/noirc_frontend/src/elaborator/types.rs b/compiler/noirc_frontend/src/elaborator/types.rs index 54920d5738b..3c8d805d802 100644 --- a/compiler/noirc_frontend/src/elaborator/types.rs +++ b/compiler/noirc_frontend/src/elaborator/types.rs @@ -4,7 +4,10 @@ use iter_extended::vecmap; use noirc_errors::{Location, Span}; use crate::{ - ast::{BinaryOpKind, IntegerBitSize, UnresolvedTraitConstraint, UnresolvedTypeExpression}, + ast::{ + BinaryOpKind, IntegerBitSize, NoirTypeAlias, UnresolvedGenerics, UnresolvedTraitConstraint, + UnresolvedTypeExpression, + }, hir::{ def_map::ModuleDefId, resolution::{ @@ -26,7 +29,10 @@ use crate::{ HirExpression, HirLiteral, HirStatement, Path, PathKind, SecondaryAttribute, Signedness, UnaryOp, UnresolvedType, UnresolvedTypeData, }, - node_interner::{DefinitionKind, ExprId, GlobalId, TraitId, TraitImplKind, TraitMethodId}, + node_interner::{ + DefinitionKind, DependencyId, ExprId, GlobalId, TraitId, TraitImplKind, TraitMethodId, + TypeAliasId, + }, Generics, Shared, StructType, Type, TypeAlias, TypeBinding, TypeVariable, TypeVariableKind, }; @@ -1435,4 +1441,27 @@ impl<'context> Elaborator<'context> { } } } + + pub fn add_existing_generics(&mut self, names: &UnresolvedGenerics, generics: &Generics) { + assert_eq!(names.len(), generics.len()); + + for (name, typevar) in names.iter().zip(generics) { + self.add_existing_generic(&name.0.contents, name.0.span(), typevar.clone()); + } + } + + pub fn add_existing_generic(&mut self, name: &str, span: Span, typevar: TypeVariable) { + // Check for name collisions of this generic + let rc_name = Rc::new(name.to_owned()); + + if let Some((_, _, first_span)) = self.find_generic(&rc_name) { + self.push_err(ResolverError::DuplicateDefinition { + name: name.to_owned(), + first_span: *first_span, + second_span: span, + }); + } else { + self.generics.push((rc_name, typevar, span)); + } + } } From 20c4b81c6f89a89714e0c5205f49f1358110d728 Mon Sep 17 00:00:00 2001 From: jfecher Date: Wed, 22 May 2024 10:35:09 -0500 Subject: [PATCH 21/61] chore(experimental): Elaborate globals (#5069) # Description ## Problem\* Working towards #4992 ## Summary\* Adds support for elaborating globals. This was the last major item for resolution + type checking in the elaborator. ## Additional Context Next up in the elaborator will be integrating the scanning pass/interpreter and hooking it up to our integration tests. ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_frontend/src/elaborator/mod.rs | 68 +++++++++++++++++-- .../src/hir/def_collector/dc_crate.rs | 2 +- compiler/noirc_frontend/src/node_interner.rs | 12 ++++ 3 files changed, 75 insertions(+), 7 deletions(-) diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index 50b39757fda..0581e7900f8 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -11,7 +11,10 @@ use crate::{ }, hir::{ def_collector::{ - dc_crate::{CompilationError, UnresolvedStruct, UnresolvedTrait, UnresolvedTypeAlias}, + dc_crate::{ + filter_literal_globals, CompilationError, UnresolvedGlobal, UnresolvedStruct, + UnresolvedTrait, UnresolvedTypeAlias, + }, errors::DuplicateType, }, resolution::{errors::ResolverError, path_resolver::PathResolver, resolver::LambdaContext}, @@ -25,13 +28,14 @@ use crate::{ HirInfixExpression, HirLambda, HirMemberAccess, HirMethodCallExpression, HirMethodReference, HirPrefixExpression, }, + stmt::HirLetStatement, traits::TraitConstraint, }, macros_api::{ BlockExpression, CallExpression, CastExpression, Expression, ExpressionKind, HirExpression, HirLiteral, HirStatement, Ident, IndexExpression, Literal, MemberAccessExpression, - MethodCallExpression, NodeInterner, NoirFunction, NoirStruct, PrefixExpression, Statement, - StatementKind, StructId, + MethodCallExpression, NodeInterner, NoirFunction, NoirStruct, Pattern, PrefixExpression, + SecondaryAttribute, Statement, StatementKind, StructId, }, node_interner::{DefinitionKind, DependencyId, ExprId, FuncId, StmtId, TraitId, TypeAliasId}, Shared, StructType, Type, TypeVariable, @@ -207,25 +211,48 @@ impl<'context> Elaborator<'context> { ) -> Vec<(CompilationError, FileId)> { let mut this = Self::new(context, crate_id); - // the resolver filters literal globals first - for global in items.globals {} + // We must first resolve and intern the globals before we can resolve any stmts inside each function. + // Each function uses its own resolver with a newly created ScopeForest, and must be resolved again to be within a function's scope + // + // Additionally, we must resolve integer globals before structs since structs may refer to + // the values of integer globals as numeric generics. + let (literal_globals, non_literal_globals) = filter_literal_globals(items.globals); + + for global in literal_globals { + this.elaborate_global(global); + } for (alias_id, alias) in items.type_aliases { this.define_type_alias(alias_id, alias); } this.collect_traits(items.traits); + + // Must resolve structs before we resolve globals. this.collect_struct_definitions(items.types); + // Bind trait impls to their trait. Collect trait functions, that have a + // default implementation, which hasn't been overridden. for trait_impl in &mut items.trait_impls { this.collect_trait_impl(trait_impl); } + // Before we resolve any function symbols we must go through our impls and + // re-collect the methods within into their proper module. This cannot be + // done during def collection since we need to be able to resolve the type of + // the impl since that determines the module we should collect into. + // + // These are resolved after trait impls so that struct methods are chosen + // over trait methods if there are name conflicts. for ((typ, module), impls) in &items.impls { this.collect_impls(typ, *module, impls); } - // resolver resolves non-literal globals here + // We must wait to resolve non-literal globals until after we resolve structs since struct + // globals will need to reference the struct type they're initialized to to ensure they are valid. + for global in non_literal_globals { + this.elaborate_global(global); + } for functions in items.functions { this.elaborate_functions(functions); @@ -1173,4 +1200,33 @@ impl<'context> Elaborator<'context> { (generics, fields) } + + fn elaborate_global(&mut self, global: UnresolvedGlobal) { + self.local_module = global.module_id; + self.file = global.file_id; + + let global_id = global.global_id; + self.current_item = Some(DependencyId::Global(global_id)); + + let definition_kind = DefinitionKind::Global(global_id); + let let_stmt = global.stmt_def; + + if !self.in_contract + && let_stmt.attributes.iter().any(|attr| matches!(attr, SecondaryAttribute::Abi(_))) + { + let span = let_stmt.pattern.span(); + self.push_err(ResolverError::AbiAttributeOutsideContract { span }); + } + + if !let_stmt.comptime && matches!(let_stmt.pattern, Pattern::Mutable(..)) { + let span = let_stmt.pattern.span(); + self.push_err(ResolverError::MutableGlobal { span }); + } + + let (let_statement, _typ) = self.elaborate_let(let_stmt); + + let statement_id = self.interner.get_global(global_id).let_statement; + self.interner.get_global_definition_mut(global_id).kind = definition_kind; + self.interner.replace_statement(statement_id, let_statement); + } } diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index d2eaf79b0f0..afec3839599 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -486,7 +486,7 @@ fn inject_prelude( /// Separate the globals Vec into two. The first element in the tuple will be the /// literal globals, except for arrays, and the second will be all other globals. /// We exclude array literals as they can contain complex types -fn filter_literal_globals( +pub fn filter_literal_globals( globals: Vec, ) -> (Vec, Vec) { globals.into_iter().partition(|global| match &global.stmt_def.expression.kind { diff --git a/compiler/noirc_frontend/src/node_interner.rs b/compiler/noirc_frontend/src/node_interner.rs index 7f1b67abfbd..d4145ef6a1d 100644 --- a/compiler/noirc_frontend/src/node_interner.rs +++ b/compiler/noirc_frontend/src/node_interner.rs @@ -916,6 +916,13 @@ impl NodeInterner { &self.definitions[id.0] } + /// Retrieves the definition where the given id was defined. + /// This will panic if given DefinitionId::dummy_id. Use try_definition for + /// any call with a possibly undefined variable. + pub fn definition_mut(&mut self, id: DefinitionId) -> &mut DefinitionInfo { + &mut self.definitions[id.0] + } + /// Tries to retrieve the given id's definition. /// This function should be used during name resolution or type checking when we cannot be sure /// all variables have corresponding definitions (in case of an error in the user's code). @@ -997,6 +1004,11 @@ impl NodeInterner { self.definition(global.definition_id) } + pub fn get_global_definition_mut(&mut self, global_id: GlobalId) -> &mut DefinitionInfo { + let global = self.get_global(global_id); + self.definition_mut(global.definition_id) + } + pub fn get_all_globals(&self) -> &[GlobalInfo] { &self.globals } From d43ba1bddbf6ebd56a7bee0e1db38d155fec95d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustavo=20Gir=C3=A1ldez?= Date: Wed, 22 May 2024 11:53:50 -0400 Subject: [PATCH 22/61] fix: Use plain integer addresses for opcodes in DAP disassembly view (#4941) # Description ## Problem\* Resolves #4904 The disassembly view from VS.Code didn't work properly. Sometimes it would only show the first opcode only and once open it wouldn't update the current opcode pointer when stepping through the code. This was because we were using opcode locations (eg. `3.17`) as instruction references (typed as string in the API), but VS.Code expects integers either in decimal or hexadecimal format. ## Summary\* This PR updates the disassembly request DAP command handler to return integer addresses only, and changes the instruction set breakpoint command to parse and map the given address to the appropriate opcode location. ## Additional Context ## Documentation\* Check one: - [X] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [X] I have tested the changes locally. - [X] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- tooling/debugger/src/context.rs | 259 ++++++++++++-------------------- tooling/debugger/src/dap.rs | 93 ++++++------ 2 files changed, 145 insertions(+), 207 deletions(-) diff --git a/tooling/debugger/src/context.rs b/tooling/debugger/src/context.rs index 646beaf0096..a031d127d82 100644 --- a/tooling/debugger/src/context.rs +++ b/tooling/debugger/src/context.rs @@ -34,6 +34,10 @@ pub(super) struct DebugContext<'a, B: BlackBoxFunctionSolver> { breakpoints: HashSet, source_to_opcodes: BTreeMap>, unconstrained_functions: &'a [BrilligBytecode], + + // Absolute (in terms of all the opcodes ACIR+Brillig) addresses of the ACIR + // opcodes with one additional entry for to indicate the last valid address. + acir_opcode_addresses: Vec, } impl<'a, B: BlackBoxFunctionSolver> DebugContext<'a, B> { @@ -46,6 +50,7 @@ impl<'a, B: BlackBoxFunctionSolver> DebugContext<'a, B> { unconstrained_functions: &'a [BrilligBytecode], ) -> Self { let source_to_opcodes = build_source_to_opcode_debug_mappings(debug_artifact); + let acir_opcode_addresses = build_acir_opcode_offsets(circuit, unconstrained_functions); Self { // TODO: need to handle brillig pointer in the debugger acvm: ACVM::new( @@ -61,6 +66,7 @@ impl<'a, B: BlackBoxFunctionSolver> DebugContext<'a, B> { breakpoints: HashSet::new(), source_to_opcodes, unconstrained_functions, + acir_opcode_addresses, } } @@ -213,111 +219,55 @@ impl<'a, B: BlackBoxFunctionSolver> DebugContext<'a, B> { .collect() } - fn get_opcodes_sizes(&self) -> Vec { - self.get_opcodes() - .iter() - .map(|opcode| match opcode { - Opcode::BrilligCall { id, .. } => { - self.unconstrained_functions[*id as usize].bytecode.len() - } - _ => 1, - }) - .collect() + /// Returns the absolute address of the opcode at the given location. + /// Absolute here means accounting for nested Brillig opcodes in BrilligCall + /// opcodes. + pub fn opcode_location_to_address(&self, location: &OpcodeLocation) -> usize { + match location { + OpcodeLocation::Acir(acir_index) => self.acir_opcode_addresses[*acir_index], + OpcodeLocation::Brillig { acir_index, brillig_index } => { + self.acir_opcode_addresses[*acir_index] + *brillig_index + } + } } - /// Offsets the given location by the given number of opcodes (including - /// Brillig opcodes). If the offset would move the location outside of a - /// valid circuit location, returns None and the number of remaining - /// opcodes/instructions left which span outside the valid range in the - /// second element of the returned tuple. - pub(super) fn offset_opcode_location( - &self, - location: &Option, - mut offset: i64, - ) -> (Option, i64) { - if offset == 0 { - return (*location, 0); + pub fn address_to_opcode_location(&self, address: usize) -> Option { + if address >= *self.acir_opcode_addresses.last().unwrap_or(&0) { + return None; } - let Some(location) = location else { - return (None, offset); - }; - - let (mut acir_index, mut brillig_index) = match location { - OpcodeLocation::Acir(acir_index) => (*acir_index, 0), - OpcodeLocation::Brillig { acir_index, brillig_index } => (*acir_index, *brillig_index), - }; - let opcode_sizes = self.get_opcodes_sizes(); - if offset > 0 { - while offset > 0 { - let opcode_size = opcode_sizes[acir_index] as i64 - brillig_index as i64; - if offset >= opcode_size { - acir_index += 1; - offset -= opcode_size; - brillig_index = 0; - } else { - brillig_index += offset as usize; - offset = 0; - } - if acir_index >= opcode_sizes.len() { - return (None, offset); - } + let location = match self.acir_opcode_addresses.binary_search(&address) { + Ok(found_index) => OpcodeLocation::Acir(found_index), + Err(insert_index) => { + let acir_index = insert_index - 1; + let base_offset = self.acir_opcode_addresses[acir_index]; + let brillig_index = address - base_offset; + OpcodeLocation::Brillig { acir_index, brillig_index } } - } else { - while offset < 0 { - if brillig_index > 0 { - if brillig_index > (-offset) as usize { - brillig_index -= (-offset) as usize; - offset = 0; - } else { - offset += brillig_index as i64; - brillig_index = 0; - } - } else { - if acir_index == 0 { - return (None, offset); - } - acir_index -= 1; - let opcode_size = opcode_sizes[acir_index] as i64; - if opcode_size <= -offset { - offset += opcode_size; - } else { - brillig_index = (opcode_size + offset) as usize; - offset = 0; - } - } - } - } - if brillig_index > 0 { - (Some(OpcodeLocation::Brillig { acir_index, brillig_index }), 0) - } else { - (Some(OpcodeLocation::Acir(acir_index)), 0) - } + }; + Some(location) } - pub(super) fn render_opcode_at_location(&self, location: &Option) -> String { + pub(super) fn render_opcode_at_location(&self, location: &OpcodeLocation) -> String { let opcodes = self.get_opcodes(); match location { - None => String::from("invalid"), - Some(OpcodeLocation::Acir(acir_index)) => { + OpcodeLocation::Acir(acir_index) => { let opcode = &opcodes[*acir_index]; match opcode { Opcode::BrilligCall { id, .. } => { let first_opcode = &self.unconstrained_functions[*id as usize].bytecode[0]; - format!("BRILLIG CALL {first_opcode:?}") + format!("BRILLIG {first_opcode:?}") } _ => format!("{opcode:?}"), } } - Some(OpcodeLocation::Brillig { acir_index, brillig_index }) => { - match &opcodes[*acir_index] { - Opcode::BrilligCall { id, .. } => { - let bytecode = &self.unconstrained_functions[*id as usize].bytecode; - let opcode = &bytecode[*brillig_index]; - format!(" | {opcode:?}") - } - _ => String::from(" | invalid"), + OpcodeLocation::Brillig { acir_index, brillig_index } => match &opcodes[*acir_index] { + Opcode::BrilligCall { id, .. } => { + let bytecode = &self.unconstrained_functions[*id as usize].bytecode; + let opcode = &bytecode[*brillig_index]; + format!(" | {opcode:?}") } - } + _ => String::from(" | invalid"), + }, } } @@ -640,6 +590,28 @@ fn build_source_to_opcode_debug_mappings( result } +fn build_acir_opcode_offsets( + circuit: &Circuit, + unconstrained_functions: &[BrilligBytecode], +) -> Vec { + let mut result = Vec::with_capacity(circuit.opcodes.len() + 1); + // address of the first opcode is always 0 + result.push(0); + circuit.opcodes.iter().fold(0, |acc, opcode| { + let acc = acc + + match opcode { + Opcode::BrilligCall { id, .. } => { + unconstrained_functions[*id as usize].bytecode.len() + } + _ => 1, + }; + // push the starting address of the next opcode + result.push(acc); + acc + }); + result +} + // TODO: update all debugger tests to use unconstrained brillig pointers #[cfg(test)] mod tests { @@ -851,7 +823,7 @@ mod tests { } #[test] - fn test_offset_opcode_location() { + fn test_address_opcode_location_mapping() { let brillig_bytecode = BrilligBytecode { bytecode: vec![ BrilligOpcode::Stop { return_data_offset: 0, return_data_size: 0 }, @@ -883,85 +855,48 @@ mod tests { brillig_funcs, ); - assert_eq!(context.offset_opcode_location(&None, 0), (None, 0)); - assert_eq!(context.offset_opcode_location(&None, 2), (None, 2)); - assert_eq!(context.offset_opcode_location(&None, -2), (None, -2)); - assert_eq!( - context.offset_opcode_location(&Some(OpcodeLocation::Acir(0)), 0), - (Some(OpcodeLocation::Acir(0)), 0) - ); - assert_eq!( - context.offset_opcode_location(&Some(OpcodeLocation::Acir(0)), 1), - (Some(OpcodeLocation::Brillig { acir_index: 0, brillig_index: 1 }), 0) - ); - assert_eq!( - context.offset_opcode_location(&Some(OpcodeLocation::Acir(0)), 2), - (Some(OpcodeLocation::Brillig { acir_index: 0, brillig_index: 2 }), 0) - ); - assert_eq!( - context.offset_opcode_location(&Some(OpcodeLocation::Acir(0)), 3), - (Some(OpcodeLocation::Acir(1)), 0) - ); - assert_eq!( - context.offset_opcode_location(&Some(OpcodeLocation::Acir(0)), 4), - (Some(OpcodeLocation::Acir(2)), 0) - ); - assert_eq!( - context.offset_opcode_location(&Some(OpcodeLocation::Acir(0)), 5), - (Some(OpcodeLocation::Brillig { acir_index: 2, brillig_index: 1 }), 0) - ); - assert_eq!( - context.offset_opcode_location(&Some(OpcodeLocation::Acir(0)), 7), - (Some(OpcodeLocation::Acir(3)), 0) - ); - assert_eq!(context.offset_opcode_location(&Some(OpcodeLocation::Acir(0)), 8), (None, 0)); - assert_eq!(context.offset_opcode_location(&Some(OpcodeLocation::Acir(0)), 20), (None, 12)); - assert_eq!( - context.offset_opcode_location(&Some(OpcodeLocation::Acir(1)), 2), - (Some(OpcodeLocation::Brillig { acir_index: 2, brillig_index: 1 }), 0) - ); - assert_eq!(context.offset_opcode_location(&Some(OpcodeLocation::Acir(0)), -1), (None, -1)); - assert_eq!( - context.offset_opcode_location(&Some(OpcodeLocation::Acir(0)), -10), - (None, -10) - ); + let locations = + (0..=7).map(|address| context.address_to_opcode_location(address)).collect::>(); + // mapping from addresses to opcode locations assert_eq!( - context.offset_opcode_location( - &Some(OpcodeLocation::Brillig { acir_index: 0, brillig_index: 1 }), - -1 - ), - (Some(OpcodeLocation::Acir(0)), 0) - ); - assert_eq!( - context.offset_opcode_location( - &Some(OpcodeLocation::Brillig { acir_index: 0, brillig_index: 2 }), - -2 - ), - (Some(OpcodeLocation::Acir(0)), 0) - ); - assert_eq!( - context.offset_opcode_location(&Some(OpcodeLocation::Acir(1)), -3), - (Some(OpcodeLocation::Acir(0)), 0) - ); - assert_eq!( - context.offset_opcode_location(&Some(OpcodeLocation::Acir(2)), -4), - (Some(OpcodeLocation::Acir(0)), 0) - ); - assert_eq!( - context.offset_opcode_location( - &Some(OpcodeLocation::Brillig { acir_index: 2, brillig_index: 1 }), - -5 - ), - (Some(OpcodeLocation::Acir(0)), 0) + locations, + vec![ + Some(OpcodeLocation::Acir(0)), + Some(OpcodeLocation::Brillig { acir_index: 0, brillig_index: 1 }), + Some(OpcodeLocation::Brillig { acir_index: 0, brillig_index: 2 }), + Some(OpcodeLocation::Acir(1)), + Some(OpcodeLocation::Acir(2)), + Some(OpcodeLocation::Brillig { acir_index: 2, brillig_index: 1 }), + Some(OpcodeLocation::Brillig { acir_index: 2, brillig_index: 2 }), + Some(OpcodeLocation::Acir(3)), + ] ); + + let addresses = locations + .iter() + .flatten() + .map(|location| context.opcode_location_to_address(location)) + .collect::>(); + + // and vice-versa + assert_eq!(addresses, (0..=7).collect::>()); + + // check edge cases + assert_eq!(None, context.address_to_opcode_location(8)); assert_eq!( - context.offset_opcode_location(&Some(OpcodeLocation::Acir(3)), -7), - (Some(OpcodeLocation::Acir(0)), 0) + 0, + context.opcode_location_to_address(&OpcodeLocation::Brillig { + acir_index: 0, + brillig_index: 0 + }) ); assert_eq!( - context.offset_opcode_location(&Some(OpcodeLocation::Acir(2)), -2), - (Some(OpcodeLocation::Brillig { acir_index: 0, brillig_index: 2 }), 0) + 4, + context.opcode_location_to_address(&OpcodeLocation::Brillig { + acir_index: 2, + brillig_index: 0 + }) ); } } diff --git a/tooling/debugger/src/dap.rs b/tooling/debugger/src/dap.rs index 060945132f5..c9b6b816a7e 100644 --- a/tooling/debugger/src/dap.rs +++ b/tooling/debugger/src/dap.rs @@ -1,6 +1,5 @@ use std::collections::BTreeMap; use std::io::{Read, Write}; -use std::str::FromStr; use acvm::acir::circuit::brillig::BrilligBytecode; use acvm::acir::circuit::{Circuit, OpcodeLocation}; @@ -205,6 +204,7 @@ impl<'a, R: Read, W: Write, B: BlackBoxFunctionSolver> DapSession<'a, R, W, B> { Some(frame) => format!("{} {}", frame.function_name, index), None => format!("frame #{index}"), }; + let address = self.context.opcode_location_to_address(opcode_location); StackFrame { id: index as i64, @@ -218,7 +218,7 @@ impl<'a, R: Read, W: Write, B: BlackBoxFunctionSolver> DapSession<'a, R, W, B> { }), line: line_number as i64, column: column_number as i64, - instruction_pointer_reference: Some(opcode_location.to_string()), + instruction_pointer_reference: Some(address.to_string()), ..StackFrame::default() } }) @@ -240,50 +240,41 @@ impl<'a, R: Read, W: Write, B: BlackBoxFunctionSolver> DapSession<'a, R, W, B> { let Command::Disassemble(ref args) = req.command else { unreachable!("handle_disassemble called on a non disassemble request"); }; - let starting_ip = OpcodeLocation::from_str(args.memory_reference.as_str()).ok(); + + // we assume memory references are unsigned integers + let starting_address = args.memory_reference.parse::().unwrap_or(0); let instruction_offset = args.instruction_offset.unwrap_or(0); - let (mut opcode_location, mut invalid_count) = - self.context.offset_opcode_location(&starting_ip, instruction_offset); + + let mut address = starting_address + instruction_offset; let mut count = args.instruction_count; let mut instructions: Vec = vec![]; - // leading invalid locations (when the request goes back - // beyond the start of the program) - if invalid_count < 0 { - while invalid_count < 0 { + while count > 0 { + let opcode_location = if address >= 0 { + self.context.address_to_opcode_location(address as usize) + } else { + None + }; + + if let Some(opcode_location) = opcode_location { instructions.push(DisassembledInstruction { - address: String::from("---"), - instruction: String::from("---"), + address: address.to_string(), + // we'll use the instruction_bytes field to render the OpcodeLocation + instruction_bytes: Some(opcode_location.to_string()), + instruction: self.context.render_opcode_at_location(&opcode_location), + ..DisassembledInstruction::default() + }); + } else { + // entry for invalid location to fill up the request + instructions.push(DisassembledInstruction { + address: "---".to_owned(), + instruction: "---".to_owned(), ..DisassembledInstruction::default() }); - invalid_count += 1; - count -= 1; - } - if count > 0 { - opcode_location = Some(OpcodeLocation::Acir(0)); } - } - // the actual opcodes - while count > 0 && opcode_location.is_some() { - instructions.push(DisassembledInstruction { - address: format!("{}", opcode_location.unwrap()), - instruction: self.context.render_opcode_at_location(&opcode_location), - ..DisassembledInstruction::default() - }); - (opcode_location, _) = self.context.offset_opcode_location(&opcode_location, 1); - count -= 1; - } - // any remaining instruction count is beyond the valid opcode - // vector so return invalid placeholders - while count > 0 { - instructions.push(DisassembledInstruction { - address: String::from("---"), - instruction: String::from("---"), - ..DisassembledInstruction::default() - }); - invalid_count -= 1; count -= 1; + address += 1; } self.server.respond( @@ -418,25 +409,35 @@ impl<'a, R: Read, W: Write, B: BlackBoxFunctionSolver> DapSession<'a, R, W, B> { .breakpoints .iter() .map(|breakpoint| { - let Ok(location) = - OpcodeLocation::from_str(breakpoint.instruction_reference.as_str()) - else { + let offset = breakpoint.offset.unwrap_or(0); + let address = breakpoint.instruction_reference.parse::().unwrap_or(0) + offset; + let Ok(address): Result = address.try_into() else { return Breakpoint { verified: false, - message: Some(String::from("Missing instruction reference")), + message: Some(String::from("Invalid instruction reference/offset")), ..Breakpoint::default() }; }; - if !self.context.is_valid_opcode_location(&location) { + let Some(location) = self + .context + .address_to_opcode_location(address) + .filter(|location| self.context.is_valid_opcode_location(location)) + else { return Breakpoint { verified: false, message: Some(String::from("Invalid opcode location")), ..Breakpoint::default() }; - } + }; let id = self.get_next_breakpoint_id(); breakpoints_to_set.push((location, id)); - Breakpoint { id: Some(id), verified: true, ..Breakpoint::default() } + Breakpoint { + id: Some(id), + verified: true, + offset: Some(0), + instruction_reference: Some(address.to_string()), + ..Breakpoint::default() + } }) .collect(); @@ -496,15 +497,17 @@ impl<'a, R: Read, W: Write, B: BlackBoxFunctionSolver> DapSession<'a, R, W, B> { ..Breakpoint::default() }; } - let instruction_reference = format!("{}", location); + let breakpoint_address = self.context.opcode_location_to_address(&location); + let instruction_reference = format!("{}", breakpoint_address); let breakpoint_id = self.get_next_breakpoint_id(); breakpoints_to_set.push((location, breakpoint_id)); Breakpoint { id: Some(breakpoint_id), verified: true, source: Some(args.source.clone()), - instruction_reference: Some(instruction_reference), line: Some(line), + instruction_reference: Some(instruction_reference), + offset: Some(0), ..Breakpoint::default() } }) From c9fda3c7fd4575bfe7d457e8d4230e071f0129a0 Mon Sep 17 00:00:00 2001 From: guipublic <47281315+guipublic@users.noreply.github.com> Date: Wed, 22 May 2024 18:36:23 +0200 Subject: [PATCH 23/61] feat: Activate return_data in ACIR opcodes (#5080) # Description ## Problem\* Related to #4974 ## Summary\* This PR mark return data array with return_data block type, and disable the unused arrays optimisation for databus. This is required because the return_data is not returned from main although similar constraints will be generated on the backend side. ## Additional Context This should be the last piece for this databus iteration from issue #4974, and it will allow to generate an end-to-end test with the databus to check if we get what is expected. ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [X] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [X] I have tested the changes locally. - [X] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- acvm-repo/acir/src/circuit/opcodes.rs | 6 ++++++ acvm-repo/acvm/src/compiler/optimizers/unused_memory.rs | 5 +++-- compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs | 4 +++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/acvm-repo/acir/src/circuit/opcodes.rs b/acvm-repo/acir/src/circuit/opcodes.rs index e6dc11dac78..6043196dfff 100644 --- a/acvm-repo/acir/src/circuit/opcodes.rs +++ b/acvm-repo/acir/src/circuit/opcodes.rs @@ -18,6 +18,12 @@ pub enum BlockType { ReturnData, } +impl BlockType { + pub fn is_databus(&self) -> bool { + matches!(self, BlockType::CallData | BlockType::ReturnData) + } +} + #[allow(clippy::large_enum_variant)] #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum Opcode { diff --git a/acvm-repo/acvm/src/compiler/optimizers/unused_memory.rs b/acvm-repo/acvm/src/compiler/optimizers/unused_memory.rs index 18eefa79ac2..5fdcf54a492 100644 --- a/acvm-repo/acvm/src/compiler/optimizers/unused_memory.rs +++ b/acvm-repo/acvm/src/compiler/optimizers/unused_memory.rs @@ -44,8 +44,9 @@ impl UnusedMemoryOptimizer { let mut optimized_opcodes = Vec::with_capacity(self.circuit.opcodes.len()); for (idx, opcode) in self.circuit.opcodes.into_iter().enumerate() { match opcode { - Opcode::MemoryInit { block_id, .. } - if self.unused_memory_initializations.contains(&block_id) => + Opcode::MemoryInit { block_id, block_type, .. } + if !block_type.is_databus() + && self.unused_memory_initializations.contains(&block_id) => { // Drop opcode } diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index fefe5f6f8e6..30fd83d7704 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -1728,7 +1728,7 @@ impl<'a> Context<'a> { &mut self, terminator: &TerminatorInstruction, dfg: &DataFlowGraph, - ) -> Result, InternalError> { + ) -> Result, RuntimeError> { let (return_values, call_stack) = match terminator { TerminatorInstruction::Return { return_values, call_stack } => { (return_values, call_stack) @@ -1750,6 +1750,8 @@ impl<'a> Context<'a> { if !is_databus { // We do not return value for the data bus. self.acir_context.return_var(acir_var)?; + } else { + self.check_array_is_initialized(self.data_bus.return_data.unwrap(), dfg)?; } } Ok(warnings) From 4ae91cf083e4357adc74df510e33ef00b94fc620 Mon Sep 17 00:00:00 2001 From: TomAFrench Date: Wed, 22 May 2024 19:03:48 +0000 Subject: [PATCH 24/61] chore: update `nargo info` table to remove circuit size column --- tooling/nargo_cli/src/cli/info_cmd.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tooling/nargo_cli/src/cli/info_cmd.rs b/tooling/nargo_cli/src/cli/info_cmd.rs index 11cf6e22ab5..6c0709e7611 100644 --- a/tooling/nargo_cli/src/cli/info_cmd.rs +++ b/tooling/nargo_cli/src/cli/info_cmd.rs @@ -94,7 +94,7 @@ pub(crate) fn run(args: InfoCommand, config: NargoConfig) -> Result<(), CliError }) .collect(); - let info_report = InfoReport { programs: program_info, contracts: Vec::new() }; + let info_report = InfoReport { programs: program_info }; if args.json { // Expose machine-readable JSON data. @@ -102,7 +102,7 @@ pub(crate) fn run(args: InfoCommand, config: NargoConfig) -> Result<(), CliError } else { // Otherwise print human-readable table. if !info_report.programs.is_empty() { - let mut program_table = table!([Fm->"Package", Fm->"Function", Fm->"Expression Width", Fm->"ACIR Opcodes", Fm->"Backend Circuit Size"]); + let mut program_table = table!([Fm->"Package", Fm->"Function", Fm->"Expression Width", Fm->"ACIR Opcodes"]); for program_info in info_report.programs { let program_rows: Vec = program_info.into(); @@ -169,7 +169,6 @@ fn byte_index(string: &str, index: u32) -> usize { #[derive(Debug, Default, Serialize)] struct InfoReport { programs: Vec, - contracts: Vec, } #[derive(Debug, Serialize)] From e807f0d5080707794af7b3612b51b3956d7417e8 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 23 May 2024 00:25:08 +0100 Subject: [PATCH 25/61] chore: automatically clear any unwanted directories in `test_programs` (#5081) # Description ## Problem\* Closes #5035 ## Summary\* Alternative to #5035 which just deletes any test programs which don't have a Nargo.toml file. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- test_programs/rebuild.sh | 8 ++++++++ tooling/nargo_cli/src/cli/info_cmd.rs | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/test_programs/rebuild.sh b/test_programs/rebuild.sh index 4733bad10c3..cfc6479febf 100755 --- a/test_programs/rebuild.sh +++ b/test_programs/rebuild.sh @@ -8,6 +8,14 @@ process_dir() { local current_dir=$2 local dir_name=$(basename "$dir") + if [[ ! -f "$dir/Nargo.toml" ]]; then + # This directory isn't a proper test but just hold some stale build artifacts + # We then delete it and carry on. + rm -rf $dir + return 0 + fi + + if [[ ! -d "$current_dir/acir_artifacts/$dir_name" ]]; then mkdir -p $current_dir/acir_artifacts/$dir_name fi diff --git a/tooling/nargo_cli/src/cli/info_cmd.rs b/tooling/nargo_cli/src/cli/info_cmd.rs index 6c0709e7611..7c50e907dc9 100644 --- a/tooling/nargo_cli/src/cli/info_cmd.rs +++ b/tooling/nargo_cli/src/cli/info_cmd.rs @@ -102,7 +102,8 @@ pub(crate) fn run(args: InfoCommand, config: NargoConfig) -> Result<(), CliError } else { // Otherwise print human-readable table. if !info_report.programs.is_empty() { - let mut program_table = table!([Fm->"Package", Fm->"Function", Fm->"Expression Width", Fm->"ACIR Opcodes"]); + let mut program_table = + table!([Fm->"Package", Fm->"Function", Fm->"Expression Width", Fm->"ACIR Opcodes"]); for program_info in info_report.programs { let program_rows: Vec = program_info.into(); From 23a64779c7a7384b852bf1c51295f3eb77573130 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 23 May 2024 00:37:57 +0100 Subject: [PATCH 26/61] chore: reactivate gates report (#5084) # Description ## Problem\* Resolves ## Summary\* This PR reactivates the gates report workflow now that we don't have access to the number of constraints through `nargo info` ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .github/workflows/gates_report.yml | 180 +++++++++--------- .../brillig_slice_input/Nargo.toml | 0 .../brillig_slice_input/src/main.nr | 0 .../regression_4383/Nargo.toml | 0 .../regression_4383/src/main.nr | 0 .../regression_4436/Nargo.toml | 0 .../regression_4436/src/main.nr | 0 .../slice_init_with_complex_type/Nargo.toml | 0 .../slice_init_with_complex_type/Prover.toml | 0 .../slice_init_with_complex_type/src/main.nr | 0 test_programs/gates_report.sh | 39 ++-- 11 files changed, 113 insertions(+), 106 deletions(-) rename test_programs/{execution_success => compile_success_empty}/brillig_slice_input/Nargo.toml (100%) rename test_programs/{execution_success => compile_success_empty}/brillig_slice_input/src/main.nr (100%) rename test_programs/{execution_success => compile_success_empty}/regression_4383/Nargo.toml (100%) rename test_programs/{execution_success => compile_success_empty}/regression_4383/src/main.nr (100%) rename test_programs/{execution_success => compile_success_empty}/regression_4436/Nargo.toml (100%) rename test_programs/{execution_success => compile_success_empty}/regression_4436/src/main.nr (100%) rename test_programs/{execution_success => compile_success_empty}/slice_init_with_complex_type/Nargo.toml (100%) rename test_programs/{execution_success => compile_success_empty}/slice_init_with_complex_type/Prover.toml (100%) rename test_programs/{execution_success => compile_success_empty}/slice_init_with_complex_type/src/main.nr (100%) diff --git a/.github/workflows/gates_report.yml b/.github/workflows/gates_report.yml index 3d4bef1940e..0cc94a1a04d 100644 --- a/.github/workflows/gates_report.yml +++ b/.github/workflows/gates_report.yml @@ -1,88 +1,94 @@ -# name: Report gates diff - -# on: -# push: -# branches: -# - master -# pull_request: - -# jobs: -# build-nargo: -# runs-on: ubuntu-latest -# strategy: -# matrix: -# target: [x86_64-unknown-linux-gnu] - -# steps: -# - name: Checkout Noir repo -# uses: actions/checkout@v4 - -# - name: Setup toolchain -# uses: dtolnay/rust-toolchain@1.74.1 - -# - uses: Swatinem/rust-cache@v2 -# with: -# key: ${{ matrix.target }} -# cache-on-failure: true -# save-if: ${{ github.event_name != 'merge_group' }} - -# - name: Build Nargo -# run: cargo build --package nargo_cli --release - -# - name: Package artifacts -# run: | -# mkdir dist -# cp ./target/release/nargo ./dist/nargo -# 7z a -ttar -so -an ./dist/* | 7z a -si ./nargo-x86_64-unknown-linux-gnu.tar.gz - -# - name: Upload artifact -# uses: actions/upload-artifact@v4 -# with: -# name: nargo -# path: ./dist/* -# retention-days: 3 - - -# compare_gas_reports: -# needs: [build-nargo] -# runs-on: ubuntu-latest -# permissions: -# pull-requests: write - -# steps: -# - uses: actions/checkout@v4 - -# - name: Download nargo binary -# uses: actions/download-artifact@v4 -# with: -# name: nargo -# path: ./nargo - -# - name: Set nargo on PATH -# run: | -# nargo_binary="${{ github.workspace }}/nargo/nargo" -# chmod +x $nargo_binary -# echo "$(dirname $nargo_binary)" >> $GITHUB_PATH -# export PATH="$PATH:$(dirname $nargo_binary)" -# nargo -V - -# - name: Generate gates report -# working-directory: ./test_programs -# run: | -# ./gates_report.sh -# mv gates_report.json ../gates_report.json +name: Report gates diff + +on: + push: + branches: + - master + pull_request: + +jobs: + build-nargo: + runs-on: ubuntu-latest + strategy: + matrix: + target: [x86_64-unknown-linux-gnu] + + steps: + - name: Checkout Noir repo + uses: actions/checkout@v4 + + - name: Setup toolchain + uses: dtolnay/rust-toolchain@1.74.1 + + - uses: Swatinem/rust-cache@v2 + with: + key: ${{ matrix.target }} + cache-on-failure: true + save-if: ${{ github.event_name != 'merge_group' }} + + - name: Build Nargo + run: cargo build --package nargo_cli --release + + - name: Package artifacts + run: | + mkdir dist + cp ./target/release/nargo ./dist/nargo + 7z a -ttar -so -an ./dist/* | 7z a -si ./nargo-x86_64-unknown-linux-gnu.tar.gz + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: nargo + path: ./dist/* + retention-days: 3 + + + compare_gates_reports: + needs: [build-nargo] + runs-on: ubuntu-latest + permissions: + pull-requests: write + + steps: + - uses: actions/checkout@v4 + + - name: Install `bb` + run: | + ./scripts/install_bb.sh + echo "$HOME/.bb/" >> $GITHUB_PATH + + - name: Download nargo binary + uses: actions/download-artifact@v4 + with: + name: nargo + path: ./nargo + + - name: Set nargo on PATH + run: | + nargo_binary="${{ github.workspace }}/nargo/nargo" + chmod +x $nargo_binary + echo "$(dirname $nargo_binary)" >> $GITHUB_PATH + export PATH="$PATH:$(dirname $nargo_binary)" + nargo -V + + - name: Generate gates report + working-directory: ./test_programs + run: | + ./rebuild.sh + ./gates_report.sh + mv gates_report.json ../gates_report.json -# - name: Compare gates reports -# id: gates_diff -# uses: vezenovm/noir-gates-diff@acf12797860f237117e15c0d6e08d64253af52b6 -# with: -# report: gates_report.json -# summaryQuantile: 0.9 # only display the 10% most significant circuit size diffs in the summary (defaults to 20%) - -# - name: Add gates diff to sticky comment -# if: github.event_name == 'pull_request' || github.event_name == 'pull_request_target' -# uses: marocchino/sticky-pull-request-comment@v2 -# with: -# # delete the comment in case changes no longer impact circuit sizes -# delete: ${{ !steps.gates_diff.outputs.markdown }} -# message: ${{ steps.gates_diff.outputs.markdown }} + - name: Compare gates reports + id: gates_diff + uses: vezenovm/noir-gates-diff@acf12797860f237117e15c0d6e08d64253af52b6 + with: + report: gates_report.json + summaryQuantile: 0.9 # only display the 10% most significant circuit size diffs in the summary (defaults to 20%) + + - name: Add gates diff to sticky comment + if: github.event_name == 'pull_request' || github.event_name == 'pull_request_target' + uses: marocchino/sticky-pull-request-comment@v2 + with: + # delete the comment in case changes no longer impact circuit sizes + delete: ${{ !steps.gates_diff.outputs.markdown }} + message: ${{ steps.gates_diff.outputs.markdown }} diff --git a/test_programs/execution_success/brillig_slice_input/Nargo.toml b/test_programs/compile_success_empty/brillig_slice_input/Nargo.toml similarity index 100% rename from test_programs/execution_success/brillig_slice_input/Nargo.toml rename to test_programs/compile_success_empty/brillig_slice_input/Nargo.toml diff --git a/test_programs/execution_success/brillig_slice_input/src/main.nr b/test_programs/compile_success_empty/brillig_slice_input/src/main.nr similarity index 100% rename from test_programs/execution_success/brillig_slice_input/src/main.nr rename to test_programs/compile_success_empty/brillig_slice_input/src/main.nr diff --git a/test_programs/execution_success/regression_4383/Nargo.toml b/test_programs/compile_success_empty/regression_4383/Nargo.toml similarity index 100% rename from test_programs/execution_success/regression_4383/Nargo.toml rename to test_programs/compile_success_empty/regression_4383/Nargo.toml diff --git a/test_programs/execution_success/regression_4383/src/main.nr b/test_programs/compile_success_empty/regression_4383/src/main.nr similarity index 100% rename from test_programs/execution_success/regression_4383/src/main.nr rename to test_programs/compile_success_empty/regression_4383/src/main.nr diff --git a/test_programs/execution_success/regression_4436/Nargo.toml b/test_programs/compile_success_empty/regression_4436/Nargo.toml similarity index 100% rename from test_programs/execution_success/regression_4436/Nargo.toml rename to test_programs/compile_success_empty/regression_4436/Nargo.toml diff --git a/test_programs/execution_success/regression_4436/src/main.nr b/test_programs/compile_success_empty/regression_4436/src/main.nr similarity index 100% rename from test_programs/execution_success/regression_4436/src/main.nr rename to test_programs/compile_success_empty/regression_4436/src/main.nr diff --git a/test_programs/execution_success/slice_init_with_complex_type/Nargo.toml b/test_programs/compile_success_empty/slice_init_with_complex_type/Nargo.toml similarity index 100% rename from test_programs/execution_success/slice_init_with_complex_type/Nargo.toml rename to test_programs/compile_success_empty/slice_init_with_complex_type/Nargo.toml diff --git a/test_programs/execution_success/slice_init_with_complex_type/Prover.toml b/test_programs/compile_success_empty/slice_init_with_complex_type/Prover.toml similarity index 100% rename from test_programs/execution_success/slice_init_with_complex_type/Prover.toml rename to test_programs/compile_success_empty/slice_init_with_complex_type/Prover.toml diff --git a/test_programs/execution_success/slice_init_with_complex_type/src/main.nr b/test_programs/compile_success_empty/slice_init_with_complex_type/src/main.nr similarity index 100% rename from test_programs/execution_success/slice_init_with_complex_type/src/main.nr rename to test_programs/compile_success_empty/slice_init_with_complex_type/src/main.nr diff --git a/test_programs/gates_report.sh b/test_programs/gates_report.sh index 3b0b4d9e148..b33e81b037c 100755 --- a/test_programs/gates_report.sh +++ b/test_programs/gates_report.sh @@ -1,36 +1,37 @@ #!/usr/bin/env bash set -e +BACKEND=${BACKEND:-bb} + # These tests are incompatible with gas reporting excluded_dirs=("workspace" "workspace_default_member" "double_verify_nested_proof") -# These tests cause failures in CI with a stack overflow for some reason. -ci_excluded_dirs=("eddsa") - current_dir=$(pwd) -base_path="$current_dir/execution_success" -test_dirs=$(ls $base_path) +artifacts_path="$current_dir/acir_artifacts" +test_dirs=$(ls $artifacts_path) -# We generate a Noir workspace which contains all of the test cases -# This allows us to generate a gates report using `nargo info` for all of them at once. +echo "{\"programs\": [" > gates_report.json -echo "[workspace]" > Nargo.toml -echo "members = [" >> Nargo.toml +# Bound for checking where to place last parentheses +NUM_ARTIFACTS=$(ls -1q "$artifacts_path" | wc -l) -for dir in $test_dirs; do - if [[ " ${excluded_dirs[@]} " =~ " ${dir} " ]]; then - continue - fi +ITER="1" +for pathname in $test_dirs; do + ARTIFACT_NAME=$(basename "$pathname") + + GATES_INFO=$($BACKEND gates -b "$artifacts_path/$ARTIFACT_NAME/target/program.json") + MAIN_FUNCTION_INFO=$(echo $GATES_INFO | jq -r '.functions[0] | .name = "main"') + echo "{\"package_name\": \"$ARTIFACT_NAME\", \"functions\": [$MAIN_FUNCTION_INFO]" >> gates_report.json - if [[ ${CI-false} = "true" ]] && [[ " ${ci_excluded_dirs[@]} " =~ " ${dir} " ]]; then - continue + if (($ITER == $NUM_ARTIFACTS)); then + echo "}" >> gates_report.json + else + echo "}, " >> gates_report.json fi - echo " \"execution_success/$dir\"," >> Nargo.toml + ITER=$(( $ITER + 1 )) done -echo "]" >> Nargo.toml +echo "]}" >> gates_report.json -nargo info --json > gates_report.json -rm Nargo.toml From 2b4755c2b57460d5eb839ee835f8c9acd5773a7c Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Thu, 23 May 2024 14:14:43 +0100 Subject: [PATCH 27/61] fix: Apply self type from generic trait constraint before instantiating identifiers (#5087) # Description ## Problem\* Resolves #5063 ## Summary\* After the turbofish PRs we want the ability to instantiate a variable from a generic trait. This was possible but it required a redundant type annotiation like such (assume `H` has been specified with a `where` clause): ```rust let hasher: H = H::default() ``` Similarly to trait generics, we now add type bindings from a trait constraint if the trait impl is assumed to exist. We now can just do: ```rust let hasher = H::default() ``` ## Additional Context ## Documentation\* Check one: - [X] No documentation needed. - [ ] Documentation included in this PR. - [] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [X] I have tested the changes locally. - [X] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_frontend/src/hir/type_check/expr.rs | 12 +++++++++++- compiler/noirc_frontend/src/tests.rs | 4 ++-- noir_stdlib/src/eddsa.nr | 2 +- .../turbofish_call_func_diff_types/src/main.nr | 4 +--- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/type_check/expr.rs b/compiler/noirc_frontend/src/hir/type_check/expr.rs index abff466e1d5..9a54e76b8a4 100644 --- a/compiler/noirc_frontend/src/hir/type_check/expr.rs +++ b/compiler/noirc_frontend/src/hir/type_check/expr.rs @@ -371,7 +371,7 @@ impl<'interner> TypeChecker<'interner> { // We need to do this first since otherwise instantiating the type below // will replace each trait generic with a fresh type variable, rather than // the type used in the trait constraint (if it exists). See #4088. - if let ImplKind::TraitMethod(_, constraint, _) = &ident.impl_kind { + if let ImplKind::TraitMethod(_, constraint, assumed) = &ident.impl_kind { let the_trait = self.interner.get_trait(constraint.trait_id); assert_eq!(the_trait.generics.len(), constraint.trait_generics.len()); @@ -381,6 +381,16 @@ impl<'interner> TypeChecker<'interner> { bindings.insert(param.id(), (param.clone(), arg.clone())); } } + + // If the trait impl is already assumed to exist we should add any type bindings for `Self`. + // Otherwise `self` will be replaced with a fresh type variable, which will require the user + // to specify a redundant type annotation. + if *assumed { + bindings.insert( + the_trait.self_type_typevar_id, + (the_trait.self_type_typevar.clone(), constraint.typ.clone()), + ); + } } // An identifiers type may be forall-quantified in the case of generic functions. diff --git a/compiler/noirc_frontend/src/tests.rs b/compiler/noirc_frontend/src/tests.rs index 7bf5655486b..bd81752c046 100644 --- a/compiler/noirc_frontend/src/tests.rs +++ b/compiler/noirc_frontend/src/tests.rs @@ -1430,14 +1430,14 @@ fn specify_method_types_with_turbofish() { } impl Foo { - fn generic_method(_self: Self) where U: Default { + fn generic_method(_self: Self) -> U where U: Default { U::default() } } fn main() { let foo: Foo = Foo { inner: 1 }; - foo.generic_method::(); + let _ = foo.generic_method::(); } "#; let errors = get_program_errors(src); diff --git a/noir_stdlib/src/eddsa.nr b/noir_stdlib/src/eddsa.nr index 1ab0158af8f..337969be90e 100644 --- a/noir_stdlib/src/eddsa.nr +++ b/noir_stdlib/src/eddsa.nr @@ -45,7 +45,7 @@ where H: Hasher + Default { // Ensure S < Subgroup Order assert(signature_s.lt(bjj.suborder)); // Calculate the h = H(R, A, msg) - let mut hasher: H = H::default(); + let mut hasher = H::default(); hasher.write(signature_r8_x); hasher.write(signature_r8_y); hasher.write(pub_key_x); diff --git a/test_programs/execution_success/turbofish_call_func_diff_types/src/main.nr b/test_programs/execution_success/turbofish_call_func_diff_types/src/main.nr index 709a694e77b..b880d3ae047 100644 --- a/test_programs/execution_success/turbofish_call_func_diff_types/src/main.nr +++ b/test_programs/execution_success/turbofish_call_func_diff_types/src/main.nr @@ -23,9 +23,7 @@ fn main(x: Field, y: pub Field) { fn hash_simple_array(input: [Field; 2]) -> Field where H: Hasher + Default { // Check that we can call a trait method instead of a trait implementation - // TODO(https://github.com/noir-lang/noir/issues/5063): Need to remove the need for this type annotation - // Curently, without the annotation we will get `Expression type is ambiguous` when trying to use the `hasher` - let mut hasher: H = H::default(); + let mut hasher = H::default(); // Regression that the object is converted to a mutable reference type `&mut _`. // Otherwise will see `Expected type &mut _, found type H`. // Then we need to make sure to also auto dereference later in the type checking process From 86fd0ac4e6dd168227de6b8c97ed08da89e58a89 Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Thu, 23 May 2024 22:18:48 +0100 Subject: [PATCH 28/61] chore: Move turbofish changes to the elaborator (#5094) # Description ## Problem\* Resolves ## Summary\* Moving https://github.com/noir-lang/noir/pull/3542, https://github.com/noir-lang/noir/pull/5041, and https://github.com/noir-lang/noir/pull/5087 to the elaborator ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: jfecher --- .../src/elaborator/expressions.rs | 33 ++++++--- .../noirc_frontend/src/elaborator/patterns.rs | 70 +++++++++++++++++-- .../noirc_frontend/src/hir/type_check/expr.rs | 3 +- 3 files changed, 88 insertions(+), 18 deletions(-) diff --git a/compiler/noirc_frontend/src/elaborator/expressions.rs b/compiler/noirc_frontend/src/elaborator/expressions.rs index 75c95c06d09..f1631286336 100644 --- a/compiler/noirc_frontend/src/elaborator/expressions.rs +++ b/compiler/noirc_frontend/src/elaborator/expressions.rs @@ -194,7 +194,7 @@ impl<'context> Elaborator<'context> { let expr_id = self.interner.push_expr(ident); self.interner.push_expr_location(expr_id, call_expr_span, self.file); let ident = old_value.ident.clone(); - let typ = self.type_check_variable(ident, expr_id); + let typ = self.type_check_variable(ident, expr_id, None); self.interner.push_expr_type(expr_id, typ.clone()); capture_types.push(typ); fmt_str_idents.push(expr_id); @@ -291,16 +291,25 @@ impl<'context> Elaborator<'context> { Some(method_ref) => { // Automatically add `&mut` if the method expects a mutable reference and // the object is not already one. - if let HirMethodReference::FuncId(func_id) = &method_ref { - if *func_id != FuncId::dummy_id() { - let function_type = self.interner.function_meta(func_id).typ.clone(); - - self.try_add_mutable_reference_to_object( - &function_type, - &mut object_type, - &mut object, - ); + let func_id = match &method_ref { + HirMethodReference::FuncId(func_id) => *func_id, + HirMethodReference::TraitMethodId(method_id, _) => { + let id = self.interner.trait_method_id(*method_id); + let definition = self.interner.definition(id); + let DefinitionKind::Function(func_id) = definition.kind else { + unreachable!("Expected trait function to be a DefinitionKind::Function") + }; + func_id } + }; + + if func_id != FuncId::dummy_id() { + let function_type = self.interner.function_meta(&func_id).typ.clone(); + self.try_add_mutable_reference_to_object( + &function_type, + &mut object_type, + &mut object, + ); } // These arguments will be given to the desugared function call. @@ -322,6 +331,7 @@ impl<'context> Elaborator<'context> { let generics = method_call.generics.map(|option_inner| { option_inner.into_iter().map(|generic| self.resolve_type(generic)).collect() }); + let turbofish_generics = generics.clone(); let method_call = HirMethodCallExpression { method, object, arguments, location, generics }; @@ -335,7 +345,8 @@ impl<'context> Elaborator<'context> { self.interner, ); - let func_type = self.type_check_variable(function_name, function_id); + let func_type = + self.type_check_variable(function_name, function_id, turbofish_generics); // Type check the new call now that it has been changed from a method call // to a function call. This way we avoid duplicating code. diff --git a/compiler/noirc_frontend/src/elaborator/patterns.rs b/compiler/noirc_frontend/src/elaborator/patterns.rs index 810e1b90743..17c11b88f4a 100644 --- a/compiler/noirc_frontend/src/elaborator/patterns.rs +++ b/compiler/noirc_frontend/src/elaborator/patterns.rs @@ -5,6 +5,7 @@ use rustc_hash::FxHashSet as HashSet; use crate::{ ast::ERROR_IDENT, hir::{ + def_collector::dc_crate::CompilationError, resolution::errors::ResolverError, type_check::{Source, TypeCheckError}, }, @@ -330,9 +331,9 @@ impl<'context> Elaborator<'context> { ) -> (ExprId, Type) { let span = variable.span; let expr = self.resolve_variable(variable); - let id = self.interner.push_expr(HirExpression::Ident(expr.clone(), generics)); + let id = self.interner.push_expr(HirExpression::Ident(expr.clone(), generics.clone())); self.interner.push_expr_location(id, span, self.file); - let typ = self.type_check_variable(expr, id); + let typ = self.type_check_variable(expr, id, generics); self.interner.push_expr_type(id, typ.clone()); (id, typ) } @@ -384,14 +385,19 @@ impl<'context> Elaborator<'context> { } } - pub(super) fn type_check_variable(&mut self, ident: HirIdent, expr_id: ExprId) -> Type { + pub(super) fn type_check_variable( + &mut self, + ident: HirIdent, + expr_id: ExprId, + generics: Option>, + ) -> Type { let mut bindings = TypeBindings::new(); // Add type bindings from any constraints that were used. // We need to do this first since otherwise instantiating the type below // will replace each trait generic with a fresh type variable, rather than // the type used in the trait constraint (if it exists). See #4088. - if let ImplKind::TraitMethod(_, constraint, _) = &ident.impl_kind { + if let ImplKind::TraitMethod(_, constraint, assumed) = &ident.impl_kind { let the_trait = self.interner.get_trait(constraint.trait_id); assert_eq!(the_trait.generics.len(), constraint.trait_generics.len()); @@ -401,6 +407,16 @@ impl<'context> Elaborator<'context> { bindings.insert(param.id(), (param.clone(), arg.clone())); } } + + // If the trait impl is already assumed to exist we should add any type bindings for `Self`. + // Otherwise `self` will be replaced with a fresh type variable, which will require the user + // to specify a redundant type annotation. + if *assumed { + bindings.insert( + the_trait.self_type_typevar_id, + (the_trait.self_type_typevar.clone(), constraint.typ.clone()), + ); + } } // An identifiers type may be forall-quantified in the case of generic functions. @@ -409,10 +425,21 @@ impl<'context> Elaborator<'context> { // variable to handle generic functions. let t = self.interner.id_type_substitute_trait_as_type(ident.id); + let definition = self.interner.try_definition(ident.id); + let function_generic_count = definition.map_or(0, |definition| match &definition.kind { + DefinitionKind::Function(function) => { + self.interner.function_modifiers(function).generic_count + } + _ => 0, + }); + + let span = self.interner.expr_span(&expr_id); + let location = self.interner.expr_location(&expr_id); // This instantiates a trait's generics as well which need to be set // when the constraint below is later solved for when the function is // finished. How to link the two? - let (typ, bindings) = t.instantiate_with_bindings(bindings, self.interner); + let (typ, bindings) = + self.instantiate(t, bindings, generics, function_generic_count, span, location); // Push any trait constraints required by this definition to the context // to be checked later when the type of this variable is further constrained. @@ -447,6 +474,39 @@ impl<'context> Elaborator<'context> { typ } + fn instantiate( + &mut self, + typ: Type, + bindings: TypeBindings, + turbofish_generics: Option>, + function_generic_count: usize, + span: Span, + location: Location, + ) -> (Type, TypeBindings) { + match turbofish_generics { + Some(turbofish_generics) => { + if turbofish_generics.len() != function_generic_count { + let type_check_err = TypeCheckError::IncorrectTurbofishGenericCount { + expected_count: function_generic_count, + actual_count: turbofish_generics.len(), + span, + }; + self.errors.push((CompilationError::TypeError(type_check_err), location.file)); + typ.instantiate_with_bindings(bindings, self.interner) + } else { + // Fetch the count of any implicit generics on the function, such as + // for a method within a generic impl. + let implicit_generic_count = match &typ { + Type::Forall(generics, _) => generics.len() - function_generic_count, + _ => 0, + }; + typ.instantiate_with(turbofish_generics, self.interner, implicit_generic_count) + } + } + None => typ.instantiate_with_bindings(bindings, self.interner), + } + } + fn get_ident_from_path(&mut self, path: Path) -> (HirIdent, usize) { let location = Location::new(path.span(), self.file); diff --git a/compiler/noirc_frontend/src/hir/type_check/expr.rs b/compiler/noirc_frontend/src/hir/type_check/expr.rs index 9a54e76b8a4..336c1cedbb6 100644 --- a/compiler/noirc_frontend/src/hir/type_check/expr.rs +++ b/compiler/noirc_frontend/src/hir/type_check/expr.rs @@ -399,8 +399,6 @@ impl<'interner> TypeChecker<'interner> { // variable to handle generic functions. let t = self.interner.id_type_substitute_trait_as_type(ident.id); - let span = self.interner.expr_span(expr_id); - let definition = self.interner.try_definition(ident.id); let function_generic_count = definition.map_or(0, |definition| match &definition.kind { DefinitionKind::Function(function) => { @@ -409,6 +407,7 @@ impl<'interner> TypeChecker<'interner> { _ => 0, }); + let span = self.interner.expr_span(expr_id); // This instantiates a trait's generics as well which need to be set // when the constraint below is later solved for when the function is // finished. How to link the two? From 281ebf26e4cd16daf361938de505697f8d5fbd5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Fri, 24 May 2024 16:44:32 +0200 Subject: [PATCH 29/61] feat: Add intrinsic to get if running inside an unconstrained context (#5098) # Description ## Problem\* Currently, when creating a regular (not marked with unconstrained) function, it can end up running in both a constrained and unconstrained context. ## Summary\* This intrinsic is resolved at compile time a provides a way for developers to dispatch to different implementations in library code for constrained and unconstrained context. This intrinsic has been used in stdlib's field comparison code as demonstration. ## Additional Context It's very typical for the constrained version of a calculation to take a hint of a computed value and verify it. However, in the unconstrained version of that calculation we just need to compute the value, there is no point in verifying what we just did. This intrinsic provides a tool for devs to optimize a function for unconstrained removing these verifications. ## Documentation\* Check one: - [ ] No documentation needed. - [x] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> --- compiler/noirc_evaluator/src/ssa.rs | 1 + .../noirc_evaluator/src/ssa/ir/instruction.rs | 6 +- .../src/ssa/ir/instruction/call.rs | 1 + compiler/noirc_evaluator/src/ssa/opt/mod.rs | 1 + .../src/ssa/opt/remove_enable_side_effects.rs | 3 +- .../src/ssa/opt/remove_if_else.rs | 3 +- .../src/ssa/opt/resolve_is_unconstrained.rs | 56 ++++++ .../noir/standard_library/is_unconstrained.md | 59 ++++++ noir_stdlib/src/field/bn254.nr | 183 +++++++++++------- noir_stdlib/src/lib.nr | 2 + noir_stdlib/src/runtime.nr | 2 + .../is_unconstrained/Nargo.toml | 6 + .../is_unconstrained/Prover.toml | 1 + .../is_unconstrained/src/main.nr | 14 ++ tooling/debugger/ignored-tests.txt | 1 + 15 files changed, 263 insertions(+), 76 deletions(-) create mode 100644 compiler/noirc_evaluator/src/ssa/opt/resolve_is_unconstrained.rs create mode 100644 docs/docs/noir/standard_library/is_unconstrained.md create mode 100644 noir_stdlib/src/runtime.nr create mode 100644 test_programs/execution_success/is_unconstrained/Nargo.toml create mode 100644 test_programs/execution_success/is_unconstrained/Prover.toml create mode 100644 test_programs/execution_success/is_unconstrained/src/main.nr diff --git a/compiler/noirc_evaluator/src/ssa.rs b/compiler/noirc_evaluator/src/ssa.rs index 69e5f6ddfcc..c2fe7878bf8 100644 --- a/compiler/noirc_evaluator/src/ssa.rs +++ b/compiler/noirc_evaluator/src/ssa.rs @@ -56,6 +56,7 @@ pub(crate) fn optimize_into_acir( .run_pass(Ssa::defunctionalize, "After Defunctionalization:") .run_pass(Ssa::remove_paired_rc, "After Removing Paired rc_inc & rc_decs:") .run_pass(Ssa::inline_functions, "After Inlining:") + .run_pass(Ssa::resolve_is_unconstrained, "After Resolving IsUnconstrained:") // Run mem2reg with the CFG separated into blocks .run_pass(Ssa::mem2reg, "After Mem2Reg:") .run_pass(Ssa::as_slice_optimization, "After `as_slice` optimization") diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs index f136d3c5fb2..93ea703721f 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -65,6 +65,7 @@ pub(crate) enum Intrinsic { FromField, AsField, AsWitness, + IsUnconstrained, } impl std::fmt::Display for Intrinsic { @@ -89,6 +90,7 @@ impl std::fmt::Display for Intrinsic { Intrinsic::FromField => write!(f, "from_field"), Intrinsic::AsField => write!(f, "as_field"), Intrinsic::AsWitness => write!(f, "as_witness"), + Intrinsic::IsUnconstrained => write!(f, "is_unconstrained"), } } } @@ -116,7 +118,8 @@ impl Intrinsic { | Intrinsic::SliceRemove | Intrinsic::StrAsBytes | Intrinsic::FromField - | Intrinsic::AsField => false, + | Intrinsic::AsField + | Intrinsic::IsUnconstrained => false, // Some black box functions have side-effects Intrinsic::BlackBox(func) => matches!(func, BlackBoxFunc::RecursiveAggregation), @@ -145,6 +148,7 @@ impl Intrinsic { "from_field" => Some(Intrinsic::FromField), "as_field" => Some(Intrinsic::AsField), "as_witness" => Some(Intrinsic::AsWitness), + "is_unconstrained" => Some(Intrinsic::IsUnconstrained), other => BlackBoxFunc::lookup(other).map(Intrinsic::BlackBox), } } diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs index 8e320de9337..8f57d9de368 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs @@ -294,6 +294,7 @@ pub(super) fn simplify_call( SimplifyResult::SimplifiedToInstruction(instruction) } Intrinsic::AsWitness => SimplifyResult::None, + Intrinsic::IsUnconstrained => SimplifyResult::None, } } diff --git a/compiler/noirc_evaluator/src/ssa/opt/mod.rs b/compiler/noirc_evaluator/src/ssa/opt/mod.rs index 27536d59ea5..f6c3f022bfc 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/mod.rs @@ -17,5 +17,6 @@ mod rc; mod remove_bit_shifts; mod remove_enable_side_effects; mod remove_if_else; +mod resolve_is_unconstrained; mod simplify_cfg; mod unrolling; diff --git a/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs b/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs index 9309652d508..464faa57323 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs @@ -158,7 +158,8 @@ impl Context { | Intrinsic::FromField | Intrinsic::AsField | Intrinsic::AsSlice - | Intrinsic::AsWitness => false, + | Intrinsic::AsWitness + | Intrinsic::IsUnconstrained => false, }, // We must assume that functions contain a side effect as we cannot inspect more deeply. diff --git a/compiler/noirc_evaluator/src/ssa/opt/remove_if_else.rs b/compiler/noirc_evaluator/src/ssa/opt/remove_if_else.rs index 3d2b5142219..91b455dbf29 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/remove_if_else.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/remove_if_else.rs @@ -232,6 +232,7 @@ fn slice_capacity_change( | Intrinsic::BlackBox(_) | Intrinsic::FromField | Intrinsic::AsField - | Intrinsic::AsWitness => SizeChange::None, + | Intrinsic::AsWitness + | Intrinsic::IsUnconstrained => SizeChange::None, } } diff --git a/compiler/noirc_evaluator/src/ssa/opt/resolve_is_unconstrained.rs b/compiler/noirc_evaluator/src/ssa/opt/resolve_is_unconstrained.rs new file mode 100644 index 00000000000..2c9e33ae528 --- /dev/null +++ b/compiler/noirc_evaluator/src/ssa/opt/resolve_is_unconstrained.rs @@ -0,0 +1,56 @@ +use crate::ssa::{ + ir::{ + function::{Function, RuntimeType}, + instruction::{Instruction, Intrinsic}, + types::Type, + value::Value, + }, + ssa_gen::Ssa, +}; +use acvm::FieldElement; +use fxhash::FxHashSet as HashSet; + +impl Ssa { + /// An SSA pass to find any calls to `Intrinsic::IsUnconstrained` and replacing any uses of the result of the intrinsic + /// with the resolved boolean value. + /// Note that this pass must run after the pass that does runtime separation, since in SSA generation an ACIR function can end up targeting brillig. + #[tracing::instrument(level = "trace", skip(self))] + pub(crate) fn resolve_is_unconstrained(mut self) -> Self { + for func in self.functions.values_mut() { + replace_is_unconstrained_result(func); + } + self + } +} + +fn replace_is_unconstrained_result(func: &mut Function) { + let mut is_unconstrained_calls = HashSet::default(); + // Collect all calls to is_unconstrained + for block_id in func.reachable_blocks() { + for &instruction_id in func.dfg[block_id].instructions() { + let target_func = match &func.dfg[instruction_id] { + Instruction::Call { func, .. } => *func, + _ => continue, + }; + + if let Value::Intrinsic(Intrinsic::IsUnconstrained) = &func.dfg[target_func] { + is_unconstrained_calls.insert(instruction_id); + } + } + } + + for instruction_id in is_unconstrained_calls { + let call_returns = func.dfg.instruction_results(instruction_id); + let original_return_id = call_returns[0]; + + // We replace the result with a fresh id. This will be unused, so the DIE pass will remove the leftover intrinsic call. + func.dfg.replace_result(instruction_id, original_return_id); + + let is_within_unconstrained = func.dfg.make_constant( + FieldElement::from(matches!(func.runtime(), RuntimeType::Brillig)), + Type::bool(), + ); + // Replace all uses of the original return value with the constant + func.dfg.set_value_from_id(original_return_id, is_within_unconstrained); + } +} diff --git a/docs/docs/noir/standard_library/is_unconstrained.md b/docs/docs/noir/standard_library/is_unconstrained.md new file mode 100644 index 00000000000..bb157e719dc --- /dev/null +++ b/docs/docs/noir/standard_library/is_unconstrained.md @@ -0,0 +1,59 @@ +--- +title: Is Unconstrained Function +description: + The is_unconstrained function returns wether the context at that point of the program is unconstrained or not. +keywords: + [ + unconstrained + ] +--- + +It's very common for functions in circuits to take unconstrained hints of an expensive computation and then verify it. This is done by running the hint in an unconstrained context and then verifying the result in a constrained context. + +When a function is marked as unconstrained, any subsequent functions that it calls will also be run in an unconstrained context. However, if we are implementing a library function, other users might call it within an unconstrained context or a constrained one. Generally, in an unconstrained context we prefer just computing the result instead of taking a hint of it and verifying it, since that'd mean doing the same computation twice: + +```rust + +fn my_expensive_computation(){ + ... +} + +unconstrained fn my_expensive_computation_hint(){ + my_expensive_computation() +} + +pub fn external_interface(){ + my_expensive_computation_hint(); + // verify my_expensive_computation: If external_interface is called from unconstrained, this is redundant + ... +} + +``` + +In order to improve the performance in an unconstrained context you can use the function at `std::runtime::is_unconstrained() -> bool`: + + +```rust +use dep::std::runtime::is_unconstrained; + +fn my_expensive_computation(){ + ... +} + +unconstrained fn my_expensive_computation_hint(){ + my_expensive_computation() +} + +pub fn external_interface(){ + if is_unconstrained() { + my_expensive_computation(); + } else { + my_expensive_computation_hint(); + // verify my_expensive_computation + ... + } +} + +``` + +The is_unconstrained result is resolved at compile time, so in unconstrained contexts the compiler removes the else branch, and in constrained contexts the compiler removes the if branch, reducing the amount of compute necessary to run external_interface. \ No newline at end of file diff --git a/noir_stdlib/src/field/bn254.nr b/noir_stdlib/src/field/bn254.nr index 2e82d9e7c23..bcdc23f80dc 100644 --- a/noir_stdlib/src/field/bn254.nr +++ b/noir_stdlib/src/field/bn254.nr @@ -1,11 +1,13 @@ +use crate::runtime::is_unconstrained; + // The low and high decomposition of the field modulus global PLO: Field = 53438638232309528389504892708671455233; global PHI: Field = 64323764613183177041862057485226039389; global TWO_POW_128: Field = 0x100000000000000000000000000000000; -/// A hint for decomposing a single field into two 16 byte fields. -unconstrained fn decompose_unsafe(x: Field) -> (Field, Field) { +// Decomposes a single field into two 16 byte fields. +fn compute_decomposition(x: Field) -> (Field, Field) { let x_bytes = x.to_le_bytes(32); let mut low: Field = 0; @@ -21,37 +23,11 @@ unconstrained fn decompose_unsafe(x: Field) -> (Field, Field) { (low, high) } -// Assert that (alo > blo && ahi >= bhi) || (alo <= blo && ahi > bhi) -fn assert_gt_limbs(a: (Field, Field), b: (Field, Field)) { - let (alo, ahi) = a; - let (blo, bhi) = b; - let borrow = lte_unsafe_16(alo, blo); - - let rlo = alo - blo - 1 + (borrow as Field) * TWO_POW_128; - let rhi = ahi - bhi - (borrow as Field); - - rlo.assert_max_bit_size(128); - rhi.assert_max_bit_size(128); -} - -/// Decompose a single field into two 16 byte fields. -pub fn decompose(x: Field) -> (Field, Field) { - // Take hints of the decomposition - let (xlo, xhi) = decompose_unsafe(x); - - // Range check the limbs - xlo.assert_max_bit_size(128); - xhi.assert_max_bit_size(128); - - // Check that the decomposition is correct - assert_eq(x, xlo + TWO_POW_128 * xhi); - - // Assert that the decomposition of P is greater than the decomposition of x - assert_gt_limbs((PLO, PHI), (xlo, xhi)); - (xlo, xhi) +unconstrained fn decompose_hint(x: Field) -> (Field, Field) { + compute_decomposition(x) } -fn lt_unsafe_internal(x: Field, y: Field, num_bytes: u32) -> bool { +fn compute_lt(x: Field, y: Field, num_bytes: u32) -> bool { let x_bytes = x.to_le_radix(256, num_bytes); let y_bytes = y.to_le_radix(256, num_bytes); let mut x_is_lt = false; @@ -70,29 +46,67 @@ fn lt_unsafe_internal(x: Field, y: Field, num_bytes: u32) -> bool { x_is_lt } -fn lte_unsafe_internal(x: Field, y: Field, num_bytes: u32) -> bool { +fn compute_lte(x: Field, y: Field, num_bytes: u32) -> bool { if x == y { true } else { - lt_unsafe_internal(x, y, num_bytes) + compute_lt(x, y, num_bytes) } } -unconstrained fn lt_unsafe_32(x: Field, y: Field) -> bool { - lt_unsafe_internal(x, y, 32) +unconstrained fn lt_32_hint(x: Field, y: Field) -> bool { + compute_lt(x, y, 32) } -unconstrained fn lte_unsafe_16(x: Field, y: Field) -> bool { - lte_unsafe_internal(x, y, 16) +unconstrained fn lte_16_hint(x: Field, y: Field) -> bool { + compute_lte(x, y, 16) +} + +// Assert that (alo > blo && ahi >= bhi) || (alo <= blo && ahi > bhi) +fn assert_gt_limbs(a: (Field, Field), b: (Field, Field)) { + let (alo, ahi) = a; + let (blo, bhi) = b; + let borrow = lte_16_hint(alo, blo); + + let rlo = alo - blo - 1 + (borrow as Field) * TWO_POW_128; + let rhi = ahi - bhi - (borrow as Field); + + rlo.assert_max_bit_size(128); + rhi.assert_max_bit_size(128); +} + +/// Decompose a single field into two 16 byte fields. +pub fn decompose(x: Field) -> (Field, Field) { + if is_unconstrained() { + compute_decomposition(x) + } else { + // Take hints of the decomposition + let (xlo, xhi) = decompose_hint(x); + + // Range check the limbs + xlo.assert_max_bit_size(128); + xhi.assert_max_bit_size(128); + + // Check that the decomposition is correct + assert_eq(x, xlo + TWO_POW_128 * xhi); + + // Assert that the decomposition of P is greater than the decomposition of x + assert_gt_limbs((PLO, PHI), (xlo, xhi)); + (xlo, xhi) + } } pub fn assert_gt(a: Field, b: Field) { - // Decompose a and b - let a_limbs = decompose(a); - let b_limbs = decompose(b); + if is_unconstrained() { + assert(compute_lt(b, a, 32)); + } else { + // Decompose a and b + let a_limbs = decompose(a); + let b_limbs = decompose(b); - // Assert that a_limbs is greater than b_limbs - assert_gt_limbs(a_limbs, b_limbs) + // Assert that a_limbs is greater than b_limbs + assert_gt_limbs(a_limbs, b_limbs) + } } pub fn assert_lt(a: Field, b: Field) { @@ -100,14 +114,19 @@ pub fn assert_lt(a: Field, b: Field) { } pub fn gt(a: Field, b: Field) -> bool { - if a == b { - false - } else if lt_unsafe_32(a, b) { - assert_gt(b, a); + if is_unconstrained() { + compute_lt(b, a, 32) + } else if a == b { false - } else { - assert_gt(a, b); - true + } else { + // Take a hint of the comparison and verify it + if lt_32_hint(a, b) { + assert_gt(b, a); + false + } else { + assert_gt(a, b); + true + } } } @@ -117,44 +136,41 @@ pub fn lt(a: Field, b: Field) -> bool { mod tests { // TODO: Allow imports from "super" - use crate::field::bn254::{ - decompose_unsafe, decompose, lt_unsafe_internal, assert_gt, gt, lt, TWO_POW_128, - lte_unsafe_internal, PLO, PHI - }; + use crate::field::bn254::{decompose_hint, decompose, compute_lt, assert_gt, gt, lt, TWO_POW_128, compute_lte, PLO, PHI}; #[test] - fn check_decompose_unsafe() { - assert_eq(decompose_unsafe(TWO_POW_128), (0, 1)); - assert_eq(decompose_unsafe(TWO_POW_128 + 0x1234567890), (0x1234567890, 1)); - assert_eq(decompose_unsafe(0x1234567890), (0x1234567890, 0)); + fn check_decompose() { + assert_eq(decompose(TWO_POW_128), (0, 1)); + assert_eq(decompose(TWO_POW_128 + 0x1234567890), (0x1234567890, 1)); + assert_eq(decompose(0x1234567890), (0x1234567890, 0)); } #[test] - fn check_decompose() { + unconstrained fn check_decompose_unconstrained() { assert_eq(decompose(TWO_POW_128), (0, 1)); assert_eq(decompose(TWO_POW_128 + 0x1234567890), (0x1234567890, 1)); assert_eq(decompose(0x1234567890), (0x1234567890, 0)); } #[test] - fn check_lt_unsafe() { - assert(lt_unsafe_internal(0, 1, 16)); - assert(lt_unsafe_internal(0, 0x100, 16)); - assert(lt_unsafe_internal(0x100, TWO_POW_128 - 1, 16)); - assert(!lt_unsafe_internal(0, TWO_POW_128, 16)); + fn check_compute_lt() { + assert(compute_lt(0, 1, 16)); + assert(compute_lt(0, 0x100, 16)); + assert(compute_lt(0x100, TWO_POW_128 - 1, 16)); + assert(!compute_lt(0, TWO_POW_128, 16)); } #[test] - fn check_lte_unsafe() { - assert(lte_unsafe_internal(0, 1, 16)); - assert(lte_unsafe_internal(0, 0x100, 16)); - assert(lte_unsafe_internal(0x100, TWO_POW_128 - 1, 16)); - assert(!lte_unsafe_internal(0, TWO_POW_128, 16)); - - assert(lte_unsafe_internal(0, 0, 16)); - assert(lte_unsafe_internal(0x100, 0x100, 16)); - assert(lte_unsafe_internal(TWO_POW_128 - 1, TWO_POW_128 - 1, 16)); - assert(lte_unsafe_internal(TWO_POW_128, TWO_POW_128, 16)); + fn check_compute_lte() { + assert(compute_lte(0, 1, 16)); + assert(compute_lte(0, 0x100, 16)); + assert(compute_lte(0x100, TWO_POW_128 - 1, 16)); + assert(!compute_lte(0, TWO_POW_128, 16)); + + assert(compute_lte(0, 0, 16)); + assert(compute_lte(0x100, 0x100, 16)); + assert(compute_lte(TWO_POW_128 - 1, TWO_POW_128 - 1, 16)); + assert(compute_lte(TWO_POW_128, TWO_POW_128, 16)); } #[test] @@ -166,6 +182,15 @@ mod tests { assert_gt(0 - 1, 0); } + #[test] + unconstrained fn check_assert_gt_unconstrained() { + assert_gt(1, 0); + assert_gt(0x100, 0); + assert_gt((0 - 1), (0 - 2)); + assert_gt(TWO_POW_128, 0); + assert_gt(0 - 1, 0); + } + #[test] fn check_gt() { assert(gt(1, 0)); @@ -178,6 +203,18 @@ mod tests { assert(!gt(0 - 2, 0 - 1)); } + #[test] + unconstrained fn check_gt_unconstrained() { + assert(gt(1, 0)); + assert(gt(0x100, 0)); + assert(gt((0 - 1), (0 - 2))); + assert(gt(TWO_POW_128, 0)); + assert(!gt(0, 0)); + assert(!gt(0, 0x100)); + assert(gt(0 - 1, 0 - 2)); + assert(!gt(0 - 2, 0 - 1)); + } + #[test] fn check_plo_phi() { assert_eq(PLO + PHI * TWO_POW_128, 0); diff --git a/noir_stdlib/src/lib.nr b/noir_stdlib/src/lib.nr index f11b21003ad..ad47171fa46 100644 --- a/noir_stdlib/src/lib.nr +++ b/noir_stdlib/src/lib.nr @@ -25,6 +25,7 @@ mod default; mod prelude; mod uint128; mod bigint; +mod runtime; // Oracle calls are required to be wrapped in an unconstrained function // Thus, the only argument to the `println` oracle is expected to always be an ident @@ -70,3 +71,4 @@ pub fn wrapping_mul(x: T, y: T) -> T { #[builtin(as_witness)] pub fn as_witness(x: Field) {} + diff --git a/noir_stdlib/src/runtime.nr b/noir_stdlib/src/runtime.nr new file mode 100644 index 00000000000..c075107cd52 --- /dev/null +++ b/noir_stdlib/src/runtime.nr @@ -0,0 +1,2 @@ +#[builtin(is_unconstrained)] +pub fn is_unconstrained() -> bool {} diff --git a/test_programs/execution_success/is_unconstrained/Nargo.toml b/test_programs/execution_success/is_unconstrained/Nargo.toml new file mode 100644 index 00000000000..deef68c7f72 --- /dev/null +++ b/test_programs/execution_success/is_unconstrained/Nargo.toml @@ -0,0 +1,6 @@ +[package] +name = "is_unconstrained" +type = "bin" +authors = [""] + +[dependencies] diff --git a/test_programs/execution_success/is_unconstrained/Prover.toml b/test_programs/execution_success/is_unconstrained/Prover.toml new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/test_programs/execution_success/is_unconstrained/Prover.toml @@ -0,0 +1 @@ + diff --git a/test_programs/execution_success/is_unconstrained/src/main.nr b/test_programs/execution_success/is_unconstrained/src/main.nr new file mode 100644 index 00000000000..af40af1029f --- /dev/null +++ b/test_programs/execution_success/is_unconstrained/src/main.nr @@ -0,0 +1,14 @@ +use dep::std::runtime::is_unconstrained; + +fn check(should_be_unconstrained: bool) { + assert_eq(should_be_unconstrained, is_unconstrained()); +} + +unconstrained fn unconstrained_intermediate() { + check(true); +} + +fn main() { + unconstrained_intermediate(); + check(false); +} diff --git a/tooling/debugger/ignored-tests.txt b/tooling/debugger/ignored-tests.txt index cda26169421..a6d3c9a3a94 100644 --- a/tooling/debugger/ignored-tests.txt +++ b/tooling/debugger/ignored-tests.txt @@ -25,3 +25,4 @@ fold_fibonacci fold_complex_outputs slice_init_with_complex_type hashmap +is_unconstrained \ No newline at end of file From 9db206e98555ccd8089256144ef39ed43bd981b6 Mon Sep 17 00:00:00 2001 From: guipublic <47281315+guipublic@users.noreply.github.com> Date: Fri, 24 May 2024 18:03:43 +0200 Subject: [PATCH 30/61] chore: Avoid creating witness for simple multiplications (#5100) # Description ## Problem\* Related to #4629 ## Summary\* Do not create a witness when multiplying a witness (or an affine transformation of a witness) with an expression of degree 1. ## Additional Context This PR does NOT fix the issue #4629, but it should help reducing the overall gates number. The arithmetic expressions resulting from the multiplication should not explode in width since I only consider multiplication with a witness (or 'affine witness'). ## Documentation\* Check one: - [X] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [X] I have tested the changes locally. - [X] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../acvm/src/compiler/transformers/csat.rs | 4 +- .../src/ssa/acir_gen/acir_ir/acir_variable.rs | 41 ++++++++++++++++--- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/acvm-repo/acvm/src/compiler/transformers/csat.rs b/acvm-repo/acvm/src/compiler/transformers/csat.rs index 9e2e3091c74..12a37e3e37a 100644 --- a/acvm-repo/acvm/src/compiler/transformers/csat.rs +++ b/acvm-repo/acvm/src/compiler/transformers/csat.rs @@ -210,16 +210,16 @@ impl CSatTransformer { } } else { // No more usable elements left in the old opcode - opcode.linear_combinations = remaining_linear_terms; break; } } + opcode.linear_combinations.extend(remaining_linear_terms); + // Constraint this intermediate_opcode to be equal to the temp variable by adding it into the IndexMap // We need a unique name for our intermediate variable // XXX: Another optimization, which could be applied in another algorithm // If two opcodes have a large fan-in/out and they share a few common terms, then we should create intermediate variables for them // Do some sort of subset matching algorithm for this on the terms of the polynomial - let inter_var = Self::get_or_create_intermediate_vars( intermediate_variables, intermediate_opcode, diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index 90cdbb650c2..b6e88a8d4b0 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -614,13 +614,44 @@ impl AcirContext { expr.push_multiplication_term(FieldElement::one(), lhs_witness, rhs_witness); self.add_data(AcirVarData::Expr(expr)) } - ( - AcirVarData::Expr(_) | AcirVarData::Witness(_), - AcirVarData::Expr(_) | AcirVarData::Witness(_), - ) => { + (AcirVarData::Expr(expression), AcirVarData::Witness(witness)) + | (AcirVarData::Witness(witness), AcirVarData::Expr(expression)) + if expression.is_linear() => + { + let mut expr = Expression::default(); + for term in expression.linear_combinations.iter() { + expr.push_multiplication_term(term.0, term.1, witness); + } + expr.push_addition_term(expression.q_c, witness); + self.add_data(AcirVarData::Expr(expr)) + } + (AcirVarData::Expr(lhs_expr), AcirVarData::Expr(rhs_expr)) => { + let degree_one = if lhs_expr.is_linear() && rhs_expr.is_degree_one_univariate() { + Some((lhs_expr, rhs_expr)) + } else if rhs_expr.is_linear() && lhs_expr.is_degree_one_univariate() { + Some((rhs_expr, lhs_expr)) + } else { + None + }; + if let Some((lin, univariate)) = degree_one { + let mut expr = Expression::default(); + let rhs_term = univariate.linear_combinations[0]; + for term in lin.linear_combinations.iter() { + expr.push_multiplication_term(term.0 * rhs_term.0, term.1, rhs_term.1); + } + expr.push_addition_term(lin.q_c * rhs_term.0, rhs_term.1); + expr.sort(); + expr = expr.add_mul(univariate.q_c, &lin); + self.add_data(AcirVarData::Expr(expr)) + } else { + let lhs = self.get_or_create_witness_var(lhs)?; + let rhs = self.get_or_create_witness_var(rhs)?; + self.mul_var(lhs, rhs)? + } + } + _ => { let lhs = self.get_or_create_witness_var(lhs)?; let rhs = self.get_or_create_witness_var(rhs)?; - self.mul_var(lhs, rhs)? } }; From 6a7c7a95864a60a34a79e896163ba2b70cd06bbe Mon Sep 17 00:00:00 2001 From: josh crites Date: Fri, 24 May 2024 17:23:53 -0400 Subject: [PATCH 31/61] chore(docs): Link to evmdiff for supported EVM chains (#5107) # Description Links to evmdiff.com to show which EVM chains have the required precompiles ## Problem\* related to #4964 ## Summary\* ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [x] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- docs/docs/how_to/how-to-solidity-verifier.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/how_to/how-to-solidity-verifier.md b/docs/docs/how_to/how-to-solidity-verifier.md index 7c96e22b8d5..e6ed9abaec6 100644 --- a/docs/docs/how_to/how-to-solidity-verifier.md +++ b/docs/docs/how_to/how-to-solidity-verifier.md @@ -230,7 +230,7 @@ It would be incorrect to say that a Noir proof verification costs any gas at all ## A Note on EVM chains -ZK-SNARK verification depends on some precompiled cryptographic primitives such as Elliptic Curve Pairings (if you like complex math, you can read about EC Pairings [here](https://medium.com/@VitalikButerin/exploring-elliptic-curve-pairings-c73c1864e627)). Not all EVM chains support EC Pairings, notably some of the ZK-EVMs. This means that you won't be able to use the verifier contract in all of them. +Noir proof verification requires the ecMul, ecAdd and ecPairing precompiles. Not all EVM chains support EC Pairings, notably some of the ZK-EVMs. This means that you won't be able to use the verifier contract in all of them. You can find an incomplete list of which EVM chains support these precompiles [here](https://www.evmdiff.com/features?feature=precompiles). For example, chains like `zkSync ERA` and `Polygon zkEVM` do not currently support these precompiles, so proof verification via Solidity verifier contracts won't work. Here's a quick list of EVM chains that have been tested and are known to work: From e4eb5f539f377fd3c2e1a874707ffce62a5bc10a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Mon, 27 May 2024 11:30:33 +0200 Subject: [PATCH 32/61] feat: Consider block parameters in variable liveness (#5097) # Description ## Problem\* Previously, on variable liveness we completely ignored block parameters, by allocating all the parameters of all blocks at the start of the function codegen and maintaining them allocated for the whole function. ## Summary\* With this change, we add a definition point for block parameters and we start considering them and allocating and freeing them dynamically. This should save space in the stack, especially in heavily inlined functions with many blocks. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../src/brillig/brillig_gen.rs | 2 +- .../src/brillig/brillig_gen/brillig_block.rs | 35 +++-- .../brillig_gen/brillig_block_variables.rs | 48 ++---- .../src/brillig/brillig_gen/brillig_fn.rs | 31 +--- .../brillig/brillig_gen/brillig_slice_ops.rs | 4 +- .../brillig/brillig_gen/variable_liveness.rs | 138 +++++++++++++++--- .../Nargo.toml | 6 + .../Prover.toml | 1 + .../src/main.nr | 91 ++++++++++++ 9 files changed, 247 insertions(+), 109 deletions(-) create mode 100644 test_programs/execution_success/brillig_block_parameter_liveness/Nargo.toml create mode 100644 test_programs/execution_success/brillig_block_parameter_liveness/Prover.toml create mode 100644 test_programs/execution_success/brillig_block_parameter_liveness/src/main.nr diff --git a/compiler/noirc_evaluator/src/brillig/brillig_gen.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen.rs index 22814a22889..5576d673f1d 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_gen.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen.rs @@ -14,7 +14,7 @@ use crate::ssa::ir::function::Function; pub(crate) fn convert_ssa_function(func: &Function, enable_debug_trace: bool) -> BrilligArtifact { let mut brillig_context = BrilligContext::new(enable_debug_trace); - let mut function_context = FunctionContext::new(func, &mut brillig_context); + let mut function_context = FunctionContext::new(func); brillig_context.enter_context(FunctionContext::function_id_to_function_label(func.id())); diff --git a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs index 6a4f9f5cc0e..0dbab80dace 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs @@ -7,7 +7,7 @@ use crate::brillig::brillig_ir::{ use crate::ssa::ir::dfg::CallStack; use crate::ssa::ir::instruction::ConstrainError; use crate::ssa::ir::{ - basic_block::{BasicBlock, BasicBlockId}, + basic_block::BasicBlockId, dfg::DataFlowGraph, function::FunctionId, instruction::{ @@ -49,8 +49,7 @@ impl<'block> BrilligBlock<'block> { dfg: &DataFlowGraph, ) { let live_in = function_context.liveness.get_live_in(&block_id); - let variables = - BlockVariables::new(live_in.clone(), function_context.all_block_parameters()); + let variables = BlockVariables::new(live_in.clone()); brillig_context.set_allocated_registers( variables @@ -72,9 +71,9 @@ impl<'block> BrilligBlock<'block> { let block_label = self.create_block_label_for_current_function(self.block_id); self.brillig_context.enter_context(block_label); - // Convert the block parameters + self.convert_block_params(dfg); + let block = &dfg[self.block_id]; - self.convert_block_params(block, dfg); // Convert all of the instructions into the block for instruction_id in block.instructions() { @@ -134,12 +133,8 @@ impl<'block> BrilligBlock<'block> { let target_block = &dfg[*destination_block]; for (src, dest) in arguments.iter().zip(target_block.parameters()) { // Destinations are block parameters so they should have been allocated previously. - let destination = self.variables.get_block_param( - self.function_context, - *destination_block, - *dest, - dfg, - ); + let destination = + self.variables.get_allocation(self.function_context, *dest, dfg); let source = self.convert_ssa_value(*src, dfg); self.pass_variable(source, destination); } @@ -206,10 +201,14 @@ impl<'block> BrilligBlock<'block> { } } - /// Converts SSA Block parameters into Brillig Registers. - fn convert_block_params(&mut self, block: &BasicBlock, dfg: &DataFlowGraph) { - for param_id in block.parameters() { - let value = &dfg[*param_id]; + /// Allocates the block parameters that the given block is defining + fn convert_block_params(&mut self, dfg: &DataFlowGraph) { + // We don't allocate the block parameters here, we allocate the parameters the block is defining. + // Since predecessors to a block have to know where the parameters of the block are allocated to pass data to it, + // the block parameters need to be defined/allocated before the given block. Variable liveness provides when the block parameters are defined. + // For the entry block, the defined block params will be the params of the function + any extra params of blocks it's the immediate dominator of. + for param_id in self.function_context.liveness.defined_block_params(&self.block_id) { + let value = &dfg[param_id]; let param_type = match value { Value::Param { typ, .. } => typ, _ => unreachable!("ICE: Only Param type values should appear in block parameters"), @@ -220,10 +219,10 @@ impl<'block> BrilligBlock<'block> { // Be a valid pointer to the array. // For slices, two registers are passed, the pointer to the data and a register holding the size of the slice. Type::Numeric(_) | Type::Array(..) | Type::Slice(..) | Type::Reference(_) => { - self.variables.get_block_param( + self.variables.define_variable( self.function_context, - self.block_id, - *param_id, + self.brillig_context, + param_id, dfg, ); } diff --git a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block_variables.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block_variables.rs index 892e82d771a..fb9a8577d94 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block_variables.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block_variables.rs @@ -9,7 +9,6 @@ use crate::{ BrilligContext, }, ssa::ir::{ - basic_block::BasicBlockId, dfg::DataFlowGraph, types::{CompositeType, Type}, value::ValueId, @@ -21,18 +20,13 @@ use super::brillig_fn::FunctionContext; #[derive(Debug, Default)] pub(crate) struct BlockVariables { available_variables: HashSet, - block_parameters: HashSet, available_constants: HashMap, } impl BlockVariables { /// Creates a BlockVariables instance. It uses the variables that are live in to the block and the global available variables (block parameters) - pub(crate) fn new(live_in: HashSet, all_block_parameters: HashSet) -> Self { - BlockVariables { - available_variables: live_in.into_iter().chain(all_block_parameters.clone()).collect(), - block_parameters: all_block_parameters, - ..Default::default() - } + pub(crate) fn new(live_in: HashSet) -> Self { + BlockVariables { available_variables: live_in, ..Default::default() } } /// Returns all non-constant variables that have not been removed at this point. @@ -92,16 +86,13 @@ impl BlockVariables { brillig_context: &mut BrilligContext, ) { assert!(self.available_variables.remove(value_id), "ICE: Variable is not available"); - // Block parameters should not be deallocated - if !self.block_parameters.contains(value_id) { - let variable = function_context - .ssa_value_allocations - .get(value_id) - .expect("ICE: Variable allocation not found"); - variable.extract_registers().iter().for_each(|register| { - brillig_context.deallocate_register(*register); - }); - } + let variable = function_context + .ssa_value_allocations + .get(value_id) + .expect("ICE: Variable allocation not found"); + variable.extract_registers().iter().for_each(|register| { + brillig_context.deallocate_register(*register); + }); } /// For a given SSA value id, return the corresponding cached allocation. @@ -155,27 +146,6 @@ impl BlockVariables { pub(crate) fn dump_constants(&mut self) { self.available_constants.clear(); } - - /// For a given block parameter, return the allocation that was done globally to the function. - pub(crate) fn get_block_param( - &mut self, - function_context: &FunctionContext, - block_id: BasicBlockId, - value_id: ValueId, - dfg: &DataFlowGraph, - ) -> BrilligVariable { - let value_id = dfg.resolve(value_id); - assert!( - function_context - .block_parameters - .get(&block_id) - .expect("Block not found") - .contains(&value_id), - "Value is not a block parameter" - ); - - *function_context.ssa_value_allocations.get(&value_id).expect("Block param not found") - } } /// Computes the length of an array. This will match with the indexes that SSA will issue diff --git a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_fn.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_fn.rs index 617e400b92f..000d1230ece 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_fn.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_fn.rs @@ -4,7 +4,6 @@ use crate::{ brillig::brillig_ir::{ artifact::{BrilligParameter, Label}, brillig_variable::{get_bit_size_from_ssa_type, BrilligVariable}, - BrilligContext, }, ssa::ir::{ basic_block::BasicBlockId, @@ -14,16 +13,14 @@ use crate::{ value::ValueId, }, }; -use fxhash::{FxHashMap as HashMap, FxHashSet as HashSet}; +use fxhash::FxHashMap as HashMap; -use super::{brillig_block_variables::allocate_value, variable_liveness::VariableLiveness}; +use super::variable_liveness::VariableLiveness; pub(crate) struct FunctionContext { pub(crate) function_id: FunctionId, /// Map from SSA values its allocation. Since values can be only defined once in SSA form, we insert them here on when we allocate them at their definition. pub(crate) ssa_value_allocations: HashMap, - /// Block parameters are pre allocated at the function level. - pub(crate) block_parameters: HashMap>, /// The block ids of the function in reverse post order. pub(crate) blocks: Vec, /// Liveness information for each variable in the function. @@ -31,40 +28,22 @@ pub(crate) struct FunctionContext { } impl FunctionContext { - /// Creates a new function context. It will allocate parameters for all blocks and compute the liveness of every variable. - pub(crate) fn new(function: &Function, brillig_context: &mut BrilligContext) -> Self { + /// Creates a new function context. It will compute the liveness of every variable. + pub(crate) fn new(function: &Function) -> Self { let id = function.id(); let mut reverse_post_order = Vec::new(); reverse_post_order.extend_from_slice(PostOrder::with_function(function).as_slice()); reverse_post_order.reverse(); - let mut block_parameters = HashMap::default(); - let mut ssa_variable_to_register_or_memory = HashMap::default(); - - for &block_id in &reverse_post_order { - let block = &function.dfg[block_id]; - let parameters = block.parameters().to_vec(); - parameters.iter().for_each(|&value_id| { - let variable = allocate_value(value_id, brillig_context, &function.dfg); - ssa_variable_to_register_or_memory.insert(value_id, variable); - }); - block_parameters.insert(block_id, parameters); - } - Self { function_id: id, - ssa_value_allocations: ssa_variable_to_register_or_memory, - block_parameters, + ssa_value_allocations: HashMap::default(), blocks: reverse_post_order, liveness: VariableLiveness::from_function(function), } } - pub(crate) fn all_block_parameters(&self) -> HashSet { - self.block_parameters.values().flat_map(|parameters| parameters.iter()).cloned().collect() - } - /// Creates a function label from a given SSA function id. pub(crate) fn function_id_to_function_label(function_id: FunctionId) -> Label { function_id.to_string() diff --git a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs index 3e1515b1eed..491086e8c0f 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs @@ -377,9 +377,9 @@ mod tests { builder.set_runtime(RuntimeType::Brillig); let ssa = builder.finish(); - let mut brillig_context = create_context(); + let brillig_context = create_context(); - let function_context = FunctionContext::new(ssa.main(), &mut brillig_context); + let function_context = FunctionContext::new(ssa.main()); (ssa, function_context, brillig_context) } diff --git a/compiler/noirc_evaluator/src/brillig/brillig_gen/variable_liveness.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/variable_liveness.rs index c9f1cd1e247..52eded81919 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_gen/variable_liveness.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/variable_liveness.rs @@ -93,6 +93,9 @@ fn variables_used_in_block(block: &BasicBlock, dfg: &DataFlowGraph) -> Vec Vec; -fn compute_defined_variables(block: &BasicBlock, dfg: &DataFlowGraph) -> Variables { - let mut defined_vars = HashSet::default(); - - for parameter in block.parameters() { - defined_vars.insert(dfg.resolve(*parameter)); - } - - for instruction_id in block.instructions() { - let result_values = dfg.instruction_results(*instruction_id); - for result_value in result_values { - defined_vars.insert(dfg.resolve(*result_value)); - } - } - - defined_vars -} - fn compute_used_before_def( block: &BasicBlock, dfg: &DataFlowGraph, @@ -142,6 +128,8 @@ pub(crate) struct VariableLiveness { live_in: HashMap, /// The variables that stop being alive after each specific instruction last_uses: HashMap, + /// The list of block params the given block is defining. The order matters for the entry block, so it's a vec. + param_definitions: HashMap>, } impl VariableLiveness { @@ -150,8 +138,15 @@ impl VariableLiveness { let cfg = ControlFlowGraph::with_function(func); let post_order = PostOrder::with_function(func); - let mut instance = - Self { cfg, post_order, live_in: HashMap::default(), last_uses: HashMap::default() }; + let mut instance = Self { + cfg, + post_order, + live_in: HashMap::default(), + last_uses: HashMap::default(), + param_definitions: HashMap::default(), + }; + + instance.compute_block_param_definitions(func); instance.compute_live_in_of_blocks(func); @@ -179,6 +174,30 @@ impl VariableLiveness { self.last_uses.get(block_id).expect("Last uses should have been calculated") } + /// Retrieves the list of block params the given block is defining. + /// Block params are defined before the block that owns them (since they are used by the predecessor blocks). They must be defined in the immediate dominator. + /// This is the last point where the block param can be allocated without it being allocated in different places in different branches. + pub(crate) fn defined_block_params(&self, block_id: &BasicBlockId) -> Vec { + self.param_definitions.get(block_id).cloned().unwrap_or_default() + } + + fn compute_block_param_definitions(&mut self, func: &Function) { + let tree = DominatorTree::with_cfg_and_post_order(&self.cfg, &self.post_order); + + // Going in reverse post order to process the entry block first + let mut reverse_post_order = Vec::new(); + reverse_post_order.extend_from_slice(self.post_order.as_slice()); + reverse_post_order.reverse(); + for block in reverse_post_order { + let params = func.dfg[block].parameters(); + // If it has no dominator, it's the entry block + let dominator_block = tree.immediate_dominator(block).unwrap_or(func.entry_block()); + let definitions_for_the_dominator = + self.param_definitions.entry(dominator_block).or_default(); + definitions_for_the_dominator.extend(params.iter()); + } + } + fn compute_live_in_of_blocks(&mut self, func: &Function) { let back_edges = find_back_edges(func, &self.cfg, &self.post_order); @@ -197,9 +216,10 @@ impl VariableLiveness { block_id: BasicBlockId, back_edges: &HashSet, ) { - let block = &func.dfg[block_id]; + let defined = self.compute_defined_variables(block_id, &func.dfg); + + let block: &BasicBlock = &func.dfg[block_id]; - let defined = compute_defined_variables(block, &func.dfg); let used_before_def = compute_used_before_def(block, &func.dfg, &defined); let mut live_out = HashSet::default(); @@ -222,6 +242,24 @@ impl VariableLiveness { self.live_in.insert(block_id, used_before_def.union(&passthrough_vars).cloned().collect()); } + fn compute_defined_variables(&self, block_id: BasicBlockId, dfg: &DataFlowGraph) -> Variables { + let block: &BasicBlock = &dfg[block_id]; + let mut defined_vars = HashSet::default(); + + for parameter in self.defined_block_params(&block_id) { + defined_vars.insert(dfg.resolve(parameter)); + } + + for instruction_id in block.instructions() { + let result_values = dfg.instruction_results(*instruction_id); + for result_value in result_values { + defined_vars.insert(dfg.resolve(*result_value)); + } + } + + defined_vars + } + fn update_live_ins_within_loop(&mut self, back_edge: BackEdge) { let header_live_ins = self .live_in @@ -513,12 +551,12 @@ mod test { let liveness = VariableLiveness::from_function(func); assert!(liveness.get_live_in(&func.entry_block()).is_empty()); - assert_eq!(liveness.get_live_in(&b1), &FxHashSet::from_iter([v0, v1, v3].into_iter())); + assert_eq!(liveness.get_live_in(&b1), &FxHashSet::from_iter([v0, v1, v3, v4].into_iter())); assert_eq!(liveness.get_live_in(&b3), &FxHashSet::from_iter([v3].into_iter())); assert_eq!(liveness.get_live_in(&b2), &FxHashSet::from_iter([v0, v1, v3, v4].into_iter())); assert_eq!( liveness.get_live_in(&b4), - &FxHashSet::from_iter([v0, v1, v3, v4, v6].into_iter()) + &FxHashSet::from_iter([v0, v1, v3, v4, v6, v7].into_iter()) ); assert_eq!(liveness.get_live_in(&b6), &FxHashSet::from_iter([v0, v1, v3, v4].into_iter())); assert_eq!( @@ -540,4 +578,58 @@ mod test { Some(&FxHashSet::from_iter([v3].into_iter())) ); } + + #[test] + fn block_params() { + // brillig fn main f0 { + // b0(v0: u1): + // jmpif v0 then: b1, else: b2 + // b1(): + // jmp b3(Field 27, Field 29) + // b3(v1: Field, v2: Field): + // return v1 + // b2(): + // jmp b3(Field 28, Field 40) + // } + + let main_id = Id::test_new(1); + let mut builder = FunctionBuilder::new("main".into(), main_id); + builder.set_runtime(RuntimeType::Brillig); + + let v0 = builder.add_parameter(Type::bool()); + + let b1 = builder.insert_block(); + let b2 = builder.insert_block(); + let b3 = builder.insert_block(); + + builder.terminate_with_jmpif(v0, b1, b2); + + builder.switch_to_block(b1); + let twenty_seven = builder.field_constant(27_u128); + let twenty_nine = builder.field_constant(29_u128); + builder.terminate_with_jmp(b3, vec![twenty_seven, twenty_nine]); + + builder.switch_to_block(b3); + let v1 = builder.add_block_parameter(b3, Type::field()); + let v2 = builder.add_block_parameter(b3, Type::field()); + builder.terminate_with_return(vec![v1]); + + builder.switch_to_block(b2); + let twenty_eight = builder.field_constant(28_u128); + let forty = builder.field_constant(40_u128); + builder.terminate_with_jmp(b3, vec![twenty_eight, forty]); + + let ssa = builder.finish(); + let func = ssa.main(); + let liveness = VariableLiveness::from_function(func); + + // Entry point defines its own params and also b3's params. + assert_eq!(liveness.defined_block_params(&func.entry_block()), vec![v0, v1, v2]); + assert_eq!(liveness.defined_block_params(&b1), vec![]); + assert_eq!(liveness.defined_block_params(&b2), vec![]); + assert_eq!(liveness.defined_block_params(&b3), vec![]); + + assert_eq!(liveness.get_live_in(&b1), &FxHashSet::from_iter([v1, v2].into_iter())); + assert_eq!(liveness.get_live_in(&b2), &FxHashSet::from_iter([v1, v2].into_iter())); + } } diff --git a/test_programs/execution_success/brillig_block_parameter_liveness/Nargo.toml b/test_programs/execution_success/brillig_block_parameter_liveness/Nargo.toml new file mode 100644 index 00000000000..e094862a1dc --- /dev/null +++ b/test_programs/execution_success/brillig_block_parameter_liveness/Nargo.toml @@ -0,0 +1,6 @@ +[package] +name = "brillig_block_parameter_liveness" +type = "bin" +authors = [""] + +[dependencies] diff --git a/test_programs/execution_success/brillig_block_parameter_liveness/Prover.toml b/test_programs/execution_success/brillig_block_parameter_liveness/Prover.toml new file mode 100644 index 00000000000..6b7fd9c6ab6 --- /dev/null +++ b/test_programs/execution_success/brillig_block_parameter_liveness/Prover.toml @@ -0,0 +1 @@ +conditions = ["1", "0", "1", "0", "1"] diff --git a/test_programs/execution_success/brillig_block_parameter_liveness/src/main.nr b/test_programs/execution_success/brillig_block_parameter_liveness/src/main.nr new file mode 100644 index 00000000000..142290ecbe2 --- /dev/null +++ b/test_programs/execution_success/brillig_block_parameter_liveness/src/main.nr @@ -0,0 +1,91 @@ +// Tests that we run liveness in block parameters by trying to create too many block parameters to fit in the stack + +// Uses up 10 stack items +struct Inner { + a: u64, + b: u64, + c: u64, + d: u64, + e: u64, + f: u64, + g: u64, + h: u64, + i: u64, + j: u64, +} + +// Uses up 50 stack items +struct Middle { + inner_a: Inner, + inner_b: Inner, + inner_c: Inner, + inner_d: Inner, + inner_e: Inner, +} + +// Uses up 500 stack items +struct Outer { + middle_a: Middle, + middle_b: Middle, + middle_c: Middle, + middle_d: Middle, + middle_e: Middle, + middle_f: Middle, + middle_g: Middle, + middle_h: Middle, +} + +// If we don't take into account block parameter liveness, this function will need 5*500=2500 stack items +unconstrained fn main(conditions: [bool; 5]) -> pub Outer { + let out0 = if conditions[0] { + let mut outer: Outer = dep::std::unsafe::zeroed(); + outer.middle_a.inner_a.a = 1; + outer + } else { + let mut outer: Outer= dep::std::unsafe::zeroed(); + outer.middle_f.inner_c.d = 2; + outer + }; + + let out1 = if conditions[1] { + let mut new_outer = out0; + new_outer.middle_a.inner_a.b = 3; + new_outer + } else { + let mut new_outer = out0; + new_outer.middle_f.inner_c.c = 4; + new_outer + }; + + let out2 = if conditions[2] { + let mut new_outer = out1; + new_outer.middle_a.inner_a.c = 5; + new_outer + } else { + let mut new_outer = out1; + new_outer.middle_f.inner_c.b = 6; + new_outer + }; + + let out3 = if conditions[3] { + let mut new_outer = out2; + new_outer.middle_a.inner_a.d = 7; + new_outer + } else { + let mut new_outer = out2; + new_outer.middle_f.inner_c.a = 8; + new_outer + }; + + let out4 = if conditions[4] { + let mut new_outer = out3; + new_outer.middle_a.inner_a.f = 9; + new_outer + } else { + let mut new_outer = out3; + new_outer.middle_f.inner_c.f = 10; + new_outer + }; + + out4 +} From b359bacf6981343bba4e684489a58573e20dfdb4 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 28 May 2024 15:54:08 +0100 Subject: [PATCH 33/61] chore: perform dead instruction elimination through `std::as_witness` (#5123) # Description ## Problem\* Resolves ## Summary\* This PR adds handling for `std::as_witness` in dead instruction elimination. i.e. if we're asking for an SSA value to be assigned to a witness when that value would not otherwise be represented in the ACIR then we can remove it. This issue can be seen in #5122 where making two calls to the same function with the same inputs and asserting that the outputs are the same results in constraints whereas this can be determined at runtime. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_evaluator/src/ssa/ir/dfg.rs | 2 +- compiler/noirc_evaluator/src/ssa/opt/die.rs | 49 ++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/ir/dfg.rs b/compiler/noirc_evaluator/src/ssa/ir/dfg.rs index 85630b75614..c71781557bd 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/dfg.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/dfg.rs @@ -284,7 +284,7 @@ impl DataFlowGraph { intrinsic_value_id } - pub(crate) fn get_intrinsic(&mut self, intrinsic: Intrinsic) -> Option<&ValueId> { + pub(crate) fn get_intrinsic(&self, intrinsic: Intrinsic) -> Option<&ValueId> { self.intrinsics.get(&intrinsic) } diff --git a/compiler/noirc_evaluator/src/ssa/opt/die.rs b/compiler/noirc_evaluator/src/ssa/opt/die.rs index d045762f9e9..42383680f44 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/die.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/die.rs @@ -7,7 +7,7 @@ use crate::ssa::{ basic_block::{BasicBlock, BasicBlockId}, dfg::DataFlowGraph, function::Function, - instruction::{Instruction, InstructionId}, + instruction::{Instruction, InstructionId, Intrinsic}, post_order::PostOrder, value::{Value, ValueId}, }, @@ -111,6 +111,10 @@ impl Context { if instruction.can_eliminate_if_unused(&function.dfg) { let results = function.dfg.instruction_results(instruction_id); results.iter().all(|result| !self.used_values.contains(result)) + } else if let Instruction::Call { func, arguments } = instruction { + // TODO: make this more general for instructions which don't have results but have side effects "sometimes" like `Intrinsic::AsWitness` + let as_witness_id = function.dfg.get_intrinsic(Intrinsic::AsWitness); + as_witness_id == Some(func) && !self.used_values.contains(&arguments[0]) } else { // If the instruction has side effects we should never remove it. false @@ -256,4 +260,47 @@ mod test { assert_eq!(main.dfg[main.entry_block()].instructions().len(), 1); assert_eq!(main.dfg[b1].instructions().len(), 6); } + + #[test] + fn as_witness_die() { + // fn main f0 { + // b0(v0: Field): + // v1 = add v0, Field 1 + // v2 = add v0, Field 2 + // call as_witness(v2) + // return v1 + // } + let main_id = Id::test_new(0); + + // Compiling main + let mut builder = FunctionBuilder::new("main".into(), main_id); + let v0 = builder.add_parameter(Type::field()); + + let one = builder.field_constant(1u128); + let two = builder.field_constant(2u128); + + let v1 = builder.insert_binary(v0, BinaryOp::Add, one); + let v2 = builder.insert_binary(v0, BinaryOp::Add, two); + let as_witness = builder.import_intrinsic("as_witness").unwrap(); + builder.insert_call(as_witness, vec![v2], Vec::new()); + builder.terminate_with_return(vec![v1]); + + let ssa = builder.finish(); + let main = ssa.main(); + + // The instruction count never includes the terminator instruction + assert_eq!(main.dfg[main.entry_block()].instructions().len(), 3); + + // Expected output: + // + // acir(inline) fn main f0 { + // b0(v0: Field): + // v3 = add v0, Field 1 + // return v3 + // } + let ssa = ssa.dead_instruction_elimination(); + let main = ssa.main(); + + assert_eq!(main.dfg[main.entry_block()].instructions().len(), 1); + } } From 56c1a85056ed338644595f1aa58cc94563786b9e Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Tue, 28 May 2024 16:50:55 +0100 Subject: [PATCH 34/61] fix: Auto dereference trait methods in the elaborator (#5124) # Description ## Problem\* Follow-up to https://github.com/noir-lang/noir/pull/5094 ## Summary\* This was missed when moving over changes due to the turbofish operator over to the elaborato.r ## Additional Context ## Documentation\* Check one: - [X] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [X] I have tested the changes locally. - [X] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_frontend/src/elaborator/mod.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index 0581e7900f8..121a4d89ef0 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -344,8 +344,15 @@ impl<'context> Elaborator<'context> { } // Verify any remaining trait constraints arising from the function body - for (constraint, expr_id) in std::mem::take(&mut self.trait_constraints) { + for (mut constraint, expr_id) in std::mem::take(&mut self.trait_constraints) { let span = self.interner.expr_span(&expr_id); + + if matches!(&constraint.typ, Type::MutableReference(_)) { + let (_, dereferenced_typ) = + self.insert_auto_dereferences(expr_id, constraint.typ.clone()); + constraint.typ = dereferenced_typ; + } + self.verify_trait_constraint( &constraint.typ, constraint.trait_id, From 70f374c06642962d8f2b95b80f8c938fcf7761d7 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 28 May 2024 16:55:30 +0100 Subject: [PATCH 35/61] feat: make ACVM generic across fields (#5114) # Description Step towards #5055 ## Summary\* This PR starts us down the road towards removing the compile-time flags for specifying which field is being used by replacing the usage of the `FieldElement` type with an `AcirField` trait. This trait is mostly all of the external methods from `FieldElement` dumped into it for now but we can break it down in future PRs (XOR and AND are looking ready for culling) I've taken this route rather than just using `generic_ark::FieldElement` as we'd need to have trait bounds for `PrimeField` anyway so we might as well have our own trait. I've had to delete a couple of trait implementations which fall afoul of the orphan rule now it's being implemented for a generic type (e.g. we need to use `MemoryValue::new_field` explicitly now) but nothing too bad. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- Cargo.lock | 2 + acvm-repo/acir/Cargo.toml | 5 +- acvm-repo/acir/benches/serialization.rs | 8 +- acvm-repo/acir/src/circuit/brillig.rs | 10 +- acvm-repo/acir/src/circuit/directives.rs | 4 +- acvm-repo/acir/src/circuit/mod.rs | 94 +++--- acvm-repo/acir/src/circuit/opcodes.rs | 21 +- .../opcodes/black_box_function_call.rs | 10 +- .../src/circuit/opcodes/memory_operation.rs | 15 +- acvm-repo/acir/src/lib.rs | 23 +- .../acir/src/native_types/expression/mod.rs | 135 ++++---- .../src/native_types/expression/operators.rs | 212 ++++++------ .../src/native_types/expression/ordering.rs | 10 +- acvm-repo/acir/src/native_types/witness.rs | 13 - .../acir/src/native_types/witness_map.rs | 37 +-- .../acir/src/native_types/witness_stack.rs | 26 +- .../acir/tests/test_program_serialization.rs | 37 ++- acvm-repo/acir_field/Cargo.toml | 15 +- acvm-repo/acir_field/src/generic_ark.rs | 312 +++++++++++------- acvm-repo/acir_field/src/lib.rs | 17 +- acvm-repo/acvm/Cargo.toml | 2 +- acvm-repo/acvm/src/compiler/mod.rs | 17 +- .../acvm/src/compiler/optimizers/general.rs | 20 +- acvm-repo/acvm/src/compiler/optimizers/mod.rs | 11 +- .../compiler/optimizers/redundant_range.rs | 21 +- .../src/compiler/optimizers/unused_memory.rs | 12 +- .../acvm/src/compiler/transformers/csat.rs | 244 +++++++------- .../acvm/src/compiler/transformers/mod.rs | 18 +- acvm-repo/acvm/src/lib.rs | 2 +- acvm-repo/acvm/src/pwg/arithmetic.rs | 139 ++++---- acvm-repo/acvm/src/pwg/blackbox/aes128.rs | 10 +- acvm-repo/acvm/src/pwg/blackbox/bigint.rs | 20 +- .../src/pwg/blackbox/embedded_curve_ops.rs | 17 +- acvm-repo/acvm/src/pwg/blackbox/hash.rs | 48 ++- acvm-repo/acvm/src/pwg/blackbox/logic.rs | 22 +- acvm-repo/acvm/src/pwg/blackbox/mod.rs | 18 +- acvm-repo/acvm/src/pwg/blackbox/pedersen.rs | 17 +- acvm-repo/acvm/src/pwg/blackbox/range.rs | 8 +- .../acvm/src/pwg/blackbox/signature/ecdsa.rs | 18 +- .../src/pwg/blackbox/signature/schnorr.rs | 16 +- acvm-repo/acvm/src/pwg/blackbox/utils.rs | 14 +- acvm-repo/acvm/src/pwg/brillig.rs | 68 ++-- acvm-repo/acvm/src/pwg/directives/mod.rs | 14 +- acvm-repo/acvm/src/pwg/memory_op.rs | 35 +- acvm-repo/acvm/src/pwg/mod.rs | 154 +++++---- acvm-repo/acvm/tests/solver.rs | 43 ++- acvm-repo/acvm_js/src/black_box_solvers.rs | 2 +- acvm-repo/acvm_js/src/execute.rs | 37 ++- acvm-repo/acvm_js/src/foreign_call/inputs.rs | 4 +- acvm-repo/acvm_js/src/foreign_call/mod.rs | 6 +- acvm-repo/acvm_js/src/foreign_call/outputs.rs | 12 +- acvm-repo/acvm_js/src/js_execution_error.rs | 7 +- acvm-repo/acvm_js/src/js_witness_map.rs | 13 +- acvm-repo/acvm_js/src/js_witness_stack.rs | 8 +- acvm-repo/acvm_js/src/public_witness.rs | 19 +- acvm-repo/blackbox_solver/Cargo.toml | 1 - .../src/curve_specific_solver.rs | 82 ++--- .../benches/criterion.rs | 2 +- .../src/embedded_curve_ops.rs | 7 +- acvm-repo/bn254_blackbox_solver/src/lib.rs | 2 +- .../src/pedersen/commitment.rs | 2 +- .../src/pedersen/hash.rs | 2 +- .../bn254_blackbox_solver/src/poseidon2.rs | 4 +- .../bn254_blackbox_solver/src/schnorr/mod.rs | 2 +- acvm-repo/brillig/Cargo.toml | 1 - acvm-repo/brillig/src/foreign_call.rs | 40 +-- acvm-repo/brillig/src/opcodes.rs | 6 +- acvm-repo/brillig_vm/Cargo.toml | 1 - acvm-repo/brillig_vm/src/arithmetic.rs | 37 ++- acvm-repo/brillig_vm/src/black_box.rs | 95 ++++-- acvm-repo/brillig_vm/src/lib.rs | 140 ++++---- acvm-repo/brillig_vm/src/memory.rs | 124 +++---- aztec_macros/Cargo.toml | 1 + aztec_macros/src/transforms/storage.rs | 1 + aztec_macros/src/utils/hir_utils.rs | 1 + compiler/noirc_driver/src/contract.rs | 4 +- compiler/noirc_driver/src/program.rs | 4 +- .../src/brillig/brillig_gen/brillig_block.rs | 2 +- .../brillig/brillig_gen/brillig_directive.rs | 1 + .../noirc_evaluator/src/brillig/brillig_ir.rs | 15 +- .../src/brillig/brillig_ir/artifact.rs | 14 +- .../brillig/brillig_ir/brillig_variable.rs | 1 + .../brillig/brillig_ir/codegen_intrinsic.rs | 1 + .../src/brillig/brillig_ir/entry_point.rs | 2 +- .../src/brillig/brillig_ir/instructions.rs | 5 +- compiler/noirc_evaluator/src/ssa.rs | 19 +- .../src/ssa/acir_gen/acir_ir/acir_variable.rs | 62 ++-- .../src/ssa/acir_gen/acir_ir/big_int.rs | 2 +- .../ssa/acir_gen/acir_ir/generated_acir.rs | 36 +- .../noirc_evaluator/src/ssa/acir_gen/mod.rs | 7 +- .../src/ssa/function_builder/mod.rs | 2 +- compiler/noirc_evaluator/src/ssa/ir/dfg.rs | 2 +- .../noirc_evaluator/src/ssa/ir/instruction.rs | 1 + .../src/ssa/ir/instruction/binary.rs | 2 +- .../src/ssa/ir/instruction/call.rs | 2 +- .../src/ssa/ir/instruction/cast.rs | 2 +- .../src/ssa/ir/instruction/constrain.rs | 2 +- .../noirc_evaluator/src/ssa/ir/printer.rs | 1 + compiler/noirc_evaluator/src/ssa/ir/types.rs | 2 +- .../src/ssa/opt/constant_folding.rs | 3 +- .../src/ssa/opt/flatten_cfg.rs | 4 +- .../ssa/opt/flatten_cfg/capacity_tracker.rs | 2 +- .../src/ssa/opt/flatten_cfg/value_merger.rs | 2 +- .../noirc_evaluator/src/ssa/opt/inlining.rs | 3 +- .../noirc_evaluator/src/ssa/opt/mem2reg.rs | 2 +- .../src/ssa/opt/remove_bit_shifts.rs | 2 +- .../src/ssa/opt/remove_enable_side_effects.rs | 2 +- .../src/ssa/opt/remove_if_else.rs | 2 +- .../src/ssa/opt/simplify_cfg.rs | 3 + .../noirc_evaluator/src/ssa/opt/unrolling.rs | 2 + .../src/ssa/ssa_gen/context.rs | 2 +- compiler/noirc_frontend/src/ast/expression.rs | 2 +- compiler/noirc_frontend/src/ast/mod.rs | 1 + compiler/noirc_frontend/src/ast/statement.rs | 1 + .../noirc_frontend/src/elaborator/types.rs | 1 + .../noirc_frontend/src/hir/comptime/errors.rs | 2 +- .../src/hir/comptime/interpreter.rs | 2 +- .../src/hir/resolution/resolver.rs | 2 + .../noirc_frontend/src/hir/type_check/stmt.rs | 1 + compiler/noirc_frontend/src/lexer/token.rs | 2 +- .../src/monomorphization/debug.rs | 1 + .../src/monomorphization/mod.rs | 2 +- compiler/noirc_printable_type/src/lib.rs | 14 +- compiler/wasm/Cargo.toml | 2 +- tooling/acvm_cli/src/cli/execute_cmd.rs | 7 +- tooling/acvm_cli/src/cli/fs/inputs.rs | 6 +- tooling/acvm_cli/src/cli/fs/witness.rs | 12 +- tooling/debugger/src/context.rs | 36 +- tooling/debugger/src/dap.rs | 16 +- tooling/debugger/src/foreign_calls.rs | 6 +- tooling/debugger/src/lib.rs | 16 +- tooling/debugger/src/repl.rs | 30 +- tooling/lsp/src/lib.rs | 12 +- tooling/lsp/src/solver.rs | 4 +- tooling/nargo/src/artifacts/contract.rs | 4 +- tooling/nargo/src/artifacts/program.rs | 3 +- tooling/nargo/src/errors.rs | 5 +- tooling/nargo/src/ops/execute.rs | 52 +-- tooling/nargo/src/ops/foreign_calls.rs | 52 +-- tooling/nargo/src/ops/optimize.rs | 7 +- tooling/nargo/src/ops/test.rs | 6 +- tooling/nargo/src/ops/transform.rs | 9 +- tooling/nargo_cli/Cargo.toml | 2 +- tooling/nargo_cli/src/cli/dap_cmd.rs | 3 +- tooling/nargo_cli/src/cli/debug_cmd.rs | 5 +- tooling/nargo_cli/src/cli/execute_cmd.rs | 5 +- tooling/nargo_cli/src/cli/fs/witness.rs | 4 +- tooling/nargo_cli/src/cli/test_cmd.rs | 6 +- tooling/noirc_abi/src/input_parser/json.rs | 2 +- tooling/noirc_abi/src/input_parser/mod.rs | 6 +- tooling/noirc_abi/src/input_parser/toml.rs | 2 +- tooling/noirc_abi/src/lib.rs | 8 +- tooling/noirc_abi_wasm/Cargo.toml | 2 +- tooling/noirc_abi_wasm/src/js_witness_map.rs | 10 +- tooling/noirc_abi_wasm/src/lib.rs | 15 +- 155 files changed, 1760 insertions(+), 1519 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bfc012d23f0..919bdc48748 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,6 +44,7 @@ version = "0.46.0" dependencies = [ "acir", "acvm_blackbox_solver", + "ark-bls12-381", "brillig_vm", "indexmap 1.9.3", "num-bigint", @@ -445,6 +446,7 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" name = "aztec_macros" version = "0.30.0" dependencies = [ + "acvm", "convert_case 0.6.0", "iter-extended", "noirc_errors", diff --git a/acvm-repo/acir/Cargo.toml b/acvm-repo/acir/Cargo.toml index 32a9bbe8303..101ce7a0f39 100644 --- a/acvm-repo/acir/Cargo.toml +++ b/acvm-repo/acir/Cargo.toml @@ -33,9 +33,8 @@ criterion.workspace = true pprof.workspace = true [features] -default = ["bn254"] -bn254 = ["acir_field/bn254", "brillig/bn254"] -bls12_381 = ["acir_field/bls12_381", "brillig/bls12_381"] +bn254 = ["acir_field/bn254"] +bls12_381 = ["acir_field/bls12_381"] [[bench]] name = "serialization" diff --git a/acvm-repo/acir/benches/serialization.rs b/acvm-repo/acir/benches/serialization.rs index a7f32b4a4c7..792200c8912 100644 --- a/acvm-repo/acir/benches/serialization.rs +++ b/acvm-repo/acir/benches/serialization.rs @@ -11,8 +11,8 @@ use pprof::criterion::{Output, PProfProfiler}; const SIZES: [usize; 9] = [10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000]; -fn sample_program(num_opcodes: usize) -> Program { - let assert_zero_opcodes: Vec = (0..num_opcodes) +fn sample_program(num_opcodes: usize) -> Program { + let assert_zero_opcodes: Vec> = (0..num_opcodes) .map(|i| { Opcode::AssertZero(Expression { mul_terms: vec![( @@ -83,7 +83,7 @@ fn bench_deserialization(c: &mut Criterion) { BenchmarkId::from_parameter(size), &serialized_program, |b, program| { - b.iter(|| Program::deserialize_program(program)); + b.iter(|| Program::::deserialize_program(program)); }, ); } @@ -107,7 +107,7 @@ fn bench_deserialization(c: &mut Criterion) { |b, program| { b.iter(|| { let mut deserializer = serde_json::Deserializer::from_slice(program); - Program::deserialize_program_base64(&mut deserializer) + Program::::deserialize_program_base64(&mut deserializer) }); }, ); diff --git a/acvm-repo/acir/src/circuit/brillig.rs b/acvm-repo/acir/src/circuit/brillig.rs index ecf6f7a9761..ee25d05afb0 100644 --- a/acvm-repo/acir/src/circuit/brillig.rs +++ b/acvm-repo/acir/src/circuit/brillig.rs @@ -6,9 +6,9 @@ use serde::{Deserialize, Serialize}; /// Inputs for the Brillig VM. These are the initial inputs /// that the Brillig VM will use to start. #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] -pub enum BrilligInputs { - Single(Expression), - Array(Vec), +pub enum BrilligInputs { + Single(Expression), + Array(Vec>), MemoryArray(BlockId), } @@ -24,6 +24,6 @@ pub enum BrilligOutputs { /// a full Brillig function to be executed by the Brillig VM. /// This is stored separately on a program and accessed through a [BrilligPointer]. #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Default, Debug)] -pub struct BrilligBytecode { - pub bytecode: Vec, +pub struct BrilligBytecode { + pub bytecode: Vec>, } diff --git a/acvm-repo/acir/src/circuit/directives.rs b/acvm-repo/acir/src/circuit/directives.rs index 099d0634399..3bc66288590 100644 --- a/acvm-repo/acir/src/circuit/directives.rs +++ b/acvm-repo/acir/src/circuit/directives.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; /// Directives do not apply any constraints. /// You can think of them as opcodes that allow one to use non-determinism /// In the future, this can be replaced with asm non-determinism blocks -pub enum Directive { +pub enum Directive { //decomposition of a: a=\sum b[i]*radix^i where b is an array of witnesses < radix in little endian form - ToLeRadix { a: Expression, b: Vec, radix: u32 }, + ToLeRadix { a: Expression, b: Vec, radix: u32 }, } diff --git a/acvm-repo/acir/src/circuit/mod.rs b/acvm-repo/acir/src/circuit/mod.rs index 6a26a45d88b..7632afda423 100644 --- a/acvm-repo/acir/src/circuit/mod.rs +++ b/acvm-repo/acir/src/circuit/mod.rs @@ -4,7 +4,7 @@ pub mod directives; pub mod opcodes; use crate::native_types::{Expression, Witness}; -use acir_field::FieldElement; +use acir_field::AcirField; pub use opcodes::Opcode; use thiserror::Error; @@ -38,17 +38,17 @@ pub enum ExpressionWidth { /// A program represented by multiple ACIR circuits. The execution trace of these /// circuits is dictated by construction of the [crate::native_types::WitnessStack]. #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Default)] -pub struct Program { - pub functions: Vec, - pub unconstrained_functions: Vec, +pub struct Program { + pub functions: Vec>, + pub unconstrained_functions: Vec>, } #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Default)] -pub struct Circuit { +pub struct Circuit { // current_witness_index is the highest witness index in the circuit. The next witness to be added to this circuit // will take on this value. (The value is cached here as an optimization.) pub current_witness_index: u32, - pub opcodes: Vec, + pub opcodes: Vec>, pub expression_width: ExpressionWidth, /// The set of private inputs to the circuit. @@ -67,7 +67,7 @@ pub struct Circuit { // Note: This should be a BTreeMap, but serde-reflect is creating invalid // c++ code at the moment when it is, due to OpcodeLocation needing a comparison // implementation which is never generated. - pub assert_messages: Vec<(OpcodeLocation, AssertionPayload)>, + pub assert_messages: Vec<(OpcodeLocation, AssertionPayload)>, /// States whether the backend should use a SNARK recursion friendly prover. /// If implemented by a backend, this means that proofs generated with this circuit @@ -76,15 +76,15 @@ pub struct Circuit { } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub enum ExpressionOrMemory { - Expression(Expression), +pub enum ExpressionOrMemory { + Expression(Expression), Memory(BlockId), } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub enum AssertionPayload { +pub enum AssertionPayload { StaticString(String), - Dynamic(/* error_selector */ u64, Vec), + Dynamic(/* error_selector */ u64, Vec>), } #[derive(Debug, Copy, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)] @@ -127,15 +127,15 @@ impl<'de> Deserialize<'de> for ErrorSelector { pub const STRING_ERROR_SELECTOR: ErrorSelector = ErrorSelector(0); #[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] -pub struct RawAssertionPayload { +pub struct RawAssertionPayload { pub selector: ErrorSelector, - pub data: Vec, + pub data: Vec, } #[derive(Clone, PartialEq, Eq, Debug)] -pub enum ResolvedAssertionPayload { +pub enum ResolvedAssertionPayload { String(String), - Raw(RawAssertionPayload), + Raw(RawAssertionPayload), } #[derive(Debug, Copy, Clone)] @@ -204,7 +204,7 @@ impl FromStr for OpcodeLocation { } } -impl Circuit { +impl Circuit { pub fn num_vars(&self) -> u32 { self.current_witness_index + 1 } @@ -223,7 +223,7 @@ impl Circuit { } } -impl Program { +impl Program { fn write(&self, writer: W) -> std::io::Result<()> { let buf = bincode::serialize(self).unwrap(); let mut encoder = flate2::write::GzEncoder::new(writer, Compression::default()); @@ -232,26 +232,14 @@ impl Program { Ok(()) } - fn read(reader: R) -> std::io::Result { - let mut gz_decoder = flate2::read::GzDecoder::new(reader); - let mut buf_d = Vec::new(); - gz_decoder.read_to_end(&mut buf_d)?; - bincode::deserialize(&buf_d) - .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidInput, err)) - } - - pub fn serialize_program(program: &Program) -> Vec { + pub fn serialize_program(program: &Self) -> Vec { let mut program_bytes: Vec = Vec::new(); program.write(&mut program_bytes).expect("expected circuit to be serializable"); program_bytes } - pub fn deserialize_program(serialized_circuit: &[u8]) -> std::io::Result { - Program::read(serialized_circuit) - } - // Serialize and base64 encode program - pub fn serialize_program_base64(program: &Program, s: S) -> Result + pub fn serialize_program_base64(program: &Self, s: S) -> Result where S: Serializer, { @@ -259,9 +247,23 @@ impl Program { let encoded_b64 = base64::engine::general_purpose::STANDARD.encode(program_bytes); s.serialize_str(&encoded_b64) } +} + +impl Deserialize<'a>> Program { + fn read(reader: R) -> std::io::Result { + let mut gz_decoder = flate2::read::GzDecoder::new(reader); + let mut buf_d = Vec::new(); + gz_decoder.read_to_end(&mut buf_d)?; + bincode::deserialize(&buf_d) + .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidInput, err)) + } + + pub fn deserialize_program(serialized_circuit: &[u8]) -> std::io::Result { + Program::read(serialized_circuit) + } // Deserialize and base64 decode program - pub fn deserialize_program_base64<'de, D>(deserializer: D) -> Result + pub fn deserialize_program_base64<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { @@ -274,7 +276,7 @@ impl Program { } } -impl std::fmt::Display for Circuit { +impl std::fmt::Display for Circuit { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { writeln!(f, "current witness index : {}", self.current_witness_index)?; @@ -313,13 +315,13 @@ impl std::fmt::Display for Circuit { } } -impl std::fmt::Debug for Circuit { +impl std::fmt::Debug for Circuit { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self, f) } } -impl std::fmt::Display for Program { +impl std::fmt::Display for Program { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { for (func_index, function) in self.functions.iter().enumerate() { writeln!(f, "func {}", func_index)?; @@ -333,7 +335,7 @@ impl std::fmt::Display for Program { } } -impl std::fmt::Debug for Program { +impl std::fmt::Debug for Program { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self, f) } @@ -365,21 +367,22 @@ mod tests { circuit::{ExpressionWidth, Program}, native_types::Witness, }; - use acir_field::FieldElement; + use acir_field::{AcirField, FieldElement}; + use serde::{Deserialize, Serialize}; - fn and_opcode() -> Opcode { + fn and_opcode() -> Opcode { Opcode::BlackBoxFuncCall(BlackBoxFuncCall::AND { lhs: FunctionInput { witness: Witness(1), num_bits: 4 }, rhs: FunctionInput { witness: Witness(2), num_bits: 4 }, output: Witness(3), }) } - fn range_opcode() -> Opcode { + fn range_opcode() -> Opcode { Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { input: FunctionInput { witness: Witness(1), num_bits: 8 }, }) } - fn keccakf1600_opcode() -> Opcode { + fn keccakf1600_opcode() -> Opcode { let inputs: Box<[FunctionInput; 25]> = Box::new(std::array::from_fn(|i| FunctionInput { witness: Witness(i as u32 + 1), num_bits: 8, @@ -388,7 +391,7 @@ mod tests { Opcode::BlackBoxFuncCall(BlackBoxFuncCall::Keccakf1600 { inputs, outputs }) } - fn schnorr_verify_opcode() -> Opcode { + fn schnorr_verify_opcode() -> Opcode { let public_key_x = FunctionInput { witness: Witness(1), num_bits: FieldElement::max_num_bits() }; let public_key_y = @@ -413,7 +416,7 @@ mod tests { let circuit = Circuit { current_witness_index: 5, expression_width: ExpressionWidth::Unbounded, - opcodes: vec![and_opcode(), range_opcode(), schnorr_verify_opcode()], + opcodes: vec![and_opcode::(), range_opcode(), schnorr_verify_opcode()], private_parameters: BTreeSet::new(), public_parameters: PublicInputs(BTreeSet::from_iter(vec![Witness(2), Witness(12)])), return_values: PublicInputs(BTreeSet::from_iter(vec![Witness(4), Witness(12)])), @@ -422,7 +425,9 @@ mod tests { }; let program = Program { functions: vec![circuit], unconstrained_functions: Vec::new() }; - fn read_write(program: Program) -> (Program, Program) { + fn read_write Deserialize<'a>>( + program: Program, + ) -> (Program, Program) { let bytes = Program::serialize_program(&program); let got_program = Program::deserialize_program(&bytes).unwrap(); (program, got_program) @@ -475,7 +480,8 @@ mod tests { encoder.write_all(bad_circuit).unwrap(); encoder.finish().unwrap(); - let deserialization_result = Program::deserialize_program(&zipped_bad_circuit); + let deserialization_result: Result, _> = + Program::deserialize_program(&zipped_bad_circuit); assert!(deserialization_result.is_err()); } } diff --git a/acvm-repo/acir/src/circuit/opcodes.rs b/acvm-repo/acir/src/circuit/opcodes.rs index 6043196dfff..20c6903dc52 100644 --- a/acvm-repo/acir/src/circuit/opcodes.rs +++ b/acvm-repo/acir/src/circuit/opcodes.rs @@ -3,6 +3,7 @@ use super::{ directives::Directive, }; use crate::native_types::{Expression, Witness}; +use acir_field::AcirField; use serde::{Deserialize, Serialize}; mod black_box_function_call; @@ -26,19 +27,19 @@ impl BlockType { #[allow(clippy::large_enum_variant)] #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] -pub enum Opcode { - AssertZero(Expression), +pub enum Opcode { + AssertZero(Expression), /// Calls to "gadgets" which rely on backends implementing support for specialized constraints. /// /// Often used for exposing more efficient implementations of SNARK-unfriendly computations. BlackBoxFuncCall(BlackBoxFuncCall), - Directive(Directive), + Directive(Directive), /// Atomic operation on a block of memory MemoryOp { block_id: BlockId, - op: MemOp, + op: MemOp, /// Predicate of the memory operation - indicates if it should be skipped - predicate: Option, + predicate: Option>, }, MemoryInit { block_id: BlockId, @@ -51,11 +52,11 @@ pub enum Opcode { /// to fetch the appropriate Brillig bytecode from this id. id: u32, /// Inputs to the function call - inputs: Vec, + inputs: Vec>, /// Outputs to the function call outputs: Vec, /// Predicate of the Brillig execution - indicates if it should be skipped - predicate: Option, + predicate: Option>, }, /// Calls to functions represented as a separate circuit. A call opcode allows us /// to build a call stack when executing the outer-most circuit. @@ -68,11 +69,11 @@ pub enum Opcode { /// Outputs of the function call outputs: Vec, /// Predicate of the circuit execution - indicates if it should be skipped - predicate: Option, + predicate: Option>, }, } -impl std::fmt::Display for Opcode { +impl std::fmt::Display for Opcode { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Opcode::AssertZero(expr) => { @@ -147,7 +148,7 @@ impl std::fmt::Display for Opcode { } } -impl std::fmt::Debug for Opcode { +impl std::fmt::Debug for Opcode { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self, f) } diff --git a/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs b/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs index b0e77b15c2c..362e9ba5936 100644 --- a/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs +++ b/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs @@ -481,11 +481,11 @@ where mod tests { use crate::{circuit::Opcode, native_types::Witness}; - use acir_field::FieldElement; + use acir_field::{AcirField, FieldElement}; use super::{BlackBoxFuncCall, FunctionInput}; - fn keccakf1600_opcode() -> Opcode { + fn keccakf1600_opcode() -> Opcode { let inputs: Box<[FunctionInput; 25]> = Box::new(std::array::from_fn(|i| FunctionInput { witness: Witness(i as u32 + 1), num_bits: 8, @@ -494,7 +494,7 @@ mod tests { Opcode::BlackBoxFuncCall(BlackBoxFuncCall::Keccakf1600 { inputs, outputs }) } - fn schnorr_verify_opcode() -> Opcode { + fn schnorr_verify_opcode() -> Opcode { let public_key_x = FunctionInput { witness: Witness(1), num_bits: FieldElement::max_num_bits() }; let public_key_y = @@ -516,7 +516,7 @@ mod tests { #[test] fn keccakf1600_serialization_roundtrip() { - let opcode = keccakf1600_opcode(); + let opcode = keccakf1600_opcode::(); let buf = bincode::serialize(&opcode).unwrap(); let recovered_opcode = bincode::deserialize(&buf).unwrap(); assert_eq!(opcode, recovered_opcode); @@ -524,7 +524,7 @@ mod tests { #[test] fn schnorr_serialization_roundtrip() { - let opcode = schnorr_verify_opcode(); + let opcode = schnorr_verify_opcode::(); let buf = bincode::serialize(&opcode).unwrap(); let recovered_opcode = bincode::deserialize(&buf).unwrap(); assert_eq!(opcode, recovered_opcode); diff --git a/acvm-repo/acir/src/circuit/opcodes/memory_operation.rs b/acvm-repo/acir/src/circuit/opcodes/memory_operation.rs index 0e94c0f051e..2147e7430b2 100644 --- a/acvm-repo/acir/src/circuit/opcodes/memory_operation.rs +++ b/acvm-repo/acir/src/circuit/opcodes/memory_operation.rs @@ -1,4 +1,5 @@ use crate::native_types::{Expression, Witness}; +use acir_field::AcirField; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash, Copy, Default)] @@ -7,22 +8,22 @@ pub struct BlockId(pub u32); /// Operation on a block of memory /// We can either write or read at an index in memory #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] -pub struct MemOp { +pub struct MemOp { /// Can be 0 (read) or 1 (write) - pub operation: Expression, - pub index: Expression, - pub value: Expression, + pub operation: Expression, + pub index: Expression, + pub value: Expression, } -impl MemOp { +impl MemOp { /// Creates a `MemOp` which reads from memory at `index` and inserts the read value /// into the [`WitnessMap`][crate::native_types::WitnessMap] at `witness` - pub fn read_at_mem_index(index: Expression, witness: Witness) -> Self { + pub fn read_at_mem_index(index: Expression, witness: Witness) -> Self { MemOp { operation: Expression::zero(), index, value: witness.into() } } /// Creates a `MemOp` which writes the [`Expression`] `value` into memory at `index`. - pub fn write_to_mem_index(index: Expression, value: Expression) -> Self { + pub fn write_to_mem_index(index: Expression, value: Expression) -> Self { MemOp { operation: Expression::one(), index, value } } } diff --git a/acvm-repo/acir/src/lib.rs b/acvm-repo/acir/src/lib.rs index f60f1b46b6a..f064cfaca0e 100644 --- a/acvm-repo/acir/src/lib.rs +++ b/acvm-repo/acir/src/lib.rs @@ -9,7 +9,7 @@ pub mod circuit; pub mod native_types; pub use acir_field; -pub use acir_field::FieldElement; +pub use acir_field::{AcirField, FieldElement}; pub use brillig; pub use circuit::black_box_functions::BlackBoxFunc; @@ -31,6 +31,7 @@ mod reflection { path::{Path, PathBuf}, }; + use acir_field::FieldElement; use brillig::{ BinaryFieldOp, BinaryIntOp, BlackBoxOp, HeapValueType, Opcode as BrilligOpcode, ValueOrArray, @@ -61,23 +62,23 @@ mod reflection { let mut tracer = Tracer::new(TracerConfig::default()); tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); + tracer.trace_simple_type::>().unwrap(); + tracer.trace_simple_type::>().unwrap(); tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); + tracer.trace_simple_type::>().unwrap(); tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); + tracer.trace_simple_type::>().unwrap(); tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); + tracer.trace_simple_type::>().unwrap(); tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); + tracer.trace_simple_type::>().unwrap(); tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); + tracer.trace_simple_type::>().unwrap(); + tracer.trace_simple_type::>().unwrap(); let registry = tracer.registry().unwrap(); @@ -110,8 +111,8 @@ mod reflection { let mut tracer = Tracer::new(TracerConfig::default()); tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); + tracer.trace_simple_type::>().unwrap(); + tracer.trace_simple_type::>().unwrap(); let registry = tracer.registry().unwrap(); diff --git a/acvm-repo/acir/src/native_types/expression/mod.rs b/acvm-repo/acir/src/native_types/expression/mod.rs index 402aa3eb3a6..b34862429e7 100644 --- a/acvm-repo/acir/src/native_types/expression/mod.rs +++ b/acvm-repo/acir/src/native_types/expression/mod.rs @@ -1,8 +1,7 @@ use crate::native_types::Witness; -use acir_field::FieldElement; +use acir_field::AcirField; use serde::{Deserialize, Serialize}; use std::cmp::Ordering; - mod operators; mod ordering; @@ -14,30 +13,26 @@ mod ordering; // In the multiplication polynomial // XXX: If we allow the degree of the quotient polynomial to be arbitrary, then we will need a vector of wire values #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)] -pub struct Expression { +pub struct Expression { // To avoid having to create intermediate variables pre-optimization // We collect all of the multiplication terms in the assert-zero opcode // A multiplication term if of the form q_M * wL * wR // Hence this vector represents the following sum: q_M1 * wL1 * wR1 + q_M2 * wL2 * wR2 + .. + - pub mul_terms: Vec<(FieldElement, Witness, Witness)>, + pub mul_terms: Vec<(F, Witness, Witness)>, - pub linear_combinations: Vec<(FieldElement, Witness)>, + pub linear_combinations: Vec<(F, Witness)>, // TODO: rename q_c to `constant` moreover q_X is not clear to those who // TODO are not familiar with PLONK - pub q_c: FieldElement, + pub q_c: F, } -impl Default for Expression { - fn default() -> Expression { - Expression { - mul_terms: Vec::new(), - linear_combinations: Vec::new(), - q_c: FieldElement::zero(), - } +impl Default for Expression { + fn default() -> Self { + Expression { mul_terms: Vec::new(), linear_combinations: Vec::new(), q_c: F::zero() } } } -impl std::fmt::Display for Expression { +impl std::fmt::Display for Expression { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { if let Some(witness) = self.to_witness() { write!(f, "x{}", witness.witness_index()) @@ -47,7 +42,7 @@ impl std::fmt::Display for Expression { } } -impl Expression { +impl Expression { // TODO: possibly remove, and move to noir repo. pub const fn can_defer_constraint(&self) -> bool { false @@ -58,30 +53,25 @@ impl Expression { self.mul_terms.len() } - pub fn from_field(q_c: FieldElement) -> Expression { + pub fn from_field(q_c: F) -> Self { Self { q_c, ..Default::default() } } - pub fn one() -> Expression { - Self::from_field(FieldElement::one()) + pub fn one() -> Self { + Self::from_field(F::one()) } - pub fn zero() -> Expression { + pub fn zero() -> Self { Self::default() } /// Adds a new linear term to the `Expression`. - pub fn push_addition_term(&mut self, coefficient: FieldElement, variable: Witness) { + pub fn push_addition_term(&mut self, coefficient: F, variable: Witness) { self.linear_combinations.push((coefficient, variable)); } /// Adds a new quadratic term to the `Expression`. - pub fn push_multiplication_term( - &mut self, - coefficient: FieldElement, - lhs: Witness, - rhs: Witness, - ) { + pub fn push_multiplication_term(&mut self, coefficient: F, lhs: Witness, rhs: Witness) { self.mul_terms.push((coefficient, lhs, rhs)); } @@ -145,7 +135,7 @@ impl Expression { /// - f(x,y) = 2*y + 6 would return `None` /// - f(x,y) = x + y would return `None` /// - f(x,y) = 5 would return `FieldElement(5)` - pub fn to_const(&self) -> Option { + pub fn to_const(&self) -> Option { self.is_const().then_some(self.q_c) } @@ -216,7 +206,7 @@ impl Expression { let mul_term = &self.mul_terms[0]; // The coefficient should be non-zero, as this method is ran after the compiler removes all zero coefficient terms - assert_ne!(mul_term.0, FieldElement::zero()); + assert_ne!(mul_term.0, F::zero()); let mut found_x = false; let mut found_y = false; @@ -240,18 +230,19 @@ impl Expression { } /// Returns `self + k*b` - pub fn add_mul(&self, k: FieldElement, b: &Expression) -> Expression { + pub fn add_mul(&self, k: F, b: &Self) -> Self { if k.is_zero() { return self.clone(); } else if self.is_const() { - return self.q_c + (k * b); + let kb = b * k; + return kb + self.q_c; } else if b.is_const() { return self.clone() + (k * b.q_c); } - let mut mul_terms: Vec<(FieldElement, Witness, Witness)> = + let mut mul_terms: Vec<(F, Witness, Witness)> = Vec::with_capacity(self.mul_terms.len() + b.mul_terms.len()); - let mut linear_combinations: Vec<(FieldElement, Witness)> = + let mut linear_combinations: Vec<(F, Witness)> = Vec::with_capacity(self.linear_combinations.len() + b.linear_combinations.len()); let q_c = self.q_c + k * b.q_c; @@ -338,7 +329,7 @@ impl Expression { while i2 < b.mul_terms.len() { let (b_c, b_wl, b_wr) = b.mul_terms[i2]; let coeff = b_c * k; - if coeff != FieldElement::zero() { + if coeff != F::zero() { mul_terms.push((coeff, b_wl, b_wr)); } i2 += 1; @@ -348,57 +339,63 @@ impl Expression { } } -impl From for Expression { - fn from(constant: FieldElement) -> Expression { +impl From for Expression { + fn from(constant: F) -> Self { Expression { q_c: constant, linear_combinations: Vec::new(), mul_terms: Vec::new() } } } -impl From for Expression { +impl From for Expression { /// Creates an Expression from a Witness. /// /// This is infallible since an `Expression` is /// a multi-variate polynomial and a `Witness` /// can be seen as a univariate polynomial - fn from(wit: Witness) -> Expression { + fn from(wit: Witness) -> Self { Expression { - q_c: FieldElement::zero(), - linear_combinations: vec![(FieldElement::one(), wit)], + q_c: F::zero(), + linear_combinations: vec![(F::one(), wit)], mul_terms: Vec::new(), } } } -#[test] -fn add_mul_smoketest() { - let a = Expression { - mul_terms: vec![(FieldElement::from(2u128), Witness(1), Witness(2))], - ..Default::default() - }; - - let k = FieldElement::from(10u128); - - let b = Expression { - mul_terms: vec![ - (FieldElement::from(3u128), Witness(0), Witness(2)), - (FieldElement::from(3u128), Witness(1), Witness(2)), - (FieldElement::from(4u128), Witness(4), Witness(5)), - ], - linear_combinations: vec![(FieldElement::from(4u128), Witness(4))], - q_c: FieldElement::one(), - }; - - let result = a.add_mul(k, &b); - assert_eq!( - result, - Expression { +#[cfg(test)] +mod tests { + use super::*; + use acir_field::{AcirField, FieldElement}; + + #[test] + fn add_mul_smoketest() { + let a = Expression { + mul_terms: vec![(FieldElement::from(2u128), Witness(1), Witness(2))], + ..Default::default() + }; + + let k = FieldElement::from(10u128); + + let b = Expression { mul_terms: vec![ - (FieldElement::from(30u128), Witness(0), Witness(2)), - (FieldElement::from(32u128), Witness(1), Witness(2)), - (FieldElement::from(40u128), Witness(4), Witness(5)), + (FieldElement::from(3u128), Witness(0), Witness(2)), + (FieldElement::from(3u128), Witness(1), Witness(2)), + (FieldElement::from(4u128), Witness(4), Witness(5)), ], - linear_combinations: vec![(FieldElement::from(40u128), Witness(4))], - q_c: FieldElement::from(10u128) - } - ); + linear_combinations: vec![(FieldElement::from(4u128), Witness(4))], + q_c: FieldElement::one(), + }; + + let result = a.add_mul(k, &b); + assert_eq!( + result, + Expression { + mul_terms: vec![ + (FieldElement::from(30u128), Witness(0), Witness(2)), + (FieldElement::from(32u128), Witness(1), Witness(2)), + (FieldElement::from(40u128), Witness(4), Witness(5)), + ], + linear_combinations: vec![(FieldElement::from(40u128), Witness(4))], + q_c: FieldElement::from(10u128) + } + ); + } } diff --git a/acvm-repo/acir/src/native_types/expression/operators.rs b/acvm-repo/acir/src/native_types/expression/operators.rs index 29cdc6967bb..a8f5dc8e7ad 100644 --- a/acvm-repo/acir/src/native_types/expression/operators.rs +++ b/acvm-repo/acir/src/native_types/expression/operators.rs @@ -1,5 +1,5 @@ use crate::native_types::Witness; -use acir_field::FieldElement; +use acir_field::AcirField; use std::{ cmp::Ordering, ops::{Add, Mul, Neg, Sub}, @@ -9,8 +9,8 @@ use super::Expression; // Negation -impl Neg for &Expression { - type Output = Expression; +impl Neg for &Expression { + type Output = Expression; fn neg(self) -> Self::Output { // XXX(med) : Implement an efficient way to do this @@ -27,9 +27,9 @@ impl Neg for &Expression { // FieldElement -impl Add for Expression { - type Output = Expression; - fn add(self, rhs: FieldElement) -> Self::Output { +impl Add for Expression { + type Output = Self; + fn add(self, rhs: F) -> Self::Output { // Increase the constant let q_c = self.q_c + rhs; @@ -37,17 +37,9 @@ impl Add for Expression { } } -impl Add for FieldElement { - type Output = Expression; - #[inline] - fn add(self, rhs: Expression) -> Self::Output { - rhs + self - } -} - -impl Sub for Expression { - type Output = Expression; - fn sub(self, rhs: FieldElement) -> Self::Output { +impl Sub for Expression { + type Output = Self; + fn sub(self, rhs: F) -> Self::Output { // Increase the constant let q_c = self.q_c - rhs; @@ -55,17 +47,9 @@ impl Sub for Expression { } } -impl Sub for FieldElement { - type Output = Expression; - #[inline] - fn sub(self, rhs: Expression) -> Self::Output { - rhs - self - } -} - -impl Mul for &Expression { - type Output = Expression; - fn mul(self, rhs: FieldElement) -> Self::Output { +impl Mul for &Expression { + type Output = Expression; + fn mul(self, rhs: F) -> Self::Output { // Scale the mul terms let mul_terms: Vec<_> = self.mul_terms.iter().map(|(q_m, w_l, w_r)| (*q_m * rhs, *w_l, *w_r)).collect(); @@ -81,42 +65,34 @@ impl Mul for &Expression { } } -impl Mul<&Expression> for FieldElement { - type Output = Expression; - #[inline] - fn mul(self, rhs: &Expression) -> Self::Output { - rhs * self - } -} - // Witness -impl Add for &Expression { - type Output = Expression; - fn add(self, rhs: Witness) -> Expression { +impl Add for &Expression { + type Output = Expression; + fn add(self, rhs: Witness) -> Self::Output { self + &Expression::from(rhs) } } -impl Add<&Expression> for Witness { - type Output = Expression; +impl Add<&Expression> for Witness { + type Output = Expression; #[inline] - fn add(self, rhs: &Expression) -> Expression { + fn add(self, rhs: &Expression) -> Self::Output { rhs + self } } -impl Sub for &Expression { - type Output = Expression; - fn sub(self, rhs: Witness) -> Expression { +impl Sub for &Expression { + type Output = Expression; + fn sub(self, rhs: Witness) -> Self::Output { self - &Expression::from(rhs) } } -impl Sub<&Expression> for Witness { - type Output = Expression; +impl Sub<&Expression> for Witness { + type Output = Expression; #[inline] - fn sub(self, rhs: &Expression) -> Expression { + fn sub(self, rhs: &Expression) -> Self::Output { rhs - self } } @@ -125,25 +101,25 @@ impl Sub<&Expression> for Witness { // Expression -impl Add<&Expression> for &Expression { - type Output = Expression; - fn add(self, rhs: &Expression) -> Expression { - self.add_mul(FieldElement::one(), rhs) +impl Add<&Expression> for &Expression { + type Output = Expression; + fn add(self, rhs: &Expression) -> Self::Output { + self.add_mul(F::one(), rhs) } } -impl Sub<&Expression> for &Expression { - type Output = Expression; - fn sub(self, rhs: &Expression) -> Expression { - self.add_mul(-FieldElement::one(), rhs) +impl Sub<&Expression> for &Expression { + type Output = Expression; + fn sub(self, rhs: &Expression) -> Self::Output { + self.add_mul(-F::one(), rhs) } } -impl Mul<&Expression> for &Expression { - type Output = Option; - fn mul(self, rhs: &Expression) -> Option { +impl Mul<&Expression> for &Expression { + type Output = Option>; + fn mul(self, rhs: &Expression) -> Self::Output { if self.is_const() { - return Some(self.q_c * rhs); + return Some(rhs * self.q_c); } else if rhs.is_const() { return Some(self * rhs.q_c); } else if !(self.is_linear() && rhs.is_linear()) { @@ -215,7 +191,7 @@ impl Mul<&Expression> for &Expression { } /// Returns `w*b.linear_combinations` -fn single_mul(w: Witness, b: &Expression) -> Expression { +fn single_mul(w: Witness, b: &Expression) -> Expression { Expression { mul_terms: b .linear_combinations @@ -229,62 +205,68 @@ fn single_mul(w: Witness, b: &Expression) -> Expression { } } -#[test] -fn add_smoke_test() { - let a = Expression { - mul_terms: vec![], - linear_combinations: vec![(FieldElement::from(2u128), Witness(2))], - q_c: FieldElement::from(2u128), - }; - - let b = Expression { - mul_terms: vec![], - linear_combinations: vec![(FieldElement::from(4u128), Witness(4))], - q_c: FieldElement::one(), - }; - - assert_eq!( - &a + &b, - Expression { +#[cfg(test)] +mod tests { + use super::*; + use acir_field::{AcirField, FieldElement}; + + #[test] + fn add_smoke_test() { + let a = Expression { mul_terms: vec![], - linear_combinations: vec![ - (FieldElement::from(2u128), Witness(2)), - (FieldElement::from(4u128), Witness(4)) - ], - q_c: FieldElement::from(3u128) - } - ); + linear_combinations: vec![(FieldElement::from(2u128), Witness(2))], + q_c: FieldElement::from(2u128), + }; - // Enforce commutativity - assert_eq!(&a + &b, &b + &a); -} + let b = Expression { + mul_terms: vec![], + linear_combinations: vec![(FieldElement::from(4u128), Witness(4))], + q_c: FieldElement::one(), + }; + + assert_eq!( + &a + &b, + Expression { + mul_terms: vec![], + linear_combinations: vec![ + (FieldElement::from(2u128), Witness(2)), + (FieldElement::from(4u128), Witness(4)) + ], + q_c: FieldElement::from(3u128) + } + ); -#[test] -fn mul_smoke_test() { - let a = Expression { - mul_terms: vec![], - linear_combinations: vec![(FieldElement::from(2u128), Witness(2))], - q_c: FieldElement::from(2u128), - }; - - let b = Expression { - mul_terms: vec![], - linear_combinations: vec![(FieldElement::from(4u128), Witness(4))], - q_c: FieldElement::one(), - }; - - assert_eq!( - (&a * &b).unwrap(), - Expression { - mul_terms: vec![(FieldElement::from(8u128), Witness(2), Witness(4)),], - linear_combinations: vec![ - (FieldElement::from(2u128), Witness(2)), - (FieldElement::from(8u128), Witness(4)) - ], - q_c: FieldElement::from(2u128) - } - ); + // Enforce commutativity + assert_eq!(&a + &b, &b + &a); + } - // Enforce commutativity - assert_eq!(&a * &b, &b * &a); + #[test] + fn mul_smoke_test() { + let a = Expression { + mul_terms: vec![], + linear_combinations: vec![(FieldElement::from(2u128), Witness(2))], + q_c: FieldElement::from(2u128), + }; + + let b = Expression { + mul_terms: vec![], + linear_combinations: vec![(FieldElement::from(4u128), Witness(4))], + q_c: FieldElement::one(), + }; + + assert_eq!( + (&a * &b).unwrap(), + Expression { + mul_terms: vec![(FieldElement::from(8u128), Witness(2), Witness(4)),], + linear_combinations: vec![ + (FieldElement::from(2u128), Witness(2)), + (FieldElement::from(8u128), Witness(4)) + ], + q_c: FieldElement::from(2u128) + } + ); + + // Enforce commutativity + assert_eq!(&a * &b, &b * &a); + } } diff --git a/acvm-repo/acir/src/native_types/expression/ordering.rs b/acvm-repo/acir/src/native_types/expression/ordering.rs index e24a25ec3af..b0e5e88454f 100644 --- a/acvm-repo/acir/src/native_types/expression/ordering.rs +++ b/acvm-repo/acir/src/native_types/expression/ordering.rs @@ -1,3 +1,5 @@ +use acir_field::AcirField; + use crate::native_types::Witness; use std::cmp::Ordering; @@ -6,7 +8,7 @@ use super::Expression; // TODO: It's undecided whether `Expression` should implement `Ord/PartialOrd`. // This is currently used in ACVM in the compiler. -impl Ord for Expression { +impl Ord for Expression { fn cmp(&self, other: &Self) -> Ordering { let mut i1 = self.get_max_idx(); let mut i2 = other.get_max_idx(); @@ -17,13 +19,13 @@ impl Ord for Expression { if m1.is_none() && m2.is_none() { return Ordering::Equal; } - result = Expression::cmp_max(m1, m2); + result = Expression::::cmp_max(m1, m2); } result } } -impl PartialOrd for Expression { +impl PartialOrd for Expression { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } @@ -35,7 +37,7 @@ struct WitnessIdx { second_term: bool, } -impl Expression { +impl Expression { fn get_max_idx(&self) -> WitnessIdx { WitnessIdx { linear: self.linear_combinations.len(), diff --git a/acvm-repo/acir/src/native_types/witness.rs b/acvm-repo/acir/src/native_types/witness.rs index 740d10d2951..3e9beb510bc 100644 --- a/acvm-repo/acir/src/native_types/witness.rs +++ b/acvm-repo/acir/src/native_types/witness.rs @@ -1,10 +1,5 @@ -use std::ops::Add; - -use acir_field::FieldElement; use serde::{Deserialize, Serialize}; -use super::Expression; - // Witness might be a misnomer. This is an index that represents the position a witness will take #[derive( Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Serialize, Deserialize, @@ -33,11 +28,3 @@ impl From for Witness { Self(value) } } - -impl Add for Witness { - type Output = Expression; - - fn add(self, rhs: Witness) -> Self::Output { - Expression::from(self).add_mul(FieldElement::one(), &Expression::from(rhs)) - } -} diff --git a/acvm-repo/acir/src/native_types/witness_map.rs b/acvm-repo/acir/src/native_types/witness_map.rs index 00245d5842c..e508fe5b186 100644 --- a/acvm-repo/acir/src/native_types/witness_map.rs +++ b/acvm-repo/acir/src/native_types/witness_map.rs @@ -4,7 +4,6 @@ use std::{ ops::Index, }; -use acir_field::FieldElement; use flate2::bufread::GzDecoder; use flate2::bufread::GzEncoder; use flate2::Compression; @@ -25,63 +24,63 @@ pub struct WitnessMapError(#[from] SerializationError); /// A map from the witnesses in a constraint system to the field element values #[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Serialize, Deserialize)] -pub struct WitnessMap(BTreeMap); +pub struct WitnessMap(BTreeMap); -impl WitnessMap { +impl WitnessMap { pub fn new() -> Self { Self(BTreeMap::new()) } - pub fn get(&self, witness: &Witness) -> Option<&FieldElement> { + pub fn get(&self, witness: &Witness) -> Option<&F> { self.0.get(witness) } - pub fn get_index(&self, index: u32) -> Option<&FieldElement> { + pub fn get_index(&self, index: u32) -> Option<&F> { self.0.get(&index.into()) } pub fn contains_key(&self, key: &Witness) -> bool { self.0.contains_key(key) } - pub fn insert(&mut self, key: Witness, value: FieldElement) -> Option { + pub fn insert(&mut self, key: Witness, value: F) -> Option { self.0.insert(key, value) } } -impl Index<&Witness> for WitnessMap { - type Output = FieldElement; +impl Index<&Witness> for WitnessMap { + type Output = F; fn index(&self, index: &Witness) -> &Self::Output { &self.0[index] } } -pub struct IntoIter(btree_map::IntoIter); +pub struct IntoIter(btree_map::IntoIter); -impl Iterator for IntoIter { - type Item = (Witness, FieldElement); +impl Iterator for IntoIter { + type Item = (Witness, F); fn next(&mut self) -> Option { self.0.next() } } -impl IntoIterator for WitnessMap { - type Item = (Witness, FieldElement); - type IntoIter = IntoIter; +impl IntoIterator for WitnessMap { + type Item = (Witness, F); + type IntoIter = IntoIter; fn into_iter(self) -> Self::IntoIter { IntoIter(self.0.into_iter()) } } -impl From> for WitnessMap { - fn from(value: BTreeMap) -> Self { +impl From> for WitnessMap { + fn from(value: BTreeMap) -> Self { Self(value) } } -impl TryFrom for Vec { +impl TryFrom> for Vec { type Error = WitnessMapError; - fn try_from(val: WitnessMap) -> Result { + fn try_from(val: WitnessMap) -> Result { let buf = bincode::serialize(&val).unwrap(); let mut deflater = GzEncoder::new(buf.as_slice(), Compression::best()); let mut buf_c = Vec::new(); @@ -90,7 +89,7 @@ impl TryFrom for Vec { } } -impl TryFrom<&[u8]> for WitnessMap { +impl Deserialize<'a>> TryFrom<&[u8]> for WitnessMap { type Error = WitnessMapError; fn try_from(bytes: &[u8]) -> Result { diff --git a/acvm-repo/acir/src/native_types/witness_stack.rs b/acvm-repo/acir/src/native_types/witness_stack.rs index 7c79e3db431..8a4fffa1577 100644 --- a/acvm-repo/acir/src/native_types/witness_stack.rs +++ b/acvm-repo/acir/src/native_types/witness_stack.rs @@ -20,28 +20,28 @@ pub struct WitnessStackError(#[from] SerializationError); /// An ordered set of witness maps for separate circuits #[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Serialize, Deserialize)] -pub struct WitnessStack { - stack: Vec, +pub struct WitnessStack { + stack: Vec>, } #[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Serialize, Deserialize)] -pub struct StackItem { +pub struct StackItem { /// Index into a [crate::circuit::Program] function list for which we have an associated witness pub index: u32, /// A full witness for the respective constraint system specified by the index - pub witness: WitnessMap, + pub witness: WitnessMap, } -impl WitnessStack { - pub fn push(&mut self, index: u32, witness: WitnessMap) { +impl WitnessStack { + pub fn push(&mut self, index: u32, witness: WitnessMap) { self.stack.push(StackItem { index, witness }); } - pub fn pop(&mut self) -> Option { + pub fn pop(&mut self) -> Option> { self.stack.pop() } - pub fn peek(&self) -> Option<&StackItem> { + pub fn peek(&self) -> Option<&StackItem> { self.stack.last() } @@ -50,17 +50,17 @@ impl WitnessStack { } } -impl From for WitnessStack { - fn from(witness: WitnessMap) -> Self { +impl From> for WitnessStack { + fn from(witness: WitnessMap) -> Self { let stack = vec![StackItem { index: 0, witness }]; Self { stack } } } -impl TryFrom for Vec { +impl TryFrom> for Vec { type Error = WitnessStackError; - fn try_from(val: WitnessStack) -> Result { + fn try_from(val: WitnessStack) -> Result { let buf = bincode::serialize(&val).unwrap(); let mut deflater = GzEncoder::new(buf.as_slice(), Compression::best()); let mut buf_c = Vec::new(); @@ -69,7 +69,7 @@ impl TryFrom for Vec { } } -impl TryFrom<&[u8]> for WitnessStack { +impl Deserialize<'a>> TryFrom<&[u8]> for WitnessStack { type Error = WitnessStackError; fn try_from(bytes: &[u8]) -> Result { diff --git a/acvm-repo/acir/tests/test_program_serialization.rs b/acvm-repo/acir/tests/test_program_serialization.rs index 19e4beb6158..d4c7a8782ab 100644 --- a/acvm-repo/acir/tests/test_program_serialization.rs +++ b/acvm-repo/acir/tests/test_program_serialization.rs @@ -19,7 +19,7 @@ use acir::{ }, native_types::{Expression, Witness}, }; -use acir_field::FieldElement; +use acir_field::{AcirField, FieldElement}; use brillig::{HeapArray, HeapValueType, MemoryAddress, ValueOrArray}; #[test] @@ -34,12 +34,12 @@ fn addition_circuit() { q_c: FieldElement::zero(), }); - let circuit = Circuit { + let circuit: Circuit = Circuit { current_witness_index: 4, opcodes: vec![addition], private_parameters: BTreeSet::from([Witness(1), Witness(2)]), return_values: PublicInputs([Witness(3)].into()), - ..Circuit::default() + ..Circuit::::default() }; let program = Program { functions: vec![circuit], unconstrained_functions: vec![] }; @@ -59,18 +59,19 @@ fn addition_circuit() { #[test] fn multi_scalar_mul_circuit() { - let multi_scalar_mul = Opcode::BlackBoxFuncCall(BlackBoxFuncCall::MultiScalarMul { - points: vec![ - FunctionInput { witness: Witness(1), num_bits: 128 }, - FunctionInput { witness: Witness(2), num_bits: 128 }, - FunctionInput { witness: Witness(3), num_bits: 1 }, - ], - scalars: vec![ - FunctionInput { witness: Witness(4), num_bits: 128 }, - FunctionInput { witness: Witness(5), num_bits: 128 }, - ], - outputs: (Witness(6), Witness(7), Witness(8)), - }); + let multi_scalar_mul: Opcode = + Opcode::BlackBoxFuncCall(BlackBoxFuncCall::MultiScalarMul { + points: vec![ + FunctionInput { witness: Witness(1), num_bits: 128 }, + FunctionInput { witness: Witness(2), num_bits: 128 }, + FunctionInput { witness: Witness(3), num_bits: 1 }, + ], + scalars: vec![ + FunctionInput { witness: Witness(4), num_bits: 128 }, + FunctionInput { witness: Witness(5), num_bits: 128 }, + ], + outputs: (Witness(6), Witness(7), Witness(8)), + }); let circuit = Circuit { current_witness_index: 9, @@ -107,7 +108,7 @@ fn pedersen_circuit() { domain_separator: 0, }); - let circuit = Circuit { + let circuit: Circuit = Circuit { current_witness_index: 4, opcodes: vec![pedersen], private_parameters: BTreeSet::from([Witness(1)]), @@ -151,7 +152,7 @@ fn schnorr_verify_circuit() { output, }); - let circuit = Circuit { + let circuit: Circuit = Circuit { current_witness_index: 100, opcodes: vec![schnorr], private_parameters: BTreeSet::from_iter((1..=last_input).map(Witness)), @@ -219,7 +220,7 @@ fn simple_brillig_foreign_call() { predicate: None, }]; - let circuit = Circuit { + let circuit: Circuit = Circuit { current_witness_index: 8, opcodes, private_parameters: BTreeSet::from([Witness(1), Witness(2)]), diff --git a/acvm-repo/acir_field/Cargo.toml b/acvm-repo/acir_field/Cargo.toml index dd4b7af9ffc..8d8a1e9e2bd 100644 --- a/acvm-repo/acir_field/Cargo.toml +++ b/acvm-repo/acir_field/Cargo.toml @@ -18,17 +18,12 @@ num-bigint.workspace = true serde.workspace = true num-traits.workspace = true -ark-bn254 = { version = "^0.4.0", optional = true, default-features = false, features = [ - "curve", -] } -ark-bls12-381 = { version = "^0.4.0", optional = true, default-features = false, features = [ - "curve", -] } -ark-ff = { version = "^0.4.0", optional = true, default-features = false } +ark-bn254 = { version = "^0.4.0", default-features = false, features = ["curve"] } +ark-bls12-381 = { version = "^0.4.0", optional = true, default-features = false, features = ["curve"] } +ark-ff = { version = "^0.4.0", default-features = false } cfg-if = "1.0.0" [features] -default = ["bn254"] -bn254 = ["dep:ark-bn254", "dep:ark-ff"] -bls12_381 = ["dep:ark-bls12-381", "dep:ark-ff"] +bn254 = [] +bls12_381 = ["dep:ark-bls12-381"] diff --git a/acvm-repo/acir_field/src/generic_ark.rs b/acvm-repo/acir_field/src/generic_ark.rs index 3178011a075..c1bc7971922 100644 --- a/acvm-repo/acir_field/src/generic_ark.rs +++ b/acvm-repo/acir_field/src/generic_ark.rs @@ -4,9 +4,90 @@ use num_bigint::BigUint; use serde::{Deserialize, Serialize}; use std::borrow::Cow; +/// This trait is extremely unstable and WILL have breaking changes. +pub trait AcirField: + std::marker::Sized + + Display + + Debug + + Default + + Clone + + Copy + + Neg + + Add + + Sub + + Mul + + Div + + PartialOrd + + AddAssign + + SubAssign + + From + + From + // + From + // + From + // + From + // + From + + From + + Hash + + std::cmp::Eq +{ + fn one() -> Self; + fn zero() -> Self; + + fn is_zero(&self) -> bool; + fn is_one(&self) -> bool; + + fn pow(&self, exponent: &Self) -> Self; + + /// Maximum number of bits needed to represent a field element + /// This is not the amount of bits being used to represent a field element + /// Example, you only need 254 bits to represent a field element in BN256 + /// But the representation uses 256 bits, so the top two bits are always zero + /// This method would return 254 + fn max_num_bits() -> u32; + + /// Maximum numbers of bytes needed to represent a field element + /// We are not guaranteed that the number of bits being used to represent a field element + /// will always be divisible by 8. If the case that it is not, we add one to the max number of bytes + /// For example, a max bit size of 254 would give a max byte size of 32. + fn max_num_bytes() -> u32; + + fn modulus() -> BigUint; + + /// This is the number of bits required to represent this specific field element + fn num_bits(&self) -> u32; + + fn to_u128(self) -> u128; + + fn try_into_u128(self) -> Option; + + fn to_i128(self) -> i128; + + fn try_to_u64(&self) -> Option; + + /// Computes the inverse or returns zero if the inverse does not exist + /// Before using this FieldElement, please ensure that this behavior is necessary + fn inverse(&self) -> Self; + + fn to_hex(self) -> String; + + fn from_hex(hex_str: &str) -> Option; + + fn to_be_bytes(self) -> Vec; + + /// Converts bytes into a FieldElement and applies a reduction if needed. + fn from_be_bytes_reduce(bytes: &[u8]) -> Self; + + /// Returns the closest number of bytes to the bits specified + /// This method truncates + fn fetch_nearest_bytes(&self, num_bits: usize) -> Vec; + + fn and(&self, rhs: &Self, num_bits: u32) -> Self; + fn xor(&self, rhs: &Self, num_bits: u32) -> Self; +} + // XXX: Switch out for a trait and proper implementations // This implementation is in-efficient, can definitely remove hex usage and Iterator instances for trivial functionality -#[derive(Clone, Copy, Eq, PartialOrd, Ord)] +#[derive(Default, Clone, Copy, Eq, PartialOrd, Ord)] pub struct FieldElement(F); impl std::fmt::Display for FieldElement { @@ -161,25 +242,104 @@ impl From for FieldElement { } impl FieldElement { - pub fn one() -> FieldElement { + pub fn from_repr(field: F) -> Self { + Self(field) + } + + // XXX: This method is used while this field element + // implementation is not generic. + pub fn into_repr(self) -> F { + self.0 + } + + fn is_negative(&self) -> bool { + self.neg().num_bits() < self.num_bits() + } + + fn fits_in_u128(&self) -> bool { + self.num_bits() <= 128 + } + + /// Returns None, if the string is not a canonical + /// representation of a field element; less than the order + /// or if the hex string is invalid. + /// This method can be used for both hex and decimal representations. + pub fn try_from_str(input: &str) -> Option> { + if input.contains('x') { + return FieldElement::from_hex(input); + } + + let fr = F::from_str(input).ok()?; + Some(FieldElement(fr)) + } + + // mask_to methods will not remove any bytes from the field + // they are simply zeroed out + // Whereas truncate_to will remove those bits and make the byte array smaller + fn mask_to_be_bytes(&self, num_bits: u32) -> Vec { + let mut bytes = self.to_be_bytes(); + mask_vector_le(&mut bytes, num_bits as usize); + bytes + } + + fn bits(&self) -> Vec { + fn byte_to_bit(byte: u8) -> Vec { + let mut bits = Vec::with_capacity(8); + for index in (0..=7).rev() { + bits.push((byte & (1 << index)) >> index == 1); + } + bits + } + + let bytes = self.to_be_bytes(); + let mut bits = Vec::with_capacity(bytes.len() * 8); + for byte in bytes { + let _bits = byte_to_bit(byte); + bits.extend(_bits); + } + bits + } + + fn and_xor(&self, rhs: &FieldElement, num_bits: u32, is_xor: bool) -> FieldElement { + // XXX: Gadgets like SHA256 need to have their input be a multiple of 8 + // This is not a restriction caused by SHA256, as it works on bits + // but most backends assume bytes. + // We could implicitly pad, however this may not be intuitive for users. + // assert!( + // num_bits % 8 == 0, + // "num_bits is not a multiple of 8, it is {}", + // num_bits + // ); + + let lhs_bytes = self.mask_to_be_bytes(num_bits); + let rhs_bytes = rhs.mask_to_be_bytes(num_bits); + + let and_byte_arr: Vec<_> = lhs_bytes + .into_iter() + .zip(rhs_bytes) + .map(|(lhs, rhs)| if is_xor { lhs ^ rhs } else { lhs & rhs }) + .collect(); + + FieldElement::from_be_bytes_reduce(&and_byte_arr) + } +} + +impl AcirField for FieldElement { + fn one() -> FieldElement { FieldElement(F::one()) } - pub fn zero() -> FieldElement { + fn zero() -> FieldElement { FieldElement(F::zero()) } - pub fn is_zero(&self) -> bool { + fn is_zero(&self) -> bool { self == &Self::zero() } - pub fn is_one(&self) -> bool { + fn is_one(&self) -> bool { self == &Self::one() } - pub fn is_negative(&self) -> bool { - self.neg().num_bits() < self.num_bits() - } - - pub fn pow(&self, exponent: &Self) -> Self { + fn pow(&self, exponent: &Self) -> Self { FieldElement(self.0.pow(exponent.0.into_bigint())) } @@ -188,7 +348,7 @@ impl FieldElement { /// Example, you only need 254 bits to represent a field element in BN256 /// But the representation uses 256 bits, so the top two bits are always zero /// This method would return 254 - pub const fn max_num_bits() -> u32 { + fn max_num_bits() -> u32 { F::MODULUS_BIT_SIZE } @@ -196,7 +356,7 @@ impl FieldElement { /// We are not guaranteed that the number of bits being used to represent a field element /// will always be divisible by 8. If the case that it is not, we add one to the max number of bytes /// For example, a max bit size of 254 would give a max byte size of 32. - pub const fn max_num_bytes() -> u32 { + fn max_num_bytes() -> u32 { let num_bytes = Self::max_num_bits() / 8; if Self::max_num_bits() % 8 == 0 { num_bytes @@ -205,24 +365,12 @@ impl FieldElement { } } - pub fn modulus() -> BigUint { + fn modulus() -> BigUint { F::MODULUS.into() } - /// Returns None, if the string is not a canonical - /// representation of a field element; less than the order - /// or if the hex string is invalid. - /// This method can be used for both hex and decimal representations. - pub fn try_from_str(input: &str) -> Option> { - if input.contains('x') { - return FieldElement::from_hex(input); - } - - let fr = F::from_str(input).ok()?; - Some(FieldElement(fr)) - } /// This is the number of bits required to represent this specific field element - pub fn num_bits(&self) -> u32 { + fn num_bits(&self) -> u32 { let bits = self.bits(); // Iterate the number of bits and pop off all leading zeroes let iter = bits.iter().skip_while(|x| !(**x)); @@ -231,57 +379,39 @@ impl FieldElement { iter.count() as u32 } - pub fn fits_in_u128(&self) -> bool { - self.num_bits() <= 128 - } - - pub fn to_u128(self) -> u128 { + fn to_u128(self) -> u128 { let bytes = self.to_be_bytes(); u128::from_be_bytes(bytes[16..32].try_into().unwrap()) } - pub fn try_into_u128(self) -> Option { + fn try_into_u128(self) -> Option { self.fits_in_u128().then(|| self.to_u128()) } - pub fn to_i128(self) -> i128 { + fn to_i128(self) -> i128 { let is_negative = self.is_negative(); let bytes = if is_negative { self.neg() } else { self }.to_be_bytes(); i128::from_be_bytes(bytes[16..32].try_into().unwrap()) * if is_negative { -1 } else { 1 } } - pub fn try_to_u64(&self) -> Option { + fn try_to_u64(&self) -> Option { (self.num_bits() <= 64).then(|| self.to_u128() as u64) } /// Computes the inverse or returns zero if the inverse does not exist /// Before using this FieldElement, please ensure that this behavior is necessary - pub fn inverse(&self) -> FieldElement { + fn inverse(&self) -> FieldElement { let inv = self.0.inverse().unwrap_or_else(F::zero); FieldElement(inv) } - pub fn try_inverse(mut self) -> Option { - self.0.inverse_in_place().map(|f| FieldElement(*f)) - } - - pub fn from_repr(field: F) -> Self { - Self(field) - } - - // XXX: This method is used while this field element - // implementation is not generic. - pub fn into_repr(self) -> F { - self.0 - } - - pub fn to_hex(self) -> String { + fn to_hex(self) -> String { let mut bytes = Vec::new(); self.0.serialize_uncompressed(&mut bytes).unwrap(); bytes.reverse(); hex::encode(bytes) } - pub fn from_hex(hex_str: &str) -> Option> { + fn from_hex(hex_str: &str) -> Option> { let value = hex_str.strip_prefix("0x").unwrap_or(hex_str); // Values of odd length require an additional "0" prefix let sanitized_value = @@ -290,7 +420,7 @@ impl FieldElement { Some(FieldElement::from_be_bytes_reduce(&hex_as_bytes)) } - pub fn to_be_bytes(self) -> Vec { + fn to_be_bytes(self) -> Vec { // to_be_bytes! uses little endian which is why we reverse the output // TODO: Add a little endian equivalent, so the caller can use whichever one // TODO they desire @@ -302,31 +432,13 @@ impl FieldElement { /// Converts bytes into a FieldElement and applies a /// reduction if needed. - pub fn from_be_bytes_reduce(bytes: &[u8]) -> FieldElement { + fn from_be_bytes_reduce(bytes: &[u8]) -> FieldElement { FieldElement(F::from_be_bytes_mod_order(bytes)) } - pub fn bits(&self) -> Vec { - let bytes = self.to_be_bytes(); - let mut bits = Vec::with_capacity(bytes.len() * 8); - for byte in bytes { - let _bits = FieldElement::::byte_to_bit(byte); - bits.extend(_bits); - } - bits - } - - fn byte_to_bit(byte: u8) -> Vec { - let mut bits = Vec::with_capacity(8); - for index in (0..=7).rev() { - bits.push((byte & (1 << index)) >> index == 1); - } - bits - } - /// Returns the closest number of bytes to the bits specified /// This method truncates - pub fn fetch_nearest_bytes(&self, num_bits: usize) -> Vec { + fn fetch_nearest_bytes(&self, num_bits: usize) -> Vec { fn nearest_bytes(num_bits: usize) -> usize { ((num_bits + 7) / 8) * 8 } @@ -340,45 +452,17 @@ impl FieldElement { bytes[0..num_elements].to_vec() } - // mask_to methods will not remove any bytes from the field - // they are simply zeroed out - // Whereas truncate_to will remove those bits and make the byte array smaller - fn mask_to_be_bytes(&self, num_bits: u32) -> Vec { - let mut bytes = self.to_be_bytes(); - mask_vector_le(&mut bytes, num_bits as usize); - bytes - } - - fn and_xor(&self, rhs: &FieldElement, num_bits: u32, is_xor: bool) -> FieldElement { - // XXX: Gadgets like SHA256 need to have their input be a multiple of 8 - // This is not a restriction caused by SHA256, as it works on bits - // but most backends assume bytes. - // We could implicitly pad, however this may not be intuitive for users. - // assert!( - // num_bits % 8 == 0, - // "num_bits is not a multiple of 8, it is {}", - // num_bits - // ); - - let lhs_bytes = self.mask_to_be_bytes(num_bits); - let rhs_bytes = rhs.mask_to_be_bytes(num_bits); - - let and_byte_arr: Vec<_> = lhs_bytes - .into_iter() - .zip(rhs_bytes) - .map(|(lhs, rhs)| if is_xor { lhs ^ rhs } else { lhs & rhs }) - .collect(); - - FieldElement::from_be_bytes_reduce(&and_byte_arr) - } - pub fn and(&self, rhs: &FieldElement, num_bits: u32) -> FieldElement { + fn and(&self, rhs: &FieldElement, num_bits: u32) -> FieldElement { self.and_xor(rhs, num_bits, false) } - pub fn xor(&self, rhs: &FieldElement, num_bits: u32) -> FieldElement { + fn xor(&self, rhs: &FieldElement, num_bits: u32) -> FieldElement { self.and_xor(rhs, num_bits, true) } } +use std::fmt::Debug; +use std::fmt::Display; +use std::hash::Hash; use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign}; impl Neg for FieldElement { @@ -489,6 +573,8 @@ fn superscript(n: u64) -> String { #[cfg(test)] mod tests { + use super::{AcirField, FieldElement}; + #[test] fn and() { let max = 10_000u32; @@ -496,7 +582,7 @@ mod tests { let num_bits = (std::mem::size_of::() * 8) as u32 - max.leading_zeros(); for x in 0..max { - let x = crate::generic_ark::FieldElement::::from(x as i128); + let x = FieldElement::::from(x as i128); let res = x.and(&x, num_bits); assert_eq!(res.to_be_bytes(), x.to_be_bytes()); } @@ -513,8 +599,7 @@ mod tests { ]; for (i, string) in hex_strings.into_iter().enumerate() { - let minus_i_field_element = - -crate::generic_ark::FieldElement::::from(i as i128); + let minus_i_field_element = -FieldElement::::from(i as i128); assert_eq!(minus_i_field_element.to_hex(), string); } } @@ -525,12 +610,9 @@ mod tests { let hex_strings = vec![("0x0", "0x00"), ("0x1", "0x01"), ("0x002", "0x0002"), ("0x00003", "0x000003")]; for (i, case) in hex_strings.into_iter().enumerate() { - let i_field_element = - crate::generic_ark::FieldElement::::from(i as i128); - let odd_field_element = - crate::generic_ark::FieldElement::::from_hex(case.0).unwrap(); - let even_field_element = - crate::generic_ark::FieldElement::::from_hex(case.1).unwrap(); + let i_field_element = FieldElement::::from(i as i128); + let odd_field_element = FieldElement::::from_hex(case.0).unwrap(); + let even_field_element = FieldElement::::from_hex(case.1).unwrap(); assert_eq!(i_field_element, odd_field_element); assert_eq!(odd_field_element, even_field_element); @@ -539,7 +621,7 @@ mod tests { #[test] fn max_num_bits_smoke() { - let max_num_bits_bn254 = crate::generic_ark::FieldElement::::max_num_bits(); + let max_num_bits_bn254 = FieldElement::::max_num_bits(); assert_eq!(max_num_bits_bn254, 254); } } diff --git a/acvm-repo/acir_field/src/lib.rs b/acvm-repo/acir_field/src/lib.rs index eafe4bb2ad4..7f06330ed8d 100644 --- a/acvm-repo/acir_field/src/lib.rs +++ b/acvm-repo/acir_field/src/lib.rs @@ -5,19 +5,20 @@ use num_bigint::BigUint; use num_traits::Num; +mod generic_ark; -cfg_if::cfg_if! { - if #[cfg(feature = "bn254")] { - mod generic_ark; - pub type FieldElement = generic_ark::FieldElement; - pub const CHOSEN_FIELD : FieldOptions = FieldOptions::BN254; +pub use generic_ark::AcirField; + +/// Temporarily exported generic field to aid migration to `AcirField` +pub use generic_ark::FieldElement as GenericFieldElement; - } else if #[cfg(feature = "bls12_381")] { - mod generic_ark; +cfg_if::cfg_if! { + if #[cfg(feature = "bls12_381")] { pub type FieldElement = generic_ark::FieldElement; pub const CHOSEN_FIELD : FieldOptions = FieldOptions::BLS12_381; } else { - compile_error!("please specify a field to compile with"); + pub type FieldElement = generic_ark::FieldElement; + pub const CHOSEN_FIELD : FieldOptions = FieldOptions::BN254; } } diff --git a/acvm-repo/acvm/Cargo.toml b/acvm-repo/acvm/Cargo.toml index 74aed429f9a..577978939b0 100644 --- a/acvm-repo/acvm/Cargo.toml +++ b/acvm-repo/acvm/Cargo.toml @@ -24,7 +24,6 @@ acvm_blackbox_solver.workspace = true indexmap = "1.7.0" [features] -default = ["bn254"] bn254 = [ "acir/bn254", "brillig_vm/bn254", @@ -40,3 +39,4 @@ bls12_381 = [ rand = "0.8.5" proptest = "1.2.0" paste = "1.0.14" +ark-bls12-381 = { version = "^0.4.0", default-features = false, features = ["curve"] } \ No newline at end of file diff --git a/acvm-repo/acvm/src/compiler/mod.rs b/acvm-repo/acvm/src/compiler/mod.rs index 436db648ea8..5ece3d19a6e 100644 --- a/acvm-repo/acvm/src/compiler/mod.rs +++ b/acvm-repo/acvm/src/compiler/mod.rs @@ -1,6 +1,9 @@ use std::collections::HashMap; -use acir::circuit::{AssertionPayload, Circuit, ExpressionWidth, OpcodeLocation}; +use acir::{ + circuit::{AssertionPayload, Circuit, ExpressionWidth, OpcodeLocation}, + AcirField, +}; // The various passes that we can use over ACIR mod optimizers; @@ -53,10 +56,10 @@ impl AcirTransformationMap { } } -fn transform_assert_messages( - assert_messages: Vec<(OpcodeLocation, AssertionPayload)>, +fn transform_assert_messages( + assert_messages: Vec<(OpcodeLocation, AssertionPayload)>, map: &AcirTransformationMap, -) -> Vec<(OpcodeLocation, AssertionPayload)> { +) -> Vec<(OpcodeLocation, AssertionPayload)> { assert_messages .into_iter() .flat_map(|(location, message)| { @@ -67,10 +70,10 @@ fn transform_assert_messages( } /// Applies [`ProofSystemCompiler`][crate::ProofSystemCompiler] specific optimizations to a [`Circuit`]. -pub fn compile( - acir: Circuit, +pub fn compile( + acir: Circuit, expression_width: ExpressionWidth, -) -> (Circuit, AcirTransformationMap) { +) -> (Circuit, AcirTransformationMap) { let (acir, acir_opcode_positions) = optimize_internal(acir); let (mut acir, acir_opcode_positions) = diff --git a/acvm-repo/acvm/src/compiler/optimizers/general.rs b/acvm-repo/acvm/src/compiler/optimizers/general.rs index a48a590a05e..39a01a38cac 100644 --- a/acvm-repo/acvm/src/compiler/optimizers/general.rs +++ b/acvm-repo/acvm/src/compiler/optimizers/general.rs @@ -1,6 +1,6 @@ use acir::{ native_types::{Expression, Witness}, - FieldElement, + AcirField, }; use indexmap::IndexMap; @@ -10,7 +10,7 @@ use indexmap::IndexMap; pub(crate) struct GeneralOptimizer; impl GeneralOptimizer { - pub(crate) fn optimize(opcode: Expression) -> Expression { + pub(crate) fn optimize(opcode: Expression) -> Expression { // XXX: Perhaps this optimization can be done on the fly let opcode = remove_zero_coefficients(opcode); let opcode = simplify_mul_terms(opcode); @@ -19,7 +19,7 @@ impl GeneralOptimizer { } // Remove all terms with zero as a coefficient -fn remove_zero_coefficients(mut opcode: Expression) -> Expression { +fn remove_zero_coefficients(mut opcode: Expression) -> Expression { // Check the mul terms opcode.mul_terms.retain(|(scale, _, _)| !scale.is_zero()); // Check the linear combination terms @@ -28,8 +28,8 @@ fn remove_zero_coefficients(mut opcode: Expression) -> Expression { } // Simplifies all mul terms with the same bi-variate variables -fn simplify_mul_terms(mut gate: Expression) -> Expression { - let mut hash_map: IndexMap<(Witness, Witness), FieldElement> = IndexMap::new(); +fn simplify_mul_terms(mut gate: Expression) -> Expression { + let mut hash_map: IndexMap<(Witness, Witness), F> = IndexMap::new(); // Canonicalize the ordering of the multiplication, lets just order by variable name for (scale, w_l, w_r) in gate.mul_terms.into_iter() { @@ -37,7 +37,7 @@ fn simplify_mul_terms(mut gate: Expression) -> Expression { // Sort using rust sort algorithm pair.sort(); - *hash_map.entry((pair[0], pair[1])).or_insert_with(FieldElement::zero) += scale; + *hash_map.entry((pair[0], pair[1])).or_insert_with(F::zero) += scale; } gate.mul_terms = hash_map.into_iter().map(|((w_l, w_r), scale)| (scale, w_l, w_r)).collect(); @@ -45,17 +45,17 @@ fn simplify_mul_terms(mut gate: Expression) -> Expression { } // Simplifies all linear terms with the same variables -fn simplify_linear_terms(mut gate: Expression) -> Expression { - let mut hash_map: IndexMap = IndexMap::new(); +fn simplify_linear_terms(mut gate: Expression) -> Expression { + let mut hash_map: IndexMap = IndexMap::new(); // Canonicalize the ordering of the terms, lets just order by variable name for (scale, witness) in gate.linear_combinations.into_iter() { - *hash_map.entry(witness).or_insert_with(FieldElement::zero) += scale; + *hash_map.entry(witness).or_insert_with(F::zero) += scale; } gate.linear_combinations = hash_map .into_iter() - .filter(|(_, scale)| scale != &FieldElement::zero()) + .filter(|(_, scale)| !scale.is_zero()) .map(|(witness, scale)| (scale, witness)) .collect(); gate diff --git a/acvm-repo/acvm/src/compiler/optimizers/mod.rs b/acvm-repo/acvm/src/compiler/optimizers/mod.rs index dfe348d4ff5..e20ad97a108 100644 --- a/acvm-repo/acvm/src/compiler/optimizers/mod.rs +++ b/acvm-repo/acvm/src/compiler/optimizers/mod.rs @@ -1,4 +1,7 @@ -use acir::circuit::{Circuit, Opcode}; +use acir::{ + circuit::{Circuit, Opcode}, + AcirField, +}; // mod constant_backpropagation; mod general; @@ -15,7 +18,7 @@ use self::unused_memory::UnusedMemoryOptimizer; use super::{transform_assert_messages, AcirTransformationMap}; /// Applies [`ProofSystemCompiler`][crate::ProofSystemCompiler] independent optimizations to a [`Circuit`]. -pub fn optimize(acir: Circuit) -> (Circuit, AcirTransformationMap) { +pub fn optimize(acir: Circuit) -> (Circuit, AcirTransformationMap) { let (mut acir, new_opcode_positions) = optimize_internal(acir); let transformation_map = AcirTransformationMap::new(new_opcode_positions); @@ -27,7 +30,7 @@ pub fn optimize(acir: Circuit) -> (Circuit, AcirTransformationMap) { /// Applies [`ProofSystemCompiler`][crate::ProofSystemCompiler] independent optimizations to a [`Circuit`]. #[tracing::instrument(level = "trace", name = "optimize_acir" skip(acir))] -pub(super) fn optimize_internal(acir: Circuit) -> (Circuit, Vec) { +pub(super) fn optimize_internal(acir: Circuit) -> (Circuit, Vec) { // Track original acir opcode positions throughout the transformation passes of the compilation // by applying the modifications done to the circuit opcodes and also to the opcode_positions (delete and insert) let acir_opcode_positions = (0..acir.opcodes.len()).collect(); @@ -40,7 +43,7 @@ pub(super) fn optimize_internal(acir: Circuit) -> (Circuit, Vec) { info!("Number of opcodes before: {}", acir.opcodes.len()); // General optimizer pass - let opcodes: Vec = acir + let opcodes: Vec> = acir .opcodes .into_iter() .map(|opcode| { diff --git a/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs b/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs index 0e1629717b3..7001c953d63 100644 --- a/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs +++ b/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs @@ -4,6 +4,7 @@ use acir::{ Circuit, Opcode, }, native_types::Witness, + AcirField, }; use std::collections::{BTreeMap, HashSet}; @@ -26,16 +27,16 @@ use std::collections::{BTreeMap, HashSet}; /// /// This optimization pass will keep the 16-bit range constraint /// and remove the 32-bit range constraint opcode. -pub(crate) struct RangeOptimizer { +pub(crate) struct RangeOptimizer { /// Maps witnesses to their lowest known bit sizes. lists: BTreeMap, - circuit: Circuit, + circuit: Circuit, } -impl RangeOptimizer { +impl RangeOptimizer { /// Creates a new `RangeOptimizer` by collecting all known range /// constraints from `Circuit`. - pub(crate) fn new(circuit: Circuit) -> Self { + pub(crate) fn new(circuit: Circuit) -> Self { let range_list = Self::collect_ranges(&circuit); Self { circuit, lists: range_list } } @@ -46,7 +47,7 @@ impl RangeOptimizer { /// both 32 bits and 16 bits. This function will /// only store the fact that we have constrained it to /// be 16 bits. - fn collect_ranges(circuit: &Circuit) -> BTreeMap { + fn collect_ranges(circuit: &Circuit) -> BTreeMap { let mut witness_to_bit_sizes: BTreeMap = BTreeMap::new(); for opcode in &circuit.opcodes { @@ -95,7 +96,10 @@ impl RangeOptimizer { /// Returns a `Circuit` where each Witness is only range constrained /// once to the lowest number `bit size` possible. - pub(crate) fn replace_redundant_ranges(self, order_list: Vec) -> (Circuit, Vec) { + pub(crate) fn replace_redundant_ranges( + self, + order_list: Vec, + ) -> (Circuit, Vec) { let mut already_seen_witness = HashSet::new(); let mut new_order_list = Vec::with_capacity(order_list.len()); @@ -148,10 +152,11 @@ mod tests { Circuit, ExpressionWidth, Opcode, PublicInputs, }, native_types::{Expression, Witness}, + FieldElement, }; - fn test_circuit(ranges: Vec<(Witness, u32)>) -> Circuit { - fn test_range_constraint(witness: Witness, num_bits: u32) -> Opcode { + fn test_circuit(ranges: Vec<(Witness, u32)>) -> Circuit { + fn test_range_constraint(witness: Witness, num_bits: u32) -> Opcode { Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { input: FunctionInput { witness, num_bits }, }) diff --git a/acvm-repo/acvm/src/compiler/optimizers/unused_memory.rs b/acvm-repo/acvm/src/compiler/optimizers/unused_memory.rs index 5fdcf54a492..1963430210f 100644 --- a/acvm-repo/acvm/src/compiler/optimizers/unused_memory.rs +++ b/acvm-repo/acvm/src/compiler/optimizers/unused_memory.rs @@ -2,15 +2,15 @@ use acir::circuit::{opcodes::BlockId, Circuit, Opcode}; use std::collections::HashSet; /// `UnusedMemoryOptimizer` will remove initializations of memory blocks which are unused. -pub(crate) struct UnusedMemoryOptimizer { +pub(crate) struct UnusedMemoryOptimizer { unused_memory_initializations: HashSet, - circuit: Circuit, + circuit: Circuit, } -impl UnusedMemoryOptimizer { +impl UnusedMemoryOptimizer { /// Creates a new `UnusedMemoryOptimizer ` by collecting unused memory init /// opcodes from `Circuit`. - pub(crate) fn new(circuit: Circuit) -> Self { + pub(crate) fn new(circuit: Circuit) -> Self { let unused_memory_initializations = Self::collect_unused_memory_initializations(&circuit); Self { circuit, unused_memory_initializations } } @@ -18,7 +18,7 @@ impl UnusedMemoryOptimizer { /// Creates a set of ids for memory blocks for which no [`Opcode::MemoryOp`]s exist. /// /// These memory blocks can be safely removed. - fn collect_unused_memory_initializations(circuit: &Circuit) -> HashSet { + fn collect_unused_memory_initializations(circuit: &Circuit) -> HashSet { let mut unused_memory_initialization = HashSet::new(); for opcode in &circuit.opcodes { @@ -39,7 +39,7 @@ impl UnusedMemoryOptimizer { pub(crate) fn remove_unused_memory_initializations( self, order_list: Vec, - ) -> (Circuit, Vec) { + ) -> (Circuit, Vec) { let mut new_order_list = Vec::with_capacity(order_list.len()); let mut optimized_opcodes = Vec::with_capacity(self.circuit.opcodes.len()); for (idx, opcode) in self.circuit.opcodes.into_iter().enumerate() { diff --git a/acvm-repo/acvm/src/compiler/transformers/csat.rs b/acvm-repo/acvm/src/compiler/transformers/csat.rs index 12a37e3e37a..6cf74c04205 100644 --- a/acvm-repo/acvm/src/compiler/transformers/csat.rs +++ b/acvm-repo/acvm/src/compiler/transformers/csat.rs @@ -2,7 +2,7 @@ use std::{cmp::Ordering, collections::HashSet}; use acir::{ native_types::{Expression, Witness}, - FieldElement, + AcirField, }; use indexmap::IndexMap; @@ -30,7 +30,7 @@ impl CSatTransformer { } /// Check if the equation 'expression=0' can be solved, and if yes, add the solved witness to set of solvable witness - fn try_solve(&mut self, opcode: &Expression) { + fn try_solve(&mut self, opcode: &Expression) { let mut unresolved = Vec::new(); for (_, w1, w2) in &opcode.mul_terms { if !self.solvable_witness.contains(w1) { @@ -64,12 +64,12 @@ impl CSatTransformer { // Still missing dead witness optimization. // To do this, we will need the whole set of assert-zero opcodes // I think it can also be done before the local optimization seen here, as dead variables will come from the user - pub(crate) fn transform( + pub(crate) fn transform( &mut self, - opcode: Expression, - intermediate_variables: &mut IndexMap, + opcode: Expression, + intermediate_variables: &mut IndexMap, (F, Witness)>, num_witness: &mut u32, - ) -> Expression { + ) -> Expression { // Here we create intermediate variables and constrain them to be equal to any subset of the polynomial that can be represented as a full opcode let opcode = self.full_opcode_scan_optimization(opcode, intermediate_variables, num_witness); @@ -107,12 +107,12 @@ impl CSatTransformer { // The polynomial now looks like so t + t2 // We can no longer extract another full opcode, hence the algorithm terminates. Creating two intermediate variables t and t2. // This stage of preprocessing does not guarantee that all polynomials can fit into a opcode. It only guarantees that all full opcodes have been extracted from each polynomial - fn full_opcode_scan_optimization( + fn full_opcode_scan_optimization( &mut self, - mut opcode: Expression, - intermediate_variables: &mut IndexMap, + mut opcode: Expression, + intermediate_variables: &mut IndexMap, (F, Witness)>, num_witness: &mut u32, - ) -> Expression { + ) -> Expression { // We pass around this intermediate variable IndexMap, so that we do not create intermediate variables that we have created before // One instance where this might happen is t1 = wL * wR and t2 = wR * wL @@ -245,7 +245,7 @@ impl CSatTransformer { /// Normalize an expression by dividing it by its first coefficient /// The first coefficient here means coefficient of the first linear term, or of the first quadratic term if no linear terms exist. /// The function panic if the input expression is constant - fn normalize(mut expr: Expression) -> (FieldElement, Expression) { + fn normalize(mut expr: Expression) -> (F, Expression) { expr.sort(); let a = if !expr.linear_combinations.is_empty() { expr.linear_combinations[0].0 @@ -259,11 +259,11 @@ impl CSatTransformer { /// The sets of previously generated witness and their (normalized) expression is cached in the intermediate_variables map /// If there is no cache hit, we generate a new witness (and add the expression to the cache) /// else, we return the cached witness along with the scaling factor so it is equal to the provided expression - fn get_or_create_intermediate_vars( - intermediate_variables: &mut IndexMap, - expr: Expression, + fn get_or_create_intermediate_vars( + intermediate_variables: &mut IndexMap, (F, Witness)>, + expr: Expression, num_witness: &mut u32, - ) -> (FieldElement, Witness) { + ) -> (F, Witness) { let (k, normalized_expr) = Self::normalize(expr); if intermediate_variables.contains_key(&normalized_expr) { @@ -274,7 +274,7 @@ impl CSatTransformer { *num_witness += 1; // Add intermediate opcode and variable to map intermediate_variables.insert(normalized_expr, (k, inter_var)); - (FieldElement::one(), inter_var) + (F::one(), inter_var) } } @@ -315,12 +315,12 @@ impl CSatTransformer { // Also remember that since we did full opcode scan, there is no way we can have a non-zero mul term along with the wL and wR terms being non-zero // // Cases, a lot of mul terms, a lot of fan-in terms, 50/50 - fn partial_opcode_scan_optimization( + fn partial_opcode_scan_optimization( &mut self, - mut opcode: Expression, - intermediate_variables: &mut IndexMap, + mut opcode: Expression, + intermediate_variables: &mut IndexMap, (F, Witness)>, num_witness: &mut u32, - ) -> Expression { + ) -> Expression { // We will go for the easiest route, which is to convert all multiplications into additions using intermediate variables // Then use intermediate variables again to squash the fan-in, so that it can fit into the appropriate width @@ -409,101 +409,113 @@ impl CSatTransformer { } } -#[test] -fn simple_reduction_smoke_test() { - let a = Witness(0); - let b = Witness(1); - let c = Witness(2); - let d = Witness(3); - - // a = b + c + d; - let opcode_a = Expression { - mul_terms: vec![], - linear_combinations: vec![ - (FieldElement::one(), a), - (-FieldElement::one(), b), - (-FieldElement::one(), c), - (-FieldElement::one(), d), - ], - q_c: FieldElement::zero(), - }; - - let mut intermediate_variables: IndexMap = IndexMap::new(); - - let mut num_witness = 4; - - let mut optimizer = CSatTransformer::new(3); - optimizer.mark_solvable(b); - optimizer.mark_solvable(c); - optimizer.mark_solvable(d); - let got_optimized_opcode_a = - optimizer.transform(opcode_a, &mut intermediate_variables, &mut num_witness); - - // a = b + c + d => a - b - c - d = 0 - // For width3, the result becomes: - // a - d + e = 0 - // - c - b - e = 0 - // - // a - b + e = 0 - let e = Witness(4); - let expected_optimized_opcode_a = Expression { - mul_terms: vec![], - linear_combinations: vec![ - (FieldElement::one(), a), - (-FieldElement::one(), d), - (FieldElement::one(), e), - ], - q_c: FieldElement::zero(), - }; - assert_eq!(expected_optimized_opcode_a, got_optimized_opcode_a); - - assert_eq!(intermediate_variables.len(), 1); - - // e = - c - b - let expected_intermediate_opcode = Expression { - mul_terms: vec![], - linear_combinations: vec![(-FieldElement::one(), c), (-FieldElement::one(), b)], - q_c: FieldElement::zero(), - }; - let (_, normalized_opcode) = CSatTransformer::normalize(expected_intermediate_opcode); - assert!(intermediate_variables.contains_key(&normalized_opcode)); - assert_eq!(intermediate_variables[&normalized_opcode].1, e); -} +#[cfg(test)] +mod tests { + use super::*; + use acir::{AcirField, FieldElement}; + + #[test] + fn simple_reduction_smoke_test() { + let a = Witness(0); + let b = Witness(1); + let c = Witness(2); + let d = Witness(3); + + // a = b + c + d; + let opcode_a = Expression { + mul_terms: vec![], + linear_combinations: vec![ + (FieldElement::one(), a), + (-FieldElement::one(), b), + (-FieldElement::one(), c), + (-FieldElement::one(), d), + ], + q_c: FieldElement::zero(), + }; + + let mut intermediate_variables: IndexMap< + Expression, + (FieldElement, Witness), + > = IndexMap::new(); + + let mut num_witness = 4; + + let mut optimizer = CSatTransformer::new(3); + optimizer.mark_solvable(b); + optimizer.mark_solvable(c); + optimizer.mark_solvable(d); + let got_optimized_opcode_a = + optimizer.transform(opcode_a, &mut intermediate_variables, &mut num_witness); + + // a = b + c + d => a - b - c - d = 0 + // For width3, the result becomes: + // a - d + e = 0 + // - c - b - e = 0 + // + // a - b + e = 0 + let e = Witness(4); + let expected_optimized_opcode_a = Expression { + mul_terms: vec![], + linear_combinations: vec![ + (FieldElement::one(), a), + (-FieldElement::one(), d), + (FieldElement::one(), e), + ], + q_c: FieldElement::zero(), + }; + assert_eq!(expected_optimized_opcode_a, got_optimized_opcode_a); + + assert_eq!(intermediate_variables.len(), 1); -#[test] -fn stepwise_reduction_test() { - let a = Witness(0); - let b = Witness(1); - let c = Witness(2); - let d = Witness(3); - let e = Witness(4); - - // a = b + c + d + e; - let opcode_a = Expression { - mul_terms: vec![], - linear_combinations: vec![ - (-FieldElement::one(), a), - (FieldElement::one(), b), - (FieldElement::one(), c), - (FieldElement::one(), d), - (FieldElement::one(), e), - ], - q_c: FieldElement::zero(), - }; - - let mut intermediate_variables: IndexMap = IndexMap::new(); - - let mut num_witness = 4; - - let mut optimizer = CSatTransformer::new(3); - optimizer.mark_solvable(a); - optimizer.mark_solvable(c); - optimizer.mark_solvable(d); - optimizer.mark_solvable(e); - let got_optimized_opcode_a = - optimizer.transform(opcode_a, &mut intermediate_variables, &mut num_witness); - - // Since b is not known, it cannot be put inside intermediate opcodes, so it must belong to the transformed opcode. - let contains_b = got_optimized_opcode_a.linear_combinations.iter().any(|(_, w)| *w == b); - assert!(contains_b); + // e = - c - b + let expected_intermediate_opcode = Expression { + mul_terms: vec![], + linear_combinations: vec![(-FieldElement::one(), c), (-FieldElement::one(), b)], + q_c: FieldElement::zero(), + }; + let (_, normalized_opcode) = CSatTransformer::normalize(expected_intermediate_opcode); + assert!(intermediate_variables.contains_key(&normalized_opcode)); + assert_eq!(intermediate_variables[&normalized_opcode].1, e); + } + + #[test] + fn stepwise_reduction_test() { + let a = Witness(0); + let b = Witness(1); + let c = Witness(2); + let d = Witness(3); + let e = Witness(4); + + // a = b + c + d + e; + let opcode_a = Expression { + mul_terms: vec![], + linear_combinations: vec![ + (-FieldElement::one(), a), + (FieldElement::one(), b), + (FieldElement::one(), c), + (FieldElement::one(), d), + (FieldElement::one(), e), + ], + q_c: FieldElement::zero(), + }; + + let mut intermediate_variables: IndexMap< + Expression, + (FieldElement, Witness), + > = IndexMap::new(); + + let mut num_witness = 4; + + let mut optimizer = CSatTransformer::new(3); + optimizer.mark_solvable(a); + optimizer.mark_solvable(c); + optimizer.mark_solvable(d); + optimizer.mark_solvable(e); + let got_optimized_opcode_a = + optimizer.transform(opcode_a, &mut intermediate_variables, &mut num_witness); + + // Since b is not known, it cannot be put inside intermediate opcodes, so it must belong to the transformed opcode. + let contains_b = got_optimized_opcode_a.linear_combinations.iter().any(|(_, w)| *w == b); + assert!(contains_b); + } } diff --git a/acvm-repo/acvm/src/compiler/transformers/mod.rs b/acvm-repo/acvm/src/compiler/transformers/mod.rs index 0099519e4b6..4fd8ba7883f 100644 --- a/acvm-repo/acvm/src/compiler/transformers/mod.rs +++ b/acvm-repo/acvm/src/compiler/transformers/mod.rs @@ -1,7 +1,7 @@ use acir::{ circuit::{brillig::BrilligOutputs, directives::Directive, Circuit, ExpressionWidth, Opcode}, native_types::{Expression, Witness}, - FieldElement, + AcirField, }; use indexmap::IndexMap; @@ -12,10 +12,10 @@ pub(crate) use csat::CSatTransformer; use super::{transform_assert_messages, AcirTransformationMap}; /// Applies [`ProofSystemCompiler`][crate::ProofSystemCompiler] specific optimizations to a [`Circuit`]. -pub fn transform( - acir: Circuit, +pub fn transform( + acir: Circuit, expression_width: ExpressionWidth, -) -> (Circuit, AcirTransformationMap) { +) -> (Circuit, AcirTransformationMap) { // Track original acir opcode positions throughout the transformation passes of the compilation // by applying the modifications done to the circuit opcodes and also to the opcode_positions (delete and insert) let acir_opcode_positions = acir.opcodes.iter().enumerate().map(|(i, _)| i).collect(); @@ -34,11 +34,11 @@ pub fn transform( /// /// Accepts an injected `acir_opcode_positions` to allow transformations to be applied directly after optimizations. #[tracing::instrument(level = "trace", name = "transform_acir", skip(acir, acir_opcode_positions))] -pub(super) fn transform_internal( - acir: Circuit, +pub(super) fn transform_internal( + acir: Circuit, expression_width: ExpressionWidth, acir_opcode_positions: Vec, -) -> (Circuit, Vec) { +) -> (Circuit, Vec) { let mut transformer = match &expression_width { ExpressionWidth::Unbounded => { return (acir, acir_opcode_positions); @@ -64,7 +64,7 @@ pub(super) fn transform_internal( let mut next_witness_index = acir.current_witness_index + 1; // maps a normalized expression to the intermediate variable which represents the expression, along with its 'norm' // the 'norm' is simply the value of the first non zero coefficient in the expression, taken from the linear terms, or quadratic terms if there is none. - let mut intermediate_variables: IndexMap = IndexMap::new(); + let mut intermediate_variables: IndexMap, (F, Witness)> = IndexMap::new(); for (index, opcode) in acir.opcodes.into_iter().enumerate() { match opcode { Opcode::AssertZero(arith_expr) => { @@ -83,7 +83,7 @@ pub(super) fn transform_internal( // de-normalize let mut intermediate_opcode = g * *norm; // constrain the intermediate opcode to the intermediate variable - intermediate_opcode.linear_combinations.push((-FieldElement::one(), *w)); + intermediate_opcode.linear_combinations.push((-F::one(), *w)); intermediate_opcode.sort(); new_opcodes.push(intermediate_opcode); } diff --git a/acvm-repo/acvm/src/lib.rs b/acvm-repo/acvm/src/lib.rs index 00a253fde07..4c64e1da749 100644 --- a/acvm-repo/acvm/src/lib.rs +++ b/acvm-repo/acvm/src/lib.rs @@ -11,7 +11,7 @@ use pwg::OpcodeResolutionError; // re-export acir pub use acir; -pub use acir::FieldElement; +pub use acir::{AcirField, FieldElement}; // re-export brillig vm pub use brillig_vm; // re-export blackbox solver diff --git a/acvm-repo/acvm/src/pwg/arithmetic.rs b/acvm-repo/acvm/src/pwg/arithmetic.rs index b971e4a0efb..5eeabd8a833 100644 --- a/acvm-repo/acvm/src/pwg/arithmetic.rs +++ b/acvm-repo/acvm/src/pwg/arithmetic.rs @@ -1,6 +1,6 @@ use acir::{ native_types::{Expression, Witness, WitnessMap}, - FieldElement, + AcirField, }; use super::{insert_value, ErrorLocation, OpcodeNotSolvable, OpcodeResolutionError}; @@ -10,24 +10,24 @@ use super::{insert_value, ErrorLocation, OpcodeNotSolvable, OpcodeResolutionErro pub(crate) struct ExpressionSolver; #[allow(clippy::enum_variant_names)] -pub(super) enum OpcodeStatus { - OpcodeSatisfied(FieldElement), - OpcodeSolvable(FieldElement, (FieldElement, Witness)), +pub(super) enum OpcodeStatus { + OpcodeSatisfied(F), + OpcodeSolvable(F, (F, Witness)), OpcodeUnsolvable, } -pub(crate) enum MulTerm { - OneUnknown(FieldElement, Witness), // (qM * known_witness, unknown_witness) +pub(crate) enum MulTerm { + OneUnknown(F, Witness), // (qM * known_witness, unknown_witness) TooManyUnknowns, - Solved(FieldElement), + Solved(F), } impl ExpressionSolver { /// Derives the rest of the witness based on the initial low level variables - pub(crate) fn solve( - initial_witness: &mut WitnessMap, - opcode: &Expression, - ) -> Result<(), OpcodeResolutionError> { + pub(crate) fn solve( + initial_witness: &mut WitnessMap, + opcode: &Expression, + ) -> Result<(), OpcodeResolutionError> { let opcode = &ExpressionSolver::evaluate(opcode, initial_witness); // Evaluate multiplication term let mul_result = @@ -133,14 +133,14 @@ impl ExpressionSolver { /// If the witness values are not known, then the function returns a None /// XXX: Do we need to account for the case where 5xy + 6x = 0 ? We do not know y, but it can be solved given x . But I believe x can be solved with another opcode /// XXX: What about making a mul opcode = a constant 5xy + 7 = 0 ? This is the same as the above. - fn solve_mul_term( - arith_opcode: &Expression, - witness_assignments: &WitnessMap, - ) -> Result { + fn solve_mul_term( + arith_opcode: &Expression, + witness_assignments: &WitnessMap, + ) -> Result, OpcodeStatus> { // First note that the mul term can only contain one/zero term // We are assuming it has been optimized. match arith_opcode.mul_terms.len() { - 0 => Ok(MulTerm::Solved(FieldElement::zero())), + 0 => Ok(MulTerm::Solved(F::zero())), 1 => Ok(ExpressionSolver::solve_mul_term_helper( &arith_opcode.mul_terms[0], witness_assignments, @@ -149,10 +149,10 @@ impl ExpressionSolver { } } - fn solve_mul_term_helper( - term: &(FieldElement, Witness, Witness), - witness_assignments: &WitnessMap, - ) -> MulTerm { + fn solve_mul_term_helper( + term: &(F, Witness, Witness), + witness_assignments: &WitnessMap, + ) -> MulTerm { let (q_m, w_l, w_r) = term; // Check if these values are in the witness assignments let w_l_value = witness_assignments.get(w_l); @@ -166,10 +166,10 @@ impl ExpressionSolver { } } - fn solve_fan_in_term_helper( - term: &(FieldElement, Witness), - witness_assignments: &WitnessMap, - ) -> Option { + fn solve_fan_in_term_helper( + term: &(F, Witness), + witness_assignments: &WitnessMap, + ) -> Option { let (q_l, w_l) = term; // Check if we have w_l let w_l_value = witness_assignments.get(w_l); @@ -179,17 +179,17 @@ impl ExpressionSolver { /// Returns the summation of all of the variables, plus the unknown variable /// Returns None, if there is more than one unknown variable /// We cannot assign - pub(super) fn solve_fan_in_term( - arith_opcode: &Expression, - witness_assignments: &WitnessMap, - ) -> OpcodeStatus { + pub(super) fn solve_fan_in_term( + arith_opcode: &Expression, + witness_assignments: &WitnessMap, + ) -> OpcodeStatus { // This is assuming that the fan-in is more than 0 // This is the variable that we want to assign the value to - let mut unknown_variable = (FieldElement::zero(), Witness::default()); + let mut unknown_variable = (F::zero(), Witness::default()); let mut num_unknowns = 0; // This is the sum of all of the known variables - let mut result = FieldElement::zero(); + let mut result = F::zero(); for term in arith_opcode.linear_combinations.iter() { let value = ExpressionSolver::solve_fan_in_term_helper(term, witness_assignments); @@ -215,7 +215,10 @@ impl ExpressionSolver { } // Partially evaluate the opcode using the known witnesses - pub(crate) fn evaluate(expr: &Expression, initial_witness: &WitnessMap) -> Expression { + pub(crate) fn evaluate( + expr: &Expression, + initial_witness: &WitnessMap, + ) -> Expression { let mut result = Expression::default(); for &(c, w1, w2) in &expr.mul_terms { let mul_result = ExpressionSolver::solve_mul_term_helper(&(c, w1, w2), initial_witness); @@ -245,43 +248,49 @@ impl ExpressionSolver { } } -#[test] -fn expression_solver_smoke_test() { - let a = Witness(0); - let b = Witness(1); - let c = Witness(2); - let d = Witness(3); +#[cfg(test)] +mod tests { + use super::*; + use acir::FieldElement; - // a = b + c + d; - let opcode_a = Expression { - mul_terms: vec![], - linear_combinations: vec![ - (FieldElement::one(), a), - (-FieldElement::one(), b), - (-FieldElement::one(), c), - (-FieldElement::one(), d), - ], - q_c: FieldElement::zero(), - }; + #[test] + fn expression_solver_smoke_test() { + let a = Witness(0); + let b = Witness(1); + let c = Witness(2); + let d = Witness(3); - let e = Witness(4); - let opcode_b = Expression { - mul_terms: vec![], - linear_combinations: vec![ - (FieldElement::one(), e), - (-FieldElement::one(), a), - (-FieldElement::one(), b), - ], - q_c: FieldElement::zero(), - }; + // a = b + c + d; + let opcode_a = Expression { + mul_terms: vec![], + linear_combinations: vec![ + (FieldElement::one(), a), + (-FieldElement::one(), b), + (-FieldElement::one(), c), + (-FieldElement::one(), d), + ], + q_c: FieldElement::zero(), + }; - let mut values = WitnessMap::new(); - values.insert(b, FieldElement::from(2_i128)); - values.insert(c, FieldElement::from(1_i128)); - values.insert(d, FieldElement::from(1_i128)); + let e = Witness(4); + let opcode_b = Expression { + mul_terms: vec![], + linear_combinations: vec![ + (FieldElement::one(), e), + (-FieldElement::one(), a), + (-FieldElement::one(), b), + ], + q_c: FieldElement::zero(), + }; - assert_eq!(ExpressionSolver::solve(&mut values, &opcode_a), Ok(())); - assert_eq!(ExpressionSolver::solve(&mut values, &opcode_b), Ok(())); + let mut values = WitnessMap::new(); + values.insert(b, FieldElement::from(2_i128)); + values.insert(c, FieldElement::from(1_i128)); + values.insert(d, FieldElement::from(1_i128)); - assert_eq!(values.get(&a).unwrap(), &FieldElement::from(4_i128)); + assert_eq!(ExpressionSolver::solve(&mut values, &opcode_a), Ok(())); + assert_eq!(ExpressionSolver::solve(&mut values, &opcode_b), Ok(())); + + assert_eq!(values.get(&a).unwrap(), &FieldElement::from(4_i128)); + } } diff --git a/acvm-repo/acvm/src/pwg/blackbox/aes128.rs b/acvm-repo/acvm/src/pwg/blackbox/aes128.rs index c02c59a174f..181a78a2a6a 100644 --- a/acvm-repo/acvm/src/pwg/blackbox/aes128.rs +++ b/acvm-repo/acvm/src/pwg/blackbox/aes128.rs @@ -1,7 +1,7 @@ use acir::{ circuit::opcodes::FunctionInput, native_types::{Witness, WitnessMap}, - FieldElement, + AcirField, }; use acvm_blackbox_solver::aes128_encrypt; @@ -9,13 +9,13 @@ use crate::{pwg::insert_value, OpcodeResolutionError}; use super::utils::{to_u8_array, to_u8_vec}; -pub(super) fn solve_aes128_encryption_opcode( - initial_witness: &mut WitnessMap, +pub(super) fn solve_aes128_encryption_opcode( + initial_witness: &mut WitnessMap, inputs: &[FunctionInput], iv: &[FunctionInput; 16], key: &[FunctionInput; 16], outputs: &[Witness], -) -> Result<(), OpcodeResolutionError> { +) -> Result<(), OpcodeResolutionError> { let scalars = to_u8_vec(initial_witness, inputs)?; let iv = to_u8_array(initial_witness, iv)?; @@ -25,7 +25,7 @@ pub(super) fn solve_aes128_encryption_opcode( // Write witness assignments for (output_witness, value) in outputs.iter().zip(ciphertext.into_iter()) { - insert_value(output_witness, FieldElement::from(value as u128), initial_witness)?; + insert_value(output_witness, F::from(value as u128), initial_witness)?; } Ok(()) diff --git a/acvm-repo/acvm/src/pwg/blackbox/bigint.rs b/acvm-repo/acvm/src/pwg/blackbox/bigint.rs index 3c05fb2761d..be5a4613a55 100644 --- a/acvm-repo/acvm/src/pwg/blackbox/bigint.rs +++ b/acvm-repo/acvm/src/pwg/blackbox/bigint.rs @@ -1,7 +1,7 @@ use acir::{ circuit::opcodes::FunctionInput, native_types::{Witness, WitnessMap}, - BlackBoxFunc, FieldElement, + AcirField, BlackBoxFunc, }; use acvm_blackbox_solver::BigIntSolver; @@ -18,13 +18,13 @@ pub(crate) struct AcvmBigIntSolver { } impl AcvmBigIntSolver { - pub(crate) fn bigint_from_bytes( + pub(crate) fn bigint_from_bytes( &mut self, inputs: &[FunctionInput], modulus: &[u8], output: u32, - initial_witness: &mut WitnessMap, - ) -> Result<(), OpcodeResolutionError> { + initial_witness: &mut WitnessMap, + ) -> Result<(), OpcodeResolutionError> { let bytes = inputs .iter() .map(|input| initial_witness.get(&input.witness).unwrap().to_u128() as u8) @@ -33,29 +33,29 @@ impl AcvmBigIntSolver { Ok(()) } - pub(crate) fn bigint_to_bytes( + pub(crate) fn bigint_to_bytes( &self, input: u32, outputs: &[Witness], - initial_witness: &mut WitnessMap, - ) -> Result<(), OpcodeResolutionError> { + initial_witness: &mut WitnessMap, + ) -> Result<(), OpcodeResolutionError> { let mut bytes = self.bigint_solver.bigint_to_bytes(input)?; while bytes.len() < outputs.len() { bytes.push(0); } bytes.iter().zip(outputs.iter()).for_each(|(byte, output)| { - initial_witness.insert(*output, FieldElement::from(*byte as u128)); + initial_witness.insert(*output, F::from(*byte as u128)); }); Ok(()) } - pub(crate) fn bigint_op( + pub(crate) fn bigint_op( &mut self, lhs: u32, rhs: u32, output: u32, func: BlackBoxFunc, - ) -> Result<(), OpcodeResolutionError> { + ) -> Result<(), OpcodeResolutionError> { self.bigint_solver.bigint_op(lhs, rhs, output, func)?; Ok(()) } diff --git a/acvm-repo/acvm/src/pwg/blackbox/embedded_curve_ops.rs b/acvm-repo/acvm/src/pwg/blackbox/embedded_curve_ops.rs index 0b52ae295a2..411a6d1b737 100644 --- a/acvm-repo/acvm/src/pwg/blackbox/embedded_curve_ops.rs +++ b/acvm-repo/acvm/src/pwg/blackbox/embedded_curve_ops.rs @@ -1,18 +1,19 @@ use acir::{ circuit::opcodes::FunctionInput, native_types::{Witness, WitnessMap}, + AcirField, }; use acvm_blackbox_solver::BlackBoxFunctionSolver; use crate::pwg::{insert_value, witness_to_value, OpcodeResolutionError}; -pub(super) fn multi_scalar_mul( - backend: &impl BlackBoxFunctionSolver, - initial_witness: &mut WitnessMap, +pub(super) fn multi_scalar_mul( + backend: &impl BlackBoxFunctionSolver, + initial_witness: &mut WitnessMap, points: &[FunctionInput], scalars: &[FunctionInput], outputs: (Witness, Witness, Witness), -) -> Result<(), OpcodeResolutionError> { +) -> Result<(), OpcodeResolutionError> { let points: Result, _> = points.iter().map(|input| witness_to_value(initial_witness, input.witness)).collect(); let points: Vec<_> = points?.into_iter().cloned().collect(); @@ -39,13 +40,13 @@ pub(super) fn multi_scalar_mul( Ok(()) } -pub(super) fn embedded_curve_add( - backend: &impl BlackBoxFunctionSolver, - initial_witness: &mut WitnessMap, +pub(super) fn embedded_curve_add( + backend: &impl BlackBoxFunctionSolver, + initial_witness: &mut WitnessMap, input1: [FunctionInput; 3], input2: [FunctionInput; 3], outputs: (Witness, Witness, Witness), -) -> Result<(), OpcodeResolutionError> { +) -> Result<(), OpcodeResolutionError> { let input1_x = witness_to_value(initial_witness, input1[0].witness)?; let input1_y = witness_to_value(initial_witness, input1[1].witness)?; let input1_infinite = witness_to_value(initial_witness, input1[2].witness)?; diff --git a/acvm-repo/acvm/src/pwg/blackbox/hash.rs b/acvm-repo/acvm/src/pwg/blackbox/hash.rs index caa09ea8973..fe9bd46b091 100644 --- a/acvm-repo/acvm/src/pwg/blackbox/hash.rs +++ b/acvm-repo/acvm/src/pwg/blackbox/hash.rs @@ -1,7 +1,7 @@ use acir::{ circuit::opcodes::FunctionInput, native_types::{Witness, WitnessMap}, - FieldElement, + AcirField, }; use acvm_blackbox_solver::{sha256compression, BlackBoxFunctionSolver, BlackBoxResolutionError}; @@ -10,13 +10,13 @@ use crate::OpcodeResolutionError; /// Attempts to solve a 256 bit hash function opcode. /// If successful, `initial_witness` will be mutated to contain the new witness assignment. -pub(super) fn solve_generic_256_hash_opcode( - initial_witness: &mut WitnessMap, +pub(super) fn solve_generic_256_hash_opcode( + initial_witness: &mut WitnessMap, inputs: &[FunctionInput], var_message_size: Option<&FunctionInput>, outputs: &[Witness; 32], hash_function: fn(data: &[u8]) -> Result<[u8; 32], BlackBoxResolutionError>, -) -> Result<(), OpcodeResolutionError> { +) -> Result<(), OpcodeResolutionError> { let message_input = get_hash_input(initial_witness, inputs, var_message_size)?; let digest: [u8; 32] = hash_function(&message_input)?; @@ -24,11 +24,11 @@ pub(super) fn solve_generic_256_hash_opcode( } /// Reads the hash function input from a [`WitnessMap`]. -fn get_hash_input( - initial_witness: &WitnessMap, +fn get_hash_input( + initial_witness: &WitnessMap, inputs: &[FunctionInput], message_size: Option<&FunctionInput>, -) -> Result, OpcodeResolutionError> { +) -> Result, OpcodeResolutionError> { // Read witness assignments. let mut message_input = Vec::new(); for input in inputs.iter() { @@ -62,26 +62,22 @@ fn get_hash_input( } /// Writes a `digest` to the [`WitnessMap`] at witness indices `outputs`. -fn write_digest_to_outputs( - initial_witness: &mut WitnessMap, +fn write_digest_to_outputs( + initial_witness: &mut WitnessMap, outputs: &[Witness; 32], digest: [u8; 32], -) -> Result<(), OpcodeResolutionError> { +) -> Result<(), OpcodeResolutionError> { for (output_witness, value) in outputs.iter().zip(digest.into_iter()) { - insert_value( - output_witness, - FieldElement::from_be_bytes_reduce(&[value]), - initial_witness, - )?; + insert_value(output_witness, F::from_be_bytes_reduce(&[value]), initial_witness)?; } Ok(()) } -fn to_u32_array( - initial_witness: &WitnessMap, +fn to_u32_array( + initial_witness: &WitnessMap, inputs: &[FunctionInput; N], -) -> Result<[u32; N], OpcodeResolutionError> { +) -> Result<[u32; N], OpcodeResolutionError> { let mut result = [0; N]; for (it, input) in result.iter_mut().zip(inputs) { let witness_value = witness_to_value(initial_witness, input.witness)?; @@ -90,31 +86,31 @@ fn to_u32_array( Ok(result) } -pub(crate) fn solve_sha_256_permutation_opcode( - initial_witness: &mut WitnessMap, +pub(crate) fn solve_sha_256_permutation_opcode( + initial_witness: &mut WitnessMap, inputs: &[FunctionInput; 16], hash_values: &[FunctionInput; 8], outputs: &[Witness; 8], -) -> Result<(), OpcodeResolutionError> { +) -> Result<(), OpcodeResolutionError> { let message = to_u32_array(initial_witness, inputs)?; let mut state = to_u32_array(initial_witness, hash_values)?; sha256compression(&mut state, &message); for (output_witness, value) in outputs.iter().zip(state.into_iter()) { - insert_value(output_witness, FieldElement::from(value as u128), initial_witness)?; + insert_value(output_witness, F::from(value as u128), initial_witness)?; } Ok(()) } -pub(crate) fn solve_poseidon2_permutation_opcode( - backend: &impl BlackBoxFunctionSolver, - initial_witness: &mut WitnessMap, +pub(crate) fn solve_poseidon2_permutation_opcode( + backend: &impl BlackBoxFunctionSolver, + initial_witness: &mut WitnessMap, inputs: &[FunctionInput], outputs: &[Witness], len: u32, -) -> Result<(), OpcodeResolutionError> { +) -> Result<(), OpcodeResolutionError> { if len as usize != inputs.len() { return Err(OpcodeResolutionError::BlackBoxFunctionFailed( acir::BlackBoxFunc::Poseidon2Permutation, diff --git a/acvm-repo/acvm/src/pwg/blackbox/logic.rs b/acvm-repo/acvm/src/pwg/blackbox/logic.rs index 8e69730f71d..6e2ade3c49b 100644 --- a/acvm-repo/acvm/src/pwg/blackbox/logic.rs +++ b/acvm-repo/acvm/src/pwg/blackbox/logic.rs @@ -3,17 +3,17 @@ use crate::OpcodeResolutionError; use acir::{ circuit::opcodes::FunctionInput, native_types::{Witness, WitnessMap}, - FieldElement, + AcirField, }; /// Solves a [`BlackBoxFunc::And`][acir::circuit::black_box_functions::BlackBoxFunc::AND] opcode and inserts /// the result into the supplied witness map -pub(super) fn and( - initial_witness: &mut WitnessMap, +pub(super) fn and( + initial_witness: &mut WitnessMap, lhs: &FunctionInput, rhs: &FunctionInput, output: &Witness, -) -> Result<(), OpcodeResolutionError> { +) -> Result<(), OpcodeResolutionError> { assert_eq!( lhs.num_bits, rhs.num_bits, "number of bits specified for each input must be the same" @@ -25,12 +25,12 @@ pub(super) fn and( /// Solves a [`BlackBoxFunc::XOR`][acir::circuit::black_box_functions::BlackBoxFunc::XOR] opcode and inserts /// the result into the supplied witness map -pub(super) fn xor( - initial_witness: &mut WitnessMap, +pub(super) fn xor( + initial_witness: &mut WitnessMap, lhs: &FunctionInput, rhs: &FunctionInput, output: &Witness, -) -> Result<(), OpcodeResolutionError> { +) -> Result<(), OpcodeResolutionError> { assert_eq!( lhs.num_bits, rhs.num_bits, "number of bits specified for each input must be the same" @@ -41,13 +41,13 @@ pub(super) fn xor( } /// Derives the rest of the witness based on the initial low level variables -fn solve_logic_opcode( - initial_witness: &mut WitnessMap, +fn solve_logic_opcode( + initial_witness: &mut WitnessMap, a: &Witness, b: &Witness, result: Witness, - logic_op: impl Fn(&FieldElement, &FieldElement) -> FieldElement, -) -> Result<(), OpcodeResolutionError> { + logic_op: impl Fn(&F, &F) -> F, +) -> Result<(), OpcodeResolutionError> { let w_l_value = witness_to_value(initial_witness, *a)?; let w_r_value = witness_to_value(initial_witness, *b)?; let assignment = logic_op(w_l_value, w_r_value); diff --git a/acvm-repo/acvm/src/pwg/blackbox/mod.rs b/acvm-repo/acvm/src/pwg/blackbox/mod.rs index 99ed09a52e4..8bda9221d8a 100644 --- a/acvm-repo/acvm/src/pwg/blackbox/mod.rs +++ b/acvm-repo/acvm/src/pwg/blackbox/mod.rs @@ -1,7 +1,7 @@ use acir::{ circuit::opcodes::{BlackBoxFuncCall, FunctionInput}, native_types::{Witness, WitnessMap}, - FieldElement, + AcirField, }; use acvm_blackbox_solver::{blake2s, blake3, keccak256, keccakf1600, sha256}; @@ -37,8 +37,8 @@ use signature::{ /// Check if all of the inputs to the function have assignments /// /// Returns the first missing assignment if any are missing -fn first_missing_assignment( - witness_assignments: &WitnessMap, +fn first_missing_assignment( + witness_assignments: &WitnessMap, inputs: &[FunctionInput], ) -> Option { inputs.iter().find_map(|input| { @@ -51,16 +51,16 @@ fn first_missing_assignment( } /// Check if all of the inputs to the function have assignments -fn contains_all_inputs(witness_assignments: &WitnessMap, inputs: &[FunctionInput]) -> bool { +fn contains_all_inputs(witness_assignments: &WitnessMap, inputs: &[FunctionInput]) -> bool { inputs.iter().all(|input| witness_assignments.contains_key(&input.witness)) } -pub(crate) fn solve( - backend: &impl BlackBoxFunctionSolver, - initial_witness: &mut WitnessMap, +pub(crate) fn solve( + backend: &impl BlackBoxFunctionSolver, + initial_witness: &mut WitnessMap, bb_func: &BlackBoxFuncCall, bigint_solver: &mut AcvmBigIntSolver, -) -> Result<(), OpcodeResolutionError> { +) -> Result<(), OpcodeResolutionError> { let inputs = bb_func.get_inputs_vec(); if !contains_all_inputs(initial_witness, &inputs) { let unassigned_witness = first_missing_assignment(initial_witness, &inputs) @@ -108,7 +108,7 @@ pub(crate) fn solve( } let output_state = keccakf1600(state)?; for (output_witness, value) in outputs.iter().zip(output_state.into_iter()) { - insert_value(output_witness, FieldElement::from(value as u128), initial_witness)?; + insert_value(output_witness, F::from(value as u128), initial_witness)?; } Ok(()) } diff --git a/acvm-repo/acvm/src/pwg/blackbox/pedersen.rs b/acvm-repo/acvm/src/pwg/blackbox/pedersen.rs index bb214c1ceaf..f64a3a79465 100644 --- a/acvm-repo/acvm/src/pwg/blackbox/pedersen.rs +++ b/acvm-repo/acvm/src/pwg/blackbox/pedersen.rs @@ -1,6 +1,7 @@ use acir::{ circuit::opcodes::FunctionInput, native_types::{Witness, WitnessMap}, + AcirField, }; use crate::{ @@ -8,13 +9,13 @@ use crate::{ BlackBoxFunctionSolver, }; -pub(super) fn pedersen( - backend: &impl BlackBoxFunctionSolver, - initial_witness: &mut WitnessMap, +pub(super) fn pedersen( + backend: &impl BlackBoxFunctionSolver, + initial_witness: &mut WitnessMap, inputs: &[FunctionInput], domain_separator: u32, outputs: (Witness, Witness), -) -> Result<(), OpcodeResolutionError> { +) -> Result<(), OpcodeResolutionError> { let scalars: Result, _> = inputs.iter().map(|input| witness_to_value(initial_witness, input.witness)).collect(); let scalars: Vec<_> = scalars?.into_iter().cloned().collect(); @@ -27,13 +28,13 @@ pub(super) fn pedersen( Ok(()) } -pub(super) fn pedersen_hash( - backend: &impl BlackBoxFunctionSolver, - initial_witness: &mut WitnessMap, +pub(super) fn pedersen_hash( + backend: &impl BlackBoxFunctionSolver, + initial_witness: &mut WitnessMap, inputs: &[FunctionInput], domain_separator: u32, output: Witness, -) -> Result<(), OpcodeResolutionError> { +) -> Result<(), OpcodeResolutionError> { let scalars: Result, _> = inputs.iter().map(|input| witness_to_value(initial_witness, input.witness)).collect(); let scalars: Vec<_> = scalars?.into_iter().cloned().collect(); diff --git a/acvm-repo/acvm/src/pwg/blackbox/range.rs b/acvm-repo/acvm/src/pwg/blackbox/range.rs index aac50b32fc8..0ca001aff7a 100644 --- a/acvm-repo/acvm/src/pwg/blackbox/range.rs +++ b/acvm-repo/acvm/src/pwg/blackbox/range.rs @@ -2,12 +2,12 @@ use crate::{ pwg::{witness_to_value, ErrorLocation}, OpcodeResolutionError, }; -use acir::{circuit::opcodes::FunctionInput, native_types::WitnessMap}; +use acir::{circuit::opcodes::FunctionInput, native_types::WitnessMap, AcirField}; -pub(crate) fn solve_range_opcode( - initial_witness: &WitnessMap, +pub(crate) fn solve_range_opcode( + initial_witness: &WitnessMap, input: &FunctionInput, -) -> Result<(), OpcodeResolutionError> { +) -> Result<(), OpcodeResolutionError> { let w_value = witness_to_value(initial_witness, input.witness)?; if w_value.num_bits() > input.num_bits { return Err(OpcodeResolutionError::UnsatisfiedConstrain { diff --git a/acvm-repo/acvm/src/pwg/blackbox/signature/ecdsa.rs b/acvm-repo/acvm/src/pwg/blackbox/signature/ecdsa.rs index ce2e57e0bd7..707e3f26af0 100644 --- a/acvm-repo/acvm/src/pwg/blackbox/signature/ecdsa.rs +++ b/acvm-repo/acvm/src/pwg/blackbox/signature/ecdsa.rs @@ -1,7 +1,7 @@ use acir::{ circuit::opcodes::FunctionInput, native_types::{Witness, WitnessMap}, - FieldElement, + AcirField, }; use acvm_blackbox_solver::{ecdsa_secp256k1_verify, ecdsa_secp256r1_verify}; @@ -13,14 +13,14 @@ use crate::{ OpcodeResolutionError, }; -pub(crate) fn secp256k1_prehashed( - initial_witness: &mut WitnessMap, +pub(crate) fn secp256k1_prehashed( + initial_witness: &mut WitnessMap, public_key_x_inputs: &[FunctionInput; 32], public_key_y_inputs: &[FunctionInput; 32], signature_inputs: &[FunctionInput; 64], hashed_message_inputs: &[FunctionInput], output: Witness, -) -> Result<(), OpcodeResolutionError> { +) -> Result<(), OpcodeResolutionError> { let hashed_message = to_u8_vec(initial_witness, hashed_message_inputs)?; let pub_key_x: [u8; 32] = to_u8_array(initial_witness, public_key_x_inputs)?; @@ -29,17 +29,17 @@ pub(crate) fn secp256k1_prehashed( let is_valid = ecdsa_secp256k1_verify(&hashed_message, &pub_key_x, &pub_key_y, &signature)?; - insert_value(&output, FieldElement::from(is_valid), initial_witness) + insert_value(&output, F::from(is_valid), initial_witness) } -pub(crate) fn secp256r1_prehashed( - initial_witness: &mut WitnessMap, +pub(crate) fn secp256r1_prehashed( + initial_witness: &mut WitnessMap, public_key_x_inputs: &[FunctionInput; 32], public_key_y_inputs: &[FunctionInput; 32], signature_inputs: &[FunctionInput; 64], hashed_message_inputs: &[FunctionInput], output: Witness, -) -> Result<(), OpcodeResolutionError> { +) -> Result<(), OpcodeResolutionError> { let hashed_message = to_u8_vec(initial_witness, hashed_message_inputs)?; let pub_key_x: [u8; 32] = to_u8_array(initial_witness, public_key_x_inputs)?; @@ -48,5 +48,5 @@ pub(crate) fn secp256r1_prehashed( let is_valid = ecdsa_secp256r1_verify(&hashed_message, &pub_key_x, &pub_key_y, &signature)?; - insert_value(&output, FieldElement::from(is_valid), initial_witness) + insert_value(&output, F::from(is_valid), initial_witness) } diff --git a/acvm-repo/acvm/src/pwg/blackbox/signature/schnorr.rs b/acvm-repo/acvm/src/pwg/blackbox/signature/schnorr.rs index 7b085d9ff47..5e0ac94f8be 100644 --- a/acvm-repo/acvm/src/pwg/blackbox/signature/schnorr.rs +++ b/acvm-repo/acvm/src/pwg/blackbox/signature/schnorr.rs @@ -8,21 +8,21 @@ use crate::{ use acir::{ circuit::opcodes::FunctionInput, native_types::{Witness, WitnessMap}, - FieldElement, + AcirField, }; #[allow(clippy::too_many_arguments)] -pub(crate) fn schnorr_verify( - backend: &impl BlackBoxFunctionSolver, - initial_witness: &mut WitnessMap, +pub(crate) fn schnorr_verify( + backend: &impl BlackBoxFunctionSolver, + initial_witness: &mut WitnessMap, public_key_x: FunctionInput, public_key_y: FunctionInput, signature: &[FunctionInput; 64], message: &[FunctionInput], output: Witness, -) -> Result<(), OpcodeResolutionError> { - let public_key_x: &FieldElement = witness_to_value(initial_witness, public_key_x.witness)?; - let public_key_y: &FieldElement = witness_to_value(initial_witness, public_key_y.witness)?; +) -> Result<(), OpcodeResolutionError> { + let public_key_x: &F = witness_to_value(initial_witness, public_key_x.witness)?; + let public_key_y: &F = witness_to_value(initial_witness, public_key_y.witness)?; let signature = to_u8_array(initial_witness, signature)?; let message = to_u8_vec(initial_witness, message)?; @@ -30,7 +30,7 @@ pub(crate) fn schnorr_verify( let valid_signature = backend.schnorr_verify(public_key_x, public_key_y, &signature, &message)?; - insert_value(&output, FieldElement::from(valid_signature), initial_witness)?; + insert_value(&output, F::from(valid_signature), initial_witness)?; Ok(()) } diff --git a/acvm-repo/acvm/src/pwg/blackbox/utils.rs b/acvm-repo/acvm/src/pwg/blackbox/utils.rs index 700f30890ae..6880d21a324 100644 --- a/acvm-repo/acvm/src/pwg/blackbox/utils.rs +++ b/acvm-repo/acvm/src/pwg/blackbox/utils.rs @@ -1,11 +1,11 @@ -use acir::{circuit::opcodes::FunctionInput, native_types::WitnessMap}; +use acir::{circuit::opcodes::FunctionInput, native_types::WitnessMap, AcirField}; use crate::pwg::{witness_to_value, OpcodeResolutionError}; -pub(crate) fn to_u8_array( - initial_witness: &WitnessMap, +pub(crate) fn to_u8_array( + initial_witness: &WitnessMap, inputs: &[FunctionInput; N], -) -> Result<[u8; N], OpcodeResolutionError> { +) -> Result<[u8; N], OpcodeResolutionError> { let mut result = [0; N]; for (it, input) in result.iter_mut().zip(inputs) { let witness_value_bytes = witness_to_value(initial_witness, input.witness)?.to_be_bytes(); @@ -17,10 +17,10 @@ pub(crate) fn to_u8_array( Ok(result) } -pub(crate) fn to_u8_vec( - initial_witness: &WitnessMap, +pub(crate) fn to_u8_vec( + initial_witness: &WitnessMap, inputs: &[FunctionInput], -) -> Result, OpcodeResolutionError> { +) -> Result, OpcodeResolutionError> { let mut result = Vec::with_capacity(inputs.len()); for input in inputs { let witness_value_bytes = witness_to_value(initial_witness, input.witness)?.to_be_bytes(); diff --git a/acvm-repo/acvm/src/pwg/brillig.rs b/acvm-repo/acvm/src/pwg/brillig.rs index c911202c823..7e6c207b69a 100644 --- a/acvm-repo/acvm/src/pwg/brillig.rs +++ b/acvm-repo/acvm/src/pwg/brillig.rs @@ -9,7 +9,7 @@ use acir::{ STRING_ERROR_SELECTOR, }, native_types::WitnessMap, - FieldElement, + AcirField, }; use acvm_blackbox_solver::BlackBoxFunctionSolver; use brillig_vm::{FailureReason, MemoryValue, VMStatus, VM}; @@ -19,31 +19,31 @@ use crate::{pwg::OpcodeNotSolvable, OpcodeResolutionError}; use super::{get_value, insert_value, memory_op::MemoryOpSolver}; #[derive(Debug)] -pub enum BrilligSolverStatus { +pub enum BrilligSolverStatus { Finished, InProgress, - ForeignCallWait(ForeignCallWaitInfo), + ForeignCallWait(ForeignCallWaitInfo), } -pub struct BrilligSolver<'b, B: BlackBoxFunctionSolver> { - vm: VM<'b, B>, +pub struct BrilligSolver<'b, F, B: BlackBoxFunctionSolver> { + vm: VM<'b, F, B>, acir_index: usize, } -impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { +impl<'b, B: BlackBoxFunctionSolver, F: AcirField> BrilligSolver<'b, F, B> { /// Assigns the zero value to all outputs of the given [`Brillig`] bytecode. pub(super) fn zero_out_brillig_outputs( - initial_witness: &mut WitnessMap, + initial_witness: &mut WitnessMap, outputs: &[BrilligOutputs], - ) -> Result<(), OpcodeResolutionError> { + ) -> Result<(), OpcodeResolutionError> { for output in outputs { match output { BrilligOutputs::Simple(witness) => { - insert_value(witness, FieldElement::zero(), initial_witness)?; + insert_value(witness, F::zero(), initial_witness)?; } BrilligOutputs::Array(witness_arr) => { for witness in witness_arr { - insert_value(witness, FieldElement::zero(), initial_witness)?; + insert_value(witness, F::zero(), initial_witness)?; } } } @@ -54,27 +54,27 @@ impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { /// Constructs a solver for a Brillig block given the bytecode and initial /// witness. pub(crate) fn new_call( - initial_witness: &WitnessMap, - memory: &HashMap, - inputs: &'b [BrilligInputs], - brillig_bytecode: &'b [BrilligOpcode], + initial_witness: &WitnessMap, + memory: &HashMap>, + inputs: &'b [BrilligInputs], + brillig_bytecode: &'b [BrilligOpcode], bb_solver: &'b B, acir_index: usize, - ) -> Result { + ) -> Result> { let vm = Self::setup_brillig_vm(initial_witness, memory, inputs, brillig_bytecode, bb_solver)?; Ok(Self { vm, acir_index }) } fn setup_brillig_vm( - initial_witness: &WitnessMap, - memory: &HashMap, - inputs: &[BrilligInputs], - brillig_bytecode: &'b [BrilligOpcode], + initial_witness: &WitnessMap, + memory: &HashMap>, + inputs: &[BrilligInputs], + brillig_bytecode: &'b [BrilligOpcode], bb_solver: &'b B, - ) -> Result, OpcodeResolutionError> { + ) -> Result, OpcodeResolutionError> { // Set input values - let mut calldata: Vec = Vec::new(); + let mut calldata: Vec = Vec::new(); // Each input represents an expression or array of expressions to evaluate. // Iterate over each input and evaluate the expression(s) associated with it. // Push the results into memory. @@ -123,11 +123,11 @@ impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { Ok(vm) } - pub fn get_memory(&self) -> &[MemoryValue] { + pub fn get_memory(&self) -> &[MemoryValue] { self.vm.get_memory() } - pub fn write_memory_at(&mut self, ptr: usize, value: MemoryValue) { + pub fn write_memory_at(&mut self, ptr: usize, value: MemoryValue) { self.vm.write_memory_at(ptr, value); } @@ -135,12 +135,12 @@ impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { self.vm.get_call_stack() } - pub(crate) fn solve(&mut self) -> Result { + pub(crate) fn solve(&mut self) -> Result, OpcodeResolutionError> { let status = self.vm.process_opcodes(); self.handle_vm_status(status) } - pub fn step(&mut self) -> Result { + pub fn step(&mut self) -> Result, OpcodeResolutionError> { let status = self.vm.process_opcode(); self.handle_vm_status(status) } @@ -151,8 +151,8 @@ impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { fn handle_vm_status( &self, - vm_status: VMStatus, - ) -> Result { + vm_status: VMStatus, + ) -> Result, OpcodeResolutionError> { // Check the status of the Brillig VM and return a resolution. // It may be finished, in-progress, failed, or may be waiting for results of a foreign call. // Return the "resolution" to the caller who may choose to make subsequent calls @@ -227,9 +227,9 @@ impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { pub(crate) fn finalize( self, - witness: &mut WitnessMap, + witness: &mut WitnessMap, outputs: &[BrilligOutputs], - ) -> Result<(), OpcodeResolutionError> { + ) -> Result<(), OpcodeResolutionError> { // Finish the Brillig execution by writing the outputs to the witness map let vm_status = self.vm.get_status(); match vm_status { @@ -243,11 +243,11 @@ impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { fn write_brillig_outputs( &self, - witness_map: &mut WitnessMap, + witness_map: &mut WitnessMap, return_data_offset: usize, return_data_size: usize, outputs: &[BrilligOutputs], - ) -> Result<(), OpcodeResolutionError> { + ) -> Result<(), OpcodeResolutionError> { // Write VM execution results into the witness map let memory = self.vm.get_memory(); let mut current_ret_data_idx = return_data_offset; @@ -274,7 +274,7 @@ impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { Ok(()) } - pub fn resolve_pending_foreign_call(&mut self, foreign_call_result: ForeignCallResult) { + pub fn resolve_pending_foreign_call(&mut self, foreign_call_result: ForeignCallResult) { match self.vm.get_status() { VMStatus::ForeignCallWait { .. } => self.vm.resolve_foreign_call(foreign_call_result), _ => unreachable!("Brillig VM is not waiting for a foreign call"), @@ -287,9 +287,9 @@ impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { /// /// The caller must resolve this opcode externally based upon the information in the request. #[derive(Debug, PartialEq, Clone)] -pub struct ForeignCallWaitInfo { +pub struct ForeignCallWaitInfo { /// An identifier interpreted by the caller process pub function: String, /// Resolved inputs to a foreign call computed in the previous steps of a Brillig VM process - pub inputs: Vec, + pub inputs: Vec>, } diff --git a/acvm-repo/acvm/src/pwg/directives/mod.rs b/acvm-repo/acvm/src/pwg/directives/mod.rs index db79379a374..d7bee88c278 100644 --- a/acvm-repo/acvm/src/pwg/directives/mod.rs +++ b/acvm-repo/acvm/src/pwg/directives/mod.rs @@ -1,4 +1,4 @@ -use acir::{circuit::directives::Directive, native_types::WitnessMap, FieldElement}; +use acir::{circuit::directives::Directive, native_types::WitnessMap, AcirField}; use num_bigint::BigUint; use crate::OpcodeResolutionError; @@ -11,10 +11,10 @@ use super::{get_value, insert_value, ErrorLocation}; /// Returns `Ok(OpcodeResolution)` to signal whether the directive was successful solved. /// /// Returns `Err(OpcodeResolutionError)` if a circuit constraint is unsatisfied. -pub(crate) fn solve_directives( - initial_witness: &mut WitnessMap, - directive: &Directive, -) -> Result<(), OpcodeResolutionError> { +pub(crate) fn solve_directives( + initial_witness: &mut WitnessMap, + directive: &Directive, +) -> Result<(), OpcodeResolutionError> { match directive { Directive::ToLeRadix { a, b, radix } => { let value_a = get_value(a, initial_witness)?; @@ -36,8 +36,8 @@ pub(crate) fn solve_directives( // If it is not available, which can happen when the decomposed integer // list is shorter than the witness list, we return 0. let value = match decomposed_integer.get(i) { - Some(digit) => FieldElement::from_be_bytes_reduce(&[*digit]), - None => FieldElement::zero(), + Some(digit) => F::from_be_bytes_reduce(&[*digit]), + None => F::zero(), }; insert_value(witness, value, initial_witness)?; diff --git a/acvm-repo/acvm/src/pwg/memory_op.rs b/acvm-repo/acvm/src/pwg/memory_op.rs index 672c13e11c2..a9ed7f5d15b 100644 --- a/acvm-repo/acvm/src/pwg/memory_op.rs +++ b/acvm-repo/acvm/src/pwg/memory_op.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use acir::{ circuit::opcodes::MemOp, native_types::{Expression, Witness, WitnessMap}, - FieldElement, + AcirField, }; use super::{ @@ -15,17 +15,17 @@ type MemoryIndex = u32; /// Maintains the state for solving [`MemoryInit`][`acir::circuit::Opcode::MemoryInit`] and [`MemoryOp`][`acir::circuit::Opcode::MemoryOp`] opcodes. #[derive(Default)] -pub(crate) struct MemoryOpSolver { - pub(super) block_value: HashMap, +pub(crate) struct MemoryOpSolver { + pub(super) block_value: HashMap, pub(super) block_len: u32, } -impl MemoryOpSolver { +impl MemoryOpSolver { fn write_memory_index( &mut self, index: MemoryIndex, - value: FieldElement, - ) -> Result<(), OpcodeResolutionError> { + value: F, + ) -> Result<(), OpcodeResolutionError> { if index >= self.block_len { return Err(OpcodeResolutionError::IndexOutOfBounds { opcode_location: ErrorLocation::Unresolved, @@ -37,7 +37,7 @@ impl MemoryOpSolver { Ok(()) } - fn read_memory_index(&self, index: MemoryIndex) -> Result { + fn read_memory_index(&self, index: MemoryIndex) -> Result> { self.block_value.get(&index).copied().ok_or(OpcodeResolutionError::IndexOutOfBounds { opcode_location: ErrorLocation::Unresolved, index, @@ -49,8 +49,8 @@ impl MemoryOpSolver { pub(crate) fn init( &mut self, init: &[Witness], - initial_witness: &WitnessMap, - ) -> Result<(), OpcodeResolutionError> { + initial_witness: &WitnessMap, + ) -> Result<(), OpcodeResolutionError> { self.block_len = init.len() as u32; for (memory_index, witness) in init.iter().enumerate() { self.write_memory_index( @@ -63,10 +63,10 @@ impl MemoryOpSolver { pub(crate) fn solve_memory_op( &mut self, - op: &MemOp, - initial_witness: &mut WitnessMap, - predicate: &Option, - ) -> Result<(), OpcodeResolutionError> { + op: &MemOp, + initial_witness: &mut WitnessMap, + predicate: &Option>, + ) -> Result<(), OpcodeResolutionError> { let operation = get_value(&op.operation, initial_witness)?; // Find the memory index associated with this memory operation. @@ -96,11 +96,8 @@ impl MemoryOpSolver { // A zero predicate indicates that we should skip the read operation // and zero out the operation's output. - let value_in_array = if skip_operation { - FieldElement::zero() - } else { - self.read_memory_index(memory_index)? - }; + let value_in_array = + if skip_operation { F::zero() } else { self.read_memory_index(memory_index)? }; insert_value(&value_read_witness, value_in_array, initial_witness) } else { // `arr[memory_index] = value_write` @@ -129,7 +126,7 @@ mod tests { use acir::{ circuit::opcodes::MemOp, native_types::{Expression, Witness, WitnessMap}, - FieldElement, + AcirField, FieldElement, }; use super::MemoryOpSolver; diff --git a/acvm-repo/acvm/src/pwg/mod.rs b/acvm-repo/acvm/src/pwg/mod.rs index f2649b93991..da4510db63a 100644 --- a/acvm-repo/acvm/src/pwg/mod.rs +++ b/acvm-repo/acvm/src/pwg/mod.rs @@ -10,7 +10,7 @@ use acir::{ STRING_ERROR_SELECTOR, }, native_types::{Expression, Witness, WitnessMap}, - BlackBoxFunc, FieldElement, + AcirField, BlackBoxFunc, }; use acvm_blackbox_solver::BlackBoxResolutionError; @@ -36,7 +36,7 @@ pub use self::brillig::{BrilligSolver, BrilligSolverStatus}; pub use brillig::ForeignCallWaitInfo; #[derive(Debug, Clone, PartialEq)] -pub enum ACVMStatus { +pub enum ACVMStatus { /// All opcodes have been solved. Solved, @@ -45,23 +45,23 @@ pub enum ACVMStatus { /// The ACVM has encountered an irrecoverable error while executing the circuit and can not progress. /// Most commonly this will be due to an unsatisfied constraint due to invalid inputs to the circuit. - Failure(OpcodeResolutionError), + Failure(OpcodeResolutionError), /// The ACVM has encountered a request for a Brillig [foreign call][acir::brillig_vm::Opcode::ForeignCall] /// to retrieve information from outside of the ACVM. The result of the foreign call must be passed back /// to the ACVM using [`ACVM::resolve_pending_foreign_call`]. /// /// Once this is done, the ACVM can be restarted to solve the remaining opcodes. - RequiresForeignCall(ForeignCallWaitInfo), + RequiresForeignCall(ForeignCallWaitInfo), /// The ACVM has encountered a request for an ACIR [call][acir::circuit::Opcode] /// to execute a separate ACVM instance. The result of the ACIR call must be passd back to the ACVM. /// /// Once this is done, the ACVM can be restarted to solve the remaining opcodes. - RequiresAcirCall(AcirCallWaitInfo), + RequiresAcirCall(AcirCallWaitInfo), } -impl std::fmt::Display for ACVMStatus { +impl std::fmt::Display for ACVMStatus { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { ACVMStatus::Solved => write!(f, "Solved"), @@ -73,9 +73,9 @@ impl std::fmt::Display for ACVMStatus { } } -pub enum StepResult<'a, B: BlackBoxFunctionSolver> { - Status(ACVMStatus), - IntoBrillig(BrilligSolver<'a, B>), +pub enum StepResult<'a, F, B: BlackBoxFunctionSolver> { + Status(ACVMStatus), + IntoBrillig(BrilligSolver<'a, F, B>), } // This enum represents the different cases in which an @@ -87,13 +87,13 @@ pub enum StepResult<'a, B: BlackBoxFunctionSolver> { // TODO: we could have a error enum for expression solver failure cases in that module // TODO that can be converted into an OpcodeNotSolvable or OpcodeResolutionError enum #[derive(Clone, PartialEq, Eq, Debug, Error)] -pub enum OpcodeNotSolvable { +pub enum OpcodeNotSolvable { #[error("missing assignment for witness index {0}")] MissingAssignment(u32), #[error("Attempted to load uninitialized memory block")] MissingMemoryBlock(u32), #[error("expression has too many unknowns {0}")] - ExpressionHasTooManyUnknowns(Expression), + ExpressionHasTooManyUnknowns(Expression), } /// Allows to point to a specific opcode as cause in errors. @@ -117,13 +117,13 @@ impl std::fmt::Display for ErrorLocation { } #[derive(Clone, PartialEq, Eq, Debug, Error)] -pub enum OpcodeResolutionError { +pub enum OpcodeResolutionError { #[error("Cannot solve opcode: {0}")] - OpcodeNotSolvable(#[from] OpcodeNotSolvable), + OpcodeNotSolvable(#[from] OpcodeNotSolvable), #[error("Cannot satisfy constraint")] UnsatisfiedConstrain { opcode_location: ErrorLocation, - payload: Option, + payload: Option>, }, #[error("Index out of bounds, array has size {array_size:?}, but index was {index:?}")] IndexOutOfBounds { opcode_location: ErrorLocation, index: u32, array_size: u32 }, @@ -132,7 +132,7 @@ pub enum OpcodeResolutionError { #[error("Failed to solve brillig function")] BrilligFunctionFailed { call_stack: Vec, - payload: Option, + payload: Option>, }, #[error("Attempted to call `main` with a `Call` opcode")] AcirMainCallAttempted { opcode_location: ErrorLocation }, @@ -140,7 +140,7 @@ pub enum OpcodeResolutionError { AcirCallOutputsMismatch { opcode_location: ErrorLocation, results_size: u32, outputs_size: u32 }, } -impl From for OpcodeResolutionError { +impl From for OpcodeResolutionError { fn from(value: BlackBoxResolutionError) -> Self { match value { BlackBoxResolutionError::Failed(func, reason) => { @@ -150,45 +150,45 @@ impl From for OpcodeResolutionError { } } -pub struct ACVM<'a, B: BlackBoxFunctionSolver> { - status: ACVMStatus, +pub struct ACVM<'a, F, B: BlackBoxFunctionSolver> { + status: ACVMStatus, backend: &'a B, /// Stores the solver for memory operations acting on blocks of memory disambiguated by [block][`BlockId`]. - block_solvers: HashMap, + block_solvers: HashMap>, bigint_solver: AcvmBigIntSolver, /// A list of opcodes which are to be executed by the ACVM. - opcodes: &'a [Opcode], + opcodes: &'a [Opcode], /// Index of the next opcode to be executed. instruction_pointer: usize, - witness_map: WitnessMap, + witness_map: WitnessMap, - brillig_solver: Option>, + brillig_solver: Option>, /// A counter maintained throughout an ACVM process that determines /// whether the caller has resolved the results of an ACIR [call][Opcode::Call]. acir_call_counter: usize, /// Represents the outputs of all ACIR calls during an ACVM process /// List is appended onto by the caller upon reaching a [ACVMStatus::RequiresAcirCall] - acir_call_results: Vec>, + acir_call_results: Vec>, // Each unconstrained function referenced in the program - unconstrained_functions: &'a [BrilligBytecode], + unconstrained_functions: &'a [BrilligBytecode], - assertion_payloads: &'a [(OpcodeLocation, AssertionPayload)], + assertion_payloads: &'a [(OpcodeLocation, AssertionPayload)], } -impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { +impl<'a, F: AcirField, B: BlackBoxFunctionSolver> ACVM<'a, F, B> { pub fn new( backend: &'a B, - opcodes: &'a [Opcode], - initial_witness: WitnessMap, - unconstrained_functions: &'a [BrilligBytecode], - assertion_payloads: &'a [(OpcodeLocation, AssertionPayload)], + opcodes: &'a [Opcode], + initial_witness: WitnessMap, + unconstrained_functions: &'a [BrilligBytecode], + assertion_payloads: &'a [(OpcodeLocation, AssertionPayload)], ) -> Self { let status = if opcodes.is_empty() { ACVMStatus::Solved } else { ACVMStatus::InProgress }; ACVM { @@ -210,20 +210,16 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { /// Returns a reference to the current state of the ACVM's [`WitnessMap`]. /// /// Once execution has completed, the witness map can be extracted using [`ACVM::finalize`] - pub fn witness_map(&self) -> &WitnessMap { + pub fn witness_map(&self) -> &WitnessMap { &self.witness_map } - pub fn overwrite_witness( - &mut self, - witness: Witness, - value: FieldElement, - ) -> Option { + pub fn overwrite_witness(&mut self, witness: Witness, value: F) -> Option { self.witness_map.insert(witness, value) } /// Returns a slice containing the opcodes of the circuit being executed. - pub fn opcodes(&self) -> &[Opcode] { + pub fn opcodes(&self) -> &[Opcode] { self.opcodes } @@ -233,7 +229,7 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { } /// Finalize the ACVM execution, returning the resulting [`WitnessMap`]. - pub fn finalize(self) -> WitnessMap { + pub fn finalize(self) -> WitnessMap { if self.status != ACVMStatus::Solved { panic!("ACVM execution is not complete: ({})", self.status); } @@ -242,29 +238,29 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { /// Updates the current status of the VM. /// Returns the given status. - fn status(&mut self, status: ACVMStatus) -> ACVMStatus { + fn status(&mut self, status: ACVMStatus) -> ACVMStatus { self.status = status.clone(); status } - pub fn get_status(&self) -> &ACVMStatus { + pub fn get_status(&self) -> &ACVMStatus { &self.status } /// Sets the VM status to [ACVMStatus::Failure] using the provided `error`. /// Returns the new status. - fn fail(&mut self, error: OpcodeResolutionError) -> ACVMStatus { + fn fail(&mut self, error: OpcodeResolutionError) -> ACVMStatus { self.status(ACVMStatus::Failure(error)) } /// Sets the status of the VM to `RequiresForeignCall`. /// Indicating that the VM is now waiting for a foreign call to be resolved. - fn wait_for_foreign_call(&mut self, foreign_call: ForeignCallWaitInfo) -> ACVMStatus { + fn wait_for_foreign_call(&mut self, foreign_call: ForeignCallWaitInfo) -> ACVMStatus { self.status(ACVMStatus::RequiresForeignCall(foreign_call)) } /// Return a reference to the arguments for the next pending foreign call, if one exists. - pub fn get_pending_foreign_call(&self) -> Option<&ForeignCallWaitInfo> { + pub fn get_pending_foreign_call(&self) -> Option<&ForeignCallWaitInfo> { if let ACVMStatus::RequiresForeignCall(foreign_call) = &self.status { Some(foreign_call) } else { @@ -275,7 +271,7 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { /// Resolves a foreign call's [result][acir::brillig_vm::ForeignCallResult] using a result calculated outside of the ACVM. /// /// The ACVM can then be restarted to solve the remaining Brillig VM process as well as the remaining ACIR opcodes. - pub fn resolve_pending_foreign_call(&mut self, foreign_call_result: ForeignCallResult) { + pub fn resolve_pending_foreign_call(&mut self, foreign_call_result: ForeignCallResult) { if !matches!(self.status, ACVMStatus::RequiresForeignCall(_)) { panic!("ACVM is not expecting a foreign call response as no call was made"); } @@ -289,14 +285,14 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { /// Sets the status of the VM to `RequiresAcirCall` /// Indicating that the VM is now waiting for an ACIR call to be resolved - fn wait_for_acir_call(&mut self, acir_call: AcirCallWaitInfo) -> ACVMStatus { + fn wait_for_acir_call(&mut self, acir_call: AcirCallWaitInfo) -> ACVMStatus { self.status(ACVMStatus::RequiresAcirCall(acir_call)) } /// Resolves an ACIR call's result (simply a list of fields) using a result calculated by a separate ACVM instance. /// /// The current ACVM instance can then be restarted to solve the remaining ACIR opcodes. - pub fn resolve_pending_acir_call(&mut self, call_result: Vec) { + pub fn resolve_pending_acir_call(&mut self, call_result: Vec) { if !matches!(self.status, ACVMStatus::RequiresAcirCall(_)) { panic!("ACVM is not expecting an ACIR call response as no call was made"); } @@ -316,14 +312,14 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { /// 1. All opcodes have been executed successfully. /// 2. The circuit has been found to be unsatisfiable. /// 2. A Brillig [foreign call][`ForeignCallWaitInfo`] has been encountered and must be resolved. - pub fn solve(&mut self) -> ACVMStatus { + pub fn solve(&mut self) -> ACVMStatus { while self.status == ACVMStatus::InProgress { self.solve_opcode(); } self.status.clone() } - pub fn solve_opcode(&mut self) -> ACVMStatus { + pub fn solve_opcode(&mut self) -> ACVMStatus { let opcode = &self.opcodes[self.instruction_pointer]; let resolution = match opcode { @@ -357,8 +353,8 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { fn handle_opcode_resolution( &mut self, - resolution: Result<(), OpcodeResolutionError>, - ) -> ACVMStatus { + resolution: Result<(), OpcodeResolutionError>, + ) -> ACVMStatus { match resolution { Ok(()) => { self.instruction_pointer += 1; @@ -400,7 +396,7 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { fn extract_assertion_payload( &self, location: OpcodeLocation, - ) -> Option { + ) -> Option> { let (_, found_assertion_payload) = self.assertion_payloads.iter().find(|(loc, _)| location == *loc)?; match found_assertion_payload { @@ -458,7 +454,7 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { fn solve_brillig_call_opcode( &mut self, - ) -> Result, OpcodeResolutionError> { + ) -> Result>, OpcodeResolutionError> { let Opcode::BrilligCall { id, inputs, outputs, predicate } = &self.opcodes[self.instruction_pointer] else { @@ -466,13 +462,13 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { }; if is_predicate_false(&self.witness_map, predicate)? { - return BrilligSolver::::zero_out_brillig_outputs(&mut self.witness_map, outputs) + return BrilligSolver::::zero_out_brillig_outputs(&mut self.witness_map, outputs) .map(|_| None); } // If we're resuming execution after resolving a foreign call then // there will be a cached `BrilligSolver` to avoid recomputation. - let mut solver: BrilligSolver<'_, B> = match self.brillig_solver.take() { + let mut solver: BrilligSolver<'_, F, B> = match self.brillig_solver.take() { Some(solver) => solver, None => BrilligSolver::new_call( &self.witness_map, @@ -503,7 +499,7 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { } } - fn map_brillig_error(&self, mut err: OpcodeResolutionError) -> OpcodeResolutionError { + fn map_brillig_error(&self, mut err: OpcodeResolutionError) -> OpcodeResolutionError { match &mut err { OpcodeResolutionError::BrilligFunctionFailed { call_stack, payload } => { // Some brillig errors have static strings as payloads, we can resolve them here @@ -528,7 +524,7 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { } } - pub fn step_into_brillig(&mut self) -> StepResult<'a, B> { + pub fn step_into_brillig(&mut self) -> StepResult<'a, F, B> { let Opcode::BrilligCall { id, inputs, outputs, predicate } = &self.opcodes[self.instruction_pointer] else { @@ -541,7 +537,7 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { Err(err) => return StepResult::Status(self.handle_opcode_resolution(Err(err))), }; if should_skip { - let resolution = BrilligSolver::::zero_out_brillig_outputs(witness, outputs); + let resolution = BrilligSolver::::zero_out_brillig_outputs(witness, outputs); return StepResult::Status(self.handle_opcode_resolution(resolution)); } @@ -559,7 +555,7 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { } } - pub fn finish_brillig_with_solver(&mut self, solver: BrilligSolver<'a, B>) -> ACVMStatus { + pub fn finish_brillig_with_solver(&mut self, solver: BrilligSolver<'a, F, B>) -> ACVMStatus { if !matches!(self.opcodes[self.instruction_pointer], Opcode::BrilligCall { .. }) { unreachable!("Not executing a Brillig/BrilligCall opcode"); } @@ -567,7 +563,9 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { self.solve_opcode() } - pub fn solve_call_opcode(&mut self) -> Result, OpcodeResolutionError> { + pub fn solve_call_opcode( + &mut self, + ) -> Result>, OpcodeResolutionError> { let Opcode::Call { id, inputs, outputs, predicate } = &self.opcodes[self.instruction_pointer] else { @@ -584,7 +582,7 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { if is_predicate_false(&self.witness_map, predicate)? { // Zero out the outputs if we have a false predicate for output in outputs { - insert_value(output, FieldElement::zero(), &mut self.witness_map)?; + insert_value(output, F::zero(), &mut self.witness_map)?; } return Ok(None); } @@ -621,10 +619,10 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { // Returns the concrete value for a particular witness // If the witness has no assignment, then // an error is returned -pub fn witness_to_value( - initial_witness: &WitnessMap, +pub fn witness_to_value( + initial_witness: &WitnessMap, witness: Witness, -) -> Result<&FieldElement, OpcodeResolutionError> { +) -> Result<&F, OpcodeResolutionError> { match initial_witness.get(&witness) { Some(value) => Ok(value), None => Err(OpcodeNotSolvable::MissingAssignment(witness.0).into()), @@ -633,10 +631,10 @@ pub fn witness_to_value( // TODO: There is an issue open to decide on whether we need to get values from Expressions // TODO versus just getting values from Witness -pub fn get_value( - expr: &Expression, - initial_witness: &WitnessMap, -) -> Result { +pub fn get_value( + expr: &Expression, + initial_witness: &WitnessMap, +) -> Result> { let expr = ExpressionSolver::evaluate(expr, initial_witness); match expr.to_const() { Some(value) => Ok(value), @@ -650,11 +648,11 @@ pub fn get_value( /// /// Returns an error if there was already a value in the map /// which does not match the value that one is about to insert -pub fn insert_value( +pub fn insert_value( witness: &Witness, - value_to_insert: FieldElement, - initial_witness: &mut WitnessMap, -) -> Result<(), OpcodeResolutionError> { + value_to_insert: F, + initial_witness: &mut WitnessMap, +) -> Result<(), OpcodeResolutionError> { let optional_old_value = initial_witness.insert(*witness, value_to_insert); let old_value = match optional_old_value { @@ -675,7 +673,7 @@ pub fn insert_value( // Returns one witness belonging to an expression, in no relevant order // Returns None if the expression is const // The function is used during partial witness generation to report unsolved witness -fn any_witness_from_expression(expr: &Expression) -> Option { +fn any_witness_from_expression(expr: &Expression) -> Option { if expr.linear_combinations.is_empty() { if expr.mul_terms.is_empty() { None @@ -690,10 +688,10 @@ fn any_witness_from_expression(expr: &Expression) -> Option { /// Returns `true` if the predicate is zero /// A predicate is used to indicate whether we should skip a certain operation. /// If we have a zero predicate it means the operation should be skipped. -pub(crate) fn is_predicate_false( - witness: &WitnessMap, - predicate: &Option, -) -> Result { +pub(crate) fn is_predicate_false( + witness: &WitnessMap, + predicate: &Option>, +) -> Result> { match predicate { Some(pred) => get_value(pred, witness).map(|pred_value| pred_value.is_zero()), // If the predicate is `None`, then we treat it as an unconditional `true` @@ -702,9 +700,9 @@ pub(crate) fn is_predicate_false( } #[derive(Debug, Clone, PartialEq)] -pub struct AcirCallWaitInfo { +pub struct AcirCallWaitInfo { /// Index in the list of ACIR function's that should be called pub id: u32, /// Initial witness for the given circuit to be called - pub initial_witness: WitnessMap, + pub initial_witness: WitnessMap, } diff --git a/acvm-repo/acvm/tests/solver.rs b/acvm-repo/acvm/tests/solver.rs index 495389d7b3e..e55dbb73ae1 100644 --- a/acvm-repo/acvm/tests/solver.rs +++ b/acvm-repo/acvm/tests/solver.rs @@ -1,6 +1,7 @@ use std::collections::BTreeMap; use acir::{ + acir_field::GenericFieldElement, brillig::{BinaryFieldOp, HeapArray, MemoryAddress, Opcode as BrilligOpcode, ValueOrArray}, circuit::{ brillig::{BrilligBytecode, BrilligInputs, BrilligOutputs}, @@ -8,7 +9,7 @@ use acir::{ Opcode, OpcodeLocation, }, native_types::{Expression, Witness, WitnessMap}, - FieldElement, + AcirField, FieldElement, }; use acvm::pwg::{ACVMStatus, ErrorLocation, ForeignCallWaitInfo, OpcodeResolutionError, ACVM}; @@ -17,6 +18,38 @@ use brillig_vm::brillig::HeapValueType; // Reenable these test cases once we move the brillig implementation of inversion down into the acvm stdlib. +#[test] +fn bls12_381_circuit() { + type Bls12FieldElement = GenericFieldElement; + + let addition = Opcode::AssertZero(Expression { + mul_terms: Vec::new(), + linear_combinations: vec![ + (Bls12FieldElement::one(), Witness(1)), + (Bls12FieldElement::one(), Witness(2)), + (-Bls12FieldElement::one(), Witness(3)), + ], + q_c: Bls12FieldElement::zero(), + }); + let opcodes = [addition]; + + let witness_assignments = BTreeMap::from([ + (Witness(1), Bls12FieldElement::from(2u128)), + (Witness(2), Bls12FieldElement::from(3u128)), + ]) + .into(); + + let mut acvm = ACVM::new(&StubbedBlackBoxSolver, &opcodes, witness_assignments, &[], &[]); + // use the partial witness generation solver with our acir program + let solver_status = acvm.solve(); + assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); + + // ACVM should be able to be finalized in `Solved` state. + let witness_stack = acvm.finalize(); + + assert_eq!(witness_stack.get(&Witness(3)).unwrap(), &Bls12FieldElement::from(5u128)); +} + #[test] fn inversion_brillig_oracle_equivalence() { // Opcodes below describe the following: @@ -123,7 +156,7 @@ fn inversion_brillig_oracle_equivalence() { ); assert_eq!(acvm.instruction_pointer(), 0, "brillig should have been removed"); - let foreign_call_wait_info: &ForeignCallWaitInfo = + let foreign_call_wait_info: &ForeignCallWaitInfo = acvm.get_pending_foreign_call().expect("should have a brillig foreign call request"); assert_eq!(foreign_call_wait_info.inputs.len(), 1, "Should be waiting for a single input"); @@ -268,7 +301,7 @@ fn double_inversion_brillig_oracle() { ); assert_eq!(acvm.instruction_pointer(), 0, "should stall on brillig"); - let foreign_call_wait_info: &ForeignCallWaitInfo = + let foreign_call_wait_info: &ForeignCallWaitInfo = acvm.get_pending_foreign_call().expect("should have a brillig foreign call request"); assert_eq!(foreign_call_wait_info.inputs.len(), 1, "Should be waiting for a single input"); @@ -405,7 +438,7 @@ fn oracle_dependent_execution() { ); assert_eq!(acvm.instruction_pointer(), 1, "should stall on brillig"); - let foreign_call_wait_info: &ForeignCallWaitInfo = + let foreign_call_wait_info: &ForeignCallWaitInfo = acvm.get_pending_foreign_call().expect("should have a brillig foreign call request"); assert_eq!(foreign_call_wait_info.inputs.len(), 1, "Should be waiting for a single input"); @@ -421,7 +454,7 @@ fn oracle_dependent_execution() { ); assert_eq!(acvm.instruction_pointer(), 1, "should stall on brillig"); - let foreign_call_wait_info: &ForeignCallWaitInfo = + let foreign_call_wait_info: &ForeignCallWaitInfo = acvm.get_pending_foreign_call().expect("should have a brillig foreign call request"); assert_eq!(foreign_call_wait_info.inputs.len(), 1, "Should be waiting for a single input"); diff --git a/acvm-repo/acvm_js/src/black_box_solvers.rs b/acvm-repo/acvm_js/src/black_box_solvers.rs index 188e5334ed5..4f2676f8d2f 100644 --- a/acvm-repo/acvm_js/src/black_box_solvers.rs +++ b/acvm-repo/acvm_js/src/black_box_solvers.rs @@ -2,7 +2,7 @@ use js_sys::JsString; use wasm_bindgen::prelude::*; use crate::js_witness_map::{field_element_to_js_string, js_value_to_field_element}; -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; /// Performs a bitwise AND operation between `lhs` and `rhs` #[wasm_bindgen] diff --git a/acvm-repo/acvm_js/src/execute.rs b/acvm-repo/acvm_js/src/execute.rs index 9f2b07b31fc..85cc3f455a0 100644 --- a/acvm-repo/acvm_js/src/execute.rs +++ b/acvm-repo/acvm_js/src/execute.rs @@ -2,12 +2,12 @@ use std::{future::Future, pin::Pin}; use acvm::acir::circuit::brillig::BrilligBytecode; use acvm::acir::circuit::ResolvedAssertionPayload; -use acvm::BlackBoxFunctionSolver; use acvm::{ acir::circuit::{Circuit, Program}, acir::native_types::{WitnessMap, WitnessStack}, pwg::{ACVMStatus, ErrorLocation, OpcodeResolutionError, ACVM}, }; +use acvm::{BlackBoxFunctionSolver, FieldElement}; use bn254_blackbox_solver::Bn254BlackBoxSolver; use js_sys::Error; @@ -72,7 +72,7 @@ pub async fn execute_circuit_with_return_witness( ) -> Result { console_error_panic_hook::set_once(); - let program: Program = Program::deserialize_program(&program) + let program: Program = Program::deserialize_program(&program) .map_err(|_| JsExecutionError::new("Failed to deserialize circuit. This is likely due to differing serialization formats between ACVM_JS and your compiler".to_string(), None, None))?; let mut witness_stack = execute_program_with_native_program_and_return( @@ -148,8 +148,8 @@ async fn execute_program_with_native_type_return( program: Vec, initial_witness: JsWitnessMap, foreign_call_executor: &ForeignCallHandler, -) -> Result { - let program: Program = Program::deserialize_program(&program) +) -> Result, Error> { + let program: Program = Program::deserialize_program(&program) .map_err(|_| JsExecutionError::new( "Failed to deserialize circuit. This is likely due to differing serialization formats between ACVM_JS and your compiler".to_string(), None, @@ -160,10 +160,10 @@ async fn execute_program_with_native_type_return( } async fn execute_program_with_native_program_and_return( - program: &Program, + program: &Program, initial_witness: JsWitnessMap, foreign_call_executor: &ForeignCallHandler, -) -> Result { +) -> Result, Error> { let blackbox_solver = Bn254BlackBoxSolver; let executor = ProgramExecutor::new( &program.functions, @@ -176,20 +176,20 @@ async fn execute_program_with_native_program_and_return( Ok(witness_stack) } -struct ProgramExecutor<'a, B: BlackBoxFunctionSolver> { - functions: &'a [Circuit], +struct ProgramExecutor<'a, B: BlackBoxFunctionSolver> { + functions: &'a [Circuit], - unconstrained_functions: &'a [BrilligBytecode], + unconstrained_functions: &'a [BrilligBytecode], blackbox_solver: &'a B, foreign_call_handler: &'a ForeignCallHandler, } -impl<'a, B: BlackBoxFunctionSolver> ProgramExecutor<'a, B> { +impl<'a, B: BlackBoxFunctionSolver> ProgramExecutor<'a, B> { fn new( - functions: &'a [Circuit], - unconstrained_functions: &'a [BrilligBytecode], + functions: &'a [Circuit], + unconstrained_functions: &'a [BrilligBytecode], blackbox_solver: &'a B, foreign_call_handler: &'a ForeignCallHandler, ) -> Self { @@ -201,7 +201,10 @@ impl<'a, B: BlackBoxFunctionSolver> ProgramExecutor<'a, B> { } } - async fn execute(&self, initial_witness: WitnessMap) -> Result { + async fn execute( + &self, + initial_witness: WitnessMap, + ) -> Result, Error> { let main = &self.functions[0]; let mut witness_stack = WitnessStack::default(); @@ -212,10 +215,10 @@ impl<'a, B: BlackBoxFunctionSolver> ProgramExecutor<'a, B> { fn execute_circuit( &'a self, - circuit: &'a Circuit, - initial_witness: WitnessMap, - witness_stack: &'a mut WitnessStack, - ) -> Pin> + 'a>> { + circuit: &'a Circuit, + initial_witness: WitnessMap, + witness_stack: &'a mut WitnessStack, + ) -> Pin, Error>> + 'a>> { Box::pin(async { let mut acvm = ACVM::new( self.blackbox_solver, diff --git a/acvm-repo/acvm_js/src/foreign_call/inputs.rs b/acvm-repo/acvm_js/src/foreign_call/inputs.rs index ebd29fb7d58..dd12bc639ec 100644 --- a/acvm-repo/acvm_js/src/foreign_call/inputs.rs +++ b/acvm-repo/acvm_js/src/foreign_call/inputs.rs @@ -1,9 +1,9 @@ -use acvm::brillig_vm::brillig::ForeignCallParam; +use acvm::{brillig_vm::brillig::ForeignCallParam, FieldElement}; use crate::js_witness_map::field_element_to_js_string; pub(super) fn encode_foreign_call_inputs( - foreign_call_inputs: &[ForeignCallParam], + foreign_call_inputs: &[ForeignCallParam], ) -> js_sys::Array { let inputs = js_sys::Array::default(); for input in foreign_call_inputs { diff --git a/acvm-repo/acvm_js/src/foreign_call/mod.rs b/acvm-repo/acvm_js/src/foreign_call/mod.rs index 9ccaf733f84..4884c1173dc 100644 --- a/acvm-repo/acvm_js/src/foreign_call/mod.rs +++ b/acvm-repo/acvm_js/src/foreign_call/mod.rs @@ -1,4 +1,4 @@ -use acvm::{brillig_vm::brillig::ForeignCallResult, pwg::ForeignCallWaitInfo}; +use acvm::{brillig_vm::brillig::ForeignCallResult, pwg::ForeignCallWaitInfo, FieldElement}; use js_sys::{Error, JsString}; use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; @@ -29,8 +29,8 @@ extern "C" { pub(super) async fn resolve_brillig( foreign_call_callback: &ForeignCallHandler, - foreign_call_wait_info: &ForeignCallWaitInfo, -) -> Result { + foreign_call_wait_info: &ForeignCallWaitInfo, +) -> Result, Error> { // Prepare to call let name = JsString::from(foreign_call_wait_info.function.clone()); let inputs = inputs::encode_foreign_call_inputs(&foreign_call_wait_info.inputs); diff --git a/acvm-repo/acvm_js/src/foreign_call/outputs.rs b/acvm-repo/acvm_js/src/foreign_call/outputs.rs index 78fa520aa15..2b3f44fe98d 100644 --- a/acvm-repo/acvm_js/src/foreign_call/outputs.rs +++ b/acvm-repo/acvm_js/src/foreign_call/outputs.rs @@ -1,9 +1,12 @@ -use acvm::brillig_vm::brillig::{ForeignCallParam, ForeignCallResult}; +use acvm::{ + brillig_vm::brillig::{ForeignCallParam, ForeignCallResult}, + FieldElement, +}; use wasm_bindgen::JsValue; use crate::js_witness_map::js_value_to_field_element; -fn decode_foreign_call_output(output: JsValue) -> Result { +fn decode_foreign_call_output(output: JsValue) -> Result, String> { if output.is_string() { let value = js_value_to_field_element(output)?; Ok(ForeignCallParam::Single(value)) @@ -22,8 +25,9 @@ fn decode_foreign_call_output(output: JsValue) -> Result Result { - let mut values: Vec = Vec::with_capacity(js_array.length() as usize); +) -> Result, String> { + let mut values: Vec> = + Vec::with_capacity(js_array.length() as usize); for elem in js_array.iter() { values.push(decode_foreign_call_output(elem)?); } diff --git a/acvm-repo/acvm_js/src/js_execution_error.rs b/acvm-repo/acvm_js/src/js_execution_error.rs index b34ea5ddb60..e51a912a63a 100644 --- a/acvm-repo/acvm_js/src/js_execution_error.rs +++ b/acvm-repo/acvm_js/src/js_execution_error.rs @@ -1,4 +1,7 @@ -use acvm::acir::circuit::{OpcodeLocation, RawAssertionPayload}; +use acvm::{ + acir::circuit::{OpcodeLocation, RawAssertionPayload}, + FieldElement, +}; use gloo_utils::format::JsValueSerdeExt; use js_sys::{Array, Error, JsString, Reflect}; use wasm_bindgen::prelude::{wasm_bindgen, JsValue}; @@ -34,7 +37,7 @@ impl JsExecutionError { pub fn new( message: String, call_stack: Option>, - assertion_payload: Option, + assertion_payload: Option>, ) -> Self { let mut error = JsExecutionError::constructor(JsString::from(message)); let js_call_stack = match call_stack { diff --git a/acvm-repo/acvm_js/src/js_witness_map.rs b/acvm-repo/acvm_js/src/js_witness_map.rs index c4482c4a234..8316059e21a 100644 --- a/acvm-repo/acvm_js/src/js_witness_map.rs +++ b/acvm-repo/acvm_js/src/js_witness_map.rs @@ -1,5 +1,6 @@ use acvm::{ acir::native_types::{Witness, WitnessMap}, + acir::AcirField, FieldElement, }; use js_sys::{JsString, Map, Object}; @@ -51,8 +52,8 @@ impl Default for JsSolvedAndReturnWitness { } } -impl From for JsWitnessMap { - fn from(witness_map: WitnessMap) -> Self { +impl From> for JsWitnessMap { + fn from(witness_map: WitnessMap) -> Self { let js_map = JsWitnessMap::new(); for (key, value) in witness_map { js_map.set( @@ -64,7 +65,7 @@ impl From for JsWitnessMap { } } -impl From for WitnessMap { +impl From for WitnessMap { fn from(js_map: JsWitnessMap) -> Self { let mut witness_map = WitnessMap::new(); js_map.for_each(&mut |value, key| { @@ -76,8 +77,8 @@ impl From for WitnessMap { } } -impl From<(WitnessMap, WitnessMap)> for JsSolvedAndReturnWitness { - fn from(witness_maps: (WitnessMap, WitnessMap)) -> Self { +impl From<(WitnessMap, WitnessMap)> for JsSolvedAndReturnWitness { + fn from(witness_maps: (WitnessMap, WitnessMap)) -> Self { let js_solved_witness = JsWitnessMap::from(witness_maps.0); let js_return_witness = JsWitnessMap::from(witness_maps.1); @@ -113,7 +114,7 @@ mod test { use acvm::{ acir::native_types::{Witness, WitnessMap}, - FieldElement, + AcirField, FieldElement, }; use wasm_bindgen::JsValue; diff --git a/acvm-repo/acvm_js/src/js_witness_stack.rs b/acvm-repo/acvm_js/src/js_witness_stack.rs index 59f2dbc051e..d59ee508086 100644 --- a/acvm-repo/acvm_js/src/js_witness_stack.rs +++ b/acvm-repo/acvm_js/src/js_witness_stack.rs @@ -1,4 +1,4 @@ -use acvm::acir::native_types::WitnessStack; +use acvm::{acir::native_types::WitnessStack, FieldElement}; use js_sys::{Array, Map, Object}; use wasm_bindgen::prelude::{wasm_bindgen, JsValue}; @@ -38,8 +38,8 @@ impl Default for JsWitnessStack { } } -impl From for JsWitnessStack { - fn from(mut witness_stack: WitnessStack) -> Self { +impl From> for JsWitnessStack { + fn from(mut witness_stack: WitnessStack) -> Self { let js_witness_stack = JsWitnessStack::new(); while let Some(stack_item) = witness_stack.pop() { let js_map = JsWitnessMap::from(stack_item.witness); @@ -57,7 +57,7 @@ impl From for JsWitnessStack { } } -impl From for WitnessStack { +impl From for WitnessStack { fn from(js_witness_stack: JsWitnessStack) -> Self { let mut witness_stack = WitnessStack::default(); js_witness_stack.for_each(&mut |stack_item, _, _| { diff --git a/acvm-repo/acvm_js/src/public_witness.rs b/acvm-repo/acvm_js/src/public_witness.rs index 4ba054732d4..245d5b4dd0a 100644 --- a/acvm-repo/acvm_js/src/public_witness.rs +++ b/acvm-repo/acvm_js/src/public_witness.rs @@ -1,6 +1,9 @@ -use acvm::acir::{ - circuit::Program, - native_types::{Witness, WitnessMap}, +use acvm::{ + acir::{ + circuit::Program, + native_types::{Witness, WitnessMap}, + }, + FieldElement, }; use js_sys::JsString; use wasm_bindgen::prelude::wasm_bindgen; @@ -8,9 +11,9 @@ use wasm_bindgen::prelude::wasm_bindgen; use crate::JsWitnessMap; pub(crate) fn extract_indices( - witness_map: &WitnessMap, + witness_map: &WitnessMap, indices: Vec, -) -> Result { +) -> Result, String> { let mut extracted_witness_map = WitnessMap::new(); for witness in indices { let witness_value = witness_map.get(&witness).ok_or(format!( @@ -36,7 +39,7 @@ pub fn get_return_witness( witness_map: JsWitnessMap, ) -> Result { console_error_panic_hook::set_once(); - let program: Program = + let program: Program = Program::deserialize_program(&program).expect("Failed to deserialize circuit"); let circuit = match program.functions.len() { 0 => return Ok(JsWitnessMap::from(WitnessMap::new())), @@ -63,7 +66,7 @@ pub fn get_public_parameters_witness( solved_witness: JsWitnessMap, ) -> Result { console_error_panic_hook::set_once(); - let program: Program = + let program: Program = Program::deserialize_program(&program).expect("Failed to deserialize circuit"); let circuit = match program.functions.len() { 0 => return Ok(JsWitnessMap::from(WitnessMap::new())), @@ -90,7 +93,7 @@ pub fn get_public_witness( solved_witness: JsWitnessMap, ) -> Result { console_error_panic_hook::set_once(); - let program: Program = + let program: Program = Program::deserialize_program(&program).expect("Failed to deserialize circuit"); let circuit = match program.functions.len() { 0 => return Ok(JsWitnessMap::from(WitnessMap::new())), diff --git a/acvm-repo/blackbox_solver/Cargo.toml b/acvm-repo/blackbox_solver/Cargo.toml index 6c1cd190254..00c87bbca74 100644 --- a/acvm-repo/blackbox_solver/Cargo.toml +++ b/acvm-repo/blackbox_solver/Cargo.toml @@ -40,6 +40,5 @@ p256 = { version = "0.11.0", features = [ libaes = "0.7.0" [features] -default = ["bn254"] bn254 = ["acir/bn254"] bls12_381 = ["acir/bls12_381"] diff --git a/acvm-repo/blackbox_solver/src/curve_specific_solver.rs b/acvm-repo/blackbox_solver/src/curve_specific_solver.rs index 73f64d3d9d1..0ee3a252840 100644 --- a/acvm-repo/blackbox_solver/src/curve_specific_solver.rs +++ b/acvm-repo/blackbox_solver/src/curve_specific_solver.rs @@ -1,4 +1,4 @@ -use acir::{BlackBoxFunc, FieldElement}; +use acir::BlackBoxFunc; use crate::BlackBoxResolutionError; @@ -6,44 +6,44 @@ use crate::BlackBoxResolutionError; /// doesn't have a canonical Rust implementation. /// /// Returns an [`BlackBoxResolutionError`] if the backend does not support the given [`acir::BlackBoxFunc`]. -pub trait BlackBoxFunctionSolver { +pub trait BlackBoxFunctionSolver { fn schnorr_verify( &self, - public_key_x: &FieldElement, - public_key_y: &FieldElement, + public_key_x: &F, + public_key_y: &F, signature: &[u8; 64], message: &[u8], ) -> Result; fn pedersen_commitment( &self, - inputs: &[FieldElement], + inputs: &[F], domain_separator: u32, - ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError>; + ) -> Result<(F, F), BlackBoxResolutionError>; fn pedersen_hash( &self, - inputs: &[FieldElement], + inputs: &[F], domain_separator: u32, - ) -> Result; + ) -> Result; fn multi_scalar_mul( &self, - points: &[FieldElement], - scalars_lo: &[FieldElement], - scalars_hi: &[FieldElement], - ) -> Result<(FieldElement, FieldElement, FieldElement), BlackBoxResolutionError>; + points: &[F], + scalars_lo: &[F], + scalars_hi: &[F], + ) -> Result<(F, F, F), BlackBoxResolutionError>; fn ec_add( &self, - input1_x: &FieldElement, - input1_y: &FieldElement, - input1_infinite: &FieldElement, - input2_x: &FieldElement, - input2_y: &FieldElement, - input2_infinite: &FieldElement, - ) -> Result<(FieldElement, FieldElement, FieldElement), BlackBoxResolutionError>; + input1_x: &F, + input1_y: &F, + input1_infinite: &F, + input2_x: &F, + input2_y: &F, + input2_infinite: &F, + ) -> Result<(F, F, F), BlackBoxResolutionError>; fn poseidon2_permutation( &self, - _inputs: &[FieldElement], + _inputs: &[F], _len: u32, - ) -> Result, BlackBoxResolutionError>; + ) -> Result, BlackBoxResolutionError>; } pub struct StubbedBlackBoxSolver; @@ -57,11 +57,11 @@ impl StubbedBlackBoxSolver { } } -impl BlackBoxFunctionSolver for StubbedBlackBoxSolver { +impl BlackBoxFunctionSolver for StubbedBlackBoxSolver { fn schnorr_verify( &self, - _public_key_x: &FieldElement, - _public_key_y: &FieldElement, + _public_key_x: &F, + _public_key_y: &F, _signature: &[u8; 64], _message: &[u8], ) -> Result { @@ -69,42 +69,42 @@ impl BlackBoxFunctionSolver for StubbedBlackBoxSolver { } fn pedersen_commitment( &self, - _inputs: &[FieldElement], + _inputs: &[F], _domain_separator: u32, - ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { + ) -> Result<(F, F), BlackBoxResolutionError> { Err(Self::fail(BlackBoxFunc::PedersenCommitment)) } fn pedersen_hash( &self, - _inputs: &[FieldElement], + _inputs: &[F], _domain_separator: u32, - ) -> Result { + ) -> Result { Err(Self::fail(BlackBoxFunc::PedersenHash)) } fn multi_scalar_mul( &self, - _points: &[FieldElement], - _scalars_lo: &[FieldElement], - _scalars_hi: &[FieldElement], - ) -> Result<(FieldElement, FieldElement, FieldElement), BlackBoxResolutionError> { + _points: &[F], + _scalars_lo: &[F], + _scalars_hi: &[F], + ) -> Result<(F, F, F), BlackBoxResolutionError> { Err(Self::fail(BlackBoxFunc::MultiScalarMul)) } fn ec_add( &self, - _input1_x: &FieldElement, - _input1_y: &FieldElement, - _input1_infinite: &FieldElement, - _input2_x: &FieldElement, - _input2_y: &FieldElement, - _input2_infinite: &FieldElement, - ) -> Result<(FieldElement, FieldElement, FieldElement), BlackBoxResolutionError> { + _input1_x: &F, + _input1_y: &F, + _input1_infinite: &F, + _input2_x: &F, + _input2_y: &F, + _input2_infinite: &F, + ) -> Result<(F, F, F), BlackBoxResolutionError> { Err(Self::fail(BlackBoxFunc::EmbeddedCurveAdd)) } fn poseidon2_permutation( &self, - _inputs: &[FieldElement], + _inputs: &[F], _len: u32, - ) -> Result, BlackBoxResolutionError> { + ) -> Result, BlackBoxResolutionError> { Err(Self::fail(BlackBoxFunc::Poseidon2Permutation)) } } diff --git a/acvm-repo/bn254_blackbox_solver/benches/criterion.rs b/acvm-repo/bn254_blackbox_solver/benches/criterion.rs index b86414423cf..cbcb75a3291 100644 --- a/acvm-repo/bn254_blackbox_solver/benches/criterion.rs +++ b/acvm-repo/bn254_blackbox_solver/benches/criterion.rs @@ -1,7 +1,7 @@ use criterion::{criterion_group, criterion_main, Criterion}; use std::{hint::black_box, time::Duration}; -use acir::FieldElement; +use acir::{AcirField, FieldElement}; use acvm_blackbox_solver::BlackBoxFunctionSolver; use bn254_blackbox_solver::{poseidon2_permutation, Bn254BlackBoxSolver}; diff --git a/acvm-repo/bn254_blackbox_solver/src/embedded_curve_ops.rs b/acvm-repo/bn254_blackbox_solver/src/embedded_curve_ops.rs index 901eb9d5a0f..148accd8b23 100644 --- a/acvm-repo/bn254_blackbox_solver/src/embedded_curve_ops.rs +++ b/acvm-repo/bn254_blackbox_solver/src/embedded_curve_ops.rs @@ -3,7 +3,8 @@ use ark_ec::AffineRepr; use ark_ff::MontConfig; use num_bigint::BigUint; -use acir::{BlackBoxFunc, FieldElement}; +use acir::BlackBoxFunc; +use acir::{AcirField, FieldElement}; use crate::BlackBoxResolutionError; @@ -117,10 +118,10 @@ fn create_point( #[cfg(test)] mod tests { - use ark_ff::BigInteger; - use super::*; + use ark_ff::BigInteger; + fn get_generator() -> [FieldElement; 3] { let generator = grumpkin::SWAffine::generator(); let generator_x = FieldElement::from_repr(*generator.x().unwrap()); diff --git a/acvm-repo/bn254_blackbox_solver/src/lib.rs b/acvm-repo/bn254_blackbox_solver/src/lib.rs index ae5a1c3db6d..e3cea1153be 100644 --- a/acvm-repo/bn254_blackbox_solver/src/lib.rs +++ b/acvm-repo/bn254_blackbox_solver/src/lib.rs @@ -18,7 +18,7 @@ pub use poseidon2::poseidon2_permutation; #[derive(Default)] pub struct Bn254BlackBoxSolver; -impl BlackBoxFunctionSolver for Bn254BlackBoxSolver { +impl BlackBoxFunctionSolver for Bn254BlackBoxSolver { fn schnorr_verify( &self, public_key_x: &FieldElement, diff --git a/acvm-repo/bn254_blackbox_solver/src/pedersen/commitment.rs b/acvm-repo/bn254_blackbox_solver/src/pedersen/commitment.rs index 6769150508a..5ff2c269d8c 100644 --- a/acvm-repo/bn254_blackbox_solver/src/pedersen/commitment.rs +++ b/acvm-repo/bn254_blackbox_solver/src/pedersen/commitment.rs @@ -27,7 +27,7 @@ pub(crate) fn commit_native_with_index( #[cfg(test)] mod test { - use acir::FieldElement; + use acir::{AcirField, FieldElement}; use ark_ec::short_weierstrass::Affine; use ark_std::{One, Zero}; use grumpkin::Fq; diff --git a/acvm-repo/bn254_blackbox_solver/src/pedersen/hash.rs b/acvm-repo/bn254_blackbox_solver/src/pedersen/hash.rs index 28bf354edc9..5c637207491 100644 --- a/acvm-repo/bn254_blackbox_solver/src/pedersen/hash.rs +++ b/acvm-repo/bn254_blackbox_solver/src/pedersen/hash.rs @@ -31,7 +31,7 @@ pub(crate) mod test { use super::*; - use acir::FieldElement; + use acir::{AcirField, FieldElement}; use ark_std::One; use grumpkin::Fq; diff --git a/acvm-repo/bn254_blackbox_solver/src/poseidon2.rs b/acvm-repo/bn254_blackbox_solver/src/poseidon2.rs index 65058e15099..95c620aab0d 100644 --- a/acvm-repo/bn254_blackbox_solver/src/poseidon2.rs +++ b/acvm-repo/bn254_blackbox_solver/src/poseidon2.rs @@ -1,4 +1,4 @@ -use acir::FieldElement; +use acir::{AcirField, FieldElement}; use acvm_blackbox_solver::BlackBoxResolutionError; use lazy_static::lazy_static; @@ -543,7 +543,7 @@ impl<'a> Poseidon2<'a> { #[cfg(test)] mod test { - use acir::FieldElement; + use acir::{AcirField, FieldElement}; use super::{field_from_hex, poseidon2_permutation}; diff --git a/acvm-repo/bn254_blackbox_solver/src/schnorr/mod.rs b/acvm-repo/bn254_blackbox_solver/src/schnorr/mod.rs index cb213726973..62e515a0792 100644 --- a/acvm-repo/bn254_blackbox_solver/src/schnorr/mod.rs +++ b/acvm-repo/bn254_blackbox_solver/src/schnorr/mod.rs @@ -65,7 +65,7 @@ fn schnorr_generate_challenge( #[cfg(test)] mod schnorr_tests { - use acir::FieldElement; + use acir::{AcirField, FieldElement}; use super::verify_signature; diff --git a/acvm-repo/brillig/Cargo.toml b/acvm-repo/brillig/Cargo.toml index f60bde6f074..245767dcecd 100644 --- a/acvm-repo/brillig/Cargo.toml +++ b/acvm-repo/brillig/Cargo.toml @@ -17,6 +17,5 @@ acir_field.workspace = true serde.workspace = true [features] -default = ["bn254"] bn254 = ["acir_field/bn254"] bls12_381 = ["acir_field/bls12_381"] diff --git a/acvm-repo/brillig/src/foreign_call.rs b/acvm-repo/brillig/src/foreign_call.rs index e547b99f0eb..a439d5c3202 100644 --- a/acvm-repo/brillig/src/foreign_call.rs +++ b/acvm-repo/brillig/src/foreign_call.rs @@ -1,34 +1,34 @@ -use acir_field::FieldElement; +use acir_field::AcirField; use serde::{Deserialize, Serialize}; /// Single output of a [foreign call][crate::Opcode::ForeignCall]. #[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone)] -pub enum ForeignCallParam { - Single(FieldElement), - Array(Vec), +pub enum ForeignCallParam { + Single(F), + Array(Vec), } -impl From for ForeignCallParam { - fn from(value: FieldElement) -> Self { +impl From for ForeignCallParam { + fn from(value: F) -> Self { ForeignCallParam::Single(value) } } -impl From> for ForeignCallParam { - fn from(values: Vec) -> Self { +impl From> for ForeignCallParam { + fn from(values: Vec) -> Self { ForeignCallParam::Array(values) } } -impl ForeignCallParam { - pub fn fields(&self) -> Vec { +impl ForeignCallParam { + pub fn fields(&self) -> Vec { match self { ForeignCallParam::Single(value) => vec![*value], - ForeignCallParam::Array(values) => values.clone(), + ForeignCallParam::Array(values) => values.to_vec(), } } - pub fn unwrap_field(&self) -> FieldElement { + pub fn unwrap_field(&self) -> F { match self { ForeignCallParam::Single(value) => *value, ForeignCallParam::Array(_) => panic!("Expected single value, found array"), @@ -38,25 +38,25 @@ impl ForeignCallParam { /// Represents the full output of a [foreign call][crate::Opcode::ForeignCall]. #[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone, Default)] -pub struct ForeignCallResult { +pub struct ForeignCallResult { /// Resolved output values of the foreign call. - pub values: Vec, + pub values: Vec>, } -impl From for ForeignCallResult { - fn from(value: FieldElement) -> Self { +impl From for ForeignCallResult { + fn from(value: F) -> Self { ForeignCallResult { values: vec![value.into()] } } } -impl From> for ForeignCallResult { - fn from(values: Vec) -> Self { +impl From> for ForeignCallResult { + fn from(values: Vec) -> Self { ForeignCallResult { values: vec![values.into()] } } } -impl From> for ForeignCallResult { - fn from(values: Vec) -> Self { +impl From>> for ForeignCallResult { + fn from(values: Vec>) -> Self { ForeignCallResult { values } } } diff --git a/acvm-repo/brillig/src/opcodes.rs b/acvm-repo/brillig/src/opcodes.rs index a060aa83d41..78c6ba8097c 100644 --- a/acvm-repo/brillig/src/opcodes.rs +++ b/acvm-repo/brillig/src/opcodes.rs @@ -1,5 +1,5 @@ use crate::black_box::BlackBoxOp; -use acir_field::FieldElement; +use acir_field::{AcirField, FieldElement}; use serde::{Deserialize, Serialize}; pub type Label = usize; @@ -89,7 +89,7 @@ pub enum ValueOrArray { } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub enum BrilligOpcode { +pub enum BrilligOpcode { /// Takes the fields in addresses `lhs` and `rhs` /// Performs the specified binary operation /// and stores the value in the `result` address. @@ -142,7 +142,7 @@ pub enum BrilligOpcode { Const { destination: MemoryAddress, bit_size: u32, - value: FieldElement, + value: F, }, Return, /// Used to get data from an outside source. diff --git a/acvm-repo/brillig_vm/Cargo.toml b/acvm-repo/brillig_vm/Cargo.toml index 7dd11912449..4735514c9a7 100644 --- a/acvm-repo/brillig_vm/Cargo.toml +++ b/acvm-repo/brillig_vm/Cargo.toml @@ -20,6 +20,5 @@ num-traits.workspace = true thiserror.workspace = true [features] -default = ["bn254"] bn254 = ["acir/bn254"] bls12_381 = ["acir/bls12_381"] diff --git a/acvm-repo/brillig_vm/src/arithmetic.rs b/acvm-repo/brillig_vm/src/arithmetic.rs index c17c019d11c..c88e06e2b94 100644 --- a/acvm-repo/brillig_vm/src/arithmetic.rs +++ b/acvm-repo/brillig_vm/src/arithmetic.rs @@ -1,5 +1,5 @@ use acir::brillig::{BinaryFieldOp, BinaryIntOp}; -use acir::FieldElement; +use acir::AcirField; use num_bigint::BigUint; use num_traits::ToPrimitive; use num_traits::{One, Zero}; @@ -19,36 +19,36 @@ pub(crate) enum BrilligArithmeticError { } /// Evaluate a binary operation on two FieldElement memory values. -pub(crate) fn evaluate_binary_field_op( +pub(crate) fn evaluate_binary_field_op( op: &BinaryFieldOp, - lhs: MemoryValue, - rhs: MemoryValue, -) -> Result { + lhs: MemoryValue, + rhs: MemoryValue, +) -> Result, BrilligArithmeticError> { let MemoryValue::Field(a) = lhs else { return Err(BrilligArithmeticError::MismatchedLhsBitSize { lhs_bit_size: lhs.bit_size(), - op_bit_size: FieldElement::max_num_bits(), + op_bit_size: F::max_num_bits(), }); }; let MemoryValue::Field(b) = rhs else { return Err(BrilligArithmeticError::MismatchedLhsBitSize { lhs_bit_size: rhs.bit_size(), - op_bit_size: FieldElement::max_num_bits(), + op_bit_size: F::max_num_bits(), }); }; Ok(match op { // Perform addition, subtraction, multiplication, and division based on the BinaryOp variant. - BinaryFieldOp::Add => (a + b).into(), - BinaryFieldOp::Sub => (a - b).into(), - BinaryFieldOp::Mul => (a * b).into(), - BinaryFieldOp::Div => (a / b).into(), + BinaryFieldOp::Add => MemoryValue::new_field(a + b), + BinaryFieldOp::Sub => MemoryValue::new_field(a - b), + BinaryFieldOp::Mul => MemoryValue::new_field(a * b), + BinaryFieldOp::Div => MemoryValue::new_field(a / b), BinaryFieldOp::IntegerDiv => { let a_big = BigUint::from_bytes_be(&a.to_be_bytes()); let b_big = BigUint::from_bytes_be(&b.to_be_bytes()); let result = a_big / b_big; - FieldElement::from_be_bytes_reduce(&result.to_bytes_be()).into() + MemoryValue::new_field(F::from_be_bytes_reduce(&result.to_bytes_be())) } BinaryFieldOp::Equals => (a == b).into(), BinaryFieldOp::LessThan => (a < b).into(), @@ -57,12 +57,12 @@ pub(crate) fn evaluate_binary_field_op( } /// Evaluate a binary operation on two unsigned big integers with a given bit size. -pub(crate) fn evaluate_binary_int_op( +pub(crate) fn evaluate_binary_int_op( op: &BinaryIntOp, - lhs: MemoryValue, - rhs: MemoryValue, + lhs: MemoryValue, + rhs: MemoryValue, bit_size: u32, -) -> Result { +) -> Result, BrilligArithmeticError> { let lhs = lhs.expect_integer_with_bit_size(bit_size).map_err(|err| match err { MemoryTypeError::MismatchedBitSize { value_bit_size, expected_bit_size } => { BrilligArithmeticError::MismatchedLhsBitSize { @@ -82,7 +82,7 @@ pub(crate) fn evaluate_binary_int_op( } })?; - if bit_size == FieldElement::max_num_bits() { + if bit_size == F::max_num_bits() { return Err(BrilligArithmeticError::IntegerOperationOnField { op: *op }); } @@ -155,6 +155,7 @@ pub(crate) fn evaluate_binary_int_op( #[cfg(test)] mod tests { use super::*; + use acir::{AcirField, FieldElement}; struct TestParams { a: u128, @@ -163,7 +164,7 @@ mod tests { } fn evaluate_u128(op: &BinaryIntOp, a: u128, b: u128, bit_size: u32) -> u128 { - let result_value = evaluate_binary_int_op( + let result_value: MemoryValue = evaluate_binary_int_op( op, MemoryValue::new_integer(a.into(), bit_size), MemoryValue::new_integer(b.into(), bit_size), diff --git a/acvm-repo/brillig_vm/src/black_box.rs b/acvm-repo/brillig_vm/src/black_box.rs index ebaa6976283..2053f4e7c86 100644 --- a/acvm-repo/brillig_vm/src/black_box.rs +++ b/acvm-repo/brillig_vm/src/black_box.rs @@ -1,5 +1,5 @@ use acir::brillig::{BlackBoxOp, HeapArray, HeapVector}; -use acir::{BlackBoxFunc, FieldElement}; +use acir::{AcirField, BlackBoxFunc}; use acvm_blackbox_solver::BigIntSolver; use acvm_blackbox_solver::{ aes128_encrypt, blake2s, blake3, ecdsa_secp256k1_verify, ecdsa_secp256r1_verify, keccak256, @@ -10,17 +10,23 @@ use num_bigint::BigUint; use crate::memory::MemoryValue; use crate::Memory; -fn read_heap_vector<'a>(memory: &'a Memory, vector: &HeapVector) -> &'a [MemoryValue] { +fn read_heap_vector<'a, F: AcirField>( + memory: &'a Memory, + vector: &HeapVector, +) -> &'a [MemoryValue] { let size = memory.read(vector.size); memory.read_slice(memory.read_ref(vector.pointer), size.to_usize()) } -fn read_heap_array<'a>(memory: &'a Memory, array: &HeapArray) -> &'a [MemoryValue] { +fn read_heap_array<'a, F: AcirField>( + memory: &'a Memory, + array: &HeapArray, +) -> &'a [MemoryValue] { memory.read_slice(memory.read_ref(array.pointer), array.size) } /// Extracts the last byte of every value -fn to_u8_vec(inputs: &[MemoryValue]) -> Vec { +fn to_u8_vec(inputs: &[MemoryValue]) -> Vec { let mut result = Vec::with_capacity(inputs.len()); for input in inputs { result.push(input.try_into().unwrap()); @@ -28,14 +34,14 @@ fn to_u8_vec(inputs: &[MemoryValue]) -> Vec { result } -fn to_value_vec(input: &[u8]) -> Vec { +fn to_value_vec(input: &[u8]) -> Vec> { input.iter().map(|&x| x.into()).collect() } -pub(crate) fn evaluate_black_box( +pub(crate) fn evaluate_black_box>( op: &BlackBoxOp, solver: &Solver, - memory: &mut Memory, + memory: &mut Memory, bigint_solver: &mut BigIntSolver, ) -> Result<(), BlackBoxResolutionError> { match op { @@ -91,7 +97,7 @@ pub(crate) fn evaluate_black_box( let new_state = keccakf1600(state)?; - let new_state: Vec = new_state.into_iter().map(|x| x.into()).collect(); + let new_state: Vec> = new_state.into_iter().map(|x| x.into()).collect(); memory.write_slice(memory.read_ref(output.pointer), &new_state); Ok(()) } @@ -146,8 +152,8 @@ pub(crate) fn evaluate_black_box( Ok(()) } BlackBoxOp::SchnorrVerify { public_key_x, public_key_y, message, signature, result } => { - let public_key_x = memory.read(*public_key_x).try_into().unwrap(); - let public_key_y = memory.read(*public_key_y).try_into().unwrap(); + let public_key_x = *memory.read(*public_key_x).extract_field().unwrap(); + let public_key_y = *memory.read(*public_key_y).extract_field().unwrap(); let message: Vec = to_u8_vec(read_heap_vector(memory, message)); let signature: [u8; 64] = to_u8_vec(read_heap_vector(memory, signature)).try_into().unwrap(); @@ -157,20 +163,22 @@ pub(crate) fn evaluate_black_box( Ok(()) } BlackBoxOp::MultiScalarMul { points, scalars, outputs: result } => { - let points: Vec = read_heap_vector(memory, points) + let points: Vec = read_heap_vector(memory, points) .iter() .enumerate() .map(|(i, x)| { if i % 3 == 2 { let is_infinite: bool = x.try_into().unwrap(); - FieldElement::from(is_infinite as u128) + F::from(is_infinite as u128) } else { - x.try_into().unwrap() + *x.extract_field().unwrap() } }) .collect(); - let scalars: Vec = - read_heap_vector(memory, scalars).iter().map(|x| x.try_into().unwrap()).collect(); + let scalars: Vec = read_heap_vector(memory, scalars) + .iter() + .map(|x| *x.extract_field().unwrap()) + .collect(); let mut scalars_lo = Vec::with_capacity(scalars.len() / 2); let mut scalars_hi = Vec::with_capacity(scalars.len() / 2); for (i, scalar) in scalars.iter().enumerate() { @@ -183,7 +191,11 @@ pub(crate) fn evaluate_black_box( let (x, y, is_infinite) = solver.multi_scalar_mul(&points, &scalars_lo, &scalars_hi)?; memory.write_slice( memory.read_ref(result.pointer), - &[x.into(), y.into(), is_infinite.into()], + &[ + MemoryValue::new_field(x), + MemoryValue::new_field(y), + MemoryValue::new_field(is_infinite), + ], ); Ok(()) } @@ -196,11 +208,11 @@ pub(crate) fn evaluate_black_box( input1_infinite, input2_infinite, } => { - let input1_x = memory.read(*input1_x).try_into().unwrap(); - let input1_y = memory.read(*input1_y).try_into().unwrap(); + let input1_x = *memory.read(*input1_x).extract_field().unwrap(); + let input1_y = *memory.read(*input1_y).extract_field().unwrap(); let input1_infinite: bool = memory.read(*input1_infinite).try_into().unwrap(); - let input2_x = memory.read(*input2_x).try_into().unwrap(); - let input2_y = memory.read(*input2_y).try_into().unwrap(); + let input2_x = *memory.read(*input2_x).extract_field().unwrap(); + let input2_y = *memory.read(*input2_y).extract_field().unwrap(); let input2_infinite: bool = memory.read(*input2_infinite).try_into().unwrap(); let (x, y, infinite) = solver.ec_add( &input1_x, @@ -212,13 +224,19 @@ pub(crate) fn evaluate_black_box( )?; memory.write_slice( memory.read_ref(result.pointer), - &[x.into(), y.into(), infinite.into()], + &[ + MemoryValue::new_field(x), + MemoryValue::new_field(y), + MemoryValue::new_field(infinite), + ], ); Ok(()) } BlackBoxOp::PedersenCommitment { inputs, domain_separator, output } => { - let inputs: Vec = - read_heap_vector(memory, inputs).iter().map(|x| x.try_into().unwrap()).collect(); + let inputs: Vec = read_heap_vector(memory, inputs) + .iter() + .map(|x| *x.extract_field().unwrap()) + .collect(); let domain_separator: u32 = memory.read(*domain_separator).try_into().map_err(|_| { BlackBoxResolutionError::Failed( @@ -227,12 +245,17 @@ pub(crate) fn evaluate_black_box( ) })?; let (x, y) = solver.pedersen_commitment(&inputs, domain_separator)?; - memory.write_slice(memory.read_ref(output.pointer), &[x.into(), y.into()]); + memory.write_slice( + memory.read_ref(output.pointer), + &[MemoryValue::new_field(x), MemoryValue::new_field(y)], + ); Ok(()) } BlackBoxOp::PedersenHash { inputs, domain_separator, output } => { - let inputs: Vec = - read_heap_vector(memory, inputs).iter().map(|x| x.try_into().unwrap()).collect(); + let inputs: Vec = read_heap_vector(memory, inputs) + .iter() + .map(|x| *x.extract_field().unwrap()) + .collect(); let domain_separator: u32 = memory.read(*domain_separator).try_into().map_err(|_| { BlackBoxResolutionError::Failed( @@ -241,7 +264,7 @@ pub(crate) fn evaluate_black_box( ) })?; let hash = solver.pedersen_hash(&inputs, domain_separator)?; - memory.write(*output, hash.into()); + memory.write(*output, MemoryValue::new_field(hash)); Ok(()) } BlackBoxOp::BigIntAdd { lhs, rhs, output } => { @@ -297,12 +320,12 @@ pub(crate) fn evaluate_black_box( } BlackBoxOp::Poseidon2Permutation { message, output, len } => { let input = read_heap_vector(memory, message); - let input: Vec = input.iter().map(|x| x.try_into().unwrap()).collect(); + let input: Vec = input.iter().map(|x| *x.extract_field().unwrap()).collect(); let len = memory.read(*len).try_into().unwrap(); let result = solver.poseidon2_permutation(&input, len)?; let mut values = Vec::new(); for i in result { - values.push(i.into()); + values.push(MemoryValue::new_field(i)); } memory.write_slice(memory.read_ref(output.pointer), &values); Ok(()) @@ -338,17 +361,16 @@ pub(crate) fn evaluate_black_box( Ok(()) } BlackBoxOp::ToRadix { input, radix, output } => { - let input: FieldElement = - memory.read(*input).try_into().expect("ToRadix input not a field"); + let input: F = *memory.read(*input).extract_field().expect("ToRadix input not a field"); let mut input = BigUint::from_bytes_be(&input.to_be_bytes()); let radix = BigUint::from(*radix); - let mut limbs: Vec = Vec::with_capacity(output.size); + let mut limbs: Vec> = Vec::with_capacity(output.size); for _ in 0..output.size { let limb = &input % &radix; - limbs.push(FieldElement::from_be_bytes_reduce(&limb.to_bytes_be()).into()); + limbs.push(MemoryValue::new_field(F::from_be_bytes_reduce(&limb.to_bytes_be()))); input /= &radix; } @@ -388,7 +410,10 @@ fn black_box_function_from_op(op: &BlackBoxOp) -> BlackBoxFunc { #[cfg(test)] mod test { - use acir::brillig::{BlackBoxOp, MemoryAddress}; + use acir::{ + brillig::{BlackBoxOp, MemoryAddress}, + FieldElement, + }; use acvm_blackbox_solver::{BigIntSolver, StubbedBlackBoxSolver}; use crate::{ @@ -401,7 +426,7 @@ mod test { let message: Vec = b"hello world".to_vec(); let message_length = message.len(); - let mut memory = Memory::default(); + let mut memory: Memory = Memory::default(); let message_pointer = 3; let result_pointer = message_pointer + message_length; memory.write(MemoryAddress(0), message_pointer.into()); diff --git a/acvm-repo/brillig_vm/src/lib.rs b/acvm-repo/brillig_vm/src/lib.rs index 7901c313596..aaf55056589 100644 --- a/acvm-repo/brillig_vm/src/lib.rs +++ b/acvm-repo/brillig_vm/src/lib.rs @@ -15,7 +15,7 @@ use acir::brillig::{ BinaryFieldOp, BinaryIntOp, ForeignCallParam, ForeignCallResult, HeapArray, HeapValueType, HeapVector, MemoryAddress, Opcode, ValueOrArray, }; -use acir::FieldElement; +use acir::AcirField; use acvm_blackbox_solver::{BigIntSolver, BlackBoxFunctionSolver}; use arithmetic::{evaluate_binary_field_op, evaluate_binary_int_op, BrilligArithmeticError}; use black_box::evaluate_black_box; @@ -39,7 +39,7 @@ pub enum FailureReason { } #[derive(Debug, PartialEq, Eq, Clone)] -pub enum VMStatus { +pub enum VMStatus { Finished { return_data_offset: usize, return_data_size: usize, @@ -60,15 +60,15 @@ pub enum VMStatus { function: String, /// Input values /// Each input is a list of values as an input can be either a single value or a memory pointer - inputs: Vec, + inputs: Vec>, }, } #[derive(Debug, PartialEq, Eq, Clone)] /// VM encapsulates the state of the Brillig VM during execution. -pub struct VM<'a, B: BlackBoxFunctionSolver> { +pub struct VM<'a, F, B: BlackBoxFunctionSolver> { /// Calldata to the brillig function - calldata: Vec, + calldata: Vec, /// Instruction pointer program_counter: usize, /// A counter maintained throughout a Brillig process that determines @@ -76,13 +76,13 @@ pub struct VM<'a, B: BlackBoxFunctionSolver> { foreign_call_counter: usize, /// Represents the outputs of all foreign calls during a Brillig process /// List is appended onto by the caller upon reaching a [VMStatus::ForeignCallWait] - foreign_call_results: Vec, + foreign_call_results: Vec>, /// Executable opcodes - bytecode: &'a [Opcode], + bytecode: &'a [Opcode], /// Status of the VM - status: VMStatus, + status: VMStatus, /// Memory of the VM - memory: Memory, + memory: Memory, /// Call stack call_stack: Vec, /// The solver for blackbox functions @@ -91,12 +91,12 @@ pub struct VM<'a, B: BlackBoxFunctionSolver> { bigint_solver: BigIntSolver, } -impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { +impl<'a, F: AcirField, B: BlackBoxFunctionSolver> VM<'a, F, B> { /// Constructs a new VM instance pub fn new( - calldata: Vec, - bytecode: &'a [Opcode], - foreign_call_results: Vec, + calldata: Vec, + bytecode: &'a [Opcode], + foreign_call_results: Vec>, black_box_solver: &'a B, ) -> Self { Self { @@ -115,17 +115,17 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { /// Updates the current status of the VM. /// Returns the given status. - fn status(&mut self, status: VMStatus) -> VMStatus { + fn status(&mut self, status: VMStatus) -> VMStatus { self.status = status.clone(); status } - pub fn get_status(&self) -> VMStatus { + pub fn get_status(&self) -> VMStatus { self.status.clone() } /// Sets the current status of the VM to Finished (completed execution). - fn finish(&mut self, return_data_offset: usize, return_data_size: usize) -> VMStatus { + fn finish(&mut self, return_data_offset: usize, return_data_size: usize) -> VMStatus { self.status(VMStatus::Finished { return_data_offset, return_data_size }) } @@ -134,12 +134,12 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { fn wait_for_foreign_call( &mut self, function: String, - inputs: Vec, - ) -> VMStatus { + inputs: Vec>, + ) -> VMStatus { self.status(VMStatus::ForeignCallWait { function, inputs }) } - pub fn resolve_foreign_call(&mut self, foreign_call_result: ForeignCallResult) { + pub fn resolve_foreign_call(&mut self, foreign_call_result: ForeignCallResult) { if self.foreign_call_counter < self.foreign_call_results.len() { panic!("No unresolved foreign calls"); } @@ -156,7 +156,7 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { /// Sets the current status of the VM to `fail`. /// Indicating that the VM encountered a `Trap` Opcode /// or an invalid state. - fn trap(&mut self, revert_data_offset: usize, revert_data_size: usize) -> VMStatus { + fn trap(&mut self, revert_data_offset: usize, revert_data_size: usize) -> VMStatus { self.status(VMStatus::Failure { call_stack: self.get_error_stack(), reason: FailureReason::Trap { revert_data_offset, revert_data_size }, @@ -164,7 +164,7 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { self.status.clone() } - fn fail(&mut self, message: String) -> VMStatus { + fn fail(&mut self, message: String) -> VMStatus { self.status(VMStatus::Failure { call_stack: self.get_error_stack(), reason: FailureReason::RuntimeError { message }, @@ -173,7 +173,7 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { } /// Loop over the bytecode and update the program counter - pub fn process_opcodes(&mut self) -> VMStatus { + pub fn process_opcodes(&mut self) -> VMStatus { while !matches!( self.process_opcode(), VMStatus::Finished { .. } | VMStatus::Failure { .. } | VMStatus::ForeignCallWait { .. } @@ -181,11 +181,11 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { self.status.clone() } - pub fn get_memory(&self) -> &[MemoryValue] { + pub fn get_memory(&self) -> &[MemoryValue] { self.memory.values() } - pub fn write_memory_at(&mut self, ptr: usize, value: MemoryValue) { + pub fn write_memory_at(&mut self, ptr: usize, value: MemoryValue) { self.memory.write(MemoryAddress(ptr), value); } @@ -196,7 +196,7 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { } /// Process a single opcode and modify the program counter. - pub fn process_opcode(&mut self) -> VMStatus { + pub fn process_opcode(&mut self) -> VMStatus { let opcode = &self.bytecode[self.program_counter]; match opcode { Opcode::BinaryFieldOp { op, lhs, rhs, destination: result } => { @@ -360,14 +360,14 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { } /// Increments the program counter by 1. - fn increment_program_counter(&mut self) -> VMStatus { + fn increment_program_counter(&mut self) -> VMStatus { self.set_program_counter(self.program_counter + 1) } /// Increments the program counter by `value`. /// If the program counter no longer points to an opcode /// in the bytecode, then the VMStatus reports halted. - fn set_program_counter(&mut self, value: usize) -> VMStatus { + fn set_program_counter(&mut self, value: usize) -> VMStatus { assert!(self.program_counter < self.bytecode.len()); self.program_counter = value; if self.program_counter >= self.bytecode.len() { @@ -380,10 +380,10 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { &self, input: ValueOrArray, value_type: &HeapValueType, - ) -> ForeignCallParam { + ) -> ForeignCallParam { match (input, value_type) { (ValueOrArray::MemoryAddress(value_index), HeapValueType::Simple(_)) => { - self.memory.read(value_index).to_field().into() + ForeignCallParam::Single(self.memory.read(value_index).to_field()) } ( ValueOrArray::HeapArray(HeapArray { pointer: pointer_index, size }), @@ -421,7 +421,7 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { start: MemoryAddress, size: usize, value_types: &[HeapValueType], - ) -> Vec { + ) -> Vec> { if HeapValueType::all_simple(value_types) { self.memory.read_slice(start, size).to_vec() } else { @@ -618,7 +618,7 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { } /// Casts a value to a different bit size. - fn cast(&self, bit_size: u32, source_value: MemoryValue) -> MemoryValue { + fn cast(&self, bit_size: u32, source_value: MemoryValue) -> MemoryValue { let lhs_big = source_value.to_integer(); let mask = BigUint::from(2_u32).pow(bit_size) - 1_u32; MemoryValue::new_from_integer(lhs_big & mask, bit_size) @@ -627,6 +627,7 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { #[cfg(test)] mod tests { + use acir::{AcirField, FieldElement}; use acvm_blackbox_solver::StubbedBlackBoxSolver; use super::*; @@ -664,7 +665,7 @@ mod tests { #[test] fn jmpif_opcode() { - let mut calldata = vec![]; + let mut calldata: Vec = vec![]; let mut opcodes = vec![]; let lhs = { @@ -709,7 +710,7 @@ mod tests { #[test] fn jmpifnot_opcode() { - let calldata = vec![1u128.into(), 2u128.into()]; + let calldata: Vec = vec![1u128.into(), 2u128.into()]; let calldata_copy = Opcode::CalldataCopy { destination_address: MemoryAddress::from(0), @@ -779,7 +780,7 @@ mod tests { #[test] fn cast_opcode() { - let calldata = vec![((2_u128.pow(32)) - 1).into()]; + let calldata: Vec = vec![((2_u128.pow(32)) - 1).into()]; let opcodes = &[ Opcode::CalldataCopy { @@ -813,7 +814,7 @@ mod tests { #[test] fn mov_opcode() { - let calldata = vec![(1u128).into(), (2u128).into(), (3u128).into()]; + let calldata: Vec = vec![(1u128).into(), (2u128).into(), (3u128).into()]; let calldata_copy = Opcode::CalldataCopy { destination_address: MemoryAddress::from(0), @@ -844,7 +845,8 @@ mod tests { #[test] fn cmov_opcode() { - let calldata = vec![(0u128).into(), (1u128).into(), (2u128).into(), (3u128).into()]; + let calldata: Vec = + vec![(0u128).into(), (1u128).into(), (2u128).into(), (3u128).into()]; let calldata_copy = Opcode::CalldataCopy { destination_address: MemoryAddress::from(0), @@ -910,7 +912,7 @@ mod tests { #[test] fn cmp_binary_ops() { let bit_size = 32; - let calldata = + let calldata: Vec = vec![(2u128).into(), (2u128).into(), (0u128).into(), (5u128).into(), (6u128).into()]; let calldata_size = calldata.len(); @@ -1010,14 +1012,14 @@ mod tests { /// memory[i] = i as Value; /// i += 1; /// } - fn brillig_write_memory(item_count: usize) -> Vec { + fn brillig_write_memory(item_count: usize) -> Vec> { let bit_size = 64; let r_i = MemoryAddress::from(0); let r_len = MemoryAddress::from(1); let r_tmp = MemoryAddress::from(2); let r_pointer = MemoryAddress::from(3); - let start = [ + let start: [Opcode; 3] = [ // i = 0 Opcode::Const { destination: r_i, value: 0u128.into(), bit_size }, // len = memory.len() (approximation) @@ -1091,7 +1093,7 @@ mod tests { let r_tmp = MemoryAddress::from(3); let r_pointer = MemoryAddress::from(4); - let start = [ + let start: [Opcode; 5] = [ // sum = 0 Opcode::Const { destination: r_sum, @@ -1179,18 +1181,18 @@ mod tests { /// recursive_write(memory, i + 1, len); /// } /// Note we represent a 100% in-stack optimized form in brillig - fn brillig_recursive_write_memory(size: usize) -> Vec { + fn brillig_recursive_write_memory(size: usize) -> Vec> { let bit_size = 64; let r_i = MemoryAddress::from(0); let r_len = MemoryAddress::from(1); let r_tmp = MemoryAddress::from(2); let r_pointer = MemoryAddress::from(3); - let start = [ + let start: [Opcode; 5] = [ // i = 0 Opcode::Const { destination: r_i, value: 0u128.into(), bit_size }, // len = size - Opcode::Const { destination: r_len, value: size.into(), bit_size }, + Opcode::Const { destination: r_len, value: (size as u128).into(), bit_size }, // pointer = free_memory_ptr Opcode::Const { destination: r_pointer, value: 4u128.into(), bit_size }, // call recursive_fn @@ -1245,28 +1247,28 @@ mod tests { vm.get_memory()[4..].to_vec() } - let memory = brillig_recursive_write_memory(5); + let memory = brillig_recursive_write_memory::(5); let expected = vec![(0u64).into(), (1u64).into(), (2u64).into(), (3u64).into(), (4u64).into()]; assert_eq!(memory, expected); - let memory = brillig_recursive_write_memory(1024); + let memory = brillig_recursive_write_memory::(1024); let expected: Vec<_> = (0..1024).map(|i: u64| i.into()).collect(); assert_eq!(memory, expected); } /// Helper to execute brillig code - fn brillig_execute_and_get_vm( - calldata: Vec, - opcodes: &[Opcode], - ) -> VM<'_, StubbedBlackBoxSolver> { + fn brillig_execute_and_get_vm( + calldata: Vec, + opcodes: &[Opcode], + ) -> VM<'_, F, StubbedBlackBoxSolver> { let mut vm = VM::new(calldata, opcodes, vec![], &StubbedBlackBoxSolver); brillig_execute(&mut vm); assert_eq!(vm.call_stack, vec![]); vm } - fn brillig_execute(vm: &mut VM) { + fn brillig_execute(vm: &mut VM) { loop { let status = vm.process_opcode(); if matches!(status, VMStatus::Finished { .. } | VMStatus::ForeignCallWait { .. }) { @@ -1330,7 +1332,8 @@ mod tests { let r_output = MemoryAddress::from(1); // Define a simple 2x2 matrix in memory - let initial_matrix = vec![(1u128).into(), (2u128).into(), (3u128).into(), (4u128).into()]; + let initial_matrix: Vec = + vec![(1u128).into(), (2u128).into(), (3u128).into(), (4u128).into()]; // Transpose of the matrix (but arbitrary for this test, the 'correct value') let expected_result: Vec = @@ -1505,7 +1508,8 @@ mod tests { let r_output = MemoryAddress::from(1); // Define a simple 2x2 matrix in memory - let initial_matrix = vec![(1u128).into(), (2u128).into(), (3u128).into(), (4u128).into()]; + let initial_matrix: Vec = + vec![(1u128).into(), (2u128).into(), (3u128).into(), (4u128).into()]; // Transpose of the matrix (but arbitrary for this test, the 'correct value') let expected_result: Vec = @@ -1592,9 +1596,11 @@ mod tests { let r_output = MemoryAddress::from(2); // Define a simple 2x2 matrix in memory - let matrix_a = vec![(1u128).into(), (2u128).into(), (3u128).into(), (4u128).into()]; + let matrix_a: Vec = + vec![(1u128).into(), (2u128).into(), (3u128).into(), (4u128).into()]; - let matrix_b = vec![(10u128).into(), (11u128).into(), (12u128).into(), (13u128).into()]; + let matrix_b: Vec = + vec![(10u128).into(), (11u128).into(), (12u128).into(), (13u128).into()]; // Transpose of the matrix (but arbitrary for this test, the 'correct value') let expected_result: Vec = @@ -1678,17 +1684,19 @@ mod tests { fn foreign_call_opcode_nested_arrays_and_slices_input() { // [(1, <2,3>, [4]), (5, <6,7,8>, [9])] - let v2: Vec = vec![ - MemoryValue::from(FieldElement::from(2u128)), - MemoryValue::from(FieldElement::from(3u128)), + let v2: Vec> = vec![ + MemoryValue::new_field(FieldElement::from(2u128)), + MemoryValue::new_field(FieldElement::from(3u128)), ]; - let a4: Vec = vec![FieldElement::from(4u128).into()]; - let v6: Vec = vec![ - MemoryValue::from(FieldElement::from(6u128)), - MemoryValue::from(FieldElement::from(7u128)), - MemoryValue::from(FieldElement::from(8u128)), + let a4: Vec> = + vec![MemoryValue::new_field(FieldElement::from(4u128))]; + let v6: Vec> = vec![ + MemoryValue::new_field(FieldElement::from(6u128)), + MemoryValue::new_field(FieldElement::from(7u128)), + MemoryValue::new_field(FieldElement::from(8u128)), ]; - let a9: Vec = vec![FieldElement::from(9u128).into()]; + let a9: Vec> = + vec![MemoryValue::new_field(FieldElement::from(9u128))]; // construct memory by declaring all inner arrays/vectors first let v2_ptr: usize = 0usize; @@ -1710,11 +1718,11 @@ mod tests { // finally we add the contents of the outer array let outer_ptr = memory.len(); let outer_array = vec![ - MemoryValue::from(FieldElement::from(1u128)), + MemoryValue::new_field(FieldElement::from(1u128)), MemoryValue::from(v2.len()), MemoryValue::from(v2_start), MemoryValue::from(a4_start), - MemoryValue::from(FieldElement::from(5u128)), + MemoryValue::new_field(FieldElement::from(5u128)), MemoryValue::from(v6.len()), MemoryValue::from(v6_start), MemoryValue::from(a9_start), @@ -1801,7 +1809,7 @@ mod tests { // Check result let result_value = vm.memory.read(r_output); - assert_eq!(result_value, MemoryValue::from(FieldElement::from(45u128))); + assert_eq!(result_value, MemoryValue::new_field(FieldElement::from(45u128))); // Ensure the foreign call counter has been incremented assert_eq!(vm.foreign_call_counter, 1); diff --git a/acvm-repo/brillig_vm/src/memory.rs b/acvm-repo/brillig_vm/src/memory.rs index feeb3706bde..4092cd06ae0 100644 --- a/acvm-repo/brillig_vm/src/memory.rs +++ b/acvm-repo/brillig_vm/src/memory.rs @@ -1,12 +1,12 @@ -use acir::{brillig::MemoryAddress, FieldElement}; +use acir::{brillig::MemoryAddress, AcirField}; use num_bigint::BigUint; use num_traits::{One, Zero}; pub const MEMORY_ADDRESSING_BIT_SIZE: u32 = 64; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub enum MemoryValue { - Field(FieldElement), +pub enum MemoryValue { + Field(F), Integer(BigUint, u32), } @@ -16,10 +16,10 @@ pub enum MemoryTypeError { MismatchedBitSize { value_bit_size: u32, expected_bit_size: u32 }, } -impl MemoryValue { +impl MemoryValue { /// Builds a memory value from a field element. - pub fn new_from_field(value: FieldElement, bit_size: u32) -> Self { - if bit_size == FieldElement::max_num_bits() { + pub fn new_from_field(value: F, bit_size: u32) -> Self { + if bit_size == F::max_num_bits() { MemoryValue::new_field(value) } else { MemoryValue::new_integer(BigUint::from_bytes_be(&value.to_be_bytes()), bit_size) @@ -28,16 +28,16 @@ impl MemoryValue { /// Builds a memory value from an integer pub fn new_from_integer(value: BigUint, bit_size: u32) -> Self { - if bit_size == FieldElement::max_num_bits() { - MemoryValue::new_field(FieldElement::from_be_bytes_reduce(&value.to_bytes_be())) + if bit_size == F::max_num_bits() { + MemoryValue::new_field(F::from_be_bytes_reduce(&value.to_bytes_be())) } else { MemoryValue::new_integer(value, bit_size) } } /// Builds a memory value from a field element, checking that the value is within the bit size. - pub fn new_checked(value: FieldElement, bit_size: u32) -> Option { - if bit_size < FieldElement::max_num_bits() && value.num_bits() > bit_size { + pub fn new_checked(value: F, bit_size: u32) -> Option { + if bit_size < F::max_num_bits() && value.num_bits() > bit_size { return None; } @@ -45,21 +45,21 @@ impl MemoryValue { } /// Builds a field-typed memory value. - pub fn new_field(value: FieldElement) -> Self { + pub fn new_field(value: F) -> Self { MemoryValue::Field(value) } /// Builds an integer-typed memory value. pub fn new_integer(value: BigUint, bit_size: u32) -> Self { assert!( - bit_size != FieldElement::max_num_bits(), + bit_size != F::max_num_bits(), "Tried to build a field memory value via new_integer" ); MemoryValue::Integer(value, bit_size) } /// Extracts the field element from the memory value, if it is typed as field element. - pub fn extract_field(&self) -> Option<&FieldElement> { + pub fn extract_field(&self) -> Option<&F> { match self { MemoryValue::Field(value) => Some(value), _ => None, @@ -75,12 +75,10 @@ impl MemoryValue { } /// Converts the memory value to a field element, independent of its type. - pub fn to_field(&self) -> FieldElement { + pub fn to_field(&self) -> F { match self { MemoryValue::Field(value) => *value, - MemoryValue::Integer(value, _) => { - FieldElement::from_be_bytes_reduce(&value.to_bytes_be()) - } + MemoryValue::Integer(value, _) => F::from_be_bytes_reduce(&value.to_bytes_be()), } } @@ -94,7 +92,7 @@ impl MemoryValue { pub fn bit_size(&self) -> u32 { match self { - MemoryValue::Field(_) => FieldElement::max_num_bits(), + MemoryValue::Field(_) => F::max_num_bits(), MemoryValue::Integer(_, bit_size) => *bit_size, } } @@ -107,11 +105,11 @@ impl MemoryValue { self.extract_integer().unwrap().0.try_into().unwrap() } - pub fn expect_field(&self) -> Result<&FieldElement, MemoryTypeError> { + pub fn expect_field(&self) -> Result<&F, MemoryTypeError> { match self { MemoryValue::Integer(_, bit_size) => Err(MemoryTypeError::MismatchedBitSize { value_bit_size: *bit_size, - expected_bit_size: FieldElement::max_num_bits(), + expected_bit_size: F::max_num_bits(), }), MemoryValue::Field(field) => Ok(field), } @@ -132,14 +130,14 @@ impl MemoryValue { Ok(value) } MemoryValue::Field(_) => Err(MemoryTypeError::MismatchedBitSize { - value_bit_size: FieldElement::max_num_bits(), + value_bit_size: F::max_num_bits(), expected_bit_size, }), } } } -impl std::fmt::Display for MemoryValue { +impl std::fmt::Display for MemoryValue { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { match self { MemoryValue::Field(value) => write!(f, "{}: field", value), @@ -155,85 +153,71 @@ impl std::fmt::Display for MemoryValue { } } -impl Default for MemoryValue { +impl Default for MemoryValue { fn default() -> Self { MemoryValue::new_integer(BigUint::zero(), 0) } } -impl From for MemoryValue { - fn from(field: FieldElement) -> Self { - MemoryValue::new_field(field) - } -} - -impl From for MemoryValue { +impl From for MemoryValue { fn from(value: usize) -> Self { MemoryValue::new_integer(value.into(), MEMORY_ADDRESSING_BIT_SIZE) } } -impl From for MemoryValue { +impl From for MemoryValue { fn from(value: u64) -> Self { MemoryValue::new_integer(value.into(), 64) } } -impl From for MemoryValue { +impl From for MemoryValue { fn from(value: u32) -> Self { MemoryValue::new_integer(value.into(), 32) } } -impl From for MemoryValue { +impl From for MemoryValue { fn from(value: u8) -> Self { MemoryValue::new_integer(value.into(), 8) } } -impl From for MemoryValue { +impl From for MemoryValue { fn from(value: bool) -> Self { let value = if value { BigUint::one() } else { BigUint::zero() }; MemoryValue::new_integer(value, 1) } } -impl TryFrom for FieldElement { - type Error = MemoryTypeError; - - fn try_from(memory_value: MemoryValue) -> Result { - memory_value.expect_field().copied() - } -} - -impl TryFrom for u64 { +impl TryFrom> for u64 { type Error = MemoryTypeError; - fn try_from(memory_value: MemoryValue) -> Result { + fn try_from(memory_value: MemoryValue) -> Result { memory_value.expect_integer_with_bit_size(64).map(|value| value.try_into().unwrap()) } } -impl TryFrom for u32 { +impl TryFrom> for u32 { type Error = MemoryTypeError; - fn try_from(memory_value: MemoryValue) -> Result { + fn try_from(memory_value: MemoryValue) -> Result { memory_value.expect_integer_with_bit_size(32).map(|value| value.try_into().unwrap()) } } -impl TryFrom for u8 { +impl TryFrom> for u8 { type Error = MemoryTypeError; - fn try_from(memory_value: MemoryValue) -> Result { + fn try_from(memory_value: MemoryValue) -> Result { memory_value.expect_integer_with_bit_size(8).map(|value| value.try_into().unwrap()) } } -impl TryFrom for bool { +impl TryFrom> for bool { type Error = MemoryTypeError; - fn try_from(memory_value: MemoryValue) -> Result { + fn try_from(memory_value: MemoryValue) -> Result { let as_integer = memory_value.expect_integer_with_bit_size(1)?; if as_integer.is_zero() { @@ -246,48 +230,40 @@ impl TryFrom for bool { } } -impl TryFrom<&MemoryValue> for FieldElement { - type Error = MemoryTypeError; - - fn try_from(memory_value: &MemoryValue) -> Result { - memory_value.expect_field().copied() - } -} - -impl TryFrom<&MemoryValue> for u64 { +impl TryFrom<&MemoryValue> for u64 { type Error = MemoryTypeError; - fn try_from(memory_value: &MemoryValue) -> Result { + fn try_from(memory_value: &MemoryValue) -> Result { memory_value.expect_integer_with_bit_size(64).map(|value| { value.try_into().expect("memory_value has been asserted to contain a 64 bit integer") }) } } -impl TryFrom<&MemoryValue> for u32 { +impl TryFrom<&MemoryValue> for u32 { type Error = MemoryTypeError; - fn try_from(memory_value: &MemoryValue) -> Result { + fn try_from(memory_value: &MemoryValue) -> Result { memory_value.expect_integer_with_bit_size(32).map(|value| { value.try_into().expect("memory_value has been asserted to contain a 32 bit integer") }) } } -impl TryFrom<&MemoryValue> for u8 { +impl TryFrom<&MemoryValue> for u8 { type Error = MemoryTypeError; - fn try_from(memory_value: &MemoryValue) -> Result { + fn try_from(memory_value: &MemoryValue) -> Result { memory_value.expect_integer_with_bit_size(8).map(|value| { value.try_into().expect("memory_value has been asserted to contain an 8 bit integer") }) } } -impl TryFrom<&MemoryValue> for bool { +impl TryFrom<&MemoryValue> for bool { type Error = MemoryTypeError; - fn try_from(memory_value: &MemoryValue) -> Result { + fn try_from(memory_value: &MemoryValue) -> Result { let as_integer = memory_value.expect_integer_with_bit_size(1)?; if as_integer.is_zero() { @@ -301,15 +277,15 @@ impl TryFrom<&MemoryValue> for bool { } #[derive(Debug, Clone, Default, PartialEq, Eq)] -pub struct Memory { +pub struct Memory { // Memory is a vector of values. // We grow the memory when values past the end are set, extending with 0s. - inner: Vec, + inner: Vec>, } -impl Memory { +impl Memory { /// Gets the value at pointer - pub fn read(&self, ptr: MemoryAddress) -> MemoryValue { + pub fn read(&self, ptr: MemoryAddress) -> MemoryValue { self.inner.get(ptr.to_usize()).cloned().unwrap_or_default() } @@ -317,12 +293,12 @@ impl Memory { MemoryAddress(self.read(ptr).to_usize()) } - pub fn read_slice(&self, addr: MemoryAddress, len: usize) -> &[MemoryValue] { + pub fn read_slice(&self, addr: MemoryAddress, len: usize) -> &[MemoryValue] { &self.inner[addr.to_usize()..(addr.to_usize() + len)] } /// Sets the value at pointer `ptr` to `value` - pub fn write(&mut self, ptr: MemoryAddress, value: MemoryValue) { + pub fn write(&mut self, ptr: MemoryAddress, value: MemoryValue) { self.resize_to_fit(ptr.to_usize() + 1); self.inner[ptr.to_usize()] = value; } @@ -335,13 +311,13 @@ impl Memory { } /// Sets the values after pointer `ptr` to `values` - pub fn write_slice(&mut self, ptr: MemoryAddress, values: &[MemoryValue]) { + pub fn write_slice(&mut self, ptr: MemoryAddress, values: &[MemoryValue]) { self.resize_to_fit(ptr.to_usize() + values.len()); self.inner[ptr.to_usize()..(ptr.to_usize() + values.len())].clone_from_slice(values); } /// Returns the values of the memory - pub fn values(&self) -> &[MemoryValue] { + pub fn values(&self) -> &[MemoryValue] { &self.inner } } diff --git a/aztec_macros/Cargo.toml b/aztec_macros/Cargo.toml index 355036d28a7..ed70066af22 100644 --- a/aztec_macros/Cargo.toml +++ b/aztec_macros/Cargo.toml @@ -10,6 +10,7 @@ repository.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +acvm.workspace = true noirc_frontend.workspace = true noirc_errors.workspace = true iter-extended.workspace = true diff --git a/aztec_macros/src/transforms/storage.rs b/aztec_macros/src/transforms/storage.rs index 0a210934827..bd9fff3c3d3 100644 --- a/aztec_macros/src/transforms/storage.rs +++ b/aztec_macros/src/transforms/storage.rs @@ -1,3 +1,4 @@ +use acvm::acir::AcirField; use noirc_errors::Span; use noirc_frontend::ast::{ BlockExpression, Expression, ExpressionKind, FunctionDefinition, Ident, Literal, NoirFunction, diff --git a/aztec_macros/src/utils/hir_utils.rs b/aztec_macros/src/utils/hir_utils.rs index 99b02acd606..34aed3b34a4 100644 --- a/aztec_macros/src/utils/hir_utils.rs +++ b/aztec_macros/src/utils/hir_utils.rs @@ -1,3 +1,4 @@ +use acvm::acir::AcirField; use iter_extended::vecmap; use noirc_errors::Location; use noirc_frontend::ast; diff --git a/compiler/noirc_driver/src/contract.rs b/compiler/noirc_driver/src/contract.rs index d6c3dc6205d..11fc1bb637a 100644 --- a/compiler/noirc_driver/src/contract.rs +++ b/compiler/noirc_driver/src/contract.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap}; -use acvm::acir::circuit::Program; +use acvm::{acir::circuit::Program, FieldElement}; use fm::FileId; use noirc_abi::{Abi, AbiType, AbiValue}; use noirc_errors::debug_info::DebugInfo; @@ -51,7 +51,7 @@ pub struct ContractFunction { serialize_with = "Program::serialize_program_base64", deserialize_with = "Program::deserialize_program_base64" )] - pub bytecode: Program, + pub bytecode: Program, pub debug: Vec, diff --git a/compiler/noirc_driver/src/program.rs b/compiler/noirc_driver/src/program.rs index ed7ddb29f59..8e02de0b8b3 100644 --- a/compiler/noirc_driver/src/program.rs +++ b/compiler/noirc_driver/src/program.rs @@ -1,6 +1,6 @@ use std::collections::BTreeMap; -use acvm::acir::circuit::Program; +use acvm::{acir::circuit::Program, FieldElement}; use fm::FileId; use noirc_errors::debug_info::DebugInfo; @@ -22,7 +22,7 @@ pub struct CompiledProgram { serialize_with = "Program::serialize_program_base64", deserialize_with = "Program::deserialize_program_base64" )] - pub program: Program, + pub program: Program, pub abi: noirc_abi::Abi, pub debug: Vec, pub file_map: BTreeMap, diff --git a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs index 0dbab80dace..1fa4f41b29c 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs @@ -18,7 +18,7 @@ use crate::ssa::ir::{ }; use acvm::acir::brillig::{MemoryAddress, ValueOrArray}; use acvm::brillig_vm::brillig::HeapVector; -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use fxhash::{FxHashMap as HashMap, FxHashSet as HashSet}; use iter_extended::vecmap; use num_bigint::BigUint; diff --git a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs index 4b97a61491d..74319595795 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs @@ -1,5 +1,6 @@ use acvm::{ acir::brillig::{BinaryFieldOp, BinaryIntOp, MemoryAddress, Opcode as BrilligOpcode}, + acir::AcirField, FieldElement, }; diff --git a/compiler/noirc_evaluator/src/brillig/brillig_ir.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir.rs index 2bd57dc9486..9341db2ead7 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir.rs @@ -27,7 +27,10 @@ pub(crate) use instructions::BrilligBinaryOp; use self::{artifact::BrilligArtifact, registers::BrilligRegistersContext}; use crate::ssa::ir::dfg::CallStack; -use acvm::acir::brillig::{MemoryAddress, Opcode as BrilligOpcode}; +use acvm::{ + acir::brillig::{MemoryAddress, Opcode as BrilligOpcode}, + FieldElement, +}; use debug_show::DebugShow; /// The Brillig VM does not apply a limit to the memory address space, @@ -110,7 +113,7 @@ impl BrilligContext { result } /// Adds a brillig instruction to the brillig byte code - fn push_opcode(&mut self, opcode: BrilligOpcode) { + fn push_opcode(&mut self, opcode: BrilligOpcode) { self.obj.push_opcode(opcode); } @@ -143,7 +146,7 @@ pub(crate) mod tests { pub(crate) struct DummyBlackBoxSolver; - impl BlackBoxFunctionSolver for DummyBlackBoxSolver { + impl BlackBoxFunctionSolver for DummyBlackBoxSolver { fn schnorr_verify( &self, _public_key_x: &FieldElement, @@ -217,8 +220,8 @@ pub(crate) mod tests { pub(crate) fn create_and_run_vm( calldata: Vec, - bytecode: &[BrilligOpcode], - ) -> (VM<'_, DummyBlackBoxSolver>, usize, usize) { + bytecode: &[BrilligOpcode], + ) -> (VM<'_, FieldElement, DummyBlackBoxSolver>, usize, usize) { let mut vm = VM::new(calldata, bytecode, vec![], &DummyBlackBoxSolver); let status = vm.process_opcodes(); @@ -277,7 +280,7 @@ pub(crate) mod tests { context.stop_instruction(); - let bytecode: Vec = context.artifact().finish().byte_code; + let bytecode: Vec> = context.artifact().finish().byte_code; let number_sequence: Vec = (0_usize..12_usize).map(FieldElement::from).collect(); let mut vm = VM::new( diff --git a/compiler/noirc_evaluator/src/brillig/brillig_ir/artifact.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir/artifact.rs index dee6c6076f4..99e922c1580 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir/artifact.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir/artifact.rs @@ -1,4 +1,4 @@ -use acvm::acir::brillig::Opcode as BrilligOpcode; +use acvm::{acir::brillig::Opcode as BrilligOpcode, FieldElement}; use std::collections::{BTreeMap, HashMap}; use crate::ssa::ir::dfg::CallStack; @@ -19,7 +19,7 @@ pub(crate) enum BrilligParameter { /// This is ready to run bytecode with attached metadata. #[derive(Debug, Default)] pub(crate) struct GeneratedBrillig { - pub(crate) byte_code: Vec, + pub(crate) byte_code: Vec>, pub(crate) locations: BTreeMap, pub(crate) assert_messages: BTreeMap, } @@ -28,7 +28,7 @@ pub(crate) struct GeneratedBrillig { /// Artifacts resulting from the compilation of a function into brillig byte code. /// It includes the bytecode of the function and all the metadata that allows linking with other functions. pub(crate) struct BrilligArtifact { - pub(crate) byte_code: Vec, + pub(crate) byte_code: Vec>, /// A map of bytecode positions to assertion messages. /// Some error messages (compiler intrinsics) are not emitted via revert data, /// instead, they are handled externally so they don't add size to user programs. @@ -154,7 +154,7 @@ impl BrilligArtifact { } /// Adds a brillig instruction to the brillig byte code - pub(crate) fn push_opcode(&mut self, opcode: BrilligOpcode) { + pub(crate) fn push_opcode(&mut self, opcode: BrilligOpcode) { if !self.call_stack.is_empty() { self.locations.insert(self.index_of_next_opcode(), self.call_stack.clone()); } @@ -164,7 +164,7 @@ impl BrilligArtifact { /// Adds a unresolved jump to be fixed at the end of bytecode processing. pub(crate) fn add_unresolved_jump( &mut self, - jmp_instruction: BrilligOpcode, + jmp_instruction: BrilligOpcode, destination: UnresolvedJumpLocation, ) { assert!( @@ -178,7 +178,7 @@ impl BrilligArtifact { /// Adds a unresolved external call that will be fixed once linking has been done. pub(crate) fn add_unresolved_external_call( &mut self, - call_instruction: BrilligOpcode, + call_instruction: BrilligOpcode, destination: UnresolvedJumpLocation, ) { // TODO: Add a check to ensure that the opcode is a call instruction @@ -188,7 +188,7 @@ impl BrilligArtifact { } /// Returns true if the opcode is a jump instruction - fn is_jmp_instruction(instruction: &BrilligOpcode) -> bool { + fn is_jmp_instruction(instruction: &BrilligOpcode) -> bool { matches!( instruction, BrilligOpcode::JumpIfNot { .. } diff --git a/compiler/noirc_evaluator/src/brillig/brillig_ir/brillig_variable.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir/brillig_variable.rs index bbfdbb69f7c..cf1fd555191 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir/brillig_variable.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir/brillig_variable.rs @@ -1,4 +1,5 @@ use acvm::{ + acir::AcirField, brillig_vm::brillig::{HeapArray, HeapValueType, HeapVector, MemoryAddress, ValueOrArray}, FieldElement, }; diff --git a/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs index 58166554e1d..42f3b34aea0 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs @@ -1,5 +1,6 @@ use acvm::{ acir::brillig::{BlackBoxOp, HeapArray}, + acir::AcirField, FieldElement, }; diff --git a/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs index 38e9bdfa8b8..9023183eb36 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs @@ -5,7 +5,7 @@ use super::{ registers::BrilligRegistersContext, BrilligBinaryOp, BrilligContext, ReservedRegisters, }; -use acvm::{acir::brillig::MemoryAddress, FieldElement}; +use acvm::{acir::brillig::MemoryAddress, acir::AcirField, FieldElement}; pub(crate) const MAX_STACK_SIZE: usize = 2048; diff --git a/compiler/noirc_evaluator/src/brillig/brillig_ir/instructions.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir/instructions.rs index 5d2430208e4..03a9216b73a 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir/instructions.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir/instructions.rs @@ -3,6 +3,7 @@ use acvm::{ BinaryFieldOp, BinaryIntOp, BlackBoxOp, HeapArray, HeapValueType, MemoryAddress, Opcode as BrilligOpcode, ValueOrArray, }, + acir::AcirField, FieldElement, }; @@ -212,7 +213,7 @@ impl BrilligContext { /// Adds a unresolved `Jump` to the bytecode. fn add_unresolved_jump( &mut self, - jmp_instruction: BrilligOpcode, + jmp_instruction: BrilligOpcode, destination: UnresolvedJumpLocation, ) { self.obj.add_unresolved_jump(jmp_instruction, destination); @@ -380,7 +381,7 @@ impl BrilligContext { constant, result.bit_size ); - if result.bit_size > 128 && !constant.fits_in_u128() { + if result.bit_size > 128 && constant.num_bits() > 128 { let high = FieldElement::from_be_bytes_reduce( constant.to_be_bytes().get(0..16).expect("FieldElement::to_be_bytes() too short!"), ); diff --git a/compiler/noirc_evaluator/src/ssa.rs b/compiler/noirc_evaluator/src/ssa.rs index c2fe7878bf8..d38601bfc1b 100644 --- a/compiler/noirc_evaluator/src/ssa.rs +++ b/compiler/noirc_evaluator/src/ssa.rs @@ -10,12 +10,15 @@ use std::collections::{BTreeMap, BTreeSet}; use crate::errors::{RuntimeError, SsaReport}; -use acvm::acir::{ - circuit::{ - brillig::BrilligBytecode, Circuit, ErrorSelector, ExpressionWidth, Program as AcirProgram, - PublicInputs, +use acvm::{ + acir::{ + circuit::{ + brillig::BrilligBytecode, Circuit, ErrorSelector, ExpressionWidth, + Program as AcirProgram, PublicInputs, + }, + native_types::Witness, }, - native_types::Witness, + FieldElement, }; use noirc_errors::debug_info::{DebugFunctions, DebugInfo, DebugTypes, DebugVariables}; @@ -102,7 +105,7 @@ fn time(name: &str, print_timings: bool, f: impl FnOnce() -> T) -> T { #[derive(Default)] pub struct SsaProgramArtifact { - pub program: AcirProgram, + pub program: AcirProgram, pub debug: Vec, pub warnings: Vec, pub main_input_witnesses: Vec, @@ -113,7 +116,7 @@ pub struct SsaProgramArtifact { impl SsaProgramArtifact { fn new( - unconstrained_functions: Vec, + unconstrained_functions: Vec>, error_types: BTreeMap, ) -> Self { let program = AcirProgram { functions: Vec::default(), unconstrained_functions }; @@ -194,7 +197,7 @@ pub fn create_program( pub struct SsaCircuitArtifact { name: String, - circuit: Circuit, + circuit: Circuit, debug_info: DebugInfo, warnings: Vec, input_witnesses: Vec, diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index b6e88a8d4b0..4a0f9f798ff 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -13,6 +13,7 @@ use acvm::acir::circuit::{AssertionPayload, ExpressionOrMemory, Opcode}; use acvm::blackbox_solver; use acvm::brillig_vm::{MemoryValue, VMStatus, VM}; use acvm::{ + acir::AcirField, acir::{ brillig::Opcode as BrilligOpcode, circuit::opcodes::FunctionInput, @@ -269,7 +270,10 @@ impl AcirContext { } /// Converts an [`AcirVar`] to an [`Expression`] - pub(crate) fn var_to_expression(&self, var: AcirVar) -> Result { + pub(crate) fn var_to_expression( + &self, + var: AcirVar, + ) -> Result, InternalError> { let var_data = match self.vars.get(&var) { Some(var_data) => var_data, None => { @@ -498,7 +502,7 @@ impl AcirContext { &mut self, lhs: AcirVar, rhs: AcirVar, - assert_message: Option, + assert_message: Option>, ) -> Result<(), RuntimeError> { let lhs_expr = self.var_to_expression(lhs)?; let rhs_expr = self.var_to_expression(rhs)?; @@ -527,7 +531,7 @@ impl AcirContext { pub(crate) fn vars_to_expressions_or_memory( &self, values: &[AcirValue], - ) -> Result, RuntimeError> { + ) -> Result>, RuntimeError> { let mut result = Vec::with_capacity(values.len()); for value in values { match value { @@ -901,7 +905,7 @@ impl AcirContext { // Optimization when rhs is const and fits within a u128 let rhs_expr = self.var_to_expression(rhs)?; - if rhs_expr.is_const() && rhs_expr.q_c.fits_in_u128() { + if rhs_expr.is_const() && rhs_expr.q_c.num_bits() <= 128 { // We try to move the offset to rhs let rhs_offset = if self.is_constant_one(&offset) && rhs_expr.q_c.to_u128() >= 1 { lhs_offset = lhs; @@ -1554,21 +1558,24 @@ impl AcirContext { brillig_function_index: u32, brillig_stdlib_func: Option, ) -> Result, RuntimeError> { - let brillig_inputs = try_vecmap(inputs, |i| -> Result<_, InternalError> { - match i { - AcirValue::Var(var, _) => Ok(BrilligInputs::Single(self.var_to_expression(var)?)), - AcirValue::Array(vars) => { - let mut var_expressions: Vec = Vec::new(); - for var in vars { - self.brillig_array_input(&mut var_expressions, var)?; + let brillig_inputs: Vec> = + try_vecmap(inputs, |i| -> Result<_, InternalError> { + match i { + AcirValue::Var(var, _) => { + Ok(BrilligInputs::Single(self.var_to_expression(var)?)) + } + AcirValue::Array(vars) => { + let mut var_expressions: Vec> = Vec::new(); + for var in vars { + self.brillig_array_input(&mut var_expressions, var)?; + } + Ok(BrilligInputs::Array(var_expressions)) + } + AcirValue::DynamicArray(AcirDynamicArray { block_id, .. }) => { + Ok(BrilligInputs::MemoryArray(block_id)) } - Ok(BrilligInputs::Array(var_expressions)) - } - AcirValue::DynamicArray(AcirDynamicArray { block_id, .. }) => { - Ok(BrilligInputs::MemoryArray(block_id)) } - } - })?; + })?; // Optimistically try executing the brillig now, if we can complete execution they just return the results. // This is a temporary measure pending SSA optimizations being applied to Brillig which would remove constant-input opcodes (See #2066) @@ -1645,7 +1652,7 @@ impl AcirContext { fn brillig_array_input( &mut self, - var_expressions: &mut Vec, + var_expressions: &mut Vec>, input: AcirValue, ) -> Result<(), InternalError> { match input { @@ -1704,8 +1711,8 @@ impl AcirContext { fn execute_brillig( &mut self, - code: &[BrilligOpcode], - inputs: &[BrilligInputs], + code: &[BrilligOpcode], + inputs: &[BrilligInputs], outputs_types: &[AcirType], ) -> Option> { let mut memory = (execute_brillig(code, inputs)?).into_iter(); @@ -1730,7 +1737,7 @@ impl AcirContext { &mut self, element_types: &[AcirType], size: usize, - memory_iter: &mut impl Iterator, + memory_iter: &mut impl Iterator>, ) -> AcirValue { let mut array_values = im::Vector::new(); for _ in 0..size { @@ -1885,7 +1892,7 @@ impl AcirContext { #[derive(Debug, Eq, Clone)] enum AcirVarData { Witness(Witness), - Expr(Expression), + Expr(Expression), Const(FieldElement), } @@ -1917,7 +1924,7 @@ impl AcirVarData { None } /// Converts all enum variants to an Expression. - pub(crate) fn to_expression(&self) -> Cow { + pub(crate) fn to_expression(&self) -> Cow> { match self { AcirVarData::Witness(witness) => Cow::Owned(Expression::from(*witness)), AcirVarData::Expr(expr) => Cow::Borrowed(expr), @@ -1938,8 +1945,8 @@ impl From for AcirVarData { } } -impl From for AcirVarData { - fn from(expr: Expression) -> Self { +impl From> for AcirVarData { + fn from(expr: Expression) -> Self { // Prefer simpler variants if possible. if let Some(constant) = expr.to_const() { AcirVarData::from(constant) @@ -1960,7 +1967,10 @@ pub(crate) struct AcirVar(usize); /// Returns the finished state of the Brillig VM if execution can complete. /// /// Returns `None` if complete execution of the Brillig bytecode is not possible. -fn execute_brillig(code: &[BrilligOpcode], inputs: &[BrilligInputs]) -> Option> { +fn execute_brillig( + code: &[BrilligOpcode], + inputs: &[BrilligInputs], +) -> Option>> { // Set input values let mut calldata: Vec = Vec::new(); diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/big_int.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/big_int.rs index c21188a8dbc..b9c596d80c7 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/big_int.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/big_int.rs @@ -1,4 +1,4 @@ -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use num_bigint::BigUint; /// Represents a bigint value in the form (id, modulus) where diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index d23f4abe5f5..6c79c0a228d 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -17,6 +17,7 @@ use acvm::acir::{ BlackBoxFunc, }; use acvm::{ + acir::AcirField, acir::{circuit::directives::Directive, native_types::Expression}, FieldElement, }; @@ -41,7 +42,7 @@ pub(crate) struct GeneratedAcir { current_witness_index: Option, /// The opcodes of which the compiled ACIR will comprise. - opcodes: Vec, + opcodes: Vec>, /// All witness indices that comprise the final return value of the program /// @@ -60,7 +61,7 @@ pub(crate) struct GeneratedAcir { pub(crate) call_stack: CallStack, /// Correspondence between an opcode index and the error message associated with it. - pub(crate) assertion_payloads: BTreeMap, + pub(crate) assertion_payloads: BTreeMap>, pub(crate) warnings: Vec, @@ -99,18 +100,18 @@ impl GeneratedAcir { } /// Adds a new opcode into ACIR. - pub(crate) fn push_opcode(&mut self, opcode: AcirOpcode) { + pub(crate) fn push_opcode(&mut self, opcode: AcirOpcode) { self.opcodes.push(opcode); if !self.call_stack.is_empty() { self.locations.insert(self.last_acir_opcode_location(), self.call_stack.clone()); } } - pub(crate) fn opcodes(&self) -> &[AcirOpcode] { + pub(crate) fn opcodes(&self) -> &[AcirOpcode] { &self.opcodes } - pub(crate) fn take_opcodes(&mut self) -> Vec { + pub(crate) fn take_opcodes(&mut self) -> Vec> { std::mem::take(&mut self.opcodes) } @@ -129,7 +130,7 @@ impl GeneratedAcir { /// /// If `expr` can be represented as a `Witness` then this function will return it, /// else a new opcode will be added to create a `Witness` that is equal to `expr`. - pub(crate) fn get_or_create_witness(&mut self, expr: &Expression) -> Witness { + pub(crate) fn get_or_create_witness(&mut self, expr: &Expression) -> Witness { match expr.to_witness() { Some(witness) => witness, None => self.create_witness_for_expression(expr), @@ -142,7 +143,10 @@ impl GeneratedAcir { /// This means you cannot multiply an infinite amount of `Expression`s together. /// Once the `Expression` goes over degree-2, then it needs to be reduced to a `Witness` /// which has degree-1 in order to be able to continue the multiplication chain. - pub(crate) fn create_witness_for_expression(&mut self, expression: &Expression) -> Witness { + pub(crate) fn create_witness_for_expression( + &mut self, + expression: &Expression, + ) -> Witness { let fresh_witness = self.next_witness_index(); // Create a constraint that sets them to be equal to each other @@ -392,7 +396,7 @@ impl GeneratedAcir { /// Only radix that are a power of two are supported pub(crate) fn radix_le_decompose( &mut self, - input_expr: &Expression, + input_expr: &Expression, radix: u32, limb_count: u32, bit_size: u32, @@ -438,7 +442,7 @@ impl GeneratedAcir { /// /// Safety: It is the callers responsibility to ensure that the /// resulting `Witness` is constrained to be the inverse. - pub(crate) fn brillig_inverse(&mut self, expr: Expression) -> Witness { + pub(crate) fn brillig_inverse(&mut self, expr: Expression) -> Witness { // Create the witness for the result let inverted_witness = self.next_witness_index(); @@ -462,14 +466,18 @@ impl GeneratedAcir { /// /// If `expr` is not zero, then the constraint system will /// fail upon verification. - pub(crate) fn assert_is_zero(&mut self, expr: Expression) { + pub(crate) fn assert_is_zero(&mut self, expr: Expression) { self.push_opcode(AcirOpcode::AssertZero(expr)); } /// Returns a `Witness` that is constrained to be: /// - `1` if `lhs == rhs` /// - `0` otherwise - pub(crate) fn is_equal(&mut self, lhs: &Expression, rhs: &Expression) -> Witness { + pub(crate) fn is_equal( + &mut self, + lhs: &Expression, + rhs: &Expression, + ) -> Witness { let t = lhs - rhs; self.is_zero(&t) @@ -527,7 +535,7 @@ impl GeneratedAcir { /// By setting `z` to be `0`, we can make `y` equal to `1`. /// This is easily observed: `y = 1 - t * 0` /// Now since `y` is one, this means that `t` needs to be zero, or else `y * t == 0` will fail. - fn is_zero(&mut self, t_expr: &Expression) -> Witness { + fn is_zero(&mut self, t_expr: &Expression) -> Witness { // We're checking for equality with zero so we can negate the expression without changing the result. // This is useful as it will sometimes allow us to simplify an expression down to a witness. let t_witness = if let Some(witness) = t_expr.to_witness() { @@ -588,9 +596,9 @@ impl GeneratedAcir { pub(crate) fn brillig_call( &mut self, - predicate: Option, + predicate: Option>, generated_brillig: &GeneratedBrillig, - inputs: Vec, + inputs: Vec>, outputs: Vec, brillig_function_index: u32, stdlib_func: Option, diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index 30fd83d7704..e9b2d5f46df 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -37,6 +37,7 @@ use acvm::acir::circuit::{AssertionPayload, ErrorSelector, OpcodeLocation}; use acvm::acir::native_types::Witness; use acvm::acir::BlackBoxFunc; use acvm::{ + acir::AcirField, acir::{circuit::opcodes::BlockId, native_types::Expression}, FieldElement, }; @@ -278,7 +279,7 @@ impl AcirValue { } pub(crate) type Artifacts = - (Vec, Vec, BTreeMap); + (Vec, Vec>, BTreeMap); impl Ssa { #[tracing::instrument(level = "trace", skip_all)] @@ -3097,7 +3098,7 @@ mod test { } fn check_call_opcode( - opcode: &Opcode, + opcode: &Opcode, expected_id: u32, expected_inputs: Vec, expected_outputs: Vec, @@ -3425,7 +3426,7 @@ mod test { fn check_brillig_calls( brillig_stdlib_function_locations: &BTreeMap, - opcodes: &[Opcode], + opcodes: &[Opcode], num_normal_brillig_functions: u32, expected_num_stdlib_calls: u32, expected_num_normal_calls: u32, diff --git a/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs b/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs index f5afbfae1bb..b24c5632b24 100644 --- a/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs @@ -516,7 +516,7 @@ impl std::ops::Index for FunctionBuilder { mod tests { use std::rc::Rc; - use acvm::FieldElement; + use acvm::{acir::AcirField, FieldElement}; use crate::ssa::ir::{ instruction::{Endian, Intrinsic}, diff --git a/compiler/noirc_evaluator/src/ssa/ir/dfg.rs b/compiler/noirc_evaluator/src/ssa/ir/dfg.rs index c71781557bd..545827df1c5 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/dfg.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/dfg.rs @@ -13,7 +13,7 @@ use super::{ value::{Value, ValueId}, }; -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use fxhash::FxHashMap as HashMap; use iter_extended::vecmap; use noirc_errors::Location; diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs index 93ea703721f..5110140bfcc 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -1,6 +1,7 @@ use std::hash::{Hash, Hasher}; use acvm::{ + acir::AcirField, acir::{ circuit::{ErrorSelector, STRING_ERROR_SELECTOR}, BlackBoxFunc, diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs index 9099268ace9..dbb717b0a10 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs @@ -1,4 +1,4 @@ -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use super::{ DataFlowGraph, Instruction, InstructionResultType, NumericType, SimplifyResult, Type, ValueId, diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs index 8f57d9de368..74e5653c7ba 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs @@ -1,7 +1,7 @@ use fxhash::FxHashMap as HashMap; use std::{collections::VecDeque, rc::Rc}; -use acvm::{acir::BlackBoxFunc, BlackBoxResolutionError, FieldElement}; +use acvm::{acir::AcirField, acir::BlackBoxFunc, BlackBoxResolutionError, FieldElement}; use iter_extended::vecmap; use num_bigint::BigUint; diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/cast.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/cast.rs index 671820e801d..d0ed5a1fa9c 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction/cast.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/cast.rs @@ -1,4 +1,4 @@ -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use num_bigint::BigUint; use super::{DataFlowGraph, Instruction, NumericType, SimplifyResult, Type, Value, ValueId}; diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/constrain.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/constrain.rs index d844f350927..66f50440d64 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction/constrain.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/constrain.rs @@ -1,4 +1,4 @@ -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use super::{Binary, BinaryOp, ConstrainError, DataFlowGraph, Instruction, Type, Value, ValueId}; diff --git a/compiler/noirc_evaluator/src/ssa/ir/printer.rs b/compiler/noirc_evaluator/src/ssa/ir/printer.rs index 58c593b0ad6..f7ffe2406ec 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/printer.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/printer.rs @@ -5,6 +5,7 @@ use std::{ }; use acvm::acir::circuit::{ErrorSelector, STRING_ERROR_SELECTOR}; +use acvm::acir::AcirField; use iter_extended::vecmap; use super::{ diff --git a/compiler/noirc_evaluator/src/ssa/ir/types.rs b/compiler/noirc_evaluator/src/ssa/ir/types.rs index d72ad487f66..ded385d2d3c 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/types.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/types.rs @@ -1,6 +1,6 @@ use std::rc::Rc; -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use iter_extended::vecmap; /// A numeric type in the Intermediate representation diff --git a/compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs b/compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs index ac2f6424332..48bd70ff139 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs @@ -21,7 +21,7 @@ //! different blocks are merged, i.e. after the [`flatten_cfg`][super::flatten_cfg] pass. use std::collections::HashSet; -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use iter_extended::vecmap; use crate::ssa::{ @@ -288,6 +288,7 @@ mod test { value::{Value, ValueId}, }, }; + use acvm::acir::AcirField; #[test] fn simple_constant_fold() { diff --git a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs index 0f8b49b40ec..690c0244f62 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs @@ -134,7 +134,7 @@ use fxhash::FxHashMap as HashMap; use std::collections::{BTreeMap, HashSet}; -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use iter_extended::vecmap; use crate::ssa::{ @@ -792,6 +792,8 @@ impl<'f> Context<'f> { mod test { use std::rc::Rc; + use acvm::acir::AcirField; + use crate::ssa::{ function_builder::FunctionBuilder, ir::{ diff --git a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/capacity_tracker.rs b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/capacity_tracker.rs index 4fc19acd2ac..f0760f29006 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/capacity_tracker.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/capacity_tracker.rs @@ -5,7 +5,7 @@ use crate::ssa::ir::{ value::{Value, ValueId}, }; -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use fxhash::FxHashMap as HashMap; pub(crate) struct SliceCapacityTracker<'a> { diff --git a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/value_merger.rs b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/value_merger.rs index 80f6529b7b3..c59134e4ecc 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/value_merger.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/value_merger.rs @@ -1,4 +1,4 @@ -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use fxhash::{FxHashMap as HashMap, FxHashSet}; use crate::ssa::ir::{ diff --git a/compiler/noirc_evaluator/src/ssa/opt/inlining.rs b/compiler/noirc_evaluator/src/ssa/opt/inlining.rs index 73dc3888184..1293671da50 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/inlining.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/inlining.rs @@ -4,6 +4,7 @@ //! be a single function remaining when the pass finishes. use std::collections::{BTreeSet, HashSet}; +use acvm::acir::AcirField; use iter_extended::{btree_map, vecmap}; use crate::ssa::{ @@ -562,7 +563,7 @@ impl<'function> PerFunctionContext<'function> { #[cfg(test)] mod test { - use acvm::FieldElement; + use acvm::{acir::AcirField, FieldElement}; use noirc_frontend::monomorphization::ast::InlineType; use crate::ssa::{ diff --git a/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs b/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs index 7b87142d824..5b1139e5b9c 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs @@ -406,7 +406,7 @@ impl<'f> PerFunctionContext<'f> { mod tests { use std::rc::Rc; - use acvm::FieldElement; + use acvm::{acir::AcirField, FieldElement}; use im::vector; use crate::ssa::{ diff --git a/compiler/noirc_evaluator/src/ssa/opt/remove_bit_shifts.rs b/compiler/noirc_evaluator/src/ssa/opt/remove_bit_shifts.rs index 65a77552c79..628e1bd7410 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/remove_bit_shifts.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/remove_bit_shifts.rs @@ -1,6 +1,6 @@ use std::{borrow::Cow, rc::Rc}; -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use crate::ssa::{ ir::{ diff --git a/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs b/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs index 464faa57323..6db76996747 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs @@ -10,7 +10,7 @@ //! before the [Instruction]. Continue inserting instructions until the next [Instruction::EnableSideEffects] is encountered. use std::collections::HashSet; -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use crate::ssa::{ ir::{ diff --git a/compiler/noirc_evaluator/src/ssa/opt/remove_if_else.rs b/compiler/noirc_evaluator/src/ssa/opt/remove_if_else.rs index 91b455dbf29..6ca7eb74e9d 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/remove_if_else.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/remove_if_else.rs @@ -1,6 +1,6 @@ use std::collections::hash_map::Entry; -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use fxhash::FxHashMap as HashMap; use crate::ssa::ir::value::ValueId; diff --git a/compiler/noirc_evaluator/src/ssa/opt/simplify_cfg.rs b/compiler/noirc_evaluator/src/ssa/opt/simplify_cfg.rs index f524b10f1f2..9d5d7879dcb 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/simplify_cfg.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/simplify_cfg.rs @@ -11,6 +11,8 @@ //! Currently, 1 and 4 are unimplemented. use std::collections::HashSet; +use acvm::acir::AcirField; + use crate::ssa::{ ir::{ basic_block::BasicBlockId, cfg::ControlFlowGraph, dfg::CallStack, function::Function, @@ -159,6 +161,7 @@ mod test { types::Type, }, }; + use acvm::acir::AcirField; #[test] fn inline_blocks() { diff --git a/compiler/noirc_evaluator/src/ssa/opt/unrolling.rs b/compiler/noirc_evaluator/src/ssa/opt/unrolling.rs index cfb5cfac326..5f58be41422 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/unrolling.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/unrolling.rs @@ -16,6 +16,8 @@ //! we remove reference count instructions because they are only used by Brillig bytecode use std::collections::HashSet; +use acvm::acir::AcirField; + use crate::{ errors::RuntimeError, ssa::{ diff --git a/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs b/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs index ebcbfbabe73..df14ee99bd3 100644 --- a/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs +++ b/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs @@ -1,7 +1,7 @@ use std::rc::Rc; use std::sync::{Mutex, RwLock}; -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use iter_extended::vecmap; use noirc_errors::Location; use noirc_frontend::ast::{BinaryOpKind, Signedness}; diff --git a/compiler/noirc_frontend/src/ast/expression.rs b/compiler/noirc_frontend/src/ast/expression.rs index 0173b17d28f..21131c71217 100644 --- a/compiler/noirc_frontend/src/ast/expression.rs +++ b/compiler/noirc_frontend/src/ast/expression.rs @@ -6,7 +6,7 @@ use crate::ast::{ UnresolvedTraitConstraint, UnresolvedType, UnresolvedTypeData, Visibility, }; use crate::token::{Attributes, Token}; -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use iter_extended::vecmap; use noirc_errors::{Span, Spanned}; diff --git a/compiler/noirc_frontend/src/ast/mod.rs b/compiler/noirc_frontend/src/ast/mod.rs index c3556dac6af..090a41fa7d9 100644 --- a/compiler/noirc_frontend/src/ast/mod.rs +++ b/compiler/noirc_frontend/src/ast/mod.rs @@ -26,6 +26,7 @@ use crate::{ token::IntType, BinaryTypeOperator, }; +use acvm::acir::AcirField; use iter_extended::vecmap; #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Ord, PartialOrd)] diff --git a/compiler/noirc_frontend/src/ast/statement.rs b/compiler/noirc_frontend/src/ast/statement.rs index 863615da53d..9b2c0fbfee8 100644 --- a/compiler/noirc_frontend/src/ast/statement.rs +++ b/compiler/noirc_frontend/src/ast/statement.rs @@ -1,6 +1,7 @@ use std::fmt::Display; use std::sync::atomic::{AtomicU32, Ordering}; +use acvm::acir::AcirField; use acvm::FieldElement; use iter_extended::vecmap; use noirc_errors::{Span, Spanned}; diff --git a/compiler/noirc_frontend/src/elaborator/types.rs b/compiler/noirc_frontend/src/elaborator/types.rs index 3c8d805d802..4c2b58580cf 100644 --- a/compiler/noirc_frontend/src/elaborator/types.rs +++ b/compiler/noirc_frontend/src/elaborator/types.rs @@ -1,5 +1,6 @@ use std::rc::Rc; +use acvm::{acir::AcirField, FieldElement}; use iter_extended::vecmap; use noirc_errors::{Location, Span}; diff --git a/compiler/noirc_frontend/src/hir/comptime/errors.rs b/compiler/noirc_frontend/src/hir/comptime/errors.rs index af5ba9a44cf..34cecf0ece4 100644 --- a/compiler/noirc_frontend/src/hir/comptime/errors.rs +++ b/compiler/noirc_frontend/src/hir/comptime/errors.rs @@ -1,5 +1,5 @@ use crate::{hir::def_collector::dc_crate::CompilationError, Type}; -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use noirc_errors::{CustomDiagnostic, Location}; use super::value::Value; diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs index 5984e454f7a..c0aeb910f22 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs @@ -1,6 +1,6 @@ use std::{collections::hash_map::Entry, rc::Rc}; -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use im::Vector; use iter_extended::try_vecmap; use noirc_errors::Location; diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index 1f006697359..8beac340c4b 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -11,6 +11,8 @@ // XXX: Change mentions of intern to resolve. In regards to the above comment // // XXX: Resolver does not check for unused functions +use acvm::acir::AcirField; + use crate::hir_def::expr::{ HirArrayLiteral, HirBinaryOp, HirBlockExpression, HirCallExpression, HirCapturedVar, HirCastExpression, HirConstructorExpression, HirExpression, HirIdent, HirIfExpression, diff --git a/compiler/noirc_frontend/src/hir/type_check/stmt.rs b/compiler/noirc_frontend/src/hir/type_check/stmt.rs index 0760749c9e0..3a570922c81 100644 --- a/compiler/noirc_frontend/src/hir/type_check/stmt.rs +++ b/compiler/noirc_frontend/src/hir/type_check/stmt.rs @@ -1,3 +1,4 @@ +use acvm::acir::AcirField; use iter_extended::vecmap; use noirc_errors::Span; diff --git a/compiler/noirc_frontend/src/lexer/token.rs b/compiler/noirc_frontend/src/lexer/token.rs index ebbc7fc9813..fdda271e79c 100644 --- a/compiler/noirc_frontend/src/lexer/token.rs +++ b/compiler/noirc_frontend/src/lexer/token.rs @@ -1,4 +1,4 @@ -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use noirc_errors::{Position, Span, Spanned}; use std::{fmt, iter::Map, vec::IntoIter}; diff --git a/compiler/noirc_frontend/src/monomorphization/debug.rs b/compiler/noirc_frontend/src/monomorphization/debug.rs index 88943be727f..3b399c75706 100644 --- a/compiler/noirc_frontend/src/monomorphization/debug.rs +++ b/compiler/noirc_frontend/src/monomorphization/debug.rs @@ -1,3 +1,4 @@ +use acvm::acir::AcirField; use iter_extended::vecmap; use noirc_errors::debug_info::DebugVarId; use noirc_errors::Location; diff --git a/compiler/noirc_frontend/src/monomorphization/mod.rs b/compiler/noirc_frontend/src/monomorphization/mod.rs index 54a6af97744..2e74eb87e60 100644 --- a/compiler/noirc_frontend/src/monomorphization/mod.rs +++ b/compiler/noirc_frontend/src/monomorphization/mod.rs @@ -21,7 +21,7 @@ use crate::{ token::FunctionAttribute, Type, TypeBinding, TypeBindings, TypeVariable, TypeVariableKind, }; -use acvm::FieldElement; +use acvm::{acir::AcirField, FieldElement}; use iter_extended::{btree_map, try_vecmap, vecmap}; use noirc_errors::Location; use noirc_printable_type::PrintableType; diff --git a/compiler/noirc_printable_type/src/lib.rs b/compiler/noirc_printable_type/src/lib.rs index cc0dbca247e..a12ecf01b56 100644 --- a/compiler/noirc_printable_type/src/lib.rs +++ b/compiler/noirc_printable_type/src/lib.rs @@ -1,6 +1,6 @@ use std::{collections::BTreeMap, str}; -use acvm::{brillig_vm::brillig::ForeignCallParam, FieldElement}; +use acvm::{acir::AcirField, brillig_vm::brillig::ForeignCallParam, FieldElement}; use iter_extended::vecmap; use regex::{Captures, Regex}; use serde::{Deserialize, Serialize}; @@ -81,10 +81,12 @@ pub enum ForeignCallError { ResolvedAssertMessage(String), } -impl TryFrom<&[ForeignCallParam]> for PrintableValueDisplay { +impl TryFrom<&[ForeignCallParam]> for PrintableValueDisplay { type Error = ForeignCallError; - fn try_from(foreign_call_inputs: &[ForeignCallParam]) -> Result { + fn try_from( + foreign_call_inputs: &[ForeignCallParam], + ) -> Result { let (is_fmt_str, foreign_call_inputs) = foreign_call_inputs.split_last().ok_or(ForeignCallError::MissingForeignCallInputs)?; @@ -97,7 +99,7 @@ impl TryFrom<&[ForeignCallParam]> for PrintableValueDisplay { } fn convert_string_inputs( - foreign_call_inputs: &[ForeignCallParam], + foreign_call_inputs: &[ForeignCallParam], ) -> Result { // Fetch the PrintableType from the foreign call input // The remaining input values should hold what is to be printed @@ -114,7 +116,7 @@ fn convert_string_inputs( } fn convert_fmt_string_inputs( - foreign_call_inputs: &[ForeignCallParam], + foreign_call_inputs: &[ForeignCallParam], ) -> Result { let (message, input_and_printable_types) = foreign_call_inputs.split_first().ok_or(ForeignCallError::MissingForeignCallInputs)?; @@ -143,7 +145,7 @@ fn convert_fmt_string_inputs( } fn fetch_printable_type( - printable_type: &ForeignCallParam, + printable_type: &ForeignCallParam, ) -> Result { let printable_type_as_fields = printable_type.fields(); let printable_type_as_string = decode_string_value(&printable_type_as_fields); diff --git a/compiler/wasm/Cargo.toml b/compiler/wasm/Cargo.toml index 31ef5161014..23686cc4ea1 100644 --- a/compiler/wasm/Cargo.toml +++ b/compiler/wasm/Cargo.toml @@ -13,7 +13,7 @@ license.workspace = true crate-type = ["cdylib"] [dependencies] -acvm.workspace = true +acvm = { workspace = true, features = ["bn254"] } fm.workspace = true nargo.workspace = true noirc_driver.workspace = true diff --git a/tooling/acvm_cli/src/cli/execute_cmd.rs b/tooling/acvm_cli/src/cli/execute_cmd.rs index 5f9651c9138..ac3af03684f 100644 --- a/tooling/acvm_cli/src/cli/execute_cmd.rs +++ b/tooling/acvm_cli/src/cli/execute_cmd.rs @@ -2,6 +2,7 @@ use std::io::{self, Write}; use acir::circuit::Program; use acir::native_types::{WitnessMap, WitnessStack}; +use acir::FieldElement; use bn254_blackbox_solver::Bn254BlackBoxSolver; use clap::Args; @@ -63,11 +64,11 @@ pub(crate) fn run(args: ExecuteCommand) -> Result { } pub(crate) fn execute_program_from_witness( - inputs_map: WitnessMap, + inputs_map: WitnessMap, bytecode: &[u8], foreign_call_resolver_url: Option<&str>, -) -> Result { - let program: Program = Program::deserialize_program(bytecode) +) -> Result, CliError> { + let program: Program = Program::deserialize_program(bytecode) .map_err(|_| CliError::CircuitDeserializationError())?; execute_program( &program, diff --git a/tooling/acvm_cli/src/cli/fs/inputs.rs b/tooling/acvm_cli/src/cli/fs/inputs.rs index 2a46cfba884..a0b6e3a9545 100644 --- a/tooling/acvm_cli/src/cli/fs/inputs.rs +++ b/tooling/acvm_cli/src/cli/fs/inputs.rs @@ -1,6 +1,6 @@ use acir::{ native_types::{Witness, WitnessMap}, - FieldElement, + AcirField, FieldElement, }; use toml::Table; @@ -11,7 +11,7 @@ use std::{fs::read, path::Path}; pub(crate) fn read_inputs_from_file>( working_directory: P, file_name: &String, -) -> Result { +) -> Result, CliError> { let file_path = working_directory.as_ref().join(file_name); if !file_path.exists() { return Err(CliError::FilesystemError(FilesystemError::MissingTomlFile( @@ -25,7 +25,7 @@ pub(crate) fn read_inputs_from_file>( let input_map = input_string .parse::() .map_err(|_| FilesystemError::InvalidTomlFile(file_name.clone()))?; - let mut witnesses: WitnessMap = WitnessMap::new(); + let mut witnesses: WitnessMap = WitnessMap::new(); for (key, value) in input_map.into_iter() { let index = Witness(key.trim().parse().map_err(|_| CliError::WitnessIndexError(key.clone()))?); diff --git a/tooling/acvm_cli/src/cli/fs/witness.rs b/tooling/acvm_cli/src/cli/fs/witness.rs index 30ef4278f4b..6ecba9792c3 100644 --- a/tooling/acvm_cli/src/cli/fs/witness.rs +++ b/tooling/acvm_cli/src/cli/fs/witness.rs @@ -5,7 +5,11 @@ use std::{ path::{Path, PathBuf}, }; -use acvm::acir::native_types::{WitnessMap, WitnessStack}; +use acir::FieldElement; +use acvm::acir::{ + native_types::{WitnessMap, WitnessStack}, + AcirField, +}; use crate::errors::{CliError, FilesystemError}; @@ -31,7 +35,9 @@ fn write_to_file(bytes: &[u8], path: &Path) -> String { } /// Creates a toml representation of the provided witness map -pub(crate) fn create_output_witness_string(witnesses: &WitnessMap) -> Result { +pub(crate) fn create_output_witness_string( + witnesses: &WitnessMap, +) -> Result { let mut witness_map: BTreeMap = BTreeMap::new(); for (key, value) in witnesses.clone().into_iter() { witness_map.insert(key.0.to_string(), format!("0x{}", value.to_hex())); @@ -41,7 +47,7 @@ pub(crate) fn create_output_witness_string(witnesses: &WitnessMap) -> Result>( - witnesses: WitnessStack, + witnesses: WitnessStack, witness_name: &str, witness_dir: P, ) -> Result { diff --git a/tooling/debugger/src/context.rs b/tooling/debugger/src/context.rs index a031d127d82..110e3211e24 100644 --- a/tooling/debugger/src/context.rs +++ b/tooling/debugger/src/context.rs @@ -26,28 +26,28 @@ pub(super) enum DebugCommandResult { Error(NargoError), } -pub(super) struct DebugContext<'a, B: BlackBoxFunctionSolver> { - acvm: ACVM<'a, B>, - brillig_solver: Option>, +pub(super) struct DebugContext<'a, B: BlackBoxFunctionSolver> { + acvm: ACVM<'a, FieldElement, B>, + brillig_solver: Option>, foreign_call_executor: Box, debug_artifact: &'a DebugArtifact, breakpoints: HashSet, source_to_opcodes: BTreeMap>, - unconstrained_functions: &'a [BrilligBytecode], + unconstrained_functions: &'a [BrilligBytecode], // Absolute (in terms of all the opcodes ACIR+Brillig) addresses of the ACIR // opcodes with one additional entry for to indicate the last valid address. acir_opcode_addresses: Vec, } -impl<'a, B: BlackBoxFunctionSolver> DebugContext<'a, B> { +impl<'a, B: BlackBoxFunctionSolver> DebugContext<'a, B> { pub(super) fn new( blackbox_solver: &'a B, - circuit: &'a Circuit, + circuit: &'a Circuit, debug_artifact: &'a DebugArtifact, - initial_witness: WitnessMap, + initial_witness: WitnessMap, foreign_call_executor: Box, - unconstrained_functions: &'a [BrilligBytecode], + unconstrained_functions: &'a [BrilligBytecode], ) -> Self { let source_to_opcodes = build_source_to_opcode_debug_mappings(debug_artifact); let acir_opcode_addresses = build_acir_opcode_offsets(circuit, unconstrained_functions); @@ -70,11 +70,11 @@ impl<'a, B: BlackBoxFunctionSolver> DebugContext<'a, B> { } } - pub(super) fn get_opcodes(&self) -> &[Opcode] { + pub(super) fn get_opcodes(&self) -> &[Opcode] { self.acvm.opcodes() } - pub(super) fn get_witness_map(&self) -> &WitnessMap { + pub(super) fn get_witness_map(&self) -> &WitnessMap { self.acvm.witness_map() } @@ -302,7 +302,10 @@ impl<'a, B: BlackBoxFunctionSolver> DebugContext<'a, B> { } } - fn handle_foreign_call(&mut self, foreign_call: ForeignCallWaitInfo) -> DebugCommandResult { + fn handle_foreign_call( + &mut self, + foreign_call: ForeignCallWaitInfo, + ) -> DebugCommandResult { let foreign_call_result = self.foreign_call_executor.execute(&foreign_call); match foreign_call_result { Ok(foreign_call_result) => { @@ -319,7 +322,7 @@ impl<'a, B: BlackBoxFunctionSolver> DebugContext<'a, B> { } } - fn handle_acvm_status(&mut self, status: ACVMStatus) -> DebugCommandResult { + fn handle_acvm_status(&mut self, status: ACVMStatus) -> DebugCommandResult { if let ACVMStatus::RequiresForeignCall(foreign_call) = status { return self.handle_foreign_call(foreign_call); } @@ -465,7 +468,7 @@ impl<'a, B: BlackBoxFunctionSolver> DebugContext<'a, B> { } } - pub(super) fn get_brillig_memory(&self) -> Option<&[MemoryValue]> { + pub(super) fn get_brillig_memory(&self) -> Option<&[MemoryValue]> { self.brillig_solver.as_ref().map(|solver| solver.get_memory()) } @@ -539,7 +542,7 @@ impl<'a, B: BlackBoxFunctionSolver> DebugContext<'a, B> { matches!(self.acvm.get_status(), ACVMStatus::Solved) } - pub fn finalize(self) -> WitnessMap { + pub fn finalize(self) -> WitnessMap { self.acvm.finalize() } } @@ -591,8 +594,8 @@ fn build_source_to_opcode_debug_mappings( } fn build_acir_opcode_offsets( - circuit: &Circuit, - unconstrained_functions: &[BrilligBytecode], + circuit: &Circuit, + unconstrained_functions: &[BrilligBytecode], ) -> Vec { let mut result = Vec::with_capacity(circuit.opcodes.len() + 1); // address of the first opcode is always 0 @@ -625,6 +628,7 @@ mod tests { opcodes::BlockId, }, native_types::Expression, + AcirField, }, blackbox_solver::StubbedBlackBoxSolver, brillig_vm::brillig::{ diff --git a/tooling/debugger/src/dap.rs b/tooling/debugger/src/dap.rs index c9b6b816a7e..d0ed0559b89 100644 --- a/tooling/debugger/src/dap.rs +++ b/tooling/debugger/src/dap.rs @@ -4,7 +4,7 @@ use std::io::{Read, Write}; use acvm::acir::circuit::brillig::BrilligBytecode; use acvm::acir::circuit::{Circuit, OpcodeLocation}; use acvm::acir::native_types::WitnessMap; -use acvm::BlackBoxFunctionSolver; +use acvm::{BlackBoxFunctionSolver, FieldElement}; use crate::context::DebugCommandResult; use crate::context::DebugContext; @@ -31,7 +31,7 @@ use noirc_driver::CompiledProgram; type BreakpointId = i64; -pub struct DapSession<'a, R: Read, W: Write, B: BlackBoxFunctionSolver> { +pub struct DapSession<'a, R: Read, W: Write, B: BlackBoxFunctionSolver> { server: Server, context: DebugContext<'a, B>, debug_artifact: &'a DebugArtifact, @@ -57,14 +57,14 @@ impl From for ScopeReferences { } } -impl<'a, R: Read, W: Write, B: BlackBoxFunctionSolver> DapSession<'a, R, W, B> { +impl<'a, R: Read, W: Write, B: BlackBoxFunctionSolver> DapSession<'a, R, W, B> { pub fn new( server: Server, solver: &'a B, - circuit: &'a Circuit, + circuit: &'a Circuit, debug_artifact: &'a DebugArtifact, - initial_witness: WitnessMap, - unconstrained_functions: &'a [BrilligBytecode], + initial_witness: WitnessMap, + unconstrained_functions: &'a [BrilligBytecode], ) -> Self { let context = DebugContext::new( solver, @@ -602,11 +602,11 @@ impl<'a, R: Read, W: Write, B: BlackBoxFunctionSolver> DapSession<'a, R, W, B> { } } -pub fn run_session( +pub fn run_session>( server: Server, solver: &B, program: CompiledProgram, - initial_witness: WitnessMap, + initial_witness: WitnessMap, ) -> Result<(), ServerError> { let debug_artifact = DebugArtifact { debug_symbols: program.debug, diff --git a/tooling/debugger/src/foreign_calls.rs b/tooling/debugger/src/foreign_calls.rs index 209439f5f92..6989936ae93 100644 --- a/tooling/debugger/src/foreign_calls.rs +++ b/tooling/debugger/src/foreign_calls.rs @@ -1,7 +1,7 @@ use acvm::{ acir::brillig::{ForeignCallParam, ForeignCallResult}, pwg::ForeignCallWaitInfo, - FieldElement, + AcirField, FieldElement, }; use nargo::{ artifacts::debug::{DebugArtifact, DebugVars, StackFrame}, @@ -93,8 +93,8 @@ fn debug_fn_id(value: &FieldElement) -> DebugFnId { impl ForeignCallExecutor for DefaultDebugForeignCallExecutor { fn execute( &mut self, - foreign_call: &ForeignCallWaitInfo, - ) -> Result { + foreign_call: &ForeignCallWaitInfo, + ) -> Result, ForeignCallError> { let foreign_call_name = foreign_call.function.as_str(); match DebugForeignCall::lookup(foreign_call_name) { Some(DebugForeignCall::VarAssign) => { diff --git a/tooling/debugger/src/lib.rs b/tooling/debugger/src/lib.rs index a8fc61c893f..d7a1337c82f 100644 --- a/tooling/debugger/src/lib.rs +++ b/tooling/debugger/src/lib.rs @@ -10,29 +10,29 @@ use std::io::{Read, Write}; use ::dap::errors::ServerError; use ::dap::server::Server; use acvm::acir::circuit::brillig::BrilligBytecode; -use acvm::BlackBoxFunctionSolver; use acvm::{acir::circuit::Circuit, acir::native_types::WitnessMap}; +use acvm::{BlackBoxFunctionSolver, FieldElement}; use nargo::artifacts::debug::DebugArtifact; use nargo::NargoError; use noirc_driver::CompiledProgram; -pub fn debug_circuit( +pub fn debug_circuit>( blackbox_solver: &B, - circuit: &Circuit, + circuit: &Circuit, debug_artifact: DebugArtifact, - initial_witness: WitnessMap, - unconstrained_functions: &[BrilligBytecode], -) -> Result, NargoError> { + initial_witness: WitnessMap, + unconstrained_functions: &[BrilligBytecode], +) -> Result>, NargoError> { repl::run(blackbox_solver, circuit, &debug_artifact, initial_witness, unconstrained_functions) } -pub fn run_dap_loop( +pub fn run_dap_loop>( server: Server, solver: &B, program: CompiledProgram, - initial_witness: WitnessMap, + initial_witness: WitnessMap, ) -> Result<(), ServerError> { dap::run_session(server, solver, program, initial_witness) } diff --git a/tooling/debugger/src/repl.rs b/tooling/debugger/src/repl.rs index 8f908a38ffc..5aef12ad8d4 100644 --- a/tooling/debugger/src/repl.rs +++ b/tooling/debugger/src/repl.rs @@ -15,23 +15,23 @@ use std::cell::RefCell; use crate::source_code_printer::print_source_code_location; -pub struct ReplDebugger<'a, B: BlackBoxFunctionSolver> { +pub struct ReplDebugger<'a, B: BlackBoxFunctionSolver> { context: DebugContext<'a, B>, blackbox_solver: &'a B, - circuit: &'a Circuit, + circuit: &'a Circuit, debug_artifact: &'a DebugArtifact, - initial_witness: WitnessMap, + initial_witness: WitnessMap, last_result: DebugCommandResult, - unconstrained_functions: &'a [BrilligBytecode], + unconstrained_functions: &'a [BrilligBytecode], } -impl<'a, B: BlackBoxFunctionSolver> ReplDebugger<'a, B> { +impl<'a, B: BlackBoxFunctionSolver> ReplDebugger<'a, B> { pub fn new( blackbox_solver: &'a B, - circuit: &'a Circuit, + circuit: &'a Circuit, debug_artifact: &'a DebugArtifact, - initial_witness: WitnessMap, - unconstrained_functions: &'a [BrilligBytecode], + initial_witness: WitnessMap, + unconstrained_functions: &'a [BrilligBytecode], ) -> Self { let foreign_call_executor = Box::new(DefaultDebugForeignCallExecutor::from_artifact(true, debug_artifact)); @@ -161,7 +161,7 @@ impl<'a, B: BlackBoxFunctionSolver> ReplDebugger<'a, B> { "" } }; - let print_brillig_bytecode = |acir_index, bytecode: &[BrilligOpcode]| { + let print_brillig_bytecode = |acir_index, bytecode: &[BrilligOpcode]| { for (brillig_index, brillig_opcode) in bytecode.iter().enumerate() { println!( "{:>3}.{:<2} |{:2} {:?}", @@ -371,18 +371,18 @@ impl<'a, B: BlackBoxFunctionSolver> ReplDebugger<'a, B> { self.context.is_solved() } - fn finalize(self) -> WitnessMap { + fn finalize(self) -> WitnessMap { self.context.finalize() } } -pub fn run( +pub fn run>( blackbox_solver: &B, - circuit: &Circuit, + circuit: &Circuit, debug_artifact: &DebugArtifact, - initial_witness: WitnessMap, - unconstrained_functions: &[BrilligBytecode], -) -> Result, NargoError> { + initial_witness: WitnessMap, + unconstrained_functions: &[BrilligBytecode], +) -> Result>, NargoError> { let context = RefCell::new(ReplDebugger::new( blackbox_solver, circuit, diff --git a/tooling/lsp/src/lib.rs b/tooling/lsp/src/lib.rs index 05345b96c80..304a2d34e47 100644 --- a/tooling/lsp/src/lib.rs +++ b/tooling/lsp/src/lib.rs @@ -13,7 +13,7 @@ use std::{ task::{self, Poll}, }; -use acvm::BlackBoxFunctionSolver; +use acvm::{BlackBoxFunctionSolver, FieldElement}; use async_lsp::{ router::Router, AnyEvent, AnyNotification, AnyRequest, ClientSocket, Error, LspService, ResponseError, @@ -79,7 +79,10 @@ pub struct LspState { } impl LspState { - fn new(client: &ClientSocket, solver: impl BlackBoxFunctionSolver + 'static) -> Self { + fn new( + client: &ClientSocket, + solver: impl BlackBoxFunctionSolver + 'static, + ) -> Self { Self { client: client.clone(), root_path: None, @@ -99,7 +102,10 @@ pub struct NargoLspService { } impl NargoLspService { - pub fn new(client: &ClientSocket, solver: impl BlackBoxFunctionSolver + 'static) -> Self { + pub fn new( + client: &ClientSocket, + solver: impl BlackBoxFunctionSolver + 'static, + ) -> Self { let state = LspState::new(client, solver); let mut router = Router::new(state); router diff --git a/tooling/lsp/src/solver.rs b/tooling/lsp/src/solver.rs index 87327b01e36..0fcac73b905 100644 --- a/tooling/lsp/src/solver.rs +++ b/tooling/lsp/src/solver.rs @@ -3,9 +3,9 @@ use acvm::BlackBoxFunctionSolver; // This is a struct that wraps a dynamically dispatched `BlackBoxFunctionSolver` // where we proxy the unimplemented stuff to the wrapped backend, but it // allows us to avoid changing function signatures to include the `Box` -pub(super) struct WrapperSolver(pub(super) Box); +pub(super) struct WrapperSolver(pub(super) Box>); -impl BlackBoxFunctionSolver for WrapperSolver { +impl BlackBoxFunctionSolver for WrapperSolver { fn schnorr_verify( &self, public_key_x: &acvm::FieldElement, diff --git a/tooling/nargo/src/artifacts/contract.rs b/tooling/nargo/src/artifacts/contract.rs index a864da7c33c..1afc7977aec 100644 --- a/tooling/nargo/src/artifacts/contract.rs +++ b/tooling/nargo/src/artifacts/contract.rs @@ -1,4 +1,4 @@ -use acvm::acir::circuit::Program; +use acvm::{acir::circuit::Program, FieldElement}; use noirc_abi::{Abi, AbiType, AbiValue}; use noirc_driver::{CompiledContract, CompiledContractOutputs, ContractFunction}; use serde::{Deserialize, Serialize}; @@ -65,7 +65,7 @@ pub struct ContractFunctionArtifact { serialize_with = "Program::serialize_program_base64", deserialize_with = "Program::deserialize_program_base64" )] - pub bytecode: Program, + pub bytecode: Program, #[serde( serialize_with = "ProgramDebugInfo::serialize_compressed_base64_json", diff --git a/tooling/nargo/src/artifacts/program.rs b/tooling/nargo/src/artifacts/program.rs index 3c25b9e3345..91f02157414 100644 --- a/tooling/nargo/src/artifacts/program.rs +++ b/tooling/nargo/src/artifacts/program.rs @@ -1,6 +1,7 @@ use std::collections::BTreeMap; use acvm::acir::circuit::Program; +use acvm::FieldElement; use fm::FileId; use noirc_abi::Abi; use noirc_driver::CompiledProgram; @@ -24,7 +25,7 @@ pub struct ProgramArtifact { serialize_with = "Program::serialize_program_base64", deserialize_with = "Program::deserialize_program_base64" )] - pub bytecode: Program, + pub bytecode: Program, #[serde( serialize_with = "ProgramDebugInfo::serialize_compressed_base64_json", diff --git a/tooling/nargo/src/errors.rs b/tooling/nargo/src/errors.rs index 63a72247e2f..200420e5ce5 100644 --- a/tooling/nargo/src/errors.rs +++ b/tooling/nargo/src/errors.rs @@ -6,6 +6,7 @@ use acvm::{ ResolvedOpcodeLocation, }, pwg::{ErrorLocation, OpcodeResolutionError}, + FieldElement, }; use noirc_abi::{display_abi_error, Abi, AbiErrorType}; use noirc_errors::{ @@ -95,10 +96,10 @@ impl NargoError { #[derive(Debug, Error)] pub enum ExecutionError { #[error("Failed assertion")] - AssertionFailed(ResolvedAssertionPayload, Vec), + AssertionFailed(ResolvedAssertionPayload, Vec), #[error("Failed to solve program: '{}'", .0)] - SolvingError(OpcodeResolutionError, Option>), + SolvingError(OpcodeResolutionError, Option>), } /// Extracts the opcode locations from a nargo error. diff --git a/tooling/nargo/src/ops/execute.rs b/tooling/nargo/src/ops/execute.rs index 4a75212ba47..42e93e0e3cf 100644 --- a/tooling/nargo/src/ops/execute.rs +++ b/tooling/nargo/src/ops/execute.rs @@ -1,22 +1,24 @@ use acvm::acir::circuit::brillig::BrilligBytecode; -use acvm::acir::circuit::{OpcodeLocation, Program, ResolvedOpcodeLocation}; +use acvm::acir::circuit::{ + OpcodeLocation, Program, ResolvedAssertionPayload, ResolvedOpcodeLocation, +}; use acvm::acir::native_types::WitnessStack; use acvm::pwg::{ACVMStatus, ErrorLocation, OpcodeNotSolvable, OpcodeResolutionError, ACVM}; -use acvm::BlackBoxFunctionSolver; use acvm::{acir::circuit::Circuit, acir::native_types::WitnessMap}; +use acvm::{BlackBoxFunctionSolver, FieldElement}; use crate::errors::ExecutionError; use crate::NargoError; use super::foreign_calls::ForeignCallExecutor; -struct ProgramExecutor<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> { - functions: &'a [Circuit], +struct ProgramExecutor<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> { + functions: &'a [Circuit], - unconstrained_functions: &'a [BrilligBytecode], + unconstrained_functions: &'a [BrilligBytecode], // This gets built as we run through the program looking at each function call - witness_stack: WitnessStack, + witness_stack: WitnessStack, blackbox_solver: &'a B, @@ -32,10 +34,12 @@ struct ProgramExecutor<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> { current_function_index: usize, } -impl<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> ProgramExecutor<'a, B, F> { +impl<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> + ProgramExecutor<'a, B, F> +{ fn new( - functions: &'a [Circuit], - unconstrained_functions: &'a [BrilligBytecode], + functions: &'a [Circuit], + unconstrained_functions: &'a [BrilligBytecode], blackbox_solver: &'a B, foreign_call_executor: &'a mut F, ) -> Self { @@ -50,12 +54,15 @@ impl<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> ProgramExecutor<'a, } } - fn finalize(self) -> WitnessStack { + fn finalize(self) -> WitnessStack { self.witness_stack } #[tracing::instrument(level = "trace", skip_all)] - fn execute_circuit(&mut self, initial_witness: WitnessMap) -> Result { + fn execute_circuit( + &mut self, + initial_witness: WitnessMap, + ) -> Result, NargoError> { let circuit = &self.functions[self.current_function_index]; let mut acvm = ACVM::new( self.blackbox_solver, @@ -102,13 +109,14 @@ impl<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> ProgramExecutor<'a, _ => None, }; - let assertion_payload = match &error { - OpcodeResolutionError::BrilligFunctionFailed { payload, .. } - | OpcodeResolutionError::UnsatisfiedConstrain { payload, .. } => { - payload.clone() - } - _ => None, - }; + let assertion_payload: Option> = + match &error { + OpcodeResolutionError::BrilligFunctionFailed { payload, .. } + | OpcodeResolutionError::UnsatisfiedConstrain { payload, .. } => { + payload.clone() + } + _ => None, + }; return Err(NargoError::ExecutionError(match assertion_payload { Some(payload) => ExecutionError::AssertionFailed( @@ -166,12 +174,12 @@ impl<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> ProgramExecutor<'a, } #[tracing::instrument(level = "trace", skip_all)] -pub fn execute_program( - program: &Program, - initial_witness: WitnessMap, +pub fn execute_program, F: ForeignCallExecutor>( + program: &Program, + initial_witness: WitnessMap, blackbox_solver: &B, foreign_call_executor: &mut F, -) -> Result { +) -> Result, NargoError> { let mut executor = ProgramExecutor::new( &program.functions, &program.unconstrained_functions, diff --git a/tooling/nargo/src/ops/foreign_calls.rs b/tooling/nargo/src/ops/foreign_calls.rs index c314a230cef..c6b284beb13 100644 --- a/tooling/nargo/src/ops/foreign_calls.rs +++ b/tooling/nargo/src/ops/foreign_calls.rs @@ -1,7 +1,7 @@ use acvm::{ acir::brillig::{ForeignCallParam, ForeignCallResult}, pwg::ForeignCallWaitInfo, - FieldElement, + AcirField, FieldElement, }; use jsonrpc::{arg as build_json_rpc_arg, minreq_http::Builder, Client}; use noirc_printable_type::{decode_string_value, ForeignCallError, PrintableValueDisplay}; @@ -9,8 +9,8 @@ use noirc_printable_type::{decode_string_value, ForeignCallError, PrintableValue pub trait ForeignCallExecutor { fn execute( &mut self, - foreign_call: &ForeignCallWaitInfo, - ) -> Result; + foreign_call: &ForeignCallWaitInfo, + ) -> Result, ForeignCallError>; } /// This enumeration represents the Brillig foreign calls that are natively supported by nargo. @@ -66,11 +66,11 @@ struct MockedCall { /// The oracle it's mocking name: String, /// Optionally match the parameters - params: Option>, + params: Option>>, /// The parameters with which the mock was last called - last_called_params: Option>, + last_called_params: Option>>, /// The result to return when this mock is called - result: ForeignCallResult, + result: ForeignCallResult, /// How many times should this mock be called before it is removed times_left: Option, } @@ -89,7 +89,7 @@ impl MockedCall { } impl MockedCall { - fn matches(&self, name: &str, params: &[ForeignCallParam]) -> bool { + fn matches(&self, name: &str, params: &[ForeignCallParam]) -> bool { self.name == name && (self.params.is_none() || self.params.as_deref() == Some(params)) } } @@ -130,8 +130,8 @@ impl DefaultForeignCallExecutor { impl DefaultForeignCallExecutor { fn extract_mock_id( - foreign_call_inputs: &[ForeignCallParam], - ) -> Result<(usize, &[ForeignCallParam]), ForeignCallError> { + foreign_call_inputs: &[ForeignCallParam], + ) -> Result<(usize, &[ForeignCallParam]), ForeignCallError> { let (id, params) = foreign_call_inputs.split_first().ok_or(ForeignCallError::MissingForeignCallInputs)?; let id = @@ -148,12 +148,14 @@ impl DefaultForeignCallExecutor { self.mocked_responses.iter_mut().find(|response| response.id == id) } - fn parse_string(param: &ForeignCallParam) -> String { + fn parse_string(param: &ForeignCallParam) -> String { let fields: Vec<_> = param.fields().to_vec(); decode_string_value(&fields) } - fn execute_print(foreign_call_inputs: &[ForeignCallParam]) -> Result<(), ForeignCallError> { + fn execute_print( + foreign_call_inputs: &[ForeignCallParam], + ) -> Result<(), ForeignCallError> { let skip_newline = foreign_call_inputs[0].unwrap_field().is_zero(); let foreign_call_inputs = @@ -166,7 +168,7 @@ impl DefaultForeignCallExecutor { } fn format_printable_value( - foreign_call_inputs: &[ForeignCallParam], + foreign_call_inputs: &[ForeignCallParam], skip_newline: bool, ) -> Result { let display_values: PrintableValueDisplay = foreign_call_inputs.try_into()?; @@ -180,8 +182,8 @@ impl DefaultForeignCallExecutor { impl ForeignCallExecutor for DefaultForeignCallExecutor { fn execute( &mut self, - foreign_call: &ForeignCallWaitInfo, - ) -> Result { + foreign_call: &ForeignCallWaitInfo, + ) -> Result, ForeignCallError> { let foreign_call_name = foreign_call.function.as_str(); match ForeignCall::lookup(foreign_call_name) { Some(ForeignCall::Print) => { @@ -280,7 +282,7 @@ impl ForeignCallExecutor for DefaultForeignCallExecutor { let response = external_resolver.send_request(req)?; - let parsed_response: ForeignCallResult = response.result()?; + let parsed_response: ForeignCallResult = response.result()?; Ok(parsed_response) } else { @@ -314,20 +316,32 @@ mod tests { #[rpc] pub trait OracleResolver { #[rpc(name = "echo")] - fn echo(&self, param: ForeignCallParam) -> RpcResult; + fn echo( + &self, + param: ForeignCallParam, + ) -> RpcResult>; #[rpc(name = "sum")] - fn sum(&self, array: ForeignCallParam) -> RpcResult; + fn sum( + &self, + array: ForeignCallParam, + ) -> RpcResult>; } struct OracleResolverImpl; impl OracleResolver for OracleResolverImpl { - fn echo(&self, param: ForeignCallParam) -> RpcResult { + fn echo( + &self, + param: ForeignCallParam, + ) -> RpcResult> { Ok(vec![param].into()) } - fn sum(&self, array: ForeignCallParam) -> RpcResult { + fn sum( + &self, + array: ForeignCallParam, + ) -> RpcResult> { let mut res: FieldElement = 0_usize.into(); for value in array.fields() { diff --git a/tooling/nargo/src/ops/optimize.rs b/tooling/nargo/src/ops/optimize.rs index a62f4696328..07adfb57df4 100644 --- a/tooling/nargo/src/ops/optimize.rs +++ b/tooling/nargo/src/ops/optimize.rs @@ -1,4 +1,4 @@ -use acvm::acir::circuit::Program; +use acvm::{acir::circuit::Program, FieldElement}; use iter_extended::vecmap; use noirc_driver::{CompiledContract, CompiledProgram}; use noirc_errors::debug_info::DebugInfo; @@ -18,7 +18,10 @@ pub fn optimize_contract(contract: CompiledContract) -> CompiledContract { CompiledContract { functions, ..contract } } -fn optimize_program_internal(mut program: Program, debug: &mut [DebugInfo]) -> Program { +fn optimize_program_internal( + mut program: Program, + debug: &mut [DebugInfo], +) -> Program { let functions = std::mem::take(&mut program.functions); let optimized_functions = functions diff --git a/tooling/nargo/src/ops/test.rs b/tooling/nargo/src/ops/test.rs index 86dd8cd7cd5..ed45251ac8a 100644 --- a/tooling/nargo/src/ops/test.rs +++ b/tooling/nargo/src/ops/test.rs @@ -1,6 +1,6 @@ use acvm::{ acir::native_types::{WitnessMap, WitnessStack}, - BlackBoxFunctionSolver, + BlackBoxFunctionSolver, FieldElement, }; use noirc_abi::Abi; use noirc_driver::{compile_no_check, CompileError, CompileOptions}; @@ -23,7 +23,7 @@ impl TestStatus { } } -pub fn run_test( +pub fn run_test>( blackbox_solver: &B, context: &mut Context, test_function: &TestFunction, @@ -76,7 +76,7 @@ fn test_status_program_compile_pass( test_function: &TestFunction, abi: Abi, debug: Vec, - circuit_execution: Result, + circuit_execution: Result, NargoError>, ) -> TestStatus { let circuit_execution_err = match circuit_execution { // Circuit execution was successful; ie no errors or unsatisfied constraints diff --git a/tooling/nargo/src/ops/transform.rs b/tooling/nargo/src/ops/transform.rs index b4811bd5780..9255ac3e0ec 100644 --- a/tooling/nargo/src/ops/transform.rs +++ b/tooling/nargo/src/ops/transform.rs @@ -1,4 +1,7 @@ -use acvm::acir::circuit::{ExpressionWidth, Program}; +use acvm::{ + acir::circuit::{ExpressionWidth, Program}, + FieldElement, +}; use iter_extended::vecmap; use noirc_driver::{CompiledContract, CompiledProgram}; use noirc_errors::debug_info::DebugInfo; @@ -30,10 +33,10 @@ pub fn transform_contract( } fn transform_program_internal( - mut program: Program, + mut program: Program, debug: &mut [DebugInfo], expression_width: ExpressionWidth, -) -> Program { +) -> Program { let functions = std::mem::take(&mut program.functions); let optimized_functions = functions diff --git a/tooling/nargo_cli/Cargo.toml b/tooling/nargo_cli/Cargo.toml index d10dd6a22ff..9e886bc7002 100644 --- a/tooling/nargo_cli/Cargo.toml +++ b/tooling/nargo_cli/Cargo.toml @@ -32,7 +32,7 @@ noirc_driver.workspace = true noirc_frontend.workspace = true noirc_abi.workspace = true noirc_errors.workspace = true -acvm.workspace = true +acvm = { workspace = true, features = ["bn254"] } bn254_blackbox_solver.workspace = true toml.workspace = true serde.workspace = true diff --git a/tooling/nargo_cli/src/cli/dap_cmd.rs b/tooling/nargo_cli/src/cli/dap_cmd.rs index eded2bfd8d2..a84e961cfe7 100644 --- a/tooling/nargo_cli/src/cli/dap_cmd.rs +++ b/tooling/nargo_cli/src/cli/dap_cmd.rs @@ -1,5 +1,6 @@ use acvm::acir::circuit::ExpressionWidth; use acvm::acir::native_types::WitnessMap; +use acvm::FieldElement; use bn254_blackbox_solver::Bn254BlackBoxSolver; use clap::Args; use nargo::constants::PROVER_INPUT_FILE; @@ -101,7 +102,7 @@ fn load_and_compile_project( expression_width: ExpressionWidth, acir_mode: bool, skip_instrumentation: bool, -) -> Result<(CompiledProgram, WitnessMap), LoadError> { +) -> Result<(CompiledProgram, WitnessMap), LoadError> { let workspace = find_workspace(project_folder, package) .ok_or(LoadError::Generic(workspace_not_found_error_msg(project_folder, package)))?; let package = workspace diff --git a/tooling/nargo_cli/src/cli/debug_cmd.rs b/tooling/nargo_cli/src/cli/debug_cmd.rs index 7865b608261..adc17f41598 100644 --- a/tooling/nargo_cli/src/cli/debug_cmd.rs +++ b/tooling/nargo_cli/src/cli/debug_cmd.rs @@ -1,6 +1,7 @@ use std::path::PathBuf; use acvm::acir::native_types::{WitnessMap, WitnessStack}; +use acvm::FieldElement; use bn254_blackbox_solver::Bn254BlackBoxSolver; use clap::Args; @@ -199,7 +200,7 @@ fn debug_program_and_decode( program: CompiledProgram, package: &Package, prover_name: &str, -) -> Result<(Option, Option), CliError> { +) -> Result<(Option, Option>), CliError> { // Parse the initial witness values from Prover.toml let (inputs_map, _) = read_inputs_from_file(&package.root_dir, prover_name, Format::Toml, &program.abi)?; @@ -218,7 +219,7 @@ fn debug_program_and_decode( pub(crate) fn debug_program( compiled_program: &CompiledProgram, inputs_map: &InputMap, -) -> Result, CliError> { +) -> Result>, CliError> { let initial_witness = compiled_program.abi.encode(inputs_map, None)?; let debug_artifact = DebugArtifact { diff --git a/tooling/nargo_cli/src/cli/execute_cmd.rs b/tooling/nargo_cli/src/cli/execute_cmd.rs index 3fcedbb8f54..c312cc4cfd6 100644 --- a/tooling/nargo_cli/src/cli/execute_cmd.rs +++ b/tooling/nargo_cli/src/cli/execute_cmd.rs @@ -1,4 +1,5 @@ use acvm::acir::native_types::WitnessStack; +use acvm::FieldElement; use bn254_blackbox_solver::Bn254BlackBoxSolver; use clap::Args; @@ -91,7 +92,7 @@ fn execute_program_and_decode( package: &Package, prover_name: &str, foreign_call_resolver_url: Option<&str>, -) -> Result<(Option, WitnessStack), CliError> { +) -> Result<(Option, WitnessStack), CliError> { // Parse the initial witness values from Prover.toml let (inputs_map, _) = read_inputs_from_file(&package.root_dir, prover_name, Format::Toml, &program.abi)?; @@ -109,7 +110,7 @@ pub(crate) fn execute_program( compiled_program: &CompiledProgram, inputs_map: &InputMap, foreign_call_resolver_url: Option<&str>, -) -> Result { +) -> Result, CliError> { let initial_witness = compiled_program.abi.encode(inputs_map, None)?; let solved_witness_stack_err = nargo::ops::execute_program( diff --git a/tooling/nargo_cli/src/cli/fs/witness.rs b/tooling/nargo_cli/src/cli/fs/witness.rs index 613cdec28da..f95eb3d7a4c 100644 --- a/tooling/nargo_cli/src/cli/fs/witness.rs +++ b/tooling/nargo_cli/src/cli/fs/witness.rs @@ -1,13 +1,13 @@ use std::path::{Path, PathBuf}; -use acvm::acir::native_types::WitnessStack; +use acvm::{acir::native_types::WitnessStack, FieldElement}; use nargo::constants::WITNESS_EXT; use super::{create_named_dir, write_to_file}; use crate::errors::FilesystemError; pub(crate) fn save_witness_to_dir>( - witness_stack: WitnessStack, + witness_stack: WitnessStack, witness_name: &str, witness_dir: P, ) -> Result { diff --git a/tooling/nargo_cli/src/cli/test_cmd.rs b/tooling/nargo_cli/src/cli/test_cmd.rs index 51e21248afd..99c284e5019 100644 --- a/tooling/nargo_cli/src/cli/test_cmd.rs +++ b/tooling/nargo_cli/src/cli/test_cmd.rs @@ -1,6 +1,6 @@ use std::io::Write; -use acvm::BlackBoxFunctionSolver; +use acvm::{BlackBoxFunctionSolver, FieldElement}; use bn254_blackbox_solver::Bn254BlackBoxSolver; use clap::Args; use fm::FileManager; @@ -119,7 +119,7 @@ pub(crate) fn run(args: TestCommand, config: NargoConfig) -> Result<(), CliError } } -fn run_tests( +fn run_tests + Default>( file_manager: &FileManager, parsed_files: &ParsedFiles, package: &Package, @@ -157,7 +157,7 @@ fn run_tests( Ok(test_report) } -fn run_test( +fn run_test + Default>( file_manager: &FileManager, parsed_files: &ParsedFiles, package: &Package, diff --git a/tooling/noirc_abi/src/input_parser/json.rs b/tooling/noirc_abi/src/input_parser/json.rs index 7618cd6c15a..070f9effe42 100644 --- a/tooling/noirc_abi/src/input_parser/json.rs +++ b/tooling/noirc_abi/src/input_parser/json.rs @@ -1,6 +1,6 @@ use super::{parse_str_to_field, InputValue}; use crate::{errors::InputParserError, Abi, AbiType, MAIN_RETURN_NAME}; -use acvm::FieldElement; +use acvm::{AcirField, FieldElement}; use iter_extended::{try_btree_map, try_vecmap}; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; diff --git a/tooling/noirc_abi/src/input_parser/mod.rs b/tooling/noirc_abi/src/input_parser/mod.rs index 9629ddc87ab..14d92bc71b3 100644 --- a/tooling/noirc_abi/src/input_parser/mod.rs +++ b/tooling/noirc_abi/src/input_parser/mod.rs @@ -3,7 +3,7 @@ use num_traits::{Num, Zero}; use std::collections::{BTreeMap, HashSet}; use thiserror::Error; -use acvm::FieldElement; +use acvm::{AcirField, FieldElement}; use serde::Serialize; use crate::errors::InputParserError; @@ -229,7 +229,7 @@ impl Format { mod serialization_tests { use std::collections::BTreeMap; - use acvm::FieldElement; + use acvm::{AcirField, FieldElement}; use strum::IntoEnumIterator; use crate::{ @@ -362,7 +362,7 @@ fn field_from_big_int(bigint: BigInt) -> FieldElement { #[cfg(test)] mod test { - use acvm::FieldElement; + use acvm::{AcirField, FieldElement}; use num_bigint::BigUint; use super::parse_str_to_field; diff --git a/tooling/noirc_abi/src/input_parser/toml.rs b/tooling/noirc_abi/src/input_parser/toml.rs index b216fe58794..321d3511b5d 100644 --- a/tooling/noirc_abi/src/input_parser/toml.rs +++ b/tooling/noirc_abi/src/input_parser/toml.rs @@ -1,6 +1,6 @@ use super::{parse_str_to_field, parse_str_to_signed, InputValue}; use crate::{errors::InputParserError, Abi, AbiType, MAIN_RETURN_NAME}; -use acvm::FieldElement; +use acvm::{AcirField, FieldElement}; use iter_extended::{try_btree_map, try_vecmap}; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; diff --git a/tooling/noirc_abi/src/lib.rs b/tooling/noirc_abi/src/lib.rs index 7a1d1787ca5..0acace71fb3 100644 --- a/tooling/noirc_abi/src/lib.rs +++ b/tooling/noirc_abi/src/lib.rs @@ -8,7 +8,7 @@ use acvm::{ circuit::ErrorSelector, native_types::{Witness, WitnessMap}, }, - FieldElement, + AcirField, FieldElement, }; use errors::AbiError; use input_parser::InputValue; @@ -331,7 +331,7 @@ impl Abi { &self, input_map: &InputMap, return_value: Option, - ) -> Result { + ) -> Result, AbiError> { // Check that no extra witness values have been provided. let param_names = self.parameter_names(); if param_names.len() < input_map.len() { @@ -439,7 +439,7 @@ impl Abi { /// Decode a `WitnessMap` into the types specified in the ABI. pub fn decode( &self, - witness_map: &WitnessMap, + witness_map: &WitnessMap, ) -> Result<(InputMap, Option), AbiError> { let public_inputs_map = try_btree_map(self.parameters.clone(), |AbiParameter { name, typ, .. }| { @@ -652,7 +652,7 @@ pub fn display_abi_error( mod test { use std::collections::BTreeMap; - use acvm::{acir::native_types::Witness, FieldElement}; + use acvm::{acir::native_types::Witness, AcirField, FieldElement}; use crate::{ input_parser::InputValue, Abi, AbiParameter, AbiReturnType, AbiType, AbiVisibility, diff --git a/tooling/noirc_abi_wasm/Cargo.toml b/tooling/noirc_abi_wasm/Cargo.toml index c78c3ead0c3..5692c757d3e 100644 --- a/tooling/noirc_abi_wasm/Cargo.toml +++ b/tooling/noirc_abi_wasm/Cargo.toml @@ -12,7 +12,7 @@ license.workspace = true crate-type = ["cdylib"] [dependencies] -acvm.workspace = true +acvm = { workspace = true, features = ["bn254"] } noirc_abi.workspace = true iter-extended.workspace = true wasm-bindgen.workspace = true diff --git a/tooling/noirc_abi_wasm/src/js_witness_map.rs b/tooling/noirc_abi_wasm/src/js_witness_map.rs index 293c5c089f8..a82621822e4 100644 --- a/tooling/noirc_abi_wasm/src/js_witness_map.rs +++ b/tooling/noirc_abi_wasm/src/js_witness_map.rs @@ -2,7 +2,7 @@ use acvm::{ acir::native_types::{Witness, WitnessMap}, - FieldElement, + AcirField, FieldElement, }; use js_sys::{JsString, Map}; use wasm_bindgen::prelude::{wasm_bindgen, JsValue}; @@ -25,8 +25,8 @@ impl Default for JsWitnessMap { } } -impl From for JsWitnessMap { - fn from(witness_map: WitnessMap) -> Self { +impl From> for JsWitnessMap { + fn from(witness_map: WitnessMap) -> Self { let js_map = JsWitnessMap::new(); for (key, value) in witness_map { js_map.set( @@ -38,7 +38,7 @@ impl From for JsWitnessMap { } } -impl From for WitnessMap { +impl From for WitnessMap { fn from(js_map: JsWitnessMap) -> Self { let mut witness_map = WitnessMap::new(); js_map.for_each(&mut |value, key| { @@ -73,7 +73,7 @@ mod test { use acvm::{ acir::native_types::{Witness, WitnessMap}, - FieldElement, + AcirField, FieldElement, }; use wasm_bindgen::JsValue; diff --git a/tooling/noirc_abi_wasm/src/lib.rs b/tooling/noirc_abi_wasm/src/lib.rs index 10c0c43b352..ef4a468b661 100644 --- a/tooling/noirc_abi_wasm/src/lib.rs +++ b/tooling/noirc_abi_wasm/src/lib.rs @@ -5,9 +5,12 @@ // See Cargo.toml for explanation. use getrandom as _; -use acvm::acir::{ - circuit::RawAssertionPayload, - native_types::{WitnessMap, WitnessStack}, +use acvm::{ + acir::{ + circuit::RawAssertionPayload, + native_types::{WitnessMap, WitnessStack}, + }, + FieldElement, }; use iter_extended::try_btree_map; use noirc_abi::{ @@ -125,8 +128,8 @@ pub fn abi_decode(abi: JsAbi, witness_map: JsWitnessMap) -> Result Result, JsAbiError> { console_error_panic_hook::set_once(); - let converted_witness: WitnessMap = witness_map.into(); - let witness_stack: WitnessStack = converted_witness.into(); + let converted_witness: WitnessMap = witness_map.into(); + let witness_stack: WitnessStack = converted_witness.into(); let output = witness_stack.try_into(); output.map_err(|_| JsAbiError::new("Failed to convert to Vec".to_string())) } @@ -140,7 +143,7 @@ pub fn abi_decode_error( let mut abi: Abi = JsValueSerdeExt::into_serde(&JsValue::from(abi)).map_err(|err| err.to_string())?; - let raw_error: RawAssertionPayload = + let raw_error: RawAssertionPayload = JsValueSerdeExt::into_serde(&JsValue::from(raw_error)).map_err(|err| err.to_string())?; let error_type = abi.error_types.remove(&raw_error.selector).expect("Missing error type"); From 33c2b6b8102aad5597aa9d71b04a59185bb285cf Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 28 May 2024 17:03:21 +0100 Subject: [PATCH 36/61] chore: remove warnings field from `DebugArtifact` (#5118) # Description ## Problem\* Resolves ## Summary\* I'm not sure why the SSA warnings were ever added onto the `DebugArtifact` but we don't use it at all so we can just remove them (which avoids a dependency on `noirc_evaluator`) ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- Cargo.lock | 1 - tooling/debugger/src/context.rs | 9 +++------ tooling/debugger/src/dap.rs | 6 +----- tooling/nargo/Cargo.toml | 1 - tooling/nargo/src/artifacts/debug.rs | 23 ++++------------------- tooling/nargo_cli/src/cli/debug_cmd.rs | 1 - tooling/nargo_cli/src/cli/execute_cmd.rs | 1 - 7 files changed, 8 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 919bdc48748..f1ea5929d32 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2484,7 +2484,6 @@ dependencies = [ "noirc_abi", "noirc_driver", "noirc_errors", - "noirc_evaluator", "noirc_frontend", "noirc_printable_type", "rayon", diff --git a/tooling/debugger/src/context.rs b/tooling/debugger/src/context.rs index 110e3211e24..9dc5c758c6f 100644 --- a/tooling/debugger/src/context.rs +++ b/tooling/debugger/src/context.rs @@ -679,8 +679,7 @@ mod tests { let debug_symbols = vec![]; let file_map = BTreeMap::new(); - let warnings = vec![]; - let debug_artifact = &DebugArtifact { debug_symbols, file_map, warnings }; + let debug_artifact = &DebugArtifact { debug_symbols, file_map }; let initial_witness = BTreeMap::from([(Witness(1), fe_1)]).into(); @@ -789,8 +788,7 @@ mod tests { let debug_symbols = vec![]; let file_map = BTreeMap::new(); - let warnings = vec![]; - let debug_artifact = &DebugArtifact { debug_symbols, file_map, warnings }; + let debug_artifact = &DebugArtifact { debug_symbols, file_map }; let initial_witness = BTreeMap::from([(Witness(1), fe_1), (Witness(2), fe_1)]).into(); @@ -847,8 +845,7 @@ mod tests { Opcode::AssertZero(Expression::default()), ]; let circuit = Circuit { opcodes, ..Circuit::default() }; - let debug_artifact = - DebugArtifact { debug_symbols: vec![], file_map: BTreeMap::new(), warnings: vec![] }; + let debug_artifact = DebugArtifact { debug_symbols: vec![], file_map: BTreeMap::new() }; let brillig_funcs = &vec![brillig_bytecode]; let context = DebugContext::new( &StubbedBlackBoxSolver, diff --git a/tooling/debugger/src/dap.rs b/tooling/debugger/src/dap.rs index d0ed0559b89..40b77f0ad2a 100644 --- a/tooling/debugger/src/dap.rs +++ b/tooling/debugger/src/dap.rs @@ -608,11 +608,7 @@ pub fn run_session>( program: CompiledProgram, initial_witness: WitnessMap, ) -> Result<(), ServerError> { - let debug_artifact = DebugArtifact { - debug_symbols: program.debug, - file_map: program.file_map, - warnings: program.warnings, - }; + let debug_artifact = DebugArtifact { debug_symbols: program.debug, file_map: program.file_map }; let mut session = DapSession::new( server, solver, diff --git a/tooling/nargo/Cargo.toml b/tooling/nargo/Cargo.toml index 72b412ac5b9..48047d10ea6 100644 --- a/tooling/nargo/Cargo.toml +++ b/tooling/nargo/Cargo.toml @@ -15,7 +15,6 @@ fm.workspace = true noirc_abi.workspace = true noirc_driver.workspace = true noirc_errors.workspace = true -noirc_evaluator.workspace = true noirc_frontend.workspace = true noirc_printable_type.workspace = true iter-extended.workspace = true diff --git a/tooling/nargo/src/artifacts/debug.rs b/tooling/nargo/src/artifacts/debug.rs index 2570c3f5c9f..21102c40fcf 100644 --- a/tooling/nargo/src/artifacts/debug.rs +++ b/tooling/nargo/src/artifacts/debug.rs @@ -1,7 +1,6 @@ use codespan_reporting::files::{Error, Files, SimpleFile}; use noirc_driver::{CompiledContract, CompiledProgram, DebugFile}; use noirc_errors::{debug_info::DebugInfo, Location}; -use noirc_evaluator::errors::SsaReport; use serde::{Deserialize, Serialize}; use std::{ collections::{BTreeMap, BTreeSet}, @@ -18,7 +17,6 @@ use fm::{FileId, FileManager, PathString}; pub struct DebugArtifact { pub debug_symbols: Vec, pub file_map: BTreeMap, - pub warnings: Vec, } impl DebugArtifact { @@ -45,7 +43,7 @@ impl DebugArtifact { ); } - Self { debug_symbols, file_map, warnings: Vec::new() } + Self { debug_symbols, file_map } } /// Given a location, returns its file's source code @@ -121,11 +119,7 @@ impl DebugArtifact { impl From for DebugArtifact { fn from(compiled_program: CompiledProgram) -> Self { - DebugArtifact { - debug_symbols: compiled_program.debug, - file_map: compiled_program.file_map, - warnings: compiled_program.warnings, - } + DebugArtifact { debug_symbols: compiled_program.debug, file_map: compiled_program.file_map } } } @@ -134,7 +128,6 @@ impl From for DebugArtifact { DebugArtifact { debug_symbols: program_artifact.debug_symbols.debug_infos, file_map: program_artifact.file_map, - warnings: Vec::new(), } } } @@ -147,11 +140,7 @@ impl From for DebugArtifact { .flat_map(|contract_function| contract_function.debug) .collect(); - DebugArtifact { - debug_symbols: all_functions_debug, - file_map: compiled_artifact.file_map, - warnings: compiled_artifact.warnings, - } + DebugArtifact { debug_symbols: all_functions_debug, file_map: compiled_artifact.file_map } } } @@ -163,11 +152,7 @@ impl From for DebugArtifact { .flat_map(|contract_function| contract_function.debug_symbols.debug_infos) .collect(); - DebugArtifact { - debug_symbols: all_functions_debug, - file_map: compiled_artifact.file_map, - warnings: Vec::new(), - } + DebugArtifact { debug_symbols: all_functions_debug, file_map: compiled_artifact.file_map } } } diff --git a/tooling/nargo_cli/src/cli/debug_cmd.rs b/tooling/nargo_cli/src/cli/debug_cmd.rs index adc17f41598..ebcd9ff6569 100644 --- a/tooling/nargo_cli/src/cli/debug_cmd.rs +++ b/tooling/nargo_cli/src/cli/debug_cmd.rs @@ -225,7 +225,6 @@ pub(crate) fn debug_program( let debug_artifact = DebugArtifact { debug_symbols: compiled_program.debug.clone(), file_map: compiled_program.file_map.clone(), - warnings: compiled_program.warnings.clone(), }; noir_debugger::debug_circuit( diff --git a/tooling/nargo_cli/src/cli/execute_cmd.rs b/tooling/nargo_cli/src/cli/execute_cmd.rs index c312cc4cfd6..5d6754b29f7 100644 --- a/tooling/nargo_cli/src/cli/execute_cmd.rs +++ b/tooling/nargo_cli/src/cli/execute_cmd.rs @@ -125,7 +125,6 @@ pub(crate) fn execute_program( let debug_artifact = DebugArtifact { debug_symbols: compiled_program.debug.clone(), file_map: compiled_program.file_map.clone(), - warnings: compiled_program.warnings.clone(), }; if let Some(diagnostic) = From a40a9a55571deed386688fb84260bdf2794d4d38 Mon Sep 17 00:00:00 2001 From: Aztec Bot <49558828+AztecBot@users.noreply.github.com> Date: Tue, 28 May 2024 12:09:10 -0400 Subject: [PATCH 37/61] feat: Sync from aztec-packages (#5125) Automated pull of Noir development from [aztec-packages](https://github.com/AztecProtocol/aztec-packages). BEGIN_COMMIT_OVERRIDE feat: remove external blackbox solver from acir simulator (https://github.com/AztecProtocol/aztec-packages/pull/6586) chore: remove aes slice (https://github.com/AztecProtocol/aztec-packages/pull/6550) END_COMMIT_OVERRIDE --------- Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> Co-authored-by: TomAFrench --- .aztec-sync-commit | 2 +- acvm-repo/acvm_js/src/execute.rs | 57 +---------- acvm-repo/acvm_js/src/lib.rs | 5 +- .../test/browser/execute_circuit.test.ts | 30 +----- .../acvm_js/test/node/execute_circuit.test.ts | 37 ++----- aztec_macros/src/lib.rs | 13 +-- .../src/transforms/contract_interface.rs | 6 +- aztec_macros/src/transforms/functions.rs | 47 ++++----- aztec_macros/src/transforms/note_interface.rs | 96 ++++++++++++++++--- aztec_macros/src/utils/hir_utils.rs | 2 +- .../test/browser/recursion.test.ts | 3 +- .../onchain_recursive_verification.test.ts | 3 +- noir_stdlib/src/aes128.nr | 3 - .../ecdsa_secp256r1_3x/Nargo.toml | 7 ++ .../ecdsa_secp256r1_3x/Prover.toml | 57 +++++++++++ .../ecdsa_secp256r1_3x/src/main.nr | 23 +++++ tooling/noir_js/src/witness_generation.ts | 26 +---- 17 files changed, 221 insertions(+), 196 deletions(-) create mode 100644 test_programs/execution_success/ecdsa_secp256r1_3x/Nargo.toml create mode 100644 test_programs/execution_success/ecdsa_secp256r1_3x/Prover.toml create mode 100644 test_programs/execution_success/ecdsa_secp256r1_3x/src/main.nr diff --git a/.aztec-sync-commit b/.aztec-sync-commit index 82e81e9d74c..fdbc14d511e 100644 --- a/.aztec-sync-commit +++ b/.aztec-sync-commit @@ -1 +1 @@ -221e2479622aef8e70120dc0a9f91ffcbc99efba +1d785fd1087d7387fc29213ca3be50b2fc9c4725 diff --git a/acvm-repo/acvm_js/src/execute.rs b/acvm-repo/acvm_js/src/execute.rs index 85cc3f455a0..94ef30604e2 100644 --- a/acvm-repo/acvm_js/src/execute.rs +++ b/acvm-repo/acvm_js/src/execute.rs @@ -19,20 +19,6 @@ use crate::{ JsExecutionError, JsSolvedAndReturnWitness, JsWitnessMap, JsWitnessStack, }; -#[wasm_bindgen] -pub struct WasmBlackBoxFunctionSolver; - -impl WasmBlackBoxFunctionSolver { - async fn initialize() -> WasmBlackBoxFunctionSolver { - WasmBlackBoxFunctionSolver - } -} - -#[wasm_bindgen(js_name = "createBlackBoxSolver")] -pub async fn create_black_box_solver() -> WasmBlackBoxFunctionSolver { - WasmBlackBoxFunctionSolver::initialize().await -} - /// Executes an ACIR circuit to generate the solved witness from the initial witness. /// /// @param {Uint8Array} circuit - A serialized representation of an ACIR circuit @@ -58,14 +44,12 @@ pub async fn execute_circuit( /// Executes an ACIR circuit to generate the solved witness from the initial witness. /// This method also extracts the public return values from the solved witness into its own return witness. /// -/// @param {&WasmBlackBoxFunctionSolver} solver - A black box solver. /// @param {Uint8Array} circuit - A serialized representation of an ACIR circuit /// @param {WitnessMap} initial_witness - The initial witness map defining all of the inputs to `circuit`.. /// @param {ForeignCallHandler} foreign_call_handler - A callback to process any foreign calls from the circuit. /// @returns {SolvedAndReturnWitness} The solved witness calculated by executing the circuit on the provided inputs, as well as the return witness indices as specified by the circuit. #[wasm_bindgen(js_name = executeCircuitWithReturnWitness, skip_jsdoc)] pub async fn execute_circuit_with_return_witness( - _solver: &WasmBlackBoxFunctionSolver, program: Vec, initial_witness: JsWitnessMap, foreign_call_handler: ForeignCallHandler, @@ -94,28 +78,10 @@ pub async fn execute_circuit_with_return_witness( /// Executes an ACIR circuit to generate the solved witness from the initial witness. /// -/// @param {&WasmBlackBoxFunctionSolver} solver - A black box solver. -/// @param {Uint8Array} circuit - A serialized representation of an ACIR circuit -/// @param {WitnessMap} initial_witness - The initial witness map defining all of the inputs to `circuit`.. -/// @param {ForeignCallHandler} foreign_call_handler - A callback to process any foreign calls from the circuit. -/// @returns {WitnessMap} The solved witness calculated by executing the circuit on the provided inputs. -#[wasm_bindgen(js_name = executeCircuitWithBlackBoxSolver, skip_jsdoc)] -pub async fn execute_circuit_with_black_box_solver( - _solver: &WasmBlackBoxFunctionSolver, - program: Vec, - initial_witness: JsWitnessMap, - foreign_call_handler: ForeignCallHandler, -) -> Result { - console_error_panic_hook::set_once(); - - let mut witness_stack = - execute_program_with_native_type_return(program, initial_witness, &foreign_call_handler) - .await?; - let witness_map = - witness_stack.pop().expect("Should have at least one witness on the stack").witness; - Ok(witness_map.into()) -} - +/// @param {Uint8Array} program - A serialized representation of an ACIR program +/// @param {WitnessMap} initial_witness - The initial witness map defining all of the inputs to `program`. +/// @param {ForeignCallHandler} foreign_call_handler - A callback to process any foreign calls from the program. +/// @returns {WitnessStack} The solved witness calculated by executing the program on the provided inputs. #[wasm_bindgen(js_name = executeProgram, skip_jsdoc)] pub async fn execute_program( program: Vec, @@ -124,21 +90,8 @@ pub async fn execute_program( ) -> Result { console_error_panic_hook::set_once(); - let solver = WasmBlackBoxFunctionSolver::initialize().await; - - execute_program_with_black_box_solver(&solver, program, initial_witness, &foreign_call_handler) - .await -} - -#[wasm_bindgen(js_name = executeProgramWithBlackBoxSolver, skip_jsdoc)] -pub async fn execute_program_with_black_box_solver( - _solver: &WasmBlackBoxFunctionSolver, - program: Vec, - initial_witness: JsWitnessMap, - foreign_call_executor: &ForeignCallHandler, -) -> Result { let witness_stack = - execute_program_with_native_type_return(program, initial_witness, foreign_call_executor) + execute_program_with_native_type_return(program, initial_witness, &foreign_call_handler) .await?; Ok(witness_stack.into()) diff --git a/acvm-repo/acvm_js/src/lib.rs b/acvm-repo/acvm_js/src/lib.rs index 3b8210f4875..fdb8d5ffe08 100644 --- a/acvm-repo/acvm_js/src/lib.rs +++ b/acvm-repo/acvm_js/src/lib.rs @@ -23,10 +23,7 @@ pub use build_info::build_info; pub use compression::{ compress_witness, compress_witness_stack, decompress_witness, decompress_witness_stack, }; -pub use execute::{ - create_black_box_solver, execute_circuit, execute_circuit_with_black_box_solver, - execute_circuit_with_return_witness, execute_program, execute_program_with_black_box_solver, -}; +pub use execute::{execute_circuit, execute_circuit_with_return_witness, execute_program}; pub use js_execution_error::JsExecutionError; pub use js_witness_map::JsSolvedAndReturnWitness; pub use js_witness_map::JsWitnessMap; diff --git a/acvm-repo/acvm_js/test/browser/execute_circuit.test.ts b/acvm-repo/acvm_js/test/browser/execute_circuit.test.ts index 625cc91cfe9..cfd5523b79f 100644 --- a/acvm-repo/acvm_js/test/browser/execute_circuit.test.ts +++ b/acvm-repo/acvm_js/test/browser/execute_circuit.test.ts @@ -1,13 +1,5 @@ import { expect } from '@esm-bundle/chai'; -import initACVM, { - createBlackBoxSolver, - executeCircuit, - executeCircuitWithBlackBoxSolver, - WasmBlackBoxFunctionSolver, - WitnessMap, - initLogLevel, - ForeignCallHandler, -} from '@noir-lang/acvm_js'; +import initACVM, { executeCircuit, WitnessMap, initLogLevel, ForeignCallHandler } from '@noir-lang/acvm_js'; beforeEach(async () => { await initACVM(); @@ -122,23 +114,3 @@ it('successfully executes a MemoryOp opcode', async () => { expect(solvedWitness).to.be.deep.eq(expectedWitnessMap); }); - -it('successfully executes two circuits with same backend', async function () { - // chose pedersen op here because it is the one with slow initialization - // that led to the decision to pull backend initialization into a separate - // function/wasmbind - const solver: WasmBlackBoxFunctionSolver = await createBlackBoxSolver(); - - const { bytecode, initialWitnessMap, expectedWitnessMap } = await import('../shared/pedersen'); - - const solvedWitness0: WitnessMap = await executeCircuitWithBlackBoxSolver(solver, bytecode, initialWitnessMap, () => { - throw Error('unexpected oracle'); - }); - - expect(solvedWitness0).to.be.deep.eq(expectedWitnessMap); - - const solvedWitness1: WitnessMap = await executeCircuitWithBlackBoxSolver(solver, bytecode, initialWitnessMap, () => { - throw Error('unexpected oracle'); - }); - expect(solvedWitness1).to.be.deep.eq(expectedWitnessMap); -}); diff --git a/acvm-repo/acvm_js/test/node/execute_circuit.test.ts b/acvm-repo/acvm_js/test/node/execute_circuit.test.ts index 3f9bde2898e..1e3517e8814 100644 --- a/acvm-repo/acvm_js/test/node/execute_circuit.test.ts +++ b/acvm-repo/acvm_js/test/node/execute_circuit.test.ts @@ -1,9 +1,6 @@ import { expect } from 'chai'; import { - createBlackBoxSolver, executeCircuit, - executeCircuitWithBlackBoxSolver, - WasmBlackBoxFunctionSolver, WitnessMap, ForeignCallHandler, executeProgram, @@ -120,40 +117,18 @@ it('successfully executes a MemoryOp opcode', async () => { expect(solvedWitness).to.be.deep.eq(expectedWitnessMap); }); -it('successfully executes two circuits with same backend', async function () { - this.timeout(10000); - - // chose pedersen op here because it is the one with slow initialization - // that led to the decision to pull backend initialization into a separate - // function/wasmbind - const solver: WasmBlackBoxFunctionSolver = await createBlackBoxSolver(); - - const { bytecode, initialWitnessMap, expectedWitnessMap } = await import('../shared/pedersen'); - - const solvedWitness0 = await executeCircuitWithBlackBoxSolver(solver, bytecode, initialWitnessMap, () => { - throw Error('unexpected oracle'); - }); - - const solvedWitness1 = await executeCircuitWithBlackBoxSolver(solver, bytecode, initialWitnessMap, () => { - throw Error('unexpected oracle'); - }); - - expect(solvedWitness0).to.be.deep.eq(expectedWitnessMap); - expect(solvedWitness1).to.be.deep.eq(expectedWitnessMap); -}); - -it('successfully executes 500 circuits with same backend', async function () { +it('successfully executes 500 pedersen circuits', async function () { this.timeout(100000); - // chose pedersen op here because it is the one with slow initialization - // that led to the decision to pull backend initialization into a separate - // function/wasmbind - const solver: WasmBlackBoxFunctionSolver = await createBlackBoxSolver(); + // Pedersen opcodes used to have a large upfront cost due to generator calculation + // so we'd need to pass around the blackbox solver in JS to avoid redoing this work. + // + // This test now shows that we don't need to do this anymore without a performance regression. const { bytecode, initialWitnessMap, expectedWitnessMap } = await import('../shared/pedersen'); for (let i = 0; i < 500; i++) { - const solvedWitness = await executeCircuitWithBlackBoxSolver(solver, bytecode, initialWitnessMap, () => { + const solvedWitness = await executeCircuit(bytecode, initialWitnessMap, () => { throw Error('unexpected oracle'); }); diff --git a/aztec_macros/src/lib.rs b/aztec_macros/src/lib.rs index 5326920511b..2daf86dc643 100644 --- a/aztec_macros/src/lib.rs +++ b/aztec_macros/src/lib.rs @@ -134,7 +134,6 @@ fn transform_module( for func in module.functions.iter_mut() { let mut is_private = false; let mut is_public = false; - let mut is_public_vm = false; let mut is_initializer = false; let mut is_internal = false; let mut insert_init_check = has_initializer; @@ -152,8 +151,6 @@ fn transform_module( is_internal = true; } else if is_custom_attribute(&secondary_attribute, "aztec(public)") { is_public = true; - } else if is_custom_attribute(&secondary_attribute, "aztec(public-vm)") { - is_public_vm = true; } if is_custom_attribute(&secondary_attribute, "aztec(view)") { is_static = true; @@ -161,14 +158,8 @@ fn transform_module( } // Apply transformations to the function based on collected attributes - if is_private || is_public || is_public_vm { - let fn_type = if is_private { - "Private" - } else if is_public_vm { - "Avm" - } else { - "Public" - }; + if is_private || is_public { + let fn_type = if is_private { "Private" } else { "Public" }; let stub_src = stub_function(fn_type, func, is_static); stubs.push((stub_src, Location { file: *file_id, span: func.name_ident().span() })); diff --git a/aztec_macros/src/transforms/contract_interface.rs b/aztec_macros/src/transforms/contract_interface.rs index bb63357d251..90f9ce6164a 100644 --- a/aztec_macros/src/transforms/contract_interface.rs +++ b/aztec_macros/src/transforms/contract_interface.rs @@ -88,7 +88,7 @@ pub fn stub_function(aztec_visibility: &str, func: &NoirFunction, is_static_call }) .collect::>() .join(""); - if aztec_visibility != "Avm" { + if aztec_visibility != "Public" { let args_hash = if !parameters.is_empty() { format!( "let mut args_acc: [Field] = &[]; @@ -125,7 +125,7 @@ pub fn stub_function(aztec_visibility: &str, func: &NoirFunction, is_static_call ); let fn_body = format!( "{} - dep::aztec::context::Avm{}{}CallInterface {{ + dep::aztec::context::Public{}{}CallInterface {{ target_contract: self.target_contract, selector: {}, args: args_acc, @@ -134,7 +134,7 @@ pub fn stub_function(aztec_visibility: &str, func: &NoirFunction, is_static_call args, is_static, is_void, fn_selector, ); format!( - "pub fn {}(self, {}) -> dep::aztec::context::Avm{}{}CallInterface{} {{ + "pub fn {}(self, {}) -> dep::aztec::context::Public{}{}CallInterface{} {{ {} }}", fn_name, fn_parameters, is_static, is_void, return_type_hint, fn_body diff --git a/aztec_macros/src/transforms/functions.rs b/aztec_macros/src/transforms/functions.rs index 00e9c444421..0fb13975fec 100644 --- a/aztec_macros/src/transforms/functions.rs +++ b/aztec_macros/src/transforms/functions.rs @@ -36,15 +36,15 @@ pub fn transform_function( is_internal: bool, is_static: bool, ) -> Result<(), AztecMacroError> { + assert!(matches!(ty, "Private" | "Public")); let context_name = format!("{}Context", ty); let inputs_name = format!("{}ContextInputs", ty); let return_type_name = format!("{}CircuitPublicInputs", ty); - let is_avm = ty == "Avm"; let is_private = ty == "Private"; // Force a static context if the function is static if is_static { - let is_static_check = create_static_check(func.name(), is_avm); + let is_static_check = create_static_check(func.name(), is_private); func.def.body.statements.insert(0, is_static_check); } @@ -72,10 +72,10 @@ pub fn transform_function( } // Insert the context creation as the first action - let create_context = if !is_avm { - create_context(&context_name, &func.def.parameters)? + let create_context = if is_private { + create_context_private(&context_name, &func.def.parameters)? } else { - create_context_avm()? + create_context_public()? }; func.def.body.statements.splice(0..0, (create_context).iter().cloned()); @@ -84,7 +84,7 @@ pub fn transform_function( func.def.parameters.insert(0, input); // Abstract return types such that they get added to the kernel's return_values - if !is_avm { + if is_private { if let Some(return_values_statements) = abstract_return_values(func)? { // In case we are pushing return values to the context, we remove the statement that originated it // This avoids running duplicate code, since blocks like if/else can be value returning statements @@ -101,13 +101,13 @@ pub fn transform_function( } // Push the finish method call to the end of the function - if !is_avm { + if is_private { let finish_def = create_context_finish(); func.def.body.statements.push(finish_def); } // The AVM doesn't need a return type yet. - if !is_avm { + if is_private { let return_type = create_return_type(&return_type_name); func.def.return_type = return_type; func.def.return_visibility = Visibility::Public; @@ -116,7 +116,7 @@ pub fn transform_function( } // Public functions should have unconstrained auto-inferred - func.def.is_unconstrained = matches!(ty, "Public" | "Avm"); + func.def.is_unconstrained = !is_private; // Private functions need to be recursive if is_private { @@ -285,8 +285,8 @@ fn create_mark_as_initialized(ty: &str) -> Statement { /// ```noir /// assert(context.inputs.call_context.is_static_call == true, "Function can only be called statically") /// ``` -fn create_static_check(fname: &str, is_avm: bool) -> Statement { - let is_static_call_expr = if !is_avm { +fn create_static_check(fname: &str, is_private: bool) -> Statement { + let is_static_call_expr = if is_private { ["inputs", "call_context", "is_static_call"] .iter() .fold(variable("context"), |acc, member| member_access(acc, member)) @@ -410,7 +410,7 @@ fn serialize_to_hasher( /// let mut context = PrivateContext::new(inputs, hasher.hash()); /// } /// ``` -fn create_context(ty: &str, params: &[Param]) -> Result, AztecMacroError> { +fn create_context_private(ty: &str, params: &[Param]) -> Result, AztecMacroError> { let mut injected_statements: Vec = vec![]; let hasher_name = "args_hasher"; @@ -471,30 +471,33 @@ fn create_context(ty: &str, params: &[Param]) -> Result, AztecMac Ok(injected_statements) } -/// Creates the private context object to be accessed within the function, the parameters need to be extracted to be -/// appended into the args hash object. +/// Creates the public context object to be accessed within the function. /// /// The replaced code: /// ```noir -/// #[aztec(public-vm)] -/// fn foo(inputs: AvmContextInputs, ...) -> Field { -/// let mut context = AvmContext::new(inputs); +/// #[aztec(public)] +/// fn foo(inputs: PublicContextInputs, ...) -> Field { +/// let mut context = PublicContext::new(inputs); /// } /// ``` -fn create_context_avm() -> Result, AztecMacroError> { +fn create_context_public() -> Result, AztecMacroError> { let mut injected_expressions: Vec = vec![]; // Create the inputs to the context - let ty = "AvmContext"; let inputs_expression = variable("inputs"); - let path_snippet = ty.to_case(Case::Snake); // e.g. private_context // let mut context = {ty}::new(inputs, hash); let let_context = mutable_assignment( "context", // Assigned to call( - variable_path(chained_dep!("aztec", "context", &path_snippet, ty, "new")), // Path - vec![inputs_expression], // args + variable_path(chained_dep!( + "aztec", + "context", + "public_context", + "PublicContext", + "new" + )), // Path + vec![inputs_expression], // args ), ); injected_expressions.push(let_context); diff --git a/aztec_macros/src/transforms/note_interface.rs b/aztec_macros/src/transforms/note_interface.rs index f183c69b27a..fdce8b81db2 100644 --- a/aztec_macros/src/transforms/note_interface.rs +++ b/aztec_macros/src/transforms/note_interface.rs @@ -76,19 +76,27 @@ pub fn generate_note_interface_impl(module: &mut SortedModule) -> Result<(), Azt // Identify the note type (struct name), its fields and its serialized length (generic param of NoteInterface trait impl) let note_type = note_struct.name.0.contents.to_string(); let mut note_fields = vec![]; - let note_serialized_len = match &trait_impl.trait_generics[0].typ { - UnresolvedTypeData::Named(path, _, _) => Ok(path.last_segment().0.contents.to_string()), - UnresolvedTypeData::Expression(UnresolvedTypeExpression::Constant(val, _)) => { - Ok(val.to_string()) - } - _ => Err(AztecMacroError::CouldNotImplementNoteInterface { - span: trait_impl.object_type.span, - secondary_message: Some(format!( - "Cannot find note serialization length for: {}", - note_type - )), - }), - }?; + let note_interface_generics = trait_impl + .trait_generics + .iter() + .map(|gen| match gen.typ.clone() { + UnresolvedTypeData::Named(path, _, _) => { + Ok(path.last_segment().0.contents.to_string()) + } + UnresolvedTypeData::Expression(UnresolvedTypeExpression::Constant(val, _)) => { + Ok(val.to_string()) + } + _ => Err(AztecMacroError::CouldNotImplementNoteInterface { + span: trait_impl.object_type.span, + secondary_message: Some(format!( + "NoteInterface must be generic over NOTE_LEN and NOTE_BYTES_LEN: {}", + note_type + )), + }), + }) + .collect::, _>>()?; + let [note_serialized_len, note_bytes_len]: [_; 2] = + note_interface_generics.try_into().unwrap(); let note_type_id = note_type_id(¬e_type); // Automatically inject the header field if it's not present @@ -186,12 +194,73 @@ pub fn generate_note_interface_impl(module: &mut SortedModule) -> Result<(), Azt generate_compute_note_content_hash(¬e_type, note_interface_impl_span)?; trait_impl.items.push(TraitImplItem::Function(get_header_fn)); } + + if !check_trait_method_implemented(trait_impl, "to_be_bytes") { + let get_header_fn = generate_note_to_be_bytes( + ¬e_type, + note_bytes_len.as_str(), + note_serialized_len.as_str(), + note_interface_impl_span, + )?; + trait_impl.items.push(TraitImplItem::Function(get_header_fn)); + } } module.types.extend(structs_to_inject); Ok(()) } +fn generate_note_to_be_bytes( + note_type: &String, + byte_length: &str, + serialized_length: &str, + impl_span: Option, +) -> Result { + let function_source = format!( + " + fn to_be_bytes(self: {1}, storage_slot: Field) -> [u8; {0}] {{ + assert({0} == {2} * 32 + 64, \"Note byte length must be equal to (serialized_length * 32) + 64 bytes\"); + let serialized_note = self.serialize_content(); + + let mut buffer: [u8; {0}] = [0; {0}]; + + let storage_slot_bytes = storage_slot.to_be_bytes(32); + let note_type_id_bytes = {1}::get_note_type_id().to_be_bytes(32); + + for i in 0..32 {{ + buffer[i] = storage_slot_bytes[i]; + buffer[32 + i] = note_type_id_bytes[i]; + }} + + for i in 0..serialized_note.len() {{ + let bytes = serialized_note[i].to_be_bytes(32); + for j in 0..32 {{ + buffer[64 + i * 32 + j] = bytes[j]; + }} + }} + buffer + }} + ", + byte_length, note_type, serialized_length + ) + .to_string(); + + let (function_ast, errors) = parse_program(&function_source); + if !errors.is_empty() { + dbg!(errors); + return Err(AztecMacroError::CouldNotImplementNoteInterface { + secondary_message: Some("Failed to parse Noir macro code (fn to_be_bytes). This is either a bug in the compiler or the Noir macro code".to_string()), + span: impl_span + }); + } + + let mut function_ast = function_ast.into_sorted(); + let mut noir_fn = function_ast.functions.remove(0); + noir_fn.def.span = impl_span.unwrap(); + noir_fn.def.visibility = ItemVisibility::Public; + Ok(noir_fn) +} + fn generate_note_get_header( note_type: &String, note_header_field_name: &String, @@ -209,6 +278,7 @@ fn generate_note_get_header( let (function_ast, errors) = parse_program(&function_source); if !errors.is_empty() { + dbg!(errors); return Err(AztecMacroError::CouldNotImplementNoteInterface { secondary_message: Some("Failed to parse Noir macro code (fn get_header). This is either a bug in the compiler or the Noir macro code".to_string()), span: impl_span diff --git a/aztec_macros/src/utils/hir_utils.rs b/aztec_macros/src/utils/hir_utils.rs index 34aed3b34a4..7ce280c4c7f 100644 --- a/aztec_macros/src/utils/hir_utils.rs +++ b/aztec_macros/src/utils/hir_utils.rs @@ -325,7 +325,7 @@ pub fn get_serialized_length( .iter() .find_map(|&trait_id| { let r#trait = interner.get_trait(trait_id); - if r#trait.name.0.contents == trait_name && r#trait.generics.len() == 1 { + if r#trait.name.0.contents == trait_name { interner.lookup_all_trait_implementations(typ, trait_id).into_iter().next() } else { None diff --git a/compiler/integration-tests/test/browser/recursion.test.ts b/compiler/integration-tests/test/browser/recursion.test.ts index a8927aa6a75..abbee7b96ad 100644 --- a/compiler/integration-tests/test/browser/recursion.test.ts +++ b/compiler/integration-tests/test/browser/recursion.test.ts @@ -40,7 +40,8 @@ describe('It compiles noir program code, receiving circuit bytes and abi object. circuit_main_toml = await new Response(await getFile(`${base_relative_path}/${circuit_main}/Prover.toml`)).text(); }); - it('Should generate valid inner proof for correct input, then verify proof within a proof', async () => { + // TODO(https://github.com/noir-lang/noir/issues/5106): Reinstate this test. + it.skip('Should generate valid inner proof for correct input, then verify proof within a proof', async () => { const main_program = await getCircuit(`${base_relative_path}/${circuit_main}`); const main_inputs: InputMap = TOML.parse(circuit_main_toml) as InputMap; diff --git a/compiler/integration-tests/test/node/onchain_recursive_verification.test.ts b/compiler/integration-tests/test/node/onchain_recursive_verification.test.ts index 6147f770f16..ca7f19309d6 100644 --- a/compiler/integration-tests/test/node/onchain_recursive_verification.test.ts +++ b/compiler/integration-tests/test/node/onchain_recursive_verification.test.ts @@ -11,7 +11,8 @@ import { Field, InputMap } from '@noir-lang/noirc_abi'; import { compile, createFileManager } from '@noir-lang/noir_wasm'; -it(`smart contract can verify a recursive proof`, async () => { +// TODO(https://github.com/AztecProtocol/aztec-packages/issues/6672): Reinstate this test. +it.skip(`smart contract can verify a recursive proof`, async () => { const basePath = resolve(join(__dirname, '../../../../')); const fm = createFileManager(basePath); const innerCompilationResult = await compile( diff --git a/noir_stdlib/src/aes128.nr b/noir_stdlib/src/aes128.nr index cd61021a953..e6e2a5e4997 100644 --- a/noir_stdlib/src/aes128.nr +++ b/noir_stdlib/src/aes128.nr @@ -2,6 +2,3 @@ // docs:start:aes128 pub fn aes128_encrypt(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8] {} // docs:end:aes128 - -#[foreign(aes128_encrypt)] -pub fn aes128_encrypt_slice(input: [u8], iv: [u8; 16], key: [u8; 16]) -> [u8] {} diff --git a/test_programs/execution_success/ecdsa_secp256r1_3x/Nargo.toml b/test_programs/execution_success/ecdsa_secp256r1_3x/Nargo.toml new file mode 100644 index 00000000000..860b863a365 --- /dev/null +++ b/test_programs/execution_success/ecdsa_secp256r1_3x/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ecdsa_secp256r1_3x" +description = "Three ECDSA secp256r1 verifications" +type = "bin" +authors = [""] + +[dependencies] diff --git a/test_programs/execution_success/ecdsa_secp256r1_3x/Prover.toml b/test_programs/execution_success/ecdsa_secp256r1_3x/Prover.toml new file mode 100644 index 00000000000..e8edf26b2f3 --- /dev/null +++ b/test_programs/execution_success/ecdsa_secp256r1_3x/Prover.toml @@ -0,0 +1,57 @@ +hashed_message = [ + 84, 112, 91, 163, 186, 175, 219, 223, 186, 140, 95, 154, 112, 247, 168, 155, 238, 152, + 217, 6, 181, 62, 49, 7, 77, 167, 186, 236, 220, 13, 169, 173, +] +pub_key_x = [ + 85, 15, 71, 16, 3, 243, 223, 151, 195, 223, 80, 106, 199, 151, 246, 114, 31, 177, 161, + 251, 123, 143, 111, 131, 210, 36, 73, 138, 101, 200, 142, 36, +] +pub_key_y = [ + 19, 96, 147, 215, 1, 46, 80, 154, 115, 113, 92, 189, 11, 0, 163, 204, 15, 244, 181, + 192, 27, 63, 250, 25, 106, 177, 251, 50, 112, 54, 184, 230, +] +signature = [ + 44, 112, 168, 208, 132, 182, 43, 252, 92, 224, 54, 65, 202, 249, 247, 42, + 212, 218, 140, 129, 191, 230, 236, 148, 135, 187, 94, 27, 239, 98, 161, 50, + 24, 173, 158, 226, 158, 175, 53, 31, 220, 80, 241, 82, 12, 66, 94, 155, + 144, 138, 7, 39, 139, 67, 176, 236, 123, 135, 39, 120, 193, 78, 7, 132 +] + +hashed_message_2 = [ + 84, 112, 91, 163, 186, 175, 219, 223, 186, 140, 95, 154, 112, 247, 168, 155, 238, 152, + 217, 6, 181, 62, 49, 7, 77, 167, 186, 236, 220, 13, 169, 173, +] +pub_key_x_2 = [ + 85, 15, 71, 16, 3, 243, 223, 151, 195, 223, 80, 106, 199, 151, 246, 114, 31, 177, 161, + 251, 123, 143, 111, 131, 210, 36, 73, 138, 101, 200, 142, 36, +] +pub_key_y_2 = [ + 19, 96, 147, 215, 1, 46, 80, 154, 115, 113, 92, 189, 11, 0, 163, 204, 15, 244, 181, + 192, 27, 63, 250, 25, 106, 177, 251, 50, 112, 54, 184, 230, +] +signature_2 = [ + 44, 112, 168, 208, 132, 182, 43, 252, 92, 224, 54, 65, 202, 249, 247, 42, + 212, 218, 140, 129, 191, 230, 236, 148, 135, 187, 94, 27, 239, 98, 161, 50, + 24, 173, 158, 226, 158, 175, 53, 31, 220, 80, 241, 82, 12, 66, 94, 155, + 144, 138, 7, 39, 139, 67, 176, 236, 123, 135, 39, 120, 193, 78, 7, 132 +] + + +hashed_message_3 = [ + 84, 112, 91, 163, 186, 175, 219, 223, 186, 140, 95, 154, 112, 247, 168, 155, 238, 152, + 217, 6, 181, 62, 49, 7, 77, 167, 186, 236, 220, 13, 169, 173, +] +pub_key_x_3 = [ + 85, 15, 71, 16, 3, 243, 223, 151, 195, 223, 80, 106, 199, 151, 246, 114, 31, 177, 161, + 251, 123, 143, 111, 131, 210, 36, 73, 138, 101, 200, 142, 36, +] +pub_key_y_3 = [ + 19, 96, 147, 215, 1, 46, 80, 154, 115, 113, 92, 189, 11, 0, 163, 204, 15, 244, 181, + 192, 27, 63, 250, 25, 106, 177, 251, 50, 112, 54, 184, 230, +] +signature_3 = [ + 44, 112, 168, 208, 132, 182, 43, 252, 92, 224, 54, 65, 202, 249, 247, 42, + 212, 218, 140, 129, 191, 230, 236, 148, 135, 187, 94, 27, 239, 98, 161, 50, + 24, 173, 158, 226, 158, 175, 53, 31, 220, 80, 241, 82, 12, 66, 94, 155, + 144, 138, 7, 39, 139, 67, 176, 236, 123, 135, 39, 120, 193, 78, 7, 132 +] \ No newline at end of file diff --git a/test_programs/execution_success/ecdsa_secp256r1_3x/src/main.nr b/test_programs/execution_success/ecdsa_secp256r1_3x/src/main.nr new file mode 100644 index 00000000000..e7a6be9d47a --- /dev/null +++ b/test_programs/execution_success/ecdsa_secp256r1_3x/src/main.nr @@ -0,0 +1,23 @@ +use dep::std; + +fn main( + hashed_message: [u8; 32], + pub_key_x: [u8; 32], + pub_key_y: [u8; 32], + signature: [u8; 64], + hashed_message_2: [u8; 32], + pub_key_x_2: [u8; 32], + pub_key_y_2: [u8; 32], + signature_2: [u8; 64], + hashed_message_3: [u8; 32], + pub_key_x_3: [u8; 32], + pub_key_y_3: [u8; 32], + signature_3: [u8; 64] +) { + let valid_signature = std::ecdsa_secp256r1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); + assert(valid_signature); + let valid_signature_2 = std::ecdsa_secp256r1::verify_signature(pub_key_x_2, pub_key_y_2, signature_2, hashed_message_2); + assert(valid_signature_2); + let valid_signature_3 = std::ecdsa_secp256r1::verify_signature(pub_key_x_3, pub_key_y_3, signature_3, hashed_message_3); + assert(valid_signature_3); +} diff --git a/tooling/noir_js/src/witness_generation.ts b/tooling/noir_js/src/witness_generation.ts index 7d018c81d53..c84cb2e83b3 100644 --- a/tooling/noir_js/src/witness_generation.ts +++ b/tooling/noir_js/src/witness_generation.ts @@ -1,25 +1,8 @@ import { abiDecodeError, abiEncode, InputMap } from '@noir-lang/noirc_abi'; import { base64Decode } from './base64_decode.js'; -import { - WitnessStack, - ForeignCallHandler, - ForeignCallInput, - createBlackBoxSolver, - WasmBlackBoxFunctionSolver, - executeProgramWithBlackBoxSolver, - ExecutionError, -} from '@noir-lang/acvm_js'; +import { WitnessStack, ForeignCallHandler, ForeignCallInput, ExecutionError, executeProgram } from '@noir-lang/acvm_js'; import { Abi, CompiledCircuit } from '@noir-lang/types'; -let solver: Promise; - -const getSolver = (): Promise => { - if (!solver) { - solver = createBlackBoxSolver(); - } - return solver; -}; - const defaultForeignCallHandler: ForeignCallHandler = async (name: string, args: ForeignCallInput[]) => { if (name == 'print') { // By default we do not print anything for `print` foreign calls due to a need for formatting, @@ -70,12 +53,7 @@ export async function generateWitness( // Execute the circuit to generate the rest of the witnesses and serialize // them into a Uint8Array. try { - const solvedWitness = await executeProgramWithBlackBoxSolver( - await getSolver(), - base64Decode(compiledProgram.bytecode), - witnessMap, - foreignCallHandler, - ); + const solvedWitness = await executeProgram(base64Decode(compiledProgram.bytecode), witnessMap, foreignCallHandler); return solvedWitness; } catch (err) { // Typescript types catched errors as unknown or any, so we need to narrow its type to check if it has raw assertion payload. From a2894047f580a8861898d71cd335c06ee53290a4 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 28 May 2024 17:19:00 +0100 Subject: [PATCH 38/61] chore: deduplicate `ReturnConstant` warning (#5109) # Description ## Problem\* Resolves ## Summary\* This PR inlines `flatten_value_list` into `define_result_var` and deduplicates any `InternalWarning::ReturnConstant` warnings ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../noirc_evaluator/src/ssa/acir_gen/mod.rs | 75 ++++++++----------- 1 file changed, 31 insertions(+), 44 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index e9b2d5f46df..13677506d0b 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -1732,29 +1732,44 @@ impl<'a> Context<'a> { ) -> Result, RuntimeError> { let (return_values, call_stack) = match terminator { TerminatorInstruction::Return { return_values, call_stack } => { - (return_values, call_stack) + (return_values, call_stack.clone()) } // TODO(https://github.com/noir-lang/noir/issues/4616): Enable recursion on foldable/non-inlined ACIR functions _ => unreachable!("ICE: Program must have a singular return"), }; - // The return value may or may not be an array reference. Calling `flatten_value_list` - // will expand the array if there is one. - let return_acir_vars = self.flatten_value_list(return_values, dfg)?; - let mut warnings = Vec::new(); - for (acir_var, is_databus) in return_acir_vars { - if self.acir_context.is_constant(&acir_var) { - warnings.push(SsaReport::Warning(InternalWarning::ReturnConstant { - call_stack: call_stack.clone(), - })); - } - if !is_databus { - // We do not return value for the data bus. - self.acir_context.return_var(acir_var)?; - } else { - self.check_array_is_initialized(self.data_bus.return_data.unwrap(), dfg)?; + let mut has_constant_return = false; + for value_id in return_values { + let is_databus = self + .data_bus + .return_data + .map_or(false, |return_databus| dfg[*value_id] == dfg[return_databus]); + let value = self.convert_value(*value_id, dfg); + + // `value` may or may not be an array reference. Calling `flatten` will expand the array if there is one. + let acir_vars = self.acir_context.flatten(value)?; + for (acir_var, _) in acir_vars { + has_constant_return |= self.acir_context.is_constant(&acir_var); + if is_databus { + // We do not return value for the data bus. + self.check_array_is_initialized( + self.data_bus.return_data.expect( + "`is_databus == true` implies `data_bus.return_data` is `Some`", + ), + dfg, + )?; + } else { + self.acir_context.return_var(acir_var)?; + } } } + + let warnings = if has_constant_return { + vec![SsaReport::Warning(InternalWarning::ReturnConstant { call_stack })] + } else { + Vec::new() + }; + Ok(warnings) } @@ -2679,34 +2694,6 @@ impl<'a> Context<'a> { } } - /// Maps an ssa value list, for which some values may be references to arrays, by inlining - /// the `AcirVar`s corresponding to the contents of each array into the list of `AcirVar`s - /// that correspond to other values. - fn flatten_value_list( - &mut self, - arguments: &[ValueId], - dfg: &DataFlowGraph, - ) -> Result, InternalError> { - let mut acir_vars = Vec::with_capacity(arguments.len()); - for value_id in arguments { - let is_databus = if let Some(return_databus) = self.data_bus.return_data { - dfg[*value_id] == dfg[return_databus] - } else { - false - }; - let value = self.convert_value(*value_id, dfg); - acir_vars.append( - &mut self - .acir_context - .flatten(value)? - .iter() - .map(|(var, _)| (*var, is_databus)) - .collect(), - ); - } - Ok(acir_vars) - } - /// Convert a Vec into a Vec using the given result ids. /// If the type of a result id is an array, several acir vars are collected into /// a single AcirValue::Array of the same length. From 06dd2f25a28201e0095a3647cf420337d8465236 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 28 May 2024 18:16:07 +0100 Subject: [PATCH 39/61] chore: move `is_native_field` up into `noirc_frontend` (#5119) # Description ## Problem\* Resolves ## Summary\* This struct is only used for a single check up in `noirc_frontend` so we should move this logic closer to where it's used. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- Cargo.lock | 4 ++- acvm-repo/acir_field/Cargo.toml | 1 - acvm-repo/acir_field/src/lib.rs | 32 ------------------- compiler/noirc_frontend/Cargo.toml | 6 ++++ .../src/hir/def_collector/dc_mod.rs | 29 +++++++++++++++-- compiler/wasm/Cargo.toml | 2 +- tooling/nargo_cli/Cargo.toml | 2 +- tooling/noirc_abi/Cargo.toml | 10 ++++++ tooling/noirc_abi_wasm/Cargo.toml | 2 +- 9 files changed, 49 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f1ea5929d32..4b140a513f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,7 +34,6 @@ dependencies = [ "cfg-if 1.0.0", "hex", "num-bigint", - "num-traits", "serde", ] @@ -2821,6 +2820,7 @@ version = "0.30.0" dependencies = [ "acvm", "base64 0.21.2", + "cfg-if 1.0.0", "chumsky", "fm", "im", @@ -2830,6 +2830,8 @@ dependencies = [ "noirc_arena", "noirc_errors", "noirc_printable_type", + "num-bigint", + "num-traits", "petgraph", "regex", "rustc-hash", diff --git a/acvm-repo/acir_field/Cargo.toml b/acvm-repo/acir_field/Cargo.toml index 8d8a1e9e2bd..f182c6c4aba 100644 --- a/acvm-repo/acir_field/Cargo.toml +++ b/acvm-repo/acir_field/Cargo.toml @@ -16,7 +16,6 @@ repository.workspace = true hex.workspace = true num-bigint.workspace = true serde.workspace = true -num-traits.workspace = true ark-bn254 = { version = "^0.4.0", default-features = false, features = ["curve"] } ark-bls12-381 = { version = "^0.4.0", optional = true, default-features = false, features = ["curve"] } diff --git a/acvm-repo/acir_field/src/lib.rs b/acvm-repo/acir_field/src/lib.rs index 7f06330ed8d..9b8919e4bcb 100644 --- a/acvm-repo/acir_field/src/lib.rs +++ b/acvm-repo/acir_field/src/lib.rs @@ -2,9 +2,6 @@ #![warn(unreachable_pub)] #![warn(clippy::semicolon_if_nothing_returned)] #![cfg_attr(not(test), warn(unused_crate_dependencies, unused_extern_crates))] - -use num_bigint::BigUint; -use num_traits::Num; mod generic_ark; pub use generic_ark::AcirField; @@ -15,40 +12,11 @@ pub use generic_ark::FieldElement as GenericFieldElement; cfg_if::cfg_if! { if #[cfg(feature = "bls12_381")] { pub type FieldElement = generic_ark::FieldElement; - pub const CHOSEN_FIELD : FieldOptions = FieldOptions::BLS12_381; } else { pub type FieldElement = generic_ark::FieldElement; - pub const CHOSEN_FIELD : FieldOptions = FieldOptions::BN254; } } -#[derive(Debug, PartialEq, Eq)] -pub enum FieldOptions { - BN254, - BLS12_381, -} - -impl FieldOptions { - pub fn to_string(&self) -> &str { - match self { - FieldOptions::BN254 => "bn254", - FieldOptions::BLS12_381 => "bls12_381", - } - } - - pub fn is_native_field(str: &str) -> bool { - let big_num = if let Some(hex) = str.strip_prefix("0x") { - BigUint::from_str_radix(hex, 16) - } else { - BigUint::from_str_radix(str, 10) - }; - if let Ok(big_num) = big_num { - big_num == FieldElement::modulus() - } else { - CHOSEN_FIELD.to_string() == str - } - } -} // This is needed because features are additive through the dependency graph; if a dependency turns on the bn254, then it // will be turned on in all crates that depend on it #[macro_export] diff --git a/compiler/noirc_frontend/Cargo.toml b/compiler/noirc_frontend/Cargo.toml index 0430d214d53..381eb4a9bb9 100644 --- a/compiler/noirc_frontend/Cargo.toml +++ b/compiler/noirc_frontend/Cargo.toml @@ -21,13 +21,17 @@ smol_str.workspace = true im.workspace = true serde_json.workspace = true serde.workspace = true +num-bigint.workspace = true +num-traits.workspace = true rustc-hash = "1.1.0" small-ord-set = "0.1.3" regex = "1.9.1" +cfg-if = "1.0.0" tracing.workspace = true petgraph = "0.6" lalrpop-util = { version = "0.20.2", features = ["lexer"] } + [dev-dependencies] base64.workspace = true strum = "0.24" @@ -39,3 +43,5 @@ lalrpop = "0.20.2" [features] experimental_parser = [] +bn254 = [] +bls12_381 = [] diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index 3d0ffdb0155..56a0387cf8d 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -1,8 +1,10 @@ use std::{collections::HashMap, path::Path, vec}; -use acvm::acir::acir_field::FieldOptions; +use acvm::{AcirField, FieldElement}; use fm::{FileId, FileManager, FILE_EXTENSION}; use noirc_errors::Location; +use num_bigint::BigUint; +use num_traits::Num; use crate::ast::{ FunctionDefinition, Ident, ItemVisibility, LetStatement, ModuleDeclaration, NoirFunction, @@ -233,7 +235,7 @@ impl<'a> ModCollector<'a> { for function in functions { // check if optional field attribute is compatible with native field if let Some(field) = function.attributes().get_field_attribute() { - if !FieldOptions::is_native_field(&field) { + if !is_native_field(&field) { continue; } } @@ -721,6 +723,29 @@ fn should_check_siblings_for_module(module_path: &Path, parent_path: &Path) -> b } } +cfg_if::cfg_if! { + if #[cfg(feature = "bn254")] { + pub const CHOSEN_FIELD: &str = "bn254"; + } else if #[cfg(feature = "bls12_381")] { + pub const CHOSEN_FIELD: &str = "bls12_381"; + } else { + compile_error!("please specify a field to compile with"); + } +} + +fn is_native_field(str: &str) -> bool { + let big_num = if let Some(hex) = str.strip_prefix("0x") { + BigUint::from_str_radix(hex, 16) + } else { + BigUint::from_str_radix(str, 10) + }; + if let Ok(big_num) = big_num { + big_num == FieldElement::modulus() + } else { + CHOSEN_FIELD == str + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/compiler/wasm/Cargo.toml b/compiler/wasm/Cargo.toml index 23686cc4ea1..03e59b3e269 100644 --- a/compiler/wasm/Cargo.toml +++ b/compiler/wasm/Cargo.toml @@ -17,7 +17,7 @@ acvm = { workspace = true, features = ["bn254"] } fm.workspace = true nargo.workspace = true noirc_driver.workspace = true -noirc_frontend.workspace = true +noirc_frontend = { workspace = true, features = ["bn254"] } noirc_errors.workspace = true noirc_evaluator.workspace = true wasm-bindgen.workspace = true diff --git a/tooling/nargo_cli/Cargo.toml b/tooling/nargo_cli/Cargo.toml index 9e886bc7002..a9946c8700c 100644 --- a/tooling/nargo_cli/Cargo.toml +++ b/tooling/nargo_cli/Cargo.toml @@ -29,7 +29,7 @@ nargo_toml.workspace = true noir_lsp.workspace = true noir_debugger.workspace = true noirc_driver.workspace = true -noirc_frontend.workspace = true +noirc_frontend = { workspace = true, features = ["bn254"] } noirc_abi.workspace = true noirc_errors.workspace = true acvm = { workspace = true, features = ["bn254"] } diff --git a/tooling/noirc_abi/Cargo.toml b/tooling/noirc_abi/Cargo.toml index 040f8a0dc79..baae2dfa35e 100644 --- a/tooling/noirc_abi/Cargo.toml +++ b/tooling/noirc_abi/Cargo.toml @@ -23,3 +23,13 @@ num-traits = "0.2" [dev-dependencies] strum = "0.24" strum_macros = "0.24" + +[features] +bn254 = [ + "acvm/bn254", + "noirc_frontend/bn254", +] +bls12_381 = [ + "acvm/bls12_381", + "noirc_frontend/bls12_381", +] \ No newline at end of file diff --git a/tooling/noirc_abi_wasm/Cargo.toml b/tooling/noirc_abi_wasm/Cargo.toml index 5692c757d3e..daa619ca01d 100644 --- a/tooling/noirc_abi_wasm/Cargo.toml +++ b/tooling/noirc_abi_wasm/Cargo.toml @@ -13,7 +13,7 @@ crate-type = ["cdylib"] [dependencies] acvm = { workspace = true, features = ["bn254"] } -noirc_abi.workspace = true +noirc_abi = { workspace = true, features = ["bn254"] } iter-extended.workspace = true wasm-bindgen.workspace = true serde.workspace = true From ffcb410978a362c73783fbfe5bbdc9691499609e Mon Sep 17 00:00:00 2001 From: jfecher Date: Tue, 28 May 2024 12:23:34 -0500 Subject: [PATCH 40/61] fix(experimental elaborator): Fix panic in the elaborator (#5082) # Description ## Problem\* Working towards #4594 ## Summary\* When run on a program the elaborator would always panic previously due to `FuncMeta`s not yet being set for other functions while one function was being elaborated. This is because we used to set them during name resolution and only check them during type checking, but now that these two passes are merged we'll need to set them all before elaboration instead. This PR creates a new `define_function_metas` function to create the `FuncMeta`s beforehand. I imagine there are more changes required here related to scoping / generics / parameters but this at least stops the panic. ## Additional Context This is the first of the elaborator PRs to feature only new changes rather than largely copied code, so feel free to critique as usual if you think a different approach would be better, notice an issue, etc. After this PR the elaborator will run on a small example program, only producing 1052 errors in the standard library :slightly_smiling_face:. Most of these errors appear to be variants of "no method named '...' found for ..." and "no matching impl found for ..." ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> Co-authored-by: Maxim Vezenov --- .../src/elaborator/expressions.rs | 12 +- compiler/noirc_frontend/src/elaborator/mod.rs | 168 ++++++++++++------ .../noirc_frontend/src/elaborator/scope.rs | 4 +- .../noirc_frontend/src/elaborator/traits.rs | 18 +- .../noirc_frontend/src/elaborator/types.rs | 16 +- .../src/hir/def_collector/dc_crate.rs | 13 +- .../src/hir/def_collector/dc_mod.rs | 7 +- compiler/noirc_frontend/src/node_interner.rs | 21 +-- .../noirc_frontend/src/resolve_locations.rs | 4 +- 9 files changed, 161 insertions(+), 102 deletions(-) diff --git a/compiler/noirc_frontend/src/elaborator/expressions.rs b/compiler/noirc_frontend/src/elaborator/expressions.rs index f1631286336..2ad1598c6a2 100644 --- a/compiler/noirc_frontend/src/elaborator/expressions.rs +++ b/compiler/noirc_frontend/src/elaborator/expressions.rs @@ -15,9 +15,9 @@ use crate::{ hir_def::{ expr::{ HirArrayLiteral, HirBinaryOp, HirBlockExpression, HirCallExpression, HirCastExpression, - HirConstructorExpression, HirIdent, HirIfExpression, HirIndexExpression, - HirInfixExpression, HirLambda, HirMemberAccess, HirMethodCallExpression, - HirMethodReference, HirPrefixExpression, + HirConstructorExpression, HirIfExpression, HirIndexExpression, HirInfixExpression, + HirLambda, HirMemberAccess, HirMethodCallExpression, HirMethodReference, + HirPrefixExpression, }, traits::TraitConstraint, }, @@ -84,10 +84,10 @@ impl<'context> Elaborator<'context> { expr_type: inner_expr_type.clone(), expr_span: span, }); + } - if i + 1 == statements.len() { - block_type = stmt_type; - } + if i + 1 == statements.len() { + block_type = stmt_type; } } diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index 121a4d89ef0..c537531a748 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -1,19 +1,15 @@ -#![allow(unused)] use std::{ collections::{BTreeMap, BTreeSet}, rc::Rc, }; use crate::{ - ast::{ - ArrayLiteral, ConstructorExpression, FunctionKind, IfExpression, InfixExpression, Lambda, - UnresolvedTraitConstraint, UnresolvedTypeExpression, - }, + ast::{FunctionKind, UnresolvedTraitConstraint}, hir::{ def_collector::{ dc_crate::{ - filter_literal_globals, CompilationError, UnresolvedGlobal, UnresolvedStruct, - UnresolvedTrait, UnresolvedTypeAlias, + filter_literal_globals, CompilationError, ImplMap, UnresolvedGlobal, + UnresolvedStruct, UnresolvedTypeAlias, }, errors::DuplicateType, }, @@ -21,38 +17,21 @@ use crate::{ scope::ScopeForest as GenericScopeForest, type_check::TypeCheckError, }, - hir_def::{ - expr::{ - HirArrayLiteral, HirBinaryOp, HirBlockExpression, HirCallExpression, HirCastExpression, - HirConstructorExpression, HirIdent, HirIfExpression, HirIndexExpression, - HirInfixExpression, HirLambda, HirMemberAccess, HirMethodCallExpression, - HirMethodReference, HirPrefixExpression, - }, - stmt::HirLetStatement, - traits::TraitConstraint, - }, + hir_def::{expr::HirIdent, function::Parameters, traits::TraitConstraint}, macros_api::{ - BlockExpression, CallExpression, CastExpression, Expression, ExpressionKind, HirExpression, - HirLiteral, HirStatement, Ident, IndexExpression, Literal, MemberAccessExpression, - MethodCallExpression, NodeInterner, NoirFunction, NoirStruct, Pattern, PrefixExpression, - SecondaryAttribute, Statement, StatementKind, StructId, + Ident, NodeInterner, NoirFunction, NoirStruct, Pattern, SecondaryAttribute, StructId, }, - node_interner::{DefinitionKind, DependencyId, ExprId, FuncId, StmtId, TraitId, TypeAliasId}, - Shared, StructType, Type, TypeVariable, + node_interner::{DefinitionKind, DependencyId, ExprId, FuncId, TraitId, TypeAliasId}, + Shared, Type, TypeVariable, }; use crate::{ ast::{TraitBound, UnresolvedGenerics}, graph::CrateId, hir::{ - def_collector::{ - dc_crate::{CollectedItems, DefCollector}, - errors::DefCollectorErrorKind, - }, + def_collector::{dc_crate::CollectedItems, errors::DefCollectorErrorKind}, def_map::{LocalModuleId, ModuleDefId, ModuleId, MAIN_FUNCTION}, resolution::{ - errors::PubPosition, - import::{PathResolution, PathResolutionError}, - path_resolver::StandardPathResolver, + errors::PubPosition, import::PathResolution, path_resolver::StandardPathResolver, }, Context, }, @@ -81,7 +60,6 @@ mod types; use fm::FileId; use iter_extended::vecmap; use noirc_errors::{Location, Span}; -use regex::Regex; use rustc_hash::FxHashSet as HashSet; /// ResolverMetas are tagged onto each definition to track how many times they are used @@ -226,6 +204,8 @@ impl<'context> Elaborator<'context> { this.define_type_alias(alias_id, alias); } + this.define_function_metas(&mut items.functions, &mut items.impls, &mut items.trait_impls); + this.collect_traits(items.traits); // Must resolve structs before we resolve globals. @@ -268,7 +248,6 @@ impl<'context> Elaborator<'context> { let cycle_errors = this.interner.check_for_dependency_cycles(); this.errors.extend(cycle_errors); - this.errors } @@ -285,7 +264,6 @@ impl<'context> Elaborator<'context> { fn elaborate_function(&mut self, mut function: NoirFunction, id: FuncId) { self.current_function = Some(id); - self.resolve_where_clause(&mut function.def.where_clause); // Without this, impl methods can accidentally be placed in contracts. See #3254 if self.self_type.is_some() { @@ -297,9 +275,6 @@ impl<'context> Elaborator<'context> { // Check whether the function has globals in the local module and add them to the scope self.resolve_local_globals(); - self.add_generics(&function.def.generics); - - self.desugar_impl_trait_args(&mut function, id); self.trait_bounds = function.def.where_clause.clone(); let is_low_level_or_oracle = function @@ -312,8 +287,19 @@ impl<'context> Elaborator<'context> { self.in_unconstrained_fn = true; } - let func_meta = self.extract_meta(&function, id); + let func_meta = self.interner.func_meta.get(&id); + let func_meta = func_meta + .expect("FuncMetas should be declared before a function is elaborated") + .clone(); + for (parameter, param2) in function.def.parameters.iter().zip(&func_meta.parameters.0) { + let definition_kind = DefinitionKind::Local(None); + self.elaborate_pattern(parameter.pattern.clone(), param2.1.clone(), definition_kind); + } + + self.add_generics(&function.def.generics); + self.desugar_impl_trait_args(&mut function, id); + self.declare_numeric_generics(&func_meta.parameters, func_meta.return_type()); self.add_trait_constraints_to_scope(&func_meta); let (hir_func, body_type) = match function.kind { @@ -376,7 +362,6 @@ impl<'context> Elaborator<'context> { self.trait_bounds.clear(); - self.interner.push_fn_meta(func_meta, id); self.interner.update_fn(id, hir_func); self.current_function = None; } @@ -538,9 +523,23 @@ impl<'context> Elaborator<'context> { /// Extract metadata from a NoirFunction /// to be used in analysis and intern the function parameters - /// Prerequisite: self.add_generics() has already been called with the given - /// function's generics, including any generics from the impl, if any. - fn extract_meta(&mut self, func: &NoirFunction, func_id: FuncId) -> FuncMeta { + /// Prerequisite: any implicit generics, including any generics from the impl, + /// have already been added to scope via `self.add_generics`. + fn define_function_meta(&mut self, func: &mut NoirFunction, func_id: FuncId) { + self.current_function = Some(func_id); + self.resolve_where_clause(&mut func.def.where_clause); + + // Without this, impl methods can accidentally be placed in contracts. See #3254 + if self.self_type.is_some() { + self.in_contract = false; + } + + self.scopes.start_function(); + self.current_item = Some(DependencyId::Function(func_id)); + + // Check whether the function has globals in the local module and add them to the scope + self.resolve_local_globals(); + let location = Location::new(func.name_ident().span(), self.file); let id = self.interner.function_definition_id(func_id); let name_ident = HirIdent::non_trait_method(id, location); @@ -565,6 +564,8 @@ impl<'context> Elaborator<'context> { let has_inline_attribute = has_no_predicates_attribute || should_fold; let is_entry_point = self.is_entry_point_function(func); + self.add_generics(&func.def.generics); + let mut generics = vecmap(&self.generics, |(_, typevar, _)| typevar.clone()); let mut parameters = vec![]; let mut parameter_types = vec![]; @@ -593,8 +594,6 @@ impl<'context> Elaborator<'context> { let return_type = Box::new(self.resolve_type(func.return_type())); - self.declare_numeric_generics(¶meter_types, &return_type); - if !self.pub_allowed(func) && func.def.return_visibility == Visibility::Public { self.push_err(ResolverError::UnnecessaryPub { ident: func.name_ident().clone(), @@ -647,7 +646,7 @@ impl<'context> Elaborator<'context> { .map(|(name, typevar, _span)| (name.clone(), typevar.clone())) .collect(); - FuncMeta { + let meta = FuncMeta { name: name_ident, kind: func.kind, location, @@ -661,7 +660,12 @@ impl<'context> Elaborator<'context> { trait_constraints: self.resolve_trait_constraints(&func.def.where_clause), is_entry_point, has_inline_attribute, - } + }; + + self.interner.push_fn_meta(meta, func_id); + self.current_function = None; + self.scopes.end_function(); + self.current_item = None; } /// Only sized types are valid to be used as main's parameters or the parameters to a contract @@ -701,7 +705,7 @@ impl<'context> Elaborator<'context> { } } - fn declare_numeric_generics(&mut self, params: &[Type], return_type: &Type) { + fn declare_numeric_generics(&mut self, params: &Parameters, return_type: &Type) { if self.generics.is_empty() { return; } @@ -724,11 +728,11 @@ impl<'context> Elaborator<'context> { } fn find_numeric_generics( - parameters: &[Type], + parameters: &Parameters, return_type: &Type, ) -> Vec<(String, TypeVariable)> { let mut found = BTreeMap::new(); - for parameter in parameters { + for (_, parameter, _) in ¶meters.0 { Self::find_numeric_generics_in_type(parameter, &mut found); } Self::find_numeric_generics_in_type(return_type, &mut found); @@ -842,10 +846,11 @@ impl<'context> Elaborator<'context> { module: LocalModuleId, impls: Vec<(Vec, Span, UnresolvedFunctions)>, ) { - self.generics.clear(); + self.local_module = module; for (generics, _, functions) in impls { self.file = functions.file_id; + let old_generics_length = self.generics.len(); self.add_generics(&generics); let self_type = self.resolve_type(typ.clone()); self.self_type = Some(self_type.clone()); @@ -869,6 +874,8 @@ impl<'context> Elaborator<'context> { } } } + + self.generics.truncate(old_generics_length); } } @@ -878,18 +885,20 @@ impl<'context> Elaborator<'context> { let unresolved_type = trait_impl.object_type; let self_type_span = unresolved_type.span; + let old_generics_length = self.generics.len(); self.add_generics(&trait_impl.generics); let trait_generics = vecmap(&trait_impl.trait_generics, |generic| self.resolve_type(generic.clone())); - let self_type = self.resolve_type(unresolved_type.clone()); - let impl_id = self.interner.next_trait_impl_id(); + let self_type = trait_impl.resolved_object_type.unwrap_or(Type::Error); + let impl_id = + trait_impl.impl_id.expect("An impls' id should be set during define_function_metas"); self.self_type = Some(self_type.clone()); - self.current_trait_impl = Some(impl_id); + self.current_trait_impl = trait_impl.impl_id; - let mut methods = trait_impl.methods.function_ids(); + let methods = trait_impl.methods.function_ids(); self.elaborate_functions(trait_impl.methods); @@ -944,7 +953,7 @@ impl<'context> Elaborator<'context> { self.self_type = None; self.current_trait_impl = None; - self.generics.clear(); + self.generics.truncate(old_generics_length); } fn collect_impls( @@ -1236,4 +1245,55 @@ impl<'context> Elaborator<'context> { self.interner.get_global_definition_mut(global_id).kind = definition_kind; self.interner.replace_statement(statement_id, let_statement); } + + fn define_function_metas( + &mut self, + functions: &mut [UnresolvedFunctions], + impls: &mut ImplMap, + trait_impls: &mut [UnresolvedTraitImpl], + ) { + for function_set in functions { + self.define_function_metas_for_functions(function_set); + } + + for ((_typ, local_module), function_sets) in impls { + self.local_module = *local_module; + + for (_generics, _, function_set) in function_sets { + self.define_function_metas_for_functions(function_set); + } + } + + for trait_impl in trait_impls { + self.file = trait_impl.file_id; + self.local_module = trait_impl.module_id; + + let unresolved_type = &trait_impl.object_type; + let old_generics_length = self.generics.len(); + self.add_generics(&trait_impl.generics); + + let self_type = self.resolve_type(unresolved_type.clone()); + self.self_type = Some(self_type.clone()); + + let impl_id = self.interner.next_trait_impl_id(); + self.current_trait_impl = Some(impl_id); + + self.define_function_metas_for_functions(&mut trait_impl.methods); + + trait_impl.resolved_object_type = self.self_type.take(); + trait_impl.impl_id = self.current_trait_impl.take(); + self.generics.truncate(old_generics_length); + } + } + + fn define_function_metas_for_functions(&mut self, function_set: &mut UnresolvedFunctions) { + self.file = function_set.file_id; + + for (local_module, id, func) in &mut function_set.functions { + self.local_module = *local_module; + let old_generics_length = self.generics.len(); + self.define_function_meta(func, *id); + self.generics.truncate(old_generics_length); + } + } } diff --git a/compiler/noirc_frontend/src/elaborator/scope.rs b/compiler/noirc_frontend/src/elaborator/scope.rs index cf10dbbc2b2..6ae43bd3c49 100644 --- a/compiler/noirc_frontend/src/elaborator/scope.rs +++ b/compiler/noirc_frontend/src/elaborator/scope.rs @@ -1,8 +1,6 @@ use noirc_errors::Spanned; -use rustc_hash::FxHashMap as HashMap; use crate::ast::ERROR_IDENT; -use crate::hir::comptime::Value; use crate::hir::def_map::{LocalModuleId, ModuleId}; use crate::hir::resolution::path_resolver::{PathResolver, StandardPathResolver}; use crate::hir::resolution::resolver::SELF_TYPE_NAME; @@ -18,7 +16,7 @@ use crate::{ traits::Trait, }, macros_api::{Path, StructId}, - node_interner::{DefinitionId, TraitId, TypeAliasId}, + node_interner::{DefinitionId, TraitId}, Shared, StructType, }; use crate::{Type, TypeAlias}; diff --git a/compiler/noirc_frontend/src/elaborator/traits.rs b/compiler/noirc_frontend/src/elaborator/traits.rs index e7018d900d8..c2f9a83e559 100644 --- a/compiler/noirc_frontend/src/elaborator/traits.rs +++ b/compiler/noirc_frontend/src/elaborator/traits.rs @@ -5,14 +5,8 @@ use noirc_errors::Location; use crate::{ ast::{FunctionKind, TraitItem, UnresolvedGenerics, UnresolvedTraitConstraint}, - hir::{ - def_collector::dc_crate::UnresolvedTrait, def_map::ModuleId, - resolution::path_resolver::StandardPathResolver, - }, - hir_def::{ - function::{FuncMeta, HirFunction}, - traits::{TraitConstant, TraitFunction, TraitType}, - }, + hir::def_collector::dc_crate::UnresolvedTrait, + hir_def::traits::{TraitConstant, TraitFunction, TraitType}, macros_api::{ BlockExpression, FunctionDefinition, FunctionReturnType, Ident, ItemVisibility, NoirFunction, Param, Pattern, UnresolvedType, Visibility, @@ -26,10 +20,6 @@ use super::Elaborator; impl<'context> Elaborator<'context> { pub fn collect_traits(&mut self, traits: BTreeMap) { - for (trait_id, unresolved_trait) in &traits { - self.interner.push_empty_trait(*trait_id, unresolved_trait); - } - for (trait_id, unresolved_trait) in traits { let generics = vecmap(&unresolved_trait.trait_def.generics, |_| { TypeVariable::unbound(self.interner.next_type_variable_id()) @@ -187,7 +177,9 @@ impl<'context> Elaborator<'context> { return_visibility: Visibility::Private, }; - self.elaborate_function(NoirFunction { kind, def }, func_id); + let mut function = NoirFunction { kind, def }; + self.define_function_meta(&mut function, func_id); + self.elaborate_function(function, func_id); let _ = self.scopes.end_function(); // Don't check the scope tree for unused variables, they can't be used in a declaration anyway. self.trait_bounds.clear(); diff --git a/compiler/noirc_frontend/src/elaborator/types.rs b/compiler/noirc_frontend/src/elaborator/types.rs index 4c2b58580cf..059ff857df8 100644 --- a/compiler/noirc_frontend/src/elaborator/types.rs +++ b/compiler/noirc_frontend/src/elaborator/types.rs @@ -1,19 +1,18 @@ use std::rc::Rc; -use acvm::{acir::AcirField, FieldElement}; +use acvm::acir::AcirField; use iter_extended::vecmap; use noirc_errors::{Location, Span}; use crate::{ ast::{ - BinaryOpKind, IntegerBitSize, NoirTypeAlias, UnresolvedGenerics, UnresolvedTraitConstraint, + BinaryOpKind, IntegerBitSize, UnresolvedGenerics, UnresolvedTraitConstraint, UnresolvedTypeExpression, }, hir::{ def_map::ModuleDefId, resolution::{ errors::ResolverError, - import::PathResolution, resolver::{verify_mutable_reference, SELF_TYPE_NAME}, }, type_check::{Source, TypeCheckError}, @@ -24,17 +23,14 @@ use crate::{ HirPrefixExpression, }, function::FuncMeta, - traits::{Trait, TraitConstraint}, + traits::TraitConstraint, }, macros_api::{ HirExpression, HirLiteral, HirStatement, Path, PathKind, SecondaryAttribute, Signedness, UnaryOp, UnresolvedType, UnresolvedTypeData, }, - node_interner::{ - DefinitionKind, DependencyId, ExprId, GlobalId, TraitId, TraitImplKind, TraitMethodId, - TypeAliasId, - }, - Generics, Shared, StructType, Type, TypeAlias, TypeBinding, TypeVariable, TypeVariableKind, + node_interner::{DefinitionKind, ExprId, GlobalId, TraitId, TraitImplKind, TraitMethodId}, + Generics, Type, TypeBinding, TypeVariable, TypeVariableKind, }; use super::Elaborator; @@ -636,7 +632,7 @@ impl<'context> Elaborator<'context> { rhs_type: &Type, span: Span, ) -> Type { - let mut unify = |this: &mut Self, expected| { + let unify = |this: &mut Self, expected| { this.unify(rhs_type, &expected, || TypeCheckError::TypeMismatch { expr_typ: rhs_type.to_string(), expected_typ: expected.to_string(), diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index afec3839599..60b841699f1 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -5,6 +5,7 @@ use crate::graph::CrateId; use crate::hir::comptime::{Interpreter, InterpreterError}; use crate::hir::def_map::{CrateDefMap, LocalModuleId, ModuleId}; use crate::hir::resolution::errors::ResolverError; +use crate::Type; use crate::hir::resolution::import::{resolve_import, ImportDirective, PathResolution}; use crate::hir::resolution::{ @@ -18,7 +19,9 @@ use crate::hir::type_check::{ use crate::hir::Context; use crate::macros_api::{MacroError, MacroProcessor}; -use crate::node_interner::{FuncId, GlobalId, NodeInterner, StructId, TraitId, TypeAliasId}; +use crate::node_interner::{ + FuncId, GlobalId, NodeInterner, StructId, TraitId, TraitImplId, TypeAliasId, +}; use crate::ast::{ ExpressionKind, Ident, LetStatement, Literal, NoirFunction, NoirStruct, NoirTrait, @@ -107,13 +110,17 @@ pub struct UnresolvedTrait { pub struct UnresolvedTraitImpl { pub file_id: FileId, pub module_id: LocalModuleId, - pub trait_id: Option, pub trait_generics: Vec, pub trait_path: Path, pub object_type: UnresolvedType, pub methods: UnresolvedFunctions, pub generics: UnresolvedGenerics, pub where_clause: Vec, + + // These fields are filled in later during elaboration + pub trait_id: Option, + pub impl_id: Option, + pub resolved_object_type: Option, } #[derive(Clone)] @@ -337,7 +344,7 @@ impl DefCollector { if use_elaborator { let mut more_errors = Elaborator::elaborate(context, crate_id, def_collector.items); - more_errors.append(&mut errors); + errors.append(&mut more_errors); return errors; } diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index 56a0387cf8d..645c41ad33b 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -189,8 +189,12 @@ impl<'a> ModCollector<'a> { object_type: trait_impl.object_type, generics: trait_impl.impl_generics, where_clause: trait_impl.where_clause, - trait_id: None, // will be filled later trait_generics: trait_impl.trait_generics, + + // These last fields are filled later on + trait_id: None, + impl_id: None, + resolved_object_type: None, }; self.def_collector.items.trait_impls.push(unresolved_trait_impl); @@ -509,6 +513,7 @@ impl<'a> ModCollector<'a> { method_ids, fns_with_default_impl: unresolved_functions, }; + context.def_interner.push_empty_trait(trait_id, &unresolved); self.def_collector.items.traits.insert(trait_id, unresolved); } errors diff --git a/compiler/noirc_frontend/src/node_interner.rs b/compiler/noirc_frontend/src/node_interner.rs index d4145ef6a1d..60cc2580bb8 100644 --- a/compiler/noirc_frontend/src/node_interner.rs +++ b/compiler/noirc_frontend/src/node_interner.rs @@ -111,7 +111,9 @@ pub struct NodeInterner { // The purpose for this hashmap is to detect duplication of trait implementations ( if any ) // // Indexed by TraitImplIds - pub(crate) trait_implementations: Vec>, + pub(crate) trait_implementations: HashMap>, + + next_trait_implementation_id: usize, /// Trait implementations on each type. This is expected to always have the same length as /// `self.trait_implementations`. @@ -485,7 +487,8 @@ impl Default for NodeInterner { struct_attributes: HashMap::new(), type_aliases: Vec::new(), traits: HashMap::new(), - trait_implementations: Vec::new(), + trait_implementations: HashMap::new(), + next_trait_implementation_id: 0, trait_implementation_map: HashMap::new(), selected_trait_implementations: HashMap::new(), operator_traits: HashMap::new(), @@ -1143,7 +1146,7 @@ impl NodeInterner { } pub fn get_trait_implementation(&self, id: TraitImplId) -> Shared { - self.trait_implementations[id.0].clone() + self.trait_implementations[&id].clone() } /// Given a `ObjectType: TraitId` pair, try to find an existing impl that satisfies the @@ -1378,9 +1381,7 @@ impl NodeInterner { impl_generics: Generics, trait_impl: Shared, ) -> Result<(), (Span, FileId)> { - assert_eq!(impl_id.0, self.trait_implementations.len(), "trait impl defined out of order"); - - self.trait_implementations.push(trait_impl.clone()); + self.trait_implementations.insert(impl_id, trait_impl.clone()); // Replace each generic with a fresh type variable let substitutions = impl_generics @@ -1483,10 +1484,10 @@ impl NodeInterner { } /// Returns what the next trait impl id is expected to be. - /// Note that this does not actually reserve the slot so care should - /// be taken that the next trait impl added matches this ID. - pub fn next_trait_impl_id(&self) -> TraitImplId { - TraitImplId(self.trait_implementations.len()) + pub fn next_trait_impl_id(&mut self) -> TraitImplId { + let next_id = self.next_trait_implementation_id; + self.next_trait_implementation_id += 1; + TraitImplId(next_id) } /// Removes all TraitImplKind::Assumed from the list of known impls for the given trait diff --git a/compiler/noirc_frontend/src/resolve_locations.rs b/compiler/noirc_frontend/src/resolve_locations.rs index 2fa7c8adbf8..5efe2e4a041 100644 --- a/compiler/noirc_frontend/src/resolve_locations.rs +++ b/compiler/noirc_frontend/src/resolve_locations.rs @@ -157,11 +157,11 @@ impl NodeInterner { self.trait_implementations .iter() .find(|shared_trait_impl| { - let trait_impl = shared_trait_impl.borrow(); + let trait_impl = shared_trait_impl.1.borrow(); trait_impl.file == location.file && trait_impl.ident.span().contains(&location.span) }) .and_then(|shared_trait_impl| { - let trait_impl = shared_trait_impl.borrow(); + let trait_impl = shared_trait_impl.1.borrow(); self.traits.get(&trait_impl.trait_id).map(|trait_| trait_.location) }) } From f5d294645e82fc85d8dc28ee2a846ba11af85ce5 Mon Sep 17 00:00:00 2001 From: jfecher Date: Tue, 28 May 2024 13:55:31 -0500 Subject: [PATCH 41/61] fix(experimental elaborator): Only call `add_generics` once (#5091) # Description ## Problem\* Resolves an issue introduced by https://github.com/noir-lang/noir/pull/5082 where `add_generics` would be called multiple times on a given item. Once when declaring the FuncMeta beforehand, and again when defining it afterward. This is an issue because `add_generics` will give a fresh set of generics each time. This meant the generics in a function's signature weren't the same type variables as the ones used internally, which led to type errors. ## Summary\* ## Additional Context Down to ~~400~~ 226 errors in the stdlib down from 1050 Edit: Fixed a case where structs never popped their generics out of scope ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Maxim Vezenov --- compiler/noirc_frontend/src/elaborator/mod.rs | 195 ++++++++++-------- .../noirc_frontend/src/elaborator/traits.rs | 2 +- .../src/hir/def_collector/dc_crate.rs | 9 +- .../src/hir/def_collector/dc_mod.rs | 19 +- .../src/hir/resolution/resolver.rs | 4 + .../noirc_frontend/src/hir/type_check/mod.rs | 4 +- .../noirc_frontend/src/hir_def/function.rs | 24 ++- 7 files changed, 154 insertions(+), 103 deletions(-) diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index c537531a748..261a97ec3fb 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -205,7 +205,6 @@ impl<'context> Elaborator<'context> { } this.define_function_metas(&mut items.functions, &mut items.impls, &mut items.trait_impls); - this.collect_traits(items.traits); // Must resolve structs before we resolve globals. @@ -224,7 +223,7 @@ impl<'context> Elaborator<'context> { // // These are resolved after trait impls so that struct methods are chosen // over trait methods if there are name conflicts. - for ((typ, module), impls) in &items.impls { + for ((typ, module), impls) in &mut items.impls { this.collect_impls(typ, *module, impls); } @@ -238,8 +237,8 @@ impl<'context> Elaborator<'context> { this.elaborate_functions(functions); } - for ((typ, module), impls) in items.impls { - this.elaborate_impls(typ, module, impls); + for impls in items.impls.into_values() { + this.elaborate_impls(impls); } for trait_impl in items.trait_impls { @@ -251,15 +250,27 @@ impl<'context> Elaborator<'context> { this.errors } + /// Runs `f` and if it modifies `self.generics`, `self.generics` is truncated + /// back to the previous length. + fn recover_generics(&mut self, f: impl FnOnce(&mut Self) -> T) -> T { + let generics_count = self.generics.len(); + let ret = f(self); + self.generics.truncate(generics_count); + ret + } + fn elaborate_functions(&mut self, functions: UnresolvedFunctions) { self.file = functions.file_id; self.trait_id = functions.trait_id; // TODO: Resolve? + self.self_type = functions.self_type; + for (local_module, id, func) in functions.functions { self.local_module = local_module; - let generics_count = self.generics.len(); - self.elaborate_function(func, id); - self.generics.truncate(generics_count); + self.recover_generics(|this| this.elaborate_function(func, id)); } + + self.self_type = None; + self.trait_id = None; } fn elaborate_function(&mut self, mut function: NoirFunction, id: FuncId) { @@ -277,12 +288,6 @@ impl<'context> Elaborator<'context> { self.resolve_local_globals(); self.trait_bounds = function.def.where_clause.clone(); - let is_low_level_or_oracle = function - .attributes() - .function - .as_ref() - .map_or(false, |func| func.is_low_level() || func.is_oracle()); - if function.def.is_unconstrained { self.in_unconstrained_fn = true; } @@ -297,7 +302,7 @@ impl<'context> Elaborator<'context> { self.elaborate_pattern(parameter.pattern.clone(), param2.1.clone(), definition_kind); } - self.add_generics(&function.def.generics); + self.generics = func_meta.all_generics.clone(); self.desugar_impl_trait_args(&mut function, id); self.declare_numeric_generics(&func_meta.parameters, func_meta.return_type()); self.add_trait_constraints_to_scope(&func_meta); @@ -315,7 +320,8 @@ impl<'context> Elaborator<'context> { } }; - if !func_meta.can_ignore_return_type() { + // Don't verify the return type for builtin functions & trait function declarations + if !func_meta.is_stub() { self.type_check_function_body(body_type, &func_meta, hir_func.as_expr()); } @@ -356,7 +362,7 @@ impl<'context> Elaborator<'context> { let func_scope_tree = self.scopes.end_function(); // The arguments to low-level and oracle functions are always unused so we do not produce warnings for them. - if !is_low_level_or_oracle { + if !func_meta.is_stub() { self.check_for_unused_variables_in_scope_tree(func_scope_tree); } @@ -525,7 +531,12 @@ impl<'context> Elaborator<'context> { /// to be used in analysis and intern the function parameters /// Prerequisite: any implicit generics, including any generics from the impl, /// have already been added to scope via `self.add_generics`. - fn define_function_meta(&mut self, func: &mut NoirFunction, func_id: FuncId) { + fn define_function_meta( + &mut self, + func: &mut NoirFunction, + func_id: FuncId, + is_trait_function: bool, + ) { self.current_function = Some(func_id); self.resolve_where_clause(&mut func.def.where_clause); @@ -652,6 +663,7 @@ impl<'context> Elaborator<'context> { location, typ, direct_generics, + all_generics: self.generics.clone(), trait_impl: self.current_trait_impl, parameters: parameters.into(), return_type: func.def.return_type.clone(), @@ -659,6 +671,7 @@ impl<'context> Elaborator<'context> { has_body: !func.def.body.is_empty(), trait_constraints: self.resolve_trait_constraints(&func.def.where_clause), is_entry_point, + is_trait_function, has_inline_attribute, }; @@ -840,42 +853,10 @@ impl<'context> Elaborator<'context> { } } - fn elaborate_impls( - &mut self, - typ: UnresolvedType, - module: LocalModuleId, - impls: Vec<(Vec, Span, UnresolvedFunctions)>, - ) { - self.local_module = module; - - for (generics, _, functions) in impls { + fn elaborate_impls(&mut self, impls: Vec<(Vec, Span, UnresolvedFunctions)>) { + for (_, _, functions) in impls { self.file = functions.file_id; - let old_generics_length = self.generics.len(); - self.add_generics(&generics); - let self_type = self.resolve_type(typ.clone()); - self.self_type = Some(self_type.clone()); - - let function_ids = vecmap(&functions.functions, |(_, id, _)| *id); - self.elaborate_functions(functions); - - if self_type != Type::Error { - for method_id in function_ids { - let method_name = self.interner.function_name(&method_id).to_owned(); - - if let Some(first_fn) = - self.interner.add_method(&self_type, method_name.clone(), method_id, false) - { - let error = ResolverError::DuplicateDefinition { - name: method_name, - first_span: self.interner.function_ident(&first_fn).span(), - second_span: self.interner.function_ident(&method_id).span(), - }; - self.push_err(error); - } - } - } - - self.generics.truncate(old_generics_length); + self.recover_generics(|this| this.elaborate_functions(functions)); } } @@ -886,7 +867,7 @@ impl<'context> Elaborator<'context> { let unresolved_type = trait_impl.object_type; let self_type_span = unresolved_type.span; let old_generics_length = self.generics.len(); - self.add_generics(&trait_impl.generics); + self.generics = trait_impl.resolved_generics; let trait_generics = vecmap(&trait_impl.trait_generics, |generic| self.resolve_type(generic.clone())); @@ -895,7 +876,6 @@ impl<'context> Elaborator<'context> { let impl_id = trait_impl.impl_id.expect("An impls' id should be set during define_function_metas"); - self.self_type = Some(self_type.clone()); self.current_trait_impl = trait_impl.impl_id; let methods = trait_impl.methods.function_ids(); @@ -960,13 +940,16 @@ impl<'context> Elaborator<'context> { &mut self, self_type: &UnresolvedType, module: LocalModuleId, - impls: &[(Vec, Span, UnresolvedFunctions)], + impls: &mut [(Vec, Span, UnresolvedFunctions)], ) { self.local_module = module; for (generics, span, unresolved) in impls { self.file = unresolved.file_id; - self.declare_method_on_struct(self_type, generics, false, unresolved, *span); + self.recover_generics(|this| { + this.add_generics(generics); + this.declare_methods_on_struct(self_type, false, unresolved, *span); + }); } } @@ -980,8 +963,12 @@ impl<'context> Elaborator<'context> { let span = trait_impl.object_type.span.expect("All trait self types should have spans"); let object_type = &trait_impl.object_type; - let generics = &trait_impl.generics; - self.declare_method_on_struct(object_type, generics, true, &trait_impl.methods, span); + + self.recover_generics(|this| { + this.add_generics(&trait_impl.generics); + trait_impl.resolved_generics = this.generics.clone(); + this.declare_methods_on_struct(object_type, true, &mut trait_impl.methods, span); + }); } } @@ -990,33 +977,33 @@ impl<'context> Elaborator<'context> { &mut self.def_maps.get_mut(&module.krate).expect(message).modules[module.local_id.0] } - fn declare_method_on_struct( + fn declare_methods_on_struct( &mut self, self_type: &UnresolvedType, - generics: &UnresolvedGenerics, is_trait_impl: bool, - functions: &UnresolvedFunctions, + functions: &mut UnresolvedFunctions, span: Span, ) { - let generic_count = self.generics.len(); - self.add_generics(generics); - let typ = self.resolve_type(self_type.clone()); + let self_type = self.resolve_type(self_type.clone()); + + functions.self_type = Some(self_type.clone()); + + let function_ids = functions.function_ids(); - if let Type::Struct(struct_type, _generics) = typ { - let struct_type = struct_type.borrow(); + if let Type::Struct(struct_type, _) = &self_type { + let struct_ref = struct_type.borrow(); // `impl`s are only allowed on types defined within the current crate - if !is_trait_impl && struct_type.id.krate() != self.crate_id { - let type_name = struct_type.name.to_string(); + if !is_trait_impl && struct_ref.id.krate() != self.crate_id { + let type_name = struct_ref.name.to_string(); self.push_err(DefCollectorErrorKind::ForeignImpl { span, type_name }); - self.generics.truncate(generic_count); return; } // Grab the module defined by the struct type. Note that impls are a case // where the module the methods are added to is not the same as the module // they are resolved in. - let module = self.get_module_mut(struct_type.id.module_id()); + let module = self.get_module_mut(struct_ref.id.module_id()); for (_, method_id, method) in &functions.functions { // If this method was already declared, remove it from the module so it cannot @@ -1028,11 +1015,33 @@ impl<'context> Elaborator<'context> { module.remove_function(method.name_ident()); } } - // Prohibit defining impls for primitive types if we're not in the stdlib - } else if !is_trait_impl && typ != Type::Error && !self.crate_id.is_stdlib() { - self.push_err(DefCollectorErrorKind::NonStructTypeInImpl { span }); + + self.declare_struct_methods(&self_type, &function_ids); + // We can define methods on primitive types only if we're in the stdlib + } else if !is_trait_impl && self_type != Type::Error { + if self.crate_id.is_stdlib() { + self.declare_struct_methods(&self_type, &function_ids); + } else { + self.push_err(DefCollectorErrorKind::NonStructTypeInImpl { span }); + } + } + } + + fn declare_struct_methods(&mut self, self_type: &Type, function_ids: &[FuncId]) { + for method_id in function_ids { + let method_name = self.interner.function_name(method_id).to_owned(); + + if let Some(first_fn) = + self.interner.add_method(self_type, method_name.clone(), *method_id, false) + { + let error = ResolverError::DuplicateDefinition { + name: method_name, + first_span: self.interner.function_ident(&first_fn).span(), + second_span: self.interner.function_ident(method_id).span(), + }; + self.push_err(error); + } } - self.generics.truncate(generic_count); } fn collect_trait_impl_methods( @@ -1203,18 +1212,20 @@ impl<'context> Elaborator<'context> { unresolved: NoirStruct, struct_id: StructId, ) -> (Generics, Vec<(Ident, Type)>) { - let generics = self.add_generics(&unresolved.generics); + self.recover_generics(|this| { + let generics = this.add_generics(&unresolved.generics); - // Check whether the struct definition has globals in the local module and add them to the scope - self.resolve_local_globals(); + // Check whether the struct definition has globals in the local module and add them to the scope + this.resolve_local_globals(); - self.current_item = Some(DependencyId::Struct(struct_id)); + this.current_item = Some(DependencyId::Struct(struct_id)); - self.resolving_ids.insert(struct_id); - let fields = vecmap(unresolved.fields, |(ident, typ)| (ident, self.resolve_type(typ))); - self.resolving_ids.remove(&struct_id); + this.resolving_ids.insert(struct_id); + let fields = vecmap(unresolved.fields, |(ident, typ)| (ident, this.resolve_type(typ))); + this.resolving_ids.remove(&struct_id); - (generics, fields) + (generics, fields) + }) } fn elaborate_global(&mut self, global: UnresolvedGlobal) { @@ -1256,11 +1267,16 @@ impl<'context> Elaborator<'context> { self.define_function_metas_for_functions(function_set); } - for ((_typ, local_module), function_sets) in impls { + for ((self_type, local_module), function_sets) in impls { self.local_module = *local_module; - for (_generics, _, function_set) in function_sets { + for (generics, _, function_set) in function_sets { + self.add_generics(generics); + let self_type = self.resolve_type(self_type.clone()); + function_set.self_type = Some(self_type.clone()); + self.self_type = Some(self_type); self.define_function_metas_for_functions(function_set); + self.generics.clear(); } } @@ -1269,11 +1285,12 @@ impl<'context> Elaborator<'context> { self.local_module = trait_impl.module_id; let unresolved_type = &trait_impl.object_type; - let old_generics_length = self.generics.len(); self.add_generics(&trait_impl.generics); let self_type = self.resolve_type(unresolved_type.clone()); + self.self_type = Some(self_type.clone()); + trait_impl.methods.self_type = Some(self_type); let impl_id = self.interner.next_trait_impl_id(); self.current_trait_impl = Some(impl_id); @@ -1282,7 +1299,7 @@ impl<'context> Elaborator<'context> { trait_impl.resolved_object_type = self.self_type.take(); trait_impl.impl_id = self.current_trait_impl.take(); - self.generics.truncate(old_generics_length); + self.generics.clear(); } } @@ -1291,9 +1308,9 @@ impl<'context> Elaborator<'context> { for (local_module, id, func) in &mut function_set.functions { self.local_module = *local_module; - let old_generics_length = self.generics.len(); - self.define_function_meta(func, *id); - self.generics.truncate(old_generics_length); + self.recover_generics(|this| { + this.define_function_meta(func, *id, false); + }); } } } diff --git a/compiler/noirc_frontend/src/elaborator/traits.rs b/compiler/noirc_frontend/src/elaborator/traits.rs index c2f9a83e559..76cdc592276 100644 --- a/compiler/noirc_frontend/src/elaborator/traits.rs +++ b/compiler/noirc_frontend/src/elaborator/traits.rs @@ -178,7 +178,7 @@ impl<'context> Elaborator<'context> { }; let mut function = NoirFunction { kind, def }; - self.define_function_meta(&mut function, func_id); + self.define_function_meta(&mut function, func_id, true); self.elaborate_function(function, func_id); let _ = self.scopes.end_function(); // Don't check the scope tree for unused variables, they can't be used in a declaration anyway. diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index 60b841699f1..838aac3f067 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -5,7 +5,7 @@ use crate::graph::CrateId; use crate::hir::comptime::{Interpreter, InterpreterError}; use crate::hir::def_map::{CrateDefMap, LocalModuleId, ModuleId}; use crate::hir::resolution::errors::ResolverError; -use crate::Type; +use crate::{Type, TypeVariable}; use crate::hir::resolution::import::{resolve_import, ImportDirective, PathResolution}; use crate::hir::resolution::{ @@ -33,6 +33,7 @@ use iter_extended::vecmap; use noirc_errors::{CustomDiagnostic, Span}; use std::collections::{BTreeMap, HashMap}; +use std::rc::Rc; use std::vec; #[derive(Default)] @@ -50,6 +51,9 @@ pub struct UnresolvedFunctions { pub file_id: FileId, pub functions: Vec<(LocalModuleId, FuncId, NoirFunction)>, pub trait_id: Option, + + // The object type this set of functions was declared on, if there is one. + pub self_type: Option, } impl UnresolvedFunctions { @@ -117,10 +121,11 @@ pub struct UnresolvedTraitImpl { pub generics: UnresolvedGenerics, pub where_clause: Vec, - // These fields are filled in later during elaboration + // These fields are filled in later pub trait_id: Option, pub impl_id: Option, pub resolved_object_type: Option, + pub resolved_generics: Vec<(Rc, TypeVariable, Span)>, } #[derive(Clone)] diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index 645c41ad33b..536332d8f8a 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -146,6 +146,7 @@ impl<'a> ModCollector<'a> { file_id: self.file_id, functions: Vec::new(), trait_id: None, + self_type: None, }; for (method, _) in r#impl.methods { @@ -195,6 +196,7 @@ impl<'a> ModCollector<'a> { trait_id: None, impl_id: None, resolved_object_type: None, + resolved_generics: Vec::new(), }; self.def_collector.items.trait_impls.push(unresolved_trait_impl); @@ -207,8 +209,12 @@ impl<'a> ModCollector<'a> { trait_impl: &NoirTraitImpl, krate: CrateId, ) -> UnresolvedFunctions { - let mut unresolved_functions = - UnresolvedFunctions { file_id: self.file_id, functions: Vec::new(), trait_id: None }; + let mut unresolved_functions = UnresolvedFunctions { + file_id: self.file_id, + functions: Vec::new(), + trait_id: None, + self_type: None, + }; let module = ModuleId { krate, local_id: self.module_id }; @@ -230,8 +236,12 @@ impl<'a> ModCollector<'a> { functions: Vec, krate: CrateId, ) -> Vec<(CompilationError, FileId)> { - let mut unresolved_functions = - UnresolvedFunctions { file_id: self.file_id, functions: Vec::new(), trait_id: None }; + let mut unresolved_functions = UnresolvedFunctions { + file_id: self.file_id, + functions: Vec::new(), + trait_id: None, + self_type: None, + }; let mut errors = vec![]; let module = ModuleId { krate, local_id: self.module_id }; @@ -404,6 +414,7 @@ impl<'a> ModCollector<'a> { file_id: self.file_id, functions: Vec::new(), trait_id: None, + self_type: None, }; let mut method_ids = HashMap::new(); diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index 8beac340c4b..9fe0d473f15 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -1106,6 +1106,10 @@ impl<'a> Resolver<'a> { trait_constraints: self.resolve_trait_constraints(&func.def.where_clause), is_entry_point: self.is_entry_point_function(func), has_inline_attribute, + + // This is only used by the elaborator + all_generics: Vec::new(), + is_trait_function: false, } } diff --git a/compiler/noirc_frontend/src/hir/type_check/mod.rs b/compiler/noirc_frontend/src/hir/type_check/mod.rs index b2a76828c88..70d7c4021ed 100644 --- a/compiler/noirc_frontend/src/hir/type_check/mod.rs +++ b/compiler/noirc_frontend/src/hir/type_check/mod.rs @@ -49,7 +49,7 @@ pub struct TypeChecker<'interner> { pub fn type_check_func(interner: &mut NodeInterner, func_id: FuncId) -> Vec { let meta = interner.function_meta(&func_id); let declared_return_type = meta.return_type().clone(); - let can_ignore_ret = meta.can_ignore_return_type(); + let can_ignore_ret = meta.is_stub(); let function_body_id = &interner.function(&func_id).as_expr(); @@ -549,7 +549,9 @@ pub mod test { trait_constraints: Vec::new(), direct_generics: Vec::new(), is_entry_point: true, + is_trait_function: false, has_inline_attribute: false, + all_generics: Vec::new(), }; interner.push_fn_meta(func_meta, func_id); diff --git a/compiler/noirc_frontend/src/hir_def/function.rs b/compiler/noirc_frontend/src/hir_def/function.rs index ceec9ad8580..9e03f074ffe 100644 --- a/compiler/noirc_frontend/src/hir_def/function.rs +++ b/compiler/noirc_frontend/src/hir_def/function.rs @@ -109,6 +109,12 @@ pub struct FuncMeta { /// such as a trait's `Self` type variable. pub direct_generics: Vec<(Rc, TypeVariable)>, + /// All the generics used by this function, which includes any implicit generics or generics + /// from outer scopes, such as those introduced by an impl. + /// This is stored when the FuncMeta is first created to later be used to set the current + /// generics when the function's body is later resolved. + pub all_generics: Vec<(Rc, TypeVariable, Span)>, + pub location: Location, // This flag is needed for the attribute check pass @@ -123,6 +129,11 @@ pub struct FuncMeta { /// For non-contracts, this means the function is `main`. pub is_entry_point: bool, + /// True if this function was defined within a trait (not a trait impl!). + /// Trait functions are just stubs and shouldn't have their return type checked + /// against their body type, nor should unused variables be checked. + pub is_trait_function: bool, + /// True if this function is marked with an attribute /// that indicates it should be inlined differently than the default (inline everything). /// For example, such as `fold` (never inlined) or `no_predicates` (inlined after flattening) @@ -130,12 +141,13 @@ pub struct FuncMeta { } impl FuncMeta { - /// Builtin, LowLevel and Oracle functions usually have the return type - /// declared, however their function bodies will be empty - /// So this method tells the type checker to ignore the return - /// of the empty function, which is unit - pub fn can_ignore_return_type(&self) -> bool { - self.kind.can_ignore_return_type() + /// A stub function does not have a body. This includes Builtin, LowLevel, + /// and Oracle functions in addition to method declarations within a trait. + /// + /// We don't check the return type of these functions since it will always have + /// an empty body, and we don't check for unused parameters. + pub fn is_stub(&self) -> bool { + self.kind.can_ignore_return_type() || self.is_trait_function } pub fn function_signature(&self) -> FunctionSignature { From 11e98f348d1d43a9b28d83ec3308027b7afc0da6 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 28 May 2024 20:14:22 +0100 Subject: [PATCH 42/61] feat: replace stdlib poseidon implementation with optimized version (#5122) # Description ## Problem\* Resolves ## Summary\* This PR pulls out the existing poseidon implementation and replaces it with @zac-williamson's improved version. I've removed the "optimized" version which hardcodes the values of `rf`/`rp` as it was equivalent to just using a constant config (something which I expect would happen in 99.9999% of cases). ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Maxim Vezenov --- noir_stdlib/src/hash/poseidon.nr | 198 +- noir_stdlib/src/hash/poseidon/bn254.nr | 85 +- noir_stdlib/src/hash/poseidon/bn254/consts.nr | 24885 +++++++++++++++- noir_stdlib/src/hash/poseidon/bn254/perm.nr | 2 +- 4 files changed, 24981 insertions(+), 189 deletions(-) diff --git a/noir_stdlib/src/hash/poseidon.nr b/noir_stdlib/src/hash/poseidon.nr index 742bfcaf804..f40ea2738ed 100644 --- a/noir_stdlib/src/hash/poseidon.nr +++ b/noir_stdlib/src/hash/poseidon.nr @@ -3,66 +3,134 @@ use crate::field::modulus_num_bits; use crate::hash::Hasher; use crate::default::Default; -struct PoseidonConfig { - t: Field, // Width, i.e. state size - rf: u8, // Number of full rounds; should be even - rp: u8, // Number of partial rounds - alpha: Field, // S-box power; depends on the underlying field - ark: [Field; M], // Additive round keys - mds: [Field; N] // MDS Matrix in row-major order +// A config struct defining the parameters of the Poseidon instance to use. +// +// A thorough writeup of this method (along with an unoptimized method) can be found at: https://spec.filecoin.io/algorithms/crypto/poseidon/ +struct PoseidonConfig { + // State width, should be equal to `T` + t: Field, + // Number of full rounds. should be even + rf: u8, + // Number of partial rounds + rp: u8, + // S-box power; depends on the underlying field + alpha: Field, + // The round constants for the + round_constants: [Field; N], + // The MDS matrix for the Poseidon instance + mds: [[Field; T]; T], + // An MDS matrix which also applies a basis transformation which allows + // sparse matrices to be used for the partial rounds. + // + // This should be applied instead of `mds` in the final full round. + presparse_mds: [[Field; T]; T], + // A set of sparse matrices used for MDS mixing for the partial rounds. + sparse_mds: [Field; X], } -pub fn config( +pub fn config( t: Field, rf: u8, rp: u8, alpha: Field, - ark: [Field; M], - mds: [Field; N] -) -> PoseidonConfig { + round_constants: [Field; N], + mds: [[Field; T]; T], + presparse_mds: [[Field; T]; T], + sparse_mds: [Field; X] +) -> PoseidonConfig { // Input checks - let mul = crate::wrapping_mul(t as u8, (rf + rp)); - assert(mul == ark.len() as u8); - assert(t * t == mds.len() as Field); + assert_eq(rf & 1, 0); + assert_eq((t as u8) * rf + rp, N); + assert_eq(t, T); assert(alpha != 0); - PoseidonConfig { t, rf, rp, alpha, ark, mds } + PoseidonConfig { t, rf, rp, alpha, round_constants, mds, presparse_mds, sparse_mds } } -// General Poseidon permutation on elements of type Field -fn permute(pos_conf: PoseidonConfig, mut state: [Field; O]) -> [Field; O] { - let PoseidonConfig {t, rf, rp, alpha, ark, mds} = pos_conf; - assert(t == state.len() as Field); +pub fn permute(pos_conf: PoseidonConfig, mut state: [Field; T]) -> [Field; T] { + let PoseidonConfig {t, rf, rp, alpha, round_constants, mds, presparse_mds, sparse_mds } = pos_conf; - let mut count = 0; - // for r in 0..rf + rp - for r in 0..(ark.len() / state.len()) { - for i in 0..state.len() { - state[i] = state[i] + ark[count + i]; - } // Shift by round constants + for i in 0..state.len() { + state[i] += round_constants[i]; + } + + for _r in 0..rf / 2 - 1 { + state = sigma(state); + for i in 0..T { + state[i] += round_constants[T * (_r + 1) as u64 + i]; + } + state = apply_matrix(mds, state); + } + + state = sigma(state); + for i in 0..T { + state[i] += round_constants[T * (rf / 2) as u64 + i]; + } + state = apply_matrix(presparse_mds, state); + + for i in 0..T { + crate::as_witness(state[i]); + } + + for _r in 0..rp { state[0] = state[0].pow_32(alpha); - // Check whether we are in a full round - if (r as u8 < rf / 2) | (r as u8 >= rf / 2 + rp) { - for i in 1..state.len() { - state[i] = state[i].pow_32(alpha); + state[0] += round_constants[(rf/2 + 1) as u64 * T + _r as u64]; + crate::as_witness(state[0]); + { + let mut newState0 = 0; + for j in 0..T { + newState0 += sparse_mds[(T * 2 - 1) * _r as u64 + j as u64] * state[j]; + } + for k in 1..T { + state[k] += state[0] * sparse_mds[(t * 2 - 1) as u64 * _r as u64 + T + k - 1]; + } + state[0] = newState0; + + if (_r & 1 == 0) { + for k in 1..T { + crate::as_witness(state[k]); + } } } + } - state = apply_matrix(mds, state); // Apply MDS matrix - count = count + t as u64; + for _r in 0..rf / 2 - 1 { + state = sigma(state); + for i in 0..state.len() { + state[i] += round_constants[(rf/2+1) as u64 * T + rp as u64 + (_r as u64) * T + i]; + } + state = apply_matrix(mds, state); } + state = sigma(state); + state = apply_matrix(mds, state); + state } -// Absorption. Fully absorbs input message. -fn absorb( - pos_conf: PoseidonConfig, - mut state: [Field; O], // Initial state; usually [0; O] - rate: Field, // Rate - capacity: Field, // Capacity; usually 1 - msg: [Field; P] -) -> [Field; O] { - assert(pos_conf.t == rate + capacity); + +// Performs matrix multiplication on a vector +fn apply_matrix(matrix: [[Field; N]; N], vec: [Field; N]) -> [Field; N] { + let mut out = [0; N]; + + for i in 0..N { + for j in 0..N { + out[i] += vec[j] * matrix[j][i]; + } + } + + out +} + +// Corresponding absorption. +fn absorb( + pos_conf: PoseidonConfig, + // Initial state; usually [0; O] + mut state: [Field; T], + rate: Field, + capacity: Field, + msg: [Field; O] // Arbitrary length message +) -> [Field; T] { + assert_eq(pos_conf.t, rate + capacity); let mut i = 0; @@ -83,25 +151,24 @@ fn absorb( state } + +fn sigma(x: [Field; O]) -> [Field; O] { + let mut y = x; + for i in 0..O { + let t = y[i]; + let tt = t * t; + let tttt = tt * tt; + y[i] *= tttt; + } + y +} + // Check security of sponge instantiation fn check_security(rate: Field, width: Field, security: Field) -> bool { let n = modulus_num_bits(); ((n - 1) as Field * (width - rate) / 2) as u8 > security as u8 } -// A*x where A is an n x n matrix in row-major order and x an n-vector -fn apply_matrix(a: [Field; M], x: [Field; N]) -> [Field; N] { - let mut y = x; - - for i in 0..x.len() { - y[i] = 0; - for j in 0..x.len() { - y[i] = y[i] + a[x.len()*i + j]* x[j]; - } - } - - y -} struct PoseidonHasher{ _state: [Field], @@ -174,3 +241,28 @@ impl Default for PoseidonHasher{ } } } + +mod poseidon_tests { + use crate::hash::poseidon; + + #[test] + fn reference_impl_test_vectors() { + // hardcoded test vectors from https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/test_vectors.txt + { + let mut state = [0, 1, 2]; + let mut expected = [ + 0x115cc0f5e7d690413df64c6b9662e9cf2a3617f2743245519e19607a4417189a, 0x0fca49b798923ab0239de1c9e7a4a9a2210312b6a2f616d18b5a87f9b628ae29, 0x0e7ae82e40091e63cbd4f16a6d16310b3729d4b6e138fcf54110e2867045a30c + ]; + assert_eq(expected, poseidon::bn254::perm::x5_3(state), "Failed to reproduce output for [0, 1, 2]"); + } + { + let mut state = [0, 1, 2, 3, 4]; + let mut expected = [ + 0x299c867db6c1fdd79dcefa40e4510b9837e60ebb1ce0663dbaa525df65250465, 0x1148aaef609aa338b27dafd89bb98862d8bb2b429aceac47d86206154ffe053d, 0x24febb87fed7462e23f6665ff9a0111f4044c38ee1672c1ac6b0637d34f24907, 0x0eb08f6d809668a981c186beaf6110060707059576406b248e5d9cf6e78b3d3e, 0x07748bc6877c9b82c8b98666ee9d0626ec7f5be4205f79ee8528ef1c4a376fc7 + ]; + assert_eq( + expected, poseidon::bn254::perm::x5_5(state), "Failed to reproduce output for [0, 1, 2, 3, 4]" + ); + } + } +} diff --git a/noir_stdlib/src/hash/poseidon/bn254.nr b/noir_stdlib/src/hash/poseidon/bn254.nr index 37b08e3c8fb..54f22884e29 100644 --- a/noir_stdlib/src/hash/poseidon/bn254.nr +++ b/noir_stdlib/src/hash/poseidon/bn254.nr @@ -2,93 +2,14 @@ mod perm; mod consts; -use crate::hash::poseidon::PoseidonConfig; -use crate::hash::poseidon::apply_matrix; -// Optimised permutation for this particular field; uses hardcoded rf and rp values, -// which should agree with those in pos_conf. -#[field(bn254)] -pub fn permute(pos_conf: PoseidonConfig, mut state: [Field; O]) -> [Field; O] { - let PoseidonConfig {t, rf: config_rf, rp: config_rp, alpha, ark, mds} = pos_conf; - let rf: u8 = 8; - let rp: u8 = [56, 57, 56, 60, 60, 63, 64, 63, 60, 66, 60, 65, 70, 60, 64, 68][state.len() - 2]; - - assert(t == state.len() as Field); - assert(rf == config_rf); - assert(rp == config_rp); - - let mut count = 0; - // First half of full rounds - for _r in 0..rf / 2 { - for i in 0..state.len() { - state[i] = state[i] + ark[count + i]; - } // Shift by round constants - for i in 0..state.len() { - state[i] = state[i].pow_32(alpha); - } - - state = apply_matrix(mds, state); // Apply MDS matrix - count = count + t as u64; - } - // Partial rounds - for _r in 0..rp { - for i in 0..state.len() { - state[i] = state[i] + ark[count + i]; - } // Shift by round constants - state[0] = state[0].pow_32(alpha); - - state = apply_matrix(mds, state); // Apply MDS matrix - count = count + t as u64; - } - // Second half of full rounds - for _r in 0..rf / 2 { - for i in 0..state.len() { - state[i] = state[i] + ark[count + i]; - } // Shift by round constants - for i in 0..state.len() { - state[i] = state[i].pow_32(alpha); - } - - state = apply_matrix(mds, state); // Apply MDS matrix - count = count + t as u64; - } - - state -} -// Corresponding absorption. -#[field(bn254)] -fn absorb( - pos_conf: PoseidonConfig, - mut state: [Field; O], // Initial state; usually [0; O] - rate: Field, // Rate - capacity: Field, // Capacity; usually 1 - msg: [Field; P] // Arbitrary length message -) -> [Field; O] { - assert(pos_conf.t == rate + capacity); - - let mut i = 0; - - for k in 0..msg.len() { - // Add current block to state - state[capacity + i] += msg[k]; - i = i+1; - // Enough to absorb - if i == rate { - state = permute(pos_conf, state); - i = 0; - } - } - // If we have one more block to permute - if i != 0 { - state = permute(pos_conf, state); - } - - state -} +use crate::hash::poseidon::{PoseidonConfig, absorb}; + // Variable-length Poseidon-128 sponge as suggested in second bullet point of §3 of https://eprint.iacr.org/2019/458.pdf #[field(bn254)] pub fn sponge(msg: [Field; N]) -> Field { absorb(consts::x5_5_config(), [0; 5], 4, 1, msg)[1] } + // Various instances of the Poseidon hash function // Consistent with Circom's implementation pub fn hash_1(input: [Field; 1]) -> Field { diff --git a/noir_stdlib/src/hash/poseidon/bn254/consts.nr b/noir_stdlib/src/hash/poseidon/bn254/consts.nr index 62b5f4b5212..81d78377ce8 100644 --- a/noir_stdlib/src/hash/poseidon/bn254/consts.nr +++ b/noir_stdlib/src/hash/poseidon/bn254/consts.nr @@ -1,9 +1,11 @@ +// Parameters are generated by a reference script https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/generate_parameters_grain.sage +// Used like so: sage generate_parameters_grain.sage 1 0 254 2 8 56 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 + // Constants for various Poseidon instances in the case of the prime field of the same order as BN254. // Consistent with https://github.com/iden3/circomlib/blob/master/circuits/poseidon.circom and https://github.com/iden3/circomlib/blob/master/circuits/poseidon_constants.circom use crate::hash::poseidon::PoseidonConfig; use crate::hash::poseidon::config; // Number of full rounds -global rf = 8; // Number of partial rounds fn rp() -> [u8; 16] { [56, 57, 56, 60, 60, 63, 64, 63, 60, 66, 60, 65, 70, 60, 64, 68] @@ -12,181 +14,24958 @@ fn rp() -> [u8; 16] { fn alpha() -> Field { 5 } -// Poseidon configurations for states of size 2 to 17. + // noir-fmt:ignore -pub fn x5_2_config() -> PoseidonConfig<128, 4> { +pub fn x5_2_config() -> PoseidonConfig<2, 72, 168> { config( 2, 8, 56, alpha(), - [4417881134626180770308697923359573201005643519861877412381846989312604493735,5433650512959517612316327474713065966758808864213826738576266661723522780033,13641176377184356099764086973022553863760045607496549923679278773208775739952,17949713444224994136330421782109149544629237834775211751417461773584374506783,13765628375339178273710281891027109699578766420463125835325926111705201856003,19179513468172002314585757290678967643352171735526887944518845346318719730387,5157412437176756884543472904098424903141745259452875378101256928559722612176,535160875740282236955320458485730000677124519901643397458212725410971557409,1050793453380762984940163090920066886770841063557081906093018330633089036729,10665495010329663932664894101216428400933984666065399374198502106997623173873,19965634623406616956648724894636666805991993496469370618546874926025059150737,13007250030070838431593222885902415182312449212965120303174723305710127422213,16877538715074991604507979123743768693428157847423939051086744213162455276374,18211747749504876135588847560312685184956239426147543810126553367063157141465,18151553319826126919739798892854572062191241985315767086020821632812331245635,19957033149976712666746140949846950406660099037474791840946955175819555930825,3469514863538261843186854830917934449567467100548474599735384052339577040841,989698510043911779243192466312362856042600749099921773896924315611668507708,12568377015646290945235387813564567111330046038050864455358059568128000172201,20856104135605479600325529349246932565148587186338606236677138505306779314172,8206918720503535523121349917159924938835810381723474192155637697065780938424,1309058477013932989380617265069188723120054926187607548493110334522527703566,14076116939332667074621703729512195584105250395163383769419390236426287710606,10153498892749751942204288991871286290442690932856658983589258153608012428674,18202499207234128286137597834010475797175973146805180988367589376893530181575,12739388830157083522877690211447248168864006284243907142044329113461613743052,15123358710467780770838026754240340042441262572309759635224051333176022613949,19925004701844594370904593774447343836015483888496504201331110250494635362184,10352416606816998476681131583320899030072315953910679608943150613208329645891,10567371822366244361703342347428230537114808440249611395507235283708966113221,5635498582763880627392290206431559361272660937399944184533035305989295959602,11866432933224219174041051738704352719163271639958083608224676028593315904909,5795020705294401441272215064554385591292330721703923167136157291459784140431,9482202378699252817564375087302794636287866584767523335624368774856230692758,4245237636894546151746468406560945873445548423466753843402086544922216329298,12000500941313982757584712677991730019124834399479314697467598397927435905133,7596790274058425558167520209857956363736666939016807569082239187494363541787,2484867918246116343205467273440098378820186751202461278013576281097918148877,18312645949449997391810445935615409295369169383463185688973803378104013950190,15320686572748723004980855263301182130424010735782762814513954166519592552733,12618438900597948888520621062416758747872180395546164387827245287017031303859,17438141672027706116733201008397064011774368832458707512367404736905021019585,6374197807230665998865688675365359100400438034755781666913068586172586548950,2189398913433273865510950346186699930188746169476472274335177556702504595264,6268495580028970231803791523870131137294646402347399003576649137450213034606,17896250365994900261202920044129628104272791547990619503076839618914047059275,13692156312448722528008862371944543449350293305158722920787736248435893008873,15234446864368744483209945022439268713300180233589581910497691316744177619376,1572426502623310766593681563281600503979671244997798691029595521622402217227,80103447810215150918585162168214870083573048458555897999822831203653996617,8228820324013669567851850635126713973797711779951230446503353812192849106342,5375851433746509614045812476958526065449377558695752132494533666370449415873,12115998939203497346386774317892338270561208357481805380546938146796257365018,9764067909645821279940531410531154041386008396840887338272986634350423466622,8538708244538850542384936174629541085495830544298260335345008245230827876882,7140127896620013355910287215441004676619168261422440177712039790284719613114,14297402962228458726038826185823085337698917275385741292940049024977027409762,6667115556431351074165934212337261254608231545257434281887966406956835140819,20226761165244293291042617464655196752671169026542832236139342122602741090001,12038289506489256655759141386763477208196694421666339040483042079632134429119,19027757334170818571203982241812412991528769934917288000224335655934473717551,16272152964456553579565580463468069884359929612321610357528838696790370074720,2500392889689246014710135696485946334448570271481948765283016105301740284071,8595254970528530312401637448610398388203855633951264114100575485022581946023,11635945688914011450976408058407206367914559009113158286982919675551688078198,614739068603482619581328040478536306925147663946742687395148680260956671871,18692271780377861570175282183255720350972693125537599213951106550953176268753,4987059230784976306647166378298632695585915319042844495357753339378260807164,21851403978498723616722415377430107676258664746210815234490134600998983955497,9830635451186415300891533983087800047564037813328875992115573428596207326204,4842706106434537116860242620706030229206345167233200482994958847436425185478,6422235064906823218421386871122109085799298052314922856340127798647926126490,4564364104986856861943331689105797031330091877115997069096365671501473357846,1944043894089780613038197112872830569538541856657037469098448708685350671343,21179865974855950600518216085229498748425990426231530451599322283119880194955,14296697761894107574369608843560006996183955751502547883167824879840894933162,12274619649702218570450581712439138337725246879938860735460378251639845671898,16371396450276899401411886674029075408418848209575273031725505038938314070356,3702561221750983937578095019779188631407216522704543451228773892695044653565,19721616877735564664624984774636557499099875603996426215495516594530838681980,6383350109027696789969911008057747025018308755462287526819231672217685282429,20860583956177367265984596617324237471765572961978977333122281041544719622905,5766390934595026947545001478457407504285452477687752470140790011329357286275,4043175758319898049344746138515323336207420888499903387536875603879441092484,15579382179133608217098622223834161692266188678101563820988612253342538956534,1864640783252634743892105383926602930909039567065240010338908865509831749824,15943719865023133586707144161652035291705809358178262514871056013754142625673,2326415993032390211558498780803238091925402878871059708106213703504162832999,19995326402773833553207196590622808505547443523750970375738981396588337910289,5143583711361588952673350526320181330406047695593201009385718506918735286622,15436006486881920976813738625999473183944244531070780793506388892313517319583,16660446760173633166698660166238066533278664023818938868110282615200613695857,4966065365695755376133119391352131079892396024584848298231004326013366253934,20683781957411705574951987677641476019618457561419278856689645563561076926702,17280836839165902792086432296371645107551519324565649849400948918605456875699,17045635513701208892073056357048619435743564064921155892004135325530808465371,17055032967194400710390142791334572297458033582458169295920670679093585707295,15727174639569115300068198908071514334002742825679221638729902577962862163505,1001755657610446661315902885492677747789366510875120894840818704741370398633,18638547332826171619311285502376343504539399518545103511265465604926625041234,6751954224763196429755298529194402870632445298969935050224267844020826420799,3526747115904224771452549517614107688674036840088422555827581348280834879405,15705897908180497062880001271426561999724005008972544196300715293701537574122,574386695213920937259007343820417029802510752426579750428758189312416867750,15973040855000600860816974646787367136127946402908768408978806375685439868553,20934130413948796333037139460875996342810005558806621330680156931816867321122,6918585327145564636398173845411579411526758237572034236476079610890705810764,14158163500813182062258176233162498241310167509137716527054939926126453647182,4164602626597695668474100217150111342272610479949122406544277384862187287433,12146526846507496913615390662823936206892812880963914267275606265272996025304,10153527926900017763244212043512822363696541810586522108597162891799345289938,13564663485965299104296214940873270349072051793008946663855767889066202733588,5612449256997576125867742696783020582952387615430650198777254717398552960096,12151885480032032868507892738683067544172874895736290365318623681886999930120,380452237704664384810613424095477896605414037288009963200982915188629772177,9067557551252570188533509616805287919563636482030947363841198066124642069518,21280306817619711661335268484199763923870315733198162896599997188206277056900,5567165819557297006750252582140767993422097822227408837378089569369734876257,10411936321072105429908396649383171465939606386380071222095155850987201580137,21338390051413922944780864872652000187403217966653363270851298678606449622266,12156296560457833712186127325312904760045212412680904475497938949653569234473,4271647814574748734312113971565139132510281260328947438246615707172526380757,9061738206062369647211128232833114177054715885442782773131292534862178874950,10134551893627587797380445583959894183158393780166496661696555422178052339133,8932270237664043612366044102088319242789325050842783721780970129656616386103,3339412934966886386194449782756711637636784424032779155216609410591712750636,9704903972004596791086522314847373103670545861209569267884026709445485704400,17467570179597572575614276429760169990940929887711661192333523245667228809456], - [2910766817845651019878574839501801340070030115151021261302834310722729507541,19727366863391167538122140361473584127147630672623100827934084310230022599144,5776684794125549462448597414050232243778680302179439492664047328281728356345,8348174920934122550483593999453880006756108121341067172388445916328941978568] + [ + 0x9c46e9ec68e9bd4fe1faaba294cba38a71aa177534cdd1b6c7dc0dbd0abd7a7, + 0xc0356530896eec42a97ed937f3135cfc5142b3ae405b8343c1d83ffa604cb81, + 0x250f5116a417d76aaa422952fcc5b33329f7714fc26d56c0432507fc740a87c4, + 0x264065ad87572e016659626c33c8213f7a373b9b8225a384f458d850bb4a949f, + 0x2bb8e94ad8d8adca6ce909ff94b8750729b294e4400376da39e33fda24bd42af, + 0x19051065d05d861ec813c15291d46a328f6201b21ad5d239d4f85fbb09a5dbae, + 0x245bd0617aa449618f5bd4550aac7b8e08d4d1c017165943cdf4776cdff3434a, + 0x9fb1a1118074ff79d8acbf5b02131e048a1570155e0f2b1c36ad091d491a88f, + 0x234ab504bbae8198972741952f78b7eb018ea192f05e54c1484ab8973ff66d88, + 0x1f66e509b84c355ae3d4c3513a282fd48f9c8c6439f42a7835fbcfe0f2a324c, + 0x1b22f5d69d725e6002cf00dd9ee62d1a5af0efdc4910f54127a920ccc43f91fa, + 0x252b55edead135f852968b7f1c4f490fa659ecd5b47a78a7db91f65a6dfc23f, + 0x1773ae2e1637c92ad0677c2a047fea8eca4b53303f21871f6892a2c0487d7ff1, + 0x2d57b02906cd0ab82a79e76faeef6f87666eac093cf7715645d5ec9f7ac732f5, + 0xa16f3a62824b281e8b2ddb8fc391a498fb061317faffa03696f834596313d93, + 0x1666f525f7f4b6988d2a37834ab747eae0587757b788eb7f1e26b08e36a08591, + 0x5da44f8e0a3b8bb13231f0ca25b50b57f5c82128e1dfec3e541d912ebe17b76, + 0x9a39ba9993303ba191bac8bdb3e0144dbfb5f39624cdd9524dc7861633bc95a, + 0x6c0fb824a19202d30ee6b418c0029e100e85a6d158f9f2a828dfd2ed0920a68, + 0x387d8e056b2b176a9776b4492cb3b418adc660627e52bb3324283bf9522395d, + 0x147a1af82036ef5b28a7a37bea40d6ac3013cf1b62358396bf7156f5c2dc9684, + 0x3038d92060daeaaf1bd0482bd3f0613d88e8dff90a7a0525f9227e4cb7c6f81b, + 0x72940aa1d538a5a39a323f9e5d65616cf6c223339006f9789a97245532908f5, + 0x2d3d604949f4e14c70b8a879aedec49b3a367ba216af048f464ed6f15e2b9023, + 0x225b9e4f35c7549f80774c2b4d18309b2dcf7c7287b982e49746a176641e73c5, + 0x1ea781288fdf13b2190095a2344828e37dfe81c75a09709f0d139bbbf6c70414, + 0x8e96c3e7e8de4432b202405458468b90dc6890d4cee128b3502e5b6cb4aeeeb, + 0x5b43da7c8aa29af6dcaae57d070b49d29ce889a64a4ac183e85d55b366c805f, + 0xbec98a034e3b8af7ba4861f1ad5a48dcef7c996e7a51c7cdde724d8f610e52, + 0x2eb67ccfa29e2b422b9f84a5d0575fc435b30fcae303039480be384ee4ebe72a, + 0x102bbdc21a3f147bf04eedee5d70bd084a7105c631c86ecd2c4e8749a13915ca, + 0x274bc16c88721babfd5bbe8d8562c1bf127ae38915280fbb8e3115cad3582f79, + 0x185cece417549b25283de04511f769101c8850b409d4928ab831611351bd9938, + 0x13c73fb043f7e978bc9cfb55c7faacb4f4c823674abe17737059ac0a32c36007, + 0x24b3a1d83308742b360c9c60595673e201cdd4cef5a4145c933c4e5969481d70, + 0x18b5ae94df9ec97aaa2a8f0f42425bcccdc8266a070f866ef0f48d7a3744398b, + 0x20eb398cb958cc2ccc7cb1fac38501abbe38169b2d8522d9e5f099f2d5905cb4, + 0x1e588dd3ec8b0d252c2c7c0c78a02b22bbbad1f4dcaa2e78a8b8eef2f4e29344, + 0xf8bf3bd6c22ba3b1bf3ab2e3fb40818cd4217ffbaf294ca42331d4e3043a0a6, + 0x388c9fcf30fc2841d648f46bad01dd10bee9dc184d25eabc9f617021109cec3, + 0x2bb7f397c5941ac67befa8b232f15c8853dac263da793555441a90cec83b6454, + 0x17f389b52f9ea7a98874a4a31ef6a7beb43fb17db0e499250bb3f0181c59fb21, + 0x3a2090eacb897a31fb10561d560a9aeec24b7ad14d17b145f20c875a0b28c7c, + 0xc398534f0eb580f1fe4bf64553389e67cca4714399430e09619dcbee17ba099, + 0x7095ac9fda46afa7f181259e3635feffa7f11ee63f3ee777a5cebf4822328c4, + 0x2046f7cf1c8f13ef2b69cbc8bc0d5d809f82568abe2b33d1cd060958b1ced683, + 0x2c274136a5de2849de6e7f92f9097296501acb68d56138fbcb660c4cb0f69107, + 0x1c4d5178acb5c6b6eceef23afc6f16ec7b0383094cb6467e8d0f4507b3cf74c3, + 0x65b1447d0d64ceced116785b92c63a6a7dd9701507dcbe8b909325e28f7b8d3, + 0x2265d7e244881220c81a193d979330409c9bfa333438951340e023e7b72a1961, + 0x15b12b355af7e05637a1c76e67f9cec6fca8a6449b37669f6850502256b30aba, + 0x1a1522fecc6ae028e4d3e3029497b88f35c2b48c687af168ec2582d9075b4387, + 0x22f56e79e81b7496e472a641a053c414bcc53b0a9350e2589240803076f58f26, + 0x202ddb66d0988994e7aabad692ceac4e2324672a17ab8417d1ee278afd17fd0c, + 0x12b0701e8813c5b21a8e30208f8f1158b96cd428ae77bdea72f84510f73edfce, + 0x1e63fd20e706e1407c8838ceb26b84c9fe693fdde0eb1e1a9df7e84e53eeee7e, + 0x20a16c5a86256deffd15af174c39f9d9aa11500676ac7e570088280dd1896259, + 0x1c8f8bf8e153da55ad5aca2eaaee38da563e0435c0f2f37c27558fb9bae0a3eb, + 0xd7732687bb7bf5f3aabcfdcc4fbb67e159c1983213e416c3880124fddf187c9, + 0xcdd04475a86999a2edcbbbf8264b195e108b3b60b6475d835f6ccef9e2f6865, + 0x2fe65586cd4e754b4c63a88c2ed3f9ba0e3bfa43f547b41153560c214fe3cbcd, + 0x503cf963c8273604e659128ec29261f62399815d98c56dbf4f2837c727ad4d9, + 0x1ee48ea27839061b78379936f6d97ca9400b393ef5fdf38ef1475c8742cb334c, + 0x1a423f8d8fc892b22d7cd5bf0197c575c579e83563d04859d73b2c1c5c0413f9, + 0x69a0da50133e9952f00e61778972a7be0e8d8ab76c95616ae465636abb97ec7, + 0x1bf7879dd42f2cbb91c65a0976356f67964c2f94dfbf0e44cf2b9909165d8614, + 0x1b23dccf485822065c8fc0afe610be7164e25056267f6c4a805fffd4547a0b98, + 0x2ebe90d6f6fdca420e0c2e004ce5c5a4409e564c9c4f3671e3011f627bec7c2e, + 0x167cd6930535a816dfebe81d20c376e77687760f3a2fa0da290b2f4d6c6863f7, + 0x8865c10f4a633c54ccc8b68b79df285f19f1210374cc64e3c8a966d4f90264b, + 0x1de902fbc0bf01951ca25abb39d78894721b37e071851b03a72cc6b833b7893b, + 0xe3eca007699dd0f852eb22da642e495f67c988dd5bf0137676b16a31eab4667 + ], + [ + [ + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0xcc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff9 + ], + [ + 0x2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e8, + 0x1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c8 + ] + ], + [ + [ + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x20e3e914631964e394d269ae59f17efee3fecee512cbb163d32cc760be574bd6 + ], + [ + 0x2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e8, + 0x10a44ed9dd9ce568563394632833d8633690d329ae737c8c7220a9b197ee3f46 + ] + ], + [ + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x1fd20dcb58503896fd52998d6a5be6f12ec33b3cbd590c793e45de825ff8cb5f, + 0x8c8295df0ba11861e97f0cdde8f202a7096c1e6452d33d64a11b5be4e0a1efb, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x2458ee6d7c526073d165d2b08b95cf8947e20e05a76bc12b401b996421e89835, + 0x18c235e6e723390aa65baf06ffa557829f78a2fe1fbfb44eef84e938209c92f9, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x1868e106689f8ea2e9c561b4b192899d07b52e58595c393436c37df24976a584, + 0x2d5161804f0ec6445cb8904ad3e8e9ec21153350df4075c9cbe840b7b609ca92, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x3510550ddf6292355c690f03b9b815aab2dc3f4914612da7ecb79ddcf7b0b90, + 0x9a2e7bb3b278a1d5f264a26345ad8365efe0058403d8a52909cf2d5f6ee6170, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x13dd4148c491a166b015a7a4233f4e488ae94a0e6439be66fe149b50b55759c0, + 0x1d2d3b261f5beb3fc010f42ec3825649d90150eee4ce55dc9f86ddf110295550, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x221b4477678dad4e2abcabb47eb5e7a4129190b3855ae4eecd8ba68643ff77e5, + 0x16b76448e9855f165f2043f5f09bedf1830a4998ff45ebc25f1d40e8e8fcd6e4, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x2a10b6a2cbae9578142cf66104b69e448eae6d3bd53ac8602363460e2286c92d, + 0x2db84dba4a9d96cebe94dfb1d59edfa58ccfa871b9c067c522e31949b69f2bec, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x1ca9bbf26402238296ad897ec1a55b4fc273cf20c1f68f03d5c149be890e7b60, + 0x283d37fa5e35d25c83d1b9d34ecb00cd03848ca730ace52f367e0d7b5fde30d6, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x349057941b141ceea5a063a0ff8ab221271e618a174e5d8009ab5f9c791d960, + 0x1af2e1d98c3c09908503883d3b9ed50fe8958eb1e5d6538016c344d40070efc2, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x5b7bddacf4522b0aa3082e2c05448962743d0023bb6402291f592e6c1da4679, + 0x1fceeccf337e8a903cf6a0c21a6445da7ff8c4a0bc78909c7e704131c8a35241, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x2f30a25f4d843e28afdd850f31d1920ee058dfb6d91c322fc960473e917a6768, + 0x1a55160bf49a4936bcc59162617026194574a89e5857751b68f3c08f7c07ce87, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x19c66ee887ab4763b17573b6ad192b7df1af24f54761998b03b342b95709041e, + 0x1a82828b7f87eba7f5f8624b31e1115506ab3e723266777b3789c9104f9c781e, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0xf506d3199d96083de9fc4e71b250825e84a242d81ae3a81d99debc7faed3385, + 0x1cac7482d91faef657db9072a97567ff172374d99987a8b24b2c04472aab9f83, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x249b26b1d4e333b23f3192f0e4f52884ee63d489ee153ecc3216939a72848150, + 0x13d1aeb10b225e2a8b97131154407d1bf145972dcd3a0073339dca336180dfb1, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0xb90f72b7fcf867eb2e0f9400787d1dd52720cbc14a7095784e4116624d16df3, + 0x25e346edd8dd55142abd2135951398230f0c8d08bc5c365c5a6cd70011a8f39, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x263003b8ed502577c6427b0b4589ef6ceb87b4e21b7c424e587f2630a7b868a2, + 0x2d92ef6b8bdc53dd1b6c5b1c92e5a8248eb9c12255b910ff89c09961ec12ead7, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x2eb36b6d0bfc593a8d6d9459a7af04f0b15bcae4181bbb123543870c11316681, + 0x1e48bb591146f461c1d2f085f3979139e37f4a5c2354952c833b2791f59034e0, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0xe759913751418871f0351ee180ca466cf8a03f541079c1b51bb001550d8162a, + 0x1e45e194b16936c5b1f81c72eb0fe8c62e859c4661b14b7e327503cf49eca55b, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x28c8b58c9e4cfb830a51af4529318b6269c4f6ac1867ed1174ce4aefc57fbeb3, + 0x255b293fcb1be27d9e5aafd4cd28c26746fc3520889367eed1355c2c41b93016, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x1db1367a8e37c5597835365bbfa66f6ecf40da775a54c35d5c94da70415544fe, + 0xcdd97951c2f0b885edc683b9db74f08df61286578a69989a9fed7ca34c5b4ce, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0xe4d4e42cacb9fa6745c6dd3630ec5a4cca8a912b7ec28576ab3ba29c57306c9, + 0x2141a925c279e4c4e351641744750d4702d90ef2137d1905dada0bae3c7b3af6, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x8f9f9b3abc79ed89c20597cfbfe49021119cc50648ce401dc50cb042a54d167, + 0x6af6c072313d868cd945c9f0eb7d4eadb24c8d4763fa042952b99353df2b236, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x8b43c97bf4a40b4f376d1fa0c5e6e6955cbf9ba301f878ed3eae4ac812b79d1, + 0x11e0e607ac6781ca34a714e6c5b7a4f839852377446520032420e2abe16115a7, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x2dd7f0e1b303f425cb7e6b1c30ca428b3bff751e7b651152eb4de008b2c00da6, + 0x107d7f92d1c6a24068b917120f993ae3ee84349aaadb71eaa4128b349812dda8, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x10ab9e8e4ec9ad5fdb1166c64ed2fc3223c7e16dd982f66dcd820a7861ae1463, + 0x3000d3b3ddb3fb864ccc729984468a7317397713303544a84d7de1d209d25cb1, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x17610359e624e7feb3eede8099a1dc45c4a0c6b2debc2dc8f200fa27a0da6ebd, + 0x2affce5b7a7d8c5aac04f6c2708794cd01a8439b65d74df5982d24ad2a944eb8, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x2d439fbefe8d2b65ed32658bd21fc5604408d5fb69e1f64965e5895ca61c6e09, + 0xb51cc2a1b1c329fd72a286d4938540db3cfc4320de363a3f68a7935cd193ab9, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x1468ea2868d31f7ebafe78af8c24656a3185963272f34c51d5e2695c43bd3247, + 0x29553949324f27f4fa7bd734920e9be7b662a0ec5797fdd4ed3fe19464879b95, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0xd9780ee7d395f7c977fd4b86329f6cd720047a7f9d1672d18d2cfb428343afa, + 0x210a098afd451fca3997860e220106c7487f4716831dfff78036de18f17cb31d, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x1cedcfe2751b360e73d6ef5af88cd5b75a2b2d97c571889a0dda87a0dd90ad81, + 0x22719f26e16723c1bd45a619e91836c340a304f3648672f90de2b047880aee03, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0xae0cec959c4c7859f670f19c7490f8eef6ad66346e04613c1350597be000be2, + 0x177560de731482bdb7316c238bc38f20a16cd03edda2e0393b1c515ec64b0727, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x1f19a267da0b8fc2b4850a4f458add5514edf0aad6f7a7f175aef0b98e816a40, + 0x1da77cdeff9cf822b54509031ea2888f6f398051ae1870afd3770e7724c09f31, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x2d1e17aaaa96743665a869970255c267ba338cfd43ec9b33ecaa764f48f17a8, + 0xc376a8ff1da39dec980316ea26ef66fae5c86877a8f82266c14670024329d12, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0xbb856048ef43a77b39560adeb3c7a9a783db5cad8e3f422495a69c56680a79, + 0x1d81808a3c73be1bb2c99b6403f3ac4a532c88d29ad652cbb20061656006c19a, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x15e52ae83a9db363d24cc5900df8ff0b81e445d4409a0e2aafd3223c354add62, + 0x2aa2fc03cb5f72e237f7d88ef66f765a159be533354ffb88751abb8885203ad4, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x10afedad881a1da7dace5c69546d0890bc35f41992b1062a7c7789b03ac932c0, + 0x1d18193701979ad24042446e947dfedfad22a6e7d4f6bde875fe2d8c882c858a, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x2f0b8457690e4d9770beb0300a09fc7001cd417061e826bc450dd96d7b24f36, + 0xdc31897d61d70e16870e0b02b9776bc53b8b9848be3062f8da18ff9d981effb, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x203c94bb7694f9cdad3a14a7603e3cb69c141200fd46bdc9ebb0d5d73663525, + 0x2b778a231f21f8a6cdaa3c84372933e610eb985dcc81af9926fe8b09f1afc81f, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x2c8a0376c766055e6a9d5272a2466a28faa7e359db111e84d98b2138c8c9d5d2, + 0x2ffda33f5b85a4fde16ba590ae0cd49fce4ad01e095f94f49138fe44aaa8c778, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x318af53cfd822ec2a7f4d40614f72fc6cb27f44067fb58d15789bbe15444844, + 0xd24997465c5b23d4e7436a4ecef2f91ce9f8910b6fa8a4a3ba6f884bd7206cc, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x1ea39e4d9edebf65d648e42880b396a6becfa66b3c5e47ff9a33577a3d2a658, + 0x15e4e016c94a026fd9ede9bdcf11268f7735cf5ebdbdd4a092fda1ee8b50f2ff, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x2ef185c4b1cdb7072a82fd43fe4bb145c4dbd04973fb3ef76e757b00392eac9d, + 0x15cedc8a4ef6f7017d1dd3d92255beb54f1d7d1e3bb0204cb07ab81c71435902, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0xdbf148ee8983db0c117b111270f1c2c8219565733684494eaf5ce0645e5749a, + 0x2842f44ddc05dbd5b319b1efe6b3eabced380b99ffc42dfb08805ea2b4c48aab, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x1aa07e7ffa4a036f1b7efb2e124e75028426fdf5f1e4fb8bb62e1ebf3298af2c, + 0x1e5a2abded8c7022a8ba97ea683b605d09f017fd43e92296656561eb96d25d32, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0xacf3ab02c018573bc3d36b0cb73de6df11e8cc1dea223e98a2a0cfbc028d2af, + 0x1bab48ad2c31dcec5fcc6df1f02dc4164f949202122673b06105f7ff1beabb29, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x1a36af3ad1c61cddc06a2a4c6967dc004b589a4a8b358ded11a38cce6a7f31c, + 0x125e0e822514cf49536fa643a66e1d2fa6788cb5b4805c9cd3cb69a584e0d8d2, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x85be8486ecb3dbf71d63940d8d689f9b142434a14d5d4f8c93d7d0f17bfcbd3, + 0x275651360d88063b2feead8bc71ae9c002d5db9822ab63b058f11e0d506b17e3, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0xf7eb245596d9ac5ecc21446ed94c80289db1e1f9f620c18f7815b247b228a6f, + 0x221862a04a00f406bc67f7677ab459c9d887c8bb88091513f0fc2fb103ad549c, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x1bd575603b7085afcf0a588a5fadf8705cda7eb1d4ab7e70137dbd47fc26e3a2, + 0x146d1d176245ff772db8575d986a82e931079de61e67184c4158a6f62db446f1, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x2202ec1e7fd85c4749393664f024d578d392d59cb12a42e2ef4fa728da4cd3a, + 0x1c0e72693a0e12bff0ab3e12a1203c846b5dfdb9dd5ba26a7309c6970371421, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x2b3d8733bb4872b6cbb0bd83378163ab14a585dbf5ad9758c07948de056071e0, + 0x185d12aa30aed1a0575b9d3dcee6332f4fa34643a429cfdd8de0fdc87a29640e, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x1b394227301f28bee29bd3dfc35dfcc8e1c60ec6dd944dd33593a9a77675f641, + 0x15b1cfd522bdc418f6c08a3deb114a4ff48854b4a496537d41eb3a325f2265e7, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0xbca3aef46833e8a30a9db0a16b59abc619800d2da15da01dd5a0713ff4cbbb8, + 0x529062596e51b8ca2c2f8c7cf4adff0853150015e2e6b4ce7af212500f5e6ca, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x2fda517f4261325a7366a45da1e847cd150d022be2982eb6105dcfc31fdef60, + 0x1fec5a09cea4d25e5b7ff9d2fbab64d264db993e8d8629b7154a1539d12dd1cf, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x2d87776eef5dfabbe5605094751af17b831717fa3f8e01943b74d1a9a42eb1bb, + 0xd257a437910f3995aebd0afb9be584967afa4188c4684958f68c39f9f01ff19, + 0x66f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, + 0x98f0aa06092ed2cbcbac004f90799e6e1c32fc24a9f0b6066f8d7289716aee4, + 0xcc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff9 + ] ) - } + // noir-fmt:ignore -pub fn x5_3_config() -> PoseidonConfig<195, 9> { +pub fn x5_3_config() -> PoseidonConfig<3, 81, 285> { config( 3, 8, 57, - 5, - [6745197990210204598374042828761989596302876299545964402857411729872131034734,426281677759936592021316809065178817848084678679510574715894138690250139748,4014188762916583598888942667424965430287497824629657219807941460227372577781,21328925083209914769191926116470334003273872494252651254811226518870906634704,19525217621804205041825319248827370085205895195618474548469181956339322154226,1402547928439424661186498190603111095981986484908825517071607587179649375482,18320863691943690091503704046057443633081959680694199244583676572077409194605,17709820605501892134371743295301255810542620360751268064484461849423726103416,15970119011175710804034336110979394557344217932580634635707518729185096681010,9818625905832534778628436765635714771300533913823445439412501514317783880744,6235167673500273618358172865171408902079591030551453531218774338170981503478,12575685815457815780909564540589853169226710664203625668068862277336357031324,7381963244739421891665696965695211188125933529845348367882277882370864309593,14214782117460029685087903971105962785460806586237411939435376993762368956406,13382692957873425730537487257409819532582973556007555550953772737680185788165,2203881792421502412097043743980777162333765109810562102330023625047867378813,2916799379096386059941979057020673941967403377243798575982519638429287573544,4341714036313630002881786446132415875360643644216758539961571543427269293497,2340590164268886572738332390117165591168622939528604352383836760095320678310,5222233506067684445011741833180208249846813936652202885155168684515636170204,7963328565263035669460582454204125526132426321764384712313576357234706922961,1394121618978136816716817287892553782094854454366447781505650417569234586889,20251767894547536128245030306810919879363877532719496013176573522769484883301,141695147295366035069589946372747683366709960920818122842195372849143476473,15919677773886738212551540894030218900525794162097204800782557234189587084981,2616624285043480955310772600732442182691089413248613225596630696960447611520,4740655602437503003625476760295930165628853341577914460831224100471301981787,19201590924623513311141753466125212569043677014481753075022686585593991810752,12116486795864712158501385780203500958268173542001460756053597574143933465696,8481222075475748672358154589993007112877289817336436741649507712124418867136,5181207870440376967537721398591028675236553829547043817076573656878024336014,1576305643467537308202593927724028147293702201461402534316403041563704263752,2555752030748925341265856133642532487884589978209403118872788051695546807407,18840924862590752659304250828416640310422888056457367520753407434927494649454,14593453114436356872569019099482380600010961031449147888385564231161572479535,20826991704411880672028799007667199259549645488279985687894219600551387252871,9159011389589751902277217485643457078922343616356921337993871236707687166408,5605846325255071220412087261490782205304876403716989785167758520729893194481,1148784255964739709393622058074925404369763692117037208398835319441214134867,20945896491956417459309978192328611958993484165135279604807006821513499894540,229312996389666104692157009189660162223783309871515463857687414818018508814,21184391300727296923488439338697060571987191396173649012875080956309403646776,21853424399738097885762888601689700621597911601971608617330124755808946442758,12776298811140222029408960445729157525018582422120161448937390282915768616621,7556638921712565671493830639474905252516049452878366640087648712509680826732,19042212131548710076857572964084011858520620377048961573689299061399932349935,12871359356889933725034558434803294882039795794349132643274844130484166679697,3313271555224009399457959221795880655466141771467177849716499564904543504032,15080780006046305940429266707255063673138269243146576829483541808378091931472,21300668809180077730195066774916591829321297484129506780637389508430384679582,20480395468049323836126447690964858840772494303543046543729776750771407319822,10034492246236387932307199011778078115444704411143703430822959320969550003883,19584962776865783763416938001503258436032522042569001300175637333222729790225,20155726818439649091211122042505326538030503429443841583127932647435472711802,13313554736139368941495919643765094930693458639277286513236143495391474916777,14606609055603079181113315307204024259649959674048912770003912154260692161833,5563317320536360357019805881367133322562055054443943486481491020841431450882,10535419877021741166931390532371024954143141727751832596925779759801808223060,12025323200952647772051708095132262602424463606315130667435888188024371598063,2906495834492762782415522961458044920178260121151056598901462871824771097354,19131970618309428864375891649512521128588657129006772405220584460225143887876,8896386073442729425831367074375892129571226824899294414632856215758860965449,7748212315898910829925509969895667732958278025359537472413515465768989125274,422974903473869924285294686399247660575841594104291551918957116218939002865,6398251826151191010634405259351528880538837895394722626439957170031528482771,18978082967849498068717608127246258727629855559346799025101476822814831852169,19150742296744826773994641927898928595714611370355487304294875666791554590142,12896891575271590393203506752066427004153880610948642373943666975402674068209,9546270356416926575977159110423162512143435321217584886616658624852959369669,2159256158967802519099187112783460402410585039950369442740637803310736339200,8911064487437952102278704807713767893452045491852457406400757953039127292263,745203718271072817124702263707270113474103371777640557877379939715613501668,19313999467876585876087962875809436559985619524211587308123441305315685710594,13254105126478921521101199309550428567648131468564858698707378705299481802310,1842081783060652110083740461228060164332599013503094142244413855982571335453,9630707582521938235113899367442877106957117302212260601089037887382200262598,5066637850921463603001689152130702510691309665971848984551789224031532240292,4222575506342961001052323857466868245596202202118237252286417317084494678062,2919565560395273474653456663643621058897649501626354982855207508310069954086,6828792324689892364977311977277548750189770865063718432946006481461319858171,2245543836264212411244499299744964607957732316191654500700776604707526766099,19602444885919216544870739287153239096493385668743835386720501338355679311704,8239538512351936341605373169291864076963368674911219628966947078336484944367,15053013456316196458870481299866861595818749671771356646798978105863499965417,7173615418515925804810790963571435428017065786053377450925733428353831789901,8239211677777829016346247446855147819062679124993100113886842075069166957042,15330855478780269194281285878526984092296288422420009233557393252489043181621,10014883178425964324400942419088813432808659204697623248101862794157084619079,14014440630268834826103915635277409547403899966106389064645466381170788813506,3580284508947993352601712737893796312152276667249521401778537893620670305946,2559754020964039399020874042785294258009596917335212876725104742182177996988,14898657953331064524657146359621913343900897440154577299309964768812788279359,2094037260225570753385567402013028115218264157081728958845544426054943497065,18051086536715129874440142649831636862614413764019212222493256578581754875930,21680659279808524976004872421382255670910633119979692059689680820959727969489,13950668739013333802529221454188102772764935019081479852094403697438884885176,9703845704528288130475698300068368924202959408694460208903346143576482802458,12064310080154762977097567536495874701200266107682637369509532768346427148165,16970760937630487134309762150133050221647250855182482010338640862111040175223,9790997389841527686594908620011261506072956332346095631818178387333642218087,16314772317774781682315680698375079500119933343877658265473913556101283387175,82044870826814863425230825851780076663078706675282523830353041968943811739,21696416499108261787701615667919260888528264686979598953977501999747075085778,327771579314982889069767086599893095509690747425186236545716715062234528958,4606746338794869835346679399457321301521448510419912225455957310754258695442,64499140292086295251085369317820027058256893294990556166497635237544139149,10455028514626281809317431738697215395754892241565963900707779591201786416553,10421411526406559029881814534127830959833724368842872558146891658647152404488,18848084335930758908929996602136129516563864917028006334090900573158639401697,13844582069112758573505569452838731733665881813247931940917033313637916625267,13488838454403536473492810836925746129625931018303120152441617863324950564617,15742141787658576773362201234656079648895020623294182888893044264221895077688,6756884846734501741323584200608866954194124526254904154220230538416015199997,7860026400080412708388991924996537435137213401947704476935669541906823414404,7871040688194276447149361970364037034145427598711982334898258974993423182255,20758972836260983284101736686981180669442461217558708348216227791678564394086,21723241881201839361054939276225528403036494340235482225557493179929400043949,19428469330241922173653014973246050805326196062205770999171646238586440011910,7969200143746252148180468265998213908636952110398450526104077406933642389443,10950417916542216146808986264475443189195561844878185034086477052349738113024,18149233917533571579549129116652755182249709970669448788972210488823719849654,3729796741814967444466779622727009306670204996071028061336690366291718751463,5172504399789702452458550583224415301790558941194337190035441508103183388987,6686473297578275808822003704722284278892335730899287687997898239052863590235,19426913098142877404613120616123695099909113097119499573837343516470853338513,5120337081764243150760446206763109494847464512045895114970710519826059751800,5055737465570446530938379301905385631528718027725177854815404507095601126720,14235578612970484492268974539959119923625505766550088220840324058885914976980,653592517890187950103239281291172267359747551606210609563961204572842639923,5507360526092411682502736946959369987101940689834541471605074817375175870579,7864202866011437199771472205361912625244234597659755013419363091895334445453,21294659996736305811805196472076519801392453844037698272479731199885739891648,13767183507040326119772335839274719411331242166231012705169069242737428254651,810181532076738148308457416289197585577119693706380535394811298325092337781,14232321930654703053193240133923161848171310212544136614525040874814292190478,16796904728299128263054838299534612533844352058851230375569421467352578781209,16256310366973209550759123431979563367001604350120872788217761535379268327259,19791658638819031543640174069980007021961272701723090073894685478509001321817,7046232469803978873754056165670086532908888046886780200907660308846356865119,16001732848952745747636754668380555263330934909183814105655567108556497219752,9737276123084413897604802930591512772593843242069849260396983774140735981896,11410895086919039954381533622971292904413121053792570364694836768885182251535,19098362474249267294548762387533474746422711206129028436248281690105483603471,11013788190750472643548844759298623898218957233582881400726340624764440203586,2206958256327295151076063922661677909471794458896944583339625762978736821035,7171889270225471948987523104033632910444398328090760036609063776968837717795,2510237900514902891152324520472140114359583819338640775472608119384714834368,8825275525296082671615660088137472022727508654813239986303576303490504107418,1481125575303576470988538039195271612778457110700618040436600537924912146613,16268684562967416784133317570130804847322980788316762518215429249893668424280,4681491452239189664806745521067158092729838954919425311759965958272644506354,3131438137839074317765338377823608627360421824842227925080193892542578675835,7930402370812046914611776451748034256998580373012248216998696754202474945793,8973151117361309058790078507956716669068786070949641445408234962176963060145,10223139291409280771165469989652431067575076252562753663259473331031932716923,2232089286698717316374057160056566551249777684520809735680538268209217819725,16930089744400890347392540468934821520000065594669279286854302439710657571308,21739597952486540111798430281275997558482064077591840966152905690279247146674,7508315029150148468008716674010060103310093296969466203204862163743615534994,11418894863682894988747041469969889669847284797234703818032750410328384432224,10895338268862022698088163806301557188640023613155321294365781481663489837917,18644184384117747990653304688839904082421784959872380449968500304556054962449,7414443845282852488299349772251184564170443662081877445177167932875038836497,5391299369598751507276083947272874512197023231529277107201098701900193273851,10329906873896253554985208009869159014028187242848161393978194008068001342262,4711719500416619550464783480084256452493890461073147512131129596065578741786,11943219201565014805519989716407790139241726526989183705078747065985453201504,4298705349772984837150885571712355513879480272326239023123910904259614053334,9999044003322463509208400801275356671266978396985433172455084837770460579627,4908416131442887573991189028182614782884545304889259793974797565686968097291,11963412684806827200577486696316210731159599844307091475104710684559519773777,20129916000261129180023520480843084814481184380399868943565043864970719708502,12884788430473747619080473633364244616344003003135883061507342348586143092592,20286808211545908191036106582330883564479538831989852602050135926112143921015,16282045180030846845043407450751207026423331632332114205316676731302016331498,4332932669439410887701725251009073017227450696965904037736403407953448682093,11105712698773407689561953778861118250080830258196150686012791790342360778288,21853934471586954540926699232107176721894655187276984175226220218852955976831,9807888223112768841912392164376763820266226276821186661925633831143729724792,13411808896854134882869416756427789378942943805153730705795307450368858622668,17906847067500673080192335286161014930416613104209700445088168479205894040011,14554387648466176616800733804942239711702169161888492380425023505790070369632,4264116751358967409634966292436919795665643055548061693088119780787376143967,2401104597023440271473786738539405349187326308074330930748109868990675625380,12251645483867233248963286274239998200789646392205783056343767189806123148785,15331181254680049984374210433775713530849624954688899814297733641575188164316,13108834590369183125338853868477110922788848506677889928217413952560148766472,6843160824078397950058285123048455551935389277899379615286104657075620692224,10151103286206275742153883485231683504642432930275602063393479013696349676320,7074320081443088514060123546121507442501369977071685257650287261047855962224,11413928794424774638606755585641504971720734248726394295158115188173278890938,7312756097842145322667451519888915975561412209738441762091369106604423801080,7181677521425162567568557182629489303281861794357882492140051324529826589361,15123155547166304758320442783720138372005699143801247333941013553002921430306,13409242754315411433193860530743374419854094495153957441316635981078068351329], - [7511745149465107256748700652201246547602992235352608707588321460060273774987,10370080108974718697676803824769673834027675643658433702224577712625900127200,19705173408229649878903981084052839426532978878058043055305024233888854471533,18732019378264290557468133440468564866454307626475683536618613112504878618481,20870176810702568768751421378473869562658540583882454726129544628203806653987,7266061498423634438633389053804536045105766754026813321943009179476902321146,9131299761947733513298312097611845208338517739621853568979632113419485819303,10595341252162738537912664445405114076324478519622938027420701542910180337937,11597556804922396090267472882856054602429588299176362916247939723151043581408]) - + alpha(), + [ + 0xee9a592ba9a9518d05986d656f40c2114c4993c11bb29938d21d47304cd8e6e, + 0xf1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e864, + 0x8dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f5, + 0x84d520e4e5bb469e1f9075cb7c490efa59565eedae2d00ca8ef88ceea2b0197, + 0x2d15d982d99577fa33da56722416fd734b3e667a2f9f15d8eb3e767ae0fd811e, + 0xed2538844aba161cf1578a43cf0364e91601f6536a5996d0efbe65632c41b6d, + 0x2600c27d879fbca186e739e6363c71cf804c877d829b735dcc3e3af02955e60a, + 0x28f8bd44a583cbaa475bd15396430e7ccb99a5517440dfd970058558282bf2c5, + 0x9cd7d4c380dc5488781aad012e7eaef1ed314d7f697a5572d030c55df153221, + 0x11bb6ee1291aabb206120ecaace460d24b6713febe82234951e2bee7d0f855f5, + 0x2d74e8fa0637d9853310f3c0e3fae1d06f171580f5b8fd05349cadeecfceb230, + 0x2735e4ec9d39bdffac9bef31bacba338b1a09559a511a18be4b4d316ed889033, + 0xf03c1e9e0895db1a5da6312faa78e971106c33f826e08dcf617e24213132dfd, + 0x17094cd297bf827caf92920205b719c18741090b8f777811848a7e9ead6778c4, + 0xdb8f419c21f92461fc2b3219465798348df90d4178042c81ba7d4b4d559e2b8, + 0x243443613f64ffa417427ed5933fcfbc66809db60b9ca1724a22709ceceeece2, + 0x22af49fbfd5d7e9fcd256c25c07d3dd8ecbbae6deecd03aa04bb191fada75411, + 0x14fbd37fa8ad6e4e0c78a20d93c7230c4677f797b4327323f7f7c097c19420e0, + 0x15a9298bbb882534d4b2c9fbc6e4ef4189420c4eb3f3e1ea22faa7e18b5ae625, + 0x2f7de75f23ddaaa5221323ebceb2f2ac83eef92e854e75434c2f1d90562232bc, + 0x36a4432a868283b78a315e84c4ae5aeca216f2ff9e9b2e623584f7479cd5c27, + 0x2180d7786a8cf810e277218ab14a11e5e39f3c962f11e860ae1c5682c797de5c, + 0xa268ef870736eebd0cb55be640d73ee3778990484cc03ce53572377eefff8e4, + 0x1eefefe11c0be4664f2999031f15994829e982e8c90e09069df9bae16809a5b2, + 0x27e87f033bd1e0a89ca596e8cb77fe3a4b8fb93d9a1129946571a3c3cf244c52, + 0x1498a3e6599fe243321f57d6c5435889979c4f9d2a3e184d21451809178ee39, + 0x27c0a41f4cb9fe67e9dd4d7ce33707f74d5d6bcc235bef108dea1bbebde507aa, + 0x1f75230908b141b46637238b120fc770f4f4ae825d5004c16a7c91fe1dae280f, + 0x25f99a9198e923167bba831b15fffd2d7b97b3a089808d4eb1f0a085bee21656, + 0x101bc318e9ea5920d0f6acdc2bb526593d3d56ec8ed14c67622974228ba900c6, + 0x1a175607067d517397c1334ecb019754ebc0c852a3cf091ec1ccc43207a83c76, + 0xf02f0e6d25f9ea3deb245f3e8c381ee6b2eb380ba4af5c1c4d89770155df37b, + 0x151d757acc8237af08d8a6677203ec9692565de456ae789ff358b3163b393bc9, + 0x256cd9577cea143049e0a1fe0068dd20084980ee5b757890a79d13a3a624fad4, + 0x513abaff6195ea48833b13da50e0884476682c3fbdd195497b8ae86e1937c61, + 0x1d9570dc70a205f36f610251ee6e2e8039246e84e4ac448386d19dbac4e4a655, + 0x18f1a5194755b8c5d5d7f1bf8aaa6f56effb012dd784cf5e044eec50b29fc9d4, + 0x266b53b615ef73ac866512c091e4a4f2fa4bb0af966ef420d88163238eebbca8, + 0x2d63234c9207438aa42b8de27644c02268304dfeb8c89a1a3f4fd6e8344ae0f7, + 0x2ab30fbe51ee49bc7b3adde219a6f0b5fbb976205ef8df7e0021daee6f55c693, + 0x1aee6d4b3ebe9366dcb9cce48969d4df1dc42abcd528b270068d9207fa6a45c9, + 0x1891aeab71e34b895a79452e5864ae1d11f57646c60bb34aa211d123f6095219, + 0x24492b5f95c0b0876437e94b4101c69118e16b2657771bd3a7caab01c818aa4b, + 0x1752161b3350f7e1b3b2c8663a0d642964628213d66c10ab2fddf71bcfde68f, + 0xab676935722e2f67cfb84938e614c6c2f445b8d148de54368cfb8f90a00f3a7, + 0xb0f72472b9a2f5f45bc730117ed9ae5683fc2e6e227e3d4fe0da1f7aa348189, + 0x16aa6f9273acd5631c201d1a52fc4f8acaf2b2152c3ae6df13a78a513edcd369, + 0x2f60b987e63614eb13c324c1d8716eb0bf62d9b155d23281a45c08d52435cd60, + 0x18d24ae01dde92fd7606bb7884554e9df1cb89b042f508fd9db76b7cc1b21212, + 0x4fc3bf76fe31e2f8d776373130df79d18c3185fdf1593960715d4724cffa586, + 0xd18f6b53fc69546cfdd670b41732bdf6dee9e06b21260c6b5d26270468dbf82, + 0xba4231a918f13acec11fbafa17c5223f1f70b4cdb045036fa5d7045bd10e24, + 0x7b458b2e00cd7c6100985301663e7ec33c826da0635ff1ebedd0dd86120b4c8, + 0x1c35c2d96db90f4f6058e76f15a0c8286bba24e2ed40b16cec39e9fd7baa5799, + 0x1d12bea3d8c32a5d766568f03dd1ecdb0a4f589abbef96945e0dde688e292050, + 0xd953e20022003270525f9a73526e9889c995bb62fdea94313db405a61300286, + 0x29f053ec388795d786a40bec4c875047f06ff0b610b4040a760e33506d2671e1, + 0x4188e33735f46b14a4952a98463bc12e264d5f446e0c3f64b9679caaae44fc2, + 0x149ec28846d4f438a84f1d0529431bb9e996a408b7e97eb3bf1735cdbe96f68f, + 0xde20fae0af5188bca24b5f63630bad47aeafd98e651922d148cce1c5fdddee8, + 0x12d650e8f790b1253ea94350e722ad2f7d836c234b8660edf449fba6984c6709, + 0x22ab53aa39f34ad30ea96717ba7446aafdadbc1a8abe28d78340dfc4babb8f6c, + 0x26503e8d4849bdf5450dabea7907bc3de0de109871dd776904a129db9149166c, + 0x1d5e7a0e2965dffa00f5454f5003c5c8ec34b23d897e7fc4c8064035b0d33850, + 0xee3d8daa098bee012d96b7ec48448c6bc9a6aefa544615b9cb3c7bbd07104cb, + 0x1bf282082a04979955d30754cd4d9056fa9ef7a7175703d91dc232b5f98ead00, + 0x7ae1344abfc6c2ce3e951bc316bee49971645f16b693733a0272173ee9ad461, + 0x217e3a247827c376ec21b131d511d7dbdc98a36b7a47d97a5c8e89762ee80488, + 0x215ffe584b0eb067a003d438e2fbe28babe1e50efc2894117509b616addc30ee, + 0x1e770fc8ecbfdc8692dcedc597c4ca0fbec19b84e33da57412a92d1d3ce3ec20, + 0x2f6243cda919bf4c9f1e3a8a6d66a05742914fc19338b3c0e50e828f69ff6d1f, + 0x246efddc3117ecd39595d0046f44ab303a195d0e9cc89345d3c03ff87a11b693, + 0x53e8d9b3ea5b8ed4fe006f139cbc4e0168b1c89a918dfbe602bc62cec6adf1, + 0x1b894a2f45cb96647d910f6a710d38b7eb4f261beefff135aec04c1abe59427b, + 0xaeb1554e266693d8212652479107d5fdc077abf88651f5a42553d54ec242cc0, + 0x16a735f6f7209d24e6888680d1781c7f04ba7d71bd4b7d0e11faf9da8d9ca28e, + 0x487b8b7fab5fc8fd7c13b4df0543cd260e4bcbb615b19374ff549dcf073d41b, + 0x1e75b9d2c2006307124bea26b0772493cfb5d512068c3ad677fdf51c92388793, + 0x5120e3d0e28003c253b46d5ff77d272ae46fa1e239d1c6c961dcb02da3b388f, + 0xda5feb534576492b822e8763240119ac0900a053b171823f890f5fd55d78372, + 0x2e211b39a023031a22acc1a1f5f3bb6d8c2666a6379d9d2c40cc8f78b7bd9abe + ], + [ + [ + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771, + 0x143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7 + ], + [ + 0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0, + 0x2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe23, + 0x176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee2911 + ], + [ + 0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d, + 0x101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa, + 0x19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e0 + ] + ], + [ + [ + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x1e6f20a11d1e31e43f83dcedddb9a0236203f5f24ae72c925a8a79a66831f51d, + 0x1bd8c528472e57bdc722a141f8785694484f426725403ae24084e3027e782467 + ], + [ + 0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0, + 0x2d51ba82c8073c6d6bacf1ad5e56655b7143625b0a9e9c3190527a1a5f05079a, + 0x1b07d6d51e6f7e97e0ab10fc2e51ea83ce0611f940ff0731b5f927fe8d6a77c9 + ], + [ + 0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d, + 0x11e12a40d262ae88e8376f62d19edf43093cdef1ccf34d985a3e53f0bc5765a0, + 0x221c170e4d02a2479c6f3e47b5ff55781574f980d89038308a3ef37cce8463bd + ] + ], + [ + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x3f0815ab463f1b76ee25a9b8768b3231a89752f427f4f063ab718e707576b31, + 0x15648bf46f60d82954c7e33029b3617357012a3d3b1d34c8e008859f1dbfb317, + 0x127e00c2253de07818ca7f2eafdd7564d05ea850cf61f1daa0cfefbf7fbfba85, + 0x66365afd18a41ef9382fc0b1d265cb4d3ce470a8cbbb878f7d48051630747bd, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x219d14f823513140dc69a96f7fe7e086f4fa24c84e57dcf2b099715c4404aae7, + 0x3a30bfbbf2cb86d4a6a63a8050d91f9f14f4d33696d37ebaefa9ac2302132d5, + 0x2121bbcdeaa33a35b0270fb7d5c9f94edad5a84d74b06e3385104b0b41935bcc, + 0x196b544fbeb0a792cfbb82c289e579b7cd5580c2e338a389d053ef8b3d10e70e, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x2809c3a1547c0cee89c1db270ef479c26973ec73edb4bd4e7d907ea0202f560f, + 0x11c34446b083ef92ca157585a02b8b342a4c67175b31f4b5d40d4e96dfc5c8f1, + 0x253ea0b33a8bf3b2367c030e3289cbe0f6242ad7709d90b86d9d8026e2e39925, + 0x30467dc1930f6afe90c89d4007ad29fc4f5a19c006d1030438c16df85637bd5f, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x2f9d4b55495f7e377e20e6f5a3a88af7aa6a536458b38bbe13c8ebfbbba54f44, + 0x1d9e9d5c736e3151f11d36d499e7e093d8ee2353be18aad54cfd03ff0feac4b8, + 0x124b617b43e598f9ebf622f7823a3de7d1bfedb87e097c315f343de301e54841, + 0x198e7cfc66ae45774055cf073bedc945a5f9c5b19cae08d789cc5748ffe199b2, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x2eac25b3498dfadffd124ab3aad57789eb945ba57443099c5bb6c27ed977fe24, + 0x1ee02c175cdfe1871b378305c1bb9c904e8af1d4454ed3550b3c6ab5f4f90126, + 0x616f8c34c607266b29ea8f9d2dfa47ff6fbb1d9745c48609fa98301d0f679d5, + 0x181d68b0a188504958b9f19cbbdb972a853e51ed385e4883a43a42832803370b, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x2d5397ce863464a25d6b7f5b015d579181d1ce2f24cbabf6059e9327f5ba7004, + 0x15bf817491b94d71e8912940cc0b80277713e7d32da2b6591724d8dbd4bc2618, + 0x2a7cbd11460b177ab76feab28b69485ac8cc687740bc910994a3827d29c08714, + 0xf7cd5ffa4661730ab56e447fae5cc1763cb462da80a85614c237b290de9d502, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0xe0766004b4c4176eb13273508eb6575f768137d86d305be644ce04531008100, + 0x625fa7145813481f6d148be6b9c8bb7b54ee3c1afac00104e1f763000b9924c, + 0x7c5472508b459916ee0f5461aad2e0b19cd9c7b184f515b65136318ce2c6a5, + 0x567375470d189b693ac77ab3fb7557231d53073951d43c54685879cb7a89fcb, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x1d0406bcbec83f8d5165f56c063e42108ad21f51ea4bfc71601174ba5c7b8bcc, + 0xc02b18eef22332d280a8aa1f86405f3375f06342f8696ee7c73b46c63272cb7, + 0x17c1fc174cd9a6ebeaa7add2f801a664823509ad4fd1b15aad053a55ad6da4cf, + 0x5f843c23024eb1dab7ebbc86709a021aaa6caf433f7ed258a08638e9584b32d, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x22df2420697ca28b5cc51c53165e002727b45ccd90a55c87589f792f0ad8cb37, + 0x2f1438303a7b49d473400aaedf0f48009fd3af804b76be86417588efc4d7302a, + 0x2323d5fcf2da8965c6b2b7b4fbf9a24bbaa7f4dccd35d5ca6155c5463093b23b, + 0x26c85b9dfbbe48fe83b753a5e7336b9f40f7b961e9c54f94e37700073d4d26e, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x31511000251ec86feb38b5ab4e335f070b271df4c20979528e41d65384c318f, + 0x18e588324a9bbaacb42fa69e5d90a0c0e27cd16b941e34a60ff5df9a26c03af1, + 0x2642b5d8e16b953b070635775c8d3c9498357d6ad9bef2e7d99f03c10ea1f95f, + 0x21fc313ba11c60e8e84ff60db906a0f031189b0b48335c4221f909aef836c133, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x2d3562e3d4b42bc6890b698cc6ab89f7311298bcbac6e4e9f2f4d93d06dae151, + 0xa74ef541d360e842e3e0b6ff7e5c7c77934a5f67616f01c189d886dfd2e0808, + 0x140564b53e0a812ac3983d6e3b433afa43f434087d9e754967c2c9b1b02caf8a, + 0x14709e32d98ae4cd18b400181e71ab9759c436c8e83fa6993adb6f2db6bba9d0, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x734b2366c59e394423f179e1266dd392372db4f2dba651f4a619a4b52bdc010, + 0x11fb2d705c94b08d5ad3e3c5fb6629abe963ed92913642c7d02d7e71088fd2d4, + 0x27d03abf5c1f290e5d715eba19371050ef6eb7f78fd84be834e4cc3618059484, + 0x13ed9e9e6b452df27fb3353cfc2cd63ebe817f212a39c6a8bb9b441ac1395861, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x1319c51cf37aaa10246cdaaa04a12e88795de4452604263a7c5b79ab99cbd23c, + 0xbca25588d187b7f9dad839f2c8cb526a4cf444eebbd0e715b6cea019ac3f2, + 0x1d837ea0341c5964181226874b923cd01a069b493f02f7a3c01be23cf51d593f, + 0x1b41ce9ed3634cbd42c427ce4c5c83774149e2a6dbd25f24012090db7de4e7f9, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x671f0e3b674ae7cddc790ecc4e946f4bca74b98b78a127c7b56bd6673f1ce1f, + 0x19fc073797a39b272e40cd30615f55fefeb682c1ac14143071d0449a5426e4e, + 0x17bee47d262a497fd1f7c5c6d5a7c70fa4209480bf5d97311c5096619e9fd13, + 0x2073cff92d3141b480763539cff2978a4c7944721cc937ba00cc8527274471e3, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x3bd7b3e2c1885877f43182a55a91d48f9c58d152e730fe2c7aa46b1fa663baa, + 0x226ebc9a538b5bbaff128edfb9bbf5fa0ceb100719a14c8dfed9ffbbbad9b6b7, + 0xd395f0b08b9fede0373a06e1552c0e634a49572af1d830dc6e394e8a5d3b21a, + 0x28242439b524540a30d49b68e19e31ba5284bd3bcf1e0f2f41f77d5331f99ffa, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x370d6fa19eaac142d2de034801ab85e0b457e129e91f929754b48c6154d4df6, + 0x9a16f573b3280f390762abf269579eaa37939bc0c753feb0a2b2e0bcbde1659, + 0x2228e360fb5b162b496ac443f98127ee3c0021a690b71b268d99981368231d97, + 0x7e42c2ca633d2c49fabf83991476d209431e34d8032b6a1b97675f3c567f944, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x2ce12d7269663770c3cab85a6215a32eed35fda1d8e9d753a50fe96097724a9f, + 0x3d7427704c61e2009eeb9b1b45a0125084bc4daf70973a7ba0b2231815b15de, + 0x10f8abf0764185861c1267fcf4b4b33ca096fb4ddc4626732d86921e553e69c6, + 0x17ccaf6f26f7267a025d7cb456e3aeb251a1a620aaf6568a5c95644c7c5914cc, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x63bb306b96310051385c3ce00ca820ad0e3651a6e55754d59de6df28cea4d51, + 0x1f761ee5553c5e86f2c304a18095ab7403242e0b65e608bc920cf993a4169974, + 0xdc5f00bbfd7c1d9a23c0e666859ba6564bcde8761b45717cd6bdfc09de4e8f2, + 0x6de511520e277b7df07c3536381c13eb44cf790a230abc391089760bfc40ef2, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x2a134348c8660efcf9ef54863e70528a1fd4481b50a1fe21f24a8c06e10cca03, + 0xaeb5023bbb9a64c4bd80089e99edf8ed5f6f1ffb63a7dbba1b33520bcfce37b, + 0x141a6d0810366ae225ecb5f0bfdc9995406c5960ab26155836fc51fb7cb933d1, + 0x9d2ea05ef54dadbbe776f404dca6626cc0b2539990bc0b8bfe87497f1e2c5b7, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x1e56d244a8e41be5d104d5f8ef70891d22d4a5432441bfe8ff1a16e91719cdde, + 0x1d4f020c57c4f14aec908b2f99b5c4fd5e09447fa85c2fd68ba4d5c5f50c7b49, + 0x763911a3a92a4f0e09f4e14cd03398d8d82a1e09db80fb0ee1e833764c18fd3, + 0x12857275be2fe6b9ba2ec68f9061643f1fc5d9a2c5e47e55684366e54b302946, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x2ed11ccd2e2e2376655ffe9a96c4b81adc0a60353c5d83d4d0ebf50d1bbf87c0, + 0x3e31de8958e82645b320d5e3e966ef4726d5b1c2cfbb4acd288a21543c6d594, + 0x11e880dfefdbd08858ae890046533d58da28a608d7e905366ec2ca4a36e71963, + 0x1835b275deaed2d00704a9c3cc21ab7a44a34662978d53c190dc25e969a507b2, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x68b75315e25ed4ace5a4a9480e1d82ce5d44f76f1324240419f372ff8d3c3f5, + 0x1b7ef7d04aec73d62b052d2ad12b92a4268fccd795c839d698ad3b22823274d1, + 0x28c0c848022a90606f6193ff5501b57216b670727f4b8efcc240d30bbaa9f03f, + 0x13bda49296cbcc51686a7bfb1c39f3f254370985a16660efd6e5d82d4f068e1b, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x2e7987ea8204389d11eb10b34265e378a945729f86c3e0e2fd38490d3a594141, + 0x826d4a2324ad3aa4b2b45c10a190fedef702aeffda3226ce5415fffd03935c8, + 0x2dbeee85eaeaa9fa3675ef541c9df7bb964a85435c3b59685f93b434036ded, + 0x227ee7a945edaee6919418ecb3279b11e6fa44f5f5c5abfb966a4be599cb86c7, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x1d0a6d1a9519877805ac90d696faf2a5ffadc23986de8c698d541471c7244220, + 0x2208aaba508ae816da4f333b7854fbbcd10eea1db284ec3e9f4de02b25f6e9d4, + 0x28a58901035b2c99e36a7d29b587a215c9e59268e2f8e01a175720971ccf04ec, + 0x112f6d8d42b0a0d123a07865ca1376df317a2a14ffc0191226f38a8adfd6238, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x8c6eb19c016d1833174dda182d266d5c727f97fb4d01f1daf906b6d3c6e2308, + 0x1359d2d6c8b5a116d0b38b95f9c642df75b1be9a48c8698ecfea9103f73f1879, + 0x10c5052ec67ab9b6a467c1cc1878d91aaa07aacf7725f8a5ed42b699c4af3ca7, + 0x583c4d292d54f3cdb708803e6338fc6afdb188d5d4e9f060193823684c96c75, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x2d94a1c55be382151a4054c5b96322e7bcd1fe2b3e076e16ee2c18bfc06f57b4, + 0x15e3402fdde8770fb997369579c1b1703ef77c671927ead80dbc64dd2211c3ec, + 0x185be98784817f22f7b21e6b867d5a71b5000bef8bb902eb302677e20a727be3, + 0x18db4321c721c03666ed8927c89890aa8aad1b00c054547b5ca14cd94de467b6, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x2a852b6247f5d61f0c390b3f3d799188528849bcd2cd0aff4eb2134a039b5126, + 0x2510aeed51b7f506e65fb9a18ee0124aa5276f6de1cd771b165930204da58f22, + 0xf2074a32eb8260fb5bd3a236f03a47b47b7fb54dcad1d7977d6486513bab5f2, + 0x2f4c69297866bd45a8270e19941926cec3531c9e12c4c2c84971404bfa044090, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x154668727d2dbadf05d083a65093c0d0e92df5fd5f3fd75e9b792c562a37473f, + 0x1e6ffc5d6a1ff5dc4fd77fc5ab5c8c4e8d3e2e375bcd1194a91e5b0f7b13cadf, + 0x2cf1a1d7c44309109d75acbc9395cb8398c8b2d428538571fafa389da29990c6, + 0x140fb39a89f26f6d87cf76cd5ce8da47aa5d8a023e24cf016ecf64cf793c9880, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x1289d13d58a17b5bf0712b201fb3cddfce2c16dac159990b8298a93a8589f9e8, + 0xf45cf974d2c9edb5781e8d3d207adc8370cf56bc5218749610920fe98b2db2e, + 0x11909c81a16518046b79edfd24f5abcc585a81d1b333568b8687a1c9eceb44d4, + 0x2990b23c81882f7709f3b891a0e3da4d6917672f2d5a1041fd7bbd6792330d16, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x609551b14716ca3cd5560e0821e7285e0a083ea9a16dc102ecf461e4aef7277, + 0xc8c1abdfab99d03fd93dced2467354b6175de1755f4f93dc0880eaa08d03f77, + 0x138bd098c4923b9fbd02f33f8bec6c730db3fed298ec09f78a7a55d08f2e0b10, + 0x2e61e4bc021630114673f0f77161ae55dcd0b45ce07d9ae3f21bb5a3190f14c0, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x124860913e3df8f65a9c4060ce3297c626abd1c22401c905ddb408260d8e910, + 0x13807f89c394a133ec104804d955cbe125f24c5701d98286c6ac8b7ed052ec8, + 0x2e88d1a6938f0788132aa9eeaec08d2f59aa444050c8f4c4e85578abb0fc2fe5, + 0x1f3d24f17cfc6050a0cbf64e1f1787e2257be3c3ba607c2e8fcc1f26abf3104, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x1fe1cb0e2ae169f83b9d4f133d41fb5b3fe6c76a82a916bfd9b62f82f0f8d0bf, + 0xef79351229409cd353329221229827e19946f3d8d1c48bf5e3377f9177071f3, + 0x18fb2e46fc1b90fe1c4893ef77a9d111507551883127860e89088608373beda9, + 0x77afe2579f42ec14c32ef0761e23a3cc0ad6263a68c5cb61916bd57120d1868, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x79769092daa5a752642c04ccf8a6ea54e2ac9836fdd65d248b186f1490b7b99, + 0x1d8bf229c19968f0254eb6e09c5c8bfd67eb9734606b676b663c76cf76bab4a5, + 0x2a33b7d855e7fe55f93556e49e4b37737664f14236f17256428f29f6ec1bddad, + 0x25b0331d7e2b15af4ec161c86e84ba6ab2056077e7aa7536340dc3187ccca8b2, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x762098f5fe26598ccbf45e4810211b0ffcf8ccbb92c16e2f4f13f22342474e2, + 0xe234d720d70b2886d0da4c007b1bda42362e144185c70716dece2b6172c2514, + 0x1d82bedccd2bc8a06e3742e720b7fec2ea72182f11c0c60d135c811152aa4b60, + 0x480064d4b3eb0ada5e9a3e7d05930b7c3397fd6b94d481314bd1c690a17c979, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x10a892763b3cca9ef7593fbb1140edc8c8e4580568560cf41867f7464fb0c11a, + 0xb5ec64548ea841ac921f9b2553680785978b315667ae4714dde4cd7f4de8b91, + 0x10554aca4e348e5949761bd7131dfaebd78010edd030e1a9ce3c65c9db931d46, + 0x15be66f38d86b0998b93655462b1f475b9be9de306e150d4ac648fab3db0cff6, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x176ad3600fd3491182d182957ffad01bf6c26e9d4ab0c23caaf308e427d3dbe8, + 0x2b6f355b3dbf65f09335001d705ac125e3beb20f4fc11bd3ce82b5cf0af2e6f2, + 0x1c85c06a6d5d40d81d7c89edefb32d1a8448c51288fa296b6de9ff788c77451, + 0x20e1e876c4746a0cbd9a51d76b2e25f82361c389e43f7d1f51a70aaac2460d79, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x20e46219f684186d2a024b637bc35a29ee3b08ce737701392d987dda9217fa08, + 0x2ea7279db9f2aa0f654e987907277c24480766367a8bd90e28be0f2ed6091367, + 0x136be2a7f18924c9362096d472bc75ca0969dc077c9171b1641be95091780f74, + 0x1ca2033501baa3f73067c4300fb0f51119ed5736fbc8f1f6c924baf0df5a0e9e, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0xa82f199c2505277ecaa75e495f34e3525824f7a4a9d9fa1da810832b48a50c7, + 0xecf10485307b4bae92fefb0d7f7782a9f37a2722e7ed9eb7925a2dea580b7d5, + 0x7b642138dfd6a6dd12aa22f08a8296d68615c8478f13af16aebbbb339a3936b, + 0x1d9dda43a25593ffd2256d34921fb86ed70e760ba76d61e9cbc3b6dd0f1a2150, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x2f1af228520c8b751dc91136c91c6bccd5367eb08213d392958ce2fd3d7d2fce, + 0x1fecfe833ad540455c6d6c1ab3de4abae61ada625a1a2b6b18551a45a6cde123, + 0x18fc8e608c735b2b3b0d7583460227575657ff8a77abe637bdd3ad28e4a23c88, + 0x28f740bc1182e9706ebf03cb3f53aba8a43ce0b618783a5586388a7547faa815, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x47998cc0af5a26b94ad301e4b998d29e960a4851cfd13822bed35b7146966a4, + 0x1b5f1525b31db911dda43e415e1b9a3a9725c7b52e880ee130a14a692b777b70, + 0x275a83fa5d19b4535f65e965a90eac9bf770ae9bd1d7b1af945fa57ed5c8de6e, + 0x2e8789257ed2cbcccb430568e49bc9dc2a563359808c9897ce3e40a6f6a27aa8, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x927f46cfe80feefeb2721a4c09e9d17f60c34500dcd6e41e2925a39c8e2c7c1, + 0x1f868ae04832a5dbc37619bfe6ab6a97fd8fb2cfbc1ecf9e0e484bbfe7698101, + 0x9d7a11e27d2f53109b73f745b2defed65d94ba80f308fb19ce6d56c9b45eff4, + 0x282d857cfe8da3b5104e1c2823fb7c5b9a7b25924fda5995b0c351aa2b879dff, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x20ba8a9fcec815b13f349ff830ae663b27576e135c0744f6987fb0f6ff49c217, + 0x11b6afc91e32f1ca4589fba12e657d226d57b471ddd2ab1b66a8ae4dcbfb136e, + 0x2e666402ac9cc588316e335c7d93db344788eec2c72ddf3f908141736cebc3be, + 0x17522e0e9e64f795a202a110e283faad7057aec5c9ed9a1a74920f2794f18595, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x2d2ed17f7a1f3ee9e20b470cad4cc7319e6adb40e2ff24b7878cb9878edbd3b9, + 0x1a81efb19d7e1edaa96fa276e89e85d08f75e54a8136f4d73c937da16c7bf9f4, + 0x27ff57c1ca847e57210a7b44e52e5630f299c5f451c7a0d515a16bb3bd33e237, + 0x1c1a8e22230abcd13c5be96031bfa167840d117b3c6a5a0a11be26a7f5fb1a94, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x2a1c3f15d4927c843627a9cd533e4250d81e7774d2c32b59d5836f9c19a5657, + 0x2ddbb7239eb904d81c52499b37cb4be1af0373a10ac112e185acb219899357e4, + 0xdff198393085a754e0d6faec54be81d8edf8bc25edadab48a86fad6da0afb60, + 0x10d50c2473146bbc76275fcc589d038dec8db28728789f28b6d5f504bd1645ca, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x61e8328fb5593f92a53dfd40e1022e6231ba45948506282536b08b4476c1538, + 0x1b589243847198ded90b644bee31ac58067debf3f07d3c51cfa5a0dd9f6d9784, + 0x4b00c0da1f851e59863b053bd4c6087190f0bdcced99d5ce6f67a420a3bd1f7, + 0x239941a46c2b93d9126a70163009a7ac27f8a8d42e35018b3bec8cdcb5ddfd67, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x204f26ca7993b03ac2c35377cb0a3712bfc9bc3ec0bfecb4e87ef6814acf2ea2, + 0x85aff9c7fdadba039d832d8be165a1e5747cf7308d515e348ef117e926d721c, + 0x249042a8dc111f27c4ae9db044c0b0b3f10e57d05e093158efd375df00ea2068, + 0x6e799bcdf2b4a74542854f3029803e2f84550665203327b3e0825977413e96b, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x1cb3caed4bffb6aca9f4d2c002921bc3fffed333cae12085c612496183b87996, + 0xb47e9755fae480128a128bfd4faa6a3dd6ea03cab566889dcd99e84d310d51c, + 0xc7e4cea365c2061920a0c9fd2c360a6506293bc024fd1ca3f0bb730da886a4f, + 0x21da1f701bac77bcbbaa30d964d6f6f63dbe1b20d9d6988c8dcd7ba4187215df, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x9ae612e8ba1ca1370905fb67899d10db86b47bd19965b6edd1a9486e3c6cc55, + 0x262e1e0b56cac47fc150f284491190e6aab75445b0c99373fe1f7a0e3b95cf3d, + 0x234bf4a7dce7587c2c87c293e3bb7c9e2a7bfa5f29fd4ddeaa5d3f67491d34bd, + 0x2f6cbac694c886b02d0a527cac744fb658d2690e213d7432eee67f6cb69f70c2, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x22accb18b7c49b4b7bb8c9fdf78b7aded52aa1842fff818d9a3300876dec3ad9, + 0x81e2f0652f898c6d659f22d2c77be302eabd9182a0b3d3cbf623a1df7f8f2fc, + 0x12c0a25e70d006eccea3ada75d669b8c534b962890f3ffc016b3186ad675b935, + 0x10ef9c23848128cc2fd6fc869df24d7ab56efd349edd56f49f8d4f2381df3259, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x2161cd280772819dd4a81262b71df1bcc2c1d41b9491e0620bda347962b240f0, + 0x2cebb0ae5108318eb406590041b5248292533364f799bc41b7f4fdd12cb8d38a, + 0x2b2092f86b5979a7fe4f7c22d9561f3bf2852283a656880fb759e08709a0a62f, + 0x1566b3402d774b8c08146188425a442450cfc900cf643e7382b2d8507a065fed, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x11a316aa31607f268fb4c56d6c57ba01627c3635fccf8d3d1a163e601d1a0173, + 0xde7ee069c934256b782648b560e595408a5e8434644609152e353d9c2874e44, + 0x2d36f4029245704cc84df0297708c5e5845c36ae706c72e67128b8949eab1af, + 0x1b8cc326b5ee160f53198c217fb34e899bde46cd82dabdc284d7951d546f858, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x27625da0f73ea07110689fb2187b71694cbf9203fd4ddf8a96ece85407550ebb, + 0x1cd8338a3e5b1ad7cdc0da581a6950f6dea349c3edda06cb99ba025b94e4790d, + 0x5ea02d65b209f6da763856c94b6438c78a8aed8d3e67e877a10a84072741a56, + 0x9f7cb68d4e388f85366cfcf284a895d8b6250ced627e810817743ce03330a55, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x18c6230ddc0f896827b043f5e58dbd1aec13995a202e4ebcdfeb969e9d5c1212, + 0x73a6114b997285e1a91c0a0fdccdaa8452e4f07bfd2e1a10578232096db6dcd, + 0x2e78746340b2a6d222c6a1fc0838adf5fe013f39b1660ce7a3e7742b2f37be7f, + 0x7aa27e7150baddd06303ad8e5e4bf4249b7ea846553def28e675259d3e5c851, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0xb66fdec210ea4eabf623d2712cf4d9fa90273ccb4643f680cbc98345715ead8, + 0x2fb6a29d9f394a589b633b8a4d6be51c9c0601ce0b140be641acea41c49aa5e3, + 0x29025cc66fd041c4fc845e9c1c2cd1288569fb243d049bd675a69dc889b2ce2a, + 0x150963f0aca9bcbe4126214ab9c627a6f7ed731cfa695168b85d534b17be3f48, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0xed59780302257663f72c1bfc6656eb7b5bca2e47bec0d5798a08a32a61a8a65, + 0x7e19cb8a893369b3d30ae188c767f391c11888a3000debfc8d30c06143cc084, + 0x600c7d2b6946345e5f1eeeafb5eb8ec2b6ecfe528d2c052cd860afb4a3aa272, + 0x596083b6c972bc13022a1f33d6523b4773f2cd0a480e19ea0125119f0385705, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0x210b5c36f27a07d97f98b9d8663d85db2e64513099a8e1ef6db21043631e24c4, + 0x13bb2764bf1475cfc7bb9f3d563c5cc201c2489874e9159326a8f4930b7883f9, + 0x202cf557d625c26080eb082862a76757287872b181e89997219e4b7576e24d30, + 0xe561c3f8bd4f76e76d49e97142d220601fbc5a03d905a4728ea1f95fd8824b2, + 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, + 0xde20097480e7555471785de07bd9809d57dd859bbe827307c33ae9ed7890597, + 0x72f2a6287fb984bb810df8c5788eebcfd2825613cb72bb80cde8edd76d2e97d, + 0x2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771, + 0x143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7 + ] + ) } + // noir-fmt:ignore -pub fn x5_4_config() -> PoseidonConfig<256, 16> { +pub fn x5_4_config() -> PoseidonConfig<4, 88, 392> { config( 4, 8, 56, alpha(), - [11633431549750490989983886834189948010834808234699737327785600195936805266405,17353750182810071758476407404624088842693631054828301270920107619055744005334,11575173631114898451293296430061690731976535592475236587664058405912382527658,9724643380371653925020965751082872123058642683375812487991079305063678725624,20936725237749945635418633443468987188819556232926135747685274666391889856770,6427758822462294912934022562310355233516927282963039741999349770315205779230,16782979953202249973699352594809882974187694538612412531558950864304931387798,8979171037234948998646722737761679613767384188475887657669871981433930833742,5428827536651017352121626533783677797977876323745420084354839999137145767736,507241738797493565802569310165979445570507129759637903167193063764556368390,6711578168107599474498163409443059675558516582274824463959700553865920673097,2197359304646916921018958991647650011119043556688567376178243393652789311643,4634703622846121403803831560584049007806112989824652272428991253572845447400,17008376818199175111793852447685303011746023680921106348278379453039148937791,18430784755956196942937899353653692286521408688385681805132578732731487278753,4573768376486344895797915946239137669624900197544620153250805961657870918727,5624865188680173294191042415227598609140934495743721047183803859030618890703,8228252753786907198149068514193371173033070694924002912950645971088002709521,17586714789554691446538331362711502394998837215506284064347036653995353304693,12985198716830497423350597750558817467658937953000235442251074063454897365701,13480076116139680784838493959937969792577589073830107110893279354229821035984,480609231761423388761863647137314056373740727639536352979673303078459561332,19503345496799249258956440299354839375920540225688429628121751361906635419276,16837818502122887883669221005435922946567532037624537243846974433811447595173,5492108497278641078569490709794391352213168666744080628008171695469579703581,11365311159988448419785032079155356000691294261495515880484003277443744617083,13876891705632851072613751905778242936713392247975808888614530203269491723653,10660388389107698747692475159023710744797290186015856503629656779989214850043,18876318870401623474401728758498150977988613254023317877612912724282285739292,15543349138237018307536452195922365893694804703361435879256942490123776892424,2839988449157209999638903652853828318645773519300826410959678570041742458201,7566039810305694135184226097163626060317478635973510706368412858136696413063,6344830340705033582410486810600848473125256338903726340728639711688240744220,12475357769019880256619207099578191648078162511547701737481203260317463892731,13337401254840718303633782478677852514218549070508887338718446132574012311307,21161869193849404954234950798647336336709035097706159414187214758702055364571,20671052961616073313397254362345395594858011165315285344464242404604146448678,2772189387845778213446441819361180378678387127454165972767013098872140927416,3339032002224218054945450150550795352855387702520990006196627537441898997147,14919705931281848425960108279746818433850049439186607267862213649460469542157,17056699976793486403099510941807022658662936611123286147276760381688934087770,16144580075268719403964467603213740327573316872987042261854346306108421013323,15582343953927413680541644067712456296539774919658221087452235772880573393376,17528510080741946423534916423363640132610906812668323263058626230135522155749,3190600034239022251529646836642735752388641846393941612827022280601486805721,8463814172152682468446984305780323150741498069701538916468821815030498611418,16533435971270903741871235576178437313873873358463959658178441562520661055273,11845696835505436397913764735273748291716405946246049903478361223369666046634,18391057370973634202531308463652130631065370546571735004701144829951670507215,262537877325812689820791215463881982531707709719292538608229687240243203710,2187234489894387585309965540987639130975753519805550941279098789852422770021,19189656350920455659006418422409390013967064310525314160026356916172976152967,15839474183930359560478122372067744245080413846070743460407578046890458719219,1805019124769763805045852541831585930225376844141668951787801647576910524592,323592203814803486950280155834638828455175703393817797003361354810251742052,9780393509796825017346015868945480913627956475147371732521398519483580624282,14009429785059642386335012561867511048847749030947687313594053997432177705759,13749550162460745037234826077137388777330401847577727796245150843898019635981,19497187499283431845443758879472819384797584633472792651343926414232528405311,3708428802547661961864524194762556064568867603968214870300574294082023305587,1339414413482882567499652761996854155383863472782829777976929310155400981782,6396261245879814100794661157306877072718690153118140891315137894471052482309,2069661495404347929962833138824526893650803079024564477269192079629046031674,15793521554502133342917616035884588152451122589545915605459159078589855944361,17053424498357819626596285492499512504457128907932827007302385782133229252374,13658536470391360399708067455536748955260723760813498481671323619545320978896,21546095668130239633971575351786704948662094117932406102037724221634677838565,21411726238386979516934941789127061362496195649331822900487557574597304399109,1944776378988765673004063363506638781964264107780425928778257145151172817981,15590719714223718537172639598316570285163081746016049278954513732528516468773,1351266421179051765004709939353170430290500926943038391678843253157009556309,6772476224477167317130064764757502335545080109882028900432703947986275397548,10670120969725161535937685539136065944959698664551200616467222887025111751992,4731853626374224678749618809759140702342195350742653173378450474772131006181,14473527495914528513885847341981310373531349450901830749157165104135412062812,16937191362061486658876740597821783333355021670608822932942683228741190786143,5656559696428674390125424316117443507583679061659043998559560535270557939546,8897648276515725841133578021896617755369443750194849587616503841335248902806,14938684446722672719637788054570691068799510611164812175626676768545923371470,15284149043690546115252102390417391226617211133644099356880071475803043461465,2623479025068612775740107497276979457946709347831661908218182874823658838107,6809791961761836061129379546794905411734858375517368211894790874813684813988,2417620338751920563196799065781703780495622795713803712576790485412779971775,4445143310792944321746901285176579692343442786777464604312772017806735512661,1429019233589939118995503267516676481141938536269008901607126781291273208629,19874283200702583165110559932895904979843482162236139561356679724680604144459,13426632171723830006915194799390005513190035492503509233177687891041405113055,10582332261829184460912611488470654685922576576939233092337240630493625631748,21233753931561918964692715735079738969202507286592442257083521969358109931739,15570526832729960536088203016939646235070527502823725736220985057263010426410,9379993197409194016084018867205217180276068758980710078281820842068357746159,20771047769547788232530761122022227554484215799917531852224053856574439035591,20468066117407230615347036860121267564735050776924839007390915936603720868039,5488458379783632930817704196671117722181776789793038046303454621235628350505,1394272944960494549436156060041871735938329188644910029274839018389507786995,5147716541319265558364686380685869814344975511061045836883803841066664401308,14583556014436264794011679557180458872925270147116325433110111823036572987256,11881598145635709076820802010238799308467020773223027240974808290357539410246,1566675577370566803714158020143436746360531503329117352692311127363508063658,212097210828847555076368799807292486212366234848453077606919035866276438405,7447795983723838393344606913699113402588250391491430720006009618589586043349,7626475329478847982857743246276194948757851985510858890691733676098590062312,148936322117705719734052984176402258788283488576388928671173547788498414614,15456385653678559339152734484033356164266089951521103188900320352052358038156,18207029603568083031075933940507782729612798852390383193518574746240484434885,2783356767974552799246444090988849933848968900471538294757665724820698962027,2721136724873145834448711197875719736776242904173494370334510875996324906822,2101139679159828164567502977338446902934095964116292264803779234163802308621,8995221857405946029753863203034191016106353727035116779995228902499254557482,502050382895618998241481591846956281507455925731652006822624065608151015665,4998642074447347292230083981705092465562944918178587362047610976950173759150,9349925422548495396957991080641322437286312278286826683803695584372829655908,11780347248050333407713097022607360765169543706092266937432199545936788840710,17875657248128792902343900636176628524337469245418171053476833541334867949063,10366707960411170224546487410133378396211437543372531210718212258701730218585,16918708725327525329474486073529093971911689155838787615544405646587858805834,18845394288827839099791436411179859406694814287249240544635770075956540806104,9838806160073701591447223014625214979004281138811495046618998465898136914308,10285680425916086863571101560978592912547567902925573205991454216988033815759,1292119286233210185026381033809498665433650491423040630240164455269575958565,2665524343601461489082054230426835550060387413710679950970616347092017688857,13502286133892103192305476866434484921895765252706158317341618311553476426306,686854655578191041672292972738875170071982317195092845673566320025160026512,9315942923163981372372434957632152754092082859001311184186702151150554806508,17166793131238158480636170455452575971861309825745828685724097210995239015581,4443784618760852757287735236046535266034706880634443644576653970979377878608,21470445782021672615018345703580059646973568891521510437236903770708690160080,6932852445473908850835611723958058203645654625170962537129706393570586565567,17078326120157725640173982185667969009350208542843294226397809921509565607842,19251873001736801921864956728611772738233338338726553113352118847732921831266,13062907978694932362695258750558734366820802962383346229947907261606619788585,16576609187793673559170206379939616900133457644695219057683704871664434872406,17140499059660867342372156843620845644831519603574612796639429147195776838516,16226688173010504218547945848523900236290532501559570164276462499487632388445,2806068123803905806401128967330263340459046260107112845068533446899070326517,17788735370835052317224182711467216134690146479710634688273650370951230404901,9840665370904113434661468973557421114403401847108482949465899631150766783733,17357287363046228581837055771327121704742940914150998420465281177406182088510,8956082469997974864521346025916496675956939495318858500685756691488425559998,10583741436561099911914917245130852199607666337956354910388730829023746895549,15241902639811607164983030447109332729761435946009172128089506810551693978973,10889882303914055687481932975789161945462141459528413507160087442461090813788,19789561133254944544821898921133697408237804586549835559829396563401674817160,20741336668287037026472434608739333171202674306575625457456116338034432647230,17864073449995977742930566850933082711031717858550870842712972350665650521079,6017691253505466300212182439349954426085752315661098358839308909771637792741,5209125836207196173669497054522582922896061838702136844305036341250990710540,8138726312837322624537330169363664364899441867118983214176695868443641051381,15491983986041746833254372934846748393213690608865689646440909282144232382678,5054332867608171303802774230688792431028169804536607979111644888500809938980,15427030776591294577308915282298854681562344215287630895931797573417982096417,21754057982677295571284116502193272661309010996970316384923307174180521790164,16265286590463120486705206231835953324076688991892805307349612983237844034032,17679791107777049796013011282788633179411040182820636236163074053597517790779,4281652562868629887097957174897458165728741859103571825874408386197225591996,9168010397863299719604788533602757515513214141450093775967322808686129400625,17584182367226175071087689123358883902969885218985589531538416263709138156515,15671512310414658663135385639435845966109237059155734764323312289873534719186,10536294659491685326297777845632759824567028904726211134518740400643540109527,13431319759608247201135260841651365578663315527795431484765940626659812285319,9584697124715190200241839387725546204368618031045071660911490086723434692561,5180327104839158483066851400960171505063442195966219343315555549982472660055,18888217223053385111625483360538133292128748730565502371803782424772027937822,19535732913737027522540340630296365525208404217634392013266346283017745945894,8577759627886344995887423695190093296190181539234301534326157005220006624466,16793670928407147476673650839110019799844249677846432113010280456483595763987,13926032620965299897272071104154310460519723329016284975305942957859374938463,4794697578055472890255676575927616606591024075768967985031137397587590174501,3529566190782060578446859853852791941913086545101307988176595267965876143250,3975008029239568933166738482470827494289192118694622729549964538823092192163,17739094873244464728483944474780943281491793683051033330476367597242349886622,7367136451127531266518046223598095299278392589059366687082785080179161005418,11175297939460631138047404082172242706491354303440776362693987984031241399771,21687543815463985355165197827968086406938428974327951792877419032069230058777,21156136641989461785420005321350884477682466566148802533375726181416623358719,17347558768803521970212188258074365309929638984714303299899732035040892048478,16293716234695956076322008955071091921491953458541407305955104663269677475740,4206144021605871396668976569508168522675546062304959729829228403361714668567,19988050626299122864942213847548542155670073758974734015174045163059179151544,747972634423324369570795147739377097591383105262743308036321386836856106229,4612470951309047869982067912468200581649949743307592869671537990797895413707,9630852913694079049153027193127278569487291430069466630362958024525616303220,17941539917430916523930519432495442476511211427972760202450248798031711471474,20332911350443969653703295317915788278109458962706923653715140186132935894113,21764801803055897327474057344100833670291402543384934706514147201527191846513,18792043166429470991157980448329308661526906138700725174612608941551872082876,12308177224490762720061048892842527800271687977085172836705858261595655154325,6234555076867437297776538521925679658360922070165740193866337972293380196151,4651047048822067434403056477377459986292934655827821636179452835839127581305,4762047093602693619418269784972874862577325737690375448572644958129932507374,12373514879531674477721132062882065826558811149582829246378921774344318418269,452512704634345955634014968317367844987135264395068376894497483188243356523,21642936370936057063268550589361090955573362743817395689260298777690935495218,16170209200627740434842090607802586195654207376087117044989637541681675086276,11682826760471401430136435257946377996085824742031456481961511737883954750045,20628055165039718158878805520495324869838279647796500565701893698896698211929,16438375313036818694140277721632185529697783132872683043559674569424388375143,4855690425141732729622202649174026736476144238882856677953515240716341676853,11680269552161854836013784579325442981497075865007420427279871128110023581360,7052688838948398479718163301866620773458411881591190572311273079833122884040,10339199500986679207942447430230758709198802637648680544816596214595887890122,16310974164366557619327768780809157500356605306298690718711623172209302167675,4572051236178600578566286373491186377601851723137133424312445102215267283375,20933392620931420860078756859763708025350478446661033451436796955762857910093,10145870387395991071594748880090507240612313913083518483680901820696866812598,11173854866888110108878560284050142518686158431744851782991510385755602063727,3895357290105797542988795070918100785105415165483657264407967118738833241858,16358886674154007883356717944805100413481233709808000948036974385803613296849,10544067501284177518983466437755150442726536257903869254459488412549270232123,10495171258604974589451578238018388630585794890815982293891430761424812600427,13820724103604550843562070971473423552484851063169471886037640613650155173554,2334954333435579600152488915208745055087482119087065911968347050969338669409,15100284614446277058846085121308897497066957549089629374506920751044105723791,8493821960754696376711287628276980042183127459347650448500304251148421115590,18612435536889941393944858783110719304584209891406420832295898519317994950798,362101794940079733974215941991047456600874474038781578925062694203564740952,11020033081956343850903875701444955317664141075326494650405276926536449284939,9396289482656518627529185765935649373549564165735162258912975312413185691167,6879055176150676925438486069371149089824290576271090206945130252868108043422,12466610601804566637227883322591924115458766539177061670432424956205788935144,6570302110526154075173287644133038486970998888099669190857256824048085590052,20997862990590350605775941983360263378441519274215787225587679916056749626824,2642485040919927233352421501444361753154137311893617974318977215281720542724,18832940311494549247524002614969382413324906834787422940144532352384742506504,18751288968473015103659806087408412890105261892140397690496125593160830694164,13938622158186434739533995447553824444480420613323252752005511269934155122652,12878982657080117316101160964182202074759312554860119090514406868768962707099,13757859113119127982418426758782225628393556023865807897214601826218702003247,11817871682869491875135867072669251115204978941736982465520516648114811792373,11336448548896065624515261709306933490181794458266726453198857687608284871020,194970717714150352477887371297168267861902418496792228400198694925721020795,4999282817977533227652305360183045040853565298259070645110453061034932285549,17094174197873140035316532568922652294881600587639905417701074492648767414173,8484251464872873032022789624790167173458682056313339863651348894878144808746,10260366716129057466862964875306868898686918428814373470382979997177852668590,549263552864476084904464374701167884060947403076520259964592729731619317724,10052714818439832487575851829190658679562445501271745818931448693381812170889,1735373362835209096342827192021124337509188507323448903608623506589963950966,7998373949540733111485892137806629484517602009122941425332571732658301689428,9035170288660659483243066011612158174896974797912618405030929911180945246244,6458619567307414386633203375143968061892762498463026121155477954682976784731,12314261817227551876673777186352972884847144237148169773300066404053441924532,19869454329688183813243851218196625862680921049019496233616575272637276975230,20326917073492686652690019138603910654692396590122884746951129061818467704300,20403270805536666081472738304916561119325397964511536801752236086414818653063,2865941730880218719188224311916978807415673142487507504983320505748719154068,20614246027521726470902405957496110178017768563127335842405314212897493119848,12060194341463088508348622863463208827312128863463014006529428845777217660299,1128906798719793375274166820235650701301189774851381709919492584451845983197,19670876372911656158743764425809421400123168087389888660308456184201759209723,5647230694522866559497222129254930524469944430191328619422533907417776118543,318629082509194371490189248876734616088516535434806492900653650176451776632,13685970881538585172319228162662520285656571966985351768743970447782846353365,8283840607829148567836919316142994745766280854211662326632930274668867638198,8968895518159422029900464138741638511289476298837958524156654785428413265371,10061801991000917366002570579819627134666386452411986168205986791283562415829], - [16023668707004248971294664614290028914393192768609916554276071736843535714477,17849615858846139011678879517964683507928512741474025695659909954675835121177,1013663139540921998616312712475594638459213772728467613870351821911056489570,13211800058103802189838759488224684841774731021206389709687693993627918500545,19204974983793400699898444372535256207646557857575315905278218870961389967884,3722304780857845144568029505892077496425786544014166938942516810831732569870,11920634922168932145084219049241528148129057802067880076377897257847125830511,6085682566123812000257211683010755099394491689511511633947011263229442977967,14672613178263529785795301930884172260797190868602674472542654261498546023746,20850178060552184587113773087797340350525370429749200838012809627359404457643,7082289538076771741936674361200789891432311337766695368327626572220036527624,1787876543469562003404632310460227730887431311758627706450615128255538398187,21407770160218607278833379114951608489910182969042472165261557405353704846967,16058955581309173858487265533260133430557379878452348481750737813742488209262,593311177550138061601452020934455734040559402531605836278498327468203888086,341662423637860635938968460722645910313598807845686354625820505885069260074] + [ + 0x19b849f69450b06848da1d39bd5e4a4302bb86744edc26238b0878e269ed23e5, + 0x265ddfe127dd51bd7239347b758f0a1320eb2cc7450acc1dad47f80c8dcf34d6, + 0x199750ec472f1809e0f66a545e1e51624108ac845015c2aa3dfc36bab497d8aa, + 0x157ff3fe65ac7208110f06a5f74302b14d743ea25067f0ffd032f787c7f1cdf8, + 0x1b0f68f0726a0514a4d05b377b58aabc45945842e70183784a4ab5a32337b8f8, + 0x1228d2565787140430569d69342d374d85509dea4245db479fdef1a425e27526, + 0x17a8784ecdcdd6e550875c36a89610f7b8c1d245d52f53ff96eeb91283585e0b, + 0x9870a8b450722a2b2d5ee7ae865aaf0aa00adcfc31520a32e0ceaa250aaebaf, + 0x1e1d6aaa902574e3e4055c6b6f03a49b2bbdb7847f940ebc78c0a6d3f9372a64, + 0x2816c4fa6b085487e1eec1eefd92ee9fef40f30190ac61009103d03266550db2, + 0x17359fd88be36ba867000e83f76ffb46660634efbad15dcf4d4d502d427ff51c, + 0xe3004cb44ba455a3f16fefbd0c026404cbac203c0f236baad879610b8661022, + 0xa55f276af1ceb6ebc6c6820f334b26f11ca4af98c833bc1b496193d6b04a7ca, + 0x1ee4b0458adcd4c4861a27adc1404a5981d320b6b8e20e51d31b9b877e8346d, + 0x14315e2753e7fb94f70199f8645d78f87c194a4054e69872b3841da1b4f482f1, + 0x2b7b63ecffd55d95c660f435ad9e2e25f266cb57e17ebd1b6b0d75e88a6a56d6, + 0xbb56fa3e9fd48ab46d4e7295bbe1204b652ebe958221860f56e38db80d83c0, + 0x50653bf5dd59edd6d15fa6071f5005057218b33a8f92a58b9c2656081249f82, + 0x2c575423e24b522655c5a976c65d069287900c8d5825514098c5b13c86f1fcdc, + 0x2ff3a2ccdee91e09a32f74232b704cdd99f72c1f78557a2ce568b07e218071d7, + 0x1144734901a81c1543b8bc6fc9d365f50469eb89949491d3693dbe9c6238d90c, + 0x1eff9a954e24bcd4af20b6ab74d89e1cd38bc694a9e75ea6da217a98db80cd22, + 0x14707de7496c5638f97fe9bd7d485c20ead6bfdbfc0599791e49fad0301cd6df, + 0x13d0de341ba819f90fe3ef1f7ce0a54d8538acdd9b3ef840a91d48ee536042b8, + 0x26520ab1d20055daded712d59b07088458c18afbd0da58aee9f151a903372ba1, + 0x68cb4827ac485fc6e7537a3c0a06d08a4c2790f5c65d9866d75296999f7495f, + 0x7d6baaa2e587c21b03dfa0eb71136e2982cb389b438c8bc282748d0e674e89e, + 0x15b92d36db02cb16b831eeab2e6ed75d126ffbc274cc3362370851526de13d27, + 0x277b9ce89133de7b7918ad5fcfab7323ef5b9c1916b588cd7e5a0d814cbc3395, + 0x2ae847b66b3c5d73b70b733040aa86c51f737092d65c3492d529000fa1802b24, + 0x2fa3e8ae1fef974cded6aba6dc25cf567e16e0af29e675706643f21bf8efd651, + 0xb1d4b9508cec4d19aa53f4efe46c57952dbd368fcbcd454a8b1087bc18a2088, + 0x2d381014d01578b888b3273270babdc393ac392e7958be0478947fafa569bb0, + 0x2e79a827c85406242523a94431007021bc865a45cabcba4368c41d4486fefec8, + 0x207c99b7d594a5c61d7e60cc2365c4c0c804cd434098af6244f0a00c259b347, + 0x119c124086ea58ebb83f14f262c693424360e97e6fb42ae8596badbe9edb2dca, + 0x104ff38cca0f00173ccd0b68bddba09fc543f074f753bd8e413f8334f887a251, + 0x2f5b5377bd156f89845811eb262436638dc038b8cb10e147a87df4c0e2384253, + 0xf70e8e02d1d23968930a8e0db69b1c20204f3e3b4cecd101f81476d0b5ea996, + 0x1ac4653a51071ae722f90a03f006d8575814db782b7f19f607dae4d56ad586b3, + 0x12b12600e3bfd8e7bdfae5ef9c4f3805fa41e74acabf7de817823017a8b23db9, + 0x11b9d19908919dacb7e0f8d0ba77286d417529a18a1d89c405ed1c30289fdd28, + 0x2c350d245f4f75864744f88dbff8fe335b00f4fb688895c1363a7484ace820d3, + 0x16a7f76fd2b2147db6ef94c22c78bff782de17ef73e52da7df82603f422b461f, + 0x1d18d8024be1e96ec25626af06a139f6093545aa504033dac7e285d1cc3db3de, + 0xc8cab1ad5998072945b9b88228f53c295466819fb94d8f6a9ed449be8f7c18c, + 0x1a68d133d703cd406ca30041913ce3423c73b13384187ab1530109b756ad4f7a, + 0x24a58b9e86ce823ff4c45342941417ff23d03c80fcdef9498ca0d860855e01a9, + 0xe6315c93fbb89d38021148b6c35320fb793c41c6a4386d6aed6acfe2f952c57, + 0x2c3806d99a69ce63299e876f5f218c7295d87224795d7568d558696e34c692f8, + 0x59c893a771e94774d49a356494568dd376856ab89705dff25db8273860fa04e, + 0x1166d9819c4faae8982243d0deb1f8977027d5cc56bf52ce260bec5e27e8b0f5, + 0x12806fab3fcb09fc2b79406c3c203c4965fc7259112af2104312e1537327e0a3, + 0x172015e0e33736058f60aa33e82d3dd73dc3ead89f98ded0dba35dcc1d8bda2c, + 0x77ba18800d852d0a34f70ae8cfd68a080296bf9d47a1b40de7e6fd6392a0d30, + 0x2094ecd768bfa8f0df0d78d0d946e1aff4a2d38e029e41479d6e3c0fe79fa8b9, + 0xccebd302afe84c20ff774d3c1f650ca7cd0bca08baa1e261da9c7441a823f89, + 0x5b9303053bb40c73671f5d55b4052e0d5549871f1b5283f01485a6b568cd05, + 0x2527289084ab492275b4cd67d38311a2b816eaa68ee6bdb2389eeefd6ba4c721, + 0x2222f9738290d8d5f2a3eacdad95f12cd4e7417ed2661b012f6448c7503877f2, + 0x226c8208f26d69e6b7e02fe26557e6bd160fcbe27ee741fd1e581161c1789354, + 0x216b208c0261f3c91faf609e15f7a9d4853e40d9204496b2441115d73c2941c5, + 0xe0d660e046a259f3bad6829729b6ae3151fbcd75de33b122fe134ca3d5a4dd6, + 0x240f039d2026b3266f39ba5c4ec48ac6ace88aadaef991498cd52daaa0ffbba8, + 0x28c8cccf7b40a2c3cfd2eee0ec4d160a876a4dfeb408ffe333e92fa5e1ee4d79, + 0xd7f81b4b46d4f247c4243f045a852cc957d2b2923d28eb2fa77b5a9844efd69, + 0x2be432f87b2c5094a82c788457651dd8cdb0200ac3b42860cbf54475996b772f, + 0x13ea39f2d63d9adae187af14dd07b533d45a63435e0ea4e5e555d35e70d4016b, + 0x29e3b1afe1973be9cd1cf4b047325abfaa65cf2b98ff3aed47870461977ec921, + 0x8db7d684e6b841b5e9692498f95a1f950a1cf1eb638bb4e48f3bc1a3c571197, + 0xf4f1041a976aa05196da1c042124e3277ea1a28fb6eeeab4bec1243bd31618b, + 0x5a9d0526d6f18c86b255f00e86ec34e7f8a26c251b51c21fe4c12bdc4c0ff1d, + 0x284b0304dd6ce669bcf650c5ab85c89d4410d472aa6eb00df1b8d17e52f2f3ff, + 0x2363e9b01a0163598962ff86907002f95902e725049294ca7ab10cc7aa3f06ba, + 0x2c2db12647c4c0461dd3290a75c5f2fd8d7f115b3e040cb05dd7e3ad260d842, + 0x2e3c42f671431f9560f3d0863ac445052422d5b993e9fda6b81486b14ffe3a74, + 0x1d38441f228c0ce22ff2882560f5d7ee3b4c0caa101371cb7782ffd97af5fff1, + 0x268141b0e49c59eab1d573ead4e2e1f379364dd133f2cec574c25ade2c794287, + 0x2209cb2e187df1522810d3f28868da6cf52af9a65dbd7b806049f472d966374a, + 0xa5eb2510e6f804d1830d7974ac1677d082034e5388bfaee91a319eca7c1ffab, + 0x1cb2864c38800736f8f3ad98669d3ad7a9d5ee52138e96b8a7015e1089e36ae0, + 0x2af8ed05bfc8f8ada547ee9bc6c7c6c5e8c15c6c0d380a3f9aa277273321b54e, + 0xf85d1593b35be03f79b222885555a252bf1f0a3911d784132c49b1a96ac0f3c, + 0x29095192ec53e0b859eba456295d95bc4567d351a6dad391b8b89707855008c5, + 0x1a92efde1f5fa56aeb02b4c4b8f51ac80831f898c7843407113fbb6011177854, + 0x2a05e8deeea15e4377c080aa70fd6a86dc73f3fdfa6b55f5610614c184b0b02e, + 0x12119f3b019cc3fc46ecc80893e86f510b1dd4030b2ce28c9dadcd1e71ad4891, + 0x42b6ffe687bc23a2bf6b73317286a543c60ed122fc225aae742c3a1c2dd3a1d + ], + [ + [ + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x2a75a171563b807db525be259699ab28fe9bc7fb1f70943ff049bc970e841a0c, + 0x2070679e798782ef592a52ca9cef820d497ad2eecbaa7e42f366b3e521c4ed42, + 0x2f545e578202c9732488540e41f783b68ff0613fd79375f8ba8b3d30958e7677 + ], + [ + 0x277686494f7644bbc4a9b194e10724eb967f1dc58718e59e3cedc821b2a7ae19, + 0x83abff5e10051f078e2827d092e1ae808b4dd3e15ccc3706f38ce4157b6770e, + 0x2e18c8570d20bf5df800739a53da75d906ece318cd224ab6b3a2be979e2d7eab, + 0x23810bf82877fc19bff7eefeae3faf4bb8104c32ba4cd701596a15623d01476e + ], + [ + 0x23db68784e3f0cc0b85618826a9b3505129c16479973b0a84a4529e66b09c62, + 0x1a5ad71bbbecd8a97dc49cfdbae303ad24d5c4741eab8b7568a9ff8253a1eb6f, + 0xfa86f0f27e4d3dd7f3367ce86f684f1f2e4386d3e5b9f38fa283c6aa723b608, + 0x14fcd5eb0be6d5beeafc4944034cf321c068ef930f10be2207ed58d2a34cdd6 + ], + [ + 0x1d359d245f286c12d50d663bae733f978af08cdbd63017c57b3a75646ff382c1, + 0xd745fd00dd167fb86772133640f02ce945004a7bc2c59e8790f725c5d84f0af, + 0x3f3e6fab791f16628168e4b14dbaeb657035ee3da6b2ca83f0c2491e0b403eb, + 0xc15fc3a1d5733dd835eae0823e377f8ba4a8b627627cc2bb661c25d20fb52a + ] + ], + [ +[ +0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, +0x2b257df708d2f3d6785ff39129c7f268c13aef87ee92e9096bd6bd8d2989a74, +0x224a7cc70daf93a67ba74c0f2d80c5b0aea7ec1bb1f4e17ea21ff147c58b0a1b, +0x18ce43c42faa57788e66b11b59c98363b6970c4fbe9206a0986ac7a4438b96c9 +], +[ +0x277686494f7644bbc4a9b194e10724eb967f1dc58718e59e3cedc821b2a7ae19, +0x27907df41fa277d8c74c3725e5b8be54f4b35d3d0b6e57b26ead3cde3d431897, +0x1b7e85dfcfe013c45746d870fb2114991d43131fadbf80494c01d5b105d44a5e, +0x2c1597f81dc951f0b27440567676ac64ea1b184e65eb25292cc4da61d8bf9824 +], +[ +0x23db68784e3f0cc0b85618826a9b3505129c16479973b0a84a4529e66b09c62, +0x2460a032cf84ecd1f57096c9d21f5d48d1b21abc6d70277d7a75946997aed17, +0xc7a2ae4396db1838e5cb1ee490a768c1777efac919031924ab242d19be92806, +0x8c2147f957a152ffc37eec7b1cb029c07ecfabcc84489502a6e052aa6f94288 +], +[ +0x1d359d245f286c12d50d663bae733f978af08cdbd63017c57b3a75646ff382c1, +0x2456b3c4841aabbcc4bcb4950dae4a0f8e60cf0511decb8b67afdabeca0dc590, +0x1a2e45b92aba8f36f92110d68941ce37d39fe27d02b794d53f7b961b7ed377c5, +0x182d95b63ec720b3af3a3bc6d0a6012d4885ba5754f32aa1f1d92ba130fe5745 +] +], + [ + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x2ca7b911ea4f6a11da0bd5e72ab3cc621c5908b59ff3d76c609ea9c2fba8fa41, + 0x2de5f3a5bbe5b20d77ba6a6f8ffe2db01ff5000901b9ce0140df133385fd9506, + 0xa150cdbffe3c60c7a52cefa903bbee4d3846d24339f926c3655cdf9f81f67fb, + 0x2026ad7e03636deef47934dd0d5dd29d87056d172e993bf5e96d6a3bb32d2e9c, + 0x232507a3d48ca163c5e1b6f5bf391141524733d9cef80d404fdf78393c90151d, + 0x1b16b96e6aec89d326a5a6c18336ec3c56e7189f8c1fe74c5c46074b865a1d83, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0xfdf5d15426498ac82411ff8a7a3884894f02c5242eab1dd7fdfca1cfdabd35b, + 0x97cfa1218fe00b4edf8ce61cd20b4f8875ea5c8282d90f6f7153c9463bfbd95, + 0xfd1ebd67968d1e49926c3952aaf96d3558aa856acbfe48e5a9fdb4285ad9bda, + 0x27d5dc47f678316695d548d3b4fd1b00244a11d4cb753edd917d849cfa02fb8c, + 0x2602ddd7ea3a280860321a70aa806562a57bebfa5a0f5d2770f3a169b88ae244, + 0x2fafd30b7fac7a6699776892b07366b40fa387bc4141e009ee42070337088a89, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x1b2ac2c9f97eb32560cee0b8e8320f52866b17042d2c7c13178dbd963936517, + 0xc6db19118e83768bce24e1556ab9d383adb0f4f2b63c3f540d5b5e4deebb1f4, + 0xf94cafc14403845ea574997bf75caba6b2016ee5a10de57ae35923c9c6a2261, + 0x9145c337938ac3f71b78022c80fcdce4c1742f47dd2190c31c3cc5a41980f5d, + 0xa0ca462d8ae218e235b6f24f4c17747886524aded7e4f3a59631497a4f98863, + 0x1851288ccce2bdece3a7f68ff33b00cb961e6292f2af29c775cdf6ce3fe0777b, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x9ad33992db79124edac791c80e82876cf3a60a043edfcd7bfb5a93ee3feab08, + 0xb320d1000c50439a989886c4c11e711bd26667e61c50afba9d347cbd4b312f3, + 0x26123488a4f037ba7b2a51391f25f91642ae52bae1435dfe32c5f47ce63f68a5, + 0xd7a4403c3407d64ff5f63275add86c161183b2f1e88dab842607a8f3fcaa270, + 0x2cad68fb4be69ca135d9b37e2d3084557efa6423a9662f1fb24150b310c71727, + 0x2e122deb202b0e2c6a25e15226c09b9564cc57a8fc0d3645be77c36f8f27d4fd, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x23e090845b17c18cc12ff83ce7deb2e58cff2f37771c39cd0b68ba14f4cd65ac, + 0x8b041b40e47ef1883a30a5e631cb1e0596543f5c240701002be9d495d59a775, + 0x19d0ad6176cd87e6109b92dff1b863104182e2c85bbaac5330b2b7a4b56f9a6e, + 0x11296e1ff67a98dff758d023ea74c5fabe372a797f86a621bac4bbcdf31878bd, + 0x1b0943c04cc4c3885335624a4df555ff89e439a40e6691d5db44732aea1b36ab, + 0xc2cb45703a55a050e57ca3e51bf386b2cba4d5dadeb1749f8a6e047c5e9ac1d, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x20c061a0f70692748ab2f61b7e52e5ddd5e704e51de165eb19312700eef604a9, + 0x2aeb2df6a12c099b42c03dac1557681f03947ecd76426d6cb8a749dfb9f964f0, + 0x111fa84f899677752592a75d53083c3188d97a72d8aa1be3835b681bc6813270, + 0x1aad37ed6a2102cb892b98a7783fb019752cc8c0327190be544ad76165251f90, + 0x1be6d262a580b10956cd6163ef221f3d9b0dc3e5cbc7ab04b3f8f2a0ffe86be9, + 0x19fb44907e93686f59b9f17c0266c8139f8f4d8a5d212503bec1c6ef72409fca, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0xccbd07f12f007d8f30c6150e395dacffde4eae8fa51bf6bea1d6a7c421a586d, + 0x9a3428b0108143dc9c78633aa3bb37807bcd9603406be211bb286e42b58cb52, + 0x2a7ab6ca90a4e66f52e863c4b0f515148798ac8f92661b2b816902e915d8227c, + 0x179239cb6d96131ef12f09a58f9535b66b23c4367bcfab687e9a7c3c880a040f, + 0x7f9eff8cd62907b5d607140bd0b0944d175f17abe2b2eed814b6463ad29b8ce, + 0x2f44cd6674099eae8cee5c6f84e9b25cfd7c801e0b457278e83fe4b511458c8e, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x241d4acb53e51cee878b7d23223fd33311ff0aae81f4faa07816546eb732d8d9, + 0x13016b694f63245a8a9b2f09a84bef7c0711bb8838b3ad49e0b7838f6f644560, + 0x240a3ff47c2e7332534647a5a2fe278aff069cc479fa000d7c31a78ce2929bd1, + 0x1a510b683ed295b19be81ace3dfbf7cf1061b07a18579325f7cd001d38146c30, + 0x20c4eceba419b0575a95e295d84e71bd1a928d5ccca5d79a809059de3342c9cf, + 0xbaf9899a51723a56cda43c1aecd6c096a499b57ae1893e16a28908bc5dcff6a, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x162315c3b31a4d5b766510f46974ff89071424364fd69c9bfba1b6e0bece8eac, + 0x2f6a4f9489ad4e1439c806d757799fd6ee58ca5d0560d15a8f658c6eb86f47d6, + 0xf67999a01cf660e19180113f770041cc147a335e19f545e3f31a61bb6b4efa9, + 0x9146d7f035d379789456542d3d727b593a6fc67252a631ec407053635478fa0, + 0x2e44a6eb2efede0a5768d8491e4c86bfcd63b0ee2f383b74d62af311cf91de5a, + 0x160631bd9c54749181816c9aca5fe004260ee7a56fd35fb56977ef04911d5e71, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x26f7f151e37cde405da94d5b7e897e9768862af285902b590b636e12bb43c7af, + 0xeeffd18325f8754d15db8adf98d290ac816cab0e4315306b2418068e78dd02f, + 0x284277b5d2b0fd66df351ff703419da6b1aea5ee405bba09bd4a369e6eaea49a, + 0x13584c5168cf2fc77f884d111e05fa8512e7cffec60dd3a105503196d682ca12, + 0x1ebd55190bbbaae0e9dd1af991eaf3ae13af0e71fa686312224c886c97e9e2f9, + 0x13a449ace196028aea035af0cd9d5b763d29f8d292443a762d8be06b1e136dfb, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x21fa424cf90bf0b715656aeb3d02acc326cb56880bcd91602efacf66164bd07b, + 0x24694b5ba9200603bca8f52d73d0f3fea26c0ee1939d2cec8a9bc5f961cd68c7, + 0x1a6d98f744fca59c910dfb19ad89d7c25f2c719332edbbafb6cc85c190e4e170, + 0xab904b12244246c2dd95c69a28ab91d2c34e641f697b5361bd91d1625c937dc, + 0xfd87c8923668cce921af698cda67103c048864129954800460374ded5b86770, + 0x2098ce0512ca13bea1141e48f14bc691b410cf81de7f597d062465e1431c4c2a, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x4d94ebda7313ce25cd0dfcd1dde7992439daae630c054d7cfd6d690a85c27e9, + 0xaf2fa274dd5b1e16568fc4613e76c9ab4fa99d09d10105e98bd9b92b82ea455, + 0x19153b7441c48cd270b491762e96e470858714e9650aac65169577d2fc755af4, + 0x2a5c69d030248d78f70674af65d92a908a7c27c34f32f9fd2417450e0585254b, + 0x436d86f139382ffb61085560e2592290518eced5230894b4a8bcdebe06a88fb, + 0x23b40e7f1bd0b7fae8cf2ea0608ace9299b903ac8d9994f7448bc2e46090af99, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x21427832371fd1ce0efebe904a3ffae941142d4f35ce77e064e256ab5937653a, + 0x1b527a15f36d4f03015a6ff483cfb5c18f8b331a7caf79237998fb914dd46149, + 0x13d847e25b71d35789c6cde81ad9ad9c1afa6ace79ecf363920dc233e5646338, + 0x238b13365a6b8fcd6580ff9f4bf267b01366a41d7c326c826be7dfec751bd480, + 0x2fdc1ab225df187a8fdece2e14114cb71f01ed887085eed22731ded19882966b, + 0x2fc9fa00830e2671b36e8eeec5c369a6b3fc27bd96905b5fc220fcf0458d1c3e, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x101b70dd04be642aa07377610e3ee7d630bdb12e3b26295806b92e9f482151cb, + 0x1227872231f192f1c81440c79fdebe597ce8ad03894cb07ac9b3423e4db90d10, + 0x1d01d734b7090603174951fe6d338fb3cccc00c0accf2ac8d45859f45166305c, + 0xe593e9c0177976f4caa991e54fc7eeae897fb723a9fad08a811b296f3e7b10e, + 0x2fe9b7637f54d7060ff768205f9e161a4cb3bd9dcf14a8bbcb37743b6fc60c16, + 0x26ac179b67db2c393739a450573022142905e5faa7e8efdd1c717eb603a6d9c2, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x2e26f19972ff8bedefb7803e3284690f4fc7828cb0bcf3b5d5697b82714a171a, + 0x7f4790a30254f654fb0a465c42217421998843693e2c2320e58cdf31a77ceea, + 0x16adbd595b9959b8b903db7df15187e66b7f6fd433fd2ed3ca0dab8d45f8d031, + 0x1341399558f697e9e3b49e50ad3889a7a6ac1b7a169ffe1575a3172a4f33c75a, + 0x2c8e714ec99e38714e1d01b984f863c0d8e05b8c3b7ff6fbca20caacfbf3bf4, + 0xaeb4122ca96285c5eb5b52fe2c26355db417406c567aa6c35dec7fc58ba6176, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x24f5e61cac001b78c4664cdc75cd8d75bde602e45c6dac698f3b28ded5a75604, + 0x158dab8b85f4412fdaefdee4d4f1fecb22f433672964d2ee7730b03663361f1d, + 0x210a7fd894e483be032c8e6876957968f2152a9f1eded11c3cd26539ab12a213, + 0x27dd83e178817fe22e022c22e620afb88e02fb15346322b8f70bb26485b813ed, + 0x28b60c3bcdd4693b01f111dab969ee5dfa4a8840defdbf2bbf38604ce4e23e70, + 0x5c56f683ea2d1d507676f03c411a29c9925215ca5d8e7f28a3da73cd7b513de, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x1ef913d33b18f5ca1d000c2209646780c4580869163f287c4fbe537e270c308b, + 0x2f77767437b926272dcdeecd45416aaa588551a79bfeb15fc3c76d938d12afcb, + 0x2da62c50f92d8dcc0f6fdd909051708b0c8f21f966ad57ba303370f00209ed21, + 0x118c1924b687d5268424af23862f95eb629e1c699a7c27de27c581c495ef159f, + 0x1c20f20b601f89d66abc8e1854d3f29489de9a559584b9df842fb988980133c4, + 0x19078ba50370eef76a00f6c89217183bba9da58fe15d8a07c565caa019147772, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x90d697c32be00d8b71f734d1f9023cdd11a587b51581e763bac5b3c766c5043, + 0x28309a912afc86848b67f7d85be9603f34ddceac4385e702f3662b3c2bdcf9e5, + 0xb100f36ac254ea63a6b92996445318f7053603e181261d07051400f302dc3bc, + 0x1931597f6dfad68193199a2166736c0c7e874189ca4d4d2555ef9d964b06c93e, + 0xb26976995fcdb354ec5c6c50e1b29139fc3c0a64709cbfc2fa992effa833800, + 0x2dd919c2edc302e56e0ece7b8537905feaa8c6dfa6c6130f94d68f7380bca019, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x278b0231cff85bdeee497f6274fda5e07cefaac1ab05ce89f863db3fce5eeb29, + 0x9ee1dcae79dc90e4cf0d0fb5e6bdee96fa6b751adde822d30e3a80b1a5bb506, + 0x1769f50fb961ba50df8b9e03a12fc37bc965265fce93f9762b274328fd04afbd, + 0x20a99da43235a2bb30b0ef58d708d07740510f517b2eedb678a94aaa4edbdeee, + 0x11b7181ec0f9a1485d84cd91c342f70e1924c7a85f48a33e7bf8b5dba2b8b7a9, + 0x23453eb1a5e44e28b31107f29dc6a7bf4818a7ce156d2c7e81dff75cc02e937a, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x2abc91241e3275e2028d68130f5533d6c8e3d1ec2942632fa4b91a49fc762880, + 0x21653a887bf627cba0b5a35ebb3329f4602afd8440ada0050c31b249d962f86e, + 0x2ffee525440cb92eafc518b16135ca00df2ccd813bf1f9bc458252d7ee478def, + 0x104bce734fb0322de9a91058ffb340e35c212a8af5c5b6ce1817344d82137d5, + 0x12db34f34145195e64455a298fe597ce8b757426784cc53975ed5a439b91c12a, + 0x13a9a61ca0008c1b911748f5593bbeaf633308428e4e85378214be04aef88b1c, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x14ade7cef88a7726d51eb001357d8bfce8d1d8ec79472f6f2531d94792d4707a, + 0x24baee921a2b827fe96835346b85a3e94ab75b4eb9fcab4235cb9c54d0a077a6, + 0x4dfb441b179922b9e2ca9458de6d3aa0c653beca2fa7317a5d1fc4138e8782b, + 0x2efdb84c3c6faceb0f58fefdefc09e447ea2302291d3ab11101d487f3c679ee4, + 0x24d861650389f03a0da9d720f25df6e7ab3796ab597ed63d38055431655bbba5, + 0x1f8b2609f6999f6b15577697e90e891fc7b691c30c2695278042c2d152aac2ae, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x242fed5519f01070752e2e3779757e5df21033baaab86a9fbdb1a54d11cd4db6, + 0x6dff8e392f51302fd8864de5068b943a2b04fb0b239c38b679faf689d69e1a9, + 0x1ce5db5cd27794bbda0f7215bd9404f46502d2b601f74fcf2cb1a5b7fd440fbc, + 0x16aea838ec8bc6e8b8f48309cd6e783cb4a337b92728f66f701f0d5efb32a80a, + 0x1fd21a8ff13f0ef12be5a125bfbd5e952ef1e46b4f3747f3fbd8198209d4ea95, + 0x125158b21d677618076854954d977c35a6313a1f37564e36bf6d072d2500df6, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x2bb8e29cb323e3e2879d93d36e9312bb3c38a922cc6bcc1689f72793f5d4a18e, + 0xd0e2ecbd08e247ae7aff1bce2bc54ad1603fc2cf0ef32822701feeebf4e826a, + 0x2e7df0f7b842490b3f39d0d87bbb35a90cf23f3cfeef3c8a4fe4716a47699470, + 0x1d9dd609a2944aa782ecb1a08acb5c0bb857c7489920644f6839c93c10b37837, + 0x11ad269471d4b36fb23aa243904a0290608c32759020f082cda8b4d538752109, + 0x2d2f546cbe60a9822e205c3f3fd187bf89f6def774c3f988de86e4eb91595bea, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x28113fd3a8d3b95ebcf29f2ddb54c6d9ea034a51e3bd1198e4c1f4f1dcf068d0, + 0x114ed46d49b389b14c202ba1c069ed4d836c131dcec2472f4bb78f803b90025b, + 0x14a217bf8737fb3570e38b75cbc97b316ba21db8a3f316aca5a26ed35c0d1424, + 0x16c9e7a58ddf141978209561d930058233b8adbb9e3aec9702ff674c22b009d0, + 0x1388b78b9ec0242e402906d75be419cf92e3dbc2a5152df9797318e004632793, + 0x2a459318d3f7156d87e3c666a8f7626cfed0d30fca28ef7927513b1f7a294b07, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x1f3df3ca1c4b854792a69d107bb7e6e7be2f479be397de83c94cb310e8e821cb, + 0x2869447a669cafc20f1f9017028e3098b38a82fdf3cee59d9de2c888004b41e9, + 0x25eccbdcaf0a67d5ef15c7baaef8bd2a4eaa1a6d5d70385ed777c10db4796ff7, + 0x24c26970e999f27e6351f1be0a3211c0a177cdb778ead13baea9b7b4be3534a5, + 0x731afc922ad48a9f0ce9d635e26ba013a7d4ae8d52d4fb75f0f02409d83433b, + 0x217044abaa3c9ab6c51927ad1061d0c1cedc63a90b01b7b5f1c10974e66f879d, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x26cfa9ff210943f6b07c08691c2eddb1bb1d2167a417912ece724706b5c20b0e, + 0xa5509b4fa5bc8be630a2ca7c40980904713b196e36a7e9f839c4474037e049c, + 0x1c4dc788b6131f9dd132c2edffc7a46ec50b000383faff5419392f0d291c3475, + 0x150bdab59767a62d994ce37edf2c3cd5311abd0bfe541fb30968e19ee2601053, + 0x25393627a593730f4cf25a068932d447c1581f251f9a7b7d86cf9e392aca0d31, + 0x10598af7a84cfdb4c458ca7625dd8b18509491e7109db65bd8a0f80d8778a6ae, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x1fd5ba5922d7109795d5dba77bfb57ba6aef1bb6aef0baec38d0f916d35ec9d0, + 0x439026e268ca0fa85b1f6ded27c854552eed2629ddb59e6a679d4efaea6f218, + 0x1d5d47eb657ce510b9f9a17e9a49d6f0040f7f360399dab7f053faba3f06286e, + 0x5cf07dcd831c1c51062ea271b402941996f46dd9df0fbb227305a550f42697, + 0x24ef1615afe18b0ff998bf9e1fc69fedf38db66b2257f4bac76adc04ce92e029, + 0xce1da26cb97828162425a7236c23e8f4b7778bda9d7d514b1b8fc9328087c2c, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x1355e415b0db4001ca01503bc20232a49e67f0e816dc90ff18a4280437e9e9b8, + 0x11fc9669cbe3bf176da65f312e409d635dbee3fbf8f3d1d6b056b48473cb451, + 0x1d6c1910236789557b4c42df0191d2a46cddd2838ec6a74b7c308f023e71d4c5, + 0x1626f4d2cc7f2d46d7c9c97030c1b420d6c2d55033f7becea7d377541b19f57f, + 0x210c4bb43d712b400d4bae4bf8dde436786fc88bfcb82570b3e235ddc2982115, + 0x213fd23b04ea9e58ea915c1fdb460f3a0ac4b0041afe80f6ca1ba9e1a0e13825, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x2ea430efe8ee1f2c72ac009258a1ad98b87725c00f72d27a31c445046bb9a80e, + 0x2d694e23e1b3f6b632b646584e76fb7b0d35aeda598fa5069d73c75136bd0272, + 0x2ed754f34a22fe04fbb3635776e0894d21cdbf4cc6e03b8bf33787883c1a0db0, + 0xf23e64e2b59d750be3bd037f4df62f7fbf16899400e69554b893f4afeaa41ae, + 0x1cd301878d6d778480ef82b2a3cb9bcc36362d198e44c204e490cc524a2bb2b0, + 0x276d797b67c8b3d935a71d2f8342bf7cbbd68de537e32c466f95a01a5a207f04, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x16e8ab5ced34e81dfe00c24c7fbd0f4188351be2b1b26b6d63a1e02b84aea6b, + 0x1caf3b10ac5814656ec2d5852b5439f810c8dc0a4fd6ebe82d9f33134f60c7a7, + 0x225f97bdaeb6a565372c547e9d6c354c1f78fa1998cc3d92c28212ec7edb634e, + 0x2d828acba9e58e0f3adf239a3689449515a1ba244c13b0186c827d600b7a7358, + 0x1f9da4066a62e0cf290cb839bf62c9a49cf79b0ea1affe03696062ab8cb9d39b, + 0x240706e2b81b5b65343b41e59330666d2b405258c4b9b177495776c2b1b6816c, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x2d0f43029750f58be22d66c5b2963ac6b15b18c6e9d009b717044859fef9618d, + 0x14237392b60352f6c8aa0f5c08024beb882ab82dbd3e790cda3898886aa3e9bb, + 0xc8f3b03657beee6e1f94c98662b6339cfb7db5cb431fb9813587ee3f194d260, + 0x18700b515de19b3256513482566afcbf490e55633dc0ba574c2fb4efad1ef118, + 0x1c3b0a6645d002a9d1e18721a96d1e8b00217bdbea74ff1340dca47e6a326e26, + 0x2979c4d21f80db612fa98aa90bbd65e2cecc1ea431849612005a904c08bfd014, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x24509dfe357470309be062b07c05dd3df57d7cca62caa26001991820ce3af97f, + 0x2bedda6eaf8901b78a0e53e25dacd92c60673046c86deb333ce4798bcf9357e2, + 0x1f1d984e06825a3da53ac4066d4910067f6e0ff13ef83152cce3977ccb273404, + 0x1f592946ac103f244d168802c352a7e2dc52bd2e53d3ef2f4a7571af810609e, + 0x1a975c6688744220ac1e3d5295126f8ee0db7ca6283a176585e8dd5bce060ff9, + 0x1a78319fb62d99297737e9dfdccd57fe6ffe0329195b8ff713a2d6d33596a6f6, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x2fb4c2f41520052bd4498be87f445b3c62e86ca7d872dae8fa99c67b5977d11, + 0x3162b367e9f34180f2228d505e54dbb7f2f23a3a8fee14f3084aea490fbf3fa, + 0xda5cb94995f668763e7c6ecf96dc6bc13943abf3e49c55a702d37f36f79114e, + 0x2575cdf1a61befe9fb7b83e880e8cc23d82600f35598ea2f81ad1bec1bd701b9, + 0x1f83d6c20646a7e089a8fd0ad274021af2fb24e315f400dcb3d26a99ab5a35ae, + 0x2c774cf487f79664580219c9d698781249e47b432767b0cbaf5169a5079fdb42, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x203c1b59256ff5c004e70c2c5125ed51cc53e99390a8de9018e647e1be8d9888, + 0x27abfb2e0894c5b4279b39b9319fa54ccbabd1efc509b31d906a1b5f764963c1, + 0x2fea2fd0f35fffa4f84894b6525b3fec299c821a4766a78c829c2e7e69efbf0b, + 0x2451d54dc48cb608f2e96698b96fd545816fef09dcaea75c9928179373a66fba, + 0x17c5d4cbf713d33eb7c1f915dd2b0e439bebc5510cb409594adb43f94b7a0e9a, + 0x279fbf4382e4b2bc46c1a8f719063ddb4226bb09c10cd68008b37c7f32d469c, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0xeb7c1194600e6ced3d8dc88c8689704d4188dfe89970dd790bb9cb600652321, + 0xa0e776c12cd108cc589b14e8493dc743d85046b1c4ca97715ec501fcb166ba3, + 0x1a8a8487cb8a60bce5774f64f62d0bcee791dc32d3a6f872f7dc626e4a732948, + 0x16f103fdba708db2bce8b58c467a05bb8878939c82852921e94e5e955aa09ca0, + 0x27a57324ff8193272833550d82f749d1389b493f98c8d3473f1a98900376325b, + 0x26e4040378441fe8a60d1a5319aab70076c82cc203530d82e758844070c04860, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x71846aa99eae694fa17d73eae87534f09c4539fa5c3b79ea6bc56d888dfa9c1, + 0xcf75a0326b8ca3e2ad571834bc835c083555587a928fef417730656217faa2e, + 0x1b80702e894d74821bfef8a2dae36f71d4802940f63a14fe64b3081340c4f11b, + 0x2cc49fb1ce9198b927ab098ec9f454d205342ab49677037f9ff7f08e3f07ce71, + 0x1a6e74bef4b0a5b3566facbf770a14bad98d8b6feab3e45995a328135888e924, + 0x2ef1e0f0bbff91312b2c9b4710ca04f4e978061ba53657e9bc1893bdb2e7c7c9, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0xbb77a79511909681081da11a13c7abf3107373ba413ecba4d47ee5a0c288fac, + 0x23d8b2e6869d7d05101d387c1b8cde6b85b7fe860e7eed2944c50d099053bfa5, + 0x3023a8bf03a803eda3830c500d1c0e061fa85c4c15b72459475e3de290616ae9, + 0x2b27c41a943be0d396ed3630098ff7018767161fc1a24d25f47969f1a44e20eb, + 0x2a73bceed9ee2a7261290c8590e2ff679582a3a6c5988254ddf6f108f1103e13, + 0x2579c47b76db59c6206ef023b59884fae08ef6a697acf7e55b6f132fd7733bc2, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x2a5993c9c2a80be0f4b0a6f9c432e2c0604cf59d5bf5bf24609572d7d0acb900, + 0x10faea103aa36e7d5c7bf760b355e0fd381a393feca3c04450d7faf0f6a22804, + 0x2e98e92bc9904ca92c3e6d68fdd79e8bef6123ad5174f01d5dc04a240d8f47f1, + 0x119937bb5d5d9029f290239eb94fe86069f2db6bcedcda8a1028e0b7a434428, + 0x7c67a48f20850fc8ec8c735b73e07af2a08f52e7bc90084e9609e97f070cf2, + 0x2da7855de0bdab6e993fdc9ece5fadf00c5d39d58f6599a56438aa2663cc35ee, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x1a69a3840762376c3a2aec1bd8a434f2a5e410a7e92d23dbbb20a0991aadc46b, + 0x57e27ad9218a311c3627a25345c879508fb856d68b9c0aca90276b1dfa4bf15, + 0x14307851c6b079c4f3b26689dc5f62b8ac2b69ccf33f3802e9ada26718881832, + 0x26c71cfb532662f6e681dd310fe112703b78f8ce1e3c39183d5d4889ce304271, + 0x294cb0c139a1a5a345bc094d8a53f21d90e82cf47bb87e3d5e5bbd761e6d82aa, + 0x84133bb35d1cee7f10a2f61953a4c77e09c4661a5565646654ddb7fec0be900, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x1807d1d910cf5420087bc575b795cf7b77b590b7d14d3e3d2298b302c875bc1a, + 0x1df001fd3c1262358bfa1198116229dc12e112bcd91b4f3962c8136c02c57e9a, + 0x2b424b88ddb0ae2ff74d14a89099f8942df4e737c63f61f695ecea4842f9ff07, + 0x189b086bfbbb9da30885f11ff9cb213c0a353710153cadd96203c7f97203791a, + 0x1bd472ab81eb7d6c92809c07a387b1dad43a3083fe658bc88d1c3ac1672e2ec9, + 0x2bcb32de32d02f4b8f8b1d100459f537cb0e4e1f14cfe5724424107a9929bf8f, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0xcfc7baed4497a2252d54cdeaf8ce6f23773209abb5f341ca2ab616f0516195e, + 0x1cbfb6629ded2640c886dd504a2ec58f96b441839b79e54feab04260eb90b128, + 0xb3e19811df2edf55549ac304fb205cdae326abff1e7febd20f350af8752f2b, + 0x17e85c4c6fe808534124bb66995e5c663eb5a195ac1a26d8a096db675ca0dfcf, + 0x31cdebefacdf2b2dc708ff87cee0315f36e97308369e304e8d2654c342622dd, + 0x17c33efac12fd569e1ff7c0a0165c4cb8d23c279d442e7bbd073cadbe4f665b2, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x866a0d2140ed3854d5822fba68985764126345cdafbf547ebd33c39aecb895c, + 0x2bbd1e9f3114413c347ee4037d08f914d4cb655617c0cfaab77bb09ced39950, + 0x1ad0d5f7480a78dd4e048c459479d5622ed65f87880f675cbd2c4d97e7bc7847, + 0x1b88066e99b993f70306cde87ea47cab3efa6d698c9d3b1ba355b2c9f3453b74, + 0x25fa0cd0dea157ff4ed741b0dc76e0095a51fc30c799500e80d0b821aad7b9f1, + 0x208e0d0378f2c7d87a6ce8abcbd4bdd979a4d9dc80268cb96d84ad440fd0f99a, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0xbcb27a9e590ba76102f8bfa6f1c64726558f57a0027e6ddbc46d564eb8b09da, + 0xce91923c51960849a75b3f8fd1bfe1d9754dc7cd48144f964a0c91a4e08dd61, + 0x1fac92c295c763fe6b1e3c0f3604f0c7d618def2133ee2f869d2a1e774b4245d, + 0x87968a25cdbb96cd471e88fc2cccbf3e5b8bd1037b4ee5332adac070a82a109, + 0xcc8d9f53ff98eedd6fdd5c5def364a45d12ace1ff5e3626f760773b5de0e624, + 0x2b95310fe6307070e985d61390a351ca5e1c4a9f5e2c539602136fcd080f4e6a, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x28c0a6ccd9587d41eb73206239493c9150e52258eefa598382cf609d4559b2e8, + 0x165c6c313faa07be77275b235bcccbf30af0740ca973d6acce2cafa9462491d9, + 0xcdeb047d8e50b00253e926dff5f95b4279be0377669908d6759612cb73259e6, + 0x10140d5f85f2f329572c2c9b7535776b7695d62d6362ef27285485abbf9db018, + 0x9501340c196da04db07c8b1c3bc1461c228e926c9ee26f5e26364dd894b1468, + 0xf607855b7f42530fc19f6431d53035a74eb03f7251d71567982458698c93ac0, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x255be79d8de4168c44cf8a26522391ec6b67e30f2474bf2cc7c792dd25a47046, + 0x1ecb792391cc746710b586800234267adcd4d9841c4e8f1e76dfc5dd15eaec90, + 0x292470307f3a20d0205a19091cb044a8f9e58d0156f0364b21f3b6025b65d016, + 0xc3d7b0383d1377489843e884a06ba72245f0498e71043af2acda8353a47ecee, + 0xc610cb1971aaa4ae5f87fb14ed536198648cdc876c7c6e2f531d7d5d1ad625c, + 0x1c237dcaf124be157c5897960fe7f22af44d441d2d4590028a07bb249711d7e2, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x2a5e583e4003e7e747a1d39ad6027a9f347c7de946a3cfd00750a9a102c05e3b, + 0x16ccec4b4960d2331a960804ecdb0442ecb1bcddb9bab42b306c4736510675e9, + 0x2d0db3092b03a54bdb861c291c1a1f522112f9e457e3a51d731851dd59b1365f, + 0x16f1469935ef074ab1ae192294dd62af3e14ae22f1e294032222c5ae19e2adbd, + 0x67c4106d011aaf52f2539ba2f8d1fe65ce9ae081858ad629b9ebe8148cc0878, + 0x12c6eaadcc69ac3b7344b8296ea4a251facc1c96356c84e8131b662f3d5f34a3, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x2ad9831069e1f113495cdaaaf18733aa4a4eae1e850d58c06665a1c787ed6049, + 0x1a6d2b5f928d9f0a9c4022b9520d707e5eca0ac9cee84927a71737a036628f6c, + 0x1d92d368ae1f42256bfe712909a03c69a46bcd207c17461986a6de00e0952945, + 0x10ad1d35f6f8f499e64daef032a28251b50c622a28429d2b2107ab377784faaf, + 0x150225afc95fcb450fa9b2b7723479ecf7c3143eda0eaa257df4f1a798cf6375, + 0x13c542f46f245c790955fd30c8cfe7125534ebcf6df7b1d9bedbe7205eddb980, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x2fea3116266bd3005b05649b48c70089e572a077ed0f8f9730b63cbb9134a368, + 0x1bc4f0df44852b392b2a36846030f42fcd462c40b04d0c90e71129e621842af6, + 0x83b244ee2ab819a95d0c4bcdb9d915dabb6832b4dff9bde7ce0515827d19cfb, + 0x1fe91590b6942e9c496a9c696c067b3086fd707b01290a7711d4f398908c8917, + 0x2e97a6382c9007fb2b6ac74186070eda269b10506e8e4a74ba82274d154268c0, + 0x19d731e981d3dd374362f4b4f05c5ee9600b5396567615c3ee94e0a80c8cc4ac, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x1299ec83503dcd0c6aaece92e6c2cf7871b61e43318dc82a183a5039044fd000, + 0x27059db058fd253b71b341d077246299734497dc31f2159918c64a78188b85e1, + 0xf8c2dee7cdc8dc90eb57f025076157a181973f6347318feeb0c99afeae085d0, + 0x1053d862218c7ad87cda3105ac23bcb12c92e883006c3d44fa3f9166e827cfd6, + 0x1442ee0343b9bc2ae95f8c4f59cb32bb461a4c7b40a12e89b68b6990a4b71933, + 0x2ef147fa908e6186fc2ed54fadf20555ef2a1e9b3babcb6863879adf84a3472b, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x297d7f9fc303a0f583f992f7347f68b50b5bbd791acb93e2d8bc8efdc4c1ab53, + 0x2b4e8b40ce6c64abc1c906a956e5aaf5ebbdb7c98110e171adac573b81b16195, + 0x316fe041d68e38cbaa5d728d225ed818f00b2aa9ffb1ad3d9ec24bcdfccdcbc, + 0x168c57b725731fe3159d73e0d94c0ebf35171e3cf88e1267c2b556a5456ae6c1, + 0x90666d655622b3757b5ae5283432b4aeaece83148a36eb57821d241b3efbd3e, + 0x2c91164e87fcb1bd07143870286eca8a29df3678768bae50817569f48bd7bdf, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x110f901d246c2e951c579bbe91467a2950e69ecf241d8b68c4a4c98f05284b26, + 0x484e7feefee9a459b2861009d6007e8b15721afb4a35f3e5c9a6f1f70334091, + 0x11300deae6b73e9e5129595f0996c10ce002506c2c207bf672676a130aba8364, + 0xec4bcec59f43f5b5653a3cb0440d71118ce31bb60c75b9c6766b6a5e0524968, + 0xefa65a66b38b03467fe38d8669207d9fbb9f38faaf70d13a67c6bf71e1e71e6, + 0x27806883684a018d11ee2ecabb971dd9f690cc5a22ffe36ce61f17c6ea5fb4a8, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0xf4b7f229e28a7a9e7bf019b18ce7a36280fff22f7a99e60bd84d1baa891cd12, + 0x20b53ef54ebd25d7c222d418e017b7cc5e00a9ae5221191a1ff561b1ee3177b8, + 0x14efc55a08da5f53635520e21890e2e5eaf0cc1fa1fddcacf1302dc65ee059c2, + 0x1b701800b22e5765059fc4525bb4aacfac8dedf2ed37253160baa818678ef374, + 0x118648d759ffd92fb5bcb86acfdfc4bceddadd6fb1679c317cbbcf686651c67f, + 0x2601544a6e67f78415a0c2a6e8f4665f5910909c58bb2eb03f7854519af15f0, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x1bfdb6da2db944b4b79fc0ef825d6ca2acd350cbb87ff12187db30a1798d0dcf, + 0x969ce62c18f96eb6c6e3d0c5a7bc7b2b1de0cb7ae0474b47d16445f2d067cbb, + 0x13d54abe37dccf2eede120eeaabc5105b997f3647874179cfebc1c9b022b8215, + 0x27b42d0a347af048017cd6e2a577e959c0b6b6b8c2ae405cd9b05b793a2643b3, + 0x2737758ec335fcb4498d54d210c11bce1d2cf1b97b7ebb835c4bd17b1cf8d54f, + 0x1f9696df0bb5e293dc20d0579dba1866adef8f6e6d3846f42380861f5b54ca46, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x2fa9dd289eab48f0424a48c9a2b4f51d2de3ae6cf2d5e23a10b0366938541d65, + 0xfc755141d556a5eebf1efccbcbbf72ead5eecb5ad93e9814b715c4d388d7709, + 0x26127072286989c57c665090b20dc85c5fa983ae80c412fb2d8ad02194843981, + 0x229663addd9b99e225513a7d0ed1b43c0b02de97a57466355e670add9ad636b3, + 0x3011613dbd895a56a9dc81ca4f61a03f4e77c18834c6c20a51be01d4ef9062d2, + 0x5598cd7707b28488e2a0d669ac14e8464804e51537d7d3baa45a7c80e489c5b, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x16dc1f58a2e54f8f78d4a2bc67c5dd242744ff2db0ea9533a9fb3de2afa831e5, + 0x2a274cc1ef7dd9e160541523dd6b2c159fcb0f40191b63a8d0a877777b8dd060, + 0x1e8f3078f2fd0b0409460ab369a100d5a82cd93b3dd947644aa6bb8fc2f4f863, + 0x2ee81ae8b9bc0eb7d4417e09a83dd467ca8dcb6e8f0c8758b9cba555123dac67, + 0x367cb4b603a227e6b02ba57173fe7391e93db6078be2d56ef2e9164b6fd2721, + 0x184637a267f328df1bd119191fe0d1158eab799713ea537f01bebfa4fbb640f3, + 0x236d13393ef85cc48a351dd786dd7a1de5e39942296127fd87947223ae5108ad, + 0x27649a3a1db5ba83511b2f9fb3785dbdf083f1f5d4bed38b76fd379545d9ca08, + 0x8f84f219781937a7bd7ed5aecdffbcad92a1d31262fe51761c94a0f19973283, + 0x14f65d95f7359b8f9f3527527ba9722197df3e698f773cf3027c00bc4160f989, + 0x2a75a171563b807db525be259699ab28fe9bc7fb1f70943ff049bc970e841a0c, + 0x2070679e798782ef592a52ca9cef820d497ad2eecbaa7e42f366b3e521c4ed42, + 0x2f545e578202c9732488540e41f783b68ff0613fd79375f8ba8b3d30958e7677 + ] ) } + // noir-fmt:ignore -pub fn x5_5_config() -> PoseidonConfig<340, 25> { +pub fn x5_5_config() -> PoseidonConfig<5, 100, 540> { config( 5, 8, 60, alpha(), - [6652655389322448471317061533546982911992554640679550674058582942754771150993,2411464732857349694082092299330329691469354396507353145272547491824343787723,21491443688002139478732659842894153142870918973450440713149176834049574486740,20196926676989483530222124573030747187074792043523478381149800153065505592963,12986278951352369831003505493892366673723882190521699331613883287145355738793,21126146258242782643168619000295062005037298340836817770565977031890883232034,15509665795506578582538177431401381655815033647735781734613703976071034655246,6989769181472743404364681671283889685042701491627165526899522083327752110839,7062179885254277466334896166987547257487047183881628199983668518000910197987,13842521112365108087725039904948872289730786568469683976372377853164252494752,3830559505943186272618534143266118508463381443414165428900505002474439179836,17704863473432653834041116667846189591617394753001613253930974854399793083900,875580502229441633079974792778818749112423694973231971690365132230865385439,1971134273535892826573832061354985059300866001765691176219451252512658771248,4865738840363990164915013008693722144676933915103280504727326977328013515878,1148603338028060679975883868174895825055359423662532941509525326937127571764,17506086433923270253695698017062834613463718526046463655503742220257039588796,21580033018107258179208198773211859664893072138803756118939260252922297665067,15411900706973212043830142913959920716501447427702082030760032355626616412240,12219699506725448409610279620972339448030565224304464695714944121760832152291,4525719544192047521328360848269156485222470829314314216955024799558286708479,19667371373588322336224317159113441765198420040800065314868656839300028747331,18916925604689704279265158984702141998345424765142129953154245912230835240445,12789343981741773931665143789673052782408749041041266509485929045869073416222,3094428508959717445577232225505810354980663487713729230015754183012845687401,18544590634480965569098056786078005630500574069468005220462377474861119476492,20990087440247450018723844204951613913840993427110495085701200965767234569705,17552251989761134508416634118845221324472178264364440017634233349418103869223,21000797802575507763447855752602183842956182733750968489641741136166640639409,19292751508591545849778577901067988044973302547209758604667395356943370737868,18314088316445539319869442180584299715533304874169767778761887632882728399870,15003745150856597539000559910957155642193629735521291045949652201905498569732,7839443900003691950104175747634267110464104444913379977500178134209666299140,13568305490393393394812598233983935295266242465548739772708079888867621061127,6453005227995051361096639028742707098785560656441339640433794156400437698140,1420171596348195609536167209221442141824294918625468780931400849866478645240,8347329128252205996443084339884155586061343024498283583400215109265013719709,7893774494551056447960817286805128884970061671041428326788899872964096959040,8970476243368194065341537088653900235777512204874037182428362347342487241690,239049405935404678508864874854718951364753739466303321590415544572014148257,15772878921699764223771017074289335629553777447709755479885293350677783703695,5416082112919155131434995906647355834510201879607888732259087164602171650389,4384524908062410354304345761652962203632712291085564157560146286207296352050,4210984612917608245844011498198864216639269565627982123611519493203177283139,18816442907032290878644773027005263628136050677095986565400687355912498966559,21443510232279945782338486087712914668515437675585863788610958361560172084515,3234314779308300525339049581669531363375743827111579883853941968586490182859,11029499234949696730080035941750777601416171837281021031653841244636590396063,11145210633226924132308292113124660576759662647204939721872338908644906571564,4583160563963432761409369246361117506465307518522062239686649163525543782173,9813992026757562966842771727657080117609486122615087352428596024939855084450,10084171857039480706430282187972782725948479260179367780776125786119489581409,3874212709197875589640151274548083098712939093643165182881681226579903752816,21595542491397091124739711708612983479307589335640792812157875295064235960610,2068530815441314105493629066002923150651375034543842424822712297257260726954,2673459852071215292298131389250564595426361004231758522146794940265552265806,8591046256746588406353455230465605224309754008961178558834659065898923355164,1020055192431352394776887540248098706183934464205704158014904833376067287118,11085709480582865378042656141271006552092494690130782253913953070642865919312,5673844083530503489429922596812992664928167369104420134641855283771127716005,10492199162275168254265892158402955076490959375050993042712629236807564461542,2280843393156259739329331366624245275580688891778782679394848304764573859886,6807797027131305026345508953353882265754363485246407959111359919046340709440,12692191384043938397944633973317584101723715998700063415107128429315536223446,19818676957110967644349139912613239435706480354664804036688552936554140369382,18055602608192644695569077694296748842203151828348990995792087204755925787339,20934555391215769430553078793246717148484784880715746179415906355043590089450,11420705181439111353998210442417752592951340005396931802449360401461783159557,19878854521263746227125001670931867821366047088989510542865511663910116386085,8568201846715449867087132677683368912214864824182424933182820310911278496552,19198701614488576617610339232794062430644024620523684127268879880793305460015,15262122764244854433806270478871594904740306012582364033343126589996733802868,6412758421155818207287638337822550233376667015263373809976157264137577776202,17371585001641430978766734501830788427263945848682170096055857509304472649262,20262970042379497707724791203314262108784948621691331141565359315001027736581,3859750447119748295302212198327542106766447958113540005985799287718502362717,1172269945800307665458943534144481495673510885455899148864236015097947176746,8164247467959680477306326470118519335673181279975551434197731340070491876250,4513977811114181395323888111232002391599397736872779927267726121435887238972,1075250595927474080680862736233039825365918646878264905022213616210377518447,18658420120424372681792175914064174056413842231969276203770574969914576681364,17769673440848360838244654765103041739044212539359630263894092078288342647801,4319086204044362848967484441065231939136453667264715596505827197873119273506,11221173270629292820060668122527062274557317856738971635698169204652845111606,8635411372759272135249379415383299350267629947167809163276219879514948820576,926977621651476360285369760355547766944001783780761167546467658394097283069,17702143780592866375901805387463459229828093905183622296234691441436877570082,629612289140842594504574984021125242351317893847688437087866691775821981724,19990548577495092294245865870717186004301934545721835081514347926537975465539,7124830628609719908679298707909792306162298058570958688501370177898647946696,14620227791860703231425817538142948793892390269806790476396226159679984968174,18495581997440241868332244230687799183899751339442721677540757155760745277888,16922065056093401385376103551657968760602009001905886435813054626317776258714,9969610601962874779035054685661667941954971427956866645694064022029705170229,15281641269114187762159685323068136816556739502211864119670902056596295644116,12114994625438879103001132949163961965524612903017200394727056658298824651596,4840986177718281128440833017205097196672382395936939379498412745183060615212,12847307562796769659308999092658905656250954898192781948610713494470441775991,20290096217351155282642224215178246911041509999959311313223857240001143893317,16151664509646153154405691138084115125600386733136285504828908979176781265710,13848845391482751436287906247470303487958950799995701248612703022979890932133,6335716166231441585596963683321661194889815181545222079376536449814718259931,1824302750039354704619545544386637317858342555634601563660279997221547953768,11327469654081586239268713126961534952233559223228327222485848924908493444712,10077703415170135154603829433031861799853903739210136452726077323833067256620,16368073884579385814331927334821006319227867093692644942500207970751483237405,10621580796499573269115131164341885791299038227955222944695715163010783205295,2099241376651019397894434242565225315652133572870234550073686122343103853816,17104632243449417396641550271977294699471083572885397875525767745512335891599,1935453754847256492223646005402770357836971113012418013930273797463411526183,7492761611332930896292052363224494314920390056637668407353957465667515477934,16836705924460095689555600825174696605443212968244843485187771119291716736958,16995495500678141665340056658079449793587669420913589967848082091551329904176,16097379973857697753436437302681608056543122759719328497348770844548177814262,17476569537128329379528694049566216604638194592812108658767104922628767500420,17997217989870184804787026924935938133194070033518938653831611194683423549591,17573343771046232580761295935281170028624495346579002725814597714902588657750,2450087639204541254902859018960918562514681200270997307467560465282168310665,17288084325555056222618040923753050382954155896826087372317882602328092535440,21837047676579063581498107773514419735425738753079336764356909012851439336687,370061273472837873736743292149368449614309676635341873070086681342317566380,420725183996224279379885018872359102189091670793820517618337092091910692771,4966571645678139143731798992823327185758562224229132271884647901363447388530,5039558223429273757296118284876763395391635773837549121798873235133698166026,14663152729953724779401067486012084029581847325524052152795817923033297673686,7201040456590575809960214033959496417566605177095808543357813677845263237276,16872945504528960415453618286121813996587432836152082188694652370255998768595,4914824783780909279212078186433590922437371437384817332713271291839616026466,17503018483514413315464207189113334433424965178631599286655188843769810245465,4087750571011463387872022799241315348852213278729592692674275176152296405923,4006961923780091252337105595934918049936238157468198971234322013673884171131,4481908842184366902145805444001507554481032302978790080019710161108326487967,13532316826436461968093937893872910736305115143550039673102602344678825540956,11602986656925867325907196773754426955346837006705269228226729102186031417465,15306992574062791537454541745213815567999895856471097922112648012979731636068,4497571735611504561173050536899411999551839050319538712220770383407135602945,2571242673174714867278075260451133687893879636121064640779554188161591611843,7070272070524747733177730083966686149849667613589868731851816020060781720851,1308310289745495626002351437755820460104812708071634598163946330870933261232,9483468192990391193401121929514821570714432121414330663623018046165053411090,7317568349845215930675847155716598288688799068821709820024570206796617676748,1918505733423704616434273602054555051755671749253598966287072464475922854850,15158168161084905689406532256983805923258003804476527617207287404280855731962,6855540174355511438343304861678411868002455139032857270673849263857877330771,5989863238360846166935911112885654223487221280254816980802479355446167746774,20283337058688740322296928691341300752003492063748410749625272920572074851396,18957132189629332408653055312790838576277703952267542471751593810468444454136,15764518568966520670995753676429154315765754748131847346608706222194564055358,7192524197002826721654253762628934164676539329903087107420445743247046038858,142950766663597487919643890566358241353679421113406309294925836697585309311,15012262168187689680572958978610204856600235635916074406168861726626292993057,20795666834671497603181209610179324236645779324677512349797033323222380300794,12650341271833683789775531792948185319868795529390391267833516836256688318306,5597700232877580665749288204589530549415282468176625525368428476461504532052,20949303924691159143653175365242293984396858344688574262804199947001630916385,10746523145835332938672833282581864816136388045771578294905302886974358762209,4998982766221590779170630035756820066555357949247521575936385387288356143784,6936999580131731861735955554005106460473097800566952971315565150681540640020,6670695360676548472482680016233507548657051302712214051977034166870814430578,12210816592786563975173850937247594401582085430897698766795696447223454826466,14933901149105284237676334791785996160108290333321693498322435129559137152007,3848529433916624869590379003597911090976938589461403388133685310398004369431,12778805225074604003024964969486878839359935515509480774809299341511161183802,3288267180428684202786697419666969564766921974531343432588030535602163038467,1272672432174256751826350693883913844502039730140570583479554071765667798207,21130828804874452930669244946376257892693846272313548250936991077452679117587,21254559353072473881932828401787134230282801383134765683324465204971002861493,4116075860631781527931204624078712926526805345818156200756399332393348685924,17435888597009729827411190999389277840088354756277916760187756022854497211746,15837398163415665169712832984380121382150588321621493928953938599666110830812,17988638446757562417082379159769772097890681265659458369075768452342579854303,8144561030363576879343874888624208577604401139613622673042754207987577727758,20020299925602421262203305284307419339160247406220693128040712457114283033661,2945951415037890626891130390523013930737768652394758977777336357159436605764,1505954324723537402640844232704189835623922400329086438898375859826553573763,11851584491756305117491374581845512067704002072833714119284164514457248861803,14471204965036278214508938537949717553799007630471016532866101610339050785912,7163557293233604902868673807221391042191134560333950452577270522828534690707,17291625782465108601367695465389799786592304061550212130987221355832952230827,10240907112109243116543462081552827576656826251172050843989873656917271396422,20702261919346727858635106264046787321170414155594199951578791234276181642650,16678253307828004252292273162411388452019952018258857370242272543091326285541,19810917631941180098047817620026253706643400683524412974923209268916769874447,3357220165225360610202375608872621445880880830154732998557832689480921421791,4392285438534542495332422274902727975330102148971785438164412161504066619105,14642025133729666610167675086855441462580619607677226879159952689184960379911,18142623439987890999821892559271093087005885278955082040377769578204898750505,11769399023330099592616157336702104329646487200891911089287290893650532639221,7261353756299584174448625214367175510387913706095214313669922259027644778060,10406994568199070863112470594593301582798997458844791396920771226539013327304,7475277967562870216712397220016587384793504784585573136176313471517144184018,9598064630327104406929367986473441777975480987434868213697837347643980267620,21137410002545951849752865514437404724653771608225272412595423069852350320648,12345612867231779996383303763804719815752861524077922121654106906093103051400,16461750199070055335468534730937701659470268635084522644824623393184528879703,7829250842543018165409887731515254191943527926556191989558018633300783421935,19801151644322693878208767560968285812646931156576102755771403150148125880648,808770634664491371274943928223981161442027957963181999892266696287962813461,2298122748772261447929855283951027113218922003687701626762072351622993276571,17407798064458858450209051887305178872029674498718760624162479511390762310526,18585562277464562541666582720366573863334618817908062612923861658144918595030,733976598693219656339731904831283238690050114241501938501377743874139460889,11316063986696838098122262534148335669847478050407756877728672233736962269417,17614529714381496379478130066245111825610297227468263851608027100133421612826,12110694197729365219340374599835523099651939156213930558791147158357810646901,4337343008663255658976574468931581484970687989356019720784093082313510905405,1379188959674402095268172673987199124815512095460112504778179157481327937561,3116148242507754420428768481157196067508084836097458698846114802493377512591,13306507137873332434793374848948087993544118494881134631519748904811343155566,18496878480807017010077624766326681523549495609998881196570603040242554712562,3940126764022508707486095199473913866137718790062498893812401335738707507732,10030078765792498033316282784150304209584388923549357286679864120250994473810,18519871685760382462428068450331593474924737719734568498029727699878543899254,12599428893576891013523136950822667754415283296587096197120138265392279834128,16038578953099895530943034305356008247313649524436132877362941968861459073483,14319233878082524834510736727226054073026413911339853399113450188859080424272,13710161613540579690732775978855380876556751245265568031703536595040993113748,14958726446649273856607176275240008023824615720456760403465034344703779274727,20935428111942360630758629263346308597806819928838924586682307174931367773605,5826394436548487315966647466017047216786257295199620110266250301500717796281,31401797997389676486806123612280306684597605608110075525648021056710776011,10784171495708237485952707518956314344821522727746927291389338644844400581452,11604345371765580191117799693565193618158448665352599382713281103552305960442,1378145039624937931836538950217364481423707761527018494355648047365613434790,10284294167221806561993937798090888689421933711157676807977401896199778472860,8233695574758520342808807499924062869636681352769371531557726871630696672029,6570581391072134029876349038190171593169496519436674767949949730275868319732,4026501263908027819614805027945064360196399012004574117767831931274788631138,21091098569404004244061462065218203986433580687172854429523306262593782053656,20711772916118045406356429185975897495222240215931761100801599257137350834799,3165519312799351250309462589160165591299333587158531489859211268084164422251,16470663723473939739601217501478624726068461799539012562455639586886033078064,15672299304945968727435591100602007503785845873606917887638890765525875123857,21393538327627889838198844493522533627143658125568123117776524944297103649079,7688819203734248199049004650451546300187194458173935784579101984183800649342,6609663518412297884695057080546416278366560290439222127471462938252865438638,3476303650597281786976907813110835564442121684386467570637538230409080744769,20633582549754495054832414039299188930065286005370053173386561254823483851717,18067076834611402459142612082327591538480657933568191619109271502102126814407,157209609820117793892254328219308970217366919934739036156851508233236414461,1848396116513925340973398423998379465460554039715233953825786874352442451413,188642786730195655565401615804782553245486295156304142809552609651873793325,540089254487190924787439362270708251103955915909358626209177199653451469720,12796274768956950589847157187031845061404119522843128177103898080653493269942,1785666356337148874573621868025910291826158842346617719666738769156993598966,20649919247042517528354490854561347316237285929352042389729444382153378749538,9568390566108569727471722677925269460696523515877621230569682954652430518787,8590683334740232786825518158771304803451657249486419816607179533515442407283,9321198393538172042803957409292145345834077448228642847843261373640165958582,3651905214805616378360839954289447530035139753215923648216350128870943481828,1324345422558073117779462079218851558068746895262914344818945294328678893083,6666363895154434021620869731925915051086919707989020578203743660669796175288,9850757893972463103359995012900314323213006625927501272997539940766979170137,10214293226445704940138790188111862069675188797488928722469679760666574484266,16862124085118494177559484642483513597285992646267864845521573612482278871023,9172340118369291059693735314505606817316211450324955429310200429408035954801,1968992755714619414656181112336357119271845800144345284299978250769356388249,17192498940296212027365280042755701662136570107224000496521552617655679821443,10063385968535643122430064779260670089120686456635080613693015398478175344193,20101961459945738562625328882763768836449780661345042148985756598106706734632,12704305975772252539534386080950631076046431529894091327218544197389260775334,3008242816727585639441748210631464697850194693570485141354082562181236010097,7797705698071555811456747812384107102104184812467361013142453143842134807658,19323240331433203844038522035479659453946066968727795017745942269828428751105,1698137797127320576751729191866734754105401103859852376273763815257758421427,17656850887825900397821271738817912328294075224643535784810269137125067875996,20755447986835730799031196367323817361150623932048563112034040627213597261325,6221130271964372280138992636208062417325313096379273438539556580491430711297,11042709376363248213366896208587241517252100440844476816212498352999929578287,987361321094619571176752720390429919723900732295551211263814448408232028205,15077982986114392945859048373768437818569856001604485167476360943078774679228,6278894644165961404521866714059972066255652200107181684047812674333675794053,2649747800006903047073625320829560088088800522557851927539477888486006072675,2636278052351769676017824297717609512488651850924228608531372135635042762078,816232991472315395984098922575496846552245086608787214581606973359616326446,14372687274434205592004117128588852491871014819273428668840779210928924573820,7351401720390274950322621121981079413650308506660552567079785209176949174210,10275293929161727274572318228903710245677747557851999483919909420098936352013,14869686444606195206734119702227763209172799407142930791211203702643805341518,937617196362766626935279232045712623531859540210120280128165029613358941709,21331527351771920568751070369057714014285398281585036009305608379072813379081,4305436470381074948146072259605215282335211631970525440530773004228212378618,5894273721571292784412707230481346442881109207745969297947253583203466014760,6512250441044591603946512492071171861967500633638753443182294740883123881284,20863871952569294813936866452848141274047362082838805921071316386912981651979,18788566662709810970880679984141390717017951403407913908833463086244783373013,7784927597396249543149135503684024377171301321636804832597181795981969626201,13818519831569592521516488188127966399245767953522268350556654747680372036664,10515208647860053151690062640705322684876580250632027862984821874343071549235,797604926079325807488629085866693514275115789253871397971708541758696512985,8741784289526985522570446847275649913333939699807282742190607491216732972386,20966712704043418981047968701828936463778140093909973286855779694780086635828,11359697297415630167449040380538108774924967116147664240213257348125754475868,8070907838094569287067982462230761680706116783989613960066342967469297961118,1868550288036217638713133945402464194193242298015503906068429633793800456561,198709459347510170000840600179608479136663571567208109852828485236018304733,1601154135701845545733926027872374554514541574822026314034696802419388627041,4363994778006302991481199477873248350039564117453810275561422974475581105893,773054378219982710451611471050404495804413666789496412742983455527754059148,5209426340109575519362014651321132459061755868557415513439993327176584352934,16124961412020675839394907565568143713078242978522632778625312854364651991011,20812496670075231301471694692369245988519082317145989298573032859079075730004,3312489967581906638742585802390894285073229440039144559060030129184388053832,2967475373447822846542676378804990140732835322255774209561143670843223463335,19744585401442299381952694102570931935735276268739851233412754166721728873141,20026293345566344685499234599699178313754630774489046573312844763673073616936,2611303659034102517884318354550433047021831422518437228002960700934925644951,6230291832603218406134986471162106408091661326026848531605999413028246206577,9126162046556730019959291776456914453189657463686708035601186672661595109020,18827736146609035067773173111376739253733288103277133456626928961785293662143,2328703958261360872869074208611873245571971231035163763965210852182760438390,13796410059666172174899788866809560044715551934510722965495280798363043241416,1593663256684781552813616365605526150610454082601584196604084376715746899324,1565874145189898288764434737762721576951043839540107044892767693968417810945,8709849304563896945461696717753976956465219721409993781555147204068634555572,2994256803561260177499267243802460581941891553208150783951937342406846377191,10452746656507347152042187616753027475507881362159944564077673851918869542550,20130580998875572619695450234900655050996104101008767761546912649074040426200,18926933358104691474037431437316089682088433006245222723356764715400831411716,3783551594057498940671877156409957274854990650480535806320220142873170375307,7919031943604095374667473717154511882451510130166237539514111182596247372692,14518552587329209714850286012780632801030157943402419401997576700600952906519,4770764028263701271241862755569969531641408032906982530346384375773459918490,10866502826034731763529371496585294375373238783964914673031891984092997621879,4234148117462322266937279401468367908013627589417699250592523530383852950379,10747942066055887965185603234524367638106812660210378090215017248140719240336,2587411532912868255102795810490361867789634574022411742057853375399270197531,17350061113113681344498080520518808976916692173267298878258722510332360424059,16490282364669098969805528215926442920328903121380947471680517193373377657129,9274691782659584680377375192682066090127280485689527337429804211265749864190,7630965482352419767782717986075793694403609453648729580916814032587325374653,9483872310024003776681196467845329825094379763716541754956796450187787638623,12182966986735661215639970080491757244218854808156498220088212871061979325833,1853790963611367149183440339188924598268644281518961106776656221408171642714,17425077915972423995335545370701802959607559878032910147159424242864219303096,14571075346526399549826264845894977639678567831720652860528738036970272895919,5627701855249158721927849603102149698163511782011562166637339712383551336091,3620805686755372260289125555061886982808014642356719556961142525373021656729,11556995641752009899073583627136467840237831247117281278719511600076965602980,18960242154096055221658318882298412299294886669455506299567210308762501113202], - [16789463359527776692258765063233607350971630674230623383979223533600140787105,17179611066821656668705197789232102741366879862607190942874777813024566441829,18653277315487164762584377009009109585010878033606596417396490909822722930739,7373070639853668650581790286343199505413793790160702463077019294817051722180,4823864393442908763804841692709014014130031798360007432734996408628916373879,19196309854577132760746782449135315310664418272926255500908899397538686486585,18123132816088485879885148351452823314623055244145916622592591084094232513914,18436594886553181913092702411547018228276047601279727265790147051821171174455,15167500404313194506503404655898040457721633218143681920692711693000769735187,9437986152015460505719924283993842205604222075968464846270136901243896809793,21445376105821232747280055223032050399373725161014449207033808524504027971613,49684738714301073369749035791061182456037935161360748355432247732088942674,9826409059947591908303145327284336313371973037536805760095514429930589897515,8494798325496773219358794086647759478982958403252584257436898618394561204124,21251937175072447337747316555423152807036003235223125066270735279039060889959,5539100337780919206842837176908516952801756637410959104376645017856664270896,6297628909516159190915174165284309160976659474973668336571577778869958189934,12792263637464508665199868777503118105486490400267592501708855807938962470650,17254685306085558791725544672172906900581495686070720065168939143671412445514,3590396502942934679818900672232030233017710909687947858184099000783280809247,19055249881366445073616526879263250763682650596233071589085239500077496415637,7367697936402141224946246030743627391716576575953707640061577218995381577033,1322791522030759131093883057746095061798181102708855007233180025036972924046,20456741074925985565499300081580917471340328842103779922028754640077047587707,9059147312071680695674575245237100802111605600478121517359780850134328696420] + [ + 0xeb544fee2815dda7f53e29ccac98ed7d889bb4ebd47c3864f3c2bd81a6da891, + 0x554d736315b8662f02fdba7dd737fbca197aeb12ea64713ba733f28475128cb, + 0x2f83b9df259b2b68bcd748056307c37754907df0c0fb0035f5087c58d5e8c2d4, + 0x2ca70e2e8d7f39a12447ac83052451b461f15f8b41a75ef31915208f5aba9683, + 0x1cb5f9319be6a45e91b04d7222271c94994196f12ed22c5d4ec719cb83ecfea9, + 0xa9c0b1916a8e41d360d02e6e2e5d1b98c34dfcec769429c851867e46e126fa3, + 0x1dd6ba3731e49d21e8d36e9d4d1edad245ebf9bdd9ebb60a252e4804a6390f6a, + 0x24ae2a67c3d521c11a11b7112abbdee30647107b808866a980837d0d7da4e3e0, + 0xd20c9310b5c14d9ef12866af5a45eae3ca9be16d200497066c8b2ee96781d70, + 0xe047c9821fe94d55d400d763a66c4c6169993abed543c7284b4a35430019445, + 0x29474ab799b1e13948eff41d2ce79bfad335d09110157076988ac207e10c81dd, + 0x3899f139d0dc4b281be3b74ab4c70789b7f41e7aca47ea2722a20d79afbca93, + 0x1866624f761ab8dd7a91c5f37af5e47639951d5acb6b1bbf3b96ca273f71029d, + 0x13c119f36718f7d5f09ad8541325a13acf6b34db6d9ee2af7ea06061240f3009, + 0xe4a1008158077402b11f13c08890b739643cc8e93fa44487b5a1575dd867fd7, + 0xef505fd44ac10a251b670dafe14cabd9ada9e3002210ac9c3876f37de4e7ad8, + 0x1d31e4e2a5978b7491c43d367470a5a5d1445b6b8129a5b9a6fd238405720de5, + 0xa979ad5428d481cb624d9d504524a9694ca5cb4421b5d1dc6af2c030fbeac39, + 0xf7fccd2ec8bc6ed9ce3682f38aa291deea9373f4995778bf762ade36d6ab2a0, + 0x2691b924dfa123005f7c078d9bf8706defe99c2ba99bd6ee53b153e9fec7bb80, + 0x2077df6510b4860e56b913bef3a80dbc464b0e4678add60dea7a9517463220b, + 0x29ee09d8af9d24ca49350ce2e0aa47d00a3dc21bafbfac1c9ba61c58e2993e8c, + 0x8b292c661d427506b9a01916624f3cde332aaced9f1a494a733cea6f25bfaad, + 0x2583699ce536a757b22e4713edfbb050092c84abc72c90ad87393a1da9a4cf90, + 0x1e3f1b660223d65ad88999475374f6e25fd4148eb8110a0b12cffa19657b0b66, + 0x20f3ecbb37c34aec79131455461259e59b222f0ee8e02f3194cf62a9ad4c3448, + 0xdf4f5088e4444fbf87d553ba62dbda95696d8b9cf6210b1c85513b1776fbc64, + 0x2b348effd4c9cef00a1cf4dd67dd664b2ffe361a807c589a252c63bcbfc6833, + 0x1ba1e522fcb153676cd8f20e82256f0327c000fa96b1b462fc84b556f26a86c7, + 0x294c44df8e68c96144e964c37bbc5766764ed3550aff80dbe9d3fa74419fe50, + 0x313716eec6dcd8a602ca040700498dc04c77dfe2194753c59bc818c1d2636a1, + 0x287dec74696d663e2359f68225de955384d960bbafb90967429a442e19e3ec61, + 0x25e42f72c6be0942311ba097cf365683db4962c8204fec9213f0f8f72c1946be, + 0x12b6881b96654fe1768c242acd5399b08639f081a94896f5ea6da70b6b475c91, + 0xdfc2b54546fd3267d7be55c716cb243ef18118ed9498c8270449bd9418afdb5, + 0x27dd55fe0d5c0ff56ad4890fa029c27c5f36d04cdc73899ab99b2872b28eedf0, + 0xc60962711aef16e7a2ce59f587443ec8b41ef8dcfccb38188adcbddd32f173f, + 0x2edc09feb267c6b586e62fffe32bf5f16c28b585986b81116684b7e8b40d42d2, + 0xaf8386859db252ff295a19466d8d100622c90502137aa1cd4c4bcc9656d11e2, + 0x121f218392f73d4c16abe382102a459e6c080b3ca4eda51a23e651a13a680550, + 0x1ea38273f5d59e65061f8c775c571ffc75ef67d29405b5e02913cb3019d56f8e, + 0x9bd2349005699bcc0ac35b627e2f8f08bfc3b0bf30b146f37742ac1556187fe, + 0x91c505b1e92448c11aea22aaac4d44f6a7f2132f89e91b7f55f9404696c1433, + 0xb316f1c29689d4f490f7fcdd5e9f2d256d443ba14cda4bb799b0573a931a99f, + 0x2049251919a8f3f4398188b81f99d2e2d0e3f5359cfa55bdf3aa75fdadf367e7, + 0x1fe7f9eb6788101908814168e3e4cf7a899a105bf9e584af0064188a4aac55bd, + 0x158e6579b0388153b0acd630ea94de8f6d966d529c2d01b9e9b1c67c1ec1d570, + 0x1994f82f27153afb9de2aa3f4be05c4b2c487e393dcedca2566aa6b7fbc3696b, + 0x1b6250553e8629a5a8a40b568432ce7dbd83c87603eeccc8dad572ccebef6e1d, + 0x20296940a7d1eded2ae79fd78fa2ac11abb2210bf24542feabee71f0d0d7c9e, + 0x2553943f9e0ffce9c297cd31c29f1fa5f01883cc9e504fded7a905032c170c89, + 0x1c56eb362896c2f00ad18faeaf04d577f5feb4db4e077965c38f2eaf5f7be08c, + 0xed8857205e0680055de7e822b6f7d62ac0f75fef67da1ff7b7735208885cf90, + 0x118f91185a09355f9d8c3f556367a2bebe79e7d9528a8d72a592681671aac75, + 0x2a71e6a67abdb25a78010fe6fe0a20d1d84e21cba75ad55937dc1834c13af0c5, + 0x2327dbc05997ce8575680e4b8929d4e9ed25fb9204277d603061986dbee57e0, + 0xe05235e01f21cc3f2971c382d18c14e41785a5ec8d447cd93d13281792e6d6e, + 0x98afa2ea7ff065b2adfc4ab00f3b04496c1e490eab264d2370b107e5a49204e, + 0x27bddb7bf06eaa63419adae44209dd25a4e35edcb863b009bd34ccc4905d204b, + 0x2704406bc806f4ccb19085cb9d3771b12ab5ce7aabf0601e9e06a2bc98837ade, + 0x21c75c54664b9fec86756aa9027261975244f42cf91c9cc0b33c2a62b756a3ef, + 0x2be84c1d84c16038ea5f933290699daaaa8164c5ea39a02bcbddc66cf69fe8ec, + 0x2c970e41d48649cf013c676c8c688ac165563720d1d5f32628ac5b239488a96e, + 0xe1ad2660a2e958daa1f2654b3a37fee60546ca0327150733070742edc806435, + 0x2060ee7fdf775fc7e389a55376374c9e35d5c8763d597f426304e236f577b829, + 0x1e0116818c843ed86f09daee0a581af10d52deeadad77656e736eac08e6f0f17, + 0xa89c1498ef25a383d886bb58424e6940ac399e3e557e9de951a697c54a7576c, + 0x303743d6f36d925e1097483350f5bd2cb297d4ec9239209f63c516b849a67e6, + 0x8cf44446d968430232df175d462b9c9b0e2e2c37e8406764cb96c7c3446018d, + 0x2419811cbaeb3f551b0a9232eee5d53e3769fbcf5239533074375f1b00777f16, + 0x4237c622626db376b774849dbbe876809082f1b13f5824f4c58369f27fe7b6, + 0x1e5b490c72eeb607e114a5cb87a8494b178937cdee34b9e8e947342c14454558, + 0x4265333e59e1a5ff749203cb4a5d1415a72862c61380b1c242d0f32ca15b97a, + 0x189deaf74258451ac4da682532be43d24a5c683293c1ff7486de26d35d982e86, + 0x4ec516b0fd42fa53a34905cfdedaad021b36399d03d8263ae08c46af3eca76f, + 0x2ce1c8a00845a82b3aa1b6642fc988578576cef86196525e6d595c7701ad700d, + 0x247816fd0d34f9d3b396917478605c94a1c052a6ed663bdc344e7aee9686b6b4, + 0xc676dbe6c494d5609c444de622bcf60cf555091a507fce86477019daea987d, + 0x1cb395ade530fc2407aa7b2148d2dfaee30f4ddf258fc149cce3c5cde80a85d5, + 0x190e1494e3cfdada3b9e65d8fe3c1ec769540da023f9ec2e56259f6a56890b0e, + 0x18f2941b2335138336c351a792343222a845ee0a2ea5a3b9160c1d6d9b229fe2, + 0x14ea23ce8b2312e07df57e0aece1da5d2c0e01f757e6a5c86ab5e403688544dc, + 0x2818ad1005f4efb5d554361a29f85ea10940d6e71f38e8369beff3563a660bbe, + 0x23ce3a9a522915a281793977b49054c37d65f90b841e0ca90817bab49d79db4a, + 0x6c2ed2be876309a9b3b44ece37b1c42382927dd04249658a3d41e3f38d5e022, + 0x18b6740f72d77ebcf642b945ca2ed6c8a9853a3749d7fab6051e4ca36f44fc42, + 0x1feacb9eb2a6878061374d069a9dae328369ee63e75a1b99cdb06a48b0d9976a, + 0x1a44ee4565a967647300c75ed2b2543d8d45d5477fd606a356d1073bd13831d2, + 0x41f3b3b5b1050c16bf3d62d87d5d273b067da484679103231ed65a18da9fe48, + 0x1fd958cc4fe0a290bd0fbfb8b8a513acb5898d63bc0d7e585b7d081c49eb5659, + 0x175daba07c5edbf84f09c87a8c34dd73325943a48fc12cb839dca47512561d2e, + 0x9cf0a4e6e31dc24dfd5a5a27a77833e477d5b2d92cff5fc5ccad9528c43ba78, + 0x12d49465bd4120cbf78e5a3414d44c6530bc963bd701c54d4c6418a6cebe80b1, + 0x101b2f2b675804d3b26b2bd1e07c7365af0bfc2edf010916eefb39e28215d44a, + 0x114fc65faba09a59749e0b5f111930783529a0638456216232cb7e5a339736aa, + 0x1dff99b52799afc802c2bbf9b67dd044d3cb51017dc4f88358ddd67366d3a9f5, + 0x290f4496a52dd4dda59edccd7325038bbdc0554ad3a9a0be7931c91062a67027, + 0x91e8704663c516c3b96721d2033d985089fb992dca48c8ddcb97d7d15c7e188, + 0x2dce22599de04196a0169fc211d0f9c8692643aa09728eadf6d50bb534c0e323, + 0x29a7ff0720e170c0e67efde72795328fecef66daada5f0e2ca858a8c6135fd48 + ], + [ + [ + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x2a70b9f1d4bbccdbc03e17c1d1dcdb02052903dc6609ea6969f661b2eb74c839, + 0x2f69a7198e1fbcc7dea43265306a37ed55b91bff652ad69aa4fa8478970d401d, + 0xc3f050a6bf5af151981e55e3e1a29a13c3ffa4550bd2514f1afd6c5f721f830, + 0x2a20e3a4a0e57d92f97c9d6186c6c3ea7c5e55c20146259be2f78c2ccc2e3595 + ], + [ + 0x25fb50b65acf4fb047cbd3b1c17d97c7fe26ea9ca238d6e348550486e91c7765, + 0x281154651c921e746315a9934f1b8a1bba9f92ad8ef4b979115b8e2e991ccd7a, + 0x1c1edd62645b73ad931ab80e37bbb267ba312b34140e716d6a3747594d3052, + 0xdec54e6dbf75205fa75ba7992bd34f08b2efe2ecd424a73eda7784320a1a36e, + 0x1049f8210566b51faafb1e9a5d63c0ee701673aed820d9c4403b01feb727a549 + ], + [ + 0x293d617d7da72102355f39ebf62f91b06deb5325f367a4556ea1e31ed5767833, + 0x28c2be2f8264f95f0b53c732134efa338ccd8fdb9ee2b45fb86a894f7db36c37, + 0x15b98ce93e47bc64ce2f2c96c69663c439c40c603049466fa7f9a4b228bfc32b, + 0x1c482a25a729f5df20225815034b196098364a11f4d988fb7cc75cf32d8136fa, + 0x2ecac687ef5b4b568002bd9d1b96b4bef357a69e3e86b5561b9299b82d69c8e + ], + [ + 0x104d0295ab00c85e960111ac25da474366599e575a9b7edf6145f14ba6d3c1c4, + 0x21888041e6febd546d427c890b1883bb9b626d8cb4dc18dcc4ec8fa75e530a13, + 0x12c7e2adfa524e5958f65be2fbac809fcba8458b28e44d9265051de33163cf9c, + 0x2625ce48a7b39a4252732624e4ab94360812ac2fc9a14a5fb8b607ae9fd8514a, + 0x2d3a1aea2e6d44466808f88c9ba903d3bdcb6b58ba40441ed4ebcf11bbe1e37b + ], + [ + 0xaaa35e2c84baf117dea3e336cd96a39792b3813954fe9bf3ed5b90f2f69c977, + 0x14ddb5fada0171db80195b9592d8cf2be810930e3ea4574a350d65e2cbff4941, + 0x2efc2b90d688134849018222e7b8922eaf67ce79816ef468531ec2de53bbd167, + 0x7f017a7ebd56dd086f7cd4fd710c509ed7ef8e300b9a8bb9fb9f28af710251f, + 0x14074bb14c982c81c9ad171e4f35fe49b39c4a7a72dbb6d9c98d803bfed65e64 + ] + ], + [ +[ +0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, +0x12873658ecf188d299b8ccd568eb14a4d4307c5caa95633dc296f05cfc966598, +0x153cf8033d8e8a15cde2c5e6b93da4018c5954d00a9274ec5ec6d5101ea22761, +0x9f15a882446823fdca6f6ab15dd8e250d90c84470516671afbdfb0de80fb00e, +0x167c655bf6cf3e0fb64c9075773bc862b24b4ce2f69c8ec198add2758a2ce216 +], +[ +0x25fb50b65acf4fb047cbd3b1c17d97c7fe26ea9ca238d6e348550486e91c7765, +0x27f9160806de9ef57ddb4243f839e4b7e8bb293ac176fdc5b5419ed73a07999f, +0x16fceedd703bbbc2bc6f1d792e501939105b044b1b904d3b110110da983ccdc2, +0x2eaa925d06b6f5a77c0d5cb20598742791495cec84593a57ee9fc4c9115ae7ca, +0x279b324735fbc883e24f191ca7039f9986115b9e6fcf4946cf45f08ceda2dc8c +], +[ +0x293d617d7da72102355f39ebf62f91b06deb5325f367a4556ea1e31ed5767833, +0x97d71f1fd579a0d0f436a6b36165cd23a9fcab03ad25e7872cdb09b4a0ea0dc, +0x1a9fd26611128d592d594f51c251dbf4eff6dccecbcf2ebf310e34bed661337e, +0x21eb30a57e5912ab06d18573fc546b2bf3be840d5f5ede01f91dd2bbb578dcc2, +0x13abaf72889b31372b1e6f48759371ef65bc57d28ac2f60e6d227eb008b96ced +], +[ +0x104d0295ab00c85e960111ac25da474366599e575a9b7edf6145f14ba6d3c1c4, +0x19bb8abf6a012cc7b8b974039c6be6df31446a51702b39a8d90ae4be7ec33ec9, +0x11075889bc0dcc9d6f06af3012f04aadcf9049de04fc775f8fa091702e70b9bb, +0x2e4cb25599a3dbf07de338827b28d16b9c8fcab8fffe8f2a16161be6a521a358, +0xc7a700b33fb23fc642e0e8671deb84d05ded8ccbc968d15171182e158684e85 +], +[ +0xaaa35e2c84baf117dea3e336cd96a39792b3813954fe9bf3ed5b90f2f69c977, +0x2b5d28e8d648bffe0fab59e3c7d983a4099fa0a4c548df0006e6d0f4e20206c1, +0x1a96c37c461ab8a38ee15bc2784c5096d30d1482e57c2f861bab95584b90d84a, +0xdbdd3171308bfcd3cb8b8a676592858b8652e902142beb8fe4145002fba8e0f, +0x17ac4855f295a3b8fb8ceded7f4b39290647a0145af56b03b01e957808d66fa7 +] +], + [ + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x351d582486c39726623750495e297970b0e19787b49173a9388a0d5b08788ab, + 0x10e1a3beae297a472a31a3b51514c664abb12ec2d15860a29d2a9352d3ce8ba, + 0x12395fabf1c14664faf3ecc72a84623c1d5cb7b5e5744e602c886a5773e5f06d, + 0x9b91873151f00b299a173a5b736f73fbe2ce543f0b4d237565bd58758935cfd, + 0x1d53cf618f93c90852172c773264b8f49e938bf22791cff829e95ff6942299b, + 0x1a78e48450798918f254396fa7417bf2c5ff69259200c2a8d53af5f2c4d8ba1e, + 0xd3d4c1eb9828c87afeca8ea128d1d533750cf555c6b70d70a8520ccf16feb, + 0x3af062fcd1ca71ba6de0ca4436f1a5a0698a3f49abbe4ecf3daa0ea2e4dc84c, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x1ad1ba4f26d401924b25657414256b59767284a692897ba5cd53a7f5322005fc, + 0x1133694747d2cb4890f4f5982564eac6019ca5a9091b302d2c10b87297041d5f, + 0x1b46c42ff1aa475972e26f559a88164024234f7b392039fb2a2171be631bd8de, + 0x1954aa0a79f14968c817000929e2e744262871011f238d986086e7d9574936b4, + 0x7aced898db99ae9796fc7191a103b9de4c77f0e08ecea6aa593974f652ac4ba, + 0x18a5a098d914f6221726d42ada7683a1605e20217a09489c9b2d84c3cdd2c39e, + 0x13e00cf4ab3b1e028165af8d41019ca20a21aeb40926592a180f9806083eb5a0, + 0x478f72938b528ec79defe09215b46320801fb752ddc88d638a48790561b4e2b, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x8ff43b0eda2134077b96d7e4cc37a6871254910ab4c58a4bcc78c1bc6ce3937, + 0x27d7fa3ab9c438b6ad1ec5a60e8ad91aad02e4d2908ff7192e5ac0cebd91f928, + 0x1e9ac8ae7cf2b40d629999251be50d9771391326a664dfc206f2abec8efbe56f, + 0x2d6b56b4849de82b636d81f2e98476bb6c35cbc8962137b615bff86f8f261971, + 0x21e70566d2f4bb8728fdb3749da99a2143a0d90bb6c1b0d6d02125aa1fe63092, + 0x1c01c050dd9b0b8ec8e5ee1eaecac1171bf69a8f3d477eb7ec3a605b010d4ea5, + 0x282e8dde73a0dc74ee10816aacc1dba10c142109c14ad7954eb7b56ca268a16e, + 0x767cf96b16035a96d19fcc57edcd92e746d226cfe84b733454c7ff9a16d25cc, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x18974b9f253b6bb681f82ed0f2d3e6b4f70ca858468b7f1bd3ded1a581ec21d9, + 0x18153fe8966abfc450a25222a6a27f6175fe851989776dcd2111a5a2de99c2da, + 0x2da1e2e775539490c2fe2c827e65c00e382a4a5d6c49a8374381d39c627f36c, + 0x2608589b9cd3f4c12b4e832e05fc5ebdcb403cd6560a8d7ece8d17ac94e79e06, + 0x5b4b074edb1366d35bf1c1ec1451a36cff351b407a8d30d563471bde491f146, + 0x856cc5a00bc37dd0217920da66c5765dea0644555e35822d7fd464d9eb38096, + 0x2021dde3ed193bdade457c9db5ab799e6b3fca640669d2f6295b4852f54d446e, + 0x12e3785f05f36bb797b2c9f03c5a55fab52e88b0550b7155d6013b706574d41b, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x118084c76d1340b3980add4df3878df4ffc6e9fe26f0b5c4e2f9579ee6fe2c1a, + 0xb9dacae8623c514c622c85753ef7b994d9102ab46620f956c26e9c62fe53050, + 0xdaea6d18a826bb2ba972ae16dc621cb8fdf9ecd531ee3c9f9d0b4012da6769f, + 0x8f2a5df6437e253b579921fc3208b3c176e5a18dde267a4f85b7afb7f79ceed, + 0x6a91d7c75e34fd43d9aa53b7d2793e4d5d70a5fecc5fd5653b162ba2631aa68, + 0x207579e33c36af2d20d759996c313f78dc339878c0a289d5db58b6b3d6069c56, + 0x25562540cd12084b3392c8cb8cda95ffc9c2dd6f8a75054ce16acf87ba871b9f, + 0xbbf47feca60b93dd0501ee0fc294c2a82b103817b4acf0af6979183afcdc87, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x1e0814ce223453b24804a1ab4ce39815e35aed2fe9f7510e6288abb9d8b15711, + 0x18f9aa2721d95963399ae18d6d95a6f81b78b528e750554eb2613d6dabbd72a9, + 0x2ea329822ad302ab8831c559c64080e7ba6bf4c98ea0caf9cddd929bbb5875a6, + 0x29910d86bc27b38a93bca80677a3647c01cb5262ed19cd0c00872925a046a338, + 0x21c0a05ace45015ea895e01d630ce6b7423f3c211d26e8b6ef54d3dfc0660ab, + 0x25e7c463042f520ed2ff8c68be30bdddbd7ea5cdd7a91224bc6a32a3f5c0fcc, + 0xdf5b7e7663197f911e0dcd1ff4237ffdf080234e9b92201538ae7db6b6a7d21, + 0x94d0fcd9592b4771d2b9bfbc2bd78defef3b6ca923c68382650f9d63ce37c85, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x270361108967ed0391a49d4b7cd6af9bdd544e8bf048658c4fab36aa12407263, + 0x18bbf89e7cae93044c847bea654101914dbdd1656483e54e07ae332857821961, + 0x4aa47a0ede64ecdfa83507a2b8947b4b587758d75239071f6b4d3d66777bc1e, + 0x182d30ec988fca803ff7def1470c06aa6a596f56710184909fda17d354d3ce02, + 0x223c27171e456846dffc59cb1a53c761afddf85582e4c70ebafddf10eb1f8448, + 0x7d46dc97554a25edb78ea4d862c48bc5a08e9ea1eb369c5c8c2e0903114c915, + 0x1bf473a2e982e519523b486d264941d8e32cbbad362bdbf736d7ac04c4d2a964, + 0x12277b175bf54c3f2b0a57eb189e77714cf21630ace1fcf44d39397aae5b6da5, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x15c0a2cfffac7feab86a185031f489a9f83e89e3337a84b51dfe6fbb57feb15b, + 0x2b83199ec584185de52190f5a415c1fbb9efd4bb9eae4c4e2763abcf99359ccc, + 0x28601b9940a312c65b02adccb76937ef645d4e451c940ad4241b2b0f4925d7da, + 0x1a187b4875be24a2420729e016901b94ec0566c8a6936978c3f21e8d611996f7, + 0x10ed1fd44722d10bc7e44824e64978d36e68d56de2a465a0201b8e31065d5c57, + 0x2c4b6867179a949d377a9bfd3efe48456f7e70f02d859c78684a3573486dc227, + 0x15cb2c17aabecf7aa0f61655a8bb35a7afd87d0e20ac38fe21a07da7b388dfb1, + 0x4dff03c742111aab3e61f4166a733e87699c1ffa889fce179316e39f7d845ec, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x17baac874eaaa88de70cc92d5a72e00be4ec0e5e99ba7cbac2b0d98cead394a1, + 0x1dba338b4779919a2fb22ba949a050c85a73983d5ea4752cd73f664fe05f6247, + 0x1e33e7fcc41f32f90de5771d69e58f4486290c7b856becd5cd967d8e7739f719, + 0x10877ad7cf0652a2ff93977d3862e3ffb5d87d0c040f02a4f98612afafc9b604, + 0x115d3675856ff59ebcc9110defb9d6c70df6af533d4b0875d0e5eec430350595, + 0x3d74b961ba9013a874e7bcdc782f478da6097537549db7e6af4702ca749dae5, + 0x2563411e29867500a8fd18e4eba3c9a2b7992e44d263c29f7e06000f74887cdd, + 0x285501c4e0ee1b3c3e6b1b29160d6ec0f1af4dc2f36a4a1e654b7b47899738d7, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x209194489c86891b179e33103a81d969c5c75e941dc30e7228c04ed8ba68704f, + 0x2c7b2835cb79c29852926900cc168b2315aaf03a89532dd9fc162c2f7ddad845, + 0x1df181c420308c5b0bf00ee21c16f248edff686e9e835869d1022dcd4a8a635a, + 0x1ffabdffee2481d8cc1233506f708d9acabc1d758bb99c329142c866ef4c7474, + 0x8955ed55c2bec07027e4355a694a9b6ae1d9d50126563b29d8a074ea65540f5, + 0x1ab4b24a4db7c5758471846eb375163e7587791417cbc355b6ce93b64fd01da2, + 0x25a3439d2838ad459270bc633164f3a68215e11217eef1d605ecfa8b1805c609, + 0x65240d63179ae83013295a8251fbe17dd988ca5c84761ccb6a6ecb2bfbf02a6, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0xc1a91ddc1b24113bf876a2ef895c3315cd1b109cfa569b79f3155ee12b1c564, + 0x146fe8e28539ae36ae921069f4af83f675f1b68399efceb18989cab5fdd36ac9, + 0x1ba8c3cfa46425412e30790090980db139810efed7bdba7a38adf75e1a0d3641, + 0x83a58c9d889b74e66636bb8418db624726b0f1374f59eafb4d269ba1ed234d8, + 0x2b812a76ea526ce18df6032192ef033541aaf99d1c61839a0edf0336142a25f3, + 0x295f6d35fb9e57a50a5d913600538030ba8c09e021c16aa8634488cc8eeba645, + 0x1de69ba07e3b9f90c87eb67b1f64660c71befe5138061dbebb752296032542e6, + 0x24734fa363e52c64ee0162a86578ca899796e89caa1a3a3533b0965665208f59, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x2d5fb67efe93e8386fac071fe3522be1dade9dbf1d1030417a7b51e3122111f4, + 0x19522e9228feae7473e317fd7958a021a0b042a81b75da6dbf7568b857afab75, + 0x2bc3f6f0df0c7305afe83fd9ef0b708e129fbe889fce42cb695b33b290479342, + 0x783e5635eea0e623bb8c406909f0db77ad4f9302d4828b51015d6512818690e, + 0x2d61b243f02e21edaed6fd2e4969ddb95a6d0da8db17d115a9a3b0d8885bccaa, + 0x55e1a09f4bd4809a86e67f99279fc06ca89a4468df1ea25d76fe0ad36ccea12, + 0x17871eed22b0cdd2de61e55ba5c9f4e37da63ed0376420bb1ee7f077a0d7a85e, + 0x20fd0af1329bbdd70d4d835d18c915d98956c5f0a4252cfb81c1fe02fe130091, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x2e5b840ca8faeba6ec3613e22eb7b071d9633c83cef659ed96b2f6a8fcc6b262, + 0x5f5385703edf7c4a388ce585a81fe7cc92ff49e900b5601865a352c61d6b111, + 0x21e83ab5e95d369ccd30cc1c55cd5844cb1cc78ffcf0c8bc91c9c0d9937a3fab, + 0xa67b7ed9c37946306ac525597f1275b30a5d004ca50258c3d992284d90d724d, + 0x214f52f9f73a2c2d5425c9610461303d839dfe71891489c376c2ea3b5d868b27, + 0x241e0d267f7d1d899656929cdebd850f70ace216d9ac10253ab720bf40da0c7e, + 0x2229153475b7a6b282e110b10e8aed1fbc2a05a37352e954f40d85205fbd8bef, + 0xf30d0b7cd8ef10e895cdfab3faa4f4c1a61a5f4eba688634540619c84782d2d, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x265589a340c71d49e1660d3dd43d1869408176d8b9110ae8c369078de8ff7aef, + 0x1bcadf844bd1a2e7f4f464991dd651b9f15630c94977d35ebc3e85801252ac2e, + 0xc112b1c56ea288e8518cc039fe050649cf40b7ab98de8fdbc56eb7ef6bcfdde, + 0xf020b9ef75af8ddd505cd3947e11a04270be15daacbfa76fa04d9005283aa77, + 0xa426601ce9415e666acbbaf2a7cc8ef7ef7d07538d84b1a53da24c19c601688, + 0x10a1af65503614381fe2003123aee9008ab97d69739dc462e72a8be04594618e, + 0x2d792f9fe5f0ad658dddadfe3893d158012d84b3837b7415e188131595b060d2, + 0x2daa42d04e0b62fcb3869031bf382c3b9f8a98f7f5bf7421d0b63c2598f5f65e, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x144c0395157a1bfcfb5cc4187f271096784dbcdbfcb6a28c31ce8a06f908c0ac, + 0x1af8cdba0eccc83c16019622667527645e94c9ce64add4415df7f40446277a09, + 0x213c7a7ad6237e7211530c210a8d6f46a25bee433bade010591e6adf42fcd906, + 0x224f1ca24803c0119ad0e6c41a64968e064a83f5821972f2a5c9d5895da4ea42, + 0x10944d95ff5a3699efdde41ead13344937e3b1b93ba73a1531246ca4b99aad2b, + 0xcb2508b0a3395fabbeee5286ce5f1839c006ebbc09d94f475924923d8079ec2, + 0x284a14b1007ff6c5c0f8f7d8d0e4b19fe2d4a7094103912134b0f563a672acd1, + 0x2bc0bce43d55bfe1a27eed426980cf9055b0dbd42e8de516e77580b9d9a9060f, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x28e9b1884a4619b38b6f8a384368c358b7f210f3412c4481a26ae296f73c5c72, + 0x2123ca1f119a35e7d4e1b323fd2942d12ed020ccff3a7ad6b65af90457f00614, + 0x4aaffb0ba008fb9a82fc0700beaab2ce39efa895acdc280252f01e31035b8ad, + 0x1f1e16f8ec9261c82443b9b31cd908015e2c2d2314629a22639af1f37e1073d8, + 0x134928ff5ebe5e019214ef937b7f7a28248285d583613ea2bedfc66b5e2ae924, + 0x87fc99e11e63deec9d55047ac98030c57a4f09228cfa7749a3e1c7ab5f212e7, + 0x9429bcc52d6c43814df5b07fa116f8875299500a36ef791b592a64e27cca486, + 0x2267b1dfa5d26e6f0a80bc8b4c0026f0204bd4fd06c7725544d7760354e401f4, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x16fb3cdb76d21d3448c9988f428d198c8e5a640035ac2caff7aa7964b34ff1dd, + 0x80dd9d263a6698479df06bc98fc64594478028b61047ff93c425b29b092d37c, + 0x165f4f2d302a24eea5f46abeec4ab03d21e3d013865085e515bebcb2684af340, + 0xa8a3f3abf28f457c62045789fdcd302f0df1049b6ec521db2b7e72e8d9516cb, + 0x2342f103587a005c977578b12810378f9014bae831809cf7ad59ef3aed48aae9, + 0x1d1308e311e7ab846e158769c12213013eca377f396061aada6220f29eb1b7d8, + 0x2563949aeabfaa782be07dad903ebff5c913893761b75a3f8402a1e2bea5a998, + 0xcb371898d8d2e1f5bbc32dc21782704a73e415e0c9f6387157b48746bbf6ebe, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x1231d40e7c6fe5bd47010ebe4f63d186369cdb6e8823aec194093a0b4cbc6845, + 0x18943696a4da551747068255f57a0437ba0ec36ad7e5c92cbed9c49a9775b97, + 0x1fa58f378160dd4af40e3b01bfe32dfd34f2cdca527973c194a53af30bc40670, + 0xc976561eeade533c5579041bcf5e8272e4af95efe3af9e5372250fdc5ad8966, + 0xcacfeeae1a8359ae9fcf831f315a4b8c576d579eae86b1b09823656231d3bff, + 0x109b0647298eaec354e4a155308192b5facfb586bc2fe63f073cd221a2106fb4, + 0x69d4744aca289d123baa0e6754c5232202dbcdfadd0ee8d14dd19a7bea39781, + 0x156195fe27df23b8184fc58a30e1a9bafcb9cc9fa9ce071163a26dccfb7c6ad0, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x20fed35942cbdc86df51a49ca26055bb25e232a42476ef06997af8911560fc12, + 0xcf20343957a55345423dd3450c2fd74039f1a82c6c02446dd64c4569d31471e, + 0x1e177139b05dbe38a56c40f919dc1f07126bad03049fc4025d77b4bc34c25ebf, + 0x144d1944a849fdc2aba8ab2a4368d57911e9614e3956d9326ca493c83050e932, + 0x162f08d305fe4f1b0a9bb1acf1223bde3405aecbf2356508841b85f1180cbc1d, + 0x21d68868502ab599c7c5f2a54d65be40ed5caec1613a98b2a98c5f8117415d97, + 0x984adb0c5263193be4027c68c6f3a6dbf7e22cf199dc4358b52968b0a248789, + 0x2883f3a940a8c10f7f347a8011b0f0d7f6e0a4a82eff568fffc7524235d1e4f3, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0xd89a340993be3d3ba07d2fa8432d412730e8ebf2bbfacbf9378c0c4d3d1e692, + 0x105e4a12836770bdbab24c85e7a63572c77556fffafc8f55a0e3f6e7383f7b02, + 0x4b09e851bb6dbbffd0780af3f99cbb707f5e8a073810b28b1b59794c8b117a8, + 0x2c8031907c10e1df2bfdd2589dd502a012a2292202e67954091ca57d21906d41, + 0x88a360cf4c5e26faddcba291dd2553906abd82fecb0ffaff4f3f544f672d703, + 0xe9e8d8ba62712e7f95840b5651f32912e84f146bbd57c566c178084cbb155f8, + 0x38fbaea7dd737c642ec414759bdeca4250d31d6011140e7e45e86c12c6f6fe2, + 0x96dea6e0d6411dd0c18e516511b03d8506c4901c52dbc2772c3d47bdbf461ab, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x2d60fb66fb133b0507b6b41ed7fbd5278c4ba9fa0679d2889da9672d21f07037, + 0x2567f444cfdbbf4d7799d5b50c8c582e1d2038a11969b3eb2b60aebafb1efc7b, + 0x2401d941b4fafe3311bc6cd9fb0bef62ad9b59e731c1ec4e6b0ca5e2c685bb2c, + 0x28747741579283853ed4e6525da70a4312769f7040db4f098eb7d9214fc8fae6, + 0x1104899fde3f530cf99500f20c4fb9d479e512cd70a15def442a4ea92bcb9743, + 0x4ddfde1b1aacb33977d4b3020db51b834f6197a18505e3ccfb37fa8a3a8764c, + 0x2bfa6913d62c8aea04ccc3e50229220efe3b9af6a568194ece56c065e3cac8aa, + 0x5cb914ec7b72436cf25adcbd0550c2db3c9c09aac565d46f96ac156fa72a90e, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x145dcc8a89ffd8fddf4e5bbe377a3b7649ab6faaddf5eb580ced3e0421b7077c, + 0x21f1b7c169a0744e49718346cbd390dbe3287f5de3897acdaaf2e4bbc1f3e80b, + 0xeeae34b5e8e48d2ba6bd062c803ced1dd1165cce5f8f0574ff7caf4e6eaf6b4, + 0x2827170c30a7f570a12f37aa0434e01a4aed9b5d37f1815029d5de89a8ff75e2, + 0xe328161a29c0376af526c8004597fbe018328d6d0c89503eaee36f59a4cee8a, + 0xd6617ff29ac941a779f907e749603cb36778fef6644b8684fa40055c8d978c6, + 0x169506e0877092fdef32109c064d251c4d6a50257ab9c032bd79801fa23094ba, + 0x8c516740479e1a852294e8cbbcbf83b4d7095b69758aaa9f1a368004dc1742a, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x281bcec4cbcefa9e18a1aca1dfeacd7f7ec527df5deb6c002f541ee4c0f2bcda, + 0x13ea58a6a82bf43f6d4c2619b87da0ce760410b68b77f694685e3f34ff47b86c, + 0x1ed604569bf581c71e4180d59a78dd48e2103006ac045566e44162656c36080b, + 0x15d25d19f8fb93c9272f10ea525e787c758f98c5bca884e6317ed21a292abf6f, + 0x1696701143abf5794f370a122fc60dafa4f0c241e8607983222bc72d1d8d1439, + 0x1471c9bea5d880676ffb53255487c1af57a0476b77eba56204a4a3780b109b50, + 0x1ec18e953909ee6e34dcbdde64fd6ae8b99817ffef4811551a27924b714cc00d, + 0x89ad915c65eb1cc1633229dd97f098a2f86e7ea44ee6d94f3fe5f08682c807f, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x7e3bb22a5d8f517b12b42d68ab707d809ce83671dd9a933313d251889a9d55, + 0x142b4285cb7ac7249975ddf59d177aeed1a94e0412002d83861ce061e3f38621, + 0x24839c6f8fade0c2ef1e248f64c4d81e324caa4ef4052916a31c5d1da484ec43, + 0xac0879ac864dc7bf40955a3f4a19cf37846fcfa9289ae59c8f8c7c174c5a57e, + 0x44832eb1eb4ac43192406deb4a37ea61e2d110468762d3a31f01f3c6c1f8208, + 0x2b3f948fb289860a26e995d14c6f8aba2089511c7ba58a310e6cbcb533f2dca2, + 0x118bfa7e2d1386301f187c1b1eda2f48c0a03de15e370b5be0f431a0b574681e, + 0x1399fb352bfce7874d22e0fcb24553b96ab59b85364c0c3c9b0135d4970c2349, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x2f25d0089300da1d286c5efcc9cf22d095af8f615b76cbee09b9ba651d737311, + 0x84eaaf7a0b07cf4992c7d05790c42cc742a7bed021c48f614b988d99f141e3d, + 0xcbb53527ad34cbd3c4d59504fa47c87eb5be078155e58ac3f1e4b3f45dd1cec, + 0x14e8e0d80d2af6efd3cc60741cbc21f6da3a42e2429322bc209097b1d22d26b4, + 0x149dc605f3ad39d4b470a132191d2739df2ad19fb71e067f6ede3f9da3172922, + 0x1533cdda4fe346f0a3e538172b8d5636d3b4b502047cb268015b2088f12b9897, + 0x1da21ab47505b1ed4358160f3cd24a01330718bb901beedde8cca37839805c62, + 0x130eee6229e6346096e121bda6bd3892aba85c363deda16ae8c8efc6ba721b18, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x1d0669bb3cb83ad8702a76855510918ef300df2416cdf04a83061a915a6fbdeb, + 0x113f0f0db699267055417d499467b7502e23179a0c23787b7e8130967c95080d, + 0x28cd66f5e2046799405a9c14282070ef66fd409507971fcbac16032499bada61, + 0x230173d8146362d28c0cc9bc2c72a64afa7741b77653726017932821c1dc9502, + 0x4b23de911f3a1d3f32366c35a7f293837e1e7e8287b8abde423b2b3ab81c187, + 0xd4bcdd5ff441637f977dba6d523ef1f6178ba245cda76e429a91b0ca994db04, + 0x93bfbfaa8f3a8718603066321ce48219b55558f33e0f8645a93a41e6f4d3e2d, + 0x24e21e25f0b3d0e754bfd0e91e62b5fcd232e756ab34cbed6b4ab709dfca551a, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x146990fff0e10b8d70a4411f57f9e74a03d2ac0127b216400b82c8c644038303, + 0x1ddaefaba77bcd9c5ba0671b0a34a4cb37b7c689bdca187d90212f188ba4a87c, + 0xa7c37e8eab27e5edcfc3d6682b0267e3d9250fe470980956f5e3e5993ddaaaf, + 0x2d81f6984b67d7cc74b35aa9d673878f05d517085812190798dd24a510b8d6b5, + 0x7c46458e45e15ce1338bbe98ed3c0726664d8ae0c965bf0fc79ae31ad04a349, + 0x16dd83567c7289d8ea0e62df8620df74f3c987d5f162b6b0a24ab09837b5d2da, + 0x21819b9d78ef5e05c535a83e7d709f80f3ab5e8d733146139015ec4e34b29f1b, + 0x2340a29e4e4d4e920f39a6a32149b54307f918a2e179e6c7288cd02834c0e44c, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x1ced784118aac9880c9fbbee28972453b36abc3d967b20e9b0a886af86d64305, + 0x237848c6b0c87f794b30cad5a3cebfe2c6c9173f7a258f4ea139252338a3ea5a, + 0x27c636aa956756d9ee04b355abe2fad8d703b1721fcf73b17a77751813c8abb4, + 0x1b40358386698e21d43bd3950c00f81d6ae340eff9ac0821a213f8fabd142d09, + 0x695487b95b15feda7188ab9bd8072f0edfcdaea2dfbe06596f8c037bf52145b, + 0x1df336831b6745c8f22a80c252ba12b24e2bb1e7fd3615cc96145d898dbf3220, + 0x264b7a66fcd41995c19f021b71fcb1abd59986c55377a82ad92e79a1165e58f5, + 0x208defb2122d53224aacda9868250ca3b39f78b13c9d150a14d75a886a1a42bc, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x1627fe11fe92ca5b0841cd804a211151ca6c0d2706b2a17ec17a7fd224a48a13, + 0xd483b82a1ed0d6788ec73c257cacba9738eae7232e365df112b15a93459627e, + 0x24c490612a1636b43f902459851afb3cfc37d71db5e9ffd247116d5cbd34f9fc, + 0x2f2d08c8cab748b056307066141837d5cf195104459a91084768548346c8593f, + 0x42d3a4f87d782326b0c097a03de01ac1698954c8f300af708fa79a92e84790f, + 0x2b064fb3fabe9deb1593d253ecc7a12fcfae3193e8f7e16ec563876f92e4c62c, + 0x22b8060d8bd295c3a201655ef3891a481e21748554dcb7613ce6c0a532628e5a, + 0x1526148f85ce610667aa96af20059f0b02c8a9d4d463b27f0711db72a545503a, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x12d2a42d255875bd671d376e499cd79393db48c414f967d53388f60b4e180986, + 0x22d0f27c6767b64adf2eb09ed595e2f2c211a3504a8de66ac01991c81c0e2669, + 0x1fbcdf3ca6f2e0739b571248a9a994ea913375db065ed255b5eca3fde587dc91, + 0x402b7640d18feac0c700cbea0d8f527a7c3fb44a110c4d7cff21deae9a70e40, + 0x27f6c76f1b519e71c3888f1ece7cce4e0f99f231ddccc7798a31b0dee0c68206, + 0x2fe908cd208699c9d8e3b0c09f5c0fd58716d0eb50017aa7d12df08b53d963ff, + 0x1922a59ac83c1e2821afccf1610aa5fb0b3cf8eb3fe3f4957bac604c177fcffc, + 0x126fc5609db3cb254a05919034b8a7f9a0f85ec5abbde6f85068607250ea0ac0, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x28db35e17bb31e5be954d69f5bf8f6838651bb6f5c80f750b6b7017643b6c28c, + 0x26dd684288015065728c5e09454535a33e1537761d874102bd4ecd2baf40b384, + 0x1895d33a312becc17090e45df74981b4fc4b220d3aaa346c7e8485311cab159d, + 0x28bff25eb0f2a5c6d007a92a7c4d88bd9c12c5622d0ecc5a509c404048b7b5aa, + 0x130136f07c7e09acd49556f3a6bf0739c9efc0a1be738453af67b31e845c976e, + 0x259c455761e6b6420dadf3d6b64eb65493f989fb3e5698e7307a6d6075714ede, + 0x1c9ac464fb08828d02006c7529eb1e8f45eef54405ed2cfaa133bd697f618929, + 0x60abe65207efd0fda7b24719d35018f7607dd732e71c05077148f3d046dd180, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x2a41f347b5f6eebe8969667071926905a3e6e521b85a89006ec2f500ef42b000, + 0x17840fa3a180177731bce340ffeb5a3b6a68b94e3f870501e787edc5a94db63b, + 0x161ec94c3f624f928eadb0e2f2cf6b16430fba680a5a50590d89005a688d9b18, + 0x22d8be171b4571fb5b773c3a548fbb286b06e2701ce99b7630866e1bca6e2cc5, + 0x52464c9c7ad14525380aaea9b06e76f03db8edd220f90b03a9feef2fecfb978, + 0xbdee83b20d91ff9a0404d8b0593879c90f7be5a95a22c8e1b157d92c3cf4746, + 0x2d84235b4f4e04262d8f246123b8e631ad51a4e1051f41f1c89cc42b61717302, + 0x3d6b62f816bc4b464e2971cc6a7c1a585e519266c4627b1367ce7963cf93d86, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x16caff6fcc165168b3ed958d3aac8d09f98f670bdbb847ec0e9083a022d27692, + 0x2cd4beaac59c5306bf76ef7e06c81adff6de4bee730cd4676e966db45fc067d4, + 0x1b11abd8ee736830ffeda3782fc7a82623ecc5afa92c0ec9eeec58177ce8608b, + 0x2c80d3430e64bf850c9e10a22f6b781fd513af20d4705435bc870ec8cbe93cee, + 0x2d2f20d2ec0e52eec9fc2d0e49fef7a2454aa77a5055ebfc4d4449e8f83bd015, + 0x1e51c55a8d7a04be4edae4f7dfe6137e96370ee2a4ed459ec524b19de646e0b0, + 0x13d4327afa809e26c8f97e36ebb5be1d3992ec72d459760bbd25659790738f43, + 0x176222f47d8c0ff9e8a967920376793dbdb9dcc3a79b44fd25e1f43a755e6b81, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x5193cbcb59713c78012ede93db828e69336a197fdd30c6b7d03b1cfcdd6adfc, + 0x2bbe660fd34f6ac3f2545cba9f717d2eae9f8c60242851657f8661504a457c69, + 0x1fe59c3d2724f4158483406e6cd62aafa121c451f13e48ab3c857b2293333c3b, + 0x249c893f9de208601de45c9769ebad071eb864524003add0bde31fef7f4f91a7, + 0xc20c4a12bbd772e0dbb929b69b24751da26b0fa8639005ff786a25ac1a5fe96, + 0x1a0750fb1d27bcb326ceb3a3065a487cf7d513d8954f31dfb174fc5ed95ce55b, + 0x16d40c0ba7a7aa232eea997d45ec4f0567fb6814677b262aadfaefc91d409cad, + 0x25ccf860fc7237cc8721aaf1c717190db40ccd65bf65d108b16f851cebca736, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x1a25b1a6b81926e968ffffa63979c900c1e82452c986ae599ef991ba214e6f67, + 0x2b344bbb50400ea76151bd0b68c3139955f101c701d32befddcfec1ca72df25e, + 0x1044e69af594eca5f9ca7ee28cc38d161d01037fe223412e2f10838bb9ffd1e5, + 0x1145f6f783af7d1e0ee3388f107ccc27609bb8314bce27b03dbf8d02843ab2c7, + 0x20ed7009a6093b160020318b0bbfbc9a9d14de64a3aa25936ddff0ffe3a3bc4b, + 0x24cc5ed4ff9d84fce95c1508e1c7852fe60a6def592f423bb79c229327be7627, + 0x1fc31b0e67cdf9efa9c0c312afe54b5158ada1511719c76953587b772f1c830c, + 0x1faf997032cbbadc0c6d30fc804d068faeccbdf7cc90155395b739e017081259, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x1197c402e5f0a49c8f9b9a41af6fbcd013cf9adfe864613c1bdecb6201d9651e, + 0x3025d698462f4cf23c7d4d8a3eec4aa8e1a2184a43020122db653afc6d0deb4, + 0xecd1d402fafa3602052ab586f804ec15f1910542f35c608eb7a247d5a960cc9, + 0x30021619d0c0b402b429d4e962cc3c2a2d00c62c131144f7b3d7f8acae6975b8, + 0x2bcd05e889bf0fcd9dc4f5faf21c506cde15c316aaca47724e71bad0cf34b27d, + 0x1b890b4097a781900b40d9c1ffa06a5e8cd05ae8fe52e040db0e7085ca46b460, + 0x8081b53a974ee264310b279468093218cd5e5edec1b7da6b21ab35622242e48, + 0xe6632e8ec976cefca5b164e6c07ab40ac611fc723e8d8a14899a4cf4be3b2a, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x63a3f8dea9d024a6f6a851ecdb21bffbfe259ac17f6793c91e73823a82f4f76, + 0x23b2c6ec9af5d0188e75baab9990f663f8e929bcdac96cc09c4c0626274692a0, + 0x9a41c06730fe53d395c602113f1607fbe01425190d50d56e9f215658ad128cc, + 0x16571048fa92024a9345a0ffecc159e76602455a71bc7e9c9c01dc50d8aa1d6c, + 0x2a5a7e76dc76ad78878b3d3b4c74995e2ce77bc126e4d17db507161b049eadf6, + 0xa23738e129c11b285d81c1c01e3f87989c87600727e7593af45607f98fb18eb, + 0x2ce8d6eeaf4d6c7ca0922c4738e81dfba227e98fc3ed24e7696ebe9c2732a1ff, + 0x22e3bfb13d10368cee5175f5e2a2cc205d28021caf5fb2898de2389123178a5, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x66c43e71903c5b74ee8e90ec30a1d8cbff7d8c85d3c7b995a976036eef8c4b7, + 0x2fe5dfcdc9335f0c0dd3d08f4e783a5ff6c2e6fb7e2928840821e6da8d91570a, + 0x9accce03257f967a24c11ce718f21167d9d71a1cb60a4f50d0228418428300, + 0x224e2a85316b67bf2dc64549c505721a7858438a00e793fe76b961bfbfb67291, + 0x29f1447b45128f5c1cdb12a334509e0a991c0d2c9360a5cfc28af420c2ffffe0, + 0x1301ae5665bd3e87cb647f566ebcf2f2eb5bec4b257a77061a15dcc7b8b34abf, + 0xfc6599ea957e02f69b1ca585c7135425a6825867d0cdd2b06019f3c9398ba4f, + 0x22e91a30a945b960bd87d7b0d8290dcd5f5b1caa339c41aef323be1ba9c724e, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x1c7c359c26eab655aa469e0f9a8cc3d8c7a8149ba9e9baeca9233b7edddd1d24, + 0x1ddf651a5d396b680828eaea1f252625db1988504765eb4aeae3274a19cef175, + 0xab486e3e737f40898d3fdd6bab09213c0056c2e090a90acc754574739159385, + 0xd0b817b8995913e3ddd08b576951bd47b45f536739fc9cc782e769fd17e0028, + 0x13471abd3a25160947928376fcd79dd5aa58672f8382745e3a040c2acb464974, + 0x7bff672e50ff1f20296b1838e5270229a7477110d9a7fb56580371ee4ba38c4, + 0x23f91ef1b8182e80c8a0f54c3a35ad51cb9a3bb61b07b3e34386f16f7f4b32bd, + 0x16c390b3fdf09c6c42e50b66557532cc5998cb5a8c15446d31813e7b70607ec5, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x1976d21aee74f79c60d44e46029a5b04fc03ebfb9bdb09a0b5dbb89f677cd296, + 0x56e7cdc08bff8d8bc12dc72af3c84858dde68919cd991bdf513656eb0a0cfb2, + 0x22b7992d7c0ed349aab7531de2f12da4fdcf961215ba06f2b7577f5d42bfa85e, + 0x10f97fcc757a0d6d0d4e2d585ea5968b3faba9d6458d16bd366d081ab65ae95a, + 0x21bc046c3d727baf6e65b568653a398aeed8c95b73567feca3884a051ac001a2, + 0xe757fd0b77219a771723e071c9896062eedbb3da05cda25d39ead3cdf738491, + 0x1ed536c497ff36f612f326f3d03e97d30abf91605ba686af36ea04c19cce4f4a, + 0x2491340ecfed3f98ed6fd566034240e64a08e5a39a468c78b31e4734a679bd67, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x144b73c6f361a4c232674a08616b36c33f7bd667dcaeec35530a2e8fcb66103f, + 0xb244143540a248840ba5fa161cbfb2fb2dab97332073042cbf8a932144d27b, + 0xb5bedd8122560caf5a9dbd69f82f7439543bbad397d7cfb4ef7782f64ea4e12, + 0x1386c7e88c5c0bf880b28eb2735e221c2a88e7f871ca5d720c99b4287c528a67, + 0x277164cdc5187613b0a6d6450b56cabfc828f20dd7d07611edccbfc3d381c9ba, + 0x16bc97ee1ac4b1cea8f96e731dfa610212aec4a193015b94b0f2a1657d41f13, + 0xb341e4361f31734af9951c20a6aace08a3dc80f57379add9693b56b047b3480, + 0x263a060ba49fe4862df997994261e665c0406642c669c32dee4ae7a153fe1dbf, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0xdf811b70cab32c0ad0aacb576fd95b23424d3686d79e36feeff21d1aa047eb8, + 0xafae979e41c0cf7d662b4cf09e93dca70c0945c6759c4f8d2c935a6084eced, + 0x21ae12f1dbb152c33213efe9cdb6044574b3df8236be92341131435152115e5f, + 0x272fd8955a7524a09f77c28ce89d58caf7d883f9e4503ad6a37c0eab6bcbe468, + 0x3712cabfab0f6f3d23ac7beb815226883f409d60d798242c6d5e9dae8178fa6, + 0x15bc41d746b14885ba93dc7d00594ea2f174b3b3dbc1acd774335405c18b154f, + 0x9dded6d75c33754be1c1ebd2dbed077c1f1cb80938f0798bb2e25b054a52962, + 0x1d9fd7f273e141e48d7ae825a6d7758e351d80c4ed50139a659d52edff60d227, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0xca2cbfed626671d6e0f2e3d1b6b2ebb5e9048c2f1273223c34fe599429e1f2, + 0x1e9bb2efac004014858166710da5d764ab36b80e4e97500d784fe5cc2326fca1, + 0x23f8af81b77d2f06d566eb0d9096c4b267f498f92bac69d622dbed85bc8a8ada, + 0x11546811642965c71b3865d830809b7f402e02d1980c3219c4bbe48e8bd37811, + 0x2b872c434320ac521ac1e14867c05d88692de6ee063f402c28cba02adeaf9c51, + 0x1f80e8d09a04ffb20613cd83ea35fc1593f9a5d8db6c846d80dca53cd4ba5a94, + 0x117c4e17071565b51a2b97908f375ca0194dd595e9e873e8c0a158b59684ac70, + 0x14da94b9be3adb3c5f7cd04dd5c58f63e74245d5a1e6fce5de3d093d476f08a4, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x2ac96264771dd5b1762078d5132db23febb0d2edb19c7b24848d4b654e9ce670, + 0x5a23e8be5fe8e01b11d0c7a1dc85c909602604b15d620c7a51e2b017dd63830, + 0x172623676d3d38b2c68ba2b30c12c5818d874d83a98478cbec0b1d27f5dd7ece, + 0xb632ee1e8730d509691580805b890371ca2d51bce083faed1615a845481de7b, + 0x2a220ef566e4d54373e1a095231c10905a2f5e72edd2b6259b46ea45749203ce, + 0x2ebf4340ee05460d8298d52260b4ebae389357bd857cb638c41b2708cc333dc8, + 0x27e873b1750916366d2e7906ffe4f42e6dd7545bf534adc73a02b7410f7f8275, + 0x1ee70cb51ad6da4513ce42ff200e46dfa39992a90447f1004765711f3f5ad52e, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x1021282efc84669e4a98956e30ad0043c6c19dfeb98d6d14bf027bcfa555f8af, + 0x1f1c2e424bdeadd277162d70faeb398d661225414a975a59be613e47274b73c3, + 0x1a71e415abc5ccd5bf268130070e89b1e61981cd54f6e5864b8cc4e1d50bb21b, + 0x29799820e28bb9c0a7bd0a2c6d6105e5c91f8f88b2823da7c57825067214dbb6, + 0x17377cb0195b95b473606c81a6bd5c807b22870afa6cb230a1048e9515e31db, + 0x2f73cf9f22e0431d5e7bbd907ebeb8553b4117ff1fc50d09fc7b75935ef41251, + 0x19cd57e77a99328260bd31fb993e7bb3fd27fdc21b2187fe3a4bac0ad664719c, + 0xd5ff1b6b5f33d6d568d9197d0df40d07abede20ae3a94a0292c01c304012713, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x26c7615e04be2355af0773fc0e025f86baab5f59d834ba005e099d95331d61b0, + 0x170ea6732c6d1b2ce3279f2d4990926fb8d279e4864d966ce6ee6c319739c2f5, + 0x2f870269a506f351fb0b9a9d677bad1bbc5e6ab40ff0afc1772f02ba395fdc8c, + 0x11986790a1cc239c92bd4b8d8a1b9baa76e1e49f847f16ede5f6398aa83e97c2, + 0x2510c2e5a39cd6c243ff590621941b221d2a2c5a79ed6e5bb90eb1008219239f, + 0x1ba5c05a828609b93a7e151338699af0b8b0aa96d3d5cc9e7d3785333fa03dcd, + 0x8648c03bd03b5f4dc3868ac1c47363d90010b9cb19933554fc7586b97b5fbda, + 0x69d0c72c5880618f66ad58d65f09e5fc488697c71d92135be291f55d496cb7, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x91acb34aa0d03afd0ea47c1d56965a9051b05eebff9af71e07c4554184f462a, + 0x2b3f75e8ca7118776d9676fe058565eb99b6e99bd23505a8fefc927e17cf5336, + 0x16d9ae82c0073fe1dcf35384c0dce87494b2400f9027ce1e64ee440a439fcbaa, + 0x2a11becd9333eb48f3027ad8f3c24fa1a0ea671a1020278ad84c863c322e8057, + 0xd569be295d5e44ccffd9d3ba84aaf6a0c178e8639689aa6c57214f00a6a9d90, + 0xa66025e45040fd45eb136eccc63e2d7fd237aae9b62e2330aaaa0bb44dbef48, + 0x2cda68234c7e22d8fd725d952d3c529b6997b68dc02065f6a047b6cabdd29e42, + 0x1f9ab3e8029afc72f56af02ced5a6b145ebc81444ed12e82c7ea547e9ad23650, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x18a2e32bb69277e0f5e82c2a60a008b3db5caf3c53a669215c0b3493b73c7138, + 0x224c4f2e98b4fa10d4ddc83f26ada461e5b4f412f94a1eb153be707470746fbf, + 0x1b2a8787e954d981add1b123a6f6c100a609e8135c0781ac9a1e7e326c4b0f4e, + 0x2da288c34f32d86d5dfc0b2dc9891091d396d36de9f70589b7beee769a058622, + 0x2e24d351b0d0e94f3e0f83eb60f2d476b8b64dcb47674290e87b27eda7f20180, + 0x14af016f9da2f982e82aec1ff6ee809445db2c6d85382f959508a31830dce9d7, + 0x91aeac9bde9ce64a54cbad523032180c2135b51ec4547ebcda08824bc9cdf9e, + 0xcaa07eac62d9f07c17f63f749b7047eaa1adda97f5716d76f23affd6d845dd3, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x554f06e31b164d9d7ada3e01c4bbf452fdccac121ca787b08ad50dd2928ed42, + 0xbf8f8d7702b1e8830bf126dc420158a624359067a0f6385068390b01d176601, + 0x1604d181baf488dce4f99bf63c065ed934ee29f0649af4dcc9ac2a2887e8690c, + 0xac951e2944f7532d4ddce72d31c8e91c0795cdfab82df338f172dd9bffdae43, + 0x24d53d9f665348c12bdc3425c2b83e24fbea3b66b0c9d119146ed5d5a1d1e9f3, + 0x1ee01a89a7ebc6b8e93f2ac2e60b9909e3e3d855852e0e113a72a118f56e2da3, + 0x2b78c3171a3c8ec6231bb7c208e5b7c2c90a85956a7f2a1f763cb6c883059938, + 0x7ca1e306d90787461696fc7e4a3938712312494329be76c8e2b402cc0d617e1, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x1febc25f88aab92179ac3cefeea663f51562f6fc631bb236c04f5ef85b464784, + 0x1b1b065eb60dbd39a34da94414fdfa4415933a6bdba5c2de470ad8ccef1b28fd, + 0x60fcebd24cc08503ac4f80c0ffb87d0898f34bdce41420e84d941b5f7d352a, + 0x2a7b16d282447357a66d83fc5aafab7d3edbcb3f01105f193954c5ed496ae165, + 0xac39f59e76b9e296ef53921ae0436ab01217493f948bf6eca12b11ce46678b5, + 0x90b38aaae1df1873784a8966f1f62b68bbd93d34b0f4c637e208f9aeaedfc26, + 0x1ba601baf813cb2d40ed5674747b9e3d5760143501e0f21e31a7dd44b7135eb8, + 0x17695ec6204f10059ae5ca72c1332bc882cb7b4e161accd1ba9ef760b7365d5d, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0xab5930a06bb6b9a78e664dc5308da0b64d1e09e6c69fa583bc737245c5a469, + 0x16ab9a5de48bf089fba600dc70d2790ce0e8f79c1430566802f97fee43bc4e2b, + 0x75df7d5cdb7ccc175462dfad73927bf5a5f465e15ad267930c5ec846f42ae5e, + 0x23e4a7be74d0f0930279585aeaa432b5c28a4a2b21e3990aa45b5092f08d48ed, + 0x298795a8af97b8b3d378279e60b276b95227e66d74e2dc66cffa1c495af98c25, + 0x133d1455b6ea278f4acd91c65906bf75f2c90e41cdbefc2721b1e96adc5eeda7, + 0x24b722af1967cddac6a1745b71aca7bac72d436ed464e2b8ce55aa2ad5ff3502, + 0x276cb6e59cf4a06ff6775a537a4b04c6b42780c9c98a51ff634804b23acfac2b, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x1044b0ed6b39096c0ff4d292c18632c909d1519149139b1cd192de01485dce3e, + 0x2dc918abffffceeb34cb17a8cb532f889d7dea98e9ad2686ef8e30936ecdb03a, + 0x2a5030937ec5690d090ad8b3d897541ecd187d2ee126fac5be6a280fbd4aa465, + 0x16961c105f85925010e0fdd445ee840dbd3370aab933ccfcb6e4b24a8826037, + 0x17262da0f8e41b6c42707dfbabec1d9f79ecdfdd25a32c2a640d3c5a4a3e8770, + 0x59935903a135cffc7c5e8cb06de7a0adbc6fe4f66b07a74172eb65951c6a345, + 0x1ea2228bc5f09dadfabf025e3d19db3cca4e448e60f2973605d2559a27b3bff8, + 0x1e35c4737f19de2debd3760ddc81e1f5857a01c42c86f4e264ba323f4165d5ed, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x5958875cfb17091058a7e29cbfe20d0d242ecdfbd3635279cd1e0c3a1144dd8, + 0x19fd165b2741329dc18d2a5b03d7b58eb3dcdf2c2b0870731a924387139033dd, + 0x11cea375386801203c61577504cdc68493716d023d116356def9ad9825be5887, + 0x2e911408231ad83ab40e44e28ee0b017a82f7e080a0d4bc1b42c52e9205ed13a, + 0x9d3f08c1d2cd4de393b703a7dd94df0540c91b59b288df6c1ad8ba0e51f179a, + 0xd8bac92c12807a3fb4b20ec11e083a88b953070c08c1ae9be28c80cddb29a50, + 0x22829b774491c0e3add8e7d2de8096cb55a1009ae9ce983b80c14972bc68b84e, + 0x2aec91a87a1731f6b2f534955aef3d09ca7e2ee2dbdb5e9a0d15db232557c621, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x281ec503552e6778fbafd7270951cfef153fcfeca0517410e495c62b81655f9e, + 0x98a3183f2ee18973943856c28e0dceb4392af147ca8b528ebee97577178bcf1, + 0x794a78e51b51af07808b643ed37bad31e6d6c68e5ef3171dcd06de598c6c29e, + 0x214a19348cd7cc8b1f985287e637e7987a3bedfa233f98dae9774daaea42fce9, + 0x130acc584954a9048597bda6395bd25ba02fce56102928cea7d5a6f520683ca4, + 0x1d09e1227434a4bcf72d8e91f5419ffd6da212a1d1ccb2a51b03e80aa258243, + 0x127397f2b156ba00d83847f03dd242007faf326271d0e2cd4f6dc84c961b19a6, + 0x971a3d373d35db8f181e0d7b26c33cff17e533e8f560d844694f853e7197e47, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x241c8bcc463ac96e3c1cc240ce83c44edcf9c781e258a2dad09d1976d9dc6dd6, + 0x1a0b489baf0a182599f458897aa340e57986dcde7bfd34738851092a75ae6e0e, + 0x102c886ce6381276fe52d15c51dbd571e94904a8ec4d4445d457d596442e443e, + 0x289f8a46d6792691caac00cd43dde74940f122c0e5ac202588349c2eee473f6b, + 0x2ed1721123242c33f23f809f6e431511594c10b0533afde3304ba62afc55f5ec, + 0xc730a9beb7b64f090a39929af4901900e772b0f817098adace287cc20dd9e84, + 0x480eb2f48521f46f5049f8d9d682d6f4060ff6c4190b2a22c40c27d0754b912, + 0x221d30bbccbb39bc23ffe2c8571a8cd1763cd48de6dfe21d7d8f2805db1e5066, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x22eff0bad54cf4f8fda9e07bfdae36713527756cff255aa481b730bd286cc90, + 0x220c6f4c23ec9272eafb522055494a1af4de6fe7456b39c5db851e1299b7a86e, + 0x18d66b43fd01a9cc88dd14b1b5d6c0d23b29ac28775ff60d3ccf36039de0963a, + 0x1f62901537c1c56f671fabbb4fc31fa743f3236c26f9f5c98ecbf332eda817df, + 0x130beece629451200a3de22eab4c45bb592aad667f9fc6729842971d4a802fcc, + 0x24411acb2c9c481c59adc41bc54fdb0fac658ed6e0b3636cdadfd12c386f8c98, + 0x2370059923938a3552819155a8b3816fb90cbde45871f6c122c190a27e7fdc43, + 0x217ccb823582bf7edbf4a6a64692e37928f2b02d79b43775abf304500dd2da46, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0xe2be5d3f9ee73557a1c421fe42cb29bdf8f4a58679a61496bf8a5a4f9bba3be, + 0x27639d7e461732f3baeb172103de2bc4a26708623919783fe54774153bdb59bf, + 0x159c005b660c7fb3551cbf624aadcec047ce72625673c866c5fb289f8c865fff, + 0x130d38734b549e833b50c550a90580c53248bb96731c0921ad6373316dfdaa8c, + 0x13ee4afd14334602b6791a7b8f49c4f4979d485b8d1b1119cb4a2a7c31a74f39, + 0x2d2647b74c63579e81a6270afc73e636e588996745ac0499dbeb6a7cf80a889e, + 0x1b884086fa3c4173be0fd5cb1c866c87e0f9ae4c3d9f1e3df630cb4c2fa59af5, + 0x2289328b5db5b2b2d00e76ff78815696e77eb19acdcb6c84279e65fcce29d15d, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0xbbd293300c70f612c8f5b7bcc6c4106246d2f713df02774a29742c31efeb4ae, + 0x278e2893fbb5d590fe623652e50086d58ab18d3015a59d6a61602b409252ec2b, + 0x2fcc41f73df0c835b0b514cbdd469af1e2b494f05269d15a6343af34668b18c9, + 0x378097f57525674b961d42a2f57a937c1fecaba4c673bdce345050d981b8fe0, + 0x15a6727e6f181a5da795ce173f1889e07f12892e13f889c4f8f6c71725ab9f62, + 0x1edc3a58673d364ba5906c3b39ff7f654c5d42f4ff94e6e75d2c500842846477, + 0x1aeddbe743c87ec10fe447a5d08ab5c73836eb214ef95a08ce91131b8e1a7f8, + 0x286e544456f114ce609d6b805b31064ab65482585699c91b9b3e83a75ca386b3, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x1477e88daf9348ea5f95cb08426f4285c654a897a2c4895333052fe2cdba34cb, + 0xc9918bbd089bc26c937ae2e0a92a1d8c87cf4480b055e43831a5e6a3acbe5b5, + 0x283c24f7bedf789f31465682347ff86b4c0fbb7f9aacbe5630021b41532f7931, + 0xb1e5f0ca68bafaf026438a4682a55c1df5d387c4c5f3e111ead3163eb5b2754, + 0x2d9da1df21f14ce401ff84b99fba07311a9da3cd7efc200695ab55b1233b9043, + 0xbb61e50ddc0821f0c03b3bed9476f580a02157b6a69a17f2afb0eff5f1e2a37, + 0x21dc1358f62ff3dc24cfc896fdfbae88b0074323dfc7b36d680edba89c470e4b, + 0xdc75868b6f7e6ec9c26221637eb789b9e4c2b892ce81b527c7da05627ec2dc8, + 0x251e7fdf99591080080b0af133b9e4369f22e57ace3cd7f64fc6fdbcf38d7da1, + 0x8606e28acd8b2ee4c23a757886d7e99e407d177a58fb31b410ead7fbe1ef272, + 0x2f70d379513ce458231a8ee6b3029bcbbb4860ef48c104ddcffe65603d81592d, + 0x15315ba38b9e4c7a64a0844985e7b45db39eaec4c63b490cecfb19f02e102669, + 0x2a1529e4b1ca0cee97cde58af1536c4823f7e558bdc13f774e4ef3ec8454675b, + 0x2a70b9f1d4bbccdbc03e17c1d1dcdb02052903dc6609ea6969f661b2eb74c839, + 0x2f69a7198e1fbcc7dea43265306a37ed55b91bff652ad69aa4fa8478970d401d, + 0xc3f050a6bf5af151981e55e3e1a29a13c3ffa4550bd2514f1afd6c5f721f830, + 0x2a20e3a4a0e57d92f97c9d6186c6c3ea7c5e55c20146259be2f78c2ccc2e3595 + ] ) } + // noir-fmt:ignore -pub fn x5_6_config() -> PoseidonConfig<408, 36> { +pub fn x5_6_config() -> PoseidonConfig<6, 108, 660> { config( 6, 8, 60, alpha(), - [9174141306060971809979631725764298697615039980311809306145004207410652431953,4847693924685156250211477469465516228032151306221739650606132660616428517315,19669833054057639609249840291533340493211768292967819468538893000195036768991,19800508893433268850924828171290876015556093796000695603651522426066333836892,8244699449852279148780456022144420353408196866113049322676048275081354214716,1563672068712965454176533719400672258364596155638916268717470967009721945171,12723223712027468580318230235559705540011996847167975439677647504573149248849,19944398841194165937952509356635863229327574447452745793253427406349161295763,21218058308392585368594275702746106483411305671883946244077923955757637296177,18442884961885927579732373746933397748806426938144021013884176466434407012116,11138408360119814115926439449668526422561003790198269766757675305576549475808,12724564576884231109847024566806896391934587839830522481308995309797961575379,4897733190252075532660075013731462724561461746919488679609618967302541674417,4797748331306263412471031924618974997396620231469532262170060449304337691527,8626839560132907403537141283531395025838110825355541158539075100658769738351,6096293906324574249636975851522292408228519044739444932687579741964974917617,2351617695830568421216396081605990689071283678701192113347036659596049514149,3045682390398203085155257535118136303069379656645406266260961816947178911890,6935829264874515341379952008241845470659188886156484974987865751370715745075,19847439266968955911971997829840067368072860877451092633069920565944933744280,12795097343831149148337906863235678514689648096503928066579129201713661539889,10424580232112390318877053133877999442988769389050776486274146627765228950235,11651452649618223740363812212607761589812354035139843126315028745587570714609,21307929358023177131550002602820591970791247513576735567457471459920519084552,2579908580162153663820021562014873149811195641589016321720930006635393981680,8198198178555784054784079137247244121807775986273563786249987394640289859893,17176088986876377315956611075288620878117708836881362200541916957398026761276,671389874397910339333118510595007038137908096657753354622355890021074216004,19161949137729278558310070194809106779119877882343914445178348849980058405327,10827554013954037091657804154642286174226562252063767377995268439458401752538,11693672899474469123468133710607776304784343543318650064064636202512816205843,7026547767612627656560992117440221331093280829523426249915938274837157551621,14422968137896343032446633683271253661000603582016449215470992885331170459671,7685352543184863430081115767111935982586458632527708735083385591291346555502,14089009391529192464370954954330128327830078875414722902347666490457756695535,8424161061743752192085022963953944100289245618074575727145394775891645849043,9809236779073852557054640507912802523501426410996355424610807253990040160483,14100245203768962710288059230665566265892855964739454261791429988929622355986,7775683622333704945225255741567928967674629526812606133980425422182282014012,8739247215686497264451630351996892836638898510934389758205488381695687859658,9431876969679115468275053745264413939426444105271849398322497961102606290132,257914055321743732506701382989022126153391940932933566664491918941925247878,21801414068435960590201256257290267142214176965736081788536576642934903066059,9465495933537134443327560834432669768951376466867005153580146079082722525723,7862366214258716333873810314803222267215825847232397599183717032713290878315,10701164906390193792620967030790214270231326273599373762943959252633779929633,11951628827727068395937910010248864431667047516686609553745879936868276916066,14268744039571470490378560085356767818183790841094115879980723591887874138419,14468215915818797151199796266933432577607248341385185700017147731054148927023,1523824033338639123415809477892820349580561577160869448927791050266158538520,13559991428776910947424645696251487328999214391124402586267086012691140984198,18151203063828433535061866995346135260543721730169485344610433976436663085882,13436242600153492361692256644258899977135098134175123174795293078081801647137,9384556671429507406657070680351030238568956203341356106463890924933167416522,20321079285577981781556986944841048777999006905303986053275199507771332527205,13510502130738135726695195328780836716597947131948116750163533622597187969844,20903049289119144354363108865308751668897757360882852151457514926552553533040,5611953645512225417723205546533389174830971368309601830751921473015551069534,8816886019615642422040038431962872654062471314244185285424018745071289038220,16751828354835345790163611999302863949792305206769993810746019449909446216365,10421654749141018171116296259626916395875529220250947127973888230084671091757,6065225315766552671037285757918350882361743810888619479819895087632281975681,5737755346739850738724717271213687543479332312420206954339242459110768587128,14770522272891919220644639305274656491731294860310497013287297810648680944682,2777394791070450473479179489594969793054480209411136328689318984981401732197,10039559932930709555975364107098145624058027439566384376771787183526929807647,20757756003754261934858081777796652436155530474748550156383127600004580439167,13253166894715452480712170898662712132411702335275401581167208877688374856806,2037004052447343668129085129987646907388123739343356363273464870501805506884,21829471491172175426560705585746893969222010633542962882847909490991398830669,5130395545419191392223692116621486075405299333195732914002649716762739787586,20333821730990393095934147177227294218344864602777744425090741435432040213391,13629653802252084129446975515814037702423511189484562534040643669977716900228,18489091892360842692678715136565494502607711254719045543684163289077857041829,21380328601365035012832876315565064374684993115210423862017233170195286906080,2280052193465635727584791148501382679094142036232980037838088033232747821762,21415541711468815972744677841317235994302058341802530962394281077076174148777,17146992672828650459975820445250769505470616910596779130798889014378635881076,21676475584514120109058208398560066698690773910598518925936412952356431597439,18337052978997482578725645166749278142628133291693686105612531426715865276143,14864089429815580405957698645045711801464462794754089671996837547347950054532,10834607317840698149140890207826430113987295440254355899459691878793978994131,1157143498448645320415276909137008396665083714591338741616893578930275511205,5027542104048754930085470328670427788489455916338375169351586496298129661248,1922685817237874482932428650501872692326329693528175054457715565489676406535,3071473720617798005831658342971536643616129392641449174655528578463370685788,21091078808046042460442535848913779439792606439995062001271357804782672390627,19773167374024045118471391738750949555178717045037157435777574972149053404157,6418695831178793575992210834992785624340084513619644969535805236049937971859,6317875495482489567338519005308431806047606843913867465201005132273298011425,18001249545956637376455848019549801116909661454019565655561439372098476761813,15530167556609139699164228289904946047951254183080358784988008899829027775935,8702757129830652230304011519426558036441096750485189115358314568895250616455,6369986882953061252605652398893489899416599935424066958291402945530517772170,6842894437627604179732847187262933342846269043996061072487488027804029200046,20951621154051947571647917571547811655800779287153833018533872651413529893817,1219277535080749134805291725937516331501172121638812333911793209536894469364,11704605822590166851511022757496386950530399074796545751042566537118336773236,5983427701962592508775640503988144495847156070437130549832329402380170245893,20169091361583397776908351163571343158517532527313940288212943504015977979442,3347733015762117176159731683196584632702931062411889821726902331981723958255,16217509027282489850987935065936382820558307489954122630844029918951230268972,10781269196927764524006466217779648732772805761839205677745819812868343369087,10568911823766972365218731330080733630028238366288098114239172953421915095075,5568774544682750792074131352530555554984876659733959079036284517928264996437,17854353469028651373397049175548228061144941710027186166132671198740388767529,6573034112757039329551886086829829282007989555105157401271097204633906940776,14069627287078359391137554212536883450595451640858724555679971658981340584258,21119713641590541511025673864154852875977162278614553796484277752677323191505,12802116677235410441672624559825044917295689876859311183079161588690810005363,16037054471696658545113065872215787085337497333273419984439267709950724531124,11698654309680908244303850432833183602706804558317993513795996394673734185716,15147889780127043019188099948246961619198549928908180192590946633702778981583,3657342516407201801006680507925024451922115018712017224805778401726428603983,19776786467141868744713630352693556348834540992018636838044610844396164981103,7980994848490005281733955776875257044050741738176865989521982608944874160873,12415191330803073018395217955802011585094769098717180100014182475381600382452,9300986814650530426668152137665814177758578011365736727321578452726378799933,4412208980274764197258090802604347599791567698589180187154608728755887977460,2582317668924231956058541757507620542434237159213236485179804217989764223164,19860814395849792324574773787600734118308975251437485131415273418632757301303,2765909129639570206766170018363951893338720647679193401532780051354569922989,5402210382809272147099442645489124829067576777592680891367494969197685281513,21011104174655621871977821285307554463403659856745964274018020456838460357574,7018364707286303918877589672878574811337524823085078243421192184715151775983,136380103284908296988715215087018020601815024625535396780012012453684253071,15953315437474610448052466140270091879233956524793052736202793153707558909889,5912305909658884889781037379491781973092020933879206417274479331390062715252,21575635295587180789566592951559325743281772394055590203112195979769645712827,1541325805478255472079288730846072146731241030100908414806224735345400173350,17207219201921814683730773200330679841907450967511507012179337438654141678023,18266907794578843029196926509122804272900478710738403531664855427655744759655,1204224895193276222782842236712348692319665277014183965830735736728887994581,4023246588034712778784328407820569751989619386134504404739514704773521558127,9064437981037864995763386367268294611921404895425171966596873454090899491243,18733802217274421976148972926716884457128521840010001893311936746027998476583,684088380644531080099595788833220377905013807951051638705160997709156627273,11994830816367980341637110785269531718699655485484715851375754143223090344544,1831724566362300629700078416489434571462666430381219293205871349415506993475,476710745682537342427691635955087951551678644045621275039835625280220347951,3586272766499559446129476613035465343616602918105042144185864609818186807939,21220348736799044560439132291243370111879983677197111626309132298278891334631,13683795063599185801186093771702503913590598475095473714851383723199050309401,16118007386401646906425171859166434660243697555307927508268622819509657450614,20930641024767526790605168032291665313905337763598128831404465184891980632233,8098646212401100552303711812039666794078834386731698810205195111722330322418,11585783577173465460243373201831086724911159484415020913089605532852648999143,6939053275662244505087635417541857793206828446247848992283188764105131966721,12798043540382494855660472922674138947867597503468216532170157050160462426199,20713389801600667412553956346192236970217099413304167366340548074880917096741,8708207547232102069057776099666995672015399188924281674772351753887161579745,16016293152251662056020528248861487281148011452459422778601663166015837379163,14324897997637439510797191208789711173129460994362368408063402682894248793270,5652996184880208428967511742390474289004021508049280419259474250332590598159,9877106633097964013050071703002221796318046172981334418310092241450453368579,5385816971548914185604875069230499528103133871233951354186676373318036241822,8683091293306949708478955451280670950858818602696102489349595054818146782362,16854975838650963077652189417311897888852709425835763860743171659164792100482,2485160816649177905834265823672532710299580013309324666453183278408904845122,13571692148185502188613896013359942531817915076247598483272449919094247957149,11899399615412173136098732970606292047945698835588882297719609812145308198009,16827672312681684936590464376780346837611857292837989006980972390576065571472,15588237822592586948064701827497915157359094833395277985658706133691498343174,18356642512438827417103800170157877145465512961188328254773957819312191285168,21642368145757804795143182901389223409544979732781450480847315495418822041608,13104082060493963869934085622104709047787444250961437496674916673804812287386,1561532086277971111804773016487251313460788916643968126116038406859074212104,2718320602791009266532615731130512762296058687816604986701989820504700684864,6182683520717583142027400659687593712743548729948584058329789905227082638908,5757242145794370726637363237313640925174531077560764545993554185332488520899,13688467192244237790806289073845563960119021610896694359815485764764608925981,12528461541936459922472167643986446262977222390263675720335825628163511159437,4897268894447399415795897967133432014527122426051771866816059363418177665482,764332419588242767884018802335623760055144509861323437945071732931233600264,11755468878196093893190753985692714003062307843033761257593209352165323938879,6006022813561851182403581780143813226749481175437001910923100661321563995672,13901542382190510449243772206670622017835690746895066410475076631498053123535,17648853891656481911225897080296737974064729032668806126284849597245044343224,15106333841965710929952896897521673254279668876709612770907537801609875568099,20899315415025260484895459315726322363345188136910564549344894025053466430346,1409310408943258102775009950750654615881913956151269414096059752250092035807,3899088673345731523976816322438172722785832982334214339521575164464706226294,21406686765584824639201351330529610299177537976609066339927938099572420696135,9121591670793901722224770893633585291275002987585289305307167711146944200595,10711764678410479049841945177317023555168593838022414378232020467195337241279,6599257303974597452501135281719536074294806740553273627128065549267140155175,2142616913275380526921597026822750992917222975992774063376747381991404337593,16361086527663411948363284957489078505159658832010445114438602510508720771278,17122647864721668762640781848678028227021534122268561738445496382823789619088,21708018685042482318786273055293241752114005312590172460099480713746031274624,8303630654111760473056607545365338851734309857718959193970615705292826806179,3658686547507488906491014260011151850549759409901579684176172268581462329020,7720024124908065424512743488999250878143598904717873371853608249805302871508,8805244918657836956533473437651380347005779399042661429698187314657501156241,6303681354794120075893215838935586592706844702088252970663343726024171795351,21512507181643408509426104627003618425209526633080701556628608990726677651135,11835373417333287523801757951049679177935522717858158305516568595764125190183,13059698839045014411602727811400239840163533672024084777768305507840091151855,17635240655824524168378284083397931667938326555447077097306236826752492079430,3374412791113107178205006579112630099131939030015047870738873452427211677886,649711083340882271985565833699379436167716866997851102439037906608755280128,20002805138014565226408902156524463368767807620908543995020210484077706418135,11071355197960433041624284534649121637702414580710232237233568479006159191217,1105441595020980635809093220782460032826849883993030969714432603468135735502,9652765957610682812348919340146799318537766051849796416434577860126024594091,19248299650856496267902926731608572596705132576830681367365128976226233392929,15285802367070100569572399512275861017714681455564415244982064571963339715277,19970416835730683993734843405673457882587154729456022607061085470691843864556,1017865638757684714433500504002748241987153668285974836527484933462490771227,17284848056169793253916338792235498052654877955690514601079806604278964099314,11718277105372928962350331838305733149270432706448484259807630484543527733952,6670793378364949883511003949124179112275066568088468958915163969545409700112,17088789393958965094855662340742013087397643056458490270185660553870734946796,1930788514812600942005320214284180860980345276633471423966020111188605196111,8844343159753729614645407314580317697758296041737296276765583948670245312842,16657939543606018325703787748629433167511611178952563626096990460124133990109,15333343644239485619497914931918504163396626751908652058758135581206765801100,16533875915742793452819179569144271760125646811168930162441077117553849625884,19679534317472082858641184998487299940737032844519038845860980362664393659234,16385719932525604857740698205965045007053424961009717093945644387917936681719,14490521084213123170781774542655088188106794646066074998587858678154251198444,6386781978322405984893078797365492485297499058328348606653460996474947075858,17508047533433736707046937662428611868296556965172642086594091783148965906980,14904597000414815084666285064575232635645852687797347860862157463159487771060,14979972442969995336727018758631782107138089738395941038626891064816880204567,5299243186271864957800928637599294208954109271450189950375274196644046222516,16189884555052883188473617525411302750109401983487269295700675997730645714379,1645560170870292006287241616671417605853047420339675073261660626733726665673,17866745974872498136933906591373095763114066893081150553715211393380040095383,5744849574386643500716045532645657520001448510343827372577217716983339773799,14021966200238971589811034967347517039341058556783068950884921208853167419283,1201178089866013320759085637098781870734315826415474628546655403142858044361,5875644793836087035760988842421852197052681650818034527831700615895391179258,10875065950479466897559006840696567433921014267247530366235539292597441428702,2221662399199449388725697795500999209427453463134383582414172135385907744785,9758513532658579204941116584445291102215928928145103503086996542188799521709,20879593323317766577775570558015407573466986714590017262168011643343469361329,17225846522404915080676699509636264825833159640824918876741681229188434930856,15189442986691997434021855855358620506645387296294217783597931695143376252483,15973617135551858849206811241799666696907820418171736027820254766840973764431,11888113439449420418408437784450952639345990804839507528208325036625374967083,12365920814385241227394825974928370916184942218042429533600397623369545597697,11966175169612449906889690852332416255478894176917636726028104087408060623141,11163554022908212145274813635928762748847331295589087669583554722521180712379,15273476004030808005186443499782264987539818978741159793745891769358221570633,2013969196885866182480519514425192091338553670034650196068995589691938248955,5008975446746271526106846692137145404766553748264648461545948417006052208130,3926749194225734582453671614337621250954608160208554883789519551411469033731,1635544156808471185144068767649088695307748439189898784051754434524720057896,17144944482517962143604430553750908864860079758005337246916094084534304051981,13823503533305241872793740090687668844401004819859520464168798913603662683770,16335911272023134851779534303717879370955813837529588982953758998930285394340,14467284210444150699969889681308566002886261365990840091849371665183151060295,10578205764525658336257882813734672799527733392763965031628376897794294290414,18771425328697137255453620743509164311086906349726510394566012237817674245865,21804626093983212038528370352039806004465345685985435415809095637323683466452,12056805308954301132385034564357716323176447186932453788072119595595483786736,14307195735327805282612857510308008767450554777122724855715789120735513378827,6848201070063637295416045855906784325422580350462489495889308309540335269587,631364713487758647973016689203003205602593076699875191323345338325349259049,16214655556434201961140525501007839859074077768660052713461045928979956365067,20940788212183642266181811368870506130164462254923655617893660245551698033523,8257440848494309435270838240795567828478627302119374684511017376568090372435,13701089242130867705897643891164147923878521147124165292045879194108024940909,6895272953337895406509859406973110417619874994579965619097329249292199573333,530437169778092455975584310016745919549274205817234464915791595041990209639,9008612822403008353420189298381046023002474279157557733428254452507266389025,14863423501786052071018008300345884780479084379412157784789951872243409629758,20091026239041315645045502002997446404106877721183777765607724358538559881231,11103877261161399045807234470901399725912406134008627937945079980590775715243,21529163495181909351665093277427712610965764606448489357319207727176092439794,19540446772694448035410067193880900774391072899517686330271100773183944540294,17549510450820803306426739851959754252204444648959723652883552677325100583689,12252518814610348662318155253547558779974557529822012236107550517806390105567,8058115132085119666951861652409945532276905989404523986413207631657437321956,15916100116790431839835734530362130437167135501074855072245598938219364570910,14256533476494466694764843270015662315303617568641801280831873052211753536970,17865471381417606502707639037418669122823481329049436020149405646709537112534,14015711483636570179335132940981982618090553643653746531174110949872682031017,6075776171664976866533080327142904134938121198707020111533599997509054627652,6357981809351565370498807027309828058036389418343890944791766504532174516243,15145296985037303761634018005118672316118004891352906450983918852209191841446,2473672396516437070485250176897956191104549656554290725379242542480862701754,11059085933391482002269653121188853142706883316754376424538662772943167665341,14804069155713123448375113552227724310276294677318593116834685772120057819258,10146378656966122923223443263705119557842694560695035707977826044606938090895,21828309590915152213768434346306434851424116996828875020020066586363340244814,15568879616082229996551157805731419126872501425454775741945679993142071548779,17504079509060638501918729619244098692140123800571022969294759717277257664716,2998311560047298465700351970612785742605093777116697796464434026101441410385,20229972737818088327107446854254558628041027965197447598027135778783710740259,14884874200763033520375899992902136897590350894844904733314191389520252900641,9619409751736964504139815024141276029474791187139050183491749032619248817404,11534029087676783672833531415041588991838838078174102967049055562568798961925,17106297093375816944137015955705541133308466659538554159312635106186252148471,21676736161168806529097919794022110433487869702564846859065695507460463414524,12596447704589377083704857810305080195761099125652005594925931498073219198049,310943124066162607352831846280730445558498286205117614171844835745706684432,16013029710570597613246104892930389004941711962070683476555063566372534206859,14282564976066063966062366540992448474634085812789771416509095817495183298269,20757241092771652500911491636894210910134068426068355089789205706892703219255,17084251309147907751212619949757520468224028014308500329099194408342072624132,14680350698112448759886861002622963534698534998651150537754386791270019720748,17739512731440543100681958009173086667000199263945053345384367808940651002571,8967486063900234709994801661246451094429250620940593387993430620369318619734,3906067814916986286272005884942051451306945488494283077675304366798199289520,2517004675157816404807349457307096161030587393097616279110332574293494030636,9995302877359286298434340810356550712107485295049220989690824504445305103587,12849909876017357260683411536833847986127911582040960825577300322066595609115,18074515800779889507358182860997188274134395074469953155084226981497567860114,6692811728183968363967959295970424292426462800383828091752006855360167264617,17859827663908740084792157440799065184931609649811664442236242315795442091367,12243409340804252499520308602187370739653046835019551522661290645230850934962,3009118420068966587115224335717185828292538080040896739662684632413054772046,15856202298588272962175258696610233941787471472716811521132004805327415486141,7549804594729480554341356998842376772514802673462970334329441043324983960866,6390806437030742378988258255983502109201709511321162596105974797942236431761,17370236522182003753669946647208335160124999930136364231371998757664000198520,2261672244214630177095236704932243497157963117166120717011661647779055001646,17325026196605130064689259977831126468940872193987407658419640959345091161632,3631641025220845885502691330008982895233731506600778684638817282531001457735,8656561399441987116927438675277763317789561532507396244334062468892541066084,4069166732330197412844703565599514109399373916243310212229125901351402003915,19808198732373520522982274785888742523226720967259539531129335924093928174880,8555796834031869022510134190573521699378201702450788201649007358450530423866,17759660636058865290579521740750449606781204755231964378855563896473545202303,1335826395218609619260020055566056869243760115287254209950063597653055872566,21596200365241795669701682696176077888309278223833581800772036945674858315765,12619752319673193899296833725747186284394167228468888029626464753793997178599,17420588547980145067421969830249755561311178399975476925894947008643385243007,10337481272389772505654575850886249605422739785111225132545740838911222864209,17928431631046752749930349099366498612885288622404560316665023363985966878427,3075798659324203306711977985120251896073145961913793478792728028765206521425,4639500613932181914847461422373341918892878975546430906324216810326467690534,15396322795715441250300995201889120935591602515487993982711884319616897970533,6391276937505284102735701938724106665734769352007891548547667448647832351929,6811373320779057384916660178551330838095673247430496448933336925226142036083,6590973140323934807800215988687710942074412987201753370126190631819398102173,19364648614154949386936259588484266535262135334799266379433252509193375956715,4702754284612371917466042550086249683933140314858807272591351280832918881874,1081036249074169248236179367049085684430282426446509768147097371368406374049,18548093223441988703029589168425055383154624592689171393242936199350770119589,11098999608073377668352846814752381891400020647878345005629685447730764310163,16001262992680194260590639872321865154716987495605624862471107193457192704714,21696229443869118415905915570780926763029898831113534481730746953640692230062,11716215712634983607563947056324900205144202447594949676250978337464771243867,1778908113733035314726603632369389424542091991692308812147944884836647395775,4019081204388123040098634987844274011285321286777408246805308194144238418480,3473266952388383063447927231564219811787341139731701190625605897592140631276,10457881304788072618845101933412333126160339089704353596608910674508961127232,14926101732700077295531234099443522459232814784151318061435025890154852791802,4036967072197259618286839959572768559469665646019907384624959071646231971399,12776716624632228928613396031717959431597335742467953143594165782617234803915,18894783424164609284436913400522166453255844750192864579927645453695213022195,6303809107919167113924303987533838414137996606980561570652539716097058487126,4729698693443803882717817492985796053343431875965792864932005291979914613160,1645790034267553926884568714540144778649055395816210525904813567839945991808,8138260225269705405100573121045873922755899939885385491610389913906979427176,680936760009829486282006800072001712155424246576949107399338687767760991887,17240357869291182045663678468827695873425113788704614245279840174870850373113,19100963939745621863641468371111320143895293700517367016077996431570157414340,16188989656090417148189510820963186890780289777598053654241741803194118100843,18027402882394597868782011288920739982398714370069420860949975937357531046151,17780529984916796963712255733293310230026423072958099290880849386941451922559,20004531511171838591303710792081846238092292916166965045929062171308088520097,13855731634251510230399834192704620793850325654395687428672253016405315169901,16872938837392115669581040432902657478544143723662502779821325505282093696739,2541555081244462826761076743762714962901590548271316707071685417008817634653,5136424039269088350807839181761422963254683236279333039713142751702136147963,19216238128964101420135465007632926445321991494181045543846024053552797518994,18868537488540023742258053821537824724371813776839672880900985865823137839953,18246710415801024039719497716350501105591286880983169809863166130543617917249,20608694004331631709610739723463009412162748201282986294016482926528443868949,11318113915971658853560322943565673154831611543653209084299774855226816037778,16240989418312335385576389959938922684406585560688799437547298624184839261343,16171299673760267132909753100946681733778389681324959987573199154235691694977,8036823955656422391918380552495301547890420665617977624790236120392727764522,20269862530534739231936251654244170650781428788816658397167110617927916774329,2368678892744667199202318323282128737449992006513656480477288092472671147090,4618078962163037429845764284139891171861860687111566735174912070413086829215,12695350627501306162901105159009497730633599768443844225981772758225613194238,16356283146491744069785034066388746989409816380917535719898337817088223419024,6407893217596287850421377738867081146106659458551198123106454022096864887316,18168868018352364136212098098453930600797374324006271488950341490483455519349,18352629174410142476418438008157117497168118524562206830585500251463010761689,4344169393287991961961456515301754172943022039566219343212376057129143739343,19424839806870716108478074501405697296961947409763509419111261767390677718987,5796037897847804302272999466834285170265203646465480652521088328457333766863,17402105801450379889120987010453669096275392789725153915905747267778100864362,15540989618743824352651126288511222263828123668208146479603617243655978402205,945810410725426921570254447269595873973858272778720657523509910503434094174,6962323734045776666289031609372270190654631739266635759799844631053633876675,11382945272742312954364642163371436855283161775445664525053938433459897196647,18940251871958826726849623572811640436342841713786099464305053400421580490631,13969540696178305383564753026163726563325318478290740131984853424331762285147,4841983966001277917879506889862519614692143906356361564304719688757862622407,8939049562492171082419559182596894186639203815268680721033389307282239000385,19265363396776097866041313346787101192508520582744521467413665478819721956884,337106861429123598189388456471513480497137213511877011021531147545809512194,251367482782327915297484770356856386307188967585026711663629212746150191478,19506616511267234489421548744907283107923549136620297132842391511025844759064,20633589633280372440758096707466273580151526293980868749421563697429194761212,18833062060138888612708634036427140134887774731041742144004707524569102994071,2927291160590267909596732410727396533948837350308818016906834558527125752899,7095572562193114209617459307511041110255341231707924363346373597653253806883,14274988113217913224290208839851596837329960221329537670822013510325939323091,9965830780560026128320556230399915681196410289456547935188741323403719404039,10333365845496980935202034863900757172839454015352626511769637076650624839070], - [8266021233794274332054729525918686051968756165685671155584565440479247355160,7947823415909040438587565055355894256799314737783432792935458921778371169026,16508811191852041977017821887204137955816331040385276110261643892701458724933,1804800467126006102677564831888710635194614232739335985819349312754063580223,11189892034806587650995829160516587240879881493093022855087765921356611070470,20567450145123179140729389574352706949280207113956641415022972885523439610844,4666756311257455192796774305229624459258864488677689058174087310651786875914,11389253665835451896363091846189307652796786468610595637047377864063404843117,18793736599347263150867965517898541872137378991464725717839931503944801692688,4206344588923325482680116848820594823631536459347642329098796888497153867720,1739462481670645248707834504605096139894257554120906850613041004917967456145,18514227342636266640333254638454588508118462110178719555586534011641424431745,17887039315911403193186866703775654467672391491657957999455462537283842145802,2824959020572825365047639014537190268717891749361604043531643698340708119767,12521547103713919592301476538318318223836047611311454785951907894055964264287,8658146183671258251984364885894342376430874614261222570603159082682815800788,154390145585284450772861151318029820117470958184878116158462181541183085587,7593705166056392393963956710828665339496927193740869686529339432486182720653,5529559239163081088908568555890212324771345012509269613465629182165427812002,3729910453162885538930719732708124491456460687048972152311428493400220125686,11942815243552870715777415109008273807076911177089425348095503288499102855779,498938524453430895689241565973888863905147713935369405079343247530256066618,3976257517234324421403708035200810671331954932478384823208414346189926720724,723540703523219510043977323240437576248315561543814629392162302024056718473,13306548824219676333032339487546407241767961556934015003605485324283250885682,7970147269291664639740298762956131361316495463191268382513594527221399186752,20633313939958767604804835838065337107615699351647541991788258289962727735454,17162090859520817529294904484646695645841022315617926715432606252643123848792,9181379842957190051440498041153333325098774266789773971685141362947015398641,7051606617662816798224904133351061549832959857069896192072217769241273559278,16619522548478824222688310091434959542211899852679631815023615875678448806029,14965311177811968100298579672135357167599499478246106482433786066289128683961,9792733250919070275775594069208673385381167169182805600474820364274865306108,2069253833779081039049908513863485270550301879399727430830923273191877809560,15847298987712771667136245955631872888473964330474501593909263901393348546986,12244443532166430060291409356011430759892629145539185535677568234713942157668] + [0x1448614598e00f98e7ae7dea45fbd83bd968653ef8390cde2e86b706ad40c651, + 0xab7b291388e5c9e43c0dc1f591fb83ecdb65022e1b70af43b8a7b40c1dff7c3, + 0x2b7cbb217896f52c9a8c088e654af21e84cde754a3cef5b15c4d5466612d6adf, + 0x2bc6b0ddbe1d701b6570428bdc1ca1bf0da59ff3bbbb95fc2bc71c0c6e67a65c, + 0x123a55a31980384f3d20b2cecbc44ed60c38c11f7d20e9271efab9a905eefd3c, + 0x37501cc8c9dc819309a769f4df098e588b01858bc8eb7e279e2883be9fb8c53, + 0x15de231637a8ea3473c2499e1bee320c17c6a0a4f48a9b28ad1444d5351ddb36, + 0x1c9b1da36989206de9173b0ddfb539bdf07f89df055efc1cc489002da3f4b534, + 0x1f28ec9fdcb3854cb327e3e2fe3958550c37fd179198a41cf20a1a4c810654cb, + 0x2a0418e12dd26e796c091bc1fb1e50f8290263b3c80f68036e6593c2db2f83c6, + 0xdf6bc990dd688fabc1f8a5f8fa02a6a86f7a3a9ee452f5684d123eac1507890, + 0x24cd99ab301ee74e2382e238be9941d9876f320e9940481647fcbfbca7eb6a8c, + 0x1036eec6b3ab659a50c22ae3b357252e64641ce082e5c084bf61a4e61198ac85, + 0x21ece1030bf5ad5759f35ba96af936d82a64abe4f9bb2f50c28a488209286118, + 0x2e5d9059e62303d8d17fb509a60afdc4d8ee1d9137f8fff0d0c6e9135aaf66cb, + 0x2591d88c11580b75c4edf44dba6ba31c696f6789e22d3fa63bbaee71c6986857, + 0x1e647345c108005a7e2f870f01142223bb22ab44a03c7198852aaf6d765c3bdd, + 0x107e279d710e65358ef44f966e594d2ba04e3e15e37ca5aa5117adc71b441f09, + 0x173b298298adf659b3f695a02f51617ecca7e221f678375405f20405e377a44c, + 0x1228a0cd105946870acc7586969e7e3b3e8d4f5f46d450b14698202adb9ea1ce, + 0x778cb45d98c0ec68849bf203dc7b151840928cc9d7f40670bf7d48b3c661d68, + 0x72a7ff12706fa3b3400308feb33ef3ddeaeb9a5678bd4a17dff096fa99e9e64, + 0x2b0997b01165c2874503dc12fe77d6ab58a44c583b939c35d0805bb555cd09f3, + 0x80805129259af50e2e5f2d8efbde358132da1c19fcb7daf48985491c9d287b5, + 0x143e4e1f2af4def1b19038a0d6ac9606e33f40704799f0890b4aba0b2d6cb923, + 0x1c16b447df0a3026d5b9123abaf02d69076c59153052660df237b5221485da3d, + 0x2212763564a17c5b816703e5e52a7db0c5bfb668fe2e424cb251361426830b92, + 0x16dd30a48d96f76e9378f65bc341781e97cfb94af5a57091bf341342c0d7a6e, + 0xefae4a569514657f67e19ca11c01e2426ef0faa2bed48efe0711d338ea3b86b, + 0x281dcd532dc450be559536e252e0159ee21d5b91fbf9725f4a57dd870d80e779, + 0xfe4d11a8b3f24dc559b4a37118f15ab83dad5a74dfaed41637e994a81333f95, + 0x1857938e02790819328278a913222344640f200c51410456089768bfcea561a5, + 0x2007d043ddfc54fd999f6f4b63d4ca66c5f126951388cddb1dcde32944155675, + 0x23de66b927d576792c69a2c6e7df20d3fc745614f5202780bc2b4c2fb27e9e39, + 0x2bdfcbefe353fa2ffe79d2efd5a51c981345a2de40ef5c764bf90da86fedcfe3, + 0x26cffc0e5984933313e4f06dead07943880da66929d3aded77e0fa7f994244fe, + 0x21c532ad0d50674be3947ff2d4eb744eadbaa2812fc0fc25a41cb84c0fd3efb8, + 0x246ecf2ee4531862cc5a2d7842fe3c780b868ef445f70c9a1e2bff46149cc46d, + 0x397b3980a3cefa0fdc7339c4f9500b3643c54a3ee7a39600304741a2e772e90, + 0x144490957677636a9a7bf12b1ac99af955ea70999b2f972211552ac7562c6aef, + 0x4a96669777938cd9643ff257d5f56c5f4f1eb5adea49a678cec3ea17067f1d, + 0x2423a50871429a8c48ba13e4df938e6280d715b39af43449ff06030e346e3e2b, + 0x1ca50640e8f42c03c288014e8ef12b8014c3c40a62fc5856ee9b633146ec602a, + 0xa8335c2fa762d09bda1eb7e22b11cc117df788c0d023d6d8947727681a7a9eb, + 0x1c57af7a6796ed37bd964c33cd1bc9c89747ba21df6100209fc3df9f707f1cda, + 0x8f0ad5a6c01f0bde7d1a8e7d26848179f5ee31d6d59bb8e2c701e37a4cfbb22, + 0x50c7821c6e53eba185a6278fe04a5c1f2f28641bdc843c9fab2ac897e8a2466, + 0xbc5d445c5df52fb9b4b9d6954bc75763d53b0c2089832ebdca9605679f68d0e, + 0x10a6b2a07c472c2a32e9dc1f0501fbda5c9f05b861d1c78a5cff3594197b73d6, + 0x1a24448b3442479c7ac8191bfafc67d9c75e40200b318f7c72d0c2d908b3ddb3, + 0x5e230c7b91dc067802c6c9fead50897c03379389e2a7def370ef4c28e5671be, + 0x1eead685d9f3577f7e364da47f74d8ee2cf6cee31660055615d8f294a30294ac, + 0x4a22eaa10791b59b1bd8ad9626df74275535ebea301f8f912c521ef29c504b1, + 0x6377b60615b7b9a9f0eb2276786d028cca82fbce7db1cc27f50b8486c8806da, + 0xc76495da478bbdfd623fcac2f3b08d641c4c654738fad67b9e90ea0715714f, + 0x250ad6b94e1bd06817cfd2421423a95e18ba872b276c199e16a8fc650c5a9d61, + 0x1b2e0e66146fb5b1221c878286a0983e903e6a95390f57d298a50dce6f52ab47, + 0x18ca890aaeaef97c7c17cab2c3518fccf1180b8fbd134fbcbce38f786f2c0e03, + 0x1b5c3db94d9e0cd45571c1b88084186eb58930bceceb2c8f775b12f37961bea0, + 0x6294c72686a69b6069349a73a81542cb16a6ad71337b7c7ff5a5dfe06a260ae, + 0x2c18a25a8c2cae179b1a643e11159e8f5c9da448aaee3a44de48be3eca7bb253, + 0xfc45a2b9bd6f41901baa7afad40cc28d4479c304d101067c3567fe449332eb0, + 0x378bc3b5a32cf5ca088227c5b6f0a566e0b75733c704804619e6a979bc1d36f, + 0x255375346beabd092bfbfd7278b437bdd3c18bd951d7f4220cdc5013611fd9f, + 0x524853a2a9717af64500fec836c13807e5978be32886047bd3683a5a65b6859, + 0x1b3998553154fc26ce88f0488160c244e1dec648b930c132d077cb93997af5ea, + 0x12074b4d83e92f8e0ab92429aeb5270140338a97ee8e5c74f2b599d9577f25ff, + 0x1a40b1e01a096ea7ebce74c027536bc58778b45dcefb7cc056256dd07326a662, + 0xf5228bc094b9eec1967d778a2b7d6b4de58ede8e0f974165d37ab6f2336bee4, + 0x27314b961d2f96970977a33f2fac6823c043207e4b6a48a05537ea78d779c16f, + 0x2a78f5bdf98afa1da6dd45ab360b877703e1f9f0e797fecca45327ee4ab46595, + 0x2cfde59ca2f01a27fce554c265bc23fda32ddd9dff3dd0a2f1dfddd0764c20b4, + 0x1925a7d1cacee560010f843ef5fc9e7b0294667d871d49e3523a88fe0af56aa, + 0x199ff4bbaf94ee387560fbbec395db1af9eed9f50dd60dc3ca2cb92e92452263, + 0x26f7f91d959cdae91907b28fb2f149dbc275f13d55776da51a88200f8e7caf09, + 0x24cddd641b7ca3bc6c4d257832a5ae5e92126c3bd2e9f05e012731114d62d0c2, + 0x18547edf50bd77b2653c2a53284c999dce5dc69dd613804d10a0ee96bca55738, + 0x2b27178eca4b798ba72b2e6b566bdfeccb2a1e60d8504e4c8ec9192f2baebb, + 0x3020eb88ae7acfd6342709f3d3be45cf2c146bcdc906ee5795273ae4b6e7004a, + 0x54b81a6d3b1f002230c4cd623f77b0fb6eeca3afefafe694544eeeec1a170f, + 0x4d1e03c93510ba6fb49bd9ab51063d3b15e48e2ed449bda2765d03065f6cffc, + 0x2ca6a28e6b98b8c8220abc091a2fafe86f271eef1d93864b7b2bb5a160dd8d99, + 0x2a586600678651f144bf1e54de3d6f8fd519daaf4a4ad9a1f32233e89f9d6733, + 0xa94a9fb854a3c53411d736ce58dc82196b2cd13144a240a6fe173508a221d91, + 0x2d336c647cbb5478e3a72f20f41d135d35f96fbdd9b2b2884e6b23ec201e47fd, + 0x3dbe3f89948f9f4715c491a483dfbf6f6f9dcfb5853c5d3ced707f0050a218a, + 0x22466ec15338114c3b316b2d986c8c0d3d14800d82275a42f476b0ffdf9435b4, + 0x1c2d6c5b182f394e8d36999e91a9eee77da71f5490961fb783a4f8e6f842e687, + 0x4fc56515cf83247e370e48809d3bd245abb52638d86b48a1cb743167db2294d, + 0x1aaebc90617e5aa4b4f9036fcc5092da7edce9c110e3eaf00d7fd39b17aaed27, + 0x15f7dad928cb34e6858a2deb2f9d92c452a535a096c5d713f7319c0c577e413, + 0x60028307221323f46eb56773c5320fdaa2d7123875b420176e34b3ee079e972, + 0x157b288cec9b5356e60373bfa43e67511e2a7e62493650c8f38d819fc34e59d0, + 0x88dbe88f3fe8fdcbebc34ce3f00f07fda411d780ecff1da57660aebfd12ebfc, + 0x9f13c89213c82d5bfd38f8f8bcfe46fdf403d28e6d349ec0176e37df9c912fe, + 0x5bffad53722ac6c42236124c3200669abffa6dc923fbe5141c8e4157cd317a3, + 0x290a7829a4cef2e25d2f6f28421463344bfde52203d4cca736573537af33421e, + 0x9e7209dac7151697be17d3e3ac52b0ee6467929b878d814ae4cc2734b39348f, + 0x7629f5b7cd3dd536df6a866a071fb5df56352fafd0f097711cd1667ea344039, + 0x11641de0af5d033b442dce1f8334eafd4959f122304ea6c2177c377d55eae045, + 0x1021e806d83de4cbecb3c1650c761774e83cae4ecbbb0df13310150cbada88f4, + 0x4ae37e1e7676e1d3cf64285f704135c8cd640f70c895bdedd51ded260fbb69f, + 0x2a491d28b320ff77bf7221b59fcc2535c7cfc9c0f11a5fdc5e49c837a71f0239, + 0x2ba7c26958118f0b751444e8ea3524d45fccefd8744618e66e55679e42be29c6, + 0xc6516f4cbac8b8f29be9406c6c309df34e2da7d931133e4a34f29ec6283e9b3, + 0x2991acc7db5eb3159f8766c49d692079025b480a70656435ee70c5687daaeb0c, + 0x29d7605b413cddd192779b7325e1afb8e52ed3e97e92adf701c7a70c118c648d, + 0x2507bd3788f57cefee754d3ff5a92980dcf062ae4a3fad93ec0059eb2fe545ec + ], + [ + [ + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0xa514a5c227f4cec95dfa029e8dd124c34895aa46bb27c0911f3780d5015540a, + 0x278bb49a7b4e44aea46eb0f882cb692801a6e60fdd5b5c23c63cd65ccce4fe0a, + 0xc399e9f67aa40707a203feefb0b958bbdadcec5ca34901d253d026a2419f6a2, + 0x1d6b3d5f6ea369c26f825d2362933eaa31ea35ec0a77c1fbd9e01ca1523e4432, + 0x24be510095436206dd0abd0b0cbb95c883ab304aa52598b1a69306ec981a688d + ], + [ + 0x11924f02fd19b09255aaa1cf46ea0518e3d7bfeef47421609491011db0bd0b02, + 0x192e16d17d956b257b85a652eefdf2ee09589eac5be80915775723d2cb1da06d, + 0x63edec1bed831f506af8db648d6fdea145345887e8bdcff109035a1d9b674d7, + 0x83f0df3f1a0351d0330ec3ff602ca8cc353b7f6e762c7107184cd7b423449f6, + 0x119ef188bb3dd0d32306976c19941e8664be687e7a69692da27da215a6f06d40, + 0x211610e2ad4a377426fadf7068b0c1a6c299a164c1c1a603eaed944870d0b9b9 + ], + [ + 0x247fa7f022304a1994ff505456c2201ef9b717369498d3ffce446601ed9df845, + 0x298ce0c1e3113bb935c7058e7772b533b1aa9db0c0926bdc8917e5605ca3ac10, + 0x1baef1cb5509b526a42061fb53657f99b3232500e855192cbe8c940e068c475f, + 0x1a6764d5943fc4a720b4c0a19fdb8c711984307287a58b9b5f9f5d58212cb263, + 0x2d9e0ab5c06893dfdfd03481381ba86b6e6292df5609d71f2c64b2d9a79f809e, + 0x15a67d981041b1f6f09f3f9ebefd864e779d3af08157786ac077505e50ec79fc + ], + [ + 0x3fd7b19ef2c861f22f77ff810f54e277bc94eb76c02d79d986be3dcdf051c3f, + 0x94cb4e83621afd271e41bc71727f0158ebd612239ac9d698b17fe4be05b7fc8, + 0x1324564ac7bdf9e22164e9858d7fa8e368b165eaea3daf4eb67ee59c0df2e5d4, + 0x11a63a26feabf87fa66bde66cc25a922c96382d76c6a7ff48f1537beaed683a, + 0x25f16631bf77060f7ea34087c025bf135784319ef08cda2e31419ee0a529e658, + 0x49327fa79d28c12a2c82406947f77f06775b0287468b3136877701dbe7c9598 + ], + [ + 0x18bd41239c3e71579a677443ecffbd555a81eeeea69352a68b67c8563c0c2a06, + 0x3d880395be93c27d649af5fd142e76b33918cb8841d5a28173bd5cf7d328791, + 0x5761b8c6aecb1a8ca4ea4dfc2c8376064a4a8004ceeda210a55240562ddc13, + 0x8ca7b64657c3548f32bef5b63ad24288a41c0b251099ad27f9434307e3e64d4, + 0x144c7a11da5a7c5dabae3f33fbd03cad86d18bc594c79a497ecb9894edb554f1, + 0x230940dcc5232658ff9c29697a3fd416d170e8c998f1aa85dea0c42d79f951aa + ], + [ + 0x2d78c3a5d28de9ff35bf0a257635196e5730ca7f40493277078cd75da8b4ebdc, + 0x28eeae6b5866ad68e443bbaf91680db7d7e2b3037e38fef61b42cbccffceca81, + 0x10c9e283159d58cb4cb2e35fde83a3ba1fdc28002ed9963d2a99f186178a148d, + 0x1998270471e9361955446b0cdb8bea915ec0675f1cd648ddcb04303507a4489, + 0xf971162627723f3feadacb28b0c104cb8f74de508752fa8d7c0db2af13de8ee, + 0x1b121c049cd1159e289007e0c9da9995cc4bab4c26fb888ec3972a8a2e656964 + ] + ], + [ +[ +0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, +0x18ce75a35f7297cad2bcc25f0ed1bb4f7c592eea8c6903b19850511ddb83274c, +0x138f93361c6546d69015ad48ef50af34fa9e19c6e6844a847eba9d908572052f, +0x13c29b24c0e38e65a1b9428622ba42931bdb65eb5975e66d3c496c7fe6f7a30, +0x211a38485f1e9db425379f4b3fe9c20474c968aba2ef8a4bbb898a8420d0fc90, +0x2fa4d773833d944be46ec798f7d16e9fd02f51c086141af5d69acf97e9a80b2 +], +[ +0x11924f02fd19b09255aaa1cf46ea0518e3d7bfeef47421609491011db0bd0b02, +0x2c001eb6b378c49fc5b37aa41c13fdba486bf324eae0e0063ff83551827f338e, +0x51071183ba1b8fde055b8f273005056fb37684b241f88851a5b550ed0cbc452, +0x14201055ff5412f834d761da8017961213666e5c44d6c5a8237deb4d0f734d79, +0x182177db418ecda99e6e9999c3c0492f4ec27a89b2ab554dc8165da9ba8c9762, +0x1111d2d4d2a013e33fcad48d574587e3d7f7f6b484d7fefcf933dc833d13bf28 +], +[ +0x247fa7f022304a1994ff505456c2201ef9b717369498d3ffce446601ed9df845, +0x16e74e9c0932c76182ca25ffa7dc6ae62b2cfbe19142b2ce1d95ec0839d7faa, +0x1a13e7beefcfa55aef7815712c7b350b465c0785afe7d6b356342b61047d07c1, +0x1adcf63e81b22ad38811b20aa6175ec41784eb99fbee0f3e56a15df0c1ac5179, +0x2f3a76ad0307b740f6e6e7aa989335c6000d930029beebee83c0631b3b435123, +0x24dd1c38ec3e47cf711221cdaf4b2ccfc0991a178cf7df2f3d1b88f858763c40 +], +[ +0x3fd7b19ef2c861f22f77ff810f54e277bc94eb76c02d79d986be3dcdf051c3f, +0x24de008c4b20c4dd769afa3b377e2e72f0a74339f53c3f6ba8b84b0a85fbe9ab, +0x274ab81953247f18a26dae90d93deb1f33ea243af6aac4e05e117e233b922bd2, +0x16a796c4310ddbc2c435ea5ef0d6381e163250c33485426e97a566ab6f2bb07, +0x1befbb4037c8b847d2711cda8600d941a1583cf2fe06a8ae02bbc26e180259ba, +0x3a01ab7488d6cac69f70b90101e5c8beb78bf65a79fd6068c9010ec2e0fda4e +], +[ +0x18bd41239c3e71579a677443ecffbd555a81eeeea69352a68b67c8563c0c2a06, +0x2a28f2409cb364d31b858844023279404e2ce02d38430be77b2755aeb9193a56, +0x1b8e6cf61af064c9804f1888a6a83f6cea7c57e574c229f978aa922ddccd80da, +0xca6769d4383398d1a04d3d7a6f3510d85fba7f5f6e6d287d447908d11c71153, +0x125428fe689ac0be368c80b67e8b2ab83d8163ba30b4391927f352b3bf3dc5b0, +0x30516fe884be9bad887032b15a83c91d84147d44fe15c90935ec4d421f5ed05f +], +[ +0x2d78c3a5d28de9ff35bf0a257635196e5730ca7f40493277078cd75da8b4ebdc, +0x2afeb1a63b374a502180680156748121a68fd7002114733bb039f74ad576c0d1, +0x3ddf5c61fc2eae153e94adfab9b234d07b261ad228547ba9218c4caf6cbaae9, +0xc2e8c673f27f45ac1112d92cc8b81ef4af42657d7a114d2d6bcc4b74bbab7c7, +0xda5ededdd0fdac9af41d58581e5aecafee671a5253023205aa9a2b7e1df842c, +0x280364612aadf31ee5b176ccc54b4a5f961cc782168c8f83ff2ab5b4d12adc0f +] +], + [ + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x6fac61a13c7139a37697a657fafd9c12611f196b60aab2342eb6e869de7069, + 0x27b4b4ea2ab70bb1a791b43c0571329ee6e44da480d8f0bfed4eb43125bdfdc4, + 0xfce2531c0dd9b1906513da21cc6442611222f8c05b5bb5ced0c5d392a1b4254, + 0x2278afba888b07c659b7d537ef4f2da49f03e42e6fd4f6ba90966b2bd89291f, + 0x456a8c01bcdcc91bda80b7c97f7e9019009163bc2613446a40a49fba3c70ff1, + 0x2e4c46b8f3ebe49417334ca76f3dad782cb15d40bd4fc143df9937aae5fdd9c, + 0x2c13f0f7c421c96b47743df05ba0a84d302823a72fa019c251cc653bf9fce8cb, + 0x57b6bc405c5ad7f6dba556199efad30bf33380cf4bf74ec23214edd123676a3, + 0x2d127c7a346cdfcc822076c8df679eb5cf6bd0b6a1fff70f753f1317acaaf8af, + 0x1a4dc6959d65fda6047532a57790a1426499672d67b10ea360603bcdabda06e1, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x1ab539242bb16cb2ca4984bc82002d07c6fc29bd0d9a71e348669ec4f909e567, + 0x144bd8b4ba25cebbcc44c0847844f5d945e389efb61cebced8ac7740104e2da9, + 0x8325106daf6927a182c4d83e0bbe039fd390e2507a359747a98d35b41bf57, + 0x1469c5365c13ba0cb10b14f109d6893eba3239739e970ebc50b63a9870da0ede, + 0x111e82bf1fb3d4458829cb1d852b66f7c2ce4079ed210c88374dacb88c69c252, + 0x2bd6778059c21f8d5df3e825464319ba8d9f0fd7b2bdc4525ac788061031eab5, + 0x212d3cc6c2012c922fd9372f6be58aa0518c392a9e25338071401daa267e36c0, + 0x267547f0b00c32e85957a425dd05961a02626ac79b2eee417af0c450646ff99c, + 0x15f1012eb18a32c69ac392696cc974530f711109a197501b43d9b49c445d9dbf, + 0x24e5916738efe20b55496e3aecbca9239063458c2c562f3c0c2ad45ecb9a0c27, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x537e9d61e32a91ac981e5442837942833efed46c25b4009d6622c1d5cd67228, + 0x2409867674021c13c26db12dc4687258c8a7b8c39ea9e5f0e538c9a5d79d00b1, + 0x12dd0ad0bbdad721a2bb795f4b54e08a21e4e5043e30bb1fdf1e369b45abbb8a, + 0x194d2892087f1485580dbd9db047343f73d71741cb1d679264d0f15f22011a17, + 0xce1f30705772a51b72eaffe307f73c59d16cec505e28a06352fec8497398b6, + 0xb4c42bfd8b2eee4229dc6b4b6ae934b6882a560dc0b056952cea95e04e84ce8, + 0x2831274ffa49361ca9ad0f3687f1fd840db43b13fc4bd747fcbcce877ed78fec, + 0x11c3faaea57cd532f952f56dac42a8d29c72c8d1b29459ec218d5280c374e141, + 0xd01440afe63c28b5820215a0a082fe296ae749a3ee6116967d46c4b9d59b77e, + 0x27fd7799437558165b866c1b89762a0b94bf7db886b158ce62dd2ba01dc6fd48, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x2aa5a2f43e0f4bb8b52041f635ec810e7fbd82548dc722605bf2c15e7b2e044e, + 0x109e17fad36368fd93917a9c4919820ac8620c5baa64d813f420f25f0e97a087, + 0x1c6178a12c2d4fc816077f0e4825fcaed9b6ddbca03d665be624cbef3df6c10c, + 0xc8b545f3ba3005742d7867b42b2acb3895868630d4d1ca9bd2e7d18b22f7b1d, + 0x1cf272cf45a39a8f47599447b65ed8ec169b564e656acd8720550f78b1aea9e9, + 0xed81d4f2b8cc774767ad184b89c02d1cf3aef1866d4b8df571a8feac7e1fb26, + 0x25c22916d7c3d030b6207eef339a432d2f2a485a98a63fac53be6a93d90cdcc9, + 0x140c2f65889d437a0736acd2164839f1a951aa1e9ee18258b701b19d0f880820, + 0x19b9bf03c47ce774ff4541d66232a3a61a1eb767c37ec93730c2d29b43ec2d0b, + 0x1464a2e5c87714bb4afc1b5cb90f1cd587ac7f3133e7f4a5e45d0426bafa3946, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x2fdf0895b6e7dd081135a74466610d02ec2f5e53d065f8f28f55626f8984590a, + 0x2136a6254155d5370c654be03d5f2ea833abac83f3ee2aa86080b4c812f6d9ee, + 0x2c25045d4ad7cabc1457656efe3091cffa14b2a3c3a74cde1619658015d69a3e, + 0x35edf90ee5ee2937a2258e02a11d996be7d2263c30a8111a8f461b31b61d756, + 0x24a6181596fefcf6b89c799218467001223efd7b39880e0b241bac300d20a3ad, + 0x29dcdaed731430d9695b46313d84713e6dec7b565f79b94b2cfa3dd7e9e4ea51, + 0x1724f4a9b1696abe55d95e9c0dc048d1d473394ccf983f198d9e90d2c73d1b8c, + 0x1af69c74aae418d0fa8d9c030ebc68c04e608e5a8cc00a35b1910ddbc6fcf143, + 0x27a0793076b09c2b5e775c8b738f488a11171c0066277483afa7fd8c1dc5bdb0, + 0x1d4ff6c75f1778615e31525a57fcef7dfa5b5d84382b5efe78fc90625f8e1e12, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0xfdf45f1143c7650173ddbf41fd32b101ac1058dcb360e4f55fb042d86b3bbef, + 0x28605df321f1d74a93860493ae581fac9bd5dfab8755373d8bbea346601a2a1c, + 0x2894568db7debb47fdb42ebcba7bb4c2bf391c73c0ea435ff611a9a721a2ab09, + 0x193887de99914c911549cd4c5a402b7b33e650ef0009d7c99075bee089ee532f, + 0xe5688ca400eea76906895ad874136e390c7545ba17d0b64b9da48aecfd53d91, + 0x2c60db3843ae2171a20f4eeddff7e6cd3bd2b06cd8d39e97f93b895a4096371b, + 0x8fb4f2d9d8a12c667625b7df6751d25d3409df0443411de74f779e90109ff34, + 0x4d7d91e3652705f015e14eefc3aa412c707a8615d7dc336fa2da72d1a1802, + 0xc60ca70bd06719bcb51c3a8664b73f8b921234656168e68d4ff6e9552808d54, + 0x1ed054abe9f3b4e19cb8a439399c5ff5f6de90c8463a09b82da225c567d05095, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x2b3d78867b390b2fdb654d68512c316ec959c5b8c9aec49d5fe74188257c3b6b, + 0x19f72308eb341f3328570cdc9f78fa3838e628260d6e76bb3b09cb4e5136545a, + 0x54c9fdfc6bb12bd2061b153f433d828dd2ddf02d56e4d6eb280f19591597d9, + 0x20a858ce8c00fe452359acbce4df9110ff6c89a362ff4c8ccc7f9da470124a1c, + 0x1a55f3dae7d4d14c6eb851e44463ee0da6e66b0f56114b8f46dda9e717a9b1fa, + 0x65d52f3291af23a00e2d058bb6ba8e17889f7d03bfcbc5234272ae8660abf31, + 0x278715151d06026cdd68f4bb0fee4b041cd0a8c62bd5faf71b393ea9dc3bcf2b, + 0x9c6ec8631ac5a417f041efe2951033a622baf01b9f1630c7bc093ccd6f3fc60, + 0x9c078b2310e182f40304e342c5f965f8605102931254955aea231962f762f75, + 0x22f4faf4ed2ac6947282b926253d93751ab1118a05d1466bf117dc853dc3c532, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0xf24da597b74c3677589a6cf15426219cd0e2c1a60c9acb4b9764b8e5b4fb5fe, + 0xf39e91701d900bc7ea63b7f0d3b753cc31d2cf6666eef786a6400ad04515c96, + 0xb41187c60cc3bff1020fc4e647452ba940a5b3d9ffdd1b47ab613a515df66e5, + 0x619fadfd7cbaa89e7d5558c4d23275665531928f62fb14cc4aa42605f97a1b5, + 0x285ed3287367338bc9387c83fb8987cadf1b4ea7f1dc6b172e924ee0fd2ffb87, + 0x853d29d7e18010d04607ed8b3089833d55166ebf58aef558b3642f29ae2eb31, + 0xb1d3737cb97c59030221a7d5d112bb755d096d8766242158d0bad07bed5ba9b, + 0x272b60326347683fbe6dff2b97289dfefa1be8238526c8067ee0a126942ca6ae, + 0x2c7ef420b2bca189f6d7929af54403354933d68446096f3cfccd12e76818b23b, + 0x10fa5605e0b680e055175664a979aea1a45c45057f452e5b90cd613012b70508, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x2ad6fe66fcc8eb73e2dd7dc6a2186c31107f8896b5f8c7f9ebbac9bacffc59, + 0x1db23b49760ab87c22237095db005ad9b792ba63647031f2f5e8d0c66ca2c833, + 0x2b51ab38d81609e885b8d8c3ce799cedac1febdec5e27a205ca82b010b3bd9f8, + 0x2bbd8df986114303d59bf8a408982796d6f1809269b983910bb6fcbbfa72af53, + 0x3516ee288a26a7555d7bc66bdbec4203e74c105513cd8be87a99c035a176c22, + 0x21161b2869e0be07d85e11051ac0d8894044cf1b4715d5dedd57cbd6aa48b240, + 0xf4723c169e787400b2153bac8a074da0d992f44a8558a0956d563e73ac03dc3, + 0x890ec1904c98ba5b3cef6bed816850fdf6734951b143faa0c2c643a1c1368b4, + 0x1453882ebd23e2ce3f5655eb4f2db4e7d6dcd892a14e3da655caaa5f45a2744e, + 0xdf69ed4eae9a6ffcf54a77d8d8ba14541af9d276327678b71e7c49c8deb41c6, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x84cfab525ae12db3c30220f978a1b48bb652c2e47d1f5f4bf1cb3d5ea4ae0a1, + 0x220ee2aac4ec50cf3a51d76ea554c6960befe1a9b946be4b58cff8b4d8a16561, + 0x9d60891cc06c285c3ca3cf7a78e37e2516e4d0ff503179234ea12645848d45d, + 0x2f51338183dfa99604f1be042cc1dec8e96e08c7faf7bb3b7eb860dfdcdd295b, + 0x29fb82b7e1ea4acf9d2ca8b32f27e68d10b27214361156770bfa4732f85e1b01, + 0x24d4646bb66688b33367aeec4cfdcfe16b7d21f47f1bb1f88a25896e526ecb8b, + 0x2cdaecd1c5653769c095f9ab2e0b4131a3dc4f581954fa91120dc7864a5d5b5, + 0x2e48eb6f5a9dd830bab11e8f49f7431a851938335f6af547bdcde3b9a2595913, + 0xd3d729c3d04c7f9967a7f3ce11c053d5a5598f0847966dc9840eeebd9676b11, + 0x2c9c7d8f5c11a1cbf89ab2b794739a371d818f77cc71bffc6ca55d4472648f2b, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0xf330feb7fa24cbfbbafc2eae5d109a2bbe9d5358ec7a34035d728c6a531b17e, + 0x1b4af72b65b66913013263c37d97ffaddbb8a824b34d45819029b0867ccfb460, + 0x2ace1ffd40f56f145cea9e679db6c57732315343423ce026a8e9275e888307fc, + 0x1c328a5168d04cdbc31519e037fdcc5c426f9a6990fe80c875d625880c7d033f, + 0x1970922d81c9cd97d3030d53733e33e3d046684219f4960ecdd0910f5aae548d, + 0x76fcdeddfca38e6bc4c5e872eeb1628caf23d8d7b966d97963f38b8b55a86ab, + 0x3e273f1f05592ce120df7ff9ba32eff1c1bc065b149c2c2a7986c1569e4cc3a, + 0x2b1f8dfec05e8d4495fd0759474932a003b11289a3440792a48e2cb777badf6a, + 0x126fd80bd8f9f83f00cc51cde97f9e4a3bd540c93921e8f3603c0cb13f89cc9f, + 0x7cf5007a4ecae9f4cd74689126175d8a81f7c51a317a2c1657cfcd533b4a57a, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x18793b6ef20fbe077cf212e603b2a491b8b9965510bf81c85b4cef874fba6093, + 0x5bc7621748131cb19ae5e7e6cfa468344c116dd37fae01e1780381f9b1ddebc, + 0x1aa859447f3acaff5c15fbc24bf7c164faeca846b555b02637fa84a52cc9efba, + 0x28c3d01915f85693e04821e4f2ca799c62b1fdc4739123d8dcdfbd1c77636c1f, + 0x2c7f8527d2ad7d02e7046dbe690997f033e351fd18d357089e988e041223f15, + 0x126b669244c7ea73d340ded56f5edce3632a0a69b9cddede297acf2f072db9c6, + 0x24f71ee920c1cc2790112e7a8e9d3d824255420604fe31b331e98d2bef539781, + 0x182fbdc24f8599ae291b3e8a96bd15251396a94167c8e34ed1f86069c067f03f, + 0xeab7f1b18721b3c154fb3b7fb067c4f7ec18a50fa3ab3aa5873a408d6d8cbbd, + 0x2012fdfd4d53aadbac3d7ab9172a826705d55e5862d1be643cd4449e1cc6b06d, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x140490ba93d42481632e9924a725c65bf59f7e4975e98fbdf486a9772f4b6e8b, + 0x2adfb4e0a55448609a06a1ac31bc5d06d74c45a4dd23680923d985b867f054b9, + 0x2035a526748b686ac46231697cc52fb4c6d8e48c4314cb0a1ee08eaeb43938c8, + 0x242ec6b33cd2c625d1ca2833159053a0e9beeb37c59ec90e52d40c983e865096, + 0x10f8808d7f88620998e3f144046327b9522a07220a62c7986debf2820accb611, + 0x5d4d8a6023401b798a1b296dd42c9010da081b9e6073aa73dbed7a98bef4419, + 0x20be6be68c47dda41e08c5f858520b25c036923b978fa8be6e870e85fcc16ac8, + 0x39240da2e14965307bd9be9af5c0cdda03a4019f86c45bbbea90f40afcfc500, + 0x60457249c4fffb06481b95457ec48e2b795dc414d6b71350ad08b56cdba7c3c, + 0x239ebf95f3d5909ff12820066059f1b999f9ee594dc03af1fad6e0015d698e72, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x90738838c7088a39b45b7b8466e003c1d0b85fc0c95153e85f9feea552cbed3, + 0xd0aa07eb53bc77f6a7c777fd33d11e4eec54afb97da769f937310f797df2469, + 0x22e87e33862f106af8bf1a6ac33f69d994ce06f021ad32236f5529eb399a8ef, + 0x16a3ff860e2110d98eceb0f5e7946d207273ff9a4f1e088a009f1aae19c5b0c0, + 0x13e35cdae4c6ff35a681118ecf4612503081b2920a59f54cbf5603c5690ead76, + 0x11dcdcbb80fe328963d887aa5443a88e602767afcff3938a877ef8b5e6b62084, + 0x1440ac3cf3a1ca78709a2a97a0255d08882b40ae287994670dc7d58d7b929c71, + 0x9112aba3d285034fd7808ce5c69caf188aa2192e3143ca73ce3ad404c503a9a, + 0x2c8eb1b5f21c2f320943badb09721ad68f1c2f3576531713981a905daf415450, + 0x695acc1afc2070eabaf2e2279eb6f11d6e24c787b37f3a311f2bdac5cf0b160, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x1fb55d0f07f478f8d6f5a59e0856ad2bb9a4e1987cbb36e437895230685ceef5, + 0x24ffa19b717061f29d7befe633215f277119ea89aec1326f9f7e2fb3773f3a5a, + 0x16cf73a3eb3a86fe74cba7ab2b591ecf57d66ffae3113107298e11f21d7f69e5, + 0x115c7124e48b479e39faf24d853540716cea1bf2fdc19fdec358d1f740c1f874, + 0x1587c165c3d5592e72a8445bab791271ce64032bf746d66194ba23a413116cad, + 0x20677bb9ac0210a06115586f21fdcd1e6b28e8a1a8664e48681bb077b75e001c, + 0xfdcb34056ef1d893287ad074ffd8e4d767ed07f9ac97b5de1f34d8e3dd1a651, + 0x19ec313123a0d8e63b853a0931c9a99b14cc775f1c312bbb13d5d53f8818b79c, + 0x19c0eb17f727d16dc136af9e86888808b870b5e9e5d9e3a3c3f0d9431bdd5728, + 0x2b158fd09d9bb317ce4378cf6e0d574374690d42cc465100ac3f9a6bac9b6907, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x67895e624f72c2ee73f06438d1e38b380f0259e6a04047dc2ee474d543df74, + 0x24d801233a58b2016b8c6af6bb88cdb17e194fbd8c619a7d844ce681b933d5f1, + 0x18bbcf6fa75ef7e68070f388815361f028acdf41c8e0d9f2afc62b8bbb9ab94f, + 0xd8f16cc1dac32ee244cc1837b1ba594c32a38e1a594a6f1367af545463db7a6, + 0x85b04652f4427e9220976032ce4aae7e1eca676f0c169f9570bf91014ec3d60, + 0x29b6e637abd64aa25e69de1bc8bc2061010a523a6319d49c8d908c46c2e76112, + 0x686bc450316a122c312fde6bfea7146f929091962bbe3225769f767ee92e1f9, + 0x1c7db281138ff861643018caafaf569efa4f7d1dd5fe8db8115679c9d4e464ba, + 0x434b9adf694ee77662c888fe50a3f24f9a680df2fb6f501422589800c123cac, + 0x26bf3831811b3222ad4a14f3b9a5357b756702139b7d8e7e2bb87dd6034b352d, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x24b42bac7abee89474ff328bcb61e4ad5f128773e068dea11b88fc2ea6ab66b0, + 0x199ed05bbee1131c4dbba92583a02fbf9ea30aa59c7f2fc5bd5c0857cedb470f, + 0x2bd6670f967781e74ad00648e01596abb5117b74adb95734ade1c81fd02d100a, + 0x17127e11451908da53f67a87859373b4c6db941086091270d35f7742e286bb63, + 0x292010c36ff554b02f56a128071f54171b237591087f805189af62b616205261, + 0x2f6af6bf3c24ccd04480e6490018b489284a951f067750f4e8b461290402e3c, + 0x11ff6780b8da3672a8b9eceaf9d5ad240bf0f1d91028f3abce5147d0608449e7, + 0xdae6cefcea61ea52cc1bcd5bdd0c9a4f1cf123109cce7354405dd38054a8b2e, + 0x2234fe0dad3dd0ded7a39050f4478ac43bdcdeac99cb7ea75d61a66c2382c35f, + 0x1627a2a755f77f83d07a5cc58dc2aafec9ce48a85427f07f813e217e7d3e9272, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0xbc958ac5faec064de3de070d9605135bb3bc321f74b7f4795cfc4cdd4f64c7f, + 0x1761972f9f0d7d67e62f476c88b521ebe60cfe3e1aaf50580acd20f45590507, + 0x3ae68549640072b1b75251b5fe4b2282191f235ff9a753fcfccc995a3ed3734, + 0x1d3a95b2449e1d227b3cb97854bdfa5248b78bf8acc15feed87036a74829b12, + 0x1be688f94403019eb20b49acd9f201d5b765853301e9f30943647cdac98a983c, + 0xd40a2c767f9d882eb478793e2e146af99a620af4a76e6f3429d6259149311bf, + 0x2075d588d996d67e08cacafa27bdfbb6ff08a0d97d2b6470f475b87c034fad40, + 0x1db5acabacf79eef4e6079222f548fc488438af4e04f5f8e64f37a80eff37aeb, + 0x14042fd27044254958665e0fa0ef7ec155c9079147eab6fc55c9d8c35d433a04, + 0x21ca73c94e245ed00ec13dcbb943bf4ab0ae1c29b0f3c2dd27c7ed414a39c2ea, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x20ddb53f4160aa862028ef9ffc0ca24edc8e7ce304602be7e8db7a7ea7aa22ac, + 0x182fcdfa75858b86631ea8d0e0308f3e1202f77cab67f448c118d2e47080c137, + 0x28cd7a17b0f3349700263450f631d80337f6f6e490e8736b4c322f77c6eb94b5, + 0x4a6cffef8bf0db8c769ef391c25c8162ad2588db68f202adc27f23e01199f97, + 0x1f208c20855afe52522395aa73d971db1dc111dc531adef15f24a91fd6cf7085, + 0x107fa0c5c5aeeb26505669eba119568c4e249d7c16da6fac168de7abe11b444d, + 0x210dce59a46fc548ea60317c73249bc85062f0c2cef2944df4484f967c6248b9, + 0x278cd8d83323de48695c3da57cce026e001525a3dd65bc57ca2612b3c6f1cd82, + 0xb9cb7e4dbe036abc7cb070e610b96d61b7fe2bf29a4aee59d5f051bdf1b942f, + 0x2aa13fa2731b295a9974aabe82b9cf343d27373cecdb3a83e03e0aa3af07baaa, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x11e4ba066ef8a6cb251a9704dd23abb5e8ef31ffc2048d70400ab4029486d1cc, + 0x23578b304fd7b3d28d886e3d71f029c849885c84f9488e5687e5be7fbc2d2e4d, + 0x143068c60714bb1eb26b0991681a9117decf370a9e1a24ff5d2163fb6c8bb770, + 0x1a42d3af21b7f72faee430f085becc8598c057127907373ce297e1c1493715a9, + 0x260e79c967c0d5bc720f95ec7a7b088051dc85423f798776f2de0e8c26606002, + 0x2314b014bb5c57a4217f48112e9c91186bcd27feaa9a1f3800fc6b2fb6ada2d5, + 0x10ab73560f145dd61d66edf15e597c73871a80cf0645b714e6e7268bc1b59bd2, + 0x2da780f43e972a1ea7844b5cffe76215f0b86f708c3d0ebc758024a3328c67cf, + 0x26e5fd2c13423aee6c1a543b5d4fee91af5ce83d74efa84dce6ab9323d1644ce, + 0x91cf8a0d9aef97c341241ac92fade04f1f21f20c9af67c55a6a63626b73befd, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x1ac2da30c9db6a34995d64973ba9137283144b108b9619f678cf3f4a95c096e3, + 0x11376660bfc8fe7104c949626d350f6b0dc1b37973819e4797017487619ec25f, + 0x21a72bfc29af637d0a76681e97a310e9ad1dc8b47a66598807e88fd34a46aa81, + 0x1d61ed0d0221cec05abe9d2e8c0f72cb74cf4ec2df3ed582d4acfc2afc972f13, + 0x2cf2377f25f134cd525ddc0a210ae1edc91adc51cfbd451a7b280d332463fbe0, + 0x128d871cc9d69dad9adc58ff843d01210527b2e434fb21b3770a9a7e639cd55e, + 0x180f7db2b079ef5027f9e517057b6186136b6631556ed4979d115704ad305729, + 0x271f62e52e4a218aa6d6af3d547117c04b4c082c24950714dff89dc0ca70cebd, + 0x1c33419ecb6f7066567d7fc5addff3010852e87e68f89d6b6dbce38850401526, + 0x1a75ac0eb3ff4f7b647206b926ab9b6b70e54815c7d169de9dfb34b4d9baf9ec, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x1662417df464715005ce1228264c58708b62a54eb3d0300c7e2ed1017828f1bc, + 0x1bc3d8189b4c0993407f585a4e859ff2d038b607f678602ec2ee5af423dae356, + 0xd1fdc7177e273bb5962f8ade3aa5d858ed7fd9bbd22b2d9856348382e8481e6, + 0x2e847d92b4b1cd7198df2d2bd91b845c52b9d1f25d685bb54cf43d7cdc06a89e, + 0x2116ff3bbe130b9b1bd4b76f1cb4b4d7c7b472cefb4d98dc08789dc993aff289, + 0x1057a54ade240ea545bac05e9707460d7f0e1930cb04e460e261852a5aee96a1, + 0x24c6693b4bafa19500e73514069e278c2abfaa8370d62312ac7dff2d8f973327, + 0x2cb268850f0ed89fdce142c8511d2f583a22e580cbb3d0790e41bc7e47420331, + 0xa731e96f407cbd92e535d4a18dd9981ce5c8e4ab15bf7f5eccd29d831b0712e, + 0x9f9e3fd0498d86308ea480d5ffba80e367c19fb4a78b11712dbab0011cae43b, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x4670b146f637567754612aecee2b9bfcb842e7d6785b7904a3b1e37b740d4c0, + 0x3c5e0facfdd5fdebc0255a4f78af5fc16c82892038137186db5687475ee26ca, + 0x23a34dc39f0b7bdf631f9c88dafedb4bade20015c869fc463a25b7c483254b57, + 0x20a919d5f1fb9b22abce924797ec204d7cf534a9c5e908e57315992edc06062b, + 0x41f1d89022bcd40dfcd978191b200f8a2b7adb2168f3202b4f2dcce8726d922, + 0x23c914f4087c43ee789ba6be9c4b99fb032b7b5f65ca9f3af46e14dadc38134d, + 0x2d61a559f806a5e382041aeab1d5456dd212c3018ffdcada5235fd842f37ae0e, + 0x2e5457db2f94992120c5c9054a6a45974270109e5c6b5a4830e175c812549aa3, + 0x9f4292ce6a22415c7f83c120b5613b9b66fae13bc8d1b1af298418be41079c3, + 0xf82a2950fe7f2169a76eb6c5ce246ded654db2f03ba27e88030124d9ceda7f0, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0xc8a9b44c11b429d1cb9eceaf7f5501e9f0a400fbf4f0ff3fbb5f977607542f7, + 0x116275de531eb4f4861812d5dba5dc91ac027d187072cd9aab4ebc5c316eaa0f, + 0x10face39f20b71707fe83569937fa20ccd528792796bafd01dc9e094ba7336e1, + 0x6cc30ed5380e3e57cb30f3cef40f3c49819eebd7784a7b0de815fe2c007956a, + 0x11e62c7d02773e2a4bf5e2d96b2e2a7ab172514dadece61b41632f613336200c, + 0x5688b27d4a2435fb45c8d5f3743b0b1cd380ba6ddc95abb6f117aadbdc83736, + 0x22e95383d9f4bc94e9e2be09ed243d6114041ffc729e7edcc238dd82c7d5ad19, + 0x1dcf7620094c223d73dae01624272a7706c44ea51c959df302fb6e91e70f2501, + 0xd686d6407ba6f204fb927b3628ab5becc48de21f3979f6818cf12b76f7a89c1, + 0x4059e8835ec958751f897986059ac067fecc5eef0911b714170e73c389169fb, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0xce22a6f7aa9168150d064857ce6f891c975c3191bbff919474702bf4c8d813, + 0x194f2018abf3467e78243e36ce971440b9e8aabc83687a0851c048d7eea72729, + 0x29974bc9d401f128049f4732d6610eb9f269743fa28db231db6ace55216d7764, + 0x23ad853475090c61403fcef91ea2d8a36afe29741569acb39f2e5333921739d2, + 0x4efe76826f38d11a7a761748f9622e4210ddc38454bb5329eb9cd5ff5bf4556, + 0x8a2e45b2884b3bcb463f58ca3a7e4f2e7f16aada17a609bc358e339486ea6f9, + 0x1c22ab2592802c8f64a76cbf083074d7d72de9bd3f8d993467b00dec27c6e28b, + 0x180c18b59f0dc43c04da21fa47b4bdff8fcd6d845d886f71855c212307514f7b, + 0x146346178cae4f0bf5bc9dcdb8e1bfe21a0ff0d80abf33418c72499e70aaa225, + 0x301de4fecad713260a57d4ecec83a8e4966d1b89797805c4b8f2b6be9561d1df, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x80ff1bccc78688253119861fa90b44fdac2f5d2708a1be1225696d47db0da7a, + 0x2e8300243648b888b59914509ba219649e3f28cbe190cc3dfebb1c083a7a7fe9, + 0xcda045c07fc05561a686cfa9e82c9fa0774f17f34450dcfdddc1d15f88b52a3, + 0x21335dfd5874c230f903aa6249f64cdffaf2b30a19b4f8b9e42e6dc7472f3521, + 0x2e7bfd8d6d903cd0d2722ee33f82aa80805629516de6d9091afe9a1613183c05, + 0x443b099429cd33864738e414391c37d032dfc795378e8439afe62eebc49d241, + 0x215a81cf42f2710c48f96513f2d1ee0d350ae57ff01c96daf3eafbd0b769ae8f, + 0x156a1611ff9933ccf069fb2156159851c8fd02f7fc27bd5bad61ad00826c72b, + 0x90d3ac25b80c0f69e9b306380d3cc0418a5de630ffac363ec793a0fc54fcf97, + 0xf53453418098174e3a6214c9fa8b59792048cc0c963b668feb4b79fdfdfe4d7, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x167dcc32fc7311f7c5df9a1d2955a928fb6a1ce771019241fa491c655c697381, + 0x2a191b6a2f8f96da4bb2f91cd377b32fc8e84aaa857e976fecb7dc98bf518a03, + 0xc2fd4887d8b704662b62339aef5380e2cfc1eecfde9a4c9c14abc52c2a0a8c4, + 0x1e630649bc36af20c735f3e55a10e18fb1192eb537dad2b23932079a5e3e039, + 0x210302a02dd75f2d3846da16ea7c309911eab034fb60adeb5ba69c1b31b8471a, + 0x1d9e0ac6e8f8b9bfc77b7439b345b772596f8cd23370855956e42366d42a172d, + 0x2a6cf61cb3658480617be7daa4072efe4c2063b9777c1fc7748cf00ebb670067, + 0x2c6d225faad9f6f0959163a42621d26c7c91941196ddac67a618b390bf84b5ef, + 0x2d2cea26566fae8c2853a5976075b6d73da65b6a7156ab30540aa9db05d9aa29, + 0x2e13c310c5e84e55bf6453d9cc647f87c90dc2625f366a6dd61f60a0b38ca3dc, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x18f8e2508be0983a6ad4de69cd797d5f3974c5f2e4ed2dab4e67db7b13e9119a, + 0x122a34cadaaf871dbf14a2626be775882ee4653beeecd92d742541350f929c10, + 0x1eaa9c56276ed20072675773838cf7f72966a70537bcfc85874821b40bbcb7b6, + 0x10e0b85cefc5748eec9d7ebab1e9cec57d580b3d66e5b47772b1faa267eb7fd4, + 0x961d96cc4f121a184a78db78c217fa96c22521ef88e9f454ae88ac934832633, + 0x2d40eb8157494a91a99a67959fbefa10958f2f96111d46461d3abafdf3f89735, + 0x21807e2e88a4f906a998c7d9c6a395aab2c1a09b38878f047cd59a2e61f8f85d, + 0x2e19eaca5d16c8bbb6ef892613aac237eb47b65c64deb2d167904d719edcb77a, + 0x16714242c7b7e789d41c82a4c9722d57e294d6a566f6a48cdfe79123f8c1d32a, + 0x5566d38792f0671ce10c1ad7e93534075f422f61928eb6c2e4857e2ef1fa242, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x13290f24b105f48dac27734782f076151f3192c0f432da08f73ee09570c143d6, + 0x1b4b953ada89454c82b19e887dfccc01784fa68082bba9a561beb496f267eaf8, + 0x2613eebb5f02fde5560e2f1aaedbe7ac32199983ff9ba2cedda7ad9a6d3855fd, + 0x1aec57bd5745a26c3c0219ef96fa6c69250bf9b6584e371cab2aa2bdb7ae4990, + 0x67389e348c3409b4cd299d8bce723984b5f2e95b0be560fc10132d8ef8d3e85, + 0xb0e06a1e7dc543f9187aba9ddaf2e32d32ca8b8a5da85597e6ee5fda0c9eef6, + 0xa1fb4cb7fd491382e2cf3347ce4ac8a42342a72afd1a1e64eb0ff970f54d5f9, + 0x1977003ba614ea8e81991f6f0d79d62feec3b0f15d20d899b87382fc3fb13aa3, + 0x286e912fa4b01948dd7b1cc0251084aa96017f4fbfcdc6c743feaceb1dea753b, + 0x23370231ef55f59d8f37515ad3cad730625e79325fb839e1d9e9c2d1630e6ecb, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0xb1cf6bfcfeb3cf344f8d1038fdc7b9faf945027ff5bf710d10286df9cbd4ca9, + 0x123d9a409d14c996b914c9a56c54b02c25f4a33a3ecb6066fec4a77c6525acb3, + 0x89f21498630a31293ede8725da4179396e31708754f8f26935a9593ab1c207d, + 0x2f5bfc653853a2d74ee03547dd49092a78177c6bc16eef3d4513709040705202, + 0xa18b08811ddbe006ac8516b188d76ed6e8abb635697bb576f438b5eb234729d, + 0x1e0fb18481c8d9535410561b4ced6025654b74d7caac3e4d487143d74155f7e8, + 0x936106e344c77a4425d0ae924553340214d5264abf959ff5c3de4cc163fac02, + 0x1abeb831643365e91e7266135607235fce484149cdce1551fa4577791ff62fc, + 0x22892af37e8064bf4d88322256bb872e0d733c032d1f7beff2bdb749fc0c7d5, + 0x29b830534e780d7205e38ca2f9ba43ea1f1eaab7d08b6060a9a8e52e1cecdfb6, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x2ae98ec328e9150679a246222b5122c2c2e35d2044fec7950832b9774900bcb, + 0x155494f37217d033e8d586c6852ec501c6dcced5096404877c788f75f09c95e8, + 0x191c6cdbbacbbdf644b3bc357fabbbb79045e3200f2d10f824dc4761ada0db41, + 0x2d0f68dc5a731e30aeeb23a76c2d985338f7cf7aa1db7452ab7c05f6b96a1c12, + 0x8761ae31b00851939ebf81f3201610f53702765e42367d15a5a64e4fc780e75, + 0x22259606cc46b6876ed844c436ff76ee5dc734754a91bfb977d2ae9f620f738c, + 0x290031eb3efbfdd567219f6f69b6ea098dc1c7ff13db57bf22c699d9061923e, + 0x11a164ee321faecfcd283c24baaac523e609ad4dd6f6387206e8083d8ba2d08, + 0x14a6a424876b86e06f8a891826c3393bf9a9355f0f705d61c39bf65204a488a0, + 0xe1d8d72bd4c192af2d73279f2b7cc893ca0be9b313f90eeb64a5fb69e7a9771, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x2720b31b0b3687a93e8203819f9fe8f41591cc67bba0bd4c050339c327d0a6c9, + 0x22ea080102094dcc01da97ec17bd1c5ff0e61f1afc3567ba2a4c79127e16e848, + 0x7a0740ef451bc5150556d1083b5108eba7660ba47f5cef92df76ad0cd53fdd0, + 0xc191e9d1d2ac3648df5a9fa6a347c9ed3c01a4176091e91f8191417c885b674, + 0x21a6605ece262ebf5658153119ada85793c68dceeb560782c533e7143c53435c, + 0x7b585c00d1974dadd86b01acc175939143e66f0dff55a7263b7f70507294f4c, + 0x30570c2f5807b56cc39cee5e1164c58506d902a348dd400be3f3ba1ea9b918c5, + 0x2724ae7cb7eaf7d39b6ab671df9d70a260fd1691cff81987460d2c19f200fb9a, + 0x112877dce9f6f179eab02788c44fc9da3d64b99966a71cedbfc4d5ce1606ee80, + 0x3006485215c00900e3c42c74ec9c58c6fca0047827f238431e387772a30febcd, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x2f2b423c67329cc34adc75ef955e65a6ecf5fecdaddbccc7c69de3a12ae457, + 0x28020df7c36abcaba69762a94eee88063b5f132efc9bf99a8283d4fa34a7a1d9, + 0x1c1e47e09591c1ec91b7840a307819d89c19a567d6e3eb2f8fce818bafbde9a6, + 0x1a84ae16924b521e378f6db619d0a094066209f18492b604c6a8523d9574a4bd, + 0xf1f1f4fe16f636b8fb7d1aa4cecd1846bb37f73880a09eb9680ef2dc49dce4a, + 0x2033b19b71951e7d180851c4c0b54cb8e3d1df44ad55e08de3c10555ff434c0b, + 0x298497dba4b52d50c528b089cf9f51b98c797b5f9f1893df8bd71d6427957ca7, + 0x7979509bc42b0bd1855c2feeb4890c5a2e5cf6f6cbad87558b11b82e43ebab5, + 0xc027d8065b422a5d05af6953119cd1451ecdf3b1c2b49048bac9ffa19a29571, + 0x1cda0318f56da08e42b609732f23a762831ee22bd873a8565a2923adebd88e76, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x109f467daedad2bbc6b984902be029aa07e7241a63ef242966db9c5b584c39d8, + 0xdf1e1a43181d21009c9873cb22a76337ca84b8196432cee8eec9975c3c1b9cb, + 0x20e2202c033befa6d32f13f6b4426e40121c40ae7cf8ce57c8271e0d7e5f1315, + 0x8fbc9206e82a3f139c8b86fd5da23bf86a2f719c6b7b7db42c10c62a0280bfb, + 0xafcd3b41eef210253ae3d684a1f816f6772b2f253c2ebba5b444b8edc05b775, + 0x2ad7e0ba8acf03ffb2fd84b30f89033119d3f34236df92d1a985d3a71faf5492, + 0x235b9840306c9bbda7e11c12ed8805fb2de3127555334e216bff8defdaf3fa5a, + 0x108abc439242ac2ba789aca0ca17f761aaaaa7f90be1398627dd51a5b5385f50, + 0x64cfee2a05138648491938218fb9c287038cfa0f29397e83e914f355e0f6efb, + 0x169b49780138618a4ac7de6e164f1f8a95dce8dbb68be3737bd1d1d17601b583, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x37c1010183f05d3baeb2407c7105539b59355e854ee6ba69ad0ca93ffe304aa, + 0x7619f4a716dfa87c4180b37779fc156c1380a593cf4686b92f519e35431a0db, + 0x303a616ca0c021b513b39d551877b764b241e582140cd49c66650ed748742f6, + 0xe0a3c66b892792aba5936d212c510a929571e260f7ebd7e4d8fda17bbd6e4e, + 0x2db87865f56b59e6db18e9fa23e4797466341e3114f73d04a77aa96b0608289, + 0x16b7dd14f376839839b33d74035959e364029cb5ffc4a5197cf2f6654e07f9ce, + 0x1282d2dc0a5418205d397ca3b788ac90b617ab48777a3d0754f288e105bf0aa1, + 0x137494fbdd4f68f089812314c259f9d55b6f2ea9a5e01d31df36953bc67a6cd1, + 0x27939a8ae7cd5b8891f1effa260b4003c5d1f3588ca41b51fa66a15fbef587a8, + 0x209d342ed11c9c6a95f7beba1d6ae606dbb91d53c7b125329540632856980819, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x2374ed44c2bf10061ff872112598b048396433c0e99ee618a978d7b52eead11d, + 0x5037cf03e8e4060b62671b6b3738c3326b57462d2df714d312dc3cf902e3499, + 0x1bdc6d72769d56d435d2664fc00867d0818ca90f30791fd9b2b1e397f018879e, + 0x125626a10725e4febc2526fea8f28eda9fc9facdc3f853bff34df2d870b6760, + 0x6d4bff3f90a1436f9eb4cff6768bc95d0748105b6bfad3efc469005b74dde6a, + 0xa7e7d0bd3eabab06af826e769285f473ba07336539872edfe4291e7d10f8863, + 0x5b7eee126f854c941925eba6d02d796947eab9ebce35b78f94b68068b8e2577, + 0xc787497b88a8df57e716224abfb8238149ee8cb2b41a30452ac5c8c9ea11bcb, + 0x12e46e1b82dc0fc451122f0d73c36150bbdac4266091f6f16e887c29e6ab3e66, + 0x13fd578c074db81ea352cb09285b53d7e8e9979bfab7cdbe954f2ebdb014c9f8, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x9d89ecd0e9e76d53bab1d004dddb96233658cfac386ad366c614e0b270f97d4, + 0x1663ce3fd8e8a219e95598524d0a14e95ec2eddbeaceb5c91e3325f03b811cd1, + 0x2d7643a55ef8f191a8385f26b7933068bd8691d8bfacc0298edd54b5da3a81b2, + 0x10ef304c05d0641004092988202bd102a1b76a155469ebf41804b8556370ca28, + 0x2058baa454c35fe9ee8b0a8b6c3579e00d8dea44db1f036f286f8c1c5a489e10, + 0xfe297ae198ed7e6fd6836bcbc60670d9fa40d8196e48cd5e691b04cc7668744, + 0x1dc4589f1ccbbf2e48394a90cd3cb121c3bc56576398e14b37f117f3588e6156, + 0x2531aa8925a4e146a2178446d4213afe2b4bf59537090877084e08abb32b46f1, + 0x2b8d6fb09de987c69fd1423ca5ba68c7e47f24326997ee6ec06b27bb8202fd79, + 0x2cfa7103a4e60296297b5ceb2d5a59acda5b0f1c33c19c941a05b9c310f25ac7, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x10202be4306b5ec29ef575c5214a35a3ebb8c8e808c572c87ebfa388b13e947b, + 0x1b5aa16b76926df627ac1ec6f6c12602520e67cb23106c456063e8faa4b902a4, + 0x19a92337476b5856c088850149772036f311a5ff94f05442f0a15f23c5c4df81, + 0xbe8fc498e64abe93a3891dd69b068a200b4fff681cd1ac1c8b6c0dec68489b8, + 0x1a0fc42aa273470caf30582564186291b8d122dc036309656303d48a9c3d5547, + 0x18db0efcc7f60ca3fcefa9809141bf46c3659de012760d8a1002f771c77971b8, + 0x1237b3bd8e9218944b33f45ea4c9e7872be40e3d71df354d0b4d22424152274e, + 0x65c096251bd3ae0ba92367a9db4753b90bac169e7bbe2da1a23ae3402e45d27, + 0x1dc83ef066fb306e222db36b1b368020ed31d2b1589cb6ec2e84e406213c8e04, + 0x2c1a8e6e5fbc28d95ac7e784228ac12d2d28be32c4fbbafbf21c6ab0776f449a, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x17ca0461bce08a8a8853a8f49f7e9f52ab8f3d8a7cb8a925d4dfd834a92005c, + 0x1c90c977e1daec74c1d7e6d3ed14c7d41a17fec6d1440fcb3cfde4945ba43b7f, + 0x9f6aee2e43570fe682544dcaf6efe50f273784349ee907a7da08cf0a3892a09, + 0x1a9e810a073d7982a50a4a3ae97e16ef3cb1e231fe0aad228ddeff415e873d34, + 0x25fadb922987714ac135457abd253469ff387847e625a4f376a21f60c54aacf0, + 0x11b65d5a4e0393733848b5a18f5ba22c9df6667e9b87075de2dcca2a6322e980, + 0x22e9e700cc820ac9dc080e94407b9c18adc135535702c34b64005803881d3556, + 0x160c88605fad7ad65a5b926dc177fa9799c951ae17b067ed62b06679a4cf03f3, + 0x1dc2851df6d0947e5b3c9385544d31278346d45806328142b6d3b25702bd7510, + 0x8a42ac9c651c761dac4cd3334d8ff8541ecbba391cba04f21505589f39b4d00, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x289fa0e8ce8df0c60be933c0ab3902f988a6a59adc39dd4d87456c88982edc70, + 0x1e70c2b91d3d44777fde9b8672508185789aa7af7d0ed1b3e08273c02eb63201, + 0x26202efdbdd93fbc22b59bb52b001dea2076ff49c1bd9aa0ac0e732406f85362, + 0x665130b10a00cc5088515f8e16903ba3156fa42285bf0b9d1cb845209425be3, + 0x20a044a5e1a405e1ad5d751492516684148b3755b1fac705fd6b6eb666fde2a, + 0x2640e021b9313db742e534158b3737b355779eb05ffbe6257bf3a96ccd0ebefe, + 0x1937f02a9ea7e1700da7773129f32911d991f2b872def0f10a176054e332ff51, + 0xb198e0da024b3dab3d6e79f1e1a0304c6055a8ea3f4f93b0ce24c6ede206873, + 0x2c0a30d51449d8db5f3dfd12c4dae7857a91ee88e297208dc151ccd8be4f0870, + 0x187c5f8a529149c6250007730a57ba31c7dc0461d40fcc17326702020a21d33e, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x2085c1bdf91d64b88fa27cfc4c08e07efa31aedd384d465f558c3d60ffb0565b, + 0x25af25414fef41bc7e5f3320cb78b1ad4532319473caa7cbad0cebd1a77a91c6, + 0x1a1b25a6cafd3bd28f97f314456566c05ff153beed81b1db117f20ff97f132cc, + 0x2d9ab0595a2025fc0cc0850b027cbf4d778dfdb36b3f49fae8029efb2ea63f1f, + 0x2f30cc9b0e5b85bf04d9c921c26195c7431a50a6fedc28250bad8d5cfdae1d39, + 0xa37b2a74bd14072efd62cb285eff2901ae78fd90dc17e6fec4676cb04f244ac, + 0x1c424788fca025dfac66c90118b11c8272d4d68e315879b3bad72b595016b1a6, + 0x20f5240469332dac40167ee37438a75bd816dcc1fb4cce2ac7fbb77adaba5be2, + 0x38722e06b9b7d6ba8232eca553b288225456b08a94f8c0722196654430b5221, + 0x56eec5b756d6945d7f1ec8e5147ca2765ea9bf915399d7110f15bca953cb8c4, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x27f0800ddcac9fa1f1cfab29f40c24fc7d4ca5b1590f2610520e88b510a1ccb4, + 0x1a6a8f6f7e612f637ab123355dda1d4bead9dff6643c35d5407652a392e70382, + 0x1b2a744cbf0e7326885b084f907e7756f3212136d607d074486fe4ac707a413e, + 0x4abaf721c7350f1696a88a898880c58962814c3821b12fef0927677ffead3a, + 0x2f194b7fb646175f3ec81abfd10bc33c5deb6b4f69955d8e37f90d5619bb1f96, + 0x1457d0d9729fd924f98a0ab82c379d9e1fa349c99ec5d40866961486f9c9441f, + 0x24022debb2e2b1ebc444755063ded047216aef7a53efcd357c33bcf18abf7d78, + 0x2f1a9fa9fa2d06c6afdfb03865806fac1f08d5b64a4a4102dd69b8ffaa16d9f9, + 0x2a39c8affd2c36951f2d65ce28583cdd27e8d09b3c4682d9a91a8e6da20f018d, + 0x6cd4a8162b4407a90a632bcc6e13d25a93501cd27df389a7f8240da9d0fb308, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x240bdd87896f169f78702f2fddf10472d1e56b0c8dca668c3be9c5b9fc922f8, + 0x3cebc8d717886a58a2c2a2bc572e3f58922c19e6a8026dee09a8aaac59d9170, + 0xf2ac5c2f8ac681e231a623034707fabc5e81b7c766c12db359575e5402982dd, + 0x2dc50cb75530f53c584f0db1885d6c1fc03009cc8e8f8abc50b5ea096d8cc1f3, + 0x94c8952fde36c4126f4df8518ec3f831fdd80129f8fa8ff1b87d7739efde02d, + 0x180e29433d8dc3cbc26a9b063087678e5b7569bd759c2173ad0622557d942c0e, + 0x137513995f9a52a60cc08ec51aa5efd1f10828587cea9b2a5d016788021bd0e6, + 0x102c8b90ff6c327d16952ad18bc65d9d6efa7dc421443ff4159e72b02ae2cf2f, + 0x29f1e94ed28f72023e6584dbc4a4c090c6c5ee310d8b83f0f191ca9a382e83e3, + 0x1c5292bf3034389addc954d33494f4231ee9adaee58686e630548ff0eca63191, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x1430d7953574889945b2851241e066ee9d6b5cd11c106e1fd2093d691a164ea, + 0x1b3448e3a38b05b85a691e2df172b46c7501f3ca292b5f484dab6286f4a23edb, + 0xdb96c5859d2163a39d6b3ba31694b603706633accf6529526ed570fe019f001, + 0x21b598a7b1f1990081af12292ae6d85107d314c05534cc1ed39f7fca3280fd0, + 0x2110995ecd4f7cae17dbb93117661040a5059bd20650a990dd6781e6e773790e, + 0x21893b6a2b4a66316b37eb749dff8ca4ee17c8bff8632ee3765f7f8fe572b0c4, + 0x2ccaf308f912ffd14b46f30d8f8e2d4680b6f3ca217587a4a6c1c1bb840f3683, + 0x10be28be53fa8a09cda9f67606978013149dd78dbafc39b3e4ec0ff2ec75b2d0, + 0x17e826d4b7b4a2040fcba809278bede0cd4a79c0b0da81342163270a1422931a, + 0x9ece717307f52d17f18b7bd204324209c011daf9ef789973e69f9f9e09940ef, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x21c512b8be5a975e58cc3dc195f284a90a921a264c67f8723a5c9fc79c4ee590, + 0x1a9c325e96a34745f686eec8b268877ba7aa0d44b11f59b4eb11b24ba30ab1f6, + 0x256c5ed746133373328079945658a21927e576985c8c26c42fb0e27a37aeed5c, + 0x96dd009241c6a5a268d535f5ea13cb1f313735cd9ffbd97f580477251073fa7, + 0x1b5697a3492346753e3b41b5f690f4ed6cae7bc246e9050e461154da63b72346, + 0x212e6acfb305068286ecd6d2bba2ccba4bf952487d7db86840d1bc35d1890834, + 0x188957819ec0569d19dc54c6a31fac77b75a89c8190ea57720a7fc3f7e6a4917, + 0x551b30aa085a016401370424d8ec7b729442d95c263ab077ef1f717d805ed6e, + 0x22883b03ba4694c2602c5e0c148a2d8b142da732f2dae3402732527f1a57fcd1, + 0x53a4c4b2055a58c5ccb0f23464de37cc9c3af86cd2347d821612c4b017e8e25, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x12ccea9183993e5d7dfc16fdef26d9f845eed10de2fbafe63008e29d3ca8b507, + 0x582c12381fe92ce0cb41392d98cf0bfc811a96519d717af5ffd45c6ca1679b, + 0x47527fea0d1a194240f9d9f4c5198bdd620ee5041d2dca5db40375fa6ec11bb, + 0x9803bd526d49e31dc0fa4188e3069b7ad81f2d6391934de41df4aefced4b086, + 0x21d3b002266d0893a5e7c1a7bc7ad2f2aedc63bca12b0107670b271010c2c177, + 0x18f7b09e05bf3b680428a2d2baa51298016ef23bb71ac95152bf75c82ab4cd2, + 0x18bea4252cbd7815e4bc3bd34b039be2027c226b930eab9cb0714c2ee80139a, + 0x100f77a4054eb625b22130838ccde66d21c66b6a4bf8c8b10edcd1d48665b7, + 0x9c8b96501ea765284653b0d464445b012086366ef33d57e3a9e388e740233f6, + 0x6c9ac27ccf47da2979230b1b6f6704a08a30029752acbf49942c1962ea2f9da, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x68dfe569c59fe117f04ca4d04df9a59ce5c9327ab88894f60a8433cb3bbc7e7, + 0x29e21c7d1b3fdd04d0f89e3bec6e66c41347183faa487a085bcf1ad2a446319, + 0x61ac0b5b33b8d667219f7663fd68c937c548d342bc27e5f398b8f12c4fd54f9, + 0x2e8eaea01526ea362b730fa76697dcab6f0298fd91f0ee145ced504a164bfbc4, + 0x1bba6639ec598530de2706ca4264f5b42e6ed5374993f5517d407f3a287b2902, + 0x1da74a23eb1fd7db1b30cd5942ac540c379bc74a3d1e51d5b0bddd2087ed100c, + 0x2a0e3100447c818717bcadcdd0b7d120224d203c8d9ef48064d7b97f6aabe593, + 0x27753925a34a26b8a301c8531ba88815a976e1836858e054f90d6561c4373330, + 0x2370d8627c27ecd31b2b6a93c33ad409a2e785c8798bc444f361d667c59417e9, + 0x24447e984cae81901b8c1668e8a11d94557b39ddf2aec74ef457701e00d51e6b, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0xac0847e3de8e5f007ad7427f2555515e4079bdaf0b0e34b4be5e541f482f33, + 0xb2c4754b01925272d1ba4359fa02c399bdaba806b32f51c2285e2c16bf3316e, + 0xd33fb4ca1a013eb65ff09dc85098969747083ddbaf4e0093d86f29ef3948fd7, + 0xf06aa40d012cd276378c356edd414c02a77abec6bbbe8520d90b8ab96be7304, + 0x11620ba3b59e9e02401b1023d0e3675c1a26d896908931f88ac8f487cd408d26, + 0x2d1783e31f3c242476318403db851fb1a6b826651ae10aa2c8c6cee8b71e9bba, + 0x2c989d933295a819e388cbb736f1dfc008a813b11500d7a5d75c3de45443c7df, + 0x185d645f3186249ad6b20d2efeb6ae61ea7add22139c06f0fb143d4b36428a6a, + 0x295390e4301ff52cb4cc265685900719cf785fe42fb3fc7606eea8402d2c3be2, + 0x2cff591766f8ed033dd1004a216c9545cb1be5c235f59ac0189845a3f0fb623f, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x1d2f561702487b43d9f7f6583fb8a342c82f15053b53c2952a7dd2d32491d880, + 0x1431b6537ec76dc2c30ee7476301e832700ce7f638553e84cd6fce7d6f14d7e8, + 0x9f68e9512cf4368a0b526aae1af2bfb818655c50e8a87dc157f83d79b409a00, + 0x2e07015e39f5f8af17cd2d0d04a76917c1b6c30f0b3bb3c35a24d099249b17d, + 0x22d3936579de1b153c68258f36a157477c7c746fbdc4f9f3d8d0ab07d651c28e, + 0x1c1511375128ea34b876fdf17a984c28f9f5f551b8f5008a559875d627caee62, + 0x142882177b08db528d3e30ac62d3325ceceb585c4cc091e5070a79abc3105fea, + 0x1a168d198284cb1386879a2642bffaba7bb7672c91bcd6c562be03e3ab636179, + 0x17221d50c79b06811d1d66e63757c063ce62dece8b1359c38932b53e0c199401, + 0xd1d4e722fc75c3f4931701cd9ac240a172a8e3b638bafba1c99fe987492809a, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x27db073487a124e2eef709dcfbb41a62f07ee32aa952f69af50ac486b6caa7d, + 0x268c8bbdaaee13720df617507518283e1758788bd916fa548026485c7aa9a0b2, + 0x1fde18979072c0225095c73dce75c99e7c0ea3164cedac4ee985f4dd029b9e95, + 0x2531f077c0a77c6ce0ca7024c5b150a41489e06180688904997855777baa84f1, + 0x294a5bd8cf93bc687c0568c4e29e516d90acddfa5ca2c7df81eb09286583fcb6, + 0x294e322170c9ff2069704807e64caed0a0e9f31683641a3012e867f5e913559c, + 0x2b3addd6cb0f23db00d6cd79dc8856992da36e648e3bf0ee0b2715d785d5b4b4, + 0x3135e79314a76a13df9cbfa22a7eeaaa6a5d2441ec32edbad2396c270eb6003, + 0x173a562d9eddfaf8ffa687c362e2bdc39da36db4a8557a6dc851055a2c48a2bc, + 0x612d864c1ff73f7b2d780725cffad529426a6e1aa5936875bd9aa472e7829bc, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x2ba89301ebfc123b4220c6c74488005cb752c72f7487bc8ef630bebbd41bf6d9, + 0x10fd2909f9f7f2774720ce193a4c009bc92bab7f27f959a57842b3cb2f10e622, + 0x249c1b33cde3144fb9b9bdf30e45544cb98bb9304efacf2adbf1271d59bc00eb, + 0x75727d6b84d8e427bb742cea7e88009c286e83bd66e1d6951dd7929dcbe3621, + 0x1bddd7e537992438f10091b25a5225fb06132dec4ded9cbfeeb451a034acc670, + 0x7ef5e8e55faf5d9129f012479e12e08834b5e1a38ed28aea583e7ca6ebba680, + 0x14b714178fc8031d847db2e05553dded47111455674598347dce1ce8b8ce4e5f, + 0x119e1cb2a7e4cc688569e9b87952d4b229be2265a58ed6e619aaa93f30c38f0c, + 0x21575c98afb0fd8dc75ce88a04201c36aec620f733d6ce71bddd6c4dae189c0b, + 0x2e69188594acabdea88e257c19b0aabfc728d191a931d7a5f4e7ed8370c24fc4, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0xd30b0f7b463491b93ef9a20562faf35b4eee1b0dcaaf84964b850c3fa9f52, + 0x104f6ec28eac4f771576a7ec410980b2fdc63c39d1b90c3f0e721847209e2025, + 0x201753ba0a0a888b66ec516584f333b4cd1f57c164b75da22519a89811dcf077, + 0x16fc76f1f5f7644de6bc79cc484e010dd1da3d0631ef42714cf5dd21f59ebff2, + 0x10892fc5eec5ed00fc6d5d0975221d3d870685367f211ca576706cfb083b49f7, + 0x1c59c9b6844de29584ac93a73022b6761b196e0041e3fa32f548373a84307ad8, + 0x188a3064c72ee6e3b555ce35313f73c91a154bdb59e57fdbc95d286df429fb64, + 0x25a747a9139698f6b090741ac55c98ba3e55c845dc8af25ad83d6e48c945e249, + 0x19cf0ef78c77006fa9f4849ccfcc2c52dd326a646a5789cd25f79ed84f5ccc09, + 0x1145187227de632d3deb1d625a4e5fe3886f5103ae46615a8f07e6035f65397b, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x12606f5141cbc1b9a349a9121e54295d17ff69f2f9027bacdb0ebc8a6dd2d0a7, + 0x2d1ec807263d78373ca6b3aa8f4c51ae94487ae04cb9f5fa6cb7a6155d44cfe0, + 0x2b83ffd72f83ccd4c18dd16bd1d406aee308fd475bf706f00cc287d9dcd97283, + 0x2378c35a0428264b3afafa0b782312463b724a4d281a0b56ba6036abb9d84c46, + 0xddba7feea2855679ecfe13432b420858ab5d93bc835c9a0ad59b8c011fc058a, + 0x60a0091b5a50a516e31bb6ae3023d902a23e57efdb4c571c143ad6321304673, + 0xd08421d815f9281094977237c6aa7e6243ab5cd76e38d9df19dd2b4a62211d0, + 0x165a3eeb547af156b4be28850c24586c0733767364429a0a1b7dcd2e7f99822f, + 0x2367643242f32a40574489345294604135469a362e8f6f8717c381dbef5d40e2, + 0x303a0941f18aa3166611976111e43a94d92f51f6fbdaa07557b47b4680a21af4, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x1aecf5def09ba5be2ccd968996c5564145f38f60aab4191978db8089fdb31cdd, + 0x304ebc6fb5252ad8b42ca58356799e8c6961ac84708f8b465227103259913243, + 0x26ab128903aa48b65d12869a85697da4dd7dbbab09aed508b833a398855eaa29, + 0x245567a4087a5582bb36dd3803f7008596ac2514a1d7380d66ede29e27823942, + 0x46585da7e8d6c6cf0ff92b5e3394bc0499808442cde328d13646b44a69cadaa, + 0x12be98bc0a25716e254570afde08db45e96e159a86d7d1c685e1eb2a45a4b3ee, + 0x1853379c16580675d773c80841b8b6e7db0e8a2b97637204619472145e3ca760, + 0x138cc77819364fd983a34eb109c53295de653f1d905fd2de7b6f80814fe8cc0b, + 0x2db2fee2d496891332218a6eb709848a819f62b8725482c591bceeabc1e3fd43, + 0x22e95c3ae4db1cfe5e4cfb697815697cd9c34211c65111b8fe850ed25958057d, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x14f0f0699aa9bd8326bbec5ddd0bccbe3a7caeab685d9ce7883e517164bd5994, + 0x1815774675d576817db84840bb9fa16b713472d72f4bc24c2cebc09aef0c203, + 0x2a82117a43030418e52b708eb696ab01c9ab04396eb53a3ea4194b9a19824238, + 0x1f02d515206f3d9a3c2086b2d7c6b19004cc8553a77908d534ad0af83a637097, + 0x3dd5240ce1c5530fda4993dae13bc07bee4c7994c1f65f263a2b8a2f7bc9db, + 0xc414ca1ed2f718060876a21de201d87b76f6fa224faf2775ec99cc13c534117, + 0xab48043b18014d78845ac07a6b9727cfe0b283b44404e20c5da462aaa24f7cd, + 0x3fac53034fc748ce7cf966aa1f6bf15445cb4f6f3a4a929cb27ede7928667cf, + 0x1f91737266e97b633fc63e5b0e1ca82b486680cf677b132ab7a6b4ac75f70482, + 0x2556e1170d24d8da980464376850938b361e16999f2f628e1281f5d6ab0b13f8, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0xd258cad10974250f6da3a9e068f6830d7c65f1253ae250324bfb72b50ee94e8, + 0x15e2bde6eee969fbbb22dde530a8e6117fd640972712b644ebe5b4bf0841fc90, + 0x231dd2a58fc24a20243b93b6ed5cf8b88b7a94a4137961852fb85a207b6e849a, + 0x4fcf48ba86493a6ed7afdbbd1b74fa91b715a0cab2e1cb27d416d1cfd220258, + 0x27313c2f8d4e5dd6764d672e1a6f951d50083e4e404b9c1cd22334e7eed12f4, + 0x1e8cc36fca79a1a3319d34db2305478ce58717e36f9710873528b16d4f0c1a22, + 0x266e3f3550eeee1d1e2931ff3be33ed142df41311f650e0704d1a333b0bfff52, + 0x88acc576b7bb1fd00b8e1783f7a48b72b48a529e130fb6f2f6550f41c67ae65, + 0x145537172cb306df020f911d46eeec82af8134b982f00dcad839c3c10073b1f1, + 0x897eada2a51e4cc2e55be2bab91c68a0d1378aaa4a65bd985e22cc675fae8d5, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x1fede8462b07d0a305d02035683cf29be572a53ecfebc28c77d17ff531a0e873, + 0x64cddb26305c79f75302ceef162391813ffb575b21526a2a99d4d05fdd904bc, + 0x41688ddfe25e6f627d365fc18d74efe41659d9213f25808c81da4168f465efb, + 0x263065cabd50395ef40943af93df5370ad2f6d17bb6de59b3e8e7115ec56b82, + 0x1becfb943b8985991a66c0758322e4c3f22632c199c1737f83a7dc251164a730, + 0xe01451b1ef92c997edac826766a61525bc9a345dcd66955f9ff9911b653e737, + 0xb9f01062d426904168cf7092d57e2c86f6660111475f9978f6b0608ad2f2278, + 0x2f9dc8eb38534652d3eea5e1b8de7f088c3ea8f9015ae1347004c3122256efda, + 0x2d97e9440f1fca57f227bf0769729d3dba7fe6cff7fbddcebe492e1b1fa1557c, + 0x1b0553d2ee91c3a63730d686ff1a53a0478682a7363ddd4e7ece42ba0fe0cb2e, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0xe83184ff6e43582fabb4d62c346c957a365358123861b4061670720703577a7, + 0xce4cb25f594fd996c28d4578a4a8e3b0581299a6f165882fbd1ddb2d85b2ddc, + 0x585f5827997ef8691078d8ab635cf133358212340599c51e1bfa20c93226056, + 0x29bba7e4c28316d70bafc5d05ba5a97bd5451a127ed75d9ef2136a02fb0e75f8, + 0x5e8ce714d85ecab7027dc4ad12c3a5e75a211e771db239df7b3f661658d4d08, + 0x1d243f2bab7712f5d12fcc7e4239b39bc533ba6d7e1fe98779a5ced87dcf0f64, + 0x19207f2711d65bd5cc7d1f5afc770d74efbadf057865e27efe6e61db2a83f1ed, + 0x54538bfb0b84e707e000ec579bfb8d796106da1a5e4abfa8a273141d6f6ed, + 0xcbab8595eee6b93df0d9f2545d61416af5ae2dc55a4f332653af8ce11fb42d0, + 0x1dc6ca4abd54f254c1f401b871501e022c4200688e661613926a63ce19f78945, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x164b183c9251e3f103a08c44ff9bdfdee4a7f8b860850fc3b0ddac111be2c24b, + 0x80435e71f368774466eb276b7cfa5f9a7a4b90aa4c34e1984fc4998816a9fd3, + 0x24a82532902cf98917319ef392e49cbd1c7906ebc78d24a4677e1014ceb98c83, + 0x9f961322ffb0b5ce846054c4c6dc75852776dc8dfa0c2f8b66229b3fb62fce7, + 0xb9af076f893d939a48902f2107976e8a8875aa5369806e57e8c1f6fc1f5527, + 0x6c40239edae3e7600dfd00e6cfe939db8a69799a826ab5e91f035e971232cd9, + 0x24701c675052c925f2baf10f661d4f719bf145893362632605adcfbdf5acaab2, + 0x11000d892cb37fbeb8e415c01e1cfc25cb3a25d287aeb67b247d0efce56c3c29, + 0x2caaccd757a3146300021050345effd1a9e5b64182e1cbb67653997b0e391086, + 0x10d9b51b3a086b412b1cdca5ce171ada65395036badcc79ef33f84aafe908bfe, + 0x124666f80561ed5916f2f070b1bd248c6d53f44d273d956a0c87b917692a4d18, + 0x147c39dddaed8630bf1b92249600016fdddc5e9f5f08291ca1663358a41d3dde, + 0x2d25d39661406faf935d340fb1535be9086598121d96d85f84cb586880517fc1, + 0x1a2643c9cc6f7e74f27ecdc2e30158b4a6510773a5aedf52fe9fef5a2261c263, + 0x2d5d7010ca67e74c9a4d54c50188de26c802a2e02080d6d352fd3d5b5682c83a, + 0x3060121bf7682a4f51292933031818468d050b84c2809ae816f14340a635bc10, + 0xa514a5c227f4cec95dfa029e8dd124c34895aa46bb27c0911f3780d5015540a, + 0x278bb49a7b4e44aea46eb0f882cb692801a6e60fdd5b5c23c63cd65ccce4fe0a, + 0xc399e9f67aa40707a203feefb0b958bbdadcec5ca34901d253d026a2419f6a2, + 0x1d6b3d5f6ea369c26f825d2362933eaa31ea35ec0a77c1fbd9e01ca1523e4432, + 0x24be510095436206dd0abd0b0cbb95c883ab304aa52598b1a69306ec981a688d + ] ) } + // noir-fmt:ignore -pub fn x5_7_config() -> PoseidonConfig<497, 49> { +pub fn x5_7_config() -> PoseidonConfig<7, 119, 819> { config( 7, 8, 63, alpha(), - [15193892625865514930501893609026366493846449603945567488151250645948827690215,8655680243784803430516500496316192098841666200175185895457692057709359214457,11710807066713707084726423334946631888369490193496350458331067367713412617049,15442364818086019103203999366702499670382575019009657513015496640703659810202,1358747428976145481402682338881091555771254635226375581638965497131373838774,15658002471767984962034589730824699545808755102240624650914676102923421241582,6420480504329990097173256112095253518339231893829818344055438052479612135029,15457172495394305353698644252424643614748461590123908880271021612601244389162,5745943350537490600340174787616110056830333091917248931684290284533019091654,3877253492903478989342845512796806320713689655633086736499730391667425329322,11257677301507982757739320943403112189613848490812422490591766717141506751601,16906586852467953445509312290627525856126394969718997799028223470195783329296,15263589725854108297280528692120758129000336125328939290924952731952242586386,21735940039489460025710098364749096267519151075908323637361429746399161905338,20023056608360522105358681147781839024069418874082333862551226466128829664291,5677500725280079960679484373333947430817198394184436922575072427342643665917,3080516739494460477657748111767941482024045797587058388950619118994388252853,21486496065617100719537932626843898998311175055335457507845650282870586541596,5371049178920102602305531530023787518286335086323221270202212974241707302466,3074817222296007572297581554183445947239252698770067839721345984255386069425,19180807038569629573914331337874446591506172622522351734982093457681161813141,16937785199372956273358037645552299688842385008757508130180245705952406225194,1688218397616770248184651775433764527272029131542529408516364801909017591719,16315958669815317541884966612581197291281164499674338063931623110684590850347,6218230753007070123505625054833158632732536069700963073464625252554943737669,17774528060285257656595928889288330429565059134928074258373583886985960212139,16197131592052727313460949906369199026477758140133103701908949020106767192893,13418604038232148873269488320329340508522225417123160144993642839875173062296,7265658443160253752317166706266927598319661172006072732797351716897681315157,17200150079219747370109251547638276280610591698078334228421747259741754887,8627121890622175767416692555014275717515106888840919734160364408960047296494,14546964505431549758350267964924534495477687922558528647552728692912697049247,17132720822762740343718421124251772119916072270451579802112353604446214831761,234333065870376500756753915306346778417056884715946003873280290982247600083,18375643491701271245209094287106352436174133929245169725584150600992143374298,5158448692161567615645197008737390561357077078129599243188536485308363800282,614161645152783610732075198073600394068518413590650990586931263981193439341,12661793104597977909223565537293318966803153852970198322604479648383643541371,13041905650419760925682179803296711066088286278603171065755078690359168540579,15006023590144168506070897325649191051975999212058008674224953860265667513015,4983349941266961584317889823965291023669365981564144622292227613558024302012,482274340065333833495445682213681402212945945150526736364263233985449810602,3966893131006556898236790392613869798057510088913626163333804949895810673044,20923301526284527685000591080290190641416245135554916208054502046381491809443,20838692384005825835959734210506718428443540957544929066941550833051093000166,8282357714606447781782716442854085217089572080066047419459610560432999443766,5410651444876169088887579490283094453001167796545260026969919887357676973543,15276966646285075387317940436655285872037988805762800567413073418506412856419,15066911464727337689573664613158712498015597773345106524271610486257089622849,14583790985054968382519116885383608902981814292128186470697458065499359610203,12059090796146479535492139954279038037217093044815277624197659219529427760034,7273811886044732271171500579064359282424476926867187108258957006777685922641,1463086899665237074608503061872751147444637332808872866814340325832200880984,4403177494620214359779479537027014449448686844655371530169401219256448130398,10860968418848589590932601250051274256181778387706764281989724391784015147562,5268786978207139542368199165627108325282167169564314266747401266496556301775,10683355823176907476704511935094343405052640940909677712096702771871787224727,12998090263935761477316698114799901126086030852595294916463464609721875730852,21401280461419124637791689956622923839426783908187419462727763377498739154778,9827224472048063173905906705579289843819400982583185823840008976971109664519,6215804144039763858354471461864183189301201862376216122255322421321775987311,15461308489200344015891625455653488930440613755785081602434124530381300882814,19336334695450889400681207491394600659946256404722006637851709906131899294790,1712331165786355540802697725399423752392267480553199895882357858951999960061,18153038525983970702748717571053178456148003321236490384959117581005013333018,1080183517033034908031748897211289245459330899463186432840251241943892326023,8948022108193679628295152361559653763100984324221629445749311939820327674857,9553342289560502306921915013446606435600388298465288181461633559299564421155,12714965617376828547637017050548818007690047452402682720666099310241001848988,10945704657865102635748104464461970844653553427083981539165832149959193156197,17511714411688352203059545713591160825310809755917403629838415797949261359373,9253691969419856285051096287845246422848295397226841130282244592511676512433,12218945350859454581754463621617733341764245716874083264842931063272433793037,15268139709971695434346690496076067658968455677120655340969837725391575270485,7948825129295102283421620705853168119104356217418364837218892682579042520651,6887299291348589691868712194070626390224806410428583073294593431810559288717,3610235157455454109573625364057240708256027358184031380521552355839155549623,16532488069063334064099666525339953823111673083177894678898823509406678724969,19317517725107761280217103201908049748015068578935276576200982249386084367574,14980901224290526859762385599553818204548992110637275324411078408232697158492,7741797285700915051013289492475875831764653137095445146268474269974647962596,11964233864746181868467810392101989052496076326472717372132104394243614334823,12746657111181947224582102380049766839578185276220682311596480990298620200286,6408726946032901840418309506578019708113712492100046332894630652186614300568,20959261828945984489015610988397031913577918654575078054490013338416801523934,3173674599420546165852740604987014294355430358334465189504551707066179193914,16110281513253204315524614633789708146700074483476149119440509845258215816735,17135377580103690088853370572199271964414896742342749305424508776150797285064,1405769920008485935711505753346340073052795087429311991287498566024570212365,19088073362945853867763169651582894739272002359692597239222895238839593467749,19897231284455588615416169252449008151349728648961637517447194842672488184146,20476415629812014715153863754869742189693986277342067785614833846523246536739,11074321446706734150375041020583051611133090415774365192315805856051215270782,15231367549323128694183572409135806408519505225209496441892541205465727777072,10515952069292929457050921929301902464262874744159361114100398880194109971971,3216370118771824418364829250073852356774095079734089790620447714552849459645,1940445924652458480775282556203659335417827058983719042726494187979000691704,7899310668555694144370607061960060230071621529123669746309839400642332452086,3125410912833939638823760577011271607678545358020637189655641109813198731542,2980079409624774815878860133121670095839651294537928173829312563570356348730,3766498515736372882285796238406751547889526137955288498682767455795237989580,21751217522789414135074956130080241003845828660310903627224390345319859795839,4947229586642010378772262640583556676497656670779800090478805824039760706318,2168676839236948809859825591626629233985269801981092020040909992251312517552,21172906642114648036685108008020762271569381607092920279879047961076646303327,882675742500939602754673078407141697482716600335919344527751158504426951699,20942968937722199705624825492102184647835614761458159157410261242387423597787,21880640497503102067412608072166388563991106464538369680846671301780353850077,17593472026567804917122179982860735087124786197105685847979050530954084564297,4492875530722152383516030266828166766820778742874238188105265500984280376666,6799763500412433367637987497601148507907071065930142757525839585946238894092,7812331664758167657763399273963290017340604299019483750344476103319142702775,2222332747647756867926707541092465789402467819000336747029352557749400316077,20438798382149666667185974604464532451975024544676922060351031604444896151494,16155157103796724378615022758633778903205872772589663310774455593497441785913,20281325298063880945091623185126257485818350714264176365501683813650871716911,4922178080989486450454493110764936742315495846015561426329316977670113220071,19579063976700768282784922967523980346960151903154507737857728349662090787824,2458828873355000645851832396764221987760639423132968569631493912353159373462,21166618206785010755521994106737991950548963896649678270059527421944129497211,9131643699583013708059191290958290089892787165715294157378879201986981390031,1820371114511473946932363841206094088983972935646887524223011276305844153307,7264184404232663540867032945940974372967974872966180860960243405462016972362,11228656105550475045610757902396386402555430893045183008968975441800824215261,7151503559113638565935009743218857812859208253653498318591469659718664783964,16876040581364499037941813142092448836399042253618385783944016186340703846779,10334125383426918152464737478646460879481305348617711177774418125714273980769,18900559046103390399749767994653107625464807708680067464279674225251110804100,18685667289312169245526749652972366835289568864080726348092618145885982989561,19970582871354083670567197978171723431124602481748785146813441774826500485907,15873472427137024971035326229485784626398898771525077832924901475242073457867,9090803292122260583635467396769157643561973206888822931647063181944243467413,10156295009710074552070572489422360071526675259143523597882131082376797944708,18600630374968456966046654667577076758720435487386724419578803020365834014000,21292291483064245088298314957584631356250347533568992016547598449487977536460,2784266893057214755054197979675795184619614089277590464548240934105557638370,21206743389683892419024645604723431382001453245850423743581664552645211926469,7915761821775326316473924816837591351530533394717381318596295803119061411675,21881095237485064870468603451853549262304643738646051878343976465227744077912,2011784725603622472271597952122938645154942022107573948889667939904597454410,21059869383015715705096974077910228193608826877524913363323189378554601804559,13660545486380051482020817701263881806531607595506890631732662177505270213284,10831091042775967380899180760062457635694790868286967266013231823406639854653,149288128407476550494800886735600251983375852319258454101603889073198917321,4032475033542195421623899365282946172767274020529645277615759958662043553317,17860535012887415629230166789742533149365132198763199254812432302158542514395,611194463774512114860065022851497908950074400927073001695280142990812150583,5518364261187313845085346561539515049557757056751872639492957432879259341390,783263978868449790737487156609432867806742277074765259237378374864740012575,19059339826992310300213673274315612374137067865428300882729551175173242291657,3179709304184015397125565132235783368222831063701934511986753856772139349894,10954198701843076039176000728742415722273043852061382139560487789741501275316,16411266672500930935370066093245284646483148609897099268661795671514664627451,14614816948231085620934132277599546641612327229810158468490195811014141518325,2458257206135880430320027516329707989817636936777744813891328347210486074414,13549483340434455515002570470395006683062583844603627042649952800864870013910,14465927800403373425828183741641078057513049263889255157342086762479739044711,4039391352709218793104596256671892882216573882631238721514928981154171136548,12750457082077152291009387792121930725761848879916565703854704756389714536037,20703941646953337308096638741387402857948436803334980867971163138332859477843,20148755487317949638981041809982361196106823990400472213765926589941031736503,19035096428824471222963574043396024781574056587456391309795571372815435282399,13597108420431213178364236660710194375344287228654817880431599113069659963625,16737817219786305757887002253067607822378794077688837656791543060369162185533,5164935079689729145670846016031605160169301936105766707946436049006171651941,21653381930704765824477248798502813954284378782353810890869232482999795586793,2062605478140760101860087118379474541965619844748678233207247884294051836812,6841505950265078437298089354417829781031272459823272323626556598403583002674,18723551101558427097952125661588457059960574026361073828482106612260297969553,7898804490983679270754258611113569895515918945891808074921872907759024464249,10882278698112390755842292529204069263813359338030917602809789513528936860051,19447560013395173052961224723195565400117958329259001072560983848146677205053,6251288025262210726686494480483550276704856797649458538460443509657307219922,13176666617050786358406074057104742181338809005466316548399895981897535342946,20703225796049910173111490454489910459787604528779911406172217267261190895618,20336720518722954780604743873837334696992422089627753769439653667292899832714,21420427865372074512365684526694872695798980614525900481233709853915806389425,2498895690812694987926199054702295457557454143930759961192198950277119149872,18753512301709603592612141197073246313430368834576850495154922324845448997662,13229612292359498096055458608547157785066962647476451239567069089111704445000,2690879919643532184588441383789963956137193400890598777054187145581183393168,14142396602342548413722428497204107502988046500369932366351553161157672540408,20448725195660080278132534867269279218381543910636641344871383714386318629041,2559459540570011016181396098001618067535109329950570139376049832813577592045,2209294835847631004298393339896770055851570184195462947318472391473531519454,14610669112573509857774678749257346364319969641690596877040685661582231189775,15281088465087253563674405311018738676067395725444151577815750152538449780965,8600553033773805414817363397077178137667131851961144771667772828459236208319,2748346039979601666392027583251905158817539034260921486084376270967628661657,6854960712378511006304629447898292218014632388505703802374806527561178043857,20207552563190343462280438839438087615024485494479390954719687107061991587248,10281541252271366635718295778088948309847900730867531177275273130071062184625,18855605847424121529776135453072696981767402526737712879984848146282568841809,4160214035780913418097601322951078913381556877408879904436917334405689553255,2122867135885631508183413043949777333811557914428796322029495785048111325437,18793959580906171893053069386015945646795465354959679615181136313144978078417,1043591673717355695648236328597936528752358227297053230241551190351813693314,15686469257015275311444450012704351019335987785561570672026138336552980987277,14048856209379833670666148034655599475317994357805584661156301746235313941815,1011563953969880478397969933799483261900428580241502003261587014788238280391,19240556623066672446907714818724971233422104071815927265423017590508305430997,2121904286573815063480388650799381683473766736407678915747169455786741101182,6724437969134367395210139771738563153857495313330774537559578422672993498270,20206855573383441961836932177838081339503382415601366823182724056749038447809,3659051978213562322887447057085386386485486575515693147713900345497451171308,21246119528547168535908718411570119652856799993958321864163737649108920924448,10446114322905404392321651684574668727564081327779662579984472408056125404335,10052242287865403393859620372179811039720807230902452334457123873762222543944,6373462744579965543231173757071025010089494620309953425653057223643612177083,11716070974813426833631730493593924834405915845847679294742728105127112594434,6451284530793440411577197006976867289209413848762574411101073727224316913966,20143217291446069633369261481904349401356557325260758866598205109039367201468,7741896897172494958877302103827661518814930985518070029789560123401964418102,7414486245715284930410091802521351113719159777210731898112598211035848096490,6480506916211642204624111742530825907262535747743645014149694168805302825019,18349725066341807634895742572304899830893334427067633858521634672944685466440,1838291082333887710851505844271184097051704051003105078056248035350245616867,19201915197596065583046168024521824662441686729039260890206806469763190071269,11253788423541320580105520117231178489492440242200599071301755928628199128159,6048832714406694444296771635481934823208451249770515560893368035838759154821,6398008918881249487422929614611145638894557821587972164243877575640548705346,7013037564266297435879776776659289982125632651326438965546874242685502904730,5942504790082366811245813670914617310604940200824079289270465669331434165301,14344789199380317440464969138686896230070901882253997360605407637865754361287,19920212380356573378521292048728904573841049083972983190424200459025557666792,8983390577894750782268266038315113359711163721228398686939390484499979421166,14953991148867572055684497824790735528852361750007063016470842397064705671772,5592033578501586280289038012647352732276003389059749788953239057845882297561,14076883072716069263619564306953450824526010844333044566762059693672378725675,11108270411921226463443318601950168860230077781212396032908932369105145901793,3681277588815101350213324449908372578846563884174807724121308021640034446476,7194753190480156904207319938161903897566477363779122267985209483435838216959,21241255448366937244332942306324590869759761073985963892514045368815880517382,6203071960722514588958553813186803009742459823360660333787981951206442471249,19041823565851118046937769551785013706136778514067168239416647071096062639366,4928136619692555022185087228378238193895894009623071873887735418398682287593,16266329364886004534411977872528706660422476743809029518681886596981922182359,8814684891729998059175829142248330760704444206534875755023421115211106199303,11072277000652722690981202459933101924925520292174200155471966778637063588914,15889576313969861857250394875354819627977602318110620311480656842740292435237,6934515229262494305594741689326968268143898236690173897991110238064230886755,16212991575388366798683594066983659236103186124339324856776288894513503543244,21100508914867482363389012032457112622475533432309937238082785660233880354422,10381104469089401657446748653199843213201270332853172509558263968565255702795,8849389605935865968361613766905708889092097013638425059146677490704442276611,4826404934194100291623537890117339503344940312401101713754206109744511979962,9981819567268652304810465083896863711149056310505889216307212434682251812603,16218484218588441290424553684558267080330286201433140852298971691458926313766,21317661296916247018967238829275056855142711494630067664736600708605437812892,19523923008662567951910986132173659591346561824926093935331274289896011695634,21439241836891927940168832009944210084078628922824257988298290967895179737163,3818036890597976956138669961319975835941979944306305168232209375279960168960,10212547715001519604442389033695156945619060410131175896383181616280631586732,956283172524544133830416114111944076629240232397666924807554743752464221045,8545109273807246425343308224167362024331960554428088718932211551700420545275,5647769597708100114837534314408246331518385631750569421373379085922684908872,21776221280695269311212391423788179027868152904973644113087833004348746215729,15989020831232836203074762591626149244364214836699154611339161287030952623233,9384665943619921791886218744024370375464874104981653298499433530463000935024,15469006121097295841026542766455781293432005131673839148320165243166330403027,16103671377537767724271717097892044266704736999841135349844319906338275108222,842367229428650719054831004741080336526228967970570607897528985803108607790,8752325400224955775788313769797750158375262384121380328719514077259567119347,4803861091350023344885030428100876947830986453029412601567992550504530969575,7917553047944370948250445233027936387189889293110390303835890604428798853681,16378323148632546424902611135263436821435778030958161546757828745002247975096,19873719885630097137106352132870659633926425645300622070145979694717581586592,20324790419158243246762098227260178678767896786893299456278167341205663612964,4358908354524026935988729716331497263147669784003421920394531784876541301801,14403952632095852077754539203207047943619815438482171213105824864831554185165,16410713482142323347391147127545553384558868490870150984280601225023662513809,7304216341846662695189617252648753140769311862815448449926830269690397729157,16792943782280077475956215580025612636120139194657275471595325031090407485768,18494329391227402645175320826355306995912366111176422593669423022411884295357,3277597348237827068690736756050060740435013727549848360800059544123155276133,9396765756719511114743964794180256605700037182617127755220919249774110852382,5637053961584389263881381098869862042993858662768294676971865632259649027245,1752142832257643043564515360000718468888861086573246457619082905919623770956,14504506574384680785750882507533398260948836347427103366421836731538357314790,18947994518078004413210940685748534988014581551965984303066903086446389273117,8931855168578615387850254663107425567403115805663142600825724478150698936342,10982092525200624040399870568387498905840578524691489797530932831401946309626,4738907023206802373255186532236849256768509848242049657234258536668430260775,10888145285628319545262252531874405309329869513560101920454793431198094714989,4767721624212785367044047554655794533816937807005608600525762243335180089923,4054394679973840378112083329204220302222586590732553688297938891619998137578,15390471663419625573793381445844013245022413344196724396864223784781333233143,690498740448849288977645176879593806019080276382495160049117613302192708860,3326968907274045758110436838010900592335267522219473049427145975873344598768,19461545874830130561487975864151403334363998126023624462211037468138940028328,2255249425919459031033123095731665691066980364231819200773725596456576056043,17139538647342063569964264947811360956712827863014723985947727876623459280539,262834317961189780923232082352297808796511874872711860311746704570027370416,17784213646586812350819691264737755884800773322574478474130308351003659945289,9206479615073686723914227166450906925650471865894639492301222855979337534393,5955379232184076713510750681781395826148323482009739159408415185190732125682,16345512244217240951729073298135981012471478596479891072149124888060645303490,20053701095030547796310908765544502773063879272854547881438596069907281565287,11519146559536679602608982593432194283609736022486509747046459824035493513614,10868663839942247532249591973192159672852196011910414460124452013501564199585,12668355291693420029179738224611760713369106517542315102687346083105601320689,4091011252347209563858280520339886760216002486858313383741839652119084430270,11416347683590132388448480763970462739172261435271326798646502987745949753371,4462763980178675172541782335457125059884067698347130082276003539434128058577,21728891122467658477520865529973242372850367356840114983386033432316519759391,9556106604731806817435679463077765288658189491612307664294729425381901530224,5086982973132652080709554654284904229374030594786774699435814748257879554118,2278505454992311041650060186856758463754878439802195559533882189615578260695,16123495070352975934848591912315341924608875638550779884194576881433498909405,13177225503435100563531015597038445430211235761527278782674200718068329833622,11626932451843299545922103072142674578946680165802341368625957942237790110177,8872973246419344365802198448930136062421718851114220299577394844231810068090,11920016786052130191738519934437207519332291620474831138559948859328822621221,2773753221970604083383541092979093729869734021029185810064937974430862835870,1194583082499114147792330367943150006952486615245506995832323057119894886077,15293312601348482070373672684782686300692505365845870624263228679370968807837,2292156760291800990693425534213440357167359161992251338587906324724034592198,20920049766730284147153707151387304988393631464951398563908410768221002588086,3587899345078220957148828249287269521408604837648269936718299413697642586126,5857527906708110948691023855516662527925762284342493618496858248142623857037,18312267494676788897591109008609888960798722042916784593521762607767538629817,18354455618287562133438807735729369657256664914390381320892039403006410339493,18594037435499535688023807489676900345345731643180370940972090155512943637000,6361231157299815359812386352981667048590510979947935475914610076041390336883,6503045850716008738909204934356093641022474278658078426701342798380459107813,15826908470360778431798326530563200301151807861414464213699967513881040969457,913167165738148713876672473302437265273760468892350716109373788573860454641,5163418960719047707254162004625467116036830361107107814320243058319914687515,1852750695670141634014249062360862036043602867770163972096325792863710036947,16164029969996795952250343426848596535809001568622155377829217918121790073916,42291476149937488089591434144089904529405222471677684973768504172369443350,1329340386229357940610579826659090359930768580941108555938139535621252899508,14087936453397725507000489457270864434699508074557952952329368237400407748133,11454917885298514922755456675259734718428103879515668717779418480236210705323,17749966508430836878443008025013283275306943216523661550528505419303121693213,16617298839486771009961431205770630163409905047728421465641369616889696635464,5622873871440608391107520706189063847917690892897751818294742462879871297589,13537715561706278379083684257583804567523085149672090320983273122424669242274,12609629910090871112615676094781247031353826207267723991911250780907380059468,11881347692420971451998583525696964339513193164613288356598017302547676912004,3620434358220496198439193226313617496907852030586214671337652678218740406153,16586456872124455799862826347901525401871594428044067424833235946565396779382,19602593015746956165116919928045364895525104709835703557292833702385934632182,2465427491077301663150648330772125184470808854603184374760649420983178107738,12521323976712195518272978277895155774288446093713549157148428964880747896725,361951232333654306694462853852464888974834703718677826403016226307188397185,20048343816024297162848487251896481827914904696805156112188099141327595641104,997638030405613623344188782838773314122493364653596616029491564227193697621,10932007654988104622042938184134556963651043067553327861790671211490960094259,47171599193060570819891696279547021610376047998583333086685382152080932821,14669115378939104862697280661831896914139331878760241858539421915983017116504,17868874372855679948405169936193924176514630305572838555185339642210810710203,10178296575837129106771098084407669500326673901243393867574658658064222502028,11497182727976130924559852428316615034304736115488257034951588831868596612725,18847036158089242140209840241495282890278502700082131513222116906134183113862,15514518995390761662346743876733004358408187550386554449789531199638765348953,11474102901522012346251529527050392650125347221410246734211005177721289856415,6612195415835443084676700243243174090072629504450965229103970796390091290688,11572474094368358234669561324969692616275099241307798860733942350364532366113,3855324911963410548772360326122995145790506408472649961229511965629894550308,8802640003128749594245736338745752744580147773009816234644244502373660889677,15676839305513015047736600040932186843826469281853634239081282896349443894145,11124722103091011602185413968164672678635980457394627450785290630813993266691,15087674670944618980358596427703842917302233637812357643695687556421910213028,457555060782651847600218200815104907046227486293278645126081160142069992497,5340353060455057701755599760342180989590806327490432497082435572367648024359,3289809733259936118731355294329652879189400852472418229718273887860572748363,1821386174933044868215348232606758690922944887434531299978498726875279584854,17399236630582894158137572250502674699298844870791766041927951699287421557453,16772722824042046255416248879357647708113647471330900665176012648038469814744,331374066696126093678097185404981758791664151917354547180452342655690460271,5482079579065945934120471179616600325379965440378196448353560421120276746028,11861638874356162254375133266687016527365630872709665703116365332534843803431,19751278476934230895840638614095718373810690662562196455711240141902305648888,21017623330912840225230534280017695045717261514215145256795880310933667407841,9692530233397639077769939390011937602190121885296235066426091743618448584134,7914031992737639503490179289412369887137436318696390718781298556229610513180,5046304088054212585035723354298412694927209198400753780585596829596665931980,12735457541003664856181534137486291132119134214862779086936585300598349629287,8144204472889944485922664106370529127382213990656088602566223875490414163362,5526161442679804982165840590640681348630369336752481706044759543203459722566,4665464612431440885211271075488840033628676516298384234452346107374012633528,8451965709652752887539585363308640999657377914501438391781526068371105983117,18990458193856163728406448194111866469438835810342179114684453609893347662421,14602960690767985987882800342208585041637986661619503513589079723840776294824,294650277854196485752526848096008214721988745350555311479128101695333774927,9930361494944692931597991649915857642608730961125454734483697613693272941776,17972565769620820679641368732920396905240248490243886868922250461473059009007,11842743032528966560856860268344505094861546674985872961254820091273444880060,2260251491209762630871337015316066081541066308706934094017641769176593121838,21336986809148977544823484666876006147697590184356254785752148187171367963063,15637234083283356311249527335446193685599985235080555266374006156231977517227,7637477891046186378249227336975234440873859617986704147458186423096226771577,10435340982947407847927678888878882924793449778165415690957335683641419176012,21071574044063633264442120715854514033847137356154103023224485568597330648075,20085745552872944745120547909310789275453780111307008151203836541147270866122,2369255222739182549768488367357061329939116877812397072967912842660453854658,3320710154094663715463854219978294133429318041799642537800174050047893035878,2437552820481788519744888712380245016748276158860265401041560980354471184914,6687580113987208531705167517979176727449238324356562435678492283111952291541,13835828959457330678345759960614663723017667326485961761361157914420441377430,1823843951353887792473925888956554516299304358703549730900495356152013614424,18229384804985230011714562427207966412342158903455811854157839446374012856695,4983049472282717134994110428470567601005310848076496400503178535459679438524,2047051967230753763135778305592853785901616983565528680886843131244871631064,17059505494771925862841990046823342770591010831955480339095397897088168520686,5845823714127413134610517798305104245114036685335948729450609519089263487144,19810252752845594230307894817800427820113926573704856490871938876757561680148,20741340243371419379519807725035036726040739024854919427690724405113594586449,17305746835229988220561638584011917989169628535378748397361130724475478785704,16273970657972145440112726408308019138099820274904080726219726815138597785735,4927605725478881247988642936459897069651251926499343645614635597380235002430,4076655226193629464789557616268492785057128805549395585385432329518368497686,18134767316186963456589895259454813585756254459227058992203617493951135964914,20798436806114056077588608064161229365173163847083955162560624566238528904361,8811900287453512972593412116532745098600991077158875340182906101108258578231,1611466530857794066271650650204918615746591649578992581483080164777650137733,19520757346022691586967284723955378385034675472244175822936613026597514818901,8258287931139503595713718829279050060190693609290797346704848518381891359704,13807143439443425137076128013998009581746894329904809421858222329599144124143,2034200548964915935625429760202284220693125881760822084201315022529206424506,20594375914400911567795140472107624446159181622166676420027082349633992663301,17773828019575037451999782968066986504577459910353828196403976545023426528432,10645884969014005687699860915213473815514464399964009808411811895545112650817,3135829883501342672772973577699379927756997243617424917654928164800203666496,21807676600134151299257078976418813484444183016737321278512745883771478511369,14168063038909284721702678019083222059818438340503980617872573468231611140141,19022539506931505257153342575586362988716958060936788031721967221986624233067,919797128086310623571009200546035983274688764270933413427846490906074137487,10651353481391913627770814216074873532920753703051075188645774021198634943682,21601553598752750925049978818528421110707879819831249175157596816870100048288,9544964974935674319204796617933096476421551193682156030394816088243121582636,17113833205578964054057051521784698139661258340576694677296240312431808476286,9889647672195559279745677506312894570402108521106900082889976819798270827735,16028191999932520938901585234936954312994452706490572504997534210876573833649,19224701772787524647172128751148104366752057774529591812815327738829591289117,8065294760892477625290114823800398061529770004833832691347498933238361039736,8385011404987806129246014860479833290406969218526611328586242951296814426438,17626526623257098006524211054563886193098683828265081734658432468695686509315,9760584950604786147191288118087660976225563461953070125437519145090832114537,3282956645059793949082172795607530130101621492305193365378997603911833418463,3788543541342252822847978185963388795825378340921321139695221828685330606335,5728277403393912877393143174229934529937061751983246730506397742038949251701,20532577038632159357383817240596922896191478140446876998140515404169184846609,6138500779693128517529525961343097735306947649093633133232282430353593175172,16387038830089541476468870208162294639575042754761542956218362331966004300870,10184264376398708852688445921404363179240954227345322711923845040842165453208,12576299651793170522912156101640799825541149618303513174146382191633847258859,1340015400080181141720946234858756484323564628916867888877667239334982793481,733959369856163480135680991009606990817015555938726628110611986599242143578,11467033813562140192244869512537566463715027496952375979909160849747976831918,4619667645046391146577435774790188488541561222783010406420406869960248783331,58552761198135931030902257754896948615688045302818928845814661296914920622,1199849881730507352706524556330002080538296688430736582840314007371442152147,7124502590511184113044595527748024819132713282667933641439666531514739645089,8623660134669459112474551498616256867375253975034970808437732784494772311361,12655669439191191182341423414424342421477486764113555800095493091893820045534,18432703875775002490514477493898870315422995231506677048275960580528644904682,15467220287938881354678249472400749704814316816035426814619089032223454845193,2851120240492392321044027263769720216640877441121430445737594074121655318176,20519914249934881206828098454303256358482675671718589102535780334267934987941,17275124961392392047135728713829752470490098022504524438869454049765356211723,3323710067527231515807603961736782048796606296990840839366613937968342331886,4468708240622802562056471128793253296493002925988003094771284205007772045098,9006494818135081033869830730030943407240565201693254355620348420258773924028,2624130417875598753127999576825019766166727976335690685433712946223008520912,164131399455376615654870570697119442360078693174350746600132391198500093412,14931668887432843139264972187415200544679230597820424081936926034478502874299,1638753880783574431267395352024193675000113296497173968722590753809640941864,15505380865926802396097545843811910443367233632805651511272732002583232431557,17973744614207669251901495093091561913998272050499760575282030108740677066624,6137688223696761009295745609563284204827706564566466060484103844265403078408,14774243062532823236792831566222119634320864630838624098798648826842418775856,15864970393171078370207775103899428499600152663946379517190945807315353544891,19010063123357565300336230971672519561204810737546730911549311353159512986740,12607162829921425080830052984475623157169603642577010527391007035133383807243,17803108634879437217723652777640120469990779759700458421844361066182881628345,10065874953507223318296028499872542865030107611981933577973812883589535269142,3276471432535144390388324850641020151392959100393035635141206272558418581928,7532054601401798035926415744768772852833516520318445183340725930886329458991,18893822928119227829016544343228228897166113682019317256005502643243867377334,15940597493253236451533839310728876441657428995464658827726295547815292644378,4268009387843764409267791203070919313017052533005657826253994943184768120896,21611251949238422413354051947529388972078300717392131751061464498329326474580,12516447001729804412674006874184731098280474050775388553768469608793631490618,49838549447142926741568525697026885045023997277705726329780325103507790978,19763902910323896567698991616245963026306943100978479625077573937114135803058,12029297973430627253212633299020402005457460023136429653800185001711727387314,17676997725594777991384952086633589048516371093397126876621255518370680168503,10567543371894667303450346380722020266352683222046730266924342174164712049360,14583364850544999818712646438016435003942847076919084667364987497592599663937,17348091487238815837308569582101875357715798351834275089190053280855958465528,8743083090296259283603789316855921930102444739264013461469099560398359267240,15114064505647935792598848256320570567717917317803629185764147361301698519005,18332675991829764561879941291908436508530604635608341316693114747813051532006,1757567731797951053080580099911774643896363235228742197150882457231133285549,6526388717947413328592956348507481629843816325885832861915399601868279124246], - [19332164824128329382868318451458022991369413618825711961282217322674570624669,12346323761995603285640868741615937712088302657627126374070962894016296466118,3913895681115272361294397190916803190924061797587910478563401817340941991811,7048322889096718105055545382948709082135086733564574465991576956878202831861,10375086910057323893637057154182902576957472442368661576421122036461645295833,12765622911241487148932810040772504127756393086809438933166282251044289864727,266900212758702307861826326591090138389415348463003233900705815890364224151,14435131616556129905356866638030823183270286404767286105643513738132789033353,5780976801287540146775934937953368730928109502001687434229528186520268917700,1618320442446662026869390273942730786145909339107736579759397243640902802126,3818399583522206096165108192531271582827953520684743806492664825009577810261,11764506724346386316602508039052965575734225646587104133777798242528580374987,2414215974836165993714858157462355581258152126063378817495129367240311967136,17609437036230923129211608175600293197801044251801590649435913902851695334081,363438080029711424794236047863047716381155074181485245036621530063262917196,535766679023716739184211613469394818313893958493710642899297971974381051070,5305068908469731303772738758164870877638068032868328180355958394150421214337,10807632568240507366657354568432178961148417327580695024415275247652313539292,15964415873358391713354948903242729080763777490509563223190335273158191600135,20700362719972015883260687302741075186857660623182772413609788566925949033885,10135127975676256977820296631533839366076919827597067890970660746228807376456,4251490167543116819728642817282216847143714366441358372252125244838181656331,7745587495915033527847242564710473705100826890903278244320948416581724663023,11741113129223221800185946819924457344647035336264986754437921049066977440806,11630296782890656599545188109639399768829653360050213193782325240600583381364,16861140446185941149398487176581839232380972247302922484807333229513905651035,365879246117123675211400356410703684399715291171114630107795112994207447819,21725607857580053522363567649763546934441685061337033780528788383243719579033,9222866548596464928765000608129177609426964853736257576074550520759533736918,10261578281201197531384003420612639018011405529775212563256392340336951230146,15644037447921591571869862919382888810859308861783088910843592577202362807673,12752004188139535619565478547449108772137477456363099481095747591698702436636,4205805109630387448825516813913983509046636797101589615147198457314360427718,21047095155106717901091873146599497621258071512562421967648909471775919992713,15624165295872926124160584750951090817255240214488120310950503163805737026315,15064589937731741958666763896598138037875460434244947486199623542160035749721,1801577872277160959016940766173040841160105238799805406938450020949902989173,2896766420608048344829901127120623317655260981420052771341833288256800199953,12828791469509204618898135640019714232831708508424682785876476343251730674999,21363471986981372923191391880511344708743312828234098289107697080824665183315,21372706354350795416381912271616633829725494570576895047490974943034914894898,16006531510217730955981102005088687858079561573088629102219485906666961331083,2389357602244845938251345005183369360523566673990464798041306722747500447645,15275955107196234672088664710679934029171843237458844492987233368659104714648,8038797517535218686870517662905230585331773059774130312418943649247287196930,17923922393436914864421862212181654800719733137689602673604754147078808030201,12890519745320143484176500044628647247549456778462652469313611980363507314914,8058516556024397257577081553178859094042894928866720408652077334516681924252,768425396034382182896247252731538808045254601036758108993106260984310129743] + [ + 0x2197703fceb4cbf07c6dbf46c4ad93e7d14e554db66d09102ff84824743fe4e7, + 0x1322f0fffc7e4854bd8b5fc23e7106b51f59bd5061d8b565aca2fd3efe512f79, + 0x19e414f80380aa2d222133118c337d82a8c5894c2f88861ee46f448fa9d61359, + 0x22241199a4df9cb7d65249d9562cad6c65f16460e79a7939cbfdd6d7b9209d9a, + 0x301061735384dfcecf9a311c22ade327b51c78b211615f41c77f6d85e8a41b6, + 0x229e1d86c1f2810f4a2633b7b4b5bb61b7dc5d19ac95fd8d379548ff2b6850ee, + 0xe31dcf9c53209a817eeb292e989727c3f56bff65883afe5fdc28ac3dfbea675, + 0x68f917bb1b0805e5b5888b6a97824395baed195b5da0b71c42abd091c2ef54b, + 0x1d0bfb8bb90ac234002d837715613297802a5bbcb69aa2da8cfabd832f52d7b2, + 0xd67c182fbf41c18d5afcb48be20237413f02a64dbf09eaf71f23a14fb9e2103, + 0x3058909cb103557706304b9bb64d94aea4e504d8fda8b82313996f7962884886, + 0x4d06a80196e10e664adfefd075d0cca04961ee8a89f4fd6d601eeb9b60c8dbb, + 0xab062f8d4b5ed0ec21bdb42eb3fcb0a88fa13afcae4523d2386455228407b56, + 0x17380754792ad5f8195e327a5a63cd7570cd1994bd6a130e01c1fa1a173d4630, + 0x2d4f3780eef4ff99ac916f4b12dd575613cb9621bc5fa0980ed9a4ec8aade56c, + 0x2abbef481b368ca971e74dae04691439f845c10d1d57894269b275c196aaf9ee, + 0xf24324f82d68231dd9dd6f8c05f52d8eacb9ae01ccb1f3b30228222377d0e53, + 0x267617317f5146654295ef602b91250db010b45f4724ce7ec54884b29c404597, + 0x157f9e2f737498821bb01ab1001d715eb2c336dbdfcb867becf0a2bb6490c06, + 0xda7bec0cb98d337a52cdf0d66e8a97f24229671346848a552eac14c8a30c702, + 0x15fc820ef53302dca709f3ee480ba1371c91ade79f9f587fc7878d731c0596d1, + 0x845715adfca35c3e8057c0fcd4ce6a6128d0e8117d88f551d3ec6587d0f4296, + 0x422f744e2b736096bc8775a3906893a64cda874aa4457d2b442a9a771956d0f, + 0x15f421550bf6639d46ab5779fd26b1e11618e0497e05cc85c608b00faf3382a1, + 0x4f17cad2ba0ef6f8602e93f5b988d5f357e61ae5f3ec35066fcb4d1a7b720c8, + 0x1732ef5660d84ae50ca09c021eb0d77f1fb2a00cc7905b2479588c49c488673f, + 0x29b12501fa79e08bc25259985f730cdce9e2434192ec826e0f4b9d568bd351b2, + 0x207c8006aa78fc40a84db40ad82142d0f61b28dedf10e2201d815cf4f6274590, + 0xa25704ce4cb74a94d7bdcbdb5fa268abd589d88fe45b2f2c82f90326cd049a8, + 0x11211f3a71af30a00101c423ea40a9585a9eec75687725d7ee289f428f40efb2, + 0xe01e8bbf5ee611471380ce8bb8c34b932ac76e96faabcb7ad20be96187c2fa7, + 0x1c894a1430513df35523e22e4fe9f410a43de91dac73ae338c772fef1fb74363, + 0x2bee349392dfa0b5b4a08ee58ef54f002e06ab26834f94843d48ff0ced526d5c, + 0x84a60c1d70887d9f2d23a8c7713332829eb41cf3181149fb223b7abff4d7f0, + 0x23a4506c90c07f3ae176a0e2bf67f57f88d45898c97bcdebc8a8263ab602c7c5, + 0x1ab66896a1df95c0208b990e2c634707394a1110cb314bb82e0a2e2b4958aee7, + 0x2c6b842aabeb84ede49e559d8eea658293ff4bba9325b5a1d4cb649d317f4616, + 0x16321af63871328c2b88f46df432be9aa14b008b93f85cd971dd986dc16d2e35, + 0x13d647208d3dbcc9df10d1ee35b598e6c8ed85608f81ba6953088e7bc6db73ec, + 0x1c6aeda9e0fa69f5143e6f22e747b7e74e692b9254d55c61b890470cbd7f06b, + 0x287d74a5fa03a4ed65bd4a7c6daf033418f474c7dd9b957bf2b17965cac024b1, + 0x27a4327beb0b3e0cc219805b3f05e854bedcda1b7c93f11691ffd6bb76a5d0e9, + 0x271a03a000bf412e7fcfe8918baa689c6682417803f5b302f1ae30695c8e6770, + 0x1a4436200e4d0be65d2f0f4000157c957fee515e591c8b54bcd46c02d599235f, + 0x1bce9394a5dad0a4cee35b8e99b4b3c0cee058b8ae4fde301c3145a5a7a94c76, + 0x2b1b4ff2bc186b7dda9c3e05dd4932f38e6a7c04b0af0839441a5972125dc902, + 0x13c87d0e4bfa493cc2a197b1c9db49426979adfee4714048d865d4f6e95f699b, + 0xe861496d1b54e3530aa0dc64c6683ec0d01a4e3d1c69d50f4d6720b981ccd62, + 0xdb63bd46e06bcaffbcb03e5dd3faa88f26a0aaa728198c5d09a483fc4197100, + 0x2f8fca3a44bf9ea99452e1a055886af7c95850b716222ad89f0219054d45db87, + 0x5b7bb3e5a4e2946395d1d6ddd541bd9c166cfa1956d161713e7e350f5947d73, + 0x20e4e6c47a68be3175fcf5a7a3f8bf7b3b2198203b4552ed620b9593b66e5483, + 0x154a2a02379c7695ba4783e15d10a147560ee2b4d03a04a0b901dade72df4862, + 0x156f02cab5fb0e7e6fa0c743bfd64716e15e5e50e12774805b1c74dea89c5345, + 0x1d258218556d0152f0a3be042b1bd146774a616ffc7e7313e9519b5041318912, + 0x160a5da355d469412e5535804f99dfb8fa839d7ce2cb7afa50c1fd036219f4e8, + 0x1693c0c96b95f7037faf6a18289814c68237870edc94a72c883eb2c751d5ec43, + 0x2b0df0f463f69ca206ad5c4a115d1a6a83d5e0ac328bd468f35826a968d5708b, + 0x19cad23c14a9bed0e159f250bec8655c07149bba04161fe002f76954ca192b60, + 0x25857eae6be307b653c36a4090a3963d60842410e04c5722dfede28fa645f54e, + 0x29ac9714955b7a9c94e7959efbeba17c04839ad7bbabdc643b9840ae43155f72, + 0x2e637dbad876dd52a7284db266593aa85b2020bf340802625e74f45a2cdf962d, + 0x468d89779fadedbdb4f0093858113c5060321aaaf082a53d44fc74c65e7ee84, + 0x914cefd51a2822efcf8629d57eb5b6ec7195a90087762ec8814f14bde647522, + 0x120a9d3cbca58b917f4e61117c7fe2190ba6d238ce374949778c40a6d176707d, + 0x1cf1c75a1b2ca09ac655215cb308b39ecef96d746ecbc34b37583bd8e0480d5e, + 0x511cadc2d431769a953d0d2355cdd3d8c13dca7a6c5b19005bcbf3c5bcf7770, + 0x1e2aac063f4303e24a2a44b1bed5688a43279356dc78a772e4dcfad0562e5dd1, + 0x172a396d41cfb2b1241e096aa41f3a4788303d8824d5496871e03cb9590f89ba, + 0xbde068237cc41aadb7ac718d4c6b916cb7f35fb399ebb2515307e6004969e2e, + 0x1522d1f8f0cb9214b3f6602d9f867bd2ae07a8fa77aefbc3153af4d350d933ee, + 0x157d56053aca2c4cd30f7ba34e5d41b8a636961ef78c1dea1759dceaccd1ed69, + 0x10aff8c0fa2f25f58a299e22c732f1b901616f6e4bc6f63af79bb93d45fc188e, + 0xa9557d37fbb35ce046f2df3d8bd9cfccedf85eef2549843da7f2c2e36d2bde4, + 0x75029d8351a4949170136de66c179a8d6ee6b56b89598af199528d78e8d2c59, + 0x2aa767c911398696b2302fe15ad33ef35c6c97618e672f837aa4fd42930355cf, + 0x14d99c7417a329ff62d32828421e1b8a031d30242b285c86a4f63795e376623, + 0x186e1b78089467478310c35eca9d2058c0a8bb8e2ea5c324f1314e478a12894e, + 0x2ca9306ef62dfb1ad58244ac5bd70b0bc84f86368f6c9bd4e15ddaed432e9838, + 0x17630d6307628585661eaaee9438c67160f7eaf6d03d3ca6364d4adda49bdf27, + 0x21187c1dffae74340a488cdf08ce322226544816780af016098d8c39c7e72e31, + 0x1db210b93c320a18bab1769aee63276bd99ac89035b0da327cd06cb70854aca, + 0x18bb6f89805c1bd59d8d7ad109d5f26b4d18813f71cf3aaba26ee896709404e1, + 0x9c0a6c2d79cc06023f3f43196c9b8a60a55716d2c7ca095d849a5d67ff6fe98, + 0xbe6b7d6cfed9528f4d1ae306f3138306ea7c81cbf903e9b884eab5084dc4c16, + 0x16fc7c808552b1362d8a739bfdf6c6dbe70b00611780fb4818d424d5e017ed5c, + 0xf31a91e6db75df904be6bb14fe7271429e5787f9a918d1cb128ad76ac948836, + 0x230a66ce24feddd45fcfcb5ca7e4efb12461a7c0a0b673a73b252925d310d488, + 0x5ed3707e7ad3478ae508126cba274743cfe8685b46153f6da3a0b4b83ea92d0, + 0x465c370db40b8f14b4f6ef913550c11bcb2839ac707e2fe9a9c31b43cf8d938, + 0x85f42b894873a7451a60fec0539f9ff8b2e0a495e43db7b95c3a75c57c20ed, + 0x2e8b3ae9368c9c1f1542ae734cd995869f81aac64902fb1d3597022da08f9938, + 0x161485d4fa8620e6fd09b088159c4e223155019bfe9eae28f9870ff19ccff314, + 0xb6e400339e5e76c1d200fd27884599d473dd98fade9e648940833ea32b75416, + 0x261ee31fad47c0db7bc046f718437ee518fe73ec92c1e203155d8f284d44b310, + 0x4e106089b776d01a284b84adcddba4bf0ee56c2c85ac584b4d938f45023252e, + 0x4b14e89f42287dee36142a17718f7615789c9f9623b534afeffcf9c7e26449f, + 0x1d55915b20b60534f1d89f2f8c49568123fcb4c6d9197373e54662e7d9eb83b0, + 0xbf04f5b7d178a77ee32fe543be468e1c89aa457a2f4d6699aea743f80494b8, + 0x1bb1f31e887647cb45b8bc5be185e206e91accf86e5ce5bc1b39af12f857ea3e, + 0x26f0b4214212ea8030aba75b2eb699e84adf24bc4b856a3522b82c1edca87e9d, + 0x1ad7e1c6feade269c076b67239b316e7cfc194b036b5a53f9207f457599c5fca, + 0x11947cedad859f02ffb4b99e8108512fa325224ad7e1bcf82b28c61a89840035, + 0x1ef4f0330d6144228ef6cc36eda0d179384c4dc1858c95de12d070d11c43348c, + 0x1031abebb0216be506c04a6514d471f18b0dc1b5a9b616c87a465b689cd1336d, + 0x23f97eb680f5a13b3e8daae572abe2ac0dd92eaab473002f0708e6b6084b2df8, + 0x289b2ba2e3c8f665b94a4d73b5bdf7d6687468aaa84ef7f6e04fe123659e41b2, + 0xd40f713b31b2d041d3e01e2504af10020bfc45bd5bbde4f4b133f63536090b5, + 0x29204d73ce84b3fbbe047c74997ee799f92923cd16ece1eb6275c8b71659f149, + 0x23cd14b50f4129fa56263fefbe7475e51c85f67cdf38a9ae7637ad04ad644c6a, + 0x1603887bc7e6956ae4ff5b9f4423b2293ab52b69b2ec021acb90bb6da8dc3883, + 0x2137d99c24145e52ead0129bb220690c5ff8f6dbff755c8467054b645c74b0f9, + 0x1f3d6d1349096a8e0594443a487386f9f51b2fc366e910a9952d4f0b3dbec414, + 0x2148e1aab3e9c82a297d04af8191e2b05cec71b0cd6b8b4e079061dd00f01a00, + 0x17fb0721b3375406028ab6f04882a202e6801cbbbb50badcbd5d760d59e60c54, + 0x44f8ade334554cd610743aababa1196e00106e754cff8b088ac69a273ed074d, + 0x2e10e74d30679661fc3ac960b7c967cbc50029d2ea463ab8ef55633cc5405243, + 0x1e44030832526ce32d540c5cdd2def7f900509bc8019fec5e38848b3576dba8e, + 0x2c17bd7af463d52d3fd7e8723d11078369561ca3c4ece48f1298adabe7c822e0 + ], + [ + [ + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x1fe9feb5c7f7c7a426bff032cd6a3158278b6c6b2cc57a871213fcafd6427989, + 0xcdb2db9e4f9d732d217c5e3114821165d49e5a2d41556bcd53d0c4d433224c, + 0x9664216ca565c1a44fc2b98347ea8b36904b3877f2159dcc999895adeb4d70b, + 0x1463f51d4a4cb1eba16dbc115566aa48fe77b43c244c9988a3c658d2f56493d6, + 0x214e41788bd2b990347c7f2a8f47612d4dfceb1a1e6da38165873df66ce51f59, + 0x548541724f64e20128260899abe8fbcdff184a1957a9385fb715923bf0fc79d + ], + [ + 0x1b4bc5885d1cfc8eb691875300db5a0c7362ae381898acaf8b63cad04ecb36c6, + 0xcc7eabb154aa7955eac47a19f6437a2b8dec0fe9e5686150ff6e88b1a7b4bc4, + 0x12f3bb29c972793182123f5c49306e16a3a787c4bcd9c798a131b70856d1cbe, + 0x111fd8dfce2bd3b7ba0cfa93e20fb685abf76d77305857b8df30914e4849ecef, + 0x16afd8f4c39038b8006a59d292aea84731c0f83832a61b82250ed90118e8fec2, + 0x3fba82d3f783620873da94e9f4e84c8b529d76f54e4b5d7d4805272af9b9775, + 0x21c5e25a6991364e59a205e5b01c811deeb095680a72928369cfd2de71b14f98 + ], + [ + 0x8a72fbb55dde3e93c5818571a424a54953695029eedbcf91eaeb012751c7f83, + 0x393efd96399aa0726ef9af79be8b6c715e429906ca0d15076b5a990fea75ace, + 0xbba9006404c5ede82b527677daf444ed43fd1e0dbdc5528dd2cd1f17ad73481, + 0x19f53c0a592b3ea93497a511e56f66753598265b1ab6774da48eec04e4d93426, + 0x2296361f3bf154efbab996921936e9b1dff8352711f958638172055333e07579, + 0x66782fe3e869de2cebd7ebbf60fb435785329dfb12ad9bd1b4e46ed36289511, + 0x11c5cc53f6338c825817aff7792a2efbce8fff171300d41455a2edac37663d02 + ], + [ + 0xf95359a1f6845d4921892f83e500bbb1b3d3763d8fc762400af039b0abb83f5, + 0x871233835b752ea030cf8a4f43771296eeb33f697d1b0825db47d39ac9e5955, + 0x17e4e73bf701f88d219acf1ca6390cc1e17c9f84b1713820837ca070be84a2dc, + 0x19b683c39d3b002fc3523b7bee5a60148b1dbdf18dd1c318e6a541e8cf66a174, + 0x1c3160ebaeb10f809f69843cf8d5bbaca198d1f8e3439be29beb92d909ec891c, + 0x1c5cd6b23ef336be01efa37a27e6b7aae5d1643fceeb212cdff51588835fb537, + 0x27a0949fdc9f10495c4ee7214aa0edd2ad8eef68f577da8b96f9d87a39504bf9 + ], + [ + 0x16f01751ce985328afde34d81619defb43e6c7b5dadf52d0f82472fbce7770d9, + 0x1a02798f047a51baaea34fcfb26ca6afe96a5fad1d2db4270497b6e6504891cb, + 0x234b8a077ef52b53a343b8da5b20cc358ad60760dd60276d485015f73d53d207, + 0x2547113a818779f13e3448719c7ef100b8036bb3e882dd5e6456c35311c1bd5b, + 0x94c66bdcff54382cd9213abe43312edb5b4d414c6e09acca24912a7635404c6, + 0x2f3b4bf0f105f88e27248af094e29feed9ff3fad9a794e15830bd2b311539453, + 0x1c7fc68f3fbde4a23c455ef0d0dbce0ce556a0194e6d552c0455cbb5b0c230e2 + ], + [ + 0x1c391626328457fcafa629f3e6d33e2555e8d885e3c07cecc8af1f4d56596417, + 0x55665d76df3cd0fcb713c234ea79d06a31d6e3e4c3bcc657dba4c664d5a0da0, + 0x2dc3fd77394b7b5ac1cbd1b46e6ded5b835d7217a4c50a487ae9a35a7fd45d9d, + 0xcf148f8045cdbe7bb1013f72ebd4126a3e35cba9a970441ba8d5bc76943b0b, + 0x2e883bd408c4c826d004ff777d7c0938434ab5bb84f3420e5d94b853b1746f89, + 0x2f4085eaa9f80a69b739fc23f2fe4057f64729b311783fcfab3a0a36fc1ff432, + 0x11d0f56fc00e7d85b3a2939fd33991dc8abc1ced0c3f3c530cbfb4500d63de9c + ], + [ + 0x970f671b9ba35e3e3c642d1e0b8032023ed5bac91c2c1056f03965a42c5297, + 0x26ee9691a638edc7c91887e302fc55e8e7758286a44845ad88fd7de3bb1052c1, + 0x1668477640fab14c72b1c16ff0192e48cf882f12276bd12f97f82c6ee2e61e48, + 0x3008421eed767a093322a09c3733973a038168cb28cd2e1f709076c00b869599, + 0x228af6d425e91a783dd18fd89a6b38bda053f2f23c094b875f27cb3abba2030b, + 0x2363603349e94f520fa1f98fe2507f6aae361934078aa59a16214c088185638b, + 0x1b2e9d20d9b55deb048cabe1636f0e96363bec886679cbd91f332fb2bade44f + ] + ], + [ +[ +0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, +0x90df29b70c5a783521503f92a45753c8bca03a74627a24c44dbca6eca32ac42, +0x11a48e9fa064121f52297162fd169e051d154a0e203583624a16c73534430b9b, +0x1636fd9a0457ce75aede0821e036773e39c37adf6fedcc7b2cdd72254e2ec7cc, +0x2e64b2e0bd6fb47559f585b63e8dd15b430058a63f2076636052efccdea98ec6, +0x2cb7863886cc4ee1640210d29a4a329d93a040ed45f2744c25731c8fcd15f0f8, +0xf3212046ef984438989c355db0984f93ea4bf99de1700ee0185886e81f2ef43 +], +[ +0x1b4bc5885d1cfc8eb691875300db5a0c7362ae381898acaf8b63cad04ecb36c6, +0x2c628e21a22008733e14f81e953a50072ac800560554df9e97971a56c509222b, +0x1cb1d2eca719de8ea352adccabcdd100c4fddbd380871e2190e33390b8bab1ef, +0x6a0175e0d8aa3e1b994a177af69a40bdf6dfae09c41d2fb3d8c599c76e7f07a, +0x5fc6589a1d1d35b2473c61ac293c6d6cbe24fab12a9086c0aee1f8d1a28a883, +0x26342b8b16928328123d727014822f00f4fbde2cd45046f5dbb6b986edfeb632, +0xd7565999ffac123203ee5a0699bd4a2f4c491fcfe05676f928694717e572878 +], +[ +0x8a72fbb55dde3e93c5818571a424a54953695029eedbcf91eaeb012751c7f83, +0x1567d8f8711949c036030ef808665350cfe9b648f13c675379aedd83d9b83767, +0xc9037b1b5cb3451595b4f8a1ca80c3d72ceb93d6d58dfe8eba02e88d211b281, +0x183d06dae1a0ce53171aa09f25f25ee397263dbad5306dd1b7428872baabd5f, +0x7da96bbf5fc4458741de810178e19a89631a95f2e0cd7e5f2783cd237f3d911, +0x1efe4b3bfbb320e15ac79fa9abd46e4a19b21f39bc40143351321f658f6cfe7c, +0x900505bde5ee2d55f5baa932e38805bd914afbcf3fc854219cf41d147b89db9 +], +[ +0xf95359a1f6845d4921892f83e500bbb1b3d3763d8fc762400af039b0abb83f5, +0x27630d326f12eed19ada60a1f6c496680425b457f42e8999f49676af0b637a6c, +0x26920194603a11727525c5e7b267ab6580abe2a7912789eea077a55f7ec3204, +0x10e5dd7a0862c4aba24ece684e502d3d6132a99d906908b20eba4f3466812e42, +0x2d30f6e371ba6fa64853fca459d0d6e0edf941c3e8177ad5d333d4eaecd7dc7c, +0x7ed952f7c3370e03880bfca6348ab2ad35bbdf9b7e9c266e7885b580edd59fd, +0x25b7a438b7dac4f0b36183f18766ce503f69d6c1d9cd29b986d7d2b8b44be433 +], +[ +0x16f01751ce985328afde34d81619defb43e6c7b5dadf52d0f82472fbce7770d9, +0x37e3c16dbd340ff80f49ee4f7dbe1098b474176a92b7a6964a63f2fbb8acfa, +0x2cf7810985ed56d898150ddcbd42edcfab6442f0d0a7f637693f676300c85c5, +0x2595dfbda733d0477a01cb6693b93eb4cb711bef3784b5fc9e17f1b342eb15d4, +0x7d9eb804f0a999ec586c58164da8467a481c1975e27b951f6f18411a7440cd8, +0x56b8df70be9577f94b6fc2a3a94f736d9c7b9de29134ff3a524e406e3143280, +0x258a0dbb961fc61bffd39764fe6d3c687a1061b59ad00fe85d1c18594b7e7270 +], +[ +0x1c391626328457fcafa629f3e6d33e2555e8d885e3c07cecc8af1f4d56596417, +0x1814234ad66f16a36711c9d2779c1358ef58f650cab5cfd95a0678af36224c98, +0x25965b4db95bc7104bffcc6ed99af5cf5328012a3a1a35cdcbcae4ed2470175a, +0x3090eb08e04a2d235c164b71a56dd730c6b95e5a2613d39cfd932b90af23ad0, +0xaca5e46d797e1748aa438d2e2967569992dfcd41997be143c3ebd2a823b7660, +0x18e6cc7c6ba50e61933de0f615fd4458d39a6c34c2f241a4cb78dab9dd1b4283, +0x216fe55a6f2e8daa2523b65eda5367ad3a3a6c55856c5447f398a280e57d6535 +], +[ +0x970f671b9ba35e3e3c642d1e0b8032023ed5bac91c2c1056f03965a42c5297, +0x1bfb7975cfa9022d9bea2acafbd020c85cd3f1091794d28413510f2d723ffdb3, +0x20c27ab9c365c5d2de660b9b31d4a406907c506b5488787bbe2de181b76e6a7c, +0x28feb3ed6c194200a579ff340040be172171c1f7980e63214a0b3f7603d68a02, +0x100d8a1a7ff31b30725190584c830b15c0cc5a41d9d530ed57c0bab464368b5d, +0x791d241f4743deb4afd41d9989448220d5a1d101bd96db5ab2968b981aad486, +0x1749c39995115eef14e1bcb1ccd4cdfc5c928ff14e078b38f5af326ed6b1e099 +] +], + [ + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x277ac8a3178a356b9072bb7b469ccd57a0a63dbf08fd0dd7356008d5307bb3e6, + 0x24903bdf5d3968a8e49c6bfafc0e28d539ec1e2756e69301a8e38dab87c6c402, + 0x14e025a7131c3bc8bd2d48508aa4f791c8ebd10688d7e5566a41fa0c149b8602, + 0x2e41c7e320ecfc1d86df765fd7bf43ed2b6bf27ab8b7c74174ed61d57905c555, + 0x11bb3cde82e89bb0041907d66de91029b35a9c8c90ea44de1661ea2ace917451, + 0xa7460b280828af7d0a5bf4065b2b9640a9cf83d19899cca0171ff6abcb49751, + 0x234be66b59a16a323cb35d6516c5a92f4997b76e14e656a8c41f29fc94925b0e, + 0x27c512cd854e483667792d785ed1ed7e30569dbe12fc3fcb0c804110c937adff, + 0x1532821b842df3a4e64577b7c8917219c86fa82e68857a1a5be4056e8763a864, + 0x1ec15f1ce8c3cd648f325d92ace903521d7b0f668a01c6d2b92b43e35b5ac58b, + 0x234748a5e415d7b5cd0b75b712675e72e95b1e02ce6f48d299d5a3a489905ea5, + 0x14037feed35ba091ce3dbb4e6033098d07a3cc512e981a493c0788e3827a6694, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0xa7c49a32b5a05a6d74faaded50d303c066ec843a10ec59dc90cbd37ba4b1b6b, + 0x7fe2a4ab68b94f006bc1ed36af445905c8d234d308d57011dc1d393e6bcce8a, + 0x15b26f61d51ae17017b1b9d1c9034a51083f25b33f474c96bca5bf47e8a658f0, + 0x1a9c3ed5b8f524e8e2de1678002e73c63ebeb3606fffc29ae527fb94c60f5f78, + 0x153aafcf4923742708efe169c490514516a223537245aca3ea205df20b8b5ccf, + 0x239cbec4c84afc21975a40e29610d83c1d71a378cc58995e505def01cc6bc872, + 0x1edb2bf1ce76a49c4844b7e5692018b524b30c1660a2e003b5768787d7af6d32, + 0x222778dc5bf834f9320f037f4847ce62a2ae63be8cb846a5e10a3c2eb2ff22ee, + 0x17c2ef46844a5365828904ac73e5114f9bc2833cf35f65adde116491bc86e0c0, + 0x2fff9c9428727c51c6bd6c657e31314706237633e5cb78ae244d5d4c3ace4839, + 0x1d188182ea443a5a5cea9823f3eee70a2c1e18459e4305ef862666d16236b0b8, + 0x194dfe2339f7aa042818a43f4c6d3b5b2fadf648ba0dc219e56ec7f849ec7e5d, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x1c7aa6d64a120d657fbeb04c84017166427d0f02f0406c0674899118aeb3a1c8, + 0x1dc18887cff4545b07d122b9086f80b9c464ee5aaf98ebbee8a648df3b74551d, + 0x27c28329d9f8519a1ad9973cbc710635e5cd01ff884e1c113cca7b35742578d9, + 0x289ce154bb02ab338ede3bdf7b2efe8de1fe22259477475987386544f3eb5cb8, + 0x2257e368b26697c9ae1bed7b5cae11efb9d48138dae5b7b3c499a37cde286d03, + 0x1bc9d5e7820a13f9f045f7b544abb2e4b954a8d9b6d38f198efe3275d9d7edd9, + 0x18d112c5305a06c15faf556d58b84ddc492912505da27bc8500fbd32e4df9c39, + 0x2c63e80087f924919d20067f050b7d7edbdaae2f3018fef6f8cdace9768faa75, + 0x877b395faf50d5d108121e29b7ca64c6408dbc08f173278ebf6de8b9685e113, + 0x40cdf2e7828e66a99121262b33701cc96696849e5532f492486d69b2779e9e4, + 0x16e80a1f3fe9b828493e83d1a31428b1c586b3dd54d735eedd257930a2f539b, + 0x994a923eee5e6fd6a4caa317c6926ff4beb82c3dfe033f37433d31898a60f20, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x2060946803f18c085b6fde5a3d8750d80f9b21ed391e27e1c7bed180d708e87e, + 0x24fa5c0683c2eb83b0864853cded9d57d38f33fae496818450e2f6c49968dcd7, + 0x162824e200bf52b73914219f02ddc59785407c558eb4dd72ff9b11921a351eb, + 0x1edb37284aaca008c1703ddea2da4eb79521cc4cdcb7692ae344be2b880f574f, + 0x2189adace1c5a701dfa9c5354cefcd8204c60095f5b8568232dd01acb3c09688, + 0x19f1b2d64e3cddcf28e7187f16f3a90c93975e2569625ac689e3878b2de7c778, + 0xc62cf98668e5178bb9b6b261f36e1c8f176f190d372921c9b46f824db8c6190, + 0x16ef695c32d05c8c43431f284a33a0138455d93408ca2f742944d71eee85aba6, + 0x1916a7ff07956db69d712449d024d8272e2d9fbe9428d6562c503b99337b1c14, + 0x155303d79a49e28947744f334366acd9454fca21261d32bddc76ce6086e8f1aa, + 0x21dd4756d2217bdbb9b439bc12e5daf5a8661b1effd889c642cb49c4839cd533, + 0x197232e52cfe9adf15394e38dc30548d7cf495c7499bcdd993c2df59993d72a5, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x2f1786e4f7d8187788ae6fc25c6818d2e7fb34a8896414ac9f6b958de481eb0d, + 0x7b914cb16d817387d79ee23fe9975ec91fed24d0e163dbcb5418d96b504c2ff, + 0x1958452705af91d4b3be5bbaba856067cae00977353897c5ac0d070f90e34ba8, + 0x20f47ed0ffd3fa2dd8dbfd9d0daa514b0d72d270d1327e33840cf178b27637e5, + 0x2bdcc2280fe50acaa851536e7432f37c888a6507168a4b79e2578d7372f5db82, + 0x100ca23f8d8ebcf656d1fa5cb225932b62772fe53e2c5650109e71231c3a9b0b, + 0x1d359baef3547113637ed1d8e44c89166eb4154d190d38a2c6d47afe5cc12e1, + 0xa78ae4732461eba1b90fc18b100cad3712d8b684324dd57343cc127b005a3bb, + 0x1a843ce91e265e4b6cf8ac90c3454584d4d481813247df111241cb4409b26b2d, + 0x140c4ee1c78bf8555602a74eccc3c3f71e050a5deab03ccde1d8431c151bc3b, + 0x7696859ae6cbcd413e8a035a9191cda79f3d04e6c3d18658434d0555824e4fc, + 0x2e7f9004dc09157cebb4e42884622e0307f85fe2c37fa7ad2674b0981b2c0d32, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x17607febb988532e6c79c307d903056a2266735b7423da83843f70723f09a5bf, + 0x2c02579472877870c8c3457b6d3b284eed6cac0d43e93c38af218961a9ec3ee5, + 0x2b24eeb2617860189e832b5a50bd17938b2788858e58d9ea9bbcb7ea175ea012, + 0x18c375a125854f8fbf30b0a138ccb4c771dbcff64c77d1c62b79d70a13e307f7, + 0x7251d3e863183333fdbe9dba4f3abb21777555ec7f996db96352311cd9fc784, + 0x2adb341301b3948dc700e495384dcc124d5371ec6163615ee7263009fbfef1da, + 0x1472cc421bd8fa9a7efb991ea065ec1c822b44fe601640f46995c3f10f1323c3, + 0x2c3a91912dc2c2a792df5e43134bc6d7e582f822994a5c2a6352e789997f9258, + 0x15e8c106e6ea3898a09e7660ec87c5fb217270ee9a8ebb1d052e64f3dfb155d, + 0x196b68215343e220781a52bb0a324e4ca765394d2f3201a769bebbd931dbd2ed, + 0x2ea4a2d5188e98ec570e50b70d0303ede5207bee762ee8932a466bdf891a333f, + 0xfbf65aa42b0d900ec78b68de4b2041140fc85fa3458303276d99826e97a2783, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x2d93d238704becd76c0220fc95afa0783f9695075c5d98b363f91cd249c47a22, + 0x1011608ec77a11a0ce8b8b1b36ce08de4f93af8682fa026b87d8a2795b71391b, + 0x108c04095f95a9fcbbd038c079842940d8105c509c729129f7cea1c5e968e194, + 0x27bab26eeabbce153dd52489db2fade373a936ac52383034ab82a9e252381e73, + 0xd2611e73e27ed17349dd52e13a90adec9830a5e2c7115d8823d23688ba4e570, + 0x1cb4e6780cd70a0bcb4662edfe8bb829e146a62c4461c271ff1a0d8db5c1974d, + 0x1d429b1257e514fae54614b4648d627169928dd3a496a3d021d8dd7b2a1cbfb6, + 0x919d557a82cd7294d666137090c7348da53c3b92bfa3346bf14903a12e5ffc0, + 0x1b99c14cb08972b58f1e7216933e31e2e67caf29f8e6e998fe2b1c30ecbc9473, + 0xf0435abfab0c4e0ffb1a687de5cc0ce3fed74cf9bb2b559b569a552e8ec86d9, + 0x99366a2b727e153c4e338c7cff84efbedfaf7dbf4c7904854574f75f3d8e848, + 0x187b41d7da085759b71c2028e359907408319e8c6ad842c79bb202ecb419be5f, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0xf8adabe145a57461fe9a583655046a75a03785a0a2942221ae2000664936e3b, + 0x21b8878c75b423cb1f80e0b574b3f62d28785663aa6b4e0caa3043a693bef6c2, + 0x1dec99dbe933ff6d1c4b6285f8c68771b3ee297afbb5c934aa2874765f64d602, + 0x2d23ed96c51ebc9c51489f7c87de4fa151cd8378cbbc701542f54bd4f4d808, + 0xabfef9fb01611d86e6ae1c1ce2d3febf41378ba90a38f11166b097187272e88, + 0x28f60239d945991b837eaeb4693d496be520241c8b739d3f21c7b838ee0f946d, + 0x18ad1fe91d4530ef15ee77e9ff06e2d3b05564aa44613bef3b191f6b12e1bd83, + 0x53844fdd99071115909fc518f92c7d0d7ee91beb16180cf9bd158d33c8679cc, + 0x28f997134ae9a3be6b79f6f3257aff2498774d1bb18f553b229f70076c979ddf, + 0x5dd57491f096cf44399e477bd78c20fd872d357f5d1d210873d01d3a014bfbf, + 0x1f1a859e7cd1cc205ba1a1b3cc2bf04e0b24d32a62dbed89e59e2113d54e0b37, + 0x75f98af212f11e1de886197216bd78258bb77287937f0af8e464f916d7ce5f2, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x128d5ad7a08858a2ed8c161997ed55c8ca8ff495cd27ea475983d1715cc602d3, + 0x75c499dc0dfb0ce2005e7d13c1861e5f375e03bcf06951de3239d4b56f7868e, + 0x2917faec22c04d8b879d4490a8ae7a9d9cf7f3fcdd33634aabe189b50710f87d, + 0x1a86eef4ec1b75a75d97e62178663f995cf6fdf3913595632105284bce7cc346, + 0x65be02d94e4417edcba4b6b68675b107a25462092e90e7ea887af7870c0ffc0, + 0x2a1d799daf1e300abeb7f5a66264360c7984ef52c9b153f15411f9c62ac84d87, + 0x17c036c19ef8085449f760a6365e814823f270ba4a5e41d2ce4ae1c653f087dd, + 0x2151cb617d9f323ca37ce71d5c77ae83c8490057b9cbe8c17f150945893382bc, + 0x24624a8c4bf96cf50401f7361f74ce162c47ac803ed9424b7bbe4d7465d9f20d, + 0x2c01122a63dbde586507877763b572ccfdb59f2055ff15ef205fa8487f82a3a1, + 0x17a88764e660e91940993b5efc7d317ca4d0e28d7dc164f6ab6e8c0fd2bd111b, + 0x2287b5e929e98ac38199873b142845c015bb20880cd9a1d9316a7027a9b2d208, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x25527f081eab2b3258ed36e0a72ebbfbcd874e81c49836faa218b94c0a330b87, + 0x186169de0e37c01f31821e0909bc4c7bec2129acf9a34948cf7a8ca58c9b57f9, + 0x6d5d287a7a8d09650979fd72764614e0384a22972d86d191d1255c999d3daa5, + 0x2c1f7628e8aaaee261c58c8966f5cc90e7aeb1dda64d590228e61de098e4ecf8, + 0x1c3761c8c7a1ee1f98871ebfaf81b0b89a5bd53a69966681681bb1352f1d4fa1, + 0x14d1774293d8bb21421fba59295456c98e3e9afd0c9858d6aef305318707e365, + 0x1df2d2c614e4fe2a6cae058be1dc9e56ce12171c7c3bc4b9d1e76b1916458f72, + 0xf27fd9322adc74859d8b58e4bc2595b276061b606acce303f2a90ae404beb2b, + 0xa2aeb992439b6e372a606b46e95bd4b52c2072e6fb28c0689e84b5f444f7a99, + 0x23e0b17792144b002252bc0490e7640a3d47784e77db53af09de2f3dd650e9b7, + 0x2aec9631493082d844e77232cd2202224fc38b2eb0d87e7e5e62c11c5af5d006, + 0x131847cf279637a5a337815fa4f40d51251f6e0174e59c5ff4ac4cb35e2f21fa, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x1c8f5a7ebf52e4504d205b2b92ef4a87c99bf55fed83fe42edf01645332dcec8, + 0x1eed962a391acaa8a59d90d324a9ad8447d898f4b516db4a289a4bc0c565fdcb, + 0x2b7c65f02b600d4cb64a49b484840ebb11ed7e99a43db9113ed92bc07d2ac4e7, + 0x2b21e821c34c25f6fe3b027b3f9877d0966ee34e7224c738f0e1f454ae3e6d51, + 0x2331843ec8156532e5fc129b95d129546fe5ff9928bce0b17964a9fa4d8d16ab, + 0x22dfdad5cbedc015829fa14df6356c60037761a018d0cf78e13d3805464273ac, + 0x292c701ad0a3bf427a33e1bfcd073edd2cb8b5e6e949906e6efa9356b471cd62, + 0x253d7f1f0d16d4a21b0d14d04b927f0ad96d348e78a7e36107a9c2481f51c587, + 0x12f89c0d808f729c196c25f570d2027925fa37a17f07d9cd86b366793b5b89ca, + 0x28739fec5ce7338db7feb9b2996877e00c4c5d6f1587f24d5d165672d727d4b7, + 0x2ae7492c4a9864de31330c131c06f9de5d50bbfa4b6ee21132068d43e00d87d6, + 0x22d24c6c5b0ddfc162fe02b69859138f2428a54ee04d51b7d28db3dd1de5fe75, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0xce556d3d5727d4e62e2716588f873bd595b1c1a31499dacd96b724c4b7a0848, + 0x2e9e730ca4be19d180bc945c9284a0ac19a2d1b6523bb1c0ba4c105625e428f2, + 0x662d03f6ae59288dfe205ca54c24f7f33615c42212e9e759bdc519a37573214, + 0x130fb7df8e39fffdec5284ca63b4bfa2d450757eeebc88a4876f4538bd398d03, + 0x16a882ce517234ae0932404d34fd73070e27a824e337e1e99eb71abd536a9673, + 0x29c0802ac349b823b5b63267ab07fb4ac43717bfdd344a22ce4eb347dff10b8d, + 0x26a04ea7406058bc1b0892ce3a849ca4d4692db13e1efbed22eb8846f62700d, + 0x190401694ed647aedc22c5ddcfa7e5c0690182d5901c6cd17e72d053acbcdd16, + 0x210d51487ac153bd15fd95e70ce61c1760d2ca4ed3c8904a85a7be721dc2593d, + 0xb0b2f1b7b01b969254538e7e34f31c99abb093463df48171756cb005641b641, + 0x28c21cf93221e40e088a37b7e8c4e4f6b4eca3ceda40ee4b7307c9940076206f, + 0x6131acfb2371ead4b47df9a6f6e7ae744931224d78ea55cc67caaf0e5804ae, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x2bebdfc924b28a04eafda183476a1a5add23075c9d02b679e1064e61e9482210, + 0x1faf98e88f5306663b31fd4e1e346eebf6e3a1cb1f21142e2c22344f2adb72d5, + 0x22cb488da424d56b9878634ac766c48a306371ab23ababb0688e9fbc2bd2f305, + 0x1ebc0f4f5901ae74815b159db10956d58d8faef0992a2c2cec68919d131a0c62, + 0x29c4ecf2d8c9d693dada0aec9e743bb283b0f02bf4ccfb0ab8fc3fd7fea381b8, + 0x2c4a092b45660f079277c81df9f8f3a7cb74d3603bc839eeb2fbfd798398919a, + 0x145c56ab4720f6ad4011ca83e7a29a83fb11f6f1a5f9fbc2782f7ff4f7f18618, + 0x2809c4d7a6aa62cf849cd656c9f76c7ebe815d51f180e1dee45cde9714261b6, + 0x14881d4e8659014f6dbdb9c1a45f273ff86fd6491a729c1b4cf5faaad83c1319, + 0x2e10104a54b4dee285b186d2ceebb3c520a6f08b0f2dc3ef071aac189ff90a6a, + 0x1aa6d9185256a7da783e9673f47a57a4f1a539ef39f3f7f1686995e7f6de9011, + 0x1433a78ede2442f29e1c90a35c75945079ba472a07a5fff22dd632611f0514d9, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x2113235e983b253534d3373d425b2e65ad758d985010990e0cc4c8c0971fddc, + 0x2bbe5669cac7d09050c0479d3b77eb9d91f22a19776d9e396a4c79b90cdb6c80, + 0x251dce15ba53f2fcdfd39448e3ce48f74bce1d96cc2b4cac2383a40f45918c5, + 0x25af3b31579c2c0227ce1fbea8085d27d1301236e4a469f154422c0c00a3b47f, + 0x101f2400d1e814d019a47ad9bd6d800b821c2de5fec03914276fd7413071aa3d, + 0x1976bfe37936541354a1d66197e6a7818313cafdc2f4889f7647f808fa4a7b36, + 0x223ac76deff06a630762ccd8db9391023a783e28659eb7f9d57223812b6abd2c, + 0x2ac83b6435ac467384d3fe77f06d349c66d13274d40c37626c0e186ed73da3a5, + 0x1075e744bd71d84cd204e4652afab236f75fa604f833d02e2ac15f06e13ef92a, + 0x9684685d0631b2170daaeb0e82af4cbd5c2945f68dc758f05da1483c2633015, + 0x292e0a7a8cc10221f67d029c700ac0bc1a9e41dc376fd1f7ee52b1aced908f2a, + 0x1592dd8fded27b0499c5d7b77069e8eb2d27ed4d0159955db902ff47cec50d1b, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x116530f4782990542c91156b83b5283f48a5b3b96f4cc9a5eccfe8db89446397, + 0x20792a7c07e235c08d2cc9d5b4ef2a93b7ab876d9f646d0f4538c7c1ff354fbe, + 0x1c934293f228bc73fa4b8d5af9d93bc21b7db38e654c0f69a82e6d53a3babbcc, + 0xadac0d1a0eb882f325bcd49c617778178187541c3f2b877c9a6e2e200b15c29, + 0x23788446ab58d10e48572e52577108cf0d9fe33539bd0e8ba8d635c0d135b409, + 0x2745bd6d0a95fe5be2bf988b86fdc7d17bdd6323777ffed4b0ef00e692a591f8, + 0x17cdaa3978f7d9243acd9d66de86ad0a1bc5a2767206d506b43fa8df769ee178, + 0x1cacfa3a8850decdd65a7de60fe3d4b063b9eafaa858e4455d6b0da518c6b221, + 0x2291ce130877baacecde1e1932143f97da67a5c3b2bfa99ea099893932fd3e6f, + 0x15adba2fc3b14d20852d217be0744d63363ac5bdc8aefa6be3d94ebca832c3ed, + 0x150619b091f5304ccc7d367cd48d4b878a2de06dce5d9d7137ad6ee307e9cade, + 0x6bcd482b40a5463d05a49cfae4907c05872388694c4548377ef2be93c2b1499, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0xc678bf7b43613dd2c36546b68ca0dd3890f78927c5b7898a79f0051aab7199d, + 0x4d55e1ef8446fdfdd9659d06180dd772bad31738654829e3f68a54625342b6c, + 0x17451474d0a043f2ecdb1c11311e7848637cad312badb49664776d9947a25578, + 0x166f2116cf6846c85bbe1e4c78bcaabb2823e0d4c0c27a6bcec3f1c1c3a4b001, + 0x1d2d00463d86b76474ac56cfbd0fbb7f5071c792f61145f1ffd1568645e83f39, + 0x52fa6833906fac636cf7a1bbe3b6d365f16d917e5786ccd1f303eff8439447e, + 0x1aee2e06db5d4e2ebdf163a8d1ef89b70510c37acbb47b5a14d0c6496e66669f, + 0x1e4d0a71dca74b2d4c0c403a8c99cd9582611412743944d25b97ee4108026fb9, + 0x1a31ea0102b313bc96cbe558f0fc662425e25fc5f9395a42a051e927ae3fa2f3, + 0x2e7d99fc4631683d67b62afc214c8e89bebc91b4adc4625c70fc5813840b9bc1, + 0xba02e66d788b4db2c10e4b63344e564cd24c1a3e7e7f3b5c8c0bc50f2aa8051, + 0x1938e6cee09167fe4f1b6256929ec89307fea623ff00a4c15993fd44b9b9ae2, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x24ea9e2b25c1d10973fc2758114ac04d62292d75633e5a98d87d42245d3085dd, + 0xb7f3dadf80c5be4a9fe724d8c7ef9e4b4626d9e8ad61295f9482a5bdc1c6615, + 0x6d9a25f5efafbe0738e9c1d8e291d7dcc6e70434973971636fbf957353545df, + 0x57d08da194c641d1c1957a6ff6ea5037640f6b2910f854653c1d14909a73b92, + 0x1b1c3fb5c7160d87cae56ef5a808308a5188abf94b4f127411b3636a5098a628, + 0x4e0f9b281f00e246bcb7f3e5259e4554eba1148b92b1d464727259267b599d1, + 0x1f31a5baeff037edd6912779c79b566c6891b55bf02398c2a2f1f40a41b2aac9, + 0x24ecaac4d6023fb27cb5836794e1f821f6a61924d14810ec882e757bb5150709, + 0x151f138379a4341cfb1a1fa09bb3fc4ea4f58f0c0213bd2213971fdcf1791394, + 0x1f8ffc956b5fa5f6c5700394e863341ded45cbf64199185425651e92564c2fe9, + 0x17ec84b7ec93fc7204915e7cf163797456992c8b5bd1ce3879ff7238d60627ed, + 0x3a67e721da24139c6203edf65ee56debd2db5102b2c193aca10c98e70cc2354, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x199a8c4c63048f8c92b96e2fe73c3ef1be1e2ae312bc504cd6edcad0bf96967b, + 0x20d5d5315614291c431a1f27ee637d098c6b2455e019872a06bfa9b1322bbc58, + 0x204e87cda44e50d72b36c9a0bef8906abb1471cb4faea1262bbe1f148eedb60f, + 0x1ae0dc4cf8615efcdbe69bf7e65863b9884297d7320b3d2c9abac80aedf519a, + 0x19ddcb6e703520397f566c8969b47605f907fd733a7531330329fd07d0daab63, + 0x224f871490b12271549e5bf1205ac16364f8c6f9cbfda8214068b69f3b58ca57, + 0x305888f9b716c0aad54f0ce4ee1c74052bcc42261232cda96eafd2c17faee5c5, + 0x797616b6e3a31ba4090fc46bf370854483846428e52ed4fbbde16ecdb407edf, + 0x10d0c9c192672de1a9ab86b469c6c9bdf474fd4c077fa2b27e702611295e06b6, + 0x1bbe4c061e88ab93144f0cdf7873acdcdf695abe01712409f942517bf2775c29, + 0x3f37c5294f581af0e0b407e1f1691acccc9b2f0fab04fc68d968627ce38fcc, + 0x10fd1cac0351284931df18b06d6d8baaae12879304e6567e96e024258a63d84c, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x2f4ce93fa6f69179598530075c2dfed92480e40b5082c1e4d0884a6e5a970c95, + 0x48aa1e38a66c3d656ba67124986f27fbf41e16d1aea5d66b56d7ff786a5411f, + 0x69328b6c9761099bb94e1fbaff46a4643a6d52c2826038bfbad2b96aa800a55, + 0x18c5dfbb9611df4c176034f538bb3355c4ea9a34428b568b3d5484264fe2ec7e, + 0x250964c6e716f188f1a060bbfcc20bf6c9c575aed8eee7a952883875e3469e5f, + 0x1cafc40f71b4ea55f7449981d952e200242a375056b3ebeec542f743029d3680, + 0x1e345fd27b75da9f73b66d7d11fe53bf4d7d9907194ffff926b6fd73650eab00, + 0x1f86c19a4e41622c5cf6d297f3fb0966d1ddf28c14c2ef296d811dcd725656bb, + 0x67a9ca314c1b989a258f5306f02017756676c8555e15e331674dfe2de960aed, + 0x1a8c2c393c5940ee66a9fcb7745c711183ddd8d5336cd2b72880d1534fbd954f, + 0x2d0fe4e3cea76d8b33f29cf85eb4268e0097270b955369782adf6f3b56a2762c, + 0x83f71c1657f460360ace088b5682357e7d591b331beca39de70e7c057acaecd, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x1029b4658ee5d03c9476e1df7b7ec5447dca910ddf67e610247695140f7ae6b, + 0x2d2fbe8b4aa2a78e6d15b471d034a31c0710a8cb23cd64bf8a105b0f5f6c5088, + 0x2c68d13a038f7cc21d4035f2fae3ce2e44b06076755e64dbc95a48ef8fd32ec8, + 0x255433e441013f28b645c439abd003cf216195cd6ac89e9cca3a2605e2afafe9, + 0x2b6131efd66fa044954f1b2cf0798c44840b9ac5f91f73bc1d6a435d192c0606, + 0xc50cf3d47abc4d5094e4faa45ef8950e9f30f6125953caabe1240c70dac54c4, + 0x19ac7bb02c466c14f957a8683f2dc7a0f888f0bb9f233acae0568493f353b438, + 0x134932780855ca4e70db189d5439192d257a8560daab00be7ac2bb05a5f43d49, + 0x14652e3f019f18958f6e8c521fb5b375f755691cdb4cf7cc5de4ea7e5443845a, + 0xeee4bb3c7a628fe38bd14dfa58f7a774001261e2c1b0013b8abc115e4059685, + 0x1ad10967a8fa3bd36d86621d021c46dba709ff285387c064ae6f305cbb0dc77e, + 0x6fc3833718a4e8937f1151ced67bd1059ab386ffca63596129980ffe0ceb943, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x16d751a67c79f9914851155d386e13b0058b4682283da2d2078704c75576c7e1, + 0x2ded2eddee5893bd27e85a03d6501a2968b3ef18a20ecf50642d5201fd40252f, + 0x1ac7670ba55f7ee1c2ee56e825e80ee2da811ef8fa08b90d8beeedbee104929b, + 0x64cfb658abd66706a012f10e3f27e0d8c9b83b3e8e5234774dfec5e1202712d, + 0x806d16963ae96badc162c4595f484fc6a8cdf753d18d336aff5b24ce1303ddb, + 0x148cd069f578f6a864c92ca38fad53423c9a8792967e44378305739c39c3951b, + 0x1513984d0c1ca0b24ab794ed86a4b94f4750a3a5bf1977fb6feac9afc85f45d3, + 0x51f998093e4dbb4e7f8e410139a65ea44764f0d2af6ab5461b34717a9561bf6, + 0x1f87df4d84ecd7b55bd03728de507a7c5409886811152634e16cd2d35a18db0b, + 0x956f375546f0b19f6d2f31c5be42795b17904341594daa5f98886bad442108c, + 0xf17b03f697af65662c25f3dc43f1f5e050f1ecf009ab004f3fc632938130339, + 0x2d40326e94d3dd13c0534db03b0f6ba6ee54bb280af99fdd05d1cc7c94c9536d, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x2b0eee4044939efed29b0a5002b16ab0e02f75d1e193a21787d6a7f93a018508, + 0x1b59d055ed845b4c304fc1e713c622d1dfcc7eca8fdaa57f38d7182d52b1b4a9, + 0x1d2d4adfe8bf73cebefe07a088507412eef5a1efc020c7e3c81fc9c6a11036a6, + 0x2857125d19ae926856a3ccfcaf70acf2b258f9fad70fe242f7168ffa2d02d2e0, + 0x2f1da0ad4d4cdbd868691a65495006eb3728c6e410a57db82f874671f75d7c81, + 0x294d34350a9bbf726992bee62b3cd7d2a333002340a4bfed74f6209c4b6173ce, + 0x16e5f374066b223ca5a2401f102d65f5e7fbd677905b2e17e568612ff96b602c, + 0x17c1bc44d70706417225c79dcc9db569c79fbea66c018f2881321c4877b7fc31, + 0x264cd13057b3635518ee4425f88edba986a49776e94760a4d73b17902cc0d359, + 0x2b8fa1e65fdb45989701a0f231114c0ef7a8fd3725c62070a9d748e5aae95827, + 0x79f16e76efaa3caa7e2f266ae7b3f1bbb54a6ee571688463c9d62b17acfd6e8, + 0x1c5a6ff0893053c43c552cf41b68b48a7759e63d0fc6069d2ee247c170f71d25, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x277dcb1f82810d091b7dbd02eba6e8edf5c97b08407a469c4ad99ec0a7938a26, + 0x1507357ce338a6f1c5f01907a91c62082e6e5182cd8b8c47f9051b2cbacd5238, + 0x10d9fb4dc60b7064e8d6ec643727c394da7318244c57696bbb473e2bfc273cb0, + 0x51cdb7af55af1483816cf02db477c5c21a2e16760ac17395417afc92cc78979, + 0x57d7491951dbf51f0b1b05406e58ea37d61518a67546fd430178a47e5c34dc0, + 0x1a512039992c0d21bd7f2436bad315a3955b38097568c306fa92e603d4129ec1, + 0x3047f751d881408a1f583df677a7313f341d0d90150b0031bfdaf5a17c1a71a6, + 0x182d95d647c5f27363818039527bbbbcf23f4c143f6bb98b064daa5f09d127d6, + 0x25973c85813c7ec78b26bd63395f522e0f8cfb0fa6a82375b9b65ef0e24c2aff, + 0x30016e4e94afa204d5c420908f1aa18fbbe286a9512a0f7dd492b268e2bd4d0a, + 0xde8759915e7ab1ba0347e7d3cead6663449cf3e56dfbc87b231f784a6a16f6c, + 0x2b3e7d63f286ab49bb3ccb30f9a8d337c2a871799020681e7c1e5170569bb6b6, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x22f6dc515f2a6d844a494d3c307ec715cb4ac439abab7badd9f0084ce1785718, + 0x1ec843ef7fd4d4078d3c68f3f699197d1818a3321f64d15d940ea6816db2d4ed, + 0x27488355bc40e3b48175e215bb7937413eb1fe296f51266e42d421d1d744859c, + 0x2e5cb786cdfbe0c74b05fcc700ee95936658634d6bb9152251e1ad38f3ca6666, + 0x92f4b8b30e895442ee3f481121a04542cb01e9a458f3e61c773328e1b887f51, + 0x2943525f7b6302dcbdabfbf7ac5c27c0187bb016069c33b3947becc68c00a873, + 0x22a61651f69e2636019411d42edfbcb0cdbcc3b1c0f5bbee8ac9baf66b1b8487, + 0xcd43ea643c19e6eec4448fbae1ea6c40dd9665d93b04099658f4e216b0d7925, + 0xe6fb9ac72a3c4754de58d5b4ebce0f32aa651db3d14d5adbab0edf79d746644, + 0xe18bf3657ce59002f57e8a25131e39534ade10d742313d81f02beca3cbef04d, + 0x24d31ca462d9f59dfe6f114bafbbd67bbc9fb15e260bed3552e06e559bc049f2, + 0x1663ec74cf67dbb8e668d7eac5c8bf51c5742c090f7a707e297d44a0e300b093, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x159eca9b923d7cbe5bd8ca7b3ded11c3ce6226130a63cb905289e0f02a5351cb, + 0x2abbc33b435baed63f3c31aa583ebf8061236d423321e6ca666d33a0159b1193, + 0x22798974294faef1e314beb8b7dffae46b50276230b06c98069b742d5bc789ce, + 0x56841bcb1c18a70dd298ada142c577a249b7ca301d1080a6be5a621d604f15f, + 0x1823a55887acaf96966399d381bdc7b8a792d40d71e5c5dc24a51d02f9946cd2, + 0x27bb9a8678b0a2cbd911e61b68f4a6928ec6f3db90fc28884af8e20ef711842b, + 0x1391eb35e10db17d84b0e7dd45145a754977c4cbb90ed1bece966ab89de71f10, + 0x1ddaad4930fb9cff01affe0c6bc2034acbc20df09fefb4fea7c346dfadcf99d8, + 0x967a6467b486450b51ca8d529d6aea1efb101edf31f3646efe1e969535a6a8c, + 0x26edad91bcac2202606d579d3682ee71417af365a5bd3cdeda16158d0059f32d, + 0x9c8e2fd871c35f3448ee49d7e7531dcb5301a6e748809ee639b152896773878, + 0x2de254340f39689fb3c5e3740c1d1ceee26e8ef87c64c8b3ef5eeae2712a2fd, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x229ad4c71354c4b2ae2f011e374de05f72548aac7f407d8f52f00ddb74f2456c, + 0x15d1ae9e3d615f8321be16db99bd43b9231dc51fca7ae9ef2c1ff50cc948d5e5, + 0x1ad595eb60e44bda1591a4a7ea6facb03ed18e8e4c7fe44aa4949c176b3fdd93, + 0x21c6b958e8a24ddfd5686e18a1b1c93843ea3efba13869302f46382e6a57e567, + 0x1b4643c47be36a9608af217edbf9b2138045e295b062dd4b720896c55c1980e6, + 0x44415df1dbbaf342d11d905f569a68a53cdef58ce2bf19503ed0d032ad3cb58, + 0x2b1b266d410ad7a8990d350e5be5b1be70822f5cf0591cfbc00302c6a1504fad, + 0x3cf806a68e9ee25ea00b57abdeb9f4b5ca199f9af3428a8b5cc87db1efe81ad, + 0x1013c9c92352dfd09c3e6acaaffa2c44923b35492c5691bc7e9e734072fee822, + 0x18afc92340649e0d9608aa526d2f86866d4bc5280c3f45addc6567b8339286de, + 0x265cff469832ff20e35d2da4e50505b8e17a4eeaccdb516f36f3a71fc916a82d, + 0xc83c2b9df3aa4a874494e329206968b89b23b02f35258788e9bafb43c47c973, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x10bfc00fe5269d28301b200756e26cf1281be271d1300b11d988a9ebc062b10a, + 0x303c1e41ec4614539b4edebbce405652475c1282eea708cf2ff39ba8aff4a4df, + 0xcb8f9cbe9420f6adf09e987a8bb44158ffba89abd7a738ed54ac6a95f17500a, + 0x2f0cb3011c761f84dc5b01ba7a89194919d06f94304fb99dcbc0ad7a7bfaf796, + 0x10151a6d8c2e4d4dd265b3ebcc0e778aaf056a02139fff9c2ef25968dd2abad9, + 0x1e50838bb4dc4ff216abf8455b8585010107e2d64d1fa600f6f3408655d36fc0, + 0x528850ff2c7ccccd074baa85e0989e57ce76ea60b697b8ff19c97f1f9b5771b, + 0xda83be0e16ae4edebd1fbbd5b3003486f5783bd79164ea1c6a4fbd945a285b, + 0x1bf809aaf61005aa262952e1ac2141e5a0aa596fb9d828cf2ee2639b59101e65, + 0x231a51ec8565bb72d6791bb758f8abbe5392ce08a655f2bd03f7593a026ed371, + 0x227aa3bd0866433629f3cfd228e20be57f8499f4a5597d3429c40eadb238f1f0, + 0x272b5a76f45cf6eee3210ca6df476b2555fd79fd06180b3f7eb546bdf2e9e4e8, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0xaba393911c001b6e701b44726a176bcdb276d02d3eff5e70b0cc16aa7570958, + 0x282c157f6cc7614232f974eb110212f786134a965872ff9ee9430cf05a7826a6, + 0x16cb3b06654e4997a543284ea7d12efa7b821e96889b0dfebaab9eb705d829b7, + 0x2364c3f74a3b18bc2af5f89126552fcb58c80ecee9c05c0fcb4e39332dedb205, + 0x267b1113aa1f20f45d5bd1e042290c8d1e7e7b4b5628184704b81f894d07fd0f, + 0xbd187c337ead48b6889b3e20026dbf604729fb27460fc1b51b7b3a03e9812e, + 0x2691351a32661a9080480e51d758cf0e3bbb9dbc43e108293576c153dbb92654, + 0x13c49152d941d3664ef620a47f29229b8b41060b9ae5880658772ac615f6c48b, + 0xac5e68b38810d5343dccc099076b7ac9388c25cd6a2b2d182800156ad18b438, + 0x18a7e5e6e2f6d92c409fcf6bc1978d963fa8093bd83667a95f19841f1a826022, + 0x1ee76fbde9ff833d860abfe09f44cce584cede5a6a20aa765975764d97c3c38f, + 0x29139e18d16666687e950c7f417aca14588356d6737bb72d04444fe31e15c292, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x27ff4617698e6b395ced6d0e40bb327a4dda5467ae001e4ed828713c58e4cf72, + 0x1faeaa26b9d4016a7b060a1125b5b83e22174ac6131c860d77c34cf368d4d5fa, + 0x116b96192f543b8503130b1bf684a9bf282b41f400aad0041777f741f97d42af, + 0x1ace40f357a524887cbc0748e9cc2bd2f968a87ef94468359c48fdd333eaffd1, + 0xeb90e74f33e537563c4c2f8633e6d8f8d2304266741ab5b0c0c97a89c4f76b3, + 0x15f692b65b0e4a2729d1d07a728029a22e6aaf2d8013a26d80ea2f4ed7230b2d, + 0x199c258f1265f41f038d234249d79a9d7cd0f435355f9c9f9d671d12b3d81360, + 0x2aa4870dc13bc48b19f3d7ab5df282f855783d5cb1539cf358d235859cc38328, + 0x2fa96e08d4613eb78063774846b608be0b7014165df4207b83217229d452336b, + 0x1e45df6508abb41b74eef391fe603465e142e7331c1a11e6d1a6dce3b5af459e, + 0x157326de3fc278a3ab49527c3bbd66e6944065a068afdab3426acecda2fced3a, + 0x13cbb184686e4e800c03d32b9bb0e86322c0547ff70bdcd6b6dd622fe9cf772c, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x2195bf264d78f5905511e946fa2bf8fd1c31e251405f24edc679fdc2e28c4935, + 0x2891a04c8c9333c3f86cb9c27db0cd4590b91574f283d98d87588c5329070ff8, + 0x25774ca47fb81e980d6024bcb7849e10bf90974712f1c15b3c5e42d48a990b32, + 0x19afc1bfca44fab6dd8cf347d13bd9d679a663ab864dd7474c095855a69489aa, + 0x2a855f347153503391af5cdd8f33ba84d9b7f330c5d71a3d4d1308aa36ee1f5e, + 0x2169a917b5586a2cd1f44fc39acee8a0af21c0b0551fe2823662087b50d3e183, + 0x165c3839b46f2b8d9c94cfd1acda9fe4cb4b37b64f7530324e44a859b82c083f, + 0x12bf9acf97c5d1b2c23723541455fbfa679d3539879434010843e578fe33ba26, + 0x973d4990abd501d246a5bea2b5d467ae07f8f141968bc7049a8d7d100b8d80a, + 0x281a0f1018049ce5560aed11919df7e93c341795c9fb1ea17ca7f6e61f56450b, + 0x1607dc7766404c513850fdefc9f3e25d2b9f6e90b4f566418fa142b787ba1d2, + 0x100010328a776d1e0c53f55c79556f12bee9f2fc908b0b19b215253b91c071af, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0xfe6e334c004b36f6a9aa7a1695325b8413cc3a527fd77093960d6da1da678bf, + 0x192c7a5566dbab04d61dcfaf9675cc88833477473f0742c7df458dc0c72492f6, + 0x16d9f79f4e2e32895e9b7d3a13cba3f9055c22ee00fafaf94cf1a2237279c28b, + 0xb3c970c3abc81a5c64df8177d69ce62aaabafe4c797eada6f8724ed59924963, + 0x1e3480b6b43165f2e9e98cdc6b1750c9f8552375c746fd9318f6e98dde188146, + 0x3ed9978d698020e1627fbde78f83dfd7267a525315d03c27f934a04901d717f, + 0x14f962e4f1786884e7ec52bda63442115550a7523e9840ed60e8ce1d97e81c27, + 0x352ef9bb93ac53fbf0cad44a4c9f359d8be239da7c8da512c3b8f339f1eb8ca, + 0x1d7daf3d516993cdf2ab5199f7fa038ec18b7bc1d7643191dca490734b41162a, + 0x19c4fb9c7330292b9859c4471c0558692ef015cbd58c7d6b9f8f6a61701055bf, + 0x22261c2ca798dbea2a989b4959a6ce59a327a1a5817ef4d0c99147d79e119d66, + 0x1c8a822a7cc949bc91f32624282c0b91835aecebcc805add937f2c33ef2b13e0, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x241eafca2ffd1a89501dfb8ee9f6b91c270d2edfb22b77f5d96b64c074972866, + 0x1ebfd44d328c120e25331359b950e96faa3b24d803cfebfc3fbdb5aec7d3f21e, + 0x1d45f9e955be39be29b72435e60ccb82ceca4dd1f1bb242ca40461f9966dba18, + 0x3e68e982b6f9a1317a8c72d1519c8d992747107cd1647f55cf86f1274921934, + 0x24d58310c23fa88e127678cfdadc69ced4344aa62dffda5d17bfb5cc6cf92164, + 0x277159e31996dcdb712c9a030b14b40e45704c9debbf6c83381d23b98277564d, + 0x3fc9ff00ba6b7b1584eca5fb9bc2479289e05be8f7fae084849424cb08a1412, + 0x102731ced3c51f13b9f0c571a0327d5b16984151ac388ae71008e062b103c7ed, + 0x2aec624f610d949b7e050f9240bdc67eb00b17980637731a93401129babc51c5, + 0x348bd0822fa0e5733e59d37c6c25354a899286210dd11b006b45086b8936e64, + 0xf7b4685de34e45e8e884726809202d717000926dc62d3373ecdc8f6d6105a3b, + 0x229abf24fc333d2643cf514ec877c3155b9f5d4563975ddefa179e69e728ae0a, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x1e9a882703f9fc17e0b9b0e13c13361beb7f37c04d00ab391d59bff4ea9cc738, + 0x18ae81de5d561926c49500b4a1c817e127ff35bd92ef713b8becd8ca934e18ee, + 0xf691c4241640871dccc03e386a591c9068711b69e35c618ae8213a7b976b467, + 0x1dd3a781963eacb7623f1a53996b79b1c5dbdeef63ba509d264179d7c7c58367, + 0xe30b8151c59129f74a868583f2da36f7f32cf07d93a21dcb8a418929a3bab4, + 0x176a4a7f6bf803a3b2d7b366d35468d449210f48f31753fb63d4c50a522f04ee, + 0x2d0138a0a5f600964d4ba4ce8391caaf610e7b9cb46ece6bac438658e7284606, + 0x1208049ec66dd8b35cdd748c6b7e54c3dfd4ce63937a8e5f5d7bb55c70bc3256, + 0x1c9f3c36dfe21664afaeb0f1d29166f2896455fe34a3e3a937767a3de6fb92ba, + 0x203ca885554ddda35c4ca58ed2150867f677c99a1afa4796fbec4c3ea534b7bb, + 0x20e28f5d901c425eb6d48980e9f86b212911fd94de850663e4bc4042cf2fb8e, + 0x8eee40dacd3ba8ca8953eb7713bf9c642327bb96f55a7200f7f19851a25147, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x2de2cac04d23e8f84478018e4160a1cf34d66ecd6b4cb8ca67379b0dfed1707d, + 0xdee104be28ba9a4493e05d14072223610a77ef655f646a8ec1f254146b0739d, + 0x198546db1f9b3073c570cf4937bd3d716336b8267aeffda95debaad2764c91b0, + 0x2df10c785477ccf2aad54873a099f7a5245b7a1797d4b7692df35a01a4265e0c, + 0x38e6b803b72b22d07f3c4d4da85d583d1952dabe6f4cbfad8ae16ffe5aaed55, + 0x20ff66ad9f9056e8a0c513785f7f1aa1ad0b53ee305429c5d299ecb3b7d3ff95, + 0x2662e4ce6ef014cf95ae1041e8ee8f25eb02d188a234bdbcff2a4fdcd222fa0e, + 0x174299b27d180d0ac59e31ffb101a68ebee5b5e17e8ee251b61cdc2d73b5d96b, + 0x2cd73c6ce46c664bab760c4d73a7f05132e1ddfc0ec113e9b37f9144f7a1a24a, + 0x1c951a5015ebe45893a92af1b5b51688298fbbba474875f7b9bf97faaa69cdfb, + 0x1292a82ec348fc639f61c1b9d4f48e1a729f8e4d297289c45deb9d79245a7c6a, + 0xa0eb1649895b7028e7b286f147cd47655fd9380ad96b12f25d4d50134f1b624, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x153879267fe585e41277a47095c2e71a556aecc89b880549a3e6598a2b679888, + 0x20564715ed17601ede44b0ddeaab78c07b24d7c384b2a278ae5902ae4d53ac21, + 0x244a763e10b0ebfdea4ad6e115bfc6294ab8592515a0f103750f23ff4745d4bb, + 0x2313de5d350a08f83a06f60301627b52170678ec4089d95e31a85ce639d4d3fa, + 0x2f61c7a357564272a6c31f1d4a2c37d68f947ebae5ef06f0003f47baaf8b2551, + 0x2ba56182022bfcaa94b28c4bac74fd7bab368e2f17b123aca7cad3c07377ba7d, + 0x903e97b86b03d63bda9d015cfac4e1df0c7eb553114d6603e1d9cc6def5a2bf, + 0x17ef136a59507887ee376c9d03155d5638f73695829bdf753f2027c93f6e0ff4, + 0xd2cf9780d3b8665f07b485f9b61c97ad43523b52b89a216175fb479596b429c, + 0x2cb10c6713c9c041f988e1d16e1974db3bbf64fa6a0dd716654d2f3d7ee3fa08, + 0x2a7fac0f7cce1677e53465203478eb2a87f4a5acfd0ac6b10b24261967f265c1, + 0x150f1a3251ea142ce9c8863adadf908f98b6f4eca4fa8c7f60834ebda805efce, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x1f5f9f0a9e7226242aba685459ba2d087305dbcd15238e0d61537fbcb4e8ea54, + 0xfec778388bd29f1fdc01719aa2acfbbd07873a4c628caadf04ed461a49b5730, + 0x8fbb80d8ad67e52030c52512f3947eb0fa257e7a6bc97dbc18848ed6843fdb0, + 0x220ae6fc4a1411f922a67c3d2191d16fa72e4485881f5c44d07ad1b30ff72534, + 0xc24db144fed773dbf4a285f6b292f097e73c4210b64f60d0471099526125207, + 0x153e33da5f9393fb14de5f8d9ff25fec63f9c284563c9b75485b8c5965716022, + 0x28190eec890ed4fb51176a21643ca8bf8a4c6d1ddcdfbda70baee9842e771e0d, + 0xd352d314f8a649bedac97ade9cbe51cbb4c1d76124bcb753ff46124ae2c671f, + 0x589454222f880ff67b3b6771ac9579115ef98b4a5291ad1f466c37df59f7a0c, + 0x707968b36327eb7bf42d881932225d1e6a9cbae3e9a9eb1a3573575b081525f, + 0x24d15b907584822d94ed3cfb07644a1d9cf985b94ac08fbabbbf5070ca3ba2cf, + 0x2d51c48b63d97625628fc1a9c265a29f4b5ac1a1d0ba807f3f1d6a729e8d0d7, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0xc5d3e1681af8c731635a66d82e8ffa52d6fe9ae4551c31d9ce5c7e9f1482f3c, + 0x19f573c7bbaf4af57ab119d9c34a976c7a2770e9960f8324bf938e67a40bb621, + 0xdd53d93a158832a63ae02346cfb050f4aabd93d2c376a694322b70020af739a, + 0x122168471be451e1fe2383a1a82795668084d4602e136c3533156ae4eb44e5fe, + 0x181171e6af7921e268f8e4ca02a69df02f99e374f086433e2d8438465b878fa4, + 0x20fde424afb171516bdba5aba1302f3c40adbc6df6009941ce0978e1005f1570, + 0xc999a3c07697cd6e4632110862a0e3cd6f2ae7ead5a0c62f83e57e3752726ac, + 0x181e43350d64b75df7c57808060a8a467304a9b10766426597fb485016642d1c, + 0x22f941438fb638d0f6e1013d81672149e91bdd794816a149426830a140ba5520, + 0x27bc96df0a03fa540349df2a46633309b8e0d2935a624c7aa51cd859373b1d3a, + 0xda6574a31cb0b010480dfb6ad33015708e71c420b8f3664186876afb8b48b69, + 0x2a932da3d493f5d229a00f18bdc6b13a00783ef10510ef02d3836a9728e75653, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x1aa840ec7905fbed4b22675c84cbd527218db6bdd21e9558fef98860bc337607, + 0x2c5107353c0edc8e05ad36b277477c9d3ab2d26fd43dd2252878ca814c48459d, + 0x1aced21cae771d0294a1630be67579d81245093d2731898a72b822f8185ef3f8, + 0x1a24a7fa4d6d5498af1df2f86ca66471a340c4747a1e24f592aa7667346aaa8, + 0x289caf37dc4c64fd8c66718013fc3f1492b3c76cd1ca713196aef3d95281e3a9, + 0x284c43505df8fa7ddd6f9ea7464f3caca8a3b3b55d39512a38b2f37b7437802, + 0x501489e7c91a13086c850a7174848dd37bcb7e6a2f8571ca3086415e22a249a, + 0x1d911e709cba9411cf221392b1d8e8f292d3895e5cf250977f7bdf724637e7a5, + 0x26ec755542bd45c2c4968fcc98192cac25bb539cfecb7c16c926edfebc0dd4a9, + 0x211b3d812f9687467d623861909909e8a579e66c135d0ad0d36038116e858ceb, + 0x1835f5c44c7bec7bff1c814c38d109572702ee85860c2977650db910dd555db5, + 0x22bb08010cdd744ace85c758c58576d6b353ca6326e9de8ca594c57b40a76b48, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x178bdbd863dfd248db7cc60881b17996fa8cb0f5a806ba37e818d493dd4d04d5, + 0x2c2feebc25c3e9911fbcd7c77ddfc8feda0e36b3045e86059eb2507db84b20dc, + 0x1d8f0924e2fe93b786ea1ca32cd7dd268097e1144e5f386813e40d7de6385414, + 0x1d7b4297d5b583bc00d946ea2d45e79bca3b869f3889a3ef8b6986ee80515603, + 0x6b29e8a6cd82571306523e57a88ae2f1c627688af6a57ab4adec48071d864ad, + 0x23f708026a0738512248c05a5a51dc0f0b64cbd50c98f2c001301a8dada15649, + 0xfb9b67606d1b70a59afef99cc15b51ccdacd8ac412858e37fd0a5b685aa1187, + 0x2e507b8087200a7b14d7c84650e5683ef78d7e5281b489d43524206ced314cd2, + 0x1bec098d210e06aa6b800469725bb7d361da8f106e3df06fd5788b3b423bfecf, + 0x6ef2b78454ee5f43388a7ea4728996fcacb8c01c644534fa590de1da8642172, + 0xd5662f25569baaa0b10d66142378f0ff302a3654da318bfa370812bad2a66fc, + 0x2bf77b6c0aa149a79c695d67d64005c90e926b44890085b3fe631b4a8da64760, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x1bd8975c90ca4e356f1c37f12fcec0ef5ecf484736f375f78566ba8aa9e86427, + 0x2bebb46043c675d8d4b13e9d3c243f49da64640954fd5e194022c846d69cdd69, + 0x1fb7e54c00e38234348206b136e17db48743a1e8833a4146f905113960314be1, + 0xfa50d544f0434df48d3dfdcfdd164b9ebd8e57d7a60be66b879294a40a9c396, + 0x283ea6139b65326666af04d9913f3200f9b93067867be1f2431796e9add5bdac, + 0x758ac2a306bb32c1030578921fe09a5d40d83d968ec10aad31a15a7c56da8b4, + 0xf413088d4106e8a46bf7cba046d1f47b7f8a741400768835d853830ea00ef3a, + 0x466358069d58f4786b2ca782dc4f7a6786fce88983fcf9275b9a5850f814f28, + 0x1385f23802d6bee8b76743564dd5510ed1200f094ae6c16f03ff8b4cefa07047, + 0x108072d197cc79b4188436a0c50845d245ccbfd1480a4882af2cc88351d5419e, + 0xb6d297f7ec667c68d5d7ff7aef48259dde62daeac24b7868e0fad90ab3f3a79, + 0xc82418faf403bde8e551554f4c8be945cfcd1f78615c9525d3c607930b0aba9, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x297b1a1c6fb19a9f0490226d23936796caa8c47a390ce5e3414d91243adffdf5, + 0x1d8de05dd33fb6513962f6bf1406d3da402064e2d32000dcfba1aae1d39a2d97, + 0x19ac0a18a29761fe4968baa2f8d4d4d7a8d241c5fc5cb54a13997873a4bf8f0d, + 0x13009a2e1be50b353babfbfa0c9fc48341125c9028a93d99b16c31835e2191cd, + 0xd660995842ce191476ad064a5599e2c5415f48ce57392e66e671a503a30b119, + 0xe5587ae4cfd416edf434a263c9babb45d793a1b522fc96e7845005f516944b, + 0x10fbbc420434916261f6ce95d1ca7497b8237143757089de2c813388acc3070d, + 0x190d15507748b38ec5d8d96cbb40cbccd3cd004f1f500f3a8fdf9d9dd05cffc8, + 0x70e81c5cf9512b85087fec4b044bcacdf0ebc36939e0e33f12095929b153fa7, + 0x20577171accc171de1282cef827a5b3f7620c29566598066037947da13dc09fc, + 0x105c02eabf359c9fb180c1112e560bc894bc2c453941f29e1b52c28c0d8c6c31, + 0x701986232b2471f9bb70c70941f0732c59b9d1c1d7acd7df2b5c9a3d1063397, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0xbd0cfaeacb5343bc71818eec4baa3eb1f73e5ccdf4d4fb1e585b9326794d8ec, + 0xab6ce9fe9ad13beeeedb535f9cc7bdd51a9edd426a54a9b85b6f23911dbcb8e, + 0x20f5023d1e52fefee124ab42f5eb28a0c18cea887e3a0bb7c4626ee694946984, + 0x180f0ee72343b33cd7098990a9bf33abb509d454700f602d23067f031a314ab2, + 0x9e006f3e85886370bc11a2c92d6b1905da2e1d7389fbbfa8ce2b0c3797b3204, + 0xcd828a1733f7fe84eb56482b0c373b7bf9ffee9c70933a70782c46104a7abef, + 0x14ae5043d94b8f236d770e5435d370e07be470537fa8734aa62453ef2dba83ef, + 0xcfc46dedc8f1535ceabc7507cb5bc7dc27a44b69eb8d799ea037b9dc0cb49bf, + 0x13d10cd39447e65f03bcc27657ce46b8f4b9f0d6d0d9052eaa700aaac4e56204, + 0x1d19d4106503a113839685de852f7dfa1ccd2131552e18f9e62799bfdbd394e, + 0x1c1e57d62f76f88539ab7fd73bd7577c358aac8bfdbe0c0953cceccef55b1c7c, + 0x19f2dac762392328c37a5a54d4cb980383918297078ca2fccf8605c52f36ee48, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x11104096d51f11f8db806853a470e1f2838eec2abef570a01a7bc833a27526f3, + 0x203846151d74394d322ecefd82202cb29361192fc6692f8de4c0788e5364bff3, + 0x2a3214dc89d8794cc308f0b2fed1240426e9095879935f4889f7bce9b06d1223, + 0x296caa3afab57aff0ceac16ecf05b6887ae6981c263b60b49eaadbbdf5332a76, + 0x2ca633b28c1343b7c3ca88c3b6f4f9da113daa93280626e98b3c79d6932d3932, + 0x2c62732b69393a4495154205a9b636650a201271da60b65433419ae8f4543f2c, + 0x54a20f1bce174b2063f5581a86913d9edb5b6b30de76348a881f320afcd4c0d, + 0x12dbc8f4c166edc2716c576248af681b69ed94ffa1e5b3b48459c9787ce39569, + 0x13d733d018ed7c6f4a1e471d7b8a6f36047ac9ca93167d7f0aa674f1704fe7b4, + 0x2baa1b752a095c0d7552dfb65cf2f568b47a132ffd5000cba2720ba8ac4c18a1, + 0xdc97cfacd4771b400ba35d33cbebba737c70e84f07d0ca37dba093a2460c944, + 0x2eb71ba2764a7250281b7d3506deaf0416593ec3428df1a9fe2312e66541f31b, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x24a6b2f63282ecf9be0988f99d0b11798ca33f2c8bcc4e5669bc7a256ab3594b, + 0x13b074b54de58e9fa17ce6356d3a6da3d800419d9a7170e3bb1310daa4f4f96e, + 0x2711023ae2f03c0399399775a8ca018e7b91e50fb4c7529bbb09d5cc88dc9d90, + 0x9fbf1f0c9fc28e92f2040fb7b132373a55bdef07f9009c3aefd13ee0f7b369a, + 0x2b5a1ba0a4702083424b045869aff8680388290f4b164cc2f022b16eb0e96e58, + 0x1292c762ad6a3abd75f5ead608b8f2f90f8c528b772a42d750cd244d74db2e86, + 0x99282d849ffac983bc6cd99827a1d368dec42e7fbbedfb56a6947854f4177b3, + 0x176eac7dd262c43fff3d935c0c11db3d23b0542a6e5e07502dbcea633ae43106, + 0xfaa232a1d0ceb281c3a428f3e67aafe0fb1a27fbd58c89b3143f486dde5db27, + 0x20cca8c39156be9d3b7f3caa041af52ea538f3ec173cccc0b3497aa068b8e1a3, + 0x146799bee14e96cb93165e30306e78be322d11b4ff008af316286989d648ebd4, + 0x2b1d7a8ffc222693ea0d5398028d6042bcbfbce6894aae6c79c02d3398fe43f0, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x13a158f9d67d4b35e8187f741513e818c32a15e9ce3d7ad17e5e0ff76861073b, + 0x2b64a21d911a768ed8f424092d85badea0a141699d41bb31b44d05ca7677f622, + 0x6721fc051436a604df0acd76947426dd9464034c79d02f434ebeae270b8f113, + 0x1ffeeeae4f5475d7b8cfb723d7daed094e18949532bb7f47635ea7290d27b75b, + 0x94d465c413d8f36b86f1a1d2cf263ec81a2588fe3784ad6c7e7abecb2e59853, + 0x205f5fdead5ce83dc8000b0320741d41c9d2c729ff5a7f0cf8acc2c875cd3257, + 0x1978d9908c11cde5f456e20e6ebbecb4d06fcd7e31e5e70ac0efabc721aa8a8f, + 0xdb51092fb5654d04e24dbca267fbaee53776bde616f4f87975b9759cd833207, + 0xa93c02bfdbe4c17a20506b1a5c56caf375aec6dee3b0b2a0884a48b104c00ca, + 0x26d4bd0047fbd72369c8f4834ed8144c5ff28a42ae16b56818b842b9b4d6b9dc, + 0x17c89c980d214a12738a2939cc7fc425406aed9be9a932e0c427991610c0cf73, + 0x49a23ee91a6c076fe5b135cb6f92a8081c604adcc21c8d6456332de80420263, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x13f9655a5f1532244d4e030e782ca3f9d236f8d302af289b9c0a946376b45f3f, + 0x271d8aee48a5a8dc6bdbf29a491b31f24c71e023554a92693eaf0bc68a6f0272, + 0x250f4bf66572c4d089c73f90e1ffed7638ae0f926523295891cf7c765abcc0e6, + 0x155c20d00e84b634d4884c42359c91df2fbe1de2f75006677041c0e70bc23acc, + 0x14c2c6a209a7bc6aa6d978fb994d95646613ae8e6b0e0e5f5cc8f5707766c7b7, + 0xf12be26119ede0fddb6393af22db838f258136f2031fdd223dcd8e1bea243d9, + 0x2efdb0edc82b4dce032308b04745dd1f1fbbbb5640bf28b188031e0cb2e1c1dd, + 0x1ff34842585b84d2bb8c9151b3f6c65f48b84a4e34b07f60192c13a6ce08a7d4, + 0x2d9fc37d4a22c1f195838803941d2f629e69eeefc566990919974d8e7aa968bb, + 0x21b778120c0eb0974971f5a24e29c204042f8b50a61b785b7611b8c0ecc6bd8c, + 0x1fd36ff9b7adcf1b3cfa6ab317bdfe9115683da95b29f84c4e113fa6e55c6b90, + 0x151cf47cc2e82f3eea09b8d6aa86037caafdd0cd43a85ecf5fc3d314380e99d8, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x19c8e29952ab4d0984bf1da922e2448fa9910c0123a999a592dcb473f296564e, + 0x23331f65cf68a733b5e8142daf41bb2cbc40b2c334b78820e92852637f1e87ab, + 0x2a7f938a6cdc65be6c071c8807ff6df4c48a36bfbd92f55fd06c057a48bc8aff, + 0x2c121d40b94585543cbb38980aa3e320f5bb460d165fed90e367f2799cc1e8ad, + 0x2082427ee8b6508762d08df82f8449c47d4b4b117165ff4fa1ff944d63b74d7f, + 0xbbf36473715a6bfeb2bd46b4650b2e48b4fabb9059c1d41675fa76d880edf08, + 0xfcc45095ed5a36166ce4033e91caa2446d9594905b652b7b56bfcbe7fe03ff6, + 0x270c8e9de025f4460363730d789c1f3dedea3343457841db516e129b670c25ad, + 0x1e9cfb5b0f1dfd2465ef5d2731a8d5d26b5479cc6b6e438783231e5b0e805faf, + 0x1884f4ef9e723cc405fe49803473ebda5080731b4878e1d3a5108fb20896d14b, + 0x182b8932fba285b925b7454327ae2a1aef739b088bfb47dcd675730bd1aafe4f, + 0x222f2075bf57fc059a247d5e733b3828fec1aac68509a2c0e4a8ca1fdada90fc, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0xef4c76e42df7e6d4e71b536872ef6816d62d64c06322bdaac4aae65ce6d59fe, + 0x4e28c59213cc28cfb7b21091bc98169875e4488188b70a385197588025ac778, + 0x2d69c1a48c1be2b798dd77218a0653f7bec46bdefb7f55cde3e6d28f56527260, + 0x198d2bf44196f81d74761554f80cc169eae8e817f44ecb588bc64f6277f1d625, + 0x13c8bbb561fe1109612865ee008786c5d50158e42d9e91b6f52b02508b67874d, + 0x1eb37605af262ce36884c03967bfc38d8f625e080c7bbeb4bfca07e25458d12e, + 0x25cd986975f4cb765e4a8f17706cc4438675bf8ab7b110470d88dea1a64f66ad, + 0x71d02268b089992a8d62240d94fe171bee083b1a2d9bbefce3cc7c8cff5a577, + 0x12ee53cf69c9a0be3be3de51789d16cbef35961c6114e4b01244d814a5ced3a0, + 0x94acc645dc2e6929022f4b4b946e8f51ac595fb3200074cde24b86643bbfc43, + 0x22af41b2a54ccf55b3030b344dbc82eb8499ca8c67c191d4b6873bcdb7639f9d, + 0x14c87352fe94d929e26aeedc2421c5812b7fbbcb00a7b20a79877ee086416778, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x21cdd152af751112267ca585f98b2abd9bf78eae7bc404dfd9e8d34010af7c3e, + 0x20d39dbb9c5188640b6f30abed60efa7c61433e6ffeeaf7cd73bbd2d713f55b9, + 0x2642c98bb9bcf76eb3b6e3f86c309b400e79071f12bf462c19fc612a89722b65, + 0x2c2562c294b65505f0ffb6476def69c03e6d1324fd2ed7319368a61c7fc672d7, + 0x265a567985ea221426328919c3ec1bccf462516e6525bee01d1d810c172e88e2, + 0x7fe7a2e56090a75757a54a27a15711c9b7b3451536b61e6a5519a3a073a5a9e, + 0xea63f1b7258831a4f087c53827988f0a5033170186619e513ad470ac9691088, + 0x1d0082b1e2aba35d77b41e3fca46a4526360eae2d1d49d7be6a4498f315be6c8, + 0x17c7b18d8e5324867653d44a765f34f6653a43d2795b040900a2e0b4c03baf2c, + 0x29e0ca8dc73ca2f25b4dd5c756bf5316b25be6c0811e62c2f4437fdb9a7e278b, + 0x1f1e7e26201e619629f66ae5a3c2e09acde700436c22b1ff505280a62db0e242, + 0x2fbd789305950579f702ba8777534c2708028a7845173f13e187752cdc5d98c4, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x2a88c6c0393f56fa63e8e340f708efaf40ac4b85b2ee681d39ee1aa0dfe396e5, + 0x20a321497aa9e78f16a5957492e3ea0428d22442056649de52d115b1c73b1079, + 0x1f00d5da2a0498a2c1341f1698df1a0780c5169111a7b02fef79b0faf32d6498, + 0x15f194a187cba501891864984a6f52cfa2d4bc63ba2a35f61489c70cd651e9b9, + 0x5cd85fe0fc0c75c027f4e3f1bc62872153988eaa0b2ca20b0cb5e7fa3a687e8, + 0x1ed21eaf16b3d661b44df4003cb3636184353d25def19bb04baca933a3142e78, + 0x2b37b5e88cca20d2bb43f1718091b40fc1ab0ea7350f77a5a0ce905708bcf2df, + 0x232c7f2de11cfe7ee3c4dc933a0bd034b32c9979b48e2ca966c6a6cbceb82ffc, + 0x974bb70523301360dc181faffa4a31da9c89a158d446cf9f1d0dd078d681a5e, + 0x6231c17adcde68b2df5512d5137e4207b5ab127b989e551710a7cc87562fe8f, + 0x2694daf5d67e6751c38511d595f6ab520ca299dc52eea4783a1c6fbaf85e843a, + 0x2eb55960ecababf455a49b9ea9db9801a47ff818217381b791b546b262df5836, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x2e375ca4dd0623584c0be2078652c7e0f1999eaf84f80e86f6161d129ce76f8, + 0x206f7162f5d7700b7cce6981f0748ba08695dcfa544eb1a903207220febabc67, + 0x176a8b69b12a5a3269ee7ef982044b9895baaeb85938900d7ef35a89f93b879c, + 0xc58b1d3319260e528cc712e2f2a6c606d711cca0b2856a30f2ebbe57d5fc733, + 0x19b13e16ddad7823e970721ebfc7e4a7c6563a7e3d92de2135873e0e60e750a, + 0xa4e8fd444448adda180b0c6a3ffd32026f0644911a7f4ff85797d7e834fb383, + 0x18be2ac266e3d98839e5efaf7ef5f17abdfd6b6fc729e1f18d834e9a383bab83, + 0xc56583074bd6c3a67fddc94f840cf7b97b35256e00a647bdd7f992e731eb61e, + 0x28ab1c80f8d8221dccd8818785b995aaff05e17d4fd8f55664b3729715f67715, + 0xb886b2ff06d6d3db570b2060a95b75e3a085d74c6ed9dd8c4f96065ab77c5b0, + 0x841d7473d45e77983a689c8bf384015f323838d32fe65cb9991784db323e25d, + 0x1c1ee3b1346ad2c298b7ae7d837d8cf98af1cfb7a2af5e1d06f0c9a826ab1bc8, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x11e7a68f1defb47369a757ad1d47eac4fd12ec54eaa4c2f3a84e2b97e56697f6, + 0x2386b42cc098f278197163ea21b9f6758c7bf1e8a97fc99d0d48b329c908698b, + 0x2d1e8f11167a3889b194c794e8566bb92d1c622807fc519445bb09a92c10d11b, + 0x1e998707bd13625c95c9599bae3261e67f2d517f78805aa50356b8a5e6792427, + 0x1c6b72fa7c47168bc0c13b70af218b5f37ed9977f1903c64c6b0317cd1b5f738, + 0x2f50f79c2c896a12658ba1449023f04c4dba2c68e327ee5796e83b6cc7bc7218, + 0x4b15dbc180b8634691f763a02187916b21f6a9b230302cdb226c9c20b1f56bf, + 0x23c08c77cc0ed597c537ad1232524e7f9cde922aa3b9acb7a8e0eecb3f09dca3, + 0x246b55cb9b404e710f5430129208fd2f7d1c3b71b8d5d1a3c954ca326fd3e7e0, + 0x2a3c7dcb7f8fa6097e5c00f781f27f884c76c6b7ae85bd0a71ce537fd50388d8, + 0x268e6eb795786ecaaf037752d214a2422ead74f48d800ed7f14f4b174c53f76d, + 0x5ac3952618af339466cb8428c30acfd937e76257609d299f1346d72f87ed82c, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x1b2b7aacc25b941e4a03f085a09a773154f908b9e5c2d20d3f67779ca448896, + 0x22cdca81e323db126eedc2d331697df5f2157d052ec4f66e69c17307bdd15692, + 0x267f9661ee6cfaed2fd4e4c8140c3e168d16232fb26a3c2a2517b6a4899dc512, + 0x10ce863d93a47aa85b421e17c96dd0b05510418e41c576b331770a10bd4d0baa, + 0xe26a35e642d56208bc813191e7980bc9b8cf0044ca564b4ff7d92f4a0410942, + 0x230f6e95f170836c89332e68f4522dc26f56be6fb7079958cb175770aac34fe8, + 0x1838b36fd6f0d488d9d7029a50a8520511aea9750ba69c8a7f08c711ac5f9ca9, + 0x4f19bf00ae88b7c9ea78742fff7593867760fad46d653ea407726b452cdc403, + 0x133619fd5268a1c03b2486e0a7a1ab4e8b83eb2540c2b9f02159c3e487d19602, + 0xd6268401cc2509a633dce917407f9a1b569c6f9e56063022183e4be7651a006, + 0x365d7940e1c53edea08251eef9a5529c9337a408926ce27f35d56389f2d0d63, + 0x125f88039ff7e0df7f265d09018809058d3e38c77907985c4c87c75d8a76f515, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0xfa21fe3e0314d2e7486a95e6feef8d81fd5fd1b6e34a456054787fd85453e68, + 0x2951984c7afbd03db22245a37d1df055eb109e4ac7344127f2c35dcfbed8e73b, + 0x156bf5310e6b76a3cc65f74c58593ff14ab052dd9d0fc09abeeb4a95fdf0de19, + 0x774fe420c3ab105f6dfbb8eb0cc6ed4f5a13299cbcbfa9a6e20d01ca5f834eb, + 0x13a7f1f4fa81d9e5e24d6236110fd39528fd3c216f0dc86a0c79b2c438470649, + 0x1019d2e8646ed7feedcfc77169f5e9fc2dd718dace5f6f8b9a67637d933a3041, + 0xc63653fc5eef7c50cde7d0c3856f90e2b0e0fcc9c5b16fcddd1e9740faf9b00, + 0x1343f7e28ede90c999f7312542d0fc39d1bc0d3c656440b6e170a6f3bc35b0f5, + 0x1bccca2bd0880591b20d5501ca0e4134c926c5d0d97bc70da24c4c70dcc61702, + 0x227006078f001421d3488f1bec3e70a69d8a51480ee878cfcfa26a8caafe9adb, + 0x2badd9b9334957d41b28808cceebe3e3c55807bbf4e7d1997d8b7a71121704b6, + 0x15fca0d19035e164f8fecb36822f26b07efe12ffb2d831c48e5ea9cc8258b755, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x2316c328984e3a8d25f2a26fa5c8d29f762f70b66fd648c7df1248c6edebcdd8, + 0x14f86a4483471960a505e400b9adb874961582c40ad4f306ee61ca15f769db60, + 0x22448cc6b58101c266b94849c276c0b469f440cc5699098228fe293a3e15613a, + 0x9e98ce02891c97faf65620ce63a9279fc5c0ac4b7ad0073a03b8ae8951620ab, + 0x3d80d14e85f09ebe6840f5ac4f467568686cfc56acef42550d8d8c33677bf3a, + 0x3d857a698a64801730b3c11467d17cb8568fdb626cbdcd5a5586912e558c022, + 0x1793c7b3f75f911d0c7f4c64b74e7a1d344a52438774d42922a245fd55cf10e6, + 0xeefda98fc56b0b2f2467ab429a8e513b5d4ffca2b9355de8b8ef645b14732a6, + 0xb7efc4302f68263ac68294dc896062831725e4bdb1d2a6e8da2572aa4ff8471, + 0x2c4b370a050627bca60b267ee3154f0706975b6cd9df0fb5be76162dccd293c2, + 0x14b35f50c4e9103a3452cdc68fd4db02677bfe9dcc9d7619ef62197878176588, + 0x2e598155fa34aca3ecb0e66e290d99b9aa080539f461e9734bbace8c72bf2c60, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x2f83ce87bde779865b4ccc5eff39d9bd2e8bd0ecc9c2cdea49ec7472976d923d, + 0x933a19319eea25c52f096207f6d8a2ea91fa531291fcf80436ae6ebb2ada32e, + 0x263439a31e513a82bd9fc8ce9e074df4e27e59683382019b7679cabe55618338, + 0x1584ecbb64a4db8dd2d5c4608ed26bda0e0c38c1130b28cc6c1b4308dcf40e44, + 0x49e790446ad72623caef9bc50395299d0221c2781686a04415190f52b5143a3, + 0x10b37775f18ed958dc5dae40b445b28b2c4413b5ffd672491334bc73470274b0, + 0x24701d4ce3d32060677e07f1267d9f7e55d4332b56379700ccf64ee9d57d1e11, + 0x202b8fb221cdec4a092a035d4e454528eaf0b319d671e60a063f4c0724cd8c15, + 0x1d43768bfae552891485d63ce8e1c3eed865af9e608b31a925f4a31a98675866, + 0x32b94736117256d76b6f85a01f3aff1e4d954eaabc9a367b61ca0d8bbd42c37, + 0x3231b4434df84936a826b7667aa33f161a86607219730bd78142eba4bea0dd4, + 0xf45de5ea90165e3da111af4a7775204d4ac83dbabe4eac41abf318487b1e996, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x2ca2db65ad224b51a8b24e8042cdb875693897fd5503bc751d888f695d9607ec, + 0x44928f5528543c7f450eba9d4cb5db7e58b8081b98c7f752162303a16af1ed3, + 0x2733260b5780a3db7cb63e4fc82386491a217d4312c7a93e54707894e3b20da3, + 0x24f726fb193e627cb10dee649b4e3e2242b94a2524974242835db3e96befff11, + 0x1e38f6d8f6306aeade802545000b3da45ab90c9bfd2405dbc765d184b91df08, + 0x8ad1a8e37ea4e152a07cd69de6b60e41de49ad1047fad9194aa32849052b8e5, + 0x235d4b4258dc982dad9cb9a47a963088a59fae5f730093f1e9ce387abe83765c, + 0x2b01da9199fa4220f95e00c98cac996d65113f5af19912cb331c53f9c52334fb, + 0x1eda45b7f8edf24cacd398e7444437e30670bbde613facb9f1e4676b0d3f3d32, + 0x119f815c307628877d5e222bbbbfec68834f7b1338bfa7688adaf8c6e8c132a8, + 0x5f96bf0532d7b9065530d4777fa98b0410e5566b6b048b85cae029cb0e497e7, + 0x340a6c3788a26e7492b9d20754d96aa10ec846f07aed7cca49f234d45988d63, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x2515fb66f81792d13ff8bbdd5c038ae895a028fd5527645f96496ac910d44e03, + 0x18dee821d0ad52dd6641fa0289b4ca755a70a603c6bfa5bd491ec55ba7af13e2, + 0x3015c688b294a9657c6ca12c65b33865b1b79556838bbe3f4bc1af83c1e1cc8d, + 0x14fd24e81aa0eed88a08b4ca95c08addbe4ee861d173dce5289aa6897d828128, + 0x19d02cb7110cd61dc1991b925320208985e0f64fa145d3017537470c77813deb, + 0x496cc3972bd13c9f0dd2715a9cc66b770699b0832a8248334ff5d213c5a7b12, + 0x528b341e3531d9d48b0a65c5d6316d2fd21cd8801adfbf0050e0cf6f0f74553, + 0x388cd95cf4d04968d3443ceadc7fa242abaf4eca59961cf3c850efb1319a4de, + 0x1e6588c7ee49bb4547504a62550304ed4d3e5affa5ac8f08b8c0cd0eec44dd46, + 0x23d611ae14db5a2638609c8212d29f327ce0956038039f270efe1a10537363fb, + 0x2b86d928a54b3f7c987dcf5ae89d7de994331f200381dd09d12ecb846a7a9b12, + 0x13055b796975dbbe1e5a913a59c11ae296ab60bbe64202c15d4d6108d086f462, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x14f38d1ffa510f2b0332476733f9fc5c79df981b55acea4a8f0e3b4cc61dd759, + 0x1f312d4d6d9a3ca368e3dc8912bab32366d7204bd0fbdd3ebc577d3f26bc407c, + 0xd0f712e8570585e196ca13e8b1f1a2c963063f27d62427af9eaf6aad438e723, + 0x2dcbc4e8492001dd99dd80175771d5bdbb308436faa08e39f19b4dc21828c131, + 0xbbfd5086b33a2f0e5afd9be44f7ee3267d62833ae3019938c440d756a24588a, + 0x2e11c7002202decd43434c9730452b8ecfb543cd892429fc88db33c63c404387, + 0xa04ca0b4eb3a67bf9f7b699b179d0339883792d4bf4800802aea15318b7c0d0, + 0x19004be334dd838c3cfec0528bfb1f91db2d10d7d3d3454a5cf35b7f431d9f99, + 0xf0db552b704894427ab3ada1a9eb881506e592325b73d7ca4bd04002efbc259, + 0x1a1e713b1af5f35ab4fa7f9bfa19b0980ee21821afd1ab3445352cf784b8d27f, + 0x179f8e92246a7a24d55045b43b515200227c4be9e0087db3654a34db445d89f0, + 0xdf566626948128c150102e68c71e6cc60d52112b96993a1d15c43f2aa2d0d5f, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x242d3b170212915d835e974b8f24c64c866611832cdf59aea0f9e9269dd8f615, + 0x780ab3cb7bf3cfe1cb4fd742ef1dea1daf725d4505f481c9089f9a6a1aadb10, + 0x224f1cd253223cd87977be41be77930bf651ac744d3b362b302fa36ed0f6c37f, + 0x4637e287df2d94786d07580a457013d8d54a6c31418d3f3ed4cfc582ef57154, + 0x2d703aad67bdcfc9855e65f429a8120ea93da66d877ebeca1ac3b1538f2dd96f, + 0x11c9e9aec8fb7bdabbf3696cdd441207e1749e0d8fdfb21535ef940f68e904e7, + 0x2be2aaa990f638dcd8bed18d9b76465b1f326abcde1ac1f3bb907b34c6029c27, + 0x16a6ff3478e400876366dcf2c41671f4ca6cae21bc985f0493b4cea2948e83fa, + 0x2d5c1ad3358720b486ff21f6ec096377f8564a544f54db36e9fcb540933022f5, + 0x2706883c34903b26fc209d59a13cf12ea7513995f226c80e6eb8fb69ae20bc67, + 0x1c0cfdb4290fbc3c53be1bed2a7e271ed1ba5aa5f372adf67132a8e53d2cda28, + 0x5d00b6e4b2d0a2d0067e0d1ad30789c2dae657135d627485a6e782c8b9ced92, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0xacd1175f3984a9e7cf08bbf5c1777cea1e7256defb95b191ad3d868d8092534, + 0xabffa5e8d3f345572069d11f25ad4e654e8006102f8d4759188a07201b43b95, + 0x3c0a0138dacff601c9d0631e83b8970db14ca395f83cc18c7a64db35eb6328f, + 0x26cca174ba7d6ee3fcecd1e16f868bcd4228785252b2b7de96fefea71306d5d9, + 0x15461d04466499fa137c5246d7c65ef254e24fcd50b5d43ec9d5e012f89a4840, + 0xba61686f2ac1ccae7946a24316c258848a86659591468507870c9983c272759, + 0x4017df4afcb1ba3116385bf4630e9cff49539b1ccebc1f4942b5f43ce3711d9, + 0x1424d70cbb9da7aba0be6bfe60c6ed4310efdb6c0a7389ec0c17d4a6e390ef53, + 0x1b4adfeb3a81ffc9088ab0cc532061a6d3e88830178f3771dcf7a02534532e8f, + 0xa12244e29cbbc56d28f49bad8f18c3bcdbe95681a7b84889c1b8f356db69c17, + 0x1d2798cf1798c27d89de5f07a9da5e45553ae27737020e51d7f6d365bad0491e, + 0x99921cc276f9a00e458f09183b359359740bcd453f652fc0e6f6c9a173ee5a1, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x1ff1617e14011200242d96c976a9b73585ccc1103145cf23d1e2b922d03d5d6a, + 0x2c20a2a5dc3bf0aab0b87093f9c0e9ae5118db1173adf4f5117b33763bec7b68, + 0x1a5f9d44d0d30cae600f5592492ec4d112e9c0a24631d4b49f6e14ce69836859, + 0x2506549fb4f1fdb290bc61f697719b418f146af1cf8d61da1632e293230e302f, + 0x19761a80b065bb3820ea466dba6f358637f3a298d986e9a5024a8701149ec0b0, + 0x23f6ba2cafacff6a627f60f1ce6dc5b30a4caf64f4fb21c226d4c2d847b841c0, + 0x2e6f1caa062248065f02aad7120cf91d3a9c29ff5680cd4638144d7f2ca95e97, + 0x28b3b74cb98af781b0f5344c7d8526ab317280697e26d8503eff674cee5759a1, + 0x271858d8121deee03fc457245a298384b9a55b3a8359a7190ce8bd23de50eb84, + 0x2dd5829605b8e77bd72dc4ba2a12eb8a9aec46c1d253e3a8dafbceaff52cfe03, + 0x2d30204a0bede236a8b41721ec0376629eb558f6bce9a69e6a93a89af0a637f, + 0x2a6e862532fc598b61ed8c490ace702e5e92ef403111f4a9888e71f058b9883a, + 0x2abd9e16b7b48289aa19cdfec726fa3fa15cc1625102ae511bca45f39d337e9d, + 0x8496e866a25167f5c61f388550c49bf6639d6394274cc49d136a8ea4aef8f04, + 0x14e8da7feefe3d716eb940bedfcb7a3f6cff1ef49e459c3d1d0df8d9a403e1de, + 0xdbbd1d73459a395ddb33c120018d9692897578dfb67ad660d628e3a46cd398a, + 0x1342655df63fac44d438d6f4a1b1288e693cc3b530cd73b3eeb588e8f2236cb9, + 0x31a141b9e2cb72dbaa792b5b29c8a7c748c5cb4f1cd6f5c0568861265504f6c, + 0x28f97968428b8a94432861d7fd12313a084d3c7514886fa6ed30521e588088b0, + 0x1fe9feb5c7f7c7a426bff032cd6a3158278b6c6b2cc57a871213fcafd6427989, + 0xcdb2db9e4f9d732d217c5e3114821165d49e5a2d41556bcd53d0c4d433224c, + 0x9664216ca565c1a44fc2b98347ea8b36904b3877f2159dcc999895adeb4d70b, + 0x1463f51d4a4cb1eba16dbc115566aa48fe77b43c244c9988a3c658d2f56493d6, + 0x214e41788bd2b990347c7f2a8f47612d4dfceb1a1e6da38165873df66ce51f59, + 0x548541724f64e20128260899abe8fbcdff184a1957a9385fb715923bf0fc79d + ] ) } + // noir-fmt:ignore -pub fn x5_8_config() -> PoseidonConfig<576, 64> { +pub fn x5_8_config() -> PoseidonConfig<8, 128, 960> { config( 8, 8, 64, alpha(), - [8243355230504186170667337521705529968548180153769821936979698914169521362326,21549235422807751640146583237936799392598740234259041629069949854834009192195,15309683586299089746803554818142261058154570215179112411063662706557055610156,12007539402495575255755232938576927941514879725482443887151392201585760698040,18793669376013417649313139054009540629720623019893420956495818743913188610515,6637074549079529416739232814950531409613090469922787253991308038219905474403,3042007484821627445120830225760006405192082634864137749621636257026891883326,5337388510268581167254715112479133594089770138749507073603490761032513368106,12325446798142239188409242319577957593792614990556679862642230477712636037037,676789245562467194073706116744095779362669155912771165373940448756070927910,5854747984773506278911353281567883752585612596682487681686710970786834920041,11245406467967785626327694659468342056789182160059009120973665143197638081760,10395601815816075071544509552592627172226369015806880764151195346316980080894,6756096862783612163697577917108261850810460757753491809406999449771712474223,1708595072322964393019739105130946639405776432058599259998973103484499438306,2817817145890818701877539103826217929456570347854153048034669346981432211659,20337270972708498869284875601749656006552838338471813066271573323209168221011,19192338172842323468707146045612196807750411464817516820711948717057036544820,17223253657227310295312621282100531845543865578630870272599545474783775759681,15004735209586276209064505708625280228119288986650187909395010184201059452346,3875652974956649356154345677088455126258183810851242537013757276075769588050,10514447960615206081458524578173743817818597124482828867666984705327684376752,2087647010835075851760610474040959236825470174942075295716631067964093542910,5927163251920754154392384551305623830535034440727310604898855074616515892551,20585333621997037505291454298836355589763292536744926081563336065939121006537,19320876518201905459682928158170419256739531666800973485138890064423348282196,15942638804716709831210239594904570403189415026144938623559274984027906868220,11197022744936474661934096628367688581641778841814728682794507017845346201383,11034020922250561671038205476395109731446686553549026383358725302157324264144,7574933006942933995255906769787776608010920618615581322603847524789684181970,10061361506744906780155460423367413099657465765582917482575074226383566926764,18611343221859570540963418999548488653944851224739716224660835306206658947980,17094203924957299390365889251598099482992645049968199405515681968938743421467,9407145832890449495071969940777105644547801064593141904558463573167881762713,10921438560879150587765515492087524756046482460218342400194862909363870270743,15101279960899220452674629307354995123411280418550386595937683027146194547144,1872357133681596467751878560069114718371273548294363719900935160833598069645,15505500304018853111989216259257978796595506623204851206292254759641600763191,2079667978353221447444850850900204451820443725835104896018664141845782871343,2852655320672908960411014862634757863509253400797831983637863741066632490909,2702824031197306101989338159138451445088523866133498139857862801497066633794,14553308731276493692643101846551382187575566516925133957384350697980935154102,4314969815396483242407853639218064117498232660761075778657880116870422414637,20236724297078811959918602376319440958076910292454596856154100774072250182183,6360017115980704736383763605019264589498600998515606807745670287390050560160,20856970531105411628054833058646203890148287930330473527735908484791842390307,17691356258507144960616314395885779533907781694329041597441621553108536658757,4464167934150673174817562382299722091160711333547138388803048452674668158635,11538922347277268848344412167140306567742076984016453903533772667841006045703,15558861252260038101730449864896864763293561339637017072015859069059083288561,931980552683520059135814229579184511049009637966018180567726214946979768011,12746506550979326220422215987591117730943427023997792332255149062957909690818,16416138987000536018990311324687201169959549714116951891693452597169869821726,7473835750915837381583185047008243788613524206396316652305987269933344653773,21223994082372071324452834147900730753626104062167370333103771844983134656961,11102363694946721470818933128034696027504133564649607436252022322296041603786,2666835000155694643357391634256423691785613060199379949509682292216642706081,16883033667413528795407641102416904598130659502290474063092941543309042023190,13093053604456598783294628038129487761924241298889312497497820946915331319389,7426349812936697309541457521193139970366533826612714195359894150484429907425,5243217285990182677741567384304278362485372018078770234262925321063263504918,21185490040917275396474067542756068684704036418473170810170344320388557093876,16181135763579884029508432324330748636846464150219757303321560798898398598349,18088358880437096005757355821526785623101357556483672471222924931365890201571,20418860027198053484245336569800730261127301261293595190270103940460998981236,2058948081811170389115771489993053947061173620273801887242248130631460165879,6353796008567532863300373986154930294334380098977007704532496889557690195858,15854609649070278722833415779491666201355987522519101725393408435189057056690,1355942327518086746604287131396672941922424788908995789539897301592998007690,10194046920666955610804398522181498854525794643476895032285888778350918459761,18342608728256650520630397534564293474806178807929639999068140223470256007117,16101948218093381908101491223075947943147313203969904451859930796280152622017,9866645853452683082481412876547916795343134459981103407915522925093474319332,9309485422719740772955698359258466728180120624442685713365406080485336040166,5201701081505060757054562398073722930344229781365241858092054974705598137660,5279555243870694216927790669819597822350327573071817682265773244733785382064,10661662716572743893824841881707597899963881485303936548294117975770384660590,4306964326426793675768869124893413588264762573088622132302954501394542576141,19945975928045383298785833694292459276727208605892865429301546022994613804030,5037834331249812829239656466783521330249138768989720606017856991559732121456,20693877087308232030611148201802513236570270737947270986743265610517665094074,17748932969923719316564673051784340920943155490113289807023660243301385585070,16950307665556055391386715682532553772527550247031548278958142572490582126842,15034211391483347494286112687349366897258989065045859280146461213731663274520,3455096385235320554100221104677124747996171720170690637998043454239897385610,11220329458242704347549150795173830262585759464331372299692251819012138352257,8230076319752658879891285909687940775399748755759819661970430769188439691274,4178690445391578185009939705412120505162313641744671740163024993195883735198,18632680236376151061913536149173846032710756800956417249233907621575802688710,14168747730472612819827430620596085566004981811676505988180237018638188025380,16777617016129912124437138351698263064579177499617525409625791377061066895460,403267570119386144603206457308168792379980670187570608148634410971295877610,11045890302538505532103216886575539246473207034538532950483165910580782953337,2632893274667647784827087132221744991131294771819888858265016332574437797556,14022461303364013571172470728150898521630042996798160127819093871974124417229,18349129573612583311962846403448135938849737390546876598640066736462315682295,8009723611300112743690923532773238474616291315457276539919568488041436720507,3287586297388209299132232426281031982329712892122181769502106059441842217623,19893256464101780566218598404932657965361824655069879954668551189408491121155,21779954643920608321663779655887581582907923850271820082121309309571440586162,13938145028737822338330333388496944993576078307754676998341398757402576278690,17280605833933949866452995551396279974325968699794264573823990818913515933775,11562775307500290654949270847967546133812416593099094805234457839659652146289,21556021192476590536800970202944195471695121915357500612310904064652863447972,17407055226077297021071802288772735837293135175537846248261973015744713174949,21295838064085671525042198277220548723525913660103018392096215316189390548013,14589917958236435754986191512564058641868109230240077937707647376289105324812,4538073055458854134606640263494592220617270326115451287834630189270577020111,21247609438242282269742265796811514090579388884916478939008977411932487423659,19263560475610984724826226948356735903574936974192558145730920786586162783055,1898614508331499418660051276594019416852890004788354240344418815409520758722,13346547977920686435662774643991891597826323722140876186086635239306340843003,12144969177194297999321084025481801838621405926243412487948189180755523714531,11624156909934489978766768065107924627236090741698411458481638802308500352917,8674349037900011131899280296161700067911742760618648557038290076406601619864,18627233188669469962636721109716646416813512041955577645627776298400086440228,1153719160094308748956884656041023320488424966635003188538565876464091909764,8000003066081501211900754070779689975656073731442793160620896624291841806771,12069801117560082050163959286673266840809976769131514316118288648293224324822,11694828863372498882861202648883355759680038037706633938668096525787115759720,1181495201505177954430275085371953511604847831716865494220845031383860562941,18321980275956746302814628602546438645691886543647725888694024551609678639266,2785661975937033521551267460848061931764727388015171856456622007438303671899,15557886094116287182932984983441793820379366058597052543066101158081817575352,175179830261452669822497364983291141568331314582563701393865403724263011876,10455128373814266139918350629083299308526836847946708764631040462916637941146,12622681406523708498691044494295298210175441851465578469593208754136900020434,9624138424345877000077746656879336097173254842107184716328214933320809030543,11726383465426411877912203592949370178096897707629953853811352568008881233112,17566146584557385507728086844334319515338136183689530813551207417981719751958,18423839150858891406289385710861955437811779173242111498197433255650436048047,17408376662161624435555256564084894291578222902661202310977717110546842356960,20995943422377609225953642092578140203148330329113983394181012996247925741957,10409490873284794620245703460832015892256721643100501421596423100640512505920,15047062105747285153444463303020356100177963702386173227676803770571846532695,4535940688608096040988822900684697329863791065464226849059470519882399535780,18980357680792173392910397806033731294240363676914829395702138582894418363978,16468042735091009392571235146440392007609078458297170996132218787642722263238,1869769403621899262774247370472546961521039203681166934356431996537822108263,6151829532330885020831674048300360431343535966534922988242884341920915237665,14373964388615044752046531046884609884388869283450342961030080770253954449754,21429869771065858399481388829822721985084474326196139156050788103070270663923,11836916222341149344359827526882466618136359738495035945807998286429671739008,4542193081188277792793758113018430324598765345700596639963408884670534634317,17262340128494663310404052919129368521415818617921877469042393034218456907650,11614110585474201606235056157412783071151951301104822431509283035322273244217,17241248261774133453753660970137875514052923171943595080766050681996607133130,2990875140768570679733810173464987023133165559726680992079139149034178002777,10032389096385585741539206260012253444831624820404318451026478423856181568200,8391217416130739565515338215591963109158836617019021044489286448654465296819,8553700889274799411012667201578367398970695661169430162294018618925895640041,13529692770771168133213371031275281478756443444824139121847596546264553079152,14478949636372928879378459122088894160202116364833386541382488835123981766413,18528743543311452855194545818079449921167163839226390851954136986727320245809,11724222260540829258562889360923785293478512718704276634048783603461995522859,2652532822068043785753514309321715043229885635900630208154874285707479247265,16473666207635815797882774885364997250503755116232911726426811919269547851975,12436631741803099512327160776479880302093882812091908650798222524569929954222,13061081443094122428989571162147084312340276850316867585582410062467362267361,20909566607465067204267258789556187669343825005173558971220332255443231196363,14278016202378252898173761523743422243750790190417896338147106476354187349947,7703701752136585609667768350038563449121231460368808945757767724712186009894,1622258312841010773225479468430896972269503924285598181547410615000034107894,4706114868510775588142857635375822293570353199661120256611528287780303504954,12723022498690150801900112713057006417552064300221766812928489357200260312668,7736508633931646965699972944684083339925061856252811104228904321699984469949,195095354858363944780141950724441876473553677166595890451203685104276178612,18877614091447727762374351623731936445361116363480970639310200637662433378180,17239262588506530491210045452642505719938421789517734104955853192075731537629,3391556611912995522919492308422471958888145521362922265487749943660431330300,10164629656754294522862462407441648133619259920942013682702008716587122474446,11939828733425435518898229234599966533928666730047925120030711579782543312731,17335155958861138542643885799966192412363788951639890938680530110842555336617,21068414996957890621467676209673805582866493104159841584377567318112060433438,18041291613104743972430309067462668732698702146146761776321539150844598296986,6149130772490689572076747194977244577047643214871016443290724757756394340290,12105848363324940274456322072887282559016226587661485273111872063034847034485,5683957548001811989600472365740829603387405501208071642225953069881259762607,16529542077365261070047716411124689196456625611983373158922227651721798753876,11961524596519782767188645738887896272947446382672325012202336646508449392990,9785728068011868312995387469680578201705397880590293454099364001157116688561,18127416268588083447440821307938591826251677223119815897950307944959875167560,19296461637807972438220899702591874518336722552660488565818484435311224286288,6801016831512114134395242293457679538495311188529990156831889204433183626116,2964298470426582070507861407971247200639242211740381994158541687335361446525,13485975887078791259342768620261671076376983307468484850600890777864999230190,18842264035089067687391583729082424222425351385494040849910540441253540345719,14703642210510851071131854548671393020078600676544458548174965732036621712435,21220214849253889952179905879367949668848598115028365535238742829171770487419,11808561815315084933226034934054773302447242219261466208644893422841430468026,13540888692913543742580940929469376532537583430034252053023468103862294761259,7244161097354558003276348625436123965060461415149286453943040900234287411785,14838699086047571226987010390426316539929576717533827724866261274778253262656,14556703155521968503536618488028548581329555701042498979115582733446728182407,7681623302896593715513288894378158777679657507901023568046253058158573848701,1088441387469941348668229287331864702951247349577784177659963097331109780661,7314603916265509104428110912296267885635061026393352039011815022900719549691,3986211915826218802854255636104488183733664187834078111248006041750140814882,7773946401984571616670752866609685859292708427659817737120107917606152933392,2842014599902358831415178364343115068084073955515903534808862171830738904933,5310724334723991338015239276468023426385678184604207589409781216959654582406,5255222348968955358505450804240823699077014235887887249383824524518164498567,4683270496545943333741165516340250527555279356319043788098737100323469078711,1419863943011284607504318632953959861647793372073243840131919334395882404459,7983638904317557271319561780754076927110887040374328063199742162092282580125,5569432847705373609838086039153225563020182698189928344759413994203981320990,15459233133041758499623402905899885787129812358908703405750502906067055055230,13557004098047782158753673078158469379829777184696159361573537670440394932233,15455882302725774286899673141535924396516348007554186719344822187820635072053,3420919058826876625284567898132572990967515410265578892047210512917031439632,20100418454140979684745740106982178755085746706837715848777042819378494283102,2569258507332519764813672456351707773863376375715947817185409500202699032309,11051426796304102496144764766958179671506736496976882366028801902480842422589,12740229748287653735988491742372785228070141556372656548689214318469788908817,21628842595664718258888324339774974922449098458375293925060310284267692457557,16339231976272978519029290439531768093693541721039081313180796119705575069472,40124736742096746520902512885311967045111742860721554225254094895613700655,17732965892472841235257958105891466451086090480423956940377743815006013439,21822629194074446176794925064792912534191501981075390813302606875002422233533,9308214945046921143097017249780654286051601646816113552080893008307002107495,1407926751839535775233537792971129618756456590720440342541085713782189375466,5640645423977029900985251540406734874840031539109774937559862819450972865688,5033216407501194252797695593441325021622991729008118693554186469034086370061,8067057037475400447259522316648004416684453970851364075976857314405950145375,3763719773038467529952189678629891209905984306908045328296798459182240539135,16939797418368521863388331657892541744299855742774206972703171911218723184714,4830944198856568835319759101429165879092462296316662230100861015921313890231,12704214658232136513943612645116991664417275945120192627735782298715562058820,9273823420095008025667777982828688153052061387261780450903573585273931011552,11055274871946976331353174512200687536982312509623944578515862663278819898965,6608499500253253446996042326570359354182967780655057286059057541317584758989,20888058022129906086941050692798413401844596394165346138911969309287247738108,13297667979268130800823342819300433555314639138313483863899090834749801969571,18968104066692458124571065270953767119743779337036553042450471941512165236867,14932841303199490878640323744926137685749952622800747995690439854118498001885,6250599214474930878673138968631643032807502364864165001640712550360147900771,13872044280192246670253542029636668414586465840988190477111017540404431909403,81456119668307937036914780206985985650137679027930766352442712034886058018,8178364156193615628946078892680068624209694278864784660439209878556857933585,20847565685305938921688196081711559611104247746032524045765048360946563554616,14790603163347071870110696142274029411377352843070075577069234486581346354229,18977464663780407707262531952390299277523056655145169930121579582916387871374,16780630803676794749613238124686604459373604071531057035207376612438682381040,20186476042367781999034353334494913683828163385175556939730585228743410724033,6782638209588187356802454014110236225878206067794807253486060610876934918759,8993456778572039939715813797180666624819850516232234360679317411311388323391,19966302498904269727099815984264954717659138861990152509516897188319443441697,20169703794592063233917650314404110898564218327366603108408586484609331826027,5979829627203584558315118820578826847995466683728103070319484562170838879477,8237679343008214539352062545936737645555361114339038346011678993504862443129,12382432100828502258569798167004899872248210099869176340581848176730802349663,1568185664985590267262857882936657784210740515169196983171026814738347336756,21214766447038120613598232832812136678657988502205964335817205381807920739938,7692941991237742474520327457310452870153482370889548010226143053981890424652,13595129445265049664221406027681079958478209116108739005508499004805469917071,19188096071580221579092496028987371780642557049389322053081699235155567772173,17975673380464001374676034638564230054429981676012676440863525293845130019904,20841685157342026757711329464299804445471940020955209397956987009823404283299,7510778644672212989684926383821874729073504800968951172295535413714975603558,5412964648109092367425127656145675316528154462488440576988541278054587052058,6998001450950528857399821530729656471745472711969582871968416561472553420135,10017795190513370580285083759517584035694996563220913850722002288744022757377,12113185651597474067026664715619946415749981707739597619454641751791169267554,20451540737363571466111039734160615184627155382583098695879349204357410296631,729116950403569953818905038668361626861855541652418271170712441039707291924,6874571610670154627346562968411422088198077609945741147515101915358108207688,20307824547105117373454598908217917152093200208838326389260620574762152675045,8758875530447210792904496135011086289851932865540018278850670496425499052683,13224694410602002105805224454797207933944742532123981533211431845662395381395,6621493224766717216701548708726891168784911176896760330321592836065310482866,13937858022779991611039558948054774910543950212969141252259896915615778617893,4917806030251482092362529677296731621677399228082641707762616055246746126061,16304922224312728276104330461175394847795848175925462853738047204383447573035,16678452722472429203861326329044632626530032631343862086351886162579978046420,9974691111613144697061424119079539196535411918411684404824080439336446439564,12391128852318795781829794456501239823062804741032268163807689059014957151322,16376931186038869228971542812469753097050036606517944132293138523631153279825,3057841358487505418761470758562979965285993261118087156094367416201750095404,15045409518037090814105826994439679855639635253710791541219370329682069820225,13442376736433669968016223589180307683361433436806777011753497283272674012644,18917174176736242961299708438032963296686220808211170958894252981698475343631,11380920704380401611525239094209208940853859054744619020167150893676619275400,5399632748693319676480270098239871368958944610827825094400876104909425716392,3072779406768337118240884091792704214322792415195488652476136252175179362880,8351873470285292321562674159922105545256148886389216816367528787141186556758,19039526722628732399365091326361517675801947890934047817293511021151913744591,11316453563295765895775061205389385485172841919365628835333993250531664655988,7850755275953939062184858524678116551304016605992491147837939252676680785208,189663666172994057560830062107872734380479327839628938168402275701561917176,8944554955574110171273295960753608410178793391130829960067372967633462961614,7116498249918759493875054905542634690892118438594298685578805598675410965669,2535963611074434631003149876163530430931993688129878286594756194015465278460,18022460558081751594574692271414706303627866472796139479944146908393139741182,15341193598946540230880135952221211503846552166425406354080863978843527894671,2942431717153385426545606490874257811230086292797817271859433296359160259239,3009774438756820489964746831334449123894740822794580986556997529296717581423,9496138301121689616049759054935646143502980987880350156990306735995260671175,4076156724842725224174300000468119057699244699381290980710548119313376968129,20301500572584246879220468905731058339249778940966192891128325027181404226629,12240449395531309263037726882974869058539543342019721791945417590157321444565,2734576041547526732946886809654954568832411068107541730145912482251139322538,1913611111144137178181099357504813610426696502807761974432419767623037547574,8323981703091520786969788588517080546120036429535328021157459160571413370125,17608089795804665912003122420873117027406690592641558991713120617999818930151,17954961401611739290579723858653246962839079599354059880628870682426849304674,7693642591048722104105715300765742636898670019493041402551952316778508785882,10925165536949195683545612102300879902373347522535838874708839717193999335745,16740598974035404805544189925980303793846400946043080633235004418045311113846,3028458114292500648266975052798389647613432243149006395166123161184170940972,2817600861932061603203157785548222970685465773360278995551965365313604217882,2811366666795973435332404603090484498270752802044239619104866535127344245139,6901007103297959557257110184636027233977945890205420866896244199105220459744,6811040256124961160848956238308470640308462502755753004833080999365205628787,846642049586630199735666112786431409696508103735494916428842550432654381594,13061166881718302681365231291832588791959186056326831853549555763101859584396,1581547457654855644173875819143310956457964952802128135344084991507959176621,12591698412731075291488515328885878994038884715020576113812619060374399968487,7129047166046749599109058206849766841261983329246180789653876287940952140294,17780920041966559015242418384239510699940753783778307759603993814380170147815,11411967002648206460094819913767451172535988461576286592244752756526683869398,6535147980143805768211908880661065989475773196469834562468932004056012068981,12872366293792794368642323198969017581196463071340612957009439105182673573396,3845096876544992085668616039795853840768469571100517631039776002796484609549,20386025860348257305841141103130861239832870083066852913792413739711579490278,5663975388273723452136125938377376330824298621841190787892884430812699456136,20880523335705106555101009571713688438858731841737802690910851430800496104934,8664815262171336902475127109386834836220742848950659183106085559300961747316,15212672296023611959246835252860546019670000046804751249547303425954183847429,3786255974807528210793957400325837912933369979823637013145025357556219775102,19646410587152058982763388053845872310164493339475512721275474101828150077273,14407426259630290801648546162995549804322572985407158009259933675410180400077,1275955073103101917295562169849127375209112030395179332033340866715396722452,5487750760448101899937260261898752719887276580825994742322208269609306618405,12414079753210256499611439235670285717945909010061941159696368398137523291140,18058271753030912252347026705895506604519018890772902865355002646910918153759,13935235821735626611156505080089322797654275868806802361406549798199236177528,17110498079878546324718511787669387410942622969712445909354000807236690314957,10687508266469903792000405420136150569946636272800228999781195239976105560612,1277956894120355360649091990517188151791867400124079104247693321263057601099,929982009519538400155920125117423265869657236620766216139182914925009802954,16559970949358997473575123467518158994842000800881347427572300986319432656507,863852544580033885106607226598354103099120172650200980695458006092725115354,436810575313416269983882563851323926836428928449351162094565391723605483516,6334913013691170767138698286357556285297887475783792365865857018173994149486,17785859069146472999908840832788077051672090890508101583397157534162626183973,427206014337914391283601765560115825767253196347193816620589108299037926541,15115704735938262072587983952645382098893412471333885175144579020987265065203,12017969315449748476118643575203596675122272214009056004034938899095907760206,20642434407226804845623813766397536183962927868804716012482833199686414302852,18982318327848493301474677819747807686491978396022748137991684529478469330097,2306193794828709014215315860179466106408084703631347012188232489780230095671,7060813397820173935956757571314686808083877731722252822508055423697679476893,9925864312610988474999359617458205534034473691089101964213562993662824159034,14036238569106986370932971272638702550236692459418895654245682921654874601312,9509048813859143088347263336607686057099400727479311504780670742158653486206,6842166521132564137619008158396211111980991013087076743268157882198576269675,10217353423046013950417213172971567565900229914457220187215408404202554351836,18220384419265532097596052952017594673237799959023133602933674050572298730193,17866822945198657177461453619458294532377313634196332518543246556611008452933,17694368679979949511817467967015330546905282492241200905890171992458134240678,18971922685739566979638356009544944454629162680819328093994329160719843056737,18684937612086669383439812199377945074448160740155966772829350355651237261795,9235876281667970051504588287667786944160228843888838710239865727309603061015,6187574163551283282357553100017400574873868151705871779659681332774938473442,17196369096305464930639002419417036905613312721767481044644254878990952814786,18296927216321111202881056198300973553112302777685079899199090840516364581791,4983948188027170589078739023086929105628955321978589464920358286161528573448,2276814237931645487686771259585160667452008745791625290365802841496721618760,4138273157833414032755498052453436990872835066620446328921138739885868998379,5835580830979414828575054128735121537583042482361311845838347096674448689116,20992630219061340843601881100837482710979119542034786928296223633950908472388,1118381353525339785976839119511758587763620520383755136959051018516094253090,10337002023922138844951367775712178432524190386722995225923120494344904079950,9765947418137225404722546740514250763898752374389411503005283184253024586058,15411836962046751164622748177831913963909013265942110958658714173394711125370,20722527012138131360820192152290968950993396481440050289358737370268218859591,16585853587281811014582898583977502965045639444130273779047322749735299560207,21436098743421172924014781240823435281025352300035264733201366114473419058727,14178112462860881459540462916598447735177675761773338824394753907217898488960,2590560710846804342662010467713568407285290476715663333366063002353018991264,17949223181156469858379065899254284317305309247290121304422294912030586532673,6940063127036366626640075420306454154706369567406835284901717013872681276911,13212339415583029091219180722363760875223983190396769244985733901171214077679,11143838426689049623360248250302972103117784521940658207527698432687552942591,4994693363062895106345077091869420711664571716019971952890352464184561249569,7785839099197795033948112451740381108555553042322704038905686323540025631473,15291655295654923849266753004503491258117644584862711291502217292211074445996,18223946690101945712849081159295298164630378278313069852577349403051751559726,13247893325056509281811135293440873471348664328435966021736203439379360560346,1838627965154116499570588511051176331708387980121591719463695143475045130831,21746931323535899361372833028120884537569529325326959379977185108159655128847,1569229799996373000993208676467175871896208509249271061977636872731081653113,18668959729045139805375896352501526759923123936419773886979446262254907152787,12698285530824454564359053510831159718450594302921296519937334733529589738160,5743752602883180080321224936560739109224279187008023590149271256478879997507,17615461436426765950762679333452659818080751337498512367037395397687644820677,4379963027402443949761342437016192165148025657715626365315450970388283739261,12622442863880120105122485141053297017921305018805552070109568547893924027508,16493349884995741255319414030015325273883108492981717376626952633010860098410,11501183900713163689133184470477728399861217340901493951105967658399341986313,13184464903575565740074003127437693743650101614906307232173855163739473476900,19056993236227362680720448341933549082689888775458266843506880469982452347227,1180947252747369471066257076205537751320494098262241412291924855089764608729,16229532924404554580195616835338949126663348103713418556119694233568376894947,8604714607572995451336310555882946070542334844212691610961393592348706930493,8362594100280133221998296898045505539071433915735634439526614339277300552370,16399159148365956463951582514857891684943332179297226423628752792536028483990,20791958918883897879651946680726738927333774947616022833294686415482396438838,6976099533465307077876553477341301102578695004868981952387720840685240842560,17588607896443047770053818219711270035985826074286753981361920802895326076124,12865981806811655044812914486873432317316688987331760480657262748139002813688,19080259696546964979932036247707282742365340353585423017939782931928015046575,5475353703257038456872747308072401784844227202792527428899399083236860900298,699444932025038530835460727165156424336147795146205258896894678525124927461,15695622674480818777943366659102932349783785381339274197766151422625765388038,7644428489984569999599080644830401450294253782967784792584750934960812468382,2484044190398385977417569061356693291812041338880061938702052957819048506706,8456986467797277421685766156179980502998860530369856189405630837033584471075,5054041625001826317568038929780665383894838531896986763764007995985738029810,5197336058480822437408118036219119090707158130910220019747427914262297331861,8896147437242770809876821567936215621570430903276974181159659855796295866923,20755757167342693300106178757642141909843395817794855978028122598254488316281,12495257799325917448205113238508489684392516282807104246531380538192500498286,17639970982424592615983334078785592256655637539816187733799215839326807071148,8140016957188286078776165555436655378303814378750387793587919949009492167586,17209468066776420206923060639618147772644663380208004030591040036263548572020,2619409586309117922582791327977378099828554504012201484641253637770276078843,11172679254412598275301264634812740710430873755458899712228629497147611473029,16829502099778629987235691213955928527920624415791356237580609633148661633897,592799060717298365629187138482067858694007427100574367745567028165989185342,16864381084532235865281462338072964457337415344658720676113860956416999505572,1015589663070446561434523645329239389344944669662180065723984179503017360337,9982212112174542265411457778485410853904388759147308861218634697975431894510,5412525702631618381358272227447367851318305617863423359948039591381065713581,9852930575259000100332996271562617389630146990442517175422889296173516799181,6036993105785310658467845672504384047591296265363803946714632979523201713762,1821500632172143873156399122734194851200445368324858351038486833883177057468,21556520116213603298246786137688925835788594639953568860110645708136881336676,658318860971707056155247027603536846915894897192791739866840963356575472681,602842622617647573132938965729563329852165494525296971607175031334298950242,1151063223719891516862415316972915766442753873652837551132768558136109394634,20030054542089253165409106868864476953251573918915762537158006593968012247497,14455078111822464502989472874268580626098857184523941794725425258923962713053,1699191450188970110166570608380346465689006650580298122024202987580198200132,13971136504849280501801880342723497383580392506287195375689019810750613223527,11259011415071078991947983706483998982146186263873384729739331890304233635860,17741270384736018529047001790810396141344433078911295725171243367964019815741,3617456068852846022110280599700245470402025130645759911795429861830057016581,18773989857774369564707484486703863617112883499664601804221477949481034222590,391101570414854801618801587626783162239406618115954162053108159404294160435,3752824438659815340558915518196975380567589032517034180452547083690665271869,13652227089592801810376789544861979384538590096633526007583054323554301421745,5753030785259259818058977992956569985665739253964735992489420513570911607,12794765444364718066463627091127875266371595037234762762560519184694440318642,1844165267423966444579133456200541636533189889959706801468771335509321515822,799352162562582415493264759184613437140226428304061991778193411771388762097,15915114786946818157476898276501926276831197920612814619300062353559927906953,13041871949144831370743756131359537126101784549008553888408794912277392285626,1684702427149441531010110315726002248751792272226034774456204740385384491604,10195318610969070608511028432066597876456281143783329459466964443360549551082,13714193389971576085579160116206487363436474313560046541969781285568217247624,12202470771012770210445954644081270058473831351768121852596394422757629850892,7784616613742667796197638965440313242748565680231200921682296807888993222090,18581613859576442652033888735999982405110741068271804741467526764394720805037,14828223806255884089537896775456938290494683211666564494946175120085694803958,6191868112332934762674478056112840408041237177775248347690069948259811627101,6055199518589075551800066499277675747934144570099354689629636497613775458486,20043219892592698889412649805669712950039510114250762278667968995416842502234,10591576812697540586115991527347511638405122244793393962099090930538459086772,8146910292072979142616688207315340017602882692938548874592904341871514175303,15451576003386544225828312996072681331940167554848966592330715947662789205180,21156998090948310800651324456525534600543417534335507361948830316109451323115,21421497039083336739241851024868234958744697872115637345287618993148799764131,8835309990713613011240324096693076755485475658999871502819747407829989219746,13102158958973358955423565573049580406238531533936309830903999596178966162490,19927703189662863743499379923522860979653455328626544661291243971618992342837,18417771183154820005238210056528713167003520086953806649233005148247829186154,13242250186667974182640987653516460478853973058739850129463954545512907574522,10971901023853281329361069638276077765206234747340067637718378767976633645829,20436550472837870181409690438226695091760115955076127106091878852797639823191,683842651763399941903331243661454687566310039977770092715404267515366625429,3304534668380354910105587611199035768704466410761708200478786163367382500984,14327892159763789670354328059011011973128878640806462164819794130243254129821,13712101990593648405837473744314130986494510088132644940425089514662460031793,1270386163717136732049662990020454155453019401464056820650142849751291739739,4559668312052315567004252521434018809625818725552950834596073025095274632653,10289456013947128246221059115194021747046925564818529566042034047888244657473,6981981682422059144716871555026845840161063380660424650450978975416029699739,13275723002453843398308458799872954358948259042779675411059905047590837397361,18372074965684100000331046096891533070433189717560527825752357282553296305210,6007153627662867365254986874716350833679184737288669421698890656788831322929,11557682792813633323168221751485510314542594132819842305598531070629168100143,10536598621155464430657941977974614272794233321865085717974545329727298277125,20566123440884795144385782557360498238445700080133152934423121801124172346047,5484210585392274768700243869223282957415576141086566136019633416151230114084,4675266041161206862174450141632759296562489084453522360678052892725376421684,14506966485061491552710372008504993235111668026216492386033611735228479487468,3682565950309631924420685101131217452257499881999322497664342243267291843503,16753306733039910894513530708776251948831720207834805689601646616427039909037,11892397629144764406188085785897237236955294380381710017192179450763501663923,17027229171478232498721421673139332166581061755210509139252013418924500461243,3560458480908782960366816146149753544371185355186140843210760460011482921556,2523290942811919827064721825289040221770310594770466909167316010377190569820,17586848354290518015476851435178627882600199642491204839902589087637701736514,18771893348474501482962831973790983143756587183687952333177929270650139940171,6788202157749582404834375771398928959748074435244246320016871403739257327326,11025631863450004428764861086496374449453982180198151399523240056816657483248,3256907622263919521402687344729539839835290137654795380148237049547054026004,729757374802086603625382264910105909740146180896096383332210024077887641124,19863253866253150070643618896444516678169346690564661550005769233120838139485,12468569017378925985548033310919519222810416238732327538088208928920140959143,712344748962578398623451251358410865586764243720605242158768608887082462846,8546087066371010720013920767653366050032317738437010080974697619001241722483,17144825509786899110344839698077839239721239583625175190269757913667929043953,10651563297701188942358589203989937961905153035428112097802788565849122022100,19602341346389413323180922571631527509531683866957468565049297030414658843948,9238186664745057178430953403953596421917515090260446457039212350976296818523,263640414028390180122517954487976369901122460517389747631764885875587715955,2311641918305077640172935641310996393584851078677397516017312506521775283636,12911852110192471656473443086611566556755106535388637084532737811151296554463,10436700004928765835031725654432267178079115705246966695358470216435798181674,12755555289896266917759922247555708737024386059041699214870911784508162783525,17390583422165077903045260639521919716984664232208360646931078032292219709718,7412526952366864882775200227476857681850213243362827192310877977391550357930,5016060582872027330190350728607317487069057897723717249157495640519710863591,70447200134990075406173842139872041532268968648265338736409860251327029352,1545500244158153586647380894391367444874762740407966854865957002078767363820,2082567114283705201161441383508830647153064041365131752708347264051557391980,7773933577113494097575644205473257493685202208592412633139277067190461074505,15907352821797623044340355088248954282080052141018731890243639338361458586983,2453390435048874114321626738320866552399505338711520013030652128583351121221,9182038581165182763924458518550360578443802241218652973210280653624820005202,13176557622325900598244222336641110473108400343854387783748570353220729582767,10599983241136666078578113335543683963633036808782400964809769571709020578918,1430816790456574892099931300141571059151141389317227589818258647628212654923,7207251746626434553568433426934231676780727971853793874008147862305418016123,3847365229378532841231862621068765430417579646617713430532944299440264931969,922422158589085666348657924088867593873646110588554410818179794404300446471,4298485174770134050325487753075508760849575591910135387686931072102416450479,9475141350581193757416877790061277619494551108434152557051757495614692231364,7750163624390542388958191386016094472536166330496081849246099823270737686866,14363173695671306304956071467171940429435853698217676411185837490356013810171,3402134714494071567155197273072160417049647120230862441840621369782667867977,11378968132153772980874973211734670604659991740586197794619174704886870525408,2500862781199005154907185089778932765489906994365960644306361544820582839768,21880931942133046355810983155922578513531850539420426025723154879488808270315,17850206894189265929807971665186479441938275634968267590809377452033564010382,18427883853363251276513100116480886898434829323430684895879968439179171503760,18758795974827407022563870795763356401215175366078230621502388363785425038612,15672649260544536516531393740985073476934112035694203841471047634286525005174,14497479780124030172334631091033639981498927489925809517218125709975200816290,11190855071574099336548308963044121660452976926988171712775481672446931541539,8339442292395337481335048552147626044800877206694030770577319544121541364092,2461178629683239975488518502624530284391365519847067341739449204945212652770,3972313936510404965199308344697399140590038866586718833591813109326652018667,3224811019580618549699828950033477378112059204060062023677479068506440937528,18443657715765406615721041820828109800966587434816919981514222787674698772960,666201271764511484388505793135876064418452477237751508215203932379618265382,4434899717815685275523711262432486808621984251515429736982413712108987655422,14584918585762085382434085071460369807803840154636220934254933165793423091295,15646480282455307022430957975574008173154630787861430193406352480280577045711,402840791633175231660910669665966910050981784044822648466848382615330599909,15437492296189220094817534101128968523410729375545135146260659057729649968314,13987760171743052442513877961667805977500573882586118554487715622045738218279,12589095501858681021442730872878907609617459069328956803139727387371467358051,17551064250089164193025672794811675406761638177060737129533175904585851772273,13500706213131978087516005477128059726177752268287240395927379509000435850498,7331629294073516250840302816971095420668983701195024195892939287001016568514,12949377725980318589136021850295478499564248427839661600142796482665024587971,3988955063770305621858590171391799353484164878730082586815877210936858093890,20512156157023978986265779260320491356890557397261515752540394821171756173724,11624190532749034673782735319581023504009231230729490439584417709012081446066,12473562150323140802035699452896239306300376623759190078147999182702752528013,21504777935543484323252258287484534200045631968996932563017737909760083499017,16104745906544338230790783632377375683831341202924378150021598903321494336736,8312554144734150053969625169851557776466370096299754626528722906617398229171], - [12051363189633051999486642007657476767332174247874678146882148540363198906151,6387692555402871022209406699166470377527846400909826148301704257996818597444,5501161701967897191598344153113501150221327945211106479845703139297020305204,11704372055359680530622226011526065512090721245437046184430227296826364812961,1448611482943320179763394986273491989368427112997509352702795612841455555221,11429145481524962708631235759094055797723504985787912972575745356597208940857,18021858528471759023192195347788820214752298716891162685115069036283008604659,19817577944622399780828745167469547332167999743980557486183403063955748437619,16868980302925985719076889965831700407328155411673408077166038059874616424216,14717432944340806781505761211058502775325970511884444497202848327581753493322,6273484270523289845253546319956998489830555038697388950038256377785540828355,7726043103954429233325852791166106732104332590864071922310309250010129731951,21052353119157611359715869265647287129868507410601603360127523286602350622783,14881796557136180514390287939887071460258251160875710427576954128871507002642,16341327439981153879863707938117355436152690262312411284193970279829974799334,10737675906107372302108775622264379258926415910493665638388971468924879578019,17652699767629314433191915267767147860052614073432922215674211498672835339113,7457854400138129895665591719907473144796504905294990100367501377050420942800,2136850802972823585140870808569264373787409642804109426616292140046700710743,14029467347298896610468190615212519453678316548442709087191045978401072380889,17927699952921266007590534383984238136710494507499176330493504416180410161683,1404719213830610030709583332543456268094679432456284386108188509031502237811,15774757292079018355173698870903422490868220545526384876021336136892926326596,13992040374687149195439840459922227749294794072303579532004750946306028893274,19895094843870397064274579657905921299619388074084417486420154568847155746891,943833985612967248618844364501030453998731991825395875139617731659343743483,18334641092245356682448009823797080853859186519922476229272838591594967878678,12440287044655505483131716236615633401781045711053210640202766768864619378050,19130942564098572936370308509908873069169152245172660555660369853346605570826,13687979327148217614616687417475244897906227789285703940171633508277844471062,16887921327479880141959363366262254722342925451159884082370074726344024008329,20378003125024698406589040864014894045124234695859352480989552885205935609512,9961553412530901953022991497331082655746860319830309417179972582392489275965,17755268665220780466271147660314410613992814315871705414495724015443459797439,15394131279964876131165951719955566821453162041574233072088124095626652523043,12668230348320365182085867728169435383987570924921845106243310905832768752125,14046812111383844816383347755263287603387502282980410255379630204396960343368,11590093969266595252327261214735156204516524792938909229175092594303424141199,4623517074925959322927421514289132524032863498392441375476410779446526502799,11550389531965919926150256242174358326491059727918559332939872696684299343135,408487396317981846281976563618407581852133413686169882346565860317912856432,10717757571561029382519744040791773994731123262749372629687813122941078154016,21323787615496251932181222397986048515693661833099659753170924658480548866921,20780799310067873093555276926357624414275975377319941015818682052081980020892,9948385944800296129032348634683354181546876394979291412116493575442898426065,4957033413111065858035065225611730571499258914257595411830870977545212164095,5227254936689728148737265263965107718869714128941995977191096572191110991079,3582814872786080867997255427740166393615552773099677831398251586195329933975,2136737803483410555580163900871515004623198990079556379647848364282254542316,2965752098571712086281180512370022839542603960309127077035724860894697782076,1478525086510042909660572998242949118476342047444968703549274608283885678547,3563375996604290844805064443647611841824012587505923250907062088840679700555,15461452581843517997080348781604020486994675070532901120353124746087231692278,20472517020063295821544268171575414161230806406668271887185150097779785573889,21058001005918321995459971112208002381460494177332965873048074199074929946172,15805746645980285645504697043988763170971539673993759868487715403982423015009,7141240965656437676130015766799708612940092856280620325870466265817008351948,21418010338098024788434337801477243267248314524079104488811186206038748626642,20272108634229595317682817969506273496034097230124371921628691470754475805838,16734095147399743907618148751687506877774623133599770145304816136018239803101,8439324632051181834455499457268557602816180314723268640869118054114888151316,4953900961796661020464968131122569974581908893169105485631905994366550928492,18071625983692455679240094911529791119099077429122520426399552756115503123111,19638917592063029281156873227053827678889868373299664608974791764751784473040] + [ + 0x123992df3b9daa65139ec13fbb52f7d348e134333684c1596feb0e8d8c3ad596, + 0x2fa46f5dba9909ce9984a01e2af30b550dfec978be92b49119a3959c7f623703, + 0x21d8f94d3bd98f0b63a7aacb175b2cca13b2dd8a8cf68fc36d94ae29401b2d2c, + 0x1a8c06c61046e0f8dc6a39bc57aea0d07fd7db34e68f73579da89e116af87eb8, + 0x298cd7046f58c0cab77523a58a6fdfd1401b89e7ae5eef4994442d167f7ad1d3, + 0xeac737966715df4a20b31ab693eda86a07f3e830fca475a6574d67fc5f19f63, + 0x6b9b718bb3b6d45e0cbe6d5d9a2f096a77beb056821750d072262af2a70a33e, + 0xbccdad6e8b1fdfba846a9553fc7905b3f96e435d653eec3972565e1fbbc302a, + 0x21c2dfe20dc5a72167bbabdd95a18c147f8483cb7c0e2e684a1ee4012f4bd92e, + 0x24ad6b2755a6a6ee51d92fa30df2489320e50a8ce7132504ceca30e9480079b0, + 0x67a46fc4c52c6ea102cd37b4478fdbdb5e749877ec437bcb7acbfb64e61ecca, + 0x1a2623975652d476f4b9cadc4b85219268910c7c3b2d0ae12fd47eb162257f35, + 0x25f8ce30441ce86e6b21d52ca87463cec299a3ef543220d72bc2491fdc04c4b, + 0x1acdf0b48d8a4789a9b3ac5ff8962b16e9a56c880e223668a25018657834aa5d, + 0x14d3fa7ee1cd2b8be2f42eb6f4b95bb8b1d156d77f143fae3e82bb8c5610ea77, + 0x3a224f6470a64f294fa4dd67524de58b18f70812e093c0e1c06b31d758a113f, + 0x2c822aea71402807ec21db11a089668fce2e6c2d23174de3eb69484a53148527, + 0x1305b66e890e97e11d52771a60509026baedd0e0bd5e797134259c748a289995, + 0x2b1e80bc5e3f546f4b11399e77a0784eb7c439c546e9fba26eb6c77d89c14517, + 0x1562326a8b0d5436bd7bd173d3f9e69c3be74dc79270b4fb1e8539d584eac1d1, + 0x8c9aca89b447e7468bf1ea6db080346b6a6827eff1fb81392cde7f6130910b4, + 0x138e002e8c0c597550b72acbfc9c50952175ba85c061b7e973d87d979476b54b, + 0x317ee43e6f4e38796821ad2d55844d012bfc5c2b990fa48b491ef7c6372bdc3, + 0x1b60831fc11521d122d9cdc6ff45c7005e6a166717e7aa1685cb286c9ecc992b, + 0x2e73d35eba9b43a5100de17bba5c59d871ffa2a9b522b0645e283a89259d446f, + 0x22a4d3cb7750e5f4d2f0381294578f698be7d678311595793ff6f1ee3eff2df4, + 0x2471b7a969af295b9d407634a486a1c82cc273506d89a9cd5c80a53b40e1935f, + 0x197b73e1d792a106452ac3d31fd02b5e1617f5442fe26bef5fffdb7e1497754, + 0xb2df733b3541c788362a5debf818a087bd9c9a9d39c1fcf2564ad3980bae8f8, + 0x1cc66ea285b3c09cb4653283b9c6ee66b7e7a3cae20cd50315dafe3a92113a2c, + 0x25b6152ba9ebe836c2f5679d0f891b30b96ae3e06a6132da2f6f6d212fc4b52, + 0x1a889aa16461370a4e75ea6bf7ff9405c29656295996b0b5884216311ecfd7a2, + 0x1f6faf41cf708d8307442a5194c1d38dc3e833ccc4ecdfdb8aa44c5e9fce566e, + 0x170221e35fe04da2303dea141113f7711c651dca57beb7fa3624d2881085d7d3, + 0x1f4fd254340f9509fc1ce072bf795c9abcfedd5f80ad8ebea2726be474197b1b, + 0x2bb4fa69cd631d5b418837b9155db02d5489e7feb92b2eb5a17bee8031058780, + 0x2fc737a4c1073c018432cd0f9e8bc5b75c19f94f554314251d510fc788b79d5f, + 0x299d38d16803616a9065d1820e2b8608280e8157f7e9ef5b954eb3d2beb2646e, + 0x6e8fa64f6f9e2a66650e0f002b2afa7e0c2c9ae417072c68b8f1f31b217bd67, + 0x151e2effa0eef7ae28945060179f4aafda3a50635be3b3cfd4252b5ec9c29449, + 0x13f225ff220789cf3d9547f15ff5f6bd6b057570636e25cbffae7b707d6b3a6b, + 0x75f0d5b2f3aef1e72cbe0d0b406505ec9a0c2b61f37ac0fac82b44d9fdd5f79, + 0x26f491b65ef18ffd2382c44ed506a506a375a9049e2f6fa392a837f3004c50d, + 0x26916c460b0e2d5697914d1652fbc3da25179b010a1158e546de85020742ae2, + 0x178e270b0c35c5ade3457fa5985c1295f64d458a2a25fe849c7eb5b4bfc81348, + 0x12b5fb7e1894d846ff3999b3f9105329a9cc459d5b605ed00f333da7b2130905, + 0x138f42f4f01f4b059cd6cbd6afa1aad443f29893e24313d2fd3b0e61a378cfa2, + 0xaf68a2bb5f9b6fb492356bf6a80f40730056bf1d85424614ae9703ebd20ae87, + 0x711a1f848efb7d202068d15ad1825720c2b82bb2114bc884043bc38d727f6b3, + 0xf7275b3afe158fde58367a5036fd26eadb8cd1c646afb4dea64fbf1d80e1f50, + 0x455acba2c77be3a518fc64f7977ee3c646b30b534294726ec896976d6a16529, + 0xbd261d1d46c99febb2cb1bd70ac8fbe0129528be059fce75cdba328f73d7348, + 0x2e5aeeb04dfbbf5fc35ddb3712549be8e643ea1429fa000872af2ed500152719, + 0x1c86ae64c468a452e8c1c2d5208ba6e17378cc3237380a48279889bceaacccbd, + 0x2acc9d15663027fc5b4fa467e70c3b476f2a07a6ea585caf7287921100567a40, + 0x230d03be86fe9114145312605773dcafdf71b97d8e2cf9e9ef246106b5fb1459, + 0x2ab60a4154e2261c6e4e82b20be3e08f7613cd334dbae29586e48c1df49ad592, + 0x2328aa6369f0af736abace3f7885d7dc566c39ef831508178e6d62bd4380cfc1, + 0x1164b8dce7e4179ec0e294da56e5ab43de2c20a75d57b8e583ffea2349e62539, + 0x2491cd6f23416063e77171095c0db217248a2c00adc3e146ba32d9ac2b941742, + 0x1cdc848d353fc772de151f8656a7e2e24b7fda385568d6596fe81a303ea208f4, + 0x2a398eb8ec4d3bd99bdc3520db7341946d4eed3a16f6faedf167905e6552884, + 0xb07f73cc8432e1f9e4095e392359fd46467f9bff3e24af5bc4cbe9b17b43e62, + 0x4e964ad5ded274940fe678e4f72079ebb09f289b8381bfa71d7c8ef0605954b, + 0xdb2a3aab326c1344771f4c5f872a050465f87469ca27704fd93ef3fe5a5a1d6, + 0x27b044fefd92da8972a60b0297f9b93f291786a749fef1e29f8ccf6bfde72564, + 0xc6c0bf5ece0bb9be0737e0c94f9b10594489ee5c00676e51f31781155ee8729, + 0xa36c8af931781acb11cc6922f0bf6e28ce01a1a18ee990da3421a0a9aea0147, + 0x255f76204e6137ac12ae576fdc49baa054ba182678d75a0a3cebd01d0cd6c286, + 0xaa31a68117f221fbe1b609d8e269e9ba1e9ac228e2e0a512ab9c774a3a63f79, + 0x14151310e656644c86a5cda7620c6440ad2bb09688c70530c1ebac60d96d56b5, + 0x27b953b1de0e30a1a423405b749d830285bfea294cfa1d3e11b4cc5801aaa640, + 0x30476b760f0b45ab4e5b7bebef2cceafb2b06f3b4193fb9938c946c63115b008, + 0xb70ffa00f97a377990544d9501602376ef9a496ab8dfc44856306bf28a1b920, + 0x2861adb9067f446db45b36bf93ab6345f53e07746c063546df691604ec026529, + 0x33e9b4274c357a8c6dd61a3e30236735b5a23f396acb52d92d6685a5f03ef67, + 0x28b4e505d5309e29a6da8f94fdec039ac44b43110bc0f8bcde42bd833dfb0d31, + 0xf6fae1122b219ee0b1675ee8bb5c7c48744954e3dae2f9d5d1ea71c0edb0a9c, + 0x2b4173bbd542f1b89fe8d3478a050e81d42fa495e9c96af263aaea3c498e917, + 0x8d72f5f016ab29391344f20b821450da912ff016e4da674ff97c5d92bd3a1a1, + 0x1d9e387998377d9e680b0b55e8309fb8a29719551de783c1cf817cff9ad6a90b, + 0x1424e2acf5db0d91956e15d5b5dc4132ad6c4fb863c9c8e572bb49feeebf7e22, + 0xb3db34e4253558779669b849ef2fab55ffc654d4f9f770f74cbc45ba117f483, + 0x1269861c49d7f3713673f6fec4b57436c9059aa10b541d64aebdbc11e6513f6a, + 0x2557b7a318681664ac27c48349b1b5f44892e5ad02c8b81493418bdc66517342, + 0x650dcd4d3610b1d776d673024e679b6c76b5cde0b985091ba00e1cf4eb26062, + 0xeae77312a73dc3ecb243143ba64f7cfdc9465cf00fb0872958286430fd41aa, + 0xf43d99f10bb7c8d851384f5215bcdbc90489bd63c9b4fa3ec48bf1851012d93, + 0x2d95bd041d1b5522fed823a5d9d607d7afd455461f33bc8c1404ef348221abb8, + 0x2fd83f519597b7e807ab80fd8701dca3f4085957b8f2955f5df79c24f00a1f53, + 0x25c0c9abd576c803e422eecd77a3ca4f63a32b9f90f5366ed37658eea86f271d, + 0x31509bde9a7286eed15ea23537ac72dfcc35a9f4c8cdc92baf39dd7cca4939b, + 0x2f6692e9fbfa0ad64b3f748425ce43c3c69cb5e4c13a0ff06c14f2bb75141af0, + 0x1aa375c879966cbd87d4ce7089e354786c6f2a58e26b97c760dfafb72df9c5eb, + 0x2f14baf1792365a476c4c193939244a6a4edf35f41616bb6db4b2bf511642a23, + 0xc1552511a3185d9730d9ad3a86c6dce629f5871d7e9ca38399758b587830ece, + 0xa499163b884b67402058e13910d1c89873c952ea1a7d1a3eefeaa22d2a37d7f, + 0x2cfdadc4634dc875e4c2be0f579768c85b32e5a19baf3b5d536a3d10a3199bfe, + 0x2ba9818b35db18cb7631164687c593c9badacb53bf720607b46212330be420ca, + 0xe37b0ae73060dc2b5f671e27e14a7cdbf6f37b7a03e69654bee75a9fbd52c6a, + 0xfdce2fc3a75a381f6dd84b4ca5f9753a5f0f8bebf5cb6e606c59717aa7b814, + 0xfb5a2ddc03041dffb808a10877d437c2764240964c2edfdbe545854aae282af, + 0x1ea4030900b9f74c33a53a950d21f40738813f69e8baf44444d6f0a1368c6d85, + 0x2b26ae52bbf7d41a66d984ee37a40c95129c4949cc74ede40fd7df3f3bfc7714, + 0x16062ea8f9c3d1bc9acece3e3afad961eaf765069773e679240dd723dd4530fa, + 0x78830573fab36a4777b4d82c044a60d06fc2abcaac1826fffd2ce0630d00eb0, + 0x2f17fdbeedaae54d1409c5cee2a3f3ded005fb6f84db8eb600111679e471be8, + 0x1a01b0c5b209af90e35799cf630441b0fe38394300a1dbdadf7e80230425ce03, + 0xfa20a26a6950d031e20c9fe19f1317c0e694eb4397a25fdf97946bfd66e5198, + 0x1b63869e274926ea2e91c0fa091b7074d5fcfd9987e887614da86eebd6b42c1d, + 0x728043328557038e7370dd984a822050199193a7da9c0a670af7af9094382d0, + 0x9570a7f7a06102b55bcfcdff64c42cf2ae994a20254054abecf6609318b3707, + 0x1c2ff23fd6d0090161db54a99810f76ec767e2db6e830afc9aabde9614829e6, + 0x7faf7d80752f501cf0eccc6bda01cd349376330df799ca842ed4f452517f6fd, + 0x2a25dc90d45e36b9367d207e45be38d449034231ed7c6422d2795baed9e08d3f, + 0x5d6d08e40d2741bc318cfdd961e62bd5b1439145206f49aeb0e8bb68a244851, + 0x9d7b3f8a46f030b3b0b27bdc77d990cc642e4f3dd667b085ef114d08bbda9f0, + 0x2d17960ecd06706c37ddcdad5e4707ddc0385d883f08fe7c8b36659d94ef85b1, + 0x15f2471564848a163204b074c1dba4c518b1e9a4052a3a7e5d9c2a0e77e8ea99, + 0xbc29d644405d0cf3ef18b311474b8f6d0e5bb9856059ea6b908d8eabbbe4a3f, + 0x1f3cc2b9a666ca5dab8bc17436762dece0ea6ef3becf39214992627d49595ee2, + 0xc5c7ec0b72c7947f7e1129191a11ea5c2d21a431561b3ee1513d0fe07b6b5d1, + 0x1b02b02f8547bf62c0250622fdbf6c094909fc25151c3941b5c8c2e06d675be2, + 0xd3213b732109beeaf102b359db224d86031ea2bbe1406f70b654eba980ab84c, + 0x15848ecf21e60c3ec1ef45998777202b708426a72b03f8dc4e5696dc74eefc8c, + 0x14dbf6efa7caed2cf9ec698db97e7552c62b386a3483ac39028be9fb5d6e3b0c, + 0x2616126b746c3d8a4dcdcbee6d4bb8c5ab7a3ac8c5c5b91a654747119bc70ae4, + 0x191fe12396efc23ef8865e32908d76c09ab0fe52a4665554020b7ba659386297 + ], + [ + [ + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x254b8126f45243f14dd8211df41fe5516b35952d56c62678c148e73cdbad3718, + 0x270712f18b1518fafe093660f492cdbc2fb70ffab31d8a4d8a1934be68792369, + 0x2bfc3981a249aeaaec4ab9001727d32d4e6fe75598ee964fc85cf30d50df584b, + 0x16060a17e1b11f851ceab20464572b3d78d582ea050014843101485f65ab723d, + 0xe73217a106c402e4c6c166cd9ef1fd2a0b16ac1cb43646bc1c726f83177770, + 0x4b959ca07e7182ca08f2351a03545bd7ab676f740b02331637ea1434c8545ec, + 0xfc9cc95222f92715cf7476010225e14cc38f314071e50e0f3bc9ec674a8aacc + ], + [ + 0xe1f4e4d26e9da5f8ee3deaf48b493610be61d7d3db1d9754feca30879adc644, + 0x2089c597feaa4ca9a202edfbc823763100e294c9e33000e513b2a216491d474a, + 0x107cfefa1e864045a668396526ed9f675b2bbf272ca635d8d3e8801099bb97d0, + 0x21630ec3f236ed219f73cc617b9f8b267dbee99a63c528544ea31b27cde49fb, + 0x2741203d66c523c7639ea713b20346119c961cc1e9659a458af74cbee16d71bf, + 0x17b2092b0f634576b654c6de21a1a8d812bd4c01559fff83217129082e2b2b20, + 0x68e8e63411df2b3a9d7c567f66419a580d3ba15bbfdd1226effa3fd6bd47b3c, + 0x2f5a2a0cd0cb24896c94878a8106d57e82c68dcf1e209167a45ae9cf8570fed2 + ], + [ + 0xc298c14356a5a7f226c5a549e59184900385aafd8ea41d9746729964ef75f34, + 0xddeaa906cb65f3e9c9bea6344dda8db90c253c0f7f99ecef88786fefe0e5cc3, + 0x4b96a296a35acf415929b8784b6bba64a630d29dff28b628fc98ef708230b57, + 0x28890a03199b727fede5ed0090ed69494c053c97930fbb6c52358b0d7d104c16, + 0x2208c5004806c7aaf58314590bcbea16168fe62ec0497afc6bdd2938c12d9a23, + 0x2f24d609cb23720eda55fae29ec6f19902c42d8bf904fb656202736d97b2eb69, + 0x344d0c772c2f053664a7b9266b19d48ae5d2ab3d1c1a18150754ab4b836afd3, + 0x2cd19b5c55bab1809e52cc9fc1a038c08935da19cfc563e7048d6bd1970a0c8e + ], + [ + 0x19e070982d3ee675e1622ca20d13b2375e528b676706882eb8f1afe1c5045ea1, + 0x1114c9120442750493d999d4dd45dbd4f3b75ab183209235396ce83d8ee9916f, + 0x1f0465a9c133a1c6805d705be6b3ea9912a2d062c34dbef92de46955b83e7bd9, + 0x1b80f3f439396c2f466b8e9b25765a014970455a1beaed7a6fa308dac75fb582, + 0x1c01f6db435dc4885eef9cdfed193250b9d3eb4cee366674b07bdd194ff349fd, + 0x2df183fe2bc9b8b75773fa961c8d4117e582a80b656af5c58763e7024ea4189c, + 0x7e0cca1a35ed15fbdb619bfaecc7a9a8f4c51293927562acea8eab817c6b84b, + 0x24ff2986781fe40ae61e8f5ca0ef17c5a5ea7bddbc127d431547c1f6a8f5cedd + ], + [ + 0x333e2923992e89dee570a650125eda75a20a72e69e10863a19d17b7beea9295, + 0x2e8b35a8c29e639dde8dfd49b4b347f00ee467863f6efcb355fa1534ef70783f, + 0x27a2b7f5549e5eedb90105c0f8e20f0571ab7af0801f1bdd23eaad91f2229a13, + 0x2a4bbad245a33e5d9701537f751410e4ff297b8f1d1d9098fe9c518c261a1b0a, + 0x1f0e36c2cf9ac2c4388e74966d9ee7d1a0b3186916a08cfa306f6bb36d21e548, + 0x15fe963f5bd0d92878c10a894e118018db82e63528afa4d4703e9881eda118d1, + 0x222edf3e26bf74b2f503983189201d4ee8e6d6fad341d7ff50748dd739749df6, + 0x12a87d0c5419f448419840e5e5a92d276ace00963d987f2a1008913d98a27114 + ], + [ + 0x1944aac72bf6fbcdec04361238c3c4d9510d5f07439a1b6ff41f652990be0139, + 0x20e6cc613ae6cb0a518425f53db1298a7f8859ee20aad08320d0a4f9bbfe8512, + 0x31b0afb7ab2f1d241f882178f7dcdad48591cc67905d651dbcafce94b14d073, + 0x1e431f2b1b7edae4f8cbb5d307bf5131c352c2a215a870d739617f4b017c6d16, + 0x199fc2be60e49e679ec2ede6cf3345dcb3b918e5b3e07c2cd8141333934e178f, + 0xaf594dc4030e8509701fbd3d8995f73126ad72a7af0fff344eee82a31ce77ff, + 0x2d4308b4823b465db653d36818181209d23cd12f844f72f7548d49e55055a601, + 0xaf3ceff2c865a901b9406d5d9b2fc58833d642f46c6493ca030ef595061ec6c + ], + [ + 0x27d802ad019a42fd04892ad167d9e83596a730605890401319661675736359f3, + 0x2420dd1281fc0dfac176a752d15906b55f137b9cc320d5d5daa9df3f3d43d3e6, + 0x22e0323bbbdace5fbc74a0b3dedea6e1e3bf10e84dfc71fe395089ac197af744, + 0x255639889a259ebe59f74a8fdf2efce7fde1e3a666b35d8e6ec601d4d0b22689, + 0xa38d163b8a2fa3092999c1797b1af909bd971a25a656baefbdbdfa3628e678f, + 0xb8e857d9fb1d554f3a4ec307ad907de7a436438603af1b28d4e4ee379960ce7, + 0x2e8e67fc85f9b4d00e9e1197b35bedf55afd7300a4c370987c83c15cf73cae3c, + 0x27f42d86842f4d8a8c3aff2f47ffc1e179f097aaecce55bba0b0fdfd5b190aa7 + ], + [ + 0x2bd05a040a0987ac6bc01f67242d54b7a2c527a970ad2815b273471eb9623e73, + 0x17bd4f2726748d99925af9a2f2929e231c1869428c13b1e397bb0099191723a3, + 0x1eef36d62f3f864eae67c63324e47a6344e33a2d5bfb82f05bef9900c54e745a, + 0x2d0d8a814cfa16c2323f174be2dcbe0c295829fc59bf2a89f13b4ead0eb056a8, + 0x198949eef2b27c2b9c3d699e3fe57da3d5b509c2b670afce400aba1aaa9ed51f, + 0x7ebcd25a10e56693a28155fcdaf7b3519d9e0e08241e21789696cb76ee06297, + 0x22f1bc4ec138b596128ce5ee5b8184964cc262318e17ad21d45c552477f53e61, + 0x2b6b3bc340d4119e57831e4a2187013f1216ab3b639945dd92a984943241f1d0 + ] + ], + [ +[ +0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, +0x2ed795314c562ca0b6d7070712495423ae6bea218cd94677d06e1043327d5d11, +0x1c700c219b9fd0ac323c67f0960cfa94e637aec4a5b68c8c8c579da52123752c, +0x126587f4ddc000b06931fd6bb92c2497aebd10bf7d001a3f664c6d6934225f1d, +0x1d322025a71f8a8445b7c50d8020f3d755b7ecef465abebec16e0d391bf9bb8d, +0x1d3fa515e56ec187ca7657d279ee613e0f993ad146ee2b37f12d142eb8108e07, +0x146acde01679ad962ede1caeb39836b4d818c68db52a9a1cde771be24b2e5e20, +0x48997cdde9b1ec6f3bc2ef708b27929596d02b366f44386093108703f4a6106 +], +[ +0xe1f4e4d26e9da5f8ee3deaf48b493610be61d7d3db1d9754feca30879adc644, +0x17ad6adb37b2fdc36e43baa800fc4a0fca98a20a2ff9c184a838a1bff5baf530, +0x14583143fe69954ead766939d693b018c9c6d99e86ba2002e2960640f993f19e, +0x9664ce4670db8421617eef97a4619d9914046ced174c5907e7305424656d460, +0x51301752f12f6de8c23dc31745b2b19b9bb7c39cc1ea08d08738c36a5e85885, +0x226238a28654ad973e1a259a8263c6b4aec4209093ce8e563b3eadb0f1144170, +0x1fd98a7ceef4a6d3b32de8b124c7e024e57c37498fbec5e451b92f5666a9e441, +0x1f471d25bb7448b69310b975678ddae2aa9080ef691242dc6871e6a680bf6a44 +], +[ +0xc298c14356a5a7f226c5a549e59184900385aafd8ea41d9746729964ef75f34, +0x4ef313ca88e6a46eb38c9aba804ec4264f79f1dd0c05857bbdf427a86de4483, +0x117bffb0996f3b8796bcf62f00e93cded9b3e7b07180721f2c01e53c98502f42, +0x36d342dca9ebe248ef3674d1399d5cb02a51b6ce92efed9de36f2adfc837cd9, +0x1521f1fad861eeea8bb068264dcbe68a93abb6076fae2f9e17066e4ff5be87c, +0x2d6baf82ccebf60b0fb1632990d9bff876ce740798a6613203cb078a9ca1a532, +0xa2ce4bc27cb25682f84ebfce048f14689f31b45e346b713dfe35716b9447431, +0x1e1b9c1ae86ec688bdae2fe7788b7311114a3a8d6f8d7fd8ac4d79a3cbb38e4e +], +[ +0x19e070982d3ee675e1622ca20d13b2375e528b676706882eb8f1afe1c5045ea1, +0x1562e5b3db42e4e28c9c3c085cfc8fe652b68e8bce182e6e1c84ab02661a8cfe, +0x1abaf63769a9a837a0d09e1dc6efb2dd1dc312b0c1c4a8c066663998ae04bda4, +0x338e5e98906f68a17cb1852bb77b5f42f287cb74e3afdb066fe966889db200c, +0x2d74e6c13b0856c0dd85188c8a80f41dca1e9791b1042521e7bae94bb36d499f, +0x7672fca8816914835cccdbbee62aa422a95d77118fe52444b5af200af0e00b2, +0x276718d84a065a288179b23b9b2d8ff3f6e55cbf97d873ad1f7e9a2cc8a09649, +0xa1bd98c224950369af79941d860914b7cfcca9596899786e6bd0889482641bd +], +[ +0x333e2923992e89dee570a650125eda75a20a72e69e10863a19d17b7beea9295, +0x1a197674d40c43447787e6079278b5812ccb17996403315e0f06230e2dbe016a, +0x1ae4af74d44320001b70a0a230327d586b0319d53a839f5fd27fac9169085169, +0xb169fad164bc7690cbadd1ffb6ab2e67be46376d16629d663b0b83ea7b7e4f5, +0x154b82a74672e1433c3417f9cd1c53d4ec0e4efc9d4c2655eee3c24e4449655d, +0x2c54cb56058d37bdfac59708d54a16c1c7cef8012ae5d1cd83d87140ea73adeb, +0xaedbd439fc8a60c641e55ba0f17880e00420bbbe5ae332855e7be146a0a0b24, +0x1b87ebdbf566fc8747d2430b3c45edfa8ea4f8c9770230ff4091f58d6cf6b61f +], +[ +0x1944aac72bf6fbcdec04361238c3c4d9510d5f07439a1b6ff41f652990be0139, +0x32aac2605d772f1fa6f328379ca86f4368bf679a39937cfc508a58e982db9a8, +0x3a38b1fc1f632c027894c17bbc4702d45616649d8e3759d1bd4239d89c9cfa3, +0x26492ca60cbc803da9930bf40b24ab2136a9275fa8b299cfc2674ef08234ad11, +0x37a36e914e568f3de0d6be824fb24b107bfc8c77ed767e707f8aa5f0199b205, +0x5de377805bca799a16d073b79fdbb07a672e7597d16df2739345938a20c5b3, +0x2eec7d749447d3df1f1c2da415cfc4b448b3fcd473b9cb5891f36db1c33b5c17, +0x5c539bdc0b98fdf23e2c568d8aa039f8d4e200a6da374c8e764b530e9b65d2f +], +[ +0x27d802ad019a42fd04892ad167d9e83596a730605890401319661675736359f3, +0x1e8382dcf318cd0d7f58ba77c1e4641ed3412a480f0b779ee6c9b73147b09d2d, +0x5fe56b2e7f2cdf071f3a588f1c604b2ab62cf34ffc1d2c72cf8a86079f01fd4, +0x177bd045809197d7bedb995ae85f213e19c1e301a646a8caaf7c9f3492042b, +0x179ab9300b69ae8b9b7540f256c0947b8dee0e53289ed0b5b7d0ef09fd10826a, +0x2c2ad35579f01d21b61c81721de5f2787950facb1755abc12e63b0ade9c66e4d, +0xe78c7c5a33ddcd2ac7aba36f3b50757bd7e867f9e6775bef50c85632f870959, +0x2010d6aaa2a1cc21415a72760a1a9d8e1aa82111c3f91e1a35f2abe8b79f2085 +], +[ +0x2bd05a040a0987ac6bc01f67242d54b7a2c527a970ad2815b273471eb9623e73, +0x2f337068a0ab32fb994362be568487a5c9974d9ff203f3db13234838c8246469, +0x305fc4e93cd1c823068e5063fa983fd71a9804864231e37d61035bef75f60188, +0x170e3b120459d017daed43224c80f6425f59ca2260178321543bb556d501c090, +0x1e1ceec2c1097c4b47a0523f89c94a42f52f2e011da379b6a0e57ad09973e16f, +0x13e72b920d7df0336d643ff47f37bc44888b98f7ea8064d5c96f8d39d11834e, +0x2fa9d8cfc04dba7c7f80eae1154d535657bc7015459a3df9dbe47ec7044ec009, +0x288ac5e38d20b5159d4c37374d8ca702decbc6265b6396d30b2c2959ae2af9b7 +] +], + [ + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x1aaae08b891f5b2046c0e697f481c70f34b0c71e81cadc7603c7e5d31139d196, + 0x2693bc2b2377f44f7d8c291f332a6bf184d993289445a794fd3f815824c7a4aa, + 0xfa4b8bf58974824edb3fb2d26038975f49c2cf84050c8208ea7a30aec1cdf02, + 0x1746022555831c140765eeaeb08a06bdbb7e2e65f5a5f70977d41f0f2a18b757, + 0x3004430cc176cbbe7f33aa7eaebd01856b009f291df0567d4fced835382f68ca, + 0x6406c73da9aef2475718a34075970df351312c5203526d0e55bb00aac90c6f6, + 0x27db71cc71c8a22d6133172f19b8bbaf0e37ff0772a58aecacd25e869675c3d2, + 0x25a9cb700e5decd6dc4544b9c5e3b49c0e04a8d1f8557e231da51d8bc228082e, + 0x1f8b293768d050b67db5fd50be414ea637f6ac51998971b57ecf4e4db972fdb3, + 0x537fd07b3ac0757eb471a2745efbccb327fe00df9da4b4b37ce2798d5441343, + 0xf3d208e42fd3d45dc0bf71a72621a3a1f735caa82faf0c3829e666889211ccf, + 0x21b6ec876fedb5cabffce8f4386966e8f1bfd0bbac488ed7c3a9cc73afe3638d, + 0x95100091241dbbbf7446ae4b3d1cc2e00fd45c725456edfbaed74111168db13, + 0xf1cf912f0d9e8be188f3d193aa91b094e79780511c3a3853b6f20c771a1051f, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x1c0b352556b629b1e64c6e3abac4b349c05801e9fa43439fd61a8392cf186509, + 0x1298fbf78e8967359120670758f382a8c951a8d2186b96e364e9b221d7b121a0, + 0x32529e49b3721ba593bd059db34fc4c01b5d036d2495b6d3221456edb02fa3d, + 0x2dbd37ed630dd234ae12f4c3dd4d106e277497f79cb16a71b4ed871d708729d5, + 0xe9a1b9cef20c937bd369647f84e2a310bd5d83e8d177ca9c7ea457169745b77, + 0x2f25b164c0610b5cc1a2ffc3e962a54ab01e0632b062e87a0bf249f8f7a51cf5, + 0x27b73694b83e0b1c06069c9cc1fc20dba1d037e481ef2161a30f4de74c4979f5, + 0x1aca98163961aa6b3b4bbb40fa812c86822948bf91d38e606bbf5e1dbb732f2c, + 0x23f67b87edb5d48126bd42b7f2a9f8be7db2ece0206f97d840d28dc3a4967c0f, + 0x2d7104faa91a3300e3ec93486228f3657b0aaa7277f0aff4760d0aed02ca07c, + 0x2f948955cf159477c7b411b0a868b9ae9a56a240cc20e40ce1a097a4749467a1, + 0x105151aad6d4d7960ffafca05d4f8ab4ac1930b222fb91eb9eaae07ddc18ba84, + 0x3cb3379d04500d1996cefd61c5032852d43e41e87148d92329bd98003fe5d8a, + 0x12cc617757c857678ec716ed94050bfe192215d9fd76be3bf98b65401e8d12a4, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0xc8716d8ded0a8c521da019c24594a1b859e53e85311efae748ec9312a0697d6, + 0x2e082be597fce21e7ed641c2a50feab6a4b26c6050cb7733979656d9a71988f2, + 0x1775849fbef452ce7a0863e715a67ad4361b9a2b72a055469333b0b8b8175b21, + 0x1fc8ebac9a5cabb10ecd4fb66339a2fec1ee8af951e69f5837775cdf4abd3e0c, + 0xc92dc16c65e5fc74d162103763ac39f2ca7ad692aa9dbbf9132b8d7af4025af, + 0x1e5b7963f79d2bdf1f857f13e667e9d7a97b4605846db4f0a26baec8daf691a3, + 0x19172d7e44ac5b1b381c2c893dd30cfda08c46fc6277dd38cfe1b1cc4daaa8b9, + 0x184154d48a6c6cbf9613d54a604aebd5820c53049749f533c0efd168e4e83e60, + 0x1ce093daa2ab71b132dc2d3bc1fdbfb91292c35f083d350eda02629f66eae2c4, + 0x12b07847ea7982e0e6dfb1b2864ac2e8f04ddf7d766c33bee75749015a91342, + 0x1b96c0239c9b6643850b8a653486e0df1d4c7f667a59ede3064e4b5068b44200, + 0xb053365816d9cc61b7e857531ea416ea33d60c4d8a529317e29a73a3aad422e, + 0x1fb9b2c50a99cd788717b3689d46c05e0d7dfa13c58f725a54851b1174c2278a, + 0x2c34ad3345bff455c0e461587b7332e19e0a9165375225769e8dbb2087391eff, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x60718f37a9480c0837f5a5e7c13eb75c07f60a8d8c1cf9ff30ae132251203f6, + 0x4f4bbea35e9b9001e92d6cf690b28e9c0a463382cb76c5b4e6acef622c0436, + 0x304a3b30d2300c7bcd5a2b7ecea51942b79b7d04bf346f95961d37dccdfaa238, + 0x626de3124c2c8f04ef55566942ffd3a46f2b7bfc898ee9c5313e50a3810a397, + 0xaeb9945d06bfb644e310b3109297f03f2ac002c31dea430b2a06666f4d93e09, + 0xb9264fb57be56298cdbd2084d379720375d397ef5d09a3ec90f29983f0a1538, + 0x17dbef787498ee541ccad5751663330e379ec632306e689cb3dd89480adf582c, + 0x15e36a3829fcaa26cec9655273017e83e621b84a1eac7be9a764638202a1724b, + 0x243a86766734068afe7659f078d7384e2ae7a73c2e2b6dbede12dd0ac2b71a76, + 0x19f171461fb4bca771adb125c689bdf519519dc2b7960b5a7caf07c1700f0921, + 0x1f5a2974eab40b787b5ffb6de24e939ec04b5bc31475cd803bb2fe0395a6ec5b, + 0x96ee06e8758968f1be067fb4582c810694a7205d39ac72247c3bc4e74fc02a0, + 0xb960361062101863b600c67724666f71ff5acc674628f46d840329eec2a20db, + 0x54f72b1aaf1f0531eaea95d0148b0525af381f598b075f56f86ac0f7edad99, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x15d5de1e8c0f0d18b7aad179279727eece9d2ff735ee49e3634167d4d440491a, + 0x16df68e36d342998fa4818e065c50d575012f4203a0ee73e155fb6f9c4ebc049, + 0x283e201525e86ba0ffe200bb698683a35d51810b72339aa3773217411af1ead, + 0x289ddd4c7635287baba51ebee25b7e42f98cad532e2f57073dd7e8465ace409f, + 0x16c3afd8596d8515eed82ca10249d26aa036c6abdfaa26efb7c98841b2719d33, + 0x4d76016f612698f913a86dc0749646b7f4517d3e668903f76effaa95351e90f, + 0xd021dbb869aff3f4fe189fe3015d9d5848393aa6f76eceff7f9d9a72a736843, + 0xe769248c92dd03d46e9e6ac5835329f2d5f7af5cfc5d1bd920f097379443e98, + 0x189d6ee4a5b445947e0efa11690f186e98a54d3e6406d880b7706f7defe167d8, + 0x2d9bcac46f7ca9415b13759c9b4cad42a113bc19565a01cb889e1d2d698c76d1, + 0x684c2e542b4e0c59a7f03a6d361369a5f6421a91b98b1fcf0ac1b7144e631b8, + 0x1f6608bda209f29ea2d9c7df3a924b661aa614e1fe034f6ff1ec18bba7a14f38, + 0x203c71fb9d4f1881845f258bf12de6153df99d35fa3da8cda1ef4e18ddc0a65d, + 0x2bddac5720ca5c69a727c029e4edfc393e4115f898b9da856f064321ee8e37f7, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0xf415650a23aed782936a31cc331b3856b64768dc9b29c9a68a8904a08a2366c, + 0x2a3272896962e7d3fb7a1c783e24ad141781fcd588f4cdc319b3deaca21f79ed, + 0x1aa729490f697568fa8cc7587c9d92bd19610d8712eb3d31a03ee9a65bd443d8, + 0x102aefa3ca3e1722980dae564122eac6ed4b1534b65d6effe5503b615d7b76fc, + 0x8fec616df09b477c42d44cacea45c18644a68c59183933f1fb67ec8c452008c, + 0x6b5b266f1fbe4ea9237a231f8c28ea19723adb47729b6913b7af9454f23dda5, + 0x2d4a264e748b499d97b3320cffb56648af68616fd73bd29e1225e2c45c1163b6, + 0x2224e659d1d7f55a80406d270debf092f713eec67aa001eb50cd8b173a766988, + 0x20260ec25a18f49225f3accf1020805f5982f34b658c553f5f744d360d50d571, + 0x1a692c93319abaaec066616f97e14c1d511e86965517496540cc0391490b1b57, + 0x2189d255d9ca828ade6cef86f5de626fc2689904db402a6131066b41616c23c8, + 0x43059b6857affa85b90d865eb1a9a91f036aabe5a12c9a03e8ad87934991a09, + 0x2a32437cdaa6a32a0a3c060c2865abcd8cc2a79bad7efbac1cb8cdece412be75, + 0x1746046edbf4fae210a3f0273bd7cf58beabba4c210b3617b030f7b51e6f8f44, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x166371ee86c08d7d38a594cd70011ea1ecd01154007d555fcce5796dfec39e35, + 0x22f89213a0580e56569c73128c8a41351b42106d11f08b6f900f8c61e89e3edd, + 0x1b3bcf6322de40853b5647f94ceafa4b109dec51c81cd7a38b51ad6d96ecfa8d, + 0x2fed79c7828b5f8fefc7c73f312de0739c9a2081e432cf2f62731a5f02fa16ca, + 0x243db465df5d6d34ade58f233829cedd38dfb57101da284d42207eb4df69c7ea, + 0x1d49c10bee07998c64facc37ae50dcd91a17966b8731f2d1a34b3f78559bfb14, + 0x2d7c4a750b7000a296da599f89c4ea7729cfb85883037333e1b4526aed397cea, + 0xd4f4d2dd076db4bd67ac279bb51826a827742918d35aa52a5c1df7a3ac5d339, + 0x228901e5388a5c10531d4122f7e0772759d1e4d026379ec16676f45a64b818ed, + 0x111e7f5a746d046f4d7c19f2fb49c31255ba045db988cddecfa0e4172fcb2d6e, + 0x1595f02fae7bf2b328680bc0ae805194fe9ee83f4fdf4dd0d35e84ab29a122ec, + 0x2d22c9fe81fe2db64f3ba5cbac4957fada1f0c6a6a4cc883db4dd922d35906ed, + 0x21587d485b2624d0549a6f5de06c009ed06c5b48201d8f9a750c5e5a98ff19ae, + 0x24c33e212e7e9d3faf0ce44a3cb2113e74ffb7c28b45c7b4ceba5c1d6944a64d, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x187f5db526575c180e8adcabdda34e701463bf8b1596130c0c6b815dfb5e7a24, + 0x75eccf8b0d6ecb184e0f168c64404e50e013ce0df06bf31cbcef2421ed7b0e9, + 0xbf2f82a1b14f888c48822e147e332a2bcaf77ebb32d7cb3cdde813f0b1a373e, + 0x1f587a1be361522f8568d2109e0984f059a87317a35f7ccd7365c5d97d447e62, + 0x24a69effda852c7d20fb4fd8c3f413db1b6ff3979409e83922789cca594a462d, + 0x2ce67cebac6bc12ace86bece70ae7a5a59a97023cab6db35a0f8cb7110552ad4, + 0x2ef4852f4fa73b0c40c37118ee2690692f1e7101a78a38771a8686ecd37023a1, + 0x4ea49b4f2225a5cbe53c157c56f62973f394fdb3076954bbbdf30786debedfe, + 0x2e874d03cebf495782ded304d1f37903b06c3f834f170e96d26812be0ff52466, + 0x23acdefba9e5cff344b212629dae61e76e03a8a8eecef4e6c0588277f53d81fa, + 0x1173808e27354b4bfa76d6bd920cfc8309f1e9e99f997f773195070843eda183, + 0x29aea310845b4a505ea34932e7bc2a8f2b936c47fec5f2269a3c999413d048f6, + 0xf5536e4420b891f4cc82c50a833a17f0cabb89c3ae4cba4c28fdd5cb02e3d2b, + 0x7a3576f0287b2a1c0d832be178d43b6858a4c8989e30041cc143f09e2012fb, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0xa260dcd98e220b61c2012dc6380f52adef96a11d38e7371c576d54563f7bfb9, + 0x224028c158b4b4adc53ae913cfd9ea42e4456690be5dd8d4c459779945157e4, + 0x166151c43e43373467888a2ed4bdaf3148d8ea2432d998162f62f8159cec690a, + 0x556f9ec39ba4bc77b183cff006a0a582adb55d52dd0f4a8c1f156b33898b28b, + 0x201670bf6f1fa62050110754b53b3d0671086156d9890ac85f40c69aa4aa297, + 0x18a78efc7a694b6e957b209c42d6044af319f194dc16451c6da27802e7f1c85c, + 0x28efacaa79a0af5fa9ddd71cc6a711629788664849b96ff0b42a61e2e43c87df, + 0x1d07f908b2ac7783f0d734e871a40be7b2e164afe885db6fd312bcecf4cbe9ab, + 0x8f97fb3cc640d078af3d17c569f37a9ebfa6f49c48db74b3d948a8675db96e4, + 0x2718e729e940dd2d26c6a6fc7de40b89927f8c9df032cdcc06ed4ebe194fd596, + 0x2c68ea4120e5abbe11f3b62801199cdd8686dbecdc52ca8a9458ba48b19aa6a6, + 0x2f39ffaf54a4cbf00809ff50047289530732279ea49607ee779fb149b87e10c6, + 0x130fb307c6cec609ab7c5f9bd5910a9ed9958fc11e443705609ef3066197a9a7, + 0x129a1c66d1eb5e84211c482bcaf70789e6d5cc473e1001dfbda059379f7b58e1, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x1cff973af21d88635ec9afbffd85b1cc595703ae5bd5f4faa6ead489d7aeea20, + 0x27ac0db61623f033dd102e118d47d847f34fe11826bc9d23d7e3e43386ad16a9, + 0x25ed2b22b59ed4baed8f5c957caed1fb52630971092d0af3ac8ffe5fe3a13904, + 0xb634c3abd9ad8e1b2da84a144207c4ddeb62c8f4860f65aa2209c1c0d0d7e75, + 0x2158eacda450c34d62fe6ed5e3c9e211c170f4c3bf4247c5caf0b9e2340e409d, + 0x1c0e715ac64d64535fc97e4d86b95c6120401f5c2697332b1ed6a9e83710afca, + 0x1a491a07ee1df9abb02aa300654e59bd34f593a15b74306b41c04e8b9530986a, + 0x1523cc6481931e85611b1844832abbf8763fab9c85130f50ab3075fa4f60762f, + 0x2816926c129f5c99a970733571d5c01be1cc18ec0f45bc5e46068f0d188bc9e5, + 0x2d94c81e271fb9800d333223a141c9e904476dec1f8f1e6d224ed49467e18a1f, + 0x1bf8ab0b8cefdeedac41738599d38ccaee7c03914364eb617b5421e9a51a0b27, + 0x21fd6c59b0f417453f2a4d669851364f5156b6adf104625f857681411bd04c64, + 0xaea3c50afc0806b117aa98c104499b4d84bee966a94865896a39b9f8ebcb917, + 0x29a8795e1f8f1e27e7e04b23788ac40e102536d56b57aa85fd1015cc21970f55, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x17e4ac7e489fb7da610506535bce04186426722fe24a261a3e286df2f3519b34, + 0x10ae4901e443ef76726afccf1c9099fc18001fbbf5d144ed721196ac9f2cc130, + 0xe60f58884bc252084c93a18b4feff245175727c03003f025100d435a0debb60, + 0x17de16da3692bd34ac4069982a1fb163da3119cc01d12c6f1ebf64db787deca7, + 0x78d14f36f6349d1af6d92afc8dd98ae7322f3c11993c59a225b079c7acbd4fe, + 0x2cfc356c4f60781e3cc83474da74607b9567ed3a08cdd7242ffec76f7d36cecc, + 0x1531440db56edd521c68fd2dffb627155130e6f3a2b47fde65bf8785ceea104f, + 0xc9d25b13772cda116107dc0c4fe9818b74f24a51f4bbca5a63bc4fc6441996b, + 0x28a4751755712b3d33f9eee850ccecea47ebbc32a1fd199fc256b69c04456500, + 0x1eb00cff68143cfad376aa8ec83216badcd664d55e990cb2d611fcdda52e4407, + 0x1bbcd528cc66eb76816135706b090ea3b46d45f0db08af962f17df4eb996dee5, + 0x19a41df7dae052bb5821aa4f32e9103dff752baa24b9fb51fcbe4359827f8cdb, + 0x6f34fe490adf4a07fee6398a39e84a0c32c04259c9691daba54ca4bf696ac5f, + 0x10cebd9c9c4b941425619aacf24419380dffdcc7f5326e766d38e72838be3120, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x214aea2850fed7223af80a5906052159cbfd07a30736ae5d95e6b60cb4989d14, + 0x15595aea45afbcab1d4d2e73c0a36cae9d2fb50d36cdfd5c0c127f95862add38, + 0xc4055b948c4a9fe79aff19190da8995eaa7c537a20cdd18f5bca5371d0c895f, + 0x202dc56d64cd4dd16ba2e50781fbf937803bccaf08b7ba8733eadb427c13989c, + 0x2ef4191b7deb37e92edd46f965bfcc66bc5a8539957f319958d91066c3fe15da, + 0x2f6942e918adbb191600a517edb486cc96e355737961c85e0d8595ecf579552a, + 0x2cd60b5a15f37871b552d8095cd8a6ffaf033b539d7bf1ae5f671e2ffcb9f2ce, + 0x2e05c44549c1ca99a8aa9e5ccf4726240f75a4060ad8a71012deb2ad55486afb, + 0x29b52fb3d57ee05634b2864e7b2977f7393906c12e903931531f95c5f4ae08f8, + 0x1a565be54d3bd12bc9a46a1e2853a18ed26d6744c98e5cf53c83e6600cc56a60, + 0xc806f9ac20225e54ea2ff82c73c6809497b46d85d51a4b05c46f667bb3ed592, + 0x2aac8b1272085c7986012bc5c7612d5b7eb5933a9140498359b260116290048d, + 0x1ef1b93e5e0c4bdeed8d40d74e84fb0ec5e8bd52af3ecfeaa54105e674611a3a, + 0x1a1fe313685a247b03cc9abf0f0ca133ea119ad01ef6a090baf774491a001296, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x694287a5d6c2f8c7e6ad899f7960ea1abd3aa7829422a66be8e8a1ad6bafc0b, + 0x2aa1bd4878e2ef8252ff42d595d2d0b59d774a98e3439d05682cd28463e15104, + 0xecb968856d9c8a1317c756d0e48d5b1c365e6eaf980989d3cf77d110237314d, + 0x8a950f1079254aa243fbd11fbb4d25fb0cb8a0c39bea71a3aa1c0df80943907, + 0x2ca441a867e40ca07b530a40b899052427bafd17c7a31d484188f96ea21cadc0, + 0x60117f9406bde6b52e0af3a54444fe9cb69bc9ef22405e2b85d223051852c23, + 0x18cfbf11b6c20bd7cb8fa67ff4c032c39fc2b3610cd8f90bca3e6136c6b04f4e, + 0x14addf2c0a38c601d30bf96a82d3fcba2ee369b0d2f232adf5da3e2bd2970a43, + 0x2677d87f29a2a948ca7e8f5a5341b56947563be4acc97c46e557f5c60eb84442, + 0x2f423100c2e9988b6cf5e9bcb1b2aac09d926458b9f1177f841977f39109c1ec, + 0x2549090369bcca257da260694265b951c15643c8103c9cc73fbb6b065db979a8, + 0x205c0e6789ef1fad3b8f1367cf4eb199b400b16499841e1feac1cfb774412d97, + 0x116a1eb2caf56acf7308b5b7a7ca6b98224c93a655d78ca7867a3ee170b33fba, + 0x319871e083a6e2cfa6a69f480121787a71853c4c6f772fab9dea2e267f3576b, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x5b98a534aa4041bb0c7e79ae6b2f5c164053b4c0a65dba7fa318a5aea8d22b6, + 0xdd5bbcdcf0d6fe99e9ab4774911a304957b461e3e2d809775da6d9c66ff2cf8, + 0xd5e13e77b22ec3447adb2487c15a4ced671076f0d0c0e8ebc9072f1d8e37b87, + 0x20468b6dc384b134a4538c25683b468c877cf30b1321dc7c39e0fc942dc64450, + 0xe2bfc13ac065e251caa703abd5362783941ed0060dd9d1b81f50c630dca8376, + 0xf300f277165a02ff123b3078e87e6251de0de93dd81e76e8f8197b949960e0d, + 0x19ecc98c331d8b440400e5a71e1ca2f830536b1900580b3348f3b7ce93f75a5c, + 0x2b60e2012b670944ceb50be1c78808ec4568c7c442933b21f125e9cdfa7ecba8, + 0x2c3e3476d128db70aba892a46c2061ef24df0ac74db004e7731b167f32697459, + 0x2eba0701ccabc0ab29863c74c80f1eb3f6a6ae79792249f4e4fbec63b6282e0c, + 0x1b821e2031ccfef578878ebe3481c9b5db9e7df929755b98059ae847b7871a1d, + 0x12424e45b885060002f66118e487a97bbb10ca97ee0414712f85f2154a6395a0, + 0x22dd55670c91344017558b62f32c530ef0f3387736514af44cd43812c3c3830d, + 0x18c607675f0a99f94f2e7b161c693472ca5963f71823a62bcb4545249ed116df, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x2d16a32d5c9663139709f054159cd7cf6f93c5f9133007b4ec8de3983231be32, + 0x1af2c4175ff13a4c27cdf6f91e6ee2d81e56a4d42d6c13f5e1b41d8f71a985fc, + 0x244100fc9f31adb4e58ef3e56c2fa32b5b534d42a226880d78eb3be202c9dd07, + 0x25fabd23de22009b978a089414dd805837cc0e1d2d68f919a50b7e17418f2151, + 0x22f32d43c35f5cb33a857ac06d5d9777a42b92268f0c06b26d68f7542a6b50e8, + 0x20b44788f504781a9951e09b497f1c1c2d2f723b864b84e74c1523527f48f996, + 0x17192ddb8a67bd2ccbb940532adb6e376759800df7429c45e5a09314e64cf7b0, + 0x116b6619b40c6172f572650a9566ed2b809164b994e388b6fc467637b61cc2ae, + 0x1e0133f2e4adbf08938a9ccc82fa3d3693316aada3b052fb02ed3900e1d730ae, + 0x1664c7e25e5a7d2f285156dee897b4af0c1446a32e575fce4d56a3cab23deb44, + 0x2512c8e3d7d525edbbd4bb03394bc4ae7aed7bab5ed55ce3fc4aeafc329b7f49, + 0xf5800164acb67ed0f6efc527bbcdb851e66995c9dd3ea18cdd9b54259f64bba, + 0x1e4dadc5ca72e83a6f54dc097f0c2f72d506ed77d576abce800858d48cdb9cc7, + 0x398b2ad87a996aec8db980123effebfc59ef1d35be0e6a7fdacbf3929551bbc, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x2e351fe58b5f36389df6c53ace1a5366d9c012a2ce2e0c4a9dcb30cf75f59869, + 0x290c7b5e749c1532ba364061abbbde22272b62ee90ff19be581c4ea68f58c5f3, + 0x1313fd3c761307310d30f5aa63cb0733244796351a9c6077ab5ea343e996a778, + 0x2c31bfd37ed16abb1583c403f09dd2a064e4d03f9487a076f496e0c8c5dbb3ac, + 0x10cabad2beffecd1d735b7284037753a85845e6fd5b7247f3b457ba9cc9a323f, + 0xe02a96e2faec73e916458f940919859a161b6b85894abe5ae146ea4d3736d10, + 0x1d6e090f0acd4da143b23f3ccc565567bdf49353b3416207af2096389b791b06, + 0x45f7f1687d62eaaeedbfe3fd4f725c85176968069afd815dda5778563ae1a93, + 0x2874ad2d5ff34d854490d2f41eb79295d0bd9befdd54580b257fb4f2da1cb9b3, + 0x201894e0f41d2f3f21a6641ff9e3959584a749648f98c6c6b3c3dc6e8285239c, + 0x1e51409dcf81bc661657b6f0cac27edeaa209baffb0c862fde7c0d0610506b73, + 0x2cf3f549a9651db991a798c7392afcb8cfff307af338cee2a501dc1be740598a, + 0x1b7aa8f35a2488bda1d6ee416a8be05035872fddbb96fa56645d0f63bad04b69, + 0x182132ead4b05f9e1a44e7422da93b1e0e94d5906a78f63469cfa1b0ffd06a02, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x863bf81ed562159fc915b628bb76e3bae663dc10556dae9cd432ef8de50b6f9, + 0x16eb9ab36c92c197c99c3d11ef6d1469a9c4f9779daedbe99a8e5f24c8f5c0fb, + 0x2a0f1728e8a783630378d81f1509e94bb9803a47a112d99f7a58c60943c5c97d, + 0x20b391efe82379701a0f86af56e5d22cd881f98d0ac433df14ed990881cb5ac, + 0x586a52cbe0c5a8a0c45440f80dc7fc52451e815c5b0f784bb25f0ce319a1c01, + 0x4af2601360cbbcef49162688f13409f2fb6026f4137a0b9f85d4e2272106766, + 0x9ad52f4be13ee678536dc64d24eb019da0f5cfb36d4c35b667c7ef4c85ed800, + 0x177a0d318b5c0b226c15afa0ebdb0f3d582caf9373d45e73c25ea6dbd1ef0e8e, + 0x1ad9d99de7417cec3a5d831e8a8cc4d633ba770104d76f19740f8483411bc837, + 0x69f24d59c4dbc2351edef37a68c5e0133da60eaf4ec85cc174f5509e4676f2c, + 0x2f87a8a8a421081d17480f0363088e6604780562ec2d97aa1780a7be1d7808f1, + 0x2c2318745d149dfbb796aaed50048227cb01c1885ab2eeec9897423d824e65bc, + 0x128ec586a98e49ffbb2a98e078eb12b4c504448f53a7c59a7e2944ce6636ac02, + 0x2ab7de0aed5e6302873d6cf0f642ecbcf4b84d263c5f60316ea0e434f518e270, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x642e786838ddb539b8b481d50922cf6acba80cbb8cd74d91558b4f7a59cfe41, + 0x1e02bec25bd53fcc6becefa234ab7a591e14d7e1b9dded90a1bf8bdfdee1ae72, + 0x261a2baf4b655675fadc57ed29369e831a3a236768779c26340007d048dabfb6, + 0x10b56d5ccdd0be5391c62cda87eca6a70f12f8465ab4004c6742beafa69afad3, + 0xd1e13710db39230e576013e5b339b6697349b6102a915993648b2097ad216d6, + 0x2d0bd075d622a9ffaefc6998e1d3a845ac07e8827ceb27da1eb79ff36386be91, + 0x17f840bc566db8a3debeac087e4c9d5db07e4eccd0871c09c5314fa935243f1, + 0x299f4beec86f210fa27d718f78fae4f2d94a7d0b1e029c92bb0e33456c572506, + 0x6aa7db000f3f4d915c35090ac9b1a90b269c8d90e76269053befd34b76c41a5, + 0x10dc89ce0e3e131a594f3bd90a12586629af838d2dd7cd9566a66785cfc7b8de, + 0x14e4b1cc172d23e0d5fc7f219fa43fc301be8d8702dc1311fd97f784d0d1d773, + 0x26390978a65b917ecae0242affc450f91c4649139b132aaeb1406b77a751216d, + 0x19aebfa3fa2b4cf836f3d9f5b672a682b20f82ef9cbf8f092608c22327f1663e, + 0x2917d6cbc77bba7388d8c43278a57baf86c1fc54fbf57d0dc985238678c404a4, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x2962061bef3a0b557f60a3af8ca0b4e6b44336359bbfc9d30149435deeece130, + 0x1ab2e3bd8c03c56d30372867a29a5017fc95e868c228c456e318ebb2a7c2de76, + 0xdce3071ee2164d465e882c1f319aa89d169d4216a2b3a29dca0d74244c36a5e, + 0x1c7ff77683589db1c00e5303d9568894c240201761b546d2aa38e6c63831a4c9, + 0xda3ad9016d141320edf78fb242fc386662fc9183a250242fbe72997646ede8a, + 0x108c858506802f97c0a8a005b6f3d0e73e56ade83d3e1ef9291783cebeb0104, + 0x18a041ad99415766535e735d35e2406d99f500507d44c121194ab5d62bb3dc73, + 0x804d788ecca64fcd1dc6eb9594fb8e91b5fc9027c2e0542369f2a125b1cd397, + 0x7731d16594681b792f143ae2ef1365e94c7f0fe15a472a29d71aef1760961ea, + 0x2bfa3cb90f13111146c89385af82d9051c4e02f738f2f996d2a5f1db712ec6bb, + 0x1fddcd4b1429134574b4f66c202cd63a4214580e654e739ecfbfa3fc3bf8b41d, + 0x886c258df023184bd7c942c2f273140834d867b8def498fb10218af80d66425, + 0x19ccae1db1a9300785f134702d3b1c8d13d9ac87b9c2013e5285209cb804e1c2, + 0x7a4b8155eb76363e05e5f00ff95defcbd37b94afd901c13045979dcb63d6ad9, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x11526ac8331c0fb6dd4e34233c163073d83300629288634713359b2dcfafcff0, + 0x2ee5b7cdcb61f59988e2794312192b8afddd8f8fa1cf883c998f7a782891dc7b, + 0x2b88c35e9f5dc25ddc81bc209216b88fb526ad94c189d5300c9476d0445426a, + 0x1947ffebc3ac4ac3ccd1d57cefaf6190f1c1035bc5ba84706dcce44d9706f1bc, + 0x99f8cc64e0503354ea12b5a678143fd74f1b4d69654c9a8baba1d58101a3147, + 0x1afffd8d0170799d162462549921f3c7344d8a27eea55b4f9397c509f59f0e83, + 0x2fcd5239954935486f68514bc4cbb30282b25171bb9227ac96ce5ec9e6486732, + 0x2ca2a102b6561ae65db852da22c3b486fc77c6a2f5583506720a328a3aed8e20, + 0x1002dc58bfec0fd85333fb805a44eaaa1b478ae253a3d4a57681590d0b52ddfb, + 0x139557f5ff664db54d6be4e42e0b4f7ab92b47d9d81da1307240385200759205, + 0x2c89c5c93e90d0a7039ca638e7a1ea5cbc2358e61044b6a09d103cfc9ac4d9c4, + 0xcd0d79c5b4c6e7875b58f2c619fc727aba63df991c99d25ad2f24beca0df141, + 0x184b385669595dd8fa774311e59b2abe04f59546686f74fec70c9514899894c6, + 0x1cf3e5292afd10a90414741ed3287263f4af9515b8cae7f41d45e4109ab0ff06, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x2e764ed9c7bcd1b4f7a64f1afd3efad5476eece0cbc566617cc52bc51885cfd, + 0x2e6eb18b75b4908c063a9204147ea1e9707791f2c6fd201d081703b4cdc97ddb, + 0x172b99d8419fe0858380c2295d156c711ccf85f150ed4917ebc0942aba4ae961, + 0x864eea049a1f9510949a12d9a6e74537b3aac9f670c50d4f4bb77a7b68d73f0, + 0x1f9a772d2f96ded0661156db1ac0bbb7829ad3cde0c3e63bb95a5a47d4a2ca23, + 0xe72ce0076500c498994a78879704743def13b87a1c78bb60557598652e84051, + 0x183ca9c331d42e15818e0dd9fe4cea99078e0cb54013eb596f798c3dc22c4e52, + 0xcf4da57b9a9c07ecd1427b2b437664b5a2e885e76e1eb08e234c7b12761beba, + 0xc7aeb1957239cebeb8c3f35f94ab2fe443234d88b99fa1a77cc669717410a30, + 0x120218ec06b07045ed6b079c2fa91b68cab9caf72ffef5816c4bb77cb3dca124, + 0x290ab4acbb20c93cf9c99d07c9fd3189dd8a395928cf9be93857f3be7a4dcfce, + 0x1da24af446511ae52972f6cb9490df5fb5ef6f0414b514380f9c645a78c8511f, + 0x8eadf51c905e829f936a2a68786a45c09296b064ef0764b59e05398f7601d65, + 0x19b72523f030bfb311fd94c66cb20d105ba2f1ff248bea6c3bc314cd4558005f, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x177f0b80a1de3ab56e24bf4f8e63b45b31685e1dc1da5e30553d6be482bad1ad, + 0x5b07ed986c2df68a97a40e1c227c2f72d5520271666cd41326394722b9932c2, + 0x24d2c3f8955b7a068cf9a7bf1cd3cc1f7daddbf2a99b581f3af4980fb1d17892, + 0x25838298a0cc4b774b6bc89dc923f9d330599a9d122629aa96ed251b5bf10bf5, + 0x2afd3dd5e0fc21f0d9a2926ae68745e8c7bdb307a5e790ea08872e878cd3bdcc, + 0x80f2fce3bab6286e19d950f3372e78d4afe22d2b2757373253b424858b37e6e, + 0x29ad15ea08093d81d74c6fef9f18aefa1a6915eeb05e47f4779c8c44bb17c8e8, + 0xe004451085075e404f3daac34818db8878cd02f134592adbed0cc081851599a, + 0x2c1793f6782d38379e1e1e3867db57bf514320c0e37fc2961e50ce2cd3a61c82, + 0xbf3dd46be8800ec0b7452c61319c2aa365307c9b7e9d955aa7aa1057e91dad3, + 0x2dc74ff53d61799295950b34ea3daf706a0acd6d5cd2ab7461ec706dba082402, + 0x12d0bf8b8fe9ecbabdc9464854f9df7fc9950388a9f68bf7920aebb5f0285a2c, + 0x1e939676347eeeeaa96e3c0bd51e14604ecd97336f72eb054c61fa71309e43cb, + 0xa5c3db062ebf2c84c384588b0e97a0d2431f7334ea9006436f6795aba6423a7, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x41b75c1586f0664a618abc2e19231f4230761fbbf90746fa7ec06d4a517311f, + 0x202eb00eddadb4c0761953255195ee55af32ca0621e408a73eec96f080f07d1f, + 0xf0cbd02267d601b91a1a62e5d54246f07b337e84661c9a7f40de79f8527e94, + 0x14f2c248139059dfe9f4d970c661fd17be54e8fcb3a7e2cfc1160288a01d3904, + 0x1ba2c5f95dfaf2df18985f49b0be1c1892b59dfcde7afcf553fbde41c2397183, + 0xe0b040e8c04374f4ff9c54e6ae1cbd79cf4e46a5a32d644ae35f95b6c924540, + 0x3d017d86b1b62da699920b08e0bcade7c6c365edb3b9b2ed28e1cc5c37351eb, + 0x23b785d6905e142dc5f955a2ed3b4f57c0f18c79b9599d1f21a9d370d323283c, + 0x860b1ccb980266b5c9800d56394061e4a39bb2b31d503e915c8e4f2678a66c9, + 0x1e3095884e8e3e82a4282d39e2020cd3f4dd4c14def98a1bb3e4dfba4f372cd, + 0x1c0063fdf232c7cacaeaaf3243b4acd8511f8b784129c8d6a7fbaca45477c377, + 0x2de234571d455023bde68bbae1fb69b62b80b889c8c8099beb25adef8da9f879, + 0x305e6097b1a9cd0761e08a2509895f2d6ebf453aa7f3841bd97809cfa9a46635, + 0x2bcc7b73e56788e3f70565b4168248b0321f65d941840f199ca849402bd52971, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x1d437882b57028c88c69eab64507b2649e1705eb397a4069781ac10151eb2258, + 0x1af1a36aae7b181df7ddbfb34e34a53ae40e8529c224ec940907fdbcf97522e2, + 0x2785516123326658487ced2a9e864d2a9372df4a480d96a810f3ae1246840a50, + 0x27d476e2c174e2eecb790e9d96acaf1b17c675fd85f84923f0bd1744a0f700cf, + 0x1eb090499e37004464a5edf2eeedeec40e2c2becdb31426992f382a1e1197753, + 0x92fe84aaf6c1b773c1e9afa8775db02848a85bed444d4133e1fca601c6c68ca, + 0x104d16cb816ebbc760c4b3e28fe8c18aed972dadeb94896a2310ff9d61d44e3b, + 0x2fa387f6bb06f1d9cd2e78be84286a7d58cfd870c5c1e8315232361f2b44cd0f, + 0x176b64eac41dadeaa403f9ed5910f11a419372fd90df93bed240c8f79ae5c550, + 0x2ad76ba01e94f7bb8412f271b92d24ad2d7efe5eed06b0852d8f53a7700022b3, + 0x1a8932f1b4cfac9286ce27de3faeaddfa0733d07261297a38cce6399d96fc38e, + 0x1eaa55a6354586d0087e1d042859f63927cf27def44830af38905e3d876ffd15, + 0x34c7817421f2bc213fd6caced95f1cf9b176473e8721a100b1b6eef4348b786, + 0x31efc323d83d4deceef06774dfe798dacc4c5946664b0431d54e67acbb840fe, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x9e3886c90029fe260f4a2fec7d2e1c9a0d07abe79ea3598a758ad63c20e807, + 0x1525c95ae08bd592e2e428803d4e6a493016a47943488b02a78f2d552d16c4a7, + 0xb1011a90a452ee3a6bad8aa9e4885a62472da29771ebb98cee7117ba1f0e77b, + 0x2fa5ca0f8d2c52fb2b4578e1efb6e1a77fffd1bc525809626d3535833c5001bb, + 0x1db0397e4ddd02c509cf2ed25df7b81dfc5ae489bb9415ccb7127a205d3e876e, + 0x27a3012fa6ee7c193ece6fd7692ee96b8e4c89797792262db8d6d1efd755dbe0, + 0x274e23c2c097373e9a0d952f34b70020e233fd2e0a67c4e20729a5fc17f88c, + 0xaef53482e7e1c25fb664756df6ae69506b5e7aef718b3b1486aec64c4078ab9, + 0x457365cb68df73941a3ba80edae9f25aa2250e63cdd3a3b86b031cca2134d8c, + 0x1ca262a197b5402ad0640e919508176a3988519d3bcf91b55930fed1fc89ea20, + 0x2131c2ae4df6b479dcf26ed81a1ecfd47e351d7dc790ee906dbafbd803991c4c, + 0x162bf8864391b12a2b1dafcb658fb94cbfc90e0bddf199cbbc66564550036827, + 0xc7a2f06399f8766bbc313a2f1fbda042eca4ba85734b4040db27cf4ac1e8ef2, + 0x2f9fa0e3320e9ac3cf702f8750b5bd1c71c697a583c34cf417706738314eead1, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x9f933726715613504e7cdc8700fac64aff61cd1899b4754249b7e61bdba19f4, + 0xebcc03b0c123f471bf2e57426211644f0098aac347c81fd12621c7187bb787d, + 0x246aed0e85ffca6527d79f2e223c37b5d7df029c52d38b340bac3b2d3e2257bc, + 0xeed1e00ab5b0ecbf337edc63d27cfcf9135997f860f96befc4198c56e59c72, + 0x4df1a4aa55992245ce955d325c1c08a841f727b9e9ce11cbe54835d575c56fd, + 0xd5e59bf9fe7755023aaf344298440987786568aa06aa9d03f8a33f70b227fde, + 0x2ffe56ed078cbe07667f7e48e1a360d4710d046f0bb51130f9b924eee01dc332, + 0xd13ed4075159b29a4d4ff4f9fd7d768fbd28dd4487a2bdf2a813540bfb99907, + 0x173512477cbd6d2a69801143d1e7fce3a6ce79cfe3bc2a2ebeed24bb7e6672a4, + 0xcbd4277bd737219d8739e4e818cecfb664e369782e296a56290020877778329, + 0x14588264fd7d1fdd6d4ae3e372417fc1ebd7fa434fb945fadc55ee805b81d3e0, + 0x14acd0cc6605c0c722a1d399ad5433d5450614fc3231d5af742ec5926c35e77c, + 0x14320d8cb13dcc09670d6e93819b69d7e66504066f9095ed4ff25566d3a066a0, + 0x1b3e47537a897026a989e433fb7c4eba62144a10781548577de3f370434b6578, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x263d424c886417f9b6ac1de0e2c1bb2e32b870fe671b11e8219760d1ae4ad0b, + 0x1545d2c32ddd1e1e37103adeeb116e09275624e964f6efba626787ea0b1089d, + 0x287183d246f54265d2283b5bad5c4dc4ff3e5765025efb643ed93015c1de8a71, + 0xbc24a36833b64ccaa323f7622d1b9bedcc204bf19b7f83be4c62b8771a2ecee, + 0x2ac5f667d34cfc3cc80a3788402696009dce7f61ad3483b54de3246cfbdbe164, + 0x269ec95973b00d3f96125e7daca220f7ebd6bcb6f08df2d39301ba36c6ea4fb, + 0x1bda71d6e900e79196f126cddb042592ce1b6c0c0b92cd7d86bbb8613c2ee0ef, + 0x2dd51fa2045a74f10e86b8301210f5acf7bcfb7f40b8d984ed23a00e3268219e, + 0x81f8b7c05030b310ec5adfe7f6ee0efc0c44b6facb8701fb1aa3852aaa29db2, + 0x12cd7c92b7efc7b50810ad410dee511e137f3c995e4b8080e98902c5c862452f, + 0x222b991677686866f2059fb4d66bd16b9f3fff5b65df7c782747dc0bc7dfefb9, + 0x171f3e3c2562f120982c7dd903d7b74665f3e8d085e398dfc4d7f73a837c0ae9, + 0x1b7b4bd3c56e17518b850f06f15341f6e610254b420dbd4873030c0f309c3c72, + 0x16c84ba6c4962352d3073fbefa9034f5d7d1035773e84ea47a70b5cf615c7147, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x3928b7c1f5234a3ef4caf7d19b815c0ce64a8e8906f2dcac43a5ad59c24f14c, + 0x254ec8b72f52e44c83734b672b33b630e8931d1522f5b25c69273784b997bb46, + 0x17084c1eb0e0ce6e4baf294ce40d5b24ca44b06ce6551b90d9f0ef7a5caf4339, + 0xc57ca90acee1624f9315266c48c653bd44400b9424e172953f044338a77b27e, + 0x5c7aa15848b5250efecf2eefb8b6758751f0e69ed1ece426fe6f85666b6a5a7, + 0x15ed7d3733abe5c01bc9491e0816d11aec10b0dbfaa86fb47279d7a1448e20b6, + 0x2fcca33e780707db84102f6a8f1e9a652874845769918754db5d936fbdbdc5d5, + 0x2d23b90c995b3b2956fbdb6448195ed441e717a7895dc1e433815b9a8077d315, + 0x138d37c5ccdfefe044ee28894bb422f29e9f3860154ac2ddefdc900bd5b1e2ee, + 0x801587f5637bdf253298bdb8c8fa556bba51f40c6c4713d73e31a0f0e72ce6f, + 0x23cf40715c260876a24e43b5c314c2a1cce16e1f412ebcb0916f2fea18e5893d, + 0x2733d53df2ccff16c87efc741114e39ebbaeff9f12ba0376b931b402629c525c, + 0x23e801d5f635e9af022f077b1a43f877db7241055d3c71b771ffa75cf6eee4ad, + 0xd094fe93f2bf4cd4af61d10a7bfe2b145692cb94337ecbff9c91aa88ffcf890, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x93b40efe6c068bfde4c0c198171a60e496e1d834c28765c9afda090405e4a56, + 0x2305950150a0b9c2cae71061661c181c1a6b3d5c87980b91ca959450e5cad30a, + 0x2107ba64be5e7797def29bd72b72b8bf0b1428062ee8902aaa58f0676ed03aed, + 0xed4b91b00cb5bfa594ed5cb57d703424a8f2dd9daf5f54f6fff74e5cb0198d9, + 0x2c7df01a6a701115c6d07756e4e0359ff5191b58300db58aa98cdf3c985252d1, + 0x5d54d23f2d684e0c609aaf56ce816de9d5871924ba47ea7025885674f2bd411, + 0x248f367c66a05a93adc27d36acc9ecdaceac63385cc5389d01a8d7bed9388525, + 0xef717b148e289194b332dec7ed2ac824317e40beb40d74ac7bfddb23d2b3cc9, + 0x1559abe59817b0a24492729506cadb87e76fb54f9214ac87346f8013c3032b3, + 0x3bd5cd6f008061a1c0b2da097013ed88d28caa10de0036904ca03a4bcfade75, + 0x2ba9dabbe0f9fdc8efff7060142fe244cda2d8feffe907ff23cc61c08b619da8, + 0x139f0add5443dfbe642f4f60a57ab2502a2faeae1b6f12e1e5e09b1909050fbd, + 0x8965484ff559d1e6864e3abadb5d8dd402ad180059473b76e9bf827b7542463, + 0x240c21fb9f6cf7f02e733c6609f9773970098adc7e21b041f7486156b4f78e3c, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x151923a505f13bee4d368e9f471b79b499975b00aabef8962a861e7c858f2999, + 0x20f6374e3f28e5665b4288c722551c898eb41fd64f2878b47ffc9188812c1e3c, + 0x1f26fe05c0ecf99843cc88c28bf5c7bb0f744153fcb405c37d4c9e5c60dff349, + 0x101a3d68872e2a2174e1e73cc53c3034532ccbfc8645ba9bd17744a0a9b7c7ab, + 0x1015cbc312d356c0ce96131b59584b0794aa717ea120efc994512c1dfdeb4226, + 0x1a7b53d07ebf6963fe87166c26f5c041019f2210f4eb48383c9abe98a35c3c77, + 0x8fd8a0e2a1df82e44da83d916b870960f621aa62a5336b9cd0bb124bd30ed8, + 0x2c43cee66409ac215740bc8b1f684999679b5e240301f8030ad3fef640e05c51, + 0x2c29dbf22349ffb1635b0182ea7d3ba41c0748fe4bf06b44a401cd15eb0ef330, + 0x1c13b6b5651a6d7f3929ab0946246f7366f5addc9d360bc5ddce3599638a090c, + 0x10171b916d8a14075abfe7c468b01d239c7043a8f97df103701e716bf5a73f29, + 0xc57c3d6c68c9d2da843ac9b37adcf1c46a3e0eac7c42fda4dfe0ce5c799ae5d, + 0x131e361e5a8725d01e57c3c77bfa27d1f3329533b82ef4b01a1ab3ddad098856, + 0xfd9e076ff4f5dc71afbb2743c74f080a43853793f8f6d80a93f3cdd39012fa8, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x1573d9a6d17cf8af947c125da5f9f64516344307d15be028600d7fbbf3a99080, + 0x2b6645695f714c85742f738822c21a26c8906c1bc19f98e0c34cd1eb463da48a, + 0x2fec770ae63e759af86d0742b049eb76e81d45f6807728e66930d00cb9e1a404, + 0x24ed0296e066560c8dcb239e7e7f39ddcb1898e5836543f8e98aeccb6f6144fc, + 0x1ace8484c0d96d050ade091dbcf0c6cd9bef86884bbec6f8ee56ca5ff46b9325, + 0x110a7faed51892c73e54c654f2fa35e47fd2647d90d6e5e5a8afef6dda4da73d, + 0x1491aa7f36d89ac133fa9992990af2913b71196cb0d0c3511c34aa52af7d4fe4, + 0x20cb0c1cd1adeefa16498b4673c4596b37f34fdfe83a41065c1fab66c42f34b5, + 0x1ba292539d1568ec6a3e2615134dbb5134c73e6b14deca4c1b1a993f9441c830, + 0x21bbe75d7c858ac948623d0de8c35924f28f466ef62a7a473d6a1b4f592a007d, + 0x1c96f9fb4c6bc33d46892d8826bd0c2f24d7dbbf38d9dbecf09e77f69bd701f2, + 0x12d33ecdd6482928f8aac0987910bbc372ba2f107d6e2a25fee34e82f10be2d5, + 0x2c1b610ce987acbfcda328fd40b56c209b6a944bf5781e3a77d1af9fa30baa6f, + 0x2d77c3f420a31d59dc0cf83c4518721eca03f4c8913fac371b553b966cfea46e, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x1e081cb9e91ff3eb0d111f2be59f4ec3febd9407a69ecb0778d7355ed3048ced, + 0x2e0888b957e0fcfecca2a1157dd74cb01a1d8545d15ca25f937c554195da3c9d, + 0x14434487e62089ed7659870346fb4acabe0f9f9ead2a19657a88cac39f773bbe, + 0x9299821c0f470cc59fb688b6e57522d7f57aff1e589dc15722869ede760a9e1, + 0x1f1ce2cba9b4c9aad6bcaf3bf03f690e267acf7e335863a54e6987634279b9d2, + 0x199fab9479b7b342dfb6dfcd8adcdb5ef8cd9cacd897ff15a3445379d86fd826, + 0x2bcff4e8008af4e04f02c3373fb37247aa873ce7b7caa35030fba7360479a6d6, + 0x3b2b37e288090ff11cd831c00b9fbedf6d82e97540c5607b59a1a5ab4e305c2, + 0xd3c39eb880cde63d9a4fec82a68313c912a25d4638a1f6177adf9d841d3d84, + 0x121da38157e113a3b3e4060acab7e1b40b36ce2e2a677e5bef5abebd6d4c94b1, + 0x1a5923736c007cdd31311b26d560615fadc7e01e86240033e1f2465e93df234a, + 0x90f568d806c5c4b1b5e61542ba122cf1f5d4aed3966c26508d824c3228e97a0, + 0x20d2b7987c326a68610ba3cecd0b4dc54c90390df012b7d96170d9693c29cd01, + 0x3020b14b8e1529cdd9289680c5ad441627632cab08b206759d28e76a0fbfe97, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x1aed16276f89ca766d4502fe21ccce046a63cd2f7d44a0aa8770771e2f012eee, + 0x29a61b71b5a33237899eca4e7f4e40d008c97a32bbeb0c7c09d8f24d6ca574c6, + 0x301dabbfd4bbca914d16943cbbfc3ebf006988c86b054d6b613f07ae1d092afc, + 0x2a3c6d1263e470cca3ae533107339b8dfed7700c910039b2b45b2bc67575f9f4, + 0x20ff2a6b8212735ccb82ff59798862854e3244244cb0566f5d3d59e341aa36d2, + 0x2e5dab75ff69d4a42e745287c98107ca9c3e423dc6f41096c039eb9724b8252, + 0x2f0f8690c7cd4737e913653ebd84f51d5f727bb6ec729c78c42972aa34d6e4cd, + 0x2be6c4a5efe483fe0a737eb77df7815a6599f091f021131ef37fd192305c4c53, + 0x2f18439786b79df3460f437b9fed74ffa5d899e2fc7774ac78afd1c75d7d98b, + 0x257eb2e8a7939be6bfc59d3fc6fba75da35049a36277c37513de03f6cae91538, + 0x12f8298c4a68070f15caaf500879659d02c3aa9b771106241917cb6638608133, + 0x22aa263182f19c8abe727e87a2291fdd6af7014f5ee5ac6c198a108dcf02f539, + 0x14cee2715a061bc708337507b88d099267ffd7d71962eba1bf7d2a117106b111, + 0xbea09b03b5e03d2565e9b4f7c43a91ed8137de6dfa41f70ec7b24d58eb7b1b4, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x1c01114013e2d2cc0f452ef7ef2b20226cc69e57b028464e95228e951d1cd855, + 0x25c7e0412d2072062684e96b656c4410dd5d77f644c64b1b1c84ad5e882cde60, + 0x1231e9e375c85c424c5fac79600e91904f849b8fb71c7ab4c37a7ae58c17d5e0, + 0x7a0a63d6b544338243ae9c846b542b213c67256036a719a44a451b8e621d846, + 0x2894d383becca5a477263e188d30dd81d7a41e56ef5c85c10d97a309b8daccfe, + 0x101c0e6bc868c92f99608d9839fb6263313c2ae6efe4d9efc642d577577066b3, + 0x1d2a84f7475ba65bf319106ab571e734611e0aa742df49e03c98814c215582f1, + 0x2d2913e61d8423d557920d0a4ce230a35e6f45df0092e1af389d420902295e2b, + 0x1eed01941020a3099668dfa81b2a57c1639ea6c61ffd2cfce89f696e78023df, + 0x25417306ef421d8d0a06515c241b62dba2f16368b56c0a09f876850c4d008621, + 0xbd0953d640552207b0df37f4ab00cfee2f4585286e008d53eb0124464fd5506, + 0x29beb31dd4af45a599dbda7e3014c88b4b0173b369e9674313022ec3c39d1875, + 0x25305ba821d4ecca68275fbdfe54f068a8e3b5435bcef6b7bc4a8da67f912917, + 0x1bfec9a5d8a1c5ed86c4e7fdbb6b96e302602d14f55488b1b98644e612208088, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x177f31701c5cd86c2135c582fa22d1fa1005ad148e125c80046a52f99a278a07, + 0x84b44037ca846dc363a64737ed25eae81e47527aad42c8b860d2f167fc86299, + 0x5db3b44bdbc42b1b4f26c99fe1a2cf645f28e6ce71253d92a406dd86a607bcf, + 0x1878ea943321eb7644a12615ea82860ffad4e28428239902a7f4fb2fd33464bf, + 0x124df4728f64270968bda5aef3424393b51e84bcc672db75983ccca6e6efb12d, + 0x23650e1dad9d21e3b5a1140b178f9d57e838a0938bdc88ad7c23256b09624fe3, + 0x201a52e3c2b36532a496eb42060c6150fd7dc3ac2db72df850c3a2e3f254654b, + 0x1f4978ca0763083af095848af1757750ea81d782d96385665df0b60121ede60, + 0xb98fdbb00789a5b9590ef157c1907a3e9bd3cb67887bba7a251b58cd45867bc, + 0xa497dff0328c9b639bfb1f441586b3db11c09773623bdbc12c40ce544d90504, + 0xeb016dd39c878c0b09b6c6e86c6527f9cbdf0992e71d929855f0d4525775008, + 0x18efdc04259cca1130aedc7167097d26eea98c38db92d699f7140d3148b782a1, + 0x126f37ef258caacf14662c6e1f6df9dc4fc6d1792a17be1af28439b6b7c98de2, + 0x288928203b020d9e6a57ee9e15ac29d64e2777ee080493070517c1a3338cbbf9, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x296ea4e3760ee3d1cbfabf9cb73a506d7cd78b9a28ea959e977d056cb07185dc, + 0x9a7542033713ab98cae7b350528046a818dc1bc4daf2c2119d38abb2e0877a3, + 0x3034706ae9245292d2aef241b738bd3b0b211757e4c2e0137e2c65c1e3c67d17, + 0x104ca211af2cb44baee1525e9c4887c1ca96f2d147148d6f8d7083ef975b4fd7, + 0x1b523f8867ec145c19ff50d4bdb5606c20ff01ab3bce0c0768fc28a4a3d595a6, + 0xd5edeaf84c1e75e0d4f670c09dfaa070db33640e744336c60b18d1b9b90496a, + 0x5124b407c8fb40067ff8163af388ac99b168031ecc22aa7423e756fef6c962c, + 0x8ca29ea50b36354afce9507079a06f06753a3e21362599c3b72d542050c49dc, + 0x4c3626ce2dbc4d64f6ab695c59f8f51f383a183e5033700af83f83c3189c1e9, + 0x14bf66fe46f1f1180c24f16aeb7dec3f4ad00c1b6e9988c5642b549609b37573, + 0x67b2bfe7bce2dfbfeb90eeedba00121ed2622c38d4044ea6de739dfd5f75d16, + 0x9287eb9fb34d9ff43ebf373466427795393823f8d70c88ea76dbd7ac989bd6d, + 0x16ff59f0d679ae8e74aeafccd0714d966c4fe1936aa0c7fbaf8828168850524b, + 0x2051d8ce6c5dcebc2d7ffe11130757bcf7cd14283103d3fde53e7f7a880a8519, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x1d360ee3116f0744286da43406049bd1b821cfa4c3e823752c00f0451c942254, + 0x1f6ccdc7743ba72305a0491a306aacf4e3b036b0f0602daa88feb8fd8cc62cac, + 0xf8507197161fa267d0c68cd381d423f3880ca56ebd0d7ecec6ae88fa68d7a2f, + 0x18b4a57860ae5f6b5ac2d4f8c924b2bb3872dca3db783bae02da366fc84b7a14, + 0xaf716e6f1286cfdfdd93f1417a064cd76b1a7e2347d61d9b1821eb8a4ddeebc, + 0x14f128af47080db5d122ae1a8bae27475c1933fe73cfe2a80d89380b2147915e, + 0x1f2f97cd81cfeaf9ab80320e688f2af45c9dfc4a74f7227c7205fb05697ce2f2, + 0x7a985fca61c3346a08e8fc31167636507b13885850b9cbc64798de9b76cc57a, + 0x280e7d98a95b9e3ebce1a4d8325d69f42ae8c7f7325a04bfdfcd531a70d0816b, + 0x1cce1cb692b8c6c02c7b6a2e20d1fc36f031bcc44ff6bff0c4abb5b1c743af5, + 0x2ac9fd902f4b6bc5f917228507b403859cb67077ec2beae84ca18677858e5686, + 0x1b69cbf6f6bcec50e71597c63a62a8253a63412612ce4e79b262753831b970e, + 0x981ecb674c4f9996a0f8f019d64520c9d933ad0c6375f17a643430355113cac, + 0x14faa8f8184c8aca46363826f864877722020035970dbf1090d4d3911db9a9eb, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x1a6906fda19b094b2bd4def4b25eaf4d799cf919d0e1483d9380180064116cf1, + 0x1ab6dc94517f1a235d1107902b6c034b5535cfbe94ca9096bf72330be04b179e, + 0x15669b5e4dcd66cf29b6c06a9308f8672f88d069e7e8eac7cb11808b82913038, + 0x132f02aebee7db7f69fdb68ca8fbd57f387664e6420fe20060941344fe5b63fc, + 0x46f52fecf6e77a95b31226d34954f28b9d0e2e8008de5b3d11c274d7e44fe1b, + 0x2b69ede24d4e37f1a8c1d58edf35d0a7f9a0716c3f709cfe5cfa6f069fc7dcd6, + 0xdc2cca8f0d3eff4d287722ba1c50b9062230d5b6c748aa4d7003385ec5424b2, + 0xd1b03d009a6a0295cdbc9f23ef32bc2933f30a8baf2360203ab064b69388339, + 0x1a1972438cf29f99b6802d9a1b24efc501739c6d7278a5f30b1667c2b7bfc5d6, + 0x203dd92f30579361e8ecfe9e084cb41cbaf7b93fad6d7f7abc9d0f73fba44075, + 0x9d6f86adffae5e4fa6d5dfa644e97a5b382a1c7e90514bea8ecd1da42773380, + 0x12d40572e1dbe47334a16c73922e7c4da9675a76d5fe099027ba003cee8f2b8e, + 0xc3c34e73158918b72653147d1e3d059b256c1657fe50430a778e63f6140550e, + 0x6973060f725dfae61acbcf3171f17ae957cd862e86f9fc6a47fc7ace24a8867, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x1b3a5512b18428893b48c2fe915756e7cc7aeaa8ca36c2eff6dab81568264de1, + 0x2ab9670c18ff8edc1c84c1ab36ca686990f07e16b567bf9642165edaa5a6346e, + 0x10660d5082b8fcb7f5f4eb051f926e99a5fedbd706fe191bb18c26d34be30763, + 0x1aecba1af9b70281bc2722c0d82a097305c208a383c68330a1633fe3b59c94a7, + 0xd23a06e79761902a6ef30749c86998c3d20bc827cfbe2f22bba0f484dcc04d7, + 0x282b6bffb062fbebaa4772f808780b00b77da1c52fa648bd74ae0ad49fc62d9f, + 0x27d48b15b151378a1e738977abc4ce2d8bcab816dc32797ca060ee009ac74444, + 0x2552efb9ecebe9e17a82574887359facf5cd61ab2ea64bcd60c50e053124376d, + 0x2e505630db4463f1d226d0e1fcc5be4ce4577e3911bd3262317a4fb32d7f8ea7, + 0x1d85ef93d9f0524c0d579400f62d8fa7f6235c8631bad07509d79e20db614ad7, + 0x24bac63bf16607fb32c48e942d0cbec8b7fb18554f342d6973a6fe3a309c6248, + 0x2403a33705855d9d4456779033eeb1938e9c9bcedc4f1b28f90c7fce3e4f39dc, + 0xe661908904f5e530a16e3c1184aacd43ecbbfaefe6b55899026b9fc9940db1b, + 0xee6336e66fcdb3a64d86b979baab0bd235291bdfb213ed532aefa0a72e5c3a8, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0xbc63f41651e844c66007421b547d69d694573b1343b8583aadeb8f39b9c5af7, + 0xe5cdb3465f12743f71ef5f504e6a5927eb824266a82bd02df035efe08e921f0, + 0x1a0af69734aab2e4304d15e7a69b2e64956b4214c330d935647b2b127f6afd94, + 0x2144915f6e6f829e7179c5c005ffe6c9ee3a796e32de5577225696a77e7c381d, + 0x24b6274d2f945bda6058c3366b6d91e33740897c6e6f133304487b63bf0ba435, + 0x10efc44751f6ba491452b84a92594336c6ff4012098f9fe85420242cdf082baf, + 0x36ebc6a6fcb98eed5d0dcf87239433879d99acf6fbdc570510ed6c825055dea, + 0x17a1b2378fea94d0b1a96ea700505bb45c4318c9b911949a7107414f636a91cc, + 0x2e455a7518e54ec2e0fdcdd2821e488877c594f854131e6a9aee732db95666d6, + 0x1e7397644ed4f4cbb8e931b0db4904f29102b50a3ca839c43ac4c0c399c9a8ae, + 0xdf88ef1f1a67a39feb725316726c97b084981300a496619a38d3fefb6d362f, + 0x24e11fc9c4c7763829d801dd3a205359bb3792da2ef8b2741ab3b2c54acec8ad, + 0x4920b3e800f77d7cc99d8ee4d0141a45d27929e6e4a7d7bc4193ae25ae82033, + 0x20ab7b6abd43a88f684217ef931c13cc11908564c8603e01993b0e277ab29f8e, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x10f8a59f8273eacdb9154a734653e4ff7fce0da404f36b2fd001b3f077ba68b0, + 0x1652153e375ecd237c21acdc3f96d39088fd656dff8d66f867de878470fb391f, + 0x12a4756111ec068e3b9c4a1427b09f9a313e018d831f7ae5efe9f3f6c61c13f4, + 0x11243b19f113241477e4790f89b8ea79666796ebaa31cc2ce3700ff51ed3cbf0, + 0x93d6ab40a9a4a3bd74f097120654c82fecfbefd1067f73ba5aaf031b1c18c35, + 0x2f26911b23466c23bdffbb8aba815752b6d0bde3d12088becad0b08fd1dc4976, + 0x1a03dabe66a3037832d93a1c3c33574c5b28787fa643ec5149830f81ecc92bda, + 0x223b10c2c547e1a2ba41fb918bb5ab602a9ff21a19c37c157ffaebc95bac4870, + 0x1f271876f17d7ccebb222aa3da4cc09407aab4dfdd453f1ddcf248631eec1088, + 0x1adb58add70e22de5100c3f187057e930c9d122e128c3d1159874c304dcc1090, + 0x27b3f7ea1e34373d8183be5e462f0ec51d5d0c8bf049a2b48d30ca821b368afc, + 0x1e5ab69a6f006ef5ff38e49fc34b58d101ae90bacc8a638c353a636ac6e0cc6, + 0x14ebbd0ad1f23e2c7af18b8c43a41e86492189f38299783c3edf8e9fa8a2073f, + 0x939c8f74cf317552b74f7ad2ad5d0accf3e02ac3b9e67a91964539bcf09295c, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x1a55cdf6625cb645cd6090c3f525f6e297864a501041dcbcdb37b6f15af7e36a, + 0x27af5f96cbc32f217ffe217d4d478a315f2095286d6589ae3510e847a7741009, + 0x2210a4f1e6607e23b90a45345ccc56984bc8a6256c661f04292b78523bdcc7e8, + 0x21f9fb0fc7ea61cd6d0ff2d35785d6e7d15c7a9cda7cbd3e39c44166f4b175b4, + 0x1ee5d14567c941c70d07adfb6dd50467eb0668b7bdd1fce1879bdceeb059f94f, + 0x246ed97e4eadebe50c8a0afdebd6598030f27e87b89f0bf73090da4d95f12c63, + 0x16f44dd900dd9f274617e2d614733244838171bf0c89ac30256eeabd5c8ee945, + 0x1e45e42c3dcea63b20518075c16745af5e20536983b16f632d3c15c91b3d7d16, + 0x19fac5ce0028674ce8bb40058162e50f9f9f8b8905540fb7722930cbb20112a1, + 0x1190997dcdb0f5772ca3de8b876a4be62f8ee0b39d6c233c95848d073a8ed6a0, + 0x96c7db7d0085737934ded26317191715fa6c789de3df7e68f00e8af528530f3, + 0x1c21d771cd0338f0c0c00ff71e4af2c1d7db81922ced098fe6989afe7d1e4d19, + 0x2dd43d3c40b768f5625758dc35668efb3ba747347d5ffc980ec0b0cbab709c8b, + 0x1030059f96d75e04bc5f81b89fb7b5b0fff0361adf04c4f0cede89630d2f037a, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x1635019295b65b0190fdd718927dafe4c0c965772665800cfd539d559f0900a9, + 0x2c17c890b715b3bbec14cfc8f060ea84d7c12df2e51cc1e8a6e987f45c01674a, + 0xc8ffea42dd7b206033427a512377d3054fe4f8f86357aac58032fa2dfe7c7ed, + 0x12fa55dfd670309af2d98c8de77c302a5ee4ca3eb08b90f27230f05ff4287c7f, + 0x9009662a5a28a89ae9d6da9b3981767d2cced18677e42773fd4334297d6efa9, + 0x25caebb5501e77f1731a54be0e06f8c005176127f3556ddcbe24fb5804e08206, + 0x195e006734786e591acd92fd233f784503f3fdb5db18299592de56d770028a9, + 0x47885b986f4d10ab44463042a0bfc3adfa3bb9b553bac96ed40f616291bce26, + 0x930f3aa1c5410395f9b17a20a1753b721a0291fda6f32bee8aaa6ede298d720, + 0x24af63803104e8318c3e7a41cf8027ad36a631ea11d56552bedb5f00239f902a, + 0x27c63e725d17d9a44f47fc73f02d7bb2150ba0f6031f004e600ce008440aef5, + 0x157270a74e4ecc8bb6f976c5bdce70912cf64fe9c8816d62d42b0eacd9514dab, + 0x2190e7e822c0508c71e3ab7134fd89a40775be99a1b38c2767f6313835eef8b0, + 0x234f3cd5e0cf731da507c91ae18d28061082ae9aa580746149d1a48f6a8db2a6, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x1433fc6bf42a2541e40c104a24d5cb9d462fb71bf094bd998c85933874eee2f3, + 0x10a8445d83f3b7ec65128083a39f5c759b9f52bb8ce5c024be8e2d300e0cc652, + 0x1a1d8481d39a772911f9bcee025d79049764dceb488a8275f03a39870fb4c909, + 0x82dea281aa11435a7429463b3fadaa3bc680aaf49f02ee5c40d110f63731a47, + 0x13556947fd0714aed251e0fcf91cd0e8d0fef2dac3db4ff9f3b6c5365ee9ba2d, + 0x29508794226e7cb06bc170032d377edc210dabebd3a254ecd4df794d65f8cf47, + 0x3cf4fecc54b529b247e48048a963709b22630ce719ac8a9e9d1f8e74b73e702, + 0x16cc17305b3d333276a9cb43d51089ead04dc2f1e197fff0012d4c7c4db5829a, + 0xc36f031884453fce7824bd724f25e8fe71d3e640baedd9398a719d8f01c560a, + 0x50ff40107aafa9a2e30ea1a24b64129fe55da84a294ca8d0afcb9956ab09797, + 0x28b18039884a6d69dafea66b723072e0c55b1fdab6b247e801d6cdd52c7f81b9, + 0xbe18fb2749573c5b7b7534ef3cb0ad5651a801b3c6bb875fdf30cf8b155d8e6, + 0x2ed3ba243fb561e308a7da234e581898983172e58ce98d9a94aee5b6de925b5f, + 0x248eb1ee129d515abdd9f65a6fa7711b708374187faa61acbbb6d21b2e26dc7c, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x89fb8b0837e0b7c9598c3bb5efc40e62ff31e66ea4f5e51b9330a20f9d5e553, + 0x2c17324ec8d80ef220016641f18bb8ef3ad0d18e4de8dec2ca81215591dae7be, + 0x23c089339439d665507c0e956ab3208b27d643526045f4afcbe6364c44bf1093, + 0x32af6e9b670edec4744d9be16c2fb05dffd7742b035c5d5e34589f5cae382e4, + 0x13cb85e74878132b6a20784e3bf61df1818c4d6141651d1dad1efacd58774174, + 0x2db07c1bff2eeec8c5b9dbae586d6a9e7dff129340512ee92c27fe3acba78c1b, + 0x9829878aad19da18247b6ee680b5d3f8d94c0b046c24fa5641cc07813031830, + 0x1eb00d50e3b0c3ecda0b569d961583ba3ba49a3fdf62eab4137ab4ecd16515e7, + 0x1c92d7b2ab89c954d36a5da4466d4ce8fe3476cab10bc76716e6fa1469d3c881, + 0x29412e4f79957b5aa484f896baa95977808d2ea76cd61e0be6e705aa9c31c419, + 0xba6668da5d5bde10cdc9aeda5a050d864ee2f72f84ca600a303aa2f380cfef2, + 0xe3041c5fe0dabf954e6d9ab5519e5389cb3ed02301755f24be4c400844a019a, + 0x46f80bc5455aac3228986ff1910d988a8608cc8eea186ab821e5b8cb88a8a9d, + 0x886037252df484b3b2e909f79ef69e24c2b0f0a9b912d666cf624b888d7958e, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x1e5db2e40041ad9d844fc08e4932c2a893f14e107a68534c2f70fed480beedbf, + 0x2d0e5945cf1ff11b864b86659e60292c1d76e29a88d35e2d25007c3aff574837, + 0x5eda1c9de06b29e901b43f4dbeef95746bade9533d07a22b08ee2cf948bf827, + 0x92156bc60919beb0e2c262d9b4ca9c888221b1236839a25a9457b4d475754a9, + 0x20346a64ef27480102685c39833600f03276e5e4094eba2077457246bb5b0920, + 0x10807d847901c2b7ae90b281bf84af1645abbcfb22fec7626418273a5c4061d8, + 0x1a02e561e4e6c7e5c33b9eed477176c2927cd2331f07d9eadd6ec80d2d77c3cf, + 0x1a20365486ae8bbffe437fff696c78cb344622ae0d25c8b6b1b1deb62fd03bb7, + 0x10f6bc198813943da2300d26f081cabc8dafd92a953077575e8e2ae4b5b60fb3, + 0x1d7d5aaea8bfae19980b3c529fab08e7187cd71a706f39115ad1cf0b7f57f556, + 0x1df1dd45ad494f1a872a88240c1a9ac86c18265890d36f5b57f84a6db388b35c, + 0x1c29d88c5a7e44b8511c878720f8edbd2ec09956d2a47125ad08cd791a72a786, + 0x2aee9b55a2f615b6fbffcce84c652a3f41351fcda1b830ff3beafb075d0472b4, + 0x1c9ca1baa0f3d242d39a3ab72580877c176e28a5c887c004279a59b0bcf1e66f, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x1e2b6b0bf7b3b4ed5126b8e8be6b6b070efc28d062f8914ba1b5fc68ed14ee06, + 0x2b00a882fcafe8d43e7da424366a73da0b7cab19478446f56da7a29bbf24abd5, + 0x441070dc965c1abb15cc4dcd6668cfa56f1122903318ebadbe52af6495c4e9e, + 0x1804350e3abaa426cf301eb0241d2f1726387efbf0df6f0c303cd0f983997d57, + 0x1eafed7d64d1deab8a1b3ef80d833b3aae94efc9f89286a55789c6b87d637b1f, + 0xc08b894acdae0abb3e1c1f653a150d96e0666a92e8a6f732d8b438e2ff7e631, + 0x2317408517ec88bd778bae7b26efbba777aa1b4460c3af71cac88aa1d4d2d7b, + 0x17dccbe73f5a7b036e83f6233c651c883a7957861eaefbb385468785b5592d3b, + 0xa9ad70b9945cdfa736dbac21e4b4426515ed32fdf0476217415ca4edcdec1f, + 0x12b21302572045aa13728b65b9e6da2dd6a00b49c9acf7418d03431b663ec316, + 0x2f73e6061be74d0dbe147fc3de191cf54657e3516a60a6da650dca53c6d4b8, + 0xb907e76289b21473c0e6491744411e520896aa614d955fa3b7e73d25d4f560e, + 0x23c6f78eb1f358e4f34d7a1d58577cd8af362c8d7a650c9c70b7cef28c8b77b0, + 0x1fe537054dffac7ef4fff98a49f253a17562d32eeb1903ff3172e8089f88a5c, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x22420a556a4009accb54c2b2266ba65776d5455a7944ece37405f2bbb849e352, + 0x1ad1968f9921575a75470f22eb1f2e2e3a6b973c58e22ff30c731f97064bd055, + 0x2d709e99d4fc4d59e9dab4baad17bbd75d2331e8a448c2595c835e96ece5930b, + 0xe1df1d829c920e063cdff32342f223e7b4851df78ffcba180df460988e8570a, + 0x23c4fbbe1b0de3e8b57a6137c331e3b284504bbb9f20fbe9dc2b304194ccb264, + 0x2ecbb2ad59823898278473d8a768598a22d2be7922c292a964c953080ad8a690, + 0x5dba95d04fff06245d0f4ced407a98571bb522547bfbba6c61731884c4d4e30, + 0x1b6b4761d189d1e2db04e13f1702f4a15315e1b4061312633fbd2f7d9c943b01, + 0x1ee6c5f07a003e7f7cf05ca63ec2c5cb85f0137f55e1e62c81c9b4a40d9bdc29, + 0x802b4548da3f90ea8a49c26cf583724835d8add489da81917c17ff7686c97e0, + 0x1a3089854e45defe9e953808e58f14cd0f0edb9d65302732ce5450c92ca79885, + 0x2133779fb03912c1f1db22b59f3a8e96d396173ce7c5abee98f05119b914b700, + 0x18dcc23fdade276e5c1ba4f96a47cba57ccbcd1102fb8d063723523e2d819b39, + 0x2a1b87020f3b905940f757cee7f0b459217ea429b77a9ed2404cf9655763e105, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x47bbdc4836a3ffd940aeb2c8608a75fb37d4e0ed1929fa893124a87046333f, + 0x2fe188cebef3df8090f27fd40d4e1f557b2a13aafcdbd36d53cdb99ec48fa13e, + 0x1eefea2f42ed57d18b8bf7591ddfd0f54a4e7434646e84e7c79a15d2f879aaac, + 0x1394c009ab5cc43d8ea089286a43d30c904d227e9a151549bbb7f4d0cf930aa2, + 0x2a0bb922c5a36f42819d00bec63da58d50b6dd46ff20d2a3b29c1c2e1e0ff837, + 0x270b2526008fda515788b4e38ea86c9c9dc4d650ffce9638f91b85453deded4d, + 0x2ba1e2d2ebe659e779301d63ecde988d55432d5bd7f8a4f76a03e20fa31fddd7, + 0xf56832b7f06a8a3a1c287b8497ae10dc05f216917450813f21ffda4c0effad0, + 0x1959a0963b974ace1dbef8ddb09c9ccff9ecbf4dfa10c2c174d42d523098cfdc, + 0x148da04f0aeb03cea78009e2d1192865f5b99d630681b71ce71f9ec05ed55b69, + 0x51a40af416f4fb5f9f0f51faee0ae6be210f9b93c4ead16f2c9a96a855c41ac, + 0x20973f1fab9890ed48723af234150d1ecca066629dc1d07031c6cab5e60a3efe, + 0x2a28a24ef1bdd75a7e501a4f035c1b431f4d7554df5facd800ecd3f024ec8152, + 0x1d2ee4e18fa1575fb3ff723b3f9ad35cb0997b436f85746c6857882068333148, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x2629999fb52514197199686aa4c0b0961d8aa48404241177e131bc2396fda732, + 0x1f99369d70a63bad0b76652ea69f388fa92ba1658836fa3aed366744ececdec0, + 0x4511f41649be85e455ce74338ebb425c895f88540244a554c9947bce88e6edc, + 0xb696f753615462876b9efe2ee1fed79c49becdcfa3a2d0d04a29051334ca110, + 0x214f09b5557846662636de4679dcd965611c3d78e8d50a2cb0589c3ec90c9924, + 0xbf5835b4c0bc4b13a3dbe0fbd68fabd6ea6749b70450547f0c2e3b658c01301, + 0xc48c640e88a6442ae5ac574221d7f10eb2e67ca30fb0bf169cde004f4ded504, + 0x1a5935756b57bfe02a3efedbae26e5a13200bee0994712005589ddfc1ab5b8c, + 0x386ba86a06566ae39b56cda79580aed0647b9636896a47a7e0e9aa9919d9c02, + 0xf00775e400bdc3e8685b204f07964e28163ecb3c63165d46c3f463e7baffe8, + 0x1a662d8ba07d915cf7504cdbc01ec2a676ed76347ddd4e07f370e249a7b8ea5c, + 0x1f06133283ad793171f99a4e8cbd2cfb465d9d6af9ffb4592d90293421750faa, + 0xf83059507c852c9750d5280c440af49da9bb328ee63d1daceefd0becb214fda, + 0x14d1ebfbc4c284f016134d6ab56daddb4e647593caa1324ecb302a77ef0b3bd1, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x5d4c4270c1e940348df545abf1e79bf647658d2e79eacd5dcbf97d68d05f3ec, + 0x275db6ddf370d2f7e21020dfc1106254f1c60fbb7de07efeec3d6722b04bc54e, + 0xd8e04364c5a23a60f46b4548459c7e7c002b73efa630bd165ab3b6a87f96489, + 0x17f1de99ff5b961493bef67f162e464c42481e448122fa5baecec8cae0b2192, + 0x23da50aaa25b76f0dad9f50db23d12f64a4819f547027b6bf52768799362e83d, + 0x6d4ab87edb0fa0ea037a4f5ea1583c4198129f067829169c06e7440f354499, + 0x18ff576eac16541cea173c61aeb541e0761cddbefb4a90f144818947d16013aa, + 0x1408d644973d6502f93fdd2f69a71093a9fe50d7f8061acb474a0a14ba304f44, + 0x29e8f556928e09634fd0b950e5bf4e90470d45e3c16b13864d598c555e57b1e6, + 0x1637adc0e2bc513402f3a8b5314017d7ae192c809c41f3348226dd50ed82542e, + 0x73235d0a9e96cf86e0976953988a3d9a260ceb59ba7633a40cbd7fede78a51a, + 0x6dd5e9ba875bfe6f6596ba3cf35ec2342bd03422f134ab99ab7dddb9778b830, + 0x18f491c6c3b12acd06a117563f067440ac753ec468a5df0c123498fbdf0f143d, + 0x2d09fae126d15952c2b91d311932c93cff8cda2b44ce74c5d1d6dd132f4cf0bc, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x1022b57f4ec134a8f7e574fb62093d415b876af638133d32d366a9b1adf620f0, + 0x14d51a25fd8d1dc5c7720bb793a275d83d812983965bc9b05d306794cf1dcdf3, + 0x2c6a7b31575f327009eed05f25f94a4f173a544a0d8fac673474177b3b9a1413, + 0x304d2a4701c43333827db71975d9c2c4e675056a2ea1e9b72a0eaf127b25efb0, + 0x11f7c6c76441a67bc5946687a40a28a6cdcbd0ade84c389115b744115c627fb0, + 0x9a1baacd8b557f09fc35e6434ecfe9182a04537171ee1d2bd603f5378206804, + 0x8926a69b2d5a4200ee36f786770139781eb60a7d272d31406b75104efcbd3a1, + 0x21135de3337256600fabf590e04c29c5e0875991a67d17eed5f5131c567bf4d8, + 0x14b248fabdbbed0fd66c899e0a801bbbef4e1afc9bd0abfef471884bfa160841, + 0x86e20d28f53332b9e09c5af815694ff83f10f379937f09105e98529fd4b4b01, + 0x1271f30b82cb798656e4465c44a9ff204325f5fd2d2e204f2b5673f78fefa4b7, + 0x2224a8d0963f1ac4f3e85695e2692e386a3c1492aa58127086e1385b9c2cde80, + 0xfae50434b1bf26f790caa16ef2562cad5d238130522db3a97c1893b0c81ffc3, + 0x3f2a142e4084164ecfa6300a4be6abefbe155f5ad84a684f761e75275926052, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x274d4d833700eebb5cf7c8f4fb81c174a108932a0e987d2889d9b93a95d187f4, + 0xe9bb8c9f9306791b77582a16c53947e12e0dfed0c2adc1ed2116dd451598821, + 0x26a098e91130e0d10603be0507dd975431923b338b6c0a3890fbb815af28f7b, + 0x26d653ce08eff8f162c1033b52ea7e67ba0f6a8036bc64d556a75817579698a0, + 0xa8ef549b90bbf3af6d9fb4db8656b7de9cf14212989422778c52691a0ca83f9, + 0xac39f4fce06a27f59b5f434e7ae2808da542d1cd5fd18bb4b90e4d15598676e, + 0x204aed1de3b314f39afe27b3b1bd589a851183aed39cb3004e67deca646266ba, + 0x158cb2e73c4aec4c054f1759e9f3293b62ae5fdf18f69be4f6ce1c65cc1c155c, + 0x13040aca2fbe7c001c14ad386c756ba465796b9ca677735d95861600b3ce6b53, + 0x2674a9a8dffb96d38295f6edd1c5c008e9320ac1e99672b9d05289ce45fc673a, + 0x57be234d78a86ab47e3691b67a63266519bb62985701f2072494d6343322a41, + 0x12bbfac6aed9fbbd81254753e8bf4bd4c562e4af62548e577ebc973f77d9af77, + 0x103b3e26bbc4767aeb96deacd771b5b694b4d57339e351c10507f61bf55d915, + 0x5f918dc84cbd6a0a32a65b188e3f1c6e3412b76230fc7f6e5b17612c1abe8b9, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x28e6b736e2337dc438ee643098ef22b69c869252509d605d6799ceacd28d6cf0, + 0x17326264714761dfead5cf52058e2559b4c57d30fa68b4162ab616d4ddf70448, + 0x26d0b9ad617c87b600e3b27cb797f4b0ded965500a6548b554d2445f49cb614, + 0x1a57505d738aff598d51ba2c25a4ed8b41f9479332bf95c4a289537dd22a366e, + 0xbc9463f62daa20f0f245379c9b36c48c26b8f2e7d393e29a3ab5e30539764fb, + 0xd2de2c5e221a927d1e90617e8be308d83a905bad2c5a5b29ffa06186bd62c96, + 0x2acfa6917c256caecdfc13513b404367163017f92c68314e4cee7c465c016bef, + 0x2300a55d94c34ecc47785790d4cebb3ee14f43f36ed26b8a69b1e7641f5703dd, + 0x1b18386cd94edcc53b5fc04a4f6463badb0b6f1908c53765eb2953449d3bc3db, + 0x168523fcd8de4e51f21ffaeb5194c5882350e2926f76d76b4908d3e0932b5ea, + 0x230836236981243f35eca0e25d7c73c4aad7b8b0375ebc53200c5a169d1ba5b8, + 0x1644931eb3e15ac27e176ba4a0efa23a8cd2cd0a495e0ff1459ba562c39f74a4, + 0xbdba47f648104678694d1dc3e485f87821387d63b40b643681f6920ee153dae, + 0x2934ee754f94b9cda4b4193c2da7abf8854286bd37ce1d10faff250466663729, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x15bca736827fe042d7bd64f77821bfb98ac7765effc787fda6427a9c1a3d7817, + 0x1702aabda38575c6034b350e4b88a2a6ef6a5bccaf04bc9f99321753dc12b1f9, + 0xfc69497af71268ae3b232540f8c9e5b16fe351e779646f5cf34bf7d41893078, + 0x13cf63991c3ea2c423f0069eef61d41d30b7a6d907a6cc3f723b241f676131ac, + 0x8212316344803402735c663b23ffd17261728f9fbd3d91b2f86e227a34cf2b9, + 0x1d76ef5ad83cca5d452debe5dd11a2a756924c26b546782299e7c9b9e7f6802c, + 0xff4763e1cbc755ebb7308094877f3ceb4cb0d393e00545eca169da0f82c6c1b, + 0x2ee17d2391f5e2ada6745b0a56c5b2915abb69437e28975e466d218efe4346f2, + 0xcdfcd1cf5fb6f404d7686731a9a326dcbab662736555ebe2964d81d7929c86, + 0xdfa35c85f23318fa0188cd8ccf7a174e89b324b94484e9f1efed3be25eee2ba, + 0x3020e7189aa0392850f96adb46c8476a9d62951093438a948858a8bdc3400b8b, + 0xf7d3dc3a1e33f5b68e2b84d9da05e7163b40e8724c46befb4030fa88768e536, + 0x2331b3e5f7f1277ecb6ef3e862f53047a7cfbfbcd001124d96437a7559e4d954, + 0x205334d2a003f29e2eba4a0f115f491e159af79d1871614252a23ec2c81ee321, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x5c88b264202385a48b939b006669c1866bcff2ce9be97fac1e2b7fb13ebd8ce, + 0x34938d22d020660d0a009ac6a5ed48bb0097cde47bbc0d8ce942fb31c464584, + 0x22162ccea7bdf2b786c635b0bc7132a04f76645b467df815cc521e977cc4f80a, + 0x27b9ec9c27c0f868a21ff55cf455c2b3a392dd5e57ce6870b90c217ed051b792, + 0x1d40a01732b59bc72804d5be3dba2fd2be8208fc2f1ffb9a44fbeb30895d6b78, + 0x25a3c16bb29635132684ee4964e4f7364c9edb73ff5d41c613347f90519098b2, + 0x2264db5f2b0206e0b97cebaef9ae578d534c98b8a20894d99ff4cc52dd4f35ea, + 0x8599a766249f3c836cab54623833af8da7345e0f976fc683d04699c33de0097, + 0x23a4e769c41d56c98af48d9d3eb4e65d5c3cb8f1dc50dcac0895f70176c65966, + 0x6863319f9840fe8a57bd754b58b7fed2466e86365ef6e678dbe7c495054551a, + 0x124f8b0efe11009c8a15c7830dac00743a617798bbabda3df6ac877625f3590d, + 0xc399275a8d3e83e832aab6df8b0849b9d1378376e90b8a24084074e85cc4e32, + 0x119e48a1b4a77a3a6f7c61ffb60b93c904286828355b63b3fa1f7efa5cba57cd, + 0x296e14fc6bee3bc2d9dbf89f2482f9891cf1f7df9ddbb7f98292f2bc7fd9a50b, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x26a69af895a05a3493040f735b754e16de06fa2c04c7d990fa5ff5747f83b413, + 0x9d38fd6121029734acccc26a34b6c0a9c5472d921ef1db0545ea0d2ee58dfc0, + 0x9258525c420c9158ae4a5b72f73cf036d988c7dd50700b1ed3796a595c5b6d9, + 0x240b4844e1a39d4cacdaa8cb96df170cc306bd32b46539a155a91d3dec72d330, + 0x2f7bfd78087629319d6485647f8267856ac5974200d94d165da35c13dd0f1c2b, + 0x10c3c9daa9b917522fb7c6bc6c18a2a70968ed139a349805a2242d8587b98160, + 0x42e830892fd09a016aa5998930a085f20871e7305b361d30690064e8680ad2f, + 0x1bd229a43207a8eb670f87a25910257b4d6e99ba62c30eaf92c41c887b92eeb0, + 0x179259aee9804902a592512d691fc31fe7369036e50df52f17899e9f310ad8cc, + 0xc94864bca0ef906ce0f56586a71ebf9cb21907610f55d0d597c910f1832f04a, + 0x1b8129aa9b54faded8b6e4594ac9c66268f761b4579bab75e4b84565ec6151f9, + 0x138fc45fe0e94d2f56d913eee6f4dc8362019d48b48bc11d566fb136a034e7fd, + 0x11ddf7e5f957f4348bd38cc6c2b7b21db6e688426842fe2790dee3e5c7970350, + 0x273e3a99347d8bb4443f8803f3144b1c79081762f0c89996e8ca6f41e2ce9eb, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x22e161940b597798709d5732b35b7a4a6b5738d60943450c0fcf0015f74a978d, + 0x2dc5270b47eb00ed0a19788755286e5153486071d8676de57bf1dcc0c95b8269, + 0x1a70ccda609d7bfdcd04227a1c7b3b5dc51ed832b3209ad05cfff7f94bd17d78, + 0x1acb2e3c8872171cf04e8e12bdf4aed98903f30427938ff2ce2ac2ca07e89b36, + 0x2adaf126a0f5fb02185e741d6944b194959178f84bfcf24c66caa70590d009f2, + 0x1d3244fd2a96a3c547cbcb56974d8a6286e71ade5e026544cfa6a239e32a4a14, + 0x1bd9988f3abf3347a931f562d4c26b2c6c7c3b157929f1d3529438687ddc9748, + 0x1ab2d592b1c45380283e92034c93e5a2e4afdd8082525f32728c8bef6293db03, + 0x25cb1ebe5ef8d7fe207cd159cf795ceda6553f6819f07ccfc9432344648093e5, + 0x30337709090c96eb2dd63569df081569d7cb09cbdf4a7c8c1a982b1a502bd31f, + 0x26767fe5b44f802d1ac590b4af55a4cd28f4a4565a03fa412dac54a2d953d6db, + 0x206a055992663ba140839fb48dde53a37509d75de3cffe05e543ad10e2a6a880, + 0x26f63a141092d97b431869438f6f4f2eafd3587d1759eb8dc51129be57d1c9e1, + 0x651190f970efd04e85ceb47f6bb491b2391e7e4c0229354bdd377435decdf02, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x16f9cc64f644433e68a60294430fa2cb5932712fbcf1d867628561f9057b714b, + 0x271bd08af5ec9271663f987e6d26c91b496975cdf5a2c6a7c5490b62c94041d6, + 0x29f3ffb8c6f14251d4e4e6479afc22e84b5c306798067eb2ca8530c01ef8f00, + 0x3011f9b6793cf8e594cffd490b2255eec2d7c84caf1fceb7276fc50d598c4631, + 0x1592b0301bc7a225be205d464faf0f2620c9879d06b7c97632c4996b255e8b1b, + 0x1a6cb5aa790973bd44ffb4ed2981c633750d9df8e6a122639648e0a305870d8b, + 0x3006f88fc72833b83c57897743bbdade1ab69f52bd8788b4406e17ec42bdae3f, + 0x2738654c515bfb4dd54512aed800e6c044bdb1d4f77cd438945579a03ffa1416, + 0xb321f51e6793cb25dcd5261f44260a3b7c9f9c44c5ff3ff64260a81d68eb977, + 0x1477b46d71b8684f6448203310aaf0f8948c1232cbba64f2e6372b26d3b96f59, + 0x2e11978278f26a764c2c61c66edb6f2964876d189ead6fdc76731044355d9086, + 0xab2312a0dfec5f56d70efde481c1222f08750d97f0f378e32416d8911347f32, + 0x293b455b67ef83fb98b09994d43c30ce29dfb9b499ca17c6774eec84412eae78, + 0x95b635c8679c2757a0299fba438ec55029818e3de0bb66721004d4fde342a5b, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x230291320aaf817c9bdaf62fadc83c8e9d55690dddc6ab42884102fbb8c1313b, + 0xebf9d983145fe427a9c98d8467c649a6b6fd0666f80cdc3edde2d6103a0bcb9, + 0x1b8a2f071acf45649491b58cf5576a862c45978ec121aba4cbc2b344f6adcca2, + 0x24287f43b82f4a84f3a2500829657e4890974e8321736b074241d6d4c6714cc4, + 0x2ce1f1627b642c8dfaad03fb46498d7f85eba85b778efaebb2bac14d3d4c2f0, + 0x11ee152a99a5a0de87751aab98180d05db1e64f3621498bef5a821d813fc7ae6, + 0xce62d91eb6161313ea7e48273122d6a1774f96e571277109302b68c53dadb0c, + 0x19824bcea6e4ccef8b23d501840bc4f3d40837dc60b4370146a4b68f6f889b91, + 0x2d1fc70e199a73668b4d0c37356f575269d258aae7199a266e63c88ab6eb4cef, + 0x321c2b5f8938df1e2cb30488e61521a99706c58f4237e4c61500bdfe47f5626, + 0xd7da06b4dec9fc5e1dff140172e0a84a9d147154745f2678a98aabc3f7989d, + 0x2fc41f67cd32d7ec4ee517c8b667c9a0ee2308f759ebd889f6ac043d8aa82f40, + 0x1fbd55b07a5725b3de1a9739d36114c9340a987b1e66ac212b12795249bd8102, + 0xae9b9d9f2101c972f848f0a2b7a8916a3a2987bcbdcfa1d300e0b781d2da062, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x19f45db7aec76df1b89fee8492cb760e8f6d298cac167d2aaba4702d30f3105e, + 0xeb3de3aa60a1e43df813790a7b02b5774bb93b654bb4f690bbbfd8b2e19c155, + 0xb506abb65dbe55553fa65bc43d1593be440b9c5227fdc84e142ee9365742ff8, + 0x1725cf40cdabdda24e0cb35d12315bb0bcf61a681ab3f3b6ca2cd06bb6f9d899, + 0x5b2e0df1727482fc6597c7ada0624819471e4c4f2dbeef58ced0c2e5a2844fb, + 0x2cb17d3d8a51790efcfaee971ca9155f0074b2e7622abb74d7b8c984feffa7f6, + 0x57cbe9626c16bb67d7f00009f1e7881b53643eabf6abf3f4bfadb6cf9678388, + 0x1d5a175df6dcdaa9375d954c5df8ba5bcfb394070967a231cdf753e2277257d, + 0x27453d445a464bedd2f943123064cf0d6675c8946f077957772f32e02a0fcf29, + 0xf2e2a7f140c38c5d932d2d6fb694914a060efe9e6bffe14fc1dcbb840bbb466, + 0x240f3c285bc1a1c717cc08ef209175ce1efbd0aaf894599c629114fb05024f77, + 0x2dc62be8336218eb9152ec653c5f2d0eda10ffb07a974bae8ee5a370aa497b55, + 0x1544549442e755807a39faa19a9e88cbe26fe1f5f4cd27fe68fa952806a6e72c, + 0x26d85311e5bb436e105c2eeccd768ee32acbcd275b22c135bceb61f6fcc99696, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x2d5c06ffb3d2b7cf9a0dc797193cfda855060c21de622962dc73de8bc7e5309a, + 0x1142dc3dd8bcfcffce00dc87253ce16475df11a72de8b35070e2a947e8df89bd, + 0x1ef9d5eb72934c51099404ef52f846564f9d5956a61fa690c1a474ec6dd4ad2f, + 0x1f875fbc8a4be018170a281b3f9c0dab5e91371ee3101e6eeece15ff9ba2a595, + 0xc7ea4455b4e9ea7958d0549f098eccc22e73f89b049f48558910bb97226db31, + 0x1781c95b5bb00bfc0c5280da9bbc2d16aeb1ddcaeb2c45644041366c0c57b8, + 0x7d46f4970f0af1bddb0baa2b45ea78c3e043c402b34fe44600919ebb3bc638e, + 0xb97d904e55808e8d3d847315766069b15e4eaf6e48533679e0d1dc00c70e6c4, + 0xa424cfc9ac1630f815e1867b2351bc8a7a0577a06a1b3eebf8e1c012883313a, + 0xab4976c40bbc9fe9106a7610e3e611f88e46839e484ed2160086e0e83c2e4c8, + 0x2bd44e217b9b1bd7c5c687ad7653730c6a9cbc73ab2e3eca6533ce3fb568a339, + 0xcce891fce830619bc5fefea2258df3f5653c3ca6050fd8efb3a653643334ed0, + 0x6cc269de739b7f75a505392122069f46ead236c9fe14dad4b89ed3be765ab46, + 0x2ce5dad6f8c706a1e48ebcd989cdb6e79161070d56b7f488b1ddaeb207d81805, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x2e77cf5ab513e1badea5c3c891925f9638bd14587f6e342c5a92452cb2216d10, + 0x1f0a2a3c8f119ff5dc221cd21cf450ccfd2a13a51992e227a040294c78d05bf7, + 0x8af508a7bea4393d740ddce0e6f0fb819f6e333f12273739f8216a7de28c19c, + 0xb7b0b5adc8e5b80228ddc5a3bd90a11a6a58fa87ab21faf6b5ee6b4786d3bad, + 0x29b2720d570c648e23e12c70c5d903c08897ec38e8f79e3dec9f892429df3f63, + 0x2b5d0114e15e9a524981ea2e38e06976616413a966172a365e702aeb81a3e8fc, + 0x2f04e33808a800ed501c43a1cc6aaff9ed0b2431f111836ecc36db9fcaf954d, + 0x75afde514ea96d4ddf31e02c2e3c59b857e12bbef9188703417fdff2b73f0ec, + 0x294c6a950fcf5693a8241c957ef737cb0e9a2ac3b7eb618a1bd1684db4353e99, + 0x2b5cfd45d895ab09fb03ee623cff22321018031c835f4bd9446d13995ebc2702, + 0xc9cc48c4d979b1d5267a49248134fedc8c18e6678c52f82e0ead42df94bc3d9, + 0x1ab81cab0d091253489ee59b36258e7f07ed92223988de2adf4f431790b7fe73, + 0x2586cbe245b6f98d39e52d3944cf6ecd7f6b02fe5125fc06677fa3adb5c4b3de, + 0x13b2352a38dbffaf3d06de3fa376edf5b2ee4e53a57be01229dbac8729a4fe01, + 0x1aa4d470abeaa2357079129d114bab1170944f929fc178216ad847d4430f3f27, + 0x3d877056291c4194282a1028b33bbda54c8c56539d25d3813f0992d563fb344, + 0x708818327e42247f3895bd0af9998a7f3ab275831a1b7ffa2c0266090f86b75, + 0x2f6df4925de2c8eedf7a0dd36de0e83bf0ba0e6649447d6fd2a8dac7d4b1b819, + 0x1333c9e0db6849dd2fc1e56de942f8e59e6ce70f9815f74ec75ee7a710ffcd77, + 0x12abc89e5164e8c1a20e40cba62920df78cd0d31c641aa3526b5387aa499d864, + 0xb976c6394d0a9ff18c3ce234a56cf8d9625c11d0fce863278457cb08e1c4983, + 0x268b0a4cff7f67119358196bcfb46348ca332e1af2efa758b59e922a135d7e61, + 0x254b8126f45243f14dd8211df41fe5516b35952d56c62678c148e73cdbad3718, + 0x270712f18b1518fafe093660f492cdbc2fb70ffab31d8a4d8a1934be68792369, + 0x2bfc3981a249aeaaec4ab9001727d32d4e6fe75598ee964fc85cf30d50df584b, + 0x16060a17e1b11f851ceab20464572b3d78d582ea050014843101485f65ab723d, + 0xe73217a106c402e4c6c166cd9ef1fd2a0b16ac1cb43646bc1c726f83177770, + 0x4b959ca07e7182ca08f2351a03545bd7ab676f740b02331637ea1434c8545ec, + 0xfc9cc95222f92715cf7476010225e14cc38f314071e50e0f3bc9ec674a8aacc + ] ) } + // noir-fmt:ignore -pub fn x5_9_config() -> PoseidonConfig<639, 81> { +pub fn x5_9_config() -> PoseidonConfig<9, 135, 1071> { config( 9, 8, 63, alpha(), - [14715728137766105031387583973733149375806784983272780095398485311648630967927,12450793357728630597819493697261391961392738728208603858426218806728799382497,4427733724068610336929510244982091587998132283636864368924406075658439074153,17863554236640577761956319447874252524561947852685470820159498661269344021716,10723868775598272126873918500257797117892409794706524915527428530195343520361,8041366806917098496431513544630989490693774700064656765914266570204855843526,13046986480231887538692223126751085950758763070227069247275787663666591811005,20228999562936372999611354929112125019466353738760451044697249912024766542482,14238976012080913074226552202264063302466135977295108038770514743089287570221,19486717852389551661121716850619781027370627632295683938875312739716376501717,15733057748709959668511822511174594221965585899587926036013893958610587491491,12041333229715539748857491855115983195198694619439452683631630426350435252478,1829888811413627407640409778757789140470123549237476514374669162490680512211,10288898018349095056494632386514957183841700001184195479721999387950102580094,7360553146019695788111059047354435502690072975650576744373916804385350955674,17476063720528136669048514677420727796180556343667231122803521620226101935369,18384724266969916899691009636435516722111206340289089258767862754828208946542,11046121967047431151707881264774621308937270618998625466342467829704953599782,20018232138773775379089542131722766973741687507582662224374276186775807685863,7926534193496947015875888176706209291021745851605316909116853588598743879034,8826996877877607049084007876351017199517432230182001641783930871320527792100,11760708819943554023765145606995747732169597984739408998714117029765838566505,19598000655770319703844060561747179253151181702222064644764822676806532882514,15036675263180992517064890091049355832990063162957265821390555448206776251789,1053420874580688637503969479036991299021138740018858993455108201424412879748,3723543690610038931361367959096800720510056325209292666118208798533818425035,4599370243050726453512484851927735252841106375733105184316191846221056036380,18291400382386598447603657416871816375751118990979359745849342284893280004873,300341627009231088404894405580745838091318300821994947846008201887884150151,13332605655619720841053062902143052543375741442250678582318225211621890248982,13197729598850829723360679245789196039442968018972826673455394330035263151299,510788688496484172389408566109007465667555285205327059265048317979249570221,1685584118031999835794907889275254096486823415278284757369286336252006457602,15103945090904102223538479231258677032197950627619049222966748226967974852043,6653802896618953033344296077900828173967467309849915708475948018848254380036,9254803560511166426410537422101769642611302194250107918342410310963831784950,17006557344160230194691541621666219420787918477303225545533644141096551358258,773112329554511160545400721342977593377624843987783062638455005748446223137,6671483881284330250685026918783029584764740571210869197688044338476895092050,20812941492969561606721983530907505914064782270990490150214736286311482532652,1156984923268097592347582093730300227184163551449762803735684309575717323017,15303159756724065068145651405407765401796657934219121639364061501460295743948,18999785075801878445291021498876384414176522501978873700451842582224940767334,3782716983967799050957535371991538595453996691838733068933109780481907925378,810443910646366078824923626573819081371243815242873044781414798707744583851,3940687718063184864573934886068875138239553970085689518511531571139105765743,1222092197964451545227395363538155091563596468425395922702697716100572937718,11901775018663948557424314950737290815973735008800495766054692238446226616230,21839369981774608005059280910009281502958794510307248992429390932011110951241,819873152679629471918450179717035855395702808145570990556719950289951175212,2918016794043041559376798791171848118057043459636680115122516324180788251680,10788401265856066217998495397128704450484607734353922353470809976686155443188,13599498756047543641157208425687419183141596017402196474108059160235795892976,4993390793677030007023804867617329393931635615810976661139461248253851471412,973050533401342110180605419751137563184725082821038770229241448201970125921,14313276246574487682858906899808269544140218917497205965354285099641091349756,18746777136177241043722556179260854313319807637092383577312657349740719965076,14517023428366357570216698819722831600577825429761151189605029742824536459972,20223198094330596704408798588338060788093323967112845691364940702136543962642,2924401185705980722600796492514644487545258803954418619331883216838542308543,485440919681570468713530641755278841324413691217763990572458853294843435089,21560476826107225363638525612645382878298890750874072774141701406519608285783,7856508582404120415593106596945280577031904101959961641860467517902309769386,1505151890969527772884247006998953879441745452105187039442954300997320053301,18861812597641777105968621029392243993700881183944538936666186678355756609806,11964609307983840306843122014689504510236749206766494519381451521217569407396,17764783391855759749651949748230026302359698415337858912932633638930034077791,16562247632438820849068750036602367255890087581186727955070681252413797347277,3341595358840888933968836940161983842834749603437573997372892853189756769506,3198140245778498430686233550970322127895441994253754893043542706415030678798,9829840339700031668849847901844029075426216057792062644639239580989060312114,5999422607425238131817993672620301343082348300090537110946144186609066413585,19901271533560906428202710740924807375620638454776660078183104891177283526156,16697165654181109350158134734382046723004976300078845885330478879604895897280,19171906568090360833249366643372143476587242793789646446664643684138123124668,5557557332632668793539639636185643553639926364115539987556075445308999628265,4797522865199880517123583692586561796505378758857130153602827907909887751116,15409514194242892627651944305634286919424076146534027188938906487506413405089,10407013998132974348561594118793213466618426284969698091916131778477581263008,2534925381155806875978186916525958864791165037467997034976228683909613017312,16140842893634434452708565053572928560639256480905937421023970743339301598617,7517617592925372620130293329989654305076737363747701594349097857054039164182,17572708764253481596340159581412737527195601517063980704204677005617144607526,16697796470163537491131716229045730242536059781538196375577575057386248458494,38275164685285960308550480834951641755153240877853193094138358285155638204,19780228589871041196871406056718374983456578990309085234484187723923738516508,4573417308961077301452769955811063226515352449986725327722241421281202736681,4768055042642730073498433238804346134649067788593835428664493008393684000706,17566912618951175959416490797476610679702184562687840273697859062459883449046,11477598695424707935165112148975667441147635429812599883095916948275334113413,3408907078049921938725945268376819484694115736385272440041090673225197146180,2488590561390551829094067182419871806900177001183027832070626654223650976899,12116557895894464059885135778994901345424716569754903115015740397131803733982,15881232965640921626180413777392630630338847181632662075996983398726326426432,20914323757596181391651855665547258251038466184617935369425714249299063760685,4275923143992397246911855313401177253209967573031785993454148836244404305934,13098973753894185378061607442839048669135765294488505596582737281481575045554,7995472162206735324879506324600884378126850726543803581430135236761716527753,3690915804478314734124615543749602171459078573370790663994412906012450478823,1256453655839486811750227055618146120819862944082463957526146264573763714294,4406492967670422538631080907830590263463047897583684262207883537903678091970,13380843970691717863215678292643800288491103227905602355694129412234174194363,19680159398793220289979983679401118779763854719759576408245027038965290325739,8515713472495355510508289305321355004480161123461789103991491891201940557902,18392703846804297332972535728243845000077361414687818948278976164182674947067,19823604647876421559318429394175186838817554072847524297827763377975574273192,17719715026846703054856559310322577442906188886145763860157972477138788247667,8745282777320550983079435446349157218001552450433897097227622172209480270781,3259368608255603766247016957318442624095407655100612967940789373312058996520,3379679235619387594255002628664818227413294377266729211815713998759100259668,10282673789366804521601844018863748004632586596870138135887183100195194767004,8431227731426467642712572981755086675999345721043460063547234289139267810255,14117058124827023634266519281629142766485227596060997608233088670325722698559,17113232771025226173986361792697170950811880770802373827827162227101499645884,9906220434844104062978204733717072107397540599291396561476275675218575564970,711369587296778404961826907371863989722457674941832862265420496583620086218,10995654568685707735109869974152491589223292425449581061000447170660561828729,17197923097868441003908860864777521604587651639410061820516916970875615238246,3121715947184842829391029463556305441693293825061846129844634146823663627601,8817835750782344079827519863863370969960597321588294656839911940551490704717,21074199894730915603594812797833479514843396752652846676596119472522115586998,8903588044620722375103549330291845285230849782400990458525441823641905996819,7157451412319473873395155428325762769952294079544485671397508107346256362850,5366933733103001902997281886950280717532636892191522349820059149392915169558,3729196254269053915687004590799382892429870424157270200083981101426772909827,3918096703119862723362353838062260616080657756068272173354821697584630247209,11073027330528765229119199873305594827907404967404841004751556462671634016839,16424651511178205757967439516888026957937418127900739730326874335888617161971,17036562818332519536292487256920458988625450115083747105277938048739292827058,795554890382567685751618566957270321871701261784565632343709559354970377145,633072079840093073847779349151531317793918731920375040247534587265858418734,19421194221177975514787747427021411300539454454371387008642591623632727982196,9954719107136377193496025917640974425520732567100168938432529522254697824571,8674312532180246290069249621352567303340886011365637785384772665860996736758,14809129550856657213168714888239735820810817787153747648450536960647330811703,18479959092813678391370975524549834571584338614798320263799188362327888537937,11754080849414921164216607793483937490683185256818320971638570891360029327056,10287736699385961112844233987245832756528102056561178731804188514133469579013,14370616700332892416887680617217669883953806003377620695037833373409292189021,12131262377053219810698216976753909777223459611599034218924662817794274728701,15129974113281645648506209149692470898425572316691306513209191313993708898437,7871644959999350003348485402403894487663479920989578076708137744830000430296,1576915733292398470896862707357585951921545131195468346129170132189223165938,13316238922195025030929715018519212370128739646325014577776776032463179349855,15160020868051885495078648274966503057453505806774983308629511566464684311627,1692269682153339201433258246771340974628904846837119864247013056373782718416,19628837155426033423644376042848583705054394443378101622337255362403724735047,19222966046507618124793516210121558272031295169005274768240595331459420997142,12990748614547458190976906297393525840623470679364771518133250166378979874463,10124996030376091099517250678153357142212975502206884325977282211158514276950,17630673366223237394418802287655202715156124721482801416980858260564381593966,6743037447395702022066513290929048145404894812633440602191382691018136524423,3910195434942407507599129230554588207801501224467133349280934483448828467487,2025953242925331197360540874793022332074847486979998082380244277507702608951,17290925253475198968609624243667228472127383792887388480830073536530705682760,15557314422719360545874148111856256188428921052029295715627017447052250706766,19758557148246918190283097589287660972538989627091387035573386136809005998935,10859351185398338650386876904094285059182038967427299340069909694684844129362,3496018793417449121342556434800740598384008787187762642325224753304909741349,13695501250971489187692201493870442254612771332042272465953359508617675704938,13572242195808512474816152630443442412961099907068902213470234329372028271256,6257061132956659095252686302119011010885219692712894010340612889095488866530,4330599809632843338876238530496396340118064854909940219910748808728579051913,9157987606978264109338780586425009211347479724574125407732261019832259951031,2328698634372378957406958821467382289342903425118775270878244960387352862845,20636525922386221727012980541907198653039323429055563362662406273278160984146,15847894355448175995216566821171916679432807087340467956339517156584053817157,1942360378421747943668019094002571732886982847410366696537432314848905467679,9512432294361739988724195228775769058251373607278744642461344881575127503031,7373765909536890992660842391636719615263272667672747352621337161184389163446,16805165862480928364732162070809175154629112007405963636466097184868514458659,7667777941325858499291332847392489530780564386762784335358233711706517931292,6446208647487337326336908745536052288215677968074882840304817109073334759485,11285516171986135785540153632137541881991922296507010937224736080386568662797,10115214387228124714106659470937696440920497755599449040012569123044717722706,15485618097017003479590081826451772255273462073640651108645768569284210541135,14933383877101576453093795963534828854771957327481830015228527838452944594646,12699366929120600543724208703956381057734625711467645612998923493410472579972,12636366946456086231704939526732303791619337704833963854669708252203542584210,12149350767700952579168066320091211427411187251056390220529300991824437924228,7521252564104984899409328139379375498829232271563704354107116269254046402507,12033991121152464927378622393121300999333393690763174606686511857615848602007,17232776948709347607296344257668859070263618035653710252910881198999758003380,8692908682458431891302516268928916165669902656866484222966303081483718910104,1253076047322637463481069610081050841277544153675308425513468857300598987482,17753389824587331559955818909257943804816005297310986968447179587639048799696,5220269242560242526244582743085713945173060875457087963936380952653150665967,17126848126303954156127690428371193690154903947228604938919561454676410821149,16844245036721981603144243350071451732279678956963696493069130132912694448751,16797761350119564409426534689125994845767740388070744929816576998448097719798,19353620610135120026060560134469588460709151673182029068633909633596535108020,19135326024992044270104645311242450367403619348108625528873986701416220617679,17665816362466043406415418194780245586053150534372814020191541209753248047067,11399583108978058354832763133747562621839059603612742599115200702193127837394,10094334549114303273265943473013412623520307578724043117639269488721170750917,21601458494506173036246860827162868889968956934810679234022762622742359366252,6386580477827919478878489737663301647954047211008970416851133263802072756591,4792043837032853062947152822210390150724912812294333339974827814683543135564,20876886123310865680023706563792643033695666593071136348323857270657128199374,5931154799422838405687052216230902279350178420072288819326391251206607447359,5239679324690579237822809044372316561806419523557737441242604861240795339076,10385003741667422202343482240152986976068622687279646189490976516013598227432,8464156248644168452015929033942509092145250244998026718035923409819766539834,13177537753162628205208392995644675716264814191265988042404781479197639366733,5919477377826036950488668794024141041792143979412430063956231337921980979482,1351402666854456730370541080745509803482004768817122599092881844387000676155,6818673776641149273361875347660949176445649468306471072411086367313332518455,1366646945884507587781123424154966453464902291438811059924651777083838835678,16219293249111347900064666257423013936256436002819357345030961998874555359000,779230149490072246312543789505064727370429119089791148581854356816464370377,18480337167389263493513952937037301086055810692872257722500635290543939189393,1345414110418158215433956620396568245327910182467730711109133441878095212920,12518315654451653143886317929532883727219058399486775127781649065277400104111,19716171362713656659833259243590727588692449255201500490000859973307782246016,1865072487559894165339723956247507020827160163812334855490266264867949416605,8915174456326318257703177400411158958853446829269268103252573093652570933472,20191934956657253997484040571514242713447218897800997897558899754776252309230,3900170788760364547006546697350123842323924137566872497612605525517074710000,2242244954905694264442292936230335662862827521454977184433268725352453968501,17212753633823250440920113486091598217346743686574392123683302470302281044057,11939276774333100126191320505078174289237596631307779156488772314461752488631,361355126674011999247836373885105218009746852422112563922207274436194144681,3861054771271956681986534133247127581996350841974597302976225613765246291116,19968479093411941747037123171825881488638273087679549521610505739311299462846,8537196135596544183619390135426012949552627827993128615534814021127294540392,2438879838432432949185118142364194193697006515067980632650379470739663214843,10769366200854175394348657213265947929465261545591304593688343101111720627317,8455019976119342575889554308499186802278388693477937667704910645050957262689,20644389417984700539779514908032253651696357386572813102276555909201716748299,8820039786383750409041489202684137325382534899692778928304664068322226640076,8636461459675525672530300171201543901107046823820677414340465229975162161919,9061524648737340075438868917468774023866583922769991567001812766008277156749,7602969742956570438827438826124187210014769304752116695796494779120606534919,17880480383024583813657184645997268710007005482705400161841684734099773182094,12468433127385453618607022105559942067759302463679348320088817783890080634670,5227335513133160328788197758812517500875193491652227971114102085123079105787,6151293357148965084809035339276030775032864902311425722089088413878852880603,13699219811250783019541356007733829713463891996344484242492968708316395244276,20523944015644472920486129305620987253227711059638489683670518491277805771642,10421521516830672217871475174620176828341870738569247402138774913961149048583,15243709334491280025949017219424981672670169674700467979049999809115231651422,15516151337135073170256217447458198066207320794936363948307836943072374966170,17337341094266438501679457986886656365327787301649468585664115813920643670255,13262611487153423909813660830277859169133522588408913308784951544213550636850,18531665394082016871726276363920851282983017715104457591860421181826617619235,3700454591945927209171569025131477008196191968736477330379417168348613474972,3604972001659087732761769946443190920343158947813896848729866695375607825911,20952949990925307134028293094501736726689724950451065635729323134614933963162,9405357171465854081502883779215538022417071330241830295392540662303830897477,21638057691528924765719568024989208898293733581278465977164525893773900371884,1423261214711655336057796638966786076518765517452404205191550645234914655224,4051452662373209612509106830833400151748328181316060758960838588997502328136,18894191275634392250799133342573131067016712303481664374003128715704286175519,8319722910647187566775047002603641370685637216565762886509056643924765393708,18376807271218398458453428415456722166053637869198381036620575958015471551748,12035584964270041086110602893321059914382792217135345721427943800456312398294,12648928151571890511419082198798501903838843998709266232987169892491925610349,21412038262513052722667255278175073999553643537758589877888129674442282140610,7706735190856341161262212613554225730619876208755452623628315796884166016734,10999966015370832078836488333389544875338251739488999274500058322944383211399,4088296406085952300442596245852961024918851819760395990644634222875937267642,19399822412575078284884340953745677500886533272999950579143260384703504507006,3008499431966541245607724530938385192395211534821775780577277325698653345072,21447244586691806434401916456546893987941039399147865009673973728056412619884,893624395222035047010673050230651164575948871010677581303166873938544655581,21402344785412208717452894839332459679574051179708007417742748857146495441368,9392712010553327328684355664342647815409597079361837524976044019430681532876,11566000613582826375650817776243972243778859250974226949316472392849073658674,12900046757905605731200852057204734685283283637014313056501123642345467590346,2147232762440136333246788660102778148879449441151868600321283583777116020664,16301766972982581403924204059742972933467455194833897714073756335881543890771,9546560122931098895129690583175071306095759562194496054583390881525378967396,3814097068175987733354103462855355721851435755267819873064912557751073632829,10704509016547426355599213335456446765914211024738080860797634337598031536580,11921271012710313311785310319425095342886561942032945429395596578758895308264,21265249694322068914280109016742517903125526413969519857556032179013285196924,7207578215754030787157150149235357460121567678249968060366462431427104673093,20820013978092841458072065536574129286011620075823185493370309064760526240362,16441600678335369077753559950421185577542163640313037056248177018465084864223,297097313501884278852369638329400055327872945847645211148627847628970916078,18298084629287541333205519012404334789930413367615524379442280529941257264699,15206243674059814574375077493088319889784970587286591062649045683132661681752,18726053049188513051286348977772545167577661574609708038977390139794201099882,20262858185621074639529176348089123044694437795099449154711162805012934737131,2249345697973053772423677422936999849381692933292653912080014325442939977122,20814726663898441680439335735982981967722006066824203970896314191676769388296,3816485989624386223507317175678560807682224519267326958526058565555245734714,16741230612980371365533431648017361867585544111098407772560748428499802539906,2436865301432265520692873922135716828388518032014231744012990863912440945389,5265261577128499220460184630262997769060828863581478135168474766310582001180,20550548783058990082416235781987882123241946829605049684648813233836863290502,21523044301008793877416122201092687874337292497403523925455260117417170777735,9283421400783174646451499708802113832695004549893166692004850391713463380536,17813773547838391112844362681067751767404443478918792865885006908077545151618,16486730475669947890512191574075897324037778751496940417084163322433837359720,11367125189013824464048785896422572845103707778462525259651446893275289247873,4759445724467851058773503846834304672223785226936531021666916376323562671488,782273457631193956426744043048759353979593033245260492990657945904665284910,13487130697992008212099652811750242205045881544509489831523448570173633517977,15621563974535086891768796441515013364217522966350445838133979748032034816142,19364835034502915244801518193980688426244659266819997726035650961451415757173,21037385853462058267099182407141652124171361973889761119816789091401609511088,20434791917020905003166852059282129255412677606775079570484129378535005615291,4835039666519156760310260600042269943079463379265872618778854224413385690994,17796521681519947552208651467058827825861565135255248123077469895978163706264,2823350440792171019111081223801188552138104039380675927963458669980277420276,16030935304664378631941573945857397096373696981104104381156313618686049806120,17523561865544155408760007908067668065236326734119657233234283826019015377013,3861341406966982603014220134107636493882146780655211775629734223927755221098,1327887013530867777305056212037691710827939709365211251951525926327942169414,16874372098146373517691588057974501095408377103185981262983559391956463291137,1335930538845994150082853775454018356383085560294444442667355553131066129276,16846954448852864630121063053695845658867759327963014776419090787323732938912,1910615356880143423765930148112668984411979710628153215580997630269783916489,8793723522335768214688108364110927144836722932802666660252079036893034856492,3725321587522884864935206279104882080790553804758085564413847527197687551835,17549397166194503933313005107479073474671951786436058351827338574279485542057,6575272615526665941236934551769345604089554458721499014263130089965203838692,19479945993771870488240738504390121923410154808673876321101554256856036124677,15218540520084042504179141700157006972641510542203443030571191341196460163766,11605382280428426652337162672330854829498688801746852913129963366330544359414,19452583367341408020642116770501289011436457479987875413223766731278874726613,2498463382382553480222037299113185800507848748313035345734629490930688205092,1815123960727364421144419865126922339611466868807520419660969560789979822474,20531692711768862540943545541715345229360673134388506876856593310216372259130,21106443640856542784867046664180461359993554892163126756059125921876166419615,8538925154199646282458477113696635826112766123791239931164489946578874271866,6179996393486486548378164504724190431464526698002381214818146508779777698063,1334556948430115939422649531996020210538905726908545666936164977436729124944,14555087544451841622469763698691954343538388285983305607235034906273022598676,3263678860186354326206053303615515256258748076250020171477442794745232038780,1342606052959540554052550853649027290857482440100275878202185177537473434874,19067318604617984900108104413860593038444834168491290140413988853573796446193,11453576191720077983310542494091726783885546118293459348522522324645101050430,3772400828106882724656632136643514300687950364203707059277582466654856015909,19928616354232846804233301414766074864065580313304404532140360351457581578733,17669618023197654971616078177762451816976570462585423216749814198562722234016,20487504497482961764356160511764652912371612840137405927810776425577238052311,15959943319286858239034503624455112049217253792773599324329593237810330429519,18384331160163107383609864825156022277275076414745740108239579270660154123750,11807744905122445070761653068499781933485269571078706728521902995972849333739,21636069700028297640587439425598371999203459272489053044479958900301869951268,5974406255004817187688462241155741022204236935194897255519053490391727654963,18655439470676485950283686008645538637216956533059508817637925480405213882893,15164692255429309369428108531856612257028649418370969640920631880841690009016,12342219963417210875401056442100023070134657858086394031902694268469750570612,481209231155250366998260270814874408671884781003382050138985430923825730090,3242985953168013112117560001466320034030784952490866310190327264524235633420,13671160391160864796369771052335315926068131063004086507703804642392143876725,16716228406804746939632807079686149044089946710213611348848847599210659020138,9496049727665863372935045496498617414460003517119878231671018103126084599100,16483340875218689502751737973203780724082025375353804209734656041473116836207,2627597076078148403546873341483726933849452415436198036537442451261384383723,20527956374075302103516613197928664717455732919429461243667758971357150882342,11711450220231538029408058975978592998998598526983681112180323327131923215776,14877293714143600802178367397934915488570060506993092692625720179311507474506,17326201000468992158693082078045140389930457394232528033746431682308160431934,8241890704089720408679017565592201736334812957892898769189351788325500937732,6134985085876540657808139826388808003135254271482158519839818774839726308917,6944918715501093472287921248184355748547193680657762762284351108190443908482,20293371855859360749476040038457808453751087076170457949707661658124460443795,12686929429491234226470786986230897140429036877303905464553700071658994784104,17469937611674874489854850805106365496296990924579100118175990663783068480118,4389315288495042551686883151731749050970801790377604942482415778510472384968,11356013296312574683565144017425132580728729177241949155779586695189495537084,5103616537832821778796048073410908442363049367034544148603830689894368565040,17797731362169406634431131949969435652804582561417001546024888062211188454886,14413974530545126251158359344156378502844867672748912889426381728267720393327,18860675036245741580291857551498220749884348391920381715922087052471051304459,2078681010293955893545295223175290151677764183673754633340142745613957031877,11594462210573371469687203943585180057860108341927961420756260896877407822187,8232172476137304604696594035794651005660416081930158074561971898151387789159,16234745736110953717672420346414210260779855851076189537371942811750295876135,12403261277735118438898936378116787991453555210970659659639856670648844247938,10260185954137740247486488192570496092684935183379388125044125653647328054023,12655661577981598013787126068450556825218951206788052328715378240540030673155,18875782029492829253540920061867800401544385695523240332551730645990253683286,13000939909369679921538945109975441940863265779072482929455684540500587590629,239651505606383903278277662841450805219997298453219985892834268956273681444,14053674646208577108881262953518523519057705122297176784230960366018789686467,3606574524342197944154321263420984044427893927972300192386619594198948706444,4925738689374393290519002876270198297196104042467164940497567711764321354393,9820857610236925174040210045575219513594477725958302510866127781620764675531,8644935227560188528158307606853375529544842899940616765747319983176480635667,12589563927120228887319930197852404057542625019034806374830349240796880735981,13728987671030134173563628755348391107370774536000844606094840710456114349003,15280672692530045491619672502933299001869276703035606138561063102232345967821,21236672540209166733321925277807375026701626666734236841532747395149863205571,18193368154219306112046312834283644566129199372283662927472078427038205531636,17828956732555553542546753429670551891943977601119756829631880115504235233984,16641047964358580103472953437535358748387376425127849904658691126285684204504,7196281413799658043487145161620082973834461754768351228587249162400339111893,21279455923934963235610861427104388147894350922169838127737714784897083581830,10868227810739752166142906769497786680491652628709341836398414527811509748689,2545479497580424357309396388184225593698470568625667945691755386799845345027,18560104754451358950174079457178017278416450108044438296553162755384040068059,11209544817144484509471895492404241079181269159060632258040504564376475442191,14007605578670373547623429803718323316371456029307063658189484725071020560017,19316201371814679831554697580647476192318282119512681720915001227483533198021,16788142218280927569387096932066591137887806957079516944927766625343518189548,961359518362994763330685811948798278197676602059504713988410706948791494727,19776591693739287332042935252284088014720557305781829207369487992244783048185,9480779019638564372864984254416095889603560407402750333423136372713778963272,7812061847536565125280880398757948966749177710701972331770694629380983832516,14806224217889264732099766866344263686300132511433376375954468192761174167878,10982734897602724370866115596864634266746118759609469486863878972425453415519,9054801238670111257982773992849940941038784597792282084645523468554872244495,16788499373458165601983802204061832376825550128562541027433580619384299691535,4361212778425224413929793165968418385407821814716394404713983701050982051159,21198869506404830651226227162808186595284220877501140400488215541390720176503,7255012904510681544072472510832565052731304049336267892176928038570971034121,9737409770400739938717035426255379270654933363992002237053138761832402079248,14206577906412186888550704503752653056320975796075254442765439825369882967977,19036632138581200062386943078412086222459679497578993523004498970778925638274,2855178582526872375806959544405581665248537620420194093904041355969926293337,12896727255458884273207928529421874672712973447260798892551468479503233439215,20930350939164528694912500193219456539952966506926646436560438515643683077210,184093243282405111677536457857692693581379037444126410664343605529966199122,15658149328429348710722591333703516363901544310832580304722884306208924451465,17544235160628712643216064131303569753533519783718786133736357990785709619346,9378984995834426590515136439048146470293781405649183047514776402081048834772,15827462476470655610816981948418438654022314364182315935007413461648751735708,13474113844360907776462232979612140726930720201237003164521648175005015977732,1846676454601041085237775396212630553832771346942418764660365576890630152018,8958790186410745003596973786908460746144469347369569174866696175944574520886,16716100142556090678395507171596864615262575578180211444515549196841601774046,17584363243087108058467208592097637069605249776196694465943790236027601639916,15462568643993327150997687623907692370120490318886920754261967569094539968909,11670427917584674115542198398366950879185738970881616803513412243898491416455,5883010686944177614793479335292002976406988590121850032334552332298599405710,20848023045403944451304856285219275218146149181988087184275301094312642906291,20892609628755793476767683891284835591758207667306100001065280698890821585620,11041559416099382923560246079300939393371149141074957197352566129686429429340,17004024027027164912556351303862470964296900000646134239805113699616064012220,110742314120280698533248152539115345099402903868297760208823130532853128340,13611598917097489441998314826578736196564311189470688979687759717921520208428,20362978391139708024092837231934567580385484740720090300868417284017430844864,4130975720087443718484415210347908638971321493417335260526136858657572592254,15799784358302997284875412214187555553319485274948108081666806701893845835839,12410480753305882251320943831026503736012757975027018073585110506521877824193,11835843853657957571888855948788121206617247107501669280697395787347649231752,3326313455005237548503557557286834479752096887215379141590090769222516357133,3193633369267878319453517203588676707547172638050950764150162277144428673066,3543696055990388683071939150214505536733386566291338758519836333135488212473,453840133795717001022433249997110059635014609516452256954528366651276289770,10086004265216215714804100477403907145516617200748655771783383139854288214070,18938459257787140207383332020952460039308194017940327258304986766920440675756,18017538799787896442217663532610710859333377084532654794368604069493775630216,5517691591172342790575564654696650661133600869824307632295945043592492062300,5846204096126701465613249085053971321249645306247508562697696901334354225619,3177064511134248081568628736306700282095095665917536853000298191943047784014,7886005759395499452194553110700824805018792487440311729836576312028682853862,19249432464407391173245558257296856631584193393398113008165174416171947900609,16818455958785909569371690525990846776263170512884599090849081099178789681425,16250344336602567919050898941410625842485562539342327155695417850618940905704,6273998461375119044609362240019558608655450921258416376794979330773412610302,15933077340738498731035173703791932079747269039222967104684412531145625747085,17631878023023477567294765381542867314814954498487832435087010633074888584009,3387656327342575368928488173891176548794878068816523542226413637288662472792,15770343706243316227190526252701886989383556270818375222569120097305537622560,21025947829537149117391184273139276031347299127217645728072786010534368285621,11728430055160129100077268133090903533902452454196978455625432056779499908581,2184576630760971645143677026393147474439766939689140114811262608230414186937,20744811853491523948066896610767067484129121010717068573365370365324040781186,5378129452609441814399329369785055593231824205814541852039878139773312247469,18082900764136659604287793533371380099349929291808230688664846500365863263118,10463958995559323021196963984934883570109613942564610388110191948063546468897,244120224370345949702567256216804961153505781666838608095297311545160357032,17924705581798291273661662368787600134425123985006190354093511903371507000154,3107793385049037773698181795186417899797325916401357881664725445733609110598,5665818573123185227274537904890713907625420710982346291959547939830358917272,967322682615997637785254033877348832211978156650281338584051044602311410196,19419941178285529854771216440310658103611219351729270204884834098822007849679,6901963792883328370624032472781824547409040392368725235274158498520441238159,13721659825627300509722716825333808233371435398666022190921612703736274379535,2784281502858555298249063959836879135450746982163416748737579846439268828933,9904373282060708277943634486822397019446454722637742217276784802015824898651,5782567592658163731724098371574354386783075175203877502094122152538152467682,10854330629450460532485325799036675355255970975925867222693267730198057197195,7162558805520478103072398765799613453839879264508883857822705210986309908966,14561060495007338369036260685346480181377385446422680685283066135483167829865,11521954935420160563214644175207412771411940789064933791820101643809540481492,3893071612329582305940837979511590531534863287842007408024123330272447072664,19982770443796802008915975147614604175753586689418309845602797606117149147490,19714753609495058998670661272525609201695470529132258598980221623379639411831,10656632215192474178114431876399520721084839753473211054259843433641616176373,15519943627473966175746342389219894179761085602008029155282295063466585111230,429220418726674010600368106136723992478318707196454289985261340376476917460,16943119555428737036287647863079565463224985076466268175824843518378134856246,7079268853451648384434335899135383974808119657387366504271184409878695702895,5787261347913259367727842908192773692002199385877294080619854106978539332397,8254314874636465273639128395147895313719165057850599581478980264860146008069,15417738281457065064716789110361253613929614783743035738325702945037527193953,8995940809050737092434676062651493038351424361820394016896779859938155003450,8930952966754141446126393622188683431566029237395186071059700311531927009283,9012970415439810859538557593310902447051948348093454112737452817814629449500,21700461010267441715993595978543322483687194036588160210184366057201658507847,19191426116308521669196161733982754533604260068907220372422504926794231257150,18022413735343984488479130392027693687461867574196874267731354592562070094392,13853879871506882218224060020827336496729967255850404386800036291019021382781,13303720125164503437055631247918150173085142868095887759030649510172293881844,12463581809293287384469946044562671884924464520288697069370030386140109068261,20468619377263375923071378952981485015200979956112400596511865225946853604157,16682148710681177357125570715056314888342059670705617513402649433802720432267,16299073895000203963165709887505572454180623116454760411179563591228007694413,6439155427163506786329349605983728674821430800627321435200421453561910062302,16531483734580605436075637034861280240342858648848575098901014901746112480232,17413802217650584016261506268242623594956116228659732892682224912798301233645,19833018739354446018077109493089909435818386368530968355647208939546565982905,13005203599293796776324509750491064421128717423989464867065044987475986374420,15433711189444672576513248931602290892518442446252602686878477157678233603772,11272192842480959445178012145556234469776261923967845001064211055340129168135,21349777755000957327199310930646977290027138137542241555905014230683052104267,2414795183415356147955181901405712632718942970568205736628916600696077941534,13910388410253717440990758214044472114511432613509643223811561885135488623236,10073917454281511762447567386654530277776617831005093724557094001489771821135,15674657915196276639699997458656008228696751013801231738985398708672037426000,12030695425048598984176709301472822771003849589255577773183310838231109921591,6658172369461756755506276881582345916252610724131747740625283609123100367529,6460801016753822141904293563006139350014125998787400018150863192907944207957,10798491465896968361800574703868612181389697312199241920447162078078725409638,6331917501914253534943383807348566698937757752033630507696817298838693259937,21521172968280414216108032807577565012642487518706778276505136864150789112592,11443202152743097070847729825799673217706162711935940510632741405015900516668,10360970774813507384412119692215277392320350056791930702078433469299837875151,8111678922881662305935841208620197469657237670526301850210945861223648259810,3828566775247110089904016755996284741548002327940628727687176763639903716661,21019871488460899469684764817167629979753844957147537040703291790231271795829,11744049805554498869931942573519884330545637954557542018916739662277241821806,4521092770491436085084640166923844634777984445583984077999595768778116564222,2428018726292924561718904390333390438951211767580762396913313600061529081905,2672992591753804066533616673591169777906973091506536575810912266557203322920,5631180351966611479340932319081124575466459942666630580683510336616679680271,10149209329290376952496655294191511204529081153402908137750268385347783758010,18292794133971639465196495021864699906132845458944945214425906730119328661326,21442863185355178191454777233963814974940050392649316620141474331670970354424,3768420898310640667772098495371174917665155708578905018940113026409140957987,13677778555119984843885943251631654212176086447994430552012266440677394344669,13884681165958999171515885225547717032289759601884108191367706162606597842698,123196094575938824660055152882088188411485715788351262262924974166600702398,1121836698372380581784934880625694675020871234049336489788624481922395781738,20941331435492311592529607715649713508861806194386837398916323083940590908651,2470912827043971002614412337239267059969980871643559631900987795139200233821,10806505189594612637071931546921663393081238567888534876058498530874738324701,667951375802630033661777802749339877422061577764798227349674331630120025667,18416355600415187627018330134584431345513028652497077471935121971918269469363,14167152054564590179475064444026440101215733530475912312508414765738108715862,18633695428427030575173671831485026260967985663658201463236228419717189642766,152822669216765741203342297512101138657182497046533047369566701489981099230,13835701173750333056481994253160471551109858589047436642253159392878873667798,3993942321148722649703549241999711668949060533276325947207349685002693878681,15582244332423092177434976075689385819450099629893355758782548118218073388706,15110236879710270343688993144525012407319759236015974251051640787524859884359,5104405092803829419537383694663582438349376353030379488011426113631155364320,11034886586481561934231698674217393887518948538322130743646058638919797229737,21614370562083755709911993869347579638113152610927033622836963904672826178593,11909716327216431973191112809713028257963610176155315584304717743448686635887,9670047520194835060472941420215502268522351803257892125345072551055025494562,8752044341583145728028411582583224350471084864272507077624316823400738066962,20685513123216586620977713797881862528998788503897607377725195418550074311551,20219162196364967181713755472576994456615542213293827108438968625041058321145,18287830464300889532838439052863785386620820747210980263612361113628554829988,10146051396529576924597355409059465520468869175466632446875430377637660889879,13466459020798488583841582724067017412922317425102130151754649408559458307937,14062280191830459071860023268317938748180670907089383563443465249500572357980,18486553995294693573565546696966437493113894571993019524170031057367640632085,11156566424349445901806390826392443373766529722049710427351550423908421767094,209671637225069235519570008386635562520193585953162475265417907100134848923,17226989944018790920809176115775819865824823495740082575382169759054625372382,15644589951345053163188258692419292119540702867922222648564209455819510994564,3689635641036835670663293726548900381724135109917216986885298700630212836435,3367607896403464195671402279459329078003744183784952830994679539910724667259,6227320552634621985217890398406127207902736210419315868051857823685244516725,7357930890687295365886228617478473072206575811998185548162905341534675558305,9337019296542497689612612043175604595811913796434346282222317112981594913389,14658782859891978670907070276103444826326577838777644289370207112293812556778,1700861002075407761970169168361393086239805454951858464329713573177596208454,8422307882422345667268572118847227804767508317685246864132851358134342544918,3824678171886439611637777800578730196591582015637069631407414390326082519384,7520989644070067743500997565082513560943860081670904302057616063200273050286,5278276919931895959830110725703210158384647399821914390314400092195592076331,14590632939277529585876696200177152214896495867542780671631701634592299041714,14365499645924743985349770983085181263329435144891175678390938245209017764418,2519790270252875654107597063434691592006935573176284731324585122712988059511,17688843544040778657269233842324532395371012201506418912518394656290716826075,16584068781164994465207120381716024087231836173689783891650623302438290695506,12224860044594664185598615945328866758529752520066027818906177267571423023661,13664317767999211366109254182438581912610775541954425083255023643648887081779,19324196860555787958873349597666822462940695051471419602454830948112942481945,15338841226759355791277440652242849878000656382388414806186764010001628984934,11076363155150973228897602285090741665942726007445165132980573631249449594126,11228309866140794620879641097623963859536328868056691748463227126359575786386,4762608512226640372168720665137259637840828925512114281702049841301872652787,18282645934358125859102195916568492018711932725386725562892735740355836227532,12803228415054755333149187333584509982900042807310255834005394843350472605458,17675693156369747720817703064233611574822178844066411565804543111769294187197,9900029048144575309490519431063332695303076438539483419053219772370202428926,3684590949621971596368895784562632626464811455818343794800044114209066071601,5443335602638685057982926800093482287199751584817191972983546508574786160090,11352900694666160844325992247118358443639716695965864728670968730093466793722,9836739435541786452166525951732520477055729763398281521212184905286650567233,8222926590877635625730738050718327099397892409701316035188479123499338707893,8154558268770648194631329585722892880905143452138234292827603893129808716905,20661038342485310632612091028394348057035659683250957045340774030445861865592,9136910062528018177460276667688174167129493547069053533874280111057356360561,4362513385797089229061458501847196255783651860098500705320631416351847846956,2061137061600029258110405980965338431925491466724330216028866028449889153371,14607676885409772552908782897874144975643999944034675480739173900267789420534,215346512487318428553079809620502708407272005519315271404209452927497999118,18044026902282362371439577283764019415115969502361960218708274179281044595578,9652478245641134951513165220881528043195466248948069255527062590256621034842,20994154929281322813927859895894589885437941429166007529912073756113466975582,20752721666010515144550782025078875036488075535083563976118804420187462745253,20857028711523544595627940704882176284224509745902984714255291431664146535922,9631521770540523913735742126933921923952197512938165111866628665235591582568,18950423265182779471595998716023482060645307106263127634953888715515988505533,1436791836740130330138273456892846001841969807914099860317370076565131805680,18145299176463660895047063984288790313564980703886502044680749544519011424826,7008134596456692891696131297028980612714475387065733972352529833092170154127,18054087496593103261596842546955317831262607456582498514349407492750291465651,2460661191051979147731673103829326449069370361298340160666765010767300969003,1121019547339042268901204213478561141018690742635442229019134496736639790078,13486140142607002128358893931572108539446504181590991898872881746144618091798,14485083458755292442253176062192342099468601222388603924363708902524652589634,17684636079328478898730536417772675839399177918554869673260926729643471105206,12382939536995562937141167025903251534081453604974163882762565576243762872206,5191757256912351314880102858899907666377813090645991709894707944196053941770,18397247107649643640823283145149323187327745749077714626730537494597891967945,21508632378351416585385353654317189405917247727406155133342616741543833680788,19108354768686907995261340253443420621814860995097718380505789237761300853182,3649609518051015699386442513879956346519312025847003339036530556474594795760,11893851425092314587513815253407979901615516208632062595457152391110352908805,13296593391067251947204447959241604616835056311051696511507435925462940176830,18493557674615580922923001229788184231889430766683327472934879670006059540367,7669746659590113244880799806073731587177781693253502772068846650012974230120,19370654200032786851343971085637480775724705092664059950989935645178139099864,1331955346226787928500793024038189892044219824334532771311923855914410290305,14488880297827410405382492933041130286687512096290491259710680579157544248910,6760882547908259908954677726421351194118695606292587659467769365205068189814], - [708458300293891745856425423607721463509413916954480913172999113933455141974,14271228280974236486906321420750465147409060481575418066139408902283524749997,15852878306984329426654933335929774834335684656381336212668681628835945610740,14650063533814858868677752931082459040894187001723054833238582599403791885108,5582010871038992135003913294240928881356211983701117708338786934614118892655,17817167707934144056061336113828482446323869140602919022203233163412357573520,16618894908063983272770489218670262360190849213687934219652137459014587794085,10883405878649359800090160909097238327402403049670067541357916315880123123342,7439184039942350631846254109167666628442833987137988596039526179738154790587,2727663760525187222746025175304386977552466570311228286110141668880678011929,16992375884417886634716738306539629570444547136030480542879886913528563834233,4178586893949624406750122665277033849762243490544460031634329370298105635905,2517914797385699886738929430037355069462619900197972886482360691236776726214,20164173810534657634631187494276970100735049909727379228976555863615716408280,19970958827248077001061220127605534603528515080207197493660642269195127427214,15606275977308968307194602612931727810866183872589808138812916593200446820753,12261436001550634140750381230737452634746867040398895669545077774504957433511,10405309809257831434323731445544896504541938387524726028487604098725193737428,13408856444092113657034337770571899796129642125690066226794939383190876435468,19768080898957882918527124226120459667739640387901357739011662191034806046251,16749889646056241484852997428132695501278739424507088920371060969471495213919,12331609790192161246735870679870317366088443875784324655482358218146673901073,15769331739277556832196167201116801527901089923090632364403958141614820528626,5227172275505968397128736045169568430462701766148126842874241545343535393924,919073378344729780131814412541912290691661039815032069498359347682919854836,17858725475505870077023114050620337312678855554361132257763133392017321111169,21805188450184460363143840112266872832328782034569970452376470141743078343745,15808413311863154368918155104905222670782553225279887458053980771135357021692,12828907214414139667587331812274388831051429093098655261887619166452245292431,19323880880917307340820066456419195877039970908109908221992925424585030574269,17591732412986269470826282099678922890996647592922237928486497997144096433314,5282593184575641056912422403901924986019740793240905758215569065763629999318,16013130707598525718519250412251656096494468043256226360413191733653074896117,928381583587170989315021718439506896903185927814675820160976165627097308915,13354336789663524324458402003354905134416094005220899335023797754517805691310,8780135673134081873589118311874067764073719549433574820315100541871522642766,3334957744389892864165113989538814646945861179021194859030934481494560681812,10553413566358881045095498839713459314577909144176577153981801574128014927353,18894321506279909207228932263261226433242541255661384643559047811974513999438,20211894014628303327332299342564779073614790317614402383971270594430055013904,16723480621932556506775906903415088312771104391224076734252099577243237899106,1131872547334579236404174618548801749854242069301712398106619948805304881636,17386814048141719093058723520379257085987299288710382497237609774141718421404,13729980537487612221640320393867198844745491357830417754869369043292518007370,15860780436383591737179656321807464721751913977397035980422407138400867838633,14708550460111247278740231297332510059116901767161326454481923990389610737973,3132820559166321299152015048428879769905404947939291493327190426785911502819,8658132367999084824971296219169212568783540935524918908332001856872807119287,21064783047501777742084787259676320053480170916619513986794406566953069418035,20731000104011695148048713576219525164619502119638555785381543866326561323,17189725817866212967650950297463469529475851286172280116066228706121595462088,3310440878606659516028312898499559492876015493892608849966645073367377278233,18463918215326370595980949760897480127622730018343709491036454088497976892863,10894192430593140913557164014343360386192963621862346779515699758352916852228,5060610877870389107953459328006060153180283860738879092399406248484265273634,9068988823145592214189961315730261367007076042069390630024839612151270430414,13160707893890865447331361630522644819624543031829773191665491273833460019183,13920568292534026180186486064598876780779571940988254327823480971820885713801,3894011501178134026216736522445829906312115650019712122802932677318433032635,17895318821130376385979570244603067634449453259842805202694945793852667231847,9777993060458301797155055013115849176281006051494461044565335406558308324220,16521293541516305251718414192107787058980727971856888501176820100904791554730,7744063601405355255689420547832904761861257642931934580021876189691881462544,5444730929053688962452159157646022068806222098484627080046464163159451208522,1524118152994294864739915388438939180298324297960159419600850033701763764640,1334622237342346242862023763160346671504959163544406543315614662442562816653,16126317914306849967682996412350336172782726693375105190424151365140854833923,6345975085253358297751050638846919833013142450462810543971050115910612860460,2703875280053263252177031410407166981522153304496807669518295313468095058674,20550626512184448884716175825490086259235894802178999642552696391947509065676,15013718986700828670892638677446258841869291160144196138236407826511808592486,4682264015512203762723381542642871160915706748420642731100634327658667608042,12834108073603507925748862283503586970613250684810871463629807392488566121352,8422606792378744850363509404165092879785007388646473871019846954536829739979,9339209090550177650528715604504958143078492516052997365409534971861874881780,9141831918422847136631159987994781722269889810731887947045878986971886716767,18329180549061748373684938917948729366786279119056979983310618862430068636631,2009551904565170718789964252583363785971078331314490170341991643087565227885,3859729780601667888281187160881197567257456581829833310753128034179061564519,8535335342372994336873304745903510543599314397287086554558824692658347277251,14148514289641991520153975838000398174635263164584825009402034843810351225518] + [ + 0x2088ce9534577bf38be7bc457f2756d558d66e0c07b9cc001a580bd42cda0e77, + 0x1b86e63908c4b12af43cec6810356c94d21c9e37d73dfff9742a58e0ec356be1, + 0x9ca022ba1142d170f755212e2edc9d0a4ace33e16825f540d5d50d5a021a169, + 0x277e69d47a133804241f6aebe9449be6e22c849c6d8ad8c938eaf613bc1aecd4, + 0x17b57ea03754e24ae0ef425aa2ad931aac9ba5457a18cec594545a235db6b269, + 0x11c740983395e0f4a026e2c7c939236375c9077755eb1a37a77d5a1fd74abac6, + 0x1cd85529010dd7e2fb7ea403515bab5727556a479c59b822efc5a81eb37bc5bd, + 0x2cb9354002cec4bcbfa985de34f43d702ced83d197aa374b5a1f96f87b12f292, + 0x1f7af98e08f6877923f27a3dad40c525ac52f56fbbd878506544f9acd61aa32d, + 0x1a0b807de55ef1263cb74d73f1c8bf3403bb3f1e03cc502a9e2b8d423688ec18, + 0x1fd59a493af01f538eaee9b1cbcb2cd1b799d6093f0159107344047c2158d90d, + 0x1d3fa4c04d54e5263e743a2fa010370098773853777b73c7c92af64eea079612, + 0x1dc892a8d006e9b99d597f449d0553ebb51b259319ab9d8b2d02ed9c6582c232, + 0x2a0537379dcab76d9308d2699e0e900109318a740c75b8ee1ba71120edbfe071, + 0x149d2cc892e7cbc1f4102493bb96b4a36928dcf62f7dba6d9e0d446f5ffd4fa1, + 0x1e49f2771b7510aea77ee000e757ac105699c62a33a418ebda572969037b5bc8, + 0x5649ffbf48a15d39385cb62912bf049e9706155ff3dd43f7ce0e4cb35c86c3d, + 0x2698b359bbb3686b626831d596fc5b5039f4af516bc683a289876271ed62897b, + 0xcd8c08efc5d2bc627ee727dac325af99b4f72ac70f61c890b0593eb03c8cd2, + 0x36a9a9ad327aa70232cfe6c78884ec23aea703814c701a1862789367b45b3f5, + 0x2b5899d038a234824746d697d38ff423459f7bd4015782f528a3705a6f2feb9f, + 0x2524bd7a1969744168f11aa03fa82da034edcd1c31141420b2309344d2741aef, + 0x89189570593679da35b668bd5b3542489bab1022dd790ca6a99c09ed0a79aca, + 0x6608970a49c0ea65f21a544c215ebd89b4023c387e8339ec7c9cb80b6b87ae4, + 0x283a6336d81e02e8dcfbd4be67fcd7f8b73cff4ce3f8a7f3451b26e81679309d, + 0x14536ea1bd43af4d7927054ecdc962563f6f396e372f35cae0e5218d62bff454, + 0x3036ae3f4cef8a4a0a324f409f290c172e5ec23a34f75d57233a04a055648e00, + 0x22262d9a1cb0b5941b3f193c381403425b83e6fd9e1b4d930183148e414db99d, + 0x1555e4726cf5d78d11b66f4969724e64be8dc3047d0953aa84be42c4a3ab4098, + 0x2a3e9e52ac1fa4915e262406c27cecf24b0411fa674ea5046ac44897629e8544, + 0x14d8abc9700624bfc54939ff64f75e0ad187662ddd0215e3cfff56a350371231, + 0x1e0eb685b561bdcc6cb793504a4c1b5056af33ddf6f5e93c72396f6e53eeaaa5, + 0x2e7e146d9111c11d9348ec2230270bf211b4325c2e878d09faedef98bcd10dbd, + 0x18c036ef9e573369755af33142bb856437f6498fb1162b8f8af4523c390b09b2, + 0x195ce383cf5b4e65acdb300d6e359320ea6bac8fa881456c72526b4513ee1d71, + 0xc12860b292d22e5520d416427e1ff80eeeeee47799b322e0580c2d45d60e6ac, + 0x2ff73b859f68c9b8eaa94078545f54dd1e9dfd74fdd762dd65f522af19ec3ffe, + 0x1205dc46155d9cc22a89e838ff1a462738d3ef1972a01864c72af0f342e524ff, + 0xfecb680ff19b124ce745b6f70fba1b91716e12f664fe93562d93700adf0bc45, + 0x234391b786f9498db2680c6e7aabf4b0ace0f0368e21eff94528d051128cbc6a, + 0x2937dad89e2bf12f95cce70dbe3ba4c2ee0184226387421bd18038894ceaedc9, + 0x22c7ab9a912c2aa92e2afd4749e70968322f7e5750ce6c697dcb34446102b85a, + 0x1bdd8241cc91cf091780328ea6a0ca6dae8c10c50796006d462455b90e7f600e, + 0x49e3eb4d3bdb8ea3fb6ec3dc065556eace18a719864184b36da835bf3e8de11, + 0x20a8611ee3a91a1513e11ae962ec82884ba24f32171939892a34ec6d4622a88b, + 0x27d281f482154b5c001ca383a1087bb1481782f2bb457fb32505ff63315ec376, + 0x530c5ee45b6b16abc8306ebbf102a1c0774f8618699278d5d3a99f42495a3f0, + 0x256f402ec1732288a2ae27f56a2fee2199bde67ca2917984e2a6c7f3952a8e32, + 0xed544bd301d33d4b9ef359de3bf01e61397f2f29911944c5d091ddbc518e146, + 0x1370ffbb023d66ee62ec3895f61de73212207ab83194bf6cb1d49d37bdd4f34d, + 0x2a46d5538a5a9bdaf47e44594f3092112e755cdde1a6c128568994a040e9a04e, + 0x1f3396d7db31c19111069135ef2d095c1aafbe2c76d7cc387944b2f137edba64, + 0x225f3203fed96b846724c146b3d3b351d6615ee5cb1df8390a02a715ee206f18, + 0xb405da3510e7abe759298137d4853f651e35b7660028d9ce680ef29db4c22b, + 0x162df9d9cf874a89630d906160abd114b09274c010636c440c3773b5f012374c, + 0x26349d07dbfe862f47393d354491dffd8ed56bcc1424d45dc3292669be8ce0d3, + 0x1a75a0ebd02bd60bf851e0cc564a07ca5145d4ecb970625acc7f225480e29903, + 0x22dc35316d34324dc4fc4812b24468a33b94bd1187fde4092670d789f8372ba0, + 0x1f260c2068ddd344bf8fd0d985ad999e0a2a0b345b5d4e15647c60a0019ddeb9, + 0x43098906f60ba8b964c3d33854bea3bfc728ebd374b871eb716e1bee8f6fa81, + 0x17fc06025f7d0132912f6cd189b75845e8a8ebe264a3561610ec2db4cb22f800, + 0x1853501b6a22237cf790f64d592e46b76bd78d7a6e11a86a5e964bfdf98b35f8, + 0x13f85a860c328d7fe96970fbb13dac19233067b186ddca81f7b805dc7e8d4de0, + 0x2553858a2dfdee2556d24923c609eb3bd92e58f1cab1c406317019df0bddfbc7, + 0x18db95df1ef5cac1f4d5e21dd81e4e7d4fbf98deef329bac3e4744b2f72cc2d, + 0x218cfa400a003da69ff396f9a2fb282d544a43697b68fc6baccccd9cf9933939, + 0x15b192afdaf7ccc461209127b95647cd661c37044642f0207cc9cc699ee8a3fa, + 0xfa2a193cc8addadf7766d712c7af10074bc8149460ee35b5c78d15cf527034e, + 0x6f3dd41dd4a94658628fa7cfc17eb024a59ceacd9ef0fc0617f275cd9dc0fc5, + 0x7a9cbf46611387ced1b18c4f371d582cd7b05a50caf7e230a3b5fc9e028bae2, + 0x135f98871577c5e638e56325377721fbcbd590d85e93ed310fc1c0c802dd06a0, + 0xe8f8ada4fffe0a6b9faff17f6a926f28ffc38d958ddf259ddf4090083bd66e, + 0x225df6aa9bc49e9b2f5c8dc81e15c91ec1064db201be633f1e5fce6bc5b9b6a0, + 0x171c3bf7f45ba571930991e63dc8f4d823ea1d885357a37f7825274e9b9e0d40, + 0x171207761f4d71c5d5fa62352b306da902f0259f4c0470bc82409144feb9acf3, + 0x26a8805900a6087f4d916c5f8b752ab3211023d730a1c5f745d9122fd9c19973, + 0x129433d6ab5a8f5443489c357b69bc0c27cac6ae3c24997e5728ffc76439d5b9, + 0x1c0c02bd9a4f7a36fc2ad938f9a742c0af5d7745f1f0ac5b664aa3e4057a6f18, + 0x165ff7309c19adfcc8ee6ddf752f94fa5c24bd0e3ebdbac72c1fb06aef56dfb0, + 0x26b387d2dcda5acfe48872f1c9077083043981a4d22ec361830489ccb49d384c, + 0x136f73b20066bf9bb629e14dc8524e6026c159059fdbf51160066ef7c416be4c, + 0x2ab4b86e7cde3982d2e88235c312d1413d85e69d3f5d51bff97f8521bd7c35b0, + 0x15ab3bf7cdd8944501d4f6e1fbf9bcc650c5b7a96860f75ce08f5299a560e3ca, + 0x63757b1ee01190b18aaa9078ce6c59b4ff979a43897f7ac41f667ac1300c522, + 0x7235d5c897327b9b2dea43a9c924d63adf0962c8024e9486b31c7f7dc93f93d, + 0xc793e095f24f97300294b90f9c734241509ae31ac0e13f9f1df46e0fe537f8c, + 0x16c461135e143c6fb08d9c33fe385b0c7a012bc208fa6671e4619534b3e73139, + 0x3695a3fcb6f3778dd4884dad62e4e86c750e28d14fb31cd59567e3aefd0fb71, + 0x17501f012f54c4f196aa31cbd91bb126c254f553e55d4ab844f4d4c689d1a1fb, + 0x20ff8c2701723ebe114d932d485fb4af9af641e52cab0d5390db4dc624295cd8, + 0x605d48243e21cfef1ed9130f5844a0c14c790624b93ec98930d250c1b410bbf, + 0xffa032ab9b633d34909bb748a498d1d76f82057973eccae9fcfac45f50ea6e6, + 0x202d96f16f6276129f835fccc83f52e4cc1a7d5f2ac32ae4363e9421f6704beb, + 0x97e3fd4d35bd1394cd482c2fe4bc3c02881e452adbf58858a24106a1cbf0ad6, + 0x277c2847ae8ca64446c9d04e2be45b786a4ffdc7dd1d27d6bc978db85ac85ac8, + 0x3410aa7a2038d75d33082a5fd6bd77d018578ad7fba9f7712e4f41e7d397e6f, + 0xff02f1d79d410c828dd44c6338c31048ced79c8aadbc45afe4559dabec02981, + 0x49e781f466e2561b92d45a40fb76025afb1732b39a48dbae1c5542272b1e126, + 0xa88c49a585914a1ad99805da9dec850fffb2bbda64f7b509516a6713b884286, + 0x45e7bc4beec7107b2edf2649f982863c6e106589588189eb0c9de4b0e039017, + 0x828aea263b9f5db239f9c49e36a2e8cdc8e348f58904138e089cfcb8470ae5b, + 0x253955f1058a3387b40981cdfb33b74623817a3894b51087d3f9a4b39d716a10, + 0x177c69bc3df7a463c4d26b065562461ef1caff9c92d3bb143ce2b29be13b2336, + 0x14d6068c39b97b9a103cb0d40e9a8bf3ef7a6c7bd1d622d7da57b7a22cb1dfab, + 0x25dd2b57b4799f6110366e0baea665aa42325019581b8901fcaf78864b51f107, + 0x305ec758fa6ebbe5ce50bb2f16ec00d0430133a0dfd4cd79c12d69f8cc0e8ec3, + 0x11ac0a8009ce27d3e2183e31dd0175f81284b37c9f6e714e82de746969c98865, + 0x1d109b8b68f442a09a062c5a663a0935a96a91219587efcf3e95f0aa293578e5, + 0xc7b0a104e403dadc80eef55d68fd56d56aeffc40bedad4f44b2ebe780d08ae1, + 0x1807654841ffb72e7b046942c0080d97f43191c6d2e78b70e69ff867015cfa78, + 0x1b63da1a99ed90f40b0292180dba78b6e09454b75bde64ac9e5ccaf2b2b64043, + 0xd7e5c4d321bc6d180104e6a134450b8a62034e98d72c9318c61176453c96d4, + 0x2e252a397bdf1b53547239e3c6e9bb5260c1905930644e22985f41eb6a226f4d, + 0xbe3e9b1a8abdb889375ae6082e14e37bdd21b8e2a675ea56626e9f4b9d57c81, + 0x161b52904a998f03ea62ae67b561f1d74804ce154f928c1e086731d68efb5213, + 0x852f56672fc06cbe726036617efd210b8025c85b96766e95925e17f08564aff, + 0x21c4e873d8d03af989f22dbe4fa0a6af2a8719d289707ae506b39518349b6cbf, + 0x1ac41a44314ee18b9f9d4fdca582a052c9b69c09309ae447404b3ba58104581e, + 0xee333ba934442e498cede6609a1828ffce94cf07fa7b14c1c991889ad1448d9, + 0x2996c68d007ea8d16c014fdb33190fa58ee5de793f07fe4413ee3a4fca43466f, + 0x23f678b22fec25ba357cc068eb259f114754a65477022abe24cd07507825fc17, + 0x1f6c82714288549da4646534547189349ec908aa2fa02729e979df6a5882855b, + 0x1f818e74b9c3a490b612926bfe89e7947168d343c78084a3bedf771216014354, + 0x206833435ec4988772ee1f0ebb9313319cb243705c1313de603fdf61a323ef04, + 0x171785b03104df15a632aaf4dc7cb7acf47934c72c96310f1342500805120d11, + 0x20b7363891cd3589efe83abb91d9f2e6c59b575b8d3ada6c6cc84faf06763db0, + 0x2d60609bc685d0925cdec6f78d731df0a040638a754da555b8bfe26536a325d, + 0x1a91979ab3ad3401872d210b3b41347d44312e5d58df0c1217881d544ba301ab, + 0x166546d364e42050f2c39d196dd4189ae824a570d39c02ae6a85d82b00419bfc, + 0x1ac2089f74aa7d61b7c44c57ebbb6751be4c8a22b2f82f13b513959bc2f200c9, + 0x908ca864a04bcf677dba3cd272c6a1770e7a9c6381eedbf9f0491b02800ff0e, + 0x24bc8a866d9b7bed9242ed6a482252db77e9d83ace606293193994aaa126e72f, + 0x17a33b4d4a0821176c406b479e38da80d26522fec0931f218c8e54e269b0ffac, + 0x12d6d179f18bf6c6c13661026c0fdcfee596af082545f3299e05a8a78bff2e28, + 0x15c7fb9fcf8f1a92cf0c677fe58b79065a5a502d778ac6967c022f6f31132405 + ], + [ + [ + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x607cd8ff9b889773c9eb68b8a4366469d470cd7c6004106caae95c10c424419, + 0x1da524cff60b64856dc1f5dde0ff62da7b182da26908f6ba6e590adebf91b40c, + 0x22f33eaee3c481e65801b761a72832908f066fe21dab5fa5ec1d4c6e99dd6dfc, + 0x75f84e9c719bb8de8e61083290daff19aaa4337454e5ba804257787470f2f54, + 0x2084be9a57e9adb80303a8dcaffd4bb77adb6815168b36a1d363b38425437135, + 0xb303449f1bf4b92d2cbc26ab34b4215b6dd7af010747a705b2a6e3398882922, + 0xc099bc68243537203f97254f08dfb7efc09de8f96d72f3b3e0aaded45e18b4a, + 0x1c5fd9060d4e0d999264429a5004c165570bd1675b09f977708b1ca48e616388 + ], + [ + 0x1f8d3a9d2d31ab32d9bdb6375170dbba89f6f8f74d16e4fd02f3675d5fe2baad, + 0x2591580b73e7b5d5f34d9fdc0cf7fe3de7f6a18a255e4376fde3eb31dfa51d79, + 0x2bb4565893b6ffc5799139cdc151158749c2c65db48672abaf24c5b3813c0e2b, + 0x1c5ce77776893d48147444b9f6d66a4da29c95707de832756c739eab8e87658f, + 0x175505391c619b75530fa83e513184381e603d8449d1e070017ee8ec0a4d25f9, + 0x6ed1d14dedf763a3065f27e7a46d7fbf20d2b4e86a0db86692a269767d577e3, + 0x140cdda33bb7a79b2baa851df5ad459e7df569b9f2c3da542d3b8d5b76b356ce, + 0x35e9ecc464cb431cc92c3356e8a98547e843ed1324c1e971179fd1ad9fd51a0, + 0x129f06c930edd36fc2fb7044a6332751a2e3bcdbe756d883716cead6bc7063cb + ], + [ + 0x230c694139416f40422d713e13c056c45c3c631b346854523970eaea58a37df4, + 0x93cff12150aecb3465c4c99f044be85dcc1eba21d429132c2260dd3d12ea441, + 0x25081a00fc20ae366b1fe7ea6b09e62a51f6fd377f608368c12ba4e3bf89935f, + 0x2ab8edd22fbe2a1cd3ce9a4212d0efb282ccac28af4d876fc946203070c920bd, + 0x29c5ce97710c1578a0990d862cf881badf10e4f6bde629199e803cd1c426be4e, + 0x1324544a54174cf7b3cd8ffc4b86320f2319d9b88c1779b89b1916018f3fb9b7, + 0x1d18b25aac98b282e10b5a3a74ce5caa169a5c30bae52bba280ed517f3f82fef, + 0x2f35e921dae87f1284c0c8ae737dbdc4936cbbb03a03a5918552fe565270a8d, + 0x14a5ce1603228d6e6fade57c1da536659ba46d1b25566f12c28debcbedc5b4f4 + ], + [ + 0x2063a461ad06315ae5992a53a14bb598367624afc2833ccbb83af92ca0f6a334, + 0x59116da88a081267dd888204fc6fb79046c3297ccb65f9e0fe0d50b4db44ec6, + 0x1b43719cd10b60c5647c097d1fa84b8f3c12c9c475ade13b388c7ec47240be11, + 0x26e49154acca24424d5f8d29f650f9824de82eb7887329cbc83a56ae01dee4a2, + 0x2caf86cff60521ccc5ec6e2e2c83b4707bb90f948644bfaa8f80b0afcd4cde10, + 0x2e923ea46d492247e12e0a7dccf6620f5eea6629b7532b3af246809398859633, + 0x1ec6c32f513b8f30c7aab42e7d91aecbe54aeb188a84f8ca46bd7e9741b9a389, + 0x23a72c27f4f5e6ea5325d5b368f98b40693b2db1e8ca3d096739753dc5678303, + 0x143617efcdbbc0d27a091f28039eba8abb39392e2a462850b1f9cd8532f5075f + ], + [ + 0xc574e628f84b6ba9d17b9d2bfd4747e06dd68cda2383d64ce365927098c046f, + 0x2c948497373514e7d9846dea9ddf5755337ddb661043d6c628cecb8f55173bd8, + 0x22dd201ecbab94a2ee393796fefcca63aa54d9a19ab9c7f20a0bedcfb9d191f2, + 0xbadd77f516d4fa321d1099bc1e51909001591ad9919f08ce9718aeeb2bca4d6, + 0x24f92793d67638b4abfdf48ce3b62ab5d0e1b250dc274d746f2f7d0544185b62, + 0xbbbbb87eccc91d5fb07b6c55088ca514d68ddd93cf31c8ed2d2cc7f23b22b, + 0x89beeb21c346cb9bc182aa2b70f853f1a2258d56893ce5a948d9c645ecbc9bb, + 0xe07b1d22eed54fdf966ffdfbcebb653b5dac3b2a91f50272876efb17158be2c, + 0x2885f2d44be0ecff57d92a4384edb5bebfb585bb23eae2a2ea50806bab8b7bd7 + ], + [ + 0x276428d88040a3e0f442424d2ffcb8d19becf3fb6ca02c1b5c61b5ddc53ceb90, + 0x2c2729812be9ed432e75709133119cb0a14e1b6ea31c1279b7c3e495deaf108e, + 0xb8e79838cd30707999c621621e77e69c0f433d543b79c668cf379b6623bac84, + 0x23671c5d1fb556063a64b5f664340936dc5ffedd4bdbaa2e96205704da5864f5, + 0x2809dfe24c7fd7cd49b97b27150f4d38a340b60f0733fd4530cd4269b4811e4, + 0x26010a3f5295bb4481310cbca5384a47af0f9905e4c76bf54b870ef0ffefa1c8, + 0x2790643a66038cce4a6488847d8d2da2eea84961f8134b1be36947f803527e67, + 0x5fa56d431d4bd09625a86d3623464dc90bd541ea41748f2026f65025ea9d2f2, + 0x4715db6d86b513d002589f1f9522f7de3b1a8bd702c167559ede97da2c0076d + ], + [ + 0x24bdf6101b2f223174e869d6aecbe8ea5b04a14c38fdf1494393cc6fdb3e42a5, + 0x2280d6d4718f9f06b551a988408f0515070e455ed63377e910be087fb79bd191, + 0x2082d5647658eae648936cefbedfad2cd0538572aa6122ca68ccced68f432f4, + 0x20d7202ccde24901d6ce2d107e79e1fd78d6c9398ba7a4996f116adef14def3, + 0x26709688150ed035f959687edf7747ee8ee946b770173dbe50390ab8c08c5f9c, + 0x751a4a4af246255ce412c4bb47fa34a51b8628f3cd902077775c8fa488e7519, + 0x159e25e00326a76f25c1143a5be6f53fa51ccf368d9974cc6d93cce8eb81d37c, + 0x2d6f3e0e98413d5d6a1101b245c9e711bb2e956e27a5870784fd5403b39867cc, + 0x88887966c079d2e689a8d6d7bd913e92d326959bada59b99a653feaadf6c467 + ], + [ + 0x180fca184150c0e354b4b3a4a075824d4b68e8274943f4dd8b0c64eca25dc68e, + 0x1b1bba125505ae9675bcec7c9af579c5cc83533c9d555be398afa09cbf95d6a7, + 0x277bae2fc597a536adbe9c24bc8ee81731eddb574c6a5142c1c5a48c51f82e81, + 0x1d86496995f14264e7a054cc8224900368775c3e5ac6b5f54285f4a73c2171ae, + 0x1e5ae4c295ad5a17e00f973f136f1230a6fb85637631b306d3705f80effac24a, + 0x28d2351619ccc6fb31ad4206e2c064bf4d9b2292b28463e53e4771f10670ddbf, + 0x2486b884370d49a003fd041e800f0a898ab61b5e947997461ee3284241f3baaa, + 0x213176bc1a04939fe7d6bc30691aabd6152ed24f309bff3939a0d91d54c67a66, + 0x12ded41f8047da3e6c22bfed3ec5bb52d027e560048db4c0f96ca9fa85e17bc3 + ], + [ + 0x10726dcff87299c8532159976607633f1bc2ad24453c1bab26b726b82d756ebb, + 0x17013257716d3cbae28e1c272cb6aaa2844136049ffbca05ca201523032c64d4, + 0x30354c9f29c920c05e99d7cc747510e76f7fa69a71594a290eae7293c5a48441, + 0x136961746d34fd196025173c4d79bf8b3d1d05291c584928d97258fd5fb4fb4e, + 0x2310e2337e4d53c1635da18a2722178d55af583591bcc317eba842df247deaa9, + 0x1815e4f7b40a7027878640a6cdc4b2854300cf6fd4953c2ac2c77625ef44ae04, + 0x111efc136a9dfe0ebcffae8943e679cc0fbf62fd0ce03b409fecd932a8281b10, + 0xa5a1148dad4562eab18162b3914b64d5753e9617a5154e93f7e43e6860687ea, + 0x1f47c67a4325672f17b8bd1ddbd80e4e9e6c62419a9c204cc7e8821892431aae + ] + ], + [ +[ +0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, +0x7341fdd8b6d7c94a710e78e47ae71d8a2d2c45bf48dcd6fe346d2f9263adce, +0x1c4350bba48cff51ab2e0c56301b9d3b289a6fc4744b61fb90dd5bec31107ebf, +0xc6c426215bd132ce2efae38e5bcd7cbda5cbbff829320f99be9dbda88fa8a3d, +0x2810b0317abd6345a234fbe4661070c9bbd1712c64d04bc8430847e6a5435a22, +0x16ccf6000486cf0ee9eb858de4de15afda028275ae86398b37a27f1586257f4d, +0x1756383b6b2b1db75e494e291804c5ad7d947d6c79dfbc5e72009f11b69c3503, +0x55fe8568018f82fd47de970828d3b5f30fa7f671670bf1b615f8ab4b5df6c4b, +0x21b8cb5fcab5ac1e4a8e968e95a134731f85c9fb488d200998c1152f49d3c599 +], +[ +0x1f8d3a9d2d31ab32d9bdb6375170dbba89f6f8f74d16e4fd02f3675d5fe2baad, +0x3d8602794854484bae8cefc996d566594d166c98e8dbb73e70c0ee829da35d6, +0x1c6b76e0d60e628fd7ca0d7d60de7382c8c7ffdabefcce98d45a1042b4330121, +0x2deecde3659cb16fae536b2a1d81ddc50da450c1e96c100a58157b0b2707ae8c, +0x1ecce2c394a577ba99982bf4035574776ae9fbf51aa4b218a363eb0bd1b743b3, +0xb754798119ccd26f34de2ad1caefa4fc586ec4d6bcad8788a831331802bebe4, +0xf246352b2864232a8afd890b5a5c1114127ff9e80e539b5d922b3d53b4c2cb6, +0x1d6fb6b7c89bb84d5f7fa77fcc40ae0bdb914388f6578747f62f388344139ce6, +0x1aab4fcdeeec99f73a94f5e8503b377394eeea13c9c345d177c7b97923b1014d +], +[ +0x230c694139416f40422d713e13c056c45c3c631b346854523970eaea58a37df4, +0x20151c663660a16fc26c7452d683b1ae0a4bfe25e01e2d2ff682d6f8c5ad91fd, +0x22d746e18a8eb6059d6913f3d2219fe1d1abfcb21936bf4462f3deabb86ca232, +0x12bf39e8f879b7dfefaa4be7d615736957975d6b386c0cc89bb81a1b381f05dc, +0xd639e4276aa71f97d6d061929e08d78b690054d7933907c91989891d7e04496, +0x22d621427b2b65407fda26214625aa8cdaab5e27bf99cb8f8aef492030fd40e6, +0x1f9ed3d81ff1494a3e555e532cec14085a7d2897ca721cfb41627fd387d4c6ee, +0x1202c35b5378961b68f410413270c6c5eb4861f5f016891a9d3101da67f24c24, +0x1fc69a3e806ab5007fb930b1c0e8837529f3c18357d74533f14c2152147b6a88 +], +[ +0x2063a461ad06315ae5992a53a14bb598367624afc2833ccbb83af92ca0f6a334, +0x14be2c9eea6708b8055784ff7a6eaef5f2423ecd3c987507edb4d57f42263c8a, +0x1c94e3008e7fb1ccf9b36a3b272b4ebf56872e9d3ad09fc7fec8b73f3edc8dbd, +0x19c33a1bef2695e72cd132a78c4893d762540fa2eb33c56a7e4b6f88a15ffdf1, +0x129cda4d6b758aae7d636a11364f08165187bfb7cffdf51c90e7f6feeaa44d7, +0x14fd9137c30861213d9081982e9c1e3627180371bf7bdde642ce8212b70a5ad1, +0x1835c38dfb0f16b1ec8a341397cfb66317dd543c48852d8ea875827e2d5f68ad, +0x70a63f4db1f63477a7245d0577d38f8ecbbd9fd8a253adf5e36c86f285598bc, +0x1c4546e0f6a7ec769233d0ec55edb3cfbe528b846ed015e41d063b9dd42bf1ff +], +[ +0xc574e628f84b6ba9d17b9d2bfd4747e06dd68cda2383d64ce365927098c046f, +0x21e114b50d11303e7d5e39d69abc346d8c062b3bc70b5a88e0d04c104c89e576, +0x15c4bb533ce05422d3201cd04a12d976dd8d4b41ffb77dbc5f58904d9fee034f, +0x14f45f4497c4a67c90f50bef58ae132c54459facfda9a6afd38dd06113bd09cd, +0x154093b24b8ae3e4c7ecb11ce7f6d10326366c410153cec3543b8f8c696f5fe5, +0x80ef3bf4cf0ee1d45e6e64fb415c76bb901b1ae802c7ddc2f8fcf9a7c4a8f91, +0x1228c23f9d6c7b75373a17d421f64b589d7f486511f846b19d5b5a7a4ae888dd, +0x7d4d3ae7019c26ac7038b866eb5f0b9913b54315d879065236c20ed87c3f2fc, +0x1df9042167db948e9c137df365881a2137baa8afdcc75f9985d2e2a54ff2808 +], +[ +0x276428d88040a3e0f442424d2ffcb8d19becf3fb6ca02c1b5c61b5ddc53ceb90, +0x2d764f3f9ddefa066b449acde74eb4270b819cee10a4125abeb091cdca204756, +0x106913bc4e38bb6868247a3ddb23f7ac12b78d688df4cb4cce0e2a0027317fcb, +0x2968de39216f3f05107f5715ca891c8cc9a238893d7c75e8684813f9b8f489f7, +0x20f194b853c3b9aef7a751d3922d17428d595a02f6e9562f568e2cf07c928ae0, +0x30593e502ac9b6856131ba8d187dfe8d53ad20d4ce7a3b8d89ed228c91045401, +0x2dadaf44fe7fca4988d5777f9324ab2aa8606dd3c4ab4cec318e0dfa9d02d76, +0x2b30b0b25fc57a37cb46759047e4c1906a2d64b1da6bc8048d683a3aae105814, +0x2af620d499b90b1b8bdfbfed437d5c71ffe5112b22d538a33c9511cfe434cfbe +], +[ +0x24bdf6101b2f223174e869d6aecbe8ea5b04a14c38fdf1494393cc6fdb3e42a5, +0x1a8803986af5a84f9aeab49f048c67ee6ffb4689ef31cb51eff59977d250c4c9, +0x2c95ea22f6df6c0975156b08f16516ca905a828aaa2fae35c5465bc99ebd0b07, +0x17aa91194ea3c39030e17603d9b8bb80fdfd271fc603180bf0ec0b49206a76b, +0xf6884885a376b75b81ed233294372cf65cadae30ff9a657ab93592ceb935c95, +0x16a7398598ffc414f79d6d0dcc11eb3830bc6b97917ae1d9c0486fc6a162546d, +0x259a2acc8e87e4a08a384199ee3bdc03df7a3a1b07c83f49fff07b4da49e4ee0, +0x19cfa837f30749fbd33925eabe3b222452dc4f4569c826e602f2397007c0a858, +0x22be9a5ad9f369512913ab2213536ef1ea927d91f42c69c35be9071d3208dd5a +], +[ +0x180fca184150c0e354b4b3a4a075824d4b68e8274943f4dd8b0c64eca25dc68e, +0x1540dc30a1b9aedaf029e5ee97b63a63fa1a47a7c59304e2bd1fe7947ce6774b, +0x302fbf64fe705ee3a34e33211937a3cb487838f3a697e0f77c173999486876b4, +0x202f3f28f786f3047f7030428878b673a3152c0500874263b99f2a3f3652eefa, +0x24145768e616bdf16b3099e09e9e56f114c3ee6fa6e49513c2c4f2b3d0002b54, +0x80ecb13362f44510286df98f696ad51beb124014f31fc8cbd9d2dadfede5e55, +0x10a2dd7c6bdcffcaf5b00340731e2da029f81dea7271c8c19825060cbe5db6db, +0x17bb125cabad9ea535325629cbca4d37e5f30a3bc3c7f12d1aa1b63326974fe6, +0x1f5576505ab6cf76adb88b8a85e1bff7d1ccb35691118d4180034fef90d2a873 +], +[ +0x10726dcff87299c8532159976607633f1bc2ad24453c1bab26b726b82d756ebb, +0xf08d47f49171fd7d603461458053fb30596012a345aca5e6c8d307c5ef68130, +0x1e1e54bb56826529a37fb6b7bfd6af40dc9da70e6f6bdf7fc89787a7a2ed0785, +0x275c0ac30445ca28c7836765c9877e439f0b1308e5b8b5bc30be95808c9b7c03, +0x1d3ecd8624f2fbc7aee4dbeb91ff442a018b9a60b23d7e607ea9eb2f6ab6c239, +0x237522466e8ad65c715717c5273d65815a10185498c9e71b48fb441d90b5e3e6, +0x1f23b760586a694ffd7cba2757f935ade52b1b3593968ada9e0268cd71f6ed64, +0x36083127b4a9a1671954c4ec341dab8d8419322c722061075861b41df631a9, +0x236a813f6235546014ac3a47d20bd75b4b6357e043e1fba18a05ac59a9aded9b +] +], + [ + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x152fa675f337216339a9274b97b08d74eba0f31110688589baac5df73d06ba99, + 0xa60560c145b77121171f32dc6d2fa22fb894749d2686475001e0b4563ddf68e, + 0x2402bc21cbfc23a80116e7535240403b3e7ada326d3f5f28e7071680d1b57df1, + 0x26770c5cda1a14d4003cb55ac927d68a843b0a81acbdf4d1871a66201e3378e8, + 0x4ef6e3423ecb4bd4137b2b7fe78100b84a1ff459cd0a1f7212668bb96ddf0fd, + 0x16c6d4fe10c08c64f2bb14fc6d8d650b05c56fc689a93d0c4c0a79abfcf96887, + 0x1069cff9be3245f60606f94c1f214a3ac43d2249e725dc57d45716d06d905ff2, + 0xaca974e63942bfe230694165a4f72d184d4b7fb8a1674a70cb19cfd61329f13, + 0x15ea665435c28d287bdfd4978bd127392ccd486c9afa99454e9561fa992040b7, + 0x2545f2cb24c7a7c7af6beac75e34deeea9d532c0308187f7bd3b47b133a744fb, + 0x29b34fa5653b3ac5f3eedd790c7b94be1abf24beeb24ee50a34ee12159e94b15, + 0x3d5d55635085b4d05b57f78094a130400e4b60548da9cf59b90baab8e664235, + 0x2b4768592e18dee0d620b4bb3ec1f0892390a9177108346f9fc611e1cf592dc6, + 0x198e90e2b6f066f99bdbb201258054e8758dafdd397a4044af7fe73ebd0b05bc, + 0x209c25806fd4006da67b80c5f7a3fb03990dcfe087375143a7a09cc99aef143d, + 0x125cff70ce16a10ff53be8b26683420c895d366fa9d3763f14d376cbad453b79, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x2fcc1e873c2460c19aa8ea31876a63c06b6b16c56bf45ea23b2979351661c066, + 0x265596228bc6c434d211a6340c4a331df2be3b1e433aee26875876ab83840e3b, + 0x13cd5d84d4458fdf99666b4f567ee9bc2663223fea98383d29668084a67efa07, + 0xe4546898234e2c9981d06fbe84630d92d6854979472695a2aed5aa1c2fc018d, + 0x15ead9f1be93476ca2a93c83125918403b835eb9547d3ce31856d119ae8df0fb, + 0x2209a03017696e3a73afcb978c53731ae3186f4ba315ed5dc8ed6578b3d9e428, + 0x5b358d46bbf09ffb07f06af770b4c3f695e35af5f32f449a912310c69165652, + 0xd4ec14ac84189f1e114ad899c7dff8da5000fb3726ba88b6ed828451e9a4027, + 0x212a27391f1accc7e7e01e05868e41a62a2076efdc6ee94f26c30e5eb5c63359, + 0x1cf3fedf016306b0bbe65fda50235bc16cbcb1559c3f34ea6ee752f4b70b4848, + 0x52d3e0d566bd58d8097a8d1389d1caf33a2f2662de98f06518670773f74215e, + 0x2852bb73795f54c6adc9c635d5e70b03dcd03cc1229046fe2173c31b10efec53, + 0x23b69fe902f42c3489061de846512d346ad54cbde1d54984e26b551b29cfdd89, + 0x8a501e4d110e059ea6a0621d18bd4346af275aaebef1f402449c9f675feaab6, + 0x17f6697583d43520562d008293a70980e2c6564131faab56fd71c285392f5bc4, + 0x1b7e8e80739ab54fb01d2637963a91622ba49401fd5b961e892f00107781788c, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x1cad07b82878b8c153b0278fbb2e90973327826a09fe720d37166bba7c53acea, + 0x988724d5f424785949062a55133a433e27d8c89a7ec78016db5f064cf786948, + 0x2d81921df5457361416733155b8135b53f6410a41170670e3fc8204a0bec2d59, + 0x131cf6530e31b3541b8312eae98495b9b5435a8d32d35e5247c53f3170a58110, + 0x26ca4df270856d7d89521b850e376f46c84685eb832ff0abc83be2e46d008692, + 0x148832d14674b5bd61f45b882d08ce10b65eeda4a8d90caeda39210526a2930e, + 0x19395b170131e4b969e01d8bcd1a6fd6311b3375c0dbd1e31b879fa6835b9dcc, + 0x2617b1f4ad2fdf615bbf88b4efad44b6a7cd5ec6e2c469a94471d5a3add577bc, + 0xe0507aca633caa740518c6ed6ff9ca084bb59a7d0d97decf2530fb6ae3cf24c, + 0x176ed52c8a9f3f7bef3e084c2e5235496a2177f3418364c3eda28fea7f2a6624, + 0x1b1ddd3ed3c82536d4e2cc47820f37b772335bf4530356e590c69938c1ad9eb5, + 0x13c8300e2bc52c8d4c12f2cd9442cdbad38235a1e34541b42a274be0146455ce, + 0x2f5239bdf0e8f441fc01fe081832618bf1b9628cc80ef508dcd4273420cad1f2, + 0x21a41e1e2c6e4922de2cb723d64cbb9496216429a3a5a3c0c6c0019bbbdda93, + 0x3825cc9ed4f752a3a61be70f3f2bae0a22416870a8f692206aecf4570b4d751, + 0x16e3f668cb7ed8c2bd6cb4687d11dfbd02a8265f671cb58a7bb33a03a5238a1, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0xd94596be2cb2587e41dd5ac38707f4a718dda9076b74a2567949a627bcca82e, + 0xda56e7fef653a7528ebcb12a7a01082f7e23054bbf948da64bf2ec2452d098b, + 0x22ed449e9752660719b8d34f4962772d7c7b08e4882442044c73a8aadab72c4a, + 0xca9d3e4986304f7ff2894c105218dab722390273c42c427c4dae8f29d66ca5f, + 0x10b01235bf874a5b2e184a8410ab01107cbf0648040ed6633d179509f5041191, + 0x126206165d8d964565d3220cbc84cdec26a7643c68f7cc42ac60d1f8618a6200, + 0x4878d524f362da3e3aa6dd357f0bb7d5615f26cb758747cdb30490707218854, + 0x21127103c61b8936aa157eb73855ef46d5b01587aa8a199478424f3c84d9adcd, + 0x15d5439ab67e845a1f55af2ced4e06ce2d577a29fe250f1e8116500d11681999, + 0x16a7318212f1751abe1b5c422ff830f1892dfd76737c7b49433e7877358e2db9, + 0x245579de75e5089b4f5f0de11d5b88bc5e395ff9a0747a2d33b8cb3e3394aa91, + 0x2ee3d749e038889f77c0ddc80bb7cd55df093664716a75f0274b1955a8712a06, + 0x277b64ed9137d7914f9445969c33db2f0db95938df3cdad46e6c8d4ac996796d, + 0x28c9181f359dfa1ecfe51ec8331b999c4be610300576e07d8461d468672e9571, + 0x18a1ec6f905a49044a4920d0a4a1f74a907db755d1f06d2d75551c6e9b5bb520, + 0x269587fc49db8b933a31bc6678b4087a12ff762c1a19c3699e0703a39f822906, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x1c423fef62d7ed3b20636135bed12f56c33b6ed3866b4deef95935b4fdb3fcc7, + 0x2c39e9c9ffd3f1acdc23821afad680c199de68c72500ba9affa091fc35d8b230, + 0x200be427ad5d644255178ffba022a54e5ba811aa0a0cdba615991897d312933d, + 0x5bc3aef5509b9df5380dc3ff1806ab689428626a44293af5a2bc33dfd98541d, + 0x19d3a7be7f42755c49327c0865f7df015df793d73c5a036f3beadf16022d1bc7, + 0x1fce5fb51256a4df3e994252d479c8006547bfa2649b9fcbac1e77699f31e917, + 0x24d5b2801c808c74305280fec1d16f0a2185f4f7ea2709627454797e1d694aa9, + 0x1b4a744a7602f165651e06044235910295d5be42f5e5cb902cf1bd0a449f44cb, + 0x221aa0d3a117f313e2a2a20c6927618baff0fc77188801b96188ad8518b419ee, + 0x2cff615d12e087e7d90119fc9c184c7903abe446e206a02d1ade996431e0f282, + 0xcbc5ef09419a755b598b1517a196b2ba15521c55e4b940b410e647a57713310, + 0x243e638c46a410bef0335b65a5e2dfaef63e3030d9c20894d43dd580fb36aeb6, + 0x11ae740f93b3cbb1262d1a6232a4d8c32a9b4e2fcce71620dfcb541a6bf3083e, + 0x14ee58652277e60cf9d5c2690dc83b833c66db0f8a3524d9d73b4b78846b145, + 0x1bda443673db00ba4dbbe09d15420b772ee22d921a43d236368285d42bced6d7, + 0x2de86a4384d67c5e44837bf469091304ab5e77d2eea4421edf64ba3321a12718, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x1b917b840ef31eb7e0a628bc85f7c2c200daa2c53ed4ba7f6a9e1b24b1ddea35, + 0xc54f4f9747bf23552798112aec65d4e9ea425c25e4ffbbfbbc3de49009f8858, + 0x2ebdec8a92cdfa3d690a4419d1928b4b4d93d5f911521cf06140340913462731, + 0x1b74699cc5eb637115960b5f70998323c9c3db826844682cfb8ea43c375673ae, + 0xe09a75d4dbde40d4e18b88f63acf3ab1ce50c80252a3012152ac38fbbdaa61a, + 0xf7c0e52c6acfe356ef5c75f08788edd3e75cbfb209436f7a5d0c3ac9b250c5b, + 0x250fab500f159fe411838e3ac03d2587f7e358cb6c5847df2b427a6c074df62a, + 0xdcc8241d56d88000a8b7aa90f6af3a4fdffa80db18bf815ff7a0b02032b2aea, + 0x1a34b7894985f4d6b216af15dedc398d4ba39351bd325651972de2a64fd810f4, + 0x277bdbfc7a614412262af936a8be70b47e7e5d31537d85ecf155ac3ee482b920, + 0xd3a2e73d19987bba8d72256028ea7052faa7e99aca09d9a08bf0035e402c03f, + 0x1c00718f76c7b7bb506c09b6e1596c137117668022fcab596984aff97c858155, + 0xdbd5f1c327ae5b775eecb71009a20720365c0e482fde75e1bc1371e5c11fcb3, + 0x867c2b4fea85a4cab294824e2276bda8a7406fbcd5da41b6e0fdd8b69a2f1d7, + 0x1d393af52503c0a9aff9fc1da41662cf9a76ad7d3240890bd456a47731a35b4d, + 0xc4efef6ca45633d4ece8715dbdf4b9abe4121a608606d971845e47c70aa5db4, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x280e2e4d9836fd6f43a90fa68a9220a0e5679ad45fb21c8e396dd7c267e5d3a9, + 0x50dcf95a7b3b535a88ef70504cc8a444e78f8b5ef48a3486112408d1aab3b87, + 0x1ded90abdac843e977abebc17ed03d58eacc961cc82dff032df1e60371acbd1b, + 0xc83114862faa4b053ecd3df00bc7bb610d8f777319da6695211696cacc7c2da, + 0x2f38535fca1d0fcb6656a7bc9f8d6fb0951cac281e7204191d124ee1f9597056, + 0x15a8a27ccdf7f31e9c9bdeb0aa12189a62420b3fc3af4c0ccd527bccdfb31261, + 0x8538ca91007b4af17747450f2d048adfbba6ada49300d46163a6141d0d60a23, + 0x219358a11f299fe602b8336d6c74c8ed45e0af3437ee3dbd73c7415dd954f229, + 0x1a7ae67fd2b95fa482e68cfb6adf7a5f703170ef536e0c07c8f45e212331891e, + 0x2d8a33dc859b421d03eb431ef70e9955863e4bfa9a7650cb11f8cfe45521929a, + 0x23e68686a4e6ab0a2e24b04c5f89c2db9b6890816e7305ca2c92a912636772ba, + 0xc27986848ef557c8645754b95ed9edc215e526d52dd369c0777d4f378465d03, + 0x6e2cceaa215aaabf58f2e6ccb3aa062e24e506f3819645131a1f846cfc24749, + 0x4ca455e242a91ca2143ae13d31d0ad024552abe39636c4215d7772512868b97, + 0x20107d5efa2baafdc19cdb78750be25074d5052d77309209d83feaf764ef4493, + 0x284a8c5b8405a825d8acdd215c16bc5170fb4c5460d6e775207047b109fc3e63, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x2617b4b39592cb7eb00834dfb430ac37e799da74e8ea6c2cbac3bff74f3282c3, + 0x260555fed187679e25946324ff117f1f487d75d8811aaeb6afb29e02bf9e9b77, + 0x29d66baa1db480fa0976c227b8be2b1dff6206980b543319ab8e6e46bf1af27b, + 0xcd6ba2405ef9e333036c7567e0e368109489be5791633c12042106eb0dd43b4, + 0xbb6ef374a10b4538ef1ce3c0cf6ef6c885dbc2f449892bfd17e82e7fe9890f5, + 0x294e76b2d0fc3b732ec3ed8f73b8e1c616ee0012b69d61417a4cd5f18f893c00, + 0x2a2d473497afdb60a7008c7dc7ced5a33fed7c5424bb6a1299c24f373e7f16ae, + 0x60533676e96c73a3e183dd8f585c78427c0cbe99e97f8acdb098889df1439ee, + 0x4d3ad331506308539d84de77d62f6cb661c870bc064fd3359cc711a06baf4e5, + 0x23444c530e318b22418fbca527fbf9fff0c2c92d623f365277d65ac7ab90058b, + 0x84a073506da63fae8ee908965d634da2a789160f1ff73faf58b676e5c914b52, + 0x6c1018af2ab1b629440d513a4971e62b2dda42233dadeed10e4629fb1e15c48, + 0xfeae12c9ea34bbf39373aa3c159e553dcf7412caf17269a6c9b7e9dc594adb, + 0x21f5f23b0e3f44f8768aa1ca35edcf5e919eefc9d9dd47e44efcc99694e51b54, + 0x6209e20306d5ff2ae4443bffed0948b2bab65487650f1e1f956c9e5413b168d, + 0xe981747daf6de6e6be60f7ecc28e84be0e4b7e8c07ad2128fbcc12e0c7096b9, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x20802f8ba4a922457a1aefdccc804a9c34b885a1e9f0fd94473479c74e6ae02f, + 0x19cac2ada760fa14ad038d2482dc86661772ae15de0ebe6a1a767082432bfdb, + 0x2c484464a823c43053113755869610b16e5116f2bb1f3e024d65d9206c3c63f3, + 0x20aefc9cd863f976e7e5f601102158b578357e3072ad22e68028640e5513b471, + 0x1310a6b902d3736b0a50a32048c81feb98e02943bdb12700c714bf6b255f3f6c, + 0x28a2e47b087e9828ea526825aef8a8b4d5a36020f87b4672c36a0b3bea12d308, + 0x2edacc0aa69661a65100e4686e467aba4f2c430f61c77707e0ad3c2fac66c096, + 0x23b811e8af4e671b9bfd2c2d83a00883108e704dfdcd7944fa40c20e72e359ad, + 0x36cf4860115229cc61870796bfb55ab6da45a3dd204e1e66af397018f34187b, + 0x1ed097ff6526283590ece731b725b9f734a7f516d6a8b1eabd4120c8d0fce65d, + 0x2242d9a8c934bd0f2b097e37feea098bb500091a496bf689a59b795c8d7469b6, + 0x2e1dbf3119ea622492c1f15dce5addcdecb3ec045028e9ad6a8bccc85a456ef5, + 0x2d034fb552635fa6bd63f5e91ee8d7bfb8a2f1ba395190a177b2bf1aa76642b9, + 0x12c8e6f621ed980c07cca4bef17af232d32c2fd7cb3fcbfc971947e66ecff2f, + 0x548b4a31bab4692a858acd30fe523c42e8f2dce046f2f121b0c82cf5bd306b6, + 0x4985d3b7fc1a4b5fbc70fd37205abe31e33c4beb6f13777967ac5fc07a3df18, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x176ad5e77dbf9eff47130906d9f295bf1139d3cf00fa5ab42bd3e10d357bcda1, + 0x37fc3c302395fca97bfbdbdf5ff14d1f71300057e7d994fedd19f2d779e41b4, + 0x67b7fa5f5b640eea5c1173aa40084c2893f0b66c4d8eedf9e48444de48cbd81, + 0x1ef50a9851144552374b8b175f1a069b99271337c29a94945140eb7e1a9560d0, + 0x4a8f411eae9b96fceee318a3d82e839354b0999e8354ca66bf7f11281c865ba, + 0x17c90c447cd83ef7d547209c4644ac95cc1017bd65360faf58a8cfb5210bc891, + 0x2b324c5a69146a0b1d502937c9f1764757d43065f7c3c7d0a7979552354b3f98, + 0xcd0a626b860fcc13465134f015336740cef85aa91bb7c919d4f1285dbe4953c, + 0x1f2baade720437f5af71bd826e87e155552a95da11c06402c76c8c574707de8b, + 0x1ce2ccd7a415304ac0e6f1b265590359f970553a10bf8df85a55eeebf5cdabe5, + 0x1498ca31f8887cce647ee52fb4b3a177a3d8256354cfbc83ef0349fe3685d1db, + 0xe6e210f18faca167bf3d82bf9f9e58d6e094c03b56dcbd243fa737e0ef93bb3, + 0x12cf450b5228e1b7823665a58c105ab37fb064d287b28f115ccd128cae7e440b, + 0x1fde1a9a7f3a95883481d25eda60225f3dd6f67b127fd2db690aac68bb53fcf2, + 0x16b2c4b1a4276fd90d0803113fda96bd017491d592118ed721b2660a5576b192, + 0x301ae24bfd116b2a5a8ab9c08fe26cbb20d111ec34b7f7b62ad4a95c95531436, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x887f2970f378099bd8129636f847065b81b3cc57e229d2d00a15f314f1b705b, + 0x19b3b01cb6aabb13901f8fb5dc1490ca360284f262672e7f0d39dbbfe0cf5e, + 0x1b3a6e328bf97c4a2bb7b62451d8d21da221d9f79dde1d20961a5730191499e0, + 0x170932e63d8ed05d6b66499f32e6261b8001bddc0ca176081b7fd35f9c2a019c, + 0x1899457555eb5581fddb51340488569c2b4adb0e7e6e1b59a36293b3aef835e0, + 0x164f7a46d01b3ed26cf79280d675584af03ef532ffca9b0aa1fa4c046ab9729, + 0xea2ffdcabe9727588526bbfd56012495f1d56b06a5737726073eb9aa7052aaa, + 0x7ecb58097193ca637d89cd708a6610e9bff056d5d477f0f0baff2fc922d0334, + 0xf47e601e82ed174b715554cd3d5529682511ac8dfe48cf7f2ccc1093a892d5f, + 0x174f79e424542b0e34f0fba0d6451539aa56c56f72fc1b006156f46a7cb7c2ec, + 0x1609850116dfde24d7cb5510912ec1f4bc416f9a5e57cbba8de63a2556af662d, + 0x10ab565bb9cf436914f214352b48bdb7457ecada07f09215c9522fc79701ebed, + 0x25903539c56c72c86dff0d320e4b89921f177b9be69aecca9e52da81175eb5c2, + 0x24be2bc0726dec8e7e12fa3a18808211b32d0725f4d6414911c250223fde21bc, + 0x5522494472ece35e80ca3ef35636e8e5265563cbe43e50a14d77ed0d9f894d7, + 0x2a9d37d9b9bec22eefffec1acf6a2dbdaf5054fd455c300a6763169d4c4c2505, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0xfb784243c37202b1648a784010d674f2ccc662e3e72dc97c1e76f0f815948a1, + 0x993e6aad24c4d252ac53905907ca3610ef2a5e6e48eb3da752bcca5dca973a4, + 0x15fab250b63506ef0b6fbe565b15ca337504a59617751f3e91e75891e8f2fa0a, + 0x22b851ba2d74cc07a36f73cec3f54f2e24f7a5ea54bb5356e5570a4e55ed1f8, + 0xcc28d557fcbe39f2da5a831f97ab31d4c9748a30c1c027286f47660fca9fc27, + 0x392cb28a2f6f3e8bd6f869dee34d83fd84625f658d2c6b02a6acec49940d369, + 0x223232ed91851f7027a7413f23b889f73f18f20ea91b308360b074250eb5b133, + 0x247502139fe5a4fcceafc47ab0835fab3778866a0387f67c0c11730b7086b423, + 0x574e7796304031aa15766be5b419486db72f2cc43798e8a8ee6ade15ea64cb3, + 0x1d18392864858785d134b2848d7fc32cf91da60461efc01731ad49bbb99ce7f0, + 0x2b927f1d1eacf0ee5d3246fec97f13ddb9ba2e34419a7f0fe151f8d366df48a6, + 0x29ca195348764c2600076d9a475508b7fae52d6a9c92196241ac3f08d090459, + 0x291930cdffd0acc873be352600a12a6aa056da7621cf3324e7636f25ef4d905, + 0x13e6e58779312fd8a2ed9368587b5e4c207cb8cb99621f4254a1704c41477656, + 0x74c6fc957511e7287e7b6065c03d55ab19881e2cabab988bcaf997d96b90802, + 0x1da0150f5a7104c25413c83f1edcd3dbcc49a91881af8b3809d40221bbe8cf09, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x17b4a6a22f90ec5575a31b71aa505b70cc19abc0fabedce5dfc7108bd5472ed4, + 0xfb75a413209d1ea511b520b3ad4e96dd0a548ec6d5ce2de9b0edfaf667bf213, + 0x7229fa12e5e9aec5a258249b3667fa5a1a7e9bf69245efdc66a11d4cf9d16eb, + 0x29344527ccc73bd6ae01d4ab76d7d8205643e8c39628e5975b0e68ac647e7dd7, + 0x2e06815f466128d5b0fa1325a96d6f63e513c3c3590f612d01f0ef02fdf74ef5, + 0x2381219c79d22ca23e9bb37cf7f3da8125510c1a9d7e9e26d028ad61f3ba94ab, + 0xf724878c378b234a5bc4fe6f51c000682ce95721afa4c802498ff5f4e3599d, + 0x2961aca4c9ed99dcc5db33902857ae905af926ba044b93d1b8cbfdd82de72c6c, + 0x1a661c53d875032769a8a89ff224b3703864fd77adba88076f9507884ea8dc0e, + 0x20d8c84a77dbf187d873feb492185f9341bd7d20d4c82d4c588009102389aa1, + 0x273944a60bd81f3c014cff9a5e1b1d99079a7db63860abdc5b850138c3ed89bf, + 0x2c3483ea9e8733bc2df8605d84cc2903a10a4f675f803e33090bf1b96d7b6f5, + 0x2c1570fa771ac87f6c1c7dcb0f5efe2ae8bceb26280adb11f1565bdb3234193a, + 0xf8f2bcada2b15807d4e400663abb7ad2a6c653bd3e27352d2aa03cfacebaa3d, + 0x13b356322af7bf7ed892859c3512f21831d23d6ed46bf4c3514762c2a468cddf, + 0xe8ffc445422b035202aeb459085298e5c3d52ad57a4e0c982e4bf6bc430879a, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x266878c7dbb3ebf725baf09bad62441c2a05a8cac838d637371bcb71f7e637ec, + 0x69ca7aea6fe25ee984031f308b491f2a550e4134769d30dd374c0c97ee16568, + 0x190c3bdc4ae56b9371806f99c5247c7f6071ccf725631c6f3435075889f34956, + 0x1d325902dda87290a07b115f3673203fbb2039cf470f229881c786e115ee6abb, + 0x1b2936a6bb1b221aa267ce939f99c211b758c2128f8d544c4d0b5cbc660fcd54, + 0xf9fff4eb7e28845be6a783736f297193297a7cc12caf5dea6f07b5eceaf6323, + 0x20e98cfcb657b1f49c92a069ca501f89e96d73ce0791edd336a7f5e129e5ea11, + 0x15ddf382f5b945869af8a3bd1a030c98d8350e73600aa0e8e1d4ed5e9a89b5a, + 0x93aa5d4e7c2e0b87bf1135f3f0d94b40d59bb293a582031adabfc2a8ab17bed, + 0x83ea048a2fab7aed31a80902174faa9f1960bc2531d18de673fa873fe688207, + 0x4849567874ad0253387252406f2d8860b26b6b605e98c874a585bc157c57a39, + 0x10315d0548c6fde9fd87ab4a523f74d3a5c791e455f90c34b399503fd9662149, + 0x29b768d0c1c037e2c20b133eeeee017166d2797ba47a2e647595e5f0bb433c7c, + 0x2072b5dd1028087414d36c4fcb845d4e4e719885af8f4abfab39fa404fc68e6f, + 0x1434175409254eea7c9b9fc3dd93314403e8cdd56f9cd48348198334c700fe6d, + 0x2da9b2eb148cca6790f4b12286fe560880d75e66bd4c64ef8ee58d7551ca56d0, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x16bfb5fdd4ef9b81e92336ef013f8430727960333b76b5eb81dad8ef220bd284, + 0xf746438c3f4e612f088a4113940619b5d96eec18099f5b912b816fcacd03ac3, + 0x25f8d85e6102bc16cfcb5dfe2a0a6850c4f7d045a3614908d332702320cd2445, + 0x19a23070f8afa08c4a0a2e8a1067db44e95847e5ef5337057437eb68b023ddbe, + 0x19e74aea657fd4206322de101be54c0a70ed001eb5a3b897aadb178cee98303b, + 0x2a32e9f7f76615c5bc2cea017e1e937997d33d011ca2c543dcbf08664f247607, + 0x2eb2f9782b5103cce27210e54c6d760ad28af00a23b0252a608ee0536525990f, + 0x324cbb7ff16c463fd8860a5c6719122702f8f055f721f7c2ad5121d03ccb6a0, + 0x4fb92743eed5177e7a4eec1917d48ba4bf2df9864f477edd9984b5a1b37d95c, + 0x232e90742d5251ee73e1e55ede489421aa4d9b7f731d9209e18ae772b1dbf163, + 0x2888b0287bd050425c3241bd7d5336708c1d2410434d0bb8a094320552499791, + 0x5e878a6e2dcb5fb6176345fb830caf6edf06061a452e94d1d49a862b1563411, + 0x603e7150eb9b06c9c0b94832d53bfacc98e26386e2de0047d289e44483331cd, + 0x40392b8780bb071d2acf492bc6c49d03ab66a7d7d1689f16a47160923d6303e, + 0x27005786e8d1cba94d005f8821f564a42500562da999b4c40163fd15d20a7188, + 0x2f6ee6456256df4b7b4534f97dc725df7d9e359a8af4f84035db5ead72d85594, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x249d2e3a72d67b9ff1c12f00d2e2d15213b2c3d534ee1fa7e0726235d5f8a76e, + 0x66af81c271fdb20f0f7947ba7689567fa0acec8e8760311b200713a3cbf2915, + 0x2d07f33cec08d772afc8a847245583d60fba733b2874e3f14d59770a6eecc1d9, + 0x2b5752992e1969c88ef2bd4cee7cb74d7af5c73b2c43c148d47c0094163b7a03, + 0x17eed7f1d2c6c6d5a9ead4a939871196848682bc2aeb713409769599c6fb99d9, + 0x2b0443e7dd8fa52629acb60c4d9f489a3b485f9bdaa3049cce07b90494140c99, + 0x52e92369cc40d1c0cfa00124ea29c928b85c7b64c1b5a9111c07a33d28cdb7c, + 0x2d590ad359f3f6d0aaf8317cc35b62d92b05b0f5c685cc8c3a369de6d1d1ca99, + 0x2983673217a3388ea6ec1746e62fd0c1d2b2d774e63564ae271d77dba331817d, + 0xd5ce1123b37edc685e8c234f618c830e87b1b95c108a83cd9d5065ce002130f, + 0xf9b69256d0d0e083ba08fdf1bcc73a95b7b378ede36d8066cb024b8820bb003, + 0x290490f51237cd7ab3824f2057a7a2eb725f946442c7987f7392e4c85e8dbd77, + 0x2bd1c921b2655ffb99e5a5de025d08c692fce4e57a3c401fd655e2d05d92a653, + 0x3fec0bf41ee1a2c0a7a0b7ce73053431a26d2b7db92d42a41911e6129e3fa9a, + 0x2d6233e08181a3c9db09017c0160c2ef359139513990884baeee525b2597eb81, + 0xfbc98b8d3b0b6f2b8eb1e780db16d98ef5d4bf4e65ca518e62dc72f693544ac, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x1f04cf1ca4f6db30e843ddcaabd4cc71fcda39b55533db1a8b61488aafaaba74, + 0x1a6f6a78583cddaa58898327f4ca8e00ed729dd41c464fc9ab0c5e0d1b2e9bfc, + 0x3e70e81573bda5c6ab953bcf41581cfe4c65e2d3c04cf1ecf43a2c8ad250d06, + 0x13fb5b6c8df4a5257dd67b782727d8a7d90ca92c5d9a755847a1d3b6b71cdb90, + 0x4d54595c25b41536d1f203e1a367acda8feed3369537ca2557f5da49f290e84, + 0x13671d8ca7ecb93d29c9123bca96103e22f68fc5a16968fe903c0f30e8bd0b44, + 0x1486a9a8302df3771d974c562e1b03b96daff1e1fc6bebe86595d32608a85bd8, + 0x7cd279d7d44931e437f59bef5027f14e49400b0847f4117c762ce21ea66775, + 0x2358686de458647dcf3873e187eaa940fca529dd9398d2eb002a1e6f0878ac8b, + 0x196d60cd8de82119c9360e9ab96b1bc31029ea6bc5a9c891584febe494ad5d53, + 0x1e18e5d708702aec708672582aebcf2e4dad6be0100a7d84f4822e156f2370b2, + 0x18d0a6119479f34c41acce9a1086c6b1a340a3d4eca4bfa561e4205eeeb8438f, + 0x41e39755ed3b12972463551f41d5f1739433b966b759014bdb9d214ad9a6fc0, + 0x1becd98d1916cbaabea2082b8e7f1765f838f2337121baa896e437be5d4278bc, + 0x2d11307d21979b68119899fc08b91e02822cfb7c49ce878ac58584913d6c8a29, + 0x24b7d69ead7cf1c4c204d6d3e23368fd40db0f2df00a4a8388557b6110917538, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x1c414080171ef43535efed9c5babd2275b89e5b175f3b71314f6c59040c97808, + 0x397889b8011160475bb4d6d3379351bf5ecf90800b9cdf57bd3aedb21053cce, + 0x24ca54f1fda634f9bfc0e39b0d4d6a738f7a012898e9c2bfa4a42ed533e52845, + 0x171598e7caa20c990e43306d06b2fbd5879619ac63904e4395a53ad5d60e60cb, + 0x305dda5b8003c236ca1d724beb0335d07aa3b2ade1ba21c59dd763f3019b5ec7, + 0x1ab2ed07578120b399df57c5f109a40e47eaa956e66a6629e1796bde7174bd21, + 0x2a47862d2f0d0629863c878ad7fe7df592ba7f8f3f94e5e5a85aca3958229f76, + 0x1bbc9591c66436dc5cf4bb562468584632cc91a200b1f08e1a28ae61e5c30abe, + 0x265e971c9adce13dd324bc968020828cca064ecf477268ab534265d7e5e2ea21, + 0x1df96d7436aa2918ea082546a9e3e149130fbae6776590846e0632f3570657e1, + 0x10a8c8aaeaea0414d87c0c1553784b744ff2e8965942d3828e14c484f84d2535, + 0x63e4901d2d6197831f94a5ead9b058847ad67bcd8514eda44ca69a0b0ba9c19, + 0x1af00487deaaba2511ec6bba34b8f248a5106b11d69cebe26fb5f35d2745feec, + 0xceb1792ea63e2bace5b317ceff4597ccf3071a67199612396650e8defea646a, + 0x7fc963b8ac37064379d5a652f999038ee4a250e0e3948cba3b899840a119387, + 0x17aa663de33227a947a00ebad16999a905bb2976d0c997a9a5a9fda6690754e2, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x27e7f01f7e5850decff3c8f5c3ee53951fbe076ca41a7e1807cbfc4b8eedda63, + 0x13e9c09190f744dc7563c578dcf432de2522b7c7f995b2880957c5d2c54b27eb, + 0x291cdae728ab7b72e119248c0646d1a7c305afcf50c9dc1c1eaacdc9660d21a5, + 0x2df268da059255b2d959f934bc217781108e61710f0e3c460419d11f1366f45e, + 0x959f13f2c04b17e795093b408f590b85f707e54795f5df80bb57b35c994dbe, + 0x2d83db369e2b48848a27b55553a8bdb77e067a93f1f28db9de6c65b14818558e, + 0x2cac7303cf0462f21c4c154984fef173c428c47215feb2c0355c15de4dc64ae9, + 0x1f16c3b17497d87c65b61123d1954717fff18f21ccf4c86b4ae27444b535222, + 0x211a857b06dfe2df621d3a89a4bc05dd0247add6ce13502fe7fa37e63888f7db, + 0x1bebd0b81ea6cf89919ea765ea6d04d035d73cf7745eaa757cedfe625d10573b, + 0x2cb676f0cac23cd80bc40f3269d2610fbdeb7f20f5a74d72224525c6e3ff69e9, + 0x1e478ad6535f1ecc579056c6ac6ac8744f8e35209b7a081f47a5b0c33bf144d6, + 0x1669c72208abd4ae25158c9c73156e966504dfbb6a4bf9b6fe37a1e1053b049c, + 0x18a94771fbadbe268f58cc38e48ee81e3cb5a94b8b2cffa8cadaf75a171de693, + 0x203411c7e08bbc6a10164451062b19e131ea52d02dc1588d3591c8abdfe1fde6, + 0x6cff9d23d331be245ca3ea0e37355132a367f5ceedfd64c842dc9aef97651ef, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x167961cb9db6a7f1e253bf7c7d0711beed69fc736276820f1f7df8cfd1305bf5, + 0x251b413e3039cec0af54ae9d0dc7ac5ccf5feeb9ccc482a4a4e93df5dff6eaa1, + 0x22461b5ae9c4937eff6dd0c2ad5475f20abd4c5d13aa3894f20ce1ceef0511d4, + 0xd3c8cb0ca400d52f3eb96f6e403aee53c9e2283a19826f9b770d5270d3f2316, + 0x14fe9ead6519febc01088fab56bdd7826c35952169e8c60782ea746036fcef1, + 0x9e8b9302c470b946bb4e24b13b1692266be83cbb0f833527e1971abc11676e5, + 0xaa736ba6817640b3613ce5c87cac8f64ba74ec23f8f5c75f0cb1dd2ee552f00, + 0x195c4f3bfe08a064f19d6fbb6690f5f723ccf6851db01e64dce49b82640d624e, + 0x10bf96df637b9926a92efe91a6095501db10b10b9b8207e73eecc3147dfbe14a, + 0x6f9ea58e02e97445f704f68bc535b1d9d6ecbcd4d151bf2bf9f6bace985c14c, + 0xdb1da59cb0bc70afbd95e428861a2b708b9894749a2a88e62520a767c4e6d48, + 0x41dc2cccf102bb7168276813ff0dd2a3ae59f4f35de8aa1404160be701d566a, + 0x33b21d96a57d2c1d44c1482289bc607254a0395fbefa3bea25983d6e1d70893, + 0x27b5df4b4bde32d934353e58dc214d02a835318804ddb812a81effded6706985, + 0x16c436812dc3bb29c680d81bbda2fc964fc0cedea2cfbe4f9f0bca7451e2c26a, + 0x1075ab0069e8017ef2b84b9034c0e4e981de009440f57ffc72ac633624caab5b, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x1f158c6c1065f78b5f780520f03c584465ffce26ad183a50e11efb956a8ee412, + 0xbe6ce6cad51b6bc14791f01fbc62bf26f20be46ad5839ddc356afaf24dbb219, + 0x226643746553477c60b99089eaaeac4ae64b308a3c56ab343e55a6174922306b, + 0x2e82b3412adb8919fea66a8e2c0d8c5fb6376944728224b79ee3edbe56334e2d, + 0x25af6deaf2918fe03edb3989dc037a834610d69bcc3409e13e7fd657b6c404f2, + 0x10168c4b7ba5c85008a4f87c0325d238562951366b754259c06402e69422398f, + 0x20441555acd94f03732b606acbb25afa0e3cc39c7f0602214eefb497b4a340de, + 0x200658fc08ceb25b3e1ecece3989b682546d415f3eab6596fd7f63a9ebcaf3a5, + 0x8dbbd95a7fee39cb863987f4a9dd8c40ec8c1b94f21735819fa9d6fc524547a, + 0x1679802a70dd63806557cd2d8dbb8788a91dfc982c672d9c2df04efdb12c6980, + 0x18b5ee46c9ef30ba46b5c242bddd68c8a1f891122ec62eb0a1ce4e0efd408297, + 0x1760042648d3c88f3800bbac32caf5e5fd6b808f50af91cc5d834f3aa9bd2128, + 0x2bc24aa17ef22eb5273e6812a0e597bde1cb74b65fc35ae06f09358d966b243f, + 0x1871a1352a74bfb73dc35b7245903c1906a12dc3d9448667225b1d61a83e8cc5, + 0x15ffecc09ae5dab7e235644f38c84af5aa6ca42f2d23b64bdf7ec536f9e7d5f4, + 0x2c9c4d817a1351cc3f659d10453598cddcb7369f9f5978f44025b9d847935a55, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x258f6b7174e2619e3c94d65ab10273d210ddb46eca06a22f81117fe5f02bc38c, + 0x7b65580ab28befad1640084a12ab11bde32586ed38470937985e2ea07eebdde, + 0x2251fd1d0a5bd91d3f958b9377996bfb6f7e777f3b2a3bec54befd9a19b429a0, + 0x226bb0f7370463f705b99cade44a76fcd63a762a9685f7a254d9bf67d9711d19, + 0x125b1f6876e2cd4548eff5a6ea0598ebe43aa0748cfdc53c83987489c871d0c, + 0xd6400436f874ac40bc4e3e392043675a8f8bd071e38ac56d630f810a6c382b2, + 0x152557b0f424f9188e7c816e36f83ff9be71abffa7caea38fe42b0b7d2731395, + 0x2419922a2d394b1837d8687453eed9aac005a6128ae835110a204cd57663f4e5, + 0x28de832e55c53a37639618510388ac059fac106d2833311efd450dea8b112d6d, + 0x19e9bcba7b55e568c983d797460754fad7f04c39a4d078a0faa9868557f34ae1, + 0x283908c8bb48fee64ac955e7fcb47040fee47edd7810e5ea26e1d9bea337e1a7, + 0x25c8ea766fae5e6a1a1a20af4b178812c0e3e38eb4c5c2340b1fbf4468c9bcae, + 0x18cf37ce25ef86d2f7c9aeef0e79f0abb007fee6222e9952c9f734480bf974ab, + 0xd41106aab9ca69696aaea2184622f814fe087b12f716e2dae58069776e1cc02, + 0x25a1462f1d5a2353e1af93865e7ebaa573bcdd2271b268415b05fe113c8851d8, + 0x2d96abf52f1de16d6ed6d4d9279035f5bf5b825754dc21d11feb94e3b1700cb8, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x18e5610502d2a1bdca2d2cd38baabc9fd641ca4e9ab4be237ad32c72dc880c85, + 0x2bc2a1228621dc365cacd7d5607b93181b585843070c12a7abe98c2ddf0b8ce2, + 0x3e57b7e7ba3e4e3caccb663416bf20ba7df9fd5fa25d95ad29970a6098b5d47, + 0x95beee076b8de68c794636c1a75a0f1f79e694e9470af6557dd0a756ecec4b, + 0x2063d0dce7c0e4dcb6eda83c1d2e9d2f8fb7d2754b2a116c80a5fce17ecbdfb8, + 0x2793560a50cb73953010b7881649cf034817d3803411649c83fe7de6c7dddd22, + 0x927b8161885b12371bed6743e7f3cff4e26596f26ca6e10ef9b62824c6d9408, + 0x21e570ce0b93102f53c6621c813a62dfef04444d67147e86bdcf6d89982174c2, + 0x4da2abb8299af33e497e76256a8829bf2e90fdd6e170ae91514dd25fef2450, + 0xaed6f83384c5c1b36797223e5b98e0dc7e322b205d9946ad59be72a56401995, + 0x1043df1375a10cac3d79397e2572c2de5910c9b0cf9c8a36a8597362e2cad2d7, + 0x102b5227284acad6650de094677a51bce725c6da6fc1043a7668e939829a5593, + 0x71b883401c25bfdce86be56ab497a10814bb19804c57834b4eefb6990b0ca4a, + 0xee706d85983efe15078748f8f19a299283737b33a3c7a74f3c10d2e8d938fa, + 0x1e3ea0d9146581209b7018ac5660e20c5033641c101f09823d5f305220da9b2c, + 0x1135f9d772fcefd07385bb7c8b5fc0bfd38c1c41ab6de2da8c8b3bb3dc6ba093, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x5580932f510469f70096c820d9601ad87ef2f66990c8e6eb98d6a6dfde27a7, + 0xc072aa3c1344e5535661baaf0855759b2489b40320116ec0b304f81402a9a73, + 0x2c5e60d6d9cee50f3880234e54b391aab138c81550ffb9cf7ffc83e118fb1612, + 0xea984db0b29d0ceeef9eb065131137d696b4dcbe9b29e12d0bdb74736fa3cb9, + 0x1461bb4b296851abe76ef1ea0df56b555c76879960935307fce97eba31a58550, + 0x217814f2d889b58d9728a46eebe679760022e1d564c5024f6b77667d3a31838b, + 0x2e34b63991a98aeef1161f9c02adde896d1be685e9887af5ec9bfe845d2fbd25, + 0xbb51a53298cbb5297405c865b6ed23804c9926319ae9c5c7c1ce2478d90c59c, + 0xf0f1ad048e7b93df29617d62561ac209b488f58234f3461286e592f64a1dc90, + 0x24856651f6c6c72ccdb29fdf1fe0a24388247c5dbb8973c1c87f3a933fb1a341, + 0x13161ed9d7133008bfb93eedf4c667744c0df4cee0e0ad9038fd0968f726087, + 0x1ff88f2a80b4078a90df72d706725ed9e450488f975fd006196208e399d8dec1, + 0x2c300ce9260279a67bded94acaf125b7c98cc2208455fdcbff7fe98165c1d4f0, + 0x180152334a015c3e7d433b92f0ed2365345ba1b3dd06e556eb6a39b45b924ba5, + 0x1469185941b34b5a4f529c1b5a724dfac28aa98c8f830f8b1045ecc65b787f4d, + 0x7be7c3b4de9f53e54e3f4f871cf62f4c7720d3a2e7baccb74924faeb3bedf89, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0xdbd81cdf5b54b534485c26ecf29628e9e8070fec90c34b780acd5bbd4e7f0c3, + 0x1735ed9f6fd2ea72803084da6d7e20c4735bf3de68156bdabb3888dd500476b5, + 0x302871833d038dc61a984da78e5037234c7b2f114e495451bd388879b8ee1532, + 0x5bf32698276e20768a54f9bed48935b674ac85bb3d9251e1075207c1edc0060, + 0xae9a1e0aeffd431594e5745e8f4d3e5800361e8028ea0b4ba98419fb0fb578, + 0x2b98b2ea75766211d9a125db8e6e7fb4a913812216365b1f6d2663deb1f0c19d, + 0x15c0f1926bd600c94b15ee1c00e0ff93c7de8b4a935023bb59c664fe01f30bf8, + 0x18f86036c6136aa605da0ad3d4251e64ff31cd436d72b90ee5d3157af6d79e40, + 0x28542871e40749022211b244fce0bd160867865206c873f6668ec51a429f9a39, + 0x2432259e7f4740024bfb2b71fc694fa8460971ff8869fa46f539faf994d23d42, + 0x2cdbbb1f729d6ba0040b0fe63e0ab2e24a1ed05f4c2947f2a4dc78d49bf68617, + 0x1f7d6c170f7a83d6241fbec95436b20478184b02ff7f4cef3deccc92da64b3a8, + 0x18e6f168622d4679b6579a5bbe6419d8c868d67294944f8246a81415b30e6119, + 0x9a3e52a4ddb98644cf4a701766c1ca5ae4a35ef1c11a017dd6aa11945fa53d4, + 0x136a031823304ab94c93e3bf39b189e240a81e0a42b6060e38c7c2064b8148fb, + 0xd82d0c90c41c41fb24d7160c8f1708c258222ef0539a2776a20c742dae0a624, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x2b0f98b255bc9fbaffc4b09dfe423873babfeb16c64a31d8f7ba70db133e8425, + 0x137ffcc374ae9e222e733fdf9d0c515946baf3c1aeacab2c6218180eec5d6a48, + 0xe6a056e92c767cd1fc970b338fa5c7377240432e6bd45aadd958d48f15d6033, + 0x264c9a5c6eda708da60f401ff1171c9ea279af17f1df202bb27cc56773a37853, + 0x1862618d4abfaf9e176dff2dfa86f1b94e291ee3e02dfea816637787edf4f37f, + 0x4d0d2b042b8d971610b3b9433f373d693a306f1082186a35a8ed6a758e0c11c, + 0x8854bcafc5f356516b2df46f5386a116f14de1b197290316d49869ee6dd0187, + 0x4b8696c509d9557bd8cc6227caa099f002c5101ff6d5b7a4e48284e31992562, + 0x125c58848e89261172f9ad256ef6cb755841d2913f2ee2ae9d68fd2eefa84d9b, + 0x181ffc981c54778532d7ddd39ede7dd3e54d655cfe6681b049df6d85f76439fe, + 0x198f1451b611973be77cc3ae7c744af71b1c94e3e87056b7af1e949e92cee5a, + 0x4c9f885fd1b69729a871eb611c4a9ef1e009b0605a0cc3befbb806701b63853, + 0xaafeadc15dddce6b214e3991babc93af04e3c6db03ae0e1408a503e1eec3433, + 0x225622d35902840ed662b3dc9480d941545df10f2f1a8199260a65018d7af93, + 0x209d4d14e8b9192e061a42f149c09d0c9831a1f02c35412f4563cfc03304ff9c, + 0x1192a624780a6633d00dcfc49ab6cacdbe3d4a62f6c7d8abff6094a678714f2a, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x23278ece68d054afc53c1489204000d720cba66a63842ba7269e35e0bbc6d14, + 0x9177ed9f3f33508db8be8f15b53360afeccc2f208bc7143bd226b4c885786ae, + 0x175a7d6713e16fdb34e680606af50037ac78419ba5cf0dece2aba5d849184975, + 0x1bd2f6eff3f24489dd492eaababe1b0c09b50e983658c1dafb2bcdb69a724195, + 0x16b53ba34c5215013c262d62007837ae1cbfae155bc7cb3da840bf945becccce, + 0x2c062183d49d2fd7140548607e86ab487b7a6f4da0109dc8b37955c866ba91c9, + 0x22451ab479c09eecc408145baafa7f51fa598b3ff2d057365903ea317ab9064, + 0x82f7e3f789ae657cef0f342c994968f47fed29262d4242964e0e793edd2af9, + 0x11139d29901eaeae25fe8a6b8b27062045be218be37844305ca3b7e348b0438c, + 0xcbb2e8c216cfa7779e8085a1a8b24ea1ca6446a664b48d576accae16c0e12b6, + 0x48f7ffdaec0a2144b28a00ffeb5b61300386fbeee792be38552bfc8363561b7, + 0xe0bba24d78116594570dd93a932c82b5b6730cda14170f58b73105e29fd59cd, + 0xa4dc036fd4d9bc2561d3d0c35a0222670c59e5a0626e36811b56646b345a0bc, + 0x1a1f2f87b5b4221b764e44a68abc8f56f6a97936fcfec06a3022ce00a3017373, + 0x1dd702226b6b31fede8c6b8067fd51da81ad5b970b023875c1ae5bd2d56cc29c, + 0x22c40118e01863b586d4bc9b2640c4f6c903410c17f5bffc7032420d494d5058, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x18b43cb399d143c97d4f8de9fe9c4aaffb6dd3785d9ce5dc9651b975b9054167, + 0x12c599db262111be3d9842cd39f3a6f34e51abe1c1bc0711e12f69c3cc973e7e, + 0x8bb47ee7a3961cbb9c94a68b2ccd3cf4ac95e8836f7538addff55f926bf496e, + 0x2f5694920b9644b4396caec1b4c4150eb46a18cca0ebd71c4be28cedb456b39f, + 0x307bc951cc2c9d4eff936eb6098bc1fb25254728e3906bf089bced7826fb137, + 0x17bcfa98efb68a8236a23a716d27b3cc4539c8e79ca9026a9b5423a6442e2eda, + 0x14787ef740948dfc067ea4f81bc1346453f77806e6bc39e3defdaf82eb952e96, + 0x257a201998e59bfb34cf5494e14c65dc3f2fad4fcc76aa9dbaefd0005446972d, + 0x12a8d99dd91ae7dc9bd892be2c72d980ab6459d3a6fb8efb96a54dd414906257, + 0x200bf208f11f7a4a4de085188220177b52da270fcaadd23e79e9e879dce364c1, + 0x1a9f530729b8ca369b1d5e6937ae365f01dde06c24722bf111ce4ca5c764cb06, + 0x651d7f9fbca106c4e8b3b5a1ce48b2db6bc1657f7aed28d952e28711132c0ea, + 0x2a3316648cb65a090f0faea9d38323345b7d4a91a9587a9e8d1cae632896dcc9, + 0x1553ad82056a8d74b3bb80bcced6a7779eeba7eae923ca8b492b9bdae81110ed, + 0x130aa152e81341ae6952e6732a315d1567f3ab12cdff38449e42c18ee55e388a, + 0x2162c9c868800aabd5be303b798357d4530f56e0d8c94c99e095740337911cc9, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x138ee349a5126b8c59ffcc05c3e58041d520f8cb80be3db2d0b72af7a24d090, + 0x2e59364c831ea593aad5fe14da76a1d7705b7af94f331ab85362c4b5943b8b68, + 0x24b0f5945c543f6ca8126782d2337ef8dc930a1b77c0e133c6fa94fa2a19a462, + 0x2d8f29c644853834a8f1a61a8965a9890fd8460a82ed2520a9fb332e6a22b983, + 0x1e408424ad586d58ca0a0481dc08b8ee63f96c838175dc8a652ada892c293dc0, + 0x1cae05e2d2ed01ae5077fea699a2119531fc30938a5ae2c55ce656b6eef33b8a, + 0x1f0c1735c782a57b3049ebfdb7de3238a608fb6fa9f89bdfe199c3df1c1db15f, + 0x1c9b672560571e96a5590c64c2c5b799e1e317634d8de5b731bd7a51a68d5d4f, + 0xc6e7bd2073ed42eaf2db5a728b6d4f1245a87e614b322c25fc51eb0ffaa6eaa, + 0x1fae1dfd513367218a20406dde57d573c62196c4e12f5347ef486102e809cef3, + 0xe408e6db3d016f993a53e864198deee0f2aeb8309bd66f33fcfa38f401c780d, + 0x2684ad738e6116f3db8dcccb6c61cbb27fcba040b598ded972d6422299e0c09f, + 0x2ccc5b6bf5cfb7ba1e8a89e76404ba0067c3d817bf3ebfbbe4635a789c7bf067, + 0x2e3dcba12acbf09be187f2b4d453be5dd4f3cce2994f18cd1226c63de056e868, + 0x23e70e3f73723a94ddfcbba70771ce2f5a4e15b4a8f51b2828c05cb07ad2a19, + 0x169c46ee7bf4e148cbe64b6cb8aa1abee9fb5fbb04997f18ed315345a8594c5e, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x7cdcc3b6498adde2756987e13560d7664f1e805180ae0fbbee1dcf1fa417d7b, + 0x2d9b8536ae52537df2579df0ff0a06d4a99757ad71652f91d3d724b4eb970acb, + 0xa1f0085c5a9cd49df855b92dd309c3681293e5af0417301e9e5e68d1b34128c, + 0xd1376badc16946a4a5f324390a4c6fb00baf670827048805a36b06357c39c1f, + 0x106d0427df7fc4dd7aa26de279073df7fa15370084bc27e16f5f12a8b01551f2, + 0x1cadca4ffc5bd9eb861f7ef6e7ba8aa20d7709c633c90111b98e094af29df8c, + 0xff923b3ab95cf5a3957cd89d03319b4bba3287807830e11073542019971eab2, + 0x1202a33c0359b51491e38826ccf21bb0c545e660b3da916ab91b0e02e30484aa, + 0x11608aa64cc3dc635c119d0691f46b0a479e142e0532f9256d3414369f5e3010, + 0x127d38a920bd78f2b5feba943466e85100ead21ffb0bd048683c7e7ba457443f, + 0x21f792c3d068276d10650a4ef8c8e6101d763990945f044ebfc6f51126332d07, + 0x1bdbd707d55dc4709b586695c5708e9973eba79a19d6504181cf8692f7f636be, + 0x123ed252de9f1a986305fb990661544d1f0bb2d12e3e5abf36130d680d61450c, + 0xead6abad94e79729b5e708c60dca274356c3e5142349c43382984d4df096650, + 0x21eb504af959f21f9c7a6b50a58bf5278209a2631dd62bfdf6175af8f22b3c0a, + 0x27a7eed4d44ade3583fbe7ddd6fe43796ab32266aa3f4ee382c20b99debc6e1d, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x1462238c5857d995aa2c7ccdbe788cb06271537ea1a299f28c307a825e8cdfd2, + 0x20c2ff1b99b7a949739ea108f5f462a0aeea077303cbd515bc7591ae02a0d43c, + 0x2aaa992acebf67c5ac50fce7824cbf41e6e5a9f87cf42926fb964505ba60c198, + 0x2797fd373735895c3192ae84ed39007478a4b3435d8a497549edda3d559833c0, + 0x135eb9d0101c2a78ca1b03ca53bc556a8c9af537d77bacafbff7f9bc66be9b98, + 0x2f594669789d1b805b611c27ca33a5a102ca3854938369a172c78de5a4083851, + 0xb8f930192502857b534625bb6ad2ff73e94ef4db9565a7de5c513f46fbc3e83, + 0xa520b7ed463311aa8ab8e7b8fedb2fe271214127264cb3a0f7a32d0fb871735, + 0x17198721be91de95ad64e64495b07d2dfae45ea67b2c824debefece304d25858, + 0x12b591844eeeeb06eed46691ba7e1bd4d6615d2aee6f1c040e6334596ee06d0d, + 0x2e1d81aaa4a22d294a4f57ca1199bdd171c6bdc0ceb9e9e4f7371b50bf3fc969, + 0xd18e43e3b9d5671e7f8080d1b451523e655cbf183ccccbd58793628aa689057, + 0xaca56cd420446d0f57751deb06906cca2c88c5bac6d35a2f721702b1bb56c53, + 0x18370450204ee070cab3e252535bd279023c9ade36b971986e9f4a821bb0ca0, + 0x10717c1af2308a9d4ae527c637257974d71bf361d742cccfd9cbeefb04120e56, + 0x229af48ad01840fada729de64d9ac6c4e2ced8d16820f464b60969310998be7a, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x1f6027d1806f3db36b0e2918305ea28007622b62282d0aa7d2d1c38bc3a14580, + 0xd023c3469f5337eb7ad3f6a1a9a3cc877415f1aebb7e9e5a955ce93ffb786da, + 0x2b7436beb1e205a4e723df370f2c669857eff6da7fc85771e7dc8256f511c547, + 0x2cf4f5bd0389a8d20b9cf97d0b2e75a429f36d01e1a1e6a9eaebc6002e6d7f27, + 0x2c689316dee7e23d23cb31070bf6225d9cc562fb57e3fbdcec3def3143d073db, + 0x1dbe68dff3088f0cb02990e0c030039e116d0196eed2410a30e91c08cbde3dcd, + 0x16a3fcc3080e28463fa4da66d305d58b74885dc099dd32b159209361fda491f6, + 0x2f84ea8936e6f0e98529bcd5d666e87d8c7e68aaa1787fa673b8920669b10a6f, + 0xf67f541e326dfc3555b54a5a8089013085f3cef05dcdae0666cbe4d1476c1ce, + 0x22c68a5cd419b439a367b742715697ce0d2e09a481dae8751d7c7726837211aa, + 0x2063328c09ac22652283d91a52d9851b919051815bb5ad070ee015040835b157, + 0xe78527a4658f58dac40430d4ddc9043ed3cc910a8a0e30b03ea904a781ba8b6, + 0x1935fe3bceae0bc5b8a13b073b2678048252e77d85f393f84a1bbf1911b41bfd, + 0xdc76ca0df681fe5c3b9ccebaf864ae495c8f92b48bb3d9d40274154da97286, + 0x119aa817917a73d46dec3e58fea0eb8ebf74041c1b069b1a83ad4856b1809ef7, + 0x2aa46d04f1238c646746e8df5bd0cf9dbecafd57d5de4f743fdb593379ff138, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x100148238e0ea61c5b6b81fba32193d55597904d4b1220500edcac81ad52f68c, + 0x8243c72e44e0114151fd9b102eaaa569fad5df40df83a1b52accee13fe49fab, + 0x156b1e5836f0f59be75c7f198a5d153ca30f0b79882036489937fa8c3b6d8323, + 0x2c0e264b43ed6c4b0c36fef6aaf1aaed9091f35a830550ac4364d602bc9e9e4a, + 0x534b4de30df58163e970ffa0ecef0738a9fec8c0ec4e7d9d15a666a16f45c07, + 0x4dfc3e86105970cac41059c73d5f2ce55b16f40cf638a85521ff270c6e11e29, + 0x183720d9443c6a59364afe5312050095e335b211598478c7b005249e89ced914, + 0x1dd461fcefb3549ba9a151df4013b323b1183ebdf913126b53003e86c08d99ef, + 0x2656efdbacd1d58ceac9a0e79d35044753ff9b7f6dedbbc6d8a48fa48028fb5d, + 0x2ef319b13362ac4e82896c082a6fd4a64b9cb25efe1e0f5068deb6fddf95d02d, + 0x13e976b891949cb18b46fe1130d4fa1b16342e954779fdaf98258da7192b9c91, + 0x8c80492d0cc609e181c3f9d8e2da90f68390facc7e468d29d49ad9257f55c28, + 0x1aa3c7c7a08d082afa7fb91c6f1c9f989b98f9619b56dc62c7ff1e18c6b72c86, + 0x1d115ed240331ec2adbd0a398df0d4dbbbf2f6392bdb03085e088d60d7f02ba9, + 0x1444e0fd467ba09ef9c1c6ce9a80b4e7be755d0e9f81a90f74f0ab7d110015da, + 0x3ce99d4bd9007aff4e13c2679d14a31d6467b32827e68f234314d3013266217, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x1129b914cee489016fc3ff8d20e2be4c9abc873041ba82bb7e7781e976961b24, + 0x21dbd50af59bdf352310dc018015a605fe2dfe0e8e65ce1feb72f2972b985640, + 0x25a5291beb01d9f13ed31c588755e56e5e6158b2f46341c86eddd86aecd52d7f, + 0x8de172c56eebbffb029ee873bff13163cb2d06caa46108bae1dbb2c40d22216, + 0x1dd2d55f238308639169dba6066e0922ad620678106ac7a1091b7f7ae0d3090, + 0x189191a64c9e4d960a7f281e378669034e779be7ac0cdc6e4fee4da0659b04ff, + 0x141fd736c823aff77ac2f28632342c25d14a649b026ef03f36961bf4eb85d4bb, + 0x113a24d1bc9d10e47f90f308781ddcc9b9249d95bbacd113d88d5a6ea33721b2, + 0x8f0b7b38b133684b73d01fc731f895bcb30ea14364715ea92920501722d81a2, + 0x1bf14ce82aaffec31f46bdce8d22f3baff0f96b8bfa00499581fad99e61f6076, + 0x14b7be33a41e00d0333a0917a729539fdb90ba42f12451c63de66fd411f6e379, + 0x2107e9e2811d6ac968dfadd3ae015e3f71f87d0c5d5c5ce4f9f7c66bc92a3931, + 0x9e1397c5f39d763040b82fc2be1a64262cd5a4d9f32491ada436ce437bcfbea, + 0x1d1a01986546a0812d3a4dae34ab33abe9cedf2060a4f654c7cb05d1298a03cf, + 0xda3f22ff498a9cfef80f63e2c92dbd95928e85463777018a0d3204d1e50f38, + 0x25b74b90af9818fe0fd8fbf33e539dc037a45ad9f433bac8dd3717b64600b622, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0xf3d58dc69226c994ada311ddd4f11174b51c490cf3fdd93047540be437cfc8c, + 0x1d948e7f1fa4705b5ae3e5f030a59ef966fa374f1d6bb87fb74d57b76f2b61fc, + 0x224176ed89ccb581b45f6afac435d9b2fdf08a0f2622a5a20c2ba4ca8738fbcf, + 0xf5cfe8147eeb9451b966cc087d2a9927396a83cd407d7f22afbea6ed6313ad5, + 0x1b73e95446d5beaad0bb2c324a27dd0fdc5445ea8a553289a88cd540a7a8a633, + 0x1b0f4b75472ab2e5ad4482742bcedf3b45d90177dd52680bc781786ea3e96be3, + 0x2e189fd270377427f98adf8a3f49917ebddffe7716ad08db78761da20e671fa, + 0x7c0a2036465c336f0fc397665c86a87ca0173ee19696b8fe7e6075283e5f0fe, + 0x2fb5497d60412c8bbc14b961d96bcd9d2cf82a25da250d7860453dc0c36d3760, + 0x25aa324c8bdacb11e81d612e258814beb13dd01a7de07d57b721a6c83101233a, + 0x29266b9fc1cca7e41d3c58443362cce77c81557f56e3b2a9a0e3165f38fb28dd, + 0x1557e3cbcfa7fa080014f6ceadf2ddc22cc1c6debade1eb605d0cc2755268dd8, + 0x28ad3d8ba97896df26b3281b73de59d9d3a055cf84e24bf4b7cfca4a6f18e1c, + 0x27692be22a3100758923b4b09be3c0e1ca34c62eb2875d4ca2e95199ef57e13f, + 0x26cb523869e976355b8b2ead6493c3b1af3b24b9f619648976a925dbfb9c2520, + 0x2a943b5d83171ed1ba5b2d0151f770d05cf117e28c8a2d0bd07901124b7a78ec, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x24917421c163008e468b59990ce9c9659723c7a143eeddf00b22bea911a23faf, + 0x20347f9b860c7318d8abb5924973a6032790ed146dd51c2b175890e67c7c14eb, + 0xc7b4b3d63f3985e07d15f46bff54c7f1382c7fcead2fc4d2732369ecf62312a, + 0x16c3c15bfb090d3c32b6783b8f35b56bf1ed17cafab462123eb872e18f40bc84, + 0xf4bf0d79b3a4f157a77cb759e8c3a950c2bf08d3b37e6e2252feda118dfeb6c, + 0x207bc2820e9268ac4529e9415d7094f6c4a3dd32c21fb6f34a6721806e60a66e, + 0x46d6e4942fc73df5a5c24e50a1390fcd3971f81416ec30338d988421d471e62, + 0x25d86cb7ab23b7d7829d52fb3d3c2dc42ecb745bc74e6e29c00faf2eceda60e6, + 0x291e27d656977488568245f7d60e5d31f7993b3530b6e7a5d2ecc5ed8bfcab9e, + 0xdde8d80231232c0283b7ad84aa356bbf7a3e7605dba21f29b53fd949cd378cd, + 0x16b9bca3f4757ee5bd884c08642d294730db13f90182970a962c956d5ded06bc, + 0x148e1434a77d59aafd26c76dfcd0d9dd58709b43c99173ceae6ddc899e39d810, + 0x23e38e3fa1713fb566e00717c0a22fe7e056067f7f455cf67c239fed5313c484, + 0xecb380bf60702c006a2e0b413bb060a7dafdcf4d8c736483da381315d128380, + 0x1504e0be27d971001c9c52f6ddabd8839fbf3cda3a42dc01c201788063ece2ad, + 0x204cd425d4fe74aa1fc3966950209bd6e9966aa7df1f515e5ff4eb504623704c, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x26b0354a46c4b6f840abef50577ae0160c403ac2ae154cc44dd1b3ef95cc9a32, + 0x76acba1cd92e4c02cec66b997f2136e03c86a5099967b8d2d6c3fa51ce470a6, + 0x1b9f835efd362eced66b1b4feb359a5a292e5179eca20536bc05fcf71ce8b0cf, + 0x1554b5740239a036650e957cf54880a05ffda13bd4a40b9946d1454b6e5ee619, + 0x2337f0f2350dcf2d2c4cb2f2e3c8cbfe8eac44b18a4e7df6ab9659c6d3bd51f8, + 0x2f70347a3e263a829f4c9524c0528c57aad8197d74f498c96618b82d6e38c750, + 0x2ae047c01e6b790967c9af15fe9700bf12a32cb4742c75ec4f2264355251b598, + 0x12bdad753525224488f0df2411e45b18e6d99df86b64ee5c2e1eaaa26b6b1165, + 0x7ed14a9dec030c79ab897464c9c31e89ac5d398e5fc2330ebd747dc62704e80, + 0x2586c2f08326503a7ccc396ada19284c6381f5402a1ddee59134036c6f9f4c85, + 0xe28de3e58815af816aa0e449cb6b0b68151fc3b74c8844b0433fb556e13bf35, + 0x15ed9ae17b48708404c20e204de218462f5c1de7a672c0400b1a4a97d82be2fc, + 0x2897a3c61ab7e1096d59db7d062d3509dbbe5288e8503eb723a783668f39363e, + 0x19382e0101202bcff4c8186a39e4ced12ada7adcbc0d3d535a37fd8e4e65d6a8, + 0x1dccf64cf1043efc8ff525df9a110883db70b13bb644c6567c0ed56006979547, + 0x14f753284093a5bc753e6e4516dc5f1856c363cde9ecc95745dde82f8f475dfe, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x47ce0768d3b94501b69470f61a3279af86cceda48efc0aeb4f755ce355a8c06, + 0xa838da94e6aa2b7e3c8d24fbbd1abf9fe09cda8242afff691d57aff64a307c7, + 0x2ccf7207714857e1b96f90a10f6662a0a161fef6f8554acffb454b475cad2249, + 0x2c964702e998844a760e735d74ec7fc17e793f656653128910e08a1c48b27399, + 0x26c73fcc286358f8a8c45940e32da21acecd2723a3e6c00003b875972e7e4215, + 0x2503bb71691693c6cd6c045d3f40b4cd2885a71adf5348642d80b44b4274164b, + 0x21abb0f3aa09de0569e24a9adf7863bd965ce656e4ee30611d0f063c1b6b1d49, + 0x1e6c18a3ca281852b9738876128c7d16d2fd27789043907cd624471d1356d10c, + 0xbb323797079be60788e8c257caa1e1e9b52b8f58128eb49dfd8d7595fa8275c, + 0x16ed4d5164745fdda2328ab28d0ef0350a3bb50589d72655d0e0d5a8f1dbab81, + 0x1719e6626ea03d94441eddcffb00dc8e76767224986c45f5f8bf746f72e33805, + 0x20dd2444d1b30a7e45a076776b4366f04e9c5d1b32a43b260d706f646a098db7, + 0x2276006ca87d973c1f5841a3b63aa9e6a4f8446a8a0ee03e068fda23a8a2e0b1, + 0x2d3e7d6feeaad7f3c8700e6293a0d896028d4149d57c219935463621fa77998e, + 0x26f15d4ba4736c73750ddbff4a7d9865f06d5676e449e9d249d3dc9ea62053c1, + 0x3636803242973ab91fef85aa46df13cba4ac9f6537aa3730c0da88b9d05c751, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x2ef01bca238ea43551e5857e412427af1daae81b8d9aa0c33bf392bb9e71f123, + 0x3030333648057d1d46a7a3973031a86637d6cdec3559bc12fa3bec6c0aab01cc, + 0x24dce91bc3df505f0593715987d3e6bab8f1847e5eea91341a9d1e83bfc39abe, + 0x27a2aa95ce7bd870fda385fc945d76269a9cb6d64b85f943430c796311d03868, + 0xf32e1ed6656688b400c42da52ffa8fac2d25ee877612e565f9271c1cdb216e, + 0xd69d7d99a58af860357adcbab763a96d048806bb1b3352c3ddcc0795e6bfc0f, + 0xfca01158c0aecddc404d7561a6d4ee7c6e7baf54eef93f1b4c72bd9468d8140, + 0x24f65dd1622f5993f172c7a803a71af6d9936a45fcf2f11c65a2291693c409c0, + 0x23b6c1c4a9697834526084cc56e8b53ab3ccb20e06ed7bd94e752cae13e04650, + 0x6b0b0674f9e70ca31b8658df5a918b6aa90ee4da8272d7ad50109ab73af2372, + 0x119ea3133debe120feb5b0ff2128b745ade6329c228d8c93ef9ecac933de75bb, + 0x28fe0921f3e250bd0d74df9669ece211330111bcda65ff19fe8bd02779da7686, + 0x121bc322c37b3a84cfa33407bca08421c76577f4ed5009151ee61de9538906f0, + 0xc6c6d133c64df4a3f148d03064ab681f6754192023f96e5c660181bf6708e7a, + 0x1f357b000c8ec106142c05d7fcb45bee3ca8602aceed83c3254d1596854d8e9c, + 0x2c635fbb8a475d22cc9388f33298ca3286d55e529d8167d036cc97e28b5c1109, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x1416e46669e99f6376ed9f1b60b4c1cbe2c13f36ac1a0961b28c0a4ded622be, + 0x83b993a01c06914fae37498067d1cc7575d4d6692e905a76c01012829848e35, + 0x7d66eff962ec6ddaeb23a84cb8fc53fb2435fb0779fdc6de042af8cbf653e, + 0x243493ca2e9aefca93b6f729cd48e89c5b6977dc8b9f128e80f2181a0c9321f9, + 0x25315cd8d5b5f0935df3ad290e18c8fbb1aa8a200af1b3b7acb784f2b1eb65f4, + 0x219e9f27376ebda36a9da6a406a6c2346e6db6c35e36390500ffbdd24c754013, + 0x2784f770d363c088139614dcafe4e82fec4aff60cbb9420b2defa1e5ceaf52ff, + 0x2ef0972f7624a2c71c7339890b350f716c7fc3cb884c48df73788cb38e8efe3d, + 0x2638005f1bfa951f04d3e6967a19ba68e797261d015fb0b4a200084da0520420, + 0x19952bfc2b15a1b7a44e59a4f007076a56aa61c9cb4fec45f42301ef9157a095, + 0x21bfebd7f0dbfa952f62f95d4475c079f623f56f67ec13f29e51fea4b142befd, + 0xabe0cbbdad752e9c30c665546f1b68cdd2d556f659c98c9d0c4048cbf0ba4d4, + 0x20c4f2c291c5f0b15e54fad44d549bdfa06e8405141d07446ecea299bded58d4, + 0xc703a5af22bea77a163ee98e379877fc276a2e60a134bfa6b3e0f3674aad830, + 0x23898a43fb970529f4c12bd16e98f891aed64fcb59738bd5c2ef1d7f5b9bd4a7, + 0x27de205e3b4f798811873af0dc39f91c449bae168ea2b2ca268f0fff421969d, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x34e0217aaa3133ffb88fd09bad59e44d8f0e74e1a64c86f3e9aa4587000464d, + 0xf0d2954a3425d4ef6291aeeca8d1e1927250f8e566688bf01f77206b6a0e0da, + 0x38ae6c953b05fde8ec1997151d62106c38561a6563b7c5c42c3ca3f254ebba8, + 0x129dae3e6abc9b3eef8419054977e8ebb35956b5da4731f87a1558b93d5b676a, + 0x43331ce5bf13e212c36bb6028ea5edc909d6807630483960ffd1e472333de8a, + 0x6edd2bca6596515c7bfa7f82c123947366efc923072442cd0d6cb3cb95b6590, + 0x218d39e5cb24a98ff778833ec9cc9c97154a2f0dcf576e36841e61f2a9d53c10, + 0x7babdb5f969df1056dcd1a4d25ecdaab931bdcd410f51443221f43ee9ad60d7, + 0x51f51c6edca7ad20f95cbd07ce9c5c51918dd6639ecb58e2db44f9da92ac45b, + 0x18d0cb9110ed2c13ca697c51731265461aa40cbff3eec69770c471bfab8547b5, + 0x151c0d100750fd3fc64ac7ca148c41bf2634c161746e664b6403e1d5ff99edb6, + 0x1badce073db9156bc6bc0b05a5f9ad32826ff80c20dbb90991c59b84f1887631, + 0x1d09611b11f20c357da69b64b7f235ea79741583cf177a43141caee3928bc88a, + 0x15903ccf8bd20aaf86dc7a0c1919a20b2beefa10ee9373ba62a75da5db50cd54, + 0xa3ed89f4229594227e8d35c0f775d81daef83cf50f6daf6c92584dbc86bbd7f, + 0x15c5a6fdd9b6ba06ec2cdeb9f465fb29a83a9345daed49e0c27064b2a745f832, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x29c47b21c3c1399dcde464739cd972c2ae7dd8511ef4dc4ab062de40904cd041, + 0x5d20c3e118f7e163803874435eb8c4f939fad669606a0f8823155b46636b40d, + 0x2a8adf7b64ebaf6bbae4363b8de139b047e49cc258d86927cdb17f64d7a76365, + 0xcfab49644bb24735309134d8f1160397b61c23766c13afa2f67350700ea184c, + 0x978c1e24a56e9f48e04a00ebacf84a971bf524a94ff82c9fa6cf2a4145ea323, + 0x1e7feb08ad0759f1632751fda2c80347296a181f33553bfd11c84e3b99e4dca1, + 0x1636f1c4c6be9b16647fd56e418b432d81dee2c09c00d14df526a491d03df083, + 0x1d0941c7678aa3814c49962f80f06a3b6ff48c4563cb563925c87b621392968f, + 0x1ba792f0e7770d294979a396e2c55b21baee98d0be48705b32f831f2d09f470d, + 0x1adfb90be5993e8a8e82466fd94d2142e05c507c38a0095535894369079e2858, + 0x1701417adcc7a63515f58d3fe4840f96d7b87646be925abf5831c7d9f6839e9a, + 0x16669c07129defa028d468884eec4825c1852e6ae60f5acc4a7a7754f9383ee, + 0xc030db661bf66032b9e0abfe88cc482f134b5f39b13e8aa20b540d23a5cb4d6, + 0x6c29b50030b9f9653c8cfe80928a76e6ba1fe5385109b7e606ef07634d53130, + 0x158eff715b637ea2e1c4312cfcfc154d3dcae6d2e240826e791dc661d4122a0e, + 0xb7414bf9dacff0d87b4613d9bb448ef0583f07948cb26d86963b0442a478865, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x2fc5816a8a9d54f1397ed6dcc705505ca28a50d608f2d6b0351d133ea65cf8aa, + 0x24d04d2b53f9f94b51e0300c6bf97e655ab6bb25f790365c64949876fc8e400a, + 0x12c2d385c706f78b68d132d1677f1c43fe555d3d9bd6622de8dce6a01aed702a, + 0x2cfc07b04b7ac6bd6ff67cc6d32ace4717cbc56974a70b9e3dda54b1741ce3e, + 0xdbec9e92d14512f3a95f1bd6eb87e7684fd099d747641e16956e281834fcbde, + 0x11110cac8dad45362476f50536e03d139076972f5e03db946753ed0034ed3050, + 0x17be085a196605f2b021add82a2fefe6c062bf2042537e054642c521dda6e462, + 0x2d30434c0cef5fb5dd60f6b52c01556819bedd08f87f0c191941f95b833853d0, + 0x297804121986231c72d5f3db2bb23cfc41d9091b7f085eebf0905f59854ad640, + 0x263cfbe2843370e8f2352bb41b51d59a8f9dd4a39552922021dae9bd777d64f3, + 0x1ada1b57547ba0b44cec18e94b273c02af369be58ba4ca5dddfc0c54c6d952cd, + 0x1a022e3c7f181a5af4ca6b68ea1e8636ad7a51eb2e49779fea2abda08058ce2a, + 0x1a51a742b5e2a8cb02194fe5442fe8160f887d71a8c624097cc751e6fc9e106c, + 0x33a3c4fb2a336862528fe456e4b28417f0cd5b8d702fa598648593cb27ff95b, + 0x275297e881159b1ff115beb9741fefff245fcebf2267fb7788bcfdb710ee11ec, + 0xc4330cf0545fe0d4d56dcebff69cc7564232b0ba94e58e879f9a838fa43b50d, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x7b613d8cbe7c7e104e3144d883270530e6b3190606a2df92791fee2f3f0db30, + 0x328bb8607f89952c7a0e199a914abfe679afd366f57160513708a57b0bc0665, + 0x2797d2a42bf2c3f860818f92783ee5b77ea5c8ef3ac3433a4ba8f8934fe40e7f, + 0x233e6f522a14ca24067c5c09affc7b53af6c87776525bb21d9058d01fc106af, + 0x390562c095c160aa786394027404bbd6a3882cc1118cc8ed82307c6e8d80084, + 0x17106e1ac0cfcf36e9d75f64a39807c812cc85b77e3c5ada491629f71d978f6e, + 0x1aa28e48122d0a44733a370e5031375a8c9c648cc46dcf3344621e6cd4ca5c76, + 0x18f6e768b9bcf25d37f90fae8b9a4c5cac181b9b05c6bceb922d50d8444bb79e, + 0xfa9340f079ddc476b10060bfb852af827ff712c5c9fea03f62d13d0c670d988, + 0x1db99f295b05ab42a946c2c3a5c73b225ba99ee53dc906eaf360675867efafeb, + 0x97578aeb43a7d6b1b10240c0a6b9b771d65b7c5a3a5555226e3ce45de3d3477, + 0x1974c34d88938d66ade5546a726dcba9bd76c31f1b4ee763af03f8d5698f4a87, + 0xe25a828aaee6f1168bbd9ca2c177973a8f20f4d8bf3aec06a0c24512df222ce, + 0x2e13ee7394e626ffebeaa09712936f8402400971986556871516f2a0eca9057e, + 0x20be54787d3e6d7e91de4a052172de99a251cb83be6fad47ec5a56b053717254, + 0x2019386dbf15958ed2efabc0f81184a6710e0f8239e8932e25827ccaabb750, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x1195db45235e0b286717bbb0e7fb7f4bd5f1346a8d6d47dde45513baa490207c, + 0x257be62b59d6f54c021c27f0c3c0a7ca3222dc5ecfb298bed986f1b6cb74f79, + 0x2fc61e8c69f1b6a89a698d4bd390f1ad961ef1c979c315fc069d1d3364630829, + 0x4ed6dd96dd4ba79b9474bfe10517c93ceb5a6dc5b95497a71a38c42c4171dbb, + 0x10c8d7d4846014d1d37d7aa27311dce9257ea1de1700a7175a03b358f12c0dd1, + 0x7f833418697f43d68c6792ed1b6a4274500d96c2894313f43d9185129ed01b8, + 0xaa1fb14156f9db59737b23efdaccc40d8f609b346809f66d96402e5f9a2c102, + 0x1a3b635b05a022877abf26c5378da756752882d30152a75e75095a4992926de2, + 0x5ff6852ef2c7807df8c68cc1fb842fe07ef08892e6706f4ccb3059f1d80714c, + 0x18e93ae4b4c092b271ce21881f133bb369d09e3726967ceb0484698a6cb02374, + 0x5f1d71fc99fd6e8dd1a4ff1c6fb4d16aad3445b2c5b2698a8ca995b3ec32fdd, + 0x260b2c665cf863248a5c9a03fc5ec713c1d32dd3bb17f3a6dba7af1690317514, + 0x199dc26831d1b81e333ea797e6aa2e76ea2e6cfdd888393682076ce77fbd4cf3, + 0x1fc7841c3762549185cf197f765c50f4da97358c40cb69cf74940eeb165417e8, + 0x3dd8db3c33075dc724dab7416f943e45adc39e147443ffcbf3fbed8068089fd, + 0x1415d87f2ece25dd6da8a9b56a5bdcef4f235a1b676ac4fe0ece8bea54f0d620, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x173e973d92b03e8f7cd54b5dcbd49e5c93046288c5bd8ac95f711e384807a40a, + 0x1e9e9e8f087fe7eae21b84385017d6306c73ee4dcc5b09efe1f91b9df6396353, + 0x2cd39e6fda7b0a75926254d1b4bd27ad6018ea559290d2041a6a1cd485026cee, + 0x2babe32c6ad1c466c0923e89242ff07997ad91281972ca9690ad77806c79f9a8, + 0x1671e3aefead10c1eab057577cef2d003653275ea183f956583dab5e6717aef6, + 0x638040b4e068d6330e2073b9042e25763872c4564b413d1d8df3dc5271cde9d, + 0x13a1be086b1c130fc9b0377bf5f4c7ab4166b34dc1442af15bd9ada0b316489f, + 0xe92a08c67a64c7e267acf28a048035d8d702bc0e49b7157132781f3f912c04, + 0x24fcf21bb660a9465b6a50ea1e0ff6c88d463e5c14cc82e7f333bd8cd9e9da57, + 0x19c3400c22778ad2608cc33d103d7558b909f2bffe1128945021cfa3996b90ce, + 0x1804ddf73341fab213bd15ac4fb0b38b210038ab3097df363df15449ca092955, + 0x2d030e104eb695f158216f2d17baf589c6b7eb3174702acffff3459faa369209, + 0x2ac28b5273536d5520dbc0f2d1ca6225372569f2c1f815eb0d98ea23bde3e0a9, + 0x132369e44fa5b49f309bdb51e3f76481bc7151112c28ee7c6058d4404d326aab, + 0x1030d8dd6355ef0e8b3bd213083f0540158a13dc059335b0a68471c1d8f995cf, + 0x10754be6667d0c88da8d27c8d885c68c2ec53e66879efc8664a313846c8db7f4, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x245fdf24ed7cac6d987a5f1098a3dc2094e8445ea8a34d409caa0de9ee8833ad, + 0x2ddcd4b1ef28429efb5371343d7c1aa34394b214ba4d3786a72ff4a260f80341, + 0x9796da1c54e94658988e1e47f2ab2a18fb54bd12c0f69761a11428d2bf8060b, + 0x2b820079829572e4737fd84b55e00d69b9842681762d614c4cc9f4c83dc7c88a, + 0x2a2c8f2dd7ed7049029ac58e2483bbc92ca9deb979598179962834099a206d0b, + 0x2e5131ed99601233301a58544eb5b390adc2aed2f7bb8975f4e3089ba598e03d, + 0x6f800a70d479c89318ce14ace0c1f7ded913cb3186aa67acc7290b35f941c80, + 0x848edf27122e8c897ece8ff31c76e8e3da4ec246480e769809bebcdb4680146, + 0x3032a7d711f11783b0cfa12d0a9bbaff62fb9d75cbe50aa6e684f9285d55840a, + 0x156bb4b89a15827370ed5326bc516f90e80da2b33bfa976b4c9a26f4c0bcb5d4, + 0x104b800aad84f2de01925253de1300447944ff027999bf3a113dfe28236e707e, + 0xee24634e1374e506d3186a10f60315beb8a311ca69d595c0afa0e4dfad5ec22, + 0x886f6c8618d45654de796ffb0a718eb65e5236deff84adc493e6a49308509bf, + 0x303f792b77de056334bf4b95c535b224edccc1d65b28e52d569695fe0a86f7e7, + 0x2ce5f9bdc64ab48b32e5ed411be107b280119255d976673c14ca2e70c76fa68a, + 0x26f0252f0b0b6f638aa04dab03f6a8fe7875a84fe5c6763aa9443faabd36d6af, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x895eaa7421d5c92db73111875ff0e97d1f1cf13454c8d0ee65ae0c86cb9f0c6, + 0x5a37e53d3c5dbbf9cd972b637bfb018efcfa1fd5cbe8b5dbf9f37608783392a, + 0x2151abfa55e801a5dd55f82b711f05b3e61fd9c94dc77201a9e62c89091da8c0, + 0x1df7040bdf6398bfbc5dc0bcfd52e2cb6acc1e32ea9eec40e1c14a173615a901, + 0x82d9c0993ae4a12a039c11aad12743c5f5d286c648a89b4342169aa4100b9aa, + 0x295f9f8fa059d54d4b582213965eabc5ed6f785e4aa71196f6238be2c511bd11, + 0x11489075194474f063993741279cea5cea810bce027e64ad900225ced81b35e, + 0xc308adc9b0dea53e1c37e06d0576f4ed39c2aea66bf429ac00575a9105112b0, + 0x1c8ae9521d6579b43520c3cbcd712b3dfbbd2b1543d1564f7d918c6e330e08a6, + 0xc69ad644957599bb3eda1d9f831ca67b021b33f6407ff2e56870e7ab3d5a569, + 0x17de4f74815fb3a0f45728b381e2ddf7c1157e5d65989ebde47f8bcb88f36836, + 0x1fc13b76344108f12af68f0bc80c99577f09a266368f0e274794a3cf65b48d17, + 0x2fad04c4a1bf440fe56076df74e5c30a58a6e26fa9da0865bd0374b6ae37f4a2, + 0x20766bcc7f359bfe765ce87998097a7501d7924730fe7325aacceaa054e2ea5b, + 0x14eb221ab65d0dbc5edf6a2065188ea9057f935d028f7ed14729ebdd66ed5fd7, + 0x1cade81c4d562aff84daadd630392b735b948175c064ace958e0c789c9d93bf, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x19b64914374910bacc33326c70be0a8518e71f26b4e1aae5d33fd5dcebbb1f44, + 0xec087bc39e5058e0c5c1432b20c612537441be0107ed759d3a9468ada975dda, + 0x25f6ade6e9833696c4dbc19c765ca2ced09f47f0745dfc850efd26e3a8bfc5f6, + 0x842f674f65a495938dba020f22a476840e0591f179780d72c00153ddef5a9ae, + 0x24b3232f05be57ef3c4c22af9cc37a73f0ae40289fb0fa880630f7e3d00997aa, + 0x2f4b230d825a682520ac0b5326d130a24bb89363318961ef5f65391b8e7f6bc3, + 0xf1644020d8a6c0dde5068f18ab196d348172aadcfd6391c31ff1b54f513509d, + 0x73fd850ca9561f8a645c9e4af943d372a4b8620b78bbbc357a97d14f531797, + 0x284f86b9cce13fbb6fd660d8e52cf27f7bf2723a494278f3cb0c3bad0574d104, + 0x16bee52d1d6d362b9430ccf4d2f1afeafe3572ae4eaa03be6af6f1bcc05de855, + 0x254cec1178e80740cca318d1b5db37b5dd23fa2c44abb7f1535200618b9ba0c5, + 0x113069cf767ed4afc61e592e98a63edaef98278c2ce59db109c94ef6dea9cf, + 0x2829e1532b4fcdb2df9104cc23b3331a1d51c7d0da9b645a4a43dbeaea77d229, + 0x24a03c0f7b51b6e24a889690a3341f55deacaddafc1ff871af6fd6a76dce8bee, + 0x24a7c2c124131ab37ed62a0182114a5dce4ab7e62b14ff632703b23a78f391a0, + 0x19529e943e466da82e6bae8f1750de8620e060306d9df5a9d20a83a4b68fc09c, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x274c0f68f679da53bdcdf9c11393c34ef8fe59cdeeecf859d4ad53069a88789c, + 0x1c900ca5882b107a3b8a8938140b127cd3ffbf539c9145f385cea5e7dc6978f5, + 0x55a3264b130bb4316f4503af137f0d964b753ba575456a74581b68c6789df33, + 0x290033424503055ab2e6b8093a758db0f02dcfc4adaf26a30f467b0e8aa1af13, + 0x1b415d6ec7893774bf9a598a8496f83a5422861a044211e0d525493f75c7bca1, + 0x2d5e6a92650786e6ab35f3a62c5689a0288849d1eec7ebf89b9a6df75cdafd39, + 0x15b1c6c75717d38e94265523f0f6491e22d8b79a791b10b21139f008651e3037, + 0x1f929349fb5222c4a6f17fde7f0aaca6430b6785cc5f65c3e1b7842c338dc1e3, + 0x23034bb8b8618de8c8890fc8fee6422147545d11d45e41ed6326b767ff099cba, + 0x2ab706c6d21e887b5906d4db350e41b176323ed39f88a75b80f1eb2680169f69, + 0x4c1031dda5e43ef325b33a80e6cd32cb22b16ad324fbd90ccf79c1f7e9ee062, + 0x1d663d31705eefca25d29b8894223a7daf06bfecf4e8e0bb845682fce0b1a41e, + 0x18c97bc6dc2ee1c3d66bdad7046019b6d4aba6592823a51ae2a8052824c6e332, + 0xdde410729932dcaff0490adec752faade582e2eff9d05896da43fac32e1ad3a, + 0xb12de1270d788dabec1456611485a6841cdfe411a09f80c0e132828568d8eab, + 0x5194088cb1b0f39c5b1527bd0a3ac4d16c845c2388cd22dee75544eceab640c, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x2a2904f92bdc035f347c6fb6df54ac6b482a2642dd8e798f9df0915fcc86872b, + 0x8bc0f22b597fa12cd8189c5fd0f79b2b10d6c65946b287890dc5f594761d665, + 0x2bb55a554f9bcc5ea8dbd4d5453e188122c66c507fdd08d0589706c1335619d4, + 0x2471e91078add335f5c48457785ef1b469484ed697e2e9f80d0fc73852492508, + 0x2ccf72b7324cbdd4a1b980d883532ef2887c798ef446408e885f8cbd14ac42ac, + 0x1c3b75aada78c1b204a35386f68e09a8ed700bd88685d0e38cedadfbd88a583d, + 0x11164ea9623704eafef86bbcfecad592597038fc1b097380effca4502577c733, + 0x4b961c368270196ac2ada2e66e44a4440905eff5b58341302ceaddfa215f691, + 0x39dcd1dd3ff8d7fe019dda64104e9bbfa1c60fabd54065c85e727302d8335db, + 0x90f27feffe276b6c1d77f6a80d2c25680fb854af9ad1be11268064e735060b8, + 0x202922769a226e1dea3c39d791bf28ec93639c7937eb7be2c10912ee896fd3e2, + 0x163bb1b115962019e41bd1c7cf0d8783d4baa163dcbf6e25d368c543f9560a5, + 0x255dd24ea1b49972007c3b74fd98c3ccc682fde58858a2073be4b90b39e57cf8, + 0x2be5aecc70e89fd7fd3e2683bea0ce600cf42759ec5941f0746f126b11beccdc, + 0x1584587c91f57bbdc41e85ea3ac8ea67ed261cd8d5014b424a1dc01bac478b91, + 0x2131be5b4387d226c22bcd102973756cd7ff955452e9eae429107ab244294b14, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x254b0e91bf714a1b45748d756729102fdab89301fc89d029d5537f9226e042f7, + 0x303c21aa2f173c290af9ea8e0a10f7858ffab7519185843d2049a22946026b11, + 0x41e6ecfc8a13cdf52f9c21662906f395ae172f944c7575073c0eee9962941f9, + 0x19eb35e2795098faffef9ef5baca33da9ecf94d5973c0ecd25e6899630af7a76, + 0x1142d22ec011a94a940fe203deb1997b64f780bf35d06276644f98e48e2c9ff8, + 0xfddc36dde84e16a5c2f631470943ce31e4be6305bca6e5c753c6186f1059f62, + 0x5b14ba6526be3dcc17bf7d609a42aac1adfe0f449a3d9374e0c22e26b2c2362, + 0x16152ab0a00c391d450290ae825cf5ca2769fbbf2e7eb69f8764025f68e9ff5b, + 0x28cc90877e4cce38fd08c1af95cc3f885a5c5328fa0ee0bc89ca190694d8e484, + 0x2df5ab9a480bba00072c401baae420c1800155b9f7d1ab9b31e976ad800929d1, + 0x12640a01d9b60560290065a3fd812afc07a6e795408f988071aeedf22ab75e66, + 0x1b2792d807f55ebab5f4274d43ccdb9d23c155b8b9f6df8694ecc6f67e20028b, + 0x16c2ea687479d257e26a655b5c6c27bc1f455eeeac28c3b3ce654bc76cac38f3, + 0x26da8fd5fc478751e06453b0ecb6cdaabf231a58e603ac4ad14717d70db2f27d, + 0x14f3a3e34739d7c727b010a5022d9f0f3e035e91db3aa947e3ebe3366eed27c3, + 0x366141d1115aafb084cfa866c52ef40a5fa57fdc8e06fc2f1e46b967c9c6615, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x15658afd9b2c13d4bc0c637cef9717e943c50f83b67c8676d67d17050494e5cc, + 0x1f318dc3e277bd895a88dbd9e3c4febd43cdb9064683ffbf1be9e6f9b2a71669, + 0x141cdd5f2c18d63eec6e82248935eaeac4ef044ee76cb7ef0e9259ab6f93daaa, + 0xe4b254bc67d3857f499682863a0f95b76e9d5cc9fb7c2c59729db203050299f, + 0x2cc2b90a7bf9f3663b0f41ede34f60d63a99860760ed6027fe17d4fa9eb1b396, + 0x2e0819713df7c7a942c08b3ea50add92e39214104120803a5806aad10234abc1, + 0x24164a433840a28d2615c719c716f2f7c01f7c3854a327da6c5db75097fef1ee, + 0x272543f2284921391729ae58db1d9db0807629d9211778b0756ea7e4f88297b1, + 0x194af27987f50ed8730d267dcfd98a9a284a3582cfb7356e3dc46bbca1eeed6a, + 0x2044ba55f5e44c7069590bd2abfcb2b7b163d47e0e1bf2e2524c0948da4b1a37, + 0x19d37fca1b67b7ac626349cbf2928b9457863637baa2613b494d9da18cc384f0, + 0x1230ea231084e3641817b74662caf5732556c3d94a01d209fea1f6777ae6cca1, + 0x2f924a42d4d9446cb488295883fdadce8debda5ac727901eabf2d8627dc6d698, + 0x2da745785ae0d3eff1a3281d7537383abfdfba2031a880acd8dabb3388a4ce95, + 0x72fa635414d1673fab8d057107792b3039c033d924cc0b1530497c2c810428, + 0x19db329f086a50781b0c6eb2552ba454db2fcbbc125a5ec41ed2c0e840bd6774, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x1ea4f3fe9b4abfce9e655b05c4f64a0849003f9b349bdbf349ea2a249bdc945d, + 0x23c87854133b5d392742dce58aa01cf376e3983dd939634c4fee6326db21db4c, + 0xbc4774e1e80349b9a704c01709de843f3b20a75be630d1b6c6555adf3bda042, + 0x143ffd0adddc79c51edcfac6ffc1aa3d99ebf2d55349df53a54842c945a82f55, + 0x2b813146b9e70f53e3cb2549a91e68963928c40e02c08729e0fd3f5941b3d602, + 0x13de9ef153bd22f5063cb42abc061c09eec510e4b694a4e9b9bf6de56cc2f206, + 0x30015dd143c80d113c290bf94ee9d7b10cbfb93959e846751c3b3ef9f8d07490, + 0x2515eeb903d6537674e4fb3cee0b3a4c5051ef3cfc1a3d1dd2a25f4ddf96e05a, + 0x20ec5ec6cb5f91d860925a6341af5cb15fcf4b2694083235ebc7ea78ccf6421f, + 0x77160d3b99920220fa591a49f79c56a282b6e368cd1419ef09632e869599f14, + 0x2dc01f61427888cb2d5ae9d8a0499cafc03945dbf111727b1a2cbae73bb41b0d, + 0x1df3b805da3b583cc8f736372e7b16d3d0407e634b6cb7ebef2b168932194147, + 0x224a6cb7f4e964e616ca5b0f23c77859232674745d32072096bb9f12131f0075, + 0x7f74f0de535231775307017a09328c7491bf0fb7ce86ad5fb589594154983fd, + 0x2816d118f59d3cead1cedf5cc76a1a87829b2d8c1fa10adbb2fd4eebc0373b26, + 0x1698c0df24945164067e5d0d9b0321a757818a0cbfae969e28c76dc470974440, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x2d878d0119485477be8dbf01a3aefa927a230065cefa169e34cdcd8e97efee48, + 0x2af377e1ffcb6909a07fb9d03937ce4a8fead2190cabda6baebd5943445dc0e4, + 0x110ffaae8772ac77a0fe26f368484344ff681843ef616c6d73e0dd95d5f1f3e8, + 0x92cde477438d1a1335b795d5a5ae15d0949877c734a0eca249865ae30a4ce2d, + 0x2cb1dcc78144adfca1e53dc251c2e4084970c941855ee6a772d30dfbb1a6448b, + 0x1e80f366933f00562d3facb54015e72fc4cf46897bd71f3f3015bb3f8895231d, + 0x20c5d9b2e153f4787a765096aa7c1f47f990e810004ee7737c211150c40b79ed, + 0x12e81ecb7ef55b86893278ce37c429400af30b34c10b0acd786fbd7b25c3469d, + 0x1cbbeabe0289ed5942f50531a647530f105e72d1f912eb11539d1fc5588ce1f7, + 0x213c4970760a5882661e0e818f43450b8cf9e02dbd0046f27ea4d66403ed0ee7, + 0x286f73e14f72495fbb280d713b0161ff695a21091150ee6c9ae96eddf36e212b, + 0xd64a21cebd1f59801551216c693b181aa963bce18a7f4439f179e7105836296, + 0x14bb39c836c00f33ea9903dba3d3d434ec33deaec35076eafc1a4c5a01a417c3, + 0x2ca5b88e6bb11f61e5dcc2a4ef664b49a3801009f1eb74208313b7b04d59edd8, + 0x2c44af041ac89242a8bd751d96ce0f86eddf8c312e6b3127c53e6017c0d22e77, + 0x1466d21f848850fbea559a4c76b1a00787f997c1a4a5bd40643036ab684553d7, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x220cecbc247151bc202a81a4573f923bc92a2208b17e1c0bf2dfba0de4fd26da, + 0xb71d939b546f609ccb189dcbeed82a34d8f2faa2c597a3b3678369a471d817a, + 0x2cfba88722ad37fda1b7ec9489a96e09e88bbf6649c8b7014bdde34ef18a64e0, + 0xd0debc0f0d5dcdf74f2192da068f87631213a52aaf59eada0bd59bb99ba9510, + 0x1d202504d57a61c4cd6bf007e478d9588d8e6585ebc602227379aaf25bbf6ad7, + 0x251253367a3e28a691d3b6fff1209f6cf0e03736928725dea0f9f0824ae70dc2, + 0x260c55e9c06f653d9202d03f1c184fb70df2f937ad157719685863e4338fb4be, + 0x200b2246239844344cce8854c24c9a9b14e438de6a3ea445151882f23168fd20, + 0x2e3e47be40c7216d9db75470bd8193c3558ba3c61c552bc56dab2713af62506c, + 0x2784c2b142bf3e8639e090358a1a3c81e25f23edcab18001514c617cd0918a5c, + 0x125de24f4fbc6e879b4039af38a1d041e6c38a270b3b9502e10c09f149445d66, + 0x29740adacf9d3689e443639c25e367b23d07d690c9ea8da6e12fa6443502f903, + 0x2bb9d36c36a107db72deb4262776967926f923df9c96cf07708d5659cc04ac81, + 0xb3d9827d898e83333c83c65818f7fc1761fcf632d1b5f03ee95085b518dfb67, + 0x10a6e860715f76969d739bd3c393f1af2c6d27f3f8c21e101dc8cf7a515eef7e, + 0x2d8b0a8bf894b7d607d9a49dc6f8725431f69ef0541debd9a41ccec4b7c1853e, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x2f127fbd7f50d13e1ed144760d37a375a507ac1f0475fd1fa1cab401ecafc7fb, + 0x1577d27a4a8983d54a364994db2232806dc6a3f1ae005960adbcb4352a88b9e2, + 0x52914cca13bf1c8dd7b8ae8329393ccb24dcbb32c4625ea2ba6cf935be4f231, + 0x3ae3cb86c125ba7e22c68fc612f2928a961ba4967a5afc661ed2c32de93fd30, + 0x297797def82244ac873c64c1e3b0586725adff324eeb9b15a9b476823e6179e1, + 0x124a7a8c6e44e7135b58fc2b76062171b5054af0def6044d99637adfdb5b403, + 0x1122cd468ae5a811791bbfd990f5ef430eb1e1f1c6f7469e5746db7ec0426892, + 0x2409be076f6bbfe87a660f865fe5aeb4abf064c12bdada933eed7824ba271cdf, + 0x300cab922f89292915e01a78def7ae323501694f122737b9ec6739f123278b3b, + 0xd743547bd321fbd1b27ebfc7d52797b2f97323d25f1a374afec19a1630ab63b, + 0x9563550bdacc55218984e8413a1226c22b38c12d69ac16bf6e3f952a787a504, + 0x1985c8553ee8e78bd1c65b3f375fe99cb0c14d60e69fc6d205cc54bd173f5204, + 0x1bd7b38a27edbf115143764d25bdac7e921e83b29964101b494f8075a7800763, + 0x2766850751254f44f4e93db5621839bf0eced728a6d2b8cff05b0fcda945e, + 0x135b92c76b52af013119fdf43e9ff79cb40208b2c78cccd727781ff1f456039e, + 0x19da226a03cebea345c9a56cf3b4c7e6980d613471b97894a7d5fed6f3e1c743, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x92f4acca2e0ede5ba901916da9e1f67bf4458f8495eea238d17332da63aa71a, + 0x1641d2d820f16a7e3f48def116b6cd078de47aeb782d8295c5f505d89a9e4ba, + 0x85201a2d77102c3d0c63353013c47c2adea146120e8d6b3e2319d8e63ba0cca, + 0xa53d758d0108ebf22dace7bbbb70afa26f400485dee9e4e7f4f7ab7d9299677, + 0x262d9423cd20852bc68c46fe5eae59a81d1d814a66a638c8c00127fe2dd98761, + 0x2ade8678e1c4e5a88001f70873e9c28bb8b86bc77c1712731057b410468c8f30, + 0xee8ff3fc24bcd3063e995a4cbcd34f46142c9f3abff0f8e46a86795b5b46552, + 0x2b825f9cd4585ef46a5da502209c12464c824adfb18032718bb37e4738cb3292, + 0x1ac8101da6ddec552238fcff3932ff2eb40ba38ed0c39eb5903e3adccff791d, + 0x1ab95f20ef0daa5ceb85f821413b046e9fb8a70b61e77f8f5469711f508f178f, + 0x580d8b79189de04500aa5749909874f8b5968c9204d6511e05ba1a3953362c, + 0x275875a979f31b1c8db47f6dba4c553c8732aa37c4c74d7fe9f979274dc27c95, + 0x13d84732bb3b9bc97162533644a7515d91f08d970584510db56caba62dfa0d66, + 0x4d47f94ed591c3969fee09e23f392dcd0831126d621ff5a07784bbb5178e876, + 0x268be50015a5f4676f202ecef15e094130bab5822d63d777374c8a0b9f4f3832, + 0xc44a75d5020d4aed139ad7294f27763391f2be6bd3343691ea6e122c4356fcb, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x212e7e2ecfce78922708fcaf276bbbded3c0e2d8804d66a13fa020749c48ecc0, + 0x158fa860b8267b4011780eeb782c4d2b878ae2615e317b798961be28a7ca2462, + 0x1def7622e54639fd40813cf1bf8162198af19e07d88a0d42d436368745e3cca6, + 0x145ad4994d42ca69669e4c78ef8db06461047f4976dbc5ad4a6cf2c3ff78bf57, + 0x197d0463b10a21649f25670cdd2504ba58621ab912b643293b32a515f50afdfc, + 0x23398d180006069a68c7742caf4c669b87742b603d5ec75c13d2a835103a0fd4, + 0x1e0258bd63687d7b17c4fa3789f9fd82108a3d38ed4458e50a071c4b622866c8, + 0x423f6744b5b95af35bb9caa720088b05e7fe89176569010e96792e0fd06a28c, + 0xc50436db6d99e5a8933aef29ac83fa2817395c577d0ba3e0152fd383542088a, + 0x10a22724b783a4ed75e92202a6121ad76eec88c3f6b6d2b0cd5a2f829d7caa37, + 0xf49f1ad9de4f057eb3acadbe2279d617384c0f594503c616c8a1f7c05fcc886, + 0x2141c09b30eaac9f355f49e98905435476bfa52fa5339ea30fc48beabece0f4b, + 0x15c1c2b59c45dfc274c111fbcc2b79bd7440d738d0b433518ad3c8ce8d064ed, + 0x1db3bd1d64fe08c2dae2ddaddc2c339ca0402bec8b41b74d74998aabfdfb7bfc, + 0x29a5a2015c3c31790000852191471c62442721881310f01e2fb0b92157a6adaf, + 0xc8dc01d3f82d41bd600fd0759bfe0aa674a0b7d089b0ed0ea9127fd0847832, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x2a824ce1fd2a8c476123e3a989bf2d6709db1ae25b6003b35f4e9a63b414a58, + 0x12ebc9623cf8edf6e519f0b679939b74b2e4b4097992d2ed382afa7dc08b484f, + 0x16be2e58e7c791d1a9edeb27d648d697ac592d085c504517cac06dcccc9b80b9, + 0x11f10e1bbfb29ef8257b3f13add23550576bae71f723613ffadbda16f76e67de, + 0x1ad4858514fea633d11ef8b8460a55cbbff262b90a7704fc2ae9f4de51d43328, + 0x215f4b249b5c5e65fabe4b485656a746d564d4451568c1949d28e35624cd5d60, + 0x1fbad1d2ea18f2f77723b3dcf4acde26751b05615c0af9d607481ae4155b0b31, + 0x21662871d695f76be370b37b3214a511fa6a186c5c856af4f830950ca601a9e0, + 0x23ef880efe39676ca81b90ff6258371415feffe1514a33fb3b944360cebab527, + 0x2821c241fcaebd3a0039501eb930cf9a84760a177be827540ba0f3c7aec6e354, + 0x146be2228a62f0b2678d113c1e9bc68ec984fbc98358441882c3223c5d08ddac, + 0xb88bf45643cca07b10d4c2d229d9f4f8186e5da1b4a7921bdb81082d525ff22, + 0x8fc9cbeac386e14a1121a09f0ba01977c6a4b444528bf675ffa538229fd0b1e, + 0x1b50431a74a6fbb3653b07cb93b41b31f4b8e8f0069132630d85d6247c754a05, + 0x1e406be857f7f834e34e4366a64203a4587e3d15e3fb68fce7cd1648bf281d9b, + 0x148eba772251ed3515118d4b1cd35d1dad67cb449e93053aeedf6c90725deec4, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x2e04360710f57315981909dd928e62c44c44034647842dfa31526f83f4e02671, + 0x2aafcfc0a678286f879baff9f360018f642f5dc0fcdd24efede6f42ab41f3876, + 0xc056d71fbe0367362ee12d47779dbac6784d03b9effcfdeb97b91c57f65e433, + 0x115524aab9917d448fef5342d3773f10c7bc33b0fe015fc39851bb6afb542fd7, + 0x117e6ade5e05bc5efbd21dd42adbec70159c427bdabafa5df3bafe8d48240958, + 0x381334a0ddf5db66871f8bd943e4a54dfd1f9b7d13c52944fa0ff2562250fc8, + 0x43e8c4009abbada6a3350bee3e92556368245a5aac0c1b52f2338e1ce1121c4, + 0x2e88167d899544487a1cff38e196dc25b3b8ebd01a2289b382c965e11128cb7c, + 0x1c308d8fbd04e1e349b4e0ce629b3fbac322460faa3a3731112d44c3a4db27ae, + 0x34ef7e4e0ac0d3d85f4adb5bef214c96512accc1c0f3a11470b493d4a6e7946, + 0x2b6f7ec4e66fade014011c277952b270953966e9fc9def4bcd21052f62315a76, + 0x2a8510585ae4c162b269375af5bf36d48824b1cd4d323125f061dc90f06fe318, + 0x19008b99b3e1da588b1094f3110f9032354d1aaf9c93ca9f1dd0010f974c3fde, + 0x2560926db4543ac9b3ec4ad64b12021d232944ba8ddc47bdc494f5ba051f65e3, + 0x29ccea21d8edecf6359058c36019960b8e0cd6e0878f835879477fa3ba09965, + 0x22200c2de87d7552604e1ecc47c639ec983525fe8484a3d24655d5dec1a4ba33, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x2ad7a0d2da92e10ea6eb68264ba502da9a0a5b35bab9699cbc29fd8fe2e30ab1, + 0x20590023505117aecc066d41c1adbd5ad4cbf0e9b8dfeaf9f9e8799f07534408, + 0x222c46e262ca50113017fcf937c68bc5a2ce66216ece4254ac3d07fdacbff44d, + 0x18e7420a44ea5b1e13f4779818b97a2081be214baeb62671e0dae86c4023ae13, + 0x22ea7ca068c59b65cc056374a848ac65417a6f02d8caa04407d1394ea1ba8256, + 0xd3a07b74e65318c9e1879c337057cc712c0f533ba49c1c626d1b7ab155936db, + 0x61d5292ac1d8dc58ab73a0a48f6f631262c6601fb7c0b48c1a16452b546db6d, + 0x5833012960b055133c9ba572828b91414cd7ba31d68ef46f5f76078c3ca1841, + 0x2f2764c49d1bc1427e519f7690e301a620a62a89bd44dd766d6ca181d02eb406, + 0xb8a8d7bade0db2c62bb09b73bf7444c087ff5e82ef4df25cd0f9ecaa12bfff9, + 0x1bd2b4b1504d8c446a5125fa97754b345cce5966a6e0ece3586933510071283c, + 0x87c0b8b7b9ed1a7f917066f04927482b71b00120114f6eb57c272cb26ab0ab0, + 0x20fd707a8cc61d2a031709dab4ae58bf5032a09b570e7497c3415596d3d5fd24, + 0x1a33b2e800ae297e35eeaf4e3bd055dc56e533f4441bb24bfd130b924d71cf72, + 0x18415cd52a959280d64154df2c538469ce854f7561e19b7d05235c9fa478ce0c, + 0x2e6a310ed3f24d835969e401ff1df8540801ab6fafa90e70e50a8230f334ae66, + 0x190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56, + 0x2fc4ba3b1f7871a2df1a801b29d1eb494e3a4d072b6638da905d5fceefd93c51, + 0x1162c765b187e20f079a417abec80c369b6e1efebdd9a6bad7577c1722b597b, + 0x9a3571080ab89c41d2c53279c9ab9ced52efb9cd1526d24dd58b31771a75606, + 0x2fdf9f81c2ad998f2229e64e084f9149ea3f0948cd928136086120b68ae69651, + 0x178e83d7f2f9ed92d3d783287f25fe8d0d28bef0cbf2315ca03da314aaeb94bf, + 0x278d681f603da186319befa5d2c5567a9fb52eed6061787cefa92b27c28a64ee, + 0x108fd8bc50dcc43af4d73686abf8fd70b42245c1af2edcf11090784a24aa5fb9, + 0x4ff765c30d4e035bcfbc196c646541fa1d27c05d5d087e01c03ef11224b78f3, + 0x607cd8ff9b889773c9eb68b8a4366469d470cd7c6004106caae95c10c424419, + 0x1da524cff60b64856dc1f5dde0ff62da7b182da26908f6ba6e590adebf91b40c, + 0x22f33eaee3c481e65801b761a72832908f066fe21dab5fa5ec1d4c6e99dd6dfc, + 0x75f84e9c719bb8de8e61083290daff19aaa4337454e5ba804257787470f2f54, + 0x2084be9a57e9adb80303a8dcaffd4bb77adb6815168b36a1d363b38425437135, + 0xb303449f1bf4b92d2cbc26ab34b4215b6dd7af010747a705b2a6e3398882922, + 0xc099bc68243537203f97254f08dfb7efc09de8f96d72f3b3e0aaded45e18b4a, + 0x1c5fd9060d4e0d999264429a5004c165570bd1675b09f977708b1ca48e616388 + ] ) } + // noir-fmt:ignore -pub fn x5_10_config() -> PoseidonConfig<680, 100> { +pub fn x5_10_config() -> PoseidonConfig<10, 140, 1140> { config( 10, 8, 60, alpha(), - [6377232663526537440095439257883018477761342422116697881186123375221738885878,851539971462439380385862352460596759101811723695394639617127852578681769809,8777577262325190174206575699458733195047013200879424709893142671840513604890,21694543997668766291509756109744969193435163886467863962355853609369758783238,9577278996811393500051721677710083593799044422389686435650597107832854019185,16323954252044716897246121150114593642230197187021287621193086593549237094775,9789909425016820105251161906130605326280235056822272235912508431951118212950,5766700650277227528545902607164112169119010038912902265869378685414299620760,14342521005374081251816746055115831251291272287569749723238975882435091047876,2566050045458470252423704003188705777658084864238473334290159653618543192811,8762700051029310248153110133778709519032029454737126719215892745208105815416,4708553466520767412303631379034292236924119642035476122997253385705160556618,4755252554118675759917549980023743559070421272488077422007409392838436797712,8781462767081720534606018702554359272062136386754094559457527802951016005606,19167810216492792969016670752653089791475857662598893252819620255611011677188,12379801295054424513880366937656969081677178004556540562031393564676230427743,3873349522143254287251699452075145107916086554326675869006906246349942638560,1683302064923931554193379270562867202085645938091131834974486624990867609624,2777362700160137801933468204963311934247500177582714816722898763176642740860,5330041075666088752029210636784758218847391095319460299231210692948196701638,11849341704739004206642161112350419905150271791787570525216826204427280723792,7477184099861050355308565098520563835117942875101546634259876195229073147282,18811741129290507103385501216699521500514849038287903802256059864942452310117,15644162092778325718506673614750051639809307056147336506838023349115605106787,15072682042494620166496832302000289519302436589952610199010633012972669445593,7385535266916101728534366006042662339391797772494836337087929961280561819695,10606300178546340442574451452231017670874690381506662581848460294140286741651,343808333592012682122858022517390819973432303579818622412786360520154826142,6686378289544833739489172513893542192299224296746579469451376125664696638046,9325668720082019512834072623751272154060473105966456255302021143714657867878,13237356616132921941407245964289360960304194019926733744472216846697663447262,1723892942664599421365079138681309575413323508685958773158319650163306910931,6845174279248890961319599668687600484787455619619716546069389087383603254137,14429592766972645051919899517480716657546426049902884218808698177731678278944,2012555589304829161260427679955782678928810146332132910441113793264100264511,15162287124358358727307007568219331690174000191414576263088727973180750593247,6171544970310792508799412092397912280594923286679674322244394636145740843662,11560360683323732335070294251287274796083850957500974817278726137032659811346,7954890646285422519425515982220441977570181574595597355546782742910060927756,2121066076676892095526555416241546752515994960009188371572036715916593676611,1030002705665772802770205305890036009903459272665864721338890073927102958060,16664112528630425414995233349042921759383114978671010908728891678245502701008,16224205339340335222764551648549356562936176805367408466634736640263613613659,5567916191875465998022755280584031341089937668974064792042640432034217833475,10561503261915825576621563677167739482566911623771072553907339314680805249099,1281495108038254322634503929806042733441491866895195579580212370919762081047,9600700315845518751455006692480832601523246124684033595437676082879283709816,15989333248905201890715282122260615227836016238448185882687783867814184655170,3846245593630362971844915233982274952290718501967612724027782949411933001202,9981027954269438386336412342904724691774209648042702865994578173145958992921,8623595877941915162474742420309695649920307514068323484728910858137792561119,21103940025922636831675399050467233863786411927021772979799068688191712316972,18892924253208304354853962839524897599416779246859691035714354037906441368765,17137414752196927825772499610314584261795745874954692214656847237011815603711,20412422497099028107138997806006051244688526968840932637543351831550882135155,11225636734520002481404086272590673372060731353304957503311626880321065568136,18380442589598191047463232737740533198002604231823107797039491680652883496794,1080201698768913889646664841066956319958767123758689784419321296338840961295,14348402455238680465583355269916779409600823120873923092214453448424409970818,3841435364722615893087024818655055436552226081083242159440517874888324292581,3408210599862246992363134715624815235769905293647431849706383726509064300506,12828232946525727915578787875290899244261094596690184893334123105536745936334,5483797730688489537248191960281635992343565537360149542110268773175134131314,15646042484365011867018844828962923289034117590475224947755290094723626891273,2658047411395048849255440353544966399245817841159701280361972904541325691434,19496407504291857422030801612379213952698163884670351003527359060477191854359,11599969200544990318778456235768317543324325704256981991953010275435791017626,12534635949431553834868179572769836881352677117158862189611147293522496413113,14223314197724082301050736397492110631416043159307338723464864105007185825079,19822547161504065277026677714514212915462043072809743766437313193660041742198,18248624683501549165279508462273639851850239430868786828229911137041335077425,1772507929668430466250295341031184282507314702999122972093244182511342701791,12698826328883589821004991321815018437184890565199562478819948777685095680390,2107256591274868946942358544310209350935597133418111664653447540003390113607,8347096431391887603955816523197766644723983907921702200049607244690524226105,7546736802459880596530318577784618006564482951653292089248497980343037655783,7337317896163766810388205540011597034395961854295494001017429381228506327036,7657535373588628884973408484470050620893383237179421367090832333743641042323,13132621069544809006163499228792832380417930375502811639756010731409020775733,3045981446877420174701593721028589257508837379178848429319604486793747007869,1665034234802535695418712526119528879364535660712727125979361452433857586005,7153904853002570654968228858836861252211159237410458977141045356668538557384,20486065252261216388496191302294274939758504298167574880569796877079451248375,21146476302842253436461025615017889905755773199293419435978649511293941220143,4692883070549935264853696204165792104522817067387529940796053065681435988854,6240088307004733902463222083449545201088681283438656231355545734118814247048,11555561118019341206516697020813127391202363312629469259248586095720628837415,19260547999655668000047734411254185932378393753746099027853756019009568507886,20469506109273046972497148219051635976793704979896239651651205124084812945608,1236647274759658638933992315999684238758461477931896092313814863963831171033,11384423918232921171964979139440160725835135313593824548598134875347314405204,19785250372370249720518667471906851686135385809175031332352733767471970846466,4246521523867165828929729227115582186945308737715737226156399485201514735146,9952732737001449699912255226665360960719170484486452179287528363081995818191,16411145939754797754686024918808322973332629854064127851496226070432060579489,18478056933955827759744830164752062474839918604932227276753757763884050277828,13204687970556138498219183195522996570326298997850204255083662628089078309770,6486083806326529246393301553077241033740361238170679962888274443184188794118,9215573806816888307072467120643373006129084289252457249266574218300367297487,5157456141970297671458245970390083650482632128904852982724214364911239574334,17822680498490868828738779948851745357227318213932493146619109948725716270324,8322423511882718045936027421959946860221136505721064786938368517081088404769,1146280240837664421126981150154328736275224000612293306261498532925677882509,20006445160687044351950305884447426432577260116801089758873885688911862838124,13132217654381318972692935199671458140461723506405656953229384472487720023845,2321904844688587860096390475332685957247396755436885306389445060312694195758,17673723499361727802425795357032445257876321564734597671004472729727016538966,17836648739374245973743495166940645001620159031723548669336786509810303589036,19509523664323410269318198214695596019790796169778932865716910251136766472034,21365014298519541792222476772118358897898683224332026502540401938408420183049,2443777802329356458012563966932795162347891060116795715814546844741577072487,6373148417441446230918754690291753760232604931431996749195267137425734054207,17543938461501434657363693054851238526018672792888706636605942303973500302856,13900881200135928840365427722717255359580153642574547892815287601924416317614,9982616108044216660339683982954165936737826707471259937628917232293660834440,16457765153339087464480638859689501343872608914611554385236118860039346779707,6882633521418674793651640056518599843365736128725139938457347614662141371026,6558481420440543921623853603383694405865402572023705828527015346924767906364,21119564418700154632542186570611885700968350571284986971813890102274419338575,15668498634043584871060292933787839904928585875204605204028656239629550300891,17754567428791571673016885915321661773655444664247443414002133544771398853149,11486839919314218506003227795241691164988634920977758623356018460082101365168,7521215937712438604222096500164256001666624136838511497877267672752282058366,1168385489601974578347279341199760237159478798101796567718644776242789923601,13117296414138131801834212262010987517820472685866772554743932452738843734333,7749628482107487230728683638475509704638633069294493147970362304145477016517,17102526463093059579604328209955502975564943362848110499048688895825859834607,11877937469390065191819717631885427975032604373385026940117533544572408798485,9490483077873795676333795591814325768750891664453067983811838122306462917887,10191097995163502256819397252907242166733175440759424521233105453843778654820,20532048353899648065110204116821557712236052515292993984913500569982446829913,17354150523998248091397848718695616500251280749145663998809707730330346369346,7747355680464214426243190602078017576496231133574539162185621451748634683393,8756715326391069596985357282435500586860011252775122994945356255643854963530,21536474090524236379254986352553305027867958936847041677436373000730213533274,19764807787330426181831011653714787282097837960248105858049804952757136862708,16451394978386784206980716591328721244692005310628203853347165858510983157051,9958807580185090358651106618892828843813431270139145526116189671892797920190,8667474404638571999095228348352836564567923532278597424241711463350637692261,9754527193113710990714009078343561220541479581342251031659489697296746296505,11755501121260346797952875679164705763574741595098729931802001980529024314166,17343653273660706017905395390969914833245644319150049521732399082825162090569,1010378412861729818622385301577181571311206842734096023690850995284550560689,12422787992288066268619146495902983268274452848893191113634050431879037454803,13351916057777123695069150362950067630454763506856720439068955445038740053267,3268740447474291563746626019604727880178668296496938516526099943483641022899,17039539378002212101604857371251026489627400179253250833603358068705093844865,12719626976782614661983190476189661930540289684710840404911817755168256363569,7334691511591452788631693316255271478502517924558055271367172394856435073355,4177321927122082121158728850724807513004613701936483594734414988911849675880,8517156232219806038206488131493677748028421797072860831547349043281348142926,5916342138159497146131772146268734765710150180676587683832045824388433290036,21136252379072914855830890952695340864582847490462136128874077543348574696616,10470343058787342159878702644341062172468027793693540114390435145428370707552,9367903847960780027900264774906616911120367129803429048363499797310012009648,9181708529218875829085211480957344367690955470310754169594385873272587183681,5161879954208731149141751476094480416185338457043041781556700389106447006281,14144603730790033561496908848503636331176898859925995171200576238014458649562,17528475461722173509900495818763366567939364295306035018228011778228457876695,449678858200791083139507971543902712490268199763356935472396275788444419520,16677139862336739737616497869711537864422474730319606529800927093596292773684,5307258894824770781811695261046705160386034275400321369052582330095447609528,7066455454850758706236264136180958260707829859148436565416678574940588976717,17464972536694182038180604993012612781624892485542021128713500864406129068272,1827574381303563082711258077787177320452649985803311391711223171032580182910,5005224603218153811845694200896301756909926774436577539307979565859865998867,13761569869627153404623558442531816440237410187883129666707204029577726405280,7377645231791556592153877817212695036000405157132509030366572797100109551371,18929000938053222386693378771208400814166536156735504775432130183653620422676,10277912490419902146704238375228669373848088391763413912903062245600018539005,18100670309576234559559738539779745691447892297890679181953368845735547051936,19792596568315968292503371918803163404916721074550555295039247624601141857094,6568943725774928078767297883788056758405958920376813493652098209237338819058,9708751028820311560873537735196353024741491886920686045780276405320332052014,20999195425108372543557431885250084840784235258564621629580763574508120639473,4668167020556593094762451685509419403613005848434427529155545560914783238805,10260166712816802791730167674468655124354432849926388591536360669342400828562,3588854010476278115364011192514859807683141010842317346600561233941024545452,955642453625490778540666824328669289325333312941525596301926803494785606357,4102026113333601512449185655242077481750021570821512149654744152647996823622,12901729067332459436197297782018174449541114313233855185609986472102830633274,1432400515841095916662233518576616625504866912337953671606919993429647264779,13448330934580056368019676193029108114576729981976748604441994201646531786832,18698774355061680075847219006041299002465669495077065798256778682757699200357,6114255237222848342826972972054203376750041293553715842262723528673741797160,8290432657858704891136963220676191057527195528510584103201077577863568506432,10245893420315465808958329213978599152040050245022584266757834865645078424612,16235075160725310956334026818354575166666144493784149178325740173109469893465,6096223185593495310139379444667947750109489326578429517185410779366192202063,15140535409353326038030605492985074291044727716595244779768492745470176024609,2176086602170005476358821348469239586548222322021168089824748815230407069862,13619789468668594404222482251836770591464929359372018436289664558758704681508,8310543107961996371575168146304294641952910047046695374038288287522235989972,7738370036488385965043396010845927300705713772735513648600973583706126470834,4479339978160586717158719172802732929733916533373426058515465717943672025882,4249199078635815430904933856748414549211196022798648243994671515262509861644,4217767457132611540965149700331359170343442048612092095364557557503970133933,13153296757017742961007840475261159306564053749538202546045661292791402275573,4396888098805340064553349190742819413046668458070694926676742098287729413444,16734434548572604008363129496559919254718993826492605430831689587940707338899,9015659000250675923210953833943081286931414181352124970688626484896488861379,7859006238840384066905305454236928888746240833462349287375399918976884871408,20111156231978127386472936347996655414872475039138926155687856551161732442682,20628144438246471187747981572742727430082255446467380395647482352559593647287,10829450719086027299358038584474043478547531034689618353624096053194488185624,3900905003848877440680433966861518022290921312029158328541666844523704712962,17855611209216805679188603521771950395726550847102335142668673883933213178620,3545647030011914165273791133303433140616659042668342263053968795372726840341,12285059161807384662955183653994648298401051593713604819454219983692697182696,11819552939527124997493513022814576182004246358800352547817016502521627790011,14301577158059901977856927221571457807294693699285069296999743154546478489569,3571634356329355229397931369891424491520267531585441552581855575412868351910,4493956823795845864156868703591503758707793967931549819151350879135230170242,18261935892851512416084887686097384445742684392402688030129684935728742717201,11603603642132262206403092178979219208473125803069223229133184466185736048060,4847487817017177565347080569283215504545281846426948697937793918200171528656,4069745589764729706654816299792297539062872486670505242875943264008484198412,21282151145529600768369623290936085172906963145870658008436208961308948924585,10721916615176439690683002129869911178402752315827226965537395702918089626824,20400924989628432852029073867249809947097995745931036434033577251949709693425,13612038717302251316998414209460162307179960669236088330389280060785328588738,2142054298626034610320009155682451576863946725173133307732467701538715335347,6814074799679801916559787533428482395152765022569535278039545933747386331226,3320993272550636151137746220977818986579019792097013138902071906802378678391,14404588996507110096126959822135132305375204264088975725278990285893078946890,19449156048766944910033639666691724350749810714682158108539166281157709899569,21600390672948543610212878389553096169635598817477527886039588952230732642418,16122909565998431497578901034409662715618749437754826295511086000491610510803,3814026203802323919937341565517130280297397500968227915639071188757380515963,6912908852134560099979027891279882003635111070588372993239339154823206466274,8991012532130902495044589989450658026455069044478725949828656540931441650779,19794616058753707346170576299297623557371037336156984230370345545981446397931,2577593820399732466692625387687370505160505291664134162589397465829320209836,10545990182245838392125531729060296377668723705525703355179325185018108067002,12532592142366733026886391992589159605208721772700692225488484422366892623887,19135911891605926936423877585461852787990719411437518367185457251216578059981,11635603342092216271740512684448806260427922119693878652222869987036671146111,7718247137511759231158297248913810065531288952022630354624599924037308251451,15449533941190926955831618735652142785144234166497064450979389633622292725920,14793399192194938994493676084408874396657844744757917843286252680102153699293,9379880417179271734210305738187417887144762048262218697049423795232738616822,10001585874846875226646763599153358317197291234293545431914341192928883246454,17564611789675170872923370710570629576001514727841256489502945348076745512773,13526676577413987112607573245391605865887231830025935262602066777025060147701,18771091487566471187260929156402254761992313431761027006794035379840343952064,17672790933843778353408361605666344788858296349839035375070469185645819063077,10136925806345148466019786355963896194230642602748938687391144254701550469628,11669469369568255529354542182318275079656673415035219767446071893709388727608,8717156787967537877037123555054580463721012975068417092258849467938967272751,3574689732222366081898222156809576015147776290993716837975298246375762980084,2936447189567283726966987004410103389002644634186413346432130822474131530801,1699723231413680239740710996339133622208402062115605498128909025253321290927,20239438661176091033530372775196947702401783521122338633601531691101072063415,509222199143055079823531599510182326541217708021228426946045537726376153595,12460587031004227589188413497497959758507406039249371767737225675508588807598,9172361948368872306701383997811949982264909388810393902913358291336142380374,15024321518919789320143737927991052999071746110692384451602809887435324670247,19363337726355099236128975299462078599854604247644073095764375371642393487744,11352512845451687563998689687452223516295911399723160879302208800753615647616,5033097489048897691788022265636063060230313291173145751178865731392231547832,9342768693529219155995840295623046316860027403351256239528640640660995546250,11343407235843410518451234635552443892628096773317032816539735746541252484029,20271637634427257791277080766628733956630399511643807969496831759934416995624,12979118904307784600641734806775453265865076574307149193300157552133646759000,2609049561347471594361989318849223604030501563821990609941361801853208873325,16638136645184843973996251461253142824084602885453534706330402604048300209367,6290150467317840195062942193162131367777911299731759519747208884085640022080,21846903793348064415550139579740558481601211918214432128739680250084492380404,6881355315007836102200696266576401649721953812561017678365140505591991478449,11991852144633415808902015898168146769921125504309617193757255165202163636329,20579180498569037366675392921380645532641402855187025365767529341564826966764,4127941604046459390852849136716344563624191244387948802112999500161867081345,12726445769512078351769013120614118104254671239018619408743816227993876252991,12822824504588887927083519548290538468815267612767490908011540889502830894241,3525790082239104371118456157894419087904422095178764587616607951352330724979,5534817540911273750657456222142677256882873311813581893871590176089715612985,1615881228089658726040568147025008122728572958650432110106281742560315865517,1471725164982594409495579793735446246197281099521356897919523009694047660159,1375309198078109412495220212570536673190607625762682203229827372752214429058,19114911117517497826908513598723039822664580418797141695087511229965144677908,9628666313906709051161166309431160628627430386029173286325286404453712266410,21852518218578549606473925058864730694915463701150591631085298334480610743316,12775432117186202301959614842766511797651599815903402927721712100175714308106,139892473068642488659633517109052420816080027074176062905422560867217142259,8678567564479314009205848092936065091488089332028298130303782323700697895584,11749646464324896227459490085151303579078783519261033148424203540751860385879,20522934943803615109303532925965718163549240564060985032796290524829499285217,20661244899066232726889114470941159662948096319289349895724712936883638757146,1712076112157842791409364964341168524175271666408017461435914200921357859979,5274198338007371549113715286886410970476178374473353058525495747031417868052,6737897812641394021946938592351495323837784050553060267876717564065727066209,7802413308864463219891658906834234180067201307743855789866460725804890591074,10598878996622948168711729113266592565050867869138946404948068606726933771770,8999501853368885436259381006393167420075229434053961224100936590306072807402,10154159140828416502096070052350440839365634698281866510618130671547713671046,10116420503162714112005525549243891887026278400783073704446798028762825422117,5545266571933610687233921232979606259360579780771113897229483385986421780729,21233107093610116862049125654360754386798111684938073821049243264439651570366,5307392033140435516838295705521564813869712246929667484768640666687057034707,21375317482759736213193607973501605926935171024163842355374965533706641104549,2517892809920213533018018674089754443879541674948230773132283920676903837393,14360345633113115894388501084706102426582517876835778852281477705852716869669,17053269301717416242405268053150416723822210193991005718303172171427452536837,9906602428995106334942925928993621430906117671319208771657883136890126991982,10354603022009709342018106446249264303223237761462844795940043835225457441783,13398916116699661698644750814188836272580610770712272177556442659081018605804,3191149493139822128538617654520106298782669019011287540692938944153323592958,4691984423256762483396977170887219469164634656601998705889064679728271695271,17844101314007938193168524989091446035911779338131517299817551328197378135054,635635940269936042377013194809642013073936660346940411744079076043939544740,12630888356903717277892931534313436641457206712723665520324533786104375264085,14140466574121870700874387789856251566070511990708575066948924661369491559256,20370174501238434846223710470633284656345430614321812270231526837854520663574,654339196866659831266130941576738975707930915283825590200406138066808189370,5107706503321722709363385752813500904785775244074262870879244969961234309572,12198789333458214522406820255828653820578540569170284513887146039452722146485,16249136895399135618027043741098607972773831911496869243661084436243711109565,11074204104909151859533339603597929732173550047640253831218390211736882449440,17207343273400097590016935219508528858538698779767314862863101225959250875891,21262587236682681589242692923329018584317630804742733118429592061667487058638,2280753183511690306986430331340197673251265546818209861935234085004534230414,10254003274920664842497725816382563578440196723429688051808776569200020879745,7759959068226022198572347902743272598191759849179433231578496544131111538092,14214316923200364820492127575076874888948881174491573576707716667988807435892,9095544195644789922175839073929462149959586189940443682544660563790242551416,12649782796197868227327830841571149621604197483943737926454728454326532192518,16667983042241619901264223140344714132852698906756725392221839503187142280785,18383173644675687530390651274503384113459403614974472825953064896216388971884,14628141534803375030737634780152921077373561843078668533631869027351905379871,4561456211241649459019745200365185624320798675863426759321227045069329801664,12289778497980320566229781933786841623485008232338420865642173363101571189872,11975067175623680843959076988032062157059134808170430074549557650028254491562,13608090049838182253377471459358669610089588259298499702848843266957511619603,18788677463812827554544269966162484344784391485047475243938219549074331613206,4881667965195655156201239071358064948072146968570883219541497388280721871638,16809375763554448903183355905513828131657823301396908506126469252462160193891,11654980193951434743713680917141406309927211470940308818720103124789012440740,5948986090649283108120495678646398398833638108013243775975352725637369743753,13726437662355203524944601292802877111764435687388166013301616156301223567122,17457684154769676997584569814978347304006793119360850469355899127743508915640,12768218426713967613672155360932690915682228245638743313771591055379281067565,18615157783057763780308448635283319685644271696762198401466573335150909781420,17036103965935103170115214353570299052411478859579659720326549902160146217969,7150547909167136034355368387927463942994048322819447869013206336674786486676,2719491185384365067577935615529406253538979948934035375021293885648964670289,855254098406697810192507782360318218871612459371212156821698546331701832542,17895542168549626634871327801987932137768300191314912757298899767762396172426,1291731410872228901975204398582554998148747251553901848273154130903421546804,11405841699040163552814729751623598889450140001218648787184675782417123019196,20354628821067577915648505449000078769730992376974982139779446148223962828730,10728669080369994464716817080074001337835696213713101955141340296929303809038,12274798389677182426524706446934567986140214102647161938159083665963012760572,9739537323825422719175243872981907235223292084323462340852187679763167385510,6755543715589769777862111458854566169790920787355600259792850662088606657716,12126305553295538434422174339664597983843351746744739132557070380077267264590,21398878068159838390422213444802849205194012142590812651530393856342428295355,2774987220129009778448086748836270418387857350731020745311729965596748575420,12913355749231079157637607439722332211156795881932799993926379679617800720875,14002442102691266344434178456827064608589741346471232083579257521903268988567,3222000382376546717389770889292702303294866053055569943089969635516575396692,3351662579522271904655802780809448930926900026265684873057471441126697202347,8791346592452796050710862947776730913908702488104309880248248201823569029744,9103312554290751080966931020955359921020213554904162168782078094097630022273,11400762474859869669799163954742952133400547669811496311736883651700759825519,21705862854411927719091657128107442151318579935925212397760983799549487960024,43293469326476059594440269130071583321324378720711508957751360314337673988,15189563636069530033236842376689049504908622054060814965474910283072587672143,8828581874201341688220445093730125081012615712886123840297097551587278948881,4848334665131642773713411076824550175891079883511516252808850475348208758729,12614662329834759430739626588497950629642362637723265950380896878486239042155,14266355110863104530316810105072189601641436180167942829728212140901379263956,17294822327168915058983104150822364346325840621309612804535067234675456850670,455077676048323303580854786776522812365753723694705688462762996845811407009,1883008531326217838820507370543781882290544271112198177704053499351851681273,4529982458238957976485223202768823175919650810452913863593242825418350872543,2955110035783314707155321084983433537364088072013879095266124577362993635626,12967684942790110900749491528799008728014372120122130310632754743394775825471,2505175694719163834796124853767853797404065196427012487113935936321224863546,3664644243909527501109080877083112285282350623935581596506736195569817810680,13149615309511991949247749473495035486060198385636687198656459619774102038819,11675634552285986901460163850174089221624080337542386824203554725353862698973,13792241875469760333807839408609766753472484847219134966123237707758891089388,10227619387285566606296112062328719372414665296090743089679008143127205545123,12205580044090621048077686897527020579927082420674484835775119696613313405371,15208177648579495968812696435767989756568450150931633443711377393141060828911,6203604398339912597796330237774861234098507297133105016255969208311447220376,8763991852009928642943035844463232737815423121200913107779495834216057423172,94997075732443240393502290740081268967228130793200255689370554790238240979,5269706528648934838705302424114829386876854870088873864481541735257304941866,16262872163060208420029150392453401749302720607531142669546071916932112668551,8143677473154806611855981628530143157024134934286519271401846470427527147543,11345763412284980808950171535310000445785575947246043879446971501610507015402,11334003190684962190461352102674801284421167648666972792173808801060633658405,16679481501466111466382494296272414977838924060754574747550155015005991797168,8717276046214261706367755700328685033217888501922395351508483646143935055357,7961818553714372394804939036958306706260485011393197807672306728909086465660,11525513262393719593247460022637862437588876074380005892794471847411833011017,606475753731577839300896422047168640216288859417610094202862133247546805011,16216814510391154599441870283663624434960433363418315765904453229709017881340,15952802892860522124812654660125132147349553268606042022775941410073735145502,21186206422036180717988803903908106965745591204944021637150186904241796046981,6944713991333056327587649834988524981544213700413795245346955488518554424877,10185921515443194095530439914620341794217076478391514698779175769548747359464,2855919726997577698604215361496800379220625688194012864111223639042676660976,10433229026112136773123800168383892031427061365180473556460194903407247351339,19427072191035469870347195569940358526740232693667547123354147821192789102650,15644214414239800285411872105206002044880495869535621299007907341206661859610,17127893436675976263942308327239908450163069123121279064123261885014993455970,14398850115453023364458586202624524741971410970483408578015632196929131043640,2352925542671141920909613532344506652984644250240272091365991738093178607788,10172679680316429884824619312723045840067903978738893283037233244389430249509,5772194565812391639885669321239603226420464592665765672957012371288977540856,1472565977275775489403659554782408548523807638115405629626295474159727078930,13025952383827165156872004962772766979272981810832459552230024272976389350529,17564758020035152957739819749712385631015761969283204715352893305611222727560,16405514590762165467156068648660873304776064039873164250553927264160414855875,3690038285204558326066250230248548873947936562327070117434442040765096220855,17531140782998595396669833094850381400841695523035934903128529012616296113949,13168227885444297954910232183764567700890648537512256626187184942939569199780,18839532764289221356950914594613087164434882227921649252297932780104554074257,15690093187279544523035828189537219904387587938956853550130942856247262425989,4880718242480815050016604653617276367751146942554754727539176934739417585000,5767740184065294852679113060036925102298292735253600173647375101014669432601,15274885987576180935369267696345371924274924872703997373047266442038483500100,3761934589481780435501384301483991135823312027596840500386086136996196777919,17076314579416028845718050745024649043011795764818118471181221546277962595385,15977291426665432194805519962451891500931039499992781917651419845757747435870,16614058019242709692964725060926415535596693985378737640811775269245183858531,1462290731020299561638622134991867491216642860791478796650694102212515942203,15285513431606451603488599544624561225569394909979737124945690710031449859251,2108108609418057784389651014871434275919186190456064517027979476451544519949,20785453923508177251995968212118965193411372702846000862603422090322205734041,10673883530097564269607463521683039178512337022363698173454334902283390457863,5454676180617583613153450533396644120109614173104204009158828769649771925347,2308424025465899393970422846699273218513861797562089060060302466408498727592,7521209677407171946300925747807233725946342430543358547121236461545495788103,20573024021944297233730031260403312250074182051596062256738574515403295322803,9021049816696497696749267473705619787233696328020950183323376943545740004437,1865524799085825018345305851095200435959748376626055576269783687778950437080,4246459257342056987998012962024687622955192847494871592608632692951161262129,19427245695591302750338395658196139112041609989862338102918570832807123117503,21526088318229932910068935959652342185575362039375447361171773752278498069664,16191911454644420751852228901282854304136684923356871310294001321086062307024,19158667047991453406718020435447139785846629820299132383267410641682384370576,17700355947456307421977232728703295781949761612179494776757369350093380226828,4397993077875324081650432554749300545148338322818494126385494799541152486594,7333345984549245920976934899658584162392463672999208699449239323807521633803,16152786000399924760932165522677937364378936868710087711558780050692283598645,11094138063712503930108269043784479707229515809275605844595768164840752472377,1142389644011176261530925136868504263430131536560167284105696375014595703389,7947253178759456244011070491140902256859556283134055577001208685178146652802,10134714213573683528928794197545260748403530346308318902760067810116839777206,10883490621674448000789965625707254871804535943755669299023415555830424281655,3066669045698349285650257964282463204141692000014900401186330770537030238642,20081606580658665084706560391544166403289461596409550084066896490552960642479,6155695406737593769799569079058291297835886186017961489006277167996716002247,8515542419918302650566740947332213674125125387478669670818010011334680546574,20110138544602147391149732696810223660265845787019234225223667638537351747051,10742562600839811890186721654855708402836531506887842079602293928208078373859,1525909842404376057305890458989201366856740974115647536551418424527131666169,9234236770964972467234889051483942687447344616202849085905582739078803045160,2606008597707158849245186414604531348516676367660138989733829835914698874012,11796760152309688912186437926169763667717914107947289133346750725444306914631,3851377590989618761627509080069107348568977801140383151662774695134986557597,3154796336225549288800236024241376487736097402096695364582935878596928093781,5510420220665221034838403251084456079592641926247054056939582862556776533398,16879696361470925506825934570612427394067380616879319126544582610342257894977,17284649816450637986813517327310560148892948427878914253815654865007623581799,2833030338755501226260678429168722114253235114087325082893557705288230185302,7251727070132476220556183457711849452579027647540936257172964240637390843337,9575600794079237337218029036087316899348403790684983148717343996829930177678,5979306342004680208572077566967420789575741134560343288662733429960668391430,6933647198431187357226909706624729057428619440859131169201765838043283476077,19168763196217781731628598897969332495895458624888700544934409934147951462602,19829437720109810470479999873902618673477593710269745617035524777507262876935,10801527657674630131387061424571233632050383122132208702068470808513632048030,3324631869609728132956796851449123815871495758162118183753705724979320742705,15660020223439851550062020388305149722004313049334322631321250103301499692604,5967221174170233933880215190156392465136752773253659731223749128915793467895,11552412840249358443126681313794466948899653896063684296070673264241626555196,18888906666917921069717332466525186303442592625253328171173131193932302764004,9002714106167484391528827546180572105064179104525774089102236612700713696717,11048302793662652213631623254022096575352405761944396370134943300004028917865,16407259962762436968310192538354523615684343650696199890141991953040162326636,2164382359471710099213275616027528225843146809226250465653585796261822737346,10534211142437421383941598776341383955315039281979396571221999789915575101599,10666069653734320813631520107249402109728041265475244772290972049841823847727,1065893272480854115563003062650162503958098706206084024581187831004515125777,7996693710845330472615496754914137367924796497947601638820266498225398515015,779460584637732468426955849206233546264346430125102128427414524469939157403,18123487244613769854380966736011971128129435530397043581264858565849669710522,16483639590865705054952634993109499660754781472434181022666579985294889582777,15847717171578788545161470441065692492419364914649476971042627117577578420712,20212509548766945890162316166677458350544092615956421310024681889193656903241,11915838540527285091679839305488591026042934314354878896592571753630253407873,1911170159637126384084881836969666801716554202345435461162520643252230842951,2519681707616189243873692429706701363981726227724944939887394039132311807155,10525548620009931418869190498282964825273460634626042574365806552478535675090,1007287689974936217568163398662729361983046876939574893360458678319961439943,8918601076290071318953673276836220960249911431394510238963515695083601259416,1730552670090087588255812224149698933189694835321291448382024953001539943933,2692212389857059051251821082045515561682372012597270034725442717100828072430,5182752960118030069130081328243349382982053565156074602369672154634481788415,4186223293158399083027342405464955373429347225209836842209182753945871255191,20698226478040525601636369286446332773903307913544069889209490555501069209140,7848961029873906562639009619165977234892385836769337804546327846501965814365,13921935366749820642106107225856381492084238464963488385755265898574906919842,16615913254044390064369275838835406299949293202833109553557777908673881552518,17884323890135880903838623664692905800576770771455839982202688346472867240539,7671240599961467753478651569648667266853727017714987691902517051845809028276,20540170969725852651721054123169504183251616229771312133024479630289328600435,10885911618876068300178014171685162848957603467763239389113505729594133953822,1821956738503711086168534921235313501143676686594517809385967874500584768914,13900019517803309945097308036151373598859036005433194049333364013307418921490,5611521340578197244418404931199594069340846248086844299279812110836336410894,3871676825880602831129014665958446397148564007925285835033897270539554583982,8660883522091722908446182204212531338997991855689061026827047565345925404852,21369377758054514487929500216341215576252815582773920801000959327560535036910,2412441365534353741053138780929948381707801794421791967644299920632399699760,3962365750665624098182798369136001622041855947680873409890054621414139629589,15001230629104674518532645948322038846835064889071294141298776340346988584355,14880674002301694876681052915629907300219131310128131182663986425102259721980,1824158054562585980316309768551123828629842232225429989383412402628330419987,2859240361399565691265380107352020662064288346296545444794991049234114013603,5166447910779952920543762328108096228333459621541947567522578212254733957716,1007490453560275100906582245944853446313521002614529198832736321283620962455,12357031909288499920427512282658173574064133416008366625033457013843709684703,4908601693798278768903637729333835430381717019653632816739154645536641464365,3707521788266753982537350852704241176639571081938875735935799519005785641932,843648473424733414090549470297108007717585086811320449394192229155836735429,15745469357122732280411707850429686485179261034785562466267026969795211925342,10805521614324416411410037641243182724170403739698507241460822321812492198235,12065996971764501469604703952781437881524721789450462435182323617647626062291,18470487586372818033539023969236693307855263683332928699228943202064060965843,9678881733477238994400069917737562227773718359505757479334487914298656155782,14188770590313091787681039051598250350716760439974403531322107017294575035366,1689506610383677575502055715917181866056070036146379850885318902788859831848,7506643906911078844726412866492372822643011138706243954480387034094577464841,8878900588521598109866546176968107824348718386295453778616479348498221694856,6870283245627392817090238076492510507322368840526195161203457308149059064709,13770891113056770539767147807436112954402870897635701688432832537357791153049,8780360192411651104527843471573635887257900701816701590232913021169255451999,16171874311798197525909736376097249943669070404511356154621097034937309906406,5735048971584791925371366175024708991668126697294479025115320761565490442773,13229825087263355390945471875664433936256658682181329545626347347763439801377,7075776235062840728475772028477434335481293337646194082436681309306082067951,3621624535897102185304108550400513064448572525424419762329290603569136345699,8909048763816678806291702062491546272181098732106818908949274412295033032278,5679617488269393681126385387791795896201443046828191787132461584904242222704,10105279386430545635207898937992374339634464824905552041741267814807859103503,1875089455725008938828188584567435691926878726057441578850433616115151436992,7477746898926143788312536189451854889707733370802231032871868774692083118085,16386910598448767875426039948412876247096832715449382492730559004257126956048,6033432876275593677037331179852069653085950234927263672572175689211500790655,791047936106933006999775822964245334290371384592876255418502363688874468612,3694863804142244539430013086697918876101028434198177049748051320963196192691,13376682105243214738309576815193178135837123827716063891638620885853287922296,13805679067029770984721773402288418271927678860935425166689344094492548637057,17136756160106085935819446871311843510549583818138636089816199715569134828084,8109923439508142364330425377154151984256104223553589804214354752109994937475,11286249512402084538299269911568404171399278286810916548813396237061620605376,2584359677745194465235893977254941998996461095474372764450843406506578038395,416048929518775256195106483480946138344969950953407172345234478269849793039,13382468529403508085121262401866099849753365548098731797553497976873204205709,18439376867491626480684697800985907843592103465829293677253579863338320195923,17849262151524731521717998935547978553691621192854239431428238124396600612632,14944765584636478787586231666077419063063746476683640145827104348311750508175,5770158920816863002535760768793204546036568907423666489027939717423021627834,8964766646616906071571735802649575322546984330618572612076303377141821583837,12741361066585979303854420163873489016934487106922559130204774618881492938249,17155650977068989655844853330647332708031817408933941319367040661444377002549,15853135222927269109853709968587618568449580274775781838704992776508260190624,18643405831130205120436044797258461126994691116505008303058249039104682298143,18381699905134802759607923737176411134148483921733890751508148644565049938661,20771413818150322305462626795715653983446198751749952090107489229813229842550,6565230743597462418756949526565014729968376635326046194605417268756666319845,7773589221172310936780704579925742277511016906417542067089964629576305572209,14322739515259154048217383149571029180760938501429981700631245079741667837826,2211777926093208827662641428669122029599076421656786665814449320380720581777,11959359909854207341226535525210590494408522984553921513181278512110987087969,15631964544474412103208297614910610111786652867610037534463100143218625118186,6469947677147265061709088012775208497425320831040679910475868641704170242154,14273192286218513903657400373354426033843730885130815917604222619132646117025,1642305946822726119533692746690241550779067996073465721872854402290979482744,12434472654594642340204970901697561562492434882039006954954548364905225683590,18258333676501263903599077497799178704676070138517903780843551776313851126197,3154393734777301102615783657097778679162307608952237328943250741895135803910,21442924273325571860480847088112128477994226721014369494483203254968684948447,12633492209679682779165226815843032818326050497846354378961630197925565487104,5676035885913185017175294353150288993325590895201150557890586619719458353554,7971989338965840486933559372839713095797443968865735128939127037392334228821,21734085994605079916025200907658739534755548178328895704833631044593482792710,2240615781815075893018901266381250882106533308854256044823388761533658366337,19418757086351270137870941178188715468785231202435740939860626745964359442005,17658978545567285097910442499706845586224912649469751675828983048696346031860,5266889563561183172939683250833485521316204021724495164611029326138684723583,11128996685041402949333841527417312168812141699419947558499636572258705639448,4876070090528783965375514438749842173086453529590096369168455769565070437109,21181864929467364713132566956143162901336986129207766576689052262132856884478,6923705508410326350945166370499325965219890886201185955752583121521122421736,21369826512764035509040463750392604795868027299873193291279213169276615858803,4704097774288345414783119239472343512761071550401447208590340029300816575296,19335571041256357691347835994830129551703141581491004773597606130380555930148,13594634273515260829141229000646270213542265375428591690952060475706589483636,9015254066149037983117828022107604427546915195306105494160093361353622246415,4212072016320343773172520900223699632828574585381041109390033407447488634385,1102272748190005338904701274717935307889530536456982005034282115032583335111,2736300324710728232038909644774832551915915663932530690557461126955645530086,4835822801818378290852301048163831283974282641105089345434084063764482095069,8984658187927452678459930452346646248663512083082894198317485712426204609811,16633394668571656740012069555016467267297836103775110968049070854163114237249,19001311544890254637467757524866604779430904938238046630395635640108752440416,1519708912837962563938791348422981399413816048437970967955664087668434079252,21331841844372791543710397499630585987940452814579176990050363535517182938392,8907423080053260966677751803467685389883909962381980865910698188903614425511,20461083176034684313938738010980183835826228331514122093950995340802162488751,5841016603634386755712428070725428370463826644379529834480138063613116133165,6169966163271811065481708286709332934104602048421028222790926506913444959185,11123503881380576416779399092503011764979780788355198614717104650873109848686,5910862578643213547409014086432565110080048906429291885019036113399453987536,15326247930625028665035962093121096584742207235393215425729927190450227004180,11869108106148533163877422279522558694860624980410176225979111384418155447592,11642189959177792725300751489041811935498998846917246538427709581655066866054,17383982459896791073091103411713034950019457760840905433100761135071197717377,12914884881288305014413720371780941499071473169305332026567402160980899728234,1208570539962036907751277903184876797538221568150857585830629441131315144451,2323312703274674937703540014228631818729280611690694743543061204714949346767,17526158529185414889134597474769916490357130956125485429641429836800727655323,16037781653504828212828867735133494813590828457250361954137565662868257318996,5407222038113928707955890035984954296613370389143420455278606330416003035740,6601323218218927237946555844476405370566012808107313139506360075146521702852,21534867504549849931394770956914633425223988570769925897030241609788158519056,11391084204734238133980784274225569005339670690396227409155789097373857915450,19888681657658973285687297761078939800531741094128408699392512189997402853670,5332577406232753436405602237019361733171667669604896195130680826397119398314,9059600173937645065621009092166260440988612068018047518892978276246308722168,5301647598491778367767843695092267888185214608095464352349739315757388259345,15071875841892141860455823800612444188659593796102096590428526661356131692597,435778089283152858387915635050172265804266241934673566488879021420875384052,7253178577349028822394834490127746885621571949621301778647260365262978601526,1165301643600280009322317413038719889346104283514223548696059636052018656756,19642265897347119192967952847445594557926149874981543320111550169192389374838,18546070171142820328487316603855788669722411491547154393382552167546945234264,7547722208697813989490512139624144757215998986985181672151192221427497361833,21765466939205480830726051696775103538365853268148356693813986094780619132689,18066916718526031105430041386116904278122614509807635157495047212689329422097,5567247965934318360602471432895130358745239227464728512128895794990091560111,5268155242325913085615961568740884974081158441192412337454790453319219641639,15275184776514682919662155241139211655693258637032715569152004434925162363584,2179932316974455074499483491372661376888522799119184614149917286749483028849,4621405833740121725678441855520519041228014222881228746009997774516764304847,18479339496682302897017710580780845640172065272400836860950352488372424120096,18557033214894447033261016367420154444088029564584596463030003672186270737859,17200647521217215683722635843299601233863161230648748208816378327209201596867,2688200399163263049122461117289599907708945179806531635658550456745433215543,17415923022624960613510570384321832458760537169605919976471719634183381965151,8535568676654346647569376193583594529721160524940659464514765031328360321359,2988350233499987577118772810582267364198360724494195915351933486792072227259,6210620559937378902878629998722853418159056595764204463986805098114518009318,18310997638100731876764014221687199913435941820864752235028122857262977059320,13808863093029019329144013239638801163784179422135484562563156294580677444841,12914098780625672320372746314998075565042263956380764233047047668841824625393,3305953095296069725576430940963322680842934544212876613078125492458854044556,17822002370183286453254419050088898676184956527990121400547957986510775899261,14649614548507754711891632411080554775651572143141206447218484052001553765684,8109105787614676314388565737575005920261787167569229710081822989465469152070,10883787415840547710621559198296269932318487849486120162467244238276174398529,19330421887539219495728995383446553835046303504116353064676615752269857951508,10124601385542856860656799235536724683363368315551234368605365576161456958605,12586681054057195636996904714881904902720157016325364273875514276164279959735,3757165144866249284026269096089043031459271594379869902321741804365836799544,462405354647627586345675602760959074379157140949064478801734872040710235207,1920260561025181767428737283255569518557618670101985233779064285550376374001,16427781514757709627041602025461703818581117100125480080881962557048804215419,11285710669637766333985664845741699850953316015510407645702772350620723934913,12651159368793078896654108663982020308442449053255003548814357252262150375808,5416603170144910655254279621683623582654125103494176617805338836184837812634,11735378404903665808621855768545179642393017572035737886573368447383433091210,12201557541429330882554855185927797569372240536806738921957792139394552229540,12315234857861194987612137097457466405047598720463755079786381945885951345726], - [5029285279710800539227619495938136407778783814400587102957398897867261120664,21661833903534656620291231766157513264428291380933208423519374035927473262119,21013170147855726227668315492699186959893088673047129690411646575996043835024,15893628062504267735591398483514002406192781085288489283447316241330749546879,9860639032243003377544947110034203265885715041305770375052648470285182020229,10431760628292478929366440566994655480900443273305000842144090945543100651218,4662341343242273661833461144031815716144681076466659112993661636426666579986,6674279191498784183427663914511569570797862586816649467168170855788360268943,16895097041920841073767278653214275321407577186751547609698446652984399225877,8168606076413192332279322347673356872630772122089948509553934257426773045038,12091567755121016869657080116466607855522522017768906776539212195551888602502,4684576201081771194613696765517034834984066296253124029929753160055156611363,16693488266039456124835102259365515976900969074532557489095946797080826193662,7638443036775258881709317582832080783911189229963788890221615286494482929025,10111436214822932149781668218956845833675824936886829015449750181332010388640,896682691957564465177669890535917423987915406885797833670239687119295318467,12612639059115228106858238115822505521432423470330120640591982767272085175034,1851711744209473345586117150836616408053748535684022739058625441026889320297,14132260688735080257390420980422269734275443926576061985351678038992087770902,487493866037948515547037886552479973316400139387425953088274857424154262588,7712516772901240105339429973116360243232161870164307482409826131312962380842,20295556720945067049585659016570679551265845058805648954004989969704769135170,378208946912325140295069471345064814132951473534378635003955801655986417900,15111601008893945567629460471315838423301021468457758533702272669431620017222,1503682435556321218669089857094247703956565058167121192612334331910088441071,13084874799693933186811120569396911285611047490876409383659779579088985591229,17464483161247836988344436558341194021876261750085348252730901647076441211862,6628743087463083391707355927377412170189936607932592258517748766250528223430,15153763588458144568353947674975114179172744555450771328418442212716084083525,11217853102739260248713425002157925483291370125178251466195670948291389406199,11275485266433075885440484136400353724892671196084163231314370685019444807048,20167106354875398113371399754994549089359568833089630824992752829251678891797,14151330869211746069130604993916224881047448810615413435448712767752320095045,17260356243574396880210370581740651566334589568095587416844511054569255137183,12436078462666286197074526218535647721230687376129721353230123441759960021666,12001627458343654011606323250787666795709808266974343548842843520227918922255,15944850302839498288636342399223012131590208876255723227505947857641523034493,8444103924869263585176528654612076203716402818569041992813095331662367021655,13015682914180762871967848617514355587762125694235380084430680565032083402270,16200183380426364054409550129683752323493215428097334915015688753327665325485,13717643109958965551675619584464549580820722892266661529182798599670194908199,19801725181447377274232761944437523251067599053402428862557912155522673980500,8260354277364856843022982286494019620277496829494935775254726797533957063267,124621144162335766862972192337737579448571172779117809776129849377329817478,16488884047551411705397223604196364132975353217876182634038895586664127388979,17336432076451490238716890901095007360946878388179175784603587179384718443321,1210338460555723584699132156502555539583432069430631008706741082485009017102,5933432012048351362807861976737945204535374770355507745694008880123055490802,5127952499969178010015035020598142881788437616516517827214405489972695632240,21100924218139544842807404598627913291698574448527131003096325470925085906016,7683521602764604419863026286445694988900727173175219514555132623764360793654,20928394065137007852706990901925870323120588543710137320004640014111073449000,21375535333469484792161302750563386607223088895810564711097025913956371171769,8663517227154706072248636076587789834246541965140682871530851124960776424787,9182938389356039217318590654716613493414550996824701664670650439783557720226,8327338979442122743919832154397496089418582414082199116629974300650113777515,2474727241701323049333019668054716886184808783449917153147248751503852312804,8543922237501430855864877057711792269479294116675004771113148647309219620030,7863611214303285947093025404346084345102544167615769255495752297507346719791,1448902069752048144992778676670381235906144579949631101518897035253311063307,19501657783346989621892787238946890715709847672294934508902622542828235185048,17076525025777667838921778388186176564387475624769926249793144074465528465933,2381176586418291387279201678056498732033435079507661703992537801751492053086,20723508866659831749949206314442193102431573526415976696387848305764994281574,17461795780729443663350296040956479984433953861306521086706732257263430387445,14849025218838139413138931958408289986915143240245452275066866730847749323920,21207204042106390965753782189145584243052148578812105334769740484186308017901,3105302592226642624386332562899903659948819667537402316192380465808886843623,8765266846991616382097124552983206033439769882065573909634090515268812396114,9950016446092650730639179912416912603745831292536616469358668786853463197224,11739731747351277092817771330729393674312591071236310446088293450266807414263,5424991773995591044103668717299468589013142114099340604018933512575789323446,14582885509715812510585748465607279869582209618804039923778041514988867577359,12468934763690970929325823037406509081405444759649987929912706732364016057892,2792793293657306144108993077959195845478902430027171873963281969527327256602,8841327809851437433386666692145437950603022633472031964220924157605803799391,7845859360796082275932181771457755704129556353505380746504571839006944723429,10731793207832149137187382442869034250153492853628224932026933458041993639295,5597792614864287090861003890414825257635680048696075527563498604714157576447,2638669099010916296300870639816763122907432841565512299246441500223692345671,7150832464835357604208338666096132398994318721877322228060899549998179405057,5470477812928960639347760417261508685840724903499112719517942324191018679706,1063854480993555660259858748055514950231824974684462401269695511649059715242,14508243449586598349750829047481358081191713699373322296041764577478835760927,14872220983064543437506211589956319796231014912750035729896461676577407407598,9523202653584689553554068772241228948237208444616905879849472383190180438058,10557133197819890801524243760013157188954914093770589635201319240903423455316,4973822148190287060777561091733583032026446820262414806412485028147721872972,12017319043066808147670914562193696608548297038020764496633388575589573229927,20958507279974171556413354796214800332148109902768069171659933168603089927180,16142225389165963605704721785850680620029805525816101628767304750729950332962,21691255103889531967215183091383836488808797368461467004501598817850515277674,13360009791215314413428942977255018953699328534302248245107197249816193370823,5270206696221786165451075835596925139630328202641350960582852969440862939023,2626561181956261201864606929566987806068271006198808163435823619705436605447,5520368836328496672510351296660387187466158872913871354651108826881774455909,21597143280250120305740582323272730661347349587666707484376745221123282421748,5891209530846741397700015863630938364586207627850850447237189083999656313978,1202436381171550812585103405636986166232789491390007497511342220946215395818,9920320882147650877649039705433660083926352954797066179512349368247190410310] + [ + 0xe1962c232fd0a6bb54ad8962a82b9838cfef19d290a55fc49d6debd061cd2f6, + 0x1e1f45cff3e74168accd0a94536fca6317128953eb47d8d2d79b847b355cf51, + 0x1367eec3b20cb74953618fd9261047755ef7f8aae5ffe96fc8f7d9a02e37bd1a, + 0x2ff6ad40533afa2acb78c9b91650d7ccbd274b09f78c100479f3a4d72956d706, + 0x152c8c3d9e43d90ad8094831a74af8151fdcda0b18d7bd8374ffda68d1a5fc71, + 0x241707db26f96df502364d26712c7f465d0ac5597a309559b075406351a20977, + 0x15a4e4728a197dae6303d0cdd2b6d1e4114a9fad38a530bca6fd06ca1ffc1f56, + 0xcbfd63f363978c387d656e93f11e336987a68748c8f54f385887e64b1075598, + 0x1fb594474b8334f9aea6fe5e323fb0e0ac27d2895921ac64e93e524e4ffd25c4, + 0x5ac55361da931c1b4c560aa8dbabc8624ba225871bce224addb5af901676aeb, + 0xe7266f909395b5d42ec298ad3eb73f6c11149f491164f997ea76b64282b9af5, + 0x1d928ce916ec0178a2c0d8a890af90468c8af68c4c128c68f042cad51c6d7895, + 0x11521e378f229844263410fe44628fca9ffad17eae9965dee900ef14a4d2d6d2, + 0x23f3ea3b55ad3710a0052d7a4b9c9a65456ef71bc4eb16c1e908034b3cd3b2d0, + 0xd4f972e795bbca8623bb08503764a90e4384be644f57b4a56f1e7e1548922bf, + 0x2a53e60ecb9c00dd99692d57d7a54d893934468203995267e83954859d21b595, + 0x18583bb0a83ad2e710369475bd54ae1d821d75a9e1e870df11c154f41be1a632, + 0xd45688dc986f78e71c463b76ed2c056881c76dc552ccf8d3a1d795d7682efb2, + 0x1448256830ab79d2618c6ebc5af5624fd064e2a16194e5a0c35c76fcb094d371, + 0xc0c7912bf67c273baae265c68f378a3fc06eed7778ba6ad3181428bd55a148a, + 0x900cfc715edb109d3e6c02b7a578326f57efeb3da6f58e64792dca3452a55f9, + 0xb84b851d9d0d621eb2872fd75b848ad6a905911a988b46a3d0d70d264c8790a, + 0x69b8105bc60bee13097c0fb14d05a1b932d37db703f6ff557675bfbbda8a5b0, + 0xa0ad082a6226840334524022e1d3c7168423449df9c2ffcb44cd9d4d2302325, + 0x18c350500a7bb9fecc04b286ee0ebe76cf71281b4463dbbcf8e266221817d32c, + 0x2da317c459c0b0d973e04bcca9c112726c7618ce9760c2228c308b7433d907a0, + 0x232a07d1aef79c1113e3ffe7094ac379cd67c41981b9dbd30dc691eddeddbc6f, + 0x6f8ebb8cb046c0aa7ea795744cefbc827e5727dd16d0f27675d99f8964492ca, + 0x10db78837d0652586afa0666b721e1c94180173183300992c4602c8c1c415478, + 0x12f5fb7778fb2b8e1b5ec306d3d8f2a497ee4e9aa5bf1924a694d04cadd5c526, + 0xf6a94bf66121d5993932988636d0aa2479e0299aff2cea5b7efc311a15007d, + 0x18b818a1c250d6f8b77870c1ef5942250214655460e4b5aa09c8066489041732, + 0xd25185fdb4a3c65e05963b80310584f2a6069c2c0b07ab2b6df2d04bea0f52a, + 0x63666f719c9dacd3ff39599926802bd9e07c61050b10ee79adf0da04c59e8e2, + 0x25f9e2e4766cf4b7bf91a63f7dbe954b2ffa4cee7269933134b5309eaf9d702e, + 0x1237a2bfe7efc853fc4e9c4fb84d8e7c56b125286d8bc81a5434c6d8737206d3, + 0x149b17921a60f02551a03ebdd0a3a71f7048d0f9f47893075c625341ae06159, + 0x21e129ee052da457e94cbdc1ac5738ab300aabb76a3cc3c23637cb6221874630, + 0xffbccf818cccf47beddf8558b8242c90e41fb603f137b02f0774228d6978d94, + 0x13018c64072bda036ce65310501ef57816d397a9eba56f87b56024bac5ebe9e6, + 0x1b009f2e8abc03f498fdb84857c2091bbb0095778f990fe799d0f2c97e2c2670, + 0x101546fdb71f32991c1180cc07eaecf47920cd0704691e555b3bc44de5c5289f, + 0x1d1f66a2ec0621f229c3f8cc7b153683d993e220ec5a1f01d42a14db46a785c7, + 0xc0d0d8c79f76f62eb8ea785853ee6aeaac59256172a14479d34101dc8e63ad0, + 0xa3f038a5f37073c1ea7a4edfc1dcb60859c1218e1fb611ba59dd245399c9572, + 0xb7e89abaf697afea2ab793f7cbc3e807dba45231d4fbe6b657a95f03f1b1705, + 0x91c47a22bfbe8cc067f70019ea1a2eaa9b381fdf90ffa8971b247812b977f6c, + 0x23502619e347553b5bbd886ba0ebaf4b63c07c289da07b0c7728fbd6092241d1, + 0x2f5d5281749be90119354e751ea126e578ccc43a4c372d67ae66d87c0c01336b, + 0x1ce6855b5db80c42971cc52c9c35275e8bfc7705684a391bce4151ad9fcd9be7, + 0x4f03f23505d6e117603510ef25bf46de44b95506011b5642b120b76c4a7a277, + 0x2f0f36a6ecd8f53af95b4b9514997ae0a208d89e974bd3359dd98fe2e2b3d41, + 0x1cf3c4ff9ab589d0a5660b86b5fdf8f38ec3ca5e92c445bd4cfbe6c70de64929, + 0xd907e14510611fc14612e406616cfcc0b3b1258278d802a5a3d7dd785284e63, + 0x148575fd984cf84d0f3dbb49564b397c17ac817e6ffe348881321ce76e35c44, + 0x13c32c26889cbbfaaf4d1f25e64bcb720e1cca45312f90fbdea8435d9e6729af, + 0x2f28f702d684198114e721efafb6922c3a42dd08fbb1fd6831902df4b55a6a96, + 0x5fd91ec054800f61ee128bbcbe332ec4c4eb25bc57781c436c931d5a44b6367, + 0x2a07137e0211d40057d39d707b177cb576f3399b29b9a7019c3dfc7d7a22d27c, + 0x1b9592c1a0852470e5fa045d32725f7ce17982505aa3317a7daa6cb31e3e359c, + 0xcfd305387cda42a1f5a8e00a0ef5286e0504738073dcc8713a43c2439c170c1, + 0x2e10c62b1b5566b5047f18279f4680073494290584c69708553c7729b6a04da9, + 0x2bb1653a56221c6263b0c62ab8a0a773d225b414a984994b6d3d5afd0892e67d, + 0xf270ab89bd220ddf62f18fdf8d278f678379e7b616006a8bead9fac9f473c70, + 0xa1301e2c189208513673b88d6b3238759488f79b99a79dd11d0bd1c973b95a6, + 0x24cb02fc34a8ce75eecf534184d7373b7e1c90fb5f7e24fbe8ec8ea1ef54e393, + 0x1603165537fda2e431b75d03df01dee7b39fd851a472243dcebc2c96d0deff54, + 0x287166d87790f5cf540ecffb1bf65acdaf18cc46a4f1164b5bc0778022e11a18, + 0x2a81c998baf847bbb21f7b7141efe84f7ac56a834c7967ea6f45429fa2fb1a5, + 0x20c95c47c2ce176a500fc18e5b798ebf4df4eabeba1d695fe217e003ac2f0e10, + 0x54cfe239b46d49baf4568088a72b2bfed0773be27f6e7e9a2c02bbb1ffa515b, + 0x8774564392fba9a0289bd2012b509bcc7b126d9ef3378da0769d8af37cb44c7, + 0x24a7f216983732c11ad301538184100e2cb090742dd81c09783918404f1c7538, + 0xfafa523ca9deb758cc5c0f54e485919a3b1c6caab6f322a36b014821c74645c, + 0xc8b11f331a17d83848b10efb6f8716baa92e649d9ee1c9584b334d0378b5318, + 0x2fe8b8a523a08c2e5ea7600b7876fa4b75938fd56c03c74ee2b60b9d1e8299a, + 0x1d039ad8acc6c9515c4b4a78f1b8a85784c287d5fa0eccef43901435c1c41942, + 0x1b89217c5104374c0b74a3a3ee0971ca583f59d0980c37566ef8ef363b1a417a, + 0x228b4d065bd84d6104e3828caed06fe9aa11d7dd8ea90efefc28489330674b2d, + 0x1d57f64ca6fb25d9a4b65736683dc6f8f90b4d5594fcffd6034443e98733af72, + 0x11ece5bbbbb611968ad64b52d89d7ae5d1eebc4169217e07b99dfdfea0fb69d8, + 0x21ca2fb7b186974b4bb67f95f943a07adf662eb02c7392d9f5e7526764e7b986, + 0x1f47138d833b0c8cf6294ef77d0ebede94ea57a28ac0a3e64bcb5df91320f10a, + 0xb95be5cad31b06ca97ca74289d89772aab0e8007d0558228d88f11364a1496c, + 0x794a48d6d0201d4b3af86c0fcd5479391f98f75623105f3e266dde215d76157, + 0x2455a03e833b1dafa17f29a71fd76f94d8c5d09fa1fb1665373d509a88f3763e, + 0x799ea93d781c35dea4b487f9849ff1800f1b63cc97842e2fde69f547bb76763, + 0x28fd070e349d506942cc217a50064cfb2e3ebbd3cde16c09fd68b7e4eab1b822, + 0x1cf5001c9cfcee852fcb9f8d89e19e336dba95bec545410f4435b5b01f4b80d3, + 0x8edfc4e49ac404861074e34237a1b124e4d8e5d6ccde29d1ee9c043756c44f4, + 0x2ee5b6524289cdd37ce4ccc8dd19e94cd2ee72ff264b468044bda8227b110dfc, + 0x2775a93e2b3eef8dc0bf9bd322e5f14281eb5bbbff98cf7ad93d35f4c4392624, + 0x4c564ee74a1199444d3dc4261e90b1886d760a7fa68ebaeeb5b5e353684e24b, + 0x25ffe7b20eaee8f694fa81039440b5c63eca1cac712f5e3b21af1b9a7be117ad, + 0x14a1035368093069b2a4337027fa695e985b6e56ca818ff944780c1677a836aa, + 0xfd53ab1fc6def97651d2d66d0f58976b39d07db8c4c9ac195db0dab73060274, + 0x16476bc3bc364193912051b64c939c0001e95953c76f7a748957d78ccc881040, + 0xc5a52339fd84b1ecac4a163b36d41941a156f53b2559061602e64d2dd031039, + 0x21b63c30dc0baf2b71ee86b7d5c91da1c17cdcebe5a0a0e5f2c8446584e05c20, + 0x1bccca220986d8fc3d22391a70bfba575a47b4f83230652e1772e2dcd1a06ed6, + 0x162a9696d6df2a13038e0bc6da2f52239951a204bd05a9e2a09066cf6b13a6bf, + 0x1d661af4be59bd53da92acdf5736a7dce50da796c393b4e43001d27f88d58d6f, + 0x1fb43feff48b0a4e5ac9b17a6c93e241f17b5dfc76523b65dc366bc04c9f06b, + 0x1e70af5d289fea2ef26141246e9635fd007be3c3d755abf3bbcda9c4e4a600b1, + 0x148928433fc03d3a878b420efc8954f04fdd4958bc822a6123df1d4d15d02dfa, + 0x61b30453d8edaeb5a0e7a3a9f951a7211a50fc360903c4b25a51e4e36dc434a, + 0xacad4bf22e14bf31537f39286d25fb493fe67f163bddebc3e94de911a9556f1, + 0x5a4dc602f73e13984177dc0a6f2d7af269988f872b817c837c8559c79b03819, + 0x1d1f813dca1d8f54d73441c814ccb0e84beae8ef4463effb612eb6ad131cf05f, + 0xe82c3574b61d4c239a3024d6822bfa186d5989ba1ae0597092560e8694ad9ab, + 0x17ea9ef9ef7da806c992916b2409a277fff09d36339cbfdf4687606793fdee9d, + 0x19454e5c7ffa9716bd1db5d707d4d24b909f4c718137ebb73a9661ef41a7ce44, + 0xaf8dccfbedea2064586771a23ac776db9ac4df3787fdf857db4a2193e934a3b, + 0x2748872a6ad3a07b30161ae37440d5dda279a12cc2ffe14747bf9082e72630e2, + 0x1a529a39f6519dcdfe38e311c7b0f661550e388870772650e1ce02135bdae984, + 0x8a57affe13513b3bb19680381a17f82101be9f5ac7be0cf9c7e61f710e63892, + 0x200d13b0170c124a25026f780273c4f557a3e95cbd68684e4e4df5ec00610f60, + 0x14c79a357f53469f91d01f4432b728551db863ab232525c2d95cf616f7a098d8, + 0xc513fd43af43ec6c905092c6d5d50aac833f144b9630e99483a83c3402f4832, + 0xab802177b395f6b6ad3dc7d1995f60eddb63e9c378a75247a08002d2986482f, + 0x589d228f316da74fbd8f0806ba45fcc1f31dc452e37430050bd9cb8f3e0acc, + 0x1b46df6f8889fd075b585d61925fe1f08d15900074bce706ea5fb211dcc63d43, + 0x1d2b938132acf70f122b64ae172ec1a822ecbde5a188b478e789c5c3e91cefa1, + 0x2308c203544d162d54a4b87d92102ef85cbbf1ab4c3c02d6642af038730333da, + 0x2eb7379bd69996d813136c99c2e66f45ca467bcdfae03a315cfe39ea99eeda3a, + 0xcbcf8be09e77a9b7004faa49c560e84077038326398196c04f948d09ac57388, + 0x72ed6973242f117e5fc1c344d9bc38d5fb3e94bcc02f48843a057e19bacc917, + 0x6670c3a568d7efb7f10eaebd727e7a424a5e2b40d7201fb66d0b74723081ee4, + 0x1e2105cd356ebeaaa12233233a2a22e0524c822b84fbb368b409d448192ef9d7, + 0x10f3092cb126d913e829eb1e09cef850812658485e5ac06c140bd1b549f53907, + 0x2bcf1b9917cb73d1856ae5dad349ff08660e800a5b69a959add19af6558884c4, + 0x7bfcd988feeabe2fbe03ae71408c1a394daf2943c8d32e41f6b72f2493bfae, + 0x2a977dd5735a9110178e2bb0989c7129bab2c6f9276ff1a9c4b3867a115b815d, + 0x229f01e653f7b280153de1f8d4e9eaa0e18e81c3ddfe9cf0f5185b63dcf8f3ae, + 0x272ebef10616ab9c79e34eff00b0faea7521fcea55df526bdc9e342592da9469, + 0x2c8a5085170dc8e626fd9f5f1186f99763976ea6ac08c253d025fb46e1526c7, + 0x2b77b7c7f7b862b6bd45b894af1cd1cca444f426d63571ffe6d57e608f12441c, + 0x1518209639e513d5623184871ccc1a02e82536b68d48395774930dbd4f130ddd, + 0x2417244fc99acce8d1da6685df7e33876bda3dd632cd684242a60d54555b0ef4, + 0x12dbd5616e93afff056e7402afb361f5753ed668d6ded08cc8be3febe58ae3d1 + ], + [ + [ + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x1abb95b6e33243a050e563b5c4fd059de5513ec28994a6f60e57c98d3bc8f586, + 0x110d213a836478aa301bc1fd4edd388507d87745b3abfba5bf282afd21f7242a, + 0x18edb2d105bb53b768ae0137850dc2d2bf6d1303a1f8ee4aadf76d8f81990588, + 0x1e53e92df6c53ecec4c0de5b07dc4c9a0c5545f2abcc1fabf4ccb84a0a6e2c27, + 0x10fcb817e10f69f7074e64c393b807cdddf33c84a8b5cfe33f44b73fe18c0e36, + 0x2b1d8c11fc652c593543b6f9800bb7d0c9371dedb96f08bbbccffdc6cc44db98, + 0x19f473e40c05676d5f8d51e11336e9c65cb32828c397cc8125f1dc667b6cadf7, + 0xfcf3a4d9c6c3392de1bdfe25cfb86817ecb80c51be17d47f79750201f1fcd01, + 0x23b02d00fe2634889673a7d04736fe15b9f62652b1c0626a19af8d6085d70822 + ], + [ + 0x2fe429db8068e61b82624f25766273cd9fe6368ff097eab97aaa09be4c630e27, + 0xa5b604c958bc90071ad10618b1772599e0c8dddfb641131fef39daa58a39923, + 0x2cdee0c635a4fcd9549f0f91b4f4a9b628aa7319e2eaa094a693b38b5cf9a242, + 0x2c962d7d54a98c3a82a638d8c82450813f42071a17c6c05f470b44958f57ef15, + 0x2bc761185f59efb7b67bcf1d3e54da00daea067fe49e3f1d9334e5470438b454, + 0x2e450d1fe7773c9889a0be55e44453bcc844c94b56fc0bb806eb9982ac553428, + 0x25c0f87c946f375e341f72f6a8dd63a94e86f4ad182715bcfcbf2b28df6b4a0d, + 0xbfe6fc08e2a2e1b8911ae065b985388fcd105a490a4ab943b25558cf3d054b6, + 0xc182e438257c4ad7e7b79c3b68d60984e507ac597cb47dc31d913a7a540fd9a, + 0x2ff4d0b8798a82667793533730083c25223d589cdd079362f1e8c2e01d54476a + ], + [ + 0x2e750867942439083365d21fe760c7dfec9e3593c67de12a4255c6b01648b690, + 0x24e82df5873953792baca345b7c19f61039adeb1190592bca18cf4f907c1a6fe, + 0xd60f0585755d48577b465746de8e286e49925150f1784f29fb6b96dbd8f0ec, + 0x1f495e93014314988dace5e4e867f5109e09fa00fce87929d1e0ece95a449345, + 0x124331e0ecb1d9808a1d91efaa98950abe930c46fee5a30d5ad07976a5bc0263, + 0x2f421fcf54d77dd38930cd69076f9baadd3d3f1947371215a66c894d637e89b9, + 0x543b2bc66f3b2d93d4c1882039ddb37c70c0b437ac23ac5bb9868e6df24485e, + 0x203d9ee6462a586914fe7dbfc1bfa29773b7f9b3d63aea4120c601129c16660f, + 0x25a1ecbd7e7893f646f35d3e07ee997c94354737884fe6c26ae8155760db8aa, + 0x1d897f60e87fce5ceed8da7f2f4a63fdee7ff9dcf179c08e05e9e5cdd8238ac7 + ], + [ + 0x23237985a96b177ff7c01486ab0d603d29991b8324abd6b07dbb96f5c21ba17f, + 0x10e3349eefd3a112417e110fd9e832078e54b5f4537cd018aee3dfbb90541581, + 0x2168dcf216d8369a626ccc61453236a389d02519f3052e87eff9ccb8aa299c46, + 0x262903f36acf0dc055f610397df0794fbc30927ef185c6356bc33e5c31faef9f, + 0x46887724f29321895c2ef8bc0cf545df773c04baa097c352a4165395cca786, + 0x13276081db012d1d4f4b7dd2d8a2f8a5180d2ecc33854cdd35f9ceb07bf40d53, + 0x2dd117218538e8acb0301eb40adfa2435f5bffa8028ff52f96a99d77fe927066, + 0x1b912abf2e1649ad4834ca5b2a3831cc9c207d4d08e4bf274a79dca80e52fe24, + 0x20135ff263867f708ee0275170cc9788689c088b2933a361c775cf430748ef1f, + 0xba6d4ceee2182d3f2ab2e4a3ad08fc31f7f4cc0fec91ad53e92bf8ada3e278f + ], + [ + 0x15ccec857b25934ffd429af92c910db31d00dc1c3fb83745a31d8131ea5baa85, + 0x165adebe00c7ba019499018c96f5c5870eca5679c90c843d9527184a525fcca0, + 0x3530dd962ef23dc16f79b28c1fc1ddafe9458be15174cbbbf3a806de5f63cef, + 0x1b7e922b3dd503e6441ada966c8b3ba7b908cb2b98b5fbe1e4c2fb982455baa2, + 0x247460ad4580a18639eada69b904c91b19f7d4387435707696c40bac3bfbdd33, + 0x144d5be38d44c5bf8f3c5735334fb1a07c13702d86af39ba0b4220ec9a7568a2, + 0x269b06b31e89ff132daebc200efdc8ab068136fce65f2fc55a1dcb939b7fc6f5, + 0x62caa3c9fd39b69864faf701dc8a4588571cb31bfd5c9c3c59dfd97e99f701a, + 0x20e160f772998a2f7d0064c7efa15884ebc6d8b71821cd5336e2df14341c95ee, + 0x5ce94b8e9a60b28947710461d87c7757246266ae8fa5d3af3ea81776b5b8c07 + ], + [ + 0x17102ad2d98043e5509e76c331e6b22d5fb62d074760806aa675764660eb56d2, + 0x1fb81218feeedf4e7e0e33dd8ecbe62d65c6b7d4233f32e073571ff862d89c3, + 0x1cedc6d4e1476741c1099557e58e642c42892aa36e2d0a793f670781a21b0dbd, + 0x1a88ae2fde12ba32e5f4eccacf11c25bc163bdedaaa8824474cae5869e5ec20f, + 0x265412a4e3b5560aba502d20ed833deff707b7d425ba3c09f3b6392b6f1f4339, + 0x12691b599d32edc48ae99c7a73abd59e5b18f4bf773fa1051cabd2c49aaabf6b, + 0x20d4401cbbf92877ecf616d7d28551cb0aec552fae9518dcf9218c38c1a0bc90, + 0x138c03a2ecea183cb8f265eecd7e93275b0bb98297c1545a72197dc6ddd9335f, + 0x150df11291b680e3ba925a0471c7fbb30e704ab4b554ea5d8c07b70b2b96202a, + 0xc346b046af03cb9048c29353e1107d6b75e590bb2d422ea83c09a5da1ba0c65 + ], + [ + 0xa4ecaabde9d1ea11c81dafa8d5d4869bee7ad0bf4eb78397b71b8f989cf9812, + 0x1be2802fbea51003aafae82ff4499d1158377b108f8b020c82b8460a8d603afa, + 0x269c8c139a4f61e16bfaae9e8bbb1c69808c9071083b0a339dff9e4904b443d6, + 0x23407728269c70fe712b021915059dc8dc2124ae648e2cb549fc76362bc2b97d, + 0x2ad06fc9f81684542e0458aae19c0a7c18be94f1de3fce6a3e5d2335a01e90e, + 0x578a55f0fda29909b9f850c3d74be6668e4444ac691764f1644a626498218e4, + 0x2ee2da24b7f8e7035fb73b08c3414833ffa38e14b1faac198a860a5767d2feed, + 0x11589959fc2493292fb6c50730e74994ad7cd6d3533c3b00a57dae833cc701e5, + 0x17572029e8e897202d0e65c2172c571d4b91ca856e7ad3f118ad922127b87054, + 0x2fbf8cc6ec7efb30106423f2e67b0aa9403360e56e88b6c5cbaec34a80bdc7f4 + ], + [ + 0xec1821648fddc448a1512aecc8ac37714923981940f5542737a468d4d887c8f, + 0x418081de8c2958355a1e45e28ee51ba2c66cad04835f4fbd81e696de6398769, + 0xea7bc52503e2039d277912e022fd6d0ded5bc687c6ff97194976f3a28bd30c6, + 0x12ab318626d511c23d28baa9fb5b5802e0ab95e3cb17aedbaa25f4d084cfda57, + 0xd1e34192343d66fc1b6591cb6a3b0602b0835a403c7227dbcbd72fd8000c6f2, + 0x12e3b04924b2cf6e407bd26b3cd47bca61d6ffcf7efa1aea1c2e0d8a49de64be, + 0x6dd89fabf92546847b9c13b3a36bbc7e679c5bb0dd785403f3ff49bbe61c8e7, + 0x17b9facdbe747d7c5163ca00e3b0b825d012ed4357604e7185750d677c6b357f, + 0xaff15650b805bff6f8b3515d5e29cf914b7349af8924e796009f8a4f1b7264c, + 0xd064e72449efc11d1e90b97749de3909490b912bb1f72f542f41d62ab2d847a + ], + [ + 0x255a493aa4becd9d137eb76941c4120784c1233f6c5fdf5d65c0832af543e415, + 0x1f3e937ab29f3a88c6fe438698a7198a5209aa6ac9f141319f3bb201e7fd6716, + 0x2180b9eb156eb33cad1aa750ea0fa3ddbfa4127296e497f86e6441e052a23b45, + 0x1cc69d8f34ee877838950e20a9d4c4bd3e9acaf3d693aa64cae04faa225a2e1e, + 0xb565179887ee30e381631d8e5dd357c70ee2ebb410617d2321f6d8537f98970, + 0x1162a56ed3bbbb4b6760a16a300ba7202130086da4d5588a70926423ff8c242f, + 0x1360f719034572b59410c529b62a62aa94565654597e42779f33400f1d17d652, + 0xc603d03f92860da8a68c6dcb1924d1a45099aea50f1a362edb2f2a7ddfe90ff, + 0x1a918fc117d9a6445e363ee5833dc01411034b95384d98eee47ae896f92a7d67, + 0x2a88e0c35617665f3cc2fc77d90afc7a8d1001c71debcf2733ca0c71a19e1ea + ], + [ + 0x120f44670301b1435249294d9833d59e01682af4c8658719727678fd9ab7ef2e, + 0x113e968769b0ea32cb7b5ff70484aacc96f13dc2827a8e5e611695e0797fc3c, + 0x18cd1471430adad31e45b529494fc8a7e319bd2fc0619c99207dfacdb657bbf7, + 0x23d0fa965e920dfc530b52670b1e32e2d5fc2821fc918c0844a003b7141825ad, + 0x2ea6b32af37cd765d728ddefa30918902a21e19b291400854f56393c56d69460, + 0x3340cacb04d5a85614eacc4be3352938baa3fc714c2575aa9d85f739113c50b, + 0x15ff827e034c02a90767f0152840e7fc6db983e496ea0519c0ff41dea8180628, + 0x5d56f0c844d169248503135e4deb9ffd6329d54cfceed4b947d78a568681147, + 0x2e5618411efea30cc7de310d4872597d087c1e122e02ebb117db0c2dff04fc0c, + 0x15eeb3e0541bcf010da0c47adb12f6df540b974d439c93e19ea4d02f9975d446 + ] + ], + [ +[ +0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, +0x2376caeace68ac7d5504c33a2219f5c7c5ad25784cea62a8df008c4fcab50d07, +0x11738aa054dba194b2e82013feb222a4257eaec8a01f131fc657ee766f408d04, +0x22683ac3c69cb11bc0879ea8b2a5c88aecb222d25c68a660a2f4999cde166655, +0x713c79d90ea4f0449b01031fb6149994fc9b764fa494a3b0bbaea522d4e48d3, +0xc372107400e1f8f8e93964c84da46d78197aa045614a1dd700f1dce65779437, +0x5abac870bca413db4ef84c71b44676ff7e7c741c9b5e3f3c8efaa73e446c02c, +0x11c5eb9e0e5c1669df902352e35eff4517033d2a2a946a8e5fd1492a3a141229, +0x20caf8e87737232b8c429d7f8e9c9827cd7fca92cbc159a319567e646480c7ca, +0x185ebe5ac788074f48748c8b4f66564a581e615b3df9c78fc5ddb70b80475d3 +], +[ +0x2fe429db8068e61b82624f25766273cd9fe6368ff097eab97aaa09be4c630e27, +0x1b1d1d024385e8a3b81c435ef9079a52dcec3cf811253a83325e7432443ec02a, +0xa5f2f19c49d9ae6d6d8acab3a944b93221a074e7a84939dead82506063120ea, +0xba8903c5a36e9ed67d21b2297f06616760d8beb3ef96c69dc9c843bf52a3015, +0x2a850b071614649f6e6ea4c4382d7aa9981736848c3bdc0cebccf3bd795c65dd, +0x20090c8c6b2e41e84178c0700c9f81b1e128b15f65806648c6166ca8769ab30a, +0x1f9c5c5cd58a682a6155b2db3923cacc1944362035acb2eef2b421fe5bd91f44, +0x2a2190daf9de7f46b5c80235a0a468c68226c193ff86cc8a6ffaa7033626d093, +0x2dab478180d47e197cc91da2f1ff30bc0fb35da934ba38c8e5587e005cdc2f05, +0xc38b0564f60610324268079496ce366271d5693ed6646a6470acef4e779aac7 +], +[ +0x2e750867942439083365d21fe760c7dfec9e3593c67de12a4255c6b01648b690, +0x77d21c1db0df5aefc4a82442165dc0c6671bf7c8ae708c8f9b6d44b033f2139, +0x1b974a1b3977e8bf679394da2b702e724d2fde8aa4e60b83c631de610d1eeb30, +0x12f77c314190ff649ec4a608780c3ef7bd065902802f2bd41a93a0666fb8a90b, +0x7626c698acdc1e4ec6fd26aa192bb334d96a0f3935e5a88a8d7abfbdade4f03, +0x269aa03a5af8a48e20ba3147943c07e1d1ac7760edad58d9d03d0f45157935d1, +0x45f5c794d9706b43bd71f2a4d4f376bcbb76c7276da8fa942eb766955c53efa, +0x6ff77c4c464330deed91103d652330809d17045c75cca24e8b1b0a61d572af1, +0x29e529381ccf3f80fc5d54b7c39adfff8c2ebb5dfb86745cb974a21e9467455, +0x6b50f490125ae0bc287d018d60c4d6752ea3f61ad3e939622c1773df67a7f4a +], +[ +0x23237985a96b177ff7c01486ab0d603d29991b8324abd6b07dbb96f5c21ba17f, +0x2b9c40e97f4e7e6eaf4d342b420fcae7bfdebc3460c120b7a4b99240ea0db532, +0xddfa16097871dbb1337b5ed7ae8d2bca1e5ba44e482df13dc7ad593ef27a5bb, +0x165e20a2a8ea0382f56df39ade0accaab08fd9db8a7657b74ee54b114393aeef, +0x174b9be8f359863993e57e21e4c6fbd4b4a4d339d943ede1d85255ee48b3ffa0, +0x304b87fcdd673ea0ae58bba75c29249f964913b2170aa9f23d4d03894208ed87, +0x278ec34449ad1c5182395a44f2826314db9fafa533e518a5bf082096c2484918, +0x301cbe6e44e903ab193531261770925dacc71b88207e18f793f59f69a4347771, +0x20334328490fd8682bd47066200b77f9509a72a11f2d91d456220c629280aa44, +0x2301d3af42d47b43c8a8052646c069e046ee7d180c62a5d36e52dd6f215bf37d +], +[ +0x15ccec857b25934ffd429af92c910db31d00dc1c3fb83745a31d8131ea5baa85, +0x2655c9fd294d40b9dbb9566609c264c9e602c777c8701b1b2b542a5f08cf976d, +0x29898ad417130c472e0c1da3b017f7166e3a3eb80481efa32503e81a3772e5e7, +0x1681ed2917381cd1217a0c9a2f675353982a438cb3e9108fa5b2048e6b7e32de, +0xdc075092f8f83009ee73cd35e511ac13eedf5e3999f9bf5b41ef3e1a15a8fcd, +0x837fd755c29dc2c29036c497fcdfc23f95c7bffb90a62db5cc43a25e20054c2, +0x19d489fa1fa1ec6441b82b735dbf0b84788c542263d4c1ae5335e49297ed4bcd, +0xeb25d1b0322624190db666759db3c82bc9718a990288d865116787e8c527351, +0x19084cece4945482947cfe51a1f6f4e2e216f5b54742b9d71cc3840bdcbbaabd, +0x3a99be2c75989dccb246bf31a58f88dfc494ce2569c5d8b18a9a876317ecef0 +], +[ +0x17102ad2d98043e5509e76c331e6b22d5fb62d074760806aa675764660eb56d2, +0x795d5914d87c0dc8fbaedfd46afdd6451258f80779112edfcdf1a71d23af4df, +0x2c202548a326cadc3ee595a16a2c2d54ada779390f7bdd4c4fc9417d3e463d03, +0x181db647369841eb58ceb7a1b9ef841a7f3358cc6f224152dc7ad3c1d3b1c1e8, +0x26e7aa2ef4c91ee3f704849f4c181fb83b860da15f62f2250c792e0ee66c0ae6, +0x17189249537630e942f5ac39c1498bce39996c15400d052dcb6cb839aa45322, +0x23bb4a76f79b77f9f6b4940ef2538c7d60d69f1fe9922d66cfb92af9dcd0867a, +0x1ab80a8b5fbd7923f0cf79707d56f7677d1071e924cb497486766a4c4bd7f6d0, +0x1f8f4c40a0cfe0d05603433a0ed2d424c7fd040077b0a1642c25797c20d22d16, +0x29177f698bc5a897ef9aa6b915189f689efcfd88f3da8e60b84b9bccc2ae33b7 +], +[ +0xa4ecaabde9d1ea11c81dafa8d5d4869bee7ad0bf4eb78397b71b8f989cf9812, +0xc066f7a1e10d00fd3e97cd8c67212c28b43423b03ca4ac03efb4d8a376ae098, +0x1a6947c4e87ca0c30ed9f47004e53b7a45455b14da41f79045c2405d2e3cb859, +0x2481ff49ed6259def9fa646c167c8864061c04cfc022051f83ef8a3ef8db5819, +0xc13692adcb86437a860d6296d74b4253e790cae6f41683b99c1760d09921d37, +0x27a6be35c45e5f46b2eca0aedd98f67638b6645acecf50351c5a9f3c428b0e27, +0x4660af4e63d1c9ff6f059b75dd870df938980e43985c5607a38dc0ac8d273f2, +0x2eb8302f1381d9118d9c713d50e117f92837dca8a8610e9de759e76e8ee987f9, +0xe9f931dd923dc4398ac12b101aa7b5e2a22f09caa416ff8745821ff165b07c, +0x209945fe475f6767f668abc045e0c47ae6cb25cdb1efd5586da6c4e655d68e82 +], +[ +0xec1821648fddc448a1512aecc8ac37714923981940f5542737a468d4d887c8f, +0x1049076d8dd43ffc6f4ea10a82dcd60dcf4d60a2125a1b4d8c4ff954e7da3380, +0x192a1bc8e7dd6203116a0c40d58111850edd5b50f9d6e882d16f95fa6a76d80d, +0x1beae2daa2a697afd9b1388dbcd6c93731fbb4eaa0fa439f92bf777769055293, +0x1a31b8769a838df03348e01462b564e08849955efb968d1f41342f02fd627de0, +0x12f1bd9058590ca45a76e19b5891f5bfdc95d653394adb4f32090c60505de408, +0xaac3c820280c7658321df7aaf69274032fccd21be96174582a8c0c9de580068, +0x7c216183f03a4b7c77070c68b3790b31b5fa6d1df5ae42437b6a2283d5b8891, +0xda9d210a43aae4d13625782341ece1d0221bd6ee0dc4a639b7f13a6daa3c93f, +0xc0d8ee0a08021baca7a5799ed7b03734e4b9bd35430279d3f7b2ed473c48c6e +], +[ +0x255a493aa4becd9d137eb76941c4120784c1233f6c5fdf5d65c0832af543e415, +0x19a05dc5bdf1243b57474519b375ba67bd83e122b095e4272c14f9646e733666, +0xdd31347136b2eba27f0528eae1c25a710c3707bde9dff3d76ecbe33f188bb02, +0x248cdf26597e0746d01d8b7ab0e9f88aa452d90eeb039dbaf586563945972fae, +0x25718cec512fa137f8a5851510caee0dd2c000af55af09dee767e2084796a71b, +0x23688bbb9cf13bb7bb972d0d18d0e05c51bff96ba5314bef0af2d912dc5e8d1d, +0x1ee8c54669e6f0ab1fb6a54c809d1fad213e8ffb7a7b40387ef594b7cf50f4f5, +0x282e578ad2799ca36191b37835889bca6e2e8bdf7e4412628bed5e39885d688e, +0x831616989168d514c0fa151fc3874b8cedcf88d27185e7e037cbe93391022e7, +0xbc5380f3490175b28f01eb5cea3914924df2b1f745d33a9e39ab872b19c4fb5 +], +[ +0x120f44670301b1435249294d9833d59e01682af4c8658719727678fd9ab7ef2e, +0x2a25bac660d90d85f22fe81abdc80c403a86e75d4f1434ba2eda3184dc5f2833, +0x2d19334d3eb5a9781f3b8105b0b1131ee95d4012e7faacf71864762b6fcc7011, +0x267b655f26896341492acd89edc7ae96dbcc24161d1e73ac652ea55d61efc3e3, +0x1d9c8ad973feacddad16da2be2ed7eca235b3bda01521da956f1c8a7d65ea58c, +0x15b9ffc66af5ac2aafbf2dcb199a57bbd334c9f971d903d7da7fd65e920cc9bc, +0x25814a817412e861b4318985ff3cb706db6e56dece08c2c6dc20584ed6fa6c7a, +0x4190e2e1cf613602ba331d0185b43c960ff5c57bc2f86f5c8bcd84b95c789a4, +0xe3999f52ed0ec7f486ff150acc84c266aeee72529234a010988f95a1b5885fd, +0x1fcfdb43cbd7992f0088a9a85c95e4621873666105510f25ae576bc08d7f2084 +] +], + [ + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x199593eecc85367004177e717d8adae09206aac28506281403748f85ebe9985f, + 0x8dd94e1b09d8b9823fde4d4fc4a3794d631616a2c192a47fe257bfbdbccb7d, + 0xa0cd01bd7b3c21552ee7c0ba8783ad231802aa4f847d00de820e9176e227744, + 0x287eaab3e59c1cdfce30b6151543b6ef49a3be7206f3cea62db4e80fe1ca1529, + 0x2a8230f7ed05f7e334f91cf214c7bf12852996083c456a506eb316c249cfb4c8, + 0xa38f089600747a6b6e35342c2e321042ebf690726aa9431031351cbaedfb5aa, + 0x1d5301168a7dac6891b7a9f6dbcd505fbf7522f875a61254149449869d316e05, + 0x13abafc765fb2e45f793640bd7f1ea2f88d202f0d7b4200410cd96128d3ef472, + 0xda7e244a420237fbd8730ebea03fff45156a52ac87b9ff605ff1ba20f7e83fe, + 0x271d315532755b1d48814699af18654bb310bb94d1258dde0e589bcc2a5e28bb, + 0x12fb6f92ff04b5d5de41c9508842798a8b9454a99f0cc49a92afead482e84bba, + 0x24cbf9280b713f95571b177799a76e23f555db290a1187aa5ab7db69a2dda2b6, + 0x18f43c99a1b72e7cbd6fd781a46c13c38202b4b0ba7ee75cd36fcb79b5ea67e, + 0x1c69528b3df94c6f7e8a794ea0308fc165f1bc1c1e3ef090c7aaf4405f7cf3bc, + 0x1cb0d8aa6512a7543bd8e8bae1c0f0d2db1b3457e1bcc0ffd372d4eee3c6fafa, + 0x2e1fce1597591bb776ef16340aeddaffdaf039487cb42bfa6752a3ea0cfe18f7, + 0xe486a7b7cdf0fdb88306d96e72161d4549b281152c6cfc98d84b031e95ca166, + 0x1141e26a80698b742d900fd1e734839d51e4d50e0176303a675809ac47201782, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0xe3f8ddade546278648095cc835e94063972b1d55c6414506592ab57e54c8042, + 0x21933a3bc4989347b0703d7cdeddeaf6588a166e6a3f984e318de63ce674e8fa, + 0x2ca6f945f5f755039c8e1bc30935de1ad33312a7cf325b065f91083cfb001a78, + 0x129a9ad876815d96566600a97d41f958d7df9ef97291de611d28d7d9b2af46fc, + 0x26b8f200c0d0371558755081221dc59767afc5a4ddbe6f7d403c5ccb4035289b, + 0xc7c739377b0ad2ff9d3b0a8fa53e39c7016f049ea860e8113b055ec96ee3d64, + 0xd17a36749f8f9d493a0a57bd87618c969cbcf83edb4b207c89aa5ccb3feb20d, + 0xbcfe1266d757503881d56c7e64cfbbc3cb6a47ef4e655565864e01b9bd3f872, + 0x13f89db06ca471b07ac0ad1f4448cb225868b63131700d1ddddda16e6d5fcc7, + 0x24d344ea0550d7720827b6be6c09b027c8e4ad104d57d57771c258177a302b8f, + 0x208ce89913e633aea3a855a854e7daec40afa1939dc1f728dde6b349e39ba30, + 0x1fc4565041d810a750e306a14d21695074e31eda2baf0821774add15c0e2fc3d, + 0x2fa22f80d4309be21ab298ba4bc16a5b20f2ce8f3ed7bc3453135655da269649, + 0x26f3a23903d1e7d835db70f3005b3d5a67043fca7eb62aa8d78942a0c1cc8add, + 0x1ce0343fae8a12e25f2391eb038b2377e7c0c21aa60100818539d6092eeeafb0, + 0x244a2bb870f1e6f4ba5e20f1c225723f305841bd0ab932b7334990cb0572c33e, + 0x1ec61e9126f4c8fd6f0d00b28c5f02334c077e99ecb358d2536b2d321cc00aad, + 0x18b2ab087e3f0a7fa8a6bc1687900a5481ea991ffddf017ff52a7f371c22db87, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x140b91ca0e53110e898a67ba8853d04821952e760e56de985180975ad237ea52, + 0x3385f50412cc6d4caaeab9aaf1099e8c3c61295754345534a1476144a9c2678, + 0xcc396f0b80e2638615bb4a250f84e54dfe33ce76386edf22da2dbb233546ac1, + 0x2810d8ef50de86e04cd8a07f6585a06eabc4ac5efdc4410904d7a906ecd172dc, + 0x1f8b8501e9db678cc274b33246e39eb95635ac4ad2ff759a9201ac0c3f16c12b, + 0x9b10e50dc0703b65199c6cff8510a9ef2172545f366ec2aaedbb2f5ad4e391d, + 0x158a6e9ae44d1ebc7fb99b5b38e5139257c68f0ddea96593ff7a87dfe79cbbe2, + 0x68dba3eb9f1b909707e666c1e7c745192f6ec2d8439c186faf6d3bb978b42a8, + 0x100be98775675cb0864cb56fa3f82b66b216071d10cdf87358c7e46be055c723, + 0x1684c4b116063b5e05cbf4eb9b3a6ba6d68ce1f30ae3978e1bbea7a71bd20cfa, + 0x678cf4e455f8359f498a22b87a3dbfc50ce233cbbd99995cc259e419899e53d, + 0x305d111beaf3f510a104ed93aa254f20a4c539eeca95756ae03bdbdf0c8eebc1, + 0x197b0550e8e09c375f4b1976395ae6051649d6c7a8c39b78676e45d33a8630d2, + 0x190712928fc6ac88f24cd9179348b4a2832748dcf708e01c50efcd32e2b83de6, + 0xa77bfa4113e98b47e8d705a9f60160ba144ba344c274744f135f207b24929ef, + 0x2962a7083e7830d287de0a3436cc093e0fd7c2d9631b4937ac124d58fe3fb901, + 0x91a715976bd99e40777c119f68ebec701e3777cc9b9e52602588a5ff89583eb, + 0x61e3488cc92892520449518af4f4133b52412a19fb8b98d3d0812dea2636e3c, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x197ce59bc87f624e9629b7383452b9858362754ba76cabd0e3d3161eb8ca76d6, + 0x276e2e6272ab2858142f0ddaa038f436e9f4c53eb4d5dfd8812cf10ca5bab1ac, + 0x9c49831a9e1c453d072ce83e5088666b56dfd1ad0977b2abcb2aa9ec83e2ca6, + 0x2a4aadbf31a1c58a26626ef9de341f2268bca243eb859a465911da18af0173e7, + 0x21b0460dfc8645851be88e96ed5f67cc2ea5ee00f4f3025ec4b5253494105a47, + 0x120a8288745f9dc360cb1d580b012b52543030b53b9b97ac9324df79fc46df06, + 0x9f0d911f5eb1bbef4c9ee96c2fec0b0c00945de4706b4cbf64f62a02015d7c5, + 0xdd0124d8c9d7b7c202379a001263e0522ce49d1081f63816134ad16bb34277d, + 0x2bd803e20cb341debccbad79b053df6e53f567874a52ddeb9422758e73cf6ec8, + 0x19b2b4b0e24bee790fba0867847f947f975dddfbe3c11b4c566ed4673684c0cf, + 0x1acda97c75929ac11c21cb081f177a6e550331b2670e6a66c2793e4ca4bcc3e1, + 0x251c70a93b81276ea3438709b96351fd8004dbee0abc0df79329caa4d932bd62, + 0x28918984ffdfc01138df3fba5221a8604c954b7ee40de7070fb0e34e7038ea3, + 0x2ea1cff24f208aed6f4da7cf837817ebfb6f545528d85a32430aba357eef776f, + 0x15b61ada681df7de801547bc9937b1c2e75a4f9728cfb5586f765b058735ccbf, + 0x16a4ad2b453006d9fcef31919daf7ded6dedff3c5b3ba4fed692e2350899167, + 0xe8cdd7c3d33927077543bda5b1777f6369d06876b8636cb95a9060c7936be90, + 0x26152760e5dfe9f0a2fe901bed5e0dff3049827e43a1091e24aee4d457490a63, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x1ce56e15f41c99a2a005acc7f78b735e8330dba4db4cc96c524b4638010937ac, + 0x2b33ef11fc26750d1497df0fa1b969f1c01c5556522150ff976912649af06a99, + 0x47e2b54830ccb7ac893e39afe89b1d7eac35c7ec0f28b343e0249b924f15d37, + 0x2e820332c7266af2a59ddcb5206d404827e9563ca2c5dde5d2d34be269c82612, + 0x28fc123f79ace39838b7af8f86be8cbf89a3540015bed059fb7a55868edee623, + 0x121ae712c922e7ef55ebb73809f3036db42852c52fa63bff322237bd883dd555, + 0x3002f25a7ef8e035c0e82597953a107fc73a5a406770dd47ca93a34cdf8040a7, + 0x23ea2cf159ca1b8a17ca61b73bc84b33ca7204c4120cec087424470dd062076e, + 0x179e72146176bd15051df789ddc3d0f48437c973232846e4223daf05529248fe, + 0x25edc52b2cd7bb6690692d75c3f1b999f2ae0749c5d2741d2b53284b5655d46d, + 0x1cdbea76c865750ceb85ec17f20c955f2edd46df09f0ad90d04cf416b10fcaae, + 0x2edd29ae05591244e1124edc195033a404aa98a863678d3769ddb5797a2a748d, + 0x2d9d2a342475cc1662da5b26453efb92f1549efbac72a1226373414a49a13590, + 0x4783348904bbd884be3c608fa349287d2e4d4284baaac9b6ffed192a641406e, + 0x1588ed490b8448cfb883d790bb0f97a2f1962d14289c946b8ee49a4ddcf7a3eb, + 0xbf107dfc33fc7e66153c7e5d6beedd252d17b8ca1bf1f6499a9dafea570fb07, + 0x201d0f15aef01a1e0b401f946f7b29e6f01147b6257d7ee235c6d319c4474326, + 0x1015804003503668b1dbf9bbc98eea304dcdeea4eb7dafc67b41a6446af10385, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0xbee3e128dae75005ceb095d9e6e0e55285ff7edd96dc89654f5b83570593503, + 0x1853cf3ebd47b13b2f218990eb3ea26379c1d213e70feea5b84882d76241ceae, + 0x2c25e50d363cc08774bee7d9e6232855f6d8977ab169e38fc6fc76de9a63e6f, + 0x21ccc1e8f8b5ad39b401f79c51ed881ec892d2a7eebb8ffbd848ef158afcaf68, + 0x2193aa94ecd57e962604ab428aa0a8971644707c6e85663ef9b3720a685d71b0, + 0x1d3b5cd3133a0533eb15cd908cbbb5dce76ecf5b711f2535e852aa472ee4c9d1, + 0x11f29d358de76ef38d31d6d7247b64d41c42ebddc7ef5e4445c7897f57ad08b3, + 0xfcc2984d1d2b762d6fa16a3a407f4d3eec484a9129763864265add7c900836d, + 0x2f79d03e732317585ff9abb62a371800553f1eb717a71437e225b204c18f9e9b, + 0x2f4f14eee6382dd0c54d10739b354abf104cf134babadf2dff9b8cf286f9733, + 0xd0c5aa4bc4f774d03ef5b2f9619f618edd9afb37defcc420b0aa4f4fd145e85, + 0x9b150f8dc9342c87a8b7e871345e5998c084662c897899df45d73157c4fd0f0, + 0x28148860436280cd8a5fd6645fd1eb86abdb72dbcb02e8ef47065a4a681e9eb9, + 0x2cf619fe3735ed9bccedfbdf3de64031cd203231a0e178417bbcdeaf69c85d15, + 0x32f164c4f4e5122d438a9e0309459141505621343ab1c19abb63ce7c036ad03, + 0x2a3efdef552208ce3441637e2cd610386f41f402bec452d674bd2fe16c273581, + 0x1a9e7a13e4d57cd1ab3e38f0991fcaa4cac542f66fc2a46f9cf7d20029cac792, + 0x20871908a0ec043e1e43ee1f520584f15b3a7f24a2d03aa1de50e27ca599d872, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x4767ef42341d3930d7e5219fabbff62f44e103b3a0905cffaea5a2dee73c19, + 0xc4a1786e515cd9bcab2b7c9723c597e730c532555003cae4e36131a721f6ff9, + 0x147f468c58deafdcf47e57114df0ead2c77452a45020e73955cb150e10153520, + 0x1d1309f96110c70d9ef884374676b9cc3a599fde74388ef68d99e54b5802c760, + 0x134281c387edde8b6f807d253bc0ace7a625fb3c1f65b88e4537febff52e1d62, + 0x2fec2d972ac4b8ba14bbc95cee2ac6cb8c669abc35e77ae2f7dc962dccdad59b, + 0x1782c9e451cbde261da8b4ad3a15e23ef7f4daf7b406732de05570c73040c663, + 0x261bf6a9f68e313088d8b2016d3e7763a6f6eecd9b506fd2baa8d8f3593b4c4b, + 0x133315cca34af406eae080edf7ce27574fb984710e4e8ec39aeb6491b97f98b7, + 0x216763174ddb0395182ebe57e4feb91be8f13746e89949557e023df397cb679b, + 0x9dbb42bf26459d3f9ba2ed5f491b4f01fff6222c6bddb7776450edb6c652ce5, + 0xea832a969ad1d94f55cb34f35c7327f62f24fa140817b238bc676edf1f77b6c, + 0xda7dc395978e8ee00ea5ba5103a39930e284533b1a51fbcd3d7daa542142dda, + 0x183cf55053b7981ac506fe1c56fee73fe3a39ae042171e21541b2b7312618722, + 0x16eabfa4236b9b61ba1b336ce55febf1cc84343f0449a54873cccfce0ff9389e, + 0x2b62c1083fbc23f58fd694646499bcb90368a2e63794b1d39dbaa36bf782e363, + 0x11ecdbc47a72138aafe44263356d01e931541ad49ac28c048428ecd233fe3c6d, + 0xeb0e1c7cae7c3f491cff7216ddce50aeb98935e405316c6daff1c21046af99f, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x2323c898ca30f7e8fce9b31d21283d3545705a71d0ce9577c5012fde6caaa11f, + 0x2373f9b1c4df6c500768ddb13eedecf0a82bda6029c0abf90f3f15f2e7a9f87a, + 0x2b4a1e59a52b1b825f6f8dca5ef66b929032dab32a9d3a58ebb44887f84c18ca, + 0x3034ae984f1538e2163148617760f62569231a619a0e2b620d206211b232ef29, + 0xf1fb16f83c8ddd6959d01a9576a8d70c226a1a422ffae89ee0baeeb37e9a8be, + 0x58d583dcf975f97dbf31e32ebfb0841298f765476b2e4833260ad9bb82f2f2d, + 0x2b1060a96e8a6de59e2deac81b17d40ecaaa4087276b7d5a9ac2b47598c2facb, + 0x70579f1869154a6efcb59f85b43b90affe755efd5d4e62686aff46646e0808f, + 0x21444d26f9de3b9fd22efea95d62f5193c3eb0b2e1a6b393e85996439aa43992, + 0x138671f92f9ed9a8131ff4c7da6806dbc33f6c02cfd3d946aa92288df2ff9d9a, + 0x1e629d7b8f61fa02a5fb2fb163a5a57a593b158df70413fe868b338307a449d6, + 0x10f0f884186e996c19ce4939bf317b3d12cd24bb87bba0d3bb763ab716ed41b, + 0xe2f06ba65a2c7c8500850ba6a489879252d0db2af69dd23fa3ed106c92739c1, + 0x19823b0af9feb33ea07566495f0de05e7ebfa52aa89f5a5d7c66f96ad60c828e, + 0x16b0527fc6aac4b4485dded0afd8905e6b53e056efd33df7b8fc2d3d4b54cd, + 0x8a584f510af49572ee86cf723346066002e5e7621e502e946f8f35003b793fc, + 0x8a63466c0bbbdfe79375f181ed0266c97e6057653d0b285696a5ef3e93c27c7, + 0x28ae69c874a3ab1ee6360bb1ff560fbab69591e837a4bc4d80ffb4d253e232c5, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x26751aa290792a4fb3921d9ff8b5967efdf68b1fd85981b4d96401bc621b381, + 0x1cb215d90f4015cc5934293e248b2d6aca4e0afd46cca219a89eb4f676199481, + 0xb8f12cbe7152d6f3e5fbbe978884a5b7be6f35fda4c00f5c5975158df2f338e, + 0x17d6d8fe5ede1ba531918c33df5c6c9efefbc20304b2fbee19c01aef81299774, + 0xb53ad598a4e14448fd044b8ce15b6336af6b91cfb81c0da827e7dd68e98e59d, + 0x15e20ee8fc573330fa52fd42ec7b636e28cede5437be371b1990898751adeb74, + 0x154fa8d9c7f09c1ffc7fdfcb58fe7b91e6d81b03adfb8f9e2fe0522f6f7c2541, + 0xc17e59b4750d7443f8030f26ebd82d25623e2b8e5540cba1f310828e5e66988, + 0x7dfbe56e6ae749917b93471525255853fba26222d45e0504d8f74784b1a86f3, + 0xae4cd50975a86aff25632e8c9b7c0e915bc38159c90dfd9459e29ea9432e467, + 0x1fd9cc61b67d700ec892a8c09af677c9e28097463010126823cb72d07583754c, + 0x1bb36856ba8992334e795626486a4608c5d9a076cd93c8aa0e1a934ae4e8f3b4, + 0x2f9cce5050f66f493cc95213db4336536a3a0e2a17311cecc27cfd9d88e339d8, + 0x14839ed69feeab49ef110556d96b4f1793f8c95f3a38de800e9ca0df690f958f, + 0x7b5c5afb6a826ccf1b740cfc8aa6f0279ab50c3de8a98f6692bff8cedbe5f0e, + 0x142f7788b72c5fd5a9065ebef59f6e8d32eed74588cfc22ad0962aeb24a7bd0e, + 0x1d07d62eeb6dabe9df4fa00ad642bfa7d36687d6ca9c8f023a40b5d04bc78ae8, + 0x13e55cabc0bfbb9ed41bf205be0674e8668a8908c411ae821d2539d8cc587fca, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x262b44719763ef2a486e59231d9624bcf1ecb95f576bde1e7088dd5a7e4a5f89, + 0x2dfde9e5ea549d50c4497d25b4a4cecd096226253b3c7c3874057fa62b8743e2, + 0x21a567f428d745b4cfdda7100163871a5383e5d8ebbda66f7a305a4c6be0abdd, + 0x1dda63eedb6364b5da1fd1acc28b6a57b9a4033ee7749a8c2ac152a1e94d4b4f, + 0x685e2a27b7ec3fdbcbe3e017953374976ff85371aea9109c2d76f0ae1ceecd7, + 0xbadd4c6541613422a3c2b71626af0df7f380d6f3f6da676b7e6dda463f63ffc, + 0xe270311e05a64fe34fab3018b68616f08a2bf4c06a47ca457defa4c199fb96c, + 0x20782abf7216f6c5e781a8f0350099551c5e9a1a3d4b3ed2d985e5a7f566b24d, + 0x2b1a699f26b1fc4beb031df4f37b8d5cbabf780572fdc64a56de00748a65c07, + 0x791e4fd31ebc85df2e06aae29edd808f129493f8583732492fbd7056e93dee5, + 0x2cda35be891732bed62392cddd00557b6f4b195e000c1bd4fcfb605f8e369d64, + 0x6b17710849d27210afb3ecca7e7c7ad3bfa36075ddf1b46d7bf0a557c7afba4, + 0x2a1ad86529da724870dbf3bd6fc20cccc1998102cf0d7007a6b2263999e4fcd2, + 0x2ca7a691f176d709c8799b5094d28a68db601ffb5d133cdfcbfae9e565f1ed84, + 0x92ee47cd58d3038bf80c70d798516c0dc371ee7fc7715da95ccdd5a1e820347, + 0x2f0a3f3ab9033e8640e9c1b7112b31242b7eb493837b84bbdc9cf56ce5858752, + 0x2bafa447b4f5b878e812ea7b2467c72890c119992bd1f6e3ca60f926e812d2c6, + 0x6f980dec5d6b3665f1cf9fea725ecdad874c5c9cb63e7987fb41e7430a3e352, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x2d69490ba2ee43e841922e9a426a5bbc264f17ed379f8bc91ae3d275e724c21a, + 0x55c6b789c7c9586e4c88fbf4eb60783cdf8e9e58d356bba1ef92f8ec3514aac, + 0x160f356a6a05a6919dc7d2e03878c6eb552a14995edcab05f623273c0cd29a1c, + 0x2a178e1d8e4e4609710499245dc91e66f3795b5c0227a2ba8cc8a9f8830aa212, + 0x2dff2498b5124e3bc2587f3b1cfef4dbc1168c2172dc43f1d801cb75c7e18ff7, + 0x3062dff835ea1ef8f6960d05f57368fb48357ece82fd7ef12cb5254a55e3d102, + 0x7f83dab6ad44900a3be2e049bac44fc5eafddc0e261ed5d1795fd513f12722, + 0x1a037c2eb85f1dd82bc9988c67646efed697444ea2739b6800d214e8fc52c8d5, + 0x17cc92ab3464a089e4f7747fcbee5043b59bf9d7cb744346cc2d889051463061, + 0x36ec634c1127401f9a2206720e26e7198702b85deb2314a37c1f06217cfad7, + 0x13e7e74a49ed94c2a714a46b12c19e3ed6793364b22763ae2c28b53318669510, + 0x304fecd133011329f98954047995691c6991eaeba7141494506fc3876cf8268b, + 0x4e860ca205e4d78f0d93d3b743e2d82d77737faaf2704e5540e163aefe75b51, + 0x128cd6494ecba913473703b110fbd66d627440384a6187aca8088de1d51aaa60, + 0x2c7111b9259f4fca63e218ad354e9107e80a436a3e82d62f180c0ff1c7055743, + 0xb3901ec96ea864778a698866a852170eac53ec5c05c024373cb38585977fcca, + 0x9aa27e7fd140dff6a20f7696c85702c3f60ae58e60233012be3996d839f8d6e, + 0x1e3d51555af4c3321630aa1d1134ff631ce25a12b77d3c2f3068a4a981f79491, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x19b9a37490c9b0507423635e95f10a0f27a2dd48b840393432eb41c3fb9aa265, + 0x7783facafa95b276e52a4e6957b6145806c64f5c0305fac11c14095e6770e7b, + 0x1dd174936ad30ba73ea372209ca23d51868b21e533cbd15ffd438c51c9515c89, + 0x1fa6bdba3839fafe0ef67bb8f50f2bfcca95ff34ccdd072bcf4451e1b3a8f098, + 0x2a3116f7f050869bd4b0181245fb41613f482cf81d09b95898f9f813caf7c97f, + 0x2c16907e9d82fe0a3799dd07efc106bf60d114def959261470623220d9d9224c, + 0x3c373a0664f0389702f966c124355796a3819e6fcbf29583b4a33891961bff7, + 0x2e67195c545bf86e5737e4d28dbf075c11cd21965127da4aeac13b49fbadc2de, + 0xe0d816cd83dfd0535a9706aa8d7225342cd76b82d2c3df0425857d92aec38f6, + 0x1d623c057cceaf69f4438d54e954e59f7f04065ab72132da788b28fe08ae403, + 0xd7f30107ef57c75975e5a489dd2e39053d12cf5ff9f74bad3e647d6b4278659, + 0x32f7466d62e6c9dd8c02064ac112042b9082c7ea2e8caa266d04a68f9d9b15b, + 0x2a4bc62d27e720a9e53c02e6519ecdc684ed42222c063c698a9fa024c1bd0669, + 0x2f11dad1623f57beb48f1f781bdd9cf57752dab6fa75b6442db3834cebf6d5ae, + 0x7448b576267dd9d742ff7a7fc8324ddf3f340df575917d1583256b8a26c001e, + 0x10c06e0e81bba5139387282c3883c5967d1ebad7ed164f970dd697de036db5c4, + 0x30c7e1595a11101143f8997b7b9f63d265bb69efb4afffe36eb47ac4e170960, + 0x2081add9a69f880110449f883df1816b141c11bc52fee4c355821501e3fcf05d, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x288949d7c29bca2b52de67a970192cd195390c7ed0788f81d85db64c98c78aab, + 0x2589eefe89ee66a650a27700d7ad9ee3ced14f507536405c21a90857b6a3c8e8, + 0x28ff008aa0b3a7732cd4059620a76a9d1cf8286a5ef84ee4df54b435656f14da, + 0x2155df46713041cde67a10d82c7c13921f0e394bc66eb78f9047782cd17ea643, + 0x2c16fb8505a4a94a7b5c775792cabfa62e014b33a5479a81c2fc8a52e8044d36, + 0x2b1e314362badfaf84b4d272a4b6509698305104e27fd317fbbd0178137cc708, + 0x2c27c6d894ba49e73659ae668667796a1547338cdcf3c35914b3d3e004f935c1, + 0x24c4d70a62d779e831a38a510142c88b2071251f2737dbda104dc3cd5585041d, + 0x172cd6c4cfcaa0085db59ffa6051971fefa9934458a50b5e3b98bef6053f7fa9, + 0x1068776f66d6f04edcdfc6e6cb9473ee2f57d670941e4a191f6f69e7bca61a, + 0xb5fbd532099ded25d17a8ba4db930a0c9655056fa6a01c56e825843d763790a, + 0x20d62b8df28b9d5677bd4f3ac8095772befee8b2b761f9a4a7d9b9aa719209ac, + 0xab9f332e0d0c4ddb998fcd6da668a8f744260e3ea8947b6f6189ca82c5db01, + 0x2953639aa84c6c0feedbc71e3af4e4a15bc408f5cf3ba2bcb98ba5bc01c9875a, + 0x1afc3b62187190e90184c6f1f1878020f0efcfa38235f5980ec372c2d9b4a56d, + 0x2c67d12ebccd059b365736302f01da9088f2a40ae49d88e58c7ecab80621db4, + 0x23a3292e40578b5fe32b0c7ca158b298fc7d6397ca3d46a50157a528a6ada69a, + 0x2d5a92ce3878d73e89d645f35ea2b179fadea64310ff752a48a94aab957cda66, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0xfb3cf3d82f7442edce7ae58c2fcbde983a9991bfa8c583cc9e8675176f5f500, + 0x1441b92ceeaf3e93bb74d84875b7b32f66218d23cc25b747d522344c853e69ce, + 0xc66500308b0fbfef99d8dda3ee219ee7faeeb6ac7c993572c13a93b172c09a4, + 0x104281140d7c64b5bd415c250830aec689e5868c58a2396c8f4af87c06c0a617, + 0x297d4462db9786475248b39bcdc40ba0ec662e5e772f6d07c3178964c86bb6b0, + 0x882cd69f5f1b0c14f1a5f1473f44952e042d81134a25c45a01e4d997761b6be, + 0xa663c1280a5f4d285524e6163aef8f83a42ac4a8fd6d3c44bf01c5f76393e75, + 0x64ff7dc46adfef44b40646c79afa99d0c14ca6bdbf7da5aa322f346f169bf41, + 0x901c9594190b84ee79b7282a6a5bf82cda6d28d1c513fcc679b42c5da8570fe, + 0x21257b75cdd1fac9c5a38abc15274df2aa318adfad33a5263ea3cdb1a1990577, + 0x255cf0a823fa7cbf9cde67161df7378969730138f3bab39b5be3575dd62e8b51, + 0x1d4b1fbaba2e064f59db8d8a6e72ab84d49a8d82f6a2f9fd532caac3530bbdb7, + 0x3e5ecf7a394eb453de6cfd3fe8da36f826abe096b15add7bc22ada6d2ec83ad, + 0x1f068ef1dd48f8934037a95c94b3740ab3d399a0e36cdf8c91adb39ed90c5151, + 0x13b5b483529badcd3ea50b491b6a042ffe9c38f2761e8367eac4e11a85210971, + 0x28955844381caa81ec9032541abdf3f00b77b9a80b9f6e363cf4369e0b1b6642, + 0x2a3fe34d0e5e72044a5af113255b129d78fdd2fccc280f3d6b81c985d16cd288, + 0x8757825685a90d9476b5bcf376eec9556c41811a9c017fcd7d6ac44fbbb8a0f, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x5454d37baa3a2f999a53fb59504aabfee05108628378a3a9feb587663d274a4, + 0x129a7b8af836412572e06774394c69bdae4033b15dcc2a4efc10d5b4d850fb05, + 0xcbbe121aa60c9979b941f94e86121f984e67334708eb05850777184734a08bc, + 0x1925ac7783c308bb5aa53769d434c44de6faeda6015848693c50fdfc7f465d86, + 0x1e24206b35f67393f1d61933aede02c01ecbd9cd12929e48300e37e1def7b1f5, + 0x4276737b519ede14db1b652fc56169408d4cc1abf043d8a9ce90a16447a06fd, + 0x27b946d91e4453a4854c29cd248e0cda329d67a2ea66450d51b57f8b159df5fd, + 0x2cdec054ad08c8c5e31588959e605ab5b0518517fd809d437edc27f33da7580b, + 0x26e434190d53125fc7718bfae9f34f2124d41bb51bb2c23c37deea8407da3523, + 0x519d0e4b6c1228368f420926c69ff37ee7dcf8e3dc45c4e95c821477d075eda, + 0x2aae1f5ea6015e4acf22f950f6620cf74e7d7bb7a33ec09b372cfe562e5f2e12, + 0x2ffb9c618799bbf03e071bca26d130a936a380f74f6e475f567adfd9adc269ab, + 0x22a6091317f474f780d2c4e11d78e6eb875686f797f82a8ba7b3212879dd63ea, + 0x79b093f80d89162556a653dbe714975928ba10cfd5f1d0bd47c0fea68f03493, + 0x2741b4234834eca3dfd3ad4a3064246c4496defd8197e450b8416e4852028c44, + 0x15adc0ef2ac09ba1689bc3bf21e4fa50141c0089d00a80225f39a8ee63ef0032, + 0x168017fe19343b5d7d8476c0936a0870ac87beb8ef2ef9b02cb773dad72d2401, + 0x2dc5d64afabdf089bffe3152fa2b290726cbbb4d52e3e08ab52b1876070a8b03, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x2631312e2a6d973442d5dd7efea28e5073c5cc17c878cc594e2c39dea7a51950, + 0x1ae2f96df9a1a71be2965eb1f504ffe75742ff7f81a45df9086822ea4ff83f9a, + 0x17a4bb48a247c563499f4b71a2ed4763c579ba38009184f3607d9b4b5b2594c5, + 0xc9a0ebe3610863f0da6992f19a565911e14e72687f798d90b98f2c2b24bda63, + 0x2f2731211090929d349ecff21490ef33747d4a402c8c1995b827292ad299201a, + 0x9b7a78ed8d062af7d0ef55e464376fa6a4ef0de0e0cfddb6095156359825480, + 0x28abb1d3e1bfd68df633d19408b66ec34a580540eb92794fbaa033f8eb0e01b3, + 0x1e2014bbd5d2db2f97744448f2d57d1e27b6dfde486085a5d8c128058fa0e656, + 0x25f9ef11d4ff48535b9301a31a5413236fbb50568745d44af96d5d307490eb62, + 0x241b430c52d322bb0971e127e4e68fd3fad0a845f235b3e80bb514a00b75ebd2, + 0x21b6603896d2fd23cfa9b8db8fd0e550decf29eec015b5cfd665313d91014bdf, + 0x2066a222ed385ff7d9620fdd0343bc67d3fe9027c450917deb4c126ab9c5843b, + 0x148ab2277866b9d0c72eab8df30a3abb6fab1610e164a9f2400ea397e0de92a7, + 0x22b514cdab8e05d5b1289978bff23e2aa763565fe504c7e3bbc86069e0352239, + 0x15adb32fd53195fce581f92dad1925b14c6273d02a73ce8a21e988944645e829, + 0x26514ed0266951c35ca0ef8ce1de46874ec132fffec62807e01831664eb427cd, + 0x24a1401fffe3c86451355add7ffe24db5672d8656cf51377c38351f1fef09a6f, + 0x53da14e5e7a25894a0b0efdb05617d4f0922398022d656b13d24ac31c66838, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x23d4d5f42b19c73015c0c481446416d929469dfa05ec46df0163b835b30d08d0, + 0xc34142c7d90f966770924de9bd02290f2a25d7e627ec80bb3d7ba339d0e8829, + 0x15693ac825018e52a0d4c3aef740c97437e4dc3331d552a1c8e4b8a3c9e176f4, + 0xc1d7701d2b195781d2ec69c9c91b532a326163ec4fa2f0dc4afcc58540acd57, + 0x29f55706b8105e02770e12158f34ebf47fa7ef35f2ca62de699524be584a17ea, + 0x15948078ad1c9f08c03facc3daebcba846a02cd92994d709ae047be01ae1c676, + 0x1fff985fd1db0e045d0ac983e602592bdaadc7ee35c696f55da0bcad75e20a1a, + 0x16b370312e2012c15fa0c6b9619f0ce24ff0586c10b4bd02589d2b7b2dae4eff, + 0x2358120a60a01628aebf65fc72181ff9a0ecbee9ae148ebb4ab4bdc9b216e76, + 0x2f1a1712d5a7eeef8647c7a32c2c9491c10ec872fb7a8280bd5f360a3411cfc7, + 0x23b8d022a8e866d4095cac47c7ba7111429f6c08950a19de476ba2fd836b6cf1, + 0x139ad96c1432a53b6fee35ecd66f2b9da8ce4bea3ebdfbd2c4a75961efe0d892, + 0xd1a3762903cf32fffb016810eb11daccbff2d7dbd6b2a447ad32f810d88893, + 0x1e2fcaecfaaa32924f964b021dd552cac420f822a0a71e37c28654221d472b7f, + 0x12102994668f97d887812f0151144111aeb19e748eb198c3a75a9965176f8f07, + 0x2cb68b7e634347542711e393d188b6fc2eb0f6aab7a7cc9177543b3ec6d7d, + 0x215a89522290e4cbc142deb1584f336ad401aa76d058da586baedadb4c0b7b9d, + 0x508c70de806cb78a62250db957fe5ed69e4c335b86635be74a068f200768a, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x3f5d10d3e2dfdcaaaf5d2251baa6e7deef7fe6016e0e33f67413b576e78439e, + 0x5160b38288f77fe866c353e3fc4bdfaf39b54fb22c0361c6bdaa645131dcd32, + 0x1a1f53585e77207de93ff07741144e90b6f8858f6c68d52b62c96efe319aae23, + 0x2c48ab25015e0bdd2cebd18df7edf7766a28d757827818c284f15302df3d0285, + 0x3001d8c6b2c0a9c4e7f80cb2688f909dbb1bce96b7abb884f405158aca90ad9c, + 0x14ba759b81b8115d220b3bb5e077e597f805e30d961d02b132ed6d6dde416d8d, + 0x2e3b3d96803a71c846f5654d3bc43f69edd66885224a46f6c5b67967cd9b0476, + 0x1515804d3972a797545bfd5143cd3d3c2b85b18b734fbfa60e28a7d8024cb8ca, + 0x2122b140a17e84a1ce854a0f924abbb7941eeb8af8831dedee228e4ed462e38, + 0x1efeffb998ae5510b386fe1687a04b18411e23f5300e26b0dae71a1da6a16ef5, + 0xaebe0890cab1a8d389ad98ac4e56b74e1176dde08cd90b0b69037167d221c07, + 0x1392810e135502a38d126a0dbc2cf8d1977357dbefa4d84484d36a4a6e4c7799, + 0xafe48f0248af7d2f35057667e79a08c2c2bffd8225b6219d94e785c41a796e9, + 0x198eb323d5b100e891e9327f661d15848df9f2e3bc2e34692b0c644ff091b62c, + 0x29c62456a430517fcaecf1a752a55dbf245a88ccd664e1c824da61000919c45e, + 0x2817a686e5a15a89212dfdcf69fd15fa73b8bf0a5c5cd893372a7deb18d1a7f7, + 0x12d401440bb03153830e9adb349d891ae4fd80cbbe414250d9f3c2d71448d93e, + 0xfa1b160c62129071551cfdc0d384b81866bda034159475cd5107b92044b8157, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x3046d1d934cca5a2f7039907e78cd8dcdbb50c5e8cab13a78dafcef27ba5597, + 0x2d724a2ce967f1115a32a74ee7cf63760165fc405621008476db3bb65b346b47, + 0x6684ffbc3e9a720f7ac9be9c867f2532240fc9ed20c21430e2685abbae63ca0, + 0x1e4caa2fe0f585e91bf011c1755396d39dcbc30e94aa4ae3ceefd381fefc0d43, + 0x24a9509908f6b0a4aedc444647d1de173078d900d23e2770b410624472bcfe70, + 0xa444eb331e3a9d4f98039f6d9a7a45482ad85d6e9d0917486bae82a5047f729, + 0xcaac550d739a7699d5dabeabd3bdb5e37449e87f07b95ccb82fa742471b8ef4, + 0x4e0c67a911f80f93720ce27d4ce2815f7c4f2e5d234c259fecbf562f863121e, + 0x1ff8f4767dae471c0c2a4c2ef44275aaf07e1e155989a5ccf1e10537f860f72d, + 0x2f6863db06c9adeedb84708e3b7c091cf44b4251023fe8f6bef72d61519e7651, + 0x2e788ebb5af871b9ed5e9fab07da7b58126109807e5915e6f54d7cf7dc79199f, + 0x2cdafe599e42909bc0475abddf4f10a4f14df5a2c0f429bef913ced315d116f6, + 0x1b0a72225d8796640b16fec15a58e11d4be5a9a473d1337fbb495ad93b432f6c, + 0x1cb387a29a3345bbf6cc407a81958e61fe98f7708f40bb8b96741f730c7e7081, + 0x15ef88ba22652780eb14b3ab276c1dea798361f7631344cac3e771a16910179f, + 0x26893d124895c43a1a271e72a5f99c4fa9fce6ffa7bf6c31e4926a4efb888e67, + 0x9dc58192b21af8f6033bd84e9f5d696c602e0bb4c924f790b27df7db675049a, + 0x1d659f67ea472288e942baa853889e47435056a2da4398acb9ca288c2404c7f8, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x17812ce47ed47b09cf9fed086e7764010e70afef63a806d9890a0c3113fdd15d, + 0x5bc448e17449644d41ef38b762a183d1f9c0bd6f6008b4c902ca3fda45d9e4b, + 0xb8f14bac67ece8b1f9a960f436bfc6a75ae541945689bf78b89e2d768d1b1c, + 0x6e843ac5711fe5e7551ae25506875ba9eefc93563d15e03f15bb5d6e307b294, + 0x37c5948a6f6dcdd4378f4e6220a96e4fc27c8fdb102c6f2fe0988b199ad2860, + 0x9bb55e5908b10cca78ddac3e7a880cf469fc418c8b0ec0e2f96220fcddd983f, + 0x549938eec4ef16ad9d89081f27be2a2c4af49ae918988ae5574965b506f0126, + 0x13b4215b89af0652d5598eb29b34ca980cb1a1eb44eaff0e83ed8b6ef5c5cb73, + 0x2d8f43577fb26728a6f2305e2f868a4298ac5f4bebf8419f072cf709b9bf6979, + 0x58782a9e8860cb1b60314d2b18e437f36c169b5362e07575aca80c3bbcf8242, + 0xf6ed9ca8c19eab0c5100e7dff2a1e4d09b3c2ec9e19a9aabddfa4de4903cbde, + 0x11c3ba734cc607cfaabc73f220cc21f2422ab5e31d04818137793092015a1150, + 0x1ecbe5795e0f92f55c9784d7687271c7f1d99474a4c9f66fa41618d17342666a, + 0x2ed6fa55a83b01452c9e30b9888dea9544c10db14356cace8dcddcdb0a2fd223, + 0x79287ad9db6ce54e8902962f53403735a76fb7eaf2fb92e8fc7e6cec890885b, + 0x2e26aa5ce56c08151e6c8457e0ca280a1cd8117e7b4fe6895058b964859d73a4, + 0xa889a87584a87178ad4b8ee2230ebc06301c08cf8407e631e71d6467079ac3a, + 0x9c2891001f2a119d1126659c30f6123f65be071bf93729d2a76d9bdd41798ce, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x51fce24183d75c4dd506c99b7be05f0d326a972645730c2a76babdd8c7992f8, + 0x1094ccf4dbff390c02df760b78ae8360348f9ceb187059aff7dcc1a3b5d9e8cb, + 0x2d4966667b830669b5fcd632c6f3cee90687341f51653aec9f0214ab5db4a847, + 0x1b6e79f0b003e313be5fc611155d4322d1c56f22957bd201a45b53854291012c, + 0xc9d7ef70784cc153f1a325031dbb8dbac58625dc7610fd453c17cf8dee3b489, + 0x2eaba31d2ad4b02948ea76ed4d931d5a42683adb9edeb564d065363190e766ea, + 0x3af6bf9c7eaedeabe073487509937cd73b00a8fa5aeeccd8d4a9b9ccca1666, + 0x24d4c2116faf69b99c84e389413f710cef10de5cd87c041669ca51c21f3b6318, + 0x1f5cabd4bd22948e2c5cd975f92fd0850731301e6291fce364d7f5d951157b0b, + 0x32aaadbc1decf6ecf33b074eb63f5fd75bcf94af261ed3b75e049d63dbc66ee, + 0x194830799464f8ee702d72e41ac3aca3c4ab419b02428605b00829948a201752, + 0x1a88bf75b55c097681b6c07feaecaea5a7e7a84c2d9b549381c51c9b0cb64532, + 0x2c7969063d1fc97a8d063049637ca6ba63a6cdd9200b95c1ff1c941c390b89e1, + 0x79a0abd9ba495c5859ff6e10ce393b50c9f04bd92a9261ec1ef7f99f77e46cd, + 0xaf8f7e9f3eac9e6e82bc956dd7c53bdf91272cc7ae955d734c8f9c6a4e7385f, + 0x1f45d6872234334442f08c99bce292c089d3f34f4763419d02ca14f24c4b1b8, + 0x3a4a9d99286b1752d6cb735b9cd0fa27d4f1b8f0a1521d18d1517f6148b677a, + 0x19484e61180700e93699ea2a7d64814841cf11535480dbde83f6936f5ab68fb1, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x68117f11b7f8d736af79ab2ae3328e576a95d12b637b944cdff9b5758499915, + 0x118a504d77cc49d22cf454a7cb3d9ae8049efe9447a78201468e90ce576da872, + 0x1e21ecd473c3deacf25a495ebb4301092012529381b52e0d1286fac898e3c370, + 0x2e38b65fab0ea1b8152773205f8d39e6b81976426d0d64cf48cbaee81818ee56, + 0x19414eb55e2b2717e2affe4f6a520a87977e938319b9b49d02db373469bf6ccb, + 0x1f04b3026adc9f2f0995631d4ee83ad3910fababe4e78dc8b211e9c72084ce4, + 0xc1cee5ac82b0ba4ac8578c934c415a0f2a50bc7521d2058853b0a59415f6f72, + 0x1a0b86be3ba0c37e5fcba4f8f33d0af3333cc3bfb74aa262d3d484cbd60fbfb9, + 0x277f4d465b4a3f950592907b651c5ada6dbad43f7ad0dfdbaa4b5c0edbec7e4, + 0x2cbc8485f96542fe22965a7bb768cfcf79f4cea845cd70eaac0f6c383f542fd5, + 0x13b306fd43acac725673d286fbabe249cba9a5194a6b2062953b75149f02cd19, + 0x19bb715b15ee11c3f973eea2656300c00d6d96576c3724b070f38a764cd58add, + 0x2579c1bbae48a8bf9c43de695574e7d4576c2c73358b18dd15a1673528fa4d21, + 0x29bb732726698d3e98745354beed55ada619a0d0e5b8d05cc29f0ce1bedf01bf, + 0x101b8a972da8e777f74c68fc481c37f0b999ef0df3c90b6505ab2a6527c95d77, + 0x28d282b4a80e8079287ad62249731647b36221be836c246e9176c6e243623602, + 0x30f5a91d4bd3a7a00ccfb936619a49c9cae07fdd02d5f7281ead5ec765a5c68, + 0x23aeb8d675cc85209a4f47d7ce9374c6dd1bdc34caedd947a05836f8f3880cb, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x13efe2b7fcf22b13dde356329022c10caf94d0a67e448020cdf70a2a1bac2de4, + 0x20116d8a08ef558a247c6f5f943a982d94b63e8a1580c81a049ae62db7550d8f, + 0x2d082ae4142d9cf00383067665261118fc20b41dd5e3844d95d283ee935fd9ce, + 0x103520a0cf36cd976f2243249d25d74bd11b4afad705051b28f5677e7726d5f7, + 0x1e820f7db38b24a06bbc3dfc78c47d040c9dff7d8ba0160b522c6313c107852e, + 0x275832ae1f1cd86102dd968a76e57d3df95b5c1cbb1ef28dd38fa2bef749dec, + 0xece66ec104a392cd7d1e5a11f16cac7899588ee5f523b93f779b80f56ee42a2, + 0x174586e5d012f172439b4d437e58dfd9c58e7d29ed659a7471f0b80151dece5c, + 0xcc17b4f871cb91bd63924098c54be2744a3131d8a9ad21b1a55069f005ba35d, + 0x24e6611ad441830b7fc88414d4902bfa9043e60933a6d1ba6e12d6795c3c1b37, + 0x9392f480df40275b9d639dd95f8a1e0a62fb3b162b41efdb5625c90155fd3a5, + 0x19fd18a6a69d2e9327fb48fccd6e0549395b2c9362af152d9d7e9901c68154ed, + 0x174bd47eb0d06dcc5f5121b04bc3c61e02a262ef3c77f11c548b8f2580e664ff, + 0x1be5877032c20df6d798e8bf265fe511739db9d9b1042b2a9843a261cb5a53c2, + 0x263fdff0aed026e3b8654e2711dce2aabdc81bf44695f0a6694ec29174392aa2, + 0x1f71c71eb6f683d7b8516f7de5b5f0ebbf0a581077fde56843c0dfaff80acad0, + 0x115b998963794a6c504dd65e1b7d99ff4ccfe24b04462b5788cce32861eeed61, + 0x17f43dba64c1eb81be96ed641cf7801b3a45c614ccb85daa14a8153d4e57e6da, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x1e1c19e05021208ac3fdfe2d3f116c8e72ddd60fb5530005656683f528bae627, + 0x2596fa2a97ea6905c598c64a25768fa5bde504ea3004705ada129f936ed946ea, + 0x429be063b1c6a85e848627ce4bdb658eb148f89887b08e4699f37e1c4d63888, + 0x2571cd3671bb7bd7b52cc19e2291572e4dd8f8d077e295a22907d15cec049643, + 0x23e2edfaf71fb3796d9f00bd618d48df5454e6edb91a509d173c431668c494c, + 0x1a9b4db70aa7cd04e33a10c5f4188b7b7546ddb4b4215611965194caec7d961c, + 0x115d0f27b177d1bac2960bb00feb3be427e4e0184f8f6324d0a06fb47ae2366, + 0x24158958a69587f1c15512552045620f1fe1569c9f3e3668ed06dffbf0a73686, + 0x1c6761dde78638d734eb9eb1a1b33a98cef7efa4255fc3662bae703182c01fb8, + 0x2750d8eade4dae97328c60a645fd3c8431d96ae7482a818b0ae3b4cc46b9bdc8, + 0x1fd32b82dcbeb8c048e9269c2e53002f6b7fad13aa737f386a6cdfc1e2c5a9e6, + 0x594fc59fe25d24b2545c6650795cee8ba30d2ae04dd07b5d676b089ddbefa9c, + 0xc84ab77e8af0ba2da61c55b53cf3534e766735740836aac2427587fbea5c8bd, + 0x53cb97662f38bb4b44b958d4ec02f8c25fcc795969bfb079e664b87cef93dff, + 0x1603ca0816ddaba4cef9853184cd3a94d6c881b73d2d6d893db88a48c3de3447, + 0x18ea8dd9a27ca4410a40bc8becd0b6d42338881ac4c31a3ba7caa40cd1b56131, + 0x1a527748bdf0057723c86acbe4909490d3e2415647a82f1461a42f3296bf4c07, + 0x14175f91c0ddb823543a0167ffab7bd8c50273090aead801da30b25f4550584a, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x25f932ba4af84ae43ba5291e604cf8ca5fd208fd16b78c38eabc57286298d557, + 0x25475d7d649f8bff2630d97844bdc0fe8df6efb89baec75e5ab9bdba2777d431, + 0x89f1655b69d28450d05c9dfc610305d46a77dcd50eaf28042ebc878caf30d5c, + 0x123980c7cf8538b96942135959a4af1708aba866cba105e1f5a382e9bb6aade4, + 0x78cc219ae73e2ecb4025d0e0d90cf09f82f948a63243ddc062872b1070b6b30, + 0xcda20a3684d79a2e18078fea3261650a2cca213f705b56eeba2949ca203b816, + 0x21b9c66d1190ff2ddb30db322ca2508d231f7aaf8f7f5f5b95bc1711a672ea6b, + 0x22016741afc2d1ee9549ce4b74318bef293bb2b2d6495d424cdf700060dc813, + 0xd722902b755cd16c7977247cb28068a616adeaa13c00b1e2ff628c892bdc6d4, + 0x217793a53d0ac28751e3fda8caff3f8003b084c474e2458cda30330e338e22c3, + 0x2d31e0c6e311f327b0e780f291a81e25aebd9660648b0ff51fe8851d29671cfd, + 0x216d14211de9aed77200602ed78caa665a310ee03fafb5b993ddbb5ae2230f83, + 0x2681c24a56759b77d5e0a7afd37d286ae3422745564fdc15d25e0dd158c9f4e4, + 0x1e3b6edad3fcbd9d991c34f5e4d838fb76c255542d27f82d58989912b5bc7dd2, + 0x2eefb7b5eb265aa610c4356f2282dd92a03744a1b8484dedb115321df7518c2f, + 0x5a848b35a8e270224242f52686cf785d9f11ec3bad27529c02f6448a432ec41, + 0x9ff782048c9d9aa8690ed707e82164ad320e1daf646a3b30421f03dcf772423, + 0x2b294de4467526f4914af8f9895903124f2a91249c23e8d012a04e3b6fefd504, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x27d44f13d66a77a645f895ff821ddcf8cced8c8af984dbb8cf82b84653a5db10, + 0xe50c72da36c1a968102edf30c6b810795d41ce41c49783028cd0830acc37c98, + 0x2341aeac831f989ac84a00d127c0809fbc0040495ad77e1d1f589cebe120904, + 0x2071faf6e96fb5cd4400b6c58eb4ff5e527bf7d9492180bc2f4534cd0ae0679f, + 0x14da2ed4e175cc095a8d68ac6e7f9e2d702e82b1791204921bc4806b157be02f, + 0xc6232c7e84ea35400bdc0f7b8d0cd211fb5186df1fe8e927bc51ce0247d13cd, + 0x1f65c4563e9f61ed7f7f2eb3fedcde581ad3b660c5079c16e7ddb053facc5396, + 0x144675f4c54bc33e1bd7aabe8685c740738cf1c7891c5c659b07c6281fc67a8d, + 0x14ece2c3c47e0435cbb019db4708ef6c904b4af975d729a0fcd75e65abf744ab, + 0x118f931e904fffde6ba4e22eb0429be857819f9fd64f1273253b3f152fa18b0e, + 0xbade4f966d523e4656c44854982d4546abfe2f5dec203a45cc463da1093ce09, + 0x1783c94f37d6d9057a1c2e78e0d0f78efeb161a14dc2107a21661829f135d226, + 0xdeaffffd0feb209c00793e5f800761b5419d8725f4c88286eab224160ec43f1, + 0x8746a72fb64c2cdc1ef14613cb535911394a29c802d4a6a94cfef844610c609, + 0x4882711fd9c5508fdd0a1ec5a2a0810b93a6cfce441a192047a827f58ddb2d3, + 0xf2b738d3eb3b803bca325347b7af954cc10492832479183808b3aea72435c2, + 0x2b5d5eba00e09e21bd9202d72e53306361608eddc951ac1f08a53dc3bc6e955c, + 0x16d96e78a6078437404b5bf21aacd5a43d23ddd5bc2172412ad36390b3ce4512, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x2f6fd52b25a9485df2878599be34808517d5eed6c1d83ce497e1a9ea8d1c3844, + 0x2f0dc0c61f11a53d419b3fb805fc2d476837c53c1c990c66fd1539ec9d2e4e44, + 0x1b004ab51f77388c427453263ea600792a6be597e6f736509c2dbe87d4a298b1, + 0xa690789ef915053a2ed12aa90a8621340337bcae525139c9e1ab973e1bf8881, + 0xc925171c7431dace3626b7e5036dfa622bc08747fe849d6a6ae5c831143d104, + 0x27e2a355bcdae99405fcd39ac25b9ffe773ae5b0ed9a87a9e470715fe2bc271, + 0xd44cd56f0210228281e116260bc8aabf64fa0701601e98781fbc6b14faea9ed, + 0x1ee8d9f2950080571a9605c7b454c3480e64876ad27891241b8f62d71d6ebfdc, + 0x13edf09ae8addbf851e00d79fe8b990277b431d72ce0d9b48b55e3095b483bfb, + 0x1d2c7f3a44dcbed040fe5f5dabd49064622c34af68c5b4afecf631fd998de93, + 0x17e04fb5f49c12a6a91bec113708d943cdc774e64c6ec431bdbda3a6c1c0f57a, + 0x21d9dbd68c54cdb2ea8beaf7de31afad1cd404c478c62e8f59653895909a18ba, + 0x276950c5f6c44bacaee68fd94f14a44a07a0033515b10a76203ab2b12bd60440, + 0x2ca5b12a8ff6ee0156650ef67333a07ff08b156454897b370734c4b98977c6d0, + 0x2379fe3fe77b505f5fad59cc93f5fed7624e99f5359c30d56efcd0915460668, + 0x10e790cb3f6be51c0b4fd7f6e29519bf9bec842ac6e0f6f5584d5cc1431b5c56, + 0x20a94567158dc5f7b21cb0358dfd6fcf75abdd806b150bb4ef55756701d568ec, + 0x191a6a82b77415d9a305c90b8189e93ad9d915a411a544d0fd090a157113d557, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x2ce2a89b4c51f97166c6adb43491a88c24a3276110055a0deac88f7e71f976b1, + 0xe85242efe6b78087e6f76495c7bef828bab7776b3b6f5b4ae77b9a3d854933, + 0x92654dcf9e69fc2da394139bafb0592b4cae24d00e34981bddcd4b089dd948a, + 0x152d35166a3e900ca89d58fbdbe99caf3bdb1f984deae8e02cf703dd55e78a6d, + 0x250159b61c5e545befaed62a349cd00e1fcd3ea588f29ead5deb675a0101d936, + 0x1e66442753c8d95188bb9f59bad17a6ab9018f052ce8e1de58790b59bc4cd7c7, + 0x1a91965586db156cc0d4fe08208ea762030e390bc498435d3a04d41b95e854cc, + 0x205d22ff80ffd23060ee1aeb5050c709a63a4eaba0847ff587171db7d9ef27f8, + 0xe92e1e54bc59e642a77b5333ddbb2e15594a1956a3ed0e2605dbfe4cd29dd9d, + 0xecb39d5fb42dc2dc2f2b74c13e24307a1f3be67f35ab79b0ac974eaf4a0c41, + 0x77aebae118635d5a0e0160df4961f3c5b796887d878ddcd2688fe1d618150ec, + 0x2d0db6e2eb4386d10a3719148038523ebc7baf66dc538818b0b5d843002e07bb, + 0x1dc7e3849dcf39a59aa7a87ef122afb09009aeeea37dbdef6e850e57ea37f604, + 0x97559815d3b62c28056095e39c8b1a8e366bb8aa42af85f673e45273d0ae1ee, + 0x7e08fce9a5121c2188a96e591b92b958da520778ac0bca67b59da2b3b06f0fa, + 0xe3d58fdb4543949957ea33bd03e3abbfb109a1691de6696419d4b1207f542c, + 0xc991fe43818ea306d3b776847d14f4019bca2070d200e07735c62da31a3138e, + 0xaec16bb8df541908f11df6a64c676183c76bfcaf7748c503d6099acbb3f2a9c, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x85b7265354e883298caeca1761cd19e2c5c2119b36c37d6f5d666ba8ecbf19f, + 0x10d7d5e67042939ab9d5eed4d520c3fe081f9ef97b3ea8f7ffec5d5e1889e031, + 0x1cfac1f08b7bc16a7482dede1d624a8637eff2c6f5b38e5fbeda6f6bc5cea6d8, + 0x6b10274305c15e9adb7f7fe7cdbb4071c1e4968e46e461c6642a861d0ee68fe, + 0x2cf401be1c32c95cde4ebfc65cbbea9c09f9632239b314f53acc63bf37d86a56, + 0x2fd0c9ebacd03258bfb689a7a700d43b1fec422b22299d73e478801d9533a36a, + 0x4ec21b44c21c6c358789f92b5d126597e1b60f05050975b924cd7042087e630, + 0x2d42130581a19be2488f98c4473e80511c275be79f5077db40b74b43881eb4db, + 0xdf73be8b64e045f882edee4f17e9da2c5f25b2859e904595844adcf3df8f7f3, + 0x1b05101b32ca2be2837624bd01f437abcd43cf6c4b561052e0e6df3d5f0ee39, + 0x8a4f42ecec6f626427ce116b20f3405898759d0531091a87936427a99d5c919, + 0x67eb4a3514d45d7e6468f85a7a606eb86395bef7b23018f25e133f7416cfe65, + 0x3037c22112964f6f3d8e4a607f1f35ee562d505e4a22fdf24b41e6c03e506785, + 0x23c4745c095e5970dac166326b875df52d94db0c9456b5afb55077d92996a8b6, + 0x12ca85b142f5d2d2d87b44b4f190810b0a2ef1cbb96ffb43fe4094ac0bb450f4, + 0x262501f3e02e6a5c95bfcf11749917b22125ff7d02ecdfdadfa374a45173c662, + 0x2c3ec00db9c8e44aaf94ea99dae52f7688c663f0b42d186fc1d030813a4ca1b4, + 0x120aa50356c54653eb5399b101bac1eeb8d728626800003f8858a183cc1320f5, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0xb6c1dd3d2dadac79672ca69e272e4dede9b2bcbace5d12db15fd6c855bcc7f3, + 0x1dc5cfb71f9c9ff08886866b9270504c330bffed807e5f608839afd49bef8961, + 0x2ba9c16f49734f3bbf98296629f2a1a4e6d1b10063193206528ea39b11869cce, + 0x21c37ce612e1b0d5fcb0271e20f27c062dd81f2c8efabe92c73f54d87aeca299, + 0x29ca29c57a516f80006150ba546d332ace95854d3dbbb9ceb57a80f221f45b75, + 0x9644e84f727604d62f2d77c2d5c1897f8b90f362740a8c6eef25ed898e18ed2, + 0x18488a89e78505a807ffca282555f117bc71bfbbb9443d7d06e3060d9798728a, + 0x17f99a49abde27c74d8fe51bbc0a223591121cb9c0efdb32a6ef4bbbc976049, + 0x1106936fe4d91cad9dc00af8b85f8dfdca9298ac4207788a47c97ebd5adac9aa, + 0xb19213f24f13dd43d620c6d4fe77574e3ba66807d606f96055af06344a953cd, + 0x284fb79d4b5bdeb823b0a7e93566380739c2ddde6f2c1cb102f491389af88601, + 0x2bee8122aaeb513f5cd47546f15090cc6730e39d28df08a9ef4f0726dc69a1d4, + 0x109712b4385f9d1941bc8ed4cbee06fece38379f962681ff1f49f2c7577aaf01, + 0x1cee8dbc9e7c22eaa815aab454705b2c2b61ccf56bcc5181d8eb9acd08a4b708, + 0x123f9868d7ebd3d7c576a79f4bb3f0f6f8466aa50c642b2b8fb2938b2533acb6, + 0xc0fbb5f96f795f870d7a4affa961ab0a80a95f9814f2231debbe27352088c5a, + 0x3b268cc3e3aad22d4f8e5edbd7c5179e219201ba62987e3b4a5aa484a30c651, + 0x2e3ff582310fb1449330c0dfed129154d2f8aec3871d2d593b73926a70d8e5f1, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x18b0d069fd19a7ac7776eb39fd607c75bd860a3b2fa17f90f1c016881eba042f, + 0x12f75e7771d5d27c66ce2bf10cc3e3d6d542f3d39f1847e2fa726386ac83c28e, + 0x107b04155a7d9c1881def05be1797dbc8018beb8fadfc9935e569e2f2a2aa474, + 0x17318bbc96a3594382626c795cc986dd77a81a983bf0bcdc9aa59e6d71a59, + 0x132974c4fafdf621f1fadc45daef9bfe5a92a1b59d33056448a125ae2654d20b, + 0x258538ea87a962769068037de62fdd272eab79bfd68489fbbd478a7cb72e068d, + 0x2cb1201c76a7fa15f79b9ba6ea261d17e0b62c2643709e0f984c937c42115e2c, + 0x2e65cfe91bdd49c663d8749f335176abaf6377f582d48484f6748e24cc816647, + 0x2cd3d763fe99f1b6627e6352b95ab5489d191d0e5d41df07810fd7c52b9db26c, + 0x27bc4a5ea2a66172650286cbea4ff02ee1869e854ed4fcc270c8679a38cc8ef7, + 0x88ff579628efad419d54070c10f57b7e69348ae96ad0fd68b5daaf303ee96da, + 0x1cb43928e58efb24ee214ce17d29752fdce31605fe517609a60f8d2edb3ac6ca, + 0x1dcbf79109a7193b75fd86b82c1590b31abb899d0fc5da91e43fe9cefbe45a4a, + 0x2758dee8dc30394bbf30a412c6dffdb1c7b3c1588f4a93e9620db80265e128c3, + 0x18d1cf4a6c8482ec7330af0eafb66fdd2e4289ddfb61c36f76fe87c3648aafe3, + 0x2485597cfdf560f34e11989c881799ceb14143e0d5c4de20ee4a407904cf1e05, + 0x6151f2ab033782abc7bfd3aaec47dd9c428681acf32d745e37d0be4642aa764, + 0x6d2e5ef950f679c0195dfda3966ed8f2db4ccdea5739731627c012a453a9d99, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x2d3138fdcbae36004b71f47afa0ec092b328d2205d4952b47e9c90f286787d9, + 0x1c8e178d93f93f9cc56b13c437128dab31456360dbe2415edc316dd0a4cef579, + 0x25bea2246bf9516b6fd6299407d737b445cc6e2f158cd5944c194852cc32956, + 0xffdd4b3b72bb34089f3b91170fae0a6560efbd23ad5c76bea5e8ce46b7c9f3b, + 0x7c622418ddbf99ba65d8ffe6296f3907c1589d4ea2087034bcda1f7c52218f5, + 0x170dbdbc927d2213df51e928d1288f1bb989cbc074537cf64485b5ff05ab8f0a, + 0x6111fd3b375eb2fe504987aee580cfd1acfc7c39cb7a9171adedaabfa2656a2, + 0x25b706a850ee172c03d98a8a1a04dec56d264d07d7995a7bd3b50996f552f9ea, + 0x13a5b2bbccfed9c5c5f846496df832e8b3166104a183299b87cf2e0dfff8964, + 0x256b7b5635f25f506009162f09e2aeac9a24a22d194db0987e9e0196bf805ee2, + 0xa0d91ff25cbc2ef3a667475f91299ee679bffce4ece8eadf3ae0e86713e6c4c, + 0x1f799a5f2a9fe2846d8fcbe9fef4004f2aab2cfbd8380486985787f9e82f739c, + 0x8f8a5d38982c8c9eba1afb2d463d9b87cb412064271a6d721823ba76b13786b, + 0x13f2f9a571f61c75b4485d9f3f74d84222f1d3258f5446e9afb9d82bbccd5c5b, + 0x1ada050207bf232b77af0445cd3ad24ac2856a32df135462c196b718a4e2818f, + 0x2270c97bfedbe3b54bcabf5df1b60fee20cfa8b1dda8ba4c832b580d71930c59, + 0x17e429879da51390e1253592134df6fc0e6149656142baace891a5ac0b3dcad3, + 0x2ca1a03e86b8e8d2cdc32f998a9a2ae3d604104dad81ce44d7b70b7d2c147b1, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x179e9cc5ce81c3b957469968a01d8f4155d1fab43566892efeb4aac8e730bd1f, + 0x245436e222f18f0a95c5edfdbe70beb3cee0bbe4357c0ad27ec637b8276be10b, + 0x12082995e500dde2a8f5e3db03cfb08fef2e717c59536b6a48a757fe897af0b7, + 0x1ed351a76be7e560be38729f4c221d52e1b2e6b1c9a9906925d9d7fc659af29, + 0x22cea0520bc1691068292d1320ab844c4ff641bd0f3f8b3bce4e50b5302d4291, + 0x10d8cefa20bdf64f680f9f65e2f7f1181485743849125ee5009bb535fbd6737b, + 0x7cd86f2f3733907b2893e812f536766b45c7590516b8e0da820af563de5053d, + 0x18f7e2b8ed7ea1c7ccf0675a588747409ffdc5e0d9a1bd80b54bf47833ba43de, + 0x11ad65aaa14357d137232ee3e2460a65310bfeba447590580d165a80bb87bac5, + 0x149ddeff968dd3e4873a88f82aab2252e424934d62cecebf3c05e04101232c6d, + 0x216e4879dbeb136adcd2e2f9c79d1a899123ec8921531fd19e8f3db769e9b9a7, + 0xb32ffdc93ba89e798035496aa0f0e5f35173420d9605df5c29176b9c8fea9cb, + 0x10059787e4b7b91491cad89e95af648197aab657bef0347224aafea1bd70f0f8, + 0x11feafbb6d30aba9905fc46b2cfa8bd5a1cd6685c3411924f652003f98ce61f0, + 0x18737f1b8ed644fcd203182f9f71ec606dfe5722848319eb06addba0862192c2, + 0xdb96451b25bc2211c315c94b7396080febd132e48883ba5be7c6352454b2531, + 0x14a12c8868c6998c77975fb80588dc50121cb3fe9070179f48ff086ddb44cbec, + 0x64f7699ab015d1466ce5ba0fd8a92531c592eb91011e024e3a90dda0d38d3c4, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x27370d48e084e132bff2e3af0f91f787a9648ebd4fe7cdbc1cedec26c11cff0b, + 0x16f9385f9edfa3dcc7c06b94ed2c0d8609451634db5a4e6e1997cc144e1415fd, + 0x148bb2cb914552eb1ce755beda59e784541d31b0b9743c10e7d6d798afcff7d5, + 0x2e9181388b5eb930247bb3bf036adace30496887c3fe5e51a08501a57834d778, + 0x45e39ea727e4ff254ba2593f698f79e8e4b4f538d1b263912ba9f0d572a8eed, + 0x1174f11359628820efaa3cca1f5f19974f475fd989692911a7dd59754df86a59, + 0x2ed2ce65b2ae9ab3e5c33366e50e7f9a2622b21df40b38e6f0606ebbd6399143, + 0x14a902e483b773bd59d298c316ba79c4abb6bf6e625312672fc529ad2e1334af, + 0x1e68f7bd5130ceb11d06b8075b2da5fd09c5e2401fd816ccf5e6b14f3ce77b4e, + 0x29827cb7a70ff0095050678d19f2eec6994c2db9aac20c2328029b37cc1d94e, + 0x18b67ae206c91b0907dd5cb14430d2d00b7ca10382cfc464c9451accb64b3da1, + 0x1bab9c538b70fbb24712c9c9fcb250b2725138131fc8887dd31c0ee10d7853, + 0x1bb888723fe04304ff56a7c1aaa2a13edbb8c6d9b84c95c34cfaa32c44cb18e7, + 0x15b938c5888d46730f0efb92f3829ee53afc9b4b9b3e2a58729c31f21c078085, + 0xe56668d5e18b59ed8afb9f3b66f03bb0d8d0be49b2ff0ee4cf05802a6840a2e, + 0x286d890c9e0b00dc5a3185b312d61f861935f4cf230267dd147843d085cb9814, + 0x169b367b1b5b432d3e5f13374bb46fee87ebddae52745969b4d80b371a52984, + 0x2616061981a127f1f90517d00c67ccf537e6a1e60f76e2c18ceca5b4fdd39ac9, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x2505d3c4eb01aad3e3759156410967fcb1309f9028133f32b61fe8dca05e7039, + 0x6582da47cd85c00d4e318a61669afe8e1969d2c486e76ebe01968bc21302418, + 0x41b8979d269f6ec28ac184c5b2f02af58c26351c6cd943cec6adf2369cdb1e5, + 0x1443d53abe81ab259cbbe0494e98dddbd8284c1145321c2fe24b0fe672cf9115, + 0x78377bdb2570000965c2505997614b99e6affb63d0f8ac1d8909ffc8c2b7826, + 0x21343622cb874753f0d2c35633e7877c6f2f35247f080a1b0ef7012721579271, + 0x2726e864c23bab466a4e2e9c1e6c90bccce6114a31f4283b8a87be3eefbdac02, + 0x8c3cb7979e51a25092b8e3667b5ab696327cedf1db257537071a718d7a4a347, + 0xeadc7f0735863ae63f6d3a2d980cca143ddbc94203075b1a9341fb52b54e7b6, + 0x302733698edfe476ce1360d9dd8885e2fac48f10fd9b6aa494ccc84663016071, + 0x390d135ec3fb0cc6bebb4ffd755406169d4b71ab559edfc3d03da2739f99c35, + 0x29814b855ae75985f8c5a6475383bd701e5279d430aca51d87671614a2eec37f, + 0x1c8271bcd402c844d59746fbb8c809265247177b175fc929101de73f741709d5, + 0x2ea7af5aff4c8335a4556b1e621c3fb76e507132971a4452635d76310c241990, + 0x3758c3722cb764b0eef270fb45c6c76b9d03816b0feae879a3436fdc9ba2abc, + 0x2122e9a87a29841216a1c1e5dcc02363eb1185edc68f6eefdb38fc43454b588f, + 0x2e5132a0aed649314c6665d51926a7a15bdd6a1a5c6f5134faf96d52caadd140, + 0xaaca5b7aa27811dea3376af9fef0cd8275e8f98e235db83ab1361b4c49a834, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x203898b92bb3f8344f220e9f0790ab77acd669b383111e300fdd94d560eb661a, + 0x1d55edcfada4cde82093e306a8a85e703e70d62f77f83aa4158c7ae06558e2c3, + 0x1c57ec21152ef1becaac482ba2cd28adce9bce68434b291a73dafad3a2a4ab1a, + 0x2c77f75ff6857d39dc5e0ede6ee9b6574764e4ceb3d2235aafaf9d8c296bd1fa, + 0x264024c571ae242f530a593ade47778e04de4fafc1998d04196b3f8dc466b672, + 0x123a17496bdc1d2ece7ee0ab1632b43c278328056b8609eebfc76de77780e8b3, + 0x15d806ca8c7a7c727e02ed3aeb1210453d4d39cc3f2d188f421b58b7fb9b5fe7, + 0x2938fef22503472ffde7a36b04c4b36b639064aeb9d77fdebff756e82ed8e6f, + 0x1d5bd19b2c05765e3c4b83781b4d0037fec97bda292e3167002587051efd0445, + 0x5a5ea7612d82dbbecd031202c5503ab73cf5ac0eceefea81ca45697ad5dfbae, + 0x1dff1bb202e9a71287d999a4436ab81298e44daded91984d6422477266da4fa4, + 0x1a65f01a835cc6df08fe1168ef8dc72e04f3c84bc4129d8b1c57c7055fd528dc, + 0xc6bfebef542cd78b44786f865317d384a64ffabde52f6a5bc29f405d3e45c49, + 0xa06a55ed8f52246944ba9e1b351b0f04e95e8e3c80337f7bf4c4cb3682ccbe1, + 0x237af0b506f0185fc81451144bdf3ccdf7b66cbe1ad77e2ce4212f62d6271006, + 0x1d6b421f3143a560e5066eca69e6939c13cb2fb22bcdbfb96e8d55af76d0a7fb, + 0x1ea4cdc48eeb87bdc70e034a0ee1ce699e94b5b1126776f3bfa43c2facbcaf12, + 0xcfe1b82dde8c5eb500403f5ddedf6165106b28c70cd941f1b65e49725335b68, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x10cd524d82fe05ba307dd3aab96a838f6b1fb98e10e284ccc8f8b2b9585a647a, + 0x29069f8a102d5fd5db23e1e81b42867620f6af7e64b36f7444176a9febaf9a1a, + 0x3021dd41004ec315704a8d77ab12c93d89a3baba330666cf8b96cc8042eef1b6, + 0x173dbe8f25c7fa7ebb28578e0fd3103fda835507d8b53d905189757d6638eb50, + 0x1ec7dcb5fd4210ff0361f44b48f4818dfce283dcbaba35c96d77ec9888f43718, + 0xe52deb0da59b5f92497e0ba6a2a358342a8d731ce2f8c19c8df9d58ecd818d7, + 0x77276a2ab3c0fad69733ad1fd53ca148350ba77681b6bc98a0cc52bed3ee671, + 0xe62986c860d75a4502cee8d7d8932b7c77a9330c4b0884cd7152383cf21301d, + 0x1977e4ab4ef72d06317496905d6cde467a424f82f7491ade88b7027645c05600, + 0xe5fc86e5a4aa5897a6653760a4e72555f0ff79de77d4de9f5aa20db5afbc65c, + 0x133c080c57426c50ae24fbe4145ecad201b964fa12abdf7ed16ba45bb76c0d56, + 0x9809f0d9404684e91754565e4ed714b4853b2dfe29e44aed4df3df632f9664c, + 0xb9ea2ad9eb74df89ef8f3132245aee0f0d0b3c91975aca7660071a8066b9fcc, + 0x2bb6bbb4b8f9011e6167cefd64bb4874f6527a7eacdaa10ef403474e332824eb, + 0xe7505f5d74a168934234e8a83b2fd267bccfd4e6c79dd64fb024268dba03ea1, + 0xa96e9aab6d37e9d1a4d3e0ec375ed16cf201f7bf07d2db66c43d48f7dd06d2e, + 0x19109a9f6cbaa378475c1ae70ad79d2f83100b33653b9a16bd84cce3e651616f, + 0x2455d14dfc4e34f8b2f0c411722c66ec626c1727fc695abd1c849780bd746a0d, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x2720fa35b76500f2acefffd7ebf331c17d96a400b4084b78253e3284f942f855, + 0xaf8af05904f43895b5e9236f1782ff4338cdf90b962a3ac0d086812ae628cbe, + 0x25f57c83e4d1831829078d17e98537d56e3c3ca16318f2792b71a07055b11f8d, + 0x122275903e7cd0419e6c815909fd6b655ef0f3516f9c9767ef7c7eb3d8f22465, + 0x20da2a3fb1adcba29246bb19e16ec3a9f51abbd59aadf30737ff92b8efc61ee0, + 0x1942ef506c145d9b15ee431212e1be7bc2861b49e7e68c6ac9dcee40344749a2, + 0x29c8628087cf8197c8538332d6f0253bfa46480244ba31e30d23704022f55a13, + 0x23ec0870cc4460faa687538179bbb9f395a1715195e86a6bb5240d5477ef3193, + 0x220e9648212c6250017065d86188b9612f73f9039803bd329ba7040a9e53f14e, + 0x1e424309dfb1a00240f4dda0e4ddbce8f4ff4a57017fe888e78790e7bce6e92c, + 0x22dc20b39997ba1b40288caabd9dfd3e9f9dc4fd7bcd9fd11079bd602a2fe535, + 0x22275186225901c11a65a53e0a89f199541fc1212b4e96aa7bd3c5bf875ab52f, + 0x17ad868f1ce516279d8d50fd809a1c40e78010418c7aa4ee6a09f9b523a2a61a, + 0x27dff28396bef2873c44964b33b30e44b27a8fc1d08a09175f1cc9641584359a, + 0x9022e1272e97e9aa32634bc3bfc10224a2eed161b9b60f101595f8df207cff8, + 0x10e1f1602cfc30dc4ab3920be41ec7daf5bbe3d96dab568aeafbc350c5ee934a, + 0x1b1aa6b279c2a5fc8dd9a622891bf4878aaed7122fddeec0a20bcf2f9da868b8, + 0x283b86d8cbfdbc913ffd3849a5e70f92b69f5f7917a0401db92f6f1ea11ef2d7, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0xd21897ac3d9b9e3be9e5d182d1ca0441cb3b92776df8798362a4bb4035aa424, + 0x20b3d4db18dd6de3efb359c8e60c86f1d21c20e7a9f1dbe67c4505ee7a3bdd67, + 0x27db9f494aa78c119ef8358a8b122f4aed87152f92391ac9d187f9cecb07237d, + 0x203a42bc685316f63fe61c9146a7426525fff758fc625540d9ad7a5602c6cda8, + 0x2786086cb07a5e84a7bb5516818a0139fbbb33881cd289a36d55dda334f0dd5, + 0x17197184f893d19475737bd7202447e5ef385d2b5f0a5e75533cbbea61e7d791, + 0x505d0e83c6b5bd0ba7da5059689f8f448b27321c23ab4da273db77c954d55e0, + 0x167393ca748cc53ebc1ae07b28ec6a3a2f0d4113b4bd302cec7c0b398a48715, + 0xd479338ab58fc837c9197c0c1c5a3ec515cc52a1a9b2d42b7a3134f2fa13859, + 0x21c2423dd4c9fd1d183de5619442f91ffda880143e43f16bbfd42806fa6c7417, + 0x2cf480612db52dc3cbcd0fb630a07a92e2ea594304763509450bf2d199a2cc55, + 0x71f821a426e22b9a20cfc997f266c5a7a9bb521f6a7353e25dc163a35c07522, + 0x1461f8fe38f4a760b4f4d09b51e6a126d4c5e9ea529eb18c7c94cfadd1ed45fa, + 0x1357d0271c479b5dbfee4a3cb14ddcedd8cf50365a31166c5462acae0b72b38c, + 0x2b328c0d80b8e81a1de5804422b454f019947f4cc167476ae5ac14862181abda, + 0x2e3b540ace24978dedde505b42c9bfab888ae08d442362449012e0806891b93b, + 0x1ce4c3196ea44d6a2aacef87560cc1df5d652527f00924c598abceb3fa9fae01, + 0x2851d688c92c184c79c18d06e3d80ef439074686397a5ebf0800004ed10b715d, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x196637f7373413fc37b3ac318b969590ff0be31ced0513dca26a263d5dd965d9, + 0x174d93a947b4b73d687a5ebb5a4fdac7afce1d9c34af4feb7ffc41be2aa210ad, + 0x1a844947654e868c7ee686ab18a2224639739de7ade503530f19e2743f3640fa, + 0x2ca2906ae9b528c0ff4e3e3257c8d319f8c1368eb73a80ab26cdf1ce15cd497d, + 0xa94ad92e43366cba7b3db85cb00b7b950f1d221f05642cba4d9519a6afc9a1b, + 0x22bbc0a3d2c1cf2c8556116779eab7110ea892f32dfb0ba1db5ed38c6fde17a9, + 0x1e04ab6b0dd11b6c3f59c29bb6fd62733161d74a9952794eae23df935454357d, + 0x229f3e8f6afdba218d948aeb539787170f4e836aee874123698c47fcf37c175a, + 0x995cb64172f8220d642030a21f1d525c39724738d58054d8cb6ac84a16aec03, + 0x12b8663b8e3a6bcd9e2d7d334c88c0fd315117db2052793a7c2434776efb8358, + 0xe306e47bc917fa7e38db51ab6102290228c40250770884029469817b112469e, + 0x290d8cbe5211d46c41f561e89988de784422a5f75088d0cbf2679d753af7ca2d, + 0x1e0aefaf9cd8ef424965e8ac51a7562e11506da29886ec17006b289370ec77d2, + 0x4df18fcce60a87f50455c9d563db8f7630a0dd63c55df4a3f549ce98663649d, + 0x95973dc58f6505b00c033973bcc95f1d068c316710b63260c75e300e8f20f98, + 0x1d18acab418de031d02587a3df05d9dc50321e206878959871c7c2681d9e9ffe, + 0x213d73843dbd3c4e90fe3ff4afb54f113a94a1e94ae7c93e062ab7cfd7ca42a7, + 0x13807261e197788f606915b736d04f3127e3a532870f6a2885a09e47c7a9bb03, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x250b609ce88f0983f177aa4b1293825acf49cbe1ccc1d0d2218eb7b54d8720e6, + 0x2a3d7388587ce77ad142e1762efdf17d8904edd69a6a90161b19a806ca2e5361, + 0x1905f00fc3b1cf3fadde47cb7e1b25bfd0fc503fa90b34c13b3b1d660fa8478e, + 0x28d30399b0b09d77d5113875af727910162825bdf73eea4dc375729c8b1b4415, + 0xf6056c7c8bb29f47a2337228d5bf342fbedffd5237d233b3f1505e09b063b94, + 0x25e6ecb2921119f783a410b7d24c83a5d9c917461edc62d0cf95d21be424a561, + 0x28da486586fa7a6ee7a2505d51be49e38100470b4ede3b1ee7a5c364ca500cf3, + 0x1e7a7c44e72cd5a635bbd41a543c9f46945b7851ee8b482871b3176557846ad5, + 0xf8529665d21549208b12388dbbd55184f23fd713258c518249d4ee7f3acda6, + 0x1632d84a0d31502ce509b0149da1a5293df1f8c11b2e2f10d214a2f52e4ca22, + 0xe576e8ba8cebe7bb81ab72d7bf1a08c9830ad49016e9bdb83765bc6a05dd3cf, + 0x116f9f8556eac9dddd689100fc4e27dc9a42c4534322f4e18379bee32b53adf3, + 0x2617cb3f694b9d35852d5341c15fa51a47076430dc407b88dc708a57a4dad9f7, + 0x2e1dabfcdc2242aaad7c5601c45aa376f8bf128954b04c477946e91893bcc19d, + 0x20561db57fda4a5d18be48461c4209d39b3fd760fcbcee93874249d4a56dd4a0, + 0x25ff336f1b5fa16576da765273bde6d1966d96264cc4e70766d170cffa123475, + 0x2ebcfead11a0a9f882539b2129420c8c952361a46298713c3ed4d5d6af8ec602, + 0x17f4133aeaa19e905765128b43d633f345bd34b512f2eef16a1dccebc1cc56db, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x1b3a49687cfb69278fcec9c9024c2cca61a3ef43728c21bdd11f378bc219aaf3, + 0x21c2f9fbd8e7212a57051f8e39c6e68f3849797e36692723f44e0861264a5676, + 0x115d3df00fd3bd6e540dd0390165eedc883ee6efc07b409f3675deb598eade42, + 0xe5729bb5e9bad3ee592068ecaa3e9fe83de56e38603925bdb9862a460ef4615, + 0x285440545506adcfdb2776c74d3aaa25f7a7b0de3b7c55f0e5b87fb7b6e0db46, + 0x233f80e930f4324a6a0b146d07acd6fc8f3d9bb48cfe1f072d75f58da84e1eba, + 0x21f9ccd305b8bc81a6b2116e883c69ad27c8455063e66e31d6da818ad1e74de7, + 0x28fe2473f0cfc0914c93b9a49af57b809d9b205f2631dae15c8c9efc67c5ab3d, + 0x2ec03f45ffe70531d6caa30b55289cff6ce7f852160797a2b9c90768c5c4692a, + 0x1b6d0de6db03f0bad2f0d4879bddc431708a821df4cac5ee89cc9c9ef70dd9f6, + 0xa11e8876f08f694ed493dd39340e775eb7a6a41aeeb94b274f24be97e39a3b6, + 0x17ede99ae68e039acf3cb8d353b0db916c2f2e721f19965a474f47f1341cdc16, + 0x18fff4f3ec52c43729d8294575f23f8bc41d85b9bea877df8fd12726dccc4909, + 0x21df71f2c6a62f3945fddce6d52d2aa7d326b29262ef4b298027c26473b9eb10, + 0x11b89da0475d9f041a5380c999272eb4f787090d1d55b9860ede80ba3983400e, + 0x8dc1602808b04a2f3c3a15545d364304f4f7cdb9dbddbdd6f632991d0a5bc34, + 0x7faf1ea463a24aa2845460d38458855ebbfcc9e1d4e775a350a0e88275d6fe8, + 0xee38f40f3c1ef1102552cfd03824d68bea40bfde95785d7a4c3adfaeeb4ea1, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x17fbc184678cfb88bd30c7b1c3d7b28864204d74133ef42de469187f5ffdeda4, + 0x1cf9d597555605a940cde10452784e867f46a2ae74fe0465f4938c46a546c3ea, + 0x1c092bb49f2b4366b33e2dc2f6ee171468f95570188e4b2995b925b5539e8d63, + 0x12f62053127e2084dae1db28a6d94ff62ef6a1a4732ab052b20395d0cd4ad478, + 0x1eeb4476ad29cbea12ad7cb44732113e58c0ff598ab4648df979c474eb3835, + 0x2c38250647fad3eedcae687b1ab54f6daa582bd29631c73fea1d2f5c403ddb7d, + 0x2eec86ab0272f57df25d8453fb38e9fcf0dbcad228ed15b9e7ff30dc91feb902, + 0x254f0f4597efcac8bf9ee78bbbfcddc5781f71565217ef7af0beec6e5d5f06fa, + 0x12a47fcdb1b19d720a4398b659b2c74c27adbd2c24ffae0101c4d129bece130a, + 0x1bc890c0199da7edf2f39365c4118f3c1d1ae24d666af9ffb83ab48b3e00a204, + 0x125272075c48ad5c41dc73c2d27de0026796d6b47932bbeef89bccdf92fb7598, + 0xaeb8e71cc24b05d8b4a1aafb1a16f8400cddb91e6d42fc8588ce50a191b8c4, + 0x60ece14c283b3465418c6b9a9f56cf9c96218b68576081014122ba05654b3, + 0x14728be414cd1dc79e436e4d72fd9392e44ec7d6093af846a49deb20f2823269, + 0x21d5f66e745ef28c0f7178722cdc14bebe02412911433fb460be724281ec8361, + 0x6bc631335961a7b600aec2c433a850ef58c811cecbb74bd1244e0304ec9b6ef, + 0x125b7c277f162a0a077cd6f1981e5f22dbda2a0b0bec465a384387527ce3ed3, + 0x2a2a1ff5ede20300c015be7630d8f1060ea8aefcc7ec0f9606e8aa8cae99bf4b, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x247c5ff976e2ad2713b0ed0c228a561962155f3455fe766e747b3cc613629cbf, + 0x28cb0837980e09daa3e697291898baf1629eeac4e46342bc071da656c7bf5fe, + 0xfa57cf86065e02c71402e6dbdc251b1b76c1205eb14d883d95b957b376c6bf3, + 0x1333d78ac8096483ce1959d954323802c853a4a0369fee7ce1261828501ced20, + 0x14d5ea7f1472388751201a664b15f402974aa24f6cda9a91a84d56b1b6eaa776, + 0x77a697d92ad2c070d058b32564a9efc7e1a037a1d03962db5f2719de5cc6c7f, + 0x27c6793303f3e75361c67fe56b8ede9c3b13ebc8d10e6ff787e69aad56595064, + 0xd69340f71fbe2b9772464b2f1fdb25c5d93cd365e24b6926705a77a890e08d5, + 0x1e2d709a891be7d5411fcb2eabc3cafcfcfdabab79964189758d1afaf70a6970, + 0x2cdb124943fc7c3287733a0a3c078eb98adc3938120ca02b14a58a46a44f4fa7, + 0x27af11497cb4a8d207471064e855bb48d8786f0b14366f833c710766612908bd, + 0x392c9300d049ca31025170880a47ad61b80b1dc03f3e6db3264ed1219db5b04, + 0x2aa58c8c95a91bd321d83ce2682a4b7d2f6e869a0a4cec637a272b0b30d58434, + 0x16f7b5e9d83339c0a151b1142423fcd8d2c1758d677a0ff7d1dfaedd525762bb, + 0x240b50d50ff6a5930a55ed800af55fc621e8b5f0333e022a49e1382ef80231a4, + 0x16e43d57fc3ecee17611fafe5e8e7b053808f780dcb1112d1841f4ce52c15f3a, + 0x18b989d920dbb70d51598fb2a6ba22b1825c2f3f05f7fd4897516fd749e8cee4, + 0xe4db6c770ce5d662b21e5b463d99371bec01b6220af53375b8d24bf76685d9a, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x145563ae8e6e1472ade73ff73dc88ec306cf540be2894be758c99953826664f6, + 0x1892c99793221d1f11e9c5637757db12c001ecef9965c00c697cf49ba9b881d1, + 0x1f965f8daa018ee30596706f17773d33e6835e66b8aad44e71955303fce6eda0, + 0x2935511ac83c99085b247a68119593d44307b95394392d8bc1e4366b54021442, + 0x907907697dec1e1a3bd179fa8ca9a87265997bcc1bed376bbb2647430afceb7, + 0x3396c267b0ba914a9c4ba45fe06a86a8b3960aa1dc12ed7943cc8a45fcd50e4, + 0x679ebb051d64df99a0b2c93744857adaa8802bbcc6c17cf0cb29776fa229e85, + 0x2f93483d03549c31b606b33224139de1998c0be6f9e4b900d9fe9728588c98d4, + 0x1458fbe748fee53d852d83b0e7e032dea42fc174733ee672f833d8c91b811a65, + 0x1a90f8cdc1c63f289f22cd6e4eb3bdd3b7ac9f04cca49d7d7d8cfb0f725805ad, + 0x132a4fa82d6276051f33621249f4c6692cdde99766e52b21a0896e2faa1ce5ab, + 0x1d79444933015ed9a7b37b53da5f35dfdd9da1dcefe3a454ec98da690ef1880b, + 0x268a91dc77ae88ff05486fed8eddebea679c01bde73d634f5cfb29babdbefd07, + 0x1e011a8f14bd69d6439cded45b157075e5d44ce51f4f9fe6279fa269e999e1da, + 0x9d4ccb992e2ed6a7d1e09649849084e4c7af1c79db784e239c39daabbc69a66, + 0x4bd333ef75b6e20a0a9566c7f072498868dbe38e028bead637408c6aa43f232, + 0x7a22ff875664c4db8334871b434ba01e949c60a4264e8724abbec4d9822994, + 0x2ce7c0aaa7d361da7d2d170270aa48f0a962db88bc02f6779be5a5079e40c85b, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x5c14e041616b9d457521c279f662e02245266a12b5164bfe05a7503440ef15b, + 0x302134832f0832bcb9fc6fbd7f03c49e7d5d081d455eb0e3267a6e48677a417, + 0x1ff1fc0a5041e83cf8c145b226ba9e4f38e42e58d15479caf6102d5f0a46c1b9, + 0x743a2f884e7cc1bf16bd83352a5b3324366cd09838da3b7af8c09aa8b907ffe, + 0x1602376f4173d959749ec5daed8394b50facff3fb8765a89b59b6fef0a7d1b41, + 0x7d2cb9c94b0a81818fce3f94e82bdfbd1074e8c5159e7fb0ffe12291e9d833a, + 0xbb2f1a3fa920981b76feca1519db3aa3c26b703facde82423479b244bfd05bc, + 0xef15ab6018db6f518505668756a151c50ce609657ac3a1390df76759e9eeffc, + 0xe6e886b5371587ec93eadca0b54cb77c72d4a709bfd9431c5e4eafdb1f3f3bd, + 0x43868f796a09019cee928cddd4779ef6de4ad17578c1eb5ed9ea01761f46a30, + 0x244a691b12e0202fd70fb283580700f2e25747c504c2a0ebd58993becaf84eba, + 0x7db83a16d8673bbf160b3b0d5d96e7b14040490acb6787052778aeab1bbd9a4, + 0xa38eb2851046d266aa8aa6d124f312e00bd995992adb16e47a60a086d5b7819, + 0x9afd14102f5641fac42f5aad7e1e04fd5779dca6d20f21819ef3eedc779a27f, + 0x17f1055f567a079eebc36cb46488e34062e598ff88e9e4280f0472021891d500, + 0xe742b77b8daced0467679873f984332608e5cf5f573295ab6ff101c86bec259, + 0x1e0137861ce424e6fe1f8161847e1c804525945db0267bf56e8af64c14cc2d2, + 0x26af9938a85c56e60ad89ac9ea7ac83e04f574d33d340f143ca5f058e2ae18ff, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0xca3bbffa94a2440660ee1481664e28729a7a581eb47fb1e7f2b8d19b33a7633, + 0x56ddf288c8533174801eb64e46e332ba077df88559d617bbfdeffeac12c935e, + 0x18f68bd602682d1267ce57ab65f27dce1859bbbf29ea5ca4c1a7c47ee6921f3c, + 0x30595b7e6e83bacac2e1b9744f97c045f81ba17ab940a093f0786aebf107f4c7, + 0x636950f2ee62115195d570a6c43d18e92a3edafb2eb0389482211b486f979bd, + 0x874eb8555f4444b951b3e3134f96d75ad8866a0da0775fcaea7d80cc0be0c95, + 0x165b30894e68376015f8589abacd55512eb63d272ce68ce7d478beab7672b55a, + 0x19e4b9ddc57a559648da219a93cb0ddb0df84b89cb0192814743bda58e7e025e, + 0x25eccd6b96f10e2a0da8fe7001a7458e10c3e669cc6e9df84e4b108c20a7802f, + 0x12cee7ff70207b2601a5198a71c1430fe3754958721cb810b8de2fa6c464488f, + 0x1f99c9efbb41738ea513af1bb140f11e84ce414f08168e165620a36032e844de, + 0x12529d825e81e3cc950c208d2e40375f320daf93ae7e401dd21f31f69ec39dd1, + 0x60570f962275a45bde460c929edce1c9e56d5bfdea7f5165a9ad1f338e43278, + 0x13d11f33f4e872a1d7fca8fbe95fa47baf3e57002783f5503c6522c2835d8c20, + 0x2359f3c444f7908a0e3a80861a42251115f650fa4e66febf815cab17676fde4c, + 0x137c3d8494fafe8b81567121140a8933a957e06a86af79f21aa0786ee032071c, + 0x3527cd631d2e66d0f82218ec1a2ae78d58abbc17519750f028e010153b5476a, + 0xd67de5a809c3c17ec81f87ea47056557cd9a21c12e615f68b5a3b8b2be5ce9, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0xe0a49d17b5fd53e41c716eeb7c3170aa596a3d994cf780bb4fb099a3e628ced, + 0x1b7180247c35af01d58bf18ce746e193c5f9d6cb530deb707cc81f01663c2409, + 0x2093c5ad6ec79e87b4c99af53c32b7c13559735acc74ec744a45da050d6d56b, + 0x26c4d026b6da4a405fe6d74238747fd571561b7265ee49910c447438e9c0e1c4, + 0x1fd3b662959f05a5ca35ae543da8095f78a4544159475be1e9d84592c526f777, + 0x1d8a119da46c01ecd28598b1843020f2affcffbd0d2ab74513903b0271176911, + 0xdef9ecbfc4c245d08fa20010a22886c01234245042181ccad19ec06eecc5aa9, + 0x2f389eb9dd0db3310260a089bb9d0846ed025ac437c1eea56dc5c7159e8474fb, + 0x192d09f6e1f97e95858b09dda316902de5e0b946d3050a296e86fb90c0824460, + 0x2abe84bdc7a81e92248e62816419516f31b9df3c36088df8b0dadfa242af8f96, + 0xec8036ad332bbb0d8eb631bcc55ff0dd1c71823b8ebd6b8e0699417b22d64d9, + 0x212d905745129480f6496bff628cdb728a729394f7e5dfaa13004a4dd6d7ce01, + 0x28b10eae188741517e25e6abdfb63f5c0b8234a453ba5f73d55731b126b8c442, + 0x2b55e73628a3146399c9c4328e7b7c2b06c3f9c6b2d1c2f06de3b2b54c2c50cf, + 0xa288f1c2c2e7b4fd66632360642bd18970ca489714681efa3a79597368000cb, + 0x2a98c6af21ac38e6d8f70a8cbb5988d6aa929c6cd8a7bd41de02d6a461e00398, + 0x28131733b6f0f9dcab73a997d3de4c14bbfbe517135d1a8d0559f0974ebb89e3, + 0x1a0422b448652f8ff28c4099a5857e35474e8864c82b0705aa291052fadb42de, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x759e02ddcf9c02faeb9b1441d3e04e2e26b1c3c21c1a69dd452798b1ecebff5, + 0x1e6e510013a7d26108d160b3bfcf269ff0f51a0759e1e1b2731f7c3fd9f65679, + 0x87b228c959aec21d112b82be8167799104fcf2f6a1311a8f8c6ffbc9b91c0d6, + 0x1db2a8fdf80413cfcb6c77e97c570ad471dabc38e8cb2fe680016f0dd6d2c5e1, + 0x2c866e9e002f7ba0ff4a92bfc05fd5a9cbd2c4497ad9957ac9434acf2a3d3aad, + 0x29032ecf930c2a41ff93c287e9bacfe4ed6435f5bb377527f945ddd90f02269, + 0x21a948d59bbbb4b75d7e62e29f28fdc1ad21e673c3d895d264f3cbc0b9c0e0f1, + 0x1dcace62396a9c5fefb317bf0771ba35e345a4e113a9be8b9ad3bb4f6a62a287, + 0x29f8ae5c1ee78bcc95db21cba9113f31c1046c41d866a70383ce008a9e6aa748, + 0x27c5c8707b69d2ab24fdc16a043d24f3a2aacce0994aafbcb79754e26d7a3c0a, + 0x2d34b96bbc3259695bdc35d7ddb28d896f64b94f0923627193d50d82930a61fc, + 0x150254ed341e43d3a5edf9fd4825f8094317dfe0f198f908355c9ffc0485b4a3, + 0x2c4ca99c167d67e6ad639409ecf7669b0a99ace688c6c9c33a34d71dd3ef3c97, + 0x3930cd56e534c58be531f7e9e2b9cb3efd62d541bb6580a1246dc9a4067a7e0, + 0x24f69e897348f292f1ff886d4992b6b108f1312a3b194296f07314af94c27016, + 0x2334c3ba5fd553bf774f53d77c3f556d404f487ad7597abf505626e5fc34a054, + 0x2d72d7bd580f41990e776a68e9a1252d1c5d003fbc9bed64162a1dda8952ca5a, + 0x2a311a00f6cd8196a6f12a725b9791b49f46a20955a0cc05435e136c3ffaf3e2, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x15eeb7dc60695985cc24a901b81f2c2ac6aee050695ab1de79e300d546b1f043, + 0x1065fd42737ec473c96a3741ef8119bfd955ab6066955d4cdebaf9761ae33e3d, + 0x17c3d9212a09026f12794eee3b04840280b12ab06bf5c688f02cc772608fad92, + 0x1b3d7424ea8664710a024d5f57c9d3b372e2c1f5428683da382464e39154bfb0, + 0x1122aedb98479614cfe5927434d6cb11a1ddea539e33c7771ca44535c510427, + 0x55e9bded4cbbba7dad989d9b1295c5230d5a799a6211895bc412ee24086d628, + 0x30263db0209be791391ad08f2108574a6a882f05b6c8055b0ba9e0ca8715217c, + 0x643bec3e72fe54060c78a6188b7098bbbcedd5ae549f5d0f95594d03501c1d2, + 0x24739ac04c239ad6549658ca1b7e0f62067bbd53c3f0ae9c3a0160dc8982cd4, + 0x831cfa01b84554e6f26b9d604c0f91447c6c5ac03ed1d318b7944c5773827b3, + 0xc0570121f291d8fb7b7a62cae11ea568a394915a9cd70f634830a5e36f93025, + 0x2994d07daf7152b5024957f7188fab4452714606c505530854cec14a582bb6e2, + 0x2e5ad16ef38f802fc789dc46eced2ccca71fd25cead1d5d1f14c482061cc703a, + 0x9f1fd3fd77d399d36089d589dbce43f1f563d8d4d927122bf29819a0224053e, + 0x1cdd5d1efa77002334e3af50973ad87009b6d26818bf78396b7d8924c7aac675, + 0x2bfaf90c55d63a08a0ac948874f9b1fb60c0faa0a530926acf868296f8478e0a, + 0x12d3e6c5009562c1647269d1b507123a2f0b7729804b66643f081bb782ba7cfe, + 0x36e9be313a952e3b77fa42cf13942e292982a7568964ff200356a1c6f82e473, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0xc34e42c97488447c321d23db64b398c6c25d4d9fd1fcfd3b5626674a42d1cba, + 0x27d82eee53199316ed144a5591fdae1f6e2be76b469f606e7ff6759a8920dde9, + 0x895f2c2986316092a0366d6dd018ffd6439c477996b4d2eb5c3aed2cb0c1025, + 0x22ea26e3404fa1f74ca0be2b73237d0a44014f6036f9a96a1ad1b6a1393622a5, + 0x245f9c36081e0229dff1c693e33858b05299349c921d4163c12b8a60cddffd9f, + 0x120718feaf2106067a3dd824dc15c3639312811c1d8e57825aa782de88a2c3e9, + 0x1cda330df4f05747f9fdf518d146f9160556d32d06f8c21f9f22432ae2abbf0d, + 0x17c8bde1641bf784599b38a3ed9568cb3e2a8366bcedd556711e85bdfa71fcc3, + 0x3b039fece617d27bb74f64fb7c0e24adadab1215fa077988fcb513b7990caba, + 0x2585f69b3b7caeb08b4fd4403b72457ff3953e708f20a2a0d40872d5571dc707, + 0x1cf1dd7016fc72885e841cbf7e92c931d99a2cddce535f72b065485b39fde3c2, + 0x11f30f1bb28bfba19b81bf60611b0f26c1a2a7f6623aab774f999ed62be03449, + 0x179f6c3ca3fcbd7aad8e1ef759216d589ab51482a6f7395c93d5105ad79c5e00, + 0x5193282c4bce9d58154eb75ea6fa29683e2d2376d1e2b9d2265103b323c014a, + 0x13f144857af17bff0c12f0fd177a6da9b1b3b10842f4805689f124d52d1063c7, + 0x290400f022f09b1359bcb9812dcb353472449f4be850a28d949f914290aa598e, + 0x26a590e2d283ea4e4bdcc39fe4cdfcf9b8e974b4603ee78ba0cef07e042da923, + 0xb0bc561fb4ba346db8f28d41eb0bcc6bb1c40217610f165c5ccf4f2940ca1a, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0xfc4b28f50f749c8b55bb53cfd3c76ed13a11e16eb3816520d732174b68f9694, + 0x1c2ea86841afa29997e495b0e1cea881562319d9edc2aaefde7b30da0118baf5, + 0x181f1de1e627bc0229055b2c08f12ad3b70d540b24fec6128e359cb8f32a8a, + 0x2a4b0a0fe77c7afd26b08ac0eec6a30854cac5eb8c070db07a0a3c5b80626747, + 0x13f62bb9fa1cf209e303e7626fd734710668d02b4efb3ec507c1f5a4b59ea94a, + 0x2b5f4bcb8b0c0c1aaf90e370e93b611bd34015d4f4083b6feff51c60fc7f90da, + 0xf61bfbacfe1eab14181c0b9ccda1da0272742a0c64ac873321c85af7c0f4253, + 0xf29b98701d484f65bde657f17209bb04d1cdc52d1d45b8357d64153ee0639e1, + 0x4f50fac0a62268e7cc24a64ce7f784bb1d7982be69a9dd168b0f191da33a5bf, + 0x31b6743a6fee9be625862c05ffc4d4c656e30e17a4d1e9a68cd906ba9c5c784, + 0x1b2d7a1f0ad3dce2e4b7fdb43de39d6044b9713b47c82097fb72721de84b629, + 0xf2090d83056f23a0a8519ef633ad3f7454196a1da06db6aa93bb72bab913dac, + 0x1f36ea15e1ef84a869d23f3fc7c3fc0bf425301e98022694e534a564ef69610, + 0x1e7fdf4b6edfd3e8e19e73fc8f938b96bb271f0a8b5beaee67efb0f5fe1d8945, + 0x58727d0875e0a1a590634c527e8b69a4c6e443265d013000cfdd5f00b9faac0, + 0x65c67297180d56cefd31cbde7691cecd344e5517d93d36a2ca00b84f2ac6406, + 0x26efd963a80f4104192b1e66102143aa18c6956b4edb14eac83399cbb957d426, + 0x2d36f46690e480d2cbfe0f647ac99c753cb01490ad79327a1192e7c5bab301d0, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x1ae20386490ddf16dc579da580c4736d5e20066e4ca980efec6c412d6c5fbf20, + 0x13855655eb53d070d6a3b9283176ec875cdd04a2310a8bc7da3778bba3a8bf65, + 0x216a5047fc9a6423e0dce5c2fc7ed22e17a889ecd7dc313ec97da530b0012dcf, + 0xce0a7fe4c77e0d037ce338a7272ed67864f566705e5422b954effa901c1190b, + 0x295c4b9a9a97eb19dd9bc5cbc4704fd57c100276b7af57e07be392c18a953bc2, + 0x2989d23a947312faab571c5ddaf9c4d09c22d1876e7d007847511d6e42c2f407, + 0x185d73d77a0e88f9a67e2c1a59d6473706e24c79b845ce5f9950f0fe26d6c794, + 0x182b0ed46716f64fece882661791a29bb29986afb83cc9e194efe397288aad4e, + 0x22ff21a0030a575a4c62a82b286a37188b4cddf6d4285c60b60d030db206b1c8, + 0x1313437aa7949a4ab64fe85327645748fd2a58e0e3d3b85626e88f7339d7b261, + 0x6efe22994b02451beba2f6d0dcbfbe9b920817d74cb212adb7f738178ad2f40, + 0x301063036e4697bba8d213d35d188697239bbd1b369e7bd294ff4dffd10885f, + 0x1c90fb3a46ac9ade74d20bbfe8403ef060fda9603773064369d4c344bef5e817, + 0x2c52c601cc0042b449329c045fea856de70f98ea8d1b5ce3a30ccf0fa3dd8a52, + 0x19034b0b0a87c257ac4944e0500e97bfede7ed2dcb148c9546e3b581aba9db21, + 0x27b086852644a1c773f0ee6c7cb6e58d7bffa32638b79b2990bd7f1dd683eed7, + 0x16cec1cfec5d548a707a44ddc3afee7db168b5e986eaaa885748a368d1fc7607, + 0x23e0d5c20594133dc55043bcc80a422dc9d59ff92f3e1a9e934d7c7486bbd410, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0xfc871014612f0f2153585878907f011cca957eb00e86bc50f319ccba20a005e, + 0x179dfedea941ec28ce16ad4a6ff320656632b0750e6616889e853719bfc6e88, + 0x2200eedc6d000a31ba05af605292a6ac3db87e5e852b7edcda9ba306192823e0, + 0xe0627308b4486b9922aaff007d2dc88a4cb80da9d90be1bd13d63f3ed7e1fc7, + 0x941ece97766c9dd37c07cae87220151b9672f02bff4006700310b95efbf4f4d, + 0x2d8806727504e7c422452287f378c0a9b859897254372eeb4e4cabd2c038067, + 0x1f44136953c36a85d85da27e57a6dfaf955dc7e1d456790e53526625f470624e, + 0x2ad2db1a37881b1f73e5ae98d404672ece9487a08ccced17974e1c925b0f0234, + 0x1ff27989f4d74b500ad47ef372b8f08396499e4461ca7ccc5914675365cbdc8, + 0x1d9e4bb1ebbf654ac8d81380ab49c45c698f4552fc2b385d61f1729f9a434fee, + 0x269d2125ceaf4911300dab597dae2d4d97714a48abaf059f0060c26a6b462411, + 0x85fe9b1797ff4833c76f23b0dad53a01728edbfd28b9dd5097a727725bae3f6, + 0x2a1e5b7a8bbde19a0e4e3e189a5375543ce6879b8ac6c94b3541aa7b1ee5d73e, + 0x38f9b328c38f8ceba41d67319a3186ece9be1bc9d16142abc3099e2a910e1a8, + 0x3ebea7ba2a89695b6be00973736a209479d0e834a37f5ef2863063552d840a7, + 0x29a1eb861aafda5c9a36ac4c094cc8763b491902b18b9dd29bb1b8dc216bd96e, + 0xfe28a88001c17b2b1ceaeef8891bfc5abdb937c7fc6d51b2dfb56e5347c6294, + 0x26ae83ff720fb65932e831bdb0705d7ae60c0289f7bcfd89a020a5f3b30eafdf, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x1492bdc61b5ceb6fc3b3d91065f585e0d1b037bee203ca82743459c1ec00c65a, + 0x275f2dd31c5b79b5f188ae669923494e6ffed430e8c75bf202132e50b25c1a3c, + 0xb327a4ebdc41f56502186a656ca06819d1d29a32a6e70588f548c4fdb2f689e, + 0x2c5e3d0108521c8af0d038a617f2a0725d5003a5b9dd824a95a59ec6bde20b1a, + 0x1b611cb1e5f7f2a0c4fbcad4e9dc65da5c6a34190fb27a8148359d465165f9f2, + 0x22365c55c48c5736cb4b7dae8fff495e9c661e9e130af620cff5f40fa1210e96, + 0x73fb93220556a2bfae1e07d2d076caa44c085e2ba6644bf4256094af48ebf3a, + 0x213fb8bc8c11ecd95bb3311eb046398f377c3ea4208d14b80eaec8c4aff2bff6, + 0x1a617c5b998762909c55ac93513a6d19ed1c1e28ff8b78fb3f551158a9d0d99c, + 0x2e1284a59a10203966d53cdd502405dea6889490f9bcfc5a33ff9d8b6fee17c6, + 0x27c73897b8aea1c08380d8ca28d0405351b957b064abd17afcc647b73ab348cc, + 0x2bc53359578a242289a79806c04853ab89fca02a6232f152d05b3d1dfbeb6908, + 0xa8ec1ba29e112cfc42aff081ccd3e7e01410696cb5510377072bbcb2f9600c, + 0x2e0634f26f73f112cc5f285e4a232f694b79c05ac5bb9c9dab89dadfd0112ce4, + 0xac9a6885431d005e4aedee93dbcdb638cea5b17c363289adbba9ae9e3fe744c, + 0x216854bce3077af7b8294565ec200c0c455b9d5fb35cc98ca36a323620b5eae1, + 0x1603ef2a582a0adbbac5655b3c3202b60ed3c22e59fb442c2a7962b9031a33ae, + 0x2cfd0eb51e60c1c0869f5dd163666ee8630bb2f3b527af9860f8e23b2fe1a869, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x183f34db24beb7107f0f5bf9fd4c2532033855c37b5463ccbd658b68d870e6b5, + 0x1a5079190245f746de5345f0775f5ea91712edcb4f165f391e9c8f0b1268280b, + 0x249da4641b8f13206d3cb7b3943d4ff5d0813654aa5d8ef4eca39cc6cddcda09, + 0x2e99f0d1ad289d3d780147284155f335f34224f7f8d3db6b008d952a84a12f2d, + 0x1a95c807b653b762910fb0b9d8d0b4a32b000f490fbe925e0e207842a2dac0c5, + 0x127a15cfbd88e0c122b2905572c496df5eac209879a235afe08e8d2e631cf46d, + 0x1c22d61ac34f05eab74aaff0cfc01689132754d26de62038964b5a8acb1fb340, + 0x2ee46c0fbefbfd75eff882d395294889d915a1a1e858e18a5b14c4200754f9aa, + 0xab5eff34c9c0bd9fc90db5b058bdf68fab4f25eb7602e9369060fcb6df9139, + 0xa91d479dcbe07bdbda4249188361f7aa7e00c8edd81eb74dc176f19bf05e8f7, + 0x276a57e2c21843be0b10b8877849309b33d19089838744ffc2454199e6833f63, + 0x2a56e477fb4a285b4edb52b2f19fd159914ec3b384dbad98850a19dd9f44c2cc, + 0x2fc33d4b761a6ffe69a5f4f2ef4f41f727d7131a2ce15f74f67ba17236e89263, + 0xb9ed85bc3e43eb0c395ab7dfdcff5da94fa809bcf5d20da866a2e0712dddcde, + 0x2921971bfb16df44acaf0447858eae04720bff84acedf57d1059016932c0a9e3, + 0x1ef4f47e8d9e92d554c8bf9312e0c80f5850fb5f124421a4a032243627170429, + 0xb099dd3d5498781141cebbaef8b3c9a071d88ccca2efdb8d97071e878718f44, + 0x304a086e6735ef7a00c6d5fbc6a55daba181f3ca901f5de3c9a29f6161ba5f36, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x286686a6d53d085d60793a0815cc1b77c61ea45fc4451e7b99e9c8e6bc80dda8, + 0x1609e1fceea6ca88af1bc5075582363ff305d5f39683e70710f2f85501f4ef87, + 0x124f27013e00d9b8e11f6550ccbd6a2b9426da5f482ae5746601d82fbabad65a, + 0x2c47c743ff1069ae71b811ee87050e9e176a0461d8f6e0472af4a7d8328071bf, + 0x11a058b976dc5fb8424c68192aecab8f56b683f5eaf1559420349281d849d746, + 0x2222ec9d6eb62f5f431eb27a65f792b19817580562d8482027c7e84dbee5d7a, + 0xf866b167acb845b0905fc05dcf985849cc7b32a76c532fe2774353ea37f1fff, + 0x7197c02fc0c5f1e13bcd825e1f0df47111d16be06e4f90e1ce2452ed2758089, + 0x99aaa6bef62d6b1f3098bd34ec2916caada19756bfa2dd222cad7fc9b296c66, + 0x1a210aae2dc13bd0bf76b45124f771c486cd2c4ded5f125600ec961e3eff5d16, + 0x4ae93e4ec96ef4a97132edc6219ee43d41d3d3820331152a83374b363cefc61, + 0x2140d4f69e842e9257960fa14aa526f36d6b3204952c5763551600a17e9c5c06, + 0x16f77df72961ff15724b2cac0f79106cc9bdb2b3d25534263883e2e379722303, + 0x2a679813106d2d1a88e194dd55641143a5aebcc2204fb4e8f2cbb40f637e506, + 0x12582d2bfe22fab8079bbfcd7bffcfdfa6a33221fefe31e74edadd5e0e58a361, + 0x390e71fefb45b223ab77d04c90727eb97540b7d3d9ca70798bf3b3f97d91f21, + 0x26b440f48d1c54c8300aaa49b9ab8afe622d6f7579857ff986966832584f82d5, + 0x1dea175296f5bb238d04bdb371b31bdfe62974b0a219f55be2c3e644e82b5bfd, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0xe0e6eeab1dade829f7d80aa510ed423c86bdac7b39dc5fef6df9b6932cc812a, + 0x2cebbd5b0d62b44d3f06728f5db838c617d933c08491c23b707220a2d6060af3, + 0x2dc31eb7528e36ab16fe4e845b1858b44b7f4ebcff8c5e2916b5dbc93aada42a, + 0x1eb3bec02ab6b2a2977c89984273b17a0156202f622edd7adf787246ccc75f2c, + 0x220f79359bc26509ccbbfc429980c2e65b195b3c8b0695c8765057a2d025a67e, + 0x1590491b1dbde002f869c666a1f9feb983770740ede60e726926dfff31f24806, + 0x2feea161ac374df1bd1e90c3d84f0bccc39efcfa6b34e12dae7ddcd0b3d7257b, + 0x1a29866fc7a388cbc6c3c93ff3eb7f37e1c5e83659b05b0522bac1dcb33534d8, + 0xb8199ba3edbfd7da088f17687da77fdbcce7f4730915cd9f18aa86cd03574f6, + 0x2791b7c58a031d038d076f7d6ac43730933a76ef48f203fe92400d60b98d6a2d, + 0x2f454625556eacc7f31439c8f2b0ef06ff37ed616f19533f9266f28ca846019f, + 0x249369afe3c0b2111d448303abcbc18110aed1a1a4456e4b3bda7e8e2dbefc7e, + 0x12edc078ee15bebc5ad4509f3d44d7c25607fbd61e9d464d84ba3223582de54a, + 0x22580da134a629da679be562a7a84163a1565af42558a04c64579d98bba260fc, + 0x1dda309f47e45f9a6cc38c7ec04588c51a650c8f0f101044ad6c0b14a5b0e6e9, + 0x2ad483577232eb393cb943dcde6c616285468d4b5af36779d86bd789c499482c, + 0x28ebef81b1b34667338b9828e4858f956349d34cc99584e1622e6e676c221847, + 0x1352a39d4ec27f0e72f991c448a1511e1e7ecc4f4e76b705ff2551f2cd17233f, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x2697ec9fcc93302d5f66b3e1c1ad9b203521f05ba99903596fcdb8fb70e4cef, + 0x957519127bd1afa0826384ece846813066831571e2aaacca4494fbb2a628c48, + 0x1d8a3eb38e9a520787f7b37c59fd309e3ecf19a45e4e4855b53dc670de8d395, + 0x13ca248a44825ad1fd500351378a1c873fcbf6fa6aa3da48c274d1227afc90eb, + 0xde6ab6ae985160148e09d5d5b35acc7b0f61cdd119ca66ba72a11c89ffb99ae, + 0x6177434dff8487f01d4e7fe5dc1f5963020409384269ba24b5751da9470fd57, + 0x195ff62cbbd66aa75406290ea773f0e6ffecc1fb8be9b6313bd30a4e0626b6e5, + 0x17ca97378ab5b95fd548bdcf531da28e4336edffda8d3c5adbed45b7f224a04, + 0x5b258f2284fff0798c69fe24b70f96038cef3a3e7bee367a51a7e62907669dc, + 0x20a38dbc01d5a38c6908056f5c4862c351754fae0750094c93cf54bdcfe75b25, + 0x27649f4bceebf6d71f6581d40e0407b020dc73ec56bf16748c61854c6afc6c84, + 0x12eba7df6b9e4a5a1b7b92bfd51d12e756831af7133a79a622338cc53e19fd5f, + 0x8487f84ccd636bfd508b5584d1cdbf24cc1605c779e5300d4328bfcd4dd6db1, + 0xe780d26ee909fc75487670a4cc043740af57e89d045b69ee6babd8089746bb3, + 0xa58128a2fdbf500e89c8b81a8b883bb5004b4b29507158b7947178b58421d30, + 0xb680246f8aeb38b7e4eef807ecb493c3aabad1d705435fa2bb37cedd04e9695, + 0x2909a2616f3a24ab48ad9f50e4f18c75bee2c2f434bcba5ce605c1dab5721877, + 0x143f55ba8ee25793ded43c6f14c92025153c79c964b44b35c886af59bcfac0a3, + 0xb1e797eee3f15b88ce3a1fafec88da1d6329ac3c34712db570de886cf569098, + 0x216f405b93971c6d85d700b4d991a983737006cc1099f0cc1c6c98a366d5e28a, + 0xefb44ff1e32edd4f8db74ae8764f6493bb0f76744f41f2f1f35205975b49020, + 0x125e52e4d58e859809ae43a4865b821c65e630a0de0a2f4cfd5188ce3cfa93f1, + 0x4c652e865b682c60c57f60bd33a174e9b9b22b52a1d47aac4aa084b1174b929, + 0x9cad80a5de2e6e280dd9b65d56860754dce0ab2becfa07b30853a32af5b011b, + 0x81544e3cace3761ab3563b6666160aec7a52d7331dcfb34e7b035d46d9aa6db, + 0x29c9f89966182d3c7c4bdb1c751fabf9dec6ca6fd0f3d2c4b2651fcd35916a67, + 0x25ae65ab6ad76f18d3423dd2829bc059e43251ca5491c2e11c04e3e241db0e5e, + 0x1821e88b8cdb1686c33ad7c1dcd41c61f47a6435beb00bd8d68644b930e7c317, + 0x1abb95b6e33243a050e563b5c4fd059de5513ec28994a6f60e57c98d3bc8f586, + 0x110d213a836478aa301bc1fd4edd388507d87745b3abfba5bf282afd21f7242a, + 0x18edb2d105bb53b768ae0137850dc2d2bf6d1303a1f8ee4aadf76d8f81990588, + 0x1e53e92df6c53ecec4c0de5b07dc4c9a0c5545f2abcc1fabf4ccb84a0a6e2c27, + 0x10fcb817e10f69f7074e64c393b807cdddf33c84a8b5cfe33f44b73fe18c0e36, + 0x2b1d8c11fc652c593543b6f9800bb7d0c9371dedb96f08bbbccffdc6cc44db98, + 0x19f473e40c05676d5f8d51e11336e9c65cb32828c397cc8125f1dc667b6cadf7, + 0xfcf3a4d9c6c3392de1bdfe25cfb86817ecb80c51be17d47f79750201f1fcd01, + 0x23b02d00fe2634889673a7d04736fe15b9f62652b1c0626a19af8d6085d70822 + ] ) } + // noir-fmt:ignore -pub fn x5_11_config() -> PoseidonConfig<814, 121> { +pub fn x5_11_config() -> PoseidonConfig<11, 154, 1386> { config( 11, 8, 66, alpha(), - [3312280834382673867321630616941760639861515464094877629805120494360011490649,2977163727414618213643725802224710174200189681501907689708278449275625624600,17077799405481633745546679084486353025600250694578521370656758513725453934742,16210306379465933080277173890273457210762404430253284947889895341785601089390,12306944281360832043572721821716739944034354411349456264300159795863030116042,18510116198433364516004461541873904955505055486081639325191415467980353992665,20171004681243290383397478639749648403640483231061520437292129889020927831789,14216817867363924461443287436236130110420963767734530602158091056747850914504,1744244489393376249430799522637230427855625055124494576876957852023791759325,7129585843913921821110812028399979173266826966429993304814409727296136874103,13988404968409685403326663187671698975733642730286219911002602918437679901860,16920638563061193407835052036305459051417920006020130846290964059193276218943,13427470979587753937642822251845898994765547507421045262408080469011197338416,4951343674183369875263494313821909834781608226183187917185914650592996842297,8735432128376864913532575297691608527208524295369583136876379560735670033436,11506191123509320764309490571835590914265043835723578099434891464809664894670,11860937155601787389575216601739962955686948385964703064981923542694893487713,10828014814384016644406621862814561467981545748254521286078083584574739936124,4776443388323724363690349417451836132533385226194261923508005690866227183177,16639991477904781874568583121789695884424899367435699700192357030587346907362,63646460855616590932366082663720069120195784636826940928051354727568777173,13872046592464170980392921000435473279488582870563366687909512908597101541579,2903974073963148433036990643522953333905364588702098342158750794553468542208,13972003294927197976860685316247379324920372226280483226377669417062686947906,13868504415208879955736997036981136359599594082926486546672963310629609974499,8628454286960990606041697926325623221475249983044062173729208432417417750989,11883151436851199698252725037318235080760967011947670552161788839027156740653,12343286145222861673187914724623142745362406729785896500578210646320713733295,13240444180513188371213070455300718988708567038226911680564203350475184135088,17225520781620743741263824011599257737446498734177523099795883619924078366351,19655364901125310778629982245392767297984820167114789563931170716695750865678,10695212283696096281132213692300627346215324066996398339089365835910730561368,17455827037964560948521638828961298975187156274841334841074216120311558804710,4382628454630801450077593442523632674983545561122254229775876033334437860489,2989679808908579687765205532943224072820070594304724633625888454150084631070,11805110513334566809098991762079653200819786354513225301120697798603509678793,11155601993809199490094826448585668454159517005968097566996288487138255635079,20815808565222781796761554019974947099963702926722486604443826341123930622896,13761986205307878615460321377264044874010177269812603883540272922422883198979,4128370443753246025606114169149035926146394950057754901868026654335917771101,9124459754124711043815747649012164723935008821275709951889811488049411892152,9090302853448501945809598864330384875455576758214379286451409039855851539841,2611158043123761410817152601927516372222739024190920897371539155273224585905,7810155525349201315441227323507184944737106980192978514457375337581213081055,15249792920950763850993517571920601821568311809174912509031437118050063777525,9921562618684201533699293485620188871082795988970107962425978745591461148033,5414565587238798987874533039507833069864773781235217517734130524969939419113,11085088558016600803149927568829483866020077054827488081829062938808919799801,14625818170426402577283649455001357862456467374537021301451880577607106726350,11633423263664104506250995123678976351167359685182986641330218055115412525059,850899676511673590463501492472742017261347013078251845952824541653369171366,1151196396804070641219917031443763313740170846357000808196046482153806050391,14335865562369989392722415692597018596062508514718062574213639729550753584518,16165235837546690396792041022833296046736592940683337326949013823518030323769,6408098377682813619850142098164780329355428625834955152400958576961120931380,21423078154100258346688828020904418548554497199114189102725137286930868022538,21410217312460027364452766052404349950133415202888862471159726884511205456308,11096458349387432633781125315606380225216758142658673665437375204143306261827,8325016245207932555950059013310928498109578689420634828690059159861280125058,19120379171572846193451984132488836287003157955913585086569467602620121544962,15548527549295346334479152412121638073047322389003226521019746206475690857238,18510388922178653264949279980605433471616208226685385338922150015851847524587,10348792093961922144290405029634579505420677504732581441616360506905620826544,15620530873228503134208333316448182712901874887467615537478242394290577386453,20675095206674416295505702734315255961699360732886837937979451051773488542601,21623072135556656816074223163769126264910877148099315666172910436076676028248,20081866552983231525843337497912436927329172443916196026679813450860013966767,18951602909834406133815764463249536936478826139929746486734639774975812472830,2378298801465585253495854322066504889300467395616155363977621341822205588163,7488881447347091058309495011922138185162376888083687541108039236558708660027,7225960736862847948475548065508931552528126330579521291190635548005260333390,2970482373109443685421063487292183827150496377598629996362474558885993864176,21734396161383902760672518999845141937065773419899625136190973118533490737305,18986003927424880427453510819113519633513383085919786483726156674699889468820,9438591792749742425198760386567115998731905494024392289196006582112950891516,1973470346155075248881651300830631935042830364217214073906277058522882105581,13791817954605171888781711015587425735543149752618332811612012047724803625120,19907506629242812934309078271817109951335091294976452370249234742626462372763,7913144809845970358468253448033359382532594356254540499933138806226450398795,18786719915196826164016145948631708915544945593653634575689240810328854731069,6216910690440344513687669938632060553287695043116654216600911463719413604341,13963849909448408572632889978998938642084255012365277702934245702305832007005,15044749345099947962217476120263824356898437745229321420257770262954985403569,16364542436173489908162544844694842746117292595057249540926274681176755002520,18582462045999492294572047486602601352613220856614634390669602502489215736186,17106926147340558311732938581031578597532846523271406141897942990261560966411,21322204968737434192679865858477095835509790782891920152044718985713652659654,5180799590809942717590072710973007480225145652031514943521639316776384894144,17327427769240537767056224186269899694170666500703858813203303301835294225360,12795226231932513901983143961810913124288321956641191561823103283353203953207,21372571405151778511626450096485639101933984498294796899325401511071517993005,17332300051629640554924347563178488077648079908152291094969979591786473880576,15196566643676483159109284476812079407469293035334983717971092729005139246767,11231435533605861369104078150337976075098864909987541459896164149690464379912,2542242881481757350297627187544723135156543853134475677976341602496676452300,8414397814915895101029770303847330205837773505982623383796193602695811122514,20884120591077768210550361293303217187539921930869577755703150175746557517590,890887689926165781226591337399563217015154445631688026491595317246205069769,7911456647213080390137926613780820211986390960677915664339039845274033704843,8086506254215085366863905182926378819432294332631815038288539116592866850975,17073560037383161517623747613125771654997798954263090273202401066518468858416,7837662874931236958961077774488634261606966280628598881837875736120392183663,1858593536177571875355498014960393860692560832490490994119420708212532861823,2029815832061982114925482969267067531992443107339599745974909462412297854269,9638056659007828434670080110322180928336402529095853481855440674860675897358,12340090961747329883452841216385303705169146011720720105809463143491658552866,8529510825845236935037301291679257193837435275552609577171369718448324660013,4191225223853834143599110761318464286196261585898512902425773974473427757456,21023319679135760820789157052868478773370737850886002789313940767424256194356,2142526213326613906831098262446296658577569180284637200640763867788179991570,4585042017455545746057351957720948202590802829528217263388726369695890670411,10010708638531752335740573636867640657039858389864446260449096531856416238708,12350783923218275606957028867683130968505845112714635024839732952215498877130,11964414264447046767815837108295373861475122940092369903025175128013924386713,18615506936496648840383399989920850970951406181285583088268789582149764054418,14310480127014971068920522498055725465578544829224822580493909725079522528728,19209887743481507043830894286806384055543596834772181434542567255388724841969,9558553005299269735641084020216560749888705968385627813150807919487080187993,16359179198438658598155755638987769554841536772865629517841526255130745409879,13009386603860183254204895522650012288119732961876401784040013994677688723325,16165167702867558446013999607792716532235725666199142971707303433269257270111,9526255138490973975321568846030367381138407886665647949792126204681244064012,11173959697998471600463637717719289778917744248391051771189332133876606070906,8924806383303834750473706479936998674798746387089627706877519918521882863256,12086306023907343271920056592137012844278234154616893254064962297944646888123,20523426725749375175935122656912302902564898343946638208821839160006976692150,5207650950010803883388912523741229153368067016192964642079270816449299041225,1323145474328028634780912405048390126320417262412962953050466352509016682042,15985641921260285694054233699922160344414776687043687582488491933807565444789,13031771899737217701535545098380455304311851135903656399978477292561795000214,12687226379083740035799525440904048416465917656850081330730343990236073218003,5180214195408850700722613770944601169370584228844657891855699394648642429923,1934847650429153525882808430984088614158092322287601778579498068360011630130,13221691213669397834454903625729859574410480120034103769424898865047475910400,7358428584159841472154153892839275459119229492180053472830555381908577651936,10890590867941343184378544765218808644776443230231834463183835780142311216436,18106794932751537043075991633023418950145862470753313409722049187095789146702,20653121417027117499755994750040261936029675942959877982604976723194002882577,14917693547715740204091617501230563717468258023142717832164274356453628117609,12588115399854852983923905079011727575933343603816172388719899888494451203866,8737187804839661132607601320524529444256555649101505512380882940221377341037,20181178129036534248081631452735124104458169744675071995191727629040780050092,11847774883596070919125373409969812806188814542338127843683622869859801757028,11792352762436629909341171173296810156800556812208317414203786807634354583560,5039046929001603921830951923781308597413960825857893817665425268295870771062,12894400705986579725245788498699203221654445738734999525700614560206785491732,791109735149055364851227398853119460170782218988367975658618461497391330160,9962476109282060862882002156903460806939219308562214446822701651882476052460,1691961422009775486402337895262889415967004356867228407841177856000156435254,13137802539241815005932694907183711832661205367415214501122657136334369092290,14887252261014844625921142022701177088174316290502741584519763408145964517832,4710184813279024135486906523528903891606006797755655291767343324947631364837,3801875732725114698561125696836343357073399124260852478317754268545097096329,9198233237012512530002016044631468704269680036230256629514440524866699707396,19696310211066978020836317292330659233588020682368119069383469865122133603780,3893729283153055478198590025767324126269879907832064182575052081004216821718,17970322286541481482483545514302125656124172449128411566036569217140609597331,3173691464765770821621367532348960211199783691357143005417355252781889173280,2243542900289123996173306626857758207765925487218044091235839910321809834188,9813067765525696381929832954440764980538359181380263390331469145209686852182,7510903347384066721813722580189668539045635640361656120910145998846374499699,6798424040308056706713925899327404372610976624998869962003671422212921682045,13151104198292309578579089832681402880200764912297978086539824832412224275732,2808835590734075710953411057250272995919027932824027538775542577464926767888,12588027297759258617444062604210692398005597744782878589643963326768133974361,20852428689501418456174033597851660248293428726014401905473174242849532966301,21296758342898944987847487225137782473520558597036376704831839057822676021941,17749269130031982625604134600446353874123371420684509963863640790293640598822,12696062143950532198094822890688877675740383270827145944853466311043725527586,10234631072965977425954576972633890272283449053659669736631819751429358646105,15090656934406651728161310654614148547687401766770336347796859883364028754099,20297283938807526130287519089364625872430415084303524848853727877999978340129,4196012712072569404315829685460688625941300450108222372646584487742105064258,7048902004425912498834833883033670218379565315927717075817051690008258707008,10997088676112427186865690409423506551772833502185768664867716439827194601092,16660341545280246485425051709291678711850828822636537086457121822086705580853,7507040282824500274626435275567162035280839409294222666356976034789594111255,16582934771732736721752353176711248084060824111646755305570354937871610952840,8438441158635690733311342509710555256926785449251473129940736660330253698675,5997879363655967621652122271982901641685668225243330913415373444659935275798,377781155818540738714095913828188470350179572448699653767572496979822660266,21256042944489939677834126729197446597005830228623173527229465226360970832340,13462424045682641929202812263623136219335301688716109209361496824976128063539,16369985325316675741289392258637854017776166143141100299636544614904713590628,19352389303901189710313048379405187204819083083443266317372096723889889111665,10276552469336314142974101263431204498273961662600910736694134016860746072245,18939965576088516958025629296747895354615121399053610843001474455787438484084,16990956322664851054201977827659189601868639970054898553161570861097544812211,9274107214677498542007885890977699632511964198928324688228114708372115109190,19938102848869576488504727710754065647382136279175127752338128473551869244856,10947279549049485525804912961584261533182913140524900494781425525696586998449,17561385783620224695956276284426542193322408499898012489406312644517964425011,18549237431132768472559432396178388563409301393950605704070488347475233640622,4658944912168763919889884489643908669977608714692544551960581141528777169667,14358732577825715965736448712278683090180078342840106686279626250756225140484,12281258853616996819181958497578187729715864708853144319900642420503103456870,4069586715276899433893814672543891090785738315323966746105563017207510306537,15392338154382717986608388646339008932890583126043490476751054331156284554276,4517279215584833397018875849825808766631742728356316383241841280072723947253,11495036315995422771228762992950108862694073551665420165823433137577472792783,3488400840286926839516544735442894876148193865245875295688572119503866691461,4483680161275568275540790250446502401130629200290761781427443716038558729253,3942379126490099533582685851970104926928015397351808560877929535138811915511,11401623410099323944960285754389435394954200879740972352984594598244147798394,1704354226179051409424294551695786920602664449209459493691051505451583669264,6126483205301561395856828080510799275633402498512671992649940369928504550860,13606061849345999397793916269931170782757704442972401347887622528829626440142,15164492401059698496285802476110470458129619713288710918549993367398699891422,3351459252264231792942138342057542378418534651418845818443384064630601195925,2825813294993932054460723098369264495005871082754465730530978747926493034970,10630213694333677464069113775948160876773011480314305970870772509710784295967,17166444840808098079862920467594387590120730690478215313452389257289409232274,15584725536763467888732670366582920601197464509911998898151204840990765872853,3842723796922381697995350228115144219456021393259361082360164730224542750465,4831891679443026612628331848829793784542170442278947325598774522135713804734,7600866468317146506151393588648544489445105617254544624521183070936649742997,10583687645778325936823793169279337717905917984785560251868239070559362307278,6634607933824414124502549710741812867975263049249231353927669720791801705509,21200609344869125199593456019818101515444150712862469998882355110348140005358,14361714336789127058022203168794208348007919167174968797533361168719704534209,1575806469795254200103212820564180016945577757735332906646132503588215912546,10628306906313535336091114056786842183955113155572070406112143573768388478883,3089301712473516586340147971264840334080312453733093398291612940108596635146,8645795529068430110488497380845362622141451911891312096721911200350500642213,16022924422796267113820566797422451700895182144910797483992348492987850640540,21668559624091676943635408329170173151410363888407430983622558174006481336306,2072754212505196807037151376956574080111414803663052483852517767215769333105,344312312360359816789223515659978323664333965848417356296539814750513103748,8220091259162471818305840126401210949950597324344081712931466340258084434570,8081153019090920515448830088459971939645826679918559179389404338475619307845,21449241241855558649730447089457892378091011965030006823417837265982774602267,6067510299282418337933484892144351034696356612154920492037935939636907603847,21026143172839641048848076059364862575379425612028621103404211601411048352556,6070438567473697541030303531314185338530006003062193748841965554522662407077,8255130291759907832990229603685682560848952190335394603030993899908706198932,9546680581091867708464426246566048171085730057856647964775027268282058986619,19031748019605060953238957886441808197649034817040423262874632275713470713752,17096522586030137478189913833428299115382271406265963567569748424828047092166,14391874539708946761001075594593462740437739522325069415219274013650732876769,5044944855410335767979170189040984719402886766879289090117403978287180516155,12039442478120524220891851909305716836138223152615593874775855237995395028479,3523930243951081542915282337519662387190599423550808129910485998252637662407,21645562630446380089971004272761942543158290220498842219097308729146973947053,9635476273420949200636403482900193969961822409725076345852310152023632001652,20108896868320980092863545615065555118659548096203643467891646750271137801454,9185755445384903374596265352827852278482253313517817304360514098507824628136,15729448650969486701474329849747687235995473855623732466626603841221282908291,17997496197003273211403721001065741564292124821674411166555153239941325690779,1543484160386036195130212436149054066156454121707864502325718576708010327712,16363634132599571248968010449034783328746466576733841612125967259037812456762,11430550344567145066773020651025090506980499195413761807852670685184554749682,6562474642758509619875130343887830140546824045253242049540363976665708088792,3689788469446976140319903688077885060368720863836266384022598571957269060684,946161443553297471232017467760713330784613638346698353392670707850882897488,17775152994890017803033120420023910950366134526347402563464114996856742054838,18013595561755224808896799093133992096629438550898908281663802197342115179235,19550347733494203322271272376490635125389454301454207200256111665786140278650,12387591141491143807678990173849961323772837586376210707337202980616282598236,15615445216195972598868146032329101929277001754848917412471279643674750521844,11157377570334948360516367332475698893237579888172217677485190937247699033770,7130958205578403403951515578418204249480908544151977781217247531796937245530,13077463747714835214281685128657845926832593706922024570198457201391820941874,20874866618752897980777992983172936086725928829995747401713185587049763764007,9529341163966534350579350780474173060797076273832542721772111561732792505333,11142469391388881243303156644691476683457853027534314004453288809998298235798,15759641247899199119184149872340402267600476479959598970774176792522105838715,4932052011278518183097054145820640615211087138945458940865038794988474891006,10432003521315545222242540576886148188507417318972677351911763831484066879233,17415623007807480250676335953220588929877876653555913668269587494499596716638,6058502442301803313347169632367675883843035525640290470399543491756905404121,4937981332834016148179351587580087161307555148093009345111656135565068163315,4767276541447291442260238717093680167532207332378535289044385385412677713720,3479278227276561004751092786681066281912177752486503430342235086646969267132,7943278285140068849348170498689330975011840215116541312829451500334428180149,17789865444817191695636689430256327163274376252861234888599341795716694863906,11313788642745794682263060233193097297009786646629777858110154245289610960322,15451318802981646436556355654707114069777551322432702430595933898879175343955,7517270022604650172540378758621070031306040808100514057036893386092388842581,10009597627594120061689516706238257978394705225993629762944338270984243419952,16287228641302237661911798504390175297327206600486567815634358152959586818336,16488249714776419229986970659608164306511103745532215897060984940903927940510,13354728687549843942265910857129412843774195483459170542959107134210371522923,5514821690255816781301952402733589181643174815400146100135235253605240813486,5770103106430309708547950317514210165673407448643264387718101428086149468878,2694023365380190286709306630457152471177911482921639231487592222438630988204,2596360308486910596331175398746479488324950265788021808703834738076552537175,9039714509260386661160667890165090643713802650277924766536703740888044388658,9604908742305952316295642934650340892998619318487917447839433792965436657411,10397877232904834686750242142278095498016920001087513253065011131758634311960,9647356378465005298504489726754445992380752731297711041297431711301119823740,2901124847048448064485279495316677205686659456282057720583010224075223188929,19604711253175713682339631659824057587938105276478055043815802354580551412854,13814073762260094871340458282144499467492241477826265605381954643255652812563,19191277082146641271114112092268339387374938745710902056016346575725741574791,4351438127825195342433511764688522108908810411430938576079426214421798123584,13791103210113222833666019051739255444684344392875106989928046003279497788407,21004705702783423413965111534445421935934565517891538415275359891592731977145,2271618466337144497382665490697115072125990892802659816927722507215828359501,17558902460062424775395394774553055038697408789830072471787389990226026812332,19541727150539905151936633341362726755459275099586077305409909896489919664394,13692791587272861333747931194991249996571271400946738920492512367046518055252,16261859926552105019169611795692937520291616941485096436900016176047007140288,13364750885171681175943985569408970262762845797040643237076315743322239541667,13621972138767941419375174302334978784396954063748685093059444353200957635883,7816366958996751828525267034982378444982423551198678280151852851213963203655,5387588357364980194077356588147257085032575072648295273044945567343418708153,5561769804258805723102666784326040807434856561620360208220095378441903055863,2759015372384926293713393955452664141507032820282479368223024343744582995438,13981134543106614704319578938205751472742054796552637642168049339888724312989,7990257879146478669584929211133379459065259065980981194790047745364505663434,11876127927930413842997415069288338406075999315865409152476435081888707100248,16570551097531678234333612414250188586376313376162262758608423816369347322204,2912142129158840181609698148893520848427743435752721748118484524307819669362,21302711682094568025057587941584825132522581272692339045586256377620698610739,12312191496853376716581371884132892074646637957572159612619070514615509157537,6766172753918389200603997763713298721859536050788836585740520353915599111166,11495484070470791342676704007304510997655718568304345126153023374072812971624,20811664890504244597768955277493527673608205732118233091518542968150115526854,16063703627762167667966504135478113457485558849729490090362731172389730931393,14866560644094965611504947304610358591133796414154206860995591970456047599477,14070826318654672995642970624813758954945583937085129314124463556918282721543,2479865882631638665546581282869746245766113042059506929860680221143260292935,17398990555602339276684995684280302899074008602689308101178965669933564447317,608876042484390223586509032355843816374709085426455763238940304845396291392,19093816648588316664468783915406437520968219066632631005915358745999525844761,6752057404464894771427129594636749868828376343179986455821808045648379935245,19888182199106435309043037013966294783272588579928340631894231065863897158437,10082296017960550499269875102368612265371627577709879253045116718197037435449,14616172738414901831631177911088055616005574740810051337096702495520738285374,14075121030661423148825920501776601474873747801291899275268094618775991305078,186569155903133115291205664388893859453551519692185893083420327670792162388,21299949831814715974370318270705239305629929085336938013302553408219032200083,10073139629403946009284887013173459030563893496973388848686052378045073830551,1412198475257996126786641438141729921783447169582336707894995512036569315500,7779964092821851708726534513875342218194584080198381624983100710844846404634,948257338952437735532120031007610523249359469819114853137850805544224196883,21258332661476723168534084283213459804574003007208501208541743948207937371185,3571248067320885077052671052657329120832155265049255115581589211873377624342,18767668432875868101830472546043294158876614861521938962321471373462978174897,9300839292250613795491408219504842564421473000721822643979051375966405606193,7064697496603343927134791624768930499810256237088252983584462738613126284623,11853953981626198865163123682396255427116155876021473995289924391523536239496,19771876990095842377875081223218001588478929046615599374496234715810020326293,14316898881193279100266501073998404340884941240727243537292505454856307190130,14519359582636080510571261582400983934670011637905562203617314435861115398211,15526562931305845620715599917553561556373761549853248996847605985788604583130,13078262487107679022841832022599167182597313495640194703513299650288211974881,8245559318515118189428376002847388656528865763199194533482833563489439004385,14003329258302578586391126522614048791257224051921678844212914592624869865893,11725000422609501650997806599141176528384787601555518111375908215801780233121,16350891150329350826705554113837971740496662498788954571303936439413078899269,6411076187467760129645481080704474318810486795627076355267125729971512535475,21018151777353913573383620107187764987866574825379316352340980146357643078382,11358423056150266238825561031091840555431271536659827607676154506546242135862,19065833030377987569441381994102534825367123386452612836837050555888073644388,2562667974917478689245733861669928078902565222389031120733094553006681886960,3471326938285931978123873023764646019622642761349433536231294291602304868485,2563009390241284210001442885151389460822558817932742264596703331331069807625,1840397005312580276560341795534676176103474806443827954038672349702326279641,13608853165319143662474434916965520937512197511217746962619929048696566631710,19629513285164329969551640449451527909298649847319347893901982383162686335860,15394390010333989214892827255905093646577605209323130947826658910240751517983,12111906652703403073758441298171362667165880553934054594322507856217299245492,4297972575899320549167090598678621826992022863628750628394635867928789323371,13452780308396674980210210234355016032880538147426066947029982271570560372078,2831837563806484576977992168295535809035697292555489411927347217736327891352,16435334356674630023459784576727565801947528558756855054741604645713144334059,4127342592978010203327455190780821692230702238156658795505993209368069797198,19169399182658468533946629204100516992531108319585640665183465573285725904462,8598406387986750884545663645357594697293280337319305106433909682884489291980,13371924317816745712309163118606793190008424593275425616115063429517298127531,6966840677637301630181597160079353321163372268840965853806074036299182143344,7360050884120437815429010939441335996325758450523147733433611465713273074289,18472779235592140583651215638681270421642809888489121199352426980884551699243,20418315222771285674269327640703205319629639584244730201946908647328012868945,17026399731940643956418206353642733600139323525975091345342870617418039094945,12615211028716399762155462346481728092959316603121559521948867446476882144221,12396056279980752806946158389419170236239219009894918041607073720841998512650,3020267183116758520311575446823726815087071183512473845404855371056317502914,4656542918173262538192266136796850668036544742787442489947994092170369122585,6651580153776746866797134628474708113133308603326248742448594405127096716435,11937440848975251505322944134185172341897441221500443657141975704868428110206,1361826966800566560222081321267933925488529241685130208478269338961124266689,19943953771229014728170188452413560878330164558859793245021220185499985258316,5000555778712004519940673290591853777960346285299451454158729230859752281548,8421588432304272431559534311544652626307929129739056740355326524785204863675,20295164315900629557422352618552527295246432971816033569783057482727719683327,19373368537162638225474243050103347264636555313351270279300938524044041811781,19301584842175411162376576546656332386749822306022512981007234449440059593206,10803063363791701506227503212696578672701333662552932509544627248354076467851,21190447586310863247879892773912245039992873717104751727825265558975676297878,10001943442280168315414950100438358800275893831224620600570013850341287546634,11419108205602584425734602189435177828356990665164795815514509894518490834107,9176365528060199110731574560388345526295591893454204513780413140739307927521,14645264015971411259428809172021065485340465742768211283864072707152051283922,2059680394752128527783641175137415159902594391639901766513696812385555753758,1362210878544210374207986445190412893419873862912439530157828224644264948744,1767020623225215375042202191031932704135774649037849280381750341452687445659,12814227243430147774278313161816717185894261558098935373927981841389635793984,3650392274313221017884542662769899210301363377135174682150190146413571526895,8605030053804448166307797789010404548793085578661466947278557642849458591843,16243873345435203695859375103717652101719490281058055690129195139240095336348,18253688126813406708458581768662237883226849901952565733241285746065046225854,16894577548232574374120767026426945561995165201786189772245769116072691636300,6423863987901820348928069732046971656713531289251833729857903917381295249467,2313252375346549956530493743826026444705500798866360084159932659530274395286,14351648867218654569586186362113600409735374191851776253843321710353903071560,12748602702906129786642754668169435482057869301200357523545630557138115816573,9709541611470508424169916733595066328177420935464065317839768365879702321494,7178910033786777709713498702843323736165699178795466682345863412805925816311,3353312211975166615897632007255179570864390972587901806985844706830647691440,21333017166590824659869638126407263965780255207193356400088734092911593056348,5028007188794597820037691911407426228966175740057746443994889279713514676932,10712123321028508395224612143524241532236128389312765281020405990000255535908,9585591632158092894254183832493550005011787447364800638915694118244958639233,19409055735214428219964362626158681016506721676720000843605743187110212915626,7013515054956821958187738653419570061640238138610196975216698509582854871893,14195757172805460680435532998286722310304400118130745528870652671654335152142,21642947172805342858920270288264451136332732954445458690700494722054302963125,17447291201981220908729619112892222175870413627521563259423394750686485556049,7142752135376494645636618098683429493620847661912582079125447091506892873792,11965386305718013298615263282817897360134689279593443592649060011294217114060,3269287439460269094755519346810063037578116295811194645623863516503159243267,2159120529508493457616143785556394024190164584915596617279717229000244189542,13216089736556667969033672749174760723927614320685905176389819791237404133418,5739580235677403106179902507340026453834485061930671765794215270028117113169,10146496637166180435280660177294964473638207568055892239396905092844948797979,1559489237751880726567698923572583310388557924219345825351973445625480867548,2596197625765120503438747432434144655985802369868414306286213301002200644404,9161937832793127953923149604860857118908349157525975074572071369698144813595,6530106539927673920262526515085998672101393587740796643755609207665748320714,3454043461578374982297475090824066193432500488323777575207325753404726668622,3344507163548616813143529013320782527939556912905450999614978312225536850079,3495919320773160724078129285494188621289377270658655167666727615227933095154,5516726577701478990891722326081439827260225708304904918582005618283443949920,15205180713187999862939063125387810274995561110852513151225711366795547591281,6648123555675422871529580981673252698816139021904779960285680145979314385726,15841058754930028584592543963971426098015345537516384042315342065435733026794,11980445534925903182700789375967305825089780148976633769394511063611931605378,13752792603594569707463845404055123799321888887568435005345905056744143696677,451907199992567080921227130990235823262116394775607208182891587168397627680,18806959341268394516719451015233616843300011700855654586308376758853129828525,11666933396513215238559883168577675591860013867821037377342211197150469047378,18261858072527055096686249862512380033913481610225001662137639137871862029384,21560391742011390943072232187892257373961479111877969400490351307926336615662,21610883506787217615067001898587573081135488752397283684823910785658887961932,8408073424459585535553155824732179764716727837637392334926567945546036849813,15210371269884178529776581719481988665617111145372052101377092280056914506280,12126920168856651470145408021353708994570254510986190646194434994722466503351,5069682791790920726869832051575701989172948895827442056320603681340757243410,5206562653380935478898854557078389821615981777078527007269200218469247241072,20147037355698495391549064646435751868583938479186070809834102358533096530919,21648765692141622487379563405180427559394486974406039602691179361899957186441,20151743655500786952430656789085402151537047806266385436562459773879995501836,5934394754413383977455838937623522376367295023125030069688154658727645145368,12603931706566171371403975785994747990660901389421654410200684089833302667483,10026374951811566765702661526223829303823304592138671853309110795200798195351,20990348049520375634430049514368373247447730079841716683325070058824866344618,21619384435032220705428130345438986008128830023896849505537357845578039663569,13891656325513979012692764566925054630715484836057215275096343649598208636064,10516755320080836193722788097986010349704472844888704193817055904209452357159,1187924241706018031195408222997566778745910130631759501304388015015493122577,18176236836230977144874543476758297865658817104610686283126581582188371550406,12485836949850082215229286502965907740610097753180405472080386359153328488121,11294821091195763819640094447903397628795163768975434879119673473115769322204,15235618132532149904626305329048631193060570832794115447207190941624057752196,5247748280389397626917162873894276536157877881047135043409628106456158304439,12327729816009770868743571696284061855435639336028566901611215454206952326402,16602949418050455338609614423670909880567257158111141482461606053345944875474,19481131052077011331591495382924133179323957631986844309716638852480977994007,14534922095860994138017014871440884145230839148117198707882202478464336849118,14698138249781405938575978017673685687915842935570150501408655390412744761438,2268825110634009232539217412695133214837154986621027045784924577498202527005,48564023730318244345588908855562476416102457310638224830024196372769683274,13911429573364091016107598756829373924944177606409768266066645212252032518222,3072739629129037084628601278178937800555134277149245900071628775426363271424,17673164704069533606602950374212967524179027652656167791832581708629862878595,13337993423730131992645864661190106010697884214050744564788997133642079615746,10864361443255322638825945640705455870794346349925711501403405779308411872877,12776251935559898232336391171201768361485692108948381787636663233683642720570,5216617488642405414264845781989153364217494006051772154230377224854279460364,19003202417167005941636726827739223707886908723467287344441657245420838333458,1782933238160323149082341139973263731861637960761110984576354403382733192508,14049307335094461452125704957817909153045723261672970005965857346428556786126,602292860913070228058919352868668861608870961459967730841598276439118039884,4532222937868395031497077142687900610420285824272982687191592830322532698890,2099811981776987988652353966067242893298763890123265819355994207644365313244,14963517993601358850130080519783504904964131507655857293183966569857011289997,5628630657751613134050345890283140633799644494629647136869171968642164797575,20616991532748403949152312405329497795753361035307036075488592441729795933793,9449735601866166994904286297362590639752895462487835902681383517319419222042,4855933188947772127110139132590210785552455770275991391814399396690242166773,5236021116842873402180213939626155398638345682608182461380158609761274518585,8831771317829874397651604675303149337495578376535991692269465791612651585623,3088758799070584868972772977513492687395394215140736055156925465547111629717,9647320052871832007164877116869148540664111922421469306708391658695763892785,13710265959446629407575266748628250489155448638018691055085275421674700880156,3990937300186809757319839603902135620837406120640478356311388415953195593911,14183797850975043036582133930342253303942122026304366900989797745492038794070,7977072622674677196160507229659485240881624765782396719467815964585050639939,19241094982310069445586766283605264689470697759972104264399773392459234417767,1955047691838825101723033568109446280275825112435318858983042058841632309045,19123726709557210987172343550395139275104840920797922301604764165695899093438,11017985516143054945716095457545428692165844636350104202156363406141221710733,6698050162913212144220380056054973138261583127187888344395668170533632399574,9966258961247618428931643789269822918034016436345337589754558490493039380634,5992044103018260979899747087179477222620402658511576502983751749529532417546,4323136703775346257297028867845707816483717723305960372757928628051725499745,21794175040927871006132858751099842549067139289302899933403157116500725993565,4135205477235797120209733594064542822286242795709961420067213468324705376738,10502424667236605030274589825431626273558506810276755098371543260305259735173,14846816339594032738719600614652189538461600190221870378597670293625955865265,2524366986896165752091070306635323844562001546653320749202855717200081979142,20323646694453380576115350130108187509393437723558716335846490151009228206070,17922328316124774235198837264790120266787900323072144966876142176581863552114,1182636510606531787673615350114833983759075243161678674924493347851641505038,3207389967170019411093119580069334588690357331504170475184259410760933425232,8369192092815635351510306100580533943309224255100566350954698456188479225517,12030967886392195699293618525716046167148513246572831396936379799444387335164,14022141444250217995147289887822373716179013971005541169826207913322588624137,1819830254074794257713310243249746692467827341614315920377358118637602832394,5214222934428733796770137135908910242359102117443480657729178969918179851403,18138416073511031005117669443972799853597050093891426716335475360173308913456,15787040542336098200132680028140910620950068073851656692331927514281562129727,821824702031897351041935750619058900741428025283533564678462466715419856156,13945650681120508256113693182498673378848691411623235404408416652983710360306,21565424898814963463657730321537398782420569248706699928677873449861325896156,19609389297655053996872511820224772969554473578452634334180619061868015512289,11052162512235765382251445485034453773059444701618444976454738201341222665559,12166351899911550354968692629609980749815884172876848625284742219657445788950,9357004866878440721090407569238169828150449366762652916034388742054494762892,12114234396159313460221530030197986658691629189646106573755288837341527114909,20697910091918282046230152102481351960195609070206375824763685775389954486953,21217736707553075351032987119547432929010871168087324138739787787951139001106,17381364776399568820088774691862728632279841729367582228657079823795538435769,20943148878105082737615418415826125298002846495574584317442899738454169666093,7269215523851335046672197634746347471983448536436098948086942864058221294848,11453469784625194830295468663538063129244082440999065497133984430619118688913,21018146386490226380790917971415394820859127890200962707883416995754459780694,4499764602796942905287899120539899295087557389188509075023605344029409757976,6253534478331781543005728896589051616547370996281199587944537185086057029207,11552217017582571341399470106065323830802102428782340770897703340827468796773,10819374663920577173719455195284609222419659549106826920462161534187158953031,14349899656862395011953779288216924779057701185080247070042551534943737976358,909510146269051589147289065017979551607491214019225341737807929286505047312,7822991049400510485087251716608572124487352922137650148085367861004077510787,725869830997965165130427627260429551001667760503255008495920045139979612999,16876874328062330437058858063404447748425817762641981976045186363782457609729,5386742002628492275210178331450945300388007254427357938003565527570148075266,5628231453725040085705711150750978455046683883113398227942371706440013519778,5207331605257641510707403983352805778295440159078505882865873548456617745902,10535586157456772677635305329613970037048119551546559771279117980166707049697,10634858349767776643334691454267563140934605084766184133586786266071708634005,8194830686373761187394649827049013218313677678976649876752071409303459578949,7100588172111463994475475315895964854310052675103208262359133193362837864219,12698529806569743134165801249102690453926582725077752506169518961941228191732,3192504222109013167359339531059877081526474219178099463731713708944911915094,4863002263813052668246974534880517465192842993905851311847938713684622052826,5692128778265216733946522388190452257048514412064102477216511313048856040820,10126422206202050217110361146045359045967276838268265874082659894234609632351,5816818864633980489627669987512782856651289984181002178349070605011354887917,6571596820513333489228887403836877987952738840623146829273932098108053062770,14089943097204317257370418561461590134190932157472606744328891293369209454647,15650892875459028952140088123225234819706577582764200222337535746289113550733,15234537030902822319330116055095343429285315370864285347784850359841976501754,19442144493035982963093880999374393289974808397308087180018619507528159896278,4787721462177588970261549242306006751465139812381940463247588627972131957846,21188266388402646362923963971922131649215999518682418035026104849712460470697,7670120618673949888866627327541465118295930474243507723982310418317698793909,5278076033158881738611446681468941913572289692389442858337761263328869905538,6812114686357362596670812436414685361641526159356770435320544521002690748983,14512519858142345768369977582630083215640443350401036244408402584958380156234,2883669043634370578290606585906686768752718215322315377961330865510599230166,1390031372189262099215439174834826964629551818632345640955909690959488475368,2621604580741170950714666893803390793334876512814103152393976192943909783864,16238046050182542127054230631321316896861946156551854572617517416519877517341,17244586605437271554745538098470023522850216211045683035769492251097903894816,19367233841767536085266806989570452145418274769895229567119343509637411304432,60922694691641059020255299196606231058588207683679919735176896931621476211,11404572340596870708576661187798839793333697334049619025922813709736021654992,19297195320049214749532857744175644917624562154332216539771469808458364580570,20000477679980055675786972902810034261882771620364631737011618258163102706803,5145215345848317594229128468995966108988375785838942899274867896011577909800,12745405048448113216886186019434813760835051470566703617056298583393105029140,6134671602520394562619244398452258969460576801019889394876295515660617122846,4914589878992627637690178006894707570950584383330674027731006564533772285206,12220903700447451099363813812957915640017509928028867600267100643383476677026,11628588304761135026225316417404056298817057087404654319307918387873030085506,17423007615206678675839176821651284038190814226425327926691523730687305701329,8965704645750924279210398083172931641857031322145961884520939048845530423732,20213900813945518409362660921232075042618186257655700796304283970465683248159,14023473417795456589963878717505287517669917599805973068283274798230783465678,9113725901633633321816296721315176702107873006937820201651085782607150391484,548172112211359610960958872299753762974328909291797522208085351481742658142,21706861375052844683595820457538688901531393763031119579322611763049792865067,12400834297098033195346480176669546452877127463842848395269580039592533946307,18693408652472113120418656602007998722418946699666834214243410738193362834090,5734025542584829419095063290697837279993460564092839068131370421231150830964,18924630076511631254945042871273344212804227110396594419618744375738473997458,21814215076304113439159605823570645338718666334965210428557308969012775849083,15874497347478704100595228569012157674761828758432798819588001847304550645894,15630701992043410338260010633128892269216736379332650587736588580296378591400,21182316539430719202319661920312710080481096926576230463259085025268931402724,13427632056110349253603837202352903590918428276805663374267217475392463207302,10911219508671048309975190269088900191221091803425594935965400900508004506426,9158857576095512666804740759126852985161480036845995629848333137432364744220,3061727900948996735547324485012991687515955796128872254459502313385493651603,9484087600338383596528641950981362023967545451847364854943599173866192324557,15244438304843092101886329998640757457334825678432810119480500702489267475870,966872391220567196912397735096848312956568724961332613947113843660023937964,11463695793311663093741054432425795718511021724948561649345772770204331282701,4301779131461344863695073848029046722184482171568650483218315300688393400530,503085225024315480816360605760267420357374543116157267432728664696709665901,2152733644489285468694016160698899213530839938744988003049661235638107035210,15311799268435674361916200869320882308334015315600749428161144697607223747926,8821276262247279528293843357774532114304424863546634692022624148120506964899,15012215707563410212327951685975753138452396938302623171526151974041926043490,3832600555460338220245921307060619972944914111584149730708347861160918312276,4945512356937128186743764272299580525076021077689098424357488427223926571902,6352619611110096346414873193740535134097751304211531527845737802795592283759,10487432688972604512516548109465855881572886261854521534610720416206960307854,17622489873780167264774227253975567347204222125869234241462457566132215071928,7633353550826098030742486107449393642153730338494606903118637850284315354119,14024635247358847977026819464107185157647377185834445176147145227141238505750,3839080266490755896783758766005919524636645447105234209420661161997449147283,14295400414627547924873035695592309131547135626435254888679625991957098691157,9699346383521400413122931609905328425995515996718354291677850659748262244552,15892775179188924258683368801772704553840476123482448500492733919344870447160,20199645131225911044918007618559374867899861460760047877106143132248914945273,12001320852019564045161245401305456578767647373680507608908849898281736831048,14109337051994798438391426281455499687696832970217465295841248395157195678143,16327788711327335703187954019173408665382603544801329348791567767829649582022,14165345295389244679058422302892574411018017024852263235622041585515310700440,18098328140605761490641355018350075852862336947591383947449899194910504851997,17531934292095415392849417096338882004139134123682574245576387314018394586354,1733676683546726275638177172968959379163822515869952716090548401850898249951,15390925956113897743988821133394062442365524479421281886945584164621467664839,6308234777769318028945248133710542338224131559387923000379414195599812605031,18195940437872982705964842501287028751711989848794835251153117845868361639502,17490283477945958076039190253339223109810835246475119772790163703167194121322,15408396829836728115954873718864748500411741345264521674331031030247235075214,3551438511462216897614311415123740632223550882497302889988823516019801455881,1211190935634033568807015118513121103447278874630092924424376539010769615279,17406162668797550222384115208538224445727151774389004540678231208053715695274,20479453675762626017106163313206256229631927324901802475043478933123265498282,14782425647559744167182627327791886056751281195680302914811546501028210982186,925131908338441634745517290354664216337826881101842522634123686010539186420,8849707997196192490777875561563208206085973382242717199438345627124299133090,2076454320990941741925816538401596397546951763404696804371822796867698785368,17173134576726258494214130646402838956462459094351663199002055284799185636563,8278507153110957550422039807446721030659313329793830361362606551912544734153,21454855413436031867439010732150284197408206511012140387650556740240705522088,8938141846612216610282603832016394896549074914747256157702516831379429923666,3753004427655295864092888874901033504634515083469621309422669489429783662244,2366435134561993720630980767268361780485124472309182242565985427615594260755,16165357231356434631067514709216775568766632800191759830231349057343507534434,19619001519241758891959372143573350428188652312535228885075978087065138604446,18529730720102625006097708392875275467779439015225330756494090875760858662324,5652897308997297007169294392190006281027830654965418415676327691132517009477,13575260089385236342970650047136574844156206796954949409405285738862382638131,13051488122183433321152129519814259420249179451391427892934958106760313757814,16675947070785780493219656951197382898525312482169747446344506906972920892954,7175175603774065686796811506353067100604576034944842446058484596637779839013,1400986416499873501628131339252214540318552035055662222249409246587339999877,3464466866466806017745751012761954006390229805750136348643137486103734148919,18217858987033907489494644734206558680641423556261333390037659204834788684410,8406086726746620686898224574302006639796660679494669881199476338693847188630,17762341698784805474670945153199304225802481228485479435097247827908738620552,6223712186181276291315191942450380783893133091457934083606193355728586611122,4282900419919891825156385371067226030543529098387005106356966928605004273721,21245665052422749020204481966374990873300815343268950998971123603215733315757,6982432590923765268313576400153302843651774940912624901824133236148956994132,14604328114465343527250129263480156133215257207190011581958944554537477242146,4419171346687102376610201013900704798965178967312178557853149472731770706501,13245918223750947891398096117311260221538002135539665270124077712098715822692,3347693769680689230259648405537595614327886881079646330652620517715295020391,11097962153704048182055796266608903112109780112107618586656031611021161690259,103842991820173997936966388104541957651469231887516072360536421395334472158,10458487052445928020397135451416595147106158179032040258831628955988702925482,10900270612365580629478084761129851570116267768979394602611763172198923647648,9903203205178879991225339006690459919299342990467545909511182892622541268992,7206476963459461034052924246171589839665793743462578906114104789862742647145,6264046538214382166095990603552597379083154170591970728068583459736905241469,15208506074912456921421298757607137779904668310165212805848069781063650192568,14399898497646210477881830976333295219807765057833256267205543494652425724063,14270878504405431259159385066097540588788179903719271466546150744452837482681,2299469207691207005105135549235035285287116575059039549352935321891742095084,16821622844104951063765780536072686283845403348056960050391910562149383647957,9956020421344380373447956054462292461416421439742573500231969663699680679093,15930825774426452340437887971015387876460967360948156787859264923789690195070,10985728214199775151782154608793108221074450547445302100877022826701613291080,11760641126739413999815391346325702178866867588284525333479386263279622799779,12964764722311909921385583909124655151898642200440943348322605636391779313939,18379853927966213921019716164768637873544788239921704156188954474082485441441,15296912762863693782000299085702814599512114536531293086824435743573000852798,11055306663322542945964813101077231103838051414460193023274311763885249453027,8057951225246999526336336507654165264870114340865557474750852826611325059180,7217454204491887928591297314854022623729750971598154127245160014826014134117,14565102336180706753392276751790538414003260023904084675564779334184014612773,16932806574869520697162166869588187543526028859439455500295852309668070598166,9179898117866495045233038402762881324885778157159220317172535561846474551689,18779105085403868166483619694881906385652758088668461143173550878413116028260,11214136111470281555815079365242861297786837712776840366750250043823307862209,11442992999493383524983810131599863922453401327420664873617599429059754849857,16271323289864628346209913310699661044288655850612550590359075955707090062050,17108025350334840622180169650569770852833940341473970170517727066627050749958,13146248878892216294361188166665572028549000139712229260161108594416711673870,11427372820077962289622241022478467149286157602797953190515658164839928300751,893014835995617411380095483743111031917691099253220683676712243294883268295,8517095300100078150575343693630592663417209558229239005971749331683768522616,17927627171733468726764817859266182414919024487868681391571481635385817509424,2910874756516541331498135086483127887295864033618596807255973264881493597680,10351245804237587891981133156579115865490473264567370459691707360959684413970,12694211070090545997357986982035119982901819345677093614248046140600061957940,20283022323110075954579979019632104756139185475301167929737027848763705068147,15931844873010780159923673780071721836876296130477744289335217834580073984287,21827223850924748993974869213271539530659373002293617263857321497283795014386,2216130285102621170883691491664557599377015082391517585865064633069426967470,11373405503815639839270612384753272139664561558477978654573651197371057815151,12313875735580427829620793313088533328915412934622924938520740599744871213525,15142465061035421304605695594042142745567585293979295525147576522422528415408,19911123862342914329674984568751978176595422003509172434076759943963715219260,14262659769499978824697304563726231560538953195673261355416096174585413608681,14610683638141173050828300939153196590488444327501938863403192781649951814095,6637311287977459850936997036417480664822288091481538821362996372726159029429,15501657635921439788956110615190078759397404083654787694613599184616807587119,12415917438013473637314666005336278137449129158908612828862230927356476129214,3977073659694868689017260754925680384676839395821102222683036599314487912596,18021973030966989893231530982789547568199608264409750239459349680822956679629,4358661372125150502295103743733014495017362384424029473164385391234779773434,12150574573348685676904261170022340625206210894206500162919624199154445311926,19059564947466261856206182248882637129860510906425942015878496836349348075264,457803388293300831659933030795457353247367081441494540658944608302089214573,5212046878650303869536834084593989055518385481488493726863247051727387374999,10866963984944634834508529257930003255650324224099527428753028080514409460102,1567398629202166035061920213544077752133493577343656913517034032663760331227,1641623291671542299150077964313362112100008772415510478337935841080756871031,1814807183609065925468700221459835599229505862471630844515076416397596161921,18676591284813153230980779135662585498854259214169962891045023401932640144792,14582715392475730800118541203172619815507444658499922254753619352141615271717,5971201190012257917828174333108220091030383280212145099110362036705465802488,9745736062659480171553506036948675113562718355498342585124081392171087285152,20654605762814031873434196876396785695406369410937473580199071780191334325949,11844011087342569590330041590202444612516395732736950853259915342942395929104,12960729918447154570349545809398065983315955190065107446283057843674060399978,1912969365260456210218541172655492769437123937988143458973053151759348812779,6751278463897225433246228986310134589363747158535699169746372748837067912354,1405433090804402720301319240257714728362644500702704160642087476923303165683,17334203531491537592342457272578981899701055200802551766264091441355104806736,16575765689548766530893504204590870417122916172019674976779799591211403721688,12220976854598379181285138460526335801169364473128100040253401652070229420610,18565358629024373944198152078259356971563125515748886809957420832630624111647,18999218340435052500780578040305741910732238048488832712380773170203478504280,828469997232485965462944215365058139980461203417902215718115878220834198655,2385864265255813442011864217087321326832147642514277043179825610035123479208,11753087538734344167619786844012793078263845468062416000491296071906848786208,15297341509659920002867070368227904487875907462849401568145592054120947559782,17451904737564664855895845058410281315610351460549944647244100267528838462231,16288687708586503845827496209229686543350756101251970070831852982828263987682,17372190154611010904681208309570706747429785600046317069452832284803213135091,15112572862198958048036722322696004521384539985617885597335257056722713402392,3090030985871039557449539908126365491166718509536148045184016492804246563853,7579986120189318071341140006570025802626137718385790787108832330451957404666,4656625991418301006397045145531617124589866163929416672123076523538862286851,19496020801558863926434816068743011465607626373023757648812447085667986307007,13805329389975072362759970417944582121050551902725997016013251740633448473430,18188229086122124131780255528737492392822604407289151260248713532509782736083,14611835504502434276576475613524726992333885650957002636192032800434268523844,10917400920268125157880112072188560060076995206390296416305594303287585051306,13972231301490257961012583958703459454850999751676553092417436936263553366685,18328503113772388769765260234570641415081417900145352728842854263561232438288,237123037398988309289930744284813441581716633481073379308753775064025864085,1703922543704124573472350868371820728886443372137290454699485327716109471338,11303106151640297276547682977648977961130813769323129464984120148868796657869,780835119818217499025356174332702814577120774118181250962295467182217505278,7513776436281774240010548782707301011961852707217067098086617267751060890346,7053386733865795782344919942070418964042982090173077686333893187474076408826,15388377229685250353999590264475768848666849601695837177100149716633411294502,18619784384287698574679414094727959444475916860934398666937358687019863556637,6843956467116800550015577789758902600855297665349663446001269088726857226048,15027464760260005079316932218316611292633334115528481474392667994765319146064,3113497944921123135464097580210634621999169473508798646842600013742294203321,13922875552185745353363519166943408041900501129716418917715862175817917028807,6529143033058355347608548436453630783222625692384446386966623567146527415664,10224300829854530831381318053279338710395220281107133842738514322747972858570,20406735123273907201110501114056492687992916259913310564107896450511212255632,14266011897697023567365526625467367950062937074006135166584691625548787309637,6266823350995327247595338658995148275348018579417278062676982980758032485160,13382224019010393958018966744541120649420499028243672845532376433487586111361,17219221786488657036851893458562210759167416100910882352030211878162886142909,20162856829897101788693886235042939518715128237037117615656868509223185121680,19255871117980259796107225408238738190418971755264416661458453217281817348088,14978990393744959794726413403754476561984809686673856442658550453303982912228,19671827853594912540136789344716532059747421261482796306917878259275666282337,10732390517629598846596313835253769945253387192277550975463036830136687386844,17133415435299159639005309603217597288690767318016826234871049396559867937550,4238294829801619171082019239832000810131476156600856298143082034448277968560,7722327574874647121890494265704613777043492303801725732359520952354380593844,12398521387704975769381094211621106917110829744392349946808293674617176531795,11200776058775831613393435187103560072186926574904464246036376746754002391683,1438209332219971409989076556134294085612745796338690516891328286502107803440,2937570830929161760131625263024599999319751748792625900610926821498514203833,11043761204766219739712866580984621876221567501998807492499956572251345283273,17161703263657344245212174231645949667297741070344916641526821962829393621412,18619070492541478298708071132730313137437250499943292747935022132254737182602,8379242582671699656964937417808578910591927550726975853520669689659712748923,4461581878275014470922963327129159901508275066328903674248853463321568123734,8814779309876923204577653695802478749454337142645142889405691969158642344463,5916090197404556150255058868159426544438846565532168821258584401868379000295,13450130187167769463125976820336122102195298233114472585228206936434118870547,16312137321831916960674847439149202523298938366384118998520447019250845846949,3523905992883153108179926090860559860264215076129040324355490516029055984441,9941544263434232818617581658227915119072214833223636007382930887032695504069,5866421591020072450638507367259603444231034674337808358938713064987239652864], - [1098498142837982582047608372723518751721607512716925277273595859756333857326,498382712248562027578374863343601618793781182132084383060312181008958381971,19040726265283429618662679510157690394832296024968480927415996691029230011306,10367579130776133414495805974535693744211249758950881275217429221792836643614,1229596364469449066712193908302977020022727834238778132871229393863406546866,5594347757215876411130934611555467571639435097442631641074898978663329410864,625275312666547608222628560378372315159605662141936411119837279426221363981,15485529557721639677666143827295121022852505628489596851713462276650737776670,12156576509577081554587930818670905775536581975823788207855134544267814269606,1981640929928975005466842670997136169304057407742291166386016130552621471939,9375079124430521740651903984797221620963928972304905809259607327125669559872,268697279437287801043057266739136500465135819021738115532631740070584831216,9310725094036396036773344350803037792624399505581573214229419814378683970851,6144934044671205976376028664002834283864020049596457260475210339996948797436,4985941506647510031967748765284991041503308370910665002557248958100799063851,15851062719909725150709309168582658649310704358483047683106225599004779349418,9869770840966008659377598457679699092337106962689936558150689057592239644963,4964286354328869036674130011248598806906438908586967212984901377099285878228,13408525694456518383125684465410538061086669117275911801498275369395798296201,18263306792332242197764383101132914152275840410710698264525919817458731671889,10401786441956087930118823951510684636068781082958380915651220354850381871543,12496745101887166473879957440401384727148915595227764657145046356182346897947,56825204182651219072479187681186238157981743937496557304633023935549648224,7949519580094467639897040111470236633243836928348452962417270559805860514707,3509286722306670968352119363633866055096352721394520084890481975258162907251,21359945526252146173553061920944871506626324563977081669248710516265311530589,14649491209868365229844087258057697734286269047837985905275053819765825128984,12122186136173879572357400046587658543826161883897136171993927935307093999926,2666476328185593105035429309804341325262753927547102747066987631391232293139,21005241858197204874543384881533661499138265185107903730534607574687765896488,4866331653274711303641000079325074227730641553230218424779550288347820225149,938689939079340009195180604139206414955240264736983491692686499992823741696,950493909161345219342597929783079468041198261349024441783356363638640688155,8227093387774305505218050843028014038423742476679149203160700406235271548925,298899716277443866412562171123535849674476895336539413683307522836440058745,6985094123716229565713211140430519589886023406928617334981414752732877292051,4561102873171162160916461632027561255705058072826965137552144392802414262261,15422356128912397775473168682864290042256748428952418907369066530964035265216,21534011877473706794700774934355764894917955655606512952257743854629820348396,9461908500272520643111839486963426035162115487175673718316249722520977894185,9042969964854694648113546554619141983055960736166619708191725199599555275062,1441104948831954255692318866730011748129225465895791664253095290347818907280,19417400621113450826458192671383621002793369580946623762558060167661227354799,8244773274459817591888745631242804467035454174608673362960589130536385507190,17088086767144106377842029064730946925009348520592888187451688601493882340857,12886019902209719236096958359125451092745638766392722988311451127550961945660,20280862819329644063010032903732505647194710429034928708829957501178343790858,13239701144341900586601825324587185682073736334523805955933121583949546821724,2994618864933374534869864629648211464657674590007913715843569952783382900518,3072221011986428615228338853345294533299624086589539664037325300531050793357,13594276105600327401961157952766116939399999497643063180657161489419638074478,12904364780884039213184464580277965622079185353283126471569179129906875486852,15088962493677593800057541234990587773412340265413268221386103386021880406010,14138285403526705785804535000245522290348086552790608567368815987904186155718,13481415964846572771441311017814910258609608797603836070350286657768815710822,15459769479990273742477151452466966963353767555965255520456901549474045452607,8586052864861352028352866296665876117392195296860481710367953704812400661703,180502622991267551120688532508657597773982647209049478186474242637299204110,4785745751361586866577727263713743688205421961646731269452058881240942369409,4583871856798894230250707953295146343968130822948818555994825096960225600041,12377924729639905725281972784629126900954187435957722012223715002490809152047,21554415644278070156493674075483844873249829791940344144484983897474364915950,8390225843490125870104241611355504124284851919520955291024552578484662824128,2330476067094130593913781764168287559468546989640021387799865123741354870445,15749497374252464770935521609391859230015300749964554524771184068776070217841,16817654103281917947623051388088441309787140809596505043937473012669498321704,9987656178378986905964646161927549614205785047077068310684205046327286932204,21450061958292240283686535241652971764195183478875921481624114699420928365160,3904617432242099936494425054740854886663050476318725032541401300619628714123,21454964104289781104446533610149551385791852085041524046710270949744081353102,10768409462143965702783360646769759623397882338491564999208626639994081655791,19385613828688830964519526099114207553837496617978489639408163709100497624509,9385292780799468553063371906778802189174789542685475364513544798199315486080,19882577122462819381545089778080532575686772634821281258975533828284349988146,1462201549484596350490921057903425036211202388283463006651220816599917679116,16564642856725628254155356607086672564976261497486137590399143770170930986182,11606470848655267736219046910932382494518380844147406842964119623341701511194,546921055225672463086391798419385468083264065960104350335293012629066408625,12676737821548820987278730174038033161886561534502963159950183188070064038340,16429180804851559661054910451008618941371882312211198495282444364589225325606,8318514508896823373027050528521007144041407638548138855564062559664141902892,18546910687432012966956995548470714600618104024117576926439677823609854961263,12006683905722730408249989907056432037202625403043550391187503858618155798348,10816814135685807143320832554644398181525372167669730953193258726693903362148,1969445073620598650457101028079888612893685228913473332116076918643068711808,16873795316557869761040796336264749169213884122126281483001377666183529927793,8441268321647668856014389726368355391497206989491787976537908376817970369132,3378086906271763133245748026584767009750550242946195995254881868035794898559,12721353531573613369892164015903035636498816100971168742462654106875931342664,14969430369156214890953989610124286618925370029259450629468188666450865580556,8545723361883060050915916338313252821252873299513393695440138873537985282439,947668284380905375962163908708231363459059635485281084900173592739603282382,4418352807772484492818068921024797225893951828921880350002134747344565378254,18146914067008843660990756743559427698617136456156926109157771781314720068545,2353279078725994188579023195684884389261433430819033940093641668202046052763,18228226015329570627220992288018909552101992748538110505558715089403194764144,2251557590571495628913478692960173580728135227602564510397207128937882297417,20421664597091787362209209474226188711714308866665750343509458297343168321800,8187951594294388715811532560312339537604737243977265499957088579012554679278,15810834190411667509425096842396102750984990364193499272150958331088983323159,16884308240478579935994044823717491481297317573500280152191710196639752382061,234497484353824748419812158321111328486478789224631887096763967543932891899,21452418791072076854500976656696245147472896609273403517249960331326136475572,10860322289080285812992522532751459911253736747190334349942615321085283282595,149826608572716492570322179195234088797160854886751475825283168005807771516,11491761442863092383423796629001188933840969144934642247702733820824608517603,12099180244453415217270377899736157198045626379801787493348249001794558732373,13177983303979037999809722097100345612970493007300007493855625634642663397908,6849052800275826145043024580348093078809773712986428314364827674907764829568,21486255029472594818259653174918852363002807142725698741685253190938680807594,11451503340703054732459437884000132607423536025797075877436151438425159994269,8462539135531767509735697608276067216182907546891182278996691315801807234639,19944711893825824667372913293784300313762563232409638194240029859435259601775,10396631238556297232793544122243237485091433966091043100758266678889110827200,20667999270580360504376758654763163152764187226267414436968564661080084475852,10424436665500877000658892169756884171624649701456443210945810183301667922053,13894422482417998868290238401966517700776990643618129177567797594771207188055,9076475964444407787992938909179730031379198268423789105813333967195259669658,20479003631920854685589262232015009286810147171298477411667705150903826855301,9928015403359312830073752955992978705151208358029077246413002475277600546387,13981618256931763962905358530247354996931923386029793318275706908114940457317] + [ + 0x752af3c6fdccaf3868276685f0a69b9749e1706a82917b64ec2ef847f804559, + 0x69503d417e25f4568c7858ba8334301c0fa19c1b348bc7e18a4c1ace1d15418, + 0x25c1b121f33f4cf7b308ec4630f27b603d22aa81ca3595e801c5fa7d9770a096, + 0x23d6b55145bdb32827c1456af4d7be4c2d213e825c1d2f0c9ff99b2273751f6e, + 0x1b357bce3ef3f2b76afc2b5804805adb14cf6bf37fe2357c79aa7d6b32acaeca, + 0x28ec5ac0881c1e6426ba499409894a6f3c276fe5689f2c35c9027e80944877d9, + 0x2c9862524ac8a07b47d211c9c504c8b0bd398d028acf690e4b8ed4005dd06eed, + 0x1f6e6f0ac4aeb7a52343f30418078b40644cd43e290da0baee92891c4c065ac8, + 0x3db3517e233f8a76d21b2fb23c85fa7cacc577769edea09aae39407b9af2fdd, + 0xfc333dca4183dab479c5962eb05ee4b79a8ac6e0cce9e9b0a2142247bfd0877, + 0x1eed281978a8395c04289b86197673b0f2b65e1a135264527e250a5cdf99aca4, + 0x2e370db23857de3689fc9b908bf45ad8f42da900fdb4cc94a7a416286555a7f5, + 0x109bb6e5e04c0eb5297130c6524097470f3375c12fc9092d21ed33400617a0a5, + 0x73f4a17d45ce4cb6f4db87d6f3f5f4f1650c618e403e1873ea3b8c4dc187cfb, + 0x1a3bcd45a2b1dfb8e75686d3651cace13e1a22f5d838cb4a61b17417665eecf0, + 0x27214751aa86fd2654ea05fd2611f0d907287433875a8b0c3eb4b22d24d73ab7, + 0x1c5463d40460415dc684ef2415ba66628b17ab5f9fbc9597ba65b74892d34401, + 0xf934ec1ecd7ad74de590817347658a22a783496bab9943ca1a3c604d4cb745e, + 0xec2ad1eca0b260c4c6573f2f3b506e946d2a82aa5f9e65c2fc4bf65d310b1d1, + 0x10403c6f930519af3177a82f2be1532e5758127ca9fc84c93c652279618acab6, + 0x12cb8319683971740fa81660831ab6dbd3d93c7bcd441a912810d963582bf346, + 0x2c7cbab33b6294f292ee0eb31d53daf2eb8494d96a81c0fdbd62ffc681e71302, + 0x19e16c1b9123bbbf8fade03b4a36c5df8580f8de0163679b1815dc90ec581bf2, + 0x2d2734fdaea6da570313df4a533c0049e44b72b64906ae9cdcb3c86708637a4, + 0xfed7ce5d50ca2d33d1adfa990161fc780cdc30c5bf2d588184a190f686567c6, + 0x2533b8b3df21fce8544a6e12fd4c3c1fa09d3e1f146ccfab52af1ea4d6ea361c, + 0x254a9b0da17f1d13495dfaf68cde98e224f80697a0c31b89af097f3cb270f277, + 0x52a196789e7e3c6a020a0d2f82c246a903ad7f8ce3cede8153db72ac41ce566, + 0x21df9d899981e100541aafa28753e763a4c5a2af9845b0e9b7c4ed1e7beee2c5, + 0x10e9254d95c04bf4988f6de51fb019c8a7c5a20168b6a59479355e880028c873, + 0x1872d404afb8424952958f29d07b60d9f868d5f26a4d260f843373b706c3e850, + 0x2f7fbbb32af67d88737201022b56a6df47d476dafa7b88784aa9ab73c57a6f9e, + 0x27b5ad383fc085d2c2639e80629d7086e4030ae8e08ebb403860b4eb2b4ac487, + 0x20a04ba73975ea1af86ea418e5b9fff424b93a3807ecc3aeccec77de9c1d5b1f, + 0x4d2735db418968e804766f579f2a4abf79deeb66240fb29907b034db93472e6, + 0x210ba11f3526101019b98aaf9492c04491eeda701ebac8c66c453503176fc0d5, + 0x598c75413f3f84338c4ddf176e856f6ced73ccac8d5bc8fc6f12d5f306ec8ec, + 0xf1a2d9fa8407e310c58af407bf730becd9192070d7aa4215379d1efd9e6d2ba, + 0xbaf577ac2621cabdcf7ffed4073e27d1f711f9eb5a9739c12bd6df07a3cf257, + 0x23ba3057e5d9f1429ec7848b893ab3b40161bdbc6387c958c5872b4491b366a, + 0x1b6010fd6990d3e4928fdff736fa857bd517e35935e54a1d6cadd941eadb8408, + 0x2943fdadb96607530cd9f1000db50da2fc5cb030b03985d1d3cb53dcd6937ae9, + 0x9375b98fdd737f277a2ec26a56d374658f448c690fc8e376e0f1012e4da40fb, + 0x1c124f9f3a2672361b19fabaf0f2e1158b313fa2374b72c370b4662bf96e8a26, + 0x10e282b93792c2a893c54294446a63bb36a5b3565aad7504499fc22ebcc58836, + 0x4bf8cd673199f41df6b67b76dc46cefb40971f0fdd5e1fa15ee1921ab5d8603, + 0x1410cbdc261964a2ad500e3b6eaeaa50ea8b119ea11666f6558f9b3d5855acf7, + 0x2b17833b6c99d8d44c68f1a662a47493daba582bc549c3cd8ce47d572ffc9137, + 0x1ac55a0f9d9d4983292eb30427f1ca01b861f17809f2fd94d3d89b2f72627ec0, + 0xa5efc41de76c914410e9147e5e67f89c7792b20285cd0d15a1c1891e91ac293, + 0x1344b6db5439c46a22d144f4d5843e29c750b1acf7b0727106bfdb94cc023cf3, + 0x1a041839e844cdaa0f7c2a61ca9259e860599258495fb00d6a75b5c503e71977, + 0x2555c529d366e3d95899d9c4ad4c2d4ab284de4a45d6060ad91b8a8bc5fc24df, + 0x137894d2c7ff06b141e601c9a95f5664119ca32b55dc5e1667ba62524954a724, + 0x1f2ed1b26cfa389194477925f4dd3bcef79e89829c8c9645678343a13ab2f637, + 0x2072b0c4af46fd5d200122be5c5011f1bff2d44ab5d440ad946db4ba11b52350, + 0xcab3a8e77c43896efc4ab5bb12e3fd6d234a0dcb236c7c935c57a00338511ee, + 0x400e867efb3a8887126f96ca884358e969f14ba81be4df7668652e15a581cb7, + 0x594f14af7027250911a4b05478f659bab181ab426631fa4c369c361fef0e09d, + 0x171345094adedc87f3840f78d3f3ed67cef3b6a6a269b97198e012abf0ebb722, + 0x1fdbee4f85800afcffa10d76c25c01867b472d48da1296ecaab478190f81e242, + 0x1a37c8b010fe5a7f299fcf41738c50f5a904cab582e411ac14828e0c18ba8753, + 0x59cbe918d4cc5dcf2d3a31b3af2c2cc107b6cfb03b1be9a939a7f73c5075b8e, + 0x2f0054d719e7f0d3991e52178a020d3b7820a7f2a075695df201a5e292831b33, + 0xd3353ad739baccf5ca9a56840d99776b5a7fb60f9179dc15950c0639d18fb83, + 0x507a8c3d3f5f3965e2e9fe62fe9e824691cb53afd7430b625153661da3e94df, + 0x1eab1d2b44f79f50e2ba917a96b21934ebd43ef50caa5b21def5efd8c38d9174, + 0xfff97abc5a6318b03b46ea4361c8d29fd8a5a4dad51286897e77c2aba9f25ed, + 0x228907c146b4efa56af5b8f2e59beaa01741ab10f3287369efcd78e1b16ded07, + 0x183a209d14af4a1a9db0c647ad826fb75aa67506d03a50e6e937e3a4dcc2d0ce, + 0x17052b40860ecfd4bae684ae12271e93a32e1b703c3127d5d23558bd75496d2c, + 0x3a61810b60e019e3a5fb53fb055f81600c8f269b3c97fc228b373bc6a5e564d, + 0x296d0434d977a105b07f8e8d537a8381e885dcfe482c3ab773cf1c39b3bde3c9, + 0xbfac73b8e7f9882bf69125684ae20c7184882d3763ce87911dbc3eaecfe86c4, + 0x13900e213c48cdefe3e7090111aaf1c0873e21ba0f0b124daa1e9089677ea937, + 0x19f5725d859bd99469369d8a5b029401d90a4c7cf37267b4700ddcee31f78bef, + 0x10f8c20b30622bb769d902fec064d87fe8700497de4c3a32673414603f341f22, + 0x1a5d44a9d6eb166727f3bad1e4c9e4f20dd9e5c09b8ff1685813e84875f7c267, + 0x285812d1f7e9c5652ea549efde3426019405bb080408b01f51ff04af5ca4f7b9, + 0x17b5d657ca524c4fdcb6421bbf15dceaaec891e7a730177865542a3ec67644b4, + 0x1512120e54def6119fc731a80ebf8b9aa449a5e6a5654dcb16ee8781b55c40ef, + 0xce6fd9ff326d991817ed66f0fed93298dc8116c05f09e2144830c07afa25700, + 0x14c9e544ffe86f310c027522adca6e667dbf138a586e6fa425bf1f2b2114bf80, + 0x2e8ba8e57fe1c4ea06a941cdd2242c414fcc9a1e645b7e137ce61fc4456dfa25, + 0x1a1fb2e69ebf43dcb8ac7cf0e6856170be8c62ca1db0f77120d36aade9fae908, + 0x599e10ddc716d701d5857e23dec1130b5509c3913fffc727ce207783a2acca0, + 0x2908ace556ff1f368f843e0842ccd0dfaa42a34faf67e0b78de6c47de2b6a036, + 0x1e80d381cfe184b2f11fe38d64454a6292eff23f524d6fafae34ce150d1b8405, + 0x32c3b2a8872c39fb3edc92ef95e76fdb6381f829fbfcddef26004da5b5d720e, + 0xf058306e4f397b7b02a58ddae87d5165f21bb6109be64cd3175097f63d0d402, + 0x2a978242c551fa8626d0def5ee59675998dd8ff90eeafa7d935b58b8a2d0d1fc, + 0x2c646cf8d9ed14746f8a2a438cdfc86b70fa1c31033d4afd8694a7363d1ca0b1, + 0x1cc7d59c756a8e93071f95f1eb8a5cbc2aeea366715432873be8f94e3f9c8733, + 0xd09d0e6b64757bdfd7128d041c430b0d21a80a3792d0674f0028872c14fd8eb, + 0xc28d39d145cb8b6afe18576403080ed19451473b578949a491a095b6a19d082, + 0x22a2a85f132915aa09898077bcbd76e572e4340d8085708eefaabecc37ceca1d, + 0x1ad68c4e148a6c6197fdd9fa2c45f8c6f3111ddac52db08bd2ae77860e203a6d, + 0x19b59a4eb2398896e27a0e670529fbf4b72c3953a82c2bba9541a52186cf7477, + 0x1e3aeed61e3a7bc6dbf7674f8002a59ee28d3d5d51abbeb5d850dbb3af50559d, + 0x237d14fe10cc10d41cf7b9545c5dacd245207725227ee5d5578a3cd163c4c161, + 0x7a561b03c03a856f5d7b15e895448401a8a4ddf1de311b51663640c81cf44c0, + 0x20e3c12021f53fc206893985647a3ddd64fb1660257a4b9d7d33fba8be729a1a, + 0x11cfdd5386f9ddf36e9e1a271c0a8565e03aa7e427c624c5050dbeab40b10b65, + 0x97b90f7016668c55385a0f101b699d0c924d1556918eb58c9d9a16c7815b3cc, + 0x23dd4f8205e9cb9e123e27e80f46b8ebfb4554df41528acdbca14166af70a8b1, + 0x2004cf48392d1d3492069d0b20c5ea636c7de4704668bae0400f32d0678b5f90, + 0x10efba7ebb220de9af4af5b3d2cf4e3a463d6f61b3a51b190b392897922b15ae, + 0x26ca8fa32860470e9ba95f2b328f45b6d3aea8c6694f52f7b2b6139b31f0e659, + 0x2e7a6096889e932c3bbdc1234b042946ca8dbc3bd9d42894e227abe994b3954c, + 0x2b2a5b222000c7485717e5134d31d966d01094d20142ce0be0ed5bcd238fa4fc, + 0x5d252566db243c26ceed95719ff4e6b2db926a82a90af66c3913457724d688b, + 0x3016d7a342ccaefff833834f8c85e4cdde502f4cfd2e5e67a434ceea8e7e8734, + 0x22e4a5742720cc545f5a8b5ec81fc76c856674c2956c74e93d09da15b9ea85da, + 0x158c039583d91471651b425b67a9c428746b7d2ff4d3f9c7805cd097252882b0, + 0x2e2b9193aee7573ba18105d36d5452636f0a4a23f6bb808dd7b8351b3104288c, + 0x15288eeec077977863bbecc27af0e88653434f9db50041bc64cae3a4ab0267d6, + 0x294ac3d23fadc39ffde4fc51c231fcb1e9043d207384a51281ec6993806fcbc3, + 0xc994f0154a6042df030cfcb8775ea9baf8790d101fb004f7921bdefee4dd, + 0x23be197c83df334c3818a4eb54f3755fba5ad61c6ca408d6fcaee753a2e449e2, + 0xabe4f60f5710062df7838a25e613eec5c7c500292cfcdd88c4b104f92e66dcf, + 0x22d9eea2ce981be68d03a627a1ac38ae17393b42fd589e8492df86bd03f69ba5, + 0x17fd7f4e675f456e77902bd68da43d7a0cc8ba75075bdec73800b670faef2c81, + 0x3cbf13917d8f6962b85bd9b1b475e083a9a6503290264d732bc7045eb4c0e7a, + 0x13e3842e78b6be3414c29bd5528593673bcf7a071c9e547d4a6a8e8c1f29f43c, + 0x2638bcc34e7ec977e6205a356d8073edaeb37d6d0cb2ee15ccc657e00884f71, + 0x1824a36f9b33cd88b29d9d56794c02f0498c8c3520cfeb8d7d23df01dd11bcb8, + 0x2f64d3e9e9660efd747a28a181719770cb89acc868f1db0b42a0d41424d5b97c, + 0x27e976b95c1db0a431cc63d2bcb77b7420eab7240caafbd4f6ed94b771d7ee20, + 0x71017cf059038a6f1ad9223c843e6f687774a7b677edb7d7dd6d4d8aaddff, + 0x263e1eb69b7b2c87f3d9f4d492100367041a00cc20091402d6bf495d74deeba5, + 0x1dbd8f7a790ee4fb6123d8162e879b6d334e137c224da75baf9b00dbd5b14a27, + 0x1df0f444008cdfef43484dc04f5fdd1694d6c90e8f2e35a1850831879d9d7a2b, + 0x2ac29049462ba770408914036f0fc449f4ac15c4a5c16768e95e2486c62da8b9, + 0xafee4216cde441ab47db90ffdadb12b08978ac6f623f3acde4d4f9d8c77f3a8, + 0x1f5df5e1d3372dcbc83d7072bfbf2ba8914024e3398ebbc3461403d39a1e9895, + 0x11c09f4be4433544bb604db662a722bb16824fd85c484c45bf25dfa5ea9732e, + 0x111ea5feb756eb07f942b5fb23849db24d1065b278b4643d55311c0672cff942, + 0xab7c194763587f1dc30e0ed53aeb6eeb6036acd702bbec9509d649a81f940bf, + 0x282c5951f988191603f9dd07759a4f653f19976943d20e30d4c0f8faba0daa05, + 0x23b82721a7cdaac2a39f7b4bd10176e50983f32cfda8bab88ea746ebd4d25ee5, + 0xbafc22c31e735870dfad91a56a46ebbad29b29e531649c85bf79c8dc91c792a, + 0x24710e9cd9f6f42f71cc8815934ce87ca0d677facf1f3d89a9abc2da898f9687, + 0x2475ccab50e2c13fb5d772a07571e0e6be551a55e250e44f22adf1c7a4d7ede8, + 0x17326fde68e193e4a31782f2acecd7a468493aa94d63833575ae5184e9ba2441, + 0x1d044be025c79f610d4009ee0a3f3b50dc556e785718d196e67c60fcda498459, + 0xbc38517b0bedb66a044e38b1c199d110fa36adfa1251d46e635f22ce8fb3b61, + 0x218a7ed7b5b4e39d21cbd4ecdf0d4f31308cc205583a9ef6d91ed6969b45c27, + 0x70989c23efe1c0d6089f9bf987be86854b4bf5aa88b37dda3b4fbdddb068f36, + 0x11f0a1f2d5894630701027346163a4c6974023d321780e91c8df5e91ea930c7b, + 0x9070202bd144c45ab704c72dcc40a5566cbfd5826f7af4746b4472b1e68c390, + 0x243392fe4cd6ca6b6747596c387450ce6a1ae7b0a90eba222c3470d8a80138f7, + 0x1a94265093ab44062e5d0e67df9f4b702df8de8dfadcac6cb4229681117a5da9, + 0x1ab31ce49e37f690baf9ec7b1443357cd24d7bad16a9e6e95e43b6564d987b1c, + 0x2179ceef0feee3b0b03c9658e97b6342f25b208d7ed8e526150fc3b559128c5f + ], + [ + [ + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x9813c803ff84a3694eedaf4b1c2172615275dc18ca654c799a70440946ccf0, + 0x202973f7fba5bd21ed58bfe7156d7b29010d41090f63f1bb290c1d5da1ad60, + 0x12305eadf64dac24a7913a62d95aefd45f48355576c671e56fde9cc7c8344ffd, + 0x25c783ad66d6a1fc6c84770bd637f6207097dffb0378d7e0395f8c0b86b505f9, + 0x222deb606f13cf28c73a67216d88b16f5958d5d292ba10ef3bc2c10f5a0b613f, + 0x1614d025472771fd870a9e9d422b3571c5494e7d679824d8fe1212177d5fa2ec, + 0x1358bdd6b7a51b1f5b5d094dbd8ee086ccdcfb9c27faad0806e8ef718d0e2b1, + 0x1c2007eba4d1629846bb69404acc84565de5d24620f75cfcd9f11feeeb3f3748, + 0x22f49d7244077e41f409c0b353afd1696e3aa15ffdb4a0bdb883ffe7a1a87217, + 0x1951523a4270c54403dfe3218fd3d4ccefa43114f1b19fb2c2821a4374718b9d + ], + [ + 0x11a131a3778c3774233bc54096419d463d3abbae18322a7e77a511881665f93, + 0x1495af03dc9180c886f0e1bdaf9d18e32e6b0d1b80370e7cbe5745dafc433523, + 0x119344c53707f00243983c6d024fd49a0f8af80e5871933e58ff87c3a1f48b93, + 0xa92bd6a919d1605615786f2efe80743ca57c10ec80cfb926722b5bed408b79, + 0x1c7d3a92caa435cdd974520bb6fb6cac81634cc9bf4e534df77736e06d768c3c, + 0x12fb88a0f6f749d68da9250d5adecf088442827248d67f989fd14b5c9cd4d4c7, + 0x2f6c4e097bb5851be12bbe2c712c2fa906f310b78048d695b4aad301ffc0d268, + 0x1c06c782fbc0980b9e493b29a5e4a04aefc668cd4255d6cfe208e9e7c8b9a1c4, + 0x211865b7f9c1c791a33d703ad3280f69756324349afc8912a19b83de2cd06a0c, + 0x25542e07c1c13979bb14f8d4ee93dab7a3dc750806cf37f2c02ff53b4bb9e66d, + 0x12b5a09e1e95e0d01fbcd234fad473d8ee2ba976fa22827ffa6dd03c8b25a64f + ], + [ + 0x2a18ab4dc4777e13cb8358c1c423153570d1cb909544243abdacd4547c8ec3aa, + 0xd95e8cf8a66b56c32e7d11e0107e41e1297122d1acc41332f1b49895a3c97fc, + 0x7c22f96f2f55653d04edc63150567a7a04609b0b79eecfacb1485dceb7bc873, + 0xf716c54de41920c401a62df8f9186e19b9523e98637a5b113d61ccc30ba0213, + 0x2cd68fc31b67dc45fb6b16f42b5eb89dba2ae7e9aa50c5f1915275a81887190a, + 0x66292e64e6a2c64673aed365cb50f7bd4e1d3b5270f6b2e9982590c3f8400e, + 0x8a1ef65f52128eb3b22df2b6aca30509b0af8af2f7888eee766c0c24871188b, + 0x24529638ebcdf26de8816287fec6370614e112e10c039190c103a75ced11b426, + 0x12e4b5408f48641951739ea27e521067240b82aa51a42de2d4dc1e8225908187, + 0x84b88b1ce4598b701cf96a3379a02a3157d4193c8a8f1157459f6a34ec32fb, + 0x2c184e904d7bfd368d4495b9e3027f9af6b9313c8f193f929ac9e24d10d7a36f + ], + [ + 0x16ebd782cbcf6d63c38b87b27db2a4a5af5847a9a60889c4cf6aa318d6866b1e, + 0xb05f16108c4616a973b01d82e50d4fc9dcdcce67d2d21f852816bd234e9872b, + 0x2f394cfd3e442503c3a22512aa4b76b95b743c7076ca4115a9fbbb7c6b07ee5d, + 0xa157e244f939125d57f9c8e66f7d88ec0fb3c05b90f526bac0871bca84677f5, + 0x1d4567c12db648d4a9c41324c0329325b76a07730fad72ef9e490a748674985c, + 0xa94a2d7c4093c638823b095733f37176d7e747ba24645b515ac2a241ffdda81, + 0x2f6f14502f20d958a9ff23b696cac3ae24967517ae8b2e9592daf451840bb98e, + 0x12641cc3cf50ca67bc93bc8c19ed89d4613e9e281a51cdf313cbc8111922242c, + 0x2185c7a4ad8cb21f19009396f134a2c3fd614d305e475ddd19f26f6d4b3f9ce, + 0x2f6da385450911cd272e13601e7ce66c2b91d809307492f7ee578ae34d6f5fb4, + 0x16fc48e55d64d83010ad573377ea2422397fc3a7e6c88af808a566de0223f0c0 + ], + [ + 0x2b7ed47fac275d34f842f09b01ef9421014de040c26a591595b227ba7bc6fb2, + 0x230b62315b30bc49d73dff8a9de79c620e03c747b14c432f170715e588d605aa, + 0x206351750037bdc90d4f3e7918619fc690c2b5857f8bfbd86d7c001e4cf2ca18, + 0x2218be861d524eaf03b9420b1368e9c5aa7cefee72d0e6ef80732ee9d7e6e2c0, + 0x69ee4eb20b4860d4af91afe1781338f53aa354562ecd873e0e625af70746f26, + 0xa226128da1d9bd5b329f55f52c75682def3369ab13359dcb7d212eefca86229, + 0x17ceb42a19de6dd32e3b38cc2990e64273b52a5618263eebfa49d84518ea3bef, + 0x29012deffb112eb14034159c59162f866d4a1803b4d192a4329359f0f903266f, + 0x9c4b2f61adf245266168cc918e96f7f8dfc35bd3df7b23fc641ef01bcc71cce, + 0x1802b97e54bf3a8978632cbe10e429705b03680325d26ea190c0f1ebc7362ea3, + 0x2db1ac4c2b1c23a00027fdcf0f663af896d87415bb035b149d28ad3da98c6fcc + ], + [ + 0xc5e49e319fb9535073f07f9e055accaf3e3f24a35dcb46cab67dfc648efaf30, + 0x15d217a31784741048f326e155af96e90b5aae734f06779e698864039c92e123, + 0x1accea09c2bfd17f4061725c712fd1976a07e773e54d906da166215201a58136, + 0x2f9bd19d0c8c3887a7fc0173f863f075e66b183ad89f13704930416e1d5cb7ec, + 0x6cad0c2bd438c4dba2ed64bbf75066e731484c36d1f6738b6e98601e9fb498d, + 0x1b5da83966361586e8810fed032435caa80a9b476db21290474ed1977fcef22f, + 0x2adbde5c7b73e9a7e22b913f99e40d95e689c65c428c2397cd273923cf68ddbd, + 0x1a8b8ad1ecb6cb888273a90bef8b1a2cfc03dd44e0b28b18e1074e404a9e0f4c, + 0x281eca14bbc3920919e001150451c3e44ff18e1dd1171412ff5e663d74a073c1, + 0x54cc81c7d1d59581ebcd26b16ccbdcbf1968d77f87a2081d13054f51118f7c, + 0x170c05a5f8a55d5c9fdc5e8238b367be358917a19a28b4c47e46f3e73d42a085 + ], + [ + 0x161e4ae5b2d24cd638ba5c32bc2317bf90d404e37e003f1055d9a96e406d30d, + 0xaf9afbecae1761cc17d44b51ca66d1dbdeaf341e85f1082958f9cb72f7b55d4, + 0x5e52c0ff8c04a8e5e3c7eafa1d0902fe63e35898934b00f4333b38fe614f913, + 0x14eb401c1084a9ddcd5d0092e5d1a299aa0f55c351545c781703c01ce87d6b29, + 0x1e0e166d734aa614c6b53db4f691179841a33f8105430a3ee70abca83ba6ec6e, + 0x2fa75deed281db734faba5b70eaf57962f93e2eea1d3dcee34c81ab1e9fcc0ee, + 0x14bfe33115df293670393e1dc8da4d6947acc4b60249e5b1c8cae376665cd580, + 0x17ea198f3ab261da000152f26b0eb0ebe088a709e8b06a18a3dc2108c2096864, + 0x533e8a454b8cd6df8d48fa9b0a9cb2952933e1a6b1d423cbc54d0533a72599b, + 0x19681b4242d11e28aa72530cf33a7d15719f1a888fff625e04652c77ee2b2de3, + 0x1eb7f6e5520215c15e274355b19bbf71abbf04aa426cd07da536cb3f909f6e57 + ], + [ + 0x223c7fc6d24fc53d1b428edb8f1c52d20ceec592187d2c7a6b0b147b6292b81e, + 0x1da4f4e3c6790ae1b89c4118861d8ca2a50cc82a4e7f1ed3c5ba8cb944ba4689, + 0x2e708baaf894bc5835e5fea81227fa8cfaef99086d12b0a3a7f3f85bbca61d28, + 0x13fe23be24261ba5b92d363989f58e17fceed4a858d1c61fc2cf2b71dbdb6936, + 0x1c879c9428e19607d647f5ef1415e76f7c59fd01e52afb80486081851f9a5284, + 0x128cb3150b15cbc4faab14bf7d676ef3682b52cabfc8d3419dfd98109d19ecc0, + 0x2bf523cd8aa3be20ce7d891f8727a7b24b72a4d4838484de842acc782fd8bd32, + 0x45aaa99ce1e06a3c02150804a91087f57a43b79797773e83216ca969e873380, + 0x284ccf70859547fcb9c3c7b64cf0ad62e51726ec81b58eb01c1a1f8ec7a9eb70, + 0x1abfe4b1cf5db29d4078e5289bb143498abbbdc9af56720470a26a3dfa2ba855, + 0x14111a74bd24730c833699eb41b38f1d4ed16fcf0fecc1655b76f2437d4a0c9a + ], + [ + 0x1ae060e39b338d09845e2e9ebeb70bfb74cd4af926217f5732be2b6cb7fe72a6, + 0x2860aa52dc2f967c0c1a0b942ac81e02189d031430c11a919a5aa895bcfb6151, + 0xac23f00ff015baab1c8be9a90943c3c72d17818be7ad427c45eb3ff1828727d, + 0x32fa2f166622f057f61a9405c9256223cab2ba82c9495607921755ab018f690, + 0x215c0cd4e3f1bdb482b93e571879d7931be90023d7a220e8f93b21c8add41ffa, + 0x52700b19ef6d42ea392e044a094cbfc308eea1f72f2a3428b1e721bfc32c6ad, + 0x33b93a5cf15ffbafa2726f2527824a11af8e42e01d3a7ee159b273ca0a6520c, + 0x254e3acdbc75ac592679b032b65a9c91d2e092ab5e5719551b5da635b13e9471, + 0x4fa5620a2c057dc552a59fdefe50a901068190fdc3df8761991cab50a01a449, + 0x1d2279673f6cabf0a1c4b8eebf8e9c78361680b2e59d7ec19348819f5b3d5a14, + 0x2d46b48e5090c0c56a390de373f4c9a2008db311fe31063cf4fed54629113585 + ], + [ + 0x46191ab41e93929ea51f190fd4e773ac8d5083328d4b2f04828dca3e69098c3, + 0x16ff33d67c85121bcee7d81cff1618927f1c92b4d1d21c2a07b6ae18b2b7b9b7, + 0x2134798f4ca7fb9928012c937f37de87432b8665aeedf373e7ffa6fe0c13d00, + 0x2aeddbfa245756ad1e1658629f747b8da7593b195cc950324f95edc9eda42aaf, + 0x1f41fc67ca1322b37b7aa01b631fd19105281f6c6a4d37fbf68fc1b5f62802c6, + 0x22d1e64d4ee15e60c459d851ef9f3495e937f5a90990382c97867c45b7940071, + 0x249f416fae5ab52a435d65201006dd8ae8d54266e4d5643307551902423f7cc6, + 0x12a996abc8577021ac7880c16f058d9e06e9511187f0aadff6bb640e4316d26c, + 0x2d2640a74ede9af6c9888e5f68a84fac92b13337dad8fc6152fab34b55419908, + 0xf246d2fbb4e1217f09631fbc8770827c36751e6ad8d6fb16810e3395143ad80, + 0x15f30ebdfb8b8ee644241039a26b408dc7a8de77f2cc6fed754b703ea92dde53 + ], + [ + 0x14ba1b5383e3733c63d00c32c2bbffd8e54507ed33bf7544c86388191eca3e40, + 0x1ba0e835f47626b0d82426900c49170a8be29c39d90337aa5fc10764e2321a1b, + 0x219f5e28a5fa52689d2b7be432624280c940c9bf9883c1fb0fe929f78873c1b, + 0x123a6055681023b16570c70fcdf3ae8e387a973690b9e6761be22f9941d7ef76, + 0x1dce36062af7e4b0098f5590622ced7af9f28e88d476cde1391eb30408d5d266, + 0x252e74746677fd7584ceb0f8aa6936bd04f9528ef600737e9913fe4b5698eb28, + 0x19a9079a9897a237074252767912bed7b7635ae8ca0ede2dd3a42a75c1c6b81a, + 0x777edef4d91520fcd490a22dc569a97e540a0fdb527b4b1a3a854fe346b8e7f, + 0x121a3764269fd35cdf1e621c3dc6318f47b862380ba00357849d8840059463ee, + 0x2f80ca151b077b50767281ea5d4c1f7457f8da444dda16d8149bb6c1061ed0aa, + 0x1ee950c45a0c2f4a4b64688a7935ed2b63d4fe5b414afa05c1a284674409f165 + ] + ], + [ +[ +0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, +0x254a28279a58c838f7392034aa21d51ae44e1449433d90824b817e44b90cd22b, +0x281d2ccd521bc060d152223d46196f27b048f33ce6ffbbbb0884f3d5c64a6061, +0x10b388ce0c7860c8a70c4e903e61b3bf97b87e324c9150ce576aade8b2d06a1d, +0x3ed1d46b39ed65512e3e4c8d53cc1d2cf110cc65e1d65b37f1e5e785a6fe6e0, +0xbbac4700573f9573a123ac6a2735b63c48df92a7c91cfd1e88186a061a102d6, +0x4083e23f948783c32f671cad0395794a2cfa8aa1c1cb6a0c0105590904b2593, +0x1fa80347e1bb24e08599758c895a5a13fbc63df14dd9063f5ee23e5cac163b61, +0x1e465c7a4b123984937605aa07cb8cb830591e22e25b4d94d2efef2f25c17f3e, +0x125febe3a720ed956f1fdf75648260e56e67d32d0e785788d1cf97ef61f6ff69, +0xa3e7d3671a213b3184ac44ea74e12085cf5380c688ad23e8300e69333c123a7 +], +[ +0x11a131a3778c3774233bc54096419d463d3abbae18322a7e77a511881665f93, +0x11f3eefe7629e655ea90af7061b775bdffbf26dfcb0f67a5578774e4b237376d, +0x11f896a08f039c3fe481a03e0b8c880edbf71b783d169f4bff14bed5e1b5f15, +0x127270ce679a10a9b93645264ed270d96f109e3f65a437240d629e59eff1b2cd, +0xe81abedbcf77d0706b6a4a7438b5a9c42257b1233f0426225c8d410de5806f5, +0x1bd40e4b13c0eb7bac78d2650586a59f28b7ee26be01fa2a677e734078bdc210, +0x22202ee3e2df678269ac3833b87fd279d1d045fc42eb3ae75107188ad0e39bc5, +0x196301b7681fd2882ee086f61a83db475a030017f92f72dcf3ebeaedbc571520, +0xcb517d9337709a54dd958c64afc6c8ad84fca2f59fe3098f74a7537debe0d2e, +0xd9be42ce8bb76bd249d36ba2d8c5a70b52d20c9c8686b7cfe346d5c72bdc15a, +0x2240e2f64b6f5bacdb2d6aa0b444887a91d1ce0eb1bbcbdd58ea71499b7a85d5 +], +[ +0x2a18ab4dc4777e13cb8358c1c423153570d1cb909544243abdacd4547c8ec3aa, +0x1f19f9b9169b49713bfbe59154cd93aac19d03b4668733473fefac6eceaf9a63, +0x1e6425bea9db8ee466777ec75d3103cd11ad6ed24283a0b188b5aade7d496cd4, +0x22e2d64bc44841b96bb9286970439150d70c55f8d65fa79f1a4ab34befdf3c15, +0x22ea712a97059dfd8af604c752e478b8d883333e6749b2ace5385f0ba8697f67, +0xc19fc53d6d946af3d7fb79d8f22c46df2e1b0d0f2cfc983345db3287c44853e, +0x177800e892cde6dcf66dcb1c337b6f7f6f6cdb54dbe7e2e2776abbfda1fc67af, +0x133f706a099e95021e46b79e7f0fffdb210d87a4db1d129bd6fa5f62113cee23, +0x2c540ac453bc95fb61ad879a56126d5fec7ed9300d545938bcd80c2feee7a3e7, +0x2575061c9a069654a195fe41554ac0f4080dc8f7e808d676f3f33c615978d593, +0x283d7487aa3b5d0ede9c741fe754882776708f9bf68c745abdd38250ce70c288 +], +[ +0x16ebd782cbcf6d63c38b87b27db2a4a5af5847a9a60889c4cf6aa318d6866b1e, +0x15b3fe328216827e93598e15425979e9dc4d9b9ab421f25aee3e49bc6067d6bc, +0x11cb96a094be409eca05bc42f6d8ad0f6cf09cef2b286fe5945d587cc36862ea, +0x1e5c6cea55983c991761cf70ca77fc17c3789a8023d2752554b49d0b8fd1be7f, +0x257d458a2883c760b295e5b2789e6a942b8d50fa6fd3eb093a96ab81a9aa693d, +0x4603c35c98c1e379b235724bb309885e9b56284a6cdb1cd0d3953270109bed7, +0x1b2957f0c085f578b4a1b58a21143c551e5451ec46b9fbf6ffdd0cf6e586a00a, +0x17bbaa8b0ea832469bf933ec6ee5941a1bf97f0b7b1f6b0ce3f708d43795365, +0xca0c774b1bd1c2b00fe8f6698cb08022e4a3fcecf13d79953485c905b76f8a7, +0x1b0265724a00dfdba001c87dcd71e5c04736a61821b19f30e02a4b53eb59a12c, +0x29ddc736b1d7fdce1bf6a2f684702703e857b3be81599e485932a1c03f4fa16d +], +[ +0x2b7ed47fac275d34f842f09b01ef9421014de040c26a591595b227ba7bc6fb2, +0x15a1af15f1f7a77a5e6e760470e7b7cc4da48f3fd35b1b01f019384381e37135, +0x15810baa26cba809c29275debafe2859cf2350199af232bf920496c5315947a1, +0xa1c89983188b5230102c213ce35a9fa49743c5490356fa305a8578c716f7202, +0x2a9243c6a61b2b7464f22e1603009e6b6f7946f31cb71cfd4d291601458ec39e, +0x14b216d879b61949c8bb2ff6d43bc7fc3c634a90b766f2276b0a5c6b09938cb2, +0x2b2b79db9b5bdc6a1844c4e5c7f33806d44ad8644fa0117f5bbfd7183754bafc, +0x20f56843ab66f86615274f77030d662e1f6cec212015e14896139ff6d28116d5, +0xf2a31d4612576ccc0cb003c57ad2db723008007b066054d114a9ae32d8e604e, +0x1a265ab962a3796d2cb4ee2980ff3bcfa03e8d6738d59c8cfb899cb771f9a61f, +0x5f7ca424f02338e81927a8928c0f02fc78eb1d1a08c3bfb8965cc7b43d8e056 +], +[ +0xc5e49e319fb9535073f07f9e055accaf3e3f24a35dcb46cab67dfc648efaf30, +0x1d22b55a0b71329ee03adbd79c0a1e7d32efc4d765e6e581ecb349e2940f394b, +0x825a6da8cf0213b181fba494995ef1fedf1d867f8c777ddb93d10b64f1f3bac, +0x189642d90074b6ef89e102eefefd69d4d69e106cc6d77281b971315feca3f6c4, +0x1976bffe10562085862cc586a3cbff8d260055e1ca382a74332328c0eacecaf6, +0x25195d63f3bc30c2896cafcbcca1f5b73ef4b74929359594e4421c7c9a1c8f8d, +0x1f523a01526f1b783c2e3760a4e7e9ccf8ade4e32b56002d15baee4eb794465a, +0x17cb6777e65329e7c510142a85cf3781ba33de3ceb98a4ba021d783d212e7492, +0x1308c2b9ba44163ab7190c4c151c7f44f2e19eb186dc82a2443446972d667ec2, +0x3006fd98ea0d9db2b33144f885e201534edcf4c3ba6e96d8a22db2bcfe8ced48, +0x14f241ecdcca69b025108efd0fbf00ed34448e7bd804d5e85a835619791468a4 +], +[ +0x161e4ae5b2d24cd638ba5c32bc2317bf90d404e37e003f1055d9a96e406d30d, +0x2b04ed9f42228f06802c0b537dd014217f3c444670a0c6f88b3b5ce001b0197b, +0xda48eb83004661d01df489e8156b75d9b661c61a9ee1329fad03ef74521def7, +0x1ba1cb5df0f9b236e9f7c4f637dd1e70784a2b07f8e062088b72c3a392d44b2d, +0x2c22be8e5b7f7c91490c46c27a09e91872e361c1e6628793b9674569ab3c0b1f, +0x83511f996c9f415dbe56786f78ec97fd8c84f5d4ffbda454b3c4d5901ec92a6, +0xc3e13ba070756735522097a41a9138f5a44cb5856648daf70bca100d2346b1a, +0xb14339306b1b2e3114e50b0607215d3f92ba684690d78d2a6ee417a73933c65, +0x25c2045be7d9a915562c78bc1ea2d954155a0289f900c757b7138596edd9db6b, +0x1b909b20dd52d51184b58d123962b7fb22cbe54881117270d279402c4056dc39, +0x1afef8497500f3d89345974c67a21f1e18fa930f7d78a1ca691bde258c5e2c7e +], +[ +0x223c7fc6d24fc53d1b428edb8f1c52d20ceec592187d2c7a6b0b147b6292b81e, +0x8bd608629b132b0d741a305ba0002b9ec1470499f5c0ae88e26f269ef00320f, +0x238b46140eeecb9a32c7289626b692dce13cd51bc3812f1b0d866945c0e08e41, +0xa5ca2631a8379a163fd40936e6913afa60c1850b9e04b622f2b6e109d179ecf, +0x1656737ceb63a2d43d462ffd902804d11283820356001961f1239a1e7cd23108, +0x168df74339cc5c612553d91ce34b44f60123aa40e8486e3177cef84844529bfe, +0x1d1cea63939b21940f784f77c0f79ed523beb6df5432911930878b59f92c7f63, +0xa2768ee0edf0b7e5e69a734e4de8129136b926e5ad1891e6cf57a5c39a14da6, +0x22c57e5689822b5d931e748dec46c5e64c04067f579d96b89b608ab5eb5a1e38, +0x1d4ee90cc3cedbb9973609382c57bbb1b7629fc5398ba62e2f8f7a9c55496ca6, +0xf9c70d6ee5ba237f04597a71278dba03151a3efcc594cfe61ddf16b5cf1722c +], +[ +0x1ae060e39b338d09845e2e9ebeb70bfb74cd4af926217f5732be2b6cb7fe72a6, +0x81e512179c27b63294fdc958ac35b91ca61cb3fcdbe4e661ce465eb3b060adb, +0x64bd952087ea3f724ecaab7ab891c7164148247b3d9534508559f290ab2c455, +0xf48a6aba18109eb41509d160d2b6e2bb75b73f2d360b142e2253e99285a613d, +0x2144765053902fbc1577578eccf3fc1990cffbc464b8d5955e387653e427eca0, +0x149178f36e2a8348229d4e5f829a53620864b7f8c3829adb1ce2f4f8f6198a95, +0x9e651e10ec1fe98ba2bd23aa05696c4bc5acd233717b7069069a206301f7e16, +0x2f995fb2fe9a457e970030416b7811a93b31b3f2ed7c7300034cf958575b3ef, +0x98eccc1107806d905139f5aad87c4dfe9ff0d1eecc1de30e8c6a4cea8c51dcf, +0x1720f40d61fac0f66408099bb1e34e3a48b29ad05b8910a7bc257e01de20dbe5, +0x18fce50e6f51644e0968c44adeda32e68bc24c25e81ec37ce5e8771383cb76e6 +], +[ +0x46191ab41e93929ea51f190fd4e773ac8d5083328d4b2f04828dca3e69098c3, +0x662f21223a41d37668404a75b278b868ab602e313e8c423798b47c47f1f56ab, +0xebaf002ad31782757a58dca1b295b2e0ec0ff3115a8c931ebf74fddcfb734cd, +0x1e1567bb8636626357515a40b0d5ebeb351422e19acc9bb5b7edfda91649841c, +0xfdceb3ae2d8a55f07822d7b92026ef83ee8bc326e3a8b35225d587bdde25205, +0x130e0c983de0ad6d15d8770698e39fa4569f38848ee05757951cfefa1f338fd, +0x2f7be21619fd5f7c05e31d90607acc55e36fcb5b6c55f970170e660f2d818fed, +0x5338e9847d4e29692f22f938875dcc5610464d7393c6d87dd799bb3bbf810da, +0xdc0a5c9bf0d5b38785df58fb22ede06709eac85f230639056bbf1333b9a2d21, +0x10ce79d030bc12a43f0b6fff0d884c15c263113b3a6ce3b24318f0a60164f6a7, +0x232926077aaf9a6e42e885290c6ad736f29cedc9b0ed5c5a0530e405d57756b3 +], +[ +0x14ba1b5383e3733c63d00c32c2bbffd8e54507ed33bf7544c86388191eca3e40, +0xdeb781e30eced913c20323aa3f86be585d4cce7f556abd2c2a0815bde87b775, +0xa877d868ac293ccec0f559d48e3dced60c81fef80ddffc8f70905664b3bc0f, +0x1d635d1267a513c78be7288e584254f53012b3f7955147ec7153532760c6c9d5, +0x120a95649ccf899fc3a8048ec4adb59a84d3ff5c292328f6cf32ee0c14d8227a, +0xbcf6e6daea072a539fa1030a61bd0c6f425e9982286ee468ae2ab7bf1b8d114, +0x1c4a6464c867d43eb5fdce8a731867e1b9730ab208fbe77bc9ca7ca010a74192, +0x562e63099a7630323f701d2fa312c654a891e682a7e0925429c0321f6155621, +0x1bb2aca445944760eb02e57360e6d3fae93056dc357ff0dd8882d08983be3325, +0x210f17a9d928eb4f42cc8dbf8d6a7865ab53bd038180c9a1c9a506a2dbb0602a, +0x277425a5970de392ade13f6ee3752600050830d3bbea3566438924ad5159df4a +] +], + [ + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x239bbee0bd0536587314f5429186856d92bf093cb902a7513b11373dbcbf7134, + 0xac0bca8c1a15d53ce77475eaa398fc316f791caa305403407056f9b14f47f64, + 0x11ad8281442fceb40a4c536b728ee79730be6407d603333ba18ef5b7492cdd13, + 0x2927ae7db23955f84264264e7dc4f4015b070620841d9035f54c501d0d4975b1, + 0xd9455f3c59c9ea9302e721c00003feb40ec8231463b84c2d66c403cb9110dd2, + 0x14d50f175c19900cae3eac1f457e2e02218929f5c6548a6e601f3038240df458, + 0x237b9200970d84323901b9d7a12626a3d828affd132d9ac43ae01d5ac3cf618c, + 0x19d66d04ca7851e0cbaccbe73156524606cba6bd174d94bb79d3fd99da05a2e, + 0x2ca5d1e4cd8007c2a6e745ce9d3581c2661d28ebcf7b723bfafdea4a97004061, + 0xd54ce53ed8160546c3555b48c6dc1a95bfc11a529d863ef3d6d63f3799fd407, + 0x2c21c6df9e87d0942740cfed6b692c5e4868b781085a292f505a9f53e2969b94, + 0x6351ae4eccfe35f6fa2f0e50faf512ebf3bdc02a9b61fc2baad2e18c4c7e128, + 0x1c86e871f69f568ec2e47ce015f7b324c6833ab9fbfa2013173857efc040f95b, + 0x2175813936c314627ae23d64f217d0725097891f1b1cefeae407bbcddeee09b8, + 0x2ec44113a689ea96c746225258ebf92460b065c25e979e5bffbf0f8590315eaa, + 0x2facae956086465c460b678df8d1a10bc8256e85fe5a3dba26ba637f3d4eeb94, + 0x1865d5f9b9b920317a5751591a3275d233aff5b7f6e6ca7c0f6b2e3f1ea0184a, + 0x412169c5bd61a200567219a93b8df6b4391fe1da096b22755680536a2173411, + 0xbef9d4f49681702d6176c94ef8563f7d1cd1556ef5adf986cd9dd6402456513, + 0x10c7e674a66fb25905751a9f355309c0a6b4a622b7c3b29e93c61f64d95d881b, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x1934288830ec4d6ef05046f36c7e664fc0790fe76e390dae265502624f3e6764, + 0x21fe8f4f8f4fa08615bad7638ab88a92cf8f0a6f9e3e695f3458a459fabf9a8d, + 0x4e0a4f483d51dd00d1062226b3266d95da5866968c6abdb721d96f8f7e2bb1a, + 0x2d3806f1ea209c26c7b3fa95f40e8d213829e28811223aeffe523cddb5246ea1, + 0x5f7a9f8fbc8104008bcca318850c76b19c624671782c0104a04b1b03c16d792, + 0x1c429b4f17c25e0c73fca45ee8f69e5afff9bbc21b4648ec497276a7366568c0, + 0x2a5f492892b38ae10a0615eec76d2f514c9f3251000383d1d1e13a90a9dfe059, + 0x1eb8bd92044de59e84b8ff7e28347243a0cf0a665dc38be0a809245cf2632846, + 0x65ee5b5e74d35c9e411443393e2462959a11fb9fc95bc1b627cd0f48429837c, + 0x10829a880633680e7078e1fe50cbbb362a20d7a313647297a99dbdf6578bbe84, + 0xa83ccb34dc841eb9cc8d2974f083c61a9d9f162d6169db459e0544be9935d3f, + 0xf8f126cb3833ae566d7020e8bba5f7ee02525d4378d81d36730f97ddd2c358f, + 0x2783557cf3c6a0b59926f5804752bfd7de101c1e831a4ad421b12d2ec9f7bf24, + 0x91f200acb6c0436b64c4425917f2fa4c6373133a25ca40a19a28cfda9b219fc, + 0x1e4a28170c7a5034f70a700fad1088648e97a11fb4856e22a5239385099caaf2, + 0x29d63ae313de07d1dc59205c4b29f8b95baaf7efeface383982252f1173dfd2, + 0x188a2d62c5e3519664418fefd0fd0f214b101577643ef5674cb5e5e4d69bb7ff, + 0x230324a35fb7ded74a04c7fd4cf7ee0f68cd8851e1e86b5e4c2d9c1857d2dbce, + 0x27e120b07d441aa2864beace6201c4aee9a06aa4357fd66ef765c6f10b3d3c88, + 0x2d6a0fac700c78ef54b97bd61d43e88b5215f352dc6806201f3e32ef06a1dfea, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x19214ffdc30bd79894098fd3804b092c50b04ed072d36155e2003204e1628efd, + 0x2f15bce2fbc19f00682f8ef66ebefd1fc0a67d43e4255f72ff9ceda492c98752, + 0x215fec7c7c775fbdd3bd2317d73399873ec497b6dfcf434c606dc22603b41b05, + 0x28965510c52457b2b0d9e49812da55f08028f23ff9764622f2af19ced2eb250, + 0x2798d59530d1d41a6a311e90c9c37f0bd389a39737394a11829181d1f26c4988, + 0x11542d205011b400201141b40f0e818051b0a983ae9387786906bfa71cdc1f5, + 0xbaabe59e61426a7f5ebc2174ac06d27ca7854ddc67e51b8bb9573911387eb31, + 0x268937a0fa2e75f79c04d9f2aa6cc56ca52f3c34352cee551aff2b99eb953a79, + 0x1bc3e33a03e620069e915e78112c4b39bb36f9f3ce5d75e9d51624f0beb1528a, + 0x1bc41b054898379199236443a43315088018c303cfa8760d7f679149ed53d3bf, + 0x2ee37960ab5cd93080139be75dbf02d205adbc6887e96d278ad3e430a43c59dc, + 0x1cdde27557fa9f3e2540dfe7deec2ea92d7862361a4a7ada6e4b68f2f3b4e867, + 0x2215b23457c72fb4df6cb05ebb6e695a02c0c7fee8c1ea4553d130e9ab7c3a25, + 0x2c0a94bae0c8d81169dc3c1b3efbb544d16fcb0a11b18bcdc68c4b6756c1816, + 0x9c4335fe7a502889970a7670ee8537837526594d94bee1008d51506b0baab6a, + 0x1d54c7fab67c393a91a61e0e2e38d5b7ad4e43f646286e64e31704c748ba9db1, + 0x300b58fb17814ea816d0f7bcd9c3aee0c411ef4281917824180a3547f8f41b73, + 0x27855ac29fa4b1abf74da38a4ce42de382834c90dceb506eb1f1259823889f0f, + 0x2259c5da3d87b0a065ffb5a9fd340f8bc3ffc41113b77bbf66a2613a03b04874, + 0xfe5e47f909ecf12bcfb1e96d2f6a5f96e8e95f7091a921d225fb33bace62388, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x2cf624bcc1b57941669693a6ee517fe56dcf7ae5f8dc152456d68cd4c839643f, + 0x284fc4f8f116661b9dd2690be9979691b33a6af7b521472a36c154c5ecf94b54, + 0x15f336d2348dd647d17cffa8507990c62d9355d63fb15fb7b7181c0aac883733, + 0x2b097ff93c8883e63327f4009f9d0ad5518484aecc9ebbe42ab9ff386beb2d09, + 0x2b0e0d9bb68edcc80f960a98b948c1a172236a4461c5f13d2b7d1fb648d1cbf, + 0x21fb862d3aa99493e303f1fbecb67e2ff829a890338ebf642b1bcebcdd3eeba6, + 0x1d742e5595d6548a4e5cde3fa1a024fc04ba950de76aeef9d094ef3a6aa80e01, + 0x2f00e60ddbc4d8cbf208aace4afbe88c9025e161a5b3dbf495f11520fb314713, + 0x937367d77f41edb078d7efd73191a38ec61b2f7ea633aacc172fc808e6e20b9, + 0x20cc21ebecbeb50a3e7b6f0ffc58f95d9bd9990c8e0cb2b51bea7cf817e0501c, + 0x2153722c6eeac70d60abd76aa40279e600a739a3c24b2d9950e7e0d08468ae60, + 0x170429ceffee65277a55842cc1c6089270d658bc86565a5618a4e1156546957e, + 0x2881b86019bc624704431bc3ed315ae4dd4c6589118f6a60d920f1c4937696a4, + 0xf75ac5249bce09549072133d80f299f5e194bd34f820433eebeb5e020817091, + 0x9a487d60d8c77e941b03d1a4cf0e9a92b8328bc432b437318c0bf096b8c95e8, + 0xc4c7b8be9ade992204bed2fba9ab541af980a47b389cccf61abf5353640bcf0, + 0x13c6f29a13b808abc57cdc98bd5b32326c0d37640b2b1c58a988c50dd0a66e90, + 0xdcf77d7d72c03c43842c43d906862cbfa78b60f89780b9385a2d81e316d96a2, + 0x1af4ecef93add6d17e589cb3e93a7240f2285e18c1882da49b0996fa64a5f7d2, + 0x16500f1e2eb13aef4078724a58c869cf7af3bb0a8eb50236c3e2463ce54554ec, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x2fb22f7c0dcc8f0710df44a538564fa4835d8297a65bd032793c44d1ecbc66e, + 0x186c3597d2e95409839a6577665c9247c61d1d4e39ed975d7eab0407571a3cfd, + 0x268a806ff91bdb7848e65fcffcae8ab72e771dcd9e44918bbbf961d024c4e780, + 0x22a72134e6b344238cfde291a9c27c8d91a7ce8ca75efc932a3ac0fce7229618, + 0x2f3d93275b7e8f80483d94dcb59ecbb02d578565b6f3510a3b362db38b806990, + 0x2188074227737f56f2ed000fb0557da0fce247b29e3fc1e94c782497dfedca5, + 0x2795cb6a4c716bfb133f5aa5e413d7ec0643932100bee8003e35125e908e92e6, + 0x168669f585369a0e9e1e1800a4a64e59198f67da9022257ae38ed2dae2f3e890, + 0x1ffa32112a81bc68e5ce9b45a08becec9463ced766f99e3f70c5295bb287cf05, + 0x24305de92f0bb0f4bf743d990721957c6147f9712ad12bd0970d35471343f1f2, + 0x2553d6aca650db381e5a5cff064f3ae81d10dcf60fdc1b88d0b4a182cc3b86a5, + 0x2f3c1b421f6d478376b135c9d120317b4290120dc11218033e249e6f660738a0, + 0x245b4bed81074004368bbf0206d685ea4aad9ec2c5c27404550b134d60301858, + 0x5d189b960a83b4cd0a7038f8a5bb9fc4f86a1195041c3d5aca8020cbf92a015, + 0x2842fd81790b045c74803f7569b25eff6c992c2e571bbaf1cf9917f9dd45eeab, + 0xbb806b253f4b014dac7ec4b9150635e5dab4505e9194ce2046af74db06e6fb4, + 0x1130802bdbf1ce4ad31b52a3b3380ad274eaec3ad8217a45429e7b8bf9f57291, + 0x236b083a817afa7114155de365d7157d5c45d3ff29a665828689c98c118887c1, + 0x2b1118c83315eed11ca8a5128ddb9fbdfcb0944e37f30f57ae91e81344f76eb3, + 0x26c7bf0a07d43c11dd2460b3d339014666f2ccc0d6f926dc5320693ce6530213, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x62d864c511b8873334e836d12eb72f7552810f28b4b9270ea837e9118dd92fb, + 0x25587eb09d2cdb6628c520a7111ed2287f8ef7d5bf15e7ff0d9415616c14beb9, + 0x20344cc75c81860502190a88a9753741eb82f1355eff6272a687af15b3370983, + 0xcee668ab7cafe0c92f12586b73566a59fa7d9e14624394bca99d6fe9e082c57, + 0x41098b20212f04cc7fed3b8aa272d37dd719e4304f79301d4b7ae6efefeaa72, + 0x193870bbe39e62100358a649faa3ff6f81d1915da932545ad5ae3dd951529dd2, + 0x1d86daa8ff221daf2c5910e1b9adc7d1a320575c43ec64b6f8aca53cab46f16c, + 0x25923c7c452a59c736795ec2d6993a2d27a18b01107b018164dc30ffc6c7e36d, + 0x166f933a262efecbfefd5d1218289e8306130b9b3ae903564812aae0c357b73e, + 0xe710428c953a764b43ffbdd166707d10a6a08ed48aaeb562ca63a19b70c1c50, + 0x14212cc175586510bb7e0107b7e99a1add7be5eca7445e35b23a9bf5e9bc26b7, + 0x7922b817e326535d89ad077f917aa3f5ca180e982a89628502299515bd1db4b, + 0x17b1b0209846528ed24450b5b6910c3dac0d79a35c1297c2e0ad518bef18ec2b, + 0x1fcf8f4d3ba39e14ce346b78e781ccb86fa80a2c9b91b53b2b917d32201bb0e8, + 0x1328e374326bd95e9a909683113443b309c75dd559c78e48589f91d3d667fd7b, + 0x186b0b6795393cfd4a4961f0d34cd0f86d491ec8859ed1f39649f4a77d23d0be, + 0x22866b41e186a1a499d3862f90ed2138b052753dc15fb43f71d071fa54e8ca21, + 0x1a21712b5674e92a8fcdba2df567658a78f1c6409972912f59a3fca3fe10010a, + 0x169c1593ef30d80f8f26d4c287a790cec8e41ae53c718b5aca62baea5e7a7f63, + 0x10cfc561fd16648777627b6f289f95a96fbb95ecd84ee59ed541e7b81edb4d69, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x2f44dd9b3903bbe40ed4f0a14f06a691510f25d683942e3fede322c7f27db564, + 0x1be695baecbf688d6618060b85965e37e50ae175e45f09704d33f2605ae3ed6, + 0x163a43dabce2f70ea0d35c105ad54d85eea9b0953d028fe4e11c604e8b5e69a6, + 0x2956dda14554b0ab7db32968d172b733bf92a1efdec6320b0c3c9114da88bb7f, + 0x10f41dd81a27925bd837952dae5a9c494dd285ffa9a40d9ccb17d71b9098dbad, + 0x280ad3fca7cff3b3cbdf6781f295bc0ee70275c10a6409b7b8c99157753013cd, + 0xf12826ee6e2f4690c360410aceaf27726e64d0c6d39bb5eb8bcaafdb4266aea, + 0xe9f48dc6fbc4706c6375c87d3fbbce3fe78427250b0fcae92e07890d3fd942e, + 0x1c7a967977120a43bfbfc9351f2ccc84a2e1a2b9f440867e9d9257a1573c1f3f, + 0x19d6f7ac7339519c004c1893c15b90c6b50fb09410e9ce523bddd88aa3dd3d75, + 0x1b92f3e79d7fe18dd5a8a7c74fe697b800921cb181be388e65b39cc8114b32aa, + 0x22998601081051242be4d99570e60ca7ff816acddfc3605f463a1221b11e097, + 0x17f81154836c1b89e026090ab505be76f2da2674a77bb65196f29123106f15e4, + 0x27b439487ca8865a03fc7699acf9c74e7589ec1282fbb0eea9f6fc4215fb8d5f, + 0x2ebf049a07d92affe4877c3e4faa5bb176d58c7b514ce03b85ff8eea6b17011c, + 0x14b55de484bf2eda58a874c907aed547c35e892592a8704e330457a6927eb9c6, + 0x2cf300af23253ae125944cac6565ad837e1b4857ac3b9003951c414d167e4622, + 0x11a0cdf58417864a0399eb08e3af0cfca6afe79e831eb14c2c7e6ae904ac14f1, + 0x13f038e1602814d23b07765cbcb44033562f7c8192fd2e45ae1372cd3f9100ab, + 0xa324aa4a2273af5015991b7e47dc180ec2c6cdd3afaa7ca1ffba46e4cb5a78e, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x2335a58b2a4893de3bb776a21abcc6bd01746d21d60dc99407a58ec99ca5394d, + 0x3792e932762b5353053cd478898e7067fa59e0aa0f97bb5d075b83e7f1068b1, + 0x171f0973baffed9d21be47d121de7717d9200520579e674c345741ee2c0c9af0, + 0x1ff55845a587dee8b90bb11b2490e5abb7bacf3963f7739421b471e1f3cb589d, + 0x6db58db2db6fe63f54d05adb8aeaa9cb89f48d8248e45d647b9148d1fd202bf, + 0x207a78198a8af61712585f9e3aa8fb315320232612f83529fb1b5892c30527ab, + 0xda95af66e6e0aa2f1a0ac71fa29c74d75bb9f99e9458079fbc43fcdddfc1be3, + 0x244dff1663f2935bea98c07d041221ff4b866285a999a04e7badb7932a91e7ee, + 0xf1666c15799e77aab89a2b35be57b29222ba0bcb4c690b05f144b61c61099f9, + 0x2e9b5aed7ff481e79e49c949604b1d7dc241700cbf5d6e7748e13f74f30e5ac1, + 0x16834fb2ba464871b1815f1495a872d63e79504d5324e80b34adf43ca7a68908, + 0x143a59fd2f1e040c91f7230be230101ce4e6323eec738f2906357464515206a1, + 0x43dbd8535bb232d99c3535dc3d655a963324bf70d1a3274e40e64393030471c, + 0x7b166c254454f4b8d6fb5aa80087856a5f3affc248c814703364663f08fb766, + 0x2047d44ad52bb40ba8e9f31f521339de3e41cbc7ef94245e7b9c82e3d5239f2a, + 0x1e23eadfe8cd5443f15abfde942370f48254cf355214fead4e4d85a0722e3452, + 0x1371b1a0c0ef71a90bf7c32118ae414f81d593f95f864cea9a1b60607b1ecba4, + 0x29c9b03f3f02faa3d633b65dbf083f24565eb29e36ed1eee4bc5376889b5a0f5, + 0x11c0d488111b7ed7b91e9be524819faeb74d64619847d9e96cd916a50d17311, + 0x2d389c9b04a7aaa0eba8940233e3630c8b98f061a7565a7d5caaf28a3fb77307, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x12e351fea34839d65253cbc1cf32d39e34b1037767f5c2b90627d90d73d3bb0a, + 0x2e27a42188a58299c9d8044c410844229d17a11812405d3d35537974652ead64, + 0x14bdf13946d48ef5a08883efab512ddf10596421d031823284426fe729475367, + 0x9a068a755057ee06efb7fd6667bb62353ec9cd08fbc887cf5f4fcb2ccba098f, + 0x519b4409ec8e3a7860ee5c90956903fd27fadae89854357f81cf33fee0e8cfc, + 0x2e810ccf1dd607ec36f7ab647ca38d42710eab334142a8398b5da402a5840054, + 0x233108c004672dd480bed52d6f25174cd89d1a025a60ff6888a978503ddfd96b, + 0x5be8a2527d11c6c19b0e5c5a0e75a0b54c5e21e68c1850494e4fe7784cfcdc8, + 0x1c4d74ec5ad43fa3f3f50702399181ac51aa69d9260f1b32fe7c1ccbc232a0ec, + 0x2c98c881a993b1aca5ee9e7f559ccdf305e696156bd0ad4515afcf5bd168de28, + 0xac8b8f35d94988510c83febbd4925feedb7115380f6c4e167aaa9ba11ae739, + 0x28b2d2b745647c152ad021d9e1e7e87aa179c49626348fcd0c29444aee62d71d, + 0x232dd2860f628248f1b55a1f1b7f4205d5d8c86139e182b31518eb4fa1eba077, + 0x2d45676dafb1b4e4f2e5326ad8f2d6a382ccce3969091d48ce0635bccd9f1f84, + 0x23c9bab33c8ca65ba9579f56ddbd8967db1e9e3530889762e743a32277f4a56e, + 0x2e3f511a8650b0493951efe1029eac8006bb5d44f214508ae0870daf794eee04, + 0x1fadef99b87a98d042116dc8d68a6eba75609dcbba24feceedc576a5f8c56ec0, + 0x13b1c1adee57755d2c3da15fe50fe6332e5d5c5b5929c5ef8ea0387043fc156c, + 0x22a338fe1a442d6afe886f9cbcac11a4f7f9bdd77fb3a8b78dc8368a5613da63, + 0x1c069ae1b1241b93546ccf9d02a0279737dd1065e075da8cb88190a71fd2e887, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0xcd4ceac7e7f2cd68f2aadd77f8a89a35b39e6fe20795800da208139d3a12390, + 0x1c2ee3595af8de51bbd5eb8567f18d3e1db383bfa37973f87cb36e72a88c81c0, + 0xa7c2fc763da1bf375377589baab4d68685a7d3d23f08d106e5326eea97b0333, + 0x1b50d5a9d6db07dd3f14eb594c51c1cd119a0e734a1f2459cf989a47e557359a, + 0x30161bd3b8b78d824bd26c4ac8eaebf0c3bf2ac2a428c274b458406cba4799e4, + 0x7274702734590bfd2fa48046b2b21cd261a226526c126dc9841a00c5b74747d, + 0x23064c35e504e677bf3c438b120a1c02bd6e8edbc70778e46b7e5f00d1633597, + 0x7b4b8fcf8c2cabf527256c84aaccb348d19a3d8e41caecab110f3dcd563d0bd, + 0xa95e011e6866c8550e42efbedd76eddbae2a133a82edd6308f4c8d629d42964, + 0x180517d31f2656d1cf425f6aaae0751054c71dd9df0a236c6c049a3b33cb4da0, + 0xaa7c1d96d99bf95d733baeb6e88f4a8536c1f846730f460731b2074f534ff99, + 0xdd0dfedf6a1d0e3368d8f79d159d585f181aadb93429e0287324179d1e37e4b, + 0x572df3598f8791d83d3401b87b3d6e6b3a778a9a4a33e1b6c24746070a3bf18, + 0xf9cb4e73d3b6c128f629e12d409ecd7048781ea825ac98c564f11fabdff8d14, + 0x1db3c7279ff54baa1b579a2d00acce27d1f80dac5da005ac5a50052cf4ea6143, + 0x2942a1875714a0c00d3b2d20dc216f466bbc448af3a63e05aef6353073503b0c, + 0x2522caff7f2a2bf9cdf836ec99ab832e3f792614b5cef40cd3e9f00c9b2df92e, + 0x1cc0d08465538de8bc30077a0fca970b6bc309fedf4f48c79ac7ec6ba1f4a6a7, + 0x1be86dc6dca9d90b15bed5bf60edea532e1510007055893ccd65741037c814b9, + 0x2ecc73f82062b8a6d91bed0d221022331d55436042ce722797c1ab25f77a9f2b, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x1e954a04dbc733e4ad843f23a7f402bba126324674450eed047e158c4342f75a, + 0x1bf6934a5502144b995fd7a26c8be4f9507169f7d29691e460277ce8a06886b, + 0x10a770647e157ab71fc08d6e560bfc21954d55647c32096c258e244fec48629d, + 0x2379fd0b045b1b43d59bd7cc2760c8bc5055f3a441fa6288c84a3c7c7488a566, + 0x242557dd84169e034b9c9ece2f2dc4bf4f4b3520b2ec0c62754cdda61aa13759, + 0x24d0e65867e83cf7f865e89a44c0fa4f31df8eaf20194cc9e773188322020fbe, + 0xf08e39c0aca58fd66c96bb21691c0b06fc564cc300040ffd985b0ffdab6ba89, + 0x1c3119af9b3e6b5bff8c6915f68472b22cf3f9e187ab26981b86c3e90dc767e5, + 0x18836e6cd384b031b1a462ad8d0a11c34910f35baa8a92fb3e56f9615cd702c0, + 0x10b2bcb24625ababda8c1c7186890382b9ce83854d7bc4f2460f30d706a4cb48, + 0x237fdf2809ea511ef064a7c036f29c1d555c0b32dfd257334ff535fe42cd81f8, + 0x21b9cc4ec4c0832479f7cc5e15b4ad4722477a5ba013d9d359d540afc5737f67, + 0x258e26b354d7ebe2793cd3fb7c3bf6d170cf9db55cda38f57158d9b865298d8e, + 0x1d48d2d440fb27a8ed1fdf8212e7b34cc231bd2d893402412f96f938165bf3ad, + 0x138fe1103d55fc0267df8380c50775947493bf88f75a73d783b21caa92197f3c, + 0x1edf94fb5b430b784be783f8980634ad92449f73e33c25e9f7d63f3a62f30fff, + 0x8eae1383cf79a2ea6482185fb4b72345ca8689c16e67bd0a253eff22c5cffde, + 0x761d160fec46a8c06e3e055d34791703f805a77bf30042a43b6f04e35dde41d, + 0x2e23c612794a7f8cbce764b156e02bc21f2289396e30ab846536239dc8938efb, + 0x1539abe4d27172e4ab5380afc595d723f9ef3fb7e8063705f9a07c40a67e372e, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x4d800ab616d72aee2f1cfb8eaa194dbb2bd95d9bc9d8327943da4f45befc2b5, + 0x2207ae07dccbc047ccce5415be0c4941ccd2aa15ffe4f4a8e07a60c0a7fad9bd, + 0x64d711ce20b70d512f1ca107456bd158586fc1e3219d09f3de8fdece43088a5, + 0x56adb05c833c5d1984c7f6bd75b02cfc1c7b21dd7bf6daf1b52522c96978158, + 0x2efc241aa72e16ff31abc7977dacf9a6df53b26217544c53bb87807d5d61506e, + 0xf41fed22cb32a447dcf33e989193fff2157f3075848ed1e46a181128ebb7e5, + 0x169291f2bb1381ce3b16e812c546890ef5ce32c1d768d81264cd719e4e1502d5, + 0x2f9fc1e4f2924d82d17c7ea7d3b09f67be93560ba39f29537ec0c1f2befd4729, + 0x13ac8de14556e9b886de3944edae4c601a01f78fb263730f44f7d9991b8c7e2d, + 0x29a69af8e28052f2c56dc24bda3a5e61cfb3e9c6ede0fdb857a1971fa932aedb, + 0x180e9a2e161d21013486fb8598113f7a280697e89643400cbefd587893787172, + 0x29fec555b91dfa57a42cb368560d4bc471c77a2e236a9d7c9c6aab1b6d1117f2, + 0x231ef485473f733d46f0e2acbfe7e3961d045f30244244ab3bb7165863c1a46, + 0xe6c1b39867e21ef0c630a99754d1a66a6688192254d40492ce88d47e5fa15c3, + 0x2e0a260d61bad61b7891e6306df8b2310d8b8db9232fd1f7219e7fba86597031, + 0x176aa7da52727a85134b313308a4c62994d4149bd6c6fc59d6e6c0f09eac859f, + 0x12922be1b7fdc58e582eb1adc46890c48e10c8550eb8b9b11d8541694ef3a9f1, + 0x32268b4c29827a65066e67d71e10cc978a73e0442bb1c9f67bacc883a3f4fdf, + 0x10beab6538e0141fcfbfa8da4cf3070e69b2b49da1818ec8a9e54757a51b3c19, + 0x36192a82ba9eea93a2f4b1994440a11a556d0d157ae5da57192e56c21c28256, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x34207380baf33709aed4bf2cf5d387a15f30dd072028305cdce60c1737ac627, + 0x1eb09b8ad28ff81a7b21236652960fe9bcdc84caa6b21549da93a72d92ccbc8, + 0x2545313ea42693cc8c0d6315d8bf240ae624d66f60f6f0a356a105ca6a7220bf, + 0x1269b1b6e6ffd9938f8b4d7c4ae3c7feb7686b9de06a6831fd957cfc3c3bf7b7, + 0x281e84c6cc599d853fcf8ca0a606f70aadc893adf4a4a099364b8c052f169ab8, + 0xaeee3f27983d8e9eec8d6873cb1cbeb38c3d5912c74066bd0dbc559edb12c69, + 0xfdc47ab86a0a3d8e9217faaee18d9b5b86e9d64deba55018f355d3b9a36b6a8, + 0x2c35a627b5540525beacc313eb5733cf97e1ff3ddb3f9b4e8b4f063b686d2e12, + 0x332c87526e40afec8b93f9735204bcacd4c6431c60b0b3daab4fb7f120bb301, + 0xd5d00fda5d7c9aca26fec63f2565a7b64fcb58a67e7c29a64d0e450fb2b956e, + 0x1b9cb4b5f32f1ba38a685870d7a5f7f44370b9b0e4c12ed349fdf28de5f49865, + 0x1c63e1e8141a5a498ea10713d8bd8ebc5d61aad6e0ab492baff25befbbb26a26, + 0x26ab3869c42b4e0139459f133c996241607f280672e2db244466d3e425c50fc5, + 0xe8a1f3050352b43a39fde443e466884d09945cca09f31f043ef872a85511bc8, + 0x51d4fe0ed70b240156e4fdd7fb3351d55841c4fd97d1a4fdfe0910932052536, + 0xb0a1015d5b0b6a572187b97a4427f7e938485515cbe32e0016d11de7d6bc760, + 0xfbfa326f445e39a06bdb999832f75f80114c3ead6206339d7a5edf276ee54b4, + 0x9ca06de513672e4bf3625d0cebfa2286a44737b84647df4154d524528e82750, + 0x281dba97e7243b1d3437c626fda37e43c95cbe3987bea3be9d19860672ed4719, + 0x26de57caaf86357521f470a899d072f52a41043ff0bf242a845b71b8ba0dc6ae, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x2fdb2e183ab509617feaa6e075cb9de40e5165621c2a4266fb894471e9c1946d, + 0x6188498691a27faf8c8f4a2b3425dada1a87d06c53861823232acedb25d6def, + 0xbfedca0dd5e506b091baae85be99b391358740f9a7c6578c58349f522323a18, + 0x78b237302bdc513c9965872103d4588c8b19a002b784ea4217fb04455d3133e, + 0x25f15182a955582df5a3f58d36648b5cdef4bbbdddeca93eae6c94fafb198305, + 0xa07fd1f3e8a7d1f026578e5999ed3c7d63d5bffe07ff0c96cf8b23e2e0f7820, + 0xbd64bd942a57b8c209d7602bf222a0ba5c84251dde43bc098e938f75a0b678b, + 0x2cbe62c979e608377112ff7050870162a94dc68556270ee7a66e65305d1b16dd, + 0x9da1c5dbe788effd900ea877c8f099af1c03e112300d9e070e6c6f8c07b6a36, + 0x7981ab3c73beaa4e1e775d4e4abce3bc86eb79168d6f157f9cadbbc30ca97e5, + 0x3dced6534fd07a1107d6c54510a07f25c0a10b260c7376bdeb10c4e768d91a3, + 0x988db118a1974fdd8b434549e13ec8654644298f3388bac401b75b4d550ed76, + 0x1deff1662df511afe108d5322ab104e70703d65b729c1dfdc2bc74345d4170b3, + 0x3a1bb1a92965c2cfce4124a8abf82b54e3ca37474728dfbe965f7e04fae0f1d, + 0x281f0cbf3e036b4ae183795116b65070d16e37621d83b3d88ae69e98d8c44d83, + 0x15c4576d8475a4291a8db61a22db870c56b013d0849b1066386e859b996d9035, + 0x675b067ff63a96141eada800b0ad12de8eacad15c7f53e6241feb94cbe87f3b, + 0x201aa00289c06147c4b86a521818881469fd0e4f91be7bb271afcaeb1037fd56, + 0x1d590ada5a94b49917ebf20bdc55e03d0362b3f719aab865957c76b84a4413a, + 0x6011f23c13d5ec3df59516c72371f2ea28e930f73189337762e3d4df3f7193, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x289927a769b163dd67f7165490a1a4d9fc3b8ec189ad4fcee07368a3e75a7573, + 0x5a0ca87482e1f242157b180cd02fa975c72bec4c25d87f82b7c53e3a6830947, + 0x2b328309cfe721d78f7a6e8634f54524c4eacc42ef998093e0b77c24d5ff9e80, + 0x1ddfe1d1e5e9458ffb1d342e1b99a73b0083613406f932d7abadc8442204c061, + 0x2da94a9b44a2e2681f75ee004c7d9cab662ca66c1ce78fb2ebd617ce449ee43f, + 0x1efb5c3e6f22f498ced2f4e63c366b9dab0cb06adc4e92fc3f868709cdac330e, + 0x464f0cbf6ac670c19420e79606bc447e259f8b203a4ba15f72ac220e853c884, + 0x67e3c61a95e28c26b5628f679c7843e1e042d7841a670219194e99dcc618f82, + 0x2d1ec49939d788c853f85da08552dd458a48a197cf0b023157ad04a49a72a28d, + 0x25c69cc3ab094c56e86147024ede9ddabf71ddb294ab37659e9b2be22dd9e289, + 0xbec17f5afb43e6faff2a6b09a02eed8455bdacf16ca542ccfcaffb119ea2c0a, + 0x543caae6f7afe71cde9b817c9a746870d2cc62d2e7e1c6fe7fecfed5a98978d, + 0x142025c358454da1e1cb0de99504766fa297d1f6fc62deb14ae0bec430d58087, + 0x12b565ffd06708fd98bf8353991bd236bdc518c7fbb243fb05497ec7ae08939a, + 0x12f287f0f3686375ba8431deb018fe9c28382d0b3f6d42c0c8bfef68b99b0639, + 0x1b97a4c6e3b1340d563513c29d704429098877af661ac3d14a8e5caf2ec67622, + 0x1160e192c3592d85262513d57850fa5f8ab05a95877afcacdf616cf742991fc, + 0xde9cdc2af5b4780acd93ea46be905a8530e8bf89a97d41041cd39fa90975884, + 0x29a2c79a9dc7c39e8ae57cc00010cc2aec866d9106a8f2c0def35fbc29b304c3, + 0x1b39fe57a5648b6b19ed40ddeeda02db1a6a0590bcb4ac75d52c016bb5f004ab, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x2eaafd2a94018113bfeca9f6f909c380ccb8c99788645cd8169586e66968a6e0, + 0x27f7e86e479c9eb87a4c05e80dd23700a81c2e720bf0e889a6a5d5d2f2a385c4, + 0x15fd4d2d4de641f8d803e4942f19aad8bf6b01a1b703dfd0f0b51acc263aed92, + 0x172a8e725dd29bc4e28ac7a67a7f86bde15c58b1fe2f87bb21d06349bbf6a858, + 0x11820ecad02878ccdd901bf88011203539ed7f14c17edf151f237b8f3f357bf3, + 0x157bb0ec622781bd0485ed79ceb944a23eceb119dac4f88f3aa4878f082f60a, + 0x1a0c8beae4e98f3c36307ba5a8ecb345cc5ff4d33963002e42b36242c7ee6f11, + 0x19398691a16329089e7dd608cd6ea18749597908b9885b7a3818feddab8737f9, + 0x2c92297efa4d689e784dd5ca22480de59b1ee91203331f44dc2c33877789a888, + 0x2b05adc1b6cae6f7b6a2382c527c9e486e825d2f6ba1b1f9aa395fdc793e9bbe, + 0xeac0d420eaa22d35e8f1dcf344a5bf8c05559171f5b3d8490e7cc58244b619a, + 0x1f14c4c41d337360748c3f37c2e1c72f831a6f811893d188902688b43ff7ba89, + 0x2dff4909b43986a532997bb6881979cc68bcae8e01bf9caa69389dd064a21288, + 0xc5cb5da369f1f4f874bab1f706b652ef2c50b297b5340f7f6c0fad98f6f41de, + 0x13c2c78c6e2b39691d5e7da33ce14fb2cff83ce3577f1909d2a9b1b73810067d, + 0x8bcbec544fb37718da2d30fbd757ca63187f342440c8052bd9510314f6fa22, + 0x12d845717c2b2c79c55769851913284ad56f2fe4ca359ee39e569cbd52c44b74, + 0x10c0c4538604fe7ad96a08ea533aadf5307c89534a51dc4d958f769a0d225963, + 0xd2a590e3fc8aa2260656e13a383726d6490425ca80eac6481467c17f1050265, + 0x3030d8c3cade8438d664d3ebcb0b0889f57ffeef914c655e50cb68ae14c2f283, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x1ec953704f6bb2e359a38b99d230ca7a4c8eb37e3479238a282da769f0425beb, + 0x1eb6626b17b9fe129966d1ae7f272514826a0bb877d54a3a7d6fea8e46c94914, + 0x2c31aba1b873c7d14d82ed3b033e75b871a7264f4ff1beb961a532d8a3b50698, + 0xdb6e1d43e7479d449ea8e0fa42ef14a41cc880de1c7699cab480edd8a79ac7f, + 0x21d8a97ad31f1192c8d87f08764c4f9a8f6c90940a6d444d922151dc812f4275, + 0x29bd140ba4c910a6d297d316c9bb12f3a67ef0acb14f68af7afe36dcab638ca7, + 0xa61d2fd60c57f574e19261a4a5f15b98af58e10836f3175d48fa7c361e98ec8, + 0x1d593a571d4d07b6b677c7c987263c4f9ecd5d264071a49e6a65a9fbea46da81, + 0xa764ac4206cae37430c7e6554f45e251bf3a4c8348e686d3103d44a3a53b565, + 0xfc4c56a0e57f381acc4c3d8ccc8f9bc02332375f6a47343896e019f2679a7f0, + 0x1c34df18abe2bd65c68b1e40a634311aee1429b49de0ac7a0ad890d434665a9e, + 0xfa890b0f4e407242899e2812dceefc2e8e5daa8d41964612d862b182fb084bb, + 0x1df4265e4bcb86f8df10427976b496708404d3eb8370ffe06d2fb5eb21597ab9, + 0x14b74c5d557ec1780f3a0409c6d53b3b97190734d6f48b60ea42c5d54c194ab0, + 0x112e82b702e99d25a62f79b82d5f0620605381ae21c311eb3b9b6407ef712a27, + 0xb22a611ecdec54a9e15a98fbaef9be8bffe8c6f65b594fd8647ce0d03b1a819, + 0x13552102754e83cff6a90cadf9a9fb9c9c4704c65200cb87144e7bbef93823f5, + 0x90872282ea971f0593587dc8e0f8b7bbdf36a1a762b9d000353407306f7e732, + 0x101e86c640c3bb179c0805a76ae6f326efb5ce0c7b584c0aeec2ddadd727c97f, + 0x17a1236e80618f661c6b0932b1332b40802aacd5fea74c8575ab87a38bb7debb, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x12398407948eaecd57ed99dce52b4051d9a7f862241f682e26f29366b26e8acc, + 0x1846ebf17d453d52ee6bc5f217abe6a0d5aa43084af5ced178a081ae3e204fa, + 0x2054f2993d487237bf6e4a985c3abaf3ea8f0578ad5eb731f94a0dd533e846f, + 0x1911b97db6f1c83692aa3a44172aaf316d863adacf721463e9b34e93c3499d5e, + 0x1e7f11887082042971c2cf546c3fe7031d955ea7e371cff4d270e56aeb0a162, + 0x12170e18a97a2c89b045eec5263655c47fb08fdc4622c5936d0b9d2aaa721cfc, + 0x209b3d0342a6bbbcea6b3ec256daed1605bb9afb9adcb0ac9ff0d409751f136, + 0x6144e781f4197e7402726ed1e01d1a9df01807d8f679e5bff27837902bf4b85, + 0x129444fc0f4808af8a64b51d94d9be48764ade198781acd87360efc9dcc7a8a5, + 0x1f12b62b42b308fa0b8677bd62e9b5fb6644cffd6ae43eacad6d127f8437334b, + 0x2a1e7df0ce57b7a7c3fcbd73c68791c5aaf538727082f773c41e94fa24433fba, + 0x11ac54cbcf0e6175c34eb7e364adc9a26eea739c22aff79208ae371bfc8b1cf6, + 0x263230c117421eed84437ed926810a77a756789fc8b3cace2da917ee6311974a, + 0x10df3a59e7ec06ae62a749bc6791d1b9b2e7cf0bbcf519f3c023e543514e5c5b, + 0x2ee43f7cbc305d64cddff15cd91b7f6dbc0425e706b107e6b146316a8ed4c433, + 0x15e9ba236c3bd1b8efe4391047d6de8b2d8ebd45ca5912a619f7667655a1b750, + 0x1d74abec20aa969ad6f1991585c09cf7b2e4b68998a748fc84fe304511c6b599, + 0x5ae72091e906e7f9d94e8b5e00f4dd0b43039d0ee9ac1598c3616c86d7ab06c, + 0x2b548c790a449adefc53712a777b2b90bea7061df2f57d337b9f512940bff3ec, + 0xc79e3413149346cf672ce76f5181de7604163cd00c9a5263fec43477ba2fadd, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x3017a09725154c2672bc149b4bcd370771a14807833c069d712618e207531b30, + 0xb93ab490450416ec4a761155768efac5d022a8b3712cb410b78e43826dc07fd, + 0xf7ef4a57e815865508ac5e78bd6ff37c11dbc4bf0773864e943b14e0f79c872, + 0x28d3598fc9de7f8e645588886736a239902008f4c0c54525e1927cf66bd0a047, + 0x178d2dfede02ec9735d83ae6ecb07d875b78360c45d9796753b52162050f2473, + 0x2055e88d1c4873c3fc760261b724a8c8c852b05773e03e4781e03dcd410c878a, + 0x201af7d279732ff24a7300d4a63a327a0d152d481e75701bfb1ae60001808de4, + 0x20b9d7719511885b8e03da08d1289fa02923259857fa5c51a4fd3f6bbecbe8e4, + 0xc0c12d9eb25cf37cd472d0ec9f4e283832823607ca823e3ad30de69cb10bd97, + 0xc413585abc142ff58981d211bed7b8d7fbc6c0538dbffe36105ba44e18b38ec, + 0x1ad95bcc4eb2757c070d732f7f27ca45f4685886ec1a21e6222dd7b99487aef8, + 0xe9cd75323a37d831825a99061f0920e6594ae3e3e94d45a3a33aae620d670ab, + 0xfe94376e19c40263ded62340d5042f64e3708e0c556ab677b64a252de7e7201, + 0x236be50f0fe1b1545413d3a6d2c60cd28cb80b5cecaf301fb32d687ab8639656, + 0x28033ec35e8541ea37b843d7cd1613c7c95de6d6a3c1e7688cc26ac5c0433dd, + 0x186eea9c433f8f5ba4318087295fae6003a63a5250cce25ff3127ceb8ea62226, + 0x1997be30d551c31424dd592c2df897dedf13631320bf71075ebd15dd0eb234e1, + 0xc86b6e4ec0b7673c81e2a33cfab7f5ebdcf740fa723952f5553a60d7866c0fd, + 0x2079ea58606d87fa8eb2de37607a65768044990a0329f877b16141d63675cc3, + 0x17d722901c37847aaa1f74a31f9948d916c880d547bec7b0f2b9b1957ad97934, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0xe81a4c71073cfff9bc2053e730c22f6f04712a44b6fdfa3e5d031ae937ba4ec, + 0x1b643ddf9217a65dcf59a7c4a40f0a8ab16d034cc1281c981940d2ac528c11b4, + 0x26cd2f5364c6d09211ed0c9944602e97e582b47e93f8877923f0367c25ecb766, + 0x14e4f38d385b57d8cef67ce66e5199f2fdda3ff261a139a9a421ec1f2bd540b2, + 0x168e02a829c74f8224d6ec0f2a87b93714d60848920306ad51309b5f2736c998, + 0x2fb61a6b4f14e47f6ec64e4acdc941829a48782090c2f399435382ff67b7747c, + 0x2b8353e21e9a695ae8b58e8a11460e8dd7630b073db22e59ef804f570e8a55e1, + 0x29dc5e33af36ae34947c29d674778729ec99b8ab4fffd5c3d957ce532ae7ec10, + 0xf36d6ea37c6705c7ea7bcc34950a883ec6505ac89b6b5d41cc743516e6876, + 0x2799caf6a25f94e81d9f8e362093d9c5440aa9be99dee55c54f7120492a40cfb, + 0x2bcd01c7e5c45ca9764c04385a1636e247e47382b443d73a905ece066790e08c, + 0xf0d76223683dfda5320cdafcc711a2038f7ef465f9847a8c1c4904d6066adf8, + 0x2974f8366a339e664e9b42672012b8ffae9079796783a178ea0009179fd6577b, + 0x156f973d0d9d785674e3b7e05e96c5b11a582c75655082796018e9dc11bc5b64, + 0x19da910e2a4be9d039440b18d700dde2f65455708e7cafabb61809e4103c87d0, + 0x2cfc58b0abe0def0fb166d114edc3d0d3cea117ac3dedde6e6f4fe7ae4768505, + 0x2c0c40c61c6598dd8aba498ad9199f38bee4e39fc06ea761a2de890aabb5d9a4, + 0x1e30543b1ce12e136f719a5920cde3bc35e1b94142a993b522b96ea9703d4cba, + 0x12fc3e01e274c109f341fd2f9869165284c3c7567e2604dd638d0f2267d63db, + 0x2a9680b2eda565239cab76b7b7aa8089f732fe9f0167c9beeac9ca8b146387f7, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x1421e02cf82980b68a9c81a28eeb397e0ccaf80055d5aa562d9b5f68bbebee41, + 0x217804431d1cfbcd6e2ae64af07ef7eb31e21baa352bcee45c73af5f07db8d33, + 0x2d15bdfb3a952df31cade21c99f2933edaf8d7aa3f69fc1a16a3e6bef6c7f5bd, + 0x27f5885f9ddc3ec7e7f2b43d6cb0c0ae1e0e2555ef46cdbb753d13528e239f0e, + 0x3a37a151a0a4214c78b52217dfb4bc323c833a25e0c6fa5b2c9c4e1c3deb674, + 0x11a6fda46b867456af4f194a5f0571a3053adde7288f9fa84793b3516dc1ae4a, + 0x24f22cde459accabe8eba8e9608341086af4cd4c04da2440b067cf6ed63b196, + 0x532b9c8c9c2627b9822eb7cb4e26ba7356c4c867c42889e19d80903be433a1a, + 0x7f309d33a4d334ca3179048797197b7f6729a3518735d608057330342520b0f, + 0x947f36abcd0fad800f8abf23edd43565b6b6c26b7e244af6527036971340f67, + 0xbb49c33a2751cfb8848554d24c216ddb7e6b88234769ba9304ca0bd580c2493, + 0x1f791d5f90371b44b925e5fe04c2e994a584fc427e4219f551c35215e022fa9a, + 0x1618299c6088e1d3a91f6cbc0956c6afbc3c38fd691feadc8d6787ad52d976b2, + 0xcd4c820d82ae74e29d1915d6eed53be77e06c36f27598cf78773b06b362e029, + 0x158545181f2bd7b64bfa41c26e3d4f5917ef52851c0046a7f18c26a0544b2ef5, + 0x1af91ea8fc2319db6925b994492b65f631b416992595c9bfaf93ffe5839d86, + 0x26c03eac9227b0be2a855f95de0c97d337d763af75f1ba327a9e409cd5a718ca, + 0x189b176cd8975d36e0ef78f2f39f8780769d4c7411a5ad2724927981ccb1ab03, + 0x41d9c7ccbf82c77e0580400cf1f9b530aefcdee51dc5a1a4b5a142d4170c6f8, + 0x274278f69995b40626a7796e2f70b1d6b52f9fcff1dc50967080d9f0332ec782, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x1c9a29a3fb7f2b95c153503276233cb8b1e4336434661d97a25389fbabf3037, + 0x2cb5533d1d73b7b385328261659124419a9a7967483f0e3a3e63e3a4172d1712, + 0x2e9bf13980f73bc9d03f4d644e7757f4a254235e659364b078607b15841ff222, + 0x1467a26136dc7c21ae1d2eb531fd9af993c9c0f7923a0f17683babf7847ff5c7, + 0x188210cd164a330cda3a1ec91c7b55c8210ddf706cbb38ede5d8b6ad98122539, + 0x21789113e7aad51c02f8b3831e2133e1997ed31239ca267c6682b003d00f46a2, + 0xd6ae72f4cac38afb4f95f69e9af3571df0ea4d7a726ec3bad4c9c3ce743543e, + 0x29f63bb7c7b8dfc1a470d95f246c1ce2fd3126baa620abe230e181c191cb7cd1, + 0x2f0fe6071d605469e17000e29ca7b618efcb9fa7f5b296f7312515b7080ba1e5, + 0x2c993b62a92c8ceb812cad18de9b0ca96e041be6b12bedb8f64797a6b26fe167, + 0x2fa9ced73852f04ca937475317f1ca35adfc8c2b89bcc4ceae7fe40a28f05896, + 0x130264e8ed86dcaeec0aff16f605f7fd4577783b348758655222d4b6c003855e, + 0x5137ce88eb7162f2c2ee9fa54b56b951a4479f53ffe656fd6a5ff4c9a03853e, + 0x275c55e247d72ce00068db24abb786eed71968b226330472f6c8a609f2dee36c, + 0x1cd13cb77f0c869c445fa8f9d6d49189f7ef7ec00cb4c00dae22db33c763197c, + 0x6d9b6b1fd1e26a4ca07e71e3f9d40647caa0ef100a990ff9cc4b73ecee81bcb, + 0x169dd62b282e78ff51548fc12731cea18b3bb95e8262d139b1974b2933a7b373, + 0xc0653c4aa7fefb13ab5210cc32133a9faa456bbca5f4f0a4f4a1b8d14702afd, + 0x2ddeae46a42784ce32df7b9f7118aef9f13552acac2046005af17748815c23a5, + 0x2263646d28d39b4b0ff6d2243ea0e67239533523f83fa0f4f6d575bebd7bcfa2, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0xf91c7a21016b36d9010165ac8b1b7169da842bc0a274adb5abf99aadb62b936, + 0x1a2e0a81ccc7ca01220f2e7ecf9189a5f2b9b46e53ff92d8cd238b5d195e743e, + 0xbf18f381ca8ee6f9ff4bde5897d635bb27dec564132e744ef8dd436d1cd97b, + 0x13296783d0803516483338c7df1b5fcf81f710522c631a1d6db1a1feb7efe67d, + 0x21c82f469bf6605a5ee156b2511e0f67e9a242e3d1172f826864a0606ef594ad, + 0x28dc10865221c98f25307ed8eb2e235e27d5a5d41ab3fba09baa0909fc939838, + 0x23cdb14dc014cfc69098cffe231e4d43a20c6b3e4db8c6d17fc3463fe94051fc, + 0x21edeea093570815944d629d7ab442d595b6e468ceb883687bf4a1ad49fb2968, + 0xae1075937d8413c6471b481f04b5f6da78c486c9ec3a39f166de8edbf6ef5c9, + 0x2fce3f0792f5cd047fa8bc04de4cdf33e1fb7813fbe14320cf794b05df31e9b5, + 0x19d1204d38bebb4547c168a8b8e5f9266c5c88f9d30ca6097a5939ec41366bc, + 0xde612e0e3ff1ec8c10f2f6683274e98c095439b57c178a5bc0c322d94ef05aa, + 0xefa0f50e18937701c781ab79f263cf9fd325d58dd4d0936c592867f49707561, + 0x22e1e777da6b3d2afe2a2f6f74ed2487163085e736f587089fb120e5c149f8d0, + 0x18556105a08859a354db011951e9f9c5967a71ce648bf0aba15f2a559fd3976b, + 0x1a5931f9bf826e643d72f1e85104e5108ca339af493cf5b1cc364552a309326b, + 0x19473fd23dcbda0867c0d7655f4a2b99dd34160fd90b3a12dba802b661dad14c, + 0x29c96a2d870db1de1e35ba02b37449a947dcec5e3708fc592414acb59812c708, + 0x157097a50fe704e1f4c54a55088edb174721db69c7b7ae1b7394403ce694b789, + 0x21e90e34302deccd9b3588cc6c5bcf0abdb909e8c75bf618bb5a5334af7a164b, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x1d31a42740e431e210fc1553f20308cd05e93fc59b6bf166af395f9a66fdef38, + 0x7d5c120df5efe5ad44d43cf7966f6260b523a9b25da639017e7f14dfdbe22aa, + 0x1e4a39cd76190bd1b656e2982671758a893fc7d65985929f0c914553fbe793, + 0x2762072623790fc85fea72d6c64a298bfb16f90ca429e91a1db2dca2451110dc, + 0x144554ecdbfe88dc6f0c11c5f6b11fee2a86b1ec4cf9d69750091a7835ed3d20, + 0x1983b95a2c8b6fc3734c7645ebb497b942da887c3f91c054fb1a48d3c8a1fc2d, + 0x1113d1a221def2da4cb7faf3684ceb9f6bd2f3b0f52609bf08b2732252e9294d, + 0xbf64c4ef1310f286504c25a637ec31686cfbaff0c10ddf272a92f6fa8af8441, + 0x1209796e263e0d9999996e9f742ddcc4d92a12fd58ea384fe0a639da9334dcdd, + 0xb1eeb6c4cd2d793bf5e7c27bb55c1ccf4a8d010c6e6fd4909619960ab127655, + 0x4b05da50f761f6e8b2e065c6c6ec74e9277ad16d1829311bbebe773bc234a18, + 0x328086aad9ebc7aa0190d029b1b9ff8c89bd85b90206799d7f0b9a67806e99b, + 0x1ddfbad99857e4b84449e1076c3ff7a80585378d2194d944ed9a6fe227b16b85, + 0x86cc93c30e9bc4bf90c09dffe4e3755ca2272a216434ee6df144c2414930217, + 0x261fdfb4046f9f04902356a5682d941d98de74d39de11374bdc24fc441d7946a, + 0x21672ca29365e252389c40a058d9af3cd23d84e9a5c4c405b7197488037cfc09, + 0x2e04c3ce66b9cfecba87989ded13eba5fafb48fb63088e48010dbe8fa1638dbf, + 0x2c8b25d7c74be5b163c04e13cbc7478735c966253677c689ea1819e760b20aac, + 0xe9cd4551fb4ace8e62491b7e6a32d6ac5eb57fb5f801de1b27715cf1c770216, + 0x17cdc28c38b48f61a48be7d1e5e5c57e8d3caef8f59159cb8017b21d67be834f, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x1edcbf1e8c9add9f39b44ea9a4616fa51a90aa8d376e251e034a309dd69330b3, + 0x123673f7bf110ef3e41b81a4450a12dd2ca03a8e2048aa76f46be766192c68fe, + 0xee62eb21957dccda2e276ed02acdca3cf83ef2d381de42a0952ba4e2e71a086, + 0x67c268f3b750898c2a26b57a4018e3be45c9453001a6205ccbb4abb9a07696c, + 0x15a74bcb36f93b558f2f215ee8d41c64c4780df231ffa1b991e116f0c6e545f3, + 0xfd15b70fa8970f88e689bcfe746a1357b99a5b73354129d3d49673ae432210c, + 0x217e872910c020e9f11ea5437b1dbc0f45bff9a2c050bcdcfa2b6c345ac11451, + 0x1d12a9b49accc9f63862064b6f3d0a2510aa99f1d835880cba6ac0891e172578, + 0x2c9baba92c77edcd883f32d4c34ff1dd285e99653e602c33ed3a6ebb65e70a0b, + 0x2476eb407cc255bcb6509912e6748cff7adeb4cb933993b4f8c9643c03988fec, + 0x629b9717c416be51a6bb98c3716043450d39fc02078e1498121393a09663302, + 0x1b8a88c8fe80358d0e1532f7ea232f1716e561326b5000f53ae948fa3eff7e78, + 0x23739fa9f1d477e950ff4d63f82d632390546879165819be81219773004dfce9, + 0xe7522fcd267e8fac57c87e271f4cbd13d488f4c25aea6719c2a17cfde4aa8f0, + 0x58a36221cf3818847bd604233233e69a718cecf262baa457cf1e5cccb9ff6b5, + 0x9e192a9e456d483afc81ea5fc9cf93bb91a03334eb4d239753802785c6c8fdd, + 0x74cbcb738b033d9e9be837569ad0dff3d8ffc1eb3ede44892566568cb66b68, + 0x283e0b8b91557645c15defd2d8f6e21f27621adae3ffd0a7d7e9f31359110260, + 0x10eade70c487ee2cd5e43d51525ccd0f345a69ad735b603cc108c17b498152e6, + 0x2f01b82b8346c4257c16eff957b22028c5502667fa6874ce956e03fb6939f21c, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x664e78dad6b22d4333a1f9ca0ba708ad6ab875efa8e8997a0a8540a2599b0c4, + 0x4e1f57eab14954bd0b21619ace372b8d8aead861ac55f082aa3bc1d8245074e, + 0x41d00073a80f790beb8d4b4e2ac64f807f806d5fe9057aa196f880e653e6c78, + 0x2d2d71f2fb3d724683423f92661c8f441565d2e5a878b47af687fb9b76e1737f, + 0x2c80f1f732fd19836516ecae7d53f145076edfe857a6cd0749b85406ecfc14f2, + 0x2c4c5978cbe976f81116003e82010a291a0082dbd92daacb0a39bcb060a8d5e2, + 0x13e3c874118b9913d81f2d8bdf4a87a01d6e521d6548c66d7c0421db714dffac, + 0x1c0abdb801cd736feaa3fe7f98515e72f7a8d72ef56b5952e6a0e807e2c685a6, + 0xbd705c574e698fafc2d0979e92e9bbf0ff92ecb0a71378be168bda88c33d0d0, + 0x49067c522e1f0393a320557b41676f2539d7815ef2b21fcf310cf626d13a133, + 0x1989344c4aa025dd6a33c0f2ca58b22ea3f49ee5d29f0150ec05da44a6babd2e, + 0x2059839a6b9192e77c6182e6e564002b930aed9f328d24061701ce784408e3b7, + 0x2e29f425e322f7780dfc808e679480fcaa0761f752420a49075d76a085e80e28, + 0x2b310e22ebc1bbfa6514fbdee2a48cea36c1e938a6927486fcaac8201ff253a4, + 0x243b6f33e43a7d1ed19e7f1b8163316c0408e456180d572d52321b622a2296c, + 0x3028c94e563bc654584b3f335b0bc3312ec0ff0df98d3c7f2d02d710e1c7642c, + 0xce5a4699a96b251fe3c809248875d0b1d60b90cab8a30ec6f882e5ce1823fa1, + 0x2b9f25a7fb74acd52831e38877f95297970b3086d7888a5c2e1c11ce1fab81f3, + 0x2bfb58abfed4844f986fec4419dd8d83eb0d8a097b72b84c81c72a9eb4e4f7d5, + 0x239bc1e4d55fc6ed2c1e41d18252c011fc588e358fe839e1075fb344ff366d8c, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0xa948ca5c1f9c7d679c476d6cdeb6483d28b8fff1f4b3258aca45312da96c7d1, + 0xc5c83d7d624699c3654b32ca98a4da4723c4601cd7609db406bdcc5a9634a9d, + 0xfaa398f6fc63cc36b00addcfd69233489a8f96cac8fac8d91cc3c3b502d2e2e, + 0x1db588b11e10eba9c51ad6d4d990dbb580c64c0bf499a3b41006dbcac277e1e7, + 0x1cb8fddcaf050feb6977ef7fb82625d63f7286e4a0bfa52a9f601de563bcd96e, + 0x22154748d72b0e00f0f33d6d49e08b874ed2c638fe4c33648adf8862748b2f71, + 0x18bd4153a10ebedb78f02b14ea2663a857f458f2708394c628288cfbc802b043, + 0x111deeaa497d2d32e93d6d783dadfac2726f8487093472ec4fe8c36bbe2bb5d2, + 0x12edd647677abeaa0d99f2e4596bd64e1604f69552b6971c8ac3b44e7cd10a2a, + 0x2a1d5873e48e00abde4902969a921782430bec7be01a4284d0455219675df9b7, + 0x1470d1c0f33d2d5e2b2098376d16cba0738c4fe278ccfc3b824879535448338d, + 0x16899463366b193f0dfb39b35df617118d55074561482e0a91283bdf40804051, + 0x2af12631ed9ea59d387e2b2aa14a3ae1d28cc496e7fd28dc9cc149120108369e, + 0x6eefb335586d1eb862c09c79eda3712bf64ee5f51913c14e64787f59ebd4fea, + 0x256768779e0e07e677ca90aa7e514bb6eee69ceb47e749fb90ac20923d3af52a, + 0x5ab1585ae26b10fb8645be74d3e1afe99f25546e0708fd16ee2493844574dae, + 0x9b5ea9a096902a104e5b1fe5188a98ea78a373e7f9bf27f6218fd5f71f6e6ae, + 0x2d34bed47cafecc7b37ca25901e9f5e3c658950001d728722dc56b71e2d4619c, + 0x2d0071d201824d43fb057a0a523c701d2b8a37278b5178c18ed6910cbdceda12, + 0xa770d994f92bda5a4b63e65ff8cc35f59ef5dbc20732e1580f703d41b5b6281, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x1949dfa21e6b27c70609ed2bcc7aaf4f6244e289500c48fd1245566837cc74ea, + 0x18eacf1750c093e10b18f45702a42766f1803f4d2ad79399b86856d56d51f25e, + 0x29c3379e427d4e89862989d63a72321fb73197b029092ab8bf24c127183cdc8e, + 0x29fa50d3448bd783cc59afe8975b7da38d3410fcce680210b3295f8af30929e1, + 0x1bd6d35f109a3549dc1da7f96953f1c38f069e9a44141e85e69908366cd65823, + 0x2a58f6745b90dfe97d3f89415e375c43f464351bfbe3d140cabd8a343313eba4, + 0x1e34e898a082d5a1bb452870e41bd67cc5932031ea8afbf460d6fe4c253ec6f8, + 0x1f2884e10b6e90a0bb15c6ec37d269489c35a9fd5f2f8a548002cabaf189be32, + 0x1297717d266d0f55d1a8d83e85c22948a89227f47408b0a6bba88cad4e4064fb, + 0x2b9d9801a1b0a616582b65b84d5b76da1d6f428807f074108cce867bf1ecac7, + 0x701f771295984199a107564c0918dd3c397380bd47e0a9f0cecc0d57dec9feb, + 0x1a294c810d83e3f3b9bcf709dd22b810055dd3e6a11e456b284dcd40e084a263, + 0x10103201721be8dfdc55548826c8f2c6c5ac249a66079509091b71179eed1d4f, + 0x22d656009cc9ad0ea9a60cbd4eb058c820fb5387714d8b4ff52609638f3952f1, + 0x1d493a429f8db9f3df571b9eb1d25d425a09d75e6bac7ea1c8c0da141445ba5d, + 0x3d1a76c0fecbbd1ebc3b20370894284bbe97b8cf7b14bbc95dca839ec9c4c8b, + 0x230688c1f26ce65d683b5a4033cc5b781ff38d4a4e28aaeaf57b495cf843b0a5, + 0x159c9adea02eeb1276c2e1600930929edbd7e47b1283ed273db5ebdc596bc672, + 0x1abb8a81b4629456b639965a0ffee6ecaae145990d97b2b05546f47fa416e57f, + 0x12ad1b21a9c02da3018f187ac6a54e376f8f71fce321933f5ec8a55adbcd0ee5, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x3c6c55cca4740582956cee40ce3053e89ed882ea253a366d07dfc9a508c2e78, + 0x1fad53f449b581d0ed39dd41975d9330768364c1a97d9fd511d0df16cb3f408e, + 0x1fe8bcb3f7fbf9c21fedb5a0ae4dfb7ca275d535c7847b23cb74c18251b726ec, + 0x218b93667ede394ae16efa07315ff7616f6864cb8293bfd3418f9d5b14756396, + 0x41a688c1fb421db3d8716a64fc39d0e0677a5c43de90fd04dd9f3622baeb3ce, + 0x2987dcb79171d214817a006127171695659ea28858ae18c6fa8e505a4ea02033, + 0x14f45ac12d071af305059de0fc028778d5c1c8afb476d5b7b3ce2ea6a5f3250f, + 0x959f1dec81c5f8225c1f2ff4ae2c67c73e4d379756f40ee9f691c82ee08c6e9, + 0xac0780131779ad691069ecbc4f80886c0bd9518d9e04b99146d29bd7d9ffc9c, + 0x2a7e23e5aa5668bc719b0cc26dcf781d2ca359987f1bd6f9099b953751c61fbb, + 0x92c0b897d36323123bed6c99dcb3b50e397c722cdfaaa9bf6740907a4b653ea, + 0x29b1674c1e4b705e7fd93d10a380145be75934710cf6b43d24817ca38699e702, + 0x25db198e1a5de34b6974aa38ff53572ccc4036447a654aa7f068602233cdc0c1, + 0xff3174ad5ae186606ffacbd55936b65838c2be6a635bf8c9941652a485b8c6d, + 0x1bafb08bdbc32bf6b81d2026005e3ac6390ad3e36f9178be21034262ea674e90, + 0xebcf6fc297c34138661ce9235e7c0153eda1f0c99173970442976ff849eef13, + 0xd729230e5d6913a779746f2975e35197eed83aa613b7f9dcbfd2f713b8740b7, + 0x20870e26b114e1e20c70ad2d6c3c29bd78918bea5bbd7ec8bc0a60980e601dbc, + 0x84a3105ccbeb8137931901cc0a48ca7426e5dbe4d0095c11d63d0f91c64dedc, + 0x1b1e9b1d59d5f4518412a828475ca50044fdaa1c3490491bb508d7296436d5bc, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x1f4bea0f3c5dbf0b4261b9df35e5cf6a5cc36973d09f0b35fad3dcd0a4c69acd, + 0x1222849342a144de2b23e8bd848ffd096cd3332f57a245dd3ebfc26032a6186, + 0xca7b33f1129a98d404e882ed0a70737543706248c7374d9aa6470583b24ab7c, + 0x18f80a875ca2972a4d13d41d81a1cec56cf384780b5738e59988d9aba4cbb66e, + 0x2428fdee2ef9912f4693ee9c2a59e82c625e23e9af79e990dd7884410846f8e7, + 0x154781a2b5c4401f6ad2809fb9ac23f3136a8e3950ea6e3f084600a730c42d95, + 0x2c554db641533606c10532eafe2439e48d2925c9d6e183dd85f0c24986ae38ef, + 0x3b8b288b1e1a1fd2faefab9b4e00d9c503f8574e67112bbe603eea37b97ec18, + 0x93a9b03da561b4ed6aae3a98f4d2a9d1d28146eb0e91464c25a0e8f2f6011c0, + 0x108843f8d4eee7c9df86bd9a2dcf003d3ece8c1fbb2db80a0e225597ccc54286, + 0x1f043a72cb5432a4c78f14505ee630bbd2367e83f18db047defb3ff1a495715d, + 0x15a8fb06e0c14c181244b3f43d4967e28ba32bae1e84223037abb1524fc26413, + 0x1ddbc950967b1769cdb4f8684b34d9bc25b04deb0fe5fb117ad609a5b7f4049a, + 0x246a58e326b240d18618908b13785636f051ca1c3d5accddcf7cf4af1362b5c9, + 0x1cf99a40b8265758ba68441a45b4993993d732a8b3b88b4d983a62044c0bf7db, + 0xd7de5619f4c546050439e79af5f2d0b964ec40ac92ab9f33c617623c9d0479, + 0xe5e16504bd5429f1989950e8f41adacc95bc94789df4f29eb5c623a9ce4ad87, + 0x41f35a7896a627bb884f8fea782cb487c872dcfb82dce7d0e6941765d1ec149, + 0x1537debc183e50b25642a94332739b9dfa8610ef8297d963ad4f25114897675b, + 0x2d702440567bcd957920abfe3ca1796dc105a9d6d69df68f7040d45e14825154, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x14849e30e423d2818b033824be79e994d3b294a7745d47ba7a04412c976a4d86, + 0x136803dc9b44527a2831afd600b224d3be36a4fcf1f1bb12f6f3d9c78a49b55a, + 0x28ceeac4f3b856158657defc6ec2d98ae8222838625951aba51df3d92323af9d, + 0x24e2a9e2a33795f29eec4e3e5171cd1a4f102b387032736248d51da2ca097dba, + 0x176b7c931c84fc51a695bfc635c9b2d7e38c0fc9e39119a5d270be388a7ecbac, + 0xd230fbc8ba30ea43febe4d7d57cd646c1679a1e1a8066637e19d7b5f783c465, + 0xa3d177852fb1432eae4cea8005dffe984df233705a362ea87fd318658b1b10b, + 0xea4e2627f1b0f14a84fb72f14025e3f2d4087b5e23e197b4be18de9bc5d07cb, + 0x2b5a5586e185e6aff9ca42ddaaf4a48fcbeb342a33b7d8c30334f69917695c18, + 0x930ff45950e0b3a55c7b5d59b1bb103f43dad87f10dc01af4f029f1334860d4, + 0x13bf29d884e6f2f7718c62b49b2e4488f78abf3371e60ff6a55f8fe614093af9, + 0x1347ec6f72f1e6424af5dc07e72c8ed704c1de25df8d0298a06ce875337f16d, + 0x7f98eec37ea11c6a953ed4074e0de0319c71c5d80c6d9a7f1a7ed1642cdb3ef, + 0x1fbd5467ac28426e82ee95d4e67c1bf39ddbb0d00c8edc994d01b085e81025f0, + 0x160ad25d0a5b481711dfd537166e9a758f46ae98705c09a31bb5dc9ca672e06c, + 0xd1b059d762e26c7b237c2529c1a2c0420112b04b34071f365768e31c4ee44f4, + 0x576eaf22ed6ba9247a7c1cd5f36da28d3c82fee37029d5a564eae4a149f2ca7, + 0x189097900e6ed2067403aefd8cb2d68f8be1386dac2cb067f346d027b92c13ac, + 0x1d611f1ac08a2fd6b50b23612cd9a2dfbc77d3f1f01cdf0c97776885ee5f538f, + 0x21966ac51d732445609cafb1fa452a675d16df7f7c0c932aa136c7914da84816, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0xc4339f0ecf040eca09a8ce68b829e18174e1838978d18ffc85013bc4569bd80, + 0x20bf882ac8fa2b8a798c0bef93c8faaf79248ddf7520bf6615b8d4438f3e2f4a, + 0x1e097984b47ab98e3f1af30e8db0aeb16dfb7257a5d717b74a0302c0c65be5ac, + 0x2124c450afb451c834597afcdeae34d494f42b83ce16525ddd426897cb85256, + 0xae46f4aac64bbb73cbc4861b9d67dac7a5b9461185f1af393d30e0f14e6c86e, + 0x29608e35e4618f2d31f77f1222d8461c5daf83f8f96a1c3c22ece574bad1892a, + 0x8dda504925b8e72976d7225b9348b621d411c42725054f92bc5ac7f20ee1063, + 0x2d83e776ee847bb606165d71c5395381883eefe3e72db208d05671166672892e, + 0x158c6db4fa12040276f28c52fc4179c40c0b992ce3ff614cc8a335badcb5625c, + 0x2ba81ac87e1ba4a0abd35ef4d5e708098d5b3ea59df026301d29b0c639001d1c, + 0x297ca48636c22e1b41ac10da84d18930f4293297be2de6724d4a1c927ce6ac92, + 0x1ec2fa366088aa3d24faa8b0857b0ee947e7ac412a5c383d80a52219e3036715, + 0xef8e90ab9a0d92209ebc7ae7eef599134faead83d4cdc6a35e11486f256f91a, + 0x1a1ba37ce6b31c46f06b166007b84b1b5a729277769da12ac45a05329b1ab25e, + 0x1ce58fd6bb4c70f222a00ce15e034aa7f951e55745f7eb0e89d9945dc648ca8c, + 0xc96b4aebaaf211ee53c2592611cbd815cd8ad79ab87eb426ac951d465200f31, + 0x2ff556ea91ea4010ae322b26cc3dfdde21b77814aeeecd224d83754b6fa95b91, + 0x51d4d2e3822d407607a763652423f88ab8ac41d836032e330dcbdeb89dd94d5, + 0x1f484dcbd4ae03263c1043e2c67dcd871af9f682bd063efb99d6f2c1f58dc89f, + 0x3625c6bbbeba41cef4419cfc7885a6acd236f23c10bc21eb96fa3329b0aa808, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x132c2bd9c3df321b8329f997d51ea4756f06d20599a69b00d9f5d327f431bd9d, + 0x223271db36c5a5b734893666d05f8c23472da5750c9cc2185251d1ce898cdc31, + 0xe442d13a0489c8ff0792219ab95cdcb6aac03d12617b498eed4f437e9e90f8b, + 0x49bd7714d013f9d4ae5d6b0d8a1966e3b6ec2991f80938e99496db12778c62a, + 0x16863ace52579a519dc0983e73f391982f34daeb311b455cd75b3c7f75c4a406, + 0xb043bbb7a835e934403443a871e8b09789e825314c553ddb593c117ed9f7a29, + 0x2233e42b11b31512cd6662e6e2d0f6123b84428079fd25823e39ac7be086c286, + 0x1eec2344b54ebb5d2d89282cef20b5a8297eca522759df7ee82f9306cf7013f2, + 0x7d3c2f7ffa7d307b1b80cfe7fc4fdc571ee008081d1a37b83d83f928aecbed5, + 0x2040b72eb4e1314e2c6fe28b0e10cda2f444baa97cf15b110a5571ad006f36a2, + 0x968c69a272239d4657b02e1e1157635654c2493c5dc21c80e459c36943c0c7f, + 0x113daea091f19279a75d148f3407940605147f41277347181a2eb45da5e1deb3, + 0x1db9caad8a73497abeeed4ce12162d16c8ea56a6ba6680cee0253d7010c8b0c6, + 0x323906b531b036a422544f9a789b4818947bd7e1010a9d3147dfb298d747c97, + 0x2a17b02e605c66f2e9191f6001fe8d0c054e9fdd72aa912d61b14db3e9e5ff36, + 0x20215701f065bea87da0f51f31fb17022a2ff12ff86a3a7d50bf196b9a1793b3, + 0x2ffb3a8d5050efe66c798eae2e37fcb0e75c8d3098463728f1258d3d15e9c58d, + 0x42aafa50849b504124ea788b0ba7d398ce77b42c09f25618b1661af76c42d7c, + 0x1f0760c47e75e2988c7c5f2729776fd656ca950959500807c33b15d2a20b8d0b, + 0x1b41324592d37fafa8175af1dae1daf093b7bd074de9dbe0f47bf246fd338295, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x1326782be064b822cd54a82d526e0861f69cd054922b7809cb2f1c685b255442, + 0x140941464435a4da425c24627a01d5d0620429caf2b74c1cd8217f6ec0c5952, + 0x16d038333ef8265b4437495d35251402386b448bf2c652bd752875cd6abdd7a, + 0x14b3bded0283d8f82452086053472baaa94214fc64e23eefab04ff3a666ef793, + 0x265423dd06e1bc30d7ba50361df7b08371080b61cffa5cfcb4de6b840cdfce11, + 0x28c4d3106aa551425285a62673853db6ee69f820a38010b1e986ecb25a517c43, + 0xef4196f06abd4be2c6c77cdd3d9fc71b7056fcf82ba878a3c0f4a642184f33d, + 0x9ae72038e07e063172beeef085b160204d41fff261164869ddd3b35aaa852ba, + 0x1e653d313dc085a19473cbf173a65a752d300ac1001b2cc6f868c5aed1d5a957, + 0xfc8d4790130083f7d876b437a36a5a07861bd3fde394a7297affba00cc0266b, + 0x8889eb9c02f2805d59ad7c1cc11f1f8eac7d10cabb324cd28a4ceb64fab9335, + 0x5e2245fb34a0b6d4fc8c7d9b98faaaaa578a4bc650b9ccfc08f2f94596579df, + 0x1f303116020fcf151af2121de29d1237c03b89d27ccddfe6283c1edd985a8e75, + 0xf0deb6bc06f2954f1ff6e7f2b0f5874a40a67621147f49d9208913e3da2ee1d, + 0x138bd70bb31ee416686431f11be6768999f8a881cd5ded3fba47b1e715b98a76, + 0x2323cc181a6d96004077fc8afa78000b67af7eba4a37699675326751ca3587bf, + 0x2cc5a935240839d0916adf0ba2a13b373cd9a249f3dff29d4e636ea39bb2d47c, + 0x2c2f7e211539740f135771a5613be1b9d5626f84bd9bd3d086f6e33e497d4301, + 0x23a3b12944728d9d8aecd5b9ac2c1e8683a6d6fcde6de09f9d4981576f60bf7b, + 0x98c6085a8de8062c4882a80a9b53bf605cd6d3afde925b4bd97dd0ced63a2d1, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x2b1aa48ed061330641b7610a5ca3ba0397bac5aed1220abf1ff3c053799d5798, + 0x27cfd05fdfaab10d703c5613ac9c30f2fde048b85315e4cad39a76c2625878f, + 0x2c6768184cf84573a0e970704987f3627cf4f467e72d878aba9ff0e6c32c76dd, + 0x1660e8db6fb22994cd208878039549f85464278a6d593dd871de03c5fed8233d, + 0x583531effd84ca69b517fded392f636537ccac39575313c04564411eb381b38, + 0x1b1f369306d9312d665302317d2ef8ba8a5673364ebb84b82de156accbc68485, + 0x26e1ae1e46325eef62e0ad0702b7c20411e5687ac8bc8b0c42f2294ad511e36a, + 0x2267a248407bd8dc0be8d6d60a901e6a6f63198e43ce9ded8b48f35117cca600, + 0xaf3dae82886360e75e265f24f928417f3404fcdc18896104e07dac544146d05, + 0x1322272068ace8538671a961e8182ca7379ae8066dfa8824036856446ce68262, + 0x2ad6d87af121d4b9d388dc3bd0fb2160dd0d43deb5d5fce770b3f66d22a865ac, + 0x2db628ad83bdb8c87642ab36796e64464a71c8dcc07db41090014d6824e9e55, + 0xbcc76f8301e3daafd571227cd8dd395fe5b1ef2a88262aaaa30eae1be85a66a, + 0xe953f3e2a6ea919a39845e34a8fff06874f40fa0c021102551523f0052f2ac3, + 0x4ed6096b59252ceee6dabce4945012b3afa929619e124fc1674f9742de6ce9b, + 0xc45fabe45fad457d5e763ba6f401e038a8f05187a50156e2e4f73e9eb0c1521, + 0x9cd9ddf426f07cd7ca72e4abbc3ca38063705cfe04a002396d91101f41a8ebd, + 0x37124c13e8f5393d02c7dda6fc39b986e10f7eee7eb4d8e8b6798aea8bf8116, + 0x12326c23b50b4f2ad7ad2a6e2f81e766da9dbaae3a85d5256c36f54f99504c10, + 0x27097f5dd86e6bd0c09ec07ed1d565846382d11310d53e11e4ad9dadda2d2a2d, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x213719ecc1401b7f148d90bb4ceb0cfeccb1f84a03670a65cf2071a97c55188c, + 0x3ce9eb2e5a78e09fd8f99bf3677cfb69d8d81fac2ed57a3796fda4c4a75e067, + 0x2085f6b2ed31422f2ef8c9e8132320a9ea78f629f40050f9ae1f8d2212822423, + 0x18c42b10a0239a0788ca80f40bca9eceb54cce28ad7025ad73c0441f46e25d7b, + 0x2296d46885d7edc9e2f4552a8f61e0320ab91104076ba093415f525ee1bfcb4, + 0xf464a47774953e1647c8823c1f0e7965faf6e8e51a392f342e27f6b7e1e3fac, + 0x1afa5a730a377f7595ff598c11a257e2b25dc96a71a536671e98c4fef8fbb126, + 0x275f04d5ff1c821ef2729f6851a372c7db62bd3d45b68fd05375753a9ca38ad6, + 0x1ab45e9a2aa1daec4586bc866bac1bae78d8b8aa112962f34c5c19a4588f11b1, + 0x2c2b2b27465ba8f6c19c1b3e4b52ad9e76df8671ac3817d8c467fb7ce1a0d9b1, + 0x3cc2c6cd22dd586414a1f19bb9bb0f8b7dfde77369f2033f036bd19412410e7, + 0x17b6daf401b7e08bd9c414d067a6cb484ee05cb2e7c0791ac2bf415e847705ac, + 0x43084224ffff7fb2e73981b3d2da64588e746e1ff0a8e41021cf814e846cef3, + 0x19d25137be34aa73379f19107fefaab7ed485b5d49124232a91341747818b125, + 0xfbc00ac7aab927fcab38cc1f033d0c79ae42cbd8af8b9c676235361805f797, + 0x2a452e57d835dfb153c5d5ab716c615586a692f22ee8bb70cd32ce786675b85a, + 0x14ee41c5beb4f4eebb844ad27cd712b8b7b7d3bd96afb18417b0bd83650ecf59, + 0x151e1b6f64a2a6ac4afd3ed3adcb59a2f246e4d018a85a4dec29867998bdeb1f, + 0xdbc95be9577eda26c26b97276780a2c44046eff2d20ef3e233bc513eef1d289, + 0x2142c00dc3ef56e58d4fa535297d2349fe5a8720609a459de7d10ee2ac206735, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x14f9e34fb8cf902037da0287f7fd59460ee42d86542ea027f5065f4fdb362030, + 0x1af072ef30b93499a21687071d9596f8c0720959f5aadd473015a320f525f3ea, + 0x1f79f8f436951eab483845158d798af4940c43b6c7606496ac7787e23d513562, + 0x32ac1327d91fda3e58b64a629d066b7618b0d2bb14bf0054f8a99ea94a7f9d0, + 0x1690528ebb80ebae626e4c7ad7808201106c3f6958a8fcccaafbf105bb982969, + 0x28d5726bbe2136f717cba221424342090f8922b607e61fddb1278c9090879724, + 0x2b8c6cdb0da43e1a2436f8c43ab3746356bbd0a40ae0f4bc282c8f24d205b2aa, + 0x1057e1a29e1cf4f016b0ae4b377cb2946f4ecec14d8a9e906e8bcf994968ccc7, + 0x26175299ec4bce279b5cd865110cb0f7253e035e4dd530dc78e98dd167a02c40, + 0x2fe4d13a9ea0682f7c6c79e2faa642823c6ec6166864a3becc3aa96a06023078, + 0x8faf60f2754c6f88af83be51d4d8fcd91a530c7fe1a7e15c04672be2e26ff80, + 0x1125b0b9078268105061cd44cfd53e59b4441c494e4e621513c0e2a7897f2ac3, + 0x2ca18674217c0814c200984a2e6d96fa6ad7a93a350ccb857f291dfa0a6b7c87, + 0x1b654e8ca3777847d7febd35e71555b5fea755b167581b91b8e66e7557a13755, + 0x25cb5e571aef3c5ea542332f3cc646f940ce1ea986284074b9ec9a26028fc3e4, + 0x10152a1913afbe44180af20ec59ec32a3935fd2b531d968f71f0365054faae15, + 0x27d1880942fecf4f9e46d11a1e3db53c0ae9385a676104de122c85c67a61b3d0, + 0xb4adee6ba01707c232fc173d7db356fd6dcba566709cc81dce13db425685c, + 0x1e4ce7b0213b39db08d07fb861278fc32ded0de6232c7e050f9e93e4abecf7f8, + 0x9e5542f2b8481d63429010b3f89aa2c01b07684b08c406d0c85cbd0fd01d2cb, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0xe24744fcd2826a25131911f4fa8edcf83597f52c72906932a58f3047f9d16a3, + 0x17a27cff4f6f9a2f2a1bffc998f0ec03338c0fc3d3ec9794b13af50b3ed177be, + 0xbf90dbe6022bd7df688eaaf3b9030c5b6ad0c3633b351abe5905c2a2b2eccb2, + 0x2678e3c1f390d5459696d950dbadb7b264f8284ddcefaebd120eb27e2b19783a, + 0x26df8104d4cdb377d22ad344e942b76261b457f52d8498fa69de4e1b8ed37599, + 0x29c0d6adeada68a869e934d2350a77c91eeec6da2c0d7dd111b8f03d73a2f54d, + 0x1517295c7a2561c1186efce6e54a6070307540b69bffe623abffc8984451bf14, + 0xd79894bd7300df6fd04a93836438358cc4d6e6921da38520a04fbc8fb4ece95, + 0xbda733ef7b53f5843811029b9a5c412237a72b96800bcdc6c71223d57157917, + 0x27d91c5d822f56a78c86f2422ca4786b94aaa2f3e066fbeb35b81c7e16c0a1b1, + 0x1e6dd8c7e739fadd91888860adf0392f260272a68d32b914f8862493847431e0, + 0x115d86835c20a27ca16c0aef5afdd73a1b6b7ca6f12116720b235274ca89fb5f, + 0x24df0f59376b1b5e39d9ec2aad776278fab288047a2df5df60990dcf935aa50f, + 0x45885167ee8e695c6ac79eaee96e087946c584049012a309ab8ec2087491be, + 0x44b70f5e0df4319827685be272a32a36ca3c4148b97c13bdab2bd0fe365bae6, + 0x2cc8eb658bd3afc8f4209a1c99566705cafc79332571f133979940b14d736f15, + 0x238c44c84ee349b63030b0fb02fa7653e547c4a6329b9902de3602c3c4fdda0d, + 0x19a32cb6029fcc93db2b01deb8264a9eb157e995ca21aa0e335589b06ff77be7, + 0x1c8612ec98aa9278caa8cb6afdbd00c02ee2f551d3d521ff5e9f92748557933e, + 0x2a6509f5e770cc50d718f8590f5f9de7748372d2d39f59a859c9211ee4bfd50, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x1bab122c560118bee8f3e7fbe1712ab2b2a7312af61fb9820b77dee8d44d6ded, + 0x27172e3eb51483dac0c98e32f05fbce687414c3a3cc27ab1c277b13ce2378217, + 0xa9e3d7f3ef34d138cdaf36b92bff06b4b73bc9ce36156505741195b98d049b1, + 0x1eca82667b9ff6adea09ea840efcbafa5e206c97037e01ffbb28412fd2bb44af, + 0x1dd8dfcac157843cf5f94f9b10baa21f00e02a2cb5193944c3d3e970f910cd77, + 0x23a1e6890522a89b9b88d7db407b00dc68a40692a366936de0eb9a57bbf1c219, + 0x204f236b39b9136dc92f8135192c87c98c7984f1c77cb6064c71ec047975ff67, + 0x2c7480b893a528fe00d1ce1e4d22b330bf286443fa443590a63e27aa91eecd53, + 0xc5370a183a6f75b698c0fc6deb4447cba5de9ef2002cd8eb2904adfa4645843, + 0x237300db179a8dd6b6d784735cdf4640d61d44b518ea8848d8321cda2b7b4789, + 0xd9c58331bea02ccab4b9ef03eb202f1955b266c6666ad886272fdce7b289da7, + 0xfccf4375bda2c5db513e2dd0638ea1d2edaf41c2c754482f833e17c62d92019, + 0xc414e955b84493a9a6c827f24c39f62a9f9c2c8bdd9f76c3884d16217d30c87, + 0x20544d89fcc7941ac4972e5528300d0c35d5a650b8ff51f72974008a312d40aa, + 0x1af59412421b520c1171d8b74057dbb01653f41082f856ba5aa6abb79a43c354, + 0x2fc1a459440613daf728da1cf3a258c093bf41706724e6260afcecc13d324b51, + 0x177c1e93ee0ed483c73f148fc7f9891cbfc36a338075bc01498a69b0e1f8c49a, + 0x98c005b2959ede9425452eee49a4b0803237cf111f046511f8d56bedefa7682, + 0x15866d82d251f9afc692c1a115cdc5ac28b4771bea862dc26643e6db1d61978d, + 0x2797e81dc6fc1e231f5051d228081b46fe53fc394524ff424963da9a91070bb, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0xfd25da5fe62ce50a1525fe9e3566e9ff0c9587302f778d7756bd05d8c6aaafa, + 0x2a1a6a789e908952cc8c2e72ef95a937179c9248b091d016f28e38db12312308, + 0x2bb3bf8f61d1ed85e2175534e9a5ba3d17dcadce45eecb3d58749a03e2b04fbd, + 0x1a30a88ce2e48fe060eff18e1c7bca6257b8e39351823a819daf303f5fe641d9, + 0x5ecd325b357e47482e4e749cc8305b45ac1e65aa7ddd915ac37f3098dfd2d98, + 0xfd33eed2e51061ed5cbbe5de05b6ede9152f36b11468387f518a997e4f72214, + 0x95e4c2caedb1de02a6c60b086b8d8b67b9afd186f65e158d2748d2514d37b0f, + 0x1842d38786dbac9400929648db9205d259677647a5024e35caab08260744f013, + 0x203defcfa6213a500d5a788db1e0ffe30874406355502644de206a7303dff361, + 0x2941a9e3edbd2aad6138cb7582c8522c1ac4885b719dfaaf49ab0a138c24c657, + 0x10ff2a2017cba3c024111db07e677587896bf77e0673a928c5c2c9edc53cf2b7, + 0x26f456aaabdad81d33930cd48342be34c4884d52c17c604b45e9bd80cf3c19c, + 0x28e34a4031ce3e5b92d5d92f9b4733668ea65762bbe5fbbf82cb2eca7e208d9d, + 0x9479c03abe2fc4bd11f410d7fe958aa64aad1ed9ce46de12e16dce1aa9007a1, + 0x1901a62758c3b95378ffd836f543a2c2c1922ebb864000184b1a29167ed608b3, + 0x24bbe4299e388e01c96d7de61ba9e9ad46256f8d8c186b2e3a387d558cf912ae, + 0x27c84170d0a49798dfc9ab4d6a96731d0e8de772ca951c3ebb799378d22033e0, + 0xf12a9b9e0cf4da08c085755f42f2c83cf9f9addaabe06fedafbd1ccb7696e1b, + 0x2e34fc5a79f3d7859fff73ee159f8a963cc180ce2351f2709dbcbf6ec0a2d7e5, + 0x6d2b2ce15705618d1574127c9324560d2c222065da0c669ffd2304a1bd31661, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x5b22e29f9914100e09f1d9faa6ec48b849d06dbb567b978c8e2875b8eddf2ee, + 0x121d7d80eca14c71d3a9d568d1fb3d17d848312ac21722507029ec3df61d64a0, + 0x248644294d40fc12cf53892614ec0e91eb6261ddb4de5a54590770b5a63791e0, + 0x8fc50ee296f9fc6e508a23b38d180aa92fec743bb5e62017ee4a3f7c98aea88, + 0x2f233d2487f18e22836df893982a593c74b7294f6cfe3ba3edb8272bd2559179, + 0x10f6d94022fd2c078fc6dacb1532820021f50f288ba40ae4016366dfa703e8d1, + 0x37d5df7e15cf95ac9c4bd02ba53e6d03bddd677a412bee4e0603f88ea1d6ef2, + 0x12354c8b1801f10dfe6c394b08317c7e86f49e212ec933fff49d8b26553f3e72, + 0x79679dd2756be024feb1bb2ee0aa5061a39752cf710ed6c9cb588f33ede8d0e, + 0xd3b424ee9455f137160fa1dd534f67bf068cfce1913a075fdf1cae7e8324ca6, + 0x227338281ee7da633b4b3938f5bb981f838c40ade4a0710875147f526fbae49, + 0x234ac22358b519377341651ca93dad434807cce449087bd4384f46fc732f7997, + 0x2e0c95ffbe680fa7622598933adab2a57c472a0073bffe10c0284739b26700b6, + 0x15e0c89cc6c36a7db841d4270855d1d9b8849197f9b08131b625d5a6d9ba693e, + 0x2f8952ad83b1ffb3c1a4fbd1064faac4f1c9cc31d0ff156a17478a1e3d255117, + 0x1c7c48183ec207dab68d73aafeb96047ccf668318c084453e495ebd5f927d173, + 0xecf362a269cbb8e56c2b0537f108a412ac9a3c6e351d0d27d365a4db7cd75e8, + 0x11cd56f9dedcb991c0c6cd9c9a0def911edcb915dc1904390782a7ee90d0de8, + 0x1ee74e2178baae842dd9658694381cc93b01592c655160923d40f4af2b53eede, + 0x12a2830e24c8bf4e9c7f019526f71cc57bad7995f38c6ed20306bd7b00f0d7f7, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x14e12ee2c2f82a572d97c0b811a25584bbccc9be1b67ed1aa2141b2cc793fbc2, + 0x4f32291e7636221ba7905a9a3a1cae812ad570260c81b3ded9af33619fde33e, + 0x8a081bf1497e5210f6e0413c8b510f000fcf4a46be0a1b8442c5bc7e5fb7751, + 0x284571ffcffe707510d0feb89560623db7e3bf57c9675b02febce95fb7969e8, + 0x204b298a08577c1269dfb8ec9b4b3b502ed6fc3303544047d56d4135d3c01ab8, + 0x484b3ef7bcf5d63934bdcf53d8aa372a0b0363b0241320baa3701e8a1d0da03, + 0x9da34491e52c865a5b080cb9791a1fb80152c04335b1dabc34ffa6ad622842c, + 0x1fa3cef56374f00878372c54070d9c41c5ab9ab1d385968daf9ca2ad67d494f5, + 0x20b55b39b8df6f86a2ca381e2037d64987d1844c599feb2829648955ad16f758, + 0xff1c5369778d4fd96e295c21bef4dd4648fad9531f669e704ad2e4178674564, + 0x4c4c92112d998d5736b3f46120404369c9c0e428e47577c857509fa556a15ac, + 0x27a72f4b6e9896945e7d584e41fbd3cd5f75862fc6ec94651f5033c8da34cd05, + 0x2a1e46726ed9068504f7becf06cc70a5f645811bd65be579194b54486158599e, + 0x15dadcb67e30b77d8b1e5dd79edc36c3d8d0afb29b6e7f0207455e92a301dc93, + 0x29c1bcabaefb4954743a7a04502647c11c9f18de67e21c811c8d2b9f3ed82dad, + 0x7d089a851d1c43af05e6c9243b69b77b12f0c0b0dd25351c522ce8dd99fe5b6, + 0x1003d2e1e5368d1318992f181b7cda7786ec3e721be4bb89089bd794c6e9fc6b, + 0x1747c287ece311b5484adecef423434d71ca807924c54a53e31109e6a502ea15, + 0x134eff601bde8da30e62898b2e05c17f6e74d4ac31919c41363884ce7e30f017, + 0xa2d92f328082a3fcf5809958671e304daabfdb5708edc2cc207175526ba3e27, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x4ebed2d43be5a74e8a00caa83989f16c0b9e82194db68d072226148c0a3d710, + 0x29ab24663cace590f69751506905667079db84d33f78204a31c93e7bea1fa839, + 0x14351a07d387943cf46b65496c66bc6f3bec8ea200d622074ac2430eaf521d78, + 0x1c423576a075f1d7376168b207a6d7203712c523c67a9d38882e8642c8fcee02, + 0x2c0564f1c52ac2d9f46211743b632ff07b210916de258f83d04df68ba0e29228, + 0x7ae7e44ebe17fc24a06c9caaaf787c2f007c640faaac6bd1790793712a69525, + 0xc4e1c566871f3484afba7d364ab755b839b09c5771413b0c31ed6a0fd2f4293, + 0x17c4f2873e2da004f2eddea08a30a9cf2e05f196fd3331b6f7f1227ddd8e7fa2, + 0x26f0a8ab7b5b0ac4593c98a899ed92d839837d520c5f6f0afd65da69a1205cec, + 0x94dcf41915c6c7ffa168dc7137afa6778076c2b63ed63d1ab1b787681bd60a4, + 0x15240235912d9c5ead8feecc29a4d77d8da47e9d1909763294ea18c027f1bace, + 0x2bfec6d12a548b0fb9fd176c7200df86c3bd785d86b51b2076bd9d3e8247312a, + 0x15954dffe4cd018acc436b70b029e0146529a26cdb39151468767b88c80ac82f, + 0x1f430be26a11f722560b348b1c5b526894cb458d8a30b49887713d76368302da, + 0x1360de1351ff67b63c312a8cacc2a465bb82dfdd3d792244068292aac083c8f3, + 0xcae448f98a72597e67867a24eb6ef2c1ce5d454fcf1c9eb4d84d21ce81590c4, + 0x20e9336dd103f61a54f27fab65e5fd1a317e75fbb5b22a81fff27ae4c8afbc95, + 0x2e36c0ee853342906730e7a2061c3aa2dbdfefbdb554b3a330c0ef34bba74020, + 0x21be1082ecbbc3a316c9d73495cc08c60082e1c20ad3d4eeb55553eef1a96dd0, + 0x2c7cec0d47c779dc5b614efda39049642f1ff409a40be89cc93e29366df96dc2, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x287c8d33c0bd8b9ffcc38d1a3501b462711a41833390aa6291b5691321f34f3c, + 0x524f490297bfff16e253a88a02b039f4d7be41c62a47525d615558fbb91a31a, + 0x3a6f7a96eb42aca86cff7e2417d245dc19e8c7934e91f3dedb429ac4de7c61e, + 0x155dd1bf1b5319c5993ffd435ba45f0a0ac8d47ef063423008b858ba214844d1, + 0x1970a0db54455db508f369e376345b47d7df8dd58f6d69cce8330ed48723773, + 0xa17d8e77907e26a6c23a52ef2b39064da014f030b5785f3ced98a8daaeca3f5, + 0x199b42a0db3b829ede26736dc7fef94f2f211679cca63e75dfb6a221d4897807, + 0x1d492d7c7daa80eb64f335e9cdf306b0be4b418fb7edf32eabbf0e89df5b8e61, + 0x17c60af0291bf796fffdbc57db59d03897c671fd729bbd4c498e6069d0671ad3, + 0xc646e58e3442bf43b2255aa0b44c45c87bf5c947ca5192eb906432afb47791a, + 0x27bc23b6488e38e2ea87dcebd6360dd420d7ec90a58601eb1e312c6998a952b3, + 0x1c50a70dabeed7c79cbe2f91b2f9a1d3ca9ccad68afa0a419745160b03cc07be, + 0x120ae724abcc772ec7b0ac90719be72e9c17059b191f6e562620484e691f6e4, + 0x69f84058a0565f943c4f5cff4c939581975165144f1d21c05217d64978ad803, + 0x14a086d34d0cb4c050cf996b086aa3a21e451ae658ee0b037e7b0ec28f5905bb, + 0x2fe2f8e67ac2734b8b1f6eb408f5f62fe88780b37d4d0e3396c8561309f1392e, + 0x1b125268df7d9e01d789ba26c5956069989aa5328bbd46bb3a1c83e29b54f3b8, + 0x3006fe14ef14b876c2e1e2c7415c98b78918cec927d8b711c4e11987c2e2cc59, + 0x19332e6cc8221b23fd7926c431b68c75583036a24b7e6524527eacf775b5be7, + 0x2780775cfe1ae1fe97897c286142833fe289028ac4e51285719df14c4ec967fe, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x1474d911726d98132a38828196f72ba9ea28de0e540822b530d53431c3f787c2, + 0x29778cb7afc99ff62da1a393d60b87bb8573606ab7ad7cd0ce647bc1984cbb10, + 0x1483d10c35376ed7a027168198d871358c79afbba7885d27c01b766770646814, + 0x1a8c31c239faf47d773bdba0f70801eac0ac001c6df938463cce819a72a11591, + 0x2c58e07b869bc14bb0eeb649f5c7d9c278b6f7639874ec404ebf75f58dec4831, + 0x1d649850732837e1c07c9f303d6278bb14f5a54ca14c86a26379029023c3c6d1, + 0x14306d8668280502119170da14128f6a340f1ded7e2ba209004c42fa628b3a0c, + 0xd417ecfdcb5924437742605073656307d039e23dc9cffe05ef8416e9dba3a1b, + 0x1b5881474a4679cde79a4b63249d1f98d8b417f1161599f6725471f582019156, + 0x2c571e0b35cca4cf4ca7121c9de0c4c5aafc7fa6f75498e8ec57928fb1c67d64, + 0x2637d9a03ba20a6cd7ed99a69c38a6d70b79d05904e37c9dbf46ab2c90583770, + 0x1cde7eb4a685a52ecd269169466eaa897ca783401860eba2b6026e513d6d393e, + 0x4f817cbdfd445391ae482fe7248567a0c8b82136358d239d4ef180dde2f489d, + 0xda99ce6262676118f51f86309d5288eb65c95fddade417046403bfdbb087d7e, + 0x2505fbe37c3109a4d1d321b72070a152625ff3b0fb76ca925e5aa2c058879ada, + 0x2783007044f2d12e5db30735edac84614cdb1b19f69901e0f601efb3d44cd5b9, + 0x1e145eaedf86b1c5cabe622df4cffdd8155e6db891ff498ff0b887f4ceab124d, + 0x8bd690af3ee78b6d212cf184b969f3112d45cceb738558962382227a434540, + 0x5a5462e764a4f4780125247cb6befaab7e4dc0d26e2d75f44087af9f6187b4a, + 0x12c972140783d7889663c3c9da5cc43cd1a9740471de97908a62cc21d43e6e7d, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x16109bf9f0eed78c726bcbde7de40cadd12343460b04ba93a52d969201f97f7a, + 0x1e85f44c0c271ef8b9a9a29e3cc73b3b782c60d4ed7cc7624d6aeaff8e492030, + 0x9deb8ecc3bb2cdedba96ab5bd80b15d4abcc49b6528e84c1ed6971fb3aecb86, + 0x7ebccff0e97b9ffcbc6a2b256bf888739c0db05bc5d98d9e591bea4d74b5c7c, + 0x2124e4a429fa993d32f641febec0b25b9725342879f76afdf4e9eff7608eb81c, + 0x1f4217ea25fafd2a62aa709ef72365c70d66a4bd4d756ead776b40521b29e76d, + 0x10fdddc5f968f32bb7eb9555c0dd44462771f57424a761cd884cd0c152a35fe4, + 0x201c0f5551305ce9fe25f26526e409c0968c80b9e065553803aa38bdaff0182f, + 0x1cfeab50c568b3dd5c252b7cbbe28678939231d1287580ff6222d30821191ff, + 0x2b4c60bb89f1ab1bee21f45cf38de8335a2e85b513fe3a9624eeaa1bf6255765, + 0x285dc6058b80d18829ee46322acf51d442ec61ac331af40ffab6cd30a07ddd8b, + 0x13b9bd7d2cc334d2f60d6249ee87d05e356fd182830d3b3e9f435c6240f47603, + 0xfea707f44889ee47e8d9859c523f99c432083d85fdd6a8c75e1bb5771c10825, + 0x809a77036dcfb9ecb677ffe4e09ee7fab157ac28330abde61af824725d9e74f, + 0x152bb1a773b27f82406efdb0e1557c03a9397a6d87d461fa6f2e06ea9dd4e208, + 0x29da79b1af8bb1fd1dacddbcac71ac28de5fbe6aaa9e30f471acc532f5fe9290, + 0x252419542bfcaecc57733b02751f5142834e93f4560d7b95b85ad6423073be, + 0xc9ddd8aed9e907c27fcc361067f1b6c104c2b0a553e6d6053d2f82fd8cf1cf, + 0x2311bf775d429e2b982ca78c015cfb0a863fe4753625c4b63caf8e4ce36e37e0, + 0x2a72547e8d5bb41f0623072d419bcf39d08e5aea781b7358e95757a0664d4b23, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x13ee4f15f3b425aa17da17f6b1f5d00cf09454a9515ae5c719a2d2dcfb41112d, + 0x190daca6e75275d36dd65c372d302d698b1a03757c0b4c7689e59bc1a0169f61, + 0x994ac0e199f04446e19887d6aea50a4e94172fe29818bf60354e92ba3ec6d37, + 0x19d35ebcf34f6d72d2cc738a968ff2acee72f5a54cfede510482076fae55c450, + 0x13b39ce996b064bda9880f5a6ee1677d731851ed9c895f19add559025c0decb9, + 0xd53028037010842c02855ed8d3143166621d870199dcd06bcb970d30b8adb7, + 0x26abf84cccb79dab1c143c12cd741320c9811199329ac1b13c240f33cb0a1476, + 0x2f94d075a38862b56155e5bd18fef09e29267c0fe03259af2122abd935054209, + 0x1d073e9398a1528b81d2a14baf97ce3081340b03c22ece28408cd284c2752b32, + 0x1dbebbfaeb42d7d727f73f93ec0644264cd18a0180ec41db0a558f3b4430abd2, + 0x2fac339c24fe87e3763ae29dd6d341aca13594792f6d48c66fae31b464234fbe, + 0x89dbbd04d315a29ca4c4ab69cd041eb3f8484a1f4a726139de0103404e073b0, + 0x7b9bd575f2ab6d2e57a6112b84c02fd38e25987794b65487f4975d098578ee0, + 0x26563d3ad82384b0c3bdaaf1770c3cd5a04873b239fe06dc21900ffeca0346c5, + 0x24d55232a8e458e4738c163f81ab363774595c7b79722847e3d6341e1650c80b, + 0x15f6a6be40f74352caf5e8c0d27c8a96d233f38d778756dd8b09546416a42a75, + 0x2e195aac1f98bb6fd894b6c8c78d0339d8ad8b48f6753046eb438897ca67cfa, + 0x240c714f2346df0e0a84bfe85b6f624b177e2fbe84b253cc4dd67c84fb30e574, + 0x15f8e5e81c571e42d0ba368ff59ad375c2de65558b61c63d08117bc95de0a133, + 0xbc0472f8203755eea5f4a54c4202293e72cedce2f9e697cef329b4a2e4f365f, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0xc8d9a3a7bfc7f53284d3f2d8493110979d2c58fa350b37572ba8ecb87eaf0bf, + 0x2a431044a8b80f847d099afa8c1e72d7f21894f3946b0126655720f8a6c77857, + 0x1181a1791fd2439ea67078819652478d6767154c7a9d04918373cc072d53ae2e, + 0xf0ccfb008217426f92cc5dfec764630d0861c6ff9be2459b227266741a7de7a, + 0x41f755b4afa6ff133e8e46fc826c9b3e70b45db7edb7ee2ac500e47e9844a9f, + 0x1751a37439e9124554ecb92e3006d8c560d6109b98570800c2edc590016b5709, + 0x2abf7e7390de929b5c7d29f75e5c341be84679aebf5cdf21ce295cae5881865a, + 0x173d1a4bd47ad310c1227e8d26c8c7ac003258ec98cb99c4f5da10c2fed0be99, + 0x208d34eb4ac78f934ee023480a4b55edb26e044d9a46008804113b8b3ea6e237, + 0x125616d001a18f80550970d010e57191b13574c8f737e4c82b47be6b1984fa62, + 0x671703eb5922282742b194f3c2d494840e872e60fa6e77c66fc03868c71abfa, + 0xe335455fdb0c93b70a21ae7ea60638481071649d6bb76343651667a6205ed83, + 0xe83b80d5c774f2c4e2a8c7f7dcea61c0b0f000c7bcdca6bae8781aedc2513d, + 0x58c57cfec4eb7be81eea51addafb135b89b2c5a111bca597f5212eed8547da5, + 0xb1f27ab7d0817ea3f949179fc135b60938c8c20bb9cc0cec20b1bc8c5fad7c1, + 0xae5de9d9b873cc4211b1fd9fb2e0717ce46072da5f7d8610560c9582b7f06ee, + 0x4e515f4aa39a0a8667cf06abff04d87ebef4d85dc32ce64a80be9073b8e0163, + 0x19f6c6c86ba20bec8725fefa5ee70cd0b1bb88b9b20847927e963ecc6f46d376, + 0xb97af80e65d5a12a9178351fe47f3c6741b18408ef108cd73a56a785f657fe2, + 0x11001edf4b5785917fb4ba3f1cb07e46f8f038edd5eba9c657dc39b3f6a254c1, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x1f57e91f818cb6ec2ea89a4c5248e21db4ad238c11e2824455224c316c6de448, + 0xbcbc929529eeab2f4001235f0dc786e792af2641c0db97dbb1780aa611ac51e, + 0x2ffec2a43cb616c220af4bef1265a368c46b0d1c049e79d489bd62e461669061, + 0x18cfa39baabd3a1f352d1ff2571411e36ff0c72a2796a40e9fc2238d89d99383, + 0x26d86eeda466378285e93d468c3686ab5f649a40ed46a52c29c2b9aed41391cf, + 0x2120bae48bc4d0b019112e48f3daef5b38b9991285c3d03e150a21fc03826de9, + 0x2872ab1dad0eebe81027996467b9767b38ec6dfbefb43d9537d0ceff4b0d8032, + 0xcadd0bbb15b10a2a3b5976ced621686e190691ddcf2911a6d7911aace0ee731, + 0x12f83ac35b2e971f68f375e239c28cbfc8010f2d20a609ffa4bf3ca8078870d, + 0x247b58e9d413e3b9647f7204b141fb1599eea15d505520b47d61c11aea6b1eaa, + 0x13e4b5310fafb562358633169e17e3431a821e301a178c33279f5485290de69, + 0x1da54e38f590b18af24713a270573e2c12e2b569b0e90992eb88312117269373, + 0x28b85a60621eb6d7d4633f180f515bac0757a3377dfd68181bf6a65a9599121d, + 0x1a152410d786dc50b32af794cea9b7fcb7fa48231d536b3c18dbcc7509606036, + 0x92699deed292bfeeb718c76b997538a59e7ac548342832dafd64637e738f1a0, + 0x774bf3637103073fe707caa2d322d9a9044e4bd92d81c1e0ba56467c591a487, + 0x1a2f16440b008c3f42154123ee5c0c0f06eca84795d9b104c43857bf528cf79b, + 0x149a1d50c2c217a068dd2ebce1907172d58fd0a3123debf849d13d873648a8bc, + 0x246086052d1ce8675e03b097029adfed9a97c8f67f606d7093f6e412a7b4bb8d, + 0xe2a84c4e9aa19be7da3e5d4dd74a495d308369e4b26a165dab9c4238eafa4ed, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0xa62dc9863ad7e45ef7f77431acd332fc30280f65ef1ceda4ccdea63b3ceed3, + 0x1b2446bbff67b4093c04a6f3e904075a796c5e28a5a6e586d6440753ba97551c, + 0x165b84f51091009c389eabcd7fbbc992996fe32d9f8435354368e1e5b1dcd59a, + 0xc193a00c3e7e8e353d0475afadbe369f9a5d17169a169ec197977619136eff3, + 0x2088473c2b6a6ae33c857f94f2f12b90d7f5ee0569d96d801fa8b87194fc4595, + 0x8787d2cebcabac086e9e7e1fafc216e3f8fe5335bd4642dfd1708a82a5371eb, + 0x11191767947a0e4f9c3f782d1abd55624b55ff7087f34478ce0a7aa7b2715cc4, + 0x2d28a1d818e8eb1efff60aaaff9483679cd5d77a701688dd53df7a9df567f5e1, + 0x2fe813fab1011dc74f8a18e5b039dd373f0070ab1dd4fd126718a087cb2b8f9, + 0x170e6e3fcd10c27d012f844c21af6850284e6b19fd5d1fe8258861d9db249136, + 0x107d6816c1e3db9ea8bdc485fdbcc7f13e6134e807d7e4d686c587b4b02174, + 0x19758af0d83c9505493b5419c17e6c4dd7f2ff338e60e9609259dcf15f33cb96, + 0x94462f324ece93eddd9764f77d342e248121b7f1dede3f149571a9d9890ba7e, + 0x86086b36fcdb387c6dfa2ff39c4910fd0af2fb3ecdedf957350e20ad3c843a, + 0x2e3cfaefc61b8b4800158fede4808cedd9d7cb5b2280c9b1590e0429a83b3db0, + 0x828cdea83f97fbf72dbdafad73f0954b8849f09a7f12c3bae6989012f8d9fc0, + 0x462d87fc2c8185981a6d5efc6e31654b2696a1c42ae60b99eda523fd8c13ec7, + 0xe8224f268418104de9a75f6bd915d2861e8e74a74057319dec312cf8be4dfc, + 0x89163233ad979f94876f77c9717a7cc3171425a1b484d1050f7550e31c5b42a, + 0x13f4fd6d8abcafc2d57797c252abf6319f2d2122dd71b15bec6dde9544f60448, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x2cd268e81100d72c444d6246f8003ebbc08c1b5b5850a508f162541e43804c31, + 0xdece92e3458e7d6e3ed03f44c57b6a597f2a0851662e51f30c7e345ab3fc44e, + 0x2782c56f48794e225a91ffec94d427fbc775704a57e24c93a1092b003ffbba12, + 0xdea062e2b07f7c6afba58a89e4f46c9586b6ff9abca5d59ed857f5b65e618f2, + 0x53f7495e4b1275b15b3f9cd75aa20f9f7693363d4311764a772f2956af6fac5, + 0x2d8223dd32694c54cbca71235970b8f70f1a7428bd738646ca6a862f46f64ded, + 0x230d3770de4960732ed1114493287bcba5a8b219308f15bdf3d66ab0303845e3, + 0xa08b786f3debb023c5ac7f28402aeed473d83cf7345cc4e3ff319ef710c8e92, + 0x1abec3768c3f0fb09fb3f77f12a70683a00aa39dfa9bb1df8ec678d38d2f59aa, + 0x285759f5a94427ddcf1462454842a9d1f953a3d2f7ec048846fd78d01a0493e2, + 0x2b4f0d69284e2851b5e39f369bc98b54d589c08c487f8c89d1eb0c873cc4be5d, + 0x447dbf76029e36fa2eaa60a6235e5462decefe44e558246910c8f6d57b00875, + 0x275415ec216217739aa767153b11ae80c6b8b5c55c70f2b971c41ebe8e2b6af5, + 0x1a7afd3f33137e9fdcb3dc28cadb4a2dc634ec68033c4121f2e55e1fad47d19f, + 0xda8b0bf0f0197a311ecf8a70c17d6b73882fa3d36a2966583161a3f767a5cdc, + 0x2dc11aa7fc35288f4c50ead3bec7cc0e75b9e52e8a3fddb61492ba94948d5ada, + 0x195f7447bdebfa31bd8bb43dd8d1e6875c5c135b15c3b4d609d52345559d71b5, + 0xfb172e6709df3831ca8632986ef7d85745139a51a45c169c830c4e691b451aa, + 0x88051acf2f4c7ba673361201ff1639e06fa376b2a6505a1e62038906a31cc95, + 0x19e57228a8198e58cb5bccca90c63d15e07a0f3e6d5d130d973db1a831af0bab, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x22e5666a758743c42fdb3096ec7a7e4266ad74824b6be3619435d172f438e2d4, + 0x13ea60e7594766cadf7e4aa1f9f005f9d9e06177456cb4a43d919b4538492a06, + 0xff1eeeb246ed508d96db973e2c50b126fa55bc7094854acba766574c0889a7b, + 0xaffdc5342a12d31f878c045e76796ad01bd19a313b08cbe6071c9fa06d37178, + 0x291973a60e03d9e088f91cf2e0d5d4b814b2d84bb97aec7993175e5d6dc519f, + 0x11739b8ee3040e282f6d5039784f6b749c3a4d6befe0ec6276270da24f8772be, + 0xe74e778ce3b28a1acf824de6d089b276e535117c55c361debf0a40573c67eb3, + 0x1a527cc72db1098870ef84543fa630c207a6094df73caca62c47ebfe12c4dabe, + 0x12f701614f5391cc72251c38e11391e9aa2d1703c47e84a041ab471ed77450a4, + 0x11936336d54527a9299aed9f52635b8a53f9a958598336c9848564b86516ceb4, + 0x272318da87365e9fd6249ec7615961b138ae0c7a36b5175ef5465898c711be04, + 0x236b144cf42999283d59501e46fe4ea1d60003599b4046d7a60373f0688093ae, + 0x1a239569e5888ba9ff7c90a4aeb505659415da6efcd3c101e791228149b35b61, + 0x1e9e91cc7f554dc236e84f167e2baecef5a26769296b73a94648d454028ccf34, + 0x148af5b46862ea8269491067a96aa3e71f424fe1bee820cd988fd8b19527bb5b, + 0x24772a606417d978acf26d46756665b3c414dce37ee779c91e98a4caf803b6e5, + 0x1ed8140073fb5244cba84342b2727e8258108dfb63d1daa824f4330932a7f292, + 0x109b45b57572882b3de57c6d043e9477acc341231247aadf512cfefb46159244, + 0x12563836d2c2fe6d077a81786800dbbc8e90d758a5a323f549f9b8d523b630b0, + 0x1ba00aa80b49e70bd2b3748968ce6d19e9d3fdae0bdbc10cc50e90dde09dfe0, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0xf24297c2abe65471b0746d085d394de0919936ec477876d32f44707fe0bf799, + 0x20eb0b298c48450c7f613bf10e04bdd22ed3115756fa21731aedc3ffbe7cba27, + 0x176482f9dab80cb5c4d91f707575f2a2b552fced3c3b96a5bf37f9b80fcc9f64, + 0x1f79915591cfa6648201a28d89355cbc6875e30f78d96a32c3f108bb3a8d5a76, + 0x2961cce7579ff9f9f0e867a02cfa8bb2e7401cacee24f5556e9d2fce5d0cec8f, + 0x2a41178e5d6a04a7a1463ca1799dd1ba6a7b5c4782097e585793f987485559b4, + 0xec4ae2219594ec22f648bc1fd42b82673c47d95bf48e9efdc39e0da9406eae1, + 0x261794a9029605c2a4aad5463047d0cb96f9da25f3b18f391047e684519a6e05, + 0x2e2bf6b18878b8335e40349e7f475e2c85cc279f99f76c0bb717d0ff7866e5e4, + 0x153ca309df24c9e664025e69edcc363ca33cc1a9a2bef69b44f607830195235, + 0x2db12f885abe64af44a3ee3f8478b92cc71fd91b096d65099be20ef87c64628c, + 0x1f2c5b4c49bf8be7e7d4d9f83e18e6ff0c70ce913f2e246e65024ce32e0b231f, + 0x9180876813742a23b9376d01579ef57c1fb39a60e825320fa0eaca8953152e3, + 0x2ddf635158aef59c7d8a6de274b34eb7a5d0088a7fc4b0f7f4ce699a18e73a5f, + 0x77f3965e42d9f1951cc9528c4a10b099bf49f4eb00e54d389af199a8a474125, + 0x23b552370636186071152d808dcf55927b95422529bbe9900d1a1244532efa2a, + 0x10b40997e86c5be3b64959e84b6ff95dc3afd77d7a8f708ba81d649075c74ebd, + 0x19e7c76c1b1e67f86073187b4f730e17bab59bf1fa5a00365be2f3541983633d, + 0x1c1b3ca31b5179b6dcb9ee3ab883ad56a355810877c058d64e345815eb365f91, + 0x75afbdbd2dab2064406909fe766072f532bccffa959708bd53863b53f1323c1, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x2d6bd5f440b052c36e1896ae00904b584661666912e14b5a76917f2a4023a975, + 0x9fadca902762e1b9b2ea83254c1422c3fdb99ab470149b91d818f74c166448b, + 0x1fc2ef7556e6b217f26c4ce8b049b857fa69b7f22ae9665d8fe061e57ccd86b8, + 0x277e0a5d5df37f2272903866a0f10472e3e4d61505b48279dd78f9e5eb18dc6d, + 0x1926393f89d142b831b5a9463ae3860bb088973ee5ee9008f0e1c7965c79be27, + 0x2917f5ea018334c0f05c07baf8c846d354e3945fbd67d5a22d058a793275a35, + 0xf1816fcf77643185cbcd7f0b141007670a027cc2891280006f4e0fb6f700113, + 0xe5eddd2746b7345563203a3a02ba3f3be5c9de6fa3d6819c1dc8c10ca61962, + 0x2fc0ffd1f2fb9e525e97afb88c5c1f16369b7864f845a922f56af6b567abb127, + 0x13a6d507cf38dd7ab84c4fe55fc37ccc00e54ff9114fb7dda131aafaf5e3d8b4, + 0x209e31eb994b1224949ef724609a754624b12e3e96aaa426519369d729d7f0d6, + 0x29b95c4e0998e017f9a6efa329e997d750c315a7091995543108bbf2ef92ea5f, + 0x273017f65d54a8a19e933a2850fe33bcdc56245fc66dd40bd16d1963065a8215, + 0x9a00a7bb4d3c41d31473d0c97194d90a94a4348aed808ae2d9b68d66ac6da34, + 0x58f37eb54a0d174ad881009a16e033b0413350052445162508f2e3f1fbd13a8, + 0x2991d56ab55bed4794d78fbe8ba2d84e0402b704c63e8bb477815b94c0b6e72b, + 0x2cf9ac97f208cbe23d5daadf7ce8eaf17b949ea0694202d6d3b4f6802c20c8f1, + 0x2b2ffc8ad52ca2742997d3fb13e13abcb7c44ffea14776362b6bd9e1c5aad18c, + 0x3f78a9a65aa3f5e30ce1ba2779ac3c5f275ab77961819dd01638a42d14fea57, + 0x28a9d40e9c58592742de7987c8acdc7fa5e622f5e87508936c5c90e5a2b0111d, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x2da971edce5951e175b20231e2caecdd672054df0a81abceac87182f9bf2ab39, + 0x4852b72a76fcfca8332cf2fca53426d44a81025b049c6fe56186da6b592b8ed, + 0x12678cd0dd103dbf00c083c3d563aaaa6e6e39e940c80c14575ea53f7da93714, + 0x63be8111dc061b7b1f827eba7cc5e10703843b6878cf85160b1d8c37f8cf20a, + 0x1292d1489e40b2b7a96a47889a8c08c9bb62ba92c2fb6ca290d3026828b90a38, + 0x131928f8c7f6b292af217e6a3798bb3c3740fe744c9754f71e964e739fa84c7c, + 0x9dd09c082e6ef61242bae94103d3413d8e280c3d824f566b6191d86c3e52e7f, + 0x13a9b7f650fbebb1c30c63886605cfe65fb13044bbf58f6b6d6d4754a8803d9a, + 0x278e646f62cd15b671eab2feb4b10833606a737023c50356dbcc6802c47e22e8, + 0x63a048acaaba44b87639a3d246f7bf5721b2dfef3bc6387eb9a7a1753bc9edc, + 0x19137d8c7c05b4380c5427ba3589505a29927ad701293341a797f8dfc6b64eaa, + 0x4605aab2cbf1c8db31f3530518b1b058e8a9fdd52380d4365e7faf99ab86431, + 0x1a662725c05570d0cb0ce0e3cb83f5a9a0d641d7f7b5f0395b3cbaf27ee8e7a1, + 0x2f00701e4012136574084fcdcfdb8a03d4370327b6778f7dbe08468a3a221d3c, + 0xeeb43bee0ce1170554f5365901cc66aad614c7db44ee7d933114e56ae13645f, + 0x514bd58df752da3a43dd75147804956f833e61091c33e8b6ebc059d1668c3b0, + 0x2e501a1cb67757564a27a930415497ad671f61899a37206e4bd4f70525dac248, + 0x16d477454abad4ab36e15a385dfeb9d8ecbbd645a459befd544456bad6de8e6d, + 0x3c052112963b411255ac9f4937ba4162dcf4dc56fdfb5f11f585a2f973d1ceb, + 0x12dbfa8b1f22ca2b3338b85b1a1cd75ff557cbb18bf220312b18a91a24d55d81, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x10818548ab73fd03d26ee40e1a406f294dfd8c805e21f8689f1001d1d3808e16, + 0x24a35e4eb8df49312d9fefc8887e52fe90b836c0cff7f7c07a848a14b01fcbe8, + 0x2e0f1e7d21d2d04fce40c67c3746330043b7168c16650a4f2c9dbc17eaeeef9e, + 0x230af3cc2c7ce9edb2179f8615ae8a62e458eb13c246f9b673170f1466dfa17, + 0x1134692f5f1f941f285cc493c3f2327065c452ad32cf715486dcebfc2d36e000, + 0xa9d37ced0d525c9d8577b969975227cbfef65e389d902e6c4aadd01322e8ae4, + 0x1db2e2b5cd0288b1d7c7faf003be7703b5c5e45ed5cd77c0f47bb8d3f2703afd, + 0x12d629c5fe0a3943083c96e3e532897bb2f63db5519122159b61723410ada8, + 0x54da7deba9f7f2f2e2180728042a935674a8446804c3cc47c9d15178e8d6666, + 0x29fc7ab2d3d544f25354a989848126e23d60efc67d30c1d7e6dec4f01c8bd52a, + 0x14dc9c3565c4d246607923146b654a06c3a6f33ff2e7b285cc339e7e045b10f3, + 0x257f594d047a720f1ef7ae56ee5cebea62ac2239715a55b1ffcb394af09ac0b0, + 0x1202ed4a356316e5710f9f1a5727b083c1ab217050e8bbe7d95ff5f826c77669, + 0x30fe2beb49b890033bbdd087b9e263add126966570888915b43101888b8b962, + 0x5ca2c86c6b813c5ab7ecc7fa53fbafef3678c328accc49fa70b5f71a1e368dd, + 0x22b38b500c9b360fc2b4ac16b0f8fe71e8e30a9a5fffb2275f40112e01c59f71, + 0x1a85a376a332e4ed41c5b9e85dbc2806bb3c3c6f38c7f251fba31eb492d2811, + 0x30b8dd372a1546b35d430c7592b24a762c0e748b857190aa47ba294da43f9bc, + 0x58804d2aa2f1e9d511cb4bf4459d8747a00af3f8cefa52c3af281d7b71a468e, + 0x2be9874c17f4811897b082ce47809991d57d081de49d4f9259bac0c2bbb69e4d, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x10127c52ea1f6d2ae8cb3a7af70916ab29fd85fbde5d15596076ce30524ade37, + 0x2d887f38f4f5c278b142bb09fa17210717bc38dedc721327c34b5af25fa4975f, + 0x18413dd99e547cd6112c9b3890a4a927660153967a2fa3cc78281aa3743b7ca, + 0x2c8375bf705e811aea8583b90f6004ca186f06ba9005d92cf3ce7317b4fbeea4, + 0x26672152eee139f933ea3a888e343a211776aa698206a6b970cde470ad510e72, + 0x179472871d26f2e278673df45769f49f3943f98b5bc9e76bc7bd639f5cb94a3f, + 0x1ed0f4a870226c8afae5b2719e3aa60c8a4f3f491290ecb6a6fa8ed8fec32f0f, + 0x1e8ab7c5158984fd536a1fcba52e4a9a99d2406c681d0d54c194a1378aae7bf7, + 0x6e50409b0cc763889daeec7624be727dce09632fe17945329fbbbba7336b56c, + 0x5ef96066a1106782bd7942af6ee88ae6c642890863ded5c908a70f0e97188f7, + 0x275a393c79c2e975e32088fa28e808ef7b3a28ed55d7908b3304c6270b68474, + 0x232f41ac9fb55828ad89fb910fd53a80463ad16ad787e2869f315a59ce7766d6, + 0x275bb8e491e9023da98884c13b73892f2b1eb2e77dd1dda8b5095bf5c9adc9b, + 0x761b386807668eee2b21b55ffc77eac91c6081c52308c6dbafc6c07028b4e3a, + 0x493e9a3b80d179228d2a81e903a9fe8d65ad2dd99a733e8ffe044ec71a668f4, + 0x304413ebc59f08c82a9e2356ea09341910ff74938709f03599a4f0524ec719a8, + 0x2d1e1f38f6702b847019dd697437b90bbb302f642fe0d71df7faced0a3dad14c, + 0x16ac849076bc69c52529d4baa1c20d39991d1d1bdc92c8e0ff1c5bcad374f25b, + 0x1a85ec6762d6cbe146dc87cd11c2b2daa1ea599f611965a59bcfc3355a684318, + 0x196530945d3d7b35c950174d0b08a4e423a8ea2bcb1d455f4b5e042d66cf2ca0, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x7052091360f5985cd717c188ee4aa7b12542f1ff3dad0a1996b00fde6e3652b, + 0x291b5860cdbc43b0f0e3d258bdf8f8b58c839a56779bab5f918e042293b9868e, + 0xd74d3b457f71267a00679f5b34b57cd193626e69dff827153cb0a07245f97a5, + 0x6063d52c65712f8ea7af7b3405c330f3a0e1e4a1652cc21d3dc5e0f60cdbf76, + 0x66b0a3103e081f9125c429640d2db5993037180131ed22bdd413d33d6a830e9, + 0x1a1ec3ab8c7e73bee5257c0669cb9e5958eed3d51d6b8bb1a43f2683e2082a4, + 0x25bcddfb7d8a0a191d30fd1325f71e08124ad4b099485d80f41ac677e0094152, + 0x10436855078393e34186a26936181b385e1f4babccecf88b189a51b052d6931b, + 0x13fd2892c02f51e42d36d9d6986a773f1cf644bcbcca74318c486e1b1887a8d0, + 0x2c28f6b8646fe071a4d6eeaabc22f4398d09adc041da503fa5e13d55f280424a, + 0x8283969c57b0158cd5bf0dd9ee3bf1d6008dcc45c1ef3288de7d1be2423832f, + 0x1130ad17e3000bea708aa2ea9293faa1bb33c9fa734c13ad351f0409c649ca65, + 0x741c5c7d36f11cdc84ec58d9e6d7428f8cf2d15110ec45d7218f7991be58206, + 0x1f449a6d7afec87c3391d5f306fcaa5ba7498feae544c6048dbdc847c7dad3ce, + 0x13c20e3e2bc12fc0d3ef6ba869311fbc5b6a3a4d779dafed35a96098e97f2167, + 0x1fdabc23fa86f1b12e840c491a7d7bc267bdccf6eb113729e41f09eb416c0d90, + 0xb18abdac519be96bae35d898d40a26e9d9e0561f6934be88da9a5c24e498652, + 0x28b6810fffb6ed56cb0ab3df49bbeee7cf4f978461189f205aec741cbe843202, + 0xbec82d9037048c805a293a708427fbfb95dea117a6dcd1e6f34f13fc9e088f8, + 0x2f63a41ae9a12da286de92e8e7d65162eef3e275eeda01b2f1dde4a6b69826de, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x265c4fc58d97632fcf19a923a0667b9e9b28b7add612d7a71061bc93a8db0d34, + 0x12885bff48b6298f10b722b699ea5cfefd234005c83ff78a16da563a95758d70, + 0x151d53cc6bbeda594c839f198afdf5419d1c87ca6c45e23b4b5df9ce6590fa24, + 0x14d55af045f1dfd8f49d4f256e081a6b3ed093f01a72e9e7fa95964d274b990e, + 0xd2eabd86f01fa64ba065b8ed26f82ce2fc47e9e016448e3d727a7c66a7abdd6, + 0x28b3060c2dcb657bf0ad4e015552f6c057d08d94e6a7aa8f65ccaf576ae19c9, + 0x29999685e5c96a1b905f85dc5bd585d018468c52eaf77a65a6a7f7252d015006, + 0x2cc36566d5372f76a5bdd4fad63e709b1c9a1fd8c638d508d11386a963949d17, + 0xf45e1a65d563313981d7fbd8646e8b6c0a513e921fa4d91d06d1def1ac535fb, + 0xbe5a47fdf5f5ebb05760335c19650934d3c9fd5bf6a947d230ec07b04b63361, + 0x8e06c579f1e6e0130c801b93e325ccba4488227d52279b600cea03c02f55841, + 0x2f50f7000c45cd941aedbfe73b0022a95ef948e1672e5e4ae7f818c5af7a5da0, + 0x10e83f3ecde3d5babb785328a70cad7f1266ada3811812961cdd561855792100, + 0x2391b1a42d1ad62765e51ebd3fcaec9feda26eb1a8e4bc397b4a7692e5036354, + 0x5dd281f4536f0e512cf632d8fc3bc3b198fcd503172259acd0a43f6f3b2ca8d, + 0x1805c870c9eaa246e93fe07b6de600b300eb1d2cc768abb8a325d1b35a73a383, + 0x735b3cb5309a63477b17662d70e873a588e82e15bc083fca92f3b1272de5930, + 0x15a7b08ffbfad70da2050e2c609621cc2817e9fab3f8e06f0f7d37599f374039, + 0x1c7725a85e6a7f0ebaac87408b38e5e6ecfb4de63ab1819008926a7d1ed9162b, + 0x2371b576f67ab802e647290dc0ca0728bf11fa282a106e52567e430aa5cd6df9, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x2d76222e6f0ba0ffd8667c9cfb2a8bf2ffccc92e74cde3aaf9d515f6770be25b, + 0x21a9df030fc2c38623949ccc0e27da5c02225e2e4cb94258767e67046b1c9ad7, + 0xc994ae387461d0c7104186c1f4e140f224a0c8590490a5d28bf872596eae2d, + 0x27c61ff34f721d9b86250fdf7a433505b8fa72ebe9a28c0f8f9a5a86e25bd642, + 0x115aa7aae6b9596eca97b6726a631722dae0a8f630a3368604dbcaa9811a851f, + 0x18ce760e701aecf766400d3c8303e28aa7937c3c89c3109a5f0b8f9209729faa, + 0x2e8d27465c96902538919868872618261b07e2771f087e9686a07b02744a0149, + 0x100661eb6f7639b3cddca06469b717369b84248f18a9a0250198228d8580de14, + 0xbba9475dd449868c67d4d7394ed448eaafd0384f417ab5ec3582db8962e423, + 0x2ec4cea2ec233f82b5c3afc658cf0f1d5056dfe434c209ee3d3ae5101c5d38a9, + 0x15a99df7e6b5ef0315db045932d7a24de603b0b6897f567626fd1dd9f47c8553, + 0x1be6d866794b25f0ad77226028183b38ba4faffe5a4375d4b2560306acde3c5f, + 0x27257e94b2e95e861b7120ed9762d8c4c94080b7612d9b58d00691fbeef97374, + 0x3af51f300cd6fcb4ea567e6c8513d81dad94aa1d0c125a8408cdf1ed9f103e2, + 0x193b1cb5ebd78dbe0428c993ddefd3df2414c558078f757b3f8035b047090913, + 0xdc86ca1c3c10a634dba579115794017366d06315b67d84381f4e3d530800e52, + 0x1235404239a1bd35d8a5d7e41fbf7979bc1132e1316236fce4704951990487e4, + 0x17e965fa385145f2d79704557938893089dd6a9411e1a4054614bba0f1453b45, + 0x17cf6ef863dfc27d9e23767c80219a62279a7c1df9553c8c3fba34d8d80706f7, + 0x568c86457d66bf962613ccfcf294e2bdfdc444406b20a6563eb382164f6b38, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x2f5139526746698879515dc547fc4a18a47bb7b1069cf42d88c1699f37bf70e2, + 0xe9ec645e63a3358158ca6bc99b354570c61b50ae0b66a9b2cdbd5b7bd2528f6, + 0x110bf55f969e6beb814a08bedfcc429368f8a65317d9df987fdf690464e82792, + 0x50a2f40f3337b14663877a5c5c66bbad6bd40810303fc9077996384fb942223, + 0x9fa261cf5150dae90270799121e56745c2e3aff6c6edeb0d9f37ad73f2e92b7, + 0x18db0fda1f48a43c15c1d72d7a8e8ec2042ceedc57f08cde78484f8a0175afe0, + 0x12cd152e6a482b22678e14feb1d2b463560eb39b0a27bd82dc9cc6791c70e234, + 0x208785a8e7d01f556b883d201a43071c922863abb6b5b9d62b06cdbe1ca198cb, + 0xa2f6f2777331ff62db3918731dfb0f8981e3f15b0715a44a3e076abf1e29710, + 0x2e40f60a955d8717e55b97ff156a8bd9c6f2e806d042d0213ceef2356fc97f74, + 0x15b824ec28269dd4d8e6a563169d415cad68d9c1c7aee1aa279b76abed3cee6f, + 0xcb83c1917e41f61a32024d11b6d8f43c8a9e9547568b817ea72b3ac253edbe4, + 0x131c6c3ae3535f15bb791ba5c1f52051635c44d8e13e7c28d60812a763cf62fa, + 0x274de569e20256784aca3a5ddca5222476b2c06e6976e4b5332578eb744ba058, + 0x4cd6d293061e45cdf3f30796a24e66007a0aeff1b9c7cf7cc869dda589a8d14, + 0x2045eab29038ee2c289a564f10fa0ba6377679514a389b836dd6998b4799a07d, + 0x20f10e37bae5a8193adb95b06981b0f7623baf32b69b61a11696e7a8795494bb, + 0x1f55e36adac5b9b352d7cbe55651b680c4b342c335bd8562fb45aadd3e83e619, + 0x29602ba7068d0b754d8a59a67b5cb83de5a6d86092f8ba5da32960ac4237e424, + 0x16707fcaee953e548b9f04c22b714507ad45c63e242d1f386fe813701e59d18c, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x26443bd83569c93383cc8cd7a2e05eb2bcead4621e70cc188f6405c89e778a7a, + 0x5a35d0e22be0f9bd2528eb55583ced870d362ee72476e9706625e49bc556498, + 0x1021e56558839fc8b5fb2205d2c799e3b31e7657cfa3106b0651ca9f6e9def53, + 0xa4aa165b7771c0810e9caf04fdc8d6b4fa87e2b88cc08aba3c8ec908739be27, + 0xb711cd6dc591dcf07f400fabe5cc8b78ec01724bb2b9e62d11456b6de351974, + 0xdb4f89a973ddb25f113a6df8e80aa798cd2107439ca4c3a7cb4787f23148c72, + 0x24580560fa1df7a3a4921875187ef0cad6db94f0bf7348fb7aeb4c9e31bd8dd4, + 0x1de8c3e482d87d19a3348c786983ba4bae3ab00870d28ae3dc18bdbc0c8561e, + 0x35ec9a49296b184f2225b3d68de6d1d5a623236576d838e557b150893bea66c, + 0x1f7f2e438c0695e2057f62a661aa8e85793ec168e2aac1ce06ef7ddbdad1e115, + 0xdba6ba79098331b4dc93515778b2497c38c3ddb2b20e6dc9df6ed5ad85c32b5, + 0x22fa5dcd5070a8f46ad637e3cbf69c256afc6ab58dc0b0d98ff15740abee7e59, + 0x26a5fd93dff7f5eb49942b51b03b98e9cd2ab261d56db7516afb897ac2706ef9, + 0x2216a1a787d05bbccce19eff5d852b92e317606d55c6b5b3fb02afd41e69721e, + 0x2228040c2cc6457ecb0acf3ef4699eab804d0251bc75025ea928d16d15065953, + 0x1c20e02da095541abc6481a5c1594ceaa688ec99b43ffce38b098ba817af0477, + 0x106f19142419a86a234f4c8b94c9ad6f3b6f4dab9e47ff3c9d6669bed5ff3795, + 0x104c7b997f5f83d8da35fab234f56c49716df4b0a7318bdae91786b0a007f857, + 0x272b659e78a33f1541fcf58f4cb3e64e806f3cd0e2438dce20a9ab7d416a3080, + 0x1249186ebedf49fac85f76d0e10ade878518daa306d2b586e295868576a13ea9, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x1490ad8e9d330e2beaad58cbcbabda75796a6e00166bd7b9de35c84dca1fb7e4, + 0x29cedacd10b839b576f81408dba8ff1cd699b9b0b11e16e5267c217e574a559f, + 0xd55f5e0d31ed8c032f1b31ebc07fcb088feba88583dd5815f85431f3829cdbd, + 0x22c2de78b8f8caee3778d4825710b080807cd14bfb6080488f99e303dea9c4e3, + 0x256bf262a0b931d87affd8233c61534d9f5f33a3ffe59460ca8af7d0d3ba946f, + 0x259e4f6cfcc7a4b6d2246333479df052ee0477b9ee8faa7f47da45d1495d909, + 0x235e716b22b67894aef5bcad49467c7c9e8fb689bfc03f058176c9b2f2cfa6de, + 0x91246bee1d5f4063a2ab453e658c50c994dae678cfa15b73b14b0f48408e18d, + 0x1594541dd396d5948b6b0172b31330333f099973d8a3a1a9d299bba6f45d1bde, + 0x24cc95bb62ee85ac17d1e8c36c15cc50c8c66c7cb12e08f2a8b865653cca586b, + 0x2dba892c4f9bc80cdfa40ee9aa9b1c37f0d4ea781c3fbe5ec7ebda39e2272dba, + 0x2f3f255428b447ee2819975595dddeef9fa3cbd71b62f34aee8594771d350a27, + 0x2f4b81914b52b75c46b6ebcb52605d073fb458f8b1cbf68fb9db225e4919b8b8, + 0x1e35a658cb61031459363447cde6165233b2bb5107c6dbb4c2d50c459940f2a5, + 0x21938bd170ef0b687752b8714b803b82a4358bf72b74265a4623d5594de772ef, + 0xd54bc01b18dcf2553834c7a2330ac8163083186d738637650ae7bbb67e69c01, + 0x166ef423ea8ce954adec38214c8412bcb52dfc2af3ad407cc94edf187e4d825a, + 0x304b27a7490ba0e5c20d3b273abc31ab57d4c9c39f2928b81ace40b26ae3454, + 0x1873ef347ff8231585a15dd61cb7140998b4a07d1ffe2045dd368594edc0f171, + 0x67a470e0c4795e245e75c97cb69745c9d9bab71c1b8836aeff01be895f3634, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x14189f783f0179d6a700e43b6f3412af189203e47b5f6bffaccbb0faa6cf850d, + 0x121bc25b16a45c18843035e84ea0f03e550b85c5d5d865c391608764d8f9da3e, + 0x2e7705b125455c88939ebff9c94d94b32cd19988de9033421ad2497299e1c07e, + 0x4de92a097cbcd0eda877c95e7d7c623205a82e9264d48093144c02affe35f46, + 0x56267827dfdd2c8e13c31ffee09c665605e6d0f76ecfce63a1a3e0ff9ba083a, + 0x214e0300f805ffc715666db69a32b5ded6c1a5e46ce21278ef56df4cf75d6d7c, + 0xa3e3961aed3e8da84d9b2fe01de35febafd742ba83c0cfcd82c48142cf1c42a, + 0x2ec69abd5acb3679c257c3814520f5a2d4e15a9e1eda480e25744cc31074d12c, + 0x1c68a794990b7866dd921b417960123999f52f198f279489f00d5db71205a6ad, + 0x11838fb23d5f3322bbecdb09dd7f8b581465c87a0f6db0216e23c9231aaa5584, + 0x5088200a18b6f27d2d094a42fec2247f9b19a17a2f85f9827bf372ff495e118, + 0x20a562ef82e57831ee85dfb0b18b716e63de36bce2d28fe067a1ce10e365a8c7, + 0xda77e103a18b438ac860d49030a95756dc69c0118e067bba3732b3a29d8fa9a, + 0x2e71181976c28449e32e07d66706ca4fd1b6cab8da61b18e712f5816bf7e94d4, + 0x1321a6faa0815eb83709c5f4bccf3deb91d918ee15267afc6b029d923bff2b5e, + 0x27c3ea888b30068677247481893caf50ad99ce732dd4549e2f651c3e266187fc, + 0x47172c54759f37b2b4d64ac2fb6ae6c6428edb065d5b7f185394515114dea81, + 0x19fa875a5e821b2fa6c2ffe8acfa446ddd4d6f253338376fa289b20e83de1915, + 0x2db07878d810de30ca07c22cee53280d160186e6e27c4c3a0bf895fe2c3349e0, + 0xa8c2b4b98315d9c006a0a54992474ac89e5935a1346976400de47d115ca4389, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0xc098e14e0b8ea8d519e73df8da0ef38276518e4e103d8a6101993f21ade6828, + 0x26a7ab22e3d4701a4d54216b73e906da3d66859bee38d02be8f120e000a5b4f6, + 0x211a846a0b674674aa04b33558a7d8050af880d13e6762872d4560e3f7f55b73, + 0x13595dd19c159220e93fc8bf8645c5b9af252edacd343c89bae98a3a37314c7d, + 0xd839375c08776325c25610cd2e5ecf8a969154c0979ac7f14f1e58a0e7e0441, + 0x136b3190bc5d892cbe1762bceceb68b500861a7f6b590efd62be25ad1c73b2b, + 0x8765d20fa4770fa4979632a6e5b500975b173eca79b0300856e7130f6657930, + 0x3b2d35ea0ad26b1535413a38f690954f224a6f78896baa496b8e8502bf34331, + 0x290489818e00b9c0ea5d2fce994ca9256bcd9775e9ca5bfdac81972b46a4b82, + 0x24b7c1b84ec626f59c7952c4098123e690f221504c68006ae1e5815eae2e233a, + 0x2d256f845196bec5b35c52a663e4cf84dd433348157a3c877a9ad08d41da5d65, + 0xd1150f01d5d7e30b0fb3a6362c631f4664f6c7f6291e6b889544ff778131376, + 0x79717001ed6744cae07a2e491a2338a79cb8c95755392c98459c1284c70ebb5, + 0x2cd2058b448f75bc368a7cdd20f0c67f74206366bd8882235da404d702d2be65, + 0x1b7a766baff43fa8a52e26085427a1beeddd80b70edd992547818c62bd2342ef, + 0xd10757ea13e688a4d99cbfe646f4268cb2498d2f2fc8bc352694aaf44f71855, + 0x1fe27d15068f85f384f63af983d10d1ccb94147d8560d456171c3d741d427f22, + 0x2ec657144f084e48f4eeb405543606e23fe2c1b581fbf942fc3da65d8a6228ea, + 0xb71ff8252f9e1c1d3773854103c48fa3857563e8b2de93b78a54d1c929464dd, + 0x182b99aac23bebb445feb24cf5f4920497d1c735985248f317c36ee35c343115, + 0x26dba58ade8cda188f49e52fce7167b8f219dbd924d7786b0f98fb799fefa2e, + 0x1332f4f2281120300496b962963720e68a075590aa803c5c1cd8d3d582bb75eb, + 0x24c4647a7db1c869bda030a3f816ea27e8dc93909416ff20eaf39ba54576b452, + 0xf5df55c2bfac795888d3aae8751afcbc3f2c5bc2b2dec28148a252de9729426, + 0x23a4ad4858fd3c269b1df5858ee89dd659dee776a895dd5acffb17c632b66592, + 0x526ed32d567e190ff5628e6b64d762447caee284b84fa15adc9384a24ac178e, + 0x144d89dd1b606b27d51d742d02deda341a5f96e7ae5ee380263f7a23020cfd5f, + 0x8086e639a5f96c89faaf0ec803513e9c68647bc9778fc779d144991bab029b4, + 0x24a2d9babdafa3f42f87ab39e269c2edd458cc87e9e3c66dbe8b0cce81db9fb5, + 0x1fd030e5d50ca388859b18fa5617527cf0064d91bec5c81dda5ad3b611a28fde, + 0x21e5cd68cdb35c3027433f525cc2fd4f460132cbe83505823bbcb12b11ebad88, + 0x9813c803ff84a3694eedaf4b1c2172615275dc18ca654c799a70440946ccf0, + 0x202973f7fba5bd21ed58bfe7156d7b29010d41090f63f1bb290c1d5da1ad60, + 0x12305eadf64dac24a7913a62d95aefd45f48355576c671e56fde9cc7c8344ffd, + 0x25c783ad66d6a1fc6c84770bd637f6207097dffb0378d7e0395f8c0b86b505f9, + 0x222deb606f13cf28c73a67216d88b16f5958d5d292ba10ef3bc2c10f5a0b613f, + 0x1614d025472771fd870a9e9d422b3571c5494e7d679824d8fe1212177d5fa2ec, + 0x1358bdd6b7a51b1f5b5d094dbd8ee086ccdcfb9c27faad0806e8ef718d0e2b1, + 0x1c2007eba4d1629846bb69404acc84565de5d24620f75cfcd9f11feeeb3f3748, + 0x22f49d7244077e41f409c0b353afd1696e3aa15ffdb4a0bdb883ffe7a1a87217, + 0x1951523a4270c54403dfe3218fd3d4ccefa43114f1b19fb2c2821a4374718b9d + ] ) } + // noir-fmt:ignore -pub fn x5_12_config() -> PoseidonConfig<816, 144> { +pub fn x5_12_config() -> PoseidonConfig<12, 156, 1380> { config( 12, 8, 60, alpha(), - [9531912189466476916568861603725087174113765795321185751191491139118805372511,19478790955972117697384547134063865214385101762783978876290106323878777065880,1060742683967616999946346623778902980408439861665078741681079083728753884980,903807389911706192945621790390189278582333785459643079682311503388875632444,12234856961774107626670146718644057065701939000315796085771709903680607765980,7144222788160875459149511026237781941826966456792731247241581603475033054157,20698157631699630824067955298548696950174021158305550220448729049898476869972,2568732479597962725718653653192533652726437462680484211279054254158600287844,15284734447838568972934847154537240941736455475374750484902463133334986327455,11481338136657097309136761414013103615752281785975103234128467186355727286020,10612154017018914947135783711517517074090274235061056248497547614631916723906,3055604116750189009829046286798613018321687824856056202070161812694453230232,15724356578668121294244613323219019733691132614053416867337612541744349705307,14233178571890186223833398248040498471414046807101676904418988635462870136058,15569884202072601673299042953201725479510195453493088500579693825511613908294,2457655896277475748047646151777860503559023325500398204274047419681119270433,18721554772384051287322049295337473476448259922773695010270945658995924622719,14475562052679553333706265906284533085428658760049287899372861273825967798347,15603408794229592986464670990674550905587371918421438132217255356917740776753,16291020844798157226549685169153735235751877205762229274467406522127105739380,1562912009705461355815110217333069399929165391790667011738168557818438924927,11269000847557922376283381139665491298931690005135341373215203639253515983197,7952882227157644034022652849613475711023423321505769231128945987664804912273,8477623463686474590677390307150152439632807913002306242882220286965657503044,16240923770208341542260111895431885216031871921759466016566105290964433552216,3342849074804996662671621919352322750206307938435597035721084610748972602222,17931702006999673813463835283048793204134166638699010505988519059393386641671,20775104403560355444897460398679593487716638645215251442678183285176599574637,5119120619161234799144523865081220455479981813019860080498855561756227023701,14966757356872002341966020507506536570537078023526508344654458912397759281515,4186575643717625662604368224196455420957673000117335440321019421096129003102,19732993039041335023904970539797704576579318087957672270477209415993860238993,12070985110749915673363345667648496564808814323429491368289711883810537898097,11426729904237322553170474047093755836047277723343283963043397762276736900525,3316549680511845723553051012477874001156246623643069548980284069093192393275,8181145696278572952623145148622555644838658979012817598939443116317742063663,5285104126733708771192424010645473580676014333664755598112717745696037070786,20879460004955312065246827250994614761073401947673232470833608851757692374701,9225423353187148331993357472363957540141522302215231248106234750413173980751,15882456781720382955442431000301149138213435084361689595107598612703885378636,740238561845104412391944006282242126007894120431256540495139829806405656182,180417058725083825889148913143008776006125349068680455724690397852076567353,14174293519955274733372251014027762210778831326913295280840585355009025244339,8589132560109336742397080501737400189892522466285798728529721670916644735009,18608579889305084432265993644262889161778187018060113992221234915464772250895,13255562856310211555141734542720764165551582487712004861593515585281326120780,20040426996876166323258012360708147873405329072458300306708975663127708222443,3623806905318973096995680510049954452579199046783492207512283522220396562822,11410684734000900004860241940266501902598169149094443542781697771532926351566,17135477854627682759515989387435395911766329083966273406049980901836411403416,13593359321772915930716800157828568438953037754245269488538472861500074218774,8851367853862849158416384345517193602505667487160151588020171989122435915705,8486258745426030087193511835657366486234171438833758681014633470174920075557,14747490337504821136965789527401826047053378817043597026988257648138435336926,5328238162919446506214025777104049372124957345257645933410622558507658284713,11965770224330607826076459132274399741504292999992921785782448737931531131492,6397958737008655664539418210486834384969900796875514632281024739857683313517,19298424785220686762403958616740155152857782164943661260316780711617884649980,20019455348785333548837795973650078300677031008828877476192963238765813699604,498876295068369039941891884133922605442597373275805987652958540603151502762,15673948845182330978914854481229214769118100412263880346214990198207268219918,15636974430517603355685549955558840639961287398389993551242671229593610041279,21849352155479133596816471850644588093828045783688624472176874329078465894038,3710541309080539224803365587698192640065043989988405183436118622332060826084,7400908409303343897763329119747918294591391269311551693625176644493777241247,19095563460120996369257805492605849292942048841569757166438202426234116219528,7450358777752652255259382961368280387692895530851667830759412613948095056314,12616362847029801456780520061399223912377922714639139395311897747307063246381,2962396389753936883856793158008198181187288822144777145656778061306062270271,20597083262311447290143345580862519411179427096464102505623468932397345199901,5990063075931255958499395880323163728626495197217954905778613462408195572191,9361904499252311797420064091418454593805808979929563324171298064587942042557,15745983602860127054098117502599813732367772584805282887983680577406906842509,12155753549127535852899642287036910835293646693799050941038502705904075221647,17784550108352452858546269360461997898333463961938370347697582728197589684086,2486952113321483072183664368099776164387734014933893158352223909214365526945,4903545427310923282188595180893897246459463256398425200307382903876773643166,4976787025628832138140129068285715692634473783721132777844066348049003658995,17903848557396420363857191109854268785343114927997153696759251220232810232708,4112316506554809604392743006504568448930584669405889138267627731770713169451,12564921445775298869601661793895717261354052767541351424764087809438338341443,21338339987232841174606235608205622863643553456415651377028015070388899605425,15088854240518267391884187352051335059960134381458770666979402557846290860043,6521785672326022155410896706891346109402758862672817874198014517122929534795,17713017733654015756718215699238009705617793897969373435335184169505068045344,17520588725173134454654213370481559878188684108641520017594192886986887410727,20370353420481573040209617326772538556774101029132132235011046989968543481853,1112630910445876674622022594317693604373148988518983600314476620278857862788,13947879294001229379895373879944689637841444307211953543137372048528771620266,19992733820130513366333925886960985070219788486605690639975080516132656879852,20463686239191469605722985205294798392601180601616445763439546206772797296794,2399836272490730222789561326076432853292090595513010294231690669763899804691,1034212741378241815550350670737161423052400169194393567236687087583799668630,11440929010875860174917763753574001672473682534215635955505970318252592490865,14189960926817818424784917441574757301766760887770685069486059337906765736963,12315331213328078044898516229848174792421271854142211159524426707506661472774,19715153274097520886062594899069030152815615989925596868748132112713500919606,5263645674775021082527379900656937946372398687742691252725061831191269814647,17116922705336407879424247270343125398621621836566941362988393678055183546962,12965075932786028962944831711285166109972351055088920502397645336995474504411,12016029264981766758974787101200878559176627961323691741528038308088561486007,5729800253105809140207889626731612970039128485797787837679696331851897001188,12918441439057112476878371772096947366502166083699226943980929800631997660377,12122801182972566919042281354391366131886072331873675435499031824985283406080,2001381046477673840829875588313268487326797326656965151814712798463828403972,19581992323872865003173357646589705276192927057599589666190396129558198469295,12032241883699803399815479981073900218390137511663730251199663857029681112519,4486673663248066106745570699596745555749344770988892121755846988206654958447,5880818668316784480273321916242537222449799562687899946001667784663774949284,2395463900919111658295342588362130947823185484448880299307422522723986076206,12950983061674357110606111858229311283119838941890561558124046774295323335099,2237414129351562764861995011211505967387529547007150899242139479636758409691,11297958435815311160313316754342324739290776717531068730041530178142477489469,5317255860197359110199894572100590405469568868980740298600361799734023336258,20883201721979021051679862781044901365707874143019054645125857460321063446040,8182241566037373547703812967620649098015366536333588850170211599244447070966,9597640642388296782056528355964209027337895123387144965957122193392739912194,17036534143228977344737945793420370811715806669058615712195620745133828881359,11612810822316258618979762480131695561483235138506664012253801075650313633340,8933421864748994361777741056369848147887887317449099739627452478628920292098,14444070019150868677613599250973948199109012042816076287250439535772792130077,1409252976182963241946410463334709182528602279352691338387472032099813179046,11952347912832393217697966069578145988700552783923451999893230696985016550129,20459418532142116378042115609733769114184932636063412849272885250416180990630,3551971311295052916014184741437675944777358383038912487497306982998424802991,17338671457268891559841041605089015291458737421392337141908035764681448452092,20968343054904260510606682646995696017767749421435540168583945905747214877394,21712394213185895207403184789091961285240129068046002376558625468598692072071,7634967402785998572909457534910529497063727153788753124164657866643377741907,19849927917300065970782875128524194424999119369431340457180683372405088384137,15012913963479022629048645986836271605475934011232886489828149973693122241964,9429717687014890707005420840742234597648724772846627377968206537995029096421,2567188197501474210757971384017028034832891166328657542206945684532913152990,8254698320328328672738727190211578815599233720695888584349629846354725718490,17284254811803472776585305793072871837922263190673228934354908231725144505079,14935255735939697495362584034949670161356891451287847368207930876840786524288,15799240079228766996307573606262831147697506141321254927976890662889015144612,6455095726770008351501849656650198371508317633852287113372325351871125339180,13561632639572229898860364095655372109051739280251390860766414218384828962360,3063643914261015068338656198636076696013594289440915753234546912875968584726,523490668760084285231907250925228161954264885492417167368043075448446094968,8963235882996992436242593243282162189452480942366129170093695041925502792493,2822355405499444122504244694377602321152414880107322020961544617958820110728,9900962978347352867015759419877923426715239847996616012083851486863818525240,8479746689369630997477042503538860863372007378750903762662394891426272525808,16389683851395581748247134197181679668454182692374139436248933773102047859911,53288238128999697340898456182379718764153689572603829218558226366719788005,19367926616347613140684682635393090785537600078242140764999539757098535716540,15865351283225378120524944291419029041302905726785499676495076019805256191362,3306541431760940351422576606963790342897050957331449111434563465335195596604,15691440019263506851813897307599578949230726834044329611626721124859202292981,5471927110529676053035425189646230106778686168719884591627642899285735629074,21754232156244379849332999145646221923063494235010275675811923863906511018870,12691978963824033486319665437354495198660382717956695927101804737187302726210,18287930615191907073854709805749959615454583394829992950666668999967617218809,19651897318700114806760486800306423305046969021116395207725042165875775288623,14108212236437313184992367338426565912378398742941435667080068116020546770682,16999325425454851471000400176480399381440753089661500361295692310681628123507,3115621817064730307934070024882122808835435845590131246374645701268123516395,7664237802103239138782764325077413451892718354904226049706189059570344004578,10628974555344045044380058670185713528581140293158876652923633181919907860739,14113596208322488293154755998142305972509624369829087071590744312673264784912,17464956897498328434098241327703906248729109105264442832066471889452262140737,3306236514619936703817193243747225028048646569484446722868278187142340885606,1623642646505969781806818562148062924427827461950798461560800231691312453957,20812904557023426950178015281581063697341146335603865156046444216576536158479,19408105996475064309045111496637572365855316086113347445820645560307476671120,19899769975875815048945884537401834080401837433178820364413791122141366658704,19592039825831921790276944621603771771915464940035526138844575559711905257984,16653297576149039984587104062729832787430849403617977005988111857683169262526,9600749907793807254814822662348056400280037933879058284466549496283747987313,4481371968429561669477332540784950497549507725682080986909471734800926537000,901971752662861027246344512729868409066847439697888994727629776003122477075,13205641411901359105414809635566186722302364256582520884685762468367549487609,8771921370123544696277176259984315154171500395079224159374189372693912295384,5174975161282723002634664972730414710732925114695376584668768207090019053678,19270513804464040100949263044402755496385234769453916866026752765439740596759,21159175882383323828715178134104379154154907971797847682741774730382256211237,12713085776674794152643870369276859988930155976989577699924346924648017649124,14416880591724909781230787197474161383703110620356522560207527702042764430665,5782775977590089860582593877799736603230821040322957359619681360364621989990,4476458740184410293724437897879594951652562625859170065641235900450054752275,2721806229175990973363729919729809746838498228946916302499795336059265315654,20919749045138523262313225773151110447007311142131682485436367417448435698000,8313744079461516868330165973726769605125778482558912200259619501953066297351,4735608165219550054732197605756732753518722979705458514715803339137012677807,7197734920840596436781335789800800949073525267054200029424794448358957228282,21023118349982419692339995216673708826739468972915634059252379895041124776477,7361684304536881013610906796097454038829033466585052789468836114776912784525,20982662530655024673207268539471241193218964077396502472563124088553292010609,16223276590978113205386347640415975693035764887550533934078089596214147119142,16855050273631391834996719887442993598537594692357829619807594900987141342279,9447886870473301829371932239272857617552029212858469830955734178259213680272,20832064076469714454949991237859093636177561963691091143340405814107144265638,8639667923938888615556970427023258757087537766667818930469506422086574042603,17264766416417856804513499340974616744303058001571461329697855072803549043449,17850880215521300838724196369662075783108857625488733013926883881070746974079,2555423581835096020752363625782761123603321345233444467023623837801470232396,287393475373800420687070196983041262901299109116957212897422666775745916878,8502409129845334137896426506380979458386453989629214624807418474240644490658,17018903560361810748608552810594034468026623560117430817297647108682661433399,3048293276213593502083356886493678223968770697826563060833194090969377703128,21410637907835525984647506144589609474305790431496436733818309371828966617019,11884766464429332615888730245830253775469158860120272524933094891366345545984,1404751133279371734382153067811682787285007352946819870030827863597870240066,18533103709771766357713924189614422821669511650512088621974348524596673777463,2245746843374377731985282335022648129668387693745835052018700591124673151499,7164798246992914028921284523335117888604816694373355756451086598952914018661,6547792475751145534229851742995938089417776974069115284886265458921995253635,20902177810420148842648372790754609922473216539157084210657172695295335305053,6725829188763173291829388608607411327488468861041838394166490103857184986505,14877246205681405878429147764831613204208078224683457409980647858475648710211,12044111044800943869325640584272709159106488829628178962818078442934011738582,19605231155471418918091518582371485038913937726379108169052428896528644150703,7703294969707260451899023373169584023358521879520637237253564638222384534453,8646812596577526500078198446696820195057640949335282980927180585777038852172,21737243780210633072252501142816485256289884504027720271756348514717163502438,11106629219138713431737722416937344915839184447234152498273695046605412717853,10776231601191535915748483208366958548059216019309096513250460388757814780540,9570793764533387448268417521329594330897759769553789809193103230402046525968,17679865315281322154038759337512810633677645281028940369384987651076506608513,20575490035801628850469464797342943234291317406364190353186174477643080398289,1245923103633930975302215942611213577964303545113844948930979175833556792302,14007490679559289327503467618330290757962057021886611213555145469946035182448,11028796735236022300483437389742268989348582903251651368706557599156682851942,1556450270937619861275756908441730263281625715497049030992434005539032147429,7378353234583563315614681819214067843031828330274954124783678863055213281539,14666996645204144598922205770204386241062541706976832276647424877691625110244,753795180391574509648864319525512763100129705111118203505048417049290278879,14153559413038217294172720643039696432149555359470735393924921410988488820985,17643076982867120574893553230100217333463357095994549461637738074442388603622,3578933943193517852178000450144796032210613197873582924120228282439809826887,15520463167953252157432945917399723977264972626433304226673421190651502497625,17211537329205623730168383274756825219539545439487707555783029872192419895198,9802003881898384149235538364488830129822967333024012959168976309447054827302,4277753965394311084543194762939932271526308682615262493526499362805330624922,3936260403240718180440931086768355327655463497858616640513270218914599723610,11517607066800361513856730397176372083814736323098377670788083637850655404741,2243213365229554429675654538157029776597503775940697016289614299870958139625,19764298184704281654348385808308820923079630109704889940202178107926508921613,21440201729469627284915716136426033084639303793622913729895539439609852676483,18865357344271429482320975819341476664123167289165510208121280487753271844163,12062934463233700754743031150573591813637006411260363192982014497532786059086,7253500424782653645261846666860267886758998073654253013071356444451212225059,17688280285743970528696341296072681725398428119833052669003422836815517127146,7296931094727393709963826609746626294291079390951795401509403882666626382710,8944898010968990710934167772370816765379846965311172103743060979737069116954,2895100563060833104606048044246656016901407622471819180004918143679777127583,10049128690674011365994516711808882356477362224046294433720641467109283787161,20809590643316933764584815864182144455784236186778450054494378700964393080470,2552959198983852034601282535517138215015669324552132996051383405020865478519,90024510729703363025920398892759893841503303159824575434815310687587906738,2438402150656393945636277445769226062775867161339657212187540106747284678617,10290839327200266675482043018636710429195359786802953032677212989307055380477,13366445998820331718698457472184546771717827833722684584206646838628538349970,12045715338147601791240214774093449384918104627310882799600088155093595426276,5295711531017416568724842720044505396040371477829249515344865310124246197980,16400063927954668864214504458520657934817841218321732614334739112437744352318,21834268150215228276838182444784793459928322632598421948695291555558497507284,4036405082017497222204927366812040809401891394189816634089482334837550533053,16758010699927998006904853632308429832737059675503937996784758385473294734767,6851323788614107612891077153396783509346340795017622764414273403342247098685,21242220940510077461844092816930517552035812681947928514550083154475902790925,13803558028343943472219115813916734264304316037691831164863336831915596589841,3876897423511600793257560948470150518761848801469200306022138001232700430094,7873917719931107857936523614722924550340227737594948157729078597073258431354,17791290553613199208672721864188024787529313403544902623821727403694762316966,4509080040196139117885863635009327583647452661266153933806446923314670630597,7350149044068266301432651752105457672961955568647004218727518439545294630219,11503072465150450162639608555774152895393875487845468619329760555955360089418,20146546283112595992038998747954746814923105695946909075842241737548546646215,3500661581148278300592438598016870333493992384875150415517341312342838567317,16461061867640825231072403805782329353930546739796841505995525047519357319535,17419473457085759867681212087981664406569947154579733189885809269345147937957,10330084554893529954763451132860402555512473901655458870771994310647661645739,10271306411842332407495000297515719691188342515212338700550984155237667774587,6010614376730465540824294088181704678570427743830238021642540164120787031818,12211956821531047081164047854393417207581329108889222238958146335322243725690,18026227011560759880520787750218090767851915271628616216035782860818091527867,18039053385352422125173521135868691523650276298214786020953324823686654441993,21572961947836757087236508142423227244602094617521885308238188781724980380450,6952631457061838308719934275464119179697248499343745875411129234786468691942,19811900079804396120677471049757957457743518480096470411626681111649768726526,163137711020707070877550733174177256426010367795106166965347507600009523229,1531253433144642057738530256773902523524280331634644205392973718192895734956,1179712150612295194734157884657760659826346075044485388437451245699680152105,2729710616419138683641657553469892671426309689560939345577118202079250084236,14266054344296739494440365684098525973737250786286154516241047965660978988270,15026169712587706365294070206936700891511371850326743083547381843796350317368,18744742519058537072956390943103111325221767611576688631532967525091526599212,6993198712278030093898597400393962073007955430382142820465138278710889662382,2553141820754951085470014997086944345325965756649326165555729099768987826967,9720940197604032044323074196225989267295799246574437528002073812640512558241,17856885570331180579712689563952926777618369125836010409080422245803122826927,9316647413775248445962902207564207480723728241070369123275732644991331488677,14494957198204561202111268006350266984666563257512595231100502951029167863544,20990514914454458611724181917618445270429441499421925167963524958552424564602,4471904645719453756418626304970674400441871174741396875599881395188613340474,4684361390046158999250125407700867527620809473388545037966531069883415383449,21702205249470184149930308057282607474924454457414198304211876480322358864836,14125417641286741606705374243071146588481196226954437992372061774013416347499,3703736300177825900679993762695155186404123107499914435631005694624510941992,11732888492654216406505460448043873705030240266921135732988822696780340208946,11933466978112969006229130396464073172307879223153980062784019174478752039844,15171000950368540171664824924290660122824429581656415561069429955358449308299,10369486846273450968605452628621668108353399309158716739554974304206007657467,13426080534643441487992009643036732384216019130391445221701162507604477874092,17202835976136422766224805235458239972845135749171745123647755691905320873240,13003013510914746051603710434071109936447243726946691715828935535255320452661,1672563195387555152025850519159013960714433928303467231569405674199001377183,3249806644396047380745964934114987054912135505311534093405371566690536038255,10852655605415322578561541069174913253244788503288539822168510897694861970183,21180450898750475729531605846185254439124003420647553715507766256141444893981,17598208134643261198923845998804266441503487273381944592003474913329048411161,10560430398658881239820534975865220513135495522309722014743734708940471341227,15940735766678288146218967299383564752403182243037693045705028442779781161429,19840721391058424508364187473208857771270089687968326863727366457103504697646,15270655938735284505864085399423312069359806468400434801172200215370037695961,1774340315063362619348165557959238806046379939754082379283600857530102490105,1931473872849034457489264575043647960104881629328524494861951197166741512954,16037503795660448209256659529206619750469738788435653064537663524466496564778,11157294725944164923451173319705000360949753554936504404517553331688337467555,1860977382172821235372346764481514761526862185187436148114012977011560461667,7554608809888667328824255380474433026692004240460849082770678269699854930661,3812849161473445621072899414157938525926417912914872301607900000816805333995,3248257538394266288019799770714987078883986769586407060306626631267726656239,8987711810247040851774885826425578893413569065851274558714617106373602624631,7002808931888012021033077336936962976185388694934605760542880449764655464580,16260071391005121724128685673030785454758719454582904114834030329423907463299,17301316944867831355470414388420250906247821380560618462329913428602672908525,19139125176792761113369565771916762091089412261263410641074341972472699592037,8186463001964086803315373078973607488567538876768905527322257145549601226661,19715283945499391078117757449557157262014864431503022516493444981357377102136,10201366877793384824708227219959809605313335011896439133665539069386849213406,18657679796594390529926518390837962343392692362549805385222541270238612706361,7486580570539115306934569904905950241452751461260355433571179343632374451808,13210602081373832317780583229140785143149759155013988676929972636959898239126,20547921916591862189543062064340935912295194861078724580978244369580188659785,11184938862747662895633149920437248716375494917732149572183883382335006977362,4564430184172465843641043220857544376847031874739611967386619487659896927977,7141474497649513954000384074955704105249233034539438859110223132506810864380,18152904455695511183625765039917137650094202440231199346119983777378283365068,3538073603808733813419298816140509998806938194073503117538238879763400661830,9176198085009858977059589400831647890975463959467315677036348254379008625292,5358677810755468005042017406822742639656433122059352601335552810789858869197,14917263528903508585499167331159661105708948785920472586609175307188322712065,17459264445642522670023202416244479198596207282984954048459225794985333792860,18314375996391380435570814127239902609672007999779514985166492867417826496725,3831982114680501270333115239154594098561342624259756350309439921335535690506,20912918104665637113589191778450022009791755974254243256571842103252066396138,13641033990672188411010402475025484333293999311081344333460071084676167264579,11812251882211406110219542299092601278938747815723382992634003397593468524422,6831378526897417143208721431885442730179700977603214290972417120210221051272,20566372962271447276247738296560940562676849411310335464134428317792972599703,12645078398048087182293658191360551774451388858142913314124550234755654392800,18848512616065065931619133098070120448249278799586409723288680340437325332421,1336951976108001940844939305921535183133161033109848951359362159969984671656,12850569062942139371781102794220985236887099863147625303610933201225464388254,17095240610637692323679811976243261972135774635008876108449261858372552686880,9827905280236638995189439521379169431346954052078412963417337148237294494508,21756974284757687824674400821247092844224232050435881799264172836701664225928,21071024335098050648915070341467331164448998348673899538194227711074199728981,4575704980288845009798550678411618457862054601563658773482638217288811407473,17637889149961283902802970141414602882266203898461797433796173000208254839889,11333768795263093043465906246853631488076833683398258097056018834885708094795,13237413177387831469342322098638791101575804381099372225484902457329675766563,17644690723564191319649063794394358703071761592119981992193950976485565800738,4591566130221102246468298018361020201365534301234509687763578673293960293459,16880258892960147740975242226985692424894589139379261939284621634132328476631,10753253761433799332298845732798867046726308621524332340930656512278172577964,6294042736878992012448357827249736553756583459648169754872627240315677645950,2668606416345354198548309314080005930475082556427535177631964192773305378348,5244780336143933367304708103198860683485779489995095073384345019218674347056,6113177497707123341972721698332981926287006839555002718473535918066824223034,19824522867272770281143825792424101858356781501070734931688923418771980499872,16889524920861245550560790459946848535789402393200784095555799980201051324212,8007523897573727144887255293212203546407757295680344011669395834627039767919,10043972607564040581522896355091368769007227979993058004755493078808025405133,10815879623965899246220301442969866254505652264417667341661157537312485515831,11534947289183790267549825879293816175921818072299730180286203718992863665552,19282679238458671513808783870622522462539288436443040483594699323647255140729,20993973658899710060621174143488118082242133512002997296378188507484929417581,2207137584463635998515616548473102748156816296061395772266322132360447742245,1906176303891379788266254493945992658935732580384991589403254257107793504984,356009908103458769499047304270411564071705602811825215044685668712377389204,21267156990661889558161221297711049481880243497825013463587260785886036981575,9511026544995595131578865949819301816364113937202346971334793771967449171857,8732150772674776446232653795368043280414095192666412295836279503085501609742,10433912179719211724964521733928883750833304291050102060071171195374738464494,5892753211405353458072760353770523366305643800457149832130812257775605711230,6072173732058843459603530982418555383917328480859906190255818160437636798624,12537411810282601586400313857613201485446415283134353086651901233218273826014,6917382548294560607950289035591212885648538608975878502811670462230179895717,17522466317865452308300593635805699602531255301383258028599652149794243037329,13441087273853521452830121325700732493909228483089386934391461759499905593163,16343244966838333682425984150791963916204788641990311583878776392583665902296,5360331632046740140575498209972912123753748791093482084409464010367952817372,17326261745640411514384830391871497358293487167841563962966663074154000109605,11832463539058003103012764436368900007479300735896611859760466513560696030373,9332530307651641794919337618798260519292245685937263028043423079258661105173,18589656636963228136343540063542372097923688201290293330159927366465643313091,19867733544550615468612533273987508641098463295160374186223389748717034468502,21122779377039628476144200947919650885809091682970982371472379500808529828990,3027016623356326893238890601376138710903222026620502687697483362378227239102,18688538985571458464198537125324538836996766056814806096466271703920561848229,7011851562043637216927989978271187524190844597096440024970832115577672150682,6976276474543022394298383474157051715295086098335344328214084449502467982887,17332130117530488369551999111592288939240424248347612731261799228734373086235,11760005773828232229811117479200618747574322788890348748345009852749579147876,2298592572354833593457878362078773063587664198044761229360308644323231458063,17955258451898615415362730916130728340133607644716002859752428726933265234272,1495160066997898368260698151648234013994510168440470178901776412293213577673,9194083678217569822513593808499809262580238989709793956568701401108176409146,7873147134182176342443626581580817861100691419143183095128784103924898338758,16767569430250994260298195321407617265691776202802582359934917139510241475993,21740623993440608033243076692676917908105712281956015230238773795741552902992,13259811027098062609299383180292487555512077058811432839971137250443197786014,9862179315713982904488948286370860706178740748908626205136774943873439543978,5283798667794826693954690769969228006851703579605314207478989967594232871036,4252584733067990475653166725237187089775889157323429734580856783776820381431,12973205666610532230766585121029838349435114222222352682635156927179891214439,287633827640277544463301235265949941438188349560881553375976425107945733447,9088334958857736274159987824864641712847858830802240840003039491617952671684,2339929702478917712535010770935571285116447513742167345028949204167372785538,15676860121778371383024352289403909294835655990865877574625753945822204636877,12764603061737711341313014678756180651482961849974746341425597804386430732092,4838308895208597109198370123135942497394705098532245211834944708850927126449,15227615340505775109084051882530634970803647261111629470904659446755110863564,4983488923883229416538630982432842594678976476580011041728398828823305128910,13108944499697608875788753758764556629418014383923261351989967790696566041318,12840723598548611269818280989252209606886290717050913748780108061152527561849,2952676596403552231673795576822772308483388566436384169804788313391241403511,6122163114479319080164532464109940924328926458633830912986940513870140253539,10991285734105320972904604247873526149047475605919579896179431815938092849653,7998273930160782917435322581864589776803914924450929021174489205585585635343,18738565009620163104846733922742158284630011729404799909319718271414375079555,5267789578561581666385683546519898747246978052550117863765974145167441262779,11531529707082144080873135819545917882620969294873081450175882450957416920799,18780101368050367674291690806832757013309591034560713102040071432479406757422,4294785451272921756656022299749163922793391211928749628139961864310109196353,4709384663557124742915933403093691049837232917871836683405730215659929289723,14881387167977166163300411047605462807380624840482159906092434632182882848470,17882364021447094903093424534075826770336257800280425962604559742290433282224,11702502532561044172145178834042891352292518800414731965233576503757342967409,14059864978850405613608096166397211820819484772138676470000521070869797461865,1780174207952381531321288553792322300359882548955331030522024911690744446923,13028727766195703514931384985263026051594836628118028800883341509333550916528,7588265429164678210439639249095081332309245305288210445601269417147124081569,9642265589138009721420730439928969906364025440120910401773575492361904450076,10203823545087224726196594521548654230876294164502500177215475003344697986058,17120058099854629688232575694825768634386944759592366006492580522962871073389,4222192359475448381394699451673800507222765289015074154697111370954996368735,3993784121910007141124454385846036053674166308991223986620192089439929299772,8723933019744566416337803833347252328328807961776170035099333968332078001000,9712660217038548658606833881897330347907173853654574936296015219821374200265,2760535358459121107870901826259907500576486637522442431581134088651955908758,17117109873353435959712351313249763994000699552995926658366410602189225375298,15834046942685590805387820842211523319635967093317938586307927436446892526328,20540611330857822392080560199608407622162192943120548518785800532555099780387,859364761671967022958373408533303411107861007743219314752373993491065278500,2969887420026581030514962118165604753428498019600416703008438822193590952680,18165207804423071202274226128984095583162198441473954125845000361590859071975,1625906472120027348769657238152772240899619610263515830625917309020852034930,20463932955653127762144495520150037479624855783264043490725916287067071124695,4638144661708592747026214570394653618741348169520846615537958570570478926642,14161574596481971299443338101939032775184122775644932228990090697003591542529,8347184524978696917103428134030602422953969299144482352589164719698955992623,15813323300222999983430155647025925955486314051966513470055962106024932062990,15881789235120065904292616653574390818033995432226550640643889297228035707625,7140692095240485283381028349925581289679980854833888018152159900503732423858,19010917339674038277064587622527941116247281757743905062456743932291367865210,14626089726879708665184866329935404127909714172968102824599946119716141024551,7794590602415713436531570478653055404401179384350609462543106242181653823825,8762400452539506415642761970628528841241237486958209742944443338295503154358,8591771034219068368320608087757251879675617969654197927442982939795060041474,16722135923767200283514351262528880285637400101562656889998995533577538049598,89464124861540540773346410834052352014308242060847315373495379383140228595,527363371365063907312062782674442937761539145521639367736772902232593392996,2507841963726490485511335482108618130879932510673214677761709746737826243610,11600559113928855816564236457966654301430060930571013803772049573600205529037,4588632959705258135254026492226920833318427708514752831324568512946022675194,10614112216523109461118034753484116653637318222297437542653638803709000476069,9172525851971416839816439437260881435627775489982516326698553647792223169716,5792656644651436247861358501481981837063028644438334753333821264192324104118,12896881102412475846285309217744373816727588379892851016206737393174951411645,11468716910877986153680082696909131615615571055661580004775449060276352989554,16433370238306953119452573705529989067794419309147323079675422756276020408035,1273883504219371718563834088540759123243117439006904940363157254976913033897,12035946135822991823593467599431819071656367730183582372112230833767543617935,1584468415480349659495095652095228645182004993793756033988320959253925346826,21386287619427343417104905630296265178906342440158736945069239788114458023785,8353771053561995945612416527531464945642582086497086814556341372197660908215,21451387710023590786286131498774138351594763095518652036485484549943942198584,4310607037909191923700937557843586755810945477870372794480216273434853743125,14760194187040766562518106717503624683554510559335502353786749509033100485706,1989722256243159180961728174407914946336713030784288455577084756567680416269,6686508185527220254925691658356528598024140978521686081374828691583660936030,10702736220547282218129581824426150350875608542279410979052446031034395032616,21518832429688884430739158604898893220375510075322761868526168806092202700739,18894734518217824473490018310535147336620281698236505678307171602214420149474,13651080497325379255207286313267854150042736096310351308026009382931418587349,13005423795701931110183481387065874846108794433756894029607220148510576563022,1791508640954698127256430696076954377556671221508186631495000025000560314469,17328036510202475587667192203250772802218778208191122529787186719212302087427,10657963758634548274685968417226435837089760791121929723402922305566484150027,1373906129582260565717689440357805911187492936689152530374097510483815842229,9959127778329368795108284764279846598110110516049484774588901738715030294501,7658768549089819420025961609972525260083323240153758777076357709438863924071,8556349016311563259984530239150734383111823917689615136867121162886430935013,5584784611907644257624218172047384219563403421449130896517357173082649535408,12250428484720929053394094480089037225116943346244386549438429776642627577081,5894587027805929865241808030013307622768224687737099108946198448930484926182,4640000227377695114780725548825120725107463526354871525420448370293105443156,14209260856334030476503172714481690115491571124367768551485878619193949022436,12847259932859893012278918973069680996469229489435970735462165583338364177587,14707765228045361126133465815432967736466274565508518646993164305646449611538,4776938221827642494595066454007024055266353658953900973539209110395754289252,17345634507638246813894504405651157443245008745673515073520154967327741083655,14030342049076255140305545268617582878430218358427444316024303212302433090888,3081608613732784391792246085705209806228642369232320349344206761814264266822,6925544598968002128460287121334907968171640408686960604018975554503413545297,6436833790683001261207201071187060041301666725391276179040664384301147754533,15822971282077757697408895884235910303980603368062126288859779292088533186609,11405645516905544384081084440311050207481018746793339445931815864373601814301,8057851956466271394801907096296448157702512819801554261185443997708792484686,13400701029177845728937105456192536667124279186738602373189177143094323643048,11966218129646969536507242899486947493941404691279766045602150839476320695158,15426703084090770508053125497176086377457196612492405232875849008237608103107,6284964429736232174040445851307654679317453722810844133660225254133335862235,13541475439682330895175095901646773164410091796597408681295206023344696136380,746760486363018018017386520506969904420399625886684141218702464564311095236,17524104887381990279039312517306518062132617046713819525042298049738730617133,879502104476554315787832344079612181105511927448955207253764010183827781938,3322243116889956217287455917347322211093649776443788544812848110324752380511,20993304704177227988946248236539217504266305909163005794546179470620336655896,15297086470600095823350435092749336605284701364464412627268330863173424318784,7926831990131610326614433341787624222916431629609577848917665290693634271603,11271157869866761687706729926953398656059815012440629723619426315368733378302,18299023753364987381538199358983670915973737470621191699559419975990005285294,1896523269277706381575521315908503178186583134996425770080392278759498041496,12890346501512276297101448381578516979954988837373044432656264176509301317397,50683999778726139626379750772467319774169558910797110829251191014869406584,2535823474764747710030290051647541950275171691698903262059516064562837569538,21244438525273542723000364561332886617309030482024380299212725538173747919525,3566180332124074953578668480009215478053830658040437750684892555496819182968,6934760873335280553519652185111971021084408206212600990256329557702647231767,10716990663016621229729175818785901525044168020825517922453745625674725718755,16032906457960033408967366361214250817346739568272864358714497113973437241307,3843556041176221664914001975628278428195138883854078534543734996192939783081,20159201956050700213417267403145919082229292739510798606395981692137742005549,3946206250066677142194595031646387588831888396304269420593204783498093935566,15041638172488186356886629449548027800133537204416329580391498341162500701165,13278796648404195845011313500265526847654531008699937318834233691653233844557,9401997027308433525669054020953469816624994577441846092561461184007344721828,1983197599992175511555068756140439953159901969155075046465287261273690782516,14404434816783701517710626513536590424905462755924351795276920360393132910619,2265153992995968786485646516094566778663253373238301922539677847420824091645,7566790081073938501935204486802755123563765476651717380300659543531475311797,847895502208273199247564103189534214890423186204714047221696858073193176165,11963011786171849258296957535441472428283852585041548938428326288746833247421,17377294274187023009074658259347356248383537938503682836124988411002248431249,1025753579901801011233785198665030697958075722777337374303401815648687864152,19284019504590857558072823196945292661333776228606049953803221551974077538854,314204118013777455817026750462293710777754680076389729833422020056750157783,16480262479960754021966845575947830901794064422051876558808623512389290214607,1118467174052506904085279606913979573425427098904935496893365844271017524128,19632743231294128529717484081406317899334378150630214776880617163102648968680,3911642624469919820429547144355740104724495930390962678347147942124333228884,2066832981312040153658964981292230050110396574171753029116180129049784719869,5311750082320962006044746418239249402583149931726835813032955695199748985964,1668605805291951132468779303736499626803321838797652736089353191224211818512,8117527083300107176240321998574781132203045054266787492339353711594335529709,21295747743511951700871264160352432803897824342737595930859857743511472313518,17388383598447322131131146498858701344049179581377651662282122447439867066027,1285164961547283134680842635704675169007050470102043475645519044978941760131,1875066966449664224570600546742926101175136253576702799078476168727336032193,376316574400845651365366460471492295014146006765806307181242245707469972823,17926797393698382320151787394969682377223530524132422415508830165925306730854,12888413344274698384267384086384474622307363694087246755565655858542934044367,2287154516202749380541196057272317720805230156010471100500251268302509398358,12091269896021030725381711946583875149737687962883250402694805482865888072651,2866048333839936509265230844807967492604533527765757660355779329791008604324,11835071699154512268334373994146252361488263767766913426957050581680705629365,9769574961167512396467538163460983111263497516872198932597594846643533678886,6652717430998307400653769850757364796566010885765190753303419969578998970914,11706514210298927940240806568375915039663039872151275540599047371226868127844,14503173259289644850389467422758670421081762433800521230764199189580041755978,14819563269715549434612532555018280611140077716865566327825448288943759458075,10680481968851597237106707337987338182186447633463836689709242917734021556532,8842568676211857695295830062491586931539601201165478151045194686251206282625,6530738090493870852939715092085577161577833016969257865187421674974986108366,9122348442271830670856465114634608231502719005088669868106730029655164877153,8276880496499930549062062890222235677345093568048001523633692507246467514288,9159103567267771525632277936018480854652194329966882107551346987942837974086,16469319105211987147868896414457254521940280033150431057117354850784171354412,10187807714948737954868581824072203418416253898435396377923197796615888421106,12487902950231724077418777903531512931204649041424531773792238730349062186046,7128847500406995361903929050204217572789701023482188856789540128660376992648,5624482939513897521205456066520453513748417048856589163079298385117683428424,16435310041815433976313715464222273283215148709695464992270777828213079073600,6053110243546717824144224394047966869215089006720239359415188827006018953287,12155283178966050547567835509058470201630806787546132608678364857190533906654,4516299433052637321210501303761417706907638446979735686067715866937355560218,12667848710309960989666753249292981950689410172688589690222261363826904222200,20798966719534261926649504156624517814254561351583702314533431478871413942185,17967549743799112209110259394081841952094330269294500558315036929658897218889,17847714150935110939206476281446907230585782511584357788270839909827513843593,3706525735092193828297046649401002937097518714707649753675691741717374375329,7951431498272893618049118070591089643051946670270891223821638082032777246372,18050610739452223409884731462410705437134574403721907246909018802102148878228,7681233452521913704953218921671929208806506209990716853575264423980840711485,13423126358538883907022095116894303361057277664724853411599423630968340874618,16385186307753207860551232886321416660506143479955163989130433021552655688751,19863338799254785908021006319182666048802363286601429063342266271260238637645,18613864443384979831007688916611349052439959929170133474546815634162799183324,16332951432721718166552572222119667287478083212745997662304261644978474988848,15183520838042840868796366239500461619005160337097541115133209726620419190272,21819632461581352219365791577295628387565956152415171439862191463144627141459,14048533271709057229957508911818231901369646548751751133058494379648714713155,5460165509823151384714546779805746551465260311624889230527298343216031522426,7812320479950772901428223193019468171803323319794359571259026602925413892220,6861047298949697363524436975701264276161947671796912946484193048676968364570,15350000814702190667768044439440847568690389883802239839819456575900015807805,13617689242559757166326885110516025083265117478902533337635065578646035372109,7476843340092386505769477537028758806323421556263090744578424892783190404262,14826737006932111183364733677544376863485041173382717893595766527131815613201,20482222533304950354756700764919164516648372491559583778492129756055561547902,20761958166613639518991371846609568602964716408676516216766187562459779452764,383428479364004198529582849470440881390404766297544454256885030893768964772,9096063532469724072461386558496798312147772678120608720218640484115240695555,2933312980053872879818024429044461919397766967639471518371949595510364515880,9299316327986512295931957414766538459714522358165090755549540858707887390215,13488092390166418062347006407529577052576958127764741552594028975338262414671,9829077383468426688376344724031102291718825262406301642537010429132676001524,17306252922949843274941351200908184305715966839608017699204279919732909328171,17087445274779483487397521683084452362124400111143021068068404568736590545834,12957176730411938817539171430465916443660534484629425102659921020718336935547,13051137677735706323786222675600013609665436923061132301167672971485926193799,16896405620483797393236904159048703206424672638297382666760526590725313874095,12982786219003483259026043754729673677479461289605569386777999422861331902406,2025152781178874327274493576789397778291707054468278801142821085671743579422,4335304794121497318666085856101737871981186359433585080678838732369068576376,12639022425423716913754007933194900468141465623346480681305462334218095484056,8623058240535559764777469232729047628411050024996927445391922152785990079007,20506335897603554545414833361572976187621941529253485759521266317325651663673,21253532477517846630911098846446871983813752932337294199438073014278982612265,7690372912700906813961714562821752274841425123411432854046237798188463759714,14774079281706150157728885377093724231164512116594840467791057304501073046227,2057509476014278951878531863305791034496952436217061173216277825372715694262,11541539364361827516114507593054831030438985642093836719960774810015976254752,14751271529818502394785288765886130704541730104426205431367858892918636267768,20653824984831671829709191706456216192511770845470322444515326861038843106056,21794617070379980226628233360507465028625654800811478227502718633923944312665,12337675699660313500286885345145964244870355316351529815248466118884457457726,9527268832683847687152279087478212995292048665053951255936397859316414854388,9676848840550815858798680133955006115514366150476209999729932493584446713554,13718457801302749437654397628557435190188493872576865462727587887532950355038,3867324761996955514268635801392015956546058763053808698121442586705196957126,3945177530905850250597694151686052963152292050981415927393741981018273529029,9473309264240097344589730948390594137445381539328377904021534848676986947654,9996385364578703060792470002743943020203968343080025005448261317627854389642,7671875350824730767796781844941080563527207835942241721783016221076158519589,21342545963270813418079341151020475012992255268798567166496112378940512106806,8273987785742417777035293384288140933989540189974521462819168552306151314447,16162516432221515902182136237589464594279404001688534734264317844425059661177,13403805360231306331901242144909690435939614369536490494604700225511328976179,21640586272648741017978258285249302214133507217427529405059807093199643534960,13103298902142682492657114828016226525668797790480257241873358498200705227711,3251016042668618943397347852790038985788901898321438389540422820491143534512,19418047092207786422594959190763286166909227118034848590779428639908706128141,16018739283901993654877226905623763753431466873170287728134253742237701259452,17444946939314191179654576411859454283526068144165928707555552999432295774923,15128585121813842824984220733706899232093493608422847549831681212432769497258,14256042951767483060181875165067417249801798477941578288282791927486641413650,9120441102041865153472829977920901798404277796873323854759847010789551358565,16824614118285494743762017938800453590083305489658290570438237922163546634147,14066296536773839458459021526010711790088172526749593960873828093107983908643,5017173601281838065126812757441844223954524936921765951283764327160567691674,6254306109691187702602819001106221686689064495376117914248886700342291435542,8093845266500847743481398069264511597137596242374064050252920004891985410254,3578536483838573103029984288079029549393340013685219142070711310306738904812,4046636520929111297180341957015914921052723918845140326762981717454102872515,7446649718318072281388998859356555024817100796345520325890349758135889404482,12366828085438268177090003236704251656102820345668679675414643578247762288715,10235336658636336826692093860668421345161445948384101191460476320469211290719,21557699385719674753050624572282725191612933706864216121110471118396873804204,21676195031234643974566056999169564975565168161106308063972653296222128822558,6363029841115916180506080615867336124807912331702908898766344258887335068638,6363363442473598630315975560083028488315295047134858188348763022659100540644,7124701104304155953181957655778532711129611550814127577450223681003954918096,7205717562822389401795306034882449236003182581929449060008168502546885140420,9228704321577313703028591075278114440418729713968708821922150367010520752433,17614180549151511016628006398127365390131305608457060951973438257438000114647,6418032200333926158639440620980173724897942384057810379437154014285875236793,1563831431103246736895130173427149853201118983353993792302858411456255839836,2319462743404521965297213055024756354349733992588917297296444679195296432311,11927767606932195981021511932625975307755048477176557643420944859867328059951,11544836785666122785129617591037772824479186137515525949187438698705551844116,1594554937757396474339277849284988438779469013126014780880063013190163371374,3090898925598297656723114627648156566177591433413115455417582215942083585019,7446365483911748580722671015415226813450613606623816089630076567220802142731,7277804562221458254100595374565579800145724793164291138831756170012315181874,6742114513180059066582114839865181272182587124666919323239785847603969045455,17639336822454434815461281360929380680585323524008927548062809039584978130493,3577053914395256679157728351997326335158820293078866565158939674077090010647,8416461669288393104752370629542582785060946946477447413022986748926853429341,6094400991411029253990297530870616276561743402531435382960598226029406844554,17249210115827920255165876773266699947215322191164909559927557290769226533383,16910579881016588643870584852395328514859173042128957721312044020554328803878,18548800605828674358041671058553674062230830447893195908258772241250469878618,19911311709285615075760278233929935358167599770457743440215721586291252049005,14163239340563250030474254441824385465013759375574504142110478434407678615583,11636512441693145656185679602762396225011813780067642639202962721478584613773,11627821975451263242823912745820712501746551642630006051017450144021728526893,8744830043459757570443313311577350804214757169018319227421153827794333111861,15502529014760684785001315229904504412899268461167235130234930235025949266727,6349631474781311552829280885666605465500111601027794362415725063684145078154,3750521632595755853919734934063554601358504982902984744970328457148877834110,9151149071511054371049219579896119997746835784236581257692741291133486546793,19272083712610290647942715418077844472245445971738771938657138000646231164194,4825691749471936225587218745193692386291702673577201485716323799193545312215,10104595857457718843210330892798628518507052980455210862700838136878095844947,583353789674136864282067863249996585561603923757420881823548159264798915805,9605601189839871334439279312434848410060547509366999421152290140420275791851,9086947882810130237770476626970553738390827239675874433366363671998428155733,939087130792625935525433768373221635016459152936104283115879791761930303865,13281505022430256926767514868008519612680654933479762886734630854898956588159,8791789091182070262897704714134448615861594471173394864103714557845783501440,21362425094620759937169033441239641099917726266745789893288044988022041089124,21264794594588373773536904588090499011630449220310853635095227724956212914745,2201440000983888343103152416697093803247262395826184450099145084240341640621,3661470436482399872770855708635287053510507688269721514323020960038319367739,7839180633039164608733079650881737341586893235460147432870429877862925246133,1364292691308802542355455613317294540368840799230835218243676354771769346816,8772467089802087196594680904948784186594877728663145042664601336273257169460,3528294282612889297228918585517392070857581849271784732463382671241778115171,12283613789492092234060914364373118974353698674396863245366831728069561564466,12820604492590938203463369747918352644874868843295488782427665387357902190399,13019897240405241197543377542947534699610589548844172163916774096781016951470,8978439745720039208900766235834036199032761881062736449080983584518864263026,15222275515593239598230012498885809744566950744378381699594010392927659453864,6158846143100676033784762660398310184837175038752344358512599894306514737286,3419255917977463022603617504775890366430819682320515293245827217078337799273,2797549320616484645720845216321636133654549511963540737715630452964584943931,17033753202496389008484483700445909344644255293271694371709019653557282454651,1896525136564670388001069429586407694373044886658459111231294687089652643180,15410846104953506982390647924353051056630524372570695181992786623509940504512,19568185152800187670153137856814273221696851955003399523563214963248234462015,20371827999905064832491002071821973934784290275145413746617942892257828998608,18823477734276348993184895526705908983521278925070561827518170646437136680627,5656115226652970780235535706189807810471572029095698537591078819723656151288,6421434687984511183440563950015895899135677057679953590513947822215985604920,12040384754225464077155439050798210419160821091649797103441177013046869869449,9772259825341200622705640733478002328903138705997041039987261797557503104066,16498280031288829288227785307302736352936199535492502196962915104633784174443,2797879572297199909334218711222177900854374704477138347081058961121300793309,15644078107885262244699428484967291897698559437568086329631330880220396182101,1929505350484341295824323699861178332578728141996333839839142429658318709684,19829107623275996909068882503976730773632786622439634235897400991781002387336,2349581104996259830058120951667460730076264470159293978617685139254844279099,9982268711644224005105745225708318829304834159499232155579405472268549361372,9283048909915207444384413611285315401509676836116090349272606584736947471535,7228184586853275989616881380719765868918305938029647325846170897121335348738,9356148801854782728189493667017091537583121935960987886599900693915567464857,505609318575290577159607039016980344147219758564644283699477849237669899416,14366218774993226370408163695258733389122646477999733966996434517776361579764,2089359639878444205205504625611416181841134778729917955490118311877471215733,698820948911402576486200349924367867353277614409335325450207885100392818369,17294754169238631079500422194295778880256675645147530605338890302947026045725,5743114444764763990137499217919738961538814043960695215081370978081114004215,1532354676442440269809361487929394117850339080897231885482935144216545001511,15429279362464933048379761813318395642886047028548664371898579661267949218379,3996365200571187062769515782559269970838089444839642643284597375210723401466,13855942579438265547807447657820171102227439902714241541267837936207338677600,10017315263017624310653373895363026608166903346797759979504062819071927130663,16907630432341625239068562338272519243551636457245225084107387534876995927261,7499064872525146201613148795250282369576850162788310832273877734938523830020,18958126705503391332983508022395142836904315587480202621370522508346095401093,10592492611778631944134585106195825750734295091365114316628335289401976557048,10233935978161235645487498670591630814869863266947595645533111837358567006403,18003113120454128964459787917100973688362112412222897499908177070949705432002,7039143063746813662581342159908917130120555794319120640254054115394750527325,14642639620523941644124538953496946557379420056235185193901717503194398478844,12510354962778923417991098874785395513418703200631409704677335762559702597729,10937907264762102220987756825649855260366448774314976509103469790406549413612,2856291402269285412222070625188683697884675330846580808282552440813379388545,975737765008679829063246253813268073237541742979444038400325932865440884821,10846579585900798888776933082578183338805087990458930175500622018769094956268,4529602228982157635664617353676370544979061743349920696434925695574883870240,3217171861525061655884750653752887679288235310048470832136609603512214131719,8115945363448342140068934999604399115922267391140037880996539055087195710388,17017061429975823256838374218603998280878588780557395344098357759667769523464,17414822882733297737417491176979790219384604825369331340721407024843872424842,21674124478965998545524545297025636759207453169144537816299040483190680515948,17404327139726954519140759696696303110669221199013129437266401728134593481209,17114525865368445983838697023323950751616885090116888636158517909348665004808,13606067029568271979635008642466621607360271211611257253834134991337929444625,12697011972510852002753203688496604009044404157472710768958968780456921052232,17908262237776925120663573891641823998363270265606050465713306950786509533013,21456469759562487171462776687926242591840822996019886989101706511495101340835,266521013932216168881283771008004557613060760037591295825839278412991410595,4426122336489578598096667658844019947877597098504167195068107491300030650784,9386708946433085177945274757444606300245243689157314090008872819375610588441,17571201661176038894845217669278055388543910674470132087585433795958011317108,4455879691406517778738600662496288227132258098615032267607735047373372289231,10411615872931007756022633910690379435607807745769276655537160609832149769392,1369325193519585971093564667957731115918550810109208821335573114054160355015,11701493479673417478812558973813785951698004134589804881992366063053267216767,1604976076096057025943679983359889701146704427744088265030663068037609417365,5807894190026658662778129602314598491833803649976558289016319277596337255402,6604568830557716159440870492208510177395633789687151427836556682055398194130,13221322798326908033948171538573182873220915914806870794442015701313412462981,4276423994177015753526554880283981182675757973382385661312000468093685717116,20731982721228405909675906960993136550102478961136398510514645316644217252635,5084416110782735943752807643199425478022977025123417839387489101289418017943,2080632875247898509655097068576655654491657659787279629928499240720334125890], - [20214838738486568883466588390719332066160511773018226407137866846447805607366,7161524737853996242838650618412058002168848579199128467811556550737619970970,2264369418377007316930430297757084139629356094085160360541578125176213258694,18691044064909968568998201940845291098399339626807500263611343942450116503516,15978743992268694554518277110515494413411623432213713029162001242329212269562,6711615239704822975151699228936015251056551262955961924747531220602950448829,14954997163751606686696628499315041796272082739441018134122451910369305642115,21573550100361192110069886620445669562472881453105471211193858578537227040439,21785281999660091964290541777959906196912107196794342243439922177000502203701,2946923208312508080510106804563669422427642075683605437758174474435322095802,14039283821812338763616072949057938719426671560747126284782727998420210694521,2531474643515410792989587528850930504447014242967363822821359471367799986101,14281461695965914110119049602449207565231627068856382054789426564141005041994,2155595480001027852247471998853878746887483662385654030663226564169133356539,6212474220474204735846033034823136351584003532895558668927059407038678087162,21589299957493491709069669042662513245508573637668760884022386808061869005942,5228547858762057503048110033821407961973668275986265942002757629551762149969,1151995769496843179907951142523838829938796346663877830241077357918848539138,16195901973518083237059346288792924649902586274815274684503783828189220931050,6205461827971201267719191643863468322713562983419848159871959495317073732623,21004710389082547785746156915318076260017385298749146368429985483091499557183,10094301525352802553607719810440185681054064961117719137647202357989110756759,1174362264673060234121108394303385502501621739298129145129042091221378391858,14586772089804608057953886654898255839796797046217599185042293580394420546552,704103301411330239947625288325002010320119746677418877341164806595452864925,7447867166827402056774077383104558156866119014007569966692643297177923018546,4252152864489296917539284690826221964698345550054947572793948075436067436040,3675525234832046985215853449128143168168428943627479235047788418993254287405,20125795627598431311475910664717716586147044241536953058242999762934679572886,9159576094573932436478222856304524043339640337232471953289062354187369243885,10410289328536677868407694844650868516861553712016012272941004725559785872650,18813119519933909103102649065156934680537361290190751928265976568411443987994,15043786404237278119878717250753259786450872051876817420168142382486008024593,16614805203312302723146840789675006378900903626996105116400354962001922700157,899949298359737140980259063526066233582477211127560605822280959405167872532,8350589775626940122507262589996655703528509795097550101006133878991750882468,10881253968160794744779175936360108103824976232977458894007732866457848744711,19359742822671794584060954988237182553116341604406926658049749172292672638977,10716853194721085390661796797973316855886234718612858006131046035921078793777,1194676839570189281149587289656564753779383829131008000754135056646064455278,11530412134598354110310733773537950950490005376234226554463355736782774653810,7158806839647137330333220334046918613209783693378018773439140974716028082046,18873459493111992992450800068055835432261777460679870727272006783676545919785,4597339034364379110034269874329162788488647975988086437272199171979371177111,16047595573111403874356093398802733070084530893238592035018321960924442437232,192949463851654477795020911703008125546432931266166268873310745978202434603,4826544617576366487123936439697751633333779280970103286526767080486441353413,10372441609969764399977561535165700928227575842447057367716683958896898456242,21479608666927871465054861416648367371602717876964759897062141685818604541372,18757812710789932354215078701254559681588101606101822541277700443926569010598,8502339138598356500092304059172334649791727023646195989902300809704249803746,21240184871409684692673423121366677112492469214890212851758021155034260698420,2702659403779176675766431784851669876796725738129029887042678538644093630255,18760062461290937265331504644060340132840729161526164449611377215801441916965,9598514148929007169331478849372274288455651725546984183500169574552892743616,12460679873938368098608659480431260988399308425323633114529665233186673892475,20582262751655750693560201069767758489467289978119794831247596435694971251287,7495462389257720258504478831214292184152544822380786356126692935003910627822,15847020891468169726540675640439992039404102490965287792626266482436024810091,13444178956365729587956577087448840645730541657243126743158358416431709484781,975733333906184480394673719901416555779305044861384485566696694336272649841,3016935868211088289963870855929013645268121688015888423636516996750583017171,20123197829824640950428347870445510232078708523077317828689832072338303017047,18496031799198869774970797646230665906722932354114482887753612521775690376535,448875332457320150287933426080386825611557032389972932765197125881964153702,15686083476904717209874986881961195356503069952883501862704199048297926079733,7399632407841430295111381086121470926608686430000074868388902950170939693998,19157441199146430337309347165554892283908758853741856357912555742738097866135,16120175937370916934366957179931217076202557540631878137626313655342796978134,17363463873417672052573440102339969267068334412527908172228668014397269133762,19764937897808275673467150361977575240242645746672288031015882089680753193420,4264866715026149043371443488601547814355809386242957666273811883512215893986,15361071774597522987390988933793735468585435977940286138223232105339041682390,13444894080484049025660420839638753203298145906295848687612728375851966859563,21344396291142953621865942956005813155481114773979414786364869990164493168988,13658955537084761077271566555621122724333408573482369456630860179831273897019,12249794154563702076745009616085271813195258124596555920372455161542247237218,2325936171131642979629131064685171177284405924159468319138840745089808621723,3077792516542862676300186898187316876000625806438082696997401720196346610884,21531439209065692564653170259849715075994439889756241721092517464459744953429,765723669836774164873260120197059605145439283015732643840276151768662398969,18430565163341347334129211602477703661982280889871625277638214021594755964149,15168574820004856312411802521805000105968244665018577358614174215627811033660,15609931056593305381714243964783225295053513474263648739398875586829969929857,13057901697952283349663465856361305032896972742145291496691475939407531431061,12802339382735521870414423620343194986509343830854539673006232369799979885569,7880620299082787885902391014823825400306816285911629201048471522567587002433,11085221899164994413080236199596538381402309021910771788195135649489784323294,5662061777175931509849062158785593075054461300898808576328927259801174692172,19620207415640534190314969542389551464821476135583607027506853686406083753807,1396012663571482634431038119696061726217340333644346862093678929991918911771,2833239640477482582925766504780450890721725782645633022528100604619065406714,9289278993548596713194730547769009982667061443580050906003394115646319823584,255970566924787837673441110425992267446525707891905710167559324774004600788,1607914894461957709182037732125046273691353312066921168498378132410220447224,18182823650001333075321511247233769219797858542696762318647781137777390858484,7933393968545943401801081658073805133658457161128306876557740191220424567009,20347911076420909832061080138703827506796370399337016973599032573292195453934,21705355682416154516146726727072637540254191883301906287097797468012136754530,4393707213821090202627671673506613966066953344462172841905371093203947245835,20015218870609611793683104277034599032802947064261475029925414549380954228847,1857954279082383201486002148223947538500417662449637107611316684336169564836,17075622394357639776259605879156105089449277115338468776425087829255085998708,7849339039625631210191134106813689727565217371730065596482503614929894173038,21512601485458872387622978217203423557092449252654722032828165846830386134980,18829825907628826679915224363735067358668372607988097049308159580108100510295,20145344934445170391525281095510437469996020214770888614087514859850402376676,9313354461544201805378332544085825218707302313348145137439630918018863309279,10073510764514576042491642785075889098754556687860419668420630560526859371108,11174613823246619246542059297257164876488140873425479553593597508295299674750,14486836623332191458290523271325176557072260063250466764030358280051240942286,1932726606175618877183776650118686155013167275195994452359992776843317764341,10586981584735794740885178709528523597770788130558769643251430679627096503451,17058731514535449611097320348142652958393616886312564975789110366863616539420,21546144187559470183347034044609056404441744756503592317087407561629774536920,5681882870231768621749544290358493454695957383787481123871436386675876219635,6603033703828934401094376159910456525337139277249114676008536852402499584614,1075347119451441392402288921187671249679641364496638526228862984392689015760,9887880282527621962449293235959776308591956208594163166185549404667941094205,3081779595493746844428351914840666042619592907445560123915127502392400574614,11109844704163389102553826717541117344605357734084342755776036340022417198082,5060345909602600407449982784585458050225699107485058131116856520723613936306,20049893406143885619592680397871697055896501875354968455865404394786911398458,11740809795693360891733016778293494519471041728488086332325924371909574885493,21414777615318644939200434569971788107661288737252832241371433802590137831626,19926309906539946638451151936495517057597377615887396199326446649447508281702,5833294070005894544680949322571753681474561462111500624110195335953784263127,20316262126697618722223967532370347145297985363803056816800332573538115921683,20118897454905330779316757365327082825225674670546613715170828215358297124461,15893782176793316439240260419014348246083695310846638270933249304684265430800,12847296795001788271556697499714377689095182754228824085698104180563585670787,17258109440267943312537478894153608811927087776527641627893802618672319064807,3727185744255496747036491258134142468721926815259510264718979349995349167789,2377620008282598351802066487452475263179928244128123362464911386705146759528,20330733534745333298462159658402131849518313653717741882717272744687077336453,3063488930518144343621406800230347607891775381984489334408858649400823600099,11822391183098027641060542512210687183510613996100060945754635806285989372827,2697686870567304805976687716601580249659499813659634827192211658186812105269,19466890284409856892962357589067669895394760875472697889494886746493744150398,1006970646211395884475799222625896618366447925898943829426435645426534803620,18668143903499292595688863135570950175417970684200058312498191992564173409237,374118929819602952730503470915153310582862106749955863047933775501492632816,8098759627317959799834443934069068232617039455327629644555780572940389866941,5647931789489182000343586961287147762347200093731102535565999902997464444183] + [ + 0x1512df0135b6692589f071140a60749cf775c642b300da2fb4ad5c6e23ad4e5f, + 0x2b109ae037ed30361cf6544b2f4ce58f356589896d6a8849482ed3f9b66e1198, + 0x2585bece06eff553d485478a19eb149e2111ae4e1ecb1d61fc10cfe1c077f34, + 0x1ff896f4c0662f4b2ad926741b481d03b813a8cc343b9c2d2bc4819c70b2f3c, + 0x1b0caf02f434fa3d4cd4fbb13d3116ac8b7386a5afd6c67076ecbc3704aa45dc, + 0xfcb7c9f13c85517a7805894ac82b57c06f2f153a6f51f60f8e508684dfe5bcd, + 0x2dc2bdf7f43812e39cef210e42e92b4968ad8bf554541182354504d32cbf9954, + 0x5add9df20c1898da46bbf74594438beb07c9a65635c90f45c0a08febad13664, + 0x21cada6641664daa997fd55ace8b88191cdc4194fbdbb6ca5895447c8a58859f, + 0x19623504589a60f058b04489b153324d16ed66667a04df572b103590b848bf04, + 0x1776442d850a436a005e02c6475b72fd2d5f84452890c444162848ee1d57dec2, + 0x6c1691fd6d2ee98396610f3c868d70874f24eff853938d87face89234a09a98, + 0x17f0d5cf360c354a57e7fb986dadb3aaeba094920e772cdd9abc75850400aff2, + 0x3062c0db9c925c48cc2f80b698d9602642a84cfa30e1bd36408e2cf82ef3358a, + 0x239ec7e4b4723c8ed35b987db03d62c2a07c447bdd6ef183b0647821f6874c2f, + 0x2bd39ed7f4f6a72d02693e967740b5fa0314d9a1f8d9f8911c28dad3f15ffa6d, + 0x20350e75bbd562e339269cf7fd221fb7c6ed2cacfcc9036568bb4ba5cb17bdc0, + 0xe97bb9d9784920fb39abf35a433437ed6fb631525285dc3c126e24ef54e4b8f, + 0xb12ccc871d3272e80a216461403559048e4a5b3af445eeebd8224a7edac685d, + 0x1dfa3b05c202cd982e3d73cb81709d5d48b3cc105fa78ec8f0f216436826be2f, + 0x8d9fbb0715c9bf131d6de70b288d94afc02d46960459fea30e0733ed3be6b, + 0x292b7514248f1ae662e5437705ce49153e5be27c212e86107df1725ff465332e, + 0x1d58b0684f64db621ab3ad0dc98263fd7285d6bcd86e07a145bdc6aa75c901ef, + 0x4e7bbd68e9989a91190082f0b29b0b0adc2be282761c44d1ba687757514acc4, + 0xd93a5374677c75bdc1b4071b1948e53a1b67308e70ead178725b08fd9ed8d22, + 0x11eca18889e9f49b1f97d5998d235f97c163d1706b4d3d4c380d9ae1f3e79a28, + 0x266b924e67a868a585b398c2e3f28e3218783237862bab3e925e6e7a9d659a60, + 0xd2e26ad58eacea3b6a14c1c7803caca7ab3c5881bc6b5b274531c2d461867fc, + 0xbccba4532b7eea6c3e40135655171fbd92713ef6e8218169591e5013a84bddf, + 0x17a12ea9750405b3d59030af035c18e4f362e183da6b84e985808f320211d061, + 0x76510bb9eb19070dca388a1d3a95aecc5de4a2c69c3181665f982b60e0183c2, + 0x1b7034b3beb0680b858bc8f19528e8c122d6f68059b15c70599910c993b6bc00, + 0xeacf7ac9862ff85658521517138795da59f4273f1d969f815baab2382b28bd9, + 0x1344043beef1afc165d094c8c5da43e793bba98b579f2417a19fbfe538e2cb80, + 0x566dca10a0b92ce177b6f7282493e6b31391e6edd3ff4563277e504c441b1fa, + 0xc9c6b5c46b9877c2eeacd033f184fef497d2ed1a1ef276ba4548d05f3c78387, + 0x1a5f92921d4f34a7445fef0618f1b1a21d68714b80b6850dfb9c834f988a96ca, + 0x14d14e621cbe627022809f07ee078cb2b3fe4fa024715e3f7192a510f1d8e106, + 0x1b6f67ca2ff07a2de58f7a0ac8607c92fe8c4133355938cc9812c32b12b8fc75, + 0x4c3bb7f555a1a8747edde5fd33feec3ab52f53dbbe6ef23f7c26e62de26fa12, + 0x1aca03a3d87c90e7a3ffbb8233149beb0b6809492d33ce3e507951aa38a66331, + 0x2294ab2f143e49a23d279c6fe914d67ee878b3dc54f9d7ff107bbe78ac2ffaf1, + 0x2fb43038c0b4433ac0c9809f4e7d7e688f5c1d3c08f66ac64397fae941e6aa43, + 0x274479867a616c602e87c7521fffbaa85fbeb330128a3bc8c8b8360fb5a3296b, + 0x18a3410d063b4e72016500228d8889dc623201b4c055dab660b65347fb4ef820, + 0x2d6fe8d3d694ba5dadb904fd6904a251aa2d351f3cc11c6d1aa94ffeee452619, + 0x1ec5182518d6d3490ab0b3ff899ef89b61119743188eddfebb254dcd2a787e20, + 0x263a061f3ec9228bdf93eb93f2695fea629925d6dce82f18e6dba79b3be9ed0a, + 0x2fe0300a8196b9a46eb1f7d529b4d4c09dbc58765a42a9f3b61ef7c107bcd226, + 0x862f4486dc03350ea63843db9da09a5a3c3012c0854a7acb75ee18363dc0414, + 0x9ecd01d7dd15316f2d3df72a9e731274dae116592adae8a81eece51a4453353, + 0xfc127ceee377fedc0d2da69617739fe790bae028858dbe5db8a93e3254eb8f8, + 0x15d224160265df8e5e4c1b61e7f9560b3dfc57649f3038f440b64e928bd32970, + 0x110f785f7d04151a37b44935a1bbf4782afc72ad28e042c42fe63e6302550f50, + 0x17fffee137039b42943e6f8d044ae87ce06d5fb1c3e2e51e3009a45fa1873f70, + 0xacb1888950067efa97acad9291f63c05245cde116d7e0bedfa1dd90dac185a1, + 0x22a4abaa581375452fc3b531bd4ed54fef9bbfee016e665e42493f09c393fed1, + 0x25adecd63680d23f87be6226ec05a2bca8524963ddffaf863379d4c81fc793c4, + 0x220ce90ed6442f459eca1fe1f2027e6377e7189e0f6ef43e1cd364e9ca1ceb9e, + 0x2372d4e4009fed5ef65a3641db3c8d6ecb33040fc25989039394481a94b97195, + 0x11926b0acd944afe2030cf0e8994d90daa535f465967b64ab0b6cf69e316a51f, + 0x1229359753fb4a0dc741da84bc9758aa0a7662b314a31fe003474faad18e3800, + 0x2b3a66d166c51a62bf6af2e54897c51e45fd08bda74d5857adfe8fe3e4bc3977, + 0x1e7f4fa362bd86d6927781af2a4cac46a77a19b28c4ee55b2ba0881d2f7b8e2d, + 0x91f7d66fc8ea2e7ea95ec1876a93d33688f9f9d47d3c8b07df92d1554e38cba, + 0x2c17ae7d9af800bd393b5fa0f8b16293daf49e5afcada50847795b87e12b6bbe, + 0x266e76891b0271bcad1644b852ef8de9d3c3e7a53e22f6cf096ef44fb35bbbc7, + 0x24da30c34e49b417e6ce696fef7eb94e67b4d74db6d2d5cdaa4777c2602166c, + 0x4c3d31703ffeea22ef8509edd468586bad669b74c25fc9ada49a185937c2c94, + 0x2265314c66e182feca755f9a0cf7c5c7f7db6b501e010c283159f5fcc5bded33, + 0x1aa1766643eb30f96329fa3eccb67964d510054db9599f5f2536d7c37f5c1149, + 0x107e8da68896a4d3ab40eedf2fa75e025f787dd92799357218e823fabebc8947, + 0x191aff44b7bf99027bb1d6954ca0901c950f7ba8f1e1549475f0f28ac6e72d60, + 0x2d6a00ed5b8ab0055a4277b39d178918744ec5b4e5a392205dd4eae9b4f1f507, + 0x8bddd13ce3e6d0add2babc5f0da3ed9c24e10aafb289d03e968163c44f4e669, + 0x2f0575cf9b7deadb634320f90d84678d771833f9ac9d1b67c318973fcab18f13, + 0x1366a05d3047d5b3452fcc62417343245ea727795fb0d05efb80a75e1e4d7cb0, + 0x234dadc295579c62b1080fd64f340594eaf258b94225fcd6beb10e5efb4d6fe3, + 0x1f78b1c152a40027a2c7b0ac19bff6ede3202ea1b95e5d0af43125a33cea7821, + 0x1532e8db5fd0a6c2c785a0bca111741903fd089d9b73715bf0dd70c2e14df9b2, + 0x9012747fffe05e8b4482f278d35a28c6f58e6d502d69a5f351225225aa0279, + 0x105b192f778c42354f2a979d91b02fd33c52c59d542a128fc08e5d11c96fbd65, + 0x24bcbd8a492f542d2e6faee6c503c9c6f7a67cfc7d8e756759e0bae679920b81, + 0x13e55913295f26697ea8ce1aaffb07373dfbe24b8f41e789e05d8b96c2dc9e2b, + 0xac524f2908d8e1292a18ee6d5ed583c29626eebd03a593db01a61599c286139, + 0xdc402c7aebe3f023ca4b75dd5f69acf8af6607edad14bd806181077e41168a8, + 0x6d687b70f200804cb3b39546609c1ac2309c4b59fc96c7673ebdf2c900d9400, + 0x1e0c2662cdaa91336e10c7eb3c6eab12330a99da8a095e928f73a8b45accc8b3, + 0x14be0cbdb25a5f84d36b415f71ff807f9df89dbe6a9850213a288abde6db6264, + 0x2fc8c8938e2554d9d02e135eb0d2bd251390902e82d6ecb4ac37b8ab6d12233b, + 0x2059f3ad1d4ffa2787fe0577dfbf12701689bb3359647219d84a000e95c62c95, + 0x1e90ed09600b1ad7e5f927ba5e40d6fb87bb537c695d5ab6fef166da18fe7f4, + 0x64fb597e3bb0a3fdb8ed25eefa943f6ca21150b4e029836fd31d63cb81223ce, + 0x710644314ff7d6091eab77327421b8b18fbd64ab6f6756b61ba96d79854d6f2, + 0x17491b622e2f47caf07a2abf0b623896e973647d02be011f099b84af45dfd1dd, + 0x2c7aa4382c1cc1897988dd51243facdbb7d37e8cab2e27a26dd7fb0795d77712, + 0x14695d28c7fa12ea6044e898a6d8a6592a5f111a293624a45dc24944f77bb711, + 0x1602e77d6ee3a46b60aca6ba65c81457c4d36c8ee14b3559966cbea0ae32cef9, + 0x1ab02e5bfaf9d4ceac75f53983bae994d12d0c44a280d7e2df3283ee1f429ad5, + 0xd2b3a148b13d8a541e3cb82d624cb30209b4f58fef5121bb74e8eecacabd939, + 0x2e682ed8f03c5e95d84007e89a92043c968111cffe9d18665258df0d3a6a9b8e, + 0x1428a6b9c8cccc597a9eada39c3cfff0154fd9f5ce4878d9963b89c7a878cef5, + 0x125dae4075bd6f83314ff7172c70f192173a2d4eaf09d887b942d45b7cf7ada5, + 0x273aafea62ef6ad185bbfbe54a753e59f639ab2dff85b1f4c0a28e2136d4bec6, + 0x179314705df4e0b530f1d37f9d02c3a88b66e2272edca161365615999b1cf404, + 0xdc05aa8617d57fdbe30d76d7407add6a2e95fb73e9f942e4c242e2ed1016318, + 0x18469f35a1ad56b258b1e60243c962ee6dc99faf274f02feb42a8a51182652c1, + 0x2f79b79663182739a2fe0c607077163df7c0e9193143234337b9007cf472ff7a, + 0x1bb4d4ae946d5ec7cfb22cea828d263b7e574ea777aa891cb0ba07cb412c2413, + 0x27270b27dc8fb9ceb1c5aa5a49f97a795c1dc652f9012ea2110ac6877df6c20c, + 0x14da35468739dc3ff0110c91ef540be904c73e5d71e5b0b5eda5ec6dcb2f6eaf, + 0x2e90d9ee3e7c2164851b64afbcde004b6c0b82ae7ccdf6f78849fb981a35a2ee, + 0x2b15612eb94247469bd9475ae4bde9780511cacabd566c1e74ba1761d60b6158, + 0x121c521576ba4ae4a05ed2565651b2893d5f704e5c6f0a642c60e50df22c8ef9, + 0x23863fd0801582ee9b9a4c83f3b6eaef83c59068c0b1d4b9e93ec5ec1a0c2938, + 0x13a597a19307e90fb04778f82f2e6780a9e2c4e03cb0515e2cb960c51838693d, + 0xfe4f11040f7ec803ba86cc6dcc6ba00ed7569a00cb4aaf5685d014beeca35a8, + 0xc30eddac033e3f113894327db9763aafd747b32d1344b65ff7108177125de2f, + 0x16449ebb71737c6513326b4636914fdc9f7864c7f10025a09734880d423cd1c2, + 0x267f1aa1162b7284cec8df83403241884bf4a29547e2d0c470f6abc19fbc4e75, + 0xffa65c12b20f5ac05ab035a3b9cf0983bcb4cd0075d9a9e5be77ff9b4f17bfc, + 0xfe550d9e4e3eadc68883a977b6869a5887db153f6bdba49233f60bef77bf44a, + 0x255002f14c45aecf8cbdccc25c25cf16c9c771c653dd213a2ce22e190d7df111, + 0x160c6500540f89b145de5aa9fe944604eaacfcbf1c17550ec91da6078082ce1a, + 0x1383faf37b866d99769fc32b68e45a753f803ea36e351bec34222729356c6393, + 0x240b1af70af648da4ae6886dcad5c673e5b36aecfb7f2e58bd12564c5a77697c, + 0xdf9f10587e99fc6280b6a84f0ab1dcb4eaadc8958518ea2bbd5e648cca49e1a, + 0x26e4261f23f0856aef429a307bafdf1b57335d7a0f38ab992a77a5cca9b50ad0, + 0x145b8482c15986fbc1a4085dab239bf2d5b524632baed39273551273ce1765a5, + 0x25101aa4715ababd467f91767d0cd0e8037741883381e392c8521b08c6cf62dd, + 0x2896258f1d13f8b556b92d0b5fe0684f67a8665bd97747eb0364ed9b41cb2b9d, + 0xbfc25af60e375f1a7e09ec5c0411ee14b52346ede9837df5703420189fd877f, + 0x29a042bd25d6f3aa5df99619a794de17432fbd1c75fa33a1010c1af30cbcd828, + 0x1cd0de72b658cfa8975dce977ccc6b6cd06e4f8f49e620e72d7ea84ff2373c01, + 0x2197c4469eecca78bd4629b5d53bde29a8d3222bbfffc5948052e039f18e3461, + 0x59c6f40b2b1bb82739356c24e78eeb900d1d1057fa9d48289157af603d05dd0, + 0x18ce307b89e3700870c70a6e9460f1aed5169f729d2e75f7e6c7e6d0298fc334, + 0x27c70ab7d57ecf0b8348df89c42e3817450b3f018519673f9f508e5e1ddcae89, + 0x1aad5aabf3751e7d413b8138c2769035e8591227395d0d1ce29d1c5b3b42a54f, + 0x165634b54770542a49ff684eca304c99d9d06315412252bb82a2ce5efe24fde9, + 0xbe7826f267e77ace74a4eb0e10e5268f07f52cefc1d7b74e7a5b82a08c85266, + 0x263fdbeaa2840c05de52dd10fb42817361a189d2abd54ce145fec18cb11b7ed4, + 0x2c1ddd2e896c9dab5533d8400df17eb353a0191b9b97282df18774113657b473, + 0x894b90c18b05d7ea347b8dbe1471fe0020b9d0b1eb45a07b0f70d4b3bd90228, + 0x3056b80856c9e6ca2d92a5bb3ba46c03de22785d58565aba508d2d898068d741, + 0x1b3395901b0049172ec09a314e4a4183563727d32a87767a094d70535336be93, + 0x143e65a2a879b7a35660da4fe2141be33c17ae0e6f1324fb3cd9a1d061a15757, + 0x2f3f3a50c82372cac6815322698f09826210a571a9cd64c68dfec4711a5fe60b, + 0xbcc338d5a9ad15519aa00e89fe52cc24491416e1ab69635a67d3246e58b12ac, + 0x2a462fa9c4a682e118cced65a4aec9212496ddfb5de743729cb281ec3a76a8fc, + 0x7391449ce7efe315f816f0c1c3ad33b520007106ef8d11c2a2463de270ab282, + 0x8cc2bc080753c7730c57f179e38cbf95b95db1fdcabfae0a8d239342fc68c8b, + 0x1ce160503379a007e38ab3cce61d6fa0d78ff6b19526e1546023cb6dde3551a5, + 0x2fe5f53e6a16d7430ec9a765d640bd5de6587509be8bd773be71073e4e652975, + 0x2b9d6359e3de7b25159b8d2fd42c96244ad92bcb54f26ad8a6a10b2713de4d73, + 0x2f730a0fbf24810d49065521296809b50c5e96a6bdc4e3fe44d9d4517a259728 + ], + [ + [ + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x1f930557a284998225f5f4e4dfbcf5ac211f1b12d91b0562ed3d63285d7a714a, + 0x18e8222f6907da5745eeb9cd4a9e62f28b8b710aa85fe729f9ea73a3ef0099d, + 0x180e924d757d0be4066feb146ed56212e38acf9df4957432653f370f905b8b07, + 0x2f7d0715d1391190e7b14a1242b6799eac3142e21f08ca02c21755eae77a55bc, + 0x2283ed8d5e6f9470b3f4f49a771061e4a4fc7dac683defcc0348a8862c6ce71, + 0x21f60efb132b62909990b9f994f381a9c02abc3ccb54c5c8e8c9c5664c6913d6, + 0x1cde82acee60b84424e9bcee49a5464ee05d1cf0b70469208a675635ac715495, + 0x118a24510a2153f818f0a996c87de913587805f16cdb1939d9406941f958e8e1, + 0x164567b0de16b7a5550fca229bac7cb0779524325e4ca5e78a86078881660264, + 0x188ff303194112a7034527cc9dd0b4deb0960c9c106ce115178dd7087e4e8c02, + 0x83d832adf9bb4a25f686abeda9f16ebf53263dcf9ef4311781d09920d094ead + ], + [ + 0xfd547840f3a30a533a994d1fdb3f60ae5073f4484f34be951ee16a276fdeb9a, + 0x4c4061820cda9bf472df3f64d6afa004f1e8623d0a4f6142cca1f19a4c275fb, + 0x107757eb0c0799f781308d83d2e057ef8106f6b656b45e7636181e113a2cdf32, + 0x2acd39e3892ac429ed812863efa05eda746b55bb974694a4e77b9a19abb55001, + 0x29788bb6cd947ea9efaeefd0eeb7fd563fcc2e40bd623ea2b2442b55d98dc5a6, + 0x6ab8672c936070a10757adb45031a5e2922f0fb8b5fab3a4f5e3872fb582ed3, + 0x1db98a562fcd1a5e4496e61264aad5ea3b455f46eabd8957ba671e9c31e5092b, + 0x1c4dde07d0f94d1aaa832ac2f5712d438b4e1804b5209ce55942d7afb24c6401, + 0x2cfc82712ed9d71ff4fdf63ee4ad116fac195794f8d910286c152efd9f959bee, + 0x18b49b773f5799888e9abe3f6883d7063333835b6cdd333580b2b4bf48f3b27e, + 0xb300de5b99c27d332091f8fb0d97cf04a86a51d4d2037788e0d4f38e8f4eab2, + 0x541af6b96524662084d1208d71b6b2a8d66d91179745b213679c2a2bbc94968 + ], + [ + 0x5019671bda026670c7ffa9081795105963f56ce327fcf78451fba2bdb3ac1c6, + 0xdbc22c3e54c924a882c22000951239cc263755dfcb38b27ef4f880e202cb5fa, + 0x966a21b9615af2b7563dfe41b8b9fc06039512dc9c8e1196891eb77f856b608, + 0x17b18621dbd61df085da4cf8a03395e3700269c7df4d98ce4851f90abcbb3631, + 0x12cc274647fc572bb79035bfc3332a4e566a28011f69dd0874f01c56bc44c3e2, + 0x2c7d538b9e6d2b2e06e72f8aaab26dbddead1fef6a740a11e9953f8e8e9ee057, + 0x2f30800c0ee461010569d36b60685a38b02912a020bc4708598854f65822f15c, + 0x116c45e4d88ceae4565c0e94da844eaf2775d5f5b435d94d2d3d38b583fa7841, + 0x2ffccbc40031ebafecfc3a97284bd0f6dc4d45eceb8b8998f1a667bee369ed62, + 0x2007424b129ade2194c73e6e2c9d79360d1360c4fbb8c5f31330f938558b3ace, + 0x2c53d6676d4d4c87d9eaf5d4da08d1e98d103a3388d59a7c0c3de51e2623aa3a, + 0x2cf2c992c02a36334ff5dc851646ee7da04b44eb544ee3c0fadb8dc5eef2a585 + ], + [ + 0x2952c18c15558f29b2ae77fc39e51a395f173a9097db404db765ab02906b27dc, + 0x2fbb1c59e9e8999d91c40f4d44233122ab35ffc975edfb43c53ed07dbf0d9c76, + 0x82046081498eee63c287c6fa3efcdefeba1b5272a77bba9cfddb56afa53c82d, + 0x2a429c2d06dcf34d34730c3af8bc19b04abd652468de5a85b5d5cbfd9c23e6e, + 0x2ef584c3aaeedbbe2b4b103a61e94ed40a97294156ad7ddf0de43b845249f534, + 0x28e4620d210536bcaa42ee46b1cdcb21bf215933bae4eec639efbd51f4bb6557, + 0x1e32b1e2e6b59273a113d609663af6b30c95b36884fe5faf371de3d564213c3b, + 0x18820364804d22119347b728135b409956f7933defa1059d634b977d9d3abcde, + 0x9b6c00a37df2770cec0f1bf62a6aac3bd380c6ce9f4f96e0f0879237ffa510b, + 0x445e26e26f91707da2df5c188baf80ea2f48c703614980fa798971cd8ec60f5, + 0x19f5101715162976766e2b57a58674bc58e1ba2be18a59b07a07e4a93e038075, + 0x6c5df8fd61eca2fb4923f0a46dd4e416a3a3b48c10ded13133ffeab6fd153e3 + ], + [ + 0x2353a60af6bd61e5eac2c9a4263d451fad07380654d4792378daf752e5cc33fa, + 0xb8f40d2c4d28c472085203a0e460af73bbecec3b2b3a63f27028f2ca8a71251, + 0x2c7ecbf14b2d6049a6439d0f29f10e26ec975acc3e3eddb77c831a509af59196, + 0x197dfb64189c09aaef94a1f542d8c34aea27fffba704202d5286d62bd0eed372, + 0x5f9a6a8d64cca12725dd15110f74aecf99dd30e57a7d99829cd8757b75b772f, + 0xfe0def70bfba40679aef8d5a239b3a1b5a52fe8fd7edb754aee2b182d64b66, + 0x1b1523463a45a2982889048681a422c02ea373f8b8c1bf16c74a375d5060c662, + 0xc849d07b1d9e6ecbac517fc19237ff73424a0678f94699b23f76952afa4514c, + 0x2c4036616c156006337771c1e355fc0f2f238e64cbd69d068aabb4b58116886f, + 0x176804ec1cf85d35298351245d32236546838d9b98cf4242d601c7e8e501b49b, + 0x2f5855a876a37f7bbbd6104accfcae507e9ddcd2a7219b487a76b17c525b50ca, + 0x1a233c7cebfb0c6eb72dfd07aa2b537ccf291e84093aae36cc68002ffb83639b + ], + [ + 0xed6a3bd48174e370b4f264b37488b03a5e3f4c0f61cf32d3157ad3e3b86f6bd, + 0x28c01a9f01601bb46417ed466be6008595052f782e46857d81229e64e6bda02, + 0x144022e7e077ff22a2ce3dfe9923107d5aef046d0a1f2cb5f36191ab04eae4ed, + 0xfd3bdb79cad913432b7d3828e072dadc26cf4903d56b8976200723846c6577e, + 0x2979d1aeafdf97988560d4ebbacfa6e2b7f3d026946abbb9d5397645e6e81825, + 0x22ae023520979741e5c58fb04fd25d12dc8f5fcb6ad15223a5da7e0f91c7b4f5, + 0x5246ee7854b2e20e8612da021b30798e5f0d02a5bfd5e79d3f9ac6c79fa609b, + 0x2b60a4d43d12cf31076e0690e931716c47a86e7728c34b2d3cb0cbcf95bbb74f, + 0x41b909a658d136993b3f509a9e9d50138baca48f6b66399ac5c649e68dd3aa4, + 0x25b6e65e90ffbf910d19fe3ae23d037f8f64da9fe3df483fc4f4977ca36a7b1c, + 0x2c0de448a88dfeaacc9bcf2850b6ff4f701e1a538d69098bc94087cc35930966, + 0x5f6d62f54518f039e79aa726bf15a5983583eca4062405400acca58ca9d2235 + ], + [ + 0x21103a7aa20c8d15501be8c23504c6a912c6100c5d88085cc2e42a52302f4483, + 0x23ce8e402939cccf36176a5bd83183a0d54a24ee6cabe4fc7f814dfbf26f85ea, + 0x170403d414148f4681b8213550951e238edc009f46b00693ce3d9c5800fadd0a, + 0x29b9ffe05db2c52ddd1bf0e5c532eefe70497c7df4b97db2f0624836576a6b29, + 0x153891052fca1290fbf83240d334fd4ce05de78adfaa2c9686488e0c47ce1fc0, + 0x105c0b246660c4bd8a6f1b36fc3cff86a2c432c0dc9321cb50abb98a10cd1bae, + 0x6cdf8055439ac8424c435e7e9bea3f0ae93eab171ac383ed2cedb460fcb04c4, + 0x3161d7b94e1b0411fc01dcfbd748a6df3156ff04536b3dd3101f7b2ebc3811b, + 0x25c075b41ea2d827a4955b6469db9d41760faf885f2c6e9c09407ebb1c4dc274, + 0x2fa2af7970e131f7efe3a7c788890ab860f76751e55b4ff634dd46cc4de660d8, + 0xce587066eae0c345c3368c53dff2170cdb081bee52b243a1e6de6d4f82451d7, + 0x2b09de93c6e3148cf7ff5731c8e144debb66ca896ecbe4089d2d22cbdb09777e + ], + [ + 0x2fb232573e85d68c536d100c3a6ea9172884451e677b0d1cd0fb4dc4c27536b7, + 0xdb82abbcd3a1b56f7fc8d116cb54c54fe26243702bd3d57e71f7ce0d470a40f, + 0x2997d92a5e9bc66c84f635e8cbf080eb720ecd4ca3e42c3ab8d088611880861a, + 0xa2a006e3b086bf502c5b1540eaaec14b9c15bf88471cb6d479fb4563f016497, + 0x1b8c7eb04d351aff4e76af7f9fa1114fe45aaedafdeb42c1c23503b122639c7b, + 0x2a5aba3b45e79eb2606b2a5b47eb907584aecfbfc0b4cd50cda1ce4854338597, + 0x2f9a5cdb79645e3454c617d77a774feaf24ef603454c02076fc4c9d7548cc455, + 0x6438e8b0220464039a7b8022f06beaee502c5de269db82f91d88fe1b72834fa, + 0x115a91867233cc75d1c906a42930e93cb9c16afced390cc14435e5cfefb4e96e, + 0xc8fd4ece5c205190cf6c842d1683444079bf49835d5c8b8dfbb11af956ccaf3, + 0x2cea98cc64abd926df963da57f2ef4c434141cb53ac6311b2566edb957982713, + 0x239ecd92517825174f796345db296562223760fb1b81c091b74a6a4a82968a4 + ], + [ + 0x302a085be040ff9a709ad0c73238b0d1e11e1d17409abaa34fc45de29b541535, + 0x2e703ea9af99161acf9949da7afb18d462d85b671656d61c2cdee3a72390213f, + 0x21427b3a9a2cdf1e2e6c628906b21e24271d72c18b0261be68cca44865dece11, + 0x237a9e020908cd0edbd9eae8772350e0e731e3228b892fc5f64fdfa9b9daa670, + 0x2d8125dbef602bd970d11fad7cfe06c3c64f5687b09b960ab92b14f69efbea57, + 0x23a3b23d5edf5cb66160fd2523b3a383142291c0e0ee666682e946b1d57937d6, + 0x1b1625d757786a19a93b37adf7f22ca8a502aa4462ca78f7da2d7c22b37d7f9, + 0x14898babc8810cbc626688531511a8473ed89a22569d47ba586c284e45bd0ae0, + 0x2f8fb37178b525758bf6aa527f25773e1ebcf8e1425379500c8245c741ba3fc4, + 0xe992f44463e2dfd267e6a4a1c3303ea7a1186252efd6c9fae9e5f0c1f6d8266, + 0x2c7ae475d90c475f73c0d29be8889d0c4b8536fee6c0389984bf9e4dbb1aae6d, + 0x2945cb85e34532e3a22fc576703797893ce290d0156430a8dce61c9df89a8bd5 + ], + [ + 0x683e640e6154ef73c3cd6b1d0f0fd86ebf7e292e63fa84cf0a883c2f1faa8ba, + 0x16512c150c1d2fb7235efd2d4f0fad5fdd78f8d0cde53a66bc90206c82c4b597, + 0x24bba58086a78541a8ebfd535c107c36946d78ba6cb26d227e615131f71d337d, + 0x6d349d6182ec30d68c9be010587c707f7e1e175c0d324e6added6337a72c2b, + 0x10924807f6fdc4e9e586792e3ace3001f16bc02e84ada5df51d7bd37243ee1ee, + 0x26635f4df7172107dad6b7c3068d2d438bfbf486471039f9e65a9c8462a2c9c2, + 0x28bf5488a525f5514400dce722430287fe8e4c810154056eb0f4d6fe61091cf5, + 0x90dfcc0327a541672cfc26c7e1370583c5f9214177093010fd3fbf279aafd4, + 0x29a14dc4bac0a4c52bf30aaf6b9b8e05453d0d797246b64732d50f176a7ca257, + 0x2609ff97ef574fd68d16a3de0872c3b59a5b928258dd1469826a191dcbf5bd0, + 0x23238fda1417302dd03ce54607749610292945bddbd587241714fd3964af5f10, + 0xd3be6a5b12bcf1bc705c20c30f320b8881c6c2ec00e857685c0599262a3cf0 + ], + [ + 0x1f09f3fb07f7f6476fac98946b7375095e014b28f23a07ac9fc7077144ac3979, + 0x298aa5d5a44565b75ef68df902d791d01d98a75e822ef553b1761c58d6fdf32, + 0x1fd5a6eba52e9ea1db389a1fc8dd3d0283d737c18eb06e090b6fd2dc88e0a14, + 0xaabba39d220f30604d0c44dd47c3c70de3b79f5baa70a3a7a0ca02ae1b080c5, + 0x230918919b6826faa7124c5bd15d10c036d565e100b696a3be7afaedb2abba6b, + 0x2bb28ef42f5fadab6a6ffd5655b36580deb063ae3081d587bb1598878590f1cc, + 0x21891bee31fb7bd89f0e4422b3c8f5b393299af0d9825db9be73e7b20097923c, + 0x38e0c2e29c79ccf46b5ea1bc589276aec95b74e8bb82e4385c0585637c885f8, + 0x2c89dc7562b91d8f2f7daa209b7560520b6bc62ec631db41cc5edac1fb142be4, + 0x15dc57879cb41d6015da9881f948b40d20f0e03fad87746d8575af009c96033d, + 0x1c674ff2ead27ce002f4befc7ad5f0f5123e59793c0fe21075e819ce56ce1e83, + 0x11e7bc4a39d2730196b6c334f99750de5bb5e4fbca5d6a19eb7fe14abe845dbd + ], + [ + 0x598c38d2e2c78dfe4907c74e82325cb191d52608955b583e5826ebebd1857b5, + 0x203fd2078ab2a8f88b7606543145ee34daeab2aefca31bc04a476065697cabf8, + 0x1276442d9383c52d50fc9b5ac34442a4ec8e9cd7aee6d6ceacc1a6f521aae4a4, + 0x16ee980a2c67de24fa1a34082f11c71b7c45966a6e8bc6aa1a1dbc7ef6a9bab2, + 0x1db922b8c249ff7bf96121eae9d9555ef7770f3dd7b056191ae9ab38a5ccf6ed, + 0x96dd43a832ab68e35e57c98d7b01f2a2e5936807704593ac72c74001383f7e2, + 0x2282e86ade85855d4ea0657c4add20625c6daa90bc93943b59a92dbb77b63681, + 0x28331d0d31ca8675ad4767c490261bbfe5b84adb4ca2c5599a87f331908130f4, + 0x14972bfc85de037b07e55332e6bc5b4f08f39ed4eb8a9721dffc4a586dd9a1df, + 0x6d039b64e82d7975dd21a37b5ee79308f20e82e23489382ec2d176190587896, + 0x2627be68d9cd0ccda3828d51621ba409f9acf09f1a9cc503a29ec306f8606ae7, + 0xc7c9db952865fb9470f8aa1402536cb3b82276d9e288082ac7f83b10bcb6d17 + ] + ], + [ +[ +0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, +0xc894a150b70154ed3c77c170df947769ac6fd8f4170d341613e7adaefc605c1, +0xf784c25d3497fb7f058d93af7ae1a182bea00ebc2806c19377ea19a77db346a, +0x1a4f48dbda22089500b402545867e341b6b6f14bcedd66ab59a1f1482e4f2d8c, +0xf61b0bc7dc5911ba7d353e201a1f480cff116ab06d9e735e01889b688078347, +0x15f5f8ed095948c58f2cb630b9b892b1289429c3c6169f26d4501cb4b24e7d72, +0x2644c801ffbcdb796abf1036e3a240514c45708f0bb0616dc9f5475ab7ddf80c, +0x15580d2d80baf18dd310bbce40e0447c78518aeabd02fc3d66bd0f573c1b7b4b, +0x2103a7704b61ecef423c74fc864f57077ae9e68fedf93c4c24b3191c05552e8e, +0x254310df353b2d1c72076f34db3ad823aa35b7fcea7124714bd5243d90c788af, +0x23c2a54a64588d3672e1e11e0449fca37349013eb30472982df8935a727808d7, +0xe25546d7af425b5954185a669c63c9fa25d3d269e036e2770451d2cbaeb887c +], +[ +0xfd547840f3a30a533a994d1fdb3f60ae5073f4484f34be951ee16a276fdeb9a, +0x39f5e3ba736458d66a7276a3f7fc143f4d2e10cce779a0288fa042477fa8111, +0x2834c6a4b3a7068b2959204bd9df5f9eb21582db300ac6cc9bc06188814e185, +0x365a1836d0c970acea6a65b34b4018ffbfd2334bfc29ea050300fbca592da7b, +0x7b2fe7cb2612a4b8ce45aadb192514490ad985b31686b75cb895938a99c35e9, +0x4c72c3e92bcf3c9450146921952051dd7b932e045c56d2b8d1225c557a02fa4, +0x18d459655484dea4af5de8922eb66fae69bf0b742ae678e6ac5ef937fd23f145, +0x28d575bf09788e6c9f404c4f2a4794c51393c9fd263cebc2aab4f575a88c1ddf, +0x15a78c5f1d6e0176ed4e931e25aa42576e7d172bc263bb5b22fbe2a1dd096b76, +0x253af96dc191b1ddcc7da399cf751f0531e2db5cfbacce3efccf23e9aee0635d, +0xbd6477a4e98ed1b6a052a7fe6a3d111fc2478b3817bd7c2dad8b1a813dd9445, +0x1c371f42917639fd59992e6dedb5a144b079a25f242578b21baa3fd6fe98b51a +], +[ +0x5019671bda026670c7ffa9081795105963f56ce327fcf78451fba2bdb3ac1c6, +0x1c9807d9b8968d8f620640d590f151e0914406af2136f902521b8f4da19cdf64, +0x10cbecac3303667992c537c54deaec58a34528a2fe041591a98e64a8d6da5588, +0x1bc32304ad49812a051886f8904e1af0a76149223fe72e96523937f339a5d9a, +0x15dc91d6fb987bbdca99c78dd90a57b386e9b9ff7e4a4faf70d5ae18f431edce, +0x22b26a76db2dafefccea7be76f0e139a0c568e92a447ad288257ef310794df28, +0x1c76650a0527fe929be54a7e8a47efc654b515547f9cdcd58c146a0bd11872f6, +0x23d3b9deecba2482b107832457fbbe5ff670a61069cdc34a6470d2293471231d, +0x2b9a6b170ff9ce22246aa0b5091a7f33ac5a1b39904b61f0a7360c435feaa593, +0x316258271c5c2be65d5e41b0bf6f9917c8c60944d1be7f60891236cde4c2676, +0x1c67cb4dc98d5f02eb96d20f1134177396cea0f4fe4c04f856b0e2dad8e1b56, +0x25a8f4490a5df4e1eb13e2e146e0deb4de3d633d11bc4a540c5a6a21934b94c9 +], +[ +0x2952c18c15558f29b2ae77fc39e51a395f173a9097db404db765ab02906b27dc, +0x1e7fcf514768abb1800ff4f4884ff5bb6af1ee7581b96e2984c2b2c4033379cd, +0x21828d603ee0c7651c0a3bf6b18217e1fe33f283bfeaa1fa9ef9eea3b2c32fba, +0xde712fca9d7df5e0f67d3eb731a53dfc7d1a7cbdcc34411f6138d6de60fa369, +0xc58a3374648de30ed82a9ee0f4294d493710fe813edfa46b09aaf44b3ce6d86, +0x14be55982212ae54cb8f0ce42a162a7ecb440a4c0c4d73189528e4b12d34e5c8, +0x9da7079e3ff632329ed76acc28bcd293d69f9298fa25b9d5231f9611ece2c22, +0x2d865f77a39255aea1b29c483eb4a3acbe7fdd909cf17d91a0100143979a18bc, +0x2a39a308231582d0a1d003b5244fbb85588de1df3ac866dbc2fee6d1d8248c0f, +0x474c582c59ef66cb29b984f6e4bd97bfeb5a41c6485aca67dc0555ed1eea61a, +0x65cc505a691aefd234e572640f6c731993aadfdb529a9aba4bf6377ae28b69, +0x2aaef152c413b4ef991bc228242822e2a6377aaeadc7ac22e502def3d839f2d0 +], +[ +0x2353a60af6bd61e5eac2c9a4263d451fad07380654d4792378daf752e5cc33fa, +0x28d0997942c3b3b0a4ae3b17ba382c8fa4e1809be0ec701d01501f142aa401f3, +0xecf00f71b1814ced4f6525c4765846440aa3d39e7ba0e4e4610b70b5a38209b, +0x1258d5a4d495bd4be6c704992ddc3e89f7ae5c6cbd7430014491fd234be89fc6, +0x30513cdc3149663999036b87af10c4a183f71722572b4d958cfea9e3dca618c4, +0xc658aba90de155384cd4d63e285ac2d004cd95a2e95da1540ef7f1237d851af, +0x13bf5098cc05b1035e2f22bd47ab4041d8adbeb53c40aba04a75fc5d2435df46, +0x2339c682b7084d04d3c9b6072b20b63b12003e5c52043c6336ba222397269a5a, +0x2cd36c4bd8257cf74834663fcc1e38be2c3fed64f7b568e1f0eb0c269b0e14ff, +0x37b5beeecf060cb73d6e08ebb984eb5d9075b31b128fa3e5234e969036ab5c0, +0x118fc51eea37540b35bc2ad77d91af14dacc152f86db157ff4c48db58e325225, +0x29efcd78bf5b6b7c9811b6e838f5563b349606a1959751d63d28fa4c1124b5bd +], +[ +0xed6a3bd48174e370b4f264b37488b03a5e3f4c0f61cf32d3157ad3e3b86f6bd, +0x287cd855b94877a396d39c336dacdb13452eff5917a877edce1412b7ab24ebb8, +0x4f06b7fdcc319605d038881cb47f61748f1e9f14d47dcf824abfad47a73bbca, +0x4eef0886e398163b9f0009c8204cf2d9b0a4a30fb019b3cc46cca6ab3ffe666, +0x2fb04567ad27a42a4ca2ea90a0f27660e1e10acefe62de96607aa26583695932, +0x1f1c7c6bbbdecb7ad8a2c8a91b983b075f4998fc620c36e28e2b59077ab57704, +0x78a3fd180d76eea922e4237fd65bb83ed4561b268751a20ec97d3e0d7460d27, +0x11ce8d6554294777e161cfd91ca86ac2fcf71bea4228f8aea857187d579b606d, +0x17607b33a1043bcf034c42feab79507a82488808f988fd0e13f2e2982ce55e0a, +0x2c90418c775ce44e34d9de72d06a7c2c9cb072518bda77828b1e82fd1d19525f, +0x1cfcedb53846d090e72523914eb33d6d2781bb18ff1a7c885eac1326e93f7a46, +0x2a4d8464358084800c89f6fbb98bf69d589164f9a648f48d3a42aac8c5cbf177 +], +[ +0x21103a7aa20c8d15501be8c23504c6a912c6100c5d88085cc2e42a52302f4483, +0xc783dba69038bd1673bc3bed51afbf51ecde783af95067c14de12f49e49570f, +0x1cf80bf06f3525aa85416d6cacd0e8251bf1b3a771be49253b60ca83f49b2369, +0x1b6e663aa128709d83c7e5a86284927920043926cf55678bacd8ee0322178495, +0x6146f62b14c25c15ac08d1756f2302395505138a4ee1184000a38f4c7f53905, +0x1c5eea7863fca5bdfb2f4a3dad7e2a16572998329ab695adecd136fba4f4063d, +0x197b13f8af70f642e878063aec6e21ba8978ef2322f2d64bb512ebfc7bc2c7c2, +0xdfce2c65e220994dd2deaaef6e04537b35ee47eb92cdbbd7c61cc6189ad3f5e, +0xf4b71f3763666a3dfce7517b6746ac033b2392ef742470ff7365ee5976bcfcc, +0x6fa7b6308e448573f3fdd11a2ae8e44d33c3d3cf0d9ff8601df20c55c6aafa4, +0x2390d163c2c0b5d461be5ae1f2dcf4c38c2aa514cb22b4b5e104dbb6889f8a9b, +0x21c9120f90988cffd032feb1aac143901de9cf42ea3cbe83015e9275cb67907d +], +[ +0x2fb232573e85d68c536d100c3a6ea9172884451e677b0d1cd0fb4dc4c27536b7, +0x266913da539f40df5123e01fb748b241795f1aeedaf1f7ae3cef0e5728d23aaf, +0x2f6910e50cc8a14ddd99b667c6255bf66dfb3386e62bce0d74cbb47419c31572, +0x24fe05893f5e7aabb44d705fe83fb319d29b511eba00b2705561c6bb0afd7b37, +0x1ef5275b46a65f69edccb39f50fb90cc578ce4e519d54c8e61c31e6ae0710a45, +0x137569526eda65a31fefc352a005bd0b10fff52cc5692edcbf46cc5f03538ea0, +0x8552774a893c4dc375ee4efca4dbb742277f07d8980c54581b5d4d0dc1b7688, +0x2d9b07507a9df2a587056f988c7caa44693a118daae6660e160561d276c83482, +0x2c90b4ad79e2316e7986b75730418fe5d2b1f252e77817385d78ebfa34710afd, +0x275fbe17c666f61f6cf5484db2e52083e856c718ff2b8f4d4e17f130d2989e9d, +0x17f57c813764e728dd240398690408ce71dc8adf83e53f5257ac34b643a3ec15, +0x2700ff01dce092807c3f143418c11a2f9db6bee6f478edcf7145d69af66e13ef +], +[ +0x302a085be040ff9a709ad0c73238b0d1e11e1d17409abaa34fc45de29b541535, +0xf259a3b7e18add912cdcd8674b0f8fa910fdbbfad967bd816b33c778feda3b8, +0x1e43f0a896764c42eb93be791fe26928f91c7bdd278b7c810a2f588268314b95, +0x268094abd638ee0145279900f8755e55e1adeaf2dc222f402d1f08ea4953abb2, +0x2e1bfa1a1aea7b44c84b866d9e7445e4acac75f82e0ea8ab03326214c84faa0f, +0x2e1e2e2f2065961056bb63f04c175c1682eff3bd9073fd7fd76e7df0e8f12d47, +0x3a2adbca7945b9a6367799a20c37944597333320cd815d054a5794f68460c83, +0x2ba338308820d232cdd019154fc49774b0c884c7f82b9aebce6ea211db294991, +0xcfcb2e3744279efac866e0228c1b3464a4048f4910d17042ba1a6b8cd12c8e8, +0x24cb3811355775bf9bbe6431305ffeac61c7de7c629d9a5ef84d960cccb940df, +0x257540e571a74fbe3ec524ff58f183ee0560d506a8d10973d77e54c9d9061161, +0x2652e1e037bffec0d7be1355de11170b7f916d148a7c3ee3ba8fa44817d48fea +], +[ +0x683e640e6154ef73c3cd6b1d0f0fd86ebf7e292e63fa84cf0a883c2f1faa8ba, +0x10017188ff4a2e0e9b05536c8d07e27d0f194cf0689d834af2be2b93ecf20ab, +0x2afd3c4028b2ada5d194c593bb5e4e2710cc5c32edcd5865b59d4c7ec037e251, +0xebfe1c74eb49cc73b0f6c3f32f096c2fa6288b0a04823e290cd02dfb5e5dbc1, +0x2be96b6dc6b5dc0f78ebf844a52f6c1d50562238dbe7b95c47a2ba4ebc0e1c17, +0x2eeb27f0c5a205ead76c92eed0ac8a112c171711b1d12d1e066fe3527174f6bb, +0x131560b779c80ad8cdd22a9c3ba80290c76de761b1dc6e788f7f9493f84d413f, +0x7039d5dc74b4dd2f6a0701a3179b502b212c3a4503557e6e8af0193f07a5669, +0x16b1fa736396549a38076cdd9df36cc3385540ac1d7e42c79aa0c9cefc66a65f, +0xf5008caa5bdfda3401446482b3ce891ca497cfac4a24ca2571a02a8ecd6e78b, +0x427946475c0460b0fff4ad995eb4a9c608e260007589d7195b5cfb892bae4f5, +0xad2c3c083a08091a9566bf29eb7506952d2ed27eda2fc0f51894b5d2e28aedc +], +[ +0x1f09f3fb07f7f6476fac98946b7375095e014b28f23a07ac9fc7077144ac3979, +0x2bb007eb9685bfa373e688be53f5d6dafd6f87413c9805d20c579933c6ab1124, +0x2b22adee2ededd40c3dcc8e1b15d38081edf590a9a7ec2eb630cbfc5292f238a, +0x6ac8237c50116ad33685d84005ae724cc52e0ff4ade0d47b194f7923231d67f, +0x217cef9e11c01178da427e2b9f7fcbe4c1f1525d76d3ba7c8850191545e58295, +0x46e7d8895837a4a02894e5d6f3ea8d51adb0ad4897434ab0d0e8079253f2fcc, +0x1f478986f1820203e99247b23f9ae06526a085c84cd31655f82c17037b1de5ff, +0x3a1fee4f5ef14a50af278a0b62247a6669570858ac9b2074df28b0a4e9303ab, +0x188a23c2b448e79af34b9b4866c954e698a6163ab9326f25f2dd746cd1347d35, +0x1cb09fac676323645d322c13c676eb4645446638d83fadcb37c4f1788acc1252, +0x263d998161f060aee0e6bfb95f1974efe466f739715e92c278128c7f18ad5e7f, +0x2488b89af9d856ebc2f9053be37e13f9e1e546146198b764e0e0ed784115d94a +], +[ +0x598c38d2e2c78dfe4907c74e82325cb191d52608955b583e5826ebebd1857b5, +0x27fe7a3879727f44da5d035c1ee30fd12b4a6d37a488981b4903d9340b67b7dc, +0x11033939341c415cf31321211e351744c0831403f53a65832694b35adfea49cb, +0xf47bcf189e8e4ba1b486290d0c9ee89ead181850d2ff29b97bca91518d8c2f3, +0x53090370cc10eadfa09d586810cd0da5ed707080999f1211f0094108e1b3d57, +0x2e2c801404eebd30297f3ec0ddf5e0dd9c1e0aab055268e647c3fd4712dfc84, +0x203f12fe19f06faeaa77bc8baf4983c763081a7af43dc5e7bb83f789eaeee5b9, +0x18837bc92a8af3d37214cb2724b4c8b904e641660e5a48f79ae4a49a7bc37ff9, +0x9f0706eab57f151b23e4b968ba0b6bbd4fc82700acd601333382757a15de2ed, +0x1e7d6dc15eb4669f914899901e7deaa91d102a4e4d569b40b9a11d1241167ef1, +0xbc8d092c5d38d087f9f34faaecec3a55ee916469ff5e23e619b73468ee8eb57, +0x2bfb96f78ef7fe047373d118c0aaa0140ff43e5dcabda257cde23856a654b6fb +] +], + [ + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x2e57ee9089adcc51f2ec7d5fc42821e67fdf0a2f3d1add870823002a1e9ff4a9, + 0x2346c226491dde21f38b9eb1be8c16084774e9dd941895eb362c2bf763050cbe, + 0x2c294fa2466a0a9f1f89b1af5bab1ed3b86a0ea730770854684c754750efdcc9, + 0x2519e073c3abea02f7784cd8c841ddcc10d65507cb4e85e8df3bf85a8e41a70a, + 0x21ea0bdd27e0b8b71b91ab46798b907ee094cfaca4c68ad81f9c0c107e7a83a4, + 0xda23ea74cc325d3922665cba17876a643c4f6ed46f9813ad0f403955757dd80, + 0x1207beb18149148fb6f50f1090b05de32ec5d438fb30604f4c63c237a8cc1d55, + 0x1c357f783a3df3f09e57ffb971a7dfc50c1145da9f3f67f323b4742ef3ad7f82, + 0x234747b2d98835ee8b90f19b5ea03c13baeb410f21211383ddb20248608c5862, + 0xb38e11da34730bc74b7f3add58779f2e0bc55734962a059306e4b950276725d, + 0x14732e1bcc452fb9fa40e72910575640b674bb5f90353a52356a6133f26cbb9, + 0x197d6117415de8855e11099ed6c9c4d76433d39fc7f4cc800d5beba27dc7b40e, + 0x2b3a311741f8b94d8255d87810649ef6674c7a6c7711a83ff88f2ad9f7e23c53, + 0xaff38c1f5500a4ee4949e5eef338372179779bb29c95142b3ad18efa9e673ec, + 0xdd0c48ff292bc764e9fd84841939694a761178783ba99381df579cd3385d8dd, + 0x723a053723b6cab73e72b36722bfc52c957f8c7fe0322d77348955575e841bd, + 0x25ca5081fcbc5b5d8b808627af3c9494e0ef74245f9aa45419d3c400dde893f7, + 0x2df552ff14232529c8216996f16bfab8d5555923d2e4a53706da66f4bb013969, + 0x876f56eb6844dda9bf30ab548c8f0b3c4127ebe7fc31e1cb27e3ce62bb940b0, + 0xa8f10d1b35ca9268bf4403635f76f1b9ac2e39ef1b5c9e6d8174f4bcf095df1, + 0x1212b888592b16b273c55c09e887270a15efdef111fb3f0bbab6f34c4cc24d81, + 0x5f5771bd30e0b5160466f322ecc23f28e563a44a80a3df85eb30b2a6da5681f, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x26bf7fced0bbe938cd67479fa2f03e67cb8a775892e972ff4ad493655237bd8d, + 0x10a49b9136eea6f2c3fc79d946f8b8fd64854ddc3a964c57462ce17262ad7d93, + 0x5bc772beda5709a6fd33b3625682927678d5d7db7296f5703ccd7e40e0d8dc3, + 0x15d73afa88e6fb1b74cdf3ea97c694ce695fd39695ff3b7266371d1870f610c4, + 0x20656f69e483c5b05a2c5e26aeeb9f30d17b01054be5d002b4c312a32df35daf, + 0x2629526c99e13dd1862ab8d125a34cc68db0f3bc297d974044668daec9e567de, + 0x1e204bb473dc75bef5f17f5f828e521f657d8c58db1f4e096f5046589275609, + 0x2a4fc3c7b54eebcd023dd0907ea97d73cefc2955a5a8347bfb5c41cdb10fb1cd, + 0x374b0643d980373a12d798e8ce0f9e016a3b3d9c71e56e0b979534aabc3410a, + 0x2d54f4a821cd3a86fbeaa914483d0fa23a7cc04a6be217b4144b668ae70770c9, + 0x29fcf234a9344cc6a8541f6da7b2ec3b0cdf256408c362bd72048d808e72893f, + 0x4254caca99daf3eb34030e734085eb2171f7346ca2e9f43ae8f61a4ee43c358, + 0x2b4c8db3065c297d08b7f1cccb32a84a4bbe657c16ab0d9dee4bfe59465030ff, + 0x1248ae908fd75fefc42b13be685cade6bc106684ae4a4513ad415029374ae02d, + 0x1cbd111af62201c242a38f3a1bd792501cfdc5035c71961c29199a4a7167edbf, + 0x2eeba2b31864903d017a3036f11985a8361caf73d4fdb215c5552d9e477a7a52, + 0xd32eaed9cd5aba29a1f8cf029d022f77f5eb2011fbd7b8bcf442df70261c724, + 0x20971ff3e27ffa9dc609a839e591d688d07dc636d2cc79ce570c2e5b79f63b6b, + 0x2a8bdd4b9b1ef96bae00899ca737d2e1dca4917679af1c64f62677d2d626e314, + 0x26cfb0174d91280bd05b4e9553c044886e8b8c8b30c36f4316eff726808ec638, + 0x29f510be57ad8e8a7358c0697b8f2d761e7e6237c8aa2ee452d645c4fb5f3548, + 0x1c1cbfacde1ca981ae5f91b44a95f4252aacf086637ee431dc81a89d4db6b41a, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x2b7856136f545d69ebac3c459451f28a2a53aaa144ba679023b2161887ef1250, + 0x250c047260e50160cd6586bcf0ea5180821fc71c3788567481a78e7c8b9514b1, + 0xfbf82f8a52984b9d4153dd6e78c05163c8d4720915c19767cbfccd0c3973488, + 0x6bbc95542ed85d6012d232b16d3d01deca662a0f61bcc164b6554b32e61f31b, + 0x28186714392c789ae58ef7134248ad33a5f12470e416718a3354f34056fb12ff, + 0x53afba658da76de92084f426da8b4c0330e7725be947aa266b8c2f9c0c55c4a, + 0x1844872b8235f851728c66e0b29d5cbf1cd0a0ad5ea4885b2c9967508965c9b1, + 0xb09ec5a6d9b68331f53ca5fed46443c6fadd52ea4d9c4640de3fc2940c0deb7, + 0x638529db7cc2182751ea21241763d10d34cbc099c578b2603cb0d0c0fcd89cf, + 0x5d066dcaccac1ac0448d43671f20833fae00c106de7fe28c9803d7715feee67, + 0x65da2f374618a50e6fa3a0164160b1e6af42a76e9b187115b330d60a548b3af, + 0x2e202380b8f6d90705a135c42066f1cfb905077d39e7a02231a740a3262c1e08, + 0x14570c40a4e7ef1c096e9d8fcc0a46cbde32dbb57916695206ab03aac2e82f37, + 0x2d87c245080329821da248b17456f9e7c106ce8a803d3d015a8bfbf952897c4f, + 0xda8c6fc810ca1891938b417de296864f3af15c28d6cb1d59e2de28ebd010fc, + 0x2018992835e00507a6f2d97c728ca059eb76a7fca5237a36e9aad99a61265cc0, + 0x2d9099c975eb32f31f10f807baea25ddbff205c624a66a4966aa59bc8aaae718, + 0x298dee77db6b29e44395264887603d287c45850a18582a8ac9bd09d292882344, + 0xfcccb87f04870bca6382244b43a0f7f92d336e3bc4d7e7ddef48160e2de989f, + 0x1297b03aae9b949e9a5186975613ff59bea3a058d34baad1b3c15178f19e7ffd, + 0x893a222f29077408802aa74dc37c833df480b350eb1ae31eb1b9f9b20b3f02, + 0x1231b1b0d91bc7687c3813b2da32e7c71fc9189641ea0dbaf1556ead8f36182, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x2077a6155ab34ab05777651d0151e0320005731dc875986256e103209606fb1, + 0x11a4f3347aa9f08e59856002487fe97a4ac16dcb9a7962d139a3b80ca952809a, + 0x146016f8ce100f6cdc37afd22f00aa5359d531ce7179a2fc691fd12b00c12d3, + 0x25045870f9da8f4c97e11825c52cf4ce40bca1271ddec4ed01b774fdab83886c, + 0x156094487d4626cd97ecebbdcb8d41d7e70f28a6734dd3fc3382765ea111fd63, + 0x24ade6dedeeb900110df4f92bd790ebe1514d4b24bc88062d6249eec85805471, + 0x12ad265f80d855a7adcc2ab7b6bb9f49b50287cbd36e7d9e41860fc6596734ad, + 0x2f16237203d13c693faa6da2d3162b25d0d1be895c8026cafdeedacec7d7c835, + 0x1868f1766d3e2f9bb152b15a718ecbab287f6d9cd2e9bc5e66423b5bbc76e43d, + 0x128e30bad26f11c3be9a689a10d093822b5d2b920a1b78ddcd7df1a8bfca5d60, + 0x2e72c3b1f6bd3a793b27cd802532d2768deb9668ef00490a0716e95431abbc5f, + 0xa3e8c07a5a634ea815e1f57afe9494515da623e363a408e505e01471c5a2bc4, + 0x1a5c7a54a81fd93762ce79db6dc604f03bf519d683cb2702839662e69271bd6d, + 0x13222674c9603db4a5e5a36398d24d77543ac79a4a31db13b48c9a1998046035, + 0x333b7ef8d75e61e9f44ff11182db70311648a7b78addfe4f2144291ab5987a5, + 0x231ef3a554066132798e544505b11d50106c4406a937c9702c7bde44457d4f47, + 0x3016482ccd1ff28db55d6532420e95b9d3c66d1b8fdcee5b45fd94a4ad77088e, + 0x284acbcd8d3b7c6e7e7fb246fa9b39811c045820eee55e57e68d7a6cbb7f165d, + 0x17751244cbe20f816b7490b7346b8ddaeac1635588b765fc0e7cc337546999d5, + 0xe3b27a81103dd231517acad6c69e41fbf488237d0fbee8f0d652ec72bf09a21, + 0xaaeffcbd016b27891ec8c80384a7356211b9996a5cc9adebb24700a976d71b7, + 0x118f45236c875283cde478df3bd4ccdfed53d087ecf8d85d24bdfdc78b4018ca, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x2cb4a528ebaecb5ce5044e609a9ec5f36057185a88022e8340d74cf48579595d, + 0xb4aeb2205324cf9c91474b3909faa82059ace7d53f4ece6e91971c11d212adf, + 0x2e879ff17f31aa36666dcd42303d4aad9f55bc8d55ddcd7b8c54ef46fbc8e66, + 0x1bf5f6555edef79bb094218b0980f27db57f9709b63a9c94b18552be085a62c5, + 0x20a3689b70840d755fbf88c8fbe323fa7c7c5aad0e8923a165370511585f07ec, + 0x10a50b432864883bf92a5fb77e6003514f43fe4a5a1c070a932dd8340eaee2f3, + 0x6162a58c2fc725a6cd4746c8f229a99f9616dcfc54014a2c41e97b9ec1eb29c, + 0xa12e5fbbbd66f0de0d49810e948220591fa478abfcdfa1ab0fc5fe861b2140c, + 0xb899ccdc1131b112724493af11636d6421db516a59e8fc7f6e8240bd7581bfa, + 0x12506c3ee2d15b082a2cf3111e9bca3d255a2aaa48e16eaf5130461f5d8820e0, + 0x2135481566f8d976d6c776c65949849e7dc5a3097d8a7570240223569350397a, + 0x227608e1587276aed4b92b8c602d81fc32bc957826e2c4c83d8e82a46d8ab68, + 0x1f4fc5d8d275e923bd82f8f2fac04f63bba4fc9558326ac9ee895fcf682b158d, + 0x1de5b21d942edc83d8c79bfea64f54e681143399bbcf58d4b31c8c9d671355f, + 0xc8d9ae8381b7de88ac2894407c8158fe09fec7e372a4548cc0dba4d9283aeba, + 0x28e6f24ef229a25016cfaa7e3007304951e75ca14e8eaf7b19c7e1df58033833, + 0x16c93e94d5ec1faa31dbe2a105286d839588fd1517dca2e03d6b01d381adb9a4, + 0x12c51f2640a3c05726d08197e01fabf7d5da91671d33e40e00f924027ab24ae7, + 0x1ba9324d77e86ff6234db66d6183912bfe23527e2c056744231d99982d1cdedb, + 0x6616e7b8b4f34595a4591bfac7429663b852e626d20bce6ee7805367987d67a, + 0x2b291b00aada886311dbd8e92fa67673a2e9061f87b43a3d4570515dbe9656f, + 0x24bc1c978fcf44441f251c075eee52c7b0b733edab05b4d2081a4b52ea798fa, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x258a9d2af52b4fefcd409d763bd8e406c4355a9c488878a5a2c282adeafa297f, + 0x2fd82f70d05f4bebd46634d329f317e76cff5149a81424d1da18580f5c1eefc2, + 0xf4b503f7be48c09319c5a9b034ce2dbf3040873c284ac09f254f5ce86e88f63, + 0x276d0381d413ba30b831d3fd4a292440091a1f7f4ff919fca4bb2b2c900c1115, + 0x28e661e4cf942f9c9f95c503ad1d0a2d078ac4644c5dff369d5543aa7c48f798, + 0x2173c6794694634cce267bc21991598f3debac70920c9d8775947bcbe3f51124, + 0xa3fba241019270d5cd8bcb540899795fc593b5dea208cf016a8af970cf7cc2c, + 0x20fcd9c08eea8de9d38dd10180e9622d5e7c7493d0f8c511a4d2f9e5da45fefb, + 0xebc5296052433f86416ac17583ef06db0b6abd8d47110b6fc40bebbe02ac291, + 0x1d76be7dd20256408dad6674c8d0e51d5a5a5cb8fac79067d3796456168d002c, + 0xa94d77bf887daf01ce54f21c6891f3a9fe14faec2a1401fa3ee22a0244ed155, + 0x1174fd29cb4654d093226766b105e7ce63f0016a0bf790d847522e906c357a86, + 0xfc72bc5d051c4abd69d91c14cec4cdc87fb115049f1b08aa482f7ac7d7c4e2f, + 0x845158555b18fab6a2be184849b6569c1530d836d9ec37f9e4e14c2067420cd, + 0x28220c506fb21d1ff3ebbc47c2c8d766d427a30b53a3964ba575a21021d8b9d6, + 0xf45897a8f2b5c4214db423321f9763aa25692e0c05d46e9a45e5253aa696a20, + 0xf71e156500b67e356c98999c688c8b2a354d0537660e0852bfe74d038a4785d, + 0x1b933d41cac25dfd0de679e86cafc7d13855e4871d9b61e119b04d5199c09f0b, + 0x19287775fc90903925ac37f60e269bf68dc05675079d212bfc9faa6ff6a49821, + 0x207b6ae3483a8ce2bc1b2f428c1ee240acf3e1ca010f5820b0655c9d8eb868ae, + 0x25d71d41264bd75fd50528062bed8223a243f25d2768169b343334d708740ff9, + 0x2eac8212fc2ad788f72ebe8710f3c6c98625e52894645f3d714ac951daf2031c, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x172fd12d4e03af148aed931034e7060af7b8e8546e9e4e7935a32fe7727ae3fc, + 0x154dd36eb45f530fd949b85233eb745aedb76297c33ab036bca6f2eecfa030, + 0xd6fee6e12761c3832a48a89989abd5c6ac7a245be31dc258b03c12cc30818c9, + 0x1be1815b17dc7aeca4440d5850f787c64f7b251ddb137da5319dad8d9025fa8a, + 0x2be2edb8867a2c4cb3fe2653db4b526e7edabc44418341fb708a6620509b8bfc, + 0x6c0fe57a444d90391ceb5a94ad1de1443bd026cef8763daace23a3b701a5cd2, + 0x1544a456bd7e736ec88816982cbaeef38530e1c8480dc59bb74ce844de7ec438, + 0x13dcec7c410c82a7cf03cdf661e4c477cda63b31d34274653980cf3f6f04fe70, + 0x28832482d1891b799b37a9f34f26a72a8ba4cff953001ad0581cd4080d039492, + 0x1453cd3bc8d13cfcfdb0ca235673e3fe47f91772a386b11b3108faaa8b04446d, + 0x2948c35a60690dda3b5dfabbc2cc392c585671d64ba338f5112d4ac46720e3fe, + 0x15bad7a6723fea31ca2cfb8b79a656a16e6020406193e22d51897bfa4f5a2d0c, + 0x2a3eecdd1a4f9ba57ab6b9d31a359352c49dc129d68d9c509a74af0d1a27a25d, + 0xd1a72d9a9f731b1988ba20f99d8b3d81572f27035d9288d8bbd3685b288f94b, + 0x2099ac63775453e12762b57075cccfc6fd9574a65f15bac95091dd9475351a60, + 0x60d681d211c02f7909fa329f6e05dbe7455ad5879ac8d3d191138b05d207b82, + 0xb751b2674878344d13b251440475af9b37154209de0760456b1dadd1bf90288, + 0x12c11a657f6024257b1d2e79e5a9b76a1efbc3c3fdfcf0392c063086ac58a01a, + 0x17c91cad834837b9a48c46400d3e25e1a9a7154c8fcbe0115452d3d23d265b, + 0x1fc3820af6ae6515fde45a315961e27549884e2b367ff88b4ed93ceb05de6154, + 0x17a167b5b9014ca6330036496095ad717f6e37a4dc776aab1b82ea7fdf751ded, + 0x46702f62b69daf94a105978608dd2c3a8daedbe7823e8f8275c8cbe16a97dc7, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x1c44223b01de8fbda664ca95848b813295f013b8c208c88e9947d3fa8d244cf5, + 0x25c7179c48928fee7e9caced6240b851052322c5820ba2bdc329868ffdcc17d6, + 0x1958a68f02408107fa1e5de776901270181b3eecf421c6aeadc11866a64e2b55, + 0x17ad9adfd56f8195f4cd55cc87a833e9d6a12e091b59529d00ce604e99307f4a, + 0x5638e90a5883705652412ca5cf9fe315bbaa74743995b600072dd4be5f5ccf0, + 0x2467cf163474afc71287ec56cd6d8c6f53479aeb3fa0dfe5f5129db4385e5ef7, + 0x23427150e60b6fc48b7c8d5140c07d0f97f81f4397c0959fc851c88699c8f02f, + 0x16f925f73e091b1749ba5560993157d7259fff13c2010e4734eb77e7ada60aa4, + 0x2dfd7d6796e20ddac5fa12f1e533957c671fabff0c8c74bc5b8ea8ea4a4c87ec, + 0x664c8b4ddb68209c1253e424883a0fc059fd49be46a468ffed7bbb2c8978eba, + 0x1f3ce48c3ee2922ba46f2bf0ed51535e1d559d223b489bea2989116d48e7bd25, + 0x84ae17ff7f684885a4f21d24613d733fa2de7c694722611fc1e86c144618455, + 0xae2be5c975fc9c57eeb14791c5234c2f3e74c8ab151d4943fb98f4391888c11, + 0x28ae3fb3896a81bbc583a2715c9e2193209c79be2a4e9a894ea265010fdff87f, + 0x1a66346aedcb602f39974b69bde3c83fc72944ac6c2dd32a32ea5b3384b4173c, + 0x224a43476e893bd20cae3950ebb698bc5594f0f70ec5be20708dc428b2aa0b05, + 0x1d78ef43d9271f5718da099a5ad658993aa6cc4e263f0227433c1c0700be9a13, + 0x1c2ade57dbe0afc29e9c116a8b52dc653e3b67e891ddd363e1dbcd515c7f07ba, + 0xd3432e9b73c810f7b1b013cd2c9204574e75dce2c85d7279ba1ee5cfa912acd, + 0x10c5edc9f4201dc2b0366ea68593aa279438745e4e98024b5da5300bbf594f95, + 0x1424d5095a3ed3c98e8d59c21743e2ee18e6cd2fb87a4f8fb566a51d550747bd, + 0x1ec3fdc3a02833039f3ef99f01c641c62f0f90af4e2d9a961048e9b87698f117, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0xd9abef260b1cb444cc28166a74e729a2833e12445aabcf151c1cd036d1cb5de, + 0xed6cbbab2f8701da54b8b692304d8a4e8cb2e08f655c88924e27f4f15a9a52b, + 0x2c637eacb602a657668bd513a7a1007d825cefd98444e38b021b2c1d950a76f1, + 0x20fa81a9bf57087cf32bd01facb98697426792c6ebc73d02db7e5ae21b750d19, + 0x4f1d239fee709de5b0b5e5d5de370404d7df82d22b08c30e38a7550738aef85, + 0xa1de402ccd1aaafecbf31017e71429162b1c6d80579bfdc5b1eff7c48bfb810, + 0x1c14d03118d712c8ec5c8fcdc25ec9f15bfe8857749a7d43df91232dd65f37b5, + 0xc5e0c42722e6a74e7c9d75d128df4a564da3e0fb809cf7768615a2cfc0e9183, + 0x78c4b7313d470130efab6d889ce7c18832e610f66981841824e6f1d812072bb, + 0x3668b307c93ec14fd047713c1acdbb0b9248574ee5d6fa34fe883f1c22f3cba, + 0x23d9be76930ec686660aeda8b0cf9753e10c87300ebc641ba98e09dd2f52fe4e, + 0x29a3b2345ec04133c77316b42130de0131eb92263c4dde2ea07063c5c128680, + 0x2094711a12812e287d245d3c3efef7c17f18aa907378ad5060d80712b195d4c4, + 0x5c8d6aed39e2d9fa9a2eba112b4ca0aea1afac2c3a68622b50484a2c356a567, + 0x15235ad2ec7319fc572119534453ceafc36bc0bc2e4507a2a8ef1f7fa9e3e856, + 0x2a25158b0df94b0aa9db35f56bae7b9935418e9d6ae0d7004e23fcbd38de35e2, + 0x12db88ed4056400b8f336eb2d50eefb47c8cb34c31708093cd4f7dc30a13e2d6, + 0x10f2112348242ce97f64d304a108694283ae8959e5c91731b625900540bed1e9, + 0xdeb481ab3456ccc232dfcd50eb82acb8feca59538be59659fbe39426181f3c4, + 0x2bae45f1c2ff62e6048fb24ea8b3f732f6ca9620040285b5f89bc2d4db28e16c, + 0x2b93089446d7130073970ca2059fb0c06102fc91a6288339b687470613fdbf77, + 0xf0115aff5d6fc582b77c744e7a3310f569a0e786e12b526a741ad7e958e1052, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x116ba64981344053dbb50022cf797b7cc2fdd015965ef309453d3f249d581b04, + 0x15d813aa4208144a30d1b4509db1009a7eea4f4a8ba43145f72a0d9231a45553, + 0x1347fc037b2b26fb2308cf417715a9cfe43c2c65f2c71c7bb6c5c40ebf730e8b, + 0x153cbb5ae6b6d48a1360870cfd5f5e0f4c4ea591acd14df7a02b2edcc2eee347, + 0x249ff166662ab43663e65ec0789c6ba6bf1b8594471a26162cafe6c32106a003, + 0x72bc9e678fbc25cf9101f49cbcfc48cc0a51b86aa9d7e66c52897a5d3f5dcab, + 0xa6577ae2a5cabf4c9f00eea76f9fc2196288f1f8b3c16d54c21fbcb28a1da20, + 0x1c610a46a4eca6c1215870d8d35d92712544192b256de5f82ff6d3cd6eb327d1, + 0x2b9a13cbeb3acc4a615f45dcaf18828c844a1d61be9b59201a8fbd9db0cb2640, + 0x2ab0560dff6af3c0ff49de6b343eae05c665a0caf15792d3cbd8321119ce2b9b, + 0x16de08dca0ad6de9eb247866b16cf89da11890bf1285318b92cf302d8fe144fc, + 0xcf760300b2969518645ccbbc9d94ff315b966d828ce76e9e665fafe496dc979, + 0x260d564df3dc0db676e22fa410e41794fdde75c4f19584b43650ba909b44ef55, + 0x78c91572dd1477b07006fb1b5852ee50abd789a190db81c0c51de867ed1fc11, + 0x2280039d47ad466e5af645f064e0c10cf12e92c3d40675008d4c4eb9e873807e, + 0x57e2320efb4234e61691c9bb57aeda4fd11ab282b2cda1f69e91871700c81d, + 0x22f771ba7d2d275cf543283250aea007432a03973c77a82744bac9fd942136bd, + 0xf01220ddd07023709c7b55a1485f0a5443030435aa02d9ee677fe4d5ea0e62d, + 0x2e1da930eaa52749c15bb6bcd34b131e7c33ea3ada98437dd9b7eebb22db48e3, + 0x6d621c55789875af6fa6645af8da7331e54044a5ba01c54891ba11af10a36c6, + 0x1ac30223485713604244857141dacd036ab088f29363eb51c3113eba8ef808d1, + 0x24f06bb121eece3bc8c62e05fa6c0ebe28925e2a47a6d16e3269c5984682da4f, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x146b2acd097033a165d7525b2ce6ccaab4d541d5ea58e215166d393cd5677dac, + 0x1fb587e5904d58efa007310b9d86684fac658ed406c70d0e2af913ea416003b, + 0x2ca7217280f3cb8744c3c3824e46c6de85b654c41b19f4b662f8250f742041ea, + 0x1ae6ea2012fe1e87bca1988cefb126d63082cb3fa74a717b3008a4026a6eb28b, + 0x2d80fe550d7a4f7f67d2b170a430270679f03d119839d9ca72efbb9982dabfc4, + 0x137557593958b59bdbce0dc6594c99cb85c80f3e518e99179d8000b339492575, + 0x1def05089b4444afbf11ff8fb6e10259ee3b837fd0dd3d9be17595ecb5480c92, + 0x201b23b3cfb13fdb40deb239b3ece158fd8c67950c242ededb39540f9d71788a, + 0x22d9d27ccfb5d874defd155bdb5e0f9255e7be972f912c44ada9b7a2831116bd, + 0x239a279e55c2fd47d5872597cf2ce10ab41dba4cde5bf4cd7fd478342234b264, + 0x137724d6aa363143908f50d990be5f70794e6b9fe17beea4dcfea9dc0b6073c4, + 0x1dd6e3fde1b84a0b4a9fd1016d1c6d22fa80abedf000368d34d8c069be2fee72, + 0x2c94522857162e4e67bfbd495e823aed177c8a5d87d237fc57e5355b177e73c7, + 0x183022fedba6c78d0076bb2c2c6bb4722444fe77703e0a6f462dab5579dabded, + 0x2252e07ab4d0fcf8dcda2fd18514f0314282297cc99819dfcf0a5a9f35544430, + 0x719e632cee131b853c0824f527980bf00f18d8a16aa7f265480cd10ed3428fd, + 0x302441b28d3b1cf39dda7be9eced59f318c188274c6adec584737856495fd875, + 0x12692c7d7301e18bcff106c275cdd2dbc67001502b21aa890d6bd70e95a76934, + 0x1eada016794439b4d460b47956301225601ba9273266a9e955fd3e3c347aa7df, + 0x5cb3b0ddfcf2ea8552ef578139d19816d5c3ea7084f80c8cfcc43960ac2c980, + 0x13b78f0215ed7f48f40363ea5640fb9a41bfe6ff5044ad3aff51d755d9bcfb15, + 0x1b3a63d2f5d84163f48ff24f99ccba5ef05b29ca80019907e1c3a789296b22df, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x2957ffc8d1b0a3f2dd026ad7b90fb7eeb555d3772d8f2c7f47e37e913a921fd5, + 0x2a1c6c7b345e260cbe11154aa6a062d87725bb940dfe9798e794d551306f75f1, + 0x300cad430463e7de043c54011a594b2e5aa9f0aaf6558a5194a68a3285bda986, + 0xab63cd76eadd01e944a13e73f2f03afffc11b4823380c6d0f653cf2966b1eaa, + 0x26227ae79cdec5b80aff802dbb9bf4e8659ae92bd8a83be6dcba8d5917c4d34f, + 0xf30d1719ff31c8ac2175e5fd863b5b04516809e3c7ac6ec41a1a53d866a71e, + 0x11c786871cc25ea48df5ad070b2fd3969a4841f05885a80028d910b7b6e6eab2, + 0x2c7a714da7b75d6bb3eb16b8d1599f3729105bae675a1924f43c3239f9c1335b, + 0x24b7026b296c245b47ddbc1e44492034c4b7a8d35b2887cd539513c5d0532403, + 0x2c247c7290fbeec55bc8593b0f859b43451002df189238934b16bf1a20d3624a, + 0xb94893f2502d38fdb691bfd23b211fac95d934cf913f4c52eac9999fc059e6d, + 0x79b6b8524b8270e480562beac696afed88406015d4419a8ff123329050dd3b2, + 0x27e2e1708fc82a7868b3a0fabf059d164ed3dc38f0e6220534928b1cdf59e26c, + 0x3040afbc8482759cedf03abb41a1ee858cdf563190eecfb2a24424d4964911b5, + 0x1741752784ea1fc7304aca0447b2878de168c87b78e2c3ec32d6805b4d2a41e3, + 0x13445ec326f4aefaa2a84547767b65d8884679aeddb391598b219ae7ffd41830, + 0x2b23df120933a79eb1feea325a521ba5d53372e29d279a8c32dec33a83dceac5, + 0x2c6adf68e43f02f6721d9fd6d19e8934ce3a462ec543ff34210e828239177789, + 0x2e9faaed5c26fecc4672723370623d6f563537c06d1e98292134f4ae26f1cae, + 0x22c261e0c7bdfb933e808382fd75da681f46d90e703407326630768407e0c27, + 0x15605ce70aa2918973c4bff136303580b51fb071d5224a1732c10424b1fc7a82, + 0x21ecd0341474c3b4ce81101d267ca95d7cd2647fa4bfbc823956a9e348ddb877, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x2932e8876d985ea09549df2c64e8097d85c3578aa46adf5eafac039999835c5, + 0x2c1bf660a1dc8b26995b0e78875b0c28de9ef7b591fa2bc01a15ce7729b9ac5b, + 0x1e88f3c4efa334fa5bf313a919c4de396bde82e124f0002f1c00229f8dbcb67b, + 0xc774d6acb4fcc45b139d92323da82304fc4e29a919c9468746dd20a6e03fced, + 0x17c11174c9104e2ea1a374b75bea6925ec45a1d9e5293741944e5359d4d34408, + 0x221f6d3412048020aa832d764a5b5e80af3b014139b28f06920cd3a3d3c7b7b3, + 0x2c0b403d133861410859b48131001ac956fe4c9e5a368d9c3f085560e5d37699, + 0x1da9a5cdcc8d5c8e8390afe24b8d801bb87b9fb9eed429aae52aba17570c9d03, + 0xc3e382527280ac6525b3922388b310dc9864d9fd11815a2c94f7378f3d52f53, + 0x2e733c656ab7308a5f77b1747c7c7562f0b48d9bc42b4c1392632840dc67eb83, + 0x5500ca3eb4bd08bd91997d4fc698fa050d5d80d881f634f84feaaac57b15b2d, + 0x112aac301ad5ced619c2925c297d3387bd0690d0972aa21f88d7437f42bb5cf9, + 0x273c9c5526da6130164e2360c9cf111e2a1fb2b5f02a5a463c6c64d55a6c4760, + 0x5b30e5e7b01d8730fd549eef232bd3824b3a670604ccfa2407f2a63eab5f5f2, + 0x26e905c3889e46597070e8b67d4ac9ed44f5a89d59efec7add002494da376c6c, + 0x3a4bd09500b265238ee8fe2cc149e058d35559d4af804be07119815b5b98960, + 0x301e86bf4790028b674b2497deb4370f32b2410defc6a4f3ef6e500a0f29827d, + 0x86d71db143455444d99b9993964b827cadf4feafebddcf019c278f32c8114f5, + 0x174ef177c132d7a3e91f02639d7dd88248435018525f095ef18cb846bb060e62, + 0x57af114d2416184735fcff06d88e734f7d8d5dd412b7c407bb3a0f09bc2d44b, + 0x2cd21076d55f5c9c8c3c3afbf7f0eb2faf05ff80d267eb692d93b8400c9b5fd6, + 0x1ab2f05ede0b3e9790517712ef714568d570da3a0833f8e8317c1644264ce97e, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x134ff00b65e9a214f19212b4750781ba3dd2e28511f61cda7a69553bafb44dc7, + 0x144774a605bb8a7d11b2f8fbc2a0d05146812a9f1d03c4be608a544d18ad8f6d, + 0x2f1de3b0835804059ddeb1d93bbb9821f6e2070365ff34da2c43dff65d3edf8d, + 0x930a41a901ddf9dc66d27b2238016500aec43b06bac6e7113beaff39df69c74, + 0x5ea98895839deeb637c0693c60994afe4950a088d1005946b20c25f48b1f4a9, + 0x2b2ad0eb96fe5e5ca0062109b8c535d32ba984e38547f3d1050b72526884e14c, + 0xea3a0fc0b46da189a9dca213c0288e3369573fa66b3d3379ae56df2a25262f8, + 0x272ea64f54ab3526e4679a0d0982560233af7b7f2e85147a86298fe62afb073a, + 0x281aa6e665287f9540fb2f6d13a077d52e145ed62b38c64899b92a123357c089, + 0x2a432fcc6ed2fce50bf214a31f9546baa2fe8fb3d1d00145a7fca7482ae2c390, + 0xa9809138f12435ad1150f8fc74d401d992c42439a44ebd122991bece3824ed3, + 0x109adc1cf8528ec8f537cfe978e320e2a4027abba83a3781aee0b88444805154, + 0x979b7716c8be6bc4091a376ffd1fc1313e19f3266095bc753da2cd4df883ed2, + 0x163c946685c585d46b6eb8a3edaf018353549856ff6ec0a238f45a1f0d593af1, + 0xd3d1890201c5bb1a7e40dd5575b4267fad63ae91f429efc5f57f52f498f4203, + 0x1f4adf58a1ca1586815ac26a76d8d6a25c313e9b2b0ac7f830e6e1e0cee2dcc8, + 0x2916cd6ca0ee56ce79345046ce1a91a231895fe24628a840852474b240b53459, + 0x1390ae730e0297f1c7ef2e27b3c050d6713015a40370d6a281f1c985dbfe86f9, + 0x2b747562e4956de74f4b115e082bd95c00a7e2a175255c7ebef7cdc70598de11, + 0x26d57a5bdf2b1da9eda88e856c4909c4265ea86d8b7f630caf123aac328e0207, + 0x24410235e3faacc2da4215b96ccc5228faf00709dac6542f589409ee5d833901, + 0x2bb0d85f9daad9891a6ca76117c5912a19e2b959f03e59ac52ca61c6fc90bf32, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x1c53d25cc30ee67b9ca5de92e574ae8e006378568883a35ec673078c5cffffa3, + 0x15809370254e24135947fa4d4c9bb5366a809244c42e44d58ad51041ee0ac0a1, + 0x1c7feb95c74dfad69a598a6569b5544b3138c293c78957c281e16178dd4d2ffc, + 0x7160482689f59cfff868ce436b6135ce5b8d2e15aeddfad236cbbd174fceae6, + 0x1e1716d8a49f0c324485bc3adc0f6a47ca4d7921e079fec272d79aa4d4f5036b, + 0x2234e7ce1e40056deb62ede7b86c7f6482f7a253ce49aa78aa5c636a5f0f942a, + 0x1134d89c4cc64ecb35202fc26b51689c745b812587ea60ae3e2636908b428a0e, + 0x13c6c021a7904ddd8cbf3d0a7db61e044403812726e369bdb97ca31cd05142a4, + 0x1c750f568881fa07bd9d06cf2c36356c5b824b71bf2060b763fb2895667b54af, + 0x8170199a5b260bcb05638100428def3df9efdb5233441d14fc219c1bcfb0a7a, + 0x1c0bf7af434ae20e594924e912515bbe260e21afd030f32eb7b0bf5cddbfb1e0, + 0x1217414da7ee96629d16d8d7b906df0c15bb7bd5bfa5595974714aed8b3de96b, + 0x19bcebdd18dd8cd827850f36a3f6849dc028bffcc10fd5864c0e37c50156964c, + 0x67a8b7fce532eaaf198ef0fd1126b45f7d0aa8645e35b0331d7eefdc9c7b364, + 0x2a92c17b2ba923484475d4bbf164caa1a8f16523b6a23b2dba260d7178530eae, + 0x21bad2c773c7b349b2930be09781138a061c06f4f06fc38e71332b942ff2939f, + 0x28d0786689c5a9bc8c7f2eb62f2fd0b21d776f3cd74725c0bc2aeec801048801, + 0x222cc9d34695b0088ad166a5defde21377627fdd32b789575085363d6d5ef907, + 0x2a54d465647c8ac5df86ec2bac782e9aa560977f7fb60b87ccf3cde01e40ac60, + 0x13822f37a288f99d881dd1e6f6df9a8ffff482f84179be0924e7768d678a2a90, + 0x1792175406aa3a9e7056233f4a70042e8226c943b7aba99805727ff7a9565071, + 0x80bc46879014fd6b55a3e4d7698925b2a6710b7a5478a51292964f64de1d762, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x8aeebda8fdf99667caaa1b7f570e579375edf7fb6438af9b689bfc12e2c8ba3, + 0x4b0ff272995a13fede7f4465a2f0ad2134efef55626e1824c08ed67ad981bd7, + 0x63c3f451fb64fd5e95d21c8eab8fb98523a716c8f83e0f764b41a8e731daeae, + 0x1928de8cc64d6cf21107045a7fcc4e0cba4706e68cfe779044583f2aaf6e885d, + 0x1ef2ec873dca7eb1092b1835b74cdb403726d8fab6cbef50b231df9ab87ce725, + 0xae02db0ea401b8a1c747f50e885d087eea93fb3037870bd36b1440d88995031, + 0xcb7ba6cb4e056aeb2bde61a38521aeadd877772701fa572fc77915050db758b, + 0x18e89e7317025644f8043265ce00d61382467265fa055598066b9b19b47653f6, + 0x167a003eddaa7d10f96e547b66cc2bd9f2ca99d267e011fc69669f71d0b71fbb, + 0x573cbb272daa570f35256fd3826e34c3e2f35f300adea697a306f914db7a584, + 0x7fc9b6fdf58ee181a0141cff89e34513e7b4d61e01786c176dca84b9664eaa1, + 0x2b3af74c7a1c0f396429f7e2d70e68b014b3a268d92897330cb9fdb1615674c6, + 0x22580eb83a854a817e4277e8cf1a05f663d198c0b2b6458fa4cc45120b48883c, + 0xc03a653e7e2061d62e638a0931b767a550722b318ebfc8bd924b22c8a009b40, + 0x1f0f1d34546815b4410f8ddf67bec129e8ae08fe617497a70e85b80802e0557b, + 0x1dc998a827321537333b22cdf7bcf0a5fd9a72cf9ed9d9e05ca82df4105c02f3, + 0x21305fbed36a0b611ccd7139a48b7d36985041687c4b76483eef93d98e28debe, + 0x19caf75550855e1b4d0e580444a73db1d86d507b72031d11925f33fbcf7e9f10, + 0xfdea1098aa89298d72ddfdc5a47c8f9141955ff5a612b4c52ad3ea0461f3df7, + 0x15e15542d8176284cb1b007f4655236b1f6795f045634ec815fbb5f842bb3c64, + 0x24b51f84f0737f35c038d3801de3102fc32dbe223491c5367af7baca0e933482, + 0x22231a672bfb82faf7b867475382c2fc174937b53ce765f4b6fb9737177a0ecb, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x2020cec5cf125567b97756ed7174259dec539b4c40bba51bb64779221b4bca9d, + 0x16b7ffb1a4af4b1dae8d82824c542e81b7380efebf3183208dd87f3368f2cd73, + 0x29474e7fba2de80bedfa9f2f8bcaa38e6b154ba2da3454fd1436fd5bacaf2bf0, + 0x29f55a4fd3170647fad71cf38c80c4cf8af0b1039acbd193732ff1bdcb049368, + 0x2383d1015508e17fa9ff282c175ea5ed655f74bd5793bae4700459b5600cceed, + 0xb21347d3f2e1ed0ed02262545a6aeb4209b1809b132f7f1036af67f9ecc114a, + 0x1c3b4d79046a0030b73e4ed03746ef2898778560012f14b8c151f4166e0c9cfe, + 0x2bbdcab9bc95ec1509f2aec2af8b117c34d8d8079173cc099e658c863088aad5, + 0x32c3e39a7299f29c816d761fbc2abda28743e917547eea1eeaa75975b22b7cd, + 0x2402ee3c6cfac01e1fb6551c34b1591e2b419d4ec69a0a9f1331cb546c31dfb1, + 0xffbdb63b86161ab9648a7bb7e5c25d1541847070efa58c6240937eabd05acd, + 0x2dd50132157285954cbfc6ec6f2e73b0d1218c699a07fb09984690d0fc8719bc, + 0x116fcfd48ab31fc4b622f442566be132d688edf27d5337fd8afb80932769151c, + 0x2c3c7ae7989bf23c86279e146798a3ecdd80898acbb6c2ec1f716eb7a91b017b, + 0x2b7e60fcbeef2020823e799448da1cb0b866d776c8f74c031de2f5452010186c, + 0x2b4a3e4a2db9c0cba63a23100fe5b9ad29b63e1e004b40a16fc00e20a83b7d0b, + 0xd1527b252bfd505f375cf86b9fc95dc55fe1ca65dcf37409ec48da8b1207735, + 0x1b0a396a158fa717511114766ffadeafc6cd82b72390aa908e1c5b496eaa2ed, + 0x25b7181ae26411c1705d3adb389716b615f7c1bb3051ab9b9af4df76cca672a5, + 0x1ce6e261ad4d6353538814957c5184ff343521f18ed1e8ac24dd380978f1b1ff, + 0x2114b703153c05d8a458b86daacb8a1180a0e0e06313c69f0319885218d57254, + 0xbba93da8fd45f0232aac88e242f83553799a5dd893a27697169d9ff3f628dbf, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x234620365d9e508d8b7a01a20c8b84cfe78734bdd7a480a6f3c0270be6c9e031, + 0x18773402938384bdcf3ed2931a34af760d3401e10cca02854081209ca5bf9c71, + 0x12f489609e827ee3dd6a53036f1f8fb80243c0ba7ac2720ed6997504f7f50d3e, + 0x98af099212892af46e34cedbb21e88b9184ab2fccb8b8665a5324601d8c5909, + 0x229c5955c3b6f26373956d4e3ddbce6c4c97dbd1382ed1c141c6c6b8cbcfa95f, + 0x204c3dd1c157600ceb1cb55072ee278292a3003a7777febb080a33168f4fd9f6, + 0xfe2cb3ac38a35f9d943e20a4cd370598e5c1b128edfb9cb877f2d424cba56a7, + 0x2ae0af8492610bc178f36cf8887b6bc86f02da15b1dffb674706df0d9b62e9ee, + 0x1ed1520997dc0364683540a32fe3e4368385d140b61b09672ff0e0bc2b398115, + 0x25a0c2f522b7f27667a93c435c2bdc67d575da8a808bfdf2a43558b1eb12d9fd, + 0x24d9bf46734bea252329879adfb65782fa5c6809a1520a3656d7f67331348d3e, + 0x2b5277817669cc8df0c6b82feb1587ed59210f1414ae609f40def4c314d96e05, + 0x724f33acc2c20822fe7f8d3d1f0ac39b2fa1025dc18dccaa4b258a2654e705b, + 0x173f609ce483747dc7ead26598dd2227107af0521fcaac5efc2bdc3f48c07c99, + 0xcf0b2b3f0ab40d718173aad7993e6213ee48804e3e563f0e531e2c937abdf9e, + 0x17ce34f45aafd638238ac5846997636b58aa04d76b4b0bb46aa0cd078ae14f8d, + 0xaf51c9e93fa5991104504bba90149228d64eece560e4c8bc2ccf1b943cfa761, + 0x67a323bab4f3d03df325818a393ba5dfabd66405cf74e65e9dd52ee2d8fb197, + 0xc3d3445a27d7a042fa2b4c5e2b5d03c1332d38bf26a781449325896df57ebaf, + 0x1b5b3c710b37f195824a623712b2104d821ec8d859940bf0d27a3c50faa2e886, + 0x16fbcb1c414031ba771845e6f67151fa983a4e32972031ef813e5f43ff3a8cb7, + 0x2dbb1e93d3cdcff3ec3bb01debd9211951fab454e9a019fa4658a98f148cc8ff, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x1f580786a86e622d9ea1bfd87c2d7a3a5f19f25105f0247f08b0e1ed89bd9dbb, + 0xe2debc6417cbce9356f75fb55b7ef0347205dfb84b5b0de2c02f4e130453c16, + 0x286b399e2ca189612a8d7dbbe938a61a273025779047f72ac5fc902847dfc0fd, + 0x13144b54692e577de4598ca0783dde7af2a3a81cc5f0030b6c3bd92d3bf76dee, + 0xaf7247e59389d0f9509b168845f46a72b4474d9ef66dd7e35f58450fdafe9ab, + 0x18b3c1a2e20476cef58aeb4b8ec1820d80c28a5309d85f974fa62a19d262f5b9, + 0x22d6ca5d958faf4940b74e3f50fe6eef888799302c7c99399331a9db0a9dde32, + 0x28ebcdb416210c7ea0a9c44cdcc1763bfeed08267cc7a17a935f0e75dd6beb6b, + 0x264522a85698bf1cd24c21e937f975faa4cbfb3534cdbaff55a89a17f947aedd, + 0x170ca38dff04f179223dcbf96e15609225436e47f6aad10c21059b549b8ace87, + 0x1980e8052c47daa2a7eceb160ba3cb93291acf7b84c3a1b83977766d78e7ca83, + 0x2ef55e77f32308739f0831d0a98f7a6961e4822e53027d86a46aa9c9ad39b64a, + 0x284ac526379b614a14c7ea0567aba7a459c269c32fd5af192240c11103a308c1, + 0x1d5a978ae2de2380a458d23f2c2c1f7bc1791d4fbeb38b6c7a356b6f033e6dc9, + 0x1fdd8752355eee4ecb1e8924b6541942da0c3f56e2f6c12e2ab75eebfcd1bd98, + 0x274b47507df843c5fd2f4c823c4c22057b76336affc6631035f28e57f6a6d387, + 0x2d46b1ea87a9f2ed6d8665f43aa1b4f6fe399bed08d9c77bd98e82350be3f379, + 0x21e50a36ee2e6ed562fd73013bb2d34724b4ef34525c51931610076b81d49eca, + 0x2f0a7fda21c19ae55233db913f1dd886bf71e9a0fe12f425d479f462f1cf4b06, + 0x2dc7e716c1b4d182cdb078f38ee7148f0ff45a65f7f6360a66d6a29fe78172a4, + 0xa24d8de1362fe9f8f23609dee59bbb4230f39236e6729ffdd95bedcf8f404dd, + 0x2b1c087ce01523c9e0f97d81c67a77014e6f791a656f8edca33133fe9206bbbf, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x243ab6d29d356d147b7915a7a11f6ef485a0f3ef8d003ac239c0a926df820271, + 0x10f0ea299cfd16da7c54cf4315a4bf993f6c8ed21e1f1b629258655bb569f3b4, + 0x1057e97ac983fedfa508de5e9055c24629b7faa279f1e483a2927e621a45a16f, + 0x13ecb96925a985173e792bcadd76dbf62657e8aee6e732e1fef9ceb1d86688be, + 0xe6f9b2c64d9d97e1dcd59691a2944c4e610f2c9361a93284853c335ef448b93, + 0xf5130dfaac7698c83247ab7d37384c6f4fdea4c423691dbc0466cc847d22240, + 0x719c66d510d88d51a80f22c9ee06cab506ed395847532f0b0aef79e94ff5c37, + 0x19fe7de3a53de3d0cbfbbe226c6d9799cac73c343bb7f652246d3314de2cd748, + 0x1fb5113860f9c3717742da8ac8dc02d3d750447ae00236789ac400ab7b0a4a5a, + 0x28637c9718b8c1053ac27e6ccb68a14daced5c24c3932460d23aa40fe066611f, + 0x1049f5f885c559fe26f7d811c660cc9c6ffdb5103dd3217111b99808a28a10ca, + 0x11ec2b02d176c222bc479f6fba4e427738b96aca1b7c3aa11db89b27ae10f0e3, + 0x194af56781953f69e1b00c8040eae1bd59b4861dfbb3969d8161d77552233c16, + 0xe752eda03c9dc685060d7d0625d4882ee9ccf2748929286db03f0a453d8c21c, + 0x1440c319ce47daf613542b6085053ac22ace7246863f49df6488292e7bc72a2c, + 0x10cd79d6139155e4208ddc71ac9646aeb4ac61a3eadfaf337ff97ed9109e0971, + 0x2ef23590604b7f057aaa0583333f5766d25a43366d99ab87f9e290600b3f749, + 0x2ef2c45fc47b175cb8c6e23c2cd7d26332ee65470759893d167772f18b799f97, + 0x1e769953c74901e1cd39e0a9d7ea12db105fa2a0c3fe40cbe36965e11152482c, + 0x2713a7060c9901b904ee4efd31cbe1bb0ac6efee3756d59392e8b594db57a617, + 0x15b3bc638f4556ac765e5c60678b18ecc5a7aac5bcabef247da9cf116cf4249a, + 0x1df44e6b43f51e3a708b7b6f7a05c67e7817d8fe6f36e357e266265e3183535d, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0xda3ee283edb0e4256891ac9f4166ba14c17436c1ff8b6870f6dea7962f36c3c, + 0x2eed5fb764a1fa6cd387d19322790c87a6b6a0b13f832f24f0fa54f36aadc0d5, + 0xcb9fce02c3f2f82704477407a46991cab311db6e12f14e388c2a4b6093de75a, + 0x2eeba73653edce41cef62722997e5df9d2f76d799cf112d29bb5706a6eadad08, + 0x4318c41475504dce0c6bbd1e76fed829f7c8a71f1b02f45eedf5c3a71e63909, + 0x2a094657153ecc1710c0583c1c3b7e7966e67057c8faedd408e505127a78605e, + 0xf40aee2532a088cda6d1b13c48569022dea6023f85231a5544a9e6cc4edcce2, + 0xd97ae723214277576911235bc25ed81063fcd21b59e6279275f11f57c054459, + 0x82f1e5e8e5087c1aefd0f4fc62167bca4b73b8009e3a67e07cefaef1e475cee, + 0x284f24d43d09bf31c1b59d84a8f2ffd8b1b903a2b88827fba8b02468ff57a971, + 0x2b6538eb36991fc2429f8c38483f7d4ae728b7e105b4ac6bb449258eb89d3aa8, + 0x82e7991093e92b53c575b9f51f8bb8d1d2a405bb94359544a3106e033b3f2a4, + 0x288593b3cdd201b3f6ee7d9ff217e0badc9dde2bb6ca2a63359ceca59ed12d81, + 0x2762b0c05f66a7d3a2c4b46f6da9e207194c32a91a15d0c8c7a8601874649bd0, + 0x20851ccb233ef814435570f9435eaf7cd22baf2a89720b4b09d035dd42d0305, + 0x1e17e4ac7afb5980903d9faaa355d2d4bc00f661cea435cd563a0c08d89f52d7, + 0x11c64762f6e40528ef5f60c4905cd442e137348737ff11ef9fe186e85d88cc81, + 0x135a7893f0df31bdb093e2f1936efde3bf6c80cded53bbf23842d5cfa739c10d, + 0x670c942b19efe0e24ae667f88cf25482988d4fd289852b59c7400bb291fd22a, + 0x2feb899196016827ef03dffaae29bd9f7df66f312f728ac0398d2be90a10c46d, + 0x23bb8acfb809bdb5ed2b2306e5870465cd881e8517cf8d60b6eacb23993ec19d, + 0xa2f66d3d56165a8357ad4ede386e8bd3d2c1a6a51ec4a928d02aa9cf2c94025, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x2621d53d90f51a97a82455d448359f1f876b08ee77917e55298b4a4f7f2c80c3, + 0x2e1713aa13a1ed2a7b57ece72d5599b6e239d5fa53866e407444290254f10515, + 0xb0e3135b9a9bb3900a312bce8cbfaa6bf7176bf09974e9224d63f81eeb9cdde, + 0x1b37ec261be552d7f9cacbdc0d0f22ebefd7c123cdcd54a0b493db30a65359fd, + 0x100051565c2e4d9fed118b55fbef6f060608dfe4555e486a44e6971696042dd1, + 0x298819bac61778b218142e4fb26533f0ab1f8f40c8d8070fe2f1d4170d93c58b, + 0x2cbb90e508952c4b5ed26079f85f11f3bd728140e3b8cb91c1da9152c8a82560, + 0x18e9de503cef0ae3f8901d7d9004170e4661e3792b464e8d7e1a7c7f8bb17091, + 0x240a6c59aa72438261cb26070ca93ef35db217770a207e7cd9af3a4df60768af, + 0x1c5c0274172befaeca201df876ee39b582fa848a0bc9454f6834b073c4ed7f73, + 0x1dd2fcb227876523c5d075aeaad2df556ca76939be98462768f94940ca73028d, + 0x1e0ebffd9567e4222b322bd16275af85e3a09c6db8f053a7027827bcfba8a0ce, + 0x549e3fd2d8b4c8f5e1f6e5ada4adc3125ece6af1041e4f297d14cc80bd7a865, + 0xa43a7e3ba83061b5379f61580f17fdb5068f57a18cf3d8f4431ef14a7fd8bbd, + 0x2a8c713fa0bf5e002dbde544aff988ed8b347afe2b3641a08eab979bddd4d2c9, + 0x307b423ad05a7c6c5a7feac041de1c236cf3db8e0da46368ab0a5113dcfd4d0, + 0x1202dca5513d8609b3e911ffc3c1f8da4138f56287f2837bc1f8820469bd5839, + 0xa109d2e7176796406f7fc25caf837f5c8d2306962baca62457fd49673b0e48d, + 0x2158fe72a1672fc1b0aeb56bdeceff410de2a404c9f4d7a2e39c4cf0800264d3, + 0x5e83a4f3ed30f863a148e66c1771a4634ed52e73dc1f9c35e479744dacb7c2e, + 0x15146f0169d0dcb2e678a62443c00442cc342091a6d18a293a17882adaf6f146, + 0xe27f3790482529695293a0defd1f44495f0adae815cdee0d3ce9f91512c1be5, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x216bf6d0d240ce8a0b430f85259b74084cf9f998823dbf13091042a32b4ea56a, + 0x177227662dcc7ef354ef41fdb3f234ad93e7b70a6550e09be2c947ea462597b0, + 0x1864bb94cc95e4e33b7673809909ee3a156c892cea648f047f2864db12278e4a, + 0x2eba9c8ba56d6b800654a1e805d403bbaf22af7ff1aad92ab7cf420c129a2616, + 0x24133306f286c04d2c2e174c0cce34c64c21f81e0df67c2593de5b422dc1eb20, + 0xa1aeba71ae73f2846cbd57f9dda3c3e24b82291d22108a6a05a9c06e002b8d5, + 0xd2d0af3b16bd738a5e01bb7af549f842a2a9f847063845d36d7424e1d2bfeac, + 0x8e4a4d4fb97473cfd880c9285028c2883d6d08164ae7db26e6900b532e848d5, + 0x2b2ae02b9d6d53220998acbb749c29f4476c9f2cd34b74c66e4f2c4abaab6520, + 0x1fd0ca0b29e63609c2f6a3150ef62616a5fe2160266382030e48b29806298756, + 0x11e7f1f91826d815902e2d9d79e027c44e78197f4450cbf14128d704c2dd46d7, + 0x25ae141d31ff22370a99693adb350858a307e1fcfb60fe175a3279d99879e2dc, + 0x13047c24823af0bdf17ccaeda371552e8834990abeb7ee7a9a646aa7bb9f4753, + 0x266358e11e5081dc2944990007644733445e90ddab20cd50912c06cf1388e92a, + 0x1247a2077d577a1ef6f0aefe8a7a2df21828f69c44bb89b6ae70fe9c3ee1af91, + 0x2c338524f33f321e6f2e5e420edd47f14caca5bfdb7d3e065073b7b20d2814fc, + 0x2ced7c9cfc6cb9727179bfeaf0ffc028a759aa44e97257f72c3467f9a0974c26, + 0xe633982a359333b017dc5b4e683bfa274e74153f4f99d639e48de02fe239c9c, + 0x2ea0bf1ed70f15fc196a395ac836e6a579d4923fd13be32b1416d351a05afaf6, + 0x238f38e3b7a1d517e00c666c6670c099cd2bd7d8418c55facd6e511ea37c64e0, + 0x2da765692bbfefabcaeb0dab3ee18797ec0032c1feb257983ce753a8f286a75a, + 0x2cab9bc1d925ca3f6473d56a4c57ec136f52fcf02c9ee0e25ad07fe24dc281d1, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x1210303a7705212e81f926482699c6d6b6aa13ba342f4576c873ce976435efe, + 0x2e1fe52ad49d5b2cf4c43c7fd551fd05bb0cad132226c92b47e4bd24bde2852b, + 0x16e6198e30d06c12d5535709100d47d0ab174704e4953b696bdcb8318c78d80f, + 0x11087fc4daf5c010f9ea8b66e2f01e9032597965c811afb9ca9c7004e01a7eb8, + 0x268cc3c909fbb19b2d737b0feb4aaafd6a2c0f0da4f6b391ead88673c187e8bd, + 0x1200152bacfbb5e21565b19d0e6b47ae2714cf2bd9ae7038fe9132879d4b4688, + 0x28db252e756f0ffa83fd845fa7d06ebaa301d37edf474a3b71f60539a630f59b, + 0x184e95906f85e4e36b0b77e9d862fc27a56ec38c3178f8904851700c703c9db5, + 0x14d66e67decb7a7f74926f2d5ec6497b965b4de941bddbd77371a3da470e5d96, + 0x12a5b346904fd63b6c52f603e8a0c351d2284ec345e50518492ba935b07ba7b9, + 0x269094e291d79246bb735d3c4a3df2ec9fb60a6b2f2340e63c91cc6d5dfb083b, + 0x13929b4087a818cd5f602ee40afecbc30ad8ecb2b7677530094d09309808ece0, + 0x14f878c52f6d09cc1b32f3ceb6f2459a5fd6668860b945b74457d819a6d18757, + 0x2d91fc38379e50d8addc35fdfb88d27e100837e513f329afc4fc9cbc6fa0140a, + 0x27b4dd2629f029c1ec11bb5f235252371947313993a0111e4f5cd14d47b505b8, + 0xfcf71b4f58f1e845394800f32015de09e4107ce8a7bc786810e3cabb67d5d5e, + 0xdb4f212a8d9f8036174d995937618dc8074ca32f5ca1bb537fbab6898dc679c, + 0xfa6cd0c9a74c1973656d44ae21323b5d29ee26065906f0747bc3364d9fa8ff9, + 0x2f5d612a89e3ff0157b8c05eb81cdb030b3aa80728ee5f2b484e027e9d7b587, + 0x12bc2f8ea309d0aae7cf1fd15767dbe97c288b2d72e1ea489a383169d7e5cf07, + 0x20e5a78984a6e437e16aafd2e43f119233b4bb35cfb628aebcca0ab3b102b4c5, + 0x155ec9570cd3e503fc1c73fabd38c4ae24d31e5a38bc56c992b5817c9a58c18d, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x6a4859991b82108283b6091195b9244714a1997a97833c55c4e15c00747f5fa, + 0x1a17c910b931d2fa7fbf8d41a1ce86a3496148f0a62cbb541a94310c3bb931d6, + 0x13c27123ab15ac6f964022f94aefaa51f07391afc1095d7480acffec7e9cd6e1, + 0x171c742bb0ca2a0282f5fd7628191e6ccaf3e32c38305a00f6593b4fd7527f9d, + 0x16cf4b06cbdd21c5afd1ec787847f6956fc45cec34e95739af5ca67c27da7729, + 0x11e51d4503b1aedbfe993befc9c8078b70d4db75556da4942846d22f217dc694, + 0x8afd62076c7f946b4dd61967b32a6d09e794888c2702acfacead811a4fb4846, + 0x4158c5f8f1b10efa12aab63546ffc8f065ade0bb494a31a58391c41f62fa841, + 0x2f87837b6f5f2807659ec7565173893f91a4ac26b6c2e26e22d09a417309dd32, + 0x7c728d2e8d95bc8842ddf8db4c76412aefae425c2774ebdba4317ea783345f5, + 0x1455d8963d76e99083c896bf0f68f63db992b86a913f3b123a98889fd61a3b0d, + 0x8b4bf22aa0e03b5f857a51c0e04b64565f59c87efb6859f8c7169dec09e2841, + 0xed823b8b9d0f2e0b0c6aaaf3e5621308414d4be94ca3ccbc6c8aa0ce8e1b4b9, + 0x1642b64b6547c137ea9d16920d1d4273ec49148369a457cd28f73cd9098ee6a2, + 0xc9d91924e007af49ba20f16356373ae9cdd408bda9255583e41c1079c5c06ba, + 0x2f1518b8bcf463362e1e927f733dedbe8817de8dff121a6a5527b33e70778ce5, + 0x2114e089d96c5a4b64b2a6ad154fc6880bcad9eb3e8cd1d3ef980efda445281, + 0x1abc25ed5c0fae93b3813bd8fda0cf773df41cced07a8ab762fb36b6564922f7, + 0x2a5eddd216f0eadc4c50a2618f44a4dffd68ec6af8f7c0bce1a45894e6cbc010, + 0x75e0d34b920790fbbd21418ecb62663464bcfa06db3581dbec635c8cf864ec9, + 0x27b7beb430a31d0967dd287dea9fe9d0a16def46efb5518aba65fa025d82579b, + 0x270bcb008b10d32d8b92753219422002494e30327ee71b2379b09d5a8e519b9a, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x26c4a3b0ff9b7f29c97c01b4fdc65d8ed1a07717da9b297d3d2a855fda54bee0, + 0x2c6dfb52d9648d18f5ff9db4e213c6c94f2fb8151aeddd80a1cf95df1ab4862e, + 0x2f7b7e795fd4f392f9810877d44523a6fd9ca59bf9f6f15502f4449b6fda8c85, + 0x5722aaa2080e70ce91c67932130feac2c7ce93eff67e453c4a10c7923d8282b, + 0x305247769dc2fc18b8f32cff8b1a08ebe60b0ce5179bc0fef9e41893007050db, + 0x25c0007547961e0f368c5bd7bcd2335c7d35c1dcd4e04b169ea6676a2713ebf, + 0xaf75b019c88a07fb24d01cbbb2ea86e75ce904560f06eaabd617cc627ab0cec, + 0x4707e08232d55d9c5a37b7378d94cfd74933b1f483a6db89a7f7cc83d17a228, + 0x1cb2bc2b494b4a6f9e502992730dcc6b94aada6d0a04a350087b3c9866c448cc, + 0x292295bf6257bde873af036dd6932b623fea12bb31928bdfc800d1a6bdb7dc5f, + 0x235b612e67013ebf3b74fa41157682a4169a17315695f54c73f290afc4574a3a, + 0x1f412dc0da42db6a648c19e9e9119b157483bdbc7ad3936efb9dcb3e72e12114, + 0x1402bde219d915bbc5f2958edd28a107072ce6cbf62346462754c21d6d5c9d16, + 0x265eef82382e05522d8c113ab42ab0b09da4c166e107b2fd0cfa47aaee5f4756, + 0x2b329efeaf663ff307ee9a682f883da59ea63242aacb620b61ef85c0110fde26, + 0x6004617ad663a46e41d79103d1de6e8364d2fa582271da3e8b39c01adc8aee2, + 0x1a10c1c3bdcd43ffa6ea4d58f408cd7d0e74a5ea38656a1b6fa88e2013025d55, + 0x9c705ca1ee96783e0530b69117d99337fa1aaf04c5fd26e5309c0118f4bdb32, + 0x978aa5435db1ee6896c737ba36d79120681758793e1a1d56718f6cde533dc5a, + 0x1934fc546cb215a23bef42d7124ceff70e1d469081c2cca343a9ebbcef1ffa60, + 0x1ea452043466f1c5d8f26fa48267014833214842b2d204fb253b97c9b3deed6a, + 0x876bcc65ef05f89d90f3a96070a57d48d6a2a09de2aaba161fd6b9e80cd6ccb, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x1c9f9742d4bbbb6c9dec076b4b9c7ebec120c5740e04e3c62d0c786af006a303, + 0x18d9f9aee0ce3ea08d9164a5473ac114ae755c25b4f9566aee1c90d0a06e7029, + 0x22476bc02607cc745322595d63b98eb70db2782762e548e023837c9fb06021ac, + 0x22d83381d8f8800abdb2cced36e1c1d1c2f552594bfd9990abe06d0757eacae2, + 0x16382c1df41e7d0a3a4958656a42e3f1f314b21ff463c5f959b51d1a6c40118c, + 0x9e76815d09daa33a324f5d1d2404b3ee419b8e9b8833db59110c8d38f1373cf, + 0x1b0d5ae4cde6fed3fdef9312557d22f7da589e71e8712ba7d2986b4bdda6206d, + 0x2940f972586e13b6af08d49b838fbcdf24fb2a8a03f069ba612b0535ef94bf6e, + 0x19edcab2af3f18321eacf5fc4f3a933383d26aa37b1e3049d3c36c11c25f60e5, + 0x2deca7587b2175d50de4645fb5601b2599f5eb15ffdca763f0a24dd1dd4e735d, + 0x1f816bee20400357b01555222cbab8bdb2b5a6ff8aadc19f911042092e96a26a, + 0x2e950640b9cb8d14e70f81b06a9dbd4f5e01b81c448cedf2c2ea0b753d550e9e, + 0x6797a59fb805d4ccc041166d71d077763b50b1fac685126c84402f02f565179, + 0xad20de820c01db5e4c800abd15e3239b53a390d4a4a60348efc2dec244f81d8, + 0x174a6b87cea8f7dc3a7aea08317bcde182eb2aa39c927d46bb9b0dcd70954da3, + 0x2cdb547394356c92605c7b43aba9aeed3ec33a6ad515e55d8df4e678487186df, + 0x2d001f86169c7feec284389e39745c1a64345f978bdefa862e8c73f7fe610d98, + 0x2e40bd1d9e8c6b483f91eeea0e7f4f210aa786503d225e1fcf41166735737b44, + 0x149aa5d1015e9f2c509e36e547de312d41fa3d5d4a8062b05aacda70ea3923ce, + 0x284295e910196398945ebc9090400de8e5c509dd18ab3f4743a5eb521bda7d66, + 0x1a1f21bdf16296101dbcba94854f7c4b05d206a1d08b8796e6830077ddf99070, + 0x257f8d5e69aeed2ff7e194f398daf84d053941bfc75fea450fbca498389b2218, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x215c6089e0a9a6256c901e33e306ac9c415abc1875a49add4de6d0429fde8234, + 0x2cbbb480fa68f33316f0d301f3cbcaa7eaea71e2784a0fabdccff2aeba9f718a, + 0x143619ab2212d1911a586be0f6acb6b8381e47b5a3e34b91eed83ff54937a34d, + 0x2385e3c9ae95a0459e974d29cf0e35f283144cb2ba13aa914b4e17ae5c988557, + 0x2bbe7e909fde4390a7cd944e0f309103447e91f3fad40b752733063fcea07054, + 0x24303758e4ea42a45a0419d88e426c95c68ca5811974c5b0c3abadd9c29d2b5, + 0x260bb40c5f1b22fb87dedda1706c608f78fde0e5b9735ad1fde63459244d4674, + 0x21f27302db4f5b28fe8845806f38ff1f0a04e28434a3e0043bcb57e65f6f75fc, + 0x16c95bed15dfc954a1a4ba25327ee14c5b0dcf76fd8dcc529027230e9c4a0d97, + 0x20996392773e30c8e64d792b010907d8848f28f691e8b2de13ea8226baea34d8, + 0xe20275c14333df445b794b515bd07b8bf90bd8035cf43cfd845976af63519a0, + 0x16422819af615c4a947afa3e272275b5d5bcd75d494042bdc81d84cec30f7f1a, + 0x16329eed1887886307c5a94706efe31795136ede8e9511bc42c77ffbdf22276f, + 0x1e9f59aa3535d598e32de9a4a370c6f4e5f8e6090a9efb2181560fea28519269, + 0x303df7dae20bb862e852232d75fb4f6468ab85a1d36472c3dcf567cbb233dbe, + 0x103c4294a67544648daeda2ec0a2bf81ec40e4c01d75d35be0a04fec32907b03, + 0xd9fb810fe920a795ae2c3dc1b9bac0ec25aa7df2e3628241ace688bbf78fa7a, + 0x235f2eded2c0024a03e1f050c1a32820b3c33f03445a830bd06bedc4654bd320, + 0x27fe4a10ee48d2ced432a47a2a6dd4083e4fdb9d9cf44ce4889b9c7d581ba529, + 0x5c97d4fec77f242636ebf0933f378eeb74467faab3477d6b8230966db1e9e56, + 0x17b0b7d570dc76bdbf3cf5d3def37e0a005c9b4e0b39803490c012b453ed60b7, + 0x4013b73ca35eb02837465c016ae8bd13994c335fa05de42835003ac53ce46c1, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x4ed491d2af18388da53711df4d29318125bdaec68f9134c1b3f5e3bd7b831b9, + 0x16e1f43d878d2cfc40e58b5e77386d360cd3937828d8630ac2e736de89b0d118, + 0x45f7d97cd4d95f8e4e65c183869d4c15d354db95e5334ea1a5f3a0c34ad3bbb, + 0x242af80de0ae9607f5aad4250667e1cd450995afaa5293ceb1f184cc97ef25e2, + 0x2d149e6319f8dfea1e2c1893f5afd8325013eb9fe57e79b3655d626e748d931d, + 0x78a606fb0fae37d1e1a6fe99977001472cb272a670901f0da8e5126b3ef0899, + 0x1548a537c3810897af4f919f5e48b512eb727f3c47c53cd3ffcd5e3a559640df, + 0x1e3e9d29194598291365b7b7deff55f05a137b343cdb74c00037051b96cdc202, + 0x2ae46fd5b2a10a6908761a50c2f71e5f944abf11b568e0a070fb4a4cde0e9d74, + 0x1d5dbbfd82c2f3704059a5e3bf3db7b7f4dcfe27bde2786ea26063cd0921cd0a, + 0x221089932e5ffb0d72b8d896bb8243ce3d6adebcf7bae4ee56967e2b34a63946, + 0x2a5ba9e0c62d377751d13b5fcf5d8e7ba1087e74cf277212405440b3a8fa55ab, + 0x1ed96d07a94876906d0828524563f987414b2a45b4891092481659e053c7294c, + 0x1619ca922cd3654f97cba5f102327d7d6a0695bb3af22e94e33607f545c24641, + 0x93f881501a90112f530fd9185176fd85475f3427ec133cb5bccc6f277a16adb, + 0x2417824b008ac5a7e819ea42ac2e1bf2becb58661528bdc20ef63cea2e355a7d, + 0x1efb091123948573d0c0e6b95a628a617567971c5807c5d3e08bf566a3dc874a, + 0x1f2fc25f030934b6115600b1453820c4c70f8b454da461bc03cf773d033c0fe4, + 0x263a77c0aa2edd316947006fbbf4b3cebf660809da89166c7041c52169764b61, + 0x15d37f58a9589edadb9923907f947842ef6fb4b61251f8373b973dd422a1b940, + 0x76d6d847fcb997548c2b12beaa6a39876569f53e881ce861d85d9c41ce40820, + 0x1e220162696cbe1575cc2f4dd2fed5117c116d52a9965b434ddd7913272c5c6, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x12eedc290453cd77c01e543e57d4d7ae0f6e7a76b576e880e852ea8b8e98bdc6, + 0xbdc3d78a5d0f3a92fd690b227d948ae6ca94d4342ece41593514efad7086439, + 0x2207296649856f043e2d7158f68f5b758b354cd022cfc04e811e1bbb4d3468d0, + 0x21430ade4c0144f819a79b2b6f849a968fb758f76a30f3e20b5f7999110f35f9, + 0x1a70bdca6f11701536dbe4d9926b6bea87a08f6f0efa754b1132dd4e123f7c0b, + 0x285d8e90abc1496915dfdb9e2a4c4d8c42126a3f15f4bcc1d8dc721fd813fae, + 0xe57676068d4b4e3a856f2cb7b22531f5e51bf1c6f09e35a645aa8953bc45ede, + 0x1053abdbffbfcdaabe5b794ee6bef5dfa367d198e7644962afc90f37590c025e, + 0x11660d7d44db731012b02f55c5a19e4b1a10041e0085aff26ff088797f54a057, + 0x2bbee9db0a412ba731979594cea45cdea2a1ea40c90bea1f3ace29d4df767920, + 0x119c59a67e312da970edca383f4e1cc1752e7fec6bde83e437acd6136e4dd63c, + 0x2a861198a0bdb354abc6d273b4f13854cd31d745e627c21ea107620242a8d233, + 0x1a8ac82f57894230abc7f3d010003d5914170d820095f3bbd01e977142351f12, + 0x3548b5e02d4f1f988144421ba37cf75fa0963b14c2ac961ac494828c1e655d0, + 0x2cfe3bafce8aea2bcb3c145ae29dedeb9ec7123b4f3295bfa5d05681c366709, + 0x274f38fbc034b51b94982df30832c69961d65637f808541c50a395c8e0dcd32f, + 0x1154c2e042ce659dfe447ef58e09e4514726945cc5abde427500fc5411a8a365, + 0x2b6203e305e19b7730ed2731f994303777fc1c2a52422d929ba6488c2c164c3, + 0x51917b944afa399ea1e621ee2ad62ea629a35d29387be06c077b79b9569e2aa, + 0x7cf3b4f4f274f711a4bba652eae5fcf6c950fcdaf92e77c118dddfb738d9ba7, + 0x1184568d03c28368300bf5724d6958355470e629221f5221676f69e22b717352, + 0x1857839c2d8b0d6d08c21279cb8a2cfe6138df1eaf6649888cf540965ab3c168, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x26518ee75c590976af8e213b42e5988a7185438e593c9635a28ee89c60bac357, + 0x23645455ddb929ee2b596cabbd5f40df59e219b4efd8c1fcd4fcb67ae42bb5b9, + 0x16d0126c2df72ad69f419c74741165bf6e9f6c2abbe95a022efc903b62d25ebd, + 0x195050200adcbdb5e72bd63ed3e1d4d3d54e4cffe5a5fecd932e9c5684021dde, + 0x23c26b8f07749697bf6982f2e715c91f541b173fa0a3e8dfcb6bca01499134ce, + 0xffacbd7cec2233ce5a4b911dbcc61f87d759ba6e46780179e75f91ae5a720e9, + 0x231a2beac360f4917f433d7ea9eaf185e270778902e6e090ee5e207fbd0575a3, + 0x208cee18da850a2625d1500f835a216ecce022c8b08235c387b8cb1865ed8a59, + 0x2df938f310cedf2df8530cc3ea5ef1254ed966674bc08ab3f1ea148057b6c9, + 0x5cc71f44f496cfe8d69850022a141852f7dac001fdecce67de6265b69dde3ef, + 0x1e04cf375796f4714e6b51552107036d16f71fd0b77e357b61a2014449ef845b, + 0x177060e5eea7e3b800aee099735b074d3bee92ac18918a1be042ad000f861c17, + 0x27f7183ac04ef3b5307e450873f5a4cbd1ff709677de1a3de89476a7562127fa, + 0x272c4143f3f48b711d9e78964d27fde0614c2844861b23c1ba5ef6321fe64877, + 0x17c29df44b208e4d5b70aa3b57c92d0c65e0c4d780793000ab5b3ce79e90ac48, + 0x8426585ef062b24b9c4de439e0dba038e9d539a54ae8c4fa6554924c0f6b03, + 0xafaddc71d356bb01e344c03336f6c97fcf6c0ed9822cff5114e85b7fb18f3c3, + 0x27de3d9113a625f578e74566a25e54bb1d311364887d455699d89e65379e11e5, + 0xe8ae5a0eca1465645dc6b31f66d8356d6fcf434daf1cfba59ab08a91417e81d, + 0x1e41011401e99e5e548f813eb6c091f1ed7d03c1005affd1984e0149a2e59836, + 0x2fdde0adafb47ce46bd4e5d31bb8e840e8b2edded884c6c0522a0a323b078403, + 0x6d047a14724da146ae1314d38a559303e53808f6ffa90af4f2db3c52d2946b2, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x27e98739b0e44313ce32f7c5b552a0814abeb32da96cd82de769b4d0f5c94c25, + 0x96c0e16b0dbf141e6bcfdbc0e2f49d013f35cac3e4235db39c5cb35f96a5e83, + 0xa5a4adbd74977d24c7cee2d6421ee7cf5e0534388e5f9e09b811a0544d1ee3, + 0x17939f4a2fe98de1c4f37b079b35e28f9fd918492317fe59311ee844fc3e773, + 0x2fad1489f14f53e5380db86b119e1fc4ab02fa84ec4b0f283bc28cde6b738aa1, + 0x2765769537137039a892f1c38aeb083dc07de1b728a580fff63f9bcaaf455bc1, + 0x1e31bc0fe231bae89cdd1ee8c3df3d8b06da2f88825e635df9bc7ad5c128f2da, + 0x1e516c3b9ae36f836ab9824f1c10b86a622b2f49f081cd7a50ae5192d296eabd, + 0x47cc90a4be717883e0189e898fa7d9f1dc998f91d255553a394b6b798326043, + 0x1c56d70a6472d972e35698eacd7ba8d40c9fe9fc9b04927d06404ae10ba35f53, + 0x205c05088541f74e95a23f5c7ee1d9913978e98fa759b621d0d2e3b0d57c5807, + 0x16874f1578735735add0540440cb042a966b8ddf3e51b4d812c673776bbc47c9, + 0x240f602afd2d97888bf4b64b23d6e44cec734a2746cf4580c430f72e46feb453, + 0x1abe8b11e0bfa0a5829568b66934e5da83b778ecfa452ee2a6b7140e191e7b98, + 0xc276760c90c65c9f228140185e42f3a7806840c8825bce562d0766a06dacddc, + 0xab7dd18d0804d394424f2b9e37439eb4bf3324198c44e7acc78d2e595d7dddf, + 0x74abe46b34d1daba12f1e78e3cfbe69a30dcc2b090897c040564f023ef7b9e8, + 0x2f240ffafdd27616a2eac36181dd8e9d9ff82f62b54537c48d497609858280bd, + 0x1009c918f84e7180e4864c0e20912026c62699bd562ee5bb24a00fd69a30332e, + 0x9e29496159b70b34f9707a8de9ec2cad82369b2d16885e98bada319d69e4512, + 0x21afdfa37d1b9218daef0b7abbb26e4d623f8ee412934fe8ebca9d9fcc2c6672, + 0x1ba7bae9ba2546ab2fa904877151066a9c5cdd44107d8aa829ba8ea0610b18b3, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x2048256f57c9c8c24337bbfbd097c2627dcc0c2ae00ff560c3e82d32a55a4d4a, + 0x882758c559a9a38ed60d1113da22600ac3de62a8cc88e904342dfbd81f58058, + 0x54f6c1185a58025ca382d00657cea60c9667682c060fb5f2fad74f3d070d5a8, + 0x18da33071f0ebc4b2962d4b061144009608aae89e8285a326c0ba8eb0c370153, + 0x27102a58751c96a0afc1846801937ece25f59ff76675758d5388cce403ab4af3, + 0x234028cc85b8345eda398be9f3fefbd6d59973ded29c6ee52fca866a07b1f7a8, + 0xc3762675631dd7b529256732681b5b48ba5fad34019a65b1ef191b9211bbcc5, + 0xdb907e69984fa1f803f9f19d603391ec580bb3dc8357d170e3d4dbd9c107e6e, + 0x1c5a1126b94c62d06a2b2ec580e5e4a165deaa7cd1bfb0872440de9606900dfe, + 0x2e3aa301ead4fdcb606e9aee72ba7a2cb90ddfd72162ad9478e94699f776f6c6, + 0x279d20b786fb6a7ac5d4fc5d78faf9c47a3090bd561b2fa430c5db64a552396, + 0xa951ccbe5d7d13404cce3fe60751477ce1088102dfa3732e323d055cf38340d, + 0x26a8d4b18704a5aa8e41ea652ce2f60e7975c0b7eb478abc55ba0ccbaf8149e9, + 0x787247335760468918257e7dbb38f97dfadb60256f603d51104f62e4e662953, + 0xb0a7b524cb7c7519436167aeb4b5b185d16c110c2b36f162abfca872b3f489b, + 0x1efceec837f27a592824f15644f3889165bb1bc56d5566179a951333b255398, + 0x2ffa74a07ef6aa2579a1f68f1de64b58eec51380c7dce9b8966c789b4777fe01, + 0x304582e03ea48dbf3043bbaf216ea5970d49e23aeae55b774ffc615ae80d1be3, + 0x1fede6f02a4595564cd768fd400cb5eaa28b2ba191240030e1d757d6a019537d, + 0x1e33187373750a7f284427194876c8ff05ee7aa94d5b3514f6083990d4ad0561, + 0x1c5a22361e914dfae231d634ad2c502b20e84feda4d506a1b7955128e9b24bb7, + 0x1310273c02734e60e3b1f4c7607a48961c3ab97ed9690c2b26c38e36cf56361b, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x2eace5036bbf892b106d6ad25bf3acdc3c94834e60cd380a1815cc4620e79dcc, + 0x2cf399b03624f2fe3ddbf48c2fa326e788f3b6e4b4469ef0d3e6c0cc241b7ba9, + 0x22d41054830f4b29ce6882b49839e9942ae7a1ae84b6d366a98f42f7baf9e188, + 0x15ae7d83075b047fd367659fb588806f23b6be3b4690cfc3ca92c61e71f5c765, + 0x2825fd5f33d362703d2fc902578dab75ca7076ecbbf7cc916d4ed3dc43b3a0e6, + 0x12d12504ba541ca2b28129a673acf96d4f246e340574ffcdf24dbad99bd572cd, + 0x29653490a05368030d3690d4497e930fd4370b0c89d5996b75b420ec803189d6, + 0x21188ecfc9b8a96b6dcf99b67bdf3866314046229ec07c8767cc26ac6d2bc169, + 0x4ca521fed16e4c8271f4101514280093d189d84bb4129d2e54bbb1508b72908, + 0x27d867a046afbb0c3cd2eebda088e476752b08c462fa1a91effa16d22403e4a8, + 0x1e754e7744482f6d43e6990f631a35d9564f0485a116ab971d7c1ba0fc6ad629, + 0x1dff12c679a235887e6c896304b46e3833f216398da1338be75ddfba2d77bcec, + 0x1029ffd3ca881002e4f00872e7af3299d9ae979a0d9e0236d8bc4a6dc36dac09, + 0x2099a9d66b52f0ff88a110bf3247146dc2a39777bc01bae0ca27f3b3ba3f1f5b, + 0x212ed3e424ee90af48f2dfc1828a78e4c50fab366f51ce3fa716164c89787e85, + 0x3fe48adcb5e56246e6cc8968bc0a62eba94984a1472b01f5a4475628aa38cca, + 0x2d726e790f68ce53fee0841e1a8b8fe36b8a756b3a0444ea08af369ab6ff809e, + 0x168de57f2f5a7a31b7b9c96ccb8fb7b33fc545cc19452cc7a5342b70cff74ba8, + 0x1bcf256686de35f672d4e52cee81f74c552e08099b3ecb8c8e8348cd3f36f2e5, + 0x6f7d1f39f8bc8fa314984d88fe0283e64b452e260d4745f9514a012c31cc946, + 0x267158ac0a27dd2e94f422285ee979565877516c414630ca5911efee1a8e311, + 0xc4d16ebd4cb046bf8e0e7fe3218a3f23551c79e8388e65b1c7a557e2034f957, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x22e7f291772140723c33a8ebfe15373f0468e295d1b724f6e94d522abfd5f535, + 0x2c5cfb9974cb2299069f8e21329d54e5ec4f6b837f1727daf66a21af858b56a8, + 0x27a1b5dc716f8f70f18e6eef36ca15ba5df295f9b6023d0c8b860ff0948ae9cd, + 0x1510814b5e9ea61f47e924bf9b21496b391e2efd97554b057bd9d6905eaf28f9, + 0x21ce0a7da429a54515927fcc1791f25c658766ce48934cc1937dea204f64996e, + 0x2e2617468ade83de353a5a7cf3ffb4aadad12b05bcb65cd570c7200059956b87, + 0x284052fe9e822298ea89afab784617fd413448012b8a713d8b8db7db9d111f, + 0x2f1299ecb664233c145d53e9ac62772c9f917ef5fd354f595fd151a739610f2, + 0x2a89d81e36b4e71698dd2968fe86c8bf4acbeaec381985f3a5e67a5ea1318d1f, + 0x1bd908426f44f80f02514742b4860a72c00ae90ded7aa472090e5c1062c3e764, + 0x1a43e9dac11dc11ac20f3cf1edc5eb8a25dab4389d675d9322237a05cfc6b95c, + 0x2692699c30d2cfceb23d589df2a5aed5a8219ba6c436d0d920033b2254ca6a28, + 0x28857f7da86b117cefcc105f4e504eff5f11dc71e1e3718d7ab027ef6383aba9, + 0xdb4febade50738b1ab87405bfd46d20cbd4a222a1f1f8627752cf1b9a76c6e3, + 0x18724360a40cc50d7046eab1f3ccd6ded2edafc5cb4cbffdb9bf734c1dff33a1, + 0x2187d4118b5f752636e205eb4982247b95dab037310349ddde471c782e60fb2d, + 0x709ba7ecd374680134ef58e9403582339e3a55166f7f3943f281c57a275e588, + 0x202fd3f05d2bd8e2dbcf6e44d3ee0db6cf72ed53b00b7f0785605d89d139ce0, + 0x9a760b6af4b4eed3ab69ecb0498a75fc71b815b6bde4a569d39b6086096898d, + 0x2218e6abd4e31c4e2c4e21dfc8a266e946c599fe44b9813f282ef3ac6d24ece1, + 0x3fce74af211c178898a2bbbde84568bc09b8c2228481f7ad87e7b1dcde6bf8b, + 0x2201d6ae9382dc02c5345b141db249c120b288860ec8f99d504eabe8e7f23573, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x17b549a98305619700b722d1392e3f22f3515c947ca97bde2cd79a761dd9a7c, + 0x1321911b787b6c29f58b50a53d66c5f436848103f333aaeba5589e43db1208e0, + 0x9ba5765272979602f4c59c7d7ce1516f48137e61938e30460d262b22efe1fe2, + 0x1705b7f07f5aabec51703713714785de6f86c899d97f3d89ab53459801ad77e6, + 0x18ac4517cd9c3d9b13dd398e5ce614022042b3ccc82fc8bbabeae938af1e896a, + 0x2d2dcf4a755c21bb49b4028fb3dd8bfb641a08f00d045285c0ca64180234a26f, + 0x2420e764bc7ba63b706b6b39a10c092ade7b1873fc1ae1bcecb8374934383116, + 0x10eaafb36f88f19fdaa78ae39af01dd9dd5c3126eb87df41aa55ac344e440b2c, + 0x1adb582c6692385a8cefd33e6ed3c7f23a3252dbf4ce0ea80b2cb5d957844a53, + 0x17b3f1bf0717764c2f01570716b665e2ab308ec61b511dd3e65d6bfca9030a1b, + 0x27953c6c48de10d405e8225bbcc73ea9fbfdfcccaf0a3eda80ce4d7e5ec27214, + 0x15e794fec75f7c4f7e63dec570cffae247d8bbb1d0114270d44bd7ddb5ab3c80, + 0x40632b4454c59b282560f814afb01e9f60c4f24013cb1a8d450f2e23bce9d5f, + 0x1e9c0e04247d8e1f43b71350d991413eefb67c273a3ada726e15d81737717a6a, + 0x2f8dc731a366ddd2b76c0bd1418bc03b207d7065556f4796cb325b8dd1db30e, + 0x24463e539fa612ef3028038bdadfcdade3c8475e0637fa4b1dd3ce10b0aacbbc, + 0x28762b41feb35e6509ad33ea77bd88983e6fa85ca2f6738a1a1653d3bf54d52, + 0x247c44be326d67af902022444d80ea90776936a81592baa6702002b27d6b0737, + 0xa8ffb6524fac8a3820378ee0c9adb2345fea97112c2bdb9a57dd3b04be7f63f, + 0x264d334f14801fe44177ccf924d22e91f3d98e1cdf5c6388b735d60fa32c7000, + 0x1a96bd9bfc5432ea29a24ae3c46b126769d2d8f05cca70dbab11711117f2ed6f, + 0x16542734a0c4983f8b8203a8e67f1c2290f7de67a02b2e4285bf5d1c3049eb14, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x46208656464d4ae0a420f4aebf63b775d2974ee08535ef11014d4400cca822c, + 0x15f6a9ef383741e16882272bbeb9ab135f295272ad7e45a26e063aaf656094ab, + 0x40a8985a8323dd3b2ad3c285159f2f158db48b9fdef72c8c859a462d7f117f9, + 0xb9b4c7ded97f1a7fbb1dbccb8fad09ada8183cfedb790e2f11c77074634a80e, + 0x10700446bc61701c9dd17bc4354ad727247a997ec9e541ee42d9d0d2acc376e4, + 0x98a404fdb1c37a38842752a31bb1d2bb5112fb422bab40a1b546b97c719d923, + 0x1843b850d5cef8871bfd1e31525996416a8550b748cc9fd13fe42aa1f7193bf6, + 0x279c28f81499a1d819fb67132c84220d124b668cc206dbdccefe9478358a97e, + 0x1d6fa109f9d33d9e144c5b25fd5b2f189273545fdadf88af3c4a7ef1f7189e35, + 0x1e89c2383d920c8a80837bcaabc2ae9060bba4a520fc7eaa7fa5dd3dfc18d5ec, + 0x180670edb0cc070ca05eaa724cafb4ed020561150ba343ac5877fd8585edcdb, + 0x44a14d1f731de503ecf2a6438ed17ff8a552a01d9fb66a36fbd08aee8a27a6b, + 0x1391644b83aba3c7c86a81f240efb147fe4c1c53e08ae3d3b0aa02fc1033b02, + 0x1a9373fa92867334ec17aedf833ef19fe6f67a68d031f7a088091730b2d5bc91, + 0x1c5c46a6852eefafee39b8f31935c3325f450000caddbb35538f8dfa02b3feb, + 0x185b3aa7a434a7225057c6bcc8e68180dd404e58e3f0a8733fe64a0c1d534102, + 0xb562eca994127ec94b90e76255955551cc1d6e8412918f9aaed138e19cb903d, + 0x1ab2db0ae479301dee234d231988298fd46bdcf3d1ad8cc11389ee780c0af1f4, + 0x2ec8c3feb4e03afb11402d5929fbc332b5bb7109fe326a5af8613dabe9a6a94, + 0x4dc3fb12329b17a70b760ae75d620133889283cbf88035505ffc97ce4641bc9, + 0x1297d2ec92df98f1ac1a318dc100557237dd9c4a96685f1d58d0fb61ffc4c094, + 0xa84c5d2f491a40654df4992df98f681f157bc9fb4a0a6ac1aad9e0e994cddf9, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x1be6b03ffb55eaa0fcfa4ec007ad655c776ddcd62e7184dde03b1c90b1af001, + 0x2910d31a4ab9e0aca79eddd220c56905bcaa2dbd29b6d7bf389a4c50666219a3, + 0x2839abe3d67b01e69ced2af2ca20db9b2bf359230d7bf3c6bbb79232624a57f4, + 0x2d0c50609fd4832ac428bc6ed4606dc5e5cc48e9965c600c81325a8d4ef87ae7, + 0xa9180406884b203bb35bafbcf2f4abd0ffe90aa9e3e1a82ceaff556d2e22dcb, + 0xd5e3761475ba3a3d55133eb45a945042ee26b747e3eb42a077749f4f3676e4d, + 0x811919e5bf03ee004979e2164e244f1ec510eaf5fe6e5107e5e6f4bd123f77b, + 0x23d92b35fed4accbdc074695f6d1393c5c2bf6f2167fe239b2029d56579405b0, + 0x100576c563ad00ccd2b07afd817dd2f8dba2535b5c38de7bafd08691b04933e7, + 0x24cd184d143196317be3f594f8ea091f3442abcf3647c50be545e510994dd90a, + 0x128748993a58cefd65bafc84f486488896bcc8088006a3f7afacc28afd6fa380, + 0x126980393d9f697cfeca3c8cf5aa466cf7699c7b24ed1fe2bcdcb3d98e01eda, + 0x3d53b1b0659c95cef35a515696e13d67643790564a80ee3fbe3c5b2ff7dbb69, + 0xb1cbc1218a01ccaf22711fcaff805b05bffc45d21458e41527f06dbf423fb10, + 0x2d2b944d4f9dfd80472bab4f0ce520fca635f74c8b9f1e1ca0fd52ec8af49ee0, + 0x286ea70600778faee3383939faead69a24821fb400920778c7529a1b1c90f54e, + 0x1238e08378044550a836bcfb7129f0f0d6253eba654e96035de06513f6ee738d, + 0x20d38b283f1f0abbbd99af81d226cc6503ad86ea1a2ea8e9419ef15a74f8ad57, + 0x25f5d1c94a4423c994f81d1f5726c8133c5d2419fa58f226a94c09b61815c2cf, + 0x1ba4948c72f33685df0f9eb2f6678fa6bdde0ee261faab0a63917fdc30f0973c, + 0x2a306087a9453e96d0007ac70600c3f1e08b4fb5cef04232b64fe8c0598674cf, + 0x9e528bcade9d9b1e99ed53a6ca87dd8dc46140d57d0699a8f120e0c77af65bd, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x2a779727d7ab06dbd553a840294589296f3aabb6a314afb5b083f650e39db967, + 0x11aa7127dce97c6f4beee5dbdde1d5c7de812e27376e249f41a52171c108324c, + 0x2e6df565cac73a4a04c2cb1fe541d9e3df002054622c790a6c8c778e484da06b, + 0x224c4dec007432ecea73e548cabf60846d0e6b72ed2f4c907dd9e03dcb381e92, + 0x2095194e2ecab4e0e731ec6e1cbb0aefb3bf646f6e6c804be5971167ebc58f76, + 0x2ef057063be57233d59137db76c7252f1d2cbf5f3c4c6c8ccb22203c98d6e2c7, + 0x15185ba1b9b8060768c5af0f70636dc62fc29ca5100d76fd4f9c4767e8f87fb4, + 0x1ba274d2184bfef2d0be986fc2d41617f43d29a30b328b6ce3fe41a406669532, + 0x27528f734c66543901cb1afad7414892ae14cdb75ed5fc59fedcfaa399fe74c0, + 0x1185229ce9c183d7dce8a64999623a469392ca6d2e4f72bc2b6c4772a6b04896, + 0xb36b20c33f83d20c1c49c00c65ba85deee8345f8563df448993a99bebbef6d6, + 0x1ee843386b3aa0c38471fe7c60b638218ef9266b542a9b1526deb8dc9aa3c559, + 0x107972f77e0382e5d3cff5b6858e85fe6ca29cfe95b60159a9dba68cf55ea21, + 0x2fc46021b9841db9dd3cde3ce58785eb5f5b9600c8d5c0f4086130cbfb261f5c, + 0x22b8c705b7b675b691343c7f19f68e23745e55aedf5eb931c37bd89563f14a8f, + 0x1db0aae1de8a581770c890de5e66c763301cc6d522ae042db366f330e87013cf, + 0x2b17c19b2ff64a3d9a5bd5cd0d4a21cae7b7d7c899228050f593b2da46652d3, + 0x1e3a4c2c9686927495d6cc3c6e90b519deff0b55ee3124d69ce5161c91119baa, + 0x384603dcc8e7748739a4f85462cee5fbc25345e02db231f40e50a851758452d, + 0xe842866ee1599809910ecde3d7ca9f1d867f96459985ba119b51066866224aa, + 0x19c09d8567e90a622516fd1973ce27ad5fcb66aba8b248d06de9ea306a6fb2c0, + 0x134176d3a40f1bcad9f536bb92b8aeb9a4c3d424b14cdec9beed77bffbe754cd, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x1918c06693a26c41f0025c99e93ab46213ddac227215fbe5d1972dcdb6265afa, + 0x2c2d3ad00fcce75da6a5f510d5952918f446016a8fb4b1dc41af9321803468f2, + 0x18ff4731631733dd9f048503b481b9b7abd2ad7dde5a002d8e0ffc425f574c09, + 0xd14a3159cb458b4c5d65765b15c56653be2cde202d8b285f5c2cac7e01d57eb, + 0xaf7d40dbf6a9d2e138095f1499e6505c326422282f1bd30fe98d19590298e96, + 0x1f728b62200f84d56fd916f1033868066c5ff9eaf81726ac8f43f08f311bd806, + 0x2f1509a804a1e612847578f49ef3d4cf0067adf3c3575dbab3632f6e6e3dd5c, + 0x41c67e015b3770721ce4b96ae6219e6813ccffb152dbfa13fd37d25ba812f06, + 0xc336783fc41679f67e808e2eed1be9cda3fcee2b04394812df95f9febd467a2, + 0x1e34badeb3d92a88aa84decc7b70ea344c8852c9a17d3e0dcfcfd49f9d103548, + 0x2539fed64ca5f8bbd4016404921a292c7652ee3a7fba314d675e02ef29f01095, + 0xa83942d60d14f46c3c9cdaa90390faccc4fcd2e9c3ec8cc06604cd51ac820d6, + 0x2724f8dfd70e0094d613f65f6b48d42e22a961d06f589ca1a64b74e0ba9af8a5, + 0x226e101fcd7f365ac33c608817ee6a4c143504927affab95f4d7f95da55983c5, + 0x295d81ade71715f0c9071986b3771fa8621bf634006463df3b53dee9bf37b189, + 0x14aaf0e78ca5884fbdd6282dc2a2008a1b6165adffa6e9160a9e36190eb81afb, + 0x2652e6b66e323877eacdc4e0f32dc9f72d692ae7501d7fed6c96154529f45a39, + 0xfaa22bf6ee7ed51ebb087c35bd33ed34bd4474073349a80e9c9654883091a95, + 0x12bd1d8d922cb20e1d0e02d066b120f26a1979f4374bf0fae43cdcc0e5a366f3, + 0x158c1a5307ed0d18b58986c274968b23e404084a78aba5687e2e2c4f009606e6, + 0x28b5ba99540925c874c6b815bd7303dfbf774c5e1012ef2b305ca47559f597b3, + 0x2b845d95e442fcc4bb8a49be773609957b578e19ee28baa880226e3f911d26ef, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x1b66e79c663bec66bf23b5cbbcbe9bac308c47817c3f242d3f66b6d565be3b9b, + 0x79f775f411c9c90149e59e6a34d6f6f47947db4337d9d3c18bc4b51d4cad270, + 0x3009d6cbb50dc688b7404cf82d589fbad43d0742333927bc049e48da6913e606, + 0x1fc70661054fdb2111e49907222387ad311058d73c0befd6314478175e356942, + 0x1ee04e8ba0265fce330585518894029b62d9bd50c9d0a6f87f1280e82859e9fe, + 0x644f526b432da58421456fd00e0e29291e8d0df2ed27626c42d503c62e4fc9, + 0x27e99dd0f8fe2ca6883ea897815b333de616c56c483c0c9e45283067dff3c4b8, + 0x581ac976cadd2b1dfc14d8b3cc604f1e8e79dcfef24b8f67032c18b90c17e9c, + 0x6750f648570d1eea536bc3842e8a9673cc564c9784e57793475bcdb399457fd, + 0x15822b758ce9dd864fa21222839e7eea4132d1b800819ea095a6465d9ce6044f, + 0xd9ee290eeb8ccad8fc7bd054d7e10ff3eb0e3615f770151fe6a276d53da7738, + 0x2aff79aa26d195d6001c0805b35a8c05a08b59a0e819c7689f176ab29deb33fe, + 0x237fa4d9fa2fa84b58ea68d75927afee778a5e476073a9b30d6328ad62f2d807, + 0x5d20936e308b6eb8373a899e602831ae0cb091abea22cf044de6f0cbfe6723c, + 0x20470a9f2d2a3cad5d2f92c333444b429333625d0e07e064fde8454fbee764af, + 0x2e5ee062393b836f391171b5c738e5d731de49e833031ce97055486def2d6a1b, + 0x15066a745e56deeb113b9dfa9e92ec1fc4003f8dacebb4f2f0a591e9491a96fc, + 0x15af3f3747ee7d63738b4b137be08c44f0c90448307d1d2d97788fdcaf30238a, + 0xa9db2ebd67bcfd0c5c2e2baf93fa206537a0be5e295da9334c19515018d4dec, + 0x9d819663eeedf9ce5b97d71abcaa195f6ac0ffca2e4a99d89510bd29da37cc8, + 0x43e45a7ab55e8ed770c8bb140c5cf98a079f0a286c76abd11486adec2b9a69a, + 0x267390f339be917c18588ec7f9b53eddda42bbad0e44351d1cd46421389b06d7, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0xdd2adfb2aa3b4128b087b5250d5e754672ef02ca8495a5b8f9c2e51d12fe27f, + 0xe44bb76a256740fe47a818596b6dcf40b9db85c744d3701bfb808a00f7ccbe1, + 0x68a25d2e27da4305caea7b47ed35d9712720f654d72d094e4d9b3796ce88a27, + 0xa6624b2e2d3551843723976c9168b1acd3ff196804a6cfe61555ed0048c3554, + 0x2830c3937da98493bda628849823e656aea96f309f417ee6a4907009a4957fe3, + 0x1dbfab542ad1a8d1b064c18f2da82b6e5320e8285d33d524229aed44da0fcfcf, + 0x12f049967453bf43dacf198aaac17d184f44850bf49820b37f36df953e57b08b, + 0x2ff0b4f794179f6cd4d0431d7aeca0e320270aa3b0e3f63d832f1830ced770f3, + 0x287045969073b1ba8007b65f351ee152d9bbb0e68c75fcf8a3a3e0dc9cb9935d, + 0x88750a390f67a5b19a63ee69e6055949015e796d41a2150f8b83f58c1086b4e, + 0x2a1b684b9357c3b9b675c9a56d3690d3b101ff4c50d5b7f97d68d6a247ad6e3f, + 0x924a953beb10fdabf6088068bc42d18c47a292d33fb12b1dd11c0942051a5f6, + 0x5fb81ee2e1ac5e198c62ea767270d3b52af1e24d4d6857f82c2ef4b94f39740, + 0x1afe1a783a2d68ce8f79cacb2bc57502c6c5ec9ac0bbe35f55b34bd4d944e15a, + 0x128e66b9d177d588af9f9a10ebd195f03030cb2806560ccec1c0469ece8ab9b9, + 0x2a89bbfccffb647312f31a2b0b68d731f65279273447021b716f8d7d1b9eddbf, + 0x2d2c1cc8346008effbe81b219d8dbec37bbf2a6f6dfeeac3b979b761663404ed, + 0x2a10df4948ebb56a6d1edf6b2d7bc7d7bc3b3a6085565a90bccaf53739093eb6, + 0x29f0a91579b0418cddeb5fe403d13c929178124713655833284ce4386673625d, + 0x2d60032c705ab2c8e457ee0d225acb206a5cabbd75b088d97656de6df83db165, + 0x1adc61e3889546408f21d1e1cd9533415a7cc177598464799da86e31778ea854, + 0x15d24ec281355e28a085dd996ea0c90aac7efb5d87f9bd70a2a6b9db6b50b7ba, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x1be40669c4305af08dd9cfeb05bc7fcfa40b998bc74ffe11302c4f5b0553a38b, + 0xde0e333621fcd0fb11e36805f9722b7d5b53bc39cec2c63a02ff853f30c04fa, + 0x20f0930ce2a982f6372e84ab5310be3beae1b0b7f90b8e562c26c2e757702d47, + 0x299a425dac7d3a4c877808a7459597fda5984c422b6a994d81e195f30385f8dc, + 0x2f3b6c085ecf99a58b7507dde8971a225c511bd6f802ee3a6cacc0530e8a33d2, + 0x1dbfd1be6281a5c77b4fb2c7dc937a25dece301dd371ff67769ec907ff76c72, + 0x2057718828a717820912bf7aabe85d74d0e759d3357db223cfa111b82ef48f32, + 0x2634e710d328db82ab3d5c000a6e16e4cab4cf0b5c10975bf684488df5d7767, + 0x1508d73e31efd2a02b601a7151ca176fc79f3721fa686f737d66b4a43c1597d3, + 0xab1c757a2930fe704ad42fd54b19104397077d5e52947a92f810b0ef5d87871, + 0x9da497dd64c5e3273900635d09193df06c1d2426a0fd73d7dddc99c18daddf2, + 0x2381572e35bbe9d3fbdb3bb1f1963bdccc535817b1d3c077e51d7fa9cd9a6cab, + 0x1435a49f928494a49e2a67e4028810e23b7f26843d1e22e2d737b40f01da11ac, + 0xa41cdb54589156aab59180023dd35374103e5a4bbe746ed8f2fc3ddb26f8e25, + 0x14c484fdbe36491934a1eda09b63b86d803e7059cd8e3314e8d774b7910a7cfc, + 0x2a77a4002da2b4e2ab43232ac86e8fab1586b84ef60705d4f5aef26aa5421749, + 0xf63b8eebf3c4535bda0b094c007bec3bf0ebb888ceeb957858bfd41e3b33a49, + 0x1277d3fe5619089508669b1a53372f2f10ea0acfd07e684219b7526be3566d69, + 0x242bed90744413a413be2f93566487aecf7ed35f2f6886e79b95fced93648d2f, + 0x2f421f7536d6fe02069b4a2be1adef885983ef7ff87af5bdbb73904f96cc7044, + 0xdcb8d37d53a5df0f9ff37d9f8e111e005d70c93bc23557f6041711a167e62a4, + 0x2b8d52018de42ae27a896a6100b02cbb428bcef7fc95c21e0631a0edd273ecf8, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x20ffc046123c9e7c161ec2fc0033671938b1bdbbb51504bb48a6bb7691f867c4, + 0x37fff4149f4439e438ce162d27ada4858d0292fdd5cba6ad88b72e73e552b2d, + 0x1de8c8e615fa608fe89f596053f7f2aa3b21158cf1116eb6bf12e98bdc5cd339, + 0xbe3251cdac6825fe72f5f701c19215869c21db3e146faec1b7d83e291deea6e, + 0x25cc68e0156fb406fe6a1d01bf926214705937bbb2dd5af7d2feb70cda04b273, + 0x1e6d41a49f875455a20e395c2f5466ac44d906c5b77e21cab176934d6ec92fc5, + 0x2e67c91faaf0d61303858bdce074a2f61220d62977a4d6963640808413273f31, + 0xd12fb42faa45cee5774d38145639dc1393ec43ceec5d54b8d81f8ce3d74cb49, + 0x23e70a4146133f0a77a4e1d743720692125531e4b83edaf6cac156afc870df9c, + 0x2df6f710ec27c2d652198613afc234f4c6d65ce1cf6b5488b3984e0976f75cb6, + 0x195ce59e69ed9141b51479ba07aebb50eda0d40c16335c1dc3371581b006b9d8, + 0x210f8fd97f1707c4ff9610daf5bece6fd2a7e0b4c61801662ba3aa177decc92c, + 0x25f1b7680e11f44ff74657d2d3bd43aab044798def28b435e75686606d12aa67, + 0xb2c75ac5a5fb6d2b4fd51256d3aa84daf97cd4611e54b1ce9aec26e298bbf88, + 0x78398cda47317311211740262c08710b86d61c54ae55636a4d15220da5b85e4, + 0x166af5abc6ac2210fc2e48e17a3426b597bdcaf849cfb535d3a4a83a16fabd84, + 0x27194ca79ac4773ec964accb35e09bfaf60f65fec69f6c53a45ab6a7720410d6, + 0x10c46d3c254d57f49a985c74732f27a402232da4419eee8d59c39fe0d25674ff, + 0x1621881967985ae3b969ef554ded7e95027c80a3fd24ac8233b7204c46b67b15, + 0x28e893994343597be2f4993da693ab68a1b6530fa187e0708e6dddd65e19f65d, + 0x5b240574850357b93cf99c2a4fa39529f34cd568be5b51fd6bbac19d66a13ce, + 0x2a3e91c0f5583245a4519e6d5fd37530ea97eabdcd9e0d2655ac4709a88e6b58, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0xbc9156ea781bb2f4a48a6971a1463c341447af7640c0dca22fee678aaafa67f, + 0x216532d67a620605bc236aa3d9967bba132c18ed4dc9fb1c7d0b6e414b69ed68, + 0x22ddb91daa4a4545901d12772b1442f5ba4e85eee6a77637fc31bf513fb116ed, + 0x2683cdb3a1a277aef9c2b9cc42d9835ac8731f42ee8c1d97c91843e330cc797e, + 0x2be49377140f55de27dd9605e7ae0438bea87e1027be1ccbd27547bb1882a71e, + 0x3aca5d3892e4e23a82e32970ae06cf7944979744108cd4014495820f3f3cafb, + 0x67c57ee42c925a4fd7f0b70805e871b1dea5c0c64eecf286f01a7f82496d0e, + 0xae7cee32928e8bb4b2e5428f6ed56733a955dbb415961e58bda4537603370eb, + 0x270c6be726a888900c325fce8361fee0766b4178288e29892e43ac4bc5a7a53b, + 0x2dc8ef31b5b489de3a0218cca5215bcd23860891d4be8eae01bd6b6a9fd89e0e, + 0x19643edd20d71982a49a09cb1e0db7d981d928413f5aed74a20b339a45cb3a1a, + 0xcac86cfd70c7bd0f964e2186efa830356866dad5402655391b164da07230607, + 0x1e28a98366dc2b5a1dd651c8cc239f7d6a65784260e4f99d5f22d3acbf089df3, + 0x65e579467ee3caf9abf6427ee70e3f04350efd4f240a721ecd614bf510a6d15, + 0x625a0ed5662a51dd09f1b361ee979a3d90999de6544dd012e0a3d0ca7f54290, + 0x14ca160eca3dcf16f63e65745c1fc7da76bd228af16cf74d2a322a02c2e63e9a, + 0x174e5a80b5654227609644c29b2ae1f7346475075b95bcf09781b29dca6da8b5, + 0x159f373903a0a9fa1b30f1e77887b7f4a13c034eee827f0bdce9efc244d50300, + 0x1e6a451f0965435e18b8c68ed523a5f5700731fee946b446a4a56d697a65e136, + 0x292002d89878ccb5914c5d7951b45952eb8a48c0d4b8ca78af9db15c0fffd2b0, + 0xcc6c8b2dc526673c038b258a850a754ad3da11b01690ed359b1073e37ace2ba, + 0x2abfd63285e9ac80fb865ff2fda5da230f278f9020001f8172727bd6f257059a, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x2854b5984bd6b9e733809dfce1d7fe5ba63fa8d58d57e4cd9f540c2368db0dd3, + 0x2e88865414f2b4557548e383c7f525f471c9fe0d8d64f0b8001e630ea88ae41e, + 0x23790eec3f5a240f8398eca3719dd949c4e1b4c483a16aeb268afaebdda79a0e, + 0x2fcc8669dfcf04fa06c75b022b77b84d090df3b822dbbaad1fb8e3ee948e86ee, + 0x67fef650a45711037a1f204eac29045803fa922ccf8ad518334c03a29178838, + 0x248f8c46bb3f0bd3aaf83f0c410c0e56d9dec620820ae91d41c03c288c0d998d, + 0xd3b6a0004a85b63a85061b171d87480cb262b1fe4ccdb71be2114f4a8b13fa0, + 0x7b065a9ccab6b970669bc32838db4c48147f0661f53929f561a7a835fb9d567, + 0xe02b6d12d48362677df07056afc1bf5eee55cdeea65044de0648a0c7c0a7894, + 0x2fab90c9d26772010fe914e4b88a71e32f5563f4d4a138855f7ab4247252b84e, + 0x1989c2e54741cdcb6cd94407dc6ed84e7817384af807ba6ef8b85d4bcd313c5d, + 0x28de889080866bde3f19d84b253477607071c34e59569f2fb0aa180b44df1418, + 0x2804b79f457cbb808d034036efba0011bd3ab0419c39b094a7341eed26a322e4, + 0x24eb9b802012e11386b4ed5ac52da70957cefac5d3911ec1f042917e479bfa80, + 0x1666ca210112c32bb19b256acbacc96f58cc0fb7dd93874d50021fbc631b80c9, + 0x20799de358137dbfbc623c6e4acadc25845bd214d4073f52b8024ca43d99cd34, + 0x1bc10c44525f82f98f44fe8951d669c8bd1087ec8fb25d08c5da11ef1117e052, + 0x1d8dd037d73544d78d4811ce0d6b48264449172217cfcf67186eee425e18cbd8, + 0x2fbb2fcd6bbca136c183d5f94582c61f194aab068f915bfe0d85cc5d4b82bc08, + 0x1eeaaa5f7e1834a19655d80bf2daa1d2cf50d73d18e1973e6a74c487030474e2, + 0x1f7eb06d961fede066bfc2773ce8f36dd7aa35a727a60780719f0b9a627f56fe, + 0x2981fa5e6672d977bb169d70e070e73ab9d7c3f20950b3242e9295b45390f46f, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x28776c75f54ae00f3190d1e711194bc03ff39d248d96027523b166f942920a86, + 0xa4ab73336b833957012f0e7bcc36899849b2db78f8fd707b692578e14b80328, + 0x21ebae99beab3aff541833d68c75fe506d857d8919a97e07e3902b919d3e143b, + 0x3029aa9bc55b8d1ae128f45ba368cfb20896feeabf39b966d0c12742bbd28bd7, + 0x239128973757a7e9c8d29d5336d1a53b277387b48afa946628f45d03eba49de, + 0x10a0435f8e32fcd6cd5d8ceb3a3c078227b5cbb69966a76d7f1d751e594479d6, + 0x2f5d49c2ab9c95d09cb160a6ddf47a0763fe11fc3504478e45d1d07e641ab29a, + 0x1181af9db194b4bdd65f61e51a4f7d562307f5745522e265198b320ae649556c, + 0x1b9d2c4a0df2bc6d9d56c76317180d89b9660b0e3ac54e2e7ee83868ac39a621, + 0x1f5c2501487912b1ef65f072a108f1e6cd640b1eeb0dc7dc0d579032000b8570, + 0x72c3f6dc95aebfeabd7b79bff8d0073670c5fca43b5b067caa4828e67bfee02, + 0x2328cc21742ae15efdbbba3067e95d0134f49ca25303ae9872315e29eaaf3d1e, + 0x1a2d67aba6dedc8f6838af4f2318ef7575a0de251cd8bd4b9944c0a96d703b20, + 0x2eaf6ca068bbcffdf36dbd475ae928d10a2055dc10da29f77ccff5204c506876, + 0x233188598d95df9ea9c86b38db0027051e6a4bbf4bf27711ed16489783187d5a, + 0x7b462ddad87175e51fe8bad7cb756973ce7763ea732b3f64dfa38a0a0cbde51, + 0x14bbd08ca052562716a460cd30d0c3d20a21db0742da1e4021feaac3a8da738c, + 0x17bab12d3266540f45d4ee8beb4e4f01267e296fc291ed54d0f4181a87e0a53a, + 0x2a168a263170030f88743436b706dfe82da391914f492e7c48a2f62d56cc9d40, + 0x233927efe170a047d3d309380bcdd2d2c7bba7541dac277c6cfcf3d1bb16571d, + 0x10b9e5f24f1f4ef89886d8ad3f571f8f3e8633eb6a3ce7a00551d123a1de0548, + 0x2767b7f7b872770da90c9b9fa57bbcd766b878f7bf6db0a1249ef4dab08c56d8, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0xded85a7aa57678558da049aadb3f84b88357510e6424702731b6f39e9824eb5, + 0x66bffbba5403655a7eff0286ea82797fb1b78ad448612d5e5ffdd513979fe8d, + 0x2be44851213461736ad1c62746a446b9b9ea157f592c1d54f3bdbca0e81b1d28, + 0x13c7aff223c351a0136cd825f10e41da937896c3eb153e712cabbdc0dafd01a9, + 0x1e1295fede0148bb32d784c659938de19d63cd8f070b793f4af6987d4b0a2ca1, + 0x108e731bd672ffd58f3bfb3d66c3281da9a79214ff667756c3193331f15ec2ca, + 0x28ee2087caa404a7b9c88d871ea969073c05aa2d7f8c8afaa372fbbd29fec908, + 0x1929e70c3df9677a16e6bc3ca6c8f45435f1781bc7d3fab5c2d9f21836bca492, + 0xb328f15c14da87621bf2b7b1482557b0e1e4b62ed771ef0b5c0dc2839391a9b, + 0x2463924e854fc278f78d41ac3ba4c82e9ae33933c1f673d8fb988f5257ea48cb, + 0x206b2c50fbd93e4ab16f20b5e1dd4e31b40b410bbba02146d1a7e7120a0bde78, + 0x22a8169f4dc83f66b725c9db0aeaf6944c49f7f59e084741b74dc75f17a2d582, + 0x131beaf6c38d2a148c91b01285e728d83c5b40309f89f2ee1d69ccac916cf9cd, + 0x1f2f76bc23a46c9ed5441b8e0e91058e2eb16165ae943eba8b61f7629f38708e, + 0x350963d2c0aa84941005b7fc8747fc61365ae03a600af938753c62384223d64, + 0x1f43a719acb173edf3cef4ff57b3e3b54434997e03bca2ac3164d6d206298ce3, + 0x2ff2c8be1964373563d96804dcba6db4f2004109e4d73abe431271981c9c8004, + 0xc8aa745ddf7f419258d9f829ce7abbde1f5be1343ff89d90a597b8101cf3317, + 0x8ec029d60cddffc7b81dc89586a6afc233826c1641ccad7dce7da7a0d552002, + 0xaf6f27d2211b12aee10a405ba1959fba32e4da7012c94dfa822b683857685e1, + 0x23cc9f4ca99d30fe0d7780397d7281775e7359c3be70471bc6482193ca3b318c, + 0x5de7e88f631488d23cddebbab25e128f8cdfb524acbbfeaa7d2d0bf47c2e7f3, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x2ef97e821dcfca90bccc266cd3b7cfe86037c961414b970511a845251204cdf9, + 0x1e74c0e015eedebe75a4d569561ce744107d8f4f5406e65685a60f97c00c0c77, + 0xb9e7e57a6287f13cbf8760fcbd1bfb988e1dea2f70bb4352fe9acfc560d3a4a, + 0x1daceec3e24e703f54a27a8804d960d841af5a0a10b4ed8f2d5aca46b61ebdb4, + 0x14add4559507a7ff29e4e915a30bcbc79787408a6cc31c071199e81f03ed1b12, + 0x214af846405e33b9747a25b176edcd7c1934c101d36a2abb81c958a8be7c06d7, + 0x8f62c1e4c1e9fb62f1ffa5b262df316e32b769414445444c4e345b6e6a8e3d1, + 0x281cfbcfd9fe3fba3329b1e3d6da6ac72e3d401483efa9946cab0ab530342c59, + 0xc4930b204d10bf30ac793f21dd5cf84cf084aff28fbea40474f34056c4b81b8, + 0x75717917a0d4e210ed37f81df652af88c78224d99d13d46dad5a3d040907c65, + 0x10236e639476d565e1de655b0f816e859b5b3b38897ffea9ccdc9d95580dd0fa, + 0x16535568d792d43083a2c8a155e09645cb214c088e40b70589a610675f2b9bdf, + 0x209b82d2cbe5617f7cf4b7ca05f0bb1dd80dc2a652b50a23e68de856334edd78, + 0x10d0843c37e9ffcc0692fe6018d480df45f96e2ad41bf9539197ebb12ae5dcb5, + 0x175f7935e1d6d289b963b039c85cb1a3ffcba2f681cb27a6364566acf5ff2d1b, + 0x12f9631f7d9cba5b34733142a23a76a4e9bd76fc838bbb865a72aec17a3ba09e, + 0xa27aaf6ad1953f49c5240425b509144c9998735a59e27906e98518f7bcbcdf6, + 0x339c108d3ddd07caeedccf45ba3a1729cec3387338d45fb0b7b896faf618118, + 0x1c7eb764b1b6372c8a7f18549edb2dec9e713ec618365f169f0633181ed21da1, + 0x2d06b5cc446ac8715cd21b1c8889728aab4d3b5e7f4eed7faef3530fe3766440, + 0x183445f90535b07b08b20073ba06950f500eff3d0962ef609a221fc0df504b0b, + 0xe05fc0656468b85eab718ee19bcd04d0154edc633843570adc6e7d10592445b, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x6941082d94398eebb54a701966a9cc45b303a0989725381645fbd0ff97d9d66, + 0x22ea9d22606530112502f8e40f9277e1a334e8eeb307a03e3924ab8c6701f186, + 0x16ce67e884bfd1782872fcd65b18b3f27af8c1edfc8ddefcda53f3669651df33, + 0x11fc35853f485f0ae0902c650b9749b481e336c553fdd90f9767d8bfd52c63a9, + 0xf04c0f3525c56f533b23a4dd4deeb7b31938dfb1531863ef1c2066e8758dde0, + 0x2e15668ff3beca65235e7912fed8b7ccad0928136db06090fb6938ace207f363, + 0x2fafbe916d3af6fd0924cd2973e1e2474b10be1db252cf038fc32e732484bf7f, + 0x9749b2bb5e6668839c8be56fa468598f7292780e294e47b155c12322e34a0be, + 0xc81643458c5af368b81dcb405aaeb3000b4c0ba29c376855470cfbf2c35e3dd, + 0x2f7745d6f815dd3cbe2c529c63f07d4a646015842c6678456406a248252d0f78, + 0x2540261ae5b2a3becfe0ccde660cf756cfdfbe8fce0713c061da7eae6e5bffcd, + 0x1af533c9109087f14eaf413f798f4f0e8d9453e7cba136d9f5b2e680e80ac911, + 0x27115fa52689f8b86f2966af42504d25dcb23d541dd6a1f5d328b37b9f982352, + 0x1f955bcb282c2c0e74b4169a61a510d4fa506ec8a905051cd4fbdc9ef1130654, + 0xf13fc20a68d983add2992ef921aa7d9294e574b8a0c697c5d56622a585ef6b6, + 0xe480c1fd8e61a5ed800036d9110caa9a55309bc46a4fb1d7756b7e96ebd2768, + 0x208a8b0cabc7890d78e18028768a0a37120ff1e0d81cb9541bbd781d3fb5a679, + 0xa4bd40c175726b644c3dad0e29d158fa1b1753a4a59a1606738c57026eac391, + 0x859bd87fb95504fae2c58816724777f1c93a172de0b231da82c08935a950dfb, + 0x1572f4f0f2f44e7ab54f3d0ee208d13bd9f4a16a2be71600d10651b35483ccc4, + 0x2595802b887ba581a6463dc3dd4e29be1b0977c87a724078d84fa16da9b8adad, + 0x28290084f5f35de74591e06a61e7a1d696a79b2fb8db90d5a3deebdccd483987, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0xdd61a5489d4bb7be05223e75e80040cffa4469bbc1d2ecee02d0d5d99412e85, + 0x6c52f4f90d713744ace66a17d3171c6d83f5abea58367a3aec7d538736ae17e, + 0x284ce8cd77c9caeb5222618bc77d4c3d299b41cc74812489591bb1f23a5e8a14, + 0x1e914c2446466051f961f69baa9b00c56f018232a1cae8c6933a1a54efdcf1aa, + 0x1f9f1d5d61c22831aa9647a5b81bc92666882640968d63c03a338173c0fc392, + 0x1381629462428cc21dea769021a08fb83f68960303ac1368cba88b871865f06a, + 0xb272b9552f9201b03d7ebe1a1887c7f8271ebab08e81ed125a70c8f7764e1e9, + 0x7b4d12c7e949d4ee6e2e0ea93dc105afbfa277b9373af2d12a6ff64e45356a6, + 0x1b38520ba1c4589fd42014d6e8049acbe95daf2c4c2d910c44ab141a86e21ac8, + 0x1f9ad110bf1bbcba3edb9173790599a653793009ec8ab285cb9567a868e41952, + 0x2e5b599ea8d25fc97e621eae08d130909178d450803edf6e853584304f3bb0ed, + 0x1b15f498744dd45c644224cbc078e921f7c1b3e1af764a8467257d6c069fa18f, + 0x1d4cec7d699719620437c0a48f205caa856cbfee94146fb0d1d8dc66c465f4a4, + 0x173543ba0e2d1b252191c8b9392abd96810103fa3057903aa1697429a9bb9185, + 0x1b9df3514d0b3177ea22b6d61bbba61e6ecc5ef8766404333fcf6f91da0127cb, + 0x2befa98a6a5c83888ab8f22f9504c9db9faee563278a894ce253b34980873ec8, + 0x295db1d483a66191171deb6a0b95d08b843827b02f5e691aaedb0845baa64d77, + 0x16fce7e0da0af20b730d87e50ff3b8153e377304d9d262bc3c1e2b4438d0e189, + 0x1660401c207ebb47773a099e512b117987bc8d102a2ca0a7cff9947e2f2cbd4, + 0x1bde105e9ebf2795607de216e544e9638fb23ef1f598ccc6066a5b1acbbdc1db, + 0x5ff2966cc2aeebb42f6cabc2aff4ba67881a3653168b1da8919ea64188d4a4c, + 0x1de18595180cdece76bc7a389c725303f8114625785e4f8e7cb987366b7d8b50, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0xb75306c52e9faa2532157457ca751484e5de2cbea41a357481e6be641c4feb1, + 0x4c7855c4b3a6e6db0595c294ad58c4c3a41ab7a671608e04eadf389a77d5dcf, + 0x2596ff7a33d026067f427e76dee78cb0cc93819ab599c3bdf93191bb9797a3c8, + 0x8aa0063dc5903d4aee032268c89e865b3269d7545ddb1084af2479f55225ade, + 0x1548a8bb67459d26258983882563f449a56c01e3df7a608d086eaab22f93708e, + 0xd5ce47fb827e13d9eafa9befefd32eb089ccf1c0275c85946e2dfe1f43e8cc9, + 0x1b5f4423b16a0cb4af1f7bcbdcaffdf51b021924dfab1be7fd33a56647a51999, + 0x18d535b7160e89968c9633cc71fb2d97df3139814c12fdadc1e5a6f7622a7c00, + 0x16a0d6cd63bb6b5ff4c2808707201602da7d6b0f44b701e8393f98db43c24fc7, + 0x232c12d6ce6ac0ab8eaf31cf01f9f8d2cf50d24b18ed216c6292672c8d5b490e, + 0x27fb96c5c58c40aaf14a9cef49cef5a5c0b60471fca8e907c4d56c092d8ba385, + 0x21ad1bddeb6296215e8e20714f3c301769cbb0436139ebe0db55fb961cf97738, + 0x19b16870babade7b8ac30c9e62817064ae98a876c93675b2398533783343e63, + 0x16fdcef57ba6577e0c963d013271e70215c8a3bf9e4a0d6f93be6a4e9faf2d00, + 0x830ce701a93a0d7f92677aa65d53ff28af57c823098c256fc1470b3005f546e, + 0x2295d7c8b14f2ad4cbb0f762a54c58383fb6a8feaf9d4e9bde35b95fe58ca05f, + 0x9b1e43bce3e52d112b238e8f72d93493f41a8620de6e4dc9b52cb5a2a1f3dbf, + 0x87c2f1fe382f705024d1bdcb8fe8adb33b82361d8cb931ddee3f9fafca2e4a2, + 0xb17d752334a51d02c091a68034489d30b3b4c7e7659422e50b32d07a17a10a6, + 0x18d4520269ba2bb7428758e1c74bdbcedf8f058f696da3bd8fafddc3f2543e88, + 0x6d0e15f1f1c2b037bfdcaf6b1e724b26ef28d76640e68110d50e426cafe5688, + 0x29b7bc033acd92ae8a6df93def58d498b79d1de519f6aed8de984fa296d8d9f3, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x186d603bc6d93626732b1f85ea4ccac141cc8f45799dd48af4123a4f2e7a13ed, + 0x1e9fb44d51ec4915ed9a5809c50dd0bfe11b4edc69e99befd9ec30604445abc5, + 0xb48f62bf60c1124bd7be4e0b9ee6c66a642918a465fa1a50e1ab500d677cf85, + 0x247318154581bff6dc6333cbc14ae74202b1d419241b047dc891c0f60e68abe3, + 0xb26cbe5ceca89934bce5543f84e42bc739f25f298e556225742d987b0e6c269, + 0xc60ad9c62b74abf92a69f3f0c2559630ac51bc8f84c426130401b7890278a30, + 0x1b0470a9e3485e6cae2769f6a9b7aa5e3b56f101d7be6bb7c91178d594560e44, + 0x264d68f9e933b7f8263a465260aa839011aaa117eb02358945fcce72e0c93e2f, + 0xd93de8429c70415df7229fa233e610689e3145d5346511eaf5b8de2543517d6, + 0x24a99012c1ed7a1245f507ad4a9c8534658a4d1ae47ad653903dfccf66b4403e, + 0x7da99b57c2bfc56693da809691737e832191a765a51a276971f167c3a82ccb6, + 0x1cea1b13af00acb6c1f1596831afbd4be16fc313d954baa221204eb1035a8a1e, + 0x123bfb0630e8aaf56cd3744661919b2a88c0dff13bb0a571aab5253f98bb4762, + 0x1af132231252bfc602eb9d982d46f7981470c1f81d33bc2d50764daa4d0c33d4, + 0x2dba0bc37236d5b612363efeec5db5c4b8dabe365af1de7eabc4307d5d13a0e0, + 0x221ca65c9a1d3b45b69170b26e5a64921485f342c9d1796042a9d691dfa2b626, + 0x497f939c6b45ccc29d57e1291021d7fe4186becb765967766b7ef50e5f2af6f, + 0x20b8117d0bc5b325f5a6985deb0ea6c119add748d4432aaf52f1f18100c4c4cf, + 0x1fa73e129c14d72a4e3d45e1044b4e0237b38cd5f7a44284bc0e35fdce08e666, + 0x19f24a1c686e20b06039e60a1d522f8d521491a40698ea48a43219d401615c11, + 0x21f4738cd989617c3e28dfb8072f349b44fadd5bde90f169420bec4a0a89655e, + 0x14d1cea4227f6d369bc6015328bec36f0dd3cf1d9d2d088b5fe413ea7faef3a2, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x985ccba651570f4575a0ed92fc815c4d262c6bf7b880a4a2e9a6f062e0539b7, + 0x21370081514ca3496f035319fa817e42c182855c938b09f5737bd5e0b040d387, + 0x28d51de160b191dfe5213005f019a3873bb60f2b9679a3df65617502d21538d4, + 0x1ccdc75e435b8deeaa4b0c8b715f0831dc225c7538266e90609f6a6285a2bd48, + 0x15ed8a603516e1f5617875a6146dc9c8d511cd100f9ee41a1fbdfd5810408c6b, + 0x1cc5e7a4d7ecbf4bcd15e2c0d54532f2c6f367980d5afe4e148b7bd8137373a4, + 0x2289679ed75bf564bd924ff42f14a4f63663e95822eba74b35f6c58d6ff54ecf, + 0x28a844dce08ee0b8fb55e7df9630e357928dbef92ee9be0c0163b51cd555503a, + 0x2521735424459701359a4c27c2cd0d55baa5380e4f4a06ef897b2ca89bdec56d, + 0x225abd618e11689670409cdb1a66ab70d077cdc0f5efc2b387258f280a24c36c, + 0x4d7a23e3eb7a46679ac5fc1d8a13d1670dbb5f00343cbb20893fc5576120b65, + 0x166f7e2b14c9b1776ef74e4dea3147b014234f58ad5ca5a41f5cc40775185157, + 0x12681987c944d15c132a93d6dfecbe502b5b7ae4daced230eafdb89d3e8d4ee6, + 0xaa7558052b83cea0ddba30060b4b443b3a4f00ef388d98aa6081641e7ab58e3, + 0x2c817b2fd2e5ec32c6bc84f11b3c63197aa4ae8c2f372952bd016162c5d71cb0, + 0x11962159a017e25334049df13f2bd013d77cf18b3decc7f66ff81041dcf354a5, + 0x1d63c9e5c4b133a0511c8624795f54474b2e6e465afd90330f50a44eee9e57b9, + 0x2d82e29c044d1096b8c16734a6f9c726ac5c5b47a199dbd7b1aa0792a16141e2, + 0x1b28d232a19693543110917b0ac82983b78b48fad53f25fa007748f630d524af, + 0x147ba0f7c38d875d1eeee53ee9112b75fb0ae91010332de8f9325aeb85e2e22a, + 0x1ccf269bf476fecbc12491a10b7a031a43c6df180a74fd76340546abe205a7a1, + 0xfe407a56ba91ac174fd49efbb61e8730a4397e8df24abef0666c46e1696f27a, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x53ab7883a6bb37977a9f6c04b7430e1f23259c71bb63dbe2bf0fc296793b2b2, + 0xe791a7097b6e2ee5dc314d57432975400f92d69d4ffa60d7c9a004e8a8326c, + 0x4074d5f47b8529c9d8c79f8869dd7e53944046be065d4cf1d9e400cd30e005a, + 0x105b47899898ce40b7b74ce948c42b1a7f1c064c17a5588cab02b9f593b55744, + 0x2514168dc134c9550d7d4c5dd03dd3b6fa0f4c10fc363137f17a1cb71b8dc451, + 0xaf1d61be25cc6a191184e77234542f4946de687cbb08aa8cea91a61ada0548f, + 0x1dd5bea55d34b381ebdc842200ecaa4ffb28b9edc96025a7025da4d28af0c053, + 0x1c39e9f8a25300f88afc1d5aeca648517719f5c2f8977865deddc3da451f739f, + 0x3adf474709643e45b573ffe296c0cf64b0bce9705b91f83fc1092121474942, + 0x2e2bd30c5a414e196095e3e2e7acdf0762c6a54ea74dd82ded60f8e6343c44ef, + 0x2b53a13cc27545adbed481418cbf2bc4db7ac6aecda56492735ea2e9c828e876, + 0xd90f7595963d4c470a559f222fa2b6e9588660c9ab42474fbd3502b14cffc96, + 0x263b73e3488bf2c208876b22bee8e28aefac9d3a4b76768e9ec0b8395d2fcedb, + 0x2a0dbef5edad1d5b0146a0630de8e8588c6e9f8e343ceaeb1e90f1163e93e477, + 0x18c06136a1e2c542dd4cabafbb9232a98301c91bdb294072cef62ea4944b1f78, + 0x1652c71884fab33b816d894c62c6c773cc63179ee35cb7e73a568533547d323e, + 0x24c895fe21900e49b6c1e90825ecacb474a9e919a9d3451e170ef22189f5ab17, + 0xdf80fd4f963e8fec47fd44bc51d94d1a0489477b2963ea46739a99a3ebe343, + 0x1f03fdd86ee29e48309c79e90e0c1225a1ffb47ba0ca25e4e261e17e82567266, + 0x27ce3b368152a24912d9493bd7f75d54666d1633a7f95ad94ef9cb63b72b73ad, + 0x75d95500a93ba86bb52fde581cbbbd7ae1d288b85e9862fdb6a8460cd9a4d04, + 0x2987891ed79215bfdb0513344a736a5faef636e4dc1aafb953a27e60763bff4f, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x2fcf686a3213ddf2ab8630b29d271f1c038040c01d6d40917e7665f59c0f411a, + 0x261ea88ea2119c8ee660600c1c26964559b0345f3360be71685620821638be7a, + 0xfe04a27aa636785c583c247067d0fe0328b8732b173b20171573497967d8a02, + 0x2cf0912ac2237a5091ec27db0a7d5284f13bd4630fb6b58f221a68f5f4fe3232, + 0x3041569dd972c73b88e73eccc715d7043f36ce79412db0df57ed902957facf9c, + 0x2a4f9b5c59b09834c07365f58f63ed64038366bd9d17c7016f04505abb878b3c, + 0x1fc17fccc2b1f4d051595c0e4151406c29d2eb02537696aebfb7b85e98371718, + 0x16fc002eaeadbc610d53818fb1a72c47f07e7834b9433e0276eedf4e0cc779c, + 0x2fe0f6bc3242cdc940d4ad67a40328a51da22100cea8628892a20d3680e6d9dc, + 0x43423406385c4db5ea885da5766246096064fc77dda460fe8d8deb97d34ba44, + 0x90ee6fd231f2b7fa73ff9baf6db0a47a0057e62664ddfd9355924242d050e02, + 0x3005c2f73ab58a8cadfadc4dda1e3422d7c0f6ad0fe7a752045ac72001c6d445, + 0xef228d7667c66faed8d7e3c7bbe5925a55d7451df7f51a6afa3bbe0747c1ba9, + 0x2161f7618113ba7d7842db94ad2ef24f21f8a31b4c1124688a2e4dfac810f01, + 0x20f085669bf228d7ba11d93866cb3c268b2e031ddb9697d80cf62628686938e, + 0x294372804d6e2359003c9cdd1677565423edf025a9933d0b25faae3947171bc7, + 0x15d37890f0af5bba4b3abb37bfa5d5e115ef5a4e805505e2cd021c4807ac901b, + 0x287ef1d880b317586e978d5fc8ea277aaa451ee6be1bbb8de5cb447b7db251cd, + 0x5d0ffe0d01c752afbfbc3e2c49f0d34d35ee5198603300d727a11b8e7eed593, + 0x42e5fb819552fb66da7667d664838b4bf65a50c422ab1e9a85b1ff6e92d30d8, + 0x1fce9b344a773117d21974d9c3a070368065377845171e46936cb95a3d38051c, + 0x217e2377d39a2d534ef281f973ae22fe8ec4f87500899431cece3c75c410248, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x30073c53bd5375c642148a247e4260a05b56613dcdce4a093e85e10d296999e7, + 0x237c0bac139ca6595c3dbe7f8130d399906ec0710818ff44c05774b479d54fd8, + 0x1f2e23fcd2259faa7cb33a243bd212e89baaead143a7edbe6c6b1c295690db9c, + 0x2ec7439229a284f2c48edbe15599d462b1d073b3a6037e8f7c8020777f26ee4f, + 0x23c268b84e8c118733c2adb6b3b0935ff631f3b47843b112e80cd9ec5b5acc5e, + 0x136b39ab04af56cfda16f3f99411b1c3cbd3ef198b5f056e65718f52fabc7c9, + 0x29358a02315a9f5180f23577b3336be58d4039e6ce4fa251c4cf8618a955d9a4, + 0x29139674f1ed5967476c8dd777624e49bc90890a5c99750922a4725c81105775, + 0x2fce35cabeac14beb49bab9ade7e3811bba9f32b99a78e3ad655b77c473aa32e, + 0x2d0fbcf9cb5fb78fa20bd878ee7e6bdccc2eab0eb7d232741932c0e785301f0c, + 0x2ca38f6f88d6a37b8e126f72a82237850d9f26edc5b577558da58c2e55b0767b, + 0x19e38d09cdb939e187bfb8822e5c2297a897da1f16555a191157bb8a5af115a0, + 0xf61a58b977b2fd7323b48941cc010140e9b7da31271dbf3e4691b767dee7f9, + 0x22b5299787050ae04bf9fb86cfde9589253870bed1a0213b143b33eba1153df4, + 0x2becfc510eced53a873daa537c21d79a1d5071aa734f60553ee809520a9e22a6, + 0x14d5be5c690883ea5b406c10b0120725bf1e4c5de2177267d9e38e9c792bba8b, + 0xdcdc68aaff548dcc7842f194b1b30b604e4df04bca89830c0bc367e7703ddf8, + 0x1b0aa07f9f3f5aedc37e1f7266bdb1ade79a62db3714cdb833d1af86cb89d9d5, + 0x1e7b9c8adc9bee22f859972a13e0213314d43e1829f4f99fbf019de8ef79f3a2, + 0x3d090fdc48ebc009b4cc7ed3546d69ec87dedbc67970dcea6052642e517fe39, + 0x2fedb8119885c38398860a6e6c5db18431e4f0d981a2fa274a36d5c31f9cefaa, + 0xfa5fa0299ea7aeff8d357bd332f13abd6935460588e15adcd0ec76c8dd6750e, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x12342a1391a6b59ff25a5c84f352a01a24422046622625d79588a43c40f4ea8f, + 0xe21849b6b4969714a121558331c18a2a8969004cd750c3fec6bdda6384f5a30, + 0x143fa84e95c7893e11c17306bcb7c7a64e395e3fd9f1f4f086ce3594728931d2, + 0x216b7f99cfbd8ab9e124fd7ff4b172c853cf23a2ac95cb41b3a42190f035b144, + 0x18bad0594a462f033d2be7d2151cddabc6cf21ed59510c1e56d080872fb95490, + 0x2c5b49fce206c612947ff5f4a12cf1e4763a3a1f7b9407c328e30b3497d69f3a, + 0x13fbbb66309924fea1153a649786a33fcd8dfb3e4222a3d59393b40ccb39b9a5, + 0x3b44f905e3c8a2b3e7487e0ff0e1277d5abe5e1301c165ed1c9258829622f7c, + 0x56c2fe32c1944e7c9400d0a6ec21aa54cc056562006c48458386c8d92f565ea, + 0x29c47e53143446f7bfc43afb3ee84548b5caa25f4987796415d68e318889ab19, + 0x2e43c52d27448282177163200168574de40c584fe61d4fae5dcae495890217d, + 0x2fcce12507cd0630f06a2992a515f45c2b469f2742e328e07555d22c75e51e40, + 0x1d2e6d9c5e8c220f9402b82ba4ebf641b2173e94ae76eaf7ee5559d43dec7611, + 0xb1d1a4591f233e710a8f245cff5cf759fe0b4e55f46307bbbbf5d4573a860f9, + 0x163aeadf9697fd15898344233a5a30236499b728c6fe54b2534c7c9fc648bb99, + 0x2e3345617de88523b5d09b27c9669fdcb2472c6cc832ae304ff960c0d4a5a348, + 0x1859a9bfd50b4bf8d40885c992654775ce35ec41a77b896206df0ef2281efc08, + 0x1232a777b5141ee4296798cb37ffeca708d0eab3142357e4e917b65e424ec478, + 0x10c4ce967cef015fa466bcf69079f8f23bb2826cfea14c78a3b4509ab2aebd8c, + 0xb980e8a923bd3a2a9d5e9192337f070f18c11a16c809440f426126ac390b7c6, + 0x2b1d91f4222d2984db754e4133fd4060d12c1dbe6158eb34fc1c1fd0f6327b99, + 0x19ca1b4e01a1671c771897b741b03ca691c2df986c339c6f2c6b24663fae3129, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0x15e4fc48c95a30a9b34e39c7e2e5b23cf96e72dca78d25cbf1d07f6bd1f35269, + 0x2d23fdc4c0c81c5cd12440066758541d7e4b9c6bc29cabaa7bb3217fe5580c65, + 0x1e1db0902c0b9743d3e60f71c53bdbccbb995466f39a9e044074a32086f519a1, + 0x24b7c98c30ccfbd3b3c87479bccd71122f3a41e0eac0c5a82916ad9e1c77ae80, + 0x22ac75fca4d3bb5bf0f9f25bee0293c50901c2d45f4c2e1d19d7433b2771cf91, + 0x2d0777b0c575fc2be9b13118b4bac03bdc856c03c9b7236f61670dac5da95b1b, + 0x2252fa35e811593e627c8d6ffedaa4503728b6d6d9676f2e3270545cd190be5b, + 0x20b37b4ed7445a96acb5891bfe84d9a5b96e8c5a67dd111cc4dcaa8269f4f0a8, + 0x2347986652295db79f804ba06d9551d3e2a6b5a1ae358d94a1d71c34f36fe0c5, + 0x19384ebe245dce94d5e68070e3114b1c5be9123e2a3728ac3af9d340058a35e7, + 0x1fc74a00232310ce6af9e233a4934550b0f3ef063f221a3dab64c2d907138a35, + 0x104721a9a6568d9e67db56ecc61ee18623e89e26a47b9e9e44f8977da8a7c16c, + 0x16d9fd4e5dcf75863f3ab7971dd72de63e09cf77787931b0868a5c15be47c163, + 0x392be8203347a51c9157a219aaa6787f54494b61e62c54e1c91bd995addd474, + 0x1728a3905a9130b0f570af0165bd2d00dea61d61f7d103ff7c13172b179099c7, + 0x145f03cb3abe12eb5f0cac73c11dba2bbcf94c72f2e30e22193a33906507934, + 0x87ae2a368db5f3d666730029fa0ae971b6f50432881c9c0d86f5f3aa716b842, + 0xe386543bef330d6c3cc14294ad86e2408894da265fcc041225196ab8064c737, + 0x1faaf3ab79da2b30406f111cd42aa6fcf187b19448b18f4617712bb95aea6ab2, + 0x1c68410bc6f75d9d773c5cc57af29ab138e98480e1a0de15195e64afdec8c525, + 0x5b529d09da83d895ddf1aaa9849f98955d81280eb9f4b71cb7694b2a21ecc0b, + 0x5b8ef58138e7c3284d9afc4541e7f291d87b2e26b50b7feeb75cd859e3ddcc7, + 0x2cb13179d6e8a4ad1b9fec37376253cf64386ad905e240575fca86539b272dc6, + 0xd2abe6bb0c097deeeb3f2162b41f9e969035ad6ca31e71eaaebaa590edae407, + 0x1909ae6f86d6d43332fd32caf83152de39aac3f2701441302012d3b4349c458, + 0x2f0ee3a8676b72e7e5ef4794aedc88051f0911ae43d036449d7c07fcf2f5dfe1, + 0x1e378a1fb4fb0b0e168121f86be8de342265f0d9443de37ff6e24a8f31c63003, + 0x2583b1b0912cdf162a046daec4856ba80ec6df1f1fa080101ccfd225176a0e8b, + 0x11d9e38aabbe2391dcb7dd17706edc894dea224f6cbccef182edae298800e746, + 0x1d486e5b90e3f3c789830bee968e6d544b54031477fdc8c9d002d6f9cefd598f, + 0x234434965f05028a4f5330a590ab06619914476348aeb87a1ebbafa1e568eb18, + 0x3eb55944fa1e36fd16239f7b3ddf108ff5f27955e2f386139493ea05c1bf509, + 0x22d683ecc91253d08e6e535a4b62627738c2cb877d2b125aa9b190b3ed2ed9a, + 0xff142864b0e14d2734c2ed0642a474fc1f0116d7e1c5dec18bdceacb2721958, + 0x1f930557a284998225f5f4e4dfbcf5ac211f1b12d91b0562ed3d63285d7a714a, + 0x18e8222f6907da5745eeb9cd4a9e62f28b8b710aa85fe729f9ea73a3ef0099d, + 0x180e924d757d0be4066feb146ed56212e38acf9df4957432653f370f905b8b07, + 0x2f7d0715d1391190e7b14a1242b6799eac3142e21f08ca02c21755eae77a55bc, + 0x2283ed8d5e6f9470b3f4f49a771061e4a4fc7dac683defcc0348a8862c6ce71, + 0x21f60efb132b62909990b9f994f381a9c02abc3ccb54c5c8e8c9c5664c6913d6, + 0x1cde82acee60b84424e9bcee49a5464ee05d1cf0b70469208a675635ac715495, + 0x118a24510a2153f818f0a996c87de913587805f16cdb1939d9406941f958e8e1, + 0x164567b0de16b7a5550fca229bac7cb0779524325e4ca5e78a86078881660264, + 0x188ff303194112a7034527cc9dd0b4deb0960c9c106ce115178dd7087e4e8c02, + 0x83d832adf9bb4a25f686abeda9f16ebf53263dcf9ef4311781d09920d094ead + ] ) } + // noir-fmt:ignore -pub fn x5_13_config() -> PoseidonConfig<949, 169> { +pub fn x5_13_config() -> PoseidonConfig<13, 169, 1625> { config( 13, 8, 65, alpha(), - [8798508051216852101945770298446195263426534955832706109793971883081428107277,18986509933027080134736570007084643366993581436980149915398754460582000677690,12888632176077676513526604615863975427335143923557716212154194444095746278696,15218363940991075171925464923999816479227567707705088260324253815128900522726,5123856245344699442960347063644568841985144075867098178729206123344695866632,937497109650566529304426914695525196119182564119552807475810542139513078711,824338985948318627675352935105995425917124279032809525354560876904860400681,13942203133811236390194976449250445722833065335401645546668049734024419803027,21193497547768556525501812324063541319364865851059424372272833186043647143451,8250588221665279725951753271334754148372733354841465281007604695074534688729,19810263445128123914159130235504848033923366950322026683325764129239721093372,14320576994914109414332501339118128158228930675887122896979269439627163060693,18889264041663920880871940494605753485014632588652805059026615325416030193719,10698608730721598729809918763148392473410663742558667693804099019738511427166,5471531298285601691838160103499608876767872950664004448938449413930813358696,11457601248269622750970644898105156673192281665198367584690238105651871243849,16992951642443963917535033612483493956841253647152989134657936764458589935104,10681874111209657199770620844475073359855652721773538207614365548304774934508,21875342192304323235337862160226992419479798345905340775869689347883470787957,18783598503862573040343207522848147282351537545213737188311758281500392127423,1221270316640374234025430293653174054626512367600614548099335037611485538579,3803127350594514565431185919859613836470412459545124433755604579955078714169,4692704173297526575662787527414813729052368393667564364621548376076502682045,14877344233698668087821753402566363996983618742746012792982725192235615274582,1054560579819817802724755404438987869385528807680314510667741074193700268397,8052216208184446695555642950254618937388238814298100142455645263386380520432,21528486310986712871728288619461268100617012373791428855787397091733571140849,9607239927604256097021258716815750648977424271874860033430637795556811442682,2196312812082021938532541315765264710074289763312450521728804241715253452502,6605540160838083938636248853297421723407665107595785929587574408377531474397,6525948153406525772960169117380395975817023461160134354401655738067058124631,1003556227519998429556476568497227440137917634405973503866888411893650518666,13677584968475474622689223355399150668790874783709262452797580070344541448836,4272686670447940608576804106249107479440735969672981187306042096242258850880,7723948150633857131095670967217469617626942590283045283879017721699420758313,9563761958679910727099148022742805150896356950128100201760652748527446140573,2850052690445041465388681891454371728435601558220304706587137488583335087257,8526775100524058290507772716277462650712450825299014127801740914862834880076,3867865860920444582361195032750323847757212456942796852256870663055781206979,9531131437985240947539412881613144640386246585015365913532093261866651903759,7876176264763636659141490167245054739857019306622806711043600468363729864093,19195073274099628437757763039411307254419435216466391625117296911023053159082,17201596318516267959242478674525331020962456681235714852429128354797936423512,16429987001981270427843548313178399452962937303668954688438246688799503164984,2808058398896238113910841463946229560728543614115874664163904810633100174930,14219106904819518684382581834179422938681605045169559176622588393807041033595,10530037691301443797595179975755234137332257307745168342967468344289118325757,1780683171090951191330938815635375996828930714110381590102230999415067289139,20631152509228411005601100836698224543066495368069041690921190101674287477942,808499207021654020396580110067573161997188131641925849629551231827774305643,16396331554632517617174441423319546296247483740125085437207362257874071846324,2856734177282633594896606301173852733142847026457749184584827572766646232552,10322006004350928347565262203595059371944943723449117022023179276501731876345,2683049508597401695548071522846046195699870016352617057472448981851954812059,16247545910658018105089170383534659574306111291405960552997108542031333797235,18622054704352443244328095600847746501599243235049513145116519278941866455272,8702183185743408572844482710294629749653378107594727106707156268893318308842,14401120539669001367195063486710670290450638416936122540739824928865783084126,1008932491940705147356558882115440120351684984366727805937095853000783157110,3335415470820584035672268458205991064638866247863327497697585974180788121327,675348271572506248948949205284720732296364868854507020989147277054109697307,11425495584918585085965114263893597096866227224211705734884180990929134229634,3139501819004172358132939651256683854267531704642601593201346365873114559764,5783084359807455756426365693604321435940832494660634548089377362001475784943,12095094864547001070709219304829411865589880746021553931719922191437710414601,16318907049539057156624360879403805284297767691522365017367114160528018468654,11395679267999229912686944592292906403252965050428182621076890662342583575672,20304144520028193526915712162937805381528012861129116050582705669151951550558,9782367134866186358061353221055410602027546275400836771195060684844149613708,5028029607389470804476265609647401798747012470860555590083631854016382301797,9007627713847325367341162188681367076476205669132463414398773746849014673910,14471089911822534831111187815987523323244485794708545360218598163622346282781,8019180100611273479652907195647951337613619920735853449223048779220663542855,9047131412613791119405208650892730556330287685760678509615107996866748231916,7335839265467743759482091707230237155828204454352010285192894893585057443442,14787708665825803366954624175778735065630831061644057898061768895034788739773,13527353131634051756987040962797036674382517083826397597671775590484363794989,14976182354818370036095296869648510633049821903988384882639150664375161429327,1560099560219605560187324067315095140041097722845226997637592687804174779694,571671177230396783003670900588907847431348620829409362554250135027808522430,3595401819266532411007886403698316446251107730632935527816690692561072394769,5582619801223860759886119158956613012355932421337001876528290847176002785551,12913958465964733555039885816821695149723050623118481194340346951472209298707,10229385924925018504492473674441213223237935733123654864337438778499472034702,21343876046925805512584981384457719270702482935633311830189677174062117124219,6420204451041321645976980917151646516083600244123365393849746698818033299571,19251614427061141498566572096097506725955838624383486128732046911906166384020,3637855341628865891325364423447146770285076487178203925892266081818756628695,6291095057555542758591776864498618016939082736178179913313186141723218066258,15680673126007380386463552533962308522676179674235002556809204723523731273305,14161910492383069106925371061927425194676913565753916851706224000847740857190,8408124204639665996401588312942126836254203358943885876199057731364731921137,1799578340300310412035304211591366593871976523584701800579066126447600019902,3622312705549913151631696033404711371424834689912295490477655370864706883384,13273792131373119117124844835198348538764494606049066494384531598904652565002,14270260908863510838028225519201826231421616414346395482851862560529215543207,1633715375341396582749269086363023314520014551113162582725277839347569228786,3306641014838747329624593360740422499925312234577578401365800985267347686108,14198045292969051397674853108255956449504264447127690313478218267366467132592,13392638089393029927126006202520304645547980480174653070691229667854016527907,3343885948493512216041748082192584170148231918609106413514016808164860398278,3168199878854830552224332084447744849594328418779455928665560385861883941432,4414580242526682670231711868212166617171432599055299074136917305689841663873,14102753845056293060191802617344737652392043747319090694003879675100249630273,5573924339361534820906966230551252047468623512376332682801232194633308271653,21326161716444219551593862645873877150197335577674154159730974795774063715301,19432958264517639868400987651848393946587739437911153002798497064389336859842,11213890749343283806487445619338898013466071000086191642490563684623068539710,9198922780305686612592947154769134303077110139729181291466776593119643796878,21136183246673473125620223552691909911094171966517655547561646692807715461191,18418245895226184084223713341727403858051315526021187444511237652982687814864,10761950212602122725874752124635327020166823895511275020048089638533400314021,16715137911831586771799460729625653907150059087921720918100590730689273071536,17773351327415330719066508685011039352345666357995827941409702750841801825772,20231347041576378765333233596636479502524461869780149044300194060543432934519,18064563634590190884918686050639690971635922850408462075670660991277444012424,19311806793959939929201104461555154688516767798907269687984909834335608414545,18574604846458382436863152415585348247597412723601050266815439019897542533749,6791419133329459189167506884324613003818238896866734783035998091675242101498,16020026112470750192482231650248429937269643957555877460849721131766422051297,20044512180053459577124670295358045421070313597307221323295226934357969810703,5766192039785553259974801912149788259566859976619902528741727877731329189756,13160650100556144411626475539530712035286115503483655434606927361569861225444,9256036311849117781394603817644061414251138927392105895934210116699839233747,16660304826343536533933296919943639532544710122612011090406376521894383168856,5613106871918486982198177086366936520094704188389198685078718794779139126942,13070598684216243718425316519583985756848433332087820965201044383296972346897,20442537178749694119236982549472062379434941056035907413284316764767638577672,7934380525369255820244941077363404413659578389361986061643146925957595190009,5098727584136148023264970031064585917675686576590855834683443649082028079965,20311250985440103383589841574737981968195820548330595923330987127317084128947,3768224286214159313341476585351274256214081884717440852909749729584659454712,9851045187544813632080431293737874643968516290829960553238754661188963821885,19015242154372799267961042586541854827581444440949327264389997835941454171864,6579883332160451787803375748174162900180016921849643588581107525271529605849,10040045688615204420748720492172111994988850765670088109590569954563466338788,16200830095429004437461800470410149972585288873073724430176128378316485348605,9682955393234868764418991570718636989945366768432593131049879027562290804128,12304247432606946020923001398973669839540045070461170795482951827192644001957,18191542513141047176662091981681722742011120542435182371090664849144982674881,18914155310347961884616925389217412880576183372588965807237661684331120845382,13251661686687775186900604006618374427674252707179991219741046747323389941232,10249194086135063113459170280632696947988284060709952681203426883826751049011,18372233147890747575375422462203968154682646712463764047424428288714397527619,4638790386282413677458315728120268440302827185471341027696814407017634332517,16623961311962310335126734990913554770362581939583424145026358913546809927380,17860493200690068167535851968852986582339867469465298666834410487621188113531,4608305735853858774877121807982873005510358307902418229099062852681969399389,14245817054597951763417586258404021745844024655622942045401677661648532977993,3809843434538253198074703856325693344260532607506586917570357443895551048805,17962207143381407459791220803798424686492359980872541932770670422523978330935,328196272784453082510222579442282995329426913454628381427614217629272010096,12374354866281475555079168690683958365929973901084398491477273797832999248789,20853802547446175043916531515983184048009878116903616041233975407782898112824,21496110961478435785328603969876614135441859248001892605282920516413194792470,174344306580108774551764089189043165870298462272157912012996952342994211137,20687536797191141044727224925607387673330130224876076220260820047611716395831,13067331728561732140381851790951434625007152955086246816336518249186949048391,3797862935019829095677036741096081889651388634128316641681020782687008662828,19718547173056417343715166978970272483152981364164960220358919266690668222316,4038867288048886379019053981446145278427073511478003014108759946240227146792,18486919751583655613568544119169758176904901075587096135301780773087898879007,9808503221335286135961820380426080374193561918865479543141400875074697503967,11673653729232546119337900700609058880494248359777926756321171038104786463073,2206576012107962093523647385331312771747616647783007209109500521090968991064,9800772269959998996051474306860888030671933506518907174943285018516216530078,704115937219213713489981656324169840669771632134921090864597729550810437103,10450936455424589171986477572900171091143445830786569605988162504754224051029,21102186642636060890935221995324710172830713161820423345683707273376266063905,9163879187976750746407679763920281609583516506018439539723656773309855786163,3472157821801145643950882966615731480318387993084591537527672102896556538908,2411890225861629547000508300507629335095483162292985158748687911181232049540,4985409929001444812993021607654361988376208034496482520498705351994820408485,11553789937761176964063895958945223002657928340200203811287735666719305693830,16847788791386791842258653027481339013349340413294800029138566625971691859716,6760556724223230789549789607828387138865070021837886343220335025271850431529,20596400847159894247975659733452116044170283916549483164302854789226390584120,11672317719239435686809215238371249803784157167042393847476181444969645566102,2540677976918908199177572390470632080272842549139729131369041579508211107531,19442658692908544356400723297250992586408893464353224580638700020103731410947,3126219492402213962620193562481318950501969435505738692018385930122987610651,13815812651475874136168661258439176421344570120756240838952907916838907109528,21443943680756083274641262528830913057368026549878765925197792130996882062057,4605307168758134905354332635309004486671872776946937049460665298426311628483,7482893834680785986692353891953868933021236845332400077427554963067657007377,5511796194740668281350270549653399801893104530256753635073935873703864854017,1743641818114051150153510266165400817966589635697948934570080374390326493276,479348932723256576178997677888058436058269610751399398192779646687149113652,2911895727864385123299618342188487304466499987531177084686132082340794352256,20721945554748282229818069151690746976633856763939126384250406858494706697945,12250582445106986808691543043877193096050336861542243284061992098674816799798,1203513568724767846410309911297210537295690041996158208540636591896498697618,6015583439542775167098811213988699848659623500530189193065070507681443523926,13090526755326389175310761634465981673176179379933796187486632857997253599596,5204691423542830100481358117753845481374238423707185894207602712512441617128,13451357406880550276974168929055560555273701366887507611491312211347374906677,10327523031922710495308957226255708193968398139079389167803483310323608563088,20154372727310541088852354530646786495003018189623626400646862775892232254942,14022574434398251358742711545518515409780772767696241502841372748111287365393,5800935164580219886597276061890276866350374777469717717325353972942679889986,4950159996548574497193804912590478284182513481419060390699450490223901282265,16651189959199821925513089100199135327590269582473005780223712025001916349248,21313574815160763657406207917526347065428582824748947465014119238740065134827,16527537328830884258876707902602749401809299353104838028680907493128406403510,15328203752181180061659863584748718494669846163715366299567183721088123843121,12748724793783078481516963303490468110393403014501561235873124284244901317221,18960625031156828010763136389916953653374660277691326636541170359289051172470,3539001622988573864365704884620979405364663891195701665878843924015974631139,19440492503123228668247641573804742990539424862427319298139890001019307139951,20663734806319981969735713814960326046259899097186434280597673603867647826563,5638550801924521462873676353658824547611149604620661155399127974706744652941,1371302213304057480201653073728712066696195910046203705054614806040591336203,14916746318031473743643312292935459967335724866678950897137588157969538011797,21398978398848411648231431125400371920346497858046605440294787662089399525957,17030308547789363149594169656019066171879481623126106541463663868095060483032,2440921987343876776494963936103708492610319137255329185550543355589457647052,16578274606037635679209783094809437790602872464993592428997022911117833097149,584917957795662537423624049408930838570931949382380283787668885015699442922,16787159358764578324620871006477408253726184555269443751955596568136636185295,16078611438600534298861481344414944861682463507987217038328914463538066716267,8692607842423869778858860521189757647588004328790444839011233818764128397786,17461551965098847063794186994739508584146822190403534677972847044656722703432,19452713388671907333636730760656181158378071792518077405629847148635099895953,12121230247359921951208053896624893871654915559955364031951409301929413070034,4704830575919764561517254527427722789804729564629801789022427396957683932024,10670972751746137966064978863033768730585193577203300636726301560193269271720,8049285218762936069773906017628569610476710004139648882735854791085139873871,5327956364112241273910968805653529609896670219677653687154759819173833984314,16209531049562245939203780811684066382629831507349840609244051677227948603148,2041493598600414785071850826176044493717208172684229753087779307523403234108,14983712813504746225033809615975227528832540720868897893292242774973221269350,12085999002734552992271490964670175347983721486216238101789957598273374406404,2010148192415347724117376912318888220341164166588569584654147279107677185092,14204865408877079652583508111640133693635228399739312350971609944706493769468,13330601146337713429471908542961289712020817519764634531830442337284933922809,9363311761287060295640718461317428792455498134298183595944737677775311452049,326899109513011756995862753231193478723114246336082392308214181273112126881,21599711748797254989207108046977874436425859822146104148381410251216892766416,4801349866375335173289265243677780019445351052028447809305464229839535867723,14155733033291624452674783678844450106798515225633669031829757876654937709468,6249525168453913775215814309255487077884826362528424439922890888603955052499,14928369633463338040897134982481546746234350670771618196847518086862393490357,9125617238450534926549876296505645845116172794938106232962454586773357787390,17103886312678741706528259762965004480595318892735191450742885850881411200483,9561133527164819548073730465187187729026229121272078865756229410363525806403,15499339092812475393717971205752228601033972883632736148845868837711619810573,4039978125105304479934956398755842410107811106124175538862554473225969256475,2947887467809254352800319275622693352512539235808226814612313636217910816213,10793550355337981917672616521499626144068251539193270238994640132315408061844,15282024117559604646251556024222379207458577842775127240432856222129525583388,4938487600404790095807201685235688647996095712925228362099985579653367819830,1580271313232748704254579894100134003454608977989565849293374431242287188203,17650488790850180925611249978112046323146336603695505846749648092705166179072,6318477650409317961441518371381185077182540555690253948041195660104038462403,18703841587534276582593528858657361438697750302064291203982535124189673569022,6570410039872146139634976314211122538651252189045191357367613723647837080131,4058984348953256905202616995215664252962770887032362374636631606975462596559,18730155671005907941866324013560951043352315199408210078231145351355402093830,9651860366009425828519962206873795166909640005109793700260660519169015873934,5838396248515026677336009419348618624164637668061855829375740686597759055073,15333954343347884216807246400300286008899152705372200767215516907035196412750,1930765848863686695612705389177613542562429368163669004940380022708446841540,10766617427881894379670242247746203663519351900247145805786260703840625869300,5568751333625760749025074267385171935854368145626703295693077672484816860148,1572988267140272358245681202814159120843671145631424724491020423275325461878,19938390788588115516825752214441323822601991108943527563767657270216212171610,7571912702211887911260059806577378242621772456912160075153794388926572849145,6858979093205494695976875629144179789647553123886814202229119872013338208712,18762692183810081055439753242004382629435200839335768813270546391733006575124,15741259924712306779754554541398522471185852133913466875986860727321229948852,2627808396704584386154002253183040546217470699174068260518444240974395718442,13588659892026426409480708338634242111974891480475426278869635762077927444692,19520457627758833811699878500944809253730386938893290068023237193482219846683,8924178241223608091232956607418048641173985923478293687667819226283386788940,5816806026738575389886097663948769844875803508574710698349454181988557080269,12475579687915690911104520027833630083645170013159764349224529153441972577879,21056333315327274333873056478119184274531121536034759580035646721078602460263,21444457911856423029054975409869505918084415765420838103204937942386934191806,9510785855264774762445687543927870120017463057252636764104600528992946593471,20924833468200564542464376523632289762564405387275694375761127017107713239560,10520571364539530696429244627292574117914912315372596265076914837029323332385,15676633242665585964368692080238475248556973102970746891067091503318954352189,7605218463440663468653884707661331637891252539306862971462289235362996643878,8655416175027898012639173297596079731611447754405890380300192905812736625807,6587158966606269464624627411770696301475420343587060761712532930272301692115,17855802086555955087208003626983743721607218545075932831175321330674668519051,19637270878895908891611772385398729322367589125936403809351999767233932966110,13844120079506591315671522711954211929776840478156307979285069853392230439385,3896487627666829488959793133071741228529962458688538373863209568407375861949,8072922412250331052234441827200394762964253395032633720559799911487619573310,3446650687448682504274462997312106041057536787701884723175991150707212663201,6750980474265223706441237350209360446038939446132826129894534048737231433466,7932667749655660682554204871450377554998925079055538597319130615505233358592,4551937123821223485620220711817547511116227596903370212234130807711068597972,8450248183513826743946014093205824327880033986070570398677443659142729011179,20523087403588105156975104084680617581362696346833272310988747947340344564064,8021873326844086700417206574915335220587232800373998588094532336448721297757,21537680614486477925570839538957839593006098192503694567393749587557940631967,16568393458463797316294547173419555682646841229029462217197639056287054602566,16910235738263410812877183305130636228751042299094737782744154576712268208807,5629150734321853465674510845327410940323442617216962413835214171701329559576,12765131184498380847448550948920304867469527623961001350816744753387093810315,9954645632746218155245325585480173993199044803581756137160936155060542951690,4353999640943599221118281386228426498583991413938542575297776232303344359940,4598711079993417664489400987736110506328223791894077517963275447468098340703,17317745377506102303500052440899062192892945727209124468437255966617200532771,12259326473392165107331141130100680225887121989921120777667514143912156322366,11811238683014115897858309619999599808008425203222607881921631505596453270838,16699081706307776306233318220897168744889069844294482997417168581249408879966,2568026780472621467236485312283731374848886964214142251868040165224695316461,14887991441574434999687627633546581501365901473545173785249018184685706196387,3569299155477721143892535842178855295807355615071744617918410766174933059043,5498879700681283951662042539400107058426136148099967700430316029080607629654,11559660278391175834668360323261696294263059777402960440249595574565141656556,2245933817469402341452987887837905070237745132811239554297372991710914298182,16951354954717164970902473060335333600574402706601527686301478774700332367102,21515931335312240603168050753263038826093559960430063520103206567658032925825,1249411708644964091210440756030782120444589186855809089574669034358018078687,5918980335509160299664261285796224662727132279493574691223062837411060350013,17739377184579332650035245294019601185834503109963479023132769460626331642282,18469744224495747473457470133545294362819142862108342977835066995529981406258,5759336781416534390511113561800934668877971293662332789437681884454072500101,21332416097583521698710421619829192185814871724795352151990455290564854827164,14991738373834450996520664429440490206770501447625984036209559286781489862494,2292383959319987392245961291693765909376521855421393945872334290076611679644,20271880109317422113691100242542434637543023179088091376781918851828907851136,16343203714510839250939280610780086672320399980775100100207359519193914733737,19668001496569040779289443981105684833630116796777138243208746501411413314400,14867270521039301446053304216390047301289545979306959364422905455339336587211,9929001722154986846461251622116577110986506194975595510541659282347340459331,2420696236635890839197290329114608036709859071844599545644710485458818798726,7023164250260724184662962208964026963022579890290101367655364067452762770181,20508512038053113727358039673385440054337319672353371627416928672143778575477,824002554707189532054522614675201805472052085843409216867120989167259938133,8081396930643908204119214488991799751072819763127464506132047127093449268743,6146669896192112367311424975035875525640347544666981144388229137148737996133,13917552221424458749711502489369248582964839439204214559672563587245770000377,8550914481815010035465313609214308578203171728075688232687655725801893823141,17861710896808118014581828397113186358973121215643160735097781787683890541230,15595160929818874035046864313228963482705740989418337036962890306288699599497,19810339910854592376336564454416808551332919752503671392907063850461349060479,14234414635213293332305234819580453743707554476430770368421971402668862484872,19388187253394163585379147543203559718098061800153070411989058669962446974654,9996031022330018431773704931033232677865134703871368350999928908636869707277,4533799599412452199761684722747577946145532223581271248962115254510905734009,21793143524581931493773122340799146504825838409926910431529124937257399233338,19692292712401787423885461139555179726227035221831860547833110141089023723875,15361825934066824966062130821388513267446230286103312548685290096230989843672,5736434899097417592114701714539404395501559559582922276628268708302331297718,6034516841645751575815362526363553327142008775019507199148571280847313939846,3103941851061425456578524836013350351780973108926423482048781831843642166611,5899337062497322191697133509006899741055733585263214548357752956989422491317,963781557317112122222004641921550021210279319264222273713987285679221730138,12218612067667826360750451807845242059538814081271178077944945859470451709133,19859087159769083790343803575983864397266266537354870798907672197319357964101,19984410602577911276019354715470427122599274838994470055478829965861962241047,1510088699001180548764185585999030426586790568209473093795384481408826277110,6626530934788897049551186952232009297818099583639020036000874279734503731588,11102385732315753875246033828526944990963999730005798544082045825035822583016,6109966799003077547022556221879889867437672084424732190493586606121191686895,11639465666095459063122039730377449150155515188121884615987948657973378713177,5087119226269603720517452201720024842953062937909041658414079638720935374157,14200979596305023031605438052846373683912540635435718213758112152603438068044,10504614528473632996392119937661213820553616805799536317962705212982659337252,16896136248461578519387122861681641687612480673542507251813953270071486348436,19381803511891750827107737252264239897475475490344583112691529084617905175082,17541407330179013144706644068775388402691308134663811736351559302382670708984,15072973642203756087665519422382641458207399650896006837784917038035882610771,2308847250281515017414251485377760361489324048295236605725148595795546323946,12235376578863551481515043248404435233298457594750687771966106520323367004722,234919702386651406701334351738513931283772159856053034152613436560637774413,21637694258900941342752268794989465303386552780774074413553118735507317693719,5017784917192017182377763628730148212610872485218540677293490321169201123948,770314504054605850178900177028157853527192178178763005605945816624700149604,15876814891128030074112970202145286137873841691080700504603122203177789175573,21396093758862368540558980838454280107203592525118989209906020509719986520353,12395505038782995420136281017345429633379095201006284425785781752730355509942,4615582568807690433357570528319145785065741006112040062899881545600179737110,8043772689074175830138340191606864001269151441770005593654367646112660385954,5087060495541107066427394344208368671085864351635929517190622637786924485857,16943670806889779731197043466545390303516518769717829999301840370920339407796,13534112488771797914884729261168139500575711545907958816183168317604824618336,16825197446319806977233945546803116869802796446301133858223973227155555550786,415637162126135168159032709770391274308945193836031409779140830879628784155,18387406758235678040900363524694503366739497074863830200933011303909731885356,11179137042211084753827842203552443809484306307318317082624519139125401844623,21558283039234113122805760097265638181763687038555764258857715920818106215523,984886258318300688046776785673289560458722425831829175079944141959971496951,15742677322520864401961943379313620949320295584851281667782848443614715444083,4674404119733957791400958869998857022224647524150794463860851329191601384751,8650727403827795422786989886519743572356271096745868930429292580249174286422,13805664248894834838953946033892670782284990791974158822573815009987148935892,16425836039758852245186956621689031634149287919733928973102442742483370034636,12636984265967190523588079564146349074168180793368546716527682276529007569774,6817261026014072560057398041777830163991050944713581458081292224492038152943,3842591846766588833800550804121369117907947886204778461433916219752157723658,37271592202861207450496704231110333036724082963271323982767766566562691532,12329580473492550135339911865680237906360631219143722403158320079104416996484,15059957190605121115530324002634619045808465757564252411076061916764353063726,11049964099753534691591813062197785153610766318641253048434615460367998657091,9547664187984679827610628603629867733891345475510185082362431432235944303887,18137012162384412674879864487567137486356542869085283721914855801046173331814,3685098687651674532509991642879131752314328195366675630043049707942891170584,4350994188192128309646975341689829464702598370274816402210557114155641708487,6257821888636845714306847817710237763041012260573089876542080703522920377274,13253018959425522927774577647502632317700972755867567550168937147898302735178,16128520328840705715994832968486859989808820923410546017533359121760378044520,20170678152633918405966535017048153387865751946705242558406886703664743352398,3126527212972403378701842254033672681067914451311377332339121677604578433846,6867262232134903047018643171960682024396916574079628095990181177262447593546,5158367668931323144529189475506903329651812153505452886267986731006143844385,12754662355373887343223103245500264953264637968818954284520990187567577818296,8184207275666143481387081482876989547621596168672026673494737134509515879012,18182047594483210481213043235431614943690478827150601132558952379296218497290,4111619186005075315994626077421177613466749589414703176717884282581714875444,12594743600504910896656839099899310633582995354714016930508253088263104106919,5906863249972407611468323572776947701049556100204019241509444413033282677489,1980080210708070252092652836439362225685565242001269004929621280778029319218,5317272650834519781155258400716302959016815255066834148961703371077671280690,6755929511172704567967900822149236127789264783942356076752317952971695408598,756653592358533438118443361825151465623048518178327516109550024774438883797,13279387228067311574007940426672455425799739197632963751860641037826906383836,3438061374000905227745499451129047661964429059615559246017344409320261233525,7182178722730387940200728260680152279805701386434851756285719594136478079342,3232238101879637288089008409532896629862152604458430213480076264229233742462,18349073713456068979069801924492847615265826078935260207982474961526062084683,14669461622305417414928378093274931180941168738663334898025953986981156308555,21025953377099738424497295026970813014051167806216418684116056037559447904210,5255626714680656571286256248936450375168592101301691959500945926924371301668,17282802977887473307860913184523745285865757781571388182716814513918008763083,7631811346302144382630250446520799917692672405169780636309223495193617534466,20646156492067995141068212601070346054539051558428492870963989969028947901818,11672162857509134152068238052735772663152403666766041363264045356497052787977,11887096806532260110007600390059506485935624620297229185953255478078857108029,21264877166054737412301473554803422700628127592263555002579170780541880711583,17943121804479032447858025131006451946994591698842739992603829945304217132668,21741868983463662771047103688885133076855201341036000119862339617136906339944,1382607011220387511006322153920014038613273342046755883486188937618436917353,15178143370568504520122235741397126257210602740650018201900729283546561696689,19508797361068986472532319429763120919434246449052564653746851758275251767862,15432472447501574952637182729640656917161000067956855273526749406835661136043,3646314932117173966129769917469131878046956851972292537742853525040261895364,9954239280150263233476434487622548184763162539776975088510280448547072413987,2860206851873890237457963710655623849107446413141590367626845970849894602577,7624884329556925103103971646513913063945080531848229875878001163429377892391,13360943796731806773064110741074091445121635972973177327949717322801106153527,11667836424651042501953164038576384835169183507720986280095771344954386965055,11905856768069261907772799745883705412557691028383268959241049562161180720782,12186322648958524087383458213507970038354441682650936942717890758775537576715,6206377886698888214976033056004148608870783801657981445534961772175420895794,9985786843211942401460306610504559890644549482837388550821870421722527522129,7131871091468632512858311810874313071133138864883788963707243539301333044473,6863753977467122978046292703800221264317404999280683794261458513920582107611,21254007028585610870255249088819596192746568962023826736493046170403367390748,19316740566828302369845437096994220205932229807972164794086423967490376053120,20911390901671963410235703071566058542087894960862283015326592608742412435513,10947283094344459246570251013404575174415295611564471102942451430110207789270,6629514866202977686466275098623310374411361176607669574816969946802287210730,4306637640746831336889157874035984930432037257905593217438853767758187627966,17842812026941818985973284751293083233650807309923063938909281923223690155081,20979787799837328650256681706033358558090809594843147876018416522952145532570,1084395234163143750754914936597532036526030294466367212427999310133490427432,16411000398229165199635990982959651490150157098065257264356189234661735382064,19529434083761568271396183578711196610141016284281861529889071952129275189455,16011589790708451889651677332030836112945970875991060135355201890489173794391,18538965510307116327958097310749618403759736800399477577603041239573656036369,575597941676167484590243546673541695594364334533047994047106268896055691965,10154888807896331879146339491538875786991737788606023861857914666322797287434,5751458975032524671409758081174846089867075271579936974413090425599016414105,20537352507069134091732836326103935751238399876923560688100837864640768370820,388393267636951339744357828936678047569934289925965154807382118853267759467,7988929055663996471299857775851374803891818939607048669296465149104280329338,15854279006908524023292733986043025770694447645646628114187722686173514956837,4521251106518907970739816189092928174098228189505033700492425014567434676545,8157530011801905607623371429913769514135441595931542848447134013030997901186,17210220909122096186649472888037140871466614174061205406900504999283153448361,8320732794514386532143557744115700882386234810376915665505736773284988176468,18545875500168811775790253714678031231209184655369087385271022571392488988409,1254781372250935292066700779746601577560528849791669968836092329802026798977,15937651643466826506099692353730922248216886908526960483039790489122416783291,19652922102341829730840072437940487297445121681514373922080785529489772301904,10503757973376634172224417598657275807288376059467419568957007645015644121173,21061128242218898797612547848348324784465891245956046422267179077655910293944,10184102990558905165359578703213338644155257878926023646496853865036973561949,8666994074867894594122739436332358585611317775525945925668413909058593367375,6295777974744736354234904948599345763309384248069989076851179466032501025536,20085880035576919555482594174603593248431976403050445801147514535176924689286,13336325268431575611445366940808804882241012554243123490613520755178670444338,2851570355537839451958385805591947257368741486463662868962800334058987150319,15338540229139367100976188303076834527818508966890772601613851240301217961568,10371461591548028790292642751110580057135152343433828303350260803216047518940,4721084162843564631441880187545375946421625038671651491284453281351611614059,3995968148066851603072141668595964652983129138292929197582737382184727007080,7098475965261931921667649758515107427024701354618287208328785191069896296466,4781012573672976409656547624587641549313089733225902702392506095387529662756,20670752440000061451737406274881546918677944716345491651236710839944182745380,12418063571138285842036790076814486174694060062447109012153384823149675212111,7811816758498775303698763826175925041786332617584902402713486064657610670887,12183449593956360154917192849776155473122126272381798975678273623416489913308,16618893942934404572687811463808390124523121286530811532642072424179325845074,19406638405969722482660214331214972298000686566522726077456272338753715959695,10114896891602590148908922343663289384078633766105057337614271468528428689648,12530180531394196901972330325311958484582015641092775027610123114239686805374,11041683014697540482690315932778449428117122302594146671576370088141482310955,1320027017053531867758788220662625751339386035447221928720928792758652779021,13527787960362675982060947767740337401799422304150087254060335221227857899395,13729174130954201937892395283664312766703232538508820386345658917013576288760,17930242209772558948222336463641867165312462566025913611385142785331060524930,271824668681816275326818116439977879809479607030794905583278884369947027319,21830554400118502077887728598392792929421142621825963621109394022313090676569,6549136256809735363529860847857612644334750418268339758975670928910634751983,7685854228210998769567354902455601859064733599194469796921674884534065104568,10199783250519025166562439623829544304874659364288345176426181874053651581987,5943875072296398061174787119165901172801385563744445220331957391085927545285,13636089974665970650510341064071559084615387545694695884611938887433039781695,15691183714733597776429523227229000727289026713809002490626629956876436864306,8559680887315082801378048339294171503207432568538176257628851229613536726966,18821447832687547445675145256777518497433117070692725937727249438327468662992,6902270693879104513901555672223877604634815519768564032457887408714154308149,12608804561676097764962511762420917859780577008987930524021637882085147011561,7174750477556160125005376833627217199860110410544187422988321767638233689286,8781965602133662570225157578692327961234407570869748187793896100695809894931,2495257954047729673944010345252038964921244093254482708244520480856454194795,12653575930477027537985334989917636556832984698125835912664116078189272484883,19470590483773048893847572401709923514063082100887826438398963400593333077944,11678017778870321267772215799288011478356485408686518093768970488464471570815,9301784115496434107640350077213193580405719087632828834385703690626291479546,16099421215741601628246289398699744194733547679841291314995675269636375173366,4867605962743281143953362108297759970476738545503236589613425112307423983682,4859206625232481008184446590986037965722621081800881620559019195768715084241,16443855645256733949926481287606183123363410685496841842812427755007713532892,9353805991413463049534222956121131872491808501219007024034024595326412518624,14757310122557726344690376086282772240920466622515316103858910465445116386412,16114284659120061956470765697027372797086020387576070056735297826889023849274,18127578981196629851526283391389653885301579188814495702848892722544020055239,19887508599212070022669423370158309019634146887428772891372609912344825709907,17077080577854056476313617926548386910187074435097123438936357029443634140037,13226301328255541197539849574625779242079524439809722670248005223174137129917,4960598616057280250789993806465640165902417481299684068727179165412382990160,1556369617946500605910052041338863524761596681612901076288655800401759143728,8895728155072279486251055328673751534060735340135019245331916382281698263288,2289316141803713796617375788451106287296998047295030310234564594074457471782,5743949466604344050156379807720583796608463915463812355649877415948657877907,4559156913695113135073666675680811432586708455776982064075705161369076248306,15885688417651643378493200422346595912547116850227590423936072108251702846077,21139883658951849592430718453383511736537035608453172046329191674046781461328,13189533415954149093943176775514655876533454488327933935436293535694805743518,17844001788757965004299951292259913492254300676101367510089343929865197748634,14359892033284780014175740986504899257072848573639227540808851637993574775227,6889876198036781721490463051636227217181360455045088258864933221139868422058,4553935378945711471651589030479778870996380701114996688086418055402491525866,21810472237273957206786186837441232294905360772841197216403531161190353859134,9053152935239668672905478856994179206897589996100634932367989982680043213185,7903591118665286176079138425128951407213501136276774569998580497121699548452,3172076359801796733031209099819054888498110723937314354878294115265190182330,20407097360746745587552307442773353270033615342704398250066232913190814364080,7972160291863108260254701271534596191348694866685225653124288422099219831356,2512979638327596184144169725891221385374685508088897591186666227523755823449,12288114406943148383409449156486826621388266177895423682705260002640229785204,2564780208026103504658010005943517057775957652807715289383367743075323562762,1819044074894043026843741029300477751989386054356309111356865205713103547767,15212165170979376853314159201892286112393022743512259361106527770911103031833,14546339564581115494538806968483958415473632518920533358183015375037245948160,16595063968058690402196826920205083730698910363019110917303832709685137640608,15141874678776355759677532828036793885858184118820760885539425739465598163481,18904695587436094037528024957965408339655627593105121455062940021234808627517,19691835186381553427610210595631576698057108693742599090126967830113381498354,8924094782966746617987215970302687574282302360164926405994916025579749820763,19703754039872652879247596753980834118500205932499483040527802680246732547089,1222369520366776525212393255592594259431640497623436777492426726914294313696,3172344047869282929514752164510333501174713324035401216632890990510873753170,20343327187307675920101255252384731549311614062918830229591450503470004905005,21822953127524319865522817898285572788301109254914611303940997016471607290917,4119200650145180459943542547991468255860361677520024595215679941381226516262,884147971363709313208000703986053560492302821976778288962675801741886201394,14179192339259619376051698338290832703239802203346051877647263334899616811424,6257894125748014033621520751032796530871364895580315426488126143829369988797,17601756798422918594467038792255913560794153830062518652267418453154739852356,2915639491551461190644833247357672612074490352906156209159755564104341441334,3231102949049971084860869512445280179160209744399934744399854930563348405672,13021414206859086129077179016730508855909534243359809624497206694614763740073,19605385510680022189244399663099114503798708854480688481468264949015383978657,17021346162472827600023529413773560471771827295900312703532075252918830714763,797420759229039341104668808766016498233266139304135256309887013677831743527,2664903618363391534009727112222679446988960947334573306133164042707563086517,3385549618192271440433411525547058485954511711526716925876581944420956285378,1363918352372003902477247159358100870270143261694504161661979865477181878601,17725129391688775312434400553484246750421349715293800612810825705415551685950,5565167518043825254697387383458520114240098359236753821784350172714709788630,12992626143189731743865280272360549263209967124441767673953882659571766635538,11778225061486552005541072536540594809710403539663018251279263069564781285228,14855802626429861561613008610208237167206379805668816510881008293269978954622,4625126357862179281586979391899300109486628847801168774082540966299465334987,6276441096446918387723860737716070503136385106381280295004924708881687527278,1795411699207968753627657631153296652726915050129212264930465577194539027180,3713335398598470745490569816543380122933539387356971485299483223125101783622,8168117481656071903083355331291793306622574934522412245021942135108094609781,2572110912790333345146174163319527254651486901580412685997510630243717870169,7025592394229454054105021012166569277499787182283497117950324822835039311263,4277841334216388876550672363276475272389275617444687843049115977026804420380,13307361877516070836117482544809649307840244674059174145753388549462990581425,3541353704173386321602971434547681828071166901335602064587889348895191485268,7930538155879758019336102161941128485659185437630747910453735785539584502699,16450196550849346986145420593545138121140944184099182530791513972233505276989,20317647049317277971067996601837330680914292615460278222929651175763284855258,12350794170306113031197271161768360871903372891508108500893141893703359009096,3619108225491731892480788907918892224372271737626523316019551923666189881560,7777524276793695474644184635794903798228263960698425657257115554422141857963,13186962355302544705310483262369096768297692231774754772442065918802639434148,3194922763633786447595049582526939577788731446948460263029416154575517633713,21764951733983707370163229447076318279945301269175491715317016754083795809766,16974123712053830964644120202072593533882217585039161631414357628477067270637,7898037946204257594215947941255236785530939710112474014338432350690918260891,13624131700578417700359325726622999876995826287578399131977467236788609909029,711696429159123395134741628515974061981015372797792603239801873522576934606,4454694656802154477610657384658122890655367951456133773797632953453271645583,11258512209244601689743240316900203988033840864814099786180897714348264963892,17104789493255338246571119977680210285205025930099647162805883642403493155704,2453935444829235217884190831569908545427042660161097975703593935054598308172,14865321440470518031331143407868649683664573698762400527582797926467679386433,2136979677653477082590579842429661891149048368379361009535231454875783700576,4168503404348819959713764969732410335826536398112246387116198899646877476352,14962916637001251079646555121263487095246900845890500033998976380566908488027,17784806976263484298477702017969482877962979780736193065620735094916915015057,5811232683701857296108715612406368550641241305997590112572736833619623657335,1137391750177492513773516911880446733365510948924761786959001414998578780190,10377533661461362184186134231677823404558478220398261395966741229154302153880,18289640374707184240721457180013244890344288557498104400868875166742835064845,9860550380532355283228261241815983394260110595913388936133793178666677861361,4874241362571018447675014656968369345960496639223360836208429603461250621707,16865415500549523957415217905648921092860879005547743663493860402980518775170,18108918097362824701832555936428153547583210042204293837516231255476913995307,5814882735302537469013996470647050035634690283351899637246825700230993102653,5547108529079575186420571231950116618134926722630598104799502651040507258925,15206849009490203249915056590647669409740170384956300636367240071539934234123,1640644832819090575801198338202018591671247888384450305015978486631872758131,7653538136953954504326423293731449069773903668694073045541918594328126765475,15742666466329712178554069131786945235650635594806638864788722339397338233904,11117991054142148551955400250530241420008368948211075786946321189997485480110,17233487593470788370048183367208371204821743424889641470669677410605695176177,1026146833779113517033720464553035587620506307190537032842523110750653300409,10367733177218458884804949015952210383318098385156812709591442491050289560766,19795952047370883108661392932328291359892331001341014799939338429402797554384,280679929395977649114582242142346138466205172264485418126097892277002431011,11242092785741474644852794535567939603118987148698147008638503870866024069513,5042585848515676287159684547630780418802525904631814404423696800729724702441,18076295265515176256373769387621576799326851284582393083567912446445089657195,7379637951216509909219158222610656534687563904425133806818053082443647546922,3558112975941340025714332950698945379582897448619066846171473836063116876320,9573479360636272045463430387538379484130343682411115582933078720270296582700,15319039730033276973173680817870390182683166144884901717164880903880948070156,12614337451840522588925552004159363860236857822744920028925848657320885223697,11264872143423037953370674414336573063122101340016831919048747444897009600345,63551039484071672399844495086043200468124594386399597718753671627443264469,16482682562437246084957175194240509231216838776265462897558195414149416246757,13173166853778783824789219649923900522843999506901247221151336885046420684780,1129677032059045391430942335190974518204360360119509444502890845544005628775,20501934327919041700769005911882447290880962332107224642437572131655999551570,8568499318929533224876840771639984749494220751421895884374508523238084517848,21259500369117112858046793730986192593905655365067722159200063822227414197523,18511737784245858621248028192284641888665848600116211193811323135518967443130,18603594203971848110309624617834986072777858306337940642153570206399896731227,10817810567854821052648176407774626914880746517118466269332776843576340211709,11799868341887426863553231699803195039814149532556595741528976577115279703638,3757945008672794110380903983621818494776340526769633536295923729698796873418,21147309772231799704776665377393022398575359474581992532654566514687692622381,10106161080097685505341186856462439849936096425798398803226308955853233801088,14262263816750661321610690116851316864336319623922717953366014185440110799541,15141933436196205178645622716666344645155868155385407285733185900575537844179,2528094772114073897461542081006497820213677180486542945691028610950494870091,5348148742466995347556247741747876445951253226718284728036059196493410775291,9450763449774399387985728640759709076413273047954552646207186077905960887466,4298191617478880606290362740003112985908172107645583722035275913358222519724,17030410720819419348097350980058866817562528502379090451415524440163140111041,20216724013881673832814480585345314476760112405406761404693215284600396014822,3030458477787500523997196317647453871345579139634715247165773460115609582330,4498462169050723804654682081938858063245557243640516301148855502903911071559,21824371776439248570562107317467644300343374167209593758174011062336014366712,203060629973198497909844961226448148781283822023116446785885526153889141133,13138719392503582101372758211337939905779727766832919837180755391232674501632,20854865022095468190800800251894006373048202378274232848293926367900444699099,18588694216199791340977948229034824338778108765317256872571104367383806683819,2107723674718153039822163382990954569558924075626979445723435572951885590282,17271751087973139804430243764301653129405836972234862722312699991367221547648,6601353498913454241063626951167220829716071681800808284181512008975791453478,12008446685921630692928691914657961114819560167122558958661337441533504934249,2546793791363939452366278657165405700949349144309147725354170056455546924821,7509639228703028871971491982924543490428017835786144030628769546327315651842,7823420836979374535855612407590511724416995784427817183396908887631615569374,14440328435891567217327191606342183091806515070572157964854472183381142306857,13108790694241576486381404587677845524627865147145072471473988738194261674445,19983383938241398968439231728950534655853676209193309061102635732967764422018,11284194381233971884183176274626185331731276627680969047259362251065411330490,1897088360814614813239622717000987185543144416227464749796311263447835372290,5857538086726776983838909617047765193294143035705320425608254315461849915283,4535962484854275896801499258204616949002112470323390523101255172552516276853,11469688959565470671946358524828946654780293319597759366277869041848383938506,20012499472065515722935879215306365340460493343044867272369823908813586319215,7237913775106599492643101364689422933623029044428357142837972864389129948204,4449045505867908852965142075471111990333999619831208332535528566178225482875,18979580728127588847832634342765381189070401746541099544183581604411319882119,19208895793797113211677254952138771238229741398313608749033216609457932026240,5693339887541566707818870620263679026120058867908674300592248504295030161683,5766336473322649734565794453161873006745293312886382597938223884039108263098,10170500372500319676592379791726967782477062446940064561124188934689788907641,10715178415744481025577257316838846623444784908902638764026977772991007652177,9619234464729169347469055561718306819745671419829947117176160764784203967441,1725396226859654685724455004555068750501182150139117204170589152838896682582,12812488682187532465982035305360477706619015575668642434536603051988822585780,11634913038840687277143479351580381035995147077852960651195662158592298943782,590921624537670966145684975359593307845422616174883518035926979611039297697,6994357700776589034911446516222866144704328090940819982199063011389928815878,3578735612848960352693685408184960756564585180098599373883079061082850989193,21635405933646037549623279995086014983969914199701848464885184930399308788578,12427020649229929152974948764411072254994310665316587507041988661972823471907,5659276116329803541059701770846868827421187991242679567541795719989019960482,14409569205409757172710837837486699395207656272569912916147975142886221411048,20174498258690846561506592709929532887311794985051466436061305284714705004116,16144749571419779339987554753326186342500618892721832987727063682036648217899,5806868382318732909919594488299463205875390466419224655308941273678069453955,10943981499006299439884803446608501609107021429051016441936415463311572940454,1924938839701254827227113595273674646757106690922839787536830436278569286096,13979276902289154914577571664895855335838520340557113744304695510562836235170,6432081587087260245919599999151100148827877257649626745290270317469081484560,5063153002404552050282559105432952932908381495673902142745313078991883601735,10740439837861405332126185761433228439796897508030224612484767505999462329793,12737167379130609027705740172196108812439282784347836729589408028420120550933,9849845512381592257963507051167559787679646439786540183276617129759373853388,16005888832870175950940829700448047001850581165998249926419521156267014986701,14353647838770412975928759605442634240665383526900174470441397150591603642336,9246400563934815769990941385821129793696094365581285133233487333862515377594,15148965960125250145435338272790355289745702742252704183388935133186551786499,16453015856957375440870560801879892220374643048047546023962049108638908959772,19594591292469468407344408128396176069613863801953800169935974455228391704047,4786494574332708919915792733222077450535137127349578261762663721149074161698,11960730258074073655703739602687794653921577208052039888289111813676118677358,9848013027466807250590439150605527564079804116846510943688041755058752584380,12899034273953092771018315472337883592076632199623658827592500124277160375343,7444799755957099892747756300128576168091670485463138298855357993349282405924,12078602067619785815908569606330383217651816461769668980367782310218465279082,13207091244585343533434026539671489949734093160191356902826819065281696899279,15052325250252549646358568907141836154046676521102037138442805194847473405285,2221581370746975227443137026410298234625504939466881398515488592571828181681,20243663867674839549278772384366563405687275170339456055149452630358919741102,9989690042997457961300135390803031791688603090074435089369924996763771804683,2394175383139107454721858241476296570939299158552117381451586030928104650195,14935488700038770608988697394320688627203362240444723637257364275046157727507,12264662514829291661352518974189445073203160920355111833291657311513159477694,3827639321249325764386581723986872585672536887010319153929792264348424272953,13487908627465024716967075008462681337662334712641104635432980395748705243220,2271300450003775887579228062020983806396606091928055215698274988642377017880,9536464905154879502929074042077088011040150301676217212058440880221802373843,11224187363394886568032176392622806663752975492652881881608898287407285044670,16348011463839183311989740909923102224397330137023072134870626410011917574109,658746784212845073728972419644775580738462236799285816112006815020578863053,10913847351958014923157235635013414182776322060119409210360083568773647202922,5174660898410477334415120015192903322111803813558785977142572971088703464181,13435625677277740540867428279095038525759637068783477185816475988654675258528,16042236961096516425577672868221946711334425239903980281947225696871186016946,5966732498522491800452631630164751678119619125003570554878083612603498334850,19244421524004466175382168721538493986709062021717633087544245374056859990844,8953835349510092921386508744116096000868233729683707705475555286120350297772,19400107730527891751069598685513048198266948717144299472180340676627124394816,1788315965311520067508595535605409766732846405132796308898593684888230118195,4155306741635339863500551353079678816173576578036039224848730508326156410064,314333752297483020587573946457568012126281776266668278461087690408622762890,5814056308990522321998868808930979798909264311720790843253044589964499450995,8139572664280730177398240130505806903517588262678422575082094265546418213115,5891945033023051894996849367995027817716659752927558196235762187145542665778,15816119508706283096011330636590931848201515685282376441014894443298875354927,19765585883129509218113831432898646175337020355613337867993568030797990428267,7571142440759701899321724284276618755088451471808734385481644938761653631281,21372154727662886563674173359368281518527052830463392775221052936073944196548,7081252182490962865977081179238366944226264513969472284114001831030270956045,5223967788855971504613125877205268444815856778995847146009869071113923642838,7616031404430100022715089975212311635761004286094499406826744277117238450802,2964922410519663416704982602737862878081135021433460716313695716253990013571,21452022130413843576926752262576843465698254258090353961686699256674273446998,5615506565720477707126907662373732333382367798591588442255590186949548315516,13758529852543878424689721858680184284389257236387722027067085472062441696813,12270911407050929770266474860904788952698196744336477194920983584641315683723,2263765921105974400584982144019036516750696376273595921030243162454245412438,3726743207790008961875115608784686494039367610419333613620227882409630379219,12237143845448219572451550465877077742264329541226110387544727976984528388742,2409964261853228751087973651622025781333933822306168735290950339250464395333,10085433407143766997440158468408095154887290417940533218330090781308733416929,21228510717137782368419571997756416328932321564657530623869061270948157027291,12056471592273332515153939599576024781202771932636795778229482480420755693571,18213366556788088673353762707270651486693693110301565439057413547158475404035,16502444929714671396753943873426599559613041594477504659253173973027014569781,15099656057998038622782214961934296168421711158711759920714280998215172598701,20662687648270300297638887955756931826210498273982273406811895752232434295545,11319823310823640550774639562916849455005127799420683680222546170719181512525,343967214752520057864245186069476394037815047607811439097329864410341714737,17503305564468603693734885462989691651193248463782636796950758256530838277067,12741605036457271400687978857670758064474033476970216981099556950125969853613,20739683061558313403494347679816765721522415874620086168947803143944678465016,7946584883804172227025447539224245968128890222556746649628342784345139347190,8360187202053456670989734732945943173170474770371603015342370151451116337951,20059356712109588518115933733238896878411826141623495434229710888297572857371,8908929255369499016159063161703140212756115979036668550222341666828086389886,17260316215848220480068274186000229981635360232751196604952216075987952224195,16051483806631795891066047812303438046492064609198644392699337542232076970683,13616797129917979734082711158569544985901822934952385632710806021914842733604,7121878885265063724099916056725320671644022545379534508159519935129387437912,5095784041111849236518098036393508072376638346067943869740820917637881991288,15064740101319510049989912367011238454044423307266600930402588789041306100213,12407265211081220177754043474825255990635653794940031741483370307852381609406,20223426484470923566833281385864037127075416246760538371032215131656571722149,3668052915108225265616930005001596789890471435407321351170819088999432868806,11366073886283256473381607209905269811061951337531274662130606966429881340996,12582247379355857288799702955077607346019480970920005735329811307693949234935,20186938619235157734865577521404397515633405422805778974853873925656656294650,16122019959033821849412382360062366364664833933984337294691025029563985515365,254648902211450148074737989547563835748091091484232032343713819397130138530,12172833228273710344765296926585753189586602769025493553315361303084014018635,19945409419975886341220734130071717017479702410716315294907303154809664173135,20712004789058289094102947689666173023011192678139675809444116843756511650735,21105077263104009643989508074340105423304108979860049556255519287288188396634,3538342015671194745411221642090452794460666099501316339752121561502241774127,16008085602703591565147288064897579335322875565262127586367715180903703479852,21422197449727241817827580893411034314307602976542729347805156844487333432241,18799547353759539084890273894754702756999055145524208124647385295339036997359,6376647829380850860365386439681035038162788714588766405462355210239582784337,15847703763893026451216792359491847622491103863033823028942752373064363683711,21753518314824757010443592444509359716445873322887601064788806456493419038035,8018616956493930393966420225569393035642655431019891986498475494315186954398,11747316959744110931059298678334515105505609504722662598929370282308351440074,17893257331206244838570586905501874457956496735362457086282197258342214145307,15961328802051806619901962582575367866289226289028087772591680471434203677570,3236169926687880505076444874746358996739587258202752103445199991661738621601,187795190351727293099714304116924667408668969503996281039583636956966649638,239392318624502435385014551926381415338676314268675338353695671324466753801,18674319341781941734600473869568608233805776945980535084119278717005726916471,2771345443147472606857365655976656180452504182686204076714773790025740827296,19450913042313320002652706987083488807755986380163327474873550819278969177372,17088122609555961904069874590098938791545854926952758736324719542173158272235,4614324608780439388145100049836115973615823562529414178724078049067318464093,480346578559945500918475024651677711916332481019644166207062710283884336501,3976896258432286534710425248577923525874780501683135711905396303214796569813,19747713021879142821191045416534012039092734284665942138998895512844748934520,18114341948852128544591474427791645861453096798290403362024577582905309063343,16389740922636415377645046847550552757683160597807953014971200028725848855677,14347956677754622309732029695580580261895229653511993172444407254733241454730,7001790022045736128714608604018732713668075078108360908557371520612055210303,19272993806385013542500911534969336370461053778032527920746797814743961064937,20666992739220376856615766377753030050985727426420972006419425641580077380709,18907720165776367637548948232402401955322000052328805042740522159109944714138,9414327783699575006459158047005978347088459439117502202158387157394567126641,1092342932834424845294743018087259301897007735031966382725140810717192908054,3953337326499755715834998572085254989073834902724154050737740470058759118498,11743581671122680453195477167432558941219274023697487318378655108983631999472,14292519320039108746758578387893135567048390166844266988895150640926606231575,3463895766707893138928153619402823425980920627031760477180165727285868840115,17329024693549080975670914737054013479227561926835421032215803061920086593805,17069029917639740020306921281456148921331852897276386771126788265397483239836,17757973687563632162101087414879272203562112761746273122681647748208587693311,4657037101807059847480820087972588696422739806756490960821623277361176723008,10031688077390763868641078069309072895683953752120759377432369407780311740458,13372959422785941027234359900894463458148714364727687916236363488102034358213,21074689968655856473305620806477766182958744184789493409758269023421704332636,19863757339575916461434905195916835719746715041076078424686010055572742030617,20973060471220514134365115793881078818914475917880454352814198678201263612788,20786322802664930407040804724442246307149058272537433665345242730163006184858,13503324543441706240017837835235888103455201530371938269103987765298019164241,21516545371414182695629550949358554432241582789246093981854557932438611855051,4189468076924692882857105215398697213714749255613940842113064700527656187139,6356916718613787191898160559615069566270314091650855868585425220261360364619,5420879043826588690498755027108627480358930425000012254678542105050717051191,20559290756493460657385989162478253178529811977588548661414171937311774738356,7472237964286313816282734103247675024752524054147218881654824853569171740182,5587656354563280475935968622322500135733558246449238814064790207486002634312,10477445403396666334274248654801801931117602962284736619479124362799824273546,6964581565574090633894249931196779138063582556737680018364077690424381812379,14818621060919997284977287223747030674994127751231587714382341838934955054844,1561884120897562502024552266455149126373072574485245753929487036177604271779,15924114719216774839217247278498830109576711552882853826759218581616445364187,4632899269214938328686734061038562662617634605056083586217293196683107383226,414275447940334199421265067114189311498845927325050140106659496782723706629,5919841635132642392689439793932385370460582843320887853171556097049171723480,18213825499960993231734509662843099396992046367870190109129172304011496568015,19071949566664135927732333412944575018103341781608323568493744120181505633727,8055738556659889630969832748361502052460816679489752687851823555653740856922,18552532582629910542384644188750599556440125083583835015670173118025699825513,2484657787081400262201491424080522833403834349414361745080712757081157295905,16983418852456608800545535696543676988540233741050842886180695807863040864765,4238493546779457743228884918170815223308340385056120983013226844661472349292,3630132677030524902934720712211822367613329466140887879132884750998038269473,21054939309368014542663397737839771438999660373085660928983975055849174262524,7764728564558131555197022370274162477498111431299751237388301945333560774986,3593305607441900907267751550709584072658973999555174092879673804077111387503,932359123290353753331737736031582956463161520044366983625790109891741693526,4731952008769040870131753442142911445224559732127188801247458162044777478911,1306090977867005427161468095288389390649620350907397989639122170049060845154,7759081335204598570892984361955322222987825766180300022358547686895179745422,6447993445251075592811527795404536687284747599271434406060192746881971850885,8266912047004162765439491557705745929139857757706428454484671294796825044391,1314461175505921794571050454800604608649221187723852105188152934159567388084,5074821468464653205102869421665358795805465509804176663850666382476895922210,587081217806702661903500809062925367993834792468594461022841500167739579474,5264606314717935678144297576598053656417231843504500779254542039497862460981,1236480134248818593225404950925034920588295884010411301784531216110810413323,13089489778236095768305861425107967360517148121020346060932975978601131790499,17291786821946523371971061686693758035121148041300868933078085040228288669056,18124176342257558638062889896829524322479803409217207498687844328613679520644,9905839015283285144616603221521153361618378103985458187286841556656656429741,11809535677454857598311615002421831170743476213662971184893106000202355262469,4105258996829645758179809917480600473288889890938687299484408634005613929027,7249994723657380623014328438319457303659016324967581867420756005957067258456,8317023308476962783876206275099298475926201657427120954368652120829272222159,2011843005377857984465704450777581623363347938947142463422784260490016214095,6478487501062645568595261797056495837204909062128557523543545066559983302854,11332891765024246297067848612322823673574497640669814572890785705324624377152,11310396674827683007586339726668223579107272179969446205517750064367092175748,11099104200525710724155767594487158698174345291601467682384866473391802992487,9363361473795780293736671173763300702046469200956940247194666073284271734887,15151887186592767507545683753579108698447339021705506097120199743211891524973,19881265730819081878858384565138117903272592569639633426872725304622695029688,3011117599368717267651471428189462533336275598139751114483084233022831296797,17520576180525374756578417994075832591962992432186234756248866458711765589626,6155276852486738773749976144225301808688416984253808800735523464178476071704,8631372484444450448190767419844298467817852912545286035361602469665228507964,12205507917633391792796810613135648610406161967483463808645931187075958213927,18222453239521787308656394705559544583576244681888667325435264246411012699229,9033412577366915161372037999993563962295812571996632039862860993305238914757,19454897503553988644403623432258520403053811767663131188695520064462224816016,19817199370883464197796219716426529872878349643708961034403389904486407134637,21290720498988312226623568214384902017696056682729297309424737295532449054922,5006872489582777310304924776769064242968147807589802114955067857036564413999,16420397542367588392786684585727906891797023280517827697299749514608736021404,1300345640934139074405647472243803688216465663235066735522675025627248393466,15474333493788166084607018352361187159147026284793436327548632778313351493399,5141280817333171025837036045163967613491344199994520722703718097693724060240,1674845241197502896336080529694883486542569529162942594482168089081833468174,20749587232360151357799983517636847191215950040853109011833662933435613635469,21065338667581575565163875505871743203827212418043845343534420193848874866739,7051564661861006096495144384640210161011647325580302475305699820188085915761,1121065721208670659965039607998179107433568481023836429952089959263844401629,2114003185799450303041425285829091463889299614202766352631616657722513595953,3334382524507526203206024024777692800878664806770692329489928846721311223692,5349561335050661854855918228516028812586933810356904077294751460675531266141,5703041280392778021418588942391165300974701557007394123618062308100870196445,13673663050707034371520553032876769213055293448602317144467901970892454938354,5483873888673148302254721546416819014852587382013956934541598037319090821435,19318734450985860065269203041456593881321456849029001758521815811241052123018,12851330354839827372437628165464795441114428848058858241484775351172304561256,10041542640844175943995712334828870579034783871076347036534323366252583734600,3589445341963638025665117050103495399260947312205835568650192524332423143081,6240962307810325966231999724200767949498419326824465195783823947519631917688], - [5891205978627836991071144083270417159015157070199928807771268303875194037650,19534191765629085451497649051014772157774065629075791332793195826681584551273,5154833515272483128294702820663628026710043323095920240638701304804298499578,7917593571945709638335150893778153193741477651398934233734658265336884279055,5133163238095742835090645087711007173805146496653007212988348307349716673728,19458003745533910239158707983408152209004063097952693956218574434126899070042,18880819400751577287416293176849355951596193714265500681157024197361640709188,11433257809059443065528679883569438998689217744131300496692049205047550090935,12190874701550908088290603272755607342096152398135156662834905887211629834704,3673886960353993252497154566539843726250940370616316569888448647738018022083,15676037835112699420746702265028664494892600184195941373794207326709270851677,5045635616511022726309482514512221209262777381751689684810362174166837266849,2127981970274354891783037834911068612842150500572698772082540184222710046966,20602209860969247631763456039704661822909928028055826436834118113792574371849,4493454930923344041221912772221535937546211498548091351164191172571413962846,9203273896007845628978022785284502260659411177801743914849998536940830966257,8789969715987458351416076625905723956294447007026950650495844175328857015476,11215930522605102963220331022508304708093835095809374254680583403572809751875,15586225257380986275249577321891268850474446160605827963612996219805386502932,10011841080310254678847831138830289501574615297642717372149423820287945856079,18753960408421275836614693391945489354883623026056573684871883182548779915774,19761678450406536764850099419131825403291221931719095841429266089353917202891,2072721799733232450097521331054430993573774079728747665078766019206508544636,10615297085623730419003352440151421233872764050371800287995783143303761635742,11342862179098306415193268089882628716478112844171129584590093902612740081938,19276661508999391381559540866976056457016683157876039262437370976462342153704,3487982371390545412669202630006964510064537478038100559383689697998101381695,18019611455528497754832260490613820837001396745087990928355304172772344827985,18731969803319425707048526160946688629598037600738751037795347491343115736279,18895516979789867152215547520753345684534505439453679476362827176682322481937,8262582236770254192527817333585360308520228688394271238254948357217070957179,20124670759706967221386035867404978156598790198778905768160002435038055915086,10113512603622787997151768792636528607526786828914243169997168136386113705095,915897670578586705347124681284501818659263249883815809455861196950322359631,4168315355477923626825760085789663510629998017921421169386695143739645254818,13671994112691093230470350971338683534216964112891455368255908216954091232088,16886224211742114996348237388698196253930997227482938831037908300450123060344,3345133367703042017339663005080189359441174937067366586009093723866269451347,21528583089657067992968569213666076092311468898762774519530397406988724032331,15876161034145690426475777675897218203065468785806228994483284137836054650127,11419482087592638487692501143058453465931464811952523437138882421550619359191,4688593371456663565609532492788107789533208004746508669973851893459273665535,1201806670097794327812047975382630669548999745861216990648173033237996826404,4317641195125807665177432835324854194367911827066332519796115671103402289320,7278153623621857829571838333149240184056003767208572498343141321166882833584,5645725384264681461759518050072125001915558414870126637288820197391715227313,7876944044995178879031614460771670730631140542631541219377182212657483769883,1817650660807237476840344988506407016951597837358142384730920692904089879519,5477456541807551375261337022497006230056471139241891672239301675658950367705,8048211508931499636316723219242009338536169470228918968914286373316199192147,11051780522682663717015921863167554166331060525740053284975151807269395431450,13621239165564266256293257623306520070257833884735472109300551735647149439281,2212937635665982737914958126511628913962157442295931340442990688391698941226,15995366165560744217392074544914614299200056620022955679432568011246760194348,8186603384193770310414376291688089375415922904100458138117461272757184852177,19591014640167727612037871145675698427320771791339346286884839214170680861630,6878084246380728147562027775456286883121281123291292075367753371891198993189,2177050211387664317673794964274713735596159455191994291603735988793477650579,19810792753868883549077084303872022596455081266982011682803771833184330522738,7185072414158632003497987061744951789947697798790757573674746012007540132625,12527008463897431318214816404214269326472255194708737027196205809865368523993,6934500447964393691613594947677420114877610140521721836488732706620555412923,9978011727059765171039296158502240318826874847845043732001483806732259491882,21367223873262404675887107131444254925505042466133465670356500592380419754092,12370989539828127569760369184182336850673006315469364895069603190681475159813,4771734208255151020750966033073146490824522462970752283771863328392876062708,13551343845317029011162863399460125746613189002552375164523344552618567494698,8714428409330855425634336943651573814895603648572558273360471650145732556280,1770920281347553432035718101936298919487500537138994976517066719980578590089,3110069281490803391353365800012007306367848815614936878141004366920256162421,587101336788172489216190547515347729725635829809300681040400739386253763168,2745547964008447408503376832407161412155228373377123760513770235899201269964,15688219884606649780982718944113231917978875761031663915052600865004707442286,18825709614401251798160680403375685428394659815656068061728877494732182115807,7344398268236623675422623600003139537460576229211381042555723883054380022043,14666515770263042245313469306170077834894759906373286169967918153150186862642,6262353441640473491135912890626291592970997790093308164286742582769628052614,16647307543328963728423591228360400112670150511841037950484862728187168155597,11187123547390829437191210933751439038277808812390863028310714957203862953416,13431586020033401007013925927716006954532655767977222332198563123215088393612,4290575536028694423523505804878297212249395907285796384174966179335089734293,9525030500997851642842588010076299538258273880797610368114449809143832950303,8240494019366037169932737683997756281590058122972608854062263901069681117554,20634410655079842888667296641045124414486057143740858179591482529433244800210,2021226937398532158458585055746155459624344885692396128118875161667614679890,13363628208058779432402710458326211021009444288989875416757721068391318188214,14662421589311461388753832631349921077594459767269924751258576584313288868105,18478701421001679788418312436274921897007545359172305786472370930338255515306,779644354087716689348274274240595541489283221242495213448957276905050464536,16071592196394048404777963063722475415819376772419538934537115615105548954438,5095096770582161819227893847981354649325178848130636101047350986634230116037,1243295118881144894548654933667320243992122811397983231810580344448403973343,11884934205846782297010667633102865650294795721122133935339824653150509106639,7458968983251027899406062962031140351528726088472453510482489928822496580100,19572605475586099575374380909719328911692508931262625802140140705257944509766,14705309817743162695613012501115465410697971407093611587529338557210155341093,21814585268359946040619047839768523980706543116273413618895661291550785045639,18720305501197276565912107809183977276090965285535057360911917408689742145019,2134301697439195186325742384937390317718398738774895777564128344393744278579,16999326242022117650983709520661797031983791094852258286603416430772587131676,17897483181215416614794986081059087805317610826416633427262022077916365348849,19707797946013555426424189263942163273279448488563211841018471715309464788783,14555678829341308540860562709255991938855501651550888461483653488337939676588,17257409408848021559108687223120061819076248102607600439065783833668882002860,3083159817330696927114122348973911210253613266522114299928693807761894470034,5736074496230638296274343498461296106748247754169694274901381380232637436330,8207744709591183622611260068351833593643143431375276434360211505091128037806,16073710603427960567922233549405442518423088068367439127980767364626490766482,16125801016656798988611163501719363451449395969542389751490084517803061425074,16681204974924630782971582682795720527615927905982945319130944791490607417696,4072675318306311800303326010748274698511258916524447342766005819081244518392,4639558473350853876171991553789446979158416238030006798108198266387155784407,21611752344375994669307116989730257280581712049771305171467376136735830835317,14260028812889714557229612460335412900866192266288236233734870104907234066106,10936007367915129326030460455513265303372033050181411601450223671258879981020,2935032369592212871409648743766195391225915910970902425024269583756879977136,6634946569637959135045435256486295750841113686207268069245788404426148269439,11165382706437522214793349607928919108508947068233467479625942161240196013032,11449774151698349588558943383567398137746718964787475388291636245211033594857,13380655477865684658511486065341626238240224687038830357479380314844874141318,1556090800260299290436338214947407050034615159120446561828975680392439133850,15775229412830292677008903643751483031582598935755329498528261914480871637362,8325948986690458545596228454116700887740572176003019243020371356605705227449,1530006957398320461897940887072398082651602436763497487522949690691142033613,12096799031117418724262752691656478204625211872574986459351576236141568686903,9795222686269696766812901618791046177266354705263547407732303299461050133927,6370027108686216641431817942352503637286925173249339052075608610090399016749,16881432515653361341795686702127944966732199129855247935726797972793170639701,15351738821101585856536273249878864428731819041333447251288973888111661451683,14781212701946742438784746658712056984412254191444809612525158953148214912100,8091550554023025707193058566806958042583606199181127012808071174695106343115,20490495862854672187041438553984493686275844004543178578410057111061213880755,17273768908086623408127314492263145283983205996943328025810362733169697859553,19294495315219029609698328900049261980545541811825479502505060031138576089112,21659964890056395567978937545379633715401240283937936880886676845913261767053,17982445074266408124204445317785538167802060185652418682509052997213396963809,5844393214733022541634389892381973171593154485646342141850588851005973351855,18594392739980641449638044568401634303115397702236811642652121212412266849233,8182160648431978634742268417253967926524505311200391645921674911687111696608,11615953679796573972512524871850400010935503185676276201708450621253942540441,21529769273680682324960067458105490598252059794192747768640910191459525561125,20132110404365493609540330952369583903023878161175287878881490874880122068662,3315629685104800403477925330007368560121731964009894641262206418774875779654,20760167657218552641600617661638902204729190730886821404831449731791027856388,1071944235595105837840075721866496337725631499557288435858051131598364359180,4555500238184379140256400675916267083899817767012366155141824954325999920862,12550383095401941417929336389002623533497339330808819244458405679309028814897,16242206659396631583090203067480642438705316999988728264056381863300603790054,9739751068073084582742270086389269366580429568378316378361121134559060472609,16116599372526867528428771037225046273420084760475362036998100512782645537424,1491702476187736766465155485454380021314952117101776564498935819251125640550,15487639992401023512588653485898591177260483949656489128772103961337143916568,271607781293753174262565976623664759968566553298322241892863651425822643900,19977950168772761551778240748644447848771422612925087742515420134526515662483,1983058998587842721058540590280805932874010898105761473162166721490888500174,16107724245058262116195892590046753877901405295502298275519986777803068771465,15598969808860428995774387003121151871293432204528482957206560135604646381090,10303850219152079194793643117738367623863138704730923818757626414538626924093,18042134015692222011976424010811982750427479608456170876100049843530175591980,11698490610713203406365860893495577403678312400711273827266244766764136895745,15094763799279956189651458728729592947034549021140257103479085265792492443257,430096731859098382312819496464652103427606481282347941948051379574546904741,13960717870097098006695192936395126361902142536383841733120824678277505383661,4016844697779547662080765040347308557842613782172342555085194018348439875647,21390612758814913695838461279472506230937295081984131634720827665924667792338,15210153052017283712229693210655704356560541803226219169450332030313730637768,1405020343631287949667260064722407285384539868534544303707265307694982887517,923081188208761071201163943024810005498690637139303388717205039798310044759,11733793144318360060340673323677375331041661345320756410073354731608712531433] + [ + 0x1373c771cdf15121a224f330d84b6688ef9fe0038a3bc26a28e3196578a0000d, + 0x29f9fbda3c999836017f76e121af3aca5ce78bb48fa867a6a95e5b9db387533a, + 0x1c7eb5116a20075c169b786d9dc86a24ee7a2525b565bbc262209a8cda490528, + 0x21a549eb554f0f859f61d68f1b6bbe9aa3449a6238546bbdf2a1c308c9cc52e6, + 0xb53fff701347d1b9df98b46175800e0d3250ac6d4a1afa71a349ed195873508, + 0x2129ac4742415c020db2473999b34dfdbabba3cad4713718f95e6346e1583b7, + 0x1d28f305e8b0ec88da37c8251b0c8d230b68bea9401a15f5124d64c5454bc29, + 0x1ed301e02e3fc930999fce6d3744c23596700c03720705939d61cee451faff93, + 0x2edb1832966e34eaeee0903858afedb13dbba9f7c802c83ee628530d0e26ae1b, + 0x123daaddc930c65fc67bc77ca8bf4123fe81fbd0501e8f89ac31a698756d87d9, + 0x2bcc36362c90210acf67d5fe21d53104e9d5478d057141d3b17259fed8e4a8fc, + 0x1fa928cab5938207e898e61d99c7d616269144f7900815b17095f7ff76e3c9d5, + 0x29c2f1cfa72a0fb8f53a631e84cfdf5cc18fb426c254f5a905fd3e831fc7c837, + 0x2da58609f78b29ae6889f95ea2e8ef01a6a6c2814ed02317ae9e7142a29d301, + 0x2bef1f45efbae1a4f77721631df4f6982555d05ac5f5ed215dd25939af5c1b06, + 0x69266bb89813e77b00e34743aee026a873b7e31fc6f64ed57da189c460142f7, + 0x2b7198b043ff31d915deb9d5fdd0338e5bd8028992cdc033eefb9cebf92c9f55, + 0x20ff6cb38e8d9501add93d1684e5420d1bba60394e7c02787a8deb9573878000, + 0x16afd4f19d312cc4b2568dda85d89dd7c834b05b4d8ffabf4410f15c22b77cbc, + 0x2bc96c4bd9eb8f09c17483aa57c5c05f002c6a21aeae2201e882335bedf4f1fa, + 0x1827a11b658414b98b8f76dd10bd5e0fec96568c2fe059f71999ecafbab0a00a, + 0x202d1bece537583634b6e1e70659a1bcf1afe1c7775c478c00648b437578d9a9, + 0x218b5b58b3333e735ce7c88a6e2f179e907322150a7833fb841325bde83845, + 0x117267f052b39319c4ce34bc8a543b13e80784662c208ce378ad6118fdb0ace5, + 0x2979bc493ae1eb3e0df74316cf12fdef6dd1674174a00ae9ef908b3a2df98ab5, + 0x1925313243795f90651c448c814b13f2fa988cfc8895c9a2bfa8551164461a47, + 0x309b8bc3b0ab07525a643105acedd0ae664e53332f89a185ed3d7f1da80203, + 0x2c514d1803b41345f96cadcf983dcef5551b7ebe8ff78f23ecde23ebd5a36831, + 0x23d56ffd6d38c9ba909730fbe6443cb5b4cf9a9702efdd98696652c3f2d1775d, + 0x1eb7ae2f9df6ed33760e51a351cfaa3f4aaeba7c854b85bc6e2b63cc3f2a3dc6, + 0xb3a63736983f365880bedfae6fb8fe5eea0f32e0b398e16d610d62a82407957, + 0x249f511f31c4ddeb74d919cda9133fdbc1cf2d9b66288c9ad13e02c719c39612, + 0x121d3b76e65bd665f5f5d2908435c2571441546a9504370a0f0c33de6fd7e738, + 0x1e1fd57e79cf042b1b3b883d4f4265f15f08839a8b5c3f1802ab7b62d55eb238, + 0x16fefbda0580e528dbf2648ec82d6acc114c3c1b720d56af01c542ed6d656b22, + 0x83a8b8f4854d599ee237fbea3239f9090e06c223b77d130f591036be8209dbf, + 0x2a521323dfe7e7e2cd622674f46cc5d64123113e3423406966ed06f2e7d37935, + 0x10fad028a543b9445ee6841a44434121317b9a163e423a7bd6c0852ec521e965, + 0x274bdd049a73b6677e0ff3e64a8d76d34009e467760819a9b0189a94ff14f79a, + 0x2669e29b8bd468aa3991639947dfe76fc166111d6ff1b24139d2ffff1e1259ee, + 0x12f59494b5695acd76123fec001dd777e40278b7342b34863e61dab94779831f, + 0xe45ac1f353f45ff384658f34bad47b3b03da93784b770b607d22ee036c8ff62, + 0x270d5a7fc5af9d4ffbc6edc57c91594348c60f3ca8a794d141f57c7aea7b0e20, + 0x1c57c847fdb709bfd38776164af9aae7175005861f6cce68e7179dc8eb8d59da, + 0x97bd4c74c9ef8617f364e87d90a2e4f461c57f2e7b42dc48b245973a25f8198, + 0x9399dcf5fdabe6afe6c02a3fa831bf0a4f92cce46654d7aeb4aab80067863e6, + 0xa11daa6724ecf2f75d8e368d31ed437dff1bba0acd32ba12288d4428ab66d9, + 0x95ca5b00386b675738ee39827f9ae5a43ce09cd2b7a708c526c9d478f650906, + 0x1161eb2d96d8f5e199a01fb1712c5f4b29ebc97d5de98e644474aaa34391f75f, + 0x27ca09bcc614752905359dc489829b9ca0755de8b9efc1ccc6d83477db1bd60a, + 0x2f2ddd101005b0d76d47f4440b2de8d982ffcb26416bd7acd5b1218327097968, + 0x226bb0d31a8e961ff7925de0e07d33ae63c3e806ff19f375e8e96b150ac2eb9c, + 0x1e50f8ce5e8e48a47693351bc4c95fffc274e75aad2fe7e6d607d8061e08da17, + 0x17e98bdc10062dcab33e194593186fd29f06a5a3cd95a6bf373e314047ea75da, + 0x7e6d38b28db0d587b13ac7ca4056fe27cc6e51467253b9e1b9318b181f61ad9, + 0x7a06dd6230750e3f59b57edf6b3fdd71a4a1485e2b9765bc85402de6c539e15, + 0x224bcbf9e7ad9eb63bdaa8e679c0ba67c594e4c8bebd2e06f1d736c4fa5b9c19, + 0x14e43b10484fd331ef027a94de953dd133c14e823656e2a3f7580376d90b778a, + 0x21c2c69e30546f53363e24e6032202627228f2d32c61924ff4f64b7b3e93a8c8, + 0x3fe37796dedfc13fa0160d2da3998890a3f20e8c3522c4fa717e10796f40715, + 0x2bd5b2e11cda485bef53bb4c2c654c39bebb5814b06134902858ba1c79fe0883, + 0x1db6d06d30d62c08ffc1c2249d3297734c08dc141e9ad9abcc251bf4605b3b63, + 0x350d5175824d117a97a0c758ffad0d3d23df500f097a25f8e061d79dd42aeed, + 0xf46d145eace6b1dc1bb7f218431ae9af0c9278ac2912ca102627a656be2fad3, + 0xfbd2953a1cdb40ce84ca589f711a8aae5e75c745c5ca4826f65dd2bb50813d2, + 0x2e6fee6ff51b2abf66db3ce9c23271ba35caed4e6893762161bf7283e0c27982, + 0xeb4c21214c0ce434010f1fe4733a327820e1afe53ba7233312df51615d5897, + 0x149a01e3644a9aea475d77e728a2e9826f6b935ccb5de9f060c0a05d8904a470, + 0x3051abcbd422db239b04ed4beacd3b4db8bd045b8d4ab36a872454e362f82b22, + 0x138a0119816ee4ac8015badfe5abb7114820f161375b6074205af54887e788e7, + 0x16c8e1464970e0d76c1e3c4073e63fb2e514b25858bf46adef59b1751480f452, + 0x179ae599e009a3f1027b559b07961307ef54673d52e8bf8c4f87ac5f999a9ac2, + 0x13b3518cb4a884686be5ef802fe3c9a0761950f2e5f66a469df47c4980fbdbce, + 0x52a354e6f8a8c482b9ca8fa51e4732763bda214a65fe575ff12c954a433e27b, + 0x30348154b1407f9bb3b3d8fe8decc41c770cce188d64ba7b0218515b3622fe7e, + 0x22493fbdd06dc2accec415de98a9d411e393393e648cdf86ad3efb60373da4dc, + 0x2bd33c38d67da9e28ff22b4ae3b6e0ea68c6c8b275d64408cd7c0bc7f3c20746, + 0x18ca35802730ebd5aabf25fc7cd352283442bbfa6e925e66e8344345932ec3a0, + 0x123a15b31db64480736ee720631ab0088a24167d1460be4dd420f7cd40acf2e5, + 0x1ba31fb49dbfe083d1f4210e344596a9c61e6f4bccbfeddd88f3beb168921b07, + 0x10c73167a97d9141097672c848cf3ee8116d380e6f1301778533933a078f2a27, + 0x12b2f0963b677d68900fbe2500bdfd4b532085e5cafe9db9c2e636a8ab0c98cc, + 0x1feee9a8c818254bec43c0bfea4e01ce2a7e6faa9a4dd01208770a6f0bbe7c35, + 0x2388c6a47ec73b9c198bf0ad3d5922e3598457cbca82d0b1d2cdbcacf56ae36d, + 0x1bd9b76b67a672ec982cdbaeb55e14628a4db0792bc0f52451c475cab0ecf3dd, + 0xb2ee64ddecd3f26acc1c6c44ef1643b8eb6e589d0304fea3b7b7e1e91c2f534, + 0x107f80d883fd761322467565a99dc8786e69ac197fbedb7636432ec5cfcb2678, + 0x19f0a831e164772368d5365a0107d0ae264ba97bd5160bee069f1e2b459babc4, + 0x99ab87e7b852429782bcaff58bd19649ea26b24e493b243c71d411b48e36375, + 0x18db42f8cb42180422587e68173a24cd0dd62f6b17009897541f16263a405746, + 0x2a22132453db2d68d388b700545cde863d652bdbc5f733c692a1863754fc7294, + 0x2e3f81e949bbe1a2e8a06b70e21d433a1036aa684bf39b7e933839973867ea3c, + 0x2c21f85518cc932c232aafbca1e4eccaf6d7375a80b1542828e1aff7ad8d8442, + 0x21c0239127fe8b2965a32cc7ee8d063eb792ff468703c54cdde10092fa9d922d, + 0x201c6b5b791d42b85000a1011ac52b25bad5309ef4f482e26110310001bccb4e, + 0x2db1d234cd755ea9599fe56001866bb4b711ed049227d67ddb35c03bdb8c6df3, + 0x18498b6b4ebea39d429c25e5aab1b5fc97ec880e736331814a3cdf799bfea718, + 0x1e5d12fcc0c680824e0934a64153a1dedd491ec29effb629e35a45d889028343, + 0x1ddc4b9d3159354a45944b963b54081d3584448192659625d3f06fa98181f43a, + 0x11fc72e4994e6b2e99f8b58773a5eb8ab282dd06ef0607051371bada7b80c40a, + 0x21bc7461e5160f2dc86d270fbc2c8f91605a49e5c75ac57c7ae3481bf1f4bb4f, + 0x2d16510a22095aee95dac7335895a70e0ec56a9a9b33201d94b5f7cb6fc626b7, + 0x2fdfb1134a1f54ad7dd904be3991e086e1b8e0c4d5c0eb80420da5c0fe4b0944, + 0x28646d4e0061355d5cd936c08f7e8419701d959482990a46d4cbe164badafb26, + 0x1dbb1b476c0fdd507664a1c03624038c2cf2232c87bea9e711fd32dc9150622, + 0x81dbd4fdc8779da9472fc7c3dc8b35418c3f670643b4ec8e878c256f6cc22a4, + 0x886cdaa0b431c97d8463419ac5651ff457a7c15673fb88916e94fa55f584d31, + 0x2838331687e032e9ba3fff6492c1c547f685ebd7609536770c09dbd7ec3cd2de, + 0x2621bc61696ec99cf22f64501b131655f498c95fed719edc34691e18154354e5, + 0x2549d455daeaa01b7b52782493fe1b0b7c14dfb77087c9151b4ca36f15306ac9, + 0xa4c236eb53846ff3488a5bcf59fe22252f78a20e953516f22c88b4c06e7f4a7, + 0x10c077e94f0d3852b3e3c2b14eecba18c27b52cefd6fb1a1ff6a26ef95e41815, + 0x2eb187c8e8b5d69de44971a4b370ae917ecdd0286b75560c1d3036ecc54b196b, + 0xb395bd209a15083fb3a580abaa376a1fa397c54f91cf8a0c141ec7b4d7c1e97, + 0x2a1aa4e24d835d8a3f9ead7881aa391fa930752f8c9c1a448d53307ff930d8bc, + 0x1a3959bfaa6e5ec9fa45a9939b47676ed773b545d372e5f8403ce000528605ad, + 0x31eea5b773a9e18aa6a29863ff6c51130f4e76974071207bbca7f238e4910e9, + 0x109a8a86778d80cfdf86b4d6bbb1e57e218ab8fd8495f1fe051b576ff2e77c98, + 0x361d334bf2e907948c05b6252bff7903afddc738f2952a0dc893b09fb034ecf, + 0x11f636b7d7ee19603bd7eda90e668b7ecb2399750d002d9cd2978364b632ea0b, + 0x23af2f1d6a7dbe734d6006377fe06a202a5482cdf7cf324bff2c3eef417e8d9e, + 0x20057e0887d089856cd5bcdebb9e75b12474add58e57e3a77a26cb6cc36bb61c, + 0x2657371dbdb26288e4a31975410dd5772003e2255a15e5419f11e97da00aa5e2, + 0x149681e3e7671ece7381c6981fcfb46ec93264cc242f9a6140b3344aa641758d, + 0x4483482a502545fce490d73674becc29dec91db3a6721869a92856252f5ebe3, + 0x1afb1e247f5795105296f8f075ebc831ede8b5128e378bfc374343ee6f93197e, + 0x23140be54f97f6d1cc5ba00847848e4fc973656baa56ab3e1b754cc12a296bbe, + 0xae6ffce46e6c0bc0ce6341f9d308c792436f0a07142988a937db3fd8a333539, + 0x129231c0dfad986f9c0c2f9868b00c22b314e22b24b55a438770b320ef193ea7, + 0x1d62b56618a967c7d128e45a28062fe7f0bce6dc55083b58374ab6806e01573a, + 0x17e3794052d48c4aa936c5e189fde01b8bb4607fd478b67fdbbcad3e8aa9166b, + 0x24af4f43a91c5c51c6b2f3f44eca59bdc79ac86b06ca092cff9fc7d9c4691fb3, + 0x215075ce41bd685be3c97d2bc28bec174421398024a8bbe4d9122008e6e027c1, + 0x10ff29fe3e761d9f78518eb60b2a1daeb394753487490c9f5ef937df3b87699b, + 0x160ff9e43a764ba2280d5ff675a9db049a29e7924f5ba24583b1d6d90caa0324, + 0xad301157c28a1200715676e5ab5b2469fa39559c1a847f7787abf487d828055, + 0x3409e3a83bbf52d16fef10fbbeebbb40ba299ef770e3640651a48602f13d108, + 0xb1232364d87cdbc709442909811d0a0241d0d8b7933b59471799d6b30a58da4, + 0x195dcc72dd9f2629db85af3e0c9a3ff52fed868038cb27103d9f30c8c70e1fbc, + 0x192d2d9e31fb65b409ab273e7e2b050c1bff596ae56ca4687ff8e86ba8bc27af, + 0x2ad9eedb67e8bf182bb967045b906afce866e00258a320380a709b818521bf3b, + 0x2ddfe92956df2e751715ede80573cfa5308b46be5fd0f77def8a519f113a4107, + 0x1ef0dac6020d7b376e6f0fa82187820a0a4d8be7a8effda342f7f8806565f2a8, + 0xe4d6efe23c1496d8275f8a4dd536bf988a2c8ba2d2beba328f28606a4ca0f91, + 0x185b30ee2d3a166f2f59a03c7ee9f206411f74f777873b92045b6c128ff84202, + 0x19ea7d6275a6dd167757942770dac2861057e16a988d2e93e4f61849d8427aa4, + 0x23c3b4f5e49e16ae69e639b956d48ad6ba696f243a669aab13ab2c2855e1187f, + 0x29037d64b549d1c9ec4524ebbedb8069cb23218bef3cda811134b36d3551ddc7, + 0x2ea8637b89b798a2f731d98f2ab89ae9814f18deaa7effcc9633fe829a9d109b, + 0x2bb4bf36b15be77b7374a026352644b8e70b1ac9516eb87eba7672ecd03f1202, + 0x1006f07533b6e5f33d613b89b858bb6616c18f8478f225af2f4e3d726780cea8, + 0x1749f416df7b4f43257d9b8555e540bb0ad0d7c8ab0a4ae1296021da0d90ec59, + 0x26c86b58437b04557a96cc74b511dbda00e9c4c57bb86c15d49bce318da8b592, + 0x2679dc5e56ae1f6a54d38287c7ed606d0d9505a5cad5a0699b09041571c4560a, + 0x133eab2d7a718f3f741eb10e973bc5e29a021e83f6442418a832b091bc2d6136, + 0x1684a4b71cd72ec3cbee67151c638d5588e3705820c468c289c52e73d69a8fa0, + 0x17cb936bca97a37f63732c01e6c40f6807360cdb73f62d792eb910e034b4041f, + 0x1bf4b473f0c77aa5ac94a46972216b339d99c933a8f5034044b4b535adc388a7, + 0x2c6b76a42a2fd9fc8105378de5176d60c2f8129cdcca89fa0b00f3edc64e079b, + 0x2893d0cb426295edce9b5506b56a2b867eaf48b08c5242888ef79766f8d9aed2, + 0x192d74bf58f3dfad901612983c6bcc753902e2241a371f9880e351150e68292b, + 0x1bf69bb66db73ef6a0e04689e9698896ebed84d97966838113f5df5f5710736d, + 0x1f8201a8020ba29e8521a1a0cd3bff50603daafaf084f0373f2edb68fee7308d, + 0x2fc51d7afa548b449f40ee7c48386655db021f9e34e143c51b1382399bbf6e4c, + 0x1f4e909114c65d62e1a1e466d4968ba9f6fa612578d474e25cc1ea13888f360f, + 0x2957f8aa51d126b9961950fd72e1c7224668a359da4e5c0bf761d49913d147ec, + 0x1a80f9577c8384aeb8889b63361078284ef552c62d2cc0880667e85f01d0333e, + 0x1de416e08ad386d654b37fd2b61eadb5b555e0fec1b7b09d8435bee97e57b0e1, + 0x1ba2ce3d6e352d0643b2d3c5c7c023b6d1777f246278cfe6e1654e9e5413b535 + ], + [ + [ + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x2d8c70035731ad9efba92821a88119f6b8183a362be641729a93d6a327c03809, + 0x7b620c8a78e09e49ce547aa783aa78f3e4594c49ab3dd6f602bc6c0351d823f, + 0x231996b592528575567d39d00645a83b13929093bbfa00d6a661e4a690351d0f, + 0x4e47a72e49b9c5aa3f69f6af22fa0ab640c93fc524dd3c508486d66f079852a, + 0xa8cb4b2bf3f0c5da671e48f83e5c1b3018f0d31200a6f19fd5195db22eef7f4, + 0x18bbb002b46f2e5fec2b120faf87822ca8e77ace94e03aab5c16c4b931739dc8, + 0x2bfae1b054ef2e924d75a8a01283da29103c57bad129ec8396ce274ba4524df, + 0x6d101b19477d1627b9542581bf0cdfab38b05cdefdcb81965c5be00d780f192, + 0x18af61f6184ff85f104c2bef179b3ec5a5d242dfbebe8e27a2918f620e8a5be8, + 0x11e3a7c2d5f74371beb188c6e3d7a14b33128af8ee3287546d12d7777cef70cb, + 0x2de5d6a7a27343dd0422ac71b8d409b43ccb0b672e978f8fdfd214f4d7866404, + 0x227cb43b9818924f2a2588964a0ad7ddfa3df62284b4b3b10199a501ed970622 + ], + [ + 0x2b2ff5f27531b6f3d6a85d75e3e08f3a2f0dac3680a6c26d55ecbf803ca80569, + 0x9ef3492ad19dd1d0bfbeb191330a880ee7933c9d3b36bb5fa02283bae5d605e, + 0x27d6bd18703d7ca92aa24076d3187b6c0028d0b6213d9e5d2c66115237a19051, + 0x193f32a3f839f76049c9cbf2414590698a2118e83658327c4338aa3648d8f7d7, + 0x235d0e71a350f1f23d9bb5182ac44ec9e4615e77801e5aadcab8336aadb1712c, + 0x1df5c9ef694afe61bc253ae908a8f6af0a08cdb9e78a9f322c22388322f16c2a, + 0x1db2021eca3a3624a7d45bb16cf4a44e2af4fae0dc280030e7ebe55394f69d8c, + 0x1a46a26691841c26109a32ae07eb584a6b8af657273cdc4d8a112dea0bcc85cf, + 0xcae80cc05aedb66d6e649b057dbc5ae9759da5d7b43d5e25a400e1f92e9d1aa, + 0x195057af1319e24df1b905c6e2eb2957003cfc34b001c0e54b9dcf2ea5df6be9, + 0x2d4d35acd9f28a3e6bfd601472948293c1e4f084c714ddb1a075f2eae9ce21b3, + 0x25eb2ed84c520aba164e33f0353b5131886c0fbd18e55695541512dec563a0c, + 0x16c7c5c6161eda32c65bb347655acaa80bcc98bfc023f4ab12f5b2a899f37e3d + ], + [ + 0xb658849ce620bbeeff233b7d12258015ea9f87a5390f5614981eb6e4cb4a5fa, + 0x1458de516a534190c5550c6a1bed3af535c38b242eb9291373096ec60e39c1f1, + 0x2969eb5016f24b31accf173ca204668dc2229845bf6446cea007c113349bd4d7, + 0xa5da659b6fcb1a4273e1b7e3b544d2cbd362cac497afd004b8ea920fdb04bff, + 0x1219740c424743dbbf896996f0ee7a4076ba960a57e8d7679b828479218570d1, + 0x134431128e5ffc0ab60136c5d851a11dcdd63cdcf17ad64fd77517701de675f8, + 0x97c6133aea8fe48f3a5fc416bdf5e46d05de0723bc49e53b9fb5e83d350c295, + 0x107da0784dfb314d82859be44d37b4d2b6345c174b91651c65c98449682a5204, + 0x12256b3b99d31d8a372986f95d66cc139dd23e935487da26b3e249ea7cbf91ae, + 0x1d952ebffcbedd26036c54a1e8a2828fe320adf07a286e7f2c211b47f6c3ee86, + 0x26309b52cb55f6ea5a9030b01378f65d2e6b7a9619926d9b1b1e21cba01fa7e1, + 0xa12525f0781322371fd70b0928cce6e2eaaa67b8970dcdf319df25e8019a6de, + 0x27e37c68a01530f092cd37c4a26dece2737868dc2c3519435e1f2cb88f07b62c + ], + [ + 0x118132fbc1cd83f95167cb4473d54c6bd2c417e2782e5efea16e72d47b48b70f, + 0x136ef2515955ff6619498fac59424816189f896ac0ed69b59854d105df47c4b4, + 0x29c67bce04bfd020f4ff7eacab6cbde034b22fb86334675a361f059e50395311, + 0x2a832ceed3837e742196e09491fe23e3f6e51126eab9acec96e71953102ef24, + 0x2b501f1003e27aa809dc9e5cd84976a3b8c169c1e9c63977d7823f80d3f823be, + 0x3ea4e2bffe02da5977ced1f1a6e852e921abe2e015f35b36ce4bd0246c2cd89, + 0x150ef9e932a74b8debf670080641339b12684ff5a303b2fb7c1d8d56f56ab61f, + 0x2b45b3be2674fd820516acd6cc6183c4fae0f7edfa9afcd02dfeeccd02bfed46, + 0x238965d658967afa2bce50ff18cbbe535327c65b0b76e50da30739ded25eb492, + 0x370b757ac6cdd46610eec0c22d43a543d5e0482577bbdc14e71090307b5f69a, + 0x2aa84c1ef9e848a64f748b80e279ddcff871e9c4c3e2fafaaf79159b0b4e4018, + 0x1bbf43ddb5a0b0d2845923b1ce128292359cbb313c5876fbb52f5e6b1fcb7031, + 0x19dd1c6d45298248ad499531f33ce002505458d76178eca26298e39a62fb9501 + ], + [ + 0xb5944768d61c1b3562a5749f4f06c4dd085bb562b838d7e2ef14a21fdf524c0, + 0x18cbfde0cd21c183797a2f089594a81cd828f3b0742371ed02eb83fb0064dd43, + 0x124474b08829d9b717c50884bc895cd3f81d519859d21235d7a74450d0a9427b, + 0x98bb2c4c6334dfea474d04cb2e9761861f6b18a8058a52b619d6227a26228a8, + 0xf34db93ea8d2ad7d1eff86db5820cc7ada47bdcd8c82d01821f5c21a3ea2325, + 0x6e03ca1146705522bb5e9dc73560eeee6b9b4bf51d48f953fbd1f006d758a75, + 0x1237f44f036b2da0067a94947334e3afa2ac4cf1009896766f5b191cde284972, + 0x2082e9103cc45245924289111527312860f6e7ee94578f0118f4a920d0f8d525, + 0x23a6e143284e8f238c4b632ad78ace5b0dcd94a897cb05d1e297b4880e7433b2, + 0x22e076a3aa6ebfe996ba068bf5bffb17fa724338cd67f67ea25330195c628172, + 0x2fe31b0df04f276a525b619acc4a5ba3eb58d8c321c62390febab05ecdbc798d, + 0x23e8c3606aee818d2afa8c4465d5ecb9c45bde78dd819c0f35a620593c1f42e6, + 0x215f5563464e2df6a8daa8c34476a465e4ee9fa0ad01fc4399b649b2e07d1679 + ], + [ + 0x2b04d6ffbaf7144012d92c5c6212803c0b5bcc0d7b1950b889d1fa6f3e56445a, + 0x22757da9e822345297bd060a3f71bb1e70ce977049c393235035677e84357314, + 0x2c7e28f59fe8a8a3bb2fa2b2b1e114ce283fe22a978a3df9f62a171cb1d65e4e, + 0x101749f9dd2605191c1963f25694ae267f6b44bfe2d1af34fefcb65e958784b0, + 0x4d02ab05826fa50bcc5f9af9e396477e68542d076b683ee61b85869d4535893, + 0x14c499ee51925b231da17ee7b55a75f96f462e431675ee36c7be4e9b069e260, + 0x2d9ea99d2d237328266d59dd7e018bbd6bcc7941d9ff5f07a17baf0099f614d2, + 0x303a9e22855d95d07e8172f3a0536d4b95142f962b006a8ab09e7bb6335e8487, + 0x24e13a38f04d5e0fc0b6b6e0f782a6a523a8b3b0127224b8e23751b9cb9f8960, + 0x126851f3eadc0183288a750153910a41e074b3544f0610a51273ad3698be0cb9, + 0x27c1b406bd19ed13d533550b8b621186b1fd47f671e6604680317e6638b091e1, + 0x158880f5adb96dd1398128b9ff339f3d827da6463891cca129c012c06b16b321, + 0xf36d166e99139b9bfc1ac3270a3d98c4afa81bf97436076f57383da50436a5 + ], + [ + 0x29be2a42834ae32de3320fb0ee46b4c102a3d1ae44c5dce152fdeab5450c9c44, + 0x1622805125ddf344c18e351d11e82291618b975822ad0c903efbeada5a51d44f, + 0x165c0b978b4bb646a9ff225ac4900521292be54c879882d3f11eaa3103341487, + 0xc7b5e09343db5c63c110d3175d01bb498290d971b1e6dc0e9a0e9e7158356b1, + 0x2bcc82e75391be4ea9cd0f8a505f9e4f684778fc7a9b1bceb7868bb299cd2072, + 0x611ecd1f379a0062b05c4aedb100bc015244c6a88f1631a456cc2acca8930cc, + 0x477f951e19f531b8434ad755b6783d61b679efbb87fd956e394db9c434e2352, + 0x2963514313f046f844f950ffea80f5e5b424b707f16599662e5a2e3668cbe5fb, + 0x9010d73677620aae1b0fa8023ff1c812313ae9c3bf43066ea60bc1ab477a7f8, + 0x361f4082b75a6ebd23f9a6e7309d8c4e7520159da23441edd631a6ac14c20cd, + 0xcebcf30975b37267aedf521ee2bc753c3424dc4b6edf3984fb02ae1ead44daf, + 0x23a1ac07351946a974c8841e92092a4ffc6aefc7fa988e3c1f7e7c87e1512a90, + 0x1edd7c7deaf249e0fd3f5768aa92e9dad64118b491bcce12340c46f210b07ced + ], + [ + 0x1946fe9de0a943d5a716eac08561cd91f9031fec82da9ab72883c7b218b11eb7, + 0x29765d8cf77619a580658d127fb6faa44d6c70a0f4d65dbaa960754b4195d9fe, + 0x2066134bb299d9e359cb82a8380feb63b60e4b9859d9b9872edaf9152f92d4f, + 0x116a313d00cf99dc18e21f93a5bb198018bbea4b7cdced3e4d210971dd0a681b, + 0xfe29b5bead54c5bbf426bb12844a2920884ac447906101cea9888986a030b11, + 0x22af37c0e4a88deae9f7fad83819910735cb4b49311e0aae11cb7534d0bcee6e, + 0x1d8b8ba772c4cda72e8ef9b19c424d55d57251b247c632bea255271afcfc70b6, + 0x4b7f8d1d5ec8bf689adf12d656b94e15b0b229c1638c9c4757faf0d18fa6433, + 0xa41e5a4421defd5ed7acfd48401395a409a67c3edf4c168ce3368ed944212d7, + 0x1abe8badb2d12353b9bb98152086a9421b7cee17761730e25ac284d6b1ed7b37, + 0x291c0da731c016c0d6c4c75387030a962bf7a2eb35e15aac02fadf530278a3d1, + 0x34c460fff28862ef7a509a1750a26ed1e5960fcb58c4f48c7d267c77e58dd66, + 0x8e1741a97f6348ed6d68f4b7bc6ec8b2dbf03f426769cc779ceee4ba1beb03f + ], + [ + 0x1af3ca6240a55aba55df8e49835b92fa17e39ad5701ef70f8144109f894bf1d0, + 0x2bb0b6b08fc1bd11070edc42f23e807b82e8b88ef70355dfc74e096a7ff381cb, + 0x9372ed18ba1a774eafe1bff6deec4bc0814b0899c6196fa15a7acd15ecc5ca2, + 0x404c0fa1bd1f7e059054cbb87f6b5c69d11457e59f90419ce4bd10bb8a803df, + 0x1bb2091870a4fac03682fe5b1e2eb56b14ad6e48f4676fe41454bfeeb0ffd4d9, + 0x299ef95aed8c75494db82e8679fbc6d5a3d2e29aecdcf6979a9b272a607dd5df, + 0x206aa2f36e32b2b06d6be48ad493d354ca7468753f526e6bd82549fc36cd4109, + 0x259547168b64b2a228941a542f394a2699c081c149463dc2c3d21fd8b2e4f31c, + 0x2fc7d17f3a9afc1de289ad0f94126aeec834498120629cc87c4586c627780075, + 0x15a7e64a5a46f5973e4e82a263ef905ed64f182b2041baa00a1359e7e9c5eda7, + 0x1216f05607e032e49038ac1458100e89ac8519a5a3cee4545b08850d8bf160e0, + 0x223db18f31c85e98e1dd7b7245dddda0ff8e319bd7d1a67fdbc7eef56d667818, + 0x2f4aa8641ea4135031f4d97a7a2f679a8cbca562ba6aa54eae7d32ff7d04dbd2 + ], + [ + 0x81f58a91a4e0d100e0369fdd81a190035342fd0677ee1bf5215e47f8e58c2c3, + 0x4951e747b7ae6b99d9250108c5d2b70181a93ff1d4bf723781e1b938029827c, + 0x1e3a130e8caff9b5e563e8aaf84b2fc73668e351cfd28cf66f5012de61345b58, + 0xc1c216af33054c497ef04381f58582298b54335f632bd62add29e08067a59d9, + 0xf54c9c522a5c74e0d4e0c63611a7502657575b7a963c0e786d2a761c4e845bb, + 0x103cc8384be1be1087b9bb47c0eb6049f85e0413f7b408f1dc2fa1e6fc4af91b, + 0x28da9309acca103ecf19df72a722134d530bae6c660db3c364d0ebb200c2aeaa, + 0x27919dd2f9d3dc9fcbda1a23b95cf23e3630e6fd5210faca6acf4629b88e5ff1, + 0x1f86e3e9d147ed604c71e1fb6ef8459cfc40001bb4fc5ccc2661669b155abeba, + 0xe154ebd50db3c2864dbe1ed72b0816210851b86c353692d1744cb3372bfa72d, + 0x19ae65945a1dbed3965f2de3a39ff2d54ab1dee0f333b88fb49edb3fc9ac7899, + 0x99b97c878ce35c957d01b43dab07f8003e2c379b41ca61a6e56a9204fb16bc, + 0x21a0a43c88ce26effbf8b9ad668056b5b0362e5009f3d80033db473228fb7fc8 + ], + [ + 0x22a852af90680a8ca9688b71ed27c157d02b406bd6c7fd8121d7c7793ad2305d, + 0x17780b9469e81ca70c7cbb4347e7fb40c63ef68f3dde51d04cb47b3b83fc299e, + 0x255543a314afc5a2991413228c75eae398b90576b23b6cd86128665cc3bd9478, + 0x11cb20544f43437a688a7dcb573a7da4f8c7b4437349eedf3fce432a6f3c1653, + 0x160f5ac0b2481f8019e95e0b26445ba64dc03a4be8a15461496247e6ac29002a, + 0x206cf4290ac984434fa774bb0f8901a233905632b793c80b1d59966e96a73832, + 0x1b9435855d6cc4339240e9fa3819c2ff420980d6cf14721b75e4cb1fe57e118, + 0x2b9237e5941e1657efa507b892c3b8dd57fc8d52876ecb599dd5e1052b6b1f2f, + 0x182d8f91ee2a9a26215b35f3c0eecf8ec5cc360124cf6b903e70ca83126975dc, + 0x25528d5d31dbd77cfa6e7b1847f8e84c81c1ed5bae2a51c9e403cc754c54bb55, + 0x2f996ae620d00a3d4e55ef7a6ce0b681388f1b7ff3875b725aea6eb9039d8b25, + 0x2c2b1e7c70fec2f58ca01bef5ac37cbb9471ae7914bf08df7e47dd8e3bc3ce93, + 0x31b369d011f219e4a8fb21df9352878d93ff8035bcda834c3dcc41c3c2df85d + ], + [ + 0xb27ba82a0ffb98368981736ae927a227828985c00c3e5df8c1276b1001089a1, + 0x1913d51d9c71d042bfbf649d9e6e6ea5fdd82b4fd3173ff2fe02b85582528912, + 0x76547449fa03845f185e61578a5a8f2683a19733fc04c73ac6a0b89bebb8453, + 0x186f160ae866e10c4be0ea7d204cd64e57337c60c40b34c3a371d753f2ff001a, + 0x2f3d6b8e2361166089501b9147e84ab6b09792ac17a5f080d75b3e320affc86c, + 0xdd85dcf08fd38d22f316d91d812cb2a884308775afa9f667c6ca80954397c86, + 0x238832e643158e96689b5803b0b77601b59bdfb4926113a3455f1ff4df6e2b46, + 0x202e38e669883619ecbc6a6a45368b9b9a3e9ab67efef50f896dfe48b78d3dac, + 0x67d2b612d75f4f974312d04ae0fef43a35b60ef054c0f475302c55fc10bdab0, + 0x21f0c6b896fb14220d811441629c78f8e8e27746026220e331cceb89a0ee89a3, + 0x2c825ee561c4ab6a22331177999c89806fbc34518387e807c20c359739ba9eb6, + 0x4625f2258edf0262ba0647cae426a486fc801dc0b59d20ec0f4d0af8cbd23ce, + 0x20a72083579059cb659952d3f2a01ed90d21002275b5ea11f209c763baa8457 + ], + [ + 0x4b46526207edc70a0d23c8438bc49a365635552dee240661a2cdeef966f20f6, + 0x2a9e342a56c8b6466d3fe533b89f1ab441b62dff3153d3ae6500c2c3be6365e8, + 0x2f98bf081e0eb78f8025c03ee9c199f2e838c51e5a0aefd333e9f7cfb38f534b, + 0x1e1d5920edcfe9d6b2d0ddb2f6f741afb06590340fc07b182ea7c3ebbd933931, + 0x1b59bb60e986194987fcea070498bcc7c93dd561ce8af5fade754ceac07b1705, + 0x24ce0acb522da527d3eab72865cf073d954babbed3cd1706aa69d767e9afe7cd, + 0xb43b8facc43cfc067b5513abcce846504b9395cdc14df96861a528a52ae2ec5, + 0x262758fb3e076936995ff3140ef7d1b0a1e0fe4240a50747e2c3c120d977f3ac, + 0xeab3f26417e6b53c532072de92d4aa78ccdf1da91660a461abb0f9fd7bdcd7f, + 0x20addeb2afd20e752a39d2f21ebddc2772773b062922dc8dd3ba068836dba464, + 0x754947436c3cded29a60c9e898237c2183a49db7e70e7eb73aefb4b5c693246, + 0x239ca61a6ef7e501810aa89ab4996dbea8fbd47fd2f7a2c96a818e93a3c38c89, + 0x19f11771049b5be81b43ca81e3611f4108a4b9dc30cd122441f74319c3adcde9 + ] + ], + [ +[ +0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, +0x5da987f17a176320a821339189d24ff783be07f5a6adba84ea72fa0d7faa9a1, +0x142b410fdf81d2489b47702708422b35a9c6c3580144e7f3e94b971bf079585e, +0xb98437a312150d8171b81b1891f3cfc75b9d14473319a77c7043d8d2ec320bf, +0x2f88cac82b777c1c7b751129e0bc1d038481129c546e80007a6a6b73c52c7f4, +0x2b37af1db29d45113ebe8892bd41ba43e82d045eeefca95390f4a7f816639416, +0xe0fcfee5bd6119ea196992bc58dfcffba632cb20e07d9bd7f1f4c0738edf767, +0x1f801f49cc72b3cb1ad6d83474b3e98cc9ab427ac9d1807de151ff591c2d98f9, +0x5aba81d049688ec509fbf12aa240297e0a4cfbeb91c87e4d1d72bac8acb33ae, +0x1efaed0a28bad9712571c0f7200ed332ec1342c08a9270774ed84817ffe8943d, +0x2765f7a0abe74654c9182787a7d252f964c3e38c946a1f459579923b061b206f, +0x540383aee2f7779742ca518ed4d4d752980f2b5dff48339c128acb79daf88e1, +0x198d160f1f80e78fd1e93c5244d636d72185966e93e62dcd0fa8cad1b772f781 +], +[ +0x2b2ff5f27531b6f3d6a85d75e3e08f3a2f0dac3680a6c26d55ecbf803ca80569, +0x20dcb39566362206d4b38ed042277d966f03092b6910f3a05e5b1c3071f4a070, +0x2e3c5d5b931ba49c99edded32e4f404eebef7eb08ca9668d82c912cb5d428585, +0x11c900f3b1c7732081074d0a58091de7f826a4f106a930899d3798c6b02d7735, +0x2cfc4c4f3575a5f8bf5f2ef6b518a47fac9fe853558d584ede340b5e32eff61c, +0x7ba6d2ece419d75b37c87da9b00fd277259b4232542eaac3d6c7d85c8677a21, +0x2ad1869717ab4c539dac1f950998c537d101504b008b46b47d239eed0702f8a9, +0x6b21b6e86693de4b43f26771aa347307be78fc9585a91fc28b6f0f802850576, +0x1e54ea10d6b7cf0607b5224797eafc3b651b492aa74c92ae9a70a692a1965e2, +0x23b47244bbd00be19b1c8046145626bac795b4ba22beb692810bdff4794ae97, +0x16ba1b0ff54dacc9d88f85fa6bb69988a0633a3998eff403bd55f352a195192c, +0x2fca163547569280e953a94133047f3f9281b220b0c6334645e432143edbaa4, +0x262cc29dc7439873e862e94b1948eaef1068da52d8bd493fe44a9e48b47b88de +], +[ +0xb658849ce620bbeeff233b7d12258015ea9f87a5390f5614981eb6e4cb4a5fa, +0x2816fae6fcd39053c09df75bc62f75875e635472e790e295aaee0c8158961174, +0x5849562006496b3a32966a1a53d29f1c667a80e69e44993133184456ecc57a3, +0x23bdb40dc2a5072c7d0cde89e1baca83c53b963f4129487c1a68ffa36cfc46db, +0x2283767ef21ee3be90dac5aa35e2d5c39f7bdae014bd63b63039d19b042fb575, +0x1a2dc35b3c29c763895e67b7ca3ebb9c34484431cd2d1080544cee9d03194c13, +0xdf23b54c9ee2fd50b58ae1043cc7e0dc3a11f183ee0f815fe9a97caf186033, +0x160a65dbda0b6f118906dc50e0d5a8e64ce7765f4327700e11e753d7386e7392, +0x24b39cab2a81551d5d529ed57986b8ecded02a7650eedf67925eb9efad60dc20, +0x226f8e8bfff7dcdcd1980eed6f88a2566cd997d4f7bec484ef25bf8ee86eba7b, +0x2aaa2c1202b74f2dab3f58dbdc95eafd2ea49d5e3abb47f3b33cbd4ea13474c6, +0xfaa06fba9421c021c6133baf90169f65dcb46cc47ee532989d5ced54155f34f, +0x17af1f8b71c3656ec7d3262406399866d91470e4b912040132b923f891e63720 +], +[ +0x118132fbc1cd83f95167cb4473d54c6bd2c417e2782e5efea16e72d47b48b70f, +0x1df6a4c43bc5c69763183d36c26b6b37fbd5e4252de4b5c3c0da6b81d2bc00e9, +0x2fcd5953b4af9a49fd90b23229198d09fc8fc8ceafdbb53599b133d01023ef76, +0x24c66b7856c9a5d78819772b35eef0de88ae882c19af36039f785a48a75f450b, +0x1692394c144aece305a7f02749a63a355ed6fe024be532af2152a0d53d590a30, +0x2e0f2af806c4c37a9cee0b9d31be62616a7dc6eba5e51ed9854c1be1d9ebb9ed, +0xfda8fed741c4382c69bc3f63c48c052ef784b8f67ad573451a418f2f6401127, +0x1734a0338c0a652d147ea6c26feaa378580ac91d0c8801b3b06a4f50b580d01, +0x239102aa73485d2a291639612b53c10c8a729f09dbf45984e80688332199990d, +0x15c8103fc31eaee1fdcceaf57ff198cea6eeba5237969b036135084cd15e1b57, +0x1ce8ba9e5353bc50ec8a7cada1fb238a643d6d1c03449a5ad1b6826807821747, +0x13cc546736c859756b596bacedfd88344e4cfe16abcd44dfabf1234df19fb7e0, +0x1dcecb2dc57bd3cb8ed9aeae4fbae4f40e7ffc8dedb72e34c84a9318d9863678 +], +[ +0xb5944768d61c1b3562a5749f4f06c4dd085bb562b838d7e2ef14a21fdf524c0, +0x251e1806f1951c2a33eb6ae39afdf9be6b971da924ae9920246d98bc435d9c59, +0x2995212cf7dab0d9fe609ab9e441218c5181d91e3e2f6c5b6a07800c8698fede, +0x23f10d62357467c7e71eaccb73ec7cd5c44d69abfb91849559009504f81aa57f, +0xd435e4564d33704bb176ee01b59499df851abc0dd5bbd64b3ebdf9635ca39a5, +0xffb4165b1b9e112cd77c00ea81f751e9a2d46e3071e5bd3007fc3a987e842e, +0xc55394f0fbacf892378bbfcf44b8e9475af7e5d7e2373b65c205da9b1b8188d, +0x1563ed24f45a7e60b65a0379df8dc871aaab1b5cbdb24f9f675daeb6fa138423, +0x270dd42f73034ebbfbce9182a6e41fb80cdaa78c06605db3c342c0edcc22e577, +0x11293baf366c075e3cf66c9f14a4899e1d9807460f30af948e44c06d43d37653, +0xdbe92f1d5f635e182354a066756bc119c14060543e78a467507983a74f9707a, +0x22b8d93d76a89bc36f0b5d6a1ec3c6053510622713e2b833499ba773dcc0c217, +0x23b478d2e4e21e478ea7c859da3dfa7229f6a2fa20a2ef1f406d9fb0a7f62f28 +], +[ +0x2b04d6ffbaf7144012d92c5c6212803c0b5bcc0d7b1950b889d1fa6f3e56445a, +0xfdaef081ffa41b2a3c6f8f4c23a5980f85b3301bfc3c342c938199cf71aeb64, +0x33a135f38b760028fbd4b2270791912b0e3008c2007a89b30621086f994879d, +0x2e1eb1ea7a1684486cfcfcffff8c926be2670f226bd883d11591addbea75adda, +0x28bf473bec9d8842b84cdf474a435da4108204b09ca3512d6ef73c19d0be40b3, +0x2edb397ae478291b9f48edd50660fbc1b5d7d906947fdddc255ba787d02b0366, +0xfa157820a600d4a78390b8beac81aaf6e8d1607d7f4eab0afa5d7ee6abc605b, +0x283fa69d06b072eb8b27c7c655b71caec057124aa1669240971c1d04fa881c3a, +0xeaf5ba40262c5feb646c4f32ebe7cd2a1ae38a83c48a04e0c1d452730d63058, +0x2306577578a3acb6a7c070ef0649b6eb67c58224662895d470542fff984f5570, +0x2f204614994166d0a9fabf6bf5db5fc3daf0bc16645f0f202989de9df97c1161, +0x2a93e968eafe2ef56b6e5ef823e29d96b551221e994f08806f148c8d318e7920, +0x2f4f684d1f698b3aef34a939ddab2b80696f2246a13250f8978d597a6a20e202 +], +[ +0x29be2a42834ae32de3320fb0ee46b4c102a3d1ae44c5dce152fdeab5450c9c44, +0x2ec317d402fd363380a63c205dd966e0a9fdadd78b8b9485273b6902b17ed49, +0x1ac21ee4c3af5f8d60fb78d0c764adcfe0c20463b3d0abcd3b602409f2770743, +0x882e85d15875eca350c4e7c4e59a820e47a8381321dc5c7f8f78aa3e1aa68c5, +0x290075bb9d48ea0db89e805f26952bcdb6f96b1507580b45cf56e18c21871cb6, +0xdc29c413aa32c2199a2de5e9605e1129b1e681163b80f82cf846ec5f54377fd, +0x2dced935f82c932e7a2a837e2816cac70bf50da3aadafb7f8136bf973b0d3987, +0x104de5f8e59f98489ffa42926a8aa9701c422e4f13abe90507106f2a5a60f0eb, +0x23b7b05c996c963eaec7c5817eae6d0bfc78c01d9c5da84ef4acde5204c4997d, +0x177a7ae9bc58e64a1b3baa1975c6824cc81d32302740709b0c6fac0ed9fc1958, +0x1552bf00f696b1ec39debdba504f79ea16c9ac75458588eb8a879908c80c22c7, +0xbc4a8170c368a03c40fdb65123bcaacdec1f9ab057747d5a2562d28f4785ccf, +0x2593132f444b3731469755f9a76b92bb29f2e89e264ceb1e2881a4aeeec2751e +], +[ +0x1946fe9de0a943d5a716eac08561cd91f9031fec82da9ab72883c7b218b11eb7, +0xb5cfc2a2895a6f9f5ce97bf05bcd5fac012d6737d93be00df14f91d0e6e8d44, +0x1176eb406c82709b00e6c8aeb7437aee20d0e14b34c91b6d4759d425cea472f1, +0x151f15179f562e6fb43c853c9030c7d95da9bbcc9350b40862350b4339f74320, +0x1d83dbd5511b6cd9e553e82ebce5a91dd9f423bc9e311a211d6509e37e3c8283, +0x62edb4cec259e007c26a95be576fc925088cd487260bcb67fe88dbba993160a, +0xa390e27ae606a3530759c877186ef25fda97764052ade30cb5533f0ae878927, +0x17a961c4c7f021105e4facce2011ba1f6f7e4c18c6522a8879b371bc53eec16f, +0xfba90a3180e89f49b981d7f2d369f14b354f586ca695d5be51d562bb24f01f, +0x1b17b06f9727550affa91416dca65e6940ae6266c426f46a5b2a72201c9bf48f, +0x24aab8dff690a59f7a16863d2987edff9d240c46885a5fe39ce1400c1c6638e5, +0x48ed2132edee472d9b39de6eddaa2ecd7c1259af7c64ea368e66882d3cecb15, +0x3ee389275c64f648e0ef79dd7ef8d7c4034d8b0ff91a834705ad383278f1f7d +], +[ +0x1af3ca6240a55aba55df8e49835b92fa17e39ad5701ef70f8144109f894bf1d0, +0x2566dbba85110cc708700743aaa5c7061b174365a8efb5938b4bcd82ea79929a, +0x205197098d6814100ccf6c908eb3792b0294290afe47949c85b0cc054a60bed7, +0xcced1f9a364f77fe44b306c4539575f8b1ca45758c4fcbfee234e8dcd973ba6, +0x305e20ea1b93c0fc73307f4825e80471da211c98323f23b727919b63e42501e2, +0x1e473b357377aeb6c9eeca4adacf0ebbe72df720bb533055f056eb9f2c13d536, +0x56d703af2f1982a482cc560c2f4f2da32ef0356c73ce35f7b667b8f825b2451, +0x46beadefd1c7353469794eb81f574d38910f72d81431159d4c532eecc18d67, +0x2ad6ce3498864f0ae788665262f8b99756997eccbe50d70338ecd68dd1e92522, +0x8b39764e398e29ffe39a83c045a1218036653fe8071ecd3779cc6e79e643fe7, +0xffb07a9dd49578818cf9781beaf8940764dcd2f07aab4123f4c9f030513f622, +0x2e7b46afef5262f60443669d526b99983678236c8f5433cd130defb06a39023a, +0x13c717906e68279fd9e57e6419986ee2cfdf96b20d200e4adb31353b19a91470 +], +[ +0x81f58a91a4e0d100e0369fdd81a190035342fd0677ee1bf5215e47f8e58c2c3, +0xd94283e58978ce187d463c50a7277cd3c80e044e15729a6f8ec0422f2ef8b84, +0x440a6e12fefc1ebdb82b5e69c461e3e332fbd297474c18a65390fc8649a3d55, +0x12146efb02498c13aceac7fed685b0dd88fbefe8f5993c0cb21b0b4bb85b11b7, +0x64b0712fa159104820ac07e0d2723a3bbc1d1295ab39a108e2eee8230131f6a, +0x1e0f62f785734194e76cfced2e91600716eb46fa4d9235f28e47e366110af98d, +0x8204690216d1d2ef851dee5e4edd9fbfe66f098fb61c231a0e89bbbd9e9475e, +0x20bac589a995937086cb727fc2561ed052489eefb58cfcc260eefd58502b1ac6, +0x1f4bd25093fafea78a9db91966e6145c46472a4ed46af710826accac2034fe71, +0x278c85ceea23e4c040b66e41ad9cd09a7d0ac6d3457a6e596df14505f071de2e, +0x45ee69f0bcde13dcc97f5910d8228124b16945cbdf38db33cfd3933d2c15c97, +0x5ef0c0803ce631e81fcf86a7c270ded90e8127485d424abfcfa7c4a9da7d8f2, +0x12b584469f8cb8b5c200bd721bb2c299c5e63422d730a3baa52274093f9fc085 +], +[ +0x22a852af90680a8ca9688b71ed27c157d02b406bd6c7fd8121d7c7793ad2305d, +0x239a362ac4f07cd888facdc5e32f0b42e7ce6485e9697d14fb4089bb6074ead1, +0x101185b0a8c7d142bb221c50fc9840e9c5a0bf1110e9dc717b354f100b514422, +0x2719aa9c388ab97e084241110f428722c8f72de23a6ee33f7040c781fa5ae476, +0x18aacbd4af9ddb42418648314a53accac4af473cb54e3dad906a0210b98bcdf7, +0x28d0ac11170cf9ad662a2f31d00633af17b9f0e345889ce997829747120aef6, +0x1c76cca8e7372edc737fe1755f75986a465863a66539143a5f21f8ff9b0f8970, +0xafa7a7f02200447c0e943dd60c468ea6d1cd1e001505ce16ebbcc97297d6cd0, +0x28efb92a44b7e421bca73b274bc28bcf74f94c7212d72ab6913c1709386c5e3f, +0x1a03af000cdc46ccc12067c560bbda2a98119041bf9ad3ccd9053222fd2eb4c2, +0x2409f6c3cc378966ffae28eb4adef67f8c282d8a902db3ba471d9540c0039451, +0xad59025aa1e7d4a026d1f819695b3f7890b3d9631dd06f7da00abd0ecd94ab6, +0x7591d69aa28fbfb5b65dbb6f4420106f0b0906151307b976f6baeccffe2c488 +], +[ +0xb27ba82a0ffb98368981736ae927a227828985c00c3e5df8c1276b1001089a1, +0x2ceb1780957827f9d4fac39214a4e82e89a82a760a9fdd85393b285dedbd8114, +0x18259272125382f107a04abdc0d968efee527d2242e263015e121fc4b090b582, +0x10c97f58b9ca58426bd89a59173ce8493d2ea8d3c6cc827ece2453ef193bedae, +0xfdb0710ff8ec599e7ad5086a29d53a9d1834e1a4c71f0b6846849eb0dfc47bc, +0x2008c67e2365d2e73a882fe3ffe416e8e0edf4a3c490dbb05d6daf56b4da0546, +0x874dbfdc6d7035655981f935798b58b755c7a9d82876352cd26244518d67062, +0x29d294ae7d02f2371a16b483b2102e0055080956b53331aa171f50de5d9799cb, +0x2aa10edd36798bf46c3cb7bd749017867c029a54e0ead556e2f15cfeffb4d9dd, +0x2b457a5ddfc105f203eaeaaff9af5149e02c6cf80a9327ed502b29f4c3602704, +0x29ccc8e6be785237b8d99009dffe037979c7da79ab22fb062d6fc1f59d48a708, +0xd829ea3c10abe53f0153b4446f6e2a250dbd79f9ef7c45745572826549109e8, +0xcb3680ad25a34e351089474c8ae39b6091e553be4b67c2bd1fc7a62a04287e5 +], +[ +0x4b46526207edc70a0d23c8438bc49a365635552dee240661a2cdeef966f20f6, +0x1ce71edf5b935a231b0ea60402ba756a4bb45d65120cc0845f6c2ee2ba32e7ab, +0xea85373234c815ce2693a734fe28705dc6fd3fb29cacd0b9f4edb694c15672c, +0x10e60b02e5c0abb8dae47efa17b0582df94a3baebc52bcce8820f858341d7188, +0x67ac96b7ae162e5d0b43715f4c24b9031c082baa68ac7638a00f8594bc3b127, +0x293dc450b0e5c560a15853129e238b046a419ac6f0c8ec19a69bf8c409a73cab, +0x7a2dcd14fb017674965e82174a35decdaad75e42acf3d5ac1a1e235257d1fb9, +0x5cf8b0f380d29befa5eb75a0c032b7b7eafa895d98e0bc0e86f03ed066c9876, +0x2d00dde97b4150107fd9bd859c5832844e6be0d5a99cc6752d97585b560c4b2c, +0x6f2b210733fa0605a0cd753fb6ac80a0d893b2bef2d5453e5f6cfcbc6a14302, +0x1588e892f9f2d3c6a7dce89f132b3dbec142bf485e2142ae05db7fb5d7ce211d, +0x14c92dfaa3a1f830b20150093fa670dbef3c0c807f52321e5fcd28807179cca6, +0x1bb4555d8c5f8bbb268361d5e1c22f9555f7c9f4fabaa24355c963edc263af6a +] +], + [ + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x235ce940dbc6ae2af119016151581b3928bbf5dc663dc5f4b6cbf02305a440a5, + 0x1f41f49e23f371de6ee0539e873506283ef7303dcf1d6171a47311e9fabc25fe, + 0x2761de8796f7e0b5915f56fdff180ddd4f22001dfbf15bfc83fb8b76c2ed95a2, + 0x2030fa119e7ea727117fa18d61bebfdc5945b9ccfeb4173b77b373a88362544d, + 0x16fade125075ec0ee8bfb5acc676076d14b76e79b2daa5acd76fe6719476c017, + 0x154054c752e6e827543db8d8d6baafb02726fd7cdcb71489510e89dd2faf5d5d, + 0x1b492c6aa52f42a57aa6d9e9680c14875ca28a129fddb2fedbeebccb5c83cb4a, + 0x23d1d1bcdf6c2c14376e6619ef855a718aebf7d9918f578b59025e9808936311, + 0x1e509e854698b837ae62db6eae7730006480f64ecabc6189a6e923708d4aa5c1, + 0x104a16aecc2dade9539007d7a631cb12e7ea1ab9fa18e4c8d158941e13322bfa, + 0x167e341698c1e47880a08b21374178b7e318714eeb40b54504aea93443249f9d, + 0x16ff745c57280b832126534f65a36e051fcf161483d1a9ac4d2a882d55c4b3d7, + 0x16556da3145b12699852213b53eddd1859bf0c06464a69887a6ef1319cfe3dc, + 0x1f52e72aec02c1085861bec46d3c952a7b17e3b859e1e119e29f9d55b00a9d20, + 0x1439235c136533951e994a422857fcf8fd137963c823113e777cca92d5772330, + 0xa70ec5c87c2873d1927e525972dfef236ff91f79962eac7db98fec13c3ca6b, + 0x85c4d1ec109d4fe0daa8548c7b641d62bdcad7b01f0257ea54f9e6371d00550, + 0x2f4b2580ce56a2b5941abee8b7f98ae4b89e652a005b6d378edca751823992b8, + 0x134520116944cb30a05c694e90ccfe26376a23acdf44719d5e94a40c0cb4eba3, + 0x2c6f46236b3de631bb23dded37fe4349e986b9c26a99382a28125b2123e9612a, + 0xba54fa736725c45c9aa2edb10e2d160ee499707fc5d3fad092c6f6e60830363, + 0x9fec55075da3b0d949af21227dff641435e920034b8f3a054f6ceee03f8bbd6, + 0x2123de2c4d9657466e2c0994fc75161b658fccebcadb25d03e1005480ff65dbf, + 0x15190bff5104801efbac26fe09882fa5d5aa2bfa702efcd1b9e8ae4aca9f2ee1, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0xebeb78e24789d13e315aed03d6f9a7503f8027ac8c07bb31cab7d9f7c867273, + 0x1a7408d356b546b06ff9e11e706fe10311eddeb564d15f77e406c4a17eda0fae, + 0x7b909e9b3d766c0562bf5eae630eb1eaa3f486b67385e9f15840dcc75a4695c, + 0x2fbfae64d96df063622736669771b3763fe4d7e32a253b2e9a432fd404a5a1d7, + 0x2e8bae55338b9e7a202278022d1f4f1641e8dfedcb10173f8ffa47a394a792d3, + 0x95cf55bf75f13b6986a1d8dc6e23ef27c6e20049be69d275cca08a95c4fafd, + 0x590c80761bacb1996152bdc843ee9bc8d9e1106d6b44143cac61a582c93c707, + 0x2e2c9e1b232536be64e82e3fe38c9f83cc1e2ec77eb98d690ed88972c55d4dc1, + 0x2a0bdd075038ef925104da5f80d436819a8896b46194b795f9ede6451882f668, + 0x25e3f54e8788cc765abcbecddd2326c7ae8720dffc3df2e7cefb06bf572b019c, + 0x2c4e38ce29ded57148964df0816fa57324061c515ed02d9f5ca4cb4231e72d9f, + 0x17816a3115471f4af63e353a891e5c63a1de21b079324c7376c7fb778162d597, + 0x16b1e612a7910bdbb55b44174b22b72b63ccf452f485aadb834a8883f7a1129f, + 0x1cdbce6ec5631b7df36d7fbb1734c066329559906cf4c9cc7023b75445f2cdbf, + 0x8527bb0455abf9205319b4178ac91c89d27d73af39ca3eb5e267b407dc122bb, + 0x295a5be07d3fad3d9622f92a52742786741d19fa1f85424e6bb0383b2b3184df, + 0x1d10e15e892ef5c67b06061e9230a13aef08e3a2422e59ce6a7de3bdfced494b, + 0xa1cd7913f731a263b47880b483792d1eafe766bd397d6a37f9b03bff649ad97, + 0xaef18db0541091f4d0a8c6c0e04bb191c3b3eca9abfe91b336f37688f82381, + 0x2c240c1f57384c0eb11da2fefef668be130079616fbe953378ca4cee358ae80b, + 0x1ef04e55dbb7768b7ed264223a560b7462d131ac387b0e06e091075b036c2903, + 0x19df6cfa53448857b40764ac927e45c59a4ae69088b7bfec231217fb49bde976, + 0x1b794d61ed2a335a1b6ca4fb2df93b5de924f51c742c97eb1f45262f4cee3ddf, + 0x62906482824c01daf001d0b01e1558d7a2e921bc124099fa704a167305b0432, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x1ee5e91ba44d3919a02a4c05a704d15dbd6665d3a0caa7534f062cb702e12ea3, + 0x124e5670301689bd1d21125260ac980aa77f9927abfaf6625cfc4aea0542c38b, + 0x17f39c51b4f9aba0b50cf36cdb63d6485b3f79e0f4c56fcdeb1668eab22d2ee4, + 0x1e47876883221f61f5a85cbcf916e4255c146208100bdd75df2550b7f23d9ab4, + 0xf6cfbc348d0c46f2b4514fa4aec63685b7b4a77cc187f39f90352aeed2d4196, + 0x1ec916f0f8ab3534a45fb8b6fd52a0db612345f94a7d1047b9cb15bc4354d259, + 0x2299e8cfa278c8ff8acb571283f8d58b07285fd3db093f52816286f8059d745e, + 0xe63ae084d4165ef23463637d3c6c962642acba1dad62f5df322c00aaba6788b, + 0x2c652dbc12391bab6e6b1642278935adc57f028d75ae594e23e869dcd807a04b, + 0x23cca3a96c87c09a758f977f1e8e382898bdcc82debfae4df05bc7c16e74aab, + 0x2f5c19ae2b06aa09ff617a2dad69858ae545b8a63f5c730d50312ca740d538f6, + 0x185c013083f0dc7b1eecce3045555f593a1516f7c0486900029a21537acf8e03, + 0x2e4ded90ce2c40cad391f536718a6f107838719e6cf002f2e914ee1db3fda861, + 0xba3626706fae4da22a59bfc7d0b7c3cfff221ed8a6984553a6b605fb7ce4cae, + 0x228687cdc81f4bd727891f41911dfbfe24107d60dda4ea79b5b094886e89c4cf, + 0xc1a4374bc29963f2c4e68c51518e098dbe906d9c3a664e24938a403009ee28e, + 0xb49ed175ec0cb65d9fb76b9dda5859af6f7eb12e0a4895c3de51228e33662a4, + 0x26be812425de5be3e6f4fe6694d8b883ad156e67ebb1aacb6cb64fd41d64b19e, + 0x17cd4b4c75b978ac369c026e0e34885bab4c745ef05c471d7975300eff003dbf, + 0x28ecb3b468e0867e4dbe29f05490b90f6210108a30624715634e3cd6144085f6, + 0x2ad2a688d5e1fc7a853d17ff8e29487e6a9fe8e234b6423425afc192fd6926aa, + 0x177b3225d90e7c43f46ea85579f408bb2394983faa33d3eea7b7847e10b71a09, + 0x18c733d3fc6d5c4ed730650c512b0b2922fa4ede0e4281279df25cb57faf1749, + 0x25c287190fdd3f0fe552c72c747c521b8e47f042dee30f90c88cc49c425e2269, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x17223e88c5afdce6f98c3d3096fdaeb74fa99a0bf6237bb328466b843b5b481d, + 0x17edf7bb609e24ab634349d03bbac5d92a99f1f54571cdac8e155a3767946556, + 0x16384369e8e866d47b74c849496796fe485290080acb6d05a78b399906654ec8, + 0x38414054cab9daa6484886487f9b1491a0424c75dcfd6e69c00f88391963260, + 0x2add2a9f58afb253d9e9729b8510c6ded8cac2647871b4b2daf92c1ed8026670, + 0x2f59f831ed16663ae1e72b27df74f8878583b088726e2f77e2a9b71bd5eb4e8d, + 0x2c8563397614e4c977762b73467f74812d61eb6c921df0b18bf84dae0a448cda, + 0x10844b6d701b264d333ea6d5496ee62b7f99b0f3e81e4774f271acd4e6dfc452, + 0xd90e1221b226621bab0f84164c6bd657cedf457c1691c6492548cb503962f2c, + 0x675d5268e859d734fadfe6aa6a58f5bd47e9d9bcbf7311d928562f772a44312, + 0x231539abaa71d18f3c100449d2dbb5a78c8c6eca61debcf495670ab6881cdda7, + 0xc5e674c55e57e981b8de7f89d00aa088f47c5b01c39bce85ede170519bceb81, + 0x2e6b1e65cf7069fca7f5ffbf0760e5d2c6acec8da85ff34f2c3cd55f744c8446, + 0x348474ad39c09ecfa686a8710a7737acd19917fb66e90a3df84d110b5b26048, + 0x22380985f6c92bddd7a02d0187c845fb834c9b7e3664e1b064ec580536d1192, + 0x215293044ac2044e97d2d06e714e937bb16844b2c4e834bc3555633a31ce1d33, + 0x1076db0b38f462a6a9829ed423572f05d1658c390fca109dc6a5baeadb39ec85, + 0xe0b3b39e33b5f0f7689976066d5aca89f070fb078152378bbe4cbf608330e0c, + 0x1decd713548d0f04ca0fc3af31ef53eb04fafa773cc696bd5d7959d5b8781f3a, + 0x8eea1ae2e1dbabf4e3969bfba914a7a5be05a672d16aee9029c3477ad75c0b7, + 0xa3c813f669fd0550005be2ed025fd263f496cfc0c88708c5723fb6d4783090d, + 0x1482b39a31e48749f37e6cd63f9fd7498b70623637fae3183f1805deb488df4a, + 0x92c09a074272c56f7611ae231544253242fb998f1faf5a04032c897705cc180, + 0x218cae97227d24e5501a8c68d0f9b298d102b5bb4870acec8ceb068b219c5de7, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x19fd38d0a9fcfe44eab81a88bf83e966f625dccfb8c8e663c92783d2f36f435a, + 0x105b69e0c16b67fb448ce467efb92c03c0a03d0ee652aa1d3f57276bcda15b48, + 0x25d1fb19588b96b835cf451788b64356dae74ac4b1dd04105f4ff71ee538e69, + 0x1a3d3f0584d9937628708ae5bc1a677ca0d9734ba13f9f9bafd4d40ed09efd2, + 0xda29cb284f0b19e45ddd3688a097cd2fa147726da98e7d7565480753c3d69ff, + 0xbb245a4fe17933f1a323de946e9c79ecaefe27cb72746f02dd7f8a12fb97465, + 0x12968abc1e49e916dbfd8d32c99add0f2522613fdfa603384acad50adb3c93d4, + 0xb72090055db8eaed15c53223be0d59f134b6e2bc190ff8aa145de2bc81fd905, + 0x2ec92e332d64bf0a6d53aab3202f16e8f931b0b3a19d08397981e4d67f7e6149, + 0x10875e45751b9f7e6d229bcb6035a0f64d2fc266087bb15b46ed8dbac225a875, + 0x20a28d7e7bf2393dbf1e8fd1b5957d6696a586df80ea755679bc922b32214f06, + 0x2dbcb5a066131fe70e1035acecb96d60a3c48394ef025f9469318ae141b59474, + 0x5d382b11621ce81dfa3b2a5b9fce537f18f3e1a3c11b744c44b7daee0f539a4, + 0x2aa1cbda3b7224be26b553b60967d1e49a79cc1fcea1e28dcceae95257195fa5, + 0x119d098ff4fcd15606264dca209fa31b8f90d343d73408afd99cbc60bf31b38c, + 0x2d6a5ec1decfd860f606bb717c2d6fe04d5da0a512677bfb3b88c6eb828ccaa4, + 0x1d44cdd7e0f9ff30fa262b991bbd4b25b9798c52b5475288dda93773873b70f1, + 0x1a52bfe42c699db0584e9908947654007f895244c01b0827637fff73ee586351, + 0x26bc0e722f88daf0ae3100dd3603409108756c81c2d2526d432135867248f06c, + 0x2151d6544b541cbe98b57b17bcc32174691b7dede6da01a85964ff4d03c63ed0, + 0x1dc401101c1f1df1931569efaa9db035fb7eb1f94ae9ce86cd6dc0540b1a1fff, + 0x219d8e0b575d09e774acf4018fb6302ac990e13959c8bef55814abe703d0a4fe, + 0x7107aac0c5aff7df10b39501354acdd1ab5dc0091d0166c55cd063c3a3100e7, + 0x1541846836b18159c10af51567f8cbd22556df4f20dd74ed1cee58b3144fb464, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x1a21b2733e57ce5cc36d9770c7eff1ae09c59af2a97deb649f35e034173963f8, + 0xaa74005a1aba9f35de88f256300d0f55c9a568a0a3f962547fff0a2ffcf3faa, + 0x302cc36dbcf39b2bb8f4ff9da06a95c8a904275eb4ef75a5b82fb7cb80133143, + 0x1ba8fadf54ff193f90ce70d81d068ef1caff816cf4298a9e9c359b78c7b3c77c, + 0x177e25961a6d2d2538623d70bd43b86651ec63b0ab29b1e706308224a0b7f68a, + 0x29ade22a14cb16e95939ac85e6c50f089d187069df8659609634290249efc500, + 0xc3cbc360d3cc87126d6dc733e8c0276e1b576ca318d256669a2777f70d89308, + 0x138a5c75420e198be86010c147c10fb0b6c882ec10683dfab0ef1b8cc023639c, + 0xa350052193a49d3255030214d15b36a10e7b2561890a4c851128603b6a5f092, + 0x1002580094079011e6c17ea867b391cfe05b5e73c6de87869cf2545c10084594, + 0x8c06521680fa7df05e7c8fb8a3a2ffdc0526051a59411a0cdd29e5f993e8f47, + 0x2a3a540122300f3070651e9198f9d5bb0fb52546c35ae90a4deafd9baf4e65a, + 0x1416a8824238910444767922e320d38b543cca200ea6c5591db9092e224be615, + 0x507def96242fbb9a1ab87fef1da1a03f4c3349723ec4ae6de894e171a1b4af5, + 0x2d03148012d730729390a74fec2d3e7ba9fd23f45e801657fc5e2a49b43744d, + 0x19446791471a6f03c3e0e557ea0d4b24bbd2930669ed23dd286e81b7fe17abe5, + 0x23c198ae993dfc34a55d2cb02226db49afdaa1b8cfb934a05ca594e616f43f35, + 0x49ebd2c1b2507a1399a21690d0e6a900184d15280bda27f5b53099933aafe5a, + 0x28eb35a44903f387f0b17a692fc99cc80826f9f36eb1b9576e2c5c4c48ccec56, + 0x2e217b29bc22f5d1772b5bc1fadc11af5afbe87b223fd501b1b63ec28a77435e, + 0x5d617f4148cb5ad818ca83e3e25d1aac33119f4862592430498b6c044ae087d, + 0x196ddf78908da3e629df88726541e8f3dc6bf7b3434a93b25434b2773b546eff, + 0x19f43813c7b1361c536509de373c74ebd978b0f3613d0457e59295ccb3447940, + 0x1dac98a00317e1ad75b44dfd710de43a70e1a99afd151dec478a8d0b4ebd67dd, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x248389b6c1215ae80412361e031f9d19e83e305fade25b5151787bac24151f30, + 0x1d6245849595c3f2e658dff1f825202f744288c73d5b6fe3e47be01c85231a63, + 0x2828197fc5ec3d0b61e3cd35b39ff7ca0582844ea9893e47575ac698fe0fab44, + 0x5f98baa94403cbee299a7c38bca231773951a9b5ec47809445687c1fbfcae21, + 0x21c21725d982bf880516bdd009e9c82289429fd8470ee4f009281b6d610f86d7, + 0x25161628bb96c434fcdfed33abfb03d4492060f9c12e5d6e11a30da401f65624, + 0x98dfc41ac8db685ac12e9fcb277ab8b38fa0b4b943b5f5863189e57a4ec1726, + 0x20e5160dbc32bb70dd2b667ff122aac9c9a209830d177d065eedaa37c238b6d3, + 0x2282b92a3302808cdc7032e874419ad5b9445a5e6948c67e35af7b59647e6072, + 0x19183560ff143e5d855665e03136bd60d6e627117857e45ce3b170d335d19805, + 0x1cb1080ee04da98e9a546b1eafbfac68d7bbd31acd6602818742e1dbd035345, + 0x2e08e6eb7f7299ddbf4e83adb2f544c8e2bf1733140eae2a24ca09e8e190ba93, + 0x17313eb73d301839abcd85bcb243a96c662a9225d70e923f4966024ff3fea376, + 0x115a8fa0b0211dcf5a0625e77bf00d4eec93b313811c61441d04e2e927f99a1d, + 0x10671e260167bb4a73650275e517b30cb040d62e5d8bc65a23e2bab6fc0927bf, + 0x697b10896487efb0a81d149a959b22c8edd1b130e18ab45dd5e4f287fc567cf, + 0xe23561be0a6b6e5616ff582cba30e707dfb2d85aff42daeeebab0a41fdd2a9c, + 0xe6c17540a1832e4aa8682e0c1ca4471e2ad131c70a6abd6333268f39568dc32, + 0x77e8a2a9d0da541d9357eb1b603ee9410d49eda3140ba9abbe1b6cfbf8d4e36, + 0x1ef5a47f9491310e04e85c853bc42a12227721bc8ef99acf866256c6f0ac2b05, + 0x2d756bd8508664fdb9623bee29f62db368e7e9fb8c2f8cf806a2028a34a54ed8, + 0xb6440027e32df5bd12e4075461952f0c0a169f47e498833a0338776f3cfee4e, + 0x103b3141b18d49495ce38d5e0ab2a691e78193978da5888e36604c51eb757e96, + 0x4502bc324657c18c59a6bcadcc0735e706677a556f0ab33468abf64bd434649, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x226880584a57a7c552da325ea532bf382c67482108870675bac5d3d9b6a71abc, + 0x178d0b7b044c806c180b95dfbe188f99e7dad714554fae1365264f33b5204d38, + 0x110cbd05beed208043ab1cba8a604abe596258c516ea0c68b804d2e262989e28, + 0x2b4f9ba6e2d2e31078ed70f6a147e329d1c4b83c76119951dc7bcc6d2a944cd0, + 0x1712edcd1662f4dab78bdb08c5d2208e096d26aea6d8b5a2f1ea1a575dc29dbb, + 0x20e7ac1985805214842f811423601b3f18c8634e87b1433382bdf397b28b7e21, + 0x5e6b0e267ea884c7a767266b614d9f23883f297a9c40b2be9daf6af85f31fd6, + 0x15adb275543fbb0e083a10e1ec448b8eebf82185f0a99a06bca805737f0d7db1, + 0x23f2e8816906f5fc349e99c8241230167b50d8db22c5e752d640fc319c7354e1, + 0x8a8a0eb412422e0ff3bef4e8f9e98d0937293d8bd96c9ed823de14c7a60fe44, + 0x147392d188c52fe487d5e14652ff175b37253bd5fb04ec9e316de4cf5100500b, + 0x1a1a69d5bda4c559702d87b8ffbab347d61d5d5ffba016055b540409e90d050c, + 0x26265b87f8fac4c16383d9763460242746a0fbfc7fc375a251a39e5cb12c8ae, + 0x562af273c7d6798ad1772d383417f8baab7feffa3f8fe1b5061e695a63ea362, + 0x2277d743f99daccb8223eee9ed2647e6bc22c5f00a0dc9b45c26898227530c02, + 0x2ab7551e6b4731a0b2c00c1a1c57ad9dd66b2239a2754f64328d4023249f331c, + 0x67e6bb5600490688a67ca30a941a68f15dc97eb418f8cecceeb1d1f49af1cd9, + 0x299b048827a0cc67b44e53fb5897f27c57c448ed25d4be88b1b81b22186c0017, + 0x4ce6cdf689338f7df3c3ba84e7ef35ef59adce460340ea0d161a45123c4051f, + 0x17631e8c563356367e1607096074fcd220d0256a60e1e6d145bd243c5475cf9a, + 0x25be84baaea86bb16bc3de4e5578c796e1888ac898d37f1f835ea87f1aabcc04, + 0x7fd81c59493a306dec9f05c012a96c113a950a44cea7de572af401db8804f2d, + 0x2d71abfab45aa0b3d4689b2518ae16f87cb60b0fd9d40c3567e5dea122815ae4, + 0xbf1dacc9ee49263420b6b40b061e1de77884556be4629a011bb73c3cf8fd282, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x207e38309d97a6bf02d2c9071fb8c0243a8f6570c15c1dea211dcc2cbf45ea49, + 0x96401efc3b429395ea5c187ccef5c551ed99043ce3abe10e0b2f6c0fa0d29f1, + 0x25e2fb13f405f8cdc60da80af2df8f7aaea21aa8c5ea1b80edc22261c424810f, + 0x14f942438d0b6308e88366af640e59b35e7b90dafb9949cd395fb9edb36e57a, + 0x1a732391895868212d93a33c0c4de589333631c8260c991f7885b916d0037272, + 0x1e29088ed2ebabe07ada9617c87d6ae3eea384cca222ea5983550c9d25bb0648, + 0x5ee285acce6181041543d01d650e8314690f337372341336b4fb1b27dc1bdb2, + 0x252b8b5dff5e6788b2389b2e55c939e69871912bbcde09be55a0baf9f8c7a67f, + 0x5198e4ac3158c2f1f30e9c7333b8f185372db43467e884f9961396b75f7d60a, + 0x245a5fd31eed8204f89bceedefb467b89e3cf7fe91d24a33a3207bb6f083e19a, + 0x57bc812c85f04480fe94410a106b281d8f3e2d54b39e4fb45e0a5ead0910dfc, + 0x1afeecd7c598ce3f7281378c2e514c5be72109df6efe311497dbe12a819e406a, + 0x2fb8c6d1000b2bf11eac94956464fcdfb9633a271fa8b070f4b63efd7b5007b8, + 0x32899458487c72b4c48dc1f717a0b2aa3ce53b6a4b38558b7737ed21cafe78e, + 0x662f06913258bafb5bdf1aa929332c7c97d4c4490c6fbc8e798335ff76e126b, + 0x1584478d313986eb0ae24f5d342d3ec738138d749b5071e839c1693af46f3a3, + 0x2dba025efcaba3d1c4cf07885e8fbc1f11c012bcdc009087f306a399a7645111, + 0x9883180be89d40f292405a2d44f5b9bba1c37613ddf84bf28c4fe593fcf06ee, + 0x1ba2bca86f0f3a73f392649f65c1eeabb57e3527588289b4820a391a46475dcd, + 0x148b95dab3a784e6f57042365a46a01e5880f17e09f3141bf99c53ee8a1ff06, + 0x209b90e92015a18f13bd1343a34d905fca3ed55b88bf1eeabd3e542987a08628, + 0xb50cbb98c4c16293795735e6cad9a458e2d37f1c02af95b15272aeadee5307b, + 0x28f083282c1dc347bb8049f59580fc82bebfaae2fd4d5c3198eab42357656c01, + 0x1e3cfa063b3cd467a69c8a628a627faf26187744a879ed796956bc1e3b1ba00c, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x22063e51a25b5a045914651b3b3fbb41a432a2cd49fafa1a6da1f1b3abac6b39, + 0xed1ee65d2b2cb52e5c72dc18084cdaffdc8eed2dbf45309a9b31afa3239e0c5, + 0x9f1f1407a395396be8efd490907e71b2a1e1a761f5599060b1ddf9babe3ec3, + 0x24e22c3cd40dd01dea8ca00b4ac1dc8cf2fe8ec7404f09decdb5f2e27e4f6a51, + 0x297d190c65439de912d9b19a51a34f3af3062388bc90dcf02c95ac55f827f393, + 0xcbc6af2a7286736fff8c442d20accea23f927c42de68c5965be6b73f787871, + 0xbf4731c628503367f3a0979d34ebfc4e1b3a6ee8cb90f8e145ea71108f77b19, + 0x74ef632df5709022478511a69f0c35f167718dd3943a871dbabcfcfafccb99b, + 0xbf311d6ae97647aea1524d5c401392a2a6242420918607c8595073f00163f2b, + 0x2fb17a27e5d93c8fa198091d288eb25cc9a75a3cc2bb29c73b7c4962ba6b02b6, + 0x17eeb974a4bb33ec349adc4e3c5e9141c3fe5b52b8a9eb5f55897fcd3f13dff5, + 0x16c75dafa94b13f4baf5a849aa93deda4486711f92188ee41083f8ef0e2a19ac, + 0x122da8189ad70e3c28109ade01566f47039ce2a35d85eee2f2212139d7e6a83b, + 0x260972f4d1166f0a53272aaf203d54909f372f9ef5175fa8d15f863299bbac2e, + 0xaddc83c8f239eb4617cb1a6a99b9ea314b775252379d4a28092946834ec18d, + 0xcdfe4ff760184a4b1e1c7df835824830c35d9ae719993e1c8b61968341c74ff, + 0x6cb7b1d7ee8b715c2b325853d8374f2f1edd1c47defc42d560fb1ec2ec4093b, + 0x8d48ac917970f6318a8b999fcfa64bd0026915cfbbaf2356c0e68415b42cf64, + 0x20f5eca934a922f2324ec4f5cd1423fb342004e24db642dde32d4f49b020f19d, + 0x2926c1107b74752a5b0b0326f9775d3c0290079b81f1ee7b3540c857a2e6e7f3, + 0x2ad7b40da5583cbffe41e7ba8a9dcfa0aa04526e17a359e380152ab05659aa3e, + 0x157176042c8c3678e6a57db77c420cd2aac6658f392eefec6bd96ec3d75d16e1, + 0xd6e65707b940bb40ce868be699f58d8f328c635900db4f738d9ae05b337e4e3, + 0xd794b0f796362925d3c3f8f7a5fc0fa8995ff16b7cd198a7a4f2978033d3e61, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x20a525ca48bf502bca0dc9aab020e141e26b38ec47a44e1580c0d1b616351398, + 0x1ee320963332762900b4744bd20f6f06d90663c9a45ccf876dfa46ff7b6a648b, + 0x22635f8210cb3cd5a5f3d6f3c05db35f48f4dd99ce9689a4a49c1396fd0254b4, + 0x236867069537dc76045fbcc34387c0d659f274038f60bd46092c7c5c6d2a93ac, + 0x2949bfabb09d51a438ba0c845a569c3cfd415a4767babba43d49b4a7d23efe57, + 0x1834d2d0982cc3e0a6783a1817d0a70935296a1e1cf6ced2fb36e49399ff129f, + 0x42688f81e90f021c645ab69ead85df5637e8c35e5f747da2b9353fba3614759, + 0x2cbf3eaf39ad0427ce377701b0aed081ab11a4d8425a5d85eb6ed545e02a3e67, + 0x28ee79339c57962491524337981f039783042a61ba46bc4b6d27842ce253e295, + 0x2dc6b0d76d332c582bc225e0e3852a84e670441a34a35271183dd071b3a8b9f1, + 0x7cf8620fb65b2763c494dda02d454c32d86918bcd972c81af8896daa2e25220, + 0x19d3305037fe6d5dbdb1c2cf07dbccfbb3771dd745a1a776027e76b829c38e15, + 0x2e6f19575b0e917c325b5455bfc97e65b080d5ca3b0d866a13315efc1f5afb43, + 0x1e726c0acd6e169de2eeeaceff128e7691b7d4fa8a046ed41a828563547a3270, + 0x2527a428504d8fbad1a95451f6968dd7750e9b88eb737094d0d22806ea461bfa, + 0x1ee0e151bffcaf72aa962734818b53086af9a5eeeaf821fa85a16ceedf5006de, + 0x1332d8ea514225643ee26cf14ed13c2936780d3b0df8d13a0d80c7593339dc1a, + 0x67440d1b5c5c1e37921583ac6081d7c0b614430461abbce3445fdca1c25e52b, + 0x217e15b68bbd0d70328ba92eb9848533a76fa177015bbe167d9648e216d72fb, + 0x1d5f55517167e8f4e07ae1d8fb025baafb68072f0ecfc39c2ab6917e2883f001, + 0x1ce431894721293173604b5423cf3be2aa2a4c602244ca33cfc474364261e219, + 0x1870cdd25b0026ceb6ca8bb7a4abe4c835cc54fb5d4a2bdcab837776e4a41f36, + 0x13b6c4c8a9796559718d72ff32d05acd285d4e36b24a0dda09181dcc0b821225, + 0xe59398cb50c995ddf9469890c14f7eb35b6d1ff21b54fa88d75105180cc9c84, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x2471cdf128c6570022fa1786a35b379627cdf4a1cf0c888cddf80196fad77864, + 0x1eddc8c186b5952235d179801e4d1f5526b26e72d637d482d34aaf8acdfbc678, + 0x41287596ebb654ec2703cb288320c78b03e252a98d304b5c670d6a9f3b75f11, + 0x2d27cddd60f27e931720ad20633a2e0aa9e9fb34e53a1c92449c42539836cc84, + 0x386464e269edd20cd4abedb92ea083d5251633ec2ed40b9c9298a6b03d0c47f, + 0x7b28d6f381e7fb054165533e6c22be7235e01dc2111c2586c88cb6b13915daa, + 0x25a51836e32d3111c1ef3a5b222a45a8647f491b251a0e7d548aa579f04dd532, + 0x4133c14bb36f4f02735144703cf36b0e6eaec35a23b23a5b3d7bbccce729e3b, + 0x1a107c44417a85fe63fa5f32beae1188f7ef9c7e9887840e06c41442065fb590, + 0x11963a7f8f62abe87fd0e9f059bda23e56ea044fff31672c16653096035d6e60, + 0x63942281da7187cf115521332a5480ea6297764540daf35e844f9a9db14df1d, + 0x28323184f7d03f5fdb8c55416291a0f2893f3f8f704345fd197335bab60e6313, + 0x1d5ee3c314bccd0507e0e1f3d22cde05f8beef4006bdd196d1cd972a00f328b5, + 0xe3e7e1bf77551287cb3436a06bcba1356aee949507c50da7075fba70259055f, + 0xbdb1ba75288ad45c653e6731b73fcf8c2e5a06452a7e9b1055349ca1b954a8d, + 0x163efbc5313a19dfd299b4f7d24ac36fc09dae316bdaad22f2e7354890487b3c, + 0x655a2ee9811be4138b87caeac43693187ba723a4a252e1fe5aa481cdf35dcf0, + 0x221ab7029ca41cb3703fd26fdbfd99f83da62e3d6aed9c715fda493e703ded14, + 0x17e06a11e4766ab95ae693ef77be2fd5a816abeb8af48e77812af31a9bc97556, + 0x24fd79ff869a80007553fe52dae87841d271b05d3465e21632e97808db658a79, + 0x2937964cb5feff56156c0a2d36e7d717f5133c52311e8a9250e3e538c6d6a2e4, + 0x115b54ca59723ddcf0b8b72e014a3532bfb9461db00c87b805e6eb6f950eb2fb, + 0xb83ba59544995c109fe67c59e1c6682df4f0a94420449255f2e42125d1522e4, + 0x856ce0b9c472642563a58f67fbe8490d213f1e60c841539d6593ce72c8caa75, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x1234cde55f1ce07e8add8919dc2786c2a2e8baa0699f9309a24a6977cf4de312, + 0x2728518406453c21f80cdfbc5ae5a7e5bc660853c39c07f08f4ca48b866fe708, + 0x263c6e870681a568879af7059e9eee6c2107545775a707e5d397e090bb406681, + 0x264b910c5d9c7677ca26b01c95b2eabda02155d239a7525aacc9e7c3a1b31108, + 0x3626d5425f196e0ecc625c95caf99c1788ab08826db99cfc994dfc07cf7cde2, + 0x285b7fc8640c5644ef5acd76eba635788490408488d4c1c7fe5e154882885b20, + 0x806dfed34a9e837d6269442a1ac7f06b9329bc91b841651f866d001457a7e47, + 0x17d501d18a443c458bc2987ac700a167935fc95c0b43b2bc31d3d1e66f4f4185, + 0x1c265144d850ae945f896d29b8d25558fe572437cfbb23c0d2974ed75a8446c1, + 0x2d349fcab317e2f10486728b85b73fd55ef9e72913db57a96de3799d79331a5b, + 0xe3b16089c86c7518eccbf3e7b5d6c93a7f57dd663e313bd9278599baedbe8d6, + 0x16842185b0a19379239ac6fc9576f9662323e9ccb19c73ca551dae5a204363ba, + 0xafddf6a0ff562cf8cf83b9b4aa7f77ca5944dc203e6716ee136947b7774d185, + 0x1a7b9bf02113552d2267b66a6a183c58bd9b0a71b607424034ca249f48056aee, + 0x1b292db8eb2df955d186044eb865b53c345855fb04e0e7aa34728f3a33dc8f61, + 0x1166bc2548e4dd1a597827e1ff6b873b8c029056733c2b15524595f6646fb9ac, + 0x27ef791b1fb45f73950ca3297ad2eff668164240ca0fcec4d505379347a4b32f, + 0x94e36712d3e0387be23f4e8d2e8932333c2b5b329ff01b0bded642875aa8d8c, + 0xc3cb8c9451dc65e2baca4021012b4107b1277ec1e8cf85684523a86f4452caa, + 0xc16066d636413dba5340f2dc58657da3d04fd4f649280bed2ad6c43dba22557, + 0x26f53db3a19fbbae833e6dc50733326512531bacac05e1142b5169e0a6f37b16, + 0x17bfb665418fec0ddd649243c3b77515e92eba58355437ecce39a21b3da565de, + 0x21ed66971a5e0e1451a9657918e2bacc2cb244d2f101e4a870b7c40400d8e004, + 0x2fc72d372345e9a20344054b130f91cc301d409bd2ede08380b1d2cc9296a0a0, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x242b4eadff11c6d3d54f5372755d36c9829ab3f1ad36cde7fad1b4927bcfdf7f, + 0x85e6d5205bc517634147ec300edcf4d8e40d319b2774da859a677ee823b3474, + 0xd7857f8c2ef1d3f6cc0b9d269080a8352f716ced9a8541b58047570931c9a8, + 0xb8a79f4d635ec38c11720fdb6bca9a37e4ef8bbfd3c3a753815ecc975c6b1da, + 0x2d581f4dd4f7a4870f6924d8ccc3aead2778ef1e6dd93b766faa89733c57534d, + 0x26a82a89ac34602384406faabac1204664088042b012c62c312d10597d4473e, + 0x119c9ce0168defeea8eae1085b57836db28898019661e84f988bb0c5dd3cbb1a, + 0x1fdc49eac128a24057128d92ee2b8ae3a28d2ae331e53e898a9cc4baaa67e144, + 0xe63791edc085e7e68fe844a1e288175214f53697c447a06af668ebaf9624d7c, + 0x8e8a95d72c8b0f5572e434cd1e8f29a22c7a051beefe38bcc1c8c67021b6cd0, + 0x150bfbe651cb129452581c0ac0582068914d6b6225eee54f3d041e8a04ee959e, + 0x1f67b188cbddc9dfe73228557f41e28d562eb71233399c51a1120b6f6aa84fe4, + 0x3a94eec3b3b00da129a13059883d56b89d02876861ccafd677f1b692e74dedb, + 0x8a03a992c391bed4739308e90e2039caf26422b0fc314841229d9e65e29305a, + 0xf5db68b751ab629eab8876005534376e79c4cf2a3c0ce2c7681a9a67787afd5, + 0x14c1cf9ee31fc11c4611f6def094e6928ff1469cfad92b71c27eb02938999dc7, + 0x1c8430170e0d27fc8523ca6c5878db717b75136669b58b0582278e4b6a43207e, + 0x2eaabbe95b7e6d41e239af122c392f2c8a422309ca8fdf3f73fd18c4e266b50, + 0x28b85f746bc03b1a6497f9a85fa07e337b664a8e01bf96a096195cdd8dcfd78d, + 0x2eea090dddfab6d9d45f8fdc01e0697db257d6481ecee44eeb736310a57194a4, + 0x29461ccf449b9fe3a48b3527a1b792f31761ce88a12a1bd185d02989048c6723, + 0x2d1eba58a7196aeec7ff60c922a6a37d238bda29e3578e754940fe55f6b44f6a, + 0x1d8488523480035454dd45ab1136e55b48ce729fc37fb3bdf07cd401e3df9864, + 0x169904bf4f7348ccd343513cf038cc546cd137c740b77d3df58ada6cdd49b292, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0xfaa555c1adf771edfa1b4f67a73108c7325be034cbc2c2e6d24554e62efd737, + 0x1a4ceaae57de9dbb19bb3701ae021b7b246fb7550aa505df8f95be742293b7e2, + 0x22d8eb68a906dcad75da8ce62f6763cbeda8004739851057965302696e185ae8, + 0xcfc82aa08b2bf7faf7de17be9adb759389c398441bdd294ed0dc25d3f7c4f8c, + 0x216a462577d231190606ef2920c63455045b8d51fbc6981a103a5135335f83dc, + 0xe63715ac0c89614281493e16b0bfe6d11194b36c1247e22838771eb1ec766ed, + 0xd024106eade54b9f8b5874bc7c3499487354afa2db7df3be1a971c8d2405265, + 0x11daebdd919b5622e294312a5e34121ae33104fb3e1f9e89dad0668f0517158, + 0x274a0198961e0c98ea0f75fe1e38ee5e5962225738d6c8edcdd5623e7b24eb6f, + 0x136d49834864e42917bce7dbb0e439d28c2007fbf09beadc78497d1da2593b58, + 0x18daff02be933186319ae1bab91e42256c5b56ea3d2d0698189294828e2a9076, + 0x13fbadf8255db09ad6b28d0a13874e8586fa565155da2145f80fce40f0c175f8, + 0x75a76152cb77f3a74ebb64a8b949d032a2e1ef7ef0f35fddcfd89473b5c1e71, + 0x1d1a9d3eff8079f2fd739a8c1ec1a1d2c391befa15c4497ee78e2cca6a327495, + 0x29132a7d6dc081cc6d7a5c3524f2805c9ae3c66a7de1714c4e75a9ed06206bb3, + 0xc1457b4dc6efd6f506f14d2cb839adb6995e2565223add3079801818a2b3b9a, + 0x66406956a8af95c2f8e84f977161005287832eb4860d0e333bc2a6738be404e, + 0x2be8ce6965272c3ea5fef305d80056972b0cc10cc89ba56df234736a8168895, + 0xc624c5b84f86974e5992e2bf99aa7406db0bfc77db799e680ceed051578bb65, + 0x1c9fc7b076255b1dd44a3f77be12b8c0c7136880ef39f02aa002253ff808aab5, + 0x1ed5752920052d66ec89e671965ba4ef5beac9b982b7405174c8c2cf62ba9c2c, + 0x11a79d9e71816d2f90a16813583dbcb286ac19f81016b01ffa4318be074997d1, + 0x2332f2f0231e1a5f4adae2661a4988c773f58f806ad73cec7fa8410327c29ef9, + 0x92041cd3c1f24dc8700053b6d0b4d130f9709bae71ec397d1ebbcd08281e1e0, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x23402a04a12ab3776b14119bbf85cda4e8866dd1c8c2ed209c5cf5a94832d9af, + 0x21f6d7c6cc0750868e0310bb8a7fe02b70afad0229fdad5c5cf38f7231d80528, + 0xaa11c91a5f547de0061ad5ac646b4f17580e985d926dc48303da965dd994672, + 0x2542d51f269de541f7040d7d707fd4d8a045f02c7f0a662e0458abd1c787cfa, + 0xe9367b46e6b89363dc9cfd523f4abb4d123a0af9eddd5e356e63e3d49092542, + 0x13d2aae41f6b1c1b5bdd9c576c7458709c75eeb7af22fe0b7f5d98ea20609007, + 0x19a2b2dc5988a9ffdd458384dd5e0cee7970afb38c1823fe897e485fcda9dad2, + 0x8dddcf32490be94e7be38105e717382f7966deefcdbc67432c312b8aab15a1b, + 0x1a30ac3889e0467ad2178fbd85b93ccc493565c376202982dd16ec9bcced261d, + 0x2dd2470d7ca5e69e5728e76adba044e821425b245bb5cdfd48132b4df5f362e1, + 0x104563d762464be13f51050d3d210162ee31e4b14f0e37202aad99f8723f0ac0, + 0x121b7e910a0ccb4e4d5f220628cd64c2846fc5f470a7c2b6ea38170b9d058b38, + 0x2fd423fe5d1899fe054ff1b9684ff93540bc396589289388681b90fcb8e76c11, + 0x298f732a1a912702fa4c4090d00861d99bbd4eb800b20acdf1c9d4a6c8226a62, + 0x26f56ce61eaed10294727014eb88ada99fe5015c911705cf7ed7bd8f04269daa, + 0xc316eb74780def4c7c08420d1a887d3f3b8028f2d65ef3e18822ba972a50c96, + 0x1db5c65a2d669c928e82c2ba7a85213d03976e7355bd3aba90444c8d8ecbb108, + 0x29fbe3f0b5d6936f4e42cf5ed294e1a18f7c597faefd0087653f06f1cd7ce55e, + 0x133f5377394de76650324177d895cff11b4edb902724138669df63d064254274, + 0x1762e6a990654a18eb15171a84030e43a93481ec520b86ff65263055551d19cb, + 0x2bac62e64e374a494b9ba34ac9cb872ccef42966e1c98c9d12696e1b7b9caf0e, + 0x1dc2f5d192b065461e410a353b6e9ed48f8dd9a5b59e0d4567add1ca1edbbf74, + 0x1e78930fbea45070dc63eb82fa3b44feb8811842c8040f584482e5529b9c08fc, + 0x1161dd83445bc4ac05e88f82b6d4b395dcb7bc08bef6bc0394e2860e1b91a45d, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x2d84302b2f1ce369033aa5de5bb8498f718102642636ea98a13d9f2f9e03d70, + 0x3aa0b6d1722c2e927078f0d0d2a9e1651a387b0a50aabe4c3e9f9e29ce5808, + 0x1851a25520c47c40439abf21fa5b9007ae1557a0d7a737ebd36922e1ec2fe713, + 0xc88238b7bc582be65a3d9780b1c502a8b2a6bbfcf63863ea988e4caf6e75767, + 0x1231dfe4ea1c60c263b7a7f849c8d8cb42c5506161b7fa87e527e917c942c5e3, + 0x2ea0849f20d6ff258c0f184ca8057bfe236245dd4b8642c64e42ef4a1a9d8ffd, + 0x1ba62148f57f420101c599eeca0abf930464f2c0444acb90d2fb96d3db62f7b6, + 0x21f4a3066fad0b05bc69b92e00cea13278d1a5a67436c1f3f2139a6ee79bcbda, + 0x1be4c6e03d2807854d234372f267581058b173ac8b3c7483c6e8dc3352798b79, + 0x369cf9d45a15633cf75d2234f1014f60d1ab30cca21b0fc60af3c0fba6cc06, + 0x251ba00e6136bd990f4db7457a27df54e6e6a986726cb005ee21e173dc9c982a, + 0x290465aa219c5f39fc7dc5b210ce805d70d3137c43ab354abadac718f5357e1, + 0x72153d3d9304bcb121e16ac43ba352e3492aa9264e39abd0ad500003b2c1a0e, + 0x9ef6ef37f5f703229c7c5171a54a9e7d70151ab47b6312a3b592208c192cc2d, + 0x1041b9436273bece36bfd9801372251c2e753b50485953908c35b63979d9fd82, + 0x26afe74d2bbaa76d568a55b8fe35f02e5e913285cb5678ad631654ca03e11f22, + 0xab136a0298a4bbe0d53250d7be1179123aa3f7390c39c08d76facbcf387efb2, + 0x2154df61438fa728853b1e34064bf3bb988f36af48ac6097d2845a4ed924a360, + 0x59b12d8356358cdf3690ca2259447a7147e0e6d33dd5e0c62293c1fae3c7057, + 0x1a01646ed40505df3ebd020f7aefb2dfcd2b194d697f78eb2c6706193e25c783, + 0x27080e00f575ea9dfced456747507b55a0612618d5377ba4745b1a2c007fc4a1, + 0x3b12781eea743ad978032243b55ffa3c23ba980f8f1fe48f72ece1ffe09b1f7, + 0x10ac2c9f77fcd414c3bea9acf7308733892b1802d061fbe3e5ac7d93a437c85b, + 0xea74b2639185bdaa176c285f7e674e4ade050bb08aa1eaafe0a0516d5814623, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x42b91f98007bfadfc37f8c7be01e1e6d1a5a001f4163dec7e6fa8ecf7e5e9c1, + 0x4f0196b4cc4a2fd24b603ca65fa4eb23ce4523b695c34e9323a1f55693f09d5, + 0x20687749f9cbe6aef88c27b6bccc40204246a670ede772decba2f34a61bb824f, + 0x2f9039a4b8b4ab2278d0fdc4b35679678b1d8243ad4bb814b8b7bc3e1b8a4b43, + 0x6012407ccdb4f5accc26888a094e35750aa5d88775cdca0a9881e816fe240f5, + 0xe35046c49cc56a7ec8463053e159925bf55109e8fcff58caff08765476d823d, + 0xad83c2a587b98cb240f3feec78c6578473f99bf7224acc545793094333b700f, + 0xbda24254733d7bcd642ef47c6731761aa67e1ba0ec64e03609d3652e495fcaf, + 0x1eb04acee8c325faf51f6ac53200bd56b052e48806bc12513c165e90c0ea75cf, + 0x25f00927a77b2fc8aea3e3df5a038ef8249bd29e7f6422529dcce7692efd6376, + 0x86ff48a930b5807dacfe436fcc67766ad4253e352907c1957127d6a41b6387a, + 0x22d31103b21aa0b791235ce90ef06cf972c8165bce3c68b3714f89446a42f265, + 0x21f10bef68e2b8437330ebda744e2c3e1f26a92c3336c7de3b645a8f4369dc8f, + 0x2e3ed873b0f6ff7facbee3a110baba8af030fbccaeea386ce3a960bb31a71951, + 0x16d86751cd45d37bedabaca6ad75277e9864d3f6d30e4c0cc2dd25a9ae58dae, + 0x3d059764e5aac685b59387aa484960ed4ef9639843fe308f8cc3dee87e3314f, + 0x63f962a68390a818e545995d2b3d53f8a0a5f0aa23451e6d14b0851ab8bb573, + 0x2d7df484595413f83861ed05f30146f9a4efd46b0b90f7ca9440e30c27c9b931, + 0x5d966e25cf9cee974e405c86aa2a1b7ae63f5a8928e136e12249dae3cb12132, + 0x16bda6eb44145f870e0818bf6f60a068288a5ef23da1bc264e01a11fc1e013c1, + 0x287f1bc804ef51375cf720b680501f7ff1c97cbe98074ccc226d18bd5e18b381, + 0x27b1edf001e3a0a8562b991a2790a5b48e3bf45f2d637ae7b5f1ba7a6ad5822d, + 0x74ee1772d860b6ad09b16d82e458eb305228b24a28c70c5f690abbedf70d506, + 0x218ef3d8be2c4cebf3b2c6a75ddf98e77d79729a0f9d6b111ac0895ebdaba6b5, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x2e130f21aa3bc952d00ba26b10b65c1f55c92f34a51e0d6d6224d2daba241788, + 0x1e6f16db6a97a384c7164733400ef142c41deb040573adb8b0fc71efc2f76468, + 0xda66242a6a2e27b519dd2335e559ebf8334bcb00614dfce963dc07fdd7612f2, + 0x201d2a470fdb240a6d4008cfdebd4b579df34c273ffb66a52ec89962e1a59b5e, + 0x4d1c70932221e3983756ed5d5ca38ef603caff2d2168f5f937c1510775b0e9e, + 0x2a43db76fb42a082375f5e21c4daf3853e9c57d8627c2caee2d837ee857fc6e, + 0x188d71e846b0e63c5d65535a6d121a9648d99af72f72c3f38bc33751e999918a, + 0x1cb4d77c20517ccf346b92567ca15a4b7f7079a150a3b7fbc95b474d2c07d241, + 0x2de6abda392578254c6c2949559b851ca312e5c098ea17bdbff8815ac4216810, + 0x97bac96307e8ecd42940e30d9bde2904025715f5ddc8d6237691c3689635adb, + 0x11ef6e021d4e1b51f156a1c1863d497c95fc1df010d906859d510a2c2d01e537, + 0x54ed7f2b2e4cfea2ea62cb01379d94041481dc85e94cdc4bde08da9b1ba57fa, + 0x16d8390b0ba3174141236bf21283588887ce3eb966b7d45cde064d5cb2a35738, + 0x2db8640099fae4b29bc2ff73424df4851e33eb823b577e4354ccbcb1392ee0ae, + 0x1de2025f4beb8b5b58acbe6126a092ec0a6f3a664325a88e9a28bce898edf98a, + 0x21a514a8d477d92a308095092224f5562af41cf964d34be181e95370590b5788, + 0x140ce2c9605e31576e464e6cbfc8c9712ec8fa2e46f97422d52b0b6401aa5b55, + 0x20313b2273dbcf225f74da13f3e0d0909f47e77e53e833e4a12e439e185dceae, + 0xb8251930e6623b8c062163d973ecdb0f171608c126c7db4791116621f2869aa, + 0xd0b3893c4f70d16172884b37d6242f07ba39e4c7180462dbed175bb0db0714c, + 0x26917b241a12390182932069a99420c31580ecf06449a9fe7871e3193cda0bbd, + 0x179bba9ed0bc1ad6942990e43de2abcd2e7094d7d9fbc02dc2d82b50d9970e4a, + 0x2184a1b9adea49757d59d0c17c369efdc044f11ffa1598f2f3bf4bf1dc7fae58, + 0x65a085cec70ed53a9d53827c7766989219c6474bc5d415be1706e953de20273, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x13ec63dd902be70179d9a190f2e5f1dded28d2feda5d6ac4c9914c3bedcae90a, + 0x272d4b6c21e2f7d2c83b28588f5b0f462919554cf4faab4bcc668ab86c877eea, + 0x12e29b20a5157f1152c41c4e832287b963b6c774de743e4d3d7a5554cc39aac7, + 0x2c73520466905c9230aa6968c6ff3d7bed3130cdceb68bc5a24e51da861c1153, + 0xb370f950332b70ca2c247e2349d2e2e22e2d4a4f519efed6039504fa2b2b280, + 0x1c58bd926fa20dfa0ed3b7e53fde4e4d7bc4df78d13969fac999dd858f0df678, + 0x9d50596628e021f264983ab61a7bad3bcdecc9d6cd3ec46ecbd83bab569b66a, + 0xad3dd8c790db77df35aa78dc84ad3571f0a70fd70b5ec02fb62f4a459bb7d74, + 0x154ec11de0ba022622b33a918364a375f4632bbbd3a6c0c7b8fd77c3831584db, + 0x2bedf29086a4a80d125df6fca693c198a424226bf0eeacbf4c3990b7ac08c7cf, + 0x204ba94b0e1a592391c9fb397701c62d724b55d28665ff3908d277f2728c37e6, + 0x1191741fc0fcbdf5976b32953adea3cf062a2da42a317f0a9907426567d759ce, + 0x8453abba1a812cd70189049a362f26960ab98640e98233a9799ff9aebc15bce, + 0x2faa16a34bc765b803fc320e5c9c3d60cc7a62bc4317fe5996cb5352ef391f08, + 0x1073a4c13414e4f47e3dd58f411b86f1269b4662a27d153b2ea797f3af9d840e, + 0x20827cf24daa915decca0be0018f95f33da122dbc9d31890b45831132296dff8, + 0xc184be1457cd3f30372671039b63894ec186f79ac12d4155c363cf60da9c2b5, + 0x1d1037585c8c002e4fa645846b83aa46d418a7ec475f36a310b5e93ef30b4f19, + 0x1bfbe62e3714574bed5c8915cc913e23ce5654d217fa8933208cee6cd2a7a733, + 0x9ac8a47968e147d7abfcbfb80e479a5aa83ec32fc9a21fd80277a05e36d6900, + 0x6673e8c09274a6b074bac39a9280285cb628f4c90f329c27d3ba1d79b1cc17d, + 0x2a513229a77a36862deffa4a24f4e1d5602d52e7abb7734cb6a5bfb006a14c70, + 0x7aa8c2df4a2083e46169b3e24fb2d0a9867ea17103a19c13fc08f832aa17dc2, + 0x212c78bf0b03c88fe1681497cea1b03064c87db0aa244f061d8135a365168163, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x3a58dde40365d7a0250fc75c67454329da04685e04a51bf51854954a6af915a, + 0x70e75afdcb3d8000ab4d459e8be1c4c0dcac213e37c3443d5d33de59a31a0e1, + 0x1dc99b8142e7cc81ec21bc7e5b37dbe2b29e69c290c6c67aa4fc3a7d4d6f17dc, + 0x2f160a3625bcdb7eec2ebc6a27f6d3aaeaa28e9ab85df1d2c1a34126d2c648aa, + 0x1ae4132fe8261cafe562823d0e2f059cf7917203bd3e1ad0d71b58a0f0804a67, + 0x24d5f4bd7441dd4ccb80955ecb60b72e676401239370ad526851b7b2358809fd, + 0x494f46648ee996ed2e7f654ae6c07216c090b6c4f3599c6eb18aa4e7cb761e9, + 0xf5f67afb9c5934a2d662532a7ecbae90ad260df4189e76f71bf51ce6600ab1d, + 0x135cd20c46aa1a429fae22bac540071d4baa5aa1f7cc662549c2a115e1a0152a, + 0x10b14b45ef38b4d3bd1247e2da3a65dfe290fd02ff1a15ca598b05548d1f93c8, + 0x22bfb1953a1022f21f1738c8067d26e250c3da6d950f0c17a26a420f898c166c, + 0x22dd1a3efcada96371c4b909e8c42dc426e0e040d152910bffacca1ec9dc4b72, + 0x2ec9e354b5f7415057e69782bd7c0db477b2ebc45909255dc90dd3e6fa157173, + 0x1d176d1f403b4a44e598c6dc34fdaf9c08e582e542748d9f18c9c89887a7ca06, + 0x57d65c1955ac40ed215d39c30bc61d015e505e3212fbb230cc61caf6dc9ca16, + 0xc16cadb3191773117e0038e8fa48c9c200bbfe9f61359979c978de8dadb9220, + 0x228354c24667b494d2cd53dbd85eef57c0b3621228cfc75ef08ee11fb331521d, + 0x11dae093fb04008a9d994fc7cf27d09ec0e19ec3ad1d548b5e1d205e97de99a7, + 0x1e24d8a3371d286d6a87358c6acd6757f732bd816b6c77e2193f456c237f95d3, + 0x14f5fa99460312481bf2b2c6082e5fad5ac3659eb5a13978b2bf2a26627d076d, + 0x274f78864eacb329a3ebdef354bfba6a7a5d20aa8ca57917c01d5ea57bf5e449, + 0x1aef2197b2a3930a466c9f2f8ed512af424ee99cdedf0d939bf5323cc13ddc8a, + 0x241e5e13407be4e0e123f9106ba3342a687e6c966d288b3b7feda4af532a422e, + 0x7914b11b3cb937283ee3129dbde2435825df1ed64d760a62c30aebf0ea6d522, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x2ef64fd1945065ca12f48afffe7527ade3289ad350ffe9dcc51b2cb05886b4ae, + 0x1e903fd8974ca0ef97c187e30a5dacd75151b3de2615bb2b832a6c81801e82eb, + 0x20ecf1440148c2b31f9a3c33f59da812efa0755507284665a1d5d4bcfe47ef85, + 0x15e956ab5a1c5a357e9de409a19386abbac37b453bd1ddd174000079b106366c, + 0xde22a61fd6607441d0894264777d660bcfa0cdab9d1da887c81e70c7bb8f7be, + 0x14a1ab44de8546185905ec2bfb7e9b0c8a330266a62fba53b8c5356cb5f20e76, + 0x1427c18b34b9b1962db5e13937a3bbd61a2af9e9b3760eb42ae17394b9c64ffb, + 0x276b0876d63e316c4eb32dbb64a4f4db99aab13bff6d666aa985abba4e9c0b74, + 0x1856468cdd489ea75e75dfef8d33539afb3c3e8d57e0725554897319c692bf48, + 0x23da22d7fadf8ce07944da0d1ab4f4fc9e2d2bb2ba50909ad99c86f556db0481, + 0x1c41fdd0f5fffb3d99ddb3a2b67e62a13e0dbb521bb4afedbc54c7fda3406bf7, + 0xf0bfb6289d76f0eebab2d4b5fd854e030f11672c8f362334290e0cd1f9fa051, + 0x18ac33130e605df004d682d08f9b16b888f88c3e1562bf08a24f7d254ca270ad, + 0x2befdfb192edf72525e96cd3aee3a1e54d4068121a0eb34d1064e8b7c8c44267, + 0x7839fa38ddc35348448d92a9122d84ba951ccefcc88e2618712d4ef896b7a2a, + 0x2bc35b2b57bc9b2be7b8a728125403c5a78c2f4d645da33b408e6cc79674d515, + 0x1f38bf25ca2c67ef958d3e92a44c3b4b80b910d3e10c3d0ee768f28628d6d7c1, + 0x1cd11f045b25737df9183843f5fa01f7b5ab00714100f0a05bff9372f063b52, + 0xa7f87799313df2c5edcaf10983d8abf938467fa5df74bcfdf0d51efeca406c2, + 0x718d416b20114551ccde2747cb6b15e889cc3233fad8a339465abc3273dac24, + 0xb45368b0cf6a77ac6e73ed23f94d5f8fb90a77421972dadc0d70c17ce39cd62, + 0x262dac40e77efee5a07345c63e77e946aa5d7640408dfc0dd0f27be77f97ae9b, + 0xea488fc1f7afec912267c19315412c10754a080c11a7873ca4d027935fa8b89, + 0x297db1b6f71749696ce48fe0862fa63d5f28306715a19762ef8ba915b9fc49a2, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x156c90ff4f955e0fc967223524cad6608e4d9cc8715c249c3492353730d500b6, + 0x1f4644da64c00905c3a6e15ada27cf593998574f6ee744e85fa9723345632886, + 0x10d4e58ed6e17089661c0bccd2c4564df12ebd6c4a88115549e7147491c671cf, + 0x2ad782fc25c4f0db520280f8dd92871f7bed6d0e23337d36df2141fbddd7049d, + 0x2928371625d6dd4de31102aec7726a15d88df0da173ea8a047e46e4562162e5e, + 0x2665ff9e95204c0eba710556e91dbddec9f5060ddda6e898a06b9078d170abc3, + 0x110d5e6488836ae4bc344cbe2406f494dce067adb21d69eb96b43bb7083c0b1c, + 0x16f7045c1cfdb025d926b966bf994728ef8a9647acd20b245ea1c41ec07bd704, + 0x21533d8130aba1fda6a31d4be45e3b6f27e1165cc7acf062d9170a874f44566e, + 0x29b6d6e0065b8aedebd2048ffe74b6ae857373d583adef571b7ef4d8c1376cbf, + 0x2bd0d29ed27a49e3cf5804bc515475bd2482830530485f253279fe3df313651f, + 0x2e5a5bc179f78f549317605f271654bbb727f5b35fa38918a308374a221b30f9, + 0x17aa3fb8d187b2f16771319c0890cc9a814c4fef3c8fd90277eda73a7fc9c1ea, + 0xfecef506e9a1c5363eaabd2e5d75ff06657ea4a701577bcc0d31cec282e6e99, + 0x104e7bc5cb52c3949d4ced53464aa25cbd419273c7159717d4243b8ba3e66289, + 0x2e2d87bbd2649ee3d7feb4a665a658432b9864c9a4d3a5b52bb2813f43af845b, + 0x2a737d085c1ecad2baf1eba7d7b79f76f3385ec88cdf0d8823bc721e7f7d5ef6, + 0x134ffef044d6db42e7de09eb3151188391d4a52ed4df145749fc20b4d0aff94a, + 0x1f46b43cc2e57fb9f22aeb6cd6c9d671cfd6fa043702b613f3de6cf5dcd4a648, + 0x1427b946ca939159e1f36e6a4e88d850c84f00698173d8ded2dd3a649ebb811f, + 0x20efae422eaa4272a255d02f80c304ceb0eb99dbe70e734901ce8303b7e75996, + 0x1fbcd3f2b5a6b08a9f835d2c56ed46fb2b9b9f0008e71fad6f072cc23ecf4e73, + 0x1ab1d914d85a78fbe7db057ad0251cb103d0f1fe4fa9f1565bb1defeadffb560, + 0x185d3cbbbd397b4202e6d2d23a5475ef93aaae25e9c720a849189b38475f3ebb, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x9a33338a814ca4f92e0eb0145510136d27d1a970e859c461b90350506c0ec73, + 0x134919acbc6872a886527ad4607df32a93f8d4f86cbb15cccd389e3cff0d5595, + 0x2988cc231f59a14253e978202e190e60904d3641819600eec68e3bad58e6321e, + 0x7a7e7e0247dfb327857f6cb9b2cf9102847c8c16209be817cc8988f4aee731e, + 0x102415cfc2e84e3b54b636a1125c5acc86ac2414aa2a4a36fca51c0902e99a2, + 0x1205491dfda96dcd74d0ea64c9d05b74a7eb0b98cc4dce972e3c65072ec779b6, + 0xadef8dd1998f07ebf85734cd2d480c380b3ceee9c1669827f9590f1767dc148, + 0x225f99bbe94d5c93ee09123f4655dd2d6bd80aca624e4d8f0a064054e232848d, + 0x1e8c19265e6565151258ea11206b5d8a9356cb614709c31e4167046d52dba14b, + 0x452cbcfd4d1de35a869a85ac1013082dd4ac1470e430452d4a8ea1530f5a3a9, + 0x29bb179886a2e49631442fcaf681e790a8903c96d1eff6647945ed626dc4d68a, + 0x1e06f246e926b517f3de008067cd6bc9f52e8d382c458098bed8c4d2cb183ed8, + 0x92a8624e09cc127fd7d1a32aac8383e510e37d6beca3fa117cbb1355e6eb8ae, + 0x29e31cbd24fa9de5d401438492f9b920ffa56adef762687c61ea562893ce02e7, + 0x1d47bb665d1bf9254c3ea59be757187acbc504b5378076fe029c4570f835722d, + 0x224f1c92c0c3e84e360222c40aa0f4311563bbf62bc9f255a3d7641378a2cb8e, + 0x1021a099460d801d171bb0db1c7972013146d1b09625f028bdb55242d8c51f8c, + 0x1cd67c97e764b8097f62c6402fccdb45a9bd18e0bb4b41ae08c2a25c276426b, + 0xe5dbdc0ab1a14125d19d7eed9cc36af6bdd5fe07f8ff269842f0aeba902c2a1, + 0x1649e0489cb0aa3844e97f61bb769f039f60b9638524408e3425b3f030b5b068, + 0x2d8611f69f27f599ac672277c1f0787005b6fe3c162d836637fc1c890c6c70c8, + 0x19a828de992f3bb86650a8a9f3844ff27f70b612e158170f81b7e6b6f4eae660, + 0x157a427811761757bec0b2decd1c28acba88e70e8e2b3a7b53d732a471572981, + 0x1f66ff45f17e0ec5690cdff99c1ae5d22edbb0ae12aab18ba5c1adae5b36e52f, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x9c9fa00fddcf694e98845212afe04048b34923d4fb41d05f99d24955c609c01, + 0x1ac154fc3f42165840c54a350d8243a3a28f55fd038dcdff628c52e17f72aa94, + 0x28859cb23ee55c27bc363dae264a0494ae77617ba92f595dfbb1454aa2678ef, + 0x1fd179a66fdb3cb0a06e90d1404c50c38d2bacbfa030bcd0b26e6ae454e3f5f, + 0x87dc7319f4e880c7136373d13fd6fdb2e433f31e099efdde56de5f8297a69b3, + 0x1a93bc3018ec7d3475863fdfdaaab0233df37c3f6da5a966538b13818c15c43a, + 0x1174a66194739850644d05a902b25d188c67ac7bfa816f1a3b9b73ac9731c400, + 0xfde9ecbcc6fb8a9ce490e809277b9dbb717369641b96f84b3ddbaafa39d1731, + 0x21d4b10d2e577a751a1284d0d079d066f6bb300db35a9289c5f5eb39e1e4adf7, + 0x1b491207581efedddfcdf23376324b9969e36f6ba8018ec2eb055a5dd6f4f8e0, + 0x12490e92c38fc269311bdc1acd2410502ac8d7b3334e65ab644751d1c6e3ba4a, + 0x3c569375b94a021a27a56b34dfddd14c01f7feebe14e231e53eb811c0d4fc89, + 0x12f5ebe6a436e8551778858bb53f9780439eb09fa2ac457096d7158e7af3afb1, + 0x2817dca315e7d8c25ce85bca47ef2424701c91df547407c8920d4a974eeac9ce, + 0x237f87fb2661d3a16840d8b115116d7b61d99ef94043ea2fc2e311f63bfeeaa8, + 0x13b8b1ac45db6a26c854d447f2750c09dea12c26f6d4083e9e8b3df2428aac6f, + 0x1429fffd68050249e1275110a16addcfb1300f294d63c0b50b7d4764f4797077, + 0x27003d2b7f980530014a1f5e88c4cc2c4178613f657c2b40afc3816ae14e4e73, + 0x1e7c9269b68e8ff2ea5f21c376fff7f3c1dec1df43a0207dd41aad1ac7213378, + 0x73bccfee0274ee3704bac0788527f8708883699084d3ee9facecd19acc02d5f, + 0x1a23c2e99e22f60e0ecc9dbd269a6f8b56aa74bf318961a085e42375d92823f, + 0xb0b38a1ee81114a35eeeeb54d419459b1729450789f14202fb84f009f728206, + 0xb08bf53cdcd498a9fca9a0775d19a3fab7cd6f7709f007b0d2fb07d8ea7452c, + 0x1d37550ee8724571acc9ff409226d2075544fbe2b38276726ad1c8ef3d096283, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x8fce6150b67f549ff898958587c36655277440c4c8bd9565a7ba547580f81f1, + 0x9a3d90307cac625bce9dd71e513f14642153c7c4a411d59f5db597fde888b44, + 0x5e2cba2a305c29ccfe1a49bf1cfaa3f00f097ff163feb7308c40ac654c594a2, + 0x151eb4fa0b1ce608925e2459726afddd5ab7982d4749e6185e5f033d1893ade, + 0x2e3299bef41097ad9e56203ac25eb52612145c8b411375b15be4c60faf9a0e8d, + 0x2b5a4ff11bba3074f0e0c3dd34eb3e21bd00c753717f19509c49e2ca01ee48ce, + 0x1ec7a76d764fcac86c55ce076344f7bbc51826ccba7e90ac703216841fd78931, + 0x19fe7d31b79e7b1a85ae430ba472cf699a814227f0325d957ce13df654430b3a, + 0xc1066dc7ef478b2ed0fe10c9c7a0bcb9a7974a4f782d03f248087fac50ec851, + 0x23b371f53de43570805ed4c382a4e2afe26207f1e280bd963347f973cd8e26b0, + 0x15b58fbe273944415ee68b4e237fad7005ced82fd6c2f8afd13c84eb29488b19, + 0x23d8929ce30fdfb078938a291dd88e7f7a802f172c7f9d792ab7aa6ed0866b77, + 0x340691f3b793cee0cadac0b96aa26bc7072c5d1815117e302afa970e6449ef8, + 0x274ddbc823611ed63e8cbc2929430d025088373ac3be564a44a739d11e4b6ef3, + 0x23a37eb726b1fc29841728eb657191d290fa6aaac92636b177bc582465f1af43, + 0x18ee2248d9512725ba90308696beb3102e7ea86de2719d2c52b4efc02fd0223a, + 0x40a14cf4ef9e74d44383ae681c3ab35d7c6cd0ad5d94ad8fcc5050e203ee6bb, + 0x2cb32996313c6c6cfbcec54c4f5d5b5057bebbc4fb0c103b9d1436726f0b7083, + 0x2b7dafb754789ddcb1dec0ce4ec50fe340d6a3a37c8d81bdeda0755dcb14c344, + 0x13e442da971a4c71620b80f9cad48d7105535596d4b8f1fe550c3ee07328c440, + 0x198e90225a0ed6b87bd847a0102a61267f6cee4d77aa631e355cdcdf93b477d3, + 0x2006cc86ed54bf7a5fc389fa5bca90dcd5269aba4ddeca95de1719ed8ab63777, + 0x889ec7712c598251a59839e389dee66f6d9946d275a60c2ea2566cf586edf98, + 0x511826135536efaf9f5f21aee371125bb78412a608bb6c2b6d97882b672a08a, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x2f10170d2aac17a22b211248629533d81da00ca55cd8d70c6fe1b0689aa550dc, + 0x2a35dc09d4488fcaf436c893a13d4489677901a07f875537c538048ef51dd771, + 0x201b1978cbd392f6ce28a5c8d8296732f503ad63e6fa616fa639d7010f2455bc, + 0xcfdef165aa6bea35bddbdd97133f24fe5861913c9b6274f61bdb8ba42e68ca, + 0x24a14555c418ce41b24b5bf1430ba76791abd955022ba31e9ad2cc3a2bc72868, + 0x58d12e15c9d023ea1348b2dc5c9dc2b43c5854d72e3fe9841e1a2b084859ed4, + 0x29e5bd1a9bad6bebb5aab55558fc375c88a8a84cc5d7f3a569c7553f6b4abd29, + 0x1d203c249094728621279f6b8d53a7d2aca571edeae202f72656ae21c825f638, + 0x1cff362b0f9265141da25915b3ff9e4fd8b33d301a1cfb4f606b475fb5d2153b, + 0x6c0b55e10a02f6a9e5e8653b6f52029e076963f51f5a7ef4c2483781303db61, + 0x29baa73ca3725df97d26afb6e2a1a781059b81f8109082c3db2d2d076ac910a1, + 0x16bc71cf059b627baf4fde8702141c5c2ac31a8620a25f36f0f479a2749be7a9, + 0x1cb4f4979c4ba37235dbd8de125bdd0bfeeda74d1dbc8f87a9108468651cf8b7, + 0x1d9097b4f48e52e207dcb5ada14a004918dca62a16f28760d0516c3ccc9090f8, + 0x2cf444d1a5c6ed508013d34ff40f271027c9a9395cac64e6443cf88ad7481201, + 0x1af6065e84bc5d9f653c36a0c86b0f0d9fa8ff396c0cf722c97b8736aaf6ff0d, + 0x2e2c4ecf622db6f1e55623697c70b3dac0850e0369a2eeecafdca37bc120d719, + 0xae82700364dd6c301ef26d8440a1e0fb71e410355cbf7981fecb0e8ebf439e0, + 0x2b3bc2007b383da42e4f34269a47f629392643c0fd903029da5d60540aece8cb, + 0x9bf1b127c22cd17f462ed4972af3af610b5beb2818a9f405d852a168de34c87, + 0x1230f23e20b6011d5c3871017482fd38f82923d9eb4fbcf6c4c12fd744c8b7f, + 0x1b47c720f543277cdb27fd57b57e4a88be4a17f9367f5cc58a541ecd995005f4, + 0x2550ec7018dd8a12e43571625d58cbffc02e10c95e0e9297ba171d6087dd799e, + 0x2d357b96b3252065e81b5f1406be8027ac20d3919c668a746fec4e3205260dab, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x8500e01d94de904d7223966859b160af3f73ee1f67208935a726ef1f04a21b3, + 0xae88a58cd6d7dd1d38d427daaf10cbaf3be27e5abc2c2dbf94e6f4782cdfeb7, + 0x2356cf14cd716531ac576e30978c3e9af33fe0f5465c6928a70ab06769fb7c2b, + 0x4c9cc7ff1e61240f1c0cc8239aaf4522f564780415fc47bffb1c28fcdd5efed, + 0x2ac119534017f94c103fb6199dd0c4bcf237d435294d16269d69dc39be170eb7, + 0xf0389ce2af0f62066e0f0aaab541c7f1e013fa0edd0bad0c454a9befcff9b60, + 0x1df984d5fed72bed8d287cbe3bbff9ac811b56155a8d8f768b7222620bab2ab4, + 0x2464b6b8837edd47eb61562a8c1339d59446dc30b12bfe3feb6a676a5754fe1c, + 0x11e670fa739dc17de5939770830d3aca8a79190d413a8a69280275aa8848096a, + 0x8241341db938388de2e2f02c9f6dab7f2040a2a0fb2d674bd160c8fcf7513e1, + 0x215ff7a8bfce31939d8413ba030f72544092ebfe06f99f61100a6def22089576, + 0x2c7cd496518937ec37c1a7ce9e231f15087c0f266a2b6d894bee197b94b9cd58, + 0x9bc5b3a291f8de24754a6479956a704772bb305f1ab884a7a57a49c6ebc8d97, + 0xb15a0dfc22c6eba5d6617504732df69e30cff2c417d0dd2f1cb49545a026368, + 0x299e24a6a2df4e3dee797a9d9b309af7f38aa11c61bec87b3d9e01bc1b283474, + 0x14a1683e0ced5006fb58bd5f1e8fe10b5b4d5db8af6ee11f3542683d5cfa0e6e, + 0x25595e5888505e87a18dd8e2f3fd998387901198cc9823557e34167d2b6f4220, + 0x1a8ca160cb03b1c6e074c7ea982b1bb406e4b996a70f430da8a7855435dbcd8b, + 0x48fa511c78d046fa7b3f960ddba5eb39e753e40c03e026a13fdf2509362717, + 0x28606b25ca030890e0ab9d58ccb09875465d368c8fff1a9401a18a046d929341, + 0x99c988ee50b5a86686570aade7a07d7f3de7d1ebbe4a72161214fe1f59501a3, + 0xd423b8393f806bb9445a55f82aaa3663b257bce07981b55a9dcc640f9b3a6bb, + 0x20fd15ccaffbde08b904a96f9a18ce5e411128da59c299ce6a1886ba554e8858, + 0x2b8b731f93bbfd2ddf132f1b9f37f820ce2efc76485de21bee2229d03d986e54, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0xbcb4654350348f216da47f8a9085a24211feb151a906c5852a36eb7a590e5e8, + 0xe0bdd096a483b3c7159aecbfbfa52a4b66e7704b05a7df05c3fc79bec0aa903, + 0x2cea662f7c24e8a6111990ca10f7e539dca435c022fa5447ad17f1407b9e2c3e, + 0x260494fff3079a35eae887c593cf5791509815ae31538dcd7432ecc6c00dc0ce, + 0x15c010a4fc6cc1e54cad7f89188e2392df27f7d6fceb4958b7ac68c23b8deb0f, + 0x2f199edbca4bb59669b0e4ddef33a7b45821852699ad8b03c8d3dddd75e8b58e, + 0x1b63017c3c4dc94e32f7c17d67a31901875b20dd6757cbc80eefd96bbf73685e, + 0x21819c86119eee2a93533cc0557b7095119a6c6347e702aed6c41cdeb5436677, + 0x2c7ae6aae298a99a0dc53e2a0aae2cebb636e83e80f8ec2c0ca5e6d30c0de075, + 0x241559cb0c89c416bea1ee0866c17aeba29fdeca75ab98d2890d7e10697d7eb5, + 0x21de885c1616f460af9be2385dcb90a8a471f9cb4a4be8e76b45d0d0fe3f8e50, + 0x179ba320374c3c6c268f02176e13cb0d883f1ae24b145769035ba0cd28879e67, + 0x1ce20457c1471d83720591f79a33979ae70ee1e3830011d9494b7686f90434d5, + 0x9bc17ede919cfcad02017b4c83cc9e1ca6d4695eaff8e983c8451643cd7eb5c, + 0x10993c2085ece5f1f09343dd532543213ba3f046c5a39fca941374a9e8975c19, + 0x11e0deb1da2857341a2c4e2e59d5731fd240da2dad90a1e815b706f926a8f657, + 0x15313d500d879d6db9446e5465f9c08112330c9d1dca21b1cd298117456dc175, + 0x1a3da97fcba266c29d2f3b755892c4438cca1703d3685fcd263728372eb19dda, + 0x1ac3bc17591802ccf54210da2d2bf627725e11a8605503966732d16d82c7c0b6, + 0x13fd9ff54bff1a560857af2a620b2cb2d725ecdab99603c58d4b3d8311f86bbb, + 0x10cb890d09d7922b970d479473995d79d935256c9fd28f62212104d69f3c38f9, + 0x131649c6c37c467b3f8d6bd684c6cd121e1414ce5a2647fcf8d29c84fb22646, + 0x2784296e81cbe1ba5262170b35d24f5a9f428577c73f51888deee3bffb1245f3, + 0x262b646e6406d39067ecf4cd1c4e7d6dbd8f0929a1fa778906f709b8ddec0a7, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x2b78023b50bcfbb73b4497ddb0b519c703dee853fbb53438f906e8f03379822b, + 0x1834d6485429196629dfc50775e881aa5bc653d6186ebeaba1fbfa70d5459977, + 0x1e223eca065f07910015985c8185846bc6104889355c02eff9966f18aeed7383, + 0x21ce2cc395f1ea9eeb8a83f76d5ef268964304f891db51b907b57a39d40c74c0, + 0x3010da41b7bd91017bbe2f73f28d4847f1b15f7caae6f197c51aaad94942d5a7, + 0xfc7aa208e89f615b2b5ac6c1c84db0c87ed0354d3da012a505d3718205f8898, + 0x13153924c0fe679002dc1912a9669bde6c0bfc56893155fdf2e96e05a186b0aa, + 0x1e7ec9ca715167872d062b6a2f92ad6b425a3aeb45e5a44e0798451a5f3c6af1, + 0x1839eb87798ae0b89e6ce405734b770fa2e6092b0670b2f59fd93500ba32bc1d, + 0x2bd925800a8f95d0b2b6ca1ae4aeca0fedac4fbc889f464be243aef61e35d531, + 0xf1ec631ddc6f753f4288baaec5d90881966062d8e00a94d1c35caa5c1f87d81, + 0x9ab5e15c1e1cf58d46c55f0df4fa3a56cf3a41e52664b1a125bf3388887a1f9, + 0x2048f6f68b4dd0127d915cd6d7056a0104145aee77618077505619117f588ded, + 0xeed124614cf28d97c99c85a0a1456d303c6cdd2d2703982a42dd688b65559a0, + 0xe8fbccfb62b0842aaaaae01e8418d005687d3511606ee56c978d0dcfdebd825, + 0x7823b7784daa9ff5853129e7555f2fadb3898b5c4cbef6f4dd5d7e8c78bb73b, + 0x161e2a1db0ee0e75b26abf038ff6ba8b396d0c03d27b794a2eb64394680db0ed, + 0x2816d7a51708d99490bd97f5443df9a5203608feb1bcae4268d3da1e5198dc79, + 0xb298bfafa57aebe549b8f2b0f98554ae00a1761427298040bc8104ad81843e8, + 0x5b5779be0c8c88b6ef985df851f754310267048c6e68139baaa4b41d02cba63, + 0x2954e80ed49eb91d655f32571d6ed24724dcd6d013c62fd8daa0661b4c2e6f75, + 0x11f97bde1a830e979a7647e0eaf37967f2fbc2952bb50ca4575961a34b43ad70, + 0x2edabd7a99b98c5f9f8570c778e460dc19c4accd2de09381db2ae25b87affe51, + 0x285b59b5e4153c7188c7e918dffc0ef798d15695c9fa2921aef01e87bdf9bf98, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x8ebe850428b3b2e7534420e85cc70483a11f33d2b5fdf04f61382f7a12e9594, + 0xbc84e22a29a0c39bf8854d51235e45e1857ea3575fce20e891ea92d8f56de81, + 0xc546f855e8fe5529a31ced2d538dce04cbcc05379ab4f8dcf5a05b8e0030f98, + 0x4beff2ac6db7fc5ba1a66114ef2591000f8822497b661cf15e052719c05209d, + 0x17fe23f62d221e08af428582244a3a31d64a2fbb37f58f8e94bc719b2c4291e0, + 0x129c6ab33dabbe60b52c9444dedaa047775dd01de878636cb80b7d014fc98606, + 0x1ecc6d3b8bbf86ab614c85e5cf2c5dca31d86d2abc8ce91af23d37b52ed78562, + 0x2fa06eb4828858d3a737fa5170fc77e726e8a0cda438a8925fd55e593e204419, + 0x123d6c4cc8a7fd77c53de32f88e0e06bfdd78986842c8691cf7f3aedc43fccfa, + 0x29638f75c4d7ad4d6da92cc3681384bcaa6bda0aa14503de403f330f87700abe, + 0x2ca5b3f0ddb7a5c6ef388e33e501e0fc41a8b16858bfeb10882bd838238ccde7, + 0x1e7e20601229dce04a57f23005d7b8ad0375d4efabb3e276a38a0cb2cce2b7c2, + 0x1bb9781ae7d7cc141e7b72e2fff39fef57bdfb922f8ff88bfbf395738bed4043, + 0x2617acaac7e8547ebdae0bf2063a2056e5b42e39283fcef6578b256fb8ae01ef, + 0x1524426376418adb2ecbbe82913bcf05a08c0db6b1f3d80b5ba1771d72b80f1a, + 0x23b9a081fb49052cf4b2521ff600c471b22cec1c9b9c32097bc91192099f0b44, + 0x1c6cd0f87731287ebb12883e63991ce5aa8c768499f5c976285019b41ad6a272, + 0x564f9765361d0141a69ada9ac521ba33139a1bec81b1c39f9fc79d56f93d89f, + 0x18fba1f537d0bc06888730bcff570f62c8eba352d2890666846ec5c102bbec55, + 0x2ecd94fddc5654494fb41d46c4c91d264b3e17d5f37791df25a42cb680e12a55, + 0x25168b700310216d4ec9fa5c3e3514e712d694a46f169f7791bf4b01cf23fa0d, + 0xddf38a36dac9337b4add0d9a33a2c589134aeeaf141ec5a5b059db0a5466905, + 0xee74216109c48451af32cd7914b41734bdcc37c60e505a9845e5689313cbdf7, + 0x20b4aabbb4bbb48c4fa8155538d772088fc0ccd14ec9ed274c7f3356f9799e0a, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x18de85783488e68b46584675ff74d2bad45d686a789aaf80f0ccf3e3c331d973, + 0x23ab29889e8aeae37282dae6aee3a16624f058208c74af503deda66641d5b82f, + 0x2fbc8d06de03926ff1c3114b375d87283388625872b2966b781d26fb2ba5d7e6, + 0x219e0c4d566bcb09609118df2231e65e9e95f6b6e1c6149617acea7083fd9ed7, + 0x5b21b2c119617eea6edcd24e1feeb1cf75560b65b80af1027be2e1f14a15d9, + 0x5456d41afae3296fd4b13f8a096629d0b471691a4a29d9fbe2493c3ec377ff, + 0x14001dcf0234cbe8b3cf799bce377883176a4904360f83fb5908b5b7df92a447, + 0x2a5e9fdb1272447d7e50bd0ef668bff9fbc860f191c1e0cad1560e74f6d231c, + 0x22949879c5b83ea97413d666ae0eb3739decdbaacf1a33742bdc04f9e449f2c8, + 0x21eb23c8742f8d498029de7d0170a12a031c49f992f07a96af0494454e37d96a, + 0x70541062150a2f25267a8476f41bdacb2b3579c7856ba4904999f92d0b32bf1, + 0x2664518ca87044340bfd8c5a7c2b863601b8226dd566368da36b808691b9454c, + 0x14aa81c9279f3505b744bc86c3acafd4c5b03da18129f6a2b67d73a9d8e7b5db, + 0xecb94b163b561ad361efd85db88614c69a89bf74f5ef3a9387556ca3343a303, + 0x5a6d9a1efabce0a10d3389ed1571283698c90e766363859acc910968968b676, + 0x16b4dd09c4b2b3942c0019d9d39d4212626c492b7c0e7178196899f497f83082, + 0x460784ded949d3691d5bdf7d6029ece2deccf562f0e12482f001714895cbc9a, + 0x2d634ad66906cd6bea2fad599e45912c992901508aa915f0c219d66373c4f7be, + 0x1658eb086b54351ec3573b8ad8201f5a4d1f0026b8f04aca66c44c16e7516ef9, + 0x135a011e081cbe5475a1d316b78c724e181126ef44a9a352515afce9665a9d92, + 0xb4bc94836903c9787cd22b2962a05c42c7bd08182da579e277ec3977418fc64, + 0xa0a37d07785069f47e18f245effcfceb19f2405ca009947c9d2cd95673d3caa, + 0xf8ecd23da135c880c76d216fbda0267d32aee2b4a8039aa5783034d66dda113, + 0xe88eda335ac1a2204aac356a58a3ca503ae4543881ddd282bf7492f253e1930, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0xa4da37955db5d2bb893a0919e4d928361880aad89e87973b93638d9f46323dd, + 0x182420fd6b1d8bb94b35d9587499825eb5055d95f24c5a061f56af516e71c5b8, + 0x12ed236d1a3dec40061f9af7aad3cdbde95e5d41763d8b235c665d25b01151ca, + 0x2d2c50e36f2c2c402493fd98edbb914d591700011d383e289384c0fd26e46088, + 0x2e8ba0e65f5ee53abb58da0c792869bc7429749fdc88ccf7a429c1f35575c11, + 0x8491031ef5da5f6a50fe3e9fe4abccfeae091ea0992cf72a239d0dcc7000c0c, + 0xf4894b8ed58741566403ffb6a468cbe036e365d3b391b72bba73b3f916aed40, + 0x22727bcc3e3f1e76bbba95aa7aa2eb558063af92b5f624433aadbbb0ff33c700, + 0x1b120f999042730b4d2e9f4e22c528510cc26f6076905f37d5a3a6bfa19fd87f, + 0xb37ff36e5153c7abc2c0bd36db33be84dc7378340a8c6259deae5d1422d2f76, + 0x1655564966b05b47d171db24f81917a2296777b02cb30f893571217662009b93, + 0xa64dedbf4dabe0685fb8e4bfb4db52e4a3e1bc178bf7f49f1335bc3cff8fa6, + 0x21a953f0d0ca1d43ee920c54a8a1884a2dc58366e195f4a03270587bf385ffc2, + 0x228dc2c9d913d4f4588376be12a9cf6d55d7c59a14a15f9b8ebf8f0cb801a264, + 0x2b487e5c9abb4812830141572d8b1936b4b8cc3119a0038f773f3bcca83d49b0, + 0x285712493e67ed422052536731a32ab1920437cd807dcd658836beb912022bea, + 0x26c1b715b64f4ba9d47c1f97d99f91ea4b83ea105203bb5e4bbe8b3e6fabcc95, + 0xc188a42d4758ecbc3d35a73e735f3daca1295d0d93d01eed6c3a085ce1d95e9, + 0x2796103374b26554557f1efbf137c3caffec020e1de9d2e75f8a51b5dd52524d, + 0xe1523d8bab27bbf5fdb85ea4eeaf57bafeaf50481cdb89b80483698d4b47604, + 0x172ac77c37aa38790506830facdab06d091a9a98ba0a445020d87a548e68fdd5, + 0x1ea828b052ccc8c21c1417b2479bf21dbbeb8b07f1d294542e6b776c17a46ca2, + 0xc530e36f104f93cd29e9d5f6cc76b4982c8f06d52684ec9b6b6dbc6cf3e1618, + 0x257497d432a5ddb934157c1cf3218a104aa3fe58ec7de5002f82be85ff4a2992, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x9b0b4483df9298317fb5b068ecf3291dcacddad122d4f98ca84868cee25fdf6, + 0x1569ffd3186a443252de5569661c3f8eac7dfd987568aacb86e576d3f6894290, + 0x2335942544da68a26bb05c3c44845f0e9612fb8a6b33a4bd81b0da1811b1538a, + 0xf3fec305e46f3dec280a826087df17baaaca704840038f56f94f35406e6571, + 0x1c4fb366b69eea6c1ad580af7130f33ebe1ec91b044ea1c5697bcde572bfd4e2, + 0x11066a30034b0f5a0ac2e2c5d00720c5e11c1fcb71fa57e7c8dac938e7f4f8ca, + 0x136aece7d25ab58170f452dd50dbe69b1f9a77f060fb99b0e299e9bdbbfd244, + 0x656fe108785a97dff386df1e4e2edb6d68dcfc9cb961e7d44ab0d14847f3810, + 0x2132c9a946b2cacecc75bbd0b90e0fd7f1c864ec818a13cfc266379a48740a1a, + 0x26ce19f30359f871b860f7e740e1361a8dc3d4faca80890059f68742b50c1bb, + 0x7b34bb73c69a8befc171d04fdc512c2e6d29993be2aa537a5a927503d327f19, + 0x1d2076ef57a75151297521fe1aead57b361a0cfd90d9c56e5a4d94a03aea4d59, + 0x18b2d7645f44465de9d875354716726e36f092b43e11aa2feb4f749f5cc30552, + 0x29d9e936a88283376c4cc4105b7bde94ec648a2b02c4be0325ba0ee4e8e59466, + 0x8433318e395064bc720a18cda24df578cab51b13834e03f8303e988a8ecec7f, + 0x2981efbb1e761374fcb20715527de197d32cf4d87871619b505d3f5f67e0cfbf, + 0x28a84e7609bc4d9de494b53068730c0ffd154de77011ac4baa3a00bc1f565c94, + 0xb98fb0a42ca497662d3655e0f0b215aca776b94b0e842e7cc7bd80f6aa01470, + 0x92dfb1809ccdde8ecf61a6602a69fd7ab9ea0f883798425b9ca464637ca1feb, + 0x2229fecf42ca2b725ec5ab861ed051b30ad8dd362a8445e6e7f6e6d888cef6c9, + 0x2efa745708462a56d941659e4d63bbf2b15d7b5cb00f57f7d96de4987e0eb545, + 0x1eb88f6512326db22d5bb8e8ab1ce26efb8b551f8d6010438d0f26f972c9c868, + 0x357f464028357825ef34691fc07baabc77653105a5f895777bcc9fef6e4ca9f, + 0x2574b6b6eac59402740cd9ef0f50e229e4db641825d2fd7f0018dcdefbae67d1, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x22cd7ad481a520d21e467b2fa248d2cb54462c3dec29de294a16787befb181ee, + 0x1ea716292c21b4a96dc9e245738f17f364b4a9dd5cc762c7ab0a24b8ce63a95b, + 0xee07db295084e877f193bb734548249c566945980a987e853cf283e0de49c43, + 0x237a31e787ffab6bd803d4683ca9a5bac9ddc21219d119d5470a45678d916af5, + 0x22d591498fce7c5903d695cb79fdcabebb591fc68fe7a8ab4376279f3c8799de, + 0x25730debdf5daae2460cb78aceaac1540d1b32c4ac3fea8494a832c0ab9f4969, + 0x2f54afcc0ab9ef598814c0a9f83a16d44ec48ee96a06fb1dd7d8414ef40bcbff, + 0x110855e59ebf6c99c61bb7b3728db0141b0c7eb6877e3d867433277bcdb12ef2, + 0x100cbb38383038a7f72dc76e0ecb80487a1bd2afadb85eeaa6c4b38a6e2460d7, + 0xcf9ef03acb7eeee16d21ff6eee6b658c426551d5a346ec3d2226a74b9bbf085, + 0xd047f79f1c409f542bcfcac407087dc0968f9e0b82bc760d1ef72639bf0d3b3, + 0xc8d35b27373860acee2d851f3ff195897a5429797a40948ab0c18dd279cd35b, + 0xb34d4ccd429b28324635894a84e2d095c29ad520bc5434bbc004e43b79a3f90, + 0x15aa8094e890c3ce98ce64cd97f7c21445ceb3c863bdf8a788d49e233cc8926a, + 0x11637553427ccd52d28ef04c564ee9af0647215f7f4a764d97e34b3da65e664b, + 0xd77424bd2852d485495d929abc8ea1e5c2a07a938463db4e75b35f11646ff09, + 0xc48776d02d737edc95da3941a1f78a976c5051bd630deb38b10240cda1dba1f, + 0x23efafcc9a8ff43a2ee5067e9a631b0be21c1e4f028e4fa7cef38919e4f149c2, + 0x24dc88d6144669f65e8c8b0e0b84081de41ef00c3f872dabbebaa4ae3db80522, + 0x27b45f6635340a77f857c72220ab866f70739196835a22952186bc242cd69873, + 0x704b24632239ef816e17b12e0b1f95c1cf7b8f3367a263ae87cd628582563cd, + 0x176cb4987f9f3df738f3bc87712a4635656b484c52ca7624bd1245c2aabf3e79, + 0x227eb80636039b0ae67aa169b29b1ff9966feded7d239c51c6acb427cfb61f9a, + 0xc315aed179cba6ebf5470feeace0db2e1693c9fc11931f51265541c508ca784, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x1b8b75d83e3e955dbb4063f6ef293b4aee18c4a3be9227c3102d29c2a85df08b, + 0x62a3721fc4009918e908846ba5635032aa2eaa7489d5d74b13994486e1b621e, + 0x1f58606cb7e61fb55157784342ec52455c66fb882e3360b692a4677360134a68, + 0x41e93249e317db4958b8849dea281ea81d0e2041006620c78636354e20c45e1, + 0x156d561a4bfbc4b557aacf5ccc4701483f4c44c8256e619b6f7a7dae09d23c3c, + 0x11ed5fa9b46ad4b3f57a8c5084724469f36ba46cec847825e6245c4537a0e217, + 0x88a5d5188be741cd0e0ccdb10875d3fa01889e4f80e5be6ea7e127d5b28963f, + 0x271a632b843846485e2ab0f5c7d1e14f7275fc53b8cdcd8a743b7566461219d5, + 0x26c0a1c6632015e8689db93c50a3dc2e408d3c0521774aac099b931d7295c6d8, + 0x294070b0ef4e6a55e885a12b5874de04df23adf8f0a84f875cb18c4ceb8d101d, + 0x2f78931d96c5fd9d0ff47089e98809c64f5aff58b2d70080998bc0fe5e364303, + 0x230be21d8ea9e4c5d2139afd1b0eb61d14b227ea864c09175b23ae4a647d67db, + 0x23835945ae05c678cb2b9bf9100f51e7ffdaca93e74329a968c392bba321a232, + 0x187c39fab3ecc634166d78959fae651ab19b169817b7e508762ee36e8a88033d, + 0x194c8955c7e620135e624ff5abad58e58b5332c390e60f772e8b4dd477270dd, + 0x651970e3e8b816227d307071d84fdd9f417a2f1b844b7ec56a21a7b0241a684, + 0x188d9c9d0fbc3459f6a82532f1109a06c591d2b37df750c287244908f193eefc, + 0x3b8367be80bf4f8e3b9008aa9fc640b6cfac804451c91a6c51d60840f9e166d, + 0x8762e109aff306b803a0c90ff1031403458429b82dad5066a7c61c4fcd52e10, + 0x7e877480703f745c67b8bcdd6a1182bfabea54eec3b62b87f53e9eb6da0d5bf, + 0x83a1d0511d5576651a78abb8a14ac92d9d61a43f977cb5dc9befe2150e0335a, + 0x108f56572334a765f54db2146eaf1b44fa39b91203a58d3771eea19e46f3b58b, + 0x253717f1b3a60553ba8c5608d2e9b33db2e5aae1cdda665006620589183158a, + 0xf7d259d6a6986193bb88f21b9f687548b9793b1120e10386561ca5be801e762, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x2caec1da928de3ef257ea69d514c718f70d8d3820fe135dc81523d2e13494c2, + 0xffcc49b0327d4dab23fe993539c71e78cece70c65060fecf775248a4f3097d9, + 0x7d2f814a0d52f1676986648041c5ae57ec9b5fa328dfee5a22206c0f554fdb8, + 0x563d7a79d5f32dd2397acda206a6fa4947572ed4050aab01dc732ffeca2369d, + 0x2783fa364653815b9474a9972f573d171d08b4dbc9771054f0bc376a70eda070, + 0x26d7a7687e6c207f5fa597c84565bbe9d511243c1917de8656babdd38ba0eb81, + 0x1567832cd70e77ec20ef1041351577510628ac2a1c7d5c179c98315ff78c42c3, + 0x1c59c4c25db5ec760ad403047f3182e0c2db7b557883b227f8bd1e384a7b76e6, + 0x2fb984c5c36a06d07601fecccbdd1466c38f2ee47b7dd526a34bbb9e859a1fe5, + 0x193c691789f6f175105e969cabbbbc781119daac0927a2694d006edbc0845084, + 0x2934cca891879574e44e4b94f5554dce2e55070b19de421b4d2b743418b287e3, + 0x2223f7dc3c04faddc22f1c05e786dd4fb2837a1425c62d4defdcec15ff6fd6a5, + 0x267a1cd4eccdacae7277169d9000761606b0bdadf24dc97b6b50ad18f4084e57, + 0x23674c9dff69d9b06d1a41103f5b241f788624c972203d3a4804e2043eeaf97e, + 0xc86000f5a940dc4c26b7c2dceca10416c0de08242d8057506a867b181691451, + 0x237c120402aba89b701d7db41968e81e7ca9e63b6242e56d9e89b1e94b7b56f5, + 0x1f2adefdfe27e85d550a268e382e6af8e51b93d0303444311050a0bdc3a86b13, + 0x21026ca9e6c15e7e7754c24c15ef12d36969bb2505ea8eb9d24f21762063639c, + 0x257dbf207d8341ebe71a25c67f0bcfc71edcf46f5e655c2f94bb0027683e4ee7, + 0x297fc3567244be37e4b1ad88a0c3008e1f1326146b6588add2e12b812c53c7ea, + 0x2415eeb2220c514b4b50cee8df2f4f605477b540d75325287fa7df4957c388ed, + 0x2d1efae2ebd54890a00e868372dde24a8ab026c7397b54827bf51bf259371921, + 0x1f82db95c67b46b630a40310d8081c760e1bfffc39e91f179b99995a8e355615, + 0x2e817c24b08cf9346a21658572796f90b8132b6247e43a1d099c17b7823592c6, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x588c5021b24ccaee3b77fce64c0122f3cf21280619404967af6be821ac9e37f, + 0x191e71b4c665fd095461c7eb21794e3770c3b40b4bc0e22a210166e9c74aa0bf, + 0x29cb8c9eb9c4cf5bc6e1c2a782ac0503015efefe2d640a154e26b4b934dc9713, + 0xec1e3897905c451e98b774b636e1dcb80edbcaec959ba90d20a0286366ff74b, + 0x2ab786b7ffa171bb876603834679f4be8a18485f93b7b89f2dafeff334d5469e, + 0x204bbc64ac07613fd02f871122b8ef0206d670cff609fc1b2fdef7b8f1e1542b, + 0x1172cb8f6bfe22d7851f746626399b3c0536bdc6f8969c3b5ca6b697a87aba5d, + 0xcfcac24e6e99ac6a59d2946dfec1c87d4c14c95a9ce2e81ec8c8405f74ea79, + 0x25787156a9a5949b6493e08da731b2e15abb30e1d460dc238207d04302a7378c, + 0x246ac305851f4cc5079ed10d769d337af9649c46f374951dc674b2734840fe38, + 0x2db9cf683684eb9e2cc772571cf8da1bca70e222aab6ca7e60df039de8b23ff5, + 0x166212a0652ef46c22f6d8d8d8c53d99fe339c7aadc68b233c882f57925403eb, + 0x98c9afc1526b5729198f7f58b905563596143c611e1b2c8ff90dffc677d1e66, + 0x2358d524ec260f839956563785d1a727fb364547edecef5bf664e5706301a599, + 0x1901be07be45b4f8d3380b0a5e52c1e6aa94dc4f6f2e40baabb9f98fdebc91fb, + 0x92d99a4ade91479cdf8bcc22c05309ba07d86401532aafdff17bee681dfd12e, + 0x13af4969555a7dd69482d1c130eb70e05f0f9af3a93769f7fb5437173c71e1f3, + 0x28d3aae218aa0b296476d0dc373481f4ae746de4aaa1c8328370f17655614a51, + 0x14311125be69290b098c5ccb7e7a9534732886959d25d677e564d71ae1ae7647, + 0x1454832e2ed446d6ac9a981f567c57663450bb35ed147e4dddf8e7fbe30b0bb2, + 0x11055b5dc675e97c22358083da749bb066f8a99cf11a37083c1c991af56736b5, + 0x20b2ab6a88373738fec32590661140fc911f31be20d8a9b938717954ce5f1720, + 0x2171b013bb62ffa512500bb1ebad0e10cd39cc7094cbf806b10133a9f6ce3d68, + 0x13d9ae507067e98e67ca97ac691f2808251ba846c97091c99e46f8c03d6896e5, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x292e6fe5591c886319d394a3218aaf4a8fc00b2c98fc57a395ed2b52d72e5d1a, + 0x2e555bbfc78425a4fb2d9d8922252a1edb14ee448532800a36538eab6d3c3134, + 0x4b797fd25379849c5fa7039cbface5d5f01d17102671767c51dcc547a7c7f44, + 0x2bae8ca68718d729374e99bb9991ef4399fb9a5a14ff7361c52e4785781521cc, + 0x5ddac723ffda8067c2147fbae890884bf8572fb7b30810101de4369defb5612, + 0x1ec8e17ebce279adc46dde550fda171ed22736ce4e102cc8e36f3844ac67d77d, + 0xdc57f55bf67c1b68aa35126491d6e6b78f9883b5efa10b8f695e2a8fa0b83c9, + 0x2d3f4bced64b64b958b8d91bd0b7b168ba52bdfc7d5df18bbc1a176fde11b23e, + 0x2f10a6d7f877c814bc7693395dc357075d1c816495a4f03b0ba49d6d8d97a663, + 0x144b40fba529a8d725cf78c898112fc3e4826c83c1961332ed3bb0e17051bc67, + 0x9708226dc1bcda85d36d65ad6d0ca69340523e970daeceb5cc48c16db6cf3a3, + 0x1bc361e4208a017e152377add553852dae1b334c7948e008f7064f499916c154, + 0x218d7075025c32bd6ca4e15ccce886ef42a54823955d50d1abf906be69a1a10, + 0x2c36609083d08ad8df8211a51e75bc9b52691cf5c9996dee6cb39a13ab18de9a, + 0x2ee25f7ef8fed9bfb691d8a5e21717736795bbfa76df861492715c4b41261112, + 0xe02bebff560e49b14818c02e1535c5cae326071c0d74703b8ea9f1950e78e5c, + 0xa8e935c09bec781f68587e8aea897db4d3e8d643d4e8b65af941e6b56b35d82, + 0x24e4c8a3880c07950af15e4dd7785fdff4f46709f7e8a2dff46ea7670af9e69c, + 0x2d680316bb7fde988136fafd42ba36dbed8d09522f48ddb19a14d39e2305e4eb, + 0x151fc0242f88cb4b820f7960e519aa333c50260f1fac77ee841873ce4830a5fc, + 0x2a930a97b841a2680717d8322c463e7b4258340f87258c90f388f322b86a173, + 0x1a2d3151d244173a73624601b54782801bc6c0f8f7a70a3afc708a23b0af75bb, + 0x30ff291a9139cab6bc0b3568c21ad6e4542cbb3c6ec6970f01f4ab3f4e65a8b, + 0xc6142a38ef9e3709c786cf42056291aa1581aa5cb1e1c2aa01326501552075f, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x4478466a9c94183c431e91e2d96fad76caebc38cf4b6bd63d40a883887aa0e4, + 0xd2089c7872a5e0d120339c683d1243e0f56dfa30bd8ee38e9e9020be57cf9d7, + 0x7835f14f646ef12bfae699393ca8771079e5e5b105c549a6f740989bc71522d, + 0x2eb138b8e96a72fed66f988d76a56425930f788d23294bb16c006c15ba7a830e, + 0xd65fc46a4f555afe4d613d16960139d1b0ab9e97409be48d2c7d0ad708d57b8, + 0x5cb9d6fb0ea5d7c36af03889077124e159baf3f95d68f5c74b98db89b1fc3fc, + 0x1228b6eaa51d6497f12fcf864b7dc9d681b32176cab3dae788d5cdfd5fff3732, + 0x2c74a92c8d33ab0a358ff988fce0aa0ba475c783989734c9bcef6aa3d92e39aa, + 0x1800e5ce9cf840e32bbbe62d828c95e79c3e1c493ef70ff8743a88431b34dddd, + 0x58ff670014f46b7ba4bdbd48feb903fd37fb5eec4bccf5af21bda415478ecc2, + 0x21c73fcf9ad1b0107fc527d61e6d1a289ca1eb4616db1bf402579c7a9f141c61, + 0x2dab5b1427ba55d3fa1a90d83b0c569978e3ecfa9247509dd3f9e303b58dd0c0, + 0x13b905c6ad4434dbff6e782cf470c7f37cc129dd74580eedd8a8f85f984486ea, + 0x16542d30db773c54daf9fbbe3cc6329b0f1e30a5f27659b5718e073a6a3ff993, + 0x2fb9d2c332734cfd46c26f65328fccca168f58711368560028e2953c2a70965a, + 0x1bcbc6b5cb163a446455ed0879da1196a6bc4abe45d7b81af746f47db5292e7, + 0x1ddcf7b0e9bc54a5074e021add723164c981f6bd04db9e150e2f0e21a1a6a3d6, + 0xe49ca4ac1a6893b61701a02e1dd02a35f49e32a7efa7f297ac4d2c3e545b7be, + 0x268309dbe299749682f7030227677e5013880137014437f7433ad9e14ca8dea4, + 0x1bac242faedaafd205ffc4e05cecec603beadfe07666a7f970934a2ac6f629ca, + 0x28e2305a80b016478868cf732f9013b976fc92a34d1a4dca77ae572c3c69cdd2, + 0x145de9f18f59e36a93415b33aeceb48554a84eba20c56044880e1466bec0d0c6, + 0x1acb49bb5f0d3c9385fa202a23350e945f57259a6ece8a15afb3bff94fe92e13, + 0x26add7d9ed34ea73566b208120678707b1da9f64243c55a41189445672f974d0, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x16051748ed54c9e8d56e45a45a4eb202c4c91fba4ccfa8a05ee3a99100ef028, + 0x1a51e1a75bd54dc013a8365e8be4d93fc365ed1f85a41e451913a035c1a975fb, + 0x26dbf99d1718983964d70e45be99a786dc590c2b06726631e73e42cf19bcdad0, + 0x1132f8662c582598c12b82db868060fd02ab2dafd730d149f0f1c3dbb5c7540d, + 0xd20abd1b87b2dcc09f4abb60b6b936bf3196166849307a146bdda7953270fbf, + 0x1312f989d76c6cf93d0386523c2b447be5eee1a76770859a33e08baf79df94f6, + 0x28c79fe778abea865b37cb9fb6fcbff83eb5e3a6539a22c18cb0a7bb1ee3fe, + 0x19b577228ad8e6ee6c9b669d36ba8e0797ac74616e3efcc9e6a7e819610005de, + 0x152dd9b7778d894130a215abe32065d7adfe95428d02982301d4390896ac4a40, + 0x47e6db3dad97b60f47207eaa4dbf769e64880abba447ab42a64b4e9bf580f, + 0x16f9ad0b2919753c49509ba57e9c915aa32306664ce92ada426a22c9f6360d66, + 0x2921d7437d72b2235761183fef2292d581d60883f6f05163c7181e8930598142, + 0x361282380fd4190823218380191766a8c2eb6ef8f084426f9ab27ed7503d0df, + 0x2661574bc57b6eaa30224ba10cbf4c961ec5d3beafa17d846e660915b34b9ffb, + 0x2b50d64c6224a9fd03f14c5142231a82b313392062d70bb835116f71f861931, + 0x2e43be4ca9acd39a0b869ff361bdc22679619dbd7fb937ee499ef99c14b929dd, + 0x7458dcba827b917c731799c95185ebf349165eb8bd8837ad4c9a7a946acdbcc, + 0x2e565ac1c012c9b7001654e5c4b389eef1604d14da21e2cbf4682ddbde00ffee, + 0x2be1797b6ee4dab5c76f370802650571f72ff37afcd535e80c02a984257a4a31, + 0x13df73795946cbab79f5ab95a1ae07beeb368b6a672eeff9533467574cd5b637, + 0x271f3f4aa97903015b64624f4d65b15cd2fe5f18fc8dd6ccace0c520d5daf9ab, + 0x45e4c5231979d20d30f98e26acdd05b44c6101af23bab61b22b9f2ed4c2bacb, + 0x265d868fd9eb462095cd18e40ea2aeb074153cfc06fe0c62d268fc86e3fa1e9a, + 0x1c2acbdc137e6a8af39ad351f8e89255387e69c7d9cc4aa0cc0b4a3c9a2b2dd3, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x18b4e73dbe4d9c83510458712484b5a88154a64e4f000efd8a5d2d960b4d799d, + 0xe2fdde439a5f899cd7f813089c26f68018a3b0ecbfb2de15589e589c77c691, + 0x4f2b25402a03ac3a6fd61ba2e73b5acd1dcc221704afc22ab41ba3b158b7a5a, + 0x2ce09acd57a7c33da7a3083fd7336f59f1a21bb7403cc3152101127083df270c, + 0x1dc51c0843736ba1d7b5ca4ecace075a61486b9781deecb73ec0c9270880a5dc, + 0x24c96270bedcecc4ec08285665474ba417e43f1277878e25f64c7ed59d518993, + 0x1567b25ea10aa7639e7754e07fb26140e6b196466301266acb242ce0f80baa9e, + 0x1b8405e13b06a1190bf60e3fbfc762ee365d6e42a551c9449ac6e78c25c313bd, + 0x1ae7fcaa790af2f4aec1458d5e8fb9d2f6e9c4e1b3877eba711ad016a8f75883, + 0x230ffda3cf04839dda573ecd6cf6a765f419096e19c41a27e219f7624f63f918, + 0x1c821c8db96ded0ea28c83e01769d47e7cf531e5ee167154c5942dd1552c99c6, + 0x654e2ce5de54485cdbf636ff35aa519d3bb0ad0f65553c089035b399cd84ec9, + 0xcfb61bad637440ea70c21616c0021531b797dcc910b94583c7fa278feb71244, + 0xdde58a2d3a19ca8daced15c92f831571b71a3bedfff56df64ee3d3fea7c11e5, + 0x121e952932b7e95de7ec84c86576ce61bbb862ac2f13270054fe25b95540345e, + 0x77174b4e7741e4131a2adb24c6c9f223bf77e2678d9ae5b3279d86e55f87fa0, + 0x5d3eb46a0d9a2f0f47f0962a63d534c9a77d3927234620d2c928bf09ce7e5c2, + 0x246f5a9f3cb48cf1f4a13aea5a54ba53d8d3046b61871dfc1fb5d9f358cb51bf, + 0xa2e62faa91efb3dc7d4c6482d41ced93aefae8d13275135e509bb3a117b19fa, + 0x21eaba42c45ccbed93fe3468dc8b98fc42a9855e60ce78562080053784c20256, + 0x1e2cfcac1e924008271b086131dba3dd0044a03a28dfbb2f008611fec230994d, + 0x2c97d275a36bfdd250e2e2abfc4953d8e04d5e92795a914aa91a168f1a993059, + 0xb1d67cb1a69e071bb57b3f4eaed9fb9989c12e249c0900920bbfe0fe7ac6c93, + 0x1f0f655f87c30461e7c2d6a3b55d5092e4542c805f29ded8c499fe4603df979f, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x1c9a4884cf6e9cc19782fbff77ff6a2df0b1353c2e1bcc80f80685b4da9a9962, + 0x2031dbc469ef5d2ab8bbf080e779c81da08a138d18b1bce086d9650d044cda52, + 0x26d411c661443edb9fe290206a84618128d1e85e1a8fbcb9908859876db87376, + 0x21083c2f6587d4d94351b5e8d4d37ca1ed3bba605bb05ac45151c5b828acc8e2, + 0x252aa5220ba089fec5d79e776cfbcc3be42167e2b24ba6245dc60c7cf0fe818a, + 0x15aae505663cafd83758de1e586058a24e69295863d59c1221678d0a997af128, + 0x2d8e7eac5ca3205436aa38fe08be53a0fb7b57e4c35abb9c8dfb722eabc4b4f7, + 0x1d4b0338ca8f97e7f6da84d54af30e30d065138190d0c36098a69db08f44b97e, + 0x1af838255d6973d5b0b19585c52f4dc7ac7ee024b541e4c103942b7485a5f82f, + 0x301b9339d3863e05daac5aa39aa79eb948f6be9a56ade53ff27fe98531f1ba11, + 0x1e03df8a06e4161781c43cd5da85f9c521dd1f5987bcef858048020944852c7c, + 0x2caddd2b00b5b15d18a3ecb0d013c71966ca47d579403d64d0b41bd736ddb7ac, + 0xb87a369e470ab99e2c4349ce109985391d848aa3b60202f7a17ef6a0e4adf1b, + 0x21814ac94b3e32f6f295c65c4b234aabde202d9607b171ec00d826f998a6c92f, + 0x29b1228b3346a79953774564fa631d8aa6f2314f2c9216d4aa8d89299909f352, + 0x1a5e40ae67493e00371f4796181b9c0ed9f909bc5a6d9361f9b75b4c5f48d270, + 0x1ac79eac0e5bd64eff5d74fd02f19cf0a066d6e5ad8d169a2ae42a935f454e3c, + 0x1cc1592df343627349a25bda9ff38febef99da952ea6d33014b9e062d0b9c65, + 0x246ae2ade241e443bde03d8e2b323db4208434d53428628bf92a2fad2058ec10, + 0x18d00d6e9f9ca8e1f315aa97fa121430125eb2ed841bdd81f1efe69379f786f3, + 0x2a147b464ef73244b29cc4e4fd24a29f0fcb62711a840ed075c77682801b54f9, + 0x30188a7d39b26173b10d7767135b841640c15708089e2be2bf8f5d31861ae140, + 0x1cf70ee72aeb25c85554b6de9c01877c8ef5164a1e118250aa14bb0ff8cc5d94, + 0x2a27cb25999e82f8abee1351c8083c8393e5038113619e783649651c286967ac, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x16f3b44e7a69563f9b9cb04a43140d2c51a2a2641b9dd9ad5dd7b942b3898e6e, + 0x1ef9dba4b9fd5363a7c5855a1c3ae00c1874ef693336b606b1f25c4fd32c5b3c, + 0x3be108cd7d21185b6364bd86883fab9fc63c9356edefc708c05882280b75515, + 0x21631c522c8f458394bd234946f326f0a0e0caeb2dab4014e8e089f36b25d766, + 0x2b469c787003cdcf37233bdb9f3eed9dabeda742284d6f7286a426bc9022fa9e, + 0x409e474d3841d04d8f6a521cae62224e4d15d729a48f7af7357288e1af200af, + 0x239db39ca9b31c21ec61b7f3306cfd1a9c20b3aebf0ecf4af7df18c2a498ac32, + 0x3062a14d58830bdfe5c97f9111ca779b253e09f8337e457a6c4ecc1ba1bdd8fa, + 0x22e8958e08ed54020aeee58d8bd6bd816c3b99f53d664fe6c1bbaac2bb5c12ac, + 0x2689f68f2ccab8aba87dad5aaf8f24c89f24d94c33a3554413ec94c9309c2201, + 0x7ddcd764dbf337080c16b4c68e93eede25a567bde1f7dac0e3bcf6edfb4c472, + 0x293c704451a1aa66e1aa0d4c7dd56cc5392fd8cf7b8cc998f6a54b8c30b24e19, + 0x2cbffa47d2c28e5d0ec4a2dc0a168ae258368feea0ba17662168d4cba27906b2, + 0x208c5ef46b238daa217fe46cc26ae7460c70eb25fab5f1122f4edbd48318946, + 0x24fe6c2e5f21c4cba02f4c15ba1d07c732017ac72f262626eee292a4c3484c8e, + 0x1dfde7457418ea9643108cc1d13371791b90fb3a4346f4ea6830fc8601afa196, + 0x19eba78507eb7f4332dde5342776cffb8b3f53973e9d191b0f312f7f05c1e732, + 0x2be0c4e211e0892ff5d3f3b7aa0281e1602cd23684b82ba12cb61be1eba411f, + 0x9cae53a049def9f8088909b1ba59670f0d8a2180b04062eb2c8cb2c3893c11a, + 0x2e2adf7ac157ffaddf5ba5fd0b3b009b13c8e1454b54d298e5a50f15ba24a957, + 0x960206a1b5fd7f8caa23c6f979a77b2df76e53ca4071a30e96e203f6d611945, + 0x1709ed8801ed661f54156b3da294eb591aecded73dc4bab8e884618899d61929, + 0x213a699fb63a980c7dd352008ad46d6c423e77fdd87348879208531b1dcf7de3, + 0x372666a5afcbe6f5458e78471e9ef6fcfa3420dea49e713a8ce1c19cad53b49, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x17f4a43fbcf12508a933527a8912f2842333780fd30c0c46d15af216dbc9251c, + 0x2c5744c9ae7f6d8c3d5b66d4d43b95afd79ca38594b9049d886488cf10cef463, + 0x2dafa6f3c603c4c0b0ab7dea2b559314dff4f7b2a1a65894613d2194595f4476, + 0x2f7218004fcb62dc5ab37c7b3803626296dd6f876ea5eb4834eb7626c1d82217, + 0x6dfa42020ea166652a7a392a6cec8a63171b943d6853730df3c846e32176cff, + 0x23f87a617f1e8f021b83f41ccfe5e7526864953a9eeff56d62d85731ec090826, + 0x1cda3fe46da8e3f2595bd22ae9327c2d2968ffc0c686741a13456fe5b2185861, + 0xfa8625bd9c3af09956eb74e2f983eb6079a050c0186221b1a32ef5050969007, + 0x111520b0f559fe2476e6a6f48060038efb0166ff9f6bda812a02f793228af23b, + 0xc23dee172299609bd3dbc9f2ccfd1e3f76e594c5ac2c3e5ddfaa62289ed7656, + 0x105f42aec8a1b60c20e7041acb94bfeb6f6b5f8c5b71218fee02047d57c0c218, + 0x299f915785e8adc1c2378fedef3083e487db1f6f1807cc7bc66e51b73bc39147, + 0x1ef3836591f803fdb8a0bd89373dd79176fbc2e92ede7006faa5d95e9397d81, + 0x1a2785db4d9a3409adf3b7ddca9ec408b2f93044338ac23122588de468c59408, + 0x1a6ead13bcc1a5afbc63d85db0a41c4a031e480585fe7ae5fce9b64bc866a216, + 0x1f5996a035a306096eff22ff3aa805378e9f4e3ed56f9834f62144f57eb2d414, + 0x238498bc99b623c9fb4daf8ca4e4c87607338433a9bc2546c9f37c86af431840, + 0x273915d627d37ede450dbc5e96ce9489b78ee048f5756082227e62db6b9a56df, + 0x21c11618cdbabff657a20c8d84812b984a017810e97ffc169c585ee296fff9fc, + 0x203e0bf4be8fe2ad1f1eeb4926647caa4f6e429ce794db082fc07ee5330e7cf3, + 0x294ba4a28f070410c4c4f8cb5c09a56252ad05dbe4b5bccd24a4adb4fdf71df7, + 0xe403cbeb904d1582f7872035f81eeab4010de844540a9b2bfe5419d43f8bbb3, + 0x27c86e516b80bede0756a21db1a6ced3ac126996f64f9f6edfb2417fcd3829e9, + 0x26c02ced384da01a247d225b0931e3310f7f689426b3384c65bcfcf1a1e0d8f6, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x23c28b7d927210270a66d02ce14454c7608540c1c4111989c66fa5c83b953441, + 0x175c47171e64b9fcfd9a0e5ff2cbf87d0911c01f7cfcb4287a219dfb65a3c946, + 0x2b0dc6705e72fb39676c099284f87987580419e380019cec6529297780e9f143, + 0x2cd30e4b096b2ac50182c596fc4bd8de276e1d1f058acc010bfe056b50498347, + 0x213717e1ab4fe340c8edaa0f2b003ffa2adf4890ee9ab0bbe6528a2f4e436184, + 0x167ce1eb87442469edc20f5be85f41176a2bf1a7e44ad9a920605c5be99bf975, + 0x2c0874699b7fbae13046dae49db97858a6950199f9a3f3bf8238aeeb73501797, + 0x1a565a10adafab01ae826b619cb79c9c7420a140d41365669ec361b37cb5c8d1, + 0x2c8c416f3d61924456ecc73119c6ee327dc717b411a4ebdb673b48e8ccd1d4d5, + 0x267fd0effc34952354f05332b71fe925b3548f0159ee361467784ef8fb986315, + 0x2bd251e35bedda84bfaff55de37d2835277758a60db4a9bc4fda3571df5ae523, + 0xb7a443712b33fcd61028542457a0da3ab1f087b58aacb25439af6e1e55375a2, + 0x2404133570623570acc718f19ff26c6b47ba03857394f55d17e8ddafd46cb5d1, + 0xda485d8a8d3a97968c8b0789dde653796430641c4dfce40db5cbaea4f392071, + 0x2146d7115c9adecdfd5ba061103729167ca82a2e9e58df7177d10645a23744f4, + 0x2c957d723ab55cfa5de8995ef9904c3be5b70b5774a12d17efd71d7fb10b2895, + 0x80bc3e98f6ec909c5161c498e0613bb736889eeed8ce7bcc93bed02f4bc5be6, + 0x19dcf73cfac4b44c2761e024d6cb2678cc104a528c02799bf3a091908ae780cc, + 0x199422fe9fa1f5d2dbf402c9bd634d4bdc9cdaf70fcab9d0ebfbafd12a02e49e, + 0x1a4077b1cf49f41fc3a2240a37ae60309d6941b839ebf51e1e118c16a23c6aef, + 0xe53e5ebd64346a83c1e7f33878ac8753b1b45f0e1747f680311eeccadd89a17, + 0x5aeff75c7b60d39afafbcae4f99e77e223c35e301db1dbea5becba73535885e, + 0x1f9764d4b036ee9b186d5dc379c2826b17595849ac829e2d52230e243fff309b, + 0x1cbd64e54e94a1499df6fd784df7709f93942071463eab3db602a804337a436, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x190f2a683d41d29fa79f653057c0851c76bf7301c355e46d514e62a2116d7188, + 0x358bdeb885279de421d0b5bced75e4b0b909340f8a3445a3dd17d76e4abcd1a, + 0xbf755f699b7e4252b3fd62793827e613c40b0c1285a2eacd4ef65e3abfd281, + 0x26753dea98885ca2c4aa18a49b9162277722858ab51e3a482275278c53842496, + 0x2c3bb4bee55f665db599acbbb270af82a9f8320f7c3adf113cfa86d9cfb4754c, + 0x149ba255f720eda11444f804e9814260008b187f26ce17e4152c092dd477b00e, + 0x21344c682b1f31453cafeda3081b76096340dac56062762ca80a78870dab3bec, + 0x11b6c7953ad5ab4ae16f501101b9b577f0b8a1d7c6a793d66e4fa161b1e06e52, + 0xeb1bee9bfa6eac0e22bee9a13fa2155ebfcabd0908e74145bbf9428ae0b0209, + 0xf89e6f767ef77ce6ec818807d30706fc114d9e02aa610c0f3f77a3a08aaf9c7, + 0x18a72ade9ee9765de8ccff2950b0a3e8c8abb4a336ad417ea75837e8301b8dfe, + 0x239367bf5652c2b293bf645bd88f1169b6f872ccf8405c2b4f09f4d135f6fed9, + 0x239747dfc96f5ef11b8573b4714b20381ea4ca958761b44e11872f306722792b, + 0xee7d51ee88f040e9c21d5362bfa085adbb01485abe1ed5717b55b8687e40b31, + 0x216277a3d920e1266639f61d0c22d76858e85daf5fa83d6230c6b1628a077051, + 0x43527556626973735d511d252e2a1dd3b55026e3d5b38324a50d1cd44d0f9f1, + 0x16e435ebcff7dc72244e74fef07cda6add05c08a52cf07309bd2eff2ea896b39, + 0x128020b31dce80e89ac5e01bb13329cea3c62ad115a5d65ce68555e4494a867c, + 0xc840cb172dcdbb1502749bb1beb46e0439aa167caa4317282fc78056262eb46, + 0x542b0852563c2bf928db174369c82da60d6d41e9c61425d417f009c46fac67d, + 0x22452f2d9043bcbab68e526d22af55fb835a3e554e5101a82ddbbcc047411884, + 0x11b919c0b7abc6b28c582a84c158d5d68c928475503c312f86ad3a2ca97c0ec6, + 0x2d1e6445ea67dca7ec1db0b08659adb177c9379f4569bd3efd060e06d0bd01e5, + 0x251ba02f642cd5e0ff35e008a0a309c4c6780dafa9fac55b163256d39a4e4119, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x2f09e5f58f262c5f4c9ac2458e58dc1c3f5e0a409ff3f095d8ecec957ac50f2b, + 0x1315b742c5de4460a27229e970e546750da9ae91fe8ca5e51548c60c12aa8359, + 0x60e6ecb8723e793eda04e490c818bd07cc8a972dd900d0cbdc4c28c9e3ac13, + 0x1677aa582feef6ec348f1b194f4f978d6af473133203d0d22a81b08bdcf26a9, + 0x106e8e67c7213d1c649b08f8163f849d0e0cb36391672b3dc5e632983451f457, + 0x218baabcf27c9046b7ce52309a3d6d3a2ca1b3924bd2fb64c157353a88567c8e, + 0x2b2717d36fdfce6e134f255adafaab3d1a9f719b3a661cc1fe490b1e190f2b10, + 0xb0b2c3bac72604b4c5d568e4f4cf53596050af1e7bac3627e9b2cce934eb482, + 0x217a15b51fce1bdfb5678864acc464e95225e47ea40bbc78155c14a41f2be20b, + 0x1ba5231ae9c793948686f7dd7be9c44435dd6a981b3e880f344e2935e14b64b8, + 0x253e39215ddc07e604684a22eb2e7bff9c138b17d2089ba9f451cee209f14177, + 0x291dfe1da2b968d3837a2b2b94f8eea9606535776a260664e8227e212354ca64, + 0x1d3a7e1e04c422de9b7e0b090180518372473ae8ecd8d1fb81f4981bba63122d, + 0x217d25ca6a61a6551abe4bde579165d171513a7c15fdd69e62b46269a1cefb04, + 0x1d65f0b99037a8506c7ac7811c3b8ddfec719fd951a7337dd01e22c6e00f4d34, + 0x2288e24daba6872e61c70d8a4b8dbc67c63a495d41649761198efd7e4275882c, + 0x29811fb1aa54a2592816797a866eb8126f4b333f1526eb6e25bb626224493360, + 0x2d8f4b4f41d9abbc9f03c50e4da5e64fdfe87c5d07545cefcd30131f20f00d9, + 0x28d7a552fa2a86a8dbe41059439b0e35614cfdd841e0d6ef1db1af78d7108e4f, + 0x96cddca2ab8c7ae201908ba1a671a9117e24ba7bbc16b331babdea12bcad5c7, + 0x23e387be7e8d63cd8b769e13b718b560bca4a602c8992be3d75e71747a10dcfc, + 0x1f77dc7b1dd84dd7ec1069c065121f51c036a41237408070c45ff15d2462a60, + 0x7765f1e2b28bac34ff4c1574654563e8f672a14fb105676a57f2554f49da9c, + 0xe1356ea8e8068b1ef8287fe1362ced74d7e1ec18a1bb36e6fd2f22593b51e9c, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x9d1f2588934f14551f899de997bdbfc9192ea76d1490b6bd5e1d691d3403af8, + 0x1d48285a000b66b39acca3bd48ae38d761b590d846ebec486db4899d1d3c4d72, + 0xbc56781b0480256d3661ac6e0898a7084005d607165224d494103866e256c47, + 0x88867a8bfef1eb88b2ebd34daf3524cdc118d232bd1b91646c11a2a54556b06, + 0x29938e679bf6bec4d293fee8615186bb09287291d69bd50953790fb09db7ff36, + 0xf3078e2dba998b8202b3eb91f500e8cdf87e2ac9f86edccd8b907b1d73f10d5, + 0x2feca0ea4cab180c357b1dcef1e8816caa115f572fb2da374e27b2f7d2a17108, + 0x19a53e4e1a8aa7a15029ff45f528f42c8dd0360c8dacfc125ce7d192a0a70765, + 0x18ac83f6bde2bd90432ee9fc03f0e62871969e8ba27aa1dee2c72e2fb42e9351, + 0x2cf369a36a64a81b17c4521b17c8ef65d09442ac2858d03785fff1f8ae4e3881, + 0x16d6acb3b445a2dd2ce6c6bb79f1f61f15019a090285fca38fbe54e04704c55c, + 0x1bfa4fdd27298d16aa06bdc9ddb3c29f48aff4fef45b5ce80b4acdfa43fa1355, + 0xc6d30e4b903bdb97453a996931ed19b556b3887f54d63084263d278bc2de531, + 0x173ca2118a8b85e6e3667d2dcc1c480e163a338cc2d47992b0e6f09f2d363c24, + 0xaa825097578d91eacb40da93cb739f9a435c8a9bfe2ef8f63d4d392672506f1, + 0x2869d724819d09fb172258ab1fddded25d8f0afb23f1a87b331d229eb61e032d, + 0xfa3dc0a38fbb92e5f714183536dd2cec7163726a64117973fd1d927ab7b0c42, + 0x1f0f50f138ddd25e9c77dfa15f2201bc43fe818595195782fdce833664fdd244, + 0x1a8bd852a6a8a26b23057e5bb85facaf706a6487a0651c7c226d0cdff09f4507, + 0x20d045353b22be410aad1286b4a362f79c73f96103392c5c4ed31889729807d7, + 0x2830a23a528b1c1e7e277f97424cbb153b3d316fe1b167ea01309bdfa6a0f623, + 0x1f8f3d87ef4767679cbf773af4a2f27614124d5270015c7d64c0b13d25ee63b, + 0x2843847fdedc907101ab1b8915d7151dcbc7e27419d2cc24490d2020f3193683, + 0x1fd3dcb19e924d226e9b428d29f70978d7715bcbda1ec70e5984a67ae61537f0, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x22afc2a215e589f41511280dcd9a4d2f7714e205f2c4d0b663c9d2da07a231d8, + 0x256117a01b4903a52e27a41f92d7a65de53876e832d5d0013fbbfdececdcb17e, + 0x1bd505fe2027ac17a51db28bca97087a4336103a375f5d726c4957c63c1377b2, + 0x1370beeb7c62a69367b6d83f639e5eb0744df8b7197e44410965c697938a9e3e, + 0x1b23ee8b148269858c2f44c34f1058f44e4f066b2b97a357f81a0694bbf3baa2, + 0xc11837fa154861251a3c6d09c4590cf5b738abb440c9f221b6fdd86b62b950f, + 0x1e41b6d8be08383c6279628ffab3e3329bd391e954f5333c2c24bea41b1b6107, + 0x7921a5cebe4c7e339b84f0e635a48591367584d0c12a64b5637d960f35b3d11, + 0x14969d5919a6d85c58ba30919c0f0e52cde9197db39681160c5be3b98aabb92f, + 0x1d6e48aabeb209860512a8935eaf23b1bafea8797a6a81284fbfe6e81c1f7a34, + 0x2e3ce888f840d34ed8c660bfd5a48b4f4a0c040f5b39165e2615427831f86803, + 0x3383db94e9d7ac3e3abfe0d27482c9ba837264a10f482ae80f226e51042cc26, + 0xaf89e9e5eee9173993784fb566e6d538efe46346ff5cf61b1c993b52a42e46a, + 0x1ef03efbffd92cd2da93741eef43a8bed80a76f4f68cebb61493e971b8b7e7e8, + 0x274067b2a04222952d6577de3245f38219ae54f0582d9e05b7d8a01330395345, + 0x16ba37bbec0a43c8f30d001bbecb30bc3cf3db728da538ceee4ef9ff4ba486a9, + 0xce229b9c289b8e7cbc4e020a0372a370a7f282201b47781caff3d01642b8c2a, + 0x2f80729c7338be1c0dd613c22e836ee2e9a9d0b06a2fb5e52af024ba8678b5e3, + 0x1cdc6d2ae50c1329a117d13ebbfc1fe86d5526a9f9c59a50e031f37b6710dc4f, + 0x2530a467ba204bca45d83f9ca4c5ac9a568c053266ee1126607ac33c7e94650d, + 0x371303ff0fc68a7c62e17b71ff98bd5715c6717d794b69df439a6d7c00011d2, + 0x378305e20bbf96aa0c633930f4011bc20789b5c1be3f2929d693e704c552bf4, + 0x1a3636567c1ef3005e7d5839bca900888aa34197fbae582cf6826f855020d24, + 0x281e2a06fed1cf5b0e0b6e03fa2652cd608fa474299b5c7d0e59c6aa35c0b17c, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x2b3d84e5c61b2b97939674b7ef13780988f0c2da109e71d17d0598f080236a27, + 0x29e2b9bdc8dcba3617e5663dedd89fdac40bc1714f767f327c6503d7f146fa2a, + 0x216f7ae6ccd7bac97e2bb068168cf18b23505999ad5916e52ce95a23894806e3, + 0xe8d298cae881515ab0f74ec935567a5b249314023b3856d5f9ec1a5599a9b55, + 0xf1e1e45f847cb03591997bc8812b0f422dd0db2fc99c2417a81989f2e46, + 0x5132e56caac6351c00de73247be0cf09de357c4780bf705fb1d12954047a302, + 0x2c1f7dceb1501489cd4782c13dce297dfe75af4b4065dfd0fd51191e0f03489a, + 0xdd3f24843220bcd4a66586631e888956a0ed26f717c556dc5e20f38b455d4e0, + 0x2f3224043392306423d22f0e9e5c15889df84a9c1c6e2bd406a469139d132844, + 0x2b572f7e5208c5e52a759e04500a1c7d641ff06df5984a926dcab2e17ca28503, + 0xb1988858934c8a353456d44c461a763b6c98ed3cbf72a21e2e4690083399907, + 0xb0ce76163a25f724929f8ffe5592bf64313660ebe1b160472466bc091c5c3de, + 0x173b128e873c2dd53e94e438b4cd066ecfa28eb42d13bedee742efd4ebe4dc3d, + 0x22f7d627420794cb514df36097c3dd8d2e92e2890af2c1afd4b5f5bc26a6629, + 0x1f343201df3060d03e313eba7690883ba77fdec3d663fc6884ebd401938af261, + 0x2472c968883b169ab912d4327cef96e6d4fb7b2c00959bde150b5ed9708929e9, + 0x134c248a14ff13c4202f997bb87ee93058de60144cf2f5141236f01455438526, + 0x206b6361e6139253e6070f905d6b7d08eac74e4ef2f54ce09643926bf5c8e814, + 0x2db2cff5528de7a26e0643b161e7b318e554aaab93fa72f9f475d9aa7c6ec8bf, + 0x25e05b8a3965fe0a250aa7ca030e3a7439445478e59dccab16a621928d014571, + 0x2a8c5a77c61420b6b4ebe974da7140a25eaf9dbc9092f063111283e773adfd1d, + 0x13389b7bf63bef6a68983125b86f93b62b6d9e4783f96b710e2ebed3adbcbe2d, + 0x2731cadff040622fccb533fd62a0d43090455881080a898488d55c89083395db, + 0x1886f751efed6e401c5851f88bc285e68de3b94062bc810b092c3e4160b0e12c, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x1a1de7217c640816ca96d69dfa3a9ead0a32f62b2d864c5cf3d66e2977616a60, + 0x21bfb88e0d52b7dce5432f55c443964e46e72879baaba7aaa04577b59fbbf100, + 0x1e1c9ba5f1413166786c96401b61f687ba50dc735d815a4e811570bdd8954a11, + 0x378dd10a31675f7bcdb8018c96cc8da6d034a42cdb62b406c5bc00900a3377c, + 0x274d6dc05dd550d77fb31d349b2adb5f38eb4b27ec15e8f9cfaf56fe2f8b318b, + 0x24fe1bc328cc95e0857e89e99d2ca97f327c21aa4de5c111a72c2c37235e7d1c, + 0x2a98fa37a16d2f8369b3ce72873960006ea67075c023fed5b32dfe407e636057, + 0x1097f947557042baf445bdf5b8a92021976c14cd0354ee88e43e8c8c5caec4ab, + 0x7734a2111d925edc13496d0f5922ab36acba8467999f5fb727ebfeb37a38077, + 0x2fca881eadd43cd4b9b3bde9046f6a2505bc46132b2c24da4e27c102d63eef34, + 0x27c952411017987d666bec758d6036c17e440940b77db47b40d539ee1156c1a2, + 0x1b329d612f773e77721b7a0f9154b359c24a6ff2ee0f5b9733a78a798caf0f28, + 0x2e165793b072eaa3576cd18b9027582368581339ba3dc1acba9cd4a202701686, + 0x218665404266df9d5ba6ba1f5a7d9a628ad7c74a092860e287be14f0bf58774e, + 0xf42176ddc2c84d12bb3798fb2b3a06e44a4c33ac39ebe036c7d6ac6ffdaae80, + 0x21dd47b40fc1e454614ab099787fe65d6d8ea9eb0e4055bb51e34c51bebc1dcb, + 0x7d3a26830f8b14342a63c1ab7f713db81ad94ee6e5c519cbba0bf6d2b87b265, + 0x13a106fb1b648c8490a71e9c16886e0049270240189d44278c63a46f744edbaa, + 0x1caa59825f86da2ce09134f4ad823df1faec3d556f9756312cdd8991c3b56d60, + 0x15cdad7e7f40503431e7a8c20a7e1b48ace6d194ee7d7829805a38d04020426f, + 0x35c2a4fc2c424ff77ca180b9b522abf519f1fd8b5bb7ef7f1f8fc7d31c117c4, + 0xae2ec57575aeeb3814613d2390f8ea28130ed34725d1605b585b4e8cbbfb4b9, + 0x1ded456ffe562fc6df999ea5cc80de0ff6ca5fff1b0fb2607273ef1ba5262edb, + 0x2ae307a4f4670d11f5ac1c7a3a23b6dac613d3f104e107d0438e2ca6d0ed55f5, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x17570a15226e3cb10d0e0cf627fee157af900cf4b22d8bebfa0f05ab45d56306, + 0xec2cba7becd9f7b3b07b59be1f747b3fe3f40ff31873dd306105ffdfba14106, + 0x115a73bfcecc700e34ebe87a02338ec4c9e1bd0d95c2554b12cd5cafa1f75f87, + 0x271882e1e88d3a90e536ac91109d8940ae411f75de7cbd43000d6316c5ef48ab, + 0x28d797cb88e36cce87e39090fedfa11dfacdf2adf148618d262e46fda6ecd899, + 0x903165475cdefc056bf3cea7cf26e39e87e7d1c8e1497271df24330ad02d8fb, + 0x521dc03abcf3c15278e90552e8162b2dac92220d99e69ef9e449b5a0370afb0, + 0x1f80e4baee043beb212593df11501a79c07c898df6cc578190c679e64c34a2ed, + 0x1133a6e8c5d0315d2775206b849588eaabb0b63a8faddc67806ac13faf127b7, + 0x22af22b064becadae113b24d113f0cc3dd0d178f9cc56d78e84bf341354918ab, + 0x16f91f204c2bd84fb907a7ab7442742ff24ab831ba252806ca7b6e69c77ce94d, + 0x1d2c02fb8f7780faa24f3da1f29e9101c1cde4461b7d567b949bff5ce1c71ee2, + 0xf8e78d6c9a055af147b74439decce135691562dc5b8bac4e471fecb73562363, + 0x134cd1d2c86faa3bff3a72cb6226109880094173ee2cc808abe6f9586bd47844, + 0x1b9edce59f36f20f7acff0cd78bdf614f6a8f1bcf95ae9d6ddbf5c8c7fcf625f, + 0x5a6771daf1f2b83d0a92a118f30d42178846e5e209b82491656febef65abf3, + 0x1508cef9d99fd03d1b6479b90399ca9dfe3792fc63bfbdd35661e0d44bad8096, + 0x291cc5c3f65ae5bf17598f432aef5de08724ab30026f25adb70f85fb3bb0d455, + 0x2c7723a807b3944705b71db8c04cc468820d3bfb99706528f66965bb8c9734d4, + 0x9bb171d7c99e8b5b35def3624957074dc2f0a6beb861bdf417b2ae290832dc0, + 0x1943ca5707ee772b8391b577e295dad4f10c2db1c770e33d8c37fc2280d71ae8, + 0x1d7852588ccf0c51663abd65b87004ad5880721019214e00190cc8e939eb22d0, + 0xee871118f882a42a8acbe733a64b7333a2d14413c511b6a79d58aa96c08ef8c, + 0x1ae19930e083754140dd85378ca87078feea1703c3c0404e2776bbfb4cdba8d4, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0xa7c934a0347f0de7e9e7dda8b1ae9b094bd6a309b8323e06780821d7894fb5e, + 0xfcfbe728f5c1f06572e5a750260efe423bb6992a7b1bf8f0e761e7277e71d30, + 0x170dca9f0f6e9057372e380cfa924e65cb86afad866a330ec9ed35ebdae1973d, + 0xa4a917f344bce3b5f92568450a4f17e6a17e251c7357e708ec3d6e559bd89bb, + 0x127ff432555f7e08beafe0fedba0ea990b49ca5df42cbb999c3bd7b911195362, + 0x65b6e437cbc026c1623071777b10b8dfd605a3598fbda0687c74eaf525dc1b8, + 0x2faee8e6ee2f7bdd25ff36c3189aedc3b05c4bdaffde640c0e4d9284f7d9a8a5, + 0x1294fbb432ac3864a9c12eabef13d07f732b652836e66a954c485735899241d8, + 0x2dd3ab4f03573f3362bb7ddf9648bad1b43ac6939d6c4fa9ee73dc7fe66deee3, + 0x2029b79d88ff15c860971aeefb2ebe0d523faafdd6096642b018856793e74b4c, + 0x2e5c56ab0934eec6ff8c8224ffeea657f1b99f880a002f6ad5352d30f7c0b85b, + 0x24888adee436dd67b6742858809073a5c4393d61283a825b65b883114d44220e, + 0x1fb80c654292d64f24d331f4f6fac1a20a76379865a6331e7528de236f44eb11, + 0x3e8ff048f23e53a5c6ef02dc7d37f316cd4528da4e1f6cbc4582889e1470039, + 0x23a4cda868726fac1665985e13d800d100b56bace43f67e29da05733c2a351f8, + 0xe25a1b132ba0bf76f1e361bff6b9bb9fa2d3aaad114f589e100625225a04b9e, + 0xf534c5ad59c9d1c4a37bda4e52ade866d305b982309a004f3b2c6f8b10e9854, + 0x1269fd5d157f5bb62bfdbf4f3f88c1b2b684e40ce07749cfce657a373e1e4b91, + 0x1fb70d1ec4776f91b42677c88d2983442b78ef00e03b82b5de606a45ffd3b4e6, + 0x29eecc22d8e5725e00c85a0651edaf5f3e9530505cae2d7a3eff6ef496d7b1d2, + 0x2355c9e8fd9fe0eb681e8aa1e3ad43740a79cc9d930a029fd161c3ee32f7257e, + 0x390f12f658c6d9291b118f5e116727e2f4a07140e8f3563ec5b12a0ff6f6a7a, + 0x140256a4a9cc33d93eb486b96b737dbd17580a77f20924e4a3d87c23b25b233a, + 0x2d2be9983d14c81d2cb8665b0c08f89d6140539c712cf4c2ac8cc75b2daffe46, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x2cdce0a94aa8c1acc2db79358c3e67d954983ef0927dc6b26f9abad820f1d420, + 0xf49eb6531ab1674ea9a6ff88bd8148690c04addf9a9164b13ff2c4cf008443, + 0x26403014e3cc48e1cf112ed79bee8ee1467acd303d0da5c88b8683e38bcb7205, + 0xc5f602b9f3fda8e647ef7a42af34741d11abbe0a99f464c101e534b51cdea4f, + 0x18ac38aa55e95efef98c347335a80caf7fc5c3efc95901321e3b13b12cf46a2d, + 0x2b1960c727b10b666328f0c37f5cbb3b06a1ad54f61b9503f23b02e5c4678519, + 0x16f13b53b3c6a47f01c73f7e26c2fe6ab61b3e1f5e553413f2ca127e53ce4879, + 0xfc4ef669021d86d29dc04139b88f55a5a57fe0bfa253631918e0d808b1236c7, + 0x8834ddf96f673a786dc5af125eb83c9ffe1537fc773c21d101768aac7ada57a, + 0x233f13c0ce9b48867dedb88a15b1461cd1befdeb99a9c0acd863dd45e0672508, + 0x2099a619097f9565ca65ac96aff19cbea16a90e056a33b9b49dcbb725903edeb, + 0x269898a890a0eb11e9b84db6ae0735714123d4f0aa0a30db183134d279f1a90d, + 0x27fb03bad7fa46a625fb06a4799bf7a07ce3bf8dc01860cf6174f5d9cd49522e, + 0x1f0a5bd99fd979d0edddd243d6966152706bffc8326fb088545b38d95fda103e, + 0x1b082065bfb2e151552d1aeb3f2435ae8c522db79c1c3fb847fe73b728dea05a, + 0x196840a15a65ee462a8312520b868084ed0213c1a881adf907ebff992226833a, + 0x1bb7d7bc4ea0f7b8fb5a3b059478ce7f5ce2069e7d62a307c21d0400f386049c, + 0x2c0b3d687226a36e523c0677e0f3949eaa45d0d3b9c9c2d11b0431d8ecc7410d, + 0x2a22096acae1d75aedd8fc843d8130cc869b142405d3967781ecf9ff0062cfa9, + 0x11d3df41e1d31751c5b00b775f33925b4fd5f8f66dd2c5b2e2e04cb090ffb97b, + 0x29d0fc08ded332bba4a34cedcb8e3eca9d9a6929a5efbf58a72e849856a9cc67, + 0x1a0ae664c389dbc11046bb170c0ddb422c4c6c2f10c68ee98ae7ac8c00c4ee83, + 0x6f3c77706973637c7f2d5b9bd92d6e2424b926c38a2cca7bca5dfa0794e5845, + 0x56965616b2df66e2918ba840e0809b85a567a3e7d13ac5f1e532061af856a57, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x2dfcf11eef61a008f27f61a5de96abc2e329dced7092f941def6b523960afc93, + 0x4f73f5afb82d2297d4e51498f0828eeb3eddc016ae0e15a2a9e3cfff340d500, + 0x26290fc492220c99dd821c4a4d1acfe1b7f40b37a13bbd3ab51405a9f958ac93, + 0x7b53809466ff55e2e4f5ad0f029ccc5a1ac5d261732ab2b010037e8ad080317, + 0x80ca5188ef7378b939057774b2ecd1f98abf27dcd473edebccc06ac7a942e26, + 0x2b6b01434a47ed188b43157e1964f3725cf4f8113fb0a6cb4c01ec7dc2bd47e3, + 0x2c2106b5cb401bd68e15746349b56238f670e58a021ee2ac8915288d5361475d, + 0x88ee10bba489475547984b890d7e794ab25535f1fcc8fae04a33d300a5eb6c3, + 0x29108e4588512ad0ab28e432c789fa3d3e0dc0d6002e19cc3fb6795a75d6971b, + 0x241c4817a914814ced21c06ec5351e85ed7a90f2843d23bd5363aebbcedde7b9, + 0x22ecde699dc8dbd7cd3d81e80d9a81ad023c57bf3aec5a8239871472fabc551a, + 0x20dccbfe3e84b40f3908bf43f0512048facdd8686ca5f17192f983599daac6ed, + 0x2c96389333c5459ec65960d848b06bad4d6b8abc6f2602bfd81824cf43c7218a, + 0x28c59dfea6fcab6ae73beba612e62083a58bb80306a3bc2746ace09d650c83e6, + 0xdd478a62c6871c699ecb4ea12e454027212fd8f1e03a8efc005df6d20ecdd40, + 0x28772e7be45e36b90c2d439748c0d77c0b523711ea398e7dbd85b0d7df1300d5, + 0x2a37740039be074389e76e1ef0095d7d111f778072d4a57334ebca290d667a4a, + 0x2f37845d94aec2d63ddcf2cbd3fb56fead92ea8ecd819d7eac3c2b036c6c2cef, + 0x15edccc5a7e695dff4db9dacf405612f00ba80a16dfda1b55cf4beeedf90ddbf, + 0x2817134845b5ec6aeda4961644d513269f86e07a21ac3b7344d582ed07b5f46a, + 0x1ef5390790a2a3214140b10962d9435bfb0b4e6ce24b7a1ea0c9af689234b6bc, + 0x18427d6f7cd9bf7ace6341d16dd845cd1bd18ed4b9b8ecdcab36fa45860855d0, + 0x9de33bc7e2ef786db74db7eecc7ff8720454637bdf51b281a4a1478f198bae, + 0x5d2c63aa2de4534fa4df7a6c5f6d10599412fd247a59f778366bff5706110fa, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x23aba695154e684ff482751cb761dcc1637ec5e99aaea18d0bf2e2fb26eb142, + 0xba208c04ac11ef4543112dbd88212917dbaab5a87268d8158a487ae3241584e, + 0x1cfed0b58000d3ef4cac1e6fe54e64af54f393accaca4d5b8cb05f61ad9cd776, + 0xba1df4ea027f8349fcb15d1edb328a76fb536ab65ebd535787945634d09c5ae, + 0x1e136b44ef141c91945c8768805ce01001958ecdac9b065874d21717da99b408, + 0x20643e3f3c68b214605c6df2d802e1e539b465b98307fcdd0f8d5bfa1778db69, + 0x2127d0e7d940b3132fab6b1cd719577f51bf8db531e37edad5194875ee74936c, + 0x17249cdabe9c9db4a1b88bd5636d3bdb48eb0ba6a17357452c97f695b080d5f9, + 0xa6b94822882ba1ca1da954566ad30322e3458a6e0ddb143e4f5f306fc9e3336, + 0x2486410df8f9b4817d82adfbd24aae41ebf7c4bbd8708d3a7c3b18a999cf79bb, + 0xc0b7684e8ae46845e7766bf7620d2791a3d218bfd812d008f73ad351ba86aae, + 0x97d3ee321f0db8c04cede13ecfa87cca6ffc215653dbcdbf62825059b8521e3, + 0x2bff71dafae458bf4854d7957865e2362b99a7891cdd38e17f76c5828aa16531, + 0xfe15f8b13351058806bcaf16fdb68f3ccdf3c30f15a85a58df2dcfad72e296a, + 0x2bd586480aa18c155f688c75ba812ff81990930c1aafa4058ebaf667d41e53ca, + 0x2b91cb72fc45f6dcb1dabf0473e2455f28be6eb1b59cff91b5fef3b81d628ee9, + 0xcdacb5ed20f18668a7c3f21366e04150d0e877756e2ee1cee11921184a31a71, + 0x9239d69b632ebcc1f559752a2fab086bd46cee120504a8c94b4427a2fecd5b8, + 0x12bcdb6b20dc77d3d5741b3fc61e1ec6f53137b01a23f48c2a267d6fd59ca0c2, + 0x11ea73b3f04690ce2ddefc2af3bf8f8054ba74dc313b09ec09c96fa29e865b0d, + 0xdda6467c64b0249d2f065df90fbc7a685022ace6d9cc6d9c983dbd7d29eab53, + 0x15d7c61e8a8308e4a43d992947c0262b65bad163a8f101423dee64c22bc3ab02, + 0xa825acf9f09d653e06be5dba7ca63648ebd6060377101080daf3de7bd9d5380, + 0x2dfbdf5d427e2fe6892fd40d4e97ed7808dd823ead27629d894982b7aba08a66, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x1c9ea68943d8c846364060646de0e33534d528a23ad82b8ba6870754281db559, + 0xa15008aecf43fe4b9a3bdc26ff03e3867e974352926cb3ad1535f7459648a98, + 0xab17a8ff84f7fa5d0daac95c36e606fc6e133e7cb04f0f7b5334e8e6c44ea88, + 0x1495d888378f7e12c016cab0bee2534903fe878d5650aeeafb3814b3a8b1ccbc, + 0x29a054aa447d63b2124f50ddbc4c2d943636ed53f22651aaf90fd93dcedfc941, + 0x395b15a827e37a6adf3175a2691c288aca68e16154c2d98d96bb0dbee6a3f47, + 0x2f47066bab9349dfa62b25ecb43354246a47eca6216c1d12c36601fe3413ea6b, + 0x1b1ad81eede52f8a8c0aff49a041dce0b55a1f06c826b441951b6d654b804012, + 0x137f27f0b79cf88476110b34e7ef630d03ea21338c200322990157f50a8f3fec, + 0x131ff85cf21b1a68336160757d135e1d605144f82b3adac0fda110084d120349, + 0x5f848d592e921b0c3c7a36a84765487b1357d0ec01f8f329aa8c6f266f4a85, + 0x2f8999412ae8dcb4475413e72f68817ec1a094272744d32be4b8a0ff74bfdf1b, + 0xb42e032237f3bf21ae95c4062868751dd39d0f68c06ddb849f691288f33e261, + 0x199c8b45cac96bb0db0f2dcbf92c361191cedff0d949606a140d3420dfad31dc, + 0xfda38b5f5bd1100dab719bcfb3889371f5ab9ce9c42868e7bbb1ce2d5a85f58, + 0x1bbfe63a7558b0e9a002b3983058c3cf399d479f7e2193d2491d585d541a086a, + 0xeb005763e3b3d55840741f0cbfc95fe55483854e817b4d7cfb4549ac79cb34a, + 0xae77d49a777e5a22a3fc6aec242a7a80f52af3e1cd395cb8862b09bf3230ece, + 0x25c1db48d2561608e3478c8238b3872dea6de1de597c4f26ed8baa958480e5b9, + 0x150bf881bbd323068ed07cea87050866e7b29818f3d36e08fcd35b31de21b85e, + 0x2e9d25423c272d1989d6ec5e983812e73575f6040b3f775fc9bd1c7817c55, + 0x229ed6f052976bcf9f11e48f4fccbfb450a7b92efcfaa532c1c85a059db33cae, + 0x3ba04ce72a78038c64773239e8f8c1da608b93fbde21c2ce94af9615ae10f44, + 0x2ea6dd6483856ca2a36102227dc147fbb29fcb62ef939915a9db66c103a99abb, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x29e75237c1ee6bb877b6e95b7355cac03170fbf57421be8dbcc50f08693db587, + 0x137b76a84a30e906a38827cc4b62b1a22e942d835192a98c514eafd9013a2dc5, + 0x1e2a3dcda8868ab407f15b612c405069a5c1c545af827bb0f8f6e32dc55e0277, + 0x5b71c5d1613cd9b6b3cfe9400cb5d8583a16dbc1142cf760ca6aa9f816e9f28, + 0xa7603ec122e8e0178a7cb29db181e2a9a71f825effc8415b8d09feb7bf6ed31, + 0x12e4a61dd3e9834662b78d9a820c25660926039237ef579fd1eb260bce13112, + 0x17c89d0343777a479dea31744f2848ac06045696d8f0017b7fa9d3abf88cb373, + 0x104a21bdcb8e49245acd6fc281bb1263976f138797f19634c79423f349d6dded, + 0x1e6ad3ab8037bed2e36c872a9757a796696ee2950f97cf31eb83bcd4f63805, + 0x248ad6966b401086060a913af010da4ea282c2d1461e3dc100569b3bd1685a16, + 0x1b4d21b426441caf2545938d41bcb3b37c32b3fa15ed8ffd1162e65242ea4d39, + 0x29c4422c99599bab17470ab9388ee796951c249645ab164e90530fc851ea1fd7, + 0x1ce500e40779238422cd47a0a6d7f3dcfdc0c6902869966211b0b6a9acf5171d, + 0x19102e3c727844fb898c083bc1ff45d106a293d8dce6ed43895782daf691a7b9, + 0x12947f4ac2f6fe4b1125a28d17cc4a3e2db92fab0e0b97728c8b7bb2047078f3, + 0x2a7639bcd6591dbafef49fb61db710e9ca0d712cbe81cb86340d0f1698103515, + 0x83ac15141e94aa73277ab521d9eba44ee30f4e02d6e9c1568172bd18c9b7e6b, + 0x480635cff8314d917d8a55b349529dc633170a143f4865713f10007f7f4b7d9, + 0x1c03ca2e6ebcce9a2f4ce66bb039d036b2b7424ae916bda6240280d5e5ed0a1f, + 0x15e7db7d25266f604b8f942efb4e0c32c1e45621336d280f1b904c3f4052936a, + 0x2215b41943b064cdbc20179c98c4a6948c8cf249f04ddd18f519e9595aa33b, + 0xba3d24e5581d6959c2bf9c0c69560f1dcb6486734dee56834898b97e8c04b7d, + 0x10de6cbb712419d84dbecd375963ae617b7496be8ca89c5cf3ece9d30f4f854a, + 0x2a4f4573863cbfb189e17e80bc465161a508dd069ee4fac346c2b024c88b5cb3, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x79c218efa2fcbe1cac587faa89bcf970134391c8edadfc9d54c666c091a6829, + 0x112316416efb7fa45be2c134395b446f048902531554fd38e0bfbb364d196924, + 0xd77ef457994c37f8a3bd0068572311673ea26b0fd473aa1ba9c25c6a627692e, + 0x189bfb671bf421730764e771fd68f01e883f98b0aeac6e5c9b623bdf1505ea70, + 0xd77f35f4ab33fd80625be829594190adface4ea623ab12520920ff8e707a591, + 0x26288f7ab16b1812ff362b7d283539b18dfd08362e2a7c4466744a8b815b0fe9, + 0x26f1bd644a7b3118e55d6beed008d72deffbde92815b8871ff8d861153eba032, + 0xeb8a1d5ae4081352c7ef3d50b0622816fea17a0fb9cb163c0e544da8a7e8ae0, + 0xdb56b6264829c99f094eef0b8c5baf36f6c9518555a9b8ce5845b4d32eb96e2, + 0x20883c599a195873758fd917f44d2079778ccb41dc128b8003cc007b6fd664ee, + 0x19f29faf9c5393cd0b7c07a902457096ee6543d1dfaf22a4f897d2ea6599860, + 0x20a2bbb3ebc1f46f939e64356d5d1609b5e50b5b3fdc7462b4faf735cff66ee6, + 0xdf989faa8055df73bc2acd9e8d9842bfdfa81140488ecf67db886d58d2a84d3, + 0x1c208f8e89b2c7fd65a95e2fcce432f5da8e71640467d21f351b169d03395c9f, + 0x1356fbcda43f79998b2833fe6eeaaf63886cf799f55505d81164c882009151d4, + 0x2e99fece2dc2aa38fc4055171969feafb838a5f2735ecba803bb9f4d18a5dae6, + 0xe39c64bd29c62c85340ab8eb5f7086e1c9bd733945179b108891f966b220874, + 0x8432d0352bce6861217bfb3bdf0a04f3ecbeeaee2d360cd5a28c5d2305911d1, + 0x103424d7f89182df35cf2d59dbc2b453542beafd78d95995a5e386aa2e55aacb, + 0x10e4ff8e36e76842ca11e222592d318986689fed7328b94cc15104c8d86e2def, + 0xa6b0020177e766bb234bec7dee733678251b1c8899c516ed2832aec23623c5a, + 0x7514523d425b76b3a7812057725c07333577023bc38d70d079eb2d524d94f87, + 0xe666408d6019b0c96d7c9dd5ab9e08a47cc988d93292535265f710873da5b08, + 0x2339395b0617cd94dd101a4d03051e9436327044ac470ed0420b6e9bd876bb5, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x823e9cf59d9e29590ea5d5caa60265f1eefb9ef497a8a653e21e6b884bf380c, + 0x25015bc12c22856eddaff514db520795225428b8b63b82d54e6ead88904e716f, + 0x147f4836af834c89e12c52da5d778726c878bc2005e78e9c0bb46ed47740bc8b, + 0x695c3ae3f6aa362df3220e3b4b230d3aea7ce4dfa4629a0b3da2cf68ab08b2, + 0x2de7695bf1b96fcc94dd6b9f46184a9843a90ccf1891093670cff21e6f9a6fe4, + 0x21326346451906a82345ff6a916bc7ffa139b3edf1ccea12b1ccaa554eee5faf, + 0x112efaadc386b3c1abd2d173beae1b5a9424fe57fbab2c2825c2e6a7e663fbf3, + 0x1a2a5c2b2990f00cb8bde45b57589cd7fd1c5e0df587d6718999a1893f0bc8c3, + 0x2087e95ae6df27098e3ebcd46f3e4feca4aec7df172d5ef293849f671322789c, + 0x254c2d79bc6811203b55ce01f1e8295095201f0f03613708366a7af5f7b9600c, + 0x10f23dd383d2ea9524e512e2c7a3b75b76acc7766a95067116493a0d1db0efd2, + 0x80154347a02980ff5274996369c7d439951efb11b19c3607010b03de802b81e, + 0x155940fc6e3236f82e7b7257f0828b1f43cad68677571d814eeab2a6986b223e, + 0xfba722c1bb656ed1c16203506d15a78c79088a9dcbad00a18e707b71f326ac7, + 0xa31c81db83a6746fb9747989509010c547d619d1823298f1f5674551479bc09, + 0x16a2ffcbe9959f75223188ee2d7bed0c4cb9ddf552c98fea86a6c01f1c7e0dd0, + 0x2e7e9b9c74526581808097354419679f2d878fe4312934613b01820d66080fe7, + 0x2df5d5cf7d48de207d7ff06b292961084478a6023f4ee1a0da7619008977d815, + 0xe1c110badcba8d0d3190b37de62dedfdc2a25675f54d4c5bd6956fa5b6c1d91, + 0x1257af1a62fb76f7a2abb3ddeb256bde2cc31596ed9a5aa2da5df05cb56b9ebb, + 0x1197774ef4175d674951e91d56afee6229e236a6112a802c20621423b0a66f3f, + 0x15787ba0abf814438a3c358e48b84cac38c4dcf66441e29b5a89bb17b6dc50af, + 0x10df04b3f297cfd58260e1933420a96f126fe4a3f9d53000e140d4f55c2217f9, + 0x26522aedb4ef7245ad2e50ababed3e320f4ec30b43f2bf1904c956cb3b9f430e, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x30084328d537eeb68e55d5593d350824f01bcc9a9d8cf28558982dde43bb8ddc, + 0x5921d17d596463a98fabd2e90e2ed92eeca8b791f75134c9aa7538ecf90e450, + 0x1349f05b3e3290ea030b6f2696ed6df35c27205e6bd904b569c363d985c81fdb, + 0x1d92c460a4cd6ffe4582a5aa95ff6a8369a804f55d0341dd94d495d538dac09a, + 0x1e27ce95b6ad61a67da6b7ff01d06998a5e66b70ad7086962f8b6f6687fbe00a, + 0x260b78052f342b0f62c4a6d75c2aec7321b71c084fd3659255713de667cc742, + 0x131e63069626670c022ddda083bfed93280ed3db252d51ad6a7ea8948ebc9a63, + 0xd89b6c7f1e046e139cd4b937b5f30e293b478845aac1e1e64cd90738dbd2fe9, + 0x13b662585b95a62cf47a3d74e971dd1a2195a9987ba5c35349b2ac299bf6daea, + 0x299cddcb1afe110299b2c4589888afdfc8b33293a4b4f7cf822a74a922f4d61d, + 0x243f933137a5377ca39a64f788a1bdd25027e4c1579908aa2329c18f13654b40, + 0x152517da46773ba3a5708a14db3239e59b4cdaf84ca55ba6b7c61e9bffb6feec, + 0x1811c08f29173c3ffd29aaeb2d9123a5e2b5bc32e5d74a23f0dc026199f9c8db, + 0x2beb86f7fc3941962809bd8c7209613eb2f403a1db90acacbd487034b4e734e0, + 0x22d40f04d25617323bf6481a7116f5c77922d4a98d867730e9717a181c24ebdb, + 0x7984c5792dff5a244e45e8d9ca13d787cf5725f45513595bbff1405f8a12f62, + 0x54f16dcf84267fdbd028fc4e88d51fa7624405920d6f85771606130c735454c, + 0x1e14b42a14dc7272d18f47c28dd8050fb3993b0c0571a12f3b3e4a4c49ef788d, + 0x125ddc89a4aeecea6d3620f026c2a9372fa856b53d8ad5d8ad495a5eec7ba24d, + 0x149d09583cb39f4124a7145923205b3bfb7121c62a39d6238cfb380c782475b2, + 0xecae7698bbf994d656a1d3b3df5668350112f80a5787730c8d32436aae6ee32, + 0xd48fbb1cd222f052942818e73b12562f7490892f474402274151763ea668369, + 0x21ff6e0e9dc2c5eeb19793fb2b3e64cc11233b81df41803b6524ae510cf0a29e, + 0xdee76eef76340680e4f3d4a0c51b87a162db5254e981a7684756e55d8b513a2, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x1c72c610ee727a6dd1e885a0607d35cca9127f006e26ce1f986bad89bc3bf3b1, + 0x1d8bff20f53a1b7fbd3ed4f015ca18fa484cc6fe4fda3821016d43a62db85681, + 0x1c13c5149e5fabedd52729f4e4502a7d0d5058c532728db8377aa92f1c3e70e8, + 0xa2044c5c41c0e874f005528327e695ada2337dc81c9257b6663ad1e37416a31, + 0x27a159845c8347dce715b4de7d305d529b7c9bea09d3fb1615b69d5d0e2e9991, + 0x28a37316b111822f43ce287c632cdcde70bd0a094fbb0ded49467acf199cd86, + 0x69b007be4fffd6c1611b22a1f73aba8d334eb39e36488f6dcaf8f61b07cc842, + 0x159cfe01b040d2ed27293355e3ddc2727906018eab4f0be23a0fbf924d74bd12, + 0xb538e8f3455ff2d7f95203ec7c7d12262d7d25b224a92500923726f20f4dffc, + 0x1f188392740ecb474a4a589a3b83deecab0c1c583c390ae1e3654bc90d0705dd, + 0x85e8ab77fc680dbfddd3a41d1f749a5b25f207a10fbb591b2b2b70705d88911, + 0x18038e5ab85927a21df17e8a5db6e3e62242f7bdf6e662a2f973a794d132ecb7, + 0x25975674afcc9637d27a23b97bbd8b82874bee41e7b84057be13951531fa9fc2, + 0x2ff9d4e295691f9979acf589c59991f2f8917c6358b76e61a1b53e1184dd3611, + 0xff8d053d841882947fb4d33026c489c53b410dbb7afd04a3461f2c6b46869f, + 0x1c6d41952c53460b094bb1d727059e7ef08feb073f1d844845d53b9640a09f64, + 0x291c286327312c533d3e244d73732e212202e546807d2b5d7582e7bbdd28b10f, + 0x2c29cc08dd040a2ccf3c5ceb34882c68f0c773d055766b389051276b2dcdafd6, + 0xb51d6531aef720d40d878bdfb54a8dc43686066cf85e6eb5188c094b173930a, + 0x2eff7e9766928007d29d2555f466ae211166ddc034d13531728246b23850edb9, + 0x1c856f1e898cd9241df7e1bdb20857061acb1d825ce2b9c05c785be35a5066c, + 0xa88dec27698d5f11c3e2619b75601bb5f8bed6c59defa4270341b8048cadba9, + 0x171ca4dba69a7f21c315e9ec1d4324f8a365828508d62c205a0c8ab55322458e, + 0x2192264db77dda74e05a8c7389bf314447eccfea329054f694fad2ac11a8997f, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x2f9db1272bf8daf7461f68a046226bf5eb50de5222634ff09f06cd08c8d90647, + 0x2dcf0a905f69dcc006ecf519557f50b60cec57e406fbe85ce719240ac8ad4d96, + 0x1ef1e8e3bcabdd9c59f5c8bbe9c8eb2fee860feb4aca30cb0339394dd9aa845c, + 0x1f11157aed6e03678558e187e731f4e6c70b98fc36b5337562c565680e64bc04, + 0xa38ce884c10d28d82a3b6316f30c7fc833f4e1204c984b7c20098a13a0d5a2, + 0x1db78e384fc722f1290a337231d3c8986448b867adde280ef5eb72c45fbbde08, + 0x1e815a5b2ff405454bffb88b3d8ae428682375fdd858d9fc2fee3f76cd3a6d4c, + 0x370b02885c192b687c2cbb330888c9f4b3f26a6c054f70b092acf96d93f7c90, + 0x8203f9ff8db7576e14876f45be708f58f48e5f951be08bbdb4e9cfb23c244b9, + 0x29dc1ae19a1f06c6d67ad121f185ece6d0751d0ac335a9b7c879bab33dfb0e84, + 0xd3c1af0faea85e54e7da575cff80e5c027cf3876da141377410a28026ad4619, + 0x29609aac1d88be4d5aff5dc808e01361309a1a6c8c0defde126fb554c79944e2, + 0x2da5231bb84b05c467f6fe2b9b3e3bda77854f6de32ceb380fe0309c3c8c5d50, + 0x24658abc45d1109f9cb4ef1cfcea11de3ab442f13e710d10c0bb6bebe5b012ee, + 0x1f38ead2636865f16a72e393dddc1622ffc5417e5194d6c15ad8bfbd0073946d, + 0xde6a95902d88df02192471691daa4ac55617b73f448a4611f3d89172831542a, + 0x1cb8cad4994c3af3a2ae4584827640cd9dd5012fe4b55136bdf53357b4c168bf, + 0xc4b166f5e4c3ebd2ce9c84e88b3d42cfaee7aad923d9807b04a2bde61151b1b, + 0xa125c564bd818b114e3af44a87e694061155e19cbc84c50e0d29656de2a03d9, + 0x18cd16fb943e369664b89db857f6787b1d82a17b3940f15add4047f8bdf4dee1, + 0x22100b866fb7d36e656990a2c832bd09d7d0036ffc7d2693b22fcf5c26b05735, + 0x2228191716f3aed9191659eeda5fe346b80af580b666159ff25456172562c5e5, + 0x2dca6c96c30284bb8f7cf3467103d39f922aeddb431bfa3b62a7bc1f61fd9baf, + 0xa242a4882954de8d3d1e8cf0984236cd4665abdbb4d980c625c1d470349380f, + 0xd064dee824928d39f2a8be7d2fa583223c33995784d228839adde2559592592, + 0x116c85a250d461dd5bf2249536e50de23ab8e0287f5cbc62363c54c690c6d716, + 0x750eaaf76a03769c97c684d448ac7ae2ad93950a75c24f3482340bd29f566fc, + 0xde057ca401a6fa8a17d35a643f71515678944f33d6253778d116b55b7599cfb, + 0xc944093f1183d2fd822cf70dc124a07ac9397f3a941a50d0c35da8df5e35180, + 0x19376e5bb4d2266f833d7fae60c8c5f2f484b203f008003038515c66e2677233, + 0x169bcc309d7b6f8c73594d7563262ecd332ed38cb317d2c43f6f8dd704d32178, + 0x304811527f616bc8ef59c55565337f63a42094023b3abf89ae99193034cbc9c9, + 0x24bfb86617225eddd82f86320315dc68e8a7fad755ec408012968449dbe1ceb3, + 0x242f4b3a3535d5307261e9a75c570e6c06174ccdf398c934958ca129e7bde3a2, + 0x2b2f283271455095d3c2012a1f4fda54ba8f365cdbe014328e0753d94824f643, + 0x35a852e7bf5cf60b00f15be184e707d345fa227d8e44e1f4c37050d79a53a1d, + 0x150f777da222071015c6c4e025f67bc356fdfd678d9840dd2c93ba1a43f98ef6, + 0x2d8c70035731ad9efba92821a88119f6b8183a362be641729a93d6a327c03809, + 0x7b620c8a78e09e49ce547aa783aa78f3e4594c49ab3dd6f602bc6c0351d823f, + 0x231996b592528575567d39d00645a83b13929093bbfa00d6a661e4a690351d0f, + 0x4e47a72e49b9c5aa3f69f6af22fa0ab640c93fc524dd3c508486d66f079852a, + 0xa8cb4b2bf3f0c5da671e48f83e5c1b3018f0d31200a6f19fd5195db22eef7f4, + 0x18bbb002b46f2e5fec2b120faf87822ca8e77ace94e03aab5c16c4b931739dc8, + 0x2bfae1b054ef2e924d75a8a01283da29103c57bad129ec8396ce274ba4524df, + 0x6d101b19477d1627b9542581bf0cdfab38b05cdefdcb81965c5be00d780f192, + 0x18af61f6184ff85f104c2bef179b3ec5a5d242dfbebe8e27a2918f620e8a5be8, + 0x11e3a7c2d5f74371beb188c6e3d7a14b33128af8ee3287546d12d7777cef70cb, + 0x2de5d6a7a27343dd0422ac71b8d409b43ccb0b672e978f8fdfd214f4d7866404, + 0x227cb43b9818924f2a2588964a0ad7ddfa3df62284b4b3b10199a501ed970622 + ] ) } + // noir-fmt:ignore -pub fn x5_14_config() -> PoseidonConfig<1092, 196> { +pub fn x5_14_config() -> PoseidonConfig<14, 182, 1890> { config( 14, 8, 70, alpha(), - [21845584790817078371458083471368949437776490472877850604640045078191512294989,19653529167194186573342031346879012675435131167180408423801998487681049609228,2161640783454164110262374377277313793192503897274785966059544028153063342839,3054385704838408049711788708109646820127990212588286684954516786776077717445,16635301713639076283966918721405743045341739008997361549904617279107633739991,16225725689449395070421553385264743934675104858051374243666267106604469686859,13459300344588917210133884568970491767131781128923804903594902942358152425193,18076808066595657160589765822638228194586496301618971676220813553508533309824,15694780501519741286439086116053845024521602672078716577385749258673935540935,16872540725652861460604107748085417998883467929955001131816309200004825208678,18265717256656085201140362928095712147159090935193139243454994794524622317396,19947609676398163035598483882491861002323351300468831661031717096486749401185,7065348755377637300800426777670517297442798705186719592553630280930183590981,5932961695686545421777788171001317503890223201383043783424823453778021729657,2576876576710667081195577161905871971928185892200731156106299121736713352612,12555802030075275558510564984903031995058560722557285963258561359487710166944,6675427211912119210966904017515062933064977336124153512189140864737663166184,12222599141329943348111473622063042423140762381594560767061296463113725630598,10362975561623981137760844569177506781739504467939943515494131756563631401384,12107531632347826132438108083855485290921771214734424618157420540758495466114,3236413362865617508850894632024597913345632839215458268170009274560894755059,13269640842689962370480760671727240164372687082286848502921603339956981268889,8634391395282326489812410144806386699066840792624899435283359752045476380023,14222253145252965302168372301361324351891663598874510374220732501857922860417,8638897321585802770244834010345336579513350450350318876059595307827518698264,3865974821285567306249300995778666703191077355251395536574998983854299535502,7110975263857442529682465175399830853738223819847928136560110618272170902664,20747849667914457283564964533975989346418433637631755372433299771504842519646,8525337218586373689263383636693181730826089466845186214607593322372086164902,15284698092379128147447314807096025894174546974949762301780223877793581148749,7697267363768037767923915437621109821518467158489394234232803683407232938777,18552464418403713636184903318257896949762751716606049583572368219578636617127,8197992130246671682417102475937137101180310399693221498504232752936385287840,6267215711691005252092821645736755217101102985763928035625443919819600833817,17433952956528062441211440388577119958754746388457390005635829394680376947181,4412646415700345908595327060988016573431087490581498127967913815901104779675,15833191543444816612091389727640172975373200401937212078659643034429446372420,2496738022051529758808536908421531340554055955151436808600608028881270179985,18865821309368781007158439319264225124435320863391412688953283839208730853556,17356853444859379852104523062654303386446700475095103588258687890090805160214,13809314487709569674040696128771324530575306163394456992422515709961741509179,16441057642509466688507318755613056920894191930223829210993196564779122458374,13126203992288988176378067141418363395032818736472538500506274256104409609416,13787967697762688988712839398243982920760030565931489906532854488857802399817,19656786571615920765259702874045834039087950126970888730192726308970074475638,9496155930249199891836650339371004045437843955429376625371983436016490755144,6133650980214690439646563353939486183333374330790371938934927663849630407389,9878750392407472855744714788091164958447986838940220983459727015586370325700,17172636845539329981401043696407061375416986816086343858560846660524543673690,18266068074968659293646594793202575012585251834459743250538629833034512472364,88170009072279647351671114053985696295758726185186407584170034409102883821,7161623553009701438320582200845261728475099875569530553253147102879319777702,19053465421328592764143131116469165876378776722378567877265112443326967288533,15787821054928042708896412640384007326676625326396861263135967977164294783653,9615173323505112477217305395762776033870692647990635021315350642536385774258,10748585844981412663149047472971001536312431184916168605042111548221680655573,17193496554920138070905215774356694517155445370515924892481894322048517125340,20981027561373479728773182418686452188471940655764396684028110979140369006827,21262972686125563821794309741130556914165641373895499794098515843451753652777,17107658081493676403630365275304097003600155220274082934263833389505162130032,12511894931761241561787052333055670047472612011302194769826693935710455626001,17806912269440585736864672280987816575618315620498245554921738316327046304192,19545292022072695979212345737390709562681030627834519269858193519314537426533,7543800958185166098093959246645025070235714806654195385000743554473922936618,4625475082534149232161405731224600013881237737740742465433231001161153655617,12763413547514960206069967971684559703789391875445961922711624474020658766608,16881857439631059221437594346198587121133192812269921863116602807689099485795,3231850141984038920375478271531925025564375094627983241106994584163478821676,12025284448956248150398233143375971306100458475218939512492496426861431663478,4525425011555084029555870990647344303529266577387030581756537915893006804174,3795501990414375556011654275060518399449630146003978757203023617760680325709,4509128642188781738213513757207125341975604363824265606323571895455672910764,12203047758734592203615462366516348191118610129553686354997732038970187121007,13638687018405787761639420673973367506339916347486774445588648879776248875396,1480604348496719441038523415355764543336234934845679094037807499653490493865,10692361717579001228187212442602435054487474561573499974105521910665132275515,5007773285184019093586454921139763432640822738583548849737728483623941935472,14779176361271780821074929551122175132746249520990325894754727749064980218318,8810869743928256631039877155210471039332035226261305285283609913565228857800,18154173501970140404154140565370264376529820426626464552253141823874364956900,11656303509442573507998921894257944851336988233800378817636452696829680890350,17658875741559155615021995850723408238216088494443352771306394733637591342379,18902160612986281748775835015982844003483334222891067179969353562662106908838,21595310045201809412620701470963174488544609749637202383626402540041734306075,19479000691333638193560008307308022198954460138615126342769742031420251871629,2972632723219534905306782557604159867920608086253824361540409985645334537267,3847529854347283694984727631990010016411937091308711649053729266492176961919,2403423343103741792664345548178046472942690163193710191494177026621927723840,4715026270007766325068951713831542483223564562870257986931331836552507312912,10050946066792704139911540686518561899625455529845988837175998569612056291645,8462612443675205626907647847435181314299724037672159352834910195653278990554,21536131862603746518459731430650379927614037990254564979711500405913555717860,7888269140704212528047592848167567446827917489655456773861487833453406017069,1170377169572693438349285053961454675716678619265656860173330864613871015536,19621259602533287127007734174330694952187330430513568066156633937834027643682,17165866032840109673438683878903959007172818091757219456373859826178202458170,14933333727688891927411002006378277183547380244506194877231532901665762194033,9343867619319423527260818064767777717418825720619434299636538864535443951928,20583768764298760141290708372295636534035063275069820261065362331153347542719,2577125135040205550039517386386446603255535410845714513971957864613256569227,17000415305135911202592785659979381300200707282766529883690542305214226820231,12511346220893686853445962138128902612419766727072608028194026193211924059518,4149764657828794758957335209849218835702975200988138041342768571619211624011,12689460200478357229673533402655824055278729189265502524126586766684281271735,13400421547966647260602415862775725767930791927979420926402318903131836007467,2276424802663141757392692926366037451925020546827329479674513290273559843227,13207120510498253902527141512742067250437249796266587317279641215901655830896,11305234940211349140158920206630802129159533495623653407204084399910372957174,5497774303468738593952657049388763226915569613134333653497976925327612433620,11780989050042171707300156320134237383624870460000896361633114513125178671303,11197132624111031475729914540831613691695800675640925983729890209473799714664,16140443794881450163624886684327741887016098106725788249967592676372285999349,11051595327889397185166361039119529941213436445931880650633610124485963060123,4836646605031570157308209197698105249544981108702254887271797808619270080413,8209009069949005083422618473679185090070432230901987251869909206753231145136,16474909562767173375575972470108350369290532718799369728226238753027802729614,6086055204212098936385823679317209054285543683998660974885049732319143968166,15845663692001601094665565765687773803894441337616861842355695214969875896066,9098420601018427903226168857535773321796962623728010568581252061114961655465,14398020486027915166775907825392652502550084557499300430668649177321914768934,2529766650486869899750453189656713618464482405989854109458777379339220142554,10340604539765718682878802989600110179317791699890691229388614321680034249914,9878876288226000720310995235539201725902546228232202248134844052052896121876,15598631334601739991411156353640870142866768421111507060679644747315412727160,12476036027414150699365888926628033468852849122092016651897900659667567319806,20803031063635652861008057675598133287087428947752503544588637173888166669892,11219667600899420706469792543049361323110081262796605270588885844619718041942,9239500483618882938511561535687911499489200513580468310964041871852656042420,2295137860333409753273134561401486593645236761709753752653034489900637997862,513840239484316074257070195372896343613221099656421936676995152626965728304,1240423160571920455132480263739570027604064696559298170495781456216075158172,1000335770452092111597579881696386094005166181014081250146819592415429840281,17732477784640275643871498532120858657597895452427536145089468999578047484919,17170981021801009209909418054936322243367033572422755593175460758882664580508,10474002915893131225108722048498342055539813455822038310171605686332057287523,9603348396520941909404735719689357385027896452682306755794683717883589365434,13997990766251226080324180880591113480591220558468819674906322487254600879864,19165322589470665586312376362321121865643126447966933590462565164041476345514,15889877351963901365648141054999234691357421706029208812358207119735767519856,8668047067682657740038874191537478915165931784511538119786089297082841482372,17366185630903586492716760756481097015828466883331247688174482412238176387717,21876355395221655909209577718688727663428003322801196411166438189091863032706,8342495812890419318878301820827026193204690451839354912098079931173365213850,15887225707174335160711915570149252929623026695369026542224074924735308390993,6378295267974387238182583304654614405910401210077434367173120406371155400542,8599288341856208016511446109829802753279910611437057243892303163654271528710,14384569526991087242726852106274677884712683003324629101047489219988189168985,12554858483255821944447983588851327925753928086067377749529759729841684476442,1244202115364291386279329790002693224358694897412189477392486275482043163127,12995340746860271768506969399635216407185990298275348495956441603189500195767,183027008509741755078232756367286076025735908110463758323021771971495606238,3573731114015522988150416514182944755210001235963017910935079689853918043877,18230391763740278339288441222957881377176531304894832542129957275399074045651,5937391935832132177003018978899438941930145516233683431615177125757010459652,11430996404641585372503695535042106445550893936697962891622779166741655729488,9708207568505790825432073778606679121879367766370067169784170835562004694648,13398805456168802594406839007653458669253514721606724093311019328402863953525,9509172607193998955864433140854270981598209332315830561489225794322679022459,15502257451151630587420754221500874210427552449899109970701467342791400645333,11123898636843146818131986172543146864729611142704598768652657993190010179131,14756654073235850387277128827870550186598788932163678015197111219905127222330,2775596743802877046549055877116659535653734622828894792515801349479916697007,19393614735747455293764838818808226619563895886462373669050764399041257455003,1249320178045456927170274664240781660345447736835400684416240818258732622074,12796406917637014666646024992328239080230785967810042823382614274279812889313,8731150020101451449969760761271583792743252060005019647239509560664328018351,9933789898048906634037638211430912333233899173340437080629891912049447301727,7466451925704968193666093494894304477671721132981190905063657961063858961172,18149794038935586919422942907608353967008376245075544434132167909292547581560,2645338086907790474420268058095037943265764190369965623902938950146047558570,3805226260777608297922168382052882356808083423152211373837998107098065055539,4989302370880302660583716899846990066057960576662320219898456979014043515025,1070415851697739963236557454136444292508409566097266743684211383600964969141,12944245506579810779814853939016758644439439209107032516878032396119045414701,11769349237256342071683275569967616595926207710668472449278925821680308524365,7515880964846644263997052091312985911975830135506678004303761824155773875060,12464357909913670578721898201968110981078170975300784494985401212355213230335,12531063240134560397069746994123636136169642575111678588073390651101761449521,6147041690306761331612194490775813268707261569782473045839636103273693189609,20058953556654404269207947758850631052629168082562724690664696238258819343333,10671449076032051862717464872993019906670729457438083279869852502398951441572,9263778898906682528709315203073828182663073896201474787696895934306219116039,4280018790033654530253273135477384827165889895493311470077828964783579313988,830995672310831856642518343627405480722960393571135174568745694822266602592,12314576340884680561277987296413286687270775984122709242612931854296075085360,17095784374018350334250759671947431499861842886424783004809423482855754115377,1870276341686143971262732849057691846357227120913088159474346497974038463590,13105414947588023527779026549450388391878972150198998416931943855651155797800,18101033009026370452679604491367700242633788731529564744613454397646795133212,19518878118392884244142849835491751668891129028130325012169949275103156284312,10048097099868399020473369161831917580618232227587941412911792567651718843249,13720988503976110065971074438615366180970893755318530444813194189426744566454,10206920761042395073417518236713913313307032364045319534823111708069826397746,18034670825630502903409981952109964720282628088881306395156166316305807778803,17265902307488235822005808880948915593987424296023174321440226533612013329935,9429365481099850064016032865663594803605999180077296169535937496741805848481,13186685927810765291293578499657740344232117785406437983769041709812502541933,8033401834359804746763731113146503141828920003868357417085510169143014612168,14829873372988191912376824090708426813704721449621613864198115299064092181833,18455257181054398358097306328798734574318231150508108527392947186444436439740,8119199559569330746396633117116309013908934582593556748077373019932279318500,1284108314616459045915004998457007728060914233392140668856369685125999999332,21852625948025981910963631951406283302114607467722317806583142816175293668265,14294796340840469579766310516350659401625921390409030932793069064155351769891,1783113620816999591947201004404230259494066685648885624939940386561651976668,20631226309571056417714477834545747594141696200863258945898766619654143617824,6903938062054591003542771080232078653298889568458433305746325082721608484955,8256881116864939888001716449324731552833717991541507741291129726788047573071,13687405621147199886679388919812090637070670174751017085656416653029285459311,3996906960213710686419471713152378445913261990655942335471489495797584984773,18609485914058202995712970621084391939086418713703752883448366703199989106805,4737790485362149715518348725962346663474900881645708435962411601476490671749,2822552925802124863166593828171280409095683790486058849977885272116463701928,10894109234909999803847798036461479359595641981247612273970502633226141682614,7246294570777241116302579516225659482637719855779307083700855528941826872713,9013198024264523556163293154624511496427558116561774530941327330691750043628,15151960056770776873319338589377108700463507419234056013408936730718825997019,13896307757522598026854039348754398062744662686124720657491498342048635150631,936098917227958663269717535799277732372546413929626514061262842640907378836,5762347306349503820330412402395950955095460299470544346332901816556543923381,9011672463961728692091882997147124758454879881989902775354620290305441817434,8298508790377315029478690089877957774356278876814712068800423484382883105746,18441738918640842202469737660313781809854248733890462980130113721522272925935,11674356714078179732189659380227960024612632400322071192164520398757529418670,21741531861742185590228910897294372846694047325677774428196013372184305103642,10726909710822683151420187237143914110905744739798587383554354069582246136039,14605794533892313551961292244462849563801666394421863533658628423573613615452,18252321089326369077368015604893296999452816437445326292408407276685442204248,16489511737082127400599277690755867907347415222776413612685047279770378853014,12335271216576477339942530570019671580774683415225712107993157387028894905764,4626127015007086021549442631728304324061443778286284381465764558652325702889,20204422163930758830873934092037602825061261159909688022442254278786267559979,5908008139766198991903649413759936674892226062609391695798412118889649830013,18949218162516421406624855541340518738013110700902674485216824630035967277648,7857158354961323527996104954036841386964344142685428573605787682122921808752,18862506387045373228977985979058776771998946696427211846227485792071994347569,21130307920872379374988363214010414716464915978170248808030666261671221223543,4313228149429751211745340097430041420420928800665815874510443032063502322102,14718887479978402714517595897896626933964355973039392802299204272000024809808,6557683321264859885031038170253446373377122179252187766556430383002360480784,17122476831292693338874176268140351589680349774087615644242938775777697017452,1742427015172593656128486448061422456944242303531295475988475807736737942042,2027235762831193006217486738647428392424417413253628143597055373587736173882,18820467606179165158872620834655197843967670286762404094202648563691406576741,10125524296683464483537740904779830909043887085914486254166411012113004643542,449309305485238804235855079592488366640797157061432847068620096879828248038,18174298857888178621780055946769726501913338858930582293820343672195281946232,6524685458133323533884653748284163312203275737781993034758692071803006590911,5779446108310889204396522202292098396120321905868746440329327547028173740638,12117601207346032264472777912492513317230650895345305236204051403325746076935,17386891799362994472985052445984141822367941805998642899269245566076967495748,9179366996073356039318771265789433069240332535719540885945532359919512410546,17951430600208154118507690771734790328820535928178248368783575740656844500941,14192271756367781523935569988212364655718978403224403387301537958961554173399,8221174165933793163901377098818684602634389528051583218569555199418881843300,619524678975534727395248661178123212036053322038080027161284774894885656968,6811391538547034359716390364062047260775039349151599816482953672829058524341,10339322550348888691122766885623110168053574406341544663827975995639398303045,834547622517043358034390288436661677632262995429052976763390684889069201500,4521430246419400790694482286290497928487157243703675820424059696776489816307,2856429439451475378239016597030439586695051951861405539943990631405466607827,4111906549409128541352401705521383327041723912730932911918947847640475304547,21238392279368838153073998702772069142756942255081903718049634748881681359750,8024413919212120225608654701439440497293912481641002166919294547045993866155,19638917754035941400580825054915831416618623037514650566052024405861982044782,6363298127640737755043533904928034878703559551572444680730376201407773738099,5951378579926778764731263132308899303911912211097125509228135617058018449106,4299191983632622048727922852687899517860127872286225781380066638217198421795,13147530014153459600370443470203975351218206668086180214214011567772265521187,8932462500427500118784677946351185252169486521981702322459979960456999825085,12898236202423618599592389067167172325929052486002381527830813712396261626227,11097514049007489440587570256998525432340163981998515135891661207289091581098,16939217257331433664860194883658557949066598882598231827843396489027582239493,13558314929316884214321653422030897165706985165664325794343497050086242614930,19068785933927002693740188802713137005358154768592984493993019480794959714772,16219047234078325455733500620647043268680743772219676241027699492382953851822,11566125486619880337971321232314420701391596877779136632592874470668332390604,20247803830618639726625840441081484205981495541890152476410337155981008644211,10982561928418184138823352638412764796110898816926174525705905870653768875109,13865455597687551061085338688013943905732507438297014744008229213490729171094,4623686187146061526075222395870304599606839445854872221666055672567414423759,1297323969860517810025547983969849541225259454470688019030850877270479215579,14722215188887952104786572716523684038024407798912988920497316253897978502603,6270780574886929570568937279666637132374218041131318249843841984676427785096,19252799885324088942740034016032302070594496616562387546044018090542659494091,18789886326443791197255838067795128702043473536108855579944353350374719120963,4004428942869607083699086726311786949460607919907288923307322356602295441411,2877506877897472797549134443444956093653579146599656174810841010891875571228,17100820986561348145097462952844272816935030845535472396118435485954197036467,1347748684215721199150368750223253727950390142032926135229664962610534785585,4154005697105794859947043472401749393077233408100643568245878899626874345951,20933456016305992700551258430315019036248529816811141758791937748005878705139,13670472427221544431486503737474464655536253995920989690199387492221273597238,4887586768965099882782231950154450807371608927535862225573402423957578253712,20873520765554306935202238707923195971241799663989834594965009759362455236319,835408880898587261190035308896108471998627156220026699783039947254106997118,1168560772528590466033559747490971813513190425644816736321133758228053063362,11336620716299236865855310989061343228509583886619209006261263862998075759368,12980812954661261543443724949390081395650693161075132555819949729859873154552,10084252406967656001546402499122907140953995723236718543311202294822930374906,1644532730355076490850165587814950390528959259229216666472798276024619697665,9132885938811460827145905853169583367514769405887568204387077749084430489477,2725900975136309543580364211869546121021875237274249313229081305044972484552,16649132526365476017376435851279563056385888284228253635122650167497125722498,12731917506454877589272897239554773638029036473865906141458475592969608419975,13594653727945200481903485136384279897657772670755085103508581365171774040719,113624989360858461940510511528457240403880397732971520793552365714387680115,7789436153009366426158912863312519977840172895511546817589361831513864987768,16143950714560148477045714466178426422461079160482754992311521791041688103078,1313437798365489562563299651704767522651128839986029835665434483203980839176,11252213995691856633725287186457035931029344732702134439407400361778220541650,17736157138183214282785525992210357080431726331346127883418866302441793685861,7180555369115773227093283745784562042441101566557650242391581159039035173198,12210449409908576791549312007483796989239766997007433768188337654528776461829,21645736522624670721457131423612680680560891552619001261475935027688037968464,5181231859976513481992166491356437447372643837921293039933901630631480168455,1822647984377309820943781894578040991064004363022862403681677456868041924061,18871375493748399832446064841374255973869421566131394074253151764055941485971,17104418810613244184376069439022653413672092602368197196666088607272531673120,21352793177578730013875622823471064860889253282644816974785905687738185801553,9232438288408252188083609458343687653050330220889343945216702072572457878290,10304159048240945355136802455474936548590756836618851032143486546904634881690,20884395191144673183897559585241012685606665510456998263218110825947409467914,2819516448715556874313717913942313640504691377816634987702668983716292161632,7032608084905515886212514778954491987158299018684745883187663518324250619807,7559036428305013706113865872782652760220550823937161831466421604635377603666,6166475941379369323404906159647871547076193215494151224037609592313271326716,16084803679651600781285997577643662084204923480676236051120275962952234677286,6658815199061181195201720843092877884603511322340036305618980989430727251871,11532335040368550811455379206918215244397070466594500713220916970398105300183,223243445248411375033016341241378810903532891138952541245228108341484828711,3833279990355432746436294779672706393587026552206068860301259597964955244359,20021860409670140006280261770552932742716715786145482153861376747693162890815,3960940475385499730462877864983553000107482077213680397288242993303568324972,15345391775733994458108231909936015494312151716517317512597014646307002937890,18277195779471824870812914706668217603589292191686932445872231693455894425796,12683998657212817923655738438553698764065257310760896868569072930043411914592,2381616850898069714423289625050293940364468416728632275660762167225224591308,17069254001556064617313013226218540738464402615134272312196301018778835133248,18389457738365086195717208767239120166429330517506018082718782715649157736034,5051258247116083013584227503078370155132486498229823799712010421955209135014,7997986980169935581373258514853533781209293632678320920663489466999553296266,9084231611273069170288134842362168520424117219722297893241580415854843050029,9612017102514059830687104062100896777017998502712927457146148255553769995330,9213917869163068338076473790268314749980273391311658654819685979854193078147,3968414534544698110694188177667553264094402034823447016934487565301236025995,13588240166210590726886944410340082403890007139576685347416857458181479170063,8425770643762906660570072207190993414304346471106950840911695090319487814275,1652806391920335323990555627698612547647520442841733871570123598479115999627,18130776043151518739068856550215769502964647168112043888178493846726550417660,19135684176515473484108881204420762325009779099777199113513850601885029049659,18523926306415003163998391622948236629256503699057039444767412461271077678701,14918281748682691271882204320979112338671695483566718123583225923120856316295,8780852767944315665594165432479024772720494001116664689088446074574987494813,12668508386943347180515022360355291044387148272127255261058463414454846963242,4925095646155669413280350202274427260281996843455607837164490899877054944846,2595801235413574965831438899756848851934934001108314616806171013774086568322,16016207465062828688275342866097975914741628027802243675066228993942777558633,15024416797683381415563755573423733835281624847950439607885361353822729812986,13470695612540254635863734898909669181168896043111281127113964919743317383261,16896649112088097145823038767205812267673142507502911459577638240816340032813,5645009976160313260833270091943535119457478455011072475922688828021639421410,602871159134715892643983949134724748180211299390344137568222174867411670803,16865933848430240952665445021880291168087114172384742393439371745277930120747,10638616947682848797128584610899807071800790542581123346366834113610995491100,15823119882352004895965266205059246906297215947121418230976223923682971872516,6335662959372125109139397987508104273775067107064186843021683240893850916670,9015302195224176847832179354591500534302983921972567063156768309852422127379,2916208839246568972516202976435804092919863447720049244313355052730101892832,12462097677706957512887764105458513125712391543206668564860335255817545411462,12645432056886268747459912808478608940565989560801243474226148714998374680219,3180920336675161838114354449885404230480750260525222632193238650778186030194,2765038069658052652090069059291472962961753315554068900506936144102952443412,5456153930594691794518876425254629839890061712982880399455001410106283524009,475588857464770407073340860667255085025964024669275489020055454066130988320,11604422213771358649337761367286746573670774367844043829963235653833716835011,21672531595983328080827235954964353440581013778240609331813180834517858151965,4158282767336475980124978163165153479336138216933325437750412278000398054990,6032343652765967766200639763117076693275022773598878447445516751911914770612,1408994971542022766817088410277637989937031937486427645416181643240579694602,5675369397167644827707774427966283386689036453227097867563588663607826158481,16553836408556819911384314376537283029998074714786222283151724244687848945589,11305817545614916257748042736988000193121142053044277161651567885557438654074,830935697282120891923075627410843569046784310505888414612692179620161520408,7111327705324010951262975966073430392141084274376586856008212260205185475707,6041014280799995292240499899142298082182090482839684923821947404991902712715,6861532079489296739625909197765090537384733717891476126939216899495278356435,19512767336722762932902171703888917915267449700217444230295060094846152793374,11362087145491820831916999481856548088963000118526088967383804499026380829346,5345785713105818128869449775136443413167434948951799284901802489769456439786,17034353050546517551433657764343123751855407033689772581554238132654775360523,20948587704598096549680941899688868509854524167514075706787714294359604474171,4994911941995400553330254818898448719600721576253446166237206475949959408151,9688152172628114951713346942216519356583583295750612146456768853572234580639,1343745797764784294443121474436370243518251011725658365765145682550385976553,14125032499992691719199426991191077310874247595141214711018898761632184485555,7693434862282992683488101124262547552730705787109948156284399632991566403920,358969526543359888045815665915036908949414956460937733680920722686744813444,10388303602140838746049100800433273910870825475060431768126678575590491651119,12003019672927505670536349874007900046436859031431459357691867861903891807068,100475008966885612365204906854412018822648141035087921833385587863034960276,4380976634270985228665957813264807511324931231158992383372104805973515660993,6796890817241810905532067210297629305992402701618394901609217064231507595098,7688772779168713577464553940881893522916379475003769246647902913600123216803,3719641128095581959416223705616297841752773711170097329183166123897200928969,5811339040244843745049016703193592081836868671814750017107506365287109556605,10595470132919677811136446867941153163237789139416696690218064678877242827885,13030722908918648575860840375066614839148197698661025042088986261543919080554,14270313844057453712442736904892342369114041625795108985761645871570953543978,20755955200977796735614094726104970512145122846293966132203844248531587786651,9582579815411229200777590264696860160165980649555432144848137253789895405534,4350662320089661964064338788392477540031840065706369837322029959874552780000,11294656075067466938178599864610454390092206885966775647004601601555888026051,18946972646213006149468901853070557711933198234858050136328420076856760929327,6183788518442229735210652665497651321434896307527846329693517674734369795163,4357012315121006561105620778754114894493832281520086713987988030701496525309,4220425144490786998849301484441980495606132822919030749888073325247349169938,14847262709636261703845309954203315918152776098063861666522433996841734492983,2207604061881398535333278399637137320820424466179707349350037157354962490429,10374520449793714488752224568044645973292278262497536584844249765683309087900,10046752763001031505421631811000499551831682948464981948135908582555522139635,10191830759680421095919984376117799343794470779618993576052513294297834150862,15076222662591944075232357720469485509899269012588377631779056491168825321779,10030346249770809877262359992756272056670319300684833869196768465826414079904,4720507975531560789365265597577186025064384475474978173798769571327267599028,17191621856092434134985786932980111138837305571579695662259528942970338620884,20148399372131987633026319910847242205929076170415419364579318442517450329463,18536741510173922435024204045457609239829288683624474544615917164289358647693,13631750264342742049519923217689863850040711017202360015936348405918551837067,15610854494548438731317902472235239790464071411103741562289565846725908998069,18387668285066173974072893371855420071639764562065930624890442086525580978084,14766673420520500288514312076124802867192062521660406237863986898959550205282,3732185864446238105520935485353063605521423641525603230547743875428671598696,6726861976047081116380559824755952195618930495454092484512720173680677582718,14230102015194545129058653592673168907799074203765469344837164009883877641547,923698051441061755360657704655014798009775419003226945193621553062258046271,9689434574353223411824004165283477169808920117596652474458537007050145695959,6653548670473374668472111797166160911158340899061222339537692495508721251614,3795538039750942962828904073106200577850807348658267681985654384336620251059,16992880538370345570685975897913090022139738512471371596260168908478239467806,2201111019550353407862043052634082471477202486461462021878536956251970423986,10288260758300652435946350416864664136108249309736639494191503136475372654927,15709483617520776431567199768118570957603227217270596124343406544848127051229,15072326085023560939831375504206736581668538451241556883193631319058350825383,12561979699882391671048614617301093740097194439650447103774288376923816448076,11578577676104716528266269909528660737784973170422409028333858070522660907599,4774024940257712349371248845501840009544530180895035663519273410524858053238,6492684254039247711120616647406430763803059236762636509335603649550553435616,20771468823570726361366818215861608649059576818091620623157713556101748134372,11770234809483645852438195876591109251904813195909801267796013610714277347278,10322220982623441869990996687272667519839773221084466704263092761447901512117,3873750796549479014998049182061589742243147534079044128452565125163635863792,16822068107147748367260830510353037256008422122115738671496285709779217814945,9894626898191884524351933214321095257519558205219922050393534754827614996074,14601192892171927905999982540260020693712306290426245380657926166256138073598,9507456803001734658737641235710642159379435011566715643921196640676158132603,17204767985326745166438450937743889339302038750836189001173941240117259581627,11493735704785585407432943012768068237407868899310349385901453142043105992145,20264601365705944529765978188292560353562052194559042151183990689436087045415,6396166643103201291451232462310280514789516631380296812005611744416636341945,6058445133237719937803819124490281802427048168421128127070586670707895911082,17832742609350217271111001369998668554917153176201832135065834598001176606174,8301910681660121964370976371283430908357731729231997961142961954342095329645,21200700180783276860226125147359033530111487784446376587831447494082008760372,1364486141742658225769231963526281625713690163326935801558529383187840699159,20160669267302086336804098028492246933121636960809421351182280337233197662342,3635162620064198915033858334726014494627531534027138539712906873727339940152,20185829971410353373403938384712968683319708682735072330111840928607967762630,201523690073703194002962504757428126542763652704293724447838128821998746350,9709386469732131146744455888595822333747765095732359649526137736669486544832,6214797208590500165345122859363723824928963832472111818012074756679462353515,9545179136572857559578932159310632305901168870225039498707457861463081350889,7958214991370581593237224161079745627463630298171564909746677637838740804837,10143975143960280812282386246733660505472918014880729933237691446362785576312,19887571710409013601609612720342170573208042935750400481652798519320490462147,4385901431531790517574018221866017216283585679251714390188554453215701245125,1664624586830909279573419685895566313699996183243836877427547144869129575305,15793134038802395204513915871355486670799044444942914383804421551073411566881,20470704207635104884647349860077097804311221255557839038451274311052027499926,6142526726838860239230170135812194898945683787933736938595250804972260353985,13855192186192101570267811921410903075943095341965742420598451678343592386178,21061758735696246985536203700046768078820850320825204373370639318620908053680,5662817483820503797666808429029051672943117302178352551614788456216271483237,10333519634297417737172450445440333857302089078097476871967805971949123871529,8218569982501149814702324407474792474686368395700170296571212557818282461359,20233400137285640555195780437569385053497789288081872387339896466294226099158,10072372834150094335098617649200237176564672558260325152023334458902878530776,9266800412877476308026297272156162694485705323044163059710847355278349659379,5276337117659173276438760052296857124207008171563166875174912047683077401125,2006436301001583347899849869571017812498189722949517889639315185888688453745,21001242218121797019239763758294108685115914209711313091446808028690842184156,15200074016374430224281445993551091543367930754541238817021042732526880610544,19710826528876999823124699885521051879572010811534557471867248186884736123929,21404362987802009741223312847298906544768900296657310719715972255986007016585,7600530036229891939971232581797836974827849142680304648314541550980439417795,21632454463616985503979878539576013805183337895553881618120668190150301665261,6334758595723856085036854188165101506598081801208405745986881361560891199193,8057222251861033664666134852961391247267479839150238989503146436301385103200,3219721852432286392418844864881031568045047266727931843416507933961433025545,15429997317679838542619650717630685653076454689042566593207301547187192181410,329174031237742757022307048272693803097641581155976690924186132266202912753,21732746139483704151357074738923965870601454140619898689390165872304758524581,12807082000874685484816248695921308340943213652025179667821051958845707861874,16064026146032729000070008033632737632876654216683451632905581465015365908257,4212217153278443796283906098959531995688364954974810176542537190766858609818,21143229289970553639173591837823586981543332391397328546878889800049585920625,16608191574158019592113901126750079565651977188938492362618874182536574927398,3624421885419003645925287958934125046517213705659854889615838255824651468218,19316501828231774431815118527212477451661840620435061360743197812130426231605,7662891999266634580053960517366506438335835205004858023405036760628949585740,16083409929948531376998108923041427957606534473459279085237388567102877584234,13084239861882397209044914415955882241492175271640738785828432132564815850793,18210156525345343590423422394059177051429214768712959878778772626339164549874,12315464041324428320313158873511378501430493994363943547122434404767709664853,8954605304811330146055184939317681861245665333018873540562258152334326318605,17293224339343743174562117843833611404589728024045173960633854068798646969854,12077428955835955218060944701333382577662880272982277398053344529073555194830,7126046228531607392073289758329125358329379287853920330519927955077178144953,18588044234272060286987286081803360761513524944191766041826466047510554640918,20890448514466943340126201065304171306189507157689256667534257974304306634091,6801003349507087476371788107799511762780253146305342273491215439215969413940,3780619510354109448305575837112860323918556596060836509041441555683227828678,8767334354313558924867811651574408725653000725545478833889044301516199439630,21066572358677074507410523123848261256731407535120503516033231013762098795269,18362039042064137510549303809539961459419339855353944845069477034687076489851,8913523920256755688178316396983509800293437764919338700779034854771483564854,11723401432613346160205532396432709544892024270048469362382924649893252868073,13215697753311268652932970590975269015978051881025604765698398517094385751294,10096875802507022627888049762027565166660383010058121573194339315127497644823,20585340774134656767573027722172296226739825364200221949739798500696627689159,10445154974790139558211972190334915738383718443406895551366524953208899973439,21673116720904254079937605482525822519756033862602805679958950491098633276310,8625969092860470813380520419082444422545844964279894335272441710185243798934,4025288875907887520103326512414690750293134922246866469493778161136380894049,14323499257030290650454481578106573336673758956871892054979745929234879010775,4477626471847050821212591107628903165841822822191648560679737237549532746098,6035678895480961290473069135353807694173152744259585744720200702817852056059,13087537929005319145430419950489154179166101298384003566794942619862071759110,15034538492744821867836124336381708186593112293438604485661643830336837149153,8805139564894882006885168301537536158944953788019925854273090624783308357258,19958581387726270611337524069699729934757503443234146496516617463929755531372,18594586877352581063978277344172832910008313781358399221576815775414535759101,20126420557250610569978010728469817957691099256920991551072367148797364737827,12608220343122929299383466116607513455913710378844501818574872277345002049133,7472029840435729707246144983643315764441672074448478483499047549570431985698,9145534859649655987690711448922451001707059796425112511085875363972462746054,14833791973699407961392823324214593517418186311389016446279089810253909982772,5890565022258491346280610728283677536409667465411457717498759331136098626193,6036941096143250281821883413338948223454138251490770618188682101941802166158,21282043678033183106352077009071810571452663281954166213888935238324321673748,20333804372144772829649652869275200527604963503726633269029046116798625871599,588131164750999180590569033490334261814498911261696634224331209454245047082,6825251444721740074952317618082720927334521807162055931163012547596328197449,917697824543986394290655655205290161739195186499427989467675782006019774097,15041830455925245428849291972925354368991606611607025955853683450026323915411,18474239974098280549955893651580150846097530768719853315252027744284466692200,3611784158748153035104121136455977264222066374809674800505557964617331443457,20604659450393945231663570065906647078596881678092078709858521111095167311757,12029452301550033145724326108003255082656089254479215038003174967331098163936,15356676148621236051968257733981998213914051180019702757440018429006515803587,9423362269266211501814985604120446961293044110825100766698681717935266136618,15899728330782424719479421593102373102438201721567285551304437858855478298992,19106020154064303782722594063821106692950347246115176981502414167189733529368,18908465093637028691441981127932774442154173676388632144231302290143899401470,14007866203893293106212925571168282959988090650409909185874688109550330526342,5342742216767912627176491444663860490435717482395442556665323768598286007506,3597106827456013501397704575480537495681742041904755766922490829038770978602,19345954862705630389044258042054882168728404897041130532396992253851595567599,13651761202893618441816264801125692678934609890284167560926428043317180108703,16448172308101926626190311626973854215995348130429072972101942893358814042334,13856649049195496934480457183055513754814884703875171340785294070612325977764,2593658379576055879381789234288074898757591156526450196693707683508079496462,12697568363447920404231218962893478531573733618972364303216707079428387821529,10578645587798138343532931014102095372709438567484299904261443385326645475306,9492492460728662705158180596118275120458955222134204696298182307017420905508,18064023256112871749609279367679203109309609541901431681842430343172099602354,1989944422169611668560419735240024090899518972063746001231995750158992709746,19903230879435744155012664241474498197586597172440005182506995303093565641777,1728511243862152479724441453437511013527085523030423049007411340644871969509,1750200860549110325737825369011951368084185262869489413254703181129282667828,8859957468047988361338455823958226995655820770262073750796277641227321341998,19127783638542055071733839851815229696558338746338070032734486927449049698521,7078877955496438548183194474726026189811269821062629263278508622456589680639,3091324818623570240229136118759236075549426086908228304466341498471627762399,14195346783292343393569267444162421134560117165562018311694222203790784872224,7366930408724527902650425878366319531313526362168392830194685421619273052822,2217598702761121052299380093973147900304006951260118283287015270774119856107,16027808241528674736324615318588531063352235936452195394658431080548186455840,9737799828204615060867766665537725835381601825573025977613959705161843611093,8064501393540602388259218046920616332801811052858376733153856073004571475196,16842422805430821078995618361206787780503480464556310995070028960079907202166,11112062472802799468234830097050518793604563281810316763737206541428998286081,3996143098194824093843968965659132847407504849137530967999278126450907191255,6307499143062236655628471047117923013144505466650278288900215043429516667827,13925586587992763438435497293527949989397459231522640308463502932206077961500,13087452945182453051277972085750711303320428980713041081211383304385877763691,18093207370226721487749634577199906992299418255969574006908138736154443387826,14272048411789712231464337625432600879032064592923947963806042930999866142049,5112973508688401012277318169584325529641020499005098236869086381676918059371,15127813438826152618698293752642344087924814601034550461410899877754994198299,6969695649962440087033894050377257471647257275605050327543911409064993144574,6755033946723836072389613036793975461823169166252828563832361834388266522342,6630309846049050707531890910192358661458908514573775713066783149977348075866,19770918646745678079472470109308561511682083548143260940369403377403283034557,21433670531093667302664653834628387344084043216006808509497422477800438816334,20400712430451351419962326556923150417233487338363092310732550512855900177990,9914702749825526925254257687000920413318621895298404563035360292451257098124,18640006733688503648022700222053193091432820833842731658823766601630552120045,15001143407594668782401370718438100322710708950874705625981291998887962398836,6239670443845313966789296359213657096108058977356600364820415786936148776478,6433425223024186602967246363501689243341949458306873394092764835636608100956,4675918067976678709774913862522295500806856576135412363070396552169178386308,1601751749870408670839362316137379218159388455643443723425257645986433854434,13458041123361531838745263080315252882353509187267791623642428828275334206638,14471699013899259577738777309533960354293333303365529990782321200494073324178,20280430398960027135010448240285550337237252858424335652593355698129656795752,15301671314764260006262782923235826735016067425075232061024349010859210176138,8527420415370243636986575303113397012724035052720519440118106033441076019119,3475125085974928986675306749785419160190213748540322213576708845513558192234,9006980194944928107206620529900294492273459999862240882500316250867368209534,18341113199274904243447557429147408702772610985345439625451614852727142466679,641303854841744162878167226844505402377828908784963225549380412498130669293,12717068536550964634894133707393353175533641253913906785707227145457684209533,4743152264042462778433711542894756531279965736412696362852105777475691147133,12538011691198347241319721961633309700824171196141123297965193643240835576405,20609816220088637782952524444771775704801169004700347625707989982325840582078,5706720205331708334089980420369782946367580993809969730038974418250776704373,13670952207260779576827977242585356546757059123105172869720468020067882252702,14767430839071230390516499921530329576551075490453331584132978354378461913602,13855121278897572089789093806573448194721330823581341784260637700156610112500,9029464346382645337824607466955710618425900404147532427117006888589723750841,1522014999882036268928376276435422913665212355063956230967744832498304066925,8291362624704304963260873050727236420693946064959013721544766852407674345583,13589063181500587026605394799486087482543530017803239994475549538732438667645,13329949252386676079710645426263377053183751810973538969788279784055444085091,12386680681590613307772862225908657100001403625719832791304530216719729923003,7313059443635334631417408104276385788845981785748211548782869561833456731323,20041885136971069417608157269779303040508951822068411540615824115716811017904,6497376869042504752008054895287149835408180730990917088183191265348284326357,11125724561218240201117500197186012921479012541837342663628667709300377769139,19153359808996709649541642396803885814514927865816858283729145733607372609049,20152572433538554395328147373104228881714506304708579989936661727209606561409,20016439558639474267285355593250644884337484988031314831332037478976434317958,7527238505813249238885718653381005755459117986453125478349742303052560976989,18157976047185465548629298047288220777638494790360987385974875362640599836871,12215475598068312355286440209098941716275384959997573662132780937926913300161,19661498481048830903134453807971238540013636804700867840177613880955309016673,16552339415724980921932277403793066165528259484794112971750640492538556458696,18694143444126088750994041983752049518157493949000498621268553485531912882317,3713967579039675465490867111467075244841382142654006118952820645091137343179,18003791572957152311824638498878311682370695010264579557670846595111585019742,12786965212577099174577804313633357821910340940882518052929431837084369088642,19196303109560878004701565248872597636081713248916827960361832879728708100252,13503920737086542355495290621258674491187655992864087131383678759555676293479,11236070378728091455898747203990505205014449224981497050563648348504784872625,9626632821060958086537183012642203130268418644318548991569123722985663518084,13034637881184844942276438495251249937482750510182566475651230823087848537016,1332579251268852603948763724532278782861309157968811258504214239247723497919,4440487054089857105584789445239911365602192945489433191329897791642671641022,6061652828396333618822938589797622370923339089332057787863230635686741988906,20443625886285957158375952392918402164453450517610142032850159380049279019890,4971727988681610479349722318571442785499756930724120997617079739694258077982,18834174333023112536455562602096071615163100988222060601738058925300216483554,1418358707619290124642186511810240322979679442148132663647788839527968980321,9146563693745266063334532013679253366507504975079644933043489415067653903203,10198203189192787713857436708411760529883983417357336104059303759507359385362,13457105298809247477659188594503481428440666731107167805254859937557834208828,17541364687047908905500996158296679129819772711555398152345796866338919060112,20692063470613585148684100931411467587781915529223705941251811918651910411051,255059205539662129885859108675295842232143503986252525395037544865412535350,12717171726844166947240066436059787676718930218202178144871226850052045252628,11844159733516000729567466032644347431569093736490287481873540624836993897027,11002794037358979127166193862990494036532493412598623614028528989937231393875,74143635505641635571137692594773070124419429312664778822553090280375104361,7056329304173643667817989532223449288690091032171349984912618184745639839146,18641921263165235968711057500989010664480104039807002554029677125998810936539,19559632820551845243777081617723524038257569278710484296878486836843940297771,20335178684657665532201643783226288715290471620876336715869115375508863124376,1400810679146237783184309652518065868576549410755675655514372408922313217181,4901107318137271229016627403293875571324832946427895930672961592355892796524,5432919409806696890084817096600220639163358481346859637851564223110298016918,7553857716186244958951458648858814979749280269320630962042771757992327513590,10889701053782808013047326782283414392744894366555627960860238324337962809504,10225055313049541990073049693496605844127702734102449597528239569584063842673,3178201789995579607967020188792297279206559603024986232709441132816492873170,6847656471793158091195364320441056206778429470543211654532315995128613054310,12528583474708786099486823217911492959125739967840882229222854187982855300696,18467266119817551899238434875437425808022051394845724810256998883759435014686,17038264911128891077018547486438046001433165723713308233430847345626729200927,17955218916742955831569749120296633004126823963586826720707041154002710061824,7211241300282304354221867200910811631523632613327223837945134059614958044309,3903314564827641199204912578257298318982395101598969445634590319788688787892,5807166989004370646148664081075213577472290526426314941919217927313093625705,7286215868775919967580841436085988310805057373157718787975640918960675793864,1250176112708058341117534856693109443612022505613546634776485361294747168622,16240306074762036443870399577875028338427695244117010393369806321281281115890,15136410716022250493730454911117704953380153308032786787731835907574927894490,12835091061815802274496704101037812141879397401714459083078081237987781157602,9740091907879287748866588073726349058132835900960520906530105112062664428632,15914692134543071914048151066306389736053927516189539093172532429297748396169,981367411385768085119476192577825808403597700860420619441932576179905250934,8146729957224132449602418119478334118295844780357577983658167000941734233326,590349410629703152398401018217258970865749864711821880028353966569788201764,1825395473256187220041087977011184605194426952605089376835233620262931194993,7123515738169356759148725471278134181610254795201025187792320024480691382570,17726785796913877143757425784904469412799726913909454284181133920507167220504,11651205611193223879329620496932918885123654427491270580240367578782038527170,7363492115511936228845261039013774575631247230570693094937015313770023603570,12933273009260754826631125313953911983930122727552157672205237418903525642215,4587914992471995247205971137457571771256946895956563575187244174461900917940,10792746122808647351065474080470836119851772052088452562229191086431179404978,20854485826587742461285159604615271614646978291370447131740817759213177014870,7837325030066353684135714390699866228186086140255598480265046489057880448954,6126605304840233971990826423459339578353618021565536707601222973624714560789,9552503931384803960142614388346661043921110897228435044165354206374121160883,21548322368276531554717543098918449676251611754505041151177909568762524391378,18180071753020516412865055548290459200005267908156340472690024449103604081545,19794881883035632088168728687250887611858393833912902865301935760311201163703,12697056234954492550471667283339416001528754790033934829512770385731960713685,18997188462081688420104936253788181208943789361069483606382840563484861418437,13583525090048988441168973253797491422796978202781056749054729098883924623495,19314654753949754551488116156913608959581776089474885903850748881648064831000,15181859580303507964634708303997342165949140724201743603210372837522352052588,1716462370658876925282526879979978257325560447381441363811430134855582914078,8712634103130722740728459133380535370865755065924597276965974996780521350960,9765286726648838325814219419835139491993130621932376855733750920135287306908,19656947946994771960907781244127562602401277628142459052853670194718812445557,19486837510931007596539998551154014974137134735704825357816939421451262185625,21628438018144169767837932394788626973405404712219671990762156320628259145217,3756950750264795710121609861402232041406397600142239597456522141772347776528,17539873562638205978340064500452614593864489286304276949397837992418594034919,31501567535731664761828271772320938243617735864979347171792246363428922702,20352331732176385362929127748957145775981304217223745596870640808444167485233,11226695452056490225554147366326688917799653401898260586559601210633144658136,11279669284613566548129429232553360604072423151872075897074160621145515173607,18292000567925132069216498991188575797602397842406377969706321176845302551280,17394537715319668724138949078062966852069669620345676386188677668125466782838,1758531732991926253426465239898570102024009352558916489602014827893071642025,10665213752467842898072683993424618781459586563812993734884914172018996230127,8324794334508227576619756931916312729743681044831168054976090310260143855664,6775442988166121274859488523805155937302608291295720635827623408019663108145,18295585939863028658565671525942083548149809167848494003118620027469243247255,12098041580596728911973293152187391806099106269046962124832995425376587592750,4179756701368801644640767039230959196272720402682759516084041748778250510583,16793512481702225401381949294778305375341554886405623120613660547710034551886,4048682207452656355407948755890074205160404299490847582459375283758637453365,1909268909139397440485048370655601811806256012192941212480683118923705439669,3957160465110711873678443805553768764193925226448354732024034759529771356073,19248605214573594176390251265821595013690814611654024253657271349217548577373,13868854211319335141393401333112190211632180475309484073606978199113030773403,18603198177495186944736198329095228547417364118472010561530819889899131849965,14961608796326843943228062129500114917120869339277918579779470648489101516583,1868951368661473960034964936590962790214375788389753455318330338723533775732,10905586386180037341368454391941851073795645267274288454955833628477189437397,14954127679800529819463733123869358237687206843820983026443645382142721727317,100097327222806530673180018653982439008319453432490738486899052539918122124,12805546034879808469495394895280673159114129337420886322224562831326122327785,14806980879080756440413940765209361196073245400503251970584575890653655885707,11244087337738788153622356037614703414595488262581651455100475566242231927775,18570222240753995928776550172488765352849447095675359684346868515783858763055,8341186767195379582987673341587963265518616797937499770780867790468554256976,16417432689254526830515766295056137071443518160358174458760640472715479776587,16841713253514960386433216886097940412703740575768017997853214356595383383598,14194887769957144867963380965988802472719946120213216012427494993012946567028,11529543378722012166333054004374317420377342192547947476057235546295927556027,6228288822288755015903485852969606389475962987032899088796179982251184963398,7936701363023944576389877378554772776727492414245244625252565794409904100031,15001498940712434912521276724772034272928752268882108797824422534795904619598,8473716056033059546731002019964120133827043541589774095605930332153697155158,13622250811616358253729853546023741257702106070523773564774458974873057917325,365025468139420802765331768400644334625920629446545823780682161731304140845,15188301566744221387195339021364877229016833910188161414607699674936046087814,15485783106434451702559510093123052549288846753530302451778527951586674987922,16738591797575541545215307991580378005049794467812864864257667302719418546088,20925739023580534811148616300343740428924012857265956692833219002712597286911,14889383841375932440118953385212403650477118619024418302909728838111026909639,16907126208352189929083708812165010150781216847422378013750129578871272492354,14806337329187045580963626107721698864963698880842972656340333617747451702084,18421538430347165869364634373319132341572867349320823968976066555816366184444,2434665826886017086044423893890240566257398976888986717506547657107156268130,4107084864210868857776853415457685723648054900688044144581857773829680966286,9975696437638488842544898875508262421180359453753428380941136617917797565651,4271657746853939228219168189957401961257189278944783942462379137544482211389,6197095881644784733476508213210037292053663537272178396466755799876037787454,17213367299854554180584426411972899951945067477706586927352113350447914118348,459213126097844409580498104618008133837044548373643874721876534610892189686,11543212578280368772068695265607222577889093375221336525779600349460584250291,6403298899310300874478654413460079479003477532791552465502800475489780616607,9679879153779101961935393514698788441597495345714510688032433497970373876200,13406313792037016685976311954559553063553089970578743589839464948184425020319,18447061183141116334003130470774130153225311547501637266696790170481921881877,8380490825353548292894683756629385493171585978110314915970595197861650821468,17748778220767931278266669246252235981422317813726374848817938354712043425250,6989443852838917282085440504075239616539844445576232297589557657622451430824,7831657729066776489302369169030303662771324770284845700052063314128105065459,3925294941359174220766529276974428294409483857727579665373968233976340302182,11937917292063962829330707841648838486196775641195800632090436249316243167473,5653419633240940595644007985875227652581749358539968324306529520430709397246,4710671638294627998538116427765044043262338916893456876128991289569569324348,71394869385825610742630406624465024289788832054180269745498390791493509963,14738615985593994376179875742690333041302941042023229128451420345640432224466,19352351801479363044593690690009745314348194116715421753626607893015433391861,7828134540699329284695760683671979636145431779072416908240193138816504514982,21767328407325385326066972839469738803639297445302836419167176746643393964398,4363185783182535592354777041764733165968243966270266866378133278599205816107,12861900092547198665663242905083918119082751367916515401033164113207531942792,26199715195773805806030726371679979491296157888969354080702618784507347327,11422842882875515086151723214834881230789142279246505109137919711737652087050,19051762302341786952522177542948673906514656868374502102797859778503069987555,15304419135175746829806105353267450572438302765436283477928256874309497427510,15459263896362250252603436487314027681146892842462223021544635764438917687246,8022722450368098005612162808615173120915189731064159685566153653273958491689,9933514811147109956084664025371824141534792260321581906034445537159964992688,13658822996647839872436185744737341749492205026854185105317636224609004876375,14379624233209822191260559290771588358188218543089774948098229868966603288924,14958992313261503520770373701642009455846990471215730792533739030356906680013,3008264124109355458910031641850139041159853342729069847393839537381972950880,19920038730043462715603813734444323019432755215636179923851277692610637123174,17230906594400326225968287949357928337332875589057677202822764136401667097576,3295851897757873055813703602696670024935942454512523388333117755329662151138,18768678356443319065659286382395610390856779982946155969362775884999359596659,12460586127165955570640740026112067337902936125125513451212701690418329829958,11058259665604247832957658651506896706861484197660414347806317812760432481190,4480738127714472007170345890289828985073762836671874831610164101698497828459,20356672216023774813369271811683185179666462848912908217024611254147608738543,14909200607508800723484308159953932832836734953149954532962622450689109093081,9061041843468229886389838095513813426084716371809563990186852970500432288083,13877210447577198749973239837374936528445414390167357430100753821987322195433,2839635391670662085450211408709683689698694308308101424896263880864913513894,446790459594546823193048947973948688374393610819268956164912891701746906791,15513394297485200475424313247005293190116598898090270540649465364671255026149,6430544300458423909335482367339522552006494240640365398487065900428380674587,167620735842959596421416387102879695919480795342009064535989276983300514975,7851629689216713462310956055612887013872895546158054432042649792702892211944,6972603886636382162328373670318167574093559853635999968924151410796861460213,19413944499150555955013296242054320685906330193520693124525832782341915610104,12263527706889748735493918123122221596983902069097405802497958581677957096038,12724987466750360537318099905062339029588038359925927031456282032606443592484,9708897601683631082524518294366690107466919479336384437075715215088985624241,5574496517333770677326807465934080003942242224011251056548046091202080747952,4426233947499799157064891373345188337862104712594055992042177154581455374210,3323616387049914826284182817146044206680302487334156840960948301224727078983,13004254604656434940963009501076991894817629784556574456240824509876544606284,7301157702835275823143922645275544869236677259284614641634323459896004519527,18085948818621221598774302236513376768745135801526414290158313790799455691975,15187850571325688566534378765892972581891242830408971491252049503437712864152,1246313402425855943486273052355580345666640430821848725745627960892819218740,8647394846748193532697036206738902082890058434940110730560542269988727795912,10064655809228901737773717896104022245084200167358447082271876992404069509689,11849936299337845059630533008021049942767799074160683892846518986534992566533,17222503330227123082665055850287821041983218187459530901865330120583332963245,13182290359799776528759669559625168410983932493170206108456280901111876076502,16922308846046171347608544335458702314243928203269931669473214292617484140503,7558805163644194610710740916145749972491144028571940176012011742150030513578,19569775351485108268007779638227959360722563519500120339858146797114197471682,11059423706111256170971735544260170713544645580527143674901672982061741530101,14932750633257527497920398771292456029356930315768552640257901217840963910603,3437896142924792262479946438539259423504563537021031548773393821349707014872,14782805101152549038431586973278748014002447400847124060642259960939628565044,19682001999640336579725059393603666122104885151774112167088565361216155864092,4233558995266469322360257198354042357488781625226686110373130567271844168385,4047511689246902987779521780711143086427724115291088073014684434358317932158,13856430748589477860039479213633534029749590309123560510004500567115861827367,5679747763871928801801426015291106236767446876847749477902392536633742028903,2480123750122829773963967496725275864472046134363280592972001159541781284867,3193376214066985989527250356837102042223952356102254301113166141443841024511,8062756153672663466999843325461563174537500405375937887043564985230465866772,20934273497132536703003386629581299436206618333301538059074736379428757199398,3964142000339408965627671968349646710437601305543271274636785761452376263382,17659047756049778260030257809618419752271933594271518827815853540916989127582,3930343349615664221386794926953117177573248229077177174315534154624751347076,2895341264817391965072938270159088942930942041694844772295944189135688863196,20818043348799096204572140288297522915577162783223193328931006646915252532953,2323581855503968054101786162741712103392782241966098143187644164748998373979,21506950445835751487883729097676565482258136522526260378635240810473639421131,15652663761688777314836638604018575636259220826467294056546736904699739444415,7055942973426557227578535789272026034619140718369524980726263182702440802766,4949575918974841751734514119081067078445927926837555007268000255590820633720,1398399621038450203083960309132739969264364773648996881599178794373813964423,15732506799197618296258053128654220838812930643001991164136863850944185860296,7794835596508268056707656540537636605902268233816181487738953353424162592877,19334780957038992630028385332334147629399375592719839985802296503565556738324,21635034093671076768880953665214862813027411650977124864184274112296716574632,10688534301651495143056852052149424865722511689194196231759927113549978532269,976280778878149721615236526300424224199708100054560296745736876703945737879,1661236337347680899528966953581439111854379099437324147973193626090712244045,376684649999303144466214973033408609742031466036082108742020038605665915381,4455377013377822379614998251281676782235647079572422444530523356359416320717,19050227778954804843017265242388770579299436899390433258601701002663268793950,20176738847900667540339144241305449384029623393968373234965844794399275414945,6563336600400724498009526486444642892816244088883489205001024055715188696046,1774742053125969896553337470644410955775448576794083561882186570750312466523,4720344938456070076793371724100707050168913253766155392188169516296487837219,12386484928350266729292976320659720907387619673269670145583838638028478942370,16511156064543308562970376025636430728255148453048880933972883964686852788569,20161060548546289109867983393573712303980348945862267966490524939511877278515,15745678416495620522776570951840736496696200297848371457414809276602866061937,4371269787269411959190919691547618186773560770535442840395153562222650962400,9183286542027774648383851710226269089477011745654659545146528858483988667073,6831030131135399650979313302695351819580359371445002328037898607795789751628,13808316624446561665670975675845412570522644424965154154503596711464812129094,16573850887526809906244420164574513771138034770054149931125695105829690192839,6536774143914522904090235450413350153861560318210355846585220439397199352760,7433401028165144185448409996814186253264882020047922839648723974949988749262,12023679188187515805015064799648457297092902074185758947196154639017034370941,11526239531876823273618354625960431640864995247037473959040869772406787371745,9965606134640358953439667616539308986324141554480312185321082780157059913160,3745993460581557715489390110730324720335274000085036229679909083358071037494,9383224303353982312273937680493563948228572509816601479265308820357851069284,1487827268845002359294235769079867448539095616058866371843794273898817464325,12752425410737476015270360130920506733622111261208379938979967899453342006543,8485480321269023262044616550897625372838041041299338618725089063696829309383,12576415359894007789769349543504370901641305511107563487651205088993508989632,21051289172896982928450490300579871201387152257916628019163266526462496896736,15867382033370376377605746630898769390447074387330276410404020451043720395429,19175636645506837972748760370147539503389959528500852183571848133179892449157,18562815464677471696203191443459870050160752363485379734113024945295929018010,10670914301723557472895334516073215554660627986142935452136687134270343499283,15711527071984806338686904487656233279759984782956970430068615997429454331060,8708497335606838864375996732302168404094513852034309829472484268061328157580,4188819471869628756655847772489988754984005896205326092058226221066145721122,6512127543122355053584585699891817324589817660150620823656474181624359941201,485283184789889690494624068272585257719678055879291431306025716514618916201,12469998319178098719636931437231251055837496888416524814745527432538031712785,1296020106178851400649855820617531046666668928599018437234450345456859444266,10011446468770184926016968173857732818096269728811257796162165899021103326404,21669153150071610384945525175896288044525929994331131233225247540220566590451,20224127309865911841696813826362911446819981503618978937382553360215894705096,11995994988481623386912855165099904216709109375061333173068533008232786187218,9410915142880940758336239494539529470909530692135279575732428340046078892946,540343796196110456420764600417592095932817965626261174892651237721778500283,13684306082150121243464309606855998092353075421168995445316517423697818489078,20162825761581699251737493230139692067729837621407892263730870777826880180708,5352686262532923758786328475456237662420216644156835779261605606151509572690,14736042040902670309572407869335525984156459843045648740121852458089457172710,15139196852186360494919007897486360521240977399849539996614669434222882428974,15545525411887550591483485994597179301368938856348279539852576272926020931130,11742635236612776978185392287408975566560283293946133146948657681925156152641,15933911044011218543142885674144914931062698638612248403425430247045038884929,11224528638969252327238392070525091272297579382723799722332333037066879094771,10619901685741876140226157641208788563882472537632692937793306998778377039845,735284898318336599638540292516453331642892791568249331436388578312138627149,12167882615164420400306427908818494367178873976878804005748498778042330871045,963476496798286039732969224933550470500612316061831761002103352026702296408,10589214229258115348033093903975219788029199245856576715398082842145004049938,21557152519616203688970824263287584036198859167308821872261472006356046725775,573869759526051245236872936984426432239686428333700586079723439581218874054,9487380087795664760223154980070289042545005448274508346993861027000032902237,15336219129184315874932697305233742095099896250996970622669888209373427981768,18404646237880969912286263998117686518695361809473583072241508209656556652987,11799938531163685220849832019747758716514224719376128562353011229084757783628,16344281677414470708413218213072185241641469290932113189992078158350700334823,13411067297619308137174262243170594092291209705703155674514006442224279302094,347096376483719141995221552155578565668868956459941108952060114777596679497,21711034316629345478518202673372708169627878437940325626238942704003376069559,18882050099612599842940192045274010067786778900079004241849918566254608017530,5764257238170917062706360501552002326820365975520365982521494644422134554879,15701229555594307124251301047127236083745198814231032790649389796695363681317,19380342180431843316217793484208165905833096992510614135124089140124740832734,5309407894979098314097225178362235237148427064335413702368413584568729847810,19819307748431076945425543888401840319829139172119377623119035071741874422686,20514761050842041997240240118048816505140382250318444479066954659053422537618,1344402086478653057873064952452423683387555289301580402150577440089615404706,16697255135945674012509919105064086681485448643989533271078867487484115301326,4621832835239804428359762201398927678345509964776233571546153039277467113103,3806403786653298341904285490244574263470519864399252904304315511448068846106,19829858960657679259830225387994355131769725454664502533894857362311545270016,14331370957097049770140547885384829422939088321033246508644491038102571773100,17602213870111183187455849162801944225604239824059691632957781727843794239813,13431951289066965496411295925849182623784324208488725900281691974104907065599,16717461480909222952301202387848079129664321734166452456973177865963036285419,5335304795187086185403562863303763030150108130150704291401586263249269328606,12084224077193103457678419187386990486069302392148214780322095375978824542075,16562074867094659170642419054272949287052074902139533680078784684856883275478,5593185214695460463728593774938986800789091570195563391333689785627694694435,20794081973744988874029976307272029218401016626938878812907621515041534590160,15290613354786940528909115982493729676786892068577902693057827852601851859953,12549551509495378488198674258192692896591847320322918116198744545244343099813,16172760618549958023639071988927160267123900859890153325976796899698706870529,21355970775695686114097146789571025790146162225961276367865670606869296144640,6758388446832091660422761046124378827605916325205674642673860154638138778023,14106404069959859167123546389809591376301394503370836987998148793984105405167,9246221316655556670219438263600949328330249756179668376432941216174575243170,17439153852461693097676073072037755599321185173017314957734642307684740219597,8081777382362242695298005068719699951526876053236775057946263871745968444089,5955062815471620144467538738332476050500085920379711183343040972831100802372,7135549743533376618652729621156592228493633259664287822661943632128030927327,6448789306286809743113676641229641365524354356867853498363388856986312333060,3836133206442752775823759632522089911744536837043185745585363415112795166600,8306967267195429229901513132397768469414281874455321140328179401973148164445,14279081291461540920232629360665447603436685365844514491245275283801357455033,18801535274021869273717064373621101183756544015062966551566128881569524508060,1290309525505162730469471418279301124342110934722264762505649909318202025429,3684482296351796270499952631629720483486993312250657634474107248508746062899,13174517099719760880623841117042663715711430443825712743356469456554740491052,12367323038661460523248093127080567074978912019587769246568174104058982359108,5328098381011440170293483375144450438184897394389341853376147620924621832373,12027556664769952184858265393953265399418219730267455116938121684665358512140,5729732888348277625941886883620484887709258694699060380279441089816970092500,4021085134780294168590418396176917282024838594185209785357282466818023080991,17212964584402772629081731052343755101208077509065176631705574779383125014657,20917432005010641713392920477403385909781374146458276502002720501978360592707,15295563898035514774486916635776497660635050791955975586488426545424778559212,1359821178683766445655942489230783986383452848368510940932965034076334706033,8110406013405532283463947127567634123149268608919736912581466809002624991926,827196241038734359771319428856617658913932049877272548875698342240161957065,3791462512735380195191512407306530846222290938359064542531485381855595890578,11406017533405938491480863229977030648871769070115386849200353035840595881771,520670302347263967262738466276891414776779776742458165836379179429124641366,2448606803226047006259184225386977543879941109635656602752172963011710994490,7191227529515483786577983572625758056228282372415415309332838080598142611412,3307446417204024568218448979093609311776086880103323372856728466529459088211,3813554883592508538818724202670630447381185344079357801330890767369937578758,5250709431012867357277423372041580897716232143432581463056922412233378167706,1091692079685509315891403580607856616782786079784896146193867325719999481531,4469622327160639333299363654867070539113198566013450831894562184457403911597,17323310137022557438196735285237348172608407585356043526322906169573029382454,16687301461250715912904355201855034952586622338354151885963080312175524252322,4918535113766539148632870060160447192025270821762409737556656897638575667317,11072593994523457387389747805751581908149754361901108358077132406445033545004,3195233728052289389067022539306995714028010328554486938319749354377057516714,20817686894891259203267112342163112292566908705837357461445233267117792429649,17690940439879640319699865226478735545090209049084370958835445823603146902951,21690628807014351230241926358993998569388931315165663025074689739408667261702,20459556268654252373755265495950372631044421643418312123931432417755203158692,2615012003869030558909061586486157199297754407476408867239954327608829725401,10416424720480840919038397124331362407722217483977166150169359209212504823727,21194909967788113390574471899389319930586662664636393856442773352403088570772,21522774899908415003330605964114671001565200771087582504208866633533540017562,5506611081865651016465481008237511873335242056816344474949867549242155650988,9546865422597752417260521115459137295056544614907437375816616393702205361356,21830596616035544007289279751950703469521180388685936491933709578982542912017,749611610802485176586202226352686769865522163389912514564999424571463284657,6755555316754154503813947597597343604907450943684878399336695170747270471709,12170672505455181293754012516713072944675179516356563083524964881029055628483,6707337549725648754250613641063009246814657413626673293152655855698987287596,10796498904992920132771232449170737749742455370471689413932089087977711623836,8377594495858973573128154823903039902710916666748285670520960751078778241055,3984683583649079079845275538974168947709880082512288559917193166572776389589,3342097912826432514400613460588054784328673911636756618761620185294261653370,16454683529696451672086473280821594992928717172228276559555553609303793416523,18807899744562842658522302889072060930222870278511178161869216361165074271071,15733467702619867688911165419464811721151813607792971238595067966297846247623,18142314765654743253383559257284245535624730148238939832089390410939642651454,11195224772751371350570884976842181779831961285896963666553011681145523971069,439244367736881667144534860370666344402105076566699968755250684892603338082,10704735720989025726743300184412677969903347430627186939154207946469729017738,18578876165452990292495920166540986834727225658030437088905164910953626259691,8557967377050572410782106944750290348752651270453684627569664713996263383548,8761045577121588487744533431678957572685193486431511842082771483510204390408,21449005117895748002614414579158497856671036353929407470614229969798846654314,8742763699897193075490808534988551410985191733407596422193467672281063172120,21640560187468057824325948244870722744182743184907610616373323268039154063822,20504827051323136179653341596769205909304116951166709098994304340550034816775,16172525553351370894318080522373536864524825253487998830365706514360525527841,3591685457927038924948528662301423116917211093679974227116322357454330018554,6023337410706762262272160833625601604408129024083079173527188974815598816732,18314718271070348604361238020618683829686900661152269809595508349472847942062,7836153641990744469550400020392942083885339413553995305082889896550143678297,17661458352757891434962464787581216134089171454741034624471153568868635718017,4122036760441574620764812242429576792598439550172741100479310420694208068906,20862235339890611718235387895311549206105487705288574136561783190763219344570,2850551701806552645458448511649317843914427882049290827414738885733429831896,11247005361958789340696615426808536553465247486357927152826112838641725799209,595377141566787974548956333113514797724094819448399289547808025689225222483,11650535249856393960142913145219442364845834591244773725262296147168383099202,20317269079309969728497469029861008772266846936951222269809633626856816105008,18373353028723033673212698815557995243796350917201491012576826029280066160567,7414281571887634589036890397094381209738607746338326059409587963803891852201,18038763738650749116346354096722212724532913209902202281075842225944189538168,1770786615956839194004148114013826935077292967352199469327501774219607260953,7488031997643483244135856650059587771856081877857609929648968340004445042854,8828420155416920637244885570572746512651260806059857940333819295380848667606,10713758486859145329962611447140189455100648474003892294431344231535672892839,19425964738010714594065721309197326935753724219070408633462182732050226443166,2074939531697630696938698501714595125993887544292881866150005180791766942998,12047170609336587447894029543834769407220306562179617939497216596360229783300,1264730939976742978058162525644425945405879597356760675420608373469615068174,16770820387947475117163540876143499701759349964098540413422664664028819497801,16280068293625117002805552395286584356701604835446863786447466051605766622630,5829399622833188992426267462479081456743106260845929463922917463933701539334,10637584899633814574790036401685386209425675304700886428980902763634911791837,9291782595793252587833322197337655894886134207930378095811922971339860144588,5951026341599354622946777675133435736866407426534732764305509667517377130324,4403580174404926097288523091529640188805282235669930524399146786861723458014,5003639966922553172252470768563093188889050306376650665702227782913343083764,6558197410800499965347594156873334155413890035105551024236266846011615264982,2475377503098365612622742300317283313185534384082772531168342518799898155594,13480086440294256226712366993542304396509909765502683907895525126405850150623,6847184584651376043889746562956674365958636593745423518578010394007380039425,834503921046130599339994952233856873876410737494970024102211605603428829597,3623466614124962325494185109684730979089103423795285554788413052641061197022], - [6418344278839121997761558068555633277874924383297235060428040203550148460392,8184778893153361724502825398680471446632259194563037088246379746010351701224,16103007220917684483813510789286348056519805127857943417823167430289370248882,1664056765289606259902279533842090994664529145577166075019619213360544081038,8189267971733078428327714274800548471520787418839983750528172780925243373109,20200362011107872066803394413626937903139046091127740529060907959370256880701,20173744990845412211550008592188171997284132875646553363208340317991304601908,6100976759548353184263451545777211359935324012594548692714862113681123862281,18589557631793259794347972680714314322014920073994928130094285735070065431315,774191617468212021433032703138192471679212014828288788368078839883023639562,20846157077077136618808870082870348881758556999252332666235423866411633465885,179369838162302125553370844232732082673907343764950159722856079645852949296,11918621764929568738238867861947162353407822663185301208219638335882724852664,11892816132266551039449220442540498829071526084314780371963132054098089857199,8372083054789567618141127024727893763407629214826505908070525202510871464376,16053969929668995455194287538126250235271805322133461918670713060143921845064,2376335354846722834191665301267088635977856417140218787958824096999457654386,8473768787638105406889032631028566536048259675966039382891971280359035809717,21341339254986951084972542739281440827262568377712659704364142966685544694259,17589661461505870684154172724042456165609752814624225501433267429299923279866,15569410058783548405562051853887675489795673100717406458705097884992918832740,17136771849960699223133648686528512780844440317239376836819594891344485260741,6846911134505306255484642794298233221271816466086606204236441947984501580805,6155197242495613968880604860842601809115711093712877692064968695514089066009,19128637117872288039529749360298403408432890998345732113683578733270478526860,13897081066927368111242039741190751095002227555149381235627883407347099966197,15568696369607733677931070776042128239961624292553408918258251667007167792827,4872469898347155985390501972210222637651779849978701189099596399070936407527,15828528305683107589096901962734302130704783164486093165237194118210566499447,10871050448146531061933214597828428556087596885695624079458134367495768692641,12715634392841723603484337993449575047813504874083783048519693646075495401499,12461797447292058643518857326956961860724022201671935652194772338021756072767,7893478478385050482361413970069327892342442172936930424757486435631374257835,13837601157198138379089270567935062044589875195895421018230835162664685103799,2902437942374588332095798046833013227638771976745087670719351344275677524328,15243444720000907684100993103252257759861356192301299607302082943722781818072,13807772002950549127635782715429970069282430778664455286304012934232212216437,3330690659470353458591000516836956263198779643900957759109026769401030561064,9121369550752168091283493588432030055987339875340008013960004670271046125246,6735940425069065421825600687003545396352913420833444906054707032006918504438,10202597085447755780667010145999569476263425973948073114389503196598866401333,5502428069812047253902185475715178213199056100606031376530298129227524479345,16644412428296109976288812904703533310452124314681543539244699753829624611041,1464363769917768267070780357984170193149530071521363359029977430003041058712,6585015011013232733155666746473112211355795487658434466373981554623709413097,4801399347914387190330170488585953929447785020623558112311440395749307391856,4112082032915966312546686950757741516554419896344654985273514512341960565972,21751105223203500709422523072334627517145925318798961657655356624798705469220,5444707496026644829581718915396971639630623832272466243662913303978147462160,5176202236175268355216491019205403607765794084697970681965844070084688885903,9306814982626014542830328909308268815941037317672165275254890008767120833129,18534005003473959617581160840952814838772020918476059581821124675494141739706,6315286473605163880327953940950267064586093973100720152185112301408202766527,1300066066523772310953083996541204931152213396378337235691979863222476540925,5067928636570884230858740896001720688497565237268231912398775294420405805509,2247332707031505717534336329466562637772796336116582429349574314234357562544,20247738241445291688801934041857783193064556313940428743035963593744371184825,18242310613256758222060583109097399506427347785291803988073944852458874238653,5027570650503078047623512055050961603632044524914664539379503584245086748701,5171024028215683374631525538977404535998938725569475537905229563957776539718,14944506678316768982115249709678873125670683211913646815567280613875065136559,12712774808537003317921729077604843728755135888798177519726799585299850232729,9704917525949617705578174784620125192847872142914494686332094535178307346294,17607293541936391773356775760016259535976314844718033784671775110177131099056,2540563558441922228123722363766317044293335648393481767268774186670778379682,675334497725789143197575210295522345522852999942555409554666160997486976627,19406946394055111935833464724872576724279555593094398662505995447037826031689,8556081865419484437161415079267380957278647215963771014478927152338629734722,10894080579102201350420363592007910695129177124810422954037601558695648517625,11291505870061211613677608925985023369330908318817731122393740145823745286941,8111345701049008354923033690718534410144029586027127161268652239467844080405,274549942856353845785392053622966579448945647367587770109876363273061435394,4517253471300397604524436610993375842851058850598308811197142784491633632173,752091920065645178354359484693693144698238715470242001046768604290011335506,11638201273705718037686872429810169270152128290712392950719778292205581621583,347106139963113855692776969661437659762102942024424980057845079543094637582,1650860247124995235720423411540903470864782697117302631679816892337391491913,8807792864573824348524944774842835780541376663413796103538010142332713129239,10125706840777901469452374931444076850109537279493387272544675392762656076263,5796395502360267028606772833560634747652475684290748049574810918512176530377,14560087906294745333868694378307270211143393355422503000240374502300675908843,5122547319055760404581514483238475236540700695938727023605315976547513018758,18167310745991466802649320845690518166441060923615799361858509593334862918793,10537655786889979411145772153623144374332103428122704649668615330715372491734,11129217221221505592409814225825346415830118409870141057639470413354985898470,18539905463366886572265160849053355497514707079972544561033138019460289616722,2634262960559341073751666364573144239402802922297326052528609874036724778513,1017221748705774701515487698826243372900579204850532621904642815268966836932,17514607882958712820434977243901228312981191640605665595923587928949930664369,11518730158165740016295488007249832672982237183652963149460237152135828893220,5440554707898671641433725775650782970626686693839748603607869391440450924607,9147974268228093219515993293158817299424235911620662153289209094112083583914,2705991777416683673465834362340927783587369064825521543877658261521166181909,17763220243034576321349123132976335282008457858814906290437636386824597776861,8436811158855395670172615633911662578819734431001698203244903207934616540973,4138616319619099661442960332848564292509386403496259477312793995345740346110,9291305887217504987438822522544685995385674372729325355668719643387679293273,14247130176192495492949419984506575479387281081069847984799112525576996955413,12065917784915207956255864287163607339403293417584561373088222422519855200010,19602746430676351974790620090862300757670420200072717172839368523905726952498,5634613092261261536249683912838127927279222476821160426063089671641025921660,5043354945289735676261322233679902891599697472766188245131942353534121350357,10504830582720502950783794220870443419986496189960249704278002268186024527222,14773755085011014730752864609252484899166588993023999143755304644745097411069,15143011250372146369484566133567610168314155803929775363148643430052742055690,9296771043817098875687880718048618354875037373605143322099708291917193542563,6699308928121904151061270394393246387724926649022798867634982215175491150673,8773562200655600334022608356584787571874596251190350038742467377669146368640,14351113364159322541281738731216101468935785403577478179790191188832046493458,4850132968055386067280912095292570467587181719320385350609813213372507065742,4016458733475657342057293585429845015911706822034026494547861057484844319736,894041043510502707790816962794342134661931379046385946357294445947889380857,6102901509904208647404960172211548023168535043766794923435155807898706549347,10993930772305308408754972248679389846078570700140268311987303413959565163567,11304109937008720250639855591630423562437629896442798574433639679310105935745,2101572929952921976477335632619843501489349436900225186251308254022656908969,13379549674365217138865497711163371499213584223441782700932894243483907931587,14594340674649653462364863346385318403203482098904810919462071947226757935441,10647634642733631076053157841634424396589261258510712678605967658799137793311,16930068860033006574251855928288208559689461032565007963103701897524112820278,17170753006961827437085793102001841977757115057767702296590976802337127094191,1342928489123424058754093123906133488378103161461686346784407392402405815911,355084123756415397117817901422581736826549282147584490336790542339114994995,1823092998982212793902589678970070284970565355035702454684653415443223765731,8048898551230697881244098474076915607341905762324328681953519068200924158237,20856146965109368880184165603695312280799455722407374791306423939515039038196,3432336669019104452964292940253917813738689308738628946720655243686051453920,7245438991832359030357502486353272155562833935372540938834365796871211337300,3373527222057951116939099747150655397463396105930227294848620975346900604136,12572707687046208161448564696692430877391470466184921096766838283998472321208,12384937031493229201662431219560608524659573369707802134091983819133706078063,20462122407152292556380602425948480298757076111535435284512383591498863731385,6622785585380387259638611864923325325049433660844748518649420260935388464763,15605049021670133989806310757216368923392900885847286376362426319164543334301,14810486805240500676478878806350063220126440203863567013665308737654824897393,15365995118119349988306703047684161019037838200991362610041019844939301169864,6214064907470154787016516294417895267553707205697453843662274325114029144555,21692877109550228305351038417910800050989918141485758185602644390604582268196,7958034635501608074408556743462969750498597833797740641656952760348926890967,3158783210920420629823137370399691077131051120551658723733852791768119909942,18819671751132769006885776104610704012597692175792895108910904654781356258396,4790325452934584098003515312147561388538271922609950099121379835100064976005,20767398895337785696143628393192433940154143348446221959395714109953426025406,21100955173515864394919601160078443835098475047602620649008862351655083694950,8821416529246363042674973639302381036248538012124317741611227124444469290957,11914021995756592924439683950035443074155751236836696847913625157420325157778,12885168008148287764892654933214399102034605991806678959486007885552095995306,4425275709248360981167156075250953689813562430283330510520431316578062369047,18741351324856319300007832572892392651059227679283122747711533395263296376480,684786537545646459534722549414114801405982388707719975074226812265976115381,13474309605538568830758681457803561340228343878559353019653388997246494295147,3099805728977762711509412402176547022850118685798164610570416531465753528610,5600770441217208920894248156825173605916487562076226390167638135518086562704,20319458329312269677818220957673767032133429098791178878849925747919552800984,14900034607445803864669093098274289660238359682591825230729114910199159461945,8290880045417869099036293157381173265982569186829040493570954991061128070937,8462436298566072387124764625279911648753174589013128335782578822029407672023,21859976115370951722195695482147975930683297060804395404861331672395447064815,14955925753372802734448760267566451635799685206346879293698701403481312089613,4065981601972608953318716423564125873552717375448854762316325928896715511302,16523330234791629267329601436136683980570251446067965291433875700044665982992,4829516041540259457263557932051130738530942234255982016822863700315113125159,2798840870433591285859944008589519120500790120158397573735407833376475300691,13606709616318037902590277227595176470474803011913892797662975188860939656033,18594031070203820621139505381680984797252179318940256457018473319622484612714,301595919185954926511829797241004376609778538475902874115890821742528188064,13821866899865257052128875138353714301663063129600329885914206051645789155403,17834817495579398016717972195069792832976969906967797534885124084571666971093,4636638693344568063056245513561087534038777759740617868439601311740450428791,19461094558355290408553329139619939302588770167904059927666632659470708174566,21540578068459849172758651661944081878533817564350404794583097681041474789761,14656354515483866868842463518575118611017107704362419507056354562832024225447,343560765432454876700403976911389497782754407830340801930660700142029455668,11849359483183996767521484728570765305101196328390648813094255236259946055317,19924264286421201319107239943837407504286665549555105416180422159851955997381,17166797941774367858319514708612731492719223682833034509589752159955652705269,214236542688014950402766598120744795751883810511956979430464011049570919618,19396313302865541199110558245182888004201133198902041449761385765703954241755,12933296125492490585010683271492258153065303286717891025958189212827073719981,17844270568289843619005627429285364222068221173113885235581641198349558307966,10272636157097124940050637562161546985351212351240072791897429490752295849402,5635761628763643716582314870927054669889487541831762994265390120663404976213,1986614715532243876888195532508093896345436225715262830320266933005235142097,1081989267417492031457620947123272024310181199896785177670601875483149154563,4271010751492446271792663900865386872716262596127435260947966701647960153580,9432817034096362918055925335622289410018247097406473925807967486887418646785,8420506466048434939907866067225441403679080978454172178355845135440301602325,7476612931957868870953074766426582066042735713430654491467754928300129405389,7004218213610744415525118134908394594325377744218316765510260162880307132371,7571768879245095309014348656876595924444469219593531275918644914891061799835,4094897072683886403820666572344492999293005026807228977160362626188210714131,16648450944544843693538650431603587114533063135176857105384828552675810607958,12887042974366913908128212909540148628955501312789089034196573637089727885967,7707639242815954375609957852547086529799646052590213478924819089112009057667,8823950326593148986044014943552213420762296615584865468926316064433145020153,3784973153813546220636380916429273484146041804997715013288159720673291711004] + [ + 0x304c29aeb6f1873847879576d30f1f6e8a3ce41082c15c7632df920d6db5164d, + 0x2b7380d8b25bca649b3f8bbd0a86ae417109069be27066f46fdd1c7c87d4c40c, + 0x4c77200e5494b1cb8a3d334f69ae5bafa7e8775ba1924e563efe591eff302f7, + 0x6c0b8966df93080c3ac1576486e61ab0d027637aac41bb35e482bfa10e34fc5, + 0x24c73f425903904f40dbff590225f251ce1980a5a5ce2d07ae436e1d090778d7, + 0x23df6f6f4448273c745ce53d5d7abb5d26c46724a58d68844d3c3ee45e9b924b, + 0x1dc1b1ac389280188e937566071b84bf8189b955d0579b6de5ea8a5136bc2ee9, + 0x27f71c5ca774ce20028b8140f144472043917cd4919cff64d848a745bd569180, + 0x22b2ee53b302ba2e836b98783e15eb6de9d15a72cc7caa374e61b51dd0d2e2c7, + 0x254d85065f87271e86d7b411d6acc280f9ed257c098c9fdb04a2ca4df7c7d766, + 0x28620793f378bfe881e098bd2ec62beb46899f37a54abd053cfb0b3bb8d5e754, + 0x2c19f26d0836635b04f38fa30ee5c648fa0ea1b202eb0846821acd3c699cf061, + 0xf9ed87e9a1ba7ee7c28bfd7ac38ff3ba10849fb04d3322898ba9fe0104fb445, + 0xd1deff42263b7cae8a123a1641b7258015476161ab881e1dc20e165b3f04579, + 0x1ad882b228b5f22b9f6a02e10ba09049c9281b32ad71818502b66ac77ee3ac6, + 0x1822ba8c558e0e6bd0efd1ab4b45129879e43b7a6acf07579b1e6343c531a248, + 0x192c005d746c0d045f5530f10f38a29b50cb6c86039410e634d25a809203f492, + 0x2e9e6de4e745193d2eb8b89b5b573eddf8a6506746afb98a2db858134acd808d, + 0x13373a062c71d0754ee8b1872dd2861bd4c2545e807dddc654d68af43ae87f0, + 0x130c94f39a9a07d71dac7df61fb56cb975c9092ac2ab73b113b341e8198eab08, + 0x1934eeb7210877c3c2e07d9ace7b72ab4d659bb1431f8e8ae79a1a5e8daff5ee, + 0x22547365b9069f419ae8b9370816f030a387cf0ce6b88fdc54fce91c485dcdf1, + 0x108b2099b7264eec50ebab5ccd3558a359e34fca1cfb69df4e3f8c9da9faaa73, + 0x22b946f1886cee07fb01b7f8e3bc585ea8f9a7fcdb2aaec5faa878f378eb200e, + 0x229337b2b316c279097644d8fa861e5e5c07377cbe3ba168b55613542874681, + 0xe9283cb85fa800120344cab9a7f792e975f5c25d64f5cb6a521b62665af7451, + 0x112956bf9c763ec101af9a335159df07d1b0bd90bc84be291aff9a85f30f5163, + 0x26f27df4fdaf33f3d12d5948690653ad1ee625cb00aef92b73527d37365c4726, + 0x2ed4c4b73e2547622bb78403cd983c6f1d33b25534127e98a7472897a84e4b3a, + 0x9f0108ead7dd31504de2b846076a8019827086a0c4dd6570c1b7423ca05b0cd, + 0x1172c6ec16cc502fbc633f8a4c308b14551d2c4822b5918179946e6545e9de5f, + 0x26488ee5f0d4f8b5766c5b8cbf414970b750e7488aa316976dff5ab72f349f1a, + 0x392aecd00da38bf4e39fb198ef96e70bb8774b8152970dd2e1629b51ff10ae5, + 0x2f6d971cd5f9931144acd9b9e98bad6e1e78d60cbd966fb18e6f630a76dfa6b6, + 0x5a795d1230d3c781b9717735bf45464f36c41df07376364986d0fd12c8317cc, + 0x1e238a362ffe560b31e3b050539e6c8fe0da221fba18b12ad661945e22e5f5b9, + 0x35fbe3e0d9d9276c990a3b1719e27550545a077f6215eacb2479af1b3686364, + 0x7ed14110e9abeb3520e14682efad791ad5c2feb51d558ed013675289b1c6bdc, + 0x11dad822671724ee6a786e210e9536e0ada0796d4aa0fced69c1d411e11e0c06, + 0x110b32907aac869005443ad66a33ce28508c925f505e44a34b53f70a3aa45385, + 0x55a8f4be4acd26e362a4dbadf39c198b43ea025ec429df6b2011177dd8e6cfa, + 0x1bce99ccd0f37478be3ecc5b67ec7c0a84b03f7231630dffa5e16ce6f90d6bae, + 0x1d61595a714a5f1b32a5255dd5522d633a0ebf7fdf82a9cfb22271cc962c801f, + 0xde4fba8ef10768324aa1e91e606f2a3c3f3f6a29dc8d31bf7a670d31695bf02, + 0xeeaf11740f270654239779cb83a05182d0c98f3d4bb8a7a118ce4c0de477e3d, + 0x25c397489e65820a955d6284c002427a1784233faa7089c6677f103d2fafdb7c, + 0xeb3a160356c8929495bd9f58d3a8657f69f3eecab1517123e724a946dc50c4, + 0x19122ffd9b6430a6f6c81cac0bfc8b488e1a28758e9407fdef8f77aa1fe4c0ee, + 0x770ca4c67aa40a1659365097ddb70eeed6d6230739265f76786cbea0899e823, + 0x20cf3df7dbbf47bb220ccaf0ecd8f3d54e0575628a7291a72cf8db5e42e1498b, + 0x21fe2c9c9625d66a931fa931bf7fbea6c2808ffd7d07fd3bde15775957c62768, + 0x2ad158bb675ff14b1dcddc993d9d60a5b4e9f3648afbdb5bebb2cd9a98ccb881, + 0xf89c7c34499d981c6cc376c6fbeafc88b7ddf87515dfec65da9bbcdcd68eaef, + 0xd6f33ac650e35d3d642aa3fd35912fdfe5014b86cd11e8a8321794b9a9c2992, + 0x9cdcd7858f273636fc033c778e5f588b9fe6315476254f17aa602c20065caac, + 0x2bc68e029d800355300648a36fd8a24157750a0d6fb2f2303906451f3b3d9820, + 0x163f8a2427805d02620c54bc1d32186ee3d07dac41d9289e9aa3dd2cad337601, + 0x2b72cb042e079dee8d56b1762d0052790105395fa0299e79cc72f4c27bfa20f4, + 0x1aa578a5ee2c66ab8299fe99133089e90676c4a2e6d56cb9da0679fff6cbdcfd, + 0x262d1529ab1e7f58925030e6caf0e79a14c436e5926e33cd79d321388b966dfa, + 0x1aa6b71c17be336b1b1cf2384d6d3ee0a7ece1ad2003ca727f636bd4b70617a5, + 0x286a8a2c71f53994524a189eb5bf41eed57904d91f44eee40976778362547af3, + 0x37ade52ed2960d80bc2d92b815a5315883cd42d26709ae64a822ff92ff373e4, + 0xd641f097ab6260b2dc240a85b7799541f6e73a3a25649ce98b4b64a6c499dcd, + 0x1176510cc674b0f0caab00f4e9be1f8c6efbac7b7315ff6d4169184b8ef009bb, + 0x29b6783918f37a8015d122ab39713848ca84008abaa716882b0492c6ccd15642, + 0x28a8be58f110dd8c2b90428fb4feb59b67eff815e928fb7d75747d35cbc40ebd, + 0x183f2632e3ca6ec2377e8358c3205d23f9211b759f62fcabc5fb2314d0728a9a, + 0x6aeb9e100b47eacc2dacdeca2ea990f7066a79e2c7c83f2490bdab3eb43620a, + 0x212949467cdd807e8f3576d403fef09e9bb63ca3754897541c6cd77de4ceedae, + 0x1858f747bddf594d663ca49fd2aab93402ff9d186cb230a025d53b8d4c626e70, + 0x19a293adeb09485ccc03800b821707060dc27e8663e355e908e368e2e8bc0150, + 0x1d4241ed038279263a184eb3aab7f2e14326b7faf040a48628ce8a38c7b0abf8, + 0x1692838188071f73ff82734223e5999c726b055dd19bb5a68e513d57055d8bbf, + 0x81d819dda57265e88fb9eb5f7454ae7dcde39a14b00f45cdb19406e8bf24efb, + 0x1fa7ad5a2bc799dfa38a9c581b0d17990d1f53a145e26e7b10a0901a9dfbe8aa, + 0x140107d97554b55ec285011aa53f372689e16d68abd763cdffabf8718bcc77d7, + 0x1aa6e52c05aa7d40dce61bc38b038a69bb36490d2014dacf4fa46e71be012ad6, + 0x233c7ba71f9e0ca09ec20277fe09a96399a1474e4dca5158e97536892de72b56, + 0x223709deb8827076f29c20778d24a2006fab590092c7bb34f212c331b4b1b932, + 0x14187c4e94d059b6565591e16dfe2cea40731d582c1487e3efbe1cf305a9b459, + 0x12d57f9c3775b0509f5c95f1cc2e17f1264a5121afa6355611de2a71ee23d803, + 0x23ba06ba8305823e5e62cac1ed25888b6234f13294c93e1d36d5f2f73c8b613e, + 0x9018322b8f274623a4ef0562223a166c0fca597d4527ae8fbcdf297c8f6d1c7, + 0x1a8d0fc5616edc0238e5287d9fb6869468a83ac168452c5cf3f9a4063452f22, + 0x2b1a8db9aa3b060be428900b352808a1821e9c9f34f8c8e75b172def7f0b3d07, + 0x14e78cb6524a7125d7718d49dd76525f58cf2739ab9cbb0d408dcf2e12f604d0, + 0x1208b734f978bdae45714bfb76d3fa83c558d0976e9c9a1fa93a1fa69f7bead, + 0x26cb6b7c1d65f9e5b5235c3f31f9d7ff1d817e4b5b945fac94a99b3cffac3d5a, + 0x11344656431a0d87de96e6806fc0abb9e1514cdf175d617b70008b1cdfa7fb17, + 0x28180778e94d900df231aa7e551f6d7207f3344f5b4164d19ad4627e53aade25, + 0x1497cc0587aa9a662cb2e9bb2ae6bf3e75a0716db37ff072d6c5cce6ffa65277, + 0x1155b889f1798c1b597cdf4ea98b7a22e2291aa2f49d4628179115ad19817a1f, + 0x136bcfc49ef4ecf9c613bfeface129644a00a283c8e9567c0b0149ed7d7e0268, + 0x2c94ea318df6e3131d85a4681682551ce652db2f76ff670212c5375994d2da9b, + 0x11a008577edb87e5285159e1655d70b5f6ad4abbf3f8f19d66ee1a7172623cce, + 0x14262b879f58b553126cc175743b09b5deacf5aed297fe3e4124417ed2016a99, + 0x338d86b8e84fe8bd613d57a3a713ac1e971d52a586e94106b49d7d390c92658, + 0x1ad169875101e162c49ec27ec32be37ae3d379f347930fbb656d718b87c14c36, + 0x1e33654824c915e16fad4a166ee216d1b3a36428d90443dc9131f818df850f6e, + 0x23d15701d8f5da053866a07f4788c49476c5518c8a812295dee3aa1074db6d9d, + 0x2d2fba372de705aa005c21db4d71bba12c9d47dd0161bcd45409c883423948ec, + 0x168371dfb98b380fa2d2630c612f8613042e6df90658c2350b270eece90d67d, + 0x412112ecd0cac61c445ce46a8518b56e0f2baf839488591ead4aaced85fa01f, + 0x23ad0edb1f4fe974eef543fc17fcd7dc1a0f05e2ce5ac18e374c87bc09f75c78, + 0xed6be3eeb0b9147d7c509a9dab4ba2d57c7b9d4b2780fb0515525fea4278eb8, + 0x690d08198823c10f51a7ea3cb473a6d98ed0cff6a17069b50971a68567a7b11, + 0xbf5caee488cee887f67db3206cd5da24ecd1baa6badb44bc761757e2137ce3a, + 0x3dc319068295544dd33221944b9e285f7219f85e8855975c48f69f77edf0a17, + 0x164c0f9fd358e2a011e55931b51e5654352bb6fdc6cb2dfa4d8a75722f2621cc, + 0x7e8978e88b1c0789e9397e09c9eb10e368fce8724ca948f6f2ac92cf230e6ea, + 0x22c5462508c480867b3cd96e18dc3c42ffd90e1586ca41fa67158838cdf1593, + 0x922b97a92d6a11fb18178d05f054345b43db4f5c6b91c73e28f6ce3a22dec5, + 0x17626303d1bda8e47dd6d0da342e4327eae6c4200525217a20f6226cb54bd44e, + 0x16ed2d702c6f848039b31ff87fb1daaf88b23f6b00acd7f6409a7cdef83b5ae3, + 0x1d9552a42def1750b55d27edb09ce26409f8f89050fb74cc53072f788feca6c9, + 0x93f2eac6c08b0a43d4df37c1b20d1965c77103de2e6dd88862f77b322a32dd3, + 0x63648259abf1b9feb8c0b03db31f559e47f0e11de2b371b299043914d0ebda0, + 0xa8db8ae7570818bd9ce7c02dce89712cfc04f800d55f1562eb1ed27da9deaef, + 0x2addd8a7fa94a011e12910a98b2b8ae5387701242ee2281df132f9e9dd3fc7c6, + 0x82532cbc9a72e056668946fab08eac4817547cf26ef3eb8f159e76f9023dea7, + 0x2abcba0aaec141d7742c0f0785daa2726200b6ae69d464e849afd70465c9b557, + 0x113ac02d59778ac96902e3fdd0562c504b418cf8a8e349da7d61450a2fc6d685, + 0x193a7f639d4ce4d62dc7567ee718853f5c5284ba09de428fdf02846ee22331aa, + 0x76d49b5c0dc78dd9c8e7ccc9b5a35df69dce86805aa47fe3f8cf062e47e95cf, + 0x23051faea37aac8e12ae94b87a02411747b14de73751aa1a3f6a07fee98695e4, + 0x2c3a84859c46bedc24120441bb6dfb113c09dc8070b2e0cd139ed49c9647b737, + 0x165df45e8460cb7b423a9468d2935c14c93c33c700c654e32c2e6743de59deb, + 0x243c1dcf2e801df1b53ab72ad31fc24cccb07b2518594c4e5f3024da67121454, + 0x2d4f07748851869bc581212b431c20cb3e268cb7f6aef272deaef66e929bd859, + 0x1445dd9248e8bfa4e6698e7f51553ef1a152d37d88949e15b9c50c3e8074aca7, + 0x3f3128f5fceea223432d31ceae2f8b11b38a15ca9c3fce21cb8756e8e09642, + 0xe574b6201e927e5f369a966151ddfc5c06fad66e64d5e09702ef172b5ade467, + 0x784b51a7ae1076c1737eae2fc4c3bdbc2187b28f714e56cdde0cd322292aa4c, + 0x289012d3d1fb3419e3fa81294f3a64c15685ffaa658927c09c1833ce59ce5ff7, + 0x2bcf3e35ab8919e05d55166908beca23a711c712284c45695c6558e0e3da22f3, + 0x3df5cdc10feafd361d978330cb95515bc2e587e7dbb89da4ecac57461b75b6d, + 0x19dc65b4afbaa8127015b3f68d35b557c8fac9938dee95ae35ea12da61b7dcd0, + 0x1fa279d539fc9bf724da2e7622bc326f9535d00adc596916791d77d03bf016c8, + 0x237dd96ce03469858cabff18944f05521971d1ad373ed6e041987754dbfcec17, + 0x31261638cc3762eb025a716ad3bcf1d6447a080f3ccc60f8117315254f568d4, + 0x24fb403026e10160607af2e0a214aa725637f19af7ed44130a9400365bf61a7, + 0xa773f9bbec6c35b5d7a95005477796366c4f36ca634e94b283233afff57521a, + 0x2ff29b7dd04750f926b880f54acc39f2e828852f40698afac2661b3053278580, + 0x1555a820b4069893e6625d113049c46bc5b4394d627c2668adccd3ac0c6492e8, + 0x2a5d25cf71c81e5b129e7d37a5e2728dad5d99d3109d23a18c4627b4afcf8fd0, + 0xd749c5dedcefb1910ec9450ab388da7aeb25adc78cd029a75bcec29559e8d51, + 0x2134979a55dad645ef838322058e7bc8ede30969481ff2bbe496d8ccd6aa8ca5, + 0x1a5d28f1ec79a8a70d8cfb783cff4c2b96e4ce5beb97665a0f6a52e73a70bb6b, + 0x2248fef1cc977b18bf5051a571374c36cad0b338bae217bcd9cff038fcd7bc57, + 0x1a3105c3234d4afbc112d7a9f38d22206c0a1e77112d6ac26c6d6aa63ef50088, + 0x6ff45e6cf264bdcb9e8b3b4f13a44d1c197ad77ee53d02fabd0c0a78ddf6ae4, + 0x7ea34caf7f9c9734f489953d428cad95bf98cd32d5c18e5b51e01d1444b8f91, + 0xbb9bd4ea562fa887d4e6723a798e7641a08dbb42cd72852b8002a86c57f1f92, + 0xbe1e28fd888e42fad37e72eaf884f6c6c5d037afc0957bc9ebb4893e4ca121d, + 0x1de8955b5f752e29e7e7d92d6345da11bcf32937a8c2abc93c497d1affaed055, + 0x140faed032e51900fe203d8d32fa61d9842d6b7283864ceb9a4d1857d6a9cb5e, + 0x653a45ace7457b472ead1b3438668c57d36faf59e2a19134756356ce5cbe131, + 0x6d23369e024dfc31a1e36cd9114fb7892316dc57da6613ecc41ca0849a1a7e5, + 0x106a234f7e4c5d097cf00f256609b029de983d04044a66023d477897b91adb19, + 0xd5907c353b674540c20db872cd6e0de8bd66f9b3d691396aa06678b5a9b8bd4, + 0x1c8cc4858cdcd5f36aebcebb9cf185feba809a92308ff5f63b66c2b1f52dd14e, + 0x18709a5ed55ee4f8614ff04e503872021e88f83d488d8a0567597b60e8cdb3f7, + 0x20573eb7a426d39fdcd5f46fa19973e6be531160e75ae9401b99ddd7e2ac25c5, + 0x1b68b1cebbf59b96e23aec11f075769b54ac1e7de44ff13708fab5a9bfe17719, + 0x1e74628fd280b451eae0d00add965f95bf19fba43425c3c0589207782f702b7d, + 0x1adf6672bbada9f83494ca2bab97f2e90f630525f9c68338ba4b34ccc484b478, + 0x6ba3daddf68d283a85f65a0ac15913461a7ac09a320e394d09aa5ae97a50db4, + 0x23613483e811cacaf27820d0a9ca552ad22ab29d4f1d579f10bfebd39f14ee66, + 0x5ba1370283ba319cf17f631a9291fce5e0e682ec1d01bd6df2843528e363db7, + 0x130a1c1a83e91a21cb376e0df81b196d8c229ec60df85a30bce4ca8f466fc589, + 0x2ad745158e0bd5aed17084d5fe12d671b0829a83392e6dd0a90a1c0292eca0, + 0x1a4703eca8fec84cd8234d5fc467737761e6d2d6bb6d502a40e25f94044e0aef, + 0x17eeda53608b4be7d2c9b6664dd8fc672bd48641e29f6402bf55443c667bab4a, + 0x1af9e7886090fcbbe73d9b70b729ee9f8a384c4862626ea685673b4837ae2627, + 0x2c300d04412f79e15c95dfd44889ef4a7df828c6b32776db3797c674fccb5fda, + 0xf617c15c41c424a39aa8a1601c5ca44207b3c6e44b003bc13179fa7afb8232a, + 0x280e6721e233a91f7f26004f753a82aa3403fbd9ff420411c058ef275fb54295, + 0x391c3b4c6aad3203ef3e9d7d217d4b77ff1fdd8c63a9fecbe5e702d51c53f23, + 0x203f9c14aedd6319d3ec84ed7517d5fc4703aa085f45f590e86504213b17fb6b, + 0x10842bd57c470e718b75553ddf18278b60594ad3bd7fe120bc46cb0fb450d424, + 0x30250c77a64030f322e0fce46eb9783655a93645784b5219c09eb0ccf3fe88a8 + ], + [ + [ + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x12826e5b9be1c9b85f7c98aaca9ce28a870687d3628d60def0ab3072b57b09b8, + 0x22fea1297a4a5f08904d555c2e15d016102a4ed29c32b4bb10809ef14af42c77, + 0x24cc6751894087b831598b5bc7f9db3cbb48ce294d9208e1aa436cb5fa2e80e1, + 0x2cc3d0503a0e1da952b081ba5dc5b117e646bed572a645266c6ec3ce0a1474b9, + 0x11eedbe5a5969f33446503494b469a2b83f88d3aa477e5d6d7963a8333a61315, + 0x189ae9e9b162ab1a19d599cedcef428bd1325c78740aaad6715b710bfac4c1e6, + 0x1aad11449d6e2c6e1adcf9e89114c336c0145528f356ac049f52fd8cb084370a, + 0xd7e1eae2cfec406402d34c259e5966f6e2eb261d4f08e29088325a6bb669a63, + 0x796a23ad6ed2ac995104a0d3e6c75e977ce29aba1d25e62a9a8a20364ea1be0, + 0x299b8e8621d7d8c8d3d6286cb126b34ee53b2dc9a3697b8380c6e47f5711345c, + 0x20f11ee81d2ac9a9ed1cac61d9cfdf10bf1b49cdfbb6d232872a1df1427c1839, + 0xa403e979943b8d2f947f6eda6d41170881341bb5e4fbbb3b4fe3dd7dccdd777, + 0x4646253380f4bf642972ae81977779454aa0833fda36b1822cb9c09719e3dd1 + ], + [ + 0x12186bb22000ad84b6bf29179ade2d4e7e94ff07e51627e09580571061fa8ce8, + 0x237e39980f9007bbf8699dbece054fea1f19766be6101885d421fa3ea46b5348, + 0x1808cbe7ddf2a3684d8a164fe2d150df62206f6be33d577dc5798f193aeed7a1, + 0x33cccef05b0bcf7b77aa5560a0f949c90be5cc2c57122f9885d24a117c63f98, + 0x2854c82b4b5f5df6dd3872e3f371372de0d12e16e9108766920b5458105e76bd, + 0x9b63c75dfcab572d280b057fbc3640d35dd5f16244863ab8a31e0956da8802, + 0x28fd36f1c761ea7bce29e6f00067fa40b32e6b318f506b6c94bb847bf72b5b52, + 0x2b56c2e44f703a3b143da03c25749367f752b16817257e6d123b10bc85543432, + 0x184e5824689e4f81438567df435f39e1d35a819041d7eaf3af908429beb2bc2f, + 0x1004c5ecbab6b7d12f6bb4caeab33dd56c1f829ee28f47c29fbfbb147e884654, + 0xa973a665693ed09434edb2cb0a971ad277a82b3385788552349ae09e8bd0c85, + 0x125478c8973bc395b648c822091f8df469504a71ca4fdf1dab59a708d0fe4719, + 0x2b0696d45980020a2a421073440e3a4fd39edc5288e6900a5958e0cd81e0eee6, + 0x264625c74f2a3bbbdc19481b7866757e639c124b4eb560da531fcef99773903 + ], + [ + 0x2399faa648aedf9024c6ac3ceafea248216e24a9e56caf5acd29ce2546a9f6b2, + 0x540f5492497595e13080f02f6b1e653e2e51895160ffd5ca14d26aed93b8672, + 0x1c1ccb44ff8ab6da854e9271f4bef26d2ac26cd7441f1b69d16eee0d7a7b481b, + 0xe8efc85cfebde295ce589de60aec0db43c81f4be7da44eb26fa4b71f7cb7ee9, + 0xb1d810fcc721551e2a596e9009367fc6a924857ab29b703207b08c95ecd001d, + 0x9fcacc3998065124de01bf7c0c8ba26ac4241f1f7deca1eefe5ef3d5015e3ad, + 0x5d2f0a3c223122ac01214250320b52ff5a3d242118e19778b2c8cd1a976c611, + 0xc7513f762b64022a151d62302099dffd51791d9afd3dcf96cbfcf6035a2c27c, + 0x18fde6451062016edeaa32e40a8fc30751e17e9bac192f8ca891c11f39ebff81, + 0x77559473737549dfb2016dfa72558bb2c1c816d7318763a5e4fd516b04914e8, + 0x2de9ee6529e5abc7aee93b794c4eefdd517c4fe12fa56bce06a3708d86336bbe, + 0x12b591b7af35ffd997b3a613687e449225625dd5d101cef2d6f2af02d9dbd6d7, + 0x2f9f88fe9be36457e8a546455aa00a0f5100a7f32580b78f26a77bd0b7612181, + 0x9714e717daa3ceb3e9794d24abcd172831cba18066c4c048b0995e9e6df1dec + ], + [ + 0x3add29fe398ed2d44f233125ecd1509e3cede77e6be08b94af4fec87eb3e48e, + 0x12bbfbb110ec2971007ddac5f8e36f655465d05f2462996b2114efacac70afb5, + 0x1b8d209d66b2c1acbaba435e304ae20662d336d10330beb3355cf801f194733f, + 0xa9d7ee7ee91677affd3ca4fc674625be897df79f82ec438e80f1e000c8b1f70, + 0xb6eb2254edfae1d7503c3518e64cf19f3443d6cd03b71cfbf1be5936da4e046, + 0x1a9ab3fc2059b0cff7e3cc431f7db45f59d8f7f724cd10a03f31a36638f8b52, + 0x23fba23ab4bc24d4880ba5a6ffd6eb5050dfb8d0f56476d3a30290eda372ac4, + 0xb26700fd4e950c25ad78fedb63fcb0d9ba73ecab858c071664866a9096f14d5, + 0x4a572b86105dba5253d7ed1e76d35a126e6718551b976b208f593f08158dea9, + 0x1bcbe67ed5fb7522adeafd1d9a150f8d57ada218db346915c86e6c00c00e38b8, + 0x2ea6b7a7265c503fcb284c2bb19512dae71ef357125c3ac755c6bc6cc37bdb66, + 0x30544eda9c322c6c872671d667fc5fcf09cfb8d34e8e5812b6e738e7ab40d8ef, + 0x206733e327a64b78d3c48b6f7580d0887c1778343b67768859e2532d7d1c46a7, + 0x14dac9059c9e78d96c7ef807ba342b946870679782231d2af0f6e4ab76cbd101 + ], + [ + 0x121af61f4dc5bb24890abeb9251e5cea94770ab062dc0c28bb8995dd8f183635, + 0x2f2ec51c48f8b73c51b264a70d2ba0b46bdb43f933de0faea8a7da2a97cb41f3, + 0x11738ced3933c4b27de13911db71ccd58b7b31344ed9153dbddddb91fbdbceab, + 0x9175b1fafacdc0e62b5f95e6ca67c3ffc96a26e37cfc734795b92f1e46124d4, + 0x210a4a80e6eaa799f7ce05752bbda4d4ff0520742c943e1efeeb12a91229a5af, + 0x19bafd0d7942b839f36ad3d70d9c87b55674b9bdee02a7dc30e4f99ebcc1d94f, + 0x26b8eab0dd0d95b7a8439e0ff7d3438a73a27b5993d81fcece729a824a3521b1, + 0x173985fe17f3b0fb85de6104c02b46c3d79eee9dc28b567f02ab1a1c0ddec576, + 0x1d948e8774b180fa5e1a3932439dfe8c5f32a437657d21277e42614b4c9a3dc3, + 0x1b61a03e218362204fd20b67536e5e6ca7b96dbb53d53ed1602302988614876f, + 0x1380beac7b062c6b89914a976a8d0b9d3276a13c82c23fa21f4fa4403e3267cd, + 0x2110c105efb481b679ceb2f112d6ea704442763ae2ac65edf8f15cfd169c560d, + 0xc272d10af2ef78a98dff7486c49d7505edd88c922e5672a3abb15cc49f4134, + 0x129dd677c1f8aa2d36d2a7d5340645dfac34a64ae456f91b97de9f8e91313615 + ], + [ + 0x2ca8ffee2d58f2945297b00cd0b511da167080d53949b3f1fceaca9616b6143d, + 0x26e36544d0b5952dde4007d11818465bde91c4dce65abc015e7556ba58b95ffa, + 0x1e97ce013afaa6e9c993e9cfdc9aaec91b06787819830985a72e9f7c6e516ab7, + 0x3016b074c814225e2d5c1091a8303eee4be476b1458ad54c16b4e1691f6b4724, + 0x1c1b2cf11f0d3a3a121be7d0ddfb24dc71f54b9bef943aee32963966922a8399, + 0xc474824afd2a880c6a85a7b7a5a434ac422c7a63aaf8ddc7c4d9325edef40e, + 0x19775ec781fd4089859f6b7f127c91eb83eeb7ec9eade14677b0a6b10b9e6e24, + 0x20a9a6284cfc4381795e3b06837e9596815fd5b6f162bde02f97db687c8479fd, + 0x20441aa5f4d5638e64d7ad9982b1bfcfde158f6a3cd6af62941e05cc8e533151, + 0x2d3d269ee324e7c43c11aa84cd15bad65444ef8369df15749a8a6b2c8121e2b9, + 0x1a5718f4a92dd8d179b932b0820f65c7bb93eabce398f997324f98ac76323b92, + 0x8fd4397aa8b3a84dd1ba4e2d0eb7c6d1c5eda1f764814b5ffe204c8ec735606, + 0x1a327ff2c46f5969fcacb463506e102d682502381fc3f999b9ffbd4520ba4695, + 0x10879ceabc3ad045d76f6cd5b26b56dc47b512d6509458f9ffde8da79e6649cd + ], + [ + 0x2c99ef5e064147da9782b914a294b6c14d21ea7eec1f72e8761671069d82a134, + 0x226bf94b86b177cfe7f03103d59e3f9ce2393821954708e7c723f8104a68c664, + 0x66ab8beadae7bebd26a33adbd6bb392d6825da37a679e8af9ae8bc4813c3168, + 0xc099861545e013a687cdd49a3a296a8d2c2e99691c2535da712d351d5e63c10, + 0x1574c9e5caaa8a6a7fb4894d2c45d1901d1c42b3214fe9a72fd3cc668e399f76, + 0x3a65a91d35b6e877908d5c419e7850f645f62b1c913765a214bb0f7a2915b49, + 0xc073eaddb5d3f79e5bf83bac00f37700bd64502d8bf7d5a099fb3eff7d3b03f, + 0x217aa400b2b625bc36432a545e533124f99c1cb98eb85df747319e85d530470a, + 0x178a58ff122d168cd4ff11a47280a4b8e5cdb313411b6f6e9a947c7fb577a51f, + 0xea45d22479ef5773e58b0fe740868fc1e8b50bff76049d5b6ed5e723711867b, + 0x1c7cbf2448de7114eed701b041809034e07b946a0340b777268529d582c225aa, + 0x2487df9d5e066b76ffcb2f0ca190abf5fc1e5872c4b6a36a46870e9159201010, + 0x2c0cbbe46422917152ca1906462bcb5a13ef536322a8715237da09b8c594cac5, + 0xf7c3f3cc96ceda039e43c86c1b680c77d6f49f50e94de23e4db42f8e9caf7d3 + ], + [ + 0xd7d07cd3798f44d832a6571c21706758693e5e93684ce2d1a5e8a53e0cc6709, + 0x25e311b37cee693545e2c2efc2043bc073552115b3a065cef13d36547b6b9dc5, + 0x21b37be521835c32b673a31d71aed1bc7f3ea96fe1d4c23f14623a0a851a3cd8, + 0xb71a06bb75b0a10bfd28a3788bf54a8a144b3287df9c591a2643c4100fe388f, + 0x26ed5fff06ef9e1942bd3d0d3ba6848e47ec045cd26f93049d80cbfa6bcc73b0, + 0x137908baac2e35e13f86834abfe98d1b54b7c25d6c85fc6c05ec7cded9175517, + 0x143991e8386d62334ca0d87832a0845b48416ef5158c18e7b9db8cd6aee223aa, + 0x148dc9335f621fff9c8d2fa72a9cf5b6febabe1f5ce77689c1a29e393185fba3, + 0x256e145378d2604db8c509dda4552452b6c4a891fac5da199c7560768d948836, + 0x2280250e212be2a48d293796a88ac62b05411012f46a66f87a0220a3dff3f79d, + 0x9c89e06cad5430153dd52cc66ae4f521bf4145df048681beb2e06a385050117, + 0xaad68c20fade1e3e2bf70fcef4b550ba00d6399e20d83402fe09b52ddcdf527, + 0x25f4103521e36d55e418162ef8ebfec6d45695520ef47b8548ba38b52a27fbf5, + 0x10bd7824fc1b883b3da0072d2c6194c4a1e5957156594e908adbf6e6b1912b9b + ], + [ + 0x29195117106623ffffb0af525c838686d0d97259fc73a5194609ac7b7b171313, + 0xf2336e0eee4685741ca23828c34c24f073491f0e72c139610524a56f71aa405, + 0x1e86ec086805bc7712b7510def651249ba1d491076241d99d00c692880f39a75, + 0x14937879c4c7127644c765b6362f8b98cfd32f8572d7aad9cc329bed5b507a69, + 0x59de873c59806f55114bc3f8309f9b64cfcba7434aae220447ea0e9c4a66da2, + 0x1662f26cf04f5b969cdd6b93e890ef2b5b1124f51822888dc2167bbecf7c31e7, + 0x5fb897d71edd8d8eb1f3b5c823a5882a06d964056afd532e6c88893a25f2615, + 0xecfacaad0c147e0b3c7e049771e6d4072b02ee4d171c0e53224214d17ade351, + 0x25f64d42a750971afcb8023070f6ec97bb2362b196a5aae2af6a70f2e7b357af, + 0x20be703f86d7c0b9dad98ff8bb9fc92fe8ac0a84c6897a75d851146f74840b71, + 0x296f3a9c104222692a44ad24f0f6fd8190027e0755567e9a7009ec71ef440ea0, + 0x6301679b6cdb17aa6c212ce342ecf681ab7cd96bf0bfb93350368004d97c353, + 0x7940eb04b61ec5341c1702f03993faed167db6fa2cea92290cd821b15fe4c2, + 0x90da12e1595551d2500f90310b7701df97676404113c33e475b2e7749adb613 + ], + [ + 0x1b62d4b17de67375b58f248a88dbf707cc9d1491bce0095644ca0219a01e40a, + 0xd9bb7dab4a189a3b6990a5526c82b0ae50ba7dd558f951bb9fd343cbb4b0e19, + 0x75d1aa6cd2b8d181c9e0f42275c9884ae6fa09186fe227e5c4673e56e3acd28, + 0x28f9e0058ebcf1591bc007cb02ac3acde0851427db20c7358dbef9fa9c57c2ba, + 0x17e39ccba3432a135c0075d720c649562ee4d31b6da2e9c90bd72a039765e73, + 0xcd0a4c27de11aeb6460e32fa2bcb289cb83321723155304929eb0ca4eea03c9, + 0x2745a059d0962f1bf0dde1e1b97e0bbf4c4143d10fd3fdeb8d2b295ee4d7a9dd, + 0x1365a904c7f6721002dbce17077a89a92bb8038bd27af53333f447c4cf035a80, + 0x2f812121e2eaccc7d51bf266398d5ba8f601a2aa6d335eb69f7864642177667, + 0x21f8d854091ddb601dab1b01fb30c3d4f77cc3167fa3332c3b32377a07e6aac8, + 0x18393505ea6230669a8030f6e76130a14c1070a901ba5b640b88ae80d7d30b5, + 0x1e151fedfea11659c189a31ba27f2ccf6956084188eb2c4c99b827f645f1db61, + 0x2ae1ec9e09577c82c97b4b09142ace51aaad1df7dc352cd4e5813d8cee9c98db, + 0x24ceb0766de25fc22789286a09287be740310c41747320bdf2eb5c956e040356 + ], + [ + 0x2e1681bc7c22d24c433f81dd3a326fd0242bfc7e2bdeb6307e4d2aca32adda1d, + 0x2a4a6cc884cfd08af4b0dbe89b6d8e0e58113207aded8cbab2d075053efe998c, + 0x142a83206747200fdb02773e766f504c65af82b200c0e7fd942f92be23d586be, + 0xdf653524fff92dde8ec1c9a51c1bec30bf36a4f01e9b3b62eb13f8ffdf7b8bf, + 0x2ae7f1414f1443735318163e1bfb1e1bcf5c271f37f6abf1aa86766b2e59e049, + 0x2030b7bc2a70905d031674efb420336fabb0769ac0125c35dfe2ff372c1aa4eb, + 0x12a710de6d17f91af890102226853bb64209f1b41331a1d17305bf5b7b52172d, + 0x1fba713b98742311dfb3fa356ff83eef234ce8bf2b0d4a52de7af4d2519f2f12, + 0xc8f8722892a2f06c5ab454e407bd557e9c2ea77ef807ee0e3d89c6785b0d33, + 0xdbd093dc16e73832bde62d05cbb06f8271fa47229470462d8c18cf8a124f9eb, + 0x1dca3060a6bbc4c324f7efba22274fd8d1f2560a4eeba8c8b0d38997e0d9c46b, + 0x291bd9401de20916b9002a0066114b3bfae4d3c8308aba4afdccdf0aec12d66a, + 0x1c97fc775f962fe05a7b66346b93c3260c8f6a90a7f5c63223a3386e19852ead, + 0x1c7dcecea59e6f7beb6d702e2fe74588415d30e5dc09970bb2d56acc8e08328f + ], + [ + 0x65850d11d0eca87c3697b6f5e57f78ca86952bad1c9047dbd2eb6be9e9db30, + 0x1eb97819b3531ebb640ed6b42134335419101d1db60dd1a924ef9665f7a91af5, + 0xee4683c8da536b6b50773a469bbbde2e417a1cf9be221520af1e755968d7ff6, + 0x2dfcfb280a3d372dbc15639eace45c0bac562c44e292f1429bc916578fb0bfd, + 0x12ea921acf5b8adc6a4e36be85713576d658099230b0b1766c666f12d92ab142, + 0xb5342503af446ef824df4df6a088195fb67276657d420e6f312b2628e922986, + 0x9265fb314a676b6b3f827f07283a1ed4f300e8d90f967b20ff61f455d2ab2fe, + 0xab913f65e1ceb39ed8b83bd5d7fd900e78511edabcfe62314dd10d567858d8e, + 0x407d585a6a7efb561377e5f3972319a3e7285e146c5499ef6c8504a3d0b62e3, + 0x2ff5bbbc022d1b74fe184c064e58d967f1aad1f0926c906a5e356cfc3b81ad24, + 0x6da6d88c233e3182c5fa5ccda1392c0f89f7c6bec4e60da8df8054807eb0922, + 0xaab27e6279952c7291f036918f0b279d3b1d9f8e4e8ac380da77ec2fc24ea0, + 0x27737fcd76dd296c28817646d30b1168c4d00e1f764c4565caa3276defd15c7e, + 0x110a5e84de09209e9363c03c22b537ac6a7aaba2f6a9d1a1f6bfab71a960a583 + ], + [ + 0x1a59b36b94f9d723577e504d600c493f2810f0e67112672c743abbb13abf43b8, + 0x226b91e352c65de4fcee112445bff20e4a67af0e110957319b2860d5087406bb, + 0x168e771e9f8f860c49367ef919a00d4f128bab01c13d7dd72ce8d36bc6d1d835, + 0xb345890b33c23d167396c583d12e4f3d9efc904f261202512350190ab1961c5, + 0x1815d4c2e6a18f4f3fa538a004146d7f540fbe80a4605857714fba2795615df9, + 0x282a555f9ad4fb57698faa1fc3279bb8c28c1f8dc8c693225bd8520db4313489, + 0x148ab15972a6925b714602710fe9e64c0a015053acb838d0e876a46cb5653f59, + 0x8e13c2e61c446b53024d2116ab176c843600d00e676402c4641745158c243f8, + 0x11cb83e01ff5803b049a2b59ae9915b3e0045e1db694a6df9de9c4e7152d191d, + 0x119816862c8226e9e5dfabf3167b3b2bf7fb3d19063989b24a16d97c94bd53d7, + 0xc61ec79b106e9dc6494a6359f175ff637839ca53ac8e7a13471c56646180390, + 0x1e8ee641308ba6fe5600b2df492cf2f14f9892ba1025826c53c77aeb7bcdb04b, + 0x16b61b242d41e1975843309a01a36a14397d7c8e7beb4afbd9233b453aaccdba, + 0x13822dcc3f6271b71549c2cd917b859cdac36af6848804d15a354d4de0f67ef9 + ], + [ + 0x1a4b186b77cd53f961c8ccb7815d9781cef7a52af64d0bf746cb522512d3d0af, + 0xac5b86128ee47944c12af531cf1458042c35adfcd9e5b6a7531973714559de7, + 0xc2a439067121449c1ef3dba6be1ff84f6ab7fac4bbd54ad7539e61826ca1971, + 0x4f7f1fafee121bb811344f73f54f4a3583076739dd9dfc462b3ae6343c93cb0, + 0x18f6c40e3ccf885804b374433af0a962b2963fb9aa01e8bae8cc834b3e17a31d, + 0x174c1a1095e95d4f098c8d60826776c2f73691db37ec3b937835b65b01ba13d6, + 0x1f7f9704cab1cfea2b2471d579ef99d193b234af90e62ca09b5a671c2428a515, + 0x1fa02616024cd9bedf643ea36d262d1b24f38a557a77a82c686618c3c33edf9, + 0x2e1c292e06b7f8a6e4344f10540675a63ca49e452f69565fcfbcd43bac0f3af4, + 0x6fbced52576a913e6cdc5c5c96fdc8f9f4e931fa90beeb46d9b3c2d775e1e36, + 0x2cec67e62320bc6a0ca32518ec81c74363a4b6d259bd275a63425d6cede468d8, + 0x276e2623828949e6a2fdc917e2ed45dce0ee503cdaffc9add815f6d1d3c4f9d5, + 0xc75ba60f8e0f6afa126e75703b83d9908116147b8b2db45ef24f3156b8f1855, + 0x85e380905eb2cb7e753d0ab0ff4918b232c734418b6bfe1331de492fc76b21c + ] + ], + [ +[ +0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, +0x2525da24e1d134d9e989838304af65260bc9e8f31225ca603420c6f22782a31, +0x138f42d30ae01982ed697be56da923021ca5ec09fd9fdeafecaf1b815a8eb44d, +0xb68eaed660cd2cafd2ac447e6b5f44a4acc0acc59379fa1e1d6d6c23e29fd18, +0x23a87eff7dac26756048b8a99cef16bbd4ed93f085177da15c763bfbdd413a72, +0x298b224b535d0d32e971977b9fc2b3f83df09ab550af80b838c2e1308a388aff, +0x21fd7ef66c4ff374e85b552f0c1162831af7f2e1feaa30e4d42c9ffe585e730, +0x2a75ec0f43bf0249456ef5cb1e58b4716e135e1033791b706c1198e370cf5912, +0x217005316ff983a988abb4150d5b89fd58f5e7ef95d275207afab9bc736dcf79, +0xd200fbac6500899253294ec3394f5fc2374ca3e3243c34cd97c5f8f31f78edb, +0x225829f1730cfeb97ccdb5b1df418bac0f761d57293a39d5ec293014c78f38cc, +0x17b09625ab3ab20b7be3da6740eac6450972d5297ef55ff4bee47857841685e1, +0xb98d9ccb5cd1979a0c45a9ff8f87be8f15ba1cb758c602775d2a5711dab8f70, +0x26c6a596dcfab11f05dda86122034b6f2046c51c0024c4c673dd93c63ecca6e8 +], +[ +0x12186bb22000ad84b6bf29179ade2d4e7e94ff07e51627e09580571061fa8ce8, +0x945c0594d96052f702d1c0c8d423cc5f054bca11e54a939531e5c6616696a8a, +0x1a8993400bafdba532b42fe60fa719ee2bb70744c9684c87431ad462b69f6234, +0x271684ec4ed2564694dd8fd7f7ce52f573c22c72e8268ecffdb3f3256cf94d86, +0x199d5f44df92c42cdedb75daae78948bd1b812ef63e72c6d01d77c9d513bc32, +0x1554c7a78e970212db02a0c7478c02343ddeaf350d52ad460966c2198475e5d5, +0x222ab7be52097210638f70d1bcf3ad6842230e0561e1ae556519ed6e44ab56a9, +0x391e74d9ce9444812f42cfbe156e7403ec00c10888b716132c819542982da3a, +0x145f48fde51a4c7f0469cca2a20bd5c5794c594c08ea063412b82e4c21fb67ac, +0x1c346dc47106b6a9c0e34f2b6a59aa07c0e23a7f0dcd72f98698b6bbe2440a9e, +0x1d881f9bc6c0a69ad8c4cf8ae0854f5e39d7f120543ee72fc776156a6dc41e25, +0x1d6405c7bbef29b6526df75b9b3a43749f55a7cd60c2956e61ce35446a14055e, +0xe1f6e07f1a7310ed0af6b08fba57b93adf17ac40ad5b334a7b5b8d2b21822b6, +0x1dc01119987d2a025898bddb1d79385b99960e97c100208b5e992d9dc74ee608 +], +[ +0x2399faa648aedf9024c6ac3ceafea248216e24a9e56caf5acd29ce2546a9f6b2, +0x14a0f9e89a7bd2f9e93a28113256f5909e18bd8f2d4c6a4b91fa764f5d6e9813, +0x223cf3744fa802eecb6e33bb5d345a4e2e494e2e0868296a075010d891596cf3, +0x1cae3329696575edb1c98df16a20e97a0dba9988601fe24a6ac327233edbd7ef, +0x2d2d2d79eedb473fc052705abd07b5d7d13aa9a52bfa0a34b29bccb2768ce812, +0x13d95f949c83e09efec7464df18f95b0f569fb43aacf2e2b2b0d1b8d6a4ad5e, +0xdb367b50c96c5ad714104e535fcde5cc2d98a7358dd85bd98cd4e7398985874, +0x24d565383969b188f2900ee27741e48500dfaab461965ccf6acc7290c5c07b38, +0x2c08d33aa07452ec8d30fed9ac5f8218885c18de68857395b7361d06d5d50c64, +0x2eb969d5960104432dbec4c924f829411bcd4eb2582508844fb46c57e4b971de, +0x1899d3ef6a66651b27035f47a0030d77085b988bfb2595392d46a09eca668e9, +0xdcd018b542eb51472ef63566573192f167b8a41b243d2f9cf7efe0427bdc769, +0x1e76abfe0e0c0907983d49bc07cd22392c9a9fba1cad773f87877d8514e4103, +0x270775b57362a96f142cf0560a3c1f28f8b8f84b1695cfa20b271217cb9460b8 +], +[ +0x3add29fe398ed2d44f233125ecd1509e3cede77e6be08b94af4fec87eb3e48e, +0x292e485c257794ef8e1fec5dacdd6ca69f168408249a6e203853615080cd2cd5, +0x22a26c25e3631f154c6447ba2e8543b1d0f8454bd027168e715f21c86d09d399, +0x2013efe5dd2c054f547d532fd6f38d63bf3cdc07c1b3beae0b830c536936dfc2, +0x10b99b04d7a8e09059e28c723db16cb75528957858c3f9988f0050d18a30e660, +0x17e35329c9aaa754c345d6eb317c368788b093ed1d2d136714ea1b2f793da580, +0x28ec7da8ea43b28add669ec05c0866c2498ffe99bfdfbec896bbd70d08720f64, +0x145115518f4ddc7a878c4a4c3a0cda353142b420cbfcaf2f2eb7d67c6817ed1b, +0x21c96a22d60f44c34f543b5086ab4fcdec036b280b9f5a64a3a2003a2a79e906, +0x2fe67a3792bfa46545ba3633c2d504d9735e7d03b58f9208f584a3ffb3f04a82, +0xc27c0b2f86856b2350007a8501222d7c7d89c02919d2a310032c4ede9da6d5b, +0x76eb0679a3bc5901abf1204e92462dd0049c8b80f0d0b110ea12ca6d9da5808, +0x28b6ca5d7278ca2537b3167bd0e8c8094a06ff3453e060a1f52f077ce3c0f9cb, +0xf7036425c9f4bc087576419d0534698adef68a0ded0fda90b211bdcda6e05d5 +], +[ +0x121af61f4dc5bb24890abeb9251e5cea94770ab062dc0c28bb8995dd8f183635, +0x1b75bf6cc3265511f786609179f18b582a1b6261e9e6a9f05ac7e9a4bb015a3a, +0x26b90bebc295253c79bbc8d0324cec9805f3730a7c7e3c8cfe7220cc90b2ea91, +0xca34892eb7fa3d7bb497043be8462cb387ed055f83566b165a7dabc75bcc623, +0x1ce0f7ea351be6aa78e3ded0a3d69d69de3890cabc1bfcf40583226decc32d54, +0x1b5b9f9ac26a2e054deca324c9c92bf4d64b0b7be729631f2350c4db32232768, +0x94707149dc563db7a45c5cdd80091c3972bf52a6ee3f8eaf0e6bcc6ac0e3976, +0x25ceea2ec9fe11994d5d6c2e2af196963dfbe8112cfbcdb49c5b80615cbddecb, +0x2952f32d846a2cff15c9f028f02fb60bfcd8a7b34ed120ab6e393a1ec2794a4b, +0x930264343e7f5af2b7e5a4f7f25d0be85825666a68d5c02c5a813e958c3253c, +0x3f289db20976c1ec1aafcd0daba9c386dd8edb8e577311dda9ae8082369891a, +0x183e186c2c72f4a35c4fbb1eef8237e1aaa2379dd8d61facc59d6e5f44da0a83, +0x1c921c4536be42aa8a93ec0ab11a37231dcbc0ca9ab7749e3d5cf9913adefa8b, +0x8ecaa57e55d210f56d9c8141f70394e59185625df57435ee2cc924602212203 +], +[ +0x2ca8ffee2d58f2945297b00cd0b511da167080d53949b3f1fceaca9616b6143d, +0x23894e025a72e4ffd1580bfc4748a2725ab6f214a8f84e40d266e5183c6db8ed, +0x2600d56e9f728b982f23746da7a2993bce578e7204b9edd1f474405bd7593103, +0x23e3b3568798af43a561614af2c8aee40d2249d9f58452847c453594dc8f38d4, +0x2145a0959a46b3c43bc559b8811d309d48a452423025b85cbb3febcb24f4066e, +0x2f172acf4fcd26f6f939157d0da15bcbffa981ef6b22f7525c69f9ebf801192d, +0x28f529934ce9fece64356acf523f32443178669ff77a0ad6e7b86020e413ca4e, +0x9385ccdd032e8784bde4412886e9a590ec85ff5cbfee02a6c5dafcaeb90250e, +0x2a4b9eb8b2f9e4c4f2fd334185a45d0d2349163bcd7b808815b2e89543c09412, +0x3bb2a5b659f1f5c2c82bbe5824ad64a260e21e688f5fe01c61632fcda348adb, +0x29e0c22a0db446552403a18473a2e5d923f0d2a81b23f593877de4657fb1e877, +0xbb85f352ad58d8e5998cac57a0fba1d49349aae47164fba3343ae32ccbe4206, +0x24e9c71c5607519169015cca5f0be8e416f21194fc7d610a38d3e48df56dd40f, +0xa098b67cc231ed6a2b72bee29f823702b67dd0bca78f7316543097856b478cc +], +[ +0x2c99ef5e064147da9782b914a294b6c14d21ea7eec1f72e8761671069d82a134, +0x1605b0bd96a60af6d3ce4feeaba7498571b693596f79c09a3485cb6e37b1480f, +0x1b322f4a92d336fb2b92e1347e0f73037655b344fa6ceb1275eda5baabf61dd6, +0xde44974e91df8151d38ddb337dbefb7b2423f8c2db33c95249664256049447e, +0x1cbf2e32e48308fd5254bc8466ee1b448825badcd0d038171d39d77bd61c122b, +0x1e25aef828ae1b75374d1806053383a3afeb4c247bb3f4fc602a31258129088f, +0x28796af2b46e4481c8c68767d755b2f28c2229892c093faa86ea6daccf4f403b, +0x2b9c2881bdbbcab60ca2981c28b4228f8ad48e64a7b393ef4ed080907e6a1774, +0xd00d400c8809e16db25f2f1593dba403ceabbe3d0b868399bf12c1ce2a6284d, +0x17767169e7d1636e0cdab5d29588e903e1d4343000d5b54f3e523e956af6fd58, +0x12e4b3d7107e8bbf73c227c3fe04ddc9277aae8cf8b15a769c7039d282661866, +0xf53bacde9c9005381ed7bd0d3a35048f9b04d99b54cad41bbffc9704a574abc, +0x241e0bb48bf63003f858adf8134bfec90214a7836f7af1bdd263f5ac91906803, +0x106f70b5c82b6a41e401fb3c05ed0d4a5c1d6ab66ab048d2a928a323556632f0 +], +[ +0xd7d07cd3798f44d832a6571c21706758693e5e93684ce2d1a5e8a53e0cc6709, +0xb6ea459a3eea9912c01005ac024cdcb60d77df03bf6d57f9de9277855f5669c, +0x26f749e039b1b58e9fd714e0b5edbadd2ba23f0faece28348ab8eb36126e4a7b, +0x1a8077b3370f7e65d450e0e536e1e73c9ce33596023de1cb2d4f1321896f5184, +0x2f6784fa0636348e5b73d52307c09dc7de28dac12256995b7d2d8014be1511d4, +0x1b4e7d76dd8cbb42c1e90574b4f832a07a53912dc74b2f1983440252c232ab0a, +0x9367ecd533634327435fbb0317bfd4de720261bd6c77f2348f0547d4dcd155f, +0x290e7fdfa796c9a6a1b3c2e6d746601f49febda2af0d2e7ede804b822400e81c, +0xd532c4429d77c08679ecb541865f7230787381786f7d98d62a06e8a7f33f3a8, +0x78ec6b19c1d89049a01ea1a959df4525e1fa2b5c6d9c7fe00ecd899af5b8693, +0x27932ea804885d901c0a89103c29995ef207e753574a7ed679b162342c54f27f, +0x20fdd250fd434a5fb9072c597b940cc96fec2986fd603526b2becc58e431c8a, +0x211dd323ffb6bf1f7a0c747597593c44053c3d5ad428b1145d04f0a728f4199a, +0x437b94aeaefff8e636816d1f7484e12de60de9199fe298c3a8466036fde9053 +], +[ +0x29195117106623ffffb0af525c838686d0d97259fc73a5194609ac7b7b171313, +0x16be4a147414ff8080b2a744735ee85e2327c3645e26a4d21846bbda0f5f6ac1, +0x15302004242f418b70c701b89e3585ac1d2cef27046b512c7fa841e1c7fe564d, +0x103099f79452ce6c8848e50bb04b50723aff5ef915d2d7ffa0b8f72bfbb6a906, +0x1cddc847d2f8d9e6c20ff55628cc4e9cefc59a283a38842462cbe60a9a1d0336, +0x29bb557aa48769cff8a9d0ab0e7149f835c5552e5e5ae7e6384043790e45c1ed, +0x1cb2f7fda98a18a6fd20de6fbf412d07f0f41fcdf2088dfcd0e0b852fdfb1aad, +0xcddfa96db02b40d78f740716d6aa26c2c6cf125772a9835c9a34a9046702db8, +0x1f0f734e95a45cf07b70b85846b65ffd3c1eac10a95e0b917f27ce25c0ee4afd, +0x14ec222b4b95c3b602c222640d8d6dcae21dabbf1e805637ec3bfd8984577c08, +0x18f31da4274218b2691aba9611a798cbc9e9405f111267cbf424a67799ef67ee, +0x18a38fbc04f4e85a687161544a2e3323bc7bf504a5ce34e8ba4335767cb4eedd, +0x218b8f679b6f2f6070519663f49d69fd9043ba6d1bcd7b7b85e825abf8bfecdc, +0x1a3d570d5a331ae41c938e81e8155ded345d180ad5ba49b4e1bb70eeab467a36 +], +[ +0x1b62d4b17de67375b58f248a88dbf707cc9d1491bce0095644ca0219a01e40a, +0x23dfcb4155e378ef7d127383d66785b33808a3223e22a226a3e3a0f7bc5200a8, +0x1bba25ef90c2742d6bab9309747fc14cc73e4024c803db5e58c7d2525839b2ae, +0x4b3c3687111107b6b39fde1f5eabb0de5e2fafb481c0845f0e9e3e5f90057b7, +0x189aeb454f60721eede010a005c4ce55509f152e6d0e93e8c5f9a9a6d3adbbd3, +0x18572091465cabeb96748f5482d37d3926bf7c1d6680dc932f45f55a7042b02d, +0x1a5ccf7ef451a14b3fdc531a52831728f5ec26b86ba77c952701db2913a698df, +0x152f38cb9808d5c942c23624abe88852a59f2813392030fdb7b1753025829991, +0x9e543a62e93aa3005be9112a49c5308f5b6f79591b4824f6355ae12300988e8, +0x1a145f49ae38f332ad67bd90734b8bf9d97dbc5912cbac8f57417e334f14230f, +0x8857c8b3f0b9a7649805371c01a74c84c67575d9a17be0e5590aab52143377e, +0x25fda357cdab4ca130314a01d381febf812c14473e4bc9b13ce8849eef1cbf96, +0x27b831fd2727802f6a873109adb4196ece489fb5b48113565d8113427aad42d7, +0xeb8c6eb7b2a00cb45db63f58e55d78f1130d92a56095b485c662be692644733 +], +[ +0x2e1681bc7c22d24c433f81dd3a326fd0242bfc7e2bdeb6307e4d2aca32adda1d, +0x22415ca10b65c83a039f1a749e649fbda0cfe2fe3403477a40c10689ad5af158, +0x21c92d239c137b9a280a728acbd058a8c75f321e0d254c346aef2b0f3390b07e, +0x41fc409e13a628d9632b87385d24bf4f2a712e3642a36c9875cbb5e90028065, +0x6850ae560ad9a7e89bf454f4300cac5f5184453afe49fd3552e63e44e72ac55, +0x291f4b78708af2e6d2021bc67b8b43177e7c0533ae1d89287612d85cbd16a4a3, +0x22aba2a6f80e91b2b4912240c72983f027a4c158910c03cc1cff66c545f8750c, +0x22e33116da2228316bf3d68b2f1506bb5b5b87ed556aafe4f1c1638f723b0a5d, +0x27885fcd66e6a1bda1f55599328bda53f0dbbf8fe39d8e025fd500e44ffdcee2, +0x28dfb66df089941c1b64c42f01e015b5f3bf8764452add9b24f4065b7d276244, +0x2e5ffb493cfee9eeaae1200f360829d0c2c09ddb592d37d0821363aff6ece299, +0x21157a29f47613a80bdfc774d1c8278abc3f76e15937ce9b24176e1b4c9e3b7e, +0x1cc9014506211730afa1e9e45c9f38b6e6218ec646e79dfd38ae0cb8d96ccffc, +0x210396c1be722404813dca0f052e321e183c00dd1671044b18bdf1560b04ed6f +], +[ +0x65850d11d0eca87c3697b6f5e57f78ca86952bad1c9047dbd2eb6be9e9db30, +0x854fec1c464e2fbad9ed6737f451f4ea27b6a1d97349941928b5911b5b7e3b9, +0x2c240af2cced1a6d0d5aeddc36c875d3a8e74325772748ce1cbd5e01801b188f, +0x804921684796339f40259855eb51f118262da54c1ead0364ed73b7b6f328dce, +0xfea56a59a68a9d3131f96672be04f078937cfae01bb185c074be5f74a37b226, +0x11f61a3860411316eee42dfb735b05e0ab5a905a2478b9d446acd0fb1403d00d, +0xa80fee34581fae3188ac5f2c5aac9493e6db12ee7a2782a036aa65ed89f3825, +0x75c8623c44462e495ac4b62536c790a89875e9fb559e29fb51c32d6601ef297, +0xd4ee74163fe389031e01f793b3cd7f76971649372ef075dd3f2596333c5a6f8, +0x2a06bde137eb0fec584cfe2f11c2ca43be25ba8dc31e0522191cbb63ffc50b6d, +0x237277467500a6589f208fe577a0ed6bbd805f5bb1fc0543a22f21cb98b46108, +0xe20cd93d855c7f14979bcdb315d2f9891e09e4099cab4f82b66481d013eac94, +0x12dfaf2a058c0890bca0bc89b72eb4a575f10b43a009c6ae22207149884b4638, +0x299298324b7b1e7cfb05fa7c62c2c471b5a8dcb233f8c9e1becf67d8bdcb4416 +], +[ +0x1a59b36b94f9d723577e504d600c493f2810f0e67112672c743abbb13abf43b8, +0x258e09e408d6f662f3539a649aa156f18cb46302fd0fe34f007b731db06825ac, +0x2049f9cf12d0e210a7d82a56694e58c76d2f1c5ac572aaf9b6fb770c09f8dfae, +0x2d4687de2ad43600f6852c2a191cf74d0c3e4a7ca0506f974610833fa201a72b, +0x2803e055305e45f9ba2d154206439c02a37e8a5c3fa8eb38d883c75137d96216, +0x7ec1b96a04d4eb1f0728f1fa0493019c6f1a95456997ba5003bc2bfdcf43ba0, +0x1dece2bd9b515875c114246d055fbd55492a7d26aa8022227192600fb17c8c82, +0xa1973619cf434b77422536477683d092d710c68a3644946e11dfc5daf4c3e35, +0x1e4a2c836090a5c960931f020bd616629e93cb093ee02285f8b9d850a74f8b57, +0x2a12cbb75facd8548f0d464d85c961acb166b73aeb3422edcd1c3c0400824673, +0x2ba25258891906648372370673f8b9701a7a17f5159c26f83acd03dbddecb683, +0x19e70fe4bddddbd1a2010dd7f35ad802004b8486a6a1296b75fe87c2c5246908, +0x27d1991b6be57840c86c76792fd9c3b44cc9bc56569d8f5d78012c17c9d01b20, +0x26a6b81d5d4c3e4df5e93aeb39266b56a536c153210b9f4dec10ece36e3f9e +], +[ +0x1a4b186b77cd53f961c8ccb7815d9781cef7a52af64d0bf746cb522512d3d0af, +0x8b39f702949a0a1a5906339e83e663519b264c3039aba4688bf2e3788b3ecb6, +0x152877c59e07350aa9f0b36db00c436234c76249dd0099607b03567b4e7f056f, +0x1156a55febc770d3e72337b4db1bd2fd680594a9c9dad08777aa5d898510e5c, +0x1e2cdbd10cd7e2993c0a41fb073400ff938f590e30b3db6855f12c129d681f12, +0x4f089c87cb7babaf031a4d0d0f5c08e00bfc99cc7befcdb22e55256170cfea5, +0x2ebc3e6c61ae6901d3047afb5095d5f86071a28026a7351945d6fc4626c2f1f9, +0x230959791080b2d262131ee7b43c2de9422a9b3a59ee1241e762ff0da380856c, +0x10bf2e728bec374033c31e16bab6772056a1ace43bb4c3333a086256e0ed9d8e, +0xcf6a0317dc98ba7fbcb0dcef53d804271bb932225cf3c2fb8c0564b898c13b, +0x1306e43717156fb4e21ac64165dc5fd04b3f5dcbf52314fc0c84d09ba5b6578f, +0x9a6e0063c05651d63e8365f4e17415f0ab59d07df4916e9f3c6f649c4f10250, +0x211a3b4e93de320852f06668c192079c3d65a00de2a7cfab966ce0fbf9322ec0, +0x63781e7bb64e40ef54a4ac17d47785b8fae5da0c4b3bdfe4de8edbda7029bef +] +], + [ + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x1578623ddfe303311ac327a432aee9ac8552cf37d7be9b4323c9a792c5776c4, + 0x17536451518c265209c2d9d8512a80f5abe4df372bd9aeb5eebc2b799fb1d978, + 0x1025b7c8b5b38ccd6fff7dbea3215f6a1cc80c64973d8972c0bc7674c733a157, + 0x1a7c14617cefb39cde217f3c2583bf35d538750ca9818e2f04268322c282012e, + 0x27993e8fd8e80385b78a6214675405361deecbf2c86441634eafb7c99fcdda8d, + 0xeb7c2b5ac700501da181caaa6d42837f6f51713924eb3e5d6543801ee3c974d, + 0x22313b179534e4b6af14a56f8eec32f02c41988093cc7f4fefb281956250b170, + 0x277988ddf7fa2eccfb2560b2b169e12a48dd0b3707ba3cf1c0a514c4852ca68, + 0x2aff90506172c4300c94d20c37a877bdd98630c899aaa00bc83f1b7d99e6c943, + 0xad7537b0825edcd460d01970323bf5f0c336d57b4ec04b155e361068216f859, + 0x16573e4361e87edabb67f04a10a84b8655a796aadaf0ace71d282a03ef73369e, + 0x7befd625351a2e970860afe5ef0eab07dc7dd518eb6145de77252bc4769a4b4, + 0x250d2c639105c9c5a3ce4b6df01973cc41819fb85be886084076f4114fa0e654, + 0xcd782c85933dd07ae0f3f6b0e3c440acbfd915c2fd7da79cab1cfa57f634f4c, + 0x23b6198a0c85767848c17cbe8708eb23bf53938a60a99576e4c2a7caca25d18a, + 0x1f7e50e68a089b2286a3ab4c8764b2cb8d0da8b26b85c0f3a468c781f7cc114, + 0x258ebf40c08515d8976fb6d05da5f7a43455448d998e8682aa49acf25a307d24, + 0xde67b3b49cb60cf0f2074e36325065707c58c2fed40ac7a1e2856a8fcc3211c, + 0x178c746273a2650cb608c7abed3bab595e8c1403a7d01f8a8d1cb4197e3e96d5, + 0x2ab3c9a0a6988f6fe5e3739e7ab333de77084e6177b0778931f004083f807de6, + 0x2d86755d3a375e8b14ef5aae6e2eeb5105e7ec1607de4d61258de2617f790ea, + 0x196725d332dc50d6d916a1a6347fd70973f461d2a1fc2b941ab891aa04b3f5e6, + 0x132d62cf82833c79ff5136eb2e396d5719f76ec0c556565b5a7869234afda829, + 0xae37c618053667860b08f31cd97e4e266191da715708bb84444741d9eb591e, + 0x604994f682990576a6e1c907633bcae2b29d2b91ef8af1911b41fd3fd168, + 0x182aa4ce666d170a3aa6bb17e7ec00bd00dcbfebd02f3fa500e8a01d6b094a49, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x10f8dbfade79085f2d9cc0a15334272898e50848407cf0d1b6866cde260a043a, + 0x1953bff54ebfac7d02d5cb8e079d56c84eed51d6f341dea31c6eeabf1a65967, + 0x1344c0e662baa299ac79300aef7ef1387b1926b0c323ea279be046775a8ead2d, + 0x2f027dae71476ebb6b5f3b1630f9a92126bb31a72e50cfbbe9e19ba8942feda4, + 0x2b5570a23123c5568920deaa8d1f8882ecc0404bf73bec01f67562b600568862, + 0x2485dc5ae845e8acc0c38c7ac313607479e4ceeb25f35ebcecab10d829fba247, + 0x25b7907ad098b9a7ec9773bdef17a1d315baccf502a2a303ae9292fcf24cf86e, + 0x25bb66388a0f8630d499fd04740c16ae3f6f8481b2f9637a370e921489558902, + 0x2a00221d8edc58656999ae7406d58758e795a9741c004d3b99e0624d1ed9651f, + 0x41ea47bbe1f576a1bf165e9eb6c82b74cacc22011c02d1295aa68a734108477, + 0x2fa5eca22a4bfc0739f0671dadb74de19a49bcdbc6b23b3e4acd659b3ab7e2ad, + 0x1a103aceb4a30c1289f86ee6d359ee808a1075dbaa86a9b590da829f89e0e56a, + 0xea6e1b215fdc970b74cf8f31e3e78129cfad0e545939cb6ea55b4e72f348838, + 0x1017db78c2c1d169597ed69a3dcd02467e30071dd418eb6e9db209805314814a, + 0x22002c2422ecc59939f303b6e3d02d35aafd288b4f7936838314e2047b669672, + 0x7c83bfe3e0cd2efa62ff8cdf694ccf8b3268c2356be960335b45c9d57751940, + 0x256b5d75847a3cfd5c4a79c7890ff08c58b73a31f14bd07247241b70e3b892d4, + 0xaa8d8fe4f42d5ec00f582f56d0d64aad9977a43b185d66000c139614d9ea30c, + 0x221dd9b914aee821ea23c359b337345a22da01eef81613e55c97fe275b42c4b7, + 0x7a71841bdf7ee0dcf51ae4195cc8adf79be1563616fa5f6b5d932eab3cf4d9e, + 0x3f7813649d46bcc7419f8ef37cf29e9b486e285da3045d96b5e3c6b636643f, + 0x2e4b8a3c581c527e8a12b4778ff69d8405b2dbef389d6bc8ed143f72cf2e3b89, + 0x17c1a87f4f960d913f5eea140959526f4c8ed7a7fbc2744fe37ed332e26bfabb, + 0x2c46585ae9f6cb77c3217988da69423b71724cff7fbd8cd879a0c4479af148bb, + 0x2d54300c647a770fdc4340e7422d79b643596ee6ac6f7e1b3b6339022a1768fb, + 0x1bfe46241f2211c6ed0e7723765850aa6da18b5d6c692d33eea7647a73d097f2, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0xe2cbddf65c2ae0452e3eb2578ac21a1e5279c42481e4a41affbad2969721705, + 0x16ac1278c3b044618e61a767b13dee22fe364509ef89845b2fad1a47c2b9b5ad, + 0x224149478db068fb7141fdf2746d34283ea9e42313f8bfa3e9dca597a23ffd95, + 0x1a8f0b2c1be34d3d04ea78b2c38118f6e05ec781ab95c964e9fec00e9da70f45, + 0x9ac6d36b9a63d40259a98a78c9a223de633299b75cd49a944ef361e6f9fb9d7, + 0x12810af0ee251f24fb86894b758bc4e0db0db4522260a9bd5406baae536b23e, + 0x13e21a7cb8f49dfb990df144ce9b950ace2762a38331d90bfd5121a7d8cbeaf6, + 0xbf46bbc35ce9bab54a45c3b9a308df40b6b771b3a0c82634e86f0e8369aa2e6, + 0x2d3905ba22fd54bb55e4ca78722d0c3c6d922ebee33c024e3b530414b0e27819, + 0x21e94a20b029bd68674fbe1179ca813dfe61b3ac9a2cbec68fc63f4625ddf20d, + 0x2eda11aa8cf8a13cc36a5ee865c465bc8a7b91e41061abe33ba2a48945be03b2, + 0x1e86878d1a99e02c9108ca361563f8120dd46552dee8cd864599bd965905acfd, + 0x213f9fb0da20d21d4bd549eb2cd60f2e951cdf11bbaed2e8347637c28e90dccd, + 0x9ec04662663c012175d047b3badb9cefdd56abd0e1bb8824f8b1af84c81cea2, + 0x2cf6e22ebf6b69c9dcfb9b5e66d03f2c9dead8b168be2671fa0c900dc0349c62, + 0x1cb3909eae030fd0ae2a623232e8daf5a527642386e6a1a5cf8cbf36e49c9f41, + 0x2a954bb1d6463b7b6723ea7a79b331b5201cff98ebdf77311f8eaab7a4bac880, + 0x1d232685a73dc553d0e1b8099acd8936bddf42a40813d52edb2ba0e2a72a3853, + 0x252d7955742982802013cedab484c8d461f9315fd6c30a13a076ee1fd84ac652, + 0x2144739dc6440cf4f08908cadc61413b30e9fdea3d600ff64f05c5afe2742a52, + 0x26d2ef597c02295f490a26be40bf56c9505e4a977f017b0ee1b4539bab40f92b, + 0x2effc6807ad79b837e532bf4a9f65a83f920df891e563011c34c585b8b5118ff, + 0x2e095a7e1c68ccf1cebbfd1d9e6b10661fb3cef485f2ecc8dedeb107be1a99d2, + 0x226f0b52596d08e12c5d979f74cd74461c37b9ca4b74c2d3d72a467f682f67a1, + 0x27e4dc61b7f4c719754040db80c2c2103197f34a54a5de92fde3460eccf92b38, + 0x2a0121e238a13d0dfb1507f0ca6c1686f838aac334cc1ecb2f7d1ffb7b89c130, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x33c6d4d77acdece9099b3b1c2820a64c2f753582562ace2cc24fb4bf2099d13, + 0x8158a4f4a451c60b9c190787757dc064f45712636cf0171e54775a94bdf1954, + 0x1d18e0af711abc6617c0385617d21b4c1896f0199ba927f33692b3c1171294cf, + 0xc8ff9debc6b5b90f826623c99e25cc8ba5b83f810b1c2be42298e445cd1e516, + 0x7455ff7474bf2511d200716e916cb97e0842864cb89a42fdb87a479a63f5055, + 0x2b796bc4350006ffb852f826d4261ff6fc792aebc1cd37f273e652180dcdd65d, + 0x2231f46d69ae4d0ae2429ba6080b7fe51f3f934c3d6607aea12139450e394dd1, + 0x2e37b2806360065a4e80fa3e6f3acf0cc90fbfee5e8e29fe20367345f8979dc5, + 0x1e52b1dad965f7d359b8dec0592575d918b48baf65dc217a442db727e46ff8b9, + 0x266f2edefdeedb61c866a0ea64d019f31d1ddeff9607667a5e89412393765810, + 0x622b99a4f10e3ea4c1a9f0a2c0823602a1f37fcf2d70b6e729f8a50751dde06, + 0x20b6fa4bb93ba74bb91a9680f4dc15e2436baaa16cbd85173881a89d2d39bf07, + 0x1edf9a959b552bfa30461615955d8bd5ab7a2d826fb2b440d363029b7d8a16c6, + 0x2352faffb1f4d71dcc7870bade6df391c49d4046451de035837feed53448ef50, + 0xbb1c8476707800ecb7b2cf40d86e6a7d5aed4214b9d535b21a0292790294b29, + 0x1a004861dbc666a632c6ef9fca6214a36256e7b0ca97cee63d02d5740f7f72fa, + 0x115cc0fb69c30646288e34277bb9d59f5cffd364b3a48dc5df13936780e452cf, + 0x20b9d6ea816b25eef2eae178eb85edf16d922e259758611f8ca73a8560e5f612, + 0x1b7650b9721a1589244d0bb8910acba3020e5a849738c729261d229252d7570d, + 0x228969388482a46d9d2c33e3cee3f07ce2c8d2438e0023a20c7d5e7c1c84bdfb, + 0x1a1c5996f580dd93a0d48654c03d9fbd053a6d4a64b21d4487b7d16d586b9575, + 0x25c69df2d6d1a1203df21d682d24907f08c34b941f5351caa2b3c26efff3d1cc, + 0x12848ecece4c7385b709ff7c98962c528865e86bbb652a874c495e5931986f75, + 0x76bd3756046b7989e8aa9115b57abc352f470b3e8e981200cf37548edcc00fd, + 0x2884069a9ac9139181cef297a585728448ac6a74a26a6fe56bf9ef62d13ec6a3, + 0x7feff811d5e99b474c5fa155004bea6a6fcdf03a681acfef2e25ad334f71e5c, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x1d20333ffc3cf745d561f12c425d8e1148000b7d042aeb5f26c5dc223fe31865, + 0x28abbec7c9caa428c519415063a6f2d5e1a0d349e3061f05c40ef35803686d42, + 0x3a8e10fe7fabee8686830b8234275a3abf3cf888d9ac500bfc643c47d476c3a, + 0x18c2e2dc3d8b832d050468b7a71e26bc0d6e887165176ed06c07fbecd3d15a5c, + 0xd50f1334b2bcbc0cdb0117a17c5542080751590a269f4530441ee1a428cf53d, + 0x13806f8807551b28f4a063f853d51c621cf08b2f67259b03c7b1b10734945688, + 0x2b08fe6c94ebbbcaa380b0dd6bf50430c5bead290a5cefef3e75aeaeaf7b63fd, + 0x20196101b753985b8d81c33fed2d02bfc0594ed7b25aec355a1efdee746c5633, + 0x3745c143e9794534ba8e09393a84d537e45a0d9f4777e77fbc14d22daa2f067, + 0x23e0047f3bcd71895bdb2030e2656ed5ba74f2340b2cc87626a6739b65b69299, + 0x2b7432db324f5d63ee6df8a327ad7d03752feaea63b8483523e1b1ac50af5356, + 0x3230e5463fa892ae37f38ff6bffcfdb09a881baeb117cd45199c5f78498334e, + 0x6d227987110bba2e393ccee1a5d01fb046f88e9e82c975d69c25505fbe2f7e0, + 0x2137c2037b936b9af605dda34fe4424a2f095aa784956c7e1a8410602381d2e, + 0x1b85811f361794bfad1d365f9278b8ecccae2e29f16e81a4e81f8a76980b06df, + 0x18ce9e29cabc3a88ae1032aa09a664a307f07c41d0d495fd88f4729fa471d83b, + 0x16117eb08d088c3146a297600420e21723b75d24767e3e927a465ce543a442e9, + 0x143137a07224a1f3df382f66ed1eaa0000006ace56412ba51954dcecd725f03e, + 0x104d16d80f93f2955a067d5b615b3169cffa4c95c7bd28c57df7a098608b52cb, + 0x1d486d6cc1ce7b6f2b3aadc680d663e9afed57c6df3948a99edfd8d21f3283e8, + 0x26b9676c3f4be27618037e6b8681c624cc2badc95e3dcc2858f44e4227b90ec5, + 0x1b9d6e78b161f530bc835a17a56ce26bb302ca73846a159744389cba664d9309, + 0x133c6470bb5a345bbb1e3a3650b9a5f39295bcfb97ce888cb775b07188be130e, + 0x2eb4042daaad9726c71a3b6be579dee9df64b6aca59cbcdd4e014ddaf860cc82, + 0x2b7e6bf97ec1a114b17e6bc4b4808ddff15614a70e43318f7840ed715603338f, + 0xa1125917e9750fdb258e4113f2e3beff8cd77b2e4840d2a0a3efae84324f1fd, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x28f2406d5b2006a8163fa449cab775337ec435075e08f76dcb360575f1d0f9a8, + 0x2833ed76d81d99573f405e2418760ecbfad333f71b35f293fb3fb2550d32fd32, + 0x1329680ba1700fd38f42d6f88a166d7128ee68baed48025f1bd8273c6d13d5b9, + 0x2e406c465948d552b82b4d0443d9b4393e9d034c1eb96779b25554850f8d582c, + 0x16870864c7481c37732c1226601c0fd0912ecaec9c4986893da2ecf1e7e9bea5, + 0x16f0206a256a1eaf579b789362d74a6df9b4e8f4c3bc43a69d5d84f8e2b86e1b, + 0xd3769821a46417d7c41de7fd8a44cf0e6b03851b33d35f9105b91fd045f4364, + 0x208072d81c7b1e0c7fb8bcf2e372a3a6142d3643084a78bfad3232dbc4d0421b, + 0x1b00364bfd8258bc091a61caf85bdb512a8319ce47c9dce782e62103c2c7a71a, + 0x39d9478f244268c4803f9dd0dd5e63217be3c8118476c3c36c463acecc573cd, + 0x1702787253c770367113ca024f835dbae15b5c16bcb2121cf3d89bf60993d771, + 0xd424c24ab70fe46dc0b70ac44f1560b98a7c179b6fd59f87b51cb1580404f3b, + 0xc8eec67747155b02438d197c9d55437492eae235c05e385f5aff238ecbff493, + 0x19318a85cac2967adc34c434ced1261abf43e1bf1184a43a0897436121191ff7, + 0x100d0e39b0ac4162d13e523a8308b3d1185ff1abc0a44f80aab198f4d4af2e77, + 0x1dc9edb515bd622a09d6f164eaaf2cb987aca23e7a0a79c8e00d02ab44c71cdf, + 0x2cb0a4d99188559afba7226f3a7dc66b1293a6d5dd7ebf396ac96d3bb1b0dc69, + 0x457e9defe2b2e3ace40217181c5cf8a361c3303bae8d1b867e62386ee0aec8d, + 0x27cb603ef3700431472d85ceaca537bcaa301d220e8cd68c8db9b2e1f53e99d2, + 0x2a0f737481bfdbd65f8fa4cb4463e56a31bec6e77c94e27216f4d5aa734df9ed, + 0x88e30685326b92f6007d6efa42d8af737bdf42ec7e1c4d565318181d8295ea0, + 0x185dee7ffc1c09332fc1436f1c6d67eb3c6dccb36bb98177de5f2802302c68a8, + 0x1a3c2ca9dcba78005a28af3b621e50155295f14ac746057dcce986f6368d3d98, + 0x2c899f8d46c18eea46b9b431d69f5449bf5c896b07343a5199e587c748443f7e, + 0x12b7b81c78c7112c7f79de2eba33f1859e77ee9bfe54d5f3ee15bbae2d6b90aa, + 0xa9c41fcacf18941604fb129682761803f162c0e7cc1152f70bb76a28995aee8, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x18c2c80c193bf893f8e24328bb79195e1cb8ec5c30fa4d0aeb228c820e7edc8, + 0x840212cc8df69cdec9a5d73b33f77e6630cd08a0462709391407c8857b09be1, + 0x23a2a69b4c1f2a9d5da9bbc185ddfc88facc9958428e06fba83d67a6bb7cca8e, + 0x2990a00237ce280ba705df85715600a7d425d4ebe2b13ed3b42b1b44ae48fe01, + 0x268d4b3af37b5f5ec11836ac54c1ced9c569390d0463c316c2caaf71ff452c50, + 0x151286c34d2d1a88fc9f696e6c762e833309a6710e03831212d317296b1c211c, + 0x5a0f37b771fcb8d26bea09722510af9bf510ae84c5f0106d3824aa274e80f4c, + 0x2186448573dabfd800c596cf64703bb0bb45ef5b8a91fa21009862ae3aae0c0, + 0x27ac5eed415340d9907c6b414708cde2b99de1a550be1c26d6ef95c6ed5fb9ac, + 0x118baf60eb743773cde629142c30f86d49d633c5879f1977aeb8496971b3b956, + 0x2206f4af9dc21a5e94a00775629d9eb46a104ecaf0d2188122187fbd9c5f666e, + 0x1874fa5cd6fedd8dce56a38552b35512bbbc6ca56a4bc6410406ad149bd30589, + 0xf22dcdbfea00f4bc89dbfeac7b3dee60b16ee9a74f13588f5879ba714c827aa, + 0xedf94bf49c040df972e27701e16229766d84197b29f023406564e32cfd8358b, + 0x2d24ceb96532b06e751d109a7efcd29ba741e61e3472bece30c7128c47042813, + 0x26fb8b8eb2d90ed4886b9982bd3255b9df4690f84047ccd4bdf21810720bda44, + 0x1952641fff4b577803eac12d290acc39f4728e3fc086f3f76313fb2b78da5b20, + 0x2233ba51923c10394d1ef8718a6e82d84d9054de8c8498bd05d52787faa25e32, + 0x10550f7d00d83f1e7fb7e1c9772f545e32e0a60ca3ba0ae168c750147df29eec, + 0x7e5e890c3e62c5109e3790d2bd1406f8425883abfdde19cbba3b5aa7b7f2bfe, + 0xd611acfe2f91f645a07af0ed66ea813d7395b09b4e4b3cb92afc27a31e7cfb6, + 0x1fc4f96fd7c7a69fee8092b6d11c7bada79e851324da48e658a166d00e66820c, + 0x10b23d2c5bd7e976228e19064ff33921faa59f2eb4c8652d39546479d26ecb7a, + 0x2f21166be2ed1b2da47425d6bbf4ea1f2c5aac82b83265913f6ea70a3321cdf0, + 0x2ab0952fb29bbeb0d5728f07aa4d67431c1d3c348a0f1db6126e47cbefdde394, + 0x2a10c76f857e47245d3c145ce70c87a1995448579647698c122d3c7f8087639b, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0xe8bed4d86934cc84383480e2301331becf2a8756e9098c8a5541d39b3be2084, + 0xbdb68bb05cbd1a32bea32b8daee97ede7a999c31e66621b4ecc57e806e9b68b, + 0x1c68215101419d83d15a0260a0d19456d8a4d552edcef12b8eb3c8d0fce018b6, + 0x14c45f6a32e995585ac81545545d2803fdd9cd0fa462a89f2cc8d2f2869289fe, + 0x3c63147df05188262fe56d1991f872b8069a6c07b7358d166003ab422a2bf67, + 0x27b093996711ee7e4d1d6566008eb46b53bc45925a385ba64c4b314e68f5f939, + 0x1a67fc8776cf402c94587340f50ff6a0037570c50f24daf71d3b14f12c37515a, + 0x368384bc98a519dd78434f63f92be511aa6ebe497a0f202c40dad53cc9ac41d, + 0x1cb8fa7ce16b44e38432742589d4857c290e41ddecf1c04d19475381588dbe15, + 0x23597b850f364b4569de68f1ac728565dc30fa8ca25fbc7cb04de5d7c4b97c62, + 0xdd8ff19d5e1308fe4266a519030fcbe2a9dad492bf87320fee1b56378548b74, + 0x20feb7de1a5e96b834f33f0cfd2be704639c024c4d40b2e130272ee52abd43b1, + 0x20885682bab854ad9b308b29e93bcd9744b30a32a86b43656eb9eb398958c569, + 0x19d3a25bcaa553994b945b1966f0e88877b49a0eba7cfb7436425ac980d1f4b1, + 0x2ac8cfd84802b67174c30e48b6b805af5ae5c0e308beb82cf3734fab1cebda79, + 0xe7309eb986b717f72684842ee44266078aa935820e854ecc26e86b304a3aaf8, + 0x2bf7eab7ccb382e902533c265b264ffa63278fa298fd28467cd075a7e3bc332e, + 0x83dd2953c55d5c2b9f2835c418fabe9f31d712601bb68964101149a09100404, + 0x714ed30fb5590de5189a271e1a8c643e52ab0e5f138671efefe328d85eee14b, + 0x21148f9fd3b0722bd321a3f3fb59dfb18dec828c71a820e50e2dc0b77ba06c28, + 0x2232e4d97bfb4af6fa023ed73bdf899e040c85e086ec61f64d9e76bc8aefda1e, + 0x2f130c81592d14daa4a108219e2381a3c3d43f9a7fd9407eac791568a7290d97, + 0x1bc3006aeca257aa1e0a79238a6aeca17b61c6dd8c5e38ff259cecc70c6d957b, + 0x1e2cd754d9765e6bf4ee604c3027dd1553e6bc4c96f0a1860de5ec1ed4e7789d, + 0x1b03008489762f18d350e6f59491be94b91125f6d564810b226020fbf1266feb, + 0x4139587c94008d2ae2862f17f4623e00a60f095650f0f954d33e2b3e028c8a3, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x2e92d0d003478aad469bcb62a9ca4fc6a4b8b7b54aa20082421047b49526bc1b, + 0x2fa9f127e186da4adc277ed2d0fe8ecf65d7686171b3dd9b5ba57a41d94be782, + 0x16b524b227c91d14ae22fece795ab7b4e0672f93bc0be11a4bfdedba618ec632, + 0x1bae132d3cb67233efb7501a87ef7d5304d43d84795422a5980fef6deb8d9e0f, + 0xd64e85826004f524fa9633ff3dbd2acfe2147df88df435e71935e5184c0b5df, + 0x7a8991e9213182f06e7f27126e583ff1002b732d48fe69898c3dd1854468c4, + 0x78a71ff06f3a7037e3acea1df2f04e326774ddb20d6717052065d5b48e4d9c6, + 0x2bdbcc0653dff0b864ba7c35a2053688b9a13ccf83fc78b5857a91183c634ba0, + 0x135c4770b984ca724061061017f6fac63ce3fd5f42e3271af748221eafa486dc, + 0xbe4b3d77e216a0284da484fa0ec171130980d6648a10e81494264284df500af, + 0x1d33a1eac83aa2e8e33f90bf9ac51bdaa186d7714de7cee4357b5768bdaa03cf, + 0xc80a19a319c0095d10de1473bde0636e199b13b8d838336a0133f86e9fd280c, + 0x1fb00a5d5448228839fca9b108ddf4cbeee2e5c6a7cb8d6bbbb33daf72e5dff0, + 0x3428c5cf5139a60a19d3faabaf6d8571c01242000e216e3e417d37476da91cf, + 0x15313c7636e93c90281b5946d1223bb25d849c6b05a9c6e58e3459d4058b424c, + 0xbe94e5c44e86577fbf39b9db0d3ab08a8e90a14881360a3be8e77b1465d6a08, + 0x215f4fc3b36e8ef41ea226080fa331489bb1f5d5b2e9924b5f419a2900390614, + 0x16b0162d774c50882a9f2739bdb279317918d0f75e2fa75bf24e9ec3f1a21102, + 0x12c30feb12fc441d6dd5059c269074f10a69decc148bd2283dfbe594d2a538a, + 0x1649c52ddf7788ecb2150a1a48aad096b4dcda9f517ab877a11927cc3eb7fe9b, + 0x6edf4bba85eb1927ffaa307aa9385c0e11eff4ba249a8e605d624f35af6f9db, + 0xf61ad25f3641eacf1ca4fcee3830d5222f357f046c474ebdb732e0211e49e40, + 0x2adcc2f96c95a40d796e0c8bddf303d75badc37ac9aa6cd3173b868f6d177dea, + 0xa50edd8bd899b1d15dac22136bd3a3ce00ad0d581188aa6c2db96ff696613ba, + 0x26a9ed9b96681106cac0e7706f4293fe79d078d918f25f07a9243b912f5d5238, + 0x19595ba4019162353cf21250cafa1aa64a7c0597c0d0af5b1de0a18131520439, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x969363ad2fc56dedd932a66bf1193a1b96276f16e423f78cfd790850bf93477, + 0xf364b0a5a1b00f7192697f5ca0960680b217e3fee2ccd320cd408fdca0fa7fb, + 0x100fe28b46e80f15e12ef4d5759fddd560f76bf74cee6051f23ab10c8803f474, + 0x2dd0aad73d277f8bc1c76d2133bd8c8a8ba8bbd573bdfc1adce1380345bf233d, + 0x1ca5603c3bd89198d450960c8bef433ae368efe4be568d1f8f63418bc67ba269, + 0x1eb4203b299398722feb50f86e2131f870ab2fee6f726876b9a213a69c8b34c5, + 0x20d3eac3a69ed9d9963de0a1d4b554ce0b5e350033c7aab8742fd258af31392c, + 0x38ba0b5c2b7c3d41293047fb42ed9df347056965c4d73994fd38e0b3d0c3c74, + 0x226c68b53ad316f22f8aa803a90ffb02c489364fcb807ab2a6dae085a2c548e4, + 0x1159ad22fb4656dab10da606d298a856831454bfb237a222fa393a997dada332, + 0x22d898f074eadbe133b38174e7629a3fa47f8c92e8e67f62130a00fa7502b956, + 0xe118395fc451a7aa4612da12097c4372c92f7b978f5af092a4771e09a13343c, + 0x5b91237560989a738bbcf80a2175422656dd27e0f5f96741d141fd19392e462, + 0x1bb3f133c2d5f7930a9decd0caf63f17c5528844db26efc336e5101f1868545c, + 0xa39ee8089241c5cbd69954994abee040ccf43b9510d54a05056194912963bfe, + 0x11d1a72d9666be10fe5fef74e6e06431532f5157ee24ada70683b9f0a586b585, + 0x2a0872f23949f213b46b463ad828919ebe034950429f91fa3bffb275d722b47c, + 0x1da2741d74cfe7a159666231eb9981749a40bde5cea6f1a069dea57cf460ed45, + 0x225046f36d161704c26a8c378e2fa58859a2808f94d5242cdc3c742c530f60be, + 0x2ac5e790d78a3b19e40fb98b247ed9caf78b47d884da4bbd70359482c2f4ac84, + 0x2a9febeb411787c59c6b8e51108aef6d9dc63aa97cb314907602d5f6b702175b, + 0x10519bf4b5d77f8397a4e51ad3dedf5b0dee2b25e08cb5b866eeb2a891e0a6b2, + 0x21e9add284054cb149e67ec3fc4208b9e0f8a8c2011ab17bfb3c4e4419ee700f, + 0x861419b33d1a9e2a944bd86a22a03490fc560a6e3f3922410b1f4ceadbf2fce, + 0x204bee088f716345187c1c25fcfad33eef88a8be606b0441139f03be3d39de21, + 0x21a8509dc07b690f149ace959540eee40d485db5a21e3a2ce9dbe808f621c92f, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x2bcc9e799065b89040280d6bfa90d9b0f98ac91d5051d683c4dc19c6d078592e, + 0x2a2af9ccc8cd9b8976ec203de687836e6025e0197a9e756a094168da234c6255, + 0x22cda8a2057a524f13ec0bfd8cf44482691536cecc3218c934ca7f21126903d4, + 0x195abafa1531518d101c427496305c52e3d2c9e5f7192207f23985a15a85b384, + 0x226c92973e2bf06e8800bce486d3b5c5b086e9717d93b79e4084a9a3cbf41dc8, + 0x2d4b19bdffed4790eba5957e4545ccc65ffdc300d945b11fead52f83825cbbd7, + 0x20c83290d5ef608ecbd330a998cde98936060e1fb520652c9d6eb1a57558f91a, + 0x2baadcb57bf46a22bf299c393d1537bf2d612cfdc70413af5e5d8261f87dd73b, + 0xf09875c2570527eb866d31f96e357946cf01307d89962db0c6f16a02097d08d, + 0x2a29246703689c0d7c52136c2b548245b34bd6b6c341ed99c340e114b856e0fc, + 0x2f05d7232622eba1583bf831f6a810ea116f0fd933e142650c58d6af1bcb66c3, + 0x1afe5d1e1b64e7741039d6c26a054b7300ecb7d052d89e8df8ce8f1fdb5289e7, + 0x1925f2484e57a2cf13139ddeddfdc2b9235640c4e40e7332d1d632c724801f88, + 0x7752556340dcd48531bcb144583ec742cf7539c9ac2347363f9636ea060f39e, + 0x43c28a9d6f38ca50f057fa71bb6f07c62295fca2197e056160e93a6c82fc15a, + 0x417aaa17f575f42328eaa4ba22be7207ffe9d26564b42a24b41967f3e3173bd, + 0xe6da876303fbed7ee756fd87a8f3e1636325532adf26bff8910198c92e0caf5, + 0x27fa572643a35732cda21571d390600f9188739764febb8ddaf9c01bca807ff5, + 0x1a510cee95e7b6f4efdba5612e8c5121c1ce9cca1a376d8379a1fdc206a55fc8, + 0x14424c4b3e51ffba1869ff6527ce3ae53dc13cc1ea19ccb5c8792ca6be287753, + 0x21a57d8854d6cae5d0818d294fcd9e1a2dc71691a2e3f9b227fc7889cb72182e, + 0x225cb50db0b73b20058ef3f671fdbd2c0877a0defb8392630a01ceefda042d16, + 0x58641892ea470cfc83e363c5b880eb8263212533f8ba6728527c4636f3e0113, + 0x1f4505746ce4f65004b43f9f0017d2602e1bd44ee569e08fdf832d91531cc2a1, + 0x2a076d8186db2528d94fa47dc41721629bcc2fe83eeedfc433c20e8cf4c3efce, + 0x1dec0d6f62e19a1d2ab02d6c4d6a6d7a1dd1387a4a1fb15edc8622e1a3def5, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x2a48253491abad4561b2ca9cd08cc1ce7ae0335240facfa6efb4fc653a48efa4, + 0xcfd514f09e0699217166e20a7eda9b00512b6146af51fc1776dd6980588083a, + 0x1937a11923000d95131baf310078bfeb84b99a77e027e8d0d96201b918132ee9, + 0x303cfb90a228509ecf58fc6e94dcfa0860d206b34b28a8368a3559a57add1cdf, + 0x28930e4b9ec17c58ffa7934c216ab1af55df309d115d0789233f84f2c441a535, + 0x18aabdce0da91d3b644bd5ecaf154ab7148f3c3326cb01b593f8af9efcad0728, + 0x391f2ddcc9bd6fac600eb0c26e0b1a9a27571629e9b00f080d876ee2f1b648, + 0x1d765c20a588ab7217fdda5e01dcccde23dcf9a9cccec4d8f424735f39e25f3b, + 0xd914d807b0fda1cdd76d1955f170ab3616a35ce53516a81e315825f93165905, + 0x22492619b16183d3180c15994c2508c83737ae2a42d968dac85af30392294e7d, + 0x11b3baf3833cd4a6039f2bd42af1633a47f240fb88a7f0ac0902fae2a5be3510, + 0x207c403b77244c8018d8845714e68566216fbfc49acd0107c55ebb88e0de3949, + 0x2c9e431e04871524a5262b21286d04333dedb393a078f2fed92266ac22fefa6a, + 0x1fd093032821a7772421e62b4e3c23a195d27ea4798f9a3f5a6c7d4d2db583e6, + 0x2eaa82b7fd1c061940c2a77bdd2fb653842bf1b0466696b292cd304b490752eb, + 0xf98f710e410dc1552fb69cc85076b89b4fde8f27428a30b58219f52e422d130, + 0x12229b56730ba20a6a52d21bf8f7312696e8cf6537f1f6c50bfdcaaa4ed4a7ed, + 0x1c2fb95b64a0f66b65d9060f1f065bb82ef882af760419aabdc6cd3529431e7d, + 0x2f2fce632964228eef7908478c90107a5dde45af647f2323ad8a612e41c48154, + 0x61849aba4451458f718c3be3f76a38347e512cf422d1f907a82da750dc21478, + 0x2cd60c32d6ee36c374016bd4f1c0b273ff87315f6bfe1dc9a81fa0ecb1264599, + 0xc3e897a8b91c108ad19b152e9842cfb87c4af0aec8dc950e0fa325ed4d69ab, + 0x7a38f888ba67b2150b0e6431ce02408681d2ec80c8daca4c51e65b59d329fff, + 0x1af524a87fddafaad82b5231a1e75e8076c66c44d3b527a259a15422870db619, + 0x1159290a4743365d781e01a0d6bc626832260b07df2d0f288d15c95272eb1f9c, + 0x9e51cd15182d20f87b09cf6966f9268578c3d9cc58b3e7f981f67502f9478e2, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0xb0bceee45e31b08c0548711d59c548f51b7d1a80ccefe6599b5dbad0db4b738, + 0x241c6fed92ae4e391bafe3af5103035f9fc1f727a6dc8ee5f61ba9b1e3eadb9f, + 0x26aefffc4043b22cedde88f2bce76faf6fb3c21b4eda9d682c14dba06fb9e87a, + 0x2673296dd62cd736659080d030b98914f6f799752403ba5c29bf9af6afccc8f1, + 0x22ca97c4de769662b071f7cd75657c15e9cb20d744edd0a7911d78b6a4aaabe8, + 0x188fa74b7eda792dc3660885901c82d57050e74b09a12b5f346d34e1e5f67614, + 0xea0166cc4c51c2252e4f3dc92fcf33a03964a03050f9f125b87a7fe074dfea6, + 0x2134da7fb4f089a21363011b08fb72aaa8fe767c618bdf08d7b87810d5fdb594, + 0x2be62c9234dc7d3db66ac72c758b15628df1cdb781c90d0f2f23de2a29005105, + 0x282ae8812d729f2eff86f2ec478a65707c4b63d33443bf6d8f872569c40e442b, + 0x189e7984fa57098dd737293a19d6f60971ea7c74fec600b4e6fa20cc314f015b, + 0x1e20cd3dbf4a75643421e4fa713f5ceaa35ed0197150182f653ae9663a9e45c3, + 0x23bd66cfdc54f92e0d532ff413a2e2ff3cf6f561a344463e5e0a0a8c5a010304, + 0x42657182ee4b72e3e4408528c19b71ccf1d4f5f38acb0e5a5efd641cdfc6b7f, + 0xa11abc1daf1ff8ed6afb6b0a6370bd55fbbe7507f1da568f39b2ab9dbb6e340, + 0x200edeab8b94daf3135eb6046388ccf8c7140d91873d2fef04b9c60f509c7de7, + 0x58546b9e80b2dc22250fe5c53d66aa14be31d5d92b5c04a05e3525810fc78a8, + 0x1670b9e07e02e88814eb40a43d83bdc010739e9ad6799c10bba24e1f40b8afd1, + 0x1bf39f979c015af4af119c137d5c8a334ed0bd0d7f89626d4f79ef4793b91324, + 0xe19dcdf5b4a1ae01fcb6c6579db3fb615bf176d53e6ad047ccf905861acd584, + 0x28f22053f72ea545761afc9557c84b05c6f736ebe7bfd2c8c5c044d09bbd4d4, + 0x56e7854a96d6bffb29945d76b51fb9e81f5f19ad767171c568b742e926054c9, + 0x2aecacf169f418d8f47472db625ac3bdb5403667c61457666d4238bbf39d6638, + 0x15b04e62d4167a166f14364bed196d1d0e49c8ccde5bd560e261600dda4d3c3f, + 0x15f88c4b31508718af67c6e3c30cf3cf594fbf481a837e80e89156d9c2d1be74, + 0x14e6645c7627e744f9e6140679c863325d1d95e1e4786e573a498b0a790b431, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x1afd97fac1f6e77c5cfe4bce848b93051a26a3b7d3d6b18dda048863a013cce4, + 0xdf68cfb65503007db81044af06d38ce63fda1f569a7057f1848ee4597d87c01, + 0x1086b32477529f9476fa324d6d9552bbab58956c2e2095548dd1bb20e9be078, + 0x1611046b126acf5767561c32d31a36c5070d645bdf08684240a72b9832c3bf2a, + 0x1bf3eb5fbf1e5bbde992521837a8d3a15a187921832989b4d357a1b2ced9b36d, + 0x799a349b10cdde87ae631ad3959d6f9664ce23ee91e010679ddcc6017ef120e, + 0xc55d0ca35aa0d453acbdd8993d05b479e13fce555b634fc6d3e470035b0de8, + 0x20444c1bf67d6ce8afb0a20e79d6b691bac54bcb31ce4182b1579ee21ea9fc8a, + 0x22e8f59cbb4f92639cf517fd119eb650704b00e6eb3f58e92eb31e713c1b91aa, + 0x1b4841aeb035b2e896d64b59b47873cb9c74cd05ba12436e9d1865a4a74e8be7, + 0x133d49d56c7809b942db891b424b30d56ca44ee7f73aa028a5e577e82f509968, + 0x698faf29f83281d3fd421c78ebe694cf5eb371e29a09354741c59f4a4abc6ae, + 0x9cf68b95e1a447226a8c39440513f965a41fff89a1e1618c70ae4be00e92c66, + 0x57a0141a7ba203881e5a90e6d422e6d9001eac737fd9860344191026c5fe545, + 0x1b71aca0b352c5ee4eb06dea7f4202fa1b908f08e2be55dc0834a1a873607597, + 0x142915304bb01cec99a22a96d1af31c3133829bea002ae98d7011fa1516160d2, + 0x4aad51b11363b30a26aef78b4af431dd8bd65dececfcd1a6673d8f96a0e6c16, + 0xb63c18b78503b6a47a88f4d54c4da7a9c23fe346de39a8884224a2a85a9511a, + 0xfe10d1f3c9b406bfb832e85b8a844c5c4dac7398f2dc3ce2541dfa71260d259, + 0x2a42420809746917645806d70631564f61103186f9cc644df5b7b0ee4e6a27d5, + 0x5a66c6f50d393da791e5768de874774d066f0874118f0f417b6a036a657dcb9, + 0x21a4d71862dccb7c0a0a9b80945c5be92307f147f29917684378111cdbe9d2fd, + 0x46f855f83e16426aed3c81f5a2f7f92bec7ceb71e3dc7e2453514c1081ca202, + 0x185eb4c67d4f479827980a96827cdb79988cdf8d31c2f8d2532765f4155cbef7, + 0x2a4294d3919b5debce649b27b63f40e5406b2f044e1d41d58411bc00719d3e7c, + 0x2a802da0e4d59259bbaa7dc3227ea2d725f6cce50332661f0837cfb87af4af94, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x154eb8f04d175057207d617931b51ba18ec3c830e1afa755e8ade5bfa71c1d44, + 0x1c5fbb238cd09b4ad76154a2fadb7e7d732bd534603ff3cbbee8031cdde7b994, + 0x1c3a7fe14c3ef7f03426643cca0e6faad2806f9dee971ba41c0103d42f4f116a, + 0x928a9730b25d647c4563b4a7273307c94c347565eee36c781c3b8adc53973f3, + 0x2aefe39f4fea948261cdbe0accc5c7ccff6714fd741fbdcd6e298249560dd97a, + 0x1feadf4aecbf7c7f1f526d0ab1ae1513f1b4fc8731187f9b65713377c9062037, + 0xcd2f2d4d826d98ce3bf08da02ad5866f34c9b43f2068da4e5b33378d93c4c24, + 0x2e7b56a6409134126d411b560967c46ddf3a46fa47dec457fb82a070bd448b05, + 0x23ee37d1d1e1f8a3b10680bdcabcb89268a4958051e8230d14a0605af857d190, + 0x1a910c02479a6795981001f40273c702cfbdcc1c00fd03de1f8057bf2809873a, + 0x2786abcea27c34cf4ff274769e51787932001c0640033a7c89914f44bca3297f, + 0xb27d402fc69e2f23ef8e60420a38e429da969f038cfceedb073e12f28a5a260, + 0x5c8f462872ea76897742babd1099b0aca77864a1b165eaeb8dcbb3fbfb95286, + 0xd29130c3cd0ab2358ab1683597256a2f7ee611376b9329b8aed30f69505bda1, + 0x167beb74665c1a02b90450914870d4480472b6b2bd22563750afafe3de5fef8f, + 0x2574275c7bc58879004d63dd307638b057eb9bf99388ad4788659f957ef5623, + 0x1bafe22329c00fceba1e48c5f61bdc519b20eb352e183859b2434eba6cbfc4f, + 0x40f25fb048f262d0b88e5a557234c4f35ab898d104cb2eb960905e1e8ba5a80, + 0x2fc7cf259a1474e83243039afef87ae87f1a07bd433405084e3e4241c413aecf, + 0x30144980af35b582d434cab99e08835bb09644dad47fbe036aefd9b19b713ae1, + 0x140f2ab47ba1a08e4ff8c38a8245b79fc20c2916fc3470e4eaeb0b3654b4a6d8, + 0x97cb1acd89b5b12e82e14571e4a4ef516f5c2693f0bf70d4c05cd4efc72dd9f, + 0x30435adf792ba5a8a2c9fb599c91a1de531c7fa809f3fc364761e8e68f3c99de, + 0x17acbbffacec919a115cdc4c303f9335febbb1dad12f0a1825fd41359ef73491, + 0x45ac0782c8edd00c6d7c0eb594b799de598bf538c80f467fb7a4eb1f6b01d85, + 0x1e15d1be8d2281c6f25efc56b33d72bfb59a61bd91518a3de93caf2a357d0256, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x125b96c678d2ef181f7e4bfbb795150eedb5b46a913d6571d1b204790a2c7b0f, + 0x130be605c83bc01c1fa0e64c79ee75b27d4b4efd892368f66959cebd8ef1d79e, + 0x3051c6918396878ef98b13b7c484c6695a093ad607bfdcd87f01b79d420e731d, + 0x2635445a3f66389b4638ebb81a36f4ceb210d5fc5466209ec215c08023aca95f, + 0x10bce0fbd3a8796152759cc25f72601dcd99b699a8c34686e43fd2b6d1b27d89, + 0x17dae8299eebde0062043e9e93267fd1b38d6f0bcde5827c10822b137e4bbca4, + 0x2664e95646ec5ed0536a1ae2ffc84165b5a3c295c21e58606c95037ab746a878, + 0x2b8b53c8e90382786b60fa50994f281866ace7a311a40af07b633f3c30fc7776, + 0x16ae53f5d4c63a81f4fd487793eaf5cd2cb03e3c8236be7ccab8c20372f911f8, + 0x127dad336628ad2bc403718c4983c136f34cbfafdf3e45c616af7c7e1ca8793d, + 0x10a10801dfd21422b4f5a264c2eff2121e0f716512a9dde5e6371eab17e6e7f8, + 0xac6189eec8ef4ce3928d7756fac44685b425ce64bee3d4852698709e769f45d, + 0x6f49e55c72efdc84f7ff6306157d770310b1c4e6e509ba3919b9466bdede393, + 0xad1247adf1e4bc8665343425bee4d3f35429c54d6bf4a8ec3b16dfdd1dd3a45, + 0x9f989c92995f86daf29a92cfeeadce5f105a0ae272b2253bb2de3758a771c26, + 0x1fef396daa237f6467f62441a55b75cb5a09fa94cb1fdb270ac309487fa682be, + 0x130d74deb88099e35362801333bf7fae8abf96165fae4b8179579761ae1de1d4, + 0x1b1e63b7d8b5f8d9612dc59e1aa9422f962761a992079a8e8bfc91695ca204bf, + 0x2d5d5c8feaed5dec95fb9d6674066c03d6cbd0d584084827214b09553adddbd3, + 0x2278a2b596a3d0af0a9365f954adbdd2c8a1514cc906369d3b0402811c952a48, + 0x11291006cc6718940fff0378cb6cefa09db4b7b7c84d447ab132a7a47573babb, + 0x1e0bf04d48d54e8cbe871bcdbfe619ed38fe69bf9d2a61fb5def330b2d7f4078, + 0x2b0907cd35c62152c10e47e930dca88d4b12c5afa7e2836c2637ae73500b765e, + 0x2e5051c91020bf6c73339f653843436ce182cfd487c02a16578cfc96d27c31cf, + 0x1227e0c86ab02adcaf01cfc56cffc815efeab33ece8c164c31bba50b28477b13, + 0x103b328f8e9fef02f340e3f679d91d9508bb1eed21d98d569a41583aab595707, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x1e3d52642e16240dd7e2b0ee21cf4b3b4cc10c805fe52009dc7520457180945c, + 0x1fde6f3b98df6104d07b84a703494892d8fd21cce53cfe9ea41c4ac6e5125269, + 0x6934a63e04749754a1980371301caa1bc00ce38505933b1ed0e085a5755856e, + 0x2897d663791c69c9bfe9b313759be1cea16299e667c3acb3e9f18079d39209b4, + 0x2f30ba6752d0900a64be8d6be8b718eda67cf96af95a1e0dc91e720dde3eca49, + 0x219898fe3438a5e5bdc5a79611084e0977456513586fde2b23b5e8e34d7eb7dc, + 0xd90f0afc59b011d2949f998d7c5e4c2a53953aef58f971a458704fd88f6a27f, + 0xf21f3710b4f641ddfdfcbb67d13f845216ed16a0f1c0b450acb82e81c85a93d, + 0x2eb036baa89d926515281aba071798e7397122fb51f4504e07b6acccbaa17af5, + 0x1adb3f0ad3c7e2300c717a6674e22ffa2611978d8c29e3d21012fbe7606ade6, + 0x11e1d1fe7ad3865581a1a8930698e676212b04c64773601034223475f91a7b69, + 0x14648747b8bb5b1e8b433222a964b95c4e143f70d6b26e6aa620e1c57c842ed6, + 0x14558bf2daf718b30756ccb88e3890ec47f25b4b5e087cf9d47f33423e97a902, + 0x2e6d0bac325dda6331e2117c682066a1be931e8b6bf889e5aa8f716bc14358b, + 0x1bbe690c183e54f281bfb4bd843afb3961bd3e428c81dcfdaeb8220a3858736d, + 0x23528de8742f3238128e65c88122a5e74f26fb2c1162fdba69f65f7d971d52c0, + 0x13e395afe32392f6fd5c4c5c728eae324d9c247649a6c3412475c4d04c6b0ea7, + 0x1ff38b45c4e5b8682a7357723d20949f7b792ec55dfca74c72dcb53fe68c92fe, + 0x245ded3dbd6c3db094bc040def9c4e8a96e67498f9923224388fcbb441109dfb, + 0x1f6ec4aeaf3545dbe65de9602ff4a22c48911ca6647bcc632c857ffc99a42d99, + 0x2431b237299f1a5e8ef22569cf8db020247dd0e7a298716462106e5519d3fdfb, + 0x2e4939b015f27fdc938f5f1ca55e5d7e912045ecbdcffedeefcf37ac77ddbe5a, + 0x26c061cde477c7011c04505b0126eff13fa555d248df1968878956209d36e031, + 0x1c6f21300d13f52bed69b2aeb3dba9760a94ed945673e3283848cfa5c4555c44, + 0xaecfdb86a64315429605fd463ed664f224d10b2e0a32d35d3a5acab914655b4, + 0x25a11f201fcfa64aede18e05fb19be93cfb4c15587759d5e5110420a267a44b7, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x133fbbd86858b9143bcc298a4d783e5b8b4ffc4290d1d61e87d1ce5fa4f9856a, + 0x2cf3bb0c00e204f18bbac1f7f093b9febf2ca7542f44072be70cd915d2c43b53, + 0x13c1a4bbd3a938e8d0399ff791d86962d7ef1504597419c2c00f421d4459c55e, + 0x1b008db98dcf53332b67c287841ed73838203b2d8598187413c17308bd8cbe30, + 0x1e42bc2844c8f32ca38ba9a1d029c7250d75a237eadd2d40969ed5674ff88fab, + 0x5e9909d9b2a8645974d54fd3ce3e734fc0b99236a2a590e6fc564fa00c806d2, + 0x1e26282b7dbf93f3aab257ba1e13eaac39ab22fc81b7252c079a192c113ed7f4, + 0x102a6b3d3a90d1f67e639a27e76023612e096c02df65bf64110ba239361e35e9, + 0x1f8d425b3b39db5096f4897d43838bb2cc77b4ed0f1d99a7208fdb45faa3b3d7, + 0x3d122f74d869433e1457806b82f38cd91103972e456ced5ca9fbc375497ca3c, + 0x17943c0d333da5d18d0856b442553e882c75af5684f2a8127a9d52123b350c43, + 0x1cf484412484df0cb49e3916db14d6bed50eee93dfdfdd081480da21b5388ce1, + 0x3e41d466271e7fc632ee7e0acd2c4c446957175ebebf55463ef9e16f48bb9f5, + 0x2abd2c1f5f2ee158080419092b91d64876bb73f9aa94d20824e06448278f88c6, + 0x1e979043b35e1d57826c8f7192a1866ce1b287772cb266eddbd177b3c6186d8e, + 0xbdad4e92dc796512c4daf27a755b5c5dc6c666084c648c4bbff65ff662c667c, + 0x305dfb6283eebb8f5bef8a33e0dad282ca92ba895e85853d210c7cc82f56aedb, + 0x273238f0bf3b029f5064ad1beb0129b9539edf1ab828a4d113fa7652f12fd273, + 0x14b12b9068950f98de141ba4b38cddb1e398b0093d7e118651d518a7980cf6e8, + 0x3015c78de17c6ccb86e47c1ef08680b12b948b5a56da8a371e6e2e0147c42f51, + 0x1989f7bfdc360a572379c14223f75aebdf04254a589c9a9aea6d80e020e13a21, + 0x2a65e0ea8cc0ea69c631c16bd174828cc79e80143a51c35a8dcddc6a36e7e717, + 0x718f6894c8d87898d8db2c9e3fe7e924b9e31221235f56a11d91c64e4d65fac, + 0x26fcf8cceb403f4ba44219c27d6e595b794f4fa99db88133fe1a031cfd32b498, + 0x78d5c5f6e5f3e7bc47044a82bab78a85279d741c5f9d5c8f3522d34da3d8b99, + 0x8f0b5ea35e699ebc6443284da3218e73f20e8c7eefa51962ed8f0706db54bdd, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0xfb6c5b68b5bf3fc0bf849c18e813e610eee228716ce01fad6f05e005802d35c, + 0xc602aae4b39cd1a84195fc795b9f4650d45b791afe4368689339630feffbc6, + 0x110455540d38fc9c7ae7fece8bcfeda5602ca72823a8162cc4edf21ff54867bd, + 0xb380e9795f1ae5eef24029c17d3c2f1b77f2dfd1de38d84e4c95a344070ec48, + 0x2ecac08767288364ad3ab00f106c9d45fe106b02e624bdbf2bda3f92739ff03e, + 0x1743f85f877aa121f1a8ebde66a3ced16e0e2c61cfea1f89f8f050d872929332, + 0x4d0cbd1d1dd0a87474e35d15e860233328e67057c1398d9921f930db1c32b97, + 0x2d22b693ec70adb123adb300d69ae39ccdfe6873afbe66fbfed0fd1170f0e49c, + 0xfc8ea8eec07829ad468e18f804cb685425a7f56702c78bf3ef9ce424d2ff611, + 0xf4aa2f3aad32e709a407a80affce97c751d6d188b6c9ed4dd13bffe6ecdee76, + 0x5374852d2261dadf1e1404368b67bf8377399ab2a4371ac71ec0c6ec525150c, + 0x496f544992e33a4f0c52c8406887623656aad3f25ef8feb0f485903e94a2260, + 0x18a9a16e6ed044b20459820025be1a938747b97db166552581a0372127a75ef9, + 0xa2f1c011a921def0baeecda662d0cd96c5d54efccc20897ff67bc18e6359636, + 0x22aec007a72e506f9b0708c0dcadd6a95a61bdde90849d9fa0f7d6ca4900252d, + 0x12f1607ee6f4c110aaa5575fe992f47e024df0955ab3a985ff5797c7447db36c, + 0x8a0e21aebd5298400802ad68a96d644378b580aed9c46cb70bc39408bb5d961, + 0x77214bdfbecbffecf5bf823ee5dce410483c9af4906d7e5e3a6966e446924c0, + 0xd8a51d698768c1f62ff879f0e478e98f1157ffc88ccc234f8322449689ac79d, + 0x2ca7d5473e3a7a69e048db0b7eaf1cbe2d15bd97dd62c088cc222af396daf89b, + 0x1db504c331d3895a78674b2f685fcab2081482fb20b16843abd4c34f91e754c2, + 0x226760b82659919d5795bb171b21f92fdf931045381c5f341d772a6018d78f27, + 0x2c6ee4af1e71f1f46a56943cd1a40ae76de4db5447ce6603eae52581f81b35cd, + 0x18f11a6b7218237066ddf0f730b11e52404b6418028f591d2b03dde94bf407d8, + 0x1c726bc6da34803fc45168badccfbd6d0e90838303b5256be9f3e29ff5f6b2a7, + 0x230da928c59a36907165396cc12f5155e3358dbb891941e3a70d239183132785, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0xa6958be4b971b6fb712329b991d9c28ff15be0c1eae89cdd4610ce27a2c7c12, + 0x18fb79983ed105bbab4fffc7c6c532808676e702d5d4deeb82ac9bf3ae9118c9, + 0x2cf2b459fd8fbeea84fe88a081b89db2e7b502d94d149126f6a532831e31764e, + 0x24879d31eb0e13c6968d486a3bb01ebafbfe6fb47a67f3634d1294334d834e5, + 0xb2103302dbc0c7c6c86efa0fc45ccff544cf89e07377b37bd81b2e8453d953b, + 0x2e2e1fc4c5443e2ee84483bb71d753ac2c70e0993cb280e0d6f6e420763fb7fe, + 0x1a9e105d58a6f8fca7fb505e6240b2fa3f7d84d1bdf1dc5d60baed683049b488, + 0x2a1042ce88edc0b73ef4c2c44c12d6d9ca419b2f8144c4af86ed8df0379f02e4, + 0xda87077919cafe94aba4f234b6fb078f93704bb4155e9a8d55f4c7c8b887529, + 0x10df86ad83b48800b7b66fec0843926e7d958f1f69e0c2ce3305a5aad0d6b8ba, + 0x5ca67cbd464f830c5633b84cf3d172f88acb852692358e4bed0a5b69fa194e7, + 0x6f1f54b5acc18eb09f7ac569c51177a0248e9e8e9da408cda7f06826cf19cad, + 0xedcfcb405af9c2132a3992aed66c0d945d01ef726888c65a260f3c56f208b2d, + 0x3009525f3f6c8641daa9fce108036bee7bd265e758ad202810cd526101201528, + 0x943a87f4b786f072e9637b5b58e280b0ef10cf747cf13729fd4edcb5c09d76e, + 0x2fcfcd4647f625c42f4c129dc9d782771c761134be63d3140279960e6b5e3223, + 0x12afa4b24ee867bc58bc57d2e55195215bdfc1f29d541b09bf8f1311d8dcdb7a, + 0x27721fde56e70f248964e39185a35af7c38e46d8f86a160b508fd63b623489b0, + 0x2bc75c98655a355c8ef7d48b0db3654bb2c579f0fdccdcee9cf277f2af834077, + 0x1f49b0d6af4bba3a9d89764eb3fc5a63da95b559607ae0df206034450e40195f, + 0x1ca12480c0ab186896c01ecc28e0a41014814b9a28de45fa0b79b90a7cc8cf9, + 0x1040b4f3bbeedbd2ffafba407c214cdd8abd6555cb54d590f2edea7145d9a48b, + 0x131f9b70a247303bf84112dacde19a9b953f26e7274279dc974b643314f51d61, + 0x102a78fe962133773dcdc7e30a00f87fcf3a3ef135fe4f01f9a9517b572e0379, + 0x1389adcc893fb4478e38b3f3477b8c23c41382aa0bffed4b8a54f8c87ccc6285, + 0x59eb07efee98970dd36e2857a183c43d6ee9560b3c90fe54515a5dbe55621b, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x2ff7ccae4b6aed16c52d5cd2b2be44d66968914941d91a3c9c4d38d5c76ff881, + 0x27404d8154cb43997a5d6576fa461096c9ac1d885a17188bb9d7417803697661, + 0x41f16639e3d600cb3859f701e46e5e38b88927dc20e429030894d0d2bfa5f07, + 0x280cbce70a5f719bdf3096cecac201b2c79693c13f01d40af06b7dae353685a9, + 0xaeba2eab11f80d6527144cb8f13afaf2ec9cb4c55ef424bd00e2ac6f09cbbcf, + 0x11473e38a5168c35404178e0c40b35a7b2e49584246518c521375af70e99e194, + 0xdb9935eab2a555400c37dcf884cb2ccf1226c4d931ad3167493ff0a272fada4, + 0xd9a481cfa6ef0c5c441c790cb8c9b30e2be0adfd2723ea5c1cf0b962dc7a40b, + 0x2e8fefe6bb8a391222b65341bd25b01b02ce0d88b65a496a9c59abaf25ca0b5d, + 0x19dad0c5b078ac863acab028bede54e6c1f5d8f4b8c8172176ccfb53740bb10b, + 0x1dcdd9fbaeea72955e6752f92205e88e094fc5aa4e9b75fa0e173e0425a95e28, + 0x125eb35ed67f035219169de7f612c1bb3eb788e3740b9054ec89352aab2e506, + 0x1f64f0f4b2802abd8f6ec78b6a061bd3345ddd898998ab9160a12ba55f997760, + 0x1fb921d2f30b13504d31f42d0cbc3b3e83714a37353246e6426f2a8da6d26c3d, + 0x241438f09da43d99917952c9f600d47a3f30b79b5ec80924f4427326d284abae, + 0x2ca504ece10e731645d09ebe52614c3e0fe99679b4e210297887f45f99f055d, + 0xef909466b00c00c4d39e13ce788fce28c32eb73e1e4575f396110cd78c690ca, + 0x28aa2ad31f21f32f1b898fd025f6a9d34abd75cbcf29694cc35178717db80d69, + 0x2e7e619b01a79ef24869bb8a57f0c1668ace7d7b721e253167ad661f279f67be, + 0x10925878a22951d216c53068b9e2b8d2a2d4c235ee483963c68e75b246392d9a, + 0x25bf71cbaa22e93f533d72118b04e187d20eaf3c07c96b86a857e4435e870c2d, + 0x2c12c98fe7f663cc207ffb753b9c099ddc0de2d774771a7c84fdb379fbadb65b, + 0x2879d4cfc6efd84feb0d05d1546968f98e11c38374db3f72b753412d2cf2e3f9, + 0x213c205c362aa0d41804809efa5f53a93c4c26ac9d1e91ecd081922fae6346ef, + 0x1a65b2fcd5d9c0db8dad898a002a9c11ec40412378c107a8aa0ff70d7416d3aa, + 0xd6ad0b286a355b4026058b97cc6a952a6ca1ae3ae23641e81bcb757831405f6, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x13b5aadba85b01644fae9e2e542b8ebd5003686bc751399421a798a1ffac6d84, + 0x207a44c8e2044f2f2e6953c2bf4568e8abd69824f301cca26972266e0e18577c, + 0x20366c61e53dc8718125d04f64ff70881d22e856a3f4d9224cf8633143a9555f, + 0x7dd546b57abb0a5f0fc753b8a97526ef3417b06a79f30e5a2f2833d205bd29b, + 0xbb6251b7bbceeedb0b366e3fb117676d1a31802d373e10117cb07c8ef4abac3, + 0xc19b0d2fc9236505c7c7b6a4b1bea3f91f56b56d2d4d6b0dda2b6e0f428777e, + 0x3238596803492252af333365adde8b43ba1ea6722b0bef2d89eb8b215e7a568, + 0x119c3970cc386d6f0e39d351d0d1f308c857c3547373173d673b72c5d555fc96, + 0x13574c0b39382b249280ca5e86593852ad435417157fcc4a7d7af23b1425bf3, + 0x2c41dfb547330e3cd1ab36dcd14b2b65f6db6bff0cf3fc858d7b4555e1ad2c87, + 0x151ac386d35911a265199613ddf17d28ccad77333887120cd6ec04b1ae5d7844, + 0x2142f184dad54cfab54f49734a6dc8e858cdea2a2039dfdd261319fbd8ed1396, + 0x232960591ef4ac647c6f02bd38cd0b4e0f26293eb1bbe703603714676de7e4ef, + 0x2d33e28f33c118eaa8c9a50322e0796a657acca1822b9caa8368199501a577d9, + 0x12da53680185973a1018f3c8ebda54b5fdbd196a2b192f27dd4e13bda2530a6c, + 0x2cea06b27f51acf0607fc354f64c2c3687f86bcf5616dbe9e56385ed5f7246f1, + 0x12ae9658e5e33252bbc1761824ec8131cddd4f006d354f1dcbd17c6133fd84ea, + 0x1500265313eafa13e4db72b664aa06998f7d0f08603f3b59a2d4109263c8668d, + 0x121cb82b95c9461189b38b4f9d1535debbe5e49954ed684767d191d8ffd5d613, + 0x2792672831f5282bcdb13cb16e9049386e09bc11a74c1b34c2ae3a52a3d69dca, + 0x9c49e3fde0a20b1aaa8e0cfea69eb95377ad867be9df04c11fa23e9e559ca3d, + 0x2b2ef2807d34d975db74f912e385f76efedd545addecb765209f531b82c957df, + 0x7a76c4304adb61e8611d9356708e26b98920a0a3fc54bf7e8341e9e189e365b, + 0x1175aab1e1215106386e7d6ab6e8c8ab11898648556d135e9d779d932bd654e6, + 0x95881e72157a04b0e21686523efcc318cd810a2d31afa2c20a49bfa3ceca7da, + 0x1bc2595f9eb575721f2cc048180d6a1dfd39b2c9432c4288b896ff27338a0c15, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x2d72542a02d6093f229924f57769054f0c9f2341187cfcb456b25f659cca62ff, + 0x2a00d2a68a415131906040f416d85a4293bfe098ef6c6cad01deb413ede2cec8, + 0x1cb01e5cd271049bb0325eb6957d2e04fe46c4f43b88948edd3b0faea5b69528, + 0x2e83b677673216f321facbd90699c9f22c2e2629191c76f7ef99b51449c8f763, + 0x2575e049e33d2f09c8ced4d3f663f7721007dccad5ef54af1bf0503a545d78c0, + 0x27885d131c5352064f2b1dfd7eccc9c1eb563d86f3d11a4901a4ced089dd2537, + 0xbe09ca0f50c25da57ac348af3c0c51483babda2e62b2c3b55d00f1eab40c7c3, + 0x20ea980b40600cbe365168750117a9d40e156e1e7633ff512573544ee7be34cf, + 0x3f0218ea64202e828409a7c012c47419edcf7ff1c2902792c117fe42756ef64, + 0xe6a42b289d3df7f5355f32dcf2a507735a0b4e6b4ad2ec1dbe976187f62eadf, + 0x224853c3ca29c4fa226d98c4e2497e21000225c6a0e0902b3d801d8522606b2f, + 0xc5295480691ee73d8098e95570a794cff16c70ce743bb8a42dd627715648416, + 0x148645a642117f6c5870fe24306f9b0401ffa1da04908e1aa0f6b9423986badb, + 0xbe448a3f7e892d80d18a4f34e16919f8547536c517b49ca457fc4ec9162a334, + 0x2bc573630f948a668f64606f9128f8f0105c11b08a9dce89aff3b02a00f0a5c8, + 0x2519650010b2b9642414e33338b47f1d33ce4976d19f1fabf8298db70deca1ee, + 0x2825ddb803da718800beef69a8630fc7f3b58206f06c008c9876772d5227736f, + 0x2f2c24da651d81f403fdb4dce59e64a2a6bf17e83f562426a52b79ab5e7401cb, + 0x3bfdef37744dd23f5ac9e47fde12035773eb7a1c666890f3d8115a0c0f1749a, + 0x2df9d9e9d2c54cc87d0cacacc229d561566b56b0cd00a68b31dc706e3f06351b, + 0x14c29bac822f6d9d454c11d35520dea723fd79b06110c8135e178536120a0b8f, + 0x8b6fe4157191851acee98ca63208dda32c9bf73c833dd1caf158e992847a5a, + 0x25a3dfe68d7513c1a26bcda26c412412a2f7ae80cfda7afbf996bc81cfbccc54, + 0x2d3c0299af854fc8e64fde3e0ed04c3bc54292273adb103f74bf623e889691d2, + 0x8cc27272e1668638fe3f85e5ec76f5ee1595328112a949263afc8d1406d3e48, + 0x2aeb2bd0a8da3fcb57f5b428f850f41790fa68f5b54b506794af4db04a30a1d2, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x11ef04a3823d72d4a7e073114b2e6791e38b5b6aed376228ac4a20b2eea244d3, + 0x101022055653fcd3d2659d6a42694578ebd518b5738e6cc884192e1091f58878, + 0x180f05913fdc0f67f5074c976b3ce2137afcd1c1b2940eb951b8de723397d036, + 0x29ecb8a00aff8bb64fe2df4221cc57bb0cd6eb6b002eef1f735b0231a72c7e91, + 0x16156078057591db5810dade70d6c21de3a782d5fa3143211da32ed8f22c0e8c, + 0x29af8f09441dc2c0e1344abf63fd38ba7f08490f435fca75a26390b4e59b9ba1, + 0x24d8bef242f5ea95cd238844e9134d9519d6682b7448d40bc9f1ed8920eb49bb, + 0x2b76b5027eafdd7a6a3902665416cb07e713952521c74857cec4a829375fcba0, + 0x293dcd5247e1143980134b15f9efbdcad3e7700b6effaa97e17339745e004a5f, + 0x2ac6a13e798388a97a5d9b856f8fa5aee5036fd0422f9444749f3b8c4b9e884d, + 0x1f5dc64952b9c1bb892ddae76de8212aa15c49508cb760a4f579d608c665eb68, + 0xeb5587c5c438db178f2725efc1b739d53d261f52cc4340f6488a8242b74913d, + 0x2f58f77c4c03e9591ab2cc38567d41272c1dcca473cc4bcdd0a4783d2b07bcda, + 0x1c908cf8e41976b7d63c3f59cdddcf83cab22433870351c60e4bea21aaf373cf, + 0x23581184440c2ce0f3acbd6ef778e504f6162f1930e06688417c82d85a83e9dd, + 0x2fca62a378c65e6d2a0b3b6d89489e8ea6bf5d95cf27f40b16c58a15f05e0ee9, + 0x2390511812e8b21ad50a44d1eaad9690f187541f7ffb8a0ff44e35ce3b2733c7, + 0x24660a052455c262cfb78be90a43345338dbd808c422e880eed6b19a76a42d9e, + 0xdb011c8a8f6df9cc0163eec3eba51b230837db2013659415ffb24b3958cf107, + 0x1bdd458fa2cd40ad49ba12709f1bd117ba67639f7b52a7732c56b98e6df5b2f8, + 0x21fd3e66b238769774a650e1159c04c47ea364a48157df08d90d4eb53974c15, + 0x7556eebb12fbeed954d3e9dc4d5da1ffadd578d4ccaf273acdcc0635edc98aa, + 0x200a1f0fa4e71fb1aa1c9b45949185769e97d29d11caf13185fab33fab36e09c, + 0x1795336032f18e1f4e392b03b65bc3dd268813b2f9bebbec00548a18ba37900f, + 0xb3d2d7ddc758d320c61ee6ea8137f08d2f31f3d159bc918b0fae895c42fedbc, + 0x2bf1a39486382c117a286a19ab96d73bdaa9c9b45096518f69491f157df85c0e, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x22dc5c692d9baea0fa2685d2c25fc510a43bafde0315da1c52c108124bd40b0f, + 0x1c9a763950a409e9363997de4e3beaa0944b0f1feb3d917238409584e9c8fb68, + 0x15761f0591d99bc354aa0bc4a11153cfb0b5335993e4e600d4da4ed88fb33199, + 0x19374736f4b0ebf7dd3aecf4e7cbb669a53b4dfba1ddd4b951769ee44c51edc0, + 0x1616bc37e489b1559a3e813544f2d3f6c05a33dd8a39c644e0179aeebc274cc8, + 0x2fbed52ea54d56a8aae40a2f16262b5cab2bee4e964f32acba16067841ef5edf, + 0x1ee85a9999931500883944493baf240eb51de8e8015fabdcb9ea68797bb03696, + 0x2b78ea79b23365607e821a947bb4ba8035f28820f1ddddf1caba7edae1eb2919, + 0xe84e11e29a4b9ac41c2e953f61cc86d33254120f426e217d2e5727424cdd81d, + 0x2f28c96987a9aeea275da5f6bd86a15986784da79796f308fe96d7b28bc3b2f4, + 0x2c14cf8c8c895efacd96c501d5461df5c2f9494911100a4c1baa5b40f8751ae7, + 0xd311aba1168e2352b438015bd49b31d9f5ca1e8460801bbe65ebf019776ce17, + 0x2d1ff9afaca2339c66e640fde96fdbe0e586e71d79e76d145acdd126066c119f, + 0x1c5ec2267db567e8d5f1880899e3add17e7ee0c611605320bf32fa2d3b1842d1, + 0x202908d4f1a4ebead7acbd09fcecf10a8fe557435ecf51e30834bf136827a83, + 0x188d37c6825523715475a10e21e432d21a8f921b32665cdaa6dc91d31913d982, + 0xd976b5ddbc8409fb64b65e1c5f458bd058ff8d789386fdd595eef3a064eabc8, + 0x19268d14b34ccccd93947b6ec6455b6dbaeeda1ca9cba82f33d6e4e682066db6, + 0x68d38aec68f918213eeb15a3d5e65b3a3a4ff930b59b733e34b0b295f6db1b0, + 0x24cf117219d823994d2210d2bc2b60585cbf6d667eaffbc726c2b68a3fe466f0, + 0x122577912131a547f85c741fffc4d5aa5f6e45453119a63c3004f64651e821c7, + 0x1996ff6a6f3dafad0245a77ba200d39de3371ca2be5264952657ac703241d4fb, + 0x1c84f6cd3c3b1d091534dff90e04f0675e6c6e60aa660c3dc4366eaab3ddfd33, + 0x11f23290442ae048c2622f3be83e52ab302660bc6df31171f26bd42a5f356fe7, + 0x2311bcb36c72d2a3f8b103c39583be307ab91a5b020252f7c8015e1c9ae7e56c, + 0x125707cf76963d6475a5dc5c1f832166070dad40eaab70cd31b51e83ccadbcfc, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0xb4b8a05506a055387dd95d95f3c91bf6a1da689ded43e1f548f703649486988, + 0x1d0c6ac842eccd47045e4ddb34e04c1938f9e93aa78b5fe2c0f44b00c6131ae6, + 0x8eae224067879f0830f967241ed0821f41b0e20f9cd8a6121f07aac10e30cc8, + 0x73f79694b751847664cd5da30f38013f2a52fc2530a56f01a10901cef975cdc, + 0x1294381efbe257c11ce6136df76cae6caa4ca5ec1934f1a7f5d4895e97391a5f, + 0xc80e686ab09da319588f7c17b27db8dc60981c0feb8b2dd58be98ff6b3f553c, + 0x28b442efb75aa8e6b0d277ac13613d59b09959b3a1e90b457f7d93fa7bae6766, + 0x302904181cdfa19f33aa2838f6ba83cf0202f22054856155d5c10a0d5970042c, + 0x2b17dcbf694b6ee011663776b422100989f2576d78504227d547db889adc4dc9, + 0xb89fd0b5f5fcb94a3fc154664390d7dbc7a8f028db060b7a594f205eb554de6, + 0x29643b0ab6cd148bffeb6bad54e34bf13cca00ea98c538d900e949f8a223d1c0, + 0x25ac40e12ff5d3ab47779044da20a35fd1ec747e7f9804f951d3e3994f0be643, + 0x22b19dae475254f480d6ff651654f808e6c99cf54186094f5a4fcb3d9c992524, + 0x1c5591a266c5ac14f1c83848bbe3f9bc926c83b4a19031af0334da64ebcc0f57, + 0x22dfd894770188e65c40390d7ef1a907800ab916118530a0c1b736c885a42643, + 0x3ce73087e6cf15f4c0c9e94c05b1490f58f2cc4ad3fc746bbace3ee6134f65f, + 0x2d391381bc0ec52a224a9add14af01b875b9ffd69dc115e348c1d6c3c743ce29, + 0x1561f352a096cb328906c091a612b9ab92a4433f5d65f4f55e78b02c4f84414b, + 0x25de146f3cc4f32b6cf8694fdd876a1c9f0269e89d63d48a8ae9ca064ab2ae64, + 0xf410294c8d91a9bcc60d25f4c73a4797913a27067d1f664771da8d1284a77e9, + 0x11a522b6b25687e258df304954bb84ceb1aaa9d977ba292ef1ba49c652b033d5, + 0xd061366179c02608f06b6984ad53a5adc8b1effc60275817e79e7eb031f5dd1, + 0x14b4604d095f37b5974254e48d7dbccb68da55306e08d00fbbb8f06bebf15f8b, + 0x2f0d5f558fd4454b062fa33f1e52c5a6559ac1379ae507aab152104f511eb53b, + 0x11b307ffd788170d196853547920b916d6a6fb63a15d4cab5452e215f62674c2, + 0x2c4b021e2b757863b41bced2e1aa5be7e77c152e396026fbaa09cea515001c35, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x32fbae1fe345271632403da8c2a96a35805c2a3e87c4457c8a251137bcde383, + 0x197360c47371eb2f8266e052762cbf42283dd8c4ff1446213c1c11752c6c30d1, + 0x213ae97ea4c10ec4a64720db8810df370ce3e9d8492f6806e06c871f0dcc4ba0, + 0x23ea027e72e70e5db4ef89316ef3a127454fa082bd84b255763878395ce18af3, + 0x1a522fc99812fc6ade296385a9f64cefbabdc59b664d33b02cb1c805465e0bac, + 0x282bdd7da996a1d58ccd9e4797e17d6a30224531f3d773b48ef23daa5077298b, + 0x278f051ff5a35ad9a0f1e5ce9a99c9e1b669f58b127b174b1573e76b9a95cb66, + 0x14d2d438ddd5fd9756f4afe9649c2ff2c9ddaf2e6d1ad10b8dc4550862f7424c, + 0x18dbca4af7f465ad6968bc7a1837c03d10d09a94f03c3e7fd3f2767e86be7b9f, + 0xb2f4c4bb0ad8c2047f62d2e6b1024da131588d16986b03e63e8ce9ede6c7fe0, + 0x21316797b3870762390b31a48e8b33b319da5dab6cd4a0c28170eeea58f782, + 0x6b3f86ee68e72580f8949c7ce7e789b629efeecb5e71a64d17cb1e8f4b57211, + 0x21a36423378fe8ddd4d3ac4a6ded8b65b8ba023593a99758ab917ca0b67a324a, + 0x1ff68d97b4ee71f22110b03e7e9f14641d8e98513a9b70c9e1eff000fd537006, + 0x2e0d1aad3b8bf21314fd506d418cd7f78887789585a28aaed747cdacf7765b7f, + 0x148bd4a9f6dcf19bbda66f4531eb4e876443c729ece0612fc005dd89c808efa4, + 0xc11decd7766f5601e8d5dc09960399e2a441254b57aa25bb3bb80724a8510d5, + 0x653950fb31c1384207cb5f22e6adbe9392e0fd3b6fbbc9eb25f4064656e5b7, + 0x61c7be518e2a7e7d9ff8af58dcacfcb3f0499cf7c35ed13929affaf57c95818, + 0x632546dddba57da93cb55ae4fd8dd0065ec22c94686a63cafb6b151d94fefa3, + 0x1458d6428e6cbba4df84a44ba6aad2a9cb0d1c9041283c1ec5277b2990418750, + 0x1c58296b3da9f61460610a21dff1ba812b726a9011f0180e4f457874f7d8b8fa, + 0x11b039dcb0af8c795298f360dc7f55aca201c35487b1b81cf009fefc204bdcc3, + 0x1fcdbcfd2065473d499a075bf5857bacba94563f2814577e5705a020211dd0e6, + 0x2d9f02a658742633b88fe4185dc29bc4297d7aa9dd473740183ae46042dfb040, + 0x100e915a9be179a7cb25c2332a3d48481deec2ed9196214a55d765309cbc8af5, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x1a618c68dba0afe90df2de9e4aa3091ae73582b53555822bc903932747e520b7, + 0x2cc1683d5312031d06b89710f03b3889066006177c574ce3cadb093e7ff5a301, + 0x16e6197f7c10ac35b2432c0ca10249b3b39a8e3eb83d702482ffdd8a0888fe09, + 0x221e4bff156c6a15260b4c5651064fbe3b3cf8f10721e87ee9f72e7021759490, + 0x17ce9f46591fb9ea7e5794a6fa66b1434fec12507de6e8fbc1e4472d27109b28, + 0x22fce270c4b0961c89d92325c52c85141461e0994e04132d632ee19d9c51e556, + 0x15cfedfe30848fa55432b62e7791109698a457ecd5469ecaeddb9f083f66590f, + 0x3343e9088cfc374b61b75ad600de6236aacc4769e5ee8b9aec9f07bd0969f51, + 0x233d73ed21179810ccace1227dc72f2f8c80ddb446861d6e833a29c4084d44b7, + 0x20c8fd20ca1ef20c39e6c99478f2bde9c46dbbc0afa8c840ed93cb153fbc0be3, + 0x696b187d4df08aaa80aaf272d12f72352f6be2e67568dc45b9b22df83b4c672, + 0x26242eaea95d43830574a5378f27299753c7907135c9350cc0afa30c1873c429, + 0x2db7e74c58283b55cf6be1fe422fb2f2523020e04549b7cb88815694bdc078ca, + 0x1c3db6fc9f3fab8d9e62d048cb1a820bea78c43a71f202f779b8996a1559d821, + 0x14eaa8042ada3a2a7d247d46b7cc0138b9fd124674823942d207c7c6a330d395, + 0x7de2b61b5d7796c55c6c9cf4808569d61c78671f7484453d201d29cbe419aa4, + 0x1db38a0c262bf63e0aa7929777ac0914eda83aab24aa47d84e60ac4ff18bfc4d, + 0x2f2c6dc0cbcc26d091d95038e04a2886fbe8f4b368a738beeb995255fff09df9, + 0xcc224d62b63572de577993e48205d0a7f574cf32add5cbe518e55163cf540c7, + 0xf301c14380b822e1f0319cd575d63e603ec8666f361b500d1d6c28494c309a6, + 0x2e5cbdd4c1599557d596522efbd078c8e2f9deca7503fa533ea5230b622e7a9c, + 0x2b7b5611c6e8b5f05fe9fd010bda63b3d6bec1a90dd4e4d95da40bb720503d53, + 0xac828155aa6627ebf486d5491bac13c32b61cecb4d3178cd4701369c2740155, + 0x1946be8c11cae21fdd176eafd23fd635352031a5df260edc493c820fe05b00c3, + 0x19f2dfcfbf6dfb65a8051d60ccc08795e63fa53e3a4acf89b85259e6f85f0030, + 0xfe752a9169dff4e402c76a809563f0d83c6e26d9ed3ab2a3b0e4070ee7baa4e, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x275833d56c1035de1383b7eb6759e6971286af950f5b5b98ceb2a2a9fc52f45b, + 0x2c02e7a87debeb5cacd4f9c776b5999b8216f0621e87720a8f672ffd3051198f, + 0x3a6f6d6dbbd957561e33bff1e7f97ce1b8bcbb97e5e363a58810cef7ee91851, + 0x116fa8d34d5c67d290555db1263b34d2bb0ce83a89a81c5a0bd4110976efda34, + 0x1e81d2d2d04f5cc16db99fdb340df3e85d75e9c305b541d2d933f8b808b6e075, + 0x284898f56dcde9b85983aabb51a7324472955b62538c8c6fbe554080a871497c, + 0x1ff3a909f501d15420e9efb7f8071c0f4c55649d5e0f81a4de0fe31bc4e694a9, + 0x47be1a9fcf3bc7845474b57d44fb1218bde905cfa1da8c052a9614280bd9cdc, + 0x2a3787a31e5611ca3856cc840fad2b0a07bbfb4172859fa6fe527b7e0d5b35d9, + 0x2eb3bf4b3a98c7da655259991393cf7b87eb9f4908c475f00facfc5572c885b2, + 0x26aa5f863ce3498db1f5b71c96457cf97232cff235365a2a1091b6a85fc94d6d, + 0x19a6bc7f148d056a10ed1610f5f9b22a827ba85e51144c0414400ff4d2e91edf, + 0x196f5c78726e289ecfca7a2d2f6f2a5e82f51df54cd54d4ced1627b9e7f30a72, + 0x1118c048d3dead019a262810944ef9fe5fa017f472d5cbe8d27b7ffd2041db4d, + 0x4c7b810ff3f0ded46f2d4cf346e22e402a529d4793314a3bc85f963a6bb428, + 0x2e843295db044df4ab207a6c7aae26693f37a5e5765663f22c6809e22fa0ed24, + 0x17cbf9e9e90196672fcf0d0530c0a02ddf4879954bccd82f75bfefb4833842e8, + 0x27ea08561c8d05998b53f428166ca0a25ceccde43a9ca8bd275b4f7c537eee18, + 0x3491984564105af9bbe74e7d14e96eea58d73c39727a8ae616bdccb8a2451f8, + 0x287011118b922300780d5ba09878c898c662b7d5bcc838fdd8750170b643eeaf, + 0x19af1b66a5d2c6e5a4c34856b37a5a2aa1992546461d6cb65190f74d731e7b82, + 0x438f8d1a68e04ded124f370274324e9db5b35c0114b3d5e19fbea7d867e1b5c, + 0x1b7df25e02c2d88bafb19b2f9725a3ddac024746f30b4b0232518d3d4b8e9f1c, + 0x2fca63f9577b3f88ce614fdf17473f7d033bd30f104931fac24fb3878cbbe2bc, + 0x1a782b1c4732869014b1ef8926206360460ee6e9b7541f5eb0bea1a0ef184db4, + 0x16bcba1157829125674fa67f49a62a3da742c2639c62cab43c92362c29c8c186, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0xfaa456a4f334a6d64ec7443330027c0f6fdc3d0232029ec5e0b7299ea372295, + 0x21ae168025d871601564cb94712b6fd70efc57a75bd794f96e09556ac9fa499f, + 0x2659b387d06b87d28b97c58326d60f8a8e9e20956925cb774f4fb99cb0fc7bf2, + 0x6ecd6537384d3f96bcfd794a53b1cb3d4ac7574d23c753e20185ac05641a510, + 0x2c47b359757b6aadaf39168580ca135268ee4030f857e83079409db9f61a7a88, + 0x2e3c4551ba4ea1bd2f3bb46f4b411ca86accc38c54777867e6b6de8b6381e60f, + 0x1aaa42d6777c0cccdf6dd9c4628cfb4f9091c8c4e19b218d13c5ce8d41b02747, + 0x101d7175ecd398cf6b5e339400ed17866953ffde1fd49caf2327ae39ea805e2e, + 0x47aac02ad51c60e7b013d7e76e0219a33395d4103c62d76426b97fb8a720bdb, + 0x2159734df6ba0ebfcbdb4412f5e985870f836d55eac7278057bdb5fa002139a6, + 0x12c80a7f80bc5789e17e76a5323cc6e879e26b2eec7f70adc14e91a679d715fc, + 0xb37ff835c21aa08cf5e82063ef6dec2dfeddcc987e7fe222a78bc9827c797ad, + 0x136a6d023c29c33b1812073bf0cf9fb61603ad40ddeb3cadf8f202598cb3f7db, + 0xbdbf9722d2aed63d0059307617c47ac2688d9d01a8bb20f4a61b95252dd7b32, + 0x1d90c4f4c52e4c8157ec6ecb3fe1a70937ac8c365100935c3ec4c359137d468d, + 0x25d8cfba9177d817bfe2db087ca7ff74f3a4ef92986c6e5cfdea5703affac237, + 0x30562348197f23b21238c777e3d7f366cc9e69e796cb218281b210ac3f1a142, + 0x2e6b5b67a5f7449b426e3fd32efe3df98af0bfad5006d6370b574b40c645c1e0, + 0x60c72ab89831fbcfd1084cd3dc94aa8f69794540671bee622d6837d41add442, + 0x949047c842cce9e422d779c80fa13ecf5aca5859086ae9c3759cd3b02d7476b, + 0x8c9031e3f9fcc8fef60f82e8026db19bdbb5113c77a4c06fa4af3dd7bdaeb45, + 0x2850905ce0c275e427478ffb5bf44685dd95cf1f57056bc19108d6c85c3e7cd2, + 0xc76f19ff9f52168d20cb4f0cc0d10bce93d28b3acd6d479ea38b8a96f944455, + 0xb66fa2f9d2feda710dca114c22cabeaf616c70ed2bb793a7eaa328ea1ca3c99, + 0x6198754cf90bc048b64a8e925c41c9298890c946aba20953090e05e55e768ca, + 0xc637cab8864b9bff868591c6bd14424892702a1d3e654037d0625b258126c6b, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x21325a5b2ae982ee23a4c911b190b63005919d1ace55a101818397c73be72f7a, + 0x48d6872b84e860e934e439b065e7a162d5705b576d4fc14c47535d9e08bec23, + 0xde725e2f88af9c238e880d725e71d8a1d79c4be4421fd9529cbda976462ed81, + 0x27eb4b06d352a3404e16264a0fb08537ddcac2add0782481c2e7735d7ef1803, + 0x1b47254e3cdd4412e01829f03e74fbfcaf9f882b745358294012761106a0955a, + 0x1b4332f4bc0f47d8728dac5d12fe99070a53ab0ed1462c6add9ba42c2323f755, + 0x218d22d5f13b09ace89e377cd7e02d3b52b74a1285072d62540842686f728ae5, + 0x68ad6997a9ced270daca95813e82527f7e6a4d5cc4911c7e0fdde7a1a062d03, + 0x67a187bc1e0d1740ebc7f7343397b235ce0034bd6f6fdbe43fc50394edd65cd, + 0x26d27d9b4d504feb1adc50f40bc7171e56e9cc7b17086d68ac09bd337ab9a756, + 0x6e901afc5dc879d75ef7d324c7b7c8cb8772f7948829dbd2293ab032a9ce962, + 0x14c8e19997ea7bb4131f9765ed587425a2fe5f91aa4f4c918201e74110bc7526, + 0x273abe5cd98541349618c993b7192c978fb02fc236bd40dc3a4a4f61dbce96fc, + 0x715d346135f3b13f84a62b794f2d00bc19cab24d35d168d1f95429d8856e296, + 0x2b9bcfa6deb252ccf6a2550e198f21b5fe0800fd3af70329500481a1f472f174, + 0x239f7dc3817df74d0e93174b1564fbdb7e4010b69b32ad0618a169748e496c9c, + 0x21978d48e2d9c7b097fd4d0cb72c238855c33bc79834ef7b08405b1b6a25b3f6, + 0x269c70c27b7564c9d24a631fd3604d4238528e20b010912916e2c1927df5b950, + 0x2c583dc96a0a9dc9f9efaac1de85327f007597a5e812fd564df9e490b5dd8f68, + 0x121e4187606e3b3382106069e0d56de26dddd453c81d009647a9cb5f48418094, + 0xbeeab0c615c4acfb17eb9f8dd647bf03917e1169c9c38d0f397c10e9dad80ee, + 0x1e07049aefd34f62eb9b702cdd93e84e4f5bc2bf88ac583ee4c8f7f358638c3b, + 0x59c6422f0c9d34dc813948bfdbd3d525a5050122abaa725261b21794a4bb03f, + 0xada60827cce301bb3aba3c0dbc1a32d14cf5723ab4a85abd48baa37b85b318a, + 0x10370b82fad9fa38906fc9afd3d2103760b279a5a79803039ac6d7b47fbfb080, + 0x22b53d470c374ee90f3477d1bb36a57a7cd3e39305dbf4895d1a38df65828962, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x121bac144ebf731b7e106308001501b5aba39256622dc16b6832959ef32d6a8d, + 0x2ce538366c9cee7a91c93252cb96b7c42b4e4b26a6be57c1e5448524e5acf376, + 0xe1eb214d4443a823686062d4f44fbecbe3cac0513ec37dc6969a24a5c2f34ea, + 0x2b10f3aa519015cb9f2d8e03efc3e54d82cdaa8825760f40856158eea75583de, + 0x13dcdc97aaf8d23d666426b008a02be78565ea485fc5b3175f2a36d3c6589a4a, + 0x1e179f5a8d8cf761188a1af7f3aabfd0c6586a3ba2da4ac2e609406494d8b04d, + 0x26350c1076435ab7615ef9103dbd8224d3780d72055c5bf265bd8f5bc459c5cd, + 0x2569aad1663fbf0c512be5d7549b856f5058b8d9254ba788ab4b67f957703dd6, + 0x21d296071bb18ffc608d41b9284b25f99e896f90b73c4b6ebc6c7e845dd2756b, + 0x3403ad2e4edbad53108b19db3580bbeb575989bf763939ace10bf3ac11ac946, + 0x2e87a068e7e10cd0a27806e4eb87fc4a909b75602e7ef4d9b49732d30f8f68b2, + 0xfecb01322ccd429e5afeee9ec8f3888c528252874e09ee6c82110bc67e1133d, + 0x21b1a2e21480c8623fbf9fec55cda799a152e941e99d0d6426d24666ecd9a7ed, + 0x10787afe51951f551c5ea3de6eecc8c08adae2debcf2c0add7a578db5db669a, + 0x129a75842ce7f380f4adce069972a00aa0550841e41ad2f46d1665177576f052, + 0x33844a0d5987a19e66c014e83db7c903b6aa7baff5cae3ec6f2e7f9870a7102, + 0x2af0d00127c68081dd29a5c0858f6bb0d20d0e8c8c1fa50d0d539436a66b4950, + 0x2452bc4a8de2db1f282d2d8063ab568d11cf00ddd0ccfb165523b0e7199b4278, + 0x7053595c4f99205b79bf985336e456422650f494c2f79670c0d34257ec689f1, + 0x1bad1a52d292401b1a8335df15429443cd8dc8c5e856e185b8c5f9d0c9bd2a24, + 0x24635b7d3ad41a5bc44a3a17d80a7818355ff8f18379004e5344a7b1713a31b7, + 0x2e7876129f03a5f90702ccaaa35e3d3c2709756360421113997cfdfb1ed927be, + 0x1f6028d50d8a7ee644320cef9612807c7ef8fe40223751dbf8f791ac516fa897, + 0x771c9d46f602c613a689a8334d46e0e5cd1d214a4831ebbc53525ab2d80e5bc, + 0x269f052ff6df5ae60f76c891df96d8e4a23e80371c82349ef960088ef64b141e, + 0x2961710040a2b2d6ac5101cb03a28f3bc2fe649baa6efc5100592077f15de362, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x10740ce6766bd5d45ef53a0b79f688c0c9a075938902c676cefec8a82c3da53b, + 0x27f3dbcb60ac79ca5eeba26c3971c64600543857b0d7a6019b292df5d6084e02, + 0x21093160140db2a25e4a17cc7600123cee22ba57790926c04610b8c95f1fd186, + 0x891be8d562bb6feb60c7571f367d6048c3b083b2adb097a27e62e336cb27a47, + 0x2ffb17d674958fcb7a8da2d38554bc5571c6efebc77e89514688212c68d50a1f, + 0x94c68828cd769c940b27f645dba1922d26898c64fef55d5638fd6e1d357b75, + 0xd55cbcf35eb4b2a41cab995bd1b90571e4a87677a90e62793f6073343e798f0, + 0x18e91bc3e095f9b687fe66cfdbbf8c234c27af317f13fc27707d271e871e7061, + 0xec0612f29bc32d89f73f7f0926fe0b3f3587dd7eed49c772b3aef2c5d41019, + 0xccf5311099aecc81a34b567999eb4c663d907a8bf4b22c2f2ab63a324ac3451, + 0x183ffbe622900edf9b6a8021ab80db00676f619dbc1732dcc8fad67128772d26, + 0x8f4331aefe28fb6f009e17ff632db3505b18ffaa61c6b0d341fe0b6387ce2bf, + 0x9eb7f33498704db8dff1c8777ff539d1ded2bd207fae4bb7465c375b8747161, + 0xa531199830d7120018b3039c7afa9a084d529d930f865c38fadcdc40bb008e5, + 0x194b3cf28d7b62413f9b837b687bbb4804733c8e174e76bed846f92068c066f1, + 0x1b8604e1486a35ebe8e6b900127d0dbb54dc8aaca97a4eb0c8956773035f3ef6, + 0x9b8de36766da341c7e0b810a53903be22879912b707e1f3f752e6f079ade75c, + 0x1a435eb920d2b84fe3c0b803ca2cf85a6721d31f21778706d4a87a923ad0ac35, + 0x2566d9e893c2afd892f4702accbcbb979c7cceb980d234de549a3c6c34bdaf59, + 0x18df8272b0340557ca8fa98dc6e75c6d788484702d389f13fb82bb09dd5edb19, + 0x20b183f7293c68cc2324f01a2693d3edacf0c28691685520cb6c1ff79f25bb29, + 0x128c7a2624a1bc92093ebab7ea53e0d5d53b059e21004b19cb0d2bb3dba74f31, + 0x40287c11b5a3f980d59ec06db46c6fa3b54e9d4fe0f474ca15a7aad1ad0ec1, + 0x21d7fa42bc56b52d557e34b091518d6a694595207a099c718b87b6f216ffcd7f, + 0x169dc2796511017c3e4ebefbe57d6f93194a77513fda84ef7457afbada8a5d58, + 0x1d74ad732a1dc804b9584e557a9c18c0b497200e0d27312bd2432691470566cc, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x2aca8e251964d1a3261f98ec83cb17d611d17f5758aeb8b34a8121121f7eec67, + 0x12e284f43dd76a9f1751d11335d43514ef963ffdf2036171cdfd4f47c99eb5b3, + 0x5071e18392facabeab0a39fea36c393572e98073e18330d9c4c7e654572065e, + 0x260d7455c8470a5ca5cb7a63c39b0d1fcca3eb1029d2994c5f2c19a39086eae7, + 0x1cf8584e37677b19fb7a05446448d550fe72a4fc79c92e93e7576f101dd05099, + 0x2d19dba2b7658adf60d8840e9c7b115fc37503198335c9050470ca3c098cafce, + 0xd98ea1ad72116cea32da96c74565bdb292b6f62671c5cc9de0904e1ac8a3918, + 0x24ac021320aa1f1addee655d4feaf537e470915474a285ab11b80fd166a20cf0, + 0x216feb63069f6947beb294a1c7240b202d132ae945f7cb81368a2c79223d1131, + 0x20ecca83ee5156e6092763d78973859dab5cbf438b6782f4d4727f07e7951bb, + 0x1e632a42fc326036c1f3313f372803cf8912d762b3026cb4b868ffbec464da38, + 0x2e652d54941af14d90b4347529d6e8734e184f48c5827373e35e96a0441d56b1, + 0x251ff531befaaafc6933e195e6327a853e70f7956ea16f99bae74ce703e13eee, + 0x12ac47acb9b712578207e429b989e017e010e2f8e513e5fdca0d5d70cf69cfa2, + 0xcccf17e0d61b8413ac667303d31b27e5bbdbe2de4fb79272fd26a96a6033c00, + 0x20f2060a29ea58ae11aed61e371eeaedf8c49f7d2d310a20daa4b08742a9c195, + 0x1cb9f0d68dd3c14610ff690400ac156b0f88ddb3496842a82976bec878c1fcd0, + 0x1e75fd54061e8660fb82a6f24ca385580d37c17fc731ecb67aae86ddcbd2c363, + 0x2d29ebc4f807741c6975700aac34dd02857b9ca3f389a34d281aee269e9509da, + 0x1871cf71711f4036a0104f07506e2211c40ed44327c7e19acbc2400345eb7bbf, + 0x630b7ea40ac6a040959e71933395a414a78ef993f03d2306233b0aaffe4a814, + 0x1ea87ac112d60f22961d5b2da26c0a06bd4dc1e73788a388ca3bee772cc78e7f, + 0x26a7a6c245da9cf530f87c9b20ed86af369087bde004bb6dc3eee8b32882c7cf, + 0x1adf5a028ce2b8a0787eca43ebcf427dce7bb7b3ac19fe0a8c0b7016afb25e6c, + 0x5e2e3348c9fb090e628aa40101db8b4f46b6adfc7d31fa82e1f6c9fe5b55a1d, + 0x81d87bc2e14f185b9c19f4cec48fa501d99c70a2bc881ccd6ec4f6e677721aa, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x2a7ab507906adcb6522c043a1b2cb2f221e5470822f048220ba731b3933f3212, + 0x1e0791ec0c83cd1f3a0007ff027dd589fb0866c6257c181d293cfb70b62abe59, + 0x19ad62da7c5d8766ef927edd0f7fbd997d0e6c6555a6c38fdbee7f5299b26d8c, + 0x1cf518d282e00b1894f86c42ccaa292dd208bd0d3576ecd1cb1c45d426f660cc, + 0x86e5c668f2c7540e65a379bb9738416e1f43e0b41619cdc040c321aa89db7c7, + 0x2bcd694a683fb621601f2a5f0f900f6bab1f4291d65bb8c26537029484b38496, + 0x2b6f0a65bade0adb23efce9c6e3629a07cefca2718b3949029362c6da4baebaa, + 0x12b25f49fb1cd92da7fe1fdfdbcf0ab1d715ee92ae7e2c0b2a60b8f4106abbfd, + 0x797c7a863ba81aa2acc620e089ac0afe2f713e46fe4d52ccc637953a4ac2f02, + 0x113166107727b2ccd9e2bde6285860c912a318ff3cbe1cca006973f444238f17, + 0x29d8beab8a793123bdb47e3bd56d6e0d6e4c9d957b38d6ac7ca7d53a30fdc94c, + 0x68f99bd269ec2bcca30a5c05afd5136feb63a3315e05dadb2acad3caad1c7b0, + 0x1d8a2e95f5012b9744d33e3db84253261797fadda47ae08eebd349753511d342, + 0x26a6dfcbfcd2a98fa147bd0b18f3e4f66e1f1a329a168e3a61336e4da3bb8f80, + 0x1d5bdb15bbcfd215d8caa665e9687c2d8add0b51cf54c5226ed9b89866f767c5, + 0x2bea457b568fc29ac1a23ff4322caed5463a9cd648769e8a1a118aae84df1309, + 0x1dbe7419ee59dd580a0ab4305440a57fb651830f979f8d21656ff28b1590ce4d, + 0x17ab1d55da8ff17391ba874c4b6e52c77dfd316a0cd9566d1e28c5dc9308d309, + 0x4a3a0d0f9e1b091bdd336acd117c4ede9d64621c6b2ea4f07726e065f17e2cb, + 0x2634ad4e91d1f63da6e2534c1161abec660d92371ed85e8f0e39aa91523b9e60, + 0x1afec968060a10697a3889bf3456a23a4e98c3781d0ee88e29334b14cf7614c1, + 0x23a5fd23ec8919d62176ff3954f983577d5ea821cee695387f096c7fbb93808f, + 0x283039c47dab36071299505922ebc21482295f95632d17c49fb8f07e382641ff, + 0x1a0084bc1b3e951aeb3dc6388708f8ebb52247527a393209664d43a1812e13, + 0x16fdfa540f269b40f27696610cac06faa7eba7d87542dfa42d28d3f453a70622, + 0x638bad28fc8427c2349d2930b08631be095bf0c03572131f3a8132f38f4c0a8, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x2b960b4aa6bdb5968fd27106ed926399bf40c9ef7a0abce38158191156d94b47, + 0x21ee2ffd320737215ba399d91f5287b56286e5f286441b29e7f4950f2a108d82, + 0x1a912af8a3a82ac944bc34390ad7af703d1e4a8f32996ea0eca203709bd526c4, + 0x1e2d77fe49d12a919d8ee0b0bdc15475f9d3d5dda831b098a921ef8547542ab2, + 0x1e461b0bfa65838c31b66e8973fd153308af46e6563e523b4c97bad304ce6bce, + 0x1222b1bba586c324581ddde55054315ea378754416b7b74406a44d90468839d3, + 0x231cb90d301a6e6e3f6c47a07a3f262f14370bda5a9844a4c128076b5fdde8ac, + 0xe3e66e543fb59290a8d57f5fda43c4b74b235e00adf1e1440859d8f252fde19, + 0x1bcae3acb52de61f2f907f6fc16c142016e053640c8ad9b4e3baecff97b2c13d, + 0x2a2e7e286f90e3554ac96ed8f80267a3bd9f747d787fb2533bb98f465931f724, + 0x1729e7b06ac26c624dc5c6cc6d761f94d93875ca170cd57f87cff909e922223d, + 0x9565b3ec6e63401bcd15d12f12d8c805ec5c8936c2223ca4dd510a57afb12c1, + 0x1ade0fa28ee13df4d382a505b3893baf5b4568bcce7121b5d48d29567da13a9e, + 0x2301dc6a1236420c051aaf16a095e77aa88f23f63cb30b410a323ba77f21f7f0, + 0x158c6a01fb01f542f7dd93ddf2ba1771d726cfaa7c39ba5260a5f6bbbce3b9de, + 0x2757b9eec4cb27d4e4274cca6e00289f2d12e987465c267b1fa104b02932a84b, + 0x3043d8b0cdac25b084aeab7475766326ccfd15758870a4b47a8783f73f5e4f36, + 0x1a1739fefe6488c79c6c32818ff62a65afdefb9dc62a23bcb3d46428cae5cd88, + 0x56f91cf9e2444d0d477c13c994388d88a2d8e1b88d6080b5a415a53117643ca, + 0x28c8f42ca93036c7226451ee7ae0c1a7b87b0c560de7b11350dc7f74e4ae51e6, + 0x18dcb540315a43872fc246fe3f6779a237c61ef5527e87a400b24b3eda058469, + 0x1ba374f70de60473f60fb7452d42c59f4748debdd345afdcf94d09305b601a3d, + 0x1b40af6c2e106fd4756b548837d64bcf6dbfb9d9380e1a70e010769efc2281ba, + 0x2578f4a6e3dbbf2ccc5e1837b4038327925cffd00f96e8d2fdac677f2b0faa3d, + 0x2ea53ec4f2f8900d39df68853f2ae9e969819d33bbe6ab9686e1185c37933660, + 0x1cb7cd707a851d764b7c3d2da544afa59cb87f6ae19971eef7f403342c205aea, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x6bd8c397b1e2d8e3b0d32ef2594a311d49a259567ae4c635582de9cd15689bf, + 0x291adb6944892dabcf5217145ff77361815e58600ea6248b0c0069802557ddad, + 0x96477873e56e5691171631e4eb74c7d2f9b2806b4f0e45508220739587a890e, + 0x1ff4f6ed8be43e079ad849d03ff3147fd6b1fc0db8c1b8477d65c096d4b25a48, + 0x9e5e4056e55464d9d5e6ecdf7127667de411a716e88014861d5436cffeabcb7, + 0xa73b0495d174fe15185e4bc010a545402736752585288200ea5922c5f8d29a6, + 0x108e0279556e28f04c5570a6274d115d4b3b1bffd7fbcc289cebae7053f40427, + 0x20d97451d83aecfb5c0f6cded427ddd517ada729de160d4ebe2429dba9d28a53, + 0x2d8a77024da1f633ae52a6cf17898c5b908f50ae49fdbe65b4662853337cc919, + 0x10571ff92352d4e69df05c3cdc65c0e52747e03f86476850a47f092bc272b263, + 0x18f7cada1c661e5f8f2074f16e72baaa705c2ce42b68e16fdb4d6945a33054e8, + 0x786ff337450d3614fc75c4d314a61395b71473e735332d78a7aeb270443cb93, + 0xcefe88f60cb9a382d5eeded9e7bacac15e7c906dead35cec09ee6e6d0016b3d, + 0xf163a2012b2484e1de36b5991e59ab0ffd4a531574f6c72382fe92576ce82e8, + 0x63dc4f07d9f069d06a30e7c5a96830d2731ca8165abd9ed89d187753f29c682, + 0x71a3293473c1dcd0ccd5a08dec6a321265ac88dac53eea581264663e1dff0d7, + 0x41b8d2a056f60d8d3ce5e3780a341b97592920b170625c1a69f2a23e1290268, + 0x2deddd6775308aa027b3449357f8abb6a6d10e11cc3a14d0feff23e3a8597ff4, + 0xac050f54534015c810863a63b7354a35fe52279ce4b7a142b48f5502702a4f9, + 0x215bca7ae4832c5946f9ad54abc0b3e7c547f8a5a962e4df85d0b82dce914799, + 0x1efcb27d3c098f574e7fd799e2a585ccf54a59147400ce00c86da0ae0ce90684, + 0x24ddc6ad9a48856da363007a1923d1106affa889e44ffa7959bf41edba382efb, + 0x2ef8e41f289aa4c64244554413eb515b9759a6b5ed9e2562d1a674267171650c, + 0x2f1c219c4d272380eb411db7ef93f6e692eca339fa507b656e0d532801c0e205, + 0x5f18c83d3464488a90182139c312e753a60ca4499e3c2c13f7c2e72fbf47395, + 0x179165ec0d175758f57172f5a9f7d1ce6e435a4a1351d77139b92c6ebec86da, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x11c208a0495e0e7c3e473f98dd1e8c61b27b44de88dae7850122421cda7cfbe1, + 0x297f95f2fbd4565360712a71bf3c80b798b17dfac6c54d884d99f3aa7d673dc8, + 0x224ceefcf32d746010d8069e79d356d69671e3aa9403f39892e5882a1891e718, + 0x2732b23001c43c62c459cf0a1f48790deedbdc489a6372138594a5a74e5f85ef, + 0xcffe59dbecf21803d789c62b67f94bb027de571a963be229c54c84ab106f9f1, + 0x29b8feb4a9a3585ec376063cff8e0f5a4292f37f7a4b7b1ff228f03f5fac0510, + 0x26a0c0e60a2ffa10be7d6b2c878312de74cc43fcc7f9eba49e05fcfcaa3a8b90, + 0x2e570656db41e2f88c3de3c09d68baba727e76e3511dd4d1291443db29aa5f70, + 0x12bb58e4672200ef2816a8237dfcdf70a9fb07b2ddc8789b748d0b559b7cbb78, + 0x216e369c8afad59e15e88e3ffdfbb1e137e9b314785632ad2c7c81bab01a77dd, + 0x2279e39d7921b8e04b6f36503059b1bf2ed79a3b94f15af97b9720bff85ac25a, + 0x60564813a0ce62e4ac21a85ba36fe359b53e84244f908b866568084e31c4afd, + 0x2268a405631dae60e8eac4f408fbd5268b40b1c254970e3c22eab22fb8ecc554, + 0x300263f7d8a2567496a37ab94c57e2015442257c062ecad9d8412f6c6ddc0089, + 0x1963bc7aa03a152df1eb518cd9588bd04f3fd21a318314fe0e54c1f369be3c0e, + 0x136b67c2b78e28a9c5276c6fedd9afad286d344700fac868de5548c404abee95, + 0x29a329f4a94c6c6c9fc81e8cd90f7f1c9e5f6c89875a280dd9ea0b4b90b8ad2f, + 0xc3d92aec4b647cb21e6f0ebb98ef3c65c3450672ce4694f49f39919ce6da1df, + 0x2f5235ceb5912869936811f841c3ee0f648bafc9edebcba4aad0168d03f9b52, + 0x63a760609f24b3692d205c9b3bebfe088c215877de8d79deaa84dff83abb2cb, + 0x1965360730aaa2fb621c470e9042cf5db28c4824575c994b255c92b02d0b6524, + 0x1838e4b596dc759d6a97b0b763d959bdffc4ba10f84ab4b1c4c71d50a924d179, + 0x258cf09bdda431facd55b62aa65712248056e3edd9428b010a809ec78c41ac86, + 0x1e587e52329f0a29bf3db7337442690422a9722e228dec682be39df28b3bf14a, + 0x120effe3050205b3ed1c06aa186bcacbe860b61e77bd06b9b71e78a710a09500, + 0x18213dc619ab928f68d5aac28df923f90282b6ec64d5ac376880d31fa3bc1d5a, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x1f02f7e2e07843a88bcaa2797d91edf88cbd70ad743e938e35396628fff818c5, + 0xdc5a85d95f105d8e4b18eded697c62a032136374296ea9b14f54cb0ecadb9ee, + 0x219b60e6d5a22578775e83f4474206559204025913238a98fe09297e6c473c8f, + 0x435530e014db11e2bfcd58362982d8a33e222783a5bd6db56bbd327cc5237d7, + 0x28c1ffc5c10600c0dc9dc3d193bc58552b235922bdf46161b6f8c4cb5a6cea5f, + 0x1bf7a2f7bf358cd12302582a3b02600994fce154fffc218ae6442bb46026f98a, + 0x179d43fb87170d3d97f4a0166d1663da78664d328cadb544dbf5d6c5d611de99, + 0x8cabf5f7d8a6d458bb6576754fba5a716ae9e484a668217adced3296b7cccc1, + 0x177be1eacf22f916417a28651e18d379eb44e5c2000e329c1d3c8df516c1194e, + 0xa5fae0f09f85d5ab6b22833947da6cba0daa2a9671ade494b7f9d8367394987, + 0x28df87b43e795b370762f1d3f9dc2685e91bbb7a6854acc152f705c89db4938d, + 0x58de2c0fe8e6f09f1b853dac8eaa473e4f6f80fc20e0f4190875d94cada6ecc, + 0x1ba657cd2bdb97e5d24bdadfe5cc11a7543f54c18e65039c0e616e138de5e368, + 0xea5b3a4116ce4ad61e32cfbf9662a60c542aac16016d551149c76700ecc44f7, + 0x2c219d3a2b0e433c1ff243db27a237fe15c733edf0f0084d7a5ba40123fb7361, + 0x19ad974a2285cbd14d04045c6414f199a891524b798cf1e3d692b742cd6d89f6, + 0x2c7d9c944d792ce4b7535207891386b722458c54fbd627ba39521ab9cbc1ebc7, + 0x2e71a3a451566f8919a27edb83647652520bc5b920531fcdcb2859a5ec77bf73, + 0x6a4b1b530cc5e64e84e725629950bd7644f65e7223dfd4986161de535cee83b, + 0xf55042c0a72b5b62d2107153b60482981bda1190bc8b8ce4e30ad101fac7464, + 0x20378dc7686d64b35b84440493ca10a587a5505169d380fc5c5f4a9ee803fc11, + 0x26c526f859170915382b65592aa1957e73f3145c970cd7c891dc86b7d3cd41b3, + 0x194c4e5ab7214877317adfd216f34310e5bc07da13b67139dec08cc25bf2a052, + 0x29e0d646063e27cfaf0e4ffc0546f1b309333958e0ecaa3632bb9fbdcd0388aa, + 0x121b4451014b6382209a13bb0fd2727e59f0702a081fd34e04c8ddeb87d349fd, + 0x3018ea843d3f3f525b9f96b6c6c07e5c86d4a113d183cf66141aa80960048ef7, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x26a889065a9131ee8541587286f27b8ab978d106cf21e7cba567839eb83cf5c7, + 0x12f2322938e02f96227e539152719a6fa62147cf82937a0c980eb011c62b01d6, + 0x2a7052a220aa258284d8bcb1e0646c0266349044ca3c17bd0bb628ec5422a75b, + 0x1e01d825bd60d76a2040b5de5e43b90d1bfbb0876dabf550baa3a5dd47ad62d7, + 0x3002ff6560000420d0de98e87d335432be4a58ff3eea053d2d332354cbc22da9, + 0x3d28736a2952e396f2de28f3a567902027214706657773431d54cd10c0a0464, + 0x27716d5bd3e14b61afb8d6ba91b27739f9075ff2630b19c6c2c26c5d5496e195, + 0x13cde7afb44e0f9b6db2793a51226e40aee9d5e7fc75ed7c663fc2d06e9b8526, + 0x503aae89801bbfc5f702f60ffa566477a634dc17aff8f9747d1fd1fbb3cd336, + 0x1ea910a5da3ba8d8a39930b38b64ffce7616fc9c8bc7fc1fdcf12b650d04089c, + 0xeb1ff569a325e123ede757ea250df5f41f75dd2b75c6532ab96dfe64cf7f3e2, + 0x16cc1752c575ce984729208e79714c336bc3224f951fd6cd0b82a2ac4d43f892, + 0x2653378743d2eea387c330a375bb80e67878a9740fc2425a36315206a140175a, + 0x175b14e3bd393d825ff9560dc4ee5834c69beaceb5f8580156ef162c6d36369b, + 0x162b65eff59b3bc39a2ddc923c77da7a17dfe79b7557b8383367922fdd8aa5e6, + 0x297d9796101df9152043297c780dd5137e6bb2d9a25a8fa92187b5de2399affc, + 0x292db1438ce4bced35048fa12b049bfa359709bca7dc314c937f0514679f0d24, + 0x19c2715e87c332adbcd530ce981d8704f0a207e822f190baab421d4d03d24bd9, + 0x139bf2e121b6694f773a58f70956cb782a37e4949e482d87dc820b034ffd0f28, + 0x281e06a2a3e9c7ad29265b2ef8c1f4814adc59e5b3b605a05c3cce8a59e321d3, + 0xbaa4181dbff92f83386e95c6cae0c8efa07f0cd6e822bd3769e4ae8c64e7d9f, + 0x2288cd08659c856e697d93558197d16c03fac590096ede68e959636d09956d9f, + 0x2af86b3b3cafb3ace42a0cba5c99dcce7b0fc35313b2edddf0401bc029373c1d, + 0x173806fe4b0512b715cb7e3cc8679d3a7a4c2b7174e8cd710574b3c142b8197d, + 0x25b66da637a8d92f088d8faecf034ab77e2b2c3f88fce5c560922f648eef960d, + 0x12f5922b95ad36bc7a81c2fe8ffc729342bd3aeb1555969590bf2248d70a3e91, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x170bcf0294ae4059d95f36684abb4fc2cd0369a67be4bb919fe185aa39467569, + 0x17d247983fbaecafd39c9dbb1fc2633ee7ccf02383978abe8bba05e7bf498144, + 0x275c74ba59d68ebd78d02ea7bfc087b17708544436bb5438b41b053072df4836, + 0xb97a196195430ef69cf23dfd0906653e5808c3593449bf58c374242ef82bdc6, + 0x25bf621be7fe04105e8a50b02ed9025840affde6bb3bbdd06df97f2fe9e02e38, + 0x296928baa83c1016ead86e5c9011b134d5d24179b1970e68dc89794b73d024d0, + 0x23e6fc3b8617b6b51f35d983c470a99546099a6361ee1626e6e44e5e3e2f7dbc, + 0x1b9b57f457f685d54e7f7f332af4233d293106f56ac093a07c209205217108b6, + 0x290f0ac712987d7956e8b4dbdd8b6706399adce9506e3373d229d45605637311, + 0x262a3b6b3986c250d387fcb734cd914f5e8bb751b571fad1ff366a479e3e6538, + 0x295b88ac50fee49245bfd9bd911734324c8d00abea718917a4dc6c21b3e507de, + 0x2e7a6894330ce6d6478206619aff889fb1bbdcec80e6f09de69398f344a4f6e1, + 0xc3bf1bb2ee94489afed3633b8ec12dbaa4b6a2003eac80e7f1668ff340bbefc, + 0x2d61629d203317ea4449e200880be2ed8421aa6f2de73aaa56810fc304eeaae5, + 0x1d94aec8d967eabceea3de4acbd2c3b19fee00212d2dece58d5ae53bfe6037b6, + 0x2f76d72fd59722c377e315583f91b326ea792968fbe6bf73582aaf7af697d3dc, + 0xd243da739e905f8b000912519379de3a3bad6de3c3aaf91cfd78f9735b0c1bd, + 0xacfdf5f69c09506cb85199eacdba0b9b3c5a0fa1a60cf283877ff7efaf3bcf7, + 0x44de47687196189473b125ea91ec1ceb1481f8f49fcd47becef1b01f4c9fe09, + 0x27e155dea5a1134466a8e2ba58e2b03cad8c38c20716a7d3e78c483b019e79b0, + 0x2860ac51f3e70148561d5c109abdb096225aaf9b7bbc17bd7aa31ad26e243e75, + 0x1a33e054ae45916951f73826b9badc032ed3d0f3c21acc7dd18d46f268cd2a86, + 0x237acb3608d9158738b6b37b6f6b287531d9683bbe16b463c946b752c089ab8, + 0x9328966036d95ecd345f77dc984391d09732acf567d010b855e0422365c6209, + 0x6a41ffd9721ef018d7e9e2d67b8d9820d6a80be401e1617e07b29b3c5f8e53a, + 0x1bac3b3b9cd40ec41b542b47ff0dbda03997f88a37aa23de69d0d5113e5b448e, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x17dedb52641d9f9e688a673980bf47c462346d1d6731db6bbf0c27ccb2565173, + 0xd947949f35e75c29a986ed662cf1e1d85c2e3f3a9489da6d7a6a6573bf3bdff, + 0x2bdb20a8327ea3f509eea1f81865ac34f7e7c5dc43d516294a29c208cd0bac7e, + 0x2fecb170873731d070ccec6d88733be3275e5be22a47cd294ad7247cd75247f6, + 0x1183c981f815c35119fe4558a0aea9f533f9d7980195d96d75a80cb1fed40c02, + 0x5fa320ab5dae365f8a114d10921a5fa13f79f44f18b57021a483eedc2c5bba8, + 0x2b951512add2c708a010d1ca59bed166f3726cae5cb1525dd379156d810e6c2c, + 0x11f646514881127c9f1067238c06a7ca39b9c1a0234eb1b8658c2bc70404578f, + 0x72413e94aca278eeebaca63c7941b548147387d21578f97e58ec27198fd4e58, + 0x2aace8cefc1be4d4175001aebebe91fc87a46a280be0a90886383ff2d561d7b7, + 0x69e64230343d9ac3c6130b300cfa24cec6086c85a1aa1c8edd073a7d33adb2, + 0x1ce84829e4e67cd9fd3bcc8d1169a15c731e06ba76c77ad60e84b045d5d731aa, + 0x23b52a113ac4ea90a8330c189a63fe9520f2d73db94406abea72150ea2b7ea0e, + 0x160218f2b7e2d22653b3ca12190f5538563aeb27ad8ac8f2f71943bbdb0c5928, + 0x84c1a87e7fed6aa9c80f455dd132e06f897f43b6bc12f3f5ff56a4297eaa153, + 0xcecba653fff37ab5fb266ae654c23b2cab83b0f7ba92c706a078b4de3221adc, + 0x2ef80d5e15aba6b2652fef7e0419167f804f2cf713200eecf30682cd138781d1, + 0x14bd930a77fef4cdf7d47bcb46ee6fa596c43e9dd40ba87a488c613d5968cb58, + 0x1ced050594cb02e43a97cf4126a5dead21217e9b5dec28ffd803a381ada6dbc0, + 0x2efdbbe781cc22b39fdc48af3424a354c48ceb17113136ec794a9b3319fc9429, + 0x2070e4e04671601ccd0842cb7a374ff2b93838af86ae464f82ceae2f1539c1d8, + 0x123741e7f63e77fa3e2d8abd9f222b23dbba1c14e8af53385cad56594f065e1e, + 0x1b75035c35b201efc55a1d47aada8976f5fb0dc1da22482a6b61d33d555eceb6, + 0x25d76dabc919ef40ebe597d4bae43fdbd2197e9b0f7b7dda83a1360295e9fcf6, + 0x666b59c9ad666ed3fc9d1e9af97fcf7ab94ba3387573d8d31f03084f9e5c976, + 0x654f99795543eefc6e1b1e646108896ea5161c9c9a5e174f2e1cb9093809b4c, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x2a4984518cf4d03a9b3598bdc254484a1805160612b943ff7b509637f12a70cc, + 0x36731a2bdca86fe011dd7bde4043f89ca492084165aefa6ad9f74717ed54536, + 0xf5fc4d1e67992e65abcde194f07cb07b72800a4f4a26e5020e96c5d4ae3a952, + 0x20d02c9669942a2fda0de7a67b8c5cfca08b2e914f65652a71044ac9a09190be, + 0x20b3c785c2072c1016dc316a7933ad541fffa7df2d289b32799e106dc4f9c1b4, + 0x1007df7ccc98951aae782b87985756784a1444531492615315080e2c80a33131, + 0x223a10997957b12816110049ac7b56d550cd7a5c0b47bebc1f8b35167189b2da, + 0x358632186da4fff1765d4d688ccf425c333995bd7438240be0cce1428717270, + 0x216b1f88bf14a781c99ad7a394781182d40162fddaa8391917aca465382be039, + 0x108441368a058a30c565ac01d4145056d5a5614892879844c07a1c0289b2c928, + 0x3df1a412eb02d17bcc82088f46cb5f77ec6279ff7161856c52480d00554a366, + 0x2cf2d9f080d1219e2dd3d7cda1442b178464a583260e6d9632e12812b08c38b, + 0xff8f5f8d239c9afc6c9d041ff0805ee22c3ef3cf5248fa2ab198a303597d82f, + 0x22baee6a9025f961d95afb122fe50ce73d0acd9a913f2fc8d07a050f4de65dd2, + 0x1131e942fc36296247e9d9013e71cc89498a7090a683bf08bdd23e267340fe1e, + 0xac6a1c394f929725acb0a1b5e11ad9e28aa1c79da25624596451b04645d8a76, + 0x3cc80ba68d89cdcc935b0d872d775b3b8f2a0cd50df89edbc3a6269290d6950, + 0x1db513c2f29ae454a99bf928ffc2d93fbc363d0bb6cd0bcd93106d1bfe5f789a, + 0xd05dae2a4b1ec3585f98d84bee7d10717da3b17a71281672e3451916260a301, + 0x2adcd4c6f191ccdbcd5a98bdc6050ba95009e2039de7f0fd9bbeecf0c4f1ecef, + 0x4d0d5708e1d87ca69eb4d44350313730d9d8403801606def36f035183ae03e3, + 0x11184dfa1ada7118e79f8890036facdd47001b7b63b74c3d2983fceecf3ecae5, + 0xd32f8b975e939f7efa097c2a3d4cee8340deae3012758e3b3a4ee0a2fd193b4, + 0x1a24e9162049895bdba49f57cee0396e4734bcab60d8ec4305a5b685b3ca66ed, + 0x19873998ebfde4a585f34a40a6e1fa702b7fbd29b09aa141c5a878e448e48e2a, + 0x2d055b284ae3e229cbe0d4901ce6b687eef40d815da38cde743f3851c774fbc5, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x301d2bd94a2a85a3c802d0467c1cfb28e2aee547d2f7d51c2af108a549462a23, + 0x19ef6ff9413f7a05af63f528a7f80dac32bb3fe601e02ca15feb99f91a844d0c, + 0xf1cb5dd8ea58b523d3e9d9de030ea9db932b770ed97d2755da22a1512696ebb, + 0x151ec2edecad41d2a4a74e8b09748ac3d11acff9c8a825e0f0c539376313fc8e, + 0xbf605154c6e6cfca764590093b09ecec2e38a0426d4f8f0f6f9ce771d4ccfcd, + 0x10d1c2b4f3622195ccd9bc64ab73145907e7358d92beb85826770d174810cf56, + 0x79c01911499171a82059606f1a0e1683eb2f076a4a72314e51924b61259fb79, + 0x1886095782a7c6abf9faf6549080c2a72f8ececc22bf58073df90be6920473dc, + 0x261c4081f13edba795488c906dfa2b59917affb44cedf1727cb27da0b0b2c20a, + 0x2cfdc7ffc3609e9d82b3bd1f2f1d42e15d1e0b7eb24719123e0b67d060800dca, + 0x3c9ce71c00e243a950dff0d9e0a5d3c42f823983f6c1d3d50e0de1822993d84, + 0x13714ab10fbbc54e15fa5ff0d6bca9846fc940a9c6bdd87b044868600f89bbee, + 0x134d4838b8c77e7270460739fb444e60580e951d914a5a20493a2b03d294890a, + 0x1e6f53eed7f86f7291436624847ef6451457756a213c168c3bd7a5945a4f2873, + 0x8c4e9815652721c5293235dec1eae97fb8f93ac48d86c37ad6adfa77055665c, + 0x18d007112ac9205d16ff209b80cf0b5260387ce770d4e6978edee9e0003fabec, + 0x5140e8f5d27d7248a3e50e84c6bf700fa31c1a1a7ac144390f4bcff5ad61243, + 0x19f153d66e44c662af026dbe5be9be834a10a3dfeae59729555d709d61e38f7c, + 0x11e0299ac3f3ed3ee71377dce3b85768cd2a6b65e9d3bea24743d150e19f943c, + 0x190ab7e9ed8c741d54fc558afc96b35d9319d317ff6d6332ae4ca77a8a3a7911, + 0x5bf8fc4ad0126d42c22ed2c659b66f053ca3604f0968520ce5c7ef06c5a8793, + 0x28c05200db6d51df10d8a4986cb65c078001f295343de608d68fae45cabdc5f0, + 0x1d64d0d4143f869056ecb1026a361b48dd5162f38beefad1a6d139843d3dac9a, + 0x56869389330224064b29f958f37fe90fc2bb4dc2454425b0d362b892be0fb73, + 0x21124fa7acd6d96ec308ffca46465e5da69c44814c6e40e705b7c6b4d7eaa333, + 0x210de4f22732824523dd4fd0587eebdd78cc339e8dc44fbdc2a317244132f7, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0xc231a81780a5f9babc1f4137106d456a5cdf0a356e0c3b79b330982dde6c5db, + 0xd2286ef77f15b562ba8316151a92458c52ab6979d36481abb6ee9420befc144, + 0x14cd6adb239444df9b510c5e1c2a378f3ddfbc75b61371b688931bf3c6ec2563, + 0x1f94577cc0cb87a180811923adfca9a8cc77b8ef41c0efef36e1b319679f0f10, + 0x2bf8ecc53796cac7b1b4b8e8cbfe8f92c31f726dba638783eb063b675fa96064, + 0x2443dff5793f12826c9195fc95caf2162cb739d837c4e15d426e65eb20c44884, + 0x28807445f05857e5db18c6ba6c0f3d67cfd08d7ee0a1b5a3ec259c11e57f6581, + 0x2d7181a0eb717fc3d9554bb1996ee527cc29fa9dd3ddebabf346725d84389a45, + 0x1d467a0dad4ca6c95707e95f8780ca40fcc983a7e1171b111a8874b122574488, + 0x2cd6049a0ad06e9a9a9eef6333566fe7558db0007e6e92d71250ce582189453, + 0x2ec06f373cb79c1143d0ead6ea94a531574b642a2a88ed6cb21bbafbe2932c57, + 0xdadde1785a6e8705856c47207ee42045dd0360c3cb332e866dd032ef9bad925, + 0x26ef0863b7b4eb4223c88b5864b903526d84ff81c099ea942fa99ffa0e376678, + 0x26f1a2490186a61de95667c8672dffbee6bc1451ac11fe2e9d159d308f87caf9, + 0x913a0a4317ae24b6cbef39c87f10a3f47b4fa74b6e7f9286a6991027af81d6c, + 0x101d691311e602f1bf45e2bad29994880376f57804517525eb169240d21ef3b9, + 0x1c55eab0a94644305995dd5b9a4f2724390d88fd3e982be43b01a627accf5b16, + 0x1f788dca1edff5172b4e948868bc18e7c0ef3602033d72ef3227f8776bcd40b8, + 0xc5dc41e36fe501aacb4d8f8d33b12da167a12fcdc10626a1cdfc90cc25cd819, + 0x18a6e567865d428f2dbbb6e9bf298ab8958c5d1737618e5f1c5679c76787bac7, + 0xcdfb3e5975fb90caee98497768f37dd465586e1669d6bfc512b32a3895c62f6, + 0x30edc8429fa6230b5bf9553ce19f0a78055f2d68dec10957d0d64e8a3bdb3e, + 0x5ff6dbf8c00e9f32a61f908e6fa7518e49ce0bc92dab519524887ad9bcb3a8f, + 0x187c0035a20f42bb04a4d3f172d8dd71761fbe16405a0c73658a18e177012b32, + 0x267e0e37151a8018949bd766e65170ad7944b54b191df4904b67d181a3b0341d, + 0xde2f39c45dc6b47bad47d29d8ce587e60c432bf03f9924e3d70152bab232ead, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x284591632913e57214bc02159bb3e8e81c06bed2fe6f302a3d238f14152cb3e4, + 0x2f6110333487576bb66188bb38170601a18b160a41c655f55b366e138ddc3c88, + 0x10e8a25fd4ff737b1fd8eaa1ca0fdc107a1d9e48ffbcbd86fe2b388dd10ac80c, + 0x934ae9d36b935e477c1d92c9ea1b80bcd2d81f3fe0e37a4df894293f7ee2e0c, + 0x1d48097697bd76fe5b0fe21d8c182a9a032700c0aa94fa147765147a66c7a732, + 0x26a007b8e7c5a0f095c47c27e9a68c6be8b08766863ba33854b2dfcb6c708f74, + 0x1db9c979d26dc221830cfd85bb16b9bf6e6ed9032c917ed64046d24b19feca2d, + 0xeb6abf55ab892abe5ed8ad7223d04460eb7cc6591216c260250ec0ea22852f4, + 0xaf52963d2d8ca1d85fe433b3e20e360f488dc7ae40a074925f612959482fd7c, + 0x21a08ad9c5da7fbfa096b1773acb293efdb29b76a2b0d54f107110e7f7e7ae8c, + 0x6cbf675121397f0657bae080980b2b22566613e0501f74eff8f71826a5aef4b, + 0x31a23d2ad653f7306b849eff0b4373a7a2eae9279e8f048279d90241561b192, + 0x2f086707d317470467a8e0ae03ba725ef79ed1ef014395b67ad4da788237769c, + 0x24360122ee8c5a9ceb21696d69d5456a3166419377b098388a2f19966ce62005, + 0x17c0f7d233d0fbcc5c520f1ce3a5d4b095bd11fe8f39f090ab7e9d24ebca8195, + 0x3f293140b7d07e158f63f94792f943632ced772d71cdbd93e171a98a2bdb1a9, + 0x280d4d680de44f4a35a8d0baa4a1feb3701fec97a152e977b5352563c797f68b, + 0x1633dd4196cf695bfb9e5138ccbb381b0bab619ad1b728802c0e9b35770503e5, + 0x549cb9c6b3ab14ade93f695dc31df816e13e6cff79023f91c5ead9311fa37e0, + 0x12dcea4ce3927ca8c308751550a77c5ce4e095e0e9a417108c18102e4b0aba31, + 0x78331ac4c2c6702655cbabe212124d4f1a1f5005a75faf2c6fee507b9996541, + 0x5674b32b037c937ab00bb7ef41befd1c0004014b66acc26b117bd0b462870b5, + 0x165c541ff3c38f4a9af878034316bc4c08ec15fcccc77657e7aea32c982e26d9, + 0x16477e2f6956b2a232be8389586b0569feefab7d635f173ebfcaaa06040441db, + 0x1698424bc862b0a96fe6843dd5c7626ae0182d50f8323c338917bd9e8c8a8744, + 0x1dfbc6764488855933fe75e10ddd60b09d67d98c622f36cb565931d97e922988, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x2f722fe53b252f8256f3c9d613fcb12205dc97de726ac8f23c6d4ee0a9575add, + 0x4ce7f85039445253ecbcbf393061759062e52a54060331db27947bb0e04b101, + 0x2ad1ccb6918b4dbb68bbe0389521d418f1930df1cffc91de8e8ee648a6a4e62f, + 0x119ab9bbd433ff01c7e43079d288d053e7e0c4a76facdecde1a77d544906b4ed, + 0x17d263f75f3d3f0d472bce50e641017a291f8466e6c03a768c138deb1b50f3f4, + 0x248be6746b30e18cc13259078ec848411532ad11d4506ac6ccde131495c9fc42, + 0xb02fe4295790760e1fa72811dd63502ea36bed8eb8652e6b35f4faf9b554312, + 0x148b519dc0b5daa50f0073094e87db4449c8a068ccd109872696973f9eb806c0, + 0x1bb5e7ef82c1a2a02827a2f16a34cbe60209f8475d3bfc0b6652e61f4113e6da, + 0xfb76804e630b9b522d9af08f1b53880f5cdc691bb22c27151f541fc8e1bf2fb, + 0x25f15fdbcc16e5c1ab1066d294bc774db9166ec45d4dcdadc4597ede1da532c8, + 0x18cf6ec7ac6dd943c57b9472b58af18929a94dd92a340b3e43c074f62b7cffb9, + 0x28993fba9683f72a8727701674e3e657fdccac4649f82879df4295e858857317, + 0x1fdd6bf585ede657728a4e97eadf195c08f8e6144b28bd92ef6cb706e4f6b05e, + 0x1810b0fdc26d123bac819ba150ffb6ac9455ada7dec6deabf178f0dfffab05d7, + 0x17935bc39ce241e78bbd64ffc72166b8d8054be62c494f3b89abf88810808fcd, + 0x23b66feb87a9b7a105923883b0ea0c73f795e445e3cb6f68c9217cc0ffea43ef, + 0x9f6acc9470a3ca1b06e023cb2f6d68a46ca6c434c521b2d0a799cc3f7b29a9d, + 0x7059db933a49a59d77c7dd8226ea452868ab183d14aa09ba3f62011a08ca31a, + 0x110283c2d84ef498d54d8cc89f3ccd48990382ae73b8993a3644ab9961b71141, + 0x2e0861925cc9b76c5b0046d8178cb36a13b26aa4ce4e5f7d3be453378928627d, + 0x186d7f00229ad745a0123ad95fae9d1136d4dff9fb693f954ad9fca972ce9d89, + 0x22c7a666156ed3e7813e98f60d15e23a461d2e9cf389a581dbf8be0bf5afd011, + 0x1cdeb50c6bcc3f9cd2f59588fd72fb929034685f88506e891f41dd572c67c360, + 0x2978a2a151c95155411e8acb3c12cdbcf929d675fb978e636c93da663800c33b, + 0x167e72f7db7e8e21f7daf4f02fa830884851d562c3b51606b52ad3e80d4757bf, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x1957be621bd6207736b0374c7077ef66cdcfa4bf575a16d2724ec94e2d764876, + 0x3b264ea2c2a171ce3bc6672fa95706ae37155fed16218080f33e469bc9b6e54, + 0x1cac742468595a01d58239fa27bfd73e5e4c811d31bf2307e3ad7d9f7a440c82, + 0x1308e2503e1623793102a3c6ef79b0041696191d4cd1a089d440e717d15675b6, + 0x135997d11a8ab3d418e1b34376d3193d0b8355902aedfdb2f29aa43278e2790d, + 0x6f8a541f16f9f3d8bb1757aaec5ed1fdfbe7990e7b046fe6deb8c6af212ff4a, + 0x9a4037450ac7d74675a6abf0169890a2161dac550cbdbb257ca22f4026ee4e1, + 0x1bb22813c573e8209b7100e77ef81cedf79e7ce616b229a7540505854c2612fa, + 0xd5235d7acd8bad965dbeeaaac39d599543b2766dad81dfa738988f8c4fecacc, + 0x24522e82642d0c00deb6406ab28a1867dfa50cd6d0ecaa0e18b6e5824005abaf, + 0x51808f718e4a3898d1266b473a2e0fa470b9ab592f9e1efdfb177a8f1b1a863, + 0x2ebf139bad53a7408b452fdfaf8847141346688e05da4e0e5b478c178bc36c17, + 0x18f177bfdabe5eccaa6dc0fc28f75e20dbd9e470ad50337724be79e46f4b4298, + 0x23f5e3e09744ca3e73ff2660e40ac6b8152e1c0a93e507f311090e6574458779, + 0x23fc5867bd5b4d52686ae8ebe3c1454e266bc576aec1f682bf18f783853d8527, + 0xde2e3ab296be75fe02af329d61d80c5c4d29886528315b4698223699ec70de3, + 0x2f4c1d3cf6793b0f8a707de4909c1df3f888a37f5f8e382065b500936c33d207, + 0x26bfb7031fd16e59d70dc1720d4d04301d97e07a0023e58765b2b6b735b02443, + 0x8f0bea4f928caae9d19e71f19dd85c7d700b1b05b3170548784677bcc4dce73, + 0x206dd86edb0388abd591546b376a7ae6dc433041b7d248ea75d908c4b3740afc, + 0xbd896df632e39aad4e575444b0bf49de0e10183b09137b8f79f704cf2feebe6, + 0x2188116488e4192be2569647ea81c6caa45d08b896ac14e497ded7a6b80d9852, + 0xe95540fcc2df2d1f630191f9e5f48b7e4695fdd5f4e9a7c930f16598b3e9e53, + 0x29d25da59f9b238929d0eb4c669216770673bba9a48a1160793ec66e75259040, + 0x998c56e22c0fe57c936f19774ec4368ff33aca06589807db3a1e8138395b4f9, + 0x1f460a24b80724cb88af9fd2b73b512e6d5fde9ad6d0b73801db0cae1d0c0357, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0xdc5b4d3482661089384d18500ed0afdb1a635c006ec67b3137ef97cb03d27d0, + 0x22c7492f2fa7b9f297c2f0365945ce0e262793331d3cda1cb73d083fc8a0e21d, + 0x266af95c1174ed0a5781bad21a2397578ec4d16642d729c4daca8f14f6c86a91, + 0x14c46169d20fa3e4a67fd8da381ac224d61cef48dd27c1971273519b6f9b703f, + 0x1269bce1327ee515c7de22ced7aa99a4df202cf661ea0f2c520ce2a721a640f2, + 0x172bcf2621fe4e5c2919490728ee5d19f6d1b3db328addcb2f70a792490e9bc0, + 0xf26dd040a3d43e4788c20be85b4bf774763729fce73037ae53a5f490ab99c49, + 0x2fe304bb2aad7c3a3fe30b77087600d1da7ca2d9053f7ed264c1865cc8231907, + 0x2e365d1b4f6d9946faf2ba71fade06bbbf2f8475eec5a56fc4843765fb4a49fc, + 0x25a82f1231627dd4fa32b82d274658a1b64e8ebad06ee903aab649e32ffadbcf, + 0x2cb9324b95c056a7dac8511562fdb8049c4f08e6fbd3ee222bab96ecacb89c9a, + 0x1e3c03ec4cccb96e93e7b8fa96f6915a0ea2f392b4f5ebac5b2f251013fcd3a7, + 0x21011730617a2b7c760f7758dfe37725189c39224023ff0d819dbebb1a81c07, + 0x28b05c0a2e98dbe8f090863730a24b597d97ec3adb4a00f3f1a176d02f495138, + 0x27355701c30ec033287bc103652855c341a8e80aed9b0bf7a1633b3f0ab11a43, + 0xfad7793054577536c56651b9585ad1ecc2af28c4065c6fae4ff47df4289d5f0, + 0x21bb038dbba587b85cf0fbfcd5e69de9f329f6646bdd40e8e27a107161f624b3, + 0x21b1f094f3e78cbf60067b3b785e3b3f24c4161c91c452318ee990e07e225524, + 0x52d8b24d73c86adbc8311390a5b2c9b6300671f92717203ad7c463bbe0789df, + 0xd7039ff767a3d8bb07fb62d6b2ebe8c543277e3da1531da94cc861d4574f648, + 0x1b916f0851986c4edc2b927aa8bf9d92178ebe75b77552ce47a63ef70409bc03, + 0x33cab9f4d3c360924e9227254f4f9bd52fa7712fb518e534f9fe69d04d994e, + 0xe26a5327b3a023b0d1a432d4be5f7f0b09f8c4143ab881b985f2cf7e458fde4, + 0x2ca57bd0c629753607a4c9e37b783668abbec7e8e306f75b88ba97772d371595, + 0xb7533836731172ac9dbb56e54588a5eb800fd80d6754af74fdf13460c340ef3, + 0x28c3653d647bd221d2b3c79f3da382a937cd1be9a33232748f04f8e1c880bdad, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x7fc230b6a36abb1c7f4b7504fa51ab01aa880f7b3c0a60eee1637ff68889dbe, + 0xbbfe36421ba52a2fc87f6d7976aec0165e41aee0f71cbfc87f41b6b965ca6e6, + 0xfd2424b028d4d8ac1a8c66e6306af2c3df213a3a7979e367c2957eb631f17af, + 0x1b674725a1f99e1dfeeb07dffa4d961ec24a31d433d83f858cf3ffdfd2fabaeb, + 0x12c9cc35e0ea2482935ddba214f21a8c08df3dc9d6b29f75619f9ffe0d055f10, + 0x1ad3b10f3f584f4811c804d95b3709ded70c5a7d3bbbf6f91339943d85bbe21c, + 0x2abfcda5b9f799b2d0af0861c17c33253781df51eb186a65eac958b34e8c35a5, + 0xd9cf52fd20c189982504d02aa80500a5c732434dfc9e7cacaf08ddc0d0c76dd, + 0xd87620da15c58c50af67bf3533b399edf83c1e7dbc0bd9773d40d5ea287aba4, + 0x289e55051ec741e27389dce0eca1cfc0fa57be3381c12943fdfc6aa392b60af1, + 0x285ec1799c195e638e16e4cc7fe5bb7ce06b1c82105cc4d61385dc2d2ecbb979, + 0x284ce6e7141920ad4159f9c97ee921a24cd188718f7000f1ccb091067d4ddeed, + 0x2403b3f3f99fd0daa8ad77cb3f8d515055cf80d1d5e8d32e4e4627e95489f57e, + 0x2ef65bcc67502169c5c5d324e09297b7253302c82a337f00033c814aa33d9cee, + 0x2b1ced8656b92329d623a85ee61e310495566ce4effcfefb6e6606ecfcdbff4e, + 0x2cf6166a9183e66bd94be5aae54afff0f02cc6eb68d7456cdfdd86e0e7f0719d, + 0x60d392a31de88d78b696e7238af3ca3eaa5e412437c66e59d7049b69d2507c0, + 0xc2b62bd89e35735926f6474264c899eb2b5956738a478b6e76d792bf420cd16, + 0xe070af64e603d24608847ce8677d0291e08d5c10ec31f23d898d716f1c39d1a, + 0x2de645e3763155f48ca18d06dd21370f314e26382c6c9e883d84e387bd892893, + 0x17deebc35147ac645572140ca181a81785e74dfce063b37e326ce6e79c66a6da, + 0xb035d43bfeca4b7a464054eaa0f892cb035db06a3150ad9ce1ce45f6ad0b811, + 0x100c78328ef5a499443541c1e27f78d0e77f65f93738e393bdcf4b098681be52, + 0x180cd1e5a1262087a60bf156e8ed528070936923605d5fb078f4f6f956a55aef, + 0x1409c9afb266f52723089bcc3b495bb15c9f10cb55b32b73dead030f87e6e24a, + 0x100ee62d3a9d66d3b6360f540f954493d7af73e6cd95a10ddbcdd79d6739fd38, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0xf8533b51bd9ed54a1703fa8399239d3a7fe77b0a55210917343e09342a0fd81, + 0xa38a8515b1393a083782c40f7261e921d87155c081b7039db8f409beb2dc8f4, + 0x1dbe26b8ab56c6de11196b0ffe7355348b99083a94d2f2966d227fde43821f7, + 0x2fae58b811204fbf3232b298e274df120020289d06ba343bc9532fae7ccfa76a, + 0x2c33c971128abcaffde44567163b071c1c845d5e04e4b3e4f3256c690cc61efd, + 0x1d6879298603d7ce919895eaaf857157bfaf20b46ebad48c36e85927e004967d, + 0x154e2b495b2894e24c7b64fb83c0473186b256f83de4e7b5f82abc3e97b9d176, + 0x1108e6590ee097d6177f9b0e8f6df631e91ca6aad1744fdfc36a5a7cf73689c2, + 0x30e4cc0defe07e0c0ffc72ec35cfa5f902e564359dc27e6f500c921db4f22c2, + 0x1c4f81779c8633490f3e3e276603162c4a5e42fe6db58a53316f805c5c822922, + 0x2954c55e5111eb033ad80c867317b4aaba9d750b9f9bedbfc48abe8430ba3c20, + 0xd519d7237511791c479d178f6500e54532625fef17aef20782d15be156830b4, + 0xb18f5604bef3748e0e8ecb40e7f636d2452a42ed19299820a5d41241e3e27ac, + 0x2719c5dffb3c5e099e2ebe58e16855ef505dd10daf7cc2f213113ff647614b42, + 0x16e635dbb0038d05bd950a92b785afacb3fd0e6b86cce3d242132d4f1c1c0ce, + 0x3920a662038566aca072b265532745baf239bb3e60326891222047605015b23, + 0x2c4f137391f3b5e4e6024a97f1c9cbdedb1297d123add7adf4d6461ae5a875bf, + 0x2264a7d603db95df9f07582fb03dce9340e2de326cea846bba043b0946f812d9, + 0x2f1f379f002c49094dd938433a986b519a123c4d9d0189d66533665d0745067c, + 0xd29276a5ac511cfc3a3fe7b9244d4b7010cf0bdfa90d7df0d6c4000b9585d45, + 0xac3ab6802fcf30b3b6d2b1a69e54b3699179b4f30b464e0b71b6b4b6b1124bf, + 0x2dc0c34175e61183601ba4dcf9ffb457defd36abc2e24babedbb0a9450155fdd, + 0x6fd088a7bca20b5570d68665ae17172c13bb3698f3640cce22ab74ead7c5663, + 0x1de87003640c024ab5d55c378a74e14e1adea072f8d22ee932b49150dfd1126a, + 0x2e01b475d78e669a868129b1f173a77a0b28d82a89b4ebbfa274a0a41eff3e06, + 0x1ba9c82ee2f9ce1b70390faa1d3c40585d751775bc8596e32acf34bcfd58f814, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x2a61fb95295b3b5c0949c486673d1ce6ed7328f42c9dd1c82e27fa3dbb0e3bf8, + 0x156befb6eeb13f52ba65eb7390b7c812ba6aabc5d1acfc189b95f71fb47db283, + 0x13422f783a978ed5ce35e1540d99c3cbc67803de00a3a4fdbd37f7c120d7aac3, + 0x1995d00ce7c99415c2727e89618e705a87fd4456149fbd899c40f43320d5ec8b, + 0x24ebb318e440a45956fae1a46a3303ffabbcad5acb8cf98b6ee6805672ea84b3, + 0x2c6c1b35e7979c2e34b071a03101db8cf753b5c26193f206e2ad214ed47387cc, + 0x2fb55d17e5a50b80b168fcdd0d618f2da007510bdbc429c5ed7fc9e9a1ee5c0d, + 0x117c39033ac0e1f5f8b57844220b7260e3085bb99925eaf937d4a43a06bcd2bf, + 0x154a4ff3064027d0d4aaba2fccbb05fc4b074ad7bc4443132ed23c5f03d38ef1, + 0x16ea33e7327d3fab4e15cf66ccc4e99104aa40a4ae0eefbd478517475c274d62, + 0x7af162f6a41d5623cd47181367c6f1f5ee0be7b9e0b53fb8097789ea9a0cdfb, + 0x1a732e3765405223cdb6eb28abd2d425dc7d1cdbe575e08568e1028d8ddbc398, + 0x1208ce1a3a017db5d1024920a6a0f94fba55f5b88620ace2e180c3d517163641, + 0xbf9ac6ccc83f71dfb86d40b19b7609b555fbc1ad465b09f9b47b21cb230e174, + 0x1ae8cbc6e5e4b91ea924aa8045967abf4d22d687639e7f64df40e1baec14a3d0, + 0x2a1be1e4d0fddc88eadca5e835f30bf7ee39b0aadd995b48a7ba601b87d16380, + 0x1dcf4c29bab85ce96ae81703ff26262a09c8895f886a71c01413d440a2f783fc, + 0x2bde5bc567bc599e209587d01a8e5b83c9f27fd4988c978294ed9b680b03047d, + 0xd7f63416aaa46e1a5ab07653c98721b3848f7f40dda0cbe24f5be957249bfd6, + 0x201c0d5ba18737cce0bcf6069d82ac70b7c6da968029939fd793e7dfc11997c1, + 0xfd4dfde771c21adf5ff971e0bd0301b0f9c0079a5ccbebf6cc05a578218cf9f, + 0x6e26ebfae0d7f5596bc1719d578b1645bdccb473c802820e8d1e73ba95fdae5, + 0x153a90c4a4df503ade4670a019c1c539fa9abb1d7bd85c5627e2a236816e9e94, + 0x268ddb0d3607d6d88ab21623db322f70881c865d1baa284eef7b6f504649f5ca, + 0x10ad938c2c97c8785232011e8e9956ca87ab31b6e9947a3f5a9cb2dfa526c178, + 0x100a9d42b7617d60e4b3aea5150d059bbe751456c4249f0d807247629e61f0c4, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x13bc85e2ad431df8a6705d1990ac925ccc3df1282405746025b8a5b9dea661fd, + 0xcf2d89cb39c2d88605c0a34e07eb31436a77a2909604c6917c1c8ef5b490d8e, + 0x2612eaba8d6b833432665b1334d612cd9bc430a3bfe2ebb3e34b7a9d878f4054, + 0x17f2915802e376c5827e719a6890d90fb067762c96bb3bb86bb34f2f14211011, + 0x1ec7edddf6e2543f5e457ad0adfe66ff55ec07302a6051d90797b65380b8f07e, + 0x1d4406aa079fb976bf4d8a3bfac81347bcea2cc9b8ca732d3064f9413f202082, + 0x29b71a20d311389c672d8a857b34b04e5b4c95624ca72067879cd312d8b17cb0, + 0x6df0c4c7d3b8552c2298f518a19665ec355cdedba299b20eb193c67c0e72d43, + 0x26779e10800437760c7bc212ceaa5d63d53a234368296d667f1d19784f47cda8, + 0xed1c5edb7053068b07ee60910ed3d1c1e41684b276a0ade50c654de10a44cc, + 0x24b4046af28ee5013cb1662a81ae6b60c9431724b3b16202a5d9d5ecdb0dd322, + 0x2710607671674451e9da2932f51616f1478e7440017bcbe5f1df1031baa582fe, + 0xba845a38009864ca2478e043645bb6d035ab0ae20053ae65c99ae914819878f, + 0x15c5c54f3efc26d2836a2ce81c045bcb20e137945f8a64ec93b50b05fcea1624, + 0x2f416e4189aeae931290aa08d84764da18dce217ec716ec1ad530d21d035c1a6, + 0xc92385c63d6c451389a83dd7a46784f98852b6ded3100b65a8b7c5b96d89305, + 0x222e8105aa188083af23785e36e1eb3b483fec353b832f97e2d66d79dd0e2926, + 0xe98d7f5e45ac6610fd164ed687041f2952e6dd3c9fd12ebc8395a6893ae9fd, + 0x11591f35ad1543a7a8398cc80d8d46980fb2d5a91848942956072a3b58c3fb7c, + 0xfda43471cb17ed2c9e4ad1bcdaa962da09fb99a5bf74024d3223784df4e043d, + 0xa12e81049a88849ad74b40f381be30c2c2e9ec8d8c50bacec5d1868f498285a, + 0x7c6d194a73f848f7d716d6f30acb48ac7baec5affc571b6b8b6b84996168339, + 0x194f847f3c7d048a1937426a78e0784cde6075dd3ecaad21a4d8b0c29e6dcc58, + 0x478225c0df10ae1047eaa6bb766c7cba55d1b2f4ad2c92b579287d4afabd622, + 0x7098d85221394b7dd9d5e01bb8d8fa324f52cc50a01d04959f7cf47a9d426ba, + 0x152237727876536fb0492b77e2ca5083d39421c48dc34e5079a33fa3d2a86379, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x1420a14de2cbafff2579616faf1bfa74f7c6542b053a499ab551a3408f0170c1, + 0xb9d1c211a3135cf248f2ce8bbd1fe9c687788d37dca581e76ef796a06abb333, + 0x2d90ad8b96b95e07f313d485195a90e8cdee4c30fd11b740617caa864d20ba4f, + 0x1841439f401d20be41e3aa8154a1ffb5b06a7cba6987fec7f41df5f92a6bc91d, + 0x2388640642c291a6a1eb98d73ea78b7d176c2b70c6d9bb637abdb842c0f4a78, + 0x26847393fc7364e97651b2b787111e2863ae61218c0a21b8ef93292d6d3f59a3, + 0xa97aa86b7cbf546c5722540fbc3257e37e701c44023e6382785a6b8f5e2aa6d, + 0x1e66c9e1d497faeee46a478ab27fbaf5f9af29f43fde16f9a6385e0d05b17930, + 0x15dd9d1744c08352420e756cc25e76537e8dcfd70c5e0dcc445f77560b730ee8, + 0x907dbd7263cf90b8cb5dfb3bf60610d4fd44beeea309945d8205cdaeadd2a2, + 0x233dce7ca21fd1e909e98dcf2b584e9ad879edeb0f395bf9a44aa7fd588ff23d, + 0x28d0f25cc88f3d33af54d011063c0a2900fb50e18d1517d52d63ce72b435a3a6, + 0x20db88c936bfe7c6e86126581cbf8bd7edddff26237df67c02777070d012ac71, + 0x27531eb0037dc5b938ef188fb167f38039f82f2cffbb8fb6511b05676af6e230, + 0x174c8436d7632117178d777c3174aaa21b1908cedef20997afd4f9de59dbaf61, + 0x610a7245fb111b8632cd43f8d356a839751a7ea383870e108f45815e7dfe527, + 0x51ec3ebb56094e6fd5fb48401dc97a7aebc08c0321260a03ce15a64401d57f7, + 0xe79a17117660b79651058aaa102bf530a98c0fc27890c0e572ecc6d6669c36e, + 0xad64295a0a164517040af0cef26fa9e39b1ea67db4ab22db5d607c4fca3de99, + 0x2861d3d53c2665d9ac962a2a78fa4fe8cb6e81e7ab229f66c432a80dde7116c7, + 0x2ffa7a7a62d5e1bd03cbebfbc5c758444ae0d0734c4a5d667a158fba11a9ac8e, + 0x2fceca53023c3cc3e8991961644decb60806c5e26bd2ee6459424033cbea06df, + 0x1b315dd83c8b16a2aaeb9119436076344d2fa321f3359d6a9ef6cc15b45aaafa, + 0x27c786865b0c424bc2e21f43f42168d668ece1b7707b62b6ea77682a60a4b1c8, + 0x2f55ac5fe9c4deeb92cd318504423f31894b80e6a340fd21ada215856fcbf5b5, + 0x8484c73576645af031da8d059f7cacd28c66906a7ae10ad91c196373601335b, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x1f1e99a24da4de93564a110744d481be210f6020ad98006f0bd4610a054bb397, + 0x1313ce9497a6e074c155fc0218d858202308ed1c1241013fdb1b23967fa23167, + 0x20dd2b7ad2c4f1f1d19f18b29a3ae436405b6866b8dfc4fbbf0877fbb3e7eb1d, + 0x1d9a3b14077a7c4d585632de9c1e0d4a68c71203492d5911cb16f3afa68bd2e1, + 0x1731badd5397325e2221f6739002faa9da0372fef8043ebf93e4627a3fad156c, + 0x23e7e3fe8c10b5580a79f4c3298c8e1862b7f5237942f23a5455d4eac9275685, + 0x2c014180a6ecc47452808fea233b82f39e3b7caf0175687777ace7544a29e37c, + 0x292a5b755731fa19173af35e46536550ab67aaf5f7302a003d0f6df204e8976b, + 0xed8c6981ca41600dba450a860b85784655bc05193481ddbe475de4f351d243a, + 0x1a19597908036c20ac63ccefefe74a7d4a34247f7471bfa743f7d1858c8fbf19, + 0x21d82813886827e8c1985bae1dd3b8377bfcaec6e7fbe0924232f059501eb278, + 0x1a3ba88e071dfb03e2af64d4efbbab382517f94566c7268650899eb6bb1971d9, + 0x1d48d408a857660c5fa36286c7fddd68d2a4831cb0cd055f950be3c3c9607347, + 0x23a912ee06a717208ac5f8e94a3ef1c0dccb7cb14a2fc32be71d8d25e65827e0, + 0x24f16318b8064d97d3543dc09c0c2895745bdfc96371bcc99b5c6d6ff6af3e13, + 0x732c0b040e6bffbae6ac8cee5748cc4b1dd79559d2b84d73347e7868ee45e36, + 0x28d961a33687f15d8e4239aaa2edaab1dcfd543bd30437afc151cba1d8b6f93f, + 0x295338d4f509a0e6ac18622299635bd3930bbfaa4dec3b885b817bad870885dc, + 0x20bfa91fd05c7fbc2fab0619637bf4fed31f95731d89c2f7040f4c893cfab9a3, + 0x40df188035ab2406a932606a391e146c51463a5129c2bc5ab3416e6455dcc03, + 0x2483ffcf685a6a42aba1af8b1c9af41b66796946957e69947f9790615422c61b, + 0x285aaafdd3180b1543fc1994846ffac22fe06908e5a6bdd3fa3d22b3644b6ea7, + 0x2dc5f343de5cf59a69c9429e96289dc1c4c8cf08fe69184b68690f33e233fdc5, + 0x6e3d7b62ce4436fedd0a240d7a777adce79716f5a22b5efeeaad0abf1e8b5f2, + 0x1482cba9741ff1dc43ea1fc5189a2a59fd5b2bc2f1959c164241662658f2507e, + 0x1348498420e5f9e977c9db960818c96b1f93cf370a2380138bbd56e0c9d0d526, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x14fe503bb439d34ea8eaa57cfa1caae71e4284521ba6240b0afba874b93ae8f7, + 0x1f9c9a83a952c1e72697d8a93b00a57bdb092d66ebde1ad8b169343f93c3f8e0, + 0x24fbb0c0f2ace05a5faf061867d2cefb35494ed9fb7e5b590db562486c88b0ac, + 0x10f738bd7905a3db9f0d6fb73b2cf3c4877dce60cea5925d5bbece78cc5516fd, + 0x2a62e245b8b68d45298987ecf40a0a3419ea8653e4da0d6a6f55b2152d85ca67, + 0x275b72887f4a3fd32bea4bbf47394106963761ef3e007f2f1e4460140896c168, + 0x1552e36d16435150e476fa6665c4f058355854cf2202d91573072ba3dfd2807f, + 0xbe9ef904aac486fbddd1b8da7d57f9ce8d1bc5fc7ba2abc179c1fa20873b597, + 0x1e81ddff4f76a1b2dce1bd10aaa16530f8636a0e563bf33a02cb9801d7f762ea, + 0x1c9d6fd38c151b16888ff3ee7dc7a8f653fead50f462a6045cc6bdaa72231de2, + 0x249f6caee2d3f22549b753cc0857a89a85dc00258402594a5ebfbd7235c85a4f, + 0xa5bae6c55380bc6c3c5cef4aadbee3d7ba2e30ace0dec7fa2c3e852bf030798, + 0x1a591bd8ba8f5c6e64b984ad9274257d38caaf25b99cab177c84c8f0ace22c47, + 0x2f14e7a4d071ec394f43f46d60b1552aa9980bb50e7c963d42f483da3211a0ee, + 0x9dffc259c60af5ff5822cf8a170477695ac5775dc1b90104503cac64914f86f, + 0x295af9152dc405a43b353775e93828dc0dd1ad4657f1f324f75e25fc67d355bc, + 0x4ed39653bd52f01b25db50f75b0f9a7868dacf3c6f2999c23bf95f58cd5333c, + 0x10e815500f22b57ba8056deff42b51f4a4130f6e6d364bc1de7117b9023c0b37, + 0x2286d75a72832bab29d58395c45ad419d3d1273062c893a70c56fe9e38750886, + 0x111df543f14f2ae7ada849b80d01be30e23fb49ae805d09afb7a1cc98057a27f, + 0x25c1d1e13619f1ad04831b2339d163ad83da3809a89efc10610d5c62bc03da3d, + 0x2fa4fe7aa2dc0ece1dd482768838b9ab913010539fd9a94c00528b037e4f8ec4, + 0x1950f2d47f38a0976e8801a03edd51f982faa74392a70a0d381194dc258770ea, + 0xe6945795a878954644fd4d36dbdfa856c6b1513c8c38dfd71e3f6f648d568cf, + 0xf15e86e69bf0d747c7eb9d100a26930e44b558de46b2e9246c4cd269f4e0707, + 0x132cccee9c47ea27484dc9d759d93d560988d9a42ac6f90be4737761e0d438f7, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x1f19d5b58c771b1022d6aea73259634d1c9e1db227bd7face0cf3d7ec6f04a89, + 0x9e99a9892ec5c92fcb2db34f0a80d01f93db6675b839e54ac081e2616efff4c, + 0x2e39982857d71f53bdfa8b2d2fd8481727267c00bf284a011e75de1090b5ea11, + 0xa4c0ebe2118c2ac564272eb8f8996dc8ffc649480a144bda57e7c33f14ad552, + 0x25451345b35213964ce431f6f9ecd15934443b435a7f175abd80d97d999fda60, + 0xbbc4376c1f85523bc7c8ae9fcd8a172f4a4f9905d09f1de0a6d48e273ee9809, + 0x2bdd1037469a47d75d5b8994731ede44306e137f4460f2ac7c178bde7bd9fc6e, + 0xf677b2a55e756de8223dca8cbe59954989d27ca87f57b8b8e59078ee30b2748, + 0x2fb0b17b679ed6fa3e528b009e444bb34b173fe18925971a3b6777863a936411, + 0x8e4988e8ab1a27420dc600aa4fd13ea9d701291e005defdaa33e0df72d180b4, + 0x2aa3f6fb81b544fa5d338c2a7299d28d499bf86f77109ef9cd91f3156595f0f2, + 0x202ce667a6cefe69a1d12ec6f0b7674cae7fb0e02dde42e47fcfeb6afc011bd, + 0x13fc451c175cd7d0ac88a8b7013cd460af9f68982753e01eb0b9ccccc2c7b57a, + 0x1b86a2f0867f4a97d6f2ee4701f23d7e05c7700ae53c0d57284c69e170e90858, + 0x1fbf812f6d014d7c0134b54d9d6aff50f0dd76d7889926aaf59e86e69c720821, + 0x11ae5f1bc0b2f10956e35b2a125ded0ea4b312aa52707bd5e98452f6ed0d9d2b, + 0xebfd2844a28d08df2ccbddc8d52e51bf9714e9279ae25b7f7015d37769c76a3, + 0x1c9e2830d53d2fb38ec3fb2cd6f45061058949dd18312b212fde7082778eb970, + 0x2c89a19cc675823c61843f218bdcb0cccb5b9b4f0069ddbf7e900fd643c2963b, + 0x8da85ff8b6200e090cff0a2c2f05042e30c79e425907ad9a055a9a2a496e73d, + 0x960180e5d5ff549130360038aac26bf7d2f5828e88327a1fbe2227194ee270c, + 0x17ea53188c77a5760fd3da3213f549e5a45c743db6b27f4f1af87e4ef28609a, + 0x1cd300160e5cbe7b9cd7ad1180598c065a08ea594897a8b2c667508e93aad2c6, + 0x1b8db86cfd31fb27ffd05312139ac8594e4b9a587927f1d5fbb378be75fdff94, + 0x9ce92eb753807b4cd89cefe94e7f31b0eae43b4cd6b97d8248731cca7817df9, + 0xf953e8b043a5bce5c459ae0c1758ee52707f6f0dfbddc5e407483709df22a70, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0xe61fb7e75ef9295c4189d5926940c65bef29f9460fd6acab96fed3d1be3e626, + 0xda574faa3851b0f89ee096792e722ef02c0e09793b829579e62d43e9745078b, + 0x29e8bfb4394174320d8c3521f9a665b547cb0560f726a0d70f52f613b0f24686, + 0x138864a60c066835f127cc7fc18ad0bc92774eed55a5735b8f4e58f1c4de54b0, + 0xc4061a8556cba5eb98d6966f7014b7f093e6c16ca1c498bab266918efd24982, + 0x29a31f9aaa8ddea5ffe0debc4ca6968854ac196215df67c09fcbd03352180b8f, + 0x1cf3ae0b1b9b5d99445a7f94998c5e59488c6041a6205045683c42f7417b8a57, + 0x297c9cf4083fe500908bd1f4c886306df9b080e77569a534c558ab552bc61a14, + 0x1fee3441a345869bbef74446fee4f51e9303d36e0a3316905b917db8b33ee846, + 0x29f81a706163b55c6e55324777703a9303ef8bc5650160e0f46e5b800d62abce, + 0x82ef985b1721ecc770cb73b1287f745769f9652c7aa177e43706ffb01683fcc, + 0xd2909479aba19cdf059dfd28915cb101756fd0be6fdd65af27163d3d4db80a2, + 0x2f9cd946fd1c2dc74bd0f3ce5737ac83b1071b7d4e720bbb2d8f138c24e9f336, + 0x24ec8557ae626b291b510d9ec1bd354247dc3727f72832da7a79c4fcaf8cbc8c, + 0xf11a41f841b89ce70505543d7028f8c852cc0df7c8d840917239c3724114e6e, + 0x114bb82795b43471c48a7d4f21e17c270f98c6907c37f2fb1f99856266cb8089, + 0x2b62ff5f01bbb491c744a8286db0aded602f287abaec3b1fb1b4212e58e6a4c1, + 0x65601f8bdd487ec395b20fa5fc276d78ba591835f481113b3a5c59b005e499c, + 0x1fc7286cd0168e84301b48ef87d7cab67e45883e166ce3d5b398389230d9ae4b, + 0x795f23bad239c2e465601e109ffcb16e153f5e47a47354138940d99088c5069, + 0x2e953e715e0c47fdcd618c2c5291215a73d3c1a29bcbcb7b9b7d362f211072c7, + 0x577b3abeddb1cba0385cd479d5b80be73ac18ea5564d9726681d8c29857b509, + 0x17f68ef80fe53b639194195275d6dd5671d2016e67b777a0600d69fd4e72384f, + 0x20ff4e58659cb0932f9be3455d13d0e6591b12da8f4c61489013cf9060b12ede, + 0x1e22384181c19d8b6c515b275db8401e900192f0ae54d144fa7c43c0295de2d2, + 0x2b73bd9ba3aa22ee4fcb81ac91cf8ad03f66f640dfbb1cc7b61a83c4e7aa2ea8, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x6e077d5c2e4e5c9705827a87bf1d03ba0d1ad0d1ad6ca1d634d25e4c66a0a15, + 0x121a212dacbbbc0ccf4c3b4292f681523da7c9e1a46e1ba0856b900911e4f84, + 0x14a5405a71e3bf12ce347c54fde1d22398fc616db34d6d6ec57d8d0395589341, + 0xf09fa7c4eeaba22ff000bda61bd7d4e87734f3f8195b38bfcecc6ff221d2863, + 0x16c25869bd517bdef88345315641374ea86e66541f12724938ac7dff3fc14353, + 0x293cf96970b904d201ef1baa8bdaca1321ad3ff0d67548d7ad07287d2908518b, + 0xc5f2232813e8dd413410645a1385493ba715260b3d968149f307b53ecc793f8, + 0x2e620a39a57898eba4992b7a1b2bd9b0c28573a1ff470f544c625a60ef624173, + 0x1c68b64c8887d3dba495c6bb3608065f7b26b8d39050099770330891de2e8722, + 0xfe00e735c41fd0086afc250224c2d48cd0e771edab73eb5e75c58f957082478, + 0x1b668eca521af2f9222ae86819b5aef6d32d8179275e7b98f6b9c314b62653a9, + 0x285025c188e98d4e6e58b0eb6dd46fd1f8d26ad5199eb9b647e99f70472dc4ba, + 0x20dfdbeabb8900090725b38f84f661cd2ff5b11ceb3c6835ef698f7d8e02d2a0, + 0x7d91adadd5a4f674b69907c533d124ee9f15988cb71a732d1c31888924d3729, + 0x22c3db5b12155b945c7cc04c0cdb534db2f8836b88742cb32db40fd0e46c9f7e, + 0x14b640a03dd9207764cffecd90500a5f0901946bf55e6f37b4fb1764baf8382, + 0x1e9b912709e85957b58fa0e0d424c7262cfcf3c0840667012cab0d06542c6594, + 0x1f4a75e965d66b9d9665ddb5a15ad09a9d688eb2b774fc8a86af46fd72796bd0, + 0x3d5c637f69677e08331c185d53ba9759ae018a832da036e31f00dcee14513bc, + 0x1e42641bb29a48b1b9c8a187dd6cdf6ba6029cb0760df90734b5d3bad8e212b4, + 0x2d80ba897d626e0d3bb15479044bb007cb55262149e10f53e63f42a53b3e87fe, + 0x2071abfa33f109a693fd07c4da6a5ca1175ff0413513d36add5bc72012e73a1b, + 0x2857675a3c236532833e6c04c6c9cc91d4aa3e18eb8f38cea6e421c4933f058f, + 0x9d0978a861b9d85265039a22191824e4974b2b113622dd453c71b0b1f8ec663, + 0xb1ffb601c946e8089d531bbb8bc34d4a36e257e8596c47a3c773d71c68602b3, + 0x1b8cfc651b9b2a51849dbfa72c4f39ae01b098997b226f58616383513c76ac0a, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x27d167fe78708447e11dd1f9e1342f67a9d2be1dcccb7c0bf1cac60b0d1f956f, + 0x2d211a9a9b13bee0382fb707a0744ca47b3cc0f5a0afcdabb5c34e52dc8fa277, + 0x41215a7139109b953e3f75f039c3019d9a32526461cb1e749bb5e4ae9e6df14, + 0x139255318820d9f769864e4b9011bdcac24f5491a409c8d0088c0687554d0d28, + 0x26dda446062c11b3ee8a7d9f8383db1f189859d91a03d35e92c2ae1399b994e5, + 0x2a9d3359aa3ab359799d23c03f3ff677ece3080df978214c9ba08836846e31e7, + 0x25571de296a11ec26c7f5b378dbc5837c3e8cf09679fc63da463d5a26e99f24, + 0x2e9d042c2deb3cabd6d758a54cdeb282891e695d463cadaac01a44b64981e963, + 0x1ccfe17477787c3bd72741265e5ac419cf04f60ebab95dda3cd74efebf34af95, + 0x1aabcbbff42769176f05c33ed6e957f6efb3f404451d83c6c107313eb098d57d, + 0x1c3a79dc7ac79b401429b1284780f82052b0217a69adc6ce431fb6de7075da31, + 0x2451bc265dac3547353b487c443d19230f1d4f305ecb2d61baea643f183fd1da, + 0x146ee9dc5bc8dddb22c7ce8a3be636d69c0c0609709b7d183bb8a5230f490c14, + 0x1722db13180d33ba99b8199a7e6e14bfba7ddceec3bf35161a7e875c336fbdf3, + 0xf90b19061d11f2a032bad6982196c3ec2132eae07e73a7d7b7aa1a1353712f6, + 0x29dc1b8c70a75052d431288905d64240c6979f04290472b941f943deb7f7893a, + 0x1cbd570d3b626cbff744b8fab455a37c54760431142aa6780e7b346a93f32fa5, + 0x122e0d5aef6a9d944211b3087266a4dfdc64c2c1e129b146e4b45c93e8128789, + 0x6a2e87f6c251c2f8a54661ac4c177f2ead8c66bd42cdbfcf0642e4b025375c1, + 0x121b14b512f2b6767bc67691906e59d0c6f1f4be4b77e15e277526a51dbe1a62, + 0x24337459df3d36f14130ef1c8950fd267b58a86b37c30ab87d57245719f3843c, + 0x2d751407d72c38bd7803630b12fddc7a076db32d9016d3b0a938231b5f667540, + 0x1fcfa3e97394e1057eb5ef247b47a0f610ed67d67225f4c8a246f54bde575cf5, + 0x1ce46568fc2b31fc458c65d79893bacfb0cc96b0e08b51e85d4d5432e2447e84, + 0x2a2035389af7aac382d3515d999e6a687c9c2e93918c56253c6ae9695d16d79f, + 0xa7485a573492c38febb77b703b0675290ec615974c9f705fa63b175628b8548, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x3c0b95d22504012438e7da78b1a5dbeb4f95569d68fad5fa51f126e434251a, + 0x12422748193dd5410de675c58584a4b6612ee3cb8fd929320a9e70720756cba9, + 0x560d13602278afd0f96096d2554342cf3bc86970f27fc807dce69bcc0b874cc, + 0x1339418b7b039d8e68260015f55b9d91fac69bf8232722f941738aabea21cdc3, + 0x1cbb466b02755d32eb5d7924147801125833e9020af6f52be688e5d8c071bc77, + 0xf5c38aa299be85be03b8f06c2908f0aafaf67662a714edaa407df93fd1a327f, + 0x6445747eda857a8191b68e27d640cfd91d68273e54d888ff057001e476f00a3, + 0x1604659a656d9ed6e5dec461a593c3eeb6a5be5dd722675425cf883debc696ce, + 0x11fc146f9aa45f748a6cce102854720cbfb60f5297ed2f77b16c9f8ec9a4acd5, + 0x22ebd4f9bcd07c59828633805fc99370cc17c8a818e04281fc862f425a83fae3, + 0x51c3a4921bd206f65a1cab1bb83da2ec6128b927e2376508c74a7bba353712d, + 0x1b04cf2d7a71282e57b33b3a67235c89acc5a03e6e5b8c2fc784891eaba9e221, + 0x242de34ed5316ba97ae4f46f05aa9e7c2c1c15dad9dbf8695288c13171bea890, + 0x2046c91a59d50c271c09271aa40ded980c91a88ea5f7e3b2b08858464e082c12, + 0x26cd545999428c5142048b641af7077594238778d17196da2e5c8e1b253b36dc, + 0x256b2f4800071aee94ac6b9031974f26fa6dc520938c96952878364f6f9790fd, + 0x164a0f897508f50e81a4a51e1abe56413d3b53306c3761dd408e1743fb060a33, + 0x1f7569343079826f0b1240702ec507915173f38d7a39bc75ad1c86cf79bd4414, + 0x5272bb3e84e9d0cc586a7d6af710026f809ea06526ffe9da350fddccc09d1a3, + 0x22ac9bed266b94c00d2f9d34f71a2d36c0d09bb30d9ef6587be752ed8b7fbc26, + 0x7674836517777ed3779e8a584732a9509e49db9d94a77161b7870cef981c1e7, + 0xffe7a0170bb48fb6c3e0b80e6244e1d6ef99ccf3e8a3061aa3136b1f7956cf1, + 0x1afd9dce91b191147c5f764300d8eed362eee907616d0bd56c931aaa7683194d, + 0x1ae34688936fcc0968249cf2077a1a982df5358dd5abc8deceb6f33b848b455c, + 0x3386d6e82aedb6f4bc05d34e96805cf875bbdcd9f59da3b3b95f7063442b228, + 0x1a1c06ea0926bd024640936f97377319fab6833349ac323240167651f3a01037, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x30192336409d16bb77389625d09d75f79f82e3e249b9b80a56d541a463184498, + 0x19c8967febcf45820a2fac7a8f7475b591f3dc87e263392789d247b39eb74b29, + 0x97570b91ed5d59d977e8e71ee895a590b529db6ee364fd82bda34ac18fd21c8, + 0x1a4393d778fea4efd093c5a43b4f0fb318caedd91ed30e2affe80054b6cd8e4d, + 0x31f540e1c1038a98ad3b80d8fc9bdfaea35d1d153da0011063b2472004b67b, + 0x165f001bcb8a3a0f9d4e00eeaed05614063d65735dec8c39737a83da4a293f6b, + 0x22e6b223b3e435309ee74f4920584e681c03c0382ad4d4d45f7f1e04c8f1e29, + 0x153d4c74f674e56647007566cfc575d08220dd89f88e9199174e81006f4bc589, + 0x46d4654e5ea12ef7d79ea7b540efd8cfcb0f8c803be7a9f3133227f8b673919, + 0x872d96c258f6400c031024c81eb9e49f1aefbad34225fa5633347f615910152, + 0x15e8a238d295f566b70246488ae7ffd1465a0efd12d2d688ceb2ad1cce50fb28, + 0xa7c019933d1c0a25cb8de67da2926591274ac799ae7a0800e79dfb1a66b09ac, + 0x1271c70f8805321068c895e1e0370f17bd49d7b75cf8e055b87f7615892c6c3, + 0x11356c90cf6bd40bdd299859f2439cd098f43baf710198aaa457bed29b78dcd3, + 0x1cfed55f4f804d76ddbdc211f248a7a7b9441ff124e31bae6f9f7a734f75abc0, + 0x2f9fc15fa8a7aa7217dfcb63bc31e6e9a2ec67668ef14499eb4a6b932234aa3, + 0x682ca8b867c78c917f04c2a7745a9a79182816677c65a771b019e64eff93abb, + 0x21dca8a6aba3d3f01bc0e27ea518f049bd57897f1354141d461b4a0c8682e484, + 0x227615abf38c854ee4abdef8b53b2687832b44eb05210ca355082ae06d9b5f6c, + 0x2921d807cfeed7a85927966f1dd5bf26835d3877c7227ad8fce96f28d00b66f6, + 0x1c9045d27121eb200e99a9df2b8e956f570e7cb06aaa424872e64da24668fc04, + 0x40850a1c2d1b7b78b59dccb79077605dc647e3971b26679142cfa657b3e77a4, + 0x4800dd5d34860acc745f73e61c474dc48e5ed88cc2a6556fd7d8ba47f7fe19b, + 0xcd605cc107283534180cfecb268068cce0e324f8eed13dc548d238559feb80d, + 0x265a4560a8a1ccecfd48264d9ee16af19c125244c13ee626b23d72bd6c1b69dc, + 0x2d72b58f878e0d96fe819ac630ebae41297a09fbc79fff372928e6bf929a0850, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x783e03e1c20687dcfa329bfe762847ef8469b9a16f1aff46e721bcfeb4ed9a2, + 0x7c549879769b6127b1fdd9e119c7f1088459b2444ca62f946f80265c08d96b1, + 0x1025885c29c40db31ca8f1f490caa4bc621924e88725428fbc670555e4222db3, + 0x21f0feca587fe54622a731ec88768d986581c07465c474729691e31a8b4fdb75, + 0x66df9e27127d7003f397e03dad246027125ae6c99200dad3cd5faf2fe43de22, + 0x27f3ab0ce10f55f231d7d249eaf38aa45375dcfae6add9b21783d1ebc38e4913, + 0x1e2dee4d94a3cbe678af8b0a8bf277469150364496efc0ace58540865a6288b6, + 0x9972d0bc51270751cf7fdfc95ab7208812d7e9d93a9b45386e0bbd3fb23c709, + 0x147d3302a23dfa4867fcf2168badaff8e987e90f6c141e92bec278ce816a9566, + 0x2e95c0b710cc179b4e39f3d45c97d0555437195d3e894e5bf238ab9fb9929c54, + 0xedff84d026026b621e6de741849300748078db140c9fe04236c2e05a35d7f0d, + 0x245d05ec0b5dc822bea9b8a2cd6c56da38bfdda0a4fa5744da442ba833098574, + 0x138874360b6e98e6ccd8fef742dca0d8ec44826aacce221b311cf421a6ec0292, + 0x1cc05be64c2f3cd2b68699c52f15d6265d493e7bd5ab4030a53c8be2fed67e89, + 0x2f5edc508ba14e8271fc7fbccb3e7d8750f4322606b2e5dcaac7239ba72143d2, + 0x1557d4eee207353143eed1b01c37806b4f0b6e688069a13b296214439bbe0949, + 0x258650e8ca6e1162e19f92302d2a6e8e40b00bb161c7f2ca5b92364cb553b5fc, + 0x12ec2381a018b71858df6bf6b0c9e02f14d8ca492878055dcfce660c7d915532, + 0x2aecb59a26510953e9d38b5669447df6bf4c2dc1a9bae6f4b84ffdfdff6a2a29, + 0x13201907ff8421dc74e517a6b72e4f997135c8f0e8ea5446907c6fd26f1609cf, + 0x1db130e5583c812ea25e107e27899c895214abb225bb3807ea80232015d21e2, + 0x27db99bc289ac5e1ad7b1192ca0c0f3b1614c77a77781cf00ee2e411835185bd, + 0x21a326712c5b109272d6aaebb73cc74cd389543fd17e6f12cb3a6c201ae735e6, + 0x2716f822617a359b60ba9d853d76a5d051c9bebe9ea9425d51b98475a9485809, + 0xe99f2580adcf372f1c99d009a22816c53cd5272d479fd64016a45e75eeea381, + 0xa3113a6affe5598d9d8ad2ddbf83ff94d56ca7f078a48713d0af15c4529291a, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x2cf67d5d1a9383ce14adf8d7b63005e058980ca148deb3bf0f17855cb115097e, + 0x14182d28f17d764f790f9185a15a6a03144c9e41ed22e8a2269619775dd3365b, + 0x2d63510ce0f51ac8f325327191ae2e8dac8775c05f87b87897e73416a53d1007, + 0x11d2023fe50f1147998bdb7d03b70f70f1a583a67646b055be252e3393bb0fde, + 0xd5beabdfc8def1c0fafd2b625bf1f4eacb6d3dd8870d0557af54c9c98b5b799, + 0x2e8f4e6bb6f7a28422636a7d3b0fe12ca20ab14cd0c5c45c4ef13f326ea5fee8, + 0x1ae5ebcaae05bedb59194e96c92c288479dce2ab43fceb24541ca2648245762a, + 0x24cafb4c21af1cd16216dd42b7e5c42457d5fbf4bf87bdb65730418efd682a5e, + 0x2e139e0df93864516aabdb86d6ab65d6598a0017346fd732e7f895aff36e9481, + 0x2ff83bb2884713055564970f1e39cded077a9205cbd74adad70411e2f963159c, + 0x2552f8295742fd94e0f264d182e9e34023f4163fc929c6b143cb35dbc61a32c5, + 0xb05c0f1defa2ff4e6a56a7582a568d650a7a2ae9ccbc478be52bb4fe3452299, + 0x2c0588283e0bb713ea7a22fb189fa359dcab39f137c9d5953ccd0ae136770f8, + 0x18bfcedbba1f9279d2dbd1d0b4b728a4836b9682905e03f6d9ab9992ee702bdb, + 0x4b314d086daebc4f33a7e8fb2ee578c668e91adff3ac3168dd3183965f51ec8, + 0x6cd84135ffdd74d9c315bfe319d01b17060fee963e8373d1458e181027ff005, + 0x29eea9039c59c939cb82a69a7def6a60623b9868e1a7137590b930140bae4ec2, + 0x1972fc96c24121bddcc76c44074dba6ac02ca1a10bbaa7bb49ce6d7161b4ffe4, + 0x1bacfc2d72d57f6bf695f3d82859859b329b87539e0c18313a1d3f27ab9afbe7, + 0x1069e2eda47e9fb6bfddfbb48d740256acd9be07d2ea9883b63e3214d0ded0f8, + 0x1d87dc8c8e73c38d20d2edd3f6b5abd456a881deeda90d0780176cd7770419c5, + 0x1d08c8a0952b5e4fd915b39382a0ee45893e3c207e339e6c78f28f1787bce94b, + 0xfdbab60a929d492017a0691032f8042201a3223c7ad628a6e1b6340d0893c, + 0x13f25826edf3001e3d8ade5dd2965989ae6c2578b7e886116949553b6f0ce244, + 0x44fa02e1da99bc4866c220784a4ba55ae28cfc47c4b9e5ba488f43b6141c7c3, + 0x7492d98f774f6c8f67583aaa485ac632906a19003a7757119536b19ab78b9d8, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x1fbb89d438ac14128a40437352ed7182d10f22964833efe6fb46eb21b780ec01, + 0x6ae819a8e0c57d44ee1ab07a49be82ca5544d89ab8518f844385576aec43234, + 0x2b3d3a7605543d350b0838b9b3fa9656cb91a84287d6f06e9338154f316cbadb, + 0x1620323cc24fb81854d716dcd972c108ea5d3b062841752a36c994c594199774, + 0x53924bafabdf89232353e5c853dd8b946f617a28f094f9f92badf1c233c925c, + 0x199241c82a57014e3375029b265ea7683611ead5148a8f83a231065c7887951, + 0x1e8b6db0d447c099ae7433fae22a2e779d110bd3b8feca58aee056f7ec325a4f, + 0xb3908d2ea7af26d42a913972fe10c3565f627cbf3b05af7b03a03b455d2745a, + 0xc337f61785e502287e274c817e5f380e5cd314d1a3ce42887dfe19bd20e8348, + 0x965a7d0f2799aa6f3ecb0ab4fdf5f02e0fd5386bf137cd2bdbc3e6aab74b608, + 0x18d8dc79d76890bb7586c65d83acce6185e11ba38d288f4933f33db74234eaa, + 0x2048602c11e8e771bb35415db4519798c36b593ea0b8fd4560410a7057d5d6a0, + 0x2966833633f29aaaf9d5f8d206fd1353f140d989a7214cd13bfed0657b0b5407, + 0x1c6ba85ab5f85ed4b53dc40cedaba63e5ef8006c724440b9448d64ac2b394b08, + 0x65adc608aa6dc0878f5bfcc2b89b3dbc18c5944c5b868dbd6d263cfd386ccbd, + 0x2f5c69bd32960af29ce7ab14150ba089073d74b14c18b63dce9242df8da666e6, + 0xd4e47c2eefa2d97991d58198e147c5dc3f856665f35905c8dcc0c7981979669, + 0x21dc79896380c9936d5da47117ee730c16563d40826cfed9a1415636bb6d9f6c, + 0x11393d10b1b89df9a2e7c68df33f1ee41656ee8509570cd4aec6d68917732245, + 0x2501a832c4be33ce1a4752aa3c3840b89c7eb9d7a2a267b16f076d9c90a6e98c, + 0x29417a7ecc3faed51f8f4e599e13699d32073c5f3865d8ac92f664016060c84a, + 0x1e6ee4be7b5f89fe5eb7f50ea73935fbeebc6ca8756580099b3c9a41a8a66f3f, + 0x24b1094cffa81631dd9fc78b33cbd8d7a93d0269ac60501af8ff82fa646e30df, + 0x1bad44f174f12802c4ec1dcafb6852b6b99dc3723bef629361b5bea594a7e3f6, + 0x2aed2c26dc890d5283b53ad5f30f9354e22804016335e4190b551be5e28e4e44, + 0x247d59448600ad981156c2e19e2be924d7b83bed1bacf16899dab7d7a8bf7f51, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x105097314bce2c2588aa56f191b813fee58479e8b541c13bd6c9bc8e654172ae, + 0x28d5354a0ceb5dbb339ec880b3b6fbc0e7e4f07ac0ecf5348429e1af57069bef, + 0xa31c76780b39b494f7334a7a2ce004b80f56d898ac155716f65172fce3dd454, + 0x1225a8ce4e27af6625ad1a92530a1fdb3206135eb09f679b2b38c13869b9370e, + 0x98a16fe6c6a2a433a045fd0d02346e5c024d7b4bcbe12d2594469a4a7a2925b, + 0x205ad0dfc7a7298bcca92aba3ec23f7dcee21785c96aea116bcf71e07d9ba361, + 0x148f1eadc8be731f95ef81b8e1f3634f44182101b2f13d8fe46bb3aafd2300b9, + 0x4372474a7938acc947df6d261fbba26850a09a16587d069cd877151e287e1d4, + 0x2ca6979a079cb2f455da4e23b90e191cff23e2d76b7d0a6d613e0c1a4507c4a9, + 0x2ca59df55ad4923070a4669629aad754a88b50fbd4643d544045d76148451dc4, + 0x2a7055f1e24448b52bbf572d0efc12754593d59062345f918ba7d90a27130580, + 0xa644e2fe975a3d062ff496a17e7113a395ecf678289de53b2137df5811be1c4, + 0x259bb7d88bf3f1c2f0521ff84c05423a250fc32477823c44d53e11cae6028ae3, + 0x27d551eb8809df2e1c200a661838fd96bea30a7a0b7ffb20795741a46ec359c9, + 0x17e37e4432360ed9a16dcb9cf0584b47ba049cba55b53ad5b5bfdb55cbd36ac3, + 0x263693f36da574e9f6b1af2e2817e803080035a19ac1c2ff754f0f970d20c6f9, + 0x1a893c4de3717842ede135fdb2a63f3c05c834cab22572bec21d57db7c3cb052, + 0x9bca88fc417d85c16bc98e2fca531206336226ba3a02a51a7fbdc2310e26f51, + 0xfe6944c3317d58ffa98fb3a991c22698ff20765d34c2b8b95802b83fbbd9cd0, + 0x1ba3d144274a073e17ed52348cd82eb3e00c743b7d9d3e944a1e3f5a361474f7, + 0x2cc42995586265e9cdfbaa845525177269b37ba7fcd3294074613d2d12af4070, + 0xa83811bff1e7f22000720d598ed2e3508ee14a9e12ff6125dbdb78cf07a2d62, + 0x4242918a5fc9ca3c34867d674dc7d1d1136ffb519de0eace1e6f911ea197350, + 0xedba1a161aae781bab92363fa0d12d8fcfb5e3b818cddef8844f94e9db890, + 0x230942de72fe0db9196d787b929144bf4faceb69b6f12aacb6e0d6b51cc7931a, + 0x1a9561c0d020fb28ea2ebf3851832058ad1cf972e99841f4772a8c578b6ef48f, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x22c0fc9c00f53d4247c908976b1ed1e55c4138b96e9c3ac1dc1f4d268e64ef49, + 0x22729d77b7b881af2f484a1a8438f52cb7be3b93c607310c5038a1d07253a184, + 0x14883acec95e824ab505756a5336b2c5e1b984c6a193d4bdbb014c097734b464, + 0x120d96dc5b428589ffb9f37b5001c6f5915b3ce4460b25331c62d59d65adc01c, + 0x130325a89c8e74b5feebd6340dde992f569aaa3f9350e45d0904027087e89b2e, + 0x16e6e793c81a10719f613ab182ad57ebec76df8dbef775cf03e1e316646d05f5, + 0x18bb788f4ff54dc0981e35a7178809d1f2518cbd12e5e78a77c2e366d0543cf7, + 0xcedee51d5b87d9ba52d6f12490b24cee9e61c1889ef46f2f882644046626461, + 0x1bfe0f0059a451175348f8af855e1f384d1299adfd1f8d852df6c325130bfdc6, + 0x1ca82eb1aa4d6081a46094f403954399af76a7d7dad88d5a9ca921a30ae1dc9b, + 0x11e1d384eb2a64472a26e40594253acd255027b2bf1f7a9a518b954d0de04321, + 0xdc70139469e918276bb65ff8334f64ba442cdd64bc1865efe3e788ff0c74341, + 0x1896f5f3c754db9d8812e99665c89c873620d9f0e599c0b2db25f9b186c05bca, + 0x2b1eb292fbf05207b3a916692003abc04683db775eb3e97bdd5f388df5b9e6e9, + 0xe822a8b6bdab9cfadfc98982d3d27df53300922ea795b29e1ed4e61f2ef6b9e, + 0x14447323538128d076a4a7c5e7d487256a671dce167e1a37f69601c64783ee7, + 0x1731ac8243601c9ad1c2d81f6ca118d479b9d71d03ab34c282bf68f3caaca5a5, + 0x1efef24cd417daeb7fbc1789fc2381fc194f515d6bf1b7a61bccd70a0fd13c2a, + 0x26c6de8f5b580b7d222bfee2f19dbe02580da4e383217b4870f1d4c8f7b692cc, + 0xd3823efb4c4808c275f720c340a733ffaab28c36479978b485b346e4ebb1ab4, + 0x24a2b1d438ee871cdf765b899d2f068811a6f46d02422c133ff6695a7f304593, + 0x9fe29e36bc74cf6d477ce054610f63a43855a08c27b86af1ff58e98c9fe686d, + 0x123e4ce6ab585e748a6424819b24aa2fd60e371b9842355df95ef13318346c10, + 0x257d0d633e7b8e40fa3a0c30548ff79d268d90296d8b5d3e9e7ee4f39ec814f0, + 0x21f4b792c1fcaf55e70e1b1804cdfd952a7ea45dcb9982c315024446e36b4b5b, + 0x18cec0d331cbb93e5cb4c1d4f1080de356f465e2ffb2fa712feb858bace4f5c8, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x1e5f08ebfc9f997ece7730536dd4cff8b519ebf519ad1342de3c2e26473a0b5b, + 0x2d77d34a218a752dfa4b941b63d7b02ab6078037ce22ec0608d3b7b402e4efbb, + 0x19004b8f6ea39ba279e5ecf8210460c112c1a563cf106736d9a0a46b7b842695, + 0x11fb4988936908db3d50905adda5065ee297a7e7187c36212ffdf5f81220f256, + 0x1081ebe3ee722e4f687bedf259ccdcb6fa46420c44d0ea88389917cf6717c04a, + 0x185aa8d933cc96791097565775894b15e2858ec2980311e55d9827471bbba810, + 0x1ab306868bac9a5ba65245b93f2c9b936de449a9091b45f3473bf97dd425aedb, + 0x2f1fc8f6cd473593cf38527156e482897df8441db84c875587c24966f6523973, + 0x17770ba5bd03c9275e2fe0ebf158ca85503ce65969cc9f86e3fb3be24e1fbada, + 0x1d0d275c4971978edab4b7a7cdd85ad72c204a13415f140d9d28b8af514bd692, + 0x1ca07f602b20372b8d50c9863fb5ec9fa033c63eeb293015a4bc91038be3f7fc, + 0x4782f31c8fcdd4898af76effd524fd0739c8ac290480fd0f32ddfa082dbbec6, + 0x68de12e587aa2c26e2e509faea0fadf79602aaea46e45b608be969ebf46ede6, + 0xf47f3f88ec297c36cc16581fe223a95388c7c3baffe6cabc7f4f669bf746e96, + 0x17bc99581c7bd39bae9f593ae1d72e99d7628db94135a65c2c510727f6148029, + 0x1d85dc0db735b4877d9f1639020da87afa6580963e0c2dc95c30a77ec57ee2b1, + 0x27c21a6c642486aa075c9a7757b96e68419cab8ed819e40d179992652eaaf1d8, + 0x1c15013e0719650306487b07e421e718ba9c35256964071760ef99c6b8aaad28, + 0x26bb2e4e2bf9a53e1147608d79a93bf730b09f4e651d6b08db6a509ce44ebbfa, + 0x2cc7e0fa1e964c48a3e0fc90f35e4e74cc01b2f74cc4de884a2dfde37331faa2, + 0xb9c87dd914a25c9d75070b7997507399970d9add413b9a8e4397f46ab8b97df, + 0x7f9ce6c590326b73f00c860875f2c7d4e6bb52725d8e4d6958caac8f46a4ae3, + 0xc289d670c7e2e743fbd60fd2a2a5e3ca077b4bf44df78babdffa232626d3900, + 0x190ce149a93a528cb01fb27da9eaa39de2bbaea50552a99286d4fa80b8e7b22d, + 0x20633ae2a05b6d69d765ab6fc2e335ae0c5dbcac130b204c01f88f9cd091b12, + 0x2543a932d6cd8dbd7533f3bf5a905c366dd1ac737290f6671e7ad6adb557778d, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x22187dc1425cbf505392f976a839df01c17067dd9a7e67d09e9078f1ec43abac, + 0x274579b98b4831b89a42351a2bef67f33a0741af871e3b1911edce28d6b1320e, + 0x2c52925562b2b08d1d1b2696af293157692f2a0b7f34052cbe8e26e80071d256, + 0x2e2f8231db4f3786fef48e7b65f9c890f1aa834729f769feba60a3554b9284a8, + 0x521922aba91806b1e4e13a4bdf92fde9737099751626a1c4d6011cb0d28d488, + 0x2ee11408d02e460309bfd46344e5557bb6711504030c84d81d127a17aa72c787, + 0x175981ace0eca15153600235260b821b4b05013f3e0e3cad3323bd32588b398, + 0x1d17093c739566880702816f776d54eee78164e5716335708fd67bae6407b863, + 0x7a6e2b3a2495845ca96a757a279b823bec23e6e2c2ee41f3ed6705a9df22548, + 0x1dee69a0aaac76360a66e057a8eef5bf7d845cb09a3eb27bfd152239bc8a6818, + 0x15df16ae54e8e3e211eb27f95f7da0bdf38da9530007085afc20553468eee2e0, + 0x2d85cd78c80244f0900115c6f5f5cc4cfbf8295c2a0b685f987144b9151618d0, + 0x1e894f052db0012cb83762d3fb2a824db10684db641c6e3eaa9fe45c9561541f, + 0x19bde06d6e7eb6c84a02e9a0f224c77c0b2cafce0fba9fbfc063a46b69e81406, + 0x2897de5d9c274ad4302ae652103f0d8d3a041ae93c0d461ac15d30d36a60edbf, + 0xfb0ac77f9a6cfe96bbaa646fe280d4b5449eda51b5cc1ac36325c3af0f4f830, + 0x2c3f06f6f736cbfcb1b6927b53543c31a95c648d4828ec34401c2474c932a48a, + 0x23e564383465f1d1f7cb62a80d4995fa2145cf6b06fa2f1e0541effffc19f5f4, + 0x18c139146446dbc956ff95270022370c93ee09947cabee3b0377d1524ec20807, + 0x2bb3b1a1771678092e80390f181fdc6df345e7641c8b7e4932708ac1f332f0b9, + 0x8df0d04a0d8d1b2b80f219c33a9266675bfc080532e9e66430bb67e05360f7d, + 0xd39efb103e032f986c875db6b9f6a6748cfaeb333c93ad7cb45e755eafe48c8, + 0x5f47c6fdbbd7b4e59cc7877eeaf63cb8c16c4dd77f214428dc94b9b2c0214e0, + 0xee1051b33292d8a7dc350916b62440745f2f47981721b80496d2aae0c9ff288, + 0x2bbf58da087230463a98b210824453823aed830f60432ce3156c583e06edf08, + 0x1674e5bc670e98029ca22d400ffc19a4200352fb152c784da88be0b67ffa14a2, + 0xe30a774c353a2cbf244d3d014d1a0e5ff0bac5e242673ae33f1bb2030feff68, + 0x8a1e55de3e637ffa6b051ee33ab203483029584daf0c57c454bba30cf6363a8, + 0xe5b4497c397b27ca78254adc0c66a45514929a3dc0cfe2ed3c447a5d3926088, + 0xbccfad82d3fbec329e684d19569993c855483814fb2547e7b96cf79ba875616, + 0x1908c79adfdad4c4aeda2295a9db560a33e91b01050448491632705b189ae1d6, + 0x1299565dbf2547b30db50f5dd49ca835c3213eeba0130e835aea4add65037abe, + 0x2b4906e765f1e80f6e84d5852f34da89ec6d996c4a40a066c68b6a98100a2f9c, + 0x124a247b0b866c09ee5d3783bc715de3244599016f0fbe385738f95cb5dc0a28, + 0x77d1bac0f5b226607b2765d8d48118b1c55380c60aaac2ec0940afd0c05b24b, + 0x2ac41a842793f693dcffbebc5c08ed6b4aecee7db956ec59ddc230a7b3579c1d, + 0x137d327d41a9c6e42e20bb705fc3da5a282c911c8e7a79cab4e3665fbc3b529b, + 0x2dbd1fe87204abe2f9c27a8343c7257a93e781451d8e159feb4ef12f38b28e58, + 0x20d9cb838e454e9841ddd4792e4ea7b8f51cd7d7f271d6e32f3fa963a6d2cdf6, + 0xb34270663039e315f63a5c992e31d5d09451221504f85b37e1480067fe92174, + 0x12826e5b9be1c9b85f7c98aaca9ce28a870687d3628d60def0ab3072b57b09b8, + 0x22fea1297a4a5f08904d555c2e15d016102a4ed29c32b4bb10809ef14af42c77, + 0x24cc6751894087b831598b5bc7f9db3cbb48ce294d9208e1aa436cb5fa2e80e1, + 0x2cc3d0503a0e1da952b081ba5dc5b117e646bed572a645266c6ec3ce0a1474b9, + 0x11eedbe5a5969f33446503494b469a2b83f88d3aa477e5d6d7963a8333a61315, + 0x189ae9e9b162ab1a19d599cedcef428bd1325c78740aaad6715b710bfac4c1e6, + 0x1aad11449d6e2c6e1adcf9e89114c336c0145528f356ac049f52fd8cb084370a, + 0xd7e1eae2cfec406402d34c259e5966f6e2eb261d4f08e29088325a6bb669a63, + 0x796a23ad6ed2ac995104a0d3e6c75e977ce29aba1d25e62a9a8a20364ea1be0, + 0x299b8e8621d7d8c8d3d6286cb126b34ee53b2dc9a3697b8380c6e47f5711345c, + 0x20f11ee81d2ac9a9ed1cac61d9cfdf10bf1b49cdfbb6d232872a1df1427c1839, + 0xa403e979943b8d2f947f6eda6d41170881341bb5e4fbbb3b4fe3dd7dccdd777, + 0x4646253380f4bf642972ae81977779454aa0833fda36b1822cb9c09719e3dd1 + ] ) } + // noir-fmt:ignore -pub fn x5_15_config() -> PoseidonConfig<1020, 225> { +pub fn x5_15_config() -> PoseidonConfig<15, 180, 1740> { config( 15, 8, 60, alpha(), - [9296474750911444465025945061626611450573261102544117494435956219223872045013,5146180402642819236271333772846779841277266622562021651959982317806096554632,20454733758478774733902661862471466785458678414673417084919753466149262477949,16939720779646471039361700224425387363963401457766730187304254365590145685643,16508379613071589632225608856524646606497744838305343752126125339777944056893,20867355466989514329400908378893992018169546886162092188544040547127653338003,9562028189723224670918372808954372258890790835333923497839294908971703629044,9227509288281899178360094205033853851646604997619773877005168383222677033411,8509781355418257783679010460137433931646066572707591432255985024195888527301,16352397893201944000231474199631274335610857147594743875684031732171609392779,7168331327842901194795012403324475179802342440545189729818235304752196473490,6805437858781519809721294519096505646809998863249026857458359222740400480093,23666102285914319661214067066621928648019777016465806627627356483470384578,4937167589168346771422573562192746031838523475116047879790134471501476035621,1346691375815699628539641638232212515770545677194558930872887124097351576509,40983635009581820916284370715993074471281691288657861297464948812277259151,9682480346612414028382424944197316598030638601235308149341398931369789543950,20156146228109066705562831124708208402478981918458654302206305397911512087980,20244794515708180670563002449620617650597057411850557162891558214158122324521,5973431503164625202944413714022034366590666955289560873103517106326649624937,19003031440781649161524015602474761488168160816940423515211864494962159501828,20712605099727052887180337155696823289955789009114447705180663042338119444677,15751263674652110912724722781530878809312788917232502379399572977178318108528,9759440007076373606849230657528653877996372541705166313887529308971932175875,15753864581145946158736383142711883662973744817981456049085179548487345401534,18516736976984654236711834595195133682620758902795528251669085852778367276210,12505762035583653640932505661921159087471940695093437071026827168265805916842,17973475260212324625956540069233265735155253700466680406635575121618318752819,16893238145591341977099515648275086133943062918579997543738633084157810726656,9669071880586595648023284909288486812190820353718106940661900367937844527179,9349088318894477564190440283477178116641834248883927901328258581942583077569,12186865849936919100247208155624431297953689379595363409626510899600302936538,14191429059221279746000430832297028082244506830783856999765158986408198377932,180235525898780969912044806879591313131227292826139844018949863600387171682,10889092107911649889040150092427122550710450427668385404292705974881857473203,20693842198933957663269842304864226322478103663024796211607837700737760050747,19741631810531886646761927581354810838182866370317964412790883870153217103250,20514964832794580053019916730141871673725635044918093569735954402314586611172,1563081830952767432323468775999289294801679977848773475307184358241727189864,6541733180459084604825913391805383670644609126706479690307729028795470985900,14338950551652503213249338133071776308134322059752479422120853035176120166434,9445962403225070324948180958168278025259517118659455884585920056598191781467,17673503748974627902616087621827013509215108587044719385816919777868083778907,6529067669277048252246949093210874205656745103861744893697681349157159395382,18670351688014831561846153455584274335550086431574922181801742319576494275746,16087198812208315804697003049026004024678636407919712012630915190666161641979,5409244980912243970485734262038475969739470891565229610070736907935180643717,68998709875023468479905615300134369445692715997447916337587330860748485243,20797106660136416987264043187693969873379408007710762405000375236313842719688,5277839105793767851333321356647781091931078040812937205152067116052352239761,19813316014421099365974197500618281012606383357022846408656988057396247542705,14651854807736789020692970167659260203349703129364255901280500438993569147591,1953950121645869390891017290629473806985703435547819703015178261443018199466,16966986407661837074189113052135209905137771226341312735335483526986039302676,12196911666087491240035929989808617508758866763772938948559650992149525851273,6748262588722620715981149705241221174138004527637005241186672382866432164292,12351853389756326378242661122644604232955500481743248231924728979085806709527,2565243335980149108987604508873860765952308183381198225102084152967125103373,20241307878322245036836862464964995816180104231642798486998859049422772672116,6173912854438429518808824631217531662651777757438489861961683800252069642271,20373949892834246498138105881327221987245360841655169052122063615887220321147,13269719501466581754706990055797732063851220874637620573076979035861249715318,1578162066274870756439515512829351279665654675138074205960935197210851459902,15699466465478499203883101572116714566818501168342041974225130392829754730992,11504917391580472762574218883359632564098492996052059988389474392975779673931,2471534962918953214626354556158558932844702538697900698209059019370494276871,4461270721380837522838335428169036184773145514356202591842435276161887233701,17625308215993897091838888595388246859096597033404108848402595233466786865507,18815388073919190191562579690732647812407368396854637581401819367329270645091,18268550843300936597164339843045347137811481798420250960800057984676328312298,7226998309855583456700105258532413039112576746166962016437941756495852856370,8072980663193342911861442510877605529321700341477138509973424538392015970628,15269265747158306563417251524571764365372430081923021726955952481038826679058,19910037920320033458941731683391812599895690039363377502140416867160565960964,15486045363368901308969563040163325835584354680260407824152890548047474173382,16416166568440710996186902352749667794644450153896415669656858302452107263361,16719876352169334284151333613847626557780385036803676145001883066946186048592,21250242709366561537300491285945444276614074599553674495821079421382627519383,18996863118748910427791883574992010505069161233259708625680518449974859990560,17413984989888387572882804568722637770904232773299911698227583956354366272051,21597529235679499224130811468867862981087206894945208547265972184954721846149,17271950603399986802591192304636434671723720851969778588610595038101316019146,6798909530322911571363098835602980477334813891267210720952461019098407212259,15221754151466299785203667902143040752208351220550667002070154445706666401776,9969565572595685753856723561942014758757583006296150732797865871416014191612,213937728610177048236193694412457038661914578783162813372436128728852762482,15615646173777239619093550417838782753019556951599702936217300723011405507797,7718045694050546136660011535056217361530495049313202420611728185159583583910,6681562236645975908164269312121030538373320810986198141132181047805166475529,15406190007218505433124772738477886033924738791369244099805663445061334497251,12748925302440648174656014197639220978675653093966691038521528280766659388490,18792405480956246176786158899722364426273579869771820318487342148987615503627,21034833205180901867479986245412384531166379419487221053266758595893395608147,14993530305792055254503672111497655292586320227932876629369830030730566504041,9717186869050569007497148725820161576480205291215534893842038294586234260310,8846581556095542298416062056868302371695747263219967935160771313384250848220,5719380810982615524673837631402222949910527678512468701059039624789965209167,5973398204091658428913223841081738015584068771535532858878785900515770169284,390665721029373984714826019392824960041229454845430836402699997231854884676,16884099579377843869279635395084651641533249525144181522512029929860550566335,16716976662979247989662403288430439465273241484103184167374388250697744962395,1289338592939287230201589454150014946433268062090374613616251000166621302313,9317927644121595578754625372882467923006787730797841509740916536436754202554,9792346806272266839932159619375452292987210695578600955864989901266954094960,9296083977157792888817756474494818556822681079104304334773148774182988756476,10323608200914404656342379674401080164220099943588034731349775904877409752904,5665882510779783554356611639475035143817214951779938939820232711292028607543,312967658452369621468725894369965307895839161467077935727514890821777198625,20664282841391311519597819314930060269576136022608505709992590417893434920589,5323350315725158992622594066490821193659726275127554898433661812401256218478,16039351301369040724720782620886565139379163954982512295794534252600896786349,13820693026747418768344065399393852077420709727979822490883114289330249839237,13797176144228246839971555725332102191019905588045129521304130064480669479604,20861818286081952786814445160300163171950644955642439845329412070095760317081,6607366884537402504576829976217056754321721309944806800456553075345742381854,16676075047056109258708765855713030298752565264610707737757882684833916800885,2596872657894796835537858907147863451585796495210087845405329734139833282637,1129905770296794876904745792895109768657958745069004656310552795892948378584,3524768344101236852745306230236516385903870540974561871381448404874187920054,990706121628678949689364737717640674078492689689565457695471004362978678643,12808278123975447545284898374625872643451056414444411676912801184092083815084,6358161990036632946294642058872786712712883111056083194592676110308231876108,2793873016535929696420652383221830923887713214117784093571041985641508474546,17305928010614439499134847438771424617226147912488714899621343734884653872709,16284502064199759145361743401051151176267685561605421586130298595070638086967,16669378724978577155412758169912049188272082311653969294949527064226374258950,11861408925173541719238679231659983919027526756130925399544116580983984008351,20319862771317637561778652893808792643716731292949307597222212602977661607952,9965217723779805596104842963458526859730058546126612755023280528059812781678,2231229143040861060383699098560329742848948229177358362095200642518040448582,13286704465412914480712873676020914803973411257385854321890647189069199504571,10047635595882320884409798135378777636448641999630707194378323292740008960417,17087336000400458291414525340830964856800142468906625956701637877370905283650,13535594575282729223473509709844990145664370669908108705760692736046179136608,18619202345418036145538258744454149503028380077256559127312056952610301046510,17607804586369163727645967551963527279187781470886431384954240254070602283137,2633042556450301220705608140363996319867584411611510879359782399294296770849,21731768638998447189300033743436435314153248129574741734083353285598244080117,17469131737454037935821691482173830563221091395109883834897114256467877636669,7750519651616125729362402583651846123740462681349952291880562002377909054050,9447081032000164239615272903502339392629921187510175841323135270498903409976,21517411732531464267453023393592251500842566572268409532461770072252092958721,7876501141846244962862794902521772277174190799788868978106856756141641727971,112943796512817751182977688559740204117088697116147815915631198815244286561,21045605911504121416853713285261007893735116973950420994950288232723845218749,1753558144636632850096274509984476357404441186238175375676398948118672743832,15932527070583999576056453444162361416070384829011926782656187054064561647022,10670345925352776542283780467580832901477001176626927666485810080031890388634,7579612604695836258451031149594628860115515363868399672164640908835805063913,16678286807861813265032290142015890821080993558199809221760573633471452514219,15414078726286200869397977002633905619706559151321201886825291326757189172060,3948850363929702397926233515670425547474212215810847662989169477642088807390,16676527723244281555583733536047809454744760551541688199219131455695588765207,14087355065973222250918209290719451048172913300838805685888196087459492418503,8104074033209440421654249234822181338065658024406724406758136674393332631833,5187207728881418438225188748028865692950088102865770071392557429006545519499,10194509841193628413711183989804813746356025348148221750035788743075560349210,10011332996303549537072329954668024063758462809797094286213034989313201039795,16531650268844669358279021502930777186663937554425443224519161588787088219270,4198803426144178314296362723890875454161257236407666607766866723687553739691,4796265297638646381399181426481493643799772847333437062194249373663993441511,5547609802231005143723955844984958632609857658378828698100141356246667308579,9238958429509576319892727665041354560043563806656332888234436819654598656915,12517630133819614217261779870726755029108748195491643235440705119352058557308,10368014234449326131235994433740216752312468149182650354075154587397704894585,487465315883418182347663117280302929984519597673016955398438666336416216955,11185034244837678424376295011043645561088905841730131726788873681031338174455,7421225151165727634904994585688522807152162423870550118585658136113463984936,364806019968570676099566454292016788351689833960119434834370974516536828706,19587762041779243275917908822520467733740516572707471226884058208850887204874,17699580368555821903526305272862177569486615328343491839828472034082952960813,15739138573269259325517597876326746482937619260543240058947651429318524320399,17749815771695585990262895269645295514834869871993754550237121995617786628911,6001281843453332722738415535953496883454214144943230146026585272790933236244,12226248842279453247400486197034488006724059955941344491855600110495696624034,6471818050024319863197241387509891745688912297463370650154695351698691437030,17643944916136214612858153024594861226464689685432825152621939791565281052364,21110507073644152221308742247603861828087429176260377204494317652281698346306,5767681379026755049166284789191192306599058359643996830685583640018326835809,20268516002780303771030074402103352053711651542638490897887552979541377898692,12422024375924323315232423143442023050941283872688585715847426230444960244284,20694378016149655833849108581703458975143197158248183642690852771732423212333,3589864715711417186674798636588069952164879749159939425060725590030374075726,12536189236026623553502052145542282538682809966098904986394409008189339523570,2807680329090948893979159370041090163078264208853025987363628558807228757758,11134364423913486029994525311335222090667061028008118303028273833566959977738,17354950677485256631166408496835881692979370134492552889236570818914175381226,9148772489395197941519683034415731069796332771510468178434252005940900987586,11051248410353114396778661421385387052304377861539041695630551535039137025728,18136540266852326106685174083549032333515525540247442551401150755180487725743,3985310545130175559232554478662499499843818415947765870117105273186277940709,4596525943567680471287409788454878169502290977680316722474714256040545023213,21372340401058762695712005390221995267277180470546612925471076506446695116009,14075257312640062020412482491643121652025454294874360644194100265009640244905,16944503245314408069496787236107780704688926045771652862339257733069860638621,6654085263135548167634225627185378533095825854533316762555824971264586187651,14273015308464032668640083373269579252065688901233915918278293118708191497972,11764478817260526126925152191588101018315006712336605965222952598280968869260,18155813367404719470487615677791656111973118264369674303621800593085173024524,10850039649283761393985741586943649861203783935137056310000609328911733104269,14974871370837446170027589325430324426484756076474120128444445200816418916077,11027268992558661543645635853060250199670617750348905948352231500166030736735,7737561462151958609897925089803246494900406501278116203687665387696545068888,8536397585289585667363111427598616854125268561779225310999422087929379230845,20520653588911738970276129298340919743898256960050723343166349159335019506767,15573689478722985997422248150576705853901581704550704092699815959211941071233,14024637413191434115623282477558112970843649259330326803453616105375507215588,21353180477994165001466351039795610246389619571796579650797005446278678838787,10956420585038523642301267761059211443146357574323727078003385100699325814188,17634836995596798350536418601573649005517540866687768902898663209263471034753,9073831830223507407321206741538426673038288500939999264368323867070102600399,8100061233881358546546217363648928017848251671613674228091904606518338839516,14292884686436880002999028765738013651173249817687065086024117836878136072418,17843666610704256421074257091600372846189412242040711501888312601205476877610,7418496999733433074316279404200997784331208365418356982886646484553701153757,21292338796777812243292835631771215001169911232666037289555901315952974221584,21287440813442297789932443224883752220885368198719782335487617798315717278443,12316285862536720021079405901921917335504024672055930573734336005894401174699,3187192338760815459509556016254324490807541427929108750144803145054500486833,6482850190067117044880439000213252508905126459059393355671593783930481002065,8071947666795842917503687890154152458243669781913953337362618950188906690910,21450848111897538423936810899713904909897296879883982984541189476327391575319,10587193221429670115264727936502940314613396351335733485096445152378181351510,3385684482890050363671196710999686076700864071377274740326856556910758812375,15982506074704654515559890904595916307715088473006256644287900474899011899187,11051707205631537861946095917392475702553421314274237258592689190929368154151,9251268179161501251470629870144065342881530535654006637177099334228872748754,15384401424299601275458808814042231311961518546060835375991090955541715971658,15147611899621647169760029554894128666862161642594655274320073446753024250644,10615109639224170479859701634647953864795396211020891058926612120687182210257,14404478161927699835476596901422616937403414811611272602635749875651680921447,8066178271733489868262162784101440625233465103401108911752234818690246453789,20248276648316419325977215090702991722051292305169422329958075780094418699373,2029002457916171156303194520244672392499138634810303216935386602108547985314,21075731183134253416827200425853801562619807215475840771703429923133977728069,14328824218343127380036695796575765857116907766196272954596277912518546721093,19160580257616407097132379087560824295215411994049928358528355359904099586504,8132787339090119872084216324271073977022107784441826475259174173324397592845,13163912407679060956610455137901723175820157380216990622789851897632818074059,8592347632837509846508131492057017267103172209796052768156176559923311880083,7893378189384253642782385691967744125589477790209699483381677762080196748261,12191210041395050728454216483522186705806341251170673836903099334267999015601,2618630263994051322846776438484808085311498796047898764787894432257296575984,13304976328362334711292646669717074062694791647749224129724116074506061700957,624484185190294110172011007497433523891084548746061325634035014633317325140,15930533828823189720011923265223664488732840218774700941123034073028585645207,8694885217655511794794497743599831016837108207363203834593510913033381737488,17331704109224667609742217259848258607875799984699711250101367091564505664522,1143531962761362035993655799963451435028684354850849659611727546724143302608,5414384052493950126841753058585655621007207302558963578017856767058437816718,8343436020075567035126766344602793013516161248129384290738181959425998466132,4832334637017830367140676637457267590768883455902783371477346052893423021577,15960489327340978673041589758216206637417346222123069896632550487782527402630,4557633726568362237945959401789921266559833502098724828463753976542737136513,21292745345591415194683498267204047392092318996401128975083535124377610645118,9328286636803072400168705383927986130049573701928015781654594560657277940196,4380226305886799411237881027947999265683595948968607979382183326525427173817,9767464780410766464122903880954110687963200055038905098288212464855640106788,2341077008076389666838372736815646466482189988625828995627083487505977087946,20374148380136094638123722089889049817432074134077941767483383760377289749825,15787533442296590591714142770598935669897792586470392297628568666971956576563,7633568663576517885027652011215374332444473983000466204175445586239040766264,9580455424171239687884724329420941872151195359863514187490663550878551019919,19911295277809179559313541842789165346180998073715101124443882860854846201169,4696263765841909122685466774945153879000521574484303419094957852664345027123,6118063668634440692631158765198200090955204724365488531804099825202234531440,19475295610121478762637598544231725416556110773059271107863119783250115177307,20179584065699439977644558242108004135948300904465438207718184556293527131765,2676625519221951651755843575492662910087680586300055636532952929295968711540,13080027857034076796318609243033548218531614593023186061246772929628249264284,14263363493033688982783626695159053510832721506041125050282934376406154340703,2706925569052822828207630841519123914917406668054471879280093987418440726365,4296262245978655924075197707705805754837595446469608588294115404804858164512,18695068331082119185822574502658840301072706119995753204333012565779354028154,3337114200744822151016415017664070914837554273478224716426789950128003958134,6975962532267211837956893753783559781855104297873769130878094791004904433267,12231027575978562434100945363599501995871801149646690231633189894762835916126,3888650643207658707541674459822797638642380807202524073478543941467788883170,7676102615198465271172138409531332193754467889637067928466752449336805364120,9811623913757464238022803188199125269665959963552692281954397128646993550529,156972936087215783948417984577273879197745728180593700417440323304914519034,16588845615557743733989563376260327418375621586848888397570715079613783522187,12011819284668339582414804793555969540908484357893010282713633444914261107919,9658635959610321892309182692375199095125363721825304507540533137281497868500,12870566947850007704602286722292111587887779596594529150836676091488336717955,17017505534531720639069672825866463960388881234646040969078396172375695830933,12828756987874340466657656310127299330830014385503837959876241551509225608029,18359630725137047619220866091928132852289131876343072040435717392635728807670,17863140285101027979634946030001422306163257009614315954049905801373677640874,3360582341611046517265570944669154454984314353967466888538655993528259823694,17502670755424560054495200659249586316206934247721147538443383457515937914644,13927649797430421409818392324255621487749881718200898095569535249421816857631,7898469048097586242538236499785851298058905177690518852139435937277393454608,5393613856505501947177492775058221051864341377769606207857027894289988034452,3985540196927201732264077382523049411262602519666474163140081018404802939018,9933548682032172763206440650514545057762401680471287764841975167579530669418,4792769546077532311825527426101752293398958175332337087633556291257147047450,5156370681902535309417699137971512021677704826447998658592162481410036210325,4763178997526214364264420973622397594953864683634906055109407846288865926145,16580450694184328601228411647550657642835283837702883837525078295714435399937,18999059441252116518985471589622428967202991051386298987587330050320210739909,10924663926297817693040648165612355343542542868891379772060513577838006191064,21154439824594463741340124378173590149781737214921140238108168355994559155084,19866718036982650474956880892863081255204850747846301678102177541466640536845,5726341152794890743559900317356587749078768834368131432915420083753465739652,9721930072810562138700262351588760483759343649062887160202262013979665248772,8692713109320385702126858931428174471319167530336355188864897071149715822466,17412352102001079694372298819013833514973940827985696439109156982412245617083,12672821032755011921233434696998986247906307111868736700673800862103166163534,10172970004738576173270726006846527765711642326938611469845242801391711907951,9780618262465502284058891490165578338456400832996467543839344602761711940182,18851700024286130309776897830342991020297865786362943013731692845791157935866,1702470413617318930175864989944938294024268866839160834076264568335720361305,4126610465068493007303692923323412316073023198781919888394734000856090363586,18923463588257096056764527998950010226471775437259486940005784970583303111186,21839276475997615446044485384539051285181302015654907519320251876081314334359,8307810470154672938299109640101353533274474986026012646848648110658880568963,21681710504784331775159894287594944141623698915845714535863219742158877134446,13673546849110664891321911520052734162092211680871085198884137808051757614727,2216218889963359247084339208809391515747106874740680794343547186367655541588,19115757323666287625233094721549891816100455942516447718127879700062782999180,9695759088071708435257280035083149593819491025470776577904130348886983773393,14990538824992915759805383740971251128446161760292769615173978580109946105509,13500547160059033639084125020765777005399100253116035721012986936873938870871,11690620517343570003741441631732985155983668292416671376092598551135607742688,14092995167301878045390831717670181419253620142006537525508736966592448309458,3134074644668983555014847848317126775181820544161601574897784886291988720093,21356667096328346522478877399307107750543924879742810010071567516379232573327,19328894389922014017090671733282649341431509867352021154566219841026028128702,16777200051435195914695940482277275703598221309253917444691069340963118078548,12283150914371601398948839801032083610952821665268602559004246563482653048467,8031025780211541530328680242940535108474848337234033825435617391087509668168,11393488534594129202264782038673712630583567081414606145740976603672179543089,9489545274708587303435157546929129885054870357881034831999260754593859728111,6440297901700932642712459656137166095980435930130325599953289987347675780242,6894515864899267480052927589331916028154612433273964297048946097044117290367,16589536620737203892631819952021004148548871602361830198268389856564419047101,4583341011172551024562134025995013510576215116397573125685762514159294995879,5241434939346739917434576806032039711895865193494390109560604956906855912755,17826720085025179303670747265498956093868413968174402515352860124554701720680,14064177224800231170886754123172947484113558685092392153296947056267698509591,20746239761736290080585462212523994318855974409743295600262800987044075760592,9275091732796562047971474774056076192970912855497078395575768670699769126364,19100348980922843718890560618583044384034028895423544873772560921345167893474,8069571373226602742410885815839523915870737256484068502291195820379222033494,1467293981248465102656318727619114500592839521238995988554329217082570049573,6381288201275521270245376318098534380164014423572839901345374016424121324717,15155207472765568640645705040738739058676005958167290460723767903432317983809,11827307205908787524136950608324322915050519697651400085361964512106546953617,21374803923432823385981703420361272374739614104998515368780896432531799636069,1620198401197709963530631727016287708030541032398661971728351531077981225770,4800625217713746765755573372019630732124860961049092382553729057755156854314,16885045113746325978276736698359862381890909478720549186885416774857519433844,18940059701033384450370562570502818829119108154708321114250461189220553261490,17028163572961360646345264113167539623561504425952365941615928454393252072957,1611295667261368131094571297996490796385397691978293531693197200319130547745,12046456112369511110295802643603369841325461255354393474919590204243253663937,7754599975225661234551263660451457408477000193002987626530262268904609507135,2313209556333942391083901663566216617901599085931440197682535151404828238681,11201045085233852526555327068198185072847585214550933934267941732063511616826,4467724481011544137869960218540384367398804813150942792543111067523429032279,20757297420378962887523157926616026028995120570567878138398997747263606554197,17461435854008784993561933203163122288937104371480871856334630516397129102735,11233240529972088933066139644647717712375997842172826165553170491212908480221,13986517480527430903609790838030615892444640383875866009325809535938190376249,4301929714047907689515030408708811722641058401192285565408232097014641811166,17696794946098216231804098416293622660221918490072683908415671549432039016947,7439888160491058128389941744272690247182736763968209695016076283096704865863,18423890552826544443227868172047086037747632248290044990903922658938527547680,2138999949837278709489832079964510183830385901897653052233908704951853637094,8615970277754580973564280361114435711269905378483503993334701750963152744511,1245284434872653312507712347938909167594598148561528981150147522912318212857,16245768201990863935411700653063134435976966358871420800168843470345424885412,12879861318323580145511978223564804504159396722688932396568245995032194740594,2552284675231253239834976615340003107373525651900622595931449498227491766869,980488019139379194961142515231528163966929536082343598209628148732322981564,7264750621517252424008399274736151499285393886075664598878039391991523050881,2234522067987218377738399151771319350093309605278907663987720519875860528325,3115352127411243786318531509959426596747177553864136971519102170874744602976,3667866402502198123848250630765454744061857715778956702490214141676773902196,3070805472938376665214561241692318374677535766486562510422267606125416243825,7823349275852374866499481666710330223055954666864547234510846404777769619933,15260540996982618345416395328474127890176746670866447824367770359510137832585,16879450644311650077796590833984905697151358442225768059780947025899660370589,15320151525992649849875202875042133283365355535963553893454329179458534031485,14632268633016875179098944659717422356155019599115523094512078700042675723400,2897293850461343844445387032809649396366859437152990471719742534237008502809,19666002760225463497556206571085469154515092232825812732816997876615778032614,20118956923652349866364311940594053676005949829436315819799225245413961818420,11744985056755246878773405286931074634975698324846162530423833591918403445926,2015290434884472026423323399096281629968890595973845384920383969402450506434,18249544278720359760062826368546772272198884406461513288445757927068468076813,10696154943059697598572810332978032400281533074175542497867727183214332201316,3971341798054170372777083512695270701169903687966221904151853325481552612966,9959663659512617071119055590004415036736845473755952682208877124936249722622,2181868782404294694165345801562667214869325590275262047722759281472694906368,16543662218198449396015118334228119894116585978443535797616874635898860943302,56444853332991525451220607324577660725674378827134771417770990653696578708,18053264525785010356112278932118420278769989354317119094784720416230380388033,963511433856494437037779480692599956325036862396765985497581773445785537789,1640548195682821030419870544261428767973895477020340173398587128599119014650,15577232677357883687312806010171709394572550002708034453277797023283497421495,11090954381098620504472251563901051846520004004959525348540953956152044818938,17126684395012300883745178409829259734795520186865031009709416122834152378303,8422844186088908124243365558762687987341862957152073183459572023886741121702,14662184649744589649763530324217861015549859438835398957469773613387857845572,21031377022606130696364565229626602575982595290181000993536506695259062820250,12689389963301532909415546365757541009330035137990488344057816579888146178666,5214588312023400585366048036841380932988375130807938893042700215898846591858,15041893128824524382738883860992957588596383766546394405410998279035324015705,782192460855406809992878758154419200401389375934686194113667662665836876265,5661239444927590688224044135973292706791664398184824354673135332710484834774,3817944105257087067488946967989598283409314186886285679195995872866829761906,9462770371773357009169408492776891016388486549772557694482752113820123322232,15769763308905916572724877727092407815390795595917044619305377061254245212113,13771914451667791497863967930538877162560051760275863288476375824988661915333,706561967078473376761233253052150494577539018705821668938338502999740910843,12390235197745683286169097117092390888206044377209705969844343148646378449506,11145596728577531179888406424537808841248238586984730649700720979694309693930,15681641822349110677199695953283484509740812777386467296516920337242539284544,17574569459993920657262688380744386356573422289886331853177778938058648912158,5624326259006122381461763176192388804186780246412847832931645688163746289220,16496277716358307095107833912170230220700599576045238114071305799889738129888,13435082168481898917836725813624706153275101528359222531631402061384065427333,14145359265331851785705850315135126451460028716020850520657056103361268407457,7994845231841309191598369070742738315856499258678582728014902950258896103570,15231733338108258465034981184038200743349384534550555337079556783807466295081,7713361220902077511242971379188205561979775701167781811837114504665826686675,11242747039712276301478013037107867308448907318991409117791290960665848463140,578482125379746689637837359294794469152617864738083364508568444154322295070,10411717957746838375775334848320973308009407649021455865417509560443692302903,20227006425680272844667600313609218155469920109215388465037566152370252232679,4086233333215814731082706125141659248745981704236593522409792368006446650781,6808584534953180557531972017829075410964510413317063595166364533912498333198,14933356623681974917513408843614143743808832277364712291262158931793965369957,8361829936147528340154802497787058714748584629340813748839621641190595526650,5538387899076347863195504194335672966840748823754653039217054113809390157835,6615705984888160955628612086123920128735091346352058978084487503753552928718,4247091362085081761865598677360777173802067597672781739780149117241511260340,4974625254311074298909209418614844254599548567616598303359921500987075775722,9907284404283923304330882823688663208972219438730081750092058981162203620514,14238658152145851054995618234965786835935641311230999365757330392464542182773,5602036166343678358319941150088594172266643715315669628685676756102877898852,10315461382975117983285315435824656113503983463182219407091635205239799886780,18907680493658247637744313142676664986314600274326418373879671192300682190898,8553303723584937031207437681614026720261370015480962759264727133956998736136,6891145490942460969785177369488530687011218911690606251233112277697487049464,19170245246106596353570021916624717497160367167030242670159454715827568730304,12963872577905157066479007532642021260793201956955966146918319119859824768103,19825143672793576100800645640010743262329532693712002233459160547290155991184,122363237387596939334930000068508772338726942066663977131612051418977350004,14083010722716557573128541885186700095072789367734739290283132018427397490175,3438988943822218606847460625826294857914025511956848084069535393649532189446,10824463893276561180588773956898041497815337719354064658470380006885795713398,16647020853733827256761129360155419271528077519934494581063879760642045999108,14779736608400098952280783906738683105991809429340153405681057429405486938750,13142746404873014842415191205878004285381311757484122253939053617110681448928,1386333773150414920705543260472370744952980454893569383627231135209073588228,9697679119976816079822213749536923969219789272727871054723095487806154942217,3460404774244857416356250946884568630025797822298777944076755223444927083223,1247968706400267099989617117009880060043946421405967563604685657862139452642,4507768933023927635709805634829365165299253230159842263645571663212665854586,3426290614024232855381062903753364259178390841306198547519682507770097215868,14446229460062832266543880366376059431654246279317515826580297094759435628761,8067953446832743759173288639514778564060677449303509306198517269476636669111,21177512050925009490126830107933732327927737774182499659239090599165030659885,17012508948587701524178526490941665696519922093511307343255635334215277408110,13790566627669249053646494281027520203709518820977624221038904711079372230598,16958540834863372886175563802155893167203339755555003665356919890498736433754,13423323660143533006628485455163236538714121124914329148003611317540843114521,18732130441148222818743122719599795831305992743627249485606912380686722650328,21744582565522883116221789698750442373155722956313850154199652336110648496029,7144354002506963954801968243991190427536676772300009377345054067229788469802,546773555852952995236535448961524872583912665647152978722419200006698017228,4115449488659159484679292884434524602598250771770554945188450323754895822199,8595752591492411960378746550184866534422481915151040676780917721787338199480,10165757572338172851680092102888140824090130405358311565741520039277283108819,13881202481966783370628597357006999877307398877082297393247431527668438855111,164079380527758195225075822377759030452558671627014461867366308987961032431,16597854725561663920154725753244355279782548142174519652163898109297275062756,18782804026635015341133877400860675283426234307512052057983648925359584161851,11803457827110915157916889714293161979623605698803927824089144848270204757888,3790889121366006080676961526219702764983373811240106724685417109395959845261,547387322589169298813085629174571402766705427171260176930124272482922852550,2250336107342267953278191463235028062291289397936525878162948482155007182474,18878522248575655887331882357174227152771300904536167927922454904180276940063,5479817494658339363150524278522534672218076031607309533533517453567105458144,14471434214677769494999424343272645790653559928767779107202935041996962964627,15118605967190623209837537416237887934162874725496448474965882020979641133025,3039022034764509339398468046956573675942916248030956764556346100611315129267,11040960503243486479242227243433964824049773842453715686240136222246114618507,14522024554516641986547166200505804498300840654246791399797761270595590503741,6835224295711983166071915743041027338226822865794125690776093851440377194137,13366807550844486078755421216059218883003148232530961590657899207604510596943,13252007130485429909186723432146549270562877209239528962258894291232641470721,2492164358128252077612941728095518049849413853275094452844245158937134153493,17908308295682961911088181370570531617402259473536245650574431533231050717409,19598815799287079436414455405296166262841941910574843546435474727483962158191,12296683988787359527811189035096536832943622321600079901820428531954001883453,3034216468239708296411368036093482845790159680213461245275097466511477145032,21365662921308444671672644376862924257055009191312934218262773003828812482536,21643121605272677508602911313799693744649969093302740901187983246336863173757,17106474623853535335864151625226941722837229436558906235895607080504648969673,5170493063367583327862860118856811567748934103888623432970286709351028834594,16157297782580756629356992582192341437261969693717401640006420404649789675283,12726902817862860900369295542623896245980247290073629666117912397630392192361,3081548921497703421223514856379500960238907095191066190890406228882786538855,13383733165408518558908753036431726341720113406574723548828112868926423953299,17114711170811861625673949085444809223764181246137324935055609379301828432643,490084821539048617783395755779188347718107877537460289908857747116706971191,4649874458515161549974867873095987666703831126237318082002364917533053056940,18309757296672459101064597681764458207032523283974093139605613289699615669226,7819183041486966141608141659813055168335432042159899601871834502038946555307,21341796073041881721040729550176895226179046215340279859887156449076052673189,8964280440056181910087237574225882257648057952084687707991537684955336080915,17214415387533445163014526685896715822410886705201252936359885537015585673030,1103535976918892886566275197010540828604931300309949743647411661976344710321,18989472017473838846112035962614068658032619400049135145786394166114140582702,3261305106935504628452223922938937365963307399148885220969836911471709180672,8250352610228962368545929233808273614693022774196635878184474970985288333646,21336821559645974200167373849850832540612240140661136750527391104897925746090,4804442184264650022914507746660662354579855239722797010340948536245079163068,2980351069317208287298989743520302917458165906618872700838358045014403829821,20789178264137518066753395738491570400211130020259232167860189045958431732223,7043197173168479199982037485481873468680373055205806152875339535752299138160,8803416368756444354155108122527515347994446936702934474369040166131196644971,2327814593413519022021694520242495352706688146726587158472403609475455845031,21198136442842149822575509914524766455809483419897291889042050133491478146813,5588816308782619790412052393435292678862962083038610001710149574381906419148,18457707371647662280814248200286355752809748069618488571669726734664943098742,1234389524319480772210519595012254096434562205385972935754568629194134383384,8590188161561261795686801611365857510200794054668578839168287669047410512276,14470989978325106127256991312163042779416463931400090968073878504946069484989,2305522070968512786738458204005001050714630746016184992510479809638463479749,7477355783744938536562522733347415235458953622739577251175967178186753572312,567290291622042941074701939710650764088062581452752653943609540087956251460,20440460641466928749670992266608077799893623138336747959135603955102479614007,3054829023148086310176268593952124817160009906490401089445995945337990758835,1115018683950178281685995685874075286310060333362422341896901389981346771770,7809307874649635295815564328714298840313171873184814252455880392757245438416,16435322760021026161995603943756578712245360106977256514516858926570158830261,15538054347747268689904146479533221617920707373984233068744782064536586402847,2145106610221843472170037420099674539983626911224263405264737836509031499186,10469489855508967606640238771767546316388755621910047798817316247787439887327,19269976274347330455450094587958438145203987980029244301223712026832424496030,9442647357194564700611387347788116150552532746010343621293769302924097756012,3958820742734683830021295040986048520026707752457985546687457778678735761219,11348329600459394107897118896385152488024741286593365288318995787678872184581,7994061748163511046803584801099079098965771882190345699910054751589174660915,17839452077827445141859404251925903822746019560954563061323642101356666431414,13232228834563301156710808377438125900543901439977087615805079133929315161755,21820445178921591403441486524597609508081666751352389500190809234730066099269,16335255581063466649418326314739202718270800342509998411094897137707475468574,7815038267931398026175910302031438514210779836695664391140597883647619726660,6108907775060665614604453427927916450888778767561273091208488690292223394553,18731401306874205485033288380603219954710608893214981010860304692443381676445,9207310842136026530277150017022352541117999932757777916196896007342718304978,4275597059348294910195928059046438407683127030809544814087898068951365707578,8551726143850685533914504884506052366269066663000473253249997846823470852089,17722307737167433007678801800007589919417323324870850217087785924251047414732,9659885913999670803985648240505723928144853579243576606650908903914665975845,4127785260298795455679482228123141201810011802311941172182140342819621401490,7995480315864311476694461046721076190059098585527103653430045699541205743090,2710887853573837837653751249029686223333938865050270571041154550753948687821,10929954836518904033304553904442567770321295457957205208591304372724905918438,14001950425766109615209637768509276336684867788731325954527529665290504740308,13093798171633818149701610236482430519636222108426384974269506295925166461929,341112534319506600537441322030652722098845095671561271148940215817004993097,6110906587902719841743444555887325466851146812889558891609843725163499179004,4611067237252812652698946201052371234192768537459773069641551009583406296376,8813661389433335471770742946393259278020908342551057181562786643750538648664,4082028201221928661179738646263379819458232996637786410627338568216272942842,4387150015663192481675842540873436578480016784260152864928968972841893485475,5798957359608013690581519427700262504660783802132038228115867574470007647157,19722104754281068600204006779633412991974614044671884281702255273995426048636,13237763289640918787304198678609438981723281080085860502804175876747302592942,10350397375768871942356366001436797697061286173475393119069375716517495164748,9716754658986776864790426519095473979615270133917036668138857377100462313944,12559455792963077442707649745319068600669837985026401838048238001273610719876,15691474792343664499590886820783843178573436351948842211318848415073250926238,2315152971409777702150694033027032394728963326020928261979764797562368859984,10145932773746660365948684949555749309408495540108698054181994778319619682499,21031755674184251231918386922772885560228556184297650283520145773416227622020,9656774539408247026483766906298154647226870877463506520381115258572281833777,3703366867036538119931629591865173960052419475390100010069369247148720449735,1155849517605989105668895794996696646805146181003961935923384046079365333956,9462523438649504157500459081869061592673258626587962773726459717365228540892,14558942402093706312345858485376818615887511613771478694966109228129293547963,2812048253376149161843484904554248272181353897695109556171864471465530141300,14581264237688674105789045795632866727938915214983870169917226308316644895751,11806517668379902968824386871470726201210807458248501270142903146174354419162,4072157532402496076820064418241903939352389786658517709744366379045220383162,21813972253527564887362886309776329116642260196272043100875592141144150622785,10464853353887659405357329005361733216328104382848677769669050984745487501147,14772015460668233451710325522019255336227111235340236488781640750731630746977,21527357780259989210243319716428302865642384867695769975035672624351025254966,10891794486798293092627071927690327494090905691269827842959180201330098409394,13485855904336418644657500553650073084861569474830727752625752553358760580285,11448242815253167183767068865945471000243774132210813929164325622036544013989,19410155802742110833632454245227392555968304439001009443806761608484053045554,12167659128474886745250741538637209499739823457162062821474270919941304684088,16680628007927224771777485144832808896272748488695838488671868152342742322186,21298757047923195531118553955836039383942072424271519371368119907422148509278,11697718923718927022148851233178802389523673168156063462791132046990360699116,14786267704709019791824267590492332247783919098705756794174245591027365669638,4029431706248165284072638415134780930697313346853706588481402470852714029894,6637339357364931518321345115064554926275905427738668939829923099637974821930,11721089735875799137502005413616822380279134029969641544449026524015093316862,11258510956066696357188198767462611223354755428568008829233602610737417570759,17382216798452684990847332797566093767764854060615116426813871855967998298795,4497813725838018324398390685637602656336499793658559967801659260213189483769,9309905740467289615895980718346712749846725019185323382202916800724200146653,4554312255934480823406477691403023661425250519363902231000470326223736059080,15877126774677139396238817617140527789790929268045936819000883506734809330678,102909811737053415440204213495606488273727867104784554516589930311835745189,18412616692627375517300170963764173086100899052204830988805458281556342306704,12497849254798953635808071778933029738229621492383212989583296055326390275927,13190130371739872388747884175792586030658495147350847435106581404654633998344,6569505978975360946878354767391913708682729333577071120385232557177773967150,5486573030999616702165020120135398562758060949059349810688840632469582165448,10402649247177704342444720212899468852439313211834653468379224661013914061054,14870393688688048179476829039887867662050219694351765548412705799226912185902,11112866336990864101289111553915677602536611363742637349719791431991672470238,786378775702052024749700197105312354581130448431768994347811552323325137023,12804314666740390639363966758718513558509859637020806917779321368800352250093,16383777838797313001717025761299072170493145903921192845224827276088079299324,18390795790658866542478563024059495583921996400061610405032233720404354578517,19071180375782447479569450482330188708754447860024817674265020413221587566028,7064459298524756483115092315588548572944660746058573142372140457074172044435,1201661337668100759364810191918525473246105501963149603200893010746984240574,14673821426225418930674597108599685172091690120026694257549676255194170791868,8007695637892306475030605880993450528464588921978475145792244443873714795074,11523933430814198704411556653252358930965476928606503642553530463689321317157,4720685254208822524727003349181010163122046826828742211508555904133729568685,2704641256375089357490975523544121554540568505171014265704664461404637160537,17873735287572402838142305036318020439254672746974064930437541429239252592118,15591377870113101853150486245422804312550411754131695747717894157544182932395,18680866424621452161410252746147706712971801673312117262770403991597018010533,351092121232997110902065296627489736041463573095030601146795248738327912247,21410776897919290439576321311168524383878404907590335964810760611175870803022,17236852113726644484641871544732171570702656662638441976539579805457648241354,5141902767347064892821277441749408218256386923351945667768202586451461154007,9061206488410388460545711706154817066096529615910172728152676288649487389209,21501744386281091461333207234319069661329384520296829009605344252699881602491,20523123786355828261901087089746676928050070859811577818342254696196216070331,16340183952833650334331728750144828293293213803155672739442287164371494962264,11997165266626958619141537683193751516111129514708339075256579474097934990898,11727998419969202419125826890516046584560800158309390774599325003825426052070,13931457202894182485995482691171342703522733597260457019434686547274942752168,8889288417892697124945054364222718721845070552969370183001562339292498026982,10607636906736209971474676586549274600168449611294688931553643349980364319662,13373379279879419696628639312899105244563309886546920506727138704477895635504,7516778707927565776230701116353902556324173125006482617300170811322359880287,284142816263687923446544408203711951081978657997111022490562722442340431026,1663629018772009800050577108421747444431944008366135531327269967377988698730,15976560170935104892839671978479711290979780560451333565745657902528940986567,2821894717706045749560970435026664943807315523436547166205412842765540126279,16411046577927712325274395387891881155718376469810123282180259561336053360599,14830500017171075678309056171812981524309710840633235720674153550980163992149,18516862946535092410308127384088576733043708186179828736204273213102857123131,2803122828384011132142130003641446021361083629354222582787564441368260233535,8655048519095208179618171351501333519098495288987579151859877773818991560313,17628029087309631764673769418575149062296127129914718449980855676793923700717,12213182221565572417730092495989703548687597794044608925789870740387528958423,1942254992896992114200957837548346988692238147738540593160350563013662461747,18572481120445885888145197091838633506611989952111678544191205873056195137330,18140911659901689098303870986888083953843757583911874535981587625576530534701,12576912117641358754786901787127955567685279522839676706223096592944048067439,9853587546273100154686512094544697531675085181100931274409412440600306885014,11051022304629047704897656757884328402546597879242426643246383517726104682373,21747178377575326127773834076417831630856635794535286757990250257220185876652,14802894612148412188667842094308733856318572638297904757997514236587913861527,20978447371728675031404263158195920974895558458780873769079890388209356430130,1037699465155917084450585874080268028561047537346921243992399961945112783290,4796870784617170576045350520159043022811420003073563826183620782718648038813,9853767424749529094226213721882427217388134769321854800041359789143412725618,16909978741728448404835572592895383783360498936047937910269991412415349672326,1843438491269241815751499591631260690521017848626075859779071605413804154431,14341379518602865584962107623594010671519157088756134035711400970326861508492,11148607079771922951721552848779822101435560243853139254657574581631328105418,7236118376476006500577604441648338380683405215283131664289729852364085763863,9771089868728917573774866709686459919517030662395798431632764214674312680212,9110797416046523350769719273137039416172041255824880845510758575776777500007,11171998782921300624880315291878283252073139909993544537205045086249176031551,6662646470172779612845827572259867913830316914285246080650610642251248472832,7840073244312824502623215399534211251667887906747521505446844849673459134791,15746172297311038934003440308705797271829102199583540526113736537482577060229,6886137335014489748489631206590121074634704468637741127875111216297167474235,420232306382434242751186173486850411467398307214919587427625546445400284482,6101917029417345450869344197624899835171925047771043819872045680173320199082,20902767593677591005062278004159629853556955206212143592781424915847484793984,5806682782059166443158221425741828463380368530625835045262822570023351074794,8937322067898730475133772449174500828509823386740428196387523130412301822446,10698423376034838319080023911266285836831986186258448454885030311257173631094,3804139705083664873950903601295520892698549383396840546300663481183626370753,11666167980086510761582909817125709232688171970969608229444060852628732414641,5195343484230074513500630640199601466733948553952258905990513870281939709899,14624340714306078897305540751958284706578556105002276099158477226484579202503,10083361130687068583126496521090418135813124339806220406205408201612392141304,18641596433875997766126569678124500204213295416321224520910179376654463020142,2202590858941069122312246576796422760143586439968023643572584733807707875591,5606778593839139538330184356292709713321311150529135965207704575468867770974,11958475164655758519149540613838246197985233378525766327961909142873639847913,9229670488942629146704143920529444712626724835075235979345002293458105678408,16754443145923358894066339463409997111280948017357151500387305969742481068301,2409255870410101963458063337813762581436752424874011147061097403491760442109,2214559337316973031881614971177447231501212859777889339656681156270831720504,11421110362488121690592793129931919017457696830596130693048382951666066696299,3820500999703948691966833683611482557851819710346178343790665741738753374219,8756218158739871072278901807217627680176358846778830959237385752221505342071,8032449730250468861487267430306584116120245106718506069817646852031479757007,10243677923364935391432160448413375676421376200851541463326287529268288890040,1128776597481264636069298358213640667665677523022374620075432951501260575292,5644093261057489381910165706940112111858706948653266534656144218172488885132,10992382177616530304259484530083164550434687278050566643026419033635199094809,14561508845841116001383562169823893923516132174944052932403904968433057227748,21863964650894297432572505174186286520067123468863642727441839125002713095277,20755119936203820147240015392257516486599536773168698212709082762309828651450,16959073226608628398387152299601201172109169744065562346871992262472923761717,1422360831209405989940170583665509252269399522601915800432845527860741426172,17389326678043835536716857792606285368419240597293609647618693076258681847452,12197527885708217940863852882450902665816552534167940448166754267717839462635,21611570070424770005490607477701523898795002037965850794497143400504853790221,11892102040110397810197867975938039639353004723546075702397206087388005784781,13516538003340091563836438322533954338394185445401173280530387106662595790317,12048467357966566407092445451263285920234083860460644072449020638723740218202,1735010081751908190348908571270511873519447755491670766716880879623393561967,1975466263323070433866371621575002630840361531361829342799564009137157551290,14332158763257273099367529977375112575029271371581919959093592722516585473205,18308662877208906527685104306067008785578317983243580533749074382175572194649,16147771244577038318738675557955640363954546932826136022515936117397152662906,12310104474053287506280911462776789511537301762185944649254713583392295220302,20727834941236374148190412755081722896905078541838912474132444343774737989102,4772017368444066833412562265277526529104319024388995968178984274657250179860,21049615822069603562632099674853063708639208121642147875791882100914627258965,17646394174446098039184464463379581654623553955171175600685924254263103033801,20405917523260600357692281918105892289710334792700216851356175227972968907413,1288067623955526969302061242482178260544140652671589048188723078863398511616,10835537730223027316050378066698794099751744792059501849218931290020119106372,20990157274288749983727934109087848093794137769592917583326461140632177148526,16941875865072358419938961334635058647868180482918222959682613586029647175353,9843778843793690986119532637057920745140536160016368781021998854678847780413,5125414792982533413337556654533863770640044560799521974799727390524971858377,10864462495296760172304401051361158670010031482061392973919136670275578530070,18638188379508145413237672170551928898223721010749214505292285199256581752296,128198311352192300389214509562427846527025583978725552204209143056794270869,8639617857907165397429617535993768106671328412853872156360019116822694247239,4844530255382539675437452182943895677920405337347260379412255490567182702620,1804675521808388615789572941859899805904819249465788091888167545049898256219,13789062391664555041422570123657413036572356127853659660401072142070681096201,2984776938673077398183780839702246034953572367406345432704517332443032892459,2992847031807357662780885550148860874749067596604232667894089534007015158636,8223481330716908812358677489080309112433589978061949842348101802357147464280,15829423985005178435297810317464595131483457001231013788201382741845473393508,7862158982782368203916129371016962734683904219117743973675651114828548094092,19398173801438973209233005992391884365223581634877055780725266290648936529417,19275863963890569296158744143112092383404704340976692571347641477470540348192,21372102182460094800056358406250397703306525384763761377034855645794765423371,9476173056510831081934271835896053957562178504127106649888600367232767217909,8945631126280639679924915282277004291625109402912694487894772245410534789081,7926253519938744933656970287399447078338275573508348380139787090085253922642,16018716520675458445608001155996902645263605619338294478505090713237417816972,14921856253793536148329746401088158240205455851010569917169181161371242017185,2079875574141510421000322245042248069972426430967618609676296915817312672160,15980599742048633141868186018745285129739756803812956666022183903444182047036,12114893033109318668956482804227784987572764113979211644064098174620745412136,2810098426330816525728669143855005497849959012191227510766066867001705905451,9142041039259596869436365631928849454803241725030479248178020744616036193428,16789255887716308252460957605463144609726855240455194269099382954389067176728,17736208027338616948877595063010911429975090558603409155923157365536120955065,21150410646727639080649942919157548722144769190804322567561458114897439673110,8728923715723554965990413741235509264041126517176940864777942728557354521757,18877975508697261368601618378333048287851497514619873601021983336084282573042,5857216433172498779920090709564798696432088771454963449283671260189720263346,3416739349758310085403544797458080484340996684307665591910516201053743952382,10014661157797313244292934148350131996657869525790562708237180274791925878615,5349492492153439871560702687440086188179846024931646961141799958661743380684,8090802326500729500530853058367718173141097881651767619458686010109346379147,3243876699925510348842975998823895571182658963945930929780026879935610333017,2417624030466093278001094443901143647464035143208058634414228940495675339286,14707208083442648370683763592077614356382972898797034092783713393639907619177,17545631002841426592730923010822053419499562660641460363423698482744533869073,4421380624161160840991891701912641613710893511150975452841445166075745805974,1077414817249103950943875081715965937853608110732127257676522759590623460183,3507723951294024188735232556852951953031271591466929388169161213367649583178,20744267413157655820488615250021371239675627876287191610069053435816486296093,10030806611757571510773710000844469375387967668887810533790132098599140714696,4098608919187988291739821341638774871917086915024686655297087774191912756808,13453755776490865531134267856063521315028666076529776333450382526888445047611,11760020934758140446049369723964305600159936563536726075225660675360331528465,6406037247037697473727755924858735296546535018055390677906442691851004797953,11557358458236767995494355298696159281191676229524038284238319440638237580594,6743825309135636487078170799646071187521226570701598888088674184356446519660,1363740300261508449387087660891142217813794297057216573859174333622397381039,17353086088993821287882776856791148032337098217763977250246938079060857079815,6718938715458951426350417166499489427024335443629489544367851434423278337209,18987489742261748676564017446964953975327326154943753293417429206546308211028,15965659332352377592570514074534026676650570619443318860049459797446297666148,20815651494112396184410166336624878644932077115689590904142342335838514032225,13289193671002988855733226768851953818541013880219936597636372756289364866355,1567979574094562858336626709833690822884595003609499722973068728155414218656,1406894286237293229723971624858421702390230552459261102967091748375073005174,127524353461789027170460839609791116742773867221485647945877046573898816494,14964917196913210912898635537202273294898388149888129789323384554911752584731,17573975090037837489354042024755208350546900760352759486497415097145199425437,2810800768573675011848063715305835214048305201677436448513685242208560656239,3182831596404920556846849906787256417421227529749874859977287400581732004348,9293221288281284622603029762317683176118521399756060307438914930508616154161,16673727443492180846335195490607282587311771952172084861120865668023189607968,14861970206393540357193848383493197595010751639867769363872113104941368881368,1947459730453714728047065931026988640356317164613412029204943819757651786269,19307336986855330171250472129691969885469727663168817962206758878226019668925,16272723820736869927531258455696258295545428585773733795358621236250129636598,14067203273048816019998838866277520003916774532401938198162316693809632760951,21551507147108044169777874975479534770240991315165807000112720115356653530622,17717640130827927258645965421731152649890280820567693269781156985346197796607,8341245955737785666220035421009659068228682392298228242003714027037157516189,12339617302318828762816142250616108419519769797732290739230041883942137188888,10123566056273217296763559440410478584111931737336670797432668142672222468278,100330409846079023411270961296323123363585075447874304748480232510662674144,1571586856190083814591643193451371280998279878174710717174319810741950319455,17626078717574459956178559042223066518589738318146553446930321898524763562145,12597474837573442277568310997313425097295312228965354157636545560783225415194,9282629691296360927786998265863490172450342562246145699272852196309154676715,11475383910279033220892799115018315595968658540404734297367799982184306742405,21207578382911046461925166339581302823631975619749313031737447832273859578217,9867737209512713742156966231095908977298144995685201344042106615506717185970,5419250263664842635521293741086549956576183663718321466133029062700646217820,10680301618473120824196964202055452643700003562180874183620820959381512387087,11734118782551011491731695279474438578347930162244424307495336916011158044578,15017496989515336959243556328206095618035482039354824183597442359483266217611,6511621188986288868363472995938291798169517601112511039955221592826262879815,1057116630043531259822644333647831844583791045276219751332477616072560117378,19059685203310882657000346272623187407133972415131525465827340360192915270217,658459778905143381055609790895794611242407110015004801647654573954369450993,7603036257465538034144194526422841628761243007297872008772468055256213693455,9990634061622229590998343828576831787715708492431159246049355339866257946620,8811452869339089802509557934124104823648284438116748217266488878838078556311,377338624779519383654026004940027827544698613282452894117899417005371283013,20372432760811032237009833207612531537192479064270437032142982696970398716892,15755624168218886509358985223476988622172061232118179707766784427029774962558,813530157019364022188179508608879306640863329215682533796638454834580544088,15366777101659035236493629475299055460750095122762878608882821037262385854171,9412569363133467481819948072214644683803929543842857451635373713673797937906,7663229432381596357590875498997196481050744300865119408024986926994876708428,2802277205489381760400127515311144092806348374683690687945106801827615715524,10398607437116928120233501860786387490329760704107357815670770315190035281298,7713454417232694103114115606745926964297583014900008700978733395172058088330,13765632281005573885638376819890884715413389187071206345092080625293363780493,8481595129822383153686510359174155430289248263706955785322350737378030164791,19662013748902527903033807785062252860528102610990787703983459073558867314734,9308675917577065974819002737905225232234719968566022906777214056034139366532,4460305046275724592205653945612957908431797179457871442468403547092050276501,15300682822970503133550740797435695997154332692415846288727432330759835456273,12237959719178772655779639362705631668446778143915144512652426042298606318280,9074337685905972785113091085216241647906400276520026931456332814507320753649,5631451392609103370493346239448329080866515797549576094657011047227839672541,2121343968626452536232091590081231792044261748288461026059952209827486505534,13428337287072393077290174792209446111049614088462784414150825648173933048712,7637923455564736402006004688931010233604652911202725935144306827988683195798,14145144407093909228652602933032447693975357132368479264731012546112843610158,12996083206893173697199261663271430611160188106624571072102983887472126762111,1731425456500536573020772566007405873501250425959888611809221924317821607399,7235256019731839713165664289644294928953374624035695945735560280325779220974,21068041929715170328271489788020516757451181357080748023363808822374772951544,2613269578304019608168678260820703130619030694547890166073793773931717299431,2895580764674798551230549071717806800560472156999393716124982187189744328131,18080627279556321451131957341924578248984242962783250736655220087867816491510,8541787229490752355605354050088489559660583814306921152210039891158051673167,4773003619955976464416147076099271361363813479523212833233541104584120420092,3902657294907605469046100206491238707374466860318674919042657295835038516976,3278680356861257827773728996810819308957995332730291009303523122858553038927,15799387696541061708257049935405397874115977721965461912710489016029411671536,772127417921361022785917422978769290675101599783616547948775836973315286693,21172675246800560416431972802840350117631380023487771635657330436402785697771,18058055216124783386618232874069776997923635894599900180049394490069349321671,6486774126469831729812548493701084245613732338682698890925717889323571075377,15523424894706974280109344562353257665535312014690869100282355992032362528753,1155165761749577539253357611425533199963683430668786603835581376097524220748,12293270303409235416382105881403663503297523019464344830582632347870203818941,3805029697086536368150132668072389131584837710357108954351676850002928826418,10383737378445903520223858424352769490012472500810730319338019642336472424460,19139905240360031959084644666653677709382597275601060683474709422388012451876,20662040367334915413974593999171397527205617639639561319218396170856657836909,20693045501044506792047932972050932132614012706885392044610670760209701329210,7646436833143149025181986338139180317049527836176583246163126009131421429218,18468267029773286403821867293367277456399346317458918979624725373649687804739,3368837325920673645463134045719391515049969019513957645401010913338888270435,11009184090818836540140614853735105475441340244881441725231380311734117124613,16438249098211375676141540117467319174575385934122099955146653152842543524308,1978426318655034633621003481179913733408584009919893346861360079137199026039,10835870076129494328875329193612835430557328436367520958854318265497818180707,9238585128656275231406470048000584932169168279280345637986485301554767537943,9860408784513424998732752702463731273076404557148376009384338221275998841902,6200534253629734756957567067039457925613934220422888818001227120423772581272,17839095320044387599555680620747734440255270476109368494374200849742690805825,15852210333828297391427169949742706715097259872699655846272917384634556986629,13333830495117301018203298033441593118871576320662915411592512406905971557482,20141868252044007123768212581882815770873248742867175012988635705853879924105,19536412434762756561256835516560484981006774488160067264157868466806483409550,13376474825075395326396381198361278687546895119831914117080307993251668968861,5426793384935877497416931155195289044246814775306615779818726668069304816143,7377826504693724659923090551901604172560455391003832805477022207542742841455,15304023433512090811722731808458537014494291201252876199903945357536893662723,21332460757344630529450409218029849205820804076582364819572498755186176235236,10123770219692666599208924625777509883271312561577690589112346574716432563379,19563297971101084260099820862783813929179580711197283960855071977068075400435,4447207254069026895839688542596519844298864167018271339727580848327164733569,10805247891957676953966507705079087855877568284903068495618773980630496028625,15247455859749071900237435930523136345408272002648820316650110622790580875976,1523513713815340967949299977561986680730112913862622151113511170812079722460,2250092345142769832690429177076582432571233932766644284160212961505086786198,5502205194489637815685308301009607192191278776537698439488907603617260091996,12376110094727246736838305034851207905481280418572145688559541407100489476563,10967543165217223191795950135818653456591208931427429972754586323384063916713,3007127915385490247377746617881910295130312971235615226220093403044166435816,15039810425747682043693978030807314591772830040893968588297240388685740832440,21282434502237090849892927101680045504469095017581606642683944529102929897154,17820554077495649709432871866725766383400924076526622095222498536082233385393,3238921346058569633798159055732162989904755716515207404910193961449538091755,6963065779232897395043653410311694992252845745677523471496668662716409139923,12741150889158293058202855298380167280366511627706735086836055155215291856874,8505231440570036863755136868680092759740858472921139738784962359970555463386,16263867309272856871859017360735124501630350380225439505739588230939592341511,11994652030543012675378700484156120788799454178056174639173766735729691200407,7531001745062176388176369578077819605743320864253593427909699809569190244306,11827863847264026226445842677102655786795007713756694062525124054010199531855,16129429107591815909860445595042156146087129962390514833959473605760944146527,7516787161495467824155321560594800913116855117833255279107222188682607365695,10052162714097814491117037623656731155747350728656529965818461926126557689689,15866126693591846474201863966897712396582450897559972801925967203045783070614,1769345590280238074854062499047542732649300047644326060581629862863392048630,6419881722518831944067972549598430355215508824227908646199374367237336336567,8427762909619307952658968866443552584787988597438819510120993141703552873807,7893311334904009120458996652611823451343891633360441850908461624396886564456,19760139770663625588230394835227131962944058142185140281511805786245566094372,3986819882418057034478817109485859706183862449050678809809350743539886112292,19462740190201175689471975116541495793256811137828607475310915853573746549315,4950984269438746319161544135494005780273536398471035822969257463380210776783,5114126436371649572151778297196722433397981560175541938915777654399517384867,6500502433233986724406965295441070598123907669991330544723786166137230830713,16317287950659298477752416750967064455139776512193467637272228586615836234506,14644311768591599882243015624322844079095287900058309581805861693953854143586,5280400910054229241086158902425292691428494311972092134978890627089874392610,15127218399002910266114392708998449241113801821878209170134753716497261629315,2711401246560501813405727886361637939228317090729002412066290100904319360960,1913027325164607464956755298437679573731669261937548387089448543475389709293,19048913840687946111515885036078245399510860136071611921573959765837451269059,21295287720552550910280526966903203926240851680963634134437049744624969307301,3797109693086078196558789257647252246485873371501397666934942661912968057995,17220092189283987679009565165189257352830222471797888201205665583060198133070,15728859045813610297052814756440978974533041326711446421367132340721185641530,7915246674314292718027357038683169057328569313936589479968179748005116348962,3168535062320575750000050980968432832479836571078965478747377498891053785750,13803986818738311305292789973880566948405947108749390476554600214529398575121,2887021549045614886550633658248390500136948561362661868354602793719521054017,9835777853770722919097370759265493857673816349027354889969484370501195735082,9162920843634529872148328448437467777954760966007230180656824492469148201817,1074954035830520777949184022573483523978030205622574039670230048399504082838,14573949395382273725648387764764104587706358354270169802238874779976052312087,392719645589691148855449884443988672799862378880367658864925364810308158541,3685551641667332817505970777889874263257498648047179005679069858878239338060,21636266924388678043670779518381645484139129597308274177295703055588816929542,7321567536895702720774368439707249290671186165402244403568878177007380798611,7172839196695686167303608986523055739039297465612557351529643226329584487820,4229778574282653726990227569322645489471840372440828936529243607112035640074,18782302953492985194605877986375464862209789031757664619583780308051670003641,11974809482173143458078984920442199204778548823433238304966088658895546634996,16243115558222486864600123441049281534776025041710213515085053285162975382052,20774412501254836125508172987964523733402936236671082985700605339729723682856,1483065919525318072073144044234229344901017930590205131905224416619628808251,13859608645215082985012618178187462696738961393768893322969190913266642570277,21405376459105682082984005097612235541120033931778677874212817450507078023807,11689238963312530686999514700594656275688886785400717773550428094425955677451,13770805346049970815658755939543097628223982878203541747699103196190562329538,13464128750778834946158208517080192694313764854534278881787962107045396572111,21407849640224904790247752730042846775377573219483807581870525715728151019912,17742435015936027530371893290930447550842976399042348699434701387859868436168,21607472280994630036571403820711131618277491312399185275464826427174795496015,7688464458545967396781600592854525549649369419708847302997939388491317131965,4387376978957625118504779199367262576455322502411234315349687321331690532595,18931911591990162605728772083755015441650830148575725789586998382906047952930,14640568984073443762298448827081280142493018130989596534711086636304928257387,13306842042380077440486698326492089142513016713060879132515526658677539077869,16831808713587057769987931635351931409992316524094756901264732606403438287007,11322415449116068033081427912158622347193126836157199640557951056169543153666,6851604032522439802523441319645962614365864202922586227207366934548805743971,7865033453112245503939716349145002950003125074081779764874079104952011815860,7859039670086457402270651853161690366745490673814388503748678622683637617076,12915205729177842184089675224634811499690953326168778547490092950902372657871,20937773388247481346344394224147944853257697507105144044681818248765914256516,13287060897761790924722969858390853273555324655965292728828260759103061260482,13306896346810583848301553492224587956204219709116827141735317644044595737290,18219814232296473414944129594782177430971511097498319923644038792152844524438,5428298390273304248312869576101694361963883992477060046151268450358678474516,15201216935560530575994837331432805679558316705524948725894686934721622162910,9185979018761703837993382762881735970994413889163208925197647077666234876915,19181785293325954761013200262201782189994371972312628530578184844339518606203,16637687071791710254394571978230957592057586799407792249481371375691006025241,7540695380854477789623159801158526233798259867148336812702557598270412992232,21033749924623312349444484016552328468392604073844480133610758629121621931608,9900738449713019488539657454744856913719757496206137183076543026413680378482,20521005306019974539700555774138941983710853964949502636832851583991666071090,9148625417956423696904186924742393962087070575705980963607554918018064302410,21162567363216498523188025354796572574708404245885103426215436531517848841283,516078530341213545969683556809078278712251743628535410360059529914040404316,16846240853341179628895683480146570801780199580812523539736983428470139888117,3725063466997152760713869763783030250548722164672702170123853642540240150907,15613553480222544404649584760559934580548305353382956847869893563076098726977,20351109682633578989341194704546173168875553988784930480177729322649037322556,11996883326331293630396983616262966081550223706386102455796773922602029237495,7467763103586466278784854382537524995001493410600869109792768087664508057830,2017508073008218056990628353468704346479637577205333604607959225275229259220,1314798328573144515884513072855778523099366140621231925682355151505185465849,8723657373526005784062072282873485835867170661363188128978957400998918352651,17008566456391889354408264184115222893038736754092176958021304795161250142258,1277201481182954066723110290486484624236238076832533331201564897838632505678,2883326282329572573598657327001707359250291449257261775578634065330832194673,4435817386812736743435792142021329255563452933485604716406076651024269234049,12698961373404268899870565736817085990987024732021219796534551825706597317720], - [1954546571818731885139861264947334230782822161673023234242993080695489129982,11606713580838194823093847718802359011098299538034455148401855555744041817997,21778217939341959600865514937973379081571132553754734185669152755967486158807,11867012199835162777599593543744285374463489953452947402200134749407575327780,20668200962959535110219664454556867828577715202494491079283962871771719016091,6796938349934826085352626361055311106987991567096993611616805270698773290279,15108030096316731537404525399718062561401239877230837132486990179727134215091,18618583058942935584876943765894457772128324732451762769633954204661267055617,7446958258820445329937058505234183740111199633995331064868799738609505041620,11019126795578266009911151080068316016022306110283709712693862589215772062237,17644961526468872013219663511656737898249108220341985100127433673616476030536,4959721361611533340499147366149623398780635086479466110353420780375692399477,18273613083607267201259595982191169247452947601227995394305633285537292365096,17816466502776842735116945485728134149282831962573761460376746436502757322332,7013781340485780306773324480395548266877763825891494701746512901494705653158,7793291197073594006386853421213450159077336220644997691715731402410704643042,3426005025972529257284910903433598760993095858232060658495826014698591260944,18530832095369567225742997294004908129637537286260217494648426754251364141983,16489909564793485793960504581924093693287639849995832883358263301067754354184,15126602449686250365534081130480301443166072957206187316416707568927051456663,13994979972845996867477162556668014834350043400046615820474382058282820089898,17892071176071030024436108339592708638442586845389229765280031864359446154887,7094246519433675669226318744483462997736245331529142696208838903133391196837,19739600791550679646703071148379836779124671330492407813260108679076122705926,16577895124793812992345966235533166228538388644746952252700985971901794098608,2190990407832635064016354900528055762572032133913345251583721394536626731922,10838969594099257399038118686024400001327577210604256394537002295046250661365,13742554186879139633322968994905507641568437399912823098239782636831322642395,10281113667801091149613944447670705624056560574926411753502305328318932013688,7661208680673970050246952651218127022141152720979640414729369551173790735959,14369836811580283035547554195559038793886958236571577920508487931208924192768,20603628573396476191496332378884772502350107937108583985752646932901407759112,19296916296835469264085474516279583782033370007674993417080564950885860980156,10983867448590555143664432588641225682254935452824608025544914671100236945380,5670198946055747149234813634846142209283829958947146164536023332201358566553,4904816432035963931263837796941455228547544800276020247096183162764093041386,928528370618860212551901809222389226336726628142306562102221490519648216649,8727385187994811157471310113729025912812882704232858255495018737569420129281,19909768217191699902186248006262494556099457367519802119733085801884256380544,10635786582281955931244778086998962127059196955758207056871772748744817883737,7140512340052162441606422433836236465795273624186668144911701254961330905493,16598081311443832517669265039250197623929992506944409626575335140315057620768,2339664320384903939910962081546057089170206846484766939921698239663651706239,425509623704802982425483674266195224640999670982140442030650575449074971057,7922384239142329258156226873732902413897900318612725000714450267548570680404,8178140403014386057685967488315772252114289881535707170540858306748328725322,12689293740944871195190670877158259851710828253354810002997981152414697198513,13670630626216376948528966598720909229691593992164633421606526176324419533442,20189490101967313329851160663874367593390331759675962821030507426149184002493,18209972608416650990264895614325602746017028678399567737887116829945804399280,20353660437114078502000672122042327871511027701339587880609263231648053792209,367135858451744056025051491593060073950844607000402056456474235270560576836,13355850760886700974133527239382497141869096511168824351814359808886023658462,7206193356029734986150290058613471641978817208643432940709861990432648635433,7885684183122679587266799938650213096329650494585142531776846669540995068168,19085115218990181267812208821832153255121894513890241319104580206329327134131,16305675470941528258170184941405206862153955794946952667798249341324791515500,15443626257895746936982356461453477742473783071787883800166168668037169561924,101832047855527584987088220264952346019960111874606050409415217845556024488,10576438072746903138917852030571732352003417543540340689583487864994727144138,5996861730264922256270512962050361669936822432104376503237345294243995854540,14877973900502178557219336745361213333854789301797456671201806787562463919326,14807962843542542498914061591358875654692300327506360640837865566998761281322,3133673265931719924452668737189159279894652423873815799856403146721022028744,2314426743898183021393131908284299082806555710249089245305873178073379019830,15353836455896084897563929713128028858175788390437902641700134508986437653318,5529981971838869469294842442312128910934708838384001405870007618574232226406,21863108219378799978996648633069571801923287451100447450849597846874069699478,6773528450923012634292634195479655092490402578779439394568805920957004744133,12150245180431051120309675366247495517352377611113958096501103925281912163211,11142442323884902255425165263749428309435092933107089893872191462936441527962,7030165611221942623542847326918501014233687676615371955108018311000952911338,14168907664945894221515023422776939138433274836712427741726190314020662482321,17973846874050037633502661848899122581090847479984048542694367819419188584711,6612448947387099268202244798863603173886774177350810153571814261011002084641,20765273984039816245168454930434370234220284726385931011063596091927027011108,12525833775624943075128880966259784896817535866921245846013552547690890352574,18082141488353658073882233625595393585704703572017716887747923068948432979709,12080205172928213829055364897249628749790838461826174687455161036760925324146,10426041417079669712788047630796875947997831039494087898318197116078426849054,18333367395418670733687742418586004501344157225223371831515062599898496336393,10666844346085567030848134043176991777319226647942683934134661343455999941894,20287202184725945519955164847740850432153598475156573942705745729215691030796,17942851314410450183054332374663618442963349517519641485232231950262698445043,17672277011389568686180232934337352157780343745417630591806280730146798908966,17416106918062278234521335281965623696779795380548750331807903068461573518054,15034390385078628923681181367678507353936042776187855843799428131823528700439,15016371809918204032764565101078018512566551812562861502095795302834732872947,8176229788878503959342848267153225222150151339952249831413185552792554528595,14202549166569309182319866775579092322766621157492056208423752359103429675445,6628758202046565882882491271332141326521031973243028104017889062740759748530,20267845326067450413789379016153439637066264448919236391605812427944953078755,2438946774028723892708023594952994993532105735189593503088246493623252811398,5327774123437518227973303235331602588839413198088244869937007412210139714640,16416517260868931624699960600760845305546648577328049221217547593071007584547,21691457642736313179352706050711464825492028639914839210493298427277168769684,17369736170805089474636304643282290719726533149056710536120639858255935606857,19460761623902421883797374762298555710671254062576987287084819867262496770119,19770570144034267396127078712986043464609355920552337517533085194608634179666,20904722049832148410244764905538463264520496768863784169293376826852051688706,6086931305514615639236334006857789100145606465861722355610937306339550862,5885641636117295888159072068000551173102681944020015073964039109891861226751,2197549059218467728366947205357858398035068309306368786367182781869500529089,18571065033075196607590252486530861399537536653506142751073877421696969841444,8754088881400442345643534933850221698544089985357770542959718766123813634810,13673463077059539437815915980077307152850526782227553623693374041649724049605,827897346385894242944663854685785871137033256170575635435612086616249561082,3256718342276213157296321691616951565542440296040693556287210483669841487973,18851058760089844863118102177423730353882359970674430675542303019981882750705,21009037983427297652279654800570889577926790955118786173230430780907667982896,19370673591737489444054265538393258291592098201577177240415593550679982651270,9712794467513451079466753095103777002587307366322848872714822737566534970868,2452976395290300719873209484043914405675637974162415011707015440506646332236,13967023770779438454858978860214792451127045212657472381516830319420403024355,18974770134907327058718913691556562240688992993972407935785848010954975834526,18005343276101020422248769804338953747590444642920980587346957205121649916277,5364199751574723768938730543610903684616886041855996090009230701935892264768,16915141432748433783158989990154900013143930156431056052460984382677436665679,9810457740455050658326943855759399108575402539560713791636000764640385927272,15711844859260073612371012979328688796642677336582424352155989490394966892994,2523486975208775388230636032695576725855997180931786065064150527465407276212,12939257203114853364537111886847673104871159136302860798643783368852456402126,18563343508729873190283517746040347988882591986176993103658794343898711153424,9139767925154848725661711816797304370425590863714334419686930754659416933343,15630326979358561783620795846763021145439701823262337294600523076394775855291,16709031855693747432049197217266634836607267701623669179857743766059308291076,11081746589259753124653594380015131650915622160245647873370327872758282529429,10263829532434991046602117509549967441368717347217075372460446855507340910410,923380097607272775621985864770232207712801803675470117823528453022294342573,7060362012752050086965449046391069479205357779670943566418766734533864254186,4238871118210220589598309748597547342336859622832314796736348778105851398663,17520061366255155846404852213753339526277619564174678951991892080505590972066,10513625869281904114245087023227471195681135249236672625281292889978751612829,8435396899666453466602702234562279601174578748121165208762270334814881381944,8088078454252433245088686773582075061475116946251984942060002979516553775360,2719987334353537600366656327639544587227927648913835976421439609622334518069,1024019320641379568207362641296952564452568447918936948059464814762366331275,13889412498086825909291896540147715217051215696137185869382874120375855480535,16901630530096437974516169843541514517956751790577876352535912471650304576719,10977539500432168331426791033212854950231005312634634920276038346698892818211,3226460659346175003896135924099734866664778523605375090881255390738403665617,9695421696482260394078309163365413177132015345359377667904366174083251929056,11269053203885423427900382169641426379373759430258387104391167619152696936070,5178750298399029508026924620615685679610392082191932524033828050686124044833,12845878982355860044505488053971997443594073436267126888909625977253125523142,7530981388399357124357431126610695946065175975095472306777796169245607001944,14058213441446348117716607452759269076404820355922112411973297063005877380478,825603012201903073682942337154197674883919500964784037574585377691889312422,10236993586198323123785803013039327931978354285685191819502917433935835639701,9438970111160688934509448828104684236155844660381402912193342504181825365420,11536612122721678319037657954738688943272460041908847457419482683492719528721,4048128893355211133472225346691072554088570917135573376272009214966234274059,17007960555125781716346334106074020327440615260084049810189285619997415816473,2935744638594795881476272405224480626548498961519135317809162650064622710267,6384493312721061401062408865799313573644091862395937725107886310975229942194,10507848115923740198082149097677194763453026968238422206438345199258995348681,18755782391252715265425541321566381935042481942506333926799033963914433188574,1622030934879728521636669415221999170954870898240640125007128754133416241951,19178897048453000979590659690957596324038669245300140765620928017217201486492,7668471074291870526245483897884601792626426080083647233981123797699500787980,17022938204221917796509718984925895198444138607270396412440297468084153383727,10938747411001421463106680010228586254730710894241856448408311145676137003709,1892143994611253681927160695719312882099525827316460372080933907151205825399,2626413664304179483436880400231214693597358131317388676910101259191110264005,10976814250018194880310517382191223839713741375476951941358522267556104616194,3267603976137604608815546917515683877598008503122930381370588099122094818035,18223585230504941070194267966378685287221743128395324427323638965512681791787,4055897021092860484143383650117982675609656498724344612791022670810747280835,18652001434191198724037217430343155151673545332667032591923572773249520166995,1179210983342192637294098069949454912191992256395734070923896011947222260627,4403412539347069757548448548289536146089860634393235869990028179479631393017,18208249577016536190404023195559477353692681610041814639755282640930299265764,5253459060178003600605009461295776576191151024266914967218417406063967602725,2110599375707753504956307604156004992055199034205281989577749327575131764193,16838175205667561737978735977781331049290662487428014461885404122880770700959,6473428079010461623647807107937762759737150259352991014918746820779470984847,8337370031139132243770630686523670334344396638842630818638144451253681713442,5852133535345551978469538570221409138541345120679970583582105205614182914641,7693908046708935218171096369565374697059710647347392990894755587360287791527,6754690467826351700887172852005234976131445583530162984365436173814346372178,4362899351088205531982963806583486557201252717995038448293398829823910923472,11518397041006514564038599401506526387562942749501723393674197214904315107893,20606341697536003623317613291213380804130123512962185582210369767659416485838,16897394754877405156789353426985842311670174197348619627467370676352261158652,11049995264887964858828368499123384474282091734658191426291499678845498016770,18903841016151023909305743424460730902070062204415137089939274033985227379247,14501632343069777665672565757138143573066425682965558756989443143462299059377,11936194426294671569251421865691095594275214629276606276242590758676139955663,8684782852463301178275527204056308121145836348455196441596832143888384190591,13840275015334112173632265864573045139112521216777064496416258170300441524371,8976112149735004651499648151657522459186187854485087924493254571044062238478,2557541446593153253492913007582627823644717754910327615163106890559828872362,17214289010670114093415697072867115184169717632618753776383803280726887828982,9277044732799923560347274951803854995664839245943597020159605756847120319168,8665104485244718969383349524127237156930430459852710098382428996861193438718,2966017993337369327831105148290320997881600321998609267125699685969931023637,20703140915572601301330743722461592884427012015286406537986295678495182028439,12415056396133226456247587270673507158810318408454307171336801889305959276558,14096884501745579659192341381525893498221351476730589189812251926483574089240,11380799045102603249740262962085086862746282867943901718244205293076495402152,11397463999860523006350413477163951990037313029979805067679629038011006323456,3989254560279764593104713297200294887781503399600736805260233256187721580128,12670526207690537332382598355517632246478654103765566238996179271593311461311,3183711571356392622250181639411196710255078687860623143026450897732409025180,5610846600257417510307213084599977483933519996901968341741797171439650039141,3280606490416179974005759319341626407586508917823138878220428529454629673364,1201982324417186063031536229293952219287079604094432487446300310977814955299,5320694228353869326806779260357179675523748849691821041819016623807887766991,1117900147109997141002482710095589298468009897854242933473562031850755107739,3423874914270570048663861326353594445564054387733265522218157141041404209456,15544724812507000325032356684034497915485954044805225704411638706645864153677,5773122431233952373926318394008190376724448498619094117536291976195311877322,6101823265492636176451963193766486622777300610881276372298697176417958756135,15795396300010870823125638802470599845845464744307444307899702370966825169519,1323789030194931509684647858838729962688902410898850967128356366290242773839,5751046064881673173633677922158261597917572500845688735304279201507132509829,1621252171583823353515150633750260236914561977816101468910968069661001399932,12193773521417435700759146251386454694422997324768376620870510312596267301181,6582582178277044206368630428791785430498389945338461249283089656681050213384,14215781677876725356925186332463972498447213260700771466349787162195918816425,5782842445406193701766362226063474843566378485612132749823957396025995938674,5452153017648783662501027666999013472879951066118424395570738985848450672673,54899108049022846277426184613878330780751769989719315816516065174629128493,8847320923102214377720246218239804718366581789144394009065472718259977212062,7818599458828105010909362503034203380908251186730393621503231459166558068065] + [ + 0x148d9e4542066b125da6d69ff3fb676ebd27e6a38a1ff4281bd639c97af6ffd5, + 0xb60a28805324295fcaf51bb88d9692372cbf4eef1cba8b85cbc059346691a88, + 0x2d38f812ad1d7ac79c32fdd57a56edb861885f20fa4bc6d0d942c2f41e8e4a7d, + 0x25738acd1163580033367fd8f1ee199d7eb3c37891e06bc20e6b476a0357588b, + 0x247f6967fca42689ae8e20b5a7a198d63086549b78c1620a51f5d36824ccf43d, + 0x2e22813077a668b2b75249b8d515a3dcd93502006694245bb087ff0732708b93, + 0x1523ea89be61be47e1c36b0e024068c28c48da74bf7069ab2d77389c83d474f4, + 0x146695ce138230e087b53ef1bf81601f2591dd344a7cb509f138939369e0d1c3, + 0x12d05d9571fa4b4171886d9c2cd44c7d7fc5a4125195e7d28c3c47cb5cb5b7c5, + 0x242721147084d4613543788977111f3fde6c89326a556e35bccd2a2e73cac68b, + 0xfd921ba8395a5dde833e6dba4173385007b38d1af5e3841a345c9a480c9d292, + 0xf0bbdc7a39e5146929f2e1ca9fb4a63550cea8f12109c1d82e601975d581f5d, + 0xd65008588b2ee1a4dee0313b6d4396952d901385f2e1afe6a0a0def765dc2, + 0xaea567be31e1c42ce33f589d903363a482f21c1c3d8fe50fa6df018a2dc7c25, + 0x2fa334757b03dec6be1df758ebe0353317b35316ecfc72934d069f182346bbd, + 0x2180dd9f972b1eb5e8819a843d24f650e8257e7a8ccf6eef3fa3d744b16f073a, + 0x1787a3fd66cb49328100d3574d7070199a6bb88b84df6e9b44afce9798233c4f, + 0xfbf506b6714d64dc8623fc0cf426f918053ae81e5847d3367ae7df02293da8, + 0x14f57bdb3ddc75b65eb0720e27daa09412b30ecf7b115e8162b9e55faf49f5bd, + 0xdab0bef8d2d1adc80dcca581e1891ed800bbf4153eed15ce71ee5e0b0bf940a, + 0x25f6be3a9c5f2a6ff32087b2caa01b3a1b7909811f025196f156319239d359ac, + 0x25b541b96923b17550e137a4a5bc0d544d00c5da7715c6f00bdffb9bc56d0dc7, + 0x2b4ad0860f8c3c432f2a037b0e2f7da7a4a5b3601044ba24a56b5b9a3dbda40e, + 0x7d5817bd123f90a4a3c2d77528fd9366321d8dc69988458cc425581c9643af3, + 0x13fda3b1d02a53b106c4ba4652cd90f466b97acfd136c9a8431f1dce531aa443, + 0x2450fd6b1a17be1ec4638786bd3fca4cca4cd871268eb07b1e5aeeade36fcb44, + 0x1c0753ebf63794a29dfd83eb0d0e76f6d1ead583f72f64c0be39aef9e577a0a1, + 0xf110dc007ad810c0fae508899bed20aa5cc8dc3d8324f0f7bbc3995119daf8c, + 0x30623c2f24a7c6ab307f0e88488a009922fc2b8235fc741526a4d3e6a59228af, + 0x1d895817e78f2f1f18e53130a6ed8bd6e1d189543380f691a969483f0ae3148c, + 0x3abf174d2075102797f61660105cf418ded1fab324bae35d136b17a0254c01d, + 0x237478172f073d15dba9d12cae6433ee71521ac294b54d78eace7dc941b2f82e, + 0x180f820a7408dee73a72ac02f7dcc75f99a2b9f75a9aab82377d373eddca712d, + 0x2a5ebba744ea7a6e8210f483f0b6b61c1feecaa867c8c11aea0488b822772614, + 0x2282d8326c3c12e0f7575e1acc4bd941893732e1e7d3c0bcddd35e366edd5f7e, + 0xeb67d8e687cb2cba01552ecfd4fd7ffc3d5788cb47aa3887a1f2ec3beeb08f3, + 0x176f406cc04bbcc4bbb82c56e4ec20bceea588f1bef8fd757e1e58d47545b77f, + 0x1c4d0cec6c8b22be0f1a3e9e32705a8a221d887ea0bee1bea1a8226608905658, + 0x1e35dec79f5a579a42f82c45b1a191147bcc4e3fd02f45af412eddae08db4ad9, + 0x75c4a33b1289f7923abb46d7a684eeda712004f974ef5715f4e2b504397e9bf, + 0x2f416c15f901818152911089ce2a96018e79a8fb7f311c4c6a4d9ee9f7d8a83e, + 0x7a92367d210292658449ef3d46ec96b982c3448053bffc8d27b17a643f43979, + 0x168799e51ef2e7c7b435a220052e06295f6c08b1e6b0b5122aba31e2d953e44f, + 0x2c422cb4040ce223ae9c21dd7331896b68704c26a8f4ddc877bd0659e75c8c48, + 0x29966fed42c09b35591edb4cac0574441dfcfd4f52bf0cc31b2e624b7eac280a, + 0x26ddc145a94457eaf0283876d4ea7d6bf10b7827bf3a684afb10fac1d172894e, + 0x13a8a30590a2c5d476f60d9e9ea7a4c1783a5fea077af03299b8c389641bf4c2, + 0x21d12e7122c437251656760882eef8f3168c237646f3a58a51c265d8b45184f6, + 0x271a6257306b4337cceea57039d404e1996058c68e71d63ce1329810af2da4ee, + 0x1980478607e68ab7961860e38dc78da21f2e453f89acdf82ea62ad9295d8f625, + 0x260653cfe0ebc0562b54b9599ba00669da343a3cb3a14c64f86149d8510df8aa, + 0x2c4fd7be2751f8b6129d997351088081e60585ff012498424b526483f8372f98, + 0x640c9db6f458697dfe17610b0692908cc7f72c1c0bf5cff33168c4867c22a0e, + 0x925e62b7772164055008f8765b827f251b006f2dd2370535df1a16e872b923c, + 0xaf4d8cd74eaebbf7a29bceedd1dcf0ab0d00f8de6442bb8626e7f04b043f40e, + 0xcf6a34e2cd376d6b000d8b0a5ed004e7cfcad8987f3650095f4d9740afda335, + 0x1e75dc69b7b94f915b925a773280b9b3a2341ab9069eb87c883ac87da102d9e7, + 0x26bd58259c27facfca63e248ab6a130ea9893b53928f3d373a0a197c5c2737e6, + 0x1511b6c19aef08f6e79cbc7282cf4b5d3eb07aad10b9f5d65e005e5433db1130, + 0x26d816f8378615ea31b08673baef673c5151c036a5a34ff11cc0ceaffe4ad982, + 0x1c38d60817c3a646a15d82ede53a8ef821ffbeb2b16c8feabd6fa7ed02e65c2a, + 0x2ab192357923d1198143414d448648ba1f60a917f4806bbc2a4ad3b2617ecbc7, + 0x2920a902ac2c11523c9425ea2fcf9cf430b6e27c0ae9f587dc9bbbeb96536352, + 0xd4e9bfdc6f8dc1a6ee5aba8e5f9f67ef3b83a526012953a99c83edb0ae1994b, + 0x295bf676ef95ef309c1d3f8dedef57582ec317807a72ec10674adcd1b79a1717, + 0x232180e854fede1a3359dc8f1a5e14c3ae7b5186fbb1a3f6a6fd9f5252351812, + 0x2405a43f35d247ffb75de7586ba2287f9b057bb321bd9ce9bed8c89807d67979, + 0x18931b27ff3a9e92903717b2eedae0dfdf33e9cb5f0fb10a35bfa8f3badbcdc2, + 0x1fd6e10af1b3189d42548c7ccb93749c4146adf3997b8d377c095445d90af092, + 0xc4772ff9abefc798f553554cc392284b2a8ac4b043708c183f18bdf6d69be41, + 0x227fd4734e7471641aacf664825d3b15ee10d0283c2dc35364c9b167ccecaad7, + 0x132faeaa250b60ef57f7e0ae17f1799fc9530ba5e6f2baadaf01b089595df9df, + 0x1fe24af9ab6246e0c85104cc31ba59175c60b155647623f893718608efa2047e, + 0x2f376b18215290f25c3fb987cc89569a3f18ac443fff16989678e205871becb2, + 0x2f2fc0ee912aa02875b096e48336411eeeca6f3de85152f51038ca291bc0cb18, + 0x2cad38124d882410c386b4eb1445ffe1c73f7b789a273a9cd266bc232e4c68b0, + 0x52002de9c04553df4716c46a80102ed453be8d5bfd9b2f0ec7c1d3002a7e7b2, + 0x302d680ad3444e026b06cd6e4bf62cf7df234ff9e5a46c48c17c2937507cfccb, + 0x2b3a9dccd38768197abc3b4cb640ab3c01206f49add14d1d705c371c7f705afe, + 0x96a6e47d4345707b5c25e86c8a690268f5e831e6df4d864e1f3fa90f2d8537c, + 0x2e2b005a0a54d0fefacdc8c153e84f5cbb50ebca105fa0f0242343fc4893783c, + 0x11c8ac2a7f796c7852e23e76cdb576cdf35bdaba6918f90cbfe7aa2265554a95, + 0x2c2e66451aadb830f1c91d8554f2e39e4ee19b15709052851f481629bbf12b91, + 0xdb078c9e2f68eb7d8f869554da434b9576f186dd943b1f586b9be61a172f960, + 0x79328f87f73198430e17dcd7613bf651afdc86b514295f7c238d2f267618abd, + 0x57924e8f3e798044d6591af796b74ce96bfeb676de3313eb50e0810136b8b09, + 0x1730b8bb9dd03d8326981225e8e51fb9237e4c03fbdde5f0ee12004339b6b9a5, + 0xd121b54def21112d91a5bc9fed5249f5dfbde7c63bf2aa63d14cb59b0dccefb, + 0x13924c1b5bbe6d5c01944d682370c13cfdfd90f17b55f07b05860713ba9457bf, + 0x1cfaf7ae08968c76279003598eb1f7eb6b76ca3efbaa873f21e3e0ebaa637ce2, + 0x20908d07c87e65c8c66ae29d2ef20f8b8049e304a818e769a3c3c63ee4eee0d2, + 0xd225f408959d91768201fdc03575a68e7a855939852c02cf64e3348fb383d42, + 0x112785d72b09b749a03120b3ed7cf793a99ce5710afd2f07d1eeb39974f03340, + 0x2dc01fd745f8ec43d61a5b355b459750010ec7e6b4a13acdcca627d7f6f6babf, + 0x16f35ad4dc8075f6c173b9588be33839ad67fa5883783b0ae6f0601de726afa4, + 0x1bbc143e6c93e6741dae37037285fa42ef8dae0d6fe3728b9e92e79ea566b277, + 0xdf7e17da597a37884ec03429b49764d9e8cda46fd656a122f8c61d9123d4aba, + 0xd73b0c0a745dd49bcddd632d4e41f57b39c28db722520c24cb3d9ced0d8ab33, + 0x263f950c95141a28873f4ecc0d18c82b89f60e7042cb3e9f128cfc5f03e38580, + 0x195e19715160d996ce7464f95db19bec2c71c02faba0f2c6c5ce0ad748fd3d3c, + 0x1cee7204151b6a47ab8ceffea244d1928621fe2661b5c095d1cc24c1a6579693, + 0x29d7696ce5bb66f2bea6d55ccec4dbd464298d8018135f734d115430cc82c42d, + 0x26c47c18b71c8e81dd025369e12e24ccdfcec6cab974c0f86da98deedeacedc9, + 0xfac9631760c0b7f0824bf81492797db8cb3f5e4918040c4af17a4c042b116e0, + 0x7e7ea789ab2f31184f5a93820b08a4f6bddf02fe83f7c42a6af69a6328de863, + 0x20eb37fc65efcf8d87ab26c7cbd24ce2b597e7d9a73fb6f2b9db3e0775534bc0, + 0x20f4028b63bdfeba4e2dad61f4232d2a584560aeb71bdc2f6c3929a7600d64aa, + 0x60e204b7c08f1784b366a37a86d0d8d90c386989cd167fcfabc8c2741aef9cd, + 0x408cadd2b0c8fc39ccbe8366e16edee16ef6fcb00bca0b843681ed56a6784f, + 0x1722aea32703f506f24c5551e3b591dd24fc4ab9d188c149fd1b75e7b90dd353, + 0x2b056ea316811928d984e2796d56842e444501dbaa8cdcb546af5de36364f4e3, + 0x276f12a02aa48133e660f6e93ceecfa60a529dbb444a4553824b981e3396d169, + 0x1199c8941c5f8f8ed0cb67c02c5e014364ad7f708222ef17e82378e4c155a8cb, + 0x28a3d2a547967bbd877ebb18ed238e91706b259a1723c1e345de5b545b8a943f, + 0x244dde50ec65e0e66cc3bc269ca9689e25a89c5269a4b7fd5137e9ab6b7b1be3, + 0x18dd271a54f6e5ac3aa02025470b4612c9044be00c51b80e347938a528fa9d70, + 0x218e424622d7d41f3362cf743106e890d8d2108695e25d279a2e88beba3db8a2, + 0x1f05c5f5041b178a54143a02e8850a9e94625955af047d9e658e7cde580fcd4c, + 0x191da8c6357930716bc0fc614b80b71ea6b2540d14bcbfcf251086764f3f6e7f, + 0xd54bfbbf8a8cf7c99b0aa8e6a688b964e50e68f2de8ce26038e155ac0632fdc, + 0x22e1e8bb2d7d1216a9814ff5454f064d67a9c56e4bebf7700cfa1b651decf8ef, + 0x1f0fa78dc7e2300fa36abd2a40c858fc10ae1455bc43695d121c187a26dfe7c3, + 0x151c8de5c4d6b41254130c6977f790f13b73f6fe786f47d32d6a0e098dc8ca10, + 0x191451e550240b9f0f15a5f0ebbb360ea9b98c6730e1097fdf6b7b8028266433, + 0x88c58a21c4ac05f1169de675c2c543cdd22bc1dd06c42fcc4eb890bf0e518c6, + 0x1e431a01a34cf72247817b3c5684f042878c6d8f67ebeddd047773744bccdcf3, + 0x8a6ad0a360a0f2558f78abb268a4c7dce19ccecf989a34ad2abbcea4f50986e, + 0x2fa7d3a514d879b93b93049fe276e60716c547d4f290126c15e8b666224acfa3, + 0x2f352d9675da8d7c81494e015133a5b8b4c62020898be4468de2fd81a4c2cef8, + 0xf6ebe0388d424da0c79ac329f4b571cc3fd8d5bae54d596e6382da769c4fa6b, + 0x1fe4cb5bb70a9da24e0f598396e434beba5ed2e9ad539951dc93a38c37fe3fb6, + 0x29f316d8c7f3c8e7929d30849ba99edf66e61a2d414e6960081d0114f45c07bf, + 0x4febefaae3e20b5358213eef06d52c7b7817a4e5bd8db4902d2ffde8868564e, + 0x4d6b864cd130aef3a066bace271902047aa0564eb05701efaf55d1f218eecb2, + 0x159747ffd019c389e54acb68074802edf33332662d5dbbba9b67a3c21dbed46c, + 0x2116bfbf5067716afcba7419b07b3315f0ee9c8ddb034a6e6b5fd2e78793ef3b, + 0x2ba76cc7a25af15695fadb8fd7d436d91635eb3f251b2b46dc317c8f5060c4c4, + 0x238465fd273e538d938139210520a07f2ce3bdf50e381959486dbfd4dd0b35c, + 0x5c340a5328ed50d2b10d24af11e763ccf9d30906e5bfdc2a0f23fa8f23edecf, + 0x279ab61cfe4f25485cea4bb3491598d816d5734e391bd1a3edcbbfee0da1c6ba, + 0x76e2fbd39d4fab2ad6de8d53e70194771528f4ca4018fc56c68b85f041568d3, + 0x75cf8404428a1a38f04accf51f5ea6a7f7d7cf66ee412149c23bf4c4e61fad2, + 0x1b45baff5397fea5757900b2499c0aa66447e5e6372253457b9d2472dfc8622b, + 0x1a39fbeff40b73bbfff7232c26d92db4afe3286cff840d193b4256a66432b09c, + 0x1a4d4e0e68afaa99c0890c322d58e46ebfdfc24808688b64fd23ddef4e70c7f0, + 0x24d619da14e5505a0466ebd24a766f2af1fcc6fe2dc4bb58440f618d8c57a7ab, + 0x274442dd02cb4d494bb38c28a42fc02494ab3eae56e115cb3c65ae4aa728716b, + 0x26a9f2469481a594f9b546553c12df66c0fdd4b4637370cbe695cab374f5f115, + 0x19b6db087b1cc1c4b765e70274236d981d5b022a6cf0d3aabd478eda2f895894, + 0x231b94b5e1f8eda3405c1a9a05024fbb79f8722847c8c4dba6af33b0b5e8d072, + 0x276a571b8b2cf637ae48734c01c30a91890729cb137862d09b0dee2f255c5681, + 0x63d0dc1ce85c55433a780bc6ac9fa8bf4511ce6c37a121b6712cd8905787751, + 0x1b5766499bbbe4410e990a078a5ee8d6ad5c4ba9d0468a056c10e0df4f3af63c, + 0x121b65097837a750d24e9dca2ca61b8ef80e1ef478c3d4f1cbff64d4256da110, + 0x155bdd180e1446723320311ebf6ce1668158921dec0c5d9496888eef28fa8396, + 0x2c8541d4945a6610c164b4a4546b2f3b9bbf6dc9316b5658927b635d8bab8589, + 0x34a08d31b52da90215ae00874307d421ea20c786605ae7fc87d0be172b8c3c4, + 0x12552fe7124ee6d20886a7268d73a94850f06a600448641df55b08e7933077c7, + 0x2d19c9d4694d594c5382702070e7057a9f0c7f7bb2ab83ff684810de0e2106cd, + 0x20a7d7794bdbe939ba166d34ae843e1d84eb4632122b7fca26f4e341b0e28b29, + 0x225c213c0a3c9addf32f0c5bdb33fd6957691135d84757b4c44eeba59469e561, + 0x2eb542a5c77f34c674c1df077e89408f5481f4133e3ba62a4b449cf64f9b2537, + 0x303a003af9c1e54d9d3189920396d0c752c9affe1c17e3fdbaf67b3811fec7ec, + 0x2c42a27e94cb62ffb6c169979d09f39387a9e9f9b6e9df71c9ff4165a8ed5673, + 0xae6ba5ef2e7dd64e3f24af20271927e95859827e9a9d32aa247de70c5af9835, + 0x4c58d44d2b14455273dda0c92739446ed59599cee1a505d0cb3631118845410, + 0x2a5c4931de9f553fe4e020755d8b5c10c12ebc234ddd501d6f45b1b2058373f0, + 0x2fd94eb892152b5ac3b73e6061f3a4f952198f3c330e150d4f44c933e6c8fb38, + 0x1b5395c281e1bd5763201cd1c72a3b5db71a99ffcfcf7db793704c0bb4d53c94, + 0x26d18b9ffcf39ae62f03177f4639f37f569b80500e0bb4553466d67b46342b82, + 0x2c4eb768a6db2db295d215ba0f81dcdcd77e0e34bc123791c03ee7d391812b38, + 0xc2e3f65db73f4058ec7c6cc3c3ee5c49550dc106c35929f0bd2d04590309313, + 0x28f15a4dfe1c74ae128ab27ca3208dffd9313d4e87a759136eee3e194cc925de, + 0x11ecc3e8d929c5be84af974cce44aa80bc74a16f13e9b9627f705e3929fd2119, + 0x239d451ea3e39517351019674cbc2a84c6a7add8fa6080371768859e9a89f275, + 0x2a2a9313720b4adb8e4f5795c3224053b31bf2d6016d9096e56cb87f01f81124, + 0xc0089ad49e3644745a0e3596312b34ba6c0faaf19e362bcb56f4a7974c6db74, + 0x2ee82c31a946f5d71be03b9a041596afe624c9c6a6c4907a8be5dd274c3d1524, + 0x1ae0e9d39c6100a8ded3e7ecc34988b75c5338dc936c91c6f1d95c405c07bbbe, + 0x1f11f75c7d0ac841001b3123c045526e98c203d1a6caa18d635f2f2bfa735738 + ], + [ + [ + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x113ad8b46c3eec20c9965b5a7b2e8a51529871d0401b4de6f63de9e5211623e2, + 0x1fc50a16dbdfa1c3b99038f47f81a1c5d1ef6e7b221d4ccca6e821220130e000, + 0x1214a9d6d7288fe85651a8cb83048c7669c83b5ed82ca2642fff01e852a44b4a, + 0xd421a7c25af5538788f49475836712af5da156f88c5867568cd958e305026cc, + 0x2de8ba83d2b6ab6a711fb9230adee1cba46de8c930c86d266acb8c1cb9684e24, + 0xea7be82f1cb493b1bbd83ab7ca285bf0a1559ea05c3f59827b3b013d0a91fb2, + 0x1e3ae7e5775d352651d713ebdfcebf9ca8e905cfb792bf7874239450f914c8c5, + 0x5943e3618a32cf050018a4e2375f4d027b8c14ac82a0de57cbb90c5122a64b4, + 0x603755180f66e98215d61e5346b116cc00cfd058274d7d969b3af95e78bb335, + 0x19817db66fdb8215ecf70476c4044c3f41d78ac5a549c684e35845947dca0b11, + 0x73965f7a9ba8cb33a955d42da55fd7c37a3f0226b029d36dcb3fbea95d642f3, + 0x9a550431430846b6694125b5642b00607f36a1a29485361a3cf427da77eccd0, + 0x68eb4e9d6e0a588b61a6ad501f380da0f009067666c0853d156e33d59c43515, + 0x225e00a0da5a7f7496b70d0923a7cf7ff332bff06958cc0f3fad439874f6024d + ], + [ + 0x19a92ac6087ab89982fe5650e5e799f91003fd8b45400748d2c25e40f04c578d, + 0x7930cd5256f8ab77ab92b08bbb5b195a44a2382c66e27514619efb94e649110, + 0x2d8d3d924f2897199e38eafbc7e101d17d7e563488a9f3198060796ae84c1b08, + 0x1c0de2bfeafce164c9838067a8df6340f9d97edf0122333159b714f45c3f13b1, + 0x20e4a28303dd55e5cee332f30eebafbd7932e7b3531d942454c344b8b8c17cde, + 0x1bb15ee4d492a8e2cf1b10db1b738c6780066ea8347abe536357a723f6cf57be, + 0x2ccf31a572412bb7d9cfa637707853217e7db5550b1cc30a894cdf483a3b63e3, + 0x1d492c34b245bc12941bb163c5118bfcf85bc4f344042b2031ed8662a1f6ffa, + 0x1c9b5c2c07fccfd9dc6b3abfe05675fc997eb7b8cbd8d8b4cb7e671615b0ecce, + 0x243930ba01dfd3945f2aa02d588922b47c1bef2ff8023a849b4ca66a1bfe98b, + 0x8f328e5e66c0b879b36c233f598bd8578d18e2da9f019f0411731524f42d90b, + 0x284a2f083ee32a6663081c800713e0f2395e348dcecc89fc81aa75a5db2ba12b, + 0x19772e83816fc2c49b96427c6ad0573347fa49a5df691252592aebc390055a35, + 0x2dc5900039d4c8523ac379945cb9b58a54e01dbacd67f0c4baee85d353d3fe97, + 0xcc378b44e58f668b45832fdab4a49372731ef2415c37f40b5ded5594aef3cca + ], + [ + 0x302608d750f16491df5a285f5f7f6a5ce6b554f5dacf0b69d450b24bbb4967d7, + 0x28f8144bdae1b904ead70b3b72c7943037de6b48490efd3177783594edd28b9f, + 0x2aa9aae62cdb852490c650ff9e27c9b33d4cd4020ca66f5e1a6b374e662935bc, + 0x1e394d80067f0e10baa95de0d99b4e39204a18727d1401b476ec976b5f173a82, + 0x20bd028c958d57b79e35218fe34e469ebdaa8e8e714e918d58191f65046b972a, + 0x27fa2120431379cbd86205ff114f34dd2dbce13e1c2a0a8e46a1dc27e7b686fd, + 0x564651bc1179170e3c97afbc4f493617017b43b213eeed86b9b1bffe521fe86, + 0x7333cbd0ff13c8ade1febe72892d9ad435c7b451aa72a8c05a7082395882865, + 0x290a7ae732f4754e0cb91923c9248971932607be2e829163f11612ff8a955b10, + 0x1eb520feac62e4545f4fe7cdb675e36474b8b1fd19e15d7c73a2b1dfbb23fed7, + 0x259a2a1f046844724cf992aedc2635f6680f55e8a0fdac695ecd05fbc2cbbd19, + 0x8f78e6dc59cd4694c41abbca086569a9083ca8cc800bd9134e4d48ed9d89dc3, + 0x2d8ec6adad3a646843c88cda01285f8f32d29c6b1025cb5421422bf8bdba7fce, + 0x1b72ac4374e95b7b7d28cd2909507f3006e8352d4af19e47b0b909682a03200e, + 0xd7d8273de237ba2d4d5e8051c5bd5e312d298b6726ffbd3af7e732af91dff27 + ], + [ + 0x1a3c7daa6b4af5662d0d8407b287674d83eae5b7563405f48def49981c98c424, + 0x2474f543d1f2f33b5ef3fbb190651135a59390c8a3661fae2df1d3f14432b608, + 0x1848a60efc89965073b95773f467666687e38d59be208e8377d31903921057e4, + 0x2ca2d8b0a793d90ed318cdb5f697193137155bcfb942d82bef558be5fab359bd, + 0x6ed98a185bb2358f334eb257ae5e3183599c054c1b4e2022569b8368da1abc8, + 0x1ab527614a37c2ffb00c0fad360abaa447ac1063fb9fc656d0148cdce2d7c372, + 0xbc769cd7b34fcd1b454abff0c00b89b540a619b87c95444679c3ac6be84d450, + 0x29ad5236ffbb598a2f8d238703608db7a497a7453ef9d579fbf05be38f8f76f1, + 0x1434ece209d491280c5ae05d7e26cf92d99bb7289a5c1cac09a38ce53b6e03df, + 0x255dfbdf30553413a1f8f5113d60e98583838d13e11c1ee02b25a387ea00cccf, + 0x67d9294b4072b12c368c2816a53bb16b7e7e2a79979a416f2d02af862abedfb, + 0x293ca8a06c5f179d938065ea47f80f65ff21969a9429e400aa177ecf6b6ae853, + 0x255b96258dc8e1644f1bcaecee773632f25a6ea803cd32a1e01f82573775f6fc, + 0x1f2a8dcafe79fd0ea22bb1563c3b28b23c5c4d7591d45e06744b3b379d426618, + 0x22ebe0a315e07be4b0928885f52449b011b3967e519e438c424cc0428c35726f + ], + [ + 0x2db1c9855ac29acc679367dbf70f08d98894077df2411f91ef68dd90177c1e9b, + 0x21715a84742c02d057ac41f743b166da023228425681950edfaff8581201a097, + 0xc893808103549d2030cbfe0004ea6655e24ee71a1f8c1f072d5cf6e17ae2499, + 0x28427ab007a68c7ab12371f13bd7dba0acf7e97ea6e64ae52d5219210fe8a2b0, + 0x51deb4b234890e31f5ac8e69a1e532453774ae93a9e9360fe009ed377ae9c36, + 0x170cee2983fa3d3ecef2f806f40eed8d8e135ceff076fc530bbfee876c9e7f1e, + 0x244b6b63f8041a5975f4640b18c7d067e4a0627f18751dc906016b8893c35123, + 0x2e72b1b114dfee7e8d7f0161255c6895fa786070ce62d806c45a22d7d98a0a30, + 0x228e7399b0e05802852bdd5d5e09966f03c4c3aff53c683eb2f69e0fcc21c0bb, + 0x18451132581b9adf996c6cae15b92d2e4c09fdc7d6c27b4426f32b5e66a0b723, + 0xe1d7ec2a54b11b36e65d7551e9a875a88ccc7a6c0470e7c26e199670a0859b2, + 0x29b68e652deac818824da0c2a11b408d7a839a2e8576c55bfa5f1335ffc5b93, + 0x186e1360041193e12f38099b0e35e767affc3410f6a8dfce9bc75567e39bc402, + 0x19294dd22da673470377d671fabdf42cecd37ecbc018386a438706d6106b04a8, + 0x2ed3cf0214f444d436655e03af8aee2b4d96961eea06e8133bd6e8d3e38234f + ], + [ + 0xf06ee47558f182d810bbcb214a25da7f70a567a0464b348e1b30eca7de99d27, + 0x1ef0e0c1f0b5f67644c486fecf02238cb7f4fa63a082a3c030daddce65a4b82a, + 0xad80718c6e9d1c67b4a37b9e103db32f225fe42a9ba655ff065618b87b82aea, + 0x2cffc378d2cec76ba7080b37fc671a96328bcdfc4630fcc2f2133dcf29c70dd1, + 0x21f1f6a630471e32a8b9ac4b7ed4b04c56b96a71ee20a66a5458c6b8d5c6d346, + 0x288851770f1a13822251da91c84e123593fae1c9cbce6c4ff2317e70bb658209, + 0x2ff4ee110ee1be62e2715dcd119c95b95413376e88ec3ddc3f06fc9db8c27a94, + 0x2ad369a84b57f7455ba31064001ca7779d2b4b96b0b4a91f156abec366aab786, + 0x24f0fa154fcc6d6459d6c56f711f25e38d57e90be7b8046c9e001815edb41404, + 0x7221cad39d9b5f8db705a8723038b92b6baf87284131735eafbecd533dda6d1, + 0x173b3b349ee888d934aee9c14e889cd7d785d1e3e4f1eb72a5c2e56c48fd54c9, + 0x9bc3e40bfe5f616fbd520f3894a0fdd37feb29429fd3a5015953171de3a70f9, + 0x29cb31e1afef4f252578aabd76f23a1320aac90d4a0a66c2225e3d94cc48d22f, + 0x1932bc6bb488b736e0d4bf306d41e622e66c1d685aa4598153054b40f75c0b00, + 0xcb6fa0a5e11b9192a51904939d45a05af8055bdea3f379faac29d1309830e85 + ], + [ + 0x2166d78d948dafa963381cf1560d00bf3a0a1c288a743344c8643a58daf8cbb3, + 0x278e8dac8c56b28a23dba4d90fba91eb947f5092d4a7a9ec7802f61778488e87, + 0x20d87476f1243f490246f88736ee5fd6d33191f0561271487e9693fcfd7a649, + 0xcfcaa1d7d382e1fe1fcb950e14df202a08793d7185255b025d562eb8d97544, + 0xc39dbdf6e6d24a91a0a45f922c894be252baa127d9ac76909f86dc0bcc68a66, + 0x1795384e91bafa554dedf5156cd799e11210ffd2afe817b5c63ad5b85e7fdd06, + 0x2666ec1a67daa7beb057aa0e6e8a10396601a21884372369c012b49aaf849049, + 0x15793f31caea39de315dc5bf5a3662ad5d8e1a12fa1a7280f2efaadafa97adf4, + 0x18800bda17a89832fea54f26741d86c6b6fb9e15b02e7bd065533cb5661d2a95, + 0x156f6a09e6a81d8eecf4dbf21646bb968b2406786cd1dedd4cc732b7532f7fe0, + 0x2977658a10de6e7921ab9e34bcf07bbca61a72549ae57d0c15691bd143d4d2de, + 0x284181093e43419789263736e544817111fdcb559a43773f05186608acc542e4, + 0x200fa20ed1b871313900c01f8b697760d030d8cc0150fdc58e04a0d8a2b344b1, + 0x8d1d68b8437bc980aa7c59d83393b162a0827de74070d2d34b4eaedc17e7e60, + 0x39598a1443c009678602b8dd3474f276da5d62425083ec628a1737e8cca3e7c + ], + [ + 0x2929be9bfe3f93cd34fceae665d96b1de1afb26bcaeea2f4edc454c50cbc4401, + 0xfaf33843e6733437e98995e6f7bfa6feefa73d7410d8585918c347f3cfe92a5, + 0x134b86642ff202388f4fe37356ca4f0ec3805566b7d4d412d8937a359ef9b401, + 0x1d8724c5e641d96f6e372771b0a776bb742fd3c08e1ae250432246cd3bd01bde, + 0x305614aacdfd4167cd1bfdd8fcdece6892d84d4a65e86e6f7c6349fb75e48b96, + 0x2cda26473cfdcd185ba28cfdaa15e7de2359646a0287ebe8b60d702df009010c, + 0x2b0666971fd911529e70ef918d019f44b5c9d77442b6d1866f6e76832d478847, + 0x56c55df543a8d4043a12f409cd2c4bcf43a770f3e38c3fc79ad214b42da834c, + 0x16b11f24502aa4cc3b0c2562a18a24ab8f986431b244034d3fc29555402b5f4a, + 0x18ea0ede9010c7bf0fac361b5b8e7f97c75ed93a13a7ad4a017d920c03c98686, + 0x396097733de5a1fa4a548749b73ff7c426f98d9e5ad16920614d337897f6b1f, + 0xb9d5a3a957eef251ae9c26e53423f9be6f2efc24bb18756893a9d80e56a0825, + 0x1a63a589d1710aa705136cb520c2f1c44d778e490c212d4b72e9f1538e5555cf, + 0x1c0343816b8cecba48519b59b0fb6d4a9bad309ee38311dc3e8cfe8bad75dfbf, + 0x1af56e6575123f99c5d7ab7b83770f0fd60fb9f4038c2942644069e3c243793d + ], + [ + 0x1076d439c67997c37c6c1fda9a37dc2f762dd577946f36fcfdccd7898ec67cd4, + 0x2ba437d6ae6c588c6b71506c8b508347e634b65cee317af1fbb9cc2a997fc006, + 0x2c04878b4cb8156e9983d11574ed99dc7562d3fbb1878257abbc68852fdd2680, + 0xfee8f9731397974100834649ee87a27ac92be7a3810303460141aafb542a429, + 0xef9ae65eb922605d4260ab2021dfbb4774cd5ffaedc1b79dc681208be6f85c5, + 0x27ab4b40901465ef59007114ecf1fbfab6157c24f402246b86a60397267308f3, + 0x2bb5bf03cef933e4ee87f511de3985cff0323ab7b718d4cbca3f429addbf3052, + 0x1ee10e28c612d9d6ee72f1274850c3e829be5c06f5bb293280152a5610eb01e3, + 0x20a9d575fea891302b106439ab03a8a951d8b2ef2b562991946eb2541f1fbad, + 0xb73119c98d25eb6de14246b1401bef485c9dc6accedc23494b9526a39d53221, + 0x2a66defcf489c23eec5079a0ece1c5341027a59e7c592e760184b826d70dba9c, + 0x4aa8e91dc30f9ca318fe24718fe595871f7897e92d57f2d87d4b1bcf9a635e1, + 0x133369b3bcc73ee793e869360cd50d8df60fe398ed9d9c0d0d03e669f796e87f, + 0x709eab96cc6255f2ae917914f25085025490c423284916e23b608638ccce29c, + 0xe8d9c0707dc5bf80a2f08c343c69cc659def86630af3141a003acb3d3e90c08 + ], + [ + 0x185c9ad0da87cf824624d02bec3ba4665822a0f6b3b25deff3afcc687ce1321d, + 0x24a6c1919f94aba9db98a5af38feaa5391cda79f9debfaf118670d7927e41db0, + 0x1783a45215805ade9d359232120b183db54b43f9a7e8fb8dcd95ba9bbabbba59, + 0x116f239abe820737b5e1e82b2ace3a45cefac489a6bff084e323036f54277108, + 0x1adccb898e5fe18b5c29a4708c4b112b56d0fa5d299b5edc07d6f5bc00428b8b, + 0x27122781df7bb05f6ae9e14e8e99da5c23dc77cc06108c0ebb061e5d1be93626, + 0x2e37a7440e75b649a0799cffeb7f9dae38fadfc7cab6c5585e4a84f437729d02, + 0x29f356dcec3b79523c0589a7046ef0758486828b212146c3f5ce987af3fd719e, + 0xf9c05f609ad14debeaff107b95accd60e62662259905105abfafa9e8e08eaea, + 0x1c66828552cac1443334ed70b7fd7fb525f907ab64479d117864c92e911986c6, + 0x10f43368c0567f405aa6aafcf367e3e68beff957c4b0cba17c30c62b3f95490c, + 0x253a11c66463a6dcafd8399fca58ba27febbc307d8833c666e0d8df072c5f69f, + 0x1e99516c240d42bcaaad9c73f21a46193db8433349203035eea30398f9df7893, + 0xc67a06b33cf73882b1c7152d4585b78223d85c77cddc2c7d3594824c5016565, + 0x1f6dd8e85d3597bb6d37b47a1f063122014c888250b38cf8e82e3e5471ef84a9 + ], + [ + 0x2702b1be39e91044fb73926c1104719f4c037aa4151823ceab24f0cec49f4648, + 0x4d80e7ef7e27a2b1397678ac42abcc6e2662c880503e4643fdfbace67273b92, + 0xfc96302e8662de23cc5c8c228ac8ac2dcdbfc488a59f4dd41e3f27095f7e195, + 0x2a31cadb918d78b96dcd548b394425a42e2aa7a28a6b63e509261bfae6fa25b3, + 0x18a2661c03ab9b0d8f7d01091c7e563efc033196747e34139d3f5cc7ac001e9a, + 0x26812acd03db3412cad4bba1aef71bd44b0094d318ace0366c79e729ff0eb2e6, + 0x371f0d49346df2d88b9f1ada8ac99dd8125cfa6c30f3738fb9932a853268e, + 0x27cea9c43fe0bf1ce9e53c0c026e839d80a7d869136603102cddf63cdf28b975, + 0x95f1db43c827e6f0b9cd4fe929e7b8c78c93fd02ec9e0f10992feb753b4ca07, + 0x10a66268dd9a2f368e95507efc2085eeeee8ce977ca1eff5b2e3d94bc342ff58, + 0x25a2a43ee612663dbd61814f2deb06ed005a7414f99825f8be66f542f95a7b2f, + 0xe4fd498778c2c76a02d0d91d8f89825856e706f598337dfebbf3ca33397968f, + 0x13d84ca7f358aaffb1ee8ebae81c32e01adc01e90d09c9451af36e31af82170e, + 0x740c1e9b8ed16e9fae204369c554cfb72007dccfd2530f2e34d544003ae5994, + 0xcc8f90bab68e6de84845da1899bfc52440bdddb940b208301ae94a95777cb72 + ], + [ + 0xaf71a51cd463b9faeda93803cdc03186c7781845252fdf4e0155709d93dd375, + 0x17f6a3aedb0005a9b0a258e31b8e6e2a48f3f9551cef6812a49075aebb8785f5, + 0x24b22e5ce671ce79dff8de16d7cd2bd6375d7ecaa016ecf59cfeb246dac80720, + 0x240caf6d7ab2f7b6ab3d15efcf3074f5b2142a1e804f25012d988454809e096c, + 0xf8aeec74144d00a3ca38bff10bb0f3a8dbff4af6197847db879745aeb57b5ea, + 0x213d29d4e1b6c01fc0d109ea6169490076d131d8e034b3040f7bd9c3c373ea17, + 0xd0327b593042de04f58e0ff93386d1608d33a86872c1d3e7e089120aac7a4ff, + 0xbdc078b1edd9cb1fd2c2a01a97bdf7d458648439fac1f28509b41a2dc9e7740, + 0x26bc00d9cd25124442832d97abd90866d3fa7a401bf38bd95fa7ad526548fea2, + 0x1f14aab5a59ad452cf692b123c65873dd80ffc188798a4570eca792b3f2f257e, + 0x182f1c93c6eb29867b1559c58207a6aeaf40b66eaaf579ca6bd7ca40aaeb7abd, + 0x126ec8c200262c45d1133bf9da5f1e5fd62bcea1e493a080af1bd283ab86f122, + 0x5a78464a4b6bbca6e96d839827bfddbaa9d924840aef6555de643df167d4caa, + 0x2a84c424eb58f9c38b4380af38e0458468980988faa1f0d4c6e723845678523, + 0xc0dcf2b13552ec55c97166be347ca2f93b07e2a10164096d353fa280c796821 + ], + [ + 0x28667f9c7332073e293c80b98edffae01af4f67b4c52ab45e49db8b30f182d28, + 0x1e62029129492c8bdf8514945950681361591a9f5eedc2449e5f229c85bb97db, + 0x52c33fce08d4a39fd805156c8affb84349428ba4920cfd2e7902ddcf9b0557f, + 0x2224c85f0c0b4093014db1e817d1ff16918f15e0cd231b848a48cf83324c4144, + 0x1f53514a97e8b57204e57bd6b1b1d9555f3b50368154154e67c2134fd3151591, + 0x2132f71ac89892c984a0a73653f2d45222ada34181a9e6dbcea0d63961f934f3, + 0x4dbc4c8de708e59aa4b2116e53944bec97ed42309b4a184561d8f32d291f9c1, + 0x2565a17a6bc56e87b0b63664319b8a47bf662c1f49e2ec9251be4fdf33d90f4f, + 0x173e80596756cd9aee04bd6dd9dc15e4b8ebbfefe3771d9819bd4d444726f79d, + 0x1d34655b5776e24701621acb41324cacb50165e019bff1e65f98304f7d822a6, + 0x42eea616d905025147a482eb436a3b75535c9869b76d6cdace118e15c91fb77, + 0xcf030b10a1b4291e576ebabb39c583fea0fa6decfa98cff7a96dc06cb77da51, + 0x260ef13ac7e80fd2db3de9eb942edeef3f5e252d4c04508b1e1b130191ad0df6, + 0xbc367fd93ceacb599c614aa28068783a5d27eec1fc8fa1765015b76dd82f5cf, + 0x1f126117a949dff900fa5d111a0ce2661bd9d5444577c491a9951cfb58192d + ], + [ + 0x2763c33f5b2d7bc3a23040afbcdaf998bb13254c272a5f8635a12606a59c2e5c, + 0x16bae774867656e64fc95f3c249f801f150fd7ee28d195bad9eae43743875278, + 0xf0d475225c99702bba4fd01276102b5cabff7bd4d147c0e3cdee4c07ac31b1, + 0x39a288951a0381e3aaf598ef132853b5d694716c20db87923f0bcf14c914a8, + 0x27bcd639c47482d2dc8b6d13da19fb8d63f3d6c875f6fea486da6ff2ee11e107, + 0x121395023931f6bb3ef28b6063eb7a2ed7839e083fdb92c1e5593c83edff5f53, + 0x290ed9ae7479f9be13af13f98bf88507e6fdf018710e4859fd2e48cc66ff9b24, + 0x15b085b5eb678f8cedf21bfb30e2d64ae1cbdd7472449ed24e6034101c658868, + 0x12a643f4a327acd2454514dd469551e36ab0e3f24ecc3b28a76dc1f38214fe38, + 0x16a1eedbbea79c5411a639e3bf0e90f6e3f740f141599af8e6a43a2069572f95, + 0x5ce7f592dca2148e198554fd64db8c479f29d23f1f16daf3cb8930d9456e4c5, + 0x110298fe7f2bcfdac0bcdc3affeeb436d7b3a377453ae778fabd37a9acb299a7, + 0x14829f09d4beebbe6fc30545047243fb3dab99c62aab7364a7a5b427457a02c0, + 0x278b58503e0b9014104f8c446bed4c6de575c72d4dd9db3d1866846979aab9b, + 0x138f67fbd9cb91ef5206d48cabb269ac42bd352cf371e43311bccad89acc509e + ], + [ + 0xf81a8d8e08758e8a32aa8292666c4cb6ba3f5f06c4dcf4fc502ff97f03a85a6, + 0x10f0172799be23a8fc3f156adfb6c512ba415e35167b563bf7b186fd12a41e57, + 0x1183e91b7ab7372f157d4c477691eeaffc9e8863fb2d806570c67f4b1858fc54, + 0x17620d438499f6c0a66bb577add4cadd66ad39e3377d302bf83d3bba126b2aca, + 0xe9e8373114ad25af97d28e272fc42d8490373cab582193b874a10428ee6cd21, + 0x1f665ba33da4ab9d9806caff77ced39c9be254fcc4c5da8f570096111fb109b5, + 0x135aa38339bd927dd5064e4d572df55811b226bab54b0acaee511d60aedb02fa, + 0x22bc96cbe7f8cbca81b29ba7df848dd6599035ff515b6d485550842e1a35a1c2, + 0x11e1b0af7f5fc9f049877154ae173a1a72c7bc3ba192e438a9d0fa81fdfa4900, + 0x14de448becba6ca0adb21b07455d2c2864c7b85382267026e28f0978822d65ac, + 0x1844a81d4fab57aedbb4c4628e2e47fcb2922883eab0b2e1de16f248de4bb902, + 0xeef04f24ae210ee0a94bc5621574783e49d4d93365a2b3dd069fafd43055452, + 0x1328467c87ba73028921a89333bab97f8b24fcaa72f43837cbcfe5dfb7a945fe, + 0x791d832e976b66bdaaff450731ff35d998595ab9748f695bb45d2c0fef06930, + 0x11492ba406435f35623906ff45df11c39efb59fff09f501fb893d717e34f9d61 + ] + ], + [ +[ +0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, +0x312e3298297ce9b613e755220138a61f6fcb449e9f297bd2ab37fa4b060c4f8, +0x237ee46d48fc4719f3b0c74d1ce32d25ee1a406c86226b14963597d77d3b26d7, +0xe643d3d4ee78128b65244451e50daa769353d675b70cd9f3642127c70afc096, +0x276252adc5f9add05d80d4d975aa6c8506e5f3615ad04dd19b6a8fdf44554816, +0x40e4596ca95fc409132c1497cce79ce1293bf459cbf2e0b1ceda174d0e53e65, +0x6efbf7c9bf4c721cb0ebff67730a41eb0d4498251681593f54d16da5cf2e24f, +0x460e5c59d6292faa4ffea5c4f0f5b618c30291ef6259d2d5bf756df87a5df8f, +0x136b729f22d1ca74db0f67b12512925ab8597467cedf52e6d289407563cb253b, +0x28aaa152884edf31944d72dc318424c0da3492c9f7154dc8fbcb6537cd7e06bc, +0x23fdac37f71f97739b9ac6b9862be4bb4075a31e9d2118c7f4ac5074bd7f2692, +0x767aa1fbc4ea303a476f04423458ac3f6e45404c9f22c30e2ee5dbd7c9348a1, +0xcc0452c4e5cd956ef1a3b4ae5bbcaa7be7acd4c2f72d22d65077587a91c0b01, +0x1ceb88c33c35ed1e6738b9ed039e4ab506bf7ab0f08a7aaf7dab0caf13eb0e68, +0x12a998baf33d6fbf6fafcf03c462c8a5ef7704b181abf2414b689f9eb08566d1 +], +[ +0x19a92ac6087ab89982fe5650e5e799f91003fd8b45400748d2c25e40f04c578d, +0x27dc8579136c0e71f75b1cf6f5083dd8354d115bf414dd1fa540e5f39f7afc72, +0x20428c044d22ee0bcd7a3e6fab424e8b80af5027762db1e96f6580139e2bc093, +0xd17aad3b6fbd4fd8bae145159eba2a61ac1244b3fb460222167b77139c9da6d, +0x180d3e114e0939812b91fb0eff3e0b6109043c1d4018d1d2f9cbc79e384618e9, +0xcf213b1d3f6fe0b137e4524b963bed40993416f8f1b174fe697fd55079f3343, +0x190b37e8c9b7bd5ee60d0a8537d47a1a377f7a5674c75a99540baee608fd8f25, +0x3034b01c2fb47a98674d730818419829480394df38d331ade2700d39138a43dc, +0x6b1dd2a5fd27efc3cd1aceab1969f68e4959b36a0da5ca5b42c10abf0d230a8, +0x488a359cb7c3cd4063adc6ffe91ae4613f72a681535e35b7b96bc26086bda29, +0x153a1ae9f00d026c31b3462001a07a114b4276497c8144c42af93d11bb383d0a, +0x16c499c243fb5cec60a76c3292e05a6217471eacfd3ab2b95b409a367f5a77fe, +0xec171c476265c4877db3554fa9f482a8d6b647239b89e48a9097f174d5c5b56, +0x445f4d9f49d4dcb1ae866956c374e1a3cb45419e00f5836b88e5ad16d639eeb, +0xd9d065a53ec9ea1f2f08c32c30a37cf2b7ad1614e60aaf3b91508a3ffb3b301 +], +[ +0x302608d750f16491df5a285f5f7f6a5ce6b554f5dacf0b69d450b24bbb4967d7, +0x298a90da4f4bce9de81be6912c6ffb796d04c14432c8c40a105a28b135ae2735, +0x16065604a60cf2d7e406310a514e428a734b27a86e2def6fedb3f714c1679c58, +0x1b8dbca850e849940b154d50c6ee570c32444d12c847c2016b35149230395060, +0x2e93afeb1b3520058245bebe0d269664b12e730fc45bbf46cb66044d57b5bab8, +0x2eed04ef2e97eeb4738187710d3c3d598e60a7b9e6484d4b4a2f0983d2970945, +0x1b76f377622072daa3d1619b1bdc692333d5345b67f36f430cf516ef16eda936, +0xa20b0fc9107098578122aeef4dd1bbb7ef353e400ff70d382ee8abb7c481e01, +0x8e34a0ccd379ed1c637f8272a3a4cad64937438043f4ba7f5e5f5b0adf687a1, +0x1d48b6efe372666fc8519de0f01a8e5d360708e47dadce1fc01000e7dd4527c4, +0x260f8a62766f0e259aaf537577b1a99d50bc02074e10f624e91c36f3bad5491b, +0x27ffca574c26cda5aa09d071c5894e0ed95cd93036e2193e84b4e5ea7df06b0, +0x2d723e71184abac895077f84c811f4135f4d7acf5ab28f532990182a43873833, +0x278e3dfc235e7b04caeb106a14460dd6a7471b6f19d441c1f738aa625c45f28d, +0x20fd0cdac44c5b5c22cea47ac2b0d7565819a0e8110932f0e04c300eb32b223f +], +[ +0x1a3c7daa6b4af5662d0d8407b287674d83eae5b7563405f48def49981c98c424, +0x2ff508346df0d408d3d1109b26123bde5c4558bdab26d9cf3c6374a6f9291864, +0x13674b5d0d749caf2d93724d234c9a3a7b9aa8ced4f854b853c07a6d575b7ff2, +0x526e69c73070647cd5d45609e6f557bbb3b4cd4ced38e3982fe8fa217a5c22c, +0x26ea6a7932de98e85daf38c6a9a75cc6c016aa9eb31e78d7b5af1ef3936cdf54, +0x2ea7c830de80ac304f4a4342818cac408fbe27c811b25a9e6c1c2cd7a3a63ec4, +0x213b177aacada821231c6bc2090ff354d629cc89617d52a340673497b0c9b294, +0x178cdf015d8bc8ed5294bb31b6299345cd5a33e5ea30e4f03f4b6bbb2aabb2e3, +0x28548c8bb786f47791c98c20d6921d39d82a2c98681cd10f1805d4b3384605c5, +0x2a7d9ae2a915561a62c884f5ac71ef11815fa7345f61466abaae9bb172382462, +0x131105c4381b5f577a61629a53e074ae66a120d7ef9bb5c27ac675bf90676156, +0x185c152024c4fd6afd5f7f6f95134da079ce1614a9f4e03f2043914281041384, +0x1ca9f045f715d29458cb1fbdc8d84a668938b789bb4e9837cc7a2dccf90cc569, +0x1f22be26d5167ef4bb00117f8e6ea1f2866e602a986289bba484ba2f1e875591, +0x4bbff61811db870b42bcce9be11642d53a88243f2f8271b60897565ba6a6a60 +], +[ +0x2db1c9855ac29acc679367dbf70f08d98894077df2411f91ef68dd90177c1e9b, +0x1347afe5529f60fe7a738494455139994ef976212daeb0289737fc17d67bdc30, +0x17832a57483ab46808e944495407d84b427a250d2f4d8adedb0da2bf8b00f21c, +0x18aff8fe5a1798ba94632917ad3e19d4d8eccb81195395d89b7d631cf2962663, +0xa3ebcde6fceb125aee70284064b2f3524ba816c151fb6245e07cc33c13d97f5, +0x17230666ed67a7740bdd76a96b3ebcd29eca4301e827b218ea24a4a56cf11eae, +0x2efaf6a0e622f10e54e08e0e0acd1e4263ccde6164d805fc5317f9eb83418c0f, +0x2f1240e45287424dd94a661e56b89f0e5a11b9e15fcf896d04b76404ee53148d, +0x2bab506569e55b5d04ce7afa2434a095d3b43f0329b74519f88c1d63c705ec41, +0x280c7256bd6775f497c95849ff56a53a8cd9b01a60205fd41702a10532a7ceb1, +0x3de768cf69223497fd2ea181708751bcb42a0e8cf3f8580ba7d0a86fff12881, +0xaceb3f030450738e2cd5f1b0177872a632cce047ce9861db835554b1bd9de83, +0x14b711d1cabba4675d177f17d623824b3a28229a551f320b3355a9e3f9608c9f, +0x24bb09e90e64f5c63d53580b531079784e4d59d287c933d613aeeaf59add06be, +0x213b22a447492a79d3152f0ed7ff35ed7f580591cb2dfb8d91ee9dbd67ba64ad +], +[ +0xf06ee47558f182d810bbcb214a25da7f70a567a0464b348e1b30eca7de99d27, +0xfcd2ff5c8f0bd2947b6fbf00d0b81ebfb76064cd51bebbcdfdb6209e6634bb9, +0x302b344f13b30ca0578bd6eb52afb66c031b33a229b18a61a98395a95cc4a77d, +0x22b451ac56f38245014eee401568e5cc508bdec222355ab1f7194493ad7f083, +0x1b3bf735cc8f4d38d737f7fb6d87d70646bcf2fdaaaa2a02fbd0e7585d24f37b, +0x1df0e1d73bee56ad584211352e7cabb7c748edf107cd8c5750c6293ef7fa1d87, +0x994b0fad98bd40de62c6a239fd21624a196ff95d2bbfa22e0416be5694d67ea, +0x4cd761f316ecc1b03668f55b6a6a9a82ba2fd797ecbd57013176ac85d8517ec, +0x2398afa197096947d567f16acabed2956bb62acd9a5d898be5f7e154b5ce331a, +0x1f63018449c6f982d1364b473737e009d0004837e9b417d100aeaef53e5571bf, +0x1b531701fd6b02b680ac96125396ebf4df7f83acf2edfe833893eeb5f2c3a848, +0x1412ef160245006ba8ffedae4e0a1aaffb7da57e70128959a5b5e1503b4e4087, +0x3ea51d0d3eae6f814251d648892fe5985019645a2d39bb4d4928e6b4dd9d702, +0x181a8292b083644b0357e5c5b0fdd3162877cd14d98c3ae8e4e01fa39b19f468, +0x1aaeca8c009c0588d25f56bb9457a2cb260b14e88c8e81389479edbd174d73ce +], +[ +0x2166d78d948dafa963381cf1560d00bf3a0a1c288a743344c8643a58daf8cbb3, +0x2fd8655505991d7319eaca4c4b736ee81976b7b325c494ab80c69db132e55196, +0x14b1c418f3c123d91e084f3867dd62b9c73866a494c0646054f7d152824cb0b7, +0x29e7183a40f1812fd9e690cc6991f46516c6a11b6d63dfb275bdf45c2e830daf, +0x2d6e071c9a8c12592824b246bc5024f68d7f15780b8e81cb917032ea3448c77c, +0x2bcd6ecd21d028a8af782686b423a5491be09d311e8b8b311a76c6fa3b6e846b, +0x2995eda96f028f0d823d390a39a08cec8844eb9ce6c8e081c573263505dbe1c, +0x190c2382ceb77e73d72488efff7a47394c9eabaa55e913b3876f5c7425e5072, +0x1cb68d0b5a7d1e5ec01d0604e9ada4e8b0e5d657e0c3a4b981d9a89585b5b1e4, +0x17258254d8e0d6f925e7c0185f2098d534afb0760706557c11cc93481dd34dc, +0x559f237de62143ce58c3f3ffc6fd45cba5c2cc03d7a5b004324a2673ff6d5b6, +0x2d1bae8c0c7b65e609125c9900ed01b4fee0b246e1d5b40f26a321cfe962044c, +0xbb07c4601eda15ffa0c7ed3e9b5a7331deae9260915c930d39745da694ded96, +0x29a3328fef53e260a43f8fde8842280d1b74ed96c3233c5058fcf5748459fc26, +0x2694a19e4af7c2b87a94dbccdd1b3ac611b1373131cd5a9d70bc7837d8f820a2 +], +[ +0x2929be9bfe3f93cd34fceae665d96b1de1afb26bcaeea2f4edc454c50cbc4401, +0x19edbb7a983fcd768fb267d9c4a1fea3ce0b2a2b9b443f0aaa46f06e589d14b6, +0x2c1ddb439b10a092b3971318cad5b08debe8dff603bef4532577c495be1a724e, +0x28449718fd137470b9cf97b815c2140dd1c972ba998e2fe4822b7c0b33bbdfdc, +0x1f0655560b2334547cb948d9d6b9b5907c788a38ef864ae0673a78094fe7ee7b, +0x136fa4ab79c28e0be9bb475e8d02fe991a4c3e1963f8f02bd99fc08feb8af068, +0x1145dc67ca067f540d071fef09cbb91e1d3deb8202530be3829f4a74b97c83a, +0x2befa2b6dee51479054fd8dd18588a47a402dd5c3c4edca0c6c5fe3cac3058a5, +0x1589963f1ad9685037a5090e0a726b46f0d68e01b41fff4e51d7a7ee3ca0384e, +0x2e23caeb146870890855c6e35016e8fbc54757333d84d986487193341a6942b6, +0x5749c39afeb687fbf56b6749a6d2422caa3b4a4a98b702a4958b7e4ecb2d37f, +0x178880d1f6ff2f9b8e1ac338c92a0c8f92803e7f4c277c589d8f4d96102bd7d8, +0x2458edb63177cd46b51ff3f5054376a76640b495d598e472877d4efb647a629f, +0x15ac4c506f0e4516834191a3a6aa8cda30a2b3882ddc8d063ec7a9c38c4dc014, +0x24a5f8b16d150a9683e69c3ae603931192560079eb25d141ff7c2cbaab4dc9c3 +], +[ +0x1076d439c67997c37c6c1fda9a37dc2f762dd577946f36fcfdccd7898ec67cd4, +0x2d9c1650b528398e8d52dbc23335384e54aee2432d635c70a02d96243ca0b26f, +0x1b2c5206d50be044598c5897e0b4b0221bd37b510a437fe5a1b4c1c69c601b6d, +0x2edd1fa77896a64dbbfced0977e08337ee4bf613f76e8a2ce26414548b231653, +0xcbb908762517b41e306b6909833d5a107634426f22973fe83f00b0e17f13296, +0x24cbb3c94a026a76c045e4c6edfbb1367d256acf26d02cc09412eda7f59a7ecb, +0xa0bd0ea059162db49db00cb2a940d57b4a174de0f3aa95507bbf8bddfe17b1, +0x1b2b047e9e413d748553f99dd8af9b25efcc5e22d45fe891dd28f8fbc2fb5301, +0xcb96ace8a27b43f9e6227f6712da13e1fdcf8f3f9908a3a1c26a35a05b14922, +0x29ac01ae36569271195fe075de8ddfb4380c3a02d43d7342a1fb5117b8de2a53, +0x42ebef9c6a4cdbd7c6cb04d45d2e0c2aaa80deaf78bc1f58ef40906cf3d0210, +0x2e38bf07c16b3203bdbc7746fe5f9179277cca8363c860155d140ec63673791, +0x207e9157c54acea4ef46af721cd9b2f57447ed4e87be8933f1d0b6d814d6ff2, +0x167fda86032760fe696b4920c81f53d843f93d6dd536f230d2004eb414bffadf, +0xfdd5ddada0b045a445aa344bc61b1ac05142e1b5641aeb7e767de15abbc9bf5 +], +[ +0x185c9ad0da87cf824624d02bec3ba4665822a0f6b3b25deff3afcc687ce1321d, +0x99fe609dce91a41f172017be2754fe99ebf6c15cc57f31bb6f5b7d807b1f7ab, +0xd8b8636d4598fdf5326235d176c94628e61b4e7c82e78b4e564850ca2b2375a, +0xd65ab8a42892dbf60587c701d4ee79885301867045a954e709a0b39a96e3432, +0x1ff952bebf30d706276910172a3cdfcafb099480002dd0fa8c68288188ffb47, +0x1b317bd89d4ff133f75ab4d3d0b76a79ae01b0dff996cf34a725196ce703c17e, +0x124794d78885d5936bd03ff734b5c1adac8a4a596ad9f82102c00d3a684dd7c8, +0x24ffd623daab9fe13588a1c00b7f8c8f1ca8caa530a1c7131b466d950f2518ca, +0x2b38ad1a7b652e9f8bf0ef32be28b745c099922eb755a34186ac9090567d8bd2, +0x19babc734091a3be933427e66c377144245e7db110c6a2baa986003947a240ca, +0xd0289a40cf02926cbcb2747a0e1c1518e9c4f704df6aea14276211c24086080, +0x28bd66c5e1338f9704ff07003bfc744bccc39f7ce6c8ab5a577dc903cd264016, +0x170f77a7b3b9caeaf5659fce45eada32edab843510f0c1c1918e78d0f6f250f3, +0x4bf7c50eb8083a1b1aed2f2eb1e3e6ac6dac94088c526643d43fc4ffd6750bd, +0x2cacaf80e8db29ba80807838954a59a587b839dae77fae26c3766144af1c1731 +], +[ +0x2702b1be39e91044fb73926c1104719f4c037aa4151823ceab24f0cec49f4648, +0x13b4dec836bd9ccf38a503e625ed8e236c54e696c74637ae6a3686a805695912, +0x1715f73ecf73e36f8e513b1cc9ab6d82c38edc2000876f5d1bae037be5c99715, +0x133105b55e6c880ddfdf28747478b9cee5fda98c7ebb0dda7501a2798386f9f2, +0x2c728d02ad11c999b2b9b9ea9e57d496572871e774331ae56374f238082b27ad, +0x23ef277dfa1c0e0d94bc61cb2e8bbdcea30f4d4024531391a4c3e9cab4543b3b, +0x16431ad5871bcae4168c2b861ef4b0b01935d119758db9aae06c00bd30db4df8, +0x28db93b12307f5bee8a6c0b7bcca8b2305b688020740d4345fae2d04ed2505dd, +0x21b0ef1e524d8d9ebbfc6c2c749d0ec90fae708de520385ea8bf0428508c5d5b, +0x19d13c633e260305a71528af4eaa906ca4427977dc0c747c8a6a4503fef43e8c, +0x23d809de14b02c1069c3e14dff538b910e484afeff400b2c1d24fb0e0099cbef, +0x13fcf2fab4b4b66a25dac0cd517fec58f5ac1850d867be3be4aeb9854eb30efb, +0x161967aef1a7f7907817e10adad374693d3d1f981ec444384c4db438195d4daf, +0x1694d5ab473f9de3701a254240a02a4743ed5291b9208af4956404ddb30a4380, +0x1c710c033318dcb32177032074580a3504f248668c7c53de567b4830f74c9ea8 +], +[ +0xaf71a51cd463b9faeda93803cdc03186c7781845252fdf4e0155709d93dd375, +0x5fc3b1799e5b191257c7a3bc75e9fa97b164f3f4edda6ea6649c83267be51a5, +0x1c4497521275cd86c918551760f4d35becefa8ed08036c9c18d83815a9fc7f8c, +0x1c65c1b912286c5b2274387fa7965d6b2843b5b01b806bbfceb590da531c68eb, +0x29d4202e4558503b0449242495fd9ad2381705256affbba80117b4c2287175f3, +0x2933124ced84942c7077b2ac393d14464d517c7d8f1e340694ed5f1acbdff129, +0xbd580f80ea79136a9b520cea04461da846d9f23e62277f13d6b3aa6ab108ad1, +0x57b88d83808d3675ba199bfc5780633adfaa44c9b1e32463d66b79e1c6dff3a, +0x3a6c87ee34cdae1ddd7982cd318362e1a278dc9cdf1cd1dd03b6c36aff836, +0x22692fb680511799b8ceec96e7ca0e1cd21de90f94856acf334ffbe2fc262053, +0x1d85033ba0c5dd804c5237c31ab8b09684c635b8b7578c50c246b15314926871, +0x2b52e9a0a9a535ae05d79b8b555d461f148db269f49e38dd8ec6f8b8da106aa3, +0x2773fcd9cd996f38297b95daab22c1e79f179f4c79fd4bf6f4abf8725ecd5032, +0x18ad7311ad63af100808f64bdc63392bfaa0a3881ab03c3157ca8140868a70e1, +0x19b88372c544a69321b273cc62a95b006931a64222cab4536e797e578a56305f +], +[ +0x28667f9c7332073e293c80b98edffae01af4f67b4c52ab45e49db8b30f182d28, +0x1d0cea849dc7409b3b26de35715b32db618691bc123cd9c4c5e6f40b4a1e49bf, +0x161556e03e94c7156607cba64c0bb7fa00bcaa126df8afb5d42976c03b7d5e0d, +0x419c20a2ef9d70e930629591eae4c63276c5d79d6948e98f2c37acc29f1a4aa, +0x1d4a3584e3933abffe0977179b8c112f2cf08e409d33362df4775d1373f4d366, +0x104bd1b4c028b287ac3fea1ecdcbabdfa6a065e9772791c3de84d945542fc206, +0x267ef84e628bff8a9a85df724e4c32cbd3237d91bd65c43618d86502032a3694, +0x2d361efa8fc65b03d45507cfb53549b3b26a84ac50b3593dbc052806ecf59fec, +0x1285c484100d70c992f6b6953a9955f56957e9a17641679bdfd388b6bf60ea42, +0xe1a46a527394539c39e9f1e4426d3188c0d9077021790734ec0126d0828fbc7, +0xef206f21658db03fc8d5d6be5b18374247aee43b3f29b430a6fed7fa5102a84, +0x2ac3db07d831b461f38204aa0454b1edfc1a0de5b7a6e15e49c63bc7140c3327, +0xeeadf9b5fd85f9405991af7f4cb2bda816e5aca76103b34b891502f921d6096, +0x2931d38792a3769da52491346c7c6f8f106c2735ef2a1ca03725396983a0049b, +0x131154cd6dcbb9b469cd6860b861699845abcc41f428331b1d2beebba8ceb767 +], +[ +0x2763c33f5b2d7bc3a23040afbcdaf998bb13254c272a5f8635a12606a59c2e5c, +0x27ade810ab16b1c9d9b363d48e397adfc79af3a4836ed63c650053ca057a03c0, +0x177d3d44dd549944ff5772d4742603e163124583cfa4b673ccf1a25454ea3be2, +0x2c0de2ff6c43c1d034459dc8458237d808fb0ed445eae2cf7e972c83f006995, +0x27ac47846175fcaa604d687cd2ed41f2ca52905b2eefa79eaa8583ebae76291, +0x165a3778b89cc7da792542f4c9a6dba92b85175a60d3661beb77852b238629b3, +0x27e08a80dc448a0ea08c79c9198e57512968df40d45f08c26ac8242d126aedc0, +0x1fd804ca6b5d2a3cc76ae1f125a0bee456764db7a553f48bb47f468f3c57a95a, +0x174de7ca0ebe6a1290ac6a8076d51b85fe8fb4022da95a59a6e9f1fc2fbb2efb, +0xf3deafe2fe6fbae9417eb6b144885051e5d1642e49b37469d39a6bd6cbbdbbb, +0xecfff476860b104100ab4d0dc92d93b993024a1c0d6d50b339243e9ae67ccbb, +0x2cee2efaf90a0e74febcd521cb5fc61304ada5f8760adc044cb684f341b646c7, +0x140214189bf9a4001311fb36b9e5d27a3f3ceba32a457135a3c66d76e8403553, +0x2a90f5ad074f3e239345c3d75b7081804b34fdfc2fb9f720a6448818946ee976, +0x1c373710856290660f38b96ad9baaba487a10183260e1d06f9b9935d36e9b0b9 +], +[ +0xf81a8d8e08758e8a32aa8292666c4cb6ba3f5f06c4dcf4fc502ff97f03a85a6, +0xc3bf8b042a0fc9b018e64d500484eeccc8086ec911012ee19a8e94c97b1f8ba, +0x10539e3badcbe0386b58327fa5ec50e92d483bcb819b41b21dd7c54eda76a99c, +0x308a3fa0a2d7ab2ef746509f2fb76d1a5db994586a54e9d109448f18b281b31, +0x3ae04f50079403a7c6f13c02d0ecbbce7631eeeb2f9f284dc7c2a52fbff4770, +0x6bf4105aeb7839b9deb71934169cc975451f8d76f834499b281eb6cd69c071f, +0x28cd5b5220315f32a404bf919a9cd01a3082f5cf1ed6e92dd79a323bfc62df5, +0xdb2421285ea7f5979122022c62e752e1b15c491cca462b4e71b7bb0661990cb, +0x200d26a5d00a2c154aa75036fc4e24885f7d8e3ecdfa19beb7cc15767eb2de8b, +0x1a1c643b8d0510676c8afea7a4c4af98432406731046ca882a497b29a7c61777, +0x1e80c6db7632f6d64766cce10b56d0762622eba0de31b6271e95ac94cec6ef32, +0x16c8f7d85e411d0f9ba685f0fb815c6ff517ab5463c74bb9984dfdeab8299477, +0x20830e9933ab9c82b1d99369207399eb347fecd8d8ba430b5925038cc3295055, +0x256a4d8167c0f602f9f3b663dbde4a7cd3d47353587b017f4f03627650b813ff, +0x11139f7a6884d0c2efc32997248db307bbc0cba48037fc518478e9634fcc745e +] +], + [ + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0xd4e118218c553f4fd17f1dbb39ba942efd76cd18298bd6b72e1fde271c74372, + 0x1c9814a36ea57e27bd838375e1c1a562dcd2af6a66aad460bfc8afcf3d63ab8b, + 0x1c573e2904e49c6abed20981459d41c560544306978535d6becd7106ed3e41fb, + 0x9e39b302efe7ebc4307cd009e6bd6f7b5128a23298b11eb8e73047cf2f2e920, + 0x1fc427692601beee8d5f6bffaa3faa89af61a2ce7a048f9a596cf2c38ac2cfd7, + 0x1e5b7cbf92351abd6a71a235d9d2ba54bebc40e693a66f3b893174ccac29766d, + 0x2ee69d018063e4752c402c2255b267a05e49736814f2c9b7247240d61e8b684b, + 0x1eaea919368dbdf57be4a55db999baf940ba81052b4e4d5b8e7e16253274f5a, + 0x297f770923ed719ff3167e17564126bc6dda16c8cfd27aad29dfa7a466038453, + 0x13a94e1e1ffd11c4a28c86290a71162f82c03ea2634b67d98c1a5c1d06912186, + 0x19cea28494b1210a4098ac0e79d99fb546c2c3588f3cfe4a068359bb6082e56e, + 0x13841448d03b83eea61935f4d495503643436e90a8efa58be47c85e581b050b7, + 0x2df272af26c5aa5407188de71beb7cdfcf870c778b2093cae868000a2dbfaccd, + 0x29fe73f14e2420c982548ec713b85e374c1d8a43c2bc2ddb6302bef9fb2b6e24, + 0x9070c4406fbd360eca9c300edbd0a65fe8f59b876c18ae13bde14e3330e3175, + 0x2c82ea6755166fd89b688200788ba82d29734ca1b04494d0643b8689ab0b7cc2, + 0x26e76b10c0dd0dde0a57f9b731be061ae57c1d964e2e525081e1fa6084632b57, + 0x277298f3554969bc6937d1b5d5fdc5821b3c809206a3930ec894caf9a37240bd, + 0x287e53a89a23bf624bf6613a821ee5d502838605198c699cdb6ae5d274bb8453, + 0x2e9f85b46415dab53d2c1820226d4e7117e6cc96b7ddffa9f6a96cc697256255, + 0x17fcc4d649ce2696bb0e00460172bce45e5deb8c57904e5ca0d056c9df3e5297, + 0x2c971b630f9a4bca7a950159ff4411578bb39eedee8d9f0171b61ef7febbff4a, + 0x9b526beea2b32c93c9205ce33c6dd79824ee0123e0ee8309814432299a9756c, + 0xc8311c2fe1acce872212bc73164132f8fc89039b4b297090ef07e1997704279, + 0x2ea4d48161c13add4b1dc83b3666ef388ada7a353f3da4c8053efafdd1742bcb, + 0x447cfb281dd95e5bcf7a195bc52e08d78aed9e64cc9d7973873d06a42b8964a, + 0x2828d9d20b414b800a028afa5e61ec4362ada01cbd66f3a4e018f941a9edc227, + 0xf37dee2a8dc76e8cccbcfc527cd8c3383032e1f3f5065e39d2aa70b8fed775a, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x2ab166f28cfdbcfc32e51fc1db9264b527e40c696357cbdfa6bf90bf09fb97fc, + 0x2e156785cef17b7d942ced8e2ee15ce4bbe2ba73c0e55bd50eb898a1bedcf3c0, + 0xd4641251d71b781208156ca3680d6a5676f749b7588d5db0464c76ab985a43a, + 0xce5cf743d721f040dec40606144f5bcc8b068d2bbb11c3623eb423b1030e147, + 0x15e35852381a52021bfaccaff799de57d8dc8606f2465e875c7f9e22a3183ba6, + 0x7e9b4e0821320afbbb23fbe3a2027192f2ec891fde602faf446d06b3a770c04, + 0xb743d70dcb58a6acc70835a005c7ce366876fe3efe504909b0cb87aece170f6, + 0x10643f7d6181a8b5df1e921eb1a841476a937fc6a473185d8322c9a18c487a3e, + 0x2928df7c94de7ff8a3770980f0fbe3cc4e4f5908537c40b9e75247bc31e6585c, + 0x168d44f63e58a5c713c37e067709bc369c27f428af5eb3eaa79d445b9d073318, + 0x2b8845a96842f965343a94e76efa217b83bc1ebe804c7b25e8b3b58dd165e79c, + 0x1f44fb02f387d2ce14dd149cd24fb411a7c738157715d6a1be66ec028fc01bdb, + 0x217b5aaf9893ae41030f6c64ee6870bc995427c81e04a265e1774401a5412a53, + 0x45a1e21cd1e0e5b296cc6e02e249a6cd0eef3f6487292f0f1c742de712a4a4d, + 0x1901d160707a8edfbb7d4533914b9b8bb06f565b1abace77f7f761eb33f39e5c, + 0x27dee99b80374f3c665a4dc5c89a8e365a5a93d07e51c727ddd6a896c7ef8a7, + 0xb1c7058abc3ca4f1633d64c0dd5f068d7fdc10f96e3ca682d1b2ae6e289aaf6, + 0x1c495d660ada6c32fa2f107a811730d99ec01d9a17dca7001e659fb8454b9a1c, + 0x100885f5765de1733a91853cf668563b88c9c36005cb54cae61a82b6bb65160c, + 0x233544636d02f161bfe5bae6e687558cecee34870235d36cace44c6d372f0545, + 0x222a180a868a589137d947276e3cbaa74ca5052e685e02c178f64767a4e66446, + 0x22b1b89514b6a597c1331e24ec3f4e3232821a7330a525629d4d7e04950fdcd0, + 0x229fd163ea1ae80446877d78272ce7c50b8abac8fc591ba25c22661cb1e1d5a2, + 0x5efb45e61466bbb89d081dfbcc8bd398bbecd324d5950d65151b80c102a0503, + 0xcdf2465b92dd04b968ea8419be7466b0ea3785fbdf1a7550dc5b99e781853a3, + 0x2acbe99eeb7c3a167376c64ce28e10b1628cc3f7f480e68dba68bd470f29ffc6, + 0x21c173647249e75c7c8cb1d097da2d4ccda1031ccb8be5a1d2c3d392fdea5bd2, + 0x426c0054e199f89ccdd26940f3b6e8e30bb744886d5ae6677ce75f0abcb1a2, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x2664a99501d9fcc7afebe82773b4ea88245d531d59a7a0708522c437a2c63c8, + 0x1dc35aa8ae4c95f4a17d44a790157b7f27045bfea974ef5818a2ad557ae4d1ab, + 0xfdae6869465240d7a6280616afc83e937cc5821d8cdef8ae9a085395aa708cb, + 0x1782b019aadd454d509149e265b8474467c1ac219af05a53b8f671a3d1c7ab8, + 0xe543d031bc1748852a333f2e031cbcb39d5715e8637ffa18f18d620de3b1ca2, + 0x104993ba9cad115c79a58320fb01233fb0124a73e040581c6621429cf2fd8e2f, + 0x2aec2aa10254227e5e0cef19dc491ffae856bd5a9b029d926b60cdee38a2e30a, + 0x14395653083408edce60edf4f3232a9614c781cfd7f6fd183ee22e08e9d46daf, + 0x2e200704e49142bb68b20d9f7df040a1bd32118b21d44f74dca2b31818693012, + 0x2797778f8ed2e9af3fc79ec16f248b6209c03036a7f0d5066237befbab16e11c, + 0x25e0e403bfbbb31be8c5360007aa9f2e36a4dc4b5b2b0823f8cbd4349970ba35, + 0x2e8423bdead0b3ee1516ec6c5c816c7ea3004a45a0443192427bbc4415251771, + 0x2a34015d21144652f722f141385ba0510cd38da886bc0df34352ee7ae76a07be, + 0x2a3fee652dcedc95a0b44a072aaa54f5155b036b22bbaf7eaf0b9c3cde42f4cc, + 0x135692d47c5a0d4df037949a54fc72f230314fe7629e0dd7987b620c66543505, + 0x142093c728ea36edf0844de5e3c4b4f1e1b44b72a413b7b2a758b5be41c8d616, + 0x2a0b459ab3f636567fe0f1330ecb15453f62a6993b748edab79ad8cdd0d535b4, + 0x330b0a428235522e1d5e4728b882d56a82cfda90452ab9187127ce73658a9f2, + 0x2c44b22ae15ba0f22763004e8fcf0af6c602a0cbadc67eff70a74000b67017f9, + 0x1c68c04dca5f72aab61b7b60219e29d1183c8d1de5c7c8c09460738b6bf9760, + 0x1c74af78ca0448531b773a27c47800cace7f86e68e4969d29a8a12f1b9d59330, + 0x14e2ebfdbf9c76e96911a23a9f9c7076b38316393fe11a0a7492e605ec7a9c42, + 0x119a85d4048b76c56f636acfce7dae71759828d711dd6b28ed0e9a236e4d8fb3, + 0xde9be78e2e3c344a0b76a171b8d7ce1a1d05f25790a2451102e05a91472bf35, + 0x1e91cd25f12f2f3cffc2490773f8af707fe1a6843a766a3c44eb5b8fc134b002, + 0x20956c83b24ba2bb0086a91f597d0a902f2d74e53216bbd9592d35c438648061, + 0xc716d79b1bfa9d016fe75522d771400fcd75862133046a9b1011540d2331e87, + 0x2c4f3e61d58aab9d3c10abc4656fea493fb3d6374708cdb2e084a67e2fb6ea6a, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x15762393eeb335167599c130b4b6d22fc3f053dbbaf7635f39701683f9642dfe, + 0xd7579361389b5dec0c5817e57dd5b775c48facbabb151eb0f7e2da5ae19d158, + 0x265b9eb82ef9bb6fe2f70ccf516bee6b9be401183f0932784a40a61186f47a42, + 0xad7dc8d9d0b28ae3046b8f23c3a7cb614090e05a3c9ec3fe8e2fab367df2272, + 0x2a3f87839d7b3e0528e7b9c221379203354304e363684e38f5fbeb698bcb19f7, + 0x2834e210d211aeb395ae05198f7a1c475be1cb0d89a8c0877d8e88a9d62fc5ea, + 0x8cf6af0f8c7017f0de1cf6ea6947009c1041169d5b57c49938a6a4c863debbf, + 0xf9b0115c9097f360d0fb624b14c8b4a1ceff857220a181da4c32f619b164bed, + 0x10902d17db9823294cebb8706f44e8752e5a3abfd8218ac27718a4c0fc8a458c, + 0x2ffc17ee98848d878ed4315e3ce007667b4f18bd43993e4d969e9cb38d8d118f, + 0xf878f0a4df67255f88423ffb527014656515eaea2e9cc36be9c37135041fd98, + 0x5dd3e66670174cdbc764ce0711c58f427dc503c798e29140820053da7694d26, + 0x2de49ecdb01104151943ace205edcc81ab91a9ef2af4c33ee2aa2d08bad6c023, + 0x2cb9a3284c718a566d7db309aa0ce6f8e61dba64a225f746b757ef2eaf0b9311, + 0x1d1c9593d0c4ea4ed9a491dc73821969ced386145cff808364bc37335ccf5a69, + 0x23a29371ad7760d5c5de4ae5024a4612743fa77b09eb566c9f41d216c9552854, + 0xee30c0ca292c3dbbcdc2471f750036531b0cb85eb8464d3f92466008ab94247, + 0x1727f0d18b422010f97058ff5e8ac23fc850951774b431a38f60a1d9b5560175, + 0x2ac5457bc236f8945365b828183f8266e3d1b5b3dc2d9ca52febacdcde11b71b, + 0x166d29ead2255e356ca2170969b7b9b94bbd88bb34ad7e5663f4d3a25a330ee7, + 0x2e386cdbee46199b48299bcd0cc8ec486f6c6caadb087b52ea86e51d4f39e736, + 0x7937bbf56ef747bfc1543e6cf5c653434e85a225f09199ce11747da5d44a530, + 0xae9d9852098390b4a5b9a075d32020a5d61d0a2a05fc6037408840d43bd04fa, + 0x1181b5e009f4e51aa287e113ed3be581245601ea27ce4b35219c7317087568f3, + 0x2475a06052db24962d86bfe804db3f65205984e5966c1a8695351dec487b611, + 0x1e9530a8088a3c241b2e5ced4157949565aa90425ec8b494def155581d6e10d4, + 0xc9c3bdd72c3442d12734c0f3bcf2bd1bc679cf8fac9127abfb316fbcae53202, + 0x2fca60f1092c4d48164a2e2c81fe134cb4bea555f4569e095389e181a4ceb5ec, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x1115614e19e210b59b4b0e708130dd845be5bee11aa1ce43984ccb99beb3624c, + 0x26643a2ea75d103a87b50ca1690a55117340ab3f4fe78e63f81187f58a392382, + 0x699ce3db9d5882c04716cd74bc49c2bcd5cfa34039856d27ac7354b60ab8412, + 0x147e382354cd1bd30bb3383eff03f89974b035a00897f89d9545cf501ecfb243, + 0x76e68370ceb55cca9757765b0c2eff1e05426fd3b1eeae4de2bd9f49c121700, + 0x8064483b1ee3733f6b6e9dae47a7dedf7baa9b67ff8471ced25395fa38cd884, + 0x26225db4d7860e869a00f54fa10923c8041cf313eb912318aaf8f4f897401f44, + 0x15ba41ce4e4e0b3c6633aa83180dab522a28b25887f78e8acb61b6cfc6f837db, + 0x29bf9692a1f8c909bf1d0fac4a04de3804e89c3fcc2b081cd25d44b0afff7b09, + 0x29838b380b43fda29e4b8824229a76291808c2a9c4864ba8e5577fdac75a85e6, + 0x165e81bf9d1b5b89ed739b99c84c53dc3fca070e83a818d5bbfeed37630a0b48, + 0x10a7013127742057201e42ecbc83099b49a60af2365f8bf7cc403a3095ed3fa7, + 0x223759ffd12a39e3e384c76802544c3778f14149d0123c1280fbb92ed556d9ff, + 0x707296bc5dc73b70944cfa07f21c77042753a479540db83d9115f9fe9ee3e59, + 0x205f5d69af9f4bb66c51fbbd99ecd7108c76240f97f758a17e60f46bdcef86d0, + 0x1210dd2f4c47992f4d5c7150f1bd9346860046534bec9bcbb3a977802fe9037e, + 0x144ccf1aeb8b78de9437aa82f7a82ffcb958529cc51dd5a283635ffc0b0a6c8a, + 0xf996b911c7c650ebcbf4bade79e10411e3d4ab0e2ec01fce87928c4c0f77e80, + 0x1b46a1b0ed04080cb068fdff6e531b02c002fc3d66b3ed2d656137001b7926af, + 0x19fce53edadf9d4cb5eae86fd8b1c68c238aef46a5ca33603367b8de0927b2f1, + 0x26b0885672f6494dfb46ed42a401176f2a2f42790725f14adaee8e9638a986ea, + 0x2db620812477b8d733297937c52ae01076f5928ec0b7488e855dfc5b938b80a2, + 0x20d30fe0ff4f57a3cc6e6330182f23fdd72c24aaf0a5b372a32a19e80a638112, + 0x2a5e3d7b9813aa7a0cbd2ba1c425d80e81e12de4060b90ba7eaf832f00f34d2e, + 0xab8b6d9abc9cf77de47f36daec39db0f7e3c7a31db631ac6ebfa501a4b3f94f, + 0x16c8438c2ff89c19e2f9cdce14dc380a8a31c1f65d059e23931f69b921e5b4dc, + 0x13d36ffb25914bff0a9c1b490db18fc8fd7a2ff9fa3b673aa2ccb2a64539c7e7, + 0x28b8ee6f7ee1d8d0d3ebe26bf4246e8eb545148ca86e60cbd0bfdf4e9b22660d, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x10dd321b7a11a2bc96b3f4719b4b443d94e5aa2ddbf428d32e863d7b956aa085, + 0x5fc6b8b740e55f5d0690b7e2309f312d089c4555f057172a6214835460a342f, + 0x2951ef2c77380bae297a4fbc05ea97de562ed3d80aa8a986359c3ff00bcad10b, + 0x2b7c767b440ca0ddb88adb86af53231819ad6c21c222b09a8fc8f9d61108276d, + 0xe44d122f91c40d9470afc3e484ec8f8fe6ad0fd24146f1d38d717da4db7673c, + 0x1ba47ae303c2e76854d7f399c74f48dfaaa3287c07b9b79bf1fd08f9da703c4a, + 0x11b425d8000810e925867f7a9850aa799aa2338185b6f97ebbeb7b481a52feea, + 0x27abc591fdfc4152cee25f4fb6d0a1e932a396b72c311c05a99a9f923b1f7014, + 0x2a7294a73da17a02829961f0cd5b34c67c909acc3874a238637fb570d4c23046, + 0x8b325e346b09a1eef8be7fc3d81867135e87ee9958f16dab759bfba34b0adad, + 0x1d8bfded258e085fd2c871a9db0ca38ce5e5d232d2859c9e3da87829057ff232, + 0x10321b7d5466be1e92a7b8f17a16a37baba2987ed57399fa903b5385d81b19bd, + 0x1385299af14ad7cefe90edbd656d72126e0e9078317306984f201a98e3e87ff6, + 0x1b3f863460bd743da42eb33e47d2cfffd9a1855e9fe571674798d3b0d2aaa8c3, + 0x16f65f24d40213e86452cb242e20a222d8bda274251b4fbd82dc110ad78f1101, + 0x271aae4782989dad19f84117ce0466a52e16551386b42a74552db0c6e00442f, + 0x2913b1df62de1405241829ebd6bbf2719510cfde2d374c171f2b0a3956beacb7, + 0x102108bf4a73ec9abced652ec51ca12fb06e48b5df049b9e37102ce0a77b657d, + 0x206603d022cc8608f807ace7c0ec31d9dd98c202be6d1bc47a4d44df54bb48fa, + 0x28c4e8e4ef10710d1e972ee6a4a2f88aa08a0d6fbbd77cbd057ce83ab6b75bcf, + 0x1431769f19552b0579c9a23e91e9f017ccef784eaf0b52f33819bfd72ae98f42, + 0x20c42490a8ca07d9f39b11e720b833ccc033e1ed16a310d53222877b0630336, + 0x27e9b6a362bfbe53ee9fe071410ca804a9bbfd2d2e579b95a50d63a16c988da0, + 0x2e937b74fb17d63c90d32c1258c1cb4108f5e3f82246fd704d44233653aab860, + 0xb1b6974c506d78acccb5e1b6c9a5583e9c922152ec0d113495dc49b14a61c8d, + 0x18554cce997dedb95d27bf135c8bddd3b0c8aad0551a6f372bba51613c0335ac, + 0x132069ecac9f244a5e447a1cc19a998073aec780e8236c827a66bf9fc6ccf8a5, + 0x17d40185a9458fc6b98948ad7da77f035fd7a3618233a43af0d0e511e5fa37b1, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x275d28b52043874241a3fbf29f0fc8725346929cb378a7e4e9e8c7a8ac1c4128, + 0x168eb99c86d705c289b00227d74828339e88cda8ea726d3d9acbb57ae75043b1, + 0x2a76294553220b5ba2abadf6bc42a902641312f0bc1953286b08ba16ae65f435, + 0x4f55222eec01a996c9c4c70c11f6375714c601e1547cd47f1dee0b3999be4ca, + 0x26afe145a5c9d058fd25a6404e4acb62cb13d299de81fac1deb35ff9f4a40c33, + 0x2cd5c836e175ed7a902fe2334f239d499f51b58db73bbf2b1180cfe4c4df7936, + 0x29b7a4911bb67a29bd7368c0f42079aeda1fc0d452efb2b129b0ad93fec02eb1, + 0x258d09a47dffa2af8a1dd733c8b08f63911dff878a2fdb4794e319d46a63df7f, + 0x22e2643fe45193389fd7981bf191826724d5ff1f0a68651c1c98ef02d81f1b0a, + 0xecb1213c8df26deaa40d8f6c4f0a1d4e3c72da3dfc1f4370de7dad7e32618d, + 0x14ba09c0956dddfe7410192712238658b4d65506c78e318ae769d2732c63adde, + 0x2dcd28c30f44c2ee7d8121acb638debab46d0feee4dce60d494acb677134a60f, + 0x117c6959729d1d774ce1a8fe1fa28251592f3bd62f86253929ee45ca959e4b79, + 0x2c290cbd7d76fc9f9cdcfc47b48fd66ab55d20b7e2f73357e68319367c7fae08, + 0x1f40cb5c53ab688c259fc3a2bdb401115330f3b2850955a39764374e5f2b5195, + 0x2a58a19ce1744a2411fde6401a6f33d899f9fa9c59eb6375530f45bd8a751339, + 0xdf6ce7e1bb5c41d366d6d7d5707c63eb3ae9478043fe167f712758a05b49206, + 0x2a32f08c015e3dba1d7193b31362ea88156b370fccf15c48abb7133747833ae, + 0xe549b8f127e7ee7a8e67f9dc534fc8e3a627059b406379c63d86a54a593d86d, + 0x2ad6b517cba39a16caa6fcfd53d3b8a43758e360c703aed8691d721a523ac174, + 0xe000e82e93b69d72b8385885464cb1531c74d6255f1c1156539c89dfc84091, + 0x24b57d1e4c920be2b95c0fc8a84f5d5603f0c286e80d71669d60049b94770419, + 0x24c65f0e2ad6e614ea9a53b058651459f966152275afd3cd6924a1e990e7d201, + 0x1d0ae8c3033577ea4b1f2dd4b68b83620a1ffcb4d5426e9603d4ccfcb6f1fb66, + 0x12c81853619d70f737544addf33b8d104af13ee311ed522df131bf24d83dac85, + 0x50fefb4229d0fbb58756c49b28c0ad0fee9338a1fb239f8d8ef12e168aa162f, + 0x1dc4a881539b03ca1b5493a594be14ebdcb60bcb2b4d1b58868d3a6558410173, + 0x1e7e5f574d74633a061ca773e969dce83ad758e4d08c37e3900f62c5f9b805c5, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x2d030d498dd22e5f9b3761b019f812c2df002ebbdbe5da92f38be1ff1cd97e65, + 0x227f6e1b292aeefdaeefeeaa2e7af21fcd012a794ca2c18d284661cb0fb1dcaf, + 0x9a991758be8db845ca4b488dfd11e27f0c773c88c2507ad584dd73eb1709358, + 0x5b3c08cb06d23cedf2cd4c5cd248514a89b09ff70ff56f90221492081480705, + 0x207e60dbdbbbef1f316198b79e4df3e688c3c71b8f82e0480763cf729b6bba03, + 0x1d94aa3d4e98c691b3efaae72ae18d50d90ae56629eb00e7bc324eb2362d27e4, + 0x2f99f4602d8a7612c573c3ed2232eba3f91f030f8b5c2dc6de3d8aa60bba2869, + 0x185a7fb027b40f8efcfcbbde02cbe15567d64ae6ac9bf206781703c07d6272ea, + 0xeb85ffa7ee5e9fa96ae4697ca527ee7bbfb69b5df611a1b6b715a30f9b69b44, + 0xe6507cc613c091c3f6d563b24b8b78d78262d7e6a470ffd98a1ca6cd0da5ef1, + 0xfeb286fa095e4decdc49ea3f57da799b2818746837f591941e67a93f2bdcdbf, + 0x157de51c339785fabf4ea584b55e158485bce7dd521c0a25160247a84d13e6b, + 0x118b39a323a6ab543f005f26c89c673480204a183a1f68e0100d6be4d55df254, + 0x200f0d9065e79bf29e35fa9ce14f0d87038e43ec1c1c2d4fabcca003e2f2d724, + 0x271b6dbd7bbbf9d98a9c5c8814c58923aed6e4a31d7bcf8d723561f5116df99f, + 0x22594da35eddc1850dc757649b53c126403a907c6113f39e940e363bd2830509, + 0x9a6a3e13a6aed0fb709786ffc8a7d560642a59f2cee2dc68781130407455a81, + 0xd5de9b94917addd8b8ebc8eface4fdc044380a27446e5d0170c4aa965b8e48a, + 0x1ba4f74d7dbf44f967060c619e429485254c8aa06ac08bb8fb101a4c88811cad, + 0x2bd393ac0c6602f63ef13835a3601f6c4f84f09cd47cedf02ab0a92f0f59e813, + 0x132cd8a625910f7fa7a999d0338010825c353659385ea10a419255dbc0a3456d, + 0x2bc9e5ad597c8f773a7ac2dfe21c16a9d5493a1e319dc942e635067ac6924754, + 0x21af2adf48b95cc677f255d44aea3d1132115782cea08bb82a526366b7affcbc, + 0x1baa899af3a60f883362aa1b88ea17778e258d3defa44fec1b3f4f9c13b890cd, + 0x1083673f89cf1ffe18b41d3cb7084270363c519ef6a16484220e30209f83d976, + 0x5a5be7182497c5c2ec9e91b1a4af88703cb01ea7e7d8dcc535d72a60611f271, + 0xff6f076a63edf8d87f70b60ac0d64f311eb1771d961b6b33867a6378181088a, + 0xab810f3e1dce08d5e5289d8d32a3ab20ebe56a1e3f6cfec818462804b0aad37, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x36339f709425b44b4b4158479da0b011c1a67fc8edb682b0a4437607b9aab74, + 0x25f49340da53700404b20e59243b4e5158b8a2dc24acb8f072504149481dc8da, + 0x14b076d2ce8f4cb8d8323ec8d743947a7c8fc96f149c0dc4a74d883939d620b2, + 0x4a6fdd5c06168268ddb9886b5b9d23f146ee182a155e175d17b07ddce7df8f9, + 0x8868cbb867db89dc7895e3c2c06466e0cd0936eca7e35ab5fb8f63f7a4722ac, + 0x13639b2e24f941877911b94bb9a0256f480021097c2f8d713c088c628d8fe61d, + 0x2487694daea37ed9f66185b6ba5700abd9144c18def2fb87af3a4fcc5b8a6b5e, + 0x62db9b179c1677bf6cd17e9bab4cbbc17a113c73c137dc6664bf4938f723352, + 0x25d7d897d92a0fafaca382402a1034b20ffde5b709d6092aad0e89ee43f48fde, + 0xbc883b75255e0e7b62094e1ca2aa65cb2a2dc7c4b30233f6e057257b25adcc8, + 0x1e902b42eb37ffe108655260991d4f28d286585d6e9c172b6d87be8e08eccf31, + 0x41a3b254a2c8446d8e99a292e24bc1858eb3d8fc841bc7e1ab03dd5f1c40ebb, + 0x21f4b9d60cc5ec13b8e87d116b27d89626bc76c0e8ff4caad5f825f158feefff, + 0x246be41807bdfd90b7cb066201cb33203cfd557d218cca9ccfe1451a86f4b258, + 0x13760f834ed0e52211b6d9b36080dafe079c30c279777ed992882ede9fdccf3c, + 0x24e75fe9b1f75436c465b22fb0520ac1afe2cd26e0a2d7b6476a3c9740e1ada8, + 0x210a9a4b2b1e03dd5fd270b8303f7bf9eb268844761f67473372cd665b1f319b, + 0x133c572bc84ed9a77b6651162bda90620f004f61aef467671ff8019ca6c09bed, + 0x1bc35641ed2b845a94e93bb2b89889d0b9d3338d45503f21f1fe9b0c09394eac, + 0x1ee1cb63ff99f240cb1d5f11c0abf418d696a0b73560afd9302a5119750daebd, + 0x25e5840c2abad4b937edcfc1ef54894d9556774b1e921d1a437278f8c3386222, + 0x137cac7ea18f1785a86b769785cfa6d919af27b77d7e1cf07cb4070275c91384, + 0x2e39652c251cb2e6a89166be880e1021996ffc55dde4b823cca3c305a1836794, + 0x3ec58cafe270aa7824551c1948911a0412a4985d79feef0324bd63960c6995b, + 0x293b947e1e6860bd81442b2c2a6fb3ae59375d12f857b5b8161e0f4bfb430ef4, + 0x2727bae7d504f2181e1910bb7eee349eaeb0480d214fafd019662edc067a1290, + 0x1be2f1a5593378d6fc1505e59c4c28ffb6cdf5859a5e2e1bb5b49a36051f77b1, + 0xb1e3d4a0d6e3bdd411c1f8dd4f2553ae84544b84a57b1f09fbdd26670d4b007, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x1f1099181737a09a66b13631030982bf438bf84d3715a0bed3cbebecaacac44, + 0x249a7a0b3a015a04fc08a2c6cbc7787aba1cc983c94a3d5074f584edfeb2416b, + 0x237bace2c06976c536b56fb5acdd2ac51fb2be8c204834b011106f03eb3a297d, + 0x20d83c51cb9e2a1fb0a0fa7f32c69cca88e6af24878f21fad622e364a6be6c1a, + 0xe65df5618a774c899d19e6a6d8f0aad4a10c347b12ac1fcbfedf7a9f17ed09d, + 0x16ab51042d2c056da53bbedaca317fb7543846fe6fb147279b5872eee7821e54, + 0x2e2d8b570da9329bdf02f5feb01f2b6e32fb795631c6be29e03a1c0ce31c629a, + 0x24d1fd499e7bb80cb2d0ca1fd09039bc4cf518ff43725796bc2b48d237c82e78, + 0x6a96b7d99b2b7a6e57cbb355217ecb8637bc3d4ded1e046783a6d5f63689392, + 0x19a143f1c5ff5191d99a6f144d8635ee4e4833b0b80a86434a494a6a97273239, + 0xd4e60cac8694ce18785f94c5c2f18ddd5eea3cb8a70ab4bc3e533b3baa0c674, + 0x3062c4cdaf43e790dea387e5bb1bb16a167f30e644e5411f9252042d516b8f0c, + 0x1b378a25d0cd861fbc9491836aa9c1fc169456c2027b34ac1b61a6d7090faed9, + 0x21cc1b4f8732b2a733b42718b6a48429df379711208deaa65a7eea4af1cc7d30, + 0x2115e1786ec90fa373ee1a8f50768702b3b89e4c0aceff138ac487343d707792, + 0x15ce8b9c8e950b1292ee1f80d7e271d3c0b714c1de34b76063624d00a686a39a, + 0x1d0e917e058eb6cb8ee32e9da420bd6399f8b2297876d84d997ecf8ab3b0d156, + 0x24d9b1d31cd6eb19c0c63513a6c3fb04a43033968696e954431d00f128bd6349, + 0x1e4dae551bca600dacc58fd37cac50bf2713052e2a4935d64471f585508f0d9b, + 0x11b1cc629721ced48c3494595863dee3de1598c11a681412062610ac859735df, + 0x26ef5031ab96b02b00df512752c7165e368f406857478f18d7230b6e4a1c80dc, + 0xd83775fafda795718ca9d4777d79b9c4354a73bba6813c415b3b970fbac6e62, + 0x20be2cd9b7d6dabd4db0dff89911987ab0479dd9c1c081fa64b97fb97c8d3143, + 0x255bcd5c215aa3bb5bd9e05f4bae4a68e152e3118fd09368fab9fe69e23149d2, + 0x1947d75ae45108e7a86d0e3e034bbaf27b7fe718451e3a5c206dd5a122a917f8, + 0x17af7f16f78c7b517171424fc4f47ba88cf15c4224bbd13afb3bfb05df96d89e, + 0xf736ed6532f0b90d30bcdcec9b05d1c59070f105255e7d60f8d3178e753c5c4, + 0x223efe61713a8d50c4d8f00ff69c45ea5f27defce0f08a9bc74e7a82084bc788, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x13a0d52fa98cce5cd43bcb4aae2038de35a787f86d375b019d7279a135ce710d, + 0x57d3beb3548cc7650f10f293fc2d393227dfb72422e89072dd8b90466bb57c8, + 0x1a6533a65e764adb163780a18df2e7f0233bef0eeb6276895c76a474998afb79, + 0x1913a71c0e6f8c87f433ed6ec0bbe2e7397544c0dbed7199c5f4b7edceb06a79, + 0x2266891fa5e56d0240ee9871ad7107c0d740398f8cc9165a1b09e10a2b740c17, + 0xf5652567afe30f4d5e934d9852bcee7ea0a8fc142b4822d2340853022128fd0, + 0x5bbf0f89f5ae6f5713c18b57ab2997abd8bc8c0fce08e2047ffee7ff4e8bb61, + 0x1a7bcce0d63b580b6779957d56f9abfe5aa8ec1fe610e952c4259091046d42, + 0x2b775827170698c370c7fc1706cd95b8f6c7750f338ac0fcde91ebe40cad9dbb, + 0x1b9c97f57c84b5f780373eeafecd7a4ec3e065219785272820672d59e985526e, + 0x1c89b9708064d8558f1361c6acba6d73eecd06c4e4a157abcdce2731cbea3e95, + 0x9a22dd01ccbf3e6ed2de7d74e16f58edeb748843b19d0cde8756bdf30e7f222, + 0x2678274dec9c2180d4f5b5e07cfb42c2489afa4673c61f091a5dd00ab0e6018e, + 0x1400af0c777fd9934b9fa5d1fab3576164ef9b31a6c8be59f72cbfee446aa148, + 0x2bb2d320c6f15fc80d7c78fd8110e715403df00154b1d275fe6422aae8d68cc8, + 0x912b48b8c530838be3512cec8d4c210726e17d660b2a726bdb44f686052300b, + 0xfce537edac05ca8b03b6b472dbe1813bfca33c05fa1acdc695c6e91d60529c7, + 0x1be4e4888a092ed1691160e4381ccfa8997237e78cbd7ecdf8c12066a49c19e8, + 0x28bd303aebbdad8a14ee284102ac2ac5e23680287d8c3587a71cc61ccd6c5b90, + 0x110b79c0bf8f52881c24f4e7598c5f5b30112675a2655ab183be54c69f8a85f7, + 0x2d17b110312b5b8d233dce3470269203776b47b85d143e1f45d59c1685ccf272, + 0xdff609373bc4eed749b401df1e7948ce8c8084f4c816844c29ea7a07cdf320, + 0x21445547b6584627b60ff1364308b6d6d1d08615de63a5c2ff1ec7f7764304e6, + 0x1ad2606e3877709593699f24a0287e2be54a2ba74f3551ddb1332c7cedad0d30, + 0x10c695276f9d6578a7bd5c351c1cab9affdeaf9abedfdbac72ffac057b67d7fa, + 0x100f820a8faa0bc1165b8a16f64ab9baa87fc7e94ee23f5a16125a71cb06b838, + 0x7bf7f1faf360f65cdf14fa9ff38b2619b616f2913b7403a4fe0431ec15a57e7, + 0x7b95e787e34c76215dbd3e1c548e5646bf3a061d087ad6477cf962a3cf73dad, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x2ec7afda93383730c9043913c6b866c20a5122081a7744f6d6a317b01177affb, + 0xeceed2a6602d291aab1064254c70fd4113a09bbf3527f603f67f01336915d35, + 0x284b37b2fd2c4ddbb2bcdd057a56680d46b7d69fac63b80c991f14db1ab5b345, + 0x10ddbb4173b040104f12ffb5fcc87bf6730ea0c8aee88f9e2c00eaa1a4231804, + 0xb87d2c0dab9ff1ec96017e8c43bb5281266fc92231375e78f02354355eb0c74, + 0x255c350cb26d49d41652f9a27f8d6c223b8756f8797c0c960aaf36fe91b4c910, + 0x2ffb78c0bea2534d67c0b061f4ecb9cff5cdc0bbb9ba0567b35b5434329ce24, + 0x16aec970d0f171ac2f7183d67c969ce69cf1f4dc73b38e3a72d8adbad367ac92, + 0x2e74c92c412e2d6943dfb7946c80f5fa9ae87255fcdbb98c437b65f97fec81b4, + 0xbdb1fbc8b81f57cf6725c95bb9428bbed046d555dddbaeb02b3fb9baa750fe6, + 0x7bf15085936894c23de42271ca102d554a45b54ae80fa0c7e6d7aa9c72cb65a, + 0x12e18b956f687e1c43f50a6571caeee8bde8d7da9ad5e5e27ffad30f833eae36, + 0x2c45b659cd395880788e5215997b77761c46555ff084f24a0d28dacfeecf5c84, + 0x2805d6c3bf0de9aa5c7c354947020efa9489995e8baac233ddf04e8ea8ba902b, + 0x18187c330b42dbf89ecc0435f0d77a7cec28d256f65047d4a3e1ac8aa6cb199b, + 0x2fef8da38b7959eacb7ec6155488836641655c11b8babc8f12e715afff115d4f, + 0x88011673864ca6778bb97d51eb1f2962b69d07a496b6b7b370cec217c601ae8, + 0xf6e83f3c55d5fb8b6b6c89e176a5a4f81a3a0acba7113ebee661b411613438f, + 0x2d59be2aec0efbc67f59da156d934313e8be205c1460699f0e70e7fe5ecfebcc, + 0x2aa0544263e125a82d9ca1beea6d9cf22b40afc7155bcb0f1c8b1ac23a24f6c4, + 0x7e3a92c9ebc149a74d4180ffdc30e8ac7bd6598d78bb8f3530403fcd9b12221, + 0x1827bf9f11d4061c506954039093e66e60041b2c96b8f7e1e4e550582d1ea13a, + 0x2e147c8ee46a45f0ecc64de8647e833b1ec708269b37f4e29b17c91b9bab8280, + 0x3117f4c71dc298ea7cdc53dc55f0a15541a369691622934416026bb1a65b8fe, + 0x122fefefa669bf51b544de5c0aca38753c8f32419b2ece3a97f0232e523f4cb3, + 0x18e8e58431e6dd229b88f142f9cdff129883bb54edba0854b29a8add15354d97, + 0x12e0b4787edc9f9d3b12781839f3edfa715accb3e527bb66bb08d355b87afa29, + 0x2489282bdb046d49227adbf0c44fdd3abf0bb2ecb21a2886336554389d452c2d, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x1e2fa77b090a5c2e5f1d37e25ba7d06596bfa3b546362103a4ff19bbacf7e9bb, + 0x162a1276d397eeaa3cd6ee80478788dad2650b1433b55b07919d966a1b87ce8, + 0x26eb2facb83a5a98dd405a0e6a94735a4c04c19ad847c53fbf047732eb114fc, + 0x2b7496ef4e35f11f739db9bd69ffbfc416a0c45512e31f86141641bba04f3675, + 0x26792a375f1ca2315b76d17b3f2bc3d6a3edc3c54f8ae682171143a91e48f091, + 0xbff276591776a997acb59a579846525f8fe7634d66c9477f5406b05985e7769, + 0x20e9af0c21b5cad7c87e554c98052eba561458f8f6b6534c4a1a0d0713681866, + 0x1f5e270d7be396c13a4f29cdb58c7e4f267423ce2d242c93049edea4b9fb4ca7, + 0x26ff7c1cf25310bd71e59d175c3c3a0f068a54c8493c401a3b67030922b5a757, + 0x1276fdeb195702a6a855465cdd5b807f685ce377132b625b3f1a5e934636e59e, + 0xfb72a4d993f139baa0ef2fb229cda32db7cde0f10c9031ff2f9ce3f2b883491, + 0x15a52948bb2ee184cbfd9d2b419836e859f2d39291654c082261a8a1986aac6c, + 0x1a9d4106f5a30c459a80769db1359ea4a3fa0e42cb32ea4ff03c9b800dd8bec2, + 0x1d9250e3e49f0b5829ce06d877703ee0c8e9a51b516f09df7dac3410d6a7b5d8, + 0x2524fab526c690d264888df207397be10a2626b71e97dbc66d1928e358bd243d, + 0x508f820d3a3cb5e0d30b4a9712a99eddcbd3adac2b1301f123e1556e975d30e, + 0x2ef65d57e70b07fd0a22938cf1065e3ac3996df77e0c100d354eebb224dc449a, + 0x26b914f529af1a7e31afa5334e60374474b998ae18e99efdf19e40b2dedd49fb, + 0x155837584dbdbc23962e00fa5a6115c10eee76681f25c51280a1bb2842d8488, + 0x222e724b780a46377b77fd83af70b53cb39a1dddccb0eae70e4d5dd6dded8da6, + 0xd050bd15578fe41175ad1e75a8ad0b27fe8943d894ddd74aed4b463b7f02790, + 0x5c5f00321782b3d2fa6fdcb67fa63d1a00a9f63d35f4ecb08481ab535907d46, + 0x207a0c370129f953e15836e8f91d7fbde34553f94d6b899e8645c96f1731f098, + 0xf875acc749b0abfb86f3bac9e8a8e56be9b9b55ea8815d19bee069150d27fd2, + 0x38a70dd168196731fddef341631e16a97447553f924d6c204d440dfddc0b1fa, + 0x1502b8a3411c7391414156fc640e8a51a1171ad07586bd6de2be2e38fc6486a8, + 0x7984908f8931b938e16c96dac3b58d151c4dd0a92d671cda98e16953c2b7f6, + 0x694d96a531fe9e369427b3457bbed265de03924ccb0331d4bc445c4260c551e, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x17efc478730ddf82a8540cc83c4770636959f1b0d8cf438b239f60df816d7519, + 0x6d6d06423d66562ef9caef0773f3fdbdced70fab47b0de7876b7bfc1216df7c, + 0xc750b14cdfdecf7394c6039339cd465a8a010272c1bff8c9190ffe3f0018d7, + 0x15000d48d85c719b68db8c9ed7e68cd481437c653ce647bb7c965ef9fc1c07ea, + 0x1b18af3d53da20198957288dca6a567b798666bc14c13dec46429100e01f94df, + 0x16e129dc67d5c08c79c6fdaf38def1b90f6257ce0017488b42ed2d46bdec04d2, + 0x1c958e9abba1ec33523e756e8be1e0fac90cf1ed314b37d21a7b4d3c84e574c, + 0xa4487b4c046d0e836db729d214a2b6995146b527ea42d9f1b1008d321a4c7c0, + 0x169b2c93aceb1182e58c94204e285380af13476c86b6c6ab3c3a65c15fa21c4, + 0x797bc2c0b8e08a4eddead0572838c237d0d825e236b725ef88269b0eea4d28b, + 0x2179889dc88d5096ee6914c03f347b9d9e7c5cd8c8b9930b5faffac69478b6f8, + 0x1057d99f4e9409dc2a83b8940d79e8e1c8e9c1b55a2a10f4261575653bcc89ee, + 0x168c49e73137bd006b0b0996b3da6d2562db2a94f94a8e763ea36f950c0f6342, + 0x588b7dc72c564a70347721e31544dfac82344701d29b12bcfcb99c951165ff5, + 0x30052c56471167c83d58a970764a1bb51f602f45b8fe42494182d48386d19001, + 0x284487bda08c8fb308bd9f50b700e107e82ac7ecc25ce91362303a2a2286af92, + 0x2e1e79d879db7beb9259bfa882fe3a1a34345451b230d4e27d7cc8358e43dcb2, + 0x1fdae630269a40c8ab1a64d8fa09af3a160bc7ec218f7aa5ebca2346c54590da, + 0x1d6caaddfaa7d7f98b2a093524361dbccf489a6d2bcc0ea1e2e13abcb025c83d, + 0x5c7c0b2bea90e985b2fd8c7e1e9801335eee69801dcd879edb5101739294534, + 0xee54de6bffe8629a8fef48dc9de7a50885054a28dc85c6649c42abecd607dc7, + 0x93c826c2837f20a15a7dab825f873ca79fee1607b2a1ed279d561b346aa9e63, + 0x21c75ffc19ad7b92256ac9ecba8768feb4b6eace676e2f6700c87b8ea6867341, + 0x2dec2f08ab0884ac001557f139ba7305a30d8c342d4ee53e4d4e6abe61879023, + 0x12612b1a8d7ce43e1cba045f5c0ff9cd61ff60a4df948847a5f352996c0150a4, + 0xd0bfc972a52fd760da54a5e78a4d47042f43be8ce046bb4522be2beb644dc8a, + 0x1bce51a4e501309316d08e24fda303a3f39e962cf2776588c22381009c08298e, + 0x19e6822defe86285515bdee389f08a4cb9e8042ca87435a47443cbdb76d30814, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x2e931e74616f42a131d4a8b56506fbff77845d8bdd66420beb3325097c35d2ae, + 0x12cb5dfc2abb8252e9ff46727444ac95b3ea73f0410424424488e144f8699673, + 0xab23891e07d9b14ab6468d8b54083479ddbcc3aa385804af4531058b6f52f21, + 0x76c297b77611e733d1e889aa59629450dc9a47d6b0f134ccda083f436d85a5f, + 0xbeb7545c1a73b517a6c89f22ad332b7e343bec5aab4aa67759d1bd5c513cc8c, + 0x4c7d041c29a50e697120f25caaabd6be874d81442d23142978d9e30a18fcc0, + 0x564102c95e897c7df22c2a4ebd2f41df79b27754dc83ddadc1e8fb5011bef46, + 0x2c05ce35ea49db3699362c4b4b64a5ba68cc375ad8aade0365ef5421901a5a94, + 0x1656b1dd63124d1354b1830de366e2c3e19075d195f6fe6dd5b28a599f37dcdc, + 0x2507b36b6b8e24780ab4b7be3c26ad57c16fb9da2edb33c3f1dadf3ad05f6119, + 0x126e91f50c4a00292aef54cd15052c4bc6114e85478479b60318e6dcca5d6c32, + 0x2f9ab42a46ccd83e7a7005d4553ad3414e5211cc2730424122170c92769905de, + 0x25aeb979b8ba4e466651dd441683325ca06867a60d27d0b51bab47a73ef3b303, + 0x1856e09404e55249a6d7114a4554ed94bc09dbe373ee994cfe64a06a70b2cb46, + 0xb6edf4c57e87dc5eb7cda564eb72f7673631ed91a612fb422487ad732be85db, + 0x2eeb7ac6201d76d7272b2b8861c44f18045fb30837baf0040fe472d972a0051, + 0x25e7df19e834ef4fc02b6bc24f1e45c42d935dc8e324467f216fb7456e344584, + 0x22254c3bfc63bd575812867c85be048ba6f3cd2d2b600594703450a16ba7b35b, + 0x1f04d9141844aee56a08a3e8b056715e347c668ccc6f1fda6dabf94b2a077531, + 0xff41228c1c85b1f6d2df6e37422bf7ed8b7dbeaba7da63f6f96bf9b3a525fc8, + 0x286cc1fd10f3b5e4d3b48d6996d85e284b6a6b215c0b862d5a29972f6ee1b681, + 0x2cb3455b4afc670928e65d5aa1461ed1f048865f31b87ff6bae6f1b13303a69c, + 0x23dd832c9d5244d3f7d185b3e8b3d759c11b86ce8102dd3811fc743e62a44dab, + 0x128a2af0f0d1965fcb13344373cc1bb6f4fda4a5c28cb7eb31fdec881348eb90, + 0x2b9f84c295307fd52151b60b7b676d157ecad172fc2a8cc89f8dac7dd6696921, + 0x10a3da81ead6ed37cb8334cf6c7d65b69862ed22f485b092bada3c0e516c48ba, + 0xd34d3d1a4e840d8e2cebc5d527a72ce929fdc7ef27e482a0f029a7b8c6875f8, + 0x5a6ae7b5423c19aa7ec80748ae9c1f5d189935cea5723cffe87ee7ceeea8c04, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x1578614d9a2967236aeda5f4a4dfff54693efe351787f006c743eb600a936bf2, + 0x285c79334945bed5f5c307dd65410ce6d6093d95dca5550146995d79028aeb09, + 0x10b5fbbefe482164a1e9c30bb4631861a12476186ebba60da59a8172a24fbc4e, + 0x1cdbb43b87d76d420ff6e1adef1ade355edf97a1646107d44993af476b78b98, + 0x19733eab4c8e4779cc914f07598df3bb1c2aca04fbdd5a116f864a85f7a81fe3, + 0x3009eeefe893a6b04a2d51a027b63406170c305d525e5b959e057825757a8ff4, + 0x2fe6c9de6a79e7bb2342a0c0992a9b8488b4bf43da0ce566e53bea4bd24e6018, + 0x2d40f2520a5df3a80ddab03db8ed7af99ea054e3a159c4a3fb6fe79a769b685c, + 0x22340e058329ac548f679421e17152d6106de7393cda87a9f7351cedd26408ce, + 0x5609d6cb0bc2a003ef02b3f62902f51b49bbed72fdf724675ede239432cdb29, + 0xa4481c88c41e347a2ef5fd6b915772289c2c90b91b3fff301844dabc1c51cda, + 0x14ade810e267932c4023ef6fea6ab0fc56063c5740a256c89e75a17264fa2898, + 0x199252b794492b2d35beeae8c1411bd1b5177e17af65c6f86ddd3261c2f8999f, + 0x1ef0142a7d35ea276712c1b5b86e1386201c18e3f774321cf69b6a0d2ee3f226, + 0x24cf18fdd7098067ebe68731ff580f7c01de7251814a4666ff518222130aa2f3, + 0x1087f37b188ac4ae2e05051a05b60e0579df8f4223d874716a6c251ab62e5b0, + 0x1f0aeda37e4d1e81150239b71a4cda04f0e4d8d7588ce691721df28fe9f18c61, + 0x1184563ea49c28693ec800bf53d6100048fbed518e1317ad922c095d486778f7, + 0x28bb14de4caa8db804e9cfd9e92cde9011c829e5cc88a709d1761638c88a0593, + 0x5e1f290e1cd58efecd18bdb15575356b84677a59c118b465b9671f81639783e, + 0x25f7a0d0ce8b40f8b02ca63dfa95a68e391df9f6d24180cb3cc976b4ce04fc11, + 0x480ccb16af84b2184c6f5b529a3d8f444f83dc11781a106ae10da23f61587ba, + 0x539296f5b7b7008de45d5c8516fa99db18f1a822529d3266f60fbb9959d4eed, + 0x1e424153fac06000bbadc168cd28c2456abc7b0be95eb89d8dfc7b9bba75769f, + 0x932c03c10fc912a134329f330f819e8d619aa8a9b6f52599e0761ba32c60e01, + 0x1211f6c693e1d0dea72aa0a0c505dcf1f9fd56e16545cae0818d554937473906, + 0x423bc3cd7620b919908d77becca14373a0fd5e3e9ba4470d967da7ee65479, + 0x2118cbee96964430e47912132f0d6f1c2e6fef1c001c8f55ab591052123d04fc, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x1f1e2374f0f17846133ddb87fa54430c6c3ddc9c532111de01eda3684f397a94, + 0x208b76b6732f2ed681d8ab9f1b5c510c8867ac976a3fae72d5f9d88676a75a7e, + 0x1fca7fa1aef782e5f42195a7691e73b90033df38495b91e5c38e820426446820, + 0x17f136e334658510bf76430b18584795cc8bef7a11c33a61b5259339acca3353, + 0x2c03456c81a5e2e32aaf6ff4f1d5720677c920bce4adb99d1d89a60618da2320, + 0x1a5ed510e6e51803fd72011c2d6de4c638d51c6d9a57dee093680dc336f5d34e, + 0x1a936bc6777c2da71bce31f6fbd646a3d62a815680203edc66acd1148132029, + 0x1b4a61fadb468df53bf54dc94e9a1892f69e693a26623b6c768c9b6f08eb260d, + 0x22072ccc189a669fc9c1dec178dee22e6810db51fb07d2e1c4aba223a89f25f9, + 0x1970d123b4ed8e8bfb50c817284430e9349f042e456fe5d518f499c071f89430, + 0x259064221267af8baa25e034c726164172e8ac0889f3d62d29ef05acf962f9b4, + 0x2287530ba760334e46b1a49861dd542fcf4151293041712c8544a467a9071ff3, + 0x840062bb032fa90a3eaad025fd47a6353793130aa0b8626565b48035782aa66, + 0x1d555f3bbdd6465b30b7da0ecba9891624d6d041bb781264a89aa7b16d346c0a, + 0x23d4f39d8b478d9f3fe9c56850eb091e6fb14326aa5cbc9b2b0d7d87c283d763, + 0x2901b8a58d07adf7c3080c1a36cd9d70652aea9b07702d07ad0923d758cdb949, + 0x2d5fd10271ad1b7fb5f053107e3e769cd3509ed4d501be13cfa1421b5394605d, + 0x207c3b106d337e3362d760cc41cdb5be011fce738e5f485d2b46b93c64cf9b83, + 0x1492c0ecb1dbcfa1c6635de3f6b7d9eed6613a602d44fee471a9757bc7b42898, + 0x1644d335356808c816d04419514ff5ec328dfb9ddf78e623cbbb6b20b4ed3bea, + 0x2fa67fff02c7d3ca002389d54c6efc4687da94708f6e27d1bc5825f164cbf4a, + 0x21e1ca08175564b26d688202433c40a419bdaf250b832229f4a1f31e8ace5464, + 0x2cef2de85c29234f8717a47931f3e7e5d26de54c4009f0cfbed5742defb3bde7, + 0xf9101275c6d82c585bb03708869626a1b0edf857aa536ba105733f0043efda3, + 0x13d2ac8ccf60c75462050c8f441e1ef92d1b9a842c36bfc82ddff6561efd49b, + 0x23a7cbaee856630abc2b423732eeebc1ec3e071391d03f9c9b51351c67943e5b, + 0x2d3d1ee5d3afda1af49ea526d8f250430e61921b93adf072ac5202b5fd8d0f38, + 0x2c40a0792e0eec8a8ff8b91a36835ff0774e11e3f13120c7a6a0efbbd6ef1f0f, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0xce2acb8e9575bad440cc92c82f19694f1ef1e5f0dc1dfc83c39ed80919709db, + 0x255e8b6bfcd73f20e6c4bd3f61ed3b8bd17626c5e5a843858093a7ef55eb1d61, + 0x71756e3a68459939af3577f77567bf688b996b47f0003c4509df83345846c16, + 0xbffe3446589b3eea6ac107b311307d20faccc7bb45dd5d6849cfdf7ebcec41f, + 0x18787bd666cffd2d76b9b7344eed8e34feb8f96edbc138486fbba2cd628ca4b0, + 0x24dd90cfbf38861e307d9dcfd5507b2298bf6b2618fa97d7e36b07690fa7c13c, + 0x1410db3d1ff17500d908b029552bfb5c44e3cad85b44d8b7070a60c359be7abe, + 0x114c5d80f6a4fac9b3962788dc0c542378352eb593c0cf88355d8c8032efdea1, + 0x1faae4eaa27310edfbc782b40c6ba0969779c813807d81630b192d053d4d5c71, + 0x1c6a9217a08e3d6b4961cfc839d6e8218df84ad042219111f80d068524566422, + 0x2779a31633b41cf11d988b3560faa03f2fef06ac2b58f88d89fc5f386f28b6fa, + 0x1fef33a133dc716d8477f6c00854b9bbbb087ad39704e2aac12ec22518ca42c6, + 0x51d3217b934abd02e647c9cf0f9642b2c35af886b2a45cc7b50fd3268175a65, + 0x23e2976b87ebf7b64a5a3aca1926bfb61744e0f4f8360df40500f479e052e17, + 0x266d4f55ce9e2183ac237c1cb82a138cfec9b415769742b2feb57d27eba7027d, + 0x220ed82038edb07e0f74092c809db76ce01adf533a42b51200f67cd58bada0d5, + 0x1739b7715b95db81ac96c21ec1fe7bf0bc6766b37d0572066766e34ee44500e7, + 0x270da5e7651be197e4b200aea12cc8b88c633d4086a0320fbd7b25ba6bb603cf, + 0x6f6db411a03949e6bb5c0a24f49967f1eb39c35eae012aa873ea0b3447d6f5a, + 0x117a292cd83ceb0d341c01e65590f4b38741c3ba51c0d717d273ddaae5c59cbe, + 0x263e482df03f958b16c2130b9cea9b74b47ee5d7f070ed5a6ab849074386f863, + 0x2803f7d7e3cbdf5be9306a32a90b58cbfc5490d1d74609cbf6384476b29265cb, + 0x142c7e2c2e91322de905b8420ed32d6ff157d64e792a38ee29cc9b316fcea3c8, + 0x147d7bfb2d88839714acc1080d935f9c289434d5d0af4772699bf4732c13323d, + 0x24bdce338ee348af82a60c960800094d5794d7a2607d5f3ccdd1fd4fe7b95583, + 0x10a0a7c38506d41a52e6ed0c4e14dc1283848beb7de73e0e92d4a065121c25e2, + 0x2f5162740cafbc5f21e10a4eaed36ac331b046f846c46a319b54d9e2206c892d, + 0x2c74369be037f8a5d985bf78b1e89838e0f7c1aa845979b6c5142747a0bc6b0, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x28580a3d76cb8ac7d4ded32ed3b70d34ba761e0b09803f10d1196eee812c8e69, + 0x19cf15cc84de7c87a59a44d02e83f88120bd3f7d1ab07ffac878a17320f4b2dc, + 0x21ffb716f9f4688f477d2b03bfb4c4f57fc37c75b46f85ff3d8da6e028263594, + 0x1c5e5652ee5c51f74663b5612d00e002ecaeac6dfb26d143e8f52a7b62c81346, + 0x309be74d7ea79ab9868e691afcd53fdd6591a5c8cedf965a1895229eff54a7a, + 0x8533bd365bcfcca44a62b4a3d7e1b0963ba990d5bc5577aca90f3edae8e319c, + 0xe7b927fe75b3e3322651fbdea1e01e7b5b9a3022e640476d39738a016e11728, + 0x2c044e77e1889c9f2efa9d217fefb1003978eaec9d8c99a494ca9c6bae1e980d, + 0x16ca28c9c6815d47c13eeb8a6baee797a2f9fe8fafccd65bc714c8165737d172, + 0x10e2a1c88ffa4f4f58ef6974b6f612c37755a1aac408008ab7b3b47160925666, + 0x2af08e42bfe36b6a795d78d34a4d4bfbba27adc10a144920d5709fdef7977301, + 0x1312b9ac40cedcdc7154c3a110803222b42b2b0d944ce7308a992074c0fdc257, + 0x1dc24b75a241225e913226bb4e43d43c7d47be4def03fd1b569eacf726f4ed27, + 0x13d3a4fe3528fbe42ec423e367bed051490e1b014ede6b776b07d8e15509d882, + 0x32d8f0cf21c697ffbd788f3f63ee8fdc1dcfd3ab649b39cb5e11a6bd2a24d03, + 0x28c7587692973d407a133b2fb5502ee9a51a4671568fcb05435cf0b5fbe69ff0, + 0x28e40378256e3cbd8a7f8cafdbed2021aa49f01a7d7056858bd3eaac1dc0538b, + 0x25d943e06d1e141cc39bf61f79e7af2d71ee93b361fc7237a2d9a8abc986056a, + 0x17081444189ad527d5b845af2a97df8c7a4293f485b483f9e8ed7021102f6443, + 0x1c79729fbddab541d2ecdafb93faac1db19b4de80d06b964cf4cdc81e1e6da71, + 0x45619b6eb27ecb55a5fa865895e4bb27712f4e95a84af9bd717b58e500de857, + 0xe2a9db5bdf2e81d036943df530d84e17424ec54f39c8039d37dd85ef65e3dc8, + 0x2ce50979f6944eb44498a1265db4d51ade51e18ca81bc69c0324103cd4116d6a, + 0x2a77de1a9d04ffe3b955ddb3ca44d5cde5ab83aca3057ad21d2275326fe032a3, + 0x17cc644fba9e3aa9ff2cb6b1386494c67079d7904d5d02828a84f100798d4ecf, + 0x231b0e5dffe1731eef0342d728926ae7c9d14cf32b1873115a3d47b231dff70a, + 0x2975aca67d081b04e4e00d824d5007a02f47891c5b0e6d74fe4bdc36a2c3dc35, + 0x12dfba0cbb1703dd03aa3c6e434c14e50ce09615152380a14b97bad4aec1a8d7, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x138e38994513bf4cda526bbb6d9a7ad3fa60bbb5b8922f3fa889be7f81acc688, + 0x233a737f744a6f8bf1fd4d3099a005b4783893e8203403271ac14116bb96bed5, + 0x1c8af617088b03edd11e2697f3f1d61aea527eb312465a7d1d97120547e5eeac, + 0x29e028abd359a281cffcf8e6def73b243c8c0b7dfc781fe16d85c9636647b689, + 0x11cebc3218317d6a3fc99fa24c0297c3c917d2c79953fe6b195043c1ef2a2911, + 0xd9eff7d690ca6de96fd8d2f757fabff01e7cff5f9af21a331beb5bf3c2b1384, + 0x2c10ae179ec436144d591b58693d48867a3080302df8f221f646d00519233ac7, + 0x195340f99f3142d58a8374368ba7b0aabe7551bdf4c84114c543733fd41633a2, + 0x175a317578f2686003214142b6ac875027c021572904376694f8469ea2da5c31, + 0x16ffe892781788c756069f60af49a1edaccddd1252b0add84fa3850c4f80002d, + 0x82ea1876cb380488c70f7cdc9cbf6c494a3dc6db449b27b2ad55500a9132673, + 0x1cac7d7d70279321973432ff45248a4497541d07c9a2b26eac2938d661eeee13, + 0x8755249140b336749da4930b6a82f6f7190eb05c7daf28948aed60049d00f71, + 0x207de9d69726515af8d068d0d26537798246579d29ba32be2dc2175e53cdd044, + 0x1405eac8634a44a35197a6503a005446b48e7f415210523162c39a8a8df15829, + 0x22f87c997cd1bd13a3cbb02d3d534c897528939d9e6714fe0c611c673d67d86f, + 0x143d40dbf8cd786ae5b20fdc9242fceb6224b64c187b36a7ca66489c86489299, + 0x2fde0b770674587f1be3feb619b4276125f643518ef715e694213e3134b7773d, + 0x160ea6110b10e9e3f0d14cacc486c0ba8f9bec3498024257ca96c50b2d2dec4c, + 0x15b8418dc1c46f3f546d70d983bc32122e40682185698f7f567f13590a1ace6a, + 0x20d9d10cbe767a538eca9be227274944094b9e9fc01b61b657afbdf6bcdff00d, + 0x104952b13891c92a6d7f1c5cba983aee4a3dfb31a1772d99192ab343d4e8519a, + 0x107209e0e414a0e40dffbdc7b52e2ae3de04e4385a8c810e92ed2bc2f67411e, + 0x1bbff156637ba8444d8679abf776687b8dc2462d876f17229f0d0b62b6eaf9c5, + 0x61f0e30d8aeca231af662496c1a4a5f4c6b283a79ac0e01bb677cb14fda83e4, + 0x3062b61d13e9c6d61471833d8e6b52f8669578314817ac28d650af7512e2386a, + 0x156a1c93bb1bb19c46f2d621ed100918d9f3194221788493be08644da83e4aa0, + 0x1366584ccaadb9ef95ec40f53e9cc7905204400b52fc6b9c0d21672fabf65753, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x727060f004a12682948595634ffb74c7351aeb401f8c16c31a333c8638cbcee, + 0xb43e5d620c5f01be5a5a3193bd458a6ee196533aa8fea3efbed64a83ef2ff93, + 0x711911f15ad7134cb9ff97051a0f73f346b4be3f9754508ffad823c11e60415, + 0x62c118ab0b9ee4f81d12e70d751dbff7d7047c895aec5d87b0e1dbfb311f9bd, + 0x1edc90b1e2679d7b61040b272d2ecf8d471417e3df89be715d5a85a6759ec37d, + 0x2bd026a17123ff82ef6a745e786ce3b69171c73f00a518889c320675a4a31824, + 0x18b9a646b8279f3242e40800752742093df705aefdc130e903026d7e6f37711c, + 0x2b6d003cb10653085f4ca141b8674a257140e4ad022a6e85a5681cd3f415f3cf, + 0x29ca967040bb4ef6fdec0008a3a1821b9a2682629abc6c2f37911be83c4d7b51, + 0x29c5fe585036f56f24bf281bbe3891d42d867ad8df031759f34586abd4341cc2, + 0x18250473c36c6b2fc023d9f980e9117d2b7d815386613cf518a5d5e1cd98fe8, + 0x21ecaed2c0849f445ce370dbbff7a0f4e3ab45444ca614ad818856b057d0b559, + 0x50f18bada3b7265d2194dcf45262069827248a1f68fccd800ff0c8f498fcf7d, + 0x1056d0bf8e1c158a403fcba81d1b25ed10ce7bbf7436a0f82af53417d7758da7, + 0x10ec2167737c5bf2fe50fe1c44e562a4fa629576c43c31c2a067d3f7e199aec7, + 0x78d695069c5a1d37c71299f3f5667516b76a4507a4320117ed26b3b6c05efec, + 0x302b34000b8a4c5f411458a6c12a335a1e0f345bd012c03e9afc62c8fc07dc72, + 0x25110107d94ba32e47336fb64a434e02f723e7a429eb23b8413ba03500c56e7f, + 0x239c9ad23c9efd9a7be7489e4a1240870a605c5b8e84021f3bace86281f5fe6d, + 0xa71eb71ed1cfc23167804f59bf51324c69d188602e732e5cc5a6e3f73455033, + 0x22f12028dd01cbb90141cfdf5497ad73403416e437f063e1ba391cc18bc0bc5d, + 0x1d2ad4ea7240a2f71841635c52eb7a7484cb97abd94c70bdb187724db31c953d, + 0xafc6833626de473ca08a5538a64a06cf9b604242f029c4ec576ba6a1376cf97, + 0x19e01b3ffd3d1c30017cbb3ed8dfd60838f70e001773558fc4a1c9818bd4c197, + 0x26db05b80a904a64db20297cc63e2d0a190ec9fcf9d528b9db88f7e079ca4d49, + 0x2d8286dfebb09365859e524291676812918ebcd2b5e25131884e71037a5def72, + 0xf3c76d71a422101870aca73667ead0b355e8f9a8009aa29941293e5cc105d, + 0x2c7142225dd5a38f329349d4bed6e06f58baa1c3dc32a6abd057bab3a45eedca, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0xd4830722141cace7a3d588567117cd756deae9d215cdec0d2c55c7dd293cf31, + 0x826bf62570b5a5f61782845b349810b7a481153e7ec33bb3667e4a2c7ce4912, + 0xb74da59928d6c22800edc212200770147b8fcbd5d40217cba2c1ae784ac3c66, + 0xf5da0d1390cf5d4fead2ae4e463fed71d0b1d5095428572009022a7550864f1, + 0x2704d9998e1e17d5a61ea377b1b78ed6d7ec951afeaff523a406624a99447c04, + 0x300f822aa4b956ea43ab45b043adc967d41d2f7d67445ecce1bfd3259e62df82, + 0x43f2876cf4a9b33af023d447bb90b634b37fd6a432b920e2dad4fe1b9f734e3, + 0x20d982fe655c37b7c046a07110e57fa8649939e376a4fd1bb6bff3f13f88dbf0, + 0x21d6cba8317dac264ca383630b4da90214d803c503ea5520c5b44dffe2c138dc, + 0x873018963b4084347ad81b085693cfca0345ab963f656890c90882cfc5dcaf2, + 0x1e6176f2c8c0e6acb5b02f4e54d245f806b9fa7bc126b3435b79e5819fa8c9cd, + 0x21d440ca5e509e1ae0476ae546df34414d7abf9152806b4c799177b87b153f90, + 0x85ac321a5407d7ee948b0cad303f92751532cb1b55ff17e7267c0c9821bcf80, + 0x225fc6208bc12aaa5deba3688931a2bc8617e6b4ae76c1de0e85defe38e2f14a, + 0xaa6847f08b61d6fc7ea711789b76255d14b6ad7de89124c962fe57f534be98c, + 0xbb3bf6dc922baf1d7a9f555396d78f31cfc3cbbc534c016ba6879d02cf400a6, + 0x24118b406a39de6a222bbb99be1828f9d70c24cce6ae452b20644f3a6730b95, + 0x23f88043dcf501f06a9ba388b05f1c14ba29078b978e7f9a3aba55cb0bf1a7b7, + 0x1e9ff4d090215f88d9af53bbf57282d31a835a8a052dbb19b5c0b366b451cda1, + 0x26ff7979c38be718b092842e02cf124d1cec12b426a5ed8351b832385ddee404, + 0x62eed7ae94588f149905a7d148f763c8422e7e0b6bf5cf5ceaf80f7a0754fc3, + 0x2ddcb93912364f750150441743c32dfca87fba3bcfd285a5cdd854cc312a6d7f, + 0x1a61c812aa97e5dc63b827db3b987d759738826488abecce0592af6e7281336d, + 0xaf260c0175dc1188ad11222368b122a1f0cb5f71d5df47517f2190748f803ce, + 0x6c547f8d368f03ec5aa00693a85d2b4cc56aad88006aca1e46b1eabb84a5d54, + 0x15a040ea72ef3252816f453da8dc97a9b417011e9a65b0a8606248591e597199, + 0x2e0ae86bd039654fcbf8795450a36958139b3e0941b98778395b8ecbf3b40e84, + 0x71936ae5ec7e0ec777485d9400a8c414ce233e07352a9ce683ae41943341c9a, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x1fc8ace75c85e6d3a7404fe02b03139b6a67dcfe2d14f7af11cc30a2a8ece33, + 0x263815b2a80b71e1222801ac39bd44faf23d0e21d2f31fd213d300689a720d8d, + 0x1a91fe38ad898189e9dd7ef77559185a79d80481808f4044daafed03742d3ff7, + 0xb99a6192c5bbf619624d1c7cc7d90930f1ffb79a6d4cd145bdb58a85f35e324, + 0x29df5b722979b8c9c63743c5d997b720d1f938edefd5a7359651bdce60c352fa, + 0xeeffa5c228914c03da9a2eb5fc92f23254bcde82c459c81266223e6fcd3d89c, + 0x2b3647ce374ceafb0ee9c4f5ed4762db7240d45a5b01f3873f2a4c8b86a68be5, + 0x21e2872db7718e97286c2239b5b721a58d89ca37d43dde81d5cf049477dd1c74, + 0x173909ac99ccc3ecd1ab2fb89246a648ae3abbe251ce9c0160bca5712c0626ad, + 0x2e2fd250ad31b0f543e958e16c10b3cc9e62e52c1a40ec5ebab4061d3880dd32, + 0x2dc7cd826f2f2b963a180b5a0fb1b5d20d4a7cbc860679267142a707c6ba48d7, + 0xcdf628de6b0bc2b35d3f9a0b2cac4cad27e7e1966c39af983d63e1461592bf0, + 0x2bf2f603e91d6eeeb104ac9141798accd525fa3e241b1182753d4ff3f59b1630, + 0x49c9676b595755be2f328863936312442c1c07504c5bfecd793e1eba7c3f675, + 0xd1fd4d6ff542b060b3b90ecbb825f0f890820144be4bd0334a2eaf8339c9af0, + 0x2206a93fd04efa7e79130c0aac582fa50c5ca7dad614331281c3d49ee4c1c67f, + 0x1b8b1f32ab840765cb6250f4c9c019d994fa5858c67bd585a5f4a7663143ecb0, + 0x55cbd5d71b787fb96fab44c8c6a1eaf3aea505c675c32f608ae0b6ae2e71319, + 0x24a63962fa639928e90311ce846f99b35213568b65cc1db5fa65555a0141ea9d, + 0x2d41835ec9c8dc848bf62b784a9d029cf7632369d3b6e9f6877c671495831bc6, + 0x1c3ebf1cde47404db2c523c680ea3df60668ad37b67fe50298c632b77bd3f625, + 0x4d92032856d1eb29140d9825a6cffcccf00f5fea91b85aaeb68d47391a67f46, + 0x13fd59cdc2da8766343e9dc78d0604c7a453c4a4639f1e1f66b154605dd00cd4, + 0x2d56a2d39a3db620d7b172bd74553d09cfada80fe7b1f2bef3fc4cc115f76123, + 0xe8cfc663445dc81cd06b084d36c85d946c6eb49871add263ce14f2b477ad27f, + 0x2233e0d00be5b7a77da192a5fdd91db5f196705ea0754e4bd1db5a357b335092, + 0x153dcc887f5dca8999d51ae06fdda165dc03e01c67bd8790316bc465ec4b961b, + 0x1e3ea34066a170114f0c76573452033360809012bb9ae4c24b6c1fb476d5d5d5, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x6662bced08b16d3d3a50c9dbca0743d66c2b0d5060c68983d8448ba7e09735d, + 0x207357fa70e47358e4df94e0fe2860bb2ade565460c2f2ac9968718b512fd761, + 0xd88b7243e4ba947985ab06738bfdbcd72be75c0539fc2c65e016612cf48a0a8, + 0x29032f478c7b5fb111f8d32720abc1fa050676c58f783bb6740b5876211527d9, + 0x1f58b00a5be5baf9e1da120d8dbc12a767e304eb63c0c05528efad2b95f6d010, + 0x5645d027e203626b8a8c15707cad7f9954b915bdf620a343812470c63d6fd5, + 0xab572420dfe8794515a8ff4fe71b0838d46a42e63b488bdbef2c6721668758d, + 0x1876c13f9de5d341e254b3d2c4bc8c272e270b58c863ffb16324a178986dd709, + 0x21ff416c00f6e478e470f77aead4decff3ab847e058e66bb56b1c75379d67d55, + 0x104056d5d775740ba150f6807d251607c5072fcb6d204b3a92646b76f97db4eb, + 0x2859bc2f280545367b3844134b23d2fb6ca07c51c42eec18800cfc795464ffd0, + 0x232f777c06ca70171d09129c01814b57a685224a3a752deefde04487f731dc54, + 0x2cab0c414d906b4cdd83f08fcd68d3b3554fda8f17967c89d0b281f9e6e8085b, + 0x291dc030472a4633fe37225419e9e26ab406b12c6c78b40bb17a9ed3af85841c, + 0x11b3be92352e34d0894a108302d097e94aede2b931b40b162b6792f127d0dd51, + 0x1821450cf9950eb2f0ca14ee17385735c0c0f6b58ecfb4c341732c580e15289a, + 0x2c7185a2965a3dfe86d2f88a14e66ff3cde5f1a4072fdc5e903a5367012d6bc8, + 0x19f8b88431be608148ecc8a862b043c66277c6d244d4bc9b063488d470f91c57, + 0x2e07597ce199e34f1a907e135ef8c7f1d43ae46459065f5ef56dbfada7b14086, + 0x20dd50883de922f31411aa269a38a809f86ae985da0dd572a02b0a115e57317d, + 0x1deb58e4db0e059b5e4233a27f3ebfd5c56fb7c8a2e0952870ff89bd985b7fb8, + 0x772b8311e52b960baba8f9ccb8d74d520f5653608ba810243854ca306e9c5ac, + 0x26508ad8ff73d70862d1ec04e406f165c53c04a0c3e466a11a2456656a2008a8, + 0x2e03dc18ddda2eea605f357d82c0a7a9e05f74d078d0d940a0e7506dd7dbb2b7, + 0x2651122e5715b7d5d0d396b8b0a6b3b219e1b5c95a0532623d9976330dc0c7a2, + 0x1d2fa1a7f55da05e2e77eb2c7ce09b4f4c0f832722262e7e57108223bf2e4a75, + 0x20991d3f8eb785ca08fbf1695aa09c0664465858de5f63e628cfd6dff4dfa7d5, + 0x2ae4c4986606935874c81b044f450a6ad91c1c6aba4670091cf83dd34d8bdd45, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x22d5dcb58b751b33e61941e034ec6a5da20162b44a67f2f2c2a32fb2bb19efc0, + 0x18a2197cf988fa8737f9ea1f8f7cf8e1b3da3a130177b80c47efb5fe8ab3ba89, + 0x56472b01f8796af3bb76fc84acbda7f174f54c3129f03f6b36d80375bef622d, + 0x28a91c2f74f72ecbe75a6fec418b9ff6bf08c731ca114d6609478e2a498f947c, + 0xecd04c63ed1ee68ae94d51633155868402dac39e3c8383e8f0d45ffdd1daef, + 0x2865c65b845d8061dcebbc8f2e91762a9af0a69c4d7692d60e3dfe98400a40d9, + 0x2f50ae99cf9753fc9a1344a654574dd7d4bec32df7d1d4b1cb4d03dd1f7319b, + 0x26b34e635792eeb315bf2e03ecfb8b00f7b6bfc137e759436fd0e5285fa5e8fc, + 0x26cb59e555d2111646327f7ec9cafb3fb4344b894d7746069794c491f71b5f82, + 0x165c43eda77147c1408da412d24ac1314a327a371d2f6c0e3dc2c7e956e96046, + 0x172edd07fa59daaeb04cc4a4c783027401ed8b47fc6fbdfce05543136805e1b2, + 0x2bc36f035f7bceca4001545d9fd98b0f2eae858e5c4b0f0e219121591762b378, + 0x22d96b2e558884ca077f0fa9c41a38155875af1e91f5e69dded36499c5786cd7, + 0xf1146e591fc72056c2fa40a35b202e6ae29a5e6d91180713ccf8ebdaeedb917, + 0x29510d1143600cbda4f235f0c6c480f436e20daadaf9461a032204de009d6fb4, + 0x1dbad14882314499c14316375e9b8888be4351bdf3b96e2651125fd03ca89a29, + 0x19d651b0c567b6507eb6a7202081fb6311e8398a80d53195a5b327b7e5810427, + 0x196d972248e180296caa0f943f4a034746a000205310b155fd0071bf6a20341d, + 0x2e823807f3a2c2db81181bf7761447252307c8c7e088f9a470c257ad83a1fad4, + 0xae07a00e65e68f06fb34219cf2f0b819ea6bf147168ab5f982c9513a661e10c, + 0x1f3ffa4e4b5ac02fa89072fbfa10d169ff5cf382ed54a86b69fe5ec3b025c3d4, + 0x94323f9b77a979d42a49cb1fd0f4a5ea253e908b0e96f47a308e44085f0bb51, + 0x7568c62660c919b4295dae1e761a5e9bd1ddbd05f77de4977e99ea46ebddc59, + 0x1d28e05e1aee78e0a9c10c97e01193eb1771c3dc84ac0af0b7e9b7a5df35937f, + 0x1479d6a6a967e7a7672a01c2c541bb92b677308c3e365b73349327f39f4593e8, + 0x6872919996f740aa2559418c0da042d15ccbba1cda06c95daef9f0ddde4a6b, + 0x587b0974583ba3b84934a500bd726018b08125f5f007d01856fb2c124e00e4c, + 0x2ee0bbcaf6798f8cc107dc4ec3157dfcaec549f36a87c934a83f1c080035adef, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x76373d256d68ccdb201590f87f661a13d618407140b6ec21bfcffb267e0dad0, + 0x13a5be09677fa0af3fb23e95428b7cf9e7b8276baebb1a39b87a1bdc416b270f, + 0x227a7259c3b2135612d12638b5ca5973ab9d6aa6d6a335781d81821fa8be02c9, + 0x25d96493ac371c2ba8dcdc9bf29b1b512f43aaf38fcc86f17e9d44d59d870cdf, + 0x1ec1120411deede740e7e3481b96ce1492b47232b208f15afb2127b41189afed, + 0x12067c9f5be28c0974e55e19274c65f752c82287637ffc5104b35799362b0f0, + 0x462ea3958f9c42d0b2406bec8e38576c88d964597ae61f1f07d811873c464db, + 0x20450babc7a6e637d32d8b57f218412a430fe087706d88eac441d6871f5d639f, + 0xb29f887572517d826f977c371341f2819995e65a2929c078cf4a937dc68558b, + 0x27d93349e2cac8325e4006aceccfb9ab165aca3895697e42e23b78bb1f172a54, + 0x1969ee0572799902a937545397b4fecbb83446841ce8525b714d765fb25d9028, + 0x1edebdf580772f616131435b17c46e0e385b3ab83494207efb4d9a32f4667bdb, + 0x430dc17c3f1957758e57ca93c94c5623073e5580c28cabafa400c2e5eba5fda, + 0x1dfdc9b2152615a4dcc8b252f17d97b8998543e84b9b8cedf8d683d917186b64, + 0x48a9afbd6c11ff4a680204e895b655e004211e495f2bc46dffec598bf40ce49, + 0x2511be820087db2191a273650de721dbf7abd3ce15bc9e95e2a7153443ca7fe9, + 0x1b255c37973fada56a1251fe07d617ce802b4ec2f60a002e1fdd9052090d3884, + 0x5c36fe03574074a04ceecbbcf02d231d9d868aae698b20582aa556e6ee34bc2, + 0x14071daf49fe401a508085071812c378491178f66712eee8f1cd7f611f8632b0, + 0x1e8a45f66dae3bf77aced336508d0b566ef1aa9d582d9a44b9028d2e1a5c28a2, + 0x3470d55418841efb8777bb16984dc9d71ca55b601c6a9acbcc06dd8a3a4e4b1, + 0x194cd0a75e5edf346e694e78b831d42070d93b69555b692da6fb979a78afce0b, + 0x22d1fd9d50ef28dfab1c35553601cebb2dffe723e366e956a2d9f2001517b92b, + 0x64a916906b28a8a1a2df80019b67d7e40dc686d00333fcacd63ccf129d1e281, + 0xcadf1f120a7ba6a73fb4f5980c5aba2e0e44280b5c9478f5d800e61fc39c824, + 0x11783cca91ae0cd06b91cacd517e51d4f2e7fb59202993dafde30ee181115b17, + 0x1563d52bb66c227361975dcdfcfd8f6bb9749f86297a5bd3a6be74b8d5bd2bc1, + 0x2e3cf2cbb16d4b6a76f171d80a9b92c4b8324721e6c3a29b77e2c9727863314, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x106cd44586872a1e98d029a76a334797c6950fb72f241e344040ec5d1e766ebf, + 0x267c81eebd4f9bec2d7fb13ae6ab345774192825ec38779a8883265df4b743b2, + 0x5cde6fbc024c52d0dd9c940b9450547804aa6aae2bf06ab7bb2c3946fb09aa7, + 0x1db696f29132c9a065e392e606d3bb4110213b88b7125ca0157a776212418837, + 0x269b78b6fb577d3a5463b0b88bfa91ad56c1f7768b55a6908120ebadf7faabfb, + 0x1e32a4b9639edbd369aeb322109c919476aa85e28c2b7a8a111f9cd906bdfb31, + 0x2387b1982e0083a0621b4305c2faf4aaa0abd33dc265069e9b1d59673f5b1816, + 0x16f2a181e0d79d0a39169a1c9389d0b67e50fc5ecd2598d2d875ccbafc659ade, + 0x1c418ee3dafe2d97e5b84ecd7625b8598c7323e4beaa809d77cd7a3ab52f5c57, + 0x235d1dab5f72d1b0c0cad82e5f46ae1972117eba7612ae0581ab85d4dd9b77de, + 0x11eeabcb505206e74ddf6a4417f4d6c302d843dad5e5c1e536004e100f729c4, + 0x14b4f6ffdc590f859a491af89cdcff26ec963551676e4e109f333c34a0b3eca3, + 0xea3a8bd722b025559ae438ef85f1fa8364cebc831084a3129b7498fc7067aca, + 0x26a63daf3c27700bc4e5a0c13c12a234e8a13dab66deb6ff2a8b805b107a4518, + 0xdd28ac1c88f9959311bc53387840e131726a6ab9b7fdba12f403a3095034ae7, + 0x1221db6f8687604bd35fd586e0944a36880fdd1d1da2b771fc06bc80480d89ba, + 0x5dfb8aad4d6b89619e41ed02e593f0de05dde06b6aeeb1ee8b89bafb087234c, + 0x10ba8b3d427fe867422065e1b2a8e0d06d567e73717deaec3438fe36b1bddd55, + 0x13cc217fbf1b60972234be03ee877b96d287e30fb869bf816662d2887d2dc68d, + 0x1031f3acc4288235e55b67f3435fb1915cba9ce0d0d1f12e0e602e2d605497c5, + 0x18ebdc6dd67f2d5853541af16af792756aee1dd1132d3a6b1d0734db793a46db, + 0x10a4bdea8bf3a0440f456c507069645ab3738171f896cfe3b5890c9a0abebc0c, + 0x21e5b46f2b85977f8e4c67f37c30ddf03556eb1b56d8339f046a7d1aa8d9bbc2, + 0xa8735e02e11c8a1e0a56b24ebe7a39223e2beccae352597972fadd8f4fd3abb, + 0x27d5d5655c3a948d91278714a40fab8da89ca600e748a238014c98b932609fb2, + 0x18b4b6e0794cf364c6d4b5fb44a2899d4ab038d6b15ed634c6c12accead7e73d, + 0x1b89b8c9a5250e9edb3b9fff6e54be5b8c173bfbecb8eef3847d8718de0fe29, + 0x27a5ddf99d9c4cdc9643219a9cd3e4f47f63a581af9a499f8e064f4d2c726a01, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x237b081a68e30cacc4213ba3d2b153672483ed173125bad4014448763d2dfcea, + 0x29af4e6cae10dd99b672d741c5034f91762b99be844b0a938e967009578e6ccb, + 0x91bd6b2497eaa902ae05480699f34734c7f74b073af6c4c559bfa3a33d4e6e8, + 0x2f7f9c0d61cb36e331f2780b0edda03598067caaf184dfe95613950f8700360d, + 0x244d6e7fa5583e36d41ab75c679191497f27583a7ea7f5cb4e87feacf2b4dece, + 0x1f174e5f54c883afb9ae5b7e955380190767072e59db3a1e1b90d7035521359f, + 0x97f23268924c4ccf4659499274ee72a1a9c83e43178454d49d675f4e5b27150, + 0x3d2ab62fef78fb69b7049c41e34e6f1870662b336afbd1518ba776218600fec, + 0x2718711c73da1e256d1b5c21c6b2e5e43e2b0039e86f78fe5790e04b3c7938a6, + 0xd396383655c27ca25603d88e3d35c3dc6334506a93d6909745e52aa7854bd4e, + 0x1c66fd746293e23154ab298c3e4ca0ca14980c6a0a3cbac979d4ed8fdb9f692e, + 0x15708a52c8abdc860d066e0ab2a6b5b5cabdf1301f676b07feaf5342a971caeb, + 0x2b821cfd139e0da4c55cfbd8b67a7d7a4e7bf5e3ce1932b96f6701fd39e926d4, + 0xaafbee598eca5624a31b7f40b836023f364d41b6b24d0d7832eb180a60885e2, + 0x15c92eb4730eb68b229bb67da73fff3ca720814450162a81d1a7a56c83c3fc7, + 0x2f7200c5afe273cc787b0add86e9e0380db97cba269f59d0fd264b9ef144e839, + 0x2eac5180790ad9bb069b4f7e1842ae9fb0b069216c9b412da6094e2a69572126, + 0x1b7a0422eaf807c0c824c511a7b52be353c2a3789591deba9bca9a99e4d92869, + 0x1662fa1c78a1621b5bbded5e9e5880a86aee481fbc455b3849d16a37cdeda515, + 0x28972f5963c0ae4ab2b03cb80b4ae1f1dbd905fdc3c657550648bfefc4c719cf, + 0x2424d119a1299933b209b85d4af1aa89f8523801efeeebbfcf49c1b6f95ac740, + 0x262a05cbc85dc177e174047c94905083a27b4d887f8050c1b98a07608ac8e373, + 0x89d1b0af58744cdb06e1c0636306751f6b6ede06527eba770eabb7195465a93, + 0x26d8b08764b7240789d927ad67270da8521ffd23995b67f3b25de7fc60f033c0, + 0x19c594f452b69d9aba24aea1f48887b5b2bd351e7bc6984e56c346264e5c5f28, + 0x9a984983ac12405239b7d71d7e94ab74a5d7e23b3e651f61988e258147f5a61, + 0x2edfe7a5c13ee6fcf27ca3a98d230c3158dc1eab9a12a734e78e69d7bcc5ddc7, + 0x190ac6e66fc0244544a3780ae6c5a0d6e56894965b345a1b731cd96c89defed1, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x24888d5352a17beac4d1196b9ba56563192a21650b6e8cf734abbb5dc6fe0b86, + 0x27f1a77d912fc4ffeb051b44845cdca1360b3dff10f646cf4e2e31b0b52706ea, + 0x281d4a45a8beb80c2974562cc98785b37551ca4258c7b7292006e387b20d5f49, + 0x1d06a2f6b95d207416e97b18e0a33aa504251bd5473313ec4ba4aebdbcac8dec, + 0x11dc2b5aac6c6b58904b8370d622f408d4b8a22a54a59f060a9336509285500f, + 0xf03457b87c6491c043633bb8f90a9dba8eef6067f86926dc4df4a6145b9cc81, + 0x17982901cf92be1b7f477e61747a5450b97ddfe41bb5d7760bd1c25df17eb204, + 0x848af60d2939b3983df6d9fe56343916aa046933c4517a6c0c29025a3da1781, + 0x1dab170558f1782df01501d1a810d1f491caf3a03a5563c8638eb6649d852272, + 0x17c31798bf48cc0a63986b914236ba21a04dd2a2bda0afcf15213df56c46370a, + 0x2ebd4bfb0ae3e1f540f31fd15a70e59de4ab8ffacd899d56060ba394e224ccf7, + 0x16c3ea32466b179ebe57bcbbe97e3a7f94b0a4b3e091f15e3aaa9222e8b182f2, + 0x157740e3058872c28ca7331055f3daf8b9aeb36e9c2d7d231f22171c6315733e, + 0x6a974a75d941a54412814d68e6955b7f4da2b281f2a9ac426afe81b98ec27eb, + 0xfa950037d21d72090c5bdcb8bb6be911ff4a359f3e76ec625c64f1202bab37, + 0x19065585b553aa2649a420625c707e61f7e0e70c753dadf474bda8fba0354fd, + 0x183bb2b9d85c3a9368017cd1e1cd884967c0b048dc243f35b6813af5b279872a, + 0x271a9d19b99115dff27a86779104a54b252373c18105cf5f86ab5ffcb2a9942e, + 0x284fd24cc3cb45ca644f15228d786fb82cbbf3d66f1a276ccc3a1182af4fc1bc, + 0xe62b392dc27b2b80a868a9501c9e1c72410bffa12b77732ce1df084ed0a7a30, + 0x265311e1422fc3e5cecb4158eba0b249404842b16e8954bab3d80d6805fc4f65, + 0x1186e446615d83a940d96d2286d9b411b62697864531172f5e8d3d9ab6a5f9c9, + 0xa22515b9c7fdeadf64fb896271bd8d96f1f53bdb32ddd9be7cb22400d69ab77, + 0x1343f2ea91b46be725baaf77a092d6b790c1429ba87a3d4105e005b85c901551, + 0x2a58da207ab04101d89a09c69f8d8309d8e8a938deddff70e2eea30f4c884bf7, + 0x1bddc742015df54718d5a89b181f3a0110732b0ab1e014f63202f6d9eca2eabf, + 0x301144f5830574650e6093a4b75b9a34b59066777ed21d2c008f2636177e9b61, + 0x1ef4af22668248890aa7ad05b07462d777b0f09a98d8c17d59ed2a127fd2c55a, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x25b20abb9883f59516afd1b89f80c4b18be2270c4ad70f7f9f9b9188c9809ed9, + 0x27c5f600e46a854a26efc7ede1108cef8b607dcfa047c259ec32934669c1d155, + 0x1fcb1b54e79f2f06aaee7955186d71564101088f13837f11bf2ceaf9393619e1, + 0x1d24da31bcb08eb64df9e69b729ab135cf1b63cb23c4c8acc073a9d50f33bb79, + 0x21c0a2bf8c0ea05f8f319e57408ec4ca46f0003325efdeb8c84b23026d9a8952, + 0x1931ad5d7ab126465234d8fa1905de0f77eb5858758e6c838d748f23508ac1df, + 0x17af6e15929f2bca918d404d56b4cee0ccd8969195f2f3edfe56dbd1937baedd, + 0x36b2cc2645cfadcea80c47cab8cdf6eba7fb8fb2bbad631a5cf24fce6966854, + 0xf10bbaf98e0b1ce2cca1977ba2e271b89cf46933d4c7a797671c8fb0754e10d, + 0x1ae0f9bb7b72a3239de677048151e6dc40637e6559d726158debfe779a72a708, + 0x1912fe07ee7840b055e68317eded61b0283418138b9fa2fee286fb999da2e6e8, + 0x24a8a1af47ef25f18b39b5caa36c1a6df571d3c833fc1c54fbedad560aa5571d, + 0x2d3f665ea69116d266057ea4e9ef5225800a1cb2ec6b7d6ba9f3edbbfe1faced, + 0x2c5b2cabc24bdcc0e95d2e54c52c0fd0ceeea439d8fa83c0036feee0e9730e3f, + 0x1a79348c882afaa9480c28acb01547d816148bfb8e70f22a0ad3a3f534bc0452, + 0x3942e232a30d4a941a32ab45958ac49b08b0a8a416ff6dec7edf4f0dd16b8ff, + 0x24de94fdc7fa872eef8ac471ba7719d5f3f534cd988248c154ee122ec2090ec1, + 0x13af3a6a5530327a659e6bdb0e3f2643db75dc7e9eb06a5c139d84a2888aefa7, + 0xfff230d63a7ea1823e5c5eb49fadbb46522853f0d6eee45948d326f54571ead, + 0x1f67b3c311ad5eee7495b1e9ac1236f8acdd8dbbf5b20aded3c3947baa0d7fc4, + 0x5be06d2aaece5cdeb721c87ce053e8523c8992c91a1884edcdd72b96e8e448b, + 0xf3b86d20e5d8b37d9c47c0a1e0e5654edd5bf9fc4202959848cc3951f58971d, + 0x28047bfb585f17ad6e7cde5bc033d8072f3b3e90d63b884df2ea6f3a24d10603, + 0x1186aea12da52c270bcaf4bd0f87943cf5cd9ddb63bbbb2d7f34dd184baeeed, + 0x1e4d65e0bac14ec3fc7970af0d64f4ca9b932012dbee59b3a93ee42b8e52e06c, + 0x265d09835a19ac5c29f4327b9df3f35988ca8893c1ca8813a1f92b555550aa0d, + 0x255b843c053e9dd9b00d06db176106b632b4ef0e6e345ed96775e4ae313dae6d, + 0x1cdbf2d9c9e1f4099652361d830c6d691ec5eb951ae3164acd715f49aae612a2, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x26cd056174dc2477de6fde6a95b7805ed343877ab35f7bd16afceaa9771fad20, + 0x286c63dc377caf0ca4697164bddfd29a79aec07b52ebe4fff1a4601bf3178ef6, + 0x4404a2d97266886b3a00244a049d2232727c70f864afa44d11a2d37ba4179b1, + 0x2d7b33ced5c2aff1ad6b4ccd8482024effb1dfdbfa20ceb1f2d59aed40da523c, + 0x1a5a78c756a7ee0cce31b132cf6752a1fa0e904e2d6dd9ab3818fbe9426d24ef, + 0x26634b7dd87a8c0e9878b1383582b9a3bf658dd13c467e52804ebdb1698044d1, + 0x2222ed015dbbe37bc2578814782740abfa00c4118dcadc8e6a656587aa25bec5, + 0x243a463d1befd0cce1a46b772f3d11351d47cdd86ff8e0a6e6b8d0f8c7486da8, + 0xf4a9dd0ccf52f31360db5fedcde0405406d4ce2042b1856c7c14bac187ad37d, + 0x25c6e507371aba88824acd8974ec363c21ddd450a13b130f38eacd5dbc5e8c74, + 0x864d7ea740ee93ec7d2ffeb7adf4a03174c89904d9c33a683d8897eaba353a2, + 0x146cae6d1bdb0318058f424e893e0892b0a1070de370a5f460444ad2e535a920, + 0x1ebcd64df7ad6f0e1619e26eecdfe6e2ff1e69210578cdc6c052e1451e9c17c4, + 0x1a7f76a8b9a868b7abf0bbf29992d82728ad277aa0c48d2db00ab45c7a77bfc2, + 0x32b7050fdbd512fdcbc9e9f530c139f120df1b53f26240c01dfa397e227d62a, + 0x118e701ff219612ffe9524bfa2e515bbe11f2fd581a4371f18d7f45f64c7aba2, + 0xae4dd0aa671c0a3dd08f394fc0eda68ab2beeeb58c6c94e60229145f0869468, + 0x187cd95af561e161bc1a2954e04a82488721c80e7b970b51a11e318b43e3c340, + 0x13c74e83abff731872630e45384b122ed9fd07176f336d1c3e3b87837adc1c39, + 0x30392808edc88e0c24a9f0f4a384e3bfdbb65382fba12b4e7ae01b712b5073e1, + 0x1bb68781b9f841dcca210b93a99320760e7f3ac43b4ed9d621fb50ebc3440467, + 0x514eeca7cd002d04a4716478bf62c108b3f314a288be687fcba7c6d5103ed5f, + 0x1a4c1caa217b647d099e3c3de03d9677dc2398277856140804f95848275cb05a, + 0x1959d1f1414c9a59879e9489315264b7691dacd96ad16f890ebb2ec8c55f40a7, + 0x2c0e761217503c6c0b20014558eb78e6314e607130844c97ee67dbe1940b3d4d, + 0x248c9aa70622ffe24240bff18d191276417eff7762d96594e4fdb9d6803b9609, + 0x21dba9d46e89f5875fd5e925eeffd10ddfc09ac71634e69c61e9805bd0a07d1d, + 0x21280806713dc524e7eb2c697ee2e197d89bd2e73f1817609be21c35dd5bdd5a, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x3cd1743a3de44e9a172804c7b159ec17a83d2ad838f9a51f5497bb5aefe9666, + 0x64682ebaf66d718813a4d06db5e8bdf665dc8654df4af96578526fd7eff644c, + 0x27bdca50a989caa4dcad2f45d2bfa7e6d455549753fb3e8c4c3ff2553803b024, + 0x263a2119f3bf5d5330c11f3036d2521e40f391da9efb1879bf1af39f5f4dff0c, + 0x2df2f13f954b1a7cb58e84ca4f3e2ab7d0f4272b559e58c7dce7ef229213c5bf, + 0x2ac40d567d483e8d671c8e194075fdb2ddf9ec51a174219e8c351dce02d32d52, + 0x159b9154fbbcadc7209c9978cf5783aa8a47cba1a729bb297182aa674f7fd820, + 0x1a2295de4f8dc401aaa4a2b1a83d62fdb4828ced253dacc132ec9d5186e1e2c7, + 0x2404bbdf4995ad241cba1169ca4d85d5ad276ca9d009081ee3e2b5181d46d29c, + 0x6fd221e32b98c2db6dc1602ead395001edced38761cf45ebbbc340ea35cd7e1, + 0xaf3118afd7dcf599b5c65b5a3e74a8ed04faa2791f47cd2cce3a31e541032, + 0x2b2dd6d065365f0b808bee0a2f7ec63eacb1990cc04608b08549d65024113ad7, + 0x180941c6fd6e1dc8a0aa4fd86020ddc4928884b68074c8d78e52764aba6c9f9a, + 0xb86cb785671c76300f9e6d4dd23b53aeb9e2d5b6d209f966986aca09ec59801, + 0xae841f0d25bfbd009e0011201b47e2042ea8d961248d90ef9d44a360b317617, + 0x1b2f66bcbdb6fc59dda5f34ee11c654d0f2dec29e31928d5b111393c8e0f943f, + 0x2f16b66d80614604ae85a13440d46bba9d09d98d5161c878be67a0dedabe3aff, + 0x196328adca8167c649b987ae985e9e54c0822077188b8af34b3c518dc21416af, + 0x107664f2d3f3bc3ed01013faec284477785f08e9932b4226945efca7fcf56b85, + 0x2fc54bc47cdc7f7146f9b81462c64093374c71647d4ca27439406ae6e6f7cca9, + 0x8779b3359720a0f3e0898942f611aeae102f875627f2c973c97356554911cc9, + 0x2e30be5c5cb07090ca3249386926194684d1f3d2d3ddc114bae2bca9d4a07f9c, + 0x1ea45a4f0b12b578b58600b9d085aa8d9c68a583cea665805b9389f8563d53aa, + 0x1753a308b286260ee6ec2934cbd59f0f211c11647cbf22f6bf5fa7c154c0f577, + 0x102ffeb8a2a94fcde9001e08ab603aa8975edc2465d6de14b73c14df40d61db9, + 0x1ae8a9e95ee69c8774f8d3a8ff484788ab272d3d174f526a107b2c8ac34ecd95, + 0x166b84b5e6975b9e8d7ffcb7be641fd89c53d1b7238748e85f32084ddaa3aabf, + 0x2b2e47acd6445423d9e61e96965da98e206b611f52af1d13becb4ce4966e1a3a, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x10e7554983562b62de4660b318bcd5324003e95edc617d6b1c23a97b93802e4, + 0x187483dca9aca475f85b9f8cbd78aa6048bd2c848caf3973c8feb07573883a99, + 0x2c13309dec41b4df5d8fdda2b063e8264c35442bb120e28de7555569ee771f8, + 0x11710271c6783060aecd410a60cc5c96641c1cb26591b21632914aa9fd94eaa2, + 0x12bbd77d7be4e06b77b5c40e1f9888054041bdf4f8af2c5378e6386337716b6b, + 0x23ee2c9a0d3324166028728c80d60cf0e21a7bd9ee90817058ad3b87c6f28cc9, + 0x58dd3f4009e8ac3fa07e285bbd7391c2dea81930c732c3a769c9c9249084d71, + 0x128d27c4805d2365d84c754621ca2d1a82297ea43dbeda87c0baef506c851079, + 0x20f552e4cc3a62cc2f3eb768b69d8549ef4c24d2887d7de0550b17ab4f7b436d, + 0x235730472fedbab358bc7dcf25b1d0befcc70746de99e78a6dfec8f626c5a9f8, + 0x280c2ed868aeacb6be7c9e773b08c56f43ea871c01acfdf9ff5ce9d4443d3376, + 0x1bc74fb92afe9db8c0da68365326cd9944db988b65f46d032989326fd901e923, + 0x2d9c89c56578fa5031afd1a53d21212f1c3ef24cf7076460ff533ede5fc360, + 0x1e2413f3b8f23a2304735feb3fde9d2d0f88d8aa72c1c60eac921588bfaf69cf, + 0x53a4cbf4b57d882174b8891d918af78b40a7caf832c2e2af02b8ba5bf5c1cde, + 0x5e736b9e5f8a1b93fe3aef1ee0a69234f7fe62ea998a9f2559f650669d76dbd, + 0x1e88d8b3d140ec659d6cb33736a0254e178fc6c0c37d2fa5b36ae4a85b28b5a5, + 0x257237c9ee699f5d79a62f2647a3b51c8362759cd955f10872346ab3b401b04a, + 0x2b6d25849d6b81e36cd329d20ee973c15cd9b62921e27acff048e7589ddf7739, + 0x1ac7317e2e5e3011420558ffa430fcab50b2f3fb778311bb25b1019c88ced146, + 0xf3223d7e88918a33250b61acdffacf1965a5ba9807a23cef7c89c837afe5b93, + 0x1f733faa9efa2db68363757b1a50f443fe9bd4e3b8639f21f1e12ac25ef00b79, + 0x8e2e6b13aa7a352b8c33d0f52939c16819e6a92f7159986588a09e2196efa3f, + 0x208995a721ababfb4d527db0b69d35d50e263bb1c7d97b24ac52c2b316b58727, + 0x1f91d022a78f70863204042dde629c18af85757bcf4863b3eb916a8af132ba1e, + 0x63a2f4c8d518fa72d9ab87e414eb7ccae4ed3ecb6d24fb734d68b43a92e8cb0, + 0x2915c64a0bf35200cca5779c140c7f9e888ce72b9c458a9ade0f0108eb2ccf5a, + 0x17a2028a54a30e4e0eded3f7d8681d6dddfadf26ef5c43cbd1952e584ad5b0af, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x2aa225f58d57ec9fcb1d6a6711daed13537cc6db5dbc485b21a8c4b13ee4ef5, + 0x2a9a824715fb8db1d5d27fe975f011320887f593d36d6ca7e2be7cc305eabbd4, + 0x9bc4b62c4e071e43c1e20d96810ff912dab86a98b4870d66af75d10ab6578b, + 0x2d7d326fb2cd64b543ef4afc9d2969abdd53042e6038cf53f12d36ba07c21807, + 0x1e66dbd30fe311dac75382ed3843cfd75e560bf2634f4213a0d37be91c269cbc, + 0xa6115e876e097c8651c2370fc0c0a79d4f67199cbca00b3c69891c56dc81cc7, + 0x2b4cd16c063e8d125a334909b5f9271bef61a5e6fcd117405e24b7a8d505453b, + 0x19734eda61ff0dc7c62643d71daeb291cd8f18e1083f82a73ff05e5f8be31906, + 0xf44441cb1795b60b9a424df927fb54b55a53c75a98eb90708fea4b42da18eed, + 0x1e0b6f3e7526e310b7b870cccf69b9d716929e7b1f078652588617ea0b71feb9, + 0x1abfb56c8889d36a1cea7d9658016c9ff5418745bc418d8134eb44e3700d56b7, + 0x450b96e26195e4290a1e94d896daa601b0bdf44651b8575602ffea487fb536c, + 0x75d3fba1c1f0b0869714cc5b4e54a019e13c5a9b745bf38139f2b0f09c93231, + 0x22a1e5663700b7b7af22ac5604b120c3ab73294147889f73b3c986a036fdd5c2, + 0xef19ddef71117af6afddfcb5ba454602d35ebb7497d65ee1e7805dd61d807c0, + 0x293a52d85a881e3845f02993f54c6af700f6344def2da90a2dc13a714760e224, + 0x10f47c70823694adb395246c750745eda7fb57dddf5f6e71ce1a41c2e9839cf7, + 0x5b7b0f8a9586e0ecb9df50b8450b577fa537c94ab7b770ccd883184ae2718d, + 0x2694639d8fd48e40ba301e56097cb270ca1e4a6d0cb5b09933142aefd1c44efa, + 0x2b40678245e68225c4c9d8f78d2e660c5e7fcbac631d1299b1a78df3b283b195, + 0x88322cb02937145ffa566b2f0256d5c8dda53b85ff611a658f4de8aa9ca5672, + 0xf5f45c91500d38fe1acc462a8622298c1a6f53c735abf1d4a971d3d9fd10cd4, + 0x17af880583031ee7067fec80f5b3760f9e19dbbde06343e59591da9080b8dbfb, + 0x1248c5b2d3ebd0f2870307d965eda53ef7d83392cf601d95da0eb124b05c35f6, + 0x286b506a8883d6f29ebff1bcde7429156792da00142bb1292f378d0f8962a158, + 0x2fcf9e1e6970e8b883f8f72bb1c48c53541fbf72f7b43ee9f3273f9102b5548b, + 0x17f7f929e38a4357770f905e9cc5ff7e287e043d06054c78d44097a446174e7b, + 0x8326d0c8a128c073a72c7d722a129fa450fd429856732886fbda3ef61606bf5, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x244fd94ac9d2b6a02aec10be6bdfde0707d8a95440b04a34feec4eac0a881823, + 0x18f0be2e75ec1ac912920d0403ccfce0ae11a66068ed5e7f0e60146c1eb78757, + 0x67d513ea87808ec1cf7f5880f13c4ff07cb83b06a442573c2e74a679363edb8, + 0x2fad3ebee463c805024a9884e2212288d97d343a199eb1ed449d7f0cf21fb86d, + 0x29e2c3e0e04f7685d1e2cd797de07f3de790cccbcdaf77f1686f159d4e90b0ea, + 0x10bdf28bfcacb8635108ea9153bebce77eab04539700acc64c084f8bc3f4a20b, + 0x10b6a895914a782aa94948c650f6c045d9a15d2706b259acf5fd4da311e1d425, + 0x2cd506792539dbd2f2cc3c96795d96831c21fdca7bd8988bbaac60f254da8ffa, + 0xca9da7606615f15506a87151200b468c11dfc0e28dbc306bcddc6d4828ce2d1, + 0x20d854f50910c52ab1f923102bd6ca5d82da15ba3f0f54f89a1becb7ce1f94ff, + 0x10de4900ee8ec243ca53404556e6dc15caa2bab8dd7f83148dca55a598ea88bf, + 0x1b6a8eb28c126c8682542278e4e4b2c922caf387f9f08980c8b469aefbc69b75, + 0xc2a3124091527d21e1bfd56cd88f9fa0616f2209454b5d1793cbc1dce9d250a, + 0x1d4744f598a2e98144d017acc5fcf08c5187aedea146de6ec74a5612aff8c7f6, + 0xbd79ea1a224987ccdd83f9ac4490b76bcbc554fa7c2418e0fe38e9da27dea1e, + 0x2405592dc81a66a17567e6acc20cca7179ae3c0971658fb792c0986882e57107, + 0x14f497a9e8110eec107450c0fae64d03bc8a8416db391d4c4770dde9bd38d3ff, + 0x29f8bb3529da3fe6152c5ef9cd0046568adbdd9daadfca8195ff20a0df7a5bfc, + 0x2a032300fc92bf19b9cde88cbe9da3f72e3ff50c62b6342e57f713b118a5fb87, + 0x1b59a7709a531a650d5ec2ac01fb09ced8327abd4588f619f36e0886c16c3df4, + 0x1fc0a3436f100a4d61ccbc321771ef6f85e421d5663bcb4c01c889ea5049fb5c, + 0xe9acd5d917d4160434a8fe7037b041c269eddceebb9129b6a176c8a00910d22, + 0x196cc8a225f2c2986abab4268b3d6342ddb645bbcd692863e93274b717d02844, + 0x11459356b20c2ca8913d1c0b45087f5a28559190d486f04038c05221381d4aed, + 0x25e96c07ab87f3f5c0688608c095a86f80ddff5c250f0f6375a45398034d64e3, + 0x15d58252815ac471aee3a3d097d799e9efeb969cccb08c33ae0b7adef18f0250, + 0x6546b3b7f85042fde21f23c3949c39c2276f87701537434f147a3cfeec10387, + 0x1e2aa3704b080c4cf11798a00cc0c8619c8d5997bc3121a17553be7b2dd65678, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x19e24f5e120e53bfe7fc01338211f4faa1f95084f2716e5587660295ecea8d03, + 0x2ff252a61572b7b92960841bfecc4bf5940bc0d682f1770fc272f70d41682844, + 0x2b9ce87d63d943afd940ae87979d5ddf50b784fdf8cd4d1ef0e7c4f220c98647, + 0x18eef6bbabd4d2a581f11e2b22a591364f5a4fba59146a97551fbeebb865fc2f, + 0x1b094af27259dae5e2f1929f16f00fe53d3acca1867d359d4681ae8a71f9ed65, + 0x2f2fb2e00ecc111f573d8002c53959067f3bc7b52959d0269ccfea9729d89435, + 0x48c4f81825c5584e76fa65b19b9b9fff7db07039d3750f3a65faa0a608b71f6, + 0x20be19e025ea25f85f5998c77a52710dfa5dc65bb2665e58faaa5db7a0c8a92a, + 0x222a05083d24105754e3f7fe45ece6add87677e8e64df3f44041618593aaf5f7, + 0x14f3d89c38b0249acb03dd0e1130100dde039b1e442c1c92ba36f8368ea16825, + 0x13667b7bba6c07aa7e18db6ce06e1308cff4eb1c0aeccc1187798aa1e97967d5, + 0x2bc234f4828ddcf587bc65d2a2bd5ad0974f5acd1f790d590d66e8f2ec739e1a, + 0x21464644fa0fb22494f8f6a7f7a929362ece3b3eb9fcd77cfbc23b2c9066a9bd, + 0x8b65df38447cc47455b407b32c8bc2c740c0b7b37ebc4c61d867b75b844fbdb, + 0x2369e1c199639bc505ce0da45601e0a51eff0f26588d74853d07b41a40b5b701, + 0x199051763385672f6f8303896f959d2b24b4cfa4d62faeebd54cd43e190c5e6c, + 0x201ac20d62b94056b6da288cb5a75fe62dc788a8b0d37063e22318f8c8b5dda2, + 0x18157f398ab7dfe77094ab6e91a5ef4e0ec471fa1a04e89969d1c11a2cbdce5d, + 0xf33f8f6546777c507e2a79f099a48d743325864e9e90a927478545a21fd721b, + 0x23703db4b584d2c4873e7674c6f3df0e16dafd344ffa9431cc3348424e2fbaf9, + 0x4501063364805e7a5e7d0a9b8797953e7f08a5caaf873917dfbc3da3c5be895, + 0x2ea0b23d55d50d907bfb16497f56a979ac7f460172477dbeda7b450c7625d243, + 0x68dadf39001f91f51a0613004e9614a54402b6fcbb0f4b8bd8aa546275e3075, + 0x241c7eecc6aa39719bf6c6ac8a980e2100d8c341565d138ede2b374177333aeb, + 0xbb9576b315160e6d9e5878bc54cdd9cea38c935d75fdf8b39daa3479a29b27, + 0x202599b284bf67ea50cacca315c66218f4c59a49a27e193edec4b9f93bf05322, + 0x170070a071a8648635667f8315e5412c48c3196d1d551ecd114857cbff9b9d3a, + 0x302e841876fe659903563549979b9e27ca6d36f004a559bd2461d5dcaa40d2eb, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x2731f1ac5dc030ec117fbad7b53c6b02a6c9e04a17f64bc0e56885fba0c2ef3b, + 0x8e4443070b7fcb1a28f620f990800bf0a23bd32146d7eaa824f2b02f50a48ae, + 0x7f1ea73f15d8be5ee132c68b1ceb3573909753f86582c57150eb71932972e5a, + 0x5d68802b26f0b520b248a7d4fc2461df7756641131a1ad109fa2588c462320c, + 0x2c6db9f72cad44c3dd15a83d5ef9eb7216db1e716bd8bef960e52cabbfca8101, + 0x26365d95008667a1e1b2653e98f899a378e08643d7bbf706c7d3eedaac0b16f8, + 0x52ff974b2d04537b8413b1b0c85065f727ad6da454f909dda0aa5994f7cc2ba, + 0x2b769645daa19e2b07470aae4cd88672e7160cf3c07c7b271b60668382810327, + 0x25f56a0ae50d333f294efa08376a37c386dc4cf24367139c640514547dbae38e, + 0x2f2d49b2a257d8aa58b838af6357d865236ecb76e7db136a09a5a094ab7c53dc, + 0x2b173636674e54aa05d0bf2c60c5df0b31b2e801e6afb149eaa2c6fd73d6a626, + 0x2eb41bfb627052e1e7373a7392264e7d680a19cde030d8687053755207c44037, + 0x1841952650b7215b249cf50f8b6c78511c2983145ac405cebdfa1a8f54b986d2, + 0x16569fbfaa5e330f4ce139b103980e0569db854d701d76a233ec9c5a8f7bce2c, + 0x60c71281c4ed3a23d7ce20dd30c22aa172e245ce529234ed18a130222a9e611, + 0xecd53722d116536580be7b8a5c43aedc798e1110c99fe9d806be2140f5c7786, + 0x213c0693e38ab9e0cd02d2447613d5033fce7f5444387652f03e95b9a18dca64, + 0x772d0faa6c722c861da9582961e239c0f4554580a5a067f9d9e9bd71f978f85, + 0x139feacf69de1ee3d14f4fb9ecd06681b58d4ea37d309f6062a2bb34806e4b0d, + 0xfdcd35d68b9a0a9f0d39ba065449a7ff04c9301927aef113c5f34061299da94, + 0x125be84a276a6acba551894f5dc8e14f3734797d489cbe94542be8bca82c5e23, + 0x2be65bd8dbfe8d435018dda75806ee34820686caaddb53f133ccd9877913370c, + 0x78ee87a14ac262c2d74b17aba71d620685987727ca21484bad37052d59d3bf4, + 0xdff2aa73f9fc438777ec8be74d494ec8c36fc04ad3f12113624a58ba52abab9, + 0x282f6e2312ac752d294d116b0308981e7ed45e2162403c5ff705d136fc05ae60, + 0x2791a0a3c213582e9a272d6b667c740e63cd918d53ba444d23d095df767b68d6, + 0x17477c566355c80fc784384715356f69c8f104b0154533af3c92e0a8a1319ac0, + 0x2fe67e79a807315060135431a9b4426982e90f3b38ecd5d8e0ed7a0cf58d6c1f, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x957903e40cf2319059c20c0fc70a5f3f8a79a64f3330d165e2c60b5b2e7bff, + 0xfc99ae6ab79445327c6d487e32997d5b476717bd26b47b073471c8367a3cc, + 0x2962bbf10efd8a8efeccd09ff80e9ee162249389094019af228cdacd2e42549d, + 0x25a909692ae443abd87eddd74f8705c80584216d5be8a42c79ca3079fddab520, + 0x1c0e8c1b8bdcb489bb68d7239dfcfd5271c4ac39d27e222be925de97750ad5fb, + 0xba6ee96962c66ec04c070eb3e71285d8c91cc967d20d72de7291f020f2c35ab, + 0xcba1238e9ce747c7d499320e3bd270db14cd796ba829328556f7c98d64c0d5a, + 0xc875635083ed6976d068751efdd6cbc3cd65da7c97f642b5361ea734f970295, + 0x1697dcd735de9b176c4d10fc5ab1228775788ed4beb16dcb0629efa99a6a7e57, + 0x244cf5956b0289a789aaf00f2e2cad480cf0824afe8eae41e259df395bebf2d8, + 0x206c3705f63d7b871045c5245bd3bcf720e12e4f0a82fa89a1f913646d38babf, + 0x20b58ed4e80e868305522f5eb670ce452ca9b1d541897d51ad7b42c4ecd13205, + 0xaf72e95de70f64d621db85a37f69f5712ce06e7596aa97a1188bcd3861d6c2c, + 0x1c1d15ca4b3e0508280869c3ef38eee25c3d0cfae188b5f3d59d5c7c5211d773, + 0x4af306d94e8e36627df09ffc20ec563aec05452b6b8c1a17e93c8a3f30a9207, + 0x2f697c34b59c559aa232e40024bc6da390426adae165002df519d7f2c71461ca, + 0x8a7299528acfb65d196dd9a7a136401178a7d03f6fbf5df3c69e6629895dcd5, + 0x221f628204240732be38e2d0fd3addb1080248592ccf3d655364e171302b4780, + 0x2b4a05f00a373b8fb7938b4f8812be582796986113ba1d80749be041dac49088, + 0x16d94da79927c24b7bbd25defd5c0fcd67073d738f31b93ff08bad9078b2a23d, + 0xb536adba2330baa9a070a63f86c465e3463d4afcebadf59a233a0319d1bd21d, + 0x1c57a599441a0b1474521bd0470a9cdcce3615e2575ee4baaa38a25958cf1784, + 0x1f13db4a9d7ce5fdeaebf3a571fa14807e979a23d8f1d426fa16ba9941421c60, + 0x12b527cd8c1fe08e9d909cfae1c405f11321538cf59af3a2cee67a06b11d9859, + 0x1f2c0fb5f11e6d74db0c30125e48be344c15529c61d4debb013a7b06f07fff95, + 0x1352f4a6320fb513348dd5f02ca53ceb1a47d8616892608eff2284ccb7fb1d01, + 0x146dfeab263219dcae7613a9b5403759d5122c9aa490e36ba5b4a37d489f8e5c, + 0x1edaf73615e187effe0d876478e3682fef5d63e3a12edccc216dc302d776680e, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x1c28442722fb49d44d40b2b6e86e2218f956de3f4b376c3963955666a8f57189, + 0x20e9e5c1b5d8cae475cd16e899d1c9d923d8d20ec60727d9266e66cb0585a67a, + 0x2f8dfa1f54af676eea3d05bcc648b8f511ea011b5ad23e961e1b695b4b5267f2, + 0x1a1a5037e57e4ae723753d3d22f965ad8b911f613d6b0e5d64ca9050ae43633e, + 0x1ba983e3c28f6398d73ca8f7e2963564a9be471ccd5c3eb0c4f8e96635059529, + 0xd4adfe4a7dfeb3cf86702e54888304e36057c89f10d46186d647bfa700688ff, + 0x15c0166eea20cd705dec4b44aaca007e6c9e4aaf131b47789cf70e53c069e6be, + 0xceafabeda1dca814433c969943e534008012b6555b08cb2a4abf43793fe0e5b, + 0xbd15d8a31cbfbdb7c36e540f4c70a5eeead9d43a9414023c763d2fb643fbc76, + 0x17b69dff9f9dfdbf6bffec7c7ee15eab02eef17254a526022d878fcaffaedc75, + 0x272fe422dd56f28e6375cb725ad469069e1e48aa945dffdc1e9942b46307b763, + 0x27d2db5651e5293ff051000a36a2c949a7a3e7ce326b8c993845ad572ed1816e, + 0xe83466c2741c36fe6f5f5e6e60bad5bfe3ea06a7db58680dc4a518f42b6ddb9, + 0x1b97b0489274a5912c53c18137e918d8f7d3985034c617d9d5dae4cb75990486, + 0x8b09b027647befc8884bf237a58efd361641e4a25ab1e8831616ad9096aa157, + 0x22f46a0157b70196720c57a7636285c4b10854721e4533294283652b1911bfc2, + 0x2f1f803aa4a96a296bc8dae8d07335ad018e77ae6d779789bd718e72d8709a53, + 0x2245e61dfb52be01fddb5fb4179140e4b5bf8cb1c7afbbb6976382cc712d981c, + 0x1683f9bd4b791410d1a889953b716d95c440692fe4b4886107d052a8d50307c4, + 0x242e864ffee30fe0a080e21e4d275db8355560f07b7745a4e5aef58d09b653a1, + 0x1eb483efd8310203c93a42e06b18be5b4a0cc9612c335cdcc82c104c38b3e8e8, + 0xa5b1b4c8982984b6ef162eae01f0a53337c0991c27faeed2b61ce3cf99f6503, + 0x10c25a14e51fd3df8e34f70db38cd60124a4f4837d0b024d5a0cbcfa8e316724, + 0x17e9f3efea4275ce4dd5a760f4215644cf5fda3659cc82c8cdc1c66ba5336c29, + 0x25c1bfc4e679b3b3a692755b3313ada05f6d747365325250e0d6c0c566070ca5, + 0x1356277171f1d2a2e677bcb161d9d760648150d1f297247ea842abf2633d4715, + 0x28aab6b87f9f0f8c708695594610fc99a820dd994d63ab25829c0eee980d246f, + 0x148d7520ea0a3d7ab3ee550cf30cdebe434ca7c84ee346a5b8b6d5d35ae06e88, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x24170fadfbcf05e5d3c5d0d5d051f71de23175002d1f02002939eb24ce5d6d29, + 0x29491e9171d578c03ba302262531a6d8ff03ab25af7db467947e543553b25e50, + 0x10acd03b983a457e3eb10f10666a7540b46066effdfbb50a1c5996e8e42879e0, + 0x1fb89a866bed5ce87cc2170f998132512ebfde77a2aafa84f288024ebd9e6c78, + 0xd98b830d880dad4a0755da7626c0cb7dbc454bef88b16992f3242c9fdea3cb6, + 0x1c0d9302769b138d161d471195f06bb20a5a59f53f083731bb4b9407af705880, + 0x299bbd2c9b64bffc601a51ce60185e770765abb952375055e0f8c6edc3c1e7e7, + 0x1e3e012a3a23cc56b69b92c5a82ddef538fa2745d68bf99e6c4f65670b8a2581, + 0x11f5e20407ee480fba59b35af723c3c1e7e60fc4817f92d6394cd7a9c65ec766, + 0x26d3be3bd30f29131705a60fc4f5d51c6617919993bff2a9e9cbfe08819ca686, + 0x2b29ffafe79893a89844e650ccc01ada03f91f4853166006e0efd05aaf3e3647, + 0x1fbe32c5de07b6d625c86ff0062102ea1ae1f63e80ea0473ec747ad9a67e8a08, + 0x24e36875d9f11a3fc2dc23d8ae5270150759b92a7dd422d2bb196603835715c4, + 0x1859e0cdd36899ba3ea1a15b6a5343985e2429576894dcfcb39b17485e965a37, + 0x2e823c343fa815b8850dd85825f5ea80cb32e17ed0a8ecddc478609b094952c8, + 0x27ae666b5dbc3dc0d19c32a000a7df0fdf669ef25691627c4d7b17c6f4348d0d, + 0x13d3988c983fcb3cb784b222b2bb8d4e947afdd3fb1d0e5bf2ab876eab1ebfd2, + 0x26055ed2f7cfe90bc54ebeee9ae37eaf62f11d4ce7ebe370e7776167a51779a9, + 0x187a3031170f0e0ccb8ca67fc2cdab2c2a5274613a5ce191a1790b91cc6c5888, + 0x979a5a4f896cec804a633285c9457728b5a6fbfacad62593a23aeddefffe055, + 0x17a9aad3bfa4cd25d929abf715dcbda7ab2933a6868d33720a5e6c60f88e31c6, + 0x51192a624e65c0f7590c37385cb1a0b52b46205d2ae7109e076c08b307add00, + 0x2aa14feee17ac6700e5e58952f28d5435fbac37769c3275ea9fd35ca622fe7b1, + 0x354581b4a29a9ad673f3c57801bbb6f8a57098c9cf5c15860b4dd240d83b536, + 0x23bf29c02d8d818da4257fadea084078a4f7d772795ddcba9e53030e06cfe36c, + 0x209923e9cc079197d001f330069b05b75547e48685afb804931af5a3a241390c, + 0x6d614256aa7a08f67ea8d06bf03ae83b820669ef7d7c1c7fd992acb22ae6773, + 0x1131b48492673e474c8e23277571bd9f9b892b8ecd3b6af754ef83a1f30a429b, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x17ff3c20af33dcd172bc3042ca7ba8b9acc7c5d35694a795bcc8ae3c35d9e748, + 0x273eca5bc74073b2f6761b6b0494d48407c4a021056f88b79f0dc3c475802c39, + 0x24edf79bc35300c727d39b301de82e8cc21435e8ff3f34905436bedbfa6f9d91, + 0x2cb3232131a5d86145127c61ecc8afd66fcea63e3ed9b1ff1ef3099aeb2047ac, + 0x1ea49fb0e46edcc3a90651f6e1a4b36175bdb25505cc998a101710a4fceef13c, + 0x1e40d394feff0707116e1d43c523a36ea293d11ce3059b5562ee678a008a594e, + 0xfe47524266480df132a54698b09e844745eb540cba498623a93f36e48c63bee, + 0x1f113b5d7c4a3e1f1156dcc68358318ce699b352814ae0253672d6c185422980, + 0x1aed347277640a0a0cebbc2f4ce523b9a51b3750672eab8a9e689c488bc416f2, + 0x1ef98e57380c6a8084a8d77b701e23dfbb56339ef9cbdcb9644460a72a1f32e3, + 0x297ab0678798b06a4cc7147cc125baa11a058cf0889354e63229f185336cd356, + 0xee54e4f901531d3811aa6575c60409c7e6ad4b475e249fd3334883b438a2097, + 0x1b9b0f52375f34b4210e078d4824d0d385e6e412cf177f862aaafc3b6f11deef, + 0x261fe98c4a6882bf586ce9c03ba90555d428567bd98761ecb57bf8b1ec408458, + 0x28d8a46abca186e9fe9b326c166870f98acf6655eca805b881ee02ed4f3e8134, + 0x4da6035fa7dd89980485ac0feb277b1eadc58f522abf010de5bf9d33974f232, + 0x1a9738d1389ca170c20ab5bc4d39eb39992acf40d0c4da20ef3e3394ef369b88, + 0x183dd4932830f3f29bf1421cf0e03a90321b974c93a2779cc64031c4c0166274, + 0x1daefa57c81865e8a1e3163ca39d400cf5ce472f21a1888f300741ca61d61a3f, + 0x2ae49d27bf8dae3b5f8499fe9f76fd2f247b3825a8f4e89e5c53596a6ac5b13f, + 0x9063107e2a28ad8dec4ee2a43760006c728ea07dc7eff26f34c0e88becd87b0, + 0x327db09f5185889ae36e52db244214053b27bf18d3f240552dae62b60badfff, + 0x6e61b73f704a3cd70cfe843f37956d0c35cafe6bd28c5dfc1be98399c734fd, + 0x484994555a799cbc175bce4f3add547300ea3bf0597b52f08adba0d0d7478fb, + 0x1509af8f777631bb65bbe5ae68fb4bfd3e61040cc4c28250704e3e52e393a7c9, + 0x2502148be563d2dbed722eb34a878e32686eddc63235292ff336430ca6bd5f34, + 0xa90580e651271747716e4e65ea8dc039345e0609e4596fe65fe9539daa129fc, + 0x1268ac93435ddc3de28c7401ed6612751f4b244dccfe1a75269da8036a1173bc, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x11aa913289660f7deb7ccff2f4be6dad755ef59eed4b716fc8d87e247a6fdb45, + 0x29e72a16e4534eafdcdd6139bec5eb95e22b7566508e1b748614d450b54c15ff, + 0x1a958e6a0b1a339f1d3dcd38ce1328571f35f09abb1686e2fb4c3459f036c58c, + 0x2ed8337208e410744d73bfaa8049dd98a673eb4734b2f1e6c50dbfeed2532eac, + 0x29377f640a7f6f76b922b18954b3ec12216ba9c13e0010002b59ea34fa974bef, + 0x23454f27137134b9af8d43dbeb2f146c9a943bd5ec7fc7642da2ec887e9bc4cd, + 0x209816b4da19597eda949b4db4754061c72a3c902f9130edc98b592470b0ee5a, + 0xc1eae8b0bf925b0a155e42b2e51678cf5efc23a07e62a16ce7de2b5fa23a43b, + 0x86f81d19a31671e41a874adaa71edac75c4eccc6a2115c2ac96bab6e4da91b6, + 0x4c599ac0280aed84f94db0e328837392ea3338153ff37de61a7e28bd24392ce, + 0x2c4b7cb11e988d5451ea53bd7bc59c1d92a3250e5cb1b81c8017efd00693ae0b, + 0x20b49fc26af7d51f043b48670b79a409c4fc366332e67dcab28cdaed5fcb8f32, + 0x2b2de9914033de3d614ff1cc2a46234dd1f3605a9f4e52fdf2169986b31a754e, + 0x2a0a9aedae2ddb9eabbe22dedd043c670ff098249bca89b2d7b789c1a200e832, + 0x78bbcc544330029c5703ad867d374a907efee1f38764e417f6b724ba2156685, + 0x27f2b059159be5955c9e227e865d0a8add82aa951ebd9b2fe43545704f0c4bde, + 0x7a6c429e1100125d872120c307bde17b721dc31e16763cc096a989c97df7843, + 0x10424964905ef646913f708e8d4321e9ae2263875b83e5c65d096516581d4090, + 0x2c33aae7d921d4b90a0376b93aef9a02975fa8343dc0026066d791e9030e04a7, + 0x1232983e555c7d4bb4288fbdba3df682913813bbe616c9ef9568820e02459b4d, + 0x1ab5023e5ffbea8d4fe8e006beeebb3162a26e2a4546f51b1d836d3467816c0b, + 0x1cbda131f20b33ebceacff9339451b84854e65775fdc1f5ddbe8c35fab2116dc, + 0x2ba0bb8404000f7361cab18e78692a17d953323a30934ab439e23b6605c023a5, + 0x35fa0580ae06fc96e0e4af43e63b089591bebe233c526a67973f25cc7fb482c, + 0x70babb38665a3546e6e23f8f3b26f058bf131abf19d3c13d6d0588a317c6d8b, + 0xb642882c1295343e9ea28b89a62ceebe0b7919b6ca5e18811aa978bc181849e, + 0xc68a36f6df8c27deea1f66f891c80fc215aefc646f545d63cadf22ab44b5914, + 0x66489b3cc989e807be1363d97207014a2a14052de80edcd15c4e2f88d2c65dc, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x1026e6257b43e0afee22a0189f28e10718f4cc5e49b3d15405df85d8153e8e1b, + 0x3947588e943dfdbd95694ddb3a1ba7f51028c847b8a45164e87b5522418aec8, + 0x1b1cb2c496ae764bfde288ea50405ca6ae4ac6f9ad1998b83b7557787120cb1a, + 0x24fa4f9ef707a77f4f3742aaac6b8fc5bc59fa8c4046f9d024e3d5d80ac0c38b, + 0x21dca28d7160687fbc8d0d144c062711e4207f617895fa46dd87922777ff10fd, + 0x82cd14685bc3b3219e1a76ba6b2cd6b8286405a38705273a7faeda1da62b3a7, + 0x288c7734ce6cf001742b8e84fe502cf5205a623a3f0fe1d79f0fe916df073c4a, + 0xcbeaf576571ebb86d175b804c4655da7603096f9865f983a044bd8ebc416714, + 0x257aece5dd9d7be08e83df64b50b5ff1e31e4cb6ef8610c6dbc9eab409ae7383, + 0x178df36af677df81aba8a9fa9d31f995378d1f69d782058f7ef769555ad5363d, + 0x889c87f38b0244685014312d379ae5ae934531ba20b7e89f6e1e975e96d5bed, + 0x28898ecb6a12d999474f7cd98e7d0e3eb9da404cb45de9285115b647caf3102b, + 0x1544b607ee25873cc317f6eb88b72ba9371ff52bcb64753b0e90dcef61032604, + 0x30b741264c73950635ba61ae3be32eb643d9a78fb6a6f695ad4046f1b29a87d, + 0x25052d3381e118c1995ce20ebee9f1cf615053caf4d2ccc143fb1e6c4ce154f9, + 0x2f30bea892f8f2b335b8e8bd925f244335e430f0c77a2313013ddd6ed40de0aa, + 0xb0d65fa768e06aa8e5b1aea32a2d0eaa75d2548296268d7bdc1c4b7a2234989, + 0x1fa1a1014ba36436c1a7d8cea18580c577928229ed8e30ce94dabd98b873fe27, + 0x301c506433828eccfffbf89757d52692c7ec633f32e726ade9fb89f7839150a5, + 0x154a7110569dce2d4dfbb0c4d590669811751558a06207a1602bef10d3428ee, + 0x2f27c0dd673d6353840612d1cfdec89407d7a23e25678d1fc57aaf210355a84b, + 0x48683bcd4388885dd3956fb83e1890710c7d1cc5d103b48c2eb7a4e48d3c5ad, + 0x151c3648a02ad924ee9afe8dfa7f163033d1683aa8ad9508a6c96ab29c08908b, + 0x14baa70addf9eba4a80bbda03d2fce92e571486eda83f0c0fe59a7e4605eaec5, + 0xba6cd972cbb3905ed976b62ed34d972444d8211c71f82a79c089fef7a030e4d, + 0x25adc9138d823eee97b0dcf9e7142c4d791bab92c10215d5b4f44ee166c44018, + 0xf0416997a418d2a20cdac6c53e67640da3ab4b5cad5aa3c9c442efb895b7744, + 0x1dc3e4e5d9f2e587fd95028c6372a304d987eda0525879d1b7da7c775f0a417f, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0xcdacd248084fbe79ef314cb06a96f929ce94f525301e8858e6b0ab419a7b247, + 0x28765df4d0b75915b2000538e00a7dcc8219c6e428e82f452ce8882e609eef99, + 0xe81a5592eedab517a051cb7235c8bf0dc0c332258a65ca6e29a8625a334fe8e, + 0x88c064bf7c553c7e4d1b38425883f54d57f18a7f8e9800e06a3c2310f01b2b4, + 0x1d24333468728c030f01a3c93fe035e9fe913f3222c7149cc22e21d444fa49f2, + 0x81e4d01326c4596d16d5d9df406a063f0c6b323e2a8e406b2788391a6b2addf, + 0x352a5a0fac781a16a2d8bd72c9402a3b1d36199bd4ea46125e33c33732ab311, + 0x26618bc0fd81464f23f6e22fc19fad753df1b3c076275c95e0ffc437760fbbc, + 0x228b70124680c991be94ba0f8016e384609e7a7fdb2ab40d661614d65a52193, + 0x1d0ba067834fa54b50347297a3525a6198bfc7d47dd47106072c7901b900a4a0, + 0x196b16b4a3f2641cc6b343a57a66867f96be45005df9c9fc9d07710010a1df0a, + 0x2f45695ff148cac7bd348b093d94e075a73f4f60b52227eb8ed6048fbc47aeb0, + 0xe93289c741402aa1bc152dd82b4889b657db2944dd6cc5c9cbd8e72e69063e, + 0x123380ecc6c09da5e9f5ad2d298dc60dd0a9d37a4b67d4833d2fe428ae7a8db2, + 0x883e804219d5edfe1b0bfae68a76df18f1ca939207b6b0bfff7bef4309c7187, + 0x21588588decbc2f33ff25a389fec95f429fbf43b54ab23ab20d3914ab844eab, + 0x182c5a52fe6c6d2aac38a2fc06ffb65595a1ca4110cb09ab6f5070f5962fc478, + 0x6a58def11f1c27cd234bd7d9be04610f52b68575d9560d3dccf8ad9b5b741dc, + 0x29cbbb5cab2c9dffc5b12c9230afaa59c7d0b1846ff9bbd0e31de3218afb7742, + 0x9a1d4f4f00323630dc4f2d326a5ca2823e77944ebf1c22cb9343963c627f17b, + 0x25f5157f8a190e6bfbb1eae9cd55819609220a196fd89cd44b5b4603e80e87a6, + 0x2f0794e7af6874b7463bf9d7f7f6cd2b9141b2c71754e4a8e487e26b723d0d8d, + 0x2a816cbc315eb725995b6ab706c6da8757bec6f588849f85d10b31767998bd4c, + 0x2c5fd92cb6990590e62056205768da25c8132d8bed9cc787e73b81dd9ddc5448, + 0x2e80276a04b486b1a36aaaf7c15d1b6b4bd48238065cef5eab1c153235ca6937, + 0x15257a77d445dde9259c6151c0af6a1771f5c23924a4c4f7fed58669ce49bfa4, + 0x1219c007e9664d8a54be73a03262d03bfe15eb3a2f8e7c9194271235eb435814, + 0x95144c721ba3b18324e55e532885ce67613444d3cb3e95955d7201d779812d8, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x101a646241a8315f204d41adb7fad83b1a502ea09e7cdd815b21625cc0ebe09c, + 0x19282d6967bd22091e34c47fe72266e1cadc9f58d4f4679dc9255c09c2854963, + 0x42b2e9365e95f6b6afec41632d9a933f4744106315e3df2eb6633fb87356af2, + 0x86ed6b49511d6bd4815c76513809a77c277e506c3052c2beded9606623a4c99, + 0x58a4f66ba158c1aa28b651917f1fbc744b5286b3f6672ad39fe177be503345, + 0x28dde10bcf8969aa7a5b6ba1d48e2dcc3f69dfbb224566cb3fc977244a196cd1, + 0x3842b61df1832bc6b4e0ea70d7131f7b2561a94f78de3371aa976d05d635894, + 0x2c3bedddafb94b9427993c19bfa19472ed8cc066084c7cfa5c5e7f803a7582bf, + 0x163541b79f81db7f2742efa3584f07e1e7dd25a19ad934623e14b87f99601790, + 0x1846f2e5b96f8abbf20a2a6ed0d9a263337310372cf570a318dc3c91c849f112, + 0x6c7a3cee3f4166e6212f93f7d6eff60103cf16e252df30d110cfa0102331b15, + 0x25be194f6a3d69e3bf5f0b7cf58030a761e628b1a4de003d9e8a02fc2080ef74, + 0x2699fb6f71316244c10b2c672b2fbf077f217e1c910ccef06524af80f9c3fe0f, + 0x20e39137899fc0d2c5391fe185394173003faf87cdf3e438798b1666146b56c, + 0x22b9615e9d1b58292148c5aaa8c9eee5d540aa62bac93ccbe16c5b657161da59, + 0x17a4039cf90fb2c8ca78a2ab8474e5fcd1bcc7dd4974302128890f792960a722, + 0x296a7947ed0816212521f82cc836f1b747640ed9311e5a8432b24f131abf74da, + 0xe6222d1f658021ae1a8c83fef1078b54fe29719d30a30e33e95530140b2ac5e, + 0x24a832d0b62d7fedb241b289e95fc7f4507556c422183cdf1bafd1a516301960, + 0x314978ffbd36b1bf6b6efff9ceffdfd22c3128dab03035bc4d1811ed3a22465, + 0x23456fedebbef43f154140b56f0106c7b3a5b7cd60f7ce2a085a59d219364080, + 0x2bdfd3aa4bca894312e9f392192596efe7aadbe7b2c22aae990c18ce32c56f2c, + 0x1767d8e87ff8dde844b861af172f011a8094f2c93f14a367e3f4008414779996, + 0x9afea3b803901209c60fbed76494748e3af704cd3d68f6dcd846b5b37efd752, + 0x1eef9a7f080331471dd29d7d0106b95b1cf30854c201d0c7354699f2c0ff18fa, + 0x1ac0df8788f7b6b264c4b5fb1d15f9f43ccb6914fa627a6454bd7b107398f328, + 0x153587dd8856ef1c5ba584cbc5c6206ff27316111bcb089a37000e01fe12156c, + 0x1ec3422f01d367deb6566ea3f37caaeba6e6f1ab9b487e6adcd9abe7fa2d17a3, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x92ab362071be64ee1defe4c464b18ea957003ddd4fb25ef1ce8c93eb0da67e2, + 0x2087c4812bd0d03d971979f341256e284a686b63564b913c6203e3a3316a0bbe, + 0x15e9d37afb1e0877c55cd521cb79c5f20658f8f238b8679a50abfab5edd498ad, + 0x2d3aef5f158c34c12fe84c4d48d49dfc4b27ef3ad9f6e9c29b9516be85df233e, + 0x244a3d476b0a0690158a1bedff28cfab8bf6f5ba4491691326e6b1b71bb2650b, + 0x10e9d046cdec45124f7bd3aac446b7f0eba568df3462c86c60751ce3e51c3ee1, + 0x2590289589edc3112e5d87b4f474904fa9dd4dc4f26298d1e9666c281dd58357, + 0x13765e0ca93cb708b9cf1ecb6427f1a0df0b53a7d112bc1a1439c3afc8e8c13a, + 0x196d3192651b1e8b5b1cf54e775eea3a4f4d67e60db2f0be380ee48819fd495e, + 0x18c81e4ef19c7276d9cda9d9bde0b3d4334f4748c76db52bdc4cb0de91def3a5, + 0x25f4226ce2c992fdb6affc2c85c8ca64c9db486e8471f93e30d97045eb4aee58, + 0x2a152c83769c9a975382957eacc862459e4227080ef497775273995c3f30c3e7, + 0x13bdc6f2694024b1e21e3fe7b281e44a48e32c31ae815aeea28a283187bfce73, + 0x18be50dd564a7b862bb9f3fd822a9e6cf8527290d0fffd2986b6efb0e4ec3ecc, + 0x76b689cf6fc26746914c11187642ad45b934b9dba8499e1e0f645d1e7360976, + 0x24cb96220d02e7d183cd28cdd89024647df21deba55e20bb0a529909ed483db5, + 0x109261482d8eefedd9555eaa2d4466e1b9582cdb50dad968f73ad96df83b6afa, + 0x24f33850fe4d7019ffafbd669532788d02c6a0dbb39948ada0b07f444aa824ef, + 0x175369adaefa269a66baec32ffd60d1be0ee1f39ca8525dcb73a6357860abb2e, + 0x25b9fec7cc7f651e8354d7aae86dc9b3964fbdec440c6c8369fea81eeaaae8b1, + 0x2d0c8b82de5ce4c55025fcd286e9ca575c3b0b90a7da5f677a0504c05a4b0cb7, + 0x227437dd063cea6ebb85f7b564232d22be29cdd7772640936c3698b7c9fecf66, + 0x1bbba5bfc8a010cb25f637ba686157eea46f820848fc2c2fc636f933d4014101, + 0x14471102a5ec4909add2c73da2c60ca518809f1e160be7dfd14a6e9b397683e6, + 0x1b13fb4a716a8661bd984574b55249784576b8346fc245fa7ff1154e748623e5, + 0x26344c34f453274463aaf170748550a3e5cd38fb0dfff173a2ffca0a7f2dded, + 0x2541b62c8a52ffbdd29ea87ae0919225e12dcabe2104b5f4708708a2cf4fc38c, + 0xfbd922b73f16d661458c67bf7b4b325aaf303c5a12902a667a78c8507036976, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x2355f03ba072a620b568e7d310d9fa639d134ffd98561cdbd2297beb13ea0f10, + 0x25ff4bb05b96f0a0b05562057a8db99f97e1e2951137c0c40fa932de73ca19ed, + 0x2daf950c80154f6e7c49704d705e14871273499f2f619b86c5c5d157a6203dfd, + 0x51cefccdb8cf6928b91c3127747d700e86844f1148f0a34c6d77c5b849fe690, + 0x238262ec5467d6af343b33543cd5fdcdf909062c84f812fe01aed5cc87fc476b, + 0xb7daca406fc36c69aa958fa616f4838d61a9dde2e45ac8bc788fb2cb21019e4, + 0x15bc83c5e68048d36ab9dd5750982c086ebf0d155254d898c60e644231c54e13, + 0x1c63961d501d08c43558a7bbb6adf0248ce7d85c46ed8d18cb57fd255d70da87, + 0x2509bb8169fdbbd47da25a7229eea6ded1c619d3c047b7838aaace2693656732, + 0x69a50d4c1eec1a0ed50274c6fa4867ef658dc1379d8fbf9878d4b35e9fa99bf, + 0x15d74c0872e9b1164992ce0394cab9fd723220e0696d28ea011620716be1af17, + 0x10b0c815190863422b42d8bfbc68921d1ed561055ae5057b45c5e46be5a6eb4e, + 0xc11c306b5211eb36fcbe505a754052252ddc622d02f4420c77390851d6c42d2, + 0x150cfca445b9336ce22dfcad1175f597794b2f4bfd18a9780eaa12eef2ee5c55, + 0x194de31d0ce18660aa746a9356d96070ce237944e5304630884874a2fba798d5, + 0x14c2071d9d7df808b50b19e77e314406aee8b339c4a245b2770b802af790ebb5, + 0x15847c79aa8e1c92c18c3bff302c31eb38f001804c8291fd590cb9025a7d12a3, + 0xfbba1d54897882de6c7d26203aa96c3db29d788b0bd435c1d354c271b126973, + 0x1a3b7ee6c4f24ea92d2228b4b760223f9a34d8f70c3872400920bc066465877, + 0x2ce61015cc1e5520a83c0124f38a8359caeda53051194702485e00cc2ed02bf4, + 0x2b8be03a29a0e8fb62bbc207e587deb46eda5bdbe99e522e773bf63e6cff6334, + 0x105e1aedf0cf9f12ad2416a44fbf458d6237ee895960bb8c25299ac72bde12f2, + 0x120c504e8e99eeb16539249612eb1a9687e2f99e4fec80123f0c29378553bbf8, + 0xf35ac3925b66d52bde5da31655b11df9975be00efcbca7da24e85509dea2f50, + 0xf4957169958f20b8cb24ddd2c1fa8668bb5694fb82c2779a93e2d993c2a4369, + 0x7f61b3cc5f1220535cdc630b9033172c02afa0a7988a57c373a91c13263d805, + 0xe16429a495a0878289a4e187af2b3b9e0395ca3401938b70f07c0647273ad8d, + 0x18190cef50589e6c73faf348b5cd88be8dcbb44f37ecdf70e94a3b4045fb2620, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x227f232164c4e3c741afa130d206cd84d835e4817c4bab99ceabe0bf4da575df, + 0x1b1d09c8b7aea951d45cf1390c95b03c29f6820492ce2478739df09b9bf0fe5a, + 0x1bd040cdcfded9e6d08d3d6bbbf55a86aba6aa5c13cf09ff4cc6db28420a1830, + 0x2c4d2f16535632f050256086dd4e2c88479a1d3684ecb8c25fcf3096b3e1a6ca, + 0xead790bfabc7e81f7ce3b6d68134286977c619a13efef5ac110244721c097a9, + 0x8900754358a5d9716c6e2fc17133da9069794fadd42410213b5e30e7dba7565, + 0x24c0631f518904d6a003e225b34d3d02e2e5645f7c6bcebcf4f9944fad419f2a, + 0x9ec6105a057621f9bd18fe13e9dede1ebedce6d72461dc1c4faabfa1aa7f105, + 0x79b0343c865e073462767b20213ffa9443db0387c9506503586ee533302e802, + 0x7df63d142bd6c29ee03aca8d1d5428920a7fde6437b949149327c2967d14245, + 0x2ff26c8169cec62032f72ac25650a6c94a18afca7d04da0e3291d3ce71a7711c, + 0x164edabbfeeda046884e4f8595e438127c32f8467d9de721fb50a816688e33db, + 0xbf8306af475136a305a5a78b818c1f2d49ab9fa181c11de516e38a96ebf9f55, + 0x16da51bf32b4e134bdb05926f7b975562a7f2fcb671bf0584fb0e4d33f33638c, + 0x142930caa1828bd842e28c8790df9d033eefae7b165ddce53fcd46f86d3be2f0, + 0x1ae7e0a72e9bad383d09d0555a1f5a0bf1753ce1a17e254b49bef0fc899a6e99, + 0x280313df7e066df1cb639a4b30ea2aa78ba46720595d77ee31b55de2a713dc54, + 0x1ba62055d4a6b3257fa66b471f11be979422c05d3a839ee6aaffe7ac1c0b247, + 0xfddc6ca4b45778c49a7db293c78628431edc830512b7b1c8e5754ed2f39ff04, + 0x929d32df53f196e858a97b178b1d47e42247d5dcf37b08b4852ad74f9cc78a8, + 0xf967d1490ffa3280071a718013b3ae7f9727755d261fa1d85c3ef7b0559283f, + 0xf5490a89b5fc95c115da17e181a7e95b3d3d2229e73581c6bea89a0edf5421b, + 0x674bfe177fdc1301f1d49c2879734cae162898d11000050734402c75384c736, + 0x18e1ade3d71eef67b1499555516671ec9978a13c5da32b3cc87a373a6515eb66, + 0x1f9179afb7f5975be537568da903fe09944e257b2757934ccf2e36149021f009, + 0xc11a256c35c638a65f02d745d35712fd303bd7d3137311a1322339402479ee8, + 0x2ab557843dbbcbff147b3f03de15fe79e8d40e9cd6cc556b12958bee7a900f67, + 0x168dd127ba4582848eac364d737e87bd02024b8924b4adda31a9a37a3415cea4, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x2c4d427a7bec8d19617045360e52794c7a1a6de79c4e919698a87ec516366cca, + 0x36d01a16f30bd802544df169c77ea02c0008342cd8a415e67e49f2ab20538b8, + 0x104dada7b72b24405dc07a4feafa385fdd6e87d0eb0d0b0d461bce56c4f574d4, + 0x1d189ce1540193127426e68c7efbf6116be294f4e39c2ac7fb43eece2a5230f2, + 0x20969c1c5a7537d61331393f6a5a2ad15ebf51efacf6b61f37c08c8ea0823cd6, + 0x1727f8b0eb9595229baf305b3fc99c51d538637e2d2ea8931037c7350d5f96ca, + 0x1897f619c615a92fc082a589d89a7c522625432213d6a92fad9e2626aa0ee79b, + 0x1f62599143f1f32cd4efb433f14ed14544681878db55878f13e69694a226b3f6, + 0x118c2c92848d6aaeda5c8b61d8ed6953b7b659a25efae602f9961353f7c781d5, + 0x18997289e946839e6c3554194b87e6c0d4cbf30f47bc73b126d6eebe47a1cec6, + 0x130da6eb344dee64037fb513703caa96d8aaba83f7c8099308b4e6c82b14cd83, + 0x245357b0b612c4aeb12540db9ae1526513e7885ce50ee8ca0b58c5bf54261563, + 0x16efacd482e07f1fee18c96ad1725aaa33cac494d4e7301aa173f1c29a625581, + 0x1aaf282a0db417234b2f0afcd782874ec2a635899f3ebdf33f4bad118acdfaec, + 0xbb16e9a26f6e4449016a392f58cc0abdc15838cec0863a15cf24737b7a9c804, + 0x1ab091e043a032a1a8a17875c09930f2f3f8f014966977c7672e052387a88724, + 0x17a1b1b5e07302afe1156372691356ad32f77ab95b6dc1766cfdd4c02d260e0e, + 0x198f8c2021281502a922a03b04b3418571d4ce4f5359ca251015e477fd983d96, + 0x1cd705bc50da7642e8f41975abb2ac63593ce9575a0ebe0ec412e33c2955131c, + 0x2f634bc6e688daeb64b11b71780307d998916ea7db4cd7ac0761a03dd3fb1744, + 0x70efde061570346ca148955dee284634e28b4f5ef14d09018e289a5b6b5c643, + 0x129e1fa03e4374b6aa7cc2ccbc35e20a6124b84f3df49bbcc3f5aa1c25f8567a, + 0x872750e7e4e00867ca29aab19b0221191e89a4e7e17fbc0e0a97a6b99d79816, + 0x23e8c43c57b9dc6fd6b899818a44200e2544bf0865fdcac5b4256777fc765928, + 0x2a6b794cd03c70ef06885cb5ad01698f2340877a5a848c8f49ede93b5c9e830b, + 0x94578409d6462e7e25ad9d0816a6f6e2b198c464796c9c8d4fd566df266099d, + 0x1b2b611f853458bb3f92b07d97f4a8d0fe323b635959664d7003ace44646b9c6, + 0x205b0fa2b6f2ebaad41abd2b1feb4f7af003b5e73f91d342dc196ae182fbea21, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x18813c17a1991709dfc3d21cef51ad2b5a728731db369c24f53c9c18f7537922, + 0x28e2f1491faa1312b2fc0756fc93e6faf260cf3c9a798c4c75567e6e2450f189, + 0x2456cf94d7ff6e124cf859d5c41e4cf38e76e96c66356df4959af90e84caa6b7, + 0x19d01fae3e6bf2a3d738e5adc140ccb0566748abd79323db3085fd1bd3a938a8, + 0x15b9bb8c1653e644f0ce9be50bc599be543d181a965c47b1e55e75c128df6451, + 0xaf54a3486b44d6cd344d767948c8bab86a3b770730d578d35c946076ba55628, + 0x2c403933d9fdce9b2356ea5599a17ca6fa2c527472702d33a1bbe1dc6481585, + 0x1f8600480399291bcdb8f2bd4410cac16f4cc035599a6e7f7fc3896dc95595e4, + 0x20853b736e1ef67fc8dd165d3fe11a6734287efcbb6524fb6eae1a66a7b1e8df, + 0x2f4630a0f0018b04c6bb77e84776e06e3b2452d47be2d16220ead1da61106b20, + 0x2b9036c48f9af1b32085e3eae9f541c4ea7b650f1a5226ea661b9125215e8995, + 0x16e06530b370ba9ce030ecc30f063bc064d716de78cd74c2262d483406e0e68d, + 0x16965fc262e0ca879a932d721e95d16953229eea7b3e95cbe325b48bbf4e851f, + 0x282361e61365be447c940bc7b8caddef10a82e8a51423e7ce17f4ccc8ac6826e, + 0xe5f05bc3d2f27eaf48ba6efbb95fd33d29dd9d371afdb46065089f07b5aaad7, + 0x45e49d05e82f9c8192a3fd3c936e73ed07f0edd6db0007205695a23c9272ba6, + 0x1aec3601dc7eaf614f812cbc025ea069d2ad1eb2b1c8bb602500cdc8b4ec97d7, + 0x29182e5f19d8e48e13b7a98a19be4552f09b452d0e93fb876b3672cbdbd48d82, + 0xe82f9feb507fd178f0e2c0c324e07dcedcdc0cb2ad743ceeb4e2b62dd1355e3, + 0x9c0bf03083c7a7f84dad628b3528a89001d43100039491bb3729319bd75f304, + 0x1ac08c4bc322282517d3e9201c601823165882a09f83e43fac846c1620aa01b8, + 0x25661bfb76d976aa63291de2624e7f306a50ec4a32128a39bcbb6cfe34a227d0, + 0x2dfbf71289f57fad67be3438cc1f0dbc969529942a623a899addfeb77ef1945e, + 0x805aaa9f12a17bf01288cca68aec10cf08db6bcf49a8bb56edbffb97f6886df, + 0x2bfea7d79a17720df5f215d42ab5736098c83da075facb964eb2fef730b22564, + 0x297315ed7ac6f9bc92b4dd4a4052519a5029ce7c97eef84ff11a461864dbf9d8, + 0x172960704ca74222cdd9c8ebf1821031312b4c21cbb282c1f11cdee3ec28284c, + 0x14b30a8e90ee6a1e22fde21503094bafa3d61004b38a69cf94b493e101a3dd29, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x25c2fb93758a36327dbeb7dfec90e331cad05a04e5c84e6b40e65987d73ee448, + 0x15be6f22cbd5f38ec70f9133e8392e8fdb41f28d831c27bcb36e415fcf9fe843, + 0x1d2187e9af970cefee949d0888c73dc41e7e257e327a9f20e4648928551e062a, + 0x699ddcb91e856bd25bec8b21980bbb163d38a20d47fa9d813a32324e80ac79b, + 0xfced0a1de64093947616ade5773e0f7ba22eac4862322dd5ec787fdffe3325f, + 0x27768b29635a400d365c934202e4bded719df8effad85e6eeabedc24a4154888, + 0x1b1f6642ad87106cd16ec5421b38c40392423fe0d12f282efc8474efeb957d1e, + 0xa3e365d3159084cc673a44044bdd4260e1bd25b74f746772a3c77ef3e48cb9a, + 0x24179d5e64991d45a0634da43510ccf0a34059695e151682b9d356411edb7cf5, + 0xfbbbb67aa88655564de38814ec6376f4da97ee274586c5287c163d1b0f98dd5, + 0x11edd5438d9b4168d6e2bbaed31f31ea464dbab80ed5e702126fd82ed38350eb, + 0x1b76cf5e219ed4bc311a00cdb03e28ffbf86542cbd0252d0715bb48469c15dd6, + 0x148437b32c2bc48962d356ffcaa4edc05be984134fb75f3956d5d91044f79393, + 0x10942207a5f66bb8252988730fb82f23a45be26389489f66da6fa113a40ab0c0, + 0x124681e28623f42196e8ad7bb2374c77487c37485bba1a9075859582d10c061b, + 0x2f9dc5b15dc408e7e97ead3b9d8cfc654f6914922e33d7bbf4c061cd8583bb2e, + 0x11597e8f45721d0f8a2900ec7823302003282aafabbbdfffc64e5f3caa274777, + 0x14ee771b1e80f23b2fc58d2f98d43a75dde2a5c7d37fb0ec3a90b661ee4f191b, + 0x22142acbf84a03df8d16dd2ea6dad8b4100f864e5dab2f6afaa6a4a36612a4c1, + 0x17cca25c3d45d22a57fe904ab20f916d9b1890d5b7f70f56e5732325a790e637, + 0x3120041b1c3a4c87445672333283fe28d18f05deb5c7e9fdce6cda7fa4d069a, + 0x965b18e93bde84a1d8424a74e69eb6aae7a73fc920e5cf5e86410a46511ffac, + 0x3601f2a0058f85efa835c5ef0276719f80779d854e881370a3d4150a68a4b65, + 0x14f0454cb6ddaf09579651aaea20532036ee6f54bd9893614b2eadcfc041d756, + 0x11844e3d73731aa76edd24afb82a49d60c861eaa25579c45fcb23de6a45667d3, + 0xd49b3c8de5c8a009efb91116d019f97c01ee5289ca666b6807fc89fa0697e32, + 0x15ac66208d53f730d995abc5cd72d50ad90909c8cdce17c5aa78bc0b274a8571, + 0x1c9c5cb02fb78be508a818a070deeb6963c687dce2975aa4593a89ff1ea675a0, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x210b5dd8b7bfe15189d3aea8e53b5bb7b462204e8eae1f9596bfbf1cab727bcc, + 0x1e72e11f21abc22a4f68b374dd8726a2c72f9891deb6536f3a4bed98cec40858, + 0x1d0ea48d109e37ba4d144a4251066d6d7b7910bf92f44aefe7081027e1e94ffb, + 0x19c6c9e54dd8314a776b1b1e8d423cb2fd5b6d4951f3abdf7176875a0837b3e8, + 0x1722bd20050713407ab428b4a1598dbce86e6a04f9093d0d415b546bc1d265e9, + 0x1bee9ee0577f4a46e9500f2066dfbffcbaf775211450f521e13aceacd519010d, + 0x4f1c326c88072a05332ad14d25ede90d430394bd8e80321dd6869a561282e37, + 0x2db49dfe6b2f6f8f38102e019206a908503e268cdbd5fd7689855932394952e5, + 0x18cacf5fcbe1e383706c2ae6e294c691eb86074e611439200f39b49db2739409, + 0x251e39efdd606e5efeefe439a1d01dacfd6c29729472ed884160d4018d1e510, + 0x20ca4abd314e386d0154234a94bc5b85522a1730c005528a74d7f2147e449437, + 0xfd8d3092bca7b55b7ccecf94172ad86eeb0336257108ca5a1786cb88be7249f, + 0x14a262e3bfae15e0345a1f837f1343b2b245fa3dc706956bdd64a74c48e86e23, + 0x21e54491928f3904814373340aa65a0f97be52dbead9b91011fc454b2dc8f6ea, + 0x1a41918b8c68ea8d675330f618419302cdb44d7c4821561bf3f75f10824cc06c, + 0x21930445fb5f525159a17da94a2dd4d28485794801b0c9a694b03b849e0878da, + 0x17535af3d952f2a356554ad0183697eec1c86ed9db1121036de89df8f758c7cf, + 0x1a82f3c943c80fe4ee37b238146142decb389d69918a0d7abd97a691e2ab80f2, + 0x53b942c6f210f073fa9c58f6e607da4fcacadae35e5bea34eeb6a54cca2eebc, + 0xd34f91b743a6ba52c32052bd0623804fc8cf2bd384bc98002434a2c9614337c, + 0x2749b7c85c71adfbeb5900b6334c4dabc9925e9885c9a525e74f1edb1e630a8f, + 0x2284a0f1ee6a86ff447d51e642951ca76a50fc3f4c0d009228aa67f9a9b1f953, + 0x22c7f25053d11e887909b02af7de7e57f5b5f9d37ff75acd8ccdbb74b717e23a, + 0x29c30ea916675045cb996f3d2f3662cae115e6822329f93a4d159f18afcfc49b, + 0xe555cdfb1576e9bb5cb70a9234a6e9238b912c9d65100f2dd5f3130bf5a000f, + 0x2f16e6a9e0bd6fc0b41d91bd065f60dbc36179607545fd58f0b1e6efbc86e172, + 0x25f261e99981d3fd2b094a13dfdd14e1ace2d0100973ce0331081826b8c69ca7, + 0x14d1b4bde07ea82505ebc4f4f9b599ca214a099e081a286a223bf8309e9b1348, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0xc2161d0dfe1fb1b030d25ba9e72e2d0f9c7be11edc3ee0310dff7dec3ed10e0, + 0x1de725c7f6c995721e1a1d0a90cb31563110eeaf81456a3f8a9809440c9e9e14, + 0x12389968950116f0177afe2b7732608bafa5e8d50393668844f9db50455729a6, + 0x17aaa2062cdde57f4a67c7052c0990ba08b3e874633dd41237cb6094246d678c, + 0xb9984737ec0a6541f484c9fe4837a7639b58d017cdccd2beb305a937a0b79b0, + 0x320982d756176f852dcd74ce8be156b5d7f92db99df5ccbc5cc96e93d83773d, + 0x2a4319d0bc04e4c18b9b105983c8744ca4cfc428f20ea477e9a60441ca15cd52, + 0x182b9434e89db547bd499a5122ad77854562962cf0435e21d960d1c4498edb5f, + 0x1d26abc0becb0e422d36f4c59b34f6fe77ba771192b2fcadc8cd0965bf0ccfb1, + 0x958a9dce1b6a17620dfb54c364af3ee428dc932d81d1dc4669503840dcb541f, + 0xa8a70a8379d71136fbe77851617cbf9d52257c32c9c3ca4c8078c90ced7160f, + 0x208a9a840025bc0c38b883213fbbb42c311c4d7a3f1c2d53924999892fa9f931, + 0x1f1acec1766b25775db439929b1550734fd8204b77afab09e4251a2e1e123664, + 0x387e51920edf06b64c6bbf3aa91d6de80a4c3a6a55493c4cb038f55ab379b97, + 0x283a3b099b37a60369426569295e1919635a5f557c26e2d9bd62024ed42f6cb1, + 0x3a82b07486a61e769d4f4a9691129b1497ead1ea2dcd4d44fdb626b31fa4c2c, + 0x15aea7b6a44e01bd2a1993a824bb751773d6ff20d3459974f00602982b20f837, + 0x91383aa8ee58024a7d0eaacba661fa0afa042d4490bb02061a005799d8926fd, + 0x1c4738d32fed84629967a249121d25afda758ec66b825730f4c0171f05981826, + 0x5e10a29beb202a5238338a3cb6f3ad81f78d044a791cb03cfd63367678373c7, + 0xe3405582a614f4ec28465cccae382ee3e56fc67f4574846f5a011c2ae4bb316, + 0x13c2e18736871254346e7951da5758a3bfdbaea4a37c62f5204e2d833c9ffec6, + 0xe892a08fd4d17f277eb16d8cf6ea60a8ab263ed317c20970c54e02655bbbd4d, + 0x38c23026542424fca9729f5959d6b7a300d7c8663dc2de7d63c98fb737c885d, + 0x242560875a24ccbded928c30e4c78e28f36975b1767933888f3a3eedc4e56759, + 0xe32ec6d6c80d3bac0aad1635fb195ab640de35ed9e19e60033751b9b17b7938, + 0x127f81d915a7546cb2d35659181f70a31cda6b1c0f011cf3d4d2d908e44755fb, + 0x2feeb1c3f308139ae4f23ced4a2bd3df75c7dbe7ff9d89ab31405ff4e1f88034, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x1abfd157d65b0faade670c600f964a0582539691f909a27f1342ae7f1d1f1659, + 0x287edf9809122fe7f424748beab604c04270dc4bb549932ab49db3e42ccf675e, + 0x574627cd0b8f02033621b45ee0293376d29811f14dc701b6aac4565c5e2346e, + 0x13be344cefe3cb23d84de26cb8dcef9ec21de4e275675cb81d8e071b52dbbc54, + 0x2bd04c2debf244a79c22c363e0656dca89ee4a641137602268796e048f222ffe, + 0x21671759ce3b7fa3b8dd29ef4be836d011c802e90a5bd2850db423f0b84b8f97, + 0x15e2eca1f4f24c534ee99f492613185b6eee35daa601ef5c73ccc1b2183b5928, + 0x1ac428a1c403acacea5b19eb5a9db448badb082eaf12a0bdb39e33de1b2acff5, + 0x18d056fe0886b5342e70987aa78d6760e87ebf840fce54ab3790159a2359ba63, + 0x103478de82699756c898690ad0431b1a62d0779b072728b2e8f9f1c3dc0fdc44, + 0x3ad3345d4e0b9af20a5acebcd23f067ccd8aad3109ac7d180430242a083bef3, + 0x84a2a0a197a762bd6c633ed789ae1c92af3d189421801e2cff4ca4cb7bb4b9b, + 0xb9fac3f1b5b7769bf369780edeae7d4009586d8eed37df7613d8532240a4b2b, + 0x2b6c5a5b0b2e999c52d385c1ec41bf6fa8bee62c6be1e4896ec6eebcb6577f, + 0x2b891566a83432ef436b4c379f8033c4297d73e413ab6d3dde28a446727d6d01, + 0x215093cbac4cd6a567810f829abc65d556c7c7d81937770546c68fee9b0bc5aa, + 0x59542cf02d9ed7aee0b72da0ec5092043be68c53e4207e4c9d05cdee2620c95, + 0x2c5db84b283b99e21c2d7387fcbd3d71bcc262ceb616379ed537e29d3d4f4511, + 0x23a84bc9d5e7f467120927f9570e3c4646a6ab1d7177df4a0972c42588ea47da, + 0x1af62c1dd6f9e0526f8c4eb716f2cb087122b6efbab08fe32af30d76825c7e59, + 0x240df1209a4dc3cfa2e57e4e0b8369b81ae2d530ee1e022f45476ef3d5541f14, + 0x1d663e716dc9e681f325217cdd3394e128afe26e727a3e74df24263781c370a9, + 0x280935cb8ce696be4fa88e7502cf01612d955d783b8703024a85cc776ba98bb1, + 0x13dcbefa8c14a98bf73e722e6aa233610b00c4687a29badca7ce239074b0b6d8, + 0x10184429c03a6a7dcb093b06a4180cf8c2b1ebe3786a5a58149398a80bf85015, + 0x2b9b91c8e29a94d655338b761838c1698e4b8cb751a103b0a35bca7380413e61, + 0xe8036f74c51d11dfc744f686ee20f62dfb45bf99bbdaf43a5512b087566369d, + 0x1e20b85a64e45febbac3f5fbfbb8b1efc111cd57c8cd56e83dd51bf62a4b2903, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x27d3fefc3fc713f9ddb2e3fb5a4943e55c336d9881f463532e63bd3257825095, + 0x64c66b3bb1fdcd169d3d15cd51d5f7b598642e290207911002b652693f48a9a, + 0xe9a5387f39fff6e25b4c460cc50c1d9a9d772e889ad7b3d357f016eb7bbaafe, + 0x30372e3fd7ca7cf85f5c5fce64deffc2eb2f6bc1f0f81b9447ced714e4dd47e3, + 0x1c698c1fb76b93d6036f01961482e8db670da8178aa66c57ea8d6f02218046c0, + 0x165745c3218528545f671cd07fe2a521f2cd6a5cc268601b120b9794a583b2f, + 0x1bd6ac92ec06f6ac1f1f348ce1f5608e60679a7a13c7d37f881c147233749072, + 0x646a2c8ed477619f611baf19f5f2315d030d93485d7c72a057d7521b05126cd, + 0xc5d7ece37cb949c5fcf9dfd72b620951ecfa5411f8ac7f9cf6706346077b2ee, + 0xe0f95062611089d30cf1641ef9f5142d5c09677428dde2a5b70990ce98862c1, + 0x1167dfcdef684e802ee0ad2745b448bc9488677fb4a9f21f4306ad438e8a7154, + 0x8b58d9c87ea695ddef4557a17c6c6ce8b34b20ecf1dde355d4f564f529d9e52, + 0x2c0c0c0caa80990aa8b3db0b093748f6d4148b7d56d6ac8448363d592d495bb4, + 0x22cf8f510e15dbb54dd7aaaa9acbb79d93c91caa6790069822f17eadc58f3bee, + 0x1dcbdcc87c651a39a1cbbf4a2429512ef5d3d5d2ef8c2c272bb11943f15dc73f, + 0x268f76f1dcf5f445f31a5c3e2f77f9370f0c039da51a0bcf499e89c50dde72ea, + 0x12ea4be23cef2bc588a2c5d3f0a473d86fe2e62aa05e4993fd8e3c3a04fc81de, + 0xaa8a1b42480a433972000e6b714bd6205cd020e387ab80ce788b4d244893d9b, + 0x9c9635e93ef111fc995b0f41181d644507a96adc5036626025d14c67280340e, + 0x2f19542276afae3f9bf2d8bc1ff25277634b5e44631c88a3ededd309a35fc238, + 0x2bf08e4ad9318465d011b6fad36953dd572e1a06e6ae04acbddcfde42ea6c978, + 0x2e415ee818590fff4a8eba14dc2db89eab455471fcb48723a23d28bd07f22181, + 0x2ba1b1348857a0dddb145fd370c4a5145794b555fe90aaab30eaabbb831e57b2, + 0x2c45b38c22d1834fad94146ecd9e2084fa0801d4d2500d3c9b02dfdae2c686d5, + 0x55fde4fa51238ae151360d0bb3e53d6bc88454434e0a3e7e81886971f44f1bd, + 0x1b500c091d518878d60bb9c1e46487120fafcc07d99070f6abeb94cf72d099c1, + 0x1507c80ac988a1d66a9b7d7e0d489e3dfa903dccdd39cbe30d66e70a4465cfda, + 0x2c5389c4c3d7db5534ec96975e24b341bb8a3950817c95fa6886ffa17e3729ad, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x220d668f431ca31318ddab3a7d699e1daccc2681c19e28782245bf06aa393eee, + 0xf82c73508a680275741c5449a2108b0b4deabb7adce05695c6a9a56491b09c9, + 0x81d2dcbe555ead7fea3650ec79e20c01aea1bd8694204cfcb53f440ee9f0c4c, + 0x12d6def4feb3b9695f3a33305c190d41b44360fe4f7edec96b9ac2ee5d19d237, + 0x188a70595236991b549396dd83dc110ab7848143320ffbd8bfbb8d067daa0dc2, + 0x1ee5cd9ffc83473d252da6d5f220a32b0f14054ed87e47d163f611b0a03c0500, + 0x336f443081e4e4ef2f80daa0d427376db59a5cd44d09c4ca4fced8213c49792, + 0x2e31f59a54ad75b935c7968deccae44c7651c6989e7a194d8eb75db56f3c8e6e, + 0xfc66fe6e89f9c6b8fcfb1b825a394b791404b4c535db02105a0cf9b814718cb, + 0x19392614602253f18fff6c6add01041fbf1ac573c430bafd1be9d0bed661f9e, + 0x26bc696c9022801b5558f13a240c2f2595cba3d923740bb15f857012d65b4e30, + 0x3e41f8254eea920e176dab66a494aac26a9050a6083321aed3e9c60da60f30f, + 0x277e13cf936573c9ea57fec54bc20dcb76b9bb22e43dd7d3f0c88ccc4350d4cd, + 0x100790eb28152be3bbec49d19719f1e819559e0b83cd3fa5f55b3f11e2ba7c5b, + 0x8a5bcc49a8ef4b71ccba577422b91bf7b0eb873ed4f819a03f84b7b22b3748b, + 0xfe17cdcc7b34315c294c9afd7ada649e535d66e18bf207d0627af9b985f0fc0, + 0x8423e16c6102fbc4eab76ad8b96e75ab86107261c8be93c4fd3312a65ab5bf3, + 0x24659f4e6909f198d2da3d29a4be15ff86b279a012972befc5ab6d55e6d38807, + 0x145fb5febeebb5b6feb24341d5ad656cbe31346d4146c778f495fb1948270c4, + 0x13ad1e400a7375f25b79fffb3e0ad1d1022bfb6eec76f9f2762919eabe8d63ca, + 0x1d087711ceeef2c9423d13cd5d262f9c6d536fb84d1c171bef1feb446ecf88cb, + 0x2a914d202be77991a1357bb453bd09062b6073f195f314e552608fafea4fb38d, + 0x1660b2ad261b31ed9a13147bc1ee06a9f186e70cd619111a21b51b33d2d1169e, + 0x1bcc7790328fa163162a0e8544eed39b1a7a96cd61e0aa49b117ae18af29e75f, + 0x2ac02b109eeacd4b06cb5378f08cb37d622a856d0629fd3bc03d8e2cabe54ea8, + 0x30616182ee240c6e1792a51a9bfe54aa6851cc10b377c468021dccbbfa60a3fa, + 0x37e7fc430f341384ae6aa7f96a7173a91f7d896e77d464e1f8fa8c470e187ac, + 0x2c238e1df2dcb6d7c94bff7c9e3a4951fe54db4e926c431fb6332e3f6ad23da4, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x200ff178d06931904472b00fe23a8a113d17ceb33d6d0c910068fd5168a541b7, + 0x2c3afc766aee27aad8b1ba9fb14b3d56e2217c9c7e9ad3363d56fe5b31721680, + 0x2128f1a125e0c64edcf0d03a397dbca56375f0fb87ce41480e525c2470391e7d, + 0x9c62fdb776c4fd510eea089910bd2537f8efda0286768d88a2c9ffd4b8151f2, + 0x20426c548d66b90866a7ecd77278c69e33b3d1ab23f0801342e4064b3be82618, + 0x7adcb9b76dfa25de61d2902ce37140c9cfc7d51fb2f8ef8e2317163f06641d9, + 0x914a79c6d02adc94876ebafea2b8e6ada5ac238e7320147fdfda370afed4e94, + 0x3a5d3e37105e1d08281bb2840176dc462a386409ac1e7eac82be7dba931e9a8, + 0x12aa83b029bfb3b8f742e689995ddf71c0aa28984dc073e73a38aa8dd8a72de8, + 0x1b293978db1884bd8802eb86d98477a690036f148d0a07b165b9437a87c8d30, + 0x29f5d2ca3bbe30251e5228e63e1eed9c906c4d98647410c4a3c74315101fd5ff, + 0x7bf47ac1aeee2ae48457ad8031ce6b2c072a65acac7427ef29ec2166c2d1f1f, + 0x1316c94951ec5aa5a37e96922334dc116d22f3e3fb219f8195e25d93e62d282e, + 0xe5a891e769da4c1b0d10fbde39d81225fa6c48216717edfbd9443541130abd1, + 0x10a84451b6d2e943ef60255bb33321f4d3eae64981695a27bd75d7c72cd85d, + 0x344e6fa9e638ded4d99a92b2dae4381ab2401aefd50558fd8ea90764cade9b3, + 0x28a513ee6230bebef34ead9978b224ec3d8f252f2c3956a781854d04a293d5a4, + 0x1e21c489a47bf56a811404304e04714ece44f376ce998e3499ba91fbcb0fd207, + 0x2563badf855b5dd41a35570028bf5d97e9430a60962fba0441d52860765a4120, + 0x209333ede8112c2a18bed033eec46e7899c53627cbe5d7ff49e932455ab51612, + 0x1b740c4dce2fa0cf3af1053e8da92456db1f2e31c99caa6918c8297e3350fe88, + 0x2310a0173db9d135f259497b3f27551d01feb64d4e0cf2233f7823c8d4e16219, + 0x2362c8df290b748b65a8680c1ce2c43c5fa82837c5f84f8107c12ca823709f6, + 0x24bf53879bc6be25827e47537248702baa3a4773fb5c17476e142e70ab17cb69, + 0x193b4986cecdda54bf346868bb20f1d62e3e795ae49a775191a01eaa4bf095af, + 0x171de60c3b1f06108a0ea4c621016c0400fc9b96af211250f9c25062aa3f971c, + 0x170208c0bb8840367fc496ede9af48ef98913cc6800a76318fd8fef208860c19, + 0x19305439f5cd0d17d75d1981b097bf61709a427cc09e83e6e983b41bdee4d8ab, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x14d4a3a0742364a9f659b29349bfa5455751e48da07705179afb0d01e8989db, + 0x14507c7d18dbf71926567faf318f25bae7d15d1627e930fbef4dc76068a1eb9a, + 0xab92e37d54cdf29da56dfe18704f6517ee8894c9db8e42ac9d3f8c80009e6de, + 0xd3a5cce50b706d0e2d5ab6d99cc5ee19d414a99901ae56d8ed2b90c70161473, + 0x1faacbc551048977f44fdf37a9c68496027dfb6de98761ce68087ca0892cf084, + 0x82e2d6fbcfedb2a32622e4c9f6d4ced6cf0a570062df9b838c4684f4a8f6c2a, + 0x15345de0a699ca5370e036b6b65ee4d4d3412d46901b471ca44787cfba69d203, + 0x125429d4185d9e71c4e428cc2cd6b98da229e56e941f37b846d46c6dfccba94e, + 0x10f072b77d74f20ba0d03b4115303bf37ea98a20a51f03b54756e770e3503601, + 0x3a5a00dddccd6eaa0b88cc6ab2ef6b0452a206a04bb5bf2361baa3f2136b2dc, + 0x301071c4a6d3e6b3e274dd6ecd6f5889e65e92dcb190e6980d8765f946ea5ff7, + 0x497842511b8c65d38dd10ea79c157976239b771f5ee8a72930b45c15b0ce6e4, + 0x1a7f3811571bf5bcd0786a27a61702e4165a02f734965b52996a6cbc1abf6248, + 0x29b6c15ea8aacdc694b94efd98045716dc81aa60c6ae224970ebd0395a6c2039, + 0x1ac6bb7492d1e4f715604b57a281164ac925c56efc0cd0fe495e189914f1478a, + 0x1671405a7351ef20e4b093337091a308e1858d50656a24a08993b416dd0750d5, + 0x29784e4a72baef66066c6b4a580e5ee0d6010543ff0edf90ae6177bccbe3f34a, + 0x15bb878d0c3129d4ae1e3203a7e88cd90f025c8ba652403e8be7241c2908a334, + 0x145ff66f889d0eba5e243c1c4780f5ccefc25775a82f555aa6acfbb1e6f44792, + 0x2397dc005d52a49fe64bcc7e71398f4668e4b1d7d23e2cd41f5a240b7fd2015a, + 0x104fae947bc81f5ebb40171e9ce8e51d91d558d686cb92d39ab245db3b7f980d, + 0x11d92195df064b6bc2f2702af25e1d57a49adc4774f769d32b632ad5cb29c38a, + 0x1de8fb3988b840fedd6f1ec8f4156fdcadb7781b895ac7267ff16635a57cfa81, + 0x27089624e599b1c50dcca8257a778965238f557d50adeee696f52f5656affbdf, + 0x1e5b7ee2346227404b1492732b5e6f36722d8bb7c99f2ad8f48c6123519218c1, + 0x44744daf2989bde9d3d36878bbd2116fb0e6f03f36ec8c360ac7180c6a87a9c, + 0x18b6b8ae538910b9634a54cc1903d21f0e9a4626abe012f424ff26e7a4f389db, + 0x1ea586928d1078d44a1a4bdbd2e566b924a14187c428717894ec06f47d01269e, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x299ee7098c20a8d8485fb78b37b5794235fb37625243103d86edaac65fe67351, + 0x173d58cc84bfde0327aa48c131cab0183f9b471f25ecfff26cd950bfb4c4f744, + 0x163536baa734cee7b3ed0d01cf2dbefdfa8e8f5b26e6fe1eac9411f87cfbdb7e, + 0xc348237f64f9f76bae51d147a191aa505fa9134ddf66975b7f54ca99b377894, + 0x23efe24fb00b171697d7a06849d9eac5e14e032631c17ac0dfd273eecbaaa293, + 0x1e7878f760e864ef15b4039e253047ddee33b082b6e3ec3828e35c184d455a66, + 0x2bef7ad013467126fe0cd58abb1dc92d50314c8ae9410163fbf8c886f86fe02a, + 0x2202801fc79b3c1ce769d85ac6bbe8b8225e81bad63c2a26fdbd813eab14a147, + 0x12a9c7120c9ac72e58a53bec642e04890a20bd2080b06717d971c5cbc74e9d31, + 0x2dc68da29a775c40fe59bfb40d1bf330871f453995f7cdef71b67e14356086e1, + 0x110afe2764fc7945d4fb2f8bee04cf7b8cb3859bf62c54bb37d0cbbc8fa283e5, + 0x21ef54ad10c3962befed62137a17e8cca0ef4476d68f57cb31290cbd089e9123, + 0x1c4faa0f27dd17f4d20fc930a295dc90afe4b2b319b72c7ab3d5d67fd659a716, + 0x496dac1141cce7811aa16c3cc7ee5bf926b19b57e4c2a3fef441f6a4f3e5e0f, + 0x1124c584f931153f9eb51cc7bf62a908c7d935eeac92ad89be0cf7b3b70bf0a5, + 0xd60e7160e15c49ac0535919cfe58b9bba626b7a560d187d93c02a2013d7a25b, + 0x1fb86c2a75e7eb166c625ae15189b3395bbac9ca27fc7140420929c57f254dfe, + 0x302e9af922d3af8a056f402150e34809253afae3405b769561958e2ece0eb937, + 0x208a3e5caddbd869846894744991f2d5b855cf126f2fbd0da3c7655f6c44e6a7, + 0xfd167a0ef538adf695b83b0c7e2b65edf204f994296f4154adcb45d5afbd5cb, + 0x1231fcf2898720a22a2a98204af8bc2b06e0cf72daacaac1af1b08d1310e2b30, + 0xad52af94770e15ede8be17b72e4f2bc1bfe73902d78b7f3a52a254898131b43, + 0x63dedd90276c2738935a71b3acef9d2f2dd3b9bd49e54ea8b62261422d3d77d, + 0xf58416b4af85510a6f3becec11d8db6c097194ed62d4a04e5a2a295011a3bff, + 0x15933b922f212592a806daee6209c9a02ecb21ce2bfdb1353862d7629df1ef97, + 0x1228654cad70cfa7a1f1f30b4cb5d9279d2f49bfc233411477c333cb630256b6, + 0x1b099efaf6a089382b0231daf9a65505b77b54b6af4491365b9316f988bcdca6, + 0x75756cb31cafce46aff3d873280c21ab9253a0c587f5a5e107364178091e73b, + 0x4523bf1a8f284c6d95b310dec2b54e0e00e59b571dd9d46b6201c18e1b56dfe, + 0x2e36976f35a34be56bf3881e93370f08203d1f8b0be967cad4ccf4d9d2c83c52, + 0x1650b34e0e8b2ad5ab5de19ff253eaf6dcd3e20d22bc69539c834437e0888513, + 0x2154f3f4c1b5b2a42078df70bd1c6b4f042ed01adcefe5b603b4830008715af8, + 0x281286cb63e657f78e369c0f6db3c980cdab1e57fdcf32505ccc325e7a9e8c40, + 0x3008b3f202e3d206436f7dac2412d51744cccbc8e1ac457c11e0faf6d6060cf2, + 0x2c0268fe5d032bcf88a2803e4ddd2f3e1dbfb58915b47d0fca518043272d5b27, + 0x22e8ab4fa7bac348cedbcfd376a8ec6512fdf78adf936f6548594d6584953227, + 0xbf717c0f092d04fa4598afbcc898ccbcdea3eb9d3d1f5042b0f325ebd57028, + 0x1f500e6028390530690b82421f359563c768803db6fb3d0135c5366c9cae12c1, + 0x1b9881d9fb9346520e1e411de0696df0a4dac3684a15c02154dc0e7fae528484, + 0x24ecaab85ce3beec4c380c207c564f4ba6995c3290f2766a89b73010eacfca19, + 0x756a8ad9f562abf2600b8dc808abe6a2bfb0d4352824251e07be2c0e64dca67, + 0x2a1d50d0f3da33a873e9dd5e5e2966bd40445c1e6eb9504dd4b276ecfa0b318c, + 0x1fad2242540d4366495a5ad4fb69ad25b8261d2e1ee56d56669be07686e9217d, + 0x113ad8b46c3eec20c9965b5a7b2e8a51529871d0401b4de6f63de9e5211623e2, + 0x1fc50a16dbdfa1c3b99038f47f81a1c5d1ef6e7b221d4ccca6e821220130e000, + 0x1214a9d6d7288fe85651a8cb83048c7669c83b5ed82ca2642fff01e852a44b4a, + 0xd421a7c25af5538788f49475836712af5da156f88c5867568cd958e305026cc, + 0x2de8ba83d2b6ab6a711fb9230adee1cba46de8c930c86d266acb8c1cb9684e24, + 0xea7be82f1cb493b1bbd83ab7ca285bf0a1559ea05c3f59827b3b013d0a91fb2, + 0x1e3ae7e5775d352651d713ebdfcebf9ca8e905cfb792bf7874239450f914c8c5, + 0x5943e3618a32cf050018a4e2375f4d027b8c14ac82a0de57cbb90c5122a64b4, + 0x603755180f66e98215d61e5346b116cc00cfd058274d7d969b3af95e78bb335, + 0x19817db66fdb8215ecf70476c4044c3f41d78ac5a549c684e35845947dca0b11, + 0x73965f7a9ba8cb33a955d42da55fd7c37a3f0226b029d36dcb3fbea95d642f3, + 0x9a550431430846b6694125b5642b00607f36a1a29485361a3cf427da77eccd0, + 0x68eb4e9d6e0a588b61a6ad501f380da0f009067666c0853d156e33d59c43515, + 0x225e00a0da5a7f7496b70d0923a7cf7ff332bff06958cc0f3fad439874f6024d + ] ) } + // noir-fmt:ignore -pub fn x5_16_config() -> PoseidonConfig<1152, 256> { +pub fn x5_16_config() -> PoseidonConfig<16, 192, 1984> { config( 16, 8, 64, alpha(), - [8089493102530595468824649860529717181797071865148765611726566631095271469313,14191702863884040950201894968554909828474263688190658890761244249722339089253,7127251756910107506817428481560230656411897313679770455026102671367474097624,4637045655841785226199626823170615348821917492997807409130873179711115857270,20694397780982417522377524687614391225351058648522092200738043379276991211973,7370528537006777008458800981771544164650999525791518443407240929647301337224,8357863226135085648491488089966537213596680483394798064376015085804610201240,20367087512494301090653054692863377975501664994817680661442168333644299005261,1950307616347822794878104597377932622958317394806719432040871827549672571148,19534568412595886801081532478416580190048212177563706092280027206347120417736,3526428150493332211163778868665379218281231008068537115657136020226387337771,8661888879209475483716403816709663500534119170711151152467249807886559994385,2374871949454649266019269203973683966955509927334059254254180194157352943840,2602346264611026079459352146265308073912201263350931622963181149514761751618,16750875216633927741061710170647391823629779494283192027015930006045661350833,17325348607596842041611786882495470980592459865615213806942169413086586278610,19257833407854296241609506861086921463964253377452883026082737974007723285939,16875536222414380047765946704936299627494679557426090013440678117262080229388,2035577529925145134060996791483051399276402053645795728801937468290487364296,14222296831200170749164428995066771764920247405996747821740895709606052517407,19708208883712347371628256596476366883171584832295648266624355950215220127904,9765600454835189412776212142789582666145342479104764891694616693066517922502,13365055082376018935548592209736650793571432301565333849832704476237136996118,12420692692663472732723794387493491467146971343430969855362995088112286983728,17844493444787722109223680249951335211927705850925719012603471955916755628715,11924944537382281343613401541176014853361783437608625866798343540969055542140,11538333989403053525558050588509973706031711021450280471202165095037142068477,18764881783775503232423409005005138632447539466481045749407270569758537393398,883162740610443285913150132085694648635519837269866659825930623017971541006,10171610390436513861069093903522467940290613868370765425375996220687957422386,3782996878040749700177878799895260702330488343333700969514291046490113056911,2239298968343190621001798397134314102896115970272480212453695048745962826317,8391302051404015178833807081994898536482484463022532956140929200199667853077,18096164030411129129794470313655227930799185448547884977984818798794318221345,14613424916575212836238688482051323957035101724778773648452919665593660234946,21828842930708391060823304507355770719075227415675853536112390374449711667078,16155169369395425892836659730715232159396910561858841286007416017756724971516,6878543234699575736262375462702866780772252779651204219697567141737826275015,6515580357485419559928692633356133128461299871887195169242750902403019378404,3124270150531482035695013416051086970123461406854560487654035672981879561715,10574698281815682641771693421115734396172155905702803455639975437772362072107,16383053320907906491543185419013182425229207444535577699313377451249772804551,14128602818455692582904557734609240140547347183347545360942329621911511704432,5010441108136365108046592406551529565385874487432431586303802326844966531017,20105162467673383983751690623903949493335895059047083944279780871549558030082,4243524359837792598965046978953117623831146922720880550516255054678204683627,13992943040313469850370025986460260524555943628212884466234808367632688288666,1356223459509978352432345061666791804860823828908318470584528377749655994659,18723939192823222870283999271398340959482157197116460943968917507878394278385,20636603031793247786862933945150382157149390912061952007323929980504212222032,2128636310217902240014588202116301452804441854659460379597999718252532068242,8892458127594737495267008183431736534386964959413452688074230438040504386190,11063574691797903196312547816101464620325790434381460261930676459857164737407,6204567085759054728130072959301910137692879386674785283047171198023995380593,801138962072186678791979363551434811728526970692377261272697294596118718403,12941641588837981062781447688458784558606932072335320068724403816548547438675,1341967686547656677059175660053506857201298028878352128737987225407679621418,11183207447266717668611438117401741351804062326702937903525908319309155043524,18507917680426998547390822933408085624123062783706353845158832700169805897057,17600956758590554476691669608345000941959084040124470813766683278150335958657,483394656899715242498310209793599026850663551066988094136788591643990355221,10090827432001200203094010206359607863114405903353400294360808239534902160627,10039403020393871677252553778177538625214464462052976366251977746523421324197,1924712848258707645798108847678093621275398467857399987976700805356929290674,2167923809975069342404582706442301809782773089534518796665536897555762931998,17151337466618795643803903749019481111634005237742283518609358703199930418386,4693404918498880046514671012411195415185134287680728307646808116832211396470,4839381186041991439202094011010050618021148651243083039175474529769659591768,6368336559448535344096548979708211013055912139451892726345028976601375052582,1969826462127986113899121152613324197819709993940588880171966228829834184618,10949071784553227115382687140318153702912633728202525040498248461299029092720,14575837988956266060370685891330921140979730144767405243152428616625585430364,19025750374860322288379311751788635906611708349625974065695544669443137256255,8764838805814072278932908632105809429351124473407135322177352737762640822858,9508966145895699172941574119083482387827406291145211775810415653335356563307,1499853062814132179278896768948580432185360181707926223121987796423000161587,6748895423937754323870965728722563272366114856617067613970193226138372983547,9814536604142267489967579335173323116472525708739068285104384748406479290252,18898551978119284539473648820403307265793266184829523824179430658011490726286,13332891294455702171134399009213907075208764727059236543259960129130320074982,5806223588823614408610900761814632517803554600662169829453323047489266087405,8600992771060584427141790133616651912076186875693672268259185811464115092188,2345229032656719135417406942532115442859563039531904661440827899574284256939,3389225209359511603097670682835778418062727662626674404140526378611375444627,4001034682434006987902788179906586121095610380401857294704332109514659937637,13067063794999809131589470979742146742674772176859338210659998590141023560073,6021149641876662294720012642501582990883570287510418620500730995186581678990,19744062936660555217694711756418639275110313106982456779211457821487189038259,4280146833782122185864346406516267200729946534205141990397627632307276252746,461380210352497258096433274264553487092816458993207056498455795007735775326,9185904966475190600688426658264723956468287249470549941528026771035049026029,14362213733702712122544208087232387435453213772974406963783416068708716342186,3376133122839395926880247692021311631985267298172444834121553500975764354590,15430636928872496244042298024957854104479533547499980110816885404855993587926,10066678820787654667318707571747478964216410231002799394324814978870300697084,13679726663800139966289976616317518761749708307387522908283736372782010246091,14452498713182028708607687209189129972318024710956800636750706657647839477841,4665977443169087186016514814881141858109411469723890078365751966690257156734,20673947333628935106924449469424554002781432367358546714606202194020160454893,8371937803667063739943392730412639954872585103736021824547232324141910768530,4915642891224254203187535229956007243890165147322145197624420790022741880987,17737894427474715513464524059598818432164911920893615068415915800842574129123,21257751286440468433003251296883236318376753833102432675015194790356307947025,11831044910484530710733100158936923549935832556815349526083442021617595246222,6362553671302097483758288321671356788227750730995074141338726755028234269753,14935971406087488699083625022278942628959200513244202282294495763807242526556,15337281352851760799121170871115742187805714822038335053341937333897883894609,11913020597445264316110942608419581486071629740611054234626537590474050938474,1838104841451540707239841220222372684744879960533787766800248740162155353463,12200586110950172266226854658183951607066336178441918240404611233042731023944,19022187774400544497696484163376638844589760125070799280660843859892595613745,20574219232807646025576258258887918895888511977194786423008507430088227970769,16786939539299167614623107235117810634408742454195124075763115939760135086779,17293110551721019748567259052064171353712124247596873005371071440209356535788,3515336831584582569659665150343000056186787768627351931657274076732504326799,281425181255898711371985357453012506419817930424882315501470435479210893648,12703632225346671660598644961986122293501524448004046573092229475506828991982,5589259102510829346047060861494427710966525350274659545392525201677772096380,16136155264962057601674035851031539132207654054954939479993843931937787809008,6577810342827559587628942717478127045802616172145914985109615391025970118111,21163359977438641650165237544426961690819476598192610702649950529921750524674,20111680006656824813833529237249851680178501017371275377838319189183351852836,5575615948519348213741695691025005079345478514823636124237182535409145360452,5523844323060926872300411712160500242292621601876678751811292002367512597282,2341781247790586645587607723874752210647545627417738353111026163429313125329,6287726121450538785847268284295299220404766172163996260292255850387839422364,7510648235102286772333427364079209113816404370140168905255311267436378725194,5010598474035699846534727472507206499428871255705467310762876793528248455251,5700900579731011250748267725185425351062102227041063523439252105791254824347,260864497479086430816275699586473497971665832148788274905912958670548982986,789172560806161139006535038197594038879692565830598745604163919464033838458,8100205286609553283468855217617464988341806863414698413875768149192804914582,8832923720458983936387697888604823914542155000760959167380458346468815941677,16408716740290439442219096309603613006830415688534254451854294128560591562449,1113287770802944863484309232492725673552460311886837538428140710794437752025,6321319205351235108330320300049882062942831936257890309503365991814791003082,18560922321672258596191688202021423732168869299915307979899958586924038420673,5189180998718572459539043290302679421565915950138990634526371489122263353689,21059088895950142731136323564720383671175925416797251043903234558355128937274,1758538453070760465213341124871446098960577889968251388551632606564361922354,8880106936008308891697048583874212287093823544613405494775675377028797786924,478113991762053058066048308336221551443374933771727184756201865704929054005,5364027562586142278013801938849728210749918309705526248720112356632858758221,16060418035757996187280816105829974246762721308664137780198420107462005497738,5211176330971465153824216149376981285606706263050338982115099875409328929990,10368007546243825628853187421535635929255384415227635572356066208437184727920,11427684168459596442778160390157786957054817508127224050241732612892526145073,18949700777601180659579150208396846544227381511915556752893455904600581402034,7164876529024763696100437397763470424696261670104386888341279210050743231742,11672893202716354350665939605724566655297144836947407230492353459173601370992,3909710158111676258105703555994764863745260060728195069107924779522169147903,11345007057187618276350650167405783488453459256756441881422153715183450077456,16177820285119478894470005926103825065477859050875380004945625842748711696023,14605787997931757094644238801452595674783310674883843033832086542610678460710,8394271758834499906719701243007064560791869846306715272114566194508664069904,21873434283102736245937985212570921154785039540401524103800440576512828034687,5288693737755970825903341313388382553570352630888453317445067182115774973600,21527468641133089700262079461319550104586512157305923587305104390806741900810,20906707665998407830558869509347677772600060055286961495556134628147066213175,12592377229521260472205372896527756013482774884841906928184642093380092134349,12910817347876296654185371831758099341950752668436921762585644650086702363745,19707023277054651202681442144426045379962145417802880101371794305270012080065,5370501568233094600905283140114160955385907390235753857797923590879732764547,4893525410028747500809250162311718717246192757157339358355279414251440821369,16933412769230696712087772684638356779344465843185712014276708361284654443016,14752252971762751211424871408209457845535321896357466404820315342528474475265,4381439374316418237204510331759065345075613480172639747277311241150560517970,18983302468109324889867853797358234303151484569217755559414917991855202421044,1720853637877748574561923069656227402993841601703014320322493127808042278354,18055674086054269831422192610284879350534759472987936156359168085840018213729,10022985435599924530950214242280707656465340100733875531414649379326713485700,19489289237398317489155396973411927208825921597467958674111652983018260376467,2483969152386321683533021854216836603663579724438750369420802837936459253247,7096495647820661985493920714559517131838710818830485847136203068929085317377,11239734991193991562092142618442979132467959527040707676033760692044595660477,13964689425465688308583323493745924709191744803740806305195114536185949582431,16765583167493792488003846249322412563932361325466895848165782639635509252698,9258699025821383775657130802030622351199780460158138938453769223645462201380,7261743362549790776698831974802523106349906457536556119083744106556343806039,12174595715224479314914773177369125156875875973781826642881907250708051936707,5012109434360646519756574765661145101042498088812514145017131935992653466441,4700224901573028234520633038757562359543812027452948633531739331172070339917,5524276305760203869547781419982228286567487292869238897177777816144717638402,17095081617164642751160867282346616888601375485714887290060713493809720024377,13598351826191942256399407492736185075239065075291047608049023984461266141081,17308136644455825036504551600136601372687794695239587014243640872267542984788,21730115551932424945388178787861491256026727823117641122401508483473017057216,5949879858200957394974414439063213931632579243992797429658708423363937192395,12803563373135008849577150591968062878999687541475931973931310610530915756774,6197313147432278847012935526443261694774265540021863115632496255704682355001,7028974783929794816060380650452873559926928309476428464943277081506765913122,4456589108827474318002287720505015907920793224049488679883557016295128273089,6100631380538490803600079371988603006023173019183128962118450543769518343550,20177888580254527519697427670797609876974132471313961205784103868094735572841,12073238358529645427878918495905605836088922482621503239707831646933770345610,21856100081180867115422179532992210187999850914786148325024530634866939637660,12466984235357303385071417632152615871825808908890287534009467031177378240877,21079839629488810269856967110699842674750899640941851601070908540874579869846,17874776547285892135748821889881943162098691701279199858985484844123833691703,1051310306073108765618056817409777616413695911463346454738615844650030082984,13201928900083471438265807470373218252839081683324776881761206414378175945385,10190119257010511211543154766347424644241552289850760573785222226686792626364,4688333485355359912766058497543573340825697092661609637162867722200016624599,17123765906835174464437643379916457993692257252235548439872663365295598699138,17134395901615480964750415429455088485278477136528521479550104193427850309670,17940167838269540610857156370913968688439335297994033024607831012271846654207,17211561414938780959438190369003172382648707317417933395371238331823656001285,16098871745352156970746489901084198750790375003919623885201193800062775011577,8110023901773238127710250492301336333009382423651067999842110155158638763822,2422126936887420595943345532312996428472865746519279257114791700143799243285,10404075183720133448708607844137643895914849868988851944394714021532771347787,15058460651933569411128043696753704901683095219148372416995175617698935925786,12723555146577954839266714779606964953587444931552430067661560518513484316738,5711657581065990142612711893585463369566607394626940266394184697079173482347,536257458004844094090200378771107142207864145916201798362001449936167413480,16904097338561724274235483260490381087656469057354151613747001642006805270380,5885951988825802528717928331501311151617037953699202264796404860914064325522,1638374036867203230684496314040773233229976276864977417441853704948079389600,12231982678049991867660964493898657015614690001085229646831798098083877705620,15427058040900308626278462505422407030810836290013997730209614367042825008816,8287021582226423932765127558352821849475385690410389396789209560743363809623,1082920048469231434960727235146664410555571531264546962637788898495946680112,12010985569823806398477426440616395624594456642130882649075614403521532359981,1296330560506042268524168200578272313263311415565810607634491211599523487141,13952994457760775342452243315330031022436205430079469228726234965837656704462,16985743548885988875181345488907967382109958231690477723834234297604193256890,18108965571078287240054765173491615799731924163046353815744437352944165909003,767530387704511846542067425779936904920481384673999726390798572580115466105,13028307645272598127894992332463015335938472044187733546491605798735426870634,7618140648066747223455845067208730203353985191563779819124185938438241329003,9331096408013670718143367691921833484100954507332698681105640867440874379095,18801244145798024592964955007270988394935375648640247134868164095028295260248,3795459656522732094044639001176736675357207553263371458375866920248726997086,837603424793724140470838171288512417218344963365692836088493443407197621528,5831962429370013799978251611601242499647911352287066127245255213245836916243,15608629818832866779793800587027419050315344573115273720682841552596629193016,1032806196152635164955947370516112750756471391006183599859124038948506281039,15696208732714216759620197747787990886188845785832889089576996959760026394301,7234583861372635173862436546128104054595325252312930586077823639855585372879,9351673222157837029929340587547626334173727344379333167413124993232252858910,9944025695384518607461067522154717153892207999526158631473359210163311199905,2388456762928315498284690717786606118379553818175612967295585468860359388241,8762894023280585818322989976434413098781364467068028456427186735232945062041,3982990592887978322236356963193527056120817698005386105106663667178275102339,15305580827228104504176089928458181616132990558748682555478070517971443343847,19329984412710376451608868772829323267202139442902035837598118892290482040500,16858720166203416564086563387111926247316950607110418622245689767918477559853,18241191751089003023961171787624834962373436019307905123520202159673396473314,4235718345809909430818933555490446039661741163040234575769526351800272747420,19336790216312697816897624746946849815032853517670504993859895524588720552146,5833407345693372936993877824926303626341316298366978224289402960052763586750,1246029211601050773151495439169819001283925818386531745942667315981536442422,15220086581176169769190817430254624676596374261069714496878816359393753960898,2365861900029834138601812494207710261363070950725532631535675557556177296586,11098939996500166020441603457997996414027684936264124308565274744828953147961,10188381420146390141161084654671015083379584925005132911919536024814384766817,4842017639583023386245773507388835267437650777401251470903076835565728725044,2473142702350888708640145449504461869356502285425231033191892981515210840933,3420689338060147901034254227618353913575873772273264928595432321920193621195,17283074258384994096612354354366039962078336488852681769982384814157770475001,21006196209784588036771700052971738964442512933084691689593009338899209077510,18493924441589584713280363204662484496255740376612784432044649586411869984552,18050342602178255577111253065667811034294368946566845729063425104069824407598,3678841436690736561960339537207788725774745841190361109044779271967419319179,7229032436003943468306271354423246592397907094971085338195794532946516086746,6074543407778673702938004547803408348112315194664133731027958879041743082105,20066840392762178519205386382693042859978931394221116082945207576871299356172,7392805501563984757154630589230967797392843859128971344647830779113836888313,12821992933916071670969878929371658252743368422895791718047075564423909142719,17668945380988406358182777882021562738916627352451654449781528301527115094220,11046977583853814151360987998476416244370762366051844251247672138778958746421,14002539550635338734484852844372585460419306414704948112807545053902011590061,6606166606298514036368338857611676551502463523513184670555953533985389963443,5446061818493011809543734117506203755719984305445968514525154959975352640311,1111668700238284277732413088411620500087954609586256178652323895010927817926,14149444834268176201304046807022441432518948094788616136522350328948362984806,11145589672768136991149928307436511325152474561287303838823870178226307903252,10735913608001838681702607049464645919999926391398426712273901727922068271016,21604506935173200936527132172076877500255612688310066661071635553990139487164,15839861321575777225084554553361389979179161218821903561853968278717519007256,4119757287481158134674144154651639875410119871143992982693366998676854632059,21215853876753845584435912754954004476252409742434691973232278809063267703513,6474112081529376586123095858950370103982143188298415134572081362206457634840,9652012486829416433331453480518336590399776148133427672040049807230079809918,15197188648271522366095502604900923401004235531330211517976306351199244466155,20653133196783868133525869637730316323485671920172550159454294692576016995406,5372382735415117884334788700701478755716540017619541377211078296573383620529,13207488856826369213621681118482759531513035177166234417284384049787214456366,9796874023172008376751307392327706745295558991768659529793122654595100420492,9923897870015737084413253850361127061692788482930375413255676958440886663490,20345695890485642585927456012849850866425595188379347054737827588286474285546,5970363931303429796131779726714445177344307738485323531135738898520018230730,11099832493605970375935052305980301651220466371839450598182845139430995541342,3984084259485258180085200952180050171170098877962423607492480207306084313759,14795772399510400766677766636479617776597353783628606580152075755214440944984,12411649494499018184602448007465543838785542392797557004957418343044512599298,16626394877225947777126043865023393002546807148362691512796749460115071596438,19056586788697785123807358806982924302021705802715675015657752728604200366151,4434453689868848221439283056960830923558217744100875597646474729523600908085,1558497076513757145941997689136111603376893591128645477322800957597462648163,19855312204158524284458047353907697917092904349885231039917644721609392348549,14296610840588714282305996857377052531476403374009704740496611471123591762688,4255702919775232787836264045412364184259731261431115977947396605020618214051,11933778709913818332041068411271656949772987367132405709674023277986614336789,17039721891026771364303633162265090865698196106396237296534502784700270974342,17677496806049413057414389850646660368467945835594987026827101037177591654389,870853693457310346529819971157542197768087609061398183617507613118675541833,18050709179661944189572532609164386192084249162773126990656248077533050260547,12509892200475964347152748879404468874956023169504780638942472032501158691943,21290469710465436947459252705329759527038443945558987181251205171276803887919,11697948989002333965655987240828667368730889495575710652080571936823918605037,8736925166569662118997397920658489847012314542439353474077461070832299486573,15840706598368315931966990863663232282633707371020640698077565307266653295218,2336556619780315190172318504866216965057876522664932909981631800248874766723,3401386693708589750154291055903211427275255738949699968058464589080271508279,2985234144487193053560662812519604867522985647272968908108472491424983944847,4708870044417079288579972819522537183137753616055169595344370650267781985451,14922125937386550210569417108464732470846637538443952204254988396764974305556,21120247382250540544939703044577215089934389719849213503558017786742393072448,2316928219829771701890891437885406935408196453098584469128414556890718887397,6617231706636202699892427347447707304283374531129890683057423079735568483257,8090371166463272188656489380541987815472988984318384965972491395697937697839,15553944362864127106455863696894507934518908899701997904436263710171474812555,13969363969212770297664533823398202808376213044430873505018872984372178723135,12323663899898371993768411530695190245261583246438004058508426675150745422627,16566875439359417854141203050455423662432117146587478868034846190942245403701,2085197407488705803446596939115235993629808393250087488250514287409223581616,3353163139852271259915937989527822937141797275129253304946488349312180510876,12046433326685614994434242499247496702084910418498830651483913063626259071609,14532850787151304296314608701306827699237853461438425922459530673831764439726,1248026383149472348014634990743396120794718445584945878307644249641199424325,8057577408830637105543973735712037717868264099646638037329061041095961932706,483318248530006664922961695058460281946793595997210254862751288308569479187,7597115662868588435202039449596982590007976221501668730777779068799655592123,20576588045443131888269350588198092656950342341724106762422448997215666028156,1519447772833782137513870714676314005111021965782273965574223992106447841589,4564008647036378562957325007261730909909040333020122431007246472496053026801,20058604285923748821870861850977236730661592466138938301165874489677433369725,7444135345158592582936132362592519965410456021574373937334236087846829245911,2619748000882337075816263795535027848943303678661676628903586805250445194179,16416961968137667392446268131224700809614764673462182053193218154672694280838,11133666903754924307114887742321725054257211678992195923482419349863465176820,18185607668620497969429683073093259678523061297809671850245875139394070019601,21100277417778348195596070047101971906596351310455360764416675735903158404363,19242696527172349562445561603976204919773321047775511674132373901693664836452,17641599298698108341739444819055281386405281781490793437098263180756526877861,3867854105746657505538112984381791148258872175005817045777653312620913799165,13673929044343556285939637616797217757029992003977067790150536754605693560092,1413616068844936743999269099411394796998593026467324669628149625629672193659,17182247321635044788965517464433108044764735758956097220834338897775232927292,20369403412607032840251975012855741679474191692713337906759271231600952698270,3368021137971787382116663997287877185273428758197831072626886100000321343009,4058882993633327642712241699549337354407965426094339469485649412411970892252,16745738472558294852806571713586420783108275141805815749526145532281107769806,15581910313143599067008775890965264886765882549739040775187928885624726340064,18274240790635707268508029122006654280996256674828118427269328392146795445159,20233611060321484677112349983942832171860822463387331585688221516502467246411,9578794697709092641086862842633192064390680557390699768090648655701242260988,2852999879330450264744202807076238853213578558186322493583347517686662265691,10741465223456896033565854764716115079295016404042872162238148987621341827594,1287682441013790555075762279132093640356858755666376578858076731440259199594,2754348824392215081276565702993043505186786457070961060283939332925679390910,11228376276796390660691597656113154929593350154734497204665175991737933493193,3311568804745845654494413785473574358224291288129470978720234105131364795989,13909323234259677397453192122165186938471237491769110758142097116703508140857,16483726454860443352311561107200491233365512138292033674515348800113826861405,9812016698744294015002456058504358834959473085649393839832264042031387688048,15177982625372891489410897122382147270421146795964397363826406495667593673282,7519222254582187388553575935727848524972644886624855076224718541180666103816,8301393036521557606902463799168007719863879180990998631543603658427343679902,12294426767414989378173056202553334768408199886443392931845979330633289559578,6739869506728400044391551988623920236526787529007157619233939477743084008138,20069013437903411974438964103206724858007754851513756279456345172264534005155,2018834934981362435424318060070780595968114685660751661802811774334240763265,9403754976005906248280231838299490163038233707814936394634595857779528197369,10417979303761863711608825801177810340012849177958033395021985945544086842565,19604977682052360618680964990952175014659495782934855476845092758883928933035,2688418347826037364876739676610309530415711729219616027453603183128414252617,19429655781202385023906019671461539686080096105536288714975255299583443223945,21850552082723421744247018249567438591533518178485575560955887428084379635362,5617579950805240697000723938792084314286755653766678432489519653418680110671,9555670299297105865403034351288164766308791892391888668326102655956067266166,11495978801695516791606532228534536491719831441531647897999875880662918322774,13446240540987488159401062110915298027617715146895881354765875946092155869706,7830137135198409572038952404379496414181899227574329472045729197166487746395,9556039398803760338966955211123892534270670688829455928022562515996727400498,16536848921900120010270774925810022257466132951671306792158048247185847693295,14984883995702583492812943326719347992462648669814085270913355351041523830317,4449876409800178139287642958372279285293173800225271693328528758341654973266,7254404965814435397385340781449208987509307430022649779312503908065673947649,13482540945483896073831058930261724641277618328981766008722675404404347005009,8516464109813705017846673381161730340458008814885800650922822516855928737104,1123466447164703934328741246642448511199513706388932930170273400845584259512,3549658554379334242628536166107543119171319090515117171924404150785175614651,20050236656917680705173407104625075641049186986084540346810909246977321174260,4328179367990709150244102496965604541058014472966567986200766436334838205729,6523960484836646945629638483047198947455910731228954877131634689551005111678,840118507410487418552201986292140077062095264830249777356756239948365951505,9443485141542020716795178817254625558092596484849541439794346219916656780924,17517352113160950398700094980635300524550125065948318365273967900505416951637,3558475678500267728084169977682358432036940763329037251571517902892359350060,21782716253294940222641143651977099452381765047328512527623130468565364299843,5143600969269719315523014195013433247337519583796238248783742413790148311283,6937766932051718809641611511685721559694403467477888704545484121202675152929,10248511959409536383597760784458127936162061804351541810962726000050652155800,15584432188633520588792022977848834701354218910295071102828776215462904575092,16507813940325077551530806573175229924530686412372461197571308720671287449933,11975780799589036547299759597975704141323969091612997515060812893050562154894,2743143635303404960353780118079778350398309245035425997562746911685628540405,7772317651868959663361913464992926253491072635393117289337616002993612374782,2337519377771760840047685336751334655527732210909930380948789294151305059244,3616132500009609097754462360087761508553832847286785396472146776175233605533,16840763079152094997371697832566620838881567041180683145570810083272689914599,7660270111053834825889064071065415593147131275236956990950685283090480450184,20762611535627684584459315491847035257226740939101231132494468375819869523509,11042134071344142565200223013849882651956544247603198913312251335786248573941,1940414570916441943786503544322754456611678071701943345167834901237861815275,6726537219661359488596406444614225094882184675245355532878420949418407567309,13510096963519324808490741235975735288120771162631019837713476375721562862601,8622373819062603720895891234592129397052930901106318032071934400492518897707,17024729268332782126190150627072810510918979523772816301096433100167961982933,5587788522776741050743071285424100117576582212221222382824387609679897172811,12388474196602817840033287553175313493977358457560707192943603355479290048023,17628897462697931613283808657115398230150168968257584770836553363771557372104,14065018459890202233327759187460200256630019200670511082974394473420421694399,6104554150616525884927725557698817344144889522156367737688769378902924558634,10992664178398974993431947901729345793474931192615930318284939994040095999242,10969415364246753478074755753965479915045305330246521543663858633748866143603,1272956806332000540144317124032834499397723122931270496707464205344164793800,20231387145101186513751955054188659753720260135170026275339142463242692015712,13619345053559735757194629501334040876412094886252831860426351060385674007066,15232357465863047438256672278087920688704670526832495687820763524016520668185,398623536003273726220923501915643032345957170167431833298597360746684401150,7028250324917735970960317543369047790628992348836498053408852879988541935724,9906086796055827169135574765108677877733074061825927799032011921038506005373,12788056119136131846722253277450922603309904756259034915496788214657808474919,7651468821535297879836173382809170069017662802420683445433781610638854359553,783979512383179545035255083828374733462990002107251717097983319441159249905,8836457559777657917879541925866800908082149812458375523311279635635800064090,20144830911959238621340309337187081519944136818938895654338696747143855879203,6287181334311526693967500402732058645490470512478517679915786729496945390849,6578356433253304325301622313818326592018737710185433748824597250242226401957,7102838428799453179757741468552077315750505008228901893660362447987283707998,497820320926977947430162841325159818293818758853362781494155076005984229339,18160985608878840530944322708383120179552980243808985184923313895763861919637,13151612592624659285402557051397602661028781656351284997191435582230535568502,15780018535650817819214066689149640940245062275718550628416824107970066217991,20500218068755784102392504532520873969817687889455201735073738515957629646567,20888440956803193084788282136946318522770638138510716565517310266646640263708,15971618258529607882347998799169510722902529521092131094419433339204085498306,5293253007777884257810026986010586149314566166761521493811000336947093325852,11581497334099661755434309930999056492294889088823870215073663090290932016658,741799820113052677363038461398206547514107871854645629573511776865766479899,10132388802463968927185535273034278687094388163001210029432141519239006715163,9843127774781963908073388692741045845788815542021009420639678295559452765837,3807159091255176851037359514650776155078897682364934585802230436085278410633,6904224411392552889784909729922790171388456358295280077234569059475136886573,13434461271014860123956911179522881298853645897065359788401689426904150525428,12249944872255100022137726834287337969948262832177273992983186014370317983705,1080721436007830510323005297307130991703868335217850548555329006531295547187,20651452101643029862567543402727347872461377965899451538964773059299839803923,8902465483627533643127758766065785114055357770410218037441501029224645377694,17049203022284218301986830675304595858941437294636126244507847280421482250090,20389632733862984292955678575857173748595770609738193230360968914580393387194,2628553647311400613862969480533814764766703257834731382409245421165389763845,7113709286888238485244587172405174762331565517345483851543315956528264191390,21099219272139712501072896978936944264265953306877942445724732180674664269749,6196322429352603190460567397253889100476004214002852031233332452859780069595,8042719870001485176157425681827371545772290235839006373715151688719449512739,9109639854367609940132679558323551490721386060080938849664245212200893608513,20820097690315610819796383305043844702226083970185755192990081897048903995104,12474580713368057036057537615251118300654026141156267907684197425413737128906,4935701571378317615941939703137616736056472417588666676180454398865436202845,11284674041151323919882446027842742890041719161934493530658741778909469887490,10784274648620717180750449830334448050402020683452763192417352842268830091773,7221763500960709043106304906102942899855402476011030187016839441411503790134,21488573117797078819915291564603086854092528370673732237937703606783710747214,10368071846917543663295415889847910771342838450725996382692227125006143332582,7189971404170280285101021558651838178138415948558212834138150417852815291774,3622212247952623996680563730554546964978269732772060499110124228651174919309,4030261128316895271453652515658449745835613736325708089700420629607904984695,17917906020983172293093657775725231153822157764639429745264576611859524349990,7911943088433991265213669750138013059877768768674246542956611065207230165349,1237568201834766592374215633649772138875843120827112365624718270590862573855,3421335729151995408099494011827853754192179969298834320585486465552812589072,3983646153441614758977318714985842223356917025653336289250912061318144657309,11832501153279122995870584183546009144756312133876131903016034834496067810803,9642188977879773189558548598547584337663289943484049782260608599281971392829,17650631071515565052542834438104124084088724345481542312112093611903334892790,11727835841766435406263157822186528758001431234638936084294421464770985535272,4170985922866379778894675975982515174956777531610306941710536931798155932713,1904373901352853963433078121273558128713374926256562753718137883724136086536,20310106358538316988108567646970248789216107374650929380709349367764652307148,10755444294914746017826019531774644079659674520334374055753829758342372728308,21544150011748410796331015950886967191957797301800349750025078804307553228922,4791178272915634809747385261951447492552726497734131770971381971399880792451,21569911489317541997628510847711750299218484102264583013015022430206018097370,469129421958624587885163292532024178451414238938436764179429972880411747423,17178941568791193515971789991206572943108926053917999875254005411851993177716,10061493654971891913017572469769124056153763544567322059270144080123216592759,20809728888234709563099636671010468945654173909532666727272823672496239666493,13977154471274089663104412732631175732414148541501676926172952880637640768097,17159586220373273602393948660742324700378108883620196368910126875831365156676,4073500643742253412297370658761396932893392648826435730598979045413705716932,11493572320701213886088466735117685416116051720844612287863434228749232164029,20892362924238047571943713393658663337479326222564740924788211586758905169271,11301788649359616808987952401363629750830090004562424782094282760076674679757,5346827191385082048034578496490044229132766705726383391388695220005635473547,2201675309086116923924279562154152714268152257293936509978158351509848697027,17917826577478806664624583743441880347892085028222113450954395295616044284297,16998236939959525187887324821682683276592762127156629849525502305788028877451,4214391906402965555572230230924694640705243512659675242003943183722900957472,2247036556360539125313249919915213027481437766291950011195105972974928736865,9520057428546863347057860284023378728609842187323632161028631359500291204227,1828736612590741052604266070553266072363175828159047049110641125134408628099,18248580838532636162005188449054546706775958322552749296747411333541139803294,4834174634635006984667037697276171446677972706028785635301769650621697899268,489734793278913821067993383657373029590536750171301785048262915525334613888,20786356799510136039282916235428434827695977220581899018592633397684279594261,13145806261364716646031477788186247592609087183869974953048604633861380872823,3841420600164259772367211721293848988818647274121301867288590071853319905062,6882597113948243507685423253840830929482565588666222909972451758645869849656,18980943240416553858613600850285792319483905785062366023956546569017873987439,29028675420319059649770139934414847448931804950673695214332234580922091102,21775882073646833834016763184296217506960385126491507726769771477412306185790,21300410381086030882514625793664995316371660662503398686828472860934288345599,2472267536757789817746114566761390885333410401690592727164834695142144448445,9723880451630142367622302246353057781908243406397604481250639516011253801606,15313110769360181254868962440810453125247644871877064008660684649744823174300,20564192458187565149788272882595180521577855436987831222746293278781628416968,14590472970343049442795311527863765295112518097070620865372037933484660359574,17062841617700893799013325463153088719125540677385032193714935878731444635251,20200256413643364477818739581045874029732018697196252518589192345293202187361,4016942840923529049014357120480338974430876995693135820048221911362323816443,6537662900592412058939229458410964809681215707806173558553209350444735100542,18297886978176179234700005359672839811634650525194200352748308964228483504767,19662609243585750899960608765774063353658909677643282385185291970742157305960,10221731387204953046960523786878755517637874808703460048675288088446619398011,6359039963669314770815970957437041104980907769543152198211817790059980604175,12215821248736109157702052060566873526833550744650237478543432061962195037956,5935095671961849761918916493742868190941272209470285856382557274883130995501,4892952774759542491697203073862387895082272084344610213076129801679488176656,21229502683877666320987735203037721130704543292725579308736529207275811435612,17138707315635877064706472595294259087755028865414511496916808945331553578413,3064016632497858706665392042657089766401657752838410773325693629079632182414,10697546089228176531454125219656376659283555269092429548580998097316823780605,6383154332658396326745467904696030415502846256075951666613157084114882351628,15399057406934719483674477103950525850935787593222687850952111073065008222381,14222385230562109850723354194041721683341002968759594278414075630295191868997,4196055868873306164684774878036056827685013979028843775890547079994909550345,16495894724764636941708778916623546529990869478284583127943604032121307478877,16662872698072302151631604897467020278898785941962087730337008570271651661242,11474333637424192324648146148268767361869344542358721131204304533867910403346,12663733223747936066515430496850730759882234287115648507227477484368789774494,3278587449214209390499027872507714198695688159471276082957385919697290643338,19852281910336140665278848076045642033038867843956224684297984081107396007913,18119827693896204780441288678080897397841525584683046254519435612134656396725,3004914531848687259880590983112983929408762744461212501319599913078181196369,2744805266681634195002030539778050424843533661368265264531107280758966836574,12003425394929552979405575446174684244823087440054609540505332749485291543559,20899617298205776433505248799032591564097087832964850292073852661486959326400,18977355049070793830198782732221581680757588074059967640900502934882545605494,7774492678097446887356009465076901979542998304721485056654902284935411555748,6257979871454846095389581530427518297635929206624687597975380788548536091169,4200362970271656646831473686822497724241729322168501270846014047124987169639,9626555465339955137152373316361342798468143010897667050837558740100066479490,20599104767749131194316802432182162807569082153791773541255180345102031538229,263120164166236772856966508954885356163375871249262527569221312470198863328,14408635566922092915650756800314844499933046455992065014832556500390343919586,5183079049039149593555827045385122348972389627856098826226304101776790536649,9079663711634286747144802677527389482368428094888913737002695282424348199029,1730279784246934965982679327290069428428752739692892522465325889599043152257,19417355737429211343570897838176489391485942830255040228180844510907794134979,4688867852231614618639054238240140493597889866886829462162366294959927124611,9750344066229503722317800976404611879233170071789439067052923419204148303262,3998708829439769920633774213209304480109842139515896658207686741134489049438,21119879197425450902002580651023270363969638681856902851675391960298938692105,21081985423839377197813891376664505429739140831959287968556239547809632016084,2194830658993798006279037291585161216930179214066933009151541946587699367176,10072059773309529038163761158232080490764157196414798621723969165341603556957,12893922413945288356816723514764026149994443040839144958812668568890693761688,6289043885924508250801248626630354568142964747989700154772682955247795752635,7117847768519054206399668810694592559179837439189798231517777441723405148708,12250493458894268361669347775761796626700321541112455611623342396141245275173,7536889841233679602786965527644616779647633163370923759512908958092882343888,13743804807205248364239225685151790362682679734025326476864976250180416573459,15326756679387284645144696476114707028416084124671428061976908306742987298792,14138908940825881278249529554167499601250081601885817719517135886992016259170,18191604052705446018115707722428677617894390137039905732841218263472908863798,5747208788515494994202809520653945260017053266507158973974399964661798663161,16272405226087543462175411026937377018988783482980328154498443115982159189635,14959941590764331840350995267307957753388831891977493365286637018137237442649,17614662493206460042788564726025968337855721129414467376860164849857118120897,20540842142176422103053529661013282478418611089363263097515168740633056607687,3290501693077219671357645003459548779173001871326499393140572778475444534834,6447714071113870576284977914086213514251182728059734289291667058468678194763,10016099876948482641338204267737928588893338645093292975971465694121948536197,14390773887169232315205787249570222449199544947506512428178148864937891297988,14620241431433245619096116183667070956408821753296293274413828291589840475809,8494548643236049061832844399476487754775580533076308093638832054930352314493,13769276515160804060029880354652109198182914994347382081537158871751993099394,12260040442111865637116150785319893997124694704607680451569915655443058209529,18536763786390498498949547812325024712812297365266616445712766917775521176399,17646030323097974380890038898728697538005884509434748880882937861292172824089,20995211004588227271383296369921345208592928705280945008379701434887289620654,14012493030585128283500948776342859322003214361666347021120271800114480256613,13455652757462524273399933538052579123871086976307529744949349716824204294368,13176577891048443118691856747592745460758840755040242121263455031909886205386,10958007047406016650282891454669527247751542376915102729040783130554758505696,2403556896710211170900277969533691258363807287618829314859189083914528732150,21557822641920534343252006226462178185422073111762808253392360322675121740589,21301363144372514699996437466711759383396133417588035206347144265914876911832,21504297452761836117267872934293380498824936327520529664563583098264179167892,19008511347839951812168011659083529710470044770506456216838511009924048532294,20729557973386382250734811255901369475271445538588448251951105355722497057092,1596029835560146984478838415844959546370291207350745477127036146832708172428,18779043981021734310054761701946195503647990042042517453246401248591799960006,18389072889502391007861938373344479996746585336278814994866091596798460590651,11450018471721248431523978933304902015421867719856001119788032399031643640503,4695792303828705800181239521907223047109864872167868532243675764473118182293,7504424077032992561542388084424474665707766373549642837850671808747703476058,16201871852003230376980125294909568327837373609180822015372468013683148626476,9820880186139182810240320436271674897142093850866141441610372427566550592116,4474392152763162487463052318741100507628836016813487468299920576199966718180,6535313881166679884076402867701793095581869448631792643683900609540448349145,10375499075088306448884735241746141379659872937880333028048697275256343984198,3166175670215426596895103003450519990743126408554698027893417949729089445829,11825805020940873618060190367149910908253947573120883350031415196553790678909,15868728010683147011542066925511350470588043768845023267900379312401595633901,439641324715765398013368707995400811722128832670521930633684822154134655293,21389215620992100898484688007707226862245610434491939970737280409708735004882,13567457078921654178980424734811793190031829390199528822285370655562819201102,2491418221701715606532424215068729097730197896717397364135214058133617329024,2700199371443700220147927924846092239465972046042951758397024540313204379477,11101155530024798073181197117436499601132355735889219480985438157046671552075,7696323106369972761130328211405739772776004396041557644397285018363028133006,11874928928175576980576459276992229552831994515252269310033260164062026645644,240537705962136501448280118114493602675578232672944677099273394877211057455,2336277667844723086566433195865965121270861932965343039992167442067222380338,7139477698789264606031986148297940201890262913499702250627665080791275501502,5394022087396393768813205254315732819042275688988698297882925332496064046016,19793961339963600744392705441271116638543292070344579052218623579091649097618,15692138411890707768379631022903362931511371639119812810678572491600193150934,17870790093336984580535630746458834581867280473989239593391879854453602020534,8527221939827993709561548898140031570873635681631994323216682386420609693119,20583146985132338324328431878826670751588212915037908674977314222878838415115,18286401926708183610455794878977380145855167386311409319243563628128439897199,14883280595953108786791995875596640384464375470758397510182264364463199426941,15622372954112461900770387091989505548249197707826335911691325586886540655839,15015231518950399896087228957162542423583966819051318376374846686122344072726,4110275540712809298667287978052760900153083659165519222137609468305797552622,12194886690835058962976784720918154631659193272765999855977381550575603733993,15244557029932516875079143618219344257744782264536288508363832394149847400408,10234512862511661102613686672198745648772485307900923622631623670310818907316,11002446381083289255418443918954072583200871532274996806630154250111947858951,8253167315431388215871891033564848144784018068378784924459677347009078928353,12052362697319720881876615803891693831545089601220691511658506577522506606138,4222271910532283822428121153000170791277438320812055898378713943538215316712,5653799018158152396708984453701593562269544320974176828284977837083044089432,7882074107401771620456811688079120160013843021919844939348749959599330360070,16985024708206545567858733579435707605892308141313442111649869690900835499686,15657638292217617224447239244820122003415140104485558954475025681733455080516,5031435167133277726502623124488830505559857356049078624241295172338778604459,18251569826624635398451261785711619709466995337593606694180128347754947431611,13347210735949290753346060121453479592654490759925951960015474767685667320469,15097256163521186466089214691748103981791931847659339134237546471578704117651,18618539001972002803104792202843684224999903989910895364254642809781793542910,3535158924054577294148391849345768098132565619653646126038220164469413178376,5247111262643738028940705230194040190316748748116050300897903801701767549935,21069968641157288335927634486731267978865294883466175079455493856177243522705,15182016439888624540835624880056168611406902880254574867923247894452951108191,2598270152918575231168351721309733272482825217008498067779287914396446525010,5113774671804063464274403166444533180735260894306271253672198506848528131887,10007988864825946871589264454040608387449058007032979960058775715911078006740,6905160188004006948460048193173293195325586959399957154757620552653693466890,11995759573081381716106152146833656576924747390008060686555489446745383610128,3012863557306381401755965576258357584550751416148424411503270543269480674925,2913988303571063477501511529375194010078206270482236339308347176586704669764,5006524049092266462685266534385319119401827059140718482624293936686566174021,17563183357860154367150870160675168713982368687948283812578969167511639823963,17837755859790999437375156561325979429838685660428780384415700354505074279205,16080522246080742261793784524730583623229678427635608200910206239897175583035,2848708361765680705684254800195178864363439998055587286174501633177530616249,1557519954300916467422364113319270366979873515036760226798787393508368098341,11733665678441137100700293713589760125678167060800184611962879142675741739407,16521409005131685666434785453319000098069672876632224692360259274386316622759,18967967647390654785643258265157841586213408055603172849772769208320302959605,17571504476351312669488808692966809815779784230239825235217863108338926113527,1033277958139146991725614151292577955914352533347610456481561709576150765927,14781931979382308373625511201561097203707487976646566051328122813686985362864,4650875909473177450881505980066567106490273485086660264292847695230525365004,2914409799137239617504079923731151032417003482030433682771204258557926592318,1569377349856381614777306232175508373904011237210172681516586308749045834576,6819560317780627274403497421141083285449699366697573487561555149873327611188,16783037329427380826125478934695948949747971672927005004484739677562779828896,7015004192682971326660995855922915203604605225985220083215349611396572003775,4630816304408133216263172876471813378546980993666459834637527842126471866675,1048974869579541183196305195192354335945589066090693848404581740062134729282,18688715639285068183434963296396143793423259729912639999344372787920282768249,10934347243740746938446533383348729597078488045109074394137337392516949956248,6293725896350451546716316494602770048720703017891567394397586512386125658192,9703640866977553131835948007053717693480506246962404280815291341798629276781,7906707563931146558411066527524578790489630019846849753651156405406896838827,9702629288736663637774512920196886201521548938988112829178357919548773380071,11496918342981223624025423866080407628491859149911166113194854209867880853781,5310797284993667039758118840812749372556974855379167283523727209282978379416,4023078794142040206433592504682005395486039156676105856122688431286266944198,16871217006715623479558921653467262427043486550696934636603562460293483965032,11838323559167998464544738415089027103939009770214130070107400686110312526340,4980088349530490327691411848559646523716982917225546360214229685978505879808,9559603819596004088164413773616676054644268005451072511817132718244048934414,16706530320004737946238925506482163802145108867695620161891008305110107710231,17097818114876900788313405299390647115420321455669519337216918484593668351660,5849414403812965413267782406018277549067364089813096482998057955032613458546,15554882868930267918822925407791760045541474181510040631764755534058258253399,21580870201101672999738147681605702976639626554191473007622680366607482413326,6529597247071863795966038055163209598757897174702699285551712764342047434265,1034354038040835970585668649926410980243448725331655567931872752141342573332,6310767810288764607994771877877727315289627303796831154815613377794983946591,996939452759173758835198197713244238928300388619776170462989538225909183250,17830180799634516986244195887614846195714707335284590299432596686170229130983,19874559606908304758854510017033500134646556009065042866233430268619254302205,14009373839533951923879302153319163529100920268844053529575065501607218593395,14946211767155341356149843492542554767905660369447051530372801216288515919491,20201956319173972615406549564337979402376802300388863728690331165140287483581,10535506466358617363674252301599248223977286129433846317382254624662176433824,11029001794792043521930346330104687908171223556219538577009137251048931299365,8200934006947443074514571335915268415570710146769685554653690866413931711817,3756001813899409241012385101881052052933218317388650253688371184478299762463,18636887900618256435910622299263466888026971253061227337296887637280237818897,12062360063539460494176603336727957703003697981349882838776879968409682697224,11001722900962847730169711618381123657713397243841075174948041047383605406084,1100165499084337642558411348439001505815886538759724357694738775770474410180,17434145857282894864497601363005649089714522250566258141982190265575138829458,7528570688175530782083445771420581373161584322581902670613058236780353068011,19971690728399713343613282829324748110469462189895719072018362834001408037396,2720175852023799717892872520519566779572526301065275372226989199715421627391,14943825869290446747104357486851686014418770156528443888330443464181536442315,463946552619089332690398123288326517388219753658554785664250177816814153004,17828919314250532241077886046465359044175524922026640483099339343132288207680,17254663393643639301497528160788050107293708210389962463123967310041334977099,10548323428945380231342461328951126333180031707800802905121494905097297919778,15741600332199859123106892774234668638862408966232099592590755994226268019056,1447099980864195663747093395834509033779875532198378629216846242387465017398,5634271615965881595424665300014723762842669209816714518648909648355913896267,8004046094319510531556517659927356739393971820240935140962728964910152787977,20150098853172404856553856601505464455083744410516166414862502865711843962616,6051577504932496971373107947431966202921763803799244564057047344716078611429,11153752935200730615392163240542716924397740666674490478903681768299619893440,574571428841330767683871500343913695389489991910772848795148223306401258112,6644002840867033629815195671865575216742798076650013015371202918478434067981,10643887442409207306340562760946079189746204276290341516975302787467861819914,3310054989122793204488875713765468888781168322357480727671652094037000591815,14260109332138908810733885305730437910719800845345795697882239548319688811219,5210296637174697538908079595920299077484266890923778247313974722933789990659,12099525392201549319291916254076192583959301537918452056524775934199172994864,7553233508370030852973625898622143795815488816458055012305692281375143855601,338064484385145371035100049761904487152067475286477053744625247222287881704,21656711030424471443690125986754350631269722127039355499852011488517394872248,21372195548620232488593781254533859082570347959319967220919951808088029020212,6382011083971938503792804272844009960813722135917547320595901431805157825428,10487620314920598491955634712479265679552728563160570833716083687459951803271,12540875281457292616015016392478978686561298989814479837942710114246256185916,18617705893970874028060182711496372099359212095272496239846702650061090540602,18861927157583050522649066858336628481061253205783797036256319572504841854227,697040343546965749510304464460790931385381610135802696124987191773265224046,19957864832901242629222592391639674066674531543245225621817890196632976954948,18958366438463449522535881612753516577920408884030961917206372848340856779454,19038355323356709854907634385093529445778219247035572752290295596750121939785,1288546653652611126768551729241141142059005744057588910355805731786584613343,4046804685697550720337256987447438366138088525717758741922811410001913306096,1660762585827970516291367008365082875857712512262252287267067642443918638514,12490758580574114271593656499165833022285695011717771020275535753216014465968,16141486882419673588223773309048616384177430148674560859754337286781225436609,17480842754700647574286106752058337138867662945102069039800534716529718409113,15604353321749597155917847886619012355001132908396771273202434684314342259150,5617279871415371338336939332259796482400498338204339205308393954394249833452,15174696383871305992552314836076160250704499338484600692522408887766438439385,7427777880578061171924488290292477545896473049748950597878341286830693333925,14092813309756880555589883560674882809640120093304366339387019683168400944554,14371461943490927493590660203698012938705485668960202862586478499151043526062,15747628341829994869775701388730275581025993393892718204096081193836534027616,13069485962326240936812384345060376352182714448869348207061583108709995536141,12897613411832214271030930629934621444235734267985429117525716946550585934838,21009316561423875807053156778128985534726230082102006144117574738389765473006,1961079851137768143186691785724923358396590015729408078834852546188718166268,7449716401041984694438903080808992521397429308993548549788139074686598693961,541840132011603695915673487977337384196812668637554519620724199330714724824,8732237210312418481429872365007927003824155222103189850471564031658954501153,6523310024353124781137808005011914742907908537623530782692226224442022388987,21509127266455930277492767884139578463956043561699345583365079657386805307554,13989299184155011575724091657019750720502004610297338129834280607581254559697,13646882669283186383881254452527864262332184212165662411849024353857046450116,14437939637607347068422046603975325432039018873549816106341419990853530813605,12400256882351762977557053352624357859435580188305833994340851255855777961583,5318260629482404358266028277859623051836786599425915900288734688050650647740,1629695214770269012001751163254712973932233705878496747522731454404864982213,13712071936286520679632088394106925703538964875601961825262229735589116706613,16370398845138146853603171685418735096308178156853614168785529502102183447562,531316798023999736377588166858362632977098508125317800095882267717108741597,9318921203266238488822738977554047526587525733728386955697050423076330149397,270377449844572577022377874031006263208440602734811115345017690504339807539,9815014161182964374794581271513785279039355629218722105019385525592211310401,9645578731676628215511306357368922184828636697072609821617709363109131724528,8278125422456187544426337239756968442258418675393889722193805619331692372756,3793686014229600852890515574697744650225321239380634655110095131274614241795,11274706713173058310395599257524413726315092599580477329306442323879171602089,15700516289342200878818538157175110895267852686641088808116754074662814875793,14231470645515485158149500150154330504733538042275634884479799789708016096981,17009943350256143028237187628790018788978713833977098031809639804676372324573,11807744076512700514106955514318371416449053759940168158181473579522112561617,8941191247819458429052997300931331828693768320666304381154122720332624423159,20810756908118815132070882638097329621005628857845667418135716334205275433963,17633865705062992379853990460318358612898966723353031319355975229233791359833,20574714650596437874739546946725432737055645662464099228865520688481435554952,20753133214966494228304506683244546691191781338293295716113306511488052350935,20891917718961601440155839168193313007436009622881050810291426124657399756167,15254490709565398763344025189458873521593894682543200304507470388535826802423,1579686464441495454543935122179009252394402667945704420064352314351485765393,2776164910982632895181744444931014666522951510059312025217047160140701867676,18493452977704296940835401396385377366306134685072368153755232646737492155884,7466441893052199319529201615576158956429673118460829755667264030485444838721,4862779186474359727417788114204862127925883646628388801420770199523844825968,4332442906725686065471004321063349183397729160637280571390764069298441846158,6235595676847271156438843637266606946005787585155569320931268977334224113102,3283545972614629083851761609721595874215964445590540647737064482671122002155,20190238096841101806664255153033971438119127586536510897732203034569691981419,16218082928311959370464862694396129351602418127064911331498297863184968070057,18169106670538118432467974548733501686430842104311041161699612921427327878488,13082519725061669934177494520541983774227971959053999627907293338903728791646,17917738025521205167709067376626145668664963656058875474248539992479417821761,10201169720940960483107286532267011054369536208475708600788396458879352247717,10086018032281190838410153727159750412677882106214361975307419597102233105666,12682273581371325166244148831560984283003922721179649899812794401686084266959,21151848537444166847396763358911125604594195283585946282585966889014856464069,5870563280212708258714113395803290954804582727013499575940699343839714979459,15818574025355019546843656101475484151535156797083091329572001913076927497145,9172129818981348435701876676880219576808443896350696165457788920197063328446,10390962755465039363458687913467754632739357930439039623432597903165701965254,6161501669511652251380864592245214064026880951608726788784852344316145896868,5405539522259494292389572744962975583699928794990075330665720986459457361914,15953141686281883540154911071743713625324924225902448030996737734044456286469,21879157639189744211597108651045875700807085936267782759316146460177277605878,11434924404918060113007413962226874803102772070441693086168193464929290844877,20757082623598026102923542323531106955538082419998942072958829717667465557131,8919981096169474486495376362947226335482024821650926316923260800584787410595,4288509578096166644556335935101899777779885105511348520519380469688243082096,16046529059566280251436022453196743987059059184968007751447655603059461800273,11219038614950179129482943179862383597500934389713177845014944329948593838918,10043039951240572103842000677370211126438633625308559058041812947576435228523,13424594313385554045395046911081130962489696002268038176721598695954847052511,1211793291463193275930858215285948372240170625699602215748915241438580144093,13956919764638999174327326329058963982898576605238294264300483944344569472991,21763763972390992315030985535287866258485311664824948828240050483482084352503,10420983865433228040050251893025618324702726171912049836799135351770260802977,18753701818722627673883564699398410722354636353042388382508975546895568464372,3775364142286651074799331885877684616693199427012762917550076623916732710822,8292671711306889259828642403052383798091670542487370026886155070540857817510,12071789317828192902441324443833143078458416120447222512665882093850970086582,18221914904286916930821501101975619932383182494940702022220624561466550429056,1015894946220130503079847588005345557311861372219799708101258594371020452677,7497079366974677538814211796849030622236102734688468791057012961185250977217,10412524008150259624425778663311437889796006875864864836590446801100002463061,242804608586097049060214639927231617495599500538071474816862835383660136678,9327321863177171873474299501143270493456472132426279976071195256972553555122,20841963613720468677785103552893139903309688713322442693081971171914472255790,13630784939841089364059908940844732601072559390491244936534430865345773326547,20060990491599613171081634276027504616735657335613608029945430961773413795782,20369723769740268530808565104818084023349274297831884550854878783888535628782,15076862507709493588855118027827375721947856558107489434980647124128748591027,12996451838772518667606758612923003843581729895975567888341928977998771990237,4052235171895745508958823720790274122684550078188920081778152850440806616718,12335377703331511956642047444506386381049513479297082723690490432465187475758,19412573446052112260556809146936739541890274154067075795508039506436684757726,17815752693042999749244044082547565016456928313463444720511782669652296613554,15784264337580227630693723391508440881780776717973842946134335715743491257089,10667492170364941836778050228790234453197448653226319355770388144152747476935,211997855288770996034164566467801948520054169907247985981041869092209280055,4928982790134068590739975426823777812194464923471161503361037698280174981760,18608672135933853582317718913701178979379432491853388463545185599228146691207,2315480928424106999355320576364787114368100799067708928765166041722251581141,7132821772386644248930179957111951717051009389997169728630437453984113307524,11744909558588287567829975231377896922260739746243206347301263424478589809196,21821616737585515642213483301817094657757210129023396850436714925413476278715,11972412756334108055648790188313869962577071423570734765254546184728606861831,9898102092275580917130558353359107455579856499298488646821411779664420246304,9958879822047499292094876401302022972082946727826778952858218178060652972948,19871205375909775929744751330720905649873502681808501037344623586575605895174,16601345490108570384179778033128731955939874176242885190845545230306090545377,3600818319871189164836691793538369796689767756596935154198009735998848369707,20314694248383769870802453966233555256007670655653781360971318867730452026627,13418958906290175260633447769067612135267907574578622587604011162488451092514,14459952906281539694149485094281623760953141057796841403669604773900469687889,19448408956408494949564099234438127422205398424291589853947309097810118078185,7825443276535418239837092010081563810404777554695462770138005656816269166303,8463248112790565810949249352339633764856217758597371912588298951088604363676,9397106702637851943166369067733828452382029530464971824017078972309585633364,15452595095505449307828854722016355425252678164966267614739918073395150429984,10382687268437366227597120935808669117993505555024110738918156422833458968254,8525129123003317464420034009755418250374332671627293582800681623438541074422,2209915653341740331756848895690532824379055156318218590971248250386542567791,15183382625497370680223757887016738067273663916736248647060220264288252640054,5914882314939376011130904692287520473675802288813732481565058295269249787489,10737923811176739642308957871008944847331638141618843900584295941869359201136,1019349115878726003171044582547108836234898959299710235354611802499665438533,17364570285151724843778637821645803441762402239038594475632207111794332738860,1251558044831543718478805412133062543617572066062707552512150093969983011815,7568361578986094203490921683991770751640726490619033852251843934473195496119,15439738350303496845805351814211602783597897988159829928947802101119983398961,20009975853963282344191402380547695759759731502702993682892413834957351648692,2363424283223098643833999734510060612126929924822351279904900380971757668501,17136028473467909987260660923882066072229277631411461261810169503965426571985,21423452231832054119549543703585288464249234898851841557254723364015587266501,6300803647873111234660196693510491620063330061194984556803532776163457642510,2749674757601823156522337416483425720076662114029481936093706226193678544468,16123152544885237760040277581510833657110306240025009956733742940484347179299,1449335556475943566914615807167633374850907490355989852917815325720800540092,18225835808858885369557291110939124591374272404427656191824524491194015802997,10406157408365973197865488683230737937923502029339842530701446718978570586144,17998633938868470446795829948946241208954439598754402047898587965138352946507,17256506181869579387781206921456178119308959078547323103229058358574594315926,13094455817799190250176997937777121524540082751332502303810836528817463694222,773415265947842731444676861730775210907581945844672294668103420848288364110,19038336321288882240456993528476377501756672900320404015643432684581055112943,14760627809381104024315295117982862934682028410719221222838112174132134785643,2299176916578536045959722453832883315456156391111537255429863337814706171473,3669114713225196659381574151653298340387887549947282054635076450967251116153,18251972251689708305163349578105700140002711019536040700377516042131395885101,2208114007582253724814286240939815507122998650551224166265438176279104064289,5311319465851004438404228350963430011209528099234009157573275300632566893387,17704997085718018561575909495530243398580104458533121202802306468962737491818,1933762715500501610210207583856164878867609341004969983518458273086102828809,6386814998566871009542498039659511536698234159072885405476628256992102020495,18831772844239784973934592955595859276748324649808851586824036127112826604451,13462121128312374635146040270944207295588795209645130037644415451121036635451,19731805313375129918425060059406339849106971447864245585064948352741000760923,21643500371506858849424889544041572150599889621082729284012490052076449459481,138548710091390954908010216339657754049773930079521223071410504190290814535,6947102089761831011730597399319184690211329034898095828464106850135090631740,12831053427863630744244436108113801672008361468343188269856032816742671083134,4223577351003454708551493531516184634014386163092922955496011474432781253241,2714897164693927923639587351413494956248140707486375397510165870974510685388,20023038420823827383850598062203899779139064378489163672445486337197649825217,1767883277856872395041944981599210930967554162796692711247113543638244036456,11374943081906439317741616342767018365183355349301791743927619930324701508426,11803403776542021481872407152864894420411711895295228328072919482156044458427,10466014303238336135169608931533160584648879880459007777160264124745826740750,20569672017414729176046551969057922112780177375685900568749563089152585958033,17872595105302125548629012813042403567513885359499964690907253660570968601519,10903006438854654900289559455490687959429486945748385817337220540948365309048,18275515870643256842855966776500808668842291767076613550498342673701067299432,630933085628668840611776843471079145620019967645658920379584401715066362709,6825394902701793105668667323441283311921241346208501522910007054667207868452,6858750193485140252798450603380083764362623733369268015553477107387074944232,1478873465931112194691102753288035258894560238829532399713218315372158028033,20647986868364738274961741160207964168903320676158610371768611791255451415798,4340383424522509172928608655219336498337132315044301147894720301443278858359,15694054630954602584443160345828698433451692126398102396637062194669728150097,16587614091042345417694939817299154667821001841573634480871399767976428325370,6780948432583055051074963887359666213579607675322530873343441117551279310337,881888803549941181636901791599886290841557130000792317917044641982716656024,8375540908772391314073560695793592104950470672337969483097880419747173630602,10968989437172024632405943909737990264150382688586767944077705368389009715036,18851349698000339475263334762001556036662188445499369323276947028195614775701,17424154833179596191247217224032955577230090491464139783174467885567507995873,3084264395291045886600299855227253813661906050535885634611163481700929635296,9780424450121954867052166726264263906169948113675811543750657338499901472300,14927658638057710246989480138441311677749528914441518171301964877558977872737,9409069466927713011440733713350127030613235827582038407437204556786573082426,21532551006723685558182869738272976023905972040234419867623013049768952103538,5167833995989484123952079378988963389989994865716472465476503880641449880786,14740174761652743774118447006447618386992142680472177663315668117221175944698,10520805511348878943408706501985230943081177040800761729569633389778724896451,8700454790689589285537042584692084777365997167238651880195034227220137266589,2733945906594382609383183532639154621092632308934603150907320167864486314840,10291836929398020145429078280830166142519086643388813863997726059451399134380,1964652348248051415524467307507959105507630568171154193714989224874728277054,2594310934406347332341406086415178782930670052092905736460388995932291385927,14842121917468246033091527680370186171895171052114757236254597861059412933851,10375528532253513340592396399825408524430850232835146379883683152448199357827,12477762696438196028925893395417443678494787519078936487705085579706421333630,18021944163681185812898833787149788656465569272261580921039580457574363675422,14971348947199715425743490776577354350250241776207063239247262831298628671824,18527079575564336560853661036281436413609153640671180843997315618816477020062,10112969341623453459297605360048147871962444397321717541108011492952113746933,9306811905619197449152929816385830205919355838468334319731910917748600490999,3201856562784023690028197460260731000729676130502544364740684445045551547485,17677019524999624366971265277439539545709248668323859450511125252478150097491,13203760042423946863820551582066224159089369605713946028771025792976332967017,8225744798383097681411492868795146058284602972120901801159373206820642535790,1133207841388716114249120311196903646181388009397557241156806164775023041371,15623890151225925383841140893652872349082273871391477651993101123938000801867,21454879142557364834852736051259149378158105754952971451715419987896242909650,8531552648559366596105198828222595210930697829968414405502802286874489507133,9401758966490949657386555283103887925392012048184105735334446423864991206786,14182985100305261645378993603110572106752819147111838091043200594637885017186,3351125971378624693919014331249933776013465831551789721255791740304274394936,19684429419661111328145464896944065690801463972795522382446603218587092452167,10925858543362322055288327267322188904474484027644138316216578205314218206492,638388255012974167128675944413974318871770367985490338348509002020449680093,14959175299535994556786536841655834078592404933909341983568127492171858384391,4565657688930940961208733539150773567906556683309024875952853834684480507269,18262745015163208046754959923695809473174547423960055443621926543956602209348,20270410959376379064306739018970053272238947330997122046760265674383899359657,15290563044070434983378131412705775525253143318870138946525234035666015420725,584590168302279667271049654248756511695470228213252786062709717390671267095,4966088591187905712289854426727671159168968384675952400787560742388879645568,3319669368740731092651343449167365623382886973437878280133897523197651190312,9912174158284239213664392208740702249961859675813287499135373479592639861287,8516379350240514281945243250529128948244709428452350892659587420308554264613,2460558416671744640916958595519740745483455366236568201673238589517657340142,15249503582713331075672114681569135202331428122201669911203912573537116149514,5355701614078955989983290080356684040651137096346994307217952640790301753843,7986859541259474766804707773691600248831464381736783455743764933501866864285,20896597282789039779549640920767060676459830701472255011776479759676387046352,21156365340242937197411344791352838273101399835862399143303393482855843470763,8810320994466343375413166155559061722877903255339567630911647558329186883195,13305939854322882862383989397499916187143744662574072474260034250574401506438,14276510595076120373993498057833260625756300056428067994615344507361982835166,20071507901284477038407301846126798169150113895071357904039436046848822333309,8183811379732619835362931863732297053435925338898156873268534636771405892075,13219046823251102005239988390708288792968718105445890139009709283489860275155,9185773756453985715582986632685488321665392756676197265712130071752773976631,20421943269702844355893550089604182682047061852707721138511917444304707579860,12300280142885224975710767798713824153348765684179955650717019029210821361254,12007970010282235734724332615090869243055192449773846575955902036212263482679,6158352771477574748962005695592225162907260568470401385862937675095774244006,9907046449530603675289866399335586386847026415848055552734816021036571412645,20848733914096475328182569300389604774285326414256566622667108340302595094373,8365137332145458646854804122757179721555979085847877907343540983873210953635,5631007860876051233682685206319236038053360910127434722172168921859697775602,7724822014604490732390628840430579796440157358556500058829335597037618014759,369071834493409594945180455653375424679250473615867182702388739879310444614,16769246200562822457100153851476834038704115916651426939703296994708244449575,5761928395342052380070450997738075595651684639539927184355295101970822313162,5566206280191314323446398313438814776510866532854163164867370641136219947308,3342359366346342054674985507754083252076489241172458810297886110396010701777,20961070283557581225918432539907379409525514793918155863543775859703676727621,20556180232726542574747935614764094533414324377887922356987347326584809231233,15941149549798383978046697670090370142285790712496734802869937995562571324293,14600396724469636128403441949598983100001916970624980610808650856082650218424,8853454033412621833577484167285435511890615294361962242058729914818351640066,7796912448927288083851300561583091259511345752250157116939318925851741489961,3163019852372632897541834965385695185434873283151315355155397996458747882742,14952700133737822394693717249052150819987738575989807253015506109171868391432,18525964798774229541041472797217632579102334608286281048443267822115517194616,7102118124262431444884005767970969670970778150875473949502505015348122457394,14204638357887780388176917062053732214797428898508168337150295424689096270757,3277315675050465719399614805088484534242274431436504827247668714966713345731,8238377613232984055051747513217839877952472190522754887201501162730400770486,10224258402104106587652987351104010753816241645110952300303846844538654914570,15487805061491340966964538995368847025698196465175525562567846982560655044359,19219815971577427671261496058630992677146093954055100897228392314454716131964,20451783587558695494081025729566916635107391693056303514267562508131052495026,10604908883794901754591456082090038158328418399338332217230293938008589705164,12629655676673767414687101606277783347408094199429831144029123923860076780652,13709603387456116061265164612378749494975357559995793114409724336723134851988,12280342248736515373215500158719410978133041790040105888782814256839967443115,7016009627584978047738165231314996484413117067952510110423917440240605830479,1524894728322552104763656617099911162075578893415210522528939966083567287381,16110348090073067974052480411460325713852194746966461188536450049907379558864,15849314408692105099989833438461121938666945258532089314493985018340786241149,14526266680576776847324515988959661063035583100946967808594725417429124130409,12662059588246809623132277946460950856148161126345911747740066547195150214304,21784234245035153912497219470830935288918016717870099869682681847939205742526,9781991278293660355311618579950123622358901576863101735826839255817708999571,9734447579561113294373127302234593360683756540510409616709038385517649565283,15783703381085552443769424496547949342637297192593569766965137630433735196499,16818302710679242439066482280541233367708597536159643998239357880909455304,17208557330797764065799659085570688998141169399652780006230425322841317471944,68706297573456724111634550544331343558310761429949721000334906561427561646,5166796490382346553866700788131214421083284131608596259217301814881739273429,20336383765590527388425300334919391504612546166109544795528892908246473855987,3743358254907302851720282727384172290999978135762491123193685721554867920482,84015356866358900057683156333277329434974724445531256660202285630028495424,13076432415761967873214874574212608989827734997835707946240987502102677974919,674004304490160746369333425685153534516797008922146231179438460150958899661,18008401489523347421324064960257465802035658427821867761642737239891301877084,9230814159278735889507853746171683425354655931537527400639327580576056029011,2338224170787780983513724541155899891770286010849997183556172649088034621522,13774730216408957127941425099141817093498762972537953648152397183615811260761,2008226192472961561861571910859568903805945585734651871281309234451941696550,18191659524918356873059208424871952262892246019889299985115112751645849510652,9977051090514243658919274826700877766433577306278237326432737577914469740819,1382241145032463690710185532538145321402596788581319285825708537098818318411,19630880072807438067933226715597469053645950344003618599545076855182567392314,13804532717560570932337083609013921209558901545207945868049344755900793666387,19508550180350246129831873366824988420065599516069494466305637280501827380920,2848475116255698304240592397534148356674367429794174368229897070816851620326,12588734179864636951823212209185103123565413699799377322920024420368718083095,2232868200526350302935711180734463487873472319399673090914563494365441045552,21377055866142483679502571618984666212079397034684178104676086894866487789275,4635961124592421709613730717934803195170398911827834468836156717082833802089,4795610144270291375198683497266358163517248476702360287932565598454128564576,19878139464835077446055142241229890663517120197298970825225586650258704320634,9323502139000335770056400844753650839571196769328639117682123746249546059680,21112416038547244178847876677595343035216538411439215223028113590182490455841,12697374728966756322005607409702182672422756890620656219302331428706184232671,9995295835719608174333254715476035051015528223152237761898234348962139965339,19838681448410021391386343877373049070883481927354420971134124213644615857262,13348946731323604604321164467837298053616765723820806627202376009331748334141,14459243825598700354634855807582241585214330632597159841271530816381999251613,16398077966528830249699687699527475156225434078425955606570595942126461545256,7643106356234289086355359290357087474077139338168525601611444369470624871398,20959675452873599571224578970521717955557909237727928302612036851445583012450,4540025033646420810215611052662284909609074316113304153198697292213556037365,12027414908456226247222654846878068961735365399441671468269489072556154853636,1619579475293093356383780863588610629947769633032102520272612883476001600909,8181934427490631780501305508522146234029250148182651874753791841738732508561,15274797459753339681175428319112732573480605162611546476487133996977708752899,5881626303176748491435260832560365957494745248996859086310569735454431253109,3420994635070209394832291125346590627475632172750870826118213841463585026009,3253514739572615120245273590897551489662089732892213994698961442123844511104,20203053841592538933587679570153207252397020205630948336602455897993666135475,11921266577552501086897102705390311185747062744461377484820893183533643304437,13241907169609567850145071795854997578682645559619300976538988140768348089882,6151712987809690919701305472528460675037031217153195032569932714294427052374,12205705969228027397734509241211850240154931572324813086389133244191540704608,12945812038464520921512101569088203002779738300982254987224395885526111963420,11566504805689497712142963920462066842262053081516919575350242192944407040992,15723543550582708278977667347083710027075971342576647975064035406870923269719,7860258127934035634020846943939055662221372673596335233171159964609391837625,15528468237941422862373023290041270186925402725739650209357342065347651170444,11352800656251355849609307793804420136337526597168059373534052608892527331301,17897134085314321992998873273654112498897006369781950634488633467466113054350,17437455229098036757167276638155356442563492876806914963325540308515770959304,14997752382200324825750631040991638912810425809039371028733815341246302297900,14919207184372260640968465889336548904504385718633186760383678178843526009885,11844428225775333775773424762116332026943738109456526441415077427972318646084,15239467296659614730514306837963031027890655569818408146133916080687077630265,20117441496592956911595459290983302272515832294843762087476380541606326158806,11211331365407064571488620323378276965399956667340240900293979889578003659573,8791311092499361250396136430755948222248236194668427353488891370543849807047,1774021261549926243219732938834617869058292002083739109596586460663663531688,2787995130097988538722853640105055460288688373288517482894772682647739193296,14036419256752421574134832204020173449399727322774622383219518631065684283606,2503905040784637175494196915035325275253506707537902487189138102884611289404,21664450508754049721193573452150382260579289185348178882539067755355712577906,18957082022313129842427206117755534129197834418112547991189485282634468396440,16781909482475992329419834248503013105141202009836651280677498803323770600224,6643893904478082560922317503708920766922698054352006836803634579280954593309,20411224098851507032152776776680744497103387047587118749494718067214956146818,6932200046628136855984161612336282559188694975968887215970260451999517971798,13683745075914427134220228573435856137115339570721809234203113630305711234299,12049119081343437729871267418004147930387014906392381996118616615174663353079,2441975952742754201500338273078694079713769380080349023008653075072257968553,1011172201777323348203437837012280331103466286486119939185319004696667574496,4513858889726009970880526008944305706495472698013415303299122950266699858614,1829602352761774082971266699128478520319034089172917557099196106572588528973,20888913280392789424820640494940209099778028785108373950708163556643786717499,11546628016884748339883959858649314450404290142635813671623548341391668641333,21503514976315590685255962605196280426006590386762670744592186136529638021924], - [19647061463337916460942375553072101475191437675089764130648797272059706835097,2987900412319695329324667493933426290750629320482434345012869808788189293747,14313117549814523542459271158255968194819696107203500245376504355915249564569,635066671179149779961724809079155342626591882143599249747638714005480456001,14160366375280976850992425663667859199067402849136919009370279834492741756927,6973916440684075662378599037972982797550158082488606172483341283171694141353,407790128607292443078618781455551950270304278197678311107891073846005921099,1875793830194257638983834574124736838833728874912304344706772047211830871895,101555677977911034029979807139724697918613026657646487138174278033141465909,13298961474358064737775518932222238976786587146906206646633234612439936576772,6675018665213382228528485041578965344759847379196981998842754547093440230230,5085649234634970209690321129917296688853246686378177913913323311616242468355,10058141944442728296289308385948277117189357184119821310668675797744136293133,20711981720256091912789603700019290285604375596717389895155646132584571552203,20115432152302860531854002084546199214679745925822431241410388037137709465378,19426738311039094155622173280735935805207149231732138766959497422037163547769,7740589787985988848427674257205602851899971532434369842038308874897481875095,11072265639503386933704945672016505140436978537584329931993329650203494086219,6167282302581750408390138662907316184354012779517813053982109604767767995057,14593714320140781629003483490890381863557111469157054599498274206519671343499,17959188687624917851017921366866983692604241271917787434145985166811823698158,10852786592684215415216400376119268936907433212885674472022333115957039052793,15899441678259173360040901233792251513972059637300348276334545233380063193689,3640175378514868793712597306483649195648235320181954901691448087453970656158,19498930515578230344335483600141550927765501643188753803487668144320311818295,4153883544158745158953668931089517690854504894896391299015592025101035411270,19024468701496237603291237797335586206588375930028220273546773163298357041151,7469727364011292433851252680653746774195189525727608179319902706399363717756,2372143841469285674441303263292066347817168610069150223765733476276718069613,2516526351266496289030890575774410993157441063594813081137075222758309555822,20958751338961200084885567700868871946051162714262967700193597995642229058459,9198209373895042225521605474867845062450002141670817279014351290187429107128,543785608759854122795367682791595958842618445464321379849398930724000250504,10214529630060513503750965897811894289300014475522844219670830726679857175601,11576753654045835303746511804171201194442330501175712221979130082457712862265,6214928611453392028562534794962748192402530967301618657847917468183855957477,6248903930557664471829331572570457764958370320737816568669654972084840708363,3521559114442643806761280511561190556015853803605505266866910604261521098953,14207749404758918058098136067805881181486166837455095244160881284733449919110,9959485107346230833915817969343930335833003289106263613217998567268111531500,17002458248120505483758089120825692383088865286608827557586088545674133219848,9310286746554253001882911152696415122865977191166769045081952245779941262056,833245639626789987010046903814146615257437312131003591772116076699143834195,8257332153195419962290907487481324519003765405123021230564312430389478396079,15127724347963527967475442670935452967842333763417615675896327776913208692165,15791631600664089304301903868070551535052107017766205491164731100213785544191,3248589614829341629004884091016822219853816257771914825780122055933452087513,17215199223989028745431952733663229031216291778213241728328297124270973463797,3857684745108028860654397149812523817069881299315264066597992653650257401551,4707785116452305555993924679316564589154347100943642537399862884483438576343,19430682328356065477111453488344441289467658065205729792227680437122893422861,8005988640968242998051528980068908390083328633663970547195021707967989536508,1972474227742829959658839187518313253567182690341134307491795498427960575880,6504813065413498635983080741406156525863657160083764580567056987831449046042,5823311218891803691266204716746992257279538141703406410574718561307174926795,9892303067707797586148875186586047934481214044907972144908705198351662761557,20467423831764780786043971286447965746242601887189594828393353559483921550575,5337137105639218811346004301122986797373254603744281473362301032791465429184,2653918865001450389595199059314513619487087198676481143857196098234024054997,20026090683375374670866007502511215153733777854247692013299401340222837331064,16088029123818655662676092939046004587731443682967462740467056646463545748825,9880178757459464201483861677712096813007025248923714154921858424834034903165,1227858189983101698453184059397045112686910656353893224019532173573557918655,6965709790321124552058584230424761849742693958580766537537673695015364525547,5275724511243540616354496187333612866929959836267482390875038898914899476257,697708336385781014957549769788950342363636191998726381071876409126144042559,7274584324261857876506709208086520820725839679509101845928052585127373751594,1101072498472320542658663987709974387416478403320298285132888772486638626384,17063249509595154712877503960715103016753273139274556931196815282616091591377,20468232842910222775240425801279694589286852891430236774476461428028768660386,10839957331597622631657614186340514237771754591887181416690281526344756522470,1833441125433983427564061829081424752522350755265858559398836992598910515884,18955730579934733484387457001397648556717991843841809299503396866826874046919,8193171082824386660318148864436464606096456472585333569988889002087311061541,6800731829409783994258949782115883803874917294598056504156236185152975271613,4551221506539437319374784319536342657448457365716669137274070321896962382201,3888700085587860510427705376785182344099574784427861867496328978292244934753,8086322087822351497126170321910559010882234382816099821864406027930561491554,13275797274085199955841117698566970822958536692349164078040808025934114965830,11798506987450083560046523556681776539473600393190500985018551824337777992733,2379081429050928317988088394722736405728459402480510127050576787799908525809,2158947553437093664557813698796314628878318098916390925037304154608297340081,11904049624504424229914369023060185670359894203980447724969113153014864088654,21129595246904679929428089867320350013514202309069019924095527072919847726344,10893562472341509760161513998095439702562664638408764329166649578524495942254,14633782125268548143403043594739012390811363821154748677494041549086652426818,18155420130909256009162482779733306385315875131491307204196352931575522168643,12073522950076264054413053294532869251854443128423131910399999522064467473027,1433592116103756425832298952472313408701354429203600638317025112329710147915,2210939565463298865317782595691956567659826882335372151952428383797077275627,17035360868359161456401993589512915729326589319922635525934508061308509305732,21403800287219776827894322644981677663016408317172756418765747341745060868637,13463317002652268594305080031749651114168039804631789430404782211764311412845,19738499492349409431828527491123847227085394983018723982858408988105307624104,2012548380220619299131832783872761872147153098580334235039922730491934764706,3325274441705326523449614352431988173829782789776117744919906973769657338996,5261611144921901341966147913919865209616390993972727644394713260572315512744,18987697050242894331980397947115962487019662790026980590641254086717180862945,8658141027857622941054124779019043605220504649377920644749538450450805414621,11298428708044619749095290390778425959792777464903586113463716315584533582828,6730200291399992595132121834599191803078178940321882359439272645986988925939,16058286461189478903573915480209402516073069688039571574175048313793344696582,9740895146643188739739241045620497326490653096157416163918867637699590812365,17328668678982472669285290349933801381460489699965770954259262923597437466085,21089229510079204828717685354260991995629733636903215847138008238449607565274,20640971546156771190021485453412235742638585574517108137718546522103899393969,14758279983387100491873648446401986574422791750180622274744397880182747812100,1331898546985028774480334813742156878861378216830516346949642945416964272379,6432287430987511826080726363315893796139259314225964668680871966245781390173,16771287021606049252082476128446106722127174299597407353702759915141825150750,8558856604643032676967156921137773032066151674912302830855999926475047747086,3441849687388033123111488396776112259878496892302987380166582753348946609870,20817116194964519717309108464421257788806753886196720998666047916921548668924,19363239836951813038374327912605477961457473367759250309818663552575087804364,8719722538679135055399244869855972116946451760806505569767286592823561841553,18664054074328463099250618543796241821469021451703648566147509976488389212302,14668897608285076749626150823646322752663015099871458303607991619920343960884,8824985320268620533295858061606775496359110158594681923758227994736311199135,10765520116421824752776648993191019870707037690612646148788741126433863060128,20754227554163810768271776561488490692278680037121708279136293739447289576147,8507072847563043340105426835824153184629689984787563844408253684598778757305,6766982373679017786884251724806484438649942596522690604198707242527640673411,3038766798814116247860373387571799940341461487105503437312437210868806237693,16132175023628563044043762398003871532172614031006064729051923614189729264142,15583173149116838843387513514855791665649616393679968646432984027900294981739,19200443718712964237956082975258333421930476944060656325774330146577168149713,14490821043935432280588585568226041328772039440696419883978899443298638245193,1261830229525183456874822855513761625054204680497477037321364189175040481068,6528746667003363057717101918351735481714469206031070610241614606650021871543,16147698956945808666133328464174436996026072559773234518262594815923002983587,9020387669972688980419006674825908656426016085797207362353154226605692909040,6727316761823910734900206867002954254557029243225097482815337322560175181198,10066421681146255853671223544720366622786875122426340101570461526567311479729,18114193263469715956238812322551819970497722041025850638963351240642707536449,13327552382593937204593701292574430198134175441510741573417228229955049364251,2372604211171385703747757710474646305749482500024237878826421281702483230858,13257727745849193909326785093877285673934675536283265665870765530981203548766,6028193081122651452411463574343231811776375151328081689399842891316362242212,8508301356193721985012355411615100178521599009635936162890863637274261948848,19464559199695905284994131173285166577427724356611906328878634139911049316349,11574946347736941315258330071986157639717219704847732435648573723449097294965,14316018291870434740761571976364226850140038868497601980741769481529398163257,10918196690875147279977362872452345319770767457845834002916792583407449275430,8977373069224380198540140180493576791843577554452269707469880849832228035023,748498829648879147053737200607377785638767247375633990031472844537260809404,7873158704115081877804196477528352958470140833786962209738121862287852609943,8630532424574483719830065132415752445222218233997041715460638881404278125797,8690582614704926771670051368117061261335922283383440650770249469863376973533,11095347717221488007795836937657301037546485308926406743891578760518489637433,14135401679286508502504277387212121656373093920904597158275723422439876100612,14738090907871182095556666808390406734966899260337679732930591106508814238308,69949271807030541733792162811562320986072778465870031251424993196153906266,1261108319753649612663311207745706802298135850234573661502446278242936235395,16817683438765699400477322528948826720336276287491287100775393652707943792575,18841362612982270174762542916999427955157117780377439797570032391179795654286,21870116979686159000730008975387147484906370787640570497473602061164852395071,2765949947644452455039725847864010340741814376903283748968022076584286340602,17243705140322781483942034937718263695017457618400778609034996357553437986248,13677914966377093417490296499705767815775553283213762175449591670735007344873,13297897273167025228957171745153893110275891317806768533464851402665750442708,13343269561671098171091946421541340634645677702710756455899883309946421878045,14317554923995329326292532110843156058636017277221221405605647959782965284991,2449835610256525707119222686954432076774548565002604197859382557987062142872,17311927259294224200654531686487034697399582221230204382526629700762752029323,15886029754147081563564215095016637219622964863827251334461319377673888336370,12975391569205596000382467418571211360327385366404855968892273321920864753986,5192224731376769981697271181929966876988577937843948018413420047649317448463,10676192139479409715075805869252336543157972214291179434959380291895052573000,11177450837775344504988539319102121281143354970746599512770721409890402968920,4593200667847399069176143966880767249193687931869738276411303724780636851859,11038090380551563944847929106606106685586830480239388947878234434263502089528,3953526418885419728011595573117200571065709475826662733812952860173033412620,11423581837569206292763368836201420979900393158634684009052097987935130296343,20821758092880168608657749212670937227806187953778513378055795779476865339010,18497750301637542715216545677959957759969933594321504330433834545748130561538,12908315310864070359072899712184126229744818024807969170422172983759986468742,18124554128224712379655197019948407579501104121202515283344405665022477997811,20982975342803604005070898815103511622812678185245827078739170834137855132820,269825514811016046965635325890713556615518696022373524499024558861784638050,3147172016143608266119085281262979524079358702373693860744797997889998689295,14386832245166477008833710911810567249931220515383598373556096298357174022469,4556487278328022691163443795787718624849832853076824895328263286768388362379,12261472135716169178595791281788338424856082203277018628926152780653238868197,3899423277681311798156637809536718065846612626667684730473026778811334914007,19506309861341587023369919042973949592579256277585657370274971571040135953685,1364959409282923580897524375843789492029158451437094417717346158650761726050,16825446178437335546349323854223244861262257417842514939476542139147191650927,8507209116997169365742612629060440573797814488088100151461758543065101868641,15267004752470933248572062004321128218304784520473623806984809921883550707694,676031704648473427598859615894926588607941948575683685792835248653139785855,5619669402121492986528563034254744932241765329516105050276049374453441613893,14704798323824402102639327448519792804756861685698966598005087155126928897024,16320067378138810368504584396122999292945236808095532790918287639367557973453,8146733655224190459272793912328710535983522769849572460217349885461291275505,1038180418056776651442944028459510265058633383281360520702142043667403503844,19104250152149288692194160087229108962380481983770051876357439473931889382526,7003760916474780870091321276888809099928758016210575511830123521067523691017,10460150809039904156668983747345347198316841366879181914914418086579576664491,15677112907432790716289265075133862681087874169637399306212310599581157175963,15326287388823547786897864243344800490244989953594543352512215080754525987008,3009920542142872962638960374061083879344081833005888204328736035225746795718,1804978488347291728619316877980070589260679228487014904460247370976082660690,1328483773995482788116589592947585572244503408960547493086897090179230375909,5730439196427856076422854580234519707227885379777920110477133774925338997125,12981431367443547352573507131765244291012615436617972351790438163822109185806,4832711978673748239567077367987729540684018769513731999388791063624971084279,19167638139894327951096186708600927728591679782746822664161578344690189946483,9333793061773227893961520586484148770892826436173136355616167263506645189532,21458443518750111068075382716496819469049134888053123021475459386077573760694,10205061553685164402371459751106832224694007401400200656551443744478399832956,9830442925198991171494436686328858756494894392913894165312258843542937207416,13609869649628867442619044498926584416410429910199812031508542862339177409898,842857359216662427573900948838829890161571314532391785590044951074431433210,6704851129269714864143856350805682503777715960622547687053167421313207852468,20114446898395957281817578351485444375476540075666338352767091837280210668931,6130491715603374999851365684496448519606340852139128448851532580625582546602,15813600594451539718733724931622603275717510629305297903420212550967482486778,21327142130781371825633810115678136219928778056926678460292750153897861437357,4961568602907543961625596532526706517274095072299784820035412496941108876522,9960714813540172203971946479714057278358565379915043327324100653488017320531,19766028424299726292403979387148081559608033800073407130824876437622345769610,19128679427621049663909949398415698465159247423858348746959133844645715231748,5570166864868188450021144960131468276106515498742461735810689530781856406802,11574972995586621052272541749980259251569951388173301707052886832340902170154,20877646438494519923058752260065237612204466401313282232221152388173388627982,5249150519585813956946898091205522450918428396100844955321690157312140444303,2017741632554727420098342601911590665808744692822556685407780092354922864904,1195760854074467363227832424961613965990883686618742557387108941759791735821,11466582138640916980683611003811079018804741425452823176665968956853901549307,10985903304141344987201754580174851046824447026961915755527591886735857840658,2130569969210610976943124127703960718576010294778156297713757734434872381369,10738808247531379378397673739325665568136689079862172683794674460448121540040,20614646033198180892625991863201166456931543657809805208583071176938057085966,565997125213498936861304726982380864240733960104507001725677609359585569840,10632097546602816816944445466416073366486654512740953706603375905768461201631,12929362833112356946255271584627031609627907912912902502403907291451582319157,1034235212357952436868793031480652544314617407845212103021627643626485031876,19390762319422155950976700977771604452581304443563816543281343170335005291057,10630153844633439282958810722979033212891017579520387012386923832074337305798,14190876500956732147461925775340768352695586121304109940717530850819588911999,18722506055380266423054060346625995391170752586033471909467419883841861306716,3056819986793075694786756176651004538794778835114033048299678024064951583754,4672570536584218848208255703572454924953635491594309524306431682544106754221,17351556719883029551473146382008643929874047263147825865359162665615894766393,15361589507494181649833267508353254535596250253216356073840778948791727807159,13693471199005207103868448237123737586403755421081623632730820742927025187060,17755277847125531485682000612777686738631414648862078678723432159826928724703,5078737090654746516628738054730387217943533822956354885634428155918832329055,12147601749747781924069337935019031145159705806951967042421913575214356549816,14365231440612787726412058658929032228572314258997026523542183583106877612565,7278303658563994843919131396912585917500535615791945995381401546353032136647,16203755920169126984249498560164803107868240707492521482933949021054510520315,6791925607504018751125155518211487306271141824074365658905258365090537532910,13823494237593720607868138054959291887740146822262268248432322209124930846096,11009501160902109690977091445438703229756969339078969536565574715162502634351,14720462490975063947234490477382491041961626472580003583159938559677559185952] + [ + 0x11e27da7b7ef964948a332974d07cceea778bc33aedbcd09de222fa22ad0b101, + 0x1f60381b83b44a8fe65a0f4142faaafc5fbf55f79133c5740c53f036a3065b65, + 0xfc1e1ac8ad3524ebdbfa45dcc51576548234d0292adfe1cd70a706a1b6dadd8, + 0xa40798ead3a12b78bcd8f10bb15cb0c426bbd2282a81dcdc070084ce78b8d76, + 0x2dc09d3357051155987ea95594436b6cbf393b0135f51e2f675ea5f462f4a9c5, + 0x104b9241d534264532eda181de1a154dd175ee150f349033e46ddc54181da088, + 0x127a6208d98f6cd387b802fa44cab2037b3b91f0622f17084f1b8d8ac9d12698, + 0x2d075ceebab54341dc02fb1f50d938ce1dfdcde659955a930ec18f8625f86d4d, + 0x44fd5c2101a20be2ad923bebe15a477f40c6039a3dd0d7443fe72758042010c, + 0x2b302c8511fbd3702b815564c5399acb8a8f2a8eb77f96c7f0849628e09f9bc8, + 0x7cbe339db90599455d1eded1e8a870bd302c92a79b1d0f4ee87222cce99e22b, + 0x1326749312c6e8bd4ef24c97c809f78ae548394c94c3df2f28ffa8105debe211, + 0x54021406b8d1f8c7080e7c245304e4b7a797cd236dad92d929b223f269780e0, + 0x5c0e033b589f8ddb23a9d559eaeecf98691a8d018f1279bf406d08f2787cc42, + 0x2508a8cdd450f969b61c749d566c9459a16ead4330e35d5415b12eca38584bb1, + 0x264dccc02e574ca7e736da25072bd8fbe9909621fd4f4169b2bae8d368ff12d2, + 0x137199f796d310d7fe22d83663c8e607d342407dc28c10d27aedc4a45c8ff70d, + 0x2f6877c1a818cf1f087343dc38dd120833574b9691540d03128a2d051c1be240, + 0xf418e13a90e4295bd384c4d4764398e1e44865058e6d85f10396a7cb0716494, + 0x1a6864de7ca70730f8657bed417c428aa5dddafee26ee78b942c86be61a962c7, + 0xf8be2e253cba2f128e7365d8b1ad95f8986968cc60224445f2bd717c26088d9, + 0x16a8d9f265a66f69fad6d7b744cf090e490552c6d4ac77f89f09d0ae70095a5b, + 0x25f1a51ea7f88847cd19c9dfa9c8587ac7a4f4b8a10bf900d20270398b9613e5, + 0x28d4a6eebf392a9378b7ad9aab8862245279a9f2c0b1678cb6d3141ebb14644e, + 0xad7537d9d5bb7e34936eadf66fe924d80c893745fdcebd5ea08b79f9137aed5, + 0x6ae9e1b3a2edb869b5c6f231fede58dc7dfe42bf3802394ce5d62c3a65567f7, + 0x1f5d4250771eb130c046c8df1e77f7f77da20709346a334dbd22c72191045cb1, + 0x14bd6a1b5678cda4ea3a16c3b5abbf38ee1d82219849cc37fbcbd934e7de1162, + 0x22905156b6bb357e2727bdcb8f39a66a09828307046296c6d5322abdb932d0bf, + 0x2023fcb87f89e6fe4cefc3d315249ed8133834b56aeab6fe07b7fc246b096c, + 0xeef78e23ad00648fcdb65eb246c737b7b4060b37b6b845eb914108f1316646f, + 0x1f3030be5da4e16c0468d631074a65f5457462fd6be6db36c3a522453164e48e, + 0x10dc200b8c1b565d4c2e88d5bc1bad12c490a20d05dcc4cf55e9644f3534455c, + 0x11a9cf0b8e97ea26ed0d49abf3a09233703333789a390d72db661fa70b1cc2c6, + 0x15b97860d1a835a706f54a97ff04a15c69dd3beb0f86b51c83803d490c2cf2f, + 0x1225bfd0d701b349214873ab03716319d9c96e3cd8d962028b17db843e4a7f19, + 0xf4ebaee2abcbc49d408aa52c60dcc093cb0da884c4a92d0f280d7b100600560, + 0xadeeea75944cd5d35045ec8cb6a57487287a92d1f70cd0b2389a4f128792ac6, + 0x1874870c72a32f0d385294a73d0ff67d7234af8e0ec57c63b4f77e72130591fc, + 0xcd011ee52170682d3777ba0085ec1620e19b1485d9898800dd2b1d74f613576, + 0x2e72b9107cc1e1a9bef16bb21a308c9fe3fc9221e55f5d4cbd43ee8de297e02b, + 0x7ad8d8e863868745d2c0c6e1d08dd357803f4653ea2045792edb563399f7d84, + 0x273d3298e5b22284dd66bb0f5e963f0a6af68c14018c728fc42cc82acc384db3, + 0x111b832918546dae5a1a71d312b412462b9d2bbe867be4fdf089eb15820bfe13, + 0xc4dec2328aabeec22bef040c565b1227753c1dbcd9e470f906a4fcb5cdbe7ee, + 0xd21f2bf0ab2f74a5eb38abf787121f015d88ac22de1490c548d0606b8e6d7b4, + 0x1e08837512f3cfe1319b8f8babf49e738abd159e322227401b7a5441978f77d3, + 0x211eaccc37cea3485cb8300994538c153b1dc5b8d63c96b437b91434642a11b4, + 0x123e045851f8649e6332e3e208b9d4db39099f077a1104555bc38f68c62deee8, + 0x8b66ae60a35e192963af9ca3e8681012d5288a5abc67065ba52bb151d4042e1, + 0x2e9188c8e02a08b719f7cf8af307de827d424a166e6f9ebb172ba41855a405c, + 0x52458b94157b0e5d0b5cef9ffe8e014eafd7cfc1b43611faf31c2d8d59b4eac, + 0x24bb0266c20a04010addd514bf76e3da1276d13cc58faf89668e238b9ed2ed6f, + 0xcd9a619dc0621a5f4cdba8303b5f69da6206bf28a04b96d4fdfd3a214e3e54e, + 0x119949b91445ca55fa6ea8da2c11d93892e5b4cf3485599f41106eef149eea9a, + 0x265ec37b545cd5dc12a27c1128c314a13e8cb222b5d25c3b9061934e93cb97b, + 0x6aa84e7c246cd723c78fa394a7ded19596e074fff4ac200171a1f4c75bd7924, + 0x1b4e6c237527565068aa65269cd73b5c4675b1148fc31fbabcdcaa341f63205f, + 0x2bc7d97b099113c5ab67254ffaca493041bc43e8d344be98152e98a4fb786da1, + 0x1e8fd4145c4cda03e17eb62c0f9d8cc97f5b13b83ba8400b57a3d80009c00eeb, + 0xde458ac4a2ca65e25c6c028b23e73fcad1bdb3e3f1b6a730eb47e04dfa65318, + 0x2d1ba2bfddb58785ae140c239197729f0c60ef611f3b377d4aae3c6dd444b5b, + 0x29d94b0688e3236b20967ec747b92e837fcbc396fd6c348b1e0c748a6ee021f1, + 0x2ec6c5500bc7998c7b821d209c608a630195b734c02a5aeb15b1c755b7857d5f, + 0xd185c970b8d03fab0cb058605d2c0871c76af2047efcaca0e1be393a4817ef2, + 0x300c58a0b3c59893a5acfa7a0adc1de29dfa3f16b4689af0535cc2513d60920c, + 0x2360aebfee8827a4b9037013a6dec8af8f38308d119b3167df19e3eced62ef6, + 0x43ba139aaacd5a1c1349104235e9855ee8802cae5a30a85edad853b092b5181, + 0x1b0597b0023cc90297b8a4e996676d65276b1a4c6409d7c3c26008e56cfe6f63, + 0xeb1857692cae615046d0febd92edbed96417c07b841b462f78b90960771ed0, + 0x6399b5873506855684d027c760fa5b89721ac3004096114ee2b0c5ea727eaa0, + 0x92636eca31acead1a2e63131e25a2cb4cb5e5db766615861f4fcb06e4321eb, + 0x2e1d940f15c6a1f49a28f66c0d539f5ec4431ebc533ddfef8acf0f5463b7d0fd, + 0x946412137bd02c889bc3f6600635398e5c29347a580994338e44a6fa41b40b9, + 0x18ec2c5948557c8699e5e425ae42b5f51db8faeadb62bab808d1662253e61cae, + 0xac166679eb2864d7674a89bda016c235736783820591cb9504b890b9117fe4b, + 0x4db97e1cff9f2fb62e16077221c20306c32f579be40d7838e6ec15320c38443, + 0xc4d540ab17d3ba0328f95369e86fb073f3660896d85a679ff9c6c99268bb7fc, + 0x2e6b4be5eef898dd7bf66b3754ad1bdbab013ab0ed99c1632a489c76987f2ef2, + 0x15f2072ffd2d6caa3d6ca13f7703a47c0bba942b0d9ba0b141047a297ae19899, + 0x1ef8155e5c33f8855bfdcc24ac895db935559d5dbc442514d4272e0b2270604d, + 0x194f4e345835e516564677d1af5193e67f26573afe1d12fd77673126e4b6c1e0, + 0x2a3fd58a40436abcf4ff7d7a582c5bab55edf2150a786ed51c56c6ff2b668c98, + 0x11729c1bf0a0f91ac34e4456d39ee6d2dd1c064368c2f0a8b76f555802d9af0d, + 0x2e13f7ce1f37ee5f2839bacd94feb1063960ee6438f10e01000769bc2856e755, + 0xe1442f5f0fa8737f50d8935fdfc204cf07e6fb3acd7c7cbc78fd28dce78deea, + 0x1aac56dc7ff6d0adb2cb7b01c67f487e3c812350450993bccb186b2fba077957, + 0xdb64a35a35a8fd6b486cf00f5324887f84c20240637b071d462a8896af11134, + 0x2cf6b1eb727612b4676e65d750a2cb15c82f13bc858e0bf6c1cf87b96f8796f2, + 0x761d1ff3a90fa0ece518705f2f80055b7667ff667063fb5bdaa950efc805199, + 0x92a84456e8ab1a26ed09f4c9c78dfbedbf4904937bbbaaae9a23dc680fb01c0, + 0xcf9cb1a0a9e17a9d6bf4b296ee0530c1b88141bce69357f964fbc22796465ce, + 0x1fd3b34a7c3a44e18fa8eadb896e5a17ed439bed8efd723246a009446bb95f0d, + 0x4b5ad182b4ba40ada5f69e436740417c1bc901b58515f969cff2fbde530787a, + 0x17aed43f02895475ab9427f84c57b965683d44ac92554d140ebd0434fefd6944, + 0x302772848bcacef898d59e149ef84e4822edaa6091e236aa41bd683acbd43a7f, + 0x14b66c4b0f5ee36c9f94644a4110cd09825cc8c85f6cb328391e83fcc86c71e9, + 0x18d6d00bd7b85619dd8b979158baaa87e5fd97a0c6d536c211a3ec663458fb2b, + 0xc094c29ad77018d4da01ac5d06bbaf353330bafc55a942fbaa30b4876e11240, + 0x1f6c4bd9672a340c114623c83ff250c8e410f0a3a11b4fe769099f8be230e4d, + 0x279d9751ee739e974ab65792beb9276773537e2095dbe80baf236adaf2d9de3f, + 0x2560999bf8b9ba17804b13067dd4b0b0022219dcbe167dab5f9300b68236da2a, + 0x211d8050a0cc08d433d487381dfee76e39c8afc46292f336565121fddf4f8b4, + 0x26dc6f484d1445c5f5c208ff1a487e372f1f8782dec0a5da03a85f706ef48e8c, + 0xd11eab567c463fd6796c3bb711467a6a78f7d847de201eb717dba516808d237, + 0x239b30a866e3778491b842a8c2df9ae14a6315981c2394c26d99ce97c4e7fce0, + 0x2e35cdbf79533471e4849a97467eb4d1b21c6ad8ef34691e08b74ef19c27735a, + 0x2237729ead5273e8d6acd40a63eb08813a2293e21dff54ea02619c6bdbb18c77, + 0x290c8723936f36b91aa1fc42768007ea904952ec0e41480d074b96d41703d648, + 0x1c279f1d50860ece8148cc1b59f5c14a850af2f3a7e2afb8fddf72964fdf9c53, + 0x1938e4214605f8e2fa59e7f90eb10eba0e984c24a5f5c1b719f41421229922e2, + 0x1b45ae36a32c689150489056ea161cf38ed1506f33a711d6b471657277d770ee, + 0x2f0ac8b7be349d38f0ae7f7dcd7cc86eb3aa06c708b3faff90f6b24a8b691431, + 0x1c40238de6c61dc8fdb5a75611be0d4bf7f5c4eb39fe9c065c26ae970e2b1f06, + 0x1b4baa71e93d13018ae4ebb790bc188c4b46c892c6782a27115bcac4d165f3dc, + 0x145d0fd15960dfe597187dcdd2927c5170b853928ee08686555ca5a57ab4b1d3, + 0x83791a423ac40504e7c99084980599a3359ca693c6aacc47b192a325d6df626, + 0x2999885c947c9dd00616bbfc088819ffe4c0d2f9033b04f408acfcf1d79651a3, + 0x8d0a62a3ee05bc36241af5eea0b62dfd4f28c31fbe77fbaae392fa7b05af4f2, + 0x18e93970a8a8070a1835114c4316e7ffc242eb128031aca086d3ce2cd3558e33, + 0x126590f273bacddc28fc87c100b5bccf95eea5c1607dbbcbf05b6db2992cc12e, + 0x21a7b2a18aba9b81406cfe7c64c1b0b4037c241e7565b52760d74e7720e92117, + 0x4985dff243cbbd8eac16b7b6f03603118293966de095b2e057043891bf5174d, + 0x18ad558446b1c9342e3846c398d05727ebc22d4a8c03de6380cbe55aab7241bb, + 0x1b055d908da8e662ee4b05c3c66886a35bcefb67946cfa6baeeddd8cb06fb65f, + 0x1a10263fb63bd4f23fdbacba6fb3f0d7499fea2e1e1547b36b17c4fa79dc0eba, + 0x114b2c3f7730ae08a1a31bbdc27ca1b3fda63d5d8eb55bdac6578b27633395cc, + 0x1a3f27e20df3c4045f3a67065ed869377e0c63a9a367f09f7a3bc63d4006bae3, + 0x1eebb48e654885e9fdc60b3ad67b988530923f65fa76983851b1092640bebef7, + 0x2ab3b05b9cc58838ee853f9d4a4817c7bbb1efa9deedb84d52c90ad9d80c2b1e, + 0xbe8d510c3f0d8edd5716971f2452b3106ae0f4933d894404bc0b5eeecebe356, + 0x300225e792be5f679ad2d4f8b3d070495bcdf876e50523cd877b4fce9bd30543, + 0x2df4b36388d11c2ca5d95c24c93e8ad10ba7b74735753cd0c7aa4805fadbf0f7, + 0xef6deac5ae321c054639444d4f0031663195997b4cfde163c75e989eb0629b6, + 0xfe041753831aa6a6bc0ea08a153bd5a409de14ecf636b3682539074356e5852, + 0x107105d12a394dbcb31832b57081aedb73e0aa17ac7c2faee1870d2dac147f89, + 0x1c2618562f04166bcfa93b80c537ea8b35aa07d8ee33703fda76079f7b78f1ce, + 0x27f7f4d91b9f452211799438a638f0c80e3db58ecb8d194e97e211e158df46fb, + 0x2a9982f31c9f628b43652dc20217d9a91bdfa94bd125e1e032e4f6626eb3bb02, + 0x2676c1451011dab5891ee8f715409412396960849613d13334af036176b7f343, + 0x27c95df56dbab27660262717556e57b6d3d66869a0f834bffdcdf58c80de932, + 0x50255c8e75aa4e294b921733803da9d6b9a9eeee28606bbda643a9122fc76b7, + 0x26a0dbba1128c1eed674bf21e7a7d23163d48634967d0daf7e467501768d237, + 0x16e80c84883b3370e75f1ab266b46f0b839accab3726278ec206998b62e789df, + 0x9782b1fb5ac39e3124c5e857253337a4503950a6dd151f005963c92254ad7d, + 0xa6975f45d3f7bb18c7db0a286cfdfbe0d75b79c74e67ad2265cd168c1670c1f, + 0x9b2d6b4df7d70732ad35eeed1b468efd932a780e9e74cb82c3dc1c47b4c8440, + 0x96195e37522c163f5fd66f13cac8bee72ae4b445224ebd85340a69b5a322739, + 0x26d015d70931042ece8bd15db6b08bc1496b7501baf0c8bf4a5534fd60422941, + 0x39f5d3bf59ceb12854079a2675ecece7b8cc5d9ab9c3d79adc1d181ca6198a9, + 0x1352b30ec61d92dd82e2360d38137d2fb02c1e78d6f99cc437e8640becc56122, + 0xbd8e9fb03b03709c0be6510b233fcffbc1f9f63f4d6019b110f77417fe381b1, + 0x14d37b7920faff9ff10ac3568122fe38221ac783e675bd5f6e69494755853723, + 0x2208c576d439a6c9c0c380e7063fff76a1f2685bbed6fd7bed23c732f345501a, + 0x8f4fa71b7c3c71c66c0075a5b7a0cb6271c6f7568979d3742e2847cd650aa55, + 0x30553e47d42844f4dc97d3b96dee7b6c483d2868125eb7de508164de2466b74e, + 0xe10c2cb9014f110cb54d27ae0130988b0c32a55f8d111f2bf797dc5b2c39a86, + 0x2801868c0861bcc953405e4964dfd447a8888d8839aa7e414de176c7c061e238, + 0x23ea7dafbfe7bf1d8f8b4ec83aa1f0ce31fdfc9ac5d2cca02f14ed1b87caf599, + 0x22ff012edcab66b7416dca632a59caba6d641e02f6fe47e7510ce945966f3721, + 0x2dfd80076ffbaecd97311a5c0b2314400005a1f07b6c21d92228583ca5b5a4b, + 0x23c45a61f4f2c8b3e066a26e232e26db93aaa24e2f65d26601ab2d7a1b95606, + 0x2072907f984ca35bce9ad3e82d8c30f9acc0ce98d145e4fe277e628489594e2e, + 0x8964e49de9a9fee1ca762ffbf07f8c4a8122bc4e90e7b567fcff008a6e45e6, + 0x2dc503267b1497a821453a73030f2a3523213bf0db9d5b061342cd859a1cd907, + 0x5fd4295ee0e76dc56af4119e7376a593e4bb185af60adddf232b91e67fb2aee, + 0x2092ffeb6b7760870dfaf471823ed7591fcf6e6bd5b1bcf43775d3c07b462706, + 0xbf1a49f9b9ac34d30e463ba797e3e08dfb424791ea612b280932ec208c7f800, + 0x272a88a53e263ff0a56bff4cc645fcc269d3ad5a63f9625ffe9eac93a36b77d4, + 0x27bb4022b1f689184b10d6f29824311ccc5e2ef14a3914aea8f06ccb7f2aa8ce, + 0x178f0ee74c834c0d22f7aebc5171f960b20546dd9cb53b3ded78a351ab41ce10, + 0xbf6df276b3f28afd5206a8646dd6f4c095fd98871a5060502f3a6444be321b5, + 0x219d4e79092df13b3223f935d2a0a2573c1f7d509a91dd7fc5533d4c3c5d098f, + 0x20f5702b749f56df810411ad9950ca9f87f1e0f97b8163280b3b2df05b679b4d, + 0x117284f038872bce68c791ad18246ed84badb692e338f716793f5a6bf216386e, + 0x2c2dbc65a26b313f84567ed71d40847093d08ce8c2b8a343c62b7f57ef63d968, + 0x1743373e3858cdc0582049ef7e0284d33403cc8bf56997c508a10b5fb008ae77, + 0xba28f299d1ca31db5a3bc0e8202e9ce8fe85f80c4f03f9eae2dab5de051a659, + 0xe46831dc32f73c1086055faeadf047d3408c2cc0dc2e725c878dc9ce68f17eb, + 0x1d8635cde2ec64aa50d8d979e29ef11fa0060bf86ea00762250e314e2881f70a, + 0xeb6d86f7e11b1e3dc21882511e03b7aa64063688fc52f655f12e34a343dbcb9, + 0x20bb2d1b0caed114b06fca648b0703a7346f6b2690f220f82e7710b586b6a81, + 0x1c4db5ac81e0e47818bfc08f7ec2d66bf15daaab8ee766728f588539eb60075e, + 0x16eba5f5dd46415f55abb8199b0069ad3ab7a78e8eedfafcae845760a4b1e525, + 0x46718c49cfcd67cfc27daaf0bc00db0165a8b34bd1801110b85c3f890779f02, + 0x10eccf3b4cf167cd78f9eeeacc462eed71eb92a2e31bdc1fc4b16c0b19feb44f, + 0x16e1b2c0dd88527774f18bc53f4274fd15a5afcf3656f149ba7bf0d67050f3dd, + 0x1d13bd396da5a68e7b801ff0b2c6c2725f961bf633d0dfaf1a4b2c904969ae53, + 0x2023518104868b1b97d9a5170d7a33230bff0618df4a31b381fbe9a0ea3224f4, + 0x84c4f9050120239d86cb0d84535ccb94821f0a1def04495ffeb559f153ddc26, + 0x1ff6f423d94667ef2d79660600e05c570f74d77ae07139d2019069ff96c83566, + 0x7b5719a1e09b96a5ce2c130b9d3ec76002d81bd6a8b46ad27274036bb363bba + ], + [ + [ + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x111d04c083f51a6fdf87412a537f6601076d61f435094ea16946efbfa4893e97, + 0x133c5913f25ff5eaa860d0318f6a4b4349fd22f2d53530e5c785b70988a3a88, + 0x8875f47d6f518c8c2df51a786bf2207aade284067228f440e7d0307520a56cf, + 0xba9f44a107a81cb23fba66f2bc34152728f5f5ca68406649a7efe47c9473f21, + 0x542832ab23b6c7a4b547a1066037152a2442e998c5381ba97698413153ba6f1, + 0xba1f764367360952942ccb6edf051c8f937906a816641e0d1e9e2ed26906fa8, + 0x2e0611fa4ca3985d7bfaf512f21a4081141f4ed0dc4b022834d3cb6cfd8b7ffc, + 0xe6f23c0ef6f159dec68341a87830fb864b6c08cb954a14a2500876697897fb7, + 0x1a7a2a4a08d87e75f720302bead7ca21c8f7c2ed2debaced9b8b1b2da461cbc, + 0x1d8005df48c8565987dbb442b482cae5bfc10ee486ecc5b670ce861345979d1d, + 0x28122254823f8926acb7e98f557e796282e5e1271618858e76d49d0886da16f3, + 0x2414d4aefc7b4857df681328e68a582d23b2dcffd579a8e6aeed6c61050e05cd, + 0x2f710c72d6da19c7d87cbffd55665b472b0265d13e2326a9a33b96e95d3746b6, + 0x2e285441d0bed90bb41d6480836850e4d76da8211b04a236dbc7c3c30320c00e, + 0x2964901a2b42e9aea1a6593662aeb9e12077a287434bda4ec2012e36a19dc95c + ], + [ + 0x69b1779dec3eaded3f07d0c3e6cecd6cffe78d747faedad9c90665aa2d92cb3, + 0x187aae261ef3ee21b37023518a071675c6d00bde82bd7f5441448abb632a764b, + 0x169538094d4f752529471e3fddc9ef994cfad4f96dcc7d636f0fd509b8eb9c31, + 0xa68830f19c0a729b2f89be27373d397ae1157bf507e7799d4220166ea0982d7, + 0x18ae39086eebb98d1fc5f05fa0f87ddcb149b0afe38d1bbb85a65697895e63f, + 0x4c5ebc771344cc0612765710bfcb1c2e6097abc3d346f049495f7d7b7f06cb1, + 0x29faa7dadc8b7e9588d4a601e77bd80aadf272a1bfec3c443ca3ccac81d9e1e1, + 0x2acf3493012bbd818724e7ceda2431e97c8933bfaeb5d7463b512e6e8e8f7fcc, + 0x23b34612e7d052f6b312ca0e0cf70034ad232d9bf63c88821085383b6f6ec4a3, + 0x11680cc6e80b0e430a4cd3607017fa8331d86c4d03a96dfc18767c97cbe0a197, + 0x1fa772ebde6f3732444623d67fe991116298f8f30a2d1010c8ae6132a3d6907f, + 0x2e63f1740332f57e8317f2592ebd8db0812714d6604132d525e33e19b3c98494, + 0x1202e349d1d7b805846e90834efc911eb6b10c2a09eaeaa29ed288bd779b14f1, + 0x168fdc32d4aa8dc9034ad4a4fafee89f0ed5c980d3db424d38f8ce5cd04c237c, + 0xb9ae9f5ee6ad70a651b4b66e34f521b130d18c49464d86fe5d4b1820489028f, + 0x6c2194af72fac58ca13a2a5e3223104ef49a540fd2eaea0d67a920d8567040a + ], + [ + 0x1fa4effc83498d19aaa598b7771f88a0554dddda89d32dcf8a6f4cf776d13b99, + 0xda28ede7f63f75596a2568b2dd7a584576e5b282f284795b1a7aa21663822b1, + 0x199835da95f6eb22c591ebe514c7f283f674fcfa1eb787dfee5781a64f082439, + 0x2af560600b3e25abcc7f78a4d6e2cd3fd99bcba075ab82b55e9841bef7b9210d, + 0x101544d131454f20b549b24a65ec84f1b3221fd9b43461ddc6d156833b34c52a, + 0x1a51740cda5e45ea4d4bd7bf5ce5466a66a11afb5bc93cf10d5309e07d410e4e, + 0x1324558b8a5d4ba61b17790128be9f2440c0085dd5d6065b88f0a3b2537bdadd, + 0x13473024ba419fc2a7743e7df8fc8375aab150d3753a54250a808d66f2d06b91, + 0x13f15bc6453df6f9383446550534dc57aedb10139e3053e83bafdd99356175f0, + 0x1314b54f8786096244532c9f054b379636e2b58bfdceb3d48dfb2210b529b4e5, + 0x56a8ecd232a674c63d7b603ef8cd06321c560df2fd3f6c2649af576467fd798, + 0x98b740976c2a1031e75132e050bf3838b739d061582543c1c7f95c152ee262, + 0x24b96dbebfab6d23fa32c2c8e7758cb240bacd8143323c53cdb48dc8b65f8e4, + 0x15bbd5619f0d59790804f2b9b37e069fc909a2796d1f77d0c62609deda2d0278, + 0x4760054bd5d07132548bed7657f17c61c038ebcdfdd4025c7b802e08948e108, + 0xa5494c9bcfa06aa72c36fd22d98fe72dc14dc0e4e74e03d1755f38ac34050ad + ], + [ + 0x1676f5c07417ab54c37ec8ae1a8314bdeeb09964769881592043dffcb26bf41, + 0x2043bfe52d2964e4a3b2da5e30107716cc764f9b1c8ba463f215ab1f7f03498b, + 0xdbd8662511dd7000991b39da129f9d03b565a0cd2f218d6eabbb49a25f105e5, + 0x11b33a9f1818ed7f581cac020051de26fe28dc0bd8cb1a4457d5a8447bdbd6fc, + 0x26f2f58d63ca6ef59bb95206ce3ed3124885ec21762bbb1db1d6a7771ec6650, + 0x2eb6ed568377b696ad3cb237064ec68e390c24886e1f122d21d7cf3290dc6d08, + 0x18faaf1c91e002f7dbbd12f408bd5c5b92f38e02ce3635824821e0347faf53ec, + 0x29437af1b14f637a1f0e39955f2604bf20439fcb2a090e346aa65a9ebe69788e, + 0xedf86bf1b1599fe27c66f3494862d75df7764070a8263cf88778f7287938d8e, + 0x1336b208e00d8ebac83246a96ebdde351063fa3f635887e753a0ce3e29c7eedd, + 0x2646341eb44b4800d56084cb48500fac48fc533891f557e96784cc6004d8928b, + 0x6f53c79fed9e09848e112a0742d8ae84a04bd9ba5aa2765b1e5edfb1602140f, + 0x2a3c9f55afacee735a1b515526426384ad044291f7691974d9c05c634b43947e, + 0x1e16e9ca2502d696023bce3427244ad6553ce86bbc4c349a34ba61067c6b6d6a, + 0x2a4c6d3259779c396ef8173ae5fe87bd611dbe25d1c048ada96306db1e3a40d, + 0x265ca211180b012c378e0198f0b5f7758c155e3675fadf92ca79156bd56fe339 + ], + [ + 0x1f4e7bbc8d42779e58aa07bf54ff324b814fe687b4c8eb81b9b7e74448ee27ff, + 0x27b48a636a39b51a938aea3eb552091559fbfbe71e096d518c40d908dd2570ee, + 0xdd0c118f15ae07e5db55077dfa46e08109954d99e18d72cd2caf613920e390b, + 0x45c617f604c1ac9fb8d76e8d380322e5a3b69fa7b7c2ae2c8ec5966d6a4c788, + 0x25b974fc5129d82ae4c6246e35f802e03440ead09995865313c8ca91c820c2d1, + 0x181589b140c9109e492fc3ec7d8ca8e3c25a7ce58df06f13ef43561d58c5926e, + 0xee1288b29855e2e38dd26292b39e260529841344538d6499996a32e7cc523f3, + 0x206e4d445315b764280cc643b9479f49946ea86d7304b6a2c692ac34d7c98d34, + 0x1641648c26b5a2dc297daaa6d4ddb6a2f258ba738f9094e7c5cda6efa8c993b1, + 0x1887be87f7a352410482ef3bdcf7ef17976e087eb8990c76d7e971c44c048239, + 0x231f2c98bda8d48bb4a6d9c98bbbc16027235a22a1ed4f88bc8d3a6e582209f2, + 0x1fcea89286dc1db61fe1111606af396e98cb53dab5199750aa5e5d11561fb145, + 0xf7bfcfab17db34c144cee44636bdeadfab44a6bf4fc8ef384ec89a4ae9ed209, + 0x1dd0a5502743aaa9f583bd0ad35de13ad8d5fc98f1961f2612ad4c28fd9f9fa, + 0x1959db01f5c8bb0cf483490373e75b0451b87b43e59181be0b6016674f3f5efb, + 0x21f659fedaf6c2617f17d637cd6f54a27782f4e8431f87af5c8591932ce7dab7 + ], + [ + 0xf6b18c98fc89fbfa99a04c8c96ae5db35c296479f484b680df905d4cbd1dfa9, + 0x17fe75a3d11b4b9d2acf7856d6dea3bbac62ade0c501347b16864f3c73ebb7f9, + 0x7c921bf45e354848a60b0e5f292bb03c2469498b9c1e4d322f4afd1867408c9, + 0xe6197fe502328d0ef7f9b930355312b347204b877e7f85d9b569dc34f064c1a, + 0x2d409bf78bd6f6a4eca7397d065023f0bb6732207925d3ce4beef9f621da2ba2, + 0x205a6d5aab2d224b668c70fcb41582ee9ebe1ff099292b4bc50af8b292c0ea42, + 0x2380ab051d0ac580a7d116f4a9337eb31090a4c7ecbd4e638e7717b7a52bf106, + 0x1382c3c24bf2489fe9efd80a163e650111f5d9885e58a9ed729dca1f9a74e59f, + 0x280c4522ad0ffd92c391e94c70f87120b8341890c3329af050625f2be52f3a41, + 0x1f405a9483311e1497568f1bdcd6d58cd6bc813982a0e71561b620003b888204, + 0x1cafcfb62926fbc04857b0bd7d7392b8d8add16b5cbefb54b4d5312826e89942, + 0xa12e162620e71beeb203be56594416b083e7e94eec23e0f44a5ffe9e159508b, + 0x17203c4d2e1a428a17be2c27d1c4c5960dfc6aa36f22bdde8be56a0cd44e71ab, + 0xed2cfae7b36f470a7d1f6940f914e8ecd322bfd6b50f9ad9f6a2226e7a95db4, + 0x1849cd0910d72eacc32d891b71faf500bcb93e1cef2504af443b94f8b1ce7212, + 0x1e463ae3f4c3bd047aa1049f4f091a2f1d5d3550e3d5801fcff68f9a5e6828f4 + ], + [ + 0xe6cd10883e1e11c6c191d36329f30eb0045af06c2d86d0c439f5c1f4fef54b, + 0x2326c3dca7aab6b1852654fb13fff42a152ca9632124216cc7cc6f6d37522a59, + 0x1f694d1acbaab0ea5bc026a1864d568be555b89c0f49b6134e9b895ae141da86, + 0xcdfe099e7a154278dfb6c0388b9daa1e8ff323a20be6a6aa7a8438333f879cb, + 0x17f732cc1354b1fb476e70568d2dcb0b6683d30b02415dfd385504736aa86de6, + 0x28239a882dc7b2f3ff7b9aa8de9e3d81af736d4ee6ed991d5c6b4fa540148f43, + 0x158926b9e94b10fcb321b293bb8a8647627a5bd31315808d397c1c94f650f2cd, + 0x17cd11864fd2c73d0867d37264b4ca14df935a82f2a6f432c4998135fa5f4aa0, + 0x1d772098b6154921db8e7506e6f0372ca44f20af3386e13bcf71ff5dc0d61b1b, + 0x209576be72db7b0c9fe2b8329125e7dff0489a8e900a5f14c1e6e48604134264, + 0xb7ab1ef17ff6235f7737f044161902f03d594cf4a0cc67b4ffb4711ade1eb0f, + 0x1b1bbf4e9f706051716a0e28990caf17573086a5d818c038836696808b12d8e5, + 0x22a8ee74367413eccf7aa03fdd420c6bb6255a6dd82081d6b14eda9a9752329b, + 0x2c785f9d8834f5cf5d08f106d5f9918340fd414abe24f0a9ff2b8e0492b44d83, + 0x4b5dc2057b88170a718a102e0ca9177afc757ee26773a0290c6bab159ca4fb9, + 0x27412191fa2b2e5327a11d290e4b439a4124f48145c61ff4ece8448a4373eadf + ], + [ + 0x425a9641fb01558bc7170a2ffc24eb6a514198b296a1629cc284d983bca8757, + 0x80c442909227f4a9da92e33237f9a82cb0c6f7d0c4155bdea5c6517b046eb9e, + 0x1604de6a2db122bdd5d839540a1005ed402425bac3b85e3a72224d337402bdec, + 0x15ded859d501c2733feaddde22ff36fa8ae85803aec7a204f42b1f6553bcc655, + 0x40db0defe6ba4797b74a43125cf34d86a2b33e7a22e2710b0fb7a5568893aac, + 0x1ab15f2fde6f535e77e615c8c2602193d45860cc015849df578f9fef9a5bb283, + 0x264fadcc791aa18e76751a895242c30cdbbd1197a90a456dc278e10bf0bff5e5, + 0x2de279fcf77a270823a91a6cd1aafb58e9e3ab32fdff0b3b05c98d554db6fad3, + 0x53ed8ad550d8992f4b9814920183dd839bf355eaca8cc7b07020a22614a808a, + 0x279702b135d144ede943195269c00bf620f058bf0186ce9fff3cb38b22245a, + 0x179a82b77f2ccb94b38eb582ac4abbb16df429ecc22471be73cc7766f96d9948, + 0x89efed00e9d993f5fc1d5af2f2b5d47a9b70e6d5a603fbaaa8f65102123efd7, + 0x21e25f0a7f8edc38de25ba605a86cc08e08ccb03e77c5e0b9edabe74768b60c0, + 0xd8dbc3fc854c0665c30c48846d7bb0eb18d3d78a4f70fef07f242e45b865eaa, + 0x17bdf338072884b522ce3c50ef4711091b9daf48a43374bdc0a830c37e5dcdc8, + 0xb3a769c8b371562260395ee4f348f88bb056a2f0ec0f98e4e633bf7d943615f + ], + [ + 0x397a7d7434b0aa941348de45aec442cd5cad2c398884950e8233c58dd50335, + 0x2b1c00ea00893f9f91331bc907397db865c37d3bc6c4b39b81cd931696fd7837, + 0x25970ce31b7b10cef221267bb1be1656ec29146df06fdb5b4f6fe6607523aa08, + 0x2d4026bfa7b37a19a300abaf2e1d5c32dbcd42240ed860f681f61dd6d6214cef, + 0x29e89034942414a1ff6833d6e22742d4106e0f5f37d1f2ab80e5444e5a52c9c7, + 0x32b6266f24017fde1b281d0fe206dff30b539d5c5ba13b5312e488d8d6f194b, + 0x2ea014b61ed575392239bd9411c0a6c4202b7334cf2e0dd8c3040528e4a3dfda, + 0x12ced5254e260a9db7abe0cbea26396680f6e57dc07732a755d409ef751200b9, + 0x1d4f9ba4fd8ce4ef193b9f870f44956079538d63bce344f9016ac5ed63a99a5e, + 0x2c9c3135cf64b89eb5b714d7b2ebcd81fc7edae637cc6116591df208b6b2583, + 0x18b63685f6fed2aa1904856378442151dd1fa01c7ce6121d23e1e9ee20b42558, + 0x2b202e1d2626c6793d68aacf9c3a8fffb27cdf5a0b83ff8f3504f9ab26a43d15, + 0x6a78dfde1458ee341a089c15f953a2193527dffb43f552cdad595da7c6fecc6, + 0x22f62e45e50084696ac2512a25db9925244cf0214b6b543d3a9f83b8e8e58ffa, + 0x2d9379e69b178208b8496b8a0a0a90d578b21f090c53042be4767e3c10d3b40e, + 0x1adb4c87433d866e8fe5ae26d01477e3962879c20c8c3a170c0727167c06d0b8 + ], + [ + 0x1d66f208fc04411a1385c22e203dc08f0bac2f7cd9dfaccdec20d3b93252ad04, + 0x92f03c7e98e61c2a85943ffaf9c04dbb0145fc2055e4d5be90bb68b90109746, + 0x14956f80a65b01f9ee97e2eb070e9df2711cb8bcb538dd98e532636cc60782e8, + 0xbccb669cb016d498464944f7192ecff6716e6cb5f895d2715bcbbb65b1288c0, + 0x121d2ba5bd8f232ecf44aacf1044cd6ab6f93f1e537d7d1541754fd49f51b225, + 0x4e358f259a33244f4058a056110a26816bbec3c76ab6a5f7be93c9e0c92f3eb, + 0x2da2603a26d4fdec35318204ba5060663e15a0b1e4d9395258d5e6eecaea8fb1, + 0xef5f9ee6ba1ae1d1264cf1a36e0fe4b8043ab0bddf9b9c3200fb687a8ea5c83, + 0xd53d61c8a5214e0c4715274ad67a5d6a2cfb9fc3c1e791d41de22c8ba8468a4, + 0x252e78b4838ad5007f518bb9c6a4ce501871f71128eee3f0c9784cd64b183fbf, + 0xa27a8d1af6a0460ae1724f32f21a06b036668d0a863be50fcc47fec5763ce93, + 0x3048a265d0eeb40e5a531633ac22bb825f75cee9036e66a061be3d4d248c862, + 0x3fd94e51bbda6843d31a282530d54240aa496165d644d5d7737b1e5a7d60d52, + 0x2f26bc13ae48520a439c9f546abb35a1222a307e38fafc3e7ffc843f6c77d7ad, + 0x14057d02e5ebcf33c166e18fe904defa9e342a19e88d42336377f1c5e67ec30, + 0x1fc26ed027db7b9e7241c2c760176662f634ba05a9ca7a850e184ae588cbe215 + ], + [ + 0xec1ed3ae3beac4ddd1fdb17b9c7c648e7ec81885a07a5bcbd967e6a3676f356, + 0x2a0f77bb3624fc4826c9a2a66be4ec75dbc21642a16fcc4182d2d65c0fd8d7ff, + 0x1d799ae83ef6552f30edc47b9e82adc0503dc4b74da40ba0bbd2cc9eb1b0a53, + 0x5de1099c65f08a990ac0f1f45ec2fb872c771e10275dccfa4fce1146639d0d5, + 0xf0913eb4ee7d3c02d8ce73d1cec2b6cbb176a92129b34a294adf066243ff6bd, + 0x25a9ac2d1ef84abd98927b52c24f38796ea60e63858ec5b50196d7e169c93b84, + 0x20a0e3f4e1249c4c6af100dfdf63f8bdc69ec7885bcd0d2c2e98d98f9bb9d104, + 0x6b7e18d01b47ff8e4ef08078e8128a06693be657489492ac4195a854722bdfd, + 0x12cf87253913d45d287e975f2b4f5b909d16a87d89c889057f666f6ba61389b0, + 0x29a7d554e9ffbee639867842fd0e7d41ea9b1bc9621b654fcb398f71c95b668e, + 0x186756775058d09c639cdabbacd01bf3c2744152156fbf7e8f3e999fb610ed38, + 0x2532dd7487fcae0dc3a7ac50b80ec330c6fb6d4cf885f1135988bf6dfc010a6f, + 0x2efe529db1de3c01d6fe7fb8a71f1eaab6af1641fb1f7aad4f2b88cd13c9fe5, + 0xaf825f7ca24b4a285f544762d9defdc99f2b85c1b89fc5ff2079d3d50e6d4ea, + 0x17818dd0254b291d0d8f4f1a458c6a21d8841153661812bbe986b1403cf270df, + 0x10175fb6f81b16436af30682f36fbab396eddb7829a50e946c75f27e260987c7 + ], + [ + 0xb3e601e36a5d82e0214362c8419474dc1cc2c0ed8126534d69a3f790b27c603, + 0x1083b742d35332a8b79b80e7dc04a72f7e86692e529b6a1ec5687334b607da7c, + 0x12417c001be86197013b2b4871c4e9b0dceb83991919a9cafacfe54666f590af, + 0x2c465d9b5eb852d79338b427b3184d941f34046172a82cce44e2b8e5c4379478, + 0xa0fe66c0d4de00cc7761008732a0097fb14d6465f9d1df835e0423fb207d979, + 0x2f521f24bc02286ae2bf8484fbbc39843886755f52bfec7d3dd5df78d340721d, + 0x2f1d3eed36018f9679711e030bdbae51224b5efb8b1eb1cdca8ab886212f0fb, + 0x23aa7ccc3751b740eec9f35a29986bc958a4dbc7c4b12eab2be8376706deb20e, + 0x2b088cd30a10899babc325bba32aa343d329f9a8782469c4d25f0f237ff607fd, + 0x305a0c2c2c4d35998e9913829f5602504363f21bd720347350b604193e79bc3f, + 0x8bd9ddd192d797a19dd1da049beb39fa6596598a27031ea1c2b28966d96180c, + 0x12cee8e3d1cac1ca84517ab3def487c460aec058348ff220c801b78979af9e61, + 0xcab504b22a3573d09509f85d3fbd94e94417acb25392342bacd684006c37185, + 0x160590968429f480f55611c6448912fdf423d37bf483c36acccc1ac9a29d2a53, + 0x1c95c2917353c53b4cdb7f750a0fe86ce10f8d5bdb018032d3f793797d7c0a35, + 0x23d300373bb8ebf7dbcf314a3c0b1fdecd5cae23f7e7bb915bcdb6a6782b57fb + ], + [ + 0x163cb4e3a5ec92e57b25b095a3aaa8cfdc4ce59267718cc6090a07e14af10b0d, + 0x53e95f9455bc6499d447b6cedd0b6aad9cbced97ccf10060f3c9ef51e28e76d, + 0x2171fd11f94485466a819e24d0acef08b0c87d78b46d93bb9462b443fa40cdc5, + 0x23918075c8fa0929befc2b171f99ebe9ddd6683594ef9a83f84d4acfd9592d59, + 0x898ed1ec1a43687ff6aba32de5f819434528a0752b3928331899b0646b2f061, + 0x1dc3f7a659530a13accad181b6e265474108d8b1469266552dfbc38cb679d06d, + 0xe388bb105242406e372080e997a31392cf4ffbd9c694163fc366eae770e435d, + 0x2273c370eb5810c03903605d7cc94d5a92af6aaaa7b844f35189e77406a7e86b, + 0x19972ffdde7898ec8be4fb28e4b19efaa43c7ee20c88e29096ebe872e1c19475, + 0x61d78e1953d1943e2d968335b73e15fecef89075e96c943d39702b214ddc5fa, + 0x194184a825de9e9b63ed7a7bd071253ef5903e1e75a50536db93c26311a72017, + 0x21c0d1874decaf90613183ea827b91c1b2951839f71f329cb9c9b0753ffaefee, + 0x1cb33ad2ba7dd0c2063443432a847bccce775a8daf868e0c474905a4fa36d70e, + 0x2bb32cf60f8d469edb1b6c56493d4c9338b4051ae2514d4b6082ef18b1d5228a, + 0x2495b3c1bfec60741808149333fc43f04d79dec56582c292829ffdfb3c1a3c4, + 0xf0417fa6237167e741525261306c17664dc3efa9247aa0d4bcfff38e89dedee + ], + [ + 0x2dca90f3e5a15b29895f48d7a1290d7a33646b89620dd0a8ccde3aa3a51d41cb, + 0x5904dae3470d40ce12749b27d646e620e8519e2b17cfa016caeb89d9e34ee6e, + 0x22e9bf2aa02fe65e3cc74fb3d83d4e3351869bd30528c378958af462efd645ff, + 0x15d7fba62bac57be5d97452a3c06d9fa757f144df166479ee7306967480a287d, + 0x11e0b2343ef371d2d6d22805974f2539b6e510d761e0da170d0da90095a13262, + 0x2ba39845393fcc776fd383e535d567621c7f64005a83a6f7f48222bc902092a8, + 0x25143649c13e08d4b00bf34d2aa1a8e450f89788e27766896217047155c5bf1e, + 0x2a7310e75fafe902e20287a91abe388aae8420b1ea4660dd7c159c26b9632cd1, + 0x1fa6944703fe0012a16ee6042529ff02bc804313ef8c6d8b0f910a75e6f47739, + 0x261f975babd7692822473b8e39f948b9cf98730a9785de393179d4bb99dacdc8, + 0x2e08b28bdcc417d9643b3008085a27f4a9876792d3915c8b9da3567a6dd6ce82, + 0x17e9ed191c5641d768b0e55ec0d4a85f6e5419d32f5668d397d5b6cb805387f, + 0xaaf37d1f53dd0556e347ec705962379077cd543198e1c27593f4454521261f7, + 0x2a4a72e9dfe5bf25f6fde750a1847e5b44298ba58fb504be57a595e7fccdc404, + 0x2adec8549dffde7238b2bda6e7732990a911700c8d35288baa39e67015953231, + 0x1e8fd20a8030fdd94e2c4353d8f82b4b212bf887bc59615814890b0f92a47d90 + ], + [ + 0x2c78ee5ea16d38f0beb9dc0733c4bb1893cb33ff671b737a1122d64f729cff22, + 0x2e563b9dc5a3d4d5a93f476b466e371019c77fd6eea506126a4f79274f2f6b9b, + 0x72ea2f5cdc8a3789fbcea414a91e7b27bbfb3151df510d080ff4ef7cc73f0d9, + 0x2b6f16f812ba903901355955cc4ddb99f24f1c6e26430947e51811a68311bbf, + 0x1d59d5c10b0c9dd347899377da35b7e677c7d39ef1b49166b974a7f2bc99c946, + 0x4730fe04e0108c9a5145a5c48e60c5457e4708522157bfe0f82af5c664d6ea2, + 0x12ec24239ba1b0fc9f952550a223a52d209d8d22b8b21ac24881a2719276be0e, + 0x20098399725ee15d93ffd3e481e4a7b95c8c5083f9d69bff1714eea7c7d82d49, + 0x18237af733bc44418ac84e623f483a6be28b8f21d033fbf099d645ba20f1fc26, + 0x1e3d6cef37f9bdac23d1b381a6c58d0ecf06a6ebf58dfa7a995a443ed7df68e9, + 0x28e55b0bed59191216d5dbe1dd05b22c009b079de877fd54aaf5401d2c867e02, + 0xc6c9ec31c9e3be0744919fc555c77c0c125927bd16de2807712b35ca26dd045, + 0x2a607facd3936fdd0e84e9bc3e4b4bac86e8102c2b5ad15cae550d28b3654e73, + 0xc509a4bf48ad76e90410bea34a8919741608bbbb6b5503c93e732036f079d12, + 0x178074303b90d8985e376584b8b8dfb7f952f8f4cf84d815f90baaa3b644c4c6, + 0x18572826385dfc6eeca4d3c71d110b04abae013c5450d9e4947a3d019bb41b6f + ], + [ + 0x2af324ec4f9e7786dcf00439c75a294bff753e3292bbf62e66471fa730f19c79, + 0x14560083d980d172dd40c9426cff41467acea41d7f48ff11ac5fcc087ba2d5b8, + 0x260f751c7823abae61b8f3748c84791c0bd84acf7eb6854870250178e9a52cf5, + 0xf6673b7fb4be8cdea74aaa7802c9c73ff0d53a98e94a2bc60685d890a24fdeb, + 0x1a15b7e2de27125f2e6a74f4ec7cd2455f1bbfaeb1155f1af819bdb5fe54241d, + 0x75a09e41e74de8a2ac7fef27591e76a77c851e1a51185f31e99b5e08f01cc74, + 0x79c04944d50b4777dd0bebe953600645ceca9d65fba020f97365146bef9c6ce, + 0x2ca2bac7c1aa0c64e684123f0ffe22173923052b6a01f3c29be80137fd8972c, + 0x13d9035a0dc798b04dcef0f08edd241524fdca0e95ba9cac05d207bd317e19cf, + 0x1d6657d791831169c56b6e9a201f8b7b240246a2d0f854430489b983454032d4, + 0x1c89d8f975f0304282ad8f7bd41c12c3b18ac6b80e4065fccda423bbb3ffa786, + 0x20829ef3df9c183f8965e49c8f315c2995a6446a76053543eb750145f1a77400, + 0x14a2bd5a56f87009db981546533202f3af812d2ef4d6b037f2830853b9f9039c, + 0x199733da4aeed8d6cd148461617e8e46de22d3720431fc1605619b12a7fd4e2a, + 0x1f5fc060028ba07d11fc9477f4faffe79a81040ea9a04c568267644895e6737f, + 0x208b7c8c1ff8422d4a1bd13a02a94681ce217d925f40d2875f73def14de7a220 + ] + ], +[ +[ +0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, +0x214e865e2eabdb9fe5d563a141ce18bb254029e0e04e59c2fecb0850b5ff572f, +0x1e0e35883b0f1794db023f80354a83951383b62282dab4129db1d19e605c316e, +0x5c51080a74b8d28b50b14228c6a6de8ad5397cb9a4b9c6cf86bb807cad76074, +0x244e0857b01e7d7aa0eb2ef334fde51f16a2411abfec2c3beb6c62f7a7036217, +0x2a04852a90b74143f3808a150e9f1371e0177a1b6e72cbcb0fb8f1ddce8a8d02, +0x305a319725a0b7bf3def3f71517cc2bbae386b651550fe9405cec98dee21b1d6, +0xd92a7b009466985fef388ca3d70c7e2c0c2670d2260df83659d776002843107, +0x2a67eefc0930f82c8bc66ffad5ac09c107407814131cd645bc18cda6fff4f52e, +0x99674734918ce9329409e50f2e9041bd072f9d827737de601f09c7ade19d35, +0x449112125b3f10a53b2c465f2bf1183f03c13825e76d40af75da04b8137780e, +0x2c1ee387a8c15e7dbe92032a242801d1f7b411a7e5a36bfc4fa2749a22cacca, +0x1d687a4e31c6b3c91e67dc9d9dd9c47493c839b5e13ca1a9310e6ba011421cf7, +0x1dc79a5d9de443db444de0f08ac67be4826d018fd86139ee9eea781f4df48939, +0x2d5cf8172c587c0513f26105419f56319763c5cb42cf9ecb5e27d9a88c5d16c9, +0x25bacabe48b3f030c806aa879f25241fbbb17534d686bda8f5d478662b2a5ab5 +], +[ +0x69b1779dec3eaded3f07d0c3e6cecd6cffe78d747faedad9c90665aa2d92cb3, +0x29fb24fcfdda928bc18f54d5594a0c23bb822c277fe2bb999e04a37830c7595b, +0xc05c2d8ee022c59521bd441aa15fa2ddf43e6ef9811b10fe9640ee5e888c388, +0x122ca048d7c6d4b9053b59ab67650d10d22515f1365b2267c086dc7a168de657, +0x2fbb74d7dd4ab190e6244236580314c820bbfe34045f43ce14d1ec0049afa187, +0x2cadba86ff66600cf28005f0ac4870914118c62e110e3ae0513dedf3bd846d29, +0x30d436b101fcfc29d67d7fc4473218360f1a52bb7316c4a080a55c0d01a709e, +0x1041a8891a37452dae7c58396d225a87ef1985f94485bc3bb94588dd00132b2b, +0x20e8656cb5d68cf5f5aabd0cbc2384b00cd1b65ea77b1c0495a65f3270e4d881, +0x17107096614bacedf147ec8ba8ddbff1d99d5ec24df5495279a720144ad00dd2, +0x2615060f9b8b7972aad3c06f80079700edc591d0e701ac424203a6a7beb5931f, +0x1406d86f9f6ed52732899488e062f293c681767645a636d8f078dd40672e632f, +0x47dbe55f778c815cd8c79dac7d59526dc76570fef2224a93640c98770c056cf, +0x2dcdb0a971c5aa120c3d873cbd072083a649e903145e00829aa8202ef09be93b, +0x2bf712452a11b06765a0d8c7f0af790527a665863294a32cfa3d762a5aca3b0c, +0x12a68ac33549f6902b128cb376c2f52cff07f1279106386b26fde8fc49de31eb +], +[ +0x1fa4effc83498d19aaa598b7771f88a0554dddda89d32dcf8a6f4cf776d13b99, +0x19b1577a9e5fe67f71e733732ff6ba035dbb18d129f701a566068c4aad32165f, +0x82f3674a3860d8034eee2f705933c2ebf23a5ebc7a3d77c46c9279df8930298, +0x1011963b5e7be95fbbfa2848d56da05d6229a3f0292c50760027cfb98577a2fb, +0x2ab86635f447d66ea5ef5e5339031197ae8e86b7350744069280de59d7256486, +0x14fc3fe2445bef8547b023a1ced3ba9e137e16fb0e3645dec813cdd7e584ebc8, +0x136afe9a53acd5e1d68cfc75c5630d39701cae3744ad5aa2aa34f735ea830703, +0x18bef702cd3178eb4ba589b84783071cef268ed6828f70c960e379508b9ff1e2, +0x2c5c474a63c172ea6d6a1fa8be92e4bc6891e74e87c5a65c42b61aa42a9aae4e, +0x27e3943ac99174b2829fd8ffab17b16837fdb88a0c6060e20c3e5c72fb420f8, +0x288a44d1afb6a92a5c7dc766d4cde4874b0f49cc3e798fc25292cd13cfc4ebda, +0x2d255d4f28b56db356773293cbca39f6f9c06bc4cb5275839555db772a969ba6, +0x262650e9b1667b31877c8d79a5816cae80e222df97e48b574ba91e6cb509e931, +0x22bf34fc02aa2e215c993994c7cff2626dcb7212975f7ffcf11cd90b07808e70, +0x14078ef63c2a106c8895143763824ffec7a868e80b89ad6aea82263b298132ed, +0x1d16de8069581b62949f3e5bfc1188e21cbdf5d67a5bd403927da3a66f49c6b5 +], +[ +0x1676f5c07417ab54c37ec8ae1a8314bdeeb09964769881592043dffcb26bf41, +0x286415acbcc8aba3e5b854a6a357f300ba4037eb8b7c5ef6bbac868d1b4a5635, +0x1aef1d337ca51ca5d2c5c116a275a81a21f90d89834bd1af61b3aa6bed65c7c0, +0x17e864b0c0ebadbd2fd4f75177b9e7fd801bf3c066464070c6527f096b0b4e9, +0x2587c2ffb837fcc5be1b5a0d520f0f2145000b6797a9a5205ae30240af69c7a3, +0x2ad5b37b82f9ac35848de9a7b0bed4262b3074c8047d8a4736959a21946f7db2, +0xa32e49eccc90d7135c8c66fbb1953bed9da04400221cc606416f0db0b06930d, +0x24e2c86170a5b4a8c95066d5f553eaaede655dba90c32e485adb53c3db9f65df, +0x2e90955a65c11aa740e8592c94a983b542bf95bedd9bc24673647687c57a419b, +0x11ced1dc351f0b67b8de31d678da740e5a0c4bb1e9adb04b119e8de79e908283, +0x9de8b7bde7c2aa28539fc3f31b1f28538a766c53ca6e92a1639bf1706369482, +0x12550c43d8d9b152c039868ca4c52f074e02f31e1834978c8b554daf43632d88, +0x40dfc65f3133acc65a961dfc4b365d21d41b9e82cd7d65aa2a3238a3ac5b92d, +0x12f7124beb62cae35c093ed96975ab5dfc8e00f2668c6ddba351f458127e96a6, +0x530ae305c7c8a9ce61943baa1bfc0b2e16199a994469f41aec17cdbd7d074a5, +0x243efe17e4617bc0c20ecb5f9bd76f48a8dd796fa1058366f55826b80aa69794 +], +[ +0x1f4e7bbc8d42779e58aa07bf54ff324b814fe687b4c8eb81b9b7e74448ee27ff, +0x238f0b87f232229a5c7489e1c7edc9d319f816c21e6fe403ff65c60c1ca4b178, +0x1df906bd755c6a965e2ecd7d32768ae2fd8c522dd0ddcbb002389e90f5c6a707, +0x2da47d7b5389318990e3d6eb9f9e93eb7404439b362a0d84da24d8c715fa8bf1, +0x17c623def2d2610588b3c5dd236ac31026a16354f29b2f8a1b0955c391701f5a, +0x1c6c37b8caf25198a4a9cc93c559e73b7c90ca6df6ac721a2f52cee03f57221b, +0x27feaf5bb57db47ec317018969e6e767f48d768fb138698ceb4aad474f10fb3, +0x4e392117390c777ae93ee29db53979f4f0e168595d9dc5fec4eed18ea0e33c8, +0xa1bf9ddee072347f46524461f66c65582c5533be183c39ebc5325c2e111eb55, +0x23382c75620eda77c18e3d166fee7b74e30202ae8309890010849e1a79cb90db, +0x234c33dc7c164b187746919301403d75c58237965627738d9f48d393a44829af, +0x216ffb6e7e5316ddb852406f11331c24f717439f27d57ca15de065958ea44462, +0x21269800c6b53df048610f35d1b344e03a0fe15f0a5b21b73c799a48e4d0721f, +0x86ec72230cd5fc6c7842cd5eb4fd6b75c3051a915deaaeb61e9b22780579a70, +0x2f54161c4ccd936ae2c3edc204637dc114d4d3d6d98bd9b6d8bdf603bd4b7e72, +0xec71181ac2bd7226495ff60adb20a3c9a7636dd9faf14db5335d8c4c1ba3a06 +], +[ +0xf6b18c98fc89fbfa99a04c8c96ae5db35c296479f484b680df905d4cbd1dfa9, +0x12567e67abc9b35af4ffb381ed3acf244a2f9019839f5f8d2f0b442f51be88, +0x178391cf8f91a1e3b00f545a3a4a5331feafd2a0d10d9027c56954c8a3f8ebc6, +0x2abf38b2c05989402c75ec5263e3ac75bdbe9af0c1eb92883d5cda564ecbdc37, +0x2a2c5e5b24751e4a10e893ec2f7ab96f83a970cdf3a543b20a48357cc7ec8570, +0xdf7d4b832373582fd4fbcdf7f3c49749f6efb59fd99f4e8fbedbc8190a0d8de, +0x72011cfb8afcbd8b431269dd5d74aa99e795c6628dc1dcf6c2d8db003bfb436, +0x2e369b2dc96609f8c17a592f2ce063683d148204c2912b0e53a70a3c46bfa9b5, +0x59b27028b4f0949345ed48b3e799d1081350784e0042c994243297744e2e226, +0x222dddba5c72cc2d12f0aa37e940a09424f6e3d679cf725bd059b4182393c08d, +0x1d4f2427689a1dc5f1d7c68311ce5b0a56a961b3d42a746f356dd81fa147680b, +0x2b29f8fb4f37691d3981e3fc495ee58c25ecd758d6e24c3f41e5c56221a64fd4, +0x267bb17bba0da1b457e2fc71493f7d7b9da4ef5d13a62e525defa3d080b766bf, +0x2e6530de833c3b1d1f5bda0c6f6a244ad8288750865136dc22bb752c8e044039, +0x1f0b90c52358a8a14da112639c7d2ea2ff1df537b41227f4d3c9ebf7014c75e6, +0xd9acd7178242914b81219b9a60ef7a0d6dd0fb571609e4335f8d419ff982d12 +], +[ +0xe6cd10883e1e11c6c191d36329f30eb0045af06c2d86d0c439f5c1f4fef54b, +0x2bbfad45e5a92d2fccecc514648ba944d35abca3f6570958eda96ab2e03d8095, +0x1f8bbb7ab0780d5bf4070ddbd1b99eecde357757f3773ce6a8a33cb6d3d6060a, +0x2578863a750b236e5975de83fceb91727b4f588c453a94e40327a18394e835ea, +0x28284f2eb4ef38ef729f8637df230532e3a410186dbbe5ae5497c69a7cafac78, +0x1c535fdc7111ed734def9074724899bea8525c2571335159af33af57310a8db4, +0x29037a8126d3d81fcaadaff1995a15f9e5113b205c2f7c2d0bc0361f06a9678d, +0x1cc53180a2b9cfb4978339d086ed54c748a5f77190e30dc2879a76a107553e6, +0x2fd6d01024cdac4f279edd9fb5219b414815163b384f502b615537e03cff2b25, +0x205885190c6d00c1420074e1a4a3163c382f7193754fa5f87ddb98a393d032f0, +0x23cf89940b6418fdbed6f84bbfe0c5f850a9ba88c41e998554a4a4123d0ae5e9, +0x968d36ff2a38e6aeca306fe28458719e69ba1b0fc76bb561fed0f82255cba8, +0x2c9814c96a72fb32442dbda9249a412f98a23304a86ba9848567c5b0754554d, +0xc11ab9629bc935469b9fdb33f48f22db895f5dd5e182575b2cbbb221105fc69, +0x2b98eb64b8642bf4f5291ffce416102088b471aac3d2f80da585b5fe1f245886, +0x2ba9f7efe0d61c8460085cdca6c1bb78aa7bc086533f20f301e010d5099ee790 +], +[ +0x425a9641fb01558bc7170a2ffc24eb6a514198b296a1629cc284d983bca8757, +0xd964da26287f09bc190e8235411bb9bc9068003fa6d6ee03229dde65db07fcf, +0x289c0cb7f84d62638c2a2f37f10f30a58d8bd8b4c5bd8f5a3ca448e9c668f615, +0x6622bf28a5fcb361e0b7bdfd7fa08717b51640d05d1f6f6ba94b50d26ddcab6, +0x2aca8f7acb59233bc4d4df65b9c6f30479e9a72f5e6821860b39ba9dc4d03f82, +0x1330fe288bcb4ad27de36ef48f063baa8ab30be65940592fd97623c7faed4e50, +0x9efcc692545703bcbeb641ece624880f73a10c0d2c2e6132f9624eb5f41b1b6, +0x2ae8d813634a87b031bb08573bdf237ab3701215b77ee9a4e6a2c01c1c1d4ffc, +0xc2b9bb36e8ab693866b2885bd4482ed5c89f069b3e6445655d70f4d6687f8c0, +0x1a606372725698e7d7f3a7280617fd86de9acaf98bbd8971d8ee53932c2eb6a3, +0xa6632613bfca8afc8939b33e4912ddf18b034be621106ad695ebd5065afe00c, +0x2479769cd60838cc140a649e8937be28ac92c71980f149caaaf0100d1f102374, +0x1f925ba0001429fe493f48ea404a8ed283ab2cc2f3275ecfe320afe90426f462, +0x1231fe074b771ac643d6e188f5732c209c71b768739b22447e6b5dcf499b4887, +0xeda204f434a347cbc55ef698aefb23df064c57fcd4cd4cdd810e05ece651535, +0x33bf863141b2b9aea2e59cf6c4faf11466700aa5c383af451d403c9c53160bd +], +[ +0x397a7d7434b0aa941348de45aec442cd5cad2c398884950e8233c58dd50335, +0x1495e990865f559df4c7bd6f21272b8106e2c91cbb1a9e2089922c62b2a76ca7, +0x125496878120d9ff89d702f58154ba82158e818db90e3d12d6a08c5543536368, +0xf8ba5444de18d199aabbc5442c1d7c01cafafc79fe095da31928d776bf984, +0x1eeaa31dabd6b6a9efa74e4315917d902b02760a04b04eedb57e261fa2c6632a, +0x3776a7d69106118a4d22f86060ea7db0c9c8f3ce3ccd6c88ada43ee175cc811, +0xcef77234c42547957e950e45ad3b723735c011ef47ceee8ba422bd16759be2, +0x1cebeac557d2337e4687501f9f71fad7ecb14ad09550b52417ac33c2e8bca21, +0x6521b700ca47f222ea2e280f3193df67e1a5966b8cebffb01890aa3a87bb328, +0x100a85e6da4a0b92a81f1512710c889a29c8ed3e0695bc285a71ca5617705fbf, +0x1a6288255e7a54d4397ca40b3be72c0469bc489e66f916c1a90476816a2f791c, +0x33125b9cf766513a8e82a0d04374ff181bfa818f67ac1c7dd4298cf32b85e76, +0xf7e82720135b35277fc54ebdd88a026af545b745fc20449b7068c6865eac1fd, +0xa9f28e621172d911bffad3b5ea4b73a49a959de5c86e8ac52745d558a6f588, +0x18a93b5dbdde2e99c234253d4a49348312e58f033e87d4446945727da833c54, +0x2237324de68d18d407db3fce2a401e8af47ea8c5bc09d862d12b8dbfd3af5f3b +], +[ +0x1d66f208fc04411a1385c22e203dc08f0bac2f7cd9dfaccdec20d3b93252ad04, +0x1014b540da45955bbe759dfc9ec4bdf32a99d56cd2742d269ff8691d915cf247, +0x1720174606224668a7067c3e8c53b1ee68349144af6d6972d38c90bfa6bca639, +0x6693893b45a40bc7366925fe7978bb80fbd5b9a3ea27c9dcb456b2b04670c4f, +0x249c8751e7443e96c6e3b6b78d7f288e8a00c05f12597c984f8f0eb3f9c0d4f6, +0x19afe6d81031fe1cbdff2b24eb7d691a50bd6bd8da98ef658d75171480cd664c, +0x2034957e3fc373e94d77e0a050a8a84ba49095ffc6eb3a7776dd86940d90f01d, +0x1d65f2f3574c1fe006df2d50fed257bb935f902970c7aae131a41f2de4b48bb7, +0x1563bb61629e83922438cf0723716cd4daed36ae948e74c5c85dbb7e9893d645, +0x2f10b78f744104a54a8149200cae59e443e74edab1cc3cbc2d8c170ccf2f7889, +0x7396d51d19d94cb34b304ac606b54399e89273abb22ff7bb6b433e472ce1e8e, +0x1cbb8fa4be4e9fdf0ec9ea67df8df2c1b796291e75db4f427c843216fe48834a, +0x14e3a6920a412da81d917e7b9d98bba849cc165e406fb3c43ac421f9ade0c228, +0x2a8e486afaa01aa8eeda571541d2199b55c8f5f730ca5c3879f246c227809c9c, +0x7abc38167a01b6bc5831587de4d790de43e68e6ca9eabcb64b8af6895ad968, +0x1e825483a9f85081590c0ba40059fea7861719e2b7da11323437313b77b6a8d +], +[ +0xec1ed3ae3beac4ddd1fdb17b9c7c648e7ec81885a07a5bcbd967e6a3676f356, +0x1d8385e9787d1456bda399aa4d7f5c643cfaf25d6ed60e1be9ae8b98fbede91d, +0x2f574b85296045a2b1328f482a3ec674793ea300e0817720e6912d467df067a5, +0x291fb174e5ee77c060615a7f5a737a57d56e2060844aedd0aa86329b9b361496, +0x2362c38ea538ee898a12c6458c399d2870bdd8826307d56f03bb28e0e30d09f, +0x231713410ae9a8da08284c29b8b975410dab6f84f56475da37711345e68d5e2d, +0x2ef69fc1a737db3abc895f656811e59e7d873355b2e1342aa5134d8bf702ac90, +0xefb60fb18584fc86d88ee569da71046f765526b11f6c20099a6dcdfeebc4f70, +0xb044ec6d148637a47f917944f81e9c8b83b0c0c5ca1bd3462a4e0daa7703dac, +0x202678e431648172713afaabe2c8ea148061205c639f639b5e45d498be1550d7, +0x2a1e1954e5b010440c1679719e5a0db27c0aa7957b755ecf2c9b3571a8aa0a0d, +0x154d9e7b0dc8fa67c82016fc687836f61284431fc9d681405edfb38ccf28a6fc, +0x2a704d1d93253cb1096070fbf26d4df2baf4d92057d87596cadd063176267917, +0x2a24d4dfd6e9d6435e4ca1994ca11ad7adba2924b6ab7cf7c6a9ef5e7ef9ae21, +0x1688b9a9cbc3a63df3a2a35c6923aa0949816cb57fefa6e95d7627b7663a6317, +0x1d1caa8449da721f7c949ccdc38ec8c6134d97d7bbcdf58fa3c471c51a672ac +], +[ +0xb3e601e36a5d82e0214362c8419474dc1cc2c0ed8126534d69a3f790b27c603, +0xe6b936ecb8a59274624533d03746cd5d266e6c5490d3c95ada22f4a22e80e32, +0xd56cdd730e1401d9d7f93da88d6f3bfb8eb1fba440c552b078bb38a7cba55b2, +0x12c0b93d829ff5b9641d9f6f2ddb4f92c7a7b147b794139bce98ad87d680d717, +0x2de07475e19762eb5baccae3e88aa1493d35d276c4d05c670697b43824a41640, +0x2ea094a22ee4755e5df8352b2ac671e231c24785db343b9145f9e44297b361ac, +0x2ab4682e32feba55370b3a477ad83f30c88db387bb20c6a9b2e567f5d60a4a73, +0x1a70ee4fd1e45c498e771e9d0210dd14145cc2740c3607e044e3c68b6a6017d4, +0x20a815e19a6198e3a2f8a8bc2631c552521182f63e125477cf765a27707035a1, +0x266fe05c631b74ae1cceb24143a96e0e9fff59304f04fedcf4db3da13508578, +0x190dd58a88fdd887a0ca830681aca5949ea89050fab84b66297d7d14dcb91a74, +0x1ae686eecd7623655c55154aa8c5c82136eb56020fb8d1199aff5c8bc11eb0c0, +0x20ad4678ee812d96e544ff8e5e65d4fb7bf15cc6a524e6f19de6af983c997b03, +0x2caf670c84f98b68d05f4ee672a1388306376e7886e30bd2b163bfa7fc15b443, +0x1a336a86dd0b3325933238a53bf68f21ff35e9569fef12cbb61d8ab9c1f50ae6, +0xe5fc7c1d17854a0673479d4589da85e6e61f48cc950b3cc531564ce5fca874f +], +[ +0x163cb4e3a5ec92e57b25b095a3aaa8cfdc4ce59267718cc6090a07e14af10b0d, +0x19853b1669534b82fee656f037c33af733bed785ab726b0825dee79b629b9706, +0x1b164a2238c5e107696834ac58de1b21e49a366ff6307159dd461a3dd40c2f53, +0x2923c2a5464dc991733e46124db74c405e32b3fd9dfb2acb7d889b19a340ce9c, +0x2fa1a6b0c6b0e9d686ad60801c72955c1ac256d23c545152efa81dca6fe1480e, +0x27cf8750197630022efad9203e63aea2f195315a1d065a36894a5bed32bc8941, +0x23f9c83f88ce7c78d0c6cb8059fb86c2110c7c266778ba8169b665dafd9de184, +0x1d3ce51d11885aacc9a7a3b9fd2813e7ed602b33d3339fbd91bb869c6881ad73, +0x293f18aa77d8372bc9ca53668a9870de638a706734631c21edaddb20c4a6b85e, +0x197b9d069564454b7f26166ee1614896f153ed11f6215f06951b834c4da38045, +0x131c5cce643d2b8d9d294b32abf2c9010ec622bad6f1181e4dadba9545684bf3, +0x2556b61b7729a527f2c01544abc585ad6da9c92b3df9121f37bb0fd0c03d2cd1, +0x5a0d89380a2a2a14acb860c3bf32ab6b3c973d84b0d61a308ca73257c19cdb1, +0x24785c81f63404b46126436afb27fd2340122e9a98a58c467ff14abb5a90241e, +0x9fdc6f6ceaf2566ee3a618ac4d77e86327ef278b968013e33f0813190472b31, +0x2afc8316618c153350f4ba229e3382245c1399b2ee4aca25580229fc237f94e +], +[ +0x2dca90f3e5a15b29895f48d7a1290d7a33646b89620dd0a8ccde3aa3a51d41cb, +0x1ac11195f74d7fde657d093a313171f0bc3cfe2fb965e5c352900faac25305e5, +0x28fae6efd55d9648b0d9dd3b8c6e928c11a5941dd6ec235a9014c6dd35ad315a, +0x12e496bb2680b7d14ebabfb8797e9c6bbac68a40c8b8fd65b5dfb18e38c99680, +0x190489ef4eb4182eca51332b895875d6ccb7dd060aa364c1d289e2e1a7741119, +0x15776583d7d261c6e8b338c3b3fa4323abde66ed0f477d0355119c9ff5482eb8, +0x1370c01789f712284290ef1cffc5d33288fb504c5763d2801852b960ab98afe0, +0x786ebb71e920bd16e3ddfdeb748e040b7f1b1a0f04967f55210bae2f76bccf2, +0x15d4d2c713cf58f480500c6e5916f52b6ea1ac070771b0c83a6fa17cf6c9b904, +0xfab2ea8e500aed64630a51f8bf9ebf040073e23a3cf189638656d6dd1af86bb, +0x1338a1a447a9df2fde50aa09745ed3bf09e32e4ff2caea1b3b736a666c715014, +0x59df1b1e661d317d01a513fc7dfbbd80c9192d33adc60602b0b0b9d45e08535, +0x2f840b4ac5c9227c0a648693878cf37e955a037877bd5e5ccbd8efcfa38466c5, +0x844b5753fd61108fd7fb8a707e770af891ec99da9d5df68b013a3a87599ff7e, +0x2049ee37129926ecd6ff3a08e0632a007ccaadafd0d402a409561a2ce095b52, +0x1f6570fb39247442fc03a5139944567ea46f6f534a0214b611fd3b2d3b878369 +], +[ +0x2c78ee5ea16d38f0beb9dc0733c4bb1893cb33ff671b737a1122d64f729cff22, +0x350e8d2eed84802dfd14d7878b0b77cd9077778c41ff7733d2ce688961a4b30, +0x2aee7c9d86aeb8744b9d3bd7cec5c292e1c65cb633de0afc101e9d6fd2a36d5, +0x16ba6796332fb56050e3fc4111f320cc05255c292f34db71e816440fcc452baf, +0x14ae46529aa1f2b79da80878382a86338323f6a293adbd91cd58270513f4b693, +0xcf33eddfc73e29bbd785035283f6e805133bf1e34bb9e3cc2f915e06b272e27, +0x28f704162c3bd521df847d4a8a4f75439e668ef7816a91103158619fd52e5ee, +0x1c207d7a9081da93b7375312e4ea754523d9198c501f65638f5af885708d23ae, +0x1cc29ba8eed43aa2f71831b62eca71c1a46ab68007777679aaa8d6121faa5b55, +0xb39596ec65e453830650f8dd87d0fe8abc96cb59636252e27797920e06b6a2, +0x162ceb46008b073da8c811a25a68b56da01182fb893ae1c6b03d310ac8944fb5, +0x1f2526ae9adfccd223ab57e9de7e50f5d3ee83284a8d62a5e40148f4dceafab8, +0x28ff311d4a44251feee051511cac4832e177edc8a03053e133d206e9f6704f9a, +0x1c362078a104c738bf6c5fda0edf9ce2cac3b21eb2779e734d14d7276a8e5267, +0x4458b88b13af0f9d45c2b43df72abe53d6e9b56fafb1d0c15cd45a13d33b05e, +0x23897eb294a5fa4f300110fb96ec236f8c0e049f29da5078d1224337e256e703 +], +[ +0x2af324ec4f9e7786dcf00439c75a294bff753e3292bbf62e66471fa730f19c79, +0x11930ca8a8841441dd799a0e3e78e1a949f05bf99603b382ff771021770f92d3, +0x1bd210b6e6c2074d94d9f310d6906e81890175e675cc8dd659c287438a08cc4a, +0x14bb891ffdff2ba6b222332764a72059404e581f328265eafce4faee0637c6cf, +0xfa8399ba775a9e98ea3fc29231e1ae7177dd8f63c616ed4f4819f0db982aae3, +0x17749627adaf3ea1f31f149cb0fdb032b9c2f17c262aefa35ec1d516e577e6d3, +0x17a14cbbc6c3e70e50145daab58ccda20416fa7a0b0564056e0366be14d9754a, +0x1ff273747279cce54284fbfbb61bbd04f403afba107507f76812a645fa9fb774, +0x20edba75b3695a0f934c68c90d4ef19ccf1d8b1e3042d32362b5238b10deb274, +0x26852fe3fdad04b05eaab62ab7fe15fcfa55e0340534e28e2d8a3d8181b1c859, +0xbb7167ac0c34acc1d3e0b83212f50e3360eb4e967004da532861a8bb527ab66, +0x957401bb640d15d04d93e3ce3756b5f06f9869e51076b13d42a53be28a36b5a, +0x4d4b72c6c7a5922a3c9ab0b0154d7b12c45e50f8a237a930802e4c64cc7163c, +0x38fd3c972d8ed7705ffbf9d462381628ab654b76aedf4f4bb29a2fc6c922cbc, +0x98ff2fb46bfa9b48439294ce85ad25768cde5510c85175e073f1414a65e4ea0, +0xc872f10e24c0b992944862abd52152c0faa0aa508afb99a6e9a3d2d363a5c1e +] +], + [ + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x2fb280a1f23df0c4566f310cf31beafdc3e238a7d873fdc50655fe827868e909, + 0x36f175c993f4e409a6275e71558b9e1a0fcd7e4183891a7471ea6f987d6d0f2, + 0x3be177a0fe1bf76a94d443647e0f69c0a74cc5dc7af217762210b2855e849f1, + 0xed6491c4fd0f129acabcf5a68f01ebd10df6211d4d1fcf54ed75bf6c7cbc146, + 0x2158db47b374d9dd31d47c20844fa870005051c013941b2d710ee62e56c0e4ce, + 0x637d7b15c4259de4866d36005fb17b866227447e5dce4c27794413980eaa09f, + 0xb745dc1580e5e3d6319028050cb792ad8fcb5b1a156dfac6595edff287d4bd0, + 0xdc8bdccc8f3ddabca39be41a609714af65f518ef34738fda76e2755e7378699, + 0x1fdb7856e27d608c397fa9f7f6d2fdc4b31b17f45c8a347124c8c82ace7e1033, + 0xafff33732a140f6759bfd5b2949356a349c26c64b5bb018665e54acb329d3ec, + 0x1b1d97c16995fec9aee31a16facade0e2cca653efebee3d5ea70c0f7b39c1383, + 0x29ea18e6e4c75a1c3694bdbdb3fd274c37f51e2917f9e0b01d81870ef9235387, + 0x15d5f5aaf91baaebd34d07b9634610b85966c008feec7843fab7e50b0616427f, + 0xbd8e0c3a167d9eb943bf19f18d765230fd7d224df0645851e669591df01239f, + 0x129293724e2d76cbaccac841326365a0b92bfc00437147de6390d964cc0e055a, + 0x2d70576548941c2fb6bed6c525db5d0c33ca6c86f81db33838548d672b7b2641, + 0x2becbbc12e49825055888292d91ac7439a3cf337d5f9873c735d92e52a054434, + 0xcefd0b81bfabcb9920230f3a729ae3303943d8e396c5c0e5ca01f4611f3f617, + 0x6e47e966b1b597c61413dc4f996f1456719742257039015c9c1d0aa33c0b0ac, + 0xbf90647c85cbc82b06e3a94198e44335720b8afbdff06112e2aca505a43c47d, + 0x239bc57d7b109caefd8c614767a590a68f658c69cbec21fef283a50324179227, + 0xa36ae4cb35b4f865d7225191366fe691dd65ad5f2966b74f2adc28d26d2d322, + 0x11244585fece886e4685fc703c807ec8e0d591b575fcd089a969d684be4ce2b8, + 0xcaa7779dc16bdbf99a3f45903ace5079185e317efd5733fc7f766ce57e29694, + 0x26996b9d086885f9bd6908adb4aaf6deae8306e463250814dc66e00674193839, + 0x135e66a0ee13b287e51f5f1e8f79d4fe7ca55d9135e8921272920ec732bcdc16, + 0x233e95062085e2dec808029c59a0e8230077331e358613563788518a3972e5b1, + 0x23ab13b15889f8bb381efebe71172f91a0ad65d9f05af6b59e00d0c99f8ae082, + 0x1ede4de25a83103e2dea729f0c68a908589fe0e604c86f8d57e058fe11000742, + 0x2b5b5bee788dcb23bd488533ccae1431e3f3504e3b89e6eeda4ae8b5bbeb4c78, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x257363f01fbb108ce6360b115eb038270946eb8c46b6ececd68596765ed894d3, + 0xe06611bd4eee1605582fc2f0a195524e57a552ff9f2c76832189c382d763944, + 0xab70fb6823f52c277b8dd4ff261d965a9427d34af4afbf19f3b24260c15f8e0, + 0x179c941d644d804a3a4068884fd1c6d7a82d411d4698c91e1b242966d3bbdab5, + 0x37f916e90d419042d297bdc952c7cd02746cbc188149a51a0987cfefe0dc13d, + 0x43f3dc3d91b0abb531882dc015e1d9d05dd646d42dfd9f4c1493a085cc00a56, + 0x143ad19c1249acbef488ea0a074f56afd3f5b89666235cbf8bb5e6fe44096642, + 0x1b76610fc8cef2eb0f4fa76df7ce299237fe7b3a9d024b7d405ec095719c4279, + 0x1a5148d68913df74c872a1ea5aa4b542b3ab1b9c0dda2ec220cf2bc36d69ad59, + 0x13f11022ed02284972037000666e2d3edbeb9a5350c37fedc293be998eba32dc, + 0x806f266e4c35c6f066925ff73d6abde5e46f5bc55b01015db95162159092a70, + 0x2e14cdaace09d09b49d437ca48752123a6efe3c75660218f408878871d073f64, + 0x1c4fa8d7c6c8eaf33116df7af0abe56945403e111f0ed36af029a17a88027839, + 0x23436fd3d8d48c7de5ea32899d09e601877896e044051e59d481f26c6f44594, + 0x437191fdcb2c0fccb9dd2b70155e1e3eb91a104b14235a84f9c7f715f666b10, + 0x2f68a6ebb5daa3c1c0b1f8e1cc3ebbbb29dae51f21dcab1b8f24f30e52f6a1bb, + 0x2d82def6705911bbfa278a38d385fe17c9810bcafd7126f48ffbbdd197e1fec5, + 0x15fead0f7cceb9fa5a96b903121d234539c447f776bf13290f0d0fd9cd776a63, + 0x12390ef95e294ede3c435f9f14ae4f121cdaaa6b5de4f3f79969a8f91fb37793, + 0xa9f6f1757a4b1abc8e0a5b0fea83cd2b8e565105fc6d52e692dece89a6c11e6, + 0x996db2a2060b0454ec8a132ee6d810df2df49031ce420e4e790c723f578bd49, + 0x2670a74f37e6a32596938caea3cec3e05b337ced6c23d2bf2ec5987dfbcc6905, + 0x28ae07ea7a529805d3aafe9f5a2ae662f908b17f864ab59b98452ef28e3fd44e, + 0x24002c49771a2fcb63c046d1507b8b2259b4eff63a7be958329f6319fe8c787, + 0x2703e03745ed8810cc93cca78ea613cf39f492180d6ac47300e4babd4f357dce, + 0x22930293c333499085eae55a01cbf8c32b04d211a0709bd9b758f733e2ed7b7b, + 0x2a0ac5d7f2daa3edadbdeaaa440967d97baec637cf48a67a36810430014a902b, + 0x25fa48cb70003175db4b2241e6bbb08a9d30128c86f68bf6e79e9a3dd4f3f4ec, + 0xbae040ff4b1f63b97474a971446b680c23ff4d55212a99d03d1e27278770016, + 0x2fa5db728b6058cc42348c90267158f8e76ab99c646e66664dc2b93963218e16, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x114401a4ccc83c86ae0fa520a3ebe4478fa6d7c4c634b4a6503da334da8404de, + 0x1ca6273af6d2e51a8b7c2ba869a1bf10de7a5b9786ad947a02c2b1b6ee821274, + 0x2c7b4af671ec5fa12531b63b511782f1f46ee5428b9184d960caf0deb0e08d03, + 0x1230182c434b2175e9362b023e55456bf97d514e5332e4753ffeda60f5d97b0b, + 0x22e041c288ef26f1d07c86d6c24f48eb041d83a8260b6772892181e2120c91e1, + 0x28acbc69fbf7a25ed38927ba63cde5a18284f26ad6581317782219221cc6bd8e, + 0x2487337fffaa7fea6440fb59e8e888c1724bbd1f1118d32ada6a3651e46ef543, + 0x61f4630cd8a70b5c6a1950def1f7eeda1d2cfd750eac8bcd21d0928d54503db, + 0x3cfcdd58420e81bfedb04dfd4e5b57b03eb8afefb5963b81339d92445458b6, + 0x1211f09c601c31128561f10ffdef73487c927091f10086ffa889eec1378757e2, + 0xad6247ae3bacb716899003f881ae2cb44e40ff4863dc07a400bde10cabc91b, + 0x161bcf48d7d37906ef29d522a6631e22e344ff951be2f5418c1f58ef81106949, + 0x1615caafce9cf99656045f01b9050872d167219533072672a6261bdafc405e27, + 0x1f1fd1b64c8024c19dc4c906e121bc5023c76b1c9610fecc02e009e384fde164, + 0x1a343f06c742b6ea01dcca051e7f812097250e81efa506561817c2accde13fb2, + 0x1aa5ad37af4cf033774e8cedb40c36cc1bf2fd2e73c135a2145897e255644ab8, + 0xa8e74375e1ca92003153a84d2a88b38796905e42f05a2aeaa22b6174545679b, + 0xddcb524f3d1e36d26523b37e7a7a565ca7aafbe8b9d7d21805d79b391345944, + 0xc64669d92336353367ff746030b946691eed63a8710d15b44907913558ea892, + 0x18663caed52af3125ff734ea821f2b1c0ff63e253eb8df61c23998b3852eeb2b, + 0x8aa2a6dc1acace95ae99cfae9f48a5edb8d91e6be62ef97a8e48f7bf9d22cc3, + 0x1d810d45be42ede9157e37dd929a6b74d0ace0e72b96d6f1e048532027613e9d, + 0x2cc11816c46e64c6e7135d72c00a7dce65a7614cbc164dfca2be624668a51767, + 0x6bcac935d9e6233eee8555d901d6cb0b5a18e0baeb0774c42bb2c2216a8d3d7, + 0x81f422bb15ef7e9b57b79cad63226fc53cb080e6d412e790b5051b5adb01208, + 0x17233f2458d93db35c213a72c969a94aaef62fd6a76435c683129a9795177bfe, + 0x223c464793888525ecf5d3c873cdb3a6bd67587499a00b440d924c2fdc45f640, + 0x12ff515ef3e169b038bbacf953537c2b28dbd1b5ba3fc7a26900188aef36e2e7, + 0x55e0568770fbc4c9b3d698e621b1980736ec4259f0b09d9f1e820f7da4174b3, + 0x185b90addcc3b674ecbd0987f9480b74625fd07c91bdcbf048a647d561c756cc, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0xa4ab29f428a1b4040f5510e8b4f10494ebdbf12885955ce937a17360b4b295e, + 0x2a64788ea96296d7253a3a9e357715234f9318c08376c15de69487fbf9b0996d, + 0x2385278678bf43e06271b87c3f984f1b425b166ba786b2e1e723739a6752f6c9, + 0xf8d204bcf2efaa0866818f1c3986627ff998995317a960b56d8aa3f5c10fbfd, + 0x2d07b5bc553344a4887dc8f3db5858e5defda22caa9a6ccbe23e3332ba18aadd, + 0x1e1a6765877cb93580433e025985f80aa19c9089c17138480426bcae49aa1c7d, + 0x15f1a60617344d29b6da60f57ced335da1dadb402ae9a56ebad3c0aab3b69e73, + 0x6be01da4de9af6b0d2937bcb65697fdc23e8bdbf5343938315ef4dbf045d914, + 0x204479ba44f6c6079df123ba1a54e248db6d4d0480393913790ff1f10b9ead7e, + 0x1967ca2365849a5ba9abe3419797885af9736c42439f1481862a00cb4c83b24b, + 0x37b78ab4c6c1cbe83f197633c4c83e22fd38219786d9c5744ed4224eabba54b, + 0x21202d9fece3b3517c2d5e79e8a5b47824fe47658704341ba7bfda3a3414fc5a, + 0x18bd7e46303c3c2a31e68492472578708a68d1d6036b961650057b7d1ce55eb9, + 0xc5f32f34e129de8d01bf9010b16047bb2c2128ee021fce0ae2c03a2f0b20c55, + 0x1ea1c77b9ce7d24a4f32fff661e414f0793d9c4477fcc5a577b0e5145c80671f, + 0x2abb7ec37e2a52a09fa5ba144d29b8fea69efa205b4690330013d2da27fab6fb, + 0x196d47ff262f5a90329962beb3c403490547808ffe4fe96c699195d9ee5a2326, + 0x2da5dc389b073e52f92970aaef0d061beba25bbe8520b781911858598682f57e, + 0x2cce11343f974369dd5fdeb7a8a796d3a83feedcfa0a78db72dbb789bbe1d847, + 0x131262e283cf0b05fef60886f32f084a47755fcb4cb7ccc4c689e4e7f0437b75, + 0xae1188d015d3604fb38931c02d790fca244b8b284d547b62fb03f98ac887716, + 0x7579345afb1c183eb92a630bb7d061969cdc515414bf9399797d7413f8b904d, + 0x2429aebe4a674a80f0a8ae9b38a3f253e45b897ae71a7b5d0afe4fd77d5d8769, + 0x1382b92a6c573bb195a953dc0c697bbbf30dcf6806f6ab2a5f7b500a80052de9, + 0x1d182578837b58b32dd31a315254bb0a49b04b3d5ea49d582f6426637be87413, + 0x2d9888fc8880aa1e4b265cf60218727c3556ac8d31b7a3dc6a1dd5d51b902207, + 0x28fab72bbb99f1a6eaf2040a74ff55e87c5a48c2d392a7752c76fd2fb33e3390, + 0x2678f1ceacfa8e3b48b5eae7f060021a4f58cef56b12d52b9f06a09e4eda55af, + 0x1f61d359d1619ec4ff2f1eafe57827c9316e10754718b9f51b36c71979cc448f, + 0x1a1d9f64b52be377e509d5a57f004bcb6db0edc85aed26f51581d912da30e95b, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x23884cfd0f045915025a44e9bdb14491e626edf74afffee874c3e4d125a4a177, + 0x285d07475f22446af1515c134b10ef890bdd927d0328230d6374ceae21e5f169, + 0x353d664345c344fa26ce90da4f498fe33a62e8c46e7e05b47ce11b669bcccd4, + 0xa5f24df76f39b004c073e1cfcab0880702b9e84837cbcb21bd002e2449ebff0, + 0x12dc4fd8b792019288d665292050cf58bbb2c55be723d6678ddcbcf55cdf5c29, + 0x193f04538e44b693b5f03c328610092e8b253895beca308625b8bba24229e6bb, + 0xd40fe93ed90a0196dc17eb24b05dbfd08a2d9b85103dd44d887b78bbf08251e, + 0x1a1e1f731268025c10698efff9a1898281733296a02ec2e4286c0aa9d766250d, + 0x27e53cee0536c3e96bd4b78d76b1b99d611466b687c60dc5242304cf2c7f04aa, + 0x1e131e762835f631765d6a0548f8b99786b3379a5423669f348e63c1a3cd4057, + 0x18377b53a6b68420631a509767ab747af54ff52fc6a300f6759e89d0fa81f62d, + 0x2b52851f9a2c117d24b7b3ef861d3d98145e18be0ab17461bef9170dd124f2a5, + 0x203131dfe05f4f3859a2962ce2736f5f665679cd543440e5bbdf8c9e468f8f1a, + 0x11ba7216dd386406bd1ee9de577c3015b3b568f612b79d2b901955439b5f47b4, + 0x6cff68dad82139580b6ee40346acb41a1b88e34344b1ee124cd845ba4d8db12, + 0x176b605012f38593df0d0e12fdaba43a024327554f045875a394ab6d66596693, + 0x2bb40088a1add8496b2a0d0774c06d99000d9f7f5e78edefd8267bdc2602823c, + 0x6ab5edcd1a597a55efb6f5f3028b5d46dd1838af7e0a7618fabd206ae02db19, + 0x1ef4d4d25e3f6731401c06e2327e1dcdd251e5d868a49615d7c9e671b74e52ba, + 0x1132917918891833659ae5aa5d4608e9ee52f8bb8c6a15af2bb6c5b2538ee108, + 0x3ea727908383eb9c0c5fd4c8f4477c7d7cb3887c6b7408097c2a099ccdb436, + 0x1c671af55a23385b16b41f93bc5c9df9244a2b2917fa26f989936d9e10f58965, + 0x2877b09253cd0233d358dd5c03a15ebd382a94f65bb32f81a409c3209c83dd16, + 0x120ac765f71527adaadbb9e91c78bfbd17f30b1c5824bbbb6eb82d2745bd3352, + 0x1c2a7fe3bb93bafb54e3a35f4fccd2685dc5a59ff6b9e76538f37b7c79110633, + 0x245676b487e217c63beeb368b204d8fe8e5e051aa91efdbcf6854d9d5ee8aec4, + 0x1a0f4f24f3fa75b07185d59f382ff63f277dd1af0a902f7107b63fc9f450d87e, + 0x174bb5947efa62f904759a2e85cc92c84b797688ee8c2f05699d0305f6a68abc, + 0x93051276353b63507c05bf904de6f8d971f7d386c1748053840b7b775beba02, + 0x20110b96b513965874eec9b57166abe7a71dbac4300ded7aea9eb190ef9b082a, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x17a51da68d46000951b06fb3f9e3d5b83494d28feae75a0d77381129d1b5cc11, + 0x19124aeaabecf4135010e1a965341e48ca4fdb7b0cd507710ce685bece85a51f, + 0xd4eff1190530bdc2e0fad57504ad2d927a0d5d19c94424013818bbedac93ccd, + 0xc4e91e3b7cef308d9d42940dbf9a496e5e23f954bbf9cd9f6a141bc043c89f1, + 0x2a91fff770b866c8ca8c530d786a522131c1526c4694d8b7b7ad3ad8678c6140, + 0x211b948fb5c8a9cc45f8dff7f19d5092c441a1749009ee7b0d26d02d15302df7, + 0x1e30b1031a24069cc93961bcbe7ae460663d24ac25b376fa8d2a8cea3969e66a, + 0x18b82e2032f53458de5b5b8f6c69d0f59033e0e843d3523a0e433aac75004ec6, + 0x1dc22b5bfc2732c1f3481351752d7895f5594716a57b22de0953d8675f35784d, + 0xbc687ef3b18a77ed8495a8838fa82e35a2be17ae2bba47a9f5abaa26021afd8, + 0x2371c26d8f7425cee8f66acc9f647d889b78a20c02fef9bc8e65295536d55666, + 0x1477473a9e49c36a60b0415dba5e832e23ba2575682cb706c5cef38c2ee8b9b3, + 0x53e482959dcdb79f52e64a3bbe20793fad3af4f4d052c0cb9d36dfa396bf4f5, + 0x1f1b58b95eaef51e442d66ed24a23e300b3df3032f45040577402279da01620, + 0x141411af50e95784b5365ec3d4879e78d311c06d3b031a47b7b1989ff8e2a05c, + 0x2252323b3ec06cc62710778370917d94635eadd0ab946d83c7211df2fd18b12b, + 0x1f9f09cfcbdcebaea2b1053db41f39406c4bd7c08d69632e5fa88d11d8db2ff, + 0x69d5da11e6652375d70f87ebbe9b7df0addda9634eae09990b68560ac4ed710, + 0x1978e5d647456a8b3a66edba35753faa93e3f3af1c89f418aea0f68bb513a0c8, + 0x25d9a4e603b812f39a20e6e5eb99c0ed2845d383b952b42e23d65fe68209f458, + 0x234b43e3517f8573d5b4b6c905721747501928557ec4165d9513940880050221, + 0x3e66cf2636881c8a51bbb3532f0ee3abf099d16c6e029eebc7ae903a9b74d74, + 0x1e98f8fa7b0e98762453c23bac6735b00b4fadfe63c0448be0ce344456b7f189, + 0x8aa709b54a8df091ca048763f4573cf9917aeac083ca1b7f7eb84c060d0e932, + 0x52c7ca7fdca9ac2cd344a294d322f1d71d1384d5e0a6f44d0ac8b34e6aac4cd, + 0x331b02bc917bfc6691d8d7f52eba08a5fc3f47d16f02e440644390c39ab7361, + 0xd898949994a6f263a9f8225ca5d4a118b7955a4a79606262394ce69d7a7e127, + 0x10b47b130c16007b5379d744a7bc19e45f6d92e271a299766420139f20a7766e, + 0x1132f014fa7599d744c6d40d1be4ddd44e62b3fa4bdc439a48ca4c08caff36ee, + 0x1c5e38ab4551aaa2ab2ab5b69f5d6478d668719523787df968bec6e67c349a0f, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x11c9a8d1a7cf032ef4eeb3976cb45ab2639e2328e018f2450eed36a42b51724a, + 0xd68b0ef4859a99d9a3d358f48ec049222b4adc40f5211420ff9792d3380451c, + 0xf7e3fbe842d222839a6a28926d2b7dbb20cc776f5cc35ebe6de1972a8061070, + 0x20ee52f4c572121f278ca8f09daad2f1c0ef8541099378b0bae1913528b01102, + 0x24177470839e90548fe652abf877b6e788dfa4e0f4364a20487089349d2b14fa, + 0x1fa98b63c69a198ee335de75179b230861470a0f60459ed53930f592106154b0, + 0x18fed7ca1d352fdd257bd8999e955d46f48c3fb2f67e9c8b29ca0fd6ed5cc4dc, + 0x1e4afb9b1400def427a1a5c956e761be43bc3d15ef07098cb08bfa994e5c69b4, + 0x2b8b851fafcc041cedfa64521f6fb53a58788b5b166da469192a1d5aaba1ab06, + 0x91cf8ac82b6d84be9f81ac1351faa0de2226260a1019d1dfb24437ca34325de, + 0x6f7d61897e3a765d4e4526de3cc13b4c657cc5ec81e08388c41d94a808a9a5c, + 0x2862142916a2c23432ee3563951c646c4de7552008c928fa13ce3e3501ed8af, + 0x2cc6cc5a7e65d688d27ffcf1c4749764e7294c23d0108a57b29af443bb93f5a1, + 0x140d2a34847cb9f0776176010d8070cec8392f612f3573d63e58d69a4c9565bf, + 0x19800afc9d05a5b0386e87a855acdcc743a1c80b0f71063d56d0f4d6eafed03a, + 0x2691df476c22b56f9d6d0cfeb1b706d66a1e41e69de5f6da9f02b9dfd8954d35, + 0xe3d1a370a2c113f55e8be6a59667f72e0bc9018c6c2b7dc154de2ada843cf99, + 0x422041cdbb99e9110963285e90c233f1843361d8d36878b2b2425ecc9ad1468, + 0x18b3970150586c60e36243d9f787e9cd234ae54249bd47d53d8350431027541d, + 0x2608a620c9370842cc1e7eb75ced965212717b22032cff3a90f1916d5d6e4b47, + 0x102e638d33d73cd137a4bc97b16ed6ea8ff2114ef025e123a47fae1209212fa7, + 0x81127c379d08c86b6283e3ba2f7a163f156ff1efbe2d058b68ff1d8198115ea, + 0x1003330e6c9bb087c4e374163f1d93b51ea2747126942a891b93247dc3b9dfe0, + 0x26286df4b90a6d6a80afeb845b9b574c8e114dab2b23abd4d92c90d05611792f, + 0x2fcbce3693a0f365c77f5da41f04606747334c0e21ceaf4719a9c6c55a6db034, + 0xee49f7bf8d9a6b4657cca9a553b12ee1e0375a2251402b6233f14b3ae43c458, + 0x1a9ca035a5bba9e01a8339c07711d9c5e79cae3441f272af3e6fd0fa56889e06, + 0x1202f2ca7d4f98e448e3cc47113806ec2f94885d536976db84ac4f06b7df6567, + 0x89a14bbb8f0965a914cbbf83049d95598ed83fb7aebbc75a4f681efce3130fd, + 0x13488f3b0456524d4982305fef6e6c81f959a37da7bbafab57f87e8a2e3f264e, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x155c91db5f59fd8ea52fff20993ddc3285ecff97ce2ad697f4a078e8440361e2, + 0x5c61ec06f5561c87256ec21c6aa92ab1d3dce01496072af5c5081aed70a073d, + 0x9849dc13d2eca871c4dc1d117cb0d5eb5b1a98e63a1821f6e0895d0109138da, + 0x133c60ae1597bcae3f030cf1a3ef515ef77f8dfc0fecfff084411ff40a6505ce, + 0x120e93850c13de3d06be4ea933f3451cb3d4836d55f8b65b30e3814a1eac7cbd, + 0xd29374214e1a4abeeb8d36880e6f43a2a899b3bcca7ffe0fc1482411439cf27, + 0x1650118703315ae3ebf1b4f5e333373428251036a1245ace4134f4c9bd3f7a91, + 0x1853287541cd687bc66770237fe3e86db9c98208e838ad1c9fbb3c2e9f0d2f5b, + 0x845a0b9344d795ba81ca6dc433abb5b9d1e083d460254569573e8ee3e9da5ad, + 0x1903d07b2722c0dc818dda893d74a9ee7fcb8b01d3b24ac9d7604c970f68e002, + 0x2b153908b83d6a3fc4b9406f891c3d51ee429c8f6906c24326de4baa2c22d6d5, + 0x1074ad520b1b0be2f4590ce97d9927f4ba582fdbda90f73810e0a75475fd0d47, + 0x1d7a66fca345168c4cbb549ace2478d1e8f0a1906cdfc1c95d323f99d6602f2e, + 0x7d8e73fcd6a35b2d8390e56d670b9ecda356fc1da46551b8b4e15380f8cac0f, + 0x24398fe811ccf72bb1583121152844be014995a9c213ff371d0302d402a22ab, + 0x303c8e1b06ec487e715699736dd043dd4a6308ea6264525634841f4fb530be1c, + 0x15186cb1c51f7abd9485ea9ba77cf8fa72584dbc33f909e7e04b01ec550784e1, + 0x1800e20927198f24e362f7719ecbedecbfd8bf90b0aa0f804cebd483ea950dee, + 0x17b074100a4dda67b9e89789201ba089d0dc1553f4b75858f689d7f9f2608258, + 0x12a869d6d8348519d11d32e678bacfd6fe20d7b02422a1e63b958256e786f4dc, + 0xd400992babe16a1b5aab5e95bccb91660f22e401082eeec8a2a562cbb098832, + 0x67fa6a735e49401ad6d0d4043563326f8e063be13b28875f6f4a9751bed2879, + 0x8aa46ab3986198d493b9707ed84a61034da2a8bd1224c5ae8aaa3a839cdb114, + 0x7d061661185186a26c40bc3d65c84064b6819dc305e3ea6df08716f415e6be6, + 0x164b5a80cc2a390326f6062957d7d325ac244c8c497448f4b96fe6734dbe3058, + 0xd267132ff50a0e61e859189065f6bcdafa349aac4881cfeb1b0b68ee179981, + 0x29b34d0febeb62b856aaa548a5a9b7308936bd163a46f67f972d4cb32634b5f8, + 0x1b1dfe465e4578869a7a113457037d7d3180b6f8be40346f061524e76f9c7812, + 0x219d6d65c86a3850cf3648d981b51681ac8e1ac0a5d4d2646b780c9e46895f0d, + 0x1709bed140c96224597918a6d6e056c2a6f80c4d27dbba0269f35966aaad986c, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x1db013be405e1edce86acb997ef8ea68ad542ecb25ffbb8adecbb9e323e9dc4b, + 0x4672cb42f866056fff733c2d9b23531608c1b541ada0026f292d08230520f43, + 0x213116708c620427db2bbc1a422b8dbe43c50614ea1ef82ee32a92c71ba78715, + 0x1810bf41c304da8f92060da2bd4632295b784150716ec8b59a3a663925fbb556, + 0xe60fe1f6ac34ccee378a7743a96cdc77f27e36027f3ba4439f599547efff8e1, + 0x150fe3d5f19845673753c10d21683c39d806ba8b4401785d8b993d5d1485370b, + 0x106f91d87819b33c496345bfc0bdbaf0a4a6da037e2ee628a609716b120378cc, + 0x27f058d01a289b1ab1bea5dd839fc0db887d68fdfc623085c8aaef5a6cc2a2da, + 0xe0dc820be1b5a101b96f1536c465ce27a96436616a4fd1580c31e3f0be69d57, + 0x1150f83988fd71cce9335017391d240512eaa73c15f11973c28c36eb4be580b6, + 0x605b14fe858aca1b47a07bcafecb571d61c2a7d3f3559e78be31efa13632624, + 0x18579a82949ea313f07863f545e5f5365a77926f972361cf7104f2fcac832318, + 0x21b2b1c8062f7650217eb2d090922460361e6f0777c227cb685ea04e70393062, + 0xf83178738a3442e7e4ce6bbdc1750b29b3fc752d8d529d8b28be179f2808b8f, + 0x259a80dc2ea8a894232f5592feaa42db627973a90f50443e08bf743273eac236, + 0xaabc1bbb9251a3069e43205b96a072e8f69fb446dd7410e4819d6298e47cc95, + 0x18f44db51f091bf261627ab6e0be73c16b257fc358b36508627779722f45ecae, + 0x2cc4a9fe2f5afe3a0ce906c8339748dd29e2386e5ce4b5aeac22aeee17c3d79f, + 0x2c254dd92d7f002da3661a83147bcb7ede550313124d99c6288cfa538db4d904, + 0x2541852cd7c4fbea1361b129e8901ca32d9c4b20b7d51fa12c87a074a7fefe31, + 0x8c2f801a82520a9a121ffca321896ec7ad60ddd9a50b945cf3f430a05263413, + 0x25dfc7f152ac74084d93c2c517b91857c51a33f8cde248d393fa1c326916e93e, + 0x29760a2e5d63406ff254da4bbc97152ac8a6a38ad087702e594955add5c50d46, + 0x269b6bb00705c31e909147f919817dfc81d8b491b9a76f223e56f81e64a9527d, + 0x1a02cef4a79e0643edd8bfcdf61a009605843c26ebedb1e9060473418f75f0b3, + 0x12c0261d1e3b247b69e4582b3a80fd958762b0b3d3ba914a52c9e0be24918f0f, + 0x263f9acdeb8b3ce3ac83bccb1918a5d5fc712680a72fd8cfaf5e1c6712674375, + 0x207434df901289e8916ecdff56dee469a913970920c64804a7ed8a26f927f177, + 0x3a1c03c9f1fa1b8391f32fcbaa1efc6ff4b1dee7f377c8dfa5135d38a9c3ad9, + 0x1249e6129ef7507c99a866d902312d3876998ad9f62ac34454055d8ff1d352da, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x68d6807831b6e785e77a20b94dfbe5fc6c23484310d36a9fb74220671804ad4, + 0x85b97abe28e068ee5ef7bb4ccd81fadecedd4818c5a6c9cf4f53dd4b44ecad, + 0x2d2caa3b84f92053cc406a11ad2985c860c57a75ac356b95a86a83ca504bc4ee, + 0x230561c2208c63a3d10b95a64358c5bc4d68d01ae4447b5c6993c8f6132031e8, + 0x151f5672052113e6f14ddd32c28c71436daaadc71d57d830ca551e770c5035a7, + 0x2733c9d71eb1f1ce45ffba8efb3de22aef7b84fea901bebe793ffcc3ee20cc1d, + 0x122c0d0a07c233c687e8156be1567492ad00e6c48ff395d98541df9044d26051, + 0x2844674637b223f5779e688bb8adf49dcbcd9256d5c314a512707b24b7ffcd53, + 0x13a9188517254bca715d460f9c6f183ad8bdb5fca7770277117e9c477d0d3de6, + 0x1ddd8eec094dfacfe2f915e62129fcba3601daf332dc8e248b4d423586ebcd69, + 0x15f2e0c38ac84bf50c136e68f78f913f74562eae48a2c20820841a471208d051, + 0x1dd71e73cc0baf4aca734d106ac1a48cf85f182373d81a854575e65ced0dc73e, + 0xd3682c39a2dc0c0808498cee222076cfc00f11da2b929fa5e063ebfe307dac, + 0x259708945a214cbceecfc4cffd2905b0628b3dd3fa652f3efe1c2af12e8732f2, + 0x71baec7a429bd060593730c150ff1fdfa050aed0d708343259063796e831195, + 0x26865eff75e2f6fdbc66213ee03b9455a109aae2e97cce07b9319bda64cfc6b6, + 0x2864c12ac61c22d4f35fda4911370070e8b588a8ee4a82a89e15c0f1a0e2d7bf, + 0x2758b8b601674ca5f526d246d221519ec40a0498db997b8aa855545b3659127a, + 0x9002afa8899112493dca6ca6f5c6323db8f352008f7d18a048d265e8cfebef9, + 0x173c758aea38f6a7812683a6fa4589e1b4a956e8974af260ddb057519e20f7bd, + 0xefe6d624981ff5e0b45e575d0b648600bd184973ebf9d9f653d4a5a8ba17322, + 0xd14a691145b25ca49c49605c64a9bad81678ea4a4e8b03fe39321c87f09e1a0, + 0x247342aea19afa49a8dbb396dedaa253930af22b2d44fe96cefd464839482abf, + 0x161febe2355426c2fe883e58dacff6e6cdc5ad5a65b28335275feba43df71f8c, + 0x2dff5bf2cea76d0888dc40cdc73f00e3057e6ebf33793c8551e211aab41155b5, + 0x1e6b6e09f8195c35767dd23c82ef5d8862ca77e999d65c69d8dc6860d494e81a, + 0x3a8fc10bf4a3949e8469732b0148594cb3759123ce90ae3e692966e31040c61, + 0xb185f3d4ca214b2e833301ff4e99b1f9ed7179b41191c9960797b39776df2bb, + 0x1ac6b03901fdc40b1329bf3873ff9277c70fce9610151a0ef7921ed08567360c, + 0x2beb77187ad776989902a94d06a98deefb1312d0558513c3dea6df48bf637ea7, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x149e18f1233f506859275485cf5fc93cebb94ca26cde5d980e6fa2c34a2f7fd6, + 0x8a54ca25cc50b034f63d2e4d10b4c735aa759c422ebcac71f6f73c841976105, + 0x1c1210f2ce34c2958d640d0a0aaf146eedfaaaef0d37c0a0caf671a8332d34c7, + 0x17bfdbafe9e56498cb3d7b15d5cd41ab86ecd47895701cd2d6f26526aafc992a, + 0xcd27920c0441d98a8992d408c219f85989ad1056f9692e3db6e9e4196bd6d10, + 0x2dd7fb93c20805f91565bd67877e3a4ce43ec79dc435f8c7a85e82c6e5d16375, + 0x5b1e6892ff615742f728d3c0cf830aaeedb93ad22d870691a96d951dba7ff3c, + 0x831d0a313ccfd57b1cdc9f30e113c29aa35e574b1f55321ae09961b87b6d31e, + 0x600e0c844243eadb86618043d2a618ea1f5ed77f1aca63f5e0ef19f6ae09a80, + 0x5f0c79e16349cab481128d04a0cbc80b90c2bde9884a94c41ad1b0c4f868018, + 0x2aa7de5705ea010daaab30b3b20cef0e74874384af31c04de33a4e1ced8e925f, + 0x585493b750ddfe70e3eb6c9be7e72b18e65de229e357d4782b17c76deb2f566, + 0x2848f8e38361bd5512352609d7806af1fbc6b1fc285b1c761a78baaa68ff5ef6, + 0x2848a529d4f7cd4bf115528eb5e88284150af414523e25d1c012f38842d7a117, + 0x30aed4fbdf98cf0212d56baed9bf952466b5347667153e56bae4b0650d8c708, + 0x2350edbb556ef46cb8c21bd9841af642ff8b3a399569aa698ac63cb317a280de, + 0x2ae5b47ed7dbdef58bfa65f573639845e0677877926e63c9929e47338e4cb926, + 0x26e087a50e753431ab4f1ad7dd65cef00d9da6058601b8525a6c517e5259ce48, + 0x159d260467ef69e897f646782f03c24d7b3e1dfb3aeb48c469603f51cea2ac01, + 0x1e6059ee0ece798edbadc0f3c244b4bdcacb5181e9e470d0591fd8cc3c8798dd, + 0x21d0c6c19bc6bdfe12717c533169baf1a57e61fb65b7cb76be2c1265c2c90eab, + 0x96ff7a0c18ef35be9bbb3e0af410e1e4b3b902f38cb838150f8db8f034f96e0, + 0x27d16991da4e246fd333112d5d5092cd3c888d8ea89eb4ab90f3335f1e11fb80, + 0x8a1e7d8bc46b6d0b60d417e4894bdc5ec1b0da7d468cdf0f5b672544145480d, + 0x1bbb994d74d79b698beffb2c1360ad7a5da1bc9ed065a38072537bdf998d4ac0, + 0x6eaa75b2b8fb3757194332442bbe246a82300fe3d9aeb52548095747567da26, + 0x35066f49fddbb428a2316e56cb7542e5ee63e2b84a38caa27f5c07e37f0d514, + 0x1a8df2d50679834c0d1d9df72b6a33e1ff4d1a2a02659b635f3908b60411c8f, + 0x1a69f234855f2099ce018e287b94696abdd504ffdb8695755a89aac7628ec4d7, + 0x282c66cf66f278b3c8f0ed2e1936887b3f4a41968af38ba8435b4dacfe4fa1a1, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x85cd4807b25336e1ffefc9b4e5d618c7aba4c4c42e34b0ab5ec21f1e264e3da, + 0x1df72bf6d33b417979d0abc3a5879c9c18059bc954a21b1753f44c98a86531c5, + 0xed29b17ee6bc79f0d0da95407ff87f10b937c1b72f78ec36499601c536e027f, + 0x2d8f67cb6abae1b1cfe21f91b55fdfe5e62fa2fe3c7c2d61254d840c2e22d0e8, + 0xc4a844d33d7410ebfaa0be3c062b2876c22b8f4e6a4459a2942eca9902f72df, + 0x1597f8a417fa1c847018051e70eedfbb5a6020525e003b207a241f2251c88188, + 0x2dc8e5d6f14e2d43cf0b273522b35e2acc391774793f09014b27484e7b5fd137, + 0x2d24d4794146908185f2354fd271608d3098e04ab4e5c6991653a1e31ef4cec9, + 0x3343e0c40457a059a893250795a6c6ac5085fd7222dee07694f6c562d966312, + 0xaf7db3d2850fc1037428a9b6913cb57ed2b17ce12775d10a2ea59921e9ba3c1, + 0x2af76fe3326af61814f0596d1e9c7c981214efab22a78ac52e4c0d2ea5f3a559, + 0x28c5facdf2832d22fc8c7caebe4d49c28a3eac34e1c06aab03da51f4c675498b, + 0x67b910e6a3555653b7d646888b1620dab05b82afdb48c08b91422e1d089e617, + 0x1a8198a68db555bb70cbf396e3acf926b66dd19e4ae5f42a62e1870e17943d9, + 0xff3bc5a50528f42394cdb10000362e8b645cd1abca45814cae31c0c1736de96, + 0x17832e2f6a6abcf1dcf5084dfe2cc5ae9a5a9d51f3d68e74743efab4826951eb, + 0x707d9a111e2bf4971e1c28f0993d0700cc18742f7a217c4c1e2027c536d1d7d, + 0xd4674bba848291e0bc0b2c36c3e3662f09831f32af732d2163f7873dbd61031, + 0xb81f95f06e846785c898ae8f150761bdd156f063b744279ab030cee5e996788, + 0x1a4724e7a15045d9cec46bc059a6e06c0abae7410697e867f97e073e7c059e8, + 0x195b3b718107bb2d25b6546f49e1a497edc07a78a37c1de15b39b65ded042a6f, + 0x117c5877ba019563589a57a738d554caa7c8c4e3342dba0f33ecbb81cf46f7f7, + 0x29f739db99ca7b670979f4a8f3b852bab3b3a2fe0b98a4693c49484b2872ab71, + 0x8127119728f625a3d35d9dddd7d5393a9086e4192d1b203efbfe9623bd38162, + 0x143607b15463dc48fd12ddebae93c174396b76933c25dbf0b2433c789b211a30, + 0x271c4725f01cd9767c7908c9217f0377f0da33e9bc492d187df0a215cfe3e886, + 0x1053f9e74f700dd3161862102fcbe460e41f0a30adc546b62ffe3ecff5c142f0, + 0x19f6aa64f3f2298722cd31bb3789c6b74f6d12f0dbd38e6ce1ff23d667a9122c, + 0x1475d80686b48bab18eb1c32e800912b26b82ac0c4b9db036c513e0b30fa7e26, + 0x29f8598b62b2e76dfc939ae61c5e7d0a159549f309ebfe2f3f097aee1c41ac2d, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x3010b8ed80e49e580f884d5e98414cb0619b5381eb0b72bea15185c32e7f2ea7, + 0x18e9d0cd62c490a574aaba9b03b0a11dc0c11b4e632094c91ef72c14266a26d2, + 0x2495c41de1debd0cb51280193a02d320e978099f54ec96a970341abe80d96a85, + 0x92517d7731c97a877e552eebec76ee7400fd53d9be12d55ff9c6b170d68ec78, + 0x643ce7cae313fccba434207e99649376ee888d3e309bc8e5ee454466274d62c, + 0x2fa4485f1f97ad4c54fa908b0b25424bdc78255af9c77da99b95095619489583, + 0x1b327749a75f8db71a4c33e8b99e2c01808b9090d049e1ab3c7abfdf5aa908c0, + 0xa062169c4723669623251a50a4318e3b1381fb5c68556df9fe137474b624234, + 0x16c33ff536f271145daec8f03d97b56d0f8cfeedb7cc329290fdc1bbfdc2c74d, + 0x1280d067c4c7eced7dd8afac4e4cb3117be7901d7121ab53f3d43c4630f7b07b, + 0x479c7cdfb220e4d8d7aca9b5fe7380b2cd447ebf3d8a204320bf81fca29eb19, + 0x14e024fd7bab2d5031241686c4aae16ee300422df8b41919ccb73fb15ef06073, + 0x1a80d20677cd1bda8c97762d6b9a006cad73d95e78afb3eaf3b7f3f112e39bc0, + 0x1434e496824b8ea1ef9ea7f9e324c937492e33eb1af18459d89b29ba30549f84, + 0x30485e0cc5588a2f49932117b4dde4c933621ab227abe326f429c8688134893, + 0x100acb69114b53c1027ff56df9de3cfd561d7ccc81e881555696e0eddfb91f86, + 0x17a974539888ada5b3ee0bc7eaab414895d2111c3a9d5c51784889ec6d41546, + 0x194dde27e3f6373c944cf9079a28d68c7c73b7b60f5a1f5aeb7cbda3be4b9e85, + 0x2b563b2786180439fbd6f3bc4ab5f3ad52f9f20d7aa31c40b0f7906f2b0418a0, + 0x1abd1c97e97d7b5e6e9183f21305dfbc5855ed33636aa7a5cfc39e6329891c61, + 0x2aebca431ac4c7b1d96c54432751d6d20134cc8429a51bbdbf10d6a5da4dbcf7, + 0x1e93b372a671214f000aa220af2453bb8431f78694d76311abcdefde664b5bb0, + 0x195338e68902e870547679d0f4a548d1bc91eb3e144b403b6d9c05ebf879e274, + 0x2bb7a0b8bcf9f7540697e3bda7793d42e1ff60838f4b59f86a1ada0373bdb1ab, + 0x11be3da5945ef7d140bf9e06b468ec44aac37eb293dddbf871f9292f6969567f, + 0x481ae2c70bb522764ba40c7fe992913e56fc640bacb97794fee400861cd20c6, + 0x919cadc23acaa8b5e19a54a996c64b59a9032c3ee6b6aacde02696ca462116b, + 0x262de0b03fe8c9a6b04ace3660570271804c66ed640998d93362919e13dbe851, + 0x2b3c90ac3a4edfbe09b333ff56cec2918a5ef924359ad5e225e08bcf17249df9, + 0x1bbbe9819a05a6fdbb2827d1bac2c0c9736aa78280f8a81fc5969b576522014c, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x142ac1e836fc30278704b47fa49a84cdaec95cec40a60abfe73a30a10f2d72f3, + 0x102f24ed9b7cc4a98957278905f772fe4149fb11befc34b05c7556a0ce1a9444, + 0x59a56c684c34007e174577c81d669d1e0b9741d4d2b9d6077d8f8e8c1803df2, + 0x1f22f8c87034418d3a79a9f5fbb2ee493c6851499ee2a84800b0e711ba76a918, + 0x2614d18359d21d25731090abb6877365f49d58ea4e78a44a9e7adb4409a3aee3, + 0xc414a0ecac4fa0637e9a4c9679085a7bb3b1358b396b2bce7eb9af4f0c337c3, + 0x11930fb18ae2944cfc25c856cddcff702bbcc81a2c2a8a81ab68e2abd0d63d96, + 0x2ae750321489ad6aab14cf7f3089bee01f50f6f1b3a1c046060804d204d6d4, + 0x1532fb2f4f6a0dc23fab57fb2988ae3a61bd61eff35634f11687991465849525, + 0x29b85c7d9d52c98eaccfab07af6c2aaac1dd55a087ca82cf636f2868dddf398b, + 0xd50d222652f613b3cf0a36450c848108600b2c98b5d16e4b75b92a1fca288bd, + 0x16bd29ece6542611c44d90e72ca96e7e81bf04cad858b88f65b3cf059348be75, + 0x114e95888f1e263e9304531e672fa0533c59aad32e19a6c8e79a0be3daba9dc2, + 0x7ed4c3caca93550d939fee72f322f5c45c45c3262481dc6d3fc21a39ba4a9c0, + 0x2cf1d8e95a3b2cf8d4c1a0dd53adee6e975640bc902e05c357d43ce4070f6803, + 0x3730a82d1114f03ea0f98add20cd73889491c2d362fcf76eaae54df206bb984, + 0x2201627d02735d6def85f3d4409b5f675e4f5b670fc8fe334c2da72e9ebb74e9, + 0x1de69df65e50bff05222e7d15bb7c25935a419532031efbea0a88d412658025c, + 0x199e9757b4a447a466924aeee5f4e3c6c0f7c0f1545808377a8c0c436b374da9, + 0x1cc1175e9e818a6ea2646c194f36bec3c37c63294b25baa9c9f48ea3c312d08d, + 0x29d4552088b3053c16c885522c794ca388ba38c6b9eb2c55e011532a5f099fbc, + 0x23d3b2dc1c7ff3d298997d064606aff743e7df6d7834c775aedbff099d458f78, + 0x2388ad46e7bff8d8b43e0ef0fef084fa60cfe32993ea7183504ee738f6445cc0, + 0x304e1e25593dbba07c1aa88ebb4a80684d9147c0b2f9247b49b5416f13fc3898, + 0xd63f23dde7572c15586188a12a7a1c0b2bd109f6343294fc8f8bc1a778414d9, + 0x19cf6ed79057a5fc4398ae7569c1b85519c97218ab842723d6212cfa9a0a2dbe, + 0x986267435a69bf6ebcded378d2aa4a02ee3b7a8becaed9ca1e663600fc90c3f, + 0x2c1575ee85e8cd3cfb63424d84ea5000786e5927433aa8c0b0211e5d87929c84, + 0x300003af788c5a7576b764f88be5b3b1ac8cb0b9466090fb331569d4c6672c3b, + 0x9edd428de05fa06b6410c57a5796fcd1ced4e3d20d42bbdc40b00ea28aab387, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x1fcc025724948f53d0456e85fb56f3f81e0c8d4c2bced5efe3fa3af8ff77acc5, + 0xc37f3e2d38cd3138ea93327d59b885873d41ef32b76409638af6455b5bfd932, + 0x1cff93735f5e8bbdab731d6b1a60d946f268b082d912fed0b3ccb525d8cb6485, + 0x115632e11c1704f965ea72407243707ec477c716cc429f1a7eb457f4337a5b01, + 0x10d1bc0b019f8bc6d1d6f5b74ec4e472b855fb594585e4458e4c269750912717, + 0x1bfa4745da3b7737814426f2b9dd6ae7ea034a00263dd091cdd7e118a44d38c7, + 0x42f42c6cf5ed0f29ea6535ba858409145772498174886db7dd44bf9ac54d492, + 0x27da68d3c98d92e4e93777c0bac6c7cf508e16e748fccd3c0b7b9fb54e605aa7, + 0x1c0dd243e40090b31d093d35c80719303b7c49b088bdae82b248fc1dc37fa340, + 0x1c3e2814b6eb0de8347ff2db9de7d3bce67b5a97585fc9933bf45f406edb6ff5, + 0x4487bf6eb305b13eea5a82659858a64226428712237312fec1f6bd536d7c29, + 0x1d4dcc7fc6d31a37c95bdb711a21fa490f4786064834c25d2e15aa82dcb762ca, + 0x1ad252b23919c93380ebfd7fe5bcc221a3dbc4fa59e555b8d00bfad872c0c14, + 0x1b9bb478853c46abecf434115d5730c6dc59d0c70ae580013d216f9ff259656a, + 0xaa2849da666039877d1c63803500ddcb59258d9854bbd817c690b32643a696, + 0x1a80c40302e2c50b3a9a9303f10ffce49d7bb5f7e5e19ddc85838f01df61cb28, + 0xfa31af23f2b7a127dcc29d7a7896ac68e3ce309a70a86f7e680fae88ae11af1, + 0x10b6199654c3e28a05df36e3ece1922c3ef4b7641b2fa8fc80a84e3e47d15fd3, + 0x23002a3e74809dbd3de94260eccf0c50b15ad8f1d0b34296d06ae58e4a28b6f6, + 0x149568dfaf3fac96b2638c3506a8d25609ca18e846ade9d19afe0c1e05c02c68, + 0x27e032df87f6c1641dcbed6816aefdfda13783c301c6e0a90c31a98f4c0b9208, + 0x18d75157ff16e95990d83ca5bc9366251a45c6f7935adcd1eed6c944dc87f5e, + 0x3019b560b7eb66353bccfe2531464754259870d8246d7f35bbf10c6862bc73b7, + 0xf4649bbb3013488fe2f61ad0d590433f5c7876a97cf9c83e821f078834c45b9, + 0x2adab3e8388934d5ba7cf03b98c23defda5c4c153364936b136828d06db12d99, + 0x149faae0107b1cac1e064cc54d1950602711aa7308dbdad89ec173da0595ff69, + 0x18601dd152b8ac338eedb1278d537c16f70e1fccd0dd9f1b1ec673b4b86deb0d, + 0x1d65cc6e7ccb7077ab51de992f4282456b818da240f46de874bdd4f6af329aba, + 0xfdc0f5a32b65a84e134027c7353503c7e9ed38f49907e28a5969419e8438aa6, + 0x65d3e753bec13cdbd2d4cb085fc25c8733f52b5372a4aede46eba19258c2a6d, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x180a916e94037f9ef13f05a1ea22bd41ca2d4b0f5eedad386a420ba6188d4882, + 0xe6fc284e88c1403f06ab873ec9d803191655d35c290740cc682caca22fc13a0, + 0x2753bb09a0c4a77b3af2a69333e51bb27703615d09d56f86423f85cfc8827faf, + 0x272db4b6d71f80f52e4aa1061f6a24e98dc041a0bad07dc46aad59e67d96b010, + 0x2378ce2c52074b027940891562743047b7b57ffc1f6654c2dcc23bedf1cb7608, + 0x26e90f7cfd4093a277600d2c564b6cd8f4ba3899b646d7427ce907a96d25b4e3, + 0x1cadb3908ee02353a3c45fbb57dbf6b392d5b1e59a13d58b57b7e0dc71c8d3be, + 0x4d30d597f9dd6720e85eabb0a7808098f72d7beae23e0f5845283cb04334e2b, + 0x193da68a7a699b7cf33c3ac942a960c154f447a016d957e241786253101b1c88, + 0x26484e7897f16c30babb9a4eb821b94e204411ea78e3759bcb55f5f9e1f0ec02, + 0x26a496b2c2b5ca5ba3dd8af6dc73aaa2d8bfd2f6715876fc5703ad68aae6a1ed, + 0x385b7c09dd2a1a0c2595a940914780d61b49f081e20149c37d920a06dc8ae7c, + 0x215ad8b91b54598e0ad7129f26f6eb4e52a27da738fa5ec2aaf3b471c2ef63b8, + 0x25c029bc5468787fc40f8b968f9542a8cf39632ebdb520496cf9ade72f289656, + 0x2a8bf45fd684c408e8832341397ec0589167c0d26cd7bb73227cc83273632bb6, + 0x1621a4527a457936aa11821e0e183c83008e201ac922ef2491a720767d5ac282, + 0x2146604597997341b5b512c2d30536fa961d09b5195f4ffe20efd22f4e4e1088, + 0xf469417d25748e654a60d7a42da219c2c1ab164e0ecf4950a3c15aaec9d7b4b, + 0x854569ac15311adb77dd8f2cee810aca29c09a47b6130b51c16b95178d76f2b, + 0xe1696a6980d7dafa5bf5a2e10ae664e0c29153272874153cdbf2b303c6c8762, + 0x3eec28f72099f4081b58deb0a95abcef4ca06afe5250a29f565b18fc8c0f3f2, + 0xf0359dc677a2208a6b0c627912d16b736e91ab3fa83eb825a7b1ead71d000f1, + 0x1eb49e2d0f17845b3e559dc12cc37d706bf9e048e6cb55a766ddad1100a07b7e, + 0x2837d91b1501a5d4b95913f0d2c24966fef7f5c347aaa897c210ba15913def29, + 0x2bf39f6cf1cef6ccfbbf97a4254acd478c897c8cd9614d3f8f9bbef4de646c94, + 0x67912e7144d6029b3bc72d448dcfdbbfe0f7e9591293ab205b389d61eff77d, + 0x191b47b69e8adfc904ff67ab36d19fbb1021c70898b9d657fb6a020bd6bfe684, + 0x2fbeb5d54229ee582a6275b9977b77ccaa8ddc90265b7c5d59f8d19af69e46cd, + 0x223504acf848236a0f7cd946c84289c4b4aba0e123b1db8e588fde7de06ef2f3, + 0x11d8e8ef78b313743937e16395c1193c3e46d4b84c78189076d7941fbff04622, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x20d2e36125e681535785dc294c751d7557e31dc99c01cc45fb67d0e0f7031e5f, + 0x2108085ae6246ae7dd76f7b3f3e0e731b7e4067602f6026c9cc61321806d4b6c, + 0x19046a9fb27aa59fd7cbb075905c65e165d16248d948c1fab9ab472c57d8ad1a, + 0x93a926faf68ed92e943507a893163b433857a1dc564f3f26c2f497164852c86, + 0x2971a879c70793d54854f7ccdeba099226a7034fa5d9911dc81aee80cf49f279, + 0xf5f5ba9b74aed76259a159321e26cbe1cd7e5849ae8562ff497c1af96285d1f, + 0x20e7786221700e467df64d8d73e4c38753a44996aa732da38e621bd270a16e0e, + 0x1f4fc008a41a25739bd41118baabcf2465fcb0e05605bb2193aaca167737e6b5, + 0xc4a3ea3f708efc883a4bce4a0651d8517c70a1324de4935aa508c3c0ae24dca, + 0x2e7610fe10352af47b616891090714c6802f3fc1fb9efb21248694ef6246ac07, + 0x2eb8ad40c535f3b7b05c2fd963b8569e956259227ef21a24b7afe546effe4184, + 0x154989e705cf9e62b9416e28834a4a7bce6b573a1235264ce89d4b046b6ebbe1, + 0x184749a0e1bec0f94c8f3c5be0c76d87976952449c2bfe6304413dea612e2e1d, + 0x24ad4bf83c2f3341dca0c72a3575fb12805568e92cae4472fe19fdff27f11d50, + 0xe788a096b2d4192046ee742981fa38918777b65030ef53957571c3b5fb54a6d, + 0x1e22b9d4c274fad52d4e5640b4acbff2c4810127a087c42f9be9ab58809d0d5c, + 0xc8a3f2ee3246714404abf0521e74a63b83576496aaff85c2be74a7106846f12, + 0x21adde943461bfcbd7eb10345a94033b25d4701157c694519fb2b4093b756709, + 0x1ea99affaa689d6f19f8a6b82d4b81dfd1f17682831e0c00d7f2f8fd4938a37e, + 0x16949199fe4a38750de73fa737a283a6a9ad40a27b0deab631f9295ade2423cc, + 0x1e83bd581acd61c3b54afcb7a0a9a0138d9ac4c8739cdae89759da5150138fa, + 0x42a61a84c944dcf754f5a97b1dc8c2ee7bdfbde233f789210f506eda56973b3, + 0x2b93c28b157ce32bfa3b8d0f585061e75a03b79c366a75856cdb5ca2273e30bd, + 0x1f54218a5daea6045fa60b06ab2520c52560282b1cc3ade14b664bfa49752bf5, + 0xfbfdd369bdaf703669fa5e36a00aaf0b251a50912048adadc83aaf092e7f2de, + 0x3633bd5a72a51fdeca62aefe9434104b52e152655cc42f06e70455cc15f8e2f, + 0x2c0eb54b5f8cee8ba898a242dca64def09dda346d06323892957fa30b3c13af7, + 0x165035983f563b1e3bcbe6c873fbf911d194fbe54243e039b3cf7b6f2afbd822, + 0x2fd9820b3cbb131e3575de4ecece3471352587e10c96e72ad867bbc57f4c778b, + 0x1204b919d86a12cea70e977706ab2be78259c6c608dca628eeeccec50b829342, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x2f3cd03d82e80e8521a2366bf79e8d4ff5cfc3b4f46db99a4947e1ce4993b2b, + 0x1cac3fdc9674c64c1614a5f48d65239daa601e26766fcfcf29cc385d6b3735dd, + 0x65415e4dfe08e357c669d145be5fa6cc74b0126f099faf1d7e85fe9befd30d7, + 0x28ef19ab4bb2626906730f539497dde648a1a967da5ea31969feb620d115c8b6, + 0x3e88e9732a1a572e70d7cb6528857143fb51a949fe9e0fa0fa281b85b64b7d, + 0x2486ab5c5311e4bdc65ab49fc60b172f851908d6753f6a9cc40f9b1535af072e, + 0xc50469c6c6bd532c6f805d26a30a7e5d703e0537657518cda0e1c6044301ecb, + 0x28f8be525277b0346bcd664cfb0a24a028f90b89ca402254b4f95833cb7ee870, + 0xa68990da12f327a6d79b356c1d27642392b1b2cd9cc0b5d675d98436066e563, + 0x2216dafb41776a1941b1f17a5dd8cca1cbe0f60f81ceaac465861b3dc2ebbe61, + 0x20e6c97c374891d9328052361d932372efcb6c0c84628b6f3bfcd41c47d1521c, + 0xa2565ccebd103dd144534c109f53c5de275ac56e9170ad9e3ed0b600aa51ea0, + 0x1e79a45802b9e7592e60d7e4964e8920a458862cf40212db96483540a62acf3c, + 0x29f54f1a96514b9b42ec9d74b5d715e61c265b129a7061bac126bfd50f696fce, + 0x26bb61d61ff279242f1e5c7bccae627e1942ef8e103a915b64527fd0eb31a93c, + 0x1ed4d606d825d86ddee16689f24ee5d9832a140f44b437258969f41d4c442c7a, + 0x25131fe12798f1c8712f4eebbc7213e8f80b23e7d1bdebfd255c18793734f251, + 0xd921ed8053ca270d60349d85ba38dfcd05bc96c05a68677185956707385d626, + 0x25c7ab17f3ca72fef63042fcfbe1a3d5f1ef5d6e52da6d6dbb5aad46b1e17421, + 0x1ee03839ca2483009bebf461b58d11cab852212642d38d1d33e48d9956fc48e1, + 0x15a5a2eecd107f307d9565496448cfdbbd14ef42323275c0ab6597aaf1895475, + 0x3fe00f465767add4808ec12aab687e16cfd702c1453267b7a2575c6cb557ba7, + 0x1577821b07e4ba2ba893bf15ce062c0290a2c757ca7140f76c2f03b53d84edaf, + 0xc00f28af5cdd011907df891669d0a43892fbfd24ae7d2abbb951b67334158e0, + 0x11f2f4cde668fcb28b27153f0c0d85c86fdb4d0506d38fd5b76d33734868f4cc, + 0xf15bcf82d1d583869605309b58d382a4750fa8221ebe8126ee522ae696abfa3, + 0x2a87c83c58f55146158830df52d74403e32569179b409d8e97ca8a27c7446bcd, + 0x1b655b2c43eaab5b8d104f472d8d84a836246faf3733debaf470b8b68b3c6078, + 0x2b4c7891572319263680116a7a29e9ee3c39520dd8bbf33016e31b88444369da, + 0xd57a4ba309a380ed8f907c68adee0e2ec336a33d67abfa6d33c0b34191d5c3f, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x24d7026b9df6dee3dfc366bf883301d2f5b0d769ffe6f625614731c81638a5f, + 0x2ffa9260d3bc1a98adb5d9a4566a673a4ac815d921f66a78c7b6781f5a45bfed, + 0x1c49dd9439a135892456c194c0b8b727f5f8dfb8b46332cff79b0e88af0897e, + 0x20dc0d730c188f571f944cda64df0385f31ee47784649b38bc8b309fa731002f, + 0x2a57e4f3c1d3410302207d53fc653b091b9215b9914f7e21143c5ec3d6080206, + 0x18924496a011f1d0f7334c75efc82a756b5fa7b739ac213742e747f0bab85110, + 0xb488da92db9fb460de597bdff5917bc07393e560b75df7412a23f86782008ac, + 0x181707ed73abc47ed303001ae6fc388dfd30bcaa57b75d4667fbdedea39addf2, + 0x2f3fc44c1a30bcc3419b88de657072843f3eb73178989484e010a66c74a4bf41, + 0x19fc475149f3945f3fa3c88aa7bb166e056cb353a2bb28e98cb2c647aa72601b, + 0x24e52c7ecdfe59ac393a7e3659fc038f582a29f0907d9130e1615a60e0d8ab0, + 0x7be6f1cf7191d8cf88349cecd3f83df5493edce1708f65a305c3e749f06da66, + 0x1f21a4d143a3496cd6736f6462d52ce24b40630d8dc8ccaee1f4fe83d2d8f8e5, + 0x2d26efa6adf5af54f46c6835f4d6d13874b5f0f329b21a280b19399f855401ba, + 0x189d55e9c0ea390f2e219fe4abde4c0ec6fafa1b68f5a029e4d2d5f2698c0572, + 0xb825420f377252cd094db40d6f37806ac50896f01a6b563627b6fbf45bab59b, + 0x1fba0c700b9f301109b83fad61964385ccde2cde69510b66334feb80d8dc5e13, + 0xd4c0381cbbb23ff4199900fe9e98b0588229e95cdabde87734b7da4a96728b1, + 0x76f5d00e73e4dfcf13f558ced96fd848d34ba5ec48bcc141228c22d18689433, + 0x1dae42a7e24553210ec1d37a83e7e379f118af2833a638cfb2f637c2731b167a, + 0xa7cc5bf24de2b7a6553cdb103f7b93a2ca50e7b8b2947563fb8eaf4c96ac22a, + 0x2b027765c2982281f3f552c9fc239b96b0485bcd6b246567189760387d54a530, + 0x1001976662b6ff1ec3f6510318e518e6dba3e69ad0635a41153e18435653e16e, + 0x1f0a377816189522f724ea65404ef22847bac0fe95e2a6c666aab27cc4dce446, + 0x1e7a94ac5ea43fd868784c2943205aa45994575b494a0c0c469f6be322077c78, + 0x2791206766f62a06b3a0a0d71759944425e50d392218b999a86bbdd590184075, + 0x11ad87aca6c25e04cb85eb1557e42ecf5851a9d24d20f9ed554ab9de9a561814, + 0x7d76ff83e9aa3f5924ed313b0d183a5703f49eb17db9b5192bbc1e5935f41fb, + 0x18eec21072c91937e53d9fd0e38007a1d8ecfef89ee0a848e5c42a73324c0897, + 0xd7ea1d8a141670f5549461c8e6649e7c0dd2692756c6c25cc4525d437728ac9, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x1d9e4a0d2a85dbe20e640964806fa1e5122e2821f6f46ebd2f614f52586612c5, + 0x1b0529d2ba99f99c7e4958a1dd940160e451ad60a731f482e0eec4f26806ddb6, + 0x2d78de90b2cb9901ccf75821db641e2619beca024e3356fcd20b0744773bec1f, + 0xacb58a5c68bfa43b46977a9da02f76727974e24f13f1e6e7646fcc17235bd4, + 0x133449d082b88b55b324ec110cdb4dab792843e2915a039b52f1399096abb13d, + 0x1e40b0c57597c9efd9e21aa03b9e60edcfcc6313f2b325a1bb552a227f466cf3, + 0x1dc4ed7c60899b410745ed729ea5a0066568b97dc007b6e7e804769dcd4d7d36, + 0x1146cf1be34558e643e2850cbf90d1e25e3ee122f8292a12b8be4cbbc3b02f15, + 0x24cc8fc4c875a88eca4864b038945f81381b829ae63156e314ab257829531a0f, + 0x29f9668dddd6103594c092b4955bea42a78b762b014f853d12cc8a435deaf507, + 0x423f8acfb6425857f07e45bab4474b2746c987eeb3cccec94f838fe25d524eb, + 0x226d21a206f17d649306ea18a42e50d395d65136d082d91b09f226e63fb6540b, + 0x50d8e0202485f6ed926f1036d1cfcdc3252b49bee257218aa058f8b7a22323, + 0x2c6998a3a1d4988893eaba746cf07ec665089ee1498736a1580f2a7b3f840a5f, + 0x8f07def8f9291f940b044443a720f15109a6602e54670e4ddec4f9bed773f4a, + 0x15ad9c95848c4eee4228b1da242da640ecdbac2ca6f216306045c794e0cd41eb, + 0xb6c94ad59e7195e47046f5e2dbdb395bc45ec654b60c49d8f39d9f8b895d1cc, + 0x16915ac62623b19ce2101c05fe7276c373b329f20e1fe2b86f85e3bb18f2eedb, + 0x241c174139afa0867f108586e337df3173bca36eb41a669da121cc21cc52e157, + 0x2fbc48a493da3632871d2de5a8c22f22112afa88b1e71395eced016a149941d4, + 0x1faedef5274cad9d8a55c7f763fa86841960a0746745c35950bedda80b6f4224, + 0xe5ca90496f6ab2db273e54bdd99ae0d8bc1c6f0904de14932958f6c837c26f3, + 0x1783f5edffc02d572faa7798200083b86b2b1ce2320dc7c8a0b1ebffdbc9d567, + 0x1108f89b2285ad02285b4cea8eed22d0fab841f21df3d4ebfb398606a6ba3869, + 0xaf33de737c3e1f423c51d89384242ea23bc564bf402282002cd30e3b163468b, + 0xc5152ce065fcb30be4405cd338d85ca50d6a06e9344fcc7634d82e0e9759a74, + 0x29b859531add0b7229247872552339e4ac2ae3d4b6ca8c705763cc8193103aa0, + 0x87622acf27810277fe3cae6e270483d0d53158900fca1849650b0b5ecf0150c, + 0x228844894f0ecc516411b0b864dba98a8c26ef510627f2de70e1d13bc30a6e1e, + 0x196d69516c701eb00c670cb577336806429642be8b0e301fe0bb12293dbc2548, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x1f70d88a852cd16c82f70637d9d973d59f7e77b8268aacd484e4e53500f72b24, + 0x141cdcd52cc304528f7f93f23944dd16b3cca1a85b2a84670c504b9792beba19, + 0xdb56745ee0dd133af6f37bff1f6dac061ec7e40069f9a811e7d034d7a30abff, + 0x2569e01e00c725b48d55d26fd8c49785fc36248299eda8abd3b92b20b15020ba, + 0x353c1598121daacd532f8b0ffd175318b309bde28b7ffada32bb73b784d95f2, + 0x23dd1ba2b7ada18fb1337535b938fdd5318a1ad228cf00747d07efd159cc23cd, + 0xa449d239c51400de8f275b00787790aa508e1e160bb66e87d0f4e32ac5a5bb5, + 0x2bcc35ac47eaefc5ceae93b97187f199f4ea9776095a98efa5353da21540b9c9, + 0x22e49a4378b6b69566529f55b874d2304e24cbaa5d790f76900ee2f8478e3c07, + 0x66ad5b80133fd0a6391c05b7e20b13416e40c29a06469326768f24276fe1841, + 0x3f2253229c2810aae5c8411d5130ab418bbe077b0f1122623065532a259b857, + 0x2662e6c8a1134a005867e103901a5f6c67ac3737a6620accf8034cb83bdbd4a7, + 0x20a86066eeceb6979baadde6a2359befde49875bab142e57e171b0870b292086, + 0x13afbc5573e84312a43160ff4045190adc2a9db03980e7126381f4089e7c91f3, + 0x7d6db6cddf350cc1d59a474d84fbaad04fa0f2bff915f077708df41d5b2a746, + 0x268e93e46fd7f13e1a359ddf6ebb619a21c1068de6d899590aa1048b8829ddb2, + 0xf889928b305b304fce28f103f2e4194f2b29cdff231b05efe561e1cff4e70b9, + 0xc547ddbbf87c32bfe454d8e8b0ad4402c9b979caaceaebd9d59484d43cd37a9, + 0x20da83182faac059a9d00b35dc345ef0115117fd24a15f6b91b501728497ae52, + 0x1f6b643b60e535d0f2731a326273576ea723671e6c51e7b74281028ffb0462ef, + 0x2d14d43ab2196fc70e26a6b9ef3f2e9d18f60026af5833359f2a4f694ff6f9cf, + 0xe9b85853becdc05429b0a28a7e23baa59377d9037615ba740893eb971aadfa2, + 0xa664658bab11525d7086e1206ae3c6abb9ec31e3461d6b0b2547a5d6c2ed54f, + 0x2e0498e8539d8576df187245d0b1222f43cf4d3f8f0209afdcb2f68767633406, + 0x16c87c7662e6724263b44dec088080333793ba2002fb9669eb63dc3b1189b6eb, + 0x9c5eba75aefc04d0436380c834da36d20a67fd4e11653498b4ec21b30900f54, + 0x1066b5230eec70bbde6c98ed4e48e392feb18967be71a12ac18e732a04ba9841, + 0x2dd2a9adc1fd3ed04eb259dda630b58c0791d7ee79b85fc20ff8b37ca0dc0464, + 0x2e94a96ea1f18a9d99bfffc3fe43f0f751bcd549d1e5992e366943a85ccf4af4, + 0x8d72e9dff20d4f5c4543b725e43e01f1cbd2bd0d9ea8ce6b0c1a9b0b2e8499e, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x230050eb9901e2db2f16df59a7f5b8a1c441e5fe9cf3869a4ed073ba25f5d13c, + 0x1c2f7f401da1ad989e6cbb5c81e3559a7930ceb1916691b9b2d702eccfa3f844, + 0x9b391cab0c34b91b155483a41334a9ae97203942d7683850100acfa35c51600, + 0x134816b73312aacf2f573418283f27bca58d4d23624890f7a3b9ca81c12e9718, + 0x124b47f9ea87c94130ddcf77f87f4bc53ee087699d0e5f62663a63891c1675d1, + 0xfe5a21251a65261e6cfc3709404711f727a610f94057c304e1ba67b2f006526, + 0x28ab3b64f6f6f0ce2707fbe854295616d676dfb0d66177af6679b3ffa512e8d, + 0x1870499da8f58f00acf6b1133119d757220bb54ecbd793f9ed42d65c31760fb9, + 0x20db70356dd8d855ab92b28a96429acd5ca77cd9e5211aac448b991c1650893d, + 0x1a1ff1c58192f748174691a98d8c5e733ed80ea5c2fed11b098fcb815b438516, + 0x1ab2399c7e7ce1f5d3ef6c3cf33f39ba83f054bd73d8c5d7425666ef390e4f69, + 0x1e4b5f8ea2fa22e568978cfd90777937efc072338e173f49cdf7761a9caa2b7a, + 0x2305b22483287e9568160f0dfba637f50c63472dd89e56da0611b76cfe869104, + 0x1efc74710147e4e7df6580d0ca588b6f338befeb4c6f8e8a0967cf5c9dc07399, + 0x43c5e4ba3ceaec4190acd05a266e8d339681eaf1247af047fd0dce72fb37c0f, + 0x2ad5f9fe59cb81bb3eb3ae9985a905adbf2fee8426fe0ce3c1b108209aea844f, + 0x1f36ba0d22839b3176e55a9ed07dcbf0255e386bcea0a5be9823dbb3300ffc31, + 0xa565b3ce5c2aa38618127678d8aec23595e365f5e51d97474b85b16a13362f7, + 0x271dfc29144730cfa780f9accc99caaa7d14e05c42df401293d24759c12d8ed3, + 0x1119a78dd0cbf88014b97e6e5758b64c8c133a5989b758af60df2ee0540348a, + 0x157970a49dadaf8b39d46ada19fd06b34784a6f33b4d85547c2493f27f389e0b, + 0x8697357bac4131984b26ea8e352a3c5e5c33ff22f09019646f43b5137d4df31, + 0x29fecb3d70e1bd21087322a9d0f0db92c65f141f02b45936d9a5b8535f0b955e, + 0x14297a9dad6ee3dd0ad87ee9c2dc63685caae7391012e267da21ade2aaa434b1, + 0xc8f3a7ca1b4242199d6a0999b30cf3e61dfda56b98dca4c9bb199a070f9c782, + 0x2105bc020b9bfa1a23b0b2edbdfd4ce7bdedcad57906d2f58053b8ab35f11b43, + 0x2deb04f6f90c24a07d2f36e40d5bdef34639b092d395bb4a4fb483f84aecbcbf, + 0x2964c5940985822a64ac1443efdc41cf37e87dbf858535bc7c87181768091c60, + 0x20b68c1b5ede99ccfc7cd1231b13e90d5c9235c36f2f955dc6ff5352133ea9de, + 0x30096e11896ed1672687beb4f6725b749550667e8da418713bea7db5f838efca, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x6e21228ed894978b90a5e0b691d8916aa63720a5c795b9a07381452e22382b9, + 0xc9bcf80dc5fd89ebeb604437262768ae95fa7263924501540552e7a4f2414aa, + 0x9a6be7304c6da043de4c03ad5c76101a8bc21f1aac8dc10a695c7c5fc2f9072, + 0x1d78923d01c8ac2f59ddf5f046cb5bfc8bfd083ec61b1af080c79c2ddb27a832, + 0x272ae649640a5da291be7915b01cba87251bc6272140ff420b36f27774594209, + 0x4b1441ef166c520f9309f2f984011a00dfc71d6139603ee90496e59d715f775, + 0xe8d1281ac76ae45f6f8116bf74982ba76109c42a2ea163357febe0422658c42, + 0x1c5d4250da762fafbf313804257126fea15085a8ee9c103a9992950ab4af92e4, + 0x13d55c7c0b5e9acfac2196201e8e4a1ca091505b12b70064dcef6f9d3b1e18b7, + 0x3e8a03e1e25fed9131b3de7150da5ad0b53da4fdbea9729dbce40ce2535f0f8, + 0x12623c6993f1c30108c7c79868c88e3943a64595eb7bfb5814791aaad5a09ee5, + 0x1d38303334b2b1328d7453019c571fc28f1bc5e4e3c9450b491eb870d2c8fe89, + 0x192231ebe3469dd102a003b41ea79237429cfc4ae4d7d7b5f49154aa70b918e0, + 0x26587d8d2a074923798fa95b78d558a7357f48989f553ba03bbe800e4d4ee582, + 0xdbec60681a76725fcf9b009006e1235f2ba2d3f09ec62b50011d19ed58019c6, + 0xd79206c8a30d26abcfb375fb8c5a117f3cab1c9fda8ddee17c0991b11c63e13, + 0xbc57e048679764b958ec54b82fa3bc4690e99591f42216447ec6ab89e5752ee, + 0x19b73a25670160ec2631863fe8b93691a30a5e6cecff4e91e4b56dea4e9d75a8, + 0xb02dfd4eb79d59d665794ed829d301ce08e2e5285bcf6f75a83f23815f8c5c4, + 0x2e8eda48e5dfeb71e3302274f516a74131fd336a617126a1435cbed8ef6c9d90, + 0x282c1f1d562f2927e694715b631a176baaf7621c44a55b90ad2f1af512f2b499, + 0xe24552e72a2717b254956fce21df810fe3f1fb66ee0224be74aacac4f9bafee, + 0x619d6bb9fad7fe7a063998dec9888beec2a1c2206bc97f6853c10e62ede2ecd, + 0x10855580bfa613c21a4efdbb0f302d4d30a87a79a77cad82b37ac76abe5071ac, + 0x12e7d2df332cc5d618a22900e665529f2c22bd2b2aa387d9cb30da9483f71155, + 0x108fa054801185a6aff619e7ddd9dc8095884ddcf3c85b8c922aaade7fde8f66, + 0x2f8cddd8f2c5d14ab14b93182197b8073b4e9c41c138b6764ae3569771e617e9, + 0x1f4622a6c051e3696414b2024a39391743479968b4af8dcf07186d5c2ff07972, + 0xc379c514adbbdcce4502cce0b85fd03fae98db9d8f36d3f3c56cb9942ab7877, + 0x2b139708399f0c23fb51a4d24e7189fb1e619f5c7e03bcb8c8c32945d8e1930e, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x1a67fa389778c9489c495deb248e754c3aaaaa63c5ba3c6e5cfd96be4f516c01, + 0xa82b7efeec16e6c5aea5e99597b098504973c824edbd47a27cb33d65d7d09dd, + 0x58b5d72d0fb9836dab90890a9a9db183959618b7de3d6b7b1fc07621644bc7a, + 0x24411fc9331c4465de389c157199ca24f304424c0481d117e7b0ea23657af1bd, + 0x210351a45fa4ef26b2837ad06b46629051a464602e52b36ef24fae76d1d6d34e, + 0x1e05e49db66c3340e7db14921c0262a7346c687a8c26137437b510e30840eb59, + 0x2e6833d4c2d492a05a1c2be458d06a65f6be428714d1d44c2dcea661571da703, + 0x2747e0fb93ceedf91d0b703ccd88f179e8f10331090321660985bc63897241cd, + 0x21373fe7342c29074309be92546ca3308e28215172d43899d8b34e336e0c2feb, + 0x7aca07d0069a023d78e0a91f67dc748ab58990af12f54b14efbf83f6ea3f959, + 0xd31908df90c1e9debc10476b0f17dabb3ae150d731c20a321f5ad6d28213be4, + 0x28b90adb926df7693277ffd23ca737852a441517a8eca29eccd732b90dc0db56, + 0x104147d1f610150c79c7bcf61ef1eb1d1d620af87c49516a193790dc5cb1cd77, + 0x22704b0eea545e93d8567947f5736159b8c7559da9346851ef034943a9f64ea8, + 0x12cf13867e1f4c665d952955497197af8211929750dd706a6a65dc654b99e8c, + 0x2640c797ab409cc3b3ee21869418ced6c6aa32c8d96b9a3da85c99d8a2bc9501, + 0x123e01798d0948749ff8ed24a732705e44162826c2c7d28025da133ec358b822, + 0x22f5988c47c36f454fc5c2f982b854b4f4f64ac69db58a7820b10ed05a1c1b7b, + 0xd71a0b148c465727aec89bdc6601b3bf341159e0eb92672fd2cd29670509550, + 0x9c4450c0fab5b77b7feddc8f4c50031a113df973d3dbff0101564f4dda5eb64, + 0x216909b9a7ec927ff4be81f45f34004b80de648dccb64e956e689755c1d08c9c, + 0x1a676535420e170fdcc7784668b421502d69e5955992d13133f9f53829fbfc74, + 0x2f45e803db63d86ba61b8ed3af38c48a00d0ce69c1507e85647022d6f39ee208, + 0x3cf89993c4654efb4b1e804dc5abb423ff507f7abc65cc8d1a660671264a2a4, + 0x2eb840961ae22d47e776bf9f78d8f09786652eb99782097010e10fcdfdeb9ee3, + 0x13b3fcc3c156042dd30d9c935a465c52827dba78cde25cc87a436845a38cc1da, + 0x2ac2949357bcdc53d8a234e1954aa94813a0825a9308ee3659d5d386b2f10e59, + 0xe15460bf314de3c67d868973288483bc62926bcbd2e7042ea807888f7d9c19b, + 0x11c767a3163182d5eeb2ae857a5b3010395f9640b440f75a9b859c30ab1800cc, + 0xde4b8312d23ffa47cccedc65de54ccdf9596a2c26a8177b78890f9a0000f1ab, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x22a306748bbb7276a025b998d053c75dae5fa78e31d6457189abc977665065d7, + 0x11e89b2f5a9f708391bf115992b295c5df50eb4793379139749cd3718dee76c3, + 0x170d1801e156ba73911ab491c46bfed177c6cbec44bda6573298cfd6e925324e, + 0x99425a344bd24801fd74847ee7524054b2c0be72a58c42928008d7163340593, + 0xcb13076d62a1cceafc495baefa2cb03ddbf7bac1a8b24afbf0a84236a1fc1ed, + 0x105cd167cbc2994138f2492a42e39c90c71fa1112160c2c3cb86f4a3dc6f36f5, + 0x2fe235ad0ae252a09231abadf1884793e1479f8953587d08f0fd843c73cee60d, + 0x27b02875c28bfc1217490eaea552ce39441e6348a660a8dff460564b37002abf, + 0x1a48ee09ed16a03c4fe2c433bf85bdf4ae6ceaec8706c97bff764912bda1dcde, + 0x175b14cc4245b469dbffa6970992a1bfd6c61deab13c5dab26b1481b9e616fbb, + 0xd46b0974195aad4698bfd176ee33fcd84a725be4c13009c15d2d00fdc176a16, + 0x1aadcefcb3f21adf4b25dc908e1faabcbad408c2b2cc24ca5a35e5649c787361, + 0xee80d214b808612daf959f09c2314312cfd09a7050243e69cd993c351f865db, + 0x2b92ed72f750583d1091332acc37a8c11ff616ac98ced2e2ab47e2650b783ec3, + 0x7bb6c047a0ab37343ed2a2d1809345f72ee0921b06685f6356dca855053699d, + 0xb27c5c1f4f08810c4c71b00309204a5ea1602065f18c7c9568a073630551272, + 0x10eb21636ad3cc5b882f8eef50b164f5c0f05e3a45245b1f4517b3ba19693feb, + 0x139afa8d7c7016d8b50351f05260a2f1661a7be1166add0f281fee3a5fa57c22, + 0x10a8316597468b2f19a7ede834ff7ba4745e614ddcf43a373a5afebc45849d74, + 0xe7bc88dca5e934a90b30c06fc33c46eb88311db5ffd138d2cdb2376bcaf4ce1, + 0x1ed3520f1f7eb308510f20f8ad87099d28c26165a9deb3338c76fbc7b140b4e7, + 0xa5b057fe093ed51de90edec1f4fc54c24614c3540f8d36af16022affde42d34, + 0xfe1a3def2a011ba748f9b9f263e88aa32335ffb2e9857bb3a2e0a1d14edbc3f, + 0x1f6abc03a0caba9732b313a2bc3ee30d379088b772c6ed9e3d9d3cca471c249c, + 0x32cc35f494c7b826ddc1bb185d14421decdc35c89c4353e13838ec0de0e777a, + 0x3526b4fb75965e49be0d73d43e706e756d84f80db93afde6863cc49b017f199, + 0x19033bc3c4271ab5bafbeef999077c33386c044f05405600b0cf174fad12b8e2, + 0x17775184817378f639fcc8dbd97df0e13baccbd90c83f0b4807ae9a486bc0d4d, + 0xa9e1c95520650bb3f61a8fb1733069fb5eb759593c989c7c8c91cfa6108c3dc, + 0x5261006343d0f17ec876854ec7d41315565a07796e7c1735825e9dd2bf16e39, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x2fd7377f9006f870d0c079c8b10b62647b7c76cb481b2a330113cc7507effd1, + 0x1aa6d67de3f86bd58f04498f5e71270a58c7ecc20d81891ec7bcc29d92c84447, + 0x267b52a174ac8e9d118dd2d021043961fe9686c7156c324bfef84286a70a20c8, + 0x7131b4b73af0697a2a744e3483a653379f9a6f66e05821b9d12aa2b8fc7f52f, + 0x678652eac3805c1636bb62390323860ddaf6f1ebe10b167a39b975cdd89bb54, + 0x15209b10675cab6f50d0496771117e050ce5120126d241672e991c2dcc0cd1a2, + 0x1a1977bf61184ad35c53ebfdb3af41776eab03b2db826652e35ad3a12f745bd6, + 0x229644c842f9907a93becb162b12af3144a7c7f25d064d457db70e9c9cd9c099, + 0x17ed9abfbc0e4103e9e4ce7d1fcc95f2a8a0f8adde891b55e424f76a93f7a915, + 0x2104040d07bc2a79abc7fe60e6d2bd8ce79b937d7772ecae4e21cd38cef7f792, + 0x29b17696048b7c8b2805e7f2adb86cc14a6c54577d4d4b741c844203812cc98c, + 0x155b7c97543d530c1784eb12a8c8e9594d423dc45a5a93a6e2ab2aa25210f1b1, + 0x2d95cba17ff1a2f3ccb165e7009314c54d1f5d2ea514c54382ec918f0d18822, + 0xa9d8db94925ee88c53578d0312159ba4568c4c35b2160748f7dafcc99c966fd, + 0xb6f19b020cbf0eb74ccdceb22d7ae4730f72db5fff4462bd39941cb0bb2298b, + 0x2f709aa70fb82604e6614b07127fead0d6c889f96277da8085f886a592d8233f, + 0xc05d5e71c8ff96a669190965b0d7aed88d1c5df73b70de1783986bf8851507c, + 0x8facf13f8dc731b2f216581d4b35f10f3d54b6c41457fd83347417cc9a4dbd0, + 0x1bb219a4559f69a5e3ca3241a56ba26e36c86955feac34676c2d13a671f470ee, + 0x32054ccbfd7840e0fefec1ccafe4b21091c2b9262c0337b269d7bdeffbd615, + 0xad0e2165ff04113883d2e76bc8d519702644c1e938b80c614ef85b966c7ea95, + 0x5d0cd6f76ce14c2cc307b211409329b29fe0e80742c329b6468d4cb6c4f8938, + 0x2ac21c0635d3d249610b57d8312443a9c30fe4f353e75d7503d4cc646c7cc2f9, + 0x2c98f53ad12c6d2f2c1f4ae0922f10c9319cee3b55e1720799c16fa36c65af2c, + 0x1fafe9cdd001c028a8c9895b9075a18f93f8ad25632312000154e1b07d6cbafc, + 0x1c66e585cd1c5651a3b651ceba4e33bd7954af808b69f4e8171a58339b6754ae, + 0x2b8004d7066672e9c51b5efb0810da89bdc481658149d974641e43a8e6150512, + 0xf19a8fe86ec9c9146083520d9bd83bad613879a0e422c27e09cbae6558315cc, + 0x12199adee14b8fef20070207a6ebfa77f4f9202df37972a31e11cab9c622a3c6, + 0xf34bbf250e5eea168f1772d93ab7f53e1dc570c706dc9818639f0181174d8f5, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0xb2878f79547242381f83f53d71b4a5bb50ae79bac3b09690c2ec04c27952831, + 0x1636796259d819596441f2418e0c425ccfbfe67fb7b497c4361122748225fff, + 0x230101fb2086c3e4dbb4e19b17dcc891db81d3eef3b5c031b2b1429e46fb956d, + 0x2033e660632e0b2e8411b43b8b0fc9d23ba811a64aa846b0882516d954738316, + 0x244564f0c62510a5e6f69a1a8fe77d6bc22ec9989b0f97dc4113a2fddcf2fd3e, + 0xea22aab739936a78b3b85cf512de08c6ea303f53fb69e073d2da9b94d60ebca, + 0x701868cfc18808ef3f8196bdb7bf2a8aee96cd85d269db60a4cd5a1ff9b2e88, + 0x904cf11c0b58e3fe3aa7d70d8e365f6f20424f7cda13492c3a1089c3e209378, + 0x1d5930f08045de1418cfeab3a30c08015f77a7a19aba209b992fdae1837e01fe, + 0x13d07ccbe92ac9848da4c5651b692c3b298bdd002c76c1673e39b0c56c92cc4c, + 0x29fabafec859d0eaea7b49a815141e2d5e826c1bcf4fe2e2c4d80d0d9026a9e, + 0x1af5ab322e026a1b28a1dc06cba8585550db1bbfd3ee2355d8dd1c7d413126, + 0xc60f6e36113ce5d3b8824f68a33bce77f8a963eb0ac4208a35c0fec601a813f, + 0x17ac4c1dc0678e3afeeef3a11fabd3d699456839342277c4b6a57256a94cd1bf, + 0x18d140a27d4a76d1daace46e5201c2057b4e1353e6e6a90d250798e59b055209, + 0xf1336ac56c60c4bc9e27765f43bbc4a25830e514126dedcf518f1f501cab662, + 0x240e3c3a7dece37a8e4674ca411513bc5b2ef205d6afef56978ecdaa310a5fc6, + 0xc1f16c8ee024584c6e5243038d7324bd631263e4036e9df5422f78c8b01c9ca, + 0x236b70f7b76e6f16b6f4d08f6c6755776bbbf2beef38ed9f187294607fba3e4d, + 0x2fae92d9a4260c0eb67b8b5c535ef6f43913e506e546b3a1f217ecac1eb0ee5e, + 0x1e69a926148d04785f08760176dba2be1ee5b4ea19bd09135d5b68e7572cd1c, + 0x2a96f11408f216c5ade40371fac2bd452a578ec23bd220897aa3372513bc4530, + 0x1522e73fa41cc4c23e9ac6a6df46dc33e6921b802be72ccaeb06de4736cfe988, + 0x6d2c787e7b336c0556293aa8a6bcf7d31be6d8b6d4a644ce77b313bee3cdd01, + 0x1f80057bec504946a3e8d5e8d31412d2fb6461b5f174974017f2798fff57c306, + 0x139e43308691da278944e95e910ff3c4903e2faac75a6533e7f1fcf0dc8985ab, + 0x2958715623868ba98fd982a092a9eb18fd0f2cc9d3ad44d03970b8c2361ed38d, + 0x3d037c068aefcaf62bf84b4fe75a8a46a5d85d63b659278b049508fd31d673c, + 0x25f8654c412e7d630f046c138dfc4c18332573d9f2cdde26683fb472fc8b2edf, + 0x1874b9d07a26cf2fb8c65b8d47c6647008b42804af1e7ceb2c7ee466a2b5807, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x22b74f8ab6acc3f3ef0d9352aad479f2db3f5171684734ec6d18c69cfe0b14cd, + 0x28ddd3e0a84efcc63090346d5c5c0b9f7a6b8a20abd001e8ad01328ac5ff90b2, + 0x21ba1ee2990e2ba981f6e7e97f1aa879eda6e3e4a7f192be055d07d2332aac26, + 0x8923f775145f7243003eb5089160d2e0b4be6b68e77211d796e567b026e92db, + 0x2168e1158db076bd2c7503d8d78759b741f3d09e8c2863f1bbf77eb8a52f2bd5, + 0x2d91a6046ee638587087f34f8f3a45543e5a12e80db1462121d37f3d2f574ca4, + 0x19a362b36092714b50b86238ca35b3e9106efe2f1cf4a8f091a687cb71344a16, + 0x93ab3a1ec4ad5be6235fb805314d7e9f07ad5aafb214ceae7ebdcf81db72fd0, + 0x1e6f239f1cd9a373e4b8a283c86c7dd710a5aeb00a35338dabcd80e14079828e, + 0xf8b272d893f2288be54151a7c6e3e3e274b96a395616976d267ba31d59c0bac, + 0x22073c45cb975312538a8a8bed28c0a2858793e1e2a234d5fd8a6ebbf8098fad, + 0x5a2cdf46b89919b93bff18da44a4cf470a0de6b9bda0ed97d9ef3085678c9a2, + 0xb91b6af7828f5e23b06d2ec84a5acc0f6f670e64146bf82dba2cd09d8b9b160, + 0x26919b3ee33e46e95680cc8c216d561996b65915418a84d7b3d7bc0d29e3e56d, + 0x1615d651e47167b1ee9c70737c1376972ce475a1c66fd778ff5591b2e4e92017, + 0x1db6ba6e18012adf2f43482f224541dc5b5ffd5522f9336449fcfed6fdede339, + 0x157aee78ba392137b06bd8104872ec13558753788e044d38644249dde49b63f4, + 0x1bec3f9426534d61ef5ce8b40e3d9199d929a295c4b2e5768033fa7ba51f628f, + 0x1cc2614a3be0eef53905687b6d666d957c6f47b4f340d59106fc5add588b1272, + 0x17cc5ecfa4bcb4d4138bad0db4d25b8bdd921969465ce40c3783190855c0f9b6, + 0x2b71f219cdc5fca5c1ba861f3bcb51aa08fdfec6c8600ea26ea3f433090d9ec7, + 0x209098b02905832cc62767fa60e37a962c4cb7e51b23b6510389b56c510d3a61, + 0x22202b42235a0de23ef43301055066d26d87d0ac4ebfb8d4391b05fdcab190bc, + 0x27067a1a9cfa43df1faa7904359cebd06abc41ef694c89954ad076e296bc77f3, + 0x1dda2ec6fd0f92a515b4b9f0b80aa68260fd6570fe28c35acd8da5233c655c9e, + 0x20fcbe551e628d29e3625c948d92057dfb16a486be9fd88ffe308b886a7f3f5a, + 0x102b63b63b6594dba0d9502841aaa0bdf0d2aad08d25135f1090f0ed94cadf5c, + 0x2665d2b3b1f4711b362b28c1581c139aacf681f189d29cccde608c7f44dac4f7, + 0x2534e0a770bb00179e6f7621d96dab342ff960d361c91adb0f8faea486693df0, + 0x132de3965797959cbfaf61a239c5f09e1672d3b6387a1e34a53214e9d15c8201, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x1b6466ab641f7f30eb2dca03dedb89080833b2bce7b84b6a7b1eefd30677d2d8, + 0x690dec480f914c6f77ace87a47b0857ac7fdde73463e4b2445d4656c53653ee, + 0x65e0d65c2a3e1786c2bbfbf47102e427e9e31d2218112a86d821496a316d68b, + 0x2b5b1af812cfb77b30b821bdb2614c5f09aa73eefa9f6a48bf3eb146148b010c, + 0x260f7a81271cbfdc27a85f146221b30fa12e9ffba21d654a371bca4455a37bb4, + 0x2a2b6602a481c04475dacea41b360af3926cfcd4627112a8ed4192f213a823cd, + 0x11439386af5e26221df0905abda34142ce69f66151192d0143dbfddf3aeaaed8, + 0x230508e632c716e903e22a44c6002c2d39b1a0ee072bff9cd0901b3c4801e69e, + 0x23ce4e18ef472ed4e4aeb0dca528f14fb7301c6691d43e9632a65f1ec4e7bc7f, + 0x237dd8e70aa173bed421d4d488c4326af456322620483fe1a393066187a7cc08, + 0x24b0ab054d180e17971795754e027a756bc1f68ecf9cdc8b92b30b4af2c078d3, + 0xbaa7bef4cb2a2cbd1b33f9501ad22e365526a100273b8ef1a39152d779bdecf, + 0x1fb9b3569c3be925e480fd102a3432ceecdb59d346486b99d22284165df08262, + 0xed3418179e711b0a2d9bb44fdd0ff0c82741b531058111031cd123f508fc7a0, + 0x2e92aa6007576a4f815c645abb2e9ee10fe75baa5e13ab2a0b0aa700e084f071, + 0x2557fee713e3ed365d7fc7c6c07f113506d48dccb98510d84457b6d61c9a448f, + 0xeaee37321492b0595cc477585c9fe9573da00ad1619c7409ee76c625c11d447, + 0x1b9c9d4230433a193f315fab4f8cb8a7f4b0946f6241dbb2e858f3cec6c33f85, + 0x35b1d3045381d5053d0c329ef11458315d69335cd2371fecfefc8a2149a8583, + 0x2a0bf648759293e205b62ef858612f4e54cfa78dcf1fda84715cdde20acf4978, + 0x2d1f77f7bb34c7adcaac3e88bf34cc32e7aebb82e1dfec3491ed439c6b71c4a, + 0x63218d076827fb18e8fd4c14755443dcc3cbfa5bedb57a8aa1ed4b1a69b5261, + 0x2808b917c9417f47e1893c4a5b0053c64a054319988e721b42713d4abc351024, + 0x4c1b265648f11a5ed40c135675170ff486f6db120056d2b43e476bcda4e0876, + 0x1c9625a781c3530ecf4d532c0f1876e8281a454abdc914f34dec624dad8276c6, + 0xd9c2ef763966292a4585c0d7b4a1256c7b4687b8c19aefe0f2c5afdb8cb1093, + 0x11bacbb8c80b3caddc7be415c49d19c8207467eca352d2d65b3c950df899cf78, + 0x2f38ca64de487d59b0332f142c0cc9ee408f947e17bdf1ba7fe217cd50e3b088, + 0xa5b42f7d3ef308c007e91ad0b859f46582ca96b8a3fc12c6964b4e3ae230bc1, + 0xca6578515e51c2c7da9e898fa1541a6e93bea88ed529e5c1f411141884743cd, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x986957cb19cc10c36db88648feeeffc017bc7f344eca7e278313887c521b66e, + 0x2df451c36b1789c3b2a6719818a62d1d40597c6c2881225d9bcc95fd6d090f50, + 0x2bae223a93b08d3115a949252d906887fbbb2988c127c1e2668c55a00ef22483, + 0x5bebef52bb08431bbb9e92d219b4a0b2fe15e2f4346d0e837664369aefc1803, + 0x18842bff3ff8988d29a3737afc113f6bfb80c08d5a2cd06473baced406d3e2ad, + 0x2f78a8fabd2e97700ab4a2f2b5773ee348cbb2ee491bf33a5671c10e6326be6, + 0x8b3f1bcdba14103876b7f57f60d08ee3aaf9ea25f5495680a0c11876117feb5, + 0xe536221242a02f1c78e6c59133ed1768bb7c5805ad1a3e59066ad23dc8ad422, + 0x2d906eeeb9d7ed09f7fc504db42dfa79bdf74d094eab5d29fd91e70be78b472e, + 0x25ffc50d32b7badc1066a06268cdfe0a329957c10b2c448cfca1ff6ab6e0451, + 0xe77d99818d5d95b153667917050e800f778a07b2520e0cb2a8d9f3946a59bf3, + 0x2434b0943c80797cc13905ed7ee35a700a61bf601c7c3dfe20bd7fa3a62d0dd1, + 0x15f77d11fb4fc7c16e4a6670614d85b6eb833f0c96c9ef96dcc861bfbe2e1c8d, + 0x2e1db5f958cefae9e831f4d55d6c883847a2eb9f1b8ea404c6131e9cffcae8a4, + 0x205947544c2d5c9d1157bc26697d8e3c1949786e6210ab9deca2092dc55d4498, + 0xb9ba62195d29f54053e5fadce4e75e7323915fb2d047f61593c0cfe351c406, + 0x233eee9f5e744bce4d408b2c0fcd051285199f5e876fa3c6f6c99a289db64542, + 0x1818a3f0d1552f34caa7dc40defbb1ed62072bad77ff5a8221fe1bbc655e7dda, + 0xa8c36ed2f64ff121cceccda4d723afc80e17c1ed150d4d4afd9618a9be52fbd, + 0x2bbaffb37541a9f521ee370836ae3b6f0555f49b0569032f848e15e5d054054f, + 0x2dce53865aec616cfd8143aaff05c7bfbb728a48f2b81bc68eed629ffd6537f6, + 0x26a4a63df26dbff991a0fea4b9d00094354de33aea2f04f04312250deaf202dd, + 0x47dae867b6ada4550e18f2443c44281584a9b07e9104ab3790d65d0bfc2e15b, + 0x18672943f827e2833a8d9db988296aa281cac88816b11ea2ce6fc5ebff8566ee, + 0x1979353fb46d8cdf3b518ffe145af6a533b9ebfb990582fb36f31085546556a4, + 0x1b394c0b4ff11b67a1591f7d190c74f15bd83812ab056d7ba186998adfb5fbd2, + 0x2213fbfedeb46fb9bab30d5bbf854cd2945a30d1115a3e2cad6b771bf53a9c45, + 0x3045a6b98fe71341427e894e351402342da59067fc44b8a1e321de8b75b5384b, + 0x1e560b922f410efbc72ab3137afc2b4bb9d6d11e3d78ebc0c1ef970b8510b0db, + 0x793ace2e045d6dce7eb0c50bc654785c69eea92a5ff129ffe2b8224a4e66987, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x515c94018effb2fc24a7bb89b1a1055a274cce74cd1bb4fa3751331c55a830, + 0x228884947d2d1caacad64b4538521498e6a377f1f531c032a41e8c5999ce7fd5, + 0x2d7bb807c37a5dba31490c8996097552a930e55198a0c8f787cab498e4adf8c, + 0x15f5cb124b0a18bde04db081df667eb90d722fe38420c7a6a2340dd57823d4ef, + 0x2fdb6f2f83a138c09aaf67a5b7f4f2d21f9fb72def9246f8350b3d50fdcff090, + 0xdcf875be3c34cf38d62be56fe936e1f76d10f01c9acb657e4dfec02f98c84c, + 0x2f2bf29d6b7637980d02644b98030297e4ee87d51476bfe02e430700993b4e3, + 0x121dd63b185a3fbbf1e26721e1dc9207ba6ce83246856c780f1ff3f457925f1b, + 0x20e79bcfbc14855f607ffe7efdc0408b2366241ee80d388f58fc83f1140b4fc3, + 0x153dc31be4cd79fbc0f1757612c6316f994560d88ba2a0936aadabe71d3ab4fd, + 0x13804b12bdb77d63ef5f9807e60e1896a5212e1ce314a52f1e65cd6051545ae4, + 0xb6cecf0b015284998ff23c23a7c003629f8ee8f8e52d85ef6af13147fb8bb22, + 0x267f992fb1c5fd7a2adea64c4789617a205686c01f9743e29c3a36910902f83d, + 0x7c739e819b23013c6b2bba0db1f914573d0be98da778fcde3c44a82e8db6a76, + 0x15da652416fc44056205298e4837860a96e1accf42af4ddb4b6eec42fbd303a, + 0x1c33739471d1bd4fc613afe1e38b71ff3562acde29dc58bf6cabf73a192b372a, + 0xedf8c7db59823fb1f76cc67e0e3ebf8de8dd7cbe69ec468515a5f5511c8c1f5, + 0x8334b72ea2d0d35ab3dfac4f2696b0d980b65d6e0ec61fe2724c896bd3f517a, + 0xf4329ad37ea22a16517b9b1e6d38afdc75a8398df9b9a32aa2f8f2c3346e289, + 0x1f8d3e31cde1c2b3564ec9b8acb6d3dc56b946fd1ea3cc6067f04515fe80c352, + 0x94a21c0489acb58fc118cde1013f08105058d9e97d6a780ed30705c0e54a838, + 0x133b634d187f62fd2ef6d63daee9d3427ac1c9e215749786a2e17cbabda7dab4, + 0x18e1b03bf875c00f97c2d24bf7daca95935d8b176bc767f5659379937658f599, + 0x18242ad22da674a26206f354d85be06760137fa512cc7f30a5e38737854159a0, + 0x294268b5fe2beaa0c99688e9a9e4f7ceab6a87dd42bb950a25022247c790bb6b, + 0x1f13839b65eda77875e30eae082527d8b68a45094e0c63295a7130b78ee8ddf0, + 0x2baa1faf25902d89902124eda3986279278cc6007b1f7b0f193732e5527fc69e, + 0x265cf033142c6d433d701a040d8f9f35c15475a6c7ea5875d74927d37e3a6968, + 0x1c4eddd1412f02358286bf07dff4ab2e90e5adf051ff5adc369e93c3fb78cfe6, + 0x2fb924230c90e26ac6d37357a6df214f13c24c73725995873df37da56f7a3e77, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x19e494853af32baea08fcd358d25c37baa7b42e14a74e62773713083679489b1, + 0x24663e25937795d723aba2f413377e470b84418061ccbf2e7ab06545d4f69b15, + 0x28194cd3daa20ca6ae03a8dc12cc30cab003f2a1b784c9b64436a984862ad41a, + 0x3004d9469414f0a772c99f896e7f27c8d08abf0dc7e30feb91b51820e4591fc, + 0x4a90138ae63af6d831112c04dce879f943302f37a462f0c84b4f4b543737a2, + 0x16328fe8bc9d3c883accdd09cf2861ff33f072bc58cfe580113864913a5820b4, + 0x255342bb3760148dc048617882768a4d198230da53b4ddf87e5178ff4832f301, + 0xa494240f29dc89a98ec7fd0f8a70c3e82fc12d2894d92b36c5e472b51cec0c1, + 0x26d9764b65cb6775899164e5bb179aeafcaa7c262861bf582c5d6419f86946da, + 0xdc64acc51842f225a439b650e5eb3266d2ab80e7ac705ccad646770a338ea77, + 0x42d122c394166798b946f03da9b3e06fd5ba1fdbba49d3cfc9ece8244426044, + 0x20715b9135e15fd039a728fe347d6825e7cbadca0c792e2755921003b7cf9cee, + 0xb8465af4ffc725e0d9d50079c16f1a5a7d8df1fc7067728535b10e19cc70e32, + 0x1b3fe32fdaf4a4c9b5186604fb4746695561720c1a7886751635b2a416b4e37f, + 0x1ae2fdac7b7d0b3c4739dd9eb27377b3bad124823940e12d0bcb1177c96e0788, + 0x1e6b8f955ed56d144d1650f250bb0f8a8da2b631d38d75e6bca34a687eb96a5e, + 0x262dc534f682c8f874d877df14acf8ed7dc65a6e42198570d15f49520745c708, + 0xf9a4f0271d5c6aa02c42053a8d2b1fd8179a35cadd4f16299cc0037b0b16d6c, + 0x6f078c71788acce7f48fcd7271d85077c50ffa7a82ff67d81a10ddaf70d9301, + 0x2416d74e36b42dd5519bd3a03935b57120b33c05265a40cc15fa0b36e695185d, + 0x19efbe964add94b60109cf8e6795b8afb31ece021bd1e99e06a39b868ba5da18, + 0x217825dcb0fb4a2debd0856679d5f138bc28083b0583bcdd2fedd8226d71ea20, + 0x29ed9e1b8a1e7d0c5dc4e51ea5f277614970693b65758673625a6b81e0ea6305, + 0x8e7139bcf5e35d8c2826234a00c56696400cff2b012a94a6eddd3d1ea94e4bf, + 0x23b45cb4566041748ed409f32aaf3b7d59ec85f8ad75bdf008a733d500a24f7, + 0x59e1a9cc4208e8f4adc17e95a8dd0a0e0824aa4671a24075116ef1cd29ab280, + 0x1084b6a7bdcc2947835bb7f017c5fa4a018dae7a14db23c1f44e821a65434e3, + 0xae92ed115475902606d7f3e699d95659acb152108c586a30a912750ed18b0d2, + 0x11540ba858d368852b75bd5e3d31e289a182f3068ed6c2654ed4c92e9d4a9a12, + 0x219ad9e087618d15eae3780c3b2fbbbcb68667bbedb9d51490a04e4a2986b734, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x1af405bd496121de8bf68db182c52f8dcd863e5e9d0d07c332702c652f103155, + 0xfb5adb4f2ddee2c786bbd630e10b6af21566e13887264d2627e965b8a7657c0, + 0x5735d0a20981c3443c26321ce6aaeb22867087fb482f3fc52564231fe1fbfa1, + 0xd5f25ea7cd06c95915cabc11f61a2a640b5109771238b53526673bf353d8efa, + 0x276d9d19b50cc160870806a1622acf7cf1df7a5c0afeec2dd77a0962acf14cb1, + 0x2d52da76429ebef4234a94a2cf6a41afd471193888b6fdf668885a0c578d3c03, + 0x24f84ab4d1acc7cc1b4f842e502865a26591447b8bf24439782e17e032b6f535, + 0x21069f3feb18a6d2025501270c070b1bae6035caaa50bc68b6b402a909dca262, + 0x1430dd6ac598deab9432e5227ff5fa9da4994f08ea28a781f9fdae630aef746, + 0x6fc0f56ea9867dcc10385217771bae7c1901deb59d89d694a14fdad07ef7456, + 0x2ae95e39f51c7935a52f31d1e92c2fa1e2a2a43ecfff3849368a226bdf1067cc, + 0x2b53d9abe894c47db9a2e81ddc1ea0cfeea5ca257e8c0ae61d4c9db5d8a918f2, + 0x18dd0925e43f821fb7c3c9a72e5d409c13e5c42f35b1268e9b36685ab6c60a84, + 0xff74b6d96a8d00bb97508280e98c10a1eff834b46b15f474b9f4fe50174233a, + 0x18bfa382970f3598061f30c5c18b3e71105a5145ca3e6dd21f779395872e3616, + 0x1dee9f00f2b7548ffa9cc5a39edace63c461c528a7bba8a17f59b7df6e247b99, + 0x12c5810e9946497e1b6f928182d8511851683ecf234de99c649bcb3dbb8f1e76, + 0xe5953881e72ff398e4c34b50c3d66fd073fe79073f7ebd593fefdcc7bc4fe32, + 0xd25061d2528dd5351e4e8367c96fe57446429956594b2f752783f06251e1ddb, + 0xcd02124b62741431f4baa64fd8a759db1fe86465b36f26e7e91ada1a370e031, + 0x2d524e2c0a167d163be6863fb345539da3a8fceb3db496b765ea2fd7c4fedfaf, + 0x9f6ef3fd9b8eb4dd5cf6393f681db544e7339f6a129f9bf8e380041e0a43cd2, + 0x28bf2b88d392ba9823e2db09d12cda5a103b6e2f581a9a3abb8ce25c5d93476c, + 0x209e08cbdf5562b051300a64f3cba7d75c25e5032a2cd5331e6cc386db38c373, + 0xe18e80edd86792ddd92cee432ee33b15fc5102cde0ace9f8f7c9fa0663d51c5, + 0x27bd8795292bc68b6a8e0ff451cef39f92f7af2d407c1cfcf60297100a9c4841, + 0x87d2427a36da27e525bb1956015bb2e0811c037a0cc272f230cc4f18a756a13, + 0x5e017f8cba3d41aff70fd421eddd63f464254d65c086e7f5f07981790ffffd9, + 0x2eacb959ae5429d219c66b722feea009060a093d33df0cdf225553a0dfc8e7c8, + 0x27a8c07ea74055992c66e0003c03b07c090d30d45b940d303e51212a974f05b1, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x25b72e38946d8c146ee356367981e74d001803430d4ae023d08a9c68ce8fd58f, + 0x29d3d7fe8af458f8f444fc49c4cbb3fde970d6edf8ebd7bd3d067d45994075ed, + 0xdc25ac6f52dfc613dae0197322a98c7700cf04dd9d1627c90076bf2384b32d1, + 0xaf71c0bd1542973007bff10dfac94ee18f5da9221d3d6fbe04078971e3b80c0, + 0x1406d8cf97827b7d25ce71e62d17eff80c493bb0e1f2a6b951723431dde17c18, + 0xa177d75332f2aad209c9eef8004879afd6acd5ce56db116f834053ab51296cd, + 0x1e42feea60f7d4987938dd58bc9b53d4b5ae4f8ee14b2ad58d723c7c86c130d2, + 0x2c5921fa4ccd767fd2533f308d1c18c63cfdc3f7d8e10b217fccbeee2aca0ec7, + 0xac4e3d803a6c602ba6fc373c31988c294649478134d462772dbb91e40c56595, + 0x68fb1f094571ace723b59d1a0595cdbd2631d93806a5f5c758ce986289ecd0, + 0xf5a472661affd8730cefc698d6688fbca3ba07b12637beb8f0722f2f5e8c8d, + 0x2ed5af998e49f3d9c92a5badae4eb43a516b1ad840cc01d11c8a441786316c60, + 0x9929a608a5256575d7c287db82aacdf5381830b9e18b23ebdfa2adcfb46dbd9, + 0x26639e520710e998ed40fb1369c7cb039bdbe0e2e5778055072c8a5466ff9baf, + 0x2b3225c35a88f757d4c773363b825191df51b0e1cd4082541d382aff5f7b3f3b, + 0x1c1a368cc023f9aee70e3e53341a06e8095022c5413ff1de4286363b4e1b99b, + 0x1b39049a6f7088294202da65d65bb190d44745fb93f4073a00d473d38fc37392, + 0x2b966bc8a897d76c04f943c5a7aef551f3c6040d0586eebe1f4989a0248ad79f, + 0x67a2085143ae9a245bc66bd3374eea946135f565cc0efdb6358a3ccde5b6c6a, + 0x27c3ead3d76039b10f3bfe13f32df2823fb8ca146d9aa6b14d8cea182aa76bbc, + 0x13ae8e66bda5f40ad3ce0e83305176d5e73b03f2950d5dd78b1087651446f60, + 0x267e55ad34a8788497998b79193846c2822a266e8f60799978e66ffbe27018b2, + 0x1a964c5c4550c29516171a8a8766faa7159a1376a836d29809d5e901a584a686, + 0x216cce9e5b6062cd063ae93e53efdae64cf5479ae01d7549f8cc7e67a600d184, + 0x175109dd08b4de441ba589607706769fc506fdeddcf56ad57d0ec008fc3816c4, + 0x202ed46ac0e68827ffbab076167ceecbc7a9614234fd6621c6eeeb7283e439d0, + 0x2d265e49f35dc88b63abad32d14302d3555c221ae8eff1d3399a66959ee87e6, + 0x593f84a55c9e3af185e6e8e689981a9fbe1ab6282f393bf4ac2b77be21d91d6, + 0x2fc4427295d575a8fa93101a1b916e123f2652e7e9e94c364c4abae0a424334f, + 0xfd26a5a97c3cbdbec343e616c0d93f25d7c5eb827748114e4da61c017e25478, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x163e039587ae8bed242103f972c58d7b3570846f3a9ed3b6f65ca9935e0599e6, + 0x17b8c9347540a0cf46955fe40c29fe36680969a074eb4e1b7c40ce0c543df4ff, + 0x28939f23d63d09adbd1dd196dfd73eb65ffe2fba07a79e2049a8453c7caded55, + 0x22f4246a101673a3d58ce953a3740bf807f25fed08cebf1c124565310b10caa1, + 0x1335c6f50549b22023d2a973807c510d8c1b7e228e8629c35b7ea3a701ed0277, + 0x5cc88a2ab03f9f720d841583cc8387313503e804be95d3311a64d0cc3cce9c6, + 0x2000d4715746fa36d8abf22861719b23aaecfcdadcbe71d567b1bece77601904, + 0x3c2c00765201729fef4cb1ae8cef326a7de4f3fd5803521e715257f8b392e80, + 0xc5affc61d51001d7b0d8aaa6f99d44cc683af806ea1ea1d241ce56f386b5462, + 0x153a431981ad712ae13b7530797e5b2ab77c125bcf530880ac8566ad3a5ac417, + 0xd2047081d9a8fff7773d8011bbc0b61a6057fa6f9a1627a3cf321fdd666e8da, + 0x2eadef1fd011162138dfb0e0200683a3bc27e1ad12dbfb2b94b32203186e591a, + 0x21a05d0434000fb05886112242958d74bae54ed2b6f37ece00b0293322e53253, + 0x19732c8f836170ba403a0d379561bc5aa6eaecf21c4fb9fc26cd44bdeba475ea, + 0xff30532e9f7305c94c298848cf0d54dba01341a79da4db0f2a975c2e4380372, + 0x2afe8d3ea06405c8fcdab50d6d6e55b6faa676cd36e6acb87b3836581b06b46, + 0x2fd228d6e4c1a1acaeafc4597d69fa30e56282d8f11d4cbd09c360dccf546f80, + 0xc203a0ea25b7f9b4066daccb2928dcfb4d1cc0cd2d14671fab5a7928603c8, + 0x17ecb26056f6708cfa3aeb6274c3352d6bae402e4d2414526e4c2a2bc9b8e0b0, + 0x2b5745b27a5ba71c7afe5d1bf955c578d1ce3c915f4d30974f225f6f7bad7c8d, + 0x1a6eb6c48b529c6a0a166e53fa399fb68e8b414869b13ea713c1a0cab8480c23, + 0xac89d6b741aee6c180408d6006f130ed945185ee9a213dfe3c8baa49330ee36, + 0x86eca38e64cdf2e252134d79160d437d92537324cab25cd8698c5e92e94632f, + 0x2bbe2bc0467c7a4d9d1bf2157cd5cc3ee50f10166a0d442c706d9691ee60b8b0, + 0x22c4c3d27515f300d879e8bb85b0447341cb7a816d6fda516cdcf31386998d75, + 0x23e31259e8fdc69a23a603b4e5b47a90390966aafbb1f4eaf02f783219acd1b, + 0x20c0c0f899d24401bf7084d6d0be314dbb3ec267f87a2e8d3769a1f64b469a81, + 0x2daba47175558a5930490cadff1f3deaf100589f676649a3a2fb1dbd9bcfd3c0, + 0x1e759b766aa310dc7aba2245608ecaaf4fb90f509cdab694155b47e768af3417, + 0x135aafeb5b230e030273e42ba704da43085d0ef96408ea8323e7be8b546643c, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x2ca2e70a3d8145f60160984452b26220f303eaf6bf539c8055fe2ab037a64883, + 0xb25881ede6015137cdf99b53a8591aa6e0c042a5a8c6a9e6fbcd11a37023cf3, + 0x258b19d1bac9e53c3c5cc4c59c87543b0e9b33a5e631fdda56298997a5781a7a, + 0xd6e7177ca87aa3326c9420369803583d1a1d8d96adc6acc33a3e58cdd3587d9, + 0x23cbecf6d9fd7bdc4c426035908bdeef9c9c7a801667ff2b62e8ead282bbcab1, + 0x2841e2ca97eb7de3733f8a6d3299c6038e8b17f9d133ed12efb4dc6d923d804f, + 0x2bf228ab9b7490f4b0ce01cbf31bed2ee4a6ddc6d5a00a608ef1c7ebcb5a203a, + 0x22eb1fde7a1c175f0c152d5f7f85045961d2b01397db24d9de95ff0507627f0e, + 0x100932572c12a0bd1f2ee8c6b0af317dc5191c3bc2a177eee791d6e539e5b237, + 0x27e881557b4ec0f1128ef0069c22a6e5ce4fe48f7bc9d9789c48d6948bc24c85, + 0x25862853fd1b44c6aa26a414ab4f295aaae0fe4457e0fa0c4bc5dc9fc2972246, + 0x3947c7ab7d714f1f8d4503829e2edcd06baa8ba87d5b86354bd7254b841ed64, + 0x2676b506a75643609e6b0dd8986b8865a93000fc38eeb1f6cf3b026d6191ed47, + 0x1f45ca8395b4868c3b68b11911f52425202fcd2108aaba02230dddca7b36546e, + 0x1b5fe89e54f508b5188c8487302834d08095b14c1e0938aa82f9365ca3b2b44e, + 0x25826f9ae3904e80f7ded17b954c8989a04a060326ca40371dfa204e02b05eb4, + 0x2b5324e42bec45328632622c82644bde941e015946d2d9219dd0b805dbab5c26, + 0x25e011cab809208c9447ce75dbf6c90f76c6d50640829b861c2392271a51ee91, + 0x58ffecff608099006fd59ff7d75f03a528613b3633d1dde3fcb5d6f239a648c, + 0x26f052daeaab76f2ca8e18584b8586ae9a8f591a8b97a673d82d50be943aa00f, + 0x15d305bc6e3138c409925caf3968367850c6eed0384e46009d38bae5df81fcc9, + 0x16f0c3de9b8a76ff18370cc489da46a9bd962742fcbb0a0ab0aee9d12c3c5fb2, + 0x137a4fc5e63da4a366b6edd41e255fc4baa73ba9662ab7d2b69e0b7d4986b562, + 0x25a59d3b46f5c8b7a763518797faf55cc4773967c1772b01c7c23f186a75178, + 0x13df1d61814fda2e0d26ca861adbfe9b6a92c05bc3afc953cfe008d176be2c30, + 0x15b63fe5843c661cb40dd42feb664dbadbb27866e119a28f9ed8d35b537870b0, + 0x23352a3a3bae8c2e34359d75bcc9a5d870b69555ddf57948caaf074538044a80, + 0x2d223c52d6fbcb0e82e9fef6b9bd7384a2b789c4d9c273ebb35b4efe8e51e75f, + 0x1f208f14c51b48c7776faea01878bce6507182ea071505581658173217492863, + 0x194984a1a5106ddcb1bce1299b1b043edaf26b85c4afd80cb6785cc5c83b346f, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x28bdf0652d4964a6e9ea2faa6ce2d823253364d311762578721f87736aaad803, + 0x1183224ea82a68db5fdf6a21052477c8c8ff500e97b8cedc09427cbc02d57e6f, + 0xc61d22c912bef8507c6b08cbd36f7cb7979f3b56b36549613794515eb4e02d9, + 0x2ee8c7f8684dedbb1c177fa9f2574a20cc4ff3c10562877bcfb0d53c90649b77, + 0xf56193999816a0f4b15e38974273b5c5863422b93da9e94f47c5f10351d4705, + 0x90b70ecafba579d37d6d211358523ed992e26d5a7752598bbb68b637a59295, + 0x2de97266af0468dc5a587231f1b1e3aa2cdd4d1d7208205be90826491f263752, + 0x198553fff8aa46adc9af3b38d6c01cc00f1a6594ed0e1a8b8f370965f8a89669, + 0x192b3300ef2574b4a7053c24d7dbdea81c04da6f3c803269ee85c22c110782b0, + 0x1f4c7a76da30fd0e604d14833d0ceae25eaadfcf937d4ba5a6bd7507b70fcef3, + 0x11194b46ea91741f761662d56b64c9d127f2bf36142f681bca579af2e8856cc6, + 0x13233cba082bb1579428bd4a19847aef4c5031956805f6e2522e00dc9a92a087, + 0x6fc54c9a27cabca0bd75d53cefe2992bf4b744ee1f1e0cf7c254492e584886e, + 0x14870645f35e85921f579a47d013cf8812201a133bd14b6f5604f77c10ba8ba, + 0x246344f1ccee4dab0e0409bc96fbb618937e6bc629d9b1bb83a669055ee9e210, + 0x1e1c72c73d9444d6bc46a7834c66426ce4bb91446e804909153e6bf86511e628, + 0x662c514923e41038cfd078fee4bdbe72c8f6e90e5a3cfa51082a1a4f7523754, + 0x25c7e06ac250334f38bd664db0bba786d54e9d40e7c104b95989232ba0776db0, + 0x1c63774bb6aa72c366712c86792d85668f833b7af35eb91f36176de375fb2522, + 0xeef372e915f3263f31e2c3c4d214b4c9aea86fda813ddbe1cb15441881ade05, + 0x29db12448c6eb73422accef5a2a3794c7f372c283f37b2b194cbcf09b23b480e, + 0x161b72d834fdd269571186b3847084d251f4765a5b9ffaf77fe720319e0dc7c1, + 0x2434332138c93a69feb06521af0ef32c08b680bb50eb61398e377447ded461c2, + 0x140867fa61caa3dcea10be9b46b76871d983e8a7952e3d1f71aab2f531a85714, + 0x1e3877e58d7f25a988f737f229650cdd345c308a37c66366683771f9e249acd0, + 0x2e00f80aa5ba054560070a3f21c0bd37e311ce8060a7cc1c64650560c9715088, + 0x9673ea23dba537a4a0f6dd66a13df85d8887dc3431666a86730becd72f04fc4, + 0x2a05b10d1faf68ab7e607388f7c9b3de54bc151f0b2da02702e471eb5b786a50, + 0x2e8fb8bd00af6741fe18ee679ee378e8602ce8bbc429ca9986d016e17b2fb22e, + 0x23cf3f042a56c7d2da94772521a21ae6bcb3fd0433f8778cbf68fe1c365c8c08, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0xd4d295bd6bcb6716dd82907d89b8809a8af69859728773689e073bda41c709b, + 0x14f8df38aa9592d59519054d8f0ac2c79b6a1303905a9770731a3a7081b2bcda, + 0x27ca9533e2a56a644d35c53fa9cb66187a7c0ef7322168932c330724edbfbd0f, + 0x1acea5282de35d35337503c8c8a221fe22bc24d39164850efa9a7acdf1377f07, + 0xdde135f69d5ee7253d1cfffdf878b3ea75ca2c56b15907329147969fb120d46, + 0x8565cb565140d42d33d5b907a0e23f7af7daf91ea5aff759fd8ca916579ce25, + 0x19343a528505b6b303ed193e33810a005abe738057cb00f34c9a3329ca808b, + 0x9cd47fc8ac46b3e49d737eb4714d522ce235c1b0feffada0852d8173d4b080a, + 0x2b87d075e7fab29849291a7700eae8317cb01676a36c0d2c138257b852732a2f, + 0x106694e160db35b2d35998e4ebbd1769c69c448afd1ce6aaa8e1bc1ce53dbf4c, + 0x163d91a57022a4734ea17ab01fb85d94622acff6582dcf7e4b46dd0a5d72d823, + 0x2b8cbbe66ed1e1d9c5a1361ef0a80599de75573c62d6e3aa718ba233e2594408, + 0x305e4c4a93d931f927f0a213cebe1a5a3b258ec726fc912ca59590febd9b6020, + 0x26d0c3492063959cd8c3dc0e5c791356b19b9bc6e39b4da13a4d2a612e56356e, + 0x2076ca2026d04b98f821b9bd52d64fab129526fc2e626fafcc92d0d2e23a33bd, + 0xd89c4483e40c415d266d3c7f2ff6d1d66412132770be71bcf1178849502d231, + 0x13671ddf2f49e97410f41ead0e1a80564d862771c7543664bd20762324fafdbc, + 0x19694e401d2bd6b6ca4d8929129a85c9e8834e40fd1f6089da9bd69f66f840a1, + 0x1a801c574279164c937f3798748bf115f09f56044461771cdfd67c9606f1a170, + 0x7359e7661550f4af1bfd7620cedab2b030fb9645b06945a8c166a617423e588, + 0xdc31ce178e60f8dd171002e2e5849759d9caefc7dc7a1fc551b677b410c4274, + 0x3b7d51b2b8b3390923b28d0f1e181c8378bfd0910f03835a1edce3ded58ffa3, + 0x20feaca74003f750c7d517aca7f2c181745a7d26a47051da7209fd1b3ba67aed, + 0x7c71a9d84dc8d9b2d223b3302e1804f6d6cde6702ebe991c5c976a4aab0971a, + 0x1ff2e7a7045e92d955d0b3a679eb1168aaf735a7cffec5e90fd0e47fc946ee3b, + 0x1ccad4ad13abfe58d0a69ea967e9477f20630d928dc93970033796ca8049edd2, + 0x1d2277a4c8ac3e7ae945f05461d7a72caeedb456f30c1e12911c8e3dcc3a66b2, + 0x2ec2d28dcd7e75e100c13ef572e9e270d251a774f44b7c59df767ca50fe10434, + 0x2ea447c02e059970eb92d1fd14b1ecb189dd900b281e67d68b3e742523c6a801, + 0x2b4adec5ee014b305fdb460cdb1ae30796202ec0fe11d13c23dfd65703f0434f, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x1784bd17cb0965878549fc4b0e1b40bea37668f94d8da890caa7bd27d22cb2fd, + 0x149f1d9787366b84b3fc40ed430e96b646eb16901093590e7b68ba3601c364ef, + 0xe1161f13b91ea8432e12df3ab58706410da5e6a10ad20b1f62d1c34c09cdfa9, + 0x7e6d996431e217b60bc4d3e74aa3c337263f1183c92cc73807d19e59c4e6804, + 0x2086834b2a03db22c71e71dcbc89688aa02cc362496e4992be9845f57e8bee9f, + 0x1a593864d072783fe6e1ef8ac83665aaadd593b63b3dd3d4919237bf5b2c7106, + 0x1570ec833fe8f21ec48539c6ae273c34cae3bfee0acc5578c96cde92b493680, + 0x13b62a93db33b6f0e9114d3f2f19c083b397a193f6ef0f5b087f2079c2581a9b, + 0x2ab8bd24dd963ee466e2e0c3380cc88a4f82397cf9f7dada2d80ad5ea21db875, + 0xcedea082a17bcba725bc9633d2e5e67fcd43650e22b22df9aac3037daeef8e4, + 0x5df20d895beb2374b5ed6d81ed5494a6ae0e9c3bc184d7861bffbe7243b616a, + 0x1ab529db00143d7038a6e01e23d0e9d56ce89bd34002727061c8e56944e4003f, + 0x2548c562cab2de540520c050393f949e10bb8d9ed4c3fc387e21e454f1ac83cc, + 0x29042d35cc97955a80eb09f15a15b66f0c4193a58193a080662b6a5e79e68051, + 0x685b96bc1e8d70b1a7b70216b5c74a4e5db315dc36faa59eaa39f2e0494ac08, + 0x2ddbbc66fe69dd188a2e9c306cf6f7de9faa106756186b82f3fb440dd0b912a6, + 0x18c70260e52a67ab417aeea60b5d3f88eaeea2508829ae7ea3c063443cc0945b, + 0xfd423845f9f9970561e33fb0f913821e1e3180dbd45815a9238ad515543a634, + 0x6715e87f1daa773cab6957c11605b0c6ff2ee937057373dafdc2f284d95b1a9, + 0x20af32b63bd2e6aa4adb6d0f474ccd105b78a2dbb269dfbfcd615d4ccda0666a, + 0xa4333899e37c411cb633251ea98d8858dd944f73c4378b66fdfa5904ef8d9c2, + 0x92b057185e62fb11b22b5f3583d1943d561f827c54936cf20d7106b9416f3dd, + 0x1eda5120d5fdf5f2cfc9e303a45a4ac8710bdc7a9c28b5e801eb248f60ae08f6, + 0x1282a8b79cc5039edc8852ec1bbd5835f3b8004ccbc9a669f88a331e966db3d1, + 0x2335e0bc60883b59b1390d2b3652ed0bef230324e7fdab725a5d4743d5fff8c2, + 0x2e23e4d93a4b72ad0551b740879ffb0da4ee65bdc1ab71f8207d2d9da0f26d01, + 0x1b06fee7ffca419618d3bb646a203316838a684e7c878024bc058645fad01e55, + 0x66ddb3bad4a4b1374fed6b3a88b1bdc812ddf9a6bea1b028735dcf90a77bdbc, + 0x280b71aedbbd3761124fe6fad719c6930ce0ef6695938cce777ab77ea3536637, + 0x21d130fa258f6e1fe201071b3d0f643832f4aad07a3a983ea00c26890b546e5b, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x305f7337dfc2c6591e5b3d53a4783555e1ea91efc44648529448fa3e463333eb, + 0x1d69e17e5678ac53a1c046ed0326666c84b909b85e5aa9e34e516d26ab655573, + 0x1f5d0bf5a9c458a3c9c9bbe3fe48211a1127a176d4f54547aaf34589bf9128c2, + 0x2385bad332ae963b60ae73862cf86c5f723dfd37e56b05918373912d8f9754ad, + 0xd68dbe874d206f45efd8724adfd9b10999a7da1226c394c4e7959269a17a79c, + 0x27f8bff9822ba76b43b54939686caef37cac685d60efd3bb87b468808b480c1e, + 0xf2cbf2fed229b81bf91c08a642730c9633136dcf1e68907c192e34464560b24, + 0x27e6783451cd61e229f062e38e360d9d022cc244222ff2128d4901de0c5b3c1b, + 0xb0bf852c95f2476ab5280b94660b1d9d2cf5439c34d7b6a928d596b13555f32, + 0x2b543c7e1d2f84fac470489446df876c7f64956d82c8897e268cc4e2af130a2c, + 0x4367a2851e9b84ece7172ed126f7cfb63d5fb445ea19ef5a31a67517afd2fce, + 0x1dc8a2abfce437021fed52e83b1e6708a20e07d84206e4c6038bb9ff36b325a0, + 0xb217141d35c2aadebbad8d9a426b52df23d7db7c3c72f0914963046e120d5b, + 0x10682c3505cec77ba65f4af68963f3310562527b2bf1c812c04a2eff94d33376, + 0x2f3fa61cf4696622abc02bd664be628da8ff5f9b49d93db65af12a0ec0d25593, + 0x3798c88da7c1c70322f72888f6fd783585ad279f4cc06029f3bb23f3c32fd3a, + 0x154b3f2f885e3d61fa5c27875fc9b03509b9f36a18981b13e1aff4d29b7d23af, + 0x45e3caacff06ee391f46ae43cf78a2ba1e2134de0405120228cbad0694d2fdd, + 0x21a443268cf1db0a1edc3f7c366de6cbc690e1939658278de9679814a5ad4a30, + 0xfa574382520b0170ac21d000d9ab5d2523b5f86758226d49bab96fc1ad9c59b, + 0x1b8f07226473c28fc3cf78ffe2f5fb3967b6beeed42866814c648f5d4adf5fb6, + 0xdc48483de7d0df83232e5a41cc287618b7957ad2fa3db03556429286ed6a2d8, + 0x2327d3dacc8f80fa05d075b7f9b8544356c04f4e600f53d8d4d2d0f147590eef, + 0x16a6266bd6ed429272c69aac579c9032d9be7e86973b578f27d5cb8d2f6045da, + 0x9eb4e66285aa7cbb62217465768138d73953baf7eb68bcad15b749419255e25, + 0x15f3a6b27c8a2ce27e931cb599a0bbaf6042cc6f8d411d2daf1969c02c67f5e1, + 0x2727c9236d43b41a34c74c52420674daadfafc76eb313b17fcae0e77ccae7bfa, + 0x149bd00eb1da39e22ab0d8dc78d7abff54bd9c13ba38a6a531f696cc993a3f96, + 0x13ebcf06a5c9485e1767a124c3e035223eac6be5816041fa077d5cc6fcd10228, + 0x22aec7f8873c75702e0c55c1b1529b1290831cb4df73c3ae6441da67c21e8169, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x1d45f9fa11307f6de88e220e633519a3ff18d9dd8071a39b38ee29d5910fac47, + 0x215ff3e875d70ad4b7aa08800aebf47f83fdd05a246186a8ec09f674ef5aa160, + 0x1552de26acf195af643fa2625cbd3e1723284c2cfd05bfbc23495a0cf88aa369, + 0x1f9836a1eabee49b2d2e6cb1f1f666753813f5201323d302faae128f08e45168, + 0x1f8cf510bcd58b2fe258f3f812dabf08a301a71ed710d4647cd60fdf5beb779b, + 0x2c446f645eb661152de44865a3ac149bc20a76447616094884c9b6515ed45674, + 0x50a3718e48640cb644bb787fc184aa61f4e44044dc0f3f3006ceba81b8dcaae, + 0xb370b71f98dc10706712c7f348474fefe5dd772f6786fe96cce94999cb09fb7, + 0x287473939b5c47568612b150cdb25b30808c058b4b5a3633c03af83f7a7e26f2, + 0x1f5ec7598f6da577826ac5afcd6ec3721b963562999125d9d356eac51d0d513c, + 0xa9850058f74f3196f58585e6fc80ce0405dc510ea89e33eb1a9c87ff91e58b, + 0x22227d59d1ffc328aee2ff956f45c3b6adbeb782538809edbb6a1e70f262a23, + 0xac7b869caf4e71585f9f567e94b1ee6e0d802ed6af49d30b24d41b1c784e448, + 0x6d671ea1fc8bcd0d824e101c3732425de5a4435fae1bcfd1c85f501ca205d43, + 0x6cff4c2918d4ce74f4ebde86e5951ad143b09a951d136618cacc9cb40dd5799, + 0x2d9f0ee4ed51e979a0f1a582077e8e5f6669f89d79225a7da2687446184347aa, + 0x12dc6ad0e0daf28768e85b026179300312feb26584b2a4b50f830499e14f5e06, + 0x2f94df6b211d8a8a514facf931d71a3f23e3d9a8a51a11d29c0221fc9873d756, + 0x29ee741287f545a19cd02af760d56286c27ab5d4122c001fc297d43db2bd030, + 0x7d43ba525c44a894d64b500aca3b68f2e3c2577927390f60181ed36c0df68f, + 0x252866633477b3aaa0f9fda731b4dfa0d78905ab39c177ae1f4f76da5d9e5547, + 0x2308ec0db73437f83200db8f914733431ebe5149e61cf3afe3e67304c8fa8d44, + 0x517e4ee288992d99e59515e91c5be6957e839b8ba8c9c7430fd31eac44c56a2, + 0x2ab15d8887615c04e22f1e988b9d8450cddc2cfaf2b582bdb006204a50e596cf, + 0x116e33a713748ad93004391adb07d5ca64962c8af2a8835e50eb7e1b6662a557, + 0x68150e1248e7ae44ef5619127e8cc28616d7277091afb4c209ddd504923f50f, + 0x1e9e3d2964594dd5bc87a93e4bb67e6ad71b037049f90493165954fcd86a1e4e, + 0x1751f2e99cf8cf643a5ec6b3cbc81def5aa8679977cbd2779f34f476f9496911, + 0x248ef2921bdf968c74dbadcae0db56cb022ca98b983628d7110c724cdae048d6, + 0x2fb6d1bd57da1cc3610b201535bd42a2cd405ecb52b28c215237581257354352, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0xce40ef4d37ae58008a4d1b02e78aa4fec563e8840cc28fd1af61144986866fd, + 0x1f94afec8fa62f53e4bb20f756a08236e40e98a346afea85c78280f0ea33e337, + 0xf2164352021aaa641a7176ca76674a465b3b728d8af12c7b2a5f9339d6f5e47, + 0x1b86c9a7cb8287520b3943987397e8c7a742f3059fe12bea664989ae08d00e5b, + 0x11e4db5228177f30bb2a2f96098eaa7ea941229180bed1869a0d0be04cc60b0e, + 0x6378bcef2ce91bf24365b51a0970028dda29ebd7da3054a8440207c15eda844, + 0x192ef0949ebb3224247a83c74eba36e47252f4dd8c3f20eedaa39484ea78ca65, + 0x21c1cae79f5fa8283d7a8c2acb29a4f46a76b8b3f7d51fd93941bdf32d38fed8, + 0xfc260daea1f470febcdeb84cc58f03b1100ffe23ab52e88a7832c18b1b13213, + 0x1f6f7bc07589916ebe3fee5025672ad9af9a3ab798fd01c6c2228ecca20c395e, + 0x197e205923ec11dafeeb697b87ad973ba4a85d9d9d3817c364c3609ff78c18dc, + 0x2935c393a884a244b08aa314b2d261c999959d415d00857cd883277d439fc00a, + 0x2c639ac544a75088ec7aee01a854471f7b6538d83fc1c7541d9018c0a87b1916, + 0x25b2c9c2f413762e843c10e546ced0572e1a30d1a9b2c5c781d24de864ef4973, + 0x1d28735cd6da088ff72fe8cd4eadb8bc28268e15a9d754a5eede53d3513e0317, + 0x205c309b41e6c8bf2fea4671a502abcebbf0aa33c807369adb9869c0d0b1661b, + 0x2e8e8dbf8f9ab3be24fb4e8b95c2188103a384cdbcc2b65fc5b931a730416e0e, + 0x20e1291175551be80f70fa6ce6e111ad5403d1765c4bf47f611103fda64b098e, + 0xba9120de0cb289db8a951b5d348853a839af34529c972296703db5c217054dd, + 0x2898c38f27c64311d90346dfaaf3554ff6b104e56124b35af7cb322402264620, + 0x286e3762e815adfe1ce18e59928e04beb43dbdc6d4d1eb52b5741326da3c688e, + 0x2d316495c1c92a8ab5fc456dd8e7b1ea97f5cb70e90624d1af3e4bbc18cb75ef, + 0xdeb856e2bb0ca11bf197de3dbe8e8cc5dbaac998dcc275cab91acf7af3ff347, + 0x247b87e0ea690afabb1beeccffc7c12fb20f31484d684b97302ee67f588d1eed, + 0x2003afe0fe29cee7641b7f41a31c8a2fc27bdd619f85a8fe53a4536884d684f9, + 0x25d9c2e2d66052c7d5cf3d56c8865d939cba18e0bfac725dc04f468837112253, + 0x1a711ba1a3eece6595c4ee4dee4ab3e865dd77e6b58797c3677e1f494d13144, + 0x7c74f66ff199856f077f29b06acc03305bb03d7a1beae045e199b9596ac9a31, + 0x1a4d513506c6ae66d0e1a077b9e9604ad4359a6cba7738d9721db0ba826fe704, + 0x172f82b5caa7f65eb8044ae3faefe81d837e53b8e615c2d46ed02e4036142ecf, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x1c81a64c5d581191f40a709788a4fd607c71e461de2ad166b9bcca742e0a9db8, + 0x65284960bf09eab2773324ead048c3bec54af7ceba50805e3532a5a11b96b94, + 0x234f635b921f9d7a056c0fe63af46afb8b9b5430d81905bfb16ef051369fee7b, + 0x1488199577c500214d8d9c4bf6d64db0811d5e69b44f3b86a585d9410f875be5, + 0x2237a1388bd8962921cc637d8a4c5d0faa6b5fb138d589db98a508bdf9c225f6, + 0x1b89bdbe9e9ab40f2ac20793f4182a7f33ad93e907304fb0440d1e7d40063ed4, + 0x20bfe61092f2e5cb0508a73ca1dd8983127a395f6800ccbec4ed56aa95ad8c7f, + 0x5acd0c7611cfa9170896d7606a8f5c672883ceb42c2b829c29c8dae08df2ec4, + 0x2e3a22fd34491f153094c93bcf17a8e45940e4a1191fcd2d1741ef841681e0a8, + 0x26504b2d5b079c4aee6f588f825b8b28c337137e9ac1f945f715b85b5cdae979, + 0x201fbd4f4c9cac24b23d8bbf86efe15d86abe8f18838bb542975fa10e9f2a895, + 0xb13dc6afd9a8566a90cb50c82f1876fad84ffd092241c028b9ee470cd64cbbd, + 0x9c0853fae2070c4ea816a54daecef43a5940c647229be0fd869ef36f23159e, + 0x1a926cac03b4e6f41bf021460cb129cb4b20253b3c172a6f2b531d57d7a7d645, + 0x2334c0b56015f6c5a9083193b17d225ea2d977932521f5d7e328c3f0baaf7a5a, + 0x2cbf73905b5489ed3b0c5763eee04fed6594411a1381d0bd617a208a9e38d208, + 0x1e06c4d1e2edd5530f226649871f8fc83b9e7b5708d75bdf6b9a31b963be7bfb, + 0x260c2e5e5364bd914ccbfb785d01ab898a2a961daf708f5f3e34bff953b24b00, + 0x26689f7259e1061156947b136c0dbd5e8c2c1972b4823f4dcf04df33e95532cd, + 0x291df0e62b563da670d44db58d0060e20935852eb699daee6e342b3c59b6d73c, + 0x14e05591b9b889b8899134c8079886d87829cfc39538b78b7a6378b30be1c683, + 0x2be6bdf824d2cccd56cec6d1953e0f6b3117f6cba035592433b7daca12ed43db, + 0x1dbbd7c3c3ca0eaa01cd309dcc57d0c6331814ae9640071cc6bb9483ab6f9a8a, + 0x2227b2d0979591731b87cef94237e7068a5c5e03d609e61df240b7f7944e9264, + 0x1d351ed4b59e46571e5727529ed92e6ce55aaedb36e3d54cbc6c2a73fc4a2786, + 0x2312bb7364e690f64210acaf695e5d8d03a9059b261b9f5bc2fd2dd78ebfe499, + 0x1532d3c7fefda9a7e81fc949f72956bd5f6d55bc4be421d27d64847d81cdcbd4, + 0x8916c1ca3dc2d21a671ff4989f5f7ae581c2102c172054472cb63e25fd58101, + 0x199a3556e4c7a370f0832fd385952688d469177c78a0e77107ee586aeed025ca, + 0x4297e87f69747dad1391582ac26a54249d004fbd16bfc50ec12d7e6b95faa92, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x63db3a46c3e1e822357db637c8910722b22e531454a1da26f2768f59a8457bf, + 0x82793e5ecd44bfe57289068ca1bd6dcb1a9dac086bfec2ce99aba4d04c46b2f, + 0xb5214e4d1f2227947a3aa13e7b57a4d85dd94df40e39dbace02df0e7c0eec0f, + 0x15fde89fae0bd5593e8f2bea040a6f837a7bfd5c5e13b04514c39eb1ae15624d, + 0x27e7e6eea879199109f7a165585ffcb5da626a4d0c39b2681fc7b55402510f1d, + 0x82b46075b3da1e178cd6367971caf87a3676229dbc745e031b45136618255db, + 0x176668330b14e97d4f77547f3b9f430b7fdcfb1bfccd46fa70839bae63df4872, + 0x10104450f5b03a0638bddb9c1d9db41998094de2cd8a8cf7d3f04143122e5a9e, + 0x18c84287abb1d81afb7c16b5380aad2edf054867661c07e44b252ed26cc7b68e, + 0x4d7f1edeed756ae0598fe4b0ff7edc488b75f0376b1923fdc417fe7df3bae7b, + 0x16b3bcf2e5fe28543072f71ef9d83e31887dc632c0c86b4389ee730449207658, + 0x2f29c8f376d462946533c1f349391834f2ec826c08eab0eee6a263f759a43797, + 0x20d394abb3b23967e223f5b9f0a556ce582128c8ac5193f66f8c959a1efc3344, + 0xb207d38d762517ba978fd184ccf152ba1c46333dbd979194b9ff06b27a792a6, + 0xfadffe100a5861695b7059f6ad8e0d5426ffe92c2bff0d81825b72f6da517b0, + 0x279aebdde647b4118234d886bd169f051ed193b0edcf46f54a8aca2f4d3cdb4c, + 0x119f36daffe8b2be75f4e64c32fc2ecd118f319409499fa007819ce95ca2df6e, + 0x1242a6c181fe90f95fd6bdb02918b14c7bcef634ee3d02e30bad0caa161b1bb0, + 0x13b4546c3da77fdc8779f6ab0d770bcd3cd72d927c72c69fc1dd01de9ead8dc3, + 0x888fd59a93f104c423ecc2271c5926305abadf9f458f70ebbbe28a6fc401f71, + 0x25a8ff35f85072e4f8ac148e53991882409a73be3156a865cd00ce4f9fd05e39, + 0x11ebf2fa3b30212183347f0fe5632e3ac31f93a68a3b8ffb47960b505601a7dd, + 0x24e547cf052f879aed9d43e772fbe7809c500603eaf4ee69e41df75d2cdd213a, + 0xfc85a22c05e5ea21235ff75ce1128c7bdadfd9fcdf18f1bcb66e5eeb76125e6, + 0x2a9f2576a85c827399655ee856b94ee757335582e476846106dbccc7028bf19f, + 0x13a5b0372ba5ed8b2718e46b25d797b56a6cb0a2f03c621e8969b371a5d1f2dd, + 0x2cf328cd5a7f16316989013b1db59f8e8c148cea1a09bbcbefc464ec3577f253, + 0x2c6f8ae3d08a528068b4ff4da059a1a0dc88e311f87a1a9c5ba99738369762f2, + 0x2108fe376f8ae97694e36f575eaa0aa0dae306505c70d5a0575f5697daddf530, + 0x23a2991e713b01022cbb8d2d3b81cc5b71117d663e3be0f7153757231ad22cb9, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x1e9d125fb7c35dfc0064d4351a05731b95b37e5ebee77e1ca055ea754902c75c, + 0x119d649d362c0f09efab4076c479c9833ccbc80a2f0da6c362d653ecab381599, + 0xb682593d09250dc35e376127d33a34d30ea21f79f3f112066618f947872c35a, + 0x16670c641709033c5f1bb409f530b7799d280e7c9025defdbba706d9e1371733, + 0x16013d4393fb316871311a22728aa5de989bcd030f2a54ff08fbc7317375e8da, + 0x2a7d4518b4393070d22a8d824b75d8a474fef8ee3eae40cacc38d40cb525937a, + 0xa2af4ab955f7dc6d09a9c72bbff55d30ca01013651b387523782487fd6bfdb4, + 0x4fcc21d258b270458eb662ec8b16deae2c8039d68ccab74e19b4573ae413940, + 0xb5547d0028fa903aa9a2cf2eb9ba2d303bfff9ceb1d4070f87cb2821cf684c0, + 0x4eb04b4aa22c6ab9e0cd8c331a04aeb1546b58540f460621f2696f453c0e0e3, + 0x27757b5fad20eb99a306317b872275532a31ae4ac34dcbf20e80843f2511af23, + 0x23c5cd44bdc3e761827ccfffcf09d470a55aba69e7ad0fc83fd2eb7bfff41e67, + 0x21bb1a37cc6a1ca1d65febe7d1868754bf85d082215397b8985df2fa8c47c25c, + 0x2050602a2f6da4117d3257061d22608527508e58e8a578d00f2c3685f601846c, + 0x2a896c598d40d992207040a5f1629dc61549fbb0dba65e33a8cae98ad46afc16, + 0xb2f10b968c76b4a1c338057e1c67985cc3f571380db66b1c38ff9f6d630e34a, + 0x7a1e6e9dd512b10eb0817b56839e3bb85b736442b50f32e18f07a5ebdf3c191, + 0xc0a72a48434504036597a74ce362796f9021d0dc8d318ef086225a55ca1a9f1, + 0x28e3e34de5c1de1c85186e7d604e5e4a24ad603b676abbe3674a0ed2d802be72, + 0xa6d55bc7826b1e2b03850d677928f501bf4c6398104c009eccbc2b2fc5cbf17, + 0x2c042a68d06b5f7110513182d5c54efd6ab0dbbdce57f1eeb5ab12cac26322a4, + 0x18cbfbb6607f28f928f1fa2ef21ce8be9d4719a8d7c33a7fd1279b6722f151a3, + 0x2d7e6e039f81c66f329b2dc40ad3b116bb9bf4db88bd3e44be39acb676ab36ec, + 0x2ba3cf36a0580465928db18f630e47aaef388d04aea7f10ac3c600df5d2108cd, + 0x2403116000d75fb1a8bf3d0a18ab068fccc0c149c46a935d91678c45fc948b2b, + 0x62b5c358a18921954449fd14b3a2dcf3f2974710e9616b9805f715d7a9f9e50, + 0x14307431f749d428d15fa3fc56a517c677c22e0a80bfd0fa2bfa3f35f323e156, + 0x2c04854c96aaceae379bc0f7474cd235436186a5f9f01f4d059e0fc83037a57, + 0x1ba6107ff34a8cb1ec3b4536325f2845a05b0c4b8da6dc5c0e0327419880b484, + 0x1e7b9fcdcabb49b7aadb17219fb4a0bf4da78d4dcdbb6d1437e7fa56e13ff4fe, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x26968495cbd99f547d94c82d24b714e3cfea387ae1112be450ef48a93752ac5f, + 0x1ddd4f2ebf1e1ee5b8b6715e69df13d58c524c6b0bd5120777b78e26a054b978, + 0x1771396e072f342e14fa40e37a4f9e45a385b5badab8a10b8bae6bc325392c75, + 0x1334b3e12b51d4e658735203dfe259c022ddc5deac72bfc942bd8970c7d3f31e, + 0x2e7aef8fc027f0f4ed42c4ac674ff86a2314b9a88094a214325ae5f7611d3f5d, + 0x2f66d8f2e4c63ceff37adcb96812010dec93be84a18b260a659909f18ad00789, + 0x1cc80a4e8114c2086b90d7c7f0f33007d33b613444a63823b465939af409705e, + 0x4eee4396019744ef67fd43fa3739511a2370f23f80e2b5ebc5c5a1c9655135c, + 0x28ba26ef284bc535f288779980dfc0da8530588823a2f83a3d5edb7a5a25afb9, + 0x2fd84d8520146a01398ac84f33cfb557ac2850195fee0c5b28d2ee1d629b4d9b, + 0xd831e57b1adcb20c227a1adf2a6ab52a0a1cf4104e493c327cbea8897cbffdf, + 0x186b1b6b8ac98a038ece2b61971b0c83f28f32e097e28cdcdfb07aa8e685030c, + 0x7630c5932b486e74bfccc6d06d6ca99e499c8913a3a1a2ace3f6546696d9975, + 0x2ea3fc0c165f38d9aa02eec6a46e19a5854a0bb2584c2d35354e1c814babb896, + 0x1c62f3196e53f51fcda6620317b4d088d2132531a7367c8e5793bfdd5dc07395, + 0x1f352e27dd80d315a273a3ee1a159f18875744c5169bfdfa5ed6a29113caab02, + 0x193d8985e3f9126daaa4ecb2b4fec04425eafd71dafc86ff521d81fcf62cdcce, + 0x2271c906b9605c4dd48e925fa831f1267939342ec2a6f2d68dddb62a5241bb94, + 0x32817d35a0d57fe0fd10584116d3b5c48ddfd6ebe990e91ff469b1e679b7df6, + 0x164540210c18239fd0e4301e0e729018a7f419f438fcf829294179bb2c076221, + 0x2de749d2d5c5c9db3652813190e49ecd8ad1d3b3ae308c3c9efb6e98822e8dea, + 0x2a562decd5b704192adf41195234f4e1bd8d9d58b4cc48cf57a2ec9dee7ee410, + 0xdd5762ff7a8f652831aa96e9c74370e71b2e0fa1ddd1db85427bd2e79f84724, + 0x260f24c836dc07efdae65db907fd8390b38f5341faed0fc553cc7c0ad7fa549a, + 0x1a9d4050de78961851fd12689cc0f93fdf5278e1430d7295cf620713b01f2901, + 0x27d255a40de38041587f907cc4d84a8ab1a5ca07f6abf6d5342248c0df6dc441, + 0x2187634627013d30fff1a44ecd3d5a018c06352be5d480bd3146898cc004385a, + 0x2e0eed49a09486c41002557ade478e57b8ec175f9ca36fd481536189766291d, + 0x1abacf3780a60d304e373bd2f40ff6112b068c0c5d5966a3327c386e480c9181, + 0x2839a53cd148fc18db287c3ac9cbefa3a479e414095fe667b74151d2b78c6342, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x121ab2b6ab8e2c5ecf89dfc2bda8337d7f52d76cf7a2e444859fa1b714be8f01, + 0x23a405c7644f6a9b7106d4ebc99b0f2c6c5543352d391d31a2965478230f2c13, + 0x3de1ccb8e26e8dbfaf06a08bf5189bb38e8e5cf181d154fbb0c4afed03d551, + 0xd594c3a1903abb67bede24f66447fa6cc8f8696ddbdd54830a32ef205495e43, + 0x2d13cfd974b0624734fe4a5127b23dae16f69033c9b1b0d7a8ffcbb55158737, + 0x4ad4148506cf6e6d9795ef784c6c1875e322ab0cc3b6380311b19f9441d8f82, + 0x5bba1c4d35ea9bdb593e19848c3510f2450abcd24bc392456d97a6e4f18e49e, + 0x9236c366e97d741479d565c45311478a3c918e62d52d12c5f54b7366c5bf57d, + 0x2a5630fe33c0d5616c41d0953c305e67503306f2ab6942e472ee89cf34e4403f, + 0x2458e51f0164821f0ed092a42b94fedaf0d801a9e7baef3ada586ce5e8cd3c64, + 0xa3218660ff4767aca5b77aaa3060a4e1fc8f5fcc0fcd6813c9892deefd7e96e, + 0x10c628fb41830cad0df1d4045657412e0833451d9f6fb341987afcbb98cac300, + 0x365b8f2fc30b7f0e91046966b67e804b88f2e1eb7ec6c132456467e05d179a3, + 0xbde78ed9fb95b8dabde79d55c92e119f0ca502be0ed08a0dc381f89ad85cde1, + 0x1e98a3f1c8e8f9a35eeac2782615c96e12950e627ba89a9ac0b873797d30107f, + 0xc0308caff3a47cc92f51163e05a00bea0517f621a4d69cb9e680c79577542a7, + 0xbb209639cdeae029ede39f912e33007334877c0004842f75035a7ee26a5e4d5, + 0x13ffc065d98f8ba997a11cab00fea19d1efe62e20f1bd7103de4858e210b011d, + 0x24ce589a99dd7149b8a0a25f95e766a44b081e5d475d17b7cec54daa028418e0, + 0x2ab971f8aa28d7fb11b7cedc6d85bfb947bd64690e6d6cc0fd9cede6ccfc1e10, + 0x1b2e15dd9e25ad8b2506ff8f0286f34d26254d2b4732cab5dbb713d2203ac283, + 0x1f1c3559f788fed19f86c71628547cd1d5092b0d30b4be4ea634b744923cea21, + 0x1c83b3ff9fa324bc9a5316f0a85a8657123a493a9b0220006ba1100a393919a0, + 0x28958a5831727ed80010116885dc7c66a1c245f6fcab56362c986ac87caee035, + 0x282c38627758b1648078b241bbe3557375aed2e83f18278ca6c962963297a142, + 0xddeead8fcccedced8e4d4376a2bc530466bef45054731d5243454ff4acd04c1, + 0xbdb032ee13a67d9c75df4c44570244e4f78e19a039b30f9f12c532e9b0ad601, + 0x651ba2f04803d5f77235caf50305de5e55431a6abfac178f524a5a01fb4f1b3, + 0x6541fd461b311dfcdc647b2c33e272d9a3733b5ff38c7e0a2cf51a65e22c19, + 0x32293b2b6e94545d3606b723f7a3149ff5d997ff1e8097359e0e0eb2444fab4, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x1e47d96559f3d9eb6bd2fafe210c31f4a8140b853eab986dc12ee2527613016d, + 0x1aaa3fbb3f33fb63d4504fb8ea859f4156ee20b59e198b531546e6891a2497d4, + 0x65c97f1a22d2c6561ed6b3e8bb68fbc299fa56e40bbb54d49e02ec33ad6d913, + 0x2ccf556ae01de7dbe15ba504437271b8a33651d5249fc5282b8cd38fd23ef378, + 0xab4b8237c68daded18da81c5a6bfb657b4d879d4164db2b2e6ee4b854f34933, + 0x2c3329b267d11041b788317f56c3fb8a685b69c0f782ab2213d393befc80f0b, + 0x22f60f1fbc046baeefcae40d2b7843cd95c8dff7d49e0e18851f7fdacf3a4eb4, + 0x1d22dc88706281f80405f66fb60fbe665639969df32efc6e47d33635da644922, + 0x1aaf58dbdd1a14018d33f48de1b98e6f7a937d81ae46aa5313e9a6ad886e7f60, + 0x6f13d3dd83b99f56b8d840e73d3c695efa8ca7a38a891c9df57fb945b8507de, + 0x2d7c3ec573e9cc8350964a20d0a2ec03d2e948a3f8eaab6d520406808d80576b, + 0x293a2e55abaf167cedd278dc3d355975bc1f29dc3354310f21f9ce01574b0d23, + 0x2682132e373c18a17f78601edeea4f8772240bfb889b3db93b2e8ea10b2270e1, + 0x301508db6c1f9710285b1e6e44d46a133310c29c28426d90417d7c21e4f0b20d, + 0x1834c2d44e5774a7e63ba311a3896fa595c04c96df216e3f04ed409c2de9b112, + 0x76c49e633f12eb93ba03d627acf0c95d1d623b6cb42f773f3a20e02f23120af, + 0xfea2b1df3510f6e74dc89be1a061ec7f8255cff0eecea778e1cca99becab586, + 0x19c3a8e23b946d64526696670270f49298ee4eee4402888bf2ad3ced11f7ad53, + 0x86cbbeae69e83af8d6af50cd4f161f345017a925318acc46be5cca969697042, + 0x1a8a851cf400ea4e9b7a51f0bcd5b636e7894d05f3e0faedeba662bf80e901cf, + 0x1fb9f1ed4cfe567b8183fb0f9f5edd26e8af56bbae47cfb6fb6a2c5323303797, + 0xfd5bdd425e00b499e57e34f19cfae9bf0396e405fcd9b4df234a73d15f96f03, + 0x2dd4591301dce89c25a6b690ce98e4cb6c5603505055f6c84e9fb8980cdd3025, + 0x11cbe00cf364a4bfa71c70b6a4b180724765a2a4cc0f31035e44cea45c1719b, + 0x1919aba9eae5d5cbd57d3851ee4011af47be08e151339d0fe9b32602d1fbb827, + 0x6dc27862b0c4f31489bd8c0c6e2a9d8e1c8d52284f4f381b88f6ca94495f798, + 0x1911c33355ced9c551e5aadd528bde012e913b283a67667f4f269675ada590a0, + 0x2facca82fdc63330a3628ec9435d193a47caea8fd2de6617d601bbad8adb0faa, + 0x168bb7d0c7b38df856af9831f4b1da200df248edab92ab41e638e6800c57252e, + 0x33864c3cc0a4cc3fc23c51ba07bd1f797a55394f4e0c39ca4dec1dfd6473aec, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0xc732637dd53a9e2035cb048fb5ac32b68613e0cd12f68a8b8d07fabc738cbc2, + 0x2b44e82a5cbaec37e208762b75b37d4ad4bbc4d83192241a4acb22383f26dd06, + 0xcf7e6a8815f6122fceeb778851d85155384796be9a1df53639f5d81631a2555, + 0x976401c8c12d415f389d4bb64621b71f225619dd93897525be9e8134ab912a4, + 0x1a23f2aa5a0ca939496eeceea3d7a9e386f641a248fb689682a8616ea98202d3, + 0x1295f50377875eea2b8757bd93e3543b59a727da7874e646cc3ef523ffcb79fd, + 0x1f4a65f81b3fe858fee5fe292da8d2594efc08a385f89dc60be97c9c7cbd0032, + 0x12e6d92557037dc2fc85c17c4148e9018fca489e90ea096ea7f400c74297a2f7, + 0x2f1e3906e4a5b87c714556abde45934dad466c1044609b2c865e5a835667b38, + 0x102c4d0a2eb569486e7c6c7893f6491c03626259388fc7d55b519a55e377a921, + 0x2c427c75876fd20b334a45663dc28359937368097c46f7b685eb6e3fbda1a6bb, + 0x12f1968b1e77f14f0f2e90f5fa44799cf2d5cbb3b77558d1493667db2ae55267, + 0xb8730598feb9ee21584d55d5447d8bb6540b84e40c7d4f14b6062ec02ae00c6, + 0x2e13857a53b9dd57a62a790b221ecd3d8ac27dd7ddf4f10ec48e680f1a17041b, + 0x86f9752b777f6b6260f53770c94056c12f444af68c40c75bf7396dc1ca7ebd5, + 0x144d5e3d11651e180a16152b3106f937942d48ee746f217a89db2e410f06e08f, + 0x27956794096d302fe3cec23f3cd713e1e4c7ebf7a9599ac1b3734cc032811a03, + 0x2464182f248bc3f32e7d5650870a79c371dd8fc8d67034dcfca621a1f1bc596b, + 0xa75f1c2e431c46447da58c4b53b5a707030003dd525a6746963b144c9a51803, + 0x441eb396ba8329b88880db7d7b29b57e7165262b02108544170278e444e11e4, + 0x1c271f16943c48bb48f4e2d178b77e4c31f22355466d641974957a5804e78765, + 0x209c46dbafa81cd4c62071ab840fa1f138a8289e87150177ce20c6f9942dff38, + 0x3002dc8c48624cf7f6e207ed3dc4656f6c6fd56f260c96c9362714d4cd667726, + 0xfcb2bd431b6f99702c0f6b220885e57f93fadf7a8d3a365aeafa0ceb1fb7447, + 0x2a74154c3f7dc063f12decedcee953b7e7d3d71dc48f867f72c8a75b5dc7ef62, + 0x129ef0b882070816acf093a88c660245a4e58261b307457eb99fd6c697f0ed7f, + 0x24f76ebf17e1a43056e1e4767cf4aff954b2f9fde49f05fda6c18ee7d2909471, + 0x1d099f0d638efa534bd9c758f9856a7943eff18350feb2d90dd7bffc48e80c16, + 0x2c9f441f31d9aea42026c0e7cd8765aed321ad391f4c869d87118b7a1107e94b, + 0x7af13e241cfaaec4578b52b9315b5017dad324fd69bf1a6a6aa79ce75b044ad, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x255345cb88354e31d381742d0d5b42072662445df9b98a247d617c92f27cd9f1, + 0x17e5c7c425cad2fb89e6acb07a2cea4bd5b1cb02fc04fe38dbdb341be1cf7d89, + 0x146fa4eb974c8faa9f821f63aca3727479d548d9f663f6934c1f458af3999ad, + 0x727942876c6eda2c90f98458ef4f4d6ed010e0562236f1febfaa72bd11a5fff, + 0x1bc84a56570ec875efdf985272b5df66c86cfe58a5be052d91787a8e3f8d49a, + 0x1053ebe1413b33bc188e06fe047235dd3028615fed58dbd6c1d014980ed7777f, + 0x20b12ab6f4bfecc04ee5c75f4108f2d842f004e84437e9093b15542dc26803cd, + 0x1ec0cef9e5ffc3472ebeaec671ad6ccd1fc85e2fa7c5e02e619053976eae5d56, + 0x2a42e9eca9fcaefc84ca320b72a0415eece1512b0afed7bcf4938985727b633f, + 0x1a172b2e81e2559ff3ab9b31a103e77c71b2e617bf7064f7a910803ef7cc9f9a, + 0x2f2cb2dcec93e9d768a5e77302b98fe0c291467a8bf3922e270123e45f06bc56, + 0x73e947e3b071d91accefd64d9242ecf3516181b583e27222d05ac64e57e61ca, + 0x201e11dd656c3292b05c202ea3916c78752b9a796fb97bfdb2fe67a935b761ec, + 0x12ba1b074f8b55da42206d4637431163a1aa6c0891681fd604ee17a7b4a4d054, + 0x1caf77967696809dd4e470183d00c935860fe2758b85ee6c6b8212eab0bad880, + 0x2e2c8e680ddec801ea189dd679d2e16c364bf28a69d7b79cb81842ee2469b8a1, + 0x29fa1929e7f6864a6c4856e9cb2dbf44d4c77cca135cee9eae611cb42d1e950, + 0xfa23e57bcdb977f185df4258bc1ac55957909e6613086a44a6581cd275a7160, + 0x2bd1a5ba49a19dd33ecc36aad236b0e0b4a03942f42a62fe825750889d4a1524, + 0x160ac4ad5eec95bc5910faceeb460088ab7d25fa15cb698e9ed17e1612fe2bfc, + 0x4c78cf3e48577cedb8cb5245a9607cdc9254ca8a8704f78d18db58f2552b2e3, + 0x1e9ef315dfdc99112d0e410fd65fccc9c7ac728617537da3e977d7afde414c61, + 0x2b4421616df11dfe94cd2b5500891f07eaf2900bdd8ee8eb42b0175be52be74f, + 0x8a13f8dbc82ec943c8ecaae0690bd0a4bd51a9762d670c8d059038d4259744d, + 0x14167eea5c641fb122863698bbf6897cbcd778d289c28685417d02e86db36ca0, + 0x1b2d84e924984926c742b426b7ccc5841c4bd193d3e05bbd5c5ed5868991741b, + 0xa14c4040634221a68633cf4f4622251ca34e42c9ae254eb7d02a7eaf1abc3d, + 0x1aae6b2f56d3acc7ed2fa5f310a29d4e54bdb4e5f531f68c59ca5b430e1f3f81, + 0x1c6bef1a7a903d4fd215a1754ad8f30011e676e498a3812d4f15d0a8422b35d4, + 0x260d34eb550364a018d509e831a281cb5b187033ecb4814ef42f240a5c1ea119, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x29455194183fea94109c945206f2c16429d01c0a34919ffcf42ac314a969ba28, + 0x11f4f3b6a1a747fc1aa22c66926e6511a4cbf6269f30c62f36f54b580f891a86, + 0x2df1cbfe1e9ff79c44eac7909de01dbee45e899e3500bcce8269bfca310c5d39, + 0x1e3ed2a6dd4ec05059b8dd11063a93d0b6c48226115d09b7e58d6d0f620be4b, + 0x235eade019a1ac892102280841960624b179b82bb21f7a571cfbb8f4cae5434b, + 0x1063dc692e42acecc27654967d85f8c3b48760c3b269565f3581c30cecaeb6fc, + 0x144c087d0bba6b2651508013332ba01ca36cfa926efb37633cc9423e9b257275, + 0x8dc44909d34e4fbeded6e5b8802fcb8ac3c31e0c2a966956ecf0cf4c027eabc, + 0xdbb16e5b88711eb895a12babfb81dbedf8de29ce530aff091a3a16f9d363468, + 0x2bcf5c9c863de574f3fc6dd7e35b84d333faabe43e1d6cd827ad58061476fbce, + 0x13cc6568623778319060d01c7e7780d9ddf3e6fdc11dbd6e0d1daf61c0ca5904, + 0x17a2edcf8bf40ac243662fdb41e4156e987fc66e00d5077523caf74b970cecc1, + 0x193dcdfd2950a934cc3b92c1b9e826a11e6829cdd6bbf699d702c902c9c8bdf0, + 0x1f049cb7d14ebd687ac611414b6186ea76938c1d239f8bbf5f83972b778dde5b, + 0x4d9595ab4d18bed55ef3c3fd0cd99e829d8e55b8c101df09c2acda3acca9af5, + 0x11a10e1656c16d3c53f889073d9f910945506af2e029aacfd7223cd45b457f23, + 0x1c84c1b888ff8d6396ee63866219b3e1d7473ade3c14ceed3c1fdfa44b51edff, + 0xf5531ef3a85171c99a9927bd9d1cbe04e84dc94c7ac68c06004d99a391ed06a, + 0x6ee08fc691f0b4229dc871b3676f380042f6b7ac1e5344149cd7d64cc9ab46, + 0x237628e422a57b51577905847eec949cc0938adcda2e97fc960492898d0c8d4f, + 0x4b4e368d0d486b2d4772a9fb808db251fdfaadaabb59a5bcc20c97bfa38ce7b, + 0x2a0484d90b9de4de15deca9a4f8795a61a8cea3d5eed0e938bd5c2203fbe45c2, + 0x2cfa30139fcfe50e07673bfc8029dfd08f511118dd4a4bf0a77a7bb3e1e894ae, + 0x278fd68bb5971f9d8b52b9e924814f3e07af8931796fc2b5d09605eeeba95c3, + 0x24ea4315f2dfe3e361e0ec7213e50dd9b25ff8bd654d83f6d26ca562e2a7ddc9, + 0x8612599ae2e4a878ecd88d9194ec5ceedd16b40c51e6edae2cc43f5e94a2534, + 0x2003edf69a810b8a3eb8208b455fb3a6e04bfdfa7f6198f2a0475312da1da37c, + 0x1ed96d9e0748ab37d6984b7be85b6c4342d341113d255cbaca749da545d34981, + 0x24947686594e925c8ce4f919309d5ddd789f62d268e7c6340022fe0d45a8b816, + 0xa42b268cf646e69a84152d6323e1eb318392a14827ae3241981f6ef34173e, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x2c16f80293a1d647de56a4a26abf5cb6840e67570999e804d434ba92326b0758, + 0x10003b7c47202671bda6e5bd46c2564c634d600e0fb23f898d73a217eb1f7cbd, + 0x8f99c641f5a436daeb9e269146b505771e8d18f847cadd3028c959e39e47f77, + 0x174ecd880d0e89617db1a52d076801bbddcc8f63c753467e7e4b7284f9c065c6, + 0x124823019c96feb400979fbc9e8b3ea028ba45199a99118e5be4885ea25c594e, + 0x1476f2bb8bb265ecee769b8092d9687ce6b822ea2d4fc8d9aa75927be24bd03c, + 0x19dac45643cf0ec46184ef121ab7e9a1c03707c7aec4620bccc80ae83d4ceab8, + 0x14674e4b8eab3fc1f80cf57e344d0fca2081743241898bcad999dd7939cb9b7d, + 0x1ed72b8e2da7a2fd16d8accd8eafb4cbb51c59a9d05d221cc608f74b7230358b, + 0x1da5ab440f2cdb9bc079ecdeceb673ecd86b906ffc33509225c6364ebdf4f9d6, + 0xc751d0ea79515c1ac0584876431dc1ce6226dd8420077d52dcc644638eb389, + 0x6a9dda83669129d53d499be9d18471ccc3decdaa7ddb14c4c19981f7937033d, + 0x280a6226e729cc5a5fef6b66266003fb72a99a97e1985f9c1b2f3d6e1c5f4696, + 0x277ccb7f226a1920bf5ab883e320f05c6edb580037be022f9a699079c9ea1501, + 0x207e4c2a1f9d4bfda41396d244cbc313a5a5755ce9cb8780f6a6cf8ff67b090f, + 0xab72e9f2261bc7dacdf730b02c9772d67b34b71c154f06480e2576995ab7fbe, + 0x26dc9a65057fde68cbf2b518e47e52c3089085c30015d873da81924ee8117970, + 0xee4ec60b28b8ae1bde8ab75521531748078f397b9914ed1d600f94f65edb2cb, + 0x26f7aaca92a139c5e2a653e9ebb132aaa385aa192ed9e1702b04f2c89d9bb766, + 0x2d2f1c2e5326bf8b3439310ed43a8721d8705e6d1c031af9facfb15f4ff8de85, + 0x1fd6ab80e45a94d9ee539f3247f22d8fab16026c5d0126cc5570514599c94b22, + 0xf94a3d03ba6eb3cbb84ecbf443474976b4b610b2c7e0be7bd18ec026f26833d, + 0x9fda6221cf5e2593d796d7185867ab6576bf2f79813f55b6a1ae9a1fcb3437c, + 0x26846396de6a8b113b784a7dfb9c63b0b950a69a20e63634954936f520470063, + 0x19e400a2ed9606a0a39041bba22cbbeaa8547c89ca0eb006c614b5d6d1b9e0aa, + 0xe2a3a5f42587d60aec0abbbf38902fd54d392c4cf26f8359deeca160061a02e, + 0x165836d2e5f94bd9868ae471de1b194fb407c3c27a3b322c956f13789d95fa23, + 0x2bba296744ead7cb7fa4e64b0d9854814e303a8a685433053ada126285b12dd2, + 0x1c42b83e0bf8cd6e2072b5602d85f5161ba6cc9aa752366791cec9eee1228510, + 0x2a8345e521ad75f61773023d905bc873ae8754b28c0273063d4970030cf6afd1, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0xdc769889e4e60328ced67e231f45e241283d9435602a724dd8d1f8a709ba50b, + 0x1002f962d594a9b3a1cf2dfdc940b80a6b67d3fc3148be7c0d11be50e277f1fa, + 0x11604b56f285ee9acad757b62e0a8679ec868a468c6715500cb84e72be72c7a6, + 0x2cbee753288f68a90a3c4a83783d30862b6e89e21ec3ae112af1b016ee9445ce, + 0x2df869ed85aad1cf7a17b58d217df7738c29e7ee5b0d254c1d4976ab71916b6a, + 0x52b2ba2fc76a7c40e4eebc062b1c353e2c7af8430a11222e64b8f1c09e57b69, + 0x23446fb653ba07d93115d3413ff7c9676f57d1e17a08329c153eb0e89d3e303d, + 0x11f1fad8b82ef8c047feb379042297cebe6f2a6d5660e7a993f67fc10e58adff, + 0x17af0f2c5f514d29665cde2023d8662f453954101bb66e15ff582604b86147a, + 0x11d7ceb7a58360c894abafcafbbb0b08e302ea940d29f5c403971e7a7a014fab, + 0x74ad08dcce384bd2df324e56ae0ec65f035aa90479bf25d940ae94f25bcde95, + 0xa9e0e2b8db72860fd3308d7982d4c51766d89ccc8939e0087c3fc1e15d53558, + 0x10053dd72d3e24c8040482217ea6d61c3e419cbdefe8709bc58951fd2a0711a6, + 0xb8feb7949a8116ad1ec2cfe47910318bd5dc9e54ee0caffb08a23e4fa0ea22b, + 0x1b3f78f18b178ee8df4bad8cf2fade21d1698ef13f78d3598c44a063fefdda25, + 0x15af1e8fd71f0799f8c7dec891c12d89bb687b8f14d0f12b4a52084bd68af74d, + 0x147d419b1999d7896f7f2c9ab68937f4e1ddf75ce3615b51e275a33e5fa8fe96, + 0x28b7cdada2f2cb2b1ae17064a61f03b36fe64faf9db752b7470da8398a1578e7, + 0x2163e931b6d3e6641d34369bb808b3745c1003771dba9dec9bf9d5fe24c43577, + 0x1fe3bf03ba1752e0d93486397e28ff2a9350c56abb949f7f6a02575b1436636e, + 0x2ec24f69b227550297bee72b056181c91364f54f9cb31e0b14d38fc2ac37f147, + 0x98d9ca655e17d9af5fc7933beb8f6b100d78644eeb19c1e7346bbd6077fef4f, + 0x2e296e61aafd6d219daefc2b994d52310770830b5767a3c8220c2f5251e4d786, + 0x2f6884b2602c50e4cbdfb45ed64863dcb689af3b917fb10dfaf9cfa8307d112c, + 0x5e81ed97199a7c32f5844b9e3c48c60dfcae2e703bb19855260479d6556b63, + 0x7b3281ec445d3a58654d72a48b86be8a10380910a57602460c91e4efcc812ff, + 0x14e55ee2871da3b1e051cb0857adeaefa5e9101d9b5d7623580fa70cdd041385, + 0x53f6a1c6bba5a4ce92962a6a23cdf21096b5c1c0652444a52174efaaa6287ac, + 0xf55c1add25dc95f9602356a6ad006ec557378a038b09d9f46daf00b359d88e1, + 0x302ef214c4c4e78688cfe22c58544d3cb8888bac5512044709e1c56fb3a6a513, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x1e97abc82dd29d2284a66edf1d38115a8cf9d2316c79b2262afc5a43487217a, + 0x18c844b544ec0da670ba7fcad86b7e4cc3b790c3269507ce0cf608308e63d5f2, + 0x27e894e463d2d999c5bb6c29e9f5573603b4e3f55fa4b1eb315b0664794a8897, + 0x1ec3f26b1af76185f0de2d894157ddf696e80aaa3661e94163e9106a9fbddd3e, + 0x22978d983a255eae6840d50dcf586263d5a0afd5b8eb552f720cc0affc8cf533, + 0x1618d7d7b6d7ba2dafd24690ada4cfa7ec3e961f395b9c7fbf7d76d0dd837125, + 0x1df2e4ba9ba44ca6f24877919be6d84c97a6f6cc318c7297d608f1aa4f050848, + 0x1fa6c7cfaefb71fe88191e62ec1e69611c76c503ca8c6c2b45e0ae286588cacf, + 0x2f00266e50bc17514d27873eb92eee8038696ada6decb01a1138f09aaefb625, + 0x24b0ef6c8ddd8d74acd34fd2977a27c6e584febb5cc1ed119e43333934a5efa1, + 0x2eba590f514eb52770d140bbb2bfd1909fbb0056559a5bb18fbeb72f9bf1c7e5, + 0x1c01664f520b12562f93bb93f40874300703ca11b39eb1e8bae9f21944f0c4a6, + 0x158c6e1a418426179c9216cf35095705395180c264802302c2b5bdda75b4a4f6, + 0x2609db7fe10c939e0289595aad97807442c4ac5b28205bb6fd6ef7bfcb55adaa, + 0x68bca148cf00ddb73bcb32b580db9423292a3d0ca547207c281222c5ac64f05, + 0x17bcbd81a901026df975e1a27ca02b7db2b6c7daa5dc0fc9a7d71e4210c16715, + 0x2dfab84b8b358320cfd6fe1fdaadd8ee01d4658d701376506800ce70020c680c, + 0x120819aae37b3d91fc8c0babac388c536f3f091923ca13587c8fc91d2c27a9c7, + 0x12313b69bd606ca46c7008f6f4fccf3ddef09743f311adba1200581089985509, + 0x11e9b992c04a4ee4586a62142f37868d6535f948e89ebfc54151c61e1fc4378a, + 0x5f557dea69dabf8f49032a07a021b292a4cd73e51dc82f9b8e4d96d82569a53, + 0xce2bc653061b09a271f64d5ac546f7b2f3a270910f2505ed186e11b0d4eea44, + 0x195b61bc0d16c176128158e7463b3e3ee0df476d31cf641e297c8cb9f5d6368f, + 0x1d0df7d7da33f468a43a413dfd4e4e188385c6c87bd767486c4a4a6babcda2cc, + 0x13904564817a3bf9e98b1a21f1f360e5830764da4a300f059268111b51b0b761, + 0xee010fca95f45250a5ce94a89a91fbd64f2c118e2755127a562ebb00fd27ef5, + 0x279d86c488716103a7ec21aaf9d2139f72c7f72a18eabfd581ef619e0c3b20b6, + 0x11b803d7d692745f2ba754f16d795a2c51bc5576576c244edb6f80cd790dd8d3, + 0x3d093d2500c614852a3802e498bdd965dbb993e8d07397b6ccd9c3832a0907b, + 0x16652d5f69932fa04272068446046190f9c83f85e9ccbcd36210c5877778f1b8, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x2959b7c18c774ae5de1749af01c678a88eb32215afbd962a0561d6d198525e79, + 0xc26abdc5e7b095a4e2237c872e90bcbee8a10618572ec9aabe2d7b1a377d6a8, + 0x17303e79bb1728eecb88e18d8b7db784ea1a70e4eed67e7f9e6deba761b863ec, + 0x8f1351b765587773fc254d4e9c6215178b81698a6e1332bdbb16c5626879b92, + 0x24587c5be08773ab2fc2250421c4988b332bfc432cd4e283fc86de3882b7898c, + 0x972bc46f752662ec72acc9851fb74ef8fa89a03f2ceea01849ea839f9a80d2a, + 0x185382531567193bffc137ce0a17f1f087da191bab36af539545a6929b44697c, + 0x2f835f068a500a33e6b44b3a492d8f09228c2d660f84558123e6292e93f906b2, + 0x159abee658fae6ddaf7329b5f76a81e713dfff71c438f7e678a5b64365285949, + 0x2ceaccfe0874e534eb39a86b066ca9b40e25793df513a2e1a8edeee8398489ec, + 0x3e5251b721d2cd67a46b4e7bc90015c36a1134a8ec5d25194d5c7c309c0b029, + 0x1018c8b0a3de1c528680503ffa391ed74fb1b89e3dc09b140f7625249f061249, + 0x2c0015ecad1833f9b004d902644feebfde2a27e50aee9da314e4e7480a1eb9c0, + 0x24feb7104d161a328cdf2dc7c125422879578cce893fccf80e5bb265bfbe2e6c, + 0x2944d98697f7ddec78e5165cbaee2bbf0cea6359981a13c27bbd17a60709b7c3, + 0x1eb6e93cbfd035bc4f79bd6d32e25c05be28216616655908dd394f8e4beb0c17, + 0x15274c4215b3498cece507e5a9c78c728a2927ae24b72d580caca25885158c01, + 0x244439d87914ea7af64471c047d1afb3ef3e4d3eb41afc5ff4551e34e0b2e03b, + 0x7c60d6d98c85efea799c2d359aebd1cf865015712f99f6f5078776b44455899, + 0xb4448d85c58321886de5cad02508cb079e475ad06a5691610848e530cfcabdc, + 0x2d385f71e742fc3698c688df7df2ac0cd06bf1eda4db74246d5b3ef234d66603, + 0xc3c7aa72581cf03932ea40da64bf0454b26ca6c02b25798eaaa3ee0893f1479, + 0x2f4091dafd791bb3cf7089c8e714a34bbc2f5fab044416870a1110bd68da326e, + 0x9a9203152f7c7a322535f3c2445dca0be8621df8f0c9bc63a8e3654145b2388, + 0xc9944612dd0f8e184d07ec5a44ca257d67514ac9ae15e4f5be49b6c0356915a, + 0x465c847c7d119bdefe896bf452c77f78e124ee0bb245270d21ed2bd79e11721, + 0x1725856f51139de9097ed3842a414f8e8f63ea6b9e6414e5eb220842583af5bb, + 0x276c1b109f88cc834ed8c2e68672a592250c6cbfea5f9bddd0834c5563f9a886, + 0x2baf5485e19edbc5772e04a26dea28931742966fdf39011b1c16f2832ffbe3d7, + 0x2042b1e0d4a962b95c5dbcc044fa0ec53a00e8ad677a6dc39e36b41a016eb036, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x1eb87ed83839103c87434e39c910399447d9c63134d442335fb3e226f84b47b2, + 0x80a226b8c5b7ae68105818ce707b2441a0da70860d771bb4d58585ea1a62866, + 0x1b038c8d59fa36e1dfd4cca8bff7d38b6161bff01ffaad9e95e3c8591174525b, + 0x2ae9c92470f8f4d5ef9b96d9c1c235c46b5ca275d4e08dd1d193abee581d763b, + 0x21fb57daf9b4cdf828d74de7723985b3a1b0226d90f563ef1cbc0d9232fe3429, + 0x22bfeba5a5a36cd515fa31b9da51ef26a15ad6050bb42853f59ffda0277a99c4, + 0x20f3df888830ae894646d1166204af05d9817613c719cda745c09aa141590c02, + 0x63b2355acdad1a0032a2f2c7a2ea5f307e3c0321d261c9d7f5fa10934119f28, + 0x16de60437f4609882b9eafa6ac6ded955b8225b0985fc4e3983ea640add5028c, + 0x2ab849a10d24540498ba4c7ee7afac4ecdb81e0083fb82ef56b91d025e33756, + 0x25d60a27489116c12d3fb8af52c877f5691d57ad645946fc4dda53db186e2c50, + 0x1b1442dc351aedc7917b1008bbdc4a05d92e4639e7f3af1b7f8c1efc9bbc79c8, + 0x2502537d03523d64eacdc4da240a03f6981a89c3f3352ed51b95231d129f6efa, + 0x1b786044b15312f04f057fcb32f799f0176237a9e5c70bf309a9860ab90fc724, + 0x13aa1eb0dde09e3816e83ef9027b5b12fcb298f469d8523b588d728f6fbcc841, + 0x15d72e8723e077bfbcd6fc983a47dc7b580681f0c4c4225c58011bae84f8e1a, + 0x1369471512c4227330fa0c25299570db00e2db62554fdaae3159988504703cf4, + 0x1b7142089a165fc6d053090f4e2797f7ebd8faf20861604b3ca39ffa78d8fb6, + 0x65028c49121ab4bb6dd4b70ceda8065e546521a801b3690d836602df5c07a4e, + 0xb0c93a4ca60bd6782440a3ed7ed610e4ae11dbb6d73cbd43bab80e55c0ef062, + 0x538fe578ac88710d6dd29a5916aa739c9a9ffcf0f692b1f03d0e890a26a7ae7, + 0x2aaf085390a5682425de02d9feca6b1713d016d1682042a9283f70b773eb8388, + 0x12d3a3b814c1bbef754dd237698ca763867b464e9a81d9bb031ccc91574878b2, + 0x24fb699b2d537bd375a53a4cfca82569a0f7bf3417e1d05c2f0a996c5e85eded, + 0x11dff9e9c33f3786c5cceec919601c95a9569a01502843f7d4ea0a7078111ab3, + 0x261e407b0cd0b43f5b9e5c229e1372500707db45aca65d3c28421a3583367e4b, + 0x2351bf0327b143b2094e336337c156efd6dea461b8c2d23baacb18abdab7454b, + 0x1ccff891ab723798b4de646bb5ad6d3e3da5970a79a4f25dee25aee7ddc543d9, + 0x476e4b00efa019c97bd3cf545fe7a670aac04ebc418c4937827ca368ed3cbc2, + 0xc1e697b8e69d9e6cd15a5b7e2d446038e11a06250f693e21a7ef4d9ee11e53c, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x1a09d2b7e646521dd535d06cb8c4de0a1b42910ea066edc264f59380e26cffe9, + 0x17cd99a103a4adc1725b545ef98b3cb45b2bc761caf0eca510891356c0f6b6b, + 0x6b9bdeed92c495a84a828dd539be8327529a051131bea1a198bd849018a5a8b, + 0x8680012993a07914e68e1df59d14f13f130cb8c1099833fc0d2d2d11fb311d3, + 0x247b79afdd0a99fa80e82045bf81474ef05d19174b15ddfb6a5eaee7d98a66a7, + 0xeace989a2a643839e86a96e5f8a1e99e868ba1becec4171ed39c7bd2aacffc, + 0x1537fa1eb45e0b8dca81475c350eb64701fd14bacb0a2948609c9fa1b9d57fac, + 0x9ebc426effe66fcd5bbff51e0aa1f60385dbc0c7feb0d9c6f4fe06384456ea0, + 0x18467be5d0a4e54aab055cc7dbc4f876d56097c5eec5b27f9a15264059b0eea7, + 0x2dcdc0099307f6a54c05fe4f82494e0611c4909ebe6643697f44ac932f533934, + 0x3fb3d6990d8e8da405a112fc11f9caa56723a2f6093e1870a866c21d2f3433b, + 0x7903dff1ca5b78cd6e95e1284f7a87002f00a81d612f82842bb2af82fb850ab, + 0x1ccb172a7b0f1139bc8118dbba6bda8ef321cbdf153a4db826b08ad2450cb8a4, + 0x231cbab35a8a0e9dc999dba368451cb41d7456f2cc0481a14a2a7d72f201663f, + 0x1185df89f8a40ac6098d898334d0747a5b3d0285d41e2038e38712cd26081dba, + 0x2fa064d281be156cf97dda9141c6ac20d0e19d85474475ee359e109bc25a5670, + 0xa2114ecb4bb88293eba241bc0fc4a3b375da6aba30cca76e84810154a093044, + 0x2bd5621d46d2dcb41cd8f8a22620ef625d6fcee5d6d507250d157b39e469240b, + 0x1584517e545411ec6c849b82e0fe8cfe70cd715c5a657d78fe4dfa92cf690d64, + 0x612bd1a5329c91f6c6f6c31809951e143c4b5ecf97e2ff8c6b02463fe29ae6e, + 0x26d3d348ee74cbe27e5a4745e738151b3f61fbaac3ca334b1c6f0ee18a763294, + 0xd69c097ff13bad16f04826fcbc91eb99221410fdabfb06a04c69daf5d0d46ae, + 0x19df85abb6034b86a237f3c2a1849853eea70da522f725111bd78831a70f29b2, + 0xb67940a72701ac24d81e056c7ad73e3dfad45f6c1147693e8e56ae8759c75f1, + 0x2d067334ff4cab892a24cb40846b591176ac47451dbbcde9cac1de766bfd225e, + 0x250e8bf6d939e2294f6723c8b2e001809923b7157ba297cfe107b8220cbfc006, + 0x106265f59a713f1de605f071461cc7765c6eb2ce12b7494c021e07b5e0b0a121, + 0x268591932728ffa445ab526d9cb60f6a1de6c10e244cff633ba59b9bdb957e04, + 0x28a264cf3eeeb2d81d4c1532e63e34496b3500da9e62fc9e8070bd5967c5b9f5, + 0x2e289ec9d9fb747c577898f2104373a49adc00a51974b8fb1c63793f22414f2d, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x292cdc4fac941966f3f2fdcd0b64ced5ebf1766246e1cac45abc40423575d9c0, + 0x8f9166b886a64e24bd5cb9f5327942cd66aefe8904bab3ea68f1c93da72ff30, + 0x1d9346b55cfdbce62471674a48c93173f222039ca540946df8cad8f1adc4abbc, + 0x284445af50c975330a1d48657b764cf7b19c8b5d8cfd72bd8cd1aed812458804, + 0xe5caefd895dbae4ac6d9a50ba9da1fccf2e99182801e50def13f656cc52e823, + 0x2c549e8a4cd3cb9c925dcf4af0af39cc5d419957e85a1734fbe0cd495b4e6239, + 0x2f691c2890ed7ae20244dd12ee9fac94cbcacea42bbd323484146b83beef3964, + 0x189c18874e9397abc281643bfa747739e2ab4f51c2ce1c64d8e0f6e0f65f065, + 0x2eb6705a02c7da98061b74e10ca594d9fa85f2e8a76991313d2720268f65223d, + 0xb8c7b073c91922a0a25ac24de7c5781f5b95c1d29676b097409380c6e4f0d2a, + 0x2b254c1c989381315f1b091c685873377c05d1d40e3d20d41f56506756ce5ce3, + 0x1f9e68c2a44b9a206a5d1c428c27604031de91570926a23190329781dda14dec, + 0x107e82331d1a1db3aa814c0e3854ceef0db0270c842945e09b352cc69e959fdb, + 0x17fcb1867c52d50eff04a137a183d3f0dae94b5656c8818b4fe024b7a343dfda, + 0x263f802111aadcc99cc129d051f90acde70278801f4dcb1781b744c208b6aa52, + 0x27ecf8ec238d8089ba1393e8bacc856c9b4bb554dfa37c89a6d6bcb0a5954c9, + 0x2aac3bfa20e64a0c0012512611b5460908616ec7282197ab7345172daf70f421, + 0xf822bf90a6d6c7e046af505fa63c58152f880dba55cefc639313d104a99435, + 0x1d482f74f7352cc3b1e07f0c4e0ca4685417ff468574b7694f6ff7e9b438323b, + 0x9efb3fd5f2af95e1269ca6e40bfdecad8ed10297b2261e7a27cfa076bda8348, + 0xd70b85544585d7520bc48048e716d4bacc8a357c3efd735e10376c3a68e58f7, + 0x2a96c2d2c57ff7ff8a1fee90d4f30a427c4ee5faad1bc0c7640dd2628d7be337, + 0x467014fd75c87da4bc08542150237dc948da566956c03a7734f8aa3d4ce2a0b, + 0xb26d2f933b0b528867e896f30e7045af1f496d73a13e58fa1456f4aae1a911c, + 0x25d68e5bef9420f64c42a4d44aee71b216ad9054d968dab70bc5eff77556c9f, + 0x177f027b0cab57291463ca56e3be569fd5579d89ebf5fd528742f123718a79f, + 0x2c5132a44be83d88879ea114016e67092bd966a9ba0364ba501fc05b63887493, + 0x14bf8d2e43f7d1338bd93c4350007077fa9ec02ec8e64e03950d17efa18711a8, + 0x309414aa73703addc97561bbcecee45d25f19b4591dc6d772fcfe0801a85f30, + 0x40ea41587d4a40b935571880dcadf45e722e4273f0f2b32dda53e53e70a7a87, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x10b0d37ca26e90c6c139a01ff17861c46ebfb646f348fa543a44fa933dc6c7ef, + 0x175da5183f974e9606eb7d7e22cd12ae8e27dbecb9bd3c4c12b3f6ee0f7518f0, + 0xed8273a2cea837930a2c09a3f7b24188cf44b7d3b2fe41b13e03bcf26b925c9, + 0x1217c887532e425c1502f9fa496dc792acbce0cc79c661b16e4c35009e7d84a6, + 0x1903752f1c798c095c24ee714d1b8124a4b4b14d2ee2ff49ff7169ddbcd5b4b1, + 0x2803547df88fabd669511738ffb17cff8919c233c053e2b10d01bb398629deaf, + 0x4ee5ecf2b925246a34bfeaafc9239f9a5f7277fb1e39131900b432baada6dfd, + 0x4c37b33555c362050a25021d96f000d1a1dbc15c9965b2536bc4ef59b52fe8f, + 0x1a68530699df479a39fd71d5699898f91c440b61d7138d4c95a353ec2a60f0a4, + 0x62492de9362ceef05e663b2e14cfc1065415c4dabdca0d4b49b602228ab9aea, + 0xfb5d4b500ecd21e402496acd0c39a0ce6aa93741dd846628387324004b15dc7, + 0x1747b55b705c98dbe7c38903fca5260a313fb1ae77984671f6c2fd594bfddafd, + 0x2d5a953c65e21d277459d6ac17330055536bc85c49205e6e75cda3a58faf9b2c, + 0x12246b22f19de420b776858c17df7b57d3dcb9dc48a34167b9b92a429fd7a403, + 0x1133d3224669f992858632b54a9a2f3cae9a86979684bca621d21fb8a7a84dee, + 0x42c7ff4112c72f96e2a90a37d0b9755a935d43ada317de49047e45bace9214f, + 0x20948256d2882d787bd97ceb71a8f9413ca287382dead6b80ec8511a0f820a94, + 0x1a3624b0bd43a88ac7c7de460e246ca48ff71a5a23098ce0a713ed4cd3b42b7b, + 0x1df0dccc539de543bb1cc2f5a0747c1a1d39398b7e5d2542ad7df388cb9a2c1b, + 0x21dfd5ed89c255e1c584093f98d854f81cfc58f92674fe0fe8dfca8d7c1c70a, + 0x2161ac36dd50d34ad7ff8e2af49bbe1088d3318678e3a8d8e0e0b3f430d55d2a, + 0x1ed3cc39023610359593bf3e49a58dfbe99ee1afb33acb553bf08012aeac1747, + 0x24c8d8944de112708df57b28fd012d576868d998ed87276f7192f8fe82044fbc, + 0x183fb7baba3d12e905bb7184ef691982c1dd489844c06e9f7a048793c46a3b9e, + 0x67c083da1428ce521951ba41ccef834d99cb41e8b92a4c4cc7ce8dde2de4adc, + 0x1a18a9c1c45e95a541ac8dfb96cf2bcb5f93ceedd0135bde9344813b3b5762aa, + 0xddf7ac0878db5f4f384ed02d5fc90adf7215e4c3bc57d37f4c27ce4379db9a4, + 0x2adab562b4f7991948d9cebbe53a821fa08c96b9100b17a92d2ade4032f490c5, + 0x1f36cd6e66832646861d1a44378f81777cee66ee7b66ffa4466e9f9827d3efad, + 0x16c514bc623520a3c63d724ff9f8e2128de3a4e93ec26cd60596d2b74cf90df3, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x276235e6cd6b4ad073433414a39f872c42ae47d5caff6a0fd2b11db226627d13, + 0x288fc36fe0e39bf7f8deb74d5edcc5d6ac0b0e13f715a911a696212c8244cf30, + 0x1f6e77bcaf2e10160d53e81aa4bd1fb9620841cd7cdcf5626cd1347714f1790f, + 0x2c50c513ccdbe60dd9d14262db601d085beb529f9f9809e734b12cee63ad60b2, + 0x1048a932b87cf43cf61b9fe7d5e7824a9c0be2d3d8a6927819a1dbce4de7594b, + 0x258802f01620793e2b886ba9978721882e6ede295ab05ad492dfcb56055677d4, + 0x1fdefe23f71f9c4e4b5a27bb8c5ef9e97f8a272361f8e6ba93334d5292ab1c4f, + 0x1f46592f6d4c77467466a48358c5c195e12db247070f684bb30caf332e050b15, + 0x1a0628c0617ed94340450e8b212d19bb6d80e0c336a0c73ebd489718d0245512, + 0x362fec7e50a9ebf5cbc1bbd06320a44839f3e1a24c6dcec2cea98dc2ed8958a, + 0x1434da4216548b811c240f289b634c70bd0217c2c78d3515981a08f0b4228a56, + 0x2a5a298ee338866a51ab733cd5d912aefca609abb924c3b91334ff31968db1a8, + 0x2fe35de4f8239cb701957994cb678fa76b45ac2ca62d155abc6bd0063d8477f8, + 0xe81871313b59264be15b4d24465ccdfa520f1aae5e34762e48814c151eae20f, + 0x1dccfa84663bd168fead0d648a7024cc7f45de299a1552c65c9aee69800a21d, + 0xddcb95ed4ccd6154052d0399bbb3eed354d1348a26e7e3e3b767f888b7fc1c1, + 0xbdb5ed04d13305bc7abdc9a1f72a3cd3c325a8d5d0b37b3f6bc32f5bf2bc30e, + 0x1a3791a5d480f586e225f6a3419d92bc7c93d3c2c941e201aba2db0db9f15d73, + 0xab254daa5ccaa47e3ea7ddf885a32e8192d280ff8b96254036f22562e3280af, + 0x10d084b180585ee9000d1537f77b4d6d3befba3b2585edb286f9e382257acbd2, + 0xe99d44a8d7b3633a48109e8437a866139b546ddc3a43911413edf9c0abed951, + 0x1abb36484f304e28d2b406edd5d4232f52246a2642bb87e5e8049639a5a7e48e, + 0x1f24c896eadcd0d5f6b1067845c87cae3897a454e6093fc062b6e9fa9dc327db, + 0x1f8c613272cb2e0085c3de18d2c0063422bd3a3f7b34ebd39462a54f96690dd9, + 0x3f8600811917a21e6893b3147b75a987a7ad447437ad24fa472b3016129f86a, + 0x21268f597b84752db51be08a3a6a2a8b1b2284d8b0442b549ee5aaee395c020b, + 0x28d3ef83eb355a7d306caba33c70e6e86900ba153ad61f6b8b41ce49daaf52b, + 0x25d200e83b7288530086b690322a530ec8b502505f3080a7a46e6e822ac90d2, + 0x2a7f6b2aebe3142b2662d473a358fc1bb9d816498b3c2edfff86866e2ac00082, + 0x299afa0d0121fc23c6d42fb127eab14f2dd8ecb1ee0c04376b9c732e97a5bb71, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x292e5deb4d74974e5601e05fdd2a01a57ccfce1962e3f12ffc47ecf62cccddd5, + 0xb7fe07627b2b86b9e560c5c6058f62a23b9cb416af6d749319a5f0a731e9b99, + 0x1be04625c4aae2000e9e13a7959133e86b7888be0de9c4bed8431578d87ddbf6, + 0xd6b21b10daf3f589d71fb89c727278c0cce92db0d4b058ddb3b23e379fa5c7b, + 0x208f14de82a7cdf5b8f2d2c2d77fe963748847574dc8f168c53b1dc68674daed, + 0x261b3202a10a92f8f818f5c9b768d891b3fed3ae03b189e5a743b6a2f631210a, + 0x21da24b99fc179077a9f8ecd8f3ec7a3a6d4e8c62c3721f5a3f4a12fed074d91, + 0xf821357065851a94b6fc9d8d679679a05ca9ca81839c786603a98d92cd3be72, + 0x146cf2ddedf7045102306285a0322a26b9b312d8ae0d5638e122fa42221bd203, + 0x1f5595159d4bf74c70466f5a5df27f878727f037c6821bd0b4a16b9a1f9e22e1, + 0x2e555ab81d4af50711a229745a65dc974ecbbf16d855767d3ee973f261c6958b, + 0x9d88eb8fedc6dfcad4ab68ce84e1bf329725e89adb094aac5a25e36f8fa1248, + 0x5becaddb686664747af21bf5a5e4ddcb030a20314b123c58dca055cc8f47200, + 0x2b5133b32b578393ff342e4ba0169b60ad72d1082fda97c4b696610dcf06bc50, + 0x209f4bb986abb2671c9ac555ce282948dd3ec049e67812e9add90f3d83d62346, + 0x2986e1901bec371bcf3f2bfadcc34003a901cf3c6c8fce5a86715bfa70dd05d1, + 0x36f213f560cda1028bca7da534b8bcebf84ce7b4b275d873de14b03fbb8ecc, + 0x220d1b8cdb11be75d11b27932ab7026a54326b5b340ab065e1e4e35d26398677, + 0x1fcd7370575ccadc60429c962fcfd8f4b3ec9614c085d1383a943d7e487c4e37, + 0x1c49ea5e5ab4635be0cc07f0d40a8f6bf68622bed5daf5c3aae2a2001d19cce4, + 0x2c33a36c54999aaa2e54efe70048654f4d8fa8bf7001a8c92d86cce2077c8f26, + 0xe70e72a3a3d2e267a2b6af5dfdd55a25435c6f581a46ff5fd461f08d0e9f7dd, + 0x6cc0728f4993107d1ad1cc3c083d7f23847df303de20d92b5ec90ff8785e8d1, + 0x14adb5029eecd4e65bc58af84408697c8591fc5f6f74b6cb8335e7766a93ed1b, + 0x55d9943e138d24cf72d400134a020e38d4ffab9f52f85610b0e5e678b6ef47f, + 0x24659e5fd5b9d42642221039b404c0940c7a560dac0e780c59ef19df7fbb1134, + 0xe5d9ffb29775cf1d63fc54110f1e384ff63a353331c2935bc061eb0bcef7bf4, + 0x231f3394c59385b1e8bfd5709fd95d00e580cdf3e37f8a940c4213d03e6fc636, + 0x1d74d876aa5187f518188bece8d3f4510ad7c73380c362ad8252e6c61c4cbe88, + 0x22873eaa2fc0f1d24d83ad4e8c090f276cee48919965304fffe237a5c555a0ce, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x1cfde7b00570ae56d610b0ecf469c6d5417dae9656a9b36a35c5a72dd38f14a4, + 0x1a5111cb0a961ae216f5a1d83ac8da38d6910c2f74475efc1d49a8e494d161e5, + 0xcb1846e6664d919ddcd95c78357bf2029b750dd3cf02f4731b4975b4cac64f8, + 0x2cf7d663f92d7fb9c20dbd49208ff17b66a023c460eef5837a124bd89e3e607c, + 0x203ff2de4108ca7567b52a45ca3100b18c3015afbaa01b951010a46fe7b3a2d6, + 0x2abcc429149a29c4015959567a3aeb77ec781847dd62ce295a4cc9487f58d2e, + 0x172032b322c260b66b56d12d9f27327bb14859be5cc0238dfcb9d1f3a8a7c424, + 0xa0e87895274d1193436e943de47d8ee0909c998fa08a714a375656872fc5702, + 0x21eee81004b563924c0089d162a2a0b5047ad60910a5931ba25103364967bd41, + 0x19271e4f9e7b8a7f54041ca93fa5005d76e5960bc6d3dc132e1de6b2ea072329, + 0x42dc1a29bd582fd08c781efc0e67506afacecfb6997ac871b203cbf71df7120, + 0x6b8d08b07a1b58558a9dd55596a67cd72960514db555a0c21c6ba29fbe1d563, + 0x116c800fc674c2d6909c1e55568650ca2439ce3fc1ac3a81ef5ad8fe2e9ef30, + 0x21b9ef80d19679af571fb185e6c0eaa780bbff382e8bb7ed8bbd342c40aeaf04, + 0x1aed5bf3d3bf68f2ec32aaf43e0b43e380244f25666254b23a0321a33a6a5840, + 0x276ae4e84f3446a707103550805c52c0510cb0c2e253ec32f2fcba255e90ee3b, + 0x677e26ecdb28f20a7d565510f73b24c036bb6ee0636010e6bd2654a15ce49aa, + 0x144b679dfe4fdf64adcc33da78a377591421c486df1ac1247f8962762eec6353, + 0x2b3e47433e01893ba1416ba93aaa4e39de8ee93f6782e1b1f9d709701d26caeb, + 0x21007ada7a8cf858670017f02b6f452abbeea2cff05ba63511a32408bf8c55de, + 0x99eb11c109ca74fd589d0647392ff6056a100ae0659e60d0c34b9da3f27365d, + 0x256f44ae0dcaebe716aa9569b9373053ba6fa022693bd865017a093e029231e8, + 0xb43042d175b108a0e9c553cd99a4d288ba1bd0ab4b2cffc049bd63ee949bc2c, + 0x2820651d09922281a40505d755c0951dbc15977d8f3ac9c9bae3929044039a19, + 0x7c75e7a56b94c4942d893c12b0e8ba3d7ca49e2435fcafe0ec9fdf4520bb9f8, + 0x2407140cad6a6c1d58b3e8bb6f083b3d1ec411228763dc4cecef95c56ef9f801, + 0x19f6713df3399cc47648b497f80707e11c962f694d9486a1884214d63b1e2423, + 0x126880836b31b2ad4d3941a65eeb12015282959888382bbafb662ffcb146cdc9, + 0x10f48b8b5d3586007a9da374301e5246ab668094850451f601316f889073b66, + 0x2b35da385f9daebfec630113748adcdbec531e80323e00627efaaa55b9b9e977, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x413c2aabbde38d94bf1bba05b680f5fbeb526118e75df7740e03c6497fc2a93, + 0x1f5a1a9d111269b8fc9c4bf295f95df0068a17c12544161132d3d06cc6c28e17, + 0x212d07b689f77ab9b11d9c58b8eedfbc84a0f3a5c3d011c43558d04096b3c595, + 0x7c689aeb8426becf2d38e8e501aaee897c6a9aee5e479b40bf1b84a50fee324, + 0x20ad507d2e6bd8caa8b7b879d8a0f22b037fc7784994576a2053e173b8799f6, + 0x29a7b5d1df34024626bcd4d01586e1ac5addfc06e8ae7e20e4856705d6921e7d, + 0x1cbb5f6c2ab4fe1fb5e81b5bf2c583b7f0f6a3e23f51899071e6feda30610084, + 0x1ddfe3794bfaccff166ddf4fed76cb5ce75606b016aea81a4decd295fcb73d6, + 0x2b49298bd3a4415198bd2f444de89a1ad359aa90b14caf77d1afb21ce7a50b30, + 0x2c10b2b301be57504c8689054ac301f071e6aa6d9f60b9c428fce09a60acae5a, + 0x2672e1c103d7a3f8b4f25389d69b884d9bf997dc4caba63c15f4ae73f7db96a3, + 0x414ada0c4576f5279952e118e442480aabc46107cfeeda9ef834410483d7716, + 0x1c20492095f5c09599f0ca32e7df69be7724356280f799fbe074b29870e67700, + 0x3ac96e8e3ea740c8e808309ea5dcc35d62ebe5d72b66c239d5bd07be9523ce9, + 0x198f45a7fcf410eb81a12e1b309f0f95abc6608e847c5a68e3c352abf72bc469, + 0x1f46d6ace37983cc1f2e530296fef1142b1b074c0eb50521de863159edc3bd7d, + 0x95d0ed6735b0fe101e3b7ee0586f060355513c443ddf49071ad90dc1d05e4d9, + 0xb912abd1261b825f9e4b3fba00f8250befabfceeb00ceb5d0062b71e99efe2b, + 0x2fb34c0ec0486f139c4d6c674da593e2a92dd88b4556ac05151754050bf7870e, + 0xd3eba1daa20eb618ce265bb1da966997f4c131b3ff2ddafc0c71fc035a12f51, + 0x2364018273755eaac29eaae7e021dc0ee1e87dc603656b32fd3c671b7076c84c, + 0x1f05f9d5508343ae4597d0f01502a1660a8e5975a4ccf5b8915712c4e4a782c4, + 0x129498a8fb3540f610123f3187faec3fbd0f49e978dab3781e5fb0b117dff678, + 0x219e082f6b2eebcf1de778082e847881b9327f906f9b8e27d33e9ff0c10d8482, + 0x15b6568d2a70fdae1cc8b0ad01d746ff2fecba144f504261995b8c2f116780eb, + 0x16da3ade68d775f641465dfa1468999906f61926e73d3e08da7509b4a78888d, + 0x1e0899f2fb6d2385316656b5e8f64867b83dd2800633538a195f6860a750022, + 0xd5c49a0cfc9aeafaad6415787b8cfa7bfe62c569b7d69552f4c138b12db2710, + 0x58e978c6c092939294d1e723aa97c2e6000a5ca187653b0dc4858ceac8d1d56, + 0x188a71a52f914ec4bff04b742907b84cf6e1c57e855aa0097595f86caa7cb23b, + 0x2b6fd7bc3a3b595c206c43daac752b765a12255c37ab51ae183933737a8b8099, + 0x2f3a7566a10cf8d3ea9a794c4adff2f557808fc43b07e76fa4c61431a2063453, + 0x9a8e3349ecfd2e871b454f2b2e931d41dff9a96fccaa7ed0cb60361edd4ac48, + 0x6a81b30ef222ba0b2fbf14165d46c175989d325caedaf588014d126e7585a96, + 0x27c859acb50045e87ed4b70aa9a561acf5fbbc8d0a5215fbf0c5d49063f122be, + 0xe784382f4defe97fb1b1053651feaa5002b9d1c2cb522a0ccf949d59ee596e1, + 0x179e84bd06bd608d1d8cec72c4d182c13bc7d650ff510cf2b1f4e584eb24872e, + 0xf23d189f57b74ae31ab04b76d0cc3f67063ae1ff17a9648de59cc281f54fd1c, + 0x1f0d550989ea2cea26108bde473296824340fd2531a2b2c20ac14327b009d62, + 0x14a346d622c46513a5da377f73edb803a705ee18f9e447dfed88d5ada5ede42a, + 0xa71d5e77eb081c8570d2601466bfbea27f143f1b2c726a343034f015c81ece7, + 0x11fbd1c03b7aa3a9f5c607da1c4164f928055cf6e2a1272506df242230e9945e, + 0xb5dcbff27d668509bba8add0632d65ee5ddca9bac146648c6caf2bd09d9e46e, + 0xca07ef6ebaa5ffd1e6f748cac7192d6470b170355a8517eb697724cc1c3289c, + 0xe0dc71090198288bfffa79d2237c162ed9dfb5354c532f2d6369ed73df6374b, + 0x191093f164dd4120c06ab66dbaecad8a5284a96ab607afe1b0ad10048ac86920, + 0x111d04c083f51a6fdf87412a537f6601076d61f435094ea16946efbfa4893e97, + 0x133c5913f25ff5eaa860d0318f6a4b4349fd22f2d53530e5c785b70988a3a88, + 0x8875f47d6f518c8c2df51a786bf2207aade284067228f440e7d0307520a56cf, + 0xba9f44a107a81cb23fba66f2bc34152728f5f5ca68406649a7efe47c9473f21, + 0x542832ab23b6c7a4b547a1066037152a2442e998c5381ba97698413153ba6f1, + 0xba1f764367360952942ccb6edf051c8f937906a816641e0d1e9e2ed26906fa8, + 0x2e0611fa4ca3985d7bfaf512f21a4081141f4ed0dc4b022834d3cb6cfd8b7ffc, + 0xe6f23c0ef6f159dec68341a87830fb864b6c08cb954a14a2500876697897fb7, + 0x1a7a2a4a08d87e75f720302bead7ca21c8f7c2ed2debaced9b8b1b2da461cbc, + 0x1d8005df48c8565987dbb442b482cae5bfc10ee486ecc5b670ce861345979d1d, + 0x28122254823f8926acb7e98f557e796282e5e1271618858e76d49d0886da16f3, + 0x2414d4aefc7b4857df681328e68a582d23b2dcffd579a8e6aeed6c61050e05cd, + 0x2f710c72d6da19c7d87cbffd55665b472b0265d13e2326a9a33b96e95d3746b6, + 0x2e285441d0bed90bb41d6480836850e4d76da8211b04a236dbc7c3c30320c00e, + 0x2964901a2b42e9aea1a6593662aeb9e12077a287434bda4ec2012e36a19dc95c + ] ) } + // noir-fmt:ignore -pub fn x5_17_config() -> PoseidonConfig<1292, 289> { +pub fn x5_17_config() -> PoseidonConfig<17, 204, 2244> { config( 17, 8, 68, alpha(), - [21579410516734741630578831791708254656585702717204712919233299001262271512412,8554993601136913148229849281645942416873068991157116548355045570766869071269,8349770263904395404819051886764727880530744217762197718931556224723090619132,3123463970516625956994178947134086868722089624251980030957656091366977385793,21442360932957798040744480141231788172382126494033577704060991460078536626315,10231325350034913697901001930461380417506010080725776869094346614943052057882,6920436402694617694727322082450000548200664649231576891284834027764418393590,12792717999817516574604019538349201413861750406724026925198874802923611904714,7319083527910098850218832163004092895955809799710817531274971443221833500573,13757426179233640966146754686419290630140910517321420779897314617147307309749,4049033549996591060740078431987567671358359797940903000648212935570542836589,18201423118137949240970920992151778204900119273029679711616513196892916845798,20625824460928171809204757749985517429359815439093046150315733891121610507133,10457729085307334834523167401466014435492132985358294006123747181337070073721,21561527744019186913993064335391813055903937050713577176254373319368609289121,5599728995155490107164072595052340911357670532131511292391179640158683770855,13966745298956307615009517188536529139238646569224392383446375189982202020807,17756603569040095098346793596909383204174838953876788800894937537311312048006,21742079076354402484587060728532755692106347543073105531119578054037775042874,11100784872920528132266123983509067070706469425630493971770997902694662926998,20400085312205960400585536190272432205634747302273829805331461533195763963464,20028967251238446138082148432746545470729859763361092299497853989733022321309,21646094126368547381762879012999402861347883442032865497835121981839683154574,277256790316883617863153728392861425598900309956876809085316502674092638050,829273940377701999291777589563653090200708284690056650568100074655963961702,4606908934947031763433560217361121304957410936748694859993455652227072492205,10769441872728289230396615620861141176949118733537017427393172917499470840245,19521824504454300285368889620047541794275889938757845035419559810899465345698,17161053048471962353174720811774420740284389196847515292313979813334039268748,7908822737820790247231631548479205241063360318010733129560952138908448461427,4877162162397125215823403409232508291458423909077159953565289381413423118030,8487393998302601588798118543133789294087935184558260165377494640490662085979,7454433584826937164880257351721993831542783218228578962943846432869272993591,12600486335574416961082984651671003440366178113351945406282261259087640562075,229943091042136639964977508364517877844589816262259724739584329059854831474,5964363464498190105797451630207382654570897906930358361814931706994649645813,15027885081212300130366181566116370954163923966760653842199145107431036749190,6389712846176883524184535452348872799769012323597964483555439005016828865357,13050625522428562689464418495099691361897297012535198348448952952830181214686,1457960163867278804802442802649716001232992897386781587117754753421449788143,19121642548533119996481133068671203033851078573250942970641264441950592334007,3319626593342830359906793887689227542493167081286725783452961782138075389498,10182025658554317340763807114890885589336807302908478511429803960136159439487,5258867553475471512860996445670851629850555214065072419972647507253648925387,17105844700483111456515253413030059462544811526461544189616915804056937372339,15389507448590279891790879860335127747331525679865083633840630125275096453854,8628144040598587326275852302297295030455205882673458629883629373821226515849,7225764039772127797033872800338173049227188735693607855118081892986058306767,20070937673840272071045130712690506696769042932336737261842298381743641619092,12139783026483217581244209544149124607538399031092603229603855979370010147969,17581810038009568123079980574064070648109195109589787948955203592875730952957,12141791671600953962785570868053442402210784762014326945761482080946083167280,10216251141439191088257104654134450392253712707713481968388586155680061818083,1414175852848441331935246181908753253333655328715371554777242869802352097003,12411223399258687363418284739063179467323133097416451119653175668156302546282,14163252864986479721057694562184281568622251449154036885135516034438034547025,18935280158362457804125825095786762216868621594409914695877661895590787449138,19612073572528301850608997760721508284827614275438129248352825723957284031526,19819295714156197944855748114967530774512172286810045467127912108030396642179,11371593776080642722788656520803479745110058361122399788254568568846349693622,4027805955664709942434150181718117928301673452282014923837288829996079949500,12539691854417510068939338882045915380674719248923282579976372900935687263702,21456335515466708235982252733061551106892811579323562996977622319059624115114,1466175641997386496752167837552521008018514071345728218669064866303097231258,16954396739281784813954958963214415095472216566673098897333193147120371509076,12708223137926559496125521072416503266378368566414170219615449248989766379947,8788739220646322755486256871812144068464402944468818647293944655221095435821,13058732292597055849703973806172477675203122319912563406670103404654094386664,8931344638882118593791237662384261193166536469680242356398517062367452395384,15456845400516927354313637168726345061971892967841823745636300923188629474327,5751588038559337581650296498368532807067353107651773867820816744681643949204,11549544825319477431118343561134281237789591414423676704396089395115754641434,19234147263577254818888926168924920479297919454657521855750553715796101778809,3648349134208466654728357812767145066715472797730454946149007751312314206222,7718151953117918461425809889893754434608769559584222279828239292761893621712,8845522739821256867897474373924647700071798803600128774472020272335057310062,12793577303328701474174653130332291657457728764837263636620978444987214166803,12567791764609503071525053111715537148465248715927771041171097136254310005533,14173284996087186652368776168561110401474338255050963923163796413857580470909,18034666979500281081740131331708674377786999775618310647791265825609322054725,21422354834639531449049641141105504766268284938752536446702823580190877745329,10861911722118463296713372205424749768917665229584553370962914232866310912045,1426840929949909140164228257293070123281693940796332643637029311310121856472,14301944441994042783232016477141675248310618781100688243801831318561916576546,8689261616262362847656173161257424730101884874532916838450695695508844076137,15123977840288488307479771803223205244132730982232338102604391529168092315901,14782587644869453236501780556963556761570896168324364501980524203741590116061,20171126664277707857959263654502050384578410237255325322075457593732181023858,5586442008782671473934242848395070351077466917106669778054075503048330770950,14893034316669944289540729978541666240683450933307479859464390524607307041597,16358386602267214062406516556279496593235072850353941542010428321612942609886,18848866854232312978702044457572917667782740587353338084332267136131275700603,1579215194993191651478809349088803658155969078580739214414910140585581589538,17033458213089087701892498495271710586197475793707993846597834001983636294290,12940326624292849673877504632305122955030021835426715254781235159065401203407,2093340797218797584680567638361507396244460243439847174481303012347581894177,5964973748129501579884254138099588668727348462189690734364404017042795728252,1674681106235348685135834192630054282175690835155947917214719741317698144031,6021317549494232079997036595203156655990507346855425821696978600367848015237,6518804338080390019586997346732962982860290823548982950371646893604360711024,15170463834922876947772409926040699970156014460508617331830728121385518919006,15398930479669448663557196733417026149527004779216987588229439497346738958046,2669700622596766237628533802450875322874330587389952384417956610466102910333,3127548363874797616403801375102757494200866522631068411037184158214286131549,6584403272373574724590091428656742867168271029343425772452216864199113551892,18683280795877134163038651063011198948877602385157504892093537654399764426518,12422086496748175124620724672115957665892586761203533990582978803368996339430,9745099390463439278844126903162955736019504616033755299630228960871294951628,6064302059807957253392579676216068692721552882853761726090911957467256977688,860534097291826421956520903118828583111860517568849548148819591113129410233,9809207437695386100460912579554305365027175459186390700555141956544839955242,6576375143489291749779792018893403099848704832143183847385791291045583986902,2551573667498115865454648920084921687986702958687913960418526064766186248697,13043550024569409591105305093191112805611412364703194793685224224072149855745,5369051621601119248797945023525768932797813569336410551989722329535217332717,10399989003670197520503648853627144005300436598931266893609225004624861627954,6159561484143246751423457452493034991227592994791307133044136210702400602726,19651431183851896182934111830326153107040303776630454129626690653306388341484,14970612719926241839940820046954288242553272322468930717244806728631485407526,20461999502486452961875044483247881758853878278954851693532423676388213697528,5016750536904085805050275769221233811927007383797241751325050175740220466319,17316427284462136919522043989265881044949832745678035885743571937214912552561,14932533665158850512241105212984927846164589888111067103835286341225240509742,16012484446855626574765806641361955141820105388650596409595164514899481874274,4863651915422513654068087402811690721104417928537042800794511645180712743925,9478941069339421252769300213729433894403874553023597073962166402867140590783,17529734771936454727002429801459948360484278991049231778922771896004721758963,12672015814840095133854330679674924244657276110030612294537194913437310163995,13442667219867515606432268873704321985951188504382080502019480975401891351960,9346556839116407181813364316149756946394621057020562307256030525707411763792,11720199480542613604905913885140886560194773593236018605042270421391171700142,17713550818981273796962302212731756472046580671829192490772244177376146261137,10658520565101402948486320613747540160084586467440232263820881394770094857487,19120553688581692745126354026518291549778059267410591682456431863134002720631,5837704130879353469974552270945063041776968090189866547252204737075618880582,10952573317837731274507039100853076769322123807364252392559268333440123751056,16175443191562457274813386127054957574917457114692631929042817125665307085782,15651399869272720599280980856510555798668301135962902383119739133368631494409,17982602271750585864051043003255537160144994845232276906099438195600610259340,15564417296959768207318803300620712620729991326343744282367518107640962243181,20488793123009381941807231432363887878967153580282107905075818200161452173728,20845615892337349138315927113904389806784179140299978993512007141180651572609,13259443846669565093311907999318849863250202720247601058242623542433998488480,19583450200980335366984605451914375573108173291577305129314361755545713207859,838397221216450052117952481963960818729311704107008458344946293696441980221,5011508169974056046810100610889953041631883487165044189687841384459345302746,11361142794005243853743618662384069287777450724025651283005645149554307240000,633456298666951303063125949977139107258301407861096110769739192555903857431,21529743295731761646584336858048296237991767869832124757149704140550994020630,658601336565148638150196750528474813469384561163113116358457661687263150766,7199686023207207605469992040453620774208316115852720699379826196410259893822,6694724393708237460096397340665472114749949954099504252044742926933353832323,16157341357004248687598290467887486980266976396840580002635620741183071441576,18735931046113570691341052792512856145472697573166865032702507242384749856515,6329726929169898271848965669873324332951781357803010027329026944351232247476,7061209522680426874403579559245042585450674594552752972115778072823155787614,8946282535333125111854282749852344921885511854306802144459174056051518348720,3988279129283542026399878866455129212655792613180690875708855315104446444211,19788373916759119069273555853960393438264058803290744373422102428664987314058,14781179276955000841116554151929609467906998220188278865550170013658249984549,14439714507608577761834821622197467839862763277392515730094487176490304118865,7462417821368326183154895363497223167855553631230374112323789393782682375855,14594890619141141626245598750050255728680683081531253962411791337998057959565,10297822643679438597162031819677962851770740929826506853838015287832878785074,4231562753232550403815225933022904310027433526532932589628179163940950572874,10646529230382575523755302352793337142051175018996981972379640368359926883275,12164083461947216214412634084378451605511487715584004827824972078192861740778,14686738730377226817976749475359230017849316512373192440082122302915229733394,1972065207953025646946682878392649299678417507238551179215236414492110157365,2596220810659736571653162812588827790612138851645327014072494893329877375848,19742890478753895876191378843357325113803569368242719397467948082842949716134,3057722811279760312017893583084211485332195649925192440822130571411021625062,5078380046721228959752000757775271056076152925648793679038634805597314364689,13994065550182407605627049394529818937411332791332501915425485445970019749196,8718903390300613451595895490522223543548941022555756021584328963874682051659,2830037047734434537263368457077478915382396457133799070168011318577509852518,6351328336589112831842317252922662854527642572646149728733839010100363641064,2326811025141337415486606567159001979990362270551911801543813258783748664928,20631048108966815289784074608382072458460940973738551134226168800345554951214,14721204648069833595280990040775556291988674304257774357769088964732410863991,4551815408348203166379129282299441425423743023821112768447969406023780214645,16626589364834731158131207695359287961392723773324953999720551575045565560017,2119119902895954746578148914775899257881351646176141505001582342610666449702,21198001320003994532825962721847645202213745138854311312804244693213734456020,16575653563112300802890760228610449333758690368857078853765813869752023855520,19662199829424784148957376290310955285339135428848477356788149061587904074636,14365866723679934269369638167309959664282416562097092385771370076826961535871,10462405794880410718710911820471224752218613463413073336296570316774568383223,2875852545895825315521599376020869827316570932962420930916494831426174036683,9365014190378730240070787324401488407601702337948470069729769089736757502613,10207664772554042762314615033378156185686480986853035052764356129216234339601,14593204638464636358074700677706356615788934459664487787695216859702024204802,16870253735699395936222032450057462746120274245691549241725232755997497777650,10403141045354931831897350467824057442824486714796947030202528195269765938299,13491630075210993306306680088269974619065901790274179689314972497025507972072,11737690900303251277784941365088697342741256105580987740031964012547987099246,6479411522140791199878732386964631711912096436445632282256505752750116503021,1083921069605939352705123162314489784481429719496507658938926140311574639372,17653617267480348306435879910355154811805166995916787026122631473598046826333,14432164328022071373295386637326904766549408251892516429892690428586807444784,7793671760657336901389781721891199068620856343884708391197481940646184551315,1959765449995198342923438542063212054673245344496347360855620191194506656856,13782621216902843666964879695291399503179812919290969771526164415604545126461,19078359557987218636232226316587656499460623053969287998311225512418446587303,15876205697805498189610174935234268016677320029636416200517433249256912037787,7722805406045443730324325528663888753917114626390901464015754094863680930900,19209717507699122245389693034814796437142853968464799877186934474171699195095,6585127313235216502111419023607202115168882276771320178943546160044534358599,20805733952846662054565520828206551321957145521190409450891077526078523041277,1584895259816785676773529464055176663163421450657396866598813628883854756221,20856003384184708896097189495372900159489733605505425206950257455550934589790,14069406225378546242129093232844103602751521581800986668621079503726397000027,1028001874294327945398022002342466649656159450229921471622913285892988310568,17966371882429795190944428324003030336630819228004846253694564940042988400820,12876427863944186509000750451848678588143362805691657085788824358176114653258,8715273966427022806434959651283926754916348745411538421378504642158804932403,4267431569502908019256597205760133122178817596876838981125845973819244098360,19262568227942313166139131845806786518421402326465887345846202580592913547380,4587852954486808043358798482712674466376898718708260090686361850306798447997,14015025676058610927837367157870446606501041323636097276737547710444897937611,1144137690247115846969300874102656726503285917182531654472086138598330367043,9454537148137071892124156670991734830383436460928166061331273469365959775909,13012777452486288707879402995033258068339583475193898659333632638157561913335,14224623168753818289919819482009713832024545924040193705962378465158371078837,9505762419233185123340587169990814384174703626434894051560218285882560747356,7019256137023476309554512440166531052657689673592456244254319500937647800006,17246363017424260106221670693985197925080671704985089438076796011281669775795,14408593968797438981684807585445491387554770474935530894938751288467685293766,11991202914737654500568163346559814604911312199759237827422720619371707311619,17485055588733729741263685618351826350652951158142561188142663313955733134315,12950471790443580303905847354051728755537901376411054363054627208333559704631,1323445558625272814455691764419102369727943978699511295257501714917998936833,8841255445674311239873770890653537908142822789956793926192649058263474173411,9401395313777449751102417028930156506880556083443899378760756340424905478877,21060472724780336112168263494706975132712741930000971588397970288258676527061,3812019230904757099892361572360806117962259446525402823615305574055615634484,3514498070156020200040973833201476402797883738073136493951314455793989266387,7030071313560321306345374157122385026218445152391153750375781343870025689321,5268144785716401601955218888231720448573921710587461252164696334890979118029,8300685363844078100354914067414753644670881295812529449763437785519065857313,18450162872081547013081002634376155990252513846297828484205311669445865332085,13292716648615315298838871484647252965100904015865352978197979561906010036270,21013686439245380148735850740480550290335132408628769676980938610161935118557,3221231898146718165495762474085749772444251029483710808533124131909521295435,21706362586702075336538820540433124172473413960581336734430968480142138077992,13486895089928308553329688303040674812803987395822848864346610815697956322679,17668589109420826004140047157134934003621500937594400640720194981334871115223,15183620307048155399117286900834263744557758459406645835780045985078670266986,3170561135789021599641212581208901692806457808161683895582450799937372092628,6919102281737620426489877909256066802544737782816026767549277126151765906518,4002850049662127756373199253004358198702226377235167238172929008366286605110,1107642403321371666617924914652619792767807515753221818405051786669061003368,11885648350895482809772026695774528865889321558031441531978106387676087338277,15378937381250173939485112486205353769964903768096281219667852296031194688940,16437477998115322080973717158007622249171727785394053923880768422172683727081,7621121366936849931681051136134866470312478335111295204625916349299382392728,21215912298727134138155623335764864420030241120133029649046764814328222738790,3170821186412794476815678730429053912378444748965057631248759273529827834502,16084650047636623354069916778426687798588694909600147172336375822549887134716,5100048383300431022278915674482647701788618482574130930551328380700470664477,6089313816847452477548960449234592795575689699536263376449482717087314881254,3168424144644268762342999941888553529072271091445061821545187264931478820334,10404448021076504176124328273829362151757942013323044839630548232003974036828,4252171300134965718003785947840070216898476595813167252439064205515819918152,6217524790069168495104329195931800727381161902791016429835385350530530741236,10144395323727769803680924125110392290775229805005263966394467735634758369184,16773588435110330580333921944382990185799235928388619755745278707444537536196,7377711139925591251943689121143870901330717424145420584097007639933333168762,21066973161927891686455166855433069549513160220938455527728499561969343776185,19501795117214672544349409001236794757366887214419994956397195381058548371627,2696597170314397939863800656320896858584168884088153464800095340021127302558,21168940252375267860138608985225319663694276566348965377356649424639627399939,8729578229953090469373121531954476034394661891580932672218135172268595941310,2843049930012752804094477290180353526348132895187059237802643422297864799516,11477013052507658297840246977078282722343354831202397750212752940967096033484,15309765532985207981165438737385487871403890172460978621511228072457639715462,5276795386880565031975868524294990841634011123906486763299115154863864095167,16891192769456289619320007723900774808412675144364121907391915236424354884923,16679134204463371830386366769161735700621394109825781706069839015605424451750,3726779668847121591477372195002524410424328772388206362047548845558525545594,309779746952337123192541883987405477861316061278735939472746602872146210577,6116943109304762420893019486121829026477809860415070409858407396285217706031,15461534026148460547793521829520247652146949380168641953893161519404620248399,17490188391720816485403388897026469756907238275881766262188942134609165349946,695497190921838164093269283587166536603898439348751059907333515445935240850,5740644431998005711645731796487090897088650307567273144862464339327188211037,2924287064221347495709747210800576855931727720487579410745268421394700507499,14573731858717233227103947986267826915706941233771169473071405909223613015343,7774646633424887132991406013236011457803238614262239840323638862678503960297,17118778781828713462818509847054627300883191299007086864997977171169360843500,1050282722198137586289457046966751947431030691327586256768002473254440863847,13445581272162801515105119436838273760359267729139949483205892441735924907588,18349340856764570254875357271690106769333653675997142444108297087440025433976,4652091796588614730462648254434910913694389428280196479944835477366269369125,131910217723821243570751713964244292677069024546597890404591990585681690631,21456499410534986907068306761035738313492308692998775099405282472250364294940,16716064024995806321979269360595144737028204641252901859053814928024784155019,20095956414904309942694457361888203543242910622115746869354406017074786974736,3757071258857910927294547413264306476593820051587638010209583502745249383710,10923680137512329262337058371790257353876483628009769758330988714085083694256,9956537089548622902535815248396999405593511084482117014020012399528161074693,20271486778333058297667394153786073312398256884133810048721290976749349792007,14016317906581503528126751971528140956503207448983448742275011042750601060387,8746591469817011275278863986926266284079779997046001490419468813462270883629,8984522535046539605932734670718817033319009310710809111062522425202730307709,2799492130108020790397631531338556641981343238572990117018166640120082230253,20327087348772938506861277218558621387616751140016505866350214286146319911488,16319897245400426733698423830406514849234661290508433522979200712395774573821,1519870284239742680329151132587900987246869312347047206488363104123425891937,16461017950418215698742181372949724919904570515241953684108936425007551365381,18543391801737989528567594217602323229839954429370908362237267818290566814608,8685602143546136106524472764079001485875727469672211204721272795643296788175,12069346074371335540240816613547917114412632205795651309433084773115960400274,11988670992502988905175891565316960155103243235237609851490650832292602385997,17403966780192169176887636449182981656483203656331951842717004987726351707328,11324032593816374026994927363702518223149146507370165210922763265919399924610,20234844998585751045105028410680389242420574978256032494303069254030260948453,6845765195018211653702320958640753289098798259762906597713727891164248375213,3889696987737574856084707743921432094490126858489993810406205011091688718490,18124922133262643422852054628088483763756251512543531233603218549062255836441,12631624196128994950514018157378748957581711189609992774676240830354853053921,16425963978111788432975031188568839119447517807863396285900192209489855884936,8953995026906183527591662774513923704717356851383827135468523305945599975444,19118152579552440466145418131293777218789512388294771840750929877489494176003,1815764556579131181044414049066036485535218062641438722387702702907845125991,879360492005214940756250098489982523077085264774860932709313739626061471725,6498879898701797309689806511256248775170834501358785166173840360873803298370,6056271365753495672454589488039784798700896703812263056079587620516360143438,4967400286944517048147291964513981345417368809842939145340090658371340301574,4566978800722351857193060210384689061165216230883853755194411631523409885319,1472717723310974984615849145251472221350601734805367368974791217038995119259,13776027174095858271746500087697263062688345981919975914318610607049564847265,8855093701782146194984545464090688949611436896016570549019701846352658653421,18811023873792469394695147052306776708450724591075344787347859872893669250403,7691358114878791244762289651247071530769998349760928484062499608910793916658,7225113154421014531794800873967433806904006446284346811024995482075131277430,4255179040498688460969978231175134372259939403539293652133247789357971307025,20794639690572618510879417372961642037150870482839234645523330418091682849183,8794944058569076073698664070073889624033307879863301731569984292406059326253,2823363224083068189197562122730561866372340074232470613435703914053034396662,2975786158778622849913792385919164957459418638496064741275725856836606581091,16980083616151411398660130004732794369729853408844917920819260677159874549034,10213122016673910048073131434217437693976054853300442236815045010440415530751,15622844733073950747464963822187537454489639825890383970141531456136711221220,18921846985235911245949818418983694297719932450371747402698247786766269226032,3046395690298904837024144793490039860680756832120703445515317729068809524596,2583060914190138727980083409436742233507882746342184052904895573386721270220,15629635543342892581496645526353345602210475132913669274084203765913418607483,12153931408209967834920681475366877980388294821029465748773772434628588757707,7196162362609954988171353261930756212243825869655325258155368337285953898704,10832344161051287447174100117756887153534049211780756324764320129746636797806,6499757948467889740913713634114407800462786362067580649690672122741467699071,7899568931631241171429470880810625833615306002278541085808972359443075433638,12736525266255297750005081634236953960899087644399368181751506194282329326346,3885354407428541945392073706505699854042913519198595640992547091062316682031,3816703467689192492336832188741146914005957253921702912680936907951936401119,20505128951308490293180094071215431973523299690572491020108425696662802268726,12432320732362421179661978984313902638822551634634152631489842715192622778201,5512525665270220248672390077644266875095263411830016769341860810913920051168,10270457412178462574290846807202840698511884913948623978547229481110915603115,17881266377985198177178319262577725460740518218103427901653715311091974197536,8510066829287194091329244743814121446186389458433991751573612039633575413794,9055280011331581456260576278219343217137015829507887846588161405525910242827,8463744395607465452751391868824103994906876103054045629692996934328842962296,13446532739903962714217041803396024505862416007402976354796893648172348836934,20461627446006946445871657481203161690018232261049944659088120713658680145761,13772437540389795965930455187657216773904696937414401755764626097076342530873,1466290965505206997895149562488255231958570328271915401528301574657737237351,458020438009477539046680120243558779131470015073376206673948106465783075724,1421211327829956939723172049232055433330521137466148179271043779757165996383,10974718981737058413203531348845889514701700275404265370241257111393906385203,16573626183656890049533788707333278060585059246627869841186891657544526527154,9919036431890005168544961022934926297421650894480789723772572215746478261369,16576030844958446931425212176715038836356393446209694437953952981269181564296,14994178560671337822305816896620048994236927709898591331458613992689693774863,14008584724223915404998855561309674162219693188120257826434623735246475372519,1069086166685137961564210887004146480746150199033946836704942515923278172866,4441018674700315637078726026786902627166868710369033622977939038672598925463,7640939046542807984747271754089880008702702616120100267707112408768750045699,8165588904763498143729494321532511422369875008004817175656306909794360343847,7474879615118088486232080639206966699381035482748779385536890548622822072536,9155173050525839883630603125759778497949178563635870467694197797566249638786,1792459779962272311746727109790955426562388793812453852666007819191763428793,20263099395174426853367767733535578420938395109027150658334981283108594115829,10303451485708370514931418998595531573075964003678715177508051557531947678705,20321308667229656744129683025590573929765537488045735596831342276888215355579,3624395650764060579161285692706624195562301326135878674105170566731046375182,13334418042222364794805341409419804498243524763983861307681793920401725352392,6303209034428307796195867505386756492498981454350686160404486917810670093803,13336041503866400337979868539402126587964669853045701517757148479437143265311,18767353303859794045974955054051240567712613481262860811042439117400294729243,17648775923900705033106796825075257671428721760143056038927896765118752472038,21205320334769131061393260976939399463360336322318482845795119858952799244444,9155233455417262996613263565710157090618649015115334735214563627053911364986,4147290460198895367036286052342502315935666580918696244195287512520682701639,20798839743961894523110712994056132446749297094165852697406325453288254761759,10967475255107274575063249329253351284200208982490877243231819333935797701403,11107733429142106765947338633972307528508245023783319424287268815241476152303,1684156923230048092780410733570635056170405885844154942542264956876312136441,6785232819930341498287206635949744381666087373588334711760162570781902812411,3481752771358613640419060374040695972756380958880755418404724590727014534662,6255654521236333133437711371709951475374611142503566953029069344699939884443,9785296768537417566104801168235697242332552358062255540417443962942437906303,932526381863697246577606288678833611354323840639105626154693740791708621269,9020085732775576234837702925603013416533345825301814972240093864457581450960,9671990085159642158315772309293609967281764349933520964615615069622307368396,19046031964146698646372035717767563096934497588033260517438574042056341692955,4697021545834663993102099542459528774847962616007459562129439303924850728783,834623291329335140949595387679815012162663877433757180177587164505466461752,20037517567993747767719709123741990248999315495577556924410214834773675677458,17745162106287481150568322325139792027305354960331855484108228857447789511536,15954503136290327680020013900783441236098225469294487261574644367048211928766,9447580075462399824000861225221012934395732074158377365412928734066137521046,17638109886139425399034325504572336884601102137123870982594354109676619973628,4210479489522190727435015049116453108500323090316045735249662201929219316543,774908475070259367041407977077109033779248383557848908386935310773126844186,18071521129238587956292632288468255723364769404447125651660575676226691230621,13782927851189257932376007280798546946814788900735661108027866834341111483921,9061904191092017185731693336948023564331336704118962360596629665269886564501,4646677737877430404232975108246717822854320420060743321121290725024507501530,248089340757097041959106969939801712104654938085655092524027449699183655736,1925061776519306799931873233357921480445138537754738082308417409427350959191,15090381222590604653751344079459745088601676165498775998808367167579158825796,1507946310710275058017347456880204243614713444138569740896198937197257762391,9047126832872244897061755443779135724439127934417426920025891305321906533199,13210467659674398263347498463769321394392811495810195742972914861526145024497,14930790949584540337435206846889685669928690545385782178172828133028677953780,16709614617820458913659268544942181680363927832511699782451755998512279824691,21741729565131743651162167923641181853909251404044798652854243082519505872026,485748276371306614511019734420369335387299906747036897161996666725324275885,113729363155019628451995418785166919308643202089193856958029953269497359518,17315235749721747007692514702872348378105966945192310104719562066051041365785,18164826565342651411070681557540176534582615273713551079309038721773735887418,619154088023795178917549465782795919604596935887112076630902791174323663727,6356343581175745844660675205642675571886993827862033572086056964311839166798,9925861911435596968816749828945917008180837850750226489783169376408872855250,20485137494818996958862809145264015810010636121731140334074571507470008401090,19656735537075233905125360479201796779994483024563540752004528779684256455735,15774243068028338132223253794279808721177740456197787086161475053638867039504,10497591647442850110427658608196767909160517521573199077258279280018098065029,210438711366620938094565498037172584426960275594120406278610962685482768128,14574298645311491089278146576548733364636851707576602363349001846285614576119,12543161131818467611229160618197160281328232851440846538778664249828945509460,5869885827840429160723685065960013290766384774919021040094074809404023704797,14800413279643792835835488664661954863340552091411990276270728475507101877386,8706244411264045072904148746698442560958145712983473320099851020229801141593,13670524729264788581176214636184652482954266319986131183163702474027069017797,6632699635952855355682293206130135801472538218093800086693644923578553649842,14292924690435752338909900819628889644248019746008463256978678218121438364347,17727807116656957204562694366530472131199058877798797418410969267673712196106,11223858699504492688371995874202967948461173433281557745471419331000190821973,15274518373659950909975149452889634174127158243424169830798483206460674313743,7047593141729299688704504157654237466438485917193869775780994636019451364555,3378912259124002728608820025874776626345774864595321854977438303831475863909,8837103908146248796259735965370584845236705198353666155001962958984824353698,11869977356793268256679742068396296621649101901864556682314737356997442919617,16469201342422734819465744813830056682872807194264521097865986969265941221776,12990791567002738838300315843749937126679083554067128201599773654099601117791,20519376488199491586810872596388233936561051835647732260479226405592285629272,13549175857035221960740890286176570298280920124622104651989532035707272553373,15234870385685844193215578943145814211167163612264546132211506983633757513134,18704889004070339618907065844757112006583041625995006884582590095948666509530,2234955996987396568560381823250866120960007674191266942270485492312904973151,5564977611394684319243720881013051542355462582947649518330549023416464959605,1112602741380454855327102347931753030221494100363029829630354546334828994329,9128209482091812367673670394219617423875730198454831896130112252113491505252,4376101007428143823621574836425643116618104664163736787280388345260726375856,17331301745157506574267466700454501468193891305005371065208065202603272248798,21846545094192300969525954249087973697025055955155275797969191218036594965229,4498927631211901890366201669629694821005085404418517058539528045609417501903,21785888954457119007377380145673667061898185873161711282742721281162112687992,10412875728643419025694818649503070798945684772972009054835016566542500457165,10759299704717838172704330861378107927462309935609553476471308013349659622009,20590357061487044454315237834494568787816431390448334652405889873515373283815,15673836157910318771949663697819073723405442238797105611030274826598578081102,21475838557209838850221160141181337897147127057878049055974104365046170025610,12207716311215040854533276425309298962214124105108870363296256769166507046674,11559647355273809434894669847822031984160367996613651160672893927347403624957,591243049503910187533030984285442752553334033673422383798814281778102029479,16149820605774446835537612705920133098873928503868848274855310057025837143826,17994206225397988293963936097869072606400130753097128779836685484696065715846,14255641384045583862403050464134422000560975124837558223693835399889249787677,17504545541397972120376845150557483982076571058727369435414053758625774050033,20262964605263856854671661755299361371513888427580858149435552591882491905348,12438123120680430355474353651690582027160630756728481836282192739044572633306,10986893609190710977332579571229244255566870443973548516403950419251545530801,16087745879258651861681909407049342984746351306967389910641236570806978994348,3161560484131968841565856280480697486595651138902139808256180482675228360792,13935262764632300233548760451251751405084774897832419843437366109926436448024,3163708356211087269300587340868486145250960085863061247671736451529273060199,2135858951319828747123196912541413689531634489616050528404576322173340406195,19499372732572987294622585729244698705235805453794292187854255591946466724248,17894089552733756400990786239277662075181623012822588150546768816557117698135,10627476289794518149581909173158184680927686574280550541626159986648732476852,5936760260909841348473330607703047527686233710292277373302498592584078811475,1671632573007285452120449241726645612097503185776127730816609206067570503177,3240964061357526102193296883771275932317464053465161060634703562592821382373,1379991033533041123683674223861213511881534224092884787544607760074673933288,16612309984678362724113323611405699676953754495433780645121123868554119586714,8990362216544353251183644843626621823440172244041771554179888258848070990408,7792126163077137553546721412284336099138469839853005420022151183726709890605,3411642164274869168109174406711447272755835383047387248320765695217678712087,20744964603175609148844959505361532818311810796853446841217756183414690636777,15406348836110379416850862929702053477202461331674247559909297027963274533036,6655070454278595774182716706613320667767771244472415371150701320921454970910,5387596765852619562692588945067153848362301378074547750716364254552830548618,11374645815567953400996409579523063654937913407852397185357281079289695498202,4637259464430266322534397972465849540585061569384580106712860758129812888983,11664424120893756026105365780051433965998344366144921839621845056675798876861,12683173829762047157652990138425355617601406763777942452461639149511855161467,13231456998217432692837253637279353598668867747754119281167569613817285339906,18515103011277984777089818507163076049947207220694092563937098383351447664230,12292599779221056615130747040145001893088895814628302035476053980079114062115,6616224505832681391261988520162269850555430131210843369761179293711760268991,9345928984249349577886491000914566117062182722884874880308419980252230631490,18529045286534814640266328796625676801335117782021569247528965805503339014374,9213994428894984896264727606602499546795637673535140817494171390234365346197,16046191804660661030536723745809610250792224521907784347921533311133924729200,20387305341543872348027149959300247251122586296441271309757521233850527145501,20660888328716295053746457587105952359847177180169600462778173036912653930309,20868619915262427287234582212448052350184310305114553346457821129256743588185,17663781345821195819131504897468846255222386958594579879767055754372925042002,18948627844717262137578097615546021495287533410031083974644721619152121684198,13155646636245265066188794529431453696019006721019099462642586385520674193264,11607002707400435612558884657345015071868104333677950253781252883531031962578,7814494031495579790510272464332992505237344345380518199394208941034262720849,1133679025909186037940532130396250706184367022550359228793807250960294591300,17684405674061959945309711765066024811535672808158415749778270434181980067051,12226477960064982944626820350420332900927073584585614331096659786290796181633,19811925349932047710573270972607617621205677733103349721011497772488325290731,8648978019377605720004678083600719374811142735403518791266825142192290428262,13576053523641184415871793911230224707049224969614290468646557972152185575110,19246597006093201923867388663361027928531131674594730473459152193253618076466,658606426123772934076319360192555383963003130831902899767201848799898493860,17290137813713243852250776166370982880777712118107986170022122607636402519519,5468484217427333109722188824068218191654858622412608074953511216209386470685,21574260030527757195923820887880669668169386788465310192452085714817280961577,16977301410295947721817774534383483730974509825154556215531376468755351549427,15733754299741726976786941703016488589821960074385924955118036049474131193882,673051665852885808394122319132734442090810198084101653348055105938368910407,13398071607416834058601862099131647257306816396251547336997555114713122083633,12550653745423625869263455159672489463891823157792786197798074997479171696837,9401077435832768325771683033269047231487705804464911158715103022642914069963,12470382814922435426465904555965877134678525017061716145587676176477156930917,4934832010550666003820836613445526232712748207490447572633148755378222021432,10147431980198881931337046775655000300780675339813128987464503437796530727819,568707585724749374908018432889236271799675619271430223486579915440515081761,7940313483819289305875198195901580599194224791864182697672727755313391315497,18743990138882019355059105644701125600589318429506940478381096888059645669064,21390103921503672356366200239425679587351838964225860732507169466542370471389,1162301008434626626179696713526875746106593765970497860274277780972785074172,20866648005214775989252883040721823770262915606193206494879341544251201195074,7345491533727875108206436501195735628498565230546589655556895625258093485858,7625514906338569732343456767807169396379912415318224530910677456500209942160,7862757427463847382674463970373593668082249748547169027835585420099101631793,10678296207725321824311910857643347417220081751912275071080081222106552722672,16952109495603736214033791235849594583684019147749856522239399814261672810874,7275820797336428291178396248364001448190236523398157638561627689896470220284,9969981466756203881447261853491208039919719371961809442805550510895150629471,2820683912350770819480104529177445624170795283688064543451455124015297123761,1768227783012842108298280205661549942041342510905211540896799241998425991810,12106377471628405436369258554037168031059303858931832122655790690193581259368,11133684149892568979034305171877692043755100938665306193308979862319584720202,17034299967559262110637856726685484180103963204901371145115468175393665761738,7846191388095544813700988786315012990125413238605101219369138067522789941990,18501907765236851484806470528611625980973567313044760445349490286993727971054,1249778578878632628279160684089277562912849600486367726058714364522238473984,12800296338215947544269523539435530627816725976238738793426232070819346748361,21158276531398412025848449677754681262986399643402199704435277598413275051402,3445704611858969368326297112584817848554583085326694642313172161045347990986,1096936495127696656709715702297708886712481387809916555366077657639639717937,2595620917275871104056107465860277106075411236679259253450463497473275008081,17133880510415980077665570077127522127719512648188691671645676431813033706096,5074434632642876807560017812171878490042102579785821263047865225182212462287,12326838696626858713891707574688276984801973627108664533453869827609207218879,12304708188533179803341734069046800825101691162690698708386871234713091258421,17039317314373515840113235553933676165005713953680758739139458602566292834442,17138392904367957911746841143250516587142345504139102606501472531272348644184,1667176916358419631869035157338470222219117704099667397276080580945958414759,15905657308104601519308683078473840880633544254678278144766436492794698882065,5818790161586099604498469370871887484543304527772047827828829241332373438952,12442306790659206506330372960358262675060765197848150572966156688729178055833,8830924073341698588202301965823165752475570241349344118304602842583809330430,1875325218295968167735653385555759668710537053646457950513379995102733934773,17881009017973237557824378556848686261064176014957336169110006388300690909574,6685909350747636031504999384308339032316756393531361646826148497177153343308,4784523754559868056092042886072700730690109555243230003862073871950864412709,3579228774281988929604104014107948733265891035249209872698544379599035221295,4279085918474431382642565261103862932684902464862097608738233691705350921017,1137759862158982763491809087349360013612105180026300214422560224275715429456,19720837769260646491270657488868445833170057293472427873975392955686128702328,1718964391395646738355239526986888311027176887298320241700031309916500343965,19881985451679395586972172156300827725375888727627109004411614649624414408826,12172287315747539949563617756773178635584674160408496477097950831147264075213,17818348202724817301996509561425729131915819248800408750587580377834731903089,9526094675919376961704973755217702642807170426879590367299173409422751261551,3828510101756167773639196204933352052436416699730184799283196091112205339599,15234684891802383017182920097366274346299756278272648689423306851279308385365,5259340948631483055118623587523845455777103002480150827336361752510452569472,7522204711834833179288206454714805063533565847207420606996829544233502085239,4461024416231372224773966846126492961855795819183621636555920813846035684924,5024379057555899833767820321243484415757741022843259764504133153673503667684,1944348388731771850836911827979470257687115271361319233348322098245989069259,15065306781743278475238637320889039722240861069687500843669623160807616263519,10185565710140214717926900268233420932083773824278146477403635012592608678058,633282989982188437228855410820528038963373266773393154835968536206352769131,15070609296388507673139787908428420573100959040320412658731328587817279331759,21412207865606943642342520185052032190311633739645180935143927525277916223829,7878150466166009547688919693656375135045159152200952621922018706527536944814,21647238538593110963647188691796027858369673773306895927659346354059471769993,499258196791436830394876102694379667868532135110557694409916330175138906869,12884932140229984175244344672594504633237231438569204938753218905028898420879,13897088195397438949124517043146998392030835253375096249186075371152838123957,17292635307267344947001814307009165392877577631472640481991264040854674668918,3402459730835246576414179745580422332982133349475000364518392993042878622965,16196872248846772839551997397431726113069640679308998300903092440097004592538,18016286200009868237596690430345509415593965676022902141045234608328285884800,7857847074246536045428962801424396151797565515320554961976852417962849298458,3893665144753462156875073379241733664547431241880239458489799597153819411492,13248007323269384117634056450668957554780628822533632623855150478480951625390,18276875079677833610517929467816562761552054119550676368999897123627796943528,5189710327122023109841696471286837143455102090557692433286249568240177726287,7945689534444199447942235389147404638251522098536584100372965245456120158597,5423767002711680999240727030908088708424949959926318146878189397264151455693,5995072902526586585223000514086044396450113354893476089124870631086600489121,15275396095782853076485751600594247065910139735226081476243182046971110416839,7337085477458019807945256166142271568824298087615645600806448794391563720590,672727225441339286039441508031715798485173015033624765579287288711179551652,18686118639158601820164163991883068337953517102808111440802394108699280438488,14028695600256037576881239065837481650658243799767033132853744776667874365505,58443191205451688703601063117164997697541381759347793811443271650169777861,21065693836733911343227308560913091721048742432913504195640605496691788221566,330731975523362608415899785414131718097488715216703281999950906065685546389,16761217887229483694018038191674783405871691887163059178481478503168342732832,3038029821773816605245101973977979223409779873144308602734440877027458504742,15321291577034359343843366677170820527712726038561116015047816977743924220386,13707411308735348097061010267850476217721836580681738128758120478182032058809,17436870236156178819421588659602200365388268058796067042132167176029472760360,6398050943215095842335686342334715469621392080870897191300696782676608765887,3437851705781701539278760214561262405409371984542409183492392158766597659391,7124479506211457523573057217353911508610466081033238660465711588737967142974,17234798882124088040334413616145917195326697085511927239835381731514314303940,7189678840883577982600011373449005624085144056595391210996212544957416984457,11759897219791977703855743039753523539327151517291958119140418872939095386327,20863399992661754827674386311991156323060622036945800022666816987897813665853,19303856056826570957071409328135004293560711503205766767776395391371667771674,20145537319102686898024411390314804436660254524742986363357188082440068405993,10703774427752668974576334932100051927133058205544953271144849898179475571339,18572949224433194996605971200517412011627412770605201537755920772491000856992,17216568647787248412779004183002114283399247525457054305327730013550616639101,1149230406252660804924057240581611320485721839789360487426995484240018883527,16555038770640675528229594153638806495397639088923421322231578669556920716448,4570242682115771574920314226681534421057130734296724983202350760375592356599,17057311432878064305365984063315754288324488570316135529616408791432610322138,10528094520692277398437810246572829940408932590689365643375030258637643836256,18372709972473962897678516007961361205643396632377488479769034609756086158014,21838679058944462510227588871439974934573578287277780576996692447397949481484,1580935194501439869947304184720525369376830253681649968786933642354687903995,20467445367185359735288490209436765649401864859115524728703996670394981839178,1991219687938782033642326751499030593324853839359574632972633310438247709458,1439755133435743273361732699887115117694558270034210455263872898360142260289,16300147327505011303454000556020917254890545519131742846543658162285928042977,20520490665047234670156871323008670381517271529350180242819417364083994994438,6542862810250661443960454367170533117465189617181697143331232138215407738369,1321343667823388542880641322895423041177577518845790583045290901719235409147,2442599361719607622459103501177302579953568947914600055748918886479950617614,5868547468478431065596263697373807107429411676393246849408309043501871198941,12236312006031079186182743334640941452854376343312535021115608217162266564748,10096437059927455034494932369876021874913717336999122002472353603141122745838,16855287129299048285700210681474924546365514190517193678115189183373112094664,11157210691115027557284750949314979990011151769293562411757900634452166569473,12647512288244490046752876853167515938997386483355090398954955982145642073003,14545106158760908532417185649648478400561191409850112377631214176889261943702,13380884028176250201501329354617948687842379239413597035170382200236519084210,1405533288610146305353614064658402594063683037599662723217460924638972391780,12520645345847038927033831419634817247041895425958103228961545058464030447700,5466316270148149873459535347452815877745317540692907701390798166221830387727,5692512917835452114275964699861010134159019192212203758647174343214228494998,20406430429993275527714460195190469680616300984772360022156779114506307005915,2464398587529067351284637471629204475741470377175139272463319164375422871700,14514168707742420576792107362849792246555009352726620152895701096554575857830,13270866810108509432782712956020266539382253503195894711776480924657007904548,9134846497886036320932877977667565061646780167819704730891157458029677347762,6968315929580902986583144026090679082271496835598861747834541738159673277903,7271494204378938515839411341192945686765403888626619615653078042877068436796,18286507248612017881101512297381359645934672218434256889911439358758424747545,11110097749119198784554144689049124335810208369471373426127558546444086832925,8247301320031025187145317669710241636727060646792731418249820159438470005156,14294937643948997192288252800043984341826315689719836039426003941357321500134,7348709417616598268612977306891011618520420209855159927526151677200518293152,8241665213979757536094384437357490949853796937135356315008833005380426051194,14613486093064180194908604682667542845871833534699460114586605109597063839130,9113009852475701814533040575255279924173382591876828814441237692300104301457,13165038554179369948431676356672208670169443113631826535771459184335356285593,16086269628133108266869931705626389777530735876369884384351431845165268738278,6087260580031589238539099192443153008156470383537608551794229727048294996340,20512862830064709642749702619534843169107182362836772285105007708471619038567,19533181397104762456673826441378799870077181112746023293729567449839481548356,14705683451830296925170674619865205995188883759493716060771015969186134607704,12605792817445608495860292975716815181045267213200470818664710066347176280047,3592996587655107072245474938139935892949344064921754274126873928977701118749,15294232235999070733030126460937359944041996136808334336982336855120910512334,1582309023481075306597300823293668340335902140969083485284345214470852671798,1088465469116422019323930771299807477223547422484605269302564104323452973509,8883047416031049757538663266985855517015256170002963846635310997205392683864,3176854208559033403336658900147847127925792493324423188639056424099958393072,13232382305984866276823393930594443402152224642505744090163285056748376747918,2245408257366834949733190872330311995971080118654860159924241594642495281059,2379830947280597194685159865267943843813010731722978284837340564719341924509,17826177593330561305441136255554046830158210141415356927118963102466292013052,8247294876117518524724460400399686295737179004092227538368916244669417581296,9784484010004736296495309204028701732510703011300894445280176432324640320289,5252332428538395620048044694806285484695976570037776918613895482295008833982,14121980677685920870338206469007772221567007585360563336746921691628879549127,6873280017888024918917070095341125311616790755139638467124027157089622101088,11318363160576645628856748485098328456894971803038601852118504122294284627221,4121152361595345093207401693369225144531013563993157593094962034269624651820,20683333802753484511610127216996129924370396812165897253170891149253939360760,18647670031404843711327708343249425853609227031502475411522973225042672187860,2086657429367670063332013344180770222302417569271803215009583482264097874504,19709435480590614483363007409253356879041585154641286906159427713982563792526,4258866914660942354120395242129829740747833749509017072799985182732656616800,9040566395371463976833369354842616182669127821598268274888838547664814843928,4116084355554837400529216189356527577376881089426150781634827262283154963048,21605169971906188704396331617487188526616554159276096155817564565239435978416,17937211187232154582564924643486965895957558838414375726168318393094228123633,1992558685702604567028071709121593075020313087150274357559040691997376317338,3218330818271934662263059558699096796852863135305095433439395639068666897513,9251019796910681440348368762961435892628247766190360978557679196269677702320,15836693249656382763970061319175857247542072239256868703809948219144542014793,15037961154776922819548802422798270596812938540093547487192133997609110330498,2832985667948889103643595801116542064299718867280064733138075131374461684249,17231308893316371049725716015653771498326104062757761825930828499226120649063,18440767123713815329857061224743112764715289422724359826699690594664366648275,19107308066370859685275861140608997220650596581264375407813390731366162034891,5404929079073337935336499214267301362161341750373615311934457105389796446473,20619481508117738469430272904911772560595466539395055218439600469328451867796,13952701312362872281963137538185820474584748980975982879243876933687953690941,249746714007340023576169446261897246896602417046451816160506088486861113993,2031064645897563637919423800257706696891919492795925079196751344512608989440,11565396752616415432819810596660051755078386394477458037668058318114060397110,986400357247356567494096182209394879745469890962659581282966363140769490357,4537710479751915891784323654735525989928281714716787626598475607721311119956,6473679789570545843051971615499250002895246840329033388322918048865214899581,9663160517547239942952324390296932496372339501369452594336052141919689254511,5816463053578002459222339447164819661176549623835281810359748779077848682107,15884891878740533639319804312855499125304552172182333174674400304788572220390,3033403576169643300191876532878569681892028128211422158671974606431741064057,10358010399523377550281291332476224381854765291561168350961812145251103430188,5609119676745360689177377631509255444635743595725402489628064332010648311979,9629834817212476647292649072966526100818069994746003213667948679343174132340,9902671572518009781416980720459757101464549561371827438607346753254097417791,7861900468190840021147507239605680877304969442537895993247780719118539599806,17965713539282108900380748546130491121922627970953515439952089259237956451418,11875127160859896409551848475414052588524539216162668112975117611722753563101,12036060586969767703747823124372554748937989587973573397651022172958180951726,9687479700009208904244134411901361698716242095445472067017865326177763818896,9417881715546662771138833677126201059337478279387740105578558474324645551658,1453393784429512178361095160478955627301424316545464923297558140633602643591,3605661850144345838926820161654200172773665263094741288943401786929181563752,9633343945573595088617177094944240138296472849064303543706399640795820973418,12473139325003262775761026452954333162901791070446569863302424457084077761149,12050383798910643577317544771125034193641466979797280393384224161250051391008,10819280347517551331483926007074671789351833709996171469616831904311265033949,13165812145639084020184122275986846677464323294523670942848342958951658208097,4349080070868874275277456883424617452669491031060808106496345174056753179120,10004465749978899491390807601888552616948704671794075232666191099858337042324,5250553500845345497570122559573167112673420661316457421274200097450990672373,12898588403041862218453963458103462644872308284833558427909835998108927951654,18081519381738296094081786403175972446703155704846706982096034153576188388497,17428269008435424731165207394539747495252057789950545989706433801022598432683,21363561515458498091299721959548254375350819182606817501876503845082368630248,7730068437198222255038306872157350083702057866362961468917603557490811496832,804393402354592729694369925125379986785009558185994901175413585942989446396,5734375191529745066389276413443500729878560514347145222515433157787509440061,12298550311942812907291709877922367696701304981384797706564000787234950045527,11599955784759432052811066625229516027776562566066732630526030964712154732575,19052852164576098666742966317699449063762547007283635113650074658720294958279,10025188726400272980943623464270412609902684461295237328964275116870569460545,6716809200457040320003933672999684025455855713745782618771058247491604111902,13265049252191301811995103374452481986951626617983097109447548540667223415855,3243273032455921996687884516398249181181318053856384035604616213401999420878,17596345835810824358133183122550505795231799288513594802190425260560699653345,14128892069525759858946235743223382009747348980906404699362919849705747120829,13560912558482649403704338887070267536467549681310240991684055262800855969142,5146650134021051734120451478394931677954544403196703024645198760974236051136,3656624380537215154312224820978463973302627823287220718508509926228536255064,17192240779422792861455260231600955507004716950247796731699861536149977973585,14505892053752720060006987522044578502315422621292564446333307406645448977523,897766293354199284998764120885006378362273185992111179631631299334090746025,9385522526111341509707107108914634969549440746118599228963287393277576591675,16755551931355332730912571473383446100229118084434859591641172409884703288623,7998487350537565460407312493288045720319128967533762889043801066609578748620,7253071994474199371350196978282275858691584350754099653147319975858840509065,1574915908528094850594155669399292110958198100218448518346743116412237429711,4964033462714392747475438670479181630637512997723146160177292638427948047795,448448106178274062085484969210407935775566171618153143848162702130236340948,10632678501409460480908899293916037077432376165397750836428181066894132950422,6560185425582299240893314836102079088239101938875583740502225690151903320396,1579188680045650467520863974543764324416915154559115370865175124462148613819,7512915739904886375944428372792517861202973027020854741625268080946313568103,11437215569201917203849322845056384272839597879584906569042314064918170663914,12242031850346916661228168797937142001106743366886274501414812437377823138597,20754147834828558255955521879849243373047193258439455093561468286224927742847,8071694345199003059727834592733443749021397716021823212294503054151589204390,20008195907609188950845942022048531038227320303695709133926612651814670959266,3407176450804539102225412244906714437508697739163709736953739213204054495282,7164733851792769372626784323196646242013517015794517414070184073240948375536,9905209321913745841790507726277960404981926942651589731149669818541827874214,6005284264922151317117707687482989323446281090296110762814732182741632133904,3429846891758468105169655789950721158959212737421209807144772069541192906919,8594924739933231799186811828034272621585362372014000894229076451226180774305,11871888849049325223331295756953912508046243621607006393548707001434995954238,5685905463286653736673250214945816154927032180553041236977187605699044205816,213743477607202689216486321834878291503247072102535716407202454507834205331,12562677380228777117621213265298559705423375836884092254836487933903100167894,8185089847800873546122723865396073717154949803733075710451409261160174437901,6833793650798095878312843740119765700866687688998823144083128641706792979819,4953313804596399497426456604424338320630850621290040554640752190475708172557,2236942430605502498740725704270029328474562664606378240692747298661887827319,1513449164658866312019182303051862147479160906256039744485216368678117608853,20317977663255757433651259494490740600408545133225161089258307793180016743554,2805473554735433677734689688066817081805362311169954998301659824970436339447,15815182380045621180846286591593553907538664337286124104922652024183257765519,8995040978147557956715534525198883385024370476405764975921649687446895470970,8204191497925877512228406532110351579276808609895204619986274589454615200331,9804350573365946552974871840565664742492437387015600083520724662514547605734,2670072936416198613788578252423721270352613415834375050844481006480844299140,18981033918047008332984286244333212532097768099085053122971946780791175897494,12954085820551020895974547504930170442441222377530978192526624489157895091072,9097838829535778653934125096834099047122481765699682650259018742771271485024,7412500154264631610614836174268215158855286123479543445207793653417339063427,4570719057023209933442917712353770885061956176422382707340131424665352082829,3764270938841013974016907794451240962927342721628880682930414663597308799660,3003259409352957401069823305356475477293574843963128589242837442372343327078,4364045643562272249326662669199826714126432097046293502341074915354885207241,7862497546139280137858115009924456872495405978857024048016201451567691552233,2320345330709275050815413684718297588549014329479521210951823856644277128291,3472052133118830373581093491758594658278444460214482406644025496494813391646,18719780395522132269892764976785744172160001291971824246311191396996341879998,2052034405003094013719516407189467871257070713148889132320853589752948812286,12668293034393175159240347623878811740389002104040561234210863028172486003814,3030226117016103704707119677479690730613220303512226016348578882444095217375,10328007796868265401669271360208572151985515933147061282836598786351719442924,2936234154384973501504058165728446155253408008794108135203900159696674018692,488196422923618399001126311361138933209773385094782255292621218871598725659,9986243106324062707533627601692123931503570667062976466271294044444369357821,16946417777163299571223971859384083494444080413698624920773661721819621003999,6290655646787769345150128237305014645896272983703662862175950979175390099996,21576354856650767064171440939276202866931509433119578951322323205119147402280,12396222895516500136715256668686614381644469516081823538030375243855459590807,18323538829312240204982678233417444895412920429922269434090001873145951634449,5312977696789603985280968610327711512128871567270265803635161870118441769141,1256303934933114233929368123369287749699533819478400217199836088113619997588,1766722289253438664291189751442574085464717822269757100835532731400395828058,20358149792139162776765514570327167438522971057031059964363017830738523560815,18792275959974477341072288096653531684536236050557537981692565367846354045353,11262334644528432796511003492639130680887823443747110676752140224527884546026,20501847923202184923710061886495102946632889060597711856226126913397710337656,2407267120907499137598716355969720653158717479075795831021615986085480804669,17307860167097742136268530831561503531461792239855909861554172148017416960805,2162289869674344221546800054490037354766673860343307342595970088710829183154,7028199420603561050998184473139307688291589649001033510888359073812068249126,20994672525924208572413211399438489393060949253402639946739540459305617910138,20173431861606460093483867873896693022082731481398426039971589468498814864556,9008871249428555602906292660739315591043104408371562099899839775533895523948,10700805877647067083283505504782153003756758200729717834117016178491024406477,21112465741764258732843126921665151348166174697732269978267747373163853108430,11434984188666323224207642407059759324684918143122828248101482207244887988138,19774670032646206729857931401475084640123741797887602999266543966674579660422,674655537444683637096570248236990032160746930820910298495859277351312061534,12399952541366504233794506479162333424641228812125959815028858786807335765308,10787188444435222346993386033929793480957373636649543232735691292731739491178,8444484958726309128422673453859105535823575309761203789528942642797742183861,6178443234860827296437957284319327879259579261423150811121652495400576061977,9312686778448920745396192252021125483491892057300805307510293202738266404216,21035346041382930907137468070148126300607151584874513632902588011146411628958,21595380874048139145422335028184290720358814546434544789176692636485866078352,18101046998013962303174610041325057852573934184601619434223015638490343790989,19667939085949665955991312921627801957163412888505151951175612729243786613781,6926779782333484660471017512018931263032231687078574887001518725808608895509,21080823663408874605869582733040113428551737099016002655485931862299065393278,3655825253274650356501864672127621389343134570773587805971056417535174536245,3388541056162402337902270805874665052329588330241925030058121260891155159271,21883983703980930327495083710303031860831358299523823198355219501906879066592,6926045735792789706902681099796161456533517354066439495586980016226331896111,4122959111197116982155867189740721062669675590322734927703841118527609239459,13219980757163558837707442934888299444190968070207889541780648207183773341011,13812897721847878024718349018307386755424010495939938584588468146497630813114,12798580293550179822728288481477643428051047081525754174406779865733869649777,19217125674525037886170888487423869066614323854468572412518413433041373346147,375553361556668826677041847695421482571990138873344010326810282960129792132,10834658340690112017927173678735250754641576226700757836412274044036729618775,4000963705080416713341998395751411942820883040862140582570351568343523301185,11715758996898666999645486245570559500678491132871745818362150491793495427655,4263507095725155156517595569654198316584673531155392198157637482244808941446,328008196666170836733724513867841384647787752809351062335576481522598738696,16052279110256413457891846976681654137774297241350913171330588402386482933504,8560435921497695081829647680343824474942212198090196568605135998993570233835,18716362840678189592322462186141719951790452060116008532478803871048621361376,6373296854260461347237798330630093524006414867838125038061282895929391886849,18914705717475623119982002205679946947799155688028604423250694242332863378659,3615848956195277523544974986464432491666056752600413462508649484050878259586,14319383609652049721947038362087013158818175249064317958973877909037224815373,16735322269478335929131611670089342135588205793924787907856943392431725411629,20487989084414161462431324456040544956671737924589348832484117290264531005303,991404779256099913569561460005735823176831315250109345694197087497778707447,12403152875035099961283368388852584749460932263482397452647736730447907363221,4086427505181709923565832636992346270489207870131792488930389136658523450334,6143243951533181757415269381412864770996360748004903845141664179532399602512,866706669878257575355607694505677029531447447184317717274975559227499614511,5892914572161311963309388543417806910338156401784367910536431408323821746054,17195629524346618476376551682847818577110341498528926796026110967915240955181,11821298882555096497181913149211502245650586243756443688232286290083613236253,9353931901221302781036617146700068445151424017933715326811471823048576997254,287161824097962028466164990607592105232453331778514498980389789122436840050,10649681231914156546306210447083574697745999931000675911245824305402757632471,234428462053245029707379734508145490630528735544251100489484083890623632434,18386986463595680658295944092336172488193344109864388929828691162200829447922,12209205038092046905635371865560616384451716418834791040178049545643031921053,14186020280018069417447809370772570171911004194015095921511996859327548729773,18113938321789369780471778880758786581581161378582151974602552514969078582931,4811662992940356526245596671631791612493389462608103550402208802794345444140,20758900083194181903559645045132621401748979651195063688583538188953422299252,9153554145073302417837255133650907646404668180089275208960151746312542076673,9140083548410620433186361969381763393513996980985547052071730395844456832878,1995008884754637182207447536267941537231422109677541855619755654197330974956,20815985241080261061330547616924867409496454481048128927799047536950736307626,3230373257763661238115338374579765087994728137593244037768237534083906441753,15848607284344292541615961379571084541204910796797596203678379270219514113553,10428395164296448020881569101995272889447042680020183589472054992027224827786,13680122146242354024351667942887798315658431983426300974494489056276061013513,4339724378247845795006138666633339576672603219988412146454211158778911139049,16957453138566211779676251195537106997166365265767483860476580167187603818641,6903442910536492004022094150099887848831560470459811862902118892324229883825,13517533794136732881120013247194703467846939834067648417739110803619549581956,8573259981507024845652388913624603863752296398651459450944134507080250987145,7184725885552680253794089893559736740786331382981862187745268057810849566021,7444911651670419666243138241908768267984541319117854062859415506699726860996,11938251205745649282918409002562222384447298563524098642560439931062370036028,18732676061737136378462265890132297759828778436681433094170064283098167411411,8846532794008556689131513011423108042165045871690949838768507118557843169852,18388218263536244281946085549244925864711296342518046885707040924859244937400,17560203902531872086160045342305935339585392467343746359739902020514592872929,13543101793457457855715055504451796018964110256417682942067062541530681224758,12729201216656193290459172785293440324005383463664790973551946761644249872265,20749632282565878390585307142178974866932241415051524225408429188255209021839,2939350463247023543160206627078350892997171197177918468376868549940855641486,479410521971742071578523736929989300479738063431591906751176641695551615616,1215960229051771956876212387168875875104433482328478370485649365955599472636,7395834689442865088318136274271999810879214824816761763663704696957588580019,3437039086902274758103248708959011309309143141844585728091733160570479897488,17467540498235313026126845934481902834360708027699640261573503748997917041831,8422995023428881457749354920047230520807267797593122026229940569066728153312,11738236614524316047928272298201726059224571806912522830504677268234776263625,12990187369429149609670218646295887927962536468837638994349699374218402630706,21623781561819578622543358003640431769369503776252057790027825149203611468091,5669501143149367774701636329186878874504568114693026656335516415399035236206,4575509333922357841125659935390034260822150782714631158836599383911958256934,6033679984514005206127292322842556662338038222728990090780027736088500900555,20960588060390074988596726655693601209728221976889320157850211914560680389602,13413928900186225435324599444732846219399870995843202836070995363431243049194,9234295907731818534748337816708817747432963728163044189490249482655118848141,8555123146188721627588124037374319613226378704908045460846666824116325453744,15273216586585654487893582395632825165015207795457148545076967758704213266502,11125068324382272646583837096728304098536045737064996999867399544054690011336,14959670405320615939216519873622952189488168539376564485090492806106125094875,2609137341445825321095931245531863029306734693698914386115461720635228617677,18022833118482437226280994646426462585862398739142688151319660825030833751162,10525185277608968809171389414591123336341871721390818817629448578893073864965,6744998464824276672348708743166802119889279164929133576466782672127996471038,9344118411856392638882345685982595534877291739896163576786468663773481537247,5834845743289993456669132331911158234826336724070643002101495844260807919180,640787484559876348086629339096900566749702582335998287167888457763777550412,3289778183958313592191132419001427890244410850048418852950969831934946260405,21884067909485911557708530514125998779898644250629017666973972309955096019929,12413233158576537989326032313779399359311922621054801366572548255508592334846,19326971287642001797155516864971431422568657490079056599164481456075851978783,9713216558784550226779073929454993288918740379425900055346553812422457613427,18939709206067618242082635502394826733708666259540151764313557087718564592235,16287201832008230557120811959387085081039691924582377369304872636500446900292,5278016450516276499641394140854299047658079220708153291463991663971826612725,8340962164398516487176161966485950102648589482540787401234013926762930809122,2189360335587469104898894044890322510567148239646828290042687811234738731248,3449789621053765306024986494635371148296184209757783340117745997173900013891,9143283285825049929933624722851126967075894848265558258882809634241528781890,1762589836333836268173539283261821177424666871790048223025892425442664744623,14999716003380172870846520006929664713498492291151583767005426828389694408867,6657396937759865997077915983426704746176142403322137472681086594905173286297,15931240944401174032343453067874387364523175128749141502399457399279513999466,1093656103569127166341414994548826968375416499363412936873802336598768367672,15311996490740753142335607256171022029850671542830487572556180935394970969084,2114569000427676164059607854200438792707180857430926937778356703166016436297,20765151929972334364703309580474623940346949760797265180189525857343032900699,15086899750477019230037863517768898777026828694611906648102458179274814888575,11989598054307650119711820896035556261218721126425285775266572489599541225098,9091334194223602201291135947382348087276953920280768131063598550602333641673,662205156672119277592919023943339579805630811299947870362049797370818219037,1644010308269285824046398201622466330980474102922491226041283891094107089659,10802230809760799055453358968022894649048726749105153336410430294944584338077,10002812375469387387638524822236342839480428168589080127597945114460807065506,19156323136144190554785957482371465262949638224644638616894263767724257422262,17733486484176040486420248003268701811107138651833773383126692059485133299226,11591816707957137858747879818244290349664729458236317322129399152472444934827,13438697403526660565724658068461816155647612966569784134628157461074851140504,13266011411738324637226437761946084145971285033245245813436082422574964132769,19496324867803620550902836425197207665281935127556215366411961309085032313784,17828723725738030742535695874826508863700363541225603578112437608777873288872,1354878734330830246945810749621035198088901780682128075198035721915088394677,14191386869116296861827703975696048379271311137936832987484810982707013486938,19738102036337682966068176606232821315534061860926048846327720022609950683611,10125898950023999329674512710082674945903794489998271114320266993547905724563,9735132529803303628278600229677357854336331158152745512812889827254017680646,11236813353178034372164750145200156935906967316633703292491531523808184114591,2838710343346183231321901296981007702601287106254090132583144723338172491341,2260966150439461282635555159610786965904582998424984888756770014321125334804,16205138689269860259863339330838066928731455712034665818609854024821608206800,14474351689504859217283250911440109599364797953678136799363008066531050767071,6800897037717406782446195419208951974623496109363697062923841346454038837657,12439223794583479313810611548866683769924970108158641553689074442900057207206,13368632268650760591616092601174213792332738038582508245973036690611922918115,13045024155077800673372198196114071407850396125448182263497388710529843778012,15909614634449771616261546064207953846549526793661176217246033322484959782377,6286523689254946058242241932237494136885909209872547435875613686442878101066,1349982286621373054175291479185807897612755726394394337821103602455947583575,1790249021131563196559147247422502568900570496057134946620667686190353467913,6402193114585552816271289059052503078472437339555969654050634927290142355144,16657876151292774412640987426284773353540623435906797018927318161786869839630,9323926757990898215781025566456682055829536111985821344881754566754550287464,333557759600743416321063171376142987411973146341256173569676328325670137868,2979415176549537735678518951412460315394554685744871595392830851604961695296,11399925948142490745007741431204138659570087052831458877959853228053991616097,17621136800256980786736718847997675507300992679800923101555538476888606832414,19796186386112600298425768110232392434623500274218805673491160537841238382774,6150633696896276954724869550196553826388538976047912638783098883173888551921,8007744165470722314410652720217502653722691054745133622163922368886561184511,9311054107030040402449841855464250035701299963653145080544526434268446648883,17483374709267556993216232945834980676370211318754373298278341962960548363667,10342541634151745634549333576310088998125069092773405335947539258498170319639,2491113909032842407846736301373377587232014330531326042787834409966784029431,2868273648562988738033854616949524236294200717479306399357880720258598168313,10742331131465347969746591645056052543770202432577403033214021867405353469410,11262784136416067912059431910504651513874071545823747299137490135956765416093,1202953198131460912225596542947265149450470358249744433218140619832526467659,1357188592392022798249752911997083133072840552839921198518049365021930318735,6860322969159072475760401518666168198209741930191210869338776131213742985903,17512830541972446751364043570597924188477065675882039340228337890464360413831,11068769874220100931580712510878176008480346856568608049014134908792656846759,174592415638141512586004221919684850728269107225502531102930877822615095893,4529660791853304207880649392489892958123653811385478713812028357153062637877,7261086657925858393339848092042570053113017792782297779091045392687309229931,15947797860109427499686809495296483548232719158897790339724183452147879327839,20792174987130011436800220305375988411204569143955960269071283382992617027310,16004359657196683674112642475201997234099915262640166308760622340887283269558,3052232100533123772344258509339894427157169209304015026294337193048877370052,6932731371388662052904698619255543785138918159081404052613363170137706724722,18786344120940971245053939784556033915582618306965577644860589607674568931598,5543910602266336221969634219610367731229996706190750207556121552771043245699,21500331075127237626915881392062922706776178350223005349901601754581763355631,1647168321391235121087005294677186408057439085818209785557656918589059596681,18530920602212288118571329897791681729275409540471839847360270409798512800049,4854705606288041012191490612688235100018679131692705525031856778474580243436,14030500314224264714821884320124695887543721243139555484376859209010937666224,2929002685096227153223014766825090983318157894872369622190343561822695490151,19571082362460435625048830465870659122288859631947561605202388130763965600724,16262018111979731901324396497332329657354718141076944178560644525915310954979,16511368307044025445048172352133100276074403358941934299584092446434550554652,753252068911531248849891296487019536968643055711963719939888051839316478907,4925743538740679971454033971243400511986874154138434310761553437631037517931,6674573928014195188134308196945556256425786164998594495377003561132663149662,12252972387729677079741673273643386252988421977551152663330085764982570989423,8132942533382570630447992711549276375854208836400139615573300103975003948893,1767955113430187982507552626731364143386403228830412651051530991601802225661,15911785581735751807295094148896874484829666426702209837871379520505512480322,8457495441274725464495320737396221038491121993793647195771335087939175598066,4450592062983808718489321963811761580153883581981811699755824744572598554379,17594374172823696288546149573800906143533062920680825959471396256808502015697,5396987646216038506498234734744679865090292329649749592797349235509038812800,21252439428941443609961710022512211297072223091751149596182317370399721579385,18205060096578922655953660066798909616473486532390705801648322522122587090830,18335844957174152986460129513698965339432209604680688295392195893700811299508,2642745947776207344581721189041440984169021288344823913353017838424039626428,12274412791221963394261975707650556785293993588861677826296117405653175236519,9027620387743934195363518529726678172699541005293960006772332651314467807053,447942484646789701542537528994314353531710489288574350580201677777950035282,8057692910194936390243001022339132476522458573171096947792809940102911406995,12466422220613642034159029765007116066052620609909566451840020754182208020143,1171876794208841082635913903308771131102729703148972430947313152931064171577,2996001803829960955342682545650059577915377668754838044698518610136674338212,12306305078198172670943701974214620978597606399214937108559926306737496310941,1710451046983264379967941386456520655992388623198157754427123889803480356000,17294040628260706127805165314917539522165501484257724022309899345383198007240,14850723644587717617416204055806811021029607124589054329504158261611106696194,8626653016235921835569469801636971931942277275560421125462026339476626883966,16134665167778000757091607171765139146858141948472867080489695707419285323252,11129502792062576191937938132554397380912998297589916298721102071015359559556,15130530042530114554524440015929780266039077867502338045121803478767735700077,5922013411157909464044985892976718792018167710191222879749916950629215559119,15641877241146443425426298971354708474362723075989298367558100488623078084763,19807467678520679976886734556492012503982987205100734773481397135264223200444,7230620319188569738319728589376800438996515892335609872222230868954870926930,18168775389925542038768548563310374943094173375522704828602237046711660513509,15879478673208122828337915995586151196586860000621630078538789187695874266640,6026559623764003366786032824563693874782053604114144074018595121889075259493,6581629708588609217727738860658907189729022916858514019350636298557029783381,4392179832866307866014828901921327571555384668846640428849164693147430204259,4039689077078382209094762982217352133778072152116592303105622250221872775182,9439756845261909878224812875899975078023923372686432160229876632562036997401,6300039613750170323909974701574854925454386098696929245502563775636617169329,10245787402060152709811414110506095522941754087902005711632016024561712242938,10770509446150307821311775909967816156602102352374955635502734154581919715219,4445806424060983011786548514585153091691541530320683355086806781784085761841,10891448460108394317032887254041302638257759566726100966329794645560947944086,9055121436695773704587898653339600198373789357537888127317084878411452883579,8149630563292186659644235715307853879418282762593116603286751824944805128957,10164520096412584664920364217937374178249615925628067827666302990156368241543,18787580258401627795053641123916277779446570183960070225650619813208411270515,5840281460603743032409236132633000232507414411373674275076564056089047616513,1156412247030909285380152844453068577291565904060426536020772600017567322066,13125262001118293895463954353229315406286474760130294037415093324929424537303,19341994820951858136925352932235917695982462478372266716377719180643995594202,14230192493251599368583155353256194379698225636722091587422432258409725791125,18604655597949661495485553681980778009433340166469812699886221824297364988905,9484517765495232191823212744512718095318306206191891691619884709082351623103,20661548256453489016691122417433244991048818711049327729621550642733467464794,17946084952153038878596350204495193827996043096722462577062358769356218083033,9008616567490400741620365097652579204686050477332773331876377443733844010527,11222501299614818564801113661500553859475257082250633539503337648966645140931,17547881514301195137575407746474668605213387222566272868597007270413523256918,5795058045621081034219295632641782062332989904715400020698296776847639194943,10503000549984486673912349445691696940798628902104169170719393589667267164117,20627605141977035823281920467011832985049476688278934213570130229801586759490,1617802179061215386952772461423280627948056362689193604176834379576303877113,6791812933391289387114968397366223795809410677008110102514189342693442788856,21469327667867855439208525645169470185070216384607993883382520539336879692857,6209704596259199225388050030516880246912805490686902979517644524792187929012,15048235302521180373501889249113906037936587642496276368753413449431797081949,18778185090591194140890220889049934755279881763207537060835789721322305845157,4164373610491096709440557803327678927854304626112734913682240155408254130319,6352957909818668217728163741226734988658723962520906766539822539894434836600,2081726858060934846688892186400729209835095311388667168398290314717411097500,18997085104017244551079822479039381301947270057658366559839643454880390097993,15381301300391534710642382148869618456973733474322247178000572705046719371489,4198258606721523455517040976251319538290332464337310822593109666080121166366,7557782631251063800473816565466881793101085796415715068491278248627266080710,18931480224318877255548108668163955495398356426693160573742850933557366286581,14006438920977933743471268674953904657230294434994593269165676508225740552815,10552613214353127913757671512246056403297131067811718291694487016254806821431,6942360360107439367031353171424554084301681329082198856946152988574077265518,4821893567676204037011511732637248253220700045205121424698817536976139720741,8570797921121743873772790445200803600261480452613730673514117912909339929304,10210191620579364785116101817818502747961980686320008627354511305745123505207,2219514545666614569412405614553938185242666345781569909039944438048257115280,9472494948236350938478699115530847822498160599193967472596054792264811505177,1966000492511706985369338139654568276174679894528461227404736596640963023833,20046698515808110863133254224236843582890061845803004799852246848232152965906,844879645041461183539563036099295737132271525297913466134251805988318847548,4731835924119595590183070349774829521463227171971888362743688018910258502055,6665591397442095781758927683212527568272080607916992672135848576259567872049,12479020936095094085154050050726399793348028251321297846621658033596298393726,13547094394131143768607425506026982562580191167096570425566382504500825930959,14726791597032654225590630927699963688874228760066722543952181168729825328904,16458751398904781219324882164741165137205147400663608606201428995139003250837,1382702744652547575130131869708589984736039127219433507919721371542416805658,14166947289061517490924648855242003709961143010494793848406604325534604905674,17345393385322406098467895186375277399629828208438881931258894959842597584446,12612093274589904544460621781003810044552285394822234432357810635329000095532,2278721075910399058699498270814807833560549835812826924195171790394865401759,1421362911034706266530649492401610048326109063529762443419685870164992649589,20384150845787594899080953437004222732830782572958598551146508153682280572403,3495056095843097816017033529053032886550694720911641681721955773137850234745,14487246717687560703169821216097612442592434246076605506691782211475316706576,13114661974362015466065924612631881453272278776220284208159815065535423486323,9628837478322926908639029641093928246719582225562091179037197080152788423316,16456984127855989467975376775709400558526389914848937751741445859284106536098,19656266549615253685970702218272816322599871270060998775752454696892588799707,16028536897482325114555541492282064621526855756620164892739323385311597784598,11146275353887579825261271116625263398084632057838305651534583557054398181584,1266798071261939757558459653520435752781168817699931045808536221140555755937,11242956579746912399423902926753108012060763899073974272480062541403588053076,14588608018127887593991920960165305144719061971763947578582110087376128309227,5393054051309402705329828859286427425185515439646193479342950065083063200985,18307950351265411595229078848795494559405008993794506472277342386767679169011,743926999062879465491123202608691059211244131659206478586545917792531513741,11450449580887323007201214040662031298427088361641716342102428346626191862079,8918057399138776974775397421552812822591030597414174436378830421562569121660,14007657148016840281780221954150751472316590653604019267269105557294795817454,8897431240575139049076571283304115052162507033543918057893215164198174868677,17409416377040437657574990618884772475255396933561856228823381810258648281132,16403607054571283311114350132750182990388190855449188101005849970173367695642,1508877263063909922036861471040526805004287450733006660015588614987220564178,2405929790914208591765690668430163058227989428739435027301989746453297508008,18415257845847977290620817418058909465150962144437291827522053905306094819516,20783625745588167215135121578855692267545194811392233146323762172638833678083,12583735518159929222168953087285648797218797099708802919538903595273472024870,15030113532753402263141105846533650021837620483920708638977418255212037916690,2044646201923266135898414814098969242685760821863709223961924291978394037140,9562505824238493762747890608580676752653265912034931437600706699047478680911,8576622443481230638247834729157921300954369512398151853927361194153863723577,13502467573105057302451195240442043465889307076796874707692282952243564124313,8659508751425384756294968991737225118186991099981336883558347987313410663071,992836427155144083079734949008912409782777055146977880211513548288277680936,14478698156814197173486553402886358323315401752422792440407576984439553283243,20204662700070586254342470347097589341087597032672938910846995633724257876133,1812172830570486768023198219726218583158255123460220955281515074543933097836,17992769749806193849727573532001735714323064233429371707200828907106131204931,11275304845104653478990825724663443324387792098049434796341439810037846570595,11105199526118828533245892738176913532701964584183761946009726630431598631704,11393903979182757061241357325556769026145343989318381225525091986823175945546,14383047179623652129287498422471395756755287245693820194038638652931729043624,20453515719997662355844823439261666280107449255435062001366805179715649416520,16342434030539357589118587629035849207895930777526269265833103191510088418049,18401618409669783606190734020469430253158741609682792710560527808266513994586,16076963378432439787360187815002671229026877629938245603309362816936414414606,11529521787481754741418171353792184686967806427253956770441456297160607170941,12602344479327416239042579290059415968931395895265775848606068378636646131638,7874996576706323538862472352643073872193797790899948188898578232811415974069,4845431324532575010258701269749667428252187973009639700566740844013627970107,14802018959157569593654049670448062053140035551074745737518084801052997376690,1438261891736096301511736944301645044858355530036359764344568183983865122024,9702483734495711444970258278431697259819553205295174290488141405714571120392,745629299152271704331537263378566091569916279264951187804590327433939503876,13647050656573274198980106604763314305257288237932552445752822394869548724758,16745795700152546519998532820179128558740146524138261377398336069302091938316,6511309643923082597828923519243281993300211181014429981003702021394673484309,3158509665257424804238893020268668038794684527943417360064521274731483365497,10106711021741632147292275661510721445094446856823798214773373487329113893162,19539597394622940270506324036474158048415508212083560312665281444636039358507,9075752841443178653052367723489194637305474480630925657941805297419704103107,10984322959292625191378844945459317193701661510910417025411449026843907121641,17927313671844804578171839390174936993766288170716470877087434657482712787254,18872143162724264635018175304456023676931184143071101308504884978404622981510,20515902079806118899516548385287144085761546545950360604606371922174253859996,909520465300399063286844098900959690198495601569624327409635184475032912958,20206446745684213293565932220432184473350758436589542174203682990821527627997,18202239467972118142408259480727588505962487821013411792329301914239859726481,7983919062477498484336722979137049758716865253938030483468589967847498836327,8325614337212122905531318376855865321332189692321777599447159536409656516919,8597163804726192574292212854626326634508890118939606311848139014738137868745,18500944130179290196885189330659070775829081695220678669482033354888226989090,7688562031300833340110739922365866810835026837265955101002957176624104705373,19947182975808967149585827952170169153114833389807259043148589247054925861923,21517453591126354047928769118216728006629501856431780724965733122370735013602,19724728051616532722905708549906983762154956430000563385110162693578183573835,12901041676897371025108379309395257314967524835524863357724200518477312324601,3552976975075178791886580855175573474759766023206417049453393296909032090255,19723727023156957738383690313848921568395238875690539785344406327140649751346,8448482122526118108012095036728031952881057181233719818597059954973230302598,19506723656402269183886569439436103718740054288352928129647596321989076586438,14170198227468034198358292107569967739463050831964193487443803219358410981401,2398884471809169728404698398912564280110318964918284340553363751754870608551,20316276154960569208855163430299959763482642890911503054443013025286320052982,16819346170274370820168489515108636849055213099894018965040750518138293949687,14032485862625099598391073907784424901699264655891124043486362510876557553033,3741512032866709198636578814340035900693212341083373891378285003365821212725,12320998007117681710156579111620440763582440787871319835484669927670822914066,18497785580008161471127317447391820533755559610828409772165480020067085485597,4405750113669275276872999085838121306688869906871946649397890860602053182664,9830919490764773329556696442544208406733862221424439787824742578837854955405,11656214840454358128291973754562337687978444406755233034850997851692380129929,16862314752433119612255838474361565358197526603416756657147704910780503202458,13994730783691699927566696508271362101008053907735972055086535421903219406757,1854398114607336170485701571991055833572643201188015258021784624866312103211,20069390379729391520654648717585246938403361904664791681209786618785720069963,19778444821535136400266636630030874919578160245360989612631440824622767847607,21076683052368294199461719450518198858527944040936974409849054794891242446768,20411961758852468040955165630870750226459296665790953169982230333559560296737,7502887992944485334895259919103098713153732704425367381733235650810817022601,8197671201190749689041918593081864258260291777801687985230863071067546597951,570474345973383626887611250305231463005632817815912456645561438458026430574,16187881277000098252637261715701961539204559080071010626416256497925074197451,11845760454453819227975628605163841650771493308562299599588237256809780809041,12496905116588812906791602937225630677262600876144492834414412499317258049345,4202178453449927253051431595142836159883278283876420191896732301089503127871,15280239602029688372093391224297422856227971384132785248484775299588777602819,7675624637796659741242134119256859966414372807758392029058215748145801821134,1558712828795805480069595730092542425736929845400776453853052297930907571419,8635050664405255712941235442916789795311088451605341529181390886210645594786,20012080883240845774134523050094772793782396855825781678689671532280266223297,5332665745663855702669515489737590813722712486482340264533181716182162216492,4485713577378561256572703202440374134284884194291407499970429041545518915674,11594166683437400908552833183389222213106302657616725421515671119008232951402,12334131761060442183744872783660449330900007808735685674075245978195977188916,6469473140282499287719023824549928080797880736382216700350093546124693991876,9636916035199580181413428196442500662713954920605937945590797926723030993514,16259404193045476674338459391599179316200568243819582010383092764410171324132,20780929014533211529148194875929589500835169316324843103846798105106103748435,19665958036420604957261288306620614439114405875604211377014353932489316681936,15722491897648578237100473323139351762887860215830601049261437931157637153597,20474814639824406443111360000192533367769367587690127965461453022108167666929,15306300298273142257702357120212730128497075786589008381550108606914393296015,19116371381269652319147699604019975103087973589614811479290794650138683901396], - [11497693837059016825308731789443585196852778517742143582474723527597064448312,9160854578263429171202421862962594026987177464192712717562131193605088890171,16140003334191084124451468943070902129052879491017160345910048022420147165440,13954253824852759534031493316905992731351625718124698909948022659536770029356,21692459647877833789326815072729212414846887919903018341690717828718320112005,9941936267230985844518782624440910125063679135232844826673261884947459743883,13764916706054812213341909699290503443927147550756936312875016380348026052252,19102599208524798070012402067365820884265931087114568811319734727534891174260,2317229314815846955024814528087757341110607641360330608288042339421595574836,18416483069534816725178879766589878658686265350707575814092642317380006218736,1008780931278741447191637805167409477999443010661365677836100477728938308997,2545090804346934163783014162536858416885322260022963915511642447380970940906,20063061892576784746234714844937263854658165123147516223299128773175198821424,10515454963476061878165006305843100325941655508909556343534889232612007413255,14666046876279128708964624720946075308028756066224010008571298456055047416803,1019066804447509488848959767263827580870207313924599851872882869076383737080,12069305948801710705684828347680772060569105557945593846885134778987150642368,8621808318996908879998215444507382011199442894883948814246574848625262495021,2880093917191730817222149621749122107421670637456732204857760380124742164752,6542220672426887509675431131054437027921301676718161645952700116082427886835,5244163576308284656156828799646671881031097312780189786429450879353224489935,6473177356818363685990488940547034234726012773074061935352613261396549623686,21820960109882302233412313690073759484098924860992104203363318963429862834269,776485012941102583811996326817291151707768276005464663608504425462324969189,16008040671461692654565857317129301282959438973184407738728929267807682783872,11432621469217532329151110587073289606303873577842245393046608426744660231625,16529428848681190297024382986484471912959470051547049854507168832330777582917,21022141832384945339899318910964518260971220396886777286264903115370862218195,14654032557013894559632377088090851151746560959506805696507500157500224672350,21354688910115519251326230418165921377662159943573060390104844506964336391116,7752619774088278019865202458496784783724532278543560344508935599686049023521,9970654674664205783578937362441466301698784253920856829108173973533602978434,8766781005151378907464491478911534398597711022218593484510275842885145890118,427418044823104424459481289119034112585817787122063948281766019090147258009,20178400825368362428846659280983736786989246199446877730902913555280765010239,20090950791842994139452610863206653079874108855048809192426038290381481405709,20312256534186716461922298801781816516042265527822903054862895650988285562148,4909922693172591670749898596465752034935631291352031623980892388245203503556,14711873682305388680005649678171045910409841883308457847530167875811246495050,15958770417311022337941451962731041577578914593218560089308342731268531712920,14344571866504726216497643454572836820480317972842515429281824926793932325980,1769397319845168475613819781273574132774109508454697099778007579313922258588,258587389395146525547707547116022862705614858555176588203787762094788370646,7022463667655232121918607020344762877802128330181623732816227821885112788637,19845060031908398041047500648731073426448577406797522741285587091948148114644,8929070527835967284189505459276001504282186650781989399671939877306459603924,3547034362934554702033015610070536051926221082690581599667998618549114761320,4305372853651357563855521637099663044320680997112932657745973067738472275743,12214176886158725776791687535468106829515395407992835497927312162638766770078,11706938131011539306398383828922578377803816015869195385220014980091795489607,11651169608106469169652973769680487604343355235752770879131657116772958352610,13534129170664288430416028489502009030456779206590118389136628926201783734674,17992046595622622161177230469344714863802535922717313714552838880957499215981,10357743233228120740298650287569640748031608153491097653220067758242532130547,14517928487614900276301089165901434951535050275402697067248151083596639118376,8209182069608252268840455827520737704804441580266130568152978886513947166844,7640073974915695432060688995568585354936052110685953897202450273254409304465,6665784939677502535233010310165049782941185917893655988878440622136707103599,5556533518127592657586282330044128807869230494205809390140992474026365014562,408852126690043032125614061393097734033642541042497038832349288207856020928,12457107183372565990532088400464843754189254530767241274690121422398153743230,13376606774696045471509234199808902800235186345177397461276986609303176540711,5984750790245793264714000637029537436625478804219132653560918517073545131213,17088785934598552415567637681327922806463774512289686863420148678865116179843,20571346584413672249720180719864302959756306192295084730012069713189235458689,10563908856437897624492808163035753573292724651291788140893440219493498317425,8196914932493081300314276778567572383087801740102758457948867897900124032622,15351358433647454670571026954149706648025357095082471550411625465102412004635,4691549575923073479244290910433477874429633596189924034857922132851997509067,3824402350445187488499181297883462500055483166807595223590583390670577007868,3079709149206454455742256725666572935951085219797765997598190006202700553625,2933435916857570611285367519434342227981452027299670163614250683347221879812,11563256620627039928684054332499213986056102448749960304814905960272568400553,823982800920919472728462051408065816783743200056445901787723684868401502814,1426387027752743868839120378047531362360888408160839303820390910661721602405,5731997056751920185589748689260608921390513807500493745181552863591316000292,7720993839832885597994588400736035173902383878486875722645777844101744411689,9002464001048295091481045293483875664362475441902824699977741340020558338559,14092406920820325227424145554147519809410886190773484884502907926085878880530,17941121573263204671416572834368313711647830547916231506552438869447449377380,14129082317750218835304685520412323779932243077309313102580200435673568399019,12243264707350346605364305720479795822428336866265087370053925276897423448873,7359586883838006703688461248312304702229090925413466255532354254039350309505,3965462104895971860844762333128974051506845133345812196538391893357098668635,20413404046776512481224629835753522701244606906272947012890416028042446470875,14776939713848231582251698583594764736648030077584017202377553055729297756934,11733430377692682072369036122380634083002891720790435745639760545087660184574,11292503903510690808481905838273174776860675950299588217800551517281190922743,11420684871520848382159461165975179232780830769432469479502922603701278643559,508745459215920279034800716428719752357838311731203417677851933253804443780,13406614833603475717176189537057020401687589054028958458013676908546295198427,139498778461763532268768837474164379463641791532876816780917343085192436149,21267978943610728192699568453293742013765519272282009809779840168468272374983,13427075011225899058346282386775414644140701782157119231274761492276104178003,19408556542747941554117161987423225644412569826994655839704848575188694207985,4344748623903456736892311801593408666061687792073497811421388122550378864729,5249164170024197498338412206444867159273343488553715674803882832943638673489,2429321160057297680775462145791389342017255648014188548442207641044604477112,17633034583356484958669009250049760097861376611937917426871239574846566954163,8589358080626653532622087734866363152181033731195407703922685134228472217961,169706674245923892154983046053808641575955705892301306744269839968148939837,6930563539197568226045059034503291611681517204525149696500944995384070682620,7715180204730071272045176332163669182843407084675929323110162515552729145466,18820951479360410886797033460215573843065563410033088307349452904607006418510,13004571734426490172877737218587476803131320809388224624418159739666018276230,4221983194911935567520445796137770165826124860682996668925096525627918503987,4179458328609322852016864400883248432169808675570811233121213062838243996150,1974895668668582620251979849937803690939422905200315076249511583941627363923,6163089641798041487723906004413611225955533949531028903999813030048150618255,20798314848405704563578428763355242237484138146926032039199072579614133708498,7390763848541838674951447729994978703104555741288179669331719960925737939679,17595709281213749734228944927123024058411855966868873405155429088809356857614,2441295378821425129112278178696474169691086102217838124236465522719015824771,17849999656709233176331949642982487670074039937621948427273232063967495006615,5474039350730649299741439140946492457291098791158740216537321189511814004320,18047496680368319496003204418900793303422432417949101604087210129655489944730,13429638037186326961998474643589136448656547552567706898682870898125573018456,4946359485751570678621380009145072972898871622865400112232372288432448523287,3957822358540559545601980592836183988567881320017369675759228588453032530432,2400564715392273231728553914090327718988368277691346375047322875638060719294,11894303179337833272080120828007835602120013500741388580434416759507002392538,855198138664096487124576201178969627556714572486300747020353650684651888948,16178438790960495615141009256088177242852822581784859562011828222911238142141,10137977256085689928230181030370096331013301569857962720687404778057694535741,20515298296047282701750471139118794292164841708209011112551973440387123890479,7578927989884657210580284649728673292510875058413984297956940891614841867974,15739538064110791981043195085211350004676897766248503311173839899207608217532,8509314140684268376822128791119356380924264099968476717867240237437611156406,17940958334079989608306082569922896755033794405963583994940471979845228834401,6805144082112931458671099527607595264417843202533041916539891329055761729898,17799985834198911964923035884156388240555414131807336706586014102549806733421,1321093977038377443723007121319910985126631474786194145179087170534580192225,7212420993868874204016591911998823569295893131341249414736874789036080080431,16508732240056273863067547854850721821696261984346034975271352570374366672941,19365952558655609049762470933563228578883041309045062714419724629518231309330,7130642306151081144305696424018041594798737863203511582301667374235931034428,15515575256858646879456258778282520667217724217234033369846512585375869363745,9059306962111196078284859952597377729932287486280210246946890053176853282710,4280792737479805409403664514498090636723785279466801897971750554236293020515,597858655089478477234738420519139785711327216887739704481840585427214898574,12083197860096972935386715826619665719725493525449003092099143765304129114681,12386885105651539176174534724546204378869340659228252756723599802198672140462,16104345036536728728283892631581380860380214418375736872156768647788333934514,1354879242449295308208627398119082438254972230604954870747255418847391619159,4337243085646703769896498772355566596731636687256987520433742534413482763248,21848361732679483806572599977716282165817086425830260890883893707113846583427,19219603360817893268138318807528436572901663409914252265449565639651815377666,8493170221045553556330983879086435859112709446579471993956965243640551891229,14527043796091130553415865581526659472541220106744153300268446542314624889828,7937111786465239058321924657743649234315319708955946415168847089269341907969,6983241618969891267833664988834562719925952220932975709556427480787427509845,18465592203176453842524453315376851907098534348906659566313290009668304127477,12577134888425026368283611608059363450080978991251364658919457233283032077618,6518118228984271075704215109336988269949556606855830580887066004852197959585,10874313757780612756454383662805810655295466490423990025119534270332368723291,20050459982999023948350579488832955163413000705527333267976511300912322921717,21437528840108163281775491180120464654045652656938712316426352947376535924261,15993399358508475124653838111269121783855992741631266590611036066175654211556,10666318855988978766724392469406816805194254878125837815249460550109965279109,3728246313656508848829733684629154197051824118611903835393981369401120614690,15672779156766891637063280303644284349935441934769848438404666835306555334745,20385059098581842810391414884461531594818480948222590493458925664185735049630,17350905999329080753256083745369335770368978719306867594625495391694963226620,6853271030225637900654747228083647747830481256853322607732231926920221636638,16945013335725553221697952514726788415224349981949301561114619373330552300437,13958698773337419850196158271441769489630950623502500296722238460406723080346,10720560039907520317176701532328409797933913846226344831945799921818292744504,21881661898012375513399335499754096939362343783241122010305516740752509759219,8000150875389840177411621828177856485533123076967778453164076865957788973133,12006864256015504014085835403867962462497397391751885107034795661085483190829,11134943591559521791276826061536197135026619606969540608969613264694780202214,10460719249321273180939167776515335033037028258913526408809327052344611741158,15622824325483665989612723680117847052463187830077568039968213833454442303285,15410746446975895232352042328675463711076427815985485297730903996168105249910,2891625203408623652388062275887825901052275992286085168525244670232353662516,13945346776936592111645435552497641082181197055210791224507452108313960355724,9948029837520576958543862437428843878940881432043095435233721163595331057646,19462884070334019417166507501239463855294968830363882698967905077860898932836,5520136928844106525731832126160315598282989291025512087174203871698688956372,2261360495098633227748653797124151186175710067614537829940284371045336769476,18416255543912854662465760974639117371049579168655995592136361451572699752296,11463536517819692876416279640167390882172379596277754722588804736317693209031,14766312573746115666714530391277822821010415216258152152785909105008723593246,15974413313983607427146441647805917978765835122483385258268287590594890695726,7395768998784322986017026062700445312131764953109410144512127957624588026520,4984362060666297962621166548113407854009922708767986933509108968930963325593,7856069925664789206382562869453172139307214363990979700110954142509543954720,13392340056392075670742743235567931160245313927053798436913893965097578743589,14474853581934896987119860016624045909083123926480713073931600741515836999440,10281094117655562522718238098582121237113987849950975777935895552307296780258,15651874975250045926713763993802349605521485743295256479167713866101959393837,18837584337473843738351569365992574544592556787094567312567026738414350732486,5422285873429437751528536004788420694267218180077508101272917323525729776286,14483434861134394018133707852914799521209887335043004813883706597879855694501,20781651897373919207655051244184479648667009194959049646213659882342077548670,13257874746816536319517386553976680827294792028033921278407244416529098958298,11687595443717328453023567060513955787814475781716013805208754435947875015986,18166734702075655056906373297658555632769934998914813942424547912757194661408,21844245024899402789239043296889438934444349492098488274411135961103932824086,11576523423366505825808301659798885009429028155669986846400153307591026628871,1148929907457849288972409801053032039492913919668345502756020163532587226569,9833563661199700341560575887921549871699630430379479441644037429312353663854,3530072023449326955819177530541286351102246058096342120743109127661619847487,9578572618820421025088920868463234434017082077820664789170518853528041438058,7903274455513569732248555355877155817202990193424390098928646605922794954894,15657165496965632442135478212817895834512397576120080820666617370995124184076,20874620177603797416855214546759257732117862468392283423272496519554421621175,15225141515575386127960844403303707527145779098407107474807381929305493685913,18969726739742369826201131743053235807095357084892793088520738053078283905792,2273322388759602026766688787958421446004694547879317377854849512027808056744,5432511453110863684214390264939773007164867954188379597097897639266721931777,16573736113133010502307046980851924227669732687124639246608245168226674694938,14442377229880210285366376088368281053151209045775399428755468734230536622166,11507669956883827819118311484641373285663729813488745641363568933392081679659,17839532429606263422276008800408286253970022114288361307186094837217135904945,4014265539378515041529068347957642340321904838486974789543291691351911347680,13003411109936526663340169024379119873659186776343250211166084846025445488231,15306462549196010658398578543921194922332897913051564489815921371400376655492,15374920278441335059913374044144421033417626851032526544458034333565246831914,2323707387573936061377018731706151895551673463355017998838984100857163359959,8763825614293136074070194100490720958859071057754803255698169463529260604989,6460078619951263360498950096593765796985616066844041272594234887640757495947,7787749571541900537576366919010287855513576825542236245962970793208463720908,14155132064389382746286911268123763500605059883946776474093143918456417640061,5273412399684398435707041325417233001212071630727434066521150499193222197699,21782771343726562685905794523874393783448988772056027768682759741108535654588,2051311409953010480673263657665054154914165583084681916263406447692393737285,11875661765858469891704167021983258181748059479218144774825851054326067416765,21068403881106541076710977164706790160208140346094887767675202443752560686192,15758340092420689120259589661569467106735378390624556577895360824207644286190,6348044865909997285104441438862139025250301814988835887095459638724790173542,17932524652786058307278475190078972097828770914834668973535335630530452917847,3228816608788245618072625224844244257443056161113290604232896419878090903926,9551656383427589703749567396517141384933708835078892692797520811547619069163,9020946637763713728445703977273148745690000656147983844173946393849341364502,2943971707938849936044214925657955353752398302351355306608002652427585494465,13685248050363412502458409958081650237171619758299111626717716567774759779438,2868302441860272746035818268943730589208611466934920188905195434962368539498,12942754961762450702258615422302669970585456811961698112554744196254280397924,7774153016753223166594232439290374237307352882928845881491063153885238423849,6049199094489456460150873785624904803705527267070980629871787636829670320696,20845774618508072345571200270048422316984213457783733272821856328966613453129,893781271752145245996199566953390937322128434854461459523685354415462146991,18253521160421279022112163574719081086152283091051794425756555232523003389714,5830356839546054218884630677325272050228211705054095093735137780865196640272,465724850238100756077164119125411924005501292693566847128509233889037994810,16128424014911176575708362980592727342883849823936273728991741993116151256846,16294469866182032082852110477156803007474009685855833013024070339538767961172,16065302076211391028679793764673039756452069543133653373534107626161947643947,16884841668405833752583472630774457863811531316950980947099417366816649918715,6491186733352076588617073683591626846805330965399318749556699217006305107353,2905363039904017404089840194168764066155916074074586587258377722869451022895,12278525316798802696433043227895855967349302508482435733539545800309845622462,17314019937917464307399357201462393625411723762603710024519926241513301595993,17575148837153403621130441476206668397295797814863081080474688530411862819003,15471095648400918007606825575051718247465842587885842548618709676930106301461,12384318072593682092503177281279533170809948746241154089695346932340260672911,485123300957579906724434519828279717066415303115967428444773045074341666269,20783388705359037084238123327815399486599342641041862648140815340928809400500,782158089782171747510228803754257660300288627956397010472288943774913698434,3478639244366860518133129066736643188173227661380443503605881541719237123785,8117881660412001220282982503758841397343065193097821242261528946890929063115,35058721234476129650326366428341402515138917944396335645144933468879076532,16397938679668108498255642177027044558510343548921376375827648132906803583443,2433453154751221667718635947799318194191827076977739122814782387249355591958,10029257080729083671923349509739320383181145104464214096029001591053185820564,10656149073844062963681322014553075060763965763326275398946747079560564035850,16593959744982924702318121631183966060100893770061806448540495161947421822987,2068414540408163070577553011598011878961687148891918803076043034635892035594,7626934390068570344424013149524663454707020514194937543157326823804903603467,4554638618925430597188146675680715151198309496396245054063619103455584547039,13496396626587678250552586498039471308586222626132206600246125554024514007655,9386575758165199373292193827891788760863572720909068403298778509513288095168,7915179166050735066974287284338956896350001911949145779842510041370266325973,8167168351770465939827858686491835211463722244546741051891842055610292036496,2984855641991264563125921669666111398496570671860076360618117725463255935294,13345515131307851631101763161069239153529744919878592460694942948582652858318,1683899377816547722982571372970082226593844001913781056647398610840773630210,18082738493041031740109434905429676829872619916356658605260447196047710914008,3093627219579176143734483600677215286836843343902256951787659223143740127833,13711569243726999863512778161983125470458400981069655361767578939766971032706,2942999073656444791256166118886574877976523928599259988730412230442182398832,13741805436257583212406513632778404280140012772934699700695904335718144229392,2966496260001027437433299921197242880503083867421600405476235949236365134313,12214449406116917832159291589682410934022154504967698746834536840379875421993,14724028677081535225097028894192068729072210977241429998194582705094787450320,18532472576071611894578331306492326674151870705350144561012248059523768664658,12590949238667856614747230064159254583777806754508472794550424398198576585120,13228220894074693515947418568115512670466893414535562052872530653586084906533] + [ + 0x2fb583762b37592c6c5a95eb1d06694b6c6f9dc4f1ad4862dd8f5e67cb7a3f5c, + 0x12e9f46cd8231bb03d4028bf7a11d7c0e331dc05c088e6dc3d1d001da58b85a5, + 0x1275cd70326f52f816a7c53fe62e323efe61a5b8d3747f6dec5837a825873afc, + 0x6e7d165b57b0299d23e750a75ea2e12c9c7a16954c40a4d10904a61e8773541, + 0x2f67f23a93ef1e215a4add2ecb41bef4b9d85ef9135065d992800e34fa98108b, + 0x169eb9952e2a8623ef38de57e15e242df388019489e01b7c84fa839d864dcd1a, + 0xf4cd404b4024ca13a513ba3156d4de9cb3aa240c683b3e0eb7253bc98c8b5f6, + 0x1c486bfae3ab032ff519e8dca6dc41ea060b0ef9083127bd7c2c4e089fd45aca, + 0x102e745864251ce940c67b1e2f4bc4d27fd3851571ce6813baac665e8cc0c79d, + 0x1e6a6d620433d22293044ffe36a5f2a729c129cce3eeb0bdafdcd0d52bc3bab5, + 0x8f3abf97ad8d01cfd8651ff2d576e3d68ecc47aad82b4188d92138bae603b6d, + 0x283da3f1cf8477d9821ee60378b1c39c72428511a1b9d6683c0302938c248ce6, + 0x2d99cd8d88e49e0babc84cbd58adbc143a75a26ba16f96466a2e41629734437d, + 0x171edd6a7456a4c25fef8aa6d8b748ead869369f72a4e502861fd037dda8f779, + 0x2fab64694369e3a2bd573c0cc383695c02a381e785792a3fabd6e1ca8df2d3a1, + 0xc6155944f64f7694fc8ecd2a2b9a2370568c3c898db9531dc18c72474f9afe7, + 0x1ee0e5cfae030622249210cdcda71437f28f0b1730653c0915efbfc08607c3c7, + 0x1c15154895ebfcbade12f0e02f0cf65f87351b1972358beb0eae6b6976cadabc, + 0x467fedd16f9e87b3069ae697d185c9c884ed5d9e64bb814bd11f71885754083, + 0x2b5565852f65969bb087fcb51626b4754b69136d92546fff44b7048b2f9ef8a2, + 0x2250acc27d5ef8d0f4ae8ede77510a7ffb897d45d9c93fb2ece4fe4c9a520f97, + 0x2c0abe26ff8bd475ef727815bab8a81d154d2c1e36eecd07574222782b02a8c0, + 0x19b0bd9e0c5fa1f56885be00fe97cd4ce8e107e95a10838b70dff34051188a69, + 0x2342fa805eeb2b237633942aef80bafd3af387ec8d472f5d12e8f9834d32eaaa, + 0xed57663a2a64c73b2870af0065ceb8cdea397599ccd9823747f884cdcd8faf9, + 0x2c8da824719f86bbe3e601b19d3ee2a9fb766e7537aac2ea9f44ce4896e64bfc, + 0x242fba876b16361e11c677d62c6aac73930683c0c40bc11938247d2c244a4474, + 0x180cfd0b1cd3af7d5903e1e638bddc6711876fff6d5b12607290debd5e409b3, + 0xfe8ce1b265d657e790bb82e6881b2da774713b724b9a88ec36373fa66f915b, + 0xe8701cb0f031d03a5d81fcf949230dd38dec12218ed937cb31d58cc4640809, + 0x7ed575f9154b12b0fbc12bff4350c6a4d38859d10f557d38c513b37469f47be, + 0x22e9f46e17dda4066a4af81a4be19c94de4b12e0921f819030f8352aad050b91, + 0x2b21049f7b8e6e767d633dcbf2acb264dadc7a85a39b937458c134f652a6ea5d, + 0x216c5a5bff445ac3a3da1eeb706898437840905b9ff27dafbf38efa470bd0bd3, + 0x2e14bd4f01462ffd0c83929aa97706ac772f66a3a0a0326c00eac11f9d5a485b, + 0xf28e51e2f777239205f13ea21e8f33172ae538b21fb69bcfcd82ac51500eeae, + 0x2c2295ecbad9cf1b3f6a773c69714eb4663a01827044169e7f1edd5838106eea, + 0x1afe7b1d8ac438739d488ef003f9c3c679e7fe2f0918bbcf93ad1f127f2281e, + 0x2e0833dafe87279685cd5b5a0105f8b98774b3083833bef43608bca8451b210d, + 0xbbf4266fca0861341c7196fc15592fa22dce6141935e01fc6077c774cbb967c, + 0x530c66b07d2db8dee36ab00f91c5aa0a26b48d8940f0b72735a65481e5e781e, + 0x2ecabeec31877a68058a22f773e92d483867c01df7d050c3fa953ccce90acb51, + 0x1e379c0d2f9d0b659bc732b57689e48c0262a976379959e12b95cb5d45820f28, + 0x27767756606bf727b8e5361002c613d6c3a20df9c1788c9c122d3a7736a6b340, + 0x1be3d832de2196443062c3b42321ae05779368ff46eb68fe57d835d8d656ae25, + 0xe9b839700b18ef3eba297cb68ad992b3bece0cd5bec65e6e40712425447dc59, + 0x2760900970a34d2051ae587ec18f502d246070d70c2c3d7fedeeb51bdcb785d, + 0x370ec3f70286f496692cd5f50f6b06e21c5cd89fa28f9c8b71d42b4ba277906, + 0xba8f86362e1f301baeebb2333893f7fba2ea082d75969a97ee3095baabb10a8, + 0x2d683c3cd7b4f544bbe4a6baa9aaf78614434a5915299ffb37f92abcb4a4dd6a, + 0x25544ccf600d8604bf3e11aeebbed37b77cfb1b22f3b110a930c91e9e7951f82, + 0x1c583675e423f947344328315280966833f05f91a2a24aeec1ab6ed37376f959, + 0xcb752efd07c8400d50a06f3e1baba3cb35b0ba28b262f8526f5eb0ab5bc79d8, + 0x14cf442b6f22ca3f4c16974e2eb56ca084d05eb93ae1049275b8bcbe4dc238f0, + 0x1af1b935bdb5607897f4ff0745ab08140d6e80878652855b1947576fcfee4fa7, + 0x2499ad4b7965230d4dd5d1c41e00699c40433e22c2745807eff395a13e6f1f0e, + 0x2b582ea1669028196e62e62271a36f532b14c0a8109d34ce53df9b75b81d63aa, + 0x1c335a347abda047c4b5ad93dbb2e9412d526049fe1fabe1b5fee25ee99e0bef, + 0x1e3451c495c60dcd443730401ef329d70571e3644dd7b5664cea26daf8a70aa4, + 0x2d96286e6d9eadd63e393335f1217710746ccb928834e73105823acbd2da005c, + 0xc1033de21891ecce9bd0afe313334f7e65977994e545204d616ae0ec4c1bd8a, + 0xf0f51cf6db73e970a6b8efc8823bc82cac8403ec369c02a14affe5fb40eee36, + 0x8ed2dcec016b8eedc067a6da7b562484c010234d84821780662acf9d281b348, + 0x19a5ec3b7882ec910bf7590e9774b63ff37909995a6d695611d5532d6b81a5, + 0x23feec5d6235a405f0d53fc16c955fa0214cbb54fe973948a1dd39263607c33d, + 0x85438dd42c1d74fb0407e48ab1b44e0e42aa3f54b8d7d4f6efb87102c6a00e9, + 0x1916f1d621aaaf4f9072bfc4e41b4b78e82b595d7510d507591414c005fd0327, + 0xfc2435156d4ee76e9a85ac6aec2fbb50b0b77795c370c2183fca9bcbbd07693, + 0x26cf4d12199003f6978f80761784de0919d3a14887a57d4a28b4ff3ad39bd969, + 0x2c480375d8dbd4ac4f039f452fe1a9f074c811d48dc2b214d3f5de827a1a2025, + 0x219b5f8126784340f278b77b765dc4c697937b3d81ba2691f8979839f02cc0eb, + 0x14adc2f2733f55d49fb628c3ba41110e16946214996d1f93262b9347cfe69a21, + 0x230a5fe366e0aa4dfae1dc35e0206959781a64f22d5c684e53ffaa6614b1df31, + 0x1279f8d2e2d43a9eb3b7e4149d16451b78c65118b5a80f86678f5ee6fdcacbde, + 0x2be4cb4144aa4b8e705c37da42b8819f0165ef3476fbc327a3a3deb0a0e8d751, + 0x283b18f7a149cf2f2c8cc446513b5a03a06022cd859f16da1149e7dc7c60a45a, + 0x2d5baf88887aebe22d5d9096dd6c45e941f6a67369af01c75479e707803378ac, + 0x1cd9a6ffdd0daf7ca9890868d9ab398e0546335bf29623aded76e4f7afa5ad55, + 0x160767c1cb457de2acb400781d8cdd25b99f75af301e749cc46049c8db5563f7, + 0x1bbbb19bf384f9812aa63685729e0dfe06f3454c12139454707c1789c39fca6f, + 0xad3beb75c91ceb0b2bb8aba2a1c73c95e7de57b8d5a7984e9f4d010f15a1755, + 0x1841eb6cc35a1dd64feba1d8ad6cfecd65063e1e6c2cad4fd5bff1b4614e0b06, + 0x2356eedec4882d9032ce821d611b98779bd344e2abe0a57de4de06b72be6b447, + 0x10fede6245a9c78b391e69db91108306bee130faf298432d60a4944ee6ed6479, + 0x2b4f28161c7a843692b07410223d8b5db762ff16ac0cded416c3594de6a53443, + 0x1f0846b1b26aa3db14ac0d69972c9118051183ed1d1633876b44c92f022e011b, + 0x28ff7a7752e51734e1f568c6aa3dde3009c22ed210503d5dcd7dc25f7f6767da, + 0x1a3acbdd739794d252150399c6a8b3d114d97d643d4ce83fe8f64f41d8c34e93, + 0x290ba46b38179a447cc81d0031d18e9baa34da9a60ba7df3cb2c7654bef3f412, + 0xb9876589637ee3628c3a08500d67363a1a01da7a1ac81f528c450e9b050c6ea, + 0x35b7b33a1e17c6d1674cc229068e03d3d1767bc950d68a2e376f0c793a896df, + 0x7e6b30a0d3c2526be65920e6b873de72db1d761f7935202fce088538741b347, + 0xe5ed87393495c2a7f3b877578c6bc09653755179159351d8e67470abe9cc690, + 0x2824873ab7526115957736a5cdae583bfcee10b9d418ef8e17795de3386f21f, + 0x1db49ff47ea6ae80c26654ff5714e69cf3a1ff7b31b1fa7a3b9e64618305d582, + 0x1be421809f80b11a626a0eeb927a39c2413e7205d25c89276bf5633565038941, + 0x3b7c7629b535df5b487211f4e789b9a287abe7c453632ef7d42623c2d2c377e, + 0x12a9f7f6e0c65acdf8c9fd354f7ec84d6e41638465e347f3063adc04e00e809e, + 0x1df5905e387f8ec81128c20ffd995fad5402096e3cc6d2e229a23709b6859ac6, + 0x2d39da8ade615636070e6734fd848368d58428aa3b2aed784d8429f2075d122f, + 0x327c1d1f0dd35b08df840db2579623243c13d9c073b9d70984bcfc97c9beb7f, + 0x18a10f3e452a08076aeb6b825004322a48a6fb0f51956f50250a41a49454b6c1, + 0x1e94dfa0b21f7b3e6047d599b3ad491a693fe458add2a56c5ed16155fac59ea6, + 0xfe2016941461beb0f0bed25bf31e8c9a36f21fd61cf70095d2da2bb93bf3b2f, + 0xceb82937c84923d76bf855a1bbe412dd3e35d0378007404477883d885b425b4, + 0x16985b2ee64b42bf9ba0673beb0e47580763c527f4792fe994c23e3046621a9a, + 0x10e6ff96c5dad8a34d7af2e3c6ab2e1eb6ef57849233d2945fc0aabd404e5b6d, + 0x192fdbc53b382b45aa3020d21665ddd656bc1cc332581cc71ec97c3ad71dc542, + 0xd8431c14f1ff4640fbf6990506d930843bcdeb4deeef3380b5cf2161a3bd030, + 0x604632b70d1c0dbc74ed29d69d11d37b90669882c2e3d6784b47a5aad03495f, + 0xf2553c7fa5beb9cf2f6957b01ff7bb7d3ed61f9c2e6fa8a53264704f986c193, + 0x1fdc2bb41ac0418d8351414dc360ab2dd324d1622807cf59db5ca6aacae5d58e, + 0x18c42a157f39bfcada57e085c7cd33781cafc7b33d6505dda828972966a9c2ac, + 0x2645748d1b13c825bb457aa7761b9ce5425c56137e213c8634c87ab29543ba1d, + 0x2788af72cdb594ac08f41269497e1ae18d44232ed0f80a06bd9e72fd216e3972, + 0x21ae229ea6529c4f9de897bb849ab6bb15bb92ee41f73d348c10ba8d64acbcff, + 0x1abcfdf990784706f54792660668ad106d1a6936245785c3fd023a5344cc25ea, + 0x29ccf1d934f2a647595d1be0900002b9b7a343c3e7d3ab9ac3d2ab8de01abf8c, + 0x39c2ffda04fb850f5e70d97ca2d93fde05b651b310b1d27dc298b9fc888d9c0, + 0x1f2ba53bf1c99665fd6f4e862ac08899a41da938198153e4c638bade14719a16, + 0x2451b8e4232ce9c809e439b6eb5fd2bbad8f51e9bf0429a33bb0ee95b7890719, + 0x171a629d2c40364327666e0c05ce3097b2be05ea5c75123fa78851ba178980e0, + 0x8c9b34df311a18764044e24961a95d1b2dcac3c6df9bbe0480659611db8f137, + 0xb22a3e321a38a3801404091d2b160fc133530e8b7a52d2422c9f1a8b252bc20, + 0x797c435ebe5c845a743f87a7f0d267f33bfbafc9f1689c2796b392772e7d301, + 0x1e7306b31a137fcdfb389fac64b5f1ddc6147bd1cc7f30f11d67870454165dee, + 0x112f01c5aa8b6ae92e2c8ca7667f5d21a0b1e4a8ce00a2ccccdc459ade9b019, + 0x219de6b42df30699c66921c11e899b888e9ed317b586abed36fb7692b1216b1b, + 0x86a228ba57047dc5bbbb04bedef0d87c1a78cece6aaf9b698117b292705de04, + 0x14e98432357efd4cc323da2a344142e74f2aa117cc1aa4b559ad83e541ebea49, + 0x1e6b895858694eecad78b8b88d54217c879d8b86ad928190789a09147168fc96, + 0x15e37faf1d08493df2b643576e177c9fc704fecf164b7327481d32313d55d161, + 0x85d0f567ddacd3f8e5e00c4209cd9b296693dba11d00879629b522270e798ed, + 0x1067df821f616fc9635104d5b2150f831ff04a1f2b1399db49673e80c5c86db1, + 0x90332160427de3eb055f9b8748f7e2b88c11f415576e72e4e087416544557ba, + 0x2dc94749388ebd876e0d44ba0105f8da36fce0d45831e4255092d5c7f8b84225, + 0x118c857f29e5a253d50b4d24d2d0c29b82c68ac4ec31e88bc43c74a9487e795d, + 0xaf67f0d07a2fe41c72a457c92e95458a77db9ad0a28768b62b6681adeb11579, + 0x30104204ad0fae366f11620b2f12ee6bb7c141e2fec7e29d963e6fc94f8c828b, + 0x1976ac8ab874f49ccd63235f4d81cf0032ce66d53b0d9a910da3b8d0524a5a60, + 0x2c316de3167edeb721ab1270a0748ee7f77ed7a8a7c727559436f6fb9313bfa3, + 0x9d2011c83a4c911f4535e741f79432b5f2a5b8e53561d179496ddb63cb759f0, + 0x135bb87773cca2191cb5d22ed48e633d71149119bdee6569623af883ed734294, + 0x2d47ce655296753999d0d8cabcf056f0047eaa166f5f8bc3cc5eb601ed2c5600, + 0x12b3ae2f8d3633702674a4ea2e98ab5bb186da55cb7f5bad038be08a46f8f8fb, + 0x1941673c79be83924a43b0159e5f0919c3b4bd334df567e23a109d5ad7093a96, + 0xb524c1bf3c392285d49a42d8bdab4ca454514792e2abb5bb4f62c902c9b9190, + 0x1515ed77226a3311eadf3fc8f035c016fd3705a08b8a9dfc2175fd7bf58eb8da, + 0x64862973bd0b7b75f7b4624a84d680fab7da9b6741aa5d6edb76a9d0c40cbaf, + 0x1a23361fedfc5e494b0b2d4eeb80c93f8835a73100bacb989be5226fcf0df55, + 0x14752381dfb966594721cd9486750a4f1f8e337b06810938317563386d4e544, + 0x4a09034e0f69e26581ce66e097f9b5be008d08be687b8122540f2e3262914ac, + 0x10bb764a96bf402a53785cf2eb4af7b05e20d89ad0658aded12c1b581511538f, + 0x1499cfd036b8ae372458561c19a59aa635054692818f9b3234707168298fa14, + 0xa8b3b48ec68bc2fa9e34521099684e72258264b7796eaa9bc2130ca5f962fcd, + 0x1a46e59c6c21c9d54b9b231fc1403379d01e16680bfe9622dcc01555be87487e, + 0x9569a38ffb6c33d8ebcadc6029a3ba8ea8c8ade1a7874c3f017516c358cc698, + 0x16a9c201d574004d0276db42e7ef31592cd49a56b9b768ca73c7c6d1ddd6a2ca, + 0x19c05f9660f2cb6b113179e32656fe2b39c9307c0d1e9b3e680983e27bc941c7, + 0x29f4b811dddc6725ee59fa5a28af545cb21f15cb7fa6f9885cb7d6a405a063a9, + 0x1f99271ffe92b27fdf561572e5f6092fc06fb7faa9cbb2e07608067cdd529b10, + 0xb9fdcfdc7dfb8724957f00327ddd9372f8fceadbbd41583b66726b252b6c089, + 0x1936f5a41ce7135c9027047ec1d759bfd91ca70a62324400f15a31debf179ba0, + 0xe5eafa60334d7cd71251663f5b91dfe10ec503a1b2fe5b3886ad9b10662abb0, + 0x18065d065c304f7953231240f544ac51d897f58777c69bb9d1f8a486a10c177a, + 0x2678766be9d2c5251479999760ea8d6fe4a1525095e312fae3ccbaf689e7e809, + 0x23750f77af3988a0600ff868b61b9e5e3d00de0f8759612d4af260cf4b113ce2, + 0x7318b129e4789d21bec7920ba354193fdd6fc628eec1513638528431272925b, + 0x2a7bad1eb2e6418a954869513a7a531c58f0985c64aa07db26f8f7949fb0861d, + 0x1bab89c7aeb8f0f1c55bf1aebffd937a520cf6330add93cc33846077c83a987a, + 0x1552d5985864ef2844ae3d20a40a368a4e032a4ca49d8ff6546c450cb1e079a7, + 0x4b91151b3b35f11f5996365de43d43fe5476e5bafa6f711dc30face2623d320, + 0x7568334c7a0595b5ac2105b2b5f738a5df0931aba8576b970722d4e45c912dc, + 0xb162e458aeee52ea49ad59cd7b5fd2dfda24fbd9de8cfa1cdf06016e9d171c0, + 0x2cef3248eb4dae55793e1bcfa553c9315f6b78c356251508e79af7cfd8ad95d3, + 0x15e7245ad978573a5e2b912527de7964cd4add05fac3654847cc0b6edecfb9af, + 0x27c471daf0598daf80d02e06c8171f94dd4b689aa0bee6a68e57b388ddc52155, + 0x13cfdde932c2d8f94bdceae7ad7a0ba5d545f2ac20a04f7e9397d67b942b09a0, + 0x19f9a64fb9d109936e840d1cbe108c9c36eb46d237cdc8462ea8267faee7e8b7, + 0x14169ccdf08725826332bbd522d72ef94b5dc96d07a18359b0cf770331224d67, + 0x2e8744177cd2849b77040421907fc4a9c356c4cd02ccf32dd8f05386ff3122e2, + 0x1507d5deb9bf6bfa10e2b432b56daac4ca62d302fd8e37a021ecf111eb42018a, + 0x26d7097b3269c5d618a95bafb9b128a872c5c85d770515b2815b581e94c8b9fe, + 0x1c7ab275f1c221bc248d8498dbb05c47f41b97fbdb637bfe155cf1e75849d476, + 0x2673077405cc8bc1e0d88920eae1a797d7a40f9999385be0da776c0326b9206, + 0x23fe81be9b9219be0e6312f29022c7d0cec98da3c51c959852d951d6f1cb638b, + 0x10ba3c183fb3890c360fa562760adb456b01949ef7151ed8ab8103f31c7890a2, + 0x2d5259daac231ce0e74872c4065e14db8b32679927872701bae243f6842c34, + 0x1a637c2706a996ff57c037f4f5ee37501fb3e7de4d067c4c0f5ccf30f9d82a05, + 0x2e6067c558d96831add6dce3f7668546f96cd84c4e227cbce700964431ecefa0, + 0x1a0c5d35fc732851917ce3bd13a7f28f75898537f6ff8eef1a1ff41b4b7ae935, + 0x2edc867095cf941cb1ff7887926a4c8c44ceb1927172e39b362d2f7461bb1b84, + 0x2f2062a65c3fe731e2aea024198e417627f38d6cd91e0a4874a856122a9d965b, + 0x261a9965be69de3ffd74235c3a239e3e374cfe12090f6929e7c4442bfb8b61a0, + 0xe51a7f2109df256ff814fc310a3b08efd5bc160698af9ae219c26603e84b586, + 0x201537485c818bea2b1bc635035c7f92ac4be93b1a732a259e5081c6b10822ff, + 0xb1dc66c364df6ca43e96ce916012cfc49115a6635e8a76a13c56f966991ef4e, + 0x1b70f07090ddb1c480c10557d2f818c2355a0d0112f0448f457196db0ef585e4, + 0x1941694438a139d8dde10865876403207f657a2883117cd3a8cc2e7c5d24f32, + 0xcf031701838c4ceaa490cd36e710d3619ce54048ea826cf23a2c456f245e6ff, + 0x132d7fac73535b2c795ddaaa3a69281704e85097d78ac6e8b1e9e8a7721863f7, + 0x4aeffca0f9922fd0379b69a7fb710b49dcd05026a3f2576a48a6e04f91b630f, + 0x25f5b5001f87bf2581938f3ede0c2a7a35141c7abc3e5bb7bb8601a22a3cf43c, + 0xe7119275a25b2b8a4a6aca534650e84ec72b490a41384d44975ed8c80a2a28a + ], + [ + [ + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x130fc54477fd953377fc23abbd7a41be6764892a8787c759c1440fe0133c852d, + 0x2c9c91f48661771baeef6774578a78f69c355c8e907156fdf26db39d2446413f, + 0x1dec0bafa3e8190621e5e095ef751ea03c836dbb8045b2a73f8d397cfb815192, + 0xa5f52ad6ec4a8aa377d8dd2ae3aaf6eea0c68c63a1d034fbda67133ca0b85cb, + 0x20ab7394bfdab344cbb6f2123800a0e23508e2125bfe795ab4a767cecb4d9306, + 0x110ea322b0c26476c67bfa2c1b9d1713f93b3b9cf8320ce0dcd4b64288bda07a, + 0x54eabe6131681fa01fbc6dbf3e7d53595d0f8809987182142b890ac8af89cbe, + 0x224d811fbdef8ec0a006d376a019e57c93bd596213a07823b7d4abce1fd8e621, + 0xe691fca423128a7d4afcaa582b1a94799ba1f5d2a5d53bc2bba56bbecb227a1, + 0x189e279c92de0bab66707e6e6e310524e615cd4c6aacc665372a3b8e372d8ce6, + 0x1d9bcbbd17b93b1913d2f79cdf12844441237206f0294746d93f8e5bdceb4725, + 0x1179184635a9780ee1312dcc3d15c7ef042b18ae9409670e28c4c7f0fb9b608e, + 0xe48466182ae8333af1891a6aa19736741ed0680d57c931ede13fc07ae82e88b, + 0x1c9d56f71c2f22c44d3a8c17bf5b40452e05471f0b6dfe9ffe4725eb29f73464, + 0x2234546f5e8541e8f72ad794891950b32b1cd891cc66775c5b635961642e9c15, + 0x14c09d155c5d428198c234b553da338f227cbc12b0e42f2b9ce71563ee1495c0 + ], + [ + 0x1440dc2578f44694d18c25f892d98c23cfdb87a772200020e897823d4bc84d3b, + 0x65e134cb8d84447d6ea1e17932bd4a341ebef2568313c24594faf9d7eca2110, + 0x2c6b133e80abef84904fa4a75f968fbaabef890286d5fd11b87a1e52b7eb6d0d, + 0x27c72332f59a00135baa94bde294911d135d1d95f53c52eb8b3b95594374906d, + 0x87488f735b1fe2fa3c6c7148c4968e7f3479b1418a1a566743c1ca215dcfcfc, + 0x19f0e2e141896eae6d56d182b687b8a6c64cbb59e031b749f35822fc7ee353fe, + 0x299c47f1e3ecc557ab1c9abe36f0d2ba0ece01051e07f0858e97a9ce16f5664e, + 0x1a4befe11c0230c62de44ffafea0de903ba328c6d67af73680312b68f9acffda, + 0x140762d30c5c3a0b0750b1400a86a9e2f5cfc2531b729370f3ad9fe1dcd43f96, + 0x180aa4babfa7539753d9c222e5e3359aca59e06bbefc7cf3a3ffa4f961fa1d5b, + 0x17208ea9cd4dc1a6deebe6a8d27a3181ab5f86c6a706e6fd007fc1eb678e9de6, + 0x20007a0f5d37798789e0a8ef683536d9cf4831a6566eb727b41191d9f2974710, + 0x229da441a302929b0bae93741b7c75e11337c797e5721f9d7ee59235cda9a40c, + 0x1137b5c61b9684bec41e4dfaa76438256622a4378ea4e646a2844bbc85bf81cc, + 0x113003c1dc7baf35e4536f95f4eab2f3badda2c7a1c6b5afc956234ade3e7129, + 0x1b61468fab59c925f1986186bcb97965a858523a2582d434319a9525ae71158f, + 0x117fd528770fb17f718e29a2d91a63ec7c39ef1dd3039f0943f717d1804253d5 + ], + [ + 0x23aeeb0c6499b84bfc32ae3c42df9728798fd2ef774f1518b870bc57d1385900, + 0xe76c40392bd5f458bc187be54099312a0fefff44b441637020eb92670a6fcf3, + 0x2ce8546cb59f420ede61692e764e0e9f6715b16a2c8047cd8131c97646f50d24, + 0x16e64661144d816885b32f3f7809703477788268d57c14b1d939a26b29cb7ef3, + 0x6cf0db92f86b2732ee5fb881ef0176012dc4adfd849b9be4de17846a6ce5d99, + 0x18f754a95b0af0e4706ff9024bb135164abd6fc16ee40cc2d6852d88a2ffc9f7, + 0x1cc053a6a4d6f96da77e5e73adb9d49bc4d0ef2cc2f69fade48040b7f8d71386, + 0x1e40665f5bb8c5c0dc9c11f39d47e9d33e717afa31ba74f92f8737a55efe134, + 0x976d7c3844bc8deea0f0337f89b2a131302ffd2d0a870181ca5fd5fb6d4fb63, + 0x2c54287eee368d5d52dfb068282d68e6b09b76bd1b5c9333b36848ac277744f5, + 0x228a3488cabbf9f29efc0bce211a09031972b37f25ea35aca840dc2331a0cf35, + 0x16bae49f5ebb1ffe886b634d215de61ebf4f44d1cdc4f84670df8ed69310bfe2, + 0x2e269dc78f70f9103b2bced3edbd41e156e64910887b4dddf8a3eee960f601b7, + 0x1f4b85552b960d1c18b7b8f66af7305a6773d9b05faf51e0ed1a5f2ef2f95e7d, + 0xd5fb9b0e1503f2b92697c473b69cf76d38fc12912e2c3cb33996dbb0cdfaa38, + 0x11291ef514a10d6f0651e4ad0da5d4a489e3018927879da942defdbdf701ddd, + 0x120e7416d74308e24047f6828c68ae28bc288b216e8a25e8b0ebcf738480e390 + ], + [ + 0x1ed9d3e9276acb7b4dae53eba148806fd9bb07b2dd06187212fab7dcbe63d72c, + 0xb981765ecae69dd7af3b10ffa424b8aeb206cc4f49257265c6753b1cc54ebcf, + 0xadaeaf28776b813d518f645c793e57bf16067fd80eb921dd5a67e895646c9c4, + 0x2018db386a3e4e57eada8d91408b155061df050140fb22f9a4f34fb4e2d02428, + 0x67c4411745db6c6aa659ec737a586a8f4a1cde0352e30aa0063794865fc1c04, + 0x193fe0e9b48010fa319c33b86b6b18f428f323fa237ca918a38faaa91ba49567, + 0x9558ecc58bee4f3c578f62489dd900840a9889096c0a62114aa2db045a1d033, + 0x23c4abfeb83192362aae21b2e9ee5cfc765bf1000f798c3ae70133556abc78bd, + 0x152604201ca7df05994e9d5f058f3b6749cea63aa0cb5b4e1c3a00b6667958e, + 0x2f65361a4aed320fcd03a45c44dda740213571f3975ce20b96bffd960cbc6e25, + 0x22122c6313fc9a4c6d0f944d3ce238272bf35147b1b788aab2b8dbceb6024c76, + 0x229aa5b547a63780d8d129e209fdb92f85662616d59da908075e668fd817822d, + 0x21a91fed8bed14914c4fd491b6fa4dcbae7b3b8b3d456303af886c328abf4699, + 0xba8a54914886fae16700c02efdf7767413a0bec5a19ed0cf0a7d8ac60c1f1c3, + 0x2e164a524ee22eb5a8903fae1f35a3a78f882f3e3a9892b6ff4753baac934949, + 0x2df2fb2c2e321e3cce13d16091705a40c5c795f8b41b61dfd6ae7d97d63578b4, + 0x6995e510fd7669374c39d27903f342ac5bf8a1464807f308bef610b76cb693e + ], + [ + 0x2ff57f3f7e95b03411db790a86647467581197124d217520ef2e6332a5b35185, + 0xe4fb044a9fcb4087e351341f25d98b1399b576e2d6654534f348219a0acdf86, + 0x2086a01b816438a2a41c59e43d73fa9aacf0c24e4f6bac229d65fba59922554a, + 0x12263b7e3f3de60899a2c22fee919972cd79dc289a87f31f1b44baf2439dc87c, + 0x19909241cac50288c0d12343e0c12cf9b9790b405ef0a9001aa6be0289063aa9, + 0x11ff091dd551b6d586203ee0cafae2f7652e923aba82574a53b632a066f4884, + 0x93d7d5563e3ccd0b5f15a9b093fe6b863aacccf9af11ffea9b295b7dd42b1f6, + 0x1669e44bf0223a77f48fffbc9f4f20b5814f6185ae11a210f8fdfcb5f71d603d, + 0x1ab6d8fe39f87bb0ee5b883eea2725caa52c575740d5ac30b058f77113d05239, + 0x235bf178b5b56262d988bfc62708b0f85d57385cde2b4dacf9e6d592deb2afe4, + 0x6649a13e65023a713aaee5387d388e3609ae9b14ba4da10642ee0b7b4a16634, + 0x29a5b1e4e2f25445496adec230ed53a35993b37630aecb5d76e56608d1b78cc6, + 0x29f07c1effc65b5589e1ca52cbe00bd65ef5e962d01200302670b6dce79eeb00, + 0x30289c9678c0330f85cf8e362683a6144f22b841aa08f586f219dd9edaef78bc, + 0x1f9dcbde7d058134a510a711d036d1f1800e473a63b33a7e0fb04dc2e09e3af, + 0x1baaf8ff96bb2224bc34cf80c38bf13086f1e429bceec12090d8a7c376a9a82, + 0x1d814b3c17656c2327f94cc02472780b886b88394f1a5cbe34dc4f44ff134fce + ], + [ + 0x15faefbf8584a38969b4a719ffe5f02c2191a8cceda0b775162203d30b80208b, + 0x303e39ca88e8da6e5c963564712df8a7f8501a7af4a990e4ccec19e5f8fc805d, + 0x2348580de49aac01ce8fcb5aa2b467f6787dd8a96ccecd6fb47df7d5a4307398, + 0x10e420edcb6da76170b24d777ce9d31612edb1593ea6d30e8cfdacfb6974f991, + 0x1d25b94bb7c49c0170ee1fb2a5824b70e4554bcc54b6c8f8cc0cc9d74f19a5e, + 0x1da3e00601ca3fc0d90b197bd2a474b46efe3aff3b2cfaf1ebe15fa1afadf2db, + 0x45dc0579ca66e7e096d4dd86b882e68af2d35d70cf5e3b1783caaa0ec424253, + 0x2d5b3f523a9668cbe4887881bf7b40184f978713e358de270d87a600e5c5c92f, + 0x1b62ba8037a83f1261544c307f019dbea1cc6a84d481ea8960b0fc670745e8ae, + 0x1794ec2b0eeb22fbd753b21fcd949e7bedb305f15a59eaf74a961c3046635f85, + 0x1ed4c95c6283b45ec0cd88f511976f063ea2beb0695b8af7cc10589593a7978c, + 0xbfce7b120068b9a30029dbdb36be01d071e8163fa1724f13c6ca89be29b729e, + 0x506a7a5de6b56ebec5e708a70a3cecb3a2cfd25e7a20ed495e295a93023c5a8, + 0x4890048fcdbde6366761cd58fcc6ac0a3360d9a64233d3ea4d8d6be8a23ec45, + 0x285b20799970b58c63ac9f4af564ce0f28209b61802214da5bfafd0cf24c6712, + 0x7b0d70ccff1b70dad9bb4b0142e3f6dc5bc95d3766affad378cc5042484dec9, + 0x3b90da34b198cbca17e34aac98b169875ecf73aeb5c6ff1f00c9fe535aa9902 + ], + [ + 0x1e6eaab1191593de0d89cbb2399ab8aa955d829ad959428cd539be30b72fde9c, + 0x1b77995dbf30cc55f9d4cd4849ced949349da81239a015440fdb38b876abee5, + 0x1fb6bd6df650d27e8cac05ac0b45eef0700e308b29b4bd41eecff58027edc45c, + 0xebcb358f95f84b719c631d4045cef03ac6fc238f6834522cebd02e47411bb6f, + 0x3274e735db2faf186787528254272ee01967e6ae9d825141378b8354d843965, + 0x4ef41945559c1fb0b2116cb2be1f043bfce8dbc96feecccda47cbf68be59b5, + 0xda02f6410e24058a1e90412cd5302c57197f7b1af2a99496f9cff3ffd58808f, + 0x10c1856f282f556d7cf6d4a293621506724ba6d3c582e4c261842f2a4bdb0ec6, + 0x239abc7c9f866aec28685c26f4e046a92d4360d36cb50890f422e18ed6f8a7b2, + 0x83e1cd5943461ab505b200311bde4003fb4f7ed16aa58c8bc28f2e08e9f6922, + 0x15fe62a69b0438294395da1bfc93272d88797ceeef666ba2443f0c146f8ab7ee, + 0x20055568b33367bc12bf4aed7a0909c173588a5763c6a1a7598ba7c6c7e3c2a5, + 0xc02b148f4a1559b597cd320f00c02b96a7fc7c83811bd86a1e79cc3106b2201, + 0x1a4162e8a7704447be0c1d4d5cf2f777670f4841ea27ac2709cd6bffeed2cebd, + 0xce3dd727fdd11a8bc731500effa23763089ce3332cb730f9fe57146ee204810, + 0x11f28ee5da80d19e31581b566a439537466d9ca7fdf14b7086830bd8ac13c4cb, + 0x27fa77a0658791e6755781c367683f9c9333a41364f7870edff1935a347485d8 + ], + [ + 0x2a3bb020c8a50d310ef5b5c77cc408b077fe2481454754c4568ff668fe5f0974, + 0x23643add30be204734d029cf034c958144551060c1901c420a28c9688ec36a80, + 0x3e9718237c1700d7dd213e026f307e8000b3851467fed9e6f51fa5020c2369c, + 0xc48e2f304f730d48e83dae5c78a46188500bc8040a49542eea5ef1a21b9d222, + 0xcac320362e235b458d6d364cd0fff914f3c056adbb038dc2a861a49f7f70e24, + 0x2f053fdf1a72d6ad8c9df97a04d637916f25e3425b6dc33e99ca7cac5cc7e4c7, + 0x2dfb6dd598ada57ea71a8d68e6924608f0ec7838808688ee4b3fcd521f7be6d2, + 0x22cc4349f6baa3a8e0b61fc40ab97210e4bd3b3dec7f05bb8ef839c84692afbc, + 0x2fed5a03200417664537df8fa30276b85d91bd2ed21de33d901fb4d82439857, + 0x22a67a88776982d6a15f577dcf780ac485ebaae6fdf6fbe50b95ea266a7b6059, + 0x2b079a1d09b9d4a76d4e50c45c01fb7508b1c443a8fb21ebd28533e05def8864, + 0x2df1ff86644fcc42a1932cf15d314eed407608246f14a8098725ff7be809c87e, + 0x24a466f74e99a602894f421010f43a81c708b1b4ad076425190b85347f685b1a, + 0x2e944b449c1369ce9766fa6f4f99a87630b5c1f2d63677a437a537d61b6c7470, + 0x1079746ca51d9518a0c309296ca48206292798910494277be2bb65a6b134b3a, + 0x13d7b03e8fc9fa647fca6cdca97146901df7c675a164913c2bd2a3b6ee3cb4, + 0x6d6ee531ba3fdced05e24cf9103d0962dd227f1de692c0199483e92ab24ba59 + ], + [ + 0x51f815c454b6015c7ebf90c297b90e9604cd36acc6af07f99b5e51fdeb32234, + 0x1946a26ab8953f9be558105fa5179f175e76a24429dad5d532c2ceb3cfea05c9, + 0x925af35a3366801ac80a31d63f745fa807bda10560345ad572bef4cf2ce0d6, + 0xe766f03afbb7af630eaa8aff4fe60f3810f30f3f4438498efe0186333dadc0, + 0x1111ed7a66ba2ccd4bea0d43eec86ea35ab40253a1209e3637f103dcb84fc429, + 0x1daf74842c7e79104349ad399592c5c4cce16f79e1a86f50d941598772cca953, + 0x1057062b40bdcf1fe2aaef45898c871146799a92c87d0fce64302d6bc83172df, + 0x12d019e37cd1bd76fee065bb7380a9bd8331a4dbcd1c9c776792bc19045c23b6, + 0x996cae74d9627ca3c56c646095f39730274d25e82c42ce21cf789253d48a3f0, + 0x2d1188d9e7e6ac24c4b2c9dc3dfcfb0fe4782d689f31b94b1fb15ef29d11f19e, + 0xc34496a7db5abb330b2f6ce9adaef5ae6e308c8fc2c5634097ae352aa7457d4, + 0x1d4fb0f18f31c8270b4636e6b5d7a33e455b1050de1164182cfcb739cce965da, + 0x1fee18888425724970bd2897b54c7fa8e9c367dddbc8484da37864faff9f9056, + 0x22d6e787f44daa6b6593dfde5576d2fdf5dc0447e65a1d5e7712e4e62c3bdcee, + 0x23a85d4f91eda69f310c451d7d480c2f40c0d53382ddd3fcaaae627b9617170e, + 0x2440e786179a7fbcfe8d29ab18d0fc6cfa383cfb747f7a2d15b77d82d9b0d9d3, + 0x1e507921be7c76124879ffce5b62dd0e96259e98cc64c27208d62b40bfe3e482 + ], + [ + 0x28b75c2ac167fdf184725317c7bbb8083e5ac5bba937bcfa6cefcb69e4048bf0, + 0x248b533f875e5ee8e751cefa4b1d0732fcd30151c3a5cc4abbbb1e93b4655d45, + 0xf8692d64a5b69a956c4e2006bfec344477fdf5f0c9aab866609842b9d75269d, + 0x1b8a7909d7e7bd4f0bcc8003968e384ac2e8b405ad05cf610364d3ecb982db7e, + 0x13e736cc70b7c828a38dd6394ece76b9ccdae2ca4f43963432502fe8c2ad19ff, + 0x2ae8da8d0b129a22f834d0d234c8917c2f877ff00dc16215498d4b748fb40df1, + 0x26e6d18aea75a94861a02333b5364ceceaa78adfbb742817218ca3af607b910e, + 0x27aa38fa051c434189df57bafd80723ee29bdccd59fbc1aa9af11891d3722e61, + 0x304dbc0936862356e0024b2a32dfa3085abedbd337f22b89062be614d83cb083, + 0x265c43c886f07d025200d56cd246b01670b3e82ab482f5879b10608cc05a37fc, + 0x4ffe27a92cb4300e774388edc3147ab9dcc4ab354c380f51ca7a2e7fe0463c4, + 0x19d6f1d110d9f873db002ff2ed828905bd6cc5d7921c238d7569daa9b2401d32, + 0x19711c41d76f64a371aba62f3f46710dee0c3aad217b7cb00bd12613b24ef52b, + 0xe08ddb69d5efd949c3d671e4e78e4fc7628c65ec1cfbc18ba6a101aa19dbf66, + 0x240657d67f92b5e4261ace434fd286206c315565378ce8b81661523f0e6ddc54, + 0x56149221712b88ec291fc218324142d02873cdd53199679fce4dfcb5dda9116, + 0x681adaea79cf457db5701931f0ee2f15ecbb159ed50cf746a15b85c6f8a5370 + ], + [ + 0x23af324599683d9b71b61d093d63dcbbd97e44957333d2697fdd060c1e4b585, + 0x2e7a1c51da61dd214a1789d6f1ee2957f69d21b1f16d1f9458eb25a406500bd3, + 0x2bdfe7eb4fa803bc1dc0052a46d850ee3e091eba8a7f12579682f6f6fd5044d4, + 0x1d92e4213d840a330ecbdb08693dbf9a971bbd6229047eb88a03f334cadef227, + 0x1f2805084976b142f7c74a416ff439ff1bcd8b8e7b0570130040754a61b71912, + 0x99b0a6330926a4a1564dfe94f9a1104bb8374bb518a89de08c591c17dfaa059, + 0x565b96659025935d9c025c7ab20b1611db00b67ecc51426b342f8c7a17fed83, + 0xf0b9336db5c16d472fda3fb9ac13b13394c09ab9f484ecf6ad2060217b5896a, + 0x2a7de8f5ff476d81d393f1d274636ca956f05bd422bc9f3cc0fac0054b58cb02, + 0xf26d05e938f8317bd608eff0895d352dca712b653b1492f8c2ea96b26f9381e, + 0x28b73b335c72f0774871a2030d444e5fb954979c1c568e112fb911a46c666768, + 0x282a01e8f2ce09cbdd862f98fdaba3f9af02443edc962cb34802d04477de1e20, + 0x2770d14a220152fa7083040be9b3cd38c8ace9e207073486bcfafcad706748b1, + 0x27a573036509a8a29a90eaa34d2adaed5ed1ec6b207274f3c5ca23dad3880e57, + 0x2384a384bcc2c4a17ff7c9e3e7d131d39173c431333a9c7c1d6fd7110e25902b, + 0x162c5bbc81b44427be4e82c5e5253bd66c3054f5c5b73b28b29238487849a794, + 0x1e6196147508bf2edc872c4e897a967778b119f69fb431a7f646d2018eab4010 + ], + [ + 0x5a07868a7c95f50a015879fe7cdf1eb6c317e4d489d4515208ddf40a32329ea, + 0x2065e374edb1f3cbbd2919dc04d14adb07062dd01ec1501b85522e7e0faf925e, + 0x13bdacc137bbcf51d8bc9d281931d6e71122dc6e93e7ffe8b835e3393775c3d4, + 0xd3b3fb86a44b7422429a249884c85644af1975641206e610070c02ef5a9f4cd, + 0x27aa50a0e5d5588c1486e8e7fc8dda65489fffb866756c218f87e7280cddfa64, + 0xb9aebf041146c119199757ea8ceee5abcea9ec42cdb28b921caf21e84847851, + 0x2776bde52a1259472c1cc020e719f82191dec3ab7699b7d0fd769dd3fe392997, + 0x275a6f59623354d71d38b4e200ce2e9676aab74ea8b8366fce33bdbc47d0586d, + 0x12c6f6c83a3530faced60c88f19a82fd12b7d938a79864ed20a545a52fdce11d, + 0x257689a4e22f6a8768aafe54218d31de4e409fdbf42319582536bb583313a395, + 0x195821b99af2c217404ee582e29889072ba3cd994b74955c261b5ad364e5a9c7, + 0x304b679008e8a1f09448423a05889e0df663a2b65055ca9ee5a99dfe13fb9a16, + 0x8dffe684aa33f911d35e9a644b4bdbfcd15a4da49b6531816b60e8ce4f6b5e0, + 0x72372083f62195bcc2b5afab1038198a3f0546b62d171ea21c37c8f31551176, + 0x25547b51b2c6874e4538ca9b34093b714ad36a8f356e4c78e0d66b1f190038fb, + 0x178f2aa8df9a11ef33558dcc934971f7697e626cfef00ffcdeb6f3c9c1a7d10a, + 0x68efa35bc620124ab7d88990171bae4102ad21dfddfb387df0de0c8a3a189e9 + ], + [ + 0x2c5b4a65bc55ac5fbeebde53ce5fa68882faed2a92a7b3f5732832c72f7f2c30, + 0x2f36535a83a09cf09fc38a20a725477aec56668f034a364a9f4a5605fffd33cc, + 0x7d78ce0c1c87391a06a06c83d300d52524b29f183884e300e0eaddacd05f068, + 0x25c7e8faf6c48a156cb91d81a997c6673d32694a3fdd64f5e9594e9f504bad83, + 0x1f3cc6f65d9d34370825a38fd1f48f509f7c56171b9e7a624d9b0ecdf6ac4eab, + 0x55ef271e388278b1aca34d3cb00116bd6f7cb584b3c69f0de2a7afc8d98deb8, + 0xc1a324c49d15f87931821989b8c8437ea9eb46ed3aacf8895fd1cc311053e60, + 0x2ebb6730d7bafeac23fc0b457ea824eeea3c55eca634bf24b2ac2a9a21483e1, + 0x201e03f1ff672629473a24f32d2d502acdc8fdd2883014de74c98f40a195b3e4, + 0x1edc57f174e1322b627c6f9dbe27ae2703c3f11c364b38188bf41d8ca0c1709a, + 0x20a56fce37122b7400ab61a65eac815dd180f52fad2835f7fd9649063523881e, + 0x1998147edaf3a92ab179c61ac2c36af5caf3e78bcbfb684cfea15db17b835907, + 0x1cbfab7cb05e2f28254b230bfce017f005fb4f2dd8935ad11765b347d2003667, + 0x151e0bc2110e4300dd82a4c92442c4751c65b294426c8c320c69e61831958ceb, + 0xe59e1a990ec00f72edc37248349d7a5a6f7bcaef158110450f1e5985f0a5d99, + 0x24afd92f80e57788f40fbb2b79f29454dc485fbafb5a7263f462b7c84b4e500b, + 0x1b012224a4f050df841122d17c5ea4eded7c8ec2034743a432a2cee893976f29 + ], + [ + 0x173f895e472c4eb16a2aff3b8e0417fb32b83eb1e3233471c76a0550505d0607, + 0x1123d3c97ff8e6b589d118bc40ca0b9ac12ae909558f2582551f7a42345b4621, + 0x984c132b29a05f2b506ca07c06fe9a6584f36bb87506d2d316a4f353cac5f1f, + 0x2d7af834c9cdf1b38c8cfed218f1ef0ce0b9908de9e7aa7a5510c4fb917a0281, + 0x1b11713791ea4cb2e17c8c5867502043d0a8cf955384c1c793c506b75fc0db29, + 0x26fbf1a351963fbbdab590dbd760ce6284273525a1b46c41f29226c65339f4b3, + 0x27e68568e9cffd07f9253ef9dbc356251dc6b2d6a903d6c7046b5e90e1bcdc9a, + 0xff215eb1e38dc67432e262df27eda7c3aa9419d5b6e299bd948e970fc35a62f, + 0x118c3efe920c9c3f907c867743d35d2ccbff7c89e9c31bb6a17c552ef92b6c01, + 0x17b39f38636d5eff5e06eff089eb56051a602bc8f4bf1bb0ad2b2cd10cf07138, + 0x235132912db2da07a4750c5ed5df2590e718404aefc48be6953432f64424042e, + 0x28a4572cb654261cf9358435923e65aff8f40393752748b76acfd2e3f5755c9, + 0x21d7269a53d3712b20543b0039aecc9466520133d299e8442000b33184a39e84, + 0x13f1acc389c4f8e752cc7e4b81c37ae2130c60df9c8b7e87dc5fb7459caf4916, + 0x66c6090936f6b054f17dea91682954332b3e32d8f20a0ae171d417316d3622f, + 0x492ae5f5ac2a5102ea96e60ac8375553687151ae44042dbf5899232c8f2100a, + 0x208d814151bcdcddfcf835a958c259a6477bfe4b3392710edf9d80787a25c5d0 + ], + [ + 0x206cb038cc328526d0c3dc5af19437d83219751c5ee8f61b0e9e2f5881366be3, + 0x160b30c874d9c06704c92c266c7a5b7fd966a62a5db008f1bffdf443b1099a82, + 0x1b00faa85136b1bfc496e0ea9a6284cae525aa96612ffeeb514808955693879e, + 0x175af5e50e5685ec2dbb1cf7a2cd25d45680f6cddf68d7c0795dec98b87f6a71, + 0x104560e95c49febb7a030862edb3a33c2b2a3d414b0536b2e54e25ab36e8f281, + 0x12fd67863b2e03b6fb45224fb041ff280e936742b54c8e54d3823e090e144169, + 0x1db0e7e01722aad210e5296c36e9103e82d15765c318134d177146a1d9fd5358, + 0x247f9c7fa610322535feb0676cff549f1c177d0d39d3f1eee642e9253aafb82d, + 0xf705feba5f01cb27b27c104bc93f0c974f561fa26d5614f6a9d9e47d03bc655, + 0x306094ecfe63300b2f95bc98a0406c7898d86852330a7b69f9b04b5404b3eef3, + 0x1059db5e97f25826b0bbefd6bfaa6e9496c55ef5a88fefe9712691f6fbdf4298, + 0x15bd998c2729dbeaccc29b5d6e4f0fd96ad0a6037c84a1a1a785169fb336fb6e, + 0x21fde580a19886b13358f18a32d5aff685b4bd77d94f067f44f6e7a93350fd2a, + 0x6823a9baa55623732b02fa270b2f887fd3804a85c1a7f2a355df3fbefc69dc1, + 0x1b25662843b0986ab1a4e9a766193efca47c70d49364f03d50c5edb5b5517ebe, + 0x10dcb11f815c7e29c66be1dd3c5f7602c98e9fb1687c2d825b48789c521fbd0b, + 0x28f901fcaa860b0dc4192adef8ea4ae55af6ce432c85e0ce4d073e514ab24252 + ], + [ + 0x240c57897161666f28d000b88d3353921d967420f401ce86bbee42be287a4f8, + 0x1361d27c42a7b4bd6eaeb98a339592616c0d4d8fceadfdb16468162bdfa88d46, + 0x19e1e46536704ceceac3eab991bd806e347be40a0b7956dcd7037352fdbc4347, + 0x121f4a18d7b7d9650aab625ebe8695a8079439f2ab00c090279de74726234e6e, + 0x8c45f3c4c486f6b5378c779c607b517200bb70b5533bdacef18519f625b925b, + 0x600cf26635b2d546431507589739010d1b757ceaae617bf95b8e1efa98643d, + 0xaef8a4e47d5ec760e0565ae7acdabe7e8e98972de86dd2f447aaf216ab4cc17, + 0x2ad0bd9f71e2785084aa0b84616b7dada053207c418e65f4035be66a0cdc8c12, + 0x28d327a1c2d6012d9e69e9a3b4c11ad336d3c0dcdff4c5c84ddddf911eb645f5, + 0x11afecc85590543bd2df8ab952be164670a3f32593e962d4bd493bcd3c84f84d, + 0xb050c882073a581e767223705cd9510c04c30168c50ffe0c9875a28b6938299, + 0x7cdf3309e130f9ceddd688af3885369fbacf6d8a44de4d450667c0d7641213f, + 0x5232bf95807e48ad82a1eb4bc481e9b0720e95196dfe361f55c4d1cfc7926d7, + 0x1e41936e6bc0c3ed665c2e2466ab9216b9973fe136d9f9aad95878c1b5607c6e, + 0x2647635477ee5fa9e7ac5983f92db34d7336646c63c63e2dd53d60b8714bd759, + 0xa11d587cb75d48544eec662ad27ca6acfec98f7a8b7963a294e4bb329b170df, + 0x1bd639879731823c871f9cd4714e3cc56a6eb19884b73664eed24b11929119a0 + ], + [ + 0x1aaefc2e9925fcd453996fda804063fdab276b37c5f51dfdfef9255b4ec10cc0, + 0xf1e8f86860c3b5c78bc14dfb67d22c6beb8992123658842f23f75ae3a92e99, + 0x19c2540bbb1cd4e08f105437063c945cfef28ae9dd50b97e0b795f8dc5ae34e2, + 0x21f08f9b3c23f3a02518114a96929b6d1056eb4d1db147ce0c8882e1b0f7bd1b, + 0x2d2193c677bbcd56a74fc2ae50ab4f2cc69aa77ccfc33c7707452d5adac77edb, + 0xf528f5912be49455d4323b259e30ce2984d8170601eeb4bd7096b47353ab7fc, + 0x8c00c4e5b3467f01901f64f9f89c15bb0b90918d488b730cacc3296691e9200, + 0xfc3ccef00d6a64080abbed4fed90b69c5e5803134c22b42cdca0a60f03ec33c, + 0x1bce67f4dc99547f2caff1b5c6d63e3ee2565a404190664533c1c65dd9d8d532, + 0x1a8ba4f37d2315389c8560d74dac572a4447a02145516287053e6b9edefbca2d, + 0x115e60c4e2937eb53c6e4a5488f801266e84d07547a0b1cd91b18f49efef9920, + 0x152d47acb9b06c9d12c2138a31416bbbbb991a65dc4d4f8ef91a3dd728e63b6a, + 0x13602646b88ba31c0d544c757bd9181727835dbe690c30583a23f37f52fe5e3d, + 0x65766d2980331a55c0a39d83be78bd127baee77d53a24268e064c71daaf2b6a, + 0x26db2e85a9006ef5c11cd675a267d42efef9f5af90466b2aaf75eea8024b00bb, + 0x1dd6b095cb68459dcf6bdadd434aa81f80a55a08e6782c653a93afd8a65f3267, + 0x1d3ee85f078fbeecda2473efc2bedd1ba7ec6f4795faaeae3b0de48d3080c625 + ] + ], + [ +[ +0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, +0x197fc9fb21309218eb702b935044146cd33407ed33291cc599340b271c399668, +0xe8ab972df74eec491e4b8c416b4a97c3fe65a38d4e76093ebed05ff3e7d750f, +0x17af7102238531c988dc665323d3e3348ca13eff7d006be181cfca573bd77e79, +0x1b0b5e35d65981e836663ab49379580a659e1dda0d8c49c189b8078bcfdd3f0d, +0x1aa303c6d0552d6fa013df27f7f4aa907d10da9cb9e0881ef2db7ec1a74abbf5, +0xf4eea81fe11aa323228b430a2f9021e2639d66596b3821e131cd8fd5fafa0a7, +0x1b47097a86346051d2d42d6810ee8f3fa3b992b90c009040095fe8357b6be24f, +0x77cdf97e2049e1764e7169aa4ec11ed314badde9e84218bcff380ffebe45382, +0xb4d6879a54ebc4b74422f70789c1b7a47694f6bc0f88624ad0141721a89f73b, +0x14ba91f29fb5987a1d3dcab55e35edd10de3acf4199d877b5c6623b5a6ef8d9b, +0x1fabc01bf1091b88001e832b7ecaee26e5eb867f85b8f1c083832b1db57537a0, +0xb4d4c2920ec03187d1ff531b4cc1b879c7321315d7aeac09b53bad9439ec93, +0x2191792ed6ddd6c3ea8ae009cfd1174fb9efc01482488c101502e34db953815f, +0x162b05a1204ae66ca80d0a89e10426ee4d757f9b34ccf08c1aac697c55245980, +0x251575500ce3526f4b190061361eb2576591f9ef2f0a7ff9a7005efc3c71263c, +0x4384592e42ace8c8014f728704ad93695e50a16c5199d5815e00ce818ed8081 +], +[ +0x1440dc2578f44694d18c25f892d98c23cfdb87a772200020e897823d4bc84d3b, +0x2ff15351b14d1b852edfd01a8ef108ab001a10c8d66e887daf1817a315289259, +0x2fdcdec10d3354953fa9ca8769a3799d001626bb715f19a97e772f2ba1abc421, +0x146deec0773f075175a208469afb87199d1b063c994b98125db22e85844fb455, +0x20f00881fb533be89b9246780df72a26ecb103c554b9b6fb17844fddccb235f7, +0xb419e6fc9348d7c69dc15b49fa148232740635cf2e39904cb5bf7e4e1c85292, +0xc6321d9f04dfd91a4fc850ab7d1f7fa66de38d67faac26599ac62c80784319, +0x12784ae3aa761f38e035e7ee5f21242e28df65235da8599d80a93646dfdcbe9, +0x1e09ddd18fdc3c46c7b2aaf6cfd942c62720cd1630b63dca72b42b4a6409c5a2, +0x2a71a3a65e49942b825245aa127bac8dde2a6fca570c8365d3251b146dcd078c, +0x197d178b0f91d12bfaef18f402635554efba7da59bf45f6daaf3eeba444c3bc1, +0xcf6927b15b1b9df1656581cabd0909b7ee2f1dca0258e183b07b030b5db3320, +0x284151191b230312298ca0d1cc6fbf122b435f7e8de25d9d1927322b0b5a84f7, +0xcb8f5333099700c6d37c787c67bf7fa6ad5e35c32fc1a539a8df57b910257ca, +0x15d5a61db8e06697df1da0f06916eb32d90e86ddc53d177abbc7ccc86f14188, +0x2a9b60e4ae169f3d5fcb4bdd705d89e0a9361e239bc3417c30a42ce645e76d6b, +0x883b0b606695b0c96a67ccf221ab0169eba895363e66ca88425ce3700c0e7d4 +], +[ +0x23aeeb0c6499b84bfc32ae3c42df9728798fd2ef774f1518b870bc57d1385900, +0x101e7e35808991e8cdb0627796f331b89f2646cf0263924aa6003460b351a940, +0x2bb568a99f55bea84bbf76dbf0f54d5f1331ffa1f62d686f3709a56662e51931, +0xceed1b75b2f6ef1438b751e8ad4dea24f1a20f1d9a23589772db49baf9932f5, +0x2af501312e1b653155ec7f8e0e59649b2d078f5ce5121be83fa716e1b5dab2be, +0x152fdbabfe1a0ded6e2ba5497e140ecd1dbc9fa8df6705237fc8c764317ac751, +0xdf66c437cbccd268bdc448cbb706f4b179ba223b6bb87a921094257baf2b69d, +0x15e5521c580b9faa337d9ba06514ac965c373a2e604305b8efb0aad802e72a21, +0x9a09a903ce4f69ab99dd47c16087feca6fc2126ebc4cfd8def7a0253303f866, +0x2bb52dc2028e9887b2a82271ac46f7800dd147e706370ee5edb35b9550cf71b2, +0x9bf3d01f97e22646505f76fdd396b026bc8bcba0e0522ed2ba3079d301fdd88, +0x26b72c368b0bd0103cb7dcca08e68b4446ee788ef6114f6ba899202f1f19b5b1, +0x2bcbae8d5471d562e885b4b185b56ae0fe11ca5bf5461a1e0a41205568525f43, +0x805d6862cafcf5030ab30262a01f2c65b2b7312ac9279baed50c177516bd0dd, +0x2b8b1aa994b54ee5617766dc812d15d3cabf187d8db4ab8da85130f73f01e746, +0x1fed5b75b01e9f4af01ebd30a6f355e8b2cd88f19e49892a19403a895fcf284d, +0x17ee0034bef77cbb115fdd75be9880008af568ed633eb7b2abdf8361c4357500 +], +[ +0x1ed9d3e9276acb7b4dae53eba148806fd9bb07b2dd06187212fab7dcbe63d72c, +0x2c05638ae2f83e73ac9b1bac220509e30ff5757342ccad17261a4c30e3bc634b, +0xf1fa08e424e4691c66bf0a524b81e886da234ba5bbf78cc168c8a13353c9654, +0x1ee32a96f8d3e8fde8ffba0fcd72859847861b8143052e212bb56b103f6f742d, +0x20192d8adf841e5dc110994238180267954de29c8953738ae196447acb182a7a, +0x2419a609a380157d9f6c6e64ae2cfb6e4b39e0d6ec0661b546c1552a620f19c8, +0x3ce58f147c681728f2a2af586144d470e2231e80161f97200b7aa6d624b8bf9, +0x12aba963e415f9bbc95c5f1ca8affd59b6c6b03fcccdccb417a9d89a4eebfb32, +0x167f26eedae299f0e56157c8c7fdda1ecb48f90e553ecdbd4ef35b92ef9f39f9, +0x486a139560dd70e9054321196ddb973e7db09350cdacde3c1c7817fd2b8a46d, +0x1e4a632c34dad41873c541c5caeda02bf58f2127994bca0b0780bceae409256d, +0xa471e606e256e387d5e44d8de55dcdd833b364baf00a694b52e3c10f21f814c, +0xc52f1224066c212a3667bb2beeda181ea00294c5aab9348e5a71d696c8fcd20, +0x1b2e51bf0afc16188b7ec633248eacbdc550f592c742edc91b204d49dfac42a1, +0x25da91e9be50e3762edb77a90706df802461c374a7b90fb2ac018930f3b23518, +0x29db9bd9f3940384f177d7634721451ddd0c6a868fd047161c2358e9c305ad24, +0x7062de34f5c74ad5822948fb7c476255fd03a13d9d8781262712946db22156 +], +[ +0x2ff57f3f7e95b03411db790a86647467581197124d217520ef2e6332a5b35185, +0x27ca7b8c33207e75a42cba1237e0c568d3b31f475424d23a9fd0ba6ef188df9c, +0x1b6aeec49e5936a23d2182de5ca78ca56d4ffe8589d3e77d07a34692a7c5b44c, +0x5e94c1b81bbe16e77c7fd2db254949046cb85834c34e0d8986bff72ed22f6f0, +0x24a01b8801b2865c3a3d20b6f31df95350f5caa9ea158b3ac240ceb81c8f6cda, +0x18c647eabc6fb45dec61bdf9007f83863fb6b7827b23437e10e49baf8e835ca5, +0x523cbdc5787c220da27bcd517d57bf3b31cff9e4e2e97299d44d9f838d96465, +0x1799989ebc4fbcb84e487b4e42f0e4500c309c2d90e740d03f8f9bceda208616, +0x254d90f21c923e30fcb471688f64a6115f0f4340b744c5d732a077f5fd6b46aa, +0x10d8f1c90a94db10a7b730d8c21c69e793cc985e1ef2c62b8815e65c5fa91962, +0x1032ccd20d4ed4502df7faae0b2d9bf2c5368304a24611597d7651733053ce46, +0x39bed2152c1cc38fd8a0addd226c2b5d53097f83d826f7e9b9a3556a32c8001, +0x261d68c368aeeefc167d6b3e2d22be484231b5b800b51394133c7baeef2f879a, +0x28893305254197bef603078e333db361dec1a7775813bd95d39e386729cc665, +0x2f570c80d99ea49bbd76c199e961db6bf59ba6e0a47683923716f9e10e913221, +0x2318f3a1f9ef5c6326960014e622db56d8adfc885e3d0bc2d06e86ec07b156c4, +0x7946f795fb6251bbe041138607f0ee6e1243dca71d592cad53f634dffd91ccf +], +[ +0x15faefbf8584a38969b4a719ffe5f02c2191a8cceda0b775162203d30b80208b, +0x1dd8c52fbcd6e06ceddbc122ffcc656e4c28ae2e88b94da79f3a276bf5fe2acf, +0x2915408b3b7c2cf127999ef3a84a0a5c2de70e75bcb06ebac67c73ad36cd7153, +0x2e655f7e6277f2147665a414632eb3a418acd90f6a29748e4249f6713d54007e, +0xe0dedcb898406ec36e1ad2e3992b99c8b457ccaba2105b4436ba840e89bf0d0, +0x270a85dcfc9c8f202cdca355246fd989551495ec57f8b6533342e3af8a1e6d85, +0x494b4c62731baf8f3338f2cc0dd934f82606e768f563a755cc501504a50a9c6, +0x17061fdaa032097e06c003d9d719d29df4c30109d6fb86def324435e8176bbe, +0xf9e56a5af5386c4884ca7d0e7792a22d3b96a801f3e8e79a6ac6578c1ee0a75, +0x24a746819bb8574eed44e23319cefdd09c0e8c2dd1ce6924a63ffae59eb1a905, +0x703bfec7b532b9135f72a794d9e3a3c6ff665c08d590677026a06cda66055e9, +0x21bf1e826a3e2141ad2cd0c6b286146b530927f0ddca59fa78d06a36564b7a3f, +0x2f678070c83d71945038501c74ba5968b131939a6af6edb297de5f345e6692e5, +0x1c30abb88b3fb7fff8e97da6107209d608fbd9f2db97e61d74dff19d3e36f3bd, +0x2a14fabf9e37f4497914de5868daa628ef3347a611f675d94ef67fc317e28328, +0x9ea8d820c4e6ee47a4fcbfba19cd94e915de9dda25afd1399c921b1b7666854, +0x106d7b2ded46945b3901ef651245d519ae93b8d2eea8160970ed07fcb6f58015 +], +[ +0x1e6eaab1191593de0d89cbb2399ab8aa955d829ad959428cd539be30b72fde9c, +0x12f17c280efa40df0fafdb7148d7ae86b6401f823e47854b7f11c0a87ff00bf5, +0x2fd97c7d4e331e328d3eda047a68a64f7cac867b6bd3795e2932f350644374a4, +0x2c1c8f60b63e8cbba016d475ba0483d001c70653c1ebc256c51e18975371cf08, +0xfb2d646b505c61dc54f56fe9de66641c6797e59e860528aeb52867aabafc2fe, +0x1a44835e3e9620a13fdc072c1212e942ee95e683d6c07ef097527bc10616c622, +0x192e49c626530d5965c53dc6e4209856d71226aa5021b9eaaa1784044c8baaab, +0x80fa9dddf985137bcfe965068449cb6eb36b1ddb1706d8632864e954f5ac59, +0xff1355d96389f7c74b274950b3f70a3d74bbfe992860c7ba6d9066e59260c30, +0x237f4f3d794bd3a23cc52c74e0ee10dca1d4edd90a3a519af54944ac91deacc5, +0x1c94985507159d367f2aa5a1a04857bd44d205ef8439b844386b025976646bd2, +0x286fb15e9ab4224c0319add3a16b8c82dc71931fe3be2f4b3ff0289a5319c4ac, +0x236262438ed3acbbf4bd56c39d12be65fdc0126562bcd5468a49da6ba33fc9aa, +0xf695879295d610d1edb0da7c3fa43c3633e2d02d2e6af6799a2da41e41c3687, +0x22949d27c373e4447e9814d6f189d064b3b092b4480f8d21c8c12342a956cda6, +0xbe0a5f05b6f2deb2fb6bf836805d52d9ad224e8bb8af6e0ffb194a49ce026f3, +0x3070888a62ededfae0d72f144b8ab370f8a54c52597db33d98c24edf1daba0d +], +[ +0x2a3bb020c8a50d310ef5b5c77cc408b077fe2481454754c4568ff668fe5f0974, +0x1399820ddf4829a24bfacbe47f56b793117f599efdfcf9e042bd5780fabc29c4, +0x2303c2e89a14828a19a9f75d97f17fe08b6282fbc090e6dd69a4d780032624b6, +0x1f7a5f8fd30b1f9d7f5855c084e8995367889a1a076da17859cdbbfc8301afc9, +0x14f79e9e9c5998e8cbf5a2f1de18ca7707f5627b5637dcd962725f8ea1804d3c, +0x10199cfd4b1cca1f0cadacfcb429b44bcf83e13ccc098d908163aeaa1cf5a9a, +0x34459376fe4246c7ca6f298180c2150367ec05ede0dafdc4806d34e44c180fc, +0x2933eb342796a75af7e1dc15c04904b5f68bb56ac0478a85233a588509edae0e, +0xed494f6fb5598ab0a0a7c655890ddf4a7c0684f24522d2af98dbeb0204791e3, +0x228e31df905565ece7246c261aa5b700f60f6ddd5d7c249264748ab3e521a20d, +0xd36f7669a52260da523b388c608dc283f107e9578e0bcbe1e3d4201b6d5bfc, +0x2ee63ea38cc2cee0e08789581cb31eee9b112dd61e4032a8beebedceb6aaafe3, +0x2be13746d4b19b770fe382bc7e7a56e805c1ade0c9236e3e28f90a5fa874296e, +0x916249fbbb750e41ce6f9475e6cf6337ca4ace63f7a4a377c14fda9c7b205ad, +0x17855df635fe8e7fc7919412106e9852ecc57aa0b759b490cfc4773078016f53, +0xebb48f5378773ec048ac3eb5c84d44cb2585583ce45ff30a93721d70f289d0c, +0x33106bbde7d027db2f728b2563a62d3d6f8a02ae114bfb8a2593c6a2fc15524 +], +[ +0x51f815c454b6015c7ebf90c297b90e9604cd36acc6af07f99b5e51fdeb32234, +0xa44004794fbddceeac78010d88b2146984c75553cec26164754d72598358b37, +0x22423aac5a0b511923d747148e091d1945c252a77e51bcc62ee173c5483f80ab, +0x1e14c0a17f23e94ac435bb7f629c6c0ab66fca8c4db085fc56be0ad9da545827, +0x1958d6547accfb884d50229a4fd5b234a377f5c671fb865170d0a393680ba3de, +0x14bcc6d4b8326e66b453691e5c948a80a618b4f7ecdc3a380478d43dd4075ab8, +0x193025256b9871e2afebc966ed68f38d2f906a4870652805e4246353f567c5bb, +0x1e4200bffb9ca4e47bb270a09e8fd994093dbd4805c4cc15185ced28ff872e10, +0x1d1fa5a83742eb9bb853197f56a4732625b2474e7aadb9311dfbdc0f41ac61be, +0x2d650daa87c7e1c09b53b10595bab1e14c32a67142092876c57b4ba68efafd51, +0x33319bd5b5247a3cb7f63dae46dbd8136f3f3a9b4aa0a232309070d718f7d47, +0x26e56b19e55c9bb5df436c13eb6deffab5059804552442370be53a951b0a9e22, +0x1a0f0930bbea65ad095174ed8aaeaa84628d35471bdad37bdd624d2eedb6bf14, +0x297921088a94bfeeea233c91483a21bc59982034e0c8738c6526cd44f9a11306, +0x1082b0f264c61f37b71fad404cbc0207f809cf8002a7e39c0290d88a48120356, +0x25cc52901aebcb35f9ce47457bbc4507bba219c88a5bd1229f6dc46c503c769e, +0x2ae1b5b3e89117e08bb7385e0b711de334e8fdcbb50ea4bb3718d5e1a0bc8075 +], +[ +0x28b75c2ac167fdf184725317c7bbb8083e5ac5bba937bcfa6cefcb69e4048bf0, +0x4eb2ffac1de16288f52a4b74101cb73d53addd56bbed326bec180ed2363c224, +0x2bd52a360f3328d5c98a6b2de15df151e997cc92c2c72e542819e317c0ee1d2c, +0xff14782906fd866584bb5e93cd18678c22e320ddc66d6fe0e917e18de1094f7, +0xa4a053ffb41f84af21407c6151dc5496a9651a519e317664ecdedb017e3c50a, +0x19dfcf535e723327add95d36e7276afb472408699d7212f34abe32f808b4d292, +0x155dd9ca7898b0559b3e407149e6dd64bed6f9811d59b1ceca7486a110ec99aa, +0x2d9c5bcd84c97759e28dbfdbe9fce6b3c1cc7cbc9a2e35f2ce8a8bdc80a3154b, +0x1ff3d01d32a70fa0911119ebbcb4bcfc1b4fc30b2ec2298832f5da4dce3d7a4e, +0x44ce295745ded1737be0bf68729d669efc18e7e9b55e6ef65f895e2f9e95056, +0x117377429e138736228d8762c8c6567a936980b7c043882adad3951b9986859a, +0x39c17d50605261dabc76676120b2b889ae504138ba722976d8dc822bd1af974, +0x2a6f067cfc9dc40850f552ab42d6c096da045f8039453d7a9e028c39f2f1377c, +0x1d7e961151f8a1d1f6092f102a7c911194618a3bae9ef78de349a99ee05ef476, +0x20431e5d3bcff4bd90372a1eb637c04536317a81b02b48b5a3ae45a4e8380527, +0x116b0dcbc35fae766914fc09cfc359051f626100151eeb2a762d7a0738132a30, +0xab340604e81eb37a5dcbf1e7d5ffde8f2221d60b382d43cf75a0f1360ea5c72 +], +[ +0x23af324599683d9b71b61d093d63dcbbd97e44957333d2697fdd060c1e4b585, +0xb11660056e02d7f845b79d49bfbb685555febb54eaa503d987ca5299521d16d, +0x1f209382e3fcb44eb1b1c03dc2be195b3f92faa9c1ae1a0b57c4df69e7a53d51, +0x22e25afcf23ec18a36471d593ebc8d93372315cd666db66bf398f7730285f9ae, +0x18eaff4c9d5d00d3483d7b0c74551a4487c452cf672e6a74ca397be38f5d793f, +0x1ebb9f7b5f7f0c553b03552d104693515ccc17529c6c1a462c0c24473630f678, +0x1212ba1ac3bfe0c08096c503be351bbaea92aa3d3f6c264b73c7ceda7f8bd721, +0x2f0256f9b47269790f3f2b46a7ef2536d8661dae60d50a61bab58346e83885c0, +0x1b6a8442e48b709797a514e36c1f86b13a413eb1f7fef458887833ef4b482124, +0xc96e617f36391cc516eb3631eb8a18d4dd10d17135bd93f450ef6ae2a945117, +0xed9dc15c9f4a60f8150e367ba71a4a37a9cb50c9031194f55850a1e5e325911, +0x2b8b201e13900e638685cdb4d07c110a8f8e8d500cee83566aa733621cc20235, +0x23bf4e044f678ba1fef62ce070897d6373914ee936f92a2f4d5e09890e238e34, +0x22c93d459ac5db54f2b6a4f267b5f049b976a93d006b88a98a5fc0ea39f53a72, +0x1a54b0b47d98fe83acc4dfaf83b8bf7d972684923d5c7dcea9894b6a07d934ab, +0x22ccb3842b2d75a33b65465a5dcece6870afabb3e3401faeb6504de406348a23, +0x1e9abeacdd2ff75cca093b6d8826a46d8d2c05e30d1d3995da76a4a8ca9d2824 +], +[ +0x5a07868a7c95f50a015879fe7cdf1eb6c317e4d489d4515208ddf40a32329ea, +0x28c53ca5db5ceccab548d154ea6071e47ca73b6cd4fda7e423403cb684d3070e, +0x651a487e9ef91d9c4fd75178dc57aa1f76edf56c4c5c2ba6ea7c6d919e91440, +0x16d216f97bdea9f8b01025cb47acd5d03e8469dc6b558a235a23d2ba8773c71e, +0x2c8a5c7f394b071d0f329d51e451c8738f896a2b8f87c6eb3eaaec71ce1cf71c, +0x132175ccda95488f348ba37b6c3641dfbca9e4247ec43977e279f844330cb694, +0x28eba78439ba284229de2b1c6124fdde36323fc82805988501337a3b48aea040, +0x140f550b1cfe4079f7c44efcca6515f70a9ea190d2cb4a2cf116719737b15621, +0x1fa08142c4cf49ceb13532ff6f1c453f9ac4035d8ec5514f4f3b52c3dea9bb0e, +0x592cf45e5a2dd382f1c6ecb059c99232e2b52bac5475c10b6669698cae88827, +0x2897ccf4f75df225ab5b1c79de477945b24f2ea127c5cbb37954370505957a31, +0x288ec4309c81a0d2ecf16c037706ea4d526d717285ae02da008d14cb8ea23ec2, +0x12bd882b0d8af801ae2579a884b11f80f1ba15f48741f61609466bf04f68cefb, +0x2bbaca431e1d464281a1e6f483cb4e9b2002d0a0ba1fa70b60c1bececddb1e79, +0x173087cac123e07a0324ea3c2231cca859d7e4d112c8e2f4dc9249551c941007, +0xbabc1aa6aa0d7b234fe81651f7b6d616607fa766534d5baee6f63bf02995fed, +0x233f5274aab1d107af4bf7f2b7f4d57d8ee0936005a3525549cbfc75697ca640 +], +[ +0x2c5b4a65bc55ac5fbeebde53ce5fa68882faed2a92a7b3f5732832c72f7f2c30, +0x17d5e7e1862b3708cba3d41c556b070da60b73fc3ef198227f2dad5b202d5c9a, +0x1d7ef8564a9ac7dce945477d529ace63481ace463a86cbdc1140645ed57d0b3b, +0x1edca4960596d41548199aee6040d39d814e4562492a070730982f9755615117, +0x258655ae996ae6e4deba6fecf1190c2afbfc1dbe82454558a18bdc9819442f05, +0x279a42b218cc556132ecaf5666c04e89984f5ffba4225281d3261a48bec6eab9, +0x24605ce4aaa33a0bbc08d586cafd70bcf4c635bedcf98afc3fb0dd32909e8ff, +0x292481a792f2dd4979b04822d73eec02e90c1e4ea42ca5414989ba04c31529c0, +0x19f8effcd417b79016b57398a7bab72f946e75d8628f569f327df5c6832907a1, +0x279c71db7cc16b9c726b934545c2fdb75d956d16f89210aedfd7dbb4f1d9ecfe, +0x16f4afc47a61df3374a702f2800a3a39fb4450a9f92e11e240cc6d76c252de41, +0x1ba7d8b083eb0e83cf9178efe8514e612a5d3905cb9e4279b1c09ae53e8cf23a, +0xa1e2e12a51722b6e0acb9705c443d148b1334dd897185eedd4c4e87170e42c3, +0x1d6b7bb51eb9ba719799096e5e0c1aaa594456cbf08b2bf9a479279f7524d3f, +0x1129fb969355253e7cb31fa942978db34b7ccd3bc0d0cd02ba6a49e159d1cc7, +0x23e3f31479550cb197235af10741c376d326f85881d1f1076882c928212f8b9a, +0x1ac5a27a1a2ea0d7035f74d3a9b54b671e58711d79c87b56d32e40983b62c8d5 +], +[ +0x173f895e472c4eb16a2aff3b8e0417fb32b83eb1e3233471c76a0550505d0607, +0x500a676c5cd159e6351ef8d2b567646fb4d4c61d3c0b828ec201d4f425991ce, +0x1aba42213aa1f15e7550ca941d9bc485e195ac204c5036afee992a967fadc501, +0x20ebc05e620d2c7c362f8d7916ed7e3e12802cdf41c87b06790c40f5efdf724c, +0x191531c0fa2c547a1eb51cb026e79cd663abf458a2e8630e83c1f11876aeccea, +0x1ff17bff476047fd9a466842c8fbd711c1b3c1841e109c687ba4620ebc49969, +0x17d7ef1f4f75295cfe214dce7fc21dfff13ff8a3c7bb86224c8a79566037179b, +0xbc4494e3d58cd6841d0aab064400e6ae8594c35f7e9672c55f283869e0f3f93, +0x174a4219c4aadec5921ae738b7cb40a3219ef5dec8db3bdfef39b373b224d38c, +0xe989d36297ae2397d85b8025bb304fe42bfb8bf93108996d2ba13968bba9874, +0x1ad84e6a15633eba89050cc15d94e459a6c2d42825986f9c5803c66f08976329, +0x6f0eee01ada409058a818ba8369498fba956e713a7e9372b4220ef15f954a99, +0x74a08a71a7e34b1031b63978e329bd0e12ae631100f24fcecb5a60bef5c3ddc, +0x2185e4a0d25570c435162266b565c1db0f23ce4e61b85b8b8a1872517754b632, +0x2bcd8e3cf988891e58bf8b8d3a259ce52f86de01bb8e6c4d49dc903f4b3ecc07, +0x2027fe75d87804599fb66c0d65b287c4e0582a4e8d84bbbc85c6422cfb5eeb9, +0x1e2dbde2355a4d9c61ac0c0db87447c67e08550ac91bf04d96790142d88cdd00 +], +[ +0x206cb038cc328526d0c3dc5af19437d83219751c5ee8f61b0e9e2f5881366be3, +0x255fbd250e6628c5eb540c311936b282c52204f56fe81ef75c398d9f0adebe12, +0xe14d98de84653e22efab29261c9a36c207fc9f5650ec1a5bdce6ae992239e84, +0x1342f46c9e240aa8eb2f1dd6c61d0bc79fa6cdc3dd8fa67d79729b02343b6df7, +0xe41cdc0db95ad5d67946f0ff028aad8c3a3c88acf10519e736f9265ce19a2da, +0x1cc6d37794a5bf901341db685e790cd7f7427b669069e4d320efae1d55bd7157, +0x117c39e46a1ae3c90b26b0df85078ebdcb66362515c74d51cdb192f789c9cfc0, +0x2b4c77d18677eb99a966913f7ba7b478ccda159d0f61a58702e80f4952b37077, +0x250d35fabe31fb7fd1719ae0c13cafb64e706932fecfe47e475034289443f240, +0x2c712075e8848b2d26f7c8c6f7accba81a49800ed3515221f03d845407b1e1da, +0x1d04d22563bde8bff1b425e9bf113cfe2fd15dca666b9130e56511462e971465, +0x135cce03597dd23591aa6fb38b2e70ca41ef91ca05997adbc11354cd831d57f1, +0x24716ad2942c2268df507e25be255e45c00d5dba96093df6c63c8a4df733f0e, +0x11cdeee1ba873dc61888aff7be54fe50e03e3a4a5ea0f32c6acae7d15d9f7979, +0x1ae588627ea2e0c046ed4f6c208f29803a25c9b2c0c385be294b9c25a3287e47, +0x8e0df227ca5a17a9081c60caedb5435a8aff99371a70219715b05800ef811d4, +0xa1cb35782612c7998afa40dc467fd39c882e6b3dabab079e63c330bbc8e5f1c +], +[ +0x240c57897161666f28d000b88d3353921d967420f401ce86bbee42be287a4f8, +0x7c9f836c94eef4e831b3126c06a9b4ba19c11c7e886f65c0d6267e07882dc57, +0x156f5afd193a11d87249f3422912980daacb8fed225c60a5bdde7c4d93d5a019, +0x203a73837d577d910d3bce1b15fef96c1bb522d4f02cc4032becb907810bc85f, +0x217ac1a2f28cb7bd2509d90ee4c03aab4094e3fef4741cf4015e1e823f71c0e, +0xc2e41be00d98a8dff8b30f5dfbce2708412e200682bd596b2162700a67274de, +0x1fd5670b294ced78188cfd816a41358ca32bbe8e024a2a200fe11d060f8c5e1a, +0x2884fd57b70a2305bf5b94c325b01d03f3cc2e8901014e0be3dabb984514863e, +0x23e772e0725ef73aa18f59f934dc11bdbf5fae9cc67fa18a2319ea13a69b9c4e, +0x122366ae0642411af291571a8904f0b6c6fb11d1ce750b3316ac35f310e5dcef, +0x1d0b0c33d83a40412cdaf42cb7ee8e5042d9a73eb17a0d5867a3191aeaea61d7, +0x8eefbab2c1c522367f543c33400cf254fe07711f94e9036a7558565e7305c0d, +0x209ed5faeeef4d1d01bf753704574d34febc7afd299a04430bc0f8f0baafedc4, +0x1cb753a0f4efe61b05e95e099e4b556770b364873d99e1f77e38a53e9c262673, +0x2a32d7716eba1cf93c98e9bbf805b0e4d27cd7e3f26c560beb2aea41c1782d8a, +0x2936d36a869b8b2318109412bef3c1a0407a8e0b98b4959ee0b624c116040494, +0x281ad4ade7262394bc55b71a8aeb4135af3b0c2433070cb0ebd9ec8e20dc7280 +], +[ +0x1aaefc2e9925fcd453996fda804063fdab276b37c5f51dfdfef9255b4ec10cc0, +0x2eae17dc561c37084e990fd1bc5057d96e7367c4b801d27f6a6ad8e0d0c0875c, +0x247ee52031ac073a81f56a957908c200477513fcb9853942a62b06fb6eea3bc4, +0x275602e8ac1136b245f551cb053d7eaad7dff488df3f645907a5cb151c553523, +0x6143a7c97a91838b0ad68065370bc9503d3e0c8d11f2a840b2c32c3fe2e79b4, +0x1f3aed03d37f7b14629aa2e5f086bdfbac862325988c4da943f88f4313647df1, +0x18fc0aca1d4a45978f6e3fbc4a35a2579a4c12eb6ea700f79ba56727bab87117, +0x97c4f0ca6dfc073c84e97fd4b2c341ec3c45b6f716700cfd7647e423f5e634e, +0xde5765593280a32bbb1630216e58d1d669ba575b7d276a2432d9c6ee302a5d, +0x7475c2b72238b87b0d8cdc92890f037dad0bd67a3c741e5672bc8677a35c206, +0x244e984c6f2f2133efa9d5dbbc1c60463d26f7748650658395201b367a39f554, +0x27a55f5103ad08547128724e6c20a4ae7af36be03567e4efdeca9880214d42a9, +0x14b2c9ae1ec7a0c1593ef29e782b063ed48e580ddc3255c0a1f081e69b634448, +0xeaf70eb10be27fbcdcfa7ce5e1b289b66fe68a3114038522d61b435f17ef209, +0xbf40bc87a391c052a56e43aadd307df751dbc47ef7c6c5af3e7bc4ce0dc942e, +0x3afb962f8ea2cd1affb52a50cf59cd5b1f08f087537859e8a73524c3c7758e2, +0x240011c27da581b7e91efefbe8f37abfa3c6e456ac5a6da05d4af4884287bea3 +] +], + [ + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x2cbd265ce3e5beccb09bb3189ca08832cd4fe102f39f9ee2bfe851a8038ce383, + 0x1e0217f13e7f212053e2de966a7ad7fbde6a7d47335bb58b2b148ac4ad7b8cc0, + 0xf885c4008d2a4c2992b3337f1c0eb3b21bc5569e7eb6aede116420d33f981e5, + 0x2e9c594b2023ee628c88f7a8cd002e06fddca13a014922ea4fd489d7f00d0cc8, + 0x217afd05c2e55b85675cb39f0aa486a11691557ca9ee1b7ee42f06952bdae058, + 0x1f8f067c1602f54ba576795e16bc269cc4f34416fa619920126eb16da9878c5, + 0x25f3633c988971494c6c37a0de4b737a88cd5be9c14dfc66ffcc4c5200c3d6fc, + 0x18cdc8b1d7543efccdebadd46b6e9096117758a3e2c638bdab7767e74f88747c, + 0x1cd8be04f1ac72a0b7daaef83a36e688046a41b7d4ba83aa5ef3a3a4de8e58a5, + 0x1a31f69bd76c670a3183335cf97746f6676698514467df13194007eaf8ed8b8c, + 0x2ab2c3d35698ec035746c4131c8d4cdae3be77eac56e708b6fb6a9832afb3869, + 0x2217b8cac3e14934002e24683cb6fb96da2b282d12447fb97789670e716b3bb9, + 0x26d8ecc33cf52610b26d55145f298e5a387c1b4587d44bc89afd2ca81a21cb70, + 0x19b5fef4d9456e93fe0799c1b568e2f6deaf43067e119ee89cce7b1b0074e8a7, + 0x2f0ee317d5a1d6c6d6c8b01f100eaf5389bffe269131af9eff36f71b3cb7f4ba, + 0x1009a43a6a00db52b2d0e325312220738c996b79414b70b2d04f61bf8475759b, + 0x2881d241ad316ea5b04bb05c86484922c0b6c6f01173a1e84af83d8b69bd23d2, + 0xa3aa81c611a57f509b1f971352d680f75a03361e74a5c12594987287972c39b, + 0xbf1eb01ab9b46638fe9d0a135105ed65848bdd9929b93d37369240a6e5ac276, + 0x1666fad124b64cb1b1fbcc06ee6180e2d3d98bdff534ea0d4fffad2413b15925, + 0x13006947e1defbcba51ece18add637d08c38b973232ecc68b6b2f7fcc0e40f7e, + 0x20cef2fdcdcbf581527d5fdd9442d7d80e8c122c60aba74a349e318119a9b077, + 0x29308abcbb8c3d71812419611e6e3f30b64b8b3670579e5f7e6084c57f8180dc, + 0x20a651bd8eff8989f70625f7e1db0da19b408d63385e63f8b1f066d0c3912e0e, + 0x2fe8775003759af3f41c2f923f0b683c27cf89bfa609ec6fc26714b8fd7c5ea7, + 0x226d37fdd9023563a4d6e2a3bbcd23137d949f36b2d9b1b8dbafbc644ff2371d, + 0x2f11eaf353125b5b7110a75fde384c14365c2e2cbb1140f8b520204118ce6897, + 0x7cba6d14f09fa2eeec2242ee401fe0fa089c28bc77f02f0aa90a564c10b4e29, + 0x757d39b861897f4ca863713452abb9e6c14f8736417fce8359c5b4dac5be0b2, + 0x58992f42ff62ae08b3daca79a5ac83d258272802dc6556aa757b390ab22d6cc, + 0x1fa470cc67647213df51fc636fce6b6e69de3a665044696f6bda9316fadb5a1f, + 0x11049230da628e01b2a11af1b214327c58092bde0d949e8c08a0c929b39a13c8, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x29e2fa62bb11282bff23cddfbd44a2d9fca9bb0ca099f34c63153d32257e8f76, + 0x2ec58445b13f4e1b14d47aaa8d3c01489e81838dcf6a8fb2e79ae1c420dbac0a, + 0x2a26d88da92db338a1de3d64aa9f78389c45cad24daeea74fca5c5721cf0b079, + 0x25240495a831b1128568257ef0c438a227576328351ef52cc3f6a361ad097666, + 0x10356b86c6b5b46fd0913fe632fef7bcb9507005df6fe46be9089f96008fceb1, + 0x23967538833c9bf2f3a2387251089e68c81a47051f8c3154b5863fe78a6ff6f6, + 0x3dcf91d2608f94783343c6c1c9cd24847ab2cd6778f568418527be40ac23e89, + 0x1185195857959b965104d24285d2f83365412ce31a6abcfc936d74af9fb8fa13, + 0x14ef1e17d68e5cbcc3a90ead42b8c438fb56b5fbb950d8883c2d1660fb2d1ded, + 0x1175100c6ed2ddf68ba552b4f40c27047fe02cdd2b533a3b9975454399294205, + 0x230160f538e3585cff4bd3cf7b4fe333d2b2a35738fb135ae6dadc075f92ada5, + 0x88c4e4fc1b21270a933a937f739bbc7b6e7eb3e316ca1b3ebe5727e381742eb, + 0xe3e345debdf5cfbd7bb9a4cb5d36d89c20713e43323d4341795448aabbd76a3, + 0x1a4ed87c8037af1d025638bde6b974caa276671abbaf0210cc7e9db2fdc9a345, + 0x11ed48467664df00548f3cfc70eed4039f6a59e826e73dc4b95990c03a313829, + 0x18ed0bcc41aa34c5556a7ebdf27ccf1a50f32561793053215a03d931c4f72eb0, + 0x2e73e5ff39e58205a16e013ccd0dd935bebf06505cdcd650935840062e8b1f8a, + 0xf66bc73e8a87b0b028720dc420534528d2fe5609bcb3d600507a6c19d20cd59, + 0xbc095405abc012247bc4a7277cf59e25e39834bd5839542cab959ad534a23f1, + 0x1fc384fdb89e274dad330eef9dc51855c11fdadb0b9b052fa220eb3e38d61254, + 0x2805a26d24644536da5f7e9f5071443189a5f102b92613098a8c23dbe887cee0, + 0x2a2eab082079c60e24bb5dbe3549bf6390708e8ccd034a2a94a71aa9c414cfa1, + 0x5aa87bc4fe90cd48a59fcfa82226cf759ce8f60f8c208cf9632a28ff7b680ed, + 0x2038aefd81a73ef09b7d0fd466d2b3c8aed99ad9ce559eb2aa80d7e06996909f, + 0xfaf97c7bbde99e8853c67af9e2187b8ee3708e48da3446b3eac3b3252a057d4, + 0x5dd570bb1e0feb5e6f13b9dbeae629f6f3ad06a365d9ebcbd2c120c6f76deea, + 0x124548796b8905caf386a61bc868d1467251cb29948ff1f3ae4847c724ab97dd, + 0xdf9dc278a65d06f8c477dcb8b562c262dcb7f9ca4d875070b36e9c2e7fcf277, + 0x725e0e87db61e62269f56d25955fcfea65fd3882320ba3187611e7bca42c2e5, + 0x2f204d469d9ae7b364fc44f2959956654f613f60cf669afe7b69a944b6903390, + 0xf4165ffb8c3cd0c8df2a1cdcc6d99d487b204cea36ba8023e6a17c90c50d3cb, + 0x1ab6363cc8e8594caf364c93385aab21b86de4aea09591b34df2152f6b663079, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x273626b708fec9b5d1d1330bcbb2d80d97ac1c84b89895de0628a0f15fa73ac1, + 0x232c260995bc29571e821068a7fef290fc1fca974214b45cb6eb63c02f56101c, + 0x22a91317e4cd0f048e756b7b41c10a9a10f85683df9051b1aac41cfb73dfa959, + 0x1789ef31e5469c8fa9e265becaf3f6f0b66989dfdddfc52491933f990624062b, + 0x27502f81423df0f6f223bfcb038b0347be96880b4d9b26d685bc87df88a12f80, + 0x15944d6894aed7bdec1cebe81ea14066dc63e49db38b79b63b5711cdea0047de, + 0x2d5d79c75632ff589cea134763ba602c43390e05fcb6ff8e91fe8376c327cfe, + 0x1f83f223b3a559ac092b5ce1bfe95f81be64ed69bd2aba06181f9962c09ce680, + 0x1d9105ddf213b013cfd5589de071e9a19becac29cbd9f5699314f7163f14f642, + 0x2d8879a2f005d4829b5439aa1630fe03cb581dd32be37ec112cbc8fb76715870, + 0x898f42d31a6838f40ddf7874dd4afce3481b6e1eda04c4f22f82e3a7c339078, + 0x1e5273fcce91ec174a392d2b384eaeeb2856c1bdb4342e1a38976f97497e51ba, + 0x24a863988061d2464b7bcc8d4ed630e79a471fe07c829d9d6b5eccdee1740779, + 0xd3f2af2fde3dc00461fe65fc25d8ef32db567495a78776f0f4eac20d4c23222, + 0x11130f82fe058dbf04d8ea6be3175f22ecfef9c4983545870967c73267e0dd64, + 0xf327ffc10a298ab4376b35f28b7eb90e794b6c9617b9a9cb1fd60d1e6208fc1, + 0x2fc6a08cdc07224db9ed85c48555e9b6747d401fc30b477a376470a19189428d, + 0x1c33ad6d01026a48305011699dcd1ca89d10a95b096e2b7d60363374c038c62e, + 0x1e5457fba2d9da56d4ebe957e2a4960a45ce9bb8c941e2b1bcb861f1c1d88bfa, + 0x29d2839ebf586fac7dd395ce00036e0530bcfaf01c6619489494f78a6f7d5ec4, + 0x4d8bcbbde662005d7bd4ff16ef911dd1fd74e44d850f665faffe0d4724063e1, + 0x1f110564e1708c2705cbd95f592a618406fa8ccbcebfe3b4fa9420636764c7b8, + 0x1588d891ff3d8526d281bfb900ea2b4de960a5d2b3740c2562f6a8ed53f374b3, + 0x639f2677710d59d2708e3ed851a80e7133f603ae0276ec542b23181fff30907, + 0x2a2e29702f1ec78a47401585569f7b48e63e397bd64ddbef59fface62fb5591e, + 0x172b91ef6574d5d044f3e03e69e270257e80c9cd0f1000cb91d7a718971dddc6, + 0x93f4d3b969bbc023ba1de485797a6ecfc42e2e9f034ead04b17830f297c15f3, + 0x1eb585e563cd03b430e0947955e5b906db9b169af33cef14671865a04bbdc7c, + 0x15167514d32350029469eb274806d81d6ba80981c4694fd030f0bd93c8ffcf31, + 0x1240581c6c08675773597b9d50b9187f160fa7d7a739630f943e4df9b1801237, + 0x1598daab9828ae0f9490eeba9d3dbd6282a2490db8ec4789605289a3109a3079, + 0x15f48fc5ee41eb8cb97fee7e78b55d3fda674fedaea91534bb506a4b440ea560, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x6b19393be5286a5cad14b6fd12c51219467aa1dc7c4923753e7b1adeeb464f, + 0x12ab8709e0b7289c712a002a6f0bfe6e72844177720a0427631540c7695e0905, + 0x145662a0788a01d81bbc0df72d6eaf0e887d22a1e4aeac090900c432c4132fa5, + 0x1d403655755dcc00c298137bc7e029f140b9d9e71d30e9145f6dd2a040febb9b, + 0x2370434b953dd1d26c4eeed6cae501a3758014dbad14bfef1c3d26cd0f615837, + 0x1f13968a23ad91e74be05489afc4b2dcb41621f6fb8b52f73c27bc2f64d198ef, + 0x3012f6382c1bffa9df0240a0f66b310a7463e49e7cf74facc054c7fd124e20c8, + 0x1da5c938033392ffec34887bfb06e6317655c3094671a68247eafa70d630c144, + 0x1a94414d237c4ad29cdef25e46f49e5e939d9699e9a36824f51aa65ff2adcb04, + 0xa234e79999d9f55a21dc03c43eaf5e018035d2b588d5ec8cd2d1df72f83cd87, + 0x9f0c86d7cf4004d071e067316a8da875d4405044b0e799616e22c96a1140c26, + 0x11bdf8824a0955d04b5fc96abac08049c0fa9cd678bf055fec2d43634170f052, + 0x20e74a475a9faf92f4998eb559ba0d8f05659dde0ecb757950e8a6abf015d4b5, + 0x1366321b06c12b977c2c396974a2a6b0c4e58f09a53531213c6206d072f4d074, + 0x1b2b47e3ea9a39df6a054879cee1ffd2cfd789acd7823e765c675241c3acf498, + 0x1e94a144e18eafc014b1aac9157ec2faa99affa50a05f8a8ae8ecb152bdb85ca, + 0x2fc95ebe62bfd5cff9fa2464bfc67b854ab2aae650da63c494d87294735305a8, + 0x1ccaf110504e1fd4eec6cab1d20f863feff3910d832fb789ec7e31713d262bdb, + 0x151066f81bfe7b4f1ecd0f7a8fe09a48ed40b0c9450476042bc4303602891d0d, + 0x22f0502a277cf27f336d9f3ee1fb7d67fa355a2421d4a01d121f1020e44ae43b, + 0x234465d17d5ca11607fb6b7f3ed5d52d0c06dab7b1761356cbbf0227b5777de, + 0xee0c8ce14909dc5d73607dba19e39706783488f00b8cac649546d934dbeaa54, + 0xc1a12f8f600bcd0dd2963fcfb7172d5842b12aff081a8163fccf1eaec3284e, + 0x27813f720b7a7fee3b44b2fbf89888c664d960bfcd775816ceb70050e6d26308, + 0xef129ae227544508104a79cdd0fbb9e8247c352c97190b90b5e5892feb828ae, + 0x1c59bcacb92f3012c6299cc6b43ba9269481cd107c161406349db4f728bfe66, + 0x8944ab7daebb6884078a8d618105b8843503a90ba51855c079b13b6aaf5b4f6, + 0x215bf9136c8b81f9bd5b221d37fd0fa327f923dac9d52ba825cbd3d2d62459fd, + 0xea608a14f0b4b405017fa637237863552a98cbb9bc1e151b7edbe8e6d78b598, + 0xc1aad9a675df88deccc3864f8c6e16cbee74db5441a6fff425a2bf2a6f84d67, + 0x243e3a95bad03705f35109af4c8c377983f06fef4cadd95c03833dc06ea51296, + 0x29afdf61d86b2558a0cf6083069157e5039ad172997c8ae76857f73e05ca3eae, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x1a85e806efde07a54e9cc83eac927ee5f534b01fd41388f806298b28501a5f04, + 0x109d8bbad7c3c77bab1a8506d4d588e7f5b703361a6ce70d47478e7464a73574, + 0x12f04b1f932511c8596a8c3b5f3dbf1f7f1d91554020fc43db068d95b8e6168b, + 0x1f28636d87164d2217fb393b23d0bfbfec1d912dca3fc000ba1f3e2ef46b8b21, + 0x16179a1cfaa92c905e039047db38e288d336b355029b1ce1048168e55bc1d701, + 0x16c3deac1173e14fc8b54c4da1b1ff61b7bc4ee2b9c62c2871d70a14583432e0, + 0x176d6148624c45e210837dd7fd87d4dc9e89f8efa4dea7c3cff0702fc2bf042f, + 0x20dbb69374e977536f1cdc4a084edeef4ebbf0c9c3cc4191fc4a707961fa39cf, + 0x2bab10e7b585d418399454c7d80fd38bb23190eecc5f85f410d85300487b9ee9, + 0x1bdb9ff621833468a0476986be6d6d719779ec581cc283a11aaa42c5111d232a, + 0x6660bc2be087e505eed7f1d4e5d8418d55e799008cdd4f91bfd536900e9f7b3, + 0xd4beae63787b3447f813f245fd8b7d6f49c83d63fe74a400dcd66cb3d363af5, + 0x1d76613f447ed37b64000a928b3b48e2e8dd521aae874d97dad7fe9b4c57886c, + 0x1f84a0ec9dadcd3937a045561b6205385c12c2ea4c562bd420f3d27ce32677e6, + 0x1f6424f12e6950564745b305080c881ea931d9083649631687a5a302f1d86fd4, + 0x2bf626dec6b3c130ebf137a656988397de0601250e39822152d316537a891fde, + 0x134731482b66f87776639ae513fa3245540fa1d34e6d74d32f7e9587b851de32, + 0xcc894c9be43663bde1317a4e3591aff66c18abdf0d8b90d872d86012e2fc8bd, + 0x22e690f84991940125c64d8513be14cd3fa81c1efc12bb80a6beada80c7091e1, + 0x14287659216a6cb96496ea198bfae1408696c5561f01e9504d5904044d9cc1ee, + 0x237b66703bb797da48e0c64dd6633de18ec506dec2d4d72b28fe93aba30b1621, + 0x1eb201c3e2663322f85acc8d641a362ac1eb1dab575d105af0feac86d68ebb14, + 0xf2588703431e1b9b0d059f900572f8222df5e7749dc0f93c09a24285fd53e4d, + 0x18a8905e765a49b51060ddc06eacbfbfbfcc0736f621216de0f9a1a11cc66484, + 0x10e1e120dbf75198c342b585b49bd0999633fd5310840e725642ae873af4a53f, + 0xe65310148d5dc0fb00fc135ad071d9b07e28b32dff7dd8fb1a2e0670238de99, + 0x1b924a6cd822b0eb0c6227c810a51c540fe9d9d07f906e24a57ec6fece7639e3, + 0x14f708f7a7c1430e9f6adf3a23f1dc38c92ae2f175b39671aa297d590f7806bb, + 0x2c870cd5699f7a402a473b3610adc0b1b1dfba1798b30681de9359334891b5d1, + 0x2c2793cd489f2a0ba8efdda84b35034f81bc47c131a3c6b6f8107f7cbc5ab058, + 0xf12b486f743b8613685af0b508c3b3c41608d34b82c7dc3d8f15277e31842b6, + 0xea23cccde8252adc358410548ba3c53e224a3169e6ca958458940f318bbefa3, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x1e5a6dba6fde6063136d0d97f46d5f292f065b8a9db8f2ab07bc17d31566ca3b, + 0x2f5bb6281fb3085c9cf508288a809476a23c142a459949254f99e0461496897c, + 0x230133fa9c214b6cd63701c3a082ee211c2d4ffa7037d0d0a4cb63a77ef5b696, + 0x7b9beb8ce1dd13c153d36b636a7af56db3800d97c16400284b5563b192c7803, + 0x18a62bd663f364bfd0c79d7f3edbbaab5f58eaa44c0fc207291c8f71222059d3, + 0x909d7276a02aac190974de34558921d3dc8e6ce22964f0e97b69858bbf39108, + 0x191ce266e49cadd50eb403e7fad07cc9ced8d81d8d23df3dc653cc69a8e62310, + 0x29cd029dbaf281a5b72c6d730674b53cbc773dfb542428d45a11d443aee0c906, + 0x1235f2e3aa2a5663b1dc32d86d32a8e2ddcbde4e97a3edd894c7cf2f799e545c, + 0x11310308464e805034d840a94d25a3b8bd0c206d663f41d145fa66415c2dbc12, + 0x2007f67c3b1d638da29631206a6befa6e21365aa1edb39a6f3a0abfe94fd2392, + 0x121d527f117db7b0a614ad1be6fea1f84369a4c6e451c0d5d2537983fb6b913, + 0x1ca4a6c7ee32ae8f3d55e7b5f8753ffddcbc125e170dc7b7c8ba2d62701aeb80, + 0x2f4ff9505df9f5dc0ee5584631e6f331213d654435b5d2593d249b3ff4e64802, + 0x186af707cd1927045cb8ad1b1510d4150928d839d07c8c9a3d93411262351327, + 0x291caa38b2e4083119c579ad08328807d4ace7deb24f78a5d4d208cce95055a3, + 0x27e62d562d2936ef5dfd0aaee64cb42d6aa90006a6fa74a7ccee794d78c0faab, + 0x2706ec2021ef6f28fccac547cfb1aab2da02f453dac5b2daf393ac9bbfa63444, + 0x2c6c0b69710326e4bf73840601626d94cae75c92ca37aa5b5c6e61706cde5a5b, + 0x3bc51987425528eee7a4a3177a8ee4571ccbd028c70ada4bbb3f8e6da3f58eb, + 0x1273940d422f16d7b918e5b6bc3dfdba2b22abb42cd67aa154ed75496186025, + 0x253094fbc334240ab67c86378c9d8d7435f3d87d5d68f3ae901fad214e0dac85, + 0x1cda718ea0bd4ae40920c54c9d203f88deef3e00b3a6c3a5bc9243957c20133a, + 0x125308584766a4ec9815951c72a099b9ef423fab29783c9c8f8ba14ef8221ecc, + 0x130af16ef6729327847344cdc8439079d47871751ed3f0b871dc248c6b856b44, + 0x2f730d5dbd23018d8c91be93b9e666cfa9e9c077d3b2724c43a16092170d7040, + 0x278ad27534ef1afa5d3742e03bfbec8156aa660b0d663b054a5feff049aea2c8, + 0x6d35c831095f5def4afec1841c74aaf1b18880eaab4256ddba34e49653c6169, + 0x2a9eb03bb2a3ad110273c506031de6f432b6673655255c4189fd2db2d9956d24, + 0x237bad6e8955fe0485f4f72b4024855f35903b6d795cffd27468a7bd0e47056b, + 0xee091319736fcc0a648bc6cb1b31ee36b95b20c4d40f91392c315e5fcf26150, + 0x40a730f39a665fd9cb0c93989b291d281958057e9b898d0b50c752f9371a96c, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x30478f2543e91a3b1c9b3fac23fc86c06032ca0fca4bee9387722862c449cfc, + 0x41b7accd8054a88f4ed64394473fba2b13d9b9ea06fccd0f75439c8a09f968f, + 0x11bcaaccaa00dc4c80c43172a833a6fa50fa47827b3d4df0c221eedcb7e935ba, + 0x1276b1ec4d51cf23c53b104a7d1e127058b91f5a4cd2bfea420c15355b43553, + 0x144dc8dfbc21918abb47ec061c7e6a2f7fa9b32babf270047a2f465b7f8f6de5, + 0x1dd046beaf1e8476308af0089af19da322852346b18ffa584af9d98619dc8f53, + 0xfa7e283d56ded23e03a16d79c94298143d259d8c53c8e0de261d197a4a1c071, + 0x2e1a819abacfadb55e98efdbc5bcb57e216fa7ed9d60a4ed920b2a1de8fd1316, + 0x256938ee3b182642f778f742bc3bc00a60aaa25bb3ce9f7fc96559cf21b28570, + 0xe6a334e357792b5182d8b44d893ce322996913cab640a006c1a8b73c023284f, + 0x24073e4154b684459e0cbea690ef583feef556f092b2b17c82c31776725da906, + 0x2dfbe4b1760808ac37902dfb1e18691901b413b87c6d8c8ae54d79894ded6c80, + 0x20f447f6a67d3b8929e1efdde6688fa53d47964873d86ea01126f1e0d447d951, + 0x2c502b5ab202577f015431cc2b64b61f85f486161ac4ecd64c9603fe6d353d01, + 0x5caa2b6ed2b850a5ebcc686b7198604941d48d30932a09e2de9006ffa61afb7, + 0xa3d02ec260b02ef2a4d51c2979cc1b22cda27b543a1bad75d9e547b3a5c751d, + 0x724bf5486c9bd20c2427fbc1d6936ea65d052f442a417215cd089b9e4537843, + 0x1ea84269caab7c273d92e86ca287a8850995c9adf2624daa858932665fed66ea, + 0x1d7e6d3695ae5003b9dc6950af38af6b5319cf529a7a1d5076512dfd92b099ef, + 0x99642d891092eaa8df1bfbc45d79b13934c42f37f8e1dc969fd51caea4fc246, + 0xb94bf0fd8f907040c14c1fc8aa290aea61fc881aa82da20ae568c34990fc705, + 0x28fb0d75533a8263ef2ec6b85c97b5af21e526471056355253fc5f6fd3361375, + 0x10480841e4451bf366c111c8d3fdbf0a7ac9c04b9aa2d8d547285dd891e77eb1, + 0x112274c48dece347a089aec971f0cfb9d7bb1a15b32ad3678e77d15cf7107ff6, + 0x1a8c6d411ddc6e2dedd2fac64c324d88ab8a946fef1174c973dc0f658275f5e, + 0xd0a4a998536c490396be874d02c03de56bcafa3cf45590184f7b53ef5c3cd87, + 0x22016b957df82fa5c825f4fb8fcf8634e654988b63d9f9933bc7b7f256e7c67, + 0x26d2a9b0db83259f6c7d081a2d50317039076baf6151f1734883fa6c322b243, + 0x1593b4f33dd3053258dbea8117f435f21d6876e7fd2907e98bd81d13e1f8aefe, + 0x1ec80ad7ee2b685fd79b38b842b0d420b685e3c090acf3e7507a57739ff76185, + 0x10573113bb0d41c18513cef083fbba91266dfa7178674888ace5d566e1308eee, + 0x2c5bca238c2c3be6d5cf5971ee92ef3174d4a040ddd6b0431354ce434de989b4, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x2f77238c057e187797950c50dacd539a7b7a1be7baa3a3f3a617f88ec05513c1, + 0x1e4b327ddf07cc065b37a9af7f6d97b89c40479908be61b2e6312c351a4d5ef7, + 0x1fa0048409da60cdb12a2a3013fb60257940ee5f4f8c2b1bb56362e121b0c8a5, + 0x1c92ce2c35358268ac56a756f5ca943b43db8c7ec965770da62b649c45baf1b8, + 0x25a62912bc39aacc66055eb6cb404b6a4f09b703a344b752c526dcb93e768c73, + 0x2f3e3c91be6f5b034b00dafa6fdb33ed00735f48fb2300a783ab3307a6aac793, + 0x12618073f72606525b743e3ab8c2749bc83ebc31cd47ecff2f851adeb397b5f8, + 0x7e1a14a5fe9a127930b1ee9a4bbbaf3b33ecc0c23d7b3b906f59925c0670f85, + 0x185866c20721e1018a4eaf241031b69ed1f2aa25e05310a44a015aed45003576, + 0x1845f9656990a68b36e47e83b67e6d53f42df6a83cba95b016c349ff191ddbc1, + 0x285db5bd04516aa0416c2c52cc651c2690bc846621ddec2ff3037165c30444b1, + 0x230697cd1a79c303489232f2d060182c4101e0fb4b6d3ac38b82a370d59ca295, + 0x2d5d42436b19bd4916f035f323d6acddae9a252ebc7445adb1d7bf560b464bff, + 0x1ef94358c904246669907524ba5bffbdbd7c9a5afcf160e44d00f19cd804fd87, + 0xdc902c1c2f63aaebc2a69edb37331ca6c053513f29991bfcaf6dbf9cda9f8af, + 0x38cfec7101b2ee954fa5bd1156da5c5662bc77e2b4e16d39139bbf165f5e331, + 0x23940e1b0657dba41ee3c7edbe86d7ef9f3a45016a61c2dcdc39f0321af50fa2, + 0x300efb612aa09a721c8feb5775c639204c092bf5adbf9d4268dd3f24a406e969, + 0x1cdaab41d8141524f40389418576088f7c8aba62feb69e895d39843068dd5679, + 0x1f035b6f957e84c1eaeec71e31b19518f3dec9964753a2caa1a33ba14879d0e4, + 0x9ff1b666e47a433088329f94545bc44a179ff61e7988ec8c86715cdd25237fb, + 0x97ad004ad339a6ab46f92a80e303e5d431fcd77b46a5b4435f383af68f7d08, + 0x2189b934e1602af6e30d786a0e283f0877720cb8fe77369c37f7ac895886dc1e, + 0x1903bcde38ddde14e22209d72837f9b813e437099f71263f84e18bc6414ee74, + 0x81887e6be9c14e1b9ded51e9cdbfeba2001c9e6098d6ece905a0fcea98f6452, + 0x26c7af1f1cee86563e9292336fb6573a0970af2c6d49d469b682188ad55561ad, + 0x243e21405367c02b78c9da82c9102df9c32a26dea21da00beb62ca9e4e71fec5, + 0x16e3e6bb95f28d2f321e7b63f6acddf3dd6c2e9a05aef8ba4b9151b1de10a78a, + 0xb011142c18c2fd3740c07513612794c14506ad3094f440420d5265f225a84f4, + 0x836b51afd8ef110a57d3d82bcb1c294a3d0c942ac20f6f407cb20ae9f0addc3, + 0x1ef12a547707d7dd27529e8675e5e58c3f35bd50de464d5e9b1735ab22d95565, + 0x12f1b456a3fcabb116586107e089ccb38b8ea0ac2fde6f6d464302c5f62c5776, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x16e23bc3ba612e8d4104a5a608cce0d28bf3a06c6f9024f8f829edd7c84ff5e1, + 0xd4acfcea237e44009b358d998961b4719fe512aa2cdd6438aa30dd5baa6dab0, + 0x93cad17aaed41e759cfeb15461f0222addf78c3a0aedea7186431c535ed46fc, + 0x25e68166acd241fc301db582f896b8e314e398dad56de9f2926f9f131a81d5c0, + 0x8d9b1a38c7c71b2fd5dac87ef974ddb4f7119523d81f88b0d7e16d577db060c, + 0x150c5bf06a071be6de288b6deb00b6ee51ee41f96f71cdcc980a366e4049580d, + 0x1820e0533ea75404ef263e570250e25f9c0bea1228df9fa90a5da8176154f089, + 0x229fc7b637cf8316edc29145ed5f060a9188f10f71e078dbcb887d195e8da899, + 0x1cc5470c6bd5d73eee63996481a28466499751a0a9c784abdb1c3fefe643dd81, + 0xc4da78b5310d04853242a11df821ba84860fac1a2fee9fc04e25c6039bee8f4, + 0x94cc155e114ff824b23e67ebb28b2bda53aa526fd3f11927db7060ededd2bc1, + 0xdd872678b808e11045a657250172181e1fc7d9e2eabf893f09fc3c6be3a93c8, + 0x2177c7830ac6b2cb6d01ead266a371320f7069a0de0454e5dd3a2566ff9eb716, + 0x232dd9ffd97dd5068b1041fe3ed6e08e162265e9e814b85116a6561430aaf72e, + 0x87726ff3cabb6294d2106931b3160809d4d1e669ed7de25374390af8ca39b4f, + 0x364f607b21cfb12929ecdd65f7618ef65c8e9caacc4f42c440994d8b5dcd35b, + 0x304b195fa0bffadcbb23ae2267693c7da7607eaaf40c880843ba71521edeeb40, + 0x196610368a8764fcf4f0278601232bc0a5aa7ba6d20e2c5420a7862272b06749, + 0x218f52826b8e2b82e86d87d7bc87fe5cc69171430488282062d7008069c89dde, + 0x2a70f39b2d8cf212fe706545d1cc154d07405c1417712b388c919b35263c1343, + 0x65be4ea4d6caa4125badaf16b830538527414ecd718a923c3417c474fcf5032, + 0x527abf8fa6b64559c86b69eebb3f0acd94c9f23a01438ff78f034c80291d964, + 0x263078abe4570cb96d27cea17fe9b493fadb3a020605cc474be08ad173dd424e, + 0x2616b2e0a8970da8019208335d4cccaa489c6cb8da6a862f1867e246e1f36736, + 0x255f2df1f986f154768f0fc8a5a2ced1f18d395ff01165e77d6cbda3e8b7bbd9, + 0x1806ff1795d9d6c9292f980c957038acfa02ac32556c9ab826bc14a968dacc80, + 0x871baf013f2fb16c067858844cd395a520d8a8bb17abe207d3138bd591dcfbe, + 0x28f0493d5c747880a71a82644c20dc23cd3bdf84e05cbe0c0a1a48fa27312484, + 0x2a45ef02fe1dd41641c787b8611113bec4881a56784fcfa21bd896a8205798fb, + 0x7ed262400e2c66934b968e3f8713d66e85fae72ab73c6cd33eaf5b2b480f6ce, + 0x17984162d397a2b3b3bf3bb04af70532c4beae81a076d0b8e1b4c54e5feb2f7c, + 0x296ee291fc63605db9594241dfeb6576603a30c42d6d631d4123982adbf54cea, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x19933fc7d1aea36ed4516ea4768628c08d206e8cae12e53a61147f2301df7c31, + 0x2efd792c56ad19032f4e2307f7ee338895556de653bcf50239f56a6f595a59e3, + 0xd6c9475058e6029ca3162b0db37e71ca570a626e7812f8938db5bb9f54f352c, + 0x2d6e38ed12eda3856592e0348ccb4fad2477619bc8a37237d4e48a8b12d0d7e5, + 0x1b22798bb6b6e5711236933e2596905ec1a4eaf3c224cb8e18385857df475aea, + 0xee2bfadc6c771b8279d82f54770acab798e5d7e6b6c93123cd6d871ac0f9cb2, + 0x21dc8e7e1951b62eaca40550618cef0d32ff82f425264dff2743e287594d7d54, + 0x1e75bf782b602b28cb11f489a17ab323dfe881a7654af175cfabadf765d2b48e, + 0x2c49b7045f45347ea8498df2f5d5eb560154f3579016772dc017f6d43cfa563e, + 0x1a0ac37735eabe257b9c0c25c0e8ced477833e2368678c6449c1aa4baf0f2312, + 0x1f35e213914c01a5ebeb34838610578a4fba2c4a06d248e0d6b76212ef339560, + 0x236ab082f2cbd2668f53ed5a9ac5f29822440e4b06543b6ff3944739edb00a52, + 0x12261534f09c4b4f143717ec4e8b0afe58fc399671ff29f5fc8c3dd302eb70ee, + 0x1421d8d32235caeb8e90379b3abacea1d7ce42bb1ae928840a8739d85acb3127, + 0xd330afe8be63d8ace3a3a83b7da18804912e3b3c1a8ab3e556b3256f0c551c9, + 0x1563b55edf443890c4729a6c84d523e1133d54bec37000b9afda8ec393c0d2fd, + 0x2f6aaca00913c8a056867f42f64016d72982e3eddd62f7508c4b86651d2fc253, + 0x2f31927a218ce8d5931907542909a9a8a424857218573585e1a11aac34a4ac59, + 0x2245d56c69c9bcbe47ee570fa2cae8008a8bc3042410d29f84cf65adfb1d65f6, + 0xa6d1a50326bf87096bcfb5acfc3a84bdf112eff86b9fd10e935b3ea5cfe52f2, + 0xdca2fcb2fca35419f3ad6737417350e4fe4b3428e65d4f418143b97204355bb, + 0xeff0d35806c692f93f365c7ce6d5489b513aca79eca0a6663e9bbd8820f568c, + 0x761a1a536cf23aa1f57a5a10140d4b1cb968e9e3054833cd33b769db1cdd0ab, + 0x4fe0a5f272499e111984cb95f691ad3533008ae70634baef9e60bb0808feec3, + 0xe5e1a69a0f2521a67cbaa96783214399818adcf5104c8da98d45f3951df3d79, + 0x3042f99a1751ea962828ad563e8a6d6dc438459f9b912b3b5f2567ae31b74cf5, + 0x2191f2dd5699e7f46dfc7a0fb01c5abb9a34740c534690ed789a3bedbe15fa65, + 0x17886ed47f13d1d49c9c24836655683cf481f3e89d2b65b9de78b591a97b87e6, + 0x1913d17541b234d83fd9f7851782516da4bf4ffe9355c19400adbc995c417fc3, + 0x271e99ead6dfaff8400e390541cecf5146ae0f3b86d0d94898a77b67d0f59b89, + 0xb57c116f3a607094ae8b3e7a2b7ef123635bf131089ca8fc8d0264715bb72e1, + 0x1e097d47d4a82b797a5ab64eecfbc5026ad25c9aab94cbcfbeed04e47aec7e78, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0xeff65c0120d6929212be55e8e6ec2e468d7fddeb7951b01ad014948c174b971, + 0x2a5c1de1bf17f1fbb34987d445e22e3bda9510062ee81821d20944df27d1d6f1, + 0x106178470931e69d02288fd73abee97994704d2cf4c2142498fdb2487afffc91, + 0x1f2d17deb1a25ec04570838e8f5caa47250c1bc16c0406017f5b2afb2b2c8b4f, + 0x1ded3f9efde2ddbca11e2280038ded37eaf9a4542c959d9ea7edb29557118c00, + 0x132611d30c21b4909aa39e4331d2fe2a1f532198f34588e67dc92a375b1d95bd, + 0x2f5741043ed87b7272c7a0db20ad4626af621071cd0aa6759fab3518f420e751, + 0x20749c10519279b7ccb82ddcf1cab67a14b26b3080022997c05ceb47da0211e0, + 0x2f4b12cbeffe89cc8e0eb8fcce01ad903d14750534b107d1a5095b53f2eb994c, + 0x19f437a4cf9d69d918e2bd2c1ace4309e128fb911926c4396039790db1677211, + 0x2189142b8e8e62d3eabad7d3a9c92a2ffc07677dbb3927a55035436a4fe99084, + 0x26deb902804c50f44397613473add31799f85b20d1232ccdc220357e87e0444b, + 0x60feb6d13dc7538cdea6274969507ba784301ea76cef8af0eb914ab2339be82, + 0x76ef42dd0bb069840f761558e2005af793ea5beac349c3dfb9e610933b1728d, + 0x21718df0edbd2d21670fa990fc293f89f53cb169739bf7cd2b732967fd4e936b, + 0x21e9e1015d05a67cb7a314fdecdd1dac563dbee2b9edab3388ec4ef9e58eeb22, + 0x5fc174109c8e7779d39321d9b843cdfc1e0d89d8806e199e15edf3cbd724f8e, + 0x96aa7b7315c181d4bb6527c1abe5d758908a11d1443ee30c0706b31bb43da3f, + 0x100171ff805f808f17a40a9e80b4f6516ba5d39cae9cf62919e085edcb46e0d2, + 0x28a6f6698a4d25726a7e7bcb50264b66a9f377f6dd42e9affc077b5bee5680ac, + 0x2be4c72e7f354219484f1f1873eb38a8aca5924509c892c1fd072241d02cc624, + 0x120e09a9b5ba1d13db63a4d011a2ff38845564e057c641657ec24bf5ce8e532f, + 0x26c044b1e72e2ed87e620c3010acf302d6f19cb8d4d5c8554931d2e29a923da9, + 0x1621a950244b5d32dae27f189970ae10d14f0803d92f67d8912eb7588469471e, + 0x5065df755c536ba54bcc816f308c2e341f05d16254116d0e29bac9cd827250c, + 0x18165ae1001648c8d9987e38bff84bafed3414ba2dc09eb937b73a1e636f43c7, + 0x2e84dd68cccd069cad6fee65deb27c501b2a0a8c75fa6b012b6451977a1cfd14, + 0x29868ed0bed932d2ae0f4ef731251a4ae59470cce43250be9f7fd55c543ce635, + 0x296b41ce4bc8cdd06eef0021c564646332bbed4a8cd4216effa4a09a015b1e22, + 0x2c1558f35552fb1f9fd96fbfa1cf187ab296c941f0dcf1af18063db872028d57, + 0x8b1bc5debafe2cc01e92b310a9bd1b62278d9aefaf78a42ce169dbd7ccbc769, + 0x2c64eb96b29fa0e07efbd86bcdaa1fcfd342ff26fcc11adb163a3e778092fb44, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x1942e0e4dc6666d050565e3041b09d79fc20e99b393b2a3c53f67467c3dc9cd1, + 0x2a61fdc217a0fd51b44cda5669eb8c81b4e4cda33c07d96a3b3abf75bbb593a1, + 0x27676c9245df29af49d1614b032c86d99dbdfe04e1ae951e91ca88267de9fe59, + 0x796165a50209865f0c12eb768681ed7107f6e7976c76a36fe196ac36fdbc5b7, + 0xc3ee0c7cbf8623447c90b90e13d290d313b6d0c466e0c4e1629e54eea175092, + 0xca789430e09c72971ba49ab8cfbe88c7ee91571c1bdcebdb512adb061597f20, + 0x55c78ff2ca4e60c8d1fbe3c55b15ecc28f86f30e893fbc001836cc0632c955d, + 0x1b1ed198ea5aff5e8750e4fdd1b51c9e4db45a651b2d9e1b211acc3b124e31e, + 0x680a0131921ff15b6f737ed1ef99bbf554e5c41ef4fd6e200bf771134512a94, + 0x1c04574d4f435df24a38a6afd056c49edd61ce1dcbb160c69c6ab490716f4bd5, + 0x1f79fb349db705a247e689a2db091244c30680dcbda765fbacf3f36fb7feba36, + 0x1b6f45bdf0ed13a82c330a5d26eb992dbc9802f11bfc2669e3feef1c310baead, + 0x1ce38cb2bbdd94c03869f6bd81e5b7a0c359a932b676c0ba6369fc4ee9271584, + 0x2d918f60f8c7be29a0b6eb2d6c44c56f0cdd865fd8a19ed747f4c83a41a2d29f, + 0x2b1e6bef26c3c2a5f7ec39c3be4de1c0a5bb8c1dc434570d1cf9811c71c1e2dc, + 0x18231a4625a11e057412d2789b10144985ad15966fdb26809ab8091b06e3ce3c, + 0x2ba1777ec04222a9f98dcaba3a5c2023e77a8071a279c726b35482d6347fece1, + 0x183e2d6301b1e472e01e2360e02bc855b6f1a262a4d03517beca13ac2539fa50, + 0x4e6c329b88633c6a45be6f77f5a9d0d54eda85a4e015ef7c368bb145c6978eb, + 0x1f7d2b53a2456c0d398417386d87f4f760fb541cc225d0d84d9d000828b94fee, + 0x1e7e8f07fc7bd7b462f36924ade2a783ed2ad47f6a7d4a5051b9774d61dc480b, + 0x8ee6dc4b9baa362c6da82f6c3787aec48eee1f6ed33157d1a9bdff0cab20781, + 0x1fedf46ce5f0967f0d259a7ae19e5b781a801467ab97ec9b8d50265832471e92, + 0x610a62079b0c8c00ad3401ad0473fed44dcad28affdde92c74ca927a018403e, + 0x2f8dcdd501988f6da1f3d80308531ea26ad2eb7017eae7d97e867ccf9e5010d7, + 0x2bca9ade6aa068f60c0fd6a44e549bfd37df8499a589dbffb64b00d3c48fb730, + 0x1a145fd2fdce8ce3fd02830d4c4c8a68e315fe92a38fdd0f5ff7a38d698c1c1d, + 0x3874b554c5bc6c3988b1601616c70756a3f5f9de40edfbfbe0120631da540f0, + 0x2eb0cb6d015c48ad9d3065a505fd42ad811fb70d9fdb5c2d537843f63b378e8e, + 0x11454221dfba7bd389e8f03187a0723828428a6bb434c6d7bf20bfe5fd114b83, + 0x2a10c14110838c69329a80b0b2613bd9943a3ffd25f6a1e951d0a90fed4ea8ff, + 0x1e52a42d152b85d8a7807288f6f70e69634da7844d995b254f518724e4c3609c, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x2d54de07d84381601063b6e9bc507c93cded3cdab6cac3878cdc3c29720278b0, + 0x2d8d4a2f762f3df73356ba6bede1b007449304d062b2267b388e058c30d321f, + 0x109f39baaf3fc94e73d04fcc393a6b60af6c6e20d5953ee4a1b572857b4c0e76, + 0x12d501a7112aeffcc039e330790ffb66ba390d1dde79ab5ffc723f9fbae2875a, + 0x104a8ca53760ad5d9a630d85bf1d2880fc8e22a97c26864f6597b78ccda8e39a, + 0x156bf185e618c82fd5622d81779e5538941258d1ea3d26923f59b002ae7f48c5, + 0x177774923ca426cbb54827e2b0eea99d32c576101bac07394a15d89354e6eddf, + 0x113a5bceb59274549fc1801d16c19742fc8fc2139fe584c52a7bbba2a329924e, + 0xc6505ca747cb38e435eed24786617d5bf69034132a74f6464c6e802fa1fabd6, + 0x118069d4c4bb4779a3c231b4f9bb10c9e51bd7bc57cfcd602ee7a6fc0e1abf95, + 0x385980d35d14e90d64e9768701ebccc125891654fbb8d6b79a4ea17842a4975, + 0x1916313365e0bfe0bb7bed5b5f7bd03db314de71ce80422065c503181bb61c2b, + 0xbf8748279723ba405fc30c18b22b4d1c8bd2ee8a133b73c3e36170fbe2a04ba, + 0x18e633e3f93f527805cc7bdfa61eab0efc189b556f7c549f1596eab99d2e0e6b, + 0x152bc76d070352b5e3b4f350f4b07c8cefd23e9fa5c425a8b974d68aa3c07730, + 0xd27de87e407d89aed983b9db0f81620c9dfe423d47d3de44cfe3b273bc2bf85, + 0x2b50440572a0892b1c83bdb6fd2037c9ad720f13141798f8857283e01b1290e0, + 0xb5b0d8f6278e41ff57cbe18be038e3467f1bcc255156a660cfd16aa2ea9ac6a, + 0x1c4bbc69ba7ce83c1b223dddb0304428eb67dff461b719504d2a55c7bf380a4e, + 0x224b7d772c7a5d6fde26f2ba95e000eaf6fbcfa50398579c0833093d6ab8d7e6, + 0x130d060491a6bd90c3e5ee6bcff4181d9126f520c56d7d8233120e8449f0370f, + 0x26e1f7aaa668655ac3e092b9c8899994ca9e596ba992fa8863b52b3137cda92a, + 0xd910dfcde2f0b93948f265e861563afd9dd6326cde2a9c9489d22d62dbd3071, + 0x1a92a6fba93268b439845332988535624c93b616d2e972656ffb15175455e542, + 0xdb35e6ee7b9752c564e9132696f3052e39a46df1c4823fd05e246e928963d64, + 0x190484fb8797efff338127ac69877789cb80eaa47f674cae2035e2d903b6dd4b, + 0x281b15d146c4d56debf9f66bc0c8138b7c5be54cb206a9180987f1104347646c, + 0x2fa46d89ce68066bf1ab4d304d8d9163c8203f14758eeecbaeec0725cd663813, + 0x2f2ced28553cd93fd972e231deda1c8b53ec3300e9617dcaad0d2d25f2d61fa, + 0x2aee5484616632c7511346d4ac900eb5de7a04994eb95b4343d3af1e388fa74b, + 0x2bc085981337c2500fb80f2259d55e956963ef377ec1e2071c84639a19a581fb, + 0x232d9177d238a7e2d92ff1260e60e1d1199365f4cd6f911dd08315297bb6c648, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x152e232aa2f0b5ce86a9bb8ec7c916a66ea7d3eced20c3119fa4b32227a44224, + 0x2d541381556b2db0e934c244bd4f8ebbe198d35bcdfa56c77ad702ce2b4c0c5c, + 0x2e3dc0bef8262414d80245ceb411511467439879f538701e9ee094f7c14e408, + 0x16a011d07f05d6aa059d5c39ec295e27d697b94e0eb8ee80d090253627d54ce1, + 0xf2e71fb8b1efa67f9de9fa1f2a089cf8f1a995bf2efa733b40cc406b6e25cce, + 0x1231d7777e2dc2538a6a0c854cda59d734f0ce0a877b5271a1d38c67e682068e, + 0x24d78b8526e7b1c0637f2797968911f101462535e1df4d7a4c151bc6ff2ce040, + 0x22a988364a2deabc2ce747418dc02fef38ce6c811ee6074febd426aa59e135a4, + 0x15de00a932e2679f01402db621f4226348b05436f9cf4b4d6d6419e7770d1565, + 0x299e0373cd69ca5bad2e2ca004ff6dca193a9aa2e0e51de1c89770d2c260e229, + 0x1f48db87438ef28954de5702992fc180e1204b139cd825af6631d8eb0a4c9bfe, + 0x1bdff4383ad65036a6193cfd9f77601f48095adb5ffa44bb31a4acb8bf68b74c, + 0x17644aa682a852335aa5b1532c6fda9a980fff5e94c2b6358ca83ab58a9a77ed, + 0x1bfdd4600de694368af6447e16dc544f8565534d30f9581b5d81cc24a6503e26, + 0x18c8230d4cad7c815b3b71d905826a94022a81cd18a26427fdba3236667b24ff, + 0xe19493f16f0b05a6cbc8c6ee13f334f045868cb36c7e6013b5600e2eae2aefa, + 0xd2f393e71214f36cfd6a8f7f4f02b164c0bf4116e97f7198440fb9122583e4f, + 0xfee312ee60e18d3e7a6ba6bfa95e826f27a8ea0a865e3c7a7fb4e130d1c4c09, + 0x22a056cd7db5815347a2d035ecefda073dcf753bffe9415afd254621fc370eab, + 0xf5eabc9bc5fbb19864ef2113fc4c756e6b5f3d1dafb8abdedd3b04d0b80ae66, + 0x7c235ac19bd9379c4cc01b454b43218af5b573522aed311148404f3a5c743d, + 0x2d942aafd44c4635f7cc2f58e4b9314baa46e187ae91b69a70ce5ad08aae42b1, + 0x18b7536ddf2baf318f7d95ceae7c059898a997099b0e006b14a9619734d101ad, + 0x783549372d830804cccf9bfcadf1bb805df0cd74fdfd8a58ed78b2cd5493037, + 0xd0ff56581899da5c5e06929f9211224abc1701cc590571e4243ac5380251d75, + 0x10eb2ca01dbc69cf143a07d1ae33d465c21b004d93fd8ab3eccc330e8897a06d, + 0x1caff794c32f783cee39dee2bf130ea89316a74d9bf6568e1d0be5a2362f4273, + 0x26e43873787a976ee680508db2668f4e6c8ede06795ce54762ea9b7ca7654dba, + 0x8d378aa3982d2aee08f51d4ccf75af2b06f52ab03864d95d56aba9bbfcce7e8, + 0x2ff5d0d03b4b4f9d0b01d3e0db319dc28906e4dca3dfbbb4b37f99a85d1b38e2, + 0x18520d1a0bea45e0d3d8bf43f25ba325c6f2fc2a854477dd7bebdd9ac94038c5, + 0x48981c51b77cae321a249b580cb97b327075fbcc0e789b617e8d3694477e52, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x1487015218138ffaa0a59fa85396ac51e075d8925a724fd325424d928c654ac4, + 0x158e7709256be5b46df08d1e1b0be1938aa6f4e5c70197431f5f2801cb81ce9a, + 0x23ead31e3adb55af0de40f8ec4e5e40494192a137f36d6468cac8b9f8eba7888, + 0xda52b842c39529943fbff3afa9c3a75d580025df3c708ca7e312396e7c7ba62, + 0x20641a12ce32094370652c635921aee03831de2dbbe854b52d983dc669a0cfa4, + 0xe854c479dbc2e4674a8fb297f33513eaca7d1705e71cd403b3bfda7d594d063, + 0x22e3bb4d657720df9174b5bc721ec49ea213157e0a59d0fa2f2eefe9a8bd2376, + 0x3f35d5ab9a8715db37918b791480b3190493266747e93b2b922f17c4a8d303b, + 0x71d91869ac439a23c518effe61ce68bdd578204dc70878ea949b980e8ca5765, + 0xa5afe6671b39a880f2953d521327679dfc02d2cfa739e10ec0ce898a7e606fc, + 0x1a13161ee9c83cc5dad2019e320b65c9c0fb13afe6a473b03242fdf77e80607a, + 0x3026cf4032ab73cad3fb5363647b3617179ff403dcb0738688848252d5b6f2e, + 0x243e0c7d13dedc00a5a66e8ac3041de9cc0f107c69e38e0a5ac807fc57523424, + 0x2a9fcc31d5ba75ce13add9a2fbdd4bf8478f3d286638267e8d9889236ab48999, + 0x12355d3aaa77205407a218c67bf292f7389e48078ead3ad8b44a7f26b193a571, + 0x2fa06fd721aac5819fb8d72118cfc36835a96a57466c5d9c7ded627ff5f0925c, + 0x2009a1047f9adcaf5d077ebaa1d827ba73fff81d486a9bde79f66ddcf7b95670, + 0x23afd3d3c0e2e875b2a847cd2a686c1fc3c5837f41935caffa4bc413af451491, + 0x2726dd1f3fdfd05c33efe547ed972ad36a60674889b98d1786a505f73bcfe296, + 0xa1f79f8deb6a176a4a20a89c2f3134f7f2288e5e698d8daf9662f79a7df7253, + 0x233dbacfc9ba8c6e47588085cefa90f7ccf223ab050c4900ab2b262de8235c13, + 0x24e7c1d18385735c7be8ed97b21065ad3446b3a44540e129605efcac8b1d27ed, + 0x2218b114e6a493d7b5b767736aadd097ecad86b0f58972ac0efa546a5f1a4726, + 0xfe60e24f84080950e79f2dd5dc8ef6dcc5eca3bc6cd608f91b9e05a4575db3b, + 0x1d3ebedf3c91e56b3331c235edfab0c1de1b37c4fcc7506755a7e90b86a988ef, + 0x5b18530d7ead1dfd0d305e24244c90f8e66be3ff5195efa2c7f9317db72f17e, + 0xddd0529998868e7616a880793d4bfb9d9a25f7cbcf4f894d7c91443dd3a3e0f, + 0x58611fb32de45f6b800200ab76e38d4d88152beb86ece1462c2129509732672, + 0x2f4954ce179d833366a6cace0bb216235b5fc8331a0ef36ab40cf00881a1592f, + 0x10dae4642d4de29143dd5ae8b72f56fb7800d664ee0c121c9990e88976ceb878, + 0x9d1b3f83888c3b9a018f779ca69c7480aa60868a1dd1ae22d328df4667ac672, + 0x1f8cb04b5c6155dd321920c129465f8033161f66a6629acbf67d0ce8609cf2f, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x697468fa48ffbef2def6f8859c1276f40ed8603b54f336a9f5bf6c986dc4472, + 0x14845ae5256ccf9f52ef754d6e9f93df1320a86b1d085b642e9ac35fc8c659d4, + 0x20a0e20ca969d47c57a6fbf1d7c7be6fa22100b7c59f0701d589dc3a150ee595, + 0x1a54b1065df96a7fe52babdd1c8fc70975c19190d7e3f0cb6ff113eed0ac9601, + 0x60a95bf72d45427efcf1df7d0374ce564d824bd9371afbf03b58a7c2b8257bd, + 0xc6bae2f35f833cd1099626a254a8dfda1efb2aa199b74f9fa99777314688d8c, + 0x2e075d54e2f7837c58a23049c4c5bc210731775ef5ca93689d8e411d3e25c05b, + 0x7315b60ae704cd80a3649afc32608e8475c1b87ff88966d8e4bddd6bd5ca97, + 0x1c5f8d20fda642dcd8db43e9361d4188a8f48dae9021b84073ca261ae50f32df, + 0x13671823102cac626ae6c133fae6cc40e2a2e2d7f8a1191889988154b605a740, + 0x10f3889ecee1bec4a5e6c7f0336f7d193acb1cd6cc1b5de815daea4b3b760f8d, + 0x6290c4b1f8ce6ddc74050ca5d58142389edfcaaca0b3b23514e864e8aeade79, + 0xc359d3a8e6913715c369908a57f93775b7efcc28d300317a9c80812d9915a1f, + 0x1b7906c8c29ea1eaa52ea3073c80c666a686912cd52e0f8804d61087d3968f86, + 0x140e7636bb9af6ca0bc1a25757a7ddf14325f99ac07e34c22fac95cc25b47d2a, + 0x1a2ffb754f4df24371e274a2080def1f1eae921b272813446142b708219a4277, + 0x8925574c3dd6d39347dcf0d188e603ba86c85d8ad8c7bb96b503be1a4b01fc0, + 0xc4d557652fd1a40449b5245494f461ae0688771c6f4c6e287632ef3d9e19d86, + 0x2e9c11f9d848f461f467311174d68af36dd75eaee8fdeb0938fef3412cd09e48, + 0x198350eea49489bab667bac0f4c78b18f31c0d2fb615f3475ad0050bc0e99525, + 0x1feaa21fb6aa40e6d3b99d464f0c9f21c0e6d29fc4733bbf6513a40ff15e4db, + 0xbfe6c87d65833b8b7963d8c909b789d379c0a822c03e33591a77bde69936561, + 0x9d31ad63366f19f5de31ca26fddf1223533cb9809ac773c664e86ef943a5c97, + 0x2092b2bc145c4332074825b2deed1cf735a606687b4bd62d6b70147734da47f2, + 0x2c650be19dcb6005092570c6981b6c6701c999aef85850dd7524c99b0eb50772, + 0x1987da1e063088e505fe1c22279a2eee2ba492e2daedbf9bb7ff7fa0ea0c2244, + 0x2d964e6c97f1ce9fe98ec13e03e39a1418f7b586ef6b624c9b14fa7a56d43e57, + 0xe44e2dd16cd81347aa62325235cdbeac7496fb36bc98a405fb658891be8335d, + 0x2b3f3be77f4eaf5ee65b1dc9420fb479926f707b6494e45c0c3456c9b1149ac1, + 0x4510148cecaaa311e8815f62e0c11155a204b9e8419430708f270cc90369541, + 0x121f5e52b5ed6d974d5d8b5e9d535eb69c207cdfa494e75a99a26aff13c9c3ae, + 0x250897c08d5b8b109dfb0a60a31e2509ebfb5a453a57044cb4d1cee1cb36254a, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x170ded62e47a24d031e0d09a9739c181a05ffa6c072a0ae4476c8459026ac92f, + 0x7a7d93f07720b729d0fc11ea7c60a819a915cf083fc5590c8034b3e299ba0c7, + 0x2b38674819134ea743614550a13ff1e8c4ae2dca4c098dbae7179c8eca382411, + 0x271289dc176782bc802a40e2b98935e1f0cd9cce1cf75187e8bdbfc5fdaddfa5, + 0x50e0d49763f9965169c815ad6d976f2c1502d504427294ec650162b32d16249, + 0x1e16a7619369f7223562609f8571294ff3134b6d2900818958abb801ed25a2a4, + 0x55be327e8e9177db48e781385c7cb9fa1eaf7f944ad5806b8040d021328ff4c, + 0x1e218f8a23818b358a930aaac6880250eaa814f4e5f4ab3720bcb53cdb1f06d7, + 0x344ffbdf73e00c5ac9603bb8205edd7a75d44a8663da028fd643d4d6f4c2ba1, + 0x127fe6bca0178af93f621d5cb8c0f000c81096f0b6d97dbdf51785ae1d35581a, + 0x286df223607d95bb861a49f083b6dd9eac58b63dee9aea94b87f4a70e6e06e52, + 0x8e3e56ff4056ea0cce72cac7f1ab3a3f039d5948bfe24c59667056ede70e1ff, + 0x5530286c0e7eae0c6b693a0503fd0271785b1a9a8d159ead68b2777b07fb552, + 0xe5a8dc54f4762a808e384f96b9af4ac56fe9a046a3ce354ce3f7b02fe5f8840, + 0x12ae091a2d3ceb050262f732366d0461725681ef6a2c98e6cb2246e0821462f3, + 0x1bb12b01d476fb2d879e3d80e38294091670654bba4f2cc2556bf47a7fa3e533, + 0x183408f575aeeac085a605ea9934dd45294c7665bf3417c2ee55fed79fa3ff4e, + 0x13ed068f2325d6098bf97f4201013c9cc366c2212817303a540fa21a530b2186, + 0x86a1854cc12612ddc29d8130a224448fbb3f07faceef1c457b212865cbaf7f3, + 0x28e0905fb2b0cda24805076055e7a974487c163f6e275de6f0a79c2953f42686, + 0x13482a7e8bf17cbf0d729a877b9374b9bdc382818d0829df7785161c845df5a4, + 0x411f1eba980a1c2246e9dbbfc95ed50786591e99706eea93b50fd4eb7732792, + 0x2e4d2ef29fa7855a8479c385ee585e191afe05e4948d3afb261713ae3846944a, + 0x14d0b018b332223d8d3a458536fd4bb2c8ab2765b35cfbd1b4f5af2bc7eebb85, + 0x7ada6b05a15e228c703ea1deed0d89a090c888e04aeab93b903260d31fb63ab, + 0x2bf8f1482d4178227da9ba8141f98d764d7d25723d12a474a0aaf2b6f500fdf, + 0x1771ec5e8d202af9fbb5a6ccd92808069ff98a103ca38e60216f4c29bd138027, + 0x1cc45818383e71faabb1f0947a7f2e2c6fdf84ce43bdaeb3108eb95c853b951c, + 0x21ca4fbb38c5efb489a858ed9b5550cbe80765807ddeb5403956a91d3bea3921, + 0xb264544c114744badd140a81312486c6ece15085107fe41743ffbc42457190b, + 0x63f973d8f7955b230c3f623e86769a8f1fff6a2f16f542aa5d25450d77dfa26, + 0xca567c8c6074baf8976cfb1c5d6f2d339dd69b91c3b86360bb72b6cddf2a05a, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0xe84546d43156eca6ea9945a1f0bfe0d070c7b5f596a165d6f5b2db25d70c898, + 0x255224468137fa5731f4a79531b0e41467fc167a73eff9a2f8606ea4b8854157, + 0x5e444e0bfb3002592edf3b1a17b61aca96cc4f55369ea0b858d00a2429413b, + 0x2c9547cc8c30279572f43f6c98e57d007a8d8e00afe3232f22c86d92cfb3302e, + 0x128d1e7dd33b8a7eff38771210c3e2e32542927ab8a5bf70b304eac65a5e89a5, + 0x117ea550387989a27267059d04eab27171d97ad177b4722b9076ac7850469259, + 0x9c2d962801e81427424c3b82a3c2590f3d3a015f5d05dfae03f1646e85b83a8, + 0x26d1151c34d444d61380f618137cd12d3856a5112c1a229087d5237fce352402, + 0x71de2aa9593a6be60d825df98f433ccaff569e8f454b57a1a92a3a179419b40, + 0x78af695ca1926d0211a0c74b15ca6a21b21530751b6c89f16a7653d7b749273, + 0x10fac024afa92974f4f4b43777c31f0eaec838068e24173416e3e55f18f74229, + 0x252a24164cb696970f2696824ed7ab40a422cd2f561c1add5a7b94d9c8788416, + 0x2dc1cca380599b8d9c74524f5f370ecc41d22c4c792717a7ff91893c9e878bd2, + 0xf1970c566c802ca51f328d7a61668732660b84701dbcdc7388dddb0d503d32b, + 0x14410ae146ba19441bdfc99f88fd2425a30458ef81a97cb0757278de7c71b6e3, + 0xea9dd39706c27da7b07438387714c8e986a37c6bcb9cfe0aa413edb1d426620, + 0x12a0ec57214d783396e73e66cd8d163ae207afdea093f62ca08c1d03849eb81e, + 0x15f6e3cd0868b4e3bdeed8670ccbd35b084b2ec7d9f70e1b0e1bf9179f4e7aa2, + 0x273ffa3f96b6f990e5bac3da9121fead4c55e9a53a4cccded8ef7768777e04b7, + 0x265c7d50300accd451f9d10a056a0a9c4b61960abc7ac07f405544d2be981cd3, + 0x25704ec82bcf245817c0b0c38428f80e097d181fe4be674c56a431704b81220b, + 0x2bc004a70f93825fc7dda4611642819d5667d0c84de02d108fa24e7553a8ed9e, + 0x2c67b0e93decf3dd43ecf2affb6c8ec2681b530e89f028592649fb853ab6913d, + 0x25d1957093005c4eddf0f50960ec66bb0a71e99dfe635f3882224ba50ea2a19c, + 0xc05aad7df610539bee690ff338426700ee57012dfe44b456047c168d9f230f2, + 0xa09feb45b441685f960784f20a9daa679ffed8343997e028fd527f1c9615f1c, + 0xc3317b6e0f17024f3e8d48d7be78de51e60037b098935f715c5f7afeeee5559, + 0x186002e006875015c7995b512ab297b9b6a2ace2f8b1f23384f545a47a09eb4d, + 0x607f219a0a42d65871803946f468fe1a990978f7a7dc0a6565282240befe85d, + 0x83054c73153f2594282f425afb21bc06076820a2a936ca2e88aa93d198ad89f, + 0x1d279f18a4b248bbc61bf2647394bdced0fb95c8acee6dd036c0ede0c250049e, + 0x2e9fde89ba2dcecf4a0d11815b6dd2a93ad007660b67c14e84e4845521b47755, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x66bfcf07a648bceaa19dec1031fabc57395c4dca3503000a98eba19c54fe970, + 0x276ac7d1569f671ee8f23ea68b34b200488ba7f18d905e67ab0148bca152d25a, + 0x2f20f2f426186af0ee321282b00a2a641ee2b251399734d15e19af27ecd42de3, + 0x1c96a460e778f4af5015f52cd38cf2c41a6a9e85f6a30bb5f3435dbccb7b9e4e, + 0x227da7c9930fdc00476ca6928729411b9e65bdcd361ad27b66ec4c4e5b529a57, + 0x27b1127b1ce6f0686e0722d5c5a0cf8847ac68dd8eb498a1a2f6124a4e7d3eca, + 0xa510ccb52f446c48a9d886d6b7a6705680356500e63b4adfc43608a30c0d5ad, + 0x187297811a78c845dcc821d8193d2ae2ccc8be6fc0552f3e810ed9a2d044d7fa, + 0x229793d98c198e355838ad9410d16930e88ff01e0a86b8074ff75336afff596f, + 0x1214cf6c699c46ef88ff3713be9f3beec4ea27cafeed293326c7db4166b31ce9, + 0x2099cfaccaaacb25e8c1730ff9d91c6f82fcf436589b18d1a092f61c766af9c2, + 0x2322866854d0c03dbd891bca034f176e411dda04203b47ca04ca2c2a82aa5f23, + 0xafe4184fb8af7ae9177ded93afb51dff550c90fd4ab624c95b9e0bdb275ffc5, + 0x18981ec4e7b2dd5b75057171332150d62e2ebed5bc63ee632a6ccb4146745f94, + 0x1fb6ac0886f9dafcda077d270effeb93aa074c26a62ea6cfd141b82324dff556, + 0x2aeadacfa8410a4c07abda74bf85806b7034785279a95b17c6ec7a0ecbc4f72d, + 0xe640d01e5ed243961bd4361e2d3b669bcc5bf35bbd30181e231503e0ea04329, + 0x2e878ba571f0ae43c5d79cc04becc7c8e65316c9b6b83c0cd56124dd51966ffc, + 0xe4671548304dc6301e30360016f37d8289e8570c4fdd1189cc7fadbc02f6719, + 0x49f32a110437e1552ae6163e0890d534b044bbe2ff3839eb980ac72b15ca83d, + 0x29be7fd214d5ac3a21e930773ea4404cad8e7b751b02e186711e07797362be6b, + 0x6d4247fe770b6bf51c7b739fbecc3aa418f5920eef7624676835ac1ae061d66, + 0x21c02a9eec894a1ac2eb56d27410ad620122e3a5adfb8a8f83ee617f9525cbd2, + 0x232b4705581121f62cff2b79d0c8ea43db47514fadc741b3306a6900a0bb9021, + 0x2a3137d0e0a9987d06f2fd2dc9f61c22e3df55d4929a2322242d6a6b36e6141, + 0x12814250a734500401e41c65da8949663d7afe8c6868643a1dfd086389c29d15, + 0x1d221587e6acdcd041bc0e164a9ca84970807de46a767383c44262cbfa1bf972, + 0x115ec085da8a3839212ae49e93243a25f3b2f34c53b5786d5576e8a5e626319e, + 0xcdd08d5c710e497a583166923360d16215ad9a3a1629daaab0587b45de950b9, + 0x921c454f7b3d19a8c766875963305f4b4d6f7f8be1a2c4119315dff25c111a8, + 0x1b87d132d08fe5a6478b2ce4f40d73b8d4522fe23a4b26e96b31c9bb6a3bed69, + 0x22ae2be55bb3c7640477286be689776e1514c8872e1e0361ee36b13138d0f6fc, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x237ac6aaad2e2ade78bbbe46b6d53646c7404a2fba31795c331db8da4145e5ac, + 0x2877189f4c0d9fe01baa33a2b820b84a4a3a8b92964ea9c7b2149e4a2547d527, + 0x136a6e0031d277288d586824994cdd3da32221fc94bd9c961cbb4a371c6d16e4, + 0x18a97e7a120e79f25dc87650a56a580604ad0fe99a7b5c93b295b7231fc13e35, + 0x298a890330408d2eb3e6aa31347e4d68c1bb979a23d9c7266e63b47580fac913, + 0x191d5d7b95a739bb75bf19d63f8e787dd14fe945408aa987c749ac01a4e5d476, + 0x2449e2d526e2920627d993eed7cf4de57155a00e5f071f059b94eaed73645b35, + 0x1a0364ee68cb9c8a7a0e801daae0ccc07d92b82686bf5bde72c074247f6767a, + 0x1e88daef2272c0f1f9792a6d85f29b403deeb1f4f234522d28112c466790ce71, + 0x2c4b0d1c66062af96f71c6b23ea770f5e53c39967f0d3b1a950df67c9766432e, + 0x7ad869f9d13d9b270b37cf255b577346ca286f8979e546182c4b9139368d186, + 0x2015d96937e823b49d8eb2f7bcf3be82a8b6ea9bf53b5fdb52a4bf72c4375a9e, + 0x1ae82e2228f0080b37ac0d77083c3613fad8242b420de1a24fd6376cdc8d79f6, + 0x27f0ebfa6e2ec9fed23a25c07cdf68a7dd8bec39ce045c15fa0e921b75df31dd, + 0x1b129211eadf48d228e7a13a9bada042edd5164ea595d523503727419a5b6a5c, + 0x1541b4e3bd42e9287b5e0bde5ad7c3ce76dd326a0e53418892067a6cfbbc1bf1, + 0x3cb9cff50f4d9d174ffe46e382184d9a99306f350971156b859d76d13a4200e, + 0x2191176d2fe6b3607227f17aecd711d31ace1a71987962dab59e2d4dbdfdca3f, + 0x333a98f84a220a59b23b41a6eec5f1293aae65a9c1412fdbd05b6c730e7fe86, + 0x1d3133dc479ed041791efd9f449ac6b7a2ab67089c2aeadc033b12389534c8ca, + 0x11a957c8acc043e1dd0228a3bc3e2ca5054dad13c1c685d3fd1c7015dc541b88, + 0x9ab1d5764d1ab372770e72a734f3234e944f231d55b4802feeea21ff00cffed, + 0x2ab07fca009ae3784d9172cd0de7a03ab1b413207754249d54e0115671c61648, + 0x2f26dcb5b014b72bf8a7df0100847754ec09bf69ab23050aa6ab45b8bd49a8b4, + 0x12831914375fab4bf02d5923d4fb07f59ea7ec76fc424eada862287fac0121aa, + 0xf01b766464df2a94717e0b5670db63546816d0ec951e74fabd2070364513e10, + 0x1eec1596e07215f120c71f3b7fe2c872c0d1f0ecc2447cd0382ffc1b3d74ccb9, + 0x13a9df3f6c9c0363c8e81bb2ec06ac0124cacc3aafbfcb99ce0d12b15c1d960f, + 0x9941a17ae1ed8d69ce140125c49306cae9ea0a037563cd93dadcc09c1b8994a, + 0x790fc3d447ed1058bd5eca57d37adba8d645d5c42e7441e5c508e6cb2a7d581, + 0xe11f8951edc551adc073326138ef3493ec812ed643400c53da02d49033963c0, + 0x1ef50d438e0fb3260e615f2044df40bcf70bfadc6b819481222ddc36e39cf1c2, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x19a6c9e51754a1ba0ac6f28381aa453e929951403794d3f57566adca54593cee, + 0x2fe2b32027a048ab3c9fe57e0e0e63168c1beabe9cc3f5328bfc6e2620d1c0a8, + 0x252a353865d1bf6df4e243baea612d8d67a58c9b91b68be6f6ab9fd6cfa6f052, + 0x2445b945a65afd2c8c6d1e12224f0e1b5a7a4ea158a67dd4617f8d408239bd68, + 0x2aedc3a83dc324a21fc06b06f1394d6a5636c2f191f252e9d927ccab3b8a47d2, + 0x11ef3c2372ad8e0fedad2ada9740cf104fddfe5f26a74759e174eefa6f5aae49, + 0x16540a4f6d867388866e79a4f327c50bc06c7abf88df4fab1af55b9693c0833d, + 0x226a8cf3b4fd93fb027602a84e5c84e19fabdb3c6b0641903107238e7473f4d0, + 0x15829949331aecf0006a9e8f46f028a13efb7754976721622d65b6f9cac5756f, + 0x219a0633cbffa129b8be664c32a15d8c6f307fb00fa27267628de8a7cbd4da12, + 0xdef3ce304e0b1f868a4036fb628bce381a92931de8dd658f9a4db69808c2c5c, + 0x2bccbcda22270d6c62effb8e392bb7fb97637993bc102538c5cd58e88a228a4e, + 0x188172fe781d7b1804c9875e732ae5ba92da30e3fe79193172a9b2ad266b912f, + 0x1f30e5d70cc514c78a878299f52f298eaefbc73811fd69a8af04d6e1b235f8fc, + 0x36dd7eb2d37c58f0064ef539c409ff1b2866f3e37995a0e6b63d2e12794a65d, + 0x2943d171cc678d4b3e7bde9fba8cc6bec123fd9e18001704074c6b53b2d7fa55, + 0x16d3bd98a136cc6ed17d71e7ed150e659bc21e304859d7e91db4a75311b12c17, + 0x2cc46361954b156f22dea4b4e5836d017ad5e866df6f9179696836eb0b9ecde5, + 0x2093732993458c1dc5075a90772eeb28239503ebd2aee0b0831f253b5795f431, + 0x26fb0a33d8ba99f9d666fe22149b4b9c288f7a356f7d4d62ca019c426eae56f6, + 0x2ca9e5344928b4c5f6f6d72ec4bbf9f331563b93f78c5b6c693f9ca05a03b9d7, + 0xf86ace9eeacefd133e6f9e5b27e768d4dc41fa8a4b6d0b643d59a99b972b97e, + 0x16aa6528c3e5ca07060d40caf2050fc7c1199f3ea08c4bd2841f8816f8ddbbb6, + 0x1aaf0a3512751441abaf663b51bccc82b4aa9e031f95fc5ad831b6f5104b32e8, + 0x1693d12dc33373065921094c6ffb59f1f0361b0c5ce1b20e8f3f4f1bae805df, + 0x1a5b1eec5d855cc716abacd6b5ef79ad4813bc74fa3265e0f4966768088e24a5, + 0x1a98219aa97845f039309ae314e1658caf33c72235d5a045a11231048dc85871, + 0x27d38feb2f3ca73be6e78b2f51db9e904bd78d3f7ed495634b22c29b28847943, + 0x27b21eb7516a84220bc79c6ba5a35fde0c5804d4dc2b469f034f93245cd58e64, + 0x10882cc54c76c057e84e296d8568fd68a41a86bb595cfe644def5dee16e2b60c, + 0x2a5a015eeff7cd48c5f9d66baee6647ebf41fe73f15999b85aa738249667f809, + 0xbb55ca8ec263593081a7f140c88ff0eca81548ce6c2fc66d3c9041e7e61a52d, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x11a95faf7782644e66dd690770be8d58aff9b21c252a17353159e8e6a9cd2d04, + 0x1809bc4f74f8da0e56320179b35cfccf08531a383f8f38f055567f54de408856, + 0x29576ebe8b472aab3c418866b657b4bead5aebeb46731ac1686234f997c8064d, + 0x15fdd752a74e076a3bacc425ac17ef974ab4ce00d98e3b766e4e9da506338bf, + 0xa39afeb11772f20bd44212cc5274dbaaeb912c073ab120a0e3a5cff2f95321b, + 0x1bd3c83976780db74f4bf261b609505ba17d4269a823fac360138142fb482bc2, + 0x2455035975952299afab678e90178017ae59c02e88b66acbfd33a9a97e4053ec, + 0xf54c6e582707940d37a81057e0331967328f0402b139f40a152a537050d4eea, + 0xf3edf4b1021df9ee75bf77288e35c135bef2e641317adbff2cacd1cd63dfa68, + 0x15a4b29ef2de3e66e4ecbd99b63fe784c3d163534087d6e752935e3a66a81061, + 0x22de01c525edac04ce6418e44df62cfce81abc3238c0832a5721e81410124db, + 0x2f75cfbb2d72a93661691b3c313d73cbf48e570aff4a8981565691dbe6e7244e, + 0x176215e6dde458ba94fe6cd32886ab490c44d3f35708fb83ac032957477470e5, + 0x125224651632beae2362689f3f298c3d1cdde20786b700cf154dadf04aea02b2, + 0x25adc0480ab90662ace18ed71d4ec243b5d118bedf866880e5112278621657ea, + 0xf1656323cf512ca13dd9d53b6fea48d0bc03b7a0a510a1d1c376d7c879c0a6d, + 0x1f7fca35f19d9bc9a9c510bd904477a82a779df52b3d938a34ad370bcbe107a9, + 0x1650f10d70200c4cf9188ae72b638a48efa885d0d57e4eef3bad1908117cae47, + 0x2efa5eaf0d9848a2ba0426becb0edb4127f4afa0b9532f3cc8f63fdc6f9f14a3, + 0xad402c14a8aefcb0dc67b5d3c1df188d1cece3de0f53cb313bd630594e20123, + 0x9874e7aac804e0a72c21eff6800d99327636c1bd05752cd398c2e19210a92c2, + 0x127d6e66dc4de7272bc0e6174ca40f48618e1c90ce71f173e0363278e6e26edb, + 0x178b0d219dc9fb0d491fdca28d89d4f41d0e650c29d8097a6ef982a3d45686ee, + 0x856563611627d9d176f629668c19a7195b0bef83a02011485596c0fb37595bc, + 0x4f01e13e7e01f0fb607f39a334e5ac5a14649c65007df2e0125d2c07f165f4c, + 0x2fdd1f6a4746ffc3721fe601b31335874a23c0353b217cc6a65f98b52c48c32c, + 0x17732cc9a7ab756b3ed24f4b5cd348b27c476b0804a47e8e8024fca28b858022, + 0x8f9e4a25ef65884dd6b159c396447f11f374cf781a8932b436e428d8407efb0, + 0x185536364010888ec827263bd36282a0609556021920ad8349159c80d6895398, + 0x1fd0879f9628b76eaf032db092bb6caf8a03c437a8e7cc0c81c9531213d61b8b, + 0x122fc02a0d06dcaa8bc1ba52dc7905ca13f2766023a8e7811876071cb0bcbaf8, + 0x8130052ffef7fbdc6d1bd38334212f34f3715f0bd1dfc1b36eb58331f5e9106, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x21c85453b5c8f53b3e43499159ccef5152fc9bc3b14cf1d67e4a80e49bd83b, + 0x273d34ed60e945fe972b67c2c155653e1c5c38c4cdff7c5753de7c68d3bc3261, + 0xed8f8c0b64423895664ee04c994ffbf1aed16eb8f6d2c05b46edf07a56d2777, + 0x9dbc162c39375cf6247de315a85e1730c451e59671499b7bab9f73ec47c70c2, + 0x2bcc328db7c571f892d3d934ae7c031792571d716f51494e8b10fad60b9f52af, + 0xf2333e3ab2c7a3c13420d4380f2a8fc867538db7882a5fa6a8d899e4981889a, + 0x1bebbd7c3e88b63ed37c373e359a741a38d1b8de608adcc050b051dff7b51580, + 0x101b1cfce09e9afbcc995aee85711574de371ff76a293ecb26b4796a16bc57e9, + 0x9866b876de53973d54aa01a3095719031e0a5ea78e26194422dfaa80c7e39b8, + 0xd34bbeadd10a0556a40cb0e5f84ffd96baa82621d7d850260115312fef1a5ce, + 0x1dcdcddcc0aa7ee28522e5b331b2805fb95a75d2e90f876940091c4c57345433, + 0x222013e1cb04b56d232f806664f4b950bee1c8965d49dfe59c7d9a7f37be70a4, + 0x140eb0a40f600989bc70937e2fb3db0e1cbf4ee953bb5dfb11c3ac257105acbf, + 0x1c2a10c01046a2bd06eca1a7850d8815dba9dcb5002710d469763ee12ce733e, + 0x4be5c9c1a16eaf24f0fd62603edfab2a731488c6f0066a29bdd96f8595f903f, + 0x2aa1bd7546c15d05452c1ecec07be1a96d1a916f6306f11eaf52145be3efc41d, + 0x1ea9d7108069582c4db4000fe9c999d50a6732feff50099ed5863996a0f4dfc2, + 0x244b02346c1e7aa223e1cd73cc84de1c6a729e722410bcd9c6c21c10f81aca3, + 0x818f382294f0d2ad1e50c908d6d58b0567eace452491c7e7e2ec8f02dcdf30f, + 0x1a889d417861f076033045816bd9d152dc38a64344876435c43145551e938c57, + 0x2a741e0f1842497fbf481fdb838af76f016c7c7f902d0f1cf91946d9b19b8f0, + 0x6da5a57ba1e1f0e02b65254d7ba4170ad9f42f8c2e209dd3482d9d100dcb69c, + 0x2b015d97e986c22f639d439958e5582192ae2a3c5e63a93876ee2cef01cc64aa, + 0xe6fd84ece440532b1d2a84794a2c0905d14dedf21f1cb88ef011d6d40a44966, + 0x180cc40f9b1a551d6f21a2616a31fb14ae3de6cd3f90905090112f08cd2a517f, + 0x113bdae7dcdb55a5a29449e0196a7ca19785e8f406aaf81d74f7c658604d7b5a, + 0xaea1a111b956238e2034bd82eb6566729d6b744738d0f907c24e91cf0e270d9, + 0x2d877c0d3637dccbce6fced14de0db189ea37e2192595d31ef7be35042b49789, + 0x64a1369e5439801597f5f4e2a95058e001cc3b7d449aa87f991c81219590592, + 0x133405bb6e5e245a0ec3785cd300ed55706f465191cc6af05debfc09ff323eed, + 0x228bca7f9390e0cfe1125af0b7ceb2b228fe7d373e3bfe077385682669dd6231, + 0x90116384ea569082bdf437341c03094a1f388ee217c0e6aba3987a55cf62d3f, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x2dcedcc12959aba1b815150ec24051fb4dd8440208b0f4eef706f364709fd64e, + 0x4aa0509e7a94554490885f0bc0055b4f23a003e14a2cdc51a8f1500b738512c, + 0x1ad3b6634a63d1bd97d8d745888387e7030be2bd5219c84de5a4b21f6e6d5c9f, + 0x2722ff91fab311d5cd493305ca2e581d23ab35103b7a31d7436fb4351e5167c2, + 0x1756e34f7af0be32dc4312c914ac48b60ed892e0a941866b5990c475326a0a08, + 0x1f9681a26d581ac87fc486d845382aa8afb31782fcdc16ae3e996bf79e8910da, + 0x2c407593aa6fea946d0ec1289e59dc993dbc1d689a02efefd916c42b56d4e056, + 0x12d5a1f35a3bee7be87beb690bef3b422d4db19f18f457345c5b13732213de41, + 0x1e444d4510e2cb542a4bd1af5232ab8376e5998f69193243509b05648b59e317, + 0x1c51186bd573f6d8e39dc9e5f85ad954ee64951ba2455dcd9f415b2ef44813ae, + 0x24c84617d0f0266fcf18464eb08422f51633915380696b571dfcd52fdcab3825, + 0x4894d26fbb969454287e1560c81f0bd33e93a0ff0e360f882f03621ffbb724, + 0xd669e170c4428089bb490e8af37bf2b4885f61f49154eaf4bca6867321330cf, + 0x54ead1e70a68a2a5bf0f9831c8b37e0c4692840a5eecce2f10842aa9ff4c77d, + 0xaffcbcca6d353dc0060f6c0e87a7ed6926d6518e2e20181e76b0ebc3e55738b, + 0x21fca621016a771a181efcaff53647cf8ac55c30813c7e1b7e0c54b1b14d4fe1, + 0x12f2e46957b88910c30c9554fd01780e074870fb9df0252cb735dec70dfdd6df, + 0x16baad45361a5052c6008a02803656108d8bcf1ab65f3d1ee9c866e2a04f1713, + 0x202cfdc4cb85ce703b7ac41cbf904593481c951f9faa52e44594c3d0aff5f070, + 0x2782837366366c2f9b943714e6a11097321394713577fe59dbe72a78f4d93741, + 0xdd863bc6e9a0abd947b2684abe555a269da1eb7a491ea6c5d3c44e0cbdbc0d6, + 0x2b1ab0a5b5516d7a4f31b68c93f21638a3bbb9ed321b9915412b422929e8d42d, + 0x247c684cc872df52c2396d52f5c691e459e181546cd644fba41843beda35f07f, + 0x17b09bebdffdacc6d3abdfd4fddeb0a1d04150563119def60d9ae9de6b13d0b9, + 0x20377c6ac1d667eeaf88e001648da149ea26ecbaacaf079f0a089fd6ec42694d, + 0x27baae8b9a93a09459ff4c88150b93e9fa3fdeb4d719d37e4fb03b29afde1b0f, + 0xe105b04d1d6efb0def9dd3f43655181cbe4a1ea329e779cec335e27190d0840, + 0x1684a9463b01286e5ddac76b990c6ae285c81fc4f7e7715b1ddc827e5caa82f4, + 0x1a1171d2f0e3c131bab4ed613fa111bb85f3605028028f5c1337b4ab542af356, + 0x228742f926c112c443bc2e362be8a44c49ed66e17038f7be297d51482c548ad4, + 0x10bd84eea945febb47f7296e5bb833378ec26f61c36d954b87a5423754b0d1d1, + 0x2d17cac96f225898038e5ec16560f6563f768a7e127bf10ff8ce1bba63d032f, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x23091d6274d72f0516c11e52c62a89e2c218acfcec269d8588246bc63dafd307, + 0x9400b7e97812bf8321b96b3c4bb695dab509934e197ef9393d9921a320fdc5e, + 0x1c9c8e269b7b5d2527e20b5d340f2978fe4f0b969e2b1f33b5ad8ace05931036, + 0x29bcaf9978fe301ee64f032f3b6c5aee47fa89a118490ece975e4765a688e277, + 0x2c43ee462e5eaa57409884a4bf82116fc74f060cd3ed87b249066bd753e57833, + 0x1045ea9efdd2d37654f2f419bc1c1e07dffc13a78e78329d66a80e816b75e0f, + 0xbdd990f09c0fbfcafb0ad5d2e7609fc639f4643262b9fe6064b1cd9f59fea9f, + 0x1cc3aecb65d88c117e077773b2ac321f1e35552bb82ecfafc19a6d7f58cca0b5, + 0x234ca75eda2b98da7aa4bcbdaf01b94a0ba116a7cd4def0864e27ba56623ac56, + 0x1e5844a479ef874349416efe4ad14c691bbd4d60b6a069ff6fccf0b4268368a8, + 0x15cf4b909eddcc0af84d45aa2a5ce40f004cea2337de82214b5b1b8bc25fafc7, + 0x21fcbaa23db9816f459fe5dea6035f4416bfea9e46b1ab150335fc986a5d3454, + 0x23096d193c542015f5ea72945e427601d8c5213652cc7bed15a26118408f3528, + 0x11ef3930fae556e5688b2e5c5b646a9bcf2cc8c9ed84699798e380534da1ba1a, + 0xb2804a0c39e0406220d23e5180ea34743b823259dc5c037e27fa14d97aa1236, + 0x293618a713ae76e001654396f1e7ce9885f07515d1a52ae6188bb68411cde19, + 0x2083bc523f48f2310fd04db4378e73b3e4a774c04c82721c347d841cd429c1ee, + 0xaf7b362c84812df2052d0e04ad07d830100079327567a741f0e33b05f20a3af, + 0x2f0a9bfa024571a9eaebb8b6c838ee153298f8d66282665b8d413e67fb9cfe75, + 0x8e5f97cf239846c4bb22151c4fc6b54f6c078339d48834cb674108ebcd533d8, + 0x2ad7be60b34c132d62758a699ee2b9b9902b5a66f4d0a1732957fa312693130b, + 0x2bd813ea81fd2be04cf74361aa9ec03890ae9dc9f2c62e392aa0077bcef5c39f, + 0x2e720551011b0b99d8a0265f870ec80f9b866a0a5f158a2baf5647f07ebe9982, + 0x2bf18b6a692d4c64185b59523fd75a045a4844d8df2d931c739fa453740b3cc1, + 0x1c166f7ccb69a59db6b374b355fb08d50eaf4df7760b2c3084b229e822d858d4, + 0x79b610d77c02e9a71628bdb9524d75ae9822b98d32f5bc8624e3512fadac097, + 0x1916de884fe9cac13806c4f7061488f0a57abd1ae403ab0257d21b48a0e411ee, + 0xf107fa1c9d4a774cfc10bcbc3b38fd7078e0f374b5e9bdb38e1e04d26d3c383, + 0x1b3ef1482c15923666e1cd5dadca82661bfec0a3a58f89e54fbe8fe2428669e9, + 0xa27ba24a2a7ad35ec53a125a0447abffccc68a9158523ff88cfd738b0212802, + 0x1a525ed62eff06bd139f3fa58d088c836c381a9ef859bf16d0c4ed2400463a4f, + 0x822eb9645c965d4f6b677191294e0b5c757d448ce5266f76ae8ff8898b6d0df, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x1af46f08f6cf19a75e2deca250a062244a541413cca7183cdfb8ff3496283677, + 0x1839ce61b8c72bdac116fb26e68db1136b21e762a80dc263434ceae93e71e226, + 0x7bcd29e7a46c57bad325631b9dc70f779746e4e3e83b6149cf7d65224299cc1, + 0xa58deb34a1aa7a97fbd6de55294ad6ed911731da0f1973bb30cc4e50f974633, + 0xc189862d767c9d55128b55fbad2c53c3c7f09f3cc3805404bab81d881c1f79, + 0x3f08f5db02c8c4197fbb743163fa98e215093b833ca0c1d709a30517f1bff67, + 0x1bd997c5ae62f46a4fa08c71dd8281fa20da177c45a5b5e0ea4cbe42a9d768bc, + 0x1dcdc615a1d29786c2a6b9d356e15f14b0516022da0c8237329d9ce31e6c9064, + 0x2125c1065d8c42af0dbc0d44be29723de30316bb190e487fac79c6c65180c6da, + 0x2a9dd846b9a9250303ea18da7dd2f67d8525074d4259656b9d0def7f2ee018d1, + 0x2a1da460ab707f31653862ab6df0bfaf474d39cb909d7b84314482ad8015bcb8, + 0x2f4620be83dd42a9810cef816801cd8a77d59146753fd9589a4437f43c44e295, + 0x2390bc3ee228ab2dcae07fd77d2f2b82b39be4a3fa9d15a82678d487a4ced7e3, + 0xa0245ae7c93aaba110979562f1bb38e2d6e47f8f58146c2e0af29a42a8f2225, + 0x27e3d9f7c0d6c32a9db8c79a3fff7227825679bac449cc5567f21edc213d94a9, + 0x2172e74151fc03eb201e3e300b2a085798e6d27426da9b9e2eceac40374c95b6, + 0x246a685246a9403eb01cdb380b39b49b35d649136870954260afc23e51129460, + 0x4f050f7043b183cf35f65e5590bd1ef9b1a88b9a1154e5a6b48b90367679ccf, + 0x1ad58c70ac13714b721c7e1e43474983524bf5ed75ea0a375964c17eef897acd, + 0x9d3719d52186421cbe870a8dc16ca12d479447bbc1b7209991d2ada9cdd0552, + 0xb2d605b80d2d16b8bcc936be91a9b58bf372160c58214d5d05340268db293e7, + 0x15efc1be172f0c1cf80c28816163d6281796fe3f767449dce700031a9809382e, + 0x18a72ca7580618a6772dc37da2d0ec3721130a93ed2baf7ee8a458215351c5bd, + 0x18495f1fa2b09573b0122a6f3bbc62dc8eda0c773c24cfec946631bd226a5222, + 0x22835e515350739783c361cb745419032be6d7a16c27cde776cd9a43509d5027, + 0xfbf1fa536a4d74e1eb517dcb715dbd57e9c879fdd1184956e1aea742c4b0c11, + 0x1bfa4ad591bc024f156f69c1c6ce033e65507f6f2a1b50f9a370ea96dffb4fe1, + 0xb48ee00c1a3b873da040822c8d84a7d413b07806c5ef6ee1670502a2797788d, + 0x1b0c2c9ff1649fda06155af9c401957dad06ba11c9d6c284ac3d7f6b2e02196f, + 0x11b9857c7ac1e55d6696b9323eacd2b75e8e64d863221f4c49b50c0af4ddc907, + 0x4d2913e434864bcadcd0a0f187751dbcfee68f8d42eda00afdf9fcc254a9297, + 0xd47a86ba4e4c33ab37f00aaefefacf692c1baf9b37db068097f619f44061fb1, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x2ee08c0e4d7f163fcd113539b4be76d5b8c6dcc306994016e2f50b4065ac0c65, + 0x2e4ee3771e570cac361666fbb6230033f0d2e5df5a43207f4c8c4642fc9ca473, + 0x22e78c9bd18311d225b9f88c117cb18e658747d500bbbf61c291fe7ebe2bed, + 0x1b015cfa490fa705be3b9f5645d4daa23c2098cb0939f019d1697019b00a4435, + 0x153d716532b1856b425b07c5cf73f7ec4bad3458ff9e031d6c191da0c5150f5a, + 0x25ddff7645c1cdaabb52a3ae26931620a4186ed35cb914b0cb76bec51f7b561a, + 0x21bdea71747a451c7e825e508ee4c40df40404c011cd5f7dd62ced05f3841437, + 0x2feda62db255b655f3be96a4847d2f1691ce658456697ecc602589c3ff0674db, + 0xd3187541007936963cd4bb6c93596b7cfa56d828df39d9f8ff05d934def0ffe, + 0x26e633f970dbba038ffa30d735ff34541108e2f7bc0e58fb25b8d038eb574c1d, + 0x23c8473f9504bc04266fa76bf7064d8980fac8454fbf44f68c5e93fc37bbfd9b, + 0x187a7a328ebe30f3fef7620ec582ae3b457ed1d8dff8a30d60c518c1d3f8502a, + 0x1072a4199dd532ae3d36f2c3f07359148be4d81ca1f1ec06bcec2c94b50030d5, + 0x1d9c9c64cced19734c56f62f6adedccf54aadb170d499a91617c7bc34f0207a, + 0x1b09945179822511bc0b3b20afb76f146b119051e2c6c8f5b9dde03cc761b170, + 0x29d1379f40c09d9a8105f1814f9cf4cfa8419d5442c22575a0f9836ff6728216, + 0x200809b6e7114084a23b259cc6dd8d4aa9beca3ee806557a250f98523363d583, + 0x13169f87f4d5bcdc80277fd4bf931744a09d4b0332e4e54dc351ec16f256db24, + 0x22486dcd2b50c5a6e8b08cdbe012907083817073b975a842751aaa497389a092, + 0x986aed7b10fc9cff4a80d5e338f69eae4aa25b45d931499fbe7080fe13a841, + 0x2a3346c974a7faa8f021c72b4b516dc527033dd96dd87a29013a54ff235069d0, + 0x1ac08487b535338f18f39bbb2410e0c04feed1b023c2b31a69c42843b46c7b4e, + 0x2db4eb2420d57123dc86f82c289788f4f5882143e70237ed7aed2b318f2f3f6a, + 0x179e156f0f6229e6259dcb656daddb273efbdc57b78b1800b3fd492ad4e2ee85, + 0x18f1ed42c2dca995ba6b2b418378159005da5fd6d46f31d424e404fdf85ecd0e, + 0x12d1ddb3125c15c61e1a07709ecd1782cad928312bf4d32dabc0f3244b98c067, + 0x19a555ee9a57b0f249f762e63f02fc9dc41421569e40146d27b805d6926dbd17, + 0x22905039eb92f068da4da7f2bafe65b1743fc2ac15dbd1dfb50b6a8b890fc933, + 0x2aad30b3fda588c43367320323c66ea6cf3137cdcf1306e93d173f1a5f5bab0a, + 0x661d95dafea3da65844c73147d86b8a152a0c737c6550d2a590597b6be28986, + 0x149f69bee6b12529d2a1332a22ff6cae413b864da5232181dce528343488fb9c, + 0x2f40107da2eba4e1d816cf7cd488861863a460e5e00780c3c07f56c946096b24, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x89517399fdafcc090ffacbfa0f82b1a356c182a9b8bee5a125afa14416693a0, + 0x1eb0320ce68e5c0a8b9b6c8ceedddf2eec4a8dffc775f43aa9545f4432f1597, + 0x9b3b380291ed46dae5ec6779af517d4c8253ef609e78a3611e09a6a9ebcfb76, + 0x2712ea45ea88a54e4899de133f9d02454004209aea0434ed07cd33c9305c0107, + 0x13e4cec6c5fcb7a55d2c5c9e0dcab0ff3a3f7c26edb5c0c5f5bc00c036817e9d, + 0x132f73f3a5a70fe12bd077c340752e6837ebebea4e7e8c06672c3e0c09aa2436, + 0x24f5ae848c7765ed4cb20417114c602e8186fb02d209b22262ef6b2f9f4c2d4f, + 0x1f3203e2946c3e784da190ea76628d98ce46cec50d7720c6289b9a10b029102b, + 0x405b17b0927364ef8a190472cf69cc8fb91338ad0a037a6ccd6b71d3d8a5721, + 0xd7be909c6d203f7ebbb26f688c104599e34edad7bd4fa7fc11c6be8d2005234, + 0x23b843266076f360c24e39af50a5f74adf3ba002859b6bb7d503abf45cc9d338, + 0x12ecdca40e7a5ab513a78862d77f90435ce4ca0835a966112e42457c93520039, + 0x248096c473071c7c2d5c8dd84006c245c6152e0f86221d82f9d0b2ef68a0c1ea, + 0x1200227f631558e2d83c5b6c386dbccd8c019b327190ae6c21f5e6ab44bfc644, + 0x1d757abb199a6c84d960aab443cefeb6d6e433b5cebfeb198f803eee3effc0ae, + 0x273c19ee6be35b4b8999349c7b7b83cb57aa165f0b302a2d852be61e83409d9d, + 0x2d1ca26ca5d5dce1ea42db19426bd074157d35e28ac98e9d0e25cc710354ed88, + 0x2ecbd2ea29341b707d79a20744740982390655279542f9837e77f89b127d4a6, + 0x266a6643f4b1c323fd22d8bd34c4f9c431032f05b0c856e107d92c70d4bd5134, + 0x1062e99d5dbee4ab0c047ac41ccb0121b492e604fe10e2db4ad43ddf677f4266, + 0x15f2b18d006fb5f2bf5801f8973bb94ec3d4b03e8d656a59bc09954783ee2b6c, + 0x72368c0d5eff7b59f5b07b27540e85ea042a1c80ef063554f53982bc581dddb, + 0x17aa521645020d9a4914e5679bdc70c0772edabae0f82c0ec5ec29289e0cf286, + 0x2f968cd2126db9260be98ac5a64250d6b1dc60db752ce86342dea9d7d6eee209, + 0x1824ed09caa77169c3188a0a3287faa284ed7a51977826f1f64a1c2be32c909f, + 0x2b8fbabf299d9da38fbd033dc61444ae2500c1205b785a5fab8996dd9fd2ce68, + 0x1be598eea60828e10e0c4cbea95736584eb83c6ac8427320802d9083f5e6dd31, + 0x463af34caf20c7b2cfc3ba540ac128fae440690c1fbf4bd815ea2b854183ea5, + 0x2dbc1aa280bb43c06573fd90ab5f0530ad450b992bcec2797ce0adf60937ebef, + 0x2aa7cd41625eeed2f8e460ce63d2bafd64329959d40cc2e6fe1d5c48be5c501, + 0xe3c80439636f2b40b1ed8d33f792f2a5d2e602da651491913ba45df63e777de, + 0x3ae4d78e90fa89f943dc0b4c56d32f5c846734071ea1bf6bafeed9e83f40f4, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x1f3ba6f2a0ace67807ff54fb3752a740b90d4098ff54718df07cf6b99b4a3611, + 0x2b2d8688621a0b62968c64cab0db27f41a51b32a84980ef31760d2365d2c3c31, + 0x27ecb287f3d9aaf1137d4058abd749febc280bdf70dfb7e5b61a7efbdb32371a, + 0xda7a17691f64048331fdfa135dc56a636b1bb8e1c08ba7cb06e9bb1a8f5dc22, + 0x228e87cff48ac1eecddd22fa3f50214fe0505cceb58e8aa515a9b21a22cde940, + 0xbb1e094527421fde9a1229ff4878eef766152df2998fcfa44ac7b71906bdefb, + 0x2162e5b127d7ea5fb675aa6be31013c2b9d9429324fab62ba9ce1ca21b3c5f2, + 0x5e7c2a9c59abe90189615a15ad93e146c27642aadc29e4e40b8dd9cb735f4e7, + 0x3b7e7cd0a61c8a953ce16bb6adf8f61f49b560e1991497ec3af678413535e12, + 0x2b48a6d7de08553fae906852fc7fb1661e6f5036185a3f1a75c9a9abd0c784cf, + 0x1451c962e6d5dd24e45dc7e078dc64fcf59634073c13cbdc5b8792a51ffb8e37, + 0x22aba4d49ebc306f4b7b4e2bc7b7a1ff4411d89890f9fa5ba2408cfdfbfd18ae, + 0x8edd76a666b9264c34b0069c62d2cb61bbeee55882ea1625d3e178544cae4a3, + 0x1cfa9bda9fe33f9db0b1d190eea07fb0dc6855b74ef166743abf80aaa1504fbb, + 0x21825a8220bc43bf14b06dbd2b92424547a3fcd0e8b0d7ac7543f56382f98732, + 0x22a03c9f4361294621f902a43008812d5bfacad871172c3004b7b58126690dc0, + 0x2c4d459fcf7b58e7d7308af04d943530955cede00e37d3ed491b86f05c49beae, + 0xe099659a946824830b1fc5e17d4d60343f2879ef488fa45a9e3b3af3e80a143, + 0x3b256a5437fa8edaf6d7bf9a7b2e695f06dcbe80aebdca4f30e28c8c4a49882, + 0x473c1deeb016648a6d5f3d0fa4bf31d1d4b9b6ceb0c7f4a76051515104a617d, + 0xa21735e2b1040d8dfc4685c5c5a42ed07a02c216465ccdd3134c157361995d3, + 0x1a0b96ee186897808d9130525778e13d2259a406282456b2edf84434e081716, + 0x110d5d3866aa52ac620b233dc0d892c39f9e376307a7310c994c8aeac1233f4d, + 0x1fa9ce9d08bc9ef43200929b5512236852d4fdfb607f5ef24ccb666dbdf053c4, + 0x8b8fb57cdb79ddadf41dd3da20efbdcd502e89c8e21323ec99f0aa99b27dfea, + 0x20e451f487bf7f30afe6895258df980c732440567ef2be720f683b4d9bce93e4, + 0x18934ccd6b94d3d27af8fcd8f02b3b2aebe21465b9259c7def51799f1d971901, + 0x2502b2fcb6acfdf7bfdda3e968afc622b949e55d567100c4007fa0b9405936e1, + 0x1e22a9af8fdfe9185346e22a28e4fa435f64c8e0f382ef20f27c0f19df51e520, + 0x1bacd78770219cde479b8dee99d460c73a22f674ed0066ecc55d2344c72a0fed, + 0x1c5dcc7784cb1a230304a6905b05621618b89498a827ea77293b96d8fad9fe3, + 0x1514f7a6184d2f5de98511d358572d7d89d33bb2c6d27a5fdd768178af4d7789, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x2871dab4aed8cf27bf0e9a2f02f0e7f9c46057ea80fa64d358c4acd2bfbf35ca, + 0x16b48bc071b2d9d75c6715e959788a5c2c634a7ee951f61c6c252f9f4c96e139, + 0x2423991e2cecb8c7d0cbf1f6c75a96fdd9cc3e1d3404891054070888cf58c027, + 0xaf6489dcffa0471166ddb75d46bcbae57d239e90051d360100acad86309bb34, + 0xa8fb4c80f28764fb489926f032e0f6bd6bb878ab5632b94e6f960e841780072, + 0x2ab3c31cf9ddab37f0742aaee26190292952ba391eb6764ed69434d0553085e1, + 0x128a537033583b876442e4b5274483d0e766a01ee4ab310839f6d8a66c052ba4, + 0xec7bfaa62f8146ef2bb13af733cea64631b21106cd47d456823b3da92e41530, + 0x1d26f27900c3cf2629a540caa3f2fe0896977782cebec4a7c5fc610aaf9f288e, + 0xcd7296fc0086a3895770b3d0a7e27302c80383a017e432b69fe2503001d14d5, + 0x5efb5ee8e22ccf78945ddddeb3f6ab0ccdd2980aeed476369011dd2017d2cdc, + 0x2fd3058e8276c3e1044102e37c8bac9f9ceca3d4898dec5227152bdac4876063, + 0x3041d0de272cc4007331a1217ba0462b41f9396a251407964e90f77d20d2be54, + 0x22b44b6dc784db7a40c2e670800e462758b5249d78921516293fe1a51866ebeb, + 0x1472f9c6b744713482cf7c9f2c82edb0cdcb81f238ddb5305a14e164909a963, + 0x11cc50e647086a21c18d924e5cb407e0895d44337b760d95fc1254b690b857a8, + 0x1f6870318a97b3458482c2b2e8f4896d1bbfab317d95478653847bfe27f73a56, + 0x527b77967bb4404a5a78d8e449466ea5dd85d36d29792fcae4ae26f30c39253, + 0x114776906608a453804a6ab3ca1fb1357ef1e68772ce78d4fa53c219b47c4ecb, + 0x227cabf1187a8e8c8b983e4452b407d3ad0820e9cc000ea38d2298cebaf5ed10, + 0x2cdb16e7154d3366e88217ff94382b8a7dc86b47ecd50620b65ecd5f98aafd89, + 0xbba92a567cd15cd0923cb79ec491f17595d6af80463e9b7e2b2c9c6e662fe41, + 0x1621a037774eb85fbb2ae136893924aae5ec0394764f2bd204e6e3c2cd053e66, + 0x1b2f4b4974fe9c4d2f6ba8f3b51084b886a115dada554e313910e6a0a2a736be, + 0x17f058954543b8005d9e5cf0393b669790076e523dbb5bce473d67d98b4660a1, + 0x2a131d0e2c1938f53bfad52e5fb33120eb12d9412dfa7c2c79b20a4a9e618a96, + 0x1e1f17b82c8ec06747b63629d99e72f5f3cbebe8bded20c0bd7fcd7ff8422321, + 0xf92dae5b5070535247aa7062d15dff0dcd533f7ef798556b1f704acc72a1a91, + 0x1e26cb1e67c4ca4884975a5dbd44df8c05f6a7a813d9c3267fa7f735cc144db3, + 0x278e469316bcd00829620e438af377734719124f83c509d48472294be9910f9b, + 0x2d931e21c6bd70dd337a21eb006cccc570c8e248358e256655d4eb409db88256, + 0x1f3aae749c86c139151590615fceb9b55d78b0436d6846e4ab2c30abeed628a6, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x164cecda3aec3963de5deaa919a419e7c3e7ed67b00ed3fe37c941bd3aceec41, + 0x1ae5c087043dc196e76f2c1fcd004f07bf7622f91480c2f43dff37466824e28a, + 0x206d121a5d5c0e50c6696a4f6a3ce23d86e842db48b98006111cdf9eb6501362, + 0x273853516d030f966503bed07d9bb25e9a78daaaa8a16dd46ce4ead8b0ceb92b, + 0x2a473b17daa8052023496f81ff3471c76bae27ed780b23b659056288f9c80e8d, + 0x126700ad12b26c87c8f7c90e8a6edcc613530f09d04258d1d0ecf0732d143cf0, + 0x70f6900e211a2d3ed359a44c1949447264d51580679fa84dace529a0de19d42, + 0x1d196536166aafe99006756cbbb15e621903ccfb19346cd45ab951b01348abd1, + 0x16a6413bfd363eee8d28cedff00c8c86e15745dee50b2ae15d45f4d796213d15, + 0x14fe39f6bc1fb0e0a41f9cdb142b86ff95f1003519cb3a77a05e96a30153132c, + 0x2f3719862194ed2deca377a1f1b58eca9aa0b726d3d82859ac5acb5513159f08, + 0x2ca365f66b59cc38857d65e1ab5a841574d5bfbcd0f9c2607b704232d7d85a02, + 0x1823d36e1b33841eb34a4601668596fe20e08c28f8772ca3958fce53be2c6c20, + 0x15d27279b7f1b7514d007345f4702852507d07b64a2f1665718efe5b74578898, + 0x11b3efafbd53f96ed7d09373534f299562335045a51e43cb1aedf4002b7d6bb2, + 0x12a0a91a6025546911068e6f50fdd1c6e368a52afc769952c4fbd9734f5004b8, + 0xa9d7fc64fc90b912b49748faa4a4dcaeac8f3e15df09fc92f7066b55904538, + 0x15371b75e8adea4894822544c8d7cb6b670741aeb1f1c465e35786fc9c645df8, + 0x25fb2eaddcde34519e511e656d51a90db8518b6375646ff92caa4a914007d517, + 0x2dfbb6f1e212006c39bd89dd4a6543eb0fcf94882febc1c958eb81012f17cc53, + 0x29593bb7f971b987c1efaaf91cd3d70478b3b8f519e210d109413adc4de72807, + 0x134ce1956a848bec4ecf9b6033710c655b425fe7a2e42a9143d989c876e07b6e, + 0x232e589b327424a374dcc64152ec03029cbc6b1e6935e1878c89f7daca2fb8c3, + 0x2ac4f4d9d1ed520e21fbfde98b4e9169aad8f701b95f7aa6e1a2799d72b599b, + 0x13843ac1a48019a500ac2aa8313a9143b045dd338120bfc4b4e91c1750b27bb5, + 0x123366fe683fee8c58bfedfa072912dc1bf50c906115880d4954763e648a7c92, + 0x147bc77d1f7ef7f0604a669c3bbfa3aa535711a43a8ebc25f786db8c951dd7a9, + 0x2bb5eb86f2837f69911dc3afe716c5fc897ed54a1ca84c7e473a92012394166f, + 0x25e9535591df883d7704dbcd8ee87be36f7a40fa9d360b8dfb5a38892936d47d, + 0xcf22a6787e93e4af1d585205f039fe30280460e02c64b4aa6a0fd361fa09210, + 0x15daa89536023119f4f32836140088bce9082cd32db18edc2a4b963ed61665b8, + 0x26a41abc8b0969da23c9f511b4a47a978406ed147fb0687d146ff73f0a3f2908, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x24603e3d523263ba69d2161f7bd3c01b990b96aa479b47d8e7bfda5779b31a70, + 0x6f06827f0a52b2434751f1bd23bef70edc803704890114a33bc1b173cd3fa16, + 0x18821acd1d1a183b3974714b4c15b9aa338da2999ab219a65ef04d6538c9e681, + 0x25d1c75c19bd34c31e5dead0dbbabecb70a1952af3b9acc945e6bbb7af79ab85, + 0x2d16cd48d5eb9d3884782960fc5f27529562190c5c9203f1b0b220b07ebe2251, + 0x1bb2eb154cea451a7591bc895cf9cb65658133c6f63533a7b45362197d883e67, + 0x2c1c099ec563345fddf03a6c54e2915f1a7c890b6554cc496856553d2b2173c8, + 0x14de7c8a6f75d5c098439608aefd9d3f2224fd7ff2d301c62ae728c13cedcb56, + 0x2a12b1666687a8f3a14e61590ab004587a058e42c5f45840bcf0c7a03487f34c, + 0x124f681268028f4ebb6678e070951caa96bcaf09350bff4f72c093c2973d16ae, + 0xc61ee197e59676973cb1b0dccda3d618981b93d24285440f223146a7aed3f8c, + 0x1d6a13345c16963d0fc372a33a3ccb9d7113e42b8336ce4a0cf68c6c1c3bc24f, + 0xe90fe044265e093e82a00cb140c9ec848c3807ca216ae5ca0608b360547e72e, + 0x28a0106ab648b3fb1963e8b51f6a26cce8ab62d75ab26214c389e0c719737002, + 0x1903a3f14cccc405351a0a3ba23106102830c134d14c378226d3a6599e75527e, + 0xe69b6a45f98dc94d36e7f80045e56fa8927416f96bf9b2b603c32c6d0026730, + 0x24028083240f0415ae27d250b5e9d2611c5baf6b83ca01c5fa08b2c3984ba37b, + 0x10b97d7b32b7541cddf569d3fa3ba4fc792f67fb4bc8abf142bb9765ab3fbbc6, + 0x18514e6b6663e92d0b702f6830542f841872a9865e8116b68bf03d55352ed948, + 0x7e84a91c22df5f22e465c35f665c6a56c7d41e6f20f3d63589aba4a168981a0, + 0x24c67c3debacff4c75f5ab6011d39a6ba905a78980603f9b520dc5f07826d2cf, + 0x2302d72a48f7284aa9dd46013f218acf1551249c22d8331dfe48c181a06ca28e, + 0x1332fb9ed5a5a86c5f70cfdb899cd053af1cfb9557af1a5137be1e727e3169, + 0xecd3e7955fa603af46e69fcd1699d5d57db5eac3b9095c0c7e0b6d24dc7f542, + 0xb7012f95446a6e56b35ba5feabc8183ef882ab5e99b48dda6a00aa4b5282ef4, + 0x2d9a9de40201e8aedb6c83aa64d6801af749b464ca23db2a743bb6df13c72986, + 0x29bd4a19c267732d1f213a478c9c677a47804a525df520ae995bab6c79f0c375, + 0x1462f5ae05431a649833f4d33d7199c6af0a27a33c6aa74514d706bc5facb110, + 0x291f96083043911e45b87995cee2d52a0c4c1f1a2537b6e890d293b1fbfc05da, + 0x411cba90e608a51a8d3635d7e842ff58c4137db7eeef0ef16422402b588766f, + 0xf7b5ea5565816bbb8c16bfa946c6145d607e773ec10b74844511161469baf60, + 0x338cdfab4ce8fdc9f081c77f3b7a58f5331d3220cf548229c8bdc9f5e49baae, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x124f60ff00a0e62ddc0a356926a83b8892a7fb8602d5d3b955f41f9134953107, + 0x7ec673039830a0f06701ad707de762e97de268ad8218f4e771ccfef70fcaad6, + 0x740e5d063abce69067b719fb33e30e4b3da7b6c66f26bd2d7b5320a04dce396, + 0x7808acd3ea0c249f88efc1360f1c6e539561f31208e860921311b1c29b598a, + 0x112bf7f10ea174a939adcf38e91511c7c00990bf176d3478ba5c5bcf9c46d89f, + 0x197b19b25c2afe93631a78cfcbefee4d7ec4f7a5e9c87f5aa30861aa5f441049, + 0x1ee3070e40c0e0e740a67449c3789b6b1f5b64047b9adc4a1a7f9194a7ed7c62, + 0x2ea7f970eaef265df0ba7d65c20bf474925bbd7eff4c9af087c38b5bda5c8a40, + 0x87e362b638c1e17cd837e14f954fc02cc1a020c62e416bcf5106c0e84a42e4e, + 0x66c70edf98939e555fdc29bc6c8db703afd5f7317a97ec805c1aa28758081bf, + 0xb7cd01813db20a6c56bee471eb16719fad273719aacdba7c475b9cd9fd6ed2e, + 0x1baef4e284700ad99e75947e51988f8b21b306e85552c9586159cd2fa62d6208, + 0x2d70435bb7b0d2242b1bf4cfa9bd48cefa4f4949305956f07c6ce9f40a4f63cb, + 0x2c9f4b07125840d0a8db29b2c8f723da914abd2357de2d0bdfc761ed1d2cb190, + 0x1a68c6eecf6121045900f2d146f6e0dc1ffa95afca0130f4023ecc854ac90979, + 0x2bde9b2172e01e033c899e7dcb6910441e0b26ba61885817c19257c67a704459, + 0x196364688be6c007d5caf7f0aa60dde7a9d4df5a72201a010866f51d5b8e44d1, + 0x5e25bdeb203c4c1c10272422c44f883df61bd873a1181005937ac6897b820c1, + 0xf9392975fb3baceecec89ce8dde33d612f7b51809c70c79560e5aec4ea0f97e, + 0xb3a94a0d7fa6808d540ea7c94ac84329500fc61c1c921f6e1a02be72e0552e5, + 0x57f2f77f6f39fcc309ce2227ac987f88020c1156a521d8b4a6298ea3bec1f95, + 0x287141748ee5782d46d91412095b8ae8a817341797734ceed2fdf000f7bd2ca6, + 0x1d457716f5e27115f1b3bd602743ddb625242575ce407e78cec5c033380fea0b, + 0x1393304221b7afe064f39562a25a21c896a65c27cd93ed89f500e9eb5b39b2d7, + 0x1000b0acd83b8b51113119fd1783d3043017da2eb32954456b6c61faaa2ae29e, + 0x19c9c7938f860731025bd2bb1cd4add4ad7389433683ec7fd1c2c0a40840400b, + 0x218bd78be9fe83b8814a959ef810968be0cd8f20ca7778496f52251b1a5703ba, + 0x2724bc9c179c6b663419051e901b45a3c36d9f59d63f41dddccc120dfc3abbc7, + 0x1e9130d0ad5daa81b807d86cb977eefe449b9081cdfba59bf8e1b43bba4c1077, + 0x2d75c84b8825bad22720289707f2709c595d7a5ff8df9b2190359400d2e925e1, + 0x27628d274cbc76c2bbf5005702ad14bd8b44ab8cdecc65c2f323f232db788557, + 0x2a39cb3d3633cdbddcd0b7cc3744e46aff3450524dd573b8f67a3c7e3b9c7a09, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0xa09afb1c54f1db4544f6c0073aa43c0fe17ddede4eb2e965a0020b3734b3e40, + 0x18c1bc97aac4cd9735588413be17348e71d1a7d14a7bf175c8a48b5b85e9b54, + 0x1a3730dc03e7f844e8876edce2a2d00135702da038a3263faed39d048af8e466, + 0x25176e26f891655e4ecb9a383846a2aa15bb49936c1fb568519615a0d10327c, + 0x1190921ca2c2054af278beb8ae7e902f2f9fc032f1ee2e661fc045dd643569a, + 0x27301f456233aa2eaa5e58ca623471400a5885e066556edac068e8187bd53fc, + 0x14df7b40c8531784271338eb6101a7c565297bb9fd160f5633d1fe8a24f22b0f, + 0x201b7bcedc3f893285dd6a8d70641086091db277c47d721fda35ade3354d3756, + 0xd7ec7dce868dee03f3cc914c35bd061c8c075ab2b3a24d63514e43e61137f25, + 0x1f4366fbd21731723a6377369cafc1ead066d0e96336a6c0cdf44437ac6999f8, + 0xd4f720bd1b1d8dd2da533015643abbe2569c2142b3827f769bd4c8fad9eb7e3, + 0x2555325b985eb37f57ade931b07684d313c5fd72badc53f218cdf3637e28ac20, + 0x19577c98ebc619f92a0ff099cf5c3c78b18f4e5230eae7db5e2f88a18148bb4b, + 0xaab15d18bc399969878f0303b29e85aa3ed5b5f0d302efa97073d0580bcee54, + 0x15a5b74d5f80efff02db1df507fb260724238371f9da217db249b80650fc2ab, + 0x7863677bac12d9c8acb8e235fed719eca74497e0c85f1191132e72f877b4594, + 0x4622dd48eab686a6312f00bac77e56ac609832c1a3710062e2d19fa13b25059, + 0x1bfd373a0dfca60070a9cd0c5f70106366eafac34d74cad65149841c31e57659, + 0x12c3c104d455c723c30a2582a9fed0478089ecdd6256a6a14d5dd3a73e57e58b, + 0x1db62d5a9783dd6e3721980161c8e9f40b29066471ec2bb395b4de71521c9337, + 0xa1338e33d0d79c8c1143c1e94407be350de016aa190237e0fdf6aad194ec3db, + 0x230cd81310a9978fac2828de4ac38c19fe35aab2179f1e83a3127745dc709846, + 0x1d46545374f8b8117fe6aafbf40c162cfa3b13f7439191c43572ff8ca713d874, + 0x2f0bb6daff69ccbe41e11635d1a451816c1a39e3baa7359493754111c0d453d1, + 0x29329695f168370e3b3156e3ae2824a662edb778c2a23eb016d135caf72cd9d, + 0x1b9f8f4a4d8cf0878c3b5b57e82096972b7d773a197b6cd412956d9994f42393, + 0x1150ca485896d1fa88445f18deff9e46639579453dc8bd952deb10c53fc69025, + 0xeffc5e98f228858e49ca15bb98312385cd06a57a898b82a561f6fd9b5af1170, + 0x76a9c5ece422164d7689f5863a3752ad3681a28385e022c66dba35b8c87df7, + 0x1ea44dc1364ca5d1a9c217488e96b1138da5eaccfa62a3418d687da1308199a0, + 0x22390e0fb5c982881d62f7af9255b2c677559b525e70e1e993120e39cb386fd7, + 0x283880c9af3c5ee2ad175b97a9110e904ea6f1172b0abedd8726a1942bd21baf, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0xeb1b0ece2af5cde42043430b9c70ed679c2bae1000903072551ecada6dc0a6f, + 0x2da6e90774ac9bf5a07971085698cdff633c28eb52f2f57935b712c406e37066, + 0xa8125b935e8da1db2d1ad9a841efb10fab0966b438e0a6dac204ccc832ba951, + 0xd4e3b2440602bc4d019da80f29ee2ce86a44f098e32e6a47c512fa73173eb0c, + 0xca753aa57fa52ba572587eaa47c18ad91aa498048483d9a019457d014ca08e2, + 0xf9ea814187bc6dba58c6f7c1ecb3dbf62ab2ea29d075afb40fa75fafda6ccdd, + 0x1625e36facb0ba7558f4163e2f69b482cff1002b6e63a0297dd035b51126e214, + 0x1a8f5986c3af479a950f2f78c1cfb9e6eefc693568db3215ba3da8b95cf59997, + 0x2092ce2830d91cebd97e69ad4aacbf5947c8edd9e809d33aadff0a9c44c60dd2, + 0x2c34396dea567e1a3b6bbf21518b8b78bd08527d955ec8c3f71c153351975a48, + 0x27ef5d907c12b2473a024ef1ce2bf3770bb767118ab957911608ab99f5011e3d, + 0x1f290b20bef457eebf0ccce00bbc39ea19ea4c2625e54e0dccfe3db112e067d1, + 0x1db57788c30f2f18fff3908ce919ea10ac851b862b505246e81d61bdb51e0f70, + 0x2b041dbcf7846c4e72de5a0e5d201fa5306c8e797bc0c43702dee216497eba23, + 0x22a31ea557261176a10f8036c7f9aa32d7392a33e64ed90dae1fa3d9800f0077, + 0x2eced0082a7ac90051bfd190d97319e34021bd571d994f4fb633c299759876bf, + 0x171f3f295c67c80f97bb0678ad05c216e6df17c46995c7c8f801811b47f75db9, + 0x26de076f9b9cd4cd8e7f4373b3569c9c2ed867b182be695528c71e1dfc34553, + 0x18684d0ad8f841fc32151dc50ef602e4560b286339d9a299e6451d535596f41d, + 0x17baf0b6d89621ea69420282c32f94ad3a52db7394baaacc2a1ca3032656b834, + 0x19bad38eaa92c43ee1bf9289e9e66e32a2856a141ef2e36868975617765c0a13, + 0x52eda69d77234815d76a5a9b04e8f7245b9457541c4145d00fd263bcf9ac56f, + 0x2de5e640d8c2fc3acf28e99df17fd56dfb91fc1091d304773638a453037b17b2, + 0x7b075e004bfea80e69fbe1c460586a50b260289becc26cc92ea6ee18ad5c897, + 0x24ebb38197057bbdc006a2ed6d1c280e500539f98dc53f83c2b58503bafa8ca6, + 0x1ce51573e24a435d75b654a1bb80df8ec38f12bf9660d2abad366ec89770c3f8, + 0xff21e9bcae93244b09bdee7feb1841219d14b6d9e8ce6c5aa07915b5d81903d, + 0x9f7f1cb180b8111b6a3b22458cf94dcb289ef8addc4adcba913d99567bc43f, + 0x228a30bb9161835a3ca58ead6b9752d0332fd78608b1412a402fc045ef430f, + 0x15e9b1e05851c96b3bd7f09459669d852e65623f1b68f9f597ab7a0dda5e208b, + 0x196b3d652ca59d59663696ef17988ba14ada02ec506cb7e4caf2706001953bec, + 0x1c8749855c159f2b4cf83932f39f2676dc56258d3cbfde31d526b4b5ae3eeba0, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x221dd8a7d495ade1dfe6a6e119845add28d4fca1736fea74f367acb2f0c2c6b6, + 0x4b42317716dca3c5d82adef996100935cf38279042de9b6bf50b29f6a202f34, + 0x475894cb64dbaa6fa6a2ddb74816670bde6ed2bb1f535a9d5f86348369494c6, + 0x1c3946b391ed069e274939cee866a5f3d4d7dcd44bd28c59bceaa7953ba45dd, + 0x1825b793fd2ed840af6848d88c10fad3c14234a7dd3834121965a11926c5ce5e, + 0x282ec6f6215907e0cbece72ec50a5a90a2f17c3f514d85986b9983bb68f73cb7, + 0xd8f7801683a6488f5d54d9289e6cf33631007771a3580746446e05d48ebb741, + 0x1855412ba202a2a97b4bc4d141fbd547a4019f23cda4da726fd1aac4d409f48, + 0x1798f1c6901076abd77d7c40b401c93bd711d58af1b975106de72a6f6e2b250b, + 0x2edd97865d7faa4649469ad96a5e0542c35628e903e2be373a0ab7f1ca5a207d, + 0x13676cd7961ec25b87f7ab8b623d2cfad86cb66236386cce469386fd7998d956, + 0x16c0a91e9e9c2769401f26728c935e467693afac35f6476d7f45c3593496a4bc, + 0x29553d069f113822ab939a807c89614214d5866a2fc17e32d21c786ee26cd91e, + 0xcb66808581fe375cd41bb5410977379265c20dfe402d5400bc93ac24b4b03f3, + 0x243dff648c9f0c7654669b0628882c9309e5bc28587cc2b239bae21dbfaf03ee, + 0x2e171191951cef52833064fd4d4067816f2e9c892d7ec9595fcf15286fc58306, + 0x2bdb95923550209fa7cba2a746f0c2681195b0eccc5e6c253227b62c657e662, + 0x85aa13a52f4b623dd516a6a478fcd88e30c39642c22f7dfc0e4723e31fd0d5e, + 0x15f5dfb2f22e20cf08c1bf8ca7fe18ee12607615c5c3c1a7c2c9fe740bb9990b, + 0xfc58949bd8a136c38c706991c5288511da276d6fab95ef315c7ad3043f5f619, + 0x284e9569fc8ba77b4045b856dbff1c29eec71e850bed17e1533028e2d07cdd8d, + 0x5fb97885d94f32e89b37ed816cfe79118ab5f70784b3a546a50c32c52c5d7ca, + 0x1588f5edd5db73e9e42e1038f3e6817fecff001a704d18fbe96ed57022d6853b, + 0x16814981024fdcea5abca513e5674e7ef7573813b650daaebf34430a930d06ec, + 0x1b0b7c044e5a9cc60631dfadd62bf75f7976460d0a1ddd54c91f5ac00461ba9b, + 0x17d68098ed44b6a6c42a6e7e6f9fe2da0ac7059d1ecf0b26eae01afa117931be, + 0x6a32a1b358cb5288830b273671306d6e1af65718c3b4ef1a3c2c6ddf0ebf48, + 0x124899206ef866ee3d3253024894741166f53f48ef7f86c2955184d993cb6d98, + 0x282d1b8005e7c5e21adf146bbc3a80a41207d1ff7ee7b3bd2c3e6bdd5bf3121c, + 0x2ba860b0e392214dbee6ff237989665c30944617abb4b31d64b2ad85f397e33c, + 0x8dee425c9230a537b33445ffd0f032a8cd335bb0a6c95591e1bc641cfb5dac3, + 0x13e1f729e82032ae05a37e3eccdf95591b61a016f5cdfde65b9d61c84e0f0a09, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x234c770889eec5a24bc88f5a31d56e761f7487199276c8a6eee5b1a68997812a, + 0x245bfff7477831205a76d0aa1e9c55d24bc04143b3bf5dec9010569f945991a0, + 0x8f4069c0b10875a6c5a474a6632faa9ca5a971d207ed0895fb92f8ab363771f, + 0x837729d4fc85301d6b047a6dc71d2ed7ba33ee5e25cef22aeeca59f015ea9dc, + 0x294ef20f328ae6852d7f878918cfdce9ed950be58925d997ac533c91d5b6afd5, + 0x1f62b4ba6e7650e883f9c53c12adb7ac418d3d48a7514f183218c8d8c9f2e881, + 0x88e62ee0805a12f7512c58ebbbe7925c8d94d13ccae933af8ce5ad1d9c11fc9, + 0x2a15acb799a36536698c1471b93d206320f2721c13a32df2d30f40fb9b1fcf4d, + 0x2255ef233b2e051eb8fe5fbb4f03d5d0450ab225f926cc2ddf4e0f0d9de599f5, + 0xb3324f75f50fba89249228c37f2c9a3263a1ba03c624ff6b41d1c0eea4f6f7a, + 0x267abb876cf130e5ec0e545b41cb614e6b0dfb5eb2b668ca6ade5220de6d269e, + 0x19040678722dac94cc568ff3c0b9edd72deeb3cfce3f3d9fc81af7d49554afdf, + 0x9015509267d3d74355f8b8cb583ec4d4c41b01774fbb745ca58b2ee3cfed608, + 0x25792587eee7e693a2dfb7ed5fd429f501a3eeb917e6c17614fd3cd80b7356fe, + 0x2588230455c1640eef883b2650dea4b74fa7c0b2675869b3680a867f3f9983fe, + 0xa5d8e426e8a8633cb0dafabd4f32d946ee6b1c9d80e0172d2a9952e0f85ec56, + 0x2f47894426cb6983d71c100a0326090c8ec978454b359a02d618adb71fad8282, + 0x23bda45e45e20fb6c274f9a99c7083fa4ec596ec283a78d1b3682bc44c532383, + 0x6428e25941cf84268604cac47b8986bf3068257d3be89c3d6dac8f57093a650, + 0x199d93b935756b0e6f1ea60c72667b0e5686eb1b12d6cd88dad5f5d44d9bf6fa, + 0x171ce4623f0a49ff1f0b33205fbda2909f9c189b275cd7a717f4a38a5abda910, + 0xe6db378ce7e1de03348d3f7b7b17264be5adf0995de8e0273c39aad38229a, + 0x17b2b86cd66a73a60e46511acd7dec0fb3a32d6cb8bfaefcf4479b7d358fce81, + 0xd2ce771ec4979abb30c8a281fbfbe701aae7112066a813393de44e56161207d, + 0x86998aa35a19fb86ad35a9116c272887a26c95743d8214f1f2a1fc75050f867, + 0x5be1134da0692b8f92545cb326deb862136255794fa8383e1d3f266f3162243, + 0x1bcb6b8de9f866a39768466d15f521cf1e75e1e9ddbc30c05a45b53acb5f58e9, + 0x1b9e926867ec402e4fb4bfd240a82f240eda7df61c9b5ea3af1984f74089a93b, + 0xf408ecd2413f30c5794e777b8a0bde7dd69ee0e24a918253e9cefbc7d98913, + 0x2d7f052ebbb9bf5270016f796759f98056b8928efc35c09fe9e1aa26f18010e7, + 0x2da951984f4f03171413e1739831201e7346a45bbe9af89d3b23ffa2d615a952, + 0xb557ec46a7bfb8a0bc21bcaa56edb6e1c0be152d88b57fb5750cda2851c6231, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x13d3fef3eaff9b9563a1827637ad00789268d2b55a1fb6681f8b052d049a3fb3, + 0x2bc1cc959099f62eda527d7385cead603b637a28c9a223e817c9848fd78f4754, + 0xdaac8774332e509986178344e8caf8a91c6d01a275b9a1df469e5b735bd5082, + 0x27773f22500cdf92fec80f154847189a3f75f85e8cde35ce9171225d3cd8b676, + 0x79c499e130ed874a1383b978dd3c00fd5b6d0c18bf3b491cfd63787230cb9f, + 0x1ebfdb369fc74d1469c6e461f64206e4907b6f5b51b02496368aef1c54198cb7, + 0xca9e23d1f4071112543d4e8c1b303865a4064ed4e4110eea113130292d1e299, + 0x2357dfbdcbc869ea8068bb2ce056854f7a0a765a217af4a0a317888b08ae0af9, + 0x2c9e7d1ad79c49b37dfd93ff2d4aa43c8532fcc606927e975b21564a9c1070f2, + 0x837ff288c0aa9cfb3fa7cd38312ca6b83b9b2a3ff4dec506aca1af1176a4248, + 0x23d8de04d32b88a1b5102863416318011b412b11f1e609386c5d8d87da878e54, + 0xe2564431ced9aaddde433e7cacee42a04d09d3026f3ca1dd0ee3fb3085adbd9, + 0x61caeaaba163fef7965cb665f0cf305deeef1642cb63e122d845c5f6b095be1, + 0x23356942ef4d25d2b3542f5dcb54a77cf17d8fa64ba060462a3b71cb3b73d50e, + 0x1866373902a9a953c0768646f37941c805658c31f761dd39e6b4d292c8cbcd, + 0x86bb5bb78cb1149afeb670e1ef3470c5634f10b18eaa25450e87c5a9bf35146, + 0x2451e0f1a7bade779aaf54dd8a628b92d9cc8a7b7c0074076f860f87be2f8fba, + 0x84bf3740a546012b610a5bc78ae897973b85c2be04afb32fae0e39d0c085255, + 0xdef7e0528ea820d70cc9fab7935d6cb5b3f47fc8b5aba924bb237b7077f0275, + 0x1b7af60a579f6d6f9625a8b0f7c4fdb2a6af598daf08501f155665ab376f7ec6, + 0x4f92ee3832d8c4253278f77e9ed900be186f8c182a39662f59e4700213c98dc, + 0x147b948eeb385d71922becc54ba12130ff5643e49f71b7327c323ff0e2571c95, + 0x367fa68c919ef8c6a24c79f6bba07e7e839c9512b92a690d1a646bce08388ba, + 0xaadb8ffaf6b02a6a4f42e97afacf2b4d49b5d4201becf3a013dfabfa068b5a0, + 0x1f29fbe41d336788cf666a4378b1c82d5819c08e27115762277637235b9084ad, + 0x94397da30fa8ee480cc4cbc0cb3383218cef9602ccd1eb4655071c7bdcf3001, + 0x16a091b9a5cd952667b2f11309cc4e39f2c6c3ac2eb43465d99b409ab07711fb, + 0x1625cf4e2fbb6f7a25536a24bfe679c793e3bc01574d8af123d61d6b98ddb0cf, + 0x17f1ddf6108819ad72aa91411e08264c5a0756eef3101351abd131e8332e8276, + 0x272ac6af8670ef04eac5d621949f3c4ec7edbb65a38c4bd7d5ff440cab1f7a15, + 0x2ac81ebdf838c893a74deb1a575c929da0a6e12d2e6e1b0729bf0457cd7e134d, + 0x28198a6a7de09abe545ed428f83f9ca95a7bc9f91186305adc80d9a561045ddf, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x21c8f5212e43a884a0729986fc11af75bb7d2cecdf007a7175d000aad1c89e21, + 0x12e4a961e1801660228bb592204fc98865260be10e1e0288460f42b527c486d8, + 0x9ac00881ffcb7ff45a4f4530d1bf63af3de4c3eb7e8982f354d119d099b20c2, + 0x22b92591debead5bf556dfd040688701939a2dc72264c1b74c0e7b89b4557670, + 0x2388a2dfce036d5c898a465ab3c88fbde3fcdf8810c87e639f7abebec9decf80, + 0x9e2df6b54d923dd12bc44406c247281240924567a7a993e41a6eb027e959601, + 0xb05fccc0674af8deeab7d73646e2a28df0f4d76803a8b6fe7a2a5f9f444037e, + 0x148c72c32e02a21dbd3c4859046062f7a0a3a0a9c5425a5291beac5f3f54361d, + 0xcc72447af3608c9090af67a3a683e8d989688f2239bce43734d5808de3c048b, + 0xd923c01448dd3098d10140067ab3f5eaedb0a5b73fd6f29f28cb1f33a1615f7, + 0x9145690a8426952481e9c5f53c587aad25faba2f2af7a38d464c6c86e889c80, + 0xca36fff3a1b4bed7f8769fd50195c1ccff723fb1bec0db30767e922ed5c5bba, + 0x151f1a9546c4380ac89496bdc078ab54ec09e1ce303bcf99f5f7237cc7b150e9, + 0x16c046d8404c441eb03e5c0846fb9582414123eaf996781ee0b7268eb4b20682, + 0x251c3f386e8e92cd6ecbaf2cc2ad9d910f94135d41466698610f072e718ca410, + 0x1475e6349fbe26512b79202c02555f0fc6b0df8c74f12a1cf459fabdf4ec982c, + 0x2b4c00677708322d7af2ed6b2aec44c4926456b2d3829b3517f4064933e85bca, + 0x8c06b592eaeb2fad227fddcd082cbc40359d7ac8e01bf16f8c907e64c170ca5, + 0x211e364e0eeca2dcde7b7e5e45e21931fec7898963f20579ee0acc0711d66052, + 0xcd7ab2a448e03f55844c4bfb6b169790a0c8d70638d7ddc4b5e72375970a738, + 0x1930ac2e4e2ab703874dae8d6d84cb6de266b11470aceb681dc619889e61e454, + 0x1efe3fc036da6b22a66529ea8f04651ba88c4a88512711a32f4dcba84952bdff, + 0x1fc575f7be1400b0d7f57217a0993649494f6fd4dc81af8ff4f469ee25f4d3ca, + 0xf599eeafe4afe752ab67bc943a63bbd559b10d6d7340b19c5a48feacebedb2e, + 0x13161ff12c338e5fea3eab7086ea1b5c9e074e8c4343f5978dcaa9fe77d23bfb, + 0x19e8ce8bccf4d36548905830ccc2f9f13c6e0d997fb57c89415dccef20298d94, + 0xbad7770ce2057b3cc20f21c93a69b44be7b95403e6d4ccd373d8d855f42d48e, + 0xd68c25929eb71425958c7bb308245d86a52c4dd57af1f03ec17d73bd14a7b15, + 0x1a20f6c97cd59c0339e095236fb2955b50356fa59244f6173f1caf18deac4c08, + 0x13fbd61eec52c83d2dfc6b62cb1d1cb40e71c63fce17265ae9d631de6d683f17, + 0xc5c24fe6a6fce7831b9c8b2dbc30bd9dc8352c78d4431f5afec5d94a18f2522, + 0xe6f63bed21f2cb9b2886da97bb0d8f0e155f008c1e5039c2ed7080d6be70431, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x13b9e4a669c3fabe0c43f333992a5f698e08a9abbaad77cd400b2912f5ef7e8, + 0x2b0cbb582146576933f01c91c0dd2b095a2da43cf528f2273131788f1a6987cb, + 0x2e30fb85d199dca95475521b50700b699c50f1d7aae5b2de4e9b990780ce29d6, + 0x4ff7ca87e268b4a23af154c1102c8b705ec4682f08ace1273fabb3a865cafc6, + 0x23b371ac3c5e45d6d930df789f60ad510b784afe9ee4e82876081ec0ca7ef7e5, + 0x28c5fc831601998b96cccab01c028d613c200eff1d0e2caa7098eea165c119a0, + 0x1a649a762e15c9e33b6dd3a4c5daaed08ac2e5a7845df289d2c7ddfdc3771f97, + 0x1b76809608b2ca5793d346c52426aaf7228b7e4a09083c2b551bce8fc3022a0d, + 0x249de6f6cd65afa7bf206ac6a1fc864898a5135d0b0efaad0f4c86774a153d9d, + 0x162c8b3b5f7256af0a7bd83ba37d258ad7d4ab4f29d248bdd00ad36e612f6055, + 0x3a8b1979dfb950c0451ebba4e9137d78943d9eaf889becd291a669031680d1f, + 0x1fb9ae665dc60fd17dd0b4284b2eeab0845e6d4a5d6fb81b77e9f7c6b43d170a, + 0xe61edb12a4174e48a7b47b660e8175f42aa7926ff438c90692e43bc396bc6fd, + 0x2a21ad8241436a75ee8a90867aade180589a8c9c63b05253be876f192641b1fa, + 0x166620895a93525094f8bece65ae6fb9e14951d4bf7cf10a2169ce5cbd8b4cb8, + 0x22f7441fb0e816935c8813854ed5fd6ccce5e7b6a85d91d2b5a3a7a5c8a4ccf0, + 0x2523733ae5275aa5fb89c74de7ec80091727f495e729ea9bc557516b25e2cdfb, + 0x150f2ac4f573f5f9eda0d8e65fe866581f1bc11e46acd399cea41dc1ee3b4082, + 0x2e2c6a081127c11a80d60de162c1d5bd70c9e1b1312fd31f974d419d74e72a45, + 0x288f5e4a35d6a88e411113e8324d2af60b07aabb48650d27261f9e0172c063f9, + 0x1e94c48d6ccec07a6aec467ce9db1c7cf2f48f20406483bb873f696cb6139c7c, + 0x2317555099ef118ac1a6703493335db895aeab6cb1d7cb1e46caaa0e9d74ecf1, + 0x112b653324919b4300a6e9caa08f3a36c372d86bfdd4bcf10526ef3c2e8c8665, + 0x10d64d9dbfee84b7d8e426404f4f6302cd2f507c9536559f0050b2b77a15b85e, + 0xce3409a692acee5372266c97c47c2564d3268f5124fd3094ffb35d252efcd1d, + 0x1976232c6b5bc6ff77e7c6d266ea390c5fbd4fb3cad9ece623ced56ac860996a, + 0x85fe99053d3f947a665495f68291ade2c706600e56dae991b62833e75d21c5f, + 0x253875f4394f5962fe07f784c7fcae1df6d36d1840eaeb0e7c236e3d6786effa, + 0x811ef3bdcd3c837aa541d0df32d447ec54391911911e3e0739b7ffd4aeffcdc, + 0xbee1c554f9fc98cfc6b2f986fdf207859d78e2757d199e9a92b1501ef92ca06, + 0x2e46dc3b30b54925c313731501c5f003aa8d1490b16cfe28bbda33fcd0b9b0a8, + 0x29a557272646a8b096b2d1e8aec172491852af8f055779779043e048ed8edc6b, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x2cf567daf1e32b7e212860583eaa1783d871a1aacc61b1e17274d29d43c3d42b, + 0xde4e81211f6698cf1b5513963530b7b9d0b8ecc11435e75e1f8d3743dbedb1c, + 0x2441c69e3451809da5aea5422d4e21637469b4384372f06c5d6d9c14c6680981, + 0x2aeab770ed2acb63ce4026c9fb0bdea02bcd6d0e45b1c89854c2c827f09f8743, + 0x18086bea417322d173d3b67f0bbea727011d58a1307664d208687d50018c0849, + 0x1a5554a104ff43a6e64b7db4766e1ce6df735dd7d5d15bc04b224a81453b5a60, + 0x2372bbb558acc8f0a26eddb623338755aea1b2793d7e1130190fe2c6ec6393a2, + 0x10c33d11fbe22b97736174eaae79eba40bccf31bc846d8d0a8b44470c2af8cb1, + 0x3426163d8365dc4847d5bbf779c5577352e34ff6badab833597ddee1bae3f54, + 0x1c63281e368936ba2046f4c7f0b4279dbfc02ae7af0224d4bb03d847e157773e, + 0x2192bccee71b6b955f146efcc1a1781c1e1c5ce24dd9a55d2658f054614751ee, + 0x465383b8ca4136095399e23c44aa9fb454a47ce6590eaaae8517b97e476c396, + 0x57e4c25881806bd449481ec352088627fba202db4cd4b93dbd1409efcc8036c, + 0x9075ad76e6eb195188a775ab16ab65a001ac6eed2fb1455282cbfed80a0594, + 0xbe868e7bfdfa88434281a12e1753cd13b44df13b9e4f31ade7108de24a409e9, + 0x2e510e83757137479bf6a77478344c10bb07faba1f97da9c0537da9be515c5e3, + 0xda0ea6a6106068ef55cda415d30f30ac0e30877e2e03abf618ea2d79d980820, + 0x2452c916a252ad3c7c27a5257f4c8328d9027d66534d98ccc9a43421d70d83b2, + 0xf9c77bb51cac4d5ae3a97243b5b967a65f647598197721b487afdf40a7f68f7, + 0x1f9e045050fa171e0ee29df6cd436b6bf42a576b4ff50c2c913aeebc084f9115, + 0x2e7d45b66ed46a7205c8af1b5343d1d3fe32f2270741c450069783a4c5be0dd3, + 0x2516935ea1d2480e4350f961e778d72f56e02b57a98e892b0bad80ff8eebd7a6, + 0x105de12e7429ec594b85708128893f8ff201f6fa6b6e58a2f85403e04b3e3852, + 0x1fc9f7ca915a6cb6b67ef53d985021ec23469970c5eaf180b0deb0dece3bebad, + 0x2811b669db5b1a371c847093244ca2f8d653537d382f16c072df917cd59cddd2, + 0x117cbfbcfdcd7181ea2b182bdc6a43f72a78bc9a6b1c27d5a4d4f073b525f86b, + 0x1e8a05c84e5252cb9f3f4c81da5c5419ced59382540f32cf949b442f67512f78, + 0x24337a6b1cba32ffe53d724439c4554a2430c42da902997c096c26e7a3e88c8, + 0x2f90aa6e654fcb74227af9060991e0a68d47d8021f7968d384404b9d4476724f, + 0xb181fc79032f8437c5bf21425b264aa28adc4e92ab14a1e57964c79f150215b, + 0x99da6058ed7f95fe4cc85f3bd708620f371c9b32c18e235c44b415f4c12bf30, + 0x9212f04d8281e62b36d022532df405b8e5dbd81c15f00dd094130d43009b4cf, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x1107d939e735721d6dbf79d5f3060247a39316ea524ab8c0ec617b2ec201a26b, + 0x2f1c347523299d959fc1590f33534fc2a0e5adfc5de0fce0fa0eddaf5564cb21, + 0x149ef73788c5149f643a0d35623cfa246b6b83f3883475060ee613f74aec616d, + 0x2a8fd18e8e3ded0ad1e39b5e159e9b1298bda05646ac66dddb50e64280889670, + 0x47dbcd211f6c7ca6e60ad171965e1dd49d07b055b8468d33eb7c162b3627565, + 0x23ca2270b14221c76b77a1f919764a9399db0dec3db5bd28feb2d363e45de608, + 0xae18b193b1142e262a16d0d122154e48849d5cd821b8852a2cc2a2e7401e996, + 0x1857d1b6def0af45ef7d3d24dc7529d2826ffb00bc7c7c7aae74c740caba3caf, + 0xf3cc84626c45ab94e0b872c3779dfe3f41597c39094884678de39d8c1961891, + 0xe820957878be6285a630109dd71d5ab98ecf1c1e341c7f05be144a6808961e9, + 0x1dddf5d71605db9aab02d71866bcaa3f304707010eb12963e30f54270684f686, + 0x22cb55eb86c682ccce666ec7fdd5167af98a04c5731477cee41401f70bf05c89, + 0x2285685b32e30facba36b7813a94ae1486502f7c550c49b865cec83f46c2918b, + 0x89eb80349c3dcb0f5b5624debfba7da90f041de9bbcb5f0dd5e915c92377197, + 0x1ae6a640e952299c2aed2ffdfeeab32732e9c5e2dc95314d217f0642816be3a7, + 0x2ee58c48db87e8787a65b7adda68a844aa2dce2ebb95b85a0372219d5469934d, + 0x18e425f1816a3fd2371717b0210df14a186a184c14811245b0d2fb38e34da7f8, + 0x2d0b4c00ef039859dca8f5ec2242dee07eb08b40c134813ddd20f1e49cb46003, + 0x1bbf1b9e8426a43da69f0b718a93348b33ab7bfb49f32792d0b40a1df5791f2a, + 0x2bca73de43111cc97e7c860ff86c75c29b66c5cafd04f36a0673d0be35fbb343, + 0x1a77d34364e2186eda96a4c0576a632ca53a8579ea24ba17291eb71dc932e5e5, + 0x12757dbdd1ec1b481648041f49b600350ed839580fe4c022810e1f9ecae80b12, + 0x2491a75bb6c3231b90483b0f37596f07926a746aa6884f087f1b7694d191b51d, + 0x998ab89c76bd9f620abd41cff82b3d34203f4e6af0ee0f32e7f72f88e4209ce, + 0x2271c33914091a7b0760c2752a12ff2fccd4f512175ffdd949bdefe9b5444486, + 0x2b76d998c8fb9fd7a192e5bf3ad5948439cc061182456f9ecb60fcec97d69ef1, + 0xba089d24faa83dd9d34426596f4305119c2baac05c4f727363cc07dc37ce00e, + 0x168be56f3c38107ab39578355ad8f49ac0a80661977c3a758c29a08a3a7733ae, + 0x2cdd0f5feb4447b5120e670adba86c12d71e5f9860ec4b3eae28524825ca6e3a, + 0x36af5faba2b1777abb199b35334d12a4a01a92485d53fd6e9211949c43309b7, + 0x2c1dcb685cc47c1dbe9db43d809ed56ed6f5f9ac92d76bfb271c10b66b62fc77, + 0x24633d05c06303617624fc379b46a788b0d69bde4057dfc36eb3359055118bff, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x2224f3583f007840f77ac63371ade2a22805ffb999a54fd0feabba444ccebe18, + 0x26714311d757b433c90cbbef69da79f27493dd48c26aa00892a69f49412d71e1, + 0x2fcc716f7f57adc4e9cf765fa7d0d6f85b2e71b7d495d12d41657da92d50b402, + 0x294a3f5ca5239bb5a7b165470474ab58b5a07e2b3da2b4543d2cff4e1f0a1624, + 0x14b4beb63d909345cfc2891d52be18275fd436dfe64def3ee9a056da6df31674, + 0x84460af87c46a4276cfd2a1ceafadc83ae5e917669e8393ece9d52102d44ca0, + 0x141bc6edfd3d6ab0d76ccd6452f746e1e2a04d7dbea197c2ca2a6d498585de6c, + 0x1e757acda92690643a370b9c69cfeac5f2cbddc70fe984afafa7d8eb1519846f, + 0x9e92da83e2a6b8bae2a65c80e94f8ad0dd5aadd9374f9b666e5292b1c43edc7, + 0x28b539f7cf1b63612fe0e3f019dd8055760540cd2a998b70bdf5c755554a61ed, + 0x4f1315a1e31ab3f8eed8312a43dbd1b4b72362ccd637ed4dfebad3d350f2467, + 0x106aa158cdedbb22ce5caa3df644bde2d9763b32012a5fb391dfa3a761e2e33, + 0x205bcd60e27251d356cee0c9fbfe5cec10606aadcddf7dee7b6d50429248cf29, + 0x1fa4539519ef1cc1bc573c8af5bab6df0ef869778770109f8de349b606bbca41, + 0x17cab2199c1a13dd4608a9e1e4b3bc4965622d8b574ca6533a252aec9395ab05, + 0x2c34d65810a7e5a4b851f02a66ac4d1ad54ead2ab633ffdd88c95dd364b16420, + 0x128745a9a55f406ff9327e97690ef8137648a8ac585b1d483e87be00fb1e8866, + 0xd797eb05630c87b72ac57dabfd5e897f0679bcf0798652a327bb6a02bfcebce, + 0x2d49ac3f9e3ac8b8c0b37442e804c4487249047cd6a6ba32282c55ee72b9f4bd, + 0x2447bb4feec91d4b048bffde8de39dfdf87c8a9a3623cb563ff9d6203c6da1d1, + 0x790cd64d983c721f883cbb6f4aa15ea76aaa19dc39b1f44c4dba993bc9010cf, + 0x163a3b62e1a26e8604fab78ff1be0a3699a6b08d329feea137062fdac214b0b1, + 0x64d9003fc12c06923f798fbc0f49b33a6250e352180eedd7fd846b7f9593dd7, + 0x1f0d94af29f162d084ad70c2b138a6532db8d967573418a3ee82cb31cc8daa26, + 0xc30c7df8956774687f81e3881acce5c551fa89eaa5ff7369d2c9b68cf97a283, + 0x1814723bc7c2396b80b93f41ae3773543a232b0fcc80d78f92d48c908cecc77a, + 0x1efd30a08cf062ea109229b3bc2dfce564232dc6b181030d2c03ee486bca6d35, + 0x14e923cc919ce767c8d0c308031f1546740d512c6805a48b81ce2bd7e95cd9d5, + 0x21d74be8e343e93f759588cd7d29cd64a3afa4ebb48e1204a3d573ad1d56f4da, + 0x1b8e0086de4de522d5c81eb0a996955ea7004aa6e90d3dc9f37b3bf834b08430, + 0x17e5a80ec135e0c932f063972d785d9f89eb45ffe44dda9a8ffc11468081645, + 0x1a5caf74532f2c590fee8503a13bb0ee8e931b6cb92e8f1e52c337f3c7e188f5, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x1ac42d7b0a6e8b8f0a097d11d8651798aa5f2676574418f23b7fe6168f28257b, + 0x1ec67557d1bf0e6f851c89835c29d2334967383b9677c71e10f12ceda3593e41, + 0x2f47ab58a58e52340df845a782d6ce983366fa669f4d9373f849c0e3cfbca272, + 0x8f212a5650c4b2f68a8b7a14789198ad2c224facc562e07360904f0adb8efd3, + 0x2592c7276c9fb4e962b8f7f5bbb95018d17303a6e8a5b513b2f3ef87b66d5135, + 0x28eee34c1029e6eea0cc12e202dc1f4b50e73865acd6a7b69302a1b45f2c1907, + 0x11bd9407f0c9e1b9ebe379342b2a426ea14d87335522e8aaa880236f5129fd0, + 0x169f293f396fd012d20b323f9b3eb45362e5d272d2342696ddf1e3efed03c069, + 0x1e1f46890d389a50ac16e5422f79d449a6011c5be9e53c266285afcc7f5b2608, + 0x128da78e60b0758189982ebda43acd77c51eb6455d720455955ff631a922633a, + 0x1069251fcb9d2fdff50a041154e6ccc7579a360ceab1c360d20404630de5565, + 0x1ed383a4d6c433c6801b6853b5c40f67cc4fef27c2610aac9540d5355c6cdb88, + 0x6e9b3357bd837d1a5b8c7598412c78216daa02bbb25970182e089872cea4e1d, + 0x2fb62dd173e44023b3e784ae457bfc93adde1e08e98f3631c6e01bc6343c5bc, + 0x204797d9b16d45b093bb34c6ef5e27304af9ac7ca7c4a252134d3b61b6954b4d, + 0x2fa8b35e4e9405e7ef4f2d80820396ca8f026f3e330775368850d423394b2301, + 0x10c38e859ea854e2c6bbfe3acd613ed59d70053772c6fd7497ed2d4d99b2907e, + 0x1f44270853132e2b71724021bfd741e39c3414e8c63f7b148371a921355b5085, + 0x2eb4d6a5f16de3e5b2c2c33801421c2dee87a222374f4cb2c2fca1fee4fb1ce8, + 0x71e2443b4b9018d2a7ca057b35e2050e59409c688fdca9289c96444378486ac, + 0x1423a5126a2789082bcfc21a6901111b6b5299c4f76d341c8b0c2e9dc4712726, + 0x26e1e7b62d89a75f94630821b5385e6c48a97b8c5c5ae1b3b1f114444e8a10b8, + 0x14fd3ede10aa7bb382991a1128340eb1e6ce0a8d573f643bd8add5a2d8e8a45b, + 0x2aaa9048ecdf21e06da241868551cf548f683880615368a6a2cf87554d893b11, + 0x2e083ac42fa88939d480a976e73c6773d26c4583074073d6c2a9f90071bc830d, + 0x12cc2a0dc5c021316bc97e26a35a9f5b062087b78224526541f528acbde2d1c4, + 0x22adb7b0e9d4c335e55c7aff8bca2048a59c0101099e8ab99b79e64be46ecc7e, + 0x158cbe94e139620090b700f9fdef637d70081aafdf1aff2eddbb5e2f6bc02dd8, + 0xcb42f4bca1dca294e7e897d0a0b9e6cc72531cbc872789265fa904aac00252b, + 0x63156236d87d3673e07b739e18d79a22a6f1c99c2a4c3de4b982b5765c4de49, + 0xb7f0818b640763c1268912be50230493391a86d9de957810fb2d1548397a088, + 0x2aaeda58e831430d69a57059f933fa5deb7fd04fbedbb016a919bf5f4d8857c5, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x1d3a013444e777bc4e816c6f9194646b6009d5ed09931bd8011f5d3bbb01378e, + 0x18e4924f258930420b1fc45cfaa31fae7ebed37f375a17f1b8ec6e97675403f1, + 0x27c63021eb05577b17d50676669a6d590535b6114f74d6c14abb3efd3589781b, + 0x159d12a40b8694d9dcda1149dc98bc3228eedeb19040682a2c5254723a60bc61, + 0x1c04115e802bd71622e1b1425496f939414737bca8dcba1f070d8a44f6da2d21, + 0x4d0a06d0ce3dc2ac28ee5f7774898d7910714459b385b5874ac46dde92d79d6, + 0x30128d834fa6bd28116aa6cc19453b6f731a0970df12416c8c4e7830ef3f6f37, + 0x1ab7eaaaf3e533054595ab5a16d37af4b028bb6612017235432179802e34ae67, + 0x2a30c413b8cd102148977b0fd1f51d4cdd2684995eb899156438afb7bb4fdf9b, + 0x1eb6795f1e63f8933ed48dce55d257dbf972298f9186c56d0880ae76fe562730, + 0x21d1ef33916e6a7ebe055233c5e38e388ef6e2bfbac5530ec587719182cc0b40, + 0x9e2af7ab3d9206c3f54ded28a08f8b78396cba9de3d7696964d2529a0517c59, + 0x24564fb0247a0a53e81946f9f0365c5d45257ecef288d6d67d0bdc91055a80d6, + 0x1b9ded9f11fe5b6dd79066bd0e16b9253935e8d0bc2bfc130db23a8215d0de13, + 0x192711d3f80d452839ecbfff6dae32c92bde74d051a75bc14170bc690e69f9c2, + 0x1b3af1fa25c32da1a5467fef1dffb9cca1b7b92c4d50e3f7ad0548ff2c4da1c5, + 0x22bcbbbe6b9a39e310a03a9bf0e491451698d4d874aa192b828c1a4fcb86f3bb, + 0x3a947c69e09d64be68d7bf2316f4cdc647c912a6bc4a936232cb2b6d320af52, + 0x2d21f4596d98ac3b62dd919550859a7592e504009d268bb7f5bea0f38d4aaa46, + 0x2b2708b2cafc826207f80189733e6c53d6ec1ebb3c54656689c10a8526967bb2, + 0x13e69bc7a5decd620276116f40f9743e487cc219df1dc1d769b1aab8eb74316a, + 0x118aaa8f364cff4865df9535488935c34afa1943b1e28aa08d440a7a7d72d80a, + 0x11ad3bfa094695c23a74b1f23d9cf7808e7916b9f0eba90ec571e06e4f310106, + 0x2f4b6c06d0b996fac689e922707ad815b411539f857871cd1a6b9aa34386f108, + 0xa6288360ee10c1b02a2a6a6d34052b13ce79fa1ca91f8ddbed485dba92eeb9, + 0x25ddb8ea60be41e7e99c97b6b5a7822f071027932936673c02900ebddddaa88f, + 0x24c8c87f88b21ea24ac03cf1a498d64157a8bfe27ee0df70187f6d11eb856d2c, + 0x2f958a89827eb535aab871af8f3e1fda9e0b6dd0541d7c9830321202d467410a, + 0x2d2b3221d9d7539c627315e2422ae26dab5ae103cd8a8bd19d895ce97e19f866, + 0x13bddf23791d0989c17fd99bd435437bd8bcf676c689ca0595a0d04afd9c2603, + 0x2c15a1ae35281bd2fe7a611523dd767be99c5a32a8501ca19b1a8940e1062826, + 0xcec5e18e50beb5ab2c7f5c9eada9fe3f3e8689b0901afac80992dda3bbf8803, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x1d23ff4f22dbb142a5d4465aee8fcd2fbdd8e450d1cf6f29182445d4496a2e5e, + 0x172ee58685e83a795c76191742ce9df18765ec6f1e9d1233bf73ee4fbc53276d, + 0x352cf61f75587d4a82226e28ed9a38863d7e3fe6647117cd28c736cb2893b5a, + 0x1e571b53f1260a7fd4ed79e03d32e23b2627804ea5c038618a239b2873961fdd, + 0x150d7efd3ec4cb7eaa6703bb78913527c77b07e38c93a800841a123ebf3edebc, + 0x13cdaeb00438b5c6a40c0d8a039a8117269e15f580b8044214e5638f2e87a37b, + 0x9d76e8da13f87545b74c5f505af00e204eb2414a186b54e6dc3b7b8c24e27f0, + 0xb6ec96b7f761247ebbc27f64fb4275f1128472e7ed11e8a712a206cb9e16477, + 0x1e066da048cf035bcc17fbc4fae18348f4bb1140d9519f1bce81144da499a536, + 0x426afeba63d285758165a95db5df2aa86932ba9f50314c5f7ca4408bc3eaa86, + 0x2ce68ba3f40fa50262f137219ffa5e343650976b2d5d2d1e80b687e40e426d1a, + 0x1e1dbc3eccd20a0a96846877182b08ebdba8bcb16492fcdb60acaa42317ef8eb, + 0x282ae2fa425f91419dcdedfbe6800a0122a5211345524b9c320cf776a201b467, + 0x14bde086cfb19372690c53b0e04ad0ecaa78a8babbe21de8a47a796ae9730e5, + 0x114e76d2755ba6fbf01851955b051cb5e7d677db3fda594d6658ad4fc099236, + 0x2796ec5da2337effa6fc65cb8536ea82b5e60b14f10b005b07308b52d3011d2e, + 0x252c6e37471afd938b2c840b2818ed18eb7900adbe9209e038939f883a236f21, + 0x2b6e07212cf2e4304a307acfd16edc984c170d96e7953460d1cacd3e84dc9e75, + 0x2adaa99cc0a5150cfdd4e17ff6390c973f2491d4e2723918d35ac55b5deefb49, + 0x17759cb89386f9365fa875620b6f6e7cb6b5cee2d77f0b7355d9c33ba0e6a460, + 0x111bb071c2ca17121de11f36ba7cf79f699960dd76e09295610a136afd200e61, + 0xf394cb8fbdaabd31e43d4baeb5523945e29df4f720d026fe115bd1693a88818, + 0x241d58e1cf3ed5d94bdaf9f0c463fb645b65fa19c52c193ad67f1d38fcb343fc, + 0x16713a7b5d8cf3ed4c25d780a7968a80f70c566e6ba208859e6cd69801995242, + 0x19909ba7fd3b8fcb03b6f810f246f384563ebc5896fd61496737f65b5362dd02, + 0x2a9dfd2dd3048b0347dd42aef6561a277adf3d86fe83203df1778536e6c24aca, + 0x18532ee14e86e608555da020892086f155c685561272111e7f4b6c91781864d0, + 0x2509cd9ebd96c0d7cd88a3bab280b42068691da92e03f6de5930ae67ffe04f51, + 0x11c0877290f334877a26326ce2e6ca7a96dd732288d273efcabbc0294e2daf09, + 0x26009dbe4fefea6739e28a0a6fb1dffb35d8516e06914862db8738bbbafbfd1b, + 0xe9f75fd533fa509a499945055cfdd603dd9930a50634e41a935098d571012a8, + 0x1f3592557428f40b9e6582536aed2b7264c9166093b76df3ed68ff033c7ff93a, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x1befd6dac2acbea83cbc882c661e80b50b85af2021c7ce770cbd4e4cd48f69c, + 0x2ddb55369f02ada084136f4092258eff0be8e170cca9eeb6e2b65311edacdf9f, + 0x12dd67091b9f1d7101cb2cef74fd216fbf49d4cf33548e6d8310446e562cb7a9, + 0x1e824766a37cb1d1c7e75e3f9c261f4aefaaf65080f870e972b14132e7aa6cd7, + 0x4af8f03823d37cedd40c1791ac745b768c735234f5756d638b200e1c134bb1d, + 0x1b65a271d787e78382a9ee5a1715c9aa23e3570e92dacd75004aed46b5e4f778, + 0x1b239d4ebb80ce098356e864632edbe6affc3e5a34d92fb9518ab89f16ca4f22, + 0xa9f23337f4d86a82c5dd9a9216cc182a5a6b6eb6fc5e42797df022e276846ca, + 0x86e0f2ecc21e30809e1f2697cd036bbd6241d68668b26efcba5a63bfaf84037, + 0x29bdb60350b498b5e1ff14f7360deee6aa03cca4dee1a94c4181a28f0fd2a9f7, + 0x2ed66c1da1c54cb685c48a32d650d24c17162a3c758eb19aeb9779fd35ce5499, + 0x23731d564560385b611877a371f26ef53a64244728a8e8c5fb7af1d793e0c7c6, + 0x5d2071dddbfe020a1d54d3be85485fda55e94634c3c7f92b6a0e7df8c54cb47, + 0xf43e2482200419e7d6bd3242598add21ca3c7a6f1297401a48aeeeddf8c42c9, + 0x147a84a37131c4e46e9f9ca597b984d7b4a4239425a12ce32f8fd114874a8cb4, + 0x6acec506161a2536df8657ccae9de73d400b734124368cc4da6fd86ef670a19, + 0x23ca187dab655ca80e1af85d71cb254f05d27b6f8000e366443afbe83c4cc725, + 0x2f8a17922cd86c60691695f93bf0f432f1ef9f05e2e63e9532ab277fa47c0297, + 0x1846b9769a8f327eddc2fa52e235b3c54833f35db8c7989f4342d667ddf2caf2, + 0x243270c2e4a32bbc19d2bd52271b9a8da3f760251ae2f2d783d2854d749d0ab2, + 0x29e4f01c0da1655d98887dc01ea2faa33baf934660f2c934187ea6902f5e0dba, + 0x3e46dd55965a70ac8d048f6ef72742efe897a8a5cac24a0a323452a738a4271, + 0x3032ada92a06e725cfd5cf71879293c3b862c706221b604bf004900182588e87, + 0x9aa6962258ba57549d5496104be1d44d36adad0118ce7780f470655e7a79b9e, + 0x24f4c3f9b2fb7dde23f455ab4a5e76ac60617e46bb7900dd97769420911b59cb, + 0x10e408cfdce8d6f9b7b710d2cc93937cdb43d86d59580ff5417160745c80b7fd, + 0xc7e1f9439ed6f97010e5539ecf56bf151a2955f8ee20b2ec89879d81cd24a16, + 0x20bf7ddb42d4c9d7c8bc1e1b110f065665dbe466145402ba3a3febce0fbfb3d9, + 0x485724e08555b73d84eaafda9702a639baf4de0046875d1f0cf609a1270d720, + 0x2e67be03421ab1f822047861a72a6d08494e65bbfd13c3f7fe6ff48cb863749b, + 0xf79509c03da0c16557c73fb11286f9fddd8f86d235071eaa7aa71a85f547133, + 0x1df1ee0ab120c8673cd3cc8c6ef2e15d74810a03809c61e16e8bab3f20a296cf, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x214e36f5e05f24b3cff586c96031ae938f81cb8624b76697a7e1e79986f1cb94, + 0x26e5f56af93c25c1c66a64447449b0256433d47d6413c0b2fcf6210ee5f138c, + 0xb31a4ad9ec066989d7421b0f1cb06d7683bf5a64e0c3067e0b1a3bca5a64a2a, + 0x8561474777e7f179341123ab782afad4ff632de09860eff6ebe29e4fb1a0c36, + 0xffb57365252bbf56569562327f8db32f337001a18e56fceb006741a0de303ed, + 0x186989821e7ba7588a8634d87210552eec88f846e3701bb336a5b7f0507d01bb, + 0x2b68655758f842d0aa6dacaccd461eafddb981b75166e55dc1ee2c208308e5f3, + 0x2d399f586c89c60556a7651f9409b01aab8f7d9d9322ecaedc93c590d9cd0fc0, + 0x2da5bf9c9e9da4c394519580405b41e6545886063a830437dec32d7f1bdade47, + 0x2b65554e892585688e54d5bb49e321f507bc305fe56fb780e41d816dd9158369, + 0x2ba41319cdf6a416c9e11bca8441cc610c6e7e45c2108dae471840f71deac714, + 0x240f23cf9066f8f5308a2cb0f33e1b40cf634980a9f76bb6ff07e28730868f54, + 0x231ff9a1222347ab20a05faa8d43bf8cb62f0ff9df561f7af015c73d191ffe98, + 0x482fa25dc024367c8dd5429b56e7a0736c866fe84ea1afffc3f5d0f421fe651, + 0x2923732da6b8bf6ee5c73ce34d3ac60f9660eda207235d1d5af9784103f0fb3b, + 0x1753f96bcf7911bc332bcffd151e9e82248a44517474204b3e9888738e58c5f8, + 0x15e1d217ad8bcccb9a7b3009f26c09576e9a83a00f3751fd4ae4b396667be084, + 0x18e3a1c74fd50b4cf58f3096ed129eff1e129302507e6efdcc44c577ff23403, + 0x2ba6780071d6646fbda80d23fabebbaf0272a953fba3249e3af0b56f22ce8120, + 0x1f7f5e238b103729627d5c22c78d92ede19a56995972ca46a317efdc27fc70e0, + 0x2ea1bdf6dc4bb3ba6c3d068e085a361ec8676c6fe2ce66e842885b830315378c, + 0xa6fca77ea6f6437fc2bfa7f2beb768dd908dbbbe87aa75ad303c62790b34d17, + 0x6ce49d6e3d7f46d2175ae9a176153bfd3a3b8f93237a5e45ca9c4ee04ebc5da, + 0xa01cdcd06c3f24187bef0d4a83b8e21a54746f27f0f0d919e08b7cf0d241776, + 0x13c68e6f75234dd86b9568ea56dd98bce6c1b8d64fa4bde97dcd7562d0a9844b, + 0xa162dbfe59de052c7f1bfd5a6a0ed87c5d6120d538c40a537ecd0f3ac12d88b, + 0x2af4c78dae7b20fd7e337e83afb1feae26c555a544d8ca8fc5c9555423fe1c1d, + 0x2f6c75f43301c4a5bdc3d32fc1d66fdaaa4f3b04236427ede87ebcdcb6c7fe59, + 0x2a4aa9b8b9464b6ab6c584645c872959c9f68ba65c057c235b7e2fde8160e42d, + 0x2d8dcc78c6658c1188d60d080fb3cd8b34ee5fd1adccc8a47d499e62ca725b05, + 0x14d6380547e6c54a017d04ca2b2cbe305a4638b32b4163195b459db073fa9872, + 0x478b43d35f78cb355796e0ea0e8e9f5a8b8d6c59cd2cf58df4dbac1a55defef, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x1ef96c51c2b7b30f1e2c59a13e9e76f079c907a4718b3b1827228823b9d8172e, + 0x29321a97121f289220eb66f5382ef63c56ab3d289391c4db61c9dacd44a823a, + 0x1481bf24e7b45de9670afe57fdea41b8beeecfb23422e83c83de9f6845ea9576, + 0x1ef847d3c1b94f7d5dff4319c81691a1354f76fc73dbc600638472570c8c465, + 0xc266666de2f8bbbaa20aca7b4af2de342cf1930552784c300342f3896703b9e, + 0x149bb0f5b9d904cdef7c045ee236bc38a33dab8fab24381bbd14aac30b12ebc1, + 0x2ee176ae76a9196262b1d9b78ce2247cf2133e707cccd952e37d92fd71d88d9a, + 0x1376c5573ebb7265f70acb843f749ffab6f69d346c01e8fa59a1c61091e53f03, + 0x1098a7920a98fb50caa3540c5efc8f6db3dffe9b2c806aeb20501cd0e09a5b45, + 0xb01cc70e8b9fd48f7093dcc2ba65898771cb4302388e39d95095b446fbf6bc6, + 0x1b0e1d5d686b5c6879413df5c510fb672a6d6622bee86008f32c0c32d237b94, + 0x1f74ab5e561a3606ff3b9b334dce7c65d772ca2c1d8ab0e2591d7b8dbbd7870d, + 0x20de7f8e6a491ab79a1d638f7ab760fc5c27285e90c87ad512e86a1bff3b247f, + 0x2e48491edee5daef9ee63ac52cb1734aa69e15b68d8c9e0da68ad718858397d2, + 0xebddc875be02613b22701dadc5f3ad1020a797469a02c064545adfdfb73daff, + 0x171d043f251b701475bf87b388ee12b5a469cf0b5f4c120b34b7b8df3a50b898, + 0x11c7c2bb7facd8c4d0e37f220026818496ad96f0009975cade5a85dd0b319d3a, + 0x2b86058c080559f84c11d33ce0dd77e8f4aceff8644a1ccf78907b6f02f2a2e, + 0x1bd631d67d9ac357a1dfdde1c92a62b0c7fcfddc06376746b45231878b83da75, + 0x2cbdd86f5eaaeda63428d4a39c788df7e08cbe62027d423d3060f7a04fe40d13, + 0x120e0960c012805f36743a540c3b89f519e39fa631ba17d2542d13ef27469cb8, + 0x8e188acf6db761e26d65404bbfd7a0b5537d4e05d85f819de8bb08b1f9e6dd, + 0x2da3a719e3b97734dec894cdff62842dbcaf8ffc37040bdd3f2249d32df42e65, + 0x176acedbe2dc8cdbad093b2a591292b231289939391991be3b9ebf27276879d1, + 0x15964189dfb203bd5cb0a49c9d0fe330bc82a66e62b4bf29cf9a878b74133c92, + 0x7e6833725a1a694e290a34cf6d725401b7ba6c1b0b740226bfd38b66acd1b02, + 0xe4fa44c437c0b7871d7db91fee425aef4dec5461c08cb8f7e8990ab8aa30724, + 0x2e3f0bedffebdd3509be6b792530f2041b04171e729ddc9718a2caf15af84b38, + 0x1504dc8d0dcecc34da56ea5522a2bc7960d0dd2e0ea24466b84f59aa5db015a7, + 0x178c9a3999106b047952fb93395c214125f988fb1cebfffecdef4278a076e3b2, + 0x1af7832596eef3c4cc8630615883a143b7b6993e90b4332e66f36cdf167bc838, + 0x2822dceeeceb7a2e1cf3f25a018f8ebdfcfc720a39e370c67d4333e515ddc724, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x25ce0d19840e800b798a9033269b14f1726a4fd660cbd3b6dc3cb39c07f27f53, + 0x175f82195ac38e9f11db0773887a93338ee07d2852587fb4226f11d9422b8328, + 0x2017bd7838d0bfa3ea272ff2e883a80e63c7288a4433997b18b4c5f0da5f7e3, + 0x1818b2d93a4d80ce0068fd9ce46ddbd200b6040399f4355194edc9f2c55b5ac4, + 0x17c59d81c21e6f83f8972fe07e0ca9b352d04ef730fb76dd72931925c9a78427, + 0x13694ae68e1c55dd02a5b8c1915f878edfbddaf12b45fbe9fa27a2954b213a9, + 0x120221d8a84571726473bfc84ad47f1b04ff70e7a8d8e9c1e91e1165e9b4f18f, + 0x14d65cb6f3b2e4bae5ae5ed1cafb3e68ea86144d27fa8f33aeaba929cfef4d80, + 0x1a6104dae9627992b627b87d84e656009bb69a3a7a9bfee98aa80dbf21bb6ca6, + 0x1e3af87bd45255572d1d14ccba0d7b2f8dfd79b79068c6f3883ca9fee52830a7, + 0xf3d0df45aa7bd62a9768cd20f8466c37b7ec5661968b2cd18abd57367319079, + 0x13b8af0004234bf35f20a7cc7b9fccc999d0d8e4f5ff6f26c237835a1fe042fc, + 0x16e0bf0c9a24d467e38c3778c76b2e2250fb1c06fd4659fffa3093f493a9eca2, + 0x26d28c3453b3d7eca08e87a6c46bf8a698385ff358e23edbb1e174efe5c233c5, + 0x26fcf8eeebb1ea7b1754c047bac9ad888edbece428440fe2102d46969daae640, + 0x2731ccbaf234079c1038e6ab182efe0f1dba3c47effc3e21d2e195e3f0319503, + 0xc785f0fe165d5d26f6b5f2a0ffb7ded4408eb4a92f3eb3d13947eb094290d97, + 0x2581c7faa23de18b2596cfc15ff01dbc84bea0fa4806c7d1a0abc43e76ee0f3c, + 0x27e3f76b7335ff9fccffc865fffb83b368995521e989bd4dd6a86cf595d4a17e, + 0x13234d0fe49f03c4a28ed5ec2b8044e9c7dd20cb831e541b7c540db6c1800637, + 0x11a6eaf2aa5518374eea4199c11f3d937a426494ba614ddbc6ac6ea1dc804ff3, + 0x1fcc367b6de0eac68cb524cf8008e6adbd783e8c13821889031f886647664a0c, + 0x1458038bfbc93c12974f7474afe5bdc94cbd539c913100169cccbdd143151a2c, + 0xf24afffaaa9f04e88599ed696dbd4eae28447c2f05b997194ec832189cdfe25, + 0x7c8e157325437ae945c3c67c4c757493076bae3ae720b00d0c35c36453f6826, + 0x11198181950b4a2475dc01088b72115a94285ffec4c2a5ca614d13b1a14fb319, + 0xed57c8d4abec5e290ca22be70bc5e754e135771d5348f7d711d7383617ecf36, + 0xcec6b37e0709d4c9d5a8ce252840ada6dd5fb95603720af648319370941bfc3, + 0x192f0b18cf17855bfe94214aa47604eecc598f8df429d9c7a9f0c807a467511c, + 0x10323d6e384414dda110f50d67bd06633361960a357f9c6de63f837553cb58b5, + 0xadd901bde5b672bead23855ffaa43194e666b932d604f47000f08d1d2640511, + 0x16dd65f412cf9f1325a3cf4e9a8f02c27371b2c3d90888e7d4ee82713dbebaaf, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0xc86afa39353edb39b52bbff89c5c1a2bfbe2b4100df0895fa7c82d8e77c482e, + 0xc46613d67d66e8ae31191ad6e5bbae2539169134c5311d25c06ca54e9f3ab77, + 0x395678f2449c3e1a76b5b9df068e5dabe76e15ba8589e0703efa3fc1244184a, + 0x19cdd035008146af2718d7c2ea72fa725be2d10efb070b303c809b861b788b51, + 0x1a047c51c9647354891ea4acb582296dfb90bc65c97e8889f1d075fcf217cb48, + 0xc6cdfe9a0d4271a15018a2e3f2d80dfb7468e216397e85e138d20be790b2307, + 0xbc59105470408a58ed2e8816aaed1c29dd3af469e2e7eaf3e1ac366d40d312, + 0x2bd71a360bc27ecd0f2ceddb797ffc5a662dc96cc64cf15e03e2e63a19aa0453, + 0x45e127feeab8d5df95789dfd96426ae84c34723fc735865f80d98ee53eadd5d, + 0x153dfcb519caee780dbcf85d14af1fd03d6888a8f8f35e0f5d16fede2fc3be20, + 0x14e6a09539291352d800dcc6d07e0d0a15b544460b6a00c00b236fe5befec431, + 0x2eb026a3350a6d92b399aafa7e52a5e1730d63b9212e6431473dec34b227eb63, + 0x1641bb238c520d7b2da80d743f6325b013f7f2af04f83162314ca4554e4c034a, + 0x2e2b3857032c8659c4533fdbd59d3e118d810ef879943988e6239fa808bafb4d, + 0x2c37d689e22b1f332dc12fcb8490ec1b679a5e15b1f4b9b5edcc16507adbfd92, + 0x3025a60ca5e0d56b9507310cc9a8a7a6dac7bf6e942883c6f73356f8a0c2afb7, + 0x7f9e146e6c775ceee72b28edabe0f4735ac136ef900a6147570f0ea6de0782a, + 0x318bc71cb7dc9d5f8b099c165d26545fe0bbf112167860825c84c180493c6bf, + 0x2c6fe3f7e18010025df5e6b84648d0669067a473d849b4e181c3f4e03d42b128, + 0x2bfa2ee15d1c06192533994513500e6386bd767c78391160dc4ed7ec323e57a9, + 0x12f7e0085d724c9e28547f4fb7583a6b0fd4685f1fa9d8c012baf4701786270b, + 0x58f27cb9e4bb8bc4df8b66ea9b5a5f8b90cdc72b345c4b0a300b1ecb6e2aa63, + 0x1f34ca32f956eb4e099ab646d95af278ad8db5cd00ddb1c8a44593ea2fef03ec, + 0xc73343dbd1d62046a2df0d555812babf2ee35b1fc103bf6938d783ad0b44499, + 0x18e5fde3115a19d207ac2b687e135e438d915cb495c74a0069fda3370f46083, + 0x120fde4dcc6a7447775ff4e871e321ebdfea69a589ac90714ea4f9a9608e1e23, + 0x2d4601dddfecfe13175df8d48155e9aff8fcf449dafa39a245b8d6cb1706f490, + 0x173632b4f61f2083cbb3e04853acb5bafeec8c75dc4407123e2133c060905ed5, + 0x26b288e1ff854948e38cff794996597108b335f67b1fa2598c5ab2691a927730, + 0x2a688ae162bad939c6de4d889910df138d1f7dcc8989d48caf72e1e22b956422, + 0x160f4b8f49b226f36e72359509e3dac329b1372a7fb63f055d7f9b004d5734a, + 0xddb062d06f99f34542ed03bcaf07a59a456201d26f15d45b8f122e9565d4044, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x13785c4968bb97c8c769257653ae58a73b94a24553fae0e00988b29f47ab549c, + 0xec91cce07b1e9b778fdac5cb9ff8d8e6438292781351bedc3dda454afee474a, + 0x22ad585fe3ddddb3233f390ec3cf43a570cc4f56076ed366a63a50b493a6d655, + 0x11f51cd707f519aa4d0f07de79bd18a1f7b65d2b96b6023d18a87459396cffd6, + 0x16d2290bff342fae3e0f6366c4a3ccb44c611797e77ebc27d7f5ac31fdc6cb51, + 0x16d4e47f82ee3b3d81d48a335be28f4521f90a935641a451097b8298daf0a26c, + 0x269e6a80d58dbc19ef71e682b1faa7dc7394636fc15c747d04ac950496f6e118, + 0x2c1684229f0eae24af14f894023cebcab0e384703e71ad56199c4c8c70e2dd06, + 0x2d9ede2e8993c45794928190781b626fcc406ac3a977235f9d6e50267ef18fb0, + 0x11d67805271cb5d86a927303acd7fc45218098ab99eeef9756e62135bf77da70, + 0x170206f9a4e4e0d7ef55c5cd644aacce231f7727c7f98d97417b720bc37c7881, + 0x14a30c6b5536c74f98f7fc57d004129d4f887cf18ba9f869bd5630d66d341324, + 0x25804cc693b0e118e811f3a191a9d6e47a537cb64129293c947206d9290e7d10, + 0x1a7a17b400934be92901d4e91ad3cfc98231aa841e09627cce975bab7c15f2db, + 0x2c0632973f605ced6998435a7d0cad76c8c9c223c280080fb6a8c922ad09dae5, + 0x3044b16721e5ed81d39f2abd29d5f0a761c13fe26bb4f53d09d5a05620997fc1, + 0xe2cb4e18b26e4ea445c704748bc7682bc2834cef35ce6bdc043beee286025d2, + 0x1c033ddc1a9720312cc3541e886cb227d2d37eac1cf86c4588e98203692941f1, + 0x1ef28ce82fab806a49fa311c6f4e8d0423d051e0a3500db978ff731a9378bee2, + 0x51d7d3785234a09db1939ae4ceaaf14a46928189efc8ea0fa1889e5ad0d1224, + 0x462c9e533e4745c52df23623b0b72f3c9eb8e3a9f2a22a71b5ce6ca41927425, + 0x26a33280331d48e2aa9c5f8f63c4423a6dc8019b9633f49aebbdb6a55ea5cc93, + 0x8ed8b1b9618a2db7e4746115d96cc25ec51411bcb07985e9529b6111039e90f, + 0x18fe5d991dea77a7b18f1bd5c183a377cb9e5c9c2591867eb2f8e876c40c41f, + 0x25a3f5cf66d0e82be05ea92e3a982a6b3289d9a8e51618f9b21ea0e39a30e5b6, + 0x6182fd61e1b35b6f008e9909fe99904bfaef6519618e435130155d28d1dea2e, + 0x1af6ad164424b6c90ca4241382ca0cd2660ca388775973b08e6728570a22d844, + 0x6b534601619e55889aaa855c063a2ced889c6b4ba4190da327c8a612c255544, + 0x50555bc03cbfafbaaa38191f0cde54e8dcf4fde1ccafb5af5c7e00c316d655c, + 0x579cf40adfc069a0b3cac02a495fbaab0175fe948dc97ac85f7699ec9be97a4, + 0x1d9670b720e7af8fcf67b3c832d43a0e9b36c1ce11b679554086d3ebd3743815, + 0xb9f1b4372ddf2b552fb55e7d029267a0ed4f09c4f95d1b99a08c1d6585a6e74, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x80610bf8946c2cc782c83ec3eaea36684a2cb66366a9a801b63fad3332e8ec1, + 0x2837c8ba7f104dbc7503abda031731b4a7a1dee3ee8fdc708651a7385e56fc72, + 0xe4348619aa405bdc4f9fd965dac265ae73dcdfc0f71bfa3a943cf98965610fd, + 0x199e9e250ce12b1667cb730f801334157f29044410b1d98b2d6f2a261a2f7768, + 0xa0409a4aedc8480df4a99f9bd0bdb0151e5ec3cbb6707a594d8aad6334d4c75, + 0x2719d9f1e85015ea06b50d406af582c36d5e937522c974727b1e7a4eeaefdbf3, + 0x1066a17fec5e6cd2202792015dae55345167ea35b6a65ab7a7f2af91da59ca1f, + 0xe4b0a49c371457ba0eda6cd95fdc3cb81264ad715202e43e2dec5699fbe4d82, + 0x24b58a924ae3bf6ac96fc11ffab9221a2283830e95377deb2e5002c2bdd1323, + 0x259c8606be0c6467b6ef056c6a4192776c6c3536ffa82c89f038c856862af24c, + 0x21d6c0a2a54c5ae9ef9dd5f2aa73764f38df1e923aafd242e5f523b5332bbd05, + 0x3c099cdc3f61caaa2e49d484abb2b30e969416f4e1a5678bb025318e416678d, + 0x1d4d4b8c552ef0d318a9a8edd80a2f363c1c0a1dcdab35880dcc6bf3c548262f, + 0x7e4cf648e92c276185c416d6ce6f5b0c0e7cbc2eef1e250555699afdfec0a0, + 0x2992b02301dd18e00482a9940d59a69068127f06aaa50a32322dfa2af211f3d9, + 0x16871531e6fe81173d8082d8059270e70ac4125d0951616ff37e4b4aa6975598, + 0x221c08a0b7dc5aca357a52f0127797f9e9e01eb05d73655f6c779ff43f295f1e, + 0x2756a3d44e88bd6547d02fa4460c09a2e982a4d505a3421625b9bca2604bd862, + 0x2923fde3bde5751d8eac7a9a156d2444db92b629185e01e5600c4fb5a2ea53ac, + 0x179ebe0d2b17128a67f8fce5fc42ee26c654d2a892c4eb3c6577448d5fd556ba, + 0xa1814edd4f8466f7221dd98f8ef29107a18c66320825acdddd8de64feb0275b, + 0x1cf03d03226c78b2369f79beef10f08fde37c150d4e7aa197978365ad0bd316c, + 0x2fd3e923ee39fabc387d2170ea6b9a629b0a7e28296c84ba8843f8f03ec3bbc2, + 0x12c6bd4f25c2d042e4d0ed3a1e5cc01247c78ae90e49ae722d32a584286e1b4d, + 0x11b78a0b243bd45aaa4f3cdb1c79ab206e95c4011289c44ed4d8ca99686c9b9e, + 0x8945308107ba56486011898e6bb26a99ec0f0b9071ad9ce0af820d2727f459d, + 0x2172f85afc450cd67c1efebd6becbc01114bc8b3b62b4081e4cca3418693b323, + 0x2db81bcc85e548bef5059b2595b4f06b55386b9aeba12f483f49978ec6a9cfbd, + 0xef5d0ab806be48c7d0b46a2cec1766083eef4ba4373a16abb2226803305207d, + 0x17caf822e96f4cb68325943442e65736c0f1e01b845aa970824a3b193ccf8b30, + 0x2315b8f0ee989b11b9835d8ad7adb67e035f85c24835a4d53cc7d7b59ff15041, + 0x1f5c7dea1a88280a88e2a57c1015af5c5d4e84da900bb30de5fb8c5258b46794, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x92a67467c379af9424ffdcd9a81657b04289992027e3a841bfe322924e000b1, + 0x8c70f58f02446463906891b2604d2faf312cac00e6c254f30ae85874c112546, + 0xf4af67e5395b62af989d01c1fa9fbd219ad1aa4aa2be4624460940bc0c12a3c, + 0x17f7da080a7159316a1994a87177f0a4676e249247a2a577c3fc54ea8cf7fb27, + 0x1591bba9c620f87132b8ceea1de4c4c5f09872714fe1d63259e0ef80b5f333a8, + 0xcc30f15280abea47abe01145e5f35bd877550b79ae4262f61be65a5ed0cb24d, + 0x1fc9cb670a57f842d47bb906223b02a9ab6352ba622804ffa51ee99da3edaac3, + 0x8e8b798ab602d16910a34edf3f093333041aed6704a66d782d7a319dcda091, + 0x1548714c734096e2cadef4ae88dde9c8886029e21e9ff5696971f11dce6ca6e2, + 0xa133a39d296d427598f8acf721bdc057f2cd639a3317bfef3eed1bf38c610dd, + 0xa4190ed0b3c966b6d7d0bf0bfe4d586e77b84cd55bbf322dd62c4ce7a262914, + 0x26447ee04686542296d06c8f53902672e79514770b3d6490735ee9f5df35859e, + 0x2d1d51cdb7a8fdb0cd7da5fdc33db94bdd8d5128123693ab1f4aa3e78e177870, + 0x17b204236b11bd5c5c48edfde61d817b73d7cf2f5a32a888144c7b088d3ffdd9, + 0x1915106b66fdf208607ed6888d503f44723c87a5c5aec9eed658514f3692828f, + 0x1c171f06ea82d218b24213479856d66394e160dbe0b27e659a7294e07faa69c, + 0x2a4c40c22e17c0bc9f509eb1e30acebedd18ebdda1825e391523a74d4ab23f50, + 0x20515a5d86581b02f9176d72bec69e785a77c41a16fac68e1beb2ad41ee21f12, + 0xc401945dd3d8dbcca89faf8e58b0469e7e7520f2e8982214a4dc244dcca5cd1, + 0x28bf080eaf7736338ce614a62cbb2805eea22b0bfaeac1d0cd2cdeb2830ae0df, + 0x20ed87ececd54dc49ce955a83fd4db61891865b24bd09c3eac85037bd69c52c3, + 0x2baf7d6e7863aa68555f8bfd7648d1b4426f6c39fed82bac197368b3d22eaff6, + 0x1fcf69944cc889569269c5031cc1fe8a1efb0b1953ec7f9573bf63671ec7a947, + 0x980bdeb30e0498f3c45ed4e17a4ae4c8c3bee91095a6340207b69b4ddabb83a, + 0x2455522726c3c95dc14e7fcb5fc1c008b5736e569f80505e71454f8aaacfaac5, + 0x23541590ac6650296ea9c3b935009e79c446280d9bf1010b8e66cdda9f8970d9, + 0x1d14af4f4b54f0c9398e051d2a223193c78997d591a639109818b8cdd02f556c, + 0x22a747877bd35dcb97520a0f4a812c7b78702bad181237c01a05fee842840e4d, + 0x2eafe1740ca67f80d8ae595e84c17039a0560bcb9628b084a97d9ff4afaf6b2, + 0x1dba84e994a54a21666def22befb81abf49fec76c43c3f20da9043c9874ef2d8, + 0x137b47cf2f3d3afc02f3469e9d165e49a212ac255691a1bd3565bce046fcf153, + 0x1eeb1a0edc33a3e69b8445581ee8f0ddf84748fd901547d49440c863ca10caea, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x3e5726f2b2c60906deb00a314337a9c6e4eee70497a4a953ea206d200db8d69, + 0x528d0374310dd042d5f80b2e720b61c4200539fd1e1a23ee1f8f347041af0db, + 0x1da41de720a61ccf6e3b9b97ca36d7439da12c92549a11d238475e05f9037a03, + 0x21c1d92ba962ab12631e4f710fc9b066c369ef4aed709fd5f6992f57be251b99, + 0x2ebcb6f494b7d06a34d2d097c0f46ef929646c529f6efca0edeae7e733b0278d, + 0x26ba18bcbe43ee1a2ae6e1b4dd89151ec17e1341839b94e4b2bfbd70761aaf49, + 0xf05d9b39c0b9b3ca177ee5a8b12de457d00643d5a668a8fb30d6cba0266ae31, + 0xdbb12012ec467271d189184d086eacb530c1bc906895850bc80af72eb6e49a4, + 0x1e3d63755488479f0502c34e097c74fed1926b613e979d53a5353ea959ee6c9f, + 0x2939fe43f4690de6ecc251b7cbfffca082fdf3c841d5ec1aa77de64016d23c0d, + 0x29b304c4af9503a5a1ed74cfb37c9e98235404a851e915f9b476f96cf97208e9, + 0x17f58faffdddb92894ca7cdad4cd379da8c174076a250c3a69441d649ce04bc6, + 0x191456fee87886a7ae3d41901a05e755d8a3cc2a2519cc011a80724d430e918a, + 0x4301fbb26093e59eb5818971467c137eb7633a00e8d1f51856f2e38596f3d2f, + 0x127fe9f3329bc33759114950d8afe484a98e33011da6e40a41dc1f4ca2ce87a6, + 0x201ad991da475d146d85daa85c5ca3d2d9ca48ff7886b06e37dbacfb7ef69664, + 0x24a3d85006e0ccdd3d6fc62623fc5b36b1827ad57f7511a9677cc36327cebe65, + 0x273193d9b2986767b8934849938c7d1157ebc32578efcc7528d9a6a18a354953, + 0x2bb64a3b825a61f6c8b577993aa63ac00659221cafe92405be881026da729676, + 0xf656e73593dd090547fb5b3b8361d172c93f94a334e5feddc059fd03890690e, + 0x2889c18fa2eb572d474b6eee810b750942586f2792b146f455a023b89542d353, + 0x10ed5f7f60bab5b473285acbd59f0e3dd299f6d2d1e6412322ebf9378f4aa031, + 0x94d0f2d2dac4b549a1ac6b1e112ecb6e9eb337c0086cb2c39c5b98a180391cc, + 0x1b6950296c9a98930d2acc173d41e4788e70e42e3f568a97daa0fb7ad8d2eeb9, + 0x227c2f6979d9ca34ed1716207f3d70e78b9b76b1fdbf3ea97ae4b54826190e21, + 0x33ee70ee09fc264ff1cfa9060778cf77b725d24c55967846f6aeb468189f68e, + 0x103ab98622a6dd1bd90094a3b69b635873a4bfb0b1645964b8d03390192a264a, + 0x46f5bb0ba2b9a8cc19af50bd1fe9d3e73e4df3036ee569beef19fb47bba174e, + 0x1955685f6f6f936a887f4892fd66ae962f38fec2286788bd246f7eca45b5d7f3, + 0x7eaa9de669ef1442dc6d616ec080d6c921f95e73b87b7c3752782d7846d5a16, + 0x1103c98bc60cb276ac254178b668e743b6793de46309ff72291767e697516522, + 0x14e1141e0163ad2a79522578c5025149d4ad0b484ea0837c427ffd798b5c211c, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x4b913e824903a4b78ffbfa9043117402f816d24b695be147d26fb633ace8fb6, + 0x11b959c95a4da45d9da05602f07e696b8ac0ce6781702a1368d807d21eaab72f, + 0x1fbfc86fc58e1fa4032309165184ac8b6dc81dc1f81c09ff100758347243f289, + 0xfa7865327aef8246f45ac73dba9666a853fa8e71e1edc2409647207922a9041, + 0x3020170de7b6e86b2b0fcd04439ebdaaa8ce01089600b801945dded0c906d83d, + 0x10e72d8e4629ac7c8fffddca3f8374759040f8f61e1b2419cf266255d68496d3, + 0x5e90f1892363b99161345ab49317e3792eb9a536f473e85fa47480b90dd2a86, + 0x240e190d0b92f9aa7cd7bce008719c3f8d5fff587df3958c85f5a1286288f63, + 0x16e841b2ee682513db27e23b983f5fabbe6ad3a3d44303962910302eaf30840f, + 0x8a397b575fb86fad288ceb48f43315d70399c8bd9cf4af25faead935d02277a, + 0x2edad52145b10b3d0bcbd0216574b52cc2b442f9308ab528a018a78ae97067f1, + 0x1caca2ec3c3d6617fefbe6901c4252ec01ec7cdda757bdbd5f9cc62e911cda61, + 0x157303e9fe11497049ecf530db42fea5c87d7b14cc153120babb743935f30de0, + 0x20d93803a35f06d76ab5daeec28e4591d0066271d84edf26660e0350d30a9049, + 0x970dae33627a299a9cbf049505d94ce6cd1256c80a6322ad47479448bc808a2, + 0x178b6678bfc5c1d9fad6fa7aea247cb6b4facffbd49fd846c64f1411b2c2f6b0, + 0x6503b98a6cc525bd286b56e7ec81ab36835c969d4101ac249d3dd65834fd99c, + 0x21218ec0a783dc924ae7d9f38260750f0a0e039a4004cc095d5bb88e1f9be771, + 0xc0289c9220673997f0393267b29ab048761034a16f6b6e076b063ec6031846d, + 0x1984f03779ff4d9b4ccfd87d23700f204b38c3a606b0279327ca81ff9560b48d, + 0x17aa6042676f383383262058e28ab7c70d3d19b4f8ad4f54a43869e037470258, + 0x2ee1b009aa9a1ba5894110394a79e739754d9f2356ccf9293b2d851ddb6a6c52, + 0x22a586eb8ef3b8257479bca2d919afc56fd0846dbff4f3a9db9e42e4334b8727, + 0x643b1de630b4b9a250b0eb1857c4323bce1701afdb02ff2c6537a04847ac5b4, + 0x125bab28f5eb5c15dc0b3e9ce2b1e6bb246ebc56c44fe9943dc1ea4915830033, + 0x1bc10af70f7125d85f34ad4ef6e7347eeba2a11321da19894c5f826880d770ad, + 0xf6baa6289cf76db86d915ac19af0535773157e39b5423b43b1f3d0df2a4ef5c, + 0x2e80ef76053f6d815f5a779fba74e9b03bf8dbb8a19d40550c519a35f391301c, + 0x31efdb5d245fd16283ceaab1fb5d4ac1cd08918c0c22265f7f114a9ef22058a, + 0x25efb8eac91f3ab3d77ea8ef523c86fa555516d32798397a6ad00622095b9b0, + 0x14cdcee9150e86793e59fd2690a2aa102c2ec7f78d1da286826a37068c8859b5, + 0x101320abf4ad5bfdd7bf37fd1b5e5afa8f1b472c02e062a7058780fc215396c4, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x4d0659feee688cc4dbaaea4f05b259f7614cf5a5d970087016cb2f2eb343bf4, + 0x291dcb25510a3655066e860ade461e23fa4f89bc26f523b65b88aad5a753623c, + 0x1c40b5589a51a5bc3e746f93c18ee86f51331e8da3a246909b6a3063393a1b6e, + 0x50535d58a6b20676d9dde187a15c9676781eb6c1e46159f9e63d7db750c6410, + 0x1532765d3af5aad33c7cae523592894cf354ad9890479d662ce3cd51721178c1, + 0x8a6818b3d448d43c1b5ef357488c00883e342690a21d3fed21f7d62142dd589, + 0x17db4c5c59ff1ade79c01c45dbc7b6134c929ca5292cd7893a016573e7696756, + 0x2a7e1f2d365ce9b5abd3eeaf983c6f6434cdba5ea59222f6bd3a5d3ecd763f5a, + 0x6261e5b4d7188ac9e84d341f1152a4518f88d3e701ed5bfd7110577ce1dfa8f, + 0x199c5a8f0703767fe32daa280419f8c6793bb0888ecdfcbb4eb16332fbc028a9, + 0x13388d9d87929845924e078243a8d7e2476d77ccf84f1c05f7fb7c7da371bdee, + 0x7d044bf7a4fd698a6757c186c08d7c39c2083c8cbc5be29964e481592ee6684, + 0x283cd95f4743d216af04c17591b192367280dd2440ef47349a8f384f63887cd8, + 0x1356391f7516db1ad0481ebffa73034416caa2362bd2612a9f42034e35e93e27, + 0x26fd7e1f6d657b1bd8333e3f9b548f54941b9d13830bc88b8210e5b359b00f68, + 0x27ec948ca2028850a977addd6a9cccc697404d4d4b47eaadb54558c57435f916, + 0x27529d815efdab4fa4f21829ba3103982ab79e6052fa863044394fb5fc8d5dc7, + 0x1dce3f61f34639eefa0a344fea750a5751da0695e577434f20a38658cee96f09, + 0x917c97d46d5b4ff89b5cce4bd785c4b68f38c53beae9cec7e8ce31f7b11ab5e, + 0x1f389f75cde06c7ca3105a2b5769cf3915292ebb44e5819229fe3f33ff11d03a, + 0x2d9aac1c72b0a36a067ec7776c0ce2138eed3e90c3c381d13b28c43f297ff300, + 0xb8f7a8e4c0d2d5757c501e44a51e5f5160a01440281ebd4479b858614cfc09d, + 0xaa15536df2ec5905877e2ebf9d07d3763a3f94e9b4deb5c6639bd89efb86aca, + 0xb03dd77a7424fa8d945440f077f848e4137323442e11e1b4a2efe97df3214ae, + 0x70898a71952afad3ef0062e8420e92d94fa7bddc55beb355dcd1d3526f538d2, + 0x29d5413ba2416a2db49c14b165cb247362821494d738b57897a0bbe6cb53a287, + 0x7f3f807872bb8ec72dd2ccb223407a19c5b64e086cdb0c38a7b92458c5f7c8d, + 0x2f69330924f5ca89e8ea41b0334796a9961df24ad0abaef5106d89963a038f0a, + 0x2abdcf1940bf24e67ab4c8c0942df7d3440d04359da428541b0f128f6f53184e, + 0x209de37635d57f9ff0ea8a6be7cec5c70d701156bb34e25c0948c7090b319ec1, + 0x79b485de26ad58268a3b1bd5cdf3a1dbce291e7e30a1d645a7268d340a8f1f, + 0x2da731b7942de735663698b5d20570402d266df448d8a80110557643a906ba3f, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x2c8f848a56c338afe1290f12b67b57d00ff8e974e804ac53b174ea42c9970efd, + 0x2d02f17717bf0db48ac36ad0a19e621cbf73b049364d945ad2a962d481001430, + 0x2150b09c7e10ab5208e632f8dfd30bc323807c5c6b122a6783b9fe5458a859c8, + 0x5b10ef00e618a270ddc6f313e86197af2bb111ec623f2964518938e4d1ab8ce, + 0x813aef08c1ab8116f2ed8caa7eac00762afad0fcf0fed79077845b2b81888a3, + 0x217798429df3f4efe0b8010a3305f618cfa40b31226a7f01aacf05750f85e308, + 0x13dddd98f07da3c85a8a7e584a541a3d1c30131e58fd19a79d3583e1eab08db9, + 0x200c75e95d154cd5d9f42b940fd7090764594e0179db56e462c80da1b57e0826, + 0x24c60aa77eec80da564202803e367806e84056ea84571e7702e708eff20350bc, + 0x2008060f910cd57bd018a7fe79edc508e11897199106323a04369c0b2f110193, + 0x154b1730e35711d6b5e0596a7e9fdf40a369c96e9889573772e35153780d06a5, + 0x20b48f4a5019ab0f0229c8613c44f40d6ca7ff80ebc6bd6f4f595947c9e3e9a6, + 0x8da6678cb4513c79e70618c7f6a247376292a28f4b8a26d7b22cfe89262422f, + 0x1e32944ecb0c8e538be8b702f45748cbd910c621ba8c0462a03a6d536e8f3cf8, + 0x130383065e342214003bef6cd7ac224dfc22a799b13a089cefed9c8872c056c4, + 0x2bb1e946f9019e0f0a3a6f31c54d13d900e95b92657fb49a0bb1d8b085aa7bdc, + 0x12c6706724626b4a2511d5ef4cdc22e569da5743363f598b0985da3f74ebcc66, + 0x105f4876b371512fdd868e75e02332cb49f228f7f6c3ce9012fca57b9587fda7, + 0x1ecdf6fcce9eea60179494be5317b761a337f5c1eea7d4bd7b36c4b136ba893c, + 0x9cd2ef6d45dbbca0dc657384ddb563f367042010debc24bf026a4b9c59f0da7, + 0x254ac6855d05046745889295c485aa0d141421c2e7e46907c6ae60a50ee2f8ba, + 0xa99c054b9a38bbe19930906e64c1126c9f0aaeb16ab6c33d1e0e29418edcca4, + 0x220b4016fade57782896ac3ac88e5c69dca5e58f1d6ebe25f7caee67371b85a4, + 0xb1979da1c048f6ef5e0232ef793f134dbb2a9e2c8f83a710944e1ccbdb08da5, + 0x2eef2d924b88414b5f89ffa9dfd4b62047a12d0e08118d0d39a1a1fa99dd91e5, + 0x126ae3d2dcacca892ec8b9b2338953d3bd2a0b341b7ed5986138dae14b6bab77, + 0x19e7c32cf6e235f95e2ff6e9537b23f8fb2ef50b5a1f734eb757352a74eaf498, + 0x2f9bcb5e0cd5660350ea6151e4a514ac84dc6064adac393e9bc4daa628297fc6, + 0x1aa496f96372589a74cdb1523691b1fd072bd35560d30b8c48109d86c7776b75, + 0x2ea5a8d0da13d3a0051a7f1b186b35d6f0eb986a2769aee850d3945ee2409439, + 0xa633c25ff6bbbd07e365ee018c76dc3be74b40619892f106cdecf3cc4ff8372, + 0xf412148158955c69a302b9b42e5fedb330d5ab4a6cf31b25d4fd1d8135c9900, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x2f2ed1486990b9431be8fc1485b6eac869fef5cd8fd2a94c7d4d5da7e496db12, + 0xd5140886c23f2671e698c3733a296be1f4ecb97f7520b027d906189fd755860, + 0xd1b9427080a9865543b6fbe5502899198b228d02f2ee9287bd1bc1b71680370, + 0x25f14784419e0d86eba62a9cf2cb22f063caeca529be18af1fa084c73287c3fd, + 0x1cdf7679aeb1784cd81e69e41807377671163372ca50143e5b30eef5a31abea9, + 0x7abd6f3a4c53c8d3aefe49b257b3e7c0aace886107a6168a9f93e33733c1224, + 0x198e8dde62e4b800e4a5081cc43fffce5ba02ddb349795a9ba8d2ca36eaeceff, + 0x2a10fcbbc185ff7ae275115f56640a9ab88dfee8d2f371e21fade31ff9e7d249, + 0x3f74e702559a149c3ccb5dd839b3f80ce100c26671929236a4d703c6e53d53b, + 0x1e9cd241f96559366079809b034d98dc345a4814a7e947e17b41a19b4a119b75, + 0x7640b3b48b2cec9061c87ce4740d281ccaea62d865d0b3da726ffcd67d2d426, + 0xf224f2a3eeb002452e25fa54b360804dc9dd1a065655a31230e91a1f7896eda, + 0x296b25652ffb82041356634b505aec0d11bc8ffeab06b6ee76f97d3e90e11316, + 0x24b1e852a6168ca05bfe0e823f4a984b3b99ed9bf3f651cdd3ca31a2d93a21e9, + 0x1170380f35b0c131ca5d2ea71f42fed8b3caefc4ae2ddb42ffce4c72df975521, + 0x2a21146458a9b5cd2232544ec84b9c2e3c07b75cbc4a2e27f1458995a5cf7665, + 0x2cf40c380da1e84026e58bca73fc8821a6956f7866bbc6591330c7b0876d1e48, + 0xa4e5a8c25c79291e6e7906a8bb9897dbd91567061abbe4eb2b80f7e591abad5, + 0x219cccac1ff828ee50d9413629c80b870ed290d5b2197a0b9db61960913eb29e, + 0x18a4a743a05448844b46abe129001953306236ecccce1b8c885e712084ae40d9, + 0x23f5c0a65d6d3f4b017a68d513413e702ab2195a12d3007589a7ad4230792a99, + 0x248649d22bbd35db3c317fb6f1e20944adf80720fd085394e606fe58c93b227e, + 0x1da45cba740db4b50fc4b2571e40590ad20c725af7393d2e2096f782ca8451b0, + 0x59c9894d39a728ce35f569c8b59acff2a98903a73d6935236ac6ab8bb65e7d7, + 0x137afc1da2a1dd16e4049c3e23951f23e5324e12fe046652beb4cda449a21cd3, + 0x1c67f00b6836091d6642592a40c27b9b875f51cc9eb804221130d3f883d29765, + 0xbeacd79129b9b6c793b29450ce6458c86475951ca6f0941ffaaa73622709bc, + 0x1d7194f0b9970b103e3d4bd5a46b5054ab45bd42f537324cb6fec3c672cd5f0a, + 0x38c741f8607a78f328725ad18d2baf8642c005429c53f5b7f9b8be51c8a507b, + 0x1d32ee86d0a10d113b8400a3301ee9df0b4f9666c4c962073bab7f02f0c55e7, + 0xec78e82ba602f4ab67e987ff3eb4562b0818c481c6e8febf4a4a157ecea15a, + 0x2e0de6aecd184a6d47a6a7ae42b76346f15f98bc4f0f68ee1a55929939a7842a, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x93d13cd9b043a5b6a5acb2de0bc54de68b71c88e8d61c2c3c3bd52febfab688, + 0x80fab4e2e36da9276e4610197b32d28ecff28dcf155f5db596037e41a2888ae, + 0x7d2d245764c856372297c49ff64365a99137acfa81041932b4324877e33d9b6, + 0xab6a369f3d47ab68ba9add80b46b610d39531e22a75a30df3f32f4bede18a73, + 0x7a683cd3c4e68622283858eff121cf3a5ec2cb48763c290a4984f7e75a86139, + 0x1fd44c84d9e254b1c6e60cb8c1682f5e78a5c9f9cc88e53b8bd1d8e9bf20638f, + 0x2ac2bdddae01ecad6c097ec139f7d442b7a5c48c491c0a83a006e9dd1c44c9b9, + 0x24a03800df78ab8dac3b172aba870efde663176598e2489fe1371f1b8fd9ce09, + 0x12e453652194ddc8ff5f249f04214d2e0571ae46eda251ed66c9de6f412e08bf, + 0x592a798f42fe58f27f503f2ac512286fc9a0271edbbb43d263358697b731668, + 0xa92a96d55b5e02c8fe846f8cfef92f2243cbd535b6b3c0e44d3c6fcafc01963, + 0x2f43e2c6e8af0638e163e2f4d34aadf2debdb3a5df531296ee2bc5dfd2aa8d41, + 0x3117e986130d1c25eed39ddb3e1e4afef783e031d60bc17e0681288f2d910ca, + 0x25cafbb434aee06df5f90241702018c6fe677ba0bfac46f6b5b8314ef8f5d407, + 0x28b797a499c2b1082b6a674ac02ef5cc2440d6eee1ea1be1ed5a527a6e5ccc95, + 0x23bf393a579394003e64cc399506807aa684314a29992e3bbb3b67fee7f50e24, + 0x28656564d677d58df440de43115089a1790d1aa95183b390349688e8c8aa3e32, + 0x241a69500f5e134c993252fe1052c9cd7e235d501b3b2343ee0e4857e2d0209, + 0x3744e02ce85e599147162a48b8095c61ef582bd1b4027649a4b706e9d99f355, + 0x59b7a17e1c0e884def789033664d88ba112980ee5d7ce4320f4b59092a493ea, + 0x2a6efd68e5dabc912ec2b5f7814e6e1b7b8893acd10e93d8e88af5cece9e433f, + 0x20826fe980809fbe57d7af7d60262abd566278d70e03c7dbd24798c9c991ce5b, + 0x181e562d37922bad979ac96f562011311f09187613e196398d3cea64e7fcc7ca, + 0x1c4e70fbd4c9e09d3b341e1a9ff87d088e6bc4d88a5cb20bc39a2216e9a2e78b, + 0x170c6ee37a8fae5a940388717c1ed8237f9c2c51e0771fe1c5114f020720b1c2, + 0x68712f00eae99b3109162c3a1c8a6b836031f7b3fea61477d274fc39cf53b53, + 0x1937a02e7c8e39d7f3a88a82c38dc1b2b6a7f4326ceaf7aca3f8a2fd163f1388, + 0x8b99b6b338adaaec87f0f4e4106e1a76938bdcb0b55d66b9af257f46da5c6de, + 0x136d1108a8d4bcea80090baee33556f59dcf26a8365b6f657a6625029b73f354, + 0x2d8a56738cf6dc4785fdbc68f440fa3b2d4de0d5ab6d2d7c6c11649ec2e4da65, + 0x27f16feaf6fe1525cd67eef458297d1696dc45bf5f8f1ea18e17801399f3ca4f, + 0x340f8d664a1afe4fbd06793842133cd43ee4e0b2173405efa10445f43a1836a, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x14ad435cf9a9f41fbfaa62698ea2b01d778fa6ad3e6d75d628e535cec66f6183, + 0x229f1484514708285cb6c866fab78878bbc39aec362b9db5e258c101a7382806, + 0x55104ec0dfbeb910aa081864bd59497cfe65acc2091c2cc675ebb7c7b2a318f, + 0xd75b1f18144371f5a0de32dc9124230448f17584ef93ed84300270b6ef3d4cf, + 0xa1da3a581de2337e823d10c00af64ed8152a3375abc7c8e038592893e02f879, + 0x15ce644c9c753f2b508595d24c0905b3712411f8bd78c1dddb60a61e3574f50a, + 0x249251029b3a7d83a4442ef27a2f3bca3edbdfca88c33095f557cececa23fa7, + 0x2190e0657b7f4592ed17884e486aa0983f96d05d497f12d9bb08fcba65e146a2, + 0x18e7e7d031ea4b865475eca9cfa2f156d2bebd8f57c6c66630f2b3e9bdf3aa1b, + 0xc23dd68ce397790fa9d48e22108072ad02df0f80f684926ffa4b66e8871b1ee, + 0x1346be394582712818b12e409e1a2f80f258be08e8f5273e4223048a6ec68596, + 0x227413a36ae6153e431c4dc592eeb597ad18b0a119f1c644d8741c5d1302bf5d, + 0xb0ae3714255eb9abec3c60d3e9d3852c33db950e87bc17818ff0242955aa594, + 0x1f65fc46116912553c6c9bde179a09288bc29ab001fa7f58b2b36e10049da7a1, + 0x1c35284edba1cd391d618754b17f642eebed4127382b82f7c28b2e70a8f70d40, + 0x1080a3fde0e42ad7dd86de041cab7fdd025951641942374c1abcf62626f48a3, + 0x1428eb2a1f2d91707f546af2e0a14fd6f11eee2ca12eff4d36634a08a2501d8b, + 0x33503c434487731d754e92d6e8ce327ceecbae661711045060e165ed284fd29, + 0x137a5d67d8c2d7d92f83451a20d0698f3ec69d9bedca8fdf23e4cc761c30895c, + 0x33ff54a0543a859d10d23919d9353eb1c7df8c37cf77d71c033427f8785ef7f, + 0x2ef45d95ea7a2a6ebf7cd42d1bb3eede45cceeb3c13124fe3e4bf9bd43919aef, + 0x1503cc2c9f6869e97c3f356fc0888cee11b122576b7ac19e53e22e64541b864c, + 0x13b7e00bb153de07cecadd2525f0400ec81c7f3f01b2f8c0d4d923626f5074db, + 0x1560e82a44438c75cbe5e7bf4242e9b318e84d0f70c247b4941214a54e2ecbdd, + 0x16e6cbda059ea98cd388bc97b407a150d03cbc54db44314acd2fdcb856ed59ea, + 0x224e1109c1eb450d665db9aa5a324754e9de0f3645c36a4f42c06525a6a02f17, + 0x1fae1e95cc145b1b611ae98352921e5621563019bcec54ef9aa0a006c5ca9c0f, + 0x29c2c9268343afc2448493205d8efe3ca12ff4ba45195e125b1a585b3c15362c, + 0x1745aa01a6decfbf4742ca4eb4fb46936c593a8fbb1753e4b1bd8ac26107dcb6, + 0x2b8e149f0ad40ad21c74ba35026dddbf89dce7c2227dfcfc94a55130b282348d, + 0x21eb20b36f906d2693f37e6b25f10a251dae88ee9e5bed97d0bfea9d95eb6155, + 0x2e2d367ebd03ab9e863a272a0cb40240222f32d1ef3f7a79de99160236cde439, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x2e142d51bb3c63e11687bea27b03d2c1f47ff4617dcf1784fcb06139718bdc, + 0x2f9a0d8d22bb17dc91fb40146ab611c24fd7aff2721139eebc67f103abaa8abe, + 0x1cd3446fe74bd3cf4e8790869ca502315e2cb5e61bfd569b79e4bceba7dd18c5, + 0x4882cdf369a6b624cdcdf140521e2f5d4f056d5be8938eafdab02b2b6b28365, + 0xdaabd96d080089cc09b753a113f03c79cddb879fcd4fe92f64086af355320af, + 0x11fada765d840371159d393d9383846a758452164778b156ad07d2f97b1c81d5, + 0xf1bb77c65687d588f3afdd2e81ed31b0b14e7a6b34b3f194013310a430e72ff, + 0x1b6cbbda2504b6c7157070cab18a64cfa67b25174430ae34f88f41d06a5df61c, + 0x2caadb9815edd0b00891c8952f439654bff61c480d34304a559b2ee106e8555b, + 0x29d647c2ff17d90d8ac500cd862bc7cf3bcd63cae45d13ba2b2f5bd819cdf00a, + 0xf9577281c0113be755056c5a200c03b651cd175ef4c1c51526a262db78b6012, + 0x1c7a4104b1eb344a9d10ae34fe9f0d9b944b1f27b9ad60e78d076f14b1579dd1, + 0x28833764307c07236b8d64f1e872a15f26b93cbaa63062c5728b6a6126a2b3d8, + 0x245ff91d36df9a9301cc998a11ea027605aea0dac30a20a32fc5b9546ff5f22d, + 0x9c3b8ddc3c8a83b3dbc098cf547b51d197fa16571ca6ce1bfa603f23474188b, + 0x23123b0f1690f3c61a3d7877f26f33c4c26feb8579966b878f9313f2a7bb0724, + 0x2f42ef2f174748c44f63767b95d5e66b2554f75a164e00833336a9d990fe4279, + 0x1d8000747e03e93c37fe21b889bdbefdc234baa290a68aba51d3517a260e6944, + 0x103f779b0899d4250da3fc25d27e0444a18498ffc0bf0ce7ad7fb106ba311a18, + 0x7f4c9eacabf180b840cc30448d4926692e4a4d4b6c970e0e818c5e11d7a984b, + 0x17e5e03ecf01408a520c1c5bb8e1a4477b011178aec18404e414554fd78da779, + 0x116cd1a5deb317ac2200d91721cb4c794fd1bdb9e04c80d222b2ae77cdfe0412, + 0x259847fcd69413a8b787a452950cb9970981ce86ace933112f205b18b20af1ac, + 0x7244b4174980899193f70318c4c09239a011431b1f0bd3f5c79e8e36347e52c, + 0x27a6122c5882996b8b87923a9b66a2a4970c9844cd3034e847fecd91d6b13fcc, + 0x2c0bef6885d9a4d76f43a29ddde616fa8174cd24ab58d4dc707ba5f924739c41, + 0x2d0cd48e3952f4d64e4f37477e2c0ac65fcb78682dcd8fa4c4e9d744c1205af9, + 0x8d8edc9e81dfba6cd7305c1bfe73f42d7252dbb19889e125c5c9aef137804c7, + 0x20860a731c157ac1b7ad854b3b851d0c739f111995a8122aaa7147ce61355a1b, + 0x2b242cf51e3fc841f925153bac6ae94b84c0e4839da70c3639ae554a2ffb538b, + 0x71642f8fb008ca366c562ce0755bd0edc2cb3b1851d91871f7c217c6c17b812, + 0x10628390eb8c9489dd00520c4d1f3bcb7917ee849eaec5d03d662192e40e4c05, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x2c657cf556552ac00d3c6a312f941c21752d80f6fb971f6f237b9f067f55ef50, + 0x2274e5afd41f484d4bb846c23f4d15eec892ed12abfc57aadc71c431dec0ec94, + 0x21e3eead8292384cd4e9ab89698674acf899b310c4fb1474a50ed68ab15ee79b, + 0x275b0e09088d1a143b3834ed09babfca45694301eb39680c7e01456918596140, + 0x129eae0d0efd6629f2846e2659d11190f995e7f7976dba6706d5275f8ae42e2b, + 0x23c3296abead985b298d2f7359d6fc6b66428469efef7f33cce72f7d261e200e, + 0x120eb3949a1bc6dadb99eb797c5089f6c81b8489e8d2fdb648759f9b7d950c92, + 0x277b28338565bebe62ad1128dfd277e71dcc0f5cbf15884f3f4431aaa022ae2c, + 0x4f36e389ff9ebb3bcd6810d8b233c0cccd2d0a9a86f0c6eced01bccdf453a94, + 0x2548fa65475658066e282e043fb7e3a2e5916ad635f27977d292b0ad3ef3e4e5, + 0x4565577c55373eed95c9aaf5c9d202c270ce37dc1a1a2232c856f88dff9364f, + 0x233e72784c11da8ade7b9f172935e44a748c8cb94959122f9da6c7ed65a6cf10, + 0x158b72f3087e0267336e27fc3921ee3a3a534b925fecb827ca25f7dc77523334, + 0x15c260f3c32020be493ac81d6969ece9c8e8aab39cb11ad8c69bd97516886522, + 0x2396362d574b22bf4f2b162ddb6879ae4aee803609c5af81b0cc96e1dd77fb69, + 0x2d0bdfbd9147195907ed3568ae8309feb349fdff397c36b567099ae14a3770ff, + 0x2cd487c6239575748dce9a1b1e9cbaaaa9df4bdbbfa64f68ab6ed9f9685898ec, + 0x1e73a3297684b098cfd3e270ec4299fc88d970a924596014e9a7f602ee9b081b, + 0x248862b26667bf9e71255c8473c4d4f498bf02d6fe6c554e9d6a8194b443c7b1, + 0x12daded6502d15cc7ccfd3998e01c39851611629fd9a6562f628ef83c7910b8d, + 0x15e998f00cc4dd24ff559089cd43bec5566f2505b8136c5ab74d9a426d875c75, + 0x217fa23d5b14a9ffa837fcc744c4a64fd13e6fe162777fc834bf119df306c8c7, + 0xcadcf98c06aba7c6f354cd05bb28857f3798b83111652ddda6e2f8fad6a0518, + 0x1c5c0906f02d4a6e3fe315f26891dae1132436b3cfd048f897a2988abb14e005, + 0x8452c4131a7a4f5730e877519de1b927a02260f56ab0e7cf23dd41010093ced, + 0x72e4518998bb2aa7df1a094e4a1032a4f1651403a006aff7d8d3f8e0431b39a, + 0xab9888d29232bea4dcd77c9627693a4f292375d6ab81482eb0cd718adcc4752, + 0xfc2e5df60bb4a189253e73f07025b34dac9f8f6c215a26c53fa5b3b1482e105, + 0x50e82e90a419f91e690625c51ad3da156afca51ed13531b0e67a3b89385273b, + 0x2f88a4415d7e88cfd3cdf0a5b4bbc26b243319e20d0e4ce861a2f2a5042e93cb, + 0x1e10e776d5e15e0786cd5d0ef96d1ab332eb05773833ea20cd5a19891df8da96, + 0x17de64722cd216df23ac5fc20f4298bc5c23f17de82c80d361a1cc10c3f3b7a3, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x1b9c2c4eebbe7516481522714ccefbcf9f46b1d9acd32a7074f6e247ad6cc86c, + 0x1b40c39dbad124c570125eb0b2586ec99e260411e0dd871cff7869ec3864df9, + 0x33cd9b171a83f21a643c9db6174fdb0a12ed70e96e4dbcd7cd13888c4b3eb55, + 0x19cb8e0c054400347facfff66eacd97d794bd61b59323af411ad0fbe2f380942, + 0x26c218511f870b55f305e1787e4b19e1ab682b8c823153abf87d6b93d808e4d9, + 0x29e12c794848bfe525ab81ce659d2cf1111feb3fd7118f94e22a86b6f88b53cf, + 0x3a6658a834c4e3616dc5f917fa062d251c8ba4cccd09532eca0d77981b0170, + 0x168adabd67838fadbbf46c9d9716f71494ab077f42cacf9c45e489d342a3e15a, + 0x11742863039a6788df3464d2644c239b1929c3f16f43efaf505e2416f5e23a1c, + 0x126abad95e2b51fd989173eb24d170db35879d2ed95aeb53fc43f37b92e0da48, + 0x23c212335569ce5f39553eb328159fefbdba99ea37be97365fe8049e550c93da, + 0x2f4dd1170cd5681dd49cffa2b31105e7f1772c10277da6436208aa1a496c0ca3, + 0x1f1add5db460502e7d77a5abe06b5391bfd9363ec845f737ca6c072f46d26164, + 0xde4648c15ee1c296f4bbc50fcf033680afe8764c93b524d0c7f96a17c8fa0c1, + 0x2940f3f803b79a69ec13670c3bcef58b3aa6225c5ff1b9fd8bcf1ce7d9da83a9, + 0x6022a2c0e67a56ca21f209520eb78989c32443d6d66a659def8fb09e41dc3b, + 0x2614b22ed71c1ebf563048afad7b64934e51c6c1787f79d6cacb0cfa401692f3, + 0xae0351a3f38218d3f64682ea5b4bbd19c9da2312b6d66c98a4e5793f56037b6, + 0x2acb14246a8372f36e96bae26d0298d0dec2a8037325848540d092927b247af7, + 0x4ac1f3bf59ff8258755878919911219c901e45d368e485fd581702935e593b8, + 0x637c3722f5a87f3c148453456b4bd91dde864a8d689b73b12379558e5fe427, + 0x2ed10f87c57e6e4d78f31e18f1c7e9ee7c0b59117a6d034e2ead2aae114caa32, + 0x2db539eff29b1c4e93218c6e10e9552179fb7b03fc7308882fa9ada5a9eb4776, + 0xcaedc62eb88ea19a6ea5fde158da87c74f591099c56a110467fcbb2dcd21f79, + 0x485d5824b4d88b5c32a715605487a6b58ae93461b15110f2a7f71887069940e, + 0x20fa1c1846393fc776c5868c6eb0b841e64eaf613c2005ea361b317dabbca53e, + 0x2e17fb34208254172d03928de8c56b8cc29f87e29e8aef1f79b13bfb5e7ae90d, + 0x1d45f577db25f490276008376cf8b59a08f20d469d8676010f7f281d5cd1aeb1, + 0x48ea8cd9295a1a3e48cb22507e7237d0a6566b58e4747c0896fbefd7aa0c7c2, + 0x3059196428e054d558d0e6a091559ff419ddfeab8e2aa1ba796e98849098f404, + 0x1170eb002f68247115722d0638fcea7c2b7f70024953c733bc8cd94a86c23ca7, + 0x25fcb5f375ff3d5cc49ca2936b121d9591be3e09fc88efeea4cf90521aa04b97, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x23444707325fc7683a461c2dea2173d8472c0b5b13701b34b87203bffe8f4aa4, + 0x2b272e00da1d1d1d764b7da9384cd2efb8db8604c01b9f2b833a7c1520369e3b, + 0x17b59a35bca179afddf24993a2a28466862328d66cf18d77e8be5f950d7f957c, + 0x20460d5c7e4548772c619dbe8a220b477882005180887377c0ecb4b4c20ce625, + 0xd1346ae8fcfaefc96496235e8a4b6cac300a284f97be68f0a453c55569e2e1c, + 0x29d5c8e901d6f659e2c9b51f5da873c776a55de9fe0a95910c5893d9d64c180d, + 0x109297c57950d5ec34e371af14fe40615e26d74a4fd2562dbaf8b0cfc0da67b5, + 0xafa294b0b8973e74c6bcbcdf0953726679268df4b7ab3a0af0496d80f4e915a, + 0x1ccdae789483414efc596b7a74d20cc5af2de7595d53c80c6762e599c4c19918, + 0x7d80df4e972d5962e8447454033d912127d2930fd5229d1274aacb93ab35467, + 0x19e7ddd05077b3710fc6cf15a1746ff3f2ce7b0ad9355bdcc599e882881b7812, + 0x19c52a43b8a53bb146faf681e98fc8670800b6b9dde47ea38a849b82c1f17920, + 0x2ed2fd2f3a2f78c35d4ec54a41b9941d4040bf4f0766985c776b6726746efeb7, + 0x117e9b92ef305e1cecef90cb404f6b178b1d2c216e8c3bf650ad5b9f675a2446, + 0x27dbe49809655461a2940850aa8c41ce6dbd5221400a9dce49f9f3ff9b04dd57, + 0x8bc85ab2f7b9d3152fec37fd1c66ef688e2d71e325dba40eeed84dced4ea11, + 0x18550a78308e47e5ac75a3cd82d4389a37c6918ed42bffa89dd128c6b4cd6f53, + 0x22d06c4fb6f2b725a93cb9e97f08f466c2d2078953f43f4159bdafe3a9bbc2d2, + 0x1f3f2ff5ea4b6044d0d142c2850a8907dece24a9e7c508c09b3b7cbf1d2db33a, + 0x2985a2e4d66f1b2c18c3f647d444474d432fd597dc23671ccb3bf61c1351e990, + 0x177e8a83bcc683805e1af7e744206e05fc99f85b605b10f3f0867913ff45a521, + 0x97666874717688dba3d9546ff71cb3fa829d101f2bec9a191b5915ec120b658, + 0x15055d2177bd83ae6ef36e4f113f7a53fff218984f73588988acb7f890461698, + 0xe0197b38f1671c3fb6a078cb443ece122bfdd9f47486f3fc5ddcdafefdc9c5c, + 0x78b8c01a67c4e5cb15738416497b1d4b3d8fce7631cef919eb4a39015bb5b8e, + 0x26f58171d43f5d52535468f97f3f4a76a56d43bb0c8560ac98ad6fc409c6895b, + 0x2db3d892f554ae8b1b5819fbd4ae79f23a1f4627383656c93be2e3ff42f7e7c1, + 0x196b74fdd43c9fa4f77111911dced6856b397b19da47474fe1a8f0de62bc57fc, + 0x6238d5e3cdaa238c7670efd64dbcce481815965fdd55efa8ab1706d7a43aa38, + 0x22332a4ce6b7a223d45c777c7bdc960669e4a801b4a76b88b66d05039a53eea0, + 0x1f88fecb08e0101e470f5dcee2c8b846d2562f89cd27d92e6b00faacae30389f, + 0xc2ada53a5fcfb484d0a65c509305fa3f00db8a2f961d4515c149c85e677c8d4, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x1b28926cd83b4658afd2d9cfdfdce6b87aa9a072634889320a35cdcb9215e5b9, + 0x15d6448f76cf1b20262428f1e416bbd1af8630fb361d7f644639ad5b60d8f180, + 0x2af5dfa19ccc918de449d5d3b592e6d04d78bd796e6f07098e64630f2079d1c9, + 0x19d0ff169994b50d9ca896bffbd91f7f3b5c7d9ad51363fe5f0d2fb6185c2410, + 0x2755fe866df7e2d95bc2c8072e5402ca6f588b7f2734a2a54a4c519ca8297474, + 0x77a07258bfa21e2ac255e20a0d31d9a01cc85cad4bc02e6921a507ed5df4728, + 0x2ece250f68cd231dfbbdd343c367626f3cc413a32be08ebaf996dc8150003b5f, + 0x28d5f29f5df2a1b4fb5dc798dd2fb2d9099a9bb15e06933ccb382d3f712abc56, + 0x2af8e1fcf37dcf5f55699d9929ef5fc6505dfa79e061782ebc6a4bda3100fec5, + 0x1a391e08a393750010adbdfa7c621d382a29b98886d241cfe0c567bb37748954, + 0x1da3f4058cc2ce6554842588dafe5f4517661730183f0b99f9aeacabfc7acfcd, + 0x1e3b1802005fe7296d11441c07cbea61e32baf5484d40e315cb49e2063bb4942, + 0x1eca6728a58b997d09ac9d9eae05bcd86afaeec5800dfd73fb0280edc996d61b, + 0x2991dada2697975e05e0f74b4a69560557d34bef132ff73f3ecce501461f59c1, + 0x13a9e49e7875c154539d20cfef506535c91422054cd04aa195e12695a073487b, + 0xe97ef3325ec39935456c2a330435ef106d50b3d24a74e55045c58da778d2733, + 0x234fd4e50ddc42b1a40b1410ad7d9bbe27d21eb61d1b4ab05516422214059ee6, + 0xce167e175eb021fe2b91b0abb90c94667ea76c9a1139b958ecf14d64c617722, + 0x15871010759972a879b18a4d18bac0870013ee1f646d63f4bc63fcde2847ae87, + 0x168d81f62839ab0e29c4e03c0f570f9e44bd75eecde371611e98bac9a78c51cb, + 0x2c0c157479d4268e5a40179ab0a915072b91889b1eb06e1bb0e30c5936deac3b, + 0x2c1c6ea12c4f9343a80fd53d4169686705ffb51d3ff2766fd4c61f803e648e85, + 0x12c2c9b7086ab39752ea4a0afbd8703ba2ff66c309d48f404d7eb4edb90aadfa, + 0x16a90e916477870cb13cfc1ecfa73fe9365d36854efe87db94a2d8f019a3ee83, + 0x1e5674b6f90be35ef343540b191b0ee45707bdd34452407ad9035dd3bd282799, + 0x2daf0fbad1fe6737f7bca405e34dd0432a4bcd5acaaae29ddf9ed8ffc1f0c336, + 0x2908cd47730b9b031d14f778c53b64aec2838f3370f8832ac1fd7ab2d10a32e1, + 0x1385230fd1095a5c478a798071294b8a11c9805d10d4f27b670a868deff0a451, + 0x1d163c58cf48bb8e02eb3193cdfee3ef9c85133c14f87db1829663e74d10620a, + 0x2e557c38674c410f4d7c72ee1a36898f9c16ccbf5bf4709f49e1e727dffa2a55, + 0x1c05ef08c0686e237cccd7c9f7279e5abdbc39f7a27dda7238e73f37526346df, + 0x2527d4d7449be5d202aec33259a43c5daf25db035ba558b03308203a0e33f717, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x10a492ae5b487f258651a3aed0227cc02f6c7a8761586894c74e50b84ad8081a, + 0x2403d5c045640a3867d3fff22c33d5a7d4cc9c86fb7f746f0cfaa6cf0009165, + 0x2d5d1d7a9af2b5a434066ba829ad51a9d596c775d77dce9bb5e539df0869093d, + 0x9a863c700ddced174ab9a2f52feab6a6fc50d640f7cda128d3e0db7cc6d5421, + 0x2aab180f6e316fad89afe18cac953fe0795ad3b267d632d4192cdf7a7f09fb6f, + 0xd96040a550ca9da53410c291bb03f2597546be222c18ecc3ce1a6b934c9e79c, + 0x162f27f588a7684b059dcfe87e6f50d77e0b2b7c2a04d6b2bfea5e6677c07124, + 0xb923196444f67bb7b9a3549947da0d1d65c2d863062820159e7b8a15763fbe2, + 0x2004eab7ce64ce5a33d093bffdb3f5c8c062629a82df11c1b9d0237219653ab7, + 0x1227bf877742b79ae1f3f94f4a7d99e2ed3a6a9e531f224f865ef504a5bcaea0, + 0x20f776f86d93c05c559f42775c914befee8b6a77ce89e137ee9faf414a0985d7, + 0x172aa65c733a6035cda4bd931733ecb05f160dea5fac191c85b7f96c03c76ff, + 0x8be42f0fb8d0bd0918ae0c9a23d6c350992a03652a1443e10676ef0aab7758f, + 0x1fd0be6c49952151cd278ae5631d6760f0b7faa1da5cf1f86e88f04332962b0d, + 0xf9ac50342fd157a0cf0acac7bceaf4498140817dfb573e81bc6b455122abc7, + 0xcb3dfddba8d704f6abe9c8d4c31c36ba7aabd8b33866d5c34920a61a0971ca6, + 0xe770f3147cb0e321701d76e1090173d30171d6cb47618e96f0391cfe89a857c, + 0x737d887efe6fe8f9472901487cce5dd61e60b27b3a3987a5107cc0c747c73d3, + 0x1a385e2fdbacefe3fc505c0e8866ed36657ae93f963f4d8b9af435a98cc91fab, + 0x47765901d35e5b9c88c43dd5f4141cba4debe6bc675e49a08069b787252a3c1, + 0x1da4a4ede36f08e2b6f0000760e022e4c87b4828f5df067037e07ed0a3db70aa, + 0x847d2c6657d2fa009b736d83e33c9861b0192212fe8edd90dd9dfe16f52f861, + 0x3039ed5a92b2b6ac7e0dda476285292ccd649442508936442d4d3cc1d552383, + 0x77951dcf1d2ed93be5b91b720b5387db3a4097e55cc7781b69c27f5eeefe04, + 0xb585622b1f5eb8fdfcaad1c3cd7f944255a4618ebfc9f9dacf339e874df620a, + 0x1a2a7bbd62d97bb265d127d44fe34b17d9da8ee75813b5c51b9e16ee8dd7b402, + 0xdc48ec2dabd95e06d2987fd1824a959e084d4e62d1b2c5e503b33dbe6b30d02, + 0x290de95aae65845be12406a4585f7187d3d6528bf7daf00a84da01e8dfb69e1f, + 0xc017e46a4f39a1669a350ee495e7ad68562b222de7114a6c101adef47853293, + 0x2f0b5fb02d18a781e744403921d82e54c4919d1686d824bf4e62b2e4cc088cf9, + 0xe7e699b1dd9c60f0018d874e9364210eb920583d0d2d71567d38f4333bfa474, + 0x9472c6ed2b6494433a9319f2b093f2fd1923059b6002a6e896fee03e19546b8, + 0x196b76cefdcc7f6a54c71d40114a0bb82694c936f1573ac7ac1ea3fcce1fe938, + 0x2a8a40093e2bc9627fe39aa84ab78c1ce1265e8cbe28569136f8b83dbf1e1a0e, + 0x21d9b9f7094b3462aaa61148b272fba6556514dcb39cfb47b5414ac776944f82, + 0x22be02328bc62605ca6d890565b9726e83b9d8f925e702412edf291b777df027, + 0x27b5d7ddef018e17569d33d8c4e9003ae36382bb57caf96bb224b724cf237254, + 0x54ec141c594bace5c88a41767e82517f8dcd8e02dd54f8fdc1c7223d3614982, + 0x17f76454a7d3b049dc34c09012706560351dd12ff052187ba5228c9fd5abc646, + 0x189a082f5c10117ffb6b064329b31026c852cd41e01352e6c7b9d12686200598, + 0xc597daf1c2a8f602322f2796a1bca2aa3101cb8c9a876ee195a9bda90da5d5b, + 0x2ac2e1037357e29885d73882899652c5cdaf8560ae356bbdf7ded11c139dc663, + 0x6ca950f38af807cac3b6d74cb2937af0a2287576b78fddfd7200f06e66e5f22, + 0x736209bdf8c1ac643b8ecd0950d2bb4dcd8745be7c8cf64432da264fc4c6a33, + 0x1e96d9fd0f2db5bcee16ce782403a3a33acad70b237106686ad0bbd8bbc00d1f, + 0x2d7f5635e4b127aab06795499bb1a6c97c54806d79823ff7871e519f4081cc1c, + 0x1d8d18b18dd07bb89fe0c84a7740faed098c6a2b0cde5f426fb8c8b7643bf95c, + 0x28d51d4551904bbf04ec169bed853453358042ef76a08ea8d155f8677a051ccd, + 0x189be365face10b9a4183d6f21048d6c36ca9c28b0720c71d72ed529654aa624, + 0x130fc54477fd953377fc23abbd7a41be6764892a8787c759c1440fe0133c852d, + 0x2c9c91f48661771baeef6774578a78f69c355c8e907156fdf26db39d2446413f, + 0x1dec0bafa3e8190621e5e095ef751ea03c836dbb8045b2a73f8d397cfb815192, + 0xa5f52ad6ec4a8aa377d8dd2ae3aaf6eea0c68c63a1d034fbda67133ca0b85cb, + 0x20ab7394bfdab344cbb6f2123800a0e23508e2125bfe795ab4a767cecb4d9306, + 0x110ea322b0c26476c67bfa2c1b9d1713f93b3b9cf8320ce0dcd4b64288bda07a, + 0x54eabe6131681fa01fbc6dbf3e7d53595d0f8809987182142b890ac8af89cbe, + 0x224d811fbdef8ec0a006d376a019e57c93bd596213a07823b7d4abce1fd8e621, + 0xe691fca423128a7d4afcaa582b1a94799ba1f5d2a5d53bc2bba56bbecb227a1, + 0x189e279c92de0bab66707e6e6e310524e615cd4c6aacc665372a3b8e372d8ce6, + 0x1d9bcbbd17b93b1913d2f79cdf12844441237206f0294746d93f8e5bdceb4725, + 0x1179184635a9780ee1312dcc3d15c7ef042b18ae9409670e28c4c7f0fb9b608e, + 0xe48466182ae8333af1891a6aa19736741ed0680d57c931ede13fc07ae82e88b, + 0x1c9d56f71c2f22c44d3a8c17bf5b40452e05471f0b6dfe9ffe4725eb29f73464, + 0x2234546f5e8541e8f72ad794891950b32b1cd891cc66775c5b635961642e9c15, + 0x14c09d155c5d428198c234b553da338f227cbc12b0e42f2b9ce71563ee1495c0 + ] ) } diff --git a/noir_stdlib/src/hash/poseidon/bn254/perm.nr b/noir_stdlib/src/hash/poseidon/bn254/perm.nr index 890f54fdb3f..b7c022c5a00 100644 --- a/noir_stdlib/src/hash/poseidon/bn254/perm.nr +++ b/noir_stdlib/src/hash/poseidon/bn254/perm.nr @@ -1,6 +1,6 @@ // Instantiations of Poseidon permutation for the prime field of the same order as BN254 use crate::hash::poseidon::bn254::consts; -use crate::hash::poseidon::bn254::permute; +use crate::hash::poseidon::permute; use crate::hash::poseidon::PoseidonConfig; #[field(bn254)] From db561e229cfcb35f23205cbb7e41fcf5ece68ee5 Mon Sep 17 00:00:00 2001 From: jfecher Date: Tue, 28 May 2024 14:17:49 -0500 Subject: [PATCH 43/61] fix(experimental elaborator): Fix duplicate `resolve_type` on self type and don't leak a trait impl's generics (#5102) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description ## Problem\* Resolves ## Summary\* Fixes two issues: - Use cached `resolved_object_type` instead of re-resolving the self type in `declare_methods_on_struct` and `check_trait_impl_coherence`. This is needed to prevent duplicate errors, and in the later case, since generics are not added to scope to be able to re-resolve the object type at that point. - Fix a case when resolving trait impls that `self.generics` was not cleared afterward. ## Additional Context Down to 112 errors in the standard library now. The remaining errors are variants of: - "Duplicate definitions of \ found" - "Duplicate definitions of \ found" - looks to be only one case where there is a generic directly on a trait method. `fn hash(self, state: &mut H) where H: Hasher;` - "Expression type is ambiguous" - from the two turbofish cases that haven't been merged in this branch yet - "Expected type &mut _, found type H" - issues with auto-deref and trait methods possibly - "No matching impl found for ..." - trait solver issues ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> Co-authored-by: Maxim Vezenov Co-authored-by: Álvaro Rodríguez Co-authored-by: guipublic <47281315+guipublic@users.noreply.github.com> --- compiler/noirc_frontend/src/elaborator/mod.rs | 153 ++++++++---------- .../noirc_frontend/src/elaborator/traits.rs | 138 ++++++++-------- .../src/hir/def_collector/dc_crate.rs | 6 +- .../src/hir/def_collector/dc_mod.rs | 1 + 4 files changed, 135 insertions(+), 163 deletions(-) diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index 261a97ec3fb..903751331b3 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -223,8 +223,8 @@ impl<'context> Elaborator<'context> { // // These are resolved after trait impls so that struct methods are chosen // over trait methods if there are name conflicts. - for ((typ, module), impls) in &mut items.impls { - this.collect_impls(typ, *module, impls); + for ((_self_type, module), impls) in &mut items.impls { + this.collect_impls(*module, impls); } // We must wait to resolve non-literal globals until after we resolve structs since struct @@ -284,8 +284,6 @@ impl<'context> Elaborator<'context> { self.scopes.start_function(); self.current_item = Some(DependencyId::Function(id)); - // Check whether the function has globals in the local module and add them to the scope - self.resolve_local_globals(); self.trait_bounds = function.def.where_clause.clone(); if function.def.is_unconstrained { @@ -474,18 +472,6 @@ impl<'context> Elaborator<'context> { None } - fn resolve_local_globals(&mut self) { - let globals = vecmap(self.interner.get_all_globals(), |global| { - (global.id, global.local_id, global.ident.clone()) - }); - for (id, local_module_id, name) in globals { - if local_module_id == self.local_module { - let definition = DefinitionKind::Global(id); - self.add_global_variable_decl(name, definition); - } - } - } - /// TODO: This is currently only respected for generic free functions /// there's a bunch of other places where trait constraints can pop up fn resolve_trait_constraints( @@ -494,21 +480,20 @@ impl<'context> Elaborator<'context> { ) -> Vec { where_clause .iter() - .cloned() .filter_map(|constraint| self.resolve_trait_constraint(constraint)) .collect() } pub fn resolve_trait_constraint( &mut self, - constraint: UnresolvedTraitConstraint, + constraint: &UnresolvedTraitConstraint, ) -> Option { - let typ = self.resolve_type(constraint.typ); + let typ = self.resolve_type(constraint.typ.clone()); let trait_generics = - vecmap(constraint.trait_bound.trait_generics, |typ| self.resolve_type(typ)); + vecmap(&constraint.trait_bound.trait_generics, |typ| self.resolve_type(typ.clone())); let span = constraint.trait_bound.trait_path.span(); - let the_trait = self.lookup_trait_or_error(constraint.trait_bound.trait_path)?; + let the_trait = self.lookup_trait_or_error(constraint.trait_bound.trait_path.clone())?; let trait_id = the_trait.id; let expected_generics = the_trait.generics.len(); @@ -548,9 +533,6 @@ impl<'context> Elaborator<'context> { self.scopes.start_function(); self.current_item = Some(DependencyId::Function(func_id)); - // Check whether the function has globals in the local module and add them to the scope - self.resolve_local_globals(); - let location = Location::new(func.name_ident().span(), self.file); let id = self.interner.function_definition_id(func_id); let name_ident = HirIdent::non_trait_method(id, location); @@ -864,40 +846,69 @@ impl<'context> Elaborator<'context> { self.file = trait_impl.file_id; self.local_module = trait_impl.module_id; - let unresolved_type = trait_impl.object_type; - let self_type_span = unresolved_type.span; - let old_generics_length = self.generics.len(); self.generics = trait_impl.resolved_generics; + self.current_trait_impl = trait_impl.impl_id; - let trait_generics = - vecmap(&trait_impl.trait_generics, |generic| self.resolve_type(generic.clone())); + self.elaborate_functions(trait_impl.methods); - let self_type = trait_impl.resolved_object_type.unwrap_or(Type::Error); - let impl_id = - trait_impl.impl_id.expect("An impls' id should be set during define_function_metas"); + self.self_type = None; + self.current_trait_impl = None; + self.generics.clear(); + } - self.current_trait_impl = trait_impl.impl_id; + fn collect_impls( + &mut self, + module: LocalModuleId, + impls: &mut [(Vec, Span, UnresolvedFunctions)], + ) { + self.local_module = module; - let methods = trait_impl.methods.function_ids(); + for (generics, span, unresolved) in impls { + self.file = unresolved.file_id; + let old_generic_count = self.generics.len(); + self.add_generics(generics); + self.declare_methods_on_struct(false, unresolved, *span); + self.generics.truncate(old_generic_count); + } + } - self.elaborate_functions(trait_impl.methods); + fn collect_trait_impl(&mut self, trait_impl: &mut UnresolvedTraitImpl) { + self.local_module = trait_impl.module_id; + self.file = trait_impl.file_id; + trait_impl.trait_id = self.resolve_trait_by_path(trait_impl.trait_path.clone()); + + let self_type = trait_impl.methods.self_type.clone(); + let self_type = + self_type.expect("Expected struct type to be set before collect_trait_impl"); + + let self_type_span = trait_impl.object_type.span; if matches!(self_type, Type::MutableReference(_)) { let span = self_type_span.unwrap_or_else(|| trait_impl.trait_path.span()); self.push_err(DefCollectorErrorKind::MutableReferenceInTraitImpl { span }); } + assert!(trait_impl.trait_id.is_some()); if let Some(trait_id) = trait_impl.trait_id { + self.collect_trait_impl_methods(trait_id, trait_impl); + + let span = trait_impl.object_type.span.expect("All trait self types should have spans"); + self.generics = trait_impl.resolved_generics.clone(); + self.declare_methods_on_struct(true, &mut trait_impl.methods, span); + + let methods = trait_impl.methods.function_ids(); for func_id in &methods { self.interner.set_function_trait(*func_id, self_type.clone(), trait_id); } let where_clause = trait_impl .where_clause - .into_iter() + .iter() .flat_map(|item| self.resolve_trait_constraint(item)) .collect(); + let trait_generics = trait_impl.resolved_trait_generics.clone(); + let resolved_trait_impl = Shared::new(TraitImpl { ident: trait_impl.trait_path.last_segment().clone(), typ: self_type.clone(), @@ -914,7 +925,7 @@ impl<'context> Elaborator<'context> { self_type.clone(), trait_id, trait_generics, - impl_id, + trait_impl.impl_id.expect("impl_id should be set in define_function_metas"), generics, resolved_trait_impl, ) { @@ -931,45 +942,7 @@ impl<'context> Elaborator<'context> { } } - self.self_type = None; - self.current_trait_impl = None; - self.generics.truncate(old_generics_length); - } - - fn collect_impls( - &mut self, - self_type: &UnresolvedType, - module: LocalModuleId, - impls: &mut [(Vec, Span, UnresolvedFunctions)], - ) { - self.local_module = module; - - for (generics, span, unresolved) in impls { - self.file = unresolved.file_id; - self.recover_generics(|this| { - this.add_generics(generics); - this.declare_methods_on_struct(self_type, false, unresolved, *span); - }); - } - } - - fn collect_trait_impl(&mut self, trait_impl: &mut UnresolvedTraitImpl) { - self.local_module = trait_impl.module_id; - self.file = trait_impl.file_id; - trait_impl.trait_id = self.resolve_trait_by_path(trait_impl.trait_path.clone()); - - if let Some(trait_id) = trait_impl.trait_id { - self.collect_trait_impl_methods(trait_id, trait_impl); - - let span = trait_impl.object_type.span.expect("All trait self types should have spans"); - let object_type = &trait_impl.object_type; - - self.recover_generics(|this| { - this.add_generics(&trait_impl.generics); - trait_impl.resolved_generics = this.generics.clone(); - this.declare_methods_on_struct(object_type, true, &mut trait_impl.methods, span); - }); - } + self.generics.clear(); } fn get_module_mut(&mut self, module: ModuleId) -> &mut ModuleData { @@ -979,14 +952,13 @@ impl<'context> Elaborator<'context> { fn declare_methods_on_struct( &mut self, - self_type: &UnresolvedType, is_trait_impl: bool, functions: &mut UnresolvedFunctions, span: Span, ) { - let self_type = self.resolve_type(self_type.clone()); - - functions.self_type = Some(self_type.clone()); + let self_type = functions.self_type.as_ref(); + let self_type = + self_type.expect("Expected struct type to be set before declare_methods_on_struct"); let function_ids = functions.function_ids(); @@ -1016,11 +988,11 @@ impl<'context> Elaborator<'context> { } } - self.declare_struct_methods(&self_type, &function_ids); + self.declare_struct_methods(self_type, &function_ids); // We can define methods on primitive types only if we're in the stdlib - } else if !is_trait_impl && self_type != Type::Error { + } else if !is_trait_impl && *self_type != Type::Error { if self.crate_id.is_stdlib() { - self.declare_struct_methods(&self_type, &function_ids); + self.declare_struct_methods(self_type, &function_ids); } else { self.push_err(DefCollectorErrorKind::NonStructTypeInImpl { span }); } @@ -1145,8 +1117,8 @@ impl<'context> Elaborator<'context> { self.local_module = trait_impl.module_id; self.file = trait_impl.file_id; - let object_crate = match self.resolve_type(trait_impl.object_type.clone()) { - Type::Struct(struct_type, _) => struct_type.borrow().id.krate(), + let object_crate = match &trait_impl.resolved_object_type { + Some(Type::Struct(struct_type, _)) => struct_type.borrow().id.krate(), _ => CrateId::Dummy, }; @@ -1163,7 +1135,6 @@ impl<'context> Elaborator<'context> { self.local_module = alias.module_id; let generics = self.add_generics(&alias.type_alias_def.generics); - self.resolve_local_globals(); self.current_item = Some(DependencyId::Alias(alias_id)); let typ = self.resolve_type(alias.type_alias_def.typ); self.interner.set_type_alias(alias_id, typ, generics); @@ -1215,9 +1186,6 @@ impl<'context> Elaborator<'context> { self.recover_generics(|this| { let generics = this.add_generics(&unresolved.generics); - // Check whether the struct definition has globals in the local module and add them to the scope - this.resolve_local_globals(); - this.current_item = Some(DependencyId::Struct(struct_id)); this.resolving_ids.insert(struct_id); @@ -1253,7 +1221,7 @@ impl<'context> Elaborator<'context> { let (let_statement, _typ) = self.elaborate_let(let_stmt); let statement_id = self.interner.get_global(global_id).let_statement; - self.interner.get_global_definition_mut(global_id).kind = definition_kind; + self.interner.get_global_definition_mut(global_id).kind = definition_kind.clone(); self.interner.replace_statement(statement_id, let_statement); } @@ -1286,6 +1254,11 @@ impl<'context> Elaborator<'context> { let unresolved_type = &trait_impl.object_type; self.add_generics(&trait_impl.generics); + trait_impl.resolved_generics = self.generics.clone(); + + let trait_generics = + vecmap(&trait_impl.trait_generics, |generic| self.resolve_type(generic.clone())); + trait_impl.resolved_trait_generics = trait_generics; let self_type = self.resolve_type(unresolved_type.clone()); diff --git a/compiler/noirc_frontend/src/elaborator/traits.rs b/compiler/noirc_frontend/src/elaborator/traits.rs index 76cdc592276..2a35467f55a 100644 --- a/compiler/noirc_frontend/src/elaborator/traits.rs +++ b/compiler/noirc_frontend/src/elaborator/traits.rs @@ -13,7 +13,7 @@ use crate::{ }, node_interner::{FuncId, TraitId}, token::Attributes, - Generics, Type, TypeVariable, TypeVariableKind, + Type, TypeVariableKind, }; use super::Elaborator; @@ -21,21 +21,21 @@ use super::Elaborator; impl<'context> Elaborator<'context> { pub fn collect_traits(&mut self, traits: BTreeMap) { for (trait_id, unresolved_trait) in traits { - let generics = vecmap(&unresolved_trait.trait_def.generics, |_| { - TypeVariable::unbound(self.interner.next_type_variable_id()) - }); - - // Resolve order - // 1. Trait Types ( Trait constants can have a trait type, therefore types before constants) - let _ = self.resolve_trait_types(&unresolved_trait); - // 2. Trait Constants ( Trait's methods can use trait types & constants, therefore they should be after) - let _ = self.resolve_trait_constants(&unresolved_trait); - // 3. Trait Methods - let methods = self.resolve_trait_methods(trait_id, &unresolved_trait, &generics); - - self.interner.update_trait(trait_id, |trait_def| { - trait_def.set_methods(methods); - trait_def.generics = generics; + self.recover_generics(|this| { + this.add_generics(&unresolved_trait.trait_def.generics); + + // Resolve order + // 1. Trait Types ( Trait constants can have a trait type, therefore types before constants) + let _ = this.resolve_trait_types(&unresolved_trait); + // 2. Trait Constants ( Trait's methods can use trait types & constants, therefore they should be after) + let _ = this.resolve_trait_constants(&unresolved_trait); + // 3. Trait Methods + let methods = this.resolve_trait_methods(trait_id, &unresolved_trait); + + this.interner.update_trait(trait_id, |trait_def| { + trait_def.set_methods(methods); + trait_def.generics = vecmap(&this.generics, |(_, generic, _)| generic.clone()); + }); }); // This check needs to be after the trait's methods are set since @@ -64,7 +64,6 @@ impl<'context> Elaborator<'context> { &mut self, trait_id: TraitId, unresolved_trait: &UnresolvedTrait, - trait_generics: &Generics, ) -> Vec { self.local_module = unresolved_trait.module_id; self.file = self.def_maps[&self.crate_id].file_id(unresolved_trait.module_id); @@ -81,59 +80,57 @@ impl<'context> Elaborator<'context> { body: _, } = item { - let old_generic_count = self.generics.len(); - - let the_trait = self.interner.get_trait(trait_id); - let self_typevar = the_trait.self_type_typevar.clone(); - let self_type = Type::TypeVariable(self_typevar.clone(), TypeVariableKind::Normal); - let name_span = the_trait.name.span(); - - self.add_generics(generics); - self.add_existing_generics(&unresolved_trait.trait_def.generics, trait_generics); - self.add_existing_generic("Self", name_span, self_typevar); - self.self_type = Some(self_type.clone()); - - let func_id = unresolved_trait.method_ids[&name.0.contents]; - self.resolve_trait_function( - name, - generics, - parameters, - return_type, - where_clause, - func_id, - ); - - let arguments = vecmap(parameters, |param| self.resolve_type(param.1.clone())); - let return_type = self.resolve_type(return_type.get_type().into_owned()); - - let generics = vecmap(&self.generics, |(_, type_var, _)| type_var.clone()); - - let default_impl_list: Vec<_> = unresolved_trait - .fns_with_default_impl - .functions - .iter() - .filter(|(_, _, q)| q.name() == name.0.contents) - .collect(); - - let default_impl = if default_impl_list.len() == 1 { - Some(Box::new(default_impl_list[0].2.clone())) - } else { - None - }; - - let no_environment = Box::new(Type::Unit); - let function_type = - Type::Function(arguments, Box::new(return_type), no_environment); - - functions.push(TraitFunction { - name: name.clone(), - typ: Type::Forall(generics, Box::new(function_type)), - location: Location::new(name.span(), unresolved_trait.file_id), - default_impl, - default_impl_module_id: unresolved_trait.module_id, + self.recover_generics(|this| { + let the_trait = this.interner.get_trait(trait_id); + let self_typevar = the_trait.self_type_typevar.clone(); + let self_type = + Type::TypeVariable(self_typevar.clone(), TypeVariableKind::Normal); + let name_span = the_trait.name.span(); + + this.add_existing_generic("Self", name_span, self_typevar); + this.add_generics(generics); + this.self_type = Some(self_type.clone()); + + let func_id = unresolved_trait.method_ids[&name.0.contents]; + this.resolve_trait_function( + name, + generics, + parameters, + return_type, + where_clause, + func_id, + ); + + let arguments = vecmap(parameters, |param| this.resolve_type(param.1.clone())); + let return_type = this.resolve_type(return_type.get_type().into_owned()); + + let generics = vecmap(&this.generics, |(_, type_var, _)| type_var.clone()); + + let default_impl_list: Vec<_> = unresolved_trait + .fns_with_default_impl + .functions + .iter() + .filter(|(_, _, q)| q.name() == name.0.contents) + .collect(); + + let default_impl = if default_impl_list.len() == 1 { + Some(Box::new(default_impl_list[0].2.clone())) + } else { + None + }; + + let no_environment = Box::new(Type::Unit); + let function_type = + Type::Function(arguments, Box::new(return_type), no_environment); + + functions.push(TraitFunction { + name: name.clone(), + typ: Type::Forall(generics, Box::new(function_type)), + location: Location::new(name.span(), unresolved_trait.file_id), + default_impl, + default_impl_module_id: unresolved_trait.module_id, + }); }); - - self.generics.truncate(old_generic_count); } } functions @@ -151,9 +148,6 @@ impl<'context> Elaborator<'context> { let old_generic_count = self.generics.len(); self.scopes.start_function(); - // Check whether the function has globals in the local module and add them to the scope - self.resolve_local_globals(); - self.trait_bounds = where_clause.to_vec(); let kind = FunctionKind::Normal; diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index 838aac3f067..05147af5459 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -121,11 +121,15 @@ pub struct UnresolvedTraitImpl { pub generics: UnresolvedGenerics, pub where_clause: Vec, - // These fields are filled in later + // Every field after this line is filled in later in the elaborator pub trait_id: Option, pub impl_id: Option, pub resolved_object_type: Option, pub resolved_generics: Vec<(Rc, TypeVariable, Span)>, + + // The resolved generic on the trait itself. E.g. it is the `` in + // `impl Foo for Bar { ... }` + pub resolved_trait_generics: Vec, } #[derive(Clone)] diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index 536332d8f8a..5f1ef6477af 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -197,6 +197,7 @@ impl<'a> ModCollector<'a> { impl_id: None, resolved_object_type: None, resolved_generics: Vec::new(), + resolved_trait_generics: Vec::new(), }; self.def_collector.items.trait_impls.push(unresolved_trait_impl); From 7d8c0a3a1ae143b574b2fa62cae7c0a493005c70 Mon Sep 17 00:00:00 2001 From: jfecher Date: Tue, 28 May 2024 15:14:08 -0500 Subject: [PATCH 44/61] fix(experimental elaborator): Avoid calling `add_generics` twice on trait methods (#5108) # Description ## Problem\* Resolves the single "Duplicate definitions of found" error. ## Summary\* Since `resolve_trait_function` already calls `add_generics` indirectly via `define_function_meta`, we were adding generics on trait methods twice before. I've removed the first of the two to fix this. ## Additional Context After this the only errors that remain are the 5 on these lines of the stdlib: https://github.com/noir-lang/noir/blob/master/noir_stdlib/src/eddsa.nr#L49-L53. I believe these are the result of something from the turbofish changes being missed (likely https://github.com/noir-lang/noir/pull/5041) since they were recently modified from https://github.com/noir-lang/noir/pull/5050. ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_frontend/src/elaborator/mod.rs | 21 +++++-- .../noirc_frontend/src/elaborator/patterns.rs | 60 +++++++++++++++++-- .../noirc_frontend/src/elaborator/traits.rs | 7 ++- .../src/hir/resolution/resolver.rs | 1 + .../noirc_frontend/src/hir/type_check/mod.rs | 1 + .../noirc_frontend/src/hir_def/function.rs | 4 ++ 6 files changed, 79 insertions(+), 15 deletions(-) diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index 903751331b3..10ebd657494 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -295,9 +295,11 @@ impl<'context> Elaborator<'context> { .expect("FuncMetas should be declared before a function is elaborated") .clone(); - for (parameter, param2) in function.def.parameters.iter().zip(&func_meta.parameters.0) { - let definition_kind = DefinitionKind::Local(None); - self.elaborate_pattern(parameter.pattern.clone(), param2.1.clone(), definition_kind); + // The DefinitionIds for each parameter were already created in define_function_meta + // so we need to reintroduce the same IDs into scope here. + for parameter in &func_meta.parameter_idents { + let name = self.interner.definition_name(parameter.id).to_owned(); + self.add_existing_variable_to_scope(name, parameter.clone()); } self.generics = func_meta.all_generics.clone(); @@ -560,8 +562,9 @@ impl<'context> Elaborator<'context> { self.add_generics(&func.def.generics); let mut generics = vecmap(&self.generics, |(_, typevar, _)| typevar.clone()); - let mut parameters = vec![]; - let mut parameter_types = vec![]; + let mut parameters = Vec::new(); + let mut parameter_types = Vec::new(); + let mut parameter_idents = Vec::new(); for Param { visibility, pattern, typ, span: _ } in func.parameters().iter().cloned() { if visibility == Visibility::Public && !self.pub_allowed(func) { @@ -579,7 +582,12 @@ impl<'context> Elaborator<'context> { has_inline_attribute, type_span, ); - let pattern = self.elaborate_pattern(pattern, typ.clone(), DefinitionKind::Local(None)); + let pattern = self.elaborate_pattern_and_store_ids( + pattern, + typ.clone(), + DefinitionKind::Local(None), + &mut parameter_idents, + ); parameters.push((pattern, typ.clone(), visibility)); parameter_types.push(typ); @@ -648,6 +656,7 @@ impl<'context> Elaborator<'context> { all_generics: self.generics.clone(), trait_impl: self.current_trait_impl, parameters: parameters.into(), + parameter_idents, return_type: func.def.return_type.clone(), return_visibility: func.def.return_visibility, has_body: !func.def.body.is_empty(), diff --git a/compiler/noirc_frontend/src/elaborator/patterns.rs b/compiler/noirc_frontend/src/elaborator/patterns.rs index 17c11b88f4a..b6d6cb2cf2d 100644 --- a/compiler/noirc_frontend/src/elaborator/patterns.rs +++ b/compiler/noirc_frontend/src/elaborator/patterns.rs @@ -27,7 +27,19 @@ impl<'context> Elaborator<'context> { expected_type: Type, definition_kind: DefinitionKind, ) -> HirPattern { - self.elaborate_pattern_mut(pattern, expected_type, definition_kind, None) + self.elaborate_pattern_mut(pattern, expected_type, definition_kind, None, &mut Vec::new()) + } + + /// Equivalent to `elaborate_pattern`, this version just also + /// adds any new DefinitionIds that were created to the given Vec. + pub(super) fn elaborate_pattern_and_store_ids( + &mut self, + pattern: Pattern, + expected_type: Type, + definition_kind: DefinitionKind, + created_ids: &mut Vec, + ) -> HirPattern { + self.elaborate_pattern_mut(pattern, expected_type, definition_kind, None, created_ids) } fn elaborate_pattern_mut( @@ -36,6 +48,7 @@ impl<'context> Elaborator<'context> { expected_type: Type, definition: DefinitionKind, mutable: Option, + new_definitions: &mut Vec, ) -> HirPattern { match pattern { Pattern::Identifier(name) => { @@ -47,6 +60,7 @@ impl<'context> Elaborator<'context> { }; let ident = self.add_variable_decl(name, mutable.is_some(), true, definition); self.interner.push_definition_type(ident.id, expected_type); + new_definitions.push(ident.clone()); HirPattern::Identifier(ident) } Pattern::Mutable(pattern, span, _) => { @@ -54,8 +68,13 @@ impl<'context> Elaborator<'context> { self.push_err(ResolverError::UnnecessaryMut { first_mut, second_mut: span }); } - let pattern = - self.elaborate_pattern_mut(*pattern, expected_type, definition, Some(span)); + let pattern = self.elaborate_pattern_mut( + *pattern, + expected_type, + definition, + Some(span), + new_definitions, + ); let location = Location::new(span, self.file); HirPattern::Mutable(Box::new(pattern), location) } @@ -79,7 +98,13 @@ impl<'context> Elaborator<'context> { let fields = vecmap(fields.into_iter().enumerate(), |(i, field)| { let field_type = field_types.get(i).cloned().unwrap_or(Type::Error); - self.elaborate_pattern_mut(field, field_type, definition.clone(), mutable) + self.elaborate_pattern_mut( + field, + field_type, + definition.clone(), + mutable, + new_definitions, + ) }); let location = Location::new(span, self.file); HirPattern::Tuple(fields, location) @@ -91,10 +116,12 @@ impl<'context> Elaborator<'context> { expected_type, definition, mutable, + new_definitions, ), } } + #[allow(clippy::too_many_arguments)] fn elaborate_struct_pattern( &mut self, name: Path, @@ -103,6 +130,7 @@ impl<'context> Elaborator<'context> { expected_type: Type, definition: DefinitionKind, mutable: Option, + new_definitions: &mut Vec, ) -> HirPattern { let error_identifier = |this: &mut Self| { // Must create a name here to return a HirPattern::Identifier. Allowing @@ -140,6 +168,7 @@ impl<'context> Elaborator<'context> { expected_type.clone(), definition, mutable, + new_definitions, ); HirPattern::Struct(expected_type, fields, location) @@ -148,6 +177,7 @@ impl<'context> Elaborator<'context> { /// Resolve all the fields of a struct constructor expression. /// Ensures all fields are present, none are repeated, and all /// are part of the struct. + #[allow(clippy::too_many_arguments)] fn resolve_constructor_pattern_fields( &mut self, struct_type: Shared, @@ -156,6 +186,7 @@ impl<'context> Elaborator<'context> { expected_type: Type, definition: DefinitionKind, mutable: Option, + new_definitions: &mut Vec, ) -> Vec<(Ident, HirPattern)> { let mut ret = Vec::with_capacity(fields.len()); let mut seen_fields = HashSet::default(); @@ -163,8 +194,13 @@ impl<'context> Elaborator<'context> { for (field, pattern) in fields { let field_type = expected_type.get_field_type(&field.0.contents).unwrap_or(Type::Error); - let resolved = - self.elaborate_pattern_mut(pattern, field_type, definition.clone(), mutable); + let resolved = self.elaborate_pattern_mut( + pattern, + field_type, + definition.clone(), + mutable, + new_definitions, + ); if unseen_fields.contains(&field) { unseen_fields.remove(&field); @@ -239,6 +275,18 @@ impl<'context> Elaborator<'context> { ident } + pub fn add_existing_variable_to_scope(&mut self, name: String, ident: HirIdent) { + let second_span = ident.location.span; + let resolver_meta = ResolverMeta { num_times_used: 0, ident, warn_if_unused: true }; + + let old_value = self.scopes.get_mut_scope().add_key_value(name.clone(), resolver_meta); + + if let Some(old_value) = old_value { + let first_span = old_value.ident.location.span; + self.push_err(ResolverError::DuplicateDefinition { name, first_span, second_span }); + } + } + pub fn add_global_variable_decl( &mut self, name: Ident, diff --git a/compiler/noirc_frontend/src/elaborator/traits.rs b/compiler/noirc_frontend/src/elaborator/traits.rs index 2a35467f55a..30a6f50ad5a 100644 --- a/compiler/noirc_frontend/src/elaborator/traits.rs +++ b/compiler/noirc_frontend/src/elaborator/traits.rs @@ -88,7 +88,6 @@ impl<'context> Elaborator<'context> { let name_span = the_trait.name.span(); this.add_existing_generic("Self", name_span, self_typevar); - this.add_generics(generics); this.self_type = Some(self_type.clone()); let func_id = unresolved_trait.method_ids[&name.0.contents]; @@ -101,8 +100,10 @@ impl<'context> Elaborator<'context> { func_id, ); - let arguments = vecmap(parameters, |param| this.resolve_type(param.1.clone())); - let return_type = this.resolve_type(return_type.get_type().into_owned()); + let func_meta = this.interner.function_meta(&func_id); + + let arguments = vecmap(&func_meta.parameters.0, |(_, typ, _)| typ.clone()); + let return_type = func_meta.return_type().clone(); let generics = vecmap(&this.generics, |(_, type_var, _)| type_var.clone()); diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index 9fe0d473f15..fd77312e4f2 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -1110,6 +1110,7 @@ impl<'a> Resolver<'a> { // This is only used by the elaborator all_generics: Vec::new(), is_trait_function: false, + parameter_idents: Vec::new(), } } diff --git a/compiler/noirc_frontend/src/hir/type_check/mod.rs b/compiler/noirc_frontend/src/hir/type_check/mod.rs index 70d7c4021ed..de2e575b4e2 100644 --- a/compiler/noirc_frontend/src/hir/type_check/mod.rs +++ b/compiler/noirc_frontend/src/hir/type_check/mod.rs @@ -552,6 +552,7 @@ pub mod test { is_trait_function: false, has_inline_attribute: false, all_generics: Vec::new(), + parameter_idents: Vec::new(), }; interner.push_fn_meta(func_meta, func_id); diff --git a/compiler/noirc_frontend/src/hir_def/function.rs b/compiler/noirc_frontend/src/hir_def/function.rs index 9e03f074ffe..3bd85e94dca 100644 --- a/compiler/noirc_frontend/src/hir_def/function.rs +++ b/compiler/noirc_frontend/src/hir_def/function.rs @@ -95,6 +95,10 @@ pub struct FuncMeta { pub parameters: Parameters, + /// The HirIdent of each identifier within the parameter list. + /// Note that this includes separate entries for each identifier in e.g. tuple patterns. + pub parameter_idents: Vec, + pub return_type: FunctionReturnType, pub return_visibility: Visibility, From f03f8aed34393f7b0f6f68a189ce6c6192f6af6e Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 28 May 2024 23:23:40 +0100 Subject: [PATCH 45/61] chore: remove duplicated code from LSP (#5116) # Description ## Problem\* Resolves ## Summary\* We've got some copy pasted code here so I've added a helper function for converting a "position" to a "location". ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: jfecher --- tooling/lsp/src/requests/goto_declaration.rs | 40 ++++++-------------- tooling/lsp/src/requests/goto_definition.rs | 40 ++++++-------------- tooling/lsp/src/requests/mod.rs | 28 +++++++++++++- 3 files changed, 50 insertions(+), 58 deletions(-) diff --git a/tooling/lsp/src/requests/goto_declaration.rs b/tooling/lsp/src/requests/goto_declaration.rs index 5cff16b2348..4ffe6abf88a 100644 --- a/tooling/lsp/src/requests/goto_declaration.rs +++ b/tooling/lsp/src/requests/goto_declaration.rs @@ -5,12 +5,13 @@ use crate::LspState; use crate::{parse_diff, resolve_workspace_for_source_path}; use async_lsp::{ErrorCode, ResponseError}; +use fm::PathString; use lsp_types::request::{GotoDeclarationParams, GotoDeclarationResponse}; use nargo::insert_all_files_for_workspace_into_file_manager; use noirc_driver::file_manager_with_stdlib; -use super::{position_to_byte_index, to_lsp_location}; +use super::{position_to_location, to_lsp_location}; pub(crate) fn on_goto_declaration_request( state: &mut LspState, @@ -32,8 +33,6 @@ fn on_goto_definition_inner( let workspace = resolve_workspace_for_source_path(file_path.as_path()).unwrap(); let package = workspace.members.first().unwrap(); - let package_root_path: String = package.root_dir.as_os_str().to_string_lossy().into(); - let mut workspace_file_manager = file_manager_with_stdlib(&workspace.root_dir); insert_all_files_for_workspace_into_file_manager(&workspace, &mut workspace_file_manager); let parsed_files = parse_diff(&workspace_file_manager, state); @@ -41,40 +40,25 @@ fn on_goto_definition_inner( let (mut context, crate_id) = nargo::prepare_package(&workspace_file_manager, &parsed_files, package); - let interner; - if let Some(def_interner) = state.cached_definitions.get(&package_root_path) { - interner = def_interner; + let package_root_path = package.root_dir.as_os_str().to_string_lossy().into_owned(); + let interner = if let Some(def_interner) = state.cached_definitions.get(&package_root_path) { + def_interner } else { // We ignore the warnings and errors produced by compilation while resolving the definition let _ = noirc_driver::check_crate(&mut context, crate_id, false, false, false); - interner = &context.def_interner; - } - - let files = context.file_manager.as_file_map(); - let file_id = context.file_manager.name_to_id(file_path.clone()).ok_or(ResponseError::new( - ErrorCode::REQUEST_FAILED, - format!("Could not find file in file manager. File path: {:?}", file_path), - ))?; - let byte_index = - position_to_byte_index(files, file_id, ¶ms.text_document_position_params.position) - .map_err(|err| { - ResponseError::new( - ErrorCode::REQUEST_FAILED, - format!("Could not convert position to byte index. Error: {:?}", err), - ) - })?; - - let search_for_location = noirc_errors::Location { - file: file_id, - span: noirc_errors::Span::single_char(byte_index as u32), + &context.def_interner }; + let files = workspace_file_manager.as_file_map(); + let file_path = PathString::from(file_path); + let search_for_location = + position_to_location(files, &file_path, ¶ms.text_document_position_params.position)?; + let goto_declaration_response = interner.get_declaration_location_from(search_for_location).and_then(|found_location| { let file_id = found_location.file; let definition_position = to_lsp_location(files, file_id, found_location.span)?; - let response: GotoDeclarationResponse = - GotoDeclarationResponse::from(definition_position).to_owned(); + let response = GotoDeclarationResponse::from(definition_position).to_owned(); Some(response) }); diff --git a/tooling/lsp/src/requests/goto_definition.rs b/tooling/lsp/src/requests/goto_definition.rs index 32e13ce00f6..3a92e28cc11 100644 --- a/tooling/lsp/src/requests/goto_definition.rs +++ b/tooling/lsp/src/requests/goto_definition.rs @@ -4,12 +4,13 @@ use crate::{parse_diff, resolve_workspace_for_source_path}; use crate::{types::GotoDefinitionResult, LspState}; use async_lsp::{ErrorCode, ResponseError}; +use fm::PathString; use lsp_types::request::GotoTypeDefinitionParams; use lsp_types::{GotoDefinitionParams, GotoDefinitionResponse}; use nargo::insert_all_files_for_workspace_into_file_manager; use noirc_driver::file_manager_with_stdlib; -use super::{position_to_byte_index, to_lsp_location}; +use super::{position_to_location, to_lsp_location}; pub(crate) fn on_goto_definition_request( state: &mut LspState, @@ -40,8 +41,6 @@ fn on_goto_definition_inner( let workspace = resolve_workspace_for_source_path(file_path.as_path()).unwrap(); let package = workspace.members.first().unwrap(); - let package_root_path: String = package.root_dir.as_os_str().to_string_lossy().into(); - let mut workspace_file_manager = file_manager_with_stdlib(&workspace.root_dir); insert_all_files_for_workspace_into_file_manager(&workspace, &mut workspace_file_manager); let parsed_files = parse_diff(&workspace_file_manager, state); @@ -49,41 +48,26 @@ fn on_goto_definition_inner( let (mut context, crate_id) = nargo::prepare_package(&workspace_file_manager, &parsed_files, package); - let interner; - if let Some(def_interner) = state.cached_definitions.get(&package_root_path) { - interner = def_interner; + let package_root_path = package.root_dir.as_os_str().to_string_lossy().into_owned(); + let interner = if let Some(def_interner) = state.cached_definitions.get(&package_root_path) { + def_interner } else { // We ignore the warnings and errors produced by compilation while resolving the definition let _ = noirc_driver::check_crate(&mut context, crate_id, false, false, false); - interner = &context.def_interner; - } - - let files = context.file_manager.as_file_map(); - let file_id = context.file_manager.name_to_id(file_path.clone()).ok_or(ResponseError::new( - ErrorCode::REQUEST_FAILED, - format!("Could not find file in file manager. File path: {:?}", file_path), - ))?; - let byte_index = - position_to_byte_index(files, file_id, ¶ms.text_document_position_params.position) - .map_err(|err| { - ResponseError::new( - ErrorCode::REQUEST_FAILED, - format!("Could not convert position to byte index. Error: {:?}", err), - ) - })?; - - let search_for_location = noirc_errors::Location { - file: file_id, - span: noirc_errors::Span::single_char(byte_index as u32), + &context.def_interner }; + let files = workspace_file_manager.as_file_map(); + let file_path = PathString::from(file_path); + let search_for_location = + position_to_location(files, &file_path, ¶ms.text_document_position_params.position)?; + let goto_definition_response = interner .get_definition_location_from(search_for_location, return_type_location_instead) .and_then(|found_location| { let file_id = found_location.file; let definition_position = to_lsp_location(files, file_id, found_location.span)?; - let response: GotoDefinitionResponse = - GotoDefinitionResponse::from(definition_position).to_owned(); + let response = GotoDefinitionResponse::from(definition_position).to_owned(); Some(response) }); diff --git a/tooling/lsp/src/requests/mod.rs b/tooling/lsp/src/requests/mod.rs index ec56cf5045a..769e9ba17ce 100644 --- a/tooling/lsp/src/requests/mod.rs +++ b/tooling/lsp/src/requests/mod.rs @@ -1,8 +1,8 @@ use std::future::Future; use crate::types::{CodeLensOptions, InitializeParams}; -use async_lsp::ResponseError; -use fm::codespan_files::Error; +use async_lsp::{ErrorCode, ResponseError}; +use fm::{codespan_files::Error, FileMap, PathString}; use lsp_types::{ DeclarationCapability, Location, Position, TextDocumentSyncCapability, TextDocumentSyncKind, TypeDefinitionProviderCapability, Url, @@ -171,6 +171,30 @@ where } } +fn position_to_location( + files: &FileMap, + file_path: &PathString, + position: &Position, +) -> Result { + let file_id = files.get_file_id(file_path).ok_or(ResponseError::new( + ErrorCode::REQUEST_FAILED, + format!("Could not find file in file manager. File path: {:?}", file_path), + ))?; + let byte_index = position_to_byte_index(files, file_id, position).map_err(|err| { + ResponseError::new( + ErrorCode::REQUEST_FAILED, + format!("Could not convert position to byte index. Error: {:?}", err), + ) + })?; + + let location = noirc_errors::Location { + file: file_id, + span: noirc_errors::Span::single_char(byte_index as u32), + }; + + Ok(location) +} + fn character_to_line_offset(line: &str, character: u32) -> Result { let line_len = line.len(); let mut character_offset = 0; From b545744aa01fd7e60723701cb0b6e7cfaff4bb74 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Wed, 29 May 2024 15:26:57 +0100 Subject: [PATCH 46/61] chore: run all test programs in brillig as well as ACIR (#5128) # Description ## Problem\* Resolves ## Summary\* This PR helps ensure consistency between ACIR and brillig by checking that every `execution_success` test case were compiled and run in brillig then it would succeed. This has thrown up a couple of test case failures which I've added to a list to be ignored for now. We can address these in follow-up PRs ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../brillig_array_eq/Prover.toml | 2 - .../brillig_array_eq/src/main.nr | 4 -- .../brillig_bit_shifts_runtime/Nargo.toml | 6 -- .../brillig_bit_shifts_runtime/Prover.toml | 2 - .../brillig_bit_shifts_runtime/src/main.nr | 20 ------ .../brillig_embedded_curve/Nargo.toml | 6 -- .../brillig_embedded_curve/Prover.toml | 3 - .../brillig_embedded_curve/src/main.nr | 24 ------- .../brillig_schnorr/Prover.toml | 70 ------------------- .../brillig_schnorr/src/main.nr | 25 ------- .../brillig_signed_cmp/Nargo.toml | 6 -- .../brillig_to_be_bytes/Nargo.toml | 6 -- .../brillig_to_be_bytes/Prover.toml | 1 - .../brillig_to_be_bytes/src/main.nr | 12 ---- .../brillig_to_bytes_integration/Nargo.toml | 6 -- .../brillig_to_bytes_integration/Prover.toml | 2 - .../brillig_to_bytes_integration/src/main.nr | 27 ------- .../brillig_to_le_bytes/Nargo.toml | 6 -- .../brillig_to_le_bytes/Prover.toml | 1 - .../brillig_to_le_bytes/src/main.nr | 10 --- .../brillig_top_level/Nargo.toml | 6 -- .../brillig_top_level/Prover.toml | 2 - .../brillig_top_level/src/main.nr | 6 -- .../{brillig_to_bits => empty}/Nargo.toml | 2 +- .../execution_success/empty/src/main.nr | 1 + .../Nargo.toml | 2 +- .../Prover.toml | 0 .../src/main.nr | 2 +- .../Nargo.toml | 2 +- .../Prover.toml | 0 .../src/main.nr | 0 .../{brillig_wrapping => to_bits}/Nargo.toml | 3 +- .../{brillig_to_bits => to_bits}/src/main.nr | 2 +- .../unconstrained_empty/Nargo.toml | 5 -- .../unconstrained_empty/src/main.nr | 1 - .../Nargo.toml | 2 +- .../Prover.toml | 0 .../src/main.nr | 2 +- tooling/nargo_cli/build.rs | 34 +++++++++ 39 files changed, 43 insertions(+), 268 deletions(-) delete mode 100644 test_programs/execution_success/brillig_array_eq/Prover.toml delete mode 100644 test_programs/execution_success/brillig_array_eq/src/main.nr delete mode 100644 test_programs/execution_success/brillig_bit_shifts_runtime/Nargo.toml delete mode 100644 test_programs/execution_success/brillig_bit_shifts_runtime/Prover.toml delete mode 100644 test_programs/execution_success/brillig_bit_shifts_runtime/src/main.nr delete mode 100644 test_programs/execution_success/brillig_embedded_curve/Nargo.toml delete mode 100644 test_programs/execution_success/brillig_embedded_curve/Prover.toml delete mode 100644 test_programs/execution_success/brillig_embedded_curve/src/main.nr delete mode 100644 test_programs/execution_success/brillig_schnorr/Prover.toml delete mode 100644 test_programs/execution_success/brillig_schnorr/src/main.nr delete mode 100644 test_programs/execution_success/brillig_signed_cmp/Nargo.toml delete mode 100644 test_programs/execution_success/brillig_to_be_bytes/Nargo.toml delete mode 100644 test_programs/execution_success/brillig_to_be_bytes/Prover.toml delete mode 100644 test_programs/execution_success/brillig_to_be_bytes/src/main.nr delete mode 100644 test_programs/execution_success/brillig_to_bytes_integration/Nargo.toml delete mode 100644 test_programs/execution_success/brillig_to_bytes_integration/Prover.toml delete mode 100644 test_programs/execution_success/brillig_to_bytes_integration/src/main.nr delete mode 100644 test_programs/execution_success/brillig_to_le_bytes/Nargo.toml delete mode 100644 test_programs/execution_success/brillig_to_le_bytes/Prover.toml delete mode 100644 test_programs/execution_success/brillig_to_le_bytes/src/main.nr delete mode 100644 test_programs/execution_success/brillig_top_level/Nargo.toml delete mode 100644 test_programs/execution_success/brillig_top_level/Prover.toml delete mode 100644 test_programs/execution_success/brillig_top_level/src/main.nr rename test_programs/execution_success/{brillig_to_bits => empty}/Nargo.toml (67%) create mode 100644 test_programs/execution_success/empty/src/main.nr rename test_programs/execution_success/{brillig_schnorr => signed_cmp}/Nargo.toml (68%) rename test_programs/execution_success/{brillig_signed_cmp => signed_cmp}/Prover.toml (100%) rename test_programs/execution_success/{brillig_signed_cmp => signed_cmp}/src/main.nr (84%) rename test_programs/execution_success/{brillig_array_eq => signed_div}/Nargo.toml (67%) rename test_programs/execution_success/{brillig_signed_div => signed_div}/Prover.toml (100%) rename test_programs/execution_success/{brillig_signed_div => signed_div}/src/main.nr (100%) rename test_programs/execution_success/{brillig_wrapping => to_bits}/Nargo.toml (66%) rename test_programs/execution_success/{brillig_to_bits => to_bits}/src/main.nr (94%) delete mode 100644 test_programs/execution_success/unconstrained_empty/Nargo.toml delete mode 100644 test_programs/execution_success/unconstrained_empty/src/main.nr rename test_programs/execution_success/{brillig_signed_div => wrapping_operations}/Nargo.toml (65%) rename test_programs/execution_success/{brillig_wrapping => wrapping_operations}/Prover.toml (100%) rename test_programs/execution_success/{brillig_wrapping => wrapping_operations}/src/main.nr (79%) diff --git a/test_programs/execution_success/brillig_array_eq/Prover.toml b/test_programs/execution_success/brillig_array_eq/Prover.toml deleted file mode 100644 index ecfed7de213..00000000000 --- a/test_programs/execution_success/brillig_array_eq/Prover.toml +++ /dev/null @@ -1,2 +0,0 @@ -a = [77,75,108,209,54,16,50,202,155,210,174,185,217,0,170,77,69,217,234,216,10,201,66,51,116,196,81,167,37,77,7,102] -b = [77,75,108,209,54,16,50,202,155,210,174,185,217,0,170,77,69,217,234,216,10,201,66,51,116,196,81,167,37,77,7,102] diff --git a/test_programs/execution_success/brillig_array_eq/src/main.nr b/test_programs/execution_success/brillig_array_eq/src/main.nr deleted file mode 100644 index 90f631dbed8..00000000000 --- a/test_programs/execution_success/brillig_array_eq/src/main.nr +++ /dev/null @@ -1,4 +0,0 @@ -// Simple example of checking where two arrays are equal -unconstrained fn main(a: [Field; 32], b: [Field; 32]) { - assert(a == b); -} diff --git a/test_programs/execution_success/brillig_bit_shifts_runtime/Nargo.toml b/test_programs/execution_success/brillig_bit_shifts_runtime/Nargo.toml deleted file mode 100644 index ed8200d8a95..00000000000 --- a/test_programs/execution_success/brillig_bit_shifts_runtime/Nargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "brillig_bit_shifts_runtime" -type = "bin" -authors = [""] - -[dependencies] diff --git a/test_programs/execution_success/brillig_bit_shifts_runtime/Prover.toml b/test_programs/execution_success/brillig_bit_shifts_runtime/Prover.toml deleted file mode 100644 index 98d8630792e..00000000000 --- a/test_programs/execution_success/brillig_bit_shifts_runtime/Prover.toml +++ /dev/null @@ -1,2 +0,0 @@ -x = 64 -y = 1 \ No newline at end of file diff --git a/test_programs/execution_success/brillig_bit_shifts_runtime/src/main.nr b/test_programs/execution_success/brillig_bit_shifts_runtime/src/main.nr deleted file mode 100644 index cdeaad7514c..00000000000 --- a/test_programs/execution_success/brillig_bit_shifts_runtime/src/main.nr +++ /dev/null @@ -1,20 +0,0 @@ -unconstrained fn main(x: u64, y: u8) { - // runtime shifts on compile-time known values - assert(64 as u32 << y == 128); - assert(64 as u32 >> y == 32); - // runtime shifts on runtime values - assert(x << y == 128); - assert(x >> y == 32); - - // Bit-shift with signed integers - let mut a :i8 = y as i8; - let mut b: i8 = x as i8; - assert(b << 1 == -128); - assert(b >> 2 == 16); - assert(b >> y == 32); - a = -a; - assert(a << 7 == -128); - assert(a << y == -2); - - assert(x >> (x as u8) == 0); -} diff --git a/test_programs/execution_success/brillig_embedded_curve/Nargo.toml b/test_programs/execution_success/brillig_embedded_curve/Nargo.toml deleted file mode 100644 index b92e11d6383..00000000000 --- a/test_programs/execution_success/brillig_embedded_curve/Nargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "brillig_embedded_curve" -type = "bin" -authors = [""] - -[dependencies] diff --git a/test_programs/execution_success/brillig_embedded_curve/Prover.toml b/test_programs/execution_success/brillig_embedded_curve/Prover.toml deleted file mode 100644 index 7113b9cd038..00000000000 --- a/test_programs/execution_success/brillig_embedded_curve/Prover.toml +++ /dev/null @@ -1,3 +0,0 @@ -priv_key = "1" -pub_x = "0x0000000000000000000000000000000000000000000000000000000000000001" -pub_y = "0x0000000000000002cf135e7506a45d632d270d45f1181294833fc48d823f272c" \ No newline at end of file diff --git a/test_programs/execution_success/brillig_embedded_curve/src/main.nr b/test_programs/execution_success/brillig_embedded_curve/src/main.nr deleted file mode 100644 index 89a699448dc..00000000000 --- a/test_programs/execution_success/brillig_embedded_curve/src/main.nr +++ /dev/null @@ -1,24 +0,0 @@ -use dep::std; - -unconstrained fn main(priv_key: Field, pub_x: pub Field, pub_y: pub Field) { - let g1_y = 17631683881184975370165255887551781615748388533673675138860; - let g1 = std::embedded_curve_ops::EmbeddedCurvePoint { x: 1, y: g1_y, is_infinite: false }; - let scalar = std::embedded_curve_ops::EmbeddedCurveScalar { lo: priv_key, hi: 0 }; - // Test that multi_scalar_mul correctly derives the public key - let res = std::embedded_curve_ops::multi_scalar_mul([g1], [scalar]); - assert(res[0] == pub_x); - assert(res[1] == pub_y); - - // Test that double function calling embedded_curve_add works as expected - let pub_point = std::embedded_curve_ops::EmbeddedCurvePoint { x: pub_x, y: pub_y, is_infinite: false }; - let res = pub_point.double(); - let double = g1.add(g1); - - assert(double.x == res.x); - - // Test calling multi_scalar_mul with multiple points and scalars - let res = std::embedded_curve_ops::multi_scalar_mul([g1, g1], [scalar, scalar]); - - // The results should be double the g1 point because the scalars are 1 and we pass in g1 twice - assert(double.x == res[0]); -} diff --git a/test_programs/execution_success/brillig_schnorr/Prover.toml b/test_programs/execution_success/brillig_schnorr/Prover.toml deleted file mode 100644 index 2faf2018e07..00000000000 --- a/test_programs/execution_success/brillig_schnorr/Prover.toml +++ /dev/null @@ -1,70 +0,0 @@ -message = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -message_field = "0x010203040506070809" -pub_key_x = "0x04b260954662e97f00cab9adb773a259097f7a274b83b113532bce27fa3fb96a" -pub_key_y = "0x2fd51571db6c08666b0edfbfbc57d432068bccd0110a39b166ab243da0037197" -signature = [ - 1, - 13, - 119, - 112, - 212, - 39, - 233, - 41, - 84, - 235, - 255, - 93, - 245, - 172, - 186, - 83, - 157, - 253, - 76, - 77, - 33, - 128, - 178, - 15, - 214, - 67, - 105, - 107, - 177, - 234, - 77, - 48, - 27, - 237, - 155, - 84, - 39, - 84, - 247, - 27, - 22, - 8, - 176, - 230, - 24, - 115, - 145, - 220, - 254, - 122, - 135, - 179, - 171, - 4, - 214, - 202, - 64, - 199, - 19, - 84, - 239, - 138, - 124, - 12, -] diff --git a/test_programs/execution_success/brillig_schnorr/src/main.nr b/test_programs/execution_success/brillig_schnorr/src/main.nr deleted file mode 100644 index 03c635b4f6f..00000000000 --- a/test_programs/execution_success/brillig_schnorr/src/main.nr +++ /dev/null @@ -1,25 +0,0 @@ -use dep::std; -// Note: If main has any unsized types, then the verifier will never be able -// to figure out the circuit instance -unconstrained fn main( - message: [u8; 10], - message_field: Field, - pub_key_x: Field, - pub_key_y: Field, - signature: [u8; 64] -) { - // Regression for issue #2421 - // We want to make sure that we can accurately verify a signature whose message is a slice vs. an array - let message_field_bytes = message_field.to_be_bytes(10); - for i in 0..10 { - assert(message[i] == message_field_bytes[i]); - } - // Is there ever a situation where someone would want - // to ensure that a signature was invalid? - // Check that passing a slice as the message is valid - let valid_signature = std::schnorr::verify_signature_slice(pub_key_x, pub_key_y, signature, message_field_bytes); - assert(valid_signature); - // Check that passing an array as the message is valid - let valid_signature = std::schnorr::verify_signature(pub_key_x, pub_key_y, signature, message); - assert(valid_signature); -} diff --git a/test_programs/execution_success/brillig_signed_cmp/Nargo.toml b/test_programs/execution_success/brillig_signed_cmp/Nargo.toml deleted file mode 100644 index 3f485df4a82..00000000000 --- a/test_programs/execution_success/brillig_signed_cmp/Nargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "brillig_signed_cmp" -type = "bin" -authors = [""] - -[dependencies] diff --git a/test_programs/execution_success/brillig_to_be_bytes/Nargo.toml b/test_programs/execution_success/brillig_to_be_bytes/Nargo.toml deleted file mode 100644 index df6c818c90f..00000000000 --- a/test_programs/execution_success/brillig_to_be_bytes/Nargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "brillig_to_be_bytes" -type = "bin" -authors = [""] - -[dependencies] diff --git a/test_programs/execution_success/brillig_to_be_bytes/Prover.toml b/test_programs/execution_success/brillig_to_be_bytes/Prover.toml deleted file mode 100644 index 07fe857ac7c..00000000000 --- a/test_programs/execution_success/brillig_to_be_bytes/Prover.toml +++ /dev/null @@ -1 +0,0 @@ -x = "2040124" diff --git a/test_programs/execution_success/brillig_to_be_bytes/src/main.nr b/test_programs/execution_success/brillig_to_be_bytes/src/main.nr deleted file mode 100644 index 9d78411f060..00000000000 --- a/test_programs/execution_success/brillig_to_be_bytes/src/main.nr +++ /dev/null @@ -1,12 +0,0 @@ -unconstrained fn main(x: Field) -> pub [u8; 31] { - // The result of this byte array will be big-endian - let byte_array = x.to_be_bytes(31); - let mut bytes = [0; 31]; - for i in 0..31 { - bytes[i] = byte_array[i]; - } - assert(bytes[30] == 60); - assert(bytes[29] == 33); - assert(bytes[28] == 31); - bytes -} diff --git a/test_programs/execution_success/brillig_to_bytes_integration/Nargo.toml b/test_programs/execution_success/brillig_to_bytes_integration/Nargo.toml deleted file mode 100644 index 991f3d1e46c..00000000000 --- a/test_programs/execution_success/brillig_to_bytes_integration/Nargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "brillig_to_bytes_integration" -type = "bin" -authors = [""] - -[dependencies] diff --git a/test_programs/execution_success/brillig_to_bytes_integration/Prover.toml b/test_programs/execution_success/brillig_to_bytes_integration/Prover.toml deleted file mode 100644 index 23f7acea449..00000000000 --- a/test_programs/execution_success/brillig_to_bytes_integration/Prover.toml +++ /dev/null @@ -1,2 +0,0 @@ -x = "2040124" -_y = "0x2000000000000000000000000000000000000000000000000000000000000000" diff --git a/test_programs/execution_success/brillig_to_bytes_integration/src/main.nr b/test_programs/execution_success/brillig_to_bytes_integration/src/main.nr deleted file mode 100644 index e8e5b9db9ca..00000000000 --- a/test_programs/execution_success/brillig_to_bytes_integration/src/main.nr +++ /dev/null @@ -1,27 +0,0 @@ -use dep::std; - -unconstrained fn main(x: Field, _y: Field) { - // The result of this byte array will be big-endian - let y: Field = 2040124; - let be_byte_array = y.to_be_bytes(31); - // The result of this byte array will be little-endian - let le_byte_array = x.to_le_bytes(31); - - assert(le_byte_array[0] == 60); - assert(le_byte_array[0] == be_byte_array[30]); - assert(le_byte_array[1] == be_byte_array[29]); - assert(le_byte_array[2] == be_byte_array[28]); - - let z = 0 - 1; - let p_bytes = std::field::modulus_le_bytes(); - let z_bytes = z.to_le_bytes(32); - assert(p_bytes[10] == z_bytes[10]); - assert(p_bytes[0] == z_bytes[0] as u8 + 1 as u8); - - let p_bits = std::field::modulus_le_bits(); - let z_bits = z.to_le_bits(std::field::modulus_num_bits() as u32); - assert(z_bits[0] == 0); - assert(p_bits[100] == z_bits[100]); - - _y.to_le_bits(std::field::modulus_num_bits() as u32); -} diff --git a/test_programs/execution_success/brillig_to_le_bytes/Nargo.toml b/test_programs/execution_success/brillig_to_le_bytes/Nargo.toml deleted file mode 100644 index c2ce8ad01b5..00000000000 --- a/test_programs/execution_success/brillig_to_le_bytes/Nargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "brillig_to_le_bytes" -type = "bin" -authors = [""] - -[dependencies] diff --git a/test_programs/execution_success/brillig_to_le_bytes/Prover.toml b/test_programs/execution_success/brillig_to_le_bytes/Prover.toml deleted file mode 100644 index 07fe857ac7c..00000000000 --- a/test_programs/execution_success/brillig_to_le_bytes/Prover.toml +++ /dev/null @@ -1 +0,0 @@ -x = "2040124" diff --git a/test_programs/execution_success/brillig_to_le_bytes/src/main.nr b/test_programs/execution_success/brillig_to_le_bytes/src/main.nr deleted file mode 100644 index 77d292cf01b..00000000000 --- a/test_programs/execution_success/brillig_to_le_bytes/src/main.nr +++ /dev/null @@ -1,10 +0,0 @@ -unconstrained fn main(x: Field) -> pub [u8; 31] { - // The result of this byte array will be little-endian - let byte_array = x.to_le_bytes(31); - assert(byte_array.len() == 31); - let mut bytes = [0; 31]; - for i in 0..31 { - bytes[i] = byte_array[i]; - } - bytes -} diff --git a/test_programs/execution_success/brillig_top_level/Nargo.toml b/test_programs/execution_success/brillig_top_level/Nargo.toml deleted file mode 100644 index f74a2a82964..00000000000 --- a/test_programs/execution_success/brillig_top_level/Nargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "brillig_top_level" -type = "bin" -authors = [""] - -[dependencies] diff --git a/test_programs/execution_success/brillig_top_level/Prover.toml b/test_programs/execution_success/brillig_top_level/Prover.toml deleted file mode 100644 index a0150a0e562..00000000000 --- a/test_programs/execution_success/brillig_top_level/Prover.toml +++ /dev/null @@ -1,2 +0,0 @@ -x = "1" -array = ["4", "5", "6"] \ No newline at end of file diff --git a/test_programs/execution_success/brillig_top_level/src/main.nr b/test_programs/execution_success/brillig_top_level/src/main.nr deleted file mode 100644 index 6dfd98b2c3e..00000000000 --- a/test_programs/execution_success/brillig_top_level/src/main.nr +++ /dev/null @@ -1,6 +0,0 @@ -// Tests a very simple program. -// -// The feature being tested is brillig as the entry point. -unconstrained fn main(array: [Field; 3], x: pub Field) -> pub [Field; 2] { - [array[x], array[x + 1]] -} diff --git a/test_programs/execution_success/brillig_to_bits/Nargo.toml b/test_programs/execution_success/empty/Nargo.toml similarity index 67% rename from test_programs/execution_success/brillig_to_bits/Nargo.toml rename to test_programs/execution_success/empty/Nargo.toml index a18b769550d..168911f2b2b 100644 --- a/test_programs/execution_success/brillig_to_bits/Nargo.toml +++ b/test_programs/execution_success/empty/Nargo.toml @@ -1,5 +1,5 @@ [package] -name = "brillig_to_bits" +name = "empty" type = "bin" authors = [""] [dependencies] diff --git a/test_programs/execution_success/empty/src/main.nr b/test_programs/execution_success/empty/src/main.nr new file mode 100644 index 00000000000..f328e4d9d04 --- /dev/null +++ b/test_programs/execution_success/empty/src/main.nr @@ -0,0 +1 @@ +fn main() {} diff --git a/test_programs/execution_success/brillig_schnorr/Nargo.toml b/test_programs/execution_success/signed_cmp/Nargo.toml similarity index 68% rename from test_programs/execution_success/brillig_schnorr/Nargo.toml rename to test_programs/execution_success/signed_cmp/Nargo.toml index 1b598abbf74..642a0924678 100644 --- a/test_programs/execution_success/brillig_schnorr/Nargo.toml +++ b/test_programs/execution_success/signed_cmp/Nargo.toml @@ -1,5 +1,5 @@ [package] -name = "brillig_schnorr" +name = "signed_cmp" type = "bin" authors = [""] diff --git a/test_programs/execution_success/brillig_signed_cmp/Prover.toml b/test_programs/execution_success/signed_cmp/Prover.toml similarity index 100% rename from test_programs/execution_success/brillig_signed_cmp/Prover.toml rename to test_programs/execution_success/signed_cmp/Prover.toml diff --git a/test_programs/execution_success/brillig_signed_cmp/src/main.nr b/test_programs/execution_success/signed_cmp/src/main.nr similarity index 84% rename from test_programs/execution_success/brillig_signed_cmp/src/main.nr rename to test_programs/execution_success/signed_cmp/src/main.nr index 3e3ea0f4b0f..85746ada8f4 100644 --- a/test_programs/execution_success/brillig_signed_cmp/src/main.nr +++ b/test_programs/execution_success/signed_cmp/src/main.nr @@ -1,4 +1,4 @@ -unconstrained fn main(minus_one: i8) { +fn main(minus_one: i8) { assert(minus_one < 0); assert(0 < minus_one as u8); assert(0 > minus_one); diff --git a/test_programs/execution_success/brillig_array_eq/Nargo.toml b/test_programs/execution_success/signed_div/Nargo.toml similarity index 67% rename from test_programs/execution_success/brillig_array_eq/Nargo.toml rename to test_programs/execution_success/signed_div/Nargo.toml index 62ce392f96b..5ce137d8c0c 100644 --- a/test_programs/execution_success/brillig_array_eq/Nargo.toml +++ b/test_programs/execution_success/signed_div/Nargo.toml @@ -1,5 +1,5 @@ [package] -name = "brillig_array_eq" +name = "signed_div" type = "bin" authors = [""] diff --git a/test_programs/execution_success/brillig_signed_div/Prover.toml b/test_programs/execution_success/signed_div/Prover.toml similarity index 100% rename from test_programs/execution_success/brillig_signed_div/Prover.toml rename to test_programs/execution_success/signed_div/Prover.toml diff --git a/test_programs/execution_success/brillig_signed_div/src/main.nr b/test_programs/execution_success/signed_div/src/main.nr similarity index 100% rename from test_programs/execution_success/brillig_signed_div/src/main.nr rename to test_programs/execution_success/signed_div/src/main.nr diff --git a/test_programs/execution_success/brillig_wrapping/Nargo.toml b/test_programs/execution_success/to_bits/Nargo.toml similarity index 66% rename from test_programs/execution_success/brillig_wrapping/Nargo.toml rename to test_programs/execution_success/to_bits/Nargo.toml index a52246ba908..ef47f3b4ba1 100644 --- a/test_programs/execution_success/brillig_wrapping/Nargo.toml +++ b/test_programs/execution_success/to_bits/Nargo.toml @@ -1,6 +1,5 @@ [package] -name = "brillig_wrapping" +name = "to_bits" type = "bin" authors = [""] - [dependencies] diff --git a/test_programs/execution_success/brillig_to_bits/src/main.nr b/test_programs/execution_success/to_bits/src/main.nr similarity index 94% rename from test_programs/execution_success/brillig_to_bits/src/main.nr rename to test_programs/execution_success/to_bits/src/main.nr index 7ff3d2467b5..18f65f0bd66 100644 --- a/test_programs/execution_success/brillig_to_bits/src/main.nr +++ b/test_programs/execution_success/to_bits/src/main.nr @@ -1,6 +1,6 @@ use dep::std; -unconstrained fn main() { +fn main() { let field = 1000; let be_bits = field.to_be_bits(16); let le_bits = field.to_le_bits(16); diff --git a/test_programs/execution_success/unconstrained_empty/Nargo.toml b/test_programs/execution_success/unconstrained_empty/Nargo.toml deleted file mode 100644 index 48d0f5938d8..00000000000 --- a/test_programs/execution_success/unconstrained_empty/Nargo.toml +++ /dev/null @@ -1,5 +0,0 @@ -[package] -name = "unconstrained_empty" -type = "bin" -authors = [""] -[dependencies] diff --git a/test_programs/execution_success/unconstrained_empty/src/main.nr b/test_programs/execution_success/unconstrained_empty/src/main.nr deleted file mode 100644 index 5e5fb297236..00000000000 --- a/test_programs/execution_success/unconstrained_empty/src/main.nr +++ /dev/null @@ -1 +0,0 @@ -unconstrained fn main() {} diff --git a/test_programs/execution_success/brillig_signed_div/Nargo.toml b/test_programs/execution_success/wrapping_operations/Nargo.toml similarity index 65% rename from test_programs/execution_success/brillig_signed_div/Nargo.toml rename to test_programs/execution_success/wrapping_operations/Nargo.toml index 4bb9c5ecc1c..3a28b3461ec 100644 --- a/test_programs/execution_success/brillig_signed_div/Nargo.toml +++ b/test_programs/execution_success/wrapping_operations/Nargo.toml @@ -1,5 +1,5 @@ [package] -name = "brillig_signed_div" +name = "wrapping_operations" type = "bin" authors = [""] diff --git a/test_programs/execution_success/brillig_wrapping/Prover.toml b/test_programs/execution_success/wrapping_operations/Prover.toml similarity index 100% rename from test_programs/execution_success/brillig_wrapping/Prover.toml rename to test_programs/execution_success/wrapping_operations/Prover.toml diff --git a/test_programs/execution_success/brillig_wrapping/src/main.nr b/test_programs/execution_success/wrapping_operations/src/main.nr similarity index 79% rename from test_programs/execution_success/brillig_wrapping/src/main.nr rename to test_programs/execution_success/wrapping_operations/src/main.nr index 4153a466057..85fd65b193c 100644 --- a/test_programs/execution_success/brillig_wrapping/src/main.nr +++ b/test_programs/execution_success/wrapping_operations/src/main.nr @@ -1,6 +1,6 @@ use dep::std; -unconstrained fn main(x: u8, y: u8) { +fn main(x: u8, y: u8) { assert(std::wrapping_sub(x, 1) == y); assert(std::wrapping_add(y, 1) == x); assert(std::wrapping_mul(y, y) == 1); diff --git a/tooling/nargo_cli/build.rs b/tooling/nargo_cli/build.rs index 74042cf4e40..53c3966cb4c 100644 --- a/tooling/nargo_cli/build.rs +++ b/tooling/nargo_cli/build.rs @@ -38,6 +38,26 @@ fn main() { generate_compile_failure_tests(&mut test_file, &test_dir); } +/// Some tests are explicitly ignored in brillig due to them failing. +/// These should be fixed and removed from this list. +const IGNORED_BRILLIG_TESTS: [&str; 11] = [ + // Takes a very long time to execute as large loops do not get simplified. + &"regression_4709", + // bit sizes for bigint operation doesn't match up. + &"bigint", + // ICE due to looking for function which doesn't exist. + &"fold_after_inlined_calls", + &"fold_basic", + &"fold_basic_nested_call", + &"fold_call_witness_condition", + &"fold_complex_outputs", + &"fold_distinct_return", + &"fold_fibonacci", + &"fold_numeric_generic_poseidon", + // Expected to fail as test asserts on which runtime it is in. + &"is_unconstrained", +]; + fn generate_execution_success_tests(test_file: &mut File, test_data_dir: &Path) { let test_sub_dir = "execution_success"; let test_data_dir = test_data_dir.join(test_sub_dir); @@ -55,6 +75,9 @@ fn generate_execution_success_tests(test_file: &mut File, test_data_dir: &Path) }; let test_dir = &test_dir.path(); + let brillig_ignored = + if IGNORED_BRILLIG_TESTS.contains(&test_name.as_str()) { "\n#[ignore]" } else { "" }; + write!( test_file, r#" @@ -66,6 +89,17 @@ fn execution_success_{test_name}() {{ cmd.arg("--program-dir").arg(test_program_dir); cmd.arg("execute").arg("--force"); + cmd.assert().success(); +}} + +#[test]{brillig_ignored} +fn execution_success_{test_name}_brillig() {{ + let test_program_dir = PathBuf::from("{test_dir}"); + + let mut cmd = Command::cargo_bin("nargo").unwrap(); + cmd.arg("--program-dir").arg(test_program_dir); + cmd.arg("execute").arg("--force").arg("--force-brillig"); + cmd.assert().success(); }} "#, From 69eca9b8671fa54192bef814dd584fdb5387a5f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Wed, 29 May 2024 18:58:01 +0200 Subject: [PATCH 47/61] feat: Separate runtimes of SSA functions before inlining (#5121) # Description ## Problem\* Resolves https://github.com/noir-lang/noir/issues/5043
Opcode count of Aztec public functions before => after this change in the inlining strategy ``` _approve_bridge_and_exit_input_asset_to_L1 on contract Uniswap with size 3788 => 3166 _assert_token_is_same on contract TokenBridge with size 916 => 640 _assert_token_is_same on contract Uniswap with size 1845 => 1546 _borrow on contract Lending with size 10988 => 10152 _call_mint_on_token on contract TokenBridge with size 1427 => 1125 _check_deadline on contract Crowdfunding with size 1015 => 752 _deposit on contract Lending with size 1699 => 1220 _increase_public_balance on contract GasToken with size 1325 => 1103 _increase_public_balance on contract Token with size 1577 => 1201 _increase_public_balance on contract TokenBlacklist with size 1577 => 1201 _reduce_total_supply on contract Token with size 945 => 626 _reduce_total_supply on contract TokenBlacklist with size 945 => 626 _repay on contract Lending with size 6775 => 6284 _withdraw on contract Lending with size 10715 => 9850 add_args_return on contract AvmNestedCallsTest with size 15 => 15 add_args_return on contract AvmTest with size 15 => 15 add_storage_map on contract AvmTest with size 797 => 664 add_to_tally_public on contract EasyPrivateVoting with size 1496 => 1112 add_u128 on contract AvmTest with size 187 => 187 admin on contract Token with size 495 => 348 approve_public_authwit on contract EcdsaAccount with size 977 => 718 approve_public_authwit on contract SchnorrAccount with size 743 => 621 approve_public_authwit on contract SchnorrHardcodedAccount with size 742 => 620 approve_public_authwit on contract SchnorrSingleKeyAccount with size 742 => 620 assert_block_number on contract AppSubscription with size 920 => 669 assert_minter_and_mint on contract Token with size 1434 => 1035 assert_not_expired on contract AppSubscription with size 910 => 658 assert_nullifier_exists on contract AvmTest with size 242 => 156 assert_public_global_vars on contract Test with size 1054 => 679 assert_same on contract AvmNestedCallsTest with size 138 => 138 assert_unsiloed_nullifier_acvm on contract AvmAcvmInteropTest with size 102 => 16 assertion_failure on contract AvmTest with size 166 => 166 avm_to_acvm_call on contract AvmAcvmInteropTest with size 287 => 169 balance_of_public on contract GasToken with size 651 => 612 balance_of_public on contract Token with size 880 => 710 balance_of_public on contract TokenBlacklist with size 880 => 710 borrow_public on contract Lending with size 1193 => 939 broadcast on contract Benchmarking with size 419 => 337 burn_public on contract Token with size 2426 => 1962 burn_public on contract TokenBlacklist with size 3148 => 2468 call_acvm_from_avm on contract AvmAcvmInteropTest with size 574 => 503 call_avm_from_acvm on contract AvmAcvmInteropTest with size 578 => 507 check_balance on contract GasToken with size 856 => 768 check_selector on contract AvmTest with size 463 => 463 claim_public on contract GasToken with size 3963 => 3416 claim_public on contract TokenBridge with size 4176 => 3457 constant_field_acvm on contract AvmAcvmInteropTest with size 13 => 13 constant_field_avm on contract AvmAcvmInteropTest with size 13 => 13 constructor on contract AppSubscription with size 3376 => 1983 constructor on contract Auth with size 1414 => 994 constructor on contract AvmInitializerTest with size 1290 => 908 constructor on contract Claim with size 1700 => 1123 constructor on contract EasyPrivateVoting with size 1454 => 941 constructor on contract FPC with size 1700 => 1123 constructor on contract InclusionProofs with size 1021 => 704 constructor on contract Token with size 2737 => 1961 constructor on contract TokenBlacklist with size 1925 => 1285 constructor on contract TokenBridge with size 1400 => 924 constructor on contract Uniswap with size 1326 => 909 consume_message_from_arbitrary_sender_public on contract Test with size 2203 => 1893 consume_mint_public_message on contract Test with size 2910 => 2600 create_different_nullifier_in_nested_call on contract AvmNestedCallsTest with size 743 => 639 create_l2_to_l1_message_arbitrary_recipient_public on contract Test with size 56 => 12 create_l2_to_l1_message_public on contract Test with size 73 => 29 create_same_nullifier_in_nested_call on contract AvmNestedCallsTest with size 741 => 637 debug_logging on contract AvmTest with size 725 => 402 deposit_public on contract Lending with size 2286 => 1846 dummy_public_call on contract Test with size 354 => 284 emit_nullifier_and_check on contract AvmTest with size 436 => 314 emit_nullifier_public on contract Test with size 47 => 11 emit_unencrypted on contract Test with size 54 => 16 emit_unencrypted_log on contract AvmTest with size 757 => 685 end_vote on contract EasyPrivateVoting with size 514 => 279 exit_to_l1_public on contract TokenBridge with size 2154 => 1773 get_address on contract AvmTest with size 45 => 13 get_args_hash on contract AvmTest with size 18 => 18 get_asset on contract Lending with size 888 => 718 get_assets on contract Lending with size 587 => 411 get_authorized on contract Auth with size 597 => 443 get_authorized_delay on contract Auth with size 702 => 517 get_block_number on contract AvmTest with size 45 => 13 get_chain_id on contract AvmTest with size 45 => 13 get_fee_per_da_gas on contract AvmTest with size 45 => 13 get_fee_per_l2_gas on contract AvmTest with size 45 => 13 get_portal_address_public on contract TokenBridge with size 297 => 145 get_position on contract Lending with size 3908 => 3623 get_price on contract PriceFeed with size 617 => 579 get_public_value on contract StatefulTest with size 636 => 598 get_roles on contract TokenBlacklist with size 989 => 749 get_scheduled_authorized on contract Auth with size 595 => 443 get_sender on contract AvmTest with size 45 => 13 get_shared_immutable_constrained_public on contract DocsExample with size 438 => 406 get_shared_immutable_constrained_public_indirect on contract DocsExample with size 701 => 607 get_shared_immutable_constrained_public_multiple on contract DocsExample with size 136 => 98 get_storage_address on contract AvmTest with size 45 => 13 get_timestamp on contract AvmTest with size 45 => 13 get_token on contract TokenBridge with size 513 => 366 get_transaction_fee on contract AvmTest with size 45 => 13 get_version on contract AvmTest with size 45 => 13 increment_balance on contract Benchmarking with size 1472 => 1264 increment_public_value on contract StatefulTest with size 695 => 449 increment_public_value_no_init_check on contract StatefulTest with size 447 => 351 init on contract Crowdfunding with size 2100 => 1341 init on contract Lending with size 958 => 598 initialize_public_immutable on contract DocsExample with size 433 => 252 initialize_shared_immutable on contract DocsExample with size 433 => 252 is_minter on contract Token with size 838 => 668 is_time_equal on contract Test with size 56 => 18 keccak_hash on contract AvmTest with size 49 => 49 l1_to_l2_msg_exists on contract AvmTest with size 65 => 17 mint_private on contract Token with size 1247 => 790 mint_private on contract TokenBlacklist with size 1495 => 906 mint_public on contract GasToken with size 946 => 813 mint_public on contract Token with size 2048 => 1520 mint_public on contract TokenBlacklist with size 2821 => 2137 modulo2 on contract AvmTest with size 16 => 16 nested_call_to_add on contract AvmNestedCallsTest with size 862 => 756 nested_call_to_add_with_gas on contract AvmNestedCallsTest with size 929 => 799 nested_static_call_to_add on contract AvmNestedCallsTest with size 890 => 784 nested_static_call_to_set_storage on contract AvmNestedCallsTest with size 759 => 665 new_note_hash on contract AvmTest with size 47 => 11 new_nullifier on contract AvmAcvmInteropTest with size 47 => 11 new_nullifier on contract AvmNestedCallsTest with size 47 => 11 new_nullifier on contract AvmTest with size 47 => 11 new_nullifier_acvm on contract AvmAcvmInteropTest with size 47 => 11 note_hash_exists on contract AvmTest with size 65 => 17 nullifier_collision on contract AvmTest with size 82 => 12 nullifier_exists on contract AvmTest with size 103 => 17 on_card_played on contract CardGame with size 2386 => 2151 on_cards_claimed on contract CardGame with size 2176 => 1927 on_game_joined on contract CardGame with size 1972 => 1733 pay_refund on contract FPC with size 2052 => 1685 pay_refund_with_shielded_rebate on contract FPC with size 2138 => 1771 pedersen_hash on contract AvmTest with size 19 => 19 pedersen_hash_with_index on contract AvmTest with size 19 => 19 poseidon2_hash on contract AvmTest with size 1370 => 1370 prepare_fee on contract FPC with size 1643 => 1280 pub_call_public_fn on contract ImportTest with size 710 => 636 pub_entry_point on contract Parent with size 263 => 189 pub_entry_point_twice on contract Parent with size 497 => 339 pub_get_value on contract Child with size 174 => 22 pub_get_value on contract StaticChild with size 409 => 281 pub_illegal_inc_value on contract StaticChild with size 448 => 336 pub_inc_value on contract Child with size 175 => 45 pub_inc_value on contract StaticChild with size 175 => 45 pub_inc_value_internal on contract Child with size 552 => 340 pub_set_value on contract Child with size 108 => 30 pub_set_value on contract StaticChild with size 108 => 30 public_call on contract StaticParent with size 263 => 189 public_constructor on contract StatefulTest with size 1808 => 1399 public_delegate_set_value on contract Delegator with size 724 => 724 public_get_decimals on contract Token with size 557 => 411 public_get_name on contract Token with size 538 => 392 public_get_symbol on contract Token with size 546 => 400 public_get_value_from_child on contract StaticParent with size 759 => 685 public_nested_static_call on contract Parent with size 674 => 561 public_nested_static_call on contract StaticParent with size 1012 => 894 public_set_value on contract DelegatedOn with size 68 => 28 public_static_call on contract Parent with size 328 => 236 public_static_call on contract StaticParent with size 328 => 236 push_nullifier_public on contract InclusionProofs with size 285 => 117 read_storage_immutable on contract AvmInitializerTest with size 286 => 133 read_storage_list on contract AvmTest with size 101 => 62 read_storage_map on contract AvmTest with size 385 => 341 read_storage_single on contract AvmTest with size 66 => 27 register on contract KeyRegistry with size 6385 => 5041 repay_public on contract Lending with size 2141 => 1747 rotate_npk_m on contract KeyRegistry with size 2592 => 1843 send_l2_to_l1_msg on contract AvmTest with size 56 => 12 set_admin on contract Token with size 528 => 257 set_authorized on contract Auth with size 925 => 474 set_authorized_delay on contract Auth with size 679 => 400 set_minter on contract Token with size 865 => 559 set_opcode_big_field on contract AvmTest with size 19 => 19 set_opcode_small_field on contract AvmTest with size 13 => 13 set_opcode_u32 on contract AvmTest with size 13 => 13 set_opcode_u64 on contract AvmTest with size 13 => 13 set_opcode_u8 on contract AvmTest with size 13 => 13 set_portal on contract GasToken with size 434 => 272 set_price on contract PriceFeed with size 401 => 349 set_read_storage_single on contract AvmTest with size 122 => 42 set_storage_list on contract AvmTest with size 76 => 30 set_storage_map on contract AvmTest with size 409 => 355 set_storage_single on contract AvmNestedCallsTest with size 65 => 25 set_storage_single on contract AvmTest with size 65 => 25 set_value_twice_with_nested_first on contract Child with size 803 => 654 set_value_twice_with_nested_last on contract Child with size 791 => 654 set_value_with_two_nested_calls on contract Child with size 1308 => 1063 sha256_hash on contract AvmTest with size 47 => 47 shield on contract Token with size 2368 => 1809 shield on contract TokenBlacklist with size 3102 => 2315 spend_public_authwit on contract DocsExample with size 14 => 14 spend_public_authwit on contract EcdsaAccount with size 1008 => 637 spend_public_authwit on contract SchnorrAccount with size 770 => 541 spend_public_authwit on contract SchnorrHardcodedAccount with size 770 => 540 spend_public_authwit on contract SchnorrSingleKeyAccount with size 770 => 540 spend_public_authwit on contract Uniswap with size 749 => 486 start_game on contract CardGame with size 2518 => 2175 swap_public on contract Uniswap with size 7983 => 6584 test_authwit_send_money on contract AvmAcvmInteropTest with size 803 => 709 test_get_contract_instance on contract AvmTest with size 522 => 410 test_get_contract_instance_raw on contract AvmTest with size 159 => 83 test_nullifier_inclusion_from_public on contract InclusionProofs with size 332 => 121 to_radix_le on contract AvmTest with size 187 => 187 total_supply on contract Token with size 536 => 390 total_supply on contract TokenBlacklist with size 536 => 390 transfer_public on contract Token with size 3071 => 2512 transfer_public on contract TokenBlacklist with size 4491 => 3533 u128_addition_overflow on contract AvmTest with size 772 => 668 u128_from_integer_overflow on contract AvmTest with size 357 => 357 update_accumulator on contract Lending with size 8695 => 8358 update_leader on contract DocsExample with size 430 => 290 update_roles on contract TokenBlacklist with size 2058 => 1252 withdraw_public on contract Lending with size 1190 => 93 ```
## Summary\* This PR: - Creates a separate pass for "runtime separation" where we convert any Acir function called from brillig to a brillig function. After that pass, all functions have correct runtime, meaning they'll be converted to the runtime they hold. - Updates the inliner to only consider entry points all brillig functions called from ACIR and all brillig recursive functions, instead of all brillig functions With this change the inliner can correctly detect which brillig functions **must not** be inlined. This opens the door to allowing annotating brillig functions with inlining suggestions in the future. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- acvm-repo/brillig_vm/src/memory.rs | 6 + compiler/noirc_evaluator/src/ssa.rs | 3 +- compiler/noirc_evaluator/src/ssa/ir/dfg.rs | 2 +- .../noirc_evaluator/src/ssa/ir/function.rs | 7 + compiler/noirc_evaluator/src/ssa/ir/map.rs | 2 +- .../noirc_evaluator/src/ssa/opt/inlining.rs | 160 ++++++-- compiler/noirc_evaluator/src/ssa/opt/mod.rs | 1 + .../src/ssa/opt/runtime_separation.rs | 348 ++++++++++++++++++ .../src/ssa/ssa_gen/program.rs | 8 + .../acir_inside_brillig_recursion/Nargo.toml | 6 + .../acir_inside_brillig_recursion/Prover.toml | 1 + .../acir_inside_brillig_recursion/src/main.nr | 15 + tooling/debugger/ignored-tests.txt | 27 +- 13 files changed, 531 insertions(+), 55 deletions(-) create mode 100644 compiler/noirc_evaluator/src/ssa/opt/runtime_separation.rs create mode 100644 test_programs/execution_success/acir_inside_brillig_recursion/Nargo.toml create mode 100644 test_programs/execution_success/acir_inside_brillig_recursion/Prover.toml create mode 100644 test_programs/execution_success/acir_inside_brillig_recursion/src/main.nr diff --git a/acvm-repo/brillig_vm/src/memory.rs b/acvm-repo/brillig_vm/src/memory.rs index 4092cd06ae0..6c6b5968cd7 100644 --- a/acvm-repo/brillig_vm/src/memory.rs +++ b/acvm-repo/brillig_vm/src/memory.rs @@ -294,6 +294,12 @@ impl Memory { } pub fn read_slice(&self, addr: MemoryAddress, len: usize) -> &[MemoryValue] { + // Allows to read a slice of uninitialized memory if the length is zero. + // Ideally we'd be able to read uninitialized memory in general (as read does) + // but that's not possible if we want to return a slice instead of owned data. + if len == 0 { + return &[]; + } &self.inner[addr.to_usize()..(addr.to_usize() + len)] } diff --git a/compiler/noirc_evaluator/src/ssa.rs b/compiler/noirc_evaluator/src/ssa.rs index d38601bfc1b..80a63f223e7 100644 --- a/compiler/noirc_evaluator/src/ssa.rs +++ b/compiler/noirc_evaluator/src/ssa.rs @@ -58,8 +58,9 @@ pub(crate) fn optimize_into_acir( let ssa = SsaBuilder::new(program, print_passes, force_brillig_output, print_timings)? .run_pass(Ssa::defunctionalize, "After Defunctionalization:") .run_pass(Ssa::remove_paired_rc, "After Removing Paired rc_inc & rc_decs:") - .run_pass(Ssa::inline_functions, "After Inlining:") + .run_pass(Ssa::separate_runtime, "After Runtime Separation:") .run_pass(Ssa::resolve_is_unconstrained, "After Resolving IsUnconstrained:") + .run_pass(Ssa::inline_functions, "After Inlining:") // Run mem2reg with the CFG separated into blocks .run_pass(Ssa::mem2reg, "After Mem2Reg:") .run_pass(Ssa::as_slice_optimization, "After `as_slice` optimization") diff --git a/compiler/noirc_evaluator/src/ssa/ir/dfg.rs b/compiler/noirc_evaluator/src/ssa/ir/dfg.rs index 545827df1c5..f763ae52d50 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/dfg.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/dfg.rs @@ -22,7 +22,7 @@ use noirc_errors::Location; /// its blocks, instructions, and values. This struct is largely responsible for /// owning most data in a function and handing out Ids to this data that can be /// shared without worrying about ownership. -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone)] pub(crate) struct DataFlowGraph { /// All of the instructions in a function instructions: DenseMap, diff --git a/compiler/noirc_evaluator/src/ssa/ir/function.rs b/compiler/noirc_evaluator/src/ssa/ir/function.rs index a49e02b0380..c44824b464b 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/function.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/function.rs @@ -64,6 +64,13 @@ impl Function { Self { name, id, entry_block, dfg, runtime: RuntimeType::Acir(InlineType::default()) } } + /// Creates a new function as a clone of the one passed in with the passed in id. + pub(crate) fn clone_with_id(id: FunctionId, another: &Function) -> Self { + let dfg = another.dfg.clone(); + let entry_block = another.entry_block; + Self { name: another.name.clone(), id, entry_block, dfg, runtime: another.runtime } + } + /// The name of the function. /// Used exclusively for debugging purposes. pub(crate) fn name(&self) -> &str { diff --git a/compiler/noirc_evaluator/src/ssa/ir/map.rs b/compiler/noirc_evaluator/src/ssa/ir/map.rs index b6055973f1c..3c3feabc390 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/map.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/map.rs @@ -115,7 +115,7 @@ impl std::fmt::Display for Id { /// access to indices is provided. Since IDs must be stable and correspond /// to indices in the internal Vec, operations that would change element /// ordering like pop, remove, swap_remove, etc, are not possible. -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct DenseMap { storage: Vec, } diff --git a/compiler/noirc_evaluator/src/ssa/opt/inlining.rs b/compiler/noirc_evaluator/src/ssa/opt/inlining.rs index 1293671da50..e2a7f51d0a0 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/inlining.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/inlining.rs @@ -27,7 +27,7 @@ const RECURSION_LIMIT: u32 = 1000; impl Ssa { /// Inline all functions within the IR. /// - /// In the case of recursive functions, this will attempt + /// In the case of recursive Acir functions, this will attempt /// to recursively inline until the RECURSION_LIMIT is reached. /// /// Functions are recursively inlined into main until either we finish @@ -41,6 +41,8 @@ impl Ssa { /// There are some attributes that allow inlining a function at a different step of codegen. /// Currently this is just `InlineType::NoPredicates` for which we have a flag indicating /// whether treating that inline functions. The default is to treat these functions as entry points. + /// + /// This step should run after runtime separation, since it relies on the runtime of the called functions being final. #[tracing::instrument(level = "trace", skip(self))] pub(crate) fn inline_functions(self) -> Ssa { Self::inline_functions_inner(self, true) @@ -52,12 +54,17 @@ impl Ssa { } fn inline_functions_inner(mut self, no_predicates_is_entry_point: bool) -> Ssa { + let recursive_functions = find_all_recursive_functions(&self); self.functions = btree_map( - get_entry_point_functions(&self, no_predicates_is_entry_point), + get_functions_to_inline_into(&self, no_predicates_is_entry_point), |entry_point| { - let new_function = - InlineContext::new(&self, entry_point, no_predicates_is_entry_point) - .inline_all(&self); + let new_function = InlineContext::new( + &self, + entry_point, + no_predicates_is_entry_point, + recursive_functions.clone(), + ) + .inline_all(&self); (entry_point, new_function) }, ); @@ -80,6 +87,8 @@ struct InlineContext { entry_point: FunctionId, no_predicates_is_entry_point: bool, + // We keep track of the recursive functions in the SSA to avoid inlining them in a brillig context. + recursive_functions: BTreeSet, } /// The per-function inlining context contains information that is only valid for one function. @@ -113,28 +122,101 @@ struct PerFunctionContext<'function> { inlining_entry: bool, } -/// The entry point functions are each function we should inline into - and each function that -/// should be left in the final program. -/// This is the `main` function, any Acir functions with a [fold inline type][InlineType::Fold], -/// and any brillig functions used. -fn get_entry_point_functions( +/// Utility function to find out the direct calls of a function. +fn called_functions(func: &Function) -> BTreeSet { + let mut called_function_ids = BTreeSet::default(); + for block_id in func.reachable_blocks() { + for instruction_id in func.dfg[block_id].instructions() { + let Instruction::Call { func: called_value_id, .. } = &func.dfg[*instruction_id] else { + continue; + }; + + if let Value::Function(function_id) = func.dfg[*called_value_id] { + called_function_ids.insert(function_id); + } + } + } + + called_function_ids +} + +// Recursively explore the SSA to find the functions that end up calling themselves +fn find_recursive_functions( + ssa: &Ssa, + current_function: FunctionId, + mut explored_functions: im::HashSet, + recursive_functions: &mut BTreeSet, +) { + if explored_functions.contains(¤t_function) { + recursive_functions.insert(current_function); + return; + } + + let called_functions = called_functions(&ssa.functions[¤t_function]); + + explored_functions.insert(current_function); + + for called_function in called_functions { + find_recursive_functions( + ssa, + called_function, + explored_functions.clone(), + recursive_functions, + ); + } +} + +fn find_all_recursive_functions(ssa: &Ssa) -> BTreeSet { + let mut recursive_functions = BTreeSet::default(); + find_recursive_functions(ssa, ssa.main_id, im::HashSet::default(), &mut recursive_functions); + recursive_functions +} + +/// The functions we should inline into (and that should be left in the final program) are: +/// - main +/// - Any Brillig function called from Acir +/// - Any Brillig recursive function (Acir recursive functions will be inlined into the main function) +/// - Any Acir functions with a [fold inline type][InlineType::Fold], +fn get_functions_to_inline_into( ssa: &Ssa, no_predicates_is_entry_point: bool, ) -> BTreeSet { - let functions = ssa.functions.iter(); - let mut entry_points = functions - .filter(|(_, function)| { - // If we have not already finished the flattening pass, functions marked - // to not have predicates should be marked as entry points. - let no_predicates_is_entry_point = - no_predicates_is_entry_point && function.is_no_predicates(); - function.runtime().is_entry_point() || no_predicates_is_entry_point + let mut brillig_entry_points = BTreeSet::default(); + let mut acir_entry_points = BTreeSet::default(); + + for (func_id, function) in ssa.functions.iter() { + if function.runtime() == RuntimeType::Brillig { + continue; + } + + // If we have not already finished the flattening pass, functions marked + // to not have predicates should be marked as entry points. + let no_predicates_is_entry_point = + no_predicates_is_entry_point && function.is_no_predicates(); + if function.runtime().is_entry_point() || no_predicates_is_entry_point { + acir_entry_points.insert(*func_id); + } + + for called_function_id in called_functions(function) { + if ssa.functions[&called_function_id].runtime() == RuntimeType::Brillig { + brillig_entry_points.insert(called_function_id); + } + } + } + + let brillig_recursive_functions: BTreeSet<_> = find_all_recursive_functions(ssa) + .into_iter() + .filter(|recursive_function_id| { + let function = &ssa.functions[&recursive_function_id]; + function.runtime() == RuntimeType::Brillig }) - .map(|(id, _)| *id) - .collect::>(); + .collect(); - entry_points.insert(ssa.main_id); - entry_points + std::iter::once(ssa.main_id) + .chain(acir_entry_points) + .chain(brillig_entry_points) + .chain(brillig_recursive_functions) + .collect() } impl InlineContext { @@ -147,6 +229,7 @@ impl InlineContext { ssa: &Ssa, entry_point: FunctionId, no_predicates_is_entry_point: bool, + recursive_functions: BTreeSet, ) -> InlineContext { let source = &ssa.functions[&entry_point]; let mut builder = FunctionBuilder::new(source.name().to_owned(), entry_point); @@ -157,6 +240,7 @@ impl InlineContext { entry_point, call_stack: CallStack::new(), no_predicates_is_entry_point, + recursive_functions, } } @@ -391,18 +475,10 @@ impl<'function> PerFunctionContext<'function> { match &self.source_function.dfg[*id] { Instruction::Call { func, arguments } => match self.get_function(*func) { Some(func_id) => { - let function = &ssa.functions[&func_id]; - // If we have not already finished the flattening pass, functions marked - // to not have predicates should be marked as entry points unless we are inlining into brillig. - let entry_point = &ssa.functions[&self.context.entry_point]; - let no_predicates_is_entry_point = - self.context.no_predicates_is_entry_point - && function.is_no_predicates() - && !matches!(entry_point.runtime(), RuntimeType::Brillig); - if function.runtime().is_entry_point() || no_predicates_is_entry_point { - self.push_instruction(*id); - } else { + if self.should_inline_call(ssa, func_id) { self.inline_function(ssa, *id, func_id, arguments); + } else { + self.push_instruction(*id); } } None => self.push_instruction(*id), @@ -412,6 +488,24 @@ impl<'function> PerFunctionContext<'function> { } } + fn should_inline_call(&self, ssa: &Ssa, called_func_id: FunctionId) -> bool { + let function = &ssa.functions[&called_func_id]; + + if let RuntimeType::Acir(inline_type) = function.runtime() { + // If the called function is acir, we inline if it's not an entry point + + // If we have not already finished the flattening pass, functions marked + // to not have predicates should be marked as entry points. + let no_predicates_is_entry_point = + self.context.no_predicates_is_entry_point && function.is_no_predicates(); + !inline_type.is_entry_point() && !no_predicates_is_entry_point + } else { + // If the called function is brillig, we inline only if it's into brillig and the function is not recursive + ssa.functions[&self.context.entry_point].runtime() == RuntimeType::Brillig + && !self.context.recursive_functions.contains(&called_func_id) + } + } + /// Inline a function call and remember the inlined return values in the values map fn inline_function( &mut self, diff --git a/compiler/noirc_evaluator/src/ssa/opt/mod.rs b/compiler/noirc_evaluator/src/ssa/opt/mod.rs index f6c3f022bfc..4e5fa262696 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/mod.rs @@ -18,5 +18,6 @@ mod remove_bit_shifts; mod remove_enable_side_effects; mod remove_if_else; mod resolve_is_unconstrained; +mod runtime_separation; mod simplify_cfg; mod unrolling; diff --git a/compiler/noirc_evaluator/src/ssa/opt/runtime_separation.rs b/compiler/noirc_evaluator/src/ssa/opt/runtime_separation.rs new file mode 100644 index 00000000000..c0c9c0a1372 --- /dev/null +++ b/compiler/noirc_evaluator/src/ssa/opt/runtime_separation.rs @@ -0,0 +1,348 @@ +use std::collections::BTreeSet; + +use fxhash::{FxHashMap as HashMap, FxHashSet as HashSet}; + +use crate::ssa::{ + ir::{ + function::{Function, FunctionId, RuntimeType}, + instruction::Instruction, + value::{Value, ValueId}, + }, + ssa_gen::Ssa, +}; + +impl Ssa { + /// This optimization step separates the runtime of the functions in the SSA. + /// After this step, all functions with runtime `Acir` will be converted to Acir and + /// the functions with runtime `Brillig` will be converted to Brillig. + /// It does so by cloning all ACIR functions called from a Brillig context + /// and changing the runtime of the cloned functions to Brillig. + /// This pass needs to run after functions as values have been resolved (defunctionalization). + #[tracing::instrument(level = "trace", skip(self))] + pub(crate) fn separate_runtime(mut self) -> Self { + RuntimeSeparatorContext::separate_runtime(&mut self); + self + } +} + +#[derive(Debug, Default)] +struct RuntimeSeparatorContext { + // Original functions to clone to brillig + acir_functions_called_from_brillig: BTreeSet, + // Tracks the original => cloned version + mapped_functions: HashMap, +} + +impl RuntimeSeparatorContext { + pub(crate) fn separate_runtime(ssa: &mut Ssa) { + let mut runtime_separator = RuntimeSeparatorContext::default(); + + // We first collect all the acir functions called from a brillig context by exploring the SSA recursively + let mut processed_functions = HashSet::default(); + runtime_separator.collect_acir_functions_called_from_brillig( + ssa, + ssa.main_id, + false, + &mut processed_functions, + ); + + // Now we clone the relevant acir functions and change their runtime to brillig + runtime_separator.convert_acir_functions_called_from_brillig_to_brillig(ssa); + + // Now we update any calls within a brillig context to the mapped functions + runtime_separator.replace_calls_to_mapped_functions(ssa); + + // Some functions might be unreachable now (for example an acir function only called from brillig) + prune_unreachable_functions(ssa); + } + + fn collect_acir_functions_called_from_brillig( + &mut self, + ssa: &Ssa, + current_func_id: FunctionId, + mut within_brillig: bool, + processed_functions: &mut HashSet<(/* within_brillig */ bool, FunctionId)>, + ) { + // Processed functions needs the within brillig flag, since it is possible to call the same function from both brillig and acir + if processed_functions.contains(&(within_brillig, current_func_id)) { + return; + } + processed_functions.insert((within_brillig, current_func_id)); + + let func = &ssa.functions[¤t_func_id]; + if func.runtime() == RuntimeType::Brillig { + within_brillig = true; + } + + let called_functions = called_functions(func); + + if within_brillig { + for called_func_id in called_functions.iter() { + let called_func = &ssa.functions[&called_func_id]; + if matches!(called_func.runtime(), RuntimeType::Acir(_)) { + self.acir_functions_called_from_brillig.insert(*called_func_id); + } + } + } + + for called_func_id in called_functions.into_iter() { + self.collect_acir_functions_called_from_brillig( + ssa, + called_func_id, + within_brillig, + processed_functions, + ); + } + } + + fn convert_acir_functions_called_from_brillig_to_brillig(&mut self, ssa: &mut Ssa) { + for acir_func_id in self.acir_functions_called_from_brillig.iter() { + let cloned_id = ssa.clone_fn(*acir_func_id); + let new_func = + ssa.functions.get_mut(&cloned_id).expect("Cloned function should exist in SSA"); + new_func.set_runtime(RuntimeType::Brillig); + self.mapped_functions.insert(*acir_func_id, cloned_id); + } + } + + fn replace_calls_to_mapped_functions(&self, ssa: &mut Ssa) { + for (_function_id, func) in ssa.functions.iter_mut() { + if func.runtime() == RuntimeType::Brillig { + for called_func_value_id in called_functions_values(func).iter() { + let Value::Function(called_func_id) = &func.dfg[*called_func_value_id] else { + unreachable!("Value should be a function") + }; + if let Some(mapped_func_id) = self.mapped_functions.get(called_func_id) { + let mapped_value_id = func.dfg.import_function(*mapped_func_id); + func.dfg.set_value_from_id(*called_func_value_id, mapped_value_id); + } + } + } + } + } +} + +// We only consider direct calls to functions since functions as values should have been resolved +fn called_functions_values(func: &Function) -> BTreeSet { + let mut called_function_ids = BTreeSet::default(); + for block_id in func.reachable_blocks() { + for instruction_id in func.dfg[block_id].instructions() { + let Instruction::Call { func: called_value_id, .. } = &func.dfg[*instruction_id] else { + continue; + }; + + if let Value::Function(_) = func.dfg[*called_value_id] { + called_function_ids.insert(*called_value_id); + } + } + } + + called_function_ids +} + +fn called_functions(func: &Function) -> BTreeSet { + called_functions_values(func) + .into_iter() + .map(|value_id| { + let Value::Function(func_id) = func.dfg[value_id] else { + unreachable!("Value should be a function") + }; + func_id + }) + .collect() +} + +fn collect_reachable_functions( + ssa: &Ssa, + current_func_id: FunctionId, + reachable_functions: &mut HashSet, +) { + if reachable_functions.contains(¤t_func_id) { + return; + } + reachable_functions.insert(current_func_id); + + let func = &ssa.functions[¤t_func_id]; + let called_functions = called_functions(func); + + for called_func_id in called_functions.iter() { + collect_reachable_functions(ssa, *called_func_id, reachable_functions); + } +} + +fn prune_unreachable_functions(ssa: &mut Ssa) { + let mut reachable_functions = HashSet::default(); + collect_reachable_functions(ssa, ssa.main_id, &mut reachable_functions); + + ssa.functions.retain(|id, _value| reachable_functions.contains(id)); +} + +#[cfg(test)] +mod test { + use std::collections::BTreeSet; + + use noirc_frontend::monomorphization::ast::InlineType; + + use crate::ssa::{ + function_builder::FunctionBuilder, + ir::{ + function::{Function, FunctionId, RuntimeType}, + map::Id, + types::Type, + }, + opt::runtime_separation::called_functions, + ssa_gen::Ssa, + }; + + #[test] + fn basic_runtime_separation() { + // brillig fn foo { + // b0(): + // v0 = call bar() + // return v0 + // } + // acir fn bar { + // b0(): + // return 72 + // } + let foo_id = Id::test_new(0); + let mut builder = FunctionBuilder::new("foo".into(), foo_id); + builder.current_function.set_runtime(RuntimeType::Brillig); + + let bar_id = Id::test_new(1); + let bar = builder.import_function(bar_id); + let results = builder.insert_call(bar, Vec::new(), vec![Type::field()]).to_vec(); + builder.terminate_with_return(results); + + builder.new_function("bar".into(), bar_id, InlineType::default()); + let expected_return = 72u128; + let seventy_two = builder.field_constant(expected_return); + builder.terminate_with_return(vec![seventy_two]); + + let ssa = builder.finish(); + assert_eq!(ssa.functions.len(), 2); + + // Expected result + // brillig fn foo { + // b0(): + // v0 = call bar() + // return v0 + // } + // brillig fn bar { + // b0(): + // return 72 + // } + let separated = ssa.separate_runtime(); + + // The original bar function must have been pruned + assert_eq!(separated.functions.len(), 2); + + // All functions should be brillig now + for func in separated.functions.values() { + assert_eq!(func.runtime(), RuntimeType::Brillig); + } + } + + fn find_func_by_name<'ssa>( + ssa: &'ssa Ssa, + funcs: &BTreeSet, + name: &str, + ) -> &'ssa Function { + funcs + .iter() + .find_map(|id| { + let func = ssa.functions.get(id).unwrap(); + if func.name() == name { + Some(func) + } else { + None + } + }) + .unwrap() + } + + #[test] + fn same_function_shared_acir_brillig() { + // acir fn foo { + // b0(): + // v0 = call bar() + // v1 = call baz() + // return v0, v1 + // } + // brillig fn bar { + // b0(): + // v0 = call baz() + // return v0 + // } + // acir fn baz { + // b0(): + // return 72 + // } + let foo_id = Id::test_new(0); + let mut builder = FunctionBuilder::new("foo".into(), foo_id); + + let bar_id = Id::test_new(1); + let baz_id = Id::test_new(2); + let bar = builder.import_function(bar_id); + let baz = builder.import_function(baz_id); + let v0 = builder.insert_call(bar, Vec::new(), vec![Type::field()]).to_vec(); + let v1 = builder.insert_call(baz, Vec::new(), vec![Type::field()]).to_vec(); + builder.terminate_with_return(vec![v0[0], v1[0]]); + + builder.new_brillig_function("bar".into(), bar_id); + let baz = builder.import_function(baz_id); + let v0 = builder.insert_call(baz, Vec::new(), vec![Type::field()]).to_vec(); + builder.terminate_with_return(v0); + + builder.new_function("baz".into(), baz_id, InlineType::default()); + let expected_return = 72u128; + let seventy_two = builder.field_constant(expected_return); + builder.terminate_with_return(vec![seventy_two]); + + let ssa = builder.finish(); + assert_eq!(ssa.functions.len(), 3); + + // Expected result + // acir fn foo { + // b0(): + // v0 = call bar() + // v1 = call baz() <- baz_acir + // return v0, v1 + // } + // brillig fn bar { + // b0(): + // v0 = call baz() <- baz_brillig + // return v0 + // } + // acir fn baz { + // b0(): + // return 72 + // } + // brillig fn baz { + // b0(): + // return 72 + // } + let separated = ssa.separate_runtime(); + + // The original baz function must have been duplicated + assert_eq!(separated.functions.len(), 4); + + let main_function = separated.functions.get(&separated.main_id).unwrap(); + assert_eq!(main_function.runtime(), RuntimeType::Acir(InlineType::Inline)); + + let main_calls = called_functions(main_function); + assert_eq!(main_calls.len(), 2); + + let bar = find_func_by_name(&separated, &main_calls, "bar"); + let baz_acir = find_func_by_name(&separated, &main_calls, "baz"); + + assert_eq!(baz_acir.runtime(), RuntimeType::Acir(InlineType::Inline)); + assert_eq!(bar.runtime(), RuntimeType::Brillig); + + let bar_calls = called_functions(bar); + assert_eq!(bar_calls.len(), 1); + + let baz_brillig = find_func_by_name(&separated, &bar_calls, "baz"); + assert_eq!(baz_brillig.runtime(), RuntimeType::Brillig); + } +} diff --git a/compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs b/compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs index 21178c55c73..7a77aa76101 100644 --- a/compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs +++ b/compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs @@ -80,6 +80,14 @@ impl Ssa { self.functions.insert(new_id, function); new_id } + + /// Clones an already existing function with a fresh id + pub(crate) fn clone_fn(&mut self, existing_function_id: FunctionId) -> FunctionId { + let new_id = self.next_id.next(); + let function = Function::clone_with_id(new_id, &self.functions[&existing_function_id]); + self.functions.insert(new_id, function); + new_id + } } impl Display for Ssa { diff --git a/test_programs/execution_success/acir_inside_brillig_recursion/Nargo.toml b/test_programs/execution_success/acir_inside_brillig_recursion/Nargo.toml new file mode 100644 index 00000000000..462532bb484 --- /dev/null +++ b/test_programs/execution_success/acir_inside_brillig_recursion/Nargo.toml @@ -0,0 +1,6 @@ +[package] +name = "acir_inside_brillig_recursion" +type = "bin" +authors = [""] + +[dependencies] diff --git a/test_programs/execution_success/acir_inside_brillig_recursion/Prover.toml b/test_programs/execution_success/acir_inside_brillig_recursion/Prover.toml new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/test_programs/execution_success/acir_inside_brillig_recursion/Prover.toml @@ -0,0 +1 @@ + diff --git a/test_programs/execution_success/acir_inside_brillig_recursion/src/main.nr b/test_programs/execution_success/acir_inside_brillig_recursion/src/main.nr new file mode 100644 index 00000000000..92f8524a771 --- /dev/null +++ b/test_programs/execution_success/acir_inside_brillig_recursion/src/main.nr @@ -0,0 +1,15 @@ +fn main() { + assert_eq(fibonacci(3), fibonacci_hint(3)); +} + +unconstrained fn fibonacci_hint(x: u32) -> u32 { + fibonacci(x) +} + +fn fibonacci(x: u32) -> u32 { + if x <= 1 { + x + } else { + fibonacci(x - 1) + fibonacci(x - 2) + } +} diff --git a/tooling/debugger/ignored-tests.txt b/tooling/debugger/ignored-tests.txt index a6d3c9a3a94..a9193896589 100644 --- a/tooling/debugger/ignored-tests.txt +++ b/tooling/debugger/ignored-tests.txt @@ -1,28 +1,17 @@ -array_dynamic_blackbox_input bigint -bit_shifts_comptime brillig_references brillig_to_bytes_integration debug_logs -double_verify_nested_proof -double_verify_proof -double_verify_proof_recursive -modulus -references -scalar_mul -signed_comparison -to_bytes_integration +fold_after_inlined_calls fold_basic fold_basic_nested_call fold_call_witness_condition -fold_after_inlined_calls -fold_numeric_generic_poseidon -no_predicates_basic -no_predicates_numeric_generic_poseidon -regression_4709 +fold_complex_outputs fold_distinct_return fold_fibonacci -fold_complex_outputs -slice_init_with_complex_type -hashmap -is_unconstrained \ No newline at end of file +fold_numeric_generic_poseidon +is_unconstrained +modulus +references +regression_4709 +to_bytes_integration \ No newline at end of file From 3afe023543e301aafaf2b79f0ccd6d7936dd53a9 Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Wed, 29 May 2024 20:31:51 +0100 Subject: [PATCH 48/61] fix(frontend): Resolve object types from method calls a single time (#5131) # Description ## Problem\* Resolves #5065 Probably resolves #4732 but need to test it or have aztec team test it. ## Summary\* When working with a program like such where `MyType` implements `MyTrait`: ```rust fn foo() -> T where T: MyTrait { MyTrait::new() } fn concise_regression() -> MyType { Wrapper::new(foo()).unwrap() } ``` We should be able to infer the return type of `foo`. We currently always push trait constraints onto a a `Vec<(TraitConstraint, ExprId)>`. We need to do this as we can have multiple trait constraints that need to be handled during monomorphization due to generics. However, when working with a method call this can cause us to store an old trait constraint that does not necessarily apply to the expression. The nested function call in `concise_regression` initially adds a trait constraint simply for `foo` due to the call to `Wrapper::new(foo())` and then another constraint for `Wrapper::new(foo()).unwrap()`. The call to `Wrapper::new(foo())` cannot be bound to anything unless we introduce an intermediate variable. This felt like it would be overly complex and we just need to follow the accurate trait constraint for a function call expression. Taking the test in the issue and this PR we have the following trait constraints on master for the `foo` expression: ``` TraitConstraint { typ: '23646 -> '23647, trait_id: TraitId( ModuleId { krate: Root( 1, ), local_id: LocalModuleId( Index( 1, ), ), }, ), trait_generics: [], }, TraitConstraint { typ: '23648 -> '23649 -> '23650 -> MyType, trait_id: TraitId( ModuleId { krate: Root( 1, ), local_id: LocalModuleId( Index( 1, ), ), }, ), trait_generics: [], } ``` This is occurring due to an unnecessary type check on a method call's object type. This is cause a repeated trait constraint where one has incorrect type variables that cannot be resolved. I have altered how MethodCall's and Call's are resolved as to avoid repeated type checks on the object type. ## Additional Context ## Documentation\* Check one: - [X] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [X] I have tested the changes locally. - [X] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: jfecher --- .../noirc_frontend/src/hir/type_check/expr.rs | 118 +++++++++++------- .../regression_5065_failure/Nargo.toml | 7 ++ .../regression_5065_failure/src/main.nr | 40 ++++++ .../regression_5065/Nargo.toml | 7 ++ .../regression_5065/src/main.nr | 45 +++++++ 5 files changed, 171 insertions(+), 46 deletions(-) create mode 100644 test_programs/compile_failure/regression_5065_failure/Nargo.toml create mode 100644 test_programs/compile_failure/regression_5065_failure/src/main.nr create mode 100644 test_programs/compile_success_empty/regression_5065/Nargo.toml create mode 100644 test_programs/compile_success_empty/regression_5065/src/main.nr diff --git a/compiler/noirc_frontend/src/hir/type_check/expr.rs b/compiler/noirc_frontend/src/hir/type_check/expr.rs index 336c1cedbb6..6504ead178f 100644 --- a/compiler/noirc_frontend/src/hir/type_check/expr.rs +++ b/compiler/noirc_frontend/src/hir/type_check/expr.rs @@ -2,6 +2,7 @@ use iter_extended::vecmap; use noirc_errors::Span; use crate::ast::{BinaryOpKind, IntegerBitSize, UnaryOp}; +use crate::hir_def::expr::HirCallExpression; use crate::macros_api::Signedness; use crate::{ hir::{resolution::resolver::verify_mutable_reference, type_check::errors::Source}, @@ -176,16 +177,6 @@ impl<'interner> TypeChecker<'interner> { } HirExpression::Index(index_expr) => self.check_index_expression(expr_id, index_expr), HirExpression::Call(call_expr) => { - // Need to setup these flags here as `self` is borrowed mutably to type check the rest of the call expression - // These flags are later used to type check calls to unconstrained functions from constrained functions - let current_func = self.current_function; - let func_mod = current_func.map(|func| self.interner.function_modifiers(&func)); - let is_current_func_constrained = - func_mod.map_or(true, |func_mod| !func_mod.is_unconstrained); - let is_unconstrained_call = self.is_unconstrained_call(&call_expr.func); - - self.check_if_deprecated(&call_expr.func); - let function = self.check_expression(&call_expr.func); let args = vecmap(&call_expr.arguments, |arg| { @@ -193,39 +184,13 @@ impl<'interner> TypeChecker<'interner> { (typ, *arg, self.interner.expr_span(arg)) }); - // Check that we are not passing a mutable reference from a constrained runtime to an unconstrained runtime - if is_current_func_constrained && is_unconstrained_call { - for (typ, _, _) in args.iter() { - if matches!(&typ.follow_bindings(), Type::MutableReference(_)) { - self.errors.push(TypeCheckError::ConstrainedReferenceToUnconstrained { - span: self.interner.expr_span(expr_id), - }); - return Type::Error; - } - } - } - let span = self.interner.expr_span(expr_id); - let return_type = self.bind_function_type(function, args, span); - - // Check that we are not passing a slice from an unconstrained runtime to a constrained runtime - if is_current_func_constrained && is_unconstrained_call { - if return_type.contains_slice() { - self.errors.push(TypeCheckError::UnconstrainedSliceReturnToConstrained { - span: self.interner.expr_span(expr_id), - }); - return Type::Error; - } else if matches!(&return_type.follow_bindings(), Type::MutableReference(_)) { - self.errors.push(TypeCheckError::UnconstrainedReferenceToConstrained { - span: self.interner.expr_span(expr_id), - }); - return Type::Error; - } - }; - - return_type + self.check_call(&call_expr, function, args, span) } HirExpression::MethodCall(mut method_call) => { + let method_call_span = self.interner.expr_span(expr_id); + let object = method_call.object; + let object_span = self.interner.expr_span(&method_call.object); let mut object_type = self.check_expression(&method_call.object).follow_bindings(); let method_name = method_call.method.0.contents.as_str(); match self.lookup_method(&object_type, method_name, expr_id) { @@ -259,19 +224,42 @@ impl<'interner> TypeChecker<'interner> { ); } + // These arguments will be given to the desugared function call. + // Compared to the method arguments, they also contain the object. + let mut function_args = Vec::with_capacity(method_call.arguments.len() + 1); + + function_args.push((object_type.clone(), object, object_span)); + + for arg in method_call.arguments.iter() { + let span = self.interner.expr_span(arg); + let typ = self.check_expression(arg); + function_args.push((typ, *arg, span)); + } + // TODO: update object_type here? - let (_, function_call) = method_call.into_function_call( + let ((function_id, _), function_call) = method_call.into_function_call( &method_ref, object_type, location, self.interner, ); - self.interner.replace_expr(expr_id, HirExpression::Call(function_call)); + let func_type = self.check_expression(&function_id); // Type check the new call now that it has been changed from a method call // to a function call. This way we avoid duplicating code. - self.check_expression(expr_id) + // We call `check_call` rather than `check_expression` directly as we want to avoid + // resolving the object type again once it is part of the arguments. + let typ = self.check_call( + &function_call, + func_type, + function_args, + method_call_span, + ); + + self.interner.replace_expr(expr_id, HirExpression::Call(function_call)); + + typ } None => Type::Error, } @@ -333,6 +321,45 @@ impl<'interner> TypeChecker<'interner> { typ } + fn check_call( + &mut self, + call: &HirCallExpression, + func_type: Type, + args: Vec<(Type, ExprId, Span)>, + span: Span, + ) -> Type { + // Need to setup these flags here as `self` is borrowed mutably to type check the rest of the call expression + // These flags are later used to type check calls to unconstrained functions from constrained functions + let func_mod = self.current_function.map(|func| self.interner.function_modifiers(&func)); + let is_current_func_constrained = + func_mod.map_or(true, |func_mod| !func_mod.is_unconstrained); + + let is_unconstrained_call = self.is_unconstrained_call(&call.func); + self.check_if_deprecated(&call.func); + + // Check that we are not passing a mutable reference from a constrained runtime to an unconstrained runtime + if is_current_func_constrained && is_unconstrained_call { + for (typ, _, _) in args.iter() { + if matches!(&typ.follow_bindings(), Type::MutableReference(_)) { + self.errors.push(TypeCheckError::ConstrainedReferenceToUnconstrained { span }); + } + } + } + + let return_type = self.bind_function_type(func_type, args, span); + + // Check that we are not passing a slice from an unconstrained runtime to a constrained runtime + if is_current_func_constrained && is_unconstrained_call { + if return_type.contains_slice() { + self.errors.push(TypeCheckError::UnconstrainedSliceReturnToConstrained { span }); + } else if matches!(&return_type.follow_bindings(), Type::MutableReference(_)) { + self.errors.push(TypeCheckError::UnconstrainedReferenceToConstrained { span }); + } + }; + + return_type + } + fn check_block(&mut self, block: HirBlockExpression) -> Type { let mut block_type = Type::Unit; @@ -416,9 +443,8 @@ impl<'interner> TypeChecker<'interner> { // Push any trait constraints required by this definition to the context // to be checked later when the type of this variable is further constrained. if let Some(definition) = self.interner.try_definition(ident.id) { - if let DefinitionKind::Function(function) = definition.kind { - let function = self.interner.function_meta(&function); - + if let DefinitionKind::Function(func_id) = definition.kind { + let function = self.interner.function_meta(&func_id); for mut constraint in function.trait_constraints.clone() { constraint.apply_bindings(&bindings); self.trait_constraints.push((constraint, *expr_id)); diff --git a/test_programs/compile_failure/regression_5065_failure/Nargo.toml b/test_programs/compile_failure/regression_5065_failure/Nargo.toml new file mode 100644 index 00000000000..c3dda827d3c --- /dev/null +++ b/test_programs/compile_failure/regression_5065_failure/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "regression_5065_failure" +type = "bin" +authors = [""] +compiler_version = ">=0.30.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/compile_failure/regression_5065_failure/src/main.nr b/test_programs/compile_failure/regression_5065_failure/src/main.nr new file mode 100644 index 00000000000..ead1754209d --- /dev/null +++ b/test_programs/compile_failure/regression_5065_failure/src/main.nr @@ -0,0 +1,40 @@ +struct Wrapper { + _value: T, +} + +impl Wrapper { + fn new(value: T) -> Self { + Self { _value: value } + } + + fn unwrap(self) -> T { + self._value + } +} + +trait MyTrait { + fn new() -> Self; +} + +struct MyType {} + +impl MyTrait for MyType { + fn new() -> Self { + MyType {} + } +} + +fn foo() -> T where T: MyTrait { + MyTrait::new() +} + +struct BadType {} + +// Check that we get "No matching impl found for `BadType: MyTrait`" +fn concise_regression() -> BadType { + Wrapper::new(foo()).unwrap() +} + +fn main() { + let _ = concise_regression(); +} diff --git a/test_programs/compile_success_empty/regression_5065/Nargo.toml b/test_programs/compile_success_empty/regression_5065/Nargo.toml new file mode 100644 index 00000000000..b1cb9d9ba96 --- /dev/null +++ b/test_programs/compile_success_empty/regression_5065/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "regression_5065" +type = "bin" +authors = [""] +compiler_version = ">=0.30.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/compile_success_empty/regression_5065/src/main.nr b/test_programs/compile_success_empty/regression_5065/src/main.nr new file mode 100644 index 00000000000..36b0570165f --- /dev/null +++ b/test_programs/compile_success_empty/regression_5065/src/main.nr @@ -0,0 +1,45 @@ +struct Wrapper { + _value: T, +} + +impl Wrapper { + fn new_wrapper(value: T) -> Self { + Self { _value: value } + } + + fn unwrap(self) -> T { + self._value + } +} + +trait MyTrait { + fn new() -> Self; +} + +struct MyType {} + +impl MyTrait for MyType { + fn new() -> Self { + MyType {} + } +} + +fn foo() -> T where T: MyTrait { + MyTrait::new() +} + +// fn verbose_but_compiles() -> MyType { +// let a = Wrapper::new_wrapper(foo()); +// a.unwrap() +// } + +// Check that are able to infer the return type of the call to `foo` +fn concise_regression() -> MyType { + Wrapper::new_wrapper(foo()).unwrap() + // Wrapper::unwrap(Wrapper::new_wrapper(foo())) +} + +fn main() { + // let _ = verbose_but_compiles(); + let _ = concise_regression(); +} From b0a7d0b12328d3ed9faed87b78792b77786018e0 Mon Sep 17 00:00:00 2001 From: jfecher Date: Wed, 29 May 2024 14:44:03 -0500 Subject: [PATCH 49/61] fix(experimental elaborator): Clear generics after elaborating type aliases (#5136) # Description ## Problem\* ## Summary\* Adds a missed call to `generics.clear()` ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_frontend/src/elaborator/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index 10ebd657494..c55438193d1 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -1147,6 +1147,7 @@ impl<'context> Elaborator<'context> { self.current_item = Some(DependencyId::Alias(alias_id)); let typ = self.resolve_type(alias.type_alias_def.typ); self.interner.set_type_alias(alias_id, typ, generics); + self.generics.clear(); } fn collect_struct_definitions(&mut self, structs: BTreeMap) { From e73cdbb93b0714331fef754f862d89c08c28a9e5 Mon Sep 17 00:00:00 2001 From: jfecher Date: Wed, 29 May 2024 14:44:30 -0500 Subject: [PATCH 50/61] fix(experimental elaborator): Fix global values used in the elaborator (#5135) # Description ## Problem\* Resolves an issue where globals would not have their type set correctly in the elaborator. This is because `elaborate_let` was called which creates a fresh DefinitionId rather than the one already defined by the global, and pushes the type to that fresh id. ## Summary\* Adds a `elaborate_global_let` function which copies over the new type to the original DefinitionId defined by the global. This PR also adds a call to `self.type_variables.clear()` after a global is resolved so that its type is not defaulted too early. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../src/elaborator/expressions.rs | 2 + compiler/noirc_frontend/src/elaborator/mod.rs | 11 ++-- .../src/elaborator/statements.rs | 52 +++++++++++++++---- tooling/nargo_cli/tests/stdlib-tests.rs | 17 ++---- 4 files changed, 51 insertions(+), 31 deletions(-) diff --git a/compiler/noirc_frontend/src/elaborator/expressions.rs b/compiler/noirc_frontend/src/elaborator/expressions.rs index 2ad1598c6a2..8acd1867074 100644 --- a/compiler/noirc_frontend/src/elaborator/expressions.rs +++ b/compiler/noirc_frontend/src/elaborator/expressions.rs @@ -348,6 +348,8 @@ impl<'context> Elaborator<'context> { let func_type = self.type_check_variable(function_name, function_id, turbofish_generics); + self.interner.push_expr_type(function_id, func_type.clone()); + // Type check the new call now that it has been changed from a method call // to a function call. This way we avoid duplicating code. let typ = self.type_check_call(&function_call, func_type, function_args, span); diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index c55438193d1..1d66b4b952a 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -1212,8 +1212,6 @@ impl<'context> Elaborator<'context> { let global_id = global.global_id; self.current_item = Some(DependencyId::Global(global_id)); - - let definition_kind = DefinitionKind::Global(global_id); let let_stmt = global.stmt_def; if !self.in_contract @@ -1228,11 +1226,12 @@ impl<'context> Elaborator<'context> { self.push_err(ResolverError::MutableGlobal { span }); } - let (let_statement, _typ) = self.elaborate_let(let_stmt); + self.elaborate_global_let(let_stmt, global_id); - let statement_id = self.interner.get_global(global_id).let_statement; - self.interner.get_global_definition_mut(global_id).kind = definition_kind.clone(); - self.interner.replace_statement(statement_id, let_statement); + // Avoid defaulting the types of globals here since they may be used in any function. + // Otherwise we may prematurely default to a Field inside the next function if this + // global was unused there, even if it is consistently used as a u8 everywhere else. + self.type_variables.clear(); } fn define_function_metas( diff --git a/compiler/noirc_frontend/src/elaborator/statements.rs b/compiler/noirc_frontend/src/elaborator/statements.rs index a7a2df4041e..9c50e7096dd 100644 --- a/compiler/noirc_frontend/src/elaborator/statements.rs +++ b/compiler/noirc_frontend/src/elaborator/statements.rs @@ -15,7 +15,7 @@ use crate::{ macros_api::{ ForLoopStatement, ForRange, HirStatement, LetStatement, Statement, StatementKind, }, - node_interner::{DefinitionId, DefinitionKind, StmtId}, + node_interner::{DefinitionId, DefinitionKind, GlobalId, StmtId}, Type, }; @@ -24,7 +24,7 @@ use super::Elaborator; impl<'context> Elaborator<'context> { fn elaborate_statement_value(&mut self, statement: Statement) -> (HirStatement, Type) { match statement.kind { - StatementKind::Let(let_stmt) => self.elaborate_let(let_stmt), + StatementKind::Let(let_stmt) => self.elaborate_local_let(let_stmt), StatementKind::Constrain(constrain) => self.elaborate_constrain(constrain), StatementKind::Assign(assign) => self.elaborate_assign(assign), StatementKind::For(for_stmt) => self.elaborate_for(for_stmt), @@ -51,7 +51,33 @@ impl<'context> Elaborator<'context> { (id, typ) } - pub(super) fn elaborate_let(&mut self, let_stmt: LetStatement) -> (HirStatement, Type) { + pub(super) fn elaborate_local_let(&mut self, let_stmt: LetStatement) -> (HirStatement, Type) { + let (statement, typ, _) = self.elaborate_let(let_stmt); + (statement, typ) + } + + /// Elaborates a global let statement. Compared to the local version, this + /// version fixes up the result to use the given DefinitionId rather than + /// the fresh one defined by the let pattern. + pub(super) fn elaborate_global_let(&mut self, let_stmt: LetStatement, global_id: GlobalId) { + let (let_statement, _typ, new_ids) = self.elaborate_let(let_stmt); + let statement_id = self.interner.get_global(global_id).let_statement; + + // To apply the changes from the fresh id created in elaborate_let to this global + // we need to change the definition kind and update the type. + let definition_id = self.interner.get_global(global_id).definition_id; + self.interner.definition_mut(definition_id).kind = DefinitionKind::Global(global_id); + + assert_eq!(new_ids.len(), 1, "Globals should only define 1 value"); + let definition_type = self.interner.definition_type(new_ids[0].id); + self.interner.push_definition_type(definition_id, definition_type); + + self.interner.replace_statement(statement_id, let_statement); + } + + /// Elaborate a local or global let statement. In addition to the HirLetStatement and unit + /// type, this also returns each HirIdent defined by this let statement. + fn elaborate_let(&mut self, let_stmt: LetStatement) -> (HirStatement, Type, Vec) { let expr_span = let_stmt.expression.span; let (expression, expr_type) = self.elaborate_expression(let_stmt.expression); let definition = DefinitionKind::Local(Some(expression)); @@ -77,14 +103,18 @@ impl<'context> Elaborator<'context> { expr_type }; - let let_ = HirLetStatement { - pattern: self.elaborate_pattern(let_stmt.pattern, r#type.clone(), definition), - r#type, - expression, - attributes: let_stmt.attributes, - comptime: let_stmt.comptime, - }; - (HirStatement::Let(let_), Type::Unit) + let mut created_ids = Vec::new(); + let pattern = self.elaborate_pattern_and_store_ids( + let_stmt.pattern, + r#type.clone(), + definition, + &mut created_ids, + ); + + let attributes = let_stmt.attributes; + let comptime = let_stmt.comptime; + let let_ = HirLetStatement { pattern, r#type, expression, attributes, comptime }; + (HirStatement::Let(let_), Type::Unit, created_ids) } pub(super) fn elaborate_constrain(&mut self, stmt: ConstrainStatement) -> (HirStatement, Type) { diff --git a/tooling/nargo_cli/tests/stdlib-tests.rs b/tooling/nargo_cli/tests/stdlib-tests.rs index 70a9354f50a..0bb967e7502 100644 --- a/tooling/nargo_cli/tests/stdlib-tests.rs +++ b/tooling/nargo_cli/tests/stdlib-tests.rs @@ -10,7 +10,8 @@ use nargo::{ parse_all, prepare_package, }; -fn run_stdlib_tests(use_elaborator: bool) { +#[test] +fn run_stdlib_tests() { let mut file_manager = file_manager_with_stdlib(&PathBuf::from(".")); file_manager.add_file_with_source_canonical_path(&PathBuf::from("main.nr"), "".to_owned()); let parsed_files = parse_all(&file_manager); @@ -29,7 +30,7 @@ fn run_stdlib_tests(use_elaborator: bool) { let (mut context, dummy_crate_id) = prepare_package(&file_manager, &parsed_files, &dummy_package); - let result = check_crate(&mut context, dummy_crate_id, true, false, use_elaborator); + let result = check_crate(&mut context, dummy_crate_id, true, false, false); report_errors(result, &context.file_manager, true, false) .expect("Error encountered while compiling standard library"); @@ -59,15 +60,3 @@ fn run_stdlib_tests(use_elaborator: bool) { assert!(!test_report.is_empty(), "Could not find any tests within the stdlib"); assert!(test_report.iter().all(|(_, status)| !status.failed())); } - -#[test] -fn stdlib_noir_tests() { - run_stdlib_tests(false) -} - -// Once this no longer panics we can use the elaborator by default and remove the old passes -#[test] -#[should_panic] -fn stdlib_elaborator_tests() { - run_stdlib_tests(true) -} From 145b90945486907cb6db75d3f3f93a58d19b2a32 Mon Sep 17 00:00:00 2001 From: guipublic <47281315+guipublic@users.noreply.github.com> Date: Thu, 30 May 2024 15:40:15 +0200 Subject: [PATCH 51/61] fix: use predicate for curve operations (#5076) # Description ## Problem\* Resolves #5045 ## Summary\* use predicate to set is_infinite to true when side_effects are disabled, to ensure that the curve operation will not fail. ## Additional Context ## Documentation\* Check one: - [X] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [X] I have tested the changes locally. - [X] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../noirc_evaluator/src/ssa/ir/instruction.rs | 10 +++- .../src/ssa/opt/flatten_cfg.rs | 47 ++++++++++++++++++- .../regression_5045/Nargo.toml | 7 +++ .../regression_5045/Prover.toml | 1 + .../regression_5045/src/main.nr | 20 ++++++++ 5 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 test_programs/execution_success/regression_5045/Nargo.toml create mode 100644 test_programs/execution_success/regression_5045/Prover.toml create mode 100644 test_programs/execution_success/regression_5045/src/main.nr diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs index 5110140bfcc..7517b54aac3 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -123,7 +123,12 @@ impl Intrinsic { | Intrinsic::IsUnconstrained => false, // Some black box functions have side-effects - Intrinsic::BlackBox(func) => matches!(func, BlackBoxFunc::RecursiveAggregation), + Intrinsic::BlackBox(func) => matches!( + func, + BlackBoxFunc::RecursiveAggregation + | BlackBoxFunc::MultiScalarMul + | BlackBoxFunc::EmbeddedCurveAdd + ), } } @@ -340,6 +345,9 @@ impl Instruction { // Some `Intrinsic`s have side effects so we must check what kind of `Call` this is. Call { func, .. } => match dfg[*func] { + // Explicitly allows removal of unused ec operations, even if they can fail + Value::Intrinsic(Intrinsic::BlackBox(BlackBoxFunc::MultiScalarMul)) + | Value::Intrinsic(Intrinsic::BlackBox(BlackBoxFunc::EmbeddedCurveAdd)) => true, Value::Intrinsic(intrinsic) => !intrinsic.has_side_effects(), // All foreign functions are treated as having side effects. diff --git a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs index 690c0244f62..e07f947db8d 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs @@ -134,7 +134,7 @@ use fxhash::FxHashMap as HashMap; use std::collections::{BTreeMap, HashSet}; -use acvm::{acir::AcirField, FieldElement}; +use acvm::{acir::AcirField, acir::BlackBoxFunc, FieldElement}; use iter_extended::vecmap; use crate::ssa::{ @@ -769,7 +769,38 @@ impl<'f> Context<'f> { Instruction::Call { func, arguments } } + //Issue #5045: We set curve points to infinity if condition is false + Value::Intrinsic(Intrinsic::BlackBox(BlackBoxFunc::EmbeddedCurveAdd)) => { + arguments[2] = self.var_or_one(arguments[2], condition, call_stack.clone()); + arguments[5] = self.var_or_one(arguments[5], condition, call_stack.clone()); + Instruction::Call { func, arguments } + } + Value::Intrinsic(Intrinsic::BlackBox(BlackBoxFunc::MultiScalarMul)) => { + let mut array_with_predicate = im::Vector::new(); + let array_typ; + if let Value::Array { array, typ } = + &self.inserter.function.dfg[arguments[0]] + { + array_typ = typ.clone(); + for (i, value) in array.clone().iter().enumerate() { + if i % 3 == 2 { + array_with_predicate.push_back(self.var_or_one( + *value, + condition, + call_stack.clone(), + )); + } else { + array_with_predicate.push_back(*value); + } + } + } else { + unreachable!(); + } + arguments[0] = + self.inserter.function.dfg.make_array(array_with_predicate, array_typ); + Instruction::Call { func, arguments } + } _ => Instruction::Call { func, arguments }, }, other => other, @@ -779,6 +810,20 @@ impl<'f> Context<'f> { } } + // Computes: if condition { var } else { 1 } + fn var_or_one(&mut self, var: ValueId, condition: ValueId, call_stack: CallStack) -> ValueId { + let field = self.insert_instruction( + Instruction::binary(BinaryOp::Mul, var, condition), + call_stack.clone(), + ); + let not_condition = + self.insert_instruction(Instruction::Not(condition), call_stack.clone()); + self.insert_instruction( + Instruction::binary(BinaryOp::Add, field, not_condition), + call_stack, + ) + } + fn undo_stores_in_then_branch(&mut self, store_values: &HashMap) { for (address, store) in store_values { let address = *address; diff --git a/test_programs/execution_success/regression_5045/Nargo.toml b/test_programs/execution_success/regression_5045/Nargo.toml new file mode 100644 index 00000000000..8f56d392fec --- /dev/null +++ b/test_programs/execution_success/regression_5045/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "regression_5045" +version = "0.1.0" +type = "bin" +authors = [""] + +[dependencies] \ No newline at end of file diff --git a/test_programs/execution_success/regression_5045/Prover.toml b/test_programs/execution_success/regression_5045/Prover.toml new file mode 100644 index 00000000000..5444a86ec82 --- /dev/null +++ b/test_programs/execution_success/regression_5045/Prover.toml @@ -0,0 +1 @@ +is_active = false \ No newline at end of file diff --git a/test_programs/execution_success/regression_5045/src/main.nr b/test_programs/execution_success/regression_5045/src/main.nr new file mode 100644 index 00000000000..015fb1b2555 --- /dev/null +++ b/test_programs/execution_success/regression_5045/src/main.nr @@ -0,0 +1,20 @@ +use dep::std::embedded_curve_ops::EmbeddedCurvePoint; +use dep::std::embedded_curve_ops::EmbeddedCurveScalar; + +fn main(is_active: bool) { + let a = EmbeddedCurvePoint { + x: 0x1d8eb4378a3bde41e0b6a9a8dcbd21b7ff9c51bdd6ca13ce989abbbf90df3666, + y: 0x06075b63354f2504f9cddba0b94ed0cef35fc88615e69ec1f853b51eb79a24a0, + is_infinite: false + }; + + if is_active { + let bad = EmbeddedCurvePoint { x: 0, y: 5, is_infinite: false }; + let d = bad.double(); + let e = dep::std::embedded_curve_ops::multi_scalar_mul( + [a, bad], + [EmbeddedCurveScalar { lo: 1, hi: 0 }, EmbeddedCurveScalar { lo: 1, hi: 0 }] + ); + assert(e[0] != d.x); + } +} From 8ae3d751b49648f997bde337649e798c04083b98 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 30 May 2024 15:04:37 +0100 Subject: [PATCH 52/61] chore(ci): don't raise MSRV issue if workflow cancelled (#5143) # Description ## Problem\* Resolves ## Summary\* We're currently getting a large number of false positive alerts such as https://github.com/noir-lang/noir/issues/5137 due to the workflow being cancelled when multiple PRs are merged in quick succession. This PR changes the workflow to treat cancellation as a success rather than a failure to avoid this. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .github/workflows/test-rust-workspace-msrv.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-rust-workspace-msrv.yml b/.github/workflows/test-rust-workspace-msrv.yml index ccd431ea879..ae016169830 100644 --- a/.github/workflows/test-rust-workspace-msrv.yml +++ b/.github/workflows/test-rust-workspace-msrv.yml @@ -111,7 +111,7 @@ jobs: fi env: # We treat any cancelled, skipped or failing jobs as a failure for the workflow as a whole. - FAIL: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }} + FAIL: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'skipped') }} - name: Checkout if: ${{ failure() }} From 29baeb41e15918935c437e0a2759c6b936f125a4 Mon Sep 17 00:00:00 2001 From: guipublic <47281315+guipublic@users.noreply.github.com> Date: Thu, 30 May 2024 16:36:02 +0200 Subject: [PATCH 53/61] fix: wrapping in signed division (#5134) # Description ## Problem\* Resolves #5129 ## Summary\* A negative and null quotient was computed as -0=2^{bit_size}, which wraps over the bit size. ## Additional Context ## Documentation\* Check one: - [X] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [X] I have tested the changes locally. - [X] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../src/ssa/acir_gen/acir_ir/acir_variable.rs | 12 +++++++++++- .../execution_success/signed_div/src/main.nr | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index 4a0f9f798ff..93200d4f841 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -979,6 +979,7 @@ impl AcirContext { let max_power_of_two = self.add_constant( FieldElement::from(2_i128).pow(&FieldElement::from(bit_size as i128 - 1)), ); + let zero = self.add_constant(FieldElement::zero()); let one = self.add_constant(FieldElement::one()); // Get the sign bit of rhs by computing rhs / max_power_of_two @@ -998,10 +999,19 @@ impl AcirContext { // Unsigned to signed: derive q and r from q1,r1 and the signs of lhs and rhs // Quotient sign is lhs sign * rhs sign, whose resulting sign bit is the XOR of the sign bits let q_sign = self.xor_var(lhs_leading, rhs_leading, AcirType::unsigned(1))?; - let quotient = self.two_complement(q1, q_sign, bit_size)?; let remainder = self.two_complement(r1, lhs_leading, bit_size)?; + // Issue #5129 - When q1 is zero and quotient sign is -1, we compute -0=2^{bit_size}, + // which is not valid because we do not wrap integer operations + // Similar case can happen with the remainder. + let q_is_0 = self.eq_var(q1, zero)?; + let q_is_not_0 = self.not_var(q_is_0, AcirType::unsigned(1))?; + let quotient = self.mul_var(quotient, q_is_not_0)?; + let r_is_0 = self.eq_var(r1, zero)?; + let r_is_not_0 = self.not_var(r_is_0, AcirType::unsigned(1))?; + let remainder = self.mul_var(remainder, r_is_not_0)?; + Ok((quotient, remainder)) } diff --git a/test_programs/execution_success/signed_div/src/main.nr b/test_programs/execution_success/signed_div/src/main.nr index bc3f5c3bdc0..04383a459bd 100644 --- a/test_programs/execution_success/signed_div/src/main.nr +++ b/test_programs/execution_success/signed_div/src/main.nr @@ -4,7 +4,7 @@ struct SignedDivOp { result: i8, } -unconstrained fn main(ops: [SignedDivOp; 15]) { +fn main(ops: [SignedDivOp; 15]) { for i in 0..15 { assert_eq(ops[i].lhs / ops[i].rhs, ops[i].result); } From 7ea5962e77b7183374a4e14da3a237ccd63f00a0 Mon Sep 17 00:00:00 2001 From: jfecher Date: Thu, 30 May 2024 11:19:20 -0500 Subject: [PATCH 54/61] fix(experimental elaborator): Fix `impl Trait` when `--use-elaborator` is selected (#5138) # Description ## Problem\* Resolves errors when using `impl Trait` in the elaborator ## Summary\* Desugaring impl args was happening when elaborating the function when it should have been when defining the FuncMeta beforehand. Additionally, I've taken advantage of the fact that the elaborator also combines the type checking step and have shortened the `desugar_impl_args` function significantly by converting to resolved types instead and pushing to the function's resolved traits. This way there's no danger of users accidentally using the name generated for the implicit generic since it was never introduced into scope. ## Additional Context After this PR only the following two test_programs are still failing: tests::execution_success_global_consts tests::execution_success_hashmap I've yet to test to see if any of the frontend tests fail for the elaborator. ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_frontend/src/elaborator/mod.rs | 89 +++++++++---------- 1 file changed, 41 insertions(+), 48 deletions(-) diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index 1d66b4b952a..a0ff3c12ae3 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -273,7 +273,7 @@ impl<'context> Elaborator<'context> { self.trait_id = None; } - fn elaborate_function(&mut self, mut function: NoirFunction, id: FuncId) { + fn elaborate_function(&mut self, function: NoirFunction, id: FuncId) { self.current_function = Some(id); // Without this, impl methods can accidentally be placed in contracts. See #3254 @@ -303,7 +303,6 @@ impl<'context> Elaborator<'context> { } self.generics = func_meta.all_generics.clone(); - self.desugar_impl_trait_args(&mut function, id); self.declare_numeric_generics(&func_meta.parameters, func_meta.return_type()); self.add_trait_constraints_to_scope(&func_meta); @@ -373,49 +372,31 @@ impl<'context> Elaborator<'context> { } /// This turns function parameters of the form: - /// fn foo(x: impl Bar) + /// `fn foo(x: impl Bar)` /// /// into - /// fn foo(x: T0_impl_Bar) where T0_impl_Bar: Bar - fn desugar_impl_trait_args(&mut self, func: &mut NoirFunction, func_id: FuncId) { - let mut impl_trait_generics = HashSet::default(); - let mut counter: usize = 0; - for parameter in func.def.parameters.iter_mut() { - if let UnresolvedTypeData::TraitAsType(path, args) = ¶meter.typ.typ { - let mut new_generic_ident: Ident = - format!("T{}_impl_{}", func_id, path.as_string()).into(); - let mut new_generic_path = Path::from_ident(new_generic_ident.clone()); - while impl_trait_generics.contains(&new_generic_ident) - || self.lookup_generic_or_global_type(&new_generic_path).is_some() - { - new_generic_ident = - format!("T{}_impl_{}_{}", func_id, path.as_string(), counter).into(); - new_generic_path = Path::from_ident(new_generic_ident.clone()); - counter += 1; - } - impl_trait_generics.insert(new_generic_ident.clone()); - - let is_synthesized = true; - let new_generic_type_data = - UnresolvedTypeData::Named(new_generic_path, vec![], is_synthesized); - let new_generic_type = - UnresolvedType { typ: new_generic_type_data.clone(), span: None }; - let new_trait_bound = TraitBound { - trait_path: path.clone(), - trait_id: None, - trait_generics: args.to_vec(), - }; - let new_trait_constraint = UnresolvedTraitConstraint { - typ: new_generic_type, - trait_bound: new_trait_bound, - }; - - parameter.typ.typ = new_generic_type_data; - func.def.generics.push(new_generic_ident); - func.def.where_clause.push(new_trait_constraint); - } + /// `fn foo(x: T0_impl_Bar) where T0_impl_Bar: Bar` + /// although the fresh type variable is not named internally. + fn desugar_impl_trait_arg( + &mut self, + trait_path: Path, + trait_generics: Vec, + generics: &mut Vec, + trait_constraints: &mut Vec, + ) -> Type { + let new_generic_id = self.interner.next_type_variable_id(); + let new_generic = TypeVariable::unbound(new_generic_id); + generics.push(new_generic.clone()); + + let name = format!("impl {trait_path}"); + let generic_type = Type::NamedGeneric(new_generic, Rc::new(name)); + let trait_bound = TraitBound { trait_path, trait_id: None, trait_generics }; + + if let Some(new_constraint) = self.resolve_trait_bound(&trait_bound, generic_type.clone()) { + trait_constraints.push(new_constraint); } - self.add_generics(&impl_trait_generics.into_iter().collect()); + + generic_type } /// Add the given generics to scope. @@ -491,11 +472,14 @@ impl<'context> Elaborator<'context> { constraint: &UnresolvedTraitConstraint, ) -> Option { let typ = self.resolve_type(constraint.typ.clone()); - let trait_generics = - vecmap(&constraint.trait_bound.trait_generics, |typ| self.resolve_type(typ.clone())); + self.resolve_trait_bound(&constraint.trait_bound, typ) + } + + fn resolve_trait_bound(&mut self, bound: &TraitBound, typ: Type) -> Option { + let trait_generics = vecmap(&bound.trait_generics, |typ| self.resolve_type(typ.clone())); - let span = constraint.trait_bound.trait_path.span(); - let the_trait = self.lookup_trait_or_error(constraint.trait_bound.trait_path.clone())?; + let span = bound.trait_path.span(); + let the_trait = self.lookup_trait_or_error(bound.trait_path.clone())?; let trait_id = the_trait.id; let expected_generics = the_trait.generics.len(); @@ -561,6 +545,8 @@ impl<'context> Elaborator<'context> { self.add_generics(&func.def.generics); + let mut trait_constraints = self.resolve_trait_constraints(&func.def.where_clause); + let mut generics = vecmap(&self.generics, |(_, typevar, _)| typevar.clone()); let mut parameters = Vec::new(); let mut parameter_types = Vec::new(); @@ -575,7 +561,14 @@ impl<'context> Elaborator<'context> { } let type_span = typ.span.unwrap_or_else(|| pattern.span()); - let typ = self.resolve_type_inner(typ, &mut generics); + + let typ = match typ.typ { + UnresolvedTypeData::TraitAsType(path, args) => { + self.desugar_impl_trait_arg(path, args, &mut generics, &mut trait_constraints) + } + _ => self.resolve_type_inner(typ, &mut generics), + }; + self.check_if_type_is_valid_for_program_input( &typ, is_entry_point, @@ -660,7 +653,7 @@ impl<'context> Elaborator<'context> { return_type: func.def.return_type.clone(), return_visibility: func.def.return_visibility, has_body: !func.def.body.is_empty(), - trait_constraints: self.resolve_trait_constraints(&func.def.where_clause), + trait_constraints, is_entry_point, is_trait_function, has_inline_attribute, From a9a6cee501ce3e8b6a6570238057f3b7a0cad799 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 30 May 2024 17:22:25 +0100 Subject: [PATCH 55/61] chore: default to using bn254 in `noirc_frontend` (#5144) # Description ## Problem\* Resolves ## Summary\* This PR sets `noirc_frontend` to default to bn254 if no feature flag is set. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index 5f1ef6477af..5c196324b7d 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -741,12 +741,10 @@ fn should_check_siblings_for_module(module_path: &Path, parent_path: &Path) -> b } cfg_if::cfg_if! { - if #[cfg(feature = "bn254")] { - pub const CHOSEN_FIELD: &str = "bn254"; - } else if #[cfg(feature = "bls12_381")] { + if #[cfg(feature = "bls12_381")] { pub const CHOSEN_FIELD: &str = "bls12_381"; } else { - compile_error!("please specify a field to compile with"); + pub const CHOSEN_FIELD: &str = "bn254"; } } From a140dec4580459c5856d44337de3ea08aa7fb44a Mon Sep 17 00:00:00 2001 From: jfecher Date: Thu, 30 May 2024 11:40:51 -0500 Subject: [PATCH 56/61] fix(experimental elaborator): Fix definition kind of globals and tuple patterns with `--use-elaborator` flag (#5139) # Description ## Problem\* Resolves two issues: 1. A type error on some tuple patterns because a `follow_bindings` call was missing 2. When elaborating global lets we were setting the existing definition id to a DefinitionKind::Global, but it already was one. The fresh ID created by the let should have been marked global instead. ## Summary\* ## Additional Context After this PR and https://github.com/noir-lang/noir/pull/5138 all test_programs are expected to work in the elaborator. ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_frontend/src/elaborator/patterns.rs | 2 +- compiler/noirc_frontend/src/elaborator/statements.rs | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/compiler/noirc_frontend/src/elaborator/patterns.rs b/compiler/noirc_frontend/src/elaborator/patterns.rs index b6d6cb2cf2d..12b0b7b5e64 100644 --- a/compiler/noirc_frontend/src/elaborator/patterns.rs +++ b/compiler/noirc_frontend/src/elaborator/patterns.rs @@ -79,7 +79,7 @@ impl<'context> Elaborator<'context> { HirPattern::Mutable(Box::new(pattern), location) } Pattern::Tuple(fields, span) => { - let field_types = match expected_type { + let field_types = match expected_type.follow_bindings() { Type::Tuple(fields) => fields, Type::Error => Vec::new(), expected_type => { diff --git a/compiler/noirc_frontend/src/elaborator/statements.rs b/compiler/noirc_frontend/src/elaborator/statements.rs index 9c50e7096dd..40de9a3983a 100644 --- a/compiler/noirc_frontend/src/elaborator/statements.rs +++ b/compiler/noirc_frontend/src/elaborator/statements.rs @@ -65,11 +65,13 @@ impl<'context> Elaborator<'context> { // To apply the changes from the fresh id created in elaborate_let to this global // we need to change the definition kind and update the type. - let definition_id = self.interner.get_global(global_id).definition_id; - self.interner.definition_mut(definition_id).kind = DefinitionKind::Global(global_id); - assert_eq!(new_ids.len(), 1, "Globals should only define 1 value"); - let definition_type = self.interner.definition_type(new_ids[0].id); + let new_id = new_ids[0].id; + + self.interner.definition_mut(new_id).kind = DefinitionKind::Global(global_id); + + let definition_id = self.interner.get_global(global_id).definition_id; + let definition_type = self.interner.definition_type(new_id); self.interner.push_definition_type(definition_id, definition_type); self.interner.replace_statement(statement_id, let_statement); From 80fd901ac723e8885efc442683f34b5fef169660 Mon Sep 17 00:00:00 2001 From: jfecher Date: Thu, 30 May 2024 12:01:33 -0500 Subject: [PATCH 57/61] chore: Remove hir to ast pass (#5147) # Description ## Problem\* ## Summary\* Removes the Hir to Ast pass since it was only needed for the previously proposed metacircular evaluator architecture where we'd globally loop back to name resolution after the interpreter expands a macro. Now that we're using an elaborator it is unneeded. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../src/hir/comptime/hir_to_ast.rs | 369 ------------------ .../noirc_frontend/src/hir/comptime/mod.rs | 1 - 2 files changed, 370 deletions(-) delete mode 100644 compiler/noirc_frontend/src/hir/comptime/hir_to_ast.rs diff --git a/compiler/noirc_frontend/src/hir/comptime/hir_to_ast.rs b/compiler/noirc_frontend/src/hir/comptime/hir_to_ast.rs deleted file mode 100644 index e0fdd91adb4..00000000000 --- a/compiler/noirc_frontend/src/hir/comptime/hir_to_ast.rs +++ /dev/null @@ -1,369 +0,0 @@ -use iter_extended::vecmap; -use noirc_errors::{Span, Spanned}; - -use crate::ast::{ - ArrayLiteral, AssignStatement, BlockExpression, CallExpression, CastExpression, ConstrainKind, - ConstructorExpression, ExpressionKind, ForLoopStatement, ForRange, Ident, IfExpression, - IndexExpression, InfixExpression, LValue, Lambda, LetStatement, Literal, - MemberAccessExpression, MethodCallExpression, Path, Pattern, PrefixExpression, UnresolvedType, - UnresolvedTypeData, UnresolvedTypeExpression, -}; -use crate::ast::{ConstrainStatement, Expression, Statement, StatementKind}; -use crate::hir_def::expr::{HirArrayLiteral, HirBlockExpression, HirExpression, HirIdent}; -use crate::hir_def::stmt::{HirLValue, HirPattern, HirStatement}; -use crate::hir_def::types::Type; -use crate::macros_api::HirLiteral; -use crate::node_interner::{ExprId, NodeInterner, StmtId}; - -// TODO: -// - Full path for idents & types -// - Assert/AssertEq information lost -// - The type name span is lost in constructor patterns & expressions -// - All type spans are lost -// - Type::TypeVariable has no equivalent in the Ast - -impl StmtId { - #[allow(unused)] - fn to_ast(self, interner: &NodeInterner) -> Statement { - let statement = interner.statement(&self); - let span = interner.statement_span(self); - - let kind = match statement { - HirStatement::Let(let_stmt) => { - let pattern = let_stmt.pattern.into_ast(interner); - let r#type = interner.id_type(let_stmt.expression).to_ast(); - let expression = let_stmt.expression.to_ast(interner); - StatementKind::Let(LetStatement { - pattern, - r#type, - expression, - comptime: false, - attributes: Vec::new(), - }) - } - HirStatement::Constrain(constrain) => { - let expr = constrain.0.to_ast(interner); - let message = constrain.2.map(|message| message.to_ast(interner)); - - // TODO: Find difference in usage between Assert & AssertEq - StatementKind::Constrain(ConstrainStatement(expr, message, ConstrainKind::Assert)) - } - HirStatement::Assign(assign) => StatementKind::Assign(AssignStatement { - lvalue: assign.lvalue.into_ast(interner), - expression: assign.expression.to_ast(interner), - }), - HirStatement::For(for_stmt) => StatementKind::For(ForLoopStatement { - identifier: for_stmt.identifier.to_ast(interner), - range: ForRange::Range( - for_stmt.start_range.to_ast(interner), - for_stmt.end_range.to_ast(interner), - ), - block: for_stmt.block.to_ast(interner), - span, - }), - HirStatement::Break => StatementKind::Break, - HirStatement::Continue => StatementKind::Continue, - HirStatement::Expression(expr) => StatementKind::Expression(expr.to_ast(interner)), - HirStatement::Semi(expr) => StatementKind::Semi(expr.to_ast(interner)), - HirStatement::Error => StatementKind::Error, - HirStatement::Comptime(statement) => { - StatementKind::Comptime(Box::new(statement.to_ast(interner))) - } - }; - - Statement { kind, span } - } -} - -impl ExprId { - #[allow(unused)] - fn to_ast(self, interner: &NodeInterner) -> Expression { - let expression = interner.expression(&self); - let span = interner.expr_span(&self); - - let kind = match expression { - HirExpression::Ident(ident, generics) => { - let path = Path::from_ident(ident.to_ast(interner)); - ExpressionKind::Variable( - path, - generics.map(|option| option.iter().map(|generic| generic.to_ast()).collect()), - ) - } - HirExpression::Literal(HirLiteral::Array(array)) => { - let array = array.into_ast(interner, span); - ExpressionKind::Literal(Literal::Array(array)) - } - HirExpression::Literal(HirLiteral::Slice(array)) => { - let array = array.into_ast(interner, span); - ExpressionKind::Literal(Literal::Slice(array)) - } - HirExpression::Literal(HirLiteral::Bool(value)) => { - ExpressionKind::Literal(Literal::Bool(value)) - } - HirExpression::Literal(HirLiteral::Integer(value, sign)) => { - ExpressionKind::Literal(Literal::Integer(value, sign)) - } - HirExpression::Literal(HirLiteral::Str(string)) => { - ExpressionKind::Literal(Literal::Str(string)) - } - HirExpression::Literal(HirLiteral::FmtStr(string, _exprs)) => { - // TODO: Is throwing away the exprs here valid? - ExpressionKind::Literal(Literal::FmtStr(string)) - } - HirExpression::Literal(HirLiteral::Unit) => ExpressionKind::Literal(Literal::Unit), - HirExpression::Block(expr) => ExpressionKind::Block(expr.into_ast(interner)), - HirExpression::Prefix(prefix) => ExpressionKind::Prefix(Box::new(PrefixExpression { - operator: prefix.operator, - rhs: prefix.rhs.to_ast(interner), - })), - HirExpression::Infix(infix) => ExpressionKind::Infix(Box::new(InfixExpression { - lhs: infix.lhs.to_ast(interner), - operator: Spanned::from(infix.operator.location.span, infix.operator.kind), - rhs: infix.rhs.to_ast(interner), - })), - HirExpression::Index(index) => ExpressionKind::Index(Box::new(IndexExpression { - collection: index.collection.to_ast(interner), - index: index.index.to_ast(interner), - })), - HirExpression::Constructor(constructor) => { - let type_name = constructor.r#type.borrow().name.to_string(); - let type_name = Path::from_single(type_name, span); - let fields = - vecmap(constructor.fields, |(name, expr)| (name, expr.to_ast(interner))); - - ExpressionKind::Constructor(Box::new(ConstructorExpression { type_name, fields })) - } - HirExpression::MemberAccess(access) => { - ExpressionKind::MemberAccess(Box::new(MemberAccessExpression { - lhs: access.lhs.to_ast(interner), - rhs: access.rhs, - })) - } - HirExpression::Call(call) => { - let func = Box::new(call.func.to_ast(interner)); - let arguments = vecmap(call.arguments, |arg| arg.to_ast(interner)); - ExpressionKind::Call(Box::new(CallExpression { func, arguments })) - } - HirExpression::MethodCall(method_call) => { - ExpressionKind::MethodCall(Box::new(MethodCallExpression { - object: method_call.object.to_ast(interner), - method_name: method_call.method, - arguments: vecmap(method_call.arguments, |arg| arg.to_ast(interner)), - generics: method_call - .generics - .map(|option| option.iter().map(|generic| generic.to_ast()).collect()), - })) - } - HirExpression::Cast(cast) => { - let lhs = cast.lhs.to_ast(interner); - let r#type = cast.r#type.to_ast(); - ExpressionKind::Cast(Box::new(CastExpression { lhs, r#type })) - } - HirExpression::If(if_expr) => ExpressionKind::If(Box::new(IfExpression { - condition: if_expr.condition.to_ast(interner), - consequence: if_expr.consequence.to_ast(interner), - alternative: if_expr.alternative.map(|expr| expr.to_ast(interner)), - })), - HirExpression::Tuple(fields) => { - ExpressionKind::Tuple(vecmap(fields, |field| field.to_ast(interner))) - } - HirExpression::Lambda(lambda) => { - let parameters = vecmap(lambda.parameters, |(pattern, typ)| { - (pattern.into_ast(interner), typ.to_ast()) - }); - let return_type = lambda.return_type.to_ast(); - let body = lambda.body.to_ast(interner); - ExpressionKind::Lambda(Box::new(Lambda { parameters, return_type, body })) - } - HirExpression::Error => ExpressionKind::Error, - HirExpression::Comptime(block) => ExpressionKind::Comptime(block.into_ast(interner)), - HirExpression::Quote(block) => ExpressionKind::Quote(block), - - // A macro was evaluated here! - HirExpression::Unquote(block) => ExpressionKind::Block(block), - }; - - Expression::new(kind, span) - } -} - -impl HirPattern { - fn into_ast(self, interner: &NodeInterner) -> Pattern { - match self { - HirPattern::Identifier(ident) => Pattern::Identifier(ident.to_ast(interner)), - HirPattern::Mutable(pattern, location) => { - let pattern = Box::new(pattern.into_ast(interner)); - Pattern::Mutable(pattern, location.span, false) - } - HirPattern::Tuple(patterns, location) => { - let patterns = vecmap(patterns, |pattern| pattern.into_ast(interner)); - Pattern::Tuple(patterns, location.span) - } - HirPattern::Struct(typ, patterns, location) => { - let patterns = - vecmap(patterns, |(name, pattern)| (name, pattern.into_ast(interner))); - let name = match typ.follow_bindings() { - Type::Struct(struct_def, _) => { - let struct_def = struct_def.borrow(); - struct_def.name.0.contents.clone() - } - // This pass shouldn't error so if the type isn't a struct we just get a string - // representation of any other type and use that. We're relying on name - // resolution to fail later when this Ast is re-converted to Hir. - other => other.to_string(), - }; - // The name span is lost here - let path = Path::from_single(name, location.span); - Pattern::Struct(path, patterns, location.span) - } - } - } -} - -impl HirIdent { - fn to_ast(&self, interner: &NodeInterner) -> Ident { - let name = interner.definition_name(self.id).to_owned(); - Ident(Spanned::from(self.location.span, name)) - } -} - -impl Type { - fn to_ast(&self) -> UnresolvedType { - let typ = match self { - Type::FieldElement => UnresolvedTypeData::FieldElement, - Type::Array(length, element) => { - let length = length.to_type_expression(); - let element = Box::new(element.to_ast()); - UnresolvedTypeData::Array(length, element) - } - Type::Slice(element) => { - let element = Box::new(element.to_ast()); - UnresolvedTypeData::Slice(element) - } - Type::Integer(sign, bit_size) => UnresolvedTypeData::Integer(*sign, *bit_size), - Type::Bool => UnresolvedTypeData::Bool, - Type::String(length) => { - let length = length.to_type_expression(); - UnresolvedTypeData::String(Some(length)) - } - Type::FmtString(length, element) => { - let length = length.to_type_expression(); - let element = Box::new(element.to_ast()); - UnresolvedTypeData::FormatString(length, element) - } - Type::Unit => UnresolvedTypeData::Unit, - Type::Tuple(fields) => { - let fields = vecmap(fields, |field| field.to_ast()); - UnresolvedTypeData::Tuple(fields) - } - Type::Struct(def, generics) => { - let struct_def = def.borrow(); - let generics = vecmap(generics, |generic| generic.to_ast()); - let name = Path::from_ident(struct_def.name.clone()); - UnresolvedTypeData::Named(name, generics, false) - } - Type::Alias(type_def, generics) => { - // Keep the alias name instead of expanding this in case the - // alias' definition was changed - let type_def = type_def.borrow(); - let generics = vecmap(generics, |generic| generic.to_ast()); - let name = Path::from_ident(type_def.name.clone()); - UnresolvedTypeData::Named(name, generics, false) - } - Type::TypeVariable(_, _) => todo!("Convert Type::TypeVariable Hir -> Ast"), - Type::TraitAsType(_, name, generics) => { - let generics = vecmap(generics, |generic| generic.to_ast()); - let name = Path::from_single(name.as_ref().clone(), Span::default()); - UnresolvedTypeData::TraitAsType(name, generics) - } - Type::NamedGeneric(_, name) => { - let name = Path::from_single(name.as_ref().clone(), Span::default()); - UnresolvedTypeData::TraitAsType(name, Vec::new()) - } - Type::Function(args, ret, env) => { - let args = vecmap(args, |arg| arg.to_ast()); - let ret = Box::new(ret.to_ast()); - let env = Box::new(env.to_ast()); - UnresolvedTypeData::Function(args, ret, env) - } - Type::MutableReference(element) => { - let element = Box::new(element.to_ast()); - UnresolvedTypeData::MutableReference(element) - } - // Type::Forall is only for generic functions which don't store a type - // in their Ast so they don't need to call to_ast for their Forall type. - // Since there is no UnresolvedTypeData equivalent for Type::Forall, we use - // this to ignore this case since it shouldn't be needed anyway. - Type::Forall(_, typ) => return typ.to_ast(), - Type::Constant(_) => panic!("Type::Constant where a type was expected: {self:?}"), - Type::Code => UnresolvedTypeData::Code, - Type::Error => UnresolvedTypeData::Error, - }; - - UnresolvedType { typ, span: None } - } - - fn to_type_expression(&self) -> UnresolvedTypeExpression { - let span = Span::default(); - - match self.follow_bindings() { - Type::Constant(length) => UnresolvedTypeExpression::Constant(length, span), - Type::NamedGeneric(_, name) => { - let path = Path::from_single(name.as_ref().clone(), span); - UnresolvedTypeExpression::Variable(path) - } - // TODO: This should be turned into a proper error. - other => panic!("Cannot represent {other:?} as type expression"), - } - } -} - -impl HirLValue { - fn into_ast(self, interner: &NodeInterner) -> LValue { - match self { - HirLValue::Ident(ident, _) => LValue::Ident(ident.to_ast(interner)), - HirLValue::MemberAccess { object, field_name, field_index: _, typ: _, location } => { - let object = Box::new(object.into_ast(interner)); - LValue::MemberAccess { object, field_name, span: location.span } - } - HirLValue::Index { array, index, typ: _, location } => { - let array = Box::new(array.into_ast(interner)); - let index = index.to_ast(interner); - LValue::Index { array, index, span: location.span } - } - HirLValue::Dereference { lvalue, element_type: _, location } => { - let lvalue = Box::new(lvalue.into_ast(interner)); - LValue::Dereference(lvalue, location.span) - } - } - } -} - -impl HirArrayLiteral { - fn into_ast(self, interner: &NodeInterner, span: Span) -> ArrayLiteral { - match self { - HirArrayLiteral::Standard(elements) => { - ArrayLiteral::Standard(vecmap(elements, |element| element.to_ast(interner))) - } - HirArrayLiteral::Repeated { repeated_element, length } => { - let repeated_element = Box::new(repeated_element.to_ast(interner)); - let length = match length { - Type::Constant(length) => { - let literal = Literal::Integer((length as u128).into(), false); - let kind = ExpressionKind::Literal(literal); - Box::new(Expression::new(kind, span)) - } - other => panic!("Cannot convert non-constant type for repeated array literal from Hir -> Ast: {other:?}"), - }; - ArrayLiteral::Repeated { repeated_element, length } - } - } - } -} - -impl HirBlockExpression { - fn into_ast(self, interner: &NodeInterner) -> BlockExpression { - let statements = vecmap(self.statements, |statement| statement.to_ast(interner)); - BlockExpression { statements } - } -} diff --git a/compiler/noirc_frontend/src/hir/comptime/mod.rs b/compiler/noirc_frontend/src/hir/comptime/mod.rs index 0c8efae63ee..ab984d2f2be 100644 --- a/compiler/noirc_frontend/src/hir/comptime/mod.rs +++ b/compiler/noirc_frontend/src/hir/comptime/mod.rs @@ -1,5 +1,4 @@ mod errors; -mod hir_to_ast; mod interpreter; mod scan; mod tests; From 05df0cc30e6aaed70989b31a3b09d60afd1510a0 Mon Sep 17 00:00:00 2001 From: jfecher Date: Thu, 30 May 2024 13:53:16 -0500 Subject: [PATCH 58/61] chore: Remove unused `new_variables` argument from `resolve_type_inner` (#5148) # Description ## Problem\* ## Summary\* This argument was previously used to add a fresh generic to a function's signature when we found a slice type back when those used a generic for the length. Since Slice types are now their own type this code path isn't accessible anymore (*). (\*) The codepath is technically accessible by trying to use a string slice type but we don't support these yet anyway so I've removed them. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_frontend/src/ast/mod.rs | 7 +- compiler/noirc_frontend/src/elaborator/mod.rs | 2 +- .../noirc_frontend/src/elaborator/types.rs | 77 +++++-------------- .../src/hir/resolution/resolver.rs | 77 ++++++------------- compiler/noirc_frontend/src/parser/parser.rs | 4 +- 5 files changed, 46 insertions(+), 121 deletions(-) diff --git a/compiler/noirc_frontend/src/ast/mod.rs b/compiler/noirc_frontend/src/ast/mod.rs index 090a41fa7d9..a9d9f232b64 100644 --- a/compiler/noirc_frontend/src/ast/mod.rs +++ b/compiler/noirc_frontend/src/ast/mod.rs @@ -92,7 +92,7 @@ pub enum UnresolvedTypeData { Integer(Signedness, IntegerBitSize), // u32 = Integer(unsigned, ThirtyTwo) Bool, Expression(UnresolvedTypeExpression), - String(Option), + String(UnresolvedTypeExpression), FormatString(UnresolvedTypeExpression, Box), Unit, @@ -191,10 +191,7 @@ impl std::fmt::Display for UnresolvedTypeData { } Expression(expression) => expression.fmt(f), Bool => write!(f, "bool"), - String(len) => match len { - None => write!(f, "str<_>"), - Some(len) => write!(f, "str<{len}>"), - }, + String(len) => write!(f, "str<{len}>"), FormatString(len, elements) => write!(f, "fmt<{len}, {elements}"), Function(args, ret, env) => { let args = vecmap(args, ToString::to_string).join(", "); diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index a0ff3c12ae3..3c9383b8262 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -566,7 +566,7 @@ impl<'context> Elaborator<'context> { UnresolvedTypeData::TraitAsType(path, args) => { self.desugar_impl_trait_arg(path, args, &mut generics, &mut trait_constraints) } - _ => self.resolve_type_inner(typ, &mut generics), + _ => self.resolve_type_inner(typ), }; self.check_if_type_is_valid_for_program_input( diff --git a/compiler/noirc_frontend/src/elaborator/types.rs b/compiler/noirc_frontend/src/elaborator/types.rs index 059ff857df8..955b4af327a 100644 --- a/compiler/noirc_frontend/src/elaborator/types.rs +++ b/compiler/noirc_frontend/src/elaborator/types.rs @@ -39,59 +39,52 @@ impl<'context> Elaborator<'context> { /// Translates an UnresolvedType to a Type pub(super) fn resolve_type(&mut self, typ: UnresolvedType) -> Type { let span = typ.span; - let resolved_type = self.resolve_type_inner(typ, &mut vec![]); + let resolved_type = self.resolve_type_inner(typ); if resolved_type.is_nested_slice() { self.push_err(ResolverError::NestedSlices { span: span.unwrap() }); } - resolved_type } /// Translates an UnresolvedType into a Type and appends any /// freshly created TypeVariables created to new_variables. - pub fn resolve_type_inner( - &mut self, - typ: UnresolvedType, - new_variables: &mut Generics, - ) -> Type { + pub fn resolve_type_inner(&mut self, typ: UnresolvedType) -> Type { use crate::ast::UnresolvedTypeData::*; let resolved_type = match typ.typ { FieldElement => Type::FieldElement, Array(size, elem) => { - let elem = Box::new(self.resolve_type_inner(*elem, new_variables)); - let size = self.resolve_array_size(Some(size), new_variables); + let elem = Box::new(self.resolve_type_inner(*elem)); + let size = self.convert_expression_type(size); Type::Array(Box::new(size), elem) } Slice(elem) => { - let elem = Box::new(self.resolve_type_inner(*elem, new_variables)); + let elem = Box::new(self.resolve_type_inner(*elem)); Type::Slice(elem) } Expression(expr) => self.convert_expression_type(expr), Integer(sign, bits) => Type::Integer(sign, bits), Bool => Type::Bool, String(size) => { - let resolved_size = self.resolve_array_size(size, new_variables); + let resolved_size = self.convert_expression_type(size); Type::String(Box::new(resolved_size)) } FormatString(size, fields) => { let resolved_size = self.convert_expression_type(size); - let fields = self.resolve_type_inner(*fields, new_variables); + let fields = self.resolve_type_inner(*fields); Type::FmtString(Box::new(resolved_size), Box::new(fields)) } Code => Type::Code, Unit => Type::Unit, Unspecified => Type::Error, Error => Type::Error, - Named(path, args, _) => self.resolve_named_type(path, args, new_variables), - TraitAsType(path, args) => self.resolve_trait_as_type(path, args, new_variables), + Named(path, args, _) => self.resolve_named_type(path, args), + TraitAsType(path, args) => self.resolve_trait_as_type(path, args), - Tuple(fields) => { - Type::Tuple(vecmap(fields, |field| self.resolve_type_inner(field, new_variables))) - } + Tuple(fields) => Type::Tuple(vecmap(fields, |field| self.resolve_type_inner(field))), Function(args, ret, env) => { - let args = vecmap(args, |arg| self.resolve_type_inner(arg, new_variables)); - let ret = Box::new(self.resolve_type_inner(*ret, new_variables)); + let args = vecmap(args, |arg| self.resolve_type_inner(arg)); + let ret = Box::new(self.resolve_type_inner(*ret)); // expect() here is valid, because the only places we don't have a span are omitted types // e.g. a function without return type implicitly has a spanless UnresolvedType::Unit return type @@ -99,7 +92,7 @@ impl<'context> Elaborator<'context> { let env_span = env.span.expect("Unexpected missing span for closure environment type"); - let env = Box::new(self.resolve_type_inner(*env, new_variables)); + let env = Box::new(self.resolve_type_inner(*env)); match *env { Type::Unit | Type::Tuple(_) | Type::NamedGeneric(_, _) => { @@ -115,9 +108,9 @@ impl<'context> Elaborator<'context> { } } MutableReference(element) => { - Type::MutableReference(Box::new(self.resolve_type_inner(*element, new_variables))) + Type::MutableReference(Box::new(self.resolve_type_inner(*element))) } - Parenthesized(typ) => self.resolve_type_inner(*typ, new_variables), + Parenthesized(typ) => self.resolve_type_inner(*typ), }; if let Type::Struct(_, _) = resolved_type { @@ -136,12 +129,7 @@ impl<'context> Elaborator<'context> { self.generics.iter().find(|(name, _, _)| name.as_ref() == target_name) } - fn resolve_named_type( - &mut self, - path: Path, - args: Vec, - new_variables: &mut Generics, - ) -> Type { + fn resolve_named_type(&mut self, path: Path, args: Vec) -> Type { if args.is_empty() { if let Some(typ) = self.lookup_generic_or_global_type(&path) { return typ; @@ -164,7 +152,7 @@ impl<'context> Elaborator<'context> { } let span = path.span(); - let mut args = vecmap(args, |arg| self.resolve_type_inner(arg, new_variables)); + let mut args = vecmap(args, |arg| self.resolve_type_inner(arg)); if let Some(type_alias) = self.lookup_type_alias(path.clone()) { let type_alias = type_alias.borrow(); @@ -230,13 +218,8 @@ impl<'context> Elaborator<'context> { } } - fn resolve_trait_as_type( - &mut self, - path: Path, - args: Vec, - new_variables: &mut Generics, - ) -> Type { - let args = vecmap(args, |arg| self.resolve_type_inner(arg, new_variables)); + fn resolve_trait_as_type(&mut self, path: Path, args: Vec) -> Type { + let args = vecmap(args, |arg| self.resolve_type_inner(arg)); if let Some(t) = self.lookup_trait_or_error(path) { Type::TraitAsType(t.id, Rc::new(t.name.to_string()), args) @@ -286,26 +269,6 @@ impl<'context> Elaborator<'context> { } } - fn resolve_array_size( - &mut self, - length: Option, - new_variables: &mut Generics, - ) -> Type { - match length { - None => { - let id = self.interner.next_type_variable_id(); - let typevar = TypeVariable::unbound(id); - new_variables.push(typevar.clone()); - - // 'Named'Generic is a bit of a misnomer here, we want a type variable that - // wont be bound over but this one has no name since we do not currently - // require users to explicitly be generic over array lengths. - Type::NamedGeneric(typevar, Rc::new("".into())) - } - Some(length) => self.convert_expression_type(length), - } - } - pub(super) fn convert_expression_type(&mut self, length: UnresolvedTypeExpression) -> Type { match length { UnresolvedTypeExpression::Variable(path) => { @@ -622,7 +585,7 @@ impl<'context> Elaborator<'context> { pub(super) fn resolve_inferred_type(&mut self, typ: UnresolvedType) -> Type { match &typ.typ { UnresolvedTypeData::Unspecified => self.interner.next_type_variable(), - _ => self.resolve_type_inner(typ, &mut vec![]), + _ => self.resolve_type(typ), } } diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index fd77312e4f2..35ba964c499 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -538,45 +538,43 @@ impl<'a> Resolver<'a> { /// Translates an UnresolvedType into a Type and appends any /// freshly created TypeVariables created to new_variables. - fn resolve_type_inner(&mut self, typ: UnresolvedType, new_variables: &mut Generics) -> Type { + fn resolve_type_inner(&mut self, typ: UnresolvedType) -> Type { use crate::ast::UnresolvedTypeData::*; let resolved_type = match typ.typ { FieldElement => Type::FieldElement, Array(size, elem) => { - let elem = Box::new(self.resolve_type_inner(*elem, new_variables)); - let size = self.resolve_array_size(Some(size), new_variables); + let elem = Box::new(self.resolve_type_inner(*elem)); + let size = self.convert_expression_type(size); Type::Array(Box::new(size), elem) } Slice(elem) => { - let elem = Box::new(self.resolve_type_inner(*elem, new_variables)); + let elem = Box::new(self.resolve_type_inner(*elem)); Type::Slice(elem) } Expression(expr) => self.convert_expression_type(expr), Integer(sign, bits) => Type::Integer(sign, bits), Bool => Type::Bool, String(size) => { - let resolved_size = self.resolve_array_size(size, new_variables); + let resolved_size = self.convert_expression_type(size); Type::String(Box::new(resolved_size)) } FormatString(size, fields) => { let resolved_size = self.convert_expression_type(size); - let fields = self.resolve_type_inner(*fields, new_variables); + let fields = self.resolve_type_inner(*fields); Type::FmtString(Box::new(resolved_size), Box::new(fields)) } Code => Type::Code, Unit => Type::Unit, Unspecified => Type::Error, Error => Type::Error, - Named(path, args, _) => self.resolve_named_type(path, args, new_variables), - TraitAsType(path, args) => self.resolve_trait_as_type(path, args, new_variables), + Named(path, args, _) => self.resolve_named_type(path, args), + TraitAsType(path, args) => self.resolve_trait_as_type(path, args), - Tuple(fields) => { - Type::Tuple(vecmap(fields, |field| self.resolve_type_inner(field, new_variables))) - } + Tuple(fields) => Type::Tuple(vecmap(fields, |field| self.resolve_type_inner(field))), Function(args, ret, env) => { - let args = vecmap(args, |arg| self.resolve_type_inner(arg, new_variables)); - let ret = Box::new(self.resolve_type_inner(*ret, new_variables)); + let args = vecmap(args, |arg| self.resolve_type_inner(arg)); + let ret = Box::new(self.resolve_type_inner(*ret)); // expect() here is valid, because the only places we don't have a span are omitted types // e.g. a function without return type implicitly has a spanless UnresolvedType::Unit return type @@ -584,7 +582,7 @@ impl<'a> Resolver<'a> { let env_span = env.span.expect("Unexpected missing span for closure environment type"); - let env = Box::new(self.resolve_type_inner(*env, new_variables)); + let env = Box::new(self.resolve_type_inner(*env)); match *env { Type::Unit | Type::Tuple(_) | Type::NamedGeneric(_, _) => { @@ -600,9 +598,9 @@ impl<'a> Resolver<'a> { } } MutableReference(element) => { - Type::MutableReference(Box::new(self.resolve_type_inner(*element, new_variables))) + Type::MutableReference(Box::new(self.resolve_type_inner(*element))) } - Parenthesized(typ) => self.resolve_type_inner(*typ, new_variables), + Parenthesized(typ) => self.resolve_type_inner(*typ), }; if let Type::Struct(_, _) = resolved_type { @@ -621,12 +619,7 @@ impl<'a> Resolver<'a> { self.generics.iter().find(|(name, _, _)| name.as_ref() == target_name) } - fn resolve_named_type( - &mut self, - path: Path, - args: Vec, - new_variables: &mut Generics, - ) -> Type { + fn resolve_named_type(&mut self, path: Path, args: Vec) -> Type { if args.is_empty() { if let Some(typ) = self.lookup_generic_or_global_type(&path) { return typ; @@ -649,7 +642,7 @@ impl<'a> Resolver<'a> { } let span = path.span(); - let mut args = vecmap(args, |arg| self.resolve_type_inner(arg, new_variables)); + let mut args = vecmap(args, |arg| self.resolve_type_inner(arg)); if let Some(type_alias) = self.lookup_type_alias(path.clone()) { let type_alias = type_alias.borrow(); @@ -715,13 +708,8 @@ impl<'a> Resolver<'a> { } } - fn resolve_trait_as_type( - &mut self, - path: Path, - args: Vec, - new_variables: &mut Generics, - ) -> Type { - let args = vecmap(args, |arg| self.resolve_type_inner(arg, new_variables)); + fn resolve_trait_as_type(&mut self, path: Path, args: Vec) -> Type { + let args = vecmap(args, |arg| self.resolve_type_inner(arg)); if let Some(t) = self.lookup_trait_or_error(path) { Type::TraitAsType(t.id, Rc::new(t.name.to_string()), args) @@ -774,26 +762,6 @@ impl<'a> Resolver<'a> { } } - fn resolve_array_size( - &mut self, - length: Option, - new_variables: &mut Generics, - ) -> Type { - match length { - None => { - let id = self.interner.next_type_variable_id(); - let typevar = TypeVariable::unbound(id); - new_variables.push(typevar.clone()); - - // 'Named'Generic is a bit of a misnomer here, we want a type variable that - // wont be bound over but this one has no name since we do not currently - // require users to explicitly be generic over array lengths. - Type::NamedGeneric(typevar, Rc::new("".into())) - } - Some(length) => self.convert_expression_type(length), - } - } - fn convert_expression_type(&mut self, length: UnresolvedTypeExpression) -> Type { match length { UnresolvedTypeExpression::Variable(path) => { @@ -846,11 +814,10 @@ impl<'a> Resolver<'a> { /// Translates an UnresolvedType to a Type pub fn resolve_type(&mut self, typ: UnresolvedType) -> Type { let span = typ.span; - let resolved_type = self.resolve_type_inner(typ, &mut vec![]); + let resolved_type = self.resolve_type_inner(typ); if resolved_type.is_nested_slice() { self.errors.push(ResolverError::NestedSlices { span: span.unwrap() }); } - resolved_type } @@ -891,7 +858,7 @@ impl<'a> Resolver<'a> { fn resolve_inferred_type(&mut self, typ: UnresolvedType) -> Type { match &typ.typ { UnresolvedTypeData::Unspecified => self.interner.next_type_variable(), - _ => self.resolve_type_inner(typ, &mut vec![]), + _ => self.resolve_type(typ), } } @@ -1019,7 +986,7 @@ impl<'a> Resolver<'a> { // indicate we should code generate in the same way. Thus, we unify the attributes into one flag here. let has_inline_attribute = has_no_predicates_attribute || should_fold; - let mut generics = vecmap(&self.generics, |(_, typevar, _)| typevar.clone()); + let generics = vecmap(&self.generics, |(_, typevar, _)| typevar.clone()); let mut parameters = vec![]; let mut parameter_types = vec![]; @@ -1032,7 +999,7 @@ impl<'a> Resolver<'a> { } let pattern = self.resolve_pattern(pattern, DefinitionKind::Local(None)); - let typ = self.resolve_type_inner(typ, &mut generics); + let typ = self.resolve_type_inner(typ); parameters.push((pattern, typ.clone(), visibility)); parameter_types.push(typ); diff --git a/compiler/noirc_frontend/src/parser/parser.rs b/compiler/noirc_frontend/src/parser/parser.rs index 890ab795e00..702ea79af9d 100644 --- a/compiler/noirc_frontend/src/parser/parser.rs +++ b/compiler/noirc_frontend/src/parser/parser.rs @@ -745,9 +745,7 @@ fn bool_type() -> impl NoirParser { fn string_type() -> impl NoirParser { keyword(Keyword::String) - .ignore_then( - type_expression().delimited_by(just(Token::Less), just(Token::Greater)).or_not(), - ) + .ignore_then(type_expression().delimited_by(just(Token::Less), just(Token::Greater))) .map_with_span(|expr, span| UnresolvedTypeData::String(expr).with_span(span)) } From d6122eb9e88aa2b1bb6c990e452fa9678ae49704 Mon Sep 17 00:00:00 2001 From: jfecher Date: Thu, 30 May 2024 13:56:41 -0500 Subject: [PATCH 59/61] fix(experimental elaborator): Fix frontend tests when `--use-elaborator` flag is specified (#5145) # Description ## Problem\* Resolves https://github.com/noir-lang/noir/issues/5146 Fixes all failing frontend tests with the elaborator ## Summary\* This PR includes a few fixes: - Use `check_trait_impl_method_matches_declaration` to issue errors when a trait impl method is declared with an incorrect signature. - `define_function_meta` for default trait functions on impls when they're copied over. Also make sure to set `self.current_trait_impl` and `self.self_type` for them as well. - Use `try_get_trait_implementation` when getting a trait impl may fail (which may happen if there was a previous error resolving the trait for that impl). This was triggering on the test where we tried to declare a trait impl implementing a struct rather than a trait. - `check_trait_wrong_parameter_type` has a duplicate error on master but not in the elaborator so I changed the expected error count there. ## Additional Context After this PR all existing code _should_ work with the elaborator and we can get the word out to get others testing the `--use-elaborator` flag for any errors/panics. ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_frontend/src/elaborator/mod.rs | 16 +++++++++++++--- .../noirc_frontend/src/hir/type_check/mod.rs | 8 +++++++- compiler/noirc_frontend/src/node_interner.rs | 4 ++++ compiler/noirc_frontend/src/tests.rs | 13 +++++++------ 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index 3c9383b8262..594c0690033 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -15,7 +15,7 @@ use crate::{ }, resolution::{errors::ResolverError, path_resolver::PathResolver, resolver::LambdaContext}, scope::ScopeForest as GenericScopeForest, - type_check::TypeCheckError, + type_check::{check_trait_impl_method_matches_declaration, TypeCheckError}, }, hir_def::{expr::HirIdent, function::Parameters, traits::TraitConstraint}, macros_api::{ @@ -851,6 +851,12 @@ impl<'context> Elaborator<'context> { self.generics = trait_impl.resolved_generics; self.current_trait_impl = trait_impl.impl_id; + for (module, function, _) in &trait_impl.methods.functions { + self.local_module = *module; + let errors = check_trait_impl_method_matches_declaration(self.interner, *function); + self.errors.extend(errors.into_iter().map(|error| (error.into(), self.file))); + } + self.elaborate_functions(trait_impl.methods); self.self_type = None; @@ -877,12 +883,14 @@ impl<'context> Elaborator<'context> { fn collect_trait_impl(&mut self, trait_impl: &mut UnresolvedTraitImpl) { self.local_module = trait_impl.module_id; self.file = trait_impl.file_id; + self.current_trait_impl = trait_impl.impl_id; trait_impl.trait_id = self.resolve_trait_by_path(trait_impl.trait_path.clone()); let self_type = trait_impl.methods.self_type.clone(); let self_type = self_type.expect("Expected struct type to be set before collect_trait_impl"); + self.self_type = Some(self_type.clone()); let self_type_span = trait_impl.object_type.span; if matches!(self_type, Type::MutableReference(_)) { @@ -890,12 +898,11 @@ impl<'context> Elaborator<'context> { self.push_err(DefCollectorErrorKind::MutableReferenceInTraitImpl { span }); } - assert!(trait_impl.trait_id.is_some()); if let Some(trait_id) = trait_impl.trait_id { + self.generics = trait_impl.resolved_generics.clone(); self.collect_trait_impl_methods(trait_id, trait_impl); let span = trait_impl.object_type.span.expect("All trait self types should have spans"); - self.generics = trait_impl.resolved_generics.clone(); self.declare_methods_on_struct(true, &mut trait_impl.methods, span); let methods = trait_impl.methods.function_ids(); @@ -945,6 +952,8 @@ impl<'context> Elaborator<'context> { } self.generics.clear(); + self.current_trait_impl = None; + self.self_type = None; } fn get_module_mut(&mut self, module: ModuleId) -> &mut ModuleData { @@ -1059,6 +1068,7 @@ impl<'context> Elaborator<'context> { let module = self.module_id(); let location = Location::new(default_impl.def.span, trait_impl.file_id); self.interner.push_function(func_id, &default_impl.def, module, location); + self.define_function_meta(&mut default_impl_clone, func_id, false); func_ids_in_trait.insert(func_id); ordered_methods.push(( method.default_impl_module_id, diff --git a/compiler/noirc_frontend/src/hir/type_check/mod.rs b/compiler/noirc_frontend/src/hir/type_check/mod.rs index de2e575b4e2..65a3186b004 100644 --- a/compiler/noirc_frontend/src/hir/type_check/mod.rs +++ b/compiler/noirc_frontend/src/hir/type_check/mod.rs @@ -237,7 +237,13 @@ pub(crate) fn check_trait_impl_method_matches_declaration( let impl_ = meta.trait_impl.expect("Trait impl function should have a corresponding trait impl"); - let impl_ = interner.get_trait_implementation(impl_); + + // If the trait implementation is not defined in the interner then there was a previous + // error in resolving the trait path and there is likely no trait for this impl. + let Some(impl_) = interner.try_get_trait_implementation(impl_) else { + return errors; + }; + let impl_ = impl_.borrow(); let trait_info = interner.get_trait(impl_.trait_id); diff --git a/compiler/noirc_frontend/src/node_interner.rs b/compiler/noirc_frontend/src/node_interner.rs index 60cc2580bb8..e28a0a64ad0 100644 --- a/compiler/noirc_frontend/src/node_interner.rs +++ b/compiler/noirc_frontend/src/node_interner.rs @@ -1145,6 +1145,10 @@ impl NodeInterner { } } + pub fn try_get_trait_implementation(&self, id: TraitImplId) -> Option> { + self.trait_implementations.get(&id).cloned() + } + pub fn get_trait_implementation(&self, id: TraitImplId) -> Shared { self.trait_implementations[&id].clone() } diff --git a/compiler/noirc_frontend/src/tests.rs b/compiler/noirc_frontend/src/tests.rs index bd81752c046..99215c8f173 100644 --- a/compiler/noirc_frontend/src/tests.rs +++ b/compiler/noirc_frontend/src/tests.rs @@ -494,7 +494,10 @@ fn check_trait_wrong_parameter_type() { }"; let errors = get_program_errors(src); assert!(!has_parser_error(&errors)); - assert!(errors.len() == 2, "Expected 2 errors, got: {:?}", errors); + + // This is a duplicate error in the name resolver & type checker. + // In the elaborator there is no duplicate and only 1 error is issued + assert!(errors.len() <= 2, "Expected 1 or 2 errors, got: {:?}", errors); for (err, _file_id) in errors { match &err { @@ -593,22 +596,20 @@ fn check_impl_struct_not_trait() { bar: Field, array: [Field; 2], } - + struct Default { x: Field, z: Field, } - // Default is struct not a trait + // Default is a struct not a trait impl Default for Foo { fn default(x: Field, y: Field) -> Self { Self { bar: x, array: [x,y] } } } - fn main() { - } - + fn main() {} "; let errors = get_program_errors(src); assert!(!has_parser_error(&errors)); From 1252b5fcc7ed56bb55e95745b83be6e556805397 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Fri, 31 May 2024 12:38:01 +0100 Subject: [PATCH 60/61] feat: place return value witnesses directly after function arguments (#5142) # Description ## Problem\* Resolves #5104 ## Summary\* This PR preallocates some witnesses to hold the return values at the beginning of ACIR gen and then adds assertions to fill these witnesses with the return values. This ensures that the return values will be placed in the witness map directly after any function inputs (reasons for this being desirable are laid out in #5104) ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: jfecher --- .../src/ssa/acir_gen/acir_ir/acir_variable.rs | 13 +- .../ssa/acir_gen/acir_ir/generated_acir.rs | 8 -- .../noirc_evaluator/src/ssa/acir_gen/mod.rs | 122 +++++++++++------- 3 files changed, 75 insertions(+), 68 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index 93200d4f841..93dd47afe68 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -255,7 +255,7 @@ impl AcirContext { } /// Converts an [`AcirVar`] to a [`Witness`] - fn var_to_witness(&mut self, var: AcirVar) -> Result { + pub(crate) fn var_to_witness(&mut self, var: AcirVar) -> Result { let expression = self.var_to_expression(var)?; let witness = if let Some(constant) = expression.to_const() { // Check if a witness has been assigned this value already, if so reuse it. @@ -1027,15 +1027,6 @@ impl AcirContext { Ok(remainder) } - /// Converts the `AcirVar` to a `Witness` if it hasn't been already, and appends it to the - /// `GeneratedAcir`'s return witnesses. - pub(crate) fn return_var(&mut self, acir_var: AcirVar) -> Result<(), InternalError> { - let return_var = self.get_or_create_witness_var(acir_var)?; - let witness = self.var_to_witness(return_var)?; - self.acir_ir.push_return_witness(witness); - Ok(()) - } - /// Constrains the `AcirVar` variable to be of type `NumericType`. pub(crate) fn range_constrain_var( &mut self, @@ -1538,9 +1529,11 @@ impl AcirContext { pub(crate) fn finish( mut self, inputs: Vec, + return_values: Vec, warnings: Vec, ) -> GeneratedAcir { self.acir_ir.input_witnesses = inputs; + self.acir_ir.return_witnesses = return_values; self.acir_ir.warnings = warnings; self.acir_ir } diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index 6c79c0a228d..9a09e7c06ee 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -45,9 +45,6 @@ pub(crate) struct GeneratedAcir { opcodes: Vec>, /// All witness indices that comprise the final return value of the program - /// - /// Note: This may contain repeated indices, which is necessary for later mapping into the - /// abi's return type. pub(crate) return_witnesses: Vec, /// All witness indices which are inputs to the main function @@ -164,11 +161,6 @@ impl GeneratedAcir { fresh_witness } - - /// Adds a witness index to the program's return witnesses. - pub(crate) fn push_return_witness(&mut self, witness: Witness) { - self.return_witnesses.push(witness); - } } impl GeneratedAcir { diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index 13677506d0b..6d7c5e570c1 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -36,11 +36,7 @@ use acvm::acir::circuit::brillig::BrilligBytecode; use acvm::acir::circuit::{AssertionPayload, ErrorSelector, OpcodeLocation}; use acvm::acir::native_types::Witness; use acvm::acir::BlackBoxFunc; -use acvm::{ - acir::AcirField, - acir::{circuit::opcodes::BlockId, native_types::Expression}, - FieldElement, -}; +use acvm::{acir::circuit::opcodes::BlockId, acir::AcirField, FieldElement}; use fxhash::FxHashMap as HashMap; use im::Vector; use iter_extended::{try_vecmap, vecmap}; @@ -330,38 +326,10 @@ impl Ssa { bytecode: brillig.byte_code, }); - let runtime_types = self.functions.values().map(|function| function.runtime()); - for (acir, runtime_type) in acirs.iter_mut().zip(runtime_types) { - if matches!(runtime_type, RuntimeType::Acir(_)) { - generate_distinct_return_witnesses(acir); - } - } - Ok((acirs, brillig, self.error_selector_to_type)) } } -fn generate_distinct_return_witnesses(acir: &mut GeneratedAcir) { - // Create a witness for each return witness we have to guarantee that the return witnesses match the standard - // layout for serializing those types as if they were being passed as inputs. - // - // This is required for recursion as otherwise in situations where we cannot make use of the program's ABI - // (e.g. for `std::verify_proof` or the solidity verifier), we need extra knowledge about the program we're - // working with rather than following the standard ABI encoding rules. - // - // TODO: We're being conservative here by generating a new witness for every expression. - // This means that we're likely to get a number of constraints which are just renumbering witnesses. - // This can be tackled by: - // - Tracking the last assigned public input witness and only renumbering a witness if it is below this value. - // - Modifying existing constraints to rearrange their outputs so they are suitable - // - See: https://github.com/noir-lang/noir/pull/4467 - let distinct_return_witness = vecmap(acir.return_witnesses.clone(), |return_witness| { - acir.create_witness_for_expression(&Expression::from(return_witness)) - }); - - acir.return_witnesses = distinct_return_witness; -} - impl<'a> Context<'a> { fn new(shared_context: &'a mut SharedContext) -> Context<'a> { let mut acir_context = AcirContext::default(); @@ -422,6 +390,25 @@ impl<'a> Context<'a> { let dfg = &main_func.dfg; let entry_block = &dfg[main_func.entry_block()]; let input_witness = self.convert_ssa_block_params(entry_block.parameters(), dfg)?; + let num_return_witnesses = + self.get_num_return_witnesses(entry_block.unwrap_terminator(), dfg); + + // Create a witness for each return witness we have to guarantee that the return witnesses match the standard + // layout for serializing those types as if they were being passed as inputs. + // + // This is required for recursion as otherwise in situations where we cannot make use of the program's ABI + // (e.g. for `std::verify_proof` or the solidity verifier), we need extra knowledge about the program we're + // working with rather than following the standard ABI encoding rules. + // + // We allocate these witnesses now before performing ACIR gen for the rest of the program as the location of + // the function's return values can then be determined through knowledge of its ABI alone. + let return_witness_vars = + vecmap(0..num_return_witnesses, |_| self.acir_context.add_variable()); + + let return_witnesses = vecmap(&return_witness_vars, |return_var| { + let expr = self.acir_context.var_to_expression(*return_var).unwrap(); + expr.to_witness().expect("return vars should be witnesses") + }); self.data_bus = dfg.data_bus.to_owned(); let mut warnings = Vec::new(); @@ -429,8 +416,19 @@ impl<'a> Context<'a> { warnings.extend(self.convert_ssa_instruction(*instruction_id, dfg, ssa, brillig)?); } - warnings.extend(self.convert_ssa_return(entry_block.unwrap_terminator(), dfg)?); - Ok(self.acir_context.finish(input_witness, warnings)) + let (return_vars, return_warnings) = + self.convert_ssa_return(entry_block.unwrap_terminator(), dfg)?; + + // TODO: This is a naive method of assigning the return values to their witnesses as + // we're likely to get a number of constraints which are asserting one witness to be equal to another. + // + // We should search through the program and relabel these witnesses so we can remove this constraint. + for (witness_var, return_var) in return_witness_vars.iter().zip(return_vars) { + self.acir_context.assert_eq_var(*witness_var, return_var, None)?; + } + + warnings.extend(return_warnings); + Ok(self.acir_context.finish(input_witness, return_witnesses, warnings)) } fn convert_brillig_main( @@ -468,17 +466,13 @@ impl<'a> Context<'a> { )?; self.shared_context.insert_generated_brillig(main_func.id(), arguments, 0, code); - let output_vars: Vec<_> = output_values + let return_witnesses: Vec = output_values .iter() .flat_map(|value| value.clone().flatten()) - .map(|value| value.0) - .collect(); + .map(|(value, _)| self.acir_context.var_to_witness(value)) + .collect::>()?; - for acir_var in output_vars { - self.acir_context.return_var(acir_var)?; - } - - let generated_acir = self.acir_context.finish(witness_inputs, Vec::new()); + let generated_acir = self.acir_context.finish(witness_inputs, return_witnesses, Vec::new()); assert_eq!( generated_acir.opcodes().len(), @@ -1724,12 +1718,39 @@ impl<'a> Context<'a> { self.define_result(dfg, instruction, AcirValue::Var(result, typ)); } + /// Converts an SSA terminator's return values into their ACIR representations + fn get_num_return_witnesses( + &mut self, + terminator: &TerminatorInstruction, + dfg: &DataFlowGraph, + ) -> usize { + let return_values = match terminator { + TerminatorInstruction::Return { return_values, .. } => return_values, + // TODO(https://github.com/noir-lang/noir/issues/4616): Enable recursion on foldable/non-inlined ACIR functions + _ => unreachable!("ICE: Program must have a singular return"), + }; + + return_values.iter().fold(0, |acc, value_id| { + let is_databus = self + .data_bus + .return_data + .map_or(false, |return_databus| dfg[*value_id] == dfg[return_databus]); + + if is_databus { + // We do not return value for the data bus. + acc + } else { + acc + dfg.type_of_value(*value_id).flattened_size() + } + }) + } + /// Converts an SSA terminator's return values into their ACIR representations fn convert_ssa_return( &mut self, terminator: &TerminatorInstruction, dfg: &DataFlowGraph, - ) -> Result, RuntimeError> { + ) -> Result<(Vec, Vec), RuntimeError> { let (return_values, call_stack) = match terminator { TerminatorInstruction::Return { return_values, call_stack } => { (return_values, call_stack.clone()) @@ -1739,6 +1760,7 @@ impl<'a> Context<'a> { }; let mut has_constant_return = false; + let mut return_vars: Vec = Vec::new(); for value_id in return_values { let is_databus = self .data_bus @@ -1759,7 +1781,7 @@ impl<'a> Context<'a> { dfg, )?; } else { - self.acir_context.return_var(acir_var)?; + return_vars.push(acir_var); } } } @@ -1770,7 +1792,7 @@ impl<'a> Context<'a> { Vec::new() }; - Ok(warnings) + Ok((return_vars, warnings)) } /// Gets the cached `AcirVar` that was converted from the corresponding `ValueId`. If it does @@ -3079,8 +3101,8 @@ mod test { check_call_opcode( &func_with_nested_call_opcodes[1], 2, - vec![Witness(2), Witness(1)], - vec![Witness(3)], + vec![Witness(3), Witness(1)], + vec![Witness(4)], ); } @@ -3100,13 +3122,13 @@ mod test { for (expected_input, input) in expected_inputs.iter().zip(inputs) { assert_eq!( expected_input, input, - "Expected witness {expected_input:?} but got {input:?}" + "Expected input witness {expected_input:?} but got {input:?}" ); } for (expected_output, output) in expected_outputs.iter().zip(outputs) { assert_eq!( expected_output, output, - "Expected witness {expected_output:?} but got {output:?}" + "Expected output witness {expected_output:?} but got {output:?}" ); } } From c93c7380c705fcec5c77bfc436c2f5ea085edd77 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Fri, 31 May 2024 16:44:54 +0100 Subject: [PATCH 61/61] feat!: separate proving from `noir_js` (#5072) # Description ## Problem\* Resolves ## Summary\* This removes proving/verification functionality from `noir_js` in favour of interacting with the backend. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [x] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Maxim Vezenov --- .../circuits/assert_lt/Nargo.toml | 5 ++ .../circuits/assert_lt/src/main.nr | 10 +++ .../circuits/fold_fibonacci/Nargo.toml | 7 +++ .../circuits/fold_fibonacci/src/main.nr | 12 ++++ compiler/integration-tests/package.json | 2 +- .../scripts/codegen-verifiers.sh | 1 + .../scripts/compile-programs.sh | 12 ++++ compiler/integration-tests/scripts/setup.sh | 8 +++ .../test/browser/compile_prove_verify.test.ts | 11 ++-- .../onchain_recursive_verification.test.ts | 10 +-- .../test/node/prove_and_verify.test.ts | 34 +++-------- .../test/node/smart_contract_verifier.test.ts | 9 +-- docs/docs/how_to/how-to-oracles.md | 2 +- docs/docs/how_to/how-to-recursion.md | 9 +-- docs/docs/tutorials/noirjs_app.md | 5 +- tooling/noir_js/src/index.ts | 4 +- tooling/noir_js/src/program.ts | 61 +------------------ tooling/noir_js/test/node/execute.test.ts | 2 +- 18 files changed, 95 insertions(+), 109 deletions(-) create mode 100644 compiler/integration-tests/circuits/assert_lt/Nargo.toml create mode 100644 compiler/integration-tests/circuits/assert_lt/src/main.nr create mode 100644 compiler/integration-tests/circuits/fold_fibonacci/Nargo.toml create mode 100644 compiler/integration-tests/circuits/fold_fibonacci/src/main.nr mode change 100644 => 100755 compiler/integration-tests/scripts/codegen-verifiers.sh create mode 100755 compiler/integration-tests/scripts/compile-programs.sh create mode 100755 compiler/integration-tests/scripts/setup.sh rename tooling/noir_js/test/node/e2e.test.ts => compiler/integration-tests/test/node/prove_and_verify.test.ts (82%) diff --git a/compiler/integration-tests/circuits/assert_lt/Nargo.toml b/compiler/integration-tests/circuits/assert_lt/Nargo.toml new file mode 100644 index 00000000000..f32ec18cae7 --- /dev/null +++ b/compiler/integration-tests/circuits/assert_lt/Nargo.toml @@ -0,0 +1,5 @@ +[package] +name = "assert_lt" +type = "bin" +authors = [""] +[dependencies] diff --git a/compiler/integration-tests/circuits/assert_lt/src/main.nr b/compiler/integration-tests/circuits/assert_lt/src/main.nr new file mode 100644 index 00000000000..b8e255ca492 --- /dev/null +++ b/compiler/integration-tests/circuits/assert_lt/src/main.nr @@ -0,0 +1,10 @@ +use dep::std; + +fn main(x: u64, y: pub u64) -> pub u64 { + // We include a println statement to show that noirJS will ignore this and continue execution + std::println("foo"); + + + assert(x < y); + x + y +} diff --git a/compiler/integration-tests/circuits/fold_fibonacci/Nargo.toml b/compiler/integration-tests/circuits/fold_fibonacci/Nargo.toml new file mode 100644 index 00000000000..6d8214689b0 --- /dev/null +++ b/compiler/integration-tests/circuits/fold_fibonacci/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "fold_fibonacci" +type = "bin" +authors = [""] +compiler_version = ">=0.28.0" + +[dependencies] \ No newline at end of file diff --git a/compiler/integration-tests/circuits/fold_fibonacci/src/main.nr b/compiler/integration-tests/circuits/fold_fibonacci/src/main.nr new file mode 100644 index 00000000000..e150a586086 --- /dev/null +++ b/compiler/integration-tests/circuits/fold_fibonacci/src/main.nr @@ -0,0 +1,12 @@ +fn main(x: u32) { + assert(fibonacci(x) == 55); +} + +#[fold] +fn fibonacci(x: u32) -> u32 { + if x <= 1 { + x + } else { + fibonacci(x - 1) + fibonacci(x - 2) + } +} diff --git a/compiler/integration-tests/package.json b/compiler/integration-tests/package.json index 431fe408a8b..b789f1f05ce 100644 --- a/compiler/integration-tests/package.json +++ b/compiler/integration-tests/package.json @@ -6,7 +6,7 @@ "scripts": { "build": "echo Integration Test build step", "test": "yarn test:browser && yarn test:node", - "test:node": "bash ./scripts/codegen-verifiers.sh && hardhat test test/node/**/*", + "test:node": "bash ./scripts/setup.sh && hardhat test test/node/**/*", "test:browser": "web-test-runner", "test:integration:browser": "web-test-runner test/browser/**/*.test.ts", "test:integration:browser:watch": "web-test-runner test/browser/**/*.test.ts --watch", diff --git a/compiler/integration-tests/scripts/codegen-verifiers.sh b/compiler/integration-tests/scripts/codegen-verifiers.sh old mode 100644 new mode 100755 index abc26c4c465..bec59eb6889 --- a/compiler/integration-tests/scripts/codegen-verifiers.sh +++ b/compiler/integration-tests/scripts/codegen-verifiers.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -e NARGO_BACKEND_PATH=${NARGO_BACKEND_PATH:-bb} diff --git a/compiler/integration-tests/scripts/compile-programs.sh b/compiler/integration-tests/scripts/compile-programs.sh new file mode 100755 index 00000000000..a7071acc401 --- /dev/null +++ b/compiler/integration-tests/scripts/compile-programs.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -e + +self_path=$(dirname "$(readlink -f "$0")") + +package_root=$self_path/../ + +assert_lt_dir=$package_root/circuits/assert_lt/ +nargo --program-dir $assert_lt_dir compile + +fold_fibonacci_dir=$package_root/circuits/fold_fibonacci/ +nargo --program-dir $fold_fibonacci_dir compile diff --git a/compiler/integration-tests/scripts/setup.sh b/compiler/integration-tests/scripts/setup.sh new file mode 100755 index 00000000000..37db38474c0 --- /dev/null +++ b/compiler/integration-tests/scripts/setup.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -e + +self_path=$(dirname "$(readlink -f "$0")") + + +$self_path/compile-programs.sh +$self_path/codegen-verifiers.sh \ No newline at end of file diff --git a/compiler/integration-tests/test/browser/compile_prove_verify.test.ts b/compiler/integration-tests/test/browser/compile_prove_verify.test.ts index dba51895bb8..f18ceb85276 100644 --- a/compiler/integration-tests/test/browser/compile_prove_verify.test.ts +++ b/compiler/integration-tests/test/browser/compile_prove_verify.test.ts @@ -51,19 +51,20 @@ test_cases.forEach((testInfo) => { throw e; } - const backend = new BarretenbergBackend(noir_program); - const program = new Noir(noir_program, backend); - const prover_toml = await new Response(await getFile(`${base_relative_path}/${test_case}/Prover.toml`)).text(); const inputs: InputMap = TOML.parse(prover_toml) as InputMap; // JS Proving - const proofWithPublicInputs = await program.generateProof(inputs); + const program = new Noir(noir_program); + const { witness } = await program.execute(inputs); + + const backend = new BarretenbergBackend(noir_program); + const proof = await backend.generateProof(witness); // JS verification - const verified = await program.verifyProof(proofWithPublicInputs); + const verified = await backend.verifyProof(proof); expect(verified, 'Proof fails verification in JS').to.be.true; }); diff --git a/compiler/integration-tests/test/node/onchain_recursive_verification.test.ts b/compiler/integration-tests/test/node/onchain_recursive_verification.test.ts index ca7f19309d6..f4647c478f1 100644 --- a/compiler/integration-tests/test/node/onchain_recursive_verification.test.ts +++ b/compiler/integration-tests/test/node/onchain_recursive_verification.test.ts @@ -56,8 +56,7 @@ it.skip(`smart contract can verify a recursive proof`, async () => { // Final proof - const recursion_backend = new BarretenbergBackend(recursionProgram); - const recursion = new Noir(recursionProgram, recursion_backend); + const recursion = new Noir(recursionProgram); const recursion_inputs: InputMap = { verification_key: vkAsFields, @@ -66,8 +65,11 @@ it.skip(`smart contract can verify a recursive proof`, async () => { key_hash: vkHash, }; - const recursion_proof = await recursion.generateProof(recursion_inputs); - expect(await recursion.verifyProof(recursion_proof)).to.be.true; + const { witness: recursionWitness } = await recursion.execute(recursion_inputs); + + const recursion_backend = new BarretenbergBackend(recursionProgram); + const recursion_proof = await recursion_backend.generateProof(recursionWitness); + expect(await recursion_backend.verifyProof(recursion_proof)).to.be.true; // Smart contract verification diff --git a/tooling/noir_js/test/node/e2e.test.ts b/compiler/integration-tests/test/node/prove_and_verify.test.ts similarity index 82% rename from tooling/noir_js/test/node/e2e.test.ts rename to compiler/integration-tests/test/node/prove_and_verify.test.ts index dbb9abcc964..1cfe36f31e9 100644 --- a/tooling/noir_js/test/node/e2e.test.ts +++ b/compiler/integration-tests/test/node/prove_and_verify.test.ts @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import assert_lt_json from '../noir_compiled_examples/assert_lt/target/assert_lt.json' assert { type: 'json' }; -import fold_fibonacci_json from '../noir_compiled_examples/fold_fibonacci/target/fold_fibonacci.json' assert { type: 'json' }; +import assert_lt_json from '../../circuits/assert_lt/target/assert_lt.json' assert { type: 'json' }; +import fold_fibonacci_json from '../../circuits/fold_fibonacci/target/fold_fibonacci.json' assert { type: 'json' }; import { Noir } from '@noir-lang/noir_js'; import { BarretenbergBackend as Backend, BarretenbergVerifier as Verifier } from '@noir-lang/backend_barretenberg'; import { CompiledCircuit } from '@noir-lang/types'; @@ -30,25 +30,6 @@ it('end-to-end proof creation and verification (outer)', async () => { expect(isValid).to.be.true; }); -it('end-to-end proof creation and verification (outer) -- Program API', async () => { - // Noir.Js part - const inputs = { - x: '2', - y: '3', - }; - - // Initialize backend - const backend = new Backend(assert_lt_program); - // Initialize program - const program = new Noir(assert_lt_program, backend); - // Generate proof - const proof = await program.generateProof(inputs); - - // Proof verification - const isValid = await program.verifyProof(proof); - expect(isValid).to.be.true; -}); - it('end-to-end proof creation and verification (outer) -- Verifier API', async () => { // Noir.Js part const inputs = { @@ -56,12 +37,13 @@ it('end-to-end proof creation and verification (outer) -- Verifier API', async ( y: '3', }; - // Initialize backend - const backend = new Backend(assert_lt_program); - // Initialize program - const program = new Noir(assert_lt_program, backend); + // Execute program + const program = new Noir(assert_lt_program); + const { witness } = await program.execute(inputs); + // Generate proof - const proof = await program.generateProof(inputs); + const backend = new Backend(assert_lt_program); + const proof = await backend.generateProof(witness); const verificationKey = await backend.getVerificationKey(); diff --git a/compiler/integration-tests/test/node/smart_contract_verifier.test.ts b/compiler/integration-tests/test/node/smart_contract_verifier.test.ts index 79a0520da32..e109cbcab6a 100644 --- a/compiler/integration-tests/test/node/smart_contract_verifier.test.ts +++ b/compiler/integration-tests/test/node/smart_contract_verifier.test.ts @@ -38,19 +38,20 @@ test_cases.forEach((testInfo) => { const noir_program = compileResult.program; - const backend = new BarretenbergBackend(noir_program); - const program = new Noir(noir_program, backend); + const program = new Noir(noir_program); // JS Proving const prover_toml = readFileSync(resolve(`${base_relative_path}/${test_case}/Prover.toml`)).toString(); const inputs = toml.parse(prover_toml); + const { witness } = await program.execute(inputs); - const proofData = await program.generateProof(inputs); + const backend = new BarretenbergBackend(noir_program); + const proofData = await backend.generateProof(witness); // JS verification - const verified = await program.verifyProof(proofData); + const verified = await backend.verifyProof(proofData); expect(verified, 'Proof fails verification in JS').to.be.true; // Smart contract verification diff --git a/docs/docs/how_to/how-to-oracles.md b/docs/docs/how_to/how-to-oracles.md index 5f427f1e23f..2811968c634 100644 --- a/docs/docs/how_to/how-to-oracles.md +++ b/docs/docs/how_to/how-to-oracles.md @@ -194,7 +194,7 @@ For example, if your Noir program expects the host machine to provide CPU pseudo ```js const foreignCallHandler = (name, inputs) => crypto.randomBytes(16) // etc -await noir.generateProof(inputs, foreignCallHandler) +await noir.execute(inputs, foreignCallHandler) ``` As one can see, in NoirJS, the [`foreignCallHandler`](../reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md) function simply means "a callback function that returns a value of type [`ForeignCallOutput`](../reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md). It doesn't have to be an RPC call like in the case for Nargo. diff --git a/docs/docs/how_to/how-to-recursion.md b/docs/docs/how_to/how-to-recursion.md index 4c45bb87ae2..aac84e29fac 100644 --- a/docs/docs/how_to/how-to-recursion.md +++ b/docs/docs/how_to/how-to-recursion.md @@ -70,7 +70,7 @@ You can use the [`os.cpus()`](https://nodejs.org/api/os.html#oscpus) object in ` After instantiating the backend, you should also instantiate `noir_js`. We will use it to execute the circuit and get the witness. ```js -const noir = new Noir(circuit, backend) +const noir = new Noir(circuit) const { witness } = noir.execute(input) ``` @@ -155,8 +155,8 @@ const backends = { recursive: new BarretenbergBackend(circuits.recursive) } const noir_programs = { - main: new Noir(circuits.main, backends.main), - recursive: new Noir(circuits.recursive, backends.recursive) + main: new Noir(circuits.main), + recursive: new Noir(circuits.recursive) } ``` @@ -173,7 +173,8 @@ const { proofAsFields, vkAsFields, vkHash } = await backends.main.generateRecurs proof, numPublicInputs, ); -const recursiveProof = await noir_programs.recursive.generateProof(recursiveInputs) +const { witness: recursiveWitness } = await noir_programs.recursive.execute(recursiveInputs) +const recursiveProof = await backends.recursive.generateProof(recursiveWitness); ``` ::: diff --git a/docs/docs/tutorials/noirjs_app.md b/docs/docs/tutorials/noirjs_app.md index 3dd9fe7d2b0..cbb1938a5c6 100644 --- a/docs/docs/tutorials/noirjs_app.md +++ b/docs/docs/tutorials/noirjs_app.md @@ -263,7 +263,7 @@ And instantiate them inside our try-catch block: ```ts // try { const backend = new BarretenbergBackend(circuit); -const noir = new Noir(circuit, backend); +const noir = new Noir(circuit); // } ``` @@ -288,7 +288,8 @@ Now we're ready to prove stuff! Let's feed some inputs to our circuit and calcul await setup(); // let's squeeze our wasm inits here display('logs', 'Generating proof... ⌛'); -const proof = await noir.generateProof(input); +const { witness } = await noir.execute(input); +const proof = await backend.generateProof(witness); display('logs', 'Generating proof... ✅'); display('results', proof.proof); ``` diff --git a/tooling/noir_js/src/index.ts b/tooling/noir_js/src/index.ts index e7f356a582e..1feca8fa275 100644 --- a/tooling/noir_js/src/index.ts +++ b/tooling/noir_js/src/index.ts @@ -1,6 +1,6 @@ import * as acvm from '@noir-lang/acvm_js'; import * as abi from '@noir-lang/noirc_abi'; -import { CompiledCircuit, ProofData } from '@noir-lang/types'; +import { CompiledCircuit } from '@noir-lang/types'; export { ecdsa_secp256r1_verify, @@ -22,4 +22,4 @@ export { ErrorWithPayload } from './witness_generation.js'; export { acvm, abi }; // type exports for typedoc -export { CompiledCircuit, ProofData }; +export { CompiledCircuit }; diff --git a/tooling/noir_js/src/program.ts b/tooling/noir_js/src/program.ts index 86aa0f60ddf..accd89dc385 100644 --- a/tooling/noir_js/src/program.ts +++ b/tooling/noir_js/src/program.ts @@ -1,14 +1,10 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { Backend, CompiledCircuit, ProofData } from '@noir-lang/types'; +import { CompiledCircuit } from '@noir-lang/types'; import { generateWitness } from './witness_generation.js'; import initAbi, { abiDecode, InputMap, InputValue } from '@noir-lang/noirc_abi'; import initACVM, { compressWitnessStack, ForeignCallHandler } from '@noir-lang/acvm_js'; export class Noir { - constructor( - private circuit: CompiledCircuit, - private backend?: Backend, - ) {} + constructor(private circuit: CompiledCircuit) {} /** @ignore */ async init(): Promise { @@ -20,27 +16,6 @@ export class Noir { } } - /** - * - * @description - * Destroys the underlying backend instance. - * - * @example - * ```typescript - * await noir.destroy(); - * ``` - * - */ - async destroy(): Promise { - await this.backend?.destroy(); - } - - private getBackend(): Backend { - if (this.backend === undefined) throw new Error('Operation requires a backend but none was provided'); - return this.backend; - } - - // Initial inputs to your program /** * @description * Allows to execute a circuit to get its witness and return value. @@ -60,36 +35,4 @@ export class Noir { const { return_value: returnValue } = abiDecode(this.circuit.abi, main_witness); return { witness: compressWitnessStack(witness_stack), returnValue }; } - - /** - * - * @description - * Generates a witness and a proof given an object as input. - * - * @example - * ```typescript - * async generateProof(input) - * ``` - * - */ - async generateProof(inputs: InputMap, foreignCallHandler?: ForeignCallHandler): Promise { - const { witness } = await this.execute(inputs, foreignCallHandler); - return this.getBackend().generateProof(witness); - } - - /** - * - * @description - * Instantiates the verification key and verifies a proof. - * - * - * @example - * ```typescript - * async verifyProof(proof) - * ``` - * - */ - async verifyProof(proofData: ProofData): Promise { - return this.getBackend().verifyProof(proofData); - } } diff --git a/tooling/noir_js/test/node/execute.test.ts b/tooling/noir_js/test/node/execute.test.ts index d047e35035f..7c93a911042 100644 --- a/tooling/noir_js/test/node/execute.test.ts +++ b/tooling/noir_js/test/node/execute.test.ts @@ -11,7 +11,7 @@ const assert_lt_program = assert_lt_json as CompiledCircuit; const assert_msg_runtime = assert_msg_json as CompiledCircuit; const fold_fibonacci_program = fold_fibonacci_json as CompiledCircuit; -it('returns the return value of the circuit', async () => { +it('executes a single-ACIR program correctly', async () => { const inputs = { x: '2', y: '3',