From 3002245026062af4a821652ce695c14daa58ad1c Mon Sep 17 00:00:00 2001 From: "Mariano A. Nicolini" Date: Thu, 31 Aug 2023 15:19:04 -0300 Subject: [PATCH] fix: remove enforce selector constraint (#205) * Start Cairo AIR refactor * Refactor Cairo execution trace module * Fix tests so that they compile * Continue fixes * Fix cairo output and rc program test * Rearrange testing folders * Fix some tests * Fix all tests * Fixed transition degrees to the correct ones * Polish tests and fix benches * Fix makefile targets * Add documentation for add_pub_memory_in_public_input_section * Uncomment test optimizations * Fix giza bench * Fix giza bench again * Save work in progress * Fix benchmarks * Fix clippy lints * Add serialization tests * Remove Cairo 1 * Fmt * Remove no longer valid tests * Fix clippy * Update Cargo.toml --------- Co-authored-by: MauroFab Co-authored-by: Mauro Toscano <12560266+MauroToscano@users.noreply.github.com> --- Makefile | 14 +- README.md | 55 +- cairo_compile.Dockerfile | 2 +- cairo_prover/Cargo.toml | 8 +- cairo_prover/benches/criterion_giza.rs | 9 +- cairo_prover/benches/criterion_prover.rs | 15 +- cairo_prover/benches/criterion_prover_70k.rs | 17 +- .../cairo1/fibonacci_cairo1.cairo | 18 - .../cairo1/fibonacci_cairo1.casm | 378 ---- cairo_prover/src/air.rs | 434 ++-- cairo_prover/src/execution_trace.rs | 746 +------ cairo_prover/src/main.rs | 18 +- cairo_prover/src/runner/program.json | 200 -- cairo_prover/src/runner/run.rs | 313 +-- cairo_prover/src/tests/integration_tests.rs | 173 +- cairo_prover/src/tests/utils.rs | 22 +- cairo_prover/tests/wasm.rs | 1942 +++++++++++++++++ src/cairo/mod.rs | 11 + src/cairo/tests/data/mul_mem.out | Bin 0 -> 320 bytes src/cairo/tests/data/mul_trace.out | Bin 0 -> 72 bytes src/cairo/tests/mod.rs | 2 + src/cairo/tests/utils.rs | 38 + src/starks/tests/integration_tests.rs | 129 ++ src/starks/tests/mod.rs | 1 + stark_prover/src/proof/stark.rs | 17 +- 25 files changed, 2746 insertions(+), 1816 deletions(-) delete mode 100644 cairo_prover/cairo_programs/cairo1/fibonacci_cairo1.cairo delete mode 100644 cairo_prover/cairo_programs/cairo1/fibonacci_cairo1.casm delete mode 100644 cairo_prover/src/runner/program.json create mode 100644 cairo_prover/tests/wasm.rs create mode 100644 src/cairo/mod.rs create mode 100644 src/cairo/tests/data/mul_mem.out create mode 100644 src/cairo/tests/data/mul_trace.out create mode 100644 src/cairo/tests/mod.rs create mode 100644 src/cairo/tests/utils.rs create mode 100644 src/starks/tests/integration_tests.rs create mode 100644 src/starks/tests/mod.rs diff --git a/Makefile b/Makefile index d940a4f6..fea84c41 100644 --- a/Makefile +++ b/Makefile @@ -12,8 +12,8 @@ COMPILED_CAIRO0_PROGRAMS:=$(patsubst $(CAIRO0_PROGRAMS_DIR)/%.cairo, $(CAIRO0_PR # When using the docker version, be sure to build the image using `make docker_build_cairo_compiler`. $(CAIRO0_PROGRAMS_DIR)/%.json: $(CAIRO0_PROGRAMS_DIR)/%.cairo @echo "Compiling Cairo program..." - @cairo-compile --cairo_path="$(CAIRO0_PROGRAMS_DIR)" $< --output $@ 2> /dev/null || \ - docker run --rm -v $(ROOT_DIR)/$(CAIRO0_PROGRAMS_DIR):/pwd/$(CAIRO0_PROGRAMS_DIR) cairo cairo-compile /pwd/$< > $@ + @cairo-compile --cairo_path="$(CAIRO0_PROGRAMS_DIR)" $< --output $@ 2> /dev/null --proof_mode || \ + docker run --rm -v $(ROOT_DIR)/$(CAIRO0_PROGRAMS_DIR):/pwd/$(CAIRO0_PROGRAMS_DIR) cairo --proof_mode /pwd/$< > $@ build: cargo build --release @@ -66,35 +66,35 @@ docker_build_cairo_compiler: docker build -f cairo_compile.Dockerfile -t cairo . docker_compile_cairo: - docker run -v $(ROOT_DIR):/pwd cairo cairo-compile /pwd/$(PROGRAM) > $(OUTPUT) + docker run -v $(ROOT_DIR):/pwd cairo --proof_mode /pwd/$(PROGRAM) > $(OUTPUT) target/release/cairo-platinum-prover: cargo build --bin cairo-platinum-prover --release --features instruments docker_compile_and_run_all: target/release/cairo-platinum-prover @echo "Compiling program with docker" - @docker run -v $(ROOT_DIR):/pwd cairo cairo-compile /pwd/$(PROGRAM) > $(PROGRAM).json + @docker run -v $(ROOT_DIR):/pwd cairo --proof_mode /pwd/$(PROGRAM) > $(PROGRAM).json @echo "Compiling done \n" @cargo run --bin cairo-platinum-prover --features instruments --quiet --release prove_and_verify $(PROGRAM).json @rm $(PROGRAM).json docker_compile_and_prove: target/release/cairo-platinum-prover @echo "Compiling program with docker" - @docker run -v $(ROOT_DIR):/pwd cairo cairo-compile /pwd/$(PROGRAM) > $(PROGRAM).json + @docker run -v $(ROOT_DIR):/pwd cairo --proof_mode /pwd/$(PROGRAM) > $(PROGRAM).json @echo "Compiling done \n" @cargo run --bin cairo-platinum-prover --features instruments --quiet --release prove $(PROGRAM).json $(PROOF_PATH) @rm $(PROGRAM).json compile_and_run_all: target/release/cairo-platinum-prover @echo "Compiling program with cairo-compile" - @cairo-compile $(PROGRAM) > $(PROGRAM).json + @cairo-compile --proof_mode $(PROGRAM) > $(PROGRAM).json @echo "Compiling done \n" @cargo run --bin cairo-platinum-prover --features instruments --quiet --release prove_and_verify $(PROGRAM).json @rm $(PROGRAM).json compile_and_prove: target/release/cairo-platinum-prover @echo "Compiling program with cairo-compile" - @cairo-compile $(PROGRAM) > $(PROGRAM).json + @cairo-compile --proof_mode $(PROGRAM) > $(PROGRAM).json @echo "Compiling done \n" @cargo run --bin cairo-platinum-prover --features instruments --quiet --release prove $(PROGRAM).json $(PROOF_PATH) @rm $(PROGRAM).json diff --git a/README.md b/README.md index 3eb3710e..490aed02 100644 --- a/README.md +++ b/README.md @@ -30,14 +30,22 @@ CLI currently runs with 100 bits of conjecturable security ## Table of Contents -- [Main Building Blocks](#main-building-blocks) -- [Requirements](#requirements) -- [Trying it](#how-to-try-it) -- [Prove and verify](#-prove-and-verify) -- [Fuzzers](#running-fuzzers) -- [Using cairo-compile for Cairo 0 programs](#using-cairo-compile-for-cairo-0-programs) -- [References](#-references) -- [Related projects](#-related-projects) +- [🌟 Lambdaworks Stark Platinum Prover 🌟](#-lambdaworks-stark-platinum-prover-) + - [An open-source STARK prover, drop-in replacement for Winterfell.](#an-open-source-stark-prover-drop-in-replacement-for-winterfell) + - [⚠️ Disclaimer](#️-disclaimer) + - [Documentation](#documentation) + - [Table of Contents](#table-of-contents) + - [Main building blocks](#main-building-blocks) + - [Requirements](#requirements) + - [How to try it](#how-to-try-it) + - [🚀 Prove and verify](#-prove-and-verify) + - [Using Docker compiler for Cairo 0 programs](#using-docker-compiler-for-cairo-0-programs) + - [Using cairo-compile for Cairo 0 programs](#using-cairo-compile-for-cairo-0-programs) + - [Using WASM verifier](#using-wasm-verifier) + - [Running tests](#running-tests) + - [Running fuzzers](#running-fuzzers) + - [📚 References](#-references) + - [🌞 Related Projects](#-related-projects) ## Main building blocks @@ -94,11 +102,9 @@ To be added: ## How to try it -For the moment, only programs in Cairo 0 with no arguments and contracts in Cairo 1 with no arguments are supported. - ### 🚀 Prove and verify -To prove Cairo programs you can use: +To prove Cairo 0 programs without arguments you can use: ```bash make prove PROGRAM_PATH= PROOF_PATH= @@ -123,7 +129,6 @@ To prove and verify with a single command you can use: make run_all PROGRAM_PATH= ``` - ### Using Docker compiler for Cairo 0 programs Build the compiler image with: @@ -160,32 +165,6 @@ Or make compile_and_prove PROGRAM=program_name.cairo PROOF_PATH=proof_path ``` -### Compiling Cairo 1 contracts - -Clone `cairo` repository: - -``` bash -git clone https://github.com/starkware-libs/cairo -``` - -Checkout version 1.1.0 (corresponding to that tag of the repository). In the `cairo` folder, run: - -``` bash -git checkout v1.1.0 -``` - -- To create json file from Cairo contract: - - ``` bash - cargo run --bin starknet-compile -- /path/to/input.cairo /path/to/output.json - ``` - -- To create casm file from json file: - - ``` bash - cargo run --bin starknet-sierra-compile -- /path/to/input.json /path/to/output.casm - ``` - ### Using WASM verifier To use the verifier in WASM, generate a npm package using `wasm-pack` diff --git a/cairo_compile.Dockerfile b/cairo_compile.Dockerfile index d31469d5..369f6db8 100644 --- a/cairo_compile.Dockerfile +++ b/cairo_compile.Dockerfile @@ -8,4 +8,4 @@ COPY requirements.txt / RUN pip install -r /requirements.txt -CMD ["cairo-compile"] +ENTRYPOINT ["cairo-compile"] diff --git a/cairo_prover/Cargo.toml b/cairo_prover/Cargo.toml index f37d2c5d..dec149d2 100644 --- a/cairo_prover/Cargo.toml +++ b/cairo_prover/Cargo.toml @@ -6,9 +6,9 @@ version.workspace = true edition.workspace = true license.workspace = true -# [[bin]] -# name = "cairo-platinum" -# path = "src/main.rs" +[[bin]] +name = "cairo-platinum-prover" +path = "src/main.rs" [lib] crate-type = ["cdylib", "rlib"] @@ -21,12 +21,10 @@ stark-platinum-prover = { path = "../stark_prover", features = ["wasm"] } thiserror = "1.0.38" log = "0.4.17" bincode = { version = "2.0.0-rc.2", tag = "v2.0.0-rc.2", git = "https://github.com/bincode-org/bincode.git" } -# cairo-vm = { version = "0.6.0", features = ["cairo-1-hints"] } cairo-vm = { git = "https://github.com/lambdaclass/cairo-vm", rev = "e763cef", default-features = false, features = [ "cairo-1-hints", ]} sha3 = "0.10.6" -cairo-lang-starknet = { version = "2.1.0-rc2", default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" num-integer = "0.1.45" diff --git a/cairo_prover/benches/criterion_giza.rs b/cairo_prover/benches/criterion_giza.rs index f2a9aaaa..e12eb732 100644 --- a/cairo_prover/benches/criterion_giza.rs +++ b/cairo_prover/benches/criterion_giza.rs @@ -1,7 +1,6 @@ #[cfg(feature = "giza")] use cairo_platinum_prover::{ - air::generate_cairo_proof, - runner::run::{generate_prover_args, CairoVersion}, + air::generate_cairo_proof, cairo_layout::CairoLayout, runner::run::generate_prover_args, }; #[cfg(feature = "giza")] use criterion::{black_box, measurement::WallTime, BenchmarkGroup}; @@ -41,6 +40,7 @@ fn cairo_benches(c: &mut Criterion) { &proof_options, "lambdaworks/fibonacci/1000", &cairo0_program_path("fibonacci_1000.json"), + CairoLayout::Plain, ); run_giza_bench( &mut group, @@ -56,6 +56,7 @@ fn cairo_benches(c: &mut Criterion) { &proof_options, "lambdaworks/fibonacci/10000", &cairo0_program_path("fibonacci_10000.json"), + CairoLayout::Plain, ); run_giza_bench( &mut group, @@ -81,10 +82,10 @@ fn run_lambdaworks_bench( proof_options: &options::ProofOptions, benchname: &str, program_path: &str, + layout: CairoLayout, ) { let program_content = std::fs::read(program_path).unwrap(); - let (main_trace, pub_inputs) = - generate_prover_args(&program_content, &CairoVersion::V0, &None).unwrap(); + let (main_trace, pub_inputs) = generate_prover_args(&program_content, &None, layout).unwrap(); group.bench_function(benchname, |bench| { bench.iter(|| { diff --git a/cairo_prover/benches/criterion_prover.rs b/cairo_prover/benches/criterion_prover.rs index cb8b128d..9b025da6 100644 --- a/cairo_prover/benches/criterion_prover.rs +++ b/cairo_prover/benches/criterion_prover.rs @@ -1,6 +1,5 @@ use cairo_platinum_prover::{ - air::generate_cairo_proof, - runner::run::{generate_prover_args, CairoVersion}, + air::generate_cairo_proof, cairo_layout::CairoLayout, runner::run::generate_prover_args, }; use criterion::{ black_box, criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion, @@ -29,11 +28,13 @@ fn cairo_benches(c: &mut Criterion) { &mut group, "fibonacci/500", &cairo0_program_path("fibonacci_500.json"), + CairoLayout::Plain, ); run_cairo_bench( &mut group, "fibonacci/1000", &cairo0_program_path("fibonacci_1000.json"), + CairoLayout::Plain, ); } @@ -44,11 +45,15 @@ fn cairo0_program_path(program_name: &str) -> String { program_base_path + program_name } -fn run_cairo_bench(group: &mut BenchmarkGroup<'_, WallTime>, benchname: &str, program_path: &str) { +fn run_cairo_bench( + group: &mut BenchmarkGroup<'_, WallTime>, + benchname: &str, + program_path: &str, + layout: CairoLayout, +) { let program_content = std::fs::read(program_path).unwrap(); let proof_options = ProofOptions::new_secure(SecurityLevel::Provable80Bits, 3); - let (main_trace, pub_inputs) = - generate_prover_args(&program_content, &CairoVersion::V0, &None).unwrap(); + let (main_trace, pub_inputs) = generate_prover_args(&program_content, &None, layout).unwrap(); println!("Generated main trace with {} rows", main_trace.n_rows()); group.bench_function(benchname, |bench| { diff --git a/cairo_prover/benches/criterion_prover_70k.rs b/cairo_prover/benches/criterion_prover_70k.rs index 88087789..160cdd62 100644 --- a/cairo_prover/benches/criterion_prover_70k.rs +++ b/cairo_prover/benches/criterion_prover_70k.rs @@ -1,7 +1,5 @@ -use cairo_platinum_prover::{ - air::generate_cairo_proof, - runner::run::{generate_prover_args, CairoVersion}, -}; +use cairo_platinum_prover::cairo_layout::CairoLayout; +use cairo_platinum_prover::{air::generate_cairo_proof, runner::run::generate_prover_args}; use criterion::{ black_box, criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion, SamplingMode, @@ -31,6 +29,7 @@ fn fibo_70k_bench(c: &mut Criterion) { &mut group, "fibonacci/70000", &cairo0_program_path("fibonacci_70000.json"), + CairoLayout::Plain, ); } @@ -41,11 +40,15 @@ fn cairo0_program_path(program_name: &str) -> String { program_base_path + program_name } -fn run_cairo_bench(group: &mut BenchmarkGroup<'_, WallTime>, benchname: &str, program_path: &str) { +fn run_cairo_bench( + group: &mut BenchmarkGroup<'_, WallTime>, + benchname: &str, + program_path: &str, + layout: CairoLayout, +) { let program_content = std::fs::read(program_path).unwrap(); let proof_options = ProofOptions::new_secure(SecurityLevel::Provable80Bits, 3); - let (main_trace, pub_inputs) = - generate_prover_args(&program_content, &CairoVersion::V0, &None).unwrap(); + let (main_trace, pub_inputs) = generate_prover_args(&program_content, &None, layout).unwrap(); group.bench_function(benchname, |bench| { bench.iter(|| { diff --git a/cairo_prover/cairo_programs/cairo1/fibonacci_cairo1.cairo b/cairo_prover/cairo_programs/cairo1/fibonacci_cairo1.cairo deleted file mode 100644 index 44f44028..00000000 --- a/cairo_prover/cairo_programs/cairo1/fibonacci_cairo1.cairo +++ /dev/null @@ -1,18 +0,0 @@ -use core::felt252; - -#[contract] -mod Fibonacci { - #[external] - fn main() -> felt252 { - let n = 10; - let result = fib(1, 1, n); - result - } - - fn fib(a: felt252, b: felt252, n: felt252) -> felt252 { - match n { - 0 => a, - _ => fib(b, a + b, n - 1), - } - } -} diff --git a/cairo_prover/cairo_programs/cairo1/fibonacci_cairo1.casm b/cairo_prover/cairo_programs/cairo1/fibonacci_cairo1.casm deleted file mode 100644 index 8d7e5943..00000000 --- a/cairo_prover/cairo_programs/cairo1/fibonacci_cairo1.casm +++ /dev/null @@ -1,378 +0,0 @@ -{ - "prime": "0x800000000000011000000000000000000000000000000000000000000000001", - "compiler_version": "1.1.0", - "bytecode": [ - "0xa0680017fff8000", - "0x7", - "0x482680017ffa8000", - "0x100000000000000000000000000000000", - "0x400280007ff97fff", - "0x10780017fff7fff", - "0x68", - "0x4825800180007ffa", - "0x0", - "0x400280007ff97fff", - "0x48297ffc80007ffd", - "0x482680017ff98000", - "0x1", - "0x4824800180007ffe", - "0x0", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0x6", - "0x480680017fff8000", - "0x0", - "0x10780017fff7fff", - "0x4", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x1", - "0x48307ffe80007fff", - "0x20680017fff7fff", - "0x40", - "0x1104800180018000", - "0xc4", - "0x482480017fff8000", - "0xc3", - "0x480080007fff8000", - "0xa0680017fff8000", - "0x9", - "0x4824800180007ff4", - "0x0", - "0x482480017fff8000", - "0x100000000000000000000000000000000", - "0x400080007ff47fff", - "0x10780017fff7fff", - "0x23", - "0x4824800180007ff4", - "0x0", - "0x400080007ff57fff", - "0x482480017ff58000", - "0x1", - "0x48127ffe7fff8000", - "0x1104800180018000", - "0x4a", - "0x20680017fff7ffd", - "0x11", - "0x40780017fff7fff", - "0x1", - "0x48127ffe7fff8000", - "0x48127ffe7fff8000", - "0x48127ffd7fff8000", - "0x1104800180018000", - "0x5c", - "0x48127ff37fff8000", - "0x48127ff37fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x0", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", - "0x208b7fff7fff7ffe", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482480017ff28000", - "0x1", - "0x48127fef7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x480a7ffb7fff8000", - "0x1104800180018000", - "0x3f", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", - "0x400080007ffe7fff", - "0x48127ff57fff8000", - "0x48127ff27fff8000", - "0x48127ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482680017ff98000", - "0x1", - "0x480a7ffa7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x480a7ffc7fff8000", - "0x480a7ffd7fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0xa", - "0x1104800180018000", - "0x1a", - "0x20680017fff7ffd", - "0xa", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x48127ffb7fff8000", - "0x208b7fff7fff7ffe", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x208b7fff7fff7ffe", - "0x400380007ffd7ffb", - "0x480a7ffc7fff8000", - "0x482680017ffd8000", - "0x1", - "0x208b7fff7fff7ffe", - "0x480a7ffd7fff8000", - "0x208b7fff7fff7ffe", - "0x1104800180018000", - "0x44", - "0x482480017fff8000", - "0x43", - "0x480080007fff8000", - "0xa0680017fff8000", - "0x9", - "0x4825800180007ffa", - "0xa0a", - "0x482480017fff8000", - "0x100000000000000000000000000000000", - "0x400280007ff97fff", - "0x10780017fff7fff", - "0x2a", - "0x4825800180007ffa", - "0xa0a", - "0x400280007ff97fff", - "0x482680017ff98000", - "0x1", - "0x20780017fff7ffd", - "0x7", - "0x48127fff7fff8000", - "0x48127ffd7fff8000", - "0x480a7ffb7fff8000", - "0x10780017fff7fff", - "0xf", - "0x48127fff7fff8000", - "0x48127ffd7fff8000", - "0x480a7ffc7fff8000", - "0x482a7ffc7ffb8000", - "0x4825800180007ffd", - "0x1", - "0x1104800180018000", - "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffe1", - "0x20680017fff7ffd", - "0xd", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x48127ffd7fff8000", - "0x48127ffd7fff8000", - "0x48127ffd7fff8000", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x48127ffb7fff8000", - "0x208b7fff7fff7ffe", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482680017ff98000", - "0x1", - "0x480a7ffa7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffb7fff8000", - "0x482480017ffa8000", - "0x1", - "0x208b7fff7fff7ffe" - ], - "hints": [ - [ - 0, - [ - { - "TestLessThanOrEqual": { - "lhs": { - "Immediate": "0x0" - }, - "rhs": { - "Deref": { - "register": "FP", - "offset": -6 - } - }, - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 35, - [ - { - "TestLessThanOrEqual": { - "lhs": { - "Immediate": "0x0" - }, - "rhs": { - "Deref": { - "register": "AP", - "offset": -11 - } - }, - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 54, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 77, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 95, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 109, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 163, - [ - { - "TestLessThanOrEqual": { - "lhs": { - "Immediate": "0xa0a" - }, - "rhs": { - "Deref": { - "register": "FP", - "offset": -6 - } - }, - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 212, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ] - ], - "entry_points_by_type": { - "EXTERNAL": [ - { - "selector": "0xe2054f8a912367e38a22ce773328ff8aabf8082c4120bad9ef085e1dbf29a7", - "offset": 0, - "builtins": [ - "range_check" - ] - } - ], - "L1_HANDLER": [], - "CONSTRUCTOR": [] - } -} \ No newline at end of file diff --git a/cairo_prover/src/air.rs b/cairo_prover/src/air.rs index 70cb3178..b6ca9748 100644 --- a/cairo_prover/src/air.rs +++ b/cairo_prover/src/air.rs @@ -1,5 +1,6 @@ -use std::{collections::HashMap, ops::Range}; +use std::ops::Range; +use cairo_vm::without_std::collections::HashMap; use lambdaworks_crypto::fiat_shamir::transcript::Transcript; use lambdaworks_math::{ errors::DeserializationError, @@ -46,27 +47,32 @@ const MEMORY_INCREASING_0: usize = 31; const MEMORY_INCREASING_1: usize = 32; const MEMORY_INCREASING_2: usize = 33; const MEMORY_INCREASING_3: usize = 34; - -const MEMORY_CONSISTENCY_0: usize = 35; -const MEMORY_CONSISTENCY_1: usize = 36; -const MEMORY_CONSISTENCY_2: usize = 37; -const MEMORY_CONSISTENCY_3: usize = 38; - -const PERMUTATION_ARGUMENT_0: usize = 39; -const PERMUTATION_ARGUMENT_1: usize = 40; -const PERMUTATION_ARGUMENT_2: usize = 41; -const PERMUTATION_ARGUMENT_3: usize = 42; - -const RANGE_CHECK_INCREASING_0: usize = 43; -const RANGE_CHECK_INCREASING_1: usize = 44; -const RANGE_CHECK_INCREASING_2: usize = 45; - -const RANGE_CHECK_0: usize = 46; -const RANGE_CHECK_1: usize = 47; -const RANGE_CHECK_2: usize = 48; +const MEMORY_INCREASING_4: usize = 35; + +const MEMORY_CONSISTENCY_0: usize = 36; +const MEMORY_CONSISTENCY_1: usize = 37; +const MEMORY_CONSISTENCY_2: usize = 38; +const MEMORY_CONSISTENCY_3: usize = 39; +const MEMORY_CONSISTENCY_4: usize = 40; + +const PERMUTATION_ARGUMENT_0: usize = 41; +const PERMUTATION_ARGUMENT_1: usize = 42; +const PERMUTATION_ARGUMENT_2: usize = 43; +const PERMUTATION_ARGUMENT_3: usize = 44; +const PERMUTATION_ARGUMENT_4: usize = 45; + +const RANGE_CHECK_INCREASING_0: usize = 46; +const RANGE_CHECK_INCREASING_1: usize = 47; +const RANGE_CHECK_INCREASING_2: usize = 48; +const RANGE_CHECK_INCREASING_3: usize = 49; + +const RANGE_CHECK_0: usize = 50; +const RANGE_CHECK_1: usize = 51; +const RANGE_CHECK_2: usize = 52; +const RANGE_CHECK_3: usize = 53; // Range-check builtin value decomposition constraint -const RANGE_CHECK_BUILTIN: usize = 49; +const RANGE_CHECK_BUILTIN: usize = 54; // Frame row identifiers // - Flags @@ -105,43 +111,50 @@ pub const OFF_OP1: usize = 29; pub const FRAME_T0: usize = 30; pub const FRAME_T1: usize = 31; pub const FRAME_MUL: usize = 32; -pub const FRAME_SELECTOR: usize = 33; +pub const EXTRA_ADDR: usize = 33; +pub const EXTRA_VAL: usize = 34; +pub const RC_HOLES: usize = 35; // Range-check frame identifiers -pub const RC_0: usize = 34; -pub const RC_1: usize = 35; -pub const RC_2: usize = 36; -pub const RC_3: usize = 37; -pub const RC_4: usize = 38; -pub const RC_5: usize = 39; -pub const RC_6: usize = 40; -pub const RC_7: usize = 41; -pub const RC_VALUE: usize = 42; +pub const RC_0: usize = 36; +pub const RC_1: usize = 37; +pub const RC_2: usize = 38; +pub const RC_3: usize = 39; +pub const RC_4: usize = 40; +pub const RC_5: usize = 41; +pub const RC_6: usize = 42; +pub const RC_7: usize = 43; +pub const RC_VALUE: usize = 44; // Auxiliary range check columns -pub const RANGE_CHECK_COL_1: usize = 43; -pub const RANGE_CHECK_COL_2: usize = 44; -pub const RANGE_CHECK_COL_3: usize = 45; +pub const RANGE_CHECK_COL_1: usize = 45; +pub const RANGE_CHECK_COL_2: usize = 46; +pub const RANGE_CHECK_COL_3: usize = 47; +pub const RANGE_CHECK_COL_4: usize = 48; // Auxiliary memory columns -pub const MEMORY_ADDR_SORTED_0: usize = 46; -pub const MEMORY_ADDR_SORTED_1: usize = 47; -pub const MEMORY_ADDR_SORTED_2: usize = 48; -pub const MEMORY_ADDR_SORTED_3: usize = 49; - -pub const MEMORY_VALUES_SORTED_0: usize = 50; -pub const MEMORY_VALUES_SORTED_1: usize = 51; -pub const MEMORY_VALUES_SORTED_2: usize = 52; -pub const MEMORY_VALUES_SORTED_3: usize = 53; - -pub const PERMUTATION_ARGUMENT_COL_0: usize = 54; -pub const PERMUTATION_ARGUMENT_COL_1: usize = 55; -pub const PERMUTATION_ARGUMENT_COL_2: usize = 56; -pub const PERMUTATION_ARGUMENT_COL_3: usize = 57; - -pub const PERMUTATION_ARGUMENT_RANGE_CHECK_COL_1: usize = 58; -pub const PERMUTATION_ARGUMENT_RANGE_CHECK_COL_2: usize = 59; -pub const PERMUTATION_ARGUMENT_RANGE_CHECK_COL_3: usize = 60; +pub const MEMORY_ADDR_SORTED_0: usize = 49; +pub const MEMORY_ADDR_SORTED_1: usize = 50; +pub const MEMORY_ADDR_SORTED_2: usize = 51; +pub const MEMORY_ADDR_SORTED_3: usize = 52; +pub const MEMORY_ADDR_SORTED_4: usize = 53; + +pub const MEMORY_VALUES_SORTED_0: usize = 54; +pub const MEMORY_VALUES_SORTED_1: usize = 55; +pub const MEMORY_VALUES_SORTED_2: usize = 56; +pub const MEMORY_VALUES_SORTED_3: usize = 57; +pub const MEMORY_VALUES_SORTED_4: usize = 58; + +pub const PERMUTATION_ARGUMENT_COL_0: usize = 59; +pub const PERMUTATION_ARGUMENT_COL_1: usize = 60; +pub const PERMUTATION_ARGUMENT_COL_2: usize = 61; +pub const PERMUTATION_ARGUMENT_COL_3: usize = 62; +pub const PERMUTATION_ARGUMENT_COL_4: usize = 63; + +pub const PERMUTATION_ARGUMENT_RANGE_CHECK_COL_1: usize = 64; +pub const PERMUTATION_ARGUMENT_RANGE_CHECK_COL_2: usize = 65; +pub const PERMUTATION_ARGUMENT_RANGE_CHECK_COL_3: usize = 66; +pub const PERMUTATION_ARGUMENT_RANGE_CHECK_COL_4: usize = 67; // Trace layout pub const MEM_P_TRACE_OFFSET: usize = 17; @@ -178,6 +191,7 @@ pub struct PublicInputs { pub memory_segments: MemorySegmentMap, pub public_memory: HashMap, pub num_steps: usize, // number of execution steps + pub codelen: usize, // length of the program segment } impl PublicInputs { @@ -187,12 +201,12 @@ impl PublicInputs { pub fn from_regs_and_mem( register_states: &RegisterStates, memory: &CairoMemory, - program_size: usize, + codelen: usize, memory_segments: &MemorySegmentMap, ) -> Self { let output_range = memory_segments.get(&MemorySegment::Output); - let mut public_memory = (1..=program_size as u64) + let mut public_memory = (1..=codelen as u64) .map(|i| (Felt252::from(i), *memory.get(&i).unwrap())) .collect::>(); @@ -214,6 +228,7 @@ impl PublicInputs { memory_segments: memory_segments.clone(), public_memory, num_steps: register_states.steps(), + codelen, } } } @@ -268,6 +283,7 @@ impl Serializable for PublicInputs { bytes.extend(public_memory_bytes); bytes.extend(self.num_steps.to_be_bytes()); + bytes.extend(self.codelen.to_be_bytes()); bytes } @@ -431,6 +447,14 @@ impl Deserializable for PublicInputs { .map_err(|_| DeserializationError::InvalidAmountOfBytes)?, ); + let codelen = usize::from_be_bytes( + bytes + .get(0..8) + .ok_or(DeserializationError::InvalidAmountOfBytes)? + .try_into() + .map_err(|_| DeserializationError::InvalidAmountOfBytes)?, + ); + Ok(Self { pc_init, ap_init, @@ -442,6 +466,7 @@ impl Deserializable for PublicInputs { memory_segments, public_memory, num_steps, + codelen, }) } } @@ -470,22 +495,43 @@ pub struct CairoRAPChallenges { pub z_range_check: FieldElement, } +/// Receives two slices corresponding to the accessed addresses and values, filled with +/// the memory holes and with the (0, 0) public memory dummy accesses. +/// Each (address, value) public memory pair is written in a (0, 0) dummy access until +/// there is no one left. +/// +/// NOTE: At the end of this process there might be some additional (0, 0) dummy accesses +/// that were not overwritten. This is not a problem as long as all the public memory pairs +/// have been written. fn add_pub_memory_in_public_input_section( - addresses: &Vec, + addresses: &[Felt252], values: &[Felt252], public_input: &PublicInputs, ) -> (Vec, Vec) { - let mut a_aux = addresses.clone(); + let mut a_aux = addresses.to_owned(); let mut v_aux = values.to_owned(); - let public_input_section = addresses.len() - public_input.public_memory.len(); let output_range = public_input.memory_segments.get(&MemorySegment::Output); - let pub_memory_addrs = get_pub_memory_addrs(output_range, public_input); - a_aux.splice(public_input_section.., pub_memory_addrs); - for i in public_input_section..a_aux.len() { - let address = &a_aux[i]; - v_aux[i] = *public_input.public_memory.get(address).unwrap(); + let pub_addrs = get_pub_memory_addrs(output_range, public_input); + let mut pub_addrs_iter = pub_addrs.iter(); + + // Iterate over addresses + for (i, a) in a_aux.iter_mut().enumerate() { + // When address `0` is found, it means it corresponds to a dummy access. + if a == &Felt252::zero() { + // While there are public memory addresses left, overwrite the dummy + // (addr, value) accesses with the real public memory pairs. + if let Some(pub_addr) = pub_addrs_iter.next() { + *a = *pub_addr; + v_aux[i] = *public_input.public_memory.get(pub_addr).unwrap(); + } else { + // When there are no public memory pairs left to write, break the + // loop and return the (addr, value) pairs with dummy accesses + // overwritten. + break; + } + } } (a_aux, v_aux) @@ -592,16 +638,16 @@ impl AIR for CairoAIR { ) -> Self { debug_assert!(trace_length.is_power_of_two()); - let mut trace_columns = 34 + 3 + 12 + 3; + let mut trace_columns = 34 + 4 + 15 + 4; let mut transition_degrees = vec![ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // Flags 0-14. 1, // Flag 15 - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Other constraints. - 2, 2, 2, 2, // Increasing memory auxiliary constraints. - 2, 2, 2, 2, // Consistent memory auxiliary constraints. - 2, 2, 2, 2, // Permutation auxiliary constraints. - 2, 2, 2, // range-check increasing constraints. - 2, 2, 2, // range-check permutation argument constraints. + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // Other constraints. + 2, 2, 2, 2, 2, // Increasing memory auxiliary constraints. + 2, 2, 2, 2, 2, // Consistent memory auxiliary constraints. + 2, 2, 2, 2, 2, // Permutation auxiliary constraints. + 2, 2, 2, 2, // range-check increasing constraints. + 2, 2, 2, 2, // range-check permutation argument constraints. ]; let mut transition_exemptions = vec![ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // flags (16) @@ -609,19 +655,19 @@ impl AIR for CairoAIR { 0, 0, 0, // operand consraints (3) 1, 1, 1, 1, 0, 0, // register constraints (6) 0, 0, 0, 0, 0, // opcode constraints (5) - 0, 0, 0, 1, // memory continuous (4) - 0, 0, 0, 1, // memory value consistency (4) - 0, 0, 0, 1, // memory permutation argument (4) - 0, 0, 1, // range check continuous (3) - 0, 0, 0, // range check permutation argument (3) + 0, 0, 0, 0, 1, // memory continuous (4) + 0, 0, 0, 0, 1, // memory value consistency (4) + 0, 0, 0, 0, 1, // memory permutation argument (4) + 0, 0, 0, 1, // range check continuous (3) + 0, 0, 0, 0, // range check permutation argument (3) ]; - let mut num_transition_constraints = 49; + let mut num_transition_constraints = 54; // This is a hacky solution for the moment and must be changed once we start implementing // layouts functionality. The `has_rc_builtin` boolean should not exist, we will know the // layout from the Cairo public inputs directly, and the number of constraints and columns // will be enforced through that. - let has_rc_builtin = !pub_inputs.memory_segments.is_empty(); + let has_rc_builtin = pub_inputs.memory_segments.get(&MemorySegment::RangeCheck).is_some(); if has_rc_builtin { trace_columns += 8 + 1; // 8 columns for each rc of the range-check builtin values decomposition, 1 for the values transition_degrees.push(1); // Range check builtin constraint @@ -664,10 +710,17 @@ impl AIR for CairoAIR { rap_challenges: &Self::RAPChallenges, ) -> TraceTable { let addresses_original = main_trace - .get_cols(&[FRAME_PC, FRAME_DST_ADDR, FRAME_OP0_ADDR, FRAME_OP1_ADDR]) + .get_cols(&[ + FRAME_PC, + FRAME_DST_ADDR, + FRAME_OP0_ADDR, + FRAME_OP1_ADDR, + EXTRA_ADDR, + ]) .table; + let values_original = main_trace - .get_cols(&[FRAME_INST, FRAME_DST, FRAME_OP0, FRAME_OP1]) + .get_cols(&[FRAME_INST, FRAME_DST, FRAME_OP0, FRAME_OP1, EXTRA_VAL]) .table; let (addresses, values) = add_pub_memory_in_public_input_section( @@ -675,6 +728,7 @@ impl AIR for CairoAIR { &values_original, &self.pub_inputs, ); + let (addresses, values) = sort_columns_by_memory_address(addresses, values); let permutation_col = generate_memory_permutation_argument_column( @@ -686,7 +740,9 @@ impl AIR for CairoAIR { ); // Range Check - let offsets_original = main_trace.get_cols(&[OFF_DST, OFF_OP0, OFF_OP1]).table; + let offsets_original = main_trace + .get_cols(&[OFF_DST, OFF_OP0, OFF_OP1, RC_HOLES]) + .table; let mut offsets_sorted: Vec = offsets_original .iter() .map(|x| x.representative().into()) @@ -706,24 +762,29 @@ impl AIR for CairoAIR { // Convert from long-format to wide-format again let mut aux_table = Vec::new(); for i in 0..main_trace.n_rows() { - aux_table.push(offsets_sorted[3 * i]); - aux_table.push(offsets_sorted[3 * i + 1]); - aux_table.push(offsets_sorted[3 * i + 2]); - aux_table.push(addresses[4 * i]); - aux_table.push(addresses[4 * i + 1]); - aux_table.push(addresses[4 * i + 2]); - aux_table.push(addresses[4 * i + 3]); - aux_table.push(values[4 * i]); - aux_table.push(values[4 * i + 1]); - aux_table.push(values[4 * i + 2]); - aux_table.push(values[4 * i + 3]); - aux_table.push(permutation_col[4 * i]); - aux_table.push(permutation_col[4 * i + 1]); - aux_table.push(permutation_col[4 * i + 2]); - aux_table.push(permutation_col[4 * i + 3]); - aux_table.push(range_check_permutation_col[3 * i]); - aux_table.push(range_check_permutation_col[3 * i + 1]); - aux_table.push(range_check_permutation_col[3 * i + 2]); + aux_table.push(offsets_sorted[4 * i]); + aux_table.push(offsets_sorted[4 * i + 1]); + aux_table.push(offsets_sorted[4 * i + 2]); + aux_table.push(offsets_sorted[4 * i + 3]); + aux_table.push(addresses[5 * i]); + aux_table.push(addresses[5 * i + 1]); + aux_table.push(addresses[5 * i + 2]); + aux_table.push(addresses[5 * i + 3]); + aux_table.push(addresses[5 * i + 4]); + aux_table.push(values[5 * i]); + aux_table.push(values[5 * i + 1]); + aux_table.push(values[5 * i + 2]); + aux_table.push(values[5 * i + 3]); + aux_table.push(values[5 * i + 4]); + aux_table.push(permutation_col[5 * i]); + aux_table.push(permutation_col[5 * i + 1]); + aux_table.push(permutation_col[5 * i + 2]); + aux_table.push(permutation_col[5 * i + 3]); + aux_table.push(permutation_col[5 * i + 4]); + aux_table.push(range_check_permutation_col[4 * i]); + aux_table.push(range_check_permutation_col[4 * i + 1]); + aux_table.push(range_check_permutation_col[4 * i + 2]); + aux_table.push(range_check_permutation_col[4 * i + 3]); } TraceTable::new(aux_table, self.number_auxiliary_rap_columns()) @@ -738,7 +799,9 @@ impl AIR for CairoAIR { } fn number_auxiliary_rap_columns(&self) -> usize { - 12 + 3 + 3 + // RANGE_CHECK_COL_i + MEMORY_INCREASING_i + MEMORY_CONSISTENCY_i + PERMUTATION_ARGUMENT_COL_i + + // + PERMUTATION_ARGUMENT_RANGE_CHECK_COL_i + 4 + 5 + 5 + 5 + 4 } fn compute_transition( @@ -755,7 +818,6 @@ impl AIR for CairoAIR { compute_operand_constraints(&mut constraints, frame); compute_register_constraints(&mut constraints, frame); compute_opcode_constraints(&mut constraints, frame); - enforce_selector(&mut constraints, frame); memory_is_increasing(&mut constraints, frame, builtin_offset); permutation_argument(&mut constraints, frame, rap_challenges, builtin_offset); permutation_argument_range_check(&mut constraints, frame, rap_challenges, builtin_offset); @@ -807,19 +869,21 @@ impl AIR for CairoAIR { * (rap_challenges.z_memory - (address + rap_challenges.alpha_memory * value)) }) .inv(); + let permutation_final = rap_challenges .z_memory .pow(self.pub_inputs.public_memory.len()) * cumulative_product; + let permutation_final_constraint = BoundaryConstraint::new( - PERMUTATION_ARGUMENT_COL_3 - builtin_offset, + PERMUTATION_ARGUMENT_COL_4 - builtin_offset, final_index, permutation_final, ); let one: FieldElement = FieldElement::one(); let range_check_final_constraint = BoundaryConstraint::new( - PERMUTATION_ARGUMENT_RANGE_CHECK_COL_3 - builtin_offset, + PERMUTATION_ARGUMENT_RANGE_CHECK_COL_4 - builtin_offset, final_index, one, ); @@ -829,8 +893,9 @@ impl AIR for CairoAIR { 0, FieldElement::from(self.pub_inputs.range_check_min.unwrap() as u64), ); + let range_check_max = BoundaryConstraint::new( - RANGE_CHECK_COL_3 - builtin_offset, + RANGE_CHECK_COL_4 - builtin_offset, final_index, FieldElement::from(self.pub_inputs.range_check_max.unwrap() as u64), ); @@ -975,13 +1040,6 @@ fn compute_opcode_constraints(constraints: &mut [Felt252], frame: &Frame) { - let curr = frame.get_row(0); - for result_cell in constraints.iter_mut().take(ASSERT_EQ + 1).skip(INST) { - *result_cell = *result_cell * curr[FRAME_SELECTOR]; - } -} - fn memory_is_increasing( constraints: &mut [Felt252], frame: &Frame, @@ -1010,9 +1068,15 @@ fn memory_is_increasing( - one); constraints[MEMORY_INCREASING_3] = (curr[MEMORY_ADDR_SORTED_3 - builtin_offset] + - curr[MEMORY_ADDR_SORTED_4 - builtin_offset]) + * (curr[MEMORY_ADDR_SORTED_4 - builtin_offset] + - curr[MEMORY_ADDR_SORTED_3 - builtin_offset] + - one); + + constraints[MEMORY_INCREASING_4] = (curr[MEMORY_ADDR_SORTED_4 - builtin_offset] - next[MEMORY_ADDR_SORTED_0 - builtin_offset]) * (next[MEMORY_ADDR_SORTED_0 - builtin_offset] - - curr[MEMORY_ADDR_SORTED_3 - builtin_offset] + - curr[MEMORY_ADDR_SORTED_4 - builtin_offset] - one); constraints[MEMORY_CONSISTENCY_0] = (curr[MEMORY_VALUES_SORTED_0 - builtin_offset] @@ -1034,9 +1098,15 @@ fn memory_is_increasing( - one); constraints[MEMORY_CONSISTENCY_3] = (curr[MEMORY_VALUES_SORTED_3 - builtin_offset] + - curr[MEMORY_VALUES_SORTED_4 - builtin_offset]) + * (curr[MEMORY_ADDR_SORTED_4 - builtin_offset] + - curr[MEMORY_ADDR_SORTED_3 - builtin_offset] + - one); + + constraints[MEMORY_CONSISTENCY_4] = (curr[MEMORY_VALUES_SORTED_4 - builtin_offset] - next[MEMORY_VALUES_SORTED_0 - builtin_offset]) * (next[MEMORY_ADDR_SORTED_0 - builtin_offset] - - curr[MEMORY_ADDR_SORTED_3 - builtin_offset] + - curr[MEMORY_ADDR_SORTED_4 - builtin_offset] - one); } @@ -1056,26 +1126,31 @@ fn permutation_argument( let p1 = &curr[PERMUTATION_ARGUMENT_COL_1 - builtin_offset]; let p2 = &curr[PERMUTATION_ARGUMENT_COL_2 - builtin_offset]; let p3 = &curr[PERMUTATION_ARGUMENT_COL_3 - builtin_offset]; + let p4 = &curr[PERMUTATION_ARGUMENT_COL_4 - builtin_offset]; let ap0_next = &next[MEMORY_ADDR_SORTED_0 - builtin_offset]; let ap1 = &curr[MEMORY_ADDR_SORTED_1 - builtin_offset]; let ap2 = &curr[MEMORY_ADDR_SORTED_2 - builtin_offset]; let ap3 = &curr[MEMORY_ADDR_SORTED_3 - builtin_offset]; + let ap4 = &curr[MEMORY_ADDR_SORTED_4 - builtin_offset]; let vp0_next = &next[MEMORY_VALUES_SORTED_0 - builtin_offset]; let vp1 = &curr[MEMORY_VALUES_SORTED_1 - builtin_offset]; let vp2 = &curr[MEMORY_VALUES_SORTED_2 - builtin_offset]; let vp3 = &curr[MEMORY_VALUES_SORTED_3 - builtin_offset]; + let vp4 = &curr[MEMORY_VALUES_SORTED_4 - builtin_offset]; let a0_next = &next[FRAME_PC]; let a1 = &curr[FRAME_DST_ADDR]; let a2 = &curr[FRAME_OP0_ADDR]; let a3 = &curr[FRAME_OP1_ADDR]; + let a4 = &curr[EXTRA_ADDR]; let v0_next = &next[FRAME_INST]; let v1 = &curr[FRAME_DST]; let v2 = &curr[FRAME_OP0]; let v3 = &curr[FRAME_OP1]; + let v4 = &curr[EXTRA_VAL]; constraints[PERMUTATION_ARGUMENT_0] = (z - (ap1 + alpha * vp1)) * p1 - (z - (a1 + alpha * v1)) * p0; @@ -1084,7 +1159,9 @@ fn permutation_argument( constraints[PERMUTATION_ARGUMENT_2] = (z - (ap3 + alpha * vp3)) * p3 - (z - (a3 + alpha * v3)) * p2; constraints[PERMUTATION_ARGUMENT_3] = - (z - (ap0_next + alpha * vp0_next)) * p0_next - (z - (a0_next + alpha * v0_next)) * p3; + (z - (ap4 + alpha * vp4)) * p4 - (z - (a4 + alpha * v4)) * p3; + constraints[PERMUTATION_ARGUMENT_4] = + (z - (ap0_next + alpha * vp0_next)) * p0_next - (z - (a0_next + alpha * v0_next)) * p4; } fn permutation_argument_range_check( @@ -1109,27 +1186,36 @@ fn permutation_argument_range_check( - curr[RANGE_CHECK_COL_2 - builtin_offset] - one); constraints[RANGE_CHECK_INCREASING_2] = (curr[RANGE_CHECK_COL_3 - builtin_offset] + - curr[RANGE_CHECK_COL_4 - builtin_offset]) + * (curr[RANGE_CHECK_COL_4 - builtin_offset] + - curr[RANGE_CHECK_COL_3 - builtin_offset] + - one); + constraints[RANGE_CHECK_INCREASING_3] = (curr[RANGE_CHECK_COL_4 - builtin_offset] - next[RANGE_CHECK_COL_1 - builtin_offset]) * (next[RANGE_CHECK_COL_1 - builtin_offset] - - curr[RANGE_CHECK_COL_3 - builtin_offset] + - curr[RANGE_CHECK_COL_4 - builtin_offset] - one); let p0 = curr[PERMUTATION_ARGUMENT_RANGE_CHECK_COL_1 - builtin_offset]; let p0_next = next[PERMUTATION_ARGUMENT_RANGE_CHECK_COL_1 - builtin_offset]; let p1 = curr[PERMUTATION_ARGUMENT_RANGE_CHECK_COL_2 - builtin_offset]; let p2 = curr[PERMUTATION_ARGUMENT_RANGE_CHECK_COL_3 - builtin_offset]; + let p3 = curr[PERMUTATION_ARGUMENT_RANGE_CHECK_COL_4 - builtin_offset]; let ap0_next = next[RANGE_CHECK_COL_1 - builtin_offset]; let ap1 = curr[RANGE_CHECK_COL_2 - builtin_offset]; let ap2 = curr[RANGE_CHECK_COL_3 - builtin_offset]; + let ap3 = curr[RANGE_CHECK_COL_4 - builtin_offset]; let a0_next = next[OFF_DST]; let a1 = curr[OFF_OP0]; let a2 = curr[OFF_OP1]; + let a3 = curr[RC_HOLES]; constraints[RANGE_CHECK_0] = (z - ap1) * p1 - (z - a1) * p0; constraints[RANGE_CHECK_1] = (z - ap2) * p2 - (z - a2) * p1; - constraints[RANGE_CHECK_2] = (z - ap0_next) * p0_next - (z - a0_next) * p2; + constraints[RANGE_CHECK_2] = (z - ap3) * p3 - (z - a3) * p2; + constraints[RANGE_CHECK_3] = (z - ap0_next) * p0_next - (z - a0_next) * p3; } fn frame_inst_size(frame_row: &[Felt252]) -> Felt252 { @@ -1182,14 +1268,7 @@ pub fn verify_cairo_proof( #[cfg(test)] #[cfg(debug_assertions)] mod test { - use crate::{ - runner::run::{generate_prover_args, CairoVersion}, - tests::utils::cairo0_program_path, - }; - use stark_platinum_prover::{debug::validate_trace, domain::Domain}; - use super::*; - use lambdaworks_crypto::fiat_shamir::default_transcript::DefaultTranscript; use lambdaworks_math::field::element::FieldElement; #[test] @@ -1216,33 +1295,6 @@ mod test { ); } - #[test] - fn check_simple_cairo_trace_evaluates_to_zero() { - let program_content = std::fs::read(cairo0_program_path("simple_program.json")).unwrap(); - let (main_trace, public_input) = - generate_prover_args(&program_content, &CairoVersion::V0, &None).unwrap(); - let mut trace_polys = main_trace.compute_trace_polys(); - let mut transcript = DefaultTranscript::new(); - - let proof_options = ProofOptions::default_test_options(); - let cairo_air = CairoAIR::new(main_trace.n_rows(), &public_input, &proof_options); - let rap_challenges = cairo_air.build_rap_challenges(&mut transcript); - - let aux_trace = cairo_air.build_auxiliary_trace(&main_trace, &rap_challenges); - let aux_polys = aux_trace.compute_trace_polys(); - - trace_polys.extend_from_slice(&aux_polys); - - let domain = Domain::new(&cairo_air); - - assert!(validate_trace( - &cairo_air, - &trace_polys, - &domain, - &rap_challenges - )); - } - #[test] fn test_build_auxiliary_trace_add_program_in_public_input_section_works() { let dummy_public_input = PublicInputs { @@ -1254,20 +1306,24 @@ mod test { public_memory: HashMap::from([ (FieldElement::one(), FieldElement::from(10)), (FieldElement::from(2), FieldElement::from(20)), - (FieldElement::from(3), FieldElement::from(30)), ]), range_check_max: None, range_check_min: None, num_steps: 1, memory_segments: MemorySegmentMap::new(), + codelen: 3, }; let a = vec![ + FieldElement::one(), + FieldElement::one(), FieldElement::one(), FieldElement::one(), FieldElement::zero(), - FieldElement::zero(), - FieldElement::zero(), + FieldElement::from(2), + FieldElement::from(2), + FieldElement::from(2), + FieldElement::from(2), FieldElement::zero(), ]; let v = vec![ @@ -1277,6 +1333,10 @@ mod test { FieldElement::zero(), FieldElement::zero(), FieldElement::zero(), + FieldElement::zero(), + FieldElement::zero(), + FieldElement::zero(), + FieldElement::zero(), ]; let (ap, vp) = add_pub_memory_in_public_input_section(&a, &v, &dummy_public_input); assert_eq!( @@ -1284,10 +1344,14 @@ mod test { vec![ FieldElement::one(), FieldElement::one(), - FieldElement::zero(), + FieldElement::one(), + FieldElement::one(), FieldElement::one(), FieldElement::from(2), - FieldElement::from(3) + FieldElement::from(2), + FieldElement::from(2), + FieldElement::from(2), + FieldElement::from(2), ] ); assert_eq!( @@ -1296,9 +1360,13 @@ mod test { FieldElement::one(), FieldElement::one(), FieldElement::zero(), + FieldElement::zero(), FieldElement::from(10), + FieldElement::zero(), + FieldElement::zero(), + FieldElement::zero(), + FieldElement::zero(), FieldElement::from(20), - FieldElement::from(30) ] ); } @@ -1314,26 +1382,33 @@ mod test { public_memory: HashMap::from([ (FieldElement::one(), FieldElement::from(10)), (FieldElement::from(2), FieldElement::from(20)), - (FieldElement::from(3), FieldElement::from(30)), (FieldElement::from(20), FieldElement::from(40)), - (FieldElement::from(21), FieldElement::from(50)), ]), range_check_max: None, range_check_min: None, num_steps: 1, - memory_segments: MemorySegmentMap::from([(MemorySegment::Output, 20..22)]), + memory_segments: MemorySegmentMap::from([(MemorySegment::Output, 20..21)]), + codelen: 3, }; let a = vec![ + FieldElement::one(), + FieldElement::one(), FieldElement::one(), FieldElement::one(), FieldElement::zero(), + FieldElement::one(), + FieldElement::one(), + FieldElement::one(), + FieldElement::one(), FieldElement::zero(), - FieldElement::zero(), - FieldElement::zero(), - FieldElement::zero(), + FieldElement::one(), + FieldElement::one(), + FieldElement::one(), + FieldElement::one(), FieldElement::zero(), ]; + let v = vec![ FieldElement::one(), FieldElement::one(), @@ -1343,19 +1418,34 @@ mod test { FieldElement::zero(), FieldElement::zero(), FieldElement::zero(), + FieldElement::zero(), + FieldElement::zero(), + FieldElement::zero(), + FieldElement::zero(), + FieldElement::zero(), + FieldElement::zero(), + FieldElement::zero(), ]; + let (ap, vp) = add_pub_memory_in_public_input_section(&a, &v, &dummy_public_input); assert_eq!( ap, vec![ FieldElement::one(), FieldElement::one(), - FieldElement::zero(), + FieldElement::one(), + FieldElement::one(), + FieldElement::one(), + FieldElement::one(), + FieldElement::one(), + FieldElement::one(), FieldElement::one(), FieldElement::from(2), - FieldElement::from(3), + FieldElement::one(), + FieldElement::one(), + FieldElement::one(), + FieldElement::one(), FieldElement::from(20), - FieldElement::from(21) ] ); assert_eq!( @@ -1364,11 +1454,18 @@ mod test { FieldElement::one(), FieldElement::one(), FieldElement::zero(), + FieldElement::zero(), FieldElement::from(10), + FieldElement::zero(), + FieldElement::zero(), + FieldElement::zero(), + FieldElement::zero(), FieldElement::from(20), - FieldElement::from(30), + FieldElement::zero(), + FieldElement::zero(), + FieldElement::zero(), + FieldElement::zero(), FieldElement::from(40), - FieldElement::from(50) ] ); } @@ -1466,7 +1563,8 @@ mod prop_test { use crate::{ air::{generate_cairo_proof, verify_cairo_proof}, - runner::run::{generate_prover_args, CairoVersion}, + cairo_layout::CairoLayout, + runner::run::generate_prover_args, tests::utils::cairo0_program_path, Felt252, }; @@ -1490,6 +1588,7 @@ mod prop_test { range_check_max in proptest::option::of(any::()), range_check_min in proptest::option::of(any::()), num_steps in any::(), + codelen in any::(), ) -> PublicInputs { let public_memory = public_memory.iter().map(|(k, v)| (Felt252::from(*k), Felt252::from(*v))).collect(); let memory_segments = MemorySegmentMap::from([(MemorySegment::Output, 10u64..16u64), (MemorySegment::RangeCheck, 20u64..71u64)]); @@ -1504,6 +1603,7 @@ mod prop_test { range_check_min, num_steps, memory_segments, + codelen, } } } @@ -1533,7 +1633,7 @@ mod prop_test { fn deserialize_and_verify() { let program_content = std::fs::read(cairo0_program_path("fibonacci_10.json")).unwrap(); let (main_trace, pub_inputs) = - generate_prover_args(&program_content, &CairoVersion::V0, &None).unwrap(); + generate_prover_args(&program_content, &None, CairoLayout::Plain).unwrap(); let proof_options = ProofOptions::default_test_options(); @@ -1558,7 +1658,7 @@ mod prop_test { fn deserialize_should_not_panic_with_changed_and_sliced_bytes() { let program_content = std::fs::read(cairo0_program_path("fibonacci_10.json")).unwrap(); let (main_trace, pub_inputs) = - generate_prover_args(&program_content, &CairoVersion::V0, &None).unwrap(); + generate_prover_args(&program_content, &None, CairoLayout::Plain).unwrap(); let proof_options = ProofOptions::default_test_options(); diff --git a/cairo_prover/src/execution_trace.rs b/cairo_prover/src/execution_trace.rs index b6db08d0..c0e7d063 100644 --- a/cairo_prover/src/execution_trace.rs +++ b/cairo_prover/src/execution_trace.rs @@ -6,14 +6,14 @@ use lambdaworks_math::{ }, unsigned_integer::element::UnsignedInteger, }; -use num_integer::div_ceil; use stark_platinum_prover::trace::TraceTable; -use std::{iter, ops::Range}; +use std::ops::Range; +use crate::air::{EXTRA_ADDR, RC_HOLES}; use crate::{ air::{ - MemorySegment, PublicInputs, FRAME_DST, FRAME_DST_ADDR, FRAME_INST, FRAME_OP0, - FRAME_OP0_ADDR, FRAME_OP1, FRAME_OP1_ADDR, FRAME_PC, OFF_DST, OFF_OP0, OFF_OP1, + MemorySegment, PublicInputs, FRAME_DST_ADDR, FRAME_OP0_ADDR, FRAME_OP1_ADDR, FRAME_PC, + OFF_DST, OFF_OP0, OFF_OP1, }, Felt252, }; @@ -30,19 +30,6 @@ use super::{ register_states::RegisterStates, }; -pub const MEMORY_COLUMNS: [usize; 8] = [ - FRAME_PC, - FRAME_DST_ADDR, - FRAME_OP0_ADDR, - FRAME_OP1_ADDR, - FRAME_INST, - FRAME_DST, - FRAME_OP0, - FRAME_OP1, -]; - -pub const ADDR_COLUMNS: [usize; 4] = [FRAME_PC, FRAME_DST_ADDR, FRAME_OP0_ADDR, FRAME_OP1_ADDR]; - // MAIN TRACE LAYOUT // ----------------------------------------------------------------------------------------- // A. flags (16) : Decoded instruction flags @@ -76,15 +63,20 @@ pub fn build_main_trace( let (rc_holes, rc_min, rc_max) = get_rc_holes(&main_trace, &[OFF_DST, OFF_OP0, OFF_OP1]); public_input.range_check_min = Some(rc_min); public_input.range_check_max = Some(rc_max); - fill_rc_holes(&mut main_trace, rc_holes); + fill_rc_holes(&mut main_trace, &rc_holes); - let memory_holes = get_memory_holes(&address_cols, public_input.public_memory.len()); + let memory_holes = get_memory_holes(&address_cols, public_input.codelen); + // let memory_holes = get_memory_holes(&address_cols, public_input.public_memory.len()); if !memory_holes.is_empty() { fill_memory_holes(&mut main_trace, &memory_holes); } - add_pub_memory_dummy_accesses(&mut main_trace, public_input.public_memory.len()); + add_pub_memory_dummy_accesses( + &mut main_trace, + public_input.public_memory.len(), + memory_holes.len(), + ); let trace_len_next_power_of_two = main_trace.n_rows().next_power_of_two(); let padding = trace_len_next_power_of_two - main_trace.n_rows(); @@ -95,11 +87,19 @@ pub fn build_main_trace( /// Artificial `(0, 0)` dummy memory accesses must be added for the public memory. /// See section 9.8 of the Cairo whitepaper. -fn add_pub_memory_dummy_accesses( - main_trace: &mut TraceTable, +fn add_pub_memory_dummy_accesses( + main_trace: &mut TraceTable, pub_memory_len: usize, + last_memory_hole_idx: usize, ) { - pad_with_last_row_and_zeros(main_trace, (pub_memory_len >> 2) + 1, &MEMORY_COLUMNS) + for i in 0..pub_memory_len { + add_to_column( + last_memory_hole_idx + i, + main_trace, + &Felt252::zero(), + EXTRA_ADDR, + ); + } } fn pad_with_last_row(trace: &mut TraceTable, number_rows: usize) { @@ -112,27 +112,6 @@ fn pad_with_last_row(trace: &mut TraceTable, number_rows: usiz trace.table.append(&mut pad); } -/// Pads trace with its last row, with the exception of the columns specified in -/// `zero_pad_columns`, where the pad is done with zeros. -/// If the last row is [2, 1, 4, 1] and the zero pad columns are [0, 1], then the -/// padding will be [0, 0, 4, 1]. -fn pad_with_last_row_and_zeros( - trace: &mut TraceTable, - number_rows: usize, - zero_pad_columns: &[usize], -) { - let mut last_row = trace.last_row().to_vec(); - for exemption_column in zero_pad_columns.iter() { - last_row[*exemption_column] = FieldElement::zero(); - } - let mut pad: Vec<_> = std::iter::repeat(&last_row) - .take(number_rows) - .flatten() - .cloned() - .collect(); - trace.table.append(&mut pad); -} - /// Gets holes from the range-checked columns. These holes must be filled for the /// permutation range-checks, as can be read in section 9.9 of the Cairo whitepaper. /// Receives the trace and the indexes of the range-checked columns. @@ -180,15 +159,18 @@ where } /// Fills holes found in the range-checked columns. -fn fill_rc_holes(trace: &mut TraceTable, holes: Vec>) { - let zeros_left = vec![FieldElement::zero(); OFF_DST]; - let zeros_right = vec![FieldElement::zero(); trace.n_cols - OFF_OP1 - 1]; - - for i in (0..holes.len()).step_by(3) { - trace.table.append(&mut zeros_left.clone()); - trace.table.append(&mut holes[i..(i + 3)].to_vec()); - trace.table.append(&mut zeros_right.clone()); - } +fn fill_rc_holes(trace: &mut TraceTable, holes: &[Felt252]) { + holes.iter().enumerate().for_each(|(i, hole)| { + add_to_column(i, trace, hole, RC_HOLES); + }); + + // Fill the rest of the RC_HOLES column to avoid inexistent zeros + let mut offsets = trace.get_cols(&[OFF_DST, OFF_OP0, OFF_OP1, RC_HOLES]).table; + offsets.sort_by_key(|x| x.representative()); + let greatest_offset = offsets.last().unwrap(); + (holes.len()..trace.n_rows()).for_each(|i| { + add_to_column(i, trace, greatest_offset, RC_HOLES); + }); } /// Get memory holes from accessed addresses. These memory holes appear @@ -228,36 +210,26 @@ fn get_memory_holes(sorted_addrs: &[Felt252], codelen: usize) -> Vec { memory_holes } -/// Fill memory holes in each address column of the trace with the missing address, depending on the -/// trace column. If the trace column reFelt252rs to memory addresses, it will be filled with the missing -/// addresses. +/// Fill memory holes in the extra address column of the trace with the missing addresses. fn fill_memory_holes(trace: &mut TraceTable, memory_holes: &[Felt252]) { - let last_row = trace.last_row().to_vec(); - - // This number represents the amount of times we have to pad to fill the memory - // holes into the trace. - // There are a total of ADDR_COLUMNS.len() address columns, and we have to append - // hole addresses in each column until there are no more holes. - // If we have that memory_holes = [1, 2, 3, 4, 5] and there are 4 address columns, - // we will have to pad with 2 rows, one for the first [1, 2, 3, 4] and one for the - // 5 value. - let padding_size = div_ceil(memory_holes.len(), ADDR_COLUMNS.len()); - - let padding_row_iter = iter::repeat(last_row).take(padding_size); - let addr_columns_iter = iter::repeat(ADDR_COLUMNS).take(padding_size); - let mut memory_holes_iter = memory_holes.iter(); - - for (addr_cols, mut padding_row) in iter::zip(addr_columns_iter, padding_row_iter) { - // The particular placement of the holes in each column is not important, - // the only thing that matters is that the addresses are put somewhere in the address - // columns. - addr_cols.iter().for_each(|a_col| { - if let Some(hole) = memory_holes_iter.next() { - padding_row[*a_col] = *hole; - } - }); + memory_holes.iter().enumerate().for_each(|(i, hole)| { + add_to_column(i, trace, hole, EXTRA_ADDR); + }); +} - trace.table.append(&mut padding_row); +fn add_to_column( + i: usize, + trace: &mut TraceTable, + value: &Felt252, + col: usize, +) { + let trace_idx = i * trace.n_cols + col; + if trace_idx >= trace.table.len() { + let mut last_row = trace.last_row().to_vec(); + last_row[col] = *value; + trace.table.append(&mut last_row); + } else { + trace.table[trace_idx] = *value; } } @@ -329,8 +301,9 @@ pub fn build_cairo_execution_trace( let trace_repr_flags = rows_to_cols(&trace_repr_flags); let trace_repr_offsets = rows_to_cols(&trace_repr_offsets); - let mut selector = vec![Felt252::one(); n_steps]; - selector[n_steps - 1] = Felt252::zero(); + let extra_addrs = vec![Felt252::zero(); n_steps]; + let extra_vals = extra_addrs.clone(); + let rc_holes = extra_addrs.clone(); // Build Cairo trace columns to instantiate TraceTable struct as defined in the trace layout let mut trace_cols: Vec> = Vec::new(); @@ -350,7 +323,9 @@ pub fn build_cairo_execution_trace( trace_cols.push(t0); trace_cols.push(t1); trace_cols.push(mul); - trace_cols.push(selector); + trace_cols.push(extra_addrs); + trace_cols.push(extra_vals); + trace_cols.push(rc_holes); if let Some(range_check_builtin_range) = public_inputs .memory_segments @@ -642,12 +617,7 @@ fn decompose_rc_values_into_trace_columns(rc_values: &[&Felt252]) -> [Vec (res: Felt252lt) { - return (res = x * y); - } - - func main() { - let x = 2; - let y = 3; - - let (res) = mul(x, y); - assert res = 6; - - return (); - } - - ``` - */ - - let program_content = std::fs::read(cairo0_program_path("call_func.json")).unwrap(); - let (register_states, memory, program_size, _rangecheck_base_end) = run_program( - None, - CairoLayout::AllCairo, - &program_content, - &CairoVersion::V0, - ) - .unwrap(); - - let pub_inputs = PublicInputs::from_regs_and_mem( - ®ister_states, - &memory, - program_size, - &MemorySegmentMap::new(), - ); - - let execution_trace = build_cairo_execution_trace(®ister_states, &memory, &pub_inputs); - - // This trace is obtained from Giza when running the prover for the mentioned program. - let expected_trace = TraceTable::new_from_cols(&[ - // col 0 - vec![ - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::one(), - Felt252::zero(), - Felt252::one(), - ], - // col 1 - vec![ - Felt252::one(), - Felt252::one(), - Felt252::zero(), - Felt252::one(), - Felt252::one(), - Felt252::one(), - Felt252::one(), - ], - // col 2 - vec![ - Felt252::one(), - Felt252::one(), - Felt252::one(), - Felt252::zero(), - Felt252::zero(), - Felt252::one(), - Felt252::zero(), - ], - // col 3 - vec![ - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::one(), - Felt252::one(), - Felt252::zero(), - Felt252::one(), - ], - // col 4 - vec![ - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - ], - // col 5 - vec![ - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - ], - // col 6 - vec![ - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::one(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - ], - // col 7 - vec![ - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::one(), - Felt252::zero(), - Felt252::one(), - ], - // col 8 - vec![ - Felt252::zero(), - Felt252::zero(), - Felt252::one(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - ], - // col 9 - vec![ - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - ], - // col 10 - vec![ - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - ], - // col 11 - vec![ - Felt252::one(), - Felt252::one(), - Felt252::zero(), - Felt252::one(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - ], - // col 12 - vec![ - Felt252::zero(), - Felt252::zero(), - Felt252::one(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - ], - // col 13 - vec![ - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::one(), - Felt252::zero(), - Felt252::one(), - ], - // col 14 - vec![ - Felt252::one(), - Felt252::one(), - Felt252::zero(), - Felt252::one(), - Felt252::zero(), - Felt252::one(), - Felt252::zero(), - ], - // col 15 - vec![ - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - ], - // col 16 - vec![ - Felt252::from(2), - Felt252::from(3), - Felt252::from_hex_unchecked( - "0800000000000010fffffffffffffffffffffffffffffffffffffffffffffffb", - ), - Felt252::from(6), - Felt252::from(9), - Felt252::from(6), - Felt252::from(19), - ], - // col 17 - vec![ - Felt252::from(14), - Felt252::from(15), - Felt252::from(16), - Felt252::from(18), - Felt252::from(19), - Felt252::from(19), - Felt252::from(19), - ], - // col 18 - vec![ - Felt252::from(14), - Felt252::from(14), - Felt252::from(14), - Felt252::from(18), - Felt252::from(18), - Felt252::from(14), - Felt252::from(14), - ], - // col 19 - vec![ - Felt252::from(3), - Felt252::from(5), - Felt252::from(7), - Felt252::from(1), - Felt252::from(2), - Felt252::from(9), - Felt252::from(11), - ], - // col 20 - vec![ - Felt252::from(14), - Felt252::from(15), - Felt252::from(16), - Felt252::from(18), - Felt252::from(16), - Felt252::from(18), - Felt252::from(12), - ], - // col 21 - vec![ - Felt252::from(13), - Felt252::from(13), - Felt252::from(17), - Felt252::from(14), - Felt252::from(17), - Felt252::from(13), - Felt252::from(13), - ], - // col 22 - vec![ - Felt252::from(4), - Felt252::from(6), - Felt252::from(8), - Felt252::from(15), - Felt252::from(17), - Felt252::from(10), - Felt252::from(13), - ], - // col 23 - vec![ - Felt252::from(0x480680017fff8000), - Felt252::from(0x480680017fff8000), - Felt252::from(0x1104800180018000), - Felt252::from(0x484a7ffd7ffc8000), - Felt252::from(0x208b7fff7fff7ffe), - Felt252::from(0x400680017fff7fff), - Felt252::from(0x208b7fff7fff7ffe), - ], - // col 24 - vec![ - Felt252::from(2), - Felt252::from(3), - Felt252::from(14), - Felt252::from(6), - Felt252::from(14), - Felt252::from(6), - Felt252::from(19), - ], - // col 25 - vec![ - Felt252::from(19), - Felt252::from(19), - Felt252::from(9), - Felt252::from(2), - Felt252::from(9), - Felt252::from(19), - Felt252::from(19), - ], - // col 26 - vec![ - Felt252::from(2), - Felt252::from(3), - Felt252::from_hex_unchecked( - "0800000000000010fffffffffffffffffffffffffffffffffffffffffffffffb", - ), - Felt252::from(3), - Felt252::from(9), - Felt252::from(6), - Felt252::from(19), - ], - // col 27 - vec![ - Felt252::from(0x8000), - Felt252::from(0x8000), - Felt252::from(0x8000), - Felt252::from(0x8000), - Felt252::from(0x7ffe), - Felt252::from(0x7fff), - Felt252::from(0x7ffe), - ], - // col 28 - vec![ - Felt252::from(0x7fff), - Felt252::from(0x7fff), - Felt252::from(0x8001), - Felt252::from(0x7ffc), - Felt252::from(0x7fff), - Felt252::from(0x7fff), - Felt252::from(0x7fff), - ], - // col 29 - vec![ - Felt252::from(0x8001), - Felt252::from(0x8001), - Felt252::from(0x8001), - Felt252::from(0x7ffd), - Felt252::from(0x7fff), - Felt252::from(0x8001), - Felt252::from(0x7fff), - ], - // col 30 - vec![ - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - ], - // col 31 - vec![ - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - Felt252::zero(), - ], - // col 32 - vec![ - Felt252::from(38), - Felt252::from(57), - Felt252::from_hex_unchecked( - "0800000000000010ffffffffffffffffffffffffffffffffffffffffffffffcb", - ), - Felt252::from(6), - Felt252::from(81), - Felt252::from(114), - Felt252::from(0x169), - ], - // col 33 - Selector column - vec![ - Felt252::one(), - Felt252::one(), - Felt252::one(), - Felt252::one(), - Felt252::one(), - Felt252::one(), - Felt252::zero(), - ], - ]); - - assert_eq!(execution_trace.cols(), expected_trace.cols()); - } - #[test] fn test_fill_range_check_values() { let columns = vec![ @@ -1219,39 +670,38 @@ mod test { } #[test] - fn test_add_missing_values_to_offsets_column() { - let mut main_trace = TraceTable:: { - table: (0..34 * 2).map(FieldElement::from).collect(), - n_cols: 34, - }; - let missing_values = vec![ - FieldElement::from(1), - FieldElement::from(2), - FieldElement::from(3), - FieldElement::from(4), - FieldElement::from(5), - FieldElement::from(6), + fn test_add_missing_values_to_rc_holes_column() { + let mut row = vec![Felt252::from(5); 36]; + row[35] = Felt252::zero(); + let table = row.repeat(8); + + let mut main_trace = TraceTable:: { table, n_cols: 36 }; + + let rc_holes = vec![ + Felt252::from(1), + Felt252::from(2), + Felt252::from(3), + Felt252::from(4), + Felt252::from(5), + Felt252::from(6), ]; - fill_rc_holes(&mut main_trace, missing_values); - let mut expected: Vec<_> = (0..34 * 2).map(FieldElement::from).collect(); - expected.append(&mut vec![FieldElement::zero(); OFF_DST]); - expected.append(&mut vec![ - FieldElement::from(1), - FieldElement::from(2), - FieldElement::from(3), - ]); - expected.append(&mut vec![FieldElement::zero(); 34 - OFF_OP1 - 1]); - expected.append(&mut vec![FieldElement::zero(); OFF_DST]); - expected.append(&mut vec![ - FieldElement::from(4), - FieldElement::from(5), - FieldElement::from(6), - ]); - expected.append(&mut vec![FieldElement::zero(); 34 - OFF_OP1 - 1]); - assert_eq!(main_trace.table, expected); - assert_eq!(main_trace.n_cols, 34); - assert_eq!(main_trace.table.len(), 34 * 4); + fill_rc_holes(&mut main_trace, &rc_holes); + + let expected_rc_holes_column = vec![ + Felt252::from(1), + Felt252::from(2), + Felt252::from(3), + Felt252::from(4), + Felt252::from(5), + Felt252::from(6), + Felt252::from(6), + Felt252::from(6), + ]; + + let rc_holes_column = main_trace.cols()[35].clone(); + + assert_eq!(expected_rc_holes_column, rc_holes_column); } #[test] @@ -1315,7 +765,7 @@ mod test { #[test] fn test_fill_memory_holes() { const TRACE_COL_LEN: usize = 2; - const NUM_TRACE_COLS: usize = FRAME_SELECTOR + 1; + const NUM_TRACE_COLS: usize = EXTRA_VAL + 1; let mut trace_cols = vec![vec![Felt252::zero(); TRACE_COL_LEN]; NUM_TRACE_COLS]; trace_cols[FRAME_PC][0] = Felt252::one(); @@ -1331,17 +781,7 @@ mod test { let memory_holes = vec![Felt252::from(4), Felt252::from(7), Felt252::from(8)]; fill_memory_holes(&mut trace, &memory_holes); - let frame_pc = &trace.cols()[FRAME_PC]; - let dst_addr = &trace.cols()[FRAME_DST_ADDR]; - let op0_addr = &trace.cols()[FRAME_OP0_ADDR]; - let op1_addr = &trace.cols()[FRAME_OP1_ADDR]; - assert_eq!(frame_pc[0], Felt252::one()); - assert_eq!(dst_addr[0], Felt252::from(2)); - assert_eq!(op0_addr[0], Felt252::from(3)); - assert_eq!(op1_addr[0], Felt252::from(5)); - assert_eq!(frame_pc[1], Felt252::from(6)); - assert_eq!(dst_addr[1], Felt252::from(9)); - assert_eq!(op0_addr[1], Felt252::from(10)); - assert_eq!(op1_addr[1], Felt252::from(11)); + let extra_addr = &trace.cols()[EXTRA_ADDR]; + assert_eq!(extra_addr, &memory_holes) } } diff --git a/cairo_prover/src/main.rs b/cairo_prover/src/main.rs index 843f74a0..1bd5b8bc 100644 --- a/cairo_prover/src/main.rs +++ b/cairo_prover/src/main.rs @@ -1,5 +1,6 @@ use cairo_platinum_prover::air::{generate_cairo_proof, verify_cairo_proof, PublicInputs}; -use cairo_platinum_prover::runner::run::{generate_prover_args, CairoVersion}; +use cairo_platinum_prover::cairo_layout::CairoLayout; +use cairo_platinum_prover::runner::run::generate_prover_args; use lambdaworks_math::field::fields::fft_friendly::stark_252_prime_field::Stark252PrimeField; use lambdaworks_math::traits::{Deserializable, Serializable}; use stark_platinum_prover::proof::options::{ProofOptions, SecurityLevel}; @@ -14,22 +15,15 @@ fn generate_proof( ) -> Option<(StarkProof, PublicInputs)> { let timer = Instant::now(); - let cairo_version = if input_path.contains(".casm") { - println!("Running casm on CairoVM and generating trace ..."); - CairoVersion::V1 - } else { - println!("Running program on CairoVM and generating trace ..."); - CairoVersion::V0 - }; - let Ok(program_content) = std::fs::read(input_path) else { println!("Error opening {input_path} file"); return None; }; - let Ok((main_trace, pub_inputs)) = - generate_prover_args(&program_content, &cairo_version, &None) - else { + // FIXME: We should set this through the CLI in the future + let layout = CairoLayout::Plain; + + let Ok((main_trace, pub_inputs)) = generate_prover_args(&program_content, &None, layout) else { println!("Error generating prover args"); return None; }; diff --git a/cairo_prover/src/runner/program.json b/cairo_prover/src/runner/program.json deleted file mode 100644 index 58682657..00000000 --- a/cairo_prover/src/runner/program.json +++ /dev/null @@ -1,200 +0,0 @@ -{ - "attributes": [], - "builtins": [], - "compiler_version": "0.10.3", - "data": [ - "0x480680017fff8000", - "0x3", - "0x400680017fff7fff", - "0x3", - "0x208b7fff7fff7ffe" - ], - "debug_info": { - "file_contents": {}, - "instruction_locations": { - "0": { - "accessible_scopes": [ - "__main__", - "__main__.main" - ], - "flow_tracking_data": { - "ap_tracking": { - "group": 0, - "offset": 0 - }, - "reference_ids": { - "__main__.main.x": 0, - "__main__.main.y": 1 - } - }, - "hints": [], - "inst": { - "end_col": 18, - "end_line": 4, - "input_file": { - "filename": "simple_program.cairo" - }, - "start_col": 17, - "start_line": 4 - } - }, - "2": { - "accessible_scopes": [ - "__main__", - "__main__.main" - ], - "flow_tracking_data": { - "ap_tracking": { - "group": 0, - "offset": 1 - }, - "reference_ids": { - "__main__.main.__temp0": 2, - "__main__.main.x": 0, - "__main__.main.y": 1 - } - }, - "hints": [], - "inst": { - "end_col": 19, - "end_line": 4, - "input_file": { - "filename": "simple_program.cairo" - }, - "start_col": 2, - "start_line": 4 - } - }, - "4": { - "accessible_scopes": [ - "__main__", - "__main__.main" - ], - "flow_tracking_data": { - "ap_tracking": { - "group": 0, - "offset": 1 - }, - "reference_ids": { - "__main__.main.__temp0": 2, - "__main__.main.x": 0, - "__main__.main.y": 1 - } - }, - "hints": [], - "inst": { - "end_col": 12, - "end_line": 5, - "input_file": { - "filename": "simple_program.cairo" - }, - "start_col": 2, - "start_line": 5 - } - } - } - }, - "hints": {}, - "identifiers": { - "__main__.main": { - "decorators": [], - "pc": 0, - "type": "function" - }, - "__main__.main.Args": { - "full_name": "__main__.main.Args", - "members": {}, - "size": 0, - "type": "struct" - }, - "__main__.main.ImplicitArgs": { - "full_name": "__main__.main.ImplicitArgs", - "members": {}, - "size": 0, - "type": "struct" - }, - "__main__.main.Return": { - "cairo_type": "()", - "type": "type_definition" - }, - "__main__.main.SIZEOF_LOCALS": { - "type": "const", - "value": 0 - }, - "__main__.main.__temp0": { - "cairo_type": "felt", - "full_name": "__main__.main.__temp0", - "references": [ - { - "ap_tracking_data": { - "group": 0, - "offset": 1 - }, - "pc": 2, - "value": "[cast(ap + (-1), felt*)]" - } - ], - "type": "reference" - }, - "__main__.main.x": { - "cairo_type": "felt", - "full_name": "__main__.main.x", - "references": [ - { - "ap_tracking_data": { - "group": 0, - "offset": 0 - }, - "pc": 0, - "value": "cast(1, felt)" - } - ], - "type": "reference" - }, - "__main__.main.y": { - "cairo_type": "felt", - "full_name": "__main__.main.y", - "references": [ - { - "ap_tracking_data": { - "group": 0, - "offset": 0 - }, - "pc": 0, - "value": "cast(2, felt)" - } - ], - "type": "reference" - } - }, - "main_scope": "__main__", - "prime": "0x800000000000011000000000000000000000000000000000000000000000001", - "reference_manager": { - "references": [ - { - "ap_tracking_data": { - "group": 0, - "offset": 0 - }, - "pc": 0, - "value": "cast(1, felt)" - }, - { - "ap_tracking_data": { - "group": 0, - "offset": 0 - }, - "pc": 0, - "value": "cast(2, felt)" - }, - { - "ap_tracking_data": { - "group": 0, - "offset": 1 - }, - "pc": 2, - "value": "[cast(ap + (-1), felt*)]" - } - ] - } -} diff --git a/cairo_prover/src/runner/run.rs b/cairo_prover/src/runner/run.rs index 8c8f2e02..08d0a667 100644 --- a/cairo_prover/src/runner/run.rs +++ b/cairo_prover/src/runner/run.rs @@ -5,18 +5,14 @@ use crate::execution_trace::build_main_trace; use crate::register_states::RegisterStates; use super::vec_writer::VecWriter; -use cairo_lang_starknet::casm_contract_class::CasmContractClass; use cairo_vm::cairo_run::{self, EncodeTraceError}; -use cairo_vm::felt::Felt252; + use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; -use cairo_vm::hint_processor::cairo_1_hint_processor::hint_processor::Cairo1HintProcessor; -use cairo_vm::serde::deserialize_program::BuiltinName; -use cairo_vm::types::{program::Program, relocatable::MaybeRelocatable}; + use cairo_vm::vm::errors::{ cairo_run_errors::CairoRunError, trace_errors::TraceError, vm_errors::VirtualMachineError, }; -use cairo_vm::vm::runners::cairo_runner::{CairoArg, CairoRunner, RunResources}; -use cairo_vm::vm::vm_core::VirtualMachine; + use lambdaworks_math::field::fields::fft_friendly::stark_252_prime_field::Stark252PrimeField; use stark_platinum_prover::trace::TraceTable; use std::ops::Range; @@ -60,13 +56,6 @@ impl From for Error { } } -/// Indicates the version of the Cairo program. -/// This is used to determine how to parse and run the program. -pub enum CairoVersion { - V0 = 0, - V1 = 1, -} - /// Runs a cairo program in JSON format and returns trace, memory and program length. /// Uses [cairo-rs](https://github.com/lambdaclass/cairo-rs/) project to run the program. /// @@ -91,132 +80,30 @@ pub fn run_program( entrypoint_function: Option<&str>, layout: CairoLayout, program_content: &[u8], - cairo_version: &CairoVersion, ) -> Result<(RegisterStates, CairoMemory, usize, Option>), Error> { // default value for entrypoint is "main" let entrypoint = entrypoint_function.unwrap_or("main"); - let (vm, runner) = match cairo_version { - CairoVersion::V0 => { - let trace_enabled = true; - let mut hint_executor = BuiltinHintProcessor::new_empty(); - let cairo_run_config = cairo_run::CairoRunConfig { - entrypoint, - trace_enabled, - relocate_mem: true, - layout: layout.as_str(), - proof_mode: false, - secure_run: None, - }; - - let (runner, vm) = match cairo_run::cairo_run( - program_content, - &cairo_run_config, - &mut hint_executor, - ) { - Ok(runner) => runner, - Err(error) => { - eprintln!("{error}"); - panic!(); - } - }; - - (vm, runner) - } - CairoVersion::V1 => { - let args = []; - - let casm_contract: CasmContractClass = serde_json::from_slice(program_content).unwrap(); - - let program: Program = casm_contract.clone().try_into().unwrap(); - - let mut runner = CairoRunner::new(&(program), layout.as_str(), false).unwrap(); - let mut vm = VirtualMachine::new(true); - - runner - .initialize_function_runner_cairo_1(&mut vm, &[BuiltinName::range_check]) - .unwrap(); - - // Implicit Args - let syscall_segment = MaybeRelocatable::from(vm.add_memory_segment()); - - let builtins: Vec<&'static str> = runner - .get_program_builtins() - .iter() - .map(|b| b.name()) - .collect(); - - let builtin_segment: Vec = vm - .get_builtin_runners() - .iter() - .filter(|b| builtins.contains(&b.name())) - .flat_map(|b| b.initial_stack()) - .collect(); - - let initial_gas = MaybeRelocatable::from(usize::MAX); - - let mut implicit_args = builtin_segment; - implicit_args.extend([initial_gas]); - implicit_args.extend([syscall_segment]); - - // Other args - - // Load builtin costs - let builtin_costs: Vec = - vec![0.into(), 0.into(), 0.into(), 0.into(), 0.into()]; - let builtin_costs_ptr = vm.add_memory_segment(); - vm.load_data(builtin_costs_ptr, &builtin_costs).unwrap(); - - // Load extra data - let core_program_end_ptr = (runner.program_base.unwrap() + program.data_len()).unwrap(); - - let extra_data_i128 = i128::from_str_radix("208B7FFF7FFF7FFE", 16).unwrap(); - let extra_data = Felt252::from(extra_data_i128); - let program_extra_data: Vec = - vec![extra_data.into(), builtin_costs_ptr.into()]; - vm.load_data(core_program_end_ptr, &program_extra_data) - .unwrap(); - - // Load calldata - let calldata_start = vm.add_memory_segment(); - let calldata_end = vm.load_data(calldata_start, &args.to_vec()).unwrap(); - - // Create entrypoint_args - - let mut entrypoint_args: Vec = implicit_args - .iter() - .map(|m| CairoArg::from(m.clone())) - .collect(); - entrypoint_args.extend([ - MaybeRelocatable::from(calldata_start).into(), - MaybeRelocatable::from(calldata_end).into(), - ]); - let entrypoint_args: Vec<&CairoArg> = entrypoint_args.iter().collect(); - - let mut hint_processor = - Cairo1HintProcessor::new(casm_contract.hints.as_slice(), RunResources::default()); - - // Run contract entrypoint - // We assume entrypoint 0 for only one function - let _run_resources = RunResources::default(); - - runner - .run_from_entrypoint( - 0, - &entrypoint_args, - true, - Some(program.data_len() + program_extra_data.len()), - &mut vm, - &mut hint_processor, - ) - .unwrap(); - - let _ = runner.relocate(&mut vm, true); - - (vm, runner) - } + let trace_enabled = true; + let mut hint_executor = BuiltinHintProcessor::new_empty(); + let cairo_run_config = cairo_run::CairoRunConfig { + entrypoint, + trace_enabled, + relocate_mem: true, + layout: layout.as_str(), + proof_mode: true, + secure_run: None, }; + let (runner, vm) = + match cairo_run::cairo_run(program_content, &cairo_run_config, &mut hint_executor) { + Ok(runner) => runner, + Err(error) => { + eprintln!("{error}"); + panic!(); + } + }; + let relocated_trace = vm.get_relocated_trace().unwrap(); let mut trace_vec = Vec::::new(); @@ -238,19 +125,27 @@ pub fn run_program( let data_len = runner.get_program().data_len(); + let range_check_builtin_included = runner + .get_program() + .iter_builtins() + .any(|builtin| builtin.name() == "range_check_builtin"); + // get range start and end - let range_check = vm - .get_range_check_builtin() - .map(|builtin| { - let (idx, stop_offset) = builtin.get_memory_segment_addresses(); - let stop_offset = stop_offset.unwrap_or_default(); - let range_check_base = - (0..idx).fold(1, |acc, i| acc + vm.get_segment_size(i).unwrap_or_default()); - let range_check_end = range_check_base + stop_offset; - - (range_check_base, range_check_end) - }) - .ok(); + let range_check = if range_check_builtin_included { + vm.get_range_check_builtin() + .map(|builtin| { + let (idx, stop_offset) = builtin.get_memory_segment_addresses(); + let stop_offset = stop_offset.unwrap_or_default(); + let range_check_base = + (0..idx).fold(1, |acc, i| acc + vm.get_segment_size(i).unwrap_or_default()); + let range_check_end = range_check_base + stop_offset; + + (range_check_base, range_check_end) + }) + .ok() + } else { + None + }; let range_check_builtin_range = range_check.map(|(start, end)| Range { start: start as u64, @@ -267,16 +162,11 @@ pub fn run_program( pub fn generate_prover_args( program_content: &[u8], - cairo_version: &CairoVersion, output_range: &Option>, + layout: CairoLayout, ) -> Result<(TraceTable, PublicInputs), Error> { - let cairo_layout = match cairo_version { - CairoVersion::V0 => CairoLayout::Small, - CairoVersion::V1 => CairoLayout::Plain, - }; - let (register_states, memory, program_size, range_check_builtin_range) = - run_program(None, cairo_layout, program_content, cairo_version)?; + run_program(None, layout, program_content)?; let memory_segments = create_memory_segment_map(range_check_builtin_range, output_range); @@ -303,120 +193,3 @@ fn create_memory_segment_map( memory_segments } - -#[cfg(test)] -mod tests { - use crate::execution_trace::build_cairo_execution_trace; - - use super::*; - use lambdaworks_math::field::fields::fft_friendly::stark_252_prime_field::MontgomeryConfigStark252PrimeField; - use lambdaworks_math::field::{ - element::FieldElement, fields::montgomery_backed_prime_fields::U256PrimeField, - }; - - pub type Stark252PrimeField = U256PrimeField; - type FE = FieldElement; - - #[test] - fn test_parse_cairo_file() { - let base_dir = env!("CARGO_MANIFEST_DIR"); - let json_filename = base_dir.to_owned() + "/src/runner/program.json"; - - let program_content = std::fs::read(json_filename).unwrap(); - - let (register_states, memory, program_size, _rg_in_out) = run_program( - None, - CairoLayout::AllCairo, - &program_content, - &CairoVersion::V0, - ) - .unwrap(); - - let pub_inputs = PublicInputs::from_regs_and_mem( - ®ister_states, - &memory, - program_size, - &MemorySegmentMap::new(), - ); - - let execution_trace = build_cairo_execution_trace(®ister_states, &memory, &pub_inputs); - - // This trace is obtained from Giza when running the prover for the mentioned program. - let expected_trace = TraceTable::new_from_cols(&[ - // col 0 - vec![FE::zero(), FE::zero(), FE::one()], - // col 1 - vec![FE::one(), FE::one(), FE::one()], - // col 2 - vec![FE::one(), FE::one(), FE::zero()], - // col 3 - vec![FE::zero(), FE::zero(), FE::one()], - // col 4 - vec![FE::zero(), FE::zero(), FE::zero()], - // col 5 - vec![FE::zero(), FE::zero(), FE::zero()], - // col 6 - vec![FE::zero(), FE::zero(), FE::zero()], - // col 7 - vec![FE::zero(), FE::zero(), FE::one()], - // col 8 - vec![FE::zero(), FE::zero(), FE::zero()], - // col 9 - vec![FE::zero(), FE::zero(), FE::zero()], - // col 10 - vec![FE::zero(), FE::zero(), FE::zero()], - // col 11 - vec![FE::one(), FE::zero(), FE::zero()], - // col 12 - vec![FE::zero(), FE::zero(), FE::zero()], - // col 13 - vec![FE::zero(), FE::zero(), FE::one()], - // col 14 - vec![FE::one(), FE::one(), FE::zero()], - // col 15 - vec![FE::zero(), FE::zero(), FE::zero()], - // col 16 - vec![FE::from(3), FE::from(3), FE::from(9)], - // col 17 - vec![FE::from(8), FE::from(9), FE::from(9)], - // col 18 - vec![FE::from(8), FE::from(8), FE::from(8)], - // col 19 - vec![FE::from(1), FE::from(3), FE::from(5)], - // col 20 - vec![FE::from(8), FE::from(8), FE::from(6)], - // col 21 - vec![FE::from(7), FE::from(7), FE::from(7)], - // col 22 - vec![FE::from(2), FE::from(4), FE::from(7)], - // col 23 - vec![ - FE::from(0x480680017fff8000), - FE::from(0x400680017fff7fff), - FE::from(0x208b7fff7fff7ffe), - ], - // col 24 - vec![FE::from(3), FE::from(3), FE::from(9)], - // col 25 - vec![FE::from(9), FE::from(9), FE::from(9)], - // col 26 - vec![FE::from(3), FE::from(3), FE::from(9)], - // col 27 - vec![FE::from(0x8000), FE::from(0x7fff), FE::from(0x7ffe)], - // col 28 - vec![FE::from(0x7fff), FE::from(0x7fff), FE::from(0x7fff)], - // col 29 - vec![FE::from(0x8001), FE::from(0x8001), FE::from(0x7fff)], - // col 30 - vec![FE::zero(), FE::zero(), FE::zero()], - // col 31 - vec![FE::zero(), FE::zero(), FE::zero()], - // col 32 - vec![FE::from(0x1b), FE::from(0x1b), FE::from(0x51)], - // col 33 - Selector column - vec![FE::one(), FE::one(), FE::zero()], - ]); - - assert_eq!(execution_trace.cols(), expected_trace.cols()); - } -} diff --git a/cairo_prover/src/tests/integration_tests.rs b/cairo_prover/src/tests/integration_tests.rs index 54f99518..e9626025 100644 --- a/cairo_prover/src/tests/integration_tests.rs +++ b/cairo_prover/src/tests/integration_tests.rs @@ -1,70 +1,95 @@ +use lambdaworks_crypto::fiat_shamir::default_transcript::DefaultTranscript; +use lambdaworks_math::{ + errors::DeserializationError, + field::fields::fft_friendly::stark_252_prime_field::Stark252PrimeField, + traits::{Deserializable, Serializable}, +}; use stark_platinum_prover::{ - proof::options::{ProofOptions, SecurityLevel}, + debug::validate_trace, + domain::Domain, + proof::{ + options::{ProofOptions, SecurityLevel}, + stark::StarkProof, + }, trace::TraceTable, + traits::AIR, }; use crate::{ air::{ - generate_cairo_proof, verify_cairo_proof, MemorySegment, MemorySegmentMap, PublicInputs, - FRAME_DST_ADDR, FRAME_OP0_ADDR, FRAME_OP1_ADDR, FRAME_PC, + generate_cairo_proof, verify_cairo_proof, CairoAIR, MemorySegment, MemorySegmentMap, + PublicInputs, FRAME_DST_ADDR, FRAME_OP0_ADDR, FRAME_OP1_ADDR, FRAME_PC, }, cairo_layout::CairoLayout, execution_trace::build_main_trace, - runner::run::{generate_prover_args, run_program, CairoVersion}, - tests::utils::{ - cairo0_program_path, cairo1_program_path, test_prove_cairo1_program, - test_prove_cairo_program, - }, + runner::run::{generate_prover_args, run_program}, + tests::utils::{cairo0_program_path, test_prove_cairo_program}, Felt252, }; #[test_log::test] fn test_prove_cairo_simple_program() { - test_prove_cairo_program(&cairo0_program_path("simple_program.json"), &None); + let layout = CairoLayout::Plain; + test_prove_cairo_program(&cairo0_program_path("simple_program.json"), &None, layout); } #[test_log::test] fn test_prove_cairo_fibonacci_5() { - test_prove_cairo_program(&cairo0_program_path("fibonacci_5.json"), &None); + let layout = CairoLayout::Plain; + test_prove_cairo_program(&cairo0_program_path("fibonacci_5.json"), &None, layout); } #[test_log::test] fn test_prove_cairo_fibonacci_1000() { - test_prove_cairo_program(&cairo0_program_path("fibonacci_1000.json"), &None); + let layout = CairoLayout::Plain; + test_prove_cairo_program(&cairo0_program_path("fibonacci_1000.json"), &None, layout); } -#[cfg_attr(feature = "metal", ignore)] -#[test_log::test] -fn test_prove_cairo_fibonacci_casm() { - test_prove_cairo1_program(&cairo1_program_path("fibonacci_cairo1.casm")); -} +// #[cfg_attr(feature = "metal", ignore)] +// #[test_log::test] +// fn test_prove_cairo_fibonacci_casm() { +// let layout = CairoLayout::Plain; +// test_prove_cairo1_program(&cairo1_program_path("fibonacci_cairo1_mod.casm"), layout); +// } #[test_log::test] fn test_prove_cairo_rc_program() { - test_prove_cairo_program(&cairo0_program_path("rc_program.json"), &None); + let layout = CairoLayout::Small; + test_prove_cairo_program(&cairo0_program_path("rc_program.json"), &None, layout); } #[test_log::test] fn test_prove_cairo_lt_comparison() { - test_prove_cairo_program(&cairo0_program_path("lt_comparison.json"), &None); + let layout = CairoLayout::Small; + test_prove_cairo_program(&cairo0_program_path("lt_comparison.json"), &None, layout); } #[cfg_attr(feature = "metal", ignore)] #[test_log::test] fn test_prove_cairo_compare_lesser_array() { - test_prove_cairo_program(&cairo0_program_path("compare_lesser_array.json"), &None); + let layout = CairoLayout::Small; + test_prove_cairo_program( + &cairo0_program_path("compare_lesser_array.json"), + &None, + layout, + ); } #[test_log::test] fn test_prove_cairo_output_and_rc_program() { - test_prove_cairo_program(&cairo0_program_path("signed_div_rem.json"), &Some(289..293)); + let layout = CairoLayout::Small; + test_prove_cairo_program( + &cairo0_program_path("signed_div_rem.json"), + &Some(1837..1853), + layout, + ); } #[test_log::test] fn test_verifier_rejects_proof_of_a_slightly_different_program() { let program_content = std::fs::read(cairo0_program_path("simple_program.json")).unwrap(); let (main_trace, mut pub_input) = - generate_prover_args(&program_content, &CairoVersion::V0, &None).unwrap(); + generate_prover_args(&program_content, &None, CairoLayout::Plain).unwrap(); let proof_options = ProofOptions::default_test_options(); @@ -84,7 +109,7 @@ fn test_verifier_rejects_proof_of_a_slightly_different_program() { fn test_verifier_rejects_proof_with_different_range_bounds() { let program_content = std::fs::read(cairo0_program_path("simple_program.json")).unwrap(); let (main_trace, mut pub_inputs) = - generate_prover_args(&program_content, &CairoVersion::V0, &None).unwrap(); + generate_prover_args(&program_content, &None, CairoLayout::Plain).unwrap(); let proof_options = ProofOptions::default_test_options(); let proof = generate_cairo_proof(&main_trace, &pub_inputs, &proof_options).unwrap(); @@ -104,7 +129,7 @@ fn test_verifier_rejects_proof_with_changed_range_check_value() { // range-checked value won't hold, and the verifier will reject the proof. let program_content = std::fs::read(cairo0_program_path("rc_program.json")).unwrap(); let (main_trace, pub_inputs) = - generate_prover_args(&program_content, &CairoVersion::V0, &None).unwrap(); + generate_prover_args(&program_content, &None, CairoLayout::Small).unwrap(); // The malicious value, we change the previous value to a 35. let malicious_rc_value = Felt252::from(35); @@ -129,13 +154,8 @@ fn test_verifier_rejects_proof_with_overflowing_range_check_value() { // This value is greater than 2^128, and the verifier should reject the proof built with it. let overflowing_rc_value = Felt252::from_hex("0x100000000000000000000000000000001").unwrap(); let program_content = std::fs::read(cairo0_program_path("rc_program.json")).unwrap(); - let (register_states, mut malicious_memory, program_size, _) = run_program( - None, - CairoLayout::Small, - &program_content, - &CairoVersion::V0, - ) - .unwrap(); + let (register_states, mut malicious_memory, program_size, _) = + run_program(None, CairoLayout::Small, &program_content).unwrap(); // The malicious value is inserted in memory here. malicious_memory.data.insert(27, overflowing_rc_value); @@ -162,7 +182,7 @@ fn test_verifier_rejects_proof_with_overflowing_range_check_value() { fn test_verifier_rejects_proof_with_changed_output() { let program_content = std::fs::read(cairo0_program_path("output_program.json")).unwrap(); let (main_trace, pub_inputs) = - generate_prover_args(&program_content, &CairoVersion::V0, &None).unwrap(); + generate_prover_args(&program_content, &Some(27..28), CairoLayout::Small).unwrap(); // The malicious value, we change the previous value to a 100. let malicious_output_value = Felt252::from(100); @@ -179,15 +199,16 @@ fn test_verifier_rejects_proof_with_changed_output() { break; } } + let output_col_idx = *output_col_idx.unwrap(); let output_row_idx = output_row_idx.unwrap(); let proof_options = ProofOptions::default_test_options(); let mut malicious_trace_columns = main_trace.cols(); - let mut output_column = malicious_trace_columns[output_col_idx].clone(); - output_column[output_row_idx] = malicious_output_value; - malicious_trace_columns[output_col_idx] = output_column; + let mut output_value_column = malicious_trace_columns[output_col_idx + 4].clone(); + output_value_column[output_row_idx] = malicious_output_value; + malicious_trace_columns[output_col_idx + 4] = output_value_column; let malicious_trace = TraceTable::new_from_cols(&malicious_trace_columns); let proof = generate_cairo_proof(&malicious_trace, &pub_inputs, &proof_options).unwrap(); @@ -198,7 +219,7 @@ fn test_verifier_rejects_proof_with_changed_output() { fn test_verifier_rejects_proof_with_different_security_params() { let program_content = std::fs::read(cairo0_program_path("output_program.json")).unwrap(); let (main_trace, pub_inputs) = - generate_prover_args(&program_content, &CairoVersion::V0, &None).unwrap(); + generate_prover_args(&program_content, &None, CairoLayout::Small).unwrap(); let proof_options_prover = ProofOptions::new_secure(SecurityLevel::Conjecturable80Bits, 3); @@ -212,3 +233,85 @@ fn test_verifier_rejects_proof_with_different_security_params() { &proof_options_verifier )); } + +#[test] +fn check_simple_cairo_trace_evaluates_to_zero() { + let program_content = std::fs::read(cairo0_program_path("simple_program.json")).unwrap(); + let (main_trace, public_input) = + generate_prover_args(&program_content, &None, CairoLayout::Plain).unwrap(); + let mut trace_polys = main_trace.compute_trace_polys(); + let mut transcript = DefaultTranscript::new(); + + let proof_options = ProofOptions::default_test_options(); + let cairo_air = CairoAIR::new(main_trace.n_rows(), &public_input, &proof_options); + let rap_challenges = cairo_air.build_rap_challenges(&mut transcript); + + let aux_trace = cairo_air.build_auxiliary_trace(&main_trace, &rap_challenges); + let aux_polys = aux_trace.compute_trace_polys(); + + trace_polys.extend_from_slice(&aux_polys); + + let domain = Domain::new(&cairo_air); + + assert!(validate_trace( + &cairo_air, + &trace_polys, + &domain, + &rap_challenges + )); +} + +#[test] +fn deserialize_and_verify() { + let program_content = std::fs::read(cairo0_program_path("fibonacci_10.json")).unwrap(); + let (main_trace, pub_inputs) = + generate_prover_args(&program_content, &None, CairoLayout::Plain).unwrap(); + + let proof_options = ProofOptions::default_test_options(); + + // The proof is generated and serialized. + let proof = generate_cairo_proof(&main_trace, &pub_inputs, &proof_options).unwrap(); + let proof_bytes = proof.serialize(); + + // The trace and original proof are dropped to show that they are decoupled from + // the verifying process. + drop(main_trace); + drop(proof); + + // At this point, the verifier only knows about the serialized proof, the proof options + // and the public inputs. + let proof = StarkProof::::deserialize(&proof_bytes).unwrap(); + + // The proof is verified successfully. + assert!(verify_cairo_proof(&proof, &pub_inputs, &proof_options)); +} + +#[test] +fn deserialize_should_not_panic_with_changed_and_sliced_bytes() { + let program_content = std::fs::read(cairo0_program_path("fibonacci_10.json")).unwrap(); + let (main_trace, pub_inputs) = + generate_prover_args(&program_content, &None, CairoLayout::Plain).unwrap(); + + let proof_options = ProofOptions::default_test_options(); + + // The proof is generated and serialized. + let proof = generate_cairo_proof(&main_trace, &pub_inputs, &proof_options).unwrap(); + let mut proof_bytes = proof.serialize(); + + // The trace and original proof are dropped to show that they are decoupled from + // the verifying process. + drop(main_trace); + drop(proof); + + for byte in proof_bytes.iter_mut().take(21664) { + *byte = 255; + } + proof_bytes = proof_bytes[0..517].to_vec(); + + assert_eq!( + DeserializationError::InvalidAmountOfBytes, + StarkProof::::deserialize(&proof_bytes) + .err() + .unwrap() + ); +} diff --git a/cairo_prover/src/tests/utils.rs b/cairo_prover/src/tests/utils.rs index ac752882..5e51fd8e 100644 --- a/cairo_prover/src/tests/utils.rs +++ b/cairo_prover/src/tests/utils.rs @@ -4,7 +4,8 @@ use stark_platinum_prover::proof::options::ProofOptions; use crate::{ air::{generate_cairo_proof, verify_cairo_proof}, - runner::run::{generate_prover_args, CairoVersion}, + cairo_layout::CairoLayout, + runner::run::generate_prover_args, }; pub fn cairo0_program_path(program_name: &str) -> String { @@ -22,23 +23,16 @@ pub fn cairo1_program_path(program_name: &str) -> String { } /// Loads the program in path, runs it with the Cairo VM, and makes a proof of it -pub fn test_prove_cairo_program(file_path: &str, output_range: &Option>) { +pub fn test_prove_cairo_program( + file_path: &str, + output_range: &Option>, + layout: CairoLayout, +) { let proof_options = ProofOptions::default_test_options(); let program_content = std::fs::read(file_path).unwrap(); let (main_trace, pub_inputs) = - generate_prover_args(&program_content, &CairoVersion::V0, output_range).unwrap(); - let proof = generate_cairo_proof(&main_trace, &pub_inputs, &proof_options).unwrap(); - - assert!(verify_cairo_proof(&proof, &pub_inputs, &proof_options)); -} - -/// Loads the program in path, runs it with the Cairo VM, and makes a proof of it -pub fn test_prove_cairo1_program(file_path: &str) { - let proof_options = ProofOptions::default_test_options(); - let program_content = std::fs::read(file_path).unwrap(); - let (main_trace, pub_inputs) = - generate_prover_args(&program_content, &CairoVersion::V1, &None).unwrap(); + generate_prover_args(&program_content, output_range, layout).unwrap(); let proof = generate_cairo_proof(&main_trace, &pub_inputs, &proof_options).unwrap(); assert!(verify_cairo_proof(&proof, &pub_inputs, &proof_options)); diff --git a/cairo_prover/tests/wasm.rs b/cairo_prover/tests/wasm.rs new file mode 100644 index 00000000..04223cdb --- /dev/null +++ b/cairo_prover/tests/wasm.rs @@ -0,0 +1,1942 @@ +#[cfg(feature = "wasm")] +use cairo_platinum_prover::wasm_wrappers::deserialize_proof_wasm; +#[cfg(feature = "wasm")] +use cairo_platinum_prover::wasm_wrappers::verify_cairo_proof_wasm; +#[cfg(feature = "wasm")] +use stark_platinum_prover::proof::options::ProofOptions; + +#[cfg(feature = "wasm")] +use wasm_bindgen_test::*; + +#[cfg(feature = "wasm")] +#[wasm_bindgen_test] +#[test] +fn test_prove_cairo1_program_wasm() { + let proof = deserialize_proof_wasm(&SERIALIZED_TEST_PROOF); + let proof_options = ProofOptions::default_test_options(); + assert!(verify_cairo_proof_wasm( + &proof, + &PUBLIC_INPUTS, + &proof_options + )); +} + +#[cfg(feature = "wasm")] +static SERIALIZED_TEST_PROOF: [u8; 40754] = [ + 171, 108, 116, 114, 97, 99, 101, 95, 108, 101, 110, 103, 116, 104, 24, 64, 118, 108, 100, 101, + 95, 116, 114, 97, 99, 101, 95, 109, 101, 114, 107, 108, 101, 95, 114, 111, 111, 116, 115, 130, + 152, 32, 24, 32, 24, 92, 24, 179, 24, 240, 24, 173, 24, 184, 24, 181, 24, 44, 24, 42, 24, 237, + 24, 65, 24, 225, 24, 111, 24, 195, 24, 165, 24, 152, 24, 171, 24, 175, 24, 33, 24, 251, 24, + 111, 24, 204, 24, 120, 24, 222, 24, 112, 24, 158, 24, 125, 24, 204, 24, 58, 24, 239, 24, 161, + 24, 127, 152, 32, 24, 246, 24, 112, 24, 157, 24, 109, 24, 119, 24, 45, 24, 69, 24, 104, 15, 24, + 213, 24, 173, 24, 50, 24, 242, 24, 245, 24, 210, 8, 24, 87, 24, 220, 24, 30, 24, 52, 24, 105, + 24, 75, 24, 47, 24, 169, 24, 170, 24, 143, 24, 113, 24, 120, 24, 70, 24, 65, 24, 118, 24, 230, + 120, 27, 116, 114, 97, 99, 101, 95, 111, 111, 100, 95, 102, 114, 97, 109, 101, 95, 101, 118, + 97, 108, 117, 97, 116, 105, 111, 110, 115, 162, 100, 100, 97, 116, 97, 152, 104, 161, 101, 118, + 97, 108, 117, 101, 120, 65, 48, 120, 52, 57, 101, 52, 55, 99, 55, 101, 100, 56, 57, 51, 55, + 102, 48, 48, 55, 50, 48, 56, 99, 50, 50, 53, 54, 101, 48, 55, 97, 55, 99, 57, 49, 102, 48, 51, + 54, 55, 50, 98, 55, 57, 101, 57, 53, 57, 57, 98, 102, 50, 56, 55, 48, 99, 97, 97, 48, 53, 102, + 102, 57, 100, 97, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 55, 97, 100, 97, 101, 49, + 53, 101, 98, 51, 49, 51, 97, 98, 56, 52, 56, 56, 52, 48, 55, 52, 100, 48, 98, 54, 50, 57, 102, + 101, 97, 55, 99, 99, 102, 102, 49, 53, 55, 98, 52, 99, 51, 101, 50, 54, 55, 48, 49, 100, 99, + 100, 56, 48, 100, 56, 57, 50, 55, 102, 57, 100, 97, 161, 101, 118, 97, 108, 117, 101, 120, 65, + 48, 120, 51, 102, 101, 52, 97, 50, 99, 49, 101, 98, 49, 54, 48, 97, 51, 49, 55, 54, 50, 100, + 56, 99, 54, 99, 98, 101, 53, 48, 55, 100, 98, 49, 100, 52, 50, 97, 52, 49, 49, 50, 51, 100, 98, + 53, 49, 98, 99, 100, 55, 48, 101, 99, 57, 53, 52, 51, 57, 100, 55, 100, 55, 99, 98, 161, 101, + 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 98, 97, 55, 100, 49, 99, 50, 98, 54, 98, 98, 49, + 50, 57, 102, 52, 51, 101, 53, 54, 101, 52, 57, 101, 102, 56, 50, 101, 53, 50, 101, 98, 51, 54, + 48, 49, 52, 102, 53, 99, 98, 49, 98, 98, 52, 55, 52, 49, 98, 53, 99, 49, 98, 98, 55, 99, 54, + 102, 54, 51, 97, 99, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 52, 55, 51, 56, + 98, 55, 98, 53, 101, 50, 101, 101, 52, 51, 102, 52, 53, 101, 100, 48, 53, 52, 57, 53, 50, 50, + 99, 57, 100, 49, 102, 55, 56, 55, 53, 97, 57, 102, 55, 102, 55, 50, 102, 50, 102, 98, 101, 55, + 51, 98, 55, 52, 102, 48, 52, 57, 98, 56, 99, 52, 56, 98, 161, 101, 118, 97, 108, 117, 101, 120, + 65, 48, 120, 49, 53, 49, 49, 97, 49, 54, 98, 98, 54, 99, 53, 52, 52, 53, 51, 53, 98, 51, 50, + 100, 54, 97, 102, 57, 53, 50, 53, 57, 98, 51, 53, 56, 99, 97, 52, 49, 55, 56, 101, 48, 102, + 101, 49, 53, 101, 102, 56, 50, 49, 101, 100, 51, 51, 55, 51, 98, 101, 102, 56, 100, 53, 97, + 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 48, 161, 101, 118, 97, 108, 117, 101, 120, 64, + 48, 120, 102, 56, 56, 50, 98, 99, 101, 97, 51, 98, 102, 48, 49, 100, 50, 98, 57, 98, 51, 52, + 52, 55, 50, 49, 56, 56, 48, 53, 50, 97, 98, 50, 52, 98, 97, 52, 50, 56, 55, 102, 50, 55, 52, + 55, 53, 55, 56, 52, 56, 55, 49, 52, 54, 51, 98, 51, 53, 97, 56, 101, 50, 97, 161, 101, 118, 97, + 108, 117, 101, 120, 64, 48, 120, 53, 50, 53, 49, 101, 97, 49, 52, 99, 101, 99, 53, 53, 56, 98, + 55, 55, 98, 102, 56, 98, 50, 102, 52, 57, 100, 54, 48, 49, 53, 56, 51, 51, 48, 48, 101, 97, 56, + 52, 98, 51, 99, 49, 100, 57, 56, 102, 101, 50, 51, 50, 55, 102, 50, 55, 54, 100, 56, 48, 54, + 50, 56, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 97, 53, 99, 53, 48, 98, 48, 51, + 52, 100, 52, 55, 100, 50, 100, 98, 56, 53, 53, 55, 100, 98, 51, 53, 53, 56, 55, 53, 53, 49, + 100, 102, 97, 52, 57, 50, 52, 97, 51, 56, 55, 55, 52, 101, 52, 50, 51, 97, 97, 49, 53, 99, 54, + 54, 101, 100, 48, 53, 54, 98, 98, 48, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 48, 161, + 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 49, 98, 52, 97, 98, 102, 57, 55, 101, 49, + 51, 55, 53, 54, 100, 98, 49, 54, 98, 54, 98, 101, 97, 100, 54, 100, 102, 98, 55, 99, 49, 97, + 51, 56, 54, 49, 57, 57, 51, 50, 56, 55, 48, 54, 97, 53, 56, 55, 50, 100, 98, 100, 54, 57, 102, + 98, 100, 50, 53, 50, 101, 99, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 53, 50, 53, + 49, 101, 97, 49, 52, 99, 101, 99, 53, 53, 56, 98, 55, 55, 98, 102, 56, 98, 50, 102, 52, 57, + 100, 54, 48, 49, 53, 56, 51, 51, 48, 48, 101, 97, 56, 52, 98, 51, 99, 49, 100, 57, 56, 102, + 101, 50, 51, 50, 55, 102, 50, 55, 54, 100, 56, 48, 54, 50, 56, 161, 101, 118, 97, 108, 117, + 101, 120, 64, 48, 120, 102, 56, 56, 50, 98, 99, 101, 97, 51, 98, 102, 48, 49, 100, 50, 98, 57, + 98, 51, 52, 52, 55, 50, 49, 56, 56, 48, 53, 50, 97, 98, 50, 52, 98, 97, 52, 50, 56, 55, 102, + 50, 55, 52, 55, 53, 55, 56, 52, 56, 55, 49, 52, 54, 51, 98, 51, 53, 97, 56, 101, 50, 97, 161, + 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 48, 102, 54, 54, 52, 100, 102, 100, 97, 56, + 48, 50, 99, 56, 52, 49, 54, 51, 55, 98, 50, 97, 98, 52, 56, 50, 50, 53, 54, 100, 101, 97, 100, + 102, 98, 97, 101, 52, 102, 100, 50, 53, 52, 99, 99, 100, 52, 50, 98, 52, 54, 55, 52, 50, 101, + 56, 99, 56, 48, 48, 48, 48, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 48, 161, 101, 118, + 97, 108, 117, 101, 120, 65, 48, 120, 52, 97, 56, 98, 97, 55, 56, 99, 49, 57, 53, 101, 101, 51, + 100, 100, 49, 52, 100, 99, 98, 57, 99, 97, 55, 101, 57, 100, 56, 57, 51, 54, 52, 48, 102, 51, + 52, 50, 55, 99, 99, 54, 97, 100, 57, 97, 99, 49, 51, 98, 56, 98, 56, 102, 57, 48, 57, 57, 57, + 50, 101, 100, 97, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 52, 100, 102, 49, 98, + 57, 100, 101, 101, 53, 51, 55, 100, 52, 54, 49, 51, 97, 50, 56, 56, 49, 49, 55, 97, 48, 54, + 101, 102, 50, 54, 54, 51, 57, 57, 98, 99, 100, 57, 54, 49, 99, 48, 48, 57, 99, 52, 100, 102, + 50, 53, 97, 51, 54, 102, 50, 50, 54, 48, 102, 99, 54, 161, 101, 118, 97, 108, 117, 101, 120, + 65, 48, 120, 51, 100, 56, 50, 54, 48, 55, 51, 54, 56, 56, 56, 54, 51, 98, 54, 99, 49, 49, 100, + 100, 55, 98, 57, 55, 50, 53, 54, 98, 51, 50, 49, 53, 99, 97, 50, 100, 52, 48, 102, 56, 97, 54, + 51, 102, 49, 98, 100, 51, 102, 100, 99, 98, 55, 101, 55, 50, 98, 99, 97, 98, 102, 101, 161, + 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 50, 102, 55, 49, 97, 54, 51, 56, 97, 55, 48, + 55, 48, 48, 51, 55, 97, 57, 56, 101, 49, 100, 51, 99, 50, 98, 101, 99, 98, 98, 101, 50, 102, + 100, 52, 52, 98, 102, 50, 99, 50, 98, 56, 49, 100, 48, 54, 99, 50, 54, 50, 98, 51, 101, 100, + 101, 57, 56, 53, 52, 50, 52, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 57, 49, 49, + 49, 49, 51, 56, 54, 49, 54, 100, 99, 52, 100, 48, 56, 56, 55, 48, 101, 52, 102, 55, 52, 51, + 100, 53, 52, 101, 54, 100, 56, 101, 48, 49, 48, 101, 52, 100, 48, 57, 48, 53, 57, 56, 51, 102, + 48, 100, 51, 51, 51, 56, 56, 99, 101, 54, 102, 57, 101, 97, 97, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 55, 101, 98, 50, 50, 56, 99, 55, 101, 99, 55, 54, 55, 49, 54, 53, 50, + 102, 49, 54, 102, 56, 101, 50, 56, 97, 56, 56, 97, 57, 98, 100, 99, 100, 53, 50, 99, 48, 98, + 101, 53, 50, 101, 99, 48, 51, 55, 52, 100, 48, 52, 56, 55, 97, 55, 51, 98, 98, 97, 99, 101, 53, + 51, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 101, 54, 57, 100, 97, 101, 54, 99, + 102, 99, 49, 99, 48, 50, 48, 54, 53, 101, 54, 48, 98, 99, 98, 101, 57, 56, 55, 101, 102, 98, + 54, 55, 102, 51, 48, 99, 55, 55, 56, 51, 57, 98, 56, 55, 53, 100, 101, 102, 98, 57, 100, 55, + 52, 48, 102, 50, 49, 101, 55, 98, 57, 50, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, + 98, 57, 52, 55, 100, 50, 55, 52, 97, 49, 53, 99, 55, 54, 54, 100, 49, 97, 98, 56, 49, 52, 55, + 98, 53, 53, 50, 55, 98, 101, 100, 99, 98, 101, 51, 50, 98, 49, 48, 57, 54, 54, 56, 49, 101, 50, + 99, 100, 102, 55, 98, 53, 102, 100, 55, 99, 99, 48, 49, 100, 97, 49, 161, 101, 118, 97, 108, + 117, 101, 120, 65, 48, 120, 53, 53, 55, 99, 51, 51, 54, 57, 53, 55, 57, 57, 101, 48, 56, 99, + 100, 102, 99, 56, 56, 56, 99, 48, 102, 53, 54, 48, 101, 54, 53, 101, 57, 48, 54, 53, 54, 97, + 100, 98, 99, 101, 99, 101, 99, 49, 51, 56, 49, 98, 55, 57, 57, 102, 100, 51, 56, 57, 49, 51, + 98, 98, 54, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 53, 55, 99, 98, 57, 57, 50, 97, + 98, 99, 97, 97, 52, 49, 101, 100, 54, 50, 54, 53, 55, 56, 48, 50, 55, 48, 53, 98, 48, 97, 57, + 100, 98, 54, 52, 99, 57, 54, 102, 55, 50, 56, 99, 55, 100, 101, 101, 56, 56, 48, 97, 56, 101, + 100, 50, 54, 98, 55, 57, 98, 98, 53, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 55, + 51, 51, 56, 52, 56, 52, 98, 53, 54, 49, 99, 54, 55, 97, 57, 99, 98, 56, 51, 100, 99, 57, 53, + 102, 98, 100, 102, 48, 52, 101, 98, 97, 98, 101, 99, 98, 98, 53, 57, 98, 51, 57, 99, 102, 49, + 99, 54, 50, 98, 53, 102, 50, 54, 52, 55, 101, 48, 49, 100, 97, 54, 99, 161, 101, 118, 97, 108, + 117, 101, 120, 65, 48, 120, 50, 50, 57, 56, 102, 100, 54, 98, 98, 100, 57, 55, 99, 102, 100, + 97, 102, 101, 99, 99, 98, 55, 52, 49, 53, 100, 50, 54, 98, 99, 51, 50, 98, 100, 51, 97, 55, 56, + 52, 56, 100, 97, 100, 52, 48, 54, 50, 56, 98, 56, 55, 49, 56, 50, 97, 101, 53, 52, 53, 55, 51, + 56, 97, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 48, 53, 48, 101, 52, 101, 52, + 97, 57, 52, 56, 98, 97, 50, 102, 98, 52, 51, 57, 55, 52, 100, 57, 100, 53, 55, 100, 49, 48, 99, + 57, 48, 49, 53, 50, 48, 50, 57, 56, 53, 54, 53, 54, 49, 50, 101, 55, 102, 53, 52, 49, 53, 50, + 56, 99, 52, 51, 56, 100, 52, 54, 50, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, + 54, 102, 54, 99, 56, 50, 99, 51, 102, 48, 56, 102, 100, 98, 101, 48, 55, 100, 55, 57, 54, 48, + 56, 97, 53, 54, 99, 97, 54, 98, 57, 56, 51, 101, 100, 54, 48, 101, 50, 102, 97, 52, 53, 52, 97, + 101, 56, 102, 53, 54, 49, 53, 98, 48, 99, 101, 98, 56, 101, 97, 56, 52, 161, 101, 118, 97, 108, + 117, 101, 120, 65, 48, 120, 53, 98, 51, 48, 55, 101, 97, 56, 50, 101, 97, 49, 55, 54, 57, 53, + 49, 97, 56, 48, 55, 97, 57, 100, 99, 55, 51, 49, 57, 55, 98, 101, 51, 53, 54, 49, 102, 55, 100, + 53, 48, 102, 102, 98, 57, 98, 54, 56, 98, 54, 48, 102, 55, 57, 51, 97, 53, 54, 51, 52, 50, 57, + 97, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 48, 98, 48, 101, 49, 50, 97, 49, + 48, 102, 52, 52, 101, 98, 100, 54, 98, 52, 57, 48, 48, 102, 102, 56, 99, 102, 54, 100, 48, 54, + 53, 55, 50, 54, 101, 50, 97, 57, 101, 102, 48, 100, 50, 99, 48, 49, 55, 53, 51, 100, 98, 101, + 50, 55, 97, 55, 55, 49, 98, 97, 98, 98, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, + 51, 98, 49, 56, 54, 48, 101, 100, 97, 51, 98, 99, 49, 52, 49, 48, 98, 57, 99, 52, 53, 101, 54, + 52, 50, 97, 48, 56, 57, 56, 52, 48, 98, 99, 51, 50, 101, 101, 54, 56, 99, 55, 53, 100, 57, 99, + 49, 99, 53, 102, 54, 53, 53, 97, 51, 97, 54, 54, 57, 56, 99, 101, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 53, 98, 51, 55, 54, 51, 57, 57, 57, 100, 56, 57, 52, 50, 51, 57, 102, + 48, 99, 48, 97, 56, 55, 98, 98, 51, 56, 51, 56, 52, 52, 49, 98, 54, 57, 99, 49, 55, 49, 53, 97, + 53, 54, 102, 98, 48, 101, 49, 101, 98, 97, 50, 51, 55, 50, 52, 97, 99, 55, 99, 102, 100, 56, + 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 57, 98, 99, 99, 54, 99, 53, 54, 54, + 100, 52, 48, 98, 48, 97, 48, 56, 99, 97, 100, 53, 100, 53, 51, 100, 100, 56, 98, 99, 56, 97, + 99, 53, 97, 54, 49, 48, 52, 102, 52, 51, 52, 57, 98, 98, 48, 57, 50, 97, 50, 99, 98, 56, 56, + 53, 48, 102, 52, 48, 52, 54, 54, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 53, 48, + 56, 54, 56, 102, 100, 53, 51, 55, 56, 54, 52, 99, 101, 101, 57, 97, 100, 102, 97, 99, 53, 49, + 56, 57, 52, 99, 99, 101, 52, 52, 97, 52, 56, 100, 51, 99, 101, 53, 49, 55, 48, 54, 55, 54, 99, + 100, 57, 53, 98, 100, 48, 98, 54, 53, 50, 52, 56, 48, 54, 52, 52, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 49, 100, 52, 56, 102, 99, 51, 52, 48, 101, 56, 52, 48, 98, 53, 48, 48, + 99, 57, 97, 98, 98, 101, 50, 51, 102, 50, 50, 100, 99, 51, 57, 99, 99, 48, 102, 57, 55, 99, + 101, 51, 98, 57, 97, 99, 56, 102, 48, 48, 99, 54, 56, 53, 52, 48, 53, 101, 53, 97, 53, 97, 53, + 101, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 97, 102, 57, 53, 50, 100, 52, 56, + 99, 50, 97, 101, 101, 102, 97, 97, 48, 55, 98, 57, 99, 56, 55, 98, 100, 100, 53, 97, 51, 99, + 54, 50, 49, 53, 53, 100, 98, 54, 51, 56, 55, 52, 102, 49, 55, 49, 102, 99, 57, 54, 102, 48, + 102, 50, 51, 57, 56, 53, 99, 99, 101, 53, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, + 54, 48, 54, 57, 51, 101, 53, 50, 54, 98, 49, 102, 48, 48, 53, 51, 56, 50, 50, 53, 98, 50, 50, + 57, 50, 99, 49, 102, 54, 56, 98, 57, 56, 54, 102, 50, 56, 55, 101, 99, 51, 101, 49, 55, 98, 53, + 54, 101, 49, 50, 51, 102, 98, 102, 100, 99, 51, 98, 54, 101, 100, 56, 161, 101, 118, 97, 108, + 117, 101, 120, 65, 48, 120, 49, 52, 52, 52, 57, 51, 56, 55, 52, 52, 49, 51, 49, 97, 101, 48, + 51, 56, 56, 53, 100, 48, 97, 101, 52, 53, 97, 99, 52, 56, 53, 54, 56, 53, 56, 50, 50, 49, 49, + 55, 97, 52, 56, 54, 57, 53, 102, 56, 48, 102, 55, 48, 102, 56, 57, 57, 48, 54, 56, 51, 101, 57, + 54, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 56, 49, 51, 101, 55, 57, 56, 100, + 99, 52, 51, 102, 49, 55, 99, 48, 48, 55, 98, 57, 97, 54, 97, 48, 101, 101, 49, 56, 98, 51, 100, + 52, 56, 49, 101, 55, 53, 49, 51, 100, 55, 52, 51, 99, 51, 54, 98, 99, 101, 99, 57, 49, 55, 54, + 56, 55, 50, 54, 100, 54, 97, 50, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 50, + 52, 50, 54, 53, 102, 54, 54, 53, 97, 50, 99, 99, 57, 54, 54, 97, 54, 49, 57, 51, 57, 49, 53, + 48, 54, 98, 54, 51, 56, 98, 51, 101, 49, 57, 56, 51, 98, 97, 101, 101, 55, 57, 51, 98, 51, 100, + 48, 97, 101, 55, 53, 98, 50, 56, 55, 50, 51, 48, 100, 57, 100, 161, 101, 118, 97, 108, 117, + 101, 120, 64, 48, 120, 101, 50, 53, 99, 57, 98, 57, 101, 51, 52, 50, 50, 102, 57, 52, 54, 99, + 56, 50, 57, 56, 52, 48, 98, 51, 98, 51, 54, 98, 49, 99, 53, 100, 54, 52, 99, 99, 100, 102, 55, + 54, 52, 51, 51, 57, 56, 97, 54, 101, 101, 97, 98, 57, 56, 57, 101, 54, 100, 53, 57, 100, 57, + 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 53, 49, 102, 57, 53, 51, 56, 51, 101, + 101, 52, 57, 102, 100, 56, 49, 101, 51, 98, 98, 53, 52, 56, 101, 55, 97, 100, 100, 55, 102, 97, + 53, 101, 56, 57, 101, 57, 54, 50, 52, 54, 51, 53, 51, 102, 55, 54, 99, 48, 52, 51, 54, 100, 48, + 98, 102, 52, 54, 56, 50, 51, 97, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 98, + 48, 98, 97, 51, 51, 101, 57, 49, 50, 97, 55, 48, 55, 100, 97, 101, 48, 102, 48, 56, 98, 100, + 57, 102, 100, 48, 99, 55, 56, 55, 57, 102, 48, 54, 101, 99, 54, 57, 100, 55, 50, 50, 51, 57, + 53, 49, 52, 99, 101, 50, 54, 99, 49, 97, 50, 101, 54, 57, 52, 50, 102, 161, 101, 118, 97, 108, + 117, 101, 120, 65, 48, 120, 52, 57, 52, 52, 52, 48, 52, 100, 56, 48, 48, 100, 97, 98, 53, 50, + 51, 55, 52, 52, 102, 99, 54, 97, 54, 98, 97, 49, 51, 55, 53, 55, 54, 56, 101, 48, 52, 54, 102, + 100, 49, 98, 50, 51, 102, 52, 57, 54, 98, 52, 55, 52, 54, 48, 49, 49, 100, 57, 55, 54, 48, 48, + 53, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 101, 101, 50, 57, 102, 99, 50, 54, + 102, 98, 55, 48, 53, 56, 100, 57, 52, 98, 51, 50, 100, 99, 51, 49, 100, 57, 101, 97, 53, 48, + 54, 102, 98, 52, 49, 100, 101, 101, 50, 98, 48, 101, 56, 54, 48, 49, 57, 99, 98, 55, 56, 56, + 102, 48, 52, 56, 54, 51, 53, 99, 49, 100, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, + 52, 97, 99, 100, 57, 48, 53, 98, 50, 50, 54, 51, 102, 51, 98, 53, 54, 97, 51, 49, 51, 55, 57, + 48, 53, 99, 50, 48, 54, 52, 56, 102, 49, 49, 56, 50, 100, 99, 57, 99, 53, 51, 98, 55, 97, 55, + 101, 52, 97, 51, 48, 52, 49, 54, 101, 52, 55, 49, 101, 97, 56, 50, 49, 161, 101, 118, 97, 108, + 117, 101, 120, 64, 48, 120, 55, 51, 97, 52, 51, 54, 48, 97, 55, 55, 56, 48, 55, 50, 54, 48, 53, + 50, 100, 54, 55, 101, 52, 51, 98, 57, 56, 57, 97, 101, 102, 98, 99, 101, 51, 102, 50, 57, 51, + 57, 52, 51, 50, 101, 53, 55, 55, 48, 51, 97, 49, 97, 101, 53, 57, 48, 48, 98, 54, 48, 51, 102, + 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 55, 102, 57, 49, 56, 102, 100, 102, 51, 52, + 54, 98, 101, 50, 97, 49, 49, 50, 102, 53, 49, 50, 50, 101, 102, 54, 100, 50, 52, 56, 100, 54, + 51, 102, 53, 97, 54, 48, 48, 50, 100, 48, 51, 98, 98, 52, 50, 52, 48, 55, 57, 100, 52, 101, 52, + 56, 100, 52, 52, 101, 100, 53, 49, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 56, + 51, 102, 102, 50, 51, 99, 97, 56, 56, 49, 97, 100, 53, 53, 49, 52, 100, 55, 55, 98, 100, 48, + 98, 55, 53, 97, 50, 52, 99, 50, 49, 99, 101, 54, 53, 48, 98, 56, 54, 98, 50, 50, 54, 56, 49, + 101, 51, 55, 98, 52, 51, 99, 51, 50, 56, 55, 51, 52, 98, 54, 54, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 55, 53, 101, 101, 52, 51, 100, 50, 49, 53, 53, 54, 52, 51, 100, 101, 55, + 55, 57, 49, 53, 57, 102, 48, 55, 52, 55, 48, 98, 51, 48, 52, 97, 52, 100, 54, 53, 98, 57, 49, + 52, 97, 101, 54, 102, 51, 53, 49, 54, 101, 49, 97, 48, 54, 101, 52, 99, 52, 98, 55, 54, 97, 98, + 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 55, 56, 57, 102, 56, 53, 102, 98, 56, 102, + 54, 57, 50, 53, 55, 49, 54, 50, 49, 100, 97, 100, 48, 102, 50, 102, 49, 54, 51, 49, 55, 55, 99, + 54, 101, 51, 55, 52, 53, 51, 50, 50, 52, 49, 48, 97, 56, 55, 98, 48, 48, 100, 48, 51, 97, 54, + 97, 54, 97, 97, 52, 55, 54, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 51, 98, 53, + 52, 50, 54, 54, 101, 99, 55, 99, 51, 100, 57, 102, 55, 52, 99, 101, 98, 49, 99, 55, 99, 52, + 102, 97, 49, 102, 98, 101, 49, 54, 51, 51, 48, 98, 99, 99, 102, 100, 50, 53, 99, 56, 102, 52, + 56, 100, 101, 100, 51, 48, 98, 51, 102, 55, 101, 55, 56, 97, 102, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 50, 56, 99, 54, 56, 50, 57, 48, 49, 101, 52, 48, 53, 55, 51, 54, 97, 57, + 102, 56, 56, 99, 49, 55, 101, 100, 99, 52, 98, 102, 52, 50, 50, 49, 53, 99, 102, 100, 98, 55, + 51, 51, 52, 48, 102, 51, 48, 51, 100, 49, 101, 99, 102, 51, 102, 51, 98, 49, 48, 55, 52, 101, + 51, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 102, 97, 56, 56, 50, 99, 100, 55, + 49, 52, 98, 54, 51, 51, 56, 51, 98, 98, 55, 57, 56, 51, 102, 53, 51, 51, 101, 49, 50, 49, 100, + 56, 49, 55, 54, 98, 50, 48, 98, 55, 99, 52, 48, 55, 55, 51, 50, 101, 55, 56, 48, 99, 101, 55, + 98, 55, 49, 101, 100, 50, 98, 55, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 55, + 57, 48, 102, 97, 97, 50, 55, 48, 55, 52, 52, 54, 97, 49, 49, 97, 52, 102, 100, 98, 97, 56, 98, + 101, 102, 100, 50, 101, 97, 48, 53, 100, 50, 99, 53, 48, 51, 100, 53, 48, 55, 101, 57, 53, 99, + 57, 52, 54, 57, 50, 51, 100, 57, 48, 100, 100, 48, 98, 56, 54, 56, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 55, 53, 50, 52, 54, 99, 97, 53, 54, 102, 50, 51, 51, 50, 102, 99, 98, + 49, 51, 54, 48, 54, 52, 56, 100, 102, 50, 51, 54, 100, 56, 52, 101, 97, 101, 51, 100, 52, 57, + 54, 101, 56, 48, 49, 101, 102, 100, 53, 99, 55, 57, 51, 51, 49, 55, 102, 49, 50, 97, 55, 102, + 52, 54, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 48, 161, 101, 118, 97, 108, 117, 101, + 120, 65, 48, 120, 55, 51, 55, 97, 54, 55, 53, 97, 52, 50, 55, 99, 99, 102, 101, 53, 101, 97, + 53, 101, 50, 49, 100, 102, 101, 53, 52, 48, 51, 48, 49, 102, 57, 51, 101, 50, 56, 57, 99, 101, + 54, 101, 55, 102, 51, 48, 102, 55, 99, 100, 100, 97, 56, 52, 55, 102, 51, 57, 50, 57, 101, 52, + 101, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 99, 52, 97, 98, 100, 57, 57, 49, + 51, 56, 51, 99, 51, 55, 48, 56, 98, 51, 49, 52, 101, 51, 56, 51, 98, 48, 53, 101, 48, 52, 49, + 101, 57, 99, 99, 102, 52, 51, 51, 48, 50, 100, 97, 51, 55, 48, 98, 55, 50, 49, 50, 99, 102, 52, + 99, 48, 56, 49, 56, 55, 53, 51, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 53, 50, 53, + 49, 101, 97, 49, 52, 99, 101, 99, 53, 53, 56, 98, 55, 55, 98, 102, 56, 98, 50, 102, 52, 57, + 100, 54, 48, 49, 53, 56, 51, 51, 48, 48, 101, 97, 56, 52, 98, 51, 99, 49, 100, 57, 56, 102, + 101, 50, 51, 50, 55, 102, 50, 55, 54, 100, 56, 48, 54, 50, 56, 161, 101, 118, 97, 108, 117, + 101, 99, 48, 120, 48, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 53, 52, 54, 102, 99, + 100, 98, 57, 57, 102, 99, 53, 57, 53, 53, 53, 49, 102, 97, 54, 52, 54, 102, 101, 99, 54, 52, + 98, 50, 100, 57, 53, 53, 48, 97, 56, 98, 97, 54, 54, 48, 56, 55, 52, 100, 52, 100, 100, 54, + 102, 52, 50, 55, 53, 50, 100, 48, 102, 102, 55, 98, 54, 52, 161, 101, 118, 97, 108, 117, 101, + 120, 65, 48, 120, 54, 99, 52, 97, 98, 100, 57, 57, 49, 51, 56, 51, 99, 51, 55, 48, 56, 98, 51, + 49, 52, 101, 51, 56, 51, 98, 48, 53, 101, 48, 52, 49, 101, 57, 99, 99, 102, 52, 51, 51, 48, 50, + 100, 97, 51, 55, 48, 98, 55, 50, 49, 50, 99, 102, 52, 99, 48, 56, 49, 56, 55, 53, 51, 161, 101, + 118, 97, 108, 117, 101, 120, 65, 48, 120, 55, 51, 55, 97, 54, 55, 53, 97, 52, 50, 55, 99, 99, + 102, 101, 53, 101, 97, 53, 101, 50, 49, 100, 102, 101, 53, 52, 48, 51, 48, 49, 102, 57, 51, + 101, 50, 56, 57, 99, 101, 54, 101, 55, 102, 51, 48, 102, 55, 99, 100, 100, 97, 56, 52, 55, 102, + 51, 57, 50, 57, 101, 52, 101, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 98, 49, + 53, 98, 99, 54, 98, 53, 100, 49, 51, 49, 57, 51, 101, 49, 50, 98, 49, 48, 52, 98, 56, 57, 53, + 101, 51, 101, 101, 52, 54, 52, 102, 52, 102, 57, 55, 55, 57, 100, 97, 101, 52, 98, 101, 54, 99, + 100, 100, 101, 48, 50, 100, 48, 100, 53, 49, 51, 100, 52, 51, 97, 161, 101, 118, 97, 108, 117, + 101, 99, 48, 120, 48, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 101, 97, 98, 100, + 53, 98, 101, 97, 52, 50, 57, 56, 54, 100, 100, 99, 97, 98, 102, 48, 101, 98, 57, 101, 54, 48, + 52, 57, 50, 98, 99, 99, 57, 101, 48, 56, 48, 54, 53, 51, 97, 49, 56, 98, 100, 101, 100, 100, + 55, 54, 49, 57, 54, 98, 51, 98, 51, 49, 52, 102, 56, 100, 161, 101, 118, 97, 108, 117, 101, + 120, 65, 48, 120, 51, 102, 48, 102, 102, 49, 99, 101, 57, 98, 98, 49, 49, 54, 57, 50, 51, 101, + 50, 51, 101, 49, 53, 53, 50, 102, 49, 98, 55, 50, 53, 54, 99, 99, 53, 98, 50, 49, 54, 98, 55, + 54, 57, 53, 55, 102, 57, 57, 56, 98, 49, 52, 53, 52, 53, 54, 98, 100, 52, 54, 53, 53, 52, 161, + 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 48, 55, 53, 48, 52, 52, 50, 52, 54, 48, 53, + 52, 55, 48, 54, 99, 101, 55, 51, 57, 100, 99, 55, 100, 99, 55, 52, 48, 48, 48, 50, 102, 56, 55, + 102, 55, 48, 101, 102, 53, 50, 98, 52, 101, 97, 56, 100, 102, 54, 57, 53, 55, 100, 53, 49, 53, + 100, 97, 100, 101, 48, 100, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 56, 97, 53, + 54, 53, 50, 50, 49, 53, 57, 48, 99, 48, 52, 55, 52, 51, 51, 97, 57, 57, 102, 48, 51, 99, 52, + 51, 97, 55, 50, 102, 102, 51, 97, 97, 57, 52, 48, 56, 52, 54, 51, 56, 48, 50, 52, 48, 48, 98, + 53, 100, 50, 51, 50, 102, 100, 100, 53, 52, 97, 100, 52, 161, 101, 118, 97, 108, 117, 101, 120, + 65, 48, 120, 50, 99, 54, 97, 57, 54, 100, 56, 100, 57, 97, 50, 100, 102, 99, 51, 54, 101, 102, + 57, 51, 99, 57, 51, 55, 48, 55, 97, 100, 98, 49, 48, 98, 100, 56, 99, 57, 56, 57, 100, 101, + 100, 99, 99, 54, 56, 50, 98, 50, 102, 54, 50, 51, 55, 53, 99, 101, 48, 50, 55, 52, 102, 101, + 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 98, 54, 101, 49, 99, 56, 97, 52, 52, + 101, 52, 99, 52, 53, 102, 52, 56, 97, 50, 50, 99, 53, 48, 99, 54, 51, 50, 48, 49, 49, 53, 102, + 98, 52, 55, 49, 97, 101, 99, 56, 99, 101, 101, 102, 56, 56, 48, 50, 51, 52, 56, 57, 101, 102, + 102, 102, 48, 51, 101, 53, 57, 53, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 53, 53, + 100, 100, 49, 102, 97, 56, 99, 98, 98, 55, 49, 51, 51, 57, 56, 52, 54, 52, 56, 48, 99, 53, 101, + 55, 97, 102, 51, 48, 48, 100, 55, 102, 53, 101, 99, 102, 48, 101, 53, 102, 56, 52, 98, 50, 100, + 97, 100, 51, 97, 51, 52, 99, 53, 57, 49, 55, 49, 97, 52, 49, 101, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 55, 57, 55, 55, 56, 100, 53, 98, 52, 100, 48, 99, 48, 54, 54, 53, 52, + 55, 55, 101, 56, 49, 51, 54, 56, 51, 48, 101, 50, 51, 102, 102, 55, 57, 49, 56, 51, 101, 55, + 48, 48, 101, 98, 101, 56, 99, 55, 48, 57, 57, 97, 49, 53, 98, 48, 98, 56, 57, 102, 54, 56, 100, + 49, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 101, 56, 55, 57, 48, 49, 98, 51, + 97, 52, 50, 51, 55, 57, 52, 52, 55, 55, 97, 53, 51, 102, 53, 55, 101, 50, 50, 98, 51, 98, 55, + 53, 54, 53, 55, 102, 55, 53, 102, 100, 101, 50, 102, 98, 48, 101, 100, 55, 97, 48, 48, 101, + 102, 100, 56, 99, 102, 50, 52, 53, 52, 53, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, + 52, 48, 99, 54, 56, 55, 97, 50, 55, 53, 101, 56, 55, 57, 101, 99, 52, 49, 99, 98, 97, 53, 52, + 50, 98, 51, 53, 55, 50, 52, 53, 52, 100, 101, 101, 51, 53, 50, 54, 56, 102, 99, 49, 55, 55, 54, + 55, 98, 50, 97, 50, 54, 98, 102, 52, 52, 53, 98, 49, 102, 51, 97, 57, 161, 101, 118, 97, 108, + 117, 101, 120, 65, 48, 120, 50, 97, 57, 100, 52, 102, 102, 48, 48, 100, 100, 101, 52, 57, 48, + 53, 97, 57, 54, 101, 51, 101, 52, 102, 99, 100, 99, 97, 54, 52, 52, 100, 50, 56, 52, 49, 49, + 57, 49, 49, 51, 48, 52, 57, 48, 51, 52, 50, 56, 101, 100, 54, 97, 57, 55, 56, 100, 100, 98, 99, + 49, 56, 98, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 50, 102, 53, 101, 54, 98, + 53, 100, 54, 102, 51, 100, 100, 99, 56, 100, 48, 102, 97, 53, 99, 102, 56, 56, 56, 54, 52, 100, + 98, 48, 55, 52, 48, 57, 49, 52, 102, 99, 49, 51, 53, 52, 99, 50, 55, 100, 49, 52, 102, 49, 53, + 99, 49, 97, 98, 48, 51, 101, 100, 56, 49, 56, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, + 120, 50, 99, 101, 97, 100, 102, 57, 51, 50, 54, 100, 56, 56, 53, 56, 99, 100, 100, 54, 52, 56, + 100, 100, 102, 57, 100, 100, 55, 52, 52, 97, 102, 49, 56, 102, 53, 101, 57, 102, 97, 53, 52, + 48, 98, 48, 101, 51, 99, 97, 100, 52, 55, 55, 54, 97, 52, 102, 99, 98, 49, 97, 97, 53, 161, + 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 55, 53, 55, 49, 98, 56, 50, 52, 51, 102, 97, 48, + 97, 99, 99, 53, 52, 53, 57, 52, 100, 57, 54, 56, 100, 50, 57, 50, 97, 57, 101, 97, 49, 99, 100, + 49, 51, 50, 55, 57, 101, 99, 98, 102, 55, 100, 56, 100, 49, 48, 53, 52, 99, 99, 54, 49, 100, + 97, 99, 49, 52, 50, 49, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 56, 50, 99, 56, + 97, 54, 102, 57, 52, 99, 54, 48, 53, 97, 54, 50, 55, 101, 100, 102, 48, 57, 57, 97, 54, 55, 55, + 102, 57, 100, 97, 100, 98, 52, 99, 53, 100, 100, 53, 101, 56, 98, 54, 102, 98, 98, 52, 57, 55, + 51, 55, 51, 98, 98, 54, 53, 55, 101, 97, 100, 52, 102, 161, 101, 118, 97, 108, 117, 101, 120, + 65, 48, 120, 52, 49, 101, 56, 57, 98, 57, 57, 50, 102, 57, 53, 97, 53, 48, 52, 52, 57, 48, 99, + 100, 52, 57, 57, 49, 99, 57, 56, 51, 57, 54, 100, 99, 53, 100, 97, 97, 48, 50, 97, 54, 50, 56, + 101, 48, 102, 57, 50, 100, 54, 53, 98, 57, 98, 102, 49, 102, 98, 56, 49, 55, 97, 99, 161, 101, + 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 55, 48, 98, 48, 98, 100, 100, 102, 51, 100, 102, + 56, 102, 52, 49, 51, 101, 55, 54, 100, 56, 55, 53, 57, 101, 101, 53, 50, 98, 51, 48, 97, 49, + 57, 52, 51, 48, 97, 51, 98, 57, 98, 97, 99, 99, 100, 50, 98, 99, 97, 49, 102, 97, 53, 50, 48, + 100, 49, 48, 51, 101, 101, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 51, 53, 99, + 49, 57, 101, 97, 101, 97, 48, 98, 97, 51, 51, 52, 97, 51, 101, 57, 54, 50, 100, 55, 49, 54, 98, + 57, 98, 100, 49, 102, 56, 54, 102, 98, 55, 49, 53, 50, 53, 56, 100, 49, 53, 50, 101, 101, 49, + 52, 54, 51, 53, 53, 53, 101, 98, 51, 56, 98, 98, 51, 101, 161, 101, 118, 97, 108, 117, 101, + 120, 65, 48, 120, 49, 52, 101, 49, 53, 97, 98, 53, 49, 99, 97, 57, 101, 52, 48, 54, 100, 52, + 98, 100, 53, 101, 98, 53, 54, 49, 98, 99, 51, 97, 52, 51, 54, 48, 52, 55, 99, 56, 52, 51, 48, + 97, 52, 54, 48, 101, 99, 99, 100, 57, 98, 49, 54, 51, 98, 53, 48, 102, 100, 53, 57, 53, 55, + 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 53, 50, 56, 56, 51, 48, 98, 98, 50, 57, + 51, 48, 54, 99, 50, 99, 101, 51, 50, 55, 53, 57, 98, 48, 99, 54, 100, 97, 101, 100, 97, 100, + 53, 97, 49, 48, 101, 100, 51, 99, 56, 55, 48, 49, 56, 56, 48, 101, 49, 100, 100, 56, 52, 50, + 51, 52, 56, 100, 55, 101, 49, 49, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 51, 56, + 55, 98, 102, 51, 54, 55, 53, 97, 48, 98, 97, 55, 48, 56, 97, 49, 102, 48, 101, 49, 57, 97, 55, + 54, 55, 56, 102, 49, 54, 101, 55, 48, 56, 101, 101, 99, 51, 100, 53, 102, 48, 97, 53, 52, 55, + 48, 101, 50, 98, 98, 53, 56, 99, 51, 98, 98, 55, 52, 53, 54, 161, 101, 118, 97, 108, 117, 101, + 120, 64, 48, 120, 98, 56, 48, 101, 50, 99, 102, 99, 57, 57, 49, 56, 52, 54, 52, 51, 52, 50, 49, + 56, 56, 56, 53, 98, 57, 52, 49, 100, 57, 51, 99, 101, 55, 99, 52, 56, 52, 55, 101, 56, 48, 97, + 100, 50, 56, 53, 55, 51, 48, 55, 100, 57, 53, 98, 57, 99, 100, 100, 100, 55, 99, 99, 161, 101, + 118, 97, 108, 117, 101, 120, 64, 48, 120, 54, 49, 53, 102, 50, 55, 102, 56, 98, 99, 100, 48, + 100, 101, 102, 101, 53, 97, 57, 57, 98, 56, 101, 99, 55, 49, 99, 99, 97, 57, 98, 101, 51, 97, + 52, 98, 53, 50, 57, 57, 50, 54, 97, 99, 56, 99, 99, 51, 49, 57, 101, 53, 54, 102, 56, 102, 101, + 100, 99, 48, 54, 52, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 102, 57, 56, 51, + 55, 57, 48, 55, 99, 54, 53, 97, 50, 49, 51, 98, 53, 52, 50, 53, 98, 57, 98, 52, 98, 53, 99, 57, + 97, 55, 57, 50, 50, 50, 48, 57, 97, 102, 98, 54, 55, 56, 53, 48, 101, 54, 99, 49, 97, 51, 53, + 98, 99, 57, 56, 99, 56, 97, 101, 51, 57, 56, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, + 120, 52, 51, 56, 57, 99, 101, 54, 51, 99, 56, 56, 102, 51, 100, 99, 102, 100, 57, 53, 50, 53, + 53, 57, 102, 99, 53, 54, 52, 53, 53, 48, 100, 53, 54, 54, 101, 56, 54, 49, 48, 54, 50, 51, 57, + 56, 50, 98, 54, 98, 55, 97, 51, 98, 56, 49, 57, 51, 102, 53, 49, 49, 49, 49, 161, 101, 118, 97, + 108, 117, 101, 120, 65, 48, 120, 55, 56, 51, 99, 52, 54, 52, 52, 102, 102, 52, 97, 57, 53, 49, + 97, 51, 102, 57, 50, 56, 51, 51, 48, 54, 98, 54, 97, 53, 97, 97, 48, 51, 98, 57, 98, 49, 101, + 53, 48, 99, 54, 97, 51, 57, 49, 99, 57, 48, 55, 102, 49, 52, 98, 100, 49, 102, 98, 101, 52, 51, + 98, 51, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 55, 102, 97, 97, 53, 102, 53, 48, + 55, 56, 57, 101, 50, 49, 101, 48, 49, 51, 50, 55, 100, 50, 57, 52, 55, 57, 99, 56, 52, 100, + 100, 50, 49, 98, 98, 54, 98, 101, 54, 101, 97, 54, 98, 52, 102, 53, 52, 101, 99, 50, 49, 57, + 51, 100, 97, 50, 102, 51, 99, 98, 50, 55, 50, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, + 120, 52, 54, 100, 101, 56, 101, 101, 52, 48, 102, 57, 53, 55, 57, 56, 49, 99, 100, 102, 56, 54, + 99, 97, 55, 100, 56, 48, 49, 48, 54, 48, 99, 101, 102, 98, 97, 99, 101, 57, 54, 98, 98, 55, 53, + 54, 101, 101, 56, 57, 97, 53, 55, 100, 54, 52, 52, 56, 56, 99, 100, 48, 56, 55, 161, 101, 118, + 97, 108, 117, 101, 120, 65, 48, 120, 53, 57, 100, 52, 97, 48, 52, 52, 56, 51, 48, 57, 99, 54, + 48, 97, 57, 48, 50, 101, 56, 101, 99, 97, 100, 102, 98, 98, 100, 52, 54, 102, 53, 100, 55, 57, + 57, 101, 54, 54, 100, 97, 101, 50, 56, 50, 100, 99, 98, 50, 54, 48, 102, 55, 52, 57, 97, 48, + 55, 99, 52, 97, 97, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 57, 56, 55, 48, 54, + 49, 100, 98, 57, 53, 57, 52, 55, 56, 49, 102, 51, 49, 48, 98, 55, 51, 101, 101, 49, 51, 101, + 54, 55, 54, 49, 49, 53, 97, 102, 55, 57, 101, 49, 52, 99, 50, 53, 55, 99, 97, 99, 55, 54, 97, + 100, 50, 48, 98, 48, 52, 97, 101, 97, 57, 97, 54, 161, 101, 118, 97, 108, 117, 101, 120, 65, + 48, 120, 49, 57, 102, 50, 99, 51, 49, 50, 100, 100, 99, 52, 51, 101, 99, 54, 49, 57, 56, 97, + 53, 52, 99, 55, 48, 97, 51, 54, 102, 50, 49, 102, 57, 56, 101, 100, 100, 56, 99, 50, 98, 99, + 54, 53, 102, 57, 49, 56, 55, 53, 53, 57, 98, 55, 98, 102, 98, 99, 53, 98, 102, 50, 57, 161, + 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 100, 51, 48, 50, 101, 50, 48, 55, 57, 97, + 57, 97, 99, 48, 98, 57, 54, 49, 51, 55, 100, 57, 49, 53, 99, 99, 48, 54, 54, 55, 55, 48, 53, + 52, 56, 53, 101, 55, 56, 100, 56, 53, 56, 97, 53, 54, 54, 101, 55, 48, 55, 57, 55, 53, 98, 48, + 99, 100, 102, 56, 100, 98, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 55, 49, 57, 97, + 48, 102, 57, 97, 100, 49, 54, 57, 56, 101, 55, 54, 102, 101, 48, 99, 56, 102, 54, 57, 49, 53, + 55, 57, 101, 56, 98, 50, 54, 56, 102, 57, 50, 100, 50, 53, 54, 100, 50, 53, 52, 55, 55, 50, 55, + 55, 101, 55, 56, 56, 54, 99, 101, 100, 55, 53, 54, 57, 57, 161, 101, 118, 97, 108, 117, 101, + 120, 65, 48, 120, 49, 102, 98, 51, 98, 102, 53, 49, 48, 98, 99, 99, 50, 49, 57, 56, 49, 99, 98, + 50, 99, 100, 57, 99, 55, 101, 48, 100, 57, 55, 98, 101, 98, 52, 49, 49, 100, 97, 101, 48, 101, + 48, 53, 49, 51, 102, 102, 53, 52, 51, 53, 53, 50, 57, 49, 97, 57, 100, 53, 49, 98, 99, 48, 161, + 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 53, 54, 98, 55, 48, 55, 51, 51, 49, 49, 101, + 52, 98, 49, 99, 99, 50, 53, 97, 54, 56, 57, 99, 52, 98, 49, 53, 54, 53, 53, 100, 54, 56, 54, + 51, 53, 57, 53, 55, 98, 56, 57, 54, 101, 50, 97, 101, 55, 57, 50, 48, 57, 51, 98, 101, 57, 50, + 50, 50, 51, 49, 57, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 54, 98, 102, 57, + 100, 101, 54, 50, 57, 48, 56, 54, 54, 48, 54, 50, 51, 50, 99, 54, 99, 98, 51, 101, 98, 101, 48, + 56, 48, 54, 56, 97, 48, 54, 56, 56, 97, 98, 50, 50, 97, 54, 102, 50, 55, 100, 102, 57, 53, 56, + 55, 52, 52, 52, 56, 97, 52, 100, 54, 50, 98, 50, 105, 114, 111, 119, 95, 119, 105, 100, 116, + 104, 24, 52, 117, 99, 111, 109, 112, 111, 115, 105, 116, 105, 111, 110, 95, 112, 111, 108, 121, + 95, 114, 111, 111, 116, 152, 32, 24, 26, 24, 76, 6, 24, 35, 24, 204, 18, 24, 219, 24, 72, 13, + 24, 129, 24, 76, 24, 83, 24, 211, 24, 152, 24, 230, 24, 124, 17, 24, 60, 24, 27, 24, 27, 24, + 201, 24, 184, 24, 238, 24, 252, 24, 240, 24, 94, 24, 144, 24, 65, 24, 45, 24, 222, 24, 50, 24, + 134, 120, 36, 99, 111, 109, 112, 111, 115, 105, 116, 105, 111, 110, 95, 112, 111, 108, 121, 95, + 101, 118, 101, 110, 95, 111, 111, 100, 95, 101, 118, 97, 108, 117, 97, 116, 105, 111, 110, 161, + 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 101, 51, 54, 98, 57, 53, 53, 56, 101, 57, 49, + 97, 98, 99, 99, 54, 49, 101, 53, 53, 54, 50, 49, 102, 48, 99, 101, 101, 52, 57, 48, 101, 101, + 54, 98, 49, 57, 101, 48, 102, 99, 98, 99, 49, 49, 51, 48, 100, 48, 102, 51, 52, 98, 56, 54, 53, + 50, 55, 55, 52, 51, 52, 120, 35, 99, 111, 109, 112, 111, 115, 105, 116, 105, 111, 110, 95, 112, + 111, 108, 121, 95, 111, 100, 100, 95, 111, 111, 100, 95, 101, 118, 97, 108, 117, 97, 116, 105, + 111, 110, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 50, 51, 53, 98, 53, 102, 98, + 98, 98, 50, 55, 51, 55, 99, 50, 56, 52, 54, 100, 101, 51, 48, 100, 97, 100, 48, 102, 101, 51, + 101, 48, 53, 49, 100, 56, 100, 99, 57, 51, 100, 54, 54, 50, 57, 57, 56, 49, 57, 99, 56, 101, + 98, 49, 101, 51, 57, 100, 52, 100, 48, 54, 99, 119, 102, 114, 105, 95, 108, 97, 121, 101, 114, + 115, 95, 109, 101, 114, 107, 108, 101, 95, 114, 111, 111, 116, 115, 134, 152, 32, 24, 115, 24, + 189, 24, 156, 24, 53, 24, 91, 24, 183, 24, 255, 24, 40, 24, 108, 24, 47, 24, 199, 24, 161, 24, + 241, 24, 203, 24, 226, 24, 237, 24, 167, 24, 87, 24, 156, 24, 229, 24, 146, 24, 237, 24, 137, + 24, 236, 24, 246, 24, 77, 24, 238, 24, 194, 24, 58, 24, 213, 24, 78, 24, 109, 152, 32, 24, 218, + 24, 233, 24, 58, 24, 255, 24, 68, 24, 165, 24, 135, 24, 196, 24, 220, 24, 114, 24, 42, 24, 71, + 24, 247, 24, 221, 24, 122, 24, 177, 24, 166, 24, 154, 24, 187, 24, 149, 24, 33, 24, 182, 24, + 180, 24, 160, 24, 72, 24, 196, 24, 204, 24, 213, 24, 192, 24, 30, 24, 41, 24, 171, 152, 32, 24, + 29, 24, 110, 24, 250, 24, 31, 24, 95, 10, 24, 71, 3, 24, 54, 24, 45, 24, 35, 24, 81, 24, 225, + 24, 242, 24, 124, 24, 233, 24, 137, 24, 113, 24, 187, 24, 68, 24, 86, 3, 24, 139, 24, 180, 24, + 39, 24, 173, 24, 62, 24, 134, 24, 154, 24, 65, 24, 68, 24, 204, 152, 32, 18, 24, 114, 24, 27, + 24, 62, 11, 24, 255, 24, 115, 24, 112, 24, 94, 24, 165, 24, 137, 24, 219, 24, 197, 24, 187, 24, + 177, 18, 24, 126, 24, 72, 24, 151, 24, 232, 24, 225, 9, 24, 227, 24, 96, 24, 40, 24, 115, 3, + 24, 216, 24, 37, 24, 167, 24, 175, 24, 151, 152, 32, 24, 63, 24, 129, 24, 55, 24, 122, 24, 143, + 24, 254, 24, 111, 24, 100, 24, 223, 24, 187, 24, 56, 24, 128, 24, 185, 24, 145, 24, 206, 24, + 229, 24, 53, 24, 164, 24, 98, 24, 46, 24, 202, 24, 215, 0, 24, 143, 24, 135, 24, 217, 24, 193, + 24, 136, 24, 81, 24, 129, 24, 108, 24, 147, 152, 32, 24, 72, 24, 146, 24, 249, 24, 113, 24, + 173, 24, 53, 24, 214, 24, 235, 24, 180, 24, 33, 24, 94, 24, 140, 24, 184, 24, 141, 24, 100, 0, + 24, 58, 24, 138, 24, 138, 24, 179, 24, 227, 24, 71, 24, 39, 24, 196, 24, 60, 24, 86, 24, 41, + 24, 70, 24, 253, 24, 156, 24, 243, 24, 27, 110, 102, 114, 105, 95, 108, 97, 115, 116, 95, 118, + 97, 108, 117, 101, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 102, 100, 53, 53, 98, + 102, 101, 49, 53, 54, 98, 51, 54, 54, 51, 98, 55, 50, 99, 98, 54, 52, 53, 102, 51, 57, 102, 55, + 102, 99, 54, 50, 52, 56, 100, 98, 57, 49, 97, 102, 97, 97, 56, 97, 102, 99, 51, 53, 99, 55, 50, + 98, 54, 49, 55, 51, 48, 101, 99, 100, 53, 97, 106, 113, 117, 101, 114, 121, 95, 108, 105, 115, + 116, 131, 164, 117, 108, 97, 121, 101, 114, 115, 95, 97, 117, 116, 104, 95, 112, 97, 116, 104, + 115, 95, 115, 121, 109, 134, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, + 136, 152, 32, 24, 147, 7, 8, 24, 38, 24, 168, 24, 194, 1, 24, 153, 24, 169, 24, 139, 24, 145, + 24, 161, 24, 131, 24, 120, 24, 128, 24, 90, 24, 218, 24, 73, 23, 24, 114, 24, 49, 24, 208, 24, + 142, 24, 127, 24, 230, 24, 134, 24, 52, 24, 37, 24, 210, 24, 195, 24, 240, 24, 238, 152, 32, + 24, 150, 24, 239, 24, 199, 24, 254, 24, 50, 24, 213, 23, 24, 91, 24, 249, 24, 174, 24, 41, 24, + 45, 24, 134, 24, 159, 24, 60, 21, 24, 250, 24, 169, 24, 222, 24, 84, 7, 24, 208, 24, 173, 24, + 159, 24, 33, 24, 181, 24, 232, 24, 215, 24, 226, 24, 211, 24, 71, 24, 135, 152, 32, 24, 136, + 24, 104, 24, 174, 24, 78, 24, 255, 24, 159, 22, 24, 228, 24, 179, 24, 228, 22, 24, 58, 24, 60, + 24, 96, 24, 119, 24, 83, 4, 24, 53, 24, 146, 24, 52, 5, 24, 109, 21, 24, 225, 24, 169, 24, 217, + 24, 142, 24, 83, 24, 247, 24, 237, 24, 235, 24, 96, 152, 32, 24, 34, 24, 198, 24, 144, 24, 148, + 24, 62, 24, 120, 24, 143, 24, 58, 17, 24, 102, 3, 24, 139, 24, 221, 24, 110, 24, 173, 24, 133, + 24, 222, 24, 230, 6, 24, 95, 24, 109, 24, 87, 24, 246, 24, 192, 24, 77, 24, 145, 8, 24, 152, + 24, 92, 24, 179, 24, 27, 24, 159, 152, 32, 24, 117, 24, 91, 24, 53, 24, 150, 24, 203, 24, 95, + 24, 157, 2, 1, 24, 221, 24, 201, 24, 153, 24, 226, 24, 114, 24, 81, 24, 24, 24, 45, 24, 217, + 24, 252, 24, 41, 24, 243, 24, 157, 24, 159, 24, 34, 24, 101, 24, 225, 24, 117, 24, 113, 24, + 216, 24, 246, 24, 107, 24, 224, 152, 32, 24, 78, 24, 78, 24, 46, 24, 90, 24, 30, 24, 41, 24, + 197, 24, 147, 24, 226, 24, 104, 24, 186, 24, 174, 24, 52, 24, 142, 24, 79, 24, 252, 24, 124, + 24, 57, 24, 162, 5, 24, 71, 24, 72, 24, 85, 24, 119, 24, 240, 24, 137, 24, 217, 24, 171, 24, + 27, 24, 146, 24, 231, 24, 242, 152, 32, 24, 155, 24, 136, 24, 177, 24, 251, 24, 133, 24, 160, + 18, 24, 219, 24, 179, 20, 24, 153, 15, 24, 119, 24, 203, 24, 194, 24, 165, 24, 44, 14, 24, 49, + 24, 158, 24, 233, 24, 232, 24, 79, 24, 141, 6, 24, 117, 24, 103, 24, 83, 24, 25, 24, 37, 24, + 223, 24, 252, 152, 32, 24, 206, 24, 252, 24, 45, 24, 231, 24, 213, 24, 169, 24, 207, 15, 24, + 107, 24, 246, 24, 210, 24, 26, 24, 243, 24, 201, 24, 25, 24, 186, 24, 51, 24, 200, 24, 54, 24, + 76, 24, 253, 24, 42, 24, 75, 15, 0, 24, 114, 24, 103, 24, 181, 24, 43, 24, 123, 24, 208, 24, + 85, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 135, 152, 32, 24, 244, 24, + 34, 24, 65, 24, 99, 24, 40, 24, 216, 24, 47, 24, 113, 24, 171, 24, 114, 24, 227, 24, 108, 24, + 230, 13, 24, 111, 9, 24, 59, 24, 216, 17, 22, 24, 144, 24, 135, 24, 255, 24, 196, 24, 54, 24, + 232, 24, 212, 24, 215, 24, 178, 24, 101, 24, 116, 24, 41, 152, 32, 24, 247, 24, 177, 24, 171, + 24, 196, 24, 236, 24, 213, 24, 224, 24, 66, 24, 187, 24, 234, 24, 61, 24, 218, 10, 24, 218, 24, + 134, 24, 130, 24, 91, 24, 197, 24, 154, 14, 24, 98, 24, 192, 24, 116, 24, 51, 24, 169, 24, 171, + 24, 165, 24, 181, 24, 193, 24, 48, 24, 49, 24, 168, 152, 32, 24, 92, 24, 48, 1, 24, 125, 24, + 227, 24, 101, 24, 150, 24, 47, 24, 196, 24, 165, 24, 163, 24, 148, 24, 126, 24, 52, 24, 147, + 24, 207, 24, 57, 24, 90, 24, 242, 10, 24, 39, 24, 157, 24, 53, 24, 164, 24, 175, 24, 174, 24, + 123, 24, 248, 24, 75, 24, 192, 24, 92, 24, 98, 152, 32, 24, 100, 24, 214, 24, 44, 24, 238, 24, + 35, 24, 223, 24, 200, 24, 144, 3, 24, 154, 24, 158, 24, 59, 24, 189, 24, 240, 24, 142, 24, 141, + 24, 229, 24, 232, 24, 30, 24, 48, 24, 202, 24, 179, 24, 184, 24, 34, 24, 101, 24, 222, 24, 91, + 24, 178, 24, 196, 24, 209, 24, 141, 24, 74, 152, 32, 24, 203, 24, 161, 24, 153, 24, 238, 24, + 137, 24, 216, 24, 215, 24, 41, 24, 48, 24, 49, 2, 16, 24, 222, 24, 201, 6, 24, 188, 24, 147, + 24, 167, 24, 192, 24, 67, 24, 255, 24, 163, 24, 81, 24, 46, 24, 88, 24, 205, 24, 41, 24, 116, + 24, 100, 24, 84, 24, 194, 24, 86, 152, 32, 24, 59, 24, 168, 24, 35, 24, 34, 24, 169, 24, 31, + 24, 223, 8, 24, 40, 24, 170, 24, 155, 24, 220, 24, 93, 21, 24, 152, 24, 39, 24, 65, 8, 24, 212, + 24, 165, 24, 141, 24, 210, 24, 169, 24, 245, 24, 163, 24, 229, 24, 76, 12, 24, 141, 24, 165, + 24, 133, 24, 30, 152, 32, 21, 24, 250, 8, 24, 215, 24, 64, 24, 189, 24, 128, 24, 129, 24, 228, + 24, 222, 24, 77, 24, 184, 24, 227, 24, 54, 24, 128, 24, 28, 24, 176, 24, 178, 1, 24, 70, 3, 24, + 127, 24, 82, 24, 135, 24, 200, 24, 77, 24, 147, 24, 247, 4, 24, 235, 24, 166, 24, 104, 161, + 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 134, 152, 32, 20, 24, 159, 24, 245, + 24, 183, 24, 103, 12, 24, 134, 24, 73, 24, 72, 24, 252, 24, 173, 24, 90, 24, 55, 24, 29, 24, + 141, 7, 24, 161, 24, 167, 13, 12, 16, 24, 199, 24, 37, 24, 231, 24, 55, 7, 24, 61, 24, 162, 24, + 120, 24, 245, 8, 24, 243, 152, 32, 24, 26, 24, 41, 24, 27, 24, 33, 24, 62, 24, 147, 24, 179, + 24, 181, 24, 122, 24, 108, 24, 160, 24, 237, 24, 59, 24, 115, 24, 85, 24, 76, 24, 182, 22, 24, + 76, 24, 50, 24, 162, 24, 165, 10, 9, 24, 166, 24, 69, 24, 148, 24, 219, 24, 183, 3, 24, 133, + 24, 180, 152, 32, 24, 31, 24, 74, 24, 96, 24, 56, 4, 24, 167, 24, 107, 24, 189, 24, 179, 24, + 69, 24, 185, 24, 140, 24, 220, 24, 235, 24, 106, 24, 143, 11, 24, 207, 24, 164, 24, 60, 24, + 134, 24, 149, 24, 180, 24, 216, 24, 102, 24, 92, 24, 41, 24, 183, 24, 198, 24, 93, 0, 24, 186, + 152, 32, 24, 120, 23, 24, 29, 24, 83, 24, 178, 24, 71, 24, 243, 24, 251, 24, 39, 24, 217, 24, + 63, 24, 238, 24, 63, 24, 133, 24, 212, 22, 24, 79, 24, 178, 24, 241, 24, 51, 24, 236, 24, 169, + 24, 185, 24, 205, 24, 68, 24, 106, 24, 118, 24, 110, 24, 180, 24, 133, 24, 63, 24, 229, 152, + 32, 24, 192, 24, 66, 15, 24, 168, 24, 251, 24, 95, 24, 248, 24, 102, 24, 139, 24, 163, 24, 192, + 24, 233, 24, 111, 3, 24, 91, 24, 120, 9, 24, 146, 24, 198, 24, 157, 24, 228, 24, 57, 24, 237, + 24, 174, 24, 115, 24, 152, 24, 101, 4, 24, 151, 24, 69, 24, 194, 24, 93, 152, 32, 24, 156, 24, + 174, 24, 29, 24, 178, 24, 80, 24, 164, 24, 236, 24, 227, 24, 51, 24, 220, 24, 208, 24, 173, 24, + 151, 24, 166, 24, 37, 24, 36, 24, 192, 3, 24, 120, 24, 227, 24, 61, 24, 103, 24, 150, 24, 28, + 24, 32, 24, 108, 24, 63, 24, 31, 24, 55, 24, 137, 24, 36, 24, 114, 161, 107, 109, 101, 114, + 107, 108, 101, 95, 112, 97, 116, 104, 133, 152, 32, 24, 185, 24, 248, 24, 61, 24, 231, 24, 176, + 24, 131, 24, 32, 24, 199, 24, 230, 24, 127, 24, 88, 24, 122, 24, 52, 24, 34, 24, 123, 24, 184, + 24, 65, 24, 52, 24, 169, 24, 132, 24, 87, 24, 195, 24, 61, 24, 244, 24, 65, 24, 157, 20, 24, + 173, 24, 249, 24, 235, 24, 182, 24, 255, 152, 32, 24, 222, 24, 75, 24, 216, 24, 88, 24, 27, 6, + 24, 51, 24, 94, 24, 93, 24, 33, 24, 149, 8, 24, 185, 24, 230, 24, 66, 24, 126, 24, 170, 24, 80, + 24, 136, 24, 101, 24, 31, 24, 177, 24, 38, 24, 129, 24, 44, 24, 229, 24, 42, 24, 27, 24, 197, + 24, 106, 24, 103, 24, 33, 152, 32, 16, 24, 132, 24, 148, 24, 75, 24, 45, 24, 86, 24, 75, 24, + 254, 24, 44, 24, 127, 24, 76, 24, 117, 24, 128, 24, 63, 24, 26, 24, 212, 24, 211, 24, 117, 24, + 238, 24, 81, 24, 237, 24, 44, 24, 83, 24, 61, 24, 177, 24, 255, 24, 35, 24, 204, 24, 110, 24, + 192, 24, 28, 24, 169, 152, 32, 2, 22, 24, 48, 24, 103, 24, 51, 24, 117, 24, 197, 24, 190, 24, + 198, 24, 163, 24, 52, 24, 98, 24, 67, 24, 101, 24, 198, 24, 213, 14, 24, 211, 24, 95, 24, 175, + 24, 138, 24, 142, 24, 90, 24, 183, 24, 224, 24, 90, 24, 116, 24, 216, 24, 150, 24, 141, 24, + 126, 24, 213, 152, 32, 24, 62, 24, 231, 24, 121, 24, 151, 24, 168, 24, 28, 24, 127, 24, 123, + 24, 88, 24, 237, 24, 236, 24, 233, 24, 84, 24, 60, 24, 227, 24, 159, 24, 254, 24, 221, 24, 93, + 24, 132, 24, 41, 24, 220, 24, 236, 24, 230, 24, 68, 24, 103, 24, 142, 24, 96, 24, 117, 15, 24, + 60, 24, 246, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 132, 152, 32, 24, + 187, 24, 74, 17, 24, 212, 24, 133, 24, 69, 24, 150, 24, 200, 0, 24, 158, 17, 24, 139, 24, 109, + 24, 120, 24, 209, 24, 117, 24, 105, 24, 177, 24, 178, 24, 94, 24, 121, 24, 39, 24, 54, 24, 29, + 24, 214, 24, 225, 24, 197, 24, 215, 24, 67, 24, 26, 24, 116, 16, 152, 32, 24, 168, 21, 24, 95, + 24, 210, 24, 196, 24, 140, 22, 24, 120, 24, 116, 24, 162, 14, 24, 200, 24, 210, 24, 84, 24, + 135, 24, 230, 7, 24, 221, 24, 146, 24, 210, 24, 185, 24, 185, 24, 129, 7, 24, 72, 24, 242, 24, + 120, 24, 168, 24, 214, 24, 34, 24, 66, 24, 71, 152, 32, 24, 208, 24, 220, 16, 4, 24, 60, 24, + 240, 24, 126, 24, 146, 24, 166, 24, 142, 24, 138, 24, 119, 12, 0, 24, 133, 24, 236, 24, 217, + 24, 108, 24, 196, 24, 193, 24, 90, 24, 41, 24, 57, 24, 24, 24, 216, 24, 171, 24, 78, 24, 52, + 24, 215, 24, 60, 24, 137, 24, 105, 152, 32, 24, 99, 24, 186, 24, 246, 24, 150, 24, 63, 24, 185, + 24, 26, 24, 148, 24, 64, 24, 149, 24, 70, 24, 244, 24, 144, 24, 244, 24, 91, 24, 183, 24, 136, + 24, 67, 24, 188, 11, 24, 247, 10, 24, 234, 24, 170, 24, 59, 24, 27, 24, 141, 24, 159, 24, 38, + 24, 174, 24, 118, 24, 128, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 131, + 152, 32, 24, 183, 24, 242, 24, 227, 24, 101, 24, 80, 24, 232, 24, 65, 24, 132, 24, 255, 24, + 242, 24, 186, 24, 30, 14, 24, 218, 24, 83, 24, 249, 24, 79, 24, 213, 24, 73, 24, 206, 24, 56, + 24, 190, 24, 151, 16, 24, 188, 24, 207, 24, 101, 11, 24, 36, 24, 66, 24, 160, 19, 152, 32, 24, + 38, 24, 82, 24, 115, 24, 43, 24, 137, 24, 174, 0, 5, 24, 144, 24, 84, 24, 73, 24, 233, 2, 24, + 112, 24, 135, 24, 228, 24, 84, 6, 24, 208, 24, 250, 24, 91, 24, 63, 24, 202, 24, 201, 24, 120, + 19, 24, 118, 24, 244, 24, 213, 22, 24, 246, 24, 238, 152, 32, 24, 147, 24, 71, 24, 149, 24, + 241, 24, 246, 24, 30, 24, 224, 24, 242, 24, 65, 24, 73, 24, 85, 24, 195, 24, 148, 24, 80, 24, + 31, 24, 76, 24, 118, 24, 211, 24, 92, 24, 145, 24, 44, 24, 79, 24, 138, 24, 71, 24, 119, 16, + 24, 66, 24, 226, 24, 175, 24, 98, 24, 239, 24, 92, 118, 108, 97, 121, 101, 114, 115, 95, 101, + 118, 97, 108, 117, 97, 116, 105, 111, 110, 115, 95, 115, 121, 109, 134, 161, 101, 118, 97, 108, + 117, 101, 120, 65, 48, 120, 54, 52, 49, 55, 100, 48, 97, 53, 53, 102, 48, 98, 55, 51, 98, 54, + 100, 51, 99, 52, 97, 98, 52, 54, 98, 50, 53, 54, 100, 98, 97, 97, 54, 101, 49, 97, 54, 53, 98, + 57, 101, 56, 100, 98, 56, 55, 56, 53, 97, 56, 56, 50, 53, 54, 101, 57, 49, 101, 98, 100, 54, + 97, 99, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 56, 56, 56, 101, 51, 53, 100, + 52, 56, 55, 53, 54, 51, 49, 49, 55, 57, 56, 50, 53, 49, 101, 98, 48, 50, 55, 99, 48, 55, 51, + 49, 100, 101, 57, 97, 57, 100, 53, 49, 53, 99, 99, 52, 52, 101, 99, 101, 100, 49, 55, 51, 99, + 97, 100, 102, 49, 49, 51, 100, 53, 50, 97, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, + 54, 57, 50, 48, 50, 51, 50, 50, 102, 51, 52, 56, 101, 55, 100, 51, 102, 52, 101, 51, 99, 100, + 56, 101, 101, 97, 51, 54, 98, 50, 55, 99, 53, 102, 56, 56, 102, 100, 100, 53, 57, 55, 97, 49, + 57, 101, 56, 52, 54, 51, 48, 102, 52, 52, 51, 55, 97, 54, 57, 52, 99, 57, 56, 161, 101, 118, + 97, 108, 117, 101, 120, 64, 48, 120, 101, 56, 57, 51, 99, 50, 98, 48, 49, 49, 97, 56, 56, 49, + 52, 53, 55, 98, 53, 100, 100, 51, 53, 99, 56, 101, 49, 55, 101, 57, 100, 52, 97, 53, 50, 100, + 50, 101, 100, 100, 97, 97, 55, 48, 48, 52, 49, 53, 57, 55, 48, 51, 102, 97, 48, 98, 51, 50, + 101, 99, 97, 55, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 55, 53, 55, 99, 102, 57, + 100, 52, 52, 51, 56, 100, 49, 54, 100, 53, 53, 52, 56, 56, 48, 52, 50, 48, 48, 98, 100, 99, 97, + 49, 52, 98, 99, 98, 53, 57, 97, 56, 54, 50, 49, 57, 52, 98, 52, 48, 49, 56, 102, 57, 53, 57, + 51, 57, 101, 101, 49, 101, 102, 100, 48, 54, 54, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, + 120, 49, 57, 100, 101, 50, 56, 48, 98, 100, 97, 55, 53, 54, 56, 56, 56, 50, 55, 49, 101, 100, + 100, 49, 100, 50, 97, 54, 98, 48, 100, 101, 49, 100, 55, 57, 53, 57, 100, 100, 52, 50, 97, 56, + 51, 102, 102, 102, 57, 55, 53, 100, 53, 55, 97, 53, 57, 51, 49, 54, 97, 51, 49, 101, 113, 108, + 97, 121, 101, 114, 115, 95, 97, 117, 116, 104, 95, 112, 97, 116, 104, 115, 134, 161, 107, 109, + 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 136, 152, 32, 24, 223, 24, 243, 24, 103, 24, + 185, 24, 102, 24, 123, 24, 142, 24, 115, 24, 96, 24, 252, 24, 28, 1, 24, 253, 24, 76, 23, 24, + 254, 24, 218, 24, 47, 24, 74, 24, 242, 24, 246, 24, 223, 24, 190, 24, 195, 24, 186, 24, 50, 24, + 160, 24, 249, 24, 231, 12, 24, 118, 24, 135, 152, 32, 24, 130, 24, 89, 5, 24, 247, 24, 219, 24, + 71, 6, 0, 24, 87, 24, 143, 24, 217, 24, 153, 24, 29, 24, 240, 24, 228, 24, 240, 24, 238, 24, + 161, 24, 149, 24, 65, 24, 190, 24, 146, 24, 146, 24, 209, 24, 132, 24, 227, 24, 214, 24, 32, + 24, 34, 6, 24, 234, 7, 152, 32, 24, 244, 24, 186, 24, 197, 24, 150, 24, 44, 24, 250, 24, 182, + 24, 109, 24, 92, 24, 146, 24, 53, 24, 196, 24, 146, 24, 114, 24, 110, 24, 42, 24, 224, 24, 242, + 24, 169, 24, 62, 13, 24, 110, 24, 139, 24, 240, 24, 193, 24, 113, 24, 130, 24, 160, 18, 24, + 128, 24, 221, 24, 180, 152, 32, 24, 222, 24, 91, 24, 33, 24, 153, 24, 250, 24, 35, 24, 252, 24, + 30, 24, 165, 24, 225, 24, 68, 1, 24, 157, 24, 161, 24, 129, 24, 161, 24, 95, 24, 217, 5, 24, + 109, 24, 183, 24, 77, 24, 254, 24, 72, 24, 24, 24, 38, 24, 169, 22, 24, 76, 24, 69, 24, 142, + 24, 176, 152, 32, 24, 168, 24, 66, 24, 204, 24, 115, 24, 114, 24, 35, 17, 24, 95, 24, 254, 24, + 103, 24, 181, 24, 251, 4, 24, 125, 24, 207, 24, 122, 24, 36, 24, 231, 24, 129, 24, 78, 24, 74, + 12, 24, 244, 24, 212, 22, 24, 178, 24, 248, 3, 24, 180, 24, 168, 24, 76, 24, 153, 152, 32, 24, + 165, 11, 24, 197, 24, 73, 24, 230, 24, 104, 24, 56, 24, 95, 24, 66, 24, 91, 24, 163, 24, 212, + 24, 73, 24, 39, 3, 24, 44, 24, 85, 24, 150, 24, 101, 24, 55, 24, 235, 24, 88, 24, 229, 24, 97, + 24, 145, 24, 128, 24, 25, 24, 115, 24, 177, 24, 69, 24, 112, 24, 77, 152, 32, 24, 218, 24, 172, + 24, 126, 24, 128, 24, 132, 24, 67, 24, 231, 24, 163, 24, 88, 24, 160, 24, 192, 24, 251, 24, + 238, 24, 43, 24, 164, 24, 94, 24, 194, 24, 54, 0, 24, 159, 24, 165, 24, 151, 24, 232, 24, 184, + 24, 154, 24, 63, 24, 92, 24, 81, 24, 198, 24, 38, 24, 75, 24, 144, 152, 32, 24, 238, 24, 224, + 24, 221, 24, 54, 24, 77, 24, 239, 24, 42, 24, 188, 24, 110, 24, 64, 24, 109, 24, 213, 24, 240, + 24, 158, 24, 214, 24, 222, 13, 24, 122, 24, 96, 24, 114, 24, 237, 24, 50, 24, 111, 24, 247, 24, + 214, 24, 47, 24, 253, 24, 242, 2, 24, 219, 24, 115, 24, 88, 161, 107, 109, 101, 114, 107, 108, + 101, 95, 112, 97, 116, 104, 135, 152, 32, 24, 181, 24, 114, 21, 24, 196, 24, 239, 24, 168, 24, + 250, 24, 203, 24, 164, 24, 221, 24, 182, 0, 24, 90, 8, 24, 225, 24, 115, 23, 24, 31, 24, 43, + 24, 104, 24, 227, 24, 181, 24, 215, 24, 205, 24, 186, 24, 129, 24, 208, 24, 246, 0, 24, 204, + 24, 206, 24, 227, 152, 32, 24, 173, 24, 84, 24, 244, 24, 53, 14, 24, 253, 24, 27, 24, 216, 23, + 24, 88, 24, 227, 24, 231, 24, 231, 24, 189, 24, 60, 12, 24, 91, 24, 181, 24, 226, 24, 27, 24, + 149, 24, 127, 24, 53, 24, 119, 24, 63, 24, 184, 24, 96, 24, 155, 24, 114, 24, 109, 24, 73, 24, + 105, 152, 32, 24, 217, 24, 70, 24, 210, 24, 81, 24, 111, 24, 143, 24, 63, 24, 137, 24, 91, 24, + 107, 24, 107, 24, 96, 24, 218, 24, 84, 24, 89, 24, 160, 24, 138, 24, 114, 24, 172, 24, 242, 8, + 24, 79, 24, 218, 24, 135, 24, 71, 24, 207, 24, 40, 24, 38, 24, 103, 24, 147, 24, 203, 24, 225, + 152, 32, 24, 161, 24, 127, 24, 79, 24, 254, 24, 106, 24, 90, 9, 24, 199, 24, 59, 24, 249, 24, + 188, 24, 245, 24, 49, 24, 92, 24, 189, 24, 25, 24, 141, 24, 50, 3, 24, 235, 24, 212, 24, 94, + 24, 225, 24, 156, 24, 119, 24, 200, 24, 142, 24, 250, 24, 153, 24, 244, 24, 160, 24, 191, 152, + 32, 20, 24, 73, 24, 107, 6, 0, 24, 159, 24, 69, 24, 212, 24, 255, 1, 24, 72, 24, 200, 24, 231, + 24, 164, 24, 157, 24, 119, 24, 255, 8, 24, 210, 24, 191, 24, 236, 24, 250, 24, 244, 24, 200, + 24, 137, 24, 103, 24, 142, 24, 176, 24, 169, 24, 127, 24, 232, 24, 49, 152, 32, 24, 57, 24, + 115, 24, 142, 24, 129, 13, 24, 150, 24, 150, 24, 69, 24, 60, 24, 91, 23, 24, 240, 24, 110, 24, + 100, 24, 72, 24, 218, 24, 172, 24, 240, 15, 24, 248, 24, 106, 24, 205, 24, 209, 24, 178, 24, + 155, 24, 179, 16, 24, 132, 24, 78, 24, 218, 24, 169, 24, 56, 152, 32, 24, 219, 22, 24, 71, 24, + 233, 24, 242, 24, 222, 24, 156, 24, 99, 24, 70, 24, 236, 24, 159, 24, 204, 24, 104, 24, 218, + 24, 131, 24, 95, 24, 250, 24, 239, 24, 135, 24, 43, 24, 90, 24, 144, 24, 43, 24, 124, 24, 164, + 24, 169, 24, 76, 24, 72, 24, 168, 24, 113, 24, 127, 24, 124, 161, 107, 109, 101, 114, 107, 108, + 101, 95, 112, 97, 116, 104, 134, 152, 32, 24, 225, 24, 61, 24, 154, 24, 67, 24, 137, 24, 251, + 24, 190, 24, 26, 24, 183, 8, 24, 71, 24, 122, 8, 24, 222, 24, 60, 24, 24, 24, 181, 24, 226, 24, + 237, 24, 90, 24, 122, 7, 24, 64, 24, 97, 24, 180, 24, 124, 24, 81, 24, 56, 24, 128, 24, 112, + 24, 111, 24, 137, 152, 32, 6, 24, 88, 24, 181, 24, 245, 24, 191, 24, 108, 16, 24, 183, 24, 74, + 24, 87, 24, 134, 0, 9, 24, 219, 24, 36, 24, 200, 24, 102, 24, 240, 24, 28, 24, 58, 24, 252, 16, + 24, 190, 24, 229, 24, 60, 20, 13, 24, 179, 24, 131, 24, 118, 24, 44, 24, 228, 152, 32, 24, 68, + 24, 136, 24, 215, 9, 24, 137, 24, 219, 24, 86, 22, 24, 208, 24, 106, 24, 102, 14, 24, 186, 24, + 108, 24, 134, 24, 132, 20, 24, 72, 24, 107, 10, 24, 35, 24, 191, 24, 44, 24, 218, 24, 190, 24, + 188, 3, 3, 24, 201, 24, 190, 19, 24, 38, 152, 32, 24, 221, 24, 167, 24, 236, 24, 86, 24, 87, + 24, 244, 24, 88, 24, 170, 24, 208, 24, 171, 24, 133, 24, 235, 24, 38, 24, 166, 5, 24, 103, 24, + 96, 24, 103, 24, 117, 24, 73, 24, 44, 24, 164, 24, 94, 24, 184, 24, 174, 24, 117, 24, 173, 24, + 33, 24, 43, 24, 73, 24, 219, 24, 180, 152, 32, 24, 148, 24, 36, 24, 217, 24, 209, 24, 124, 24, + 41, 24, 117, 24, 35, 15, 24, 118, 24, 254, 24, 187, 24, 95, 24, 223, 24, 71, 24, 121, 24, 48, + 24, 81, 24, 215, 24, 59, 24, 244, 24, 211, 24, 40, 14, 24, 229, 15, 3, 24, 37, 24, 163, 24, + 119, 24, 191, 24, 178, 152, 32, 24, 253, 24, 163, 24, 218, 2, 24, 224, 24, 216, 24, 254, 24, + 235, 24, 216, 24, 179, 5, 24, 54, 24, 65, 24, 248, 24, 93, 13, 24, 59, 24, 150, 24, 26, 24, + 101, 24, 163, 24, 124, 24, 115, 24, 44, 24, 226, 24, 152, 24, 98, 24, 211, 24, 34, 24, 226, 24, + 155, 24, 27, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 133, 152, 32, 24, + 63, 10, 24, 59, 24, 86, 24, 104, 24, 157, 24, 52, 24, 52, 24, 127, 24, 49, 24, 238, 24, 157, 2, + 24, 43, 9, 24, 210, 24, 224, 24, 54, 24, 187, 24, 113, 24, 239, 24, 242, 24, 250, 24, 238, 24, + 220, 24, 150, 24, 62, 24, 84, 24, 189, 21, 24, 114, 24, 67, 152, 32, 24, 202, 24, 236, 8, 24, + 234, 24, 165, 24, 94, 24, 51, 14, 24, 185, 22, 24, 52, 24, 63, 24, 177, 24, 158, 24, 90, 24, + 102, 24, 92, 24, 102, 16, 24, 43, 24, 101, 24, 77, 13, 24, 221, 24, 186, 24, 166, 24, 51, 24, + 141, 24, 134, 12, 24, 186, 24, 123, 152, 32, 12, 24, 55, 24, 198, 24, 84, 16, 1, 24, 231, 9, + 24, 75, 24, 47, 24, 210, 24, 112, 24, 75, 24, 140, 24, 222, 24, 215, 24, 50, 24, 151, 24, 132, + 24, 28, 24, 92, 24, 174, 17, 24, 94, 24, 194, 24, 217, 24, 217, 24, 24, 24, 209, 24, 255, 24, + 116, 24, 79, 152, 32, 24, 155, 24, 111, 24, 60, 24, 200, 24, 100, 24, 226, 24, 142, 24, 126, + 24, 73, 24, 229, 24, 252, 24, 95, 24, 171, 24, 183, 24, 67, 24, 28, 24, 222, 24, 72, 24, 146, + 24, 204, 24, 181, 24, 50, 4, 24, 118, 24, 55, 24, 117, 24, 24, 24, 87, 24, 241, 24, 44, 24, + 164, 24, 248, 152, 32, 24, 104, 24, 124, 24, 35, 24, 63, 24, 177, 24, 192, 24, 161, 24, 157, + 24, 192, 21, 14, 24, 198, 24, 186, 24, 232, 24, 245, 24, 131, 24, 91, 24, 119, 24, 32, 24, 190, + 24, 198, 24, 222, 24, 171, 24, 255, 24, 140, 24, 93, 24, 51, 24, 188, 24, 47, 24, 105, 24, 193, + 24, 199, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 132, 152, 32, 24, 228, + 24, 59, 24, 164, 24, 199, 22, 24, 206, 2, 24, 158, 24, 158, 24, 133, 24, 63, 24, 174, 24, 159, + 24, 238, 24, 133, 24, 200, 24, 110, 24, 203, 24, 123, 24, 130, 24, 195, 24, 104, 24, 158, 24, + 67, 24, 66, 24, 57, 24, 146, 24, 169, 13, 24, 34, 24, 219, 24, 106, 152, 32, 24, 111, 24, 211, + 24, 41, 24, 59, 24, 28, 24, 30, 24, 89, 24, 234, 24, 211, 4, 24, 52, 24, 158, 24, 90, 24, 164, + 24, 30, 24, 176, 24, 231, 24, 187, 24, 188, 24, 153, 24, 88, 24, 246, 4, 9, 24, 77, 12, 24, 28, + 24, 112, 24, 221, 24, 111, 6, 24, 76, 152, 32, 24, 30, 24, 92, 24, 199, 24, 50, 24, 173, 24, + 149, 24, 137, 5, 24, 107, 15, 22, 24, 113, 24, 69, 24, 40, 24, 171, 24, 151, 24, 37, 24, 36, + 24, 158, 24, 170, 24, 162, 24, 51, 24, 153, 24, 123, 24, 24, 24, 171, 24, 81, 24, 253, 24, 132, + 2, 24, 245, 24, 243, 152, 32, 24, 88, 0, 24, 118, 24, 232, 24, 65, 24, 118, 20, 24, 229, 24, + 81, 24, 37, 24, 31, 24, 201, 24, 162, 24, 205, 24, 39, 24, 62, 24, 192, 24, 125, 24, 194, 24, + 138, 24, 86, 24, 42, 24, 207, 24, 197, 24, 149, 24, 187, 24, 106, 24, 204, 24, 200, 0, 11, 24, + 144, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 131, 152, 32, 24, 132, 24, + 200, 24, 171, 24, 200, 24, 122, 24, 194, 24, 231, 24, 61, 2, 24, 109, 24, 184, 1, 24, 85, 24, + 45, 24, 189, 24, 187, 24, 167, 24, 28, 24, 156, 24, 255, 24, 43, 24, 81, 24, 55, 24, 125, 24, + 134, 24, 242, 24, 175, 14, 24, 79, 24, 133, 24, 225, 24, 55, 152, 32, 24, 189, 24, 222, 24, + 137, 24, 133, 24, 74, 24, 181, 24, 245, 24, 59, 24, 191, 24, 134, 24, 78, 24, 189, 24, 83, 24, + 196, 24, 32, 24, 215, 24, 227, 24, 133, 15, 24, 60, 24, 128, 24, 253, 24, 90, 22, 24, 111, 24, + 221, 24, 111, 24, 84, 24, 157, 24, 30, 24, 160, 24, 53, 152, 32, 24, 224, 24, 167, 24, 224, 24, + 94, 24, 117, 24, 227, 24, 202, 24, 49, 14, 24, 153, 24, 231, 24, 232, 24, 129, 24, 222, 18, 24, + 74, 24, 50, 24, 62, 24, 81, 24, 243, 24, 109, 24, 81, 0, 24, 162, 24, 234, 24, 199, 24, 144, + 24, 110, 24, 153, 24, 182, 24, 116, 24, 159, 114, 108, 97, 121, 101, 114, 115, 95, 101, 118, + 97, 108, 117, 97, 116, 105, 111, 110, 115, 134, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, + 120, 51, 54, 49, 51, 101, 97, 102, 99, 57, 51, 101, 101, 55, 53, 101, 56, 57, 53, 98, 101, 56, + 51, 56, 51, 54, 101, 48, 97, 100, 99, 57, 97, 101, 98, 54, 102, 56, 99, 51, 99, 100, 98, 57, + 48, 51, 51, 97, 52, 50, 57, 97, 57, 51, 57, 102, 57, 48, 53, 97, 52, 97, 100, 52, 161, 101, + 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 51, 101, 56, 54, 51, 100, 55, 98, 56, 51, 99, 52, + 101, 55, 54, 99, 50, 56, 102, 48, 52, 49, 102, 98, 101, 51, 51, 97, 52, 55, 54, 53, 49, 102, + 52, 99, 57, 49, 100, 53, 55, 99, 55, 51, 100, 48, 56, 97, 97, 102, 52, 102, 49, 51, 57, 53, 49, + 100, 52, 99, 97, 56, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 97, 52, 56, 100, 52, + 54, 49, 57, 55, 52, 48, 56, 57, 100, 101, 54, 48, 97, 55, 97, 53, 56, 101, 52, 53, 98, 54, 54, + 101, 100, 101, 57, 56, 99, 100, 54, 49, 51, 100, 49, 102, 54, 98, 56, 55, 50, 49, 53, 54, 52, + 53, 48, 48, 53, 102, 55, 97, 102, 54, 102, 100, 97, 161, 101, 118, 97, 108, 117, 101, 120, 65, + 48, 120, 50, 50, 56, 57, 56, 53, 101, 55, 55, 51, 97, 52, 55, 48, 52, 98, 48, 54, 53, 51, 98, + 100, 52, 53, 98, 56, 102, 53, 100, 53, 53, 51, 55, 53, 98, 50, 52, 101, 51, 48, 57, 98, 56, 98, + 49, 98, 100, 97, 98, 55, 52, 51, 50, 56, 49, 100, 100, 52, 99, 50, 49, 99, 52, 161, 101, 118, + 97, 108, 117, 101, 120, 65, 48, 120, 49, 50, 102, 99, 55, 56, 97, 54, 97, 51, 100, 50, 102, 57, + 102, 97, 102, 55, 54, 52, 97, 48, 52, 51, 51, 55, 101, 54, 102, 98, 97, 99, 98, 48, 49, 102, + 102, 97, 53, 101, 52, 49, 49, 57, 56, 57, 98, 52, 48, 97, 51, 49, 54, 57, 101, 98, 99, 100, 49, + 49, 102, 101, 102, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 53, 53, 56, 55, 99, 99, + 101, 55, 53, 51, 55, 51, 57, 56, 57, 48, 102, 53, 56, 48, 100, 102, 101, 102, 53, 99, 102, 102, + 99, 55, 99, 53, 52, 48, 101, 49, 49, 54, 101, 100, 57, 102, 49, 101, 54, 57, 100, 99, 102, 99, + 97, 98, 54, 102, 102, 54, 99, 54, 52, 99, 101, 57, 102, 164, 117, 108, 97, 121, 101, 114, 115, + 95, 97, 117, 116, 104, 95, 112, 97, 116, 104, 115, 95, 115, 121, 109, 134, 161, 107, 109, 101, + 114, 107, 108, 101, 95, 112, 97, 116, 104, 136, 152, 32, 24, 137, 15, 24, 25, 24, 91, 24, 91, + 24, 83, 24, 163, 3, 4, 24, 166, 24, 63, 24, 79, 24, 49, 24, 218, 24, 67, 24, 223, 24, 52, 24, + 46, 24, 90, 24, 58, 24, 63, 24, 239, 24, 139, 6, 24, 206, 24, 237, 24, 222, 24, 203, 23, 24, + 220, 24, 92, 24, 58, 152, 32, 24, 104, 3, 24, 53, 24, 151, 24, 97, 24, 43, 24, 246, 24, 161, + 24, 168, 24, 58, 24, 139, 24, 235, 24, 32, 24, 196, 24, 129, 24, 40, 24, 219, 3, 24, 127, 24, + 254, 24, 189, 24, 159, 24, 39, 24, 233, 24, 241, 24, 188, 24, 105, 24, 234, 24, 63, 24, 45, 24, + 32, 24, 28, 152, 32, 24, 197, 24, 171, 24, 147, 24, 224, 24, 214, 24, 172, 24, 37, 4, 24, 202, + 24, 82, 24, 180, 24, 140, 24, 120, 24, 225, 24, 94, 24, 143, 24, 42, 24, 139, 24, 55, 24, 190, + 24, 165, 24, 109, 15, 24, 240, 24, 47, 24, 109, 24, 32, 24, 250, 24, 175, 24, 111, 24, 28, 24, + 141, 152, 32, 24, 65, 24, 77, 24, 48, 24, 54, 24, 199, 24, 52, 24, 229, 24, 237, 24, 103, 24, + 45, 19, 24, 184, 24, 129, 24, 158, 24, 86, 24, 28, 24, 96, 24, 106, 24, 187, 24, 89, 24, 246, + 24, 253, 3, 24, 248, 24, 25, 24, 121, 1, 24, 108, 24, 47, 24, 254, 24, 60, 24, 178, 152, 32, + 24, 144, 24, 103, 24, 71, 24, 114, 24, 179, 24, 224, 24, 246, 24, 121, 24, 185, 24, 86, 24, + 176, 24, 89, 24, 131, 24, 149, 24, 252, 16, 24, 110, 24, 108, 24, 201, 24, 198, 24, 211, 24, + 137, 24, 63, 24, 176, 24, 221, 24, 234, 24, 97, 24, 65, 24, 86, 24, 205, 24, 74, 24, 229, 152, + 32, 5, 24, 179, 24, 105, 24, 167, 24, 193, 24, 131, 24, 102, 16, 24, 228, 7, 7, 24, 110, 24, + 163, 24, 74, 24, 75, 24, 220, 24, 133, 24, 203, 24, 230, 24, 236, 24, 189, 4, 24, 59, 2, 24, + 37, 24, 118, 24, 117, 24, 42, 24, 245, 24, 146, 24, 52, 24, 168, 152, 32, 24, 71, 24, 165, 24, + 111, 24, 127, 24, 83, 24, 167, 24, 167, 24, 247, 24, 103, 24, 150, 24, 114, 24, 45, 24, 222, + 24, 32, 7, 24, 250, 24, 169, 24, 114, 24, 50, 24, 164, 24, 42, 24, 54, 24, 241, 24, 182, 3, 24, + 154, 24, 56, 24, 170, 23, 24, 66, 24, 191, 24, 25, 152, 32, 24, 206, 24, 252, 24, 45, 24, 231, + 24, 213, 24, 169, 24, 207, 15, 24, 107, 24, 246, 24, 210, 24, 26, 24, 243, 24, 201, 24, 25, 24, + 186, 24, 51, 24, 200, 24, 54, 24, 76, 24, 253, 24, 42, 24, 75, 15, 0, 24, 114, 24, 103, 24, + 181, 24, 43, 24, 123, 24, 208, 24, 85, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, + 116, 104, 135, 152, 32, 24, 166, 24, 251, 24, 99, 24, 91, 24, 104, 24, 57, 24, 96, 24, 72, 24, + 255, 24, 134, 24, 180, 24, 142, 24, 105, 24, 198, 24, 105, 24, 149, 24, 129, 24, 119, 24, 251, + 24, 244, 24, 118, 24, 57, 24, 182, 24, 38, 3, 22, 24, 87, 24, 95, 24, 173, 24, 89, 24, 29, 24, + 82, 152, 32, 24, 198, 5, 24, 25, 24, 189, 24, 28, 24, 154, 24, 255, 24, 145, 24, 46, 24, 239, + 24, 214, 24, 33, 24, 119, 24, 26, 24, 60, 24, 241, 24, 167, 24, 98, 16, 24, 215, 24, 120, 24, + 226, 3, 24, 187, 24, 230, 24, 26, 24, 101, 24, 243, 24, 136, 24, 179, 24, 159, 24, 157, 152, + 32, 24, 68, 24, 106, 24, 255, 24, 221, 24, 196, 12, 24, 94, 24, 117, 10, 24, 198, 24, 201, 24, + 66, 24, 49, 24, 131, 24, 48, 24, 218, 24, 239, 24, 35, 24, 127, 24, 211, 24, 140, 24, 61, 24, + 130, 24, 98, 24, 182, 18, 24, 203, 24, 108, 24, 254, 24, 106, 24, 254, 24, 50, 152, 32, 8, 24, + 104, 24, 175, 24, 78, 24, 172, 24, 30, 24, 151, 24, 232, 24, 144, 24, 204, 24, 187, 21, 24, + 211, 24, 218, 24, 52, 24, 181, 24, 103, 24, 95, 24, 148, 24, 80, 24, 186, 24, 249, 24, 243, 24, + 119, 24, 159, 24, 212, 24, 37, 24, 130, 24, 57, 24, 33, 4, 24, 87, 152, 32, 24, 54, 24, 109, 4, + 24, 86, 24, 120, 24, 168, 24, 172, 24, 238, 24, 143, 24, 115, 24, 157, 12, 24, 37, 10, 24, 150, + 24, 212, 24, 115, 20, 24, 152, 24, 108, 24, 247, 24, 230, 24, 63, 24, 253, 24, 205, 24, 95, 24, + 45, 24, 39, 24, 166, 24, 62, 24, 34, 14, 152, 32, 24, 76, 24, 252, 23, 24, 127, 24, 248, 24, + 59, 24, 143, 24, 38, 9, 24, 59, 0, 24, 92, 24, 228, 24, 57, 24, 60, 24, 247, 24, 98, 24, 156, + 24, 140, 23, 24, 158, 24, 27, 24, 147, 24, 149, 24, 32, 24, 80, 24, 56, 24, 139, 24, 176, 24, + 114, 24, 159, 24, 74, 152, 32, 24, 219, 22, 24, 71, 24, 233, 24, 242, 24, 222, 24, 156, 24, 99, + 24, 70, 24, 236, 24, 159, 24, 204, 24, 104, 24, 218, 24, 131, 24, 95, 24, 250, 24, 239, 24, + 135, 24, 43, 24, 90, 24, 144, 24, 43, 24, 124, 24, 164, 24, 169, 24, 76, 24, 72, 24, 168, 24, + 113, 24, 127, 24, 124, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 134, 152, + 32, 24, 252, 24, 210, 24, 198, 24, 221, 24, 84, 17, 24, 254, 24, 250, 24, 64, 24, 56, 24, 113, + 24, 32, 24, 52, 24, 217, 24, 136, 24, 86, 24, 217, 24, 178, 24, 198, 5, 24, 142, 22, 24, 192, + 5, 24, 117, 24, 68, 3, 24, 137, 24, 146, 24, 29, 24, 47, 24, 160, 152, 32, 24, 228, 24, 152, + 24, 122, 24, 78, 24, 194, 24, 63, 24, 233, 24, 225, 24, 225, 24, 89, 24, 119, 24, 168, 4, 24, + 179, 24, 36, 24, 190, 24, 55, 24, 141, 24, 93, 24, 241, 24, 57, 24, 78, 24, 100, 24, 227, 24, + 30, 24, 30, 24, 80, 24, 174, 24, 46, 24, 216, 24, 118, 24, 243, 152, 32, 24, 80, 24, 168, 24, + 99, 24, 80, 24, 174, 24, 140, 24, 228, 24, 173, 24, 217, 24, 195, 24, 230, 24, 51, 24, 92, 24, + 212, 24, 27, 24, 151, 24, 184, 24, 176, 24, 139, 24, 165, 24, 234, 24, 193, 24, 144, 24, 255, + 24, 40, 24, 231, 6, 24, 243, 24, 115, 24, 110, 5, 7, 152, 32, 24, 221, 17, 24, 221, 24, 185, + 24, 255, 24, 114, 24, 187, 24, 64, 1, 24, 70, 24, 159, 24, 65, 24, 134, 24, 79, 18, 24, 81, 24, + 180, 24, 130, 24, 226, 24, 249, 24, 62, 24, 72, 24, 37, 22, 24, 124, 24, 102, 24, 251, 24, 69, + 24, 186, 24, 232, 24, 248, 22, 152, 32, 24, 28, 24, 205, 22, 24, 187, 24, 99, 24, 171, 24, 37, + 24, 28, 24, 241, 24, 120, 23, 11, 24, 157, 22, 24, 27, 24, 50, 24, 65, 24, 49, 24, 27, 24, 237, + 24, 203, 24, 154, 24, 143, 24, 226, 24, 60, 24, 95, 10, 24, 187, 24, 201, 24, 49, 24, 108, 24, + 64, 152, 32, 24, 253, 24, 163, 24, 218, 2, 24, 224, 24, 216, 24, 254, 24, 235, 24, 216, 24, + 179, 5, 24, 54, 24, 65, 24, 248, 24, 93, 13, 24, 59, 24, 150, 24, 26, 24, 101, 24, 163, 24, + 124, 24, 115, 24, 44, 24, 226, 24, 152, 24, 98, 24, 211, 24, 34, 24, 226, 24, 155, 24, 27, 161, + 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 133, 152, 32, 24, 198, 24, 136, 24, + 185, 24, 151, 24, 190, 24, 63, 24, 69, 24, 172, 24, 217, 24, 166, 24, 210, 24, 228, 24, 230, + 24, 32, 24, 102, 24, 147, 24, 240, 5, 24, 166, 24, 105, 24, 149, 24, 80, 24, 249, 24, 30, 3, + 24, 24, 24, 62, 24, 212, 24, 97, 24, 229, 24, 111, 24, 117, 152, 32, 24, 72, 10, 24, 232, 24, + 244, 24, 166, 24, 171, 24, 221, 24, 140, 24, 233, 24, 232, 24, 254, 24, 231, 24, 145, 24, 199, + 8, 24, 142, 24, 27, 21, 24, 125, 24, 235, 24, 219, 1, 24, 140, 24, 103, 24, 144, 24, 180, 24, + 189, 24, 168, 24, 191, 24, 70, 24, 56, 24, 93, 152, 32, 24, 97, 24, 32, 24, 162, 24, 121, 24, + 98, 24, 102, 16, 24, 245, 24, 82, 24, 26, 24, 75, 24, 57, 19, 24, 244, 24, 86, 24, 122, 24, 91, + 24, 83, 24, 33, 24, 145, 24, 121, 24, 237, 6, 24, 111, 18, 24, 108, 24, 76, 24, 81, 24, 205, + 24, 186, 24, 70, 24, 45, 152, 32, 24, 155, 24, 111, 24, 60, 24, 200, 24, 100, 24, 226, 24, 142, + 24, 126, 24, 73, 24, 229, 24, 252, 24, 95, 24, 171, 24, 183, 24, 67, 24, 28, 24, 222, 24, 72, + 24, 146, 24, 204, 24, 181, 24, 50, 4, 24, 118, 24, 55, 24, 117, 24, 24, 24, 87, 24, 241, 24, + 44, 24, 164, 24, 248, 152, 32, 24, 104, 24, 124, 24, 35, 24, 63, 24, 177, 24, 192, 24, 161, 24, + 157, 24, 192, 21, 14, 24, 198, 24, 186, 24, 232, 24, 245, 24, 131, 24, 91, 24, 119, 24, 32, 24, + 190, 24, 198, 24, 222, 24, 171, 24, 255, 24, 140, 24, 93, 24, 51, 24, 188, 24, 47, 24, 105, 24, + 193, 24, 199, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 132, 152, 32, 24, + 128, 24, 51, 24, 84, 24, 228, 24, 100, 24, 184, 24, 162, 24, 156, 24, 153, 9, 24, 192, 24, 86, + 24, 111, 24, 247, 24, 111, 24, 235, 18, 24, 74, 24, 39, 24, 88, 24, 137, 24, 101, 24, 32, 24, + 237, 24, 97, 24, 190, 24, 30, 24, 219, 24, 149, 24, 91, 24, 82, 24, 153, 152, 32, 24, 226, 24, + 119, 24, 82, 24, 82, 24, 53, 24, 150, 24, 173, 24, 107, 24, 252, 24, 124, 24, 38, 24, 195, 24, + 37, 24, 73, 24, 46, 24, 144, 24, 109, 24, 212, 24, 175, 24, 183, 24, 109, 24, 58, 24, 191, 4, + 24, 97, 24, 198, 24, 191, 24, 172, 24, 79, 24, 85, 24, 148, 24, 78, 152, 32, 24, 156, 24, 71, + 24, 157, 3, 24, 116, 24, 28, 24, 92, 24, 83, 13, 24, 122, 24, 237, 24, 117, 24, 236, 10, 24, + 232, 20, 24, 132, 24, 193, 24, 119, 24, 254, 24, 162, 24, 32, 24, 228, 24, 58, 24, 168, 24, + 160, 24, 94, 24, 161, 24, 178, 19, 24, 112, 24, 61, 152, 32, 24, 99, 24, 186, 24, 246, 24, 150, + 24, 63, 24, 185, 24, 26, 24, 148, 24, 64, 24, 149, 24, 70, 24, 244, 24, 144, 24, 244, 24, 91, + 24, 183, 24, 136, 24, 67, 24, 188, 11, 24, 247, 10, 24, 234, 24, 170, 24, 59, 24, 27, 24, 141, + 24, 159, 24, 38, 24, 174, 24, 118, 24, 128, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, + 97, 116, 104, 131, 152, 32, 24, 65, 24, 157, 24, 111, 24, 229, 24, 63, 24, 239, 24, 69, 24, 65, + 24, 214, 24, 150, 24, 207, 19, 24, 59, 24, 171, 24, 44, 24, 231, 24, 98, 24, 201, 24, 171, 24, + 215, 24, 67, 24, 33, 24, 226, 24, 225, 24, 177, 24, 170, 16, 24, 80, 24, 134, 24, 160, 24, 134, + 24, 28, 152, 32, 4, 24, 49, 24, 223, 24, 250, 24, 138, 8, 15, 24, 97, 24, 149, 24, 140, 2, 24, + 107, 24, 70, 24, 124, 24, 147, 24, 173, 24, 50, 24, 176, 24, 85, 24, 34, 24, 99, 24, 104, 24, + 60, 24, 219, 24, 187, 24, 131, 2, 24, 184, 24, 226, 24, 42, 24, 189, 24, 117, 152, 32, 24, 224, + 24, 167, 24, 224, 24, 94, 24, 117, 24, 227, 24, 202, 24, 49, 14, 24, 153, 24, 231, 24, 232, 24, + 129, 24, 222, 18, 24, 74, 24, 50, 24, 62, 24, 81, 24, 243, 24, 109, 24, 81, 0, 24, 162, 24, + 234, 24, 199, 24, 144, 24, 110, 24, 153, 24, 182, 24, 116, 24, 159, 118, 108, 97, 121, 101, + 114, 115, 95, 101, 118, 97, 108, 117, 97, 116, 105, 111, 110, 115, 95, 115, 121, 109, 134, 161, + 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 55, 48, 99, 48, 51, 53, 54, 55, 57, 98, 98, + 56, 99, 53, 101, 51, 100, 48, 100, 101, 56, 102, 54, 53, 51, 54, 101, 48, 102, 98, 56, 50, 55, + 56, 102, 102, 50, 99, 50, 53, 55, 55, 98, 102, 101, 55, 52, 57, 56, 101, 55, 56, 52, 97, 98, + 56, 56, 101, 54, 98, 49, 100, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 52, 99, + 53, 54, 51, 99, 100, 54, 55, 53, 99, 102, 51, 56, 48, 51, 51, 50, 52, 48, 97, 51, 52, 51, 50, + 49, 51, 98, 51, 97, 48, 48, 102, 55, 51, 52, 100, 56, 52, 52, 48, 101, 55, 98, 51, 99, 55, 55, + 57, 50, 102, 51, 99, 57, 97, 102, 54, 54, 102, 100, 49, 97, 161, 101, 118, 97, 108, 117, 101, + 120, 65, 48, 120, 55, 100, 101, 50, 48, 54, 97, 100, 99, 98, 99, 54, 101, 51, 52, 100, 48, 102, + 56, 100, 52, 48, 56, 97, 52, 49, 52, 51, 53, 55, 100, 57, 51, 57, 55, 101, 48, 57, 54, 100, 55, + 98, 101, 56, 48, 56, 48, 57, 48, 49, 98, 48, 53, 99, 56, 54, 48, 97, 102, 98, 97, 99, 97, 161, + 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 57, 101, 57, 48, 100, 102, 55, 56, 51, 57, + 102, 99, 50, 102, 48, 57, 98, 57, 53, 55, 98, 101, 50, 54, 48, 50, 54, 98, 55, 49, 48, 99, 98, + 98, 50, 53, 97, 98, 101, 57, 56, 100, 50, 98, 55, 51, 101, 50, 50, 54, 57, 100, 55, 52, 54, + 102, 49, 102, 53, 53, 102, 52, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 100, 97, + 98, 54, 51, 51, 57, 55, 54, 57, 102, 56, 101, 56, 57, 97, 50, 49, 99, 48, 51, 54, 50, 101, 57, + 52, 101, 102, 52, 48, 56, 99, 48, 57, 49, 99, 99, 100, 97, 57, 53, 52, 56, 53, 48, 100, 54, 50, + 53, 50, 51, 54, 97, 56, 48, 100, 54, 99, 57, 53, 55, 101, 161, 101, 118, 97, 108, 117, 101, + 120, 65, 48, 120, 53, 100, 49, 55, 53, 102, 53, 51, 54, 57, 48, 52, 101, 99, 99, 54, 55, 55, + 100, 50, 57, 100, 53, 99, 56, 53, 100, 56, 100, 53, 54, 55, 98, 98, 55, 102, 54, 102, 97, 56, + 101, 51, 56, 56, 52, 51, 57, 52, 101, 100, 102, 56, 101, 102, 55, 50, 99, 97, 52, 48, 53, 97, + 98, 113, 108, 97, 121, 101, 114, 115, 95, 97, 117, 116, 104, 95, 112, 97, 116, 104, 115, 134, + 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 136, 152, 32, 8, 24, 242, 24, + 148, 24, 114, 24, 166, 7, 24, 118, 24, 173, 24, 132, 24, 205, 24, 58, 24, 106, 5, 24, 241, 24, + 52, 12, 24, 71, 24, 214, 24, 144, 24, 224, 24, 137, 24, 140, 24, 191, 24, 136, 24, 139, 24, + 160, 24, 227, 24, 101, 24, 165, 24, 220, 8, 24, 39, 152, 32, 24, 144, 24, 90, 24, 115, 24, 230, + 18, 24, 69, 24, 108, 9, 24, 150, 24, 221, 21, 24, 234, 9, 24, 137, 24, 211, 24, 92, 24, 222, + 24, 226, 24, 216, 24, 74, 24, 46, 24, 84, 24, 244, 24, 250, 24, 252, 17, 24, 210, 24, 151, 24, + 25, 24, 60, 24, 61, 24, 142, 152, 32, 24, 124, 24, 192, 24, 251, 24, 132, 24, 173, 24, 31, 24, + 52, 24, 140, 24, 49, 24, 50, 24, 116, 24, 178, 24, 32, 24, 210, 24, 43, 24, 119, 24, 90, 24, + 179, 24, 160, 24, 72, 5, 24, 220, 24, 171, 24, 134, 24, 181, 24, 169, 24, 31, 24, 133, 24, 186, + 24, 45, 24, 180, 24, 150, 152, 32, 24, 164, 4, 24, 89, 24, 209, 24, 116, 24, 152, 24, 171, 24, + 241, 24, 243, 6, 24, 58, 24, 206, 24, 138, 24, 116, 24, 56, 24, 62, 24, 146, 24, 130, 24, 49, + 13, 24, 155, 24, 84, 24, 193, 24, 60, 18, 24, 101, 24, 162, 24, 248, 24, 223, 24, 91, 24, 198, + 24, 104, 152, 32, 24, 114, 24, 134, 24, 230, 21, 24, 110, 24, 235, 24, 204, 24, 172, 24, 43, + 15, 24, 127, 12, 24, 153, 24, 50, 24, 226, 24, 33, 24, 60, 24, 235, 24, 225, 24, 155, 24, 42, + 24, 173, 24, 122, 24, 29, 24, 68, 24, 81, 24, 157, 24, 227, 24, 155, 24, 182, 24, 49, 1, 152, + 32, 24, 120, 24, 122, 24, 166, 24, 170, 24, 154, 24, 244, 24, 216, 24, 24, 24, 142, 24, 162, + 24, 74, 24, 218, 24, 86, 24, 190, 24, 143, 13, 24, 76, 24, 246, 24, 103, 24, 112, 24, 236, 24, + 238, 24, 201, 24, 82, 24, 236, 24, 159, 14, 24, 109, 24, 218, 24, 73, 24, 72, 24, 161, 152, 32, + 24, 169, 24, 195, 24, 186, 24, 110, 24, 211, 24, 113, 24, 208, 24, 98, 24, 88, 24, 255, 24, + 109, 12, 24, 252, 24, 247, 24, 75, 24, 148, 24, 37, 24, 170, 24, 219, 24, 84, 24, 34, 24, 137, + 24, 187, 24, 131, 24, 47, 24, 64, 24, 147, 14, 24, 242, 24, 221, 24, 33, 5, 152, 32, 24, 238, + 24, 224, 24, 221, 24, 54, 24, 77, 24, 239, 24, 42, 24, 188, 24, 110, 24, 64, 24, 109, 24, 213, + 24, 240, 24, 158, 24, 214, 24, 222, 13, 24, 122, 24, 96, 24, 114, 24, 237, 24, 50, 24, 111, 24, + 247, 24, 214, 24, 47, 24, 253, 24, 242, 2, 24, 219, 24, 115, 24, 88, 161, 107, 109, 101, 114, + 107, 108, 101, 95, 112, 97, 116, 104, 135, 152, 32, 24, 132, 24, 181, 24, 36, 24, 163, 24, 246, + 24, 163, 24, 95, 24, 45, 24, 150, 24, 47, 24, 48, 24, 214, 24, 157, 24, 225, 24, 231, 24, 91, + 4, 24, 96, 24, 161, 24, 34, 24, 115, 24, 46, 24, 165, 12, 24, 93, 24, 227, 24, 34, 17, 24, 160, + 24, 25, 24, 166, 24, 219, 152, 32, 24, 165, 24, 118, 7, 18, 24, 37, 24, 94, 24, 69, 24, 102, + 22, 24, 193, 11, 24, 118, 24, 55, 24, 151, 24, 156, 24, 65, 24, 104, 24, 163, 24, 210, 24, 141, + 24, 41, 24, 32, 16, 24, 245, 24, 67, 24, 39, 24, 110, 24, 241, 24, 194, 14, 24, 77, 24, 207, + 152, 32, 24, 134, 13, 24, 51, 24, 208, 24, 127, 24, 54, 24, 125, 24, 50, 16, 12, 15, 24, 123, + 24, 213, 13, 24, 43, 20, 24, 172, 24, 242, 24, 202, 24, 72, 24, 73, 4, 24, 215, 24, 244, 24, + 231, 24, 150, 24, 147, 24, 52, 24, 162, 24, 87, 24, 213, 24, 74, 152, 32, 24, 40, 24, 103, 24, + 148, 24, 154, 24, 90, 24, 249, 19, 24, 166, 24, 196, 24, 62, 24, 85, 24, 202, 24, 183, 24, 41, + 24, 154, 24, 80, 24, 143, 24, 94, 24, 209, 24, 145, 24, 66, 24, 249, 24, 192, 24, 122, 24, 29, + 24, 53, 24, 30, 24, 35, 24, 101, 24, 154, 24, 222, 24, 178, 152, 32, 24, 90, 24, 168, 24, 235, + 24, 192, 24, 45, 24, 234, 18, 24, 115, 24, 97, 24, 177, 24, 42, 24, 90, 24, 103, 24, 41, 24, + 252, 24, 244, 24, 200, 24, 68, 24, 143, 24, 109, 24, 157, 24, 218, 8, 0, 24, 90, 24, 170, 24, + 228, 24, 26, 24, 118, 24, 105, 24, 86, 24, 83, 152, 32, 24, 243, 24, 27, 24, 92, 24, 65, 24, + 108, 24, 158, 24, 244, 5, 24, 37, 24, 210, 24, 210, 24, 223, 24, 245, 24, 165, 24, 108, 24, 31, + 24, 60, 24, 126, 24, 115, 24, 189, 24, 192, 24, 217, 24, 161, 24, 99, 24, 44, 24, 60, 24, 89, + 24, 103, 24, 213, 24, 166, 24, 43, 24, 223, 152, 32, 21, 24, 250, 8, 24, 215, 24, 64, 24, 189, + 24, 128, 24, 129, 24, 228, 24, 222, 24, 77, 24, 184, 24, 227, 24, 54, 24, 128, 24, 28, 24, 176, + 24, 178, 1, 24, 70, 3, 24, 127, 24, 82, 24, 135, 24, 200, 24, 77, 24, 147, 24, 247, 4, 24, 235, + 24, 166, 24, 104, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 134, 152, 32, + 24, 29, 24, 38, 20, 24, 128, 24, 194, 24, 249, 24, 152, 24, 230, 24, 81, 24, 106, 24, 196, 24, + 62, 24, 111, 24, 152, 24, 215, 24, 85, 24, 190, 24, 49, 24, 68, 24, 172, 24, 202, 24, 231, 24, + 109, 24, 171, 24, 65, 24, 239, 24, 41, 24, 80, 24, 163, 18, 24, 174, 24, 239, 152, 32, 24, 201, + 24, 135, 24, 185, 24, 254, 24, 44, 24, 37, 5, 24, 107, 24, 217, 4, 3, 24, 58, 24, 86, 24, 210, + 24, 68, 3, 24, 128, 24, 25, 24, 72, 24, 180, 24, 32, 24, 67, 24, 25, 24, 124, 24, 51, 24, 91, + 24, 50, 24, 50, 24, 164, 24, 77, 17, 24, 195, 152, 32, 24, 118, 24, 32, 24, 39, 24, 133, 24, + 168, 24, 128, 24, 170, 24, 184, 24, 188, 24, 183, 24, 250, 24, 144, 17, 24, 80, 24, 130, 24, + 77, 24, 92, 24, 172, 5, 24, 124, 24, 110, 1, 24, 188, 24, 154, 24, 221, 24, 181, 4, 14, 24, 52, + 24, 177, 17, 24, 99, 152, 32, 24, 243, 24, 107, 24, 63, 24, 152, 24, 133, 24, 208, 24, 50, 9, + 24, 37, 24, 61, 24, 28, 24, 178, 24, 44, 24, 215, 24, 161, 24, 208, 24, 167, 24, 63, 24, 248, + 24, 131, 24, 164, 24, 191, 24, 27, 24, 187, 24, 143, 24, 53, 16, 3, 24, 250, 11, 24, 165, 24, + 225, 152, 32, 24, 178, 24, 254, 24, 82, 24, 229, 24, 93, 24, 68, 24, 82, 24, 240, 24, 42, 24, + 150, 24, 182, 24, 79, 2, 24, 35, 24, 115, 24, 58, 24, 166, 24, 217, 24, 94, 24, 123, 13, 24, + 205, 24, 90, 24, 188, 24, 221, 24, 52, 24, 36, 24, 219, 24, 172, 24, 139, 24, 169, 24, 74, 152, + 32, 24, 156, 24, 174, 24, 29, 24, 178, 24, 80, 24, 164, 24, 236, 24, 227, 24, 51, 24, 220, 24, + 208, 24, 173, 24, 151, 24, 166, 24, 37, 24, 36, 24, 192, 3, 24, 120, 24, 227, 24, 61, 24, 103, + 24, 150, 24, 28, 24, 32, 24, 108, 24, 63, 24, 31, 24, 55, 24, 137, 24, 36, 24, 114, 161, 107, + 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 133, 152, 32, 24, 66, 24, 190, 24, 96, 7, + 24, 33, 24, 124, 2, 2, 24, 79, 12, 24, 244, 24, 95, 24, 244, 24, 188, 4, 24, 109, 24, 127, 24, + 49, 24, 154, 24, 131, 6, 24, 35, 24, 209, 24, 161, 24, 248, 24, 66, 24, 173, 24, 63, 24, 167, + 24, 239, 16, 24, 193, 152, 32, 24, 188, 24, 135, 24, 44, 24, 162, 24, 206, 24, 61, 24, 39, 24, + 226, 24, 132, 24, 69, 24, 163, 24, 28, 24, 71, 24, 227, 24, 108, 24, 26, 24, 143, 24, 82, 4, + 24, 34, 24, 231, 24, 60, 24, 241, 24, 48, 24, 146, 24, 252, 24, 185, 24, 49, 24, 233, 24, 78, + 24, 194, 24, 91, 152, 32, 21, 24, 206, 24, 238, 24, 162, 24, 169, 24, 184, 24, 205, 24, 28, 24, + 224, 24, 131, 24, 212, 24, 134, 24, 165, 24, 154, 24, 116, 24, 73, 24, 40, 24, 27, 24, 88, 24, + 220, 24, 217, 24, 124, 24, 62, 9, 24, 235, 24, 41, 24, 28, 24, 85, 24, 105, 24, 149, 24, 221, + 24, 169, 152, 32, 2, 22, 24, 48, 24, 103, 24, 51, 24, 117, 24, 197, 24, 190, 24, 198, 24, 163, + 24, 52, 24, 98, 24, 67, 24, 101, 24, 198, 24, 213, 14, 24, 211, 24, 95, 24, 175, 24, 138, 24, + 142, 24, 90, 24, 183, 24, 224, 24, 90, 24, 116, 24, 216, 24, 150, 24, 141, 24, 126, 24, 213, + 152, 32, 24, 62, 24, 231, 24, 121, 24, 151, 24, 168, 24, 28, 24, 127, 24, 123, 24, 88, 24, 237, + 24, 236, 24, 233, 24, 84, 24, 60, 24, 227, 24, 159, 24, 254, 24, 221, 24, 93, 24, 132, 24, 41, + 24, 220, 24, 236, 24, 230, 24, 68, 24, 103, 24, 142, 24, 96, 24, 117, 15, 24, 60, 24, 246, 161, + 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 132, 152, 32, 24, 251, 24, 122, 24, + 162, 24, 143, 24, 121, 17, 24, 94, 24, 176, 24, 243, 24, 226, 24, 100, 24, 159, 24, 153, 24, + 34, 24, 231, 24, 244, 24, 141, 24, 102, 24, 56, 24, 242, 24, 213, 24, 238, 24, 123, 14, 24, + 176, 24, 31, 24, 248, 24, 253, 24, 185, 24, 32, 24, 133, 24, 187, 152, 32, 24, 202, 24, 100, + 24, 195, 24, 189, 24, 193, 24, 249, 24, 140, 24, 45, 24, 157, 24, 104, 24, 158, 24, 89, 24, + 190, 24, 233, 24, 34, 24, 135, 24, 171, 24, 161, 24, 158, 23, 24, 183, 24, 88, 24, 151, 24, 37, + 24, 56, 24, 181, 5, 24, 29, 24, 237, 24, 31, 24, 193, 16, 152, 32, 24, 178, 24, 85, 24, 146, + 24, 196, 24, 216, 23, 24, 161, 24, 105, 24, 239, 24, 198, 24, 240, 24, 60, 24, 162, 24, 133, + 24, 127, 24, 46, 24, 130, 24, 54, 24, 83, 24, 80, 24, 231, 24, 84, 24, 91, 24, 26, 24, 40, 24, + 82, 24, 251, 24, 75, 24, 131, 24, 193, 24, 44, 24, 242, 152, 32, 24, 88, 0, 24, 118, 24, 232, + 24, 65, 24, 118, 20, 24, 229, 24, 81, 24, 37, 24, 31, 24, 201, 24, 162, 24, 205, 24, 39, 24, + 62, 24, 192, 24, 125, 24, 194, 24, 138, 24, 86, 24, 42, 24, 207, 24, 197, 24, 149, 24, 187, 24, + 106, 24, 204, 24, 200, 0, 11, 24, 144, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, + 116, 104, 131, 152, 32, 24, 143, 24, 80, 24, 83, 24, 30, 22, 24, 128, 24, 48, 24, 64, 24, 180, + 24, 209, 24, 40, 24, 37, 24, 24, 24, 121, 24, 199, 24, 199, 24, 199, 7, 24, 168, 24, 73, 23, + 24, 127, 24, 79, 24, 44, 24, 110, 24, 228, 24, 195, 24, 173, 24, 124, 8, 17, 14, 152, 32, 24, + 146, 24, 83, 24, 40, 24, 241, 24, 123, 24, 63, 24, 63, 24, 30, 24, 124, 24, 199, 24, 82, 24, + 162, 24, 153, 24, 136, 24, 86, 24, 225, 24, 70, 24, 155, 24, 227, 24, 100, 24, 86, 24, 243, 24, + 87, 24, 62, 24, 27, 24, 65, 1, 24, 63, 24, 80, 24, 251, 24, 59, 24, 36, 152, 32, 24, 147, 24, + 71, 24, 149, 24, 241, 24, 246, 24, 30, 24, 224, 24, 242, 24, 65, 24, 73, 24, 85, 24, 195, 24, + 148, 24, 80, 24, 31, 24, 76, 24, 118, 24, 211, 24, 92, 24, 145, 24, 44, 24, 79, 24, 138, 24, + 71, 24, 119, 16, 24, 66, 24, 226, 24, 175, 24, 98, 24, 239, 24, 92, 114, 108, 97, 121, 101, + 114, 115, 95, 101, 118, 97, 108, 117, 97, 116, 105, 111, 110, 115, 134, 161, 101, 118, 97, 108, + 117, 101, 120, 65, 48, 120, 49, 100, 52, 97, 55, 100, 50, 102, 52, 56, 53, 53, 101, 48, 49, 56, + 100, 97, 56, 57, 100, 49, 51, 56, 53, 57, 100, 99, 55, 54, 98, 52, 98, 52, 101, 49, 51, 50, 97, + 102, 102, 49, 50, 100, 48, 101, 101, 53, 99, 97, 56, 53, 57, 55, 52, 102, 98, 99, 98, 50, 52, + 97, 53, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 51, 55, 100, 57, 56, 52, 98, + 48, 50, 51, 52, 54, 51, 55, 50, 51, 54, 53, 52, 53, 56, 97, 98, 55, 55, 52, 100, 53, 48, 52, + 49, 51, 54, 101, 99, 54, 50, 49, 53, 51, 50, 52, 53, 98, 56, 53, 57, 52, 48, 102, 56, 52, 57, + 54, 56, 50, 57, 57, 48, 55, 52, 101, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, + 48, 55, 57, 54, 98, 101, 99, 99, 56, 49, 49, 101, 49, 97, 100, 50, 97, 48, 54, 55, 102, 54, 98, + 50, 102, 100, 52, 57, 55, 52, 57, 101, 99, 55, 56, 56, 49, 49, 50, 102, 54, 102, 54, 48, 56, + 49, 55, 55, 51, 52, 100, 57, 100, 54, 55, 51, 97, 56, 55, 52, 56, 49, 161, 101, 118, 97, 108, + 117, 101, 120, 64, 48, 120, 52, 51, 48, 54, 51, 53, 55, 97, 99, 100, 100, 99, 49, 55, 97, 50, + 48, 99, 54, 99, 53, 52, 53, 97, 55, 97, 51, 101, 53, 100, 52, 54, 51, 98, 51, 54, 97, 100, 49, + 101, 57, 49, 55, 54, 52, 49, 49, 102, 57, 97, 56, 51, 55, 56, 52, 51, 56, 53, 102, 97, 54, 100, + 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 52, 48, 51, 97, 54, 49, 53, 48, 48, 49, + 55, 99, 97, 57, 51, 52, 51, 55, 48, 56, 48, 51, 48, 49, 53, 57, 54, 57, 102, 50, 53, 56, 49, + 54, 48, 100, 48, 52, 97, 50, 49, 53, 101, 54, 53, 52, 100, 53, 49, 48, 53, 52, 57, 98, 57, 102, + 99, 57, 57, 57, 55, 101, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 50, 52, 101, + 57, 53, 57, 102, 99, 52, 101, 52, 49, 52, 53, 50, 97, 52, 99, 100, 49, 102, 98, 48, 48, 49, 57, + 50, 48, 48, 51, 102, 53, 99, 102, 55, 52, 53, 49, 56, 101, 54, 49, 97, 50, 54, 52, 49, 56, 52, + 56, 55, 102, 97, 100, 100, 50, 100, 55, 54, 99, 49, 50, 164, 117, 108, 97, 121, 101, 114, 115, + 95, 97, 117, 116, 104, 95, 112, 97, 116, 104, 115, 95, 115, 121, 109, 134, 161, 107, 109, 101, + 114, 107, 108, 101, 95, 112, 97, 116, 104, 136, 152, 32, 24, 227, 24, 192, 24, 62, 24, 183, 24, + 80, 24, 119, 24, 50, 24, 156, 24, 158, 24, 108, 24, 51, 24, 187, 24, 161, 24, 111, 24, 194, 24, + 254, 24, 221, 24, 179, 24, 55, 24, 176, 24, 199, 24, 67, 24, 102, 24, 52, 24, 228, 24, 150, 24, + 77, 24, 239, 24, 28, 24, 232, 24, 101, 24, 230, 152, 32, 24, 52, 23, 24, 78, 24, 210, 24, 171, + 24, 173, 24, 148, 24, 118, 24, 184, 24, 247, 24, 102, 24, 180, 24, 56, 18, 24, 255, 24, 97, 24, + 111, 3, 24, 81, 24, 202, 24, 32, 0, 24, 64, 19, 24, 212, 24, 246, 24, 147, 24, 173, 24, 41, 24, + 135, 24, 38, 4, 152, 32, 24, 165, 24, 107, 24, 240, 24, 244, 24, 209, 24, 105, 24, 86, 24, 178, + 24, 105, 24, 26, 24, 24, 24, 50, 24, 116, 24, 219, 24, 48, 24, 141, 24, 53, 24, 222, 24, 72, + 24, 212, 24, 222, 24, 28, 24, 207, 24, 70, 24, 65, 24, 205, 24, 225, 24, 33, 24, 51, 24, 170, + 24, 82, 24, 27, 152, 32, 24, 152, 24, 32, 24, 143, 24, 58, 24, 95, 24, 120, 24, 138, 24, 84, + 24, 173, 24, 120, 24, 27, 24, 213, 14, 24, 132, 24, 30, 24, 124, 24, 141, 24, 224, 24, 189, 24, + 219, 24, 43, 23, 11, 24, 32, 8, 24, 46, 24, 198, 24, 182, 24, 217, 16, 24, 176, 24, 129, 152, + 32, 24, 238, 24, 66, 24, 255, 24, 155, 24, 195, 24, 73, 24, 113, 24, 173, 24, 181, 24, 177, 24, + 255, 24, 110, 24, 107, 24, 184, 4, 22, 24, 157, 24, 155, 19, 24, 209, 24, 141, 24, 241, 24, 64, + 24, 158, 24, 164, 24, 56, 24, 170, 24, 244, 24, 227, 24, 218, 24, 243, 24, 146, 152, 32, 24, + 165, 11, 24, 197, 24, 73, 24, 230, 24, 104, 24, 56, 24, 95, 24, 66, 24, 91, 24, 163, 24, 212, + 24, 73, 24, 39, 3, 24, 44, 24, 85, 24, 150, 24, 101, 24, 55, 24, 235, 24, 88, 24, 229, 24, 97, + 24, 145, 24, 128, 24, 25, 24, 115, 24, 177, 24, 69, 24, 112, 24, 77, 152, 32, 24, 218, 24, 172, + 24, 126, 24, 128, 24, 132, 24, 67, 24, 231, 24, 163, 24, 88, 24, 160, 24, 192, 24, 251, 24, + 238, 24, 43, 24, 164, 24, 94, 24, 194, 24, 54, 0, 24, 159, 24, 165, 24, 151, 24, 232, 24, 184, + 24, 154, 24, 63, 24, 92, 24, 81, 24, 198, 24, 38, 24, 75, 24, 144, 152, 32, 24, 238, 24, 224, + 24, 221, 24, 54, 24, 77, 24, 239, 24, 42, 24, 188, 24, 110, 24, 64, 24, 109, 24, 213, 24, 240, + 24, 158, 24, 214, 24, 222, 13, 24, 122, 24, 96, 24, 114, 24, 237, 24, 50, 24, 111, 24, 247, 24, + 214, 24, 47, 24, 253, 24, 242, 2, 24, 219, 24, 115, 24, 88, 161, 107, 109, 101, 114, 107, 108, + 101, 95, 112, 97, 116, 104, 135, 152, 32, 24, 99, 24, 164, 24, 144, 24, 168, 24, 160, 24, 191, + 24, 223, 24, 91, 24, 170, 24, 225, 24, 205, 24, 147, 24, 249, 24, 79, 24, 141, 24, 26, 24, 130, + 24, 242, 24, 220, 24, 224, 24, 161, 24, 188, 24, 137, 24, 214, 24, 85, 3, 24, 154, 24, 137, 8, + 24, 251, 24, 158, 24, 145, 152, 32, 24, 51, 24, 179, 24, 203, 24, 223, 24, 121, 24, 177, 24, + 167, 16, 24, 132, 14, 24, 190, 17, 24, 121, 24, 97, 24, 168, 24, 165, 24, 38, 24, 84, 24, 133, + 17, 24, 36, 24, 72, 24, 56, 24, 250, 24, 116, 24, 80, 24, 35, 24, 141, 24, 68, 24, 110, 24, + 228, 23, 152, 32, 24, 240, 24, 139, 24, 182, 24, 192, 24, 62, 24, 56, 24, 101, 3, 24, 98, 24, + 37, 24, 165, 24, 157, 24, 230, 24, 208, 9, 24, 139, 24, 233, 24, 188, 24, 50, 24, 190, 24, 199, + 24, 242, 24, 179, 24, 49, 24, 85, 24, 136, 24, 115, 24, 94, 24, 199, 24, 66, 24, 235, 24, 39, + 152, 32, 24, 221, 24, 99, 24, 234, 24, 197, 24, 214, 24, 190, 24, 120, 24, 48, 24, 190, 24, + 165, 24, 174, 24, 146, 24, 46, 24, 161, 24, 100, 7, 24, 170, 24, 203, 2, 24, 33, 24, 247, 24, + 44, 24, 169, 16, 24, 30, 4, 24, 67, 11, 24, 135, 24, 26, 24, 163, 24, 182, 152, 32, 24, 177, + 24, 28, 24, 157, 24, 237, 24, 141, 24, 216, 24, 114, 24, 79, 24, 48, 24, 141, 24, 122, 24, 73, + 24, 180, 24, 118, 24, 117, 24, 254, 24, 159, 24, 156, 24, 215, 24, 81, 24, 214, 24, 237, 24, + 128, 24, 99, 24, 219, 24, 60, 24, 101, 24, 73, 24, 64, 24, 179, 24, 131, 24, 179, 152, 32, 24, + 59, 24, 168, 24, 35, 24, 34, 24, 169, 24, 31, 24, 223, 8, 24, 40, 24, 170, 24, 155, 24, 220, + 24, 93, 21, 24, 152, 24, 39, 24, 65, 8, 24, 212, 24, 165, 24, 141, 24, 210, 24, 169, 24, 245, + 24, 163, 24, 229, 24, 76, 12, 24, 141, 24, 165, 24, 133, 24, 30, 152, 32, 21, 24, 250, 8, 24, + 215, 24, 64, 24, 189, 24, 128, 24, 129, 24, 228, 24, 222, 24, 77, 24, 184, 24, 227, 24, 54, 24, + 128, 24, 28, 24, 176, 24, 178, 1, 24, 70, 3, 24, 127, 24, 82, 24, 135, 24, 200, 24, 77, 24, + 147, 24, 247, 4, 24, 235, 24, 166, 24, 104, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, + 97, 116, 104, 134, 152, 32, 24, 76, 24, 141, 24, 97, 24, 205, 24, 161, 24, 75, 24, 160, 24, 48, + 24, 81, 24, 51, 24, 167, 24, 157, 24, 124, 24, 25, 24, 246, 24, 67, 24, 194, 24, 45, 24, 68, + 24, 188, 24, 215, 24, 150, 18, 24, 24, 24, 59, 10, 24, 94, 24, 239, 24, 241, 24, 138, 24, 233, + 24, 74, 152, 32, 24, 172, 24, 134, 24, 102, 24, 180, 24, 164, 24, 145, 24, 208, 24, 30, 24, 79, + 24, 156, 24, 74, 24, 243, 24, 196, 24, 237, 24, 126, 0, 24, 224, 12, 24, 151, 24, 61, 24, 129, + 24, 129, 24, 85, 24, 141, 24, 253, 24, 147, 24, 169, 24, 80, 24, 64, 24, 145, 24, 25, 24, 110, + 152, 32, 24, 93, 24, 122, 24, 63, 24, 217, 24, 226, 24, 96, 24, 215, 24, 233, 10, 24, 142, 24, + 136, 24, 139, 24, 255, 24, 45, 24, 89, 24, 172, 24, 206, 24, 124, 24, 73, 24, 177, 24, 96, 24, + 193, 24, 99, 24, 148, 24, 226, 24, 148, 24, 148, 24, 84, 24, 196, 24, 250, 24, 245, 24, 86, + 152, 32, 24, 243, 24, 107, 24, 63, 24, 152, 24, 133, 24, 208, 24, 50, 9, 24, 37, 24, 61, 24, + 28, 24, 178, 24, 44, 24, 215, 24, 161, 24, 208, 24, 167, 24, 63, 24, 248, 24, 131, 24, 164, 24, + 191, 24, 27, 24, 187, 24, 143, 24, 53, 16, 3, 24, 250, 11, 24, 165, 24, 225, 152, 32, 24, 178, + 24, 254, 24, 82, 24, 229, 24, 93, 24, 68, 24, 82, 24, 240, 24, 42, 24, 150, 24, 182, 24, 79, 2, + 24, 35, 24, 115, 24, 58, 24, 166, 24, 217, 24, 94, 24, 123, 13, 24, 205, 24, 90, 24, 188, 24, + 221, 24, 52, 24, 36, 24, 219, 24, 172, 24, 139, 24, 169, 24, 74, 152, 32, 24, 156, 24, 174, 24, + 29, 24, 178, 24, 80, 24, 164, 24, 236, 24, 227, 24, 51, 24, 220, 24, 208, 24, 173, 24, 151, 24, + 166, 24, 37, 24, 36, 24, 192, 3, 24, 120, 24, 227, 24, 61, 24, 103, 24, 150, 24, 28, 24, 32, + 24, 108, 24, 63, 24, 31, 24, 55, 24, 137, 24, 36, 24, 114, 161, 107, 109, 101, 114, 107, 108, + 101, 95, 112, 97, 116, 104, 133, 152, 32, 24, 70, 23, 24, 80, 24, 68, 24, 172, 13, 24, 63, 24, + 250, 24, 241, 24, 131, 2, 24, 220, 24, 51, 24, 133, 24, 119, 24, 74, 24, 148, 24, 251, 24, 210, + 24, 69, 24, 175, 24, 106, 24, 89, 24, 31, 24, 121, 24, 189, 24, 135, 24, 81, 9, 24, 76, 24, + 183, 24, 74, 152, 32, 24, 202, 24, 236, 8, 24, 234, 24, 165, 24, 94, 24, 51, 14, 24, 185, 22, + 24, 52, 24, 63, 24, 177, 24, 158, 24, 90, 24, 102, 24, 92, 24, 102, 16, 24, 43, 24, 101, 24, + 77, 13, 24, 221, 24, 186, 24, 166, 24, 51, 24, 141, 24, 134, 12, 24, 186, 24, 123, 152, 32, 12, + 24, 55, 24, 198, 24, 84, 16, 1, 24, 231, 9, 24, 75, 24, 47, 24, 210, 24, 112, 24, 75, 24, 140, + 24, 222, 24, 215, 24, 50, 24, 151, 24, 132, 24, 28, 24, 92, 24, 174, 17, 24, 94, 24, 194, 24, + 217, 24, 217, 24, 24, 24, 209, 24, 255, 24, 116, 24, 79, 152, 32, 24, 155, 24, 111, 24, 60, 24, + 200, 24, 100, 24, 226, 24, 142, 24, 126, 24, 73, 24, 229, 24, 252, 24, 95, 24, 171, 24, 183, + 24, 67, 24, 28, 24, 222, 24, 72, 24, 146, 24, 204, 24, 181, 24, 50, 4, 24, 118, 24, 55, 24, + 117, 24, 24, 24, 87, 24, 241, 24, 44, 24, 164, 24, 248, 152, 32, 24, 104, 24, 124, 24, 35, 24, + 63, 24, 177, 24, 192, 24, 161, 24, 157, 24, 192, 21, 14, 24, 198, 24, 186, 24, 232, 24, 245, + 24, 131, 24, 91, 24, 119, 24, 32, 24, 190, 24, 198, 24, 222, 24, 171, 24, 255, 24, 140, 24, 93, + 24, 51, 24, 188, 24, 47, 24, 105, 24, 193, 24, 199, 161, 107, 109, 101, 114, 107, 108, 101, 95, + 112, 97, 116, 104, 132, 152, 32, 24, 117, 24, 154, 24, 219, 24, 101, 6, 9, 24, 231, 24, 103, + 24, 28, 24, 228, 3, 24, 46, 24, 80, 24, 36, 24, 128, 24, 113, 24, 225, 24, 214, 24, 203, 24, + 90, 24, 169, 0, 24, 195, 23, 24, 87, 24, 31, 24, 254, 24, 56, 24, 197, 9, 24, 213, 24, 59, 152, + 32, 24, 168, 21, 24, 95, 24, 210, 24, 196, 24, 140, 22, 24, 120, 24, 116, 24, 162, 14, 24, 200, + 24, 210, 24, 84, 24, 135, 24, 230, 7, 24, 221, 24, 146, 24, 210, 24, 185, 24, 185, 24, 129, 7, + 24, 72, 24, 242, 24, 120, 24, 168, 24, 214, 24, 34, 24, 66, 24, 71, 152, 32, 24, 208, 24, 220, + 16, 4, 24, 60, 24, 240, 24, 126, 24, 146, 24, 166, 24, 142, 24, 138, 24, 119, 12, 0, 24, 133, + 24, 236, 24, 217, 24, 108, 24, 196, 24, 193, 24, 90, 24, 41, 24, 57, 24, 24, 24, 216, 24, 171, + 24, 78, 24, 52, 24, 215, 24, 60, 24, 137, 24, 105, 152, 32, 24, 99, 24, 186, 24, 246, 24, 150, + 24, 63, 24, 185, 24, 26, 24, 148, 24, 64, 24, 149, 24, 70, 24, 244, 24, 144, 24, 244, 24, 91, + 24, 183, 24, 136, 24, 67, 24, 188, 11, 24, 247, 10, 24, 234, 24, 170, 24, 59, 24, 27, 24, 141, + 24, 159, 24, 38, 24, 174, 24, 118, 24, 128, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, + 97, 116, 104, 131, 152, 32, 24, 235, 5, 24, 44, 24, 247, 24, 97, 24, 133, 18, 24, 254, 24, 75, + 4, 13, 24, 215, 24, 43, 24, 51, 24, 28, 6, 24, 152, 24, 113, 24, 61, 24, 221, 24, 249, 24, 119, + 24, 234, 24, 50, 24, 193, 24, 54, 24, 89, 24, 230, 24, 181, 24, 48, 24, 246, 24, 83, 152, 32, + 24, 38, 24, 82, 24, 115, 24, 43, 24, 137, 24, 174, 0, 5, 24, 144, 24, 84, 24, 73, 24, 233, 2, + 24, 112, 24, 135, 24, 228, 24, 84, 6, 24, 208, 24, 250, 24, 91, 24, 63, 24, 202, 24, 201, 24, + 120, 19, 24, 118, 24, 244, 24, 213, 22, 24, 246, 24, 238, 152, 32, 24, 147, 24, 71, 24, 149, + 24, 241, 24, 246, 24, 30, 24, 224, 24, 242, 24, 65, 24, 73, 24, 85, 24, 195, 24, 148, 24, 80, + 24, 31, 24, 76, 24, 118, 24, 211, 24, 92, 24, 145, 24, 44, 24, 79, 24, 138, 24, 71, 24, 119, + 16, 24, 66, 24, 226, 24, 175, 24, 98, 24, 239, 24, 92, 118, 108, 97, 121, 101, 114, 115, 95, + 101, 118, 97, 108, 117, 97, 116, 105, 111, 110, 115, 95, 115, 121, 109, 134, 161, 101, 118, 97, + 108, 117, 101, 120, 65, 48, 120, 54, 56, 55, 98, 97, 98, 49, 57, 97, 54, 52, 53, 54, 100, 98, + 54, 49, 102, 52, 97, 101, 97, 98, 101, 49, 57, 53, 52, 52, 99, 53, 97, 57, 53, 51, 54, 52, 56, + 52, 100, 53, 51, 54, 52, 51, 53, 56, 100, 55, 98, 99, 102, 50, 97, 55, 99, 57, 100, 51, 102, + 55, 50, 101, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 52, 55, 53, 53, 50, 49, + 52, 55, 48, 99, 102, 52, 101, 97, 98, 49, 99, 50, 97, 101, 98, 102, 54, 55, 52, 51, 99, 52, + 100, 100, 52, 56, 98, 48, 54, 51, 53, 101, 48, 48, 50, 50, 48, 49, 54, 53, 57, 51, 55, 55, 53, + 55, 97, 102, 52, 49, 100, 102, 49, 50, 101, 53, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, + 120, 98, 55, 52, 57, 101, 55, 53, 99, 50, 57, 51, 97, 98, 102, 56, 57, 50, 56, 98, 48, 97, 48, + 48, 101, 48, 101, 100, 97, 98, 99, 48, 99, 52, 51, 55, 57, 57, 57, 56, 51, 55, 51, 102, 102, + 56, 51, 101, 57, 53, 56, 53, 49, 102, 52, 54, 51, 51, 50, 99, 102, 99, 98, 161, 101, 118, 97, + 108, 117, 101, 120, 65, 48, 120, 53, 57, 51, 51, 55, 49, 99, 102, 57, 50, 53, 56, 101, 56, 56, + 52, 100, 53, 100, 97, 97, 54, 99, 53, 100, 99, 56, 102, 56, 52, 55, 50, 51, 57, 48, 56, 98, + 102, 102, 57, 55, 49, 99, 99, 98, 99, 99, 48, 98, 100, 97, 48, 52, 97, 98, 102, 55, 48, 50, 51, + 100, 56, 100, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 55, 48, 57, 57, 48, 98, 50, + 57, 53, 55, 48, 98, 98, 57, 101, 57, 100, 101, 97, 98, 101, 101, 48, 100, 98, 50, 48, 101, 53, + 54, 49, 102, 54, 53, 56, 53, 100, 48, 57, 53, 54, 52, 55, 53, 54, 97, 53, 55, 100, 56, 98, 53, + 49, 48, 50, 99, 99, 52, 48, 56, 53, 55, 48, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, + 52, 52, 48, 49, 50, 102, 98, 55, 50, 102, 99, 56, 57, 100, 98, 48, 97, 48, 98, 97, 52, 56, 55, + 101, 100, 49, 49, 49, 98, 97, 56, 98, 55, 48, 55, 52, 98, 52, 48, 98, 53, 55, 50, 101, 97, 98, + 55, 52, 97, 56, 102, 49, 50, 55, 101, 57, 56, 100, 102, 101, 48, 99, 50, 113, 108, 97, 121, + 101, 114, 115, 95, 97, 117, 116, 104, 95, 112, 97, 116, 104, 115, 134, 161, 107, 109, 101, 114, + 107, 108, 101, 95, 112, 97, 116, 104, 136, 152, 32, 24, 243, 24, 247, 24, 54, 24, 168, 24, 192, + 24, 61, 12, 24, 159, 4, 24, 40, 24, 36, 24, 37, 24, 167, 24, 241, 2, 0, 24, 135, 24, 125, 24, + 30, 24, 246, 24, 102, 24, 163, 18, 24, 28, 24, 80, 24, 177, 24, 166, 24, 174, 24, 205, 24, 109, + 24, 245, 24, 209, 152, 32, 3, 24, 62, 2, 24, 29, 24, 161, 24, 239, 24, 196, 16, 24, 83, 24, 44, + 24, 155, 24, 211, 24, 180, 24, 59, 24, 180, 24, 61, 24, 89, 23, 24, 111, 24, 240, 24, 119, 24, + 146, 24, 199, 24, 194, 24, 115, 24, 221, 24, 216, 24, 74, 24, 185, 24, 150, 10, 24, 124, 152, + 32, 24, 144, 24, 195, 24, 126, 24, 255, 24, 245, 24, 178, 24, 218, 24, 159, 24, 186, 24, 170, + 24, 220, 12, 24, 197, 24, 205, 24, 234, 24, 125, 24, 92, 24, 107, 24, 159, 24, 222, 24, 124, + 24, 53, 24, 87, 24, 54, 24, 102, 24, 87, 24, 48, 24, 121, 24, 184, 24, 172, 24, 141, 24, 133, + 152, 32, 24, 245, 8, 24, 127, 24, 128, 24, 106, 24, 27, 24, 75, 24, 90, 0, 24, 117, 24, 136, + 24, 124, 24, 24, 24, 204, 24, 98, 24, 131, 24, 139, 24, 216, 24, 245, 24, 94, 24, 134, 24, 104, + 24, 157, 24, 65, 24, 28, 24, 72, 24, 97, 24, 221, 24, 122, 24, 65, 24, 130, 24, 204, 152, 32, + 18, 24, 236, 24, 180, 24, 53, 24, 213, 24, 144, 24, 115, 24, 168, 24, 202, 24, 176, 24, 89, 24, + 118, 24, 205, 24, 24, 18, 24, 250, 24, 178, 24, 105, 24, 32, 24, 51, 24, 234, 24, 174, 7, 19, + 24, 213, 24, 233, 24, 131, 24, 153, 24, 196, 24, 208, 24, 231, 24, 179, 152, 32, 24, 78, 24, + 78, 24, 46, 24, 90, 24, 30, 24, 41, 24, 197, 24, 147, 24, 226, 24, 104, 24, 186, 24, 174, 24, + 52, 24, 142, 24, 79, 24, 252, 24, 124, 24, 57, 24, 162, 5, 24, 71, 24, 72, 24, 85, 24, 119, 24, + 240, 24, 137, 24, 217, 24, 171, 24, 27, 24, 146, 24, 231, 24, 242, 152, 32, 24, 155, 24, 136, + 24, 177, 24, 251, 24, 133, 24, 160, 18, 24, 219, 24, 179, 20, 24, 153, 15, 24, 119, 24, 203, + 24, 194, 24, 165, 24, 44, 14, 24, 49, 24, 158, 24, 233, 24, 232, 24, 79, 24, 141, 6, 24, 117, + 24, 103, 24, 83, 24, 25, 24, 37, 24, 223, 24, 252, 152, 32, 24, 206, 24, 252, 24, 45, 24, 231, + 24, 213, 24, 169, 24, 207, 15, 24, 107, 24, 246, 24, 210, 24, 26, 24, 243, 24, 201, 24, 25, 24, + 186, 24, 51, 24, 200, 24, 54, 24, 76, 24, 253, 24, 42, 24, 75, 15, 0, 24, 114, 24, 103, 24, + 181, 24, 43, 24, 123, 24, 208, 24, 85, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, + 116, 104, 135, 152, 32, 24, 160, 16, 24, 120, 16, 24, 239, 24, 223, 24, 146, 24, 139, 24, 184, + 24, 30, 24, 182, 24, 169, 24, 249, 24, 150, 24, 49, 24, 35, 24, 223, 24, 98, 24, 187, 24, 185, + 24, 233, 24, 110, 24, 106, 2, 24, 232, 24, 165, 24, 99, 24, 254, 24, 102, 24, 57, 24, 84, 24, + 81, 152, 32, 24, 44, 24, 65, 1, 24, 197, 24, 147, 24, 184, 24, 247, 24, 189, 24, 162, 24, 187, + 24, 135, 24, 155, 24, 34, 24, 62, 24, 182, 24, 192, 24, 77, 7, 24, 194, 24, 189, 24, 245, 24, + 169, 24, 93, 24, 51, 24, 41, 24, 172, 24, 232, 24, 105, 24, 226, 24, 90, 24, 203, 24, 34, 152, + 32, 24, 85, 24, 239, 24, 96, 24, 146, 24, 109, 24, 244, 24, 117, 24, 134, 24, 185, 24, 83, 24, + 225, 24, 99, 24, 194, 24, 104, 12, 24, 245, 24, 227, 24, 86, 24, 60, 24, 157, 24, 130, 24, 116, + 24, 186, 24, 208, 24, 29, 24, 229, 10, 24, 30, 24, 180, 19, 24, 93, 24, 135, 152, 32, 24, 232, + 24, 80, 24, 38, 24, 138, 24, 83, 24, 66, 24, 147, 24, 27, 24, 58, 24, 135, 24, 146, 24, 187, + 24, 39, 24, 224, 24, 63, 24, 35, 24, 103, 24, 192, 24, 240, 24, 123, 20, 24, 160, 24, 94, 24, + 140, 24, 126, 24, 163, 24, 127, 24, 83, 24, 200, 16, 24, 91, 24, 116, 152, 32, 24, 211, 24, + 114, 24, 153, 24, 41, 24, 184, 24, 92, 24, 161, 24, 193, 24, 192, 24, 184, 24, 227, 24, 251, + 24, 46, 18, 24, 174, 24, 38, 24, 198, 24, 81, 24, 78, 24, 54, 24, 253, 24, 89, 8, 24, 255, 24, + 56, 24, 237, 24, 157, 24, 131, 24, 103, 24, 68, 24, 236, 24, 88, 152, 32, 24, 57, 24, 115, 24, + 142, 24, 129, 13, 24, 150, 24, 150, 24, 69, 24, 60, 24, 91, 23, 24, 240, 24, 110, 24, 100, 24, + 72, 24, 218, 24, 172, 24, 240, 15, 24, 248, 24, 106, 24, 205, 24, 209, 24, 178, 24, 155, 24, + 179, 16, 24, 132, 24, 78, 24, 218, 24, 169, 24, 56, 152, 32, 24, 219, 22, 24, 71, 24, 233, 24, + 242, 24, 222, 24, 156, 24, 99, 24, 70, 24, 236, 24, 159, 24, 204, 24, 104, 24, 218, 24, 131, + 24, 95, 24, 250, 24, 239, 24, 135, 24, 43, 24, 90, 24, 144, 24, 43, 24, 124, 24, 164, 24, 169, + 24, 76, 24, 72, 24, 168, 24, 113, 24, 127, 24, 124, 161, 107, 109, 101, 114, 107, 108, 101, 95, + 112, 97, 116, 104, 134, 152, 32, 24, 80, 24, 78, 24, 87, 24, 39, 21, 24, 97, 24, 128, 24, 193, + 24, 149, 24, 238, 14, 24, 199, 24, 252, 24, 114, 24, 198, 24, 85, 24, 39, 24, 74, 24, 219, 24, + 119, 24, 56, 24, 130, 3, 24, 83, 24, 98, 24, 225, 24, 69, 24, 134, 24, 214, 22, 24, 33, 24, + 191, 152, 32, 24, 141, 24, 216, 24, 149, 24, 255, 24, 186, 24, 134, 24, 240, 24, 28, 24, 116, + 24, 244, 8, 24, 186, 24, 104, 0, 24, 103, 24, 144, 24, 111, 24, 228, 24, 223, 24, 130, 24, 119, + 24, 119, 24, 68, 24, 116, 24, 62, 1, 24, 136, 24, 186, 24, 28, 24, 241, 24, 33, 24, 145, 152, + 32, 10, 24, 36, 24, 123, 24, 192, 24, 98, 24, 243, 24, 176, 24, 39, 24, 239, 24, 150, 24, 150, + 24, 214, 24, 172, 24, 119, 24, 124, 24, 140, 22, 24, 112, 24, 138, 24, 29, 24, 92, 24, 208, 24, + 37, 24, 243, 24, 150, 24, 93, 24, 177, 24, 44, 24, 39, 24, 142, 24, 247, 24, 220, 152, 32, 24, + 221, 17, 24, 221, 24, 185, 24, 255, 24, 114, 24, 187, 24, 64, 1, 24, 70, 24, 159, 24, 65, 24, + 134, 24, 79, 18, 24, 81, 24, 180, 24, 130, 24, 226, 24, 249, 24, 62, 24, 72, 24, 37, 22, 24, + 124, 24, 102, 24, 251, 24, 69, 24, 186, 24, 232, 24, 248, 22, 152, 32, 24, 28, 24, 205, 22, 24, + 187, 24, 99, 24, 171, 24, 37, 24, 28, 24, 241, 24, 120, 23, 11, 24, 157, 22, 24, 27, 24, 50, + 24, 65, 24, 49, 24, 27, 24, 237, 24, 203, 24, 154, 24, 143, 24, 226, 24, 60, 24, 95, 10, 24, + 187, 24, 201, 24, 49, 24, 108, 24, 64, 152, 32, 24, 253, 24, 163, 24, 218, 2, 24, 224, 24, 216, + 24, 254, 24, 235, 24, 216, 24, 179, 5, 24, 54, 24, 65, 24, 248, 24, 93, 13, 24, 59, 24, 150, + 24, 26, 24, 101, 24, 163, 24, 124, 24, 115, 24, 44, 24, 226, 24, 152, 24, 98, 24, 211, 24, 34, + 24, 226, 24, 155, 24, 27, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 133, + 152, 32, 24, 83, 24, 161, 24, 71, 24, 225, 24, 49, 24, 203, 24, 95, 24, 174, 24, 87, 10, 24, + 148, 24, 180, 24, 211, 24, 193, 18, 15, 15, 24, 69, 24, 109, 24, 50, 24, 195, 24, 94, 24, 77, + 24, 211, 24, 66, 24, 220, 24, 35, 24, 219, 24, 181, 24, 157, 24, 200, 24, 170, 152, 32, 24, + 222, 24, 75, 24, 216, 24, 88, 24, 27, 6, 24, 51, 24, 94, 24, 93, 24, 33, 24, 149, 8, 24, 185, + 24, 230, 24, 66, 24, 126, 24, 170, 24, 80, 24, 136, 24, 101, 24, 31, 24, 177, 24, 38, 24, 129, + 24, 44, 24, 229, 24, 42, 24, 27, 24, 197, 24, 106, 24, 103, 24, 33, 152, 32, 16, 24, 132, 24, + 148, 24, 75, 24, 45, 24, 86, 24, 75, 24, 254, 24, 44, 24, 127, 24, 76, 24, 117, 24, 128, 24, + 63, 24, 26, 24, 212, 24, 211, 24, 117, 24, 238, 24, 81, 24, 237, 24, 44, 24, 83, 24, 61, 24, + 177, 24, 255, 24, 35, 24, 204, 24, 110, 24, 192, 24, 28, 24, 169, 152, 32, 2, 22, 24, 48, 24, + 103, 24, 51, 24, 117, 24, 197, 24, 190, 24, 198, 24, 163, 24, 52, 24, 98, 24, 67, 24, 101, 24, + 198, 24, 213, 14, 24, 211, 24, 95, 24, 175, 24, 138, 24, 142, 24, 90, 24, 183, 24, 224, 24, 90, + 24, 116, 24, 216, 24, 150, 24, 141, 24, 126, 24, 213, 152, 32, 24, 62, 24, 231, 24, 121, 24, + 151, 24, 168, 24, 28, 24, 127, 24, 123, 24, 88, 24, 237, 24, 236, 24, 233, 24, 84, 24, 60, 24, + 227, 24, 159, 24, 254, 24, 221, 24, 93, 24, 132, 24, 41, 24, 220, 24, 236, 24, 230, 24, 68, 24, + 103, 24, 142, 24, 96, 24, 117, 15, 24, 60, 24, 246, 161, 107, 109, 101, 114, 107, 108, 101, 95, + 112, 97, 116, 104, 132, 152, 32, 24, 117, 24, 114, 24, 191, 24, 148, 24, 223, 24, 83, 24, 98, + 24, 92, 24, 131, 24, 158, 24, 90, 24, 189, 24, 206, 14, 24, 117, 24, 98, 24, 195, 24, 50, 24, + 157, 24, 68, 5, 24, 51, 24, 176, 24, 215, 24, 206, 24, 26, 24, 24, 24, 196, 24, 200, 24, 252, + 24, 220, 24, 37, 152, 32, 24, 111, 24, 211, 24, 41, 24, 59, 24, 28, 24, 30, 24, 89, 24, 234, + 24, 211, 4, 24, 52, 24, 158, 24, 90, 24, 164, 24, 30, 24, 176, 24, 231, 24, 187, 24, 188, 24, + 153, 24, 88, 24, 246, 4, 9, 24, 77, 12, 24, 28, 24, 112, 24, 221, 24, 111, 6, 24, 76, 152, 32, + 24, 30, 24, 92, 24, 199, 24, 50, 24, 173, 24, 149, 24, 137, 5, 24, 107, 15, 22, 24, 113, 24, + 69, 24, 40, 24, 171, 24, 151, 24, 37, 24, 36, 24, 158, 24, 170, 24, 162, 24, 51, 24, 153, 24, + 123, 24, 24, 24, 171, 24, 81, 24, 253, 24, 132, 2, 24, 245, 24, 243, 152, 32, 24, 88, 0, 24, + 118, 24, 232, 24, 65, 24, 118, 20, 24, 229, 24, 81, 24, 37, 24, 31, 24, 201, 24, 162, 24, 205, + 24, 39, 24, 62, 24, 192, 24, 125, 24, 194, 24, 138, 24, 86, 24, 42, 24, 207, 24, 197, 24, 149, + 24, 187, 24, 106, 24, 204, 24, 200, 0, 11, 24, 144, 161, 107, 109, 101, 114, 107, 108, 101, 95, + 112, 97, 116, 104, 131, 152, 32, 24, 84, 24, 135, 24, 24, 24, 107, 24, 230, 24, 74, 24, 187, + 24, 73, 24, 124, 24, 34, 24, 242, 24, 97, 24, 183, 22, 24, 226, 24, 166, 24, 114, 24, 120, 24, + 42, 24, 44, 24, 231, 24, 213, 24, 180, 24, 122, 0, 24, 26, 24, 226, 24, 228, 6, 24, 26, 24, 40, + 24, 94, 152, 32, 24, 189, 24, 222, 24, 137, 24, 133, 24, 74, 24, 181, 24, 245, 24, 59, 24, 191, + 24, 134, 24, 78, 24, 189, 24, 83, 24, 196, 24, 32, 24, 215, 24, 227, 24, 133, 15, 24, 60, 24, + 128, 24, 253, 24, 90, 22, 24, 111, 24, 221, 24, 111, 24, 84, 24, 157, 24, 30, 24, 160, 24, 53, + 152, 32, 24, 224, 24, 167, 24, 224, 24, 94, 24, 117, 24, 227, 24, 202, 24, 49, 14, 24, 153, 24, + 231, 24, 232, 24, 129, 24, 222, 18, 24, 74, 24, 50, 24, 62, 24, 81, 24, 243, 24, 109, 24, 81, + 0, 24, 162, 24, 234, 24, 199, 24, 144, 24, 110, 24, 153, 24, 182, 24, 116, 24, 159, 114, 108, + 97, 121, 101, 114, 115, 95, 101, 118, 97, 108, 117, 97, 116, 105, 111, 110, 115, 134, 161, 101, + 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 99, 100, 51, 97, 55, 52, 56, 101, 52, 54, 101, + 51, 56, 53, 51, 57, 56, 54, 102, 99, 52, 48, 54, 100, 54, 56, 56, 55, 101, 48, 97, 98, 98, 51, + 51, 101, 100, 99, 48, 99, 55, 50, 97, 53, 102, 54, 56, 52, 50, 102, 97, 98, 52, 51, 53, 50, 54, + 100, 51, 53, 49, 48, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 53, 50, 48, 54, 54, + 53, 57, 50, 50, 57, 54, 56, 49, 53, 102, 49, 97, 102, 50, 49, 49, 51, 50, 52, 57, 56, 56, 102, + 51, 101, 52, 98, 51, 97, 99, 101, 102, 97, 52, 102, 99, 50, 54, 97, 55, 48, 49, 97, 54, 51, 49, + 99, 98, 101, 50, 55, 97, 53, 99, 49, 55, 52, 101, 161, 101, 118, 97, 108, 117, 101, 120, 65, + 48, 120, 55, 48, 50, 51, 100, 56, 54, 100, 53, 53, 99, 54, 53, 54, 56, 97, 54, 53, 51, 55, 55, + 57, 55, 51, 54, 48, 55, 52, 100, 48, 53, 51, 55, 51, 102, 56, 50, 99, 102, 57, 56, 56, 53, 50, + 51, 99, 98, 50, 98, 49, 53, 97, 100, 99, 102, 48, 101, 48, 53, 57, 97, 54, 48, 161, 101, 118, + 97, 108, 117, 101, 120, 65, 48, 120, 51, 57, 99, 98, 97, 98, 100, 50, 101, 97, 54, 102, 55, 54, + 49, 48, 57, 50, 99, 97, 48, 57, 101, 101, 51, 48, 52, 55, 57, 99, 97, 49, 98, 56, 55, 101, 54, + 52, 56, 97, 54, 98, 48, 57, 52, 52, 53, 100, 54, 101, 97, 51, 101, 101, 55, 57, 52, 52, 102, + 49, 52, 51, 51, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 56, 48, 56, 57, 49, + 101, 48, 102, 53, 56, 55, 55, 52, 57, 57, 100, 56, 102, 48, 97, 57, 100, 49, 98, 54, 48, 52, + 99, 55, 48, 101, 101, 100, 100, 100, 50, 48, 53, 101, 99, 56, 54, 48, 50, 53, 56, 102, 97, 49, + 49, 54, 56, 53, 50, 99, 55, 98, 55, 99, 54, 100, 52, 161, 101, 118, 97, 108, 117, 101, 120, 65, + 48, 120, 50, 98, 54, 52, 99, 53, 51, 98, 102, 101, 50, 48, 54, 51, 54, 56, 55, 98, 101, 53, 55, + 52, 56, 100, 98, 54, 53, 57, 49, 98, 49, 98, 97, 56, 48, 50, 48, 48, 98, 54, 55, 50, 55, 51, + 98, 101, 54, 49, 99, 57, 56, 102, 99, 50, 54, 54, 54, 57, 98, 57, 48, 102, 98, 114, 100, 101, + 101, 112, 95, 112, 111, 108, 121, 95, 111, 112, 101, 110, 105, 110, 103, 115, 131, 165, 120, + 26, 108, 100, 101, 95, 99, 111, 109, 112, 111, 115, 105, 116, 105, 111, 110, 95, 112, 111, 108, + 121, 95, 112, 114, 111, 111, 102, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, + 104, 136, 152, 32, 24, 61, 24, 102, 24, 138, 24, 80, 24, 76, 24, 153, 24, 171, 24, 127, 24, + 114, 24, 114, 24, 189, 24, 201, 24, 56, 24, 220, 4, 24, 223, 24, 146, 10, 24, 124, 24, 239, 24, + 109, 24, 97, 24, 183, 14, 24, 200, 24, 46, 19, 24, 88, 24, 67, 24, 126, 24, 67, 24, 106, 152, + 32, 24, 188, 24, 241, 24, 244, 24, 194, 24, 96, 24, 184, 9, 24, 66, 24, 203, 24, 31, 24, 52, + 24, 226, 24, 81, 24, 119, 24, 181, 9, 24, 62, 24, 74, 24, 43, 12, 22, 24, 195, 24, 74, 24, 27, + 24, 114, 24, 128, 24, 228, 2, 24, 190, 24, 40, 24, 74, 24, 88, 152, 32, 24, 147, 24, 130, 24, + 249, 24, 140, 0, 24, 252, 24, 45, 24, 240, 24, 235, 24, 45, 18, 24, 33, 24, 232, 9, 24, 228, + 24, 241, 24, 155, 24, 172, 24, 143, 24, 104, 24, 95, 24, 109, 24, 161, 24, 32, 24, 112, 24, 88, + 24, 56, 15, 24, 106, 24, 62, 24, 232, 12, 152, 32, 24, 142, 24, 189, 24, 246, 24, 114, 24, 172, + 14, 24, 25, 24, 75, 24, 125, 24, 35, 19, 24, 97, 24, 163, 24, 210, 24, 71, 24, 55, 24, 55, 24, + 58, 24, 142, 2, 24, 99, 21, 24, 219, 24, 154, 24, 100, 11, 24, 68, 24, 112, 24, 139, 24, 99, + 24, 185, 22, 152, 32, 24, 60, 24, 149, 24, 145, 24, 110, 24, 95, 24, 89, 24, 238, 24, 113, 24, + 201, 24, 83, 24, 236, 24, 250, 24, 119, 24, 131, 24, 41, 24, 210, 24, 100, 24, 118, 24, 255, + 24, 124, 24, 102, 4, 24, 111, 24, 241, 24, 69, 24, 179, 24, 248, 24, 202, 24, 194, 24, 83, 24, + 172, 24, 133, 152, 32, 24, 24, 24, 238, 14, 24, 116, 24, 99, 11, 24, 212, 24, 190, 24, 157, 5, + 24, 206, 24, 113, 24, 69, 24, 148, 24, 59, 24, 82, 24, 133, 24, 114, 24, 217, 24, 139, 24, 169, + 24, 246, 24, 67, 24, 88, 12, 24, 158, 24, 72, 24, 227, 24, 26, 24, 158, 24, 40, 24, 232, 152, + 32, 10, 24, 82, 24, 153, 24, 239, 24, 119, 24, 65, 24, 200, 24, 112, 24, 187, 24, 142, 24, 73, + 24, 248, 24, 181, 24, 200, 24, 26, 24, 36, 24, 209, 24, 214, 24, 71, 24, 226, 24, 72, 22, 24, + 178, 24, 54, 24, 196, 24, 215, 24, 209, 15, 24, 99, 24, 155, 24, 26, 18, 152, 32, 24, 30, 24, + 68, 24, 149, 24, 170, 24, 215, 24, 85, 24, 46, 24, 58, 23, 24, 204, 24, 42, 24, 72, 24, 139, + 24, 52, 24, 41, 24, 211, 24, 247, 24, 128, 24, 194, 6, 24, 107, 24, 71, 24, 239, 3, 24, 88, 24, + 116, 24, 40, 24, 116, 24, 93, 24, 78, 24, 69, 24, 209, 120, 36, 108, 100, 101, 95, 99, 111, + 109, 112, 111, 115, 105, 116, 105, 111, 110, 95, 112, 111, 108, 121, 95, 101, 118, 101, 110, + 95, 101, 118, 97, 108, 117, 97, 116, 105, 111, 110, 161, 101, 118, 97, 108, 117, 101, 120, 65, + 48, 120, 50, 100, 102, 101, 50, 53, 97, 48, 49, 102, 53, 51, 55, 57, 102, 97, 100, 102, 97, 48, + 57, 54, 100, 55, 51, 48, 53, 55, 55, 101, 97, 51, 97, 57, 48, 98, 51, 50, 48, 49, 49, 49, 100, + 48, 52, 56, 49, 51, 97, 101, 56, 55, 50, 99, 53, 97, 54, 54, 55, 102, 56, 53, 51, 120, 35, 108, + 100, 101, 95, 99, 111, 109, 112, 111, 115, 105, 116, 105, 111, 110, 95, 112, 111, 108, 121, 95, + 111, 100, 100, 95, 101, 118, 97, 108, 117, 97, 116, 105, 111, 110, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 55, 99, 102, 54, 50, 97, 54, 56, 57, 97, 55, 50, 51, 100, 49, 102, 100, + 97, 102, 50, 49, 54, 48, 57, 99, 56, 52, 97, 52, 97, 50, 57, 100, 53, 56, 56, 100, 53, 54, 51, + 56, 51, 50, 48, 53, 53, 52, 99, 98, 50, 57, 102, 52, 48, 49, 98, 53, 48, 55, 100, 52, 51, 54, + 119, 108, 100, 101, 95, 116, 114, 97, 99, 101, 95, 109, 101, 114, 107, 108, 101, 95, 112, 114, + 111, 111, 102, 115, 130, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 136, + 152, 32, 24, 113, 24, 99, 24, 201, 24, 45, 24, 176, 24, 50, 24, 63, 24, 161, 24, 108, 24, 29, + 24, 52, 24, 196, 24, 137, 24, 233, 24, 69, 24, 252, 24, 218, 24, 113, 24, 253, 24, 35, 24, 48, + 24, 67, 24, 248, 24, 185, 24, 124, 24, 146, 24, 255, 24, 208, 24, 254, 24, 148, 24, 234, 24, + 27, 152, 32, 9, 24, 162, 8, 24, 124, 24, 181, 24, 48, 24, 104, 24, 204, 24, 33, 24, 210, 24, + 141, 24, 86, 24, 63, 24, 28, 24, 176, 24, 70, 24, 61, 24, 75, 6, 24, 164, 24, 85, 24, 167, 24, + 172, 24, 110, 24, 212, 14, 24, 246, 24, 144, 24, 55, 24, 187, 24, 76, 24, 125, 152, 32, 24, 61, + 24, 243, 24, 163, 24, 27, 24, 177, 24, 161, 24, 38, 24, 93, 24, 191, 24, 232, 24, 239, 24, 64, + 24, 201, 24, 126, 24, 173, 24, 69, 24, 122, 24, 211, 24, 40, 24, 229, 24, 253, 24, 243, 24, + 114, 24, 198, 24, 167, 24, 186, 24, 225, 24, 150, 24, 77, 24, 65, 24, 126, 24, 220, 152, 32, + 24, 112, 24, 140, 14, 24, 187, 24, 199, 24, 81, 24, 137, 24, 225, 24, 238, 24, 36, 24, 78, 24, + 196, 24, 164, 24, 231, 24, 112, 24, 77, 24, 90, 24, 81, 24, 199, 11, 24, 148, 24, 215, 24, 169, + 24, 88, 24, 203, 24, 219, 24, 130, 24, 39, 24, 81, 24, 145, 24, 170, 24, 76, 152, 32, 24, 131, + 24, 162, 24, 40, 24, 104, 24, 44, 24, 69, 24, 167, 24, 194, 24, 67, 24, 28, 24, 212, 24, 217, + 24, 143, 24, 200, 24, 187, 24, 59, 24, 167, 5, 24, 184, 24, 88, 18, 24, 180, 24, 128, 24, 123, + 24, 77, 24, 119, 24, 198, 24, 112, 24, 84, 24, 47, 24, 150, 24, 212, 152, 32, 7, 24, 117, 24, + 32, 24, 135, 24, 118, 24, 146, 24, 86, 24, 145, 24, 54, 24, 220, 24, 101, 24, 110, 24, 43, 24, + 199, 24, 104, 24, 107, 24, 140, 24, 54, 24, 117, 24, 205, 24, 150, 24, 44, 24, 234, 24, 47, 24, + 196, 24, 34, 24, 206, 24, 58, 24, 233, 24, 78, 24, 75, 24, 136, 152, 32, 24, 142, 24, 27, 24, + 30, 24, 221, 24, 248, 24, 242, 24, 125, 24, 74, 10, 24, 210, 24, 62, 20, 24, 94, 24, 66, 24, + 129, 24, 48, 24, 74, 24, 237, 24, 147, 24, 229, 24, 108, 24, 201, 24, 32, 24, 180, 24, 228, 24, + 85, 24, 197, 24, 155, 24, 191, 24, 38, 24, 154, 24, 199, 152, 32, 24, 75, 24, 81, 24, 75, 24, + 37, 24, 196, 24, 183, 24, 151, 24, 197, 24, 230, 24, 52, 24, 62, 24, 78, 24, 206, 24, 29, 9, + 24, 157, 24, 240, 24, 117, 24, 31, 24, 214, 24, 94, 24, 255, 24, 138, 24, 185, 3, 24, 99, 24, + 131, 24, 138, 24, 118, 24, 31, 24, 209, 24, 39, 161, 107, 109, 101, 114, 107, 108, 101, 95, + 112, 97, 116, 104, 136, 152, 32, 24, 105, 24, 245, 24, 56, 24, 32, 24, 181, 24, 180, 24, 242, + 24, 252, 24, 163, 24, 179, 24, 97, 24, 45, 24, 122, 24, 55, 24, 167, 24, 229, 24, 114, 24, 38, + 24, 80, 24, 235, 24, 172, 24, 166, 24, 145, 24, 139, 24, 237, 24, 214, 8, 24, 222, 24, 225, 24, + 135, 24, 196, 24, 172, 152, 32, 24, 90, 24, 240, 24, 28, 24, 139, 24, 111, 21, 21, 24, 163, 24, + 49, 24, 79, 24, 190, 24, 217, 24, 168, 24, 188, 24, 163, 24, 244, 24, 74, 24, 76, 24, 87, 24, + 203, 24, 254, 24, 30, 24, 138, 24, 151, 24, 248, 5, 24, 82, 24, 199, 24, 70, 24, 116, 24, 177, + 24, 126, 152, 32, 24, 160, 24, 200, 24, 245, 24, 72, 24, 238, 24, 77, 24, 173, 24, 24, 24, 31, + 24, 137, 24, 229, 24, 131, 24, 219, 24, 96, 24, 155, 24, 250, 24, 214, 24, 239, 24, 222, 24, + 208, 24, 42, 24, 46, 24, 42, 24, 27, 24, 211, 24, 74, 24, 44, 24, 74, 24, 30, 24, 211, 24, 222, + 24, 255, 152, 32, 24, 65, 24, 220, 16, 24, 69, 24, 62, 24, 126, 24, 105, 24, 175, 24, 28, 24, + 70, 24, 171, 24, 69, 24, 99, 24, 247, 24, 178, 24, 53, 24, 190, 24, 220, 18, 24, 119, 24, 204, + 3, 11, 24, 177, 24, 38, 24, 134, 24, 220, 24, 189, 24, 198, 24, 128, 24, 106, 24, 165, 152, 32, + 24, 231, 24, 26, 24, 251, 24, 87, 24, 203, 24, 172, 24, 126, 24, 169, 24, 93, 24, 139, 24, 143, + 2, 24, 228, 24, 41, 24, 62, 22, 24, 131, 24, 89, 24, 235, 24, 206, 24, 46, 24, 170, 24, 54, 24, + 152, 24, 99, 24, 235, 24, 242, 24, 37, 18, 2, 24, 151, 21, 152, 32, 24, 202, 24, 248, 24, 216, + 24, 118, 24, 88, 24, 235, 24, 135, 24, 24, 24, 147, 24, 186, 20, 24, 170, 24, 54, 24, 122, 3, + 24, 184, 24, 132, 17, 24, 24, 24, 132, 24, 114, 24, 140, 24, 100, 24, 187, 24, 150, 24, 49, 24, + 248, 2, 24, 171, 24, 82, 24, 75, 15, 152, 32, 24, 233, 19, 24, 230, 0, 24, 210, 24, 98, 24, 62, + 24, 149, 24, 156, 24, 190, 24, 44, 24, 205, 1, 24, 244, 24, 46, 24, 120, 24, 113, 24, 243, 24, + 127, 24, 212, 23, 24, 140, 24, 176, 24, 142, 24, 236, 24, 145, 24, 197, 24, 31, 24, 88, 24, + 103, 8, 24, 164, 152, 32, 23, 24, 160, 24, 63, 24, 234, 24, 117, 15, 24, 142, 24, 222, 24, 217, + 24, 226, 24, 118, 17, 24, 148, 24, 54, 24, 157, 24, 106, 24, 35, 24, 151, 24, 192, 24, 137, 24, + 31, 24, 214, 24, 152, 24, 231, 24, 193, 1, 24, 139, 24, 99, 24, 133, 24, 151, 24, 130, 24, 180, + 117, 108, 100, 101, 95, 116, 114, 97, 99, 101, 95, 101, 118, 97, 108, 117, 97, 116, 105, 111, + 110, 115, 152, 52, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 97, 98, 56, 100, 50, + 98, 50, 48, 48, 49, 100, 98, 48, 52, 99, 52, 100, 48, 99, 53, 100, 98, 55, 102, 51, 50, 55, 52, + 99, 102, 102, 54, 97, 53, 102, 52, 97, 48, 48, 48, 102, 54, 100, 57, 56, 52, 57, 49, 49, 49, + 50, 99, 50, 49, 56, 51, 101, 57, 101, 54, 97, 98, 161, 101, 118, 97, 108, 117, 101, 120, 65, + 48, 120, 54, 55, 50, 52, 49, 53, 97, 48, 102, 99, 99, 97, 101, 50, 54, 98, 51, 55, 97, 51, 97, + 57, 99, 51, 97, 53, 55, 48, 57, 52, 97, 57, 99, 97, 102, 54, 48, 57, 101, 54, 48, 53, 56, 55, + 56, 48, 52, 97, 99, 97, 55, 55, 52, 53, 54, 99, 53, 52, 50, 52, 53, 102, 52, 161, 101, 118, 97, + 108, 117, 101, 120, 65, 48, 120, 53, 57, 55, 100, 48, 54, 51, 54, 57, 53, 98, 98, 51, 57, 52, + 57, 101, 101, 98, 49, 57, 48, 55, 100, 50, 49, 51, 98, 99, 100, 99, 52, 54, 100, 100, 53, 56, + 99, 101, 50, 52, 102, 99, 53, 56, 53, 51, 54, 100, 57, 100, 51, 97, 48, 50, 51, 51, 48, 57, 56, + 52, 97, 53, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 99, 98, 57, 50, 57, 53, 99, 49, + 52, 51, 48, 56, 100, 50, 98, 53, 55, 50, 52, 48, 57, 99, 57, 101, 54, 50, 50, 57, 97, 55, 53, + 55, 54, 97, 102, 98, 102, 102, 57, 98, 52, 50, 48, 52, 54, 101, 54, 98, 54, 53, 97, 49, 53, 97, + 55, 51, 98, 101, 98, 56, 50, 48, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 57, + 99, 57, 100, 48, 54, 100, 53, 54, 49, 52, 51, 97, 57, 97, 98, 97, 50, 97, 54, 53, 98, 56, 102, + 56, 97, 49, 57, 55, 99, 54, 49, 98, 55, 97, 98, 51, 50, 51, 102, 99, 49, 97, 51, 51, 101, 50, + 54, 102, 100, 50, 52, 97, 51, 53, 57, 51, 55, 99, 51, 51, 100, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 52, 97, 48, 54, 51, 57, 49, 51, 52, 54, 52, 51, 54, 97, 101, 102, 52, + 57, 97, 99, 97, 56, 57, 55, 50, 99, 97, 48, 50, 51, 102, 57, 52, 56, 57, 56, 51, 97, 48, 57, + 55, 52, 53, 97, 99, 54, 101, 55, 48, 56, 101, 56, 100, 55, 102, 56, 57, 56, 53, 55, 101, 56, + 97, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 48, 161, 101, 118, 97, 108, 117, 101, 120, + 65, 48, 120, 53, 99, 52, 56, 97, 98, 102, 54, 100, 97, 49, 51, 50, 56, 98, 99, 99, 57, 57, 101, + 49, 50, 56, 54, 51, 49, 102, 102, 51, 53, 50, 101, 48, 102, 55, 49, 101, 99, 51, 97, 99, 102, + 57, 100, 97, 97, 51, 57, 100, 98, 50, 50, 101, 48, 48, 52, 48, 56, 53, 56, 52, 52, 101, 161, + 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 56, 100, 98, 101, 97, 53, 102, 48, 51, 51, + 53, 49, 101, 97, 52, 99, 56, 53, 99, 53, 54, 51, 99, 53, 97, 56, 102, 54, 98, 53, 54, 51, 53, + 48, 57, 102, 54, 49, 57, 102, 97, 55, 56, 55, 102, 98, 53, 51, 53, 56, 56, 98, 97, 57, 51, 97, + 98, 100, 98, 97, 48, 101, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 101, 55, 48, 50, + 54, 98, 98, 50, 54, 48, 97, 56, 55, 56, 102, 56, 51, 54, 101, 52, 98, 51, 49, 99, 49, 50, 56, + 49, 55, 100, 49, 53, 97, 101, 100, 53, 100, 99, 53, 51, 102, 99, 102, 101, 101, 48, 102, 51, + 53, 101, 102, 101, 50, 49, 52, 51, 54, 52, 54, 50, 53, 100, 161, 101, 118, 97, 108, 117, 101, + 99, 48, 120, 48, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 99, 49, 102, 52, 102, + 50, 55, 100, 102, 49, 102, 100, 55, 49, 102, 55, 97, 49, 48, 99, 57, 98, 101, 56, 53, 98, 102, + 57, 52, 51, 102, 51, 100, 57, 55, 52, 54, 97, 48, 57, 51, 54, 101, 53, 98, 55, 97, 57, 100, + 101, 99, 53, 56, 57, 57, 55, 50, 53, 97, 97, 55, 97, 161, 101, 118, 97, 108, 117, 101, 120, 65, + 48, 120, 49, 56, 100, 98, 101, 97, 53, 102, 48, 51, 51, 53, 49, 101, 97, 52, 99, 56, 53, 99, + 53, 54, 51, 99, 53, 97, 56, 102, 54, 98, 53, 54, 51, 53, 48, 57, 102, 54, 49, 57, 102, 97, 55, + 56, 55, 102, 98, 53, 51, 53, 56, 56, 98, 97, 57, 51, 97, 98, 100, 98, 97, 48, 101, 161, 101, + 118, 97, 108, 117, 101, 120, 65, 48, 120, 53, 99, 52, 56, 97, 98, 102, 54, 100, 97, 49, 51, 50, + 56, 98, 99, 99, 57, 57, 101, 49, 50, 56, 54, 51, 49, 102, 102, 51, 53, 50, 101, 48, 102, 55, + 49, 101, 99, 51, 97, 99, 102, 57, 100, 97, 97, 51, 57, 100, 98, 50, 50, 101, 48, 48, 52, 48, + 56, 53, 56, 52, 52, 101, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 55, 99, 54, 98, + 52, 50, 101, 101, 102, 99, 97, 100, 51, 51, 50, 101, 101, 97, 57, 55, 52, 99, 48, 98, 98, 50, + 52, 57, 52, 55, 97, 97, 54, 48, 57, 54, 98, 102, 101, 53, 102, 54, 49, 57, 101, 56, 48, 49, 98, + 57, 54, 52, 56, 51, 53, 52, 49, 53, 56, 53, 102, 52, 97, 161, 101, 118, 97, 108, 117, 101, 99, + 48, 120, 48, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 100, 57, 97, 48, 99, 48, + 54, 48, 55, 52, 56, 98, 98, 54, 56, 100, 57, 54, 48, 55, 52, 51, 102, 48, 100, 50, 49, 54, 49, + 102, 56, 54, 48, 49, 100, 52, 52, 56, 57, 100, 52, 101, 54, 53, 50, 57, 98, 49, 55, 49, 99, 53, + 101, 97, 102, 57, 54, 55, 55, 98, 101, 57, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, + 54, 102, 55, 49, 51, 54, 53, 57, 55, 49, 55, 54, 99, 102, 97, 100, 100, 55, 99, 101, 48, 56, + 98, 52, 98, 98, 97, 100, 51, 54, 52, 100, 55, 57, 51, 98, 53, 55, 98, 56, 54, 53, 56, 101, 99, + 50, 51, 52, 101, 55, 49, 52, 51, 54, 100, 52, 48, 55, 102, 55, 100, 54, 48, 161, 101, 118, 97, + 108, 117, 101, 120, 65, 48, 120, 53, 52, 55, 56, 53, 49, 100, 49, 48, 50, 51, 55, 98, 50, 56, + 48, 102, 51, 53, 101, 56, 97, 97, 49, 57, 54, 57, 52, 52, 57, 97, 51, 101, 49, 53, 55, 56, 49, + 51, 97, 53, 54, 100, 49, 97, 48, 101, 54, 52, 99, 102, 99, 97, 101, 98, 48, 48, 100, 56, 50, + 50, 54, 100, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 97, 52, 101, 52, 50, 99, + 100, 53, 48, 51, 54, 99, 102, 100, 98, 100, 50, 102, 97, 50, 97, 49, 53, 101, 101, 49, 52, 56, + 48, 101, 53, 57, 99, 54, 101, 52, 52, 98, 55, 101, 56, 53, 97, 48, 97, 99, 53, 97, 54, 99, 48, + 57, 100, 49, 50, 50, 51, 98, 55, 102, 53, 48, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, + 120, 52, 102, 49, 56, 101, 97, 48, 97, 52, 56, 97, 102, 52, 55, 53, 56, 99, 51, 98, 99, 48, 98, + 53, 49, 52, 99, 57, 98, 55, 56, 53, 49, 99, 55, 52, 50, 98, 55, 54, 57, 50, 51, 56, 48, 54, 49, + 48, 54, 48, 50, 48, 57, 100, 50, 57, 50, 49, 49, 98, 53, 53, 53, 101, 161, 101, 118, 97, 108, + 117, 101, 120, 65, 48, 120, 55, 49, 50, 51, 51, 51, 53, 98, 52, 102, 50, 49, 102, 98, 100, 101, + 49, 55, 99, 98, 55, 55, 53, 54, 50, 57, 101, 49, 102, 97, 102, 51, 49, 49, 55, 52, 55, 98, 101, + 101, 56, 99, 97, 57, 100, 50, 54, 51, 53, 99, 98, 102, 99, 50, 97, 56, 52, 57, 57, 99, 100, 99, + 53, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 49, 56, 98, 51, 100, 57, 53, 48, 102, + 57, 97, 102, 52, 52, 99, 57, 99, 52, 52, 98, 99, 52, 101, 102, 101, 57, 102, 98, 49, 51, 55, + 51, 54, 52, 48, 55, 100, 99, 50, 100, 55, 50, 52, 48, 54, 49, 52, 52, 48, 101, 97, 53, 98, 50, + 49, 99, 102, 50, 50, 56, 51, 102, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 98, + 99, 55, 51, 98, 102, 51, 51, 98, 98, 100, 97, 101, 102, 49, 53, 101, 98, 102, 50, 102, 51, 54, + 97, 50, 97, 52, 50, 102, 102, 49, 55, 48, 49, 54, 52, 48, 98, 55, 99, 99, 56, 98, 54, 49, 52, + 56, 50, 97, 100, 98, 54, 101, 53, 97, 50, 52, 49, 48, 99, 53, 100, 161, 101, 118, 97, 108, 117, + 101, 120, 64, 48, 120, 99, 53, 49, 49, 49, 102, 53, 48, 52, 101, 53, 101, 98, 99, 98, 53, 54, + 50, 50, 57, 99, 54, 98, 56, 48, 101, 102, 57, 97, 57, 54, 57, 51, 101, 99, 50, 52, 51, 101, 99, + 50, 55, 49, 50, 99, 101, 54, 99, 50, 49, 97, 53, 53, 56, 100, 102, 100, 49, 55, 98, 55, 48, + 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 54, 102, 100, 98, 97, 101, 48, 100, 49, 48, + 99, 97, 55, 101, 57, 50, 102, 55, 50, 98, 50, 51, 52, 99, 57, 53, 55, 102, 56, 98, 54, 50, 99, + 50, 98, 97, 54, 49, 100, 55, 56, 49, 52, 102, 57, 57, 48, 52, 52, 97, 100, 54, 55, 98, 55, 51, + 55, 54, 49, 99, 101, 55, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 56, 98, 48, + 50, 54, 102, 98, 99, 102, 54, 56, 57, 55, 97, 52, 48, 57, 56, 101, 100, 50, 51, 54, 102, 52, + 48, 102, 55, 100, 99, 97, 102, 102, 57, 98, 54, 101, 102, 101, 49, 55, 101, 54, 98, 49, 56, 54, + 98, 52, 51, 55, 52, 55, 48, 101, 100, 54, 97, 53, 56, 57, 100, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 51, 98, 100, 50, 52, 48, 49, 57, 98, 99, 50, 99, 98, 101, 102, 56, 55, + 49, 102, 50, 55, 55, 49, 49, 50, 98, 102, 102, 57, 97, 99, 52, 97, 100, 53, 52, 57, 52, 102, + 53, 51, 101, 97, 57, 53, 52, 100, 55, 56, 99, 55, 50, 54, 102, 48, 48, 97, 57, 53, 57, 98, 56, + 48, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 53, 49, 54, 51, 97, 54, 101, 54, 48, + 50, 55, 55, 49, 53, 55, 102, 48, 54, 57, 52, 102, 52, 98, 102, 100, 101, 101, 48, 54, 97, 53, + 52, 56, 53, 57, 99, 102, 100, 54, 54, 50, 53, 57, 102, 49, 50, 55, 100, 55, 57, 50, 53, 102, + 55, 53, 54, 51, 102, 48, 51, 54, 100, 101, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, + 55, 100, 101, 99, 51, 100, 48, 50, 55, 48, 97, 48, 55, 55, 100, 55, 97, 97, 54, 100, 53, 55, + 54, 50, 100, 54, 98, 100, 51, 101, 99, 56, 97, 55, 54, 101, 98, 54, 51, 102, 53, 101, 57, 48, + 48, 56, 52, 98, 50, 50, 102, 53, 53, 50, 55, 51, 51, 48, 50, 97, 57, 51, 161, 101, 118, 97, + 108, 117, 101, 120, 65, 48, 120, 54, 101, 49, 99, 51, 55, 101, 51, 98, 48, 57, 56, 57, 101, 99, + 53, 100, 99, 101, 52, 99, 57, 100, 57, 56, 56, 49, 98, 97, 100, 99, 102, 99, 49, 56, 98, 54, + 48, 99, 54, 57, 53, 102, 102, 51, 56, 49, 99, 57, 97, 50, 53, 56, 57, 51, 97, 97, 54, 56, 49, + 98, 53, 99, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 102, 48, 97, 102, 48, 53, + 100, 50, 97, 101, 48, 55, 98, 57, 52, 99, 97, 50, 102, 53, 97, 57, 53, 50, 99, 55, 102, 101, + 48, 52, 57, 48, 56, 53, 51, 98, 98, 54, 49, 53, 53, 102, 57, 97, 52, 54, 97, 52, 52, 50, 48, + 101, 55, 52, 48, 99, 51, 56, 49, 54, 54, 100, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, + 120, 54, 50, 52, 50, 51, 97, 54, 54, 57, 53, 54, 49, 48, 51, 56, 52, 52, 48, 54, 53, 102, 49, + 50, 102, 55, 53, 55, 55, 49, 100, 49, 100, 52, 57, 101, 52, 52, 99, 48, 97, 53, 101, 101, 57, + 53, 50, 98, 55, 57, 49, 99, 100, 100, 99, 57, 99, 98, 101, 48, 101, 97, 52, 56, 161, 101, 118, + 97, 108, 117, 101, 120, 65, 48, 120, 55, 56, 55, 48, 53, 99, 100, 50, 100, 56, 52, 55, 52, 53, + 51, 99, 52, 54, 52, 51, 53, 101, 50, 57, 49, 57, 102, 48, 49, 98, 97, 57, 53, 57, 102, 98, 57, + 102, 56, 57, 102, 54, 100, 48, 51, 55, 101, 48, 100, 57, 48, 53, 101, 51, 50, 100, 51, 97, 102, + 97, 50, 97, 55, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 52, 56, 52, 55, 53, 56, + 102, 49, 54, 54, 56, 100, 52, 49, 97, 57, 48, 102, 57, 53, 54, 99, 57, 102, 102, 100, 57, 97, + 99, 99, 102, 57, 98, 100, 102, 100, 48, 55, 49, 53, 97, 100, 55, 97, 50, 100, 102, 99, 54, 51, + 52, 99, 99, 57, 100, 102, 52, 102, 54, 57, 49, 50, 161, 101, 118, 97, 108, 117, 101, 120, 64, + 48, 120, 51, 49, 102, 49, 100, 97, 55, 49, 56, 97, 102, 99, 49, 53, 52, 102, 48, 101, 51, 53, + 48, 49, 57, 101, 101, 56, 57, 57, 57, 50, 100, 100, 99, 52, 98, 56, 99, 55, 101, 102, 98, 49, + 56, 102, 54, 57, 48, 52, 53, 50, 55, 53, 55, 55, 56, 55, 98, 100, 100, 55, 99, 97, 161, 101, + 118, 97, 108, 117, 101, 120, 64, 48, 120, 50, 56, 53, 55, 57, 100, 98, 102, 97, 48, 98, 53, + 101, 56, 99, 55, 50, 97, 53, 48, 55, 57, 55, 102, 53, 100, 98, 53, 50, 51, 101, 54, 101, 102, + 98, 53, 98, 49, 48, 55, 102, 53, 97, 100, 97, 54, 56, 54, 49, 101, 52, 54, 101, 99, 101, 101, + 55, 52, 102, 100, 57, 57, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 50, 50, 56, + 57, 49, 51, 98, 53, 56, 102, 57, 99, 56, 102, 57, 55, 50, 50, 54, 102, 56, 48, 53, 48, 50, 52, + 53, 50, 55, 53, 100, 101, 97, 52, 97, 56, 101, 49, 53, 102, 49, 57, 51, 49, 53, 102, 50, 98, + 57, 101, 99, 51, 54, 100, 51, 97, 54, 54, 49, 100, 49, 51, 161, 101, 118, 97, 108, 117, 101, + 120, 65, 48, 120, 53, 50, 51, 51, 57, 101, 57, 102, 99, 50, 50, 97, 102, 48, 56, 98, 49, 56, + 48, 102, 55, 49, 49, 52, 55, 101, 101, 101, 50, 49, 53, 57, 98, 51, 101, 97, 54, 98, 98, 52, + 52, 49, 102, 97, 52, 101, 51, 98, 97, 53, 50, 50, 100, 56, 97, 48, 53, 54, 55, 55, 55, 56, 50, + 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 55, 56, 57, 53, 97, 50, 97, 50, 102, + 56, 54, 50, 97, 100, 50, 57, 56, 101, 97, 50, 100, 56, 48, 49, 57, 97, 51, 97, 100, 54, 48, 97, + 97, 101, 98, 55, 98, 49, 55, 102, 53, 54, 50, 55, 50, 97, 48, 56, 49, 52, 52, 54, 98, 56, 100, + 99, 50, 52, 55, 52, 101, 101, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 54, 102, + 53, 97, 52, 50, 100, 56, 49, 101, 100, 48, 102, 52, 51, 49, 52, 98, 102, 49, 52, 51, 51, 57, + 100, 50, 50, 99, 102, 56, 99, 56, 57, 48, 52, 52, 98, 52, 49, 55, 100, 99, 52, 53, 100, 50, 57, + 52, 55, 49, 52, 98, 49, 55, 101, 48, 100, 53, 52, 101, 54, 51, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 52, 99, 48, 54, 52, 54, 97, 55, 52, 56, 54, 55, 55, 56, 54, 50, 57, 55, + 97, 98, 55, 98, 100, 57, 57, 99, 51, 99, 102, 100, 51, 50, 51, 102, 52, 53, 100, 99, 56, 49, + 102, 53, 98, 53, 57, 102, 99, 48, 54, 100, 101, 49, 48, 50, 52, 99, 98, 100, 99, 97, 51, 97, + 48, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 53, 51, 99, 55, 57, 97, 99, 55, 48, 52, + 49, 101, 52, 98, 100, 52, 99, 57, 101, 97, 50, 57, 55, 57, 102, 53, 49, 99, 52, 52, 50, 52, 51, + 51, 50, 100, 48, 52, 102, 99, 98, 101, 57, 101, 100, 100, 51, 55, 48, 57, 52, 54, 49, 57, 57, + 52, 49, 51, 56, 97, 56, 48, 52, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 53, 99, 49, + 56, 53, 55, 48, 52, 101, 48, 98, 100, 101, 52, 101, 55, 100, 55, 97, 57, 55, 56, 99, 100, 98, + 50, 54, 97, 54, 49, 51, 102, 100, 99, 48, 49, 49, 101, 48, 98, 52, 101, 100, 99, 99, 51, 99, + 53, 102, 55, 54, 101, 101, 48, 48, 54, 54, 54, 97, 100, 100, 97, 48, 161, 101, 118, 97, 108, + 117, 101, 120, 65, 48, 120, 51, 55, 100, 98, 56, 102, 98, 102, 50, 48, 49, 98, 50, 54, 97, 102, + 97, 48, 49, 48, 50, 48, 50, 53, 57, 52, 56, 98, 100, 48, 52, 98, 48, 51, 101, 52, 49, 52, 97, + 51, 53, 51, 102, 98, 56, 100, 101, 56, 49, 98, 53, 52, 97, 49, 54, 52, 50, 48, 56, 49, 54, 52, + 97, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 101, 50, 57, 97, 48, 51, 99, 57, 98, + 50, 97, 97, 57, 52, 100, 51, 100, 56, 100, 49, 102, 57, 50, 99, 50, 102, 100, 99, 57, 102, 53, + 48, 97, 55, 50, 99, 98, 98, 54, 55, 49, 56, 101, 51, 48, 101, 100, 99, 99, 97, 101, 50, 98, 56, + 97, 54, 97, 48, 53, 52, 48, 55, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 98, 101, + 99, 53, 48, 48, 99, 99, 56, 57, 99, 55, 50, 55, 48, 50, 98, 52, 101, 55, 53, 50, 57, 51, 49, + 97, 53, 53, 51, 55, 56, 51, 54, 98, 55, 99, 57, 99, 55, 50, 49, 57, 51, 98, 55, 49, 53, 49, 52, + 50, 99, 98, 49, 50, 53, 53, 56, 50, 55, 52, 98, 57, 161, 101, 118, 97, 108, 117, 101, 120, 65, + 48, 120, 52, 51, 55, 57, 97, 55, 98, 54, 49, 48, 48, 97, 51, 53, 52, 50, 53, 57, 50, 56, 101, + 101, 50, 53, 54, 55, 57, 98, 56, 98, 50, 49, 98, 51, 53, 102, 51, 98, 102, 98, 54, 49, 52, 52, + 48, 101, 57, 100, 56, 100, 99, 101, 101, 98, 52, 98, 49, 53, 54, 48, 102, 97, 49, 161, 101, + 118, 97, 108, 117, 101, 120, 64, 48, 120, 57, 102, 97, 48, 51, 54, 100, 99, 52, 57, 52, 54, 49, + 97, 98, 51, 100, 51, 49, 50, 52, 97, 53, 53, 55, 50, 48, 57, 56, 48, 49, 55, 49, 49, 52, 101, + 56, 101, 57, 98, 51, 98, 97, 98, 98, 99, 57, 52, 48, 98, 51, 97, 98, 50, 50, 52, 48, 50, 53, + 52, 57, 55, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 51, 50, 49, 55, 52, 48, 57, + 102, 54, 97, 101, 99, 56, 56, 102, 52, 49, 102, 56, 100, 102, 101, 50, 54, 48, 48, 101, 52, 52, + 100, 99, 52, 56, 50, 54, 99, 99, 51, 99, 50, 53, 48, 52, 51, 55, 56, 97, 101, 49, 51, 48, 49, + 97, 52, 48, 50, 54, 97, 54, 50, 101, 101, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, + 49, 48, 49, 51, 101, 55, 55, 49, 56, 55, 100, 56, 54, 53, 48, 101, 101, 56, 97, 99, 56, 54, 55, + 55, 51, 100, 52, 51, 48, 101, 56, 99, 56, 53, 52, 54, 100, 49, 102, 102, 100, 56, 53, 57, 57, + 57, 99, 101, 102, 56, 54, 98, 50, 101, 98, 102, 57, 49, 49, 51, 49, 51, 99, 161, 101, 118, 97, + 108, 117, 101, 120, 65, 48, 120, 51, 51, 51, 48, 98, 48, 56, 101, 101, 98, 98, 49, 53, 54, 52, + 50, 100, 54, 99, 98, 56, 55, 49, 100, 100, 98, 57, 52, 55, 98, 97, 52, 54, 53, 55, 55, 56, 52, + 56, 52, 48, 97, 100, 49, 50, 56, 102, 54, 55, 55, 53, 54, 98, 100, 48, 102, 54, 57, 48, 99, 97, + 53, 53, 165, 120, 26, 108, 100, 101, 95, 99, 111, 109, 112, 111, 115, 105, 116, 105, 111, 110, + 95, 112, 111, 108, 121, 95, 112, 114, 111, 111, 102, 161, 107, 109, 101, 114, 107, 108, 101, + 95, 112, 97, 116, 104, 136, 152, 32, 24, 179, 24, 98, 24, 50, 24, 159, 24, 50, 24, 143, 24, 95, + 8, 24, 246, 24, 188, 24, 235, 24, 173, 19, 24, 118, 20, 24, 57, 24, 95, 24, 42, 24, 75, 24, + 104, 24, 161, 24, 33, 24, 210, 24, 130, 24, 95, 24, 239, 24, 148, 24, 50, 24, 73, 24, 207, 24, + 220, 24, 55, 152, 32, 24, 146, 24, 43, 11, 24, 107, 24, 113, 24, 215, 24, 63, 4, 24, 216, 24, + 180, 24, 183, 24, 197, 24, 44, 24, 115, 24, 239, 24, 168, 15, 24, 227, 3, 0, 24, 247, 9, 24, + 99, 24, 105, 24, 119, 24, 188, 24, 25, 24, 228, 24, 211, 24, 118, 24, 165, 24, 229, 152, 32, + 24, 228, 24, 196, 24, 102, 11, 24, 162, 24, 178, 24, 156, 24, 198, 24, 74, 24, 176, 24, 127, + 24, 193, 24, 89, 24, 168, 24, 134, 24, 41, 24, 121, 24, 144, 24, 221, 24, 176, 24, 208, 24, + 124, 24, 154, 24, 233, 24, 52, 24, 161, 24, 47, 24, 157, 24, 245, 24, 111, 24, 123, 8, 152, 32, + 24, 78, 24, 96, 24, 125, 24, 48, 24, 27, 24, 166, 4, 15, 24, 76, 24, 119, 24, 138, 24, 199, 24, + 106, 24, 59, 24, 40, 24, 88, 24, 41, 6, 1, 24, 68, 24, 171, 24, 113, 24, 152, 24, 30, 24, 89, + 24, 61, 24, 170, 2, 14, 14, 24, 197, 24, 149, 152, 32, 24, 117, 24, 77, 24, 204, 24, 150, 24, + 109, 6, 24, 248, 24, 166, 24, 152, 24, 195, 24, 107, 24, 36, 24, 79, 24, 216, 24, 193, 24, 126, + 24, 35, 24, 184, 24, 123, 2, 24, 246, 24, 27, 24, 102, 24, 56, 24, 45, 24, 74, 24, 111, 24, + 114, 24, 165, 9, 24, 251, 24, 140, 152, 32, 24, 225, 17, 24, 135, 24, 213, 24, 249, 24, 150, + 24, 234, 24, 105, 24, 115, 24, 241, 18, 24, 24, 18, 24, 47, 24, 241, 24, 40, 24, 57, 24, 232, + 24, 220, 24, 101, 24, 188, 24, 133, 24, 197, 24, 106, 24, 68, 24, 230, 24, 44, 24, 174, 24, + 161, 24, 250, 24, 174, 24, 213, 152, 32, 24, 241, 24, 94, 24, 45, 24, 156, 24, 33, 24, 159, 24, + 228, 24, 48, 24, 24, 24, 75, 8, 24, 24, 24, 238, 24, 226, 24, 245, 24, 223, 24, 154, 24, 81, + 24, 193, 24, 190, 24, 84, 24, 50, 24, 220, 24, 78, 24, 246, 24, 68, 24, 223, 24, 88, 10, 24, + 177, 24, 160, 24, 146, 152, 32, 24, 30, 24, 68, 24, 149, 24, 170, 24, 215, 24, 85, 24, 46, 24, + 58, 23, 24, 204, 24, 42, 24, 72, 24, 139, 24, 52, 24, 41, 24, 211, 24, 247, 24, 128, 24, 194, + 6, 24, 107, 24, 71, 24, 239, 3, 24, 88, 24, 116, 24, 40, 24, 116, 24, 93, 24, 78, 24, 69, 24, + 209, 120, 36, 108, 100, 101, 95, 99, 111, 109, 112, 111, 115, 105, 116, 105, 111, 110, 95, 112, + 111, 108, 121, 95, 101, 118, 101, 110, 95, 101, 118, 97, 108, 117, 97, 116, 105, 111, 110, 161, + 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 53, 101, 52, 52, 101, 97, 51, 100, 52, 97, 102, + 101, 101, 100, 53, 52, 102, 48, 51, 98, 100, 49, 56, 50, 51, 97, 102, 49, 52, 102, 101, 48, 57, + 54, 51, 50, 102, 53, 56, 52, 52, 101, 56, 101, 53, 55, 56, 102, 99, 51, 99, 57, 50, 56, 99, 54, + 54, 52, 52, 50, 50, 49, 49, 120, 35, 108, 100, 101, 95, 99, 111, 109, 112, 111, 115, 105, 116, + 105, 111, 110, 95, 112, 111, 108, 121, 95, 111, 100, 100, 95, 101, 118, 97, 108, 117, 97, 116, + 105, 111, 110, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 102, 56, 50, 100, 101, + 55, 56, 48, 51, 57, 53, 99, 102, 52, 50, 100, 53, 50, 50, 53, 101, 101, 51, 52, 50, 54, 98, 52, + 102, 49, 48, 48, 52, 99, 54, 98, 52, 100, 98, 50, 54, 56, 54, 52, 51, 48, 53, 98, 100, 53, 57, + 52, 53, 99, 51, 98, 101, 98, 102, 50, 55, 99, 119, 108, 100, 101, 95, 116, 114, 97, 99, 101, + 95, 109, 101, 114, 107, 108, 101, 95, 112, 114, 111, 111, 102, 115, 130, 161, 107, 109, 101, + 114, 107, 108, 101, 95, 112, 97, 116, 104, 136, 152, 32, 24, 247, 24, 140, 24, 115, 24, 195, 6, + 24, 143, 24, 36, 24, 103, 24, 81, 24, 79, 24, 130, 24, 62, 24, 99, 24, 240, 24, 57, 24, 218, + 24, 152, 24, 59, 24, 234, 24, 235, 24, 28, 24, 243, 24, 123, 24, 175, 24, 166, 24, 175, 9, 24, + 88, 24, 182, 24, 170, 24, 149, 3, 152, 32, 24, 43, 24, 178, 24, 226, 24, 61, 24, 231, 24, 124, + 24, 236, 24, 200, 24, 207, 24, 44, 24, 60, 24, 50, 24, 150, 24, 164, 24, 51, 24, 185, 24, 200, + 24, 107, 24, 99, 24, 221, 24, 26, 24, 91, 24, 123, 24, 143, 24, 33, 24, 202, 24, 183, 24, 188, + 24, 74, 24, 33, 24, 61, 24, 116, 152, 32, 24, 28, 24, 134, 24, 67, 24, 187, 24, 145, 24, 59, + 24, 94, 24, 30, 24, 25, 24, 83, 24, 95, 24, 235, 24, 114, 24, 32, 24, 99, 1, 24, 222, 24, 139, + 24, 119, 24, 130, 24, 240, 23, 24, 157, 24, 89, 24, 162, 24, 163, 24, 220, 24, 77, 24, 159, 24, + 154, 24, 234, 24, 93, 152, 32, 24, 192, 24, 127, 24, 200, 24, 220, 24, 102, 24, 157, 24, 48, + 24, 78, 24, 52, 24, 126, 7, 24, 168, 24, 53, 24, 40, 24, 104, 24, 251, 24, 57, 24, 240, 24, 58, + 24, 160, 24, 182, 24, 214, 24, 36, 24, 182, 24, 123, 24, 28, 24, 239, 24, 99, 24, 182, 24, 166, + 24, 141, 24, 255, 152, 32, 24, 205, 24, 234, 10, 24, 32, 24, 67, 24, 170, 24, 166, 24, 45, 24, + 62, 24, 226, 24, 179, 24, 24, 9, 24, 162, 24, 136, 24, 109, 24, 63, 24, 27, 24, 127, 24, 125, + 24, 39, 24, 209, 24, 131, 24, 253, 24, 119, 24, 59, 24, 63, 24, 215, 24, 169, 24, 228, 24, 184, + 24, 101, 152, 32, 24, 49, 24, 114, 24, 81, 24, 125, 24, 123, 24, 59, 24, 165, 24, 117, 24, 100, + 24, 112, 15, 24, 64, 24, 150, 24, 97, 24, 221, 24, 112, 24, 179, 24, 86, 24, 83, 24, 187, 14, + 24, 76, 24, 252, 24, 210, 24, 206, 24, 171, 24, 166, 24, 113, 24, 130, 24, 234, 24, 139, 24, + 121, 152, 32, 24, 179, 24, 99, 24, 136, 24, 92, 24, 62, 24, 236, 24, 196, 10, 24, 83, 24, 253, + 24, 198, 16, 24, 245, 12, 24, 129, 24, 229, 24, 53, 24, 24, 24, 145, 24, 26, 24, 245, 1, 24, + 55, 24, 156, 23, 18, 24, 180, 24, 239, 24, 83, 24, 103, 24, 100, 24, 190, 152, 32, 24, 75, 24, + 81, 24, 75, 24, 37, 24, 196, 24, 183, 24, 151, 24, 197, 24, 230, 24, 52, 24, 62, 24, 78, 24, + 206, 24, 29, 9, 24, 157, 24, 240, 24, 117, 24, 31, 24, 214, 24, 94, 24, 255, 24, 138, 24, 185, + 3, 24, 99, 24, 131, 24, 138, 24, 118, 24, 31, 24, 209, 24, 39, 161, 107, 109, 101, 114, 107, + 108, 101, 95, 112, 97, 116, 104, 136, 152, 32, 24, 76, 24, 113, 24, 149, 24, 150, 24, 226, 24, + 142, 12, 24, 42, 24, 202, 24, 38, 24, 133, 24, 119, 24, 96, 24, 80, 24, 183, 0, 24, 105, 24, + 153, 24, 158, 24, 178, 24, 84, 24, 71, 24, 152, 24, 42, 24, 80, 24, 120, 24, 96, 24, 143, 24, + 28, 24, 214, 24, 32, 24, 157, 152, 32, 24, 248, 24, 222, 24, 65, 24, 189, 24, 211, 24, 201, 8, + 24, 112, 18, 24, 209, 8, 24, 175, 24, 145, 24, 38, 15, 24, 178, 24, 80, 24, 161, 24, 165, 4, + 24, 114, 24, 203, 24, 61, 24, 135, 24, 250, 24, 171, 24, 33, 24, 209, 24, 178, 24, 100, 24, 58, + 24, 182, 152, 32, 24, 173, 24, 124, 24, 150, 24, 138, 24, 159, 24, 179, 24, 74, 24, 68, 24, + 103, 24, 83, 24, 106, 24, 210, 24, 178, 24, 237, 24, 179, 24, 244, 24, 77, 24, 111, 24, 77, 24, + 104, 23, 24, 52, 5, 24, 94, 24, 56, 24, 148, 24, 31, 24, 78, 24, 184, 24, 87, 24, 70, 24, 240, + 152, 32, 24, 67, 24, 131, 24, 128, 24, 26, 24, 35, 24, 69, 24, 244, 15, 24, 97, 24, 234, 24, + 70, 24, 75, 17, 24, 179, 24, 133, 24, 159, 24, 228, 24, 154, 24, 163, 24, 172, 24, 179, 13, 18, + 24, 137, 24, 150, 24, 251, 9, 24, 215, 24, 204, 24, 193, 24, 29, 24, 195, 152, 32, 24, 63, 24, + 99, 24, 198, 24, 78, 24, 122, 24, 44, 7, 24, 36, 24, 44, 24, 46, 24, 27, 24, 253, 24, 203, 18, + 24, 102, 24, 238, 19, 24, 190, 24, 137, 24, 48, 24, 59, 24, 150, 24, 218, 24, 141, 24, 207, 24, + 225, 13, 24, 109, 24, 203, 24, 170, 24, 186, 24, 232, 152, 32, 24, 209, 24, 173, 21, 24, 24, + 24, 149, 24, 252, 24, 254, 24, 128, 24, 209, 24, 199, 24, 215, 24, 112, 24, 226, 24, 29, 24, + 233, 24, 161, 24, 68, 24, 38, 24, 30, 24, 73, 24, 174, 24, 69, 24, 104, 24, 224, 24, 53, 24, + 238, 24, 251, 24, 132, 24, 208, 24, 102, 24, 130, 24, 254, 152, 32, 24, 93, 24, 194, 24, 135, + 24, 238, 24, 96, 24, 175, 24, 79, 4, 22, 22, 24, 64, 9, 24, 78, 24, 214, 24, 247, 24, 238, 24, + 73, 24, 31, 24, 128, 22, 24, 71, 24, 75, 24, 34, 24, 178, 24, 39, 24, 188, 24, 174, 5, 24, 249, + 24, 157, 24, 191, 4, 152, 32, 23, 24, 160, 24, 63, 24, 234, 24, 117, 15, 24, 142, 24, 222, 24, + 217, 24, 226, 24, 118, 17, 24, 148, 24, 54, 24, 157, 24, 106, 24, 35, 24, 151, 24, 192, 24, + 137, 24, 31, 24, 214, 24, 152, 24, 231, 24, 193, 1, 24, 139, 24, 99, 24, 133, 24, 151, 24, 130, + 24, 180, 117, 108, 100, 101, 95, 116, 114, 97, 99, 101, 95, 101, 118, 97, 108, 117, 97, 116, + 105, 111, 110, 115, 152, 52, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 56, 51, + 48, 52, 54, 55, 51, 97, 56, 54, 48, 57, 98, 57, 51, 54, 56, 49, 51, 54, 54, 50, 57, 48, 98, + 101, 57, 56, 99, 50, 56, 100, 100, 50, 48, 49, 102, 99, 100, 101, 100, 54, 99, 49, 97, 50, 99, + 53, 53, 57, 49, 55, 56, 100, 53, 97, 52, 54, 101, 97, 100, 98, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 54, 51, 48, 51, 99, 51, 101, 102, 99, 55, 57, 55, 52, 55, 55, 50, 51, + 98, 101, 57, 57, 100, 53, 48, 52, 54, 98, 48, 53, 50, 55, 56, 52, 101, 97, 51, 101, 98, 53, 52, + 51, 100, 54, 57, 57, 100, 54, 100, 50, 100, 51, 100, 102, 51, 97, 48, 102, 55, 100, 99, 49, 51, + 54, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 100, 53, 50, 101, 100, 57, 102, + 102, 48, 98, 100, 49, 48, 55, 101, 100, 55, 48, 98, 100, 55, 49, 49, 50, 98, 57, 50, 99, 102, + 53, 52, 52, 57, 97, 52, 97, 97, 56, 102, 53, 101, 53, 48, 57, 52, 100, 101, 50, 48, 48, 51, 55, + 102, 55, 51, 49, 98, 99, 102, 101, 57, 102, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, + 50, 49, 98, 57, 50, 49, 50, 49, 49, 97, 48, 53, 57, 53, 48, 53, 99, 99, 97, 53, 98, 53, 50, 55, + 97, 100, 52, 52, 52, 50, 56, 102, 55, 49, 97, 97, 51, 97, 102, 101, 55, 98, 56, 51, 53, 100, + 50, 102, 49, 57, 54, 102, 51, 50, 51, 99, 54, 49, 56, 102, 98, 49, 57, 161, 101, 118, 97, 108, + 117, 101, 120, 65, 48, 120, 55, 48, 102, 51, 102, 49, 51, 101, 102, 53, 51, 100, 53, 99, 57, + 98, 53, 99, 52, 101, 55, 51, 99, 55, 50, 55, 50, 56, 101, 101, 49, 99, 52, 52, 98, 49, 49, 97, + 55, 50, 50, 54, 50, 99, 48, 100, 102, 50, 99, 54, 56, 100, 52, 101, 53, 48, 56, 50, 97, 48, 54, + 52, 98, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 56, 56, 54, 101, 102, 54, 57, + 102, 50, 51, 57, 99, 99, 49, 54, 50, 49, 52, 52, 55, 97, 100, 97, 51, 55, 102, 101, 100, 97, + 57, 54, 49, 99, 99, 101, 54, 99, 57, 51, 97, 102, 101, 101, 51, 53, 97, 97, 97, 50, 49, 56, 51, + 51, 53, 102, 100, 50, 99, 48, 57, 54, 56, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 48, + 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 52, 101, 49, 51, 53, 97, 54, 101, 52, 102, + 52, 101, 54, 52, 53, 100, 55, 101, 99, 50, 101, 53, 51, 52, 57, 56, 50, 48, 49, 49, 56, 48, 50, + 49, 99, 51, 100, 53, 55, 57, 98, 52, 99, 50, 57, 97, 49, 54, 49, 53, 98, 55, 48, 101, 49, 102, + 54, 54, 102, 53, 100, 54, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 99, 102, 99, + 51, 99, 49, 48, 51, 56, 54, 56, 98, 57, 57, 100, 99, 52, 49, 54, 54, 50, 97, 102, 98, 57, 52, + 102, 97, 100, 56, 55, 98, 49, 53, 99, 49, 52, 97, 98, 99, 50, 57, 54, 54, 50, 57, 50, 100, 50, + 99, 50, 48, 99, 53, 102, 48, 56, 50, 51, 101, 99, 99, 161, 101, 118, 97, 108, 117, 101, 120, + 65, 48, 120, 50, 51, 52, 102, 49, 48, 99, 99, 99, 51, 54, 98, 98, 53, 52, 100, 57, 48, 50, 55, + 51, 55, 100, 53, 99, 50, 54, 55, 56, 98, 49, 48, 100, 98, 48, 51, 101, 50, 55, 54, 53, 50, 49, + 102, 102, 48, 56, 97, 102, 52, 51, 54, 48, 55, 102, 51, 97, 100, 102, 102, 53, 48, 53, 161, + 101, 118, 97, 108, 117, 101, 99, 48, 120, 48, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, + 120, 55, 98, 53, 99, 53, 101, 48, 50, 53, 50, 100, 52, 100, 52, 48, 102, 51, 54, 101, 100, 51, + 98, 50, 48, 57, 49, 102, 49, 99, 51, 52, 100, 102, 102, 50, 57, 53, 48, 48, 97, 98, 101, 52, + 101, 100, 51, 49, 51, 100, 57, 98, 49, 50, 56, 56, 53, 51, 100, 101, 57, 102, 56, 161, 101, + 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 99, 102, 99, 51, 99, 49, 48, 51, 56, 54, 56, 98, + 57, 57, 100, 99, 52, 49, 54, 54, 50, 97, 102, 98, 57, 52, 102, 97, 100, 56, 55, 98, 49, 53, 99, + 49, 52, 97, 98, 99, 50, 57, 54, 54, 50, 57, 50, 100, 50, 99, 50, 48, 99, 53, 102, 48, 56, 50, + 51, 101, 99, 99, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 52, 101, 49, 51, 53, 97, + 54, 101, 52, 102, 52, 101, 54, 52, 53, 100, 55, 101, 99, 50, 101, 53, 51, 52, 57, 56, 50, 48, + 49, 49, 56, 48, 50, 49, 99, 51, 100, 53, 55, 57, 98, 52, 99, 50, 57, 97, 49, 54, 49, 53, 98, + 55, 48, 101, 49, 102, 54, 54, 102, 53, 100, 54, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, + 120, 51, 97, 100, 51, 55, 100, 55, 99, 49, 102, 51, 54, 97, 98, 100, 101, 100, 51, 100, 54, 51, + 55, 50, 55, 51, 97, 99, 54, 99, 54, 52, 102, 55, 49, 56, 51, 99, 98, 56, 54, 52, 102, 102, 100, + 56, 51, 52, 48, 100, 55, 97, 99, 55, 97, 99, 98, 53, 51, 54, 100, 54, 53, 98, 161, 101, 118, + 97, 108, 117, 101, 99, 48, 120, 48, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 56, 55, + 101, 50, 49, 99, 53, 101, 54, 97, 57, 100, 54, 53, 57, 102, 57, 48, 50, 57, 100, 56, 52, 102, + 57, 54, 54, 101, 98, 49, 98, 52, 50, 100, 51, 51, 54, 57, 57, 49, 98, 57, 99, 53, 101, 57, 101, + 57, 51, 56, 57, 55, 53, 55, 102, 51, 97, 101, 57, 98, 53, 97, 161, 101, 118, 97, 108, 117, 101, + 120, 65, 48, 120, 54, 98, 99, 50, 49, 55, 49, 97, 48, 98, 54, 102, 100, 50, 99, 51, 56, 54, 98, + 102, 49, 98, 53, 53, 99, 56, 97, 51, 50, 97, 50, 97, 57, 53, 98, 48, 100, 101, 52, 49, 48, 101, + 52, 49, 48, 56, 97, 53, 50, 56, 99, 54, 57, 57, 53, 101, 57, 57, 98, 53, 51, 48, 50, 161, 101, + 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 99, 51, 48, 51, 98, 54, 55, 101, 102, 98, 101, + 97, 57, 102, 100, 49, 54, 49, 98, 57, 48, 100, 51, 99, 51, 50, 54, 57, 50, 50, 52, 101, 97, 53, + 49, 101, 52, 52, 52, 50, 48, 55, 98, 97, 51, 50, 51, 51, 97, 98, 53, 53, 97, 101, 102, 51, 48, + 49, 49, 57, 53, 51, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 97, 50, 52, 54, 57, + 52, 55, 99, 98, 50, 99, 54, 55, 100, 55, 48, 53, 54, 56, 55, 102, 52, 49, 50, 101, 52, 55, 56, + 48, 53, 54, 56, 48, 49, 101, 55, 97, 57, 97, 55, 101, 54, 102, 56, 97, 100, 51, 56, 57, 99, 53, + 56, 57, 99, 49, 52, 50, 98, 53, 100, 102, 101, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, + 120, 100, 56, 101, 102, 50, 55, 53, 97, 101, 51, 54, 53, 101, 99, 99, 102, 102, 57, 52, 99, 50, + 102, 101, 53, 102, 102, 54, 54, 51, 101, 48, 57, 53, 53, 54, 49, 101, 55, 50, 97, 55, 49, 53, + 100, 97, 101, 57, 49, 56, 53, 57, 53, 100, 101, 57, 48, 52, 48, 54, 51, 51, 54, 161, 101, 118, + 97, 108, 117, 101, 120, 64, 48, 120, 56, 97, 52, 102, 57, 100, 98, 55, 55, 97, 52, 57, 99, 53, + 100, 51, 100, 53, 50, 48, 51, 102, 57, 52, 102, 57, 97, 99, 50, 98, 54, 57, 50, 49, 48, 100, + 99, 102, 97, 101, 98, 102, 100, 102, 57, 55, 48, 102, 99, 51, 49, 99, 55, 97, 99, 48, 57, 54, + 102, 50, 102, 53, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 102, 53, 100, 48, 52, + 57, 97, 52, 52, 97, 98, 50, 56, 57, 57, 50, 54, 97, 51, 102, 48, 98, 51, 99, 51, 101, 56, 51, + 52, 50, 98, 55, 102, 54, 54, 48, 98, 53, 54, 50, 56, 48, 55, 99, 52, 51, 56, 101, 101, 53, 55, + 50, 48, 99, 97, 100, 56, 101, 100, 99, 57, 50, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, + 120, 52, 49, 50, 48, 98, 56, 50, 51, 98, 102, 53, 56, 50, 51, 52, 49, 56, 97, 50, 99, 99, 48, + 101, 97, 97, 100, 49, 51, 49, 99, 99, 55, 49, 97, 53, 99, 99, 51, 101, 53, 49, 48, 54, 50, 57, + 57, 101, 55, 54, 51, 102, 48, 50, 100, 53, 99, 99, 48, 56, 97, 53, 99, 50, 161, 101, 118, 97, + 108, 117, 101, 120, 65, 48, 120, 51, 49, 50, 54, 102, 97, 101, 54, 98, 101, 55, 102, 50, 97, + 101, 51, 54, 51, 97, 48, 55, 98, 50, 101, 102, 52, 99, 57, 99, 100, 56, 102, 50, 55, 49, 97, + 48, 99, 56, 97, 55, 49, 56, 98, 102, 51, 54, 101, 48, 52, 55, 50, 50, 51, 100, 53, 100, 56, 52, + 53, 101, 53, 50, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 55, 97, 98, 55, 52, 51, + 57, 54, 99, 56, 52, 50, 57, 51, 56, 49, 56, 50, 53, 102, 99, 102, 53, 102, 98, 49, 50, 55, 48, + 54, 100, 100, 49, 97, 49, 51, 98, 51, 52, 102, 100, 48, 100, 51, 100, 53, 48, 48, 51, 56, 56, + 101, 51, 48, 52, 102, 53, 51, 97, 50, 50, 50, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, + 120, 49, 102, 51, 56, 57, 52, 98, 49, 97, 57, 102, 52, 49, 54, 98, 102, 55, 56, 57, 99, 101, + 51, 98, 52, 50, 51, 56, 53, 99, 57, 51, 54, 100, 54, 99, 102, 54, 48, 55, 52, 55, 56, 53, 53, + 99, 100, 97, 56, 49, 97, 49, 52, 57, 101, 101, 54, 49, 48, 99, 99, 101, 97, 56, 161, 101, 118, + 97, 108, 117, 101, 120, 65, 48, 120, 53, 57, 51, 50, 97, 97, 97, 102, 102, 49, 99, 57, 98, 55, + 48, 100, 98, 102, 52, 97, 57, 56, 54, 50, 102, 52, 49, 100, 98, 50, 56, 50, 100, 57, 50, 97, + 97, 55, 54, 56, 50, 101, 101, 102, 52, 53, 48, 99, 99, 54, 57, 53, 57, 101, 49, 101, 48, 57, + 57, 99, 56, 101, 52, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 57, 56, 53, 50, 99, + 98, 56, 102, 100, 49, 49, 56, 50, 99, 97, 53, 49, 48, 57, 55, 101, 98, 54, 54, 56, 51, 52, 49, + 98, 57, 48, 52, 98, 51, 56, 99, 98, 55, 97, 55, 97, 55, 56, 100, 56, 101, 54, 48, 51, 50, 54, + 54, 56, 53, 99, 100, 102, 56, 102, 97, 54, 53, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, + 120, 49, 51, 50, 97, 50, 55, 57, 50, 52, 100, 48, 97, 98, 56, 50, 50, 55, 51, 57, 99, 97, 53, + 100, 101, 48, 52, 98, 53, 101, 99, 50, 53, 102, 102, 101, 101, 52, 49, 98, 55, 102, 53, 99, + 102, 56, 49, 50, 48, 53, 49, 51, 101, 54, 99, 56, 54, 55, 51, 97, 54, 55, 50, 57, 161, 101, + 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 56, 98, 50, 98, 52, 99, 100, 51, 52, 52, 56, 97, + 56, 100, 52, 56, 100, 50, 98, 97, 54, 98, 48, 55, 101, 56, 57, 50, 53, 98, 53, 52, 49, 53, 55, + 55, 55, 50, 57, 100, 52, 52, 54, 51, 101, 101, 57, 98, 102, 100, 50, 98, 48, 56, 102, 56, 48, + 100, 55, 101, 56, 101, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 57, 97, 50, 98, 53, + 99, 56, 49, 99, 54, 52, 52, 55, 49, 97, 52, 54, 101, 99, 53, 102, 48, 57, 99, 101, 50, 50, 49, + 53, 54, 57, 54, 48, 101, 49, 50, 57, 99, 48, 50, 50, 51, 102, 51, 102, 53, 48, 57, 99, 48, 57, + 52, 101, 57, 98, 101, 53, 50, 48, 100, 57, 98, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, + 120, 53, 55, 51, 50, 51, 100, 98, 53, 50, 52, 99, 51, 54, 48, 48, 55, 101, 48, 57, 97, 52, 53, + 53, 52, 98, 101, 101, 56, 100, 50, 97, 51, 51, 57, 50, 102, 53, 102, 102, 56, 101, 54, 101, 56, + 57, 53, 100, 54, 100, 55, 55, 99, 53, 57, 51, 57, 99, 57, 99, 48, 57, 54, 50, 161, 101, 118, + 97, 108, 117, 101, 120, 65, 48, 120, 51, 57, 51, 57, 101, 48, 54, 56, 53, 57, 52, 54, 53, 97, + 99, 50, 100, 102, 53, 97, 48, 102, 100, 99, 100, 101, 100, 55, 97, 101, 57, 56, 100, 97, 51, + 99, 51, 48, 49, 52, 55, 52, 54, 55, 51, 57, 52, 56, 48, 54, 49, 50, 99, 100, 97, 100, 50, 102, + 97, 56, 48, 54, 97, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 56, 98, 99, 99, 98, + 52, 48, 52, 56, 48, 56, 56, 50, 55, 56, 98, 57, 101, 51, 51, 48, 51, 101, 57, 51, 102, 52, 52, + 56, 102, 48, 55, 97, 48, 50, 49, 52, 49, 98, 57, 56, 49, 54, 101, 52, 49, 53, 100, 102, 57, 49, + 49, 97, 53, 97, 97, 49, 51, 97, 50, 99, 99, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, + 53, 50, 55, 102, 55, 55, 49, 99, 99, 56, 101, 97, 101, 52, 52, 53, 50, 101, 102, 57, 101, 49, + 56, 53, 98, 97, 55, 99, 53, 48, 52, 54, 101, 102, 100, 54, 50, 54, 53, 53, 98, 100, 56, 97, 50, + 51, 97, 100, 55, 97, 54, 99, 54, 56, 48, 53, 50, 101, 97, 98, 50, 54, 101, 161, 101, 118, 97, + 108, 117, 101, 120, 65, 48, 120, 54, 54, 51, 97, 102, 50, 53, 52, 52, 102, 102, 98, 53, 52, 50, + 100, 56, 97, 57, 54, 55, 98, 49, 56, 102, 55, 97, 52, 50, 99, 54, 48, 55, 99, 98, 57, 55, 102, + 55, 97, 57, 55, 53, 102, 99, 101, 48, 54, 100, 57, 98, 98, 57, 53, 51, 55, 49, 52, 52, 57, 99, + 101, 49, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 55, 97, 51, 97, 55, 48, 101, + 102, 52, 49, 54, 102, 54, 52, 98, 100, 50, 51, 98, 53, 52, 97, 54, 48, 52, 57, 99, 49, 48, 52, + 56, 100, 56, 52, 50, 51, 56, 56, 48, 100, 56, 54, 56, 101, 56, 56, 101, 48, 57, 49, 49, 57, 97, + 56, 49, 52, 49, 51, 54, 51, 49, 50, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 53, + 57, 57, 100, 100, 100, 99, 48, 98, 54, 51, 50, 51, 54, 97, 101, 52, 51, 52, 57, 56, 56, 99, 53, + 100, 53, 57, 55, 51, 55, 51, 57, 56, 100, 50, 56, 102, 102, 54, 53, 57, 56, 102, 49, 53, 51, + 98, 56, 55, 97, 54, 57, 55, 56, 48, 51, 99, 57, 98, 57, 97, 50, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 55, 54, 98, 102, 53, 101, 51, 56, 100, 101, 102, 53, 48, 48, 56, 100, + 50, 97, 100, 53, 98, 55, 50, 56, 54, 51, 53, 98, 53, 48, 56, 53, 102, 56, 50, 52, 101, 53, 98, + 98, 99, 100, 55, 102, 99, 49, 55, 102, 102, 98, 50, 55, 101, 100, 54, 97, 102, 102, 52, 53, 56, + 50, 53, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 53, 99, 99, 100, 56, 48, 54, 99, + 49, 57, 56, 101, 52, 49, 101, 100, 51, 48, 52, 50, 98, 56, 57, 97, 57, 50, 50, 51, 51, 98, 49, + 54, 52, 48, 100, 99, 53, 55, 51, 55, 54, 97, 98, 98, 98, 99, 57, 97, 102, 57, 97, 53, 54, 53, + 101, 101, 53, 48, 51, 100, 50, 53, 56, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, + 55, 53, 98, 50, 48, 101, 51, 57, 54, 99, 50, 55, 98, 98, 50, 52, 101, 101, 57, 56, 53, 97, 100, + 101, 98, 50, 50, 50, 50, 55, 97, 102, 51, 50, 99, 50, 50, 53, 49, 55, 53, 51, 53, 55, 52, 56, + 52, 100, 100, 50, 53, 53, 99, 52, 57, 101, 51, 51, 56, 48, 98, 48, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 52, 101, 51, 50, 102, 101, 51, 97, 50, 48, 54, 99, 99, 53, 98, 54, 50, + 102, 97, 52, 53, 101, 51, 51, 98, 101, 48, 50, 51, 101, 51, 101, 56, 57, 102, 49, 98, 57, 99, + 100, 49, 56, 101, 55, 53, 56, 54, 101, 102, 53, 99, 48, 54, 49, 53, 97, 49, 99, 50, 49, 54, 53, + 56, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 55, 100, 48, 52, 98, 53, 55, 50, + 55, 48, 97, 49, 52, 57, 101, 50, 51, 53, 97, 101, 53, 57, 54, 102, 50, 52, 98, 100, 100, 48, + 54, 98, 48, 55, 54, 49, 100, 98, 97, 48, 51, 98, 97, 49, 57, 97, 51, 53, 101, 54, 51, 53, 97, + 53, 98, 98, 100, 98, 102, 54, 101, 52, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, + 101, 50, 55, 48, 102, 99, 97, 55, 49, 53, 48, 100, 52, 50, 98, 57, 100, 102, 50, 56, 54, 52, + 54, 52, 49, 56, 57, 54, 52, 48, 100, 98, 48, 56, 101, 49, 52, 50, 98, 101, 56, 54, 53, 49, 51, + 52, 55, 52, 50, 100, 102, 49, 100, 99, 55, 50, 101, 52, 49, 52, 99, 51, 161, 101, 118, 97, 108, + 117, 101, 120, 65, 48, 120, 51, 56, 55, 55, 48, 48, 57, 102, 100, 49, 99, 56, 53, 102, 48, 53, + 97, 51, 51, 98, 52, 49, 55, 51, 57, 98, 102, 99, 100, 97, 99, 97, 102, 57, 54, 51, 98, 56, 100, + 57, 102, 51, 98, 101, 55, 51, 102, 56, 56, 53, 57, 97, 99, 101, 102, 55, 50, 55, 99, 55, 55, + 99, 57, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 101, 48, 56, 97, 54, 55, 102, + 98, 50, 101, 49, 55, 99, 100, 55, 53, 97, 98, 99, 100, 48, 52, 50, 98, 97, 99, 98, 55, 100, + 102, 55, 51, 51, 99, 53, 56, 53, 55, 97, 97, 52, 99, 102, 99, 97, 99, 56, 57, 99, 101, 53, 57, + 97, 100, 49, 98, 101, 98, 54, 50, 54, 57, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, + 52, 98, 54, 57, 51, 97, 51, 99, 55, 48, 102, 100, 53, 99, 49, 99, 55, 102, 99, 49, 54, 102, 53, + 50, 98, 97, 57, 101, 48, 97, 48, 51, 56, 102, 98, 97, 49, 55, 101, 53, 55, 49, 98, 52, 98, 56, + 56, 98, 55, 52, 51, 55, 54, 53, 57, 101, 52, 48, 97, 101, 50, 51, 51, 161, 101, 118, 97, 108, + 117, 101, 120, 65, 48, 120, 51, 52, 52, 50, 102, 51, 97, 98, 54, 99, 50, 52, 48, 48, 56, 98, + 101, 99, 55, 57, 98, 98, 50, 54, 100, 49, 55, 57, 102, 55, 54, 99, 55, 52, 53, 54, 49, 101, 52, + 48, 100, 50, 48, 51, 100, 102, 51, 100, 57, 52, 100, 98, 100, 50, 50, 48, 52, 102, 101, 100, + 53, 52, 97, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 52, 57, 49, 98, 56, 49, 56, + 48, 55, 52, 99, 101, 48, 98, 101, 50, 51, 57, 56, 98, 50, 53, 49, 102, 48, 55, 97, 98, 50, 54, + 57, 57, 54, 52, 48, 53, 100, 52, 52, 49, 101, 54, 55, 57, 50, 97, 55, 98, 51, 101, 97, 49, 57, + 51, 98, 51, 50, 101, 99, 101, 49, 102, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 53, + 54, 48, 50, 97, 98, 100, 97, 99, 56, 55, 49, 54, 54, 49, 98, 56, 54, 56, 52, 100, 49, 55, 100, + 54, 52, 99, 99, 57, 97, 50, 99, 100, 56, 52, 97, 51, 99, 52, 54, 48, 55, 55, 101, 48, 57, 97, + 53, 48, 50, 49, 56, 100, 56, 98, 52, 99, 53, 102, 56, 101, 101, 49, 161, 101, 118, 97, 108, + 117, 101, 120, 65, 48, 120, 53, 48, 52, 101, 50, 102, 49, 53, 101, 52, 101, 99, 54, 48, 100, + 50, 56, 56, 97, 50, 51, 100, 48, 56, 99, 52, 102, 102, 48, 98, 51, 52, 102, 54, 100, 53, 97, + 56, 53, 53, 102, 51, 54, 97, 97, 50, 99, 51, 52, 99, 48, 101, 52, 57, 51, 98, 102, 48, 99, 50, + 48, 53, 101, 165, 120, 26, 108, 100, 101, 95, 99, 111, 109, 112, 111, 115, 105, 116, 105, 111, + 110, 95, 112, 111, 108, 121, 95, 112, 114, 111, 111, 102, 161, 107, 109, 101, 114, 107, 108, + 101, 95, 112, 97, 116, 104, 136, 152, 32, 24, 198, 24, 128, 24, 156, 24, 84, 24, 168, 24, 67, + 24, 220, 24, 197, 24, 237, 24, 145, 24, 167, 24, 194, 24, 239, 1, 24, 194, 24, 250, 24, 118, + 24, 182, 24, 80, 24, 179, 2, 24, 48, 11, 24, 143, 24, 188, 24, 191, 24, 222, 24, 43, 24, 255, + 24, 147, 24, 233, 18, 152, 32, 12, 24, 228, 24, 164, 0, 24, 26, 24, 212, 24, 239, 24, 244, 24, + 173, 24, 52, 24, 243, 24, 255, 24, 229, 24, 224, 24, 91, 24, 57, 20, 22, 24, 189, 24, 209, 5, + 24, 144, 24, 148, 24, 51, 24, 43, 24, 71, 24, 73, 24, 151, 24, 140, 24, 162, 24, 209, 24, 80, + 152, 32, 24, 134, 24, 81, 24, 68, 24, 114, 24, 31, 24, 153, 12, 24, 170, 24, 47, 24, 175, 24, + 138, 24, 26, 24, 56, 24, 91, 24, 209, 24, 77, 24, 121, 24, 49, 24, 164, 24, 242, 24, 83, 24, + 70, 24, 26, 24, 204, 24, 254, 24, 63, 24, 24, 24, 24, 24, 91, 24, 144, 24, 250, 24, 146, 152, + 32, 24, 192, 24, 238, 24, 140, 24, 44, 24, 223, 24, 106, 24, 120, 24, 50, 24, 49, 16, 24, 67, + 24, 201, 24, 57, 24, 68, 24, 233, 24, 233, 24, 25, 24, 249, 24, 34, 24, 159, 24, 210, 24, 190, + 24, 83, 24, 130, 24, 108, 24, 77, 24, 73, 24, 150, 24, 78, 24, 75, 24, 60, 24, 35, 152, 32, 24, + 223, 24, 25, 24, 249, 24, 201, 24, 65, 24, 203, 24, 116, 24, 184, 24, 143, 24, 97, 24, 249, 24, + 170, 24, 180, 24, 159, 24, 130, 24, 137, 24, 229, 24, 206, 24, 157, 24, 215, 24, 89, 24, 41, + 24, 229, 24, 169, 24, 217, 20, 24, 134, 24, 210, 24, 255, 24, 24, 24, 85, 24, 100, 152, 32, 24, + 111, 24, 100, 24, 219, 24, 102, 24, 49, 24, 197, 24, 127, 24, 28, 24, 33, 24, 100, 24, 111, 24, + 132, 24, 147, 10, 24, 104, 24, 171, 24, 143, 24, 208, 24, 149, 24, 86, 24, 169, 0, 24, 246, 24, + 255, 24, 237, 24, 57, 24, 202, 24, 196, 24, 43, 24, 114, 24, 99, 8, 152, 32, 19, 24, 185, 24, + 162, 24, 83, 24, 209, 24, 28, 24, 97, 24, 244, 24, 82, 24, 247, 24, 42, 24, 165, 9, 14, 24, + 108, 1, 24, 174, 24, 183, 24, 80, 24, 158, 24, 249, 24, 219, 24, 92, 24, 177, 24, 144, 24, 102, + 24, 204, 24, 246, 24, 196, 5, 24, 130, 24, 180, 152, 32, 24, 194, 24, 161, 24, 188, 24, 192, + 24, 98, 24, 70, 24, 209, 24, 164, 24, 124, 24, 208, 24, 232, 17, 24, 146, 19, 24, 139, 24, 36, + 24, 96, 24, 53, 24, 143, 24, 87, 24, 220, 24, 212, 24, 254, 24, 177, 24, 40, 24, 176, 24, 210, + 24, 110, 24, 147, 24, 168, 24, 50, 24, 62, 120, 36, 108, 100, 101, 95, 99, 111, 109, 112, 111, + 115, 105, 116, 105, 111, 110, 95, 112, 111, 108, 121, 95, 101, 118, 101, 110, 95, 101, 118, 97, + 108, 117, 97, 116, 105, 111, 110, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 48, + 101, 100, 100, 52, 51, 100, 50, 55, 56, 98, 49, 50, 98, 98, 51, 51, 55, 51, 48, 102, 55, 53, + 100, 50, 56, 97, 101, 97, 50, 54, 100, 54, 57, 102, 49, 97, 98, 57, 97, 100, 56, 101, 50, 99, + 98, 49, 51, 50, 50, 52, 53, 101, 56, 101, 50, 50, 54, 99, 102, 51, 52, 120, 35, 108, 100, 101, + 95, 99, 111, 109, 112, 111, 115, 105, 116, 105, 111, 110, 95, 112, 111, 108, 121, 95, 111, 100, + 100, 95, 101, 118, 97, 108, 117, 97, 116, 105, 111, 110, 161, 101, 118, 97, 108, 117, 101, 120, + 65, 48, 120, 50, 53, 51, 52, 50, 51, 50, 98, 55, 100, 99, 100, 100, 55, 52, 97, 57, 51, 100, + 99, 57, 53, 52, 57, 97, 100, 56, 102, 48, 98, 54, 56, 53, 51, 56, 97, 98, 53, 52, 56, 54, 101, + 99, 99, 97, 100, 54, 53, 100, 51, 97, 102, 54, 56, 56, 49, 99, 48, 99, 99, 56, 101, 99, 119, + 108, 100, 101, 95, 116, 114, 97, 99, 101, 95, 109, 101, 114, 107, 108, 101, 95, 112, 114, 111, + 111, 102, 115, 130, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 136, 152, + 32, 4, 24, 58, 24, 226, 24, 25, 24, 93, 24, 55, 24, 60, 22, 24, 133, 24, 46, 24, 71, 24, 184, + 24, 40, 24, 144, 24, 91, 24, 219, 24, 137, 24, 209, 24, 183, 21, 24, 114, 24, 108, 24, 191, 24, + 119, 24, 68, 24, 179, 24, 192, 24, 153, 24, 177, 24, 99, 24, 181, 24, 61, 152, 32, 24, 178, 24, + 182, 24, 215, 24, 183, 16, 24, 99, 24, 26, 24, 93, 24, 90, 24, 66, 24, 249, 24, 175, 24, 52, + 24, 236, 24, 205, 24, 82, 24, 140, 24, 86, 24, 165, 24, 174, 24, 141, 24, 94, 24, 28, 24, 164, + 24, 151, 24, 145, 24, 135, 24, 43, 24, 237, 24, 83, 24, 241, 24, 135, 152, 32, 18, 24, 72, 24, + 142, 24, 85, 24, 204, 24, 198, 24, 24, 24, 68, 24, 175, 24, 254, 18, 24, 32, 24, 185, 24, 250, + 24, 255, 24, 58, 24, 188, 22, 24, 112, 24, 34, 24, 193, 12, 24, 248, 24, 192, 24, 218, 24, 132, + 24, 151, 24, 225, 24, 48, 24, 171, 24, 77, 24, 86, 152, 32, 15, 24, 125, 24, 25, 19, 24, 220, + 24, 255, 24, 124, 24, 210, 24, 117, 24, 88, 24, 169, 24, 144, 24, 171, 24, 252, 9, 24, 181, 24, + 160, 24, 115, 24, 88, 24, 34, 24, 114, 24, 109, 24, 218, 24, 153, 24, 181, 24, 110, 24, 50, 22, + 24, 168, 24, 208, 24, 88, 24, 123, 152, 32, 24, 111, 24, 47, 24, 72, 24, 56, 24, 168, 24, 66, + 24, 98, 12, 3, 24, 101, 24, 93, 24, 151, 24, 24, 24, 190, 24, 182, 24, 137, 24, 150, 24, 103, + 24, 119, 24, 157, 24, 25, 24, 221, 24, 246, 24, 175, 24, 131, 24, 215, 24, 180, 24, 25, 24, + 223, 24, 73, 24, 89, 24, 144, 152, 32, 24, 103, 24, 138, 24, 203, 24, 58, 24, 185, 24, 159, 24, + 29, 24, 147, 24, 172, 24, 173, 24, 91, 24, 235, 24, 29, 24, 121, 24, 113, 24, 175, 24, 234, 24, + 148, 11, 24, 61, 24, 113, 24, 50, 24, 34, 24, 97, 24, 113, 24, 109, 24, 77, 24, 35, 24, 227, + 24, 233, 24, 249, 24, 177, 152, 32, 24, 239, 24, 152, 24, 90, 24, 100, 24, 105, 5, 24, 229, 24, + 115, 24, 246, 24, 176, 24, 94, 24, 33, 24, 247, 24, 89, 24, 74, 24, 113, 24, 45, 24, 154, 24, + 82, 24, 96, 24, 232, 24, 192, 24, 126, 24, 124, 24, 238, 24, 106, 24, 241, 24, 206, 24, 117, + 24, 60, 24, 108, 24, 199, 152, 32, 10, 24, 92, 1, 24, 40, 24, 202, 24, 225, 24, 50, 24, 91, 24, + 233, 24, 24, 24, 242, 24, 227, 24, 189, 24, 99, 20, 24, 92, 24, 147, 24, 94, 15, 24, 162, 24, + 95, 24, 198, 24, 214, 24, 217, 24, 177, 24, 172, 24, 87, 24, 175, 21, 24, 218, 24, 236, 24, + 105, 161, 107, 109, 101, 114, 107, 108, 101, 95, 112, 97, 116, 104, 136, 152, 32, 24, 174, 24, + 169, 6, 24, 129, 24, 114, 24, 72, 24, 44, 24, 150, 24, 127, 24, 155, 24, 46, 24, 56, 24, 30, + 18, 23, 24, 156, 24, 213, 24, 208, 24, 81, 2, 24, 36, 24, 123, 24, 203, 24, 26, 24, 211, 24, + 207, 0, 24, 249, 24, 50, 24, 76, 24, 174, 24, 213, 152, 32, 24, 241, 24, 151, 24, 228, 24, 128, + 24, 97, 24, 219, 24, 121, 24, 43, 24, 219, 24, 87, 8, 24, 224, 24, 156, 18, 24, 83, 1, 16, 24, + 201, 24, 103, 24, 169, 24, 33, 24, 57, 24, 114, 24, 38, 24, 83, 24, 24, 24, 38, 13, 24, 104, + 24, 124, 24, 38, 24, 221, 152, 32, 24, 202, 24, 148, 24, 212, 24, 172, 24, 218, 24, 138, 24, + 172, 24, 83, 24, 45, 24, 24, 24, 228, 24, 90, 24, 197, 24, 235, 24, 173, 24, 208, 24, 43, 24, + 79, 24, 187, 24, 68, 24, 166, 24, 110, 24, 219, 24, 235, 24, 89, 24, 93, 24, 250, 24, 88, 24, + 129, 24, 240, 7, 24, 67, 152, 32, 24, 229, 24, 56, 10, 24, 249, 24, 96, 24, 57, 24, 45, 24, + 147, 24, 239, 24, 78, 8, 24, 191, 24, 81, 24, 75, 24, 35, 24, 78, 11, 24, 122, 24, 126, 24, + 131, 24, 214, 24, 162, 24, 72, 24, 109, 24, 120, 24, 27, 24, 170, 24, 57, 24, 93, 24, 29, 10, + 24, 116, 152, 32, 24, 197, 24, 215, 24, 88, 4, 24, 77, 24, 239, 24, 148, 24, 75, 24, 168, 24, + 251, 24, 179, 24, 162, 24, 133, 24, 193, 24, 248, 24, 171, 24, 227, 24, 192, 24, 62, 24, 84, + 24, 29, 24, 195, 24, 182, 24, 219, 24, 126, 24, 123, 24, 63, 24, 88, 24, 101, 24, 176, 24, 97, + 24, 174, 152, 32, 24, 157, 24, 142, 24, 67, 24, 245, 24, 41, 24, 125, 24, 59, 24, 237, 24, 57, + 24, 73, 24, 165, 24, 224, 24, 147, 24, 182, 24, 129, 24, 71, 24, 36, 22, 24, 67, 24, 27, 24, + 46, 24, 151, 24, 127, 24, 229, 24, 129, 24, 111, 24, 104, 24, 120, 24, 211, 24, 188, 24, 159, + 24, 199, 152, 32, 0, 24, 178, 24, 163, 24, 195, 24, 215, 24, 211, 24, 161, 24, 150, 24, 50, 24, + 160, 24, 190, 24, 103, 6, 24, 240, 24, 83, 24, 84, 24, 201, 24, 220, 24, 134, 24, 177, 24, 126, + 14, 24, 149, 2, 24, 242, 24, 128, 24, 130, 24, 248, 24, 109, 24, 116, 24, 247, 24, 156, 152, + 32, 24, 95, 21, 24, 128, 24, 112, 24, 203, 24, 200, 24, 36, 24, 59, 7, 24, 151, 24, 51, 24, + 144, 24, 142, 24, 207, 24, 221, 24, 134, 24, 218, 24, 32, 2, 24, 69, 24, 166, 21, 24, 247, 24, + 28, 24, 159, 24, 62, 24, 211, 24, 116, 24, 126, 24, 61, 24, 183, 24, 76, 117, 108, 100, 101, + 95, 116, 114, 97, 99, 101, 95, 101, 118, 97, 108, 117, 97, 116, 105, 111, 110, 115, 152, 52, + 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 53, 56, 99, 52, 102, 53, 97, 101, 56, + 99, 102, 101, 100, 99, 51, 101, 57, 49, 55, 100, 54, 49, 49, 57, 52, 56, 57, 48, 101, 49, 54, + 56, 51, 49, 52, 55, 53, 48, 49, 98, 100, 54, 48, 97, 99, 57, 99, 98, 101, 48, 101, 98, 54, 53, + 52, 48, 98, 101, 53, 100, 48, 50, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 102, + 53, 97, 55, 54, 49, 102, 54, 52, 99, 102, 49, 55, 97, 101, 101, 102, 97, 102, 56, 99, 100, 53, + 52, 55, 55, 48, 51, 55, 54, 98, 49, 99, 98, 98, 49, 48, 100, 51, 101, 102, 97, 97, 53, 48, 49, + 56, 48, 97, 50, 99, 54, 55, 97, 54, 97, 55, 49, 102, 102, 102, 97, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 50, 99, 56, 101, 48, 50, 102, 54, 48, 101, 56, 50, 56, 57, 55, 50, 98, + 55, 57, 51, 56, 99, 98, 49, 98, 52, 50, 48, 100, 57, 57, 101, 97, 52, 101, 101, 55, 55, 97, 48, + 51, 55, 99, 48, 49, 99, 99, 100, 49, 101, 101, 48, 101, 48, 53, 54, 51, 98, 55, 48, 51, 48, + 102, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 99, 101, 50, 49, 56, 48, 51, 102, + 51, 52, 51, 98, 98, 97, 56, 98, 55, 57, 57, 53, 57, 52, 98, 97, 50, 54, 55, 54, 99, 51, 57, + 101, 48, 57, 51, 99, 50, 57, 101, 48, 50, 55, 51, 97, 49, 51, 56, 49, 97, 53, 55, 49, 50, 97, + 57, 48, 55, 55, 98, 54, 56, 102, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 54, + 56, 102, 101, 53, 48, 53, 102, 101, 51, 57, 98, 98, 102, 52, 57, 48, 100, 51, 49, 97, 48, 50, + 97, 57, 55, 55, 98, 97, 50, 55, 55, 97, 55, 100, 99, 53, 99, 49, 99, 53, 99, 99, 52, 49, 102, + 97, 99, 54, 99, 56, 48, 100, 48, 48, 98, 100, 49, 52, 54, 54, 52, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 54, 56, 52, 101, 52, 101, 97, 102, 97, 49, 98, 54, 101, 54, 51, 101, + 101, 57, 54, 54, 101, 101, 56, 98, 57, 100, 52, 99, 57, 53, 51, 50, 48, 97, 51, 101, 100, 99, + 53, 51, 53, 100, 48, 101, 102, 48, 56, 100, 48, 53, 49, 48, 57, 55, 52, 97, 99, 102, 52, 56, + 97, 52, 48, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 48, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 51, 56, 98, 51, 53, 54, 99, 99, 52, 56, 52, 99, 51, 100, 51, 100, 48, + 51, 56, 101, 57, 51, 100, 100, 50, 54, 52, 98, 97, 102, 102, 55, 57, 53, 54, 55, 102, 97, 102, + 98, 50, 55, 55, 52, 52, 52, 51, 54, 56, 54, 49, 52, 53, 102, 54, 97, 101, 100, 48, 51, 56, 102, + 98, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 48, 97, 53, 56, 57, 101, 48, 57, + 98, 51, 48, 101, 57, 54, 49, 49, 48, 53, 48, 55, 51, 50, 97, 98, 56, 56, 102, 99, 56, 57, 52, + 101, 51, 52, 52, 101, 102, 50, 99, 49, 48, 53, 53, 97, 102, 101, 55, 102, 53, 100, 51, 57, 56, + 53, 57, 53, 56, 101, 48, 48, 48, 56, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, + 99, 100, 56, 102, 56, 56, 101, 97, 48, 56, 51, 98, 49, 57, 54, 101, 53, 56, 57, 52, 50, 51, 52, + 54, 101, 51, 100, 53, 101, 49, 101, 101, 100, 97, 99, 55, 97, 48, 54, 57, 53, 101, 99, 54, 56, + 54, 54, 51, 55, 102, 97, 53, 54, 101, 57, 49, 101, 101, 50, 52, 48, 56, 161, 101, 118, 97, 108, + 117, 101, 99, 48, 120, 48, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 55, 51, 97, 54, + 98, 98, 100, 99, 52, 101, 55, 50, 51, 54, 57, 56, 98, 56, 97, 53, 55, 51, 98, 53, 57, 54, 55, + 56, 51, 49, 48, 54, 51, 97, 100, 99, 51, 100, 99, 52, 100, 56, 49, 51, 51, 57, 100, 100, 98, + 48, 57, 99, 97, 51, 56, 102, 56, 98, 52, 54, 56, 101, 161, 101, 118, 97, 108, 117, 101, 120, + 65, 48, 120, 52, 48, 97, 53, 56, 57, 101, 48, 57, 98, 51, 48, 101, 57, 54, 49, 49, 48, 53, 48, + 55, 51, 50, 97, 98, 56, 56, 102, 99, 56, 57, 52, 101, 51, 52, 52, 101, 102, 50, 99, 49, 48, 53, + 53, 97, 102, 101, 55, 102, 53, 100, 51, 57, 56, 53, 57, 53, 56, 101, 48, 48, 48, 56, 161, 101, + 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 56, 98, 51, 53, 54, 99, 99, 52, 56, 52, 99, 51, + 100, 51, 100, 48, 51, 56, 101, 57, 51, 100, 100, 50, 54, 52, 98, 97, 102, 102, 55, 57, 53, 54, + 55, 102, 97, 102, 98, 50, 55, 55, 52, 52, 52, 51, 54, 56, 54, 49, 52, 53, 102, 54, 97, 101, + 100, 48, 51, 56, 102, 98, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 57, 99, 101, + 50, 54, 99, 52, 55, 98, 102, 102, 50, 57, 101, 98, 48, 54, 57, 55, 98, 54, 99, 51, 98, 50, 101, + 55, 50, 57, 53, 52, 57, 57, 97, 54, 57, 98, 100, 50, 51, 50, 52, 57, 97, 51, 55, 98, 52, 99, + 49, 100, 98, 49, 53, 50, 57, 98, 51, 97, 50, 102, 56, 161, 101, 118, 97, 108, 117, 101, 99, 48, + 120, 48, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 54, 101, 102, 53, 52, 49, 98, + 51, 98, 53, 100, 53, 48, 101, 99, 56, 48, 54, 52, 97, 57, 99, 102, 55, 50, 53, 48, 56, 100, 48, + 100, 52, 56, 99, 55, 100, 56, 57, 53, 55, 51, 57, 101, 57, 98, 48, 54, 50, 56, 56, 97, 50, 99, + 56, 48, 100, 99, 52, 56, 48, 100, 102, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, + 97, 102, 98, 56, 101, 101, 98, 51, 49, 98, 56, 98, 54, 99, 97, 55, 102, 57, 97, 51, 99, 53, + 100, 100, 52, 100, 99, 97, 97, 53, 57, 52, 56, 51, 54, 53, 98, 51, 97, 50, 56, 52, 99, 102, 54, + 101, 99, 102, 98, 102, 100, 101, 99, 97, 48, 55, 100, 51, 98, 51, 54, 48, 161, 101, 118, 97, + 108, 117, 101, 120, 65, 48, 120, 52, 102, 57, 50, 52, 101, 56, 48, 53, 52, 52, 99, 53, 49, 53, + 49, 98, 100, 97, 53, 97, 99, 52, 50, 101, 49, 50, 102, 49, 98, 99, 100, 97, 52, 101, 50, 56, + 56, 100, 97, 98, 55, 102, 100, 51, 56, 99, 49, 51, 55, 50, 101, 98, 54, 100, 102, 101, 53, 99, + 49, 52, 102, 50, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 49, 50, 55, 98, 101, 51, + 50, 97, 49, 100, 99, 54, 50, 56, 99, 101, 53, 48, 52, 54, 53, 54, 54, 49, 51, 57, 53, 48, 98, + 56, 100, 53, 50, 55, 51, 55, 50, 50, 48, 51, 98, 51, 53, 51, 52, 48, 50, 49, 50, 49, 57, 54, + 57, 54, 97, 97, 49, 99, 52, 101, 97, 53, 97, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, + 120, 50, 101, 49, 102, 53, 101, 101, 54, 98, 51, 97, 101, 97, 98, 56, 55, 100, 57, 101, 54, 51, + 100, 101, 53, 97, 100, 98, 99, 102, 101, 55, 102, 54, 56, 54, 102, 56, 51, 97, 52, 101, 48, + 100, 56, 102, 102, 57, 48, 97, 98, 53, 100, 57, 99, 100, 51, 55, 102, 52, 50, 101, 53, 54, 161, + 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 56, 54, 97, 102, 49, 52, 100, 49, 57, 49, + 53, 54, 48, 54, 56, 49, 56, 56, 100, 49, 51, 97, 53, 55, 54, 56, 98, 99, 100, 98, 98, 55, 55, + 51, 53, 101, 48, 57, 52, 100, 55, 101, 99, 56, 99, 101, 54, 51, 53, 98, 102, 56, 101, 49, 49, + 100, 99, 102, 50, 54, 55, 50, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 102, 55, + 51, 48, 101, 100, 48, 48, 51, 51, 99, 99, 54, 56, 102, 100, 102, 54, 57, 101, 50, 98, 101, 52, + 56, 102, 57, 101, 48, 97, 53, 50, 48, 51, 54, 50, 56, 54, 55, 98, 102, 52, 56, 49, 101, 51, 97, + 100, 49, 53, 50, 57, 57, 100, 49, 49, 56, 50, 98, 102, 99, 53, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 50, 102, 97, 101, 55, 57, 55, 54, 102, 100, 54, 101, 52, 99, 100, 57, + 56, 55, 49, 100, 54, 50, 97, 50, 98, 49, 55, 102, 98, 50, 100, 55, 50, 54, 102, 101, 51, 99, + 99, 52, 102, 97, 48, 57, 52, 49, 57, 50, 100, 98, 55, 51, 55, 100, 99, 101, 102, 99, 54, 98, + 48, 50, 48, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 55, 97, 54, 51, 54, 56, 99, 55, + 52, 54, 102, 100, 56, 53, 99, 55, 56, 48, 98, 50, 54, 101, 49, 51, 102, 100, 50, 48, 99, 54, + 97, 101, 101, 99, 51, 51, 55, 102, 98, 52, 54, 55, 52, 100, 50, 97, 53, 48, 57, 101, 50, 97, + 97, 97, 101, 100, 102, 49, 55, 54, 55, 99, 99, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, + 120, 49, 55, 57, 55, 97, 49, 55, 51, 101, 102, 99, 98, 53, 101, 99, 52, 53, 49, 100, 49, 57, + 100, 53, 49, 52, 99, 49, 97, 57, 55, 99, 98, 51, 100, 54, 101, 48, 52, 49, 54, 57, 99, 51, 55, + 98, 55, 50, 98, 55, 99, 51, 49, 57, 99, 49, 55, 99, 49, 48, 101, 57, 99, 52, 161, 101, 118, 97, + 108, 117, 101, 120, 65, 48, 120, 49, 52, 101, 54, 49, 50, 53, 100, 101, 102, 51, 49, 57, 98, + 52, 53, 100, 56, 99, 52, 53, 54, 99, 100, 97, 99, 53, 50, 50, 57, 51, 51, 48, 97, 98, 49, 97, + 102, 53, 48, 53, 53, 52, 49, 102, 55, 57, 54, 48, 98, 102, 50, 99, 50, 101, 53, 57, 49, 57, 49, + 56, 57, 101, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 53, 55, 97, 97, 100, 98, + 52, 100, 54, 99, 52, 54, 101, 55, 102, 99, 100, 51, 57, 98, 50, 50, 48, 48, 102, 51, 48, 100, + 102, 54, 102, 100, 54, 51, 49, 99, 52, 48, 48, 48, 97, 56, 57, 99, 101, 56, 50, 100, 97, 100, + 52, 53, 53, 53, 53, 50, 54, 100, 52, 53, 56, 99, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, + 120, 54, 53, 48, 57, 54, 48, 51, 101, 57, 52, 102, 100, 101, 51, 51, 100, 102, 51, 56, 49, 56, + 101, 55, 50, 55, 101, 100, 101, 54, 52, 97, 49, 56, 101, 48, 97, 50, 98, 101, 100, 48, 48, 99, + 100, 55, 48, 48, 51, 101, 98, 99, 97, 57, 55, 52, 54, 102, 50, 100, 97, 55, 56, 101, 161, 101, + 118, 97, 108, 117, 101, 120, 65, 48, 120, 53, 53, 102, 102, 100, 100, 51, 102, 49, 100, 101, + 52, 100, 98, 97, 100, 99, 50, 51, 51, 97, 102, 49, 53, 52, 97, 55, 54, 99, 52, 52, 101, 101, + 100, 100, 98, 100, 50, 57, 54, 49, 56, 98, 53, 101, 48, 57, 97, 98, 97, 51, 49, 57, 57, 102, + 49, 54, 97, 54, 99, 54, 102, 100, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 99, + 49, 56, 50, 99, 102, 57, 54, 99, 54, 97, 97, 55, 51, 101, 56, 99, 56, 54, 102, 102, 102, 56, + 99, 51, 101, 98, 53, 49, 56, 97, 54, 97, 102, 56, 53, 51, 48, 99, 102, 49, 50, 50, 57, 51, 56, + 98, 102, 50, 50, 98, 54, 53, 54, 55, 56, 49, 53, 102, 51, 49, 101, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 51, 56, 52, 100, 50, 57, 98, 102, 54, 53, 55, 51, 56, 99, 57, 98, 55, + 57, 56, 101, 56, 99, 55, 97, 55, 56, 52, 98, 97, 52, 51, 57, 55, 53, 57, 48, 53, 53, 100, 57, + 102, 51, 52, 50, 48, 98, 98, 54, 57, 50, 100, 50, 97, 54, 99, 100, 98, 53, 102, 56, 100, 101, + 48, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 53, 98, 57, 50, 56, 101, 54, 99, + 56, 100, 49, 98, 53, 55, 98, 50, 48, 56, 55, 56, 99, 50, 52, 97, 50, 99, 53, 100, 54, 51, 99, + 53, 51, 50, 55, 48, 97, 99, 99, 98, 54, 56, 53, 56, 99, 97, 98, 98, 100, 48, 49, 54, 49, 54, + 102, 56, 101, 54, 53, 48, 57, 49, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 53, 56, + 54, 98, 54, 50, 102, 98, 98, 52, 97, 99, 102, 56, 57, 98, 52, 102, 101, 56, 56, 97, 51, 54, 50, + 98, 53, 49, 50, 99, 56, 49, 98, 100, 52, 55, 57, 55, 56, 99, 55, 101, 56, 54, 57, 53, 56, 100, + 50, 98, 55, 52, 52, 101, 102, 57, 49, 98, 56, 102, 99, 101, 54, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 54, 48, 54, 57, 98, 101, 52, 99, 100, 48, 48, 57, 51, 100, 102, 97, 55, + 97, 97, 53, 100, 99, 101, 98, 48, 97, 49, 101, 48, 49, 51, 52, 56, 102, 57, 55, 102, 52, 48, + 48, 49, 56, 100, 99, 56, 54, 57, 56, 98, 57, 57, 52, 97, 53, 54, 54, 98, 54, 102, 101, 50, 56, + 50, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 98, 57, 100, 53, 49, 54, 51, 53, + 48, 99, 97, 54, 49, 49, 54, 48, 53, 51, 99, 98, 53, 53, 48, 48, 98, 48, 49, 48, 50, 98, 102, + 57, 98, 48, 57, 54, 50, 49, 55, 49, 49, 57, 55, 48, 100, 55, 54, 100, 48, 52, 49, 54, 50, 99, + 102, 53, 102, 98, 54, 49, 52, 97, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 53, 55, + 48, 57, 49, 55, 56, 53, 48, 101, 97, 102, 51, 97, 57, 101, 50, 52, 101, 57, 48, 54, 48, 51, 99, + 97, 98, 98, 52, 100, 49, 50, 52, 101, 49, 97, 52, 50, 49, 52, 48, 48, 101, 97, 49, 51, 101, 52, + 54, 48, 101, 56, 97, 56, 54, 99, 52, 48, 100, 97, 102, 56, 48, 161, 101, 118, 97, 108, 117, + 101, 120, 64, 48, 120, 101, 102, 97, 48, 97, 54, 55, 55, 54, 53, 48, 53, 100, 98, 56, 53, 51, + 54, 52, 56, 102, 99, 49, 54, 52, 56, 101, 50, 98, 97, 50, 55, 57, 54, 49, 50, 53, 51, 54, 48, + 97, 55, 99, 52, 49, 53, 48, 48, 99, 48, 98, 57, 54, 101, 51, 49, 54, 57, 99, 97, 56, 51, 161, + 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 50, 101, 100, 97, 57, 53, 54, 56, 53, 51, + 57, 50, 98, 53, 56, 53, 52, 54, 99, 100, 53, 51, 101, 99, 48, 50, 51, 57, 50, 49, 55, 55, 48, + 49, 52, 57, 101, 48, 54, 56, 56, 55, 102, 97, 102, 51, 53, 101, 50, 52, 101, 49, 100, 99, 101, + 57, 53, 99, 48, 48, 99, 50, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 98, 52, + 100, 51, 50, 51, 53, 54, 99, 57, 55, 49, 97, 101, 55, 98, 56, 54, 48, 51, 100, 101, 48, 52, 48, + 57, 48, 50, 55, 102, 53, 99, 57, 48, 57, 98, 54, 57, 55, 97, 56, 53, 48, 53, 57, 51, 49, 100, + 56, 102, 100, 52, 50, 100, 97, 48, 49, 53, 48, 102, 52, 101, 161, 101, 118, 97, 108, 117, 101, + 120, 65, 48, 120, 55, 54, 51, 55, 100, 57, 54, 53, 100, 54, 98, 55, 51, 100, 49, 53, 49, 50, + 99, 101, 51, 100, 54, 51, 55, 56, 54, 54, 99, 49, 99, 50, 98, 100, 102, 53, 52, 55, 54, 100, + 57, 56, 50, 56, 50, 54, 98, 101, 53, 54, 56, 48, 101, 98, 48, 52, 54, 48, 101, 54, 54, 53, 57, + 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 51, 50, 54, 52, 56, 101, 56, 54, 99, 57, + 102, 55, 52, 50, 101, 97, 57, 100, 97, 54, 49, 100, 52, 51, 97, 99, 98, 101, 53, 57, 53, 57, + 54, 101, 98, 57, 48, 55, 101, 53, 55, 55, 100, 57, 57, 54, 52, 52, 49, 53, 54, 54, 97, 51, 100, + 101, 102, 102, 57, 54, 98, 99, 50, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 50, 49, + 99, 55, 56, 56, 52, 57, 53, 49, 53, 101, 56, 53, 50, 52, 56, 100, 54, 53, 57, 51, 50, 52, 57, + 50, 100, 98, 97, 57, 102, 51, 50, 56, 102, 101, 98, 99, 49, 57, 56, 54, 51, 54, 48, 101, 97, + 98, 97, 54, 99, 98, 101, 102, 50, 51, 55, 49, 54, 49, 98, 49, 54, 161, 101, 118, 97, 108, 117, + 101, 120, 65, 48, 120, 50, 48, 101, 100, 101, 57, 53, 50, 55, 56, 98, 98, 99, 55, 51, 99, 57, + 97, 52, 102, 54, 52, 102, 51, 55, 57, 100, 51, 50, 48, 48, 49, 98, 101, 53, 50, 99, 54, 49, 50, + 97, 48, 55, 101, 50, 100, 52, 97, 55, 99, 100, 53, 48, 100, 102, 56, 55, 53, 99, 102, 100, 97, + 100, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 52, 49, 99, 52, 48, 98, 49, 98, 55, + 102, 57, 51, 57, 49, 55, 52, 50, 102, 51, 49, 55, 54, 57, 54, 55, 54, 49, 56, 51, 51, 52, 102, + 56, 99, 53, 50, 102, 57, 99, 97, 56, 97, 99, 102, 102, 56, 49, 54, 50, 53, 49, 50, 54, 53, 56, + 48, 54, 54, 101, 50, 51, 52, 102, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 55, 97, + 54, 102, 50, 51, 54, 49, 49, 101, 51, 102, 57, 99, 101, 99, 51, 50, 56, 49, 55, 51, 51, 48, 50, + 99, 55, 52, 48, 48, 51, 55, 56, 102, 54, 97, 98, 102, 97, 57, 97, 49, 55, 57, 53, 52, 56, 100, + 52, 100, 99, 97, 57, 53, 56, 100, 100, 98, 99, 98, 56, 54, 161, 101, 118, 97, 108, 117, 101, + 120, 65, 48, 120, 52, 52, 56, 51, 51, 55, 48, 55, 53, 97, 99, 51, 102, 99, 55, 53, 54, 52, 101, + 49, 49, 51, 51, 102, 48, 51, 97, 99, 97, 102, 55, 57, 48, 101, 49, 48, 56, 57, 99, 56, 54, 49, + 102, 56, 97, 48, 97, 57, 51, 97, 97, 57, 51, 57, 99, 48, 101, 54, 56, 101, 101, 48, 52, 161, + 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 50, 50, 100, 53, 54, 50, 100, 55, 102, 55, 50, + 55, 50, 48, 55, 57, 50, 101, 97, 52, 51, 101, 57, 99, 49, 54, 101, 49, 51, 102, 56, 102, 57, + 102, 54, 48, 55, 55, 101, 54, 97, 51, 99, 55, 52, 56, 52, 99, 51, 52, 57, 57, 52, 98, 51, 48, + 102, 55, 100, 97, 50, 54, 161, 101, 118, 97, 108, 117, 101, 120, 64, 48, 120, 100, 49, 57, 102, + 97, 99, 97, 98, 97, 52, 50, 99, 54, 99, 57, 57, 48, 54, 100, 57, 102, 57, 57, 98, 102, 48, 54, + 102, 50, 52, 99, 57, 100, 52, 102, 100, 57, 102, 50, 99, 97, 57, 98, 57, 99, 55, 102, 53, 49, + 48, 99, 54, 51, 53, 97, 56, 49, 100, 99, 57, 50, 52, 161, 101, 118, 97, 108, 117, 101, 120, 64, + 48, 120, 49, 98, 52, 98, 99, 56, 102, 55, 55, 52, 51, 97, 55, 100, 48, 101, 51, 48, 56, 50, 52, + 56, 101, 52, 57, 54, 48, 101, 53, 101, 101, 51, 100, 53, 54, 101, 51, 52, 54, 53, 49, 51, 100, + 54, 51, 98, 56, 48, 57, 99, 55, 99, 48, 49, 57, 54, 50, 55, 52, 48, 97, 99, 161, 101, 118, 97, + 108, 117, 101, 120, 65, 48, 120, 52, 53, 101, 102, 50, 57, 52, 50, 49, 51, 101, 99, 100, 101, + 54, 98, 99, 97, 57, 54, 100, 48, 48, 100, 57, 99, 55, 48, 54, 55, 100, 101, 52, 100, 51, 49, + 48, 51, 57, 57, 48, 48, 102, 55, 49, 48, 50, 53, 102, 54, 48, 97, 57, 49, 98, 48, 48, 57, 97, + 49, 51, 49, 57, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 54, 49, 57, 54, 53, 56, + 101, 99, 97, 102, 53, 97, 101, 55, 101, 51, 53, 100, 51, 98, 51, 49, 48, 57, 56, 54, 55, 57, + 57, 53, 101, 51, 52, 99, 49, 100, 56, 57, 50, 55, 100, 57, 53, 102, 98, 57, 101, 49, 55, 99, + 97, 56, 48, 53, 54, 53, 55, 53, 99, 53, 51, 102, 99, 101, 110, 111, 110, 99, 101, 2, +]; + +#[cfg(feature = "wasm")] +static PUBLIC_INPUTS: [u8; 1086] = [ + 170, 103, 112, 99, 95, 105, 110, 105, 116, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 49, + 103, 97, 112, 95, 105, 110, 105, 116, 161, 101, 118, 97, 108, 117, 101, 100, 48, 120, 49, 98, + 103, 102, 112, 95, 105, 110, 105, 116, 161, 101, 118, 97, 108, 117, 101, 100, 48, 120, 49, 98, + 104, 112, 99, 95, 102, 105, 110, 97, 108, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 98, + 104, 97, 112, 95, 102, 105, 110, 97, 108, 161, 101, 118, 97, 108, 117, 101, 100, 48, 120, 52, + 48, 111, 114, 97, 110, 103, 101, 95, 99, 104, 101, 99, 107, 95, 109, 105, 110, 25, 127, 251, + 111, 114, 97, 110, 103, 101, 95, 99, 104, 101, 99, 107, 95, 109, 97, 120, 25, 128, 1, 111, 109, + 101, 109, 111, 114, 121, 95, 115, 101, 103, 109, 101, 110, 116, 115, 160, 109, 112, 117, 98, + 108, 105, 99, 95, 109, 101, 109, 111, 114, 121, 184, 24, 161, 101, 118, 97, 108, 117, 101, 100, + 48, 120, 49, 51, 161, 101, 118, 97, 108, 117, 101, 114, 48, 120, 52, 56, 49, 50, 55, 102, 102, + 101, 55, 102, 102, 102, 56, 48, 48, 48, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 50, 161, + 101, 118, 97, 108, 117, 101, 99, 48, 120, 49, 161, 101, 118, 97, 108, 117, 101, 100, 48, 120, + 49, 49, 161, 101, 118, 97, 108, 117, 101, 114, 48, 120, 52, 56, 50, 97, 55, 102, 102, 99, 55, + 102, 102, 98, 56, 48, 48, 48, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 98, 161, 101, 118, + 97, 108, 117, 101, 114, 48, 120, 50, 48, 56, 98, 55, 102, 102, 102, 55, 102, 102, 102, 55, 102, + 102, 101, 161, 101, 118, 97, 108, 117, 101, 100, 48, 120, 49, 48, 161, 101, 118, 97, 108, 117, + 101, 114, 48, 120, 50, 48, 56, 98, 55, 102, 102, 102, 55, 102, 102, 102, 55, 102, 102, 101, + 161, 101, 118, 97, 108, 117, 101, 100, 48, 120, 49, 52, 161, 101, 118, 97, 108, 117, 101, 114, + 48, 120, 52, 56, 50, 54, 56, 48, 48, 49, 55, 102, 102, 100, 56, 48, 48, 48, 161, 101, 118, 97, + 108, 117, 101, 100, 48, 120, 49, 53, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 56, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 161, 101, 118, 97, 108, 117, 101, 100, + 48, 120, 49, 55, 161, 101, 118, 97, 108, 117, 101, 120, 65, 48, 120, 56, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 49, 48, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 55, 161, 101, + 118, 97, 108, 117, 101, 99, 48, 120, 54, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 53, + 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 56, 161, 101, 118, 97, 108, 117, 101, 99, 48, + 120, 53, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 55, 161, 101, 118, 97, 108, 117, 101, + 114, 48, 120, 49, 49, 48, 52, 56, 48, 48, 49, 56, 48, 48, 49, 56, 48, 48, 48, 161, 101, 118, + 97, 108, 117, 101, 99, 48, 120, 99, 161, 101, 118, 97, 108, 117, 101, 113, 48, 120, 50, 48, 55, + 56, 48, 48, 49, 55, 102, 102, 102, 55, 102, 102, 100, 161, 101, 118, 97, 108, 117, 101, 99, 48, + 120, 100, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 53, 161, 101, 118, 97, 108, 117, 101, + 99, 48, 120, 52, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 49, 161, 101, 118, 97, 108, + 117, 101, 99, 48, 120, 101, 161, 101, 118, 97, 108, 117, 101, 114, 48, 120, 52, 56, 48, 97, 55, + 102, 102, 99, 55, 102, 102, 102, 56, 48, 48, 48, 161, 101, 118, 97, 108, 117, 101, 100, 48, + 120, 49, 54, 161, 101, 118, 97, 108, 117, 101, 114, 48, 120, 49, 49, 48, 52, 56, 48, 48, 49, + 56, 48, 48, 49, 56, 48, 48, 48, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 53, 161, 101, + 118, 97, 108, 117, 101, 114, 48, 120, 52, 56, 48, 54, 56, 48, 48, 49, 55, 102, 102, 102, 56, + 48, 48, 48, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 49, 161, 101, 118, 97, 108, 117, + 101, 114, 48, 120, 52, 56, 48, 54, 56, 48, 48, 49, 55, 102, 102, 102, 56, 48, 48, 48, 161, 101, + 118, 97, 108, 117, 101, 99, 48, 120, 51, 161, 101, 118, 97, 108, 117, 101, 114, 48, 120, 52, + 56, 48, 54, 56, 48, 48, 49, 55, 102, 102, 102, 56, 48, 48, 48, 161, 101, 118, 97, 108, 117, + 101, 100, 48, 120, 49, 56, 161, 101, 118, 97, 108, 117, 101, 114, 48, 120, 50, 48, 56, 98, 55, + 102, 102, 102, 55, 102, 102, 102, 55, 102, 102, 101, 161, 101, 118, 97, 108, 117, 101, 99, 48, + 120, 102, 161, 101, 118, 97, 108, 117, 101, 114, 48, 120, 52, 56, 48, 97, 55, 102, 102, 99, 55, + 102, 102, 102, 56, 48, 48, 48, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 57, 161, 101, + 118, 97, 108, 117, 101, 114, 48, 120, 52, 48, 48, 54, 56, 48, 48, 49, 55, 102, 102, 102, 55, + 102, 102, 102, 161, 101, 118, 97, 108, 117, 101, 99, 48, 120, 97, 161, 101, 118, 97, 108, 117, + 101, 99, 48, 120, 100, 161, 101, 118, 97, 108, 117, 101, 100, 48, 120, 49, 50, 161, 101, 118, + 97, 108, 117, 101, 114, 48, 120, 52, 56, 48, 97, 55, 102, 102, 99, 55, 102, 102, 102, 56, 48, + 48, 48, 105, 110, 117, 109, 95, 115, 116, 101, 112, 115, 24, 45, +]; diff --git a/src/cairo/mod.rs b/src/cairo/mod.rs new file mode 100644 index 00000000..828d778b --- /dev/null +++ b/src/cairo/mod.rs @@ -0,0 +1,11 @@ +pub mod air; +pub mod cairo_layout; +pub mod cairo_mem; +pub mod decode; +pub mod errors; +pub mod execution_trace; +pub mod register_states; +pub mod runner; + +#[cfg(test)] +pub mod tests; diff --git a/src/cairo/tests/data/mul_mem.out b/src/cairo/tests/data/mul_mem.out new file mode 100644 index 0000000000000000000000000000000000000000..f4f866c2dd56b3c7571324a967539e35d6d6a5c5 GIT binary patch literal 320 zcmZQ%fP#kq^^6T{9xyIC%>)%-Lzh6~Gei0R>%rzZph?5IEKn99^H`zk{sGPVU*D|& dHvo+RGlvsR9G%M!6(FRJ1F8;YF1k4|J^<$b3;h59 literal 0 HcmV?d00001 diff --git a/src/cairo/tests/data/mul_trace.out b/src/cairo/tests/data/mul_trace.out new file mode 100644 index 0000000000000000000000000000000000000000..a4a295fdb52952db4d5db326f73186433a4adc4a GIT binary patch literal 72 Ycmd;JfB+6C%?PDA(Zrc?h_gb)0SS-*JOBUy literal 0 HcmV?d00001 diff --git a/src/cairo/tests/mod.rs b/src/cairo/tests/mod.rs new file mode 100644 index 00000000..8ffce3ed --- /dev/null +++ b/src/cairo/tests/mod.rs @@ -0,0 +1,2 @@ +pub mod integration_tests; +pub mod utils; diff --git a/src/cairo/tests/utils.rs b/src/cairo/tests/utils.rs new file mode 100644 index 00000000..68b51624 --- /dev/null +++ b/src/cairo/tests/utils.rs @@ -0,0 +1,38 @@ +use crate::{ + air::{generate_cairo_proof, verify_cairo_proof}, + cairo_layout::CairoLayout, + runner::run::generate_prover_args, + starks::proof::options::ProofOptions, +}; +use std::ops::Range; + +pub fn cairo0_program_path(program_name: &str) -> String { + const CARGO_DIR: &str = env!("CARGO_MANIFEST_DIR"); + const CAIRO0_BASE_REL_PATH: &str = "/cairo_programs/cairo0/"; + let program_base_path = CARGO_DIR.to_string() + CAIRO0_BASE_REL_PATH; + program_base_path + program_name +} + +pub fn cairo1_program_path(program_name: &str) -> String { + const CARGO_DIR: &str = env!("CARGO_MANIFEST_DIR"); + const CAIRO1_BASE_REL_PATH: &str = "/cairo_programs/cairo1/"; + let program_base_path = CARGO_DIR.to_string() + CAIRO1_BASE_REL_PATH; + program_base_path + program_name +} + +/// Loads the program in path, runs it with the Cairo VM, and makes a proof of it +pub fn test_prove_cairo_program( + file_path: &str, + output_range: &Option>, + layout: CairoLayout, +) { + let proof_options = ProofOptions::default_test_options(); + + let program_content = std::fs::read(file_path).unwrap(); + let (main_trace, pub_inputs) = + generate_prover_args(&program_content, output_range, layout).unwrap(); + + let proof = generate_cairo_proof(&main_trace, &pub_inputs, &proof_options).unwrap(); + + assert!(verify_cairo_proof(&proof, &pub_inputs, &proof_options)); +} diff --git a/src/starks/tests/integration_tests.rs b/src/starks/tests/integration_tests.rs new file mode 100644 index 00000000..fa3c55da --- /dev/null +++ b/src/starks/tests/integration_tests.rs @@ -0,0 +1,129 @@ +use crate::{ + starks::{ + example::{ + dummy_air::{self, DummyAIR}, + fibonacci_2_columns::{self, Fibonacci2ColsAIR}, + fibonacci_rap::{fibonacci_rap_trace, FibonacciRAP, FibonacciRAPPublicInputs}, + quadratic_air::{self, QuadraticAIR, QuadraticPublicInputs}, + simple_fibonacci::{self, FibonacciAIR, FibonacciPublicInputs}, + }, + proof::options::ProofOptions, + prover::prove, + verifier::verify, + }, + FE, +}; +use lambdaworks_math::field::fields::{ + fft_friendly::stark_252_prime_field::Stark252PrimeField as F, + u64_prime_field::{F17, FE17}, +}; + +#[test_log::test] +fn test_prove_fib() { + let trace = simple_fibonacci::fibonacci_trace([FE::from(1), FE::from(1)], 8); + + let proof_options = ProofOptions::default_test_options(); + + let pub_inputs = FibonacciPublicInputs { + a0: FE::one(), + a1: FE::one(), + }; + + let proof = prove::>(&trace, &pub_inputs, &proof_options).unwrap(); + assert!(verify::>( + &proof, + &pub_inputs, + &proof_options + )); +} + +#[test_log::test] +fn test_prove_fib17() { + let trace = simple_fibonacci::fibonacci_trace([FE17::from(1), FE17::from(1)], 4); + + let proof_options = ProofOptions { + blowup_factor: 2, + fri_number_of_queries: 7, + coset_offset: 3, + grinding_factor: 1, + }; + + let pub_inputs = FibonacciPublicInputs { + a0: FE17::one(), + a1: FE17::one(), + }; + + let proof = prove::>(&trace, &pub_inputs, &proof_options).unwrap(); + assert!(verify::>( + &proof, + &pub_inputs, + &proof_options + )); +} + +#[test_log::test] +fn test_prove_fib_2_cols() { + let trace = fibonacci_2_columns::fibonacci_trace_2_columns([FE::from(1), FE::from(1)], 16); + + let proof_options = ProofOptions::default_test_options(); + + let pub_inputs = FibonacciPublicInputs { + a0: FE::one(), + a1: FE::one(), + }; + + let proof = prove::>(&trace, &pub_inputs, &proof_options).unwrap(); + assert!(verify::>( + &proof, + &pub_inputs, + &proof_options + )); +} + +#[test_log::test] +fn test_prove_quadratic() { + let trace = quadratic_air::quadratic_trace(FE::from(3), 4); + + let proof_options = ProofOptions::default_test_options(); + + let pub_inputs = QuadraticPublicInputs { a0: FE::from(3) }; + + let proof = prove::>(&trace, &pub_inputs, &proof_options).unwrap(); + assert!(verify::>( + &proof, + &pub_inputs, + &proof_options + )); +} + +#[test_log::test] +fn test_prove_rap_fib() { + let steps = 16; + let trace = fibonacci_rap_trace([FE::from(1), FE::from(1)], steps); + + let proof_options = ProofOptions::default_test_options(); + + let pub_inputs = FibonacciRAPPublicInputs { + steps, + a0: FE::one(), + a1: FE::one(), + }; + + let proof = prove::>(&trace, &pub_inputs, &proof_options).unwrap(); + assert!(verify::>( + &proof, + &pub_inputs, + &proof_options + )); +} + +#[test_log::test] +fn test_prove_dummy() { + let trace_length = 16; + let trace = dummy_air::dummy_trace(trace_length); + + let proof_options = ProofOptions::default_test_options(); + + let proof = prove::(&trace, &(), &proof_options).unwrap(); + assert!(verify::(&proof, &(), &proof_options)); +} diff --git a/src/starks/tests/mod.rs b/src/starks/tests/mod.rs new file mode 100644 index 00000000..7345833b --- /dev/null +++ b/src/starks/tests/mod.rs @@ -0,0 +1 @@ +pub mod integration_tests; diff --git a/stark_prover/src/proof/stark.rs b/stark_prover/src/proof/stark.rs index ed3302be..72d3ef53 100644 --- a/stark_prover/src/proof/stark.rs +++ b/stark_prover/src/proof/stark.rs @@ -441,8 +441,11 @@ where mod prop_test { use lambdaworks_crypto::merkle_tree::proof::Proof; - use lambdaworks_math::field::{ - element::FieldElement, fields::fft_friendly::stark_252_prime_field::Stark252PrimeField, + use lambdaworks_math::{ + errors::DeserializationError, + field::{ + element::FieldElement, fields::fft_friendly::stark_252_prime_field::Stark252PrimeField, + }, }; use proptest::{collection, prelude::*, prop_compose, proptest}; @@ -696,4 +699,14 @@ mod prop_test { } } } + + #[test] + fn deserialize_empty_proof_should_give_error() { + assert_eq!( + DeserializationError::InvalidAmountOfBytes, + StarkProof::::deserialize(&[]) + .err() + .unwrap() + ); + } }