Unescape HTML · Rust 🤝 Opus 5.5

SHA-256 8b7aa3bc90f3fb96cded65adde930485f065ad967142392e97f29a201ca4f100

View source (63.7 KiB of Rust)
// unescape_html: decode HTML character references like Python's
// html.unescape, except that references to control characters and
// noncharacters decode to that code point (as the WHATWG tokenizer does)
// instead of being deleted.
//
// A middle ground between size and speed (Rust port).
// - The Wasm ships only a compact entity table: the 2125 names of
//   html.entities.html5 sorted and front-coded (each name stores how many
//   bytes it shares with the one before, then the rest, with the last byte's
//   high bit set), and their code points in byte planes. That gzips to
//   about 9 KB.
// - The first call to render expands it into an open-addressed hash table in
//   memory: each slot holds the name zero-padded to 32 bytes, and the value
//   as ready-to-store UTF-8 with its length. A lookup hashes the padded name,
//   compares 32 bytes with vector compares, and writes the value with one
//   8-byte store.
// - One buffer holds both output and input. The input sits IN_OFF bytes in,
//   and output is written from the start. Every reference expands by at most
//   1.2x (≪⃒ is 5 bytes in, 6 out), so the write cursor stays at least
//   IN_OFF - 0.2 * 1 MiB (about 51 KiB) behind the read cursor: decoding in
//   place is safe.
// - A sentinel '&' after the input stops every scan, so the inner loops need
//   no bounds checks. Plain text is copied 32 bytes at a time with SIMD
//   (core::arch::wasm32 v128), which stops only at '&'.
// - Legacy names without ';' (&amp, &copy, ...) use the longest legacy prefix
//   of the name, as html.unescape does.
//
// Tables generated from Python 3.14's html.entities.html5.
// Build (rustc 1.99.0): rustc unescape_html.rs --edition 2024 --crate-type cdylib
//   --target wasm32-unknown-unknown -C target-feature=+simd128 -C opt-level=z
//   -C panic=abort -C lto -C codegen-units=1 -C strip=symbols
//   -C link-arg=-zstack-size=4096 -C link-arg=--initial-memory=1507328
//   -C link-arg=--max-memory=1507328 -o unescape_html.wasm

#![no_std]

use core::arch::wasm32::*;
use core::ptr::{addr_of, addr_of_mut};

const OUT_CAP: u32 = 1310720;
const IN_CAP: u32 = 1048576;
const IN_OFF: u32 = OUT_CAP - IN_CAP;

#[repr(C, align(16))]
struct Buf([u8; OUT_CAP as usize + 64]);
static mut BUF: Buf = Buf([0; OUT_CAP as usize + 64]);

#[inline(always)]
fn buf() -> *mut u8 {
    addr_of_mut!(BUF) as *mut u8
}

#[unsafe(no_mangle)]
pub extern "C" fn input_ptr() -> u32 {
    buf() as u32 + IN_OFF
}
#[unsafe(no_mangle)]
pub extern "C" fn input_utf8_cap() -> u32 {
    IN_CAP
}
#[unsafe(no_mangle)]
pub extern "C" fn output_utf8_cap() -> u32 {
    OUT_CAP
}

const N: usize = 2125;
// Planes of N bytes each: shared-prefix length, code point low byte, high
// byte, and META (bit 6 is the code point's bit 16, bits 1-4 are index+1
// into SECOND or 0, bit 5 marks a legacy name also valid without ';').
// Then the name suffixes.
static DATA: [u8; 16228] = [
  0,1,1,1,1,2,1,1,1,1,1,1,2,1,1,1,2,1,1,0,2,3,1,1,2,2,1,1,1,1,1,0,
  1,1,2,3,2,1,2,2,2,1,1,2,1,1,1,6,6,6,1,3,10,1,5,2,3,3,2,3,2,1,1,1,
  3,0,2,1,1,1,1,2,2,1,2,1,3,1,1,11,13,11,11,3,2,1,2,3,3,2,6,8,6,10,10,7,
  14,10,6,11,6,8,6,2,9,9,4,4,8,8,14,4,9,15,4,7,4,1,2,0,1,1,1,2,2,1,1,1,
  1,1,2,5,1,2,1,1,5,3,1,2,1,1,1,2,0,1,1,6,1,2,2,1,0,1,1,5,1,1,2,2,
  1,1,1,1,1,12,7,7,7,7,7,1,1,0,1,2,1,1,1,1,2,1,2,1,4,0,1,1,1,1,2,1,
  1,1,1,2,3,2,1,3,4,2,9,1,2,2,1,1,1,2,0,2,1,1,1,2,1,0,1,1,1,2,1,1,
  1,0,1,1,2,2,2,2,1,2,2,1,5,9,9,4,4,6,8,14,4,4,9,4,7,7,5,12,12,4,6,6,
  12,4,10,4,4,2,4,4,4,4,4,1,1,2,1,1,8,4,4,8,4,2,2,5,1,2,2,1,0,1,1,2,
  1,1,1,1,1,0,1,1,2,2,1,8,11,8,2,6,2,1,1,2,2,2,3,4,3,3,4,8,4,3,10,10,
  10,10,10,10,3,7,3,15,15,5,7,7,7,7,7,3,9,3,11,11,3,4,16,16,3,15,11,17,4,9,5,11,
  11,11,5,11,3,8,8,8,3,1,1,1,0,1,1,2,1,1,1,1,2,2,1,1,9,1,1,2,1,3,1,1,
  5,8,4,0,1,1,1,1,1,1,2,1,2,8,8,8,2,2,3,10,1,2,0,1,1,1,0,1,1,2,2,4,
  1,2,2,1,2,8,7,1,1,1,6,10,10,5,5,7,9,15,5,5,8,8,6,13,13,5,7,7,13,5,11,5,
  1,2,1,1,2,1,0,2,1,1,1,2,2,2,2,1,1,5,5,5,1,1,1,1,2,6,6,12,8,14,6,1,
  1,1,3,6,2,8,8,8,3,2,2,3,8,3,0,1,1,2,1,2,1,2,2,1,1,3,2,3,1,5,5,5,
  1,1,1,2,0,2,4,1,3,1,2,1,1,1,1,1,6,9,5,2,5,1,2,1,7,7,2,2,2,5,2,2,
  2,5,2,4,1,1,1,1,0,1,1,1,5,1,2,3,4,8,8,8,3,1,1,1,1,0,1,1,1,1,0,1,
  1,1,0,1,1,1,1,2,1,1,1,1,0,1,1,2,1,1,2,1,1,1,0,1,1,2,2,2,2,2,1,1,
  2,1,1,3,2,1,3,2,1,3,3,3,3,2,3,3,3,6,7,7,7,7,7,7,7,3,5,7,3,4,3,1,
  2,1,2,2,2,2,2,2,6,1,1,2,2,5,1,1,1,2,0,1,4,4,4,7,2,3,6,1,4,1,2,1,
  1,6,2,2,2,2,3,3,1,1,4,4,3,4,4,3,4,3,11,3,3,3,1,1,5,5,13,13,13,3,2,4,
  3,2,1,3,2,1,2,3,2,2,4,4,4,3,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,3,3,4,
  4,4,3,4,4,4,4,3,3,3,3,4,4,4,3,4,4,4,4,4,4,1,1,2,1,2,2,4,2,4,4,1,
  4,2,4,4,5,0,2,3,3,3,4,3,3,2,3,1,3,2,2,2,5,1,1,2,2,4,1,1,2,5,2,1,
  3,3,4,4,11,6,7,7,7,7,3,3,3,3,1,5,1,5,6,2,5,3,4,4,6,2,4,3,2,3,3,4,
  1,2,1,2,4,3,4,1,1,6,2,3,2,6,2,3,3,4,3,3,3,2,6,3,7,5,5,3,3,10,2,2,
  1,2,1,0,1,1,2,2,2,4,1,2,1,2,1,2,3,2,1,2,2,1,2,1,4,1,4,7,4,2,2,2,
  2,3,6,3,1,1,3,1,2,2,3,5,3,3,3,2,2,4,4,11,1,2,3,1,3,2,2,1,2,4,1,2,
  1,1,2,0,2,1,2,1,2,4,2,2,1,1,1,2,1,2,2,3,1,2,2,2,3,1,2,5,5,2,4,5,
  1,2,1,2,1,4,2,2,4,4,1,3,2,3,7,2,3,3,5,2,1,2,1,2,2,1,2,1,2,1,2,2,
  3,0,1,1,1,2,3,2,1,1,1,2,2,1,1,2,3,4,1,1,5,5,5,5,5,4,5,4,5,5,4,4,
  5,4,3,2,1,0,2,1,2,5,2,1,1,2,1,1,2,2,3,3,2,3,3,6,7,3,4,1,1,2,1,1,
  1,2,2,2,1,2,4,2,3,4,2,1,1,1,2,4,4,1,2,3,2,2,2,2,4,3,3,5,3,3,1,2,
  0,1,2,2,2,3,4,4,1,1,1,6,2,2,1,1,3,1,2,2,4,2,2,1,2,2,1,2,0,1,2,2,
  1,2,1,2,1,1,2,3,2,2,1,1,3,4,4,3,2,2,1,2,2,5,2,2,3,3,4,3,3,1,2,2,
  2,1,1,1,2,4,4,4,5,4,1,2,1,2,0,2,1,1,1,1,2,1,0,5,1,2,1,1,1,1,1,1,
  0,2,2,1,1,2,1,1,2,2,2,2,4,4,2,2,2,4,5,4,4,4,4,4,4,2,3,3,4,1,2,2,
  5,3,4,6,1,2,3,2,2,1,2,5,2,3,2,1,2,9,4,11,4,4,14,9,9,4,2,2,3,3,2,3,
  3,6,7,3,4,3,4,4,6,4,4,1,2,2,1,2,1,4,5,2,1,1,2,2,2,2,1,2,6,1,2,4,
  2,3,4,2,1,3,2,2,8,4,4,2,9,2,3,3,2,2,3,2,3,3,1,4,1,2,2,5,2,2,1,2,
  2,2,4,4,2,3,5,2,1,2,3,2,2,2,2,2,2,3,4,4,1,3,1,2,0,1,2,3,4,2,3,6,
  6,6,2,1,2,1,1,1,1,1,2,3,3,3,2,5,5,6,1,2,1,1,2,1,1,2,1,2,2,0,2,3,
  1,5,2,2,3,1,1,2,1,2,2,2,3,3,3,3,2,5,7,1,2,5,1,3,2,2,5,2,2,1,1,2,
  2,4,5,2,2,2,3,2,6,1,1,2,3,4,4,3,2,2,3,1,2,2,1,2,3,2,1,1,2,2,2,2,
  3,5,3,4,4,3,4,2,2,3,5,1,1,2,3,5,5,5,6,6,3,5,6,6,1,4,4,4,2,2,3,3,
  4,5,1,2,5,5,2,2,5,1,3,3,3,2,6,2,4,5,2,2,2,5,2,4,4,4,7,9,3,5,3,4,
  4,4,7,9,1,2,2,2,13,9,14,1,2,3,3,1,2,2,2,2,3,2,2,3,3,4,2,3,2,1,2,4,
  5,2,0,1,2,1,4,2,1,2,2,2,2,1,1,2,1,2,2,1,2,1,1,2,3,2,2,1,2,2,3,3,
  1,1,2,2,1,2,2,3,5,3,3,2,2,2,2,1,2,2,1,3,6,1,1,0,3,4,3,4,3,1,1,3,
  3,3,3,1,1,3,2,2,1,2,2,1,6,4,2,4,4,4,4,5,4,4,4,4,1,1,2,2,1,2,2,2,
  2,3,4,4,4,4,5,5,4,2,5,2,3,3,2,3,4,4,3,4,2,2,1,2,1,0,1,1,1,1,1,4,
  2,5,2,0,2,2,1,1,1,3,2,2,2,4,4,4,2,2,4,4,5,4,4,4,4,4,4,4,4,2,3,5,
  1,2,2,5,3,4,6,1,2,3,2,2,1,2,2,5,2,1,4,4,4,2,2,1,2,2,1,4,5,2,3,1,
  10,5,12,5,9,5,5,5,2,2,1,2,2,1,6,1,1,3,2,2,3,3,2,1,4,2,1,1,2,2,2,3,
  5,1,2,2,4,4,4,1,1,0,1,1,2,2,3,2,2,3,2,2,3,3,2,2,2,1,4,4,1,2,4,5,
  2,2,2,2,4,2,1,3,1,2,3,2,5,2,1,5,5,2,3,3,4,3,4,3,4,3,3,3,1,1,3,2,
  2,3,2,3,4,1,2,3,4,2,1,6,3,1,5,3,5,2,5,5,8,4,5,5,8,2,3,5,3,1,1,2,
  2,2,1,4,2,8,3,1,3,3,3,4,3,3,4,3,3,3,6,8,6,9,4,4,5,2,4,4,4,4,5,5,
  4,2,2,2,3,3,3,3,3,4,3,4,3,5,3,3,3,4,3,3,6,8,6,9,4,4,5,1,2,4,5,2,
  1,0,2,1,1,2,2,1,1,1,1,5,3,5,5,2,5,3,2,3,2,1,2,5,6,5,2,1,2,3,3,3,
  4,2,1,1,2,8,8,12,8,8,13,3,3,3,3,3,3,2,1,3,2,2,1,2,7,0,1,1,2,1,3,1,
  2,1,2,2,1,2,1,1,4,2,1,6,3,2,1,2,1,2,1,2,2,9,2,2,4,4,2,1,6,3,2,2,
  1,1,2,2,4,1,2,1,0,1,4,1,1,2,3,3,3,4,4,3,4,3,4,12,5,12,3,4,11,1,1,1,
  3,3,2,2,3,1,1,1,4,1,1,1,1,2,5,3,5,1,0,1,3,5,2,1,1,1,1,2,1,0,2,2,
  1,1,1,2,1,1,2,1,1,1,2,3,2,1,2,1,2,1,2,1,1,0,3,1,2,1,1,1,1,1,1,2,
  0,1,2,1,1,2,1,1,1,1,1,1,2,198,38,193,2,194,16,4,192,145,0,83,4,56,97,197,156,84,195,196,
  22,231,6,17,53,44,146,5,57,216,44,78,39,169,6,210,69,45,12,199,8,48,10,184,183,45,167,153,150,149,151,50,
  29,25,55,116,97,47,46,2,16,51,47,158,211,77,69,17,2,5,15,33,161,228,14,20,7,148,7,180,217,221,96,220,
  196,70,59,168,220,80,47,168,211,208,212,228,248,250,249,210,168,209,213,37,147,19,245,17,80,94,189,86,95,193,87,164,
  167,211,159,16,74,208,201,26,202,45,22,8,200,8,18,251,171,24,60,149,117,66,204,48,115,151,203,3,71,36,9,252,
  170,61,0,49,49,3,62,147,220,30,34,28,19,32,10,217,62,101,219,103,162,119,126,115,162,107,42,199,94,36,12,11,
  13,0,11,38,78,79,21,50,1,205,206,24,48,17,204,17,42,72,210,44,43,194,99,98,46,64,153,16,40,6,207,52,
  25,13,65,165,8,4,37,12,154,54,26,14,66,166,9,60,57,155,234,18,158,61,59,27,232,144,228,198,8,230,97,195,
  89,10,148,78,163,164,90,178,207,180,81,96,191,88,188,82,208,212,218,102,118,161,125,114,15,216,218,63,245,247,246,248,
  250,249,67,153,152,18,176,65,106,5,28,95,51,16,19,68,51,156,10,67,71,69,29,11,11,11,11,107,106,10,17,96,
  160,21,236,98,109,38,9,96,66,4,111,113,103,107,121,126,117,78,79,234,207,236,110,112,120,106,125,116,162,161,128,175,
  224,12,235,208,237,143,226,144,227,130,136,129,176,225,127,131,137,65,68,71,73,36,169,209,157,82,211,212,30,80,18,210,
  76,169,159,70,28,24,84,170,216,213,55,214,62,222,180,220,2,31,19,166,160,177,12,25,187,122,175,124,126,51,15,55,
  29,171,168,34,20,26,172,16,174,84,235,160,22,88,86,32,28,11,203,111,28,161,233,146,229,196,9,231,93,194,85,11,
  162,166,91,179,208,181,79,92,190,84,192,83,210,29,112,219,27,177,244,41,40,44,90,188,96,94,92,33,22,147,144,146,
  145,163,24,74,26,161,147,143,145,144,146,148,174,198,208,208,134,123,176,125,127,11,17,209,131,135,209,222,34,11,38,9,
  164,100,98,34,23,52,152,95,9,60,67,69,72,75,219,175,102,218,159,73,14,108,219,35,112,24,217,106,95,223,181,221,
  195,142,114,76,145,18,197,149,110,165,165,209,213,150,151,210,165,110,176,104,220,171,235,18,169,230,193,22,22,35,124,88,
  64,10,25,77,177,170,116,192,26,78,178,27,158,79,179,47,7,46,221,118,43,28,80,180,120,22,121,125,23,123,11,150,
  40,36,181,225,3,62,62,63,226,180,48,230,97,30,224,53,53,177,1,63,38,39,85,92,88,90,32,164,32,33,168,169,
  170,171,172,173,174,175,31,190,157,34,197,124,5,82,72,112,111,74,75,39,72,74,229,182,42,72,77,227,228,51,17,237,
  76,246,53,61,205,189,5,5,181,182,76,49,30,53,53,176,246,44,178,54,108,31,194,239,195,0,1,2,6,5,189,179,
  4,193,192,13,235,170,180,190,194,184,35,146,145,147,136,61,97,16,83,165,165,200,87,84,86,83,80,102,105,100,103,93,
  90,92,89,81,108,99,96,107,98,95,201,85,82,16,12,0,101,104,44,52,159,158,160,91,88,24,20,2,106,97,94,60,
  36,28,53,216,166,183,79,61,205,92,197,200,34,34,78,174,79,79,7,41,68,73,75,71,64,41,65,199,77,13,231,9,
  76,80,11,184,178,162,183,32,71,19,19,199,203,195,198,87,186,187,174,200,155,154,157,87,16,239,194,99,99,58,84,84,
  44,64,1,24,1,2,69,109,46,84,16,169,23,181,23,184,207,209,208,210,239,56,53,222,223,182,61,42,72,70,74,141,
  69,42,183,60,222,223,206,207,164,182,183,206,207,50,49,45,211,101,32,56,147,16,163,15,221,15,52,70,33,202,119,176,
  180,177,127,33,195,194,196,196,102,102,168,221,242,247,247,199,199,82,30,13,36,85,217,80,81,56,20,161,6,147,202,195,
  194,16,31,12,185,85,246,17,241,191,190,245,111,166,95,255,119,81,233,110,27,86,234,85,77,23,71,82,34,154,232,150,
  152,153,231,19,149,151,19,5,5,5,3,4,5,75,2,25,86,213,227,113,181,181,245,86,85,66,150,149,61,95,97,120,
  229,83,113,47,80,66,183,240,235,172,33,3,48,71,82,68,64,3,0,4,35,1,102,109,2,177,146,87,0,212,217,13,
  189,83,188,85,89,91,84,86,190,87,92,88,90,93,94,68,34,187,103,140,245,179,221,134,31,29,51,33,101,219,101,103,
  126,126,169,128,130,132,219,148,36,107,217,55,83,119,146,165,164,105,138,138,136,136,105,231,88,96,10,115,142,144,62,167,
  122,215,149,124,134,120,215,219,140,119,115,105,105,212,10,189,11,74,148,72,173,15,37,101,101,38,185,37,37,38,255,59,
  169,170,89,21,189,15,39,67,16,237,99,238,56,53,161,212,38,236,72,12,45,220,41,51,43,17,16,17,49,183,181,8,
  5,30,221,49,43,186,36,186,23,60,81,47,90,185,60,191,190,8,249,245,244,243,8,98,41,86,239,53,57,39,55,91,
  191,88,84,186,240,55,58,40,56,69,92,92,192,218,208,27,14,102,139,98,58,180,18,187,232,145,232,133,171,144,228,31,
  29,169,171,57,115,162,171,25,173,173,12,114,123,91,139,143,141,62,60,8,123,59,54,28,30,103,75,178,100,144,162,189,
  188,199,148,198,203,173,203,218,100,102,125,125,168,127,129,131,218,147,133,214,218,139,118,114,124,10,41,118,145,189,188,106,
  132,89,106,199,30,107,250,64,176,176,104,137,137,135,135,104,230,236,253,230,245,247,252,246,171,172,133,93,45,52,23,95,
  202,202,235,40,147,198,31,203,109,14,191,57,193,176,114,141,143,91,24,26,66,60,166,121,214,203,201,118,123,150,195,180,
  194,74,102,104,104,58,175,66,32,32,166,166,167,164,165,174,41,60,20,33,42,39,181,35,42,240,183,18,159,56,42,219,
  38,19,167,94,19,194,62,188,184,184,217,107,107,205,206,216,106,106,207,175,174,7,68,32,73,112,75,73,73,110,110,21,
  160,78,79,67,72,70,71,109,66,61,19,96,215,36,151,151,80,98,40,66,4,4,43,103,113,113,103,126,126,117,111,111,
  206,174,242,11,252,250,11,90,205,102,154,37,112,154,174,112,102,125,125,110,116,110,234,236,36,95,172,9,249,245,9,247,
  246,12,12,254,253,38,38,253,2,20,128,224,175,128,175,207,155,51,157,155,235,237,129,225,176,195,36,38,65,68,68,36,
  38,226,227,132,197,136,130,136,197,129,176,133,198,137,131,137,198,121,241,120,234,236,235,237,189,35,22,7,173,4,77,172,
  101,62,222,2,100,60,180,3,181,60,214,35,150,150,39,200,243,155,154,244,62,157,81,56,153,188,83,191,44,219,242,193,
  181,169,46,186,190,187,62,192,77,201,191,182,150,96,183,185,149,40,187,93,52,52,170,186,182,86,87,91,52,248,152,245,
  151,54,246,61,37,182,37,243,253,2,63,37,46,48,165,49,45,198,213,51,14,192,212,214,15,14,15,43,35,158,34,20,
  37,114,177,38,39,177,21,97,163,122,179,183,124,175,122,183,124,175,185,181,232,126,50,25,181,185,232,15,46,18,19,29,
  29,126,176,197,200,8,46,12,98,87,198,13,22,63,95,34,219,210,28,15,100,61,85,26,179,233,146,165,233,187,146,117,
  229,32,51,30,170,172,69,116,163,157,26,54,26,13,115,125,93,140,142,144,89,87,9,125,64,55,105,29,29,179,28,27,
  28,29,173,174,125,11,47,193,192,108,193,241,146,163,193,192,196,204,201,157,204,218,83,196,204,15,177,177,238,237,254,231,
  134,99,46,53,41,148,18,201,58,199,177,93,25,25,204,202,185,181,184,206,104,30,91,26,123,180,184,97,125,176,95,93,
  182,186,233,19,127,65,197,161,102,216,37,152,152,167,59,41,22,22,54,48,34,111,73,72,35,37,173,195,194,194,60,106,
  67,67,158,160,157,159,70,36,114,144,22,51,228,35,35,170,172,172,76,47,196,63,100,96,96,37,147,147,148,148,143,145,
  143,145,144,146,144,146,161,161,170,170,146,200,22,35,198,6,5,245,213,175,130,197,189,134,195,193,203,138,191,121,130,134,
  197,138,203,199,213,211,123,184,125,176,186,182,233,127,17,106,131,185,178,179,198,190,216,135,196,201,215,123,194,204,139,192,
  131,135,198,139,204,200,212,214,217,38,153,153,42,223,22,196,180,101,99,66,219,21,49,52,52,184,209,209,72,60,9,72,
  60,254,220,215,160,49,48,45,40,164,54,241,101,218,41,52,34,181,191,195,180,92,185,181,236,92,58,57,205,59,226,201,
  70,91,103,108,158,160,209,99,250,145,94,109,251,67,197,113,110,126,50,249,191,190,128,28,28,15,248,107,168,115,102,145,
  149,191,190,142,197,210,197,200,29,29,14,111,249,202,240,105,181,180,200,252,167,213,232,233,168,156,245,240,5,213,214,29,
  149,241,194,138,203,139,204,209,178,179,50,162,40,187,90,238,124,124,51,178,130,131,103,29,179,203,203,138,204,139,154,117,
  95,39,89,24,52,104,24,64,64,204,194,239,195,189,53,250,247,190,248,245,252,251,0,105,1,2,249,246,205,6,4,179,
  193,192,253,79,119,75,165,54,87,106,206,78,255,122,126,55,124,40,182,55,54,221,107,207,13,12,0,0,0,1,0,4,
  213,0,3,1,42,1,213,32,0,212,34,0,0,34,42,35,4,34,33,3,213,213,2,33,34,4,0,1,34,33,33,1,
  0,1,34,1,0,0,33,3,34,34,34,34,34,32,32,34,42,34,34,34,33,34,34,42,212,34,34,33,41,4,4,4,
  32,33,42,1,4,34,3,213,0,2,2,0,2,34,33,213,0,32,34,34,0,33,33,33,42,39,39,39,33,34,33,33,
  34,33,41,33,3,41,41,33,41,41,33,41,34,33,33,212,1,1,0,0,1,0,4,1,213,0,34,1,37,37,1,213,
  3,42,34,33,33,42,3,0,34,33,4,213,37,37,213,34,33,33,4,0,3,3,1,1,1,4,1,213,34,213,34,34,
  34,42,34,42,34,212,34,4,2,0,1,33,33,33,37,33,1,34,34,4,1,4,0,0,4,1,33,0,33,1,33,33,
  34,34,34,32,32,1,213,3,33,1,4,0,1,4,213,213,212,4,4,4,4,3,1,4,213,213,212,4,0,1,3,39,
  33,33,1,1,4,39,33,33,33,35,39,41,33,41,35,33,41,34,33,41,34,41,34,41,41,33,41,33,41,33,33,34,
  34,34,42,42,34,213,34,33,1,39,39,39,39,39,39,213,33,33,33,33,1,34,41,4,32,33,213,34,213,33,3,4,
  1,1,1,4,32,32,32,32,34,34,0,213,32,0,33,42,34,34,34,34,34,34,34,34,34,34,34,34,42,34,34,34,
  34,41,34,34,34,34,34,42,34,42,42,34,42,34,34,34,41,34,34,34,34,34,34,34,34,42,34,34,34,34,34,34,
  34,34,34,212,0,3,1,0,0,4,1,213,0,1,3,3,213,32,32,42,212,0,0,42,0,32,35,35,35,34,4,213,
  3,3,0,33,33,42,34,42,34,34,32,34,34,34,212,3,0,213,33,212,41,0,1,39,33,41,1,1,4,33,34,33,
  41,33,3,39,33,33,33,35,39,41,33,41,35,34,33,41,34,41,34,41,41,33,41,33,41,33,33,41,33,33,33,41,
  4,4,4,1,42,1,1,1,4,213,33,33,33,33,3,34,213,34,37,34,34,34,34,34,34,212,34,34,34,34,34,42,
  34,34,34,34,34,34,34,34,0,33,4,4,0,3,1,1,4,213,34,3,32,32,34,34,34,34,213,32,212,1,0,33,
  41,4,1,0,4,1,213,0,1,0,35,35,35,34,34,1,213,33,41,33,33,41,34,33,33,33,33,33,3,3,1,212,
  1,0,34,42,4,34,42,34,32,32,34,0,39,34,32,213,213,212,34,1,34,213,213,212,213,3,213,212,4,4,4,0,
  1,4,213,213,212,1,4,1,1,4,1,32,3,33,33,212,0,1,34,34,34,0,0,4,0,32,213,0,33,33,3,1,
  42,0,34,42,42,42,42,34,41,34,34,41,41,41,41,41,41,41,41,34,34,41,34,0,35,1,213,34,42,42,34,34,
  0,34,34,0,212,0,34,34,0,0,34,42,42,34,3,32,34,34,34,35,35,35,35,34,4,32,34,34,41,3,33,3,
  33,34,213,34,37,34,42,42,42,42,38,37,37,42,34,34,41,41,37,37,37,37,37,36,37,37,37,37,0,34,35,213,
  34,34,34,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,41,37,37,37,37,37,37,37,37,
  37,34,34,34,37,37,37,37,37,37,37,37,37,37,37,32,2,0,212,32,34,34,0,41,39,32,32,34,42,34,34,1,
  34,42,42,42,42,42,34,32,2,42,1,0,1,42,42,1,0,41,0,0,213,4,39,39,3,37,41,2,34,33,33,0,
  36,34,34,34,34,42,42,41,38,38,0,34,34,0,0,34,34,34,33,34,42,34,213,34,0,33,33,39,212,42,42,42,
  42,34,41,41,34,34,33,41,34,42,42,42,34,42,34,33,41,34,34,34,34,0,33,33,34,34,34,34,35,33,41,32,
  33,33,32,34,41,2,1,4,33,32,33,42,0,3,41,41,213,33,33,34,34,38,38,0,3,34,0,0,34,34,4,35,
  35,0,213,2,34,34,34,34,34,35,33,33,33,33,41,35,35,212,4,41,1,34,37,37,33,41,41,4,39,42,34,0,
  42,1,34,0,34,4,1,33,34,213,42,0,42,42,42,35,33,42,42,1,34,34,34,32,32,32,1,32,1,213,34,41,
  42,3,3,3,34,34,34,42,42,0,34,34,42,41,34,41,33,34,34,3,0,0,32,0,34,33,33,34,4,38,251,251,
  251,213,251,0,38,251,37,1,213,34,34,42,42,0,33,0,33,33,33,33,33,0,33,33,33,33,33,33,32,35,212,34,
  42,1,3,3,42,1,1,4,1,34,34,34,34,42,42,42,42,42,42,34,42,213,34,34,33,4,34,42,42,42,34,42,
  42,42,42,34,34,213,0,33,34,42,42,0,42,42,34,41,42,42,41,34,34,42,34,34,34,34,33,32,0,33,4,33,
  41,33,33,1,38,38,32,34,213,41,41,33,34,33,33,213,32,212,33,1,32,32,0,32,0,4,4,0,33,213,0,33,
  42,34,41,33,1,1,33,33,33,1,34,1,34,33,34,41,1,34,34,33,34,42,42,4,1,213,3,42,0,212,34,34,
  34,34,34,34,32,1,4,0,1,4,213,2,213,212,4,4,3,3,1,4,213,1,4,4,213,212,33,33,41,41,34,42,
  41,1,41,33,3,39,41,39,42,0,33,33,41,41,33,33,41,41,33,42,41,42,42,41,39,0,0,41,41,41,1,1,
  35,0,4,41,32,32,41,41,33,34,33,33,33,33,33,33,33,33,33,34,34,34,34,42,42,42,42,42,42,34,42,42,
  34,34,42,34,34,41,35,213,34,42,33,33,41,37,4,34,33,35,41,37,1,35,35,34,42,42,42,42,34,34,39,33,
  39,39,39,39,39,33,33,41,213,42,42,34,0,37,37,41,0,41,33,35,33,41,32,34,32,212,33,34,42,42,0,32,
  32,1,0,42,42,34,34,34,41,42,41,37,34,37,41,41,34,34,34,0,38,39,39,33,33,33,33,33,37,42,4,32,
  34,213,33,0,34,0,42,0,34,34,34,42,42,32,34,34,213,34,212,34,3,34,34,34,34,34,33,33,34,34,34,33,
  34,34,34,1,34,34,42,34,1,34,38,38,33,0,34,34,42,1,1,34,42,42,4,32,34,33,41,33,33,34,34,41,
  34,34,34,213,34,34,34,34,42,42,34,34,34,33,33,42,34,34,34,34,4,33,34,33,32,34,33,33,34,34,42,42,
  34,34,34,34,34,34,213,0,34,34,34,34,34,34,34,34,34,34,34,34,42,34,42,34,34,42,34,42,33,33,41,33,
  33,34,34,34,34,42,212,34,34,34,34,34,34,34,34,34,34,42,34,34,34,42,34,42,34,42,34,34,34,42,34,0,
  34,34,34,34,34,3,0,33,32,34,41,34,34,34,0,41,41,34,0,34,41,34,34,33,41,33,33,41,36,0,34,34,
  0,4,34,1,42,34,41,1,41,213,2,0,41,41,3,34,33,41,41,32,41,1,3,3,41,34,213,41,41,34,34,33,
  42,33,33,0,0,34,42,42,42,33,0,34,0,34,42,0,35,34,0,34,42,42,34,4,0,0,32,34,32,213,3,3,
  33,38,3,34,3,33,33,33,0,42,34,42,34,42,42,0,42,42,0,42,213,0,34,42,42,34,42,34,42,34,42,42,
  42,34,34,32,33,42,42,34,34,35,35,35,34,34,34,34,212,3,32,213,42,213,32,212,33,42,0,34,0,33,33,41,
  41,41,34,1,34,41,39,41,41,39,0,33,41,33,41,41,41,33,33,41,41,33,33,41,34,33,41,39,0,0,41,41,
  41,1,1,35,0,4,41,41,32,32,33,33,33,33,33,37,0,41,35,213,33,33,41,3,3,33,33,33,33,33,33,33,
  33,34,2,34,33,33,32,35,35,42,39,33,39,41,213,42,42,0,41,42,33,32,212,33,0,32,32,34,34,37,34,37,
  41,41,33,1,32,34,42,42,1,34,42,1,1,42,42,34,42,34,4,34,34,42,33,41,33,33,0,0,41,34,34,39,
  213,35,38,4,4,34,34,0,3,3,3,34,42,34,34,42,42,42,42,34,42,41,33,34,42,41,34,35,42,42,42,4,
  0,41,35,213,38,38,34,34,34,34,34,34,34,34,34,34,34,34,34,37,37,37,37,33,212,34,35,34,38,38,3,3,
  0,34,42,42,34,42,42,42,34,42,41,34,34,42,34,42,42,42,42,34,42,34,42,42,42,34,34,34,38,34,0,0,
  0,42,42,42,34,42,39,42,41,42,42,34,42,34,34,42,34,42,42,42,42,33,41,33,33,41,0,35,3,35,1,1,
  4,32,35,213,34,34,3,3,3,34,34,32,34,34,0,2,0,34,42,42,34,41,34,35,42,213,42,41,32,33,37,37,
  37,34,34,37,34,37,34,42,42,41,42,35,212,4,4,1,34,33,33,33,41,0,33,4,1,0,4,33,1,41,41,213,
  0,33,33,37,35,35,35,37,1,0,1,213,33,33,33,33,34,3,3,3,33,35,35,35,1,37,212,34,1,37,37,33,
  0,41,33,42,42,34,41,3,3,34,3,3,34,33,3,3,34,42,34,42,3,34,34,4,34,34,34,34,34,0,0,213,
  34,34,34,213,34,34,212,42,34,42,34,41,1,42,34,34,33,213,213,33,34,34,212,34,37,34,37,213,39,39,3,39,
  39,39,34,42,213,42,42,39,39,212,42,42,37,34,34,0,4,1,4,0,213,4,213,212,4,0,1,1,4,1,33,3,
  213,4,33,213,212,32,32,32,32,32,0,32,0,64,32,0,0,0,0,64,0,32,64,0,32,32,0,0,0,0,0,0,
  0,64,64,0,0,0,0,32,0,0,0,0,0,32,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,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,64,0,0,32,
  32,0,32,0,0,64,32,0,0,0,0,0,64,0,0,0,0,0,0,0,32,0,0,0,64,0,0,64,0,0,0,0,
  32,0,0,0,0,0,0,0,64,0,64,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,32,32,0,0,0,32,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,32,0,0,64,64,64,0,0,
  0,0,0,0,0,64,64,64,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,64,0,0,0,
  0,0,0,0,0,0,0,64,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,
  0,0,8,0,0,0,8,8,0,8,0,8,8,0,8,0,0,0,0,8,8,0,8,8,0,8,0,0,0,8,0,8,
  0,8,0,12,0,0,8,0,8,12,0,0,0,0,0,0,64,32,0,0,32,32,0,0,64,32,0,0,0,64,0,0,
  0,64,32,32,0,32,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,32,64,0,
  64,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,64,0,0,
  0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,64,0,
  0,10,0,0,0,0,0,64,0,64,0,32,0,0,0,0,32,0,0,64,32,0,0,0,0,0,0,0,0,64,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,64,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,64,64,64,0,
  0,0,64,64,64,64,0,64,64,0,0,0,32,0,0,64,64,64,0,0,0,0,0,0,0,0,0,0,64,32,0,0,
  6,0,32,32,0,32,0,64,32,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,32,64,0,0,0,32,32,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,14,14,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,64,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,32,0,0,0,0,32,0,32,
  0,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,0,0,0,0,0,0,
  0,0,0,64,0,32,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,
  0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,64,0,0,
  0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,
  0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,32,0,0,0,0,0,64,0,32,0,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,0,0,0,0,0,0,0,0,0,0,0,0,
  0,32,32,0,0,0,0,0,0,0,0,0,0,0,64,0,2,0,0,0,0,64,0,0,0,0,32,0,32,0,0,0,
  0,0,32,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  16,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,32,0,0,0,0,0,0,0,
  0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,64,0,64,0,
  0,0,0,32,0,32,0,0,32,0,64,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,64,0,0,32,64,0,0,0,0,0,0,0,0,0,32,0,0,64,0,64,64,0,0,0,0,0,
  0,64,0,0,0,64,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,
  0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,16,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,0,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,0,
  0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,
  32,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,32,0,0,0,32,0,0,0,0,0,0,0,0,64,0,64,
  0,0,0,0,8,12,8,0,0,8,12,8,0,0,0,0,0,12,0,8,8,0,0,0,0,0,32,8,8,0,0,0,
  0,8,0,0,0,0,0,0,0,0,8,0,0,8,0,0,64,8,0,0,8,8,8,0,0,0,0,0,0,0,0,0,
  0,0,0,8,0,0,0,0,0,0,8,8,8,0,0,0,0,0,0,64,32,0,8,8,0,0,0,0,0,0,0,0,
  0,14,8,0,0,0,8,0,8,0,0,8,8,0,0,0,0,0,8,64,0,0,0,0,0,0,0,0,0,0,8,0,
  12,0,8,0,8,0,8,0,12,0,8,0,32,0,0,0,0,0,0,0,0,0,0,0,12,0,12,12,0,0,12,12,
  12,0,12,12,0,0,0,0,0,0,32,0,0,32,0,0,0,0,0,0,0,0,64,0,32,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,32,0,32,0,0,32,0,0,32,
  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,0,0,32,0,0,0,
  0,64,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,
  64,0,64,0,64,0,0,0,0,32,0,0,0,0,0,4,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,
  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,0,0,64,0,0,0,0,
  0,0,0,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,0,0,0,0,
  0,0,0,0,0,0,0,32,0,0,0,0,0,64,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,64,0,0,0,0,16,0,16,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,32,0,32,0,0,
  0,0,0,0,0,0,64,0,0,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,32,0,0,0,32,0,0,0,0,0,64,32,0,0,0,0,0,0,0,0,32,0,64,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,64,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,
  16,0,0,0,0,0,0,0,0,0,0,0,64,0,12,12,64,0,0,64,16,16,16,16,0,0,0,0,0,0,64,64,
  0,0,0,64,0,0,0,0,64,0,0,0,0,0,0,0,0,64,0,0,0,0,64,0,0,0,0,0,32,0,0,0,
  32,64,0,64,64,0,32,0,0,0,0,0,0,64,0,0,64,64,0,0,65,69,108,105,231,77,208,97,99,117,116,229,
  98,114,101,118,229,99,105,114,227,249,102,242,103,114,97,118,229,108,112,104,225,109,97,99,242,110,228,111,103,111,238,112,
  230,112,112,108,121,70,117,110,99,116,105,111,238,114,105,110,231,115,99,242,115,105,103,238,116,105,108,100,229,117,109,236,
  66,97,99,107,115,108,97,115,232,114,246,119,101,228,99,249,101,99,97,117,115,229,114,110,111,117,108,108,105,243,116,225,
  102,242,111,112,230,114,101,118,229,115,99,242,117,109,112,101,241,67,72,99,249,79,80,217,97,99,117,116,229,240,105,116,
  97,108,68,105,102,102,101,114,101,110,116,105,97,108,196,121,108,101,121,243,99,97,114,111,238,101,100,105,236,105,114,227,
  111,110,105,110,244,100,111,244,101,100,105,108,108,225,110,116,101,114,68,111,244,102,242,104,233,105,114,99,108,101,68,111,
  244,77,105,110,117,243,80,108,117,243,84,105,109,101,243,108,111,99,107,119,105,115,101,67,111,110,116,111,117,114,73,110,
  116,101,103,114,97,236,115,101,67,117,114,108,121,68,111,117,98,108,101,81,117,111,116,229,81,117,111,116,229,111,108,111,
  238,229,110,103,114,117,101,110,244,105,110,244,116,111,117,114,73,110,116,101,103,114,97,236,112,230,114,111,100,117,99,244,
  117,110,116,101,114,67,108,111,99,107,119,105,115,101,67,111,110,116,111,117,114,73,110,116,101,103,114,97,236,114,111,115,
  243,115,99,242,117,240,67,97,240,68,196,111,116,114,97,104,228,74,99,249,83,99,249,90,99,249,97,103,103,101,242,114,
  242,115,104,246,99,97,114,111,238,249,101,236,116,225,102,242,105,97,99,114,105,116,105,99,97,108,65,99,117,116,229,68,
  111,244,117,98,108,101,65,99,117,116,229,71,114,97,118,229,84,105,108,100,229,109,111,110,228,102,102,101,114,101,110,116,
  105,97,108,196,111,112,230,244,68,111,244,69,113,117,97,236,117,98,108,101,67,111,110,116,111,117,114,73,110,116,101,103,
  114,97,236,68,111,244,119,110,65,114,114,111,247,76,101,102,116,65,114,114,111,247,82,105,103,104,116,65,114,114,111,247,
  84,101,229,111,110,103,76,101,102,116,65,114,114,111,247,82,105,103,104,116,65,114,114,111,247,82,105,103,104,116,65,114,
  114,111,247,82,105,103,104,116,65,114,114,111,247,84,101,229,85,112,65,114,114,111,247,68,111,119,110,65,114,114,111,247,
  86,101,114,116,105,99,97,108,66,97,242,119,110,65,114,114,111,247,66,97,242,85,112,65,114,114,111,247,66,114,101,118,
  229,76,101,102,116,82,105,103,104,116,86,101,99,116,111,242,84,101,101,86,101,99,116,111,242,86,101,99,116,111,242,66,
  97,242,82,105,103,104,116,84,101,101,86,101,99,116,111,242,86,101,99,116,111,242,66,97,242,84,101,229,65,114,114,111,
  247,97,114,114,111,247,115,99,242,116,114,111,235,69,78,199,84,200,97,99,117,116,229,99,97,114,111,238,105,114,227,249,
  100,111,244,102,242,103,114,97,118,229,108,101,109,101,110,244,109,97,99,242,112,116,121,83,109,97,108,108,83,113,117,97,
  114,229,86,101,114,121,83,109,97,108,108,83,113,117,97,114,229,111,103,111,238,112,230,112,115,105,108,111,238,113,117,97,
  236,84,105,108,100,229,105,108,105,98,114,105,117,237,115,99,242,105,237,116,225,117,109,236,120,105,115,116,243,112,111,110,
  101,110,116,105,97,108,197,70,99,249,102,242,105,108,108,101,100,83,109,97,108,108,83,113,117,97,114,229,86,101,114,121,
  83,109,97,108,108,83,113,117,97,114,229,111,112,230,114,65,108,236,117,114,105,101,114,116,114,230,115,99,242,71,74,99,
  249,212,97,109,109,225,228,98,114,101,118,229,99,101,100,105,236,105,114,227,249,100,111,244,102,242,231,111,112,230,114,101,
  97,116,101,114,69,113,117,97,236,76,101,115,243,70,117,108,108,69,113,117,97,236,71,114,101,97,116,101,242,76,101,115,
  243,83,108,97,110,116,69,113,117,97,236,84,105,108,100,229,115,99,242,244,72,65,82,68,99,249,97,99,101,235,244,99,
  105,114,227,102,242,105,108,98,101,114,116,83,112,97,99,229,111,112,230,114,105,122,111,110,116,97,108,76,105,110,229,115,
  99,242,116,114,111,235,117,109,112,68,111,119,110,72,117,109,240,69,113,117,97,236,73,69,99,249,74,108,105,231,79,99,
  249,97,99,117,116,229,99,105,114,227,249,100,111,244,102,242,103,114,97,118,229,237,97,99,242,103,105,110,97,114,121,201,
  112,108,105,101,243,110,244,101,103,114,97,236,114,115,101,99,116,105,111,238,118,105,115,105,98,108,101,67,111,109,109,225,
  84,105,109,101,243,111,103,111,238,112,230,116,225,115,99,242,116,105,108,100,229,117,107,99,249,109,236,74,99,105,114,227,
  249,102,242,111,112,230,115,99,242,101,114,99,249,117,107,99,249,75,72,99,249,74,99,249,97,112,112,225,99,101,100,105,
  236,249,102,242,111,112,230,115,99,242,76,74,99,249,212,97,99,117,116,229,109,98,100,225,110,231,112,108,97,99,101,116,
  114,230,114,242,99,97,114,111,238,101,100,105,236,249,101,102,116,65,110,103,108,101,66,114,97,99,107,101,244,114,114,111,
  247,66,97,242,82,105,103,104,116,65,114,114,111,247,67,101,105,108,105,110,231,68,111,117,98,108,101,66,114,97,99,107,
  101,244,119,110,84,101,101,86,101,99,116,111,242,86,101,99,116,111,242,66,97,242,70,108,111,111,242,82,105,103,104,116,
  65,114,114,111,247,86,101,99,116,111,242,84,101,229,65,114,114,111,247,86,101,99,116,111,242,114,105,97,110,103,108,229,
  66,97,242,69,113,117,97,236,85,112,68,111,119,110,86,101,99,116,111,242,84,101,101,86,101,99,116,111,242,86,101,99,
  116,111,242,66,97,242,86,101,99,116,111,242,66,97,242,97,114,114,111,247,114,105,103,104,116,97,114,114,111,247,115,115,
  69,113,117,97,108,71,114,101,97,116,101,242,70,117,108,108,69,113,117,97,236,71,114,101,97,116,101,242,76,101,115,243,
  83,108,97,110,116,69,113,117,97,236,84,105,108,100,229,102,242,236,101,102,116,97,114,114,111,247,109,105,100,111,244,111,
  110,103,76,101,102,116,65,114,114,111,247,82,105,103,104,116,65,114,114,111,247,82,105,103,104,116,65,114,114,111,247,108,
  101,102,116,97,114,114,111,247,114,105,103,104,116,97,114,114,111,247,114,105,103,104,116,97,114,114,111,247,112,230,119,101,
  114,76,101,102,116,65,114,114,111,247,82,105,103,104,116,65,114,114,111,247,115,99,242,232,116,114,111,235,244,77,97,240,
  99,249,101,100,105,117,109,83,112,97,99,229,108,108,105,110,116,114,230,102,242,105,110,117,115,80,108,117,243,111,112,230,
  115,99,242,245,78,74,99,249,97,99,117,116,229,99,97,114,111,238,101,100,105,236,249,101,103,97,116,105,118,101,77,101,
  100,105,117,109,83,112,97,99,229,84,104,105,99,107,83,112,97,99,229,110,83,112,97,99,229,86,101,114,121,84,104,105,
  110,83,112,97,99,229,115,116,101,100,71,114,101,97,116,101,114,71,114,101,97,116,101,242,76,101,115,115,76,101,115,243,
  119,76,105,110,229,102,242,111,66,114,101,97,235,110,66,114,101,97,107,105,110,103,83,112,97,99,229,112,230,244,67,111,
  110,103,114,117,101,110,244,117,112,67,97,240,68,111,117,98,108,101,86,101,114,116,105,99,97,108,66,97,242,69,108,101,
  109,101,110,244,113,117,97,236,84,105,108,100,229,120,105,115,116,243,71,114,101,97,116,101,242,69,113,117,97,236,70,117,
  108,108,69,113,117,97,236,71,114,101,97,116,101,242,76,101,115,243,83,108,97,110,116,69,113,117,97,236,84,105,108,100,
  229,72,117,109,112,68,111,119,110,72,117,109,240,69,113,117,97,236,76,101,102,116,84,114,105,97,110,103,108,229,66,97,
  242,69,113,117,97,236,115,243,69,113,117,97,236,71,114,101,97,116,101,242,76,101,115,243,83,108,97,110,116,69,113,117,
  97,236,84,105,108,100,229,78,101,115,116,101,100,71,114,101,97,116,101,114,71,114,101,97,116,101,242,76,101,115,115,76,
  101,115,243,80,114,101,99,101,100,101,243,69,113,117,97,236,83,108,97,110,116,69,113,117,97,236,82,101,118,101,114,115,
  101,69,108,101,109,101,110,244,105,103,104,116,84,114,105,97,110,103,108,229,66,97,242,69,113,117,97,236,83,113,117,97,
  114,101,83,117,98,115,101,244,69,113,117,97,236,112,101,114,115,101,244,69,113,117,97,236,117,98,115,101,244,69,113,117,
  97,236,99,99,101,101,100,243,69,113,117,97,236,83,108,97,110,116,69,113,117,97,236,84,105,108,100,229,112,101,114,115,
  101,244,69,113,117,97,236,84,105,108,100,229,69,113,117,97,236,70,117,108,108,69,113,117,97,236,84,105,108,100,229,86,
  101,114,116,105,99,97,108,66,97,242,115,99,242,116,105,108,100,229,245,79,69,108,105,231,97,99,117,116,229,99,105,114,
  227,249,100,98,108,97,227,102,242,103,114,97,118,229,109,97,99,242,101,103,225,105,99,114,111,238,111,112,230,112,101,110,
  67,117,114,108,121,68,111,117,98,108,101,81,117,111,116,229,81,117,111,116,229,242,115,99,242,108,97,115,232,116,105,108,
  100,229,109,101,243,117,109,236,118,101,114,66,97,242,114,97,99,229,107,101,244,80,97,114,101,110,116,104,101,115,105,243,
  80,97,114,116,105,97,108,196,99,249,102,242,104,233,233,108,117,115,77,105,110,117,243,111,105,110,99,97,114,101,112,108,
  97,110,229,112,230,242,101,99,101,100,101,243,69,113,117,97,236,83,108,97,110,116,69,113,117,97,236,84,105,108,100,229,
  105,109,229,111,100,117,99,244,112,111,114,116,105,111,238,97,236,115,99,242,233,81,85,79,212,102,242,111,112,230,115,99,
  242,82,66,97,114,242,69,199,97,99,117,116,229,110,231,114,242,116,236,99,97,114,111,238,101,100,105,236,249,229,118,101,
  114,115,101,69,108,101,109,101,110,244,113,117,105,108,105,98,114,105,117,237,85,112,69,113,117,105,108,105,98,114,105,117,
  237,102,242,104,239,105,103,104,116,65,110,103,108,101,66,114,97,99,107,101,244,114,114,111,247,66,97,242,76,101,102,116,
  65,114,114,111,247,67,101,105,108,105,110,231,68,111,117,98,108,101,66,114,97,99,107,101,244,119,110,84,101,101,86,101,
  99,116,111,242,86,101,99,116,111,242,66,97,242,70,108,111,111,242,84,101,229,65,114,114,111,247,86,101,99,116,111,242,
  114,105,97,110,103,108,229,66,97,242,69,113,117,97,236,85,112,68,111,119,110,86,101,99,116,111,242,84,101,101,86,101,
  99,116,111,242,86,101,99,116,111,242,66,97,242,86,101,99,116,111,242,66,97,242,97,114,114,111,247,111,112,230,117,110,
  100,73,109,112,108,105,101,243,114,105,103,104,116,97,114,114,111,247,115,99,242,232,117,108,101,68,101,108,97,121,101,228,
  83,72,67,72,99,249,99,249,79,70,84,99,249,97,99,117,116,229,227,97,114,111,238,101,100,105,236,105,114,227,249,102,
  242,104,111,114,116,68,111,119,110,65,114,114,111,247,76,101,102,116,65,114,114,111,247,82,105,103,104,116,65,114,114,111,
  247,85,112,65,114,114,111,247,105,103,109,225,109,97,108,108,67,105,114,99,108,229,111,112,230,113,114,244,117,97,114,229,
  73,110,116,101,114,115,101,99,116,105,111,238,83,117,98,115,101,244,69,113,117,97,236,112,101,114,115,101,244,69,113,117,
  97,236,85,110,105,111,238,115,99,242,116,97,242,117,226,115,101,244,69,113,117,97,236,99,99,101,101,100,243,69,113,117,
  97,236,83,108,97,110,116,69,113,117,97,236,84,105,108,100,229,104,84,104,97,244,237,240,101,114,115,101,244,69,113,117,
  97,236,115,101,244,84,72,79,82,206,82,65,68,197,83,72,99,249,99,249,97,226,245,99,97,114,111,238,101,100,105,236,
  249,102,242,104,101,114,101,102,111,114,229,116,225,105,99,107,83,112,97,99,229,110,83,112,97,99,229,105,108,100,229,69,
  113,117,97,236,70,117,108,108,69,113,117,97,236,84,105,108,100,229,111,112,230,114,105,112,108,101,68,111,244,115,99,242,
  116,114,111,235,85,97,99,117,116,229,114,242,111,99,105,242,98,114,99,249,101,118,229,99,105,114,227,249,100,98,108,97,
  227,102,242,103,114,97,118,229,109,97,99,242,110,100,101,114,66,97,242,114,97,99,229,107,101,244,80,97,114,101,110,116,
  104,101,115,105,243,105,111,238,80,108,117,243,111,103,111,238,112,230,112,65,114,114,111,247,66,97,242,68,111,119,110,65,
  114,114,111,247,68,111,119,110,65,114,114,111,247,69,113,117,105,108,105,98,114,105,117,237,84,101,229,65,114,114,111,247,
  97,114,114,111,247,100,111,119,110,97,114,114,111,247,112,101,114,76,101,102,116,65,114,114,111,247,82,105,103,104,116,65,
  114,114,111,247,115,233,108,111,238,114,105,110,231,115,99,242,116,105,108,100,229,117,109,236,86,68,97,115,232,98,97,242,
  99,249,100,97,115,232,236,101,229,114,98,97,242,244,105,99,97,108,66,97,242,76,105,110,229,83,101,112,97,114,97,116,
  111,242,84,105,108,100,229,121,84,104,105,110,83,112,97,99,229,102,242,111,112,230,115,99,242,118,100,97,115,232,87,99,
  105,114,227,101,100,103,229,102,242,111,112,230,115,99,242,88,102,242,233,111,112,230,115,99,242,89,65,99,249,73,99,249,
  85,99,249,97,99,117,116,229,99,105,114,227,249,102,242,111,112,230,115,99,242,117,109,236,90,72,99,249,97,99,117,116,
  229,99,97,114,111,238,249,100,111,244,101,114,111,87,105,100,116,104,83,112,97,99,229,116,225,102,242,111,112,230,115,99,
  242,97,97,99,117,116,229,98,114,101,118,229,227,197,228,105,114,227,117,116,229,249,101,108,105,231,230,242,103,114,97,118,
  229,108,101,102,115,121,237,112,232,112,104,225,109,97,99,242,108,231,240,110,228,97,110,228,228,115,108,111,112,229,246,231,
  229,108,229,109,115,228,97,225,226,227,228,229,230,231,232,114,244,118,226,228,115,112,232,244,122,97,114,242,111,103,111,238,
  112,230,240,197,97,99,105,242,229,105,228,111,243,112,114,111,248,101,241,114,105,110,231,115,99,242,244,121,109,240,101,241,
  116,105,108,100,229,117,109,236,119,99,111,110,105,110,244,105,110,244,98,78,111,244,97,99,107,99,111,110,231,101,112,115,
  105,108,111,238,112,114,105,109,229,115,105,237,101,241,114,118,101,229,119,101,228,103,229,98,114,235,116,98,114,235,99,111,
  110,231,249,100,113,117,239,101,99,97,117,243,229,109,112,116,121,246,112,115,233,114,110,111,245,116,225,232,119,101,101,238,
  102,242,105,103,99,97,240,105,114,227,117,240,111,100,111,244,112,108,117,243,116,105,109,101,243,115,113,99,117,240,116,97,
  242,116,114,105,97,110,103,108,101,100,111,119,238,117,240,117,112,108,117,243,118,101,229,119,101,100,103,229,107,97,114,111,
  247,108,97,99,107,108,111,122,101,110,103,229,115,113,117,97,114,229,116,114,105,97,110,103,108,229,100,111,119,238,108,101,
  102,244,114,105,103,104,244,110,235,107,49,178,180,51,180,111,99,235,110,229,113,117,105,246,111,244,111,112,230,244,116,111,
  237,119,116,105,229,120,68,204,210,236,242,200,196,213,228,245,85,204,210,236,242,214,200,204,210,232,236,242,98,111,248,100,
  204,210,236,242,232,196,213,228,245,109,105,110,117,243,112,108,117,243,116,105,109,101,243,117,204,210,236,242,246,200,204,210,
  232,236,242,112,114,105,109,229,114,101,118,229,118,98,97,242,115,99,242,101,109,233,105,237,229,111,236,226,104,115,117,226,
  117,108,236,101,244,109,240,197,229,241,99,97,99,117,116,229,240,97,110,228,98,114,99,117,240,99,97,240,117,240,100,111,
  244,243,114,101,244,111,238,99,97,112,243,114,111,238,101,100,105,236,105,114,227,117,112,243,115,237,100,111,244,101,100,105,
  236,109,112,116,121,246,110,244,101,114,100,111,244,102,242,104,99,249,101,99,235,109,97,114,235,233,105,242,197,227,101,241,
  108,101,97,114,114,111,119,108,101,102,244,114,105,103,104,244,100,210,211,97,115,244,99,105,114,227,100,97,115,232,229,102,
  110,105,110,244,109,105,228,115,99,105,242,108,117,98,243,117,105,244,111,108,111,238,229,241,109,109,225,244,240,102,238,108,
  101,109,101,110,244,120,101,243,110,231,100,111,244,105,110,244,112,230,114,111,228,249,115,242,114,97,114,242,111,115,243,115,
  99,242,117,226,229,240,229,116,100,111,244,117,100,97,114,114,236,242,101,112,242,115,227,108,97,114,242,240,240,98,114,99,
  97,240,99,97,240,117,240,100,111,244,111,242,243,114,97,114,242,237,108,121,101,113,112,114,101,227,115,117,99,227,118,101,
  229,119,101,100,103,229,114,101,238,118,101,97,114,114,111,119,108,101,102,244,114,105,103,104,244,118,101,229,119,101,228,119,
  99,111,110,105,110,244,105,110,244,121,108,99,116,249,100,65,114,242,72,97,242,97,103,103,101,242,108,101,116,232,114,242,
  115,232,246,98,107,97,114,111,247,108,97,227,99,97,114,111,238,249,228,97,103,103,101,242,114,242,111,116,115,101,241,101,
  231,108,116,225,109,112,116,121,246,102,105,115,104,244,242,104,97,114,236,242,105,97,237,111,110,228,115,117,105,244,243,229,
  103,97,109,109,225,115,105,238,246,105,100,229,111,110,116,105,109,101,243,111,110,248,106,99,249,108,99,111,114,238,114,111,
  240,111,108,108,97,242,112,230,244,101,241,100,111,244,109,105,110,117,243,112,108,117,243,115,113,117,97,114,229,117,98,108,
  101,98,97,114,119,101,100,103,229,119,110,97,114,114,111,247,100,111,119,110,97,114,114,111,119,243,104,97,114,112,111,111,
  110,108,101,102,244,114,105,103,104,244,114,98,107,97,114,111,247,99,111,114,238,114,111,240,115,99,242,249,111,236,116,114,
  111,235,116,100,111,244,114,233,230,117,97,114,242,104,97,242,119,97,110,103,108,229,122,99,249,105,103,114,97,114,242,101,
  68,68,111,244,111,244,97,99,117,116,229,115,116,101,242,99,97,114,111,238,105,242,227,111,108,111,238,249,100,111,244,229,
  102,68,111,244,242,231,114,97,118,229,243,100,111,244,236,105,110,116,101,114,243,236,243,100,111,244,109,97,99,242,112,116,
  249,115,101,244,246,115,240,49,179,180,110,231,115,240,111,103,111,238,112,230,112,97,242,115,236,108,117,243,115,233,108,111,
  238,246,113,99,105,114,227,111,108,111,238,115,105,237,108,97,110,116,103,116,242,108,101,115,243,117,97,108,243,101,115,244,
  105,246,68,196,118,112,97,114,115,236,114,68,111,244,97,114,242,115,99,242,100,111,244,105,237,116,225,232,117,109,236,114,
  239,120,99,236,105,115,244,112,101,99,116,97,116,105,111,238,111,110,101,110,116,105,97,108,229,102,97,108,108,105,110,103,
  100,111,116,115,101,241,99,249,101,109,97,108,229,102,105,108,105,231,108,105,231,108,105,231,242,105,108,105,231,106,108,105,
  231,108,97,244,108,105,231,116,110,243,110,111,230,111,112,230,114,97,108,236,235,246,112,97,114,116,105,110,244,114,97,99,
  49,178,179,180,181,182,184,50,179,181,51,180,181,184,52,181,53,182,184,55,184,115,236,111,119,238,115,99,242,103,197,236,
  97,99,117,116,229,109,109,225,228,240,98,114,101,118,229,99,105,114,227,249,100,111,244,229,236,241,241,115,108,97,110,244,
  243,99,227,100,111,244,239,236,236,101,243,102,242,231,231,105,109,101,236,106,99,249,236,197,225,234,110,197,97,240,112,114,
  111,248,229,241,241,115,105,237,111,112,230,114,97,118,229,115,99,242,105,237,229,236,244,99,227,105,242,100,111,244,108,80,
  97,242,113,117,101,115,244,114,97,112,112,114,111,248,114,242,100,111,244,101,113,108,101,115,243,113,108,101,115,243,108,101,
  115,243,115,105,237,118,101,114,116,110,101,113,241,110,197,104,65,114,242,97,105,114,115,240,108,230,109,105,108,244,114,100,
  99,249,242,99,105,242,247,98,97,242,99,105,114,227,101,97,114,116,243,117,105,244,108,108,105,240,114,99,111,238,102,242,
  107,115,101,97,114,111,247,119,97,114,111,247,111,97,114,242,109,116,104,244,111,107,108,101,102,116,97,114,114,111,247,114,
  105,103,104,116,97,114,114,111,247,112,230,114,98,97,242,115,99,242,108,97,115,232,116,114,111,235,121,98,117,108,236,112,
  104,101,238,105,97,99,117,116,229,227,105,114,227,249,101,99,249,120,99,236,102,230,242,103,114,97,118,229,233,105,105,110,
  244,110,244,110,102,105,238,111,116,225,106,108,105,231,109,97,99,242,103,229,108,105,110,229,112,97,114,244,116,232,111,230,
  112,101,228,238,99,97,114,229,102,105,238,116,105,229,111,100,111,244,244,99,97,236,101,103,101,114,243,114,99,97,236,108,
  97,114,104,235,112,114,111,228,111,99,249,103,111,238,112,230,116,225,112,114,111,228,113,117,101,115,244,115,99,242,105,238,
  197,100,111,244,243,246,246,244,105,108,100,229,117,107,99,249,109,236,106,99,105,114,227,249,102,242,109,97,116,232,111,112,
  230,115,99,242,101,114,99,249,117,107,99,249,107,97,112,112,225,246,99,101,100,105,236,249,102,242,103,114,101,101,238,104,
  99,249,106,99,249,111,112,230,115,99,242,108,65,97,114,242,114,242,116,97,105,236,66,97,114,242,197,231,72,97,242,97,
  99,117,116,229,101,109,112,116,121,246,103,114,97,238,109,98,100,225,110,231,228,108,229,240,113,117,239,114,242,226,102,243,
  102,243,104,235,108,240,112,236,115,105,237,116,236,244,97,105,236,229,243,98,97,114,242,98,114,235,114,97,99,229,235,107,
  229,115,108,228,245,99,97,114,111,238,101,100,105,236,105,236,117,226,249,100,99,225,113,117,239,242,114,100,104,97,242,117,
  115,104,97,242,115,232,229,102,116,97,114,114,111,247,116,97,105,236,104,97,114,112,111,111,110,100,111,119,238,117,240,108,
  101,102,116,97,114,114,111,119,243,114,105,103,104,116,97,114,114,111,247,243,104,97,114,112,111,111,110,243,115,113,117,105,
  103,97,114,114,111,247,116,104,114,101,101,116,105,109,101,243,231,241,241,115,108,97,110,244,243,99,227,100,111,244,239,242,
  231,101,243,115,97,112,112,114,111,248,100,111,244,101,113,103,116,242,113,103,116,242,103,116,242,115,105,237,102,105,115,104,
  244,108,111,111,242,242,231,197,104,97,114,228,245,236,98,108,235,106,99,249,236,97,114,242,99,111,114,110,101,242,104,97,
  114,228,116,114,233,109,105,100,111,244,111,117,115,244,97,99,104,229,110,197,97,240,112,114,111,248,229,241,241,115,105,237,
  111,97,110,231,114,242,98,114,235,110,103,108,101,102,116,97,114,114,111,247,114,105,103,104,116,97,114,114,111,247,109,97,
  112,115,116,239,114,105,103,104,116,97,114,114,111,247,111,112,97,114,114,111,119,108,101,102,244,114,105,103,104,244,112,97,
  242,230,108,117,243,116,105,109,101,243,119,97,115,244,98,97,242,250,101,110,103,229,230,112,97,242,108,244,114,97,114,242,
  99,111,114,110,101,242,104,97,242,228,237,116,114,233,115,97,113,117,239,99,242,232,105,237,229,231,113,226,117,239,242,116,
  114,111,235,244,99,227,105,242,100,111,244,104,114,101,229,105,109,101,243,108,97,114,242,113,117,101,115,244,114,80,97,242,
  233,229,230,117,114,100,115,104,97,242,117,104,97,242,118,101,114,116,110,101,113,241,110,197,109,68,68,111,244,97,99,242,
  108,229,244,101,115,229,240,115,116,239,100,111,119,238,108,101,102,244,117,240,114,107,101,242,99,111,109,109,225,249,100,97,
  115,232,101,97,115,117,114,101,100,97,110,103,108,229,102,242,104,239,105,99,114,239,228,97,115,244,99,105,242,100,111,244,
  110,117,243,226,228,245,108,99,240,100,242,110,112,108,117,243,111,100,101,108,243,112,230,240,115,99,242,116,112,111,243,245,
  108,116,105,109,97,240,109,97,240,110,71,231,244,246,76,101,102,116,97,114,114,111,247,114,105,103,104,116,97,114,114,111,
  247,236,244,246,82,105,103,104,116,97,114,114,111,247,86,68,97,115,232,100,97,115,232,97,98,108,225,99,117,116,229,110,
  231,240,197,105,228,111,243,112,114,111,248,116,117,242,97,236,243,98,115,240,117,109,240,229,99,97,240,114,111,238,101,100,
  105,236,111,110,231,100,111,244,117,240,249,100,97,115,232,229,65,114,242,97,114,104,235,242,111,247,100,111,244,113,117,105,
  246,115,101,97,242,105,237,120,105,115,244,243,102,242,103,197,229,241,241,115,108,97,110,244,243,115,105,237,244,242,104,65,
  114,242,97,114,242,112,97,242,233,243,228,246,106,99,249,108,65,114,242,197,97,114,242,100,242,229,102,116,97,114,114,111,
  247,114,105,103,104,116,97,114,114,111,247,241,241,115,108,97,110,244,243,243,115,105,237,244,114,233,229,109,105,228,111,112,
  230,244,105,238,197,100,111,244,118,225,226,227,110,233,118,225,226,227,112,97,242,97,108,108,101,236,115,236,244,111,108,105,
  110,244,242,99,117,229,229,227,101,241,114,65,114,242,97,114,242,227,247,105,103,104,116,97,114,114,111,247,116,114,233,229,
  115,227,99,117,229,229,242,104,111,114,116,109,105,228,112,97,114,97,108,108,101,236,105,237,229,241,109,105,228,112,97,242,
  113,115,117,98,229,112,229,117,226,197,229,115,101,244,101,241,241,99,227,101,241,240,197,229,115,101,244,101,241,241,116,103,
  236,105,108,100,229,108,231,114,105,97,110,103,108,101,108,101,102,244,101,241,114,105,103,104,244,101,241,245,237,101,114,239,
  115,240,118,68,97,115,232,72,97,114,242,97,240,100,97,115,232,103,229,244,105,110,102,105,238,108,65,114,242,229,244,114,
  105,229,114,65,114,242,116,114,105,229,115,105,237,119,65,114,242,97,114,104,235,242,111,247,110,101,97,242,111,211,97,99,
  117,116,229,115,244,99,105,242,227,249,100,97,115,232,98,108,97,227,105,246,111,244,115,111,108,228,101,108,105,231,102,99,
  105,242,242,103,111,238,114,97,118,229,244,104,98,97,242,237,105,110,244,108,97,114,242,99,105,242,114,111,115,243,105,110,
  229,244,109,97,99,242,101,103,225,105,99,114,111,238,228,110,117,243,111,112,230,112,97,242,101,114,240,108,117,243,242,97,
  114,242,228,101,242,111,230,230,237,105,103,111,230,111,242,115,108,111,112,229,246,115,99,242,108,97,115,232,111,236,116,105,
  108,100,229,109,101,243,97,243,117,109,236,118,98,97,242,112,97,242,225,108,108,101,236,115,105,237,236,244,99,249,101,114,
  99,110,244,105,111,228,109,105,236,240,116,101,110,235,102,242,104,233,246,109,109,97,244,111,110,229,233,116,99,104,102,111,
  114,235,246,108,97,110,99,235,232,107,246,117,243,97,99,105,242,226,99,105,242,100,239,245,229,109,238,115,105,237,116,119,
  239,237,111,105,110,116,105,110,244,112,230,117,110,228,242,197,97,240,99,117,229,229,227,97,112,112,114,111,248,99,117,114,
  108,121,101,241,101,241,110,97,112,112,114,111,248,101,113,241,115,105,237,115,105,237,105,109,229,243,110,197,97,240,115,105,
  237,111,228,102,97,108,97,242,108,105,110,229,115,117,114,230,240,116,239,115,105,237,117,114,101,236,115,99,242,233,117,110,
  99,115,240,113,102,242,105,110,244,111,112,230,112,114,105,109,229,115,99,242,117,97,116,101,114,110,105,111,110,243,105,110,
  244,101,115,244,101,241,111,244,114,65,97,114,242,114,242,116,97,105,236,66,97,114,242,72,97,242,97,99,229,117,116,229,
  100,105,227,101,109,112,116,121,246,110,231,228,229,108,229,113,117,239,114,242,97,240,226,102,243,227,102,243,104,235,108,240,
  112,236,115,105,237,116,236,247,116,97,105,236,105,239,110,97,108,243,98,97,114,242,98,114,235,114,97,99,229,235,107,229,
  115,108,228,245,99,97,114,111,238,101,100,105,236,105,236,117,226,249,100,99,225,108,100,104,97,242,113,117,239,242,115,232,
  101,97,236,105,110,229,112,97,114,244,243,99,244,231,102,105,115,104,244,108,111,111,242,242,104,97,114,228,245,236,239,246,
  105,103,104,116,97,114,114,111,247,116,97,105,236,104,97,114,112,111,111,110,100,111,119,238,117,240,108,101,102,116,97,114,
  114,111,119,243,104,97,114,112,111,111,110,243,114,105,103,104,116,97,114,114,111,119,243,115,113,117,105,103,97,114,114,111,
  247,116,104,114,101,101,116,105,109,101,243,110,231,115,105,110,103,100,111,116,115,101,241,108,97,114,242,104,97,242,237,109,
  111,117,115,244,97,99,104,229,110,109,105,228,111,97,110,231,114,242,98,114,235,112,97,242,230,108,117,243,116,105,109,101,
  243,112,97,242,103,244,112,111,108,105,110,244,114,97,114,242,115,97,113,117,239,99,242,232,113,226,117,239,242,116,104,114,
  101,229,105,109,101,243,114,233,229,230,108,116,114,233,117,108,117,104,97,242,248,115,97,99,117,116,229,98,113,117,239,227,
  197,97,240,114,111,238,99,117,229,229,100,105,236,105,114,227,110,197,97,240,115,105,237,112,111,108,105,110,244,115,105,237,
  249,100,111,244,226,229,101,65,114,242,97,114,104,235,242,111,247,99,244,109,233,115,119,97,242,116,109,105,110,117,243,238,
  120,244,102,242,111,119,238,104,97,114,240,99,104,99,249,249,111,114,116,109,105,228,112,97,114,97,108,108,101,236,249,105,
  103,109,225,230,246,237,100,111,244,229,241,231,197,236,197,110,229,112,108,117,243,114,97,114,242,108,97,114,242,109,97,108,
  108,115,101,116,109,105,110,117,243,115,104,240,101,112,97,114,115,236,105,228,108,229,244,229,243,111,102,116,99,249,236,226,
  97,242,112,230,112,97,100,101,243,117,105,244,242,113,99,97,240,243,117,240,243,115,117,226,229,115,101,244,101,241,240,229,
  115,101,244,101,241,245,97,114,229,230,230,114,97,114,242,115,99,242,101,116,109,238,109,105,108,229,116,97,114,230,116,97,
  242,230,114,97,105,103,104,116,101,112,115,105,108,111,238,112,104,233,110,243,117,226,197,100,111,244,229,100,111,244,109,117,
  108,244,110,197,229,112,108,117,243,114,97,114,242,115,101,244,101,241,241,110,101,241,241,105,237,117,226,240,99,227,97,112,
  112,114,111,248,99,117,114,108,121,101,241,101,241,110,97,112,112,114,111,248,101,113,241,115,105,237,115,105,237,237,110,231,
  240,177,178,179,197,100,111,244,115,117,226,229,100,111,244,104,115,111,236,117,226,108,97,114,242,109,117,108,244,110,197,229,
  112,108,117,243,115,101,244,101,241,241,110,101,241,241,105,237,117,226,240,119,65,114,242,97,114,104,235,242,111,247,110,119,
  97,242,122,108,105,231,116,97,114,103,101,244,245,98,114,235,99,97,114,111,238,101,100,105,236,249,100,111,244,101,108,114,
  101,227,102,242,104,101,114,101,180,102,111,114,229,116,225,115,121,237,246,105,99,107,97,112,112,114,111,248,115,105,237,110,
  115,240,107,97,240,115,105,237,111,114,238,105,108,100,229,109,101,243,226,97,242,228,110,244,111,101,225,240,98,111,244,99,
  105,242,230,111,114,235,115,225,112,114,105,109,229,114,97,100,229,105,97,110,103,108,229,100,111,119,238,108,101,102,244,101,
  241,241,114,105,103,104,244,101,241,100,111,244,229,109,105,110,117,243,112,108,117,243,115,226,116,105,109,229,112,101,122,105,
  117,237,115,99,242,249,104,99,249,116,114,111,235,119,105,120,244,111,104,101,97,100,108,101,102,116,97,114,114,111,247,114,
  105,103,104,116,97,114,114,111,247,117,65,114,242,72,97,242,97,99,117,116,229,114,242,98,114,99,249,101,118,229,99,105,
  114,227,249,100,97,114,242,98,108,97,227,104,97,242,102,105,115,104,244,242,103,114,97,118,229,104,97,114,236,242,98,108,
  235,108,99,111,114,238,101,242,114,111,240,116,114,233,109,97,99,242,236,111,103,111,238,112,230,112,97,114,114,111,247,100,
  111,119,110,97,114,114,111,247,104,97,114,112,111,111,110,108,101,102,244,114,105,103,104,244,108,117,243,115,233,232,108,111,
  238,117,112,97,114,114,111,119,243,114,99,111,114,238,101,242,114,111,240,105,110,231,116,114,233,115,99,242,116,100,111,244,
  105,108,100,229,114,233,230,117,97,114,242,109,236,119,97,110,103,108,229,118,65,114,242,66,97,242,246,68,97,115,232,97,
  110,103,114,244,114,101,112,115,105,108,111,238,107,97,112,112,225,110,111,116,104,105,110,231,112,104,233,233,114,111,112,116,
  239,242,104,239,115,105,103,109,225,117,98,115,101,116,110,101,241,241,112,115,101,116,110,101,241,241,116,104,101,116,225,114,
  105,97,110,103,108,101,108,101,102,244,114,105,103,104,244,99,249,100,97,115,232,101,229,98,97,242,101,241,108,108,105,240,
  114,98,97,242,244,102,242,108,116,114,233,110,115,117,226,240,111,112,230,112,114,111,240,114,116,114,233,115,99,242,117,98,
  110,197,229,112,110,197,229,122,105,103,122,97,231,119,99,105,114,227,101,100,98,97,242,103,229,241,105,101,114,240,102,242,
  111,112,230,240,242,101,97,116,232,115,99,242,120,99,97,240,105,114,227,117,240,100,116,114,233,102,242,104,65,114,242,97,
  114,242,233,108,65,114,242,97,114,242,109,97,240,110,105,243,111,100,111,244,112,230,108,117,243,116,105,109,229,114,65,114,
  242,97,114,242,115,99,242,113,99,117,240,117,112,108,117,243,116,114,233,118,101,229,119,101,100,103,229,121,97,99,117,116,
  229,249,99,105,114,227,249,101,238,102,242,105,99,249,111,112,230,115,99,242,117,99,249,109,236,122,97,99,117,116,229,99,
  97,114,111,238,249,100,111,244,101,101,116,114,230,116,225,102,242,104,99,249,105,103,114,97,114,242,111,112,230,115,99,242,
  119,234,110,234
];
static SECOND: [u32; 8] = [106,817,819,824,8202,8402,8421,65024];
static CP1252: [u16; 32] = [
  8364,129,8218,402,8222,8230,8224,8225,
  710,8240,352,8249,338,141,381,143,
  144,8216,8217,8220,8221,8226,8211,8212,
  732,8482,353,8250,339,157,382,376
];

const SLOTS: u32 = 4096;
#[repr(C, align(16))]
struct Names([u8; SLOTS as usize * 32]);
static mut NAMES: Names = Names([0; SLOTS as usize * 32]);
// UTF-8 value in the low bytes; bits 56-59 its length; bit 63 legacy.
static mut VALS: [u64; SLOTS as usize] = [0; SLOTS as usize];
static mut READY: bool = false;

#[inline(always)]
unsafe fn data(i: usize) -> u32 {
    unsafe { *(addr_of!(DATA) as *const u8).add(i) as u32 }
}
#[inline(always)]
fn slot(h: u32) -> *mut u8 {
    unsafe { (addr_of_mut!(NAMES) as *mut u8).add(h as usize * 32) }
}
#[inline(always)]
unsafe fn val(h: u32) -> *mut u64 {
    unsafe { (addr_of_mut!(VALS) as *mut u64).add(h as usize) }
}
#[inline(always)]
unsafe fn load(p: *const u8) -> v128 {
    unsafe { v128_load(p as *const v128) }
}
#[inline(always)]
unsafe fn store(p: *mut u8, v: v128) {
    unsafe { v128_store(p as *mut v128, v) }
}
#[inline(always)]
unsafe fn rd(p: *const u8, i: u32) -> u32 {
    unsafe { *p.add(i as usize) as u32 }
}

// Hash of a name zero-padded to 32 bytes in k0 and k1.
#[inline(always)]
fn name_hash(k0: v128, k1: v128) -> u32 {
    let h = u64x2_extract_lane::<0>(k0).wrapping_mul(0x9E3779B97F4A7C15)
        ^ u64x2_extract_lane::<1>(k0).wrapping_mul(0xC2B2AE3D27D4EB4F)
        ^ u64x2_extract_lane::<0>(k1).wrapping_mul(0x165667B19E3779F9);
    (h >> 52) as u32
}

// Returns the slot holding the name k0:k1 (zero-padded), or SLOTS.
#[inline(always)]
unsafe fn lookup(k0: v128, k1: v128) -> u32 {
    let mut h = name_hash(k0, k1);
    loop {
        let p = slot(h);
        let x = unsafe { v128_or(v128_xor(load(p), k0), v128_xor(load(p.add(16)), k1)) };
        if !v128_any_true(x) {
            return h;
        }
        if unsafe { *p } == 0 {
            return SLOTS;
        }
        h = (h + 1) & (SLOTS - 1);
    }
}

// Writes c as UTF-8 and returns its length. Always stores 4 bytes (the
// buffer has room) and selects the encoding without branches.
#[inline(always)]
unsafe fn put_utf8(o: *mut u8, c: u32) -> u32 {
    let n = 1 + (c >= 0x80) as u32 + (c >= 0x800) as u32 + (c >= 0x10000) as u32;
    let t1 = 0x80 | (c & 63);
    let t2 = 0x80 | (c >> 6 & 63);
    let t3 = 0x80 | (c >> 12 & 63);
    let w = if n == 1 {
        c
    } else if n == 2 {
        (0xC0 | c >> 6) | t1 << 8
    } else if n == 3 {
        (0xE0 | c >> 12) | t2 << 8 | t1 << 16
    } else {
        (0xF0 | c >> 18) | t3 << 8 | t2 << 16 | t1 << 24
    };
    unsafe { (o as *mut u32).write_unaligned(w) };
    n
}

#[inline(never)]
unsafe fn build() {
    let mut name = [0u8; 64];
    let np = name.as_mut_ptr();
    let mut s = 4 * N;
    for i in 0..N {
        unsafe {
            let mut j = data(i) as usize;
            loop {
                let c = data(s);
                s += 1;
                *np.add(j) = (c & 127) as u8;
                j += 1;
                if c >= 128 {
                    break;
                }
            }
            store(np.add(j), u8x16_splat(0));
            store(np.add(j + 16), u8x16_splat(0));
            let k0 = load(np);
            let k1 = load(np.add(16));
            let mut h = name_hash(k0, k1);
            while *slot(h) != 0 {
                h = (h + 1) & (SLOTS - 1);
            }
            store(slot(h), k0);
            store(slot(h).add(16), k1);
            let m = data(3 * N + i);
            let mut v = 0u128;
            let vp = addr_of_mut!(v) as *mut u8;
            let mut e = put_utf8(vp, data(N + i) | data(2 * N + i) << 8 | (m >> 6 & 1) << 16);
            if m & 30 != 0 {
                let sc = *(addr_of!(SECOND) as *const u32).add((m >> 1 & 15) as usize - 1);
                e += put_utf8(vp.add(e as usize), sc);
            }
            *val(h) = v as u64 | (e as u64) << 56 | ((m >> 5 & 1) as u64) << 63;
        }
    }
    unsafe { READY = true };
}

#[inline(always)]
unsafe fn put_named(o: *mut u8, e: u32) -> u32 {
    unsafe {
        let v = *val(e);
        (o as *mut u64).write_unaligned(v);
        (v >> 56 & 15) as u32
    }
}

#[inline(always)]
fn hex_val(c: u32) -> u32 {
    if c.wrapping_sub('0' as u32) < 10 {
        return c - '0' as u32;
    }
    let l = (c | 0x20).wrapping_sub('a' as u32);
    if l < 6 { l + 10 } else { 16 }
}

#[inline(always)]
fn prefix(len: u32, iota: v128, w: v128) -> v128 {
    v128_and(w, u8x16_lt(iota, u8x16_splat(len as u8)))
}

// Decodes the reference at p (just after '&') into out+o. Returns
// (bytes consumed after '&', bytes written), or consumed 0 if none.
#[inline(always)]
unsafe fn reference(p: *const u8, out: *mut u8) -> (u32, u32) {
    unsafe {
        if rd(p, 0) == '#' as u32 {
            let mut q: u32;
            let mut v: u32 = 0;
            if rd(p, 1).wrapping_sub('0' as u32) < 10 {
                q = 1;
                while rd(p, q).wrapping_sub('0' as u32) < 10 {
                    v = v * 10 + (rd(p, q) - '0' as u32);
                    if v > 0x10FFFF {
                        v = 0x110000;
                    }
                    q += 1;
                }
            } else if (rd(p, 1) | 0x20) == 'x' as u32 && hex_val(rd(p, 2)) < 16 {
                q = 2;
                loop {
                    let dv = hex_val(rd(p, q));
                    if dv >= 16 {
                        break;
                    }
                    v = v << 4 | dv;
                    if v > 0x10FFFF {
                        v = 0x110000;
                    }
                    q += 1;
                }
            } else {
                return (0, 0);
            }
            if rd(p, q) == ';' as u32 {
                q += 1;
            }
            if v.wrapping_sub(0x80) < 32 {
                v = *(addr_of!(CP1252) as *const u16).add(v as usize - 0x80) as u32;
            } else if v == 0 || v.wrapping_sub(0xD800) < 0x800 || v > 0x10FFFF {
                v = 0xFFFD;
            }
            return (q, put_utf8(out, v));
        }
        // The name is the run of ASCII letters and digits after '&'.
        let w0 = load(p);
        let w1 = load(p.add(16));
        let mut len: u32 = 0;
        while len < 32 {
            let ch = rd(p, len);
            if (ch | 0x20).wrapping_sub('a' as u32) >= 26 && ch.wrapping_sub('0' as u32) >= 10 {
                break;
            }
            len += 1;
        }
        if len == 0 {
            return (0, 0);
        }
        let iota0 = u8x16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
        if len < 32 && rd(p, len) == ';' as u32 {
            let iota1 = u8x16(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31);
            let e = lookup(prefix(len, iota0, w0), prefix(len, iota1, w1));
            if e != SLOTS {
                return (len + 1, put_named(out, e));
            }
        }
        // html.unescape falls back to the longest legacy name (at most 6
        // bytes) that prefixes the name, used without ';'.
        let mut x = if len < 6 { len } else { 6 };
        while x >= 2 {
            let e = lookup(prefix(x, iota0, w0), u8x16_splat(0));
            if e != SLOTS && *val(e) >> 63 != 0 {
                return (x, put_named(out, e));
            }
            x -= 1;
        }
        (0, 0)
    }
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn render(n: u32) -> u64 {
    unsafe {
        let out = buf();
        let s = out.add(IN_OFF as usize);
        let mut o: u32 = 0;
        let mut i: u32 = 0;
        if !READY {
            build();
        }
        *s.add(n as usize) = b'&';
        let amp = u8x16_splat(b'&');
        loop {
            let a = load(s.add(i as usize));
            let b = load(s.add(i as usize + 16));
            store(out.add(o as usize), a);
            store(out.add(o as usize + 16), b);
            let m = u8x16_bitmask(u8x16_eq(a, amp)) as u32 | (u8x16_bitmask(u8x16_eq(b, amp)) as u32) << 16;
            if m == 0 {
                i += 32;
                o += 32;
                continue;
            }
            let k = m.trailing_zeros();
            i += k;
            o += k;
            if i >= n {
                break;
            }
            // s[i] is '&'.
            let (used, wrote) = reference(s.add(i as usize + 1), out.add(o as usize));
            if used == 0 {
                *out.add(o as usize) = b'&';
                o += 1;
                i += 1;
            } else {
                o += wrote;
                i += 1 + used;
            }
        }
        o as u64 | (out as u64) << 32
    }
}

#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
    core::arch::wasm32::unreachable()
}

Run it on the example input with qipdo (Node.js 22 or newer):

printf '%s' 'Fish &amp; chips &mdash; caf&eacute; &lt;3 &#x1F600; &copy 2026 &notit;' | npx qipdo calculated.world components/8b7aa3bc90f3fb96cded65adde930485f065ad967142392e97f29a201ca4f100.wasm

no_std Rust port of the size/speed middle-ground C entry: 2,125 entity names sorted and front-coded with code points in byte planes, expanded on first render into an open-addressed hash table of 32-byte padded names and ready-to-store UTF-8 values. core::arch::wasm32 SIMD copy loop stops only at &, sentinel & removes bounds checks, in-place decode. Passed 6,835 compliance cases, 68,000 fuzz cases and 3,291 benchmark fixtures locally.

Build details

Compiler, size, memory and checksum
Submitted
10 November 2026 at 11:35 UTC
Language
Rust
Compiler
rustc 1.99.0 --edition 2024 --crate-type cdylib --target wasm32-unknown-unknown -C target-feature=+simd128 -C opt-level=z -C panic=abort -C lto -C codegen-units=1 -C strip=symbols -C link-arg=-zstack-size=4096 -C link-arg=--initial-memory=1507328 -C link-arg=--max-memory=1507328
Size
18.3 KiB, gzip 10.2 KiB
Download
~150 ms on Slow 4G (Lighthouse’s 1.6 Mbps, 150 ms round trips)
Memory
23 pages (1.4 MiB)
SIMD
yes
AI models
claude-opus-5-5
Functions, loops, branches and other static counts
Functions
5
Instructions
1,033
Loops
10
Conditional branches
34
Indirect calls
0
Memory loads
18
Memory stores
10
SIMD instructions
52
Potentially trapping instructions
46

Instruction sites in the binary, not executions, counted by qip.dev’s wasm-counts.