From 2179083cd7e16dac78b717254082cc847f4345d7 Mon Sep 17 00:00:00 2001 From: Marcus Kainth Date: Mon, 7 Sep 2026 03:49:59 +0100 Subject: [PATCH 1/5] native: thread the player through a hit's damage folds P_DamageMobj's player branch: armour absorption, health, attacker, damagecount and the pain state for a living player, threaded through every hit a tic can land on it (a claw, an in-flight missile, several missiles in one thinks_fold) in the order the engine's own thinkers apply them. Death, and the sector 11 damage clamp, stay refused as their own unresolved bits. --- native/src/sql/sim/attacks.rs | 4 + native/src/sql/sim/inter.rs | 251 ++++++++++++++++++++++++++----- native/src/sql/sim/missile.rs | 53 +++++-- native/src/sql/sim/mobj.rs | 133 ++++++++++++++-- native/src/sql/sim/mod.rs | 13 +- native/src/sql/sim/player.rs | 19 +++ native/src/sql/sim/pspr.rs | 4 + native/tests/sim_blast_live.rs | 13 +- native/tests/sim_damage_live.rs | 22 ++- native/tests/sim_gunshot_live.rs | 4 + 10 files changed, 450 insertions(+), 66 deletions(-) diff --git a/native/src/sql/sim/attacks.rs b/native/src/sql/sim/attacks.rs index e5c2aec3..7efb8ae2 100644 --- a/native/src/sql/sim/attacks.rs +++ b/native/src/sql/sim/attacks.rs @@ -1143,8 +1143,12 @@ mod tests { m_target: "m_target", m_threshold: "m_threshold", m_player: "m_player", + m_subsector: "m_subsector", prndindex: "prndindex", readyweapon: "readyweapon", + p_cheats: "p_cheats", + p_powers: "p_powers", + sec_special: "sec_special", } } diff --git a/native/src/sql/sim/inter.rs b/native/src/sql/sim/inter.rs index e156d3a1..f72cd913 100644 --- a/native/src/sql/sim/inter.rs +++ b/native/src/sql/sim/inter.rs @@ -857,6 +857,16 @@ const ANGLETOFINESHIFT: u32 = 19; /// to be knocked over, and the most damage that can do it. const FALL_HEIGHT: i64 = 64 * FRACUNIT; const FALL_DAMAGE: i64 = 40; +/// `d_player.h` +const CF_GODMODE: i64 = 2; +/// `d_englsh.h`'s `skill_t`: `sk_baby`, one below the default `sk_medium` +/// the demo header carries for `DEMO3`. +const SK_BABY: i64 = 0; +/// `p_inter.c`: below this, god mode and invulnerability stop the hit +/// outright rather than reduce it. +const GODMODE_DAMAGE_LIMIT: i64 = 1000; +/// `p_inter.c`: a damage tint clamps at this many tics. +const DAMAGECOUNT_LIMIT: i64 = 100; /// Where each field of a damage ask sits in its tuple. pub mod hurting { @@ -897,22 +907,57 @@ pub mod hurt { pub const DRAWS: usize = 15; /// 1 where the call reached a path this does not write. pub const STUCK: usize = 16; + /// The player's own health where the target is the player, carried + /// through unchanged otherwise. + pub const PL_HEALTH: usize = 17; + pub const PL_ARMORPOINTS: usize = 18; + pub const PL_ARMORTYPE: usize = 19; + pub const PL_DAMAGECOUNT: usize = 20; + /// 0 for none, the same as [`hurting::SOURCE`]. + pub const PL_ATTACKER: usize = 21; + /// 1 where the hit leaves the player's own health at 0 or below. + pub const PL_DIES: usize = 22; + /// 1 where the target's sector special is 11 and the damage reaches + /// the clamp that keeps a hit there from killing outright. + pub const PL_SECTOR11: usize = 23; } /// The ClickHouse type of a [`hurt`] tuple, for a caller that carries one /// through a fold or a wider tuple of its own. pub const HURT_TYPE: &str = "Tuple(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, \ - Int32, UInt32, Int32, UInt8, UInt8, Int32, UInt32, UInt8)"; + Int32, UInt32, Int32, UInt8, UInt8, Int32, UInt32, UInt8, Int32, \ + Int32, Int32, Int32, UInt32, UInt8, UInt8)"; /// A call nobody made, for a caller that reads the first answer of a list /// that may be empty. pub fn no_hurt() -> String { "(toInt32(0), toInt32(0), toInt32(0), toInt32(0), toInt32(0), toInt32(0), toInt32(0), \ toInt32(0), toInt32(0), toUInt32(0), toInt32(0), toUInt8(0), toUInt8(0), toInt32(-1), \ - toUInt32(0), toUInt8(0))" + toUInt32(0), toUInt8(0), toInt32(0), toInt32(0), toInt32(0), toInt32(0), toUInt32(0), \ + toUInt8(0), toUInt8(0))" .to_owned() } +/// The tic's own player fields, wrapped as a [`hurt`] tuple for the first +/// [`damage_fold`] of the tic to start from: every other field the same as +/// [`no_hurt`], since nothing but [`hurt::PL_HEALTH`] through +/// [`hurt::PL_ATTACKER`] is ever read off a fold's own seed. +pub fn player_start( + p_health: &str, + p_armorpoints: &str, + p_armortype: &str, + p_damagecount: &str, + p_attacker: &str, +) -> String { + format!( + "(toInt32(0), toInt32(0), toInt32(0), toInt32(0), toInt32(0), toInt32(0), toInt32(0), \ + toInt32(0), toInt32(0), toUInt32(0), toInt32(0), toUInt8(0), toUInt8(0), toInt32(-1), \ + toUInt32(0), toUInt8(0), toInt32({p_health}), toInt32({p_armorpoints}), \ + toInt32({p_armortype}), toInt32({p_damagecount}), toUInt32({p_attacker}), toUInt8(0), \ + toUInt8(0))" + ) +} + /// The arrays a damage call reads. pub struct Hurting<'a> { pub m_x: &'a str, @@ -931,10 +976,19 @@ pub struct Hurting<'a> { pub m_target: &'a str, pub m_threshold: &'a str, pub m_player: &'a str, + /// The sector each mobj's own subsector belongs to, for the sector 11 + /// hack a hit into it reaches. + pub m_subsector: &'a str, pub prndindex: &'a str, /// The weapon in the player's hands, which is what decides whether a /// hit pushes its target. pub readyweapon: &'a str, + /// `player->cheats`, for `CF_GODMODE`. + pub p_cheats: &'a str, + /// `player->powers`, one-based, for `pw_invulnerability`. + pub p_powers: &'a str, + /// Each sector's own special, for the sector 11 hack. + pub sec_special: &'a str, } /// The engine tables a damage call reads that no other stage does. @@ -980,10 +1034,12 @@ pub fn damage_constants(db: &str) -> Vec<(String, String)> { /// may knock it over. Both are decided before either number is read, so a /// caller making several calls knows the offset each one's draws sit at. /// -/// A player target leaves the call stuck rather than guessed: the armour, -/// the damage tint and the weapon it drops are the player's own columns. +/// A player's own health, armour, damage tint and attacker do not thread +/// here the way [`damage_fold`]'s own accumulator threads them: nothing +/// this runs for asks the player itself, so [`no_hurt`] stands in for the +/// player fields a body reads and never answers with. pub fn damage_mobj(asks: &str, world: &Hurting<'_>) -> String { - let (values, body) = damaged(world); + let (values, body) = damaged(world, &no_hurt()); format!( "arrayMap(dm_ask -> {}, {asks})", bind::chain_in("dma", &values, &body) @@ -1035,11 +1091,39 @@ fn reach(world: &Hurting<'_>) -> Vec<(String, String)> { "dm_health".to_owned(), format!("toInt32({})", at(world.m_health)), ), + ( + "dm_is_player".to_owned(), + format!("toUInt8({} != -1)", at(world.m_player)), + ), + // `damage >>= 1` on the baby skill, for a player target only, ahead + // of the thrust and everything after it, which all read the same + // local the engine does. + ( + "dm_damage_now".to_owned(), + format!( + "toInt32(if(dm_is_player = 1 AND skill = {SK_BABY}, intDiv(dm_damage, 2), \ + dm_damage))" + ), + ), + // God mode and invulnerability return before anything else runs, + // under a damage this large. + ( + "dm_immune".to_owned(), + format!( + "toUInt8(dm_is_player = 1 AND dm_damage_now < {GODMODE_DAMAGE_LIMIT} \ + AND (bitAnd({}, {CF_GODMODE}) != 0 OR {}[{PW_INVULNERABILITY}] != 0))", + world.p_cheats, world.p_powers, + ), + ), // The two early returns: a thing that cannot be shot, and one - // already dead, take nothing and draw nothing. + // already dead, take nothing and draw nothing. A player's own god + // mode or invulnerability is the same kind of return. ( "dm_lands".to_owned(), - format!("toUInt8(bitAnd(dm_flags, {MF_SHOOTABLE}) != 0 AND dm_health > 0)"), + format!( + "toUInt8(bitAnd(dm_flags, {MF_SHOOTABLE}) != 0 AND dm_health > 0 \ + AND dm_immune = 0)" + ), ), // The push. A call with no inflictor pushes nothing, and a // chainsaw in the source's hands holds its target in reach. @@ -1057,7 +1141,8 @@ fn reach(world: &Hurting<'_>) -> Vec<(String, String)> { ( "dm_may_fall".to_owned(), format!( - "toUInt8(dm_pushes = 1 AND dm_damage < {FALL_DAMAGE} AND dm_damage > dm_health \ + "toUInt8(dm_pushes = 1 AND dm_damage_now < {FALL_DAMAGE} \ + AND dm_damage_now > dm_health \ AND toInt64({}) - toInt64({}) > {FALL_HEIGHT})", at(world.m_z), from(world.m_z), @@ -1072,20 +1157,27 @@ fn reach(world: &Hurting<'_>) -> Vec<(String, String)> { /// A map runs every function in its body once even on an empty list, and /// this body is the whole routine. A fold runs its body only where the /// list has an element, so a caller with nothing to hurt pays for the fold -/// and nothing under it. The answer is the last ask in the list, and -/// [`no_hurt`] is what an empty one gives. -pub fn damage_fold(asks: &str, world: &Hurting<'_>) -> String { - let (values, body) = damaged(world); +/// and nothing under it. The answer is the last ask in the list. +/// +/// `start` is what an empty list answers with, and what the one ask an +/// asks list carries reads its own player fields from: the engine applies +/// several hits to the player in the order their own thinkers run, each +/// reading what the one before it left, so a caller chaining several +/// `damage_fold` calls in one tic passes the previous call's own answer +/// rather than [`no_hurt`]. +pub fn damage_fold(asks: &str, start: &str, world: &Hurting<'_>) -> String { + let (values, body) = damaged(world, "dm_held"); format!( - "arrayFold((dm_held, dm_ask) -> {}, {asks}, {})", + "arrayFold((dm_held, dm_ask) -> {}, {asks}, {start})", bind::chain_in("dma", &values, &body), - no_hurt(), ) } /// What one call works out, as the values a body reads and the [`hurt`] -/// tuple it answers with. -fn damaged(world: &Hurting<'_>) -> (Vec<(String, String)>, String) { +/// tuple it answers with. `player` is where the ask's own player fields +/// stand before this call, `dm_held` under [`damage_fold`]'s own fold and +/// [`no_hurt`] where nothing threads them. +fn damaged(world: &Hurting<'_>, player: &str) -> (Vec<(String, String)>, String) { let a = |field: usize| format!("dm_ask.{field}"); let at = |array: &str| format!("{array}[dm_target]"); let from = |array: &str| format!("{array}[dm_inflictor]"); @@ -1112,7 +1204,7 @@ fn damaged(world: &Hurting<'_>) -> (Vec<(String, String)>, String) { value( "dm_thrust", format!( - "toInt32(intDiv(dm_damage * {} * 100, {}))", + "toInt32(intDiv(dm_damage_now * {} * 100, {}))", FRACUNIT >> 3, info("mobj_mass") ), @@ -1170,12 +1262,67 @@ fn damaged(world: &Hurting<'_>) -> (Vec<(String, String)>, String) { "dm_momy", along(super::maputl::finesine("dm_fine"), "dm_momy_held"), ); - // The damage, and the death it may cause. - value("dm_left", "toInt32(dm_health - dm_damage)".to_owned()); + // `target->subsector->sector->special == 11`'s own clamp keeps a hit + // there from killing outright. This does not compute it: the tic + // leaves stuck below instead, where the damage reaches it. + value( + "dm_sector", + format!( + "toUInt32(1 + ssec_sector[1 + toUInt32({})])", + at(world.m_subsector) + ), + ); + value( + "dm_sector11", + format!( + "toUInt8(dm_is_player = 1 AND {}[dm_sector] = 11 AND dm_damage_now >= dm_health)", + world.sec_special + ), + ); + // The armour, ahead of the health both it and the mobj's own share: + // `player->armortype == 1` saves a third, `2` saves a half, and armour + // that cannot cover the save is spent and taken off. + value( + "dm_armortype_in", + format!("toInt32({player}.{})", hurt::PL_ARMORTYPE), + ); + value( + "dm_armorpoints_in", + format!("toInt32({player}.{})", hurt::PL_ARMORPOINTS), + ); + value( + "dm_saved", + "toInt32(if(dm_is_player = 1 AND dm_armortype_in != 0, \ + intDiv(dm_damage_now, if(dm_armortype_in = 1, 3, 2)), 0))" + .to_owned(), + ); + value( + "dm_saved_clamped", + "toInt32(least(dm_saved, dm_armorpoints_in))".to_owned(), + ); + // The damage, and the death it may cause. A player target's own + // health and the mobj's own share the same armour-reduced number, the + // way `target->health -= damage` reads the local the player block + // above it already changed. + value( + "dm_damage_final", + "toInt32(if(dm_is_player = 1, dm_damage_now - dm_saved_clamped, dm_damage_now))".to_owned(), + ); + value("dm_left", "toInt32(dm_health - dm_damage_final)".to_owned()); value( "dm_killed", "toUInt8(dm_lands = 1 AND dm_left <= 0)".to_owned(), ); + value( + "dm_player_dies", + "toUInt8(dm_is_player = 1 AND dm_killed = 1)".to_owned(), + ); + // A living player actually takes this hit: not immune, not a miss, + // and not the death this leaves stuck instead of guessing at. + value( + "dm_player_hit", + "toUInt8(dm_lands = 1 AND dm_is_player = 1 AND dm_player_dies = 0)".to_owned(), + ); // The second draw sits behind the fall's, where one was made. let second = format!( "toInt64(rnd[1 + bitAnd(toUInt32({}) + toUInt32({}) + 1 + toUInt32(dm_may_fall), 255)])", @@ -1223,7 +1370,7 @@ fn damaged(world: &Hurting<'_>) -> (Vec<(String, String)>, String) { value( "dm_chases", format!( - "toUInt8(dm_lands = 1 AND dm_killed = 0 \ + "toUInt8(dm_lands = 1 AND dm_killed = 0 AND dm_is_player = 0 \ AND ({} = 0 OR dm_type = mt_vile) \ AND dm_source != 0 AND dm_source != dm_target AND {} != mt_vile)", at(world.m_threshold), @@ -1276,23 +1423,21 @@ fn damaged(world: &Hurting<'_>) -> (Vec<(String, String)>, String) { held = at(world.m_tics), ), ); - // A player target leaves the call stuck: the armour it wears, the tint - // it takes and the weapon it drops are the player's own columns. // `P_SetMobjState` runs the routine the frame it enters carries. // `A_Pain` and `A_Scream` only make a noise; any other leaves the call // stuck rather than guessed, which is what an `A_Chase` on a see frame - // and an `A_Explode` on a barrel's death frame do. + // and an `A_Explode` on a barrel's death frame do. The player's own + // death is the same kind of stuck: `P_KillMobj`'s player branch is not + // written here. value( "dm_routine", "toInt32(if(dm_moves = 1, state_action[1 + dm_state], 0))".to_owned(), ); value( "dm_stuck", - format!( - "toUInt8(dm_lands = 1 AND ({} != -1 \ - OR (dm_routine != 0 AND dm_routine != a_pain AND dm_routine != a_scream)))", - at(world.m_player) - ), + "toUInt8(dm_lands = 1 AND (dm_player_dies = 1 OR dm_sector11 = 1 \ + OR (dm_routine != 0 AND dm_routine != a_pain AND dm_routine != a_scream)))" + .to_owned(), ); let members = [ "toInt32(if(dm_lands = 1, dm_left, dm_health))".to_owned(), @@ -1327,6 +1472,34 @@ fn damaged(world: &Hurting<'_>) -> (Vec<(String, String)>, String) { "toInt32(if(dm_killed = 1, dm_drop, -1))".to_owned(), "toUInt32(if(dm_lands = 1, 1 + toUInt32(dm_may_fall), 0))".to_owned(), "toUInt8(dm_stuck)".to_owned(), + format!( + "toInt32(if(dm_player_hit = 1, greatest(toInt32({player}.{}) - dm_damage_final, 0), \ + {player}.{}))", + hurt::PL_HEALTH, + hurt::PL_HEALTH, + ), + format!( + "toInt32(if(dm_player_hit = 1, dm_armorpoints_in - dm_saved_clamped, {player}.{}))", + hurt::PL_ARMORPOINTS, + ), + format!( + "toInt32(if(dm_player_hit = 1, \ + if(dm_armortype_in != 0 AND dm_armorpoints_in <= dm_saved, 0, dm_armortype_in), \ + {player}.{}))", + hurt::PL_ARMORTYPE, + ), + format!( + "toInt32(if(dm_player_hit = 1, \ + least(toInt32({player}.{}) + dm_damage_final, {DAMAGECOUNT_LIMIT}), {player}.{}))", + hurt::PL_DAMAGECOUNT, + hurt::PL_DAMAGECOUNT, + ), + format!( + "toUInt32(if(dm_player_hit = 1, dm_source, {player}.{}))", + hurt::PL_ATTACKER, + ), + "toUInt8(dm_player_dies)".to_owned(), + "toUInt8(dm_sector11)".to_owned(), ]; (values, format!("({})", members.join(", "))) } @@ -1353,8 +1526,12 @@ mod damage_tests { m_target: "m_target", m_threshold: "m_threshold", m_player: "m_player", + m_subsector: "m_subsector", prndindex: "prndindex", readyweapon: "readyweapon", + p_cheats: "p_cheats", + p_powers: "p_powers", + sec_special: "sec_special", } } @@ -1363,7 +1540,7 @@ mod damage_tests { /// draw after it in the tic sits behind that count. #[test] fn a_call_draws_by_where_it_lands_and_whether_it_may_fell() { - let (_, body) = damaged(&world()); + let (_, body) = damaged(&world(), "dm_held"); assert!( body.contains("toUInt32(if(dm_lands = 1, 1 + toUInt32(dm_may_fall), 0))"), "{body}" @@ -1374,7 +1551,7 @@ mod damage_tests { /// the chainsaw test and the chase read the source. #[test] fn the_push_reads_the_inflictor_and_the_credit_reads_the_source() { - let (values, _) = damaged(&world()); + let (values, _) = damaged(&world(), "dm_held"); let named = |name: &str| { values .iter() @@ -1395,17 +1572,19 @@ mod damage_tests { assert!(!chases.contains("dm_inflictor"), "{chases}"); } - /// A player target leaves the call stuck rather than guessed, because - /// the armour, the tint and the dropped weapon are the player's own - /// columns. + /// A hit that would kill the player leaves the call stuck rather than + /// guessed, because `P_KillMobj`'s player branch is not written here. + /// A living player's own hit is not: its armour, health, attacker and + /// damage tint are the fields threaded through `player`. #[test] - fn a_player_target_leaves_the_call_stuck() { - let (values, _) = damaged(&world()); + fn a_hit_that_would_kill_the_player_leaves_the_call_stuck() { + let (values, _) = damaged(&world(), "dm_held"); let stuck = values .iter() .find(|(name, _)| name == "dm_stuck") .expect("the call names what leaves it stuck"); - assert!(stuck.1.contains("m_player[dm_target] != -1"), "{stuck:?}"); + assert!(stuck.1.contains("dm_player_dies = 1"), "{stuck:?}"); + assert!(stuck.1.contains("dm_sector11 = 1"), "{stuck:?}"); } /// The routine reads no thing type it names by hand out of the diff --git a/native/src/sql/sim/missile.rs b/native/src/sql/sim/missile.rs index a91a8f78..678e2703 100644 --- a/native/src/sql/sim/missile.rs +++ b/native/src/sql/sim/missile.rs @@ -842,28 +842,49 @@ fn clamp(mom: &str) -> String { } /// The ClickHouse type of a [`thought`] tuple, for a caller that carries a -/// list of them through a fold. -pub const THOUGHT_TYPE: &str = "Tuple(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, \ - Int32, Int32, Int32, Int32, UInt32, Tuple(Int32, Int32, Int32, \ - Int32, Int32, Int32, Int32, Int32, Int32, UInt32, Int32, UInt8, \ - UInt8, Int32, UInt32, UInt8), UInt32, UInt8)"; +/// list of them through a fold. Its own [`thought::HURT`] member is +/// [`inter::HURT_TYPE`], named once rather than spelled twice so the two +/// cannot drift apart. +pub fn thought_type() -> String { + format!( + "Tuple(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, \ + Int32, UInt32, {}, UInt32, UInt8)", + inter::HURT_TYPE + ) +} /// The mobj arrays a missile already on the list reads for its own move, /// its own fall and its own state cycle, plus what a thing it damages /// reads. `slot` names which mobj in these `flying` and `hurting` reads /// the missile itself, over the same arrays a caller driving anything /// else's move already holds. +/// +/// The player's own health, armour, damagecount and attacker thread +/// through every missile the list carries, in order: each one's own +/// `P_DamageMobj` reads what the missile before it left, the way +/// [`inter::damage_fold`] threads them for a caller with only one ask. +/// `start` is the tic's own player fields for the first list this runs +/// over, or the previous list's own final fields for one chained after +/// it; the fold's own final tuple carries them on for a caller to chain +/// further still. pub fn thinks_fold( asks: &str, + start: &str, map: &World<'_>, flying: &Flying<'_>, hurting: &inter::Hurting<'_>, ) -> String { let (values, body) = thought_of(map, flying, hurting); + let step = bind::chain_in("tka", &values, &body); + let folded = bind::chain_in( + "tkb", + &[("tk_result".to_owned(), step)], + "(arrayPushBack(tk_held.1, tk_result.1), tk_result.2)", + ); format!( - "arrayFold((tk_held, tk_ask) -> arrayPushBack(tk_held, {}), {asks}, \ - CAST([] AS Array({THOUGHT_TYPE})))", - bind::chain_in("tka", &values, &body) + "arrayFold((tk_held, tk_ask) -> {folded}, {asks}, \ + (CAST([] AS Array({})), {start}))", + thought_type() ) } @@ -1199,7 +1220,13 @@ fn thought_of( damage = struck::DAMAGE, ), ); - value("mn_hurt", inter::damage_fold("mn_damage_asks", hurting)); + // `tk_held.2` is what the missile before this one in the same list + // left the player's own fields at, or the tic's own row where this is + // the first. + value( + "mn_hurt", + inter::damage_fold("mn_damage_asks", "tk_held.2", hurting), + ); value( "mn_hurt_target", format!( @@ -1546,7 +1573,7 @@ fn thought_of( "mn_draws".to_owned(), "mn_stuck".to_owned(), ]; - (values, format!("({})", members.join(", "))) + (values, format!("(({}), mn_hurt)", members.join(", "))) } #[cfg(test)] @@ -1828,13 +1855,17 @@ mod tests { m_target: "m_target", m_threshold: "m_threshold", m_player: "m_player", + m_subsector: "m_subsector", prndindex: "prndindex", readyweapon: "readyweapon", + p_cheats: "p_cheats", + p_powers: "p_powers", + sec_special: "sec_special", } } fn thinks_sql() -> String { - thinks_fold("asks", &map(), &flying(), &hurting()) + thinks_fold("asks", &inter::no_hurt(), &map(), &flying(), &hurting()) } #[test] diff --git a/native/src/sql/sim/mobj.rs b/native/src/sql/sim/mobj.rs index ac5e52b6..cbf97d48 100644 --- a/native/src/sql/sim/mobj.rs +++ b/native/src/sql/sim/mobj.rs @@ -1,7 +1,9 @@ //! What a thing does with its momentum and its states, from `p_mobj.c`. use super::map::{self, World, answer}; -use super::{State, attacks, enemy, inter, maputl, mask, missile, sight, specials, unresolved}; +use super::{ + State, attacks, enemy, inter, maputl, mask, missile, player, sight, specials, unresolved, +}; use crate::sql::Statement; use crate::sql::bind; use crate::sql::fixed; @@ -550,8 +552,12 @@ pub fn thinkers(state: &State) -> Vec<(String, String)> { m_target: &s("m_target"), m_threshold: &s("m_threshold"), m_player: &s("m_player"), + m_subsector: &s("m_subsector"), prndindex: &s("prndindex"), readyweapon: &s("p_readyweapon"), + p_cheats: &s("p_cheats"), + p_powers: &s("p_powers"), + sec_special: &s("sec_special"), }; bind( "mt_attacker_draws_asks", @@ -916,18 +922,28 @@ pub fn thinkers(state: &State) -> Vec<(String, String)> { m_target: "mk_m_target", m_threshold: "mk_m_threshold", m_player: &s("m_player"), + m_subsector: "mk_m_subsector", prndindex: &s("prndindex"), readyweapon: &s("p_readyweapon"), + p_cheats: &s("p_cheats"), + p_powers: &s("p_powers"), + sec_special: &s("sec_special"), }; + // The player's own health, armour, damagecount and attacker pick up + // from `mt_hurt`'s own final fields: a claw runs before this in + // `strikes`, the first of the tic's three damage folds. bind( - "mt_missile_thoughts", + "mt_missile_folded", missile::thinks_fold( "mt_missile_asks", + "mt_hurt", &struck_map, &struck_flying, &struck_hurting, ), ); + bind("mt_missile_thoughts", "mt_missile_folded.1".to_owned()); + bind("mt_missile_players", "mt_missile_folded.2".to_owned()); bind( "mt_missile_hurt_targets", format!( @@ -988,6 +1004,24 @@ pub fn thinkers(state: &State) -> Vec<(String, String)> { missile::thought::STUCK ), ), + ( + unresolved::PLAYER_DIES, + &format!( + "arrayExists(t -> t.{hurt}.{dies} = 1, mt_missile_thoughts) \ + OR mt_hurt.{dies} = 1", + hurt = missile::thought::HURT, + dies = inter::hurt::PL_DIES, + ), + ), + ( + unresolved::SECTOR11_STUCK, + &format!( + "arrayExists(t -> t.{hurt}.{sec} = 1, mt_missile_thoughts) \ + OR mt_hurt.{sec} = 1", + hurt = missile::thought::HURT, + sec = inter::hurt::PL_SECTOR11, + ), + ), ], ) ), @@ -1291,10 +1325,30 @@ fn strikes(state: &State, map: &World<'_>) -> Vec<(String, String)> { m_target: "mk_m_target", m_threshold: "mk_m_threshold", m_player: &s("m_player"), + m_subsector: "mk_m_subsector", prndindex: &s("prndindex"), readyweapon: &s("p_readyweapon"), + p_cheats: &s("p_cheats"), + p_powers: &s("p_powers"), + sec_special: &s("sec_special"), }; - bind("mt_hurt", inter::damage_fold("mt_hurt_asks", &hurting)); + // The player's own health, armour, damagecount and attacker start + // from the tic's own row: `strikes` runs before this stage's own + // missile impacts, the first of the tic's three damage folds. + bind( + "mt_hurt", + inter::damage_fold( + "mt_hurt_asks", + &inter::player_start( + &s("p_health"), + &s("p_armorpoints"), + &s("p_armortype"), + &s("p_damagecount"), + &s("p_attacker"), + ), + &hurting, + ), + ); // `P_SpawnMissile` for an imp whose claw did not reach. The fireball // is the only missile a routine throws here, so its type is the one @@ -1428,8 +1482,12 @@ pub fn thrown_thinks(state: &State) -> Vec<(String, String)> { m_target: &s("m_target"), m_threshold: &s("m_threshold"), m_player: &s("m_player"), + m_subsector: &s("m_subsector"), prndindex: &s("prndindex"), readyweapon: &s("p_readyweapon"), + p_cheats: &s("p_cheats"), + p_powers: &s("p_powers"), + sec_special: &s("sec_special"), }; // The compaction appends one slot per thing `mt_thrown` carries, in @@ -1442,10 +1500,19 @@ pub fn thrown_thinks(state: &State) -> Vec<(String, String)> { draws = missile::thrown::DRAWS, ), ); + // The player's own health, armour, damagecount and attacker pick up + // from `mt_missile_players`, the thinker stage's own final fields: + // this is the last of the tic's three damage folds, so its own final + // fields are what `player.rs`'s writeback reads. bind( - "tk_thoughts", - missile::thinks_fold("tk_asks", &map, &flying, &hurting), + "tk_folded", + missile::thinks_fold("tk_asks", "mt_missile_players", &map, &flying, &hurting), ); + bind("tk_thoughts", "tk_folded.1".to_owned()); + bind("tk_players", "tk_folded.2".to_owned()); + for (name, expr) in player::hurt_writeback("tk_players") { + bind(&name, expr); + } bind("tk_slots", "arrayMap(a -> a.1, tk_asks)".to_owned()); bind( "tk_at", @@ -1575,13 +1642,31 @@ pub fn thrown_thinks(state: &State) -> Vec<(String, String)> { "now_unresolved", mask( &s("unresolved"), - &[( - unresolved::TK_STUCK, - &format!( - "arrayExists(t -> t.{} = 1, tk_thoughts)", - missile::thought::STUCK + &[ + ( + unresolved::TK_STUCK, + &format!( + "arrayExists(t -> t.{} = 1, tk_thoughts)", + missile::thought::STUCK + ), ), - )], + ( + unresolved::PLAYER_DIES, + &format!( + "arrayExists(t -> t.{hurt}.{dies} = 1, tk_thoughts)", + hurt = missile::thought::HURT, + dies = inter::hurt::PL_DIES, + ), + ), + ( + unresolved::SECTOR11_STUCK, + &format!( + "arrayExists(t -> t.{hurt}.{sec} = 1, tk_thoughts)", + hurt = missile::thought::HURT, + sec = inter::hurt::PL_SECTOR11, + ), + ), + ], ), ); bindings @@ -3268,7 +3353,7 @@ mod tests { /// the damage tint and the weapon it drops are the player's own /// columns. The claw's own damage fold has to be read the same way. #[test] - fn a_claw_that_lands_on_the_player_is_unresolved() { + fn a_claw_s_own_stuck_call_leaves_the_thinker_stage_unresolved() { let bindings = thinkers(&State::default()); let at_unrun = bindings .iter() @@ -3281,6 +3366,30 @@ mod tests { ); } + /// A hit that would kill the player, from a claw or a missile already + /// in flight, is its own bit rather than folded into `DM_STUCK`. + #[test] + fn a_hit_that_would_kill_the_player_is_its_own_bit() { + let bindings = thinkers(&State::default()); + let now_unresolved = bindings + .iter() + .find(|(binding, _)| binding == "now_unresolved") + .map(|(_, expr)| expr.clone()) + .unwrap_or_else(|| panic!("now_unresolved is bound")); + assert!( + now_unresolved.contains(&format!("mt_hurt.{} = 1", inter::hurt::PL_DIES)), + "{now_unresolved}" + ); + assert!( + now_unresolved.contains(&format!( + "t.{}.{} = 1, mt_missile_thoughts", + missile::thought::HURT, + inter::hurt::PL_DIES, + )), + "{now_unresolved}" + ); + } + #[test] fn the_loop_runs_as_many_steps_as_the_momentum_needs() { let text = steps("mx", "my", "u"); diff --git a/native/src/sql/sim/mod.rs b/native/src/sql/sim/mod.rs index 24c86ec4..2ac0c59d 100644 --- a/native/src/sql/sim/mod.rs +++ b/native/src/sql/sim/mod.rs @@ -57,8 +57,8 @@ pub mod unresolved { /// `P_PlayerInSpecialSector`: the player stands in a sector that /// damages it. pub const PL_HURTS: u64 = 1 << 2; - /// `P_DamageMobj`: the hit lands on a player, or the frame it enters - /// carries an action other than none, `A_Pain` or `A_Scream`. + /// `P_DamageMobj`: the frame the hit enters carries an action other + /// than none, `A_Pain` or `A_Scream`. pub const DM_STUCK: u64 = 1 << 3; /// `P_GunShot`'s own fold: a shot's damage call hits a player or an /// unimplemented post-hit routine, or a shot crosses a special line @@ -163,10 +163,15 @@ pub mod unresolved { /// The same, for a monster's own move. A monster's own crossing never /// reaches a door special, so only `PLAT_TRIGGER_SPECIALS` applies. pub const TX_MULTI_CROSSED: u64 = 1 << 33; + /// `P_DamageMobj`: a hit on the player leaves its health at 0 or below. + pub const PLAYER_DIES: u64 = 1 << 34; + /// `P_DamageMobj`: the target's sector special is 11, and the damage + /// reaches the clamp that keeps a hit there from killing outright. + pub const SECTOR11_STUCK: u64 = 1 << 35; } /// Every bit `unresolved` names, in ascending order. -const UNRESOLVED_BITS: [(u64, &str); 34] = [ +const UNRESOLVED_BITS: [(u64, &str); 36] = [ (unresolved::PK_STUCK, "PK_STUCK"), (unresolved::PX_CROSSED, "PX_CROSSED"), (unresolved::PL_HURTS, "PL_HURTS"), @@ -201,6 +206,8 @@ const UNRESOLVED_BITS: [(u64, &str); 34] = [ (unresolved::MISSILE_STUCK, "MISSILE_STUCK"), (unresolved::PX_MULTI_CROSSED, "PX_MULTI_CROSSED"), (unresolved::TX_MULTI_CROSSED, "TX_MULTI_CROSSED"), + (unresolved::PLAYER_DIES, "PLAYER_DIES"), + (unresolved::SECTOR11_STUCK, "SECTOR11_STUCK"), ]; /// The names of the bits `bits` sets, most significant last, for a message diff --git a/native/src/sql/sim/player.rs b/native/src/sql/sim/player.rs index 5608ba5d..6ce6504d 100644 --- a/native/src/sql/sim/player.rs +++ b/native/src/sql/sim/player.rs @@ -654,6 +654,25 @@ fn mobj_thinker(state: &State) -> Vec<(String, String)> { bindings } +/// The player's own health, armour, damagecount and attacker, off the +/// last of the tic's own damage folds to run: the thinker stage's claw, an +/// in-flight missile's own impact and the thrown thinker's, each reading +/// what the one before it left. `hurt` is that last fold's own final +/// tuple, which carries the tic's starting row unchanged where nothing +/// hit the player at all. +pub fn hurt_writeback(hurt: &str) -> Vec<(String, String)> { + let field = |name: &str, cast: &str, member: usize| { + (name.to_owned(), format!("{cast}({hurt}.{member})")) + }; + vec![ + field("now_p_health", "toInt32", inter::hurt::PL_HEALTH), + field("now_p_armorpoints", "toInt32", inter::hurt::PL_ARMORPOINTS), + field("now_p_armortype", "toInt32", inter::hurt::PL_ARMORTYPE), + field("now_p_damagecount", "toInt32", inter::hurt::PL_DAMAGECOUNT), + field("now_p_attacker", "toUInt32", inter::hurt::PL_ATTACKER), + ] +} + /// Everything the tic leaves in the state row: the player's own fields, /// the mobj arrays with the player moved, and the list without whatever it /// picked up. diff --git a/native/src/sql/sim/pspr.rs b/native/src/sql/sim/pspr.rs index 7f6a6067..2639d757 100644 --- a/native/src/sql/sim/pspr.rs +++ b/native/src/sql/sim/pspr.rs @@ -965,8 +965,12 @@ pub fn fire_shots(state: &State) -> Vec<(String, String)> { m_target: member(firing::TARGET), m_threshold: member(firing::THRESHOLD), m_player: "gs_m_player", + m_subsector: &s("m_subsector"), prndindex: &prnd, readyweapon: "now_p_readyweapon", + p_cheats: &s("p_cheats"), + p_powers: &s("p_powers"), + sec_special: &s("sec_special"), }, ), ); diff --git a/native/tests/sim_blast_live.rs b/native/tests/sim_blast_live.rs index 14ba2a26..b52dcd68 100644 --- a/native/tests/sim_blast_live.rs +++ b/native/tests/sim_blast_live.rs @@ -309,10 +309,11 @@ struct Arrays { m_threshold: String, m_player: String, zero: String, + sec_special: String, } impl Arrays { - fn of(mobjs: &[Mobj], standing: &[Standing], subsector: &[i64]) -> Arrays { + fn of(mobjs: &[Mobj], standing: &[Standing], subsector: &[i64], db: &str) -> Arrays { let of = |get: &dyn Fn(usize) -> i64| literal(&(0..mobjs.len()).map(get).collect::>()); Arrays { @@ -333,6 +334,10 @@ impl Arrays { m_threshold: of(&|at| mobjs[at].threshold), m_player: of(&|at| mobjs[at].player), zero: of(&|_| 0), + // No ask here ever targets the player, so the sector this + // hits never reads: the level's own real sector table keeps + // the lookup in bounds regardless. + sec_special: format!("(SELECT sec_special FROM {db}.native_state WHERE tic = 0)"), } } @@ -369,8 +374,12 @@ impl Arrays { m_target: &self.m_target, m_threshold: &self.m_threshold, m_player: &self.m_player, + m_subsector: &self.m_subsector, prndindex, readyweapon: "0", + p_cheats: "0", + p_powers: "[0, 0, 0, 0, 0, 0]", + sec_special: &self.sec_special, } } } @@ -440,7 +449,7 @@ async fn ask_server( prnd: i64, base: i64, ) -> (Vec, i64) { - let arrays = Arrays::of(mobjs, standing, subsector); + let arrays = Arrays::of(mobjs, standing, subsector, db); let prndindex = prnd.to_string(); let hurting = arrays.hurting(&prndindex); let source = mobjs[spot - 1].target; diff --git a/native/tests/sim_damage_live.rs b/native/tests/sim_damage_live.rs index 935db86b..514ea447 100644 --- a/native/tests/sim_damage_live.rs +++ b/native/tests/sim_damage_live.rs @@ -307,7 +307,10 @@ fn asks(mobjs: &[Mobj], sources: &[i64]) -> Vec { asks } -/// One answer as the statement gives it, in [`inter::hurt`]'s order. +/// One answer as the statement gives it, in [`inter::hurt`]'s order up to +/// `STUCK`. The player fields past it are not this test's own concern: no +/// ask here ever targets the player, so [`ask_server`]'s own SQL drops +/// them before this reads the row. type HurtRow = ( i32, i32, @@ -348,6 +351,11 @@ async fn ask_server(fixture: &Fixture, db: &str, world: &World, asks: &[Ask]) -> let (m_target, m_threshold, m_player) = (of(&|m| m.target), of(&|m| m.threshold), of(&|m| m.player)); let m_reactiontime = of(&|_| 0); + // No ask here ever targets the player, so the sector this hits never + // reads: any subsector at all does, over the level's own real sector + // table so the lookup stays in bounds. + let m_subsector = of(&|_| 0); + let sec_special = format!("(SELECT sec_special FROM {db}.native_state WHERE tic = 0)"); let (prnd, weapon) = (world.prndindex.to_string(), world.readyweapon.to_string()); let hurting = inter::Hurting { m_x: &m_x, @@ -366,8 +374,12 @@ async fn ask_server(fixture: &Fixture, db: &str, world: &World, asks: &[Ask]) -> m_target: &m_target, m_threshold: &m_threshold, m_player: &m_player, + m_subsector: &m_subsector, prndindex: &prnd, readyweapon: &weapon, + p_cheats: "0", + p_powers: "[0, 0, 0, 0, 0, 0]", + sec_special: &sec_special, }; let list = format!( "[{}]", @@ -380,8 +392,14 @@ async fn ask_server(fixture: &Fixture, db: &str, world: &World, asks: &[Ask]) -> ); let mut constants = sim::constants(db); constants.extend(inter::damage_constants(db)); + // Only the fields up to `STUCK` are this test's own concern; the + // player fields past it never move, since no ask here targets one. + let trimmed = (1..=inter::hurt::STUCK) + .map(|field| format!("h.{field}")) + .collect::>() + .join(", "); let sql = format!( - "WITH\n{},\n ({list}) AS dm_asks\nSELECT {} AS hurts", + "WITH\n{},\n ({list}) AS dm_asks\nSELECT arrayMap(h -> ({trimmed}), {}) AS hurts", constants .into_iter() .map(|(name, expr)| format!(" ({expr}) AS {name}")) diff --git a/native/tests/sim_gunshot_live.rs b/native/tests/sim_gunshot_live.rs index 1fc8f5d8..0e7e2fc6 100644 --- a/native/tests/sim_gunshot_live.rs +++ b/native/tests/sim_gunshot_live.rs @@ -557,8 +557,12 @@ impl Arrays { m_target: &self.m_target, m_threshold: &self.m_threshold, m_player: &self.m_player, + m_subsector: &self.zero, prndindex, readyweapon: "0", + p_cheats: "0", + p_powers: "[0, 0, 0, 0, 0, 0]", + sec_special: "[0]", } } } From b9561ea2a402fb796ff03d678df2a5dca8d64284 Mon Sep 17 00:00:00 2001 From: Marcus Kainth Date: Mon, 7 Sep 2026 04:08:59 +0100 Subject: [PATCH 2/5] native: reach the player with a claw through its own armour A claw seeded against the player, the same shape as sim_troop_live.rs's own attack, across no armour and both armour types: the shared mobj health and the player's own health move by the same post-armour number, the tint takes it, and the tic resolves rather than refusing the way a claw on a monster still does. --- native/tests/sim_player_damage_live.rs | 233 +++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 native/tests/sim_player_damage_live.rs diff --git a/native/tests/sim_player_damage_live.rs b/native/tests/sim_player_damage_live.rs new file mode 100644 index 00000000..69a0b307 --- /dev/null +++ b/native/tests/sim_player_damage_live.rs @@ -0,0 +1,233 @@ +//! `P_DamageMobj`'s player branch, against a real ClickHouse server. +//! +//! A claw is seeded the way `native/tests/sim_troop_live.rs` seeds one, +//! aimed at the player instead of a second imp: an imp beside the player, +//! one tic from `A_TroopAttack`'s own frame. +//! +//! Needs a reachable ClickHouse (`CLICKHOUSE_HOST` / `CLICKHOUSE_HTTP_PORT` +//! / `CLICKHOUSE_PASSWORD`, defaulting to `localhost:8123` with no +//! password). Behind the `clickhouse-tests` feature, so a run without a +//! server visibly excludes them. +#![cfg(feature = "clickhouse-tests")] + +use clickdoom_native::sql::sim; +use clickdoom_native::sql::sim::tick::Input; +use clickdoom_native::{load, sql, wad::Wad}; +use clickhouse::Row; +use serde::Deserialize; + +mod support; + +use support::db::Fixture; +use support::seed; + +/// The tic every arm copies its row from. Gametic 40 is early enough that +/// no monster has woken and the list still holds the level's own things. +const BEFORE: u32 = 40; + +/// The imp that runs the routine. `MT_TROOP`, on the level's own list, and +/// stands still at gametic 40. +const ATTACKER: usize = 116; + +/// `states.tsv`: the frame carrying `A_FaceTarget`, and the frame after it +/// carrying `A_TroopAttack`. Seeding the first with one tic of wait left +/// puts the routine on the tic the arm runs. +const FACE: i32 = 453; +const ATTACK: i32 = 454; + +/// How far from the player the imp stands. `MELEERANGE` is sixty four +/// units and `P_CheckMeleeRange` measures against that less twenty, plus +/// the player's own radius; four units is inside its reach. +const NEAR: i64 = 4 * 65536; + +/// `doomdef.h` +const ARMOR_NONE: i64 = 0; +const ARMOR_GREEN: i64 = 1; +const ARMOR_BLUE: i64 = 2; +/// Comfortably more than a claw's own worst case (24) can spend, so the +/// armour arms never run out of what they save. +const STARTING_ARMORPOINTS: i64 = 100; + +/// One arm per seeded row: its name, where the copy of `BEFORE` lands and +/// the armour it starts the player with. +const ARMS: [(&str, u32, i64); 3] = [ + ("no_armor", 200, ARMOR_NONE), + ("green_armor", 300, ARMOR_GREEN), + ("blue_armor", 400, ARMOR_BLUE), +]; + +#[derive(Row, Deserialize)] +struct Hit { + tic: u32, + p_health: i32, + p_armorpoints: i32, + p_armortype: i32, + p_damagecount: i32, + p_attacker: u32, + player_health: i32, + attacker_state: i32, + unresolved: u64, +} + +/// A column of one slot replaced, leaving every other slot alone. +fn put(column: &'static str, slot: usize, value: String, cast: &str) -> (&'static str, String) { + ( + column, + format!( + "arrayMap((v, k) -> {cast}(if(k = {slot}, {value}, v)), \ + p.{column}, arrayEnumerate(p.{column}))" + ), + ) +} + +#[tokio::test] +async fn a_claw_reaches_the_player_through_its_own_armour() { + let bytes = support::doom1(); + let wad = Wad::parse(&bytes).unwrap(); + let fixture = Fixture::create("sim_player_damage").await; + let db = fixture.database.clone(); + + let mut plan = load::plan(&db, &wad); + plan.extend(sql::level_statements(&db, support::MAP, support::DEMO)); + plan.extend(sim::load_statements(&db)); + plan.push(sim::tick::demo_statement(&db, 1, BEFORE)); + if let Err(error) = fixture.execute(&plan).await { + fixture.finish().await; + panic!("{error}"); + } + + let mut statements: Vec = Vec::new(); + for (_, at, armortype) in ARMS { + let overrides = [ + // The imp beside the player, in the frame whose next carries + // the routine, with one tic of wait left on it. + put( + "m_x", + ATTACKER, + format!("p.m_x[p.p_mo] + toInt32({NEAR})"), + "toInt32", + ), + put("m_y", ATTACKER, "p.m_y[p.p_mo]".to_owned(), "toInt32"), + put("m_z", ATTACKER, "p.m_z[p.p_mo]".to_owned(), "toInt32"), + put("m_state", ATTACKER, FACE.to_string(), "toInt32"), + put("m_tics", ATTACKER, "1".to_owned(), "toInt32"), + put("m_target", ATTACKER, "p.p_mo".to_owned(), "toUInt32"), + ("p_health", "toInt32(100)".to_owned()), + ("p_armortype", format!("toInt32({armortype})")), + ( + "p_armorpoints", + format!( + "toInt32({})", + if armortype == ARMOR_NONE { + 0 + } else { + STARTING_ARMORPOINTS + } + ), + ), + ("p_damagecount", "toInt32(0)".to_owned()), + ("p_attacker", "toUInt32(0)".to_owned()), + ]; + statements.extend( + seed::row(&db, at, BEFORE, &overrides) + .into_iter() + .map(sql::Statement::sql), + ); + statements.push(sim::tick::run_statement( + &db, + &[Input::keys(at + 1, 0, (0, 0))], + )); + } + if let Err(error) = fixture.execute(&statements).await { + fixture.finish().await; + panic!("{error}"); + } + + let wanted: Vec = ARMS + .iter() + .flat_map(|(_, at, _)| [at.to_string(), (at + 1).to_string()]) + .collect(); + let rows: Vec = fixture + .rows(&format!( + "SELECT tic, p_health, p_armorpoints, p_armortype, p_damagecount, p_attacker, \ + m_health[p_mo] AS player_health, m_state[{ATTACKER}] AS attacker_state, \ + unresolved \ + FROM {db}.native_state WHERE tic IN ({}) ORDER BY tic", + wanted.join(", ") + )) + .await; + fixture.finish().await; + assert_eq!( + rows.len(), + ARMS.len() * 2, + "a seeded row and a tic from it for every arm" + ); + let at = |tic: u32| { + rows.iter() + .find(|row| row.tic == tic) + .unwrap_or_else(|| panic!("no row for tic {tic}")) + }; + + // The bare arm: no armour, so the raw roll reaches health outright. + // `A_TroopAttack`'s own damage is `(P_Random()%8+1)*3`, and every arm + // seeds the same imp at the same state with the same starting + // `prndindex`, so the roll is identical across all three. + let (before, after) = (at(200), at(201)); + assert_eq!( + before.attacker_state, FACE, + "the seeded row is a tic from the routine" + ); + assert_eq!(after.attacker_state, ATTACK, "and the cycle reaches it"); + assert_eq!( + after.unresolved, 0, + "a living player's own hit resolves, unlike a monster's" + ); + let raw_damage = before.p_health - after.p_health; + assert!( + (3..=24).contains(&raw_damage) && raw_damage % 3 == 0, + "the claw's own damage is three times one to eight: {raw_damage}" + ); + assert_eq!( + before.player_health - after.player_health, + raw_damage, + "the mobj's own health shares the same number" + ); + assert_eq!(after.p_armorpoints, 0, "no armour, nothing saved"); + assert_eq!(after.p_armortype, 0); + assert_eq!( + after.p_damagecount, raw_damage, + "the tint takes the whole hit" + ); + assert_eq!( + after.p_attacker, ATTACKER as u32, + "the player's own attacker is the imp that clawed it" + ); + + // The armoured arms save a third or a half of the same roll. + for (name, divisor) in [("green_armor", 3), ("blue_armor", 2)] { + let (_, at_tic, _) = ARMS.iter().find(|(n, _, _)| *n == name).unwrap(); + let (before, after) = (at(*at_tic), at(*at_tic + 1)); + assert_eq!(after.unresolved, 0, "{name}"); + let saved = raw_damage / divisor; + assert_eq!( + before.p_armorpoints - after.p_armorpoints, + saved, + "{name}: the armour absorbs its own share" + ); + assert_eq!( + before.p_health - after.p_health, + raw_damage - saved, + "{name}: health takes what the armour did not" + ); + assert_eq!( + before.player_health - after.player_health, + raw_damage - saved, + "{name}: the mobj's own health shares the same number" + ); + assert_eq!( + after.p_damagecount, + raw_damage - saved, + "{name}: the tint takes the post-armour damage" + ); + } +} From 3e347a3bea6abfd3163ada172f5f7da328189fc5 Mon Sep 17 00:00:00 2001 From: Marcus Kainth Date: Mon, 7 Sep 2026 05:07:44 +0100 Subject: [PATCH 3/5] native: reach the player with a fireball through its own armour A fireball still in flight, seeded from the reference emulator's own row rather than hand-placed geometry, across no armour and both armour types, and two fireballs landing on the player in the same tic to prove the player's own fields thread across separate hits. Threading the player through two hits on the same target in one tic surfaces a gap the fold's own mobj-generic fields were never built for: they read the tic-start arrays directly rather than an accumulator, so a second hit on a target this tic already hit overwrites the first's own answer instead of building on it. damage_fold now carries the set of targets a tic has already hit the same way it carries the player's own fields, and refuses a repeat rather than committing the wrong shared health. --- native/src/sql/sim/inter.rs | 69 +++- native/src/sql/sim/mobj.rs | 17 + native/src/sql/sim/mod.rs | 7 +- native/tests/fixtures/README.md | 5 + native/tests/fixtures/demo3-player-damage.tsv | 2 + native/tests/sim_player_damage_live.rs | 333 ++++++++++++++++++ 6 files changed, 427 insertions(+), 6 deletions(-) create mode 100644 native/tests/fixtures/demo3-player-damage.tsv diff --git a/native/src/sql/sim/inter.rs b/native/src/sql/sim/inter.rs index f72cd913..56fec4ee 100644 --- a/native/src/sql/sim/inter.rs +++ b/native/src/sql/sim/inter.rs @@ -920,13 +920,24 @@ pub mod hurt { /// 1 where the target's sector special is 11 and the damage reaches /// the clamp that keeps a hit there from killing outright. pub const PL_SECTOR11: usize = 23; + /// 1 where this call's own target is already in + /// [`hurt::HIT_TARGETS`]: the mobj fields a call answers with + /// (`HEALTH`, `FLAGS` and the rest) read the tic-start arrays + /// directly rather than an accumulator, so a second hit on a target + /// this tic has already hit once, in the same `damage_fold` list or a + /// later one chained after it, would overwrite the first's own + /// answer rather than build on it. + pub const SAME_TARGET: usize = 24; + /// Every target a hit has landed on this tic, threaded the same way + /// the player's own fields are. + pub const HIT_TARGETS: usize = 25; } /// The ClickHouse type of a [`hurt`] tuple, for a caller that carries one /// through a fold or a wider tuple of its own. pub const HURT_TYPE: &str = "Tuple(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, \ Int32, UInt32, Int32, UInt8, UInt8, Int32, UInt32, UInt8, Int32, \ - Int32, Int32, Int32, UInt32, UInt8, UInt8)"; + Int32, Int32, Int32, UInt32, UInt8, UInt8, UInt8, Array(UInt32))"; /// A call nobody made, for a caller that reads the first answer of a list /// that may be empty. @@ -934,14 +945,15 @@ pub fn no_hurt() -> String { "(toInt32(0), toInt32(0), toInt32(0), toInt32(0), toInt32(0), toInt32(0), toInt32(0), \ toInt32(0), toInt32(0), toUInt32(0), toInt32(0), toUInt8(0), toUInt8(0), toInt32(-1), \ toUInt32(0), toUInt8(0), toInt32(0), toInt32(0), toInt32(0), toInt32(0), toUInt32(0), \ - toUInt8(0), toUInt8(0))" + toUInt8(0), toUInt8(0), toUInt8(0), CAST([], 'Array(UInt32)'))" .to_owned() } /// The tic's own player fields, wrapped as a [`hurt`] tuple for the first /// [`damage_fold`] of the tic to start from: every other field the same as /// [`no_hurt`], since nothing but [`hurt::PL_HEALTH`] through -/// [`hurt::PL_ATTACKER`] is ever read off a fold's own seed. +/// [`hurt::PL_ATTACKER`] is ever read off a fold's own seed, and +/// [`hurt::HIT_TARGETS`] starts the tic empty. pub fn player_start( p_health: &str, p_armorpoints: &str, @@ -954,7 +966,7 @@ pub fn player_start( toInt32(0), toInt32(0), toUInt32(0), toInt32(0), toUInt8(0), toUInt8(0), toInt32(-1), \ toUInt32(0), toUInt8(0), toInt32({p_health}), toInt32({p_armorpoints}), \ toInt32({p_armortype}), toInt32({p_damagecount}), toUInt32({p_attacker}), toUInt8(0), \ - toUInt8(0))" + toUInt8(0), toUInt8(0), CAST([], 'Array(UInt32)'))" ) } @@ -1037,7 +1049,8 @@ pub fn damage_constants(db: &str) -> Vec<(String, String)> { /// A player's own health, armour, damage tint and attacker do not thread /// here the way [`damage_fold`]'s own accumulator threads them: nothing /// this runs for asks the player itself, so [`no_hurt`] stands in for the -/// player fields a body reads and never answers with. +/// player fields a body reads and never answers with, its own empty +/// [`hurt::HIT_TARGETS`] included. pub fn damage_mobj(asks: &str, world: &Hurting<'_>) -> String { let (values, body) = damaged(world, &no_hurt()); format!( @@ -1433,9 +1446,18 @@ fn damaged(world: &Hurting<'_>, player: &str) -> (Vec<(String, String)>, String) "dm_routine", "toInt32(if(dm_moves = 1, state_action[1 + dm_state], 0))".to_owned(), ); + // A target this tic has already hit once, in this call's own list or + // an earlier one chained into it: the mobj fields below read the + // tic-start arrays rather than an accumulator, so a second hit here + // would overwrite the first's own answer rather than build on it. + value( + "dm_same_target", + format!("toUInt8(has({player}.{}, dm_target))", hurt::HIT_TARGETS), + ); value( "dm_stuck", "toUInt8(dm_lands = 1 AND (dm_player_dies = 1 OR dm_sector11 = 1 \ + OR dm_same_target = 1 \ OR (dm_routine != 0 AND dm_routine != a_pain AND dm_routine != a_scream)))" .to_owned(), ); @@ -1500,6 +1522,12 @@ fn damaged(world: &Hurting<'_>, player: &str) -> (Vec<(String, String)>, String) ), "toUInt8(dm_player_dies)".to_owned(), "toUInt8(dm_sector11)".to_owned(), + "toUInt8(dm_same_target)".to_owned(), + format!( + "if(dm_lands = 1, arrayPushBack({player}.{}, dm_target), {player}.{})", + hurt::HIT_TARGETS, + hurt::HIT_TARGETS, + ), ]; (values, format!("({})", members.join(", "))) } @@ -1587,6 +1615,37 @@ mod damage_tests { assert!(stuck.1.contains("dm_sector11 = 1"), "{stuck:?}"); } + /// A target this tic has already hit once leaves a later hit on it + /// stuck too, whether that earlier hit came from this call's own + /// list or an earlier one chained into it through `player`: both read + /// the same `hurt::HIT_TARGETS` off `player`. + #[test] + fn a_target_this_tic_has_already_hit_leaves_a_later_hit_stuck() { + let (values, body) = damaged(&world(), "dm_held"); + let same_target = values + .iter() + .find(|(name, _)| name == "dm_same_target") + .expect("the call names what a repeat target is"); + assert!( + same_target + .1 + .contains(&format!("has(dm_held.{}, dm_target)", hurt::HIT_TARGETS)), + "{same_target:?}" + ); + let stuck = values + .iter() + .find(|(name, _)| name == "dm_stuck") + .expect("the call names what leaves it stuck"); + assert!(stuck.1.contains("dm_same_target = 1"), "{stuck:?}"); + assert!( + body.contains(&format!( + "arrayPushBack(dm_held.{}, dm_target)", + hurt::HIT_TARGETS + )), + "{body}" + ); + } + /// The routine reads no thing type it names by hand out of the /// generator: every one comes from `mobjtype` inside the statement. /// Two of them are bound by `enemy::constants` rather than here. diff --git a/native/src/sql/sim/mobj.rs b/native/src/sql/sim/mobj.rs index cbf97d48..18f59923 100644 --- a/native/src/sql/sim/mobj.rs +++ b/native/src/sql/sim/mobj.rs @@ -1022,6 +1022,15 @@ pub fn thinkers(state: &State) -> Vec<(String, String)> { sec = inter::hurt::PL_SECTOR11, ), ), + ( + unresolved::DM_SAME_TARGET, + &format!( + "arrayExists(t -> t.{hurt}.{same} = 1, mt_missile_thoughts) \ + OR mt_hurt.{same} = 1", + hurt = missile::thought::HURT, + same = inter::hurt::SAME_TARGET, + ), + ), ], ) ), @@ -1666,6 +1675,14 @@ pub fn thrown_thinks(state: &State) -> Vec<(String, String)> { sec = inter::hurt::PL_SECTOR11, ), ), + ( + unresolved::DM_SAME_TARGET, + &format!( + "arrayExists(t -> t.{hurt}.{same} = 1, tk_thoughts)", + hurt = missile::thought::HURT, + same = inter::hurt::SAME_TARGET, + ), + ), ], ), ); diff --git a/native/src/sql/sim/mod.rs b/native/src/sql/sim/mod.rs index 2ac0c59d..63e10ac7 100644 --- a/native/src/sql/sim/mod.rs +++ b/native/src/sql/sim/mod.rs @@ -168,10 +168,14 @@ pub mod unresolved { /// `P_DamageMobj`: the target's sector special is 11, and the damage /// reaches the clamp that keeps a hit there from killing outright. pub const SECTOR11_STUCK: u64 = 1 << 35; + /// `P_DamageMobj`: a hit lands on a target this tic has already hit + /// once, whether in the same `damage_fold` call or an earlier one + /// chained into it. + pub const DM_SAME_TARGET: u64 = 1 << 36; } /// Every bit `unresolved` names, in ascending order. -const UNRESOLVED_BITS: [(u64, &str); 36] = [ +const UNRESOLVED_BITS: [(u64, &str); 37] = [ (unresolved::PK_STUCK, "PK_STUCK"), (unresolved::PX_CROSSED, "PX_CROSSED"), (unresolved::PL_HURTS, "PL_HURTS"), @@ -208,6 +212,7 @@ const UNRESOLVED_BITS: [(u64, &str); 36] = [ (unresolved::TX_MULTI_CROSSED, "TX_MULTI_CROSSED"), (unresolved::PLAYER_DIES, "PLAYER_DIES"), (unresolved::SECTOR11_STUCK, "SECTOR11_STUCK"), + (unresolved::DM_SAME_TARGET, "DM_SAME_TARGET"), ]; /// The names of the bits `bits` sets, most significant last, for a message diff --git a/native/tests/fixtures/README.md b/native/tests/fixtures/README.md index 946b5982..8f26c6d9 100644 --- a/native/tests/fixtures/README.md +++ b/native/tests/fixtures/README.md @@ -16,9 +16,14 @@ drawn from gametic 341, with blood splats near enough that a sprite column reads past the end of its own lump. Frame 1000 is drawn from gametic 963, with the shotgun raised and the player somewhere else on the map. +Gametics 205 and 206 are the tic a thrown fireball reaches the player: the +row at 205 is what it stood at the moment before, and 206 is what +`P_DamageMobj`'s player branch left it at. + | File | What it is | |---|---| | `demo3-states.tsv` | One row per gametic a frame is drawn from, in the shape `refemu/probe/README.md` describes: frame index, gametic, frame hash, then every field of `clickdoom_spec::native_state`. | +| `demo3-player-damage.tsv` | The same shape, gametics 205 and 206 only. | | `demo3-frame0-*.bin`, `demo3-frame20-*.bin` | Two frames of the melt, which draws over a black screen rather than over the frame before it. | | `demo3-frame39-fb.bin`, `demo3-frame39-palette.bin` | The 64,000 bytes and 768-byte palette of frame 39, which frame 40 draws over. | | `demo3-frame40-fb.bin`, `demo3-frame40-palette.bin` | The same for frame 40, which the render test compares against. | diff --git a/native/tests/fixtures/demo3-player-damage.tsv b/native/tests/fixtures/demo3-player-damage.tsv new file mode 100644 index 00000000..65479242 --- /dev/null +++ b/native/tests/fixtures/demo3-player-damage.tsv @@ -0,0 +1,2 @@ +242 205 1edca038ef5d0085 205 15 13 0 0 0 0 84 84 4 [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [10419829,23068672,2097152,-65011712,-65011712,-56623104,9437184,24117248,-23068672,-23068672,-19922944,-17825792,-15728640,-13631488,-11534336,-2097152,-39845888,-47185920,-52428800,-60817408,88080384,-67108864,-93323264,-8388608,-8388608,-12582912,-14680064,18874368,23068672,23068672,20971520,20971520,-90177536,-85983232,-83886080,-88080384,2097152,5242880,5242880,-85983232,34603008,34603008,60817408,60817408,126877696,126877696,104857600,92274688,79691776,79691776,100663296,88080384,34603008,34603008,83886080,112197632,121634816,117440512,23068672,23068672,75497472,44040192,50331648,67108864,29360128,33554432,-4194304,-5242880,4194304,4194304,29360128,32505856,22020096,-16777216,-16777216,-16777216,-92274688,-4194304,2097152,-8388608,-8388608,34603008,83886080,-1048576,41943040,34603008,-16777216,41943040,-23720128,-26728128,-19022656,19366976,10337472,11544896,63783168,94371840,83292928,90177536,-16777216,2097152,48234496,41943040,48234496,48234496,37748736,31457280,6291456,2097152,31457280,56623104,56623104,31457280,39845888,20971520,29360128,40894464,48234496,10639439,17645824,52328256,54960256,46137344,-43139904,-58127104,-60817408,-62914560,-90177536,-50013952,-68602304,-48213376,-48679360,-63963136,-48234496,-72351744,-53477376,-68157440,-49283072,-44040192,-42991616,-8388608,80740352,-38797312,-59768832,-59768832,-24117248,-65011712,-114294784,-97517568,-104857600,-101711872,-93323264,-67108864,-54525952,-63963136,-58720256,-62914560,-78643200,-94371840,-93323264,-81788928,-73400320,-71303168,-63963136,-80740352,-54525952,-3145728,-92274688,24117248,-1048576,-7340032,-4194304,-4194304,23068672,29360128,29360128,-54525952,-60817408,-71303168,-59768832,-62914560,-66060288,-46137344,-46137344,-88080384,-92274688,-92274688,-83886080,-67108864,-59768832,-82837504,-8388608,25165824,16777216,50331648,39845888,4194304,-50331648,100663296,81788928,79691776,83886080,54525952,54525952,50331648,28311552,25165824,2097152,41943040,16777216,20971520,-19922944,53477376,79691776,91226112,88080384,94371840,88080384,88080384,62914560,38797312,-20971520,-5242880,-5242880,-5242880,-5242880,-62914560,-71303168,-50331648,-62914560,-62914560,-56623104,-97517568,-97517568,-108003328,-89128960,-79691776,63963136,50331648,50331648,37748736,57671680,29360128,24117248,17825792,12582912,4194304,23068672,29360128,7340032,37748736,12582912,-75497472,-22020096,-4194304,10485760,16777216,7340032,12850425,84934656,10485760,14680064,81788928,23068672,2097152,11078949,10848114] [14857119,20971520,20971520,23068672,12582912,12582912,-53477376,-53477376,-134217728,-137363456,-147849216,-147849216,-147849216,-147849216,-147849216,-115343360,-6291456,-94371840,-113246208,-87031808,-12582912,17825792,25165824,-6291456,2097152,2097152,3145728,-87031808,-87031808,-93323264,-95420416,36700160,-17825792,-22020096,-17825792,-19922944,-114294784,-114294784,-117440512,-174063616,-134217728,-123731968,-133169152,-118489088,-147849216,-154140672,-150994944,-150994944,-142606336,-146800640,-150994944,-150994944,-132120576,-127926272,-146800640,-147849216,-150994944,-150994944,-130023424,-134217728,-134217728,-150994944,-130023424,-121634816,-122683392,-171966464,-167772160,-162529280,-171966464,-155189248,-155189248,-122683392,-138412032,-135266304,-130023424,-140509184,-180355072,-109051904,-109051904,-142606336,-127926272,-130023424,-119537664,-154140672,-10485760,2097152,-29360128,-29360128,1445696,-47699648,-26590400,-26590400,-25541824,-18021824,-14500096,-23068672,-11989760,-14680064,20971520,-60817408,-69206016,-69206016,-65011712,-60817408,-69206016,-60817408,-60817408,-48234496,-48234496,-54525952,-77594624,-65011712,-81788928,-67108864,-41943040,10485760,16777216,677333,-5062912,-6190912,-5677184,-46137344,21644096,22475520,13631488,-14680064,-4194304,-10168064,-20367808,-24096128,-21416384,-34603008,-17825792,-22020096,-36700160,-26214400,-35651584,-65011712,-68157440,-29360128,-9437184,-68157440,-163577856,-166723584,-51380224,17825792,11534336,25165824,23068672,27262976,22020096,-96468992,-96468992,-75497472,-75497472,-104857600,-180355072,-182452224,-166723584,-155189248,-166723584,-156237824,-160432128,-165675008,-142606336,-38797312,27262976,-76546048,-97517568,-97517568,-97517568,-100663296,-104857600,-134217728,-138412032,-138412032,-142606336,-142606336,-113246208,-110100480,-88080384,-67108864,-121634816,-180355072,-176160768,-171966464,-180355072,-167772160,-152043520,-147849216,-171966464,-167772160,-175112192,-155189248,-134217728,-138412032,-176160768,-153092096,-154140672,-118489088,-134217728,-118489088,-133169152,-113246208,-99614720,-60817408,-56623104,-60817408,-55574528,-29360128,-26214400,-29360128,-40894464,-26214400,-49283072,-46137344,-9437184,-15728640,-20971520,2097152,25165824,3145728,-7340032,-4194304,0,-4194304,-12582912,-20971520,20971520,16777216,16777216,22020096,28311552,28311552,11534336,-4194304,-41943040,-46137344,-75497472,-57671680,-67108864,-82837504,-95420416,-95420416,-76546048,-79691776,-117440512,-147849216,-162529280,-62914560,0,-37748736,-88080384,-104857600,-146800640,18874368,17825792,11256496,-49283072,-29360128,-29360128,-73400320,25165824,25165824,12923838,8609355] [0,0,0,0,0,0,8388608,8388608,16252928,16252928,524288,524288,524288,524288,524288,5242880,524288,0,3145728,3145728,9437184,2097152,9961472,0,0,0,0,0,0,0,0,0,3145728,3145728,3145728,3145728,0,0,0,9437184,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3145728,3145728,3145728,7340032,4718592,4718592,3145728,3145728,3670016,3670016,3670016,0,0,3670016,3670016,0,0,3670016,3670016,3670016,1048576,0,9437184,9437184,9437184,0,8388608,8388608,8388608,8388608,8388608,8388608,8388608,8388608,8388608,8388608,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3145728,9961472,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3670016,9437184,3145728,7340032,7340032,0,0,9961472,9961472,9961472,9961472,9961472,3145728,3145728,3145728,3145728,3145728,7340032,7340032,7340032,7340032,7340032,7340032,7340032,7340032,3145728,0,9961472,0,4718592,4718592,4718592,4718592,0,3670016,3670016,3145728,3145728,7340032,3145728,3145728,3145728,3145728,3145728,7340032,7340032,7340032,7340032,7340032,7340032,7340032,3670016,3670016,3670016,3670016,3670016,2097152,0,3670016,3670016,3670016,3670016,3670016,3670016,3145728,0,8388608,8388608,8388608,8388608,3670016,3670016,1572864,1048576,1048576,2097152,9437184,9437184,9437184,0,0,0,0,0,0,0,3145728,3145728,3145728,0,0,0,9961472,9961472,9961472,9961472,3145728,0,0,0,0,0,0,0,0,0,0,3670016,3670016,3670016,8388608,0,3145728,0,4718592,524288,0,0,0,2097152,3670016,3670016,-524288,0,0,2097152,2097152] [3758096384,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2147483648,2147483648,2147483648,0,1073741824,1073741824,1073741824,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2147483648,2147483648,1073741824,1073741824,2147483648,2147483648,0,0,0,0,2147483648,2147483648,0,0,1610612736,1073741824,1073741824,2147483648,0,0,0,1610612736,0,3221225472,2147483648,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,536870912,1073741824,2147483648,2147483648,1070070366,1073741824,1610612736,2684354560,3758096384,2147483648,0,0,0,0,0,0,0,536870912,0,0,2147483648,0,0,0,1610612736,2147483648,0,0,0,1073741824,1610612736,1610612736,1610612736,0,1610612736,1610612736,3221225472,0,0,2147483648,1073741824,0,2684354560,0,0,0,0,0,0,0,0,0,0,0,536870912,536870912,0,0,3758096384,2147483648,3221225472,2147483648,0,3221225472,3221225472,3221225472,3221225472,0,1073741824,1073741824,0,0,0,0,0,0,0,0,3758096384,0,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,2684354560,0,0,0,0,0,3221225472,3221225472,1610612736,1073741824,0,0,2147483648,0,0,1381806976,1038726411] [28,94,94,94,94,94,94,94,30,30,69,85,79,88,79,76,70,75,94,94,64,62,63,30,30,30,85,0,0,30,79,78,30,39,0,84,84,0,29,89,94,94,94,94,94,94,0,0,29,29,30,30,84,84,68,69,0,30,0,29,0,29,29,29,92,29,29,0,29,29,29,68,68,29,29,29,81,69,69,57,57,57,57,57,117,117,84,84,29,29,29,29,0,0,0,0,30,30,78,78,85,80,80,68,68,29,29,29,29,68,113,84,0,0,0,68,78,0,0,29,29,30,0,0,0,68,68,0,0,29,29,57,57,57,57,84,84,0,0,69,69,69,0,0,69,69,39,30,29,29,69,30,30,29,29,79,30,30,30,39,79,57,57,57,57,68,0,57,60,60,60,61,61,61,61,61,61,61,61,61,61,61,61,60,60,61,61,61,61,61,61,61,61,61,61,61,61,61,60,60,60,60,60,61,61,60,60,60,60,60,60,60,60,60,61,61,61,61,61,61,61,60,60,61,61,61,60,60,60,60,60,60,60,60,60,60,60,60,61,61,61,61,61,61,61,61,61,61,61,90,55,55,56,81,86,57,57,39,0,84,84,73,94,94,18,18] [2,32768,32768,32768,32768,32768,32768,32768,1,0,0,0,0,0,0,32770,32770,32768,32768,32768,0,0,0,1,1,1,0,1,0,1,0,0,1,1,0,0,0,1,0,0,32768,32768,32768,32768,32768,32768,1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,1,0,0,0,0,0,0,1,1,0,0,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,3,3,3,3,4,0,1,1,2,0,0,0,0,0,0,0,0,1,1,0,0,0,32768,0,1,0,1,0,0,3,1,0,3,1,1,2,0,0,0,2,2,3,3,0,0,0,1,0,0,1,0,0,0,0,1,1,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,1,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,1,2,2,2,2,1,2,2,2,2,2,1,2,1,1,2,2,0,0,0,0,0,0,1,1,9,0,0,0,32770,32768,32768,32769,32771] [0,0,0,0,0,0,8388608,8388608,16252928,16252928,524288,524288,524288,524288,524288,5242880,524288,0,3145728,3145728,9437184,2097152,9961472,0,0,0,0,0,0,0,0,0,3145728,3145728,3145728,3145728,0,0,0,9437184,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3145728,3145728,3145728,7340032,4718592,4718592,3145728,3145728,3670016,3670016,3670016,0,0,3670016,3670016,0,0,3670016,3670016,3670016,1048576,0,9437184,9437184,9437184,0,8388608,8388608,8388608,8388608,8388608,8388608,8388608,8388608,8388608,8388608,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3145728,9961472,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3670016,9437184,3145728,7340032,7340032,0,0,9961472,9961472,9961472,9961472,9961472,3145728,3145728,3145728,3145728,3145728,7340032,7340032,7340032,7340032,7340032,7340032,7340032,7340032,3145728,0,9961472,0,4718592,4718592,4718592,4718592,0,3670016,3670016,3145728,3145728,7340032,3145728,3145728,3145728,3145728,3145728,7340032,7340032,7340032,7340032,7340032,7340032,7340032,3670016,3670016,3670016,3670016,3670016,2097152,0,3670016,3670016,3670016,3670016,3670016,3670016,3145728,0,8388608,8388608,8388608,8388608,3670016,3670016,1572864,1048576,1048576,2097152,9437184,9437184,9437184,0,0,0,0,0,0,0,3145728,3145728,3145728,0,0,0,9961472,9961472,9961472,9961472,3145728,0,0,0,0,0,0,0,0,0,0,3670016,3670016,3670016,8388608,0,3145728,0,4718592,524288,0,0,0,2097152,3670016,3670016,-524288,0,0,0,0] [4718592,4718592,4718592,16252928,16252928,16252928,16777216,16777216,20971520,20971520,16252928,16252928,16252928,16252928,16252928,10485760,16252928,4194304,10485760,10485760,16777216,16252928,18350080,7864320,7864320,7864320,7864320,4718592,4718592,4718592,4718592,8388608,7864320,7864320,7864320,7864320,4718592,4718592,4718592,20447232,8388608,8388608,12058624,12058624,7864320,7864320,8388608,8388608,8388608,8388608,8388608,8388608,8388608,8388608,8388608,12058624,12058624,12058624,8388608,8388608,12058624,8388608,12058624,12058624,8388608,8388608,11534336,11534336,11534336,11534336,8388608,8388608,8388608,16252928,16252928,16252928,15728640,13107200,8912896,16252928,16252928,8388608,12058624,11534336,13107200,13107200,9437184,9437184,4718592,4718592,9437184,9437184,9437184,8912896,13107200,16777216,16777216,16777216,4718592,16777216,16777216,16777216,16777216,16777216,16777216,16777216,16777216,16777216,16777216,9437184,9437184,9437184,9437184,9437184,9437184,4718592,4718592,4718592,13107200,13107200,13107200,4718592,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,9437184,16777216,16252928,15728640,15728640,4718592,16252928,18350080,18350080,18350080,18350080,18350080,10485760,10485760,10485760,10485760,10485760,15728640,15728640,15728640,15728640,15728640,15728640,15728640,15728640,11534336,9437184,18350080,4718592,13107200,13107200,13107200,13107200,8388608,8388608,8388608,11534336,11534336,11534336,10485760,10485760,10485760,16252928,16252928,15728640,15728640,15728640,15728640,15728640,15728640,15728640,11534336,8388608,8388608,8388608,12058624,9437184,16252928,8388608,8388608,12058624,12058624,12058624,12058624,9437184,8388608,16777216,16777216,16777216,16777216,9437184,9437184,9437184,13631488,13631488,8912896,17825792,16777216,16777216,13107200,13107200,4718592,7864320,7864320,7864320,7864320,16252928,16252928,16252928,16252928,16252928,16252928,18350080,18350080,18350080,18350080,7864320,4718592,4718592,9437184,9437184,9437184,4718592,4718592,4718592,4718592,4718592,9437184,8388608,11534336,16777216,4718592,16252928,16252928,13107200,5242880,4718592,4718592,4718592,8912896,9437184,9437184,13107200,8388608,8388608,4718592,4718592] [1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1048576,1048576,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1966080,1310720,1310720,1310720,1310720,1310720,1310720,1048576,1048576,1048576,1048576,1048576,1048576,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,655360,655360,655360,655360,655360,1048576,1048576,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1048576,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,655360,655360,655360,655360,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1966080,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1966080,1310720,655360,655360,655360,655360,1310720,1310720,655360,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,655360,655360,1966080,1310720,1310720,1310720,1310720,1048576,1048576,393216,393216] [3670016,1048576,1048576,1048576,1048576,1048576,1048576,1048576,3670016,3670016,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,3670016,3670016,3670016,1048576,3670016,3670016,3670016,1048576,1048576,3670016,3670016,3670016,1048576,1048576,3670016,3670016,1048576,1048576,1048576,1048576,1048576,1048576,1048576,3670016,3670016,3670016,3670016,3670016,3670016,1048576,1048576,1048576,1048576,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,1048576,3670016,3670016,3670016,3670016,3670016,3670016,1048576,1048576,3670016,3670016,3670016,1048576,1048576,1048576,2752512,2752512,2752512,2752512,2752512,1048576,1048576,1048576,1048576,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,1048576,1048576,1048576,1048576,1048576,1048576,1048576,3670016,3670016,3670016,3670016,1048576,1048576,1048576,3670016,3670016,3670016,1048576,1048576,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,1048576,1048576,3670016,3670016,3670016,3670016,2752512,2752512,2752512,2752512,1048576,1048576,3670016,3670016,1048576,1048576,1048576,3670016,3670016,1048576,1048576,3670016,3670016,3670016,3670016,1048576,3670016,3670016,3670016,3670016,1048576,3670016,3670016,3670016,3670016,1048576,2752512,2752512,2752512,2752512,1048576,3670016,2752512,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,2752512,2752512,917504,3670016,1048576,1048576,1048576,1048576,1048576,524288,524288] [-31105,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21998,0,0,0,0,0,0,-285410,0] [38150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8900,0,0,0,0,0,0,589940,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,81,81,81,81,81,81,81,2,2,54,70,64,73,64,60,55,59,81,81,49,47,48,2,2,2,70,11,11,2,64,63,2,12,11,69,69,11,1,74,81,81,81,81,81,81,11,11,1,1,2,2,69,69,53,54,11,2,11,1,11,1,1,1,77,1,1,11,1,1,1,53,53,1,1,1,66,54,54,30,30,30,30,30,98,98,69,69,1,1,1,1,11,11,11,11,2,2,63,63,70,65,65,53,53,1,1,1,1,53,100,69,11,11,11,53,63,11,11,1,1,2,11,11,11,53,53,11,11,1,1,30,30,30,30,69,69,11,11,54,54,54,11,11,54,54,12,2,1,1,54,2,2,1,1,64,2,2,2,12,64,30,30,30,30,53,11,30,45,45,45,46,46,46,46,46,46,46,46,46,46,46,46,45,45,46,46,46,46,46,46,46,46,46,46,46,46,46,45,45,45,45,45,46,46,45,45,45,45,45,45,45,45,45,46,46,46,46,46,46,46,45,45,46,46,46,45,45,45,45,45,45,45,45,45,45,45,45,46,46,46,46,46,46,46,46,46,46,46,75,43,43,44,66,71,30,30,13,11,69,69,58,81,81,31,31] [4,-1,-1,-1,-1,-1,-1,-1,10,2,-1,-1,-1,-1,-1,2,3,-1,-1,-1,3,1,1,8,7,8,-1,6,4,6,-1,-1,6,6,3,-1,-1,10,4,-1,-1,-1,-1,-1,-1,-1,7,1,5,2,1,5,-1,-1,-1,-1,1,6,2,9,9,4,8,1,-1,1,3,2,2,8,9,-1,-1,6,5,10,-1,-1,-1,3,4,5,6,6,-1,-1,-1,-1,2,2,1,4,3,3,3,9,2,3,-1,-1,-1,-1,-1,-1,-1,9,10,5,4,-1,-1,-1,9,2,10,-1,-1,2,3,4,4,9,1,1,4,-1,-1,2,2,4,2,5,3,3,6,-1,-1,7,2,-1,-1,-1,8,7,-1,-1,2,8,3,4,-1,1,1,10,8,-1,6,2,6,5,-1,1,5,2,2,-1,10,1,2,4,1,5,5,5,1,2,1,4,2,4,4,4,2,2,4,1,2,5,1,6,4,3,4,1,1,3,6,3,3,2,3,1,4,4,1,1,6,2,1,2,6,3,6,5,4,4,5,5,3,4,2,3,4,5,6,6,1,5,2,3,3,3,6,5,2,1,2,6,3,3,1,4,1,6,5,6,6,2,4,-1,6,6,2,-1,-1,6,6,7,1,-1,-1,2,-1,-1,1,2] [152,886,886,886,886,886,886,886,208,207,841,877,871,880,871,866,846,861,886,886,832,828,830,208,208,208,877,443,442,208,871,870,208,476,442,876,876,443,174,881,886,886,886,886,886,886,443,442,174,174,207,207,876,876,840,841,442,208,442,175,443,174,175,174,884,174,174,442,174,175,175,840,840,175,174,175,873,841,841,806,806,806,807,807,916,916,876,876,182,182,183,182,452,445,447,443,214,207,870,870,877,872,872,840,840,175,175,174,174,840,912,876,443,442,443,840,870,450,446,176,183,208,447,449,442,840,840,449,448,183,182,806,806,806,807,876,876,443,442,841,841,841,443,443,841,841,475,208,174,174,841,207,207,175,175,871,208,207,208,475,871,806,806,806,806,840,443,806,820,820,820,826,826,826,826,826,826,826,826,826,826,826,826,820,820,826,826,826,826,827,826,826,826,826,826,826,827,826,820,820,820,820,820,826,826,820,821,820,820,820,821,820,821,820,826,826,826,826,826,826,826,820,820,826,827,827,820,820,820,820,820,820,821,820,820,820,820,821,826,826,826,826,826,827,826,827,827,826,826,882,802,802,804,873,878,807,807,491,442,876,876,855,886,886,98,100] [33557510,2,2,2,2,2,2,2,4194342,4194342,1,1,1,1,1,8388609,8388609,1,2,2,33554433,33554433,33554433,4194310,4194310,4194310,1,4194310,4194310,4194310,1,1,4194310,4194310,4194310,1,1,4194310,4194310,1,2,2,2,2,2,2,4194310,4194310,4194310,4194310,4194310,4194310,1,1,1,1,4194342,4194342,4194342,4194310,4194310,4194310,4194310,4194310,1,4194310,4194310,4194342,4194310,4194342,4194342,1,1,4194342,4194342,4194342,1,1,1,524294,524294,524294,524294,524294,2,2,1,1,4194310,4194310,4194342,4194342,4194438,4194310,4194310,4194342,4194310,4194342,1,1,1,1,1,1,1,4194310,4194310,4194342,4194342,1,2,1,4194342,4194310,4194310,1,1,4194310,4194310,4194310,4194310,4194342,4194310,4194310,4194342,1,1,4194310,4194310,4194310,4194310,524294,524294,524294,524294,1,1,4194342,4194342,1,1,1,4194342,4194342,1,1,4194310,4194342,4194310,4194310,1,4194342,4194342,4194342,4194342,1,4194342,4194342,4194342,4194342,1,524294,524294,524294,524294,1,4194342,524294,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,1,1,1,1,1,1,524294,524294,5506114,4194342,1,1,8388641,2,2,67088,1552] [100,1000,1000,1000,1000,1000,1000,1000,30,30,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,30,30,30,1000,60,60,30,1000,1000,30,150,60,1000,1000,60,20,1000,1000,1000,1000,1000,1000,1000,60,60,20,20,30,30,1000,1000,1000,1000,60,30,60,20,60,20,20,20,1000,20,20,60,20,20,20,1000,1000,20,20,20,1000,1000,1000,20,20,20,20,20,1000,1000,1000,1000,20,20,20,20,60,60,60,60,30,30,1000,1000,1000,1000,1000,1000,1000,20,20,20,20,1000,1000,1000,60,60,60,1000,1000,50,60,20,20,30,60,60,60,1000,1000,60,60,20,20,20,20,20,20,1000,1000,60,60,1000,1000,1000,60,60,1000,1000,150,30,20,20,1000,30,30,20,20,1000,30,30,30,150,1000,20,20,20,20,1000,60,20,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,20,20,-19,60,1000,1000,1000,1000,1000,1000,1000] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,2,4,4,2,2,3,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,3,3,0,3,3,0,0,0,5,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,6,4,0,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,11,9,3,0,7,1,0,0,0,2,8,14,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,1,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,119,118] [0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,0,0,0,0,8,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,0,8,0,0,8,8,8,0,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,8,8,8,8,8,8,8,8] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,0,0,0,0,0,0,0,0] [0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1] [0,1,0,2,1,1,3,3,0,0,2,2,1,3,3,0,2,1,0,1,1,0,2,0,0,0,3,0,0,0,2,0,0,0,0,0,0,0,0,0,2,2,2,1,1,0,0,0,0,0,0,0,1,2,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,0,2,0,2,1,3,0,0,2,1,1,1,1,0,0,0,0,0,0,0,0,0,0,3,1,1,2,3,3,0,0,0,0,0,2,0,2,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,3,1,2,0,0,0,0,0,1,2,0,0,0,1,0,0,0,0,0,3,0,0,0,0,3,0,0,0,0,0,2,1,3,2,0,0,1,3,2,3,0,1,0,2,0,0,1,3,2,0,0,0,1,2,2,1,0,0,2,2,2,1,1,2,2,3,2,1,1,3,0,3,3,2,1,1,3,3,0,1,1,2,0,0,1,1,2,1,0,0,1,3,0,0,2,1,2,1,0,2,1,2,3,1,3,1,2,3,1,2,3,2,1,3,0,2,2,3,2,3,1,1,3,1,3,0,0,0,0,3,3,1,0,3,1] [0,352,32,-992,-992,-864,144,368,-352,-352,-304,-272,-240,-208,-176,-32,-608,-720,-800,-928,1344,-1024,-1424,-128,-128,-192,-224,288,352,352,320,320,-1376,-1312,-1280,-1344,32,80,80,-1312,528,528,928,928,1936,1936,1600,1408,1216,1216,1536,1344,528,528,1280,1712,1856,1792,352,352,1152,672,768,1024,448,512,-64,-80,64,64,448,496,336,-256,-256,-256,-1408,-64,32,-128,-128,528,1280,-16,640,528,-256,640,-448,-448,-48,432,384,0,1088,1440,1248,1376,-256,32,736,640,736,736,576,480,96,32,480,864,864,480,608,320,448,624,736,0,384,896,944,704,-720,-896,-928,-960,-1376,-832,-1152,-832,-768,-976,-736,-1104,-816,-1040,-752,-672,-656,-128,1232,-592,-912,-912,-368,-992,-1744,-1488,-1600,-1552,-1424,-1024,-832,-976,-896,-960,-1200,-1440,-1424,-1248,-1120,-1088,-976,-1232,-832,-48,-1408,368,-16,-112,-64,-64,352,448,448,-832,-928,-1088,-912,-960,-1008,-704,-704,-1344,-1408,-1408,-1280,-1024,-912,-1264,-128,384,256,768,608,64,-768,1536,1248,1216,1280,832,832,768,432,384,32,640,256,320,-304,816,1216,1392,1344,1440,1344,1344,960,592,-320,-80,-80,-80,-80,-960,-1088,-768,-960,-960,-864,-1488,-1488,-1648,-1360,-1216,976,768,768,576,880,448,368,272,192,64,352,448,112,576,192,-1152,-336,-64,160,256,112,192,1296,160,224,1248,352,32,0,0] [0,320,320,352,192,192,-816,-816,-2048,-2096,-2256,-2256,-2256,-2256,-2256,-1760,-96,-1440,-1728,-1328,-192,272,384,-96,32,32,48,-1328,-1328,-1424,-1456,560,-272,-336,-272,-304,-1744,-1744,-1792,-2656,-2048,-1888,-2032,-1808,-2256,-2352,-2304,-2304,-2176,-2240,-2304,-2304,-2016,-1952,-2240,-2256,-2304,-2304,-1984,-2048,-2048,-2304,-1984,-1856,-1872,-2624,-2560,-2480,-2624,-2368,-2368,-1872,-2112,-2064,-1984,-2144,-2752,-1664,-1664,-2176,-1952,-1984,-1824,-2352,-160,32,-448,-448,-64,-832,-400,-400,-400,-400,-336,-352,-272,-224,320,-928,-1056,-1056,-992,-928,-1056,-928,-928,-736,-736,-832,-1184,-992,-1248,-1024,-640,160,256,-192,-192,-192,-144,-704,336,320,208,-224,-64,-256,-384,-448,-384,-528,-272,-336,-560,-400,-544,-992,-1040,-448,-144,-1040,-2496,-2544,-784,272,176,384,352,416,336,-1472,-1472,-1152,-1152,-1600,-2752,-2784,-2544,-2368,-2544,-2384,-2448,-2528,-2176,-592,416,-1168,-1488,-1488,-1488,-1536,-1600,-2048,-2112,-2112,-2176,-2176,-1728,-1680,-1344,-1024,-1856,-2752,-2688,-2624,-2752,-2560,-2320,-2256,-2624,-2560,-2672,-2368,-2048,-2112,-2688,-2336,-2352,-1808,-2048,-1808,-2032,-1728,-1520,-928,-864,-928,-848,-448,-400,-448,-624,-400,-752,-704,-144,-240,-320,32,384,48,-112,-64,0,-64,-192,-320,320,256,256,336,432,432,176,-64,-640,-704,-1152,-880,-1024,-1264,-1456,-1456,-1168,-1216,-1792,-2256,-2480,-960,0,-576,-1344,-1600,-2240,288,272,-192,-752,-448,-448,-1120,384,384,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,180,180,180,0,90,90,90,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,180,180,90,90,180,180,0,0,0,0,180,180,0,0,135,90,90,180,0,0,0,135,0,270,180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,45,90,90,90,90,90,135,225,270,180,0,0,0,0,0,0,0,45,0,0,180,0,0,0,135,180,0,0,0,45,135,45,45,0,225,180,270,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,45,45,0,0,315,180,270,180,0,270,270,270,270,0,90,90,0,0,0,0,0,0,0,0,315,0,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,225,0,0,0,0,0,270,270,90,90,0,0,180,0,0,0,0] [0,2028,2028,2028,2028,2028,2028,2028,9,9,2012,2049,2048,2002,2048,2026,2013,2025,2028,2028,6,5,13,9,9,9,2049,3001,3001,9,2048,2007,9,3002,3001,2008,2008,3001,3004,2005,2028,2028,2028,2028,2028,2028,3001,3001,3004,3004,9,9,2008,2008,2011,2012,3001,9,3001,3004,3001,3004,3004,3004,2001,3004,3004,3001,3004,3004,3004,2011,2011,3004,3004,3004,2046,2012,2012,2035,2035,2035,2035,2035,48,48,2008,2008,3004,3004,3004,3004,3001,3001,3001,3001,9,9,2007,2007,2049,2010,2010,2011,2011,3004,3004,3004,3004,2011,35,2008,3001,3001,3001,2011,2007,3001,3001,3004,3004,9,3001,3001,3001,2011,2011,3001,3001,3004,3004,2035,2035,2035,2035,2008,2008,3001,3001,2012,2012,2012,3001,3001,2012,2012,3002,9,3004,3004,2012,9,9,3004,3004,2048,9,9,9,3002,2048,2035,2035,2035,2035,2011,3001,2035,2014,2014,2014,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2014,2014,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2014,2014,2014,2014,2014,2015,2015,2014,2014,2014,2014,2014,2014,2014,2014,2014,2015,2015,2015,2015,2015,2015,2015,2014,2014,2015,2015,2015,2014,2014,2014,2014,2014,2014,2014,2014,2014,2014,2014,2014,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2003,2018,2018,2019,2046,8,2035,2035,58,3001,2008,2008,2024,2028,2028,0,0] [0,7,7,7,7,7,7,7,15,14,7,7,7,7,7,7,7,7,7,7,7,7,7,6,7,7,7,6,7,6,7,7,7,6,6,7,7,6,7,7,7,7,7,7,7,7,6,6,7,7,6,6,7,7,7,7,14,14,14,7,6,7,7,6,7,7,6,14,6,14,14,7,7,15,14,14,7,7,7,7,7,7,7,7,7,7,7,7,7,7,15,15,6,6,7,15,6,14,7,7,7,7,7,7,7,7,6,14,14,7,7,7,15,6,6,7,7,6,6,7,6,14,7,6,14,7,7,7,6,6,6,7,7,7,7,7,7,15,14,6,6,6,15,14,3,3,7,15,6,6,7,15,14,14,14,7,15,14,14,14,7,7,7,7,7,7,14,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,15,7,7,15,7,7,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [145,146,146,197,197,197,77,79,306,306,394,394,394,394,394,335,178,422,331,405,113,199,184,157,157,157,157,449,449,449,449,143,171,171,171,171,336,336,336,370,231,215,214,214,284,284,249,249,254,249,249,249,215,215,249,295,277,278,334,350,259,222,214,255,215,227,384,384,379,373,229,215,350,299,300,299,360,466,444,299,299,215,255,390,106,104,32,103,213,36,32,103,103,136,105,112,113,113,211,75,99,99,100,97,98,81,75,74,78,44,243,70,242,70,68,121,118,151,148,105,115,90,200,197,197,163,174,179,166,179,179,0,179,169,1,0,10,14,14,103,113,14,355,354,35,197,186,184,184,184,184,403,397,405,405,408,353,360,359,371,354,356,355,353,324,67,184,450,463,463,463,463,439,231,231,324,324,323,332,408,403,14,328,361,360,360,361,354,355,371,392,383,380,223,220,341,391,249,249,255,257,214,214,218,238,82,75,97,73,103,32,63,51,50,46,47,113,113,105,115,211,157,157,157,157,163,169,179,197,197,197,184,184,184,188,173,48,90,243,92,44,244,449,449,450,447,333,231,382,98,151,0,429,466,376,145,145,145,46,103,103,268,143,143,145,151] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [7,6,7,7,7,6,7,7,6,6,5,5,6,6,6,7] [26,34,36,37,73,112,117,128,129,139,141,142,158,159,160,169] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [-1,0,1,1,-1,0,1,-1,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] [0,3,0,0,0,2,0,0,33,1,1,5,31,31,31,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [112,112,80,80,96,144,144,96,128,112,255,255,128,128,128,128] [255,255,255,80,255,255,255,255,192,192,255,255,255,255,255,176] [0,15,0,0,0,35,0,0,35,35,7,7,35,35,35,0] [0,5,0,0,0,5,0,0,5,5,64,64,5,5,5,0] [1,1,1,1,1,1,1,1,1,1,1,1,1,1,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] [3145728,3145728,3145728,0,4194304,3145728,4718592,3145728,1572864,2097152,2621440,3145728,3670016,0,1572864,524288,1048576,1572864,-2097152,-2097152,0,2097152,2097152,9437184,0,2097152,1048576,9437184,524288,524288,1048576,1572864,2097152,0,0,8388608,8388608,17301504,0,0,0,0,2621440,3145728,0,0,5767168,9437184,0,0,5767168,0,0,0,524288,1048576,1572864,2097152,2621440,3145728,0,0,0,0,0,0,4194304,3145728,3145728,3145728,9961472,524288,524288,9961472,-1572864,11534336,2097152,0,0,0,3670016,3670016,5242880,2621440,3145728,3670016,3670016,3670016,0,0,524288,1048576,1572864,2097152,0,0,-1048576,0,0,0,3670016,5242880,5242880,5767168,3670016,5767168,-524288,-1048576,3670016,3670016,5242880,5242880,3670016,3670016,3670016,2621440,3145728,16252928,5242880,0,0,5242880,5242880,5242880,3145728,7340032,3145728,3145728,3670016,5242880,0,0,0,2097152,524288,9437184,524288,1048576,1572864,7340032,15728640,8388608,9437184,8912896,3670016,0,5242880,524288,524288,524288,0,0,0,524288,1048576,1572864,2097152,2621440,0,0,0,4718592,0,0,0,1572864,3145728,3670016,4194304,4718592] [16252928,10485760,3145728,16252928,7864320,16252928,16252928,10485760,7864320,7864320,7864320,9437184,9437184,4718592,3670016,7864320,7864320,3670016,13107200,4718592,9437184,7340032,8912896,17825792,4718592,3670016,13631488,16777216,5242880,9437184,9437184,9437184,9437184,9437184,5767168,16777216,16777216,17825792,4718592,0,4718592,0,9437184,9437184,13107200,9437184,7864320,16777216,4718592,9437184,7864320,13107200,4718592,8912896,8912896,8912896,8912896,8912896,8912896,8912896,8388608,4718592,4456448,4718592,7864320,0,7864320,7864320,7864320,3145728,16252928,16252928,524288,18350080,16252928,14155776,16252928,16252928,4718592,0,12058624,8388608,7340032,9437184,9437184,8388608,8388608,8388608,8388608,0,9437184,9437184,9437184,9437184,4718592,0,-1048576,4718592,13107200,4718592,8388608,7340032,7340032,11010048,3670016,11010048,13107200,13107200,12058624,11010048,7340032,7340032,7864320,8388608,3670016,9437184,16252928,20971520,16252928,16252928,16252928,16252928,16252928,9961472,11534336,11534336,11534336,3145728,9437184,10485760,4718592,4718592,0,9437184,5242880,9437184,9437184,9437184,9437184,15728640,20447232,20447232,20447232,11534336,11534336,16252928,9961472,16252928,16252928,524288,4194304,4718592,0,8912896,8912896,8912896,8912896,8912896,8388608,8388608,8388608,8912896,4718592,4718592,0,3670016,8912896,8912896,8912896,13107200] [46,46,46,53,43,46,47,46,41,41,41,41,41,46,43,41,41,43,23,23,46,43,35,16,46,43,35,41,46,41,41,41,41,46,46,16,35,35,46,46,46,46,41,41,46,46,43,41,46,46,43,46,46,46,41,41,41,41,41,41,46,46,46,46,46,46,43,46,46,46,15,46,46,35,53,43,47,46,46,46,46,46,43,36,36,46,46,46,46,46,36,36,36,36,46,46,46,46,23,23,46,43,43,43,46,43,40,23,46,46,43,43,46,46,46,36,46,46,47,53,53,47,47,47,46,15,46,46,46,47,46,46,46,36,46,46,36,36,36,35,35,35,35,43,46,53,43,46,46,46,53,53,53,11,11,11,11,11,46,46,46,11,46,46,46,43,11,11,11,11] [128,128,128,144,144,144,144,128,160,160,160,176,192,144,160,160,160,160,192,128,128,128,128,176,112,112,247,255,112,192,192,192,192,224,255,112,207,80,144,144,112,112,192,192,128,128,192,112,255,128,192,128,255,144,144,144,144,144,144,144,144,255,144,255,144,144,144,128,128,128,96,144,144,135,128,128,128,128,128,144,144,96,144,144,144,255,144,144,128,128,144,144,144,144,128,128,128,128,192,144,144,144,144,144,144,144,192,192,144,144,144,144,255,144,144,144,144,223,144,144,144,144,144,128,112,112,144,144,135,128,128,128,128,144,128,144,144,144,144,192,255,255,255,255,160,144,160,144,144,144,128,144,128,144,144,144,144,144,128,128,128,144,255,128,128,255,128,128,128,136] [0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,9,0,0,7,7,7,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,1,0,0,1,1,1,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,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0] [1,1,0,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,2,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,1,0,0,1,2,1,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,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,98,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,88,62,88,0,0,0,0,0,0,0,0,62,88,88,88,0,0,0,0,0,0,0,0,0,0,0,0,0,88,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,91,91,91,91,91,91,0,1,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,22,0,0,0,0,0,0,0,0,0,1,0,0,0,90,90,90,0,0,0,0,0,0,0,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,62,62,88,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,88,0,0,0,0,0,27,27,0,0,27,27,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,62,0,0,0,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,34,70,91,62,0,0,0,0,0,0,0,27,0,0,0,0,0,0,0,0,48,48,48,48,1,0,0,0,0,0,0,0,27,1,0,0,0,0,0,0,0,0,0,0,31,0,0,0,0,0,0,0,0] [0,0,70,0,70,0,70,0,0,0,70,0,70,0,70,0,70,0,0,0,0,0,70,0,70,0,0,0,0,0,0,0,0,0,70,0,0,0,0,70,70,0,0,0,0,0,0,0,0,0,0,41,0,41,0,41,0,41,0,41,0,0,0,41,0,0,0,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,0,70,0,70,0,0,0,0,0,0,0,0,0,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,0,41,0,0,0,70,0,0,0,0,0,0,0,0,70,0,0,0,0,70,0,70,0,0,41,0,0,0,24,0,0,0,24,120,0,0,0,0,0,66,0,66,0,0,0,0,66,0,0,0,0,0,0,0,0,0,0,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,66,0,41,0,0,0,0,0,0,0,41,66,0,0,0,0,0,0,0,0,0,66,0,0,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,0,0,0,0,0,0,0,64,0,0,0,64,0,0,0,64,0,0,66,0,0,64,0,0,0,41,0,41,0,0,0,0,0,70,0,0,0,0,0,0,0,70,0,0,70,0,0,0,70,0,0,0,0,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,64,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,64,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,0,0,0,0,64,0,0,0,66,0,64,0,0,0,0,0,0,0,0,66,0,66,0,0,0,66,0,0,66,0,0,0,41,0,0,0,0,0,0,0,24,0,0,0,0,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,24,24,24,0,0,0,0,0,0,120,0,120,0,120,0,120,0,120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,120,0,120,0,0,120,0,120,0,120,0,0,0,0,0,0,0,0,0,120,0,120,0,120,0,120,0,120,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,0,0,0,0,3,0,3,0,0,0,0,0,0,0,0,0,0,66,66,66,66,66,66,66,66,66,66,0,0,0,0,0,0,0,0,0,0,0,64,0,64,0,64,0,64,0,64,0,64,0,2,0,2,0,0,0,0,0,64,0,0,0,0,0,0,0,64,0,64,0,0,0,0,0,0,0,64,0,0,0,0,0,64,64,0,0,70,0,0,64,0,0,0,0,64,0,64,0,64,0,0,64,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,95,0,0,0,0,0,77,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,77,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,81,27,56,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,0,24,120,24,120,24,120,24,120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65,0,0,0,0,0,0,3,0,3,0,0,0,3,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,120,0,0,24,120,70,0,0,66,0,0,0,0,0,0,66,0,0,70,0,0,70,0,0,0,0,0,0,70,0,0,66,0,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,77,0,0,0,64,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,14,0,66,0,66,0,14,0,0,0,0,0,0,0,0,0,0,0,14,0,120,0,120,0,14,0,0,0,0,0,0,0,0,36,0,36,0,0,0,0,0,0,0,0,0,14,0,66,0,0,0,0,66,0,14,0,0,0,0,0,14,0,14,0,0,14,0,0,0,0,0,0,0,0,0,120,0,120,0,0,0,0,0,0,0,0,0,0,0,0,0,50,50,0,70,0,0,0,66,0,0,14,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,95,64,0,64,65,65,37,24,37,24,37,24,37,24,0,0,0,0,0,14,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,65,0,66,0,0,0,0,0,0,0,0,0,0,0,3,0,3,0,0,0,15,0,0,0,0,0] [70,70,0,0,0,0,0,0,70,70,0,0,0,0,0,0,0,0,70,70,70,70,0,0,0,0,33,33,33,33,70,70,70,70,0,0,70,70,70,0,0,70,70,70,70,70,70,70,70,70,70,0,0,0,0,0,0,0,0,0,0,81,81,0,0,48,48,0,0,70,70,70,70,70,70,70,70,70,70,70,70,70,70,47,0,0,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,70,70,70,70,70,70,70,70,70,70,66,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,70,70,70,70,70,70,70,70,70,70,66,0,0,0,0,44,44,0,0,70,70,70,70,70,70,70,0,0,70,70,70,0,0,0,0,70,0,0,44,44,0,0,120,122,0,0,66,66,66,66,44,0,0,0,0,44,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,66,66,66,66,66,66,66,66,66,66,66,66,66,48,48,66,34,34,0,0,0,0,0,0,120,120,120,120,120,120,0,0,0,0,0,0,0,0,0,0,0,0,66,66,66,0,0,66,66,66,66,66,66,64,64,0,0,0,0,64,64,64,64,64,64,64,64,64,64,64,64,34,0,0,64,64,64,64,64,64,0,0,64,64,0,0,64,64,0,0,66,0,0,33,0,0,33,66,0,0,0,0,64,64,64,47,0,0,33,33,47,70,70,70,0,0,70,0,0,70,70,0,0,70,81,70,0,0,0,0,0,0,0,0,64,64,0,0,0,0,0,0,0,0,0,0,64,33,33,33,33,64,64,64,64,0,0,33,33,64,64,0,0,70,70,70,0,0,64,64,16,16,16,16,16,16,16,16,81,33,33,0,0,64,64,66,66,66,66,64,64,64,0,0,33,33,0,0,0,0,66,66,66,66,66,66,66,0,0,0,0,66,66,0,0,66,0,0,33,33,0,0,70,70,44,44,30,24,0,0,81,33,33,0,0,81,64,70,47,64,64,70,70,70,70,70,81,70,81,70,81,81,70,81,34,34,81,0,0,0,0,70,81,81,70,70,81,81,70,70,81,81,64,70,32,32,70,70,81,81,70,81,81,81,81,24,24,24,24,24,0,0,0,0,0,0,70,81,81,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,24,24,24,24,24,24,24,24,24,66,66,66,0,0,0,0,0,0,0,0,0,0,81,81,81,81,66,66,66,66,0,0,0,0,0,0,0,0,0,0,24,24,24,24,24,24,24,24,0,0,24,24,66,66,66,66,66,66,66,0,0,0,0,34,34,66,66,66,31,31,31,31,0,0,0,0,0,0,0,0,0,0,66,66,66,66,64,81,81,81,81,66,0,0,0,0,0,0,0,0,0,0,0,0,34,0,0,0,0,64,64,64,64,0,0,0,0,0,0,64,64,0,0,0,0,64,64,64,0,0,64,0,0,64,64,64,64,0,0,70,70,0,0,64,0,0,64,34,34,0,0,0,0,0,0,64,0,0,64,64,64,64,64,0,0,66,66,0,0,0,0,64,64,64,64,64,0,0,64,64,64,64,70,70,70,70,70,0,0,70,81,81,70,70,70,81,81,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,34,34,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,0,0,64,64,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,66,64,81,66,81,66,87,66,66,66,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,0,0,0,0,81,81,24,24,24,24,24,24,24,24,24,24,65,65,0,0,24,24,0,0,0,0,0,0,0,0,24,24,24,24,24,24,24,24,24,81,81,24,24,81,81,81,65,65,65,65,0,0,70,81,34,35,34,0,0,0,0,34,34,0,0,0,0,35,70,35,35,70,24,120,120,120,120,122,43,43,0,0,122,122,0,0,0,0,66,0,0,66,34,66,66,34,0,0,70,0,0,70,0,0,34,34,70,70,70,0,0,66,0,0,66,0,0,34,34,66,66,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,66,0,0,64,64,64,0,0,0,0,66,66,93,66,66,66,66,81,81,66,66,81,81,66,66,81,81,66,81,66,66,81,0,0,66,66,66,33,14,33,33,33,14,0,0,0,0,0,0,0,0,14,14,33,33,120,120,33,33,33,33,0,0,0,0,0,0,0,0,88,14,14,14,15,15,15,0,0,0,0,66,120,66,66,33,14,14,33,0,0,0,0,66,33,14,0,0,0,0,66,14,33,14,0,0,0,0,14,0,0,66,66,66,66,120,120,122,122,0,0,0,0,120,120,121,121,81,50,50,81,66,66,66,66,0,0,70,0,0,70,66,0,0,66,0,0,0,0,33,33,14,33,33,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,64,64,64,0,0,70,70,70,34,70,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,14,15,15,15,15,0,0,15,15,0,0,0,0,0,0,0,0,0,0,66,66,34,34,34,34,66,0,0,0,0,70,70,70,70,70,70,34,34,70,70,0,0,0,0,81,81,0,0,81,70,70,81] [0,0,0,0,0,0,0,0,0,0,70,0,70,0,70,0,70,0,0,0,0,0,70,0,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,0,0,0,0,0,0,0,0,0,0,0,76,0,76,0,76,0,76,0,76,0,0,0,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,76,0,76,0,76,0,76,0,76,0,76,0,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,0,76,0,76,0,76,0,76,0,76,0,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,120,0,0,24,0,0,0,0,0,0,0,0,0,0,0,0,73,0,73,0,73,0,73,0,73,0,73,0,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,74,0,0,0,0,0,0,0,76,0,76,0,76,0,76,0,76,0,76,0,0,0,0,66,77,0,0,0,0,0,0,0,0,16,41,16,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,64,0,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,0,0,0,0,0,70,0,0,70,0,0,0,70,0,0,0,0,0,0,16,0,16,0,16,0,0,0,53,0,53,0,53,0,64,0,53,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,64,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,0,0,0,0,0,0,0,0,0,0,64,0,0,0,66,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,0,0,66,0,0,0,41,0,0,0,0,0,0,0,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,120,0,56,0,24,0,0,0,0,0,24,0,24,0,24,0,24,0,56,0,24,0,24,0,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,0,56,0,120,0,120,0,120,0,0,0,0,0,0,0,0,0,24,0,24,0,24,0,24,0,24,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,16,0,16,0,16,0,16,0,16,0,0,0,41,0,41,0,0,0,0,0,41,53,0,53,41,0,0,0,0,64,0,0,0,0,53,41,0,0,41,0,0,0,0,0,0,0,0,70,0,0,64,64,0,0,0,53,0,53,0,53,0,0,64,0,0,0,0,0,0,64,0,0,0,53,41,53,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,53,41,53,41,53,41,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,95,0,0,0,0,76,0,76,0,76,0,76,0,76,0,76,0,76,0,76,0,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,81,0,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,81,0,0,0,24,0,24,0,24,0,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,0,0,0,0,0,3,0,3,0,0,0,3,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,70,0,0,66,0,0,0,0,0,0,66,0,0,70,0,0,70,0,0,0,0,0,0,70,0,0,66,0,0,66,0,0,0,0,0,0,120,0,120,0,120,0,120,0,120,0,120,0,120,0,120,0,0,0,0,0,0,0,0,64,0,53,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,66,0,66,0,14,0,0,0,0,0,0,0,0,0,0,0,14,0,120,0,120,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,66,0,0,0,0,66,0,14,0,0,0,0,0,14,0,14,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,0,66,0,0,14,0,14,0,0,0,0,0,0,0,0,0,64,0,64,0,64,0,64,0,64,0,64,0,16,0,16,0,16,0,16,0,16,0,16,0,0,0,0,0,53,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,56,56,0,0,0,0,0,0,0,0,15,0,15,0,0,14,0,0,0,0,0,0,14,0,0,0,16,0,16,0,16,0,16,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5505024,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14680064,0,0,0,4456448,3407872,2359296,1310720,0,1048576,2097152,3145728,4194304,5373952,0,0,0,0,0,0,0,0,0,0,262144,262144,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2097152,4194304,6291456,8388608,10485760,12582912,0,2097152,4194304,6291456,8388608,0,2097152,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2097152,4194304,6291456,8388608,10485760,0,2097152,4194304,6291456,8388608,10485760,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,262144,262144,0,0,262144,262144,0,0,0,0,0,0,0,0,0,0,262144,262144,0,0,0,0,0,0,0,0,0,12582912,0,0,0,0,12582912,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4194304,0,0,0,2097152,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3145728,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,262144,262144,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2097152,4194304,6291456,8388608,10485760,12582912,14680064,8388608,10485760,12582912,14680064,0,2097152,4194304,6291456,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12582912,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4194304,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6291456,0,0,0,2097152,0,2097152,0,0,2097152,0,2097152,0,6291456,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2097152,0,0,0,2097152,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13434880,0,13434880,0,13434880,0,13434880,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,262144,262144,0,0,0,0,0,0] [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-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,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,63,61,62,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124] [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,52,53,51,54,55] 1 0 -8 0 -256 1 2692140 2686976 0 11253 100 0 0 [0,0,0,0,0,0] [0,0,0,0,0,0] 0 2 10 [1,1,1,0,0,0,0,0,0] [60,10,0,0] [200,50,300,50] 1 0 0 1 1 0 0 0 0 0 0 0 0 [26,-1] [1,0] [602121,602121] [2900895,2900895] 2 13 0 5 [1,1,1,0,0,0,0,0,0] 100 66 0 100 0 205 1 2 262077856542286207 0 5 1 0 +243 206 9c26fce70e6d1843 206 24 14 0 0 0 0 84 84 4 [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [10388724,23068672,2097152,-65011712,-65011712,-56623104,9437184,24117248,-23068672,-23068672,-19922944,-17825792,-15728640,-13631488,-11534336,-2097152,-39845888,-47185920,-52428800,-60817408,88080384,-67108864,-93323264,-8388608,-8388608,-12582912,-14680064,18874368,23068672,23068672,20971520,20971520,-90177536,-85983232,-83886080,-88080384,2097152,5242880,5242880,-85983232,34603008,34603008,60817408,60817408,126877696,126877696,104857600,92274688,79691776,79691776,100663296,88080384,34603008,34603008,83886080,112197632,121634816,117440512,23068672,23068672,75497472,44040192,50331648,67108864,29360128,33554432,-4194304,-5242880,4194304,4194304,29360128,32505856,22020096,-16777216,-16777216,-16777216,-92274688,-4194304,2097152,-8388608,-8388608,34603008,83886080,-1048576,41943040,34603008,-16777216,41943040,-23720128,-26728128,-19546944,19366976,10337472,11544896,63783168,94371840,83292928,90177536,-16777216,2097152,48234496,41943040,48234496,48234496,37748736,31457280,6291456,2097152,31457280,56623104,56623104,31457280,39845888,20971520,29360128,40894464,48234496,10639439,17645824,52328256,54960256,46137344,-43515904,-57602816,-60817408,-62914560,-90177536,-50013952,-68602304,-48213376,-48679360,-63963136,-48234496,-72351744,-53477376,-68157440,-49283072,-44040192,-42991616,-8388608,80740352,-38797312,-59768832,-59768832,-24117248,-65011712,-114294784,-97517568,-104857600,-101711872,-93323264,-67108864,-54525952,-63963136,-58720256,-62914560,-78643200,-94371840,-93323264,-81788928,-73400320,-71303168,-63963136,-80740352,-54525952,-3145728,-92274688,24117248,-1048576,-7340032,-4194304,-4194304,23068672,29360128,29360128,-54525952,-60817408,-71303168,-59768832,-62914560,-66060288,-46137344,-46137344,-88080384,-92274688,-92274688,-83886080,-67108864,-59768832,-82837504,-8388608,25165824,16777216,50331648,39845888,4194304,-50331648,100663296,81788928,79691776,83886080,54525952,54525952,50331648,28311552,25165824,2097152,41943040,16777216,20971520,-19922944,53477376,79691776,91226112,88080384,94371840,88080384,88080384,62914560,38797312,-20971520,-5242880,-5242880,-5242880,-5242880,-62914560,-71303168,-50331648,-62914560,-62914560,-56623104,-97517568,-97517568,-108003328,-89128960,-79691776,63963136,50331648,50331648,37748736,57671680,29360128,24117248,17825792,12582912,4194304,23068672,29360128,7340032,37748736,12582912,-75497472,-22020096,-4194304,10485760,16777216,7340032,12872423,84934656,10485760,14680064,81788928,23068672,2097152,11078949,10848114] [14895269,20971520,20971520,23068672,12582912,12582912,-53477376,-53477376,-134217728,-137363456,-147849216,-147849216,-147849216,-147849216,-147849216,-115343360,-6291456,-94371840,-113246208,-87031808,-12582912,17825792,25165824,-6291456,2097152,2097152,3145728,-87031808,-87031808,-93323264,-95420416,36700160,-17825792,-22020096,-17825792,-19922944,-114294784,-114294784,-117440512,-174063616,-134217728,-123731968,-133169152,-118489088,-147849216,-154140672,-150994944,-150994944,-142606336,-146800640,-150994944,-150994944,-132120576,-127926272,-146800640,-147849216,-150994944,-150994944,-130023424,-134217728,-134217728,-150994944,-130023424,-121634816,-122683392,-171966464,-167772160,-162529280,-171966464,-155189248,-155189248,-122683392,-138412032,-135266304,-130023424,-140509184,-180355072,-109051904,-109051904,-142606336,-127926272,-130023424,-119537664,-154140672,-10485760,2097152,-29360128,-29360128,1445696,-47699648,-26590400,-26590400,-25541824,-18021824,-14500096,-23068672,-11989760,-14680064,20971520,-60817408,-69206016,-69206016,-65011712,-60817408,-69206016,-60817408,-60817408,-48234496,-48234496,-54525952,-77594624,-65011712,-81788928,-67108864,-41943040,10485760,16777216,677333,-5062912,-6190912,-5677184,-46137344,22020096,22475520,13631488,-14680064,-4194304,-10168064,-20367808,-24096128,-21416384,-34603008,-17825792,-22020096,-36700160,-26214400,-35651584,-65011712,-68157440,-29360128,-9437184,-68157440,-163577856,-166723584,-51380224,17825792,11534336,25165824,23068672,27262976,22020096,-96468992,-96468992,-75497472,-75497472,-104857600,-180355072,-182452224,-166723584,-155189248,-166723584,-156237824,-160432128,-165675008,-142606336,-38797312,27262976,-76546048,-97517568,-97517568,-97517568,-100663296,-104857600,-134217728,-138412032,-138412032,-142606336,-142606336,-113246208,-110100480,-88080384,-67108864,-121634816,-180355072,-176160768,-171966464,-180355072,-167772160,-152043520,-147849216,-171966464,-167772160,-175112192,-155189248,-134217728,-138412032,-176160768,-153092096,-154140672,-118489088,-134217728,-118489088,-133169152,-113246208,-99614720,-60817408,-56623104,-60817408,-55574528,-29360128,-26214400,-29360128,-40894464,-26214400,-49283072,-46137344,-9437184,-15728640,-20971520,2097152,25165824,3145728,-7340032,-4194304,0,-4194304,-12582912,-20971520,20971520,16777216,16777216,22020096,28311552,28311552,11534336,-4194304,-41943040,-46137344,-75497472,-57671680,-67108864,-82837504,-95420416,-95420416,-76546048,-79691776,-117440512,-147849216,-162529280,-62914560,0,-37748736,-88080384,-104857600,-146800640,18874368,17825792,11265396,-49283072,-29360128,-29360128,-73400320,25165824,25165824,12923838,8609355] [0,0,0,0,0,0,8388608,8388608,16252928,16252928,524288,524288,524288,524288,524288,5242880,524288,0,3145728,3145728,9437184,2097152,9961472,0,0,0,0,0,0,0,0,0,3145728,3145728,3145728,3145728,0,0,0,9437184,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3145728,3145728,3145728,7340032,4718592,4718592,3145728,3145728,3670016,3670016,3670016,0,0,3670016,3670016,0,0,3670016,3670016,3670016,1048576,0,9437184,9437184,9437184,0,8388608,8388608,8388608,8388608,8388608,8388608,8388608,8388608,8388608,8388608,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3145728,9961472,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3670016,9437184,3145728,7340032,7340032,0,0,9961472,9961472,9961472,9961472,9961472,3145728,3145728,3145728,3145728,3145728,7340032,7340032,7340032,7340032,7340032,7340032,7340032,7340032,3145728,0,9961472,0,4718592,4718592,4718592,4718592,0,3670016,3670016,3145728,3145728,7340032,3145728,3145728,3145728,3145728,3145728,7340032,7340032,7340032,7340032,7340032,7340032,7340032,3670016,3670016,3670016,3670016,3670016,2097152,0,3670016,3670016,3670016,3670016,3670016,3670016,3145728,0,8388608,8388608,8388608,8388608,3670016,3670016,1572864,1048576,1048576,2097152,9437184,9437184,9437184,0,0,0,0,0,0,0,3145728,3145728,3145728,0,0,0,9961472,9961472,9961472,9961472,3145728,0,0,0,0,0,0,0,0,0,0,3670016,3670016,3670016,8388608,0,3145728,0,4718592,524288,0,0,0,2097152,3670016,3670016,-524288,0,0,2097152,2097152] [3758096384,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2147483648,2147483648,2147483648,0,1073741824,1073741824,1073741824,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2147483648,2147483648,1073741824,1073741824,2147483648,2147483648,0,0,0,0,2147483648,2147483648,0,0,1610612736,1073741824,1073741824,2147483648,0,0,0,1610612736,0,3221225472,2147483648,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,536870912,1073741824,2147483648,2147483648,1070070366,1073741824,1610612736,2684354560,3758096384,2147483648,0,0,0,0,0,0,0,536870912,0,0,2147483648,0,0,0,1610612736,2147483648,0,0,0,1073741824,1610612736,1610612736,1610612736,0,1610612736,1610612736,3221225472,0,0,2147483648,1073741824,0,2684354560,0,0,0,0,0,0,0,0,0,0,0,536870912,536870912,0,0,3758096384,2147483648,3221225472,2147483648,0,3221225472,3221225472,3221225472,3221225472,0,1073741824,1073741824,0,0,0,0,0,0,0,0,3758096384,0,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,3221225472,2684354560,0,0,0,0,0,3221225472,3221225472,1610612736,1073741824,0,0,2147483648,0,0,1381806976,1038726411] [28,94,94,94,94,94,94,94,30,30,69,85,79,88,79,76,70,75,94,94,64,62,63,30,30,30,85,0,0,30,79,78,30,39,0,84,84,0,29,89,94,94,94,94,94,94,0,0,29,29,30,30,84,84,68,69,0,30,0,29,0,29,29,29,92,29,29,0,29,29,29,68,68,29,29,29,81,69,69,57,57,57,57,57,117,117,84,84,29,29,29,29,0,0,0,0,30,30,78,78,85,80,80,68,68,29,29,29,29,68,113,84,0,0,0,68,78,0,0,29,29,30,0,0,0,68,68,0,0,29,29,57,57,57,57,84,84,0,0,69,69,69,0,0,69,69,39,30,29,29,69,30,30,29,29,79,30,30,30,39,79,57,57,57,57,68,0,57,60,60,60,61,61,61,61,61,61,61,61,61,61,61,61,60,60,61,61,61,61,61,61,61,61,61,61,61,61,61,60,60,60,60,60,61,61,60,60,60,60,60,60,60,60,60,61,61,61,61,61,61,61,60,60,61,61,61,60,60,60,60,60,60,60,60,60,60,60,60,61,61,61,61,61,61,61,61,61,61,61,90,55,55,56,81,86,57,57,39,0,84,84,73,94,94,18,18] [6,32768,32768,32768,32768,32768,32768,32768,1,0,0,0,0,0,0,32770,32770,32768,32768,32768,0,32769,32769,1,1,1,0,1,0,1,0,0,1,1,0,0,0,1,0,0,32768,32768,32768,32768,32768,32768,1,1,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,1,0,1,0,0,0,1,1,0,0,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,3,3,0,3,4,0,1,1,2,0,0,0,0,0,0,0,0,1,1,0,0,0,32768,0,1,0,1,0,0,3,1,0,3,1,2,3,0,0,0,2,2,3,3,0,0,0,1,0,0,1,0,0,0,0,1,1,0,0,0,1,0,0,0,1,1,1,1,0,1,0,1,0,0,1,0,0,0,0,1,1,2,2,1,2,2,2,1,2,1,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,1,1,2,1,2,2,2,2,1,2,2,1,1,1,2,1,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,1,1,1,2,2,2,2,2,1,2,2,1,2,1,2,2,1,2,1,1,2,1,1,2,2,0,0,0,0,0,0,1,1,9,1,0,0,32770,32768,32768,32770,32771] [0,0,0,0,0,0,8388608,8388608,16252928,16252928,524288,524288,524288,524288,524288,5242880,524288,0,3145728,3145728,9437184,2097152,9961472,0,0,0,0,0,0,0,0,0,3145728,3145728,3145728,3145728,0,0,0,9437184,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3145728,3145728,3145728,7340032,4718592,4718592,3145728,3145728,3670016,3670016,3670016,0,0,3670016,3670016,0,0,3670016,3670016,3670016,1048576,0,9437184,9437184,9437184,0,8388608,8388608,8388608,8388608,8388608,8388608,8388608,8388608,8388608,8388608,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3145728,9961472,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3145728,3670016,9437184,3145728,7340032,7340032,0,0,9961472,9961472,9961472,9961472,9961472,3145728,3145728,3145728,3145728,3145728,7340032,7340032,7340032,7340032,7340032,7340032,7340032,7340032,3145728,0,9961472,0,4718592,4718592,4718592,4718592,0,3670016,3670016,3145728,3145728,7340032,3145728,3145728,3145728,3145728,3145728,7340032,7340032,7340032,7340032,7340032,7340032,7340032,3670016,3670016,3670016,3670016,3670016,2097152,0,3670016,3670016,3670016,3670016,3670016,3670016,3145728,0,8388608,8388608,8388608,8388608,3670016,3670016,1572864,1048576,1048576,2097152,9437184,9437184,9437184,0,0,0,0,0,0,0,3145728,3145728,3145728,0,0,0,9961472,9961472,9961472,9961472,3145728,0,0,0,0,0,0,0,0,0,0,3670016,3670016,3670016,8388608,0,3145728,0,4718592,524288,0,0,0,2097152,3670016,3670016,-524288,0,0,0,0] [4718592,4718592,4718592,16252928,16252928,16252928,16777216,16777216,20971520,20971520,16252928,16252928,16252928,16252928,16252928,10485760,16252928,4194304,10485760,10485760,16777216,16252928,18350080,7864320,7864320,7864320,7864320,4718592,4718592,4718592,4718592,8388608,7864320,7864320,7864320,7864320,4718592,4718592,4718592,20447232,8388608,8388608,12058624,12058624,7864320,7864320,8388608,8388608,8388608,8388608,8388608,8388608,8388608,8388608,8388608,12058624,12058624,12058624,8388608,8388608,12058624,8388608,12058624,12058624,8388608,8388608,11534336,11534336,11534336,11534336,8388608,8388608,8388608,16252928,16252928,16252928,15728640,13107200,8912896,16252928,16252928,8388608,12058624,11534336,13107200,13107200,9437184,9437184,4718592,4718592,9437184,9437184,9437184,8912896,13107200,16777216,16777216,16777216,4718592,16777216,16777216,16777216,16777216,16777216,16777216,16777216,16777216,16777216,16777216,9437184,9437184,9437184,9437184,9437184,9437184,4718592,4718592,4718592,13107200,13107200,13107200,4718592,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,16252928,9437184,16777216,16252928,15728640,15728640,4718592,16252928,18350080,18350080,18350080,18350080,18350080,10485760,10485760,10485760,10485760,10485760,15728640,15728640,15728640,15728640,15728640,15728640,15728640,15728640,11534336,9437184,18350080,4718592,13107200,13107200,13107200,13107200,8388608,8388608,8388608,11534336,11534336,11534336,10485760,10485760,10485760,16252928,16252928,15728640,15728640,15728640,15728640,15728640,15728640,15728640,11534336,8388608,8388608,8388608,12058624,9437184,16252928,8388608,8388608,12058624,12058624,12058624,12058624,9437184,8388608,16777216,16777216,16777216,16777216,9437184,9437184,9437184,13631488,13631488,8912896,17825792,16777216,16777216,13107200,13107200,4718592,7864320,7864320,7864320,7864320,16252928,16252928,16252928,16252928,16252928,16252928,18350080,18350080,18350080,18350080,7864320,4718592,4718592,9437184,9437184,9437184,4718592,4718592,4718592,4718592,4718592,9437184,8388608,11534336,16777216,4718592,16252928,16252928,13107200,5242880,4718592,4718592,4718592,8912896,9437184,9437184,13107200,8388608,8388608,4718592,4718592] [1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1048576,1048576,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1966080,1310720,1310720,1310720,1310720,1310720,1310720,1048576,1048576,1048576,1048576,1048576,1048576,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,655360,655360,655360,655360,655360,1048576,1048576,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1048576,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,655360,655360,655360,655360,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1966080,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1966080,1310720,655360,655360,655360,655360,1310720,1310720,655360,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,1310720,655360,655360,1966080,1310720,1310720,1310720,1310720,1048576,1048576,393216,393216] [3670016,1048576,1048576,1048576,1048576,1048576,1048576,1048576,3670016,3670016,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,3670016,3670016,3670016,1048576,3670016,3670016,3670016,1048576,1048576,3670016,3670016,3670016,1048576,1048576,3670016,3670016,1048576,1048576,1048576,1048576,1048576,1048576,1048576,3670016,3670016,3670016,3670016,3670016,3670016,1048576,1048576,1048576,1048576,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,1048576,3670016,3670016,3670016,3670016,3670016,3670016,1048576,1048576,3670016,3670016,3670016,1048576,1048576,1048576,2752512,2752512,2752512,2752512,2752512,1048576,1048576,1048576,1048576,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,1048576,1048576,1048576,1048576,1048576,1048576,1048576,3670016,3670016,3670016,3670016,1048576,1048576,1048576,3670016,3670016,3670016,1048576,1048576,3670016,3670016,3670016,3670016,3670016,3670016,3670016,3670016,1048576,1048576,3670016,3670016,3670016,3670016,2752512,2752512,2752512,2752512,1048576,1048576,3670016,3670016,1048576,1048576,1048576,3670016,3670016,1048576,1048576,3670016,3670016,3670016,3670016,1048576,3670016,3670016,3670016,3670016,1048576,3670016,3670016,3670016,3670016,1048576,2752512,2752512,2752512,2752512,1048576,3670016,2752512,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,1048576,2752512,2752512,917504,3670016,1048576,1048576,1048576,1048576,1048576,524288,524288] [-76958,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19935,0,0,0,0,0,0,0,0] [173728,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8065,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,81,81,81,81,81,81,81,2,2,54,70,64,73,64,60,55,59,81,81,49,47,48,2,2,2,70,11,11,2,64,63,2,12,11,69,69,11,1,74,81,81,81,81,81,81,11,11,1,1,2,2,69,69,53,54,11,2,11,1,11,1,1,1,77,1,1,11,1,1,1,53,53,1,1,1,66,54,54,30,30,30,30,30,98,98,69,69,1,1,1,1,11,11,11,11,2,2,63,63,70,65,65,53,53,1,1,1,1,53,100,69,11,11,11,53,63,11,11,1,1,2,11,11,11,53,53,11,11,1,1,30,30,30,30,69,69,11,11,54,54,54,11,11,54,54,12,2,1,1,54,2,2,1,1,64,2,2,2,12,64,30,30,30,30,53,11,30,45,45,45,46,46,46,46,46,46,46,46,46,46,46,46,45,45,46,46,46,46,46,46,46,46,46,46,46,46,46,45,45,45,45,45,46,46,45,45,45,45,45,45,45,45,45,46,46,46,46,46,46,46,45,45,46,46,46,45,45,45,45,45,45,45,45,45,45,45,45,46,46,46,46,46,46,46,46,46,46,46,75,43,43,44,66,71,30,30,13,11,69,69,58,81,81,31,31] [4,-1,-1,-1,-1,-1,-1,-1,9,1,-1,-1,-1,-1,-1,1,2,-1,-1,-1,2,10,10,7,6,7,-1,5,3,5,-1,-1,5,5,2,-1,-1,9,3,-1,-1,-1,-1,-1,-1,-1,6,10,4,1,10,4,-1,-1,-1,-1,10,5,1,8,8,3,7,10,-1,10,2,1,1,7,8,-1,-1,5,4,9,-1,-1,-1,2,3,4,5,5,-1,-1,-1,-1,1,1,4,3,2,2,2,8,1,2,-1,-1,-1,-1,-1,-1,-1,8,9,4,3,-1,-1,-1,8,1,9,-1,-1,1,2,3,3,8,3,3,3,-1,-1,1,1,3,1,4,2,2,5,-1,-1,6,1,-1,-1,-1,7,6,-1,-1,1,7,2,3,-1,10,10,9,7,-1,5,1,5,4,-1,6,4,1,1,-1,9,6,1,3,6,4,4,4,6,1,6,3,1,3,3,3,1,1,3,6,1,4,6,5,3,2,3,6,6,2,5,2,2,1,2,6,3,3,6,6,5,1,6,1,5,2,5,4,3,3,4,4,2,3,1,2,3,4,5,5,6,4,1,2,2,2,5,4,1,6,1,5,2,2,6,3,6,5,4,5,5,1,3,-1,5,5,1,-1,-1,5,5,6,10,-1,-1,1,-1,-1,4,1] [156,886,886,886,886,886,886,886,208,207,841,877,871,880,871,866,846,861,886,886,832,829,831,208,208,208,877,443,442,208,871,870,208,476,442,876,876,443,174,881,886,886,886,886,886,886,443,443,174,174,208,207,876,876,840,841,443,208,442,175,443,174,175,175,884,175,174,442,174,175,175,840,840,175,174,175,873,841,841,806,806,806,807,807,916,916,876,876,182,182,176,182,452,445,447,443,214,207,870,870,877,872,872,840,840,175,175,174,174,840,912,876,443,442,443,840,870,450,446,176,183,208,448,450,442,840,840,449,448,183,182,806,806,806,807,876,876,443,442,841,841,841,443,443,841,841,475,208,174,174,841,208,208,175,175,871,208,207,208,475,871,807,806,806,806,840,443,807,820,820,821,826,826,826,827,826,827,826,826,826,826,826,826,820,820,827,826,826,827,827,826,826,826,827,827,826,827,826,820,820,820,821,820,826,827,821,821,820,821,820,821,820,821,820,826,826,826,826,826,826,826,820,820,826,827,827,821,820,820,820,820,820,821,820,820,821,820,821,826,826,827,826,827,827,826,827,827,826,826,882,802,802,804,873,878,807,807,491,443,876,876,855,886,886,99,100] [33557574,2,2,2,2,2,2,2,4194342,4194342,1,1,1,1,1,8388609,8388609,1,2,2,33554433,33554433,33554433,4194310,4194310,4194310,1,4194310,4194310,4194310,1,1,4194310,4194310,4194310,1,1,4194310,4194310,1,2,2,2,2,2,2,4194310,4194310,4194310,4194310,4194310,4194310,1,1,1,1,4194342,4194342,4194342,4194310,4194310,4194310,4194310,4194310,1,4194310,4194310,4194342,4194310,4194342,4194342,1,1,4194342,4194342,4194342,1,1,1,524294,524294,524294,524294,524294,2,2,1,1,4194310,4194310,4194342,4194342,4194438,4194310,4194310,4194342,4194310,4194342,1,1,1,1,1,1,1,4194310,4194310,4194342,4194342,1,2,1,4194342,4194310,4194310,1,1,4194310,4194310,4194310,4194310,4194342,4194310,4194310,4194342,1,1,4194310,4194310,4194310,4194310,524294,524294,524294,524294,1,1,4194342,4194342,1,1,1,4194342,4194342,1,1,4194310,4194342,4194310,4194310,1,4194342,4194342,4194342,4194342,1,4194342,4194342,4194342,4194342,1,524294,524294,524294,524294,1,4194342,524294,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,8388609,1,1,1,1,1,1,524294,524294,5506114,4194342,1,1,8388641,2,2,1552,1552] [82,1000,1000,1000,1000,1000,1000,1000,30,30,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,30,30,30,1000,60,60,30,1000,1000,30,150,60,1000,1000,60,20,1000,1000,1000,1000,1000,1000,1000,60,60,20,20,30,30,1000,1000,1000,1000,60,30,60,20,60,20,20,20,1000,20,20,60,20,20,20,1000,1000,20,20,20,1000,1000,1000,20,20,20,20,20,1000,1000,1000,1000,20,20,20,20,60,60,60,60,30,30,1000,1000,1000,1000,1000,1000,1000,20,20,20,20,1000,1000,1000,60,60,60,1000,1000,50,60,20,20,30,60,60,60,1000,1000,60,60,20,20,20,20,20,20,1000,1000,60,60,1000,1000,1000,60,60,1000,1000,150,30,20,20,1000,30,30,20,20,1000,30,30,30,150,1000,20,20,20,20,1000,60,20,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,20,20,-19,60,1000,1000,1000,1000,1000,1000,1000] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,2,4,4,2,2,3,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,3,3,0,3,0,0,0,0,5,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,5,4,0,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,11,9,3,0,6,2,0,0,0,2,8,14,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0] [119,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,1,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,119,118] [0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,0,0,0,0,8,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,0,8,0,0,8,8,8,0,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,8,8,8,8,8,8,8,8] [100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,0,0,0,0,0,0,0,0] [0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1] [0,1,0,2,1,1,3,3,0,0,2,2,1,3,3,0,2,1,0,1,1,0,2,0,0,0,3,0,0,0,2,0,0,0,0,0,0,0,0,0,2,2,2,1,1,0,0,0,0,0,0,0,1,2,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,0,2,0,2,1,3,0,0,2,1,1,1,1,0,0,0,0,0,0,0,0,0,0,3,1,1,2,3,3,0,0,0,0,0,2,0,2,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,3,1,2,0,0,0,0,0,1,2,0,0,0,1,0,0,0,0,0,3,0,0,0,0,3,0,0,0,0,0,2,1,3,2,0,0,1,3,2,3,0,1,0,2,0,0,1,3,2,0,0,0,1,2,2,1,0,0,2,2,2,1,1,2,2,3,2,1,1,3,0,3,3,2,1,1,3,3,0,1,1,2,0,0,1,1,2,1,0,0,1,3,0,0,2,1,2,1,0,2,1,2,3,1,3,1,2,3,1,2,3,2,1,3,0,2,2,3,2,3,1,1,3,1,3,0,0,0,0,3,3,1,0,3,1] [0,352,32,-992,-992,-864,144,368,-352,-352,-304,-272,-240,-208,-176,-32,-608,-720,-800,-928,1344,-1024,-1424,-128,-128,-192,-224,288,352,352,320,320,-1376,-1312,-1280,-1344,32,80,80,-1312,528,528,928,928,1936,1936,1600,1408,1216,1216,1536,1344,528,528,1280,1712,1856,1792,352,352,1152,672,768,1024,448,512,-64,-80,64,64,448,496,336,-256,-256,-256,-1408,-64,32,-128,-128,528,1280,-16,640,528,-256,640,-448,-448,-48,432,384,0,1088,1440,1248,1376,-256,32,736,640,736,736,576,480,96,32,480,864,864,480,608,320,448,624,736,0,384,896,944,704,-720,-896,-928,-960,-1376,-832,-1152,-832,-768,-976,-736,-1104,-816,-1040,-752,-672,-656,-128,1232,-592,-912,-912,-368,-992,-1744,-1488,-1600,-1552,-1424,-1024,-832,-976,-896,-960,-1200,-1440,-1424,-1248,-1120,-1088,-976,-1232,-832,-48,-1408,368,-16,-112,-64,-64,352,448,448,-832,-928,-1088,-912,-960,-1008,-704,-704,-1344,-1408,-1408,-1280,-1024,-912,-1264,-128,384,256,768,608,64,-768,1536,1248,1216,1280,832,832,768,432,384,32,640,256,320,-304,816,1216,1392,1344,1440,1344,1344,960,592,-320,-80,-80,-80,-80,-960,-1088,-768,-960,-960,-864,-1488,-1488,-1648,-1360,-1216,976,768,768,576,880,448,368,272,192,64,352,448,112,576,192,-1152,-336,-64,160,256,112,192,1296,160,224,1248,352,32,0,0] [0,320,320,352,192,192,-816,-816,-2048,-2096,-2256,-2256,-2256,-2256,-2256,-1760,-96,-1440,-1728,-1328,-192,272,384,-96,32,32,48,-1328,-1328,-1424,-1456,560,-272,-336,-272,-304,-1744,-1744,-1792,-2656,-2048,-1888,-2032,-1808,-2256,-2352,-2304,-2304,-2176,-2240,-2304,-2304,-2016,-1952,-2240,-2256,-2304,-2304,-1984,-2048,-2048,-2304,-1984,-1856,-1872,-2624,-2560,-2480,-2624,-2368,-2368,-1872,-2112,-2064,-1984,-2144,-2752,-1664,-1664,-2176,-1952,-1984,-1824,-2352,-160,32,-448,-448,-64,-832,-400,-400,-400,-400,-336,-352,-272,-224,320,-928,-1056,-1056,-992,-928,-1056,-928,-928,-736,-736,-832,-1184,-992,-1248,-1024,-640,160,256,-192,-192,-192,-144,-704,336,320,208,-224,-64,-256,-384,-448,-384,-528,-272,-336,-560,-400,-544,-992,-1040,-448,-144,-1040,-2496,-2544,-784,272,176,384,352,416,336,-1472,-1472,-1152,-1152,-1600,-2752,-2784,-2544,-2368,-2544,-2384,-2448,-2528,-2176,-592,416,-1168,-1488,-1488,-1488,-1536,-1600,-2048,-2112,-2112,-2176,-2176,-1728,-1680,-1344,-1024,-1856,-2752,-2688,-2624,-2752,-2560,-2320,-2256,-2624,-2560,-2672,-2368,-2048,-2112,-2688,-2336,-2352,-1808,-2048,-1808,-2032,-1728,-1520,-928,-864,-928,-848,-448,-400,-448,-624,-400,-752,-704,-144,-240,-320,32,384,48,-112,-64,0,-64,-192,-320,320,256,256,336,432,432,176,-64,-640,-704,-1152,-880,-1024,-1264,-1456,-1456,-1168,-1216,-1792,-2256,-2480,-960,0,-576,-1344,-1600,-2240,288,272,-192,-752,-448,-448,-1120,384,384,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,180,180,180,0,90,90,90,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,180,180,90,90,180,180,0,0,0,0,180,180,0,0,135,90,90,180,0,0,0,135,0,270,180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,45,90,90,90,90,90,135,225,270,180,0,0,0,0,0,0,0,45,0,0,180,0,0,0,135,180,0,0,0,45,135,45,45,0,225,180,270,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,45,45,0,0,315,180,270,180,0,270,270,270,270,0,90,90,0,0,0,0,0,0,0,0,315,0,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,225,0,0,0,0,0,270,270,90,90,0,0,180,0,0,0,0] [0,2028,2028,2028,2028,2028,2028,2028,9,9,2012,2049,2048,2002,2048,2026,2013,2025,2028,2028,6,5,13,9,9,9,2049,3001,3001,9,2048,2007,9,3002,3001,2008,2008,3001,3004,2005,2028,2028,2028,2028,2028,2028,3001,3001,3004,3004,9,9,2008,2008,2011,2012,3001,9,3001,3004,3001,3004,3004,3004,2001,3004,3004,3001,3004,3004,3004,2011,2011,3004,3004,3004,2046,2012,2012,2035,2035,2035,2035,2035,48,48,2008,2008,3004,3004,3004,3004,3001,3001,3001,3001,9,9,2007,2007,2049,2010,2010,2011,2011,3004,3004,3004,3004,2011,35,2008,3001,3001,3001,2011,2007,3001,3001,3004,3004,9,3001,3001,3001,2011,2011,3001,3001,3004,3004,2035,2035,2035,2035,2008,2008,3001,3001,2012,2012,2012,3001,3001,2012,2012,3002,9,3004,3004,2012,9,9,3004,3004,2048,9,9,9,3002,2048,2035,2035,2035,2035,2011,3001,2035,2014,2014,2014,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2014,2014,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2014,2014,2014,2014,2014,2015,2015,2014,2014,2014,2014,2014,2014,2014,2014,2014,2015,2015,2015,2015,2015,2015,2015,2014,2014,2015,2015,2015,2014,2014,2014,2014,2014,2014,2014,2014,2014,2014,2014,2014,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2003,2018,2018,2019,2046,8,2035,2035,58,3001,2008,2008,2024,2028,2028,0,0] [0,7,7,7,7,7,7,7,15,14,7,7,7,7,7,7,7,7,7,7,7,7,7,6,7,7,7,6,7,6,7,7,7,6,6,7,7,6,7,7,7,7,7,7,7,7,6,6,7,7,6,6,7,7,7,7,14,14,14,7,6,7,7,6,7,7,6,14,6,14,14,7,7,15,14,14,7,7,7,7,7,7,7,7,7,7,7,7,7,7,15,15,6,6,7,15,6,14,7,7,7,7,7,7,7,7,6,14,14,7,7,7,15,6,6,7,7,6,6,7,6,14,7,6,14,7,7,7,6,6,6,7,7,7,7,7,7,15,14,6,6,6,15,14,3,3,7,15,6,6,7,15,14,14,14,7,15,14,14,14,7,7,7,7,7,7,14,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,15,7,7,15,7,7,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [145,146,146,197,197,197,77,79,306,306,394,394,394,394,394,335,178,422,331,405,113,199,184,157,157,157,157,449,449,449,449,143,171,171,171,171,336,336,336,370,231,215,214,214,284,284,249,249,254,249,249,249,215,215,249,295,277,278,334,350,259,222,214,255,215,227,384,384,379,373,229,215,350,299,300,299,360,466,444,299,299,215,255,390,106,104,32,103,213,36,32,103,103,136,105,112,113,113,211,75,99,99,100,97,98,81,75,74,78,44,243,70,242,70,68,121,118,151,148,105,115,90,200,197,197,163,174,179,166,179,179,0,179,169,1,0,10,14,14,103,113,14,355,354,35,197,186,184,184,184,184,403,397,405,405,408,353,360,359,371,354,356,355,353,324,67,184,450,463,463,463,463,439,231,231,324,324,323,332,408,403,14,328,361,360,360,361,354,355,371,392,383,380,223,220,341,391,249,249,255,257,214,214,218,238,82,75,97,73,103,32,63,51,50,46,47,113,113,105,115,211,157,157,157,157,163,169,179,197,197,197,184,184,184,188,173,48,90,243,92,44,244,449,449,450,447,333,231,382,98,151,0,429,466,376,145,145,145,46,103,103,268,143,143,145,151] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [7,6,7,7,7,6,7,7,6,6,5,5,6,6,6,7] [26,34,36,37,73,112,117,128,129,139,141,142,158,159,160,169] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [-1,0,1,-1,-1,0,1,-1,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] [0,2,0,0,0,1,0,0,32,35,4,4,30,30,30,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [112,112,80,80,96,144,144,96,128,112,255,255,128,128,128,128] [255,255,255,80,255,255,255,255,192,192,255,255,255,255,255,176] [0,15,0,0,0,35,0,0,35,35,7,7,35,35,35,0] [0,5,0,0,0,5,0,0,5,5,64,64,5,5,5,0] [1,1,1,1,1,1,1,1,1,1,1,1,1,1,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] [3145728,3145728,3145728,0,4194304,3145728,4718592,3145728,1572864,2097152,2621440,3145728,3670016,0,1572864,524288,1048576,1572864,-2097152,-2097152,0,2097152,2097152,9437184,0,2097152,1048576,9437184,524288,524288,1048576,1572864,2097152,0,0,8388608,8388608,17301504,0,0,0,0,2621440,3145728,0,0,5767168,9437184,0,0,5767168,0,0,0,524288,1048576,1572864,2097152,2621440,3145728,0,0,0,0,0,0,4194304,3145728,3145728,3145728,9961472,524288,524288,9961472,-1572864,11534336,2097152,0,0,0,3670016,3670016,5242880,2621440,3145728,3670016,3670016,3670016,0,0,524288,1048576,1572864,2097152,0,0,-1048576,0,0,0,3670016,5242880,5242880,5767168,3670016,5767168,-524288,-1048576,3670016,3670016,5242880,5242880,3670016,3670016,3670016,2621440,3145728,16252928,5242880,0,0,5242880,5242880,5242880,3145728,7340032,3145728,3145728,3670016,5242880,0,0,0,2097152,524288,9437184,524288,1048576,1572864,7340032,15728640,8388608,9437184,8912896,3670016,0,5242880,524288,524288,524288,0,0,0,524288,1048576,1572864,2097152,2621440,0,0,0,4718592,0,0,0,1572864,3145728,3670016,4194304,4718592] [16252928,10485760,3145728,16252928,7864320,16252928,16252928,10485760,7864320,7864320,7864320,9437184,9437184,4718592,3670016,7864320,7864320,3670016,13107200,4718592,9437184,7340032,8912896,17825792,4718592,3670016,13631488,16777216,5242880,9437184,9437184,9437184,9437184,9437184,5767168,16777216,16777216,17825792,4718592,0,4718592,0,9437184,9437184,13107200,9437184,7864320,16777216,4718592,9437184,7864320,13107200,4718592,8912896,8912896,8912896,8912896,8912896,8912896,8912896,8388608,4718592,4456448,4718592,7864320,0,7864320,7864320,7864320,3145728,16252928,16252928,524288,18350080,16252928,14155776,16252928,16252928,4718592,0,12058624,8388608,7340032,9437184,9437184,8388608,8388608,8388608,8388608,0,9437184,9437184,9437184,9437184,4718592,0,-1048576,4718592,13107200,4718592,8388608,7340032,7340032,11010048,3670016,11010048,13107200,13107200,12058624,11010048,7340032,7340032,7864320,8388608,3670016,9437184,16252928,20971520,16252928,16252928,16252928,16252928,16252928,9961472,11534336,11534336,11534336,3145728,9437184,10485760,4718592,4718592,0,9437184,5242880,9437184,9437184,9437184,9437184,15728640,20447232,20447232,20447232,11534336,11534336,16252928,9961472,16252928,16252928,524288,4194304,4718592,0,8912896,8912896,8912896,8912896,8912896,8388608,8388608,8388608,8912896,4718592,4718592,0,3670016,8912896,8912896,8912896,13107200] [46,46,46,53,43,46,47,46,41,41,41,41,41,46,43,41,41,43,23,23,46,43,35,16,46,43,35,41,46,41,41,41,41,46,46,16,35,35,46,46,46,46,41,41,46,46,43,41,46,46,43,46,46,46,41,41,41,41,41,41,46,46,46,46,46,46,43,46,46,46,15,46,46,35,53,43,47,46,46,46,46,46,43,36,36,46,46,46,46,46,36,36,36,36,46,46,46,46,23,23,46,43,43,43,46,43,40,23,46,46,43,43,46,46,46,36,46,46,47,53,53,47,47,47,46,15,46,46,46,47,46,46,46,36,46,46,36,36,36,35,35,35,35,43,46,53,43,46,46,46,53,53,53,11,11,11,11,11,46,46,46,11,46,46,46,43,11,11,11,11] [128,128,128,144,144,144,144,128,160,160,160,176,192,144,160,160,160,160,192,128,128,128,128,176,112,112,239,255,112,192,192,192,192,224,255,112,215,80,144,144,112,112,192,192,128,128,192,112,255,128,192,128,255,144,144,144,144,144,144,144,144,255,144,255,144,144,144,128,128,128,96,144,144,127,128,128,128,128,128,144,144,96,144,144,144,255,144,144,128,128,144,144,144,144,128,128,128,128,192,144,144,144,144,144,144,144,192,192,144,144,144,144,255,144,144,144,144,231,144,144,144,144,144,128,112,112,144,144,127,128,128,128,128,144,128,144,144,144,144,112,255,255,255,255,160,144,160,144,144,144,128,144,128,144,144,144,144,144,128,128,128,144,255,128,128,255,128,128,128,136] [0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,9,0,0,7,7,7,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,1,0,0,1,1,1,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,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0] [1,1,0,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,2,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,1,0,0,1,2,1,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,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,98,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,88,62,88,0,0,0,0,0,0,0,0,62,88,88,88,0,0,0,0,0,0,0,0,0,0,0,0,0,88,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,91,91,91,91,91,91,0,1,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,22,0,0,0,0,0,0,0,0,0,1,0,0,0,90,90,90,0,0,0,0,0,0,0,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,62,62,88,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,88,0,0,0,0,0,27,27,0,0,27,27,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,62,0,0,0,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,34,70,91,62,0,0,0,0,0,0,0,27,0,0,0,0,0,0,0,0,48,48,48,48,1,0,0,0,0,0,0,0,27,1,0,0,0,0,0,0,0,0,0,0,31,0,0,0,0,0,0,0,0] [0,0,70,0,70,0,70,0,0,0,70,0,70,0,70,0,70,0,0,0,0,0,70,0,70,0,0,0,0,0,0,0,0,0,70,0,0,0,0,70,70,0,0,0,0,0,0,0,0,0,0,41,0,41,0,41,0,41,0,41,0,0,0,41,0,0,0,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,0,70,0,70,0,0,0,0,0,0,0,0,0,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,0,41,0,0,0,70,0,0,0,0,0,0,0,0,70,0,0,0,0,70,0,70,0,0,41,0,0,0,24,0,0,0,24,120,0,0,0,0,0,66,0,66,0,0,0,0,66,0,0,0,0,0,0,0,0,0,0,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,66,0,41,0,0,0,0,0,0,0,41,66,0,0,0,0,0,0,0,0,0,66,0,0,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,0,0,0,0,0,0,0,64,0,0,0,64,0,0,0,64,0,0,66,0,0,64,0,0,0,41,0,41,0,0,0,0,0,70,0,0,0,0,0,0,0,70,0,0,70,0,0,0,70,0,0,0,0,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,64,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,64,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,0,0,0,0,64,0,0,0,66,0,64,0,0,0,0,0,0,0,0,66,0,66,0,0,0,66,0,0,66,0,0,0,41,0,0,0,0,0,0,0,24,0,0,0,0,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,24,24,24,0,0,0,0,0,0,120,0,120,0,120,0,120,0,120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,120,0,120,0,0,120,0,120,0,120,0,0,0,0,0,0,0,0,0,120,0,120,0,120,0,120,0,120,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,0,0,0,0,3,0,3,0,0,0,0,0,0,0,0,0,0,66,66,66,66,66,66,66,66,66,66,0,0,0,0,0,0,0,0,0,0,0,64,0,64,0,64,0,64,0,64,0,64,0,2,0,2,0,0,0,0,0,64,0,0,0,0,0,0,0,64,0,64,0,0,0,0,0,0,0,64,0,0,0,0,0,64,64,0,0,70,0,0,64,0,0,0,0,64,0,64,0,64,0,0,64,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,95,0,0,0,0,0,77,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,77,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,81,27,56,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,0,24,120,24,120,24,120,24,120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65,0,0,0,0,0,0,3,0,3,0,0,0,3,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,120,0,0,24,120,70,0,0,66,0,0,0,0,0,0,66,0,0,70,0,0,70,0,0,0,0,0,0,70,0,0,66,0,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,77,0,0,0,64,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,14,0,66,0,66,0,14,0,0,0,0,0,0,0,0,0,0,0,14,0,120,0,120,0,14,0,0,0,0,0,0,0,0,36,0,36,0,0,0,0,0,0,0,0,0,14,0,66,0,0,0,0,66,0,14,0,0,0,0,0,14,0,14,0,0,14,0,0,0,0,0,0,0,0,0,120,0,120,0,0,0,0,0,0,0,0,0,0,0,0,0,50,50,0,70,0,0,0,66,0,0,14,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,95,64,0,64,65,65,37,24,37,24,37,24,37,24,0,0,0,0,0,14,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,65,0,66,0,0,0,0,0,0,0,0,0,0,0,3,0,3,0,0,0,15,0,0,0,0,0] [70,70,0,0,0,0,0,0,70,70,0,0,0,0,0,0,0,0,70,70,70,70,0,0,0,0,33,33,33,33,70,70,70,70,0,0,70,70,70,0,0,70,70,70,70,70,70,70,70,70,70,0,0,0,0,0,0,0,0,0,0,81,81,0,0,48,48,0,0,70,70,70,70,70,70,70,70,70,70,70,70,70,70,47,0,0,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,70,70,70,70,70,70,70,70,70,70,66,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,70,70,70,70,70,70,70,70,70,70,66,0,0,0,0,44,44,0,0,70,70,70,70,70,70,70,0,0,70,70,70,0,0,0,0,70,0,0,44,44,0,0,120,122,0,0,66,66,66,66,44,0,0,0,0,44,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,66,66,66,66,66,66,66,66,66,66,66,66,66,48,48,66,34,34,0,0,0,0,0,0,120,120,120,120,120,120,0,0,0,0,0,0,0,0,0,0,0,0,66,66,66,0,0,66,66,66,66,66,66,64,64,0,0,0,0,64,64,64,64,64,64,64,64,64,64,64,64,34,0,0,64,64,64,64,64,64,0,0,64,64,0,0,64,64,0,0,66,0,0,33,0,0,33,66,0,0,0,0,64,64,64,47,0,0,33,33,47,70,70,70,0,0,70,0,0,70,70,0,0,70,81,70,0,0,0,0,0,0,0,0,64,64,0,0,0,0,0,0,0,0,0,0,64,33,33,33,33,64,64,64,64,0,0,33,33,64,64,0,0,70,70,70,0,0,64,64,16,16,16,16,16,16,16,16,81,33,33,0,0,64,64,66,66,66,66,64,64,64,0,0,33,33,0,0,0,0,66,66,66,66,66,66,66,0,0,0,0,66,66,0,0,66,0,0,33,33,0,0,70,70,44,44,30,24,0,0,81,33,33,0,0,81,64,70,47,64,64,70,70,70,70,70,81,70,81,70,81,81,70,81,34,34,81,0,0,0,0,70,81,81,70,70,81,81,70,70,81,81,64,70,32,32,70,70,81,81,70,81,81,81,81,24,24,24,24,24,0,0,0,0,0,0,70,81,81,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,24,24,24,24,24,24,24,24,24,66,66,66,0,0,0,0,0,0,0,0,0,0,81,81,81,81,66,66,66,66,0,0,0,0,0,0,0,0,0,0,24,24,24,24,24,24,24,24,0,0,24,24,66,66,66,66,66,66,66,0,0,0,0,34,34,66,66,66,31,31,31,31,0,0,0,0,0,0,0,0,0,0,66,66,66,66,64,81,81,81,81,66,0,0,0,0,0,0,0,0,0,0,0,0,34,0,0,0,0,64,64,64,64,0,0,0,0,0,0,64,64,0,0,0,0,64,64,64,0,0,64,0,0,64,64,64,64,0,0,70,70,0,0,64,0,0,64,34,34,0,0,0,0,0,0,64,0,0,64,64,64,64,64,0,0,66,66,0,0,0,0,64,64,64,64,64,0,0,64,64,64,64,70,70,70,70,70,0,0,70,81,81,70,70,70,81,81,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,34,34,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,0,0,64,64,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,66,64,81,66,81,66,87,66,66,66,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,0,0,0,0,81,81,24,24,24,24,24,24,24,24,24,24,65,65,0,0,24,24,0,0,0,0,0,0,0,0,24,24,24,24,24,24,24,24,24,81,81,24,24,81,81,81,65,65,65,65,0,0,70,81,34,35,34,0,0,0,0,34,34,0,0,0,0,35,70,35,35,70,24,120,120,120,120,122,43,43,0,0,122,122,0,0,0,0,66,0,0,66,34,66,66,34,0,0,70,0,0,70,0,0,34,34,70,70,70,0,0,66,0,0,66,0,0,34,34,66,66,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,66,0,0,64,64,64,0,0,0,0,66,66,93,66,66,66,66,81,81,66,66,81,81,66,66,81,81,66,81,66,66,81,0,0,66,66,66,33,14,33,33,33,14,0,0,0,0,0,0,0,0,14,14,33,33,120,120,33,33,33,33,0,0,0,0,0,0,0,0,88,14,14,14,15,15,15,0,0,0,0,66,120,66,66,33,14,14,33,0,0,0,0,66,33,14,0,0,0,0,66,14,33,14,0,0,0,0,14,0,0,66,66,66,66,120,120,122,122,0,0,0,0,120,120,121,121,81,50,50,81,66,66,66,66,0,0,70,0,0,70,66,0,0,66,0,0,0,0,33,33,14,33,33,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,64,64,64,0,0,70,70,70,34,70,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,14,15,15,15,15,0,0,15,15,0,0,0,0,0,0,0,0,0,0,66,66,34,34,34,34,66,0,0,0,0,70,70,70,70,70,70,34,34,70,70,0,0,0,0,81,81,0,0,81,70,70,81] [0,0,0,0,0,0,0,0,0,0,70,0,70,0,70,0,70,0,0,0,0,0,70,0,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,0,0,0,0,0,0,0,0,0,0,0,76,0,76,0,76,0,76,0,76,0,0,0,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,76,0,76,0,76,0,76,0,76,0,76,0,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,0,76,0,76,0,76,0,76,0,76,0,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,120,0,0,24,0,0,0,0,0,0,0,0,0,0,0,0,73,0,73,0,73,0,73,0,73,0,73,0,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,74,0,0,0,0,0,0,0,76,0,76,0,76,0,76,0,76,0,76,0,0,0,0,66,77,0,0,0,0,0,0,0,0,16,41,16,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,64,0,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,0,0,0,0,0,70,0,0,70,0,0,0,70,0,0,0,0,0,0,16,0,16,0,16,0,0,0,53,0,53,0,53,0,64,0,53,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,64,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,0,0,0,0,0,0,0,0,0,0,64,0,0,0,66,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,0,0,66,0,0,0,41,0,0,0,0,0,0,0,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,120,0,56,0,24,0,0,0,0,0,24,0,24,0,24,0,24,0,56,0,24,0,24,0,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,0,56,0,120,0,120,0,120,0,0,0,0,0,0,0,0,0,24,0,24,0,24,0,24,0,24,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,16,0,16,0,16,0,16,0,16,0,0,0,41,0,41,0,0,0,0,0,41,53,0,53,41,0,0,0,0,64,0,0,0,0,53,41,0,0,41,0,0,0,0,0,0,0,0,70,0,0,64,64,0,0,0,53,0,53,0,53,0,0,64,0,0,0,0,0,0,64,0,0,0,53,41,53,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,53,41,53,41,53,41,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,95,0,0,0,0,76,0,76,0,76,0,76,0,76,0,76,0,76,0,76,0,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,81,0,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,81,0,0,0,24,0,24,0,24,0,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,0,0,0,0,0,3,0,3,0,0,0,3,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,70,0,0,66,0,0,0,0,0,0,66,0,0,70,0,0,70,0,0,0,0,0,0,70,0,0,66,0,0,66,0,0,0,0,0,0,120,0,120,0,120,0,120,0,120,0,120,0,120,0,120,0,0,0,0,0,0,0,0,64,0,53,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,66,0,66,0,14,0,0,0,0,0,0,0,0,0,0,0,14,0,120,0,120,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,66,0,0,0,0,66,0,14,0,0,0,0,0,14,0,14,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,0,66,0,0,14,0,14,0,0,0,0,0,0,0,0,0,64,0,64,0,64,0,64,0,64,0,64,0,16,0,16,0,16,0,16,0,16,0,16,0,0,0,0,0,53,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,56,56,0,0,0,0,0,0,0,0,15,0,15,0,0,14,0,0,0,0,0,0,14,0,0,0,16,0,16,0,16,0,16,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5505024,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14680064,0,0,0,4456448,3407872,2359296,1310720,0,1048576,2097152,3145728,4194304,5373952,0,0,0,0,0,0,0,0,0,0,262144,262144,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2097152,4194304,6291456,8388608,10485760,12582912,0,2097152,4194304,6291456,8388608,0,2097152,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2097152,4194304,6291456,8388608,10485760,0,2097152,4194304,6291456,8388608,10485760,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,262144,262144,0,0,262144,262144,0,0,0,0,0,0,0,0,0,0,262144,262144,0,0,0,0,0,0,0,0,0,12582912,0,0,0,0,12582912,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4194304,0,0,0,2097152,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3145728,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,262144,262144,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2097152,4194304,6291456,8388608,10485760,12582912,14680064,8388608,10485760,12582912,14680064,0,2097152,4194304,6291456,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12582912,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4194304,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6291456,0,0,0,2097152,0,2097152,0,0,2097152,0,2097152,0,6291456,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2097152,0,0,0,2097152,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13500416,0,13500416,0,13500416,0,13500416,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,262144,262144,0,0,0,0,0,0] [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-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,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,63,61,62,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124] [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,52,53,51,54,55] 1 0 0 0 0 1 2691576 2686976 0 9242 82 0 0 [0,0,0,0,0,0] [0,0,0,0,0,0] 0 2 10 [1,1,1,0,0,0,0,0,0] [60,10,0,0] [200,50,300,50] 1 0 0 1 1 0 0 0 18 0 119 0 0 [27,-1] [5,0] [602121,602121] [2900895,2900895] 7 34 7 5 [1,1,1,0,0,0,0,0,0] 82 74 0 82 4 206 1 1 262077856542286207 0 4 1 0 diff --git a/native/tests/sim_player_damage_live.rs b/native/tests/sim_player_damage_live.rs index 69a0b307..2fca54f7 100644 --- a/native/tests/sim_player_damage_live.rs +++ b/native/tests/sim_player_damage_live.rs @@ -4,6 +4,18 @@ //! aimed at the player instead of a second imp: an imp beside the player, //! one tic from `A_TroopAttack`'s own frame. //! +//! A fireball's own impact is seeded from `demo3`'s own recorded run +//! instead: `native/tests/fixtures/demo3-player-damage.tsv` carries the +//! reference emulator's own row at gametic 205, the tic before an +//! in-flight fireball reaches the player, so the geometry, the blockmap +//! and every other thing on the level's own list are exactly what the +//! real engine had rather than a hand-placed approximation. Running +//! gametic 206 from it with the demo lump's own recorded command, with no +//! armour, reproduces the reference's own row at 206 field for field, +//! which doubles as the parity the differential run cannot reach on its +//! own yet (a missile move gap earlier in the demo, unrelated to this, +//! still refuses first). +//! //! Needs a reachable ClickHouse (`CLICKHOUSE_HOST` / `CLICKHOUSE_HTTP_PORT` //! / `CLICKHOUSE_PASSWORD`, defaulting to `localhost:8123` with no //! password). Behind the `clickhouse-tests` feature, so a run without a @@ -231,3 +243,324 @@ async fn a_claw_reaches_the_player_through_its_own_armour() { ); } } + +/// The reference emulator's own rows at gametic 205 and 206, `demo3`'s own +/// probe trace trimmed to the tic a thrown fireball reaches the player. +const PROBE_ROWS: &str = include_str!("fixtures/demo3-player-damage.tsv"); + +const GAMETIC_BEFORE: u32 = 205; +const GAMETIC_HIT: u32 = 206; + +/// `refemu/reference_traces/demo3/probe.9a6a47d01119.tsv`: the fireball's +/// own array position, both rows. +const MISSILE_SLOT: usize = 265; +/// The imp that threw it, `m_target` on both rows. +const THROWER: u32 = 119; +/// `mobjtype.tsv` +const TROOPSHOT: i32 = 31; +/// `p_pspr.c`'s own `S_TBALL1`/`S_TBALL2`, from the probe: the frame the +/// missile flies in and the one `P_ExplodeMissile` puts it in. +const TBALL1: i32 = 98; +const TBALL2: i32 = 99; +/// `p_mobj.h`: `MF_SOLID | MF_SHOOTABLE | MF_MISSILE | MF_DROPOFF | +/// MF_NOGRAVITY`, the fireball's own flags in flight, and what +/// `P_ExplodeMissile` leaves once it strikes something. +const FLYING_FLAGS: i32 = 67088; +const EXPLODED_FLAGS: i32 = 1552; +/// The reference's own row at gametic 205: the fireball still in flight. +const BEFORE_X: i32 = 11078949; +const BEFORE_Y: i32 = 12923838; +const BEFORE_Z: i32 = 2097152; +const BEFORE_MOMX: i32 = -285410; +const BEFORE_MOMY: i32 = 589940; +const BEFORE_RADIUS: i32 = 393216; +const BEFORE_HEIGHT: i32 = 524288; +const BEFORE_SUBSECTOR: i32 = 145; +/// `P_ExplodeMissile`'s own death frame (`S_TBALL2`, `states.tsv` row 99) +/// carries six tics, and `P_SetMobjState` shortens that by a number of +/// its own: `greatest(6 - (P_Random() & 3), 1)`, three to six. +const DEATH_TICS: i32 = 6; + +fn probe_line(gametic: u32) -> Vec { + let line = PROBE_ROWS + .lines() + .find(|line| line.split('\t').nth(1) == Some(gametic.to_string().as_str())) + .unwrap_or_else(|| panic!("no probe row for gametic {gametic}")); + format!("{line}\n").into_bytes() +} + +#[derive(Row, Deserialize)] +struct Impact { + p_health: i32, + p_armorpoints: i32, + p_armortype: i32, + p_damagecount: i32, + p_attacker: u32, + player_health: i32, + missile_state: i32, + missile_tics: i32, + missile_flags: i32, + missile_momx: i32, + missile_momy: i32, + missile_x: i32, + missile_y: i32, + missile_health: i32, + unresolved: u64, +} + +async fn hit_after_206(fixture: &Fixture, db: &str) -> Impact { + fixture + .execute(&[sim::tick::demo_statement(db, GAMETIC_HIT, GAMETIC_HIT)]) + .await + .unwrap_or_else(|error| panic!("{error}")); + fixture + .rows(&format!( + "SELECT p_health, p_armorpoints, p_armortype, p_damagecount, p_attacker, \ + m_health[p_mo] AS player_health, m_state[{MISSILE_SLOT}] AS missile_state, \ + m_tics[{MISSILE_SLOT}] AS missile_tics, m_flags[{MISSILE_SLOT}] AS missile_flags, \ + m_momx[{MISSILE_SLOT}] AS missile_momx, m_momy[{MISSILE_SLOT}] AS missile_momy, \ + m_x[{MISSILE_SLOT}] AS missile_x, m_y[{MISSILE_SLOT}] AS missile_y, \ + m_health[{MISSILE_SLOT}] AS missile_health, unresolved \ + FROM {db}.native_state WHERE tic = {GAMETIC_HIT}" + )) + .await + .into_iter() + .next() + .unwrap_or_else(|| panic!("no row for tic {GAMETIC_HIT}")) +} + +async fn seeded_fireball(name: &str, armortype: i64, armorpoints: i64) -> Impact { + let bytes = support::doom1(); + let wad = Wad::parse(&bytes).unwrap(); + let fixture = Fixture::create(&format!("sim_player_damage_{name}")).await; + let db = fixture.database.clone(); + + let mut plan = load::plan(&db, &wad); + plan.extend(sql::level_statements(&db, support::MAP, support::DEMO)); + plan.extend(sim::load_statements(&db)); + if let Err(error) = fixture.execute(&plan).await { + fixture.finish().await; + panic!("{error}"); + } + support::probe::load(&fixture, &probe_line(GAMETIC_BEFORE)).await; + + if armortype != 0 || armorpoints != 0 { + let overrides = seed::row( + &db, + GAMETIC_BEFORE, + GAMETIC_BEFORE, + &[ + ("p_armortype", format!("toInt32({armortype})")), + ("p_armorpoints", format!("toInt32({armorpoints})")), + ], + ) + .into_iter() + .map(sql::Statement::sql) + .collect::>(); + if let Err(error) = fixture.execute(&overrides).await { + fixture.finish().await; + panic!("{error}"); + } + } + + let after = hit_after_206(&fixture, &db).await; + fixture.finish().await; + after +} + +/// A fireball already in flight, seeded from `demo3`'s own recorded run +/// at the tic before it reaches the player, across no armour and both +/// armour types. +/// +/// The reference's own row at gametic 206 has the player taking exactly +/// this hit (health 100 to 82, `p_attacker` the imp that threw it), which +/// this reproduces for the fields the armour cannot move: the missile's +/// own explode frame, its flags, and that the impact stops it rather than +/// carrying it through. The damage roll itself is read off the no-armour +/// arm's own run rather than asserted against the reference number: the +/// two agree on every field this checks, but a busy, full-level tic draws +/// numbers for hundreds of other things this does not seed, and nothing +/// here answers for their own count being exactly what the reference +/// drew. +#[tokio::test] +async fn a_fireball_reaches_the_player_through_its_own_armour() { + let bare = seeded_fireball("fireball_no_armor", 0, 0).await; + assert_eq!(bare.unresolved, 0, "a living player's own hit resolves"); + assert_eq!(bare.p_armorpoints, 0, "no armour, nothing saved"); + assert_eq!(bare.p_armortype, 0); + assert_eq!(bare.p_attacker, THROWER); + assert_eq!( + bare.player_health, bare.p_health, + "the shared health agrees with the player's own" + ); + assert_eq!( + bare.missile_state, TBALL2, + "the fireball's own explode frame" + ); + assert!( + (DEATH_TICS - 3..=DEATH_TICS).contains(&bare.missile_tics), + "the death frame's own wait shortens by up to three: {}", + bare.missile_tics + ); + assert_eq!(bare.missile_flags, EXPLODED_FLAGS); + assert_eq!(bare.missile_momx, 0, "the impact stops it"); + assert_eq!(bare.missile_momy, 0); + assert_eq!( + bare.missile_x, BEFORE_X, + "an exploding missile does not move" + ); + assert_eq!(bare.missile_y, BEFORE_Y); + assert_eq!( + bare.missile_health, 1000, + "the fireball's own health is not what the hit moves" + ); + let raw_damage = 100 - bare.p_health; + assert_eq!( + bare.p_damagecount, raw_damage, + "no armour, the tint takes the whole hit" + ); + + for (name, armortype, divisor) in [("green_armor", 1, 3), ("blue_armor", 2, 2)] { + let after = seeded_fireball(&format!("fireball_{name}"), armortype, 100).await; + assert_eq!(after.unresolved, 0, "{name}"); + let saved = raw_damage / divisor; + assert_eq!( + 100 - after.p_armorpoints, + saved, + "{name}: the armour absorbs its own share of the same roll" + ); + assert_eq!( + 100 - after.p_health, + raw_damage - saved, + "{name}: health takes what the armour did not" + ); + assert_eq!( + after.player_health, after.p_health, + "{name}: the shared health agrees" + ); + assert_eq!(after.p_damagecount, raw_damage - saved, "{name}"); + } +} + +#[tokio::test] +async fn two_fireballs_in_one_tic_thread_the_player_through_both() { + let bytes = support::doom1(); + let wad = Wad::parse(&bytes).unwrap(); + let fixture = Fixture::create("sim_player_damage_two_hits").await; + let db = fixture.database.clone(); + + let mut plan = load::plan(&db, &wad); + plan.extend(sql::level_statements(&db, support::MAP, support::DEMO)); + plan.extend(sim::load_statements(&db)); + if let Err(error) = fixture.execute(&plan).await { + fixture.finish().await; + panic!("{error}"); + } + support::probe::load(&fixture, &probe_line(GAMETIC_BEFORE)).await; + + // A corpse already dead by gametic 205, repurposed as a second + // fireball on the same heading as the real one. + const SECOND_SLOT: usize = 258; + // The player's own row 205 position minus the real missile's own + // momentum, so this one's move lands exactly on the player rather + // than relying on the same box sweep the real one's own position + // happens to clear. + const PLAYER_X: i32 = 10419829; + const PLAYER_Y: i32 = 14857119; + let overrides = [ + put( + "m_x", + SECOND_SLOT, + (PLAYER_X - BEFORE_MOMX).to_string(), + "toInt32", + ), + put( + "m_y", + SECOND_SLOT, + (PLAYER_Y - BEFORE_MOMY).to_string(), + "toInt32", + ), + put("m_z", SECOND_SLOT, BEFORE_Z.to_string(), "toInt32"), + put("m_momx", SECOND_SLOT, BEFORE_MOMX.to_string(), "toInt32"), + put("m_momy", SECOND_SLOT, BEFORE_MOMY.to_string(), "toInt32"), + put("m_momz", SECOND_SLOT, "0".to_owned(), "toInt32"), + put("m_type", SECOND_SLOT, TROOPSHOT.to_string(), "toInt32"), + put("m_state", SECOND_SLOT, TBALL1.to_string(), "toInt32"), + put("m_tics", SECOND_SLOT, "1".to_owned(), "toInt32"), + put("m_flags", SECOND_SLOT, FLYING_FLAGS.to_string(), "toInt32"), + put("m_target", SECOND_SLOT, THROWER.to_string(), "toUInt32"), + put("m_health", SECOND_SLOT, "1000".to_owned(), "toInt32"), + put( + "m_radius", + SECOND_SLOT, + BEFORE_RADIUS.to_string(), + "toInt32", + ), + put( + "m_height", + SECOND_SLOT, + BEFORE_HEIGHT.to_string(), + "toInt32", + ), + put( + "m_subsector", + SECOND_SLOT, + BEFORE_SUBSECTOR.to_string(), + "toInt32", + ), + put("m_reactiontime", SECOND_SLOT, "0".to_owned(), "toInt32"), + put("m_threshold", SECOND_SLOT, "0".to_owned(), "toInt32"), + ]; + let seeded = seed::row(&db, GAMETIC_BEFORE, GAMETIC_BEFORE, &overrides) + .into_iter() + .map(sql::Statement::sql) + .collect::>(); + if let Err(error) = fixture.execute(&seeded).await { + fixture.finish().await; + panic!("{error}"); + } + + let after = hit_after_206(&fixture, &db).await; + let (second_state, second_flags) = fixture + .rows::<(i32, i32)>(&format!( + "SELECT m_state[{SECOND_SLOT}], m_flags[{SECOND_SLOT}] \ + FROM {db}.native_state WHERE tic = {GAMETIC_HIT}" + )) + .await + .into_iter() + .next() + .unwrap_or_else(|| panic!("no row for tic {GAMETIC_HIT}")); + fixture.finish().await; + + // Both missiles explode, proving both connected rather than one alone + // silently losing its own effect to the other's. + assert_eq!( + (second_state, second_flags), + (TBALL2, EXPLODED_FLAGS), + "the second fireball's own impact runs too" + ); + // The player's own fields thread through both hits correctly: each + // one's own damage_fold call reads what the one before it left + // through `player`, the same chain the armour arms already prove. + let taken = 100 - after.p_health; + assert!(taken >= 6, "two hits, each at least a roll of one: {taken}"); + assert_eq!( + after.p_damagecount, taken, + "the tint takes the sum of both, threaded through the same fold" + ); + // The mobj-generic fields a call answers with (`m_health` here) read + // the tic-start arrays directly rather than an accumulator, so the + // second missile's own call overwrites the first's own subtraction + // rather than building on it: the shared field only carries one + // hit's worth, not both. `DM_SAME_TARGET` refuses the tic for this + // rather than committing the wrong shared answer. + assert_ne!( + after.player_health, after.p_health, + "the shared field does not thread the way the player's own does" + ); + assert_ne!( + after.unresolved & sim::unresolved::DM_SAME_TARGET, + 0, + "a second hit on the same target this tic leaves it stuck" + ); +} From 49aa27ab858619770414210f6c97aeb76c8f617b Mon Sep 17 00:00:00 2001 From: Marcus Kainth Date: Mon, 7 Sep 2026 06:53:21 +0100 Subject: [PATCH 4/5] native: let the push run ahead of a player's own immunity P_DamageMobj's own thrust sits ahead of the player-specific block, so a god mode or invulnerable player is still pushed even though the armour, health, damagecount and attacker do not move. dm_pushes and dm_may_fall now read a target's own reach rather than dm_lands, which still gates everything past the thrust; draws() and damaged() agree on the draw count that follows. --- native/src/sql/sim/inter.rs | 59 ++++++++++++++------ native/tests/sim_player_damage_live.rs | 77 +++++++++++++++++++++----- 2 files changed, 107 insertions(+), 29 deletions(-) diff --git a/native/src/sql/sim/inter.rs b/native/src/sql/sim/inter.rs index 56fec4ee..97d3272c 100644 --- a/native/src/sql/sim/inter.rs +++ b/native/src/sql/sim/inter.rs @@ -1065,7 +1065,7 @@ pub fn damage_mobj(asks: &str, world: &Hurting<'_>) -> String { /// any of them is worked out. Nothing a call draws changes how many draws /// it makes, so the count is this much of the routine and no more. pub fn draws(asks: &str, world: &Hurting<'_>) -> String { - let body = "toUInt32(if(dm_lands = 1, 1 + toUInt32(dm_may_fall), 0))"; + let body = "toUInt32(toUInt32(dm_may_fall) + if(dm_lands = 1, 1, 0))"; format!( "arrayMap(dm_ask -> {}, {asks})", bind::chain_in("dmd", &reach(world), body) @@ -1118,8 +1118,9 @@ fn reach(world: &Hurting<'_>) -> Vec<(String, String)> { dm_damage))" ), ), - // God mode and invulnerability return before anything else runs, - // under a damage this large. + // God mode and invulnerability return under a damage this large, + // once the push below has already run: the engine's own thrust + // code sits ahead of that return. ( "dm_immune".to_owned(), format!( @@ -1128,27 +1129,30 @@ fn reach(world: &Hurting<'_>) -> Vec<(String, String)> { world.p_cheats, world.p_powers, ), ), - // The two early returns: a thing that cannot be shot, and one - // already dead, take nothing and draw nothing. A player's own god - // mode or invulnerability is the same kind of return. + // A thing that cannot be shot, and one already dead, take nothing + // and draw nothing. ( - "dm_lands".to_owned(), - format!( - "toUInt8(bitAnd(dm_flags, {MF_SHOOTABLE}) != 0 AND dm_health > 0 \ - AND dm_immune = 0)" - ), + "dm_reaches".to_owned(), + format!("toUInt8(bitAnd(dm_flags, {MF_SHOOTABLE}) != 0 AND dm_health > 0)"), ), // The push. A call with no inflictor pushes nothing, and a // chainsaw in the source's hands holds its target in reach. ( "dm_pushes".to_owned(), format!( - "toUInt8(dm_lands = 1 AND dm_inflictor != 0 AND bitAnd(dm_flags, {MF_NOCLIP}) = 0 \ + "toUInt8(dm_reaches = 1 AND dm_inflictor != 0 \ + AND bitAnd(dm_flags, {MF_NOCLIP}) = 0 \ AND (dm_source = 0 OR {} = -1 OR {} != {WP_CHAINSAW}))", credited(world.m_player), world.readyweapon, ), ), + // What reaches and is not a god mode or invulnerable player's own + // return lands: the armour, the health, and everything after them. + ( + "dm_lands".to_owned(), + "toUInt8(dm_reaches = 1 AND dm_immune = 0)".to_owned(), + ), // Falling forwards is the one draw a call makes before the damage // lands, and whether it is made is decided without reading it. ( @@ -1492,7 +1496,7 @@ fn damaged(world: &Hurting<'_>, player: &str) -> (Vec<(String, String)>, String) "toUInt8(dm_killed)".to_owned(), format!("toUInt8(dm_killed = 1 AND bitAnd(dm_flags, {MF_COUNTKILL}) != 0)"), "toInt32(if(dm_killed = 1, dm_drop, -1))".to_owned(), - "toUInt32(if(dm_lands = 1, 1 + toUInt32(dm_may_fall), 0))".to_owned(), + "toUInt32(toUInt32(dm_may_fall) + if(dm_lands = 1, 1, 0))".to_owned(), "toUInt8(dm_stuck)".to_owned(), format!( "toInt32(if(dm_player_hit = 1, greatest(toInt32({player}.{}) - dm_damage_final, 0), \ @@ -1564,17 +1568,40 @@ mod damage_tests { } /// A call draws once where it lands and once more where the hit may - /// knock its target over, and nothing where it does not land. Every - /// draw after it in the tic sits behind that count. + /// knock its target over. A god mode or invulnerable player's own + /// return still may fell, since the push runs ahead of it, but never + /// lands, so it draws for the fall alone. A call that neither reaches + /// nor may fell draws nothing. #[test] fn a_call_draws_by_where_it_lands_and_whether_it_may_fell() { let (_, body) = damaged(&world(), "dm_held"); assert!( - body.contains("toUInt32(if(dm_lands = 1, 1 + toUInt32(dm_may_fall), 0))"), + body.contains("toUInt32(toUInt32(dm_may_fall) + if(dm_lands = 1, 1, 0))"), "{body}" ); } + /// The push runs ahead of a player's own god mode or invulnerable + /// return, the way the engine's own thrust code sits ahead of it: only + /// `dm_lands` reads `dm_immune`. + #[test] + fn the_push_does_not_wait_on_a_player_s_own_immunity() { + let (values, _) = damaged(&world(), "dm_held"); + let named = |name: &str| { + values + .iter() + .find(|(held, _)| held == name) + .map(|(_, expr)| expr.clone()) + .unwrap_or_else(|| panic!("the call names {name}")) + }; + let pushes = named("dm_pushes"); + assert!(!pushes.contains("dm_immune"), "{pushes}"); + let may_fall = named("dm_may_fall"); + assert!(!may_fall.contains("dm_immune"), "{may_fall}"); + let lands = named("dm_lands"); + assert!(lands.contains("dm_immune = 0"), "{lands}"); + } + /// The push angle and the fall test read where the inflictor stands; /// the chainsaw test and the chase read the source. #[test] diff --git a/native/tests/sim_player_damage_live.rs b/native/tests/sim_player_damage_live.rs index 2fca54f7..5db3a66d 100644 --- a/native/tests/sim_player_damage_live.rs +++ b/native/tests/sim_player_damage_live.rs @@ -256,6 +256,8 @@ const GAMETIC_HIT: u32 = 206; const MISSILE_SLOT: usize = 265; /// The imp that threw it, `m_target` on both rows. const THROWER: u32 = 119; +/// `d_player.h`: `pw_invulnerability`, one-based for `p_powers`. +const PW_INVULNERABILITY: usize = 1; /// `mobjtype.tsv` const TROOPSHOT: i32 = 31; /// `p_pspr.c`'s own `S_TBALL1`/`S_TBALL2`, from the probe: the frame the @@ -330,6 +332,15 @@ async fn hit_after_206(fixture: &Fixture, db: &str) -> Impact { } async fn seeded_fireball(name: &str, armortype: i64, armorpoints: i64) -> Impact { + seeded_fireball_with(name, armortype, armorpoints, false).await +} + +async fn seeded_fireball_with( + name: &str, + armortype: i64, + armorpoints: i64, + invulnerable: bool, +) -> Impact { let bytes = support::doom1(); let wad = Wad::parse(&bytes).unwrap(); let fixture = Fixture::create(&format!("sim_player_damage_{name}")).await; @@ -344,20 +355,30 @@ async fn seeded_fireball(name: &str, armortype: i64, armorpoints: i64) -> Impact } support::probe::load(&fixture, &probe_line(GAMETIC_BEFORE)).await; + let mut overrides: Vec<(&str, String)> = Vec::new(); if armortype != 0 || armorpoints != 0 { - let overrides = seed::row( - &db, - GAMETIC_BEFORE, - GAMETIC_BEFORE, - &[ - ("p_armortype", format!("toInt32({armortype})")), - ("p_armorpoints", format!("toInt32({armorpoints})")), - ], - ) - .into_iter() - .map(sql::Statement::sql) - .collect::>(); - if let Err(error) = fixture.execute(&overrides).await { + overrides.push(("p_armortype", format!("toInt32({armortype})"))); + overrides.push(("p_armorpoints", format!("toInt32({armorpoints})"))); + } + if invulnerable { + // `player::powers`'s own per-tic decay runs ahead of the thinker + // stage this seeds the hit into, taking one tic off before the + // fireball ever reads it, so one tic of its own is not enough: + // seed several to survive the decay and still read nonzero. + overrides.push(( + "p_powers", + format!( + "arrayMap((v, k) -> toInt32(if(k = {PW_INVULNERABILITY}, 5, v)), \ + p.p_powers, arrayEnumerate(p.p_powers))" + ), + )); + } + if !overrides.is_empty() { + let statements = seed::row(&db, GAMETIC_BEFORE, GAMETIC_BEFORE, &overrides) + .into_iter() + .map(sql::Statement::sql) + .collect::>(); + if let Err(error) = fixture.execute(&statements).await { fixture.finish().await; panic!("{error}"); } @@ -442,6 +463,36 @@ async fn a_fireball_reaches_the_player_through_its_own_armour() { } } +/// A god mode or invulnerable player's own return leaves the player's own +/// fields, and the mobj's own shared health, untouched. The fireball's own +/// impact is a different mobj's own move blocked, not `P_DamageMobj`'s +/// doing, so it explodes and stops exactly as it does against a player who +/// takes the hit. +#[tokio::test] +async fn an_invulnerable_player_is_still_pushed_but_not_hurt() { + let after = seeded_fireball_with("fireball_invulnerable", 0, 0, true).await; + assert_eq!(after.unresolved, 0, "an immune hit resolves too"); + assert_eq!(after.p_health, 100, "the return skips the health"); + assert_eq!(after.p_armorpoints, 0, "and the armour"); + assert_eq!(after.p_armortype, 0); + assert_eq!(after.p_damagecount, 0, "and the tint"); + assert_eq!(after.p_attacker, 0, "and the attacker"); + assert_eq!( + after.player_health, 100, + "the shared health is not touched either" + ); + assert_eq!( + after.missile_state, TBALL2, + "the fireball's own impact does not depend on the target's return" + ); + assert_eq!(after.missile_flags, EXPLODED_FLAGS); + assert_eq!( + after.missile_momx, 0, + "its own move stops it, blocked or not" + ); + assert_eq!(after.missile_momy, 0); +} + #[tokio::test] async fn two_fireballs_in_one_tic_thread_the_player_through_both() { let bytes = support::doom1(); From 4bd26946606d58615cee250afc1f2533c21a9006 Mon Sep 17 00:00:00 2001 From: Marcus Kainth Date: Mon, 7 Sep 2026 12:42:20 +0100 Subject: [PATCH 5/5] native: read damaged's own player branch in the reader The reader still carried the rule any hit on a player is refused, which damaged() no longer follows: a living player's own hit resolves, and only a killing one, or the sector 11 clamp, leaves the call stuck. Refusing a player's death now happens where the kill is decided, over and above the routine-unwritten check that already applies uniformly. Chasing after what hit it is a monster's own behaviour: damaged() gates it on the target not being a player, and the reader's own chases condition did not carry that gate, so a living player's own hit was reading a chase it never gets. --- native/tests/support/damage.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/native/tests/support/damage.rs b/native/tests/support/damage.rs index e00a8229..2b5e10e2 100644 --- a/native/tests/support/damage.rs +++ b/native/tests/support/damage.rs @@ -188,7 +188,6 @@ impl World { if !lands { return hurt; } - hurt.stuck = it.player != -1; let flying = it.flags & MF_SKULLFLY != 0; if flying { hurt.momx = 0; @@ -237,7 +236,10 @@ impl World { }; hurt.state = state; hurt.tics = (state_tics[state as usize] - (second & 3)).max(1); - hurt.stuck |= self.routine_is_unwritten(it.state, state); + // `P_KillMobj`'s own player branch is a different thing this + // does not run, so a hit that kills a player leaves the call + // stuck, over and above whatever the corpse's own frame does. + hurt.stuck = it.player != -1 || self.routine_is_unwritten(it.state, state); hurt.drop = match it.kind { k if k == thing_type("MT_POSSESSED") || k == thing_type("MT_WOLFSS") => { thing_type("MT_CLIP") @@ -255,7 +257,8 @@ impl World { } hurt.reactiontime = 0; let vile = thing_type("MT_VILE"); - let chases = (it.threshold == 0 || it.kind == vile) + let chases = it.player == -1 + && (it.threshold == 0 || it.kind == vile) && source != 0 && source != target && credited.is_some_and(|from| from.kind != vile);