diff --git a/zkevm-circuits/src/circuit_tools/cell_manager.rs b/zkevm-circuits/src/circuit_tools/cell_manager.rs index d3ba2c695b..457d571c7d 100644 --- a/zkevm-circuits/src/circuit_tools/cell_manager.rs +++ b/zkevm-circuits/src/circuit_tools/cell_manager.rs @@ -1,13 +1,21 @@ //! Cell manager -use crate::util::Expr; -use eth_types::Field; +use crate::{util::Expr}; +use crate::evm_circuit::util::CachedRegion; +use eth_types::{Field, Hash}; use halo2_proofs::{ circuit::{AssignedCell, Region, Value}, plonk::{Advice, Column, Error, Expression, VirtualCells}, poly::Rotation, }; +use lazy_static::__Deref; +use std::collections::HashMap; +use std::cmp::{max, Ordering}; use std::{any::Any, collections::BTreeMap}; +// Todo(Cecilia): config this number somewhere +pub(crate) const N_BYTE_LOOKUPS: usize = 4; + + #[derive(Clone)] pub(crate) struct DataTransition { prev: Expression, @@ -118,6 +126,25 @@ impl Cell { || Value::known(value), ) } + + pub(crate) fn assign_cached( + &self, + region: &mut CachedRegion<'_, '_, F>, + offset: usize, + value: F, + ) -> Result, Error> { + region.assign_advice( + || { + format!( + "Cell column: {:?} and rotation: {}", + self.column, self.rotation + ) + }, + self.column.unwrap(), + offset + self.rotation, + || Value::known(value), + ) + } } impl Expr for Cell { @@ -135,8 +162,21 @@ impl Expr for &Cell { /// CellType #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum CellType { - /// General + /// Storage type Storage, + /// Lookup Byte + LookupByte, + /// Lookup outter tables + Lookup(Table), +} + +/// Table being lookuped by cell +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub enum Table { + /// Table type + Fixed, + /// Table type + Keccak, } /// CellColumn @@ -148,22 +188,243 @@ pub struct CellColumn { pub(crate) expr: Expression, } +impl PartialEq for CellColumn { + fn eq(&self, other: &Self) -> bool { + self.index == other.index && self.cell_type == other.cell_type && self.height == other.height + } +} + +impl Eq for CellColumn {} + +impl PartialOrd for CellColumn { + fn partial_cmp(&self, other: &Self) -> Option { + self.height.partial_cmp(&other.height) + } +} + +impl Ord for CellColumn { + fn cmp(&self, other: &Self) -> Ordering { + self.height.cmp(&other.height) + } +} + impl Expr for CellColumn { fn expr(&self) -> Expression { self.expr.clone() } } +/// CellManager with context +#[derive(Clone, Debug)] +pub struct CellManager_ { + width: usize, + height: usize, + // current ctx + cells: Vec>, + columns: Vec>, + // branch ctxs + branch_ctxs: HashMap>, + parent_ctx: Option>, +} + + +#[derive(Default, Clone, Debug)] +struct CmContext{ + parent: Box>>, + columns: Vec>, +} + +impl CellManager_ { + + pub(crate) fn cur_to_parent(&mut self) { + let new_parent = match self.parent_ctx.clone() { + // if parent context exists, meaning we are deep in a callstack + // we set it as the parent of new parent + Some(ctx) => CmContext { + parent: Box::new(Some(ctx.clone())), + columns: self.columns.clone(), + }, + // otherwise, this is the fist level of callstack + // the parent of new parent is None + None => CmContext { + parent: Box::new(None), + columns: self.columns.clone(), + } + }; + self.parent_ctx = Some(new_parent); + self.reset(); + } + + pub(crate) fn cur_to_branch(&mut self, name: &str) { + let new_branch = match self.parent_ctx.clone() { + // if parent context exists, meaning we are deep in a callstack + // we set it as the parent of new branch + Some(ctx) => CmContext { + parent: Box::new(Some(ctx.clone())), + columns: self.columns.clone(), + }, + // otherwise, this is the fist level of callstack + // the parent of new branch is None + None => CmContext { + parent: Box::new(None), + columns: self.columns.clone(), + } + }; + self.branch_ctxs.insert(name.to_string(), new_branch); + self.reset(); + } + + pub(crate) fn recover_parent(&mut self) { + assert!(self.parent_ctx.is_some(), "No parent context to recover"); + self.columns = self.parent_ctx.clone().unwrap().columns.clone(); + self.parent_ctx + .clone() + .map(|ctx| self.parent_ctx = ctx.parent.deref().clone()) + .unwrap(); + self.branch_ctxs.clear(); + } + + pub(crate) fn recover_branch(&mut self, name: &str) { + self.branch_ctxs.get(name).map(|ctx| { + assert!(ctx.parent.is_some(), "Cannot have sibling without parent"); + self.columns = ctx.columns.clone(); + }).expect("CellManager has no specified context."); + self.branch_ctxs.remove(name); + } + + pub(crate) fn recover_max_branch(&mut self) { + let mut new_cols = self.columns.clone(); + let parent = self.parent_ctx.clone().expect("Retruning context needs parent"); + self.branch_ctxs + .iter() + .map(|(name, ctx)| { + for c in 0..self.width { + new_cols[c] = max(&new_cols[c], &ctx.columns[c]).clone(); + new_cols[c] = max(&new_cols[c], &parent.columns[c]).clone(); + } + }); + self.columns = new_cols; + self.branch_ctxs.clear(); + self.parent_ctx = self.parent_ctx + .clone() + .map(|ctx| ctx.parent.deref().clone()) + .unwrap(); + } + + pub(crate) fn new(meta: &mut VirtualCells, advice_columns: &[Column]) -> Self { + // Setup the columns and query the cells + let width = advice_columns.len(); + let height = 32; + let mut cells = Vec::with_capacity(height * width); + let mut columns = Vec::with_capacity(width); + for c in 0..width { + for r in 0..height { + cells.push(Cell::new(meta, advice_columns[c], r)); + } + columns.push(CellColumn { + index: c, + cell_type: CellType::Storage, + height: 0, + expr: cells[c * height].expr(), + }); + } + let mut column_idx = 0; + + + for i in 0usize..N_BYTE_LOOKUPS { + columns[i].cell_type = CellType::LookupByte; + assert_eq!(advice_columns[column_idx].column_type().phase(), 0); + column_idx += 1; + } + + + Self { + width, + height, + cells, + columns, + branch_ctxs: HashMap::new(), + parent_ctx: None, + } + } + + pub(crate) fn query_cells(&mut self, cell_type: CellType, count: usize) -> Vec> { + let mut cells = Vec::with_capacity(count); + while cells.len() < count { + let column_idx = self.next_column(cell_type); + let column = &mut self.columns[column_idx]; + cells.push(self.cells[column_idx * self.height + column.height].clone()); + column.height += 1; + } + cells + } + + pub(crate) fn query_cell(&mut self, cell_type: CellType) -> Cell { + self.query_cells(cell_type, 1)[0].clone() + } + + + pub(crate) fn reset(&mut self) { + for column in self.columns.iter_mut() { + column.height = 0; + } + } + + fn next_column(&self, cell_type: CellType) -> usize { + let mut best_index: Option = None; + let mut best_height = self.height; + for column in self.columns.iter() { + // if cell_type == CellType::LookupByte { + // println!("column.cell_type: {:?}, column.index: {:?}, cell_type: {:?}", column.cell_type, column.index, cell_type); + // } + if column.cell_type == cell_type && column.height < best_height { + best_index = Some(column.index); + best_height = column.height; + } + } + match best_index { + Some(index) => index, + None => unreachable!("not enough cells for query: {:?}", cell_type), + } + } + + pub(crate) fn get_height(&self) -> usize { + self.columns + .iter() + .map(|column| column.height) + .max() + .unwrap() + } + + /// Returns a map of CellType -> (width, height, num_cells) + pub(crate) fn get_stats(&self) -> BTreeMap { + let mut data = BTreeMap::new(); + for column in self.columns.iter() { + let (mut count, mut height, mut num_cells) = + data.get(&column.cell_type).unwrap_or(&(0, 0, 0)); + count += 1; + height = height.max(column.height); + num_cells += column.height; + data.insert(column.cell_type, (count, height, num_cells)); + } + data + } + + pub(crate) fn columns(&self) -> &[CellColumn] { + &self.columns + } +} + /// CellManager #[derive(Clone, Debug)] -pub struct CellManager { +pub struct _CellManager { width: usize, height: usize, cells: Vec>, columns: Vec>, } -impl CellManager { +impl _CellManager { pub(crate) fn new(meta: &mut VirtualCells, advice_columns: &[Column]) -> Self { // Setup the columns and query the cells let width = advice_columns.len(); @@ -181,6 +442,15 @@ impl CellManager { expr: cells[c * height].expr(), }); } + let mut column_idx = 0; + + + for i in 0usize..N_BYTE_LOOKUPS { + columns[i].cell_type = CellType::LookupByte; + assert_eq!(advice_columns[column_idx].column_type().phase(), 0); + column_idx += 1; + } + Self { width, @@ -205,6 +475,7 @@ impl CellManager { self.query_cells(cell_type, 1)[0].clone() } + pub(crate) fn reset(&mut self) { for column in self.columns.iter_mut() { column.height = 0; @@ -215,6 +486,9 @@ impl CellManager { let mut best_index: Option = None; let mut best_height = self.height; for column in self.columns.iter() { + if cell_type == CellType::LookupByte { + println!("column.cell_type: {:?}, column.index: {:?}, cell_type: {:?}", column.cell_type, column.index, cell_type); + } if column.cell_type == cell_type && column.height < best_height { best_index = Some(column.index); best_height = column.height; diff --git a/zkevm-circuits/src/circuit_tools/constraint_builder.rs b/zkevm-circuits/src/circuit_tools/constraint_builder.rs index bf9763a24e..bfe6a4f4f5 100644 --- a/zkevm-circuits/src/circuit_tools/constraint_builder.rs +++ b/zkevm-circuits/src/circuit_tools/constraint_builder.rs @@ -1,11 +1,11 @@ //! Circuit utilities -use crate::{evm_circuit::util::rlc, util::Expr}; +use crate::{evm_circuit::{util::rlc, table::Lookup}, util::Expr}; use eth_types::Field; use gadgets::util::{and, select, sum, Scalar}; -use halo2_proofs::plonk::{ConstraintSystem, Expression}; +use halo2_proofs::{plonk::{ConstraintSystem, Expression, Column, Fixed}, poly::Rotation}; use itertools::Itertools; -use super::cell_manager::{Cell, CellManager, CellType, DataTransition, Trackable}; +use super::cell_manager::{Cell, CellManager_, CellType, DataTransition, Trackable}; /// Lookup data #[derive(Clone)] @@ -32,14 +32,14 @@ pub struct ConstraintBuilder { pub lookup_tables: Vec>, /// Query offset pub query_offset: i32, - /// CellManager - pub cell_manager: Option>, + /// CellManager_ + pub cell_manager: Option>, /// Tracked objects objects: Vec>, } impl ConstraintBuilder { - pub(crate) fn new(max_degree: usize, cell_manager: Option>) -> Self { + pub(crate) fn new(max_degree: usize, cell_manager: Option>) -> Self { ConstraintBuilder { constraints: Vec::new(), max_degree, @@ -52,10 +52,34 @@ impl ConstraintBuilder { } } - pub(crate) fn set_cell_manager(&mut self, cell_manager: CellManager) { + pub(crate) fn set_cell_manager(&mut self, cell_manager: CellManager_) { + println!("set_cell_manager"); self.cell_manager = Some(cell_manager); } + pub(crate) fn enter_branch_context(&mut self) { + println!("=====>"); + match self.cell_manager.as_mut() { + Some(cm) => cm.cur_to_parent(), + None => () + }; + } + + pub(crate) fn switch_branch_context(&mut self, branch_name: &str) { + match self.cell_manager.as_mut() { + Some(cm) => cm.cur_to_branch(branch_name), + None => () + }; + } + + pub(crate) fn exit_branch_context(&mut self) { + println!("^*****"); + match self.cell_manager.as_mut() { + Some(cm) => cm.recover_max_branch(), + None => () + }; + } + pub(crate) fn require_zero(&mut self, name: &'static str, constraint: Expression) { self.add_constraint(name, constraint); } @@ -129,8 +153,7 @@ impl ConstraintBuilder { } pub(crate) fn query_byte(&mut self) -> Cell { - // TODO(Brecht): fix - self.query_cell_with_type(CellType::Storage) + self.query_cell_with_type(CellType::LookupByte) } pub(crate) fn query_bytes(&mut self) -> [Cell; N] { @@ -138,7 +161,7 @@ impl ConstraintBuilder { } pub(crate) fn query_bytes_dyn(&mut self, count: usize) -> Vec> { - self.query_cells(CellType::Storage, count) + self.query_cells(CellType::LookupByte, count) } pub(crate) fn query_cell(&mut self) -> Cell { @@ -173,20 +196,39 @@ impl ConstraintBuilder { } pub(crate) fn generate_lookups>( - &self, + &mut self, meta: &mut ConstraintSystem, - lookup_names: &[S], + byte_table: [Column; 1], + lookup_names: &[S], + // "keccek", "fixed", "parent_s" ,"parent_c","parent_s", "key_s", "key_c" ) { - for lookup_name in lookup_names.iter() { + if let Some(cm) = self.cell_manager.clone() { + for column in cm.columns() { + match column.cell_type { + CellType::Storage => (), + CellType::LookupByte => { + meta.lookup_any("Byte lookup", |meta| { + let byte_table_expression = meta.query_fixed(byte_table[0], Rotation::cur()); + vec![(column.expr(), byte_table_expression)] + }); + }, + CellType::Lookup( .. ) => () + } + } + } + for lookup_name in lookup_names.iter() { let lookups = self .lookups .iter() .cloned() .filter(|lookup| lookup.tag == lookup_name.as_ref()) .collect::>(); + // [ "parent_s" ,"parent_c","parent_s", "key_s", "key_c"] for lookup in lookups.iter() { meta.lookup_any(lookup.description, |_meta| { + // 拿对应的表 let table = self.get_lookup_table_values(lookup_name); + // 拿要查的值 let mut values: Vec<_> = lookup .values .iter() @@ -329,6 +371,7 @@ impl ConstraintBuilder { pub(crate) fn set_query_offset(&mut self, query_offset: i32) { self.query_offset = query_offset; } + } pub(crate) fn merge_lookups( @@ -993,10 +1036,17 @@ macro_rules! _matchx { ($cb:expr, $($condition:expr => $when:expr),* $(, _ => $catch_all:expr)? $(,)?) => {{ let mut conditions = Vec::new(); let mut cases = Vec::new(); + $cb.enter_branch_context(); + println!("$cb.enter_branch_context -- _matchx"); + $( $cb.push_condition($condition.expr()); let ret = $when.clone(); $cb.pop_condition(); + + println!("$cb.switch_branch_context: {:?}", stringify!($condition)); + $cb.switch_branch_context(stringify!($condition)); + cases.push(($condition.expr(), ret)); conditions.push($condition.expr()); )* @@ -1006,6 +1056,10 @@ macro_rules! _matchx { $cb.push_condition(catch_all_condition.expr()); let ret = $catch_all; $cb.pop_condition(); + + println!("$cb.switch_branch_context: catch_all_condition"); + $cb.switch_branch_context("catch_all_condition"); + cases.push((catch_all_condition.expr(), ret)); conditions.push(catch_all_condition.expr()); )* @@ -1017,6 +1071,9 @@ macro_rules! _matchx { // Exactly 1 case needs to be enabled _require!($cb, sum::expr(&conditions) => 1); + println!("$cb.exit_branch_context -- _matchx"); + $cb.exit_branch_context(); + cases.apply_conditions() }}; } @@ -1025,11 +1082,19 @@ macro_rules! _matchx { #[macro_export] macro_rules! _ifx { ($cb:expr, $($condition:expr),* => $when_true:block $(elsex $when_false:block)?) => {{ + + let descr = stringify!($($condition)*); let condition = and::expr([$($condition.expr()),*]); + $cb.enter_branch_context(); + println!("$cb.enter_branch_context"); + $cb.push_condition(condition.expr()); let ret_true = $when_true; $cb.pop_condition(); + + println!("$cb.switch_branch_context: {:?}{:?}", "ifx!", descr); + $cb.switch_branch_context(&format!("{:?}{:?}", "ifx!", descr)); #[allow(unused_assignments, unused_mut)] let mut ret = ret_true.conditional(condition.expr()); @@ -1041,8 +1106,13 @@ macro_rules! _ifx { let ret_false = $when_false; $cb.pop_condition(); + println!("$cb.switch_branch_context: {:?}{:?}", "elsex", descr); + $cb.switch_branch_context(&format!("{:?}{:?}", "elsex", descr)); + ret = ret_true.select(condition.expr(), &ret_false); )* + println!("$cb.exit_branch_context"); + $cb.exit_branch_context(); ret }}; } diff --git a/zkevm-circuits/src/circuit_tools/gadgets.rs b/zkevm-circuits/src/circuit_tools/gadgets.rs index b1e21c5c9c..25909bbab3 100644 --- a/zkevm-circuits/src/circuit_tools/gadgets.rs +++ b/zkevm-circuits/src/circuit_tools/gadgets.rs @@ -6,7 +6,7 @@ use halo2_proofs::{ plonk::{Error, Expression}, }; -use crate::evm_circuit::util::{from_bytes, pow_of_two}; +use crate::evm_circuit::util::{from_bytes, pow_of_two, CachedRegion}; use super::{cell_manager::Cell, constraint_builder::ConstraintBuilder}; @@ -53,6 +53,22 @@ impl IsZeroGadget { F::zero() }) } + + pub(crate) fn assign_cached( + &self, + region: &mut CachedRegion, + offset: usize, + value: F, + ) -> Result { + let inverse = value.invert().unwrap_or(F::zero()); + self.inverse.assign_cached(region, offset, inverse)?; + Ok(if value.is_zero().into() { + F::one() + } else { + F::zero() + }) + } + } /// Returns `1` when `lhs == rhs`, and returns `0` otherwise. @@ -85,6 +101,18 @@ impl IsEqualGadget { ) -> Result { self.is_zero.assign(region, offset, lhs - rhs) } + + + pub(crate) fn assign_cached( + &self, + region: &mut CachedRegion, + offset: usize, + lhs: F, + rhs: F, + ) -> Result { + self.is_zero.assign_cached(region, offset, lhs - rhs) + } + } /// Returns `1` when `lhs < rhs`, and returns `0` otherwise. @@ -154,6 +182,29 @@ impl LtGadget { Ok((if lt { F::one() } else { F::zero() }, diff_bytes.to_vec())) } + pub(crate) fn assign_cached( + &self, + region: &mut CachedRegion, + offset: usize, + lhs: F, + rhs: F, + ) -> Result<(F, Vec), Error> { + // Set `lt` + let lt = lhs < rhs; + self.lt + .assign_cached(region, offset, if lt { F::one() } else { F::zero() })?; + + // Set the bytes of diff + let diff = (lhs - rhs) + (if lt { self.range } else { F::zero() }); + let diff_bytes = diff.to_repr(); + for (idx, diff) in self.diff.as_ref().unwrap().iter().enumerate() { + diff.assign_cached(region, offset, F::from(diff_bytes[idx] as u64))?; + } + + Ok((if lt { F::one() } else { F::zero() }, diff_bytes.to_vec())) + } + + pub(crate) fn diff_bytes(&self) -> Vec> { self.diff.as_ref().unwrap().to_vec() } diff --git a/zkevm-circuits/src/circuit_tools/memory.rs b/zkevm-circuits/src/circuit_tools/memory.rs index 78a0711962..fe92af23b3 100644 --- a/zkevm-circuits/src/circuit_tools/memory.rs +++ b/zkevm-circuits/src/circuit_tools/memory.rs @@ -15,7 +15,7 @@ use super::constraint_builder::{merge_lookups, ConstraintBuilder}; #[derive(Clone, Debug, Default)] pub(crate) struct Memory { - columns: Vec>, + pub(crate) columns: Vec>, banks: Vec>, } diff --git a/zkevm-circuits/src/evm_circuit/execution.rs b/zkevm-circuits/src/evm_circuit/execution.rs index 2607eef28c..69d2781fbb 100644 --- a/zkevm-circuits/src/evm_circuit/execution.rs +++ b/zkevm-circuits/src/evm_circuit/execution.rs @@ -335,6 +335,7 @@ impl ExecutionConfig { let num_rows_left_next = meta.query_advice(num_rows_until_next_step, Rotation::next()); let num_rows_left_inverse = meta.query_advice(num_rows_inv, Rotation::cur()); + let mut cb = BaseConstraintBuilder::default(); // q_step needs to be enabled on the first row cb.condition(q_step_first, |cb| { diff --git a/zkevm-circuits/src/evm_circuit/util.rs b/zkevm-circuits/src/evm_circuit/util.rs index 2caeb7ed12..40dbf29e11 100644 --- a/zkevm-circuits/src/evm_circuit/util.rs +++ b/zkevm-circuits/src/evm_circuit/util.rs @@ -179,6 +179,7 @@ impl StoredExpression { } } + #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub(crate) enum CellType { Storage, diff --git a/zkevm-circuits/src/mpt_circuit.rs b/zkevm-circuits/src/mpt_circuit.rs index 0129be7ccf..399ab70f75 100644 --- a/zkevm-circuits/src/mpt_circuit.rs +++ b/zkevm-circuits/src/mpt_circuit.rs @@ -21,12 +21,13 @@ mod selectors; mod start; mod storage_leaf; mod witness_row; +mod table; use columns::MainCols; use extension_branch::ExtensionBranchConfig; use witness_row::{MptWitnessRow, MptWitnessRowType}; -use param::HASH_WIDTH; +use param::*; use self::{ account_leaf::AccountLeafConfig, @@ -43,11 +44,12 @@ use self::{ AccountNode, AccountRowType, BranchNode, ExtensionBranchNode, ExtensionBranchRowType, ExtensionNode, Node, StartNode, StartRowType, StorageNode, StorageRowType, }, + table::*, }; -use crate::mpt_circuit::helpers::Indexable; +use crate::{mpt_circuit::helpers::Indexable, evm_circuit::util::CachedRegion}; use crate::{ assign, assignf, circuit, - circuit_tools::{cell_manager::CellManager, constraint_builder::merge_lookups, memory::Memory}, + circuit_tools::{cell_manager::CellManager_, memory::Memory}, matchr, matchw, mpt_circuit::{ helpers::{extend_rand, main_memory, parent_memory, MPTConstraintBuilder}, @@ -72,6 +74,9 @@ pub struct StateMachineConfig { pub struct MPTContext { pub(crate) q_enable: Column, pub(crate) q_not_first: Column, + pub(crate) q_row: Column, + pub(crate) q_row_inv: Column, + pub(crate) mpt_table: MptTable, pub(crate) main: MainCols, pub(crate) managed_columns: Vec>, @@ -90,6 +95,7 @@ impl MPTContext { .map(|&byte| meta.query_advice(byte, Rotation(rot))) .collect::>() } + } /// Merkle Patricia Trie config. @@ -97,12 +103,20 @@ impl MPTContext { pub struct MPTConfig { pub(crate) q_enable: Column, pub(crate) q_not_first: Column, + pub(crate) main: MainCols, pub(crate) managed_columns: Vec>, pub(crate) memory: Memory, + keccak_table: KeccakTable, - fixed_table: [Column; 3], + fixed_table: [Column; 5], + byte_table: [Column; 1], state_machine: StateMachineConfig, + + pub(crate) q_node: Column, + pub(crate) q_row: Column, + pub(crate) q_row_inv: Column, + pub(crate) is_start: Column, pub(crate) is_branch: Column, pub(crate) is_account: Column, @@ -112,24 +126,6 @@ pub struct MPTConfig { cb: MPTConstraintBuilder, } -/// Enumerator to determine the type of row in the fixed table. -#[derive(Clone, Copy, Debug)] -pub enum FixedTableTag { - /// All zero lookup data - Disabled, - /// Power of randomness: [1, r], [2, r^2],... - RMult, - /// 0 - 15 - Range16, - /// 0 - 255 - Range256, - /// For checking there are 0s after the RLP stream ends - RangeKeyLen256, - /// For checking there are 0s after the RLP stream ends - RangeKeyLen16, -} - -impl_expr!(FixedTableTag); #[derive(Default)] pub(crate) struct MPTState { @@ -157,6 +153,10 @@ impl MPTConfig { let mpt_table = MptTable::construct(meta); + let q_node = meta.advice_column(); + let q_row = meta.advice_column(); + let q_row_inv = meta.advice_column(); + let is_start = meta.advice_column(); let is_branch = meta.advice_column(); let is_account = meta.advice_column(); @@ -164,11 +164,12 @@ impl MPTConfig { let main = MainCols::new(meta); - let fixed_table: [Column; 3] = (0..3) + let fixed_table: [Column; 5] = (0..5) .map(|_| meta.fixed_column()) .collect::>() .try_into() .unwrap(); + let byte_table = [meta.fixed_column()]; let managed_columns = (0..20).map(|_| meta.advice_column()).collect::>(); let memory_columns = (0..5).map(|_| meta.advice_column()).collect::>(); @@ -180,9 +181,14 @@ impl MPTConfig { memory.allocate(meta, parent_memory(true)); memory.allocate(meta, main_memory()); - let ctx = MPTContext { + let mut cb = MPTConstraintBuilder::new(33 + 10, None, power_of_randomness.clone()); + + let mut ctx = MPTContext { q_enable: q_enable.clone(), q_not_first: q_not_first.clone(), + q_row: q_row.clone(), + q_row_inv: q_row_inv.clone(), + mpt_table: mpt_table.clone(), main: main.clone(), managed_columns: managed_columns.clone(), @@ -192,12 +198,15 @@ impl MPTConfig { let mut state_machine = StateMachineConfig::default(); - let mut cb = MPTConstraintBuilder::new(33 + 10, None); + println!("total advices {}", meta.num_advice_columns()); + meta.create_gate("MPT", |meta| { - let cell_manager = CellManager::new(meta, &ctx.managed_columns); + // 20 cols * 32 height in CellManager + let cell_manager = CellManager_::new(meta, &ctx.managed_columns); cb.base.set_cell_manager(cell_manager); - + circuit!([meta, cb.base], { + let is_q_row_zero = 1.expr() - a!(q_row) * a!(q_row_inv); // State machine // TODO(Brecht): state machine constraints ifx!{f!(q_enable) => { @@ -205,22 +214,38 @@ impl MPTConfig { ifx! {not!(f!(q_not_first)) => { require!(a!(is_start) => true); }}; + // When q_row == 0, we start at a new node, + // one of [is_start, is_branch, is_account, is_storage] needs to be 1, + // if not we goes to _ => require!(true => false) + // Otherwise q_row > 0, we're in the middle of some node rows, all flags needs to be 0; + ifx! {is_q_row_zero.expr() => { + matchx! { + a!(is_start) => { + // require!(a!(q_row) + a!(q_node) => 0.expr()); + state_machine.start_config = StartConfig::configure(meta, &mut cb, ctx.clone()); + }, + a!(is_branch) => { + state_machine.branch_config = ExtensionBranchConfig::configure(meta, &mut cb, ctx.clone()); + }, + a!(is_account) => { + state_machine.account_config = AccountLeafConfig::configure(meta, &mut cb, ctx.clone()); + }, + a!(is_storage) => { + state_machine.storage_config = StorageLeafConfig::configure(meta, &mut cb, ctx.clone()); + }, + _ => require!(true => false), + }; + } elsex { + require! ((a!(is_start) + a!(is_branch) + a!(is_account) + a!(is_storage)) => 0.expr()); + }}; + + // Lookahead + // when q_row.next() != 0 then q_row.next == q_row + 1 + ifx! {a!(q_row, 1i32) => { + require!(a!(q_row) + 1.expr() => a!(q_row, 1i32)) + }}; + // Main state machine - matchx! { - a!(is_start) => { - state_machine.start_config = StartConfig::configure(meta, &mut cb, ctx.clone()); - }, - a!(is_branch) => { - state_machine.branch_config = ExtensionBranchConfig::configure(meta, &mut cb, ctx.clone()); - }, - a!(is_account) => { - state_machine.account_config = AccountLeafConfig::configure(meta, &mut cb, ctx.clone()); - }, - a!(is_storage) => { - state_machine.storage_config = StorageLeafConfig::configure(meta, &mut cb, ctx.clone()); - }, - _ => (), - }; // Only account and storage rows can have lookups, disable lookups on all other rows matchx! { a!(is_account) => (), @@ -255,14 +280,17 @@ impl MPTConfig { cb.base.generate_constraints() }); + let disable_lookups: usize = var("DISABLE_LOOKUPS") .unwrap_or_else(|_| "0".to_string()) .parse() .expect("Cannot parse DISABLE_LOOKUPS env var as usize"); + println!("DISABLE_LOOKUPS={:?}", disable_lookups); if disable_lookups == 0 { cb.base.generate_lookups( meta, + byte_table, &[ vec!["fixed".to_string(), "keccak".to_string()], ctx.memory.tags(), @@ -272,15 +300,16 @@ impl MPTConfig { } else if disable_lookups == 1 { cb.base.generate_lookups( meta, + byte_table, &[vec!["keccak".to_string()], ctx.memory.tags()].concat(), ); } else if disable_lookups == 2 { - cb.base.generate_lookups(meta, &ctx.memory.tags()); + cb.base.generate_lookups(meta, byte_table,&ctx.memory.tags()); } else if disable_lookups == 3 { cb.base - .generate_lookups(meta, &vec!["fixed".to_string(), "keccak".to_string()]); + .generate_lookups(meta, byte_table,&vec!["fixed".to_string(), "keccak".to_string()]); } else if disable_lookups == 4 { - cb.base.generate_lookups(meta, &vec!["keccak".to_string()]); + cb.base.generate_lookups(meta, byte_table,&vec!["fixed".to_string()]); } println!("num lookups: {}", meta.lookups().len()); @@ -291,6 +320,9 @@ impl MPTConfig { MPTConfig { q_enable, q_not_first, + q_node, + q_row, + q_row_inv, is_start, is_branch, is_account, @@ -299,6 +331,7 @@ impl MPTConfig { managed_columns, memory, keccak_table, + byte_table, fixed_table, state_machine, r: 0.scalar(), @@ -318,6 +351,7 @@ impl MPTConfig { let mut height = 0; let mut memory = self.memory.clone(); + // 预处理一☝️:把每行的rlp bytes搞一下 // TODO(Brecht): change this on the witness generation side let mut key_rlp_bytes = Vec::new(); for (_, row) in witness @@ -542,6 +576,7 @@ impl MPTConfig { } } + // 预处理二☝️:把记录变化的branch index放前面 // TODO(Brecht): change this on the witness generation side let cached_witness = witness.to_owned(); for (idx, row) in witness @@ -556,6 +591,8 @@ impl MPTConfig { } } + // 构造 nodes + // N1=[r0,r1] | N2=[r2,...,r23] | ... let mut nodes = Vec::new(); let witness = witness .iter() @@ -574,6 +611,7 @@ impl MPTConfig { } } + // 🌻 offset = 0 | node_rows 0-2 if new_proof { let mut new_row = witness[offset].clone(); new_row.bytes = [ @@ -596,7 +634,7 @@ impl MPTConfig { node.values = node_rows; nodes.push(node); } - + // 🌻 offset = 0 | node_rows 0-21 if witness[offset].get_type() == MptWitnessRowType::InitBranch { let row_init = witness[offset].to_owned(); let is_placeholder = row_init.is_placeholder.clone(); @@ -643,7 +681,9 @@ impl MPTConfig { node.extension_branch = Some(extension_branch_node); node.values = node_rows; nodes.push(node); - } else if witness[offset].get_type() == MptWitnessRowType::StorageLeafSKey { + } + // 🌻 offset = 19 | node_rows 22-21 + else if witness[offset].get_type() == MptWitnessRowType::StorageLeafSKey { let row_key = [&witness[offset + 0], &witness[offset + 2]]; let row_value = [&witness[offset + 1], &witness[offset + 3]]; let row_drifted = &witness[offset + 4]; @@ -731,54 +771,91 @@ impl MPTConfig { || "MPT", |mut region| { let mut pv = MPTState::new(&self.memory); - memory.clear_witness_data(); + let power_of_randomness: [F; 31] = array_init::array_init(|i | self.r.pow(&[i as u64, 0, 0, 0])); + let mut offset = 0; - for node in nodes.iter() { + for (node_id, node) in nodes.iter().enumerate() { // Assign bytes for (idx, bytes) in node.values.iter().enumerate() { for (byte, &column) in bytes.iter().zip(self.main.bytes.iter()) { assign!(region, (column, offset + idx) => byte.scalar())?; } + let idx_scalar: F = idx.scalar(); + assign!(region, (self.q_node, offset + idx) => offset.scalar())?; + assign!(region, (self.q_row, offset + idx) => idx_scalar)?; + assign!(region, (self.q_row_inv, offset + idx) => idx_scalar.invert().unwrap_or(F::zero()))?; } // Assign nodes if node.start.is_some() { - //println!("{}: start", offset); - assign!(region, (self.is_start, offset) => 1.scalar())?; - self.state_machine.start_config.assign( - &mut region, + let mut cached_region = CachedRegion::new( + &mut region, + power_of_randomness, + TOTAL_WIDTH, + StartRowType::Count as usize, + 0, + offset, + ); + println!("{}: start", offset); + assign!(cached_region, (self.is_start, offset) => 1.scalar())?; + self.state_machine.start_config.assign_cached( + &mut cached_region, self, &mut pv, offset, node, )?; } else if node.extension_branch.is_some() { - //println!("{}: branch", offset); - assign!(region, (self.is_branch, offset) => 1.scalar())?; - self.state_machine.branch_config.assign( - &mut region, + let mut cached_region = CachedRegion::new( + &mut region, + power_of_randomness, + TOTAL_WIDTH, + ExtensionBranchRowType::Count as usize, + 0, + offset, + ); + println!("{}: branch", offset); + assign!(cached_region, (self.is_branch, offset) => 1.scalar())?; + self.state_machine.branch_config.assign_cached( + &mut cached_region, self, &mut pv, offset, node, )?; } else if node.storage.is_some() { - assign!(region, (self.is_storage, offset) => 1.scalar())?; - //println!("{}: storage", offset); - self.state_machine.storage_config.assign( - &mut region, + let mut cached_region = CachedRegion::new( + &mut region, + power_of_randomness, + TOTAL_WIDTH, + StorageRowType::Count as usize, + 0, + offset, + ); + assign!(cached_region, (self.is_storage, offset) => 1.scalar())?; + println!("{}: storage", offset); + self.state_machine.storage_config.assign_cached( + &mut cached_region, self, &mut pv, offset, node, )?; } else if node.account.is_some() { - assign!(region, (self.is_account, offset) => 1.scalar())?; - //println!("{}: account", offset); - self.state_machine.account_config.assign( - &mut region, + let mut cached_region = CachedRegion::new( + &mut region, + power_of_randomness, + TOTAL_WIDTH, + AccountRowType::Count as usize, + 0, + offset, + ); + assign!(cached_region, (self.is_account, offset) => 1.scalar())?; + println!("{}: account", offset); + self.state_machine.account_config.assign_cached( + &mut cached_region, self, &mut pv, offset, @@ -786,7 +863,7 @@ impl MPTConfig { )?; } - //println!("height: {}", node.bytes.len()); + println!("height: {}", node.values.len()); offset += node.values.len(); } @@ -794,8 +871,8 @@ impl MPTConfig { memory = pv.memory; for offset in 0..height { - assignf!(region, (self.q_enable, offset) => true.scalar())?; - assignf!(region, (self.q_not_first, offset) => (offset != 0).scalar())?; + // assignf!(region, (self.q_enable, offset) => true.scalar())?; + assignf!(region, (self.q_not_first, offset) => (offset == 0).scalar())?; } Ok(()) @@ -807,6 +884,13 @@ impl MPTConfig { Ok(()) } + pub(crate) fn region_width(&self) -> usize { + self.mpt_table.columns().len() + + self.main.bytes.len() + + self.managed_columns.len() + + self.memory.columns.len() + } + fn load_fixed_table( &self, layouter: &mut impl Layouter, @@ -870,6 +954,93 @@ impl MPTConfig { offset += 1; } + // Rlp prefixes table [rlp_tag, byte, is_string, is_short, is_verylong] + for ind in 0..=127 { + // short string + assignf!(region, (self.fixed_table[0], offset) => FixedTableTag::RLP.scalar())?; + assignf!(region, (self.fixed_table[1], offset) => ind.scalar())?; + assignf!(region, (self.fixed_table[2], offset) => true.scalar())?; + assignf!(region, (self.fixed_table[3], offset) => true.scalar())?; + assignf!(region, (self.fixed_table[4], offset) => false.scalar())?; + offset += 1; + } + for ind in 128..=183 { + // long string + assignf!(region, (self.fixed_table[0], offset) => FixedTableTag::RLP.scalar())?; + assignf!(region, (self.fixed_table[1], offset) => ind.scalar())?; + assignf!(region, (self.fixed_table[2], offset) => true.scalar())?; + assignf!(region, (self.fixed_table[3], offset) => false.scalar())?; + assignf!(region, (self.fixed_table[4], offset) => false.scalar())?; + offset += 1; + } + for ind in 184..=191 { + // very long string + assignf!(region, (self.fixed_table[0], offset) => FixedTableTag::RLP.scalar())?; + assignf!(region, (self.fixed_table[1], offset) => ind.scalar())?; + assignf!(region, (self.fixed_table[2], offset) => true.scalar())?; + assignf!(region, (self.fixed_table[3], offset) => false.scalar())?; + assignf!(region, (self.fixed_table[4], offset) => true.scalar())?; + offset += 1; + } + for ind in 192..=247 { + // short list + assignf!(region, (self.fixed_table[0], offset) => FixedTableTag::RLP.scalar())?; + assignf!(region, (self.fixed_table[1], offset) => ind.scalar())?; + assignf!(region, (self.fixed_table[2], offset) => false.scalar())?; + assignf!(region, (self.fixed_table[3], offset) => true.scalar())?; + assignf!(region, (self.fixed_table[4], offset) => false.scalar())?; + offset += 1; + } + // 248 + // long list + assignf!(region, (self.fixed_table[0], offset) => FixedTableTag::RLP.scalar())?; + assignf!(region, (self.fixed_table[1], offset) => 248i32.scalar())?; + assignf!(region, (self.fixed_table[2], offset) => false.scalar())?; + assignf!(region, (self.fixed_table[3], offset) => false.scalar())?; + assignf!(region, (self.fixed_table[4], offset) => false.scalar())?; + offset += 1; + // 249 + // very long list + assignf!(region, (self.fixed_table[0], offset) => FixedTableTag::RLP.scalar())?; + assignf!(region, (self.fixed_table[1], offset) => 249i32.scalar())?; + assignf!(region, (self.fixed_table[2], offset) => false.scalar())?; + assignf!(region, (self.fixed_table[3], offset) => false.scalar())?; + assignf!(region, (self.fixed_table[4], offset) => true.scalar())?; + offset += 1; + + // Even - only the nibbles 0 0 are valid + assignf!(region, (self.fixed_table[0], offset) => FixedTableTag::ExtOddKey.scalar())?; + assignf!(region, (self.fixed_table[1], offset) => 0.scalar())?; + assignf!(region, (self.fixed_table[2], offset) => false.scalar())?; + offset += 1; + + // Odd - First nibble is 1, the second nibble can be any value + for idx in 0..16 { + assignf!(region, (self.fixed_table[0], offset) => FixedTableTag::ExtOddKey.scalar())?; + assignf!(region, (self.fixed_table[1], offset) => ((0b1_0000) + idx).scalar())?; + assignf!(region, (self.fixed_table[2], offset) => true.scalar())?; + offset += 1; + } + + Ok(()) + }, + ) + } + + /// load_byte_table loads the byte table into the circuit + pub fn load_byte_table(&self, layouter: &mut impl Layouter) -> Result<(), Error> { + layouter.assign_region( + || "byte table", + |mut region| { + for offset in 0..256 { + region.assign_fixed( + || "", + self.byte_table[0], + offset, + || Value::known(F::from(offset as u64)), + )?; + } + Ok(()) }, ) @@ -915,6 +1086,7 @@ impl Circuit for MPTCircuit { } config.load_fixed_table(&mut layouter, self.randomness)?; + config.load_byte_table(&mut layouter)?; config.assign(&mut layouter, &mut witness_rows, self.randomness)?; let challenges = Challenges::mock(Value::known(self.randomness)); @@ -934,11 +1106,14 @@ mod tests { dev::MockProver, halo2curves::{bn256::Fr, FieldExt}, }; - - use std::fs; + use std::{fs, env::VarError}; #[test] fn test_mpt() { + let only_run = var("ONLY_RUN") + .and_then(|idx| idx.parse::().map_err(|e|VarError::NotPresent) + ).ok(); + println!("ONLY_RUN={:?}", only_run); // for debugging: let path = "src/mpt_circuit/tests"; // let path = "tests"; @@ -954,31 +1129,64 @@ mod tests { }) .enumerate() .for_each(|(idx, f)| { - let path = f.path(); - let mut parts = path.to_str().unwrap().split('-'); - parts.next(); - let file = std::fs::File::open(path.clone()); - let reader = std::io::BufReader::new(file.unwrap()); - let w: Vec> = serde_json::from_reader(reader).unwrap(); - - let count = w.iter().filter(|r| r[r.len() - 1] != 5).count() * 2; - let randomness: Fr = 123456789.scalar(); - let instance: Vec> = (1..HASH_WIDTH + 1) - .map(|exp| vec![randomness.pow(&[exp as u64, 0, 0, 0]); count]) - .collect(); - - let circuit = MPTCircuit:: { - witness: w.clone(), - randomness, - }; - - println!("{} {:?}", idx, path); - // let prover = MockProver::run(9, &circuit, vec![pub_root]).unwrap(); - let num_rows = w.len() * 2; - let prover = MockProver::run(14 /* 9 */, &circuit, instance).unwrap(); - assert_eq!(prover.verify_at_rows(0..num_rows, 0..num_rows,), Ok(())); - //assert_eq!(prover.verify_par(), Ok(())); - //prover.assert_satisfied(); + let mut run = true; + if let Some(i) = only_run { + if idx != i {run = false;} + } + if run { + let path = f.path(); + let mut parts = path.to_str().unwrap().split('-'); + parts.next(); + let file = std::fs::File::open(path.clone()); + let reader = std::io::BufReader::new(file.unwrap()); + let w: Vec> = serde_json::from_reader(reader).unwrap(); + + let count = w.iter().filter(|r| r[r.len() - 1] != 5).count() * 2; + let randomness: Fr = 123456789.scalar(); + let instance: Vec> = (1..HASH_WIDTH + 1) + .map(|exp| vec![randomness.pow(&[exp as u64, 0, 0, 0]); count]) + .collect(); + + let circuit = MPTCircuit:: { + witness: w.clone(), + randomness, + }; + + println!("{} {:?}", idx, path); + // let prover = MockProver::run(9, &circuit, vec![pub_root]).unwrap(); + let num_rows = w.len() * 2; + let prover = MockProver::run(14 /* 9 */, &circuit, instance).unwrap(); + assert_eq!(prover.verify_at_rows(0..num_rows, 0..num_rows,), Ok(())); + //assert_eq!(prover.verify_par(), Ok(())); + //prover.assert_satisfied(); + } }); } + + + #[test] + fn test_mpt2() { + let wit = "[[0,1,0,1,249,2,17,249,2,17,15,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0],[0,160,215,178,43,142,72,221,147,48,230,157,99,126,109,240,144,184,54,167,1,19,157,71,126,226,97,100,220,221,118,5,202,114,0,160,215,178,43,142,72,221,147,48,230,157,99,126,109,240,144,184,54,167,1,19,157,71,126,226,97,100,220,221,118,5,202,114,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[0,160,195,19,38,251,242,179,135,46,118,82,177,213,78,156,167,171,134,95,6,233,153,168,219,176,131,34,215,213,95,252,168,165,0,160,195,19,38,251,242,179,135,46,118,82,177,213,78,156,167,171,134,95,6,233,153,168,219,176,131,34,215,213,95,252,168,165,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[0,160,242,119,75,182,209,50,158,172,168,239,218,202,172,144,155,94,44,154,149,92,253,83,150,12,4,176,33,46,25,36,170,225,0,160,242,119,75,182,209,50,158,172,168,239,218,202,172,144,155,94,44,154,149,92,253,83,150,12,4,176,33,46,25,36,170,225,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[0,160,156,18,160,254,15,159,132,100,9,112,178,98,98,93,76,54,189,166,63,219,45,193,25,238,218,78,235,150,206,67,252,253,0,160,156,18,160,254,15,159,132,100,9,112,178,98,98,93,76,54,189,166,63,219,45,193,25,238,218,78,235,150,206,67,252,253,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[0,160,100,75,99,34,122,170,85,172,143,62,172,142,154,219,40,105,162,136,113,194,41,38,129,211,105,114,94,62,145,244,97,170,0,160,100,75,99,34,122,170,85,172,143,62,172,142,154,219,40,105,162,136,113,194,41,38,129,211,105,114,94,62,145,244,97,170,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[0,160,229,94,177,9,226,34,180,156,33,249,119,163,74,194,218,172,92,90,13,44,22,231,5,100,72,203,19,192,62,46,34,34,0,160,229,94,177,9,226,34,180,156,33,249,119,163,74,194,218,172,92,90,13,44,22,231,5,100,72,203,19,192,62,46,34,34,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[0,160,15,175,179,52,244,84,197,105,112,43,252,115,186,76,237,251,88,5,62,201,157,9,7,153,100,224,202,249,250,183,125,248,0,160,15,175,179,52,244,84,197,105,112,43,252,115,186,76,237,251,88,5,62,201,157,9,7,153,100,224,202,249,250,183,125,248,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[0,160,14,229,239,45,75,116,39,109,41,89,200,43,18,94,204,133,62,175,23,200,68,93,170,95,36,226,233,183,66,98,37,184,0,160,14,229,239,45,75,116,39,109,41,89,200,43,18,94,204,133,62,175,23,200,68,93,170,95,36,226,233,183,66,98,37,184,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[0,160,6,197,49,201,57,39,248,81,26,196,11,167,230,243,100,223,97,38,20,1,226,39,180,161,172,204,67,80,173,223,89,42,0,160,6,197,49,201,57,39,248,81,26,196,11,167,230,243,100,223,97,38,20,1,226,39,180,161,172,204,67,80,173,223,89,42,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[0,160,3,131,195,206,124,22,207,14,142,91,216,135,77,202,69,1,53,115,223,85,52,95,43,227,237,82,138,95,93,70,227,232,0,160,3,131,195,206,124,22,207,14,142,91,216,135,77,202,69,1,53,115,223,85,52,95,43,227,237,82,138,95,93,70,227,232,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[0,160,98,109,64,32,201,140,205,221,164,1,209,57,84,209,249,108,87,101,70,12,37,160,114,139,27,145,104,130,62,183,150,108,0,160,98,109,64,32,201,140,205,221,164,1,209,57,84,209,249,108,87,101,70,12,37,160,114,139,27,145,104,130,62,183,150,108,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[0,160,69,221,169,92,165,83,34,53,123,93,55,127,206,167,112,175,13,233,196,118,68,137,156,246,219,49,159,137,25,37,30,157,0,160,69,221,169,92,165,83,34,53,123,93,55,127,206,167,112,175,13,233,196,118,68,137,156,246,219,49,159,137,25,37,30,157,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[0,160,39,24,29,240,236,191,237,195,74,255,251,61,19,232,218,181,111,83,69,125,70,208,135,182,81,0,125,85,38,21,25,11,0,160,39,24,29,240,236,191,237,195,74,255,251,61,19,232,218,181,111,83,69,125,70,208,135,182,81,0,125,85,38,21,25,11,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[0,160,191,249,76,252,217,172,58,95,133,138,144,243,9,87,191,253,23,150,215,186,153,214,27,17,128,10,154,202,202,43,193,173,0,160,191,249,76,252,217,172,58,95,133,138,144,243,9,87,191,253,23,150,215,186,153,214,27,17,128,10,154,202,202,43,193,173,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[0,160,238,147,22,82,116,71,41,238,84,0,62,40,0,153,205,90,194,234,61,255,205,197,55,0,41,239,197,174,219,163,6,130,0,160,238,147,22,82,116,71,41,238,84,0,62,40,0,153,205,90,194,234,61,255,205,197,55,0,41,239,197,174,219,163,6,130,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[0,160,22,99,129,222,131,163,115,40,32,94,210,97,181,141,77,173,9,184,214,164,50,44,139,113,241,255,7,213,43,8,145,41,0,160,245,44,16,35,247,198,201,190,127,121,84,12,180,160,45,116,180,243,5,121,76,186,165,227,121,49,165,118,171,248,179,191,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,17],[0,1,0,1,249,2,17,249,2,17,12,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0],[0,160,62,81,246,216,50,34,109,164,244,230,118,34,30,57,143,168,201,163,53,157,138,200,83,22,217,54,9,12,142,74,113,119,0,160,62,81,246,216,50,34,109,164,244,230,118,34,30,57,143,168,201,163,53,157,138,200,83,22,217,54,9,12,142,74,113,119,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,110,58,129,42,7,242,95,48,22,117,24,235,247,115,27,159,148,240,189,82,238,245,24,104,4,88,96,153,87,62,124,87,0,160,110,58,129,42,7,242,95,48,22,117,24,235,247,115,27,159,148,240,189,82,238,245,24,104,4,88,96,153,87,62,124,87,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,23,125,132,126,57,77,125,108,183,122,223,20,200,11,140,116,8,197,125,77,164,229,34,187,130,255,11,5,123,106,18,226,0,160,23,125,132,126,57,77,125,108,183,122,223,20,200,11,140,116,8,197,125,77,164,229,34,187,130,255,11,5,123,106,18,226,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,34,142,142,168,173,99,151,78,20,223,49,167,173,193,155,22,185,57,77,94,140,81,219,8,205,119,152,79,221,53,32,207,0,160,34,142,142,168,173,99,151,78,20,223,49,167,173,193,155,22,185,57,77,94,140,81,219,8,205,119,152,79,221,53,32,207,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,47,68,110,156,219,87,42,252,153,153,146,44,71,68,241,42,115,255,196,172,147,166,193,209,18,197,101,149,78,252,80,101,0,160,47,68,110,156,219,87,42,252,153,153,146,44,71,68,241,42,115,255,196,172,147,166,193,209,18,197,101,149,78,252,80,101,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,177,72,39,32,231,101,153,80,19,87,43,118,153,180,111,107,120,208,26,121,107,122,223,78,248,252,112,146,129,121,183,249,0,160,177,72,39,32,231,101,153,80,19,87,43,118,153,180,111,107,120,208,26,121,107,122,223,78,248,252,112,146,129,121,183,249,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,166,43,253,9,132,156,69,206,240,132,245,215,140,18,136,28,76,115,232,35,55,46,97,106,111,29,136,215,243,244,104,17,0,160,166,43,253,9,132,156,69,206,240,132,245,215,140,18,136,28,76,115,232,35,55,46,97,106,111,29,136,215,243,244,104,17,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,81,197,227,235,119,136,89,180,1,44,243,14,3,35,252,32,39,239,6,187,20,67,5,160,124,3,15,223,92,185,169,242,0,160,81,197,227,235,119,136,89,180,1,44,243,14,3,35,252,32,39,239,6,187,20,67,5,160,124,3,15,223,92,185,169,242,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,149,116,118,68,110,184,206,46,175,107,154,14,16,171,116,53,96,139,243,244,119,49,149,255,105,200,203,196,178,219,6,82,0,160,149,116,118,68,110,184,206,46,175,107,154,14,16,171,116,53,96,139,243,244,119,49,149,255,105,200,203,196,178,219,6,82,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,110,155,225,108,252,161,111,115,34,161,168,254,20,210,73,55,53,84,44,62,235,227,145,125,56,152,100,115,68,140,102,72,0,160,110,155,225,108,252,161,111,115,34,161,168,254,20,210,73,55,53,84,44,62,235,227,145,125,56,152,100,115,68,140,102,72,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,215,32,96,214,100,112,201,119,187,39,102,186,145,221,83,195,0,96,163,123,49,150,62,117,25,68,3,71,226,217,71,5,0,160,215,32,96,214,100,112,201,119,187,39,102,186,145,221,83,195,0,96,163,123,49,150,62,117,25,68,3,71,226,217,71,5,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,216,77,122,185,166,60,76,175,212,143,31,218,53,223,132,60,243,170,247,163,51,217,81,184,10,173,42,95,228,91,232,94,0,160,216,77,122,185,166,60,76,175,212,143,31,218,53,223,132,60,243,170,247,163,51,217,81,184,10,173,42,95,228,91,232,94,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,102,201,63,187,90,100,67,28,66,169,235,107,142,189,159,208,34,47,59,148,229,29,242,190,206,105,91,103,217,108,220,3,0,160,215,59,125,216,248,19,201,18,250,183,66,8,213,171,232,118,28,224,37,86,154,26,45,63,50,37,179,78,95,7,56,114,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,130,214,88,212,94,182,185,119,29,142,174,223,89,224,222,59,117,224,157,226,110,51,196,90,175,27,158,67,104,153,87,154,0,160,130,214,88,212,94,182,185,119,29,142,174,223,89,224,222,59,117,224,157,226,110,51,196,90,175,27,158,67,104,153,87,154,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,32,215,128,174,120,163,233,16,26,195,200,23,79,233,122,253,170,114,110,149,85,164,70,233,70,156,107,147,254,209,174,11,0,160,32,215,128,174,120,163,233,16,26,195,200,23,79,233,122,253,170,114,110,149,85,164,70,233,70,156,107,147,254,209,174,11,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,193,92,89,242,135,228,231,76,186,23,253,187,202,250,103,245,131,178,24,164,47,129,106,19,179,50,117,153,14,62,38,242,0,160,193,92,89,242,135,228,231,76,186,23,253,187,202,250,103,245,131,178,24,164,47,129,106,19,179,50,117,153,14,62,38,242,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,17],[0,1,0,1,249,2,17,249,2,17,14,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0],[0,160,243,248,117,132,135,179,242,217,170,170,147,202,41,30,49,202,235,19,91,182,154,115,189,49,71,95,213,18,134,202,205,168,0,160,243,248,117,132,135,179,242,217,170,170,147,202,41,30,49,202,235,19,91,182,154,115,189,49,71,95,213,18,134,202,205,168,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,248,214,27,163,48,89,69,124,39,200,95,223,46,31,254,156,7,133,69,242,252,178,116,213,90,11,24,2,233,210,95,159,0,160,248,214,27,163,48,89,69,124,39,200,95,223,46,31,254,156,7,133,69,242,252,178,116,213,90,11,24,2,233,210,95,159,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,71,79,93,73,42,149,57,51,225,103,235,189,110,188,70,240,193,23,63,219,116,110,243,110,149,7,153,50,68,75,57,255,0,160,71,79,93,73,42,149,57,51,225,103,235,189,110,188,70,240,193,23,63,219,116,110,243,110,149,7,153,50,68,75,57,255,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,247,151,249,133,151,231,1,67,135,51,218,198,210,129,152,142,23,144,43,153,113,15,227,167,123,200,117,134,246,144,41,89,0,160,247,151,249,133,151,231,1,67,135,51,218,198,210,129,152,142,23,144,43,153,113,15,227,167,123,200,117,134,246,144,41,89,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,64,41,80,117,176,86,114,226,155,222,42,78,189,238,210,98,213,168,109,98,43,187,53,78,43,64,239,233,108,49,103,145,0,160,64,41,80,117,176,86,114,226,155,222,42,78,189,238,210,98,213,168,109,98,43,187,53,78,43,64,239,233,108,49,103,145,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,81,130,213,232,226,141,41,38,167,145,141,254,200,67,223,12,25,155,31,46,162,105,182,222,2,233,159,55,73,58,81,8,0,160,81,130,213,232,226,141,41,38,167,145,141,254,200,67,223,12,25,155,31,46,162,105,182,222,2,233,159,55,73,58,81,8,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,26,77,61,137,205,196,204,129,210,129,10,70,241,189,76,121,69,162,6,215,188,152,126,170,249,149,72,157,147,95,113,240,0,160,26,77,61,137,205,196,204,129,210,129,10,70,241,189,76,121,69,162,6,215,188,152,126,170,249,149,72,157,147,95,113,240,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,76,38,106,162,112,134,133,37,202,39,149,12,3,108,165,104,174,60,185,97,253,218,30,38,19,121,89,102,165,245,8,216,0,160,76,38,106,162,112,134,133,37,202,39,149,12,3,108,165,104,174,60,185,97,253,218,30,38,19,121,89,102,165,245,8,216,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,52,133,159,70,24,244,195,146,2,17,195,222,204,211,129,28,126,50,191,31,4,148,37,228,107,40,143,95,15,239,188,142,0,160,52,133,159,70,24,244,195,146,2,17,195,222,204,211,129,28,126,50,191,31,4,148,37,228,107,40,143,95,15,239,188,142,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,30,36,232,235,34,123,13,63,36,1,92,189,49,255,191,152,101,81,234,45,170,78,228,224,41,77,6,235,75,41,95,228,0,160,30,36,232,235,34,123,13,63,36,1,92,189,49,255,191,152,101,81,234,45,170,78,228,224,41,77,6,235,75,41,95,228,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,53,118,183,248,110,40,9,128,63,159,4,146,88,128,57,182,207,231,204,72,18,102,249,225,183,253,26,165,204,221,133,107,0,160,53,118,183,248,110,40,9,128,63,159,4,146,88,128,57,182,207,231,204,72,18,102,249,225,183,253,26,165,204,221,133,107,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,47,211,121,43,20,152,236,53,207,92,248,102,254,75,207,136,49,232,147,125,59,184,15,14,62,136,58,5,56,132,135,139,0,160,47,211,121,43,20,152,236,53,207,92,248,102,254,75,207,136,49,232,147,125,59,184,15,14,62,136,58,5,56,132,135,139,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,146,83,193,207,181,29,203,52,47,58,114,231,161,55,66,1,75,127,145,210,118,37,82,232,135,3,183,30,255,240,248,11,0,160,146,83,193,207,181,29,203,52,47,58,114,231,161,55,66,1,75,127,145,210,118,37,82,232,135,3,183,30,255,240,248,11,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,74,111,171,71,106,196,108,204,154,49,109,206,164,6,195,104,55,35,226,133,78,86,140,154,197,163,105,253,218,72,68,52,0,160,74,111,171,71,106,196,108,204,154,49,109,206,164,6,195,104,55,35,226,133,78,86,140,154,197,163,105,253,218,72,68,52,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,221,162,147,55,34,170,139,142,218,244,84,132,181,168,39,246,188,198,8,193,144,16,119,237,138,12,69,220,76,152,153,153,0,160,142,150,91,3,151,108,7,234,211,182,207,220,110,244,217,170,240,12,90,203,195,243,210,201,172,9,15,30,76,40,83,183,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,250,100,42,85,168,208,19,121,181,167,41,37,110,73,50,34,56,59,218,49,242,70,153,106,217,4,105,151,51,36,134,125,0,160,250,100,42,85,168,208,19,121,181,167,41,37,110,73,50,34,56,59,218,49,242,70,153,106,217,4,105,151,51,36,134,125,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,17],[0,1,0,1,249,2,17,249,2,17,13,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0],[0,160,161,128,1,12,47,16,128,58,172,109,97,186,101,50,211,24,116,166,152,209,189,185,191,39,125,163,235,50,169,86,158,229,0,160,161,128,1,12,47,16,128,58,172,109,97,186,101,50,211,24,116,166,152,209,189,185,191,39,125,163,235,50,169,86,158,229,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,43,180,202,90,212,89,144,118,139,227,102,232,30,186,65,236,181,5,130,247,53,26,255,110,32,164,81,96,121,240,13,252,0,160,43,180,202,90,212,89,144,118,139,227,102,232,30,186,65,236,181,5,130,247,53,26,255,110,32,164,81,96,121,240,13,252,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,222,100,177,157,75,143,240,145,16,36,58,46,51,139,107,7,196,233,64,182,153,253,203,175,129,102,22,111,153,168,150,26,0,160,222,100,177,157,75,143,240,145,16,36,58,46,51,139,107,7,196,233,64,182,153,253,203,175,129,102,22,111,153,168,150,26,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,94,231,69,12,111,229,77,99,71,17,141,11,41,112,27,177,218,61,40,30,213,193,247,27,173,123,94,162,194,11,64,110,0,160,94,231,69,12,111,229,77,99,71,17,141,11,41,112,27,177,218,61,40,30,213,193,247,27,173,123,94,162,194,11,64,110,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,148,241,5,249,211,104,221,226,140,197,193,238,210,173,105,8,129,244,154,57,13,253,109,216,177,158,110,36,172,122,110,88,0,160,148,241,5,249,211,104,221,226,140,197,193,238,210,173,105,8,129,244,154,57,13,253,109,216,177,158,110,36,172,122,110,88,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,49,101,31,195,122,182,161,106,170,190,126,247,114,74,123,53,20,100,9,186,33,38,17,167,168,229,10,220,151,18,196,241,0,160,49,101,31,195,122,182,161,106,170,190,126,247,114,74,123,53,20,100,9,186,33,38,17,167,168,229,10,220,151,18,196,241,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,73,246,226,153,120,139,128,58,10,194,85,4,186,39,18,220,239,252,50,159,22,196,125,122,103,50,247,196,37,68,58,169,0,160,73,246,226,153,120,139,128,58,10,194,85,4,186,39,18,220,239,252,50,159,22,196,125,122,103,50,247,196,37,68,58,169,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,15,132,108,63,247,99,185,92,140,54,8,64,230,186,45,30,61,193,8,165,18,74,107,200,87,45,33,232,22,58,219,43,0,160,15,132,108,63,247,99,185,92,140,54,8,64,230,186,45,30,61,193,8,165,18,74,107,200,87,45,33,232,22,58,219,43,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,171,6,213,180,15,77,228,71,174,54,254,251,111,241,218,40,233,3,107,112,164,163,132,133,85,121,0,128,188,237,176,38,0,160,171,6,213,180,15,77,228,71,174,54,254,251,111,241,218,40,233,3,107,112,164,163,132,133,85,121,0,128,188,237,176,38,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,190,202,142,180,181,1,250,241,49,215,108,185,216,23,205,142,139,158,85,162,252,156,118,150,43,152,194,183,178,218,159,221,0,160,190,202,142,180,181,1,250,241,49,215,108,185,216,23,205,142,139,158,85,162,252,156,118,150,43,152,194,183,178,218,159,221,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,116,118,116,254,111,169,77,111,65,32,203,133,193,209,164,92,7,21,222,137,239,153,10,17,202,156,229,253,242,229,50,66,0,160,116,118,116,254,111,169,77,111,65,32,203,133,193,209,164,92,7,21,222,137,239,153,10,17,202,156,229,253,242,229,50,66,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,245,182,9,212,150,185,219,26,154,17,0,141,168,125,166,152,114,219,87,156,42,77,206,233,29,211,176,18,46,29,86,118,0,160,245,182,9,212,150,185,219,26,154,17,0,141,168,125,166,152,114,219,87,156,42,77,206,233,29,211,176,18,46,29,86,118,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,125,173,37,34,63,10,10,105,35,138,170,159,170,58,203,218,96,174,159,130,118,216,137,144,59,203,221,237,109,28,197,14,0,160,125,173,37,34,63,10,10,105,35,138,170,159,170,58,203,218,96,174,159,130,118,216,137,144,59,203,221,237,109,28,197,14,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,125,205,12,44,38,14,115,188,176,89,248,149,162,236,64,246,24,91,125,70,183,125,37,100,214,54,174,74,207,71,185,190,0,160,77,232,92,90,207,144,28,209,255,114,73,30,34,22,65,146,193,168,52,246,172,111,139,107,21,220,140,195,72,109,174,142,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,9,167,144,133,57,89,194,210,118,41,249,242,60,234,105,179,15,125,163,86,11,161,61,242,89,222,67,163,239,141,115,22,0,160,9,167,144,133,57,89,194,210,118,41,249,242,60,234,105,179,15,125,163,86,11,161,61,242,89,222,67,163,239,141,115,22,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,229,254,113,96,76,247,87,54,147,166,26,241,48,108,149,89,115,6,35,119,201,191,233,239,90,99,195,93,22,222,43,126,0,160,229,254,113,96,76,247,87,54,147,166,26,241,48,108,149,89,115,6,35,119,201,191,233,239,90,99,195,93,22,222,43,126,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,17],[0,1,0,1,249,2,17,249,2,17,3,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0],[0,160,1,140,240,73,75,204,201,222,156,243,213,94,33,163,61,8,206,249,37,116,57,74,97,38,98,157,136,8,8,58,80,150,0,160,1,140,240,73,75,204,201,222,156,243,213,94,33,163,61,8,206,249,37,116,57,74,97,38,98,157,136,8,8,58,80,150,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,195,199,196,181,116,185,85,110,248,215,152,211,207,168,41,60,203,5,86,141,59,163,78,219,9,213,111,185,55,120,19,233,0,160,195,199,196,181,116,185,85,110,248,215,152,211,207,168,41,60,203,5,86,141,59,163,78,219,9,213,111,185,55,120,19,233,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,140,202,218,220,242,107,140,113,118,132,7,69,53,214,70,230,137,184,171,129,43,48,107,81,80,73,247,0,177,229,219,121,0,160,140,202,218,220,242,107,140,113,118,132,7,69,53,214,70,230,137,184,171,129,43,48,107,81,80,73,247,0,177,229,219,121,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,33,36,191,50,11,87,222,33,182,77,167,63,136,123,248,241,74,182,24,11,174,247,239,125,99,202,207,255,128,35,52,165,0,160,224,226,228,152,49,191,94,18,202,42,40,43,44,135,217,234,139,112,115,185,228,196,213,42,168,79,181,143,79,201,143,96,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,149,249,75,250,81,105,43,241,150,173,198,3,252,180,149,96,0,111,180,34,118,196,43,123,93,132,160,96,250,100,217,45,0,160,149,249,75,250,81,105,43,241,150,173,198,3,252,180,149,96,0,111,180,34,118,196,43,123,93,132,160,96,250,100,217,45,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,32,39,96,173,133,195,109,50,97,77,73,185,128,89,4,150,255,132,58,164,43,120,193,117,186,32,133,65,91,116,162,173,0,160,32,39,96,173,133,195,109,50,97,77,73,185,128,89,4,150,255,132,58,164,43,120,193,117,186,32,133,65,91,116,162,173,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,98,239,63,98,146,213,134,176,5,254,159,193,14,251,162,124,237,62,243,94,97,73,108,47,3,76,184,133,162,93,214,124,0,160,98,239,63,98,146,213,134,176,5,254,159,193,14,251,162,124,237,62,243,94,97,73,108,47,3,76,184,133,162,93,214,124,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,24,110,66,31,239,73,37,228,27,69,165,214,234,132,223,109,118,39,20,166,141,25,228,24,156,85,122,60,112,195,235,154,0,160,24,110,66,31,239,73,37,228,27,69,165,214,234,132,223,109,118,39,20,166,141,25,228,24,156,85,122,60,112,195,235,154,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,124,4,254,255,41,243,241,33,206,19,170,136,141,252,149,202,221,147,172,85,213,237,197,110,71,174,111,101,127,85,205,59,0,160,124,4,254,255,41,243,241,33,206,19,170,136,141,252,149,202,221,147,172,85,213,237,197,110,71,174,111,101,127,85,205,59,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,23,49,65,202,234,196,28,65,205,115,198,37,246,143,124,72,166,37,205,232,162,25,22,39,127,188,14,26,18,214,240,152,0,160,23,49,65,202,234,196,28,65,205,115,198,37,246,143,124,72,166,37,205,232,162,25,22,39,127,188,14,26,18,214,240,152,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,51,21,215,92,255,202,104,15,118,167,53,140,39,4,142,82,127,133,147,230,204,253,47,54,99,23,226,78,113,129,89,185,0,160,51,21,215,92,255,202,104,15,118,167,53,140,39,4,142,82,127,133,147,230,204,253,47,54,99,23,226,78,113,129,89,185,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,239,123,251,65,188,11,107,22,9,46,42,104,47,193,60,78,205,118,242,12,136,145,137,46,214,157,184,26,255,37,206,38,0,160,239,123,251,65,188,11,107,22,9,46,42,104,47,193,60,78,205,118,242,12,136,145,137,46,214,157,184,26,255,37,206,38,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,179,163,103,185,250,53,96,32,14,9,248,46,117,61,151,70,245,116,155,44,163,22,115,1,102,242,244,157,45,81,102,14,0,160,179,163,103,185,250,53,96,32,14,9,248,46,117,61,151,70,245,116,155,44,163,22,115,1,102,242,244,157,45,81,102,14,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,120,51,181,75,204,140,26,229,78,145,104,6,122,193,149,189,178,100,84,118,214,32,148,10,91,248,41,39,153,51,148,250,0,160,120,51,181,75,204,140,26,229,78,145,104,6,122,193,149,189,178,100,84,118,214,32,148,10,91,248,41,39,153,51,148,250,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,152,64,28,199,229,115,92,129,39,229,199,166,105,168,252,23,227,109,56,225,3,255,171,233,92,155,115,43,225,156,231,35,0,160,152,64,28,199,229,115,92,129,39,229,199,166,105,168,252,23,227,109,56,225,3,255,171,233,92,155,115,43,225,156,231,35,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,79,205,115,234,146,184,235,250,60,154,252,244,30,28,214,37,12,114,43,159,140,167,245,162,159,65,188,1,113,43,38,143,0,160,79,205,115,234,146,184,235,250,60,154,252,244,30,28,214,37,12,114,43,159,140,167,245,162,159,65,188,1,113,43,38,143,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,17],[0,1,0,1,249,2,17,249,2,17,4,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0],[0,160,245,105,73,55,130,156,85,160,31,141,126,218,15,74,121,147,147,14,234,12,31,2,207,74,132,213,9,173,180,149,183,107,0,160,245,105,73,55,130,156,85,160,31,141,126,218,15,74,121,147,147,14,234,12,31,2,207,74,132,213,9,173,180,149,183,107,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,221,130,180,81,176,155,200,100,168,4,254,92,101,171,36,147,95,202,31,177,191,39,28,78,15,253,236,77,124,115,149,137,0,160,221,130,180,81,176,155,200,100,168,4,254,92,101,171,36,147,95,202,31,177,191,39,28,78,15,253,236,77,124,115,149,137,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,8,37,3,52,123,198,42,148,211,79,179,98,105,89,161,130,151,2,137,5,198,34,114,85,180,47,176,126,179,111,60,206,0,160,8,37,3,52,123,198,42,148,211,79,179,98,105,89,161,130,151,2,137,5,198,34,114,85,180,47,176,126,179,111,60,206,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,232,217,161,8,22,169,40,66,131,228,203,23,191,255,11,201,101,138,145,67,49,60,150,125,179,56,59,152,181,26,174,138,0,160,232,217,161,8,22,169,40,66,131,228,203,23,191,255,11,201,101,138,145,67,49,60,150,125,179,56,59,152,181,26,174,138,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,52,5,132,223,20,125,125,152,77,21,29,239,159,211,65,174,156,121,107,233,188,67,44,242,54,70,100,18,159,243,207,206,0,160,46,144,237,143,190,109,159,205,233,64,197,103,36,172,203,35,39,122,25,184,212,193,136,197,175,120,207,44,140,182,105,222,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,224,250,15,5,72,187,58,246,78,193,251,188,67,94,94,63,151,23,215,194,99,44,14,23,45,34,254,220,3,94,41,58,0,160,224,250,15,5,72,187,58,246,78,193,251,188,67,94,94,63,151,23,215,194,99,44,14,23,45,34,254,220,3,94,41,58,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,6,105,60,12,5,193,169,245,176,112,146,23,69,42,0,33,177,13,230,213,165,102,152,203,58,175,135,4,16,128,172,8,0,160,6,105,60,12,5,193,169,245,176,112,146,23,69,42,0,33,177,13,230,213,165,102,152,203,58,175,135,4,16,128,172,8,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,151,152,86,204,166,248,67,223,250,77,31,100,237,11,43,191,90,23,20,54,199,92,11,215,145,50,87,90,167,159,57,165,0,160,151,152,86,204,166,248,67,223,250,77,31,100,237,11,43,191,90,23,20,54,199,92,11,215,145,50,87,90,167,159,57,165,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,1,232,26,222,47,23,75,176,90,187,251,204,93,173,132,158,36,225,142,226,147,28,202,173,168,228,182,229,123,127,49,117,0,160,1,232,26,222,47,23,75,176,90,187,251,204,93,173,132,158,36,225,142,226,147,28,202,173,168,228,182,229,123,127,49,117,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,247,78,159,238,239,170,53,113,45,18,48,98,112,234,117,104,97,108,138,230,14,76,168,84,236,172,64,67,208,57,6,73,0,160,247,78,159,238,239,170,53,113,45,18,48,98,112,234,117,104,97,108,138,230,14,76,168,84,236,172,64,67,208,57,6,73,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,46,68,248,146,220,227,97,0,41,252,210,9,44,117,251,227,165,196,13,189,174,150,34,139,203,17,200,40,245,122,167,206,0,160,46,68,248,146,220,227,97,0,41,252,210,9,44,117,251,227,165,196,13,189,174,150,34,139,203,17,200,40,245,122,167,206,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,26,216,79,208,48,103,203,251,178,213,93,58,82,104,200,119,234,228,233,252,208,91,195,35,224,229,183,69,89,175,14,229,0,160,26,216,79,208,48,103,203,251,178,213,93,58,82,104,200,119,234,228,233,252,208,91,195,35,224,229,183,69,89,175,14,229,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,246,209,205,0,213,119,26,186,142,93,94,61,153,28,165,149,49,176,155,119,213,241,208,245,15,163,38,131,125,219,108,170,0,160,246,209,205,0,213,119,26,186,142,93,94,61,153,28,165,149,49,176,155,119,213,241,208,245,15,163,38,131,125,219,108,170,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,89,143,190,130,47,255,40,170,85,219,138,46,139,251,126,68,17,241,5,216,204,86,127,71,120,116,170,149,237,137,28,227,0,160,89,143,190,130,47,255,40,170,85,219,138,46,139,251,126,68,17,241,5,216,204,86,127,71,120,116,170,149,237,137,28,227,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,79,246,250,96,218,39,3,222,92,140,84,169,44,51,184,140,136,139,201,154,119,208,207,98,29,112,62,108,254,3,142,180,0,160,79,246,250,96,218,39,3,222,92,140,84,169,44,51,184,140,136,139,201,154,119,208,207,98,29,112,62,108,254,3,142,180,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,130,179,74,86,218,213,192,18,132,24,134,63,237,50,86,187,20,97,174,221,173,83,84,97,186,105,52,78,209,101,251,138,0,160,130,179,74,86,218,213,192,18,132,24,134,63,237,50,86,187,20,97,174,221,173,83,84,97,186,105,52,78,209,101,251,138,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,17],[1,0,1,0,248,241,0,248,241,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0],[0,160,255,151,217,75,103,5,122,115,224,137,233,146,50,189,95,178,178,247,44,237,22,101,231,39,198,40,14,249,60,251,151,15,0,160,188,253,144,87,144,251,204,78,148,203,12,141,0,77,176,70,67,92,90,100,110,40,255,28,218,97,116,184,26,121,18,49,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,60,79,85,51,115,192,158,157,93,223,211,100,62,94,72,146,251,82,116,111,190,139,246,12,252,146,211,122,66,110,206,20,0,160,60,79,85,51,115,192,158,157,93,223,211,100,62,94,72,146,251,82,116,111,190,139,246,12,252,146,211,122,66,110,206,20,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,120,190,160,200,253,109,255,226,49,189,87,112,136,160,23,77,119,59,173,185,188,145,251,156,155,144,100,217,100,114,109,106,0,160,120,190,160,200,253,109,255,226,49,189,87,112,136,160,23,77,119,59,173,185,188,145,251,156,155,144,100,217,100,114,109,106,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,69,72,113,186,79,146,63,86,46,218,1,200,131,76,71,142,217,35,30,209,101,239,91,47,163,221,136,130,249,155,236,112,0,160,69,72,113,186,79,146,63,86,46,218,1,200,131,76,71,142,217,35,30,209,101,239,91,47,163,221,136,130,249,155,236,112,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,49,65,26,94,193,156,227,78,42,198,56,211,105,254,0,33,31,96,41,208,40,13,215,156,51,173,132,112,34,192,121,49,0,160,49,65,26,94,193,156,227,78,42,198,56,211,105,254,0,33,31,96,41,208,40,13,215,156,51,173,132,112,34,192,121,49,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,244,154,252,18,232,96,245,36,84,15,253,182,157,226,247,165,106,144,166,1,2,140,228,170,110,87,112,80,140,149,162,43,0,160,244,154,252,18,232,96,245,36,84,15,253,182,157,226,247,165,106,144,166,1,2,140,228,170,110,87,112,80,140,149,162,43,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,20,103,6,95,163,140,21,238,207,84,226,60,134,0,183,217,11,213,185,123,139,201,37,22,227,234,220,30,160,20,244,115,0,160,20,103,6,95,163,140,21,238,207,84,226,60,134,0,183,217,11,213,185,123,139,201,37,22,227,234,220,30,160,20,244,115,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,17],[1,0,1,0,248,81,0,248,81,0,8,1,0,7,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,222,45,71,217,199,68,20,55,244,206,68,197,49,191,78,208,106,209,111,87,254,9,221,230,148,86,131,219,7,121,62,140,0,160,222,45,71,217,199,68,20,55,244,206,68,197,49,191,78,208,106,209,111,87,254,9,221,230,148,86,131,219,7,121,62,140,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,160,190,214,56,80,83,126,135,17,104,48,181,30,249,223,80,59,155,70,206,67,24,6,82,98,81,246,212,143,253,181,15,180,0,160,190,214,56,80,83,126,135,17,104,48,181,30,249,223,80,59,155,70,206,67,24,6,82,98,81,246,212,143,253,181,15,180,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,17],[248,102,157,55,236,125,29,155,142,209,241,75,145,144,143,254,65,81,209,56,13,192,157,236,195,213,73,132,11,251,149,241,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,6],[248,102,157,32,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,4],[0,0,157,32,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,18],[184,70,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,7],[184,70,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,8],[0,160,112,158,181,221,162,20,124,79,184,25,162,13,167,162,146,25,237,242,59,120,184,154,118,137,92,181,187,152,115,82,223,48,0,160,7,190,1,231,231,32,111,227,30,206,233,26,215,93,173,166,90,214,186,67,58,230,71,161,185,51,4,105,247,198,103,124,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,9],[0,160,112,158,181,221,162,20,124,79,184,25,162,13,167,162,146,25,237,242,59,120,184,154,118,137,92,181,187,152,115,82,223,48,0,160,7,190,1,231,231,32,111,227,30,206,233,26,215,93,173,166,90,214,186,67,58,230,71,161,185,51,4,105,247,198,103,124,0,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,11],[248,102,157,32,236,125,29,155,142,209,241,75,145,144,143,254,65,81,209,56,13,192,157,236,195,213,73,132,11,251,149,241,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,92,69,153,141,251,249,206,112,188,187,128,87,78,215,166,34,146,45,44,119,94,10,35,49,254,90,139,141,204,153,244,144,242,246,191,23,44,167,166,154,14,14,27,198,200,66,149,155,102,162,36,92,147,76,227,228,141,122,139,186,245,89,5,41,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,10],[249,2,17,160,215,178,43,142,72,221,147,48,230,157,99,126,109,240,144,184,54,167,1,19,157,71,126,226,97,100,220,221,118,5,202,114,160,195,19,38,251,242,179,135,46,118,82,177,213,78,156,167,171,134,95,6,233,153,168,219,176,131,34,215,213,95,252,168,165,160,242,119,75,182,209,50,158,172,168,239,218,202,172,144,155,94,44,154,149,92,253,83,150,12,4,176,33,46,25,36,170,225,160,156,18,160,254,15,159,132,100,9,112,178,98,98,93,76,54,189,166,63,219,45,193,25,238,218,78,235,150,206,67,252,253,160,100,75,99,34,122,170,85,172,143,62,172,142,154,219,40,105,162,136,113,194,41,38,129,211,105,114,94,62,145,244,97,170,160,229,94,177,9,226,34,180,156,33,249,119,163,74,194,218,172,92,90,13,44,22,231,5,100,72,203,19,192,62,46,34,34,160,15,175,179,52,244,84,197,105,112,43,252,115,186,76,237,251,88,5,62,201,157,9,7,153,100,224,202,249,250,183,125,248,160,14,229,239,45,75,116,39,109,41,89,200,43,18,94,204,133,62,175,23,200,68,93,170,95,36,226,233,183,66,98,37,184,160,6,197,49,201,57,39,248,81,26,196,11,167,230,243,100,223,97,38,20,1,226,39,180,161,172,204,67,80,173,223,89,42,160,3,131,195,206,124,22,207,14,142,91,216,135,77,202,69,1,53,115,223,85,52,95,43,227,237,82,138,95,93,70,227,232,160,98,109,64,32,201,140,205,221,164,1,209,57,84,209,249,108,87,101,70,12,37,160,114,139,27,145,104,130,62,183,150,108,160,69,221,169,92,165,83,34,53,123,93,55,127,206,167,112,175,13,233,196,118,68,137,156,246,219,49,159,137,25,37,30,157,160,39,24,29,240,236,191,237,195,74,255,251,61,19,232,218,181,111,83,69,125,70,208,135,182,81,0,125,85,38,21,25,11,160,191,249,76,252,217,172,58,95,133,138,144,243,9,87,191,253,23,150,215,186,153,214,27,17,128,10,154,202,202,43,193,173,160,238,147,22,82,116,71,41,238,84,0,62,40,0,153,205,90,194,234,61,255,205,197,55,0,41,239,197,174,219,163,6,130,160,22,99,129,222,131,163,115,40,32,94,210,97,181,141,77,173,9,184,214,164,50,44,139,113,241,255,7,213,43,8,145,41,128,5],[249,2,17,160,215,178,43,142,72,221,147,48,230,157,99,126,109,240,144,184,54,167,1,19,157,71,126,226,97,100,220,221,118,5,202,114,160,195,19,38,251,242,179,135,46,118,82,177,213,78,156,167,171,134,95,6,233,153,168,219,176,131,34,215,213,95,252,168,165,160,242,119,75,182,209,50,158,172,168,239,218,202,172,144,155,94,44,154,149,92,253,83,150,12,4,176,33,46,25,36,170,225,160,156,18,160,254,15,159,132,100,9,112,178,98,98,93,76,54,189,166,63,219,45,193,25,238,218,78,235,150,206,67,252,253,160,100,75,99,34,122,170,85,172,143,62,172,142,154,219,40,105,162,136,113,194,41,38,129,211,105,114,94,62,145,244,97,170,160,229,94,177,9,226,34,180,156,33,249,119,163,74,194,218,172,92,90,13,44,22,231,5,100,72,203,19,192,62,46,34,34,160,15,175,179,52,244,84,197,105,112,43,252,115,186,76,237,251,88,5,62,201,157,9,7,153,100,224,202,249,250,183,125,248,160,14,229,239,45,75,116,39,109,41,89,200,43,18,94,204,133,62,175,23,200,68,93,170,95,36,226,233,183,66,98,37,184,160,6,197,49,201,57,39,248,81,26,196,11,167,230,243,100,223,97,38,20,1,226,39,180,161,172,204,67,80,173,223,89,42,160,3,131,195,206,124,22,207,14,142,91,216,135,77,202,69,1,53,115,223,85,52,95,43,227,237,82,138,95,93,70,227,232,160,98,109,64,32,201,140,205,221,164,1,209,57,84,209,249,108,87,101,70,12,37,160,114,139,27,145,104,130,62,183,150,108,160,69,221,169,92,165,83,34,53,123,93,55,127,206,167,112,175,13,233,196,118,68,137,156,246,219,49,159,137,25,37,30,157,160,39,24,29,240,236,191,237,195,74,255,251,61,19,232,218,181,111,83,69,125,70,208,135,182,81,0,125,85,38,21,25,11,160,191,249,76,252,217,172,58,95,133,138,144,243,9,87,191,253,23,150,215,186,153,214,27,17,128,10,154,202,202,43,193,173,160,238,147,22,82,116,71,41,238,84,0,62,40,0,153,205,90,194,234,61,255,205,197,55,0,41,239,197,174,219,163,6,130,160,245,44,16,35,247,198,201,190,127,121,84,12,180,160,45,116,180,243,5,121,76,186,165,227,121,49,165,118,171,248,179,191,128,5],[249,2,17,160,62,81,246,216,50,34,109,164,244,230,118,34,30,57,143,168,201,163,53,157,138,200,83,22,217,54,9,12,142,74,113,119,160,110,58,129,42,7,242,95,48,22,117,24,235,247,115,27,159,148,240,189,82,238,245,24,104,4,88,96,153,87,62,124,87,160,23,125,132,126,57,77,125,108,183,122,223,20,200,11,140,116,8,197,125,77,164,229,34,187,130,255,11,5,123,106,18,226,160,34,142,142,168,173,99,151,78,20,223,49,167,173,193,155,22,185,57,77,94,140,81,219,8,205,119,152,79,221,53,32,207,160,47,68,110,156,219,87,42,252,153,153,146,44,71,68,241,42,115,255,196,172,147,166,193,209,18,197,101,149,78,252,80,101,160,177,72,39,32,231,101,153,80,19,87,43,118,153,180,111,107,120,208,26,121,107,122,223,78,248,252,112,146,129,121,183,249,160,166,43,253,9,132,156,69,206,240,132,245,215,140,18,136,28,76,115,232,35,55,46,97,106,111,29,136,215,243,244,104,17,160,81,197,227,235,119,136,89,180,1,44,243,14,3,35,252,32,39,239,6,187,20,67,5,160,124,3,15,223,92,185,169,242,160,149,116,118,68,110,184,206,46,175,107,154,14,16,171,116,53,96,139,243,244,119,49,149,255,105,200,203,196,178,219,6,82,160,110,155,225,108,252,161,111,115,34,161,168,254,20,210,73,55,53,84,44,62,235,227,145,125,56,152,100,115,68,140,102,72,160,215,32,96,214,100,112,201,119,187,39,102,186,145,221,83,195,0,96,163,123,49,150,62,117,25,68,3,71,226,217,71,5,160,216,77,122,185,166,60,76,175,212,143,31,218,53,223,132,60,243,170,247,163,51,217,81,184,10,173,42,95,228,91,232,94,160,102,201,63,187,90,100,67,28,66,169,235,107,142,189,159,208,34,47,59,148,229,29,242,190,206,105,91,103,217,108,220,3,160,130,214,88,212,94,182,185,119,29,142,174,223,89,224,222,59,117,224,157,226,110,51,196,90,175,27,158,67,104,153,87,154,160,32,215,128,174,120,163,233,16,26,195,200,23,79,233,122,253,170,114,110,149,85,164,70,233,70,156,107,147,254,209,174,11,160,193,92,89,242,135,228,231,76,186,23,253,187,202,250,103,245,131,178,24,164,47,129,106,19,179,50,117,153,14,62,38,242,128,5],[249,2,17,160,62,81,246,216,50,34,109,164,244,230,118,34,30,57,143,168,201,163,53,157,138,200,83,22,217,54,9,12,142,74,113,119,160,110,58,129,42,7,242,95,48,22,117,24,235,247,115,27,159,148,240,189,82,238,245,24,104,4,88,96,153,87,62,124,87,160,23,125,132,126,57,77,125,108,183,122,223,20,200,11,140,116,8,197,125,77,164,229,34,187,130,255,11,5,123,106,18,226,160,34,142,142,168,173,99,151,78,20,223,49,167,173,193,155,22,185,57,77,94,140,81,219,8,205,119,152,79,221,53,32,207,160,47,68,110,156,219,87,42,252,153,153,146,44,71,68,241,42,115,255,196,172,147,166,193,209,18,197,101,149,78,252,80,101,160,177,72,39,32,231,101,153,80,19,87,43,118,153,180,111,107,120,208,26,121,107,122,223,78,248,252,112,146,129,121,183,249,160,166,43,253,9,132,156,69,206,240,132,245,215,140,18,136,28,76,115,232,35,55,46,97,106,111,29,136,215,243,244,104,17,160,81,197,227,235,119,136,89,180,1,44,243,14,3,35,252,32,39,239,6,187,20,67,5,160,124,3,15,223,92,185,169,242,160,149,116,118,68,110,184,206,46,175,107,154,14,16,171,116,53,96,139,243,244,119,49,149,255,105,200,203,196,178,219,6,82,160,110,155,225,108,252,161,111,115,34,161,168,254,20,210,73,55,53,84,44,62,235,227,145,125,56,152,100,115,68,140,102,72,160,215,32,96,214,100,112,201,119,187,39,102,186,145,221,83,195,0,96,163,123,49,150,62,117,25,68,3,71,226,217,71,5,160,216,77,122,185,166,60,76,175,212,143,31,218,53,223,132,60,243,170,247,163,51,217,81,184,10,173,42,95,228,91,232,94,160,215,59,125,216,248,19,201,18,250,183,66,8,213,171,232,118,28,224,37,86,154,26,45,63,50,37,179,78,95,7,56,114,160,130,214,88,212,94,182,185,119,29,142,174,223,89,224,222,59,117,224,157,226,110,51,196,90,175,27,158,67,104,153,87,154,160,32,215,128,174,120,163,233,16,26,195,200,23,79,233,122,253,170,114,110,149,85,164,70,233,70,156,107,147,254,209,174,11,160,193,92,89,242,135,228,231,76,186,23,253,187,202,250,103,245,131,178,24,164,47,129,106,19,179,50,117,153,14,62,38,242,128,5],[249,2,17,160,243,248,117,132,135,179,242,217,170,170,147,202,41,30,49,202,235,19,91,182,154,115,189,49,71,95,213,18,134,202,205,168,160,248,214,27,163,48,89,69,124,39,200,95,223,46,31,254,156,7,133,69,242,252,178,116,213,90,11,24,2,233,210,95,159,160,71,79,93,73,42,149,57,51,225,103,235,189,110,188,70,240,193,23,63,219,116,110,243,110,149,7,153,50,68,75,57,255,160,247,151,249,133,151,231,1,67,135,51,218,198,210,129,152,142,23,144,43,153,113,15,227,167,123,200,117,134,246,144,41,89,160,64,41,80,117,176,86,114,226,155,222,42,78,189,238,210,98,213,168,109,98,43,187,53,78,43,64,239,233,108,49,103,145,160,81,130,213,232,226,141,41,38,167,145,141,254,200,67,223,12,25,155,31,46,162,105,182,222,2,233,159,55,73,58,81,8,160,26,77,61,137,205,196,204,129,210,129,10,70,241,189,76,121,69,162,6,215,188,152,126,170,249,149,72,157,147,95,113,240,160,76,38,106,162,112,134,133,37,202,39,149,12,3,108,165,104,174,60,185,97,253,218,30,38,19,121,89,102,165,245,8,216,160,52,133,159,70,24,244,195,146,2,17,195,222,204,211,129,28,126,50,191,31,4,148,37,228,107,40,143,95,15,239,188,142,160,30,36,232,235,34,123,13,63,36,1,92,189,49,255,191,152,101,81,234,45,170,78,228,224,41,77,6,235,75,41,95,228,160,53,118,183,248,110,40,9,128,63,159,4,146,88,128,57,182,207,231,204,72,18,102,249,225,183,253,26,165,204,221,133,107,160,47,211,121,43,20,152,236,53,207,92,248,102,254,75,207,136,49,232,147,125,59,184,15,14,62,136,58,5,56,132,135,139,160,146,83,193,207,181,29,203,52,47,58,114,231,161,55,66,1,75,127,145,210,118,37,82,232,135,3,183,30,255,240,248,11,160,74,111,171,71,106,196,108,204,154,49,109,206,164,6,195,104,55,35,226,133,78,86,140,154,197,163,105,253,218,72,68,52,160,221,162,147,55,34,170,139,142,218,244,84,132,181,168,39,246,188,198,8,193,144,16,119,237,138,12,69,220,76,152,153,153,160,250,100,42,85,168,208,19,121,181,167,41,37,110,73,50,34,56,59,218,49,242,70,153,106,217,4,105,151,51,36,134,125,128,5],[249,2,17,160,243,248,117,132,135,179,242,217,170,170,147,202,41,30,49,202,235,19,91,182,154,115,189,49,71,95,213,18,134,202,205,168,160,248,214,27,163,48,89,69,124,39,200,95,223,46,31,254,156,7,133,69,242,252,178,116,213,90,11,24,2,233,210,95,159,160,71,79,93,73,42,149,57,51,225,103,235,189,110,188,70,240,193,23,63,219,116,110,243,110,149,7,153,50,68,75,57,255,160,247,151,249,133,151,231,1,67,135,51,218,198,210,129,152,142,23,144,43,153,113,15,227,167,123,200,117,134,246,144,41,89,160,64,41,80,117,176,86,114,226,155,222,42,78,189,238,210,98,213,168,109,98,43,187,53,78,43,64,239,233,108,49,103,145,160,81,130,213,232,226,141,41,38,167,145,141,254,200,67,223,12,25,155,31,46,162,105,182,222,2,233,159,55,73,58,81,8,160,26,77,61,137,205,196,204,129,210,129,10,70,241,189,76,121,69,162,6,215,188,152,126,170,249,149,72,157,147,95,113,240,160,76,38,106,162,112,134,133,37,202,39,149,12,3,108,165,104,174,60,185,97,253,218,30,38,19,121,89,102,165,245,8,216,160,52,133,159,70,24,244,195,146,2,17,195,222,204,211,129,28,126,50,191,31,4,148,37,228,107,40,143,95,15,239,188,142,160,30,36,232,235,34,123,13,63,36,1,92,189,49,255,191,152,101,81,234,45,170,78,228,224,41,77,6,235,75,41,95,228,160,53,118,183,248,110,40,9,128,63,159,4,146,88,128,57,182,207,231,204,72,18,102,249,225,183,253,26,165,204,221,133,107,160,47,211,121,43,20,152,236,53,207,92,248,102,254,75,207,136,49,232,147,125,59,184,15,14,62,136,58,5,56,132,135,139,160,146,83,193,207,181,29,203,52,47,58,114,231,161,55,66,1,75,127,145,210,118,37,82,232,135,3,183,30,255,240,248,11,160,74,111,171,71,106,196,108,204,154,49,109,206,164,6,195,104,55,35,226,133,78,86,140,154,197,163,105,253,218,72,68,52,160,142,150,91,3,151,108,7,234,211,182,207,220,110,244,217,170,240,12,90,203,195,243,210,201,172,9,15,30,76,40,83,183,160,250,100,42,85,168,208,19,121,181,167,41,37,110,73,50,34,56,59,218,49,242,70,153,106,217,4,105,151,51,36,134,125,128,5],[249,2,17,160,161,128,1,12,47,16,128,58,172,109,97,186,101,50,211,24,116,166,152,209,189,185,191,39,125,163,235,50,169,86,158,229,160,43,180,202,90,212,89,144,118,139,227,102,232,30,186,65,236,181,5,130,247,53,26,255,110,32,164,81,96,121,240,13,252,160,222,100,177,157,75,143,240,145,16,36,58,46,51,139,107,7,196,233,64,182,153,253,203,175,129,102,22,111,153,168,150,26,160,94,231,69,12,111,229,77,99,71,17,141,11,41,112,27,177,218,61,40,30,213,193,247,27,173,123,94,162,194,11,64,110,160,148,241,5,249,211,104,221,226,140,197,193,238,210,173,105,8,129,244,154,57,13,253,109,216,177,158,110,36,172,122,110,88,160,49,101,31,195,122,182,161,106,170,190,126,247,114,74,123,53,20,100,9,186,33,38,17,167,168,229,10,220,151,18,196,241,160,73,246,226,153,120,139,128,58,10,194,85,4,186,39,18,220,239,252,50,159,22,196,125,122,103,50,247,196,37,68,58,169,160,15,132,108,63,247,99,185,92,140,54,8,64,230,186,45,30,61,193,8,165,18,74,107,200,87,45,33,232,22,58,219,43,160,171,6,213,180,15,77,228,71,174,54,254,251,111,241,218,40,233,3,107,112,164,163,132,133,85,121,0,128,188,237,176,38,160,190,202,142,180,181,1,250,241,49,215,108,185,216,23,205,142,139,158,85,162,252,156,118,150,43,152,194,183,178,218,159,221,160,116,118,116,254,111,169,77,111,65,32,203,133,193,209,164,92,7,21,222,137,239,153,10,17,202,156,229,253,242,229,50,66,160,245,182,9,212,150,185,219,26,154,17,0,141,168,125,166,152,114,219,87,156,42,77,206,233,29,211,176,18,46,29,86,118,160,125,173,37,34,63,10,10,105,35,138,170,159,170,58,203,218,96,174,159,130,118,216,137,144,59,203,221,237,109,28,197,14,160,125,205,12,44,38,14,115,188,176,89,248,149,162,236,64,246,24,91,125,70,183,125,37,100,214,54,174,74,207,71,185,190,160,9,167,144,133,57,89,194,210,118,41,249,242,60,234,105,179,15,125,163,86,11,161,61,242,89,222,67,163,239,141,115,22,160,229,254,113,96,76,247,87,54,147,166,26,241,48,108,149,89,115,6,35,119,201,191,233,239,90,99,195,93,22,222,43,126,128,5],[249,2,17,160,161,128,1,12,47,16,128,58,172,109,97,186,101,50,211,24,116,166,152,209,189,185,191,39,125,163,235,50,169,86,158,229,160,43,180,202,90,212,89,144,118,139,227,102,232,30,186,65,236,181,5,130,247,53,26,255,110,32,164,81,96,121,240,13,252,160,222,100,177,157,75,143,240,145,16,36,58,46,51,139,107,7,196,233,64,182,153,253,203,175,129,102,22,111,153,168,150,26,160,94,231,69,12,111,229,77,99,71,17,141,11,41,112,27,177,218,61,40,30,213,193,247,27,173,123,94,162,194,11,64,110,160,148,241,5,249,211,104,221,226,140,197,193,238,210,173,105,8,129,244,154,57,13,253,109,216,177,158,110,36,172,122,110,88,160,49,101,31,195,122,182,161,106,170,190,126,247,114,74,123,53,20,100,9,186,33,38,17,167,168,229,10,220,151,18,196,241,160,73,246,226,153,120,139,128,58,10,194,85,4,186,39,18,220,239,252,50,159,22,196,125,122,103,50,247,196,37,68,58,169,160,15,132,108,63,247,99,185,92,140,54,8,64,230,186,45,30,61,193,8,165,18,74,107,200,87,45,33,232,22,58,219,43,160,171,6,213,180,15,77,228,71,174,54,254,251,111,241,218,40,233,3,107,112,164,163,132,133,85,121,0,128,188,237,176,38,160,190,202,142,180,181,1,250,241,49,215,108,185,216,23,205,142,139,158,85,162,252,156,118,150,43,152,194,183,178,218,159,221,160,116,118,116,254,111,169,77,111,65,32,203,133,193,209,164,92,7,21,222,137,239,153,10,17,202,156,229,253,242,229,50,66,160,245,182,9,212,150,185,219,26,154,17,0,141,168,125,166,152,114,219,87,156,42,77,206,233,29,211,176,18,46,29,86,118,160,125,173,37,34,63,10,10,105,35,138,170,159,170,58,203,218,96,174,159,130,118,216,137,144,59,203,221,237,109,28,197,14,160,77,232,92,90,207,144,28,209,255,114,73,30,34,22,65,146,193,168,52,246,172,111,139,107,21,220,140,195,72,109,174,142,160,9,167,144,133,57,89,194,210,118,41,249,242,60,234,105,179,15,125,163,86,11,161,61,242,89,222,67,163,239,141,115,22,160,229,254,113,96,76,247,87,54,147,166,26,241,48,108,149,89,115,6,35,119,201,191,233,239,90,99,195,93,22,222,43,126,128,5],[249,2,17,160,1,140,240,73,75,204,201,222,156,243,213,94,33,163,61,8,206,249,37,116,57,74,97,38,98,157,136,8,8,58,80,150,160,195,199,196,181,116,185,85,110,248,215,152,211,207,168,41,60,203,5,86,141,59,163,78,219,9,213,111,185,55,120,19,233,160,140,202,218,220,242,107,140,113,118,132,7,69,53,214,70,230,137,184,171,129,43,48,107,81,80,73,247,0,177,229,219,121,160,33,36,191,50,11,87,222,33,182,77,167,63,136,123,248,241,74,182,24,11,174,247,239,125,99,202,207,255,128,35,52,165,160,149,249,75,250,81,105,43,241,150,173,198,3,252,180,149,96,0,111,180,34,118,196,43,123,93,132,160,96,250,100,217,45,160,32,39,96,173,133,195,109,50,97,77,73,185,128,89,4,150,255,132,58,164,43,120,193,117,186,32,133,65,91,116,162,173,160,98,239,63,98,146,213,134,176,5,254,159,193,14,251,162,124,237,62,243,94,97,73,108,47,3,76,184,133,162,93,214,124,160,24,110,66,31,239,73,37,228,27,69,165,214,234,132,223,109,118,39,20,166,141,25,228,24,156,85,122,60,112,195,235,154,160,124,4,254,255,41,243,241,33,206,19,170,136,141,252,149,202,221,147,172,85,213,237,197,110,71,174,111,101,127,85,205,59,160,23,49,65,202,234,196,28,65,205,115,198,37,246,143,124,72,166,37,205,232,162,25,22,39,127,188,14,26,18,214,240,152,160,51,21,215,92,255,202,104,15,118,167,53,140,39,4,142,82,127,133,147,230,204,253,47,54,99,23,226,78,113,129,89,185,160,239,123,251,65,188,11,107,22,9,46,42,104,47,193,60,78,205,118,242,12,136,145,137,46,214,157,184,26,255,37,206,38,160,179,163,103,185,250,53,96,32,14,9,248,46,117,61,151,70,245,116,155,44,163,22,115,1,102,242,244,157,45,81,102,14,160,120,51,181,75,204,140,26,229,78,145,104,6,122,193,149,189,178,100,84,118,214,32,148,10,91,248,41,39,153,51,148,250,160,152,64,28,199,229,115,92,129,39,229,199,166,105,168,252,23,227,109,56,225,3,255,171,233,92,155,115,43,225,156,231,35,160,79,205,115,234,146,184,235,250,60,154,252,244,30,28,214,37,12,114,43,159,140,167,245,162,159,65,188,1,113,43,38,143,128,5],[249,2,17,160,1,140,240,73,75,204,201,222,156,243,213,94,33,163,61,8,206,249,37,116,57,74,97,38,98,157,136,8,8,58,80,150,160,195,199,196,181,116,185,85,110,248,215,152,211,207,168,41,60,203,5,86,141,59,163,78,219,9,213,111,185,55,120,19,233,160,140,202,218,220,242,107,140,113,118,132,7,69,53,214,70,230,137,184,171,129,43,48,107,81,80,73,247,0,177,229,219,121,160,224,226,228,152,49,191,94,18,202,42,40,43,44,135,217,234,139,112,115,185,228,196,213,42,168,79,181,143,79,201,143,96,160,149,249,75,250,81,105,43,241,150,173,198,3,252,180,149,96,0,111,180,34,118,196,43,123,93,132,160,96,250,100,217,45,160,32,39,96,173,133,195,109,50,97,77,73,185,128,89,4,150,255,132,58,164,43,120,193,117,186,32,133,65,91,116,162,173,160,98,239,63,98,146,213,134,176,5,254,159,193,14,251,162,124,237,62,243,94,97,73,108,47,3,76,184,133,162,93,214,124,160,24,110,66,31,239,73,37,228,27,69,165,214,234,132,223,109,118,39,20,166,141,25,228,24,156,85,122,60,112,195,235,154,160,124,4,254,255,41,243,241,33,206,19,170,136,141,252,149,202,221,147,172,85,213,237,197,110,71,174,111,101,127,85,205,59,160,23,49,65,202,234,196,28,65,205,115,198,37,246,143,124,72,166,37,205,232,162,25,22,39,127,188,14,26,18,214,240,152,160,51,21,215,92,255,202,104,15,118,167,53,140,39,4,142,82,127,133,147,230,204,253,47,54,99,23,226,78,113,129,89,185,160,239,123,251,65,188,11,107,22,9,46,42,104,47,193,60,78,205,118,242,12,136,145,137,46,214,157,184,26,255,37,206,38,160,179,163,103,185,250,53,96,32,14,9,248,46,117,61,151,70,245,116,155,44,163,22,115,1,102,242,244,157,45,81,102,14,160,120,51,181,75,204,140,26,229,78,145,104,6,122,193,149,189,178,100,84,118,214,32,148,10,91,248,41,39,153,51,148,250,160,152,64,28,199,229,115,92,129,39,229,199,166,105,168,252,23,227,109,56,225,3,255,171,233,92,155,115,43,225,156,231,35,160,79,205,115,234,146,184,235,250,60,154,252,244,30,28,214,37,12,114,43,159,140,167,245,162,159,65,188,1,113,43,38,143,128,5],[249,2,17,160,245,105,73,55,130,156,85,160,31,141,126,218,15,74,121,147,147,14,234,12,31,2,207,74,132,213,9,173,180,149,183,107,160,221,130,180,81,176,155,200,100,168,4,254,92,101,171,36,147,95,202,31,177,191,39,28,78,15,253,236,77,124,115,149,137,160,8,37,3,52,123,198,42,148,211,79,179,98,105,89,161,130,151,2,137,5,198,34,114,85,180,47,176,126,179,111,60,206,160,232,217,161,8,22,169,40,66,131,228,203,23,191,255,11,201,101,138,145,67,49,60,150,125,179,56,59,152,181,26,174,138,160,52,5,132,223,20,125,125,152,77,21,29,239,159,211,65,174,156,121,107,233,188,67,44,242,54,70,100,18,159,243,207,206,160,224,250,15,5,72,187,58,246,78,193,251,188,67,94,94,63,151,23,215,194,99,44,14,23,45,34,254,220,3,94,41,58,160,6,105,60,12,5,193,169,245,176,112,146,23,69,42,0,33,177,13,230,213,165,102,152,203,58,175,135,4,16,128,172,8,160,151,152,86,204,166,248,67,223,250,77,31,100,237,11,43,191,90,23,20,54,199,92,11,215,145,50,87,90,167,159,57,165,160,1,232,26,222,47,23,75,176,90,187,251,204,93,173,132,158,36,225,142,226,147,28,202,173,168,228,182,229,123,127,49,117,160,247,78,159,238,239,170,53,113,45,18,48,98,112,234,117,104,97,108,138,230,14,76,168,84,236,172,64,67,208,57,6,73,160,46,68,248,146,220,227,97,0,41,252,210,9,44,117,251,227,165,196,13,189,174,150,34,139,203,17,200,40,245,122,167,206,160,26,216,79,208,48,103,203,251,178,213,93,58,82,104,200,119,234,228,233,252,208,91,195,35,224,229,183,69,89,175,14,229,160,246,209,205,0,213,119,26,186,142,93,94,61,153,28,165,149,49,176,155,119,213,241,208,245,15,163,38,131,125,219,108,170,160,89,143,190,130,47,255,40,170,85,219,138,46,139,251,126,68,17,241,5,216,204,86,127,71,120,116,170,149,237,137,28,227,160,79,246,250,96,218,39,3,222,92,140,84,169,44,51,184,140,136,139,201,154,119,208,207,98,29,112,62,108,254,3,142,180,160,130,179,74,86,218,213,192,18,132,24,134,63,237,50,86,187,20,97,174,221,173,83,84,97,186,105,52,78,209,101,251,138,128,5],[249,2,17,160,245,105,73,55,130,156,85,160,31,141,126,218,15,74,121,147,147,14,234,12,31,2,207,74,132,213,9,173,180,149,183,107,160,221,130,180,81,176,155,200,100,168,4,254,92,101,171,36,147,95,202,31,177,191,39,28,78,15,253,236,77,124,115,149,137,160,8,37,3,52,123,198,42,148,211,79,179,98,105,89,161,130,151,2,137,5,198,34,114,85,180,47,176,126,179,111,60,206,160,232,217,161,8,22,169,40,66,131,228,203,23,191,255,11,201,101,138,145,67,49,60,150,125,179,56,59,152,181,26,174,138,160,46,144,237,143,190,109,159,205,233,64,197,103,36,172,203,35,39,122,25,184,212,193,136,197,175,120,207,44,140,182,105,222,160,224,250,15,5,72,187,58,246,78,193,251,188,67,94,94,63,151,23,215,194,99,44,14,23,45,34,254,220,3,94,41,58,160,6,105,60,12,5,193,169,245,176,112,146,23,69,42,0,33,177,13,230,213,165,102,152,203,58,175,135,4,16,128,172,8,160,151,152,86,204,166,248,67,223,250,77,31,100,237,11,43,191,90,23,20,54,199,92,11,215,145,50,87,90,167,159,57,165,160,1,232,26,222,47,23,75,176,90,187,251,204,93,173,132,158,36,225,142,226,147,28,202,173,168,228,182,229,123,127,49,117,160,247,78,159,238,239,170,53,113,45,18,48,98,112,234,117,104,97,108,138,230,14,76,168,84,236,172,64,67,208,57,6,73,160,46,68,248,146,220,227,97,0,41,252,210,9,44,117,251,227,165,196,13,189,174,150,34,139,203,17,200,40,245,122,167,206,160,26,216,79,208,48,103,203,251,178,213,93,58,82,104,200,119,234,228,233,252,208,91,195,35,224,229,183,69,89,175,14,229,160,246,209,205,0,213,119,26,186,142,93,94,61,153,28,165,149,49,176,155,119,213,241,208,245,15,163,38,131,125,219,108,170,160,89,143,190,130,47,255,40,170,85,219,138,46,139,251,126,68,17,241,5,216,204,86,127,71,120,116,170,149,237,137,28,227,160,79,246,250,96,218,39,3,222,92,140,84,169,44,51,184,140,136,139,201,154,119,208,207,98,29,112,62,108,254,3,142,180,160,130,179,74,86,218,213,192,18,132,24,134,63,237,50,86,187,20,97,174,221,173,83,84,97,186,105,52,78,209,101,251,138,128,5],[248,241,160,255,151,217,75,103,5,122,115,224,137,233,146,50,189,95,178,178,247,44,237,22,101,231,39,198,40,14,249,60,251,151,15,128,128,128,128,160,60,79,85,51,115,192,158,157,93,223,211,100,62,94,72,146,251,82,116,111,190,139,246,12,252,146,211,122,66,110,206,20,128,160,120,190,160,200,253,109,255,226,49,189,87,112,136,160,23,77,119,59,173,185,188,145,251,156,155,144,100,217,100,114,109,106,128,160,69,72,113,186,79,146,63,86,46,218,1,200,131,76,71,142,217,35,30,209,101,239,91,47,163,221,136,130,249,155,236,112,160,49,65,26,94,193,156,227,78,42,198,56,211,105,254,0,33,31,96,41,208,40,13,215,156,51,173,132,112,34,192,121,49,160,244,154,252,18,232,96,245,36,84,15,253,182,157,226,247,165,106,144,166,1,2,140,228,170,110,87,112,80,140,149,162,43,128,160,20,103,6,95,163,140,21,238,207,84,226,60,134,0,183,217,11,213,185,123,139,201,37,22,227,234,220,30,160,20,244,115,128,128,128,5],[248,241,160,188,253,144,87,144,251,204,78,148,203,12,141,0,77,176,70,67,92,90,100,110,40,255,28,218,97,116,184,26,121,18,49,128,128,128,128,160,60,79,85,51,115,192,158,157,93,223,211,100,62,94,72,146,251,82,116,111,190,139,246,12,252,146,211,122,66,110,206,20,128,160,120,190,160,200,253,109,255,226,49,189,87,112,136,160,23,77,119,59,173,185,188,145,251,156,155,144,100,217,100,114,109,106,128,160,69,72,113,186,79,146,63,86,46,218,1,200,131,76,71,142,217,35,30,209,101,239,91,47,163,221,136,130,249,155,236,112,160,49,65,26,94,193,156,227,78,42,198,56,211,105,254,0,33,31,96,41,208,40,13,215,156,51,173,132,112,34,192,121,49,160,244,154,252,18,232,96,245,36,84,15,253,182,157,226,247,165,106,144,166,1,2,140,228,170,110,87,112,80,140,149,162,43,128,160,20,103,6,95,163,140,21,238,207,84,226,60,134,0,183,217,11,213,185,123,139,201,37,22,227,234,220,30,160,20,244,115,128,128,128,5],[248,81,128,128,128,128,128,128,128,160,222,45,71,217,199,68,20,55,244,206,68,197,49,191,78,208,106,209,111,87,254,9,221,230,148,86,131,219,7,121,62,140,160,190,214,56,80,83,126,135,17,104,48,181,30,249,223,80,59,155,70,206,67,24,6,82,98,81,246,212,143,253,181,15,180,128,128,128,128,128,128,128,128,5],[248,102,157,55,236,125,29,155,142,209,241,75,145,144,143,254,65,81,209,56,13,192,157,236,195,213,73,132,11,251,149,241,184,70,248,68,1,128,160,112,158,181,221,162,20,124,79,184,25,162,13,167,162,146,25,237,242,59,120,184,154,118,137,92,181,187,152,115,82,223,48,160,7,190,1,231,231,32,111,227,30,206,233,26,215,93,173,166,90,214,186,67,58,230,71,161,185,51,4,105,247,198,103,124,5],[248,102,157,32,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,184,70,248,68,1,23,160,112,158,181,221,162,20,124,79,184,25,162,13,167,162,146,25,237,242,59,120,184,154,118,137,92,181,187,152,115,82,223,48,160,7,190,1,231,231,32,111,227,30,206,233,26,215,93,173,166,90,214,186,67,58,230,71,161,185,51,4,105,247,198,103,124,5],[248,102,157,32,236,125,29,155,142,209,241,75,145,144,143,254,65,81,209,56,13,192,157,236,195,213,73,132,11,251,149,241,184,70,248,68,1,128,160,112,158,181,221,162,20,124,79,184,25,162,13,167,162,146,25,237,242,59,120,184,154,118,137,92,181,187,152,115,82,223,48,160,7,190,1,231,231,32,111,227,30,206,233,26,215,93,173,166,90,214,186,67,58,230,71,161,185,51,4,105,247,198,103,124,5],[248,102,157,32,236,125,29,155,142,209,241,75,145,144,143,254,65,81,209,56,13,192,157,236,195,213,73,132,11,251,149,241,184,70,248,68,1,128,160,112,158,181,221,162,20,124,79,184,25,162,13,167,162,146,25,237,242,59,120,184,154,118,137,92,181,187,152,115,82,223,48,160,7,190,1,231,231,32,111,227,30,206,233,26,215,93,173,166,90,214,186,67,58,230,71,161,185,51,4,105,247,198,103,124,5]]"; + let w: Vec> = serde_json::from_str(wit).unwrap(); + + let count = w.iter().filter(|r| r[r.len() - 1] != 5).count() * 2; + let randomness: Fr = 123456789.scalar(); + let instance: Vec> = (1..HASH_WIDTH + 1) + .map(|exp| vec![randomness.pow(&[exp as u64, 0, 0, 0]); count]) + .collect(); + + let circuit = MPTCircuit:: { + witness: w.clone(), + randomness, + }; + + // let prover = MockProver::run(9, &circuit, vec![pub_root]).unwrap(); + let num_rows = w.len() * 2; + let prover = MockProver::run(14 /* 9 */, &circuit, instance).unwrap(); + assert_eq!(prover.verify_at_rows(0..num_rows, 0..num_rows,), Ok(())); + //assert_eq!(prover.verify_par(), Ok(())); + //prover.assert_satisfied(); + + + } } diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf.rs b/zkevm-circuits/src/mpt_circuit/account_leaf.rs index f0dab2a37b..2e8a3ae0a7 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf.rs @@ -27,7 +27,7 @@ use crate::{ param::{KEY_LEN_IN_NIBBLES, RLP_LIST_LONG, RLP_LONG}, FixedTableTag, }, - mpt_circuit::{MPTConfig, MPTState}, + mpt_circuit::{MPTConfig, MPTState}, evm_circuit::util::CachedRegion, }; use crate::{ circuit_tools::constraint_builder::RLCChainable, @@ -645,4 +645,257 @@ impl AccountLeafConfig { Ok(()) } + + pub fn assign_cached( + &self, + region: &mut CachedRegion, + ctx: &MPTConfig, + pv: &mut MPTState, + offset: usize, + node: &Node, + ) -> Result<(), Error> { + let account = &node.account.clone().unwrap(); + + let key_bytes = [ + node.values[AccountRowType::KeyS as usize].clone(), + node.values[AccountRowType::KeyC as usize].clone(), + ]; + let nonce_bytes = [ + node.values[AccountRowType::NonceS as usize].clone(), + node.values[AccountRowType::NonceC as usize].clone(), + ]; + let balance_bytes = [ + node.values[AccountRowType::BalanceS as usize].clone(), + node.values[AccountRowType::BalanceC as usize].clone(), + ]; + let storage_bytes = [ + node.values[AccountRowType::StorageS as usize].clone(), + node.values[AccountRowType::StorageC as usize].clone(), + ]; + let codehash_bytes = [ + node.values[AccountRowType::CodehashS as usize].clone(), + node.values[AccountRowType::CodehashC as usize].clone(), + ]; + let drifted_bytes = node.values[AccountRowType::Drifted as usize].clone(); + let wrong_bytes = node.values[AccountRowType::Wrong as usize].clone(); + + let main_data = + self.main_data + .witness_load_cached(region, offset, &pv.memory[main_memory()], 0)?; + + // Key + let mut key_rlc = vec![0.scalar(); 2]; + let mut nonce_rlc = vec![0.scalar(); 2]; + let mut balance_rlc = vec![0.scalar(); 2]; + let mut storage_rlc = vec![0.scalar(); 2]; + let mut codehash_rlc = vec![0.scalar(); 2]; + let mut key_data = vec![KeyDataWitness::default(); 2]; + let mut parent_data = vec![ParentDataWitness::default(); 2]; + for is_s in [true, false] { + for (cell, byte) in self.value_rlp_bytes[is_s.idx()] + .iter() + .zip(account.value_rlp_bytes[is_s.idx()].iter()) + { + cell.assign_cached(region, offset, byte.scalar())?; + } + + key_data[is_s.idx()] = self.key_data[is_s.idx()].witness_load_cached( + region, + offset, + &mut pv.memory[key_memory(is_s)], + 0, + )?; + + parent_data[is_s.idx()] = self.parent_data[is_s.idx()].witness_load_cached( + region, + offset, + &mut pv.memory[parent_memory(is_s)], + 0, + )?; + + self.is_in_empty_trie[is_s.idx()].assign_cached( + region, + offset, + parent_data[is_s.idx()].rlc, + ctx.r, + )?; + + let rlp_key_witness = self.rlp_key[is_s.idx()].assign_cached( + region, + offset, + &account.list_rlp_bytes[is_s.idx()], + &key_bytes[is_s.idx()], + )?; + let nonce_witness = + self.rlp_nonce[is_s.idx()].assign_cached(region, offset, &nonce_bytes[is_s.idx()])?; + let balance_witness = + self.rlp_balance[is_s.idx()].assign_cached(region, offset, &balance_bytes[is_s.idx()])?; + let storage_witness = + self.rlp_storage[is_s.idx()].assign_cached(region, offset, &storage_bytes[is_s.idx()])?; + let codehash_witness = self.rlp_codehash[is_s.idx()].assign_cached( + region, + offset, + &codehash_bytes[is_s.idx()], + )?; + + nonce_rlc[is_s.idx()] = nonce_witness.rlc_value(ctx.r); + balance_rlc[is_s.idx()] = balance_witness.rlc_value(ctx.r); + storage_rlc[is_s.idx()] = storage_witness.rlc_value(ctx.r); + codehash_rlc[is_s.idx()] = codehash_witness.rlc_value(ctx.r); + + // + 4 because of s_rlp1, s_rlp2, c_rlp1, c_rlp2 + let mut mult_nonce = F::one(); + for _ in 0..nonce_witness.num_bytes() + 4 { + mult_nonce *= ctx.r; + } + let mut mult_balance = F::one(); + for _ in 0..balance_witness.num_bytes() { + mult_balance *= ctx.r; + } + self.nonce_mult[is_s.idx()].assign_cached(region, offset, mult_nonce)?; + self.balance_mult[is_s.idx()].assign_cached(region, offset, mult_balance)?; + + // Key + (key_rlc[is_s.idx()], _) = rlp_key_witness.key.key( + rlp_key_witness.key_value.clone(), + key_data[is_s.idx()].rlc, + key_data[is_s.idx()].mult, + ctx.r, + ); + + let mut key_mult = F::one(); + for _ in 0..rlp_key_witness.num_bytes_on_key_row() { + key_mult *= ctx.r; + } + self.key_mult[is_s.idx()].assign_cached(region, offset, key_mult)?; + + // Update key and parent state + KeyData::witness_store_cached( + region, + offset, + &mut pv.memory[key_memory(is_s)], + F::zero(), + F::one(), + 0, + false, + F::zero(), + F::one(), + )?; + ParentData::witness_store_cached( + region, + offset, + &mut pv.memory[parent_memory(is_s)], + storage_rlc[is_s.idx()], + true, + false, + storage_rlc[is_s.idx()], + )?; + } + + // Anything following this node is below the account + MainData::witness_store_cached( + region, + offset, + &mut pv.memory[main_memory()], + main_data.proof_type, + true, + account.address.rlc_value(ctx.r), + main_data.root_prev, + main_data.root, + )?; + + // Proof types + let is_non_existing_proof = self.is_non_existing_account_proof.assign_cached( + region, + offset, + main_data.proof_type.scalar(), + ProofType::AccountDoesNotExist.scalar(), + )? == true.scalar(); + let is_account_delete_mod = self.is_account_delete_mod.assign_cached( + region, + offset, + main_data.proof_type.scalar(), + ProofType::AccountDestructed.scalar(), + )? == true.scalar(); + let is_nonce_mod = self.is_nonce_mod.assign_cached( + region, + offset, + main_data.proof_type.scalar(), + ProofType::NonceChanged.scalar(), + )? == true.scalar(); + let is_balance_mod = self.is_balance_mod.assign_cached( + region, + offset, + main_data.proof_type.scalar(), + ProofType::BalanceChanged.scalar(), + )? == true.scalar(); + let is_storage_mod = self.is_storage_mod.assign_cached( + region, + offset, + main_data.proof_type.scalar(), + ProofType::StorageChanged.scalar(), + )? == true.scalar(); + let is_codehash_mod = self.is_codehash_mod.assign_cached( + region, + offset, + main_data.proof_type.scalar(), + ProofType::CodeHashExists.scalar(), + )? == true.scalar(); + + // Drifted leaf handling + self.drifted.assign_cached( + region, + offset, + &parent_data, + &account.drifted_rlp_bytes, + &drifted_bytes, + ctx.r, + )?; + + // Wrong leaf handling + self.wrong.assign_cached( + region, + offset, + is_non_existing_proof, + &key_rlc, + &account.wrong_rlp_bytes, + &wrong_bytes, + true, + key_data[true.idx()].clone(), + ctx.r, + )?; + + // Put the data in the lookup table + let (proof_type, value) = if is_nonce_mod { + (ProofType::NonceChanged, nonce_rlc) + } else if is_balance_mod { + (ProofType::BalanceChanged, balance_rlc) + } else if is_storage_mod { + (ProofType::StorageChanged, storage_rlc) + } else if is_codehash_mod { + (ProofType::CodeHashExists, codehash_rlc) + } else if is_account_delete_mod { + (ProofType::AccountDestructed, vec![0.scalar(); 2]) + } else if is_non_existing_proof { + (ProofType::AccountDoesNotExist, vec![0.scalar(); 2]) + } else { + (ProofType::Disabled, vec![0.scalar(); 2]) + }; + ctx.mpt_table.assign_cached( + region, + offset, + &MptUpdateRow { + address_rlc: account.address.rlc_value(ctx.r), + proof_type: proof_type.scalar(), + key_rlc: 0.scalar(), + value_prev: value[true.idx()], + value: value[false.idx()], + root_prev: main_data.root_prev, + root: main_data.root, + }, + )?; + + Ok(()) + } + } diff --git a/zkevm-circuits/src/mpt_circuit/branch.rs b/zkevm-circuits/src/mpt_circuit/branch.rs index 5ff3904025..8287f0f63d 100644 --- a/zkevm-circuits/src/mpt_circuit/branch.rs +++ b/zkevm-circuits/src/mpt_circuit/branch.rs @@ -23,6 +23,7 @@ use crate::{ mpt_circuit::{helpers::Indexable, param::RLP_NIL, FixedTableTag}, mpt_circuit::{MPTConfig, MPTState}, }; +use crate::evm_circuit::util::CachedRegion; #[derive(Clone, Debug)] pub(crate) struct BranchState { @@ -428,4 +429,128 @@ impl BranchGadget { mod_node_hash_rlc, )) } + + pub(crate) fn assign_cached( + &self, + region: &mut CachedRegion, + mpt_config: &MPTConfig, + _pv: &mut MPTState, + offset: usize, + is_placeholder: &[bool; 2], + key_rlc: &mut F, + key_mult: &mut F, + num_nibbles: &mut usize, + is_key_odd: &mut bool, + node: &Node, + ) -> Result<(F, F, F, [F; 2]), Error> { + let branch = &node.extension_branch.clone().unwrap().branch; + + // Data + let child_bytes: [Vec; ARITY + 1] = array_init::array_init(|i| node.values[i].clone()); + + for is_s in [true, false] { + let rlp_list_witness = self.rlp_list[is_s.idx()].assign_cached( + region, + offset, + &branch.list_rlp_bytes[is_s.idx()], + )?; + self.is_not_hashed[is_s.idx()].assign_cached( + region, + offset, + rlp_list_witness.num_bytes().scalar(), + HASH_WIDTH.scalar(), + )?; + } + + for node_index in 0..ARITY { + self.is_modified[node_index].assign_cached( + region, + offset, + (node_index == branch.modified_index).scalar(), + )?; + self.is_drifted[node_index].assign_cached( + region, + offset, + (node_index == branch.drifted_index).scalar(), + )?; + } + + // Process the branch children + let mut child_witnesses = vec![RLPItemWitness::default(); ARITY + 1]; + for node_index in 0..ARITY + 1 { + let child_witness = + self.children[node_index] + .rlp + .assign_cached(region, offset, &child_bytes[node_index])?; + child_witnesses[node_index] = child_witness.clone(); + + let mut node_mult_diff = F::one(); + for _ in 0..child_witness.num_bytes() { + node_mult_diff *= mpt_config.r; + } + + self.children[node_index] + .mult_diff + .assign_cached(region, offset, node_mult_diff)?; + self.children[node_index].rlc_branch.assign_cached( + region, + offset, + child_witness.rlc_branch(mpt_config.r), + )?; + self.children[node_index].rlc_rlp.assign_cached( + region, + offset, + child_witness.rlc_rlp(mpt_config.r), + )?; + let _is_hashed = self.children[node_index].is_hashed.assign_cached( + region, + offset, + child_witness.len().scalar(), + 32.scalar(), + )?; + } + + // one nibble is used for position in branch + *num_nibbles += 1; + // Update key parity + *is_key_odd = !*is_key_odd; + + // Update the key RLC and multiplier for the branch nibble. + let (nibble_mult, mult): (F, F) = if *is_key_odd { + // The nibble will be added as the most significant nibble using the same + // multiplier + (16.scalar(), 1.scalar()) + } else { + // The nibble will be added as the least significant nibble, the multiplier + // needs to advance + (1.scalar(), mpt_config.r) + }; + let key_rlc_post_branch = + *key_rlc + F::from(branch.modified_index as u64) * nibble_mult * *key_mult; + let key_rlc_post_drifted = + *key_rlc + F::from(branch.drifted_index as u64) * nibble_mult * *key_mult; + let key_mult_post_branch = *key_mult * mult; + + // Set the branch we'll take + let mut mod_node_hash_rlc = [0.scalar(); 2]; + for is_s in [true, false] { + mod_node_hash_rlc[is_s.idx()] = if is_placeholder[is_s.idx()] { + child_witnesses[1 + branch.drifted_index].rlc_branch(mpt_config.r) + } else { + if is_s { + child_witnesses[1 + branch.modified_index].rlc_branch(mpt_config.r) + } else { + child_witnesses[0].rlc_branch(mpt_config.r) + } + }; + self.mod_rlc[is_s.idx()].assign_cached(region, offset, mod_node_hash_rlc[is_s.idx()])?; + } + + Ok(( + key_rlc_post_branch, + key_rlc_post_drifted, + key_mult_post_branch, + mod_node_hash_rlc, + )) + } } diff --git a/zkevm-circuits/src/mpt_circuit/extension.rs b/zkevm-circuits/src/mpt_circuit/extension.rs index 67565f79f3..5169fb8fe0 100644 --- a/zkevm-circuits/src/mpt_circuit/extension.rs +++ b/zkevm-circuits/src/mpt_circuit/extension.rs @@ -21,6 +21,7 @@ use crate::{ }, mpt_circuit::{MPTConfig, MPTState}, }; +use crate::evm_circuit::util::CachedRegion; #[derive(Clone, Debug)] pub(crate) struct ExtState { @@ -71,8 +72,15 @@ impl ExtensionGadget { config.rlp_key = ListKeyGadget::construct(&mut cb.base, &key_bytes[0]); // TODO(Brecht): add lookup constraint - config.is_key_part_odd = cb.base.query_cell(); - + // let is_key_part_odd = key_bytes[0][rlp_key.key_value.num_rlp_bytes()] >> 4 == 1; + config.is_key_part_odd = cb.base.query_byte(); + let odd_flag = matchx! { + config.rlp_key.key_value.is_short() => key_bytes[0][0].expr(), + config.rlp_key.key_value.is_long() => key_bytes[0][1].expr(), + config.rlp_key.key_value.is_very_long() => key_bytes[0][2].expr(), + }; + require!((FixedTableTag::ExtOddKey.expr(), odd_flag, config.is_key_part_odd.expr()) => @"fixed"); + // We need to check that the nibbles we stored in s are between 0 and 15. cb.set_range_s(FixedTableTag::RangeKeyLen16.expr()); @@ -277,4 +285,94 @@ impl ExtensionGadget { Ok(()) } + + pub(crate) fn assign_cached( + &self, + region: &mut CachedRegion, + mpt_config: &MPTConfig, + _pv: &mut MPTState, + offset: usize, + key_data: &KeyDataWitness, + key_rlc: &mut F, + key_mult: &mut F, + num_nibbles: &mut usize, + is_key_odd: &mut bool, + node: &Node, + ) -> Result<(), Error> { + let extension = &node.extension_branch.clone().unwrap().extension; + + // Data + let key_bytes = [ + node.values[ExtensionBranchRowType::KeyS as usize].clone(), + node.values[ExtensionBranchRowType::KeyC as usize].clone(), + ]; + let value_bytes = [ + node.values[ExtensionBranchRowType::ValueS as usize].clone(), + node.values[ExtensionBranchRowType::ValueC as usize].clone(), + ]; + + let rlp_key = self.rlp_key.assign_cached( + region, + offset, + &extension.list_rlp_bytes, + &key_bytes[true.idx()], + )?; + + let mut ext_mult = F::one(); + for _ in 0..rlp_key.num_bytes_on_key_row() { + ext_mult *= mpt_config.r; + } + self.mult.assign_cached(region, offset, ext_mult)?; + + let is_key_part_odd = key_bytes[0][rlp_key.key_value.num_rlp_bytes()] >> 4 == 1; + self.is_key_part_odd + .assign_cached(region, offset, is_key_part_odd.scalar())?; + + self.is_not_hashed.assign_cached( + region, + offset, + rlp_key.rlp_list.num_bytes().scalar(), + HASH_WIDTH.scalar(), + )?; + + let mut key_len_mult = rlp_key.key_value.len(); + if !(*is_key_odd && is_key_part_odd) { + key_len_mult -= 1; + } + + // Update number of nibbles + *num_nibbles += num_nibbles::value(rlp_key.key_value.len(), is_key_part_odd); + + // Update parity + *is_key_odd = if is_key_part_odd { + !*is_key_odd + } else { + *is_key_odd + }; + + // Key RLC + let (key_rlc_ext, _) = ext_key_rlc_calc_value( + rlp_key.key_value.clone(), + key_data.mult, + is_key_part_odd, + !*is_key_odd, + key_bytes.clone(), + mpt_config.r, + ); + *key_rlc = key_data.rlc + key_rlc_ext; + + // Key mult + let mut mult_key = 1.scalar(); + for _ in 0..key_len_mult { + mult_key = mult_key * mpt_config.r; + } + self.mult_key.assign_cached(region, offset, mult_key)?; + *key_mult = key_data.mult * mult_key; + + for is_s in [true, false] { + self.rlp_value[is_s.idx()].assign_cached(region, offset, &value_bytes[is_s.idx()])?; + } + + Ok(()) + } } diff --git a/zkevm-circuits/src/mpt_circuit/extension_branch.rs b/zkevm-circuits/src/mpt_circuit/extension_branch.rs index 9a8460c0ef..4f44e785bd 100644 --- a/zkevm-circuits/src/mpt_circuit/extension_branch.rs +++ b/zkevm-circuits/src/mpt_circuit/extension_branch.rs @@ -2,7 +2,7 @@ use eth_types::Field; use gadgets::util::Scalar; use halo2_proofs::{ circuit::Region, - plonk::{Error, VirtualCells}, + plonk::{Error, VirtualCells}, poly::Rotation, }; use super::{ @@ -20,6 +20,7 @@ use crate::{ mpt_circuit::witness_row::MptWitnessRow, mpt_circuit::{MPTConfig, MPTState}, }; +use crate::evm_circuit::util::CachedRegion; #[derive(Clone, Debug, Default)] pub(crate) struct ExtensionBranchConfig { @@ -39,8 +40,8 @@ impl ExtensionBranchConfig { ) -> Self { cb.base.cell_manager.as_mut().unwrap().reset(); let mut config = ExtensionBranchConfig::default(); - circuit!([meta, cb.base], { + let q_enable = f!(ctx.q_enable); // General inputs config.is_extension = cb.base.query_bool(); // If we're in a placeholder, both the extension and the branch parts are @@ -65,6 +66,8 @@ impl ExtensionBranchConfig { require!(config.parent_data[is_s.idx()].is_placeholder => false); } + + // let cm1, cm2 = cm // Extension let ( num_nibbles, @@ -76,6 +79,7 @@ impl ExtensionBranchConfig { parent_rlc_s, parent_rlc_c, ) = ifx! {config.is_extension => { + //用 cm1 config.extension = ExtensionGadget::configure( meta, cb, @@ -96,6 +100,7 @@ impl ExtensionBranchConfig { ext.branch_rlp_rlc[false.idx()].expr(), ) } elsex { + // 用 cm2 ( config.key_data.num_nibbles.expr(), config.key_data.is_odd.expr(), @@ -107,6 +112,7 @@ impl ExtensionBranchConfig { config.parent_data[false.idx()].rlc.expr(), ) }}; + // cm = 实质上采取的 cmi let parent_rlc = [parent_rlc_s, parent_rlc_c]; let is_root = [is_root_s, is_root_c]; @@ -252,7 +258,7 @@ impl ExtensionBranchConfig { region, offset, &mut pv.memory[key_memory(is_s)], - key_rlc_post_branch, + key_rlc_post_branch, //后面新算的 key_mult_post_branch, num_nibbles, false, @@ -273,8 +279,8 @@ impl ExtensionBranchConfig { region, offset, &mut pv.memory[key_memory(is_s)], - key_data.rlc, - key_data.mult, + key_data.rlc, + key_data.mult, //维持原样,相当于重新入栈 key_data.num_nibbles, is_key_odd, key_rlc_post_drifted, @@ -294,4 +300,121 @@ impl ExtensionBranchConfig { Ok(()) } + + pub(crate) fn assign_cached( + &self, + region: &mut CachedRegion, + mpt_config: &MPTConfig, + pv: &mut MPTState, + offset: usize, + node: &Node, + ) -> Result<(), Error> { + let extension_branch = &node.extension_branch.clone().unwrap(); + + self.is_extension + .assign_cached(region, offset, extension_branch.is_extension.scalar())?; + + let key_data = + self.key_data + .witness_load_cached(region, offset, &pv.memory[key_memory(true)], 0)?; + let mut parent_data = vec![ParentDataWitness::default(); 2]; + for is_s in [true, false] { + parent_data[is_s.idx()] = self.parent_data[is_s.idx()].witness_load_cached( + region, + offset, + &mut pv.memory[parent_memory(is_s)], + 0, + )?; + self.is_placeholder[is_s.idx()].assign_cached( + region, + offset, + extension_branch.is_placeholder[is_s.idx()].scalar(), + )?; + } + + let mut key_rlc = key_data.rlc; + let mut key_mult = key_data.mult; + let mut num_nibbles = key_data.num_nibbles; + let mut is_key_odd = key_data.is_odd; + + // Extension + if extension_branch.is_extension { + self.extension.assign_cached( + region, + mpt_config, + pv, + offset, + &key_data, + &mut key_rlc, + &mut key_mult, + &mut num_nibbles, + &mut is_key_odd, + node, + )?; + } + + // Branch + let (key_rlc_post_branch, key_rlc_post_drifted, key_mult_post_branch, mod_node_hash_rlc) = + self.branch.assign_cached( + region, + mpt_config, + pv, + offset, + &extension_branch.is_placeholder, + &mut key_rlc, + &mut key_mult, + &mut num_nibbles, + &mut is_key_odd, + node, + )?; + + // Set the new parent and key + for is_s in [true, false] { + if !extension_branch.is_placeholder[is_s.idx()] { + KeyData::witness_store_cached( + region, + offset, + &mut pv.memory[key_memory(is_s)], + key_rlc_post_branch, //后面新算的 + key_mult_post_branch, + num_nibbles, + false, + 0.scalar(), + 0.scalar(), + )?; + ParentData::witness_store_cached( + region, + offset, + &mut pv.memory[parent_memory(is_s)], + mod_node_hash_rlc[is_s.idx()], + false, + false, + 0.scalar(), + )?; + } else { + KeyData::witness_store_cached( + region, + offset, + &mut pv.memory[key_memory(is_s)], + key_data.rlc, + key_data.mult, //维持原样,相当于重新入栈 + key_data.num_nibbles, + is_key_odd, + key_rlc_post_drifted, + key_mult_post_branch, + )?; + ParentData::witness_store_cached( + region, + offset, + &mut pv.memory[parent_memory(is_s)], + parent_data[is_s.idx()].rlc, + parent_data[is_s.idx()].is_root, + true, + mod_node_hash_rlc[is_s.idx()], + )?; + } + } + + Ok(()) + } } diff --git a/zkevm-circuits/src/mpt_circuit/helpers.rs b/zkevm-circuits/src/mpt_circuit/helpers.rs index a080939704..2542c08fad 100644 --- a/zkevm-circuits/src/mpt_circuit/helpers.rs +++ b/zkevm-circuits/src/mpt_circuit/helpers.rs @@ -3,7 +3,7 @@ use std::any::Any; use crate::{ _cb, circuit, circuit_tools::{ - cell_manager::{Cell, CellManager, Trackable}, + cell_manager::{Cell, CellManager_, Trackable, CellType}, constraint_builder::{ Conditionable, ConstraintBuilder, RLCChainable, RLCChainableValue, RLCable, RLCableValue, @@ -17,11 +17,13 @@ use crate::{ rlp_gadgets::{get_ext_odd_nibble, get_terminal_odd_nibble}, }, util::Expr, + evm_circuit::util::{CachedRegion, rlc}, bytecode_circuit::param::HASH_WIDTH, }; use eth_types::Field; use gadgets::util::{or, Scalar}; use halo2_proofs::{ - circuit::Region, + arithmetic::FieldExt, + circuit::{AssignedCell, Region, Value}, plonk::{Error, Expression}, }; @@ -30,8 +32,17 @@ use super::{ get_ext_odd_nibble_value, RLPListGadget, RLPListWitness, RLPValueGadget, RLPValueWitness, }, FixedTableTag, + + table::Lookup, }; +// Max degree allowed in all expressions passing through the ConstraintBuilder. +// It aims to cap `extended_k` to 2, which allows constraint degree to 2^2+1, +// but each ExecutionGadget has implicit selector degree 3, so here it only +// allows 2^2+1-3 = 2. +const MAX_DEGREE: usize = 5; +const IMPLICIT_DEGREE: usize = 3; + /// Indexable object pub trait Indexable { /// Convert to index @@ -115,6 +126,24 @@ impl LeafKeyGadget { has_no_nibble: has_no_nibble != 0.scalar(), }) } + + pub(crate) fn assign_cached( + &self, + region: &mut CachedRegion, + offset: usize, + rlp_key: RLPValueWitness, + ) -> Result { + let has_no_nibble = self.has_no_nibbles.assign_cached( + region, + offset, + F::from(rlp_key.bytes[0] as u64), + F::from(KEY_TERMINAL_PREFIX_EVEN as u64), + )?; + Ok(LeafKeyWitness { + has_no_nibble: has_no_nibble != 0.scalar(), + }) + } + } impl LeafKeyWitness { @@ -294,6 +323,27 @@ impl ListKeyGadget { }) } + pub(crate) fn assign_cached( + &self, + region: &mut CachedRegion, + offset: usize, + list_bytes: &[u8], + bytes: &[u8], + ) -> Result { + for (cell, byte) in self.rlp_list_bytes.iter().zip(list_bytes.iter()) { + cell.assign_cached(region, offset, byte.scalar())?; + } + let rlp_list = self.rlp_list.assign_cached(region, offset, list_bytes)?; + let key_value = self.key_value.assign_cached(region, offset, bytes)?; + let key = self.key.assign_cached(region, offset, key_value.clone())?; + + Ok(ListKeyWitness { + rlp_list, + key_value, + key, + }) + } + pub(crate) fn rlc(&self, r: &[Expression]) -> Expression { self.rlp_list .rlc_rlp_only(&r) @@ -442,6 +492,31 @@ impl KeyData { Ok(()) } + + pub(crate) fn witness_store_cached( + _region: &mut CachedRegion, + offset: usize, + memory: &mut MemoryBank, + rlc: F, + mult: F, + num_nibbles: usize, + placeholder_is_odd: bool, + parent_rlc: F, + parent_mult: F, + ) -> Result<(), Error> { + let values = [ + rlc, + mult, + num_nibbles.scalar(), + (num_nibbles % 2 == 1).scalar(), + placeholder_is_odd.scalar(), + parent_rlc, + parent_mult, + ]; + memory.witness_store(offset, &values); + + Ok(()) + } pub(crate) fn witness_load( &self, @@ -470,6 +545,35 @@ impl KeyData { drifted_mult: values[6], }) } + + pub(crate) fn witness_load_cached( + &self, + region: &mut CachedRegion, + offset: usize, + memory: &MemoryBank, + load_offset: usize, + ) -> Result, Error> { + let values = memory.witness_load(load_offset); + + self.rlc.assign_cached(region, offset, values[0])?; + self.mult.assign_cached(region, offset, values[1])?; + self.num_nibbles.assign_cached(region, offset, values[2])?; + self.is_odd.assign_cached(region, offset, values[3])?; + self.drifted_is_odd.assign_cached(region, offset, values[4])?; + self.drifted_rlc.assign_cached(region, offset, values[5])?; + self.drifted_mult.assign_cached(region, offset, values[6])?; + + Ok(KeyDataWitness { + rlc: values[0], + mult: values[1], + num_nibbles: values[2].get_lower_32() as usize, + is_odd: values[3] != F::zero(), + drifted_is_odd: values[4] != F::zero(), + drifted_rlc: values[5], + drifted_mult: values[6], + }) + } + } #[derive(Clone, Debug, Default)] @@ -545,6 +649,26 @@ impl ParentData { Ok(()) } + pub(crate) fn witness_store_cached( + _region: &mut CachedRegion, + offset: usize, + memory: &mut MemoryBank, + rlc: F, + force_hashed: bool, + is_placeholder: bool, + placeholder_rlc: F, + ) -> Result<(), Error> { + let values = [ + rlc, + force_hashed.scalar(), + is_placeholder.scalar(), + placeholder_rlc, + ]; + memory.witness_store(offset, &values); + + Ok(()) + } + pub(crate) fn witness_load( &self, region: &mut Region<'_, F>, @@ -566,6 +690,28 @@ impl ParentData { placeholder_rlc: values[3], }) } + + pub(crate) fn witness_load_cached( + &self, + region: &mut CachedRegion, + offset: usize, + memory: &MemoryBank, + load_offset: usize, + ) -> Result, Error> { + let values = memory.witness_load(load_offset); + + self.rlc.assign_cached(region, offset, values[0])?; + self.is_root.assign_cached(region, offset, values[1])?; + self.is_placeholder.assign_cached(region, offset, values[2])?; + self.placeholder_rlc.assign_cached(region, offset, values[3])?; + + Ok(ParentDataWitness { + rlc: values[0], + is_root: values[1] == 1.scalar(), + is_placeholder: values[2] == 1.scalar(), + placeholder_rlc: values[3], + }) + } } #[derive(Clone, Debug, Default)] @@ -647,6 +793,28 @@ impl MainData { Ok(()) } + pub(crate) fn witness_store_cached( + _region: &mut CachedRegion, + offset: usize, + memory: &mut MemoryBank, + proof_type: usize, + is_below_account: bool, + address_rlc: F, + root_prev: F, + root: F, + ) -> Result<(), Error> { + let values = [ + proof_type.scalar(), + is_below_account.scalar(), + address_rlc, + root_prev, + root, + ]; + memory.witness_store(offset, &values); + + Ok(()) + } + pub(crate) fn witness_load( &self, region: &mut Region<'_, F>, @@ -670,6 +838,31 @@ impl MainData { root: values[4], }) } + + pub(crate) fn witness_load_cached( + &self, + region: &mut CachedRegion, + offset: usize, + memory: &MemoryBank, + load_offset: usize, + ) -> Result, Error> { + let values = memory.witness_load(load_offset); + + self.proof_type.assign_cached(region, offset, values[0])?; + self.is_below_account.assign_cached(region, offset, values[1])?; + self.address_rlc.assign_cached(region, offset, values[2])?; + self.root_prev.assign_cached(region, offset, values[3])?; + self.root.assign_cached(region, offset, values[4])?; + + Ok(MainDataWitness { + proof_type: values[0].get_lower_32() as usize, + is_below_account: values[1] == 1.scalar(), + address_rlc: values[2], + root_prev: values[3], + root: values[4], + }) + } + } /// Add the nibble from the drifted branch @@ -819,6 +1012,51 @@ pub struct MPTConstraintBuilder { pub length_c: Vec<(Expression, Expression)>, /// The range to check in s bytes pub range_s: Vec<(Expression, Expression)>, + /// Store expression over max degree + pub stored_expressions: Vec>, + /// Store randomness over max degree + power_of_randomness: [Expression; HASH_WIDTH], +} + +#[derive(Debug, Clone)] +pub struct StoredExpression { + pub(crate) name: String, + cell: Cell, + cell_type: CellType, + expr: Expression, + expr_id: String, +} + +impl StoredExpression { + pub fn assign( + &self, + region: &mut CachedRegion<'_, '_, F>, + offset: usize, + ) -> Result, Error> { + let value = self.expr.evaluate( + &|scalar| scalar, + &|_| unimplemented!("selector column"), + &|fixed_query| { + region.get_fixed(offset, fixed_query.column_index(), fixed_query.rotation()) + }, + &|advide_query| { + region.get_advice(offset, advide_query.column_index(), advide_query.rotation()) + }, + &|instance_query| { + region.get_instance( + offset, + instance_query.column_index(), + instance_query.rotation(), + ) + }, + &|_| unimplemented!(), + &|a| -a, + &|a, b| a + b, + &|a, b| a * b, + &|a, scalar| a * scalar, + ); + self.cell.assign_cached(region, offset, value) + } } /// Length is set in the configuration of the rows where unused columns might @@ -832,13 +1070,19 @@ impl MPTConstraintBuilder { const NUM_BYTES_SKIP: usize = 2; // RLP bytes never need to be zero checked const DEFAULT_RANGE: FixedTableTag = FixedTableTag::RangeKeyLen256; - pub(crate) fn new(max_degree: usize, cell_manager: Option>) -> Self { + pub(crate) fn new( + max_degree: usize, + cell_manager: Option>, + power_of_randomness: [Expression; HASH_WIDTH], + ) -> Self { MPTConstraintBuilder { base: ConstraintBuilder::new(max_degree, cell_manager), length_s: Vec::new(), length_sc: 0.expr(), length_c: Vec::new(), range_s: Vec::new(), + stored_expressions: Vec::new(), + power_of_randomness } } @@ -887,6 +1131,151 @@ impl MPTConstraintBuilder { pub(crate) fn get_range_s(&self) -> Expression { Self::DEFAULT_RANGE.expr() - self.range_s.apply_conditions() } + + pub(crate) fn query_cell_with_type(&mut self, cell_type: CellType) -> Cell { + self.query_cells(cell_type, 1).first().unwrap().clone() + } + + fn query_cells(&mut self, cell_type: CellType, count: usize) -> Vec> { + self.base.cell_manager.clone().unwrap().query_cells(cell_type, count) + } + + pub(crate) fn add_constraint(&mut self, name: &'static str, constraint: Expression) { + let constraint = self.split_expression( + name, + constraint * self.base.get_condition_expr(), + MAX_DEGREE - IMPLICIT_DEGREE, + ); + + self.validate_degree(constraint.degree(), name); + self.base.add_constraint(name, constraint); + } + + pub(crate) fn validate_degree(&self, degree: usize, name: &'static str) { + // We need to subtract IMPLICIT_DEGREE from MAX_DEGREE because all expressions + // will be multiplied by state selector and q_step/q_step_first + // selector. + debug_assert!( + degree <= MAX_DEGREE - IMPLICIT_DEGREE, + "Expression {} degree too high: {} > {}", + name, + degree, + MAX_DEGREE - IMPLICIT_DEGREE, + ); + } + + pub(crate) fn add_lookup(&mut self, name: &str, lookup: Lookup) { + let lookup = match self.base.get_condition() { + Some(condition) => lookup.conditional(condition), + None => lookup, + }; + let compressed_expr = self.split_expression( + "Lookup compression", + rlc::expr(&lookup.input_exprs(), &self.power_of_randomness), + MAX_DEGREE - IMPLICIT_DEGREE, + ); + self.store_expression(name, compressed_expr, CellType::Lookup(lookup.table())); + } + + pub(crate) fn store_expression( + &mut self, + name: &str, + expr: Expression, + cell_type: CellType, + ) -> Expression { + // Check if we already stored the expression somewhere + let stored_expression = self.find_stored_expression(expr.clone(), cell_type); + match stored_expression { + Some(stored_expression) => { + debug_assert!( + !matches!(cell_type, CellType::Lookup(_)), + "The same lookup is done multiple times", + ); + stored_expression.cell.expr() + } + None => { + // Even if we're building expressions for the next step, + // these intermediate values need to be stored in the current step. + // let in_next_step = self.in_next_step; + // self.in_next_step = false; + let cell = self.query_cell_with_type(cell_type); + // self.in_next_step = in_next_step; + + // Require the stored value to equal the value of the expression + let name = format!("{} (stored expression)", name); + self.base.add_constraint( + Box::leak(name.clone().into_boxed_str()), + cell.expr() - expr.clone(), + ); + + self.stored_expressions.push(StoredExpression { + name, + cell: cell.clone(), + cell_type, + expr_id: expr.identifier(), + expr, + }); + cell.expr() + } + } + } + + pub(crate) fn find_stored_expression( + &self, + expr: Expression, + cell_type: CellType, + ) -> Option<&StoredExpression> { + let expr_id = expr.identifier(); + self.stored_expressions + .iter() + .find(|&e| e.cell_type == cell_type && e.expr_id == expr_id) + } + + fn split_expression( + &mut self, + name: &'static str, + expr: Expression, + max_degree: usize, + ) -> Expression { + if expr.degree() > max_degree { + match expr { + Expression::Negated(poly) => { + Expression::Negated(Box::new(self.split_expression(name, *poly, max_degree))) + } + Expression::Scaled(poly, v) => { + Expression::Scaled(Box::new(self.split_expression(name, *poly, max_degree)), v) + } + Expression::Sum(a, b) => { + let a = self.split_expression(name, *a, max_degree); + let b = self.split_expression(name, *b, max_degree); + a + b + } + Expression::Product(a, b) => { + let (mut a, mut b) = (*a, *b); + while a.degree() + b.degree() > max_degree { + let mut split = |expr: Expression| { + if expr.degree() > max_degree { + self.split_expression(name, expr, max_degree) + } else { + self.store_expression(name, expr, CellType::Storage) + } + }; + if a.degree() >= b.degree() { + a = split(a); + } else { + b = split(b); + } + } + a * b + } + _ => expr.clone(), + } + } else { + expr.clone() + } + } + + } /// Returns `1` when `value == 0`, and returns `0` otherwise. @@ -936,6 +1325,21 @@ impl IsEmptyTreeGadget { .assign(region, offset, parent_rlc, 0.scalar())?; Ok(()) } + + pub(crate) fn assign_cached( + &self, + region: &mut CachedRegion, + offset: usize, + parent_rlc: F, + r: F, + ) -> Result<(), Error> { + self.is_in_empty_trie + .assign_cached(region, offset, parent_rlc, EMPTY_TRIE_HASH.rlc_value(r))?; + self.is_in_empty_branch + .assign_cached(region, offset, parent_rlc, 0.scalar())?; + Ok(()) + } + } /// Handles drifted leaves @@ -1014,6 +1418,26 @@ impl DriftedGadget { } Ok(()) } + + pub(crate) fn assign_cached( + &self, + region: &mut CachedRegion, + offset: usize, + parent_data: &[ParentDataWitness], + drifted_list_bytes: &[u8], + drifted_bytes: &[u8], + r: F, + ) -> Result<(), Error> { + if parent_data[true.idx()].is_placeholder || parent_data[false.idx()].is_placeholder { + let drifted_key_witness = + self.drifted_rlp_key + .assign_cached(region, offset, drifted_list_bytes, drifted_bytes)?; + let (_, leaf_mult) = drifted_key_witness.rlc_leaf(r); + self.drifted_mult.assign_cached(region, offset, leaf_mult)?; + } + Ok(()) + } + } /// Handles wrong leaves @@ -1103,4 +1527,40 @@ impl WrongGadget { Ok(key_rlc[for_placeholder_s.idx()]) } } + + pub(crate) fn assign_cached( + &self, + region: &mut CachedRegion, + offset: usize, + is_non_existing: bool, + key_rlc: &[F], + list_bytes: &[u8], + wrong_bytes: &[u8], + for_placeholder_s: bool, + key_data: KeyDataWitness, + r: F, + ) -> Result { + if is_non_existing { + let wrong_witness = + self.wrong_rlp_key + .assign_cached(region, offset, list_bytes, wrong_bytes)?; + let (key_rlc_wrong, _) = wrong_witness.key.key( + wrong_witness.key_value.clone(), + key_data.rlc, + key_data.mult, + r, + ); + + self.is_key_equal.assign_cached( + region, + offset, + key_rlc[for_placeholder_s.idx()], + key_rlc_wrong, + )?; + Ok(key_rlc_wrong) + } else { + Ok(key_rlc[for_placeholder_s.idx()]) + } + } + } diff --git a/zkevm-circuits/src/mpt_circuit/param.rs b/zkevm-circuits/src/mpt_circuit/param.rs index 35e7d1bdde..5b444d255e 100644 --- a/zkevm-circuits/src/mpt_circuit/param.rs +++ b/zkevm-circuits/src/mpt_circuit/param.rs @@ -143,8 +143,11 @@ pub const RLP_HASH_VALUE: u8 = 128 + 32; // 0x80 pub const KEY_LEN: usize = 32; pub const KEY_LEN_IN_NIBBLES: usize = KEY_LEN * 2; + // Empty trie pub const EMPTY_TRIE_HASH: [u8; 32] = [ 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, ]; + +pub const TOTAL_WIDTH: usize = 76; \ No newline at end of file diff --git a/zkevm-circuits/src/mpt_circuit/rlp_gadgets.rs b/zkevm-circuits/src/mpt_circuit/rlp_gadgets.rs index 95e41fd220..2150e603f5 100644 --- a/zkevm-circuits/src/mpt_circuit/rlp_gadgets.rs +++ b/zkevm-circuits/src/mpt_circuit/rlp_gadgets.rs @@ -4,14 +4,17 @@ use crate::{ cell_manager::Cell, constraint_builder::{ConstraintBuilder, RLCable, RLCableValue}, }, - matchr, matchw, - mpt_circuit::param::{RLP_LIST_LONG, RLP_LIST_SHORT, RLP_SHORT}, - util::Expr, + matchr, matchw, + mpt_circuit::{ + FixedTableTag, + param::{RLP_LIST_LONG, RLP_LIST_SHORT, RLP_SHORT} + }, + util::Expr, evm_circuit::util::CachedRegion, }; use eth_types::Field; use gadgets::util::{not, Scalar}; use halo2_proofs::{ - circuit::Region, + circuit::{Region, self}, plonk::{Error, Expression}, }; @@ -37,12 +40,26 @@ pub(crate) struct RLPListWitness { impl RLPListGadget { pub(crate) fn construct(cb: &mut ConstraintBuilder, bytes: &[Expression]) -> Self { - // TODO(Brecht): add lookup/LtGadget + let is_short = cb.query_cell(); + let is_long = cb.query_cell(); + let is_very_long = cb.query_cell(); + let is_string = cb.query_cell(); + + circuit!([meta, cb], { + require!(vec![ + FixedTableTag::RLP.expr(), + bytes[0].clone(), + is_string.expr(), + is_short.expr(), + is_very_long.expr()] => @"fixed" + ); + }); + RLPListGadget { - is_short: cb.query_cell(), - is_long: cb.query_cell(), - is_very_long: cb.query_cell(), - is_string: cb.query_cell(), + is_short, + is_long, + is_very_long, + is_string, bytes: bytes.to_vec(), } } @@ -61,8 +78,11 @@ impl RLPListGadget { let mut is_very_long = false; let mut is_string = false; match bytes[0] { + // 192 - 247 RLP_LIST_SHORT..=RLP_LIST_LONG => is_short = true, + // 248 RLP_LIST_LONG_1 => is_long = true, + // 249 RLP_LIST_LONG_2 => is_very_long = true, _ => is_string = true, } @@ -82,6 +102,45 @@ impl RLPListGadget { }) } + pub(crate) fn assign_cached( + &self, + region: &mut CachedRegion, + offset: usize, + bytes: &[u8], + ) -> Result { + const RLP_LIST_LONG_1: u8 = RLP_LIST_LONG + 1; + const RLP_LIST_LONG_2: u8 = RLP_LIST_LONG + 2; + + let mut is_short = false; + let mut is_long = false; + let mut is_very_long = false; + let mut is_string = false; + match bytes[0] { + // 192 - 247 + RLP_LIST_SHORT..=RLP_LIST_LONG => is_short = true, + // 248 + RLP_LIST_LONG_1 => is_long = true, + // 249 + RLP_LIST_LONG_2 => is_very_long = true, + _ => is_string = true, + } + + self.is_short.assign_cached(region, offset, F::from(is_short))?; + self.is_long.assign_cached(region, offset, F::from(is_long))?; + self.is_very_long + .assign_cached(region, offset, F::from(is_very_long))?; + self.is_string.assign_cached(region, offset, F::from(is_string))?; + + Ok(RLPListWitness { + is_short, + is_long, + is_very_long, + is_string, + bytes: bytes.to_vec(), + }) + } + + // Single RLP byte, length at most 55 bytes pub(crate) fn is_list(&self) -> Expression { not::expr(self.is_string.expr()) @@ -236,6 +295,20 @@ impl RLPListDataGadget { self.rlp_list.assign(region, offset, list_bytes) } + + pub(crate) fn assign_cached( + &self, + region: &mut CachedRegion, + offset: usize, + list_bytes: &[u8], + ) -> Result { + for (cell, byte) in self.rlp_list_bytes.iter().zip(list_bytes.iter()) { + cell.assign_cached(region, offset, byte.scalar())?; + } + self.rlp_list.assign_cached(region, offset, list_bytes) + } + + pub(crate) fn rlc_rlp(&self, r: &[Expression]) -> (Expression, Expression) { self.rlp_list.rlc_rlp_only(&r) } @@ -261,12 +334,26 @@ pub(crate) struct RLPValueWitness { impl RLPValueGadget { pub(crate) fn construct(cb: &mut ConstraintBuilder, bytes: &[Expression]) -> Self { - // TODO(Brecht): add lookup + let is_short = cb.query_cell(); + let is_long = cb.query_cell(); + let is_very_long = cb.query_cell(); + let is_list = cb.query_cell(); + + circuit!([meta, cb], { + require!(vec![ + FixedTableTag::RLP.expr(), + bytes[0].clone(), + not::expr(is_list.expr()), + is_short.expr(), + is_very_long.expr()] => @"fixed" + ); + }); + RLPValueGadget { - is_short: cb.query_cell(), - is_long: cb.query_cell(), - is_very_long: cb.query_cell(), - is_list: cb.query_cell(), + is_short, + is_long, + is_very_long, + is_list, bytes: bytes.to_vec(), } } @@ -286,8 +373,11 @@ impl RLPValueGadget { let mut is_very_long = false; let mut is_list = false; match bytes[0] { + // 0 - 127 0..=RLP_SHORT_INCLUSIVE => is_short = true, + // 128 - 183 RLP_SHORT..=RLP_LONG => is_long = true, + // 189 - 191 RLP_LONG_EXCLUSIVE..=RLP_VALUE_MAX => is_very_long = true, _ => is_list = true, } @@ -307,6 +397,46 @@ impl RLPValueGadget { }) } + pub(crate) fn assign_cached( + &self, + region: &mut CachedRegion, + offset: usize, + bytes: &[u8], + ) -> Result { + const RLP_SHORT_INCLUSIVE: u8 = RLP_SHORT - 1; + const RLP_LONG_EXCLUSIVE: u8 = RLP_LONG + 1; + const RLP_VALUE_MAX: u8 = RLP_LIST_SHORT - 1; + + let mut is_short = false; + let mut is_long = false; + let mut is_very_long = false; + let mut is_list = false; + match bytes[0] { + // 0 - 127 + 0..=RLP_SHORT_INCLUSIVE => is_short = true, + // 128 - 183 + RLP_SHORT..=RLP_LONG => is_long = true, + // 189 - 191 + RLP_LONG_EXCLUSIVE..=RLP_VALUE_MAX => is_very_long = true, + _ => is_list = true, + } + + self.is_short.assign_cached(region, offset, F::from(is_short))?; + self.is_long.assign_cached(region, offset, F::from(is_long))?; + self.is_very_long + .assign_cached(region, offset, F::from(is_very_long))?; + self.is_list.assign_cached(region, offset, F::from(is_list))?; + + Ok(RLPValueWitness { + is_short, + is_long, + is_very_long, + is_list, + bytes: bytes.to_vec(), + }) + } + + // Returns true if this is indeed a string RLP pub(crate) fn is_string(&self) -> Expression { not::expr(self.is_list.expr()) @@ -578,6 +708,24 @@ impl RLPItemGadget { }) } + pub(crate) fn assign_cached( + &self, + region: &mut CachedRegion, + offset: usize, + bytes: &[u8], + ) -> Result { + let value_witness = self.value.assign_cached(region, offset, bytes)?; + let list_witness = self.list.assign_cached(region, offset, bytes)?; + assert!(!(value_witness.is_string() && list_witness.is_list())); + + Ok(RLPItemWitness { + value: value_witness, + list: list_witness, + bytes: bytes.to_vec(), + }) + } + + // Single RLP byte containing the byte value pub(crate) fn is_short(&self) -> Expression { circuit!([meta, _cb!()], { diff --git a/zkevm-circuits/src/mpt_circuit/start.rs b/zkevm-circuits/src/mpt_circuit/start.rs index b4b43bd1d0..5b0775ab80 100644 --- a/zkevm-circuits/src/mpt_circuit/start.rs +++ b/zkevm-circuits/src/mpt_circuit/start.rs @@ -2,6 +2,7 @@ use super::helpers::Indexable; use super::witness_row::{Node, StartRowType}; use crate::circuit_tools::cell_manager::Cell; use crate::circuit_tools::constraint_builder::{RLCable, RLCableValue}; +use crate::evm_circuit::util::CachedRegion; use crate::mpt_circuit::helpers::{main_memory, MainData}; use crate::{ circuit, @@ -138,4 +139,65 @@ impl StartConfig { Ok(()) } + + pub fn assign_cached( + &self, + region: &mut CachedRegion, + ctx: &MPTConfig, + pv: &mut MPTState, + offset: usize, + node: &Node, + ) -> Result<(), Error> { + let start = &node.start.clone().unwrap(); + + let root_bytes = [ + node.values[StartRowType::RootS as usize].clone(), + node.values[StartRowType::RootC as usize].clone(), + ]; + + self.proof_type + .assign_cached(region, offset, start.proof_type.scalar())?; + + let mut root = vec![0.scalar(); 2]; + for is_s in [true, false] { + root[is_s.idx()] = root_bytes[is_s.idx()].rlc_value(ctx.r); + } + + MainData::witness_store_cached( + region, + offset, + &mut pv.memory[main_memory()], + start.proof_type as usize, + false, + 0.scalar(), + root[true.idx()], + root[false.idx()], + )?; + + for is_s in [true, false] { + ParentData::witness_store_cached( + region, + offset, + &mut pv.memory[parent_memory(is_s)], + root[is_s.idx()], + true, + false, + root[is_s.idx()], + )?; + KeyData::witness_store_cached( + region, + offset, + &mut pv.memory[key_memory(is_s)], + F::zero(), + F::one(), + 0, + false, + F::zero(), + F::one(), + )?; + } + + Ok(()) + } + } diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs index a47f0dedf2..d603a89fa5 100644 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs @@ -6,7 +6,7 @@ use halo2_proofs::{ poly::Rotation, }; -use crate::mpt_circuit::helpers::{num_nibbles, IsEmptyTreeGadget}; +use crate::{mpt_circuit::helpers::{num_nibbles, IsEmptyTreeGadget}, evm_circuit::util::CachedRegion}; use crate::table::ProofType; use crate::{ circuit, @@ -443,4 +443,184 @@ impl StorageLeafConfig { Ok(()) } + + pub fn assign_cached( + &self, + region: &mut CachedRegion, + ctx: &MPTConfig, + pv: &mut MPTState, + offset: usize, + node: &Node, + ) -> Result<(), Error> { + let storage = &node.storage.clone().unwrap(); + + let key_bytes = [ + node.values[StorageRowType::KeyS as usize].clone(), + node.values[StorageRowType::KeyC as usize].clone(), + ]; + let value_bytes = [ + node.values[StorageRowType::ValueS as usize].clone(), + node.values[StorageRowType::ValueC as usize].clone(), + ]; + let drifted_bytes = node.values[StorageRowType::Drifted as usize].clone(); + let wrong_bytes = node.values[StorageRowType::Wrong as usize].clone(); + + let main_data = + self.main_data + .witness_load_cached(region, offset, &pv.memory[main_memory()], 0)?; + + let mut key_data = vec![KeyDataWitness::default(); 2]; + let mut parent_data = vec![ParentDataWitness::default(); 2]; + let mut key_rlc = vec![0.scalar(); 2]; + let mut value_rlc = vec![0.scalar(); 2]; + for is_s in [true, false] { + parent_data[is_s.idx()] = self.parent_data[is_s.idx()].witness_load_cached( + region, + offset, + &mut pv.memory[parent_memory(is_s)], + 0, + )?; + + let rlp_key_witness = self.rlp_key[is_s.idx()].assign_cached( + region, + offset, + &storage.list_rlp_bytes[is_s.idx()], + &key_bytes[is_s.idx()], + )?; + + let (_, leaf_mult) = rlp_key_witness.rlc_leaf(ctx.r); + self.key_mult[is_s.idx()].assign_cached(region, offset, leaf_mult)?; + + self.is_not_hashed[is_s.idx()].assign_cached( + region, + offset, + rlp_key_witness.rlp_list.num_bytes().scalar(), + 32.scalar(), + )?; + + key_data[is_s.idx()] = self.key_data[is_s.idx()].witness_load_cached( + region, + offset, + &mut pv.memory[key_memory(is_s)], + 0, + )?; + KeyData::witness_store_cached( + region, + offset, + &mut pv.memory[key_memory(is_s)], + F::zero(), + F::one(), + 0, + false, + F::zero(), + F::one(), + )?; + + // Key + (key_rlc[is_s.idx()], _) = rlp_key_witness.key.key( + rlp_key_witness.key_value.clone(), + key_data[is_s.idx()].rlc, + key_data[is_s.idx()].mult, + ctx.r, + ); + + // Value + for (cell, byte) in self.value_rlp_bytes[is_s.idx()] + .iter() + .zip(storage.value_rlp_bytes[is_s.idx()].iter()) + { + cell.assign_cached(region, offset, byte.scalar())?; + } + let value_witness = self.rlp_value[is_s.idx()].assign_cached( + region, + offset, + &storage.value_rlp_bytes[is_s.idx()], + )?; + let value_long_witness = + self.rlp_value_long[is_s.idx()].assign_cached(region, offset, &value_bytes[is_s.idx()])?; + value_rlc[is_s.idx()] = if value_witness.is_short() { + value_witness.rlc_value(ctx.r) + } else { + value_long_witness.rlc_value(ctx.r) + }; + + ParentData::witness_store_cached( + region, + offset, + &mut pv.memory[parent_memory(is_s)], + F::zero(), + true, + false, + F::zero(), + )?; + + self.is_in_empty_trie[is_s.idx()].assign_cached( + region, + offset, + parent_data[is_s.idx()].rlc, + ctx.r, + )?; + } + + let is_storage_mod_proof = self.is_storage_mod_proof.assign_cached( + region, + offset, + main_data.proof_type.scalar(), + ProofType::StorageChanged.scalar(), + )? == true.scalar(); + let is_non_existing_proof = self.is_non_existing_storage_proof.assign_cached( + region, + offset, + main_data.proof_type.scalar(), + ProofType::StorageDoesNotExist.scalar(), + )? == true.scalar(); + + // Drifted leaf handling + self.drifted.assign_cached( + region, + offset, + &parent_data, + &storage.drifted_rlp_bytes, + &drifted_bytes, + ctx.r, + )?; + + // Wrong leaf handling + let key_rlc = self.wrong.assign_cached( + region, + offset, + is_non_existing_proof, + &key_rlc, + &storage.wrong_rlp_bytes, + &wrong_bytes, + false, + key_data[true.idx()].clone(), + ctx.r, + )?; + + // Put the data in the lookup table + let proof_type = if is_storage_mod_proof { + ProofType::StorageChanged + } else if is_non_existing_proof { + ProofType::StorageDoesNotExist + } else { + ProofType::Disabled + }; + ctx.mpt_table.assign_cached( + region, + offset, + &MptUpdateRow { + address_rlc: main_data.address_rlc, + proof_type: proof_type.scalar(), + key_rlc: key_rlc, + value_prev: value_rlc[true.idx()], + value: value_rlc[false.idx()], + root_prev: main_data.root_prev, + root: main_data.root, + }, + )?; + + Ok(()) + } + } diff --git a/zkevm-circuits/src/mpt_circuit/table.rs b/zkevm-circuits/src/mpt_circuit/table.rs new file mode 100644 index 0000000000..5641c998ea --- /dev/null +++ b/zkevm-circuits/src/mpt_circuit/table.rs @@ -0,0 +1,107 @@ +use eth_types::Field; +use gadgets::util::Expr; +use halo2_proofs::plonk::Expression; +use strum_macros::EnumIter; +use gadgets::{impl_expr, util::Scalar}; +use crate::circuit_tools::cell_manager::Table; + +#[derive(Clone, Copy, Debug)] +pub enum FixedTableTag { + /// All zero lookup data + Disabled, + /// Power of randomness: [1, r], [2, r^2],... + RMult, + /// 0 - 15 + Range16, + /// 0 - 255 + Range256, + /// For checking there are 0s after the RLP stream ends + RangeKeyLen256, + /// For checking there are 0s after the RLP stream ends + RangeKeyLen16, + /// For checking RLP + RLP, + /// For distinguishing odd key part in extension + ExtOddKey, + /// State transition steps constriants + /// 2 + StartNode, + /// 21 + BranchNode, + /// 12 + AccountNode, + /// 6 + StorageNode +} +impl_expr!(FixedTableTag); + + +#[derive(Clone, Debug)] +pub(crate) enum Lookup { + /// Lookup to fixed table, which contains serveral pre-built tables such as + /// range tables or bitwise tables. + Fixed { + /// Tag to specify which table to lookup. + tag: Expression, + /// Values that must satisfy the pre-built relationship. + values: [Expression; 5], + }, + + /// Lookup to keccak table. + KeccakTable { + /// Accumulator to the input. + input_rlc: Expression, + /// Length of input that is being hashed. + input_len: Expression, + /// Output (hash) until this state. This is the RLC representation of + /// the final output keccak256 hash of the input. + output_rlc: Expression, + }, + + /// Conditional lookup enabled by the first element. + Conditional(Expression, Box>), +} + +impl Lookup { + pub(crate) fn conditional(self, condition: Expression) -> Self { + Self::Conditional(condition, self.into()) + } + + pub(crate) fn table(&self) -> Table { + match self { + Self::Fixed { .. } => Table::Fixed, + Self::KeccakTable {.. } => Table::Keccak, + Self::Conditional(_, lookup) => lookup.table(), + } + } + + pub(crate) fn input_exprs(&self) -> Vec> { + match self { + Self::Fixed { tag, values } => [vec![tag.clone()], values.to_vec()].concat(), + Self::KeccakTable { + input_rlc, + input_len, + output_rlc, + } => vec![ + 1.expr(), // is_enabled + input_rlc.clone(), + input_len.clone(), + output_rlc.clone(), + ], + Self::Conditional(condition, lookup) => lookup + .input_exprs() + .into_iter() + .map(|expr| condition.clone() * expr) + .collect(), + } + } + + pub(crate) fn degree(&self) -> usize { + self.input_exprs() + .iter() + .map(|expr| expr.degree()) + .max() + .unwrap() + } + +} \ No newline at end of file diff --git a/zkevm-circuits/src/table.rs b/zkevm-circuits/src/table.rs index 04f0d43e0f..0fa31e9fdf 100644 --- a/zkevm-circuits/src/table.rs +++ b/zkevm-circuits/src/table.rs @@ -2,7 +2,7 @@ use crate::circuit_tools::constraint_builder::ConstraintBuilder; use crate::copy_circuit::number_or_hash_to_field; -use crate::evm_circuit::util::{rlc, RandomLinearCombination}; +use crate::evm_circuit::util::{rlc, RandomLinearCombination, CachedRegion}; use crate::util::build_tx_log_address; use crate::util::Challenges; use crate::witness::{ @@ -548,6 +548,24 @@ impl MptTable { Ok(()) } + pub(crate) fn assign_cached( + &self, + region: &mut CachedRegion, + offset: usize, + row: &MptUpdateRow, + ) -> Result<(), Error> { + for (column, value) in self.columns().iter().zip_eq(row.values()) { + region.assign_advice( + || "assign mpt table row value", + *column, + offset, + || Value::known(value), + )?; + } + Ok(()) + } + + pub(crate) fn load( &self, layouter: &mut impl Layouter,