From f9786d7c902351cbc22f6c2af8b632711d6e2e52 Mon Sep 17 00:00:00 2001 From: Joseph <162703152+josephnef@users.noreply.github.com> Date: Sun, 7 Jun 2026 21:27:04 +0300 Subject: [PATCH] Add Sliding-Window RLC (RFC 8681) FEC scheme + --fec-scheme switch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Companion to the RaptorQ implementation (#86). RaptorQ is a block code; each IP packet has to wait for K source symbols to accumulate before any encoded output ships, giving an unavoidable ~95 ms per-packet latency floor on this link even at K=8/flush=20 ms. RFC 8681 RLC is a sliding-window code: every source symbol is shipped systematically (zero encoder buffer), repair symbols are linear combinations over the last `window` source symbols, and the decoder can emit each source the instant it arrives unmodified — better for interactive traffic. Per user direction the implementation wraps Inria's reference C library (irtf-nwcrg/swif-codec, co-authored by Vincent Roca, the RFC 8681 author) via cffi rather than reimplementing the codec in pure Python; the vendored source is patched (see vendor/swif-codec/PATCHES.md) to (1) fix a void/void* mismatch in the generic callback signature that breaks strict C99 builds, (2) drop a debug `#define DEBUG 1` and a few hardcoded `printf` / `full_symbol_dump` calls that flooded stdout. Wire format A new RLC envelope MAGIC `0xF534` lives alongside RaptorQ's frozen `0xF52E`. The receive dispatcher peeks the first two bytes of the stream payload and routes per-frame — a mixed-scheme deployment is silently rejected (the foreign decoder counts the symbol as malformed) instead of corrupting IP traffic. RLC inner envelope (14 B header + symbol_size payload): MAGIC(2) VER(1) TYPE(1) SYMBOL_SIZE(2) ESI(4) WIN(1) KEY(2) DT(1) Source symbols ride the same length-prefix concat-packing scheme as RaptorQ; the shared `PACKET_LEN_PREFIX` constant lives at the dispatcher. Files * `stream_fec.py` reshapes into a thin dispatcher: `FecConfig` grows `scheme` / `window` / `density_threshold` fields, `make_encoder` / `make_decoder` route to the right module. Pre-RLC callers that construct `FecConfig(k=…)` and call `FecEncoder(cfg)` still work via the backward-compat aliases — `scheme` defaults to "raptorq" so existing tests don't change behaviour. `tun_p2p.py`'s `--fec-scheme` flag flips the user-facing default to "rlc". * `stream_fec_raptorq.py` carries the moved-out RaptorQ classes unchanged (renamed `RaptorQEncoder` / `RaptorQDecoder`). * `stream_fec_rlc.py` new — `RlcEncoder` / `RlcDecoder` over the cffi binding. Encoder emits 1 source envelope + ceil(overhead) repair envelopes per sealed source symbol; decoder feeds source symbols straight through (systematic) and rebuilds the encoder's coding window on each repair to let swif-codec re-derive the same TinyMT32-driven coefficients. * `_swif_build.py` — cffi extension builder (drives gcc directly, bypasses setuptools-distutils path mangling that broke the standard `ffi.compile()` path on modern setuptools). * `vendor/swif-codec/` — pinned snapshot of upstream commit `de8cd8e`, CeCILL-B; PATCHES.md / COMMIT / AUTHORS retained. * `test_stream_fec_rlc.py` — 13 RLC tests: round-trip, loss tolerance at 0/10/20%, overhead bumping for 30% loss, concatenation packing, oversized packet, dispatcher MAGIC routing, garbage envelope drop, partial-symbol flush, distinct-MAGIC assertion, config validation. * `tun_p2p.py` — `--fec-scheme` / `--fec-window` / `--fec-density-threshold` flags. The `make_encoder` / `make_decoder` factories replace the direct constructor calls; the tx_thread / rx_thread / fec_flush_thread are scheme-agnostic. TUN write paths now drop malformed FEC-recovered packets at the boundary (count as `mal`) instead of taking the bridge down. Verification Offline — `cd tools/precoder && uv sync && uv run pytest`: * 100 tests pass (31 pipeline + 37 stream + 19 raptorq + 13 rlc). * `python tun_p2p.py --help` parses both scheme flag families. Hardware (two-netns single-host bench, RTL8812AU 0x8812 + TP-Link Archer T2U Plus / RTL8821AU 0x0120, ch 6), 10-minute soak (600 pings at 1 Hz, no --repeat): | Scheme | Config | Loss | RTT min/avg/max | blk-lost | |---------|---------------------|-------:|----------------:|---------:| | RLC | W=16, R/K=1, 20ms | 6.0% | 13 / **42** / 79 ms | 10 / 586 | | RaptorQ | K=8, R/K=1, 20ms | 0.17% | 59 / **95** / 146 ms | 1 / 606 | The 6 % RLC loss is end-to-end after recovery: ~1.7 % of RLC blocks are unrecoverable (window expires before enough repairs land); each unrecoverable block can carry multiple concatenation-packed ICMP packets, hence the higher packet-level number. Raising `--fec-overhead` closes the gap at the cost of airtime. Median RTT drops by ~45 % vs RaptorQ — the systematic-emission win that motivated bringing in a second scheme. Co-Authored-By: Claude Opus 4.7 --- tools/precoder/.gitignore | 6 + tools/precoder/_swif_build.py | 186 + tools/precoder/pyproject.toml | 11 +- tools/precoder/stream_fec.py | 414 +- tools/precoder/stream_fec_raptorq.py | 235 + tools/precoder/stream_fec_rlc.py | 473 + tools/precoder/test_stream_fec.py | 6 +- tools/precoder/test_stream_fec_rlc.py | 183 + tools/precoder/tun_p2p.py | 53 +- tools/precoder/uv.lock | 137 +- tools/precoder/vendor/swif-codec/AUTHORS.txt | 17 + tools/precoder/vendor/swif-codec/COMMIT | 1 + tools/precoder/vendor/swif-codec/LICENCE.txt | 26 + tools/precoder/vendor/swif-codec/PATCHES.md | 45 + .../vendor/swif-codec/README-upstream.md | 111 + tools/precoder/vendor/swif-codec/src/Makefile | 101 + .../vendor/swif-codec/src/Makefile.liblc | 15 + .../swif-codec/src/README-full-symbol.md | 33 + .../precoder/vendor/swif-codec/src/swif_api.c | 377 + .../precoder/vendor/swif-codec/src/swif_api.h | 709 ++ .../swif-codec/src/swif_coding_coefficients.c | 93 + .../swif-codec/src/swif_coding_coefficients.h | 41 + .../vendor/swif-codec/src/swif_full_symbol.c | 11 + .../vendor/swif-codec/src/swif_full_symbol.h | 183 + .../swif-codec/src/swif_full_symbol_impl.c | 810 ++ .../swif-codec/src/swif_full_symbol_impl.h | 167 + .../swif-codec/src/swif_full_symbol_lc.c | 233 + .../vendor/swif-codec/src/swif_general.h | 109 + .../vendor/swif-codec/src/swif_includes.h | 25 + .../vendor/swif-codec/src/swif_linear-code.c | 314 + .../vendor/swif-codec/src/swif_linear-code.h | 230 + .../vendor/swif-codec/src/swif_prng.c | 142 + .../vendor/swif-codec/src/swif_prng.h | 74 + .../vendor/swif-codec/src/swif_rlc_api.c | 628 ++ .../vendor/swif-codec/src/swif_rlc_api.h | 269 + .../vendor/swif-codec/src/swif_rlc_cb.h | 115 + .../vendor/swif-codec/src/swif_symbol.c | 119 + .../vendor/swif-codec/src/swif_symbol.h | 126 + .../swif-codec/src/swif_table-mul-gf256.c | 8256 +++++++++++++++++ 39 files changed, 14766 insertions(+), 318 deletions(-) create mode 100644 tools/precoder/.gitignore create mode 100644 tools/precoder/_swif_build.py create mode 100644 tools/precoder/stream_fec_raptorq.py create mode 100644 tools/precoder/stream_fec_rlc.py create mode 100644 tools/precoder/test_stream_fec_rlc.py create mode 100644 tools/precoder/vendor/swif-codec/AUTHORS.txt create mode 100644 tools/precoder/vendor/swif-codec/COMMIT create mode 100644 tools/precoder/vendor/swif-codec/LICENCE.txt create mode 100644 tools/precoder/vendor/swif-codec/PATCHES.md create mode 100644 tools/precoder/vendor/swif-codec/README-upstream.md create mode 100644 tools/precoder/vendor/swif-codec/src/Makefile create mode 100644 tools/precoder/vendor/swif-codec/src/Makefile.liblc create mode 100644 tools/precoder/vendor/swif-codec/src/README-full-symbol.md create mode 100644 tools/precoder/vendor/swif-codec/src/swif_api.c create mode 100644 tools/precoder/vendor/swif-codec/src/swif_api.h create mode 100644 tools/precoder/vendor/swif-codec/src/swif_coding_coefficients.c create mode 100644 tools/precoder/vendor/swif-codec/src/swif_coding_coefficients.h create mode 100644 tools/precoder/vendor/swif-codec/src/swif_full_symbol.c create mode 100644 tools/precoder/vendor/swif-codec/src/swif_full_symbol.h create mode 100644 tools/precoder/vendor/swif-codec/src/swif_full_symbol_impl.c create mode 100644 tools/precoder/vendor/swif-codec/src/swif_full_symbol_impl.h create mode 100644 tools/precoder/vendor/swif-codec/src/swif_full_symbol_lc.c create mode 100644 tools/precoder/vendor/swif-codec/src/swif_general.h create mode 100644 tools/precoder/vendor/swif-codec/src/swif_includes.h create mode 100644 tools/precoder/vendor/swif-codec/src/swif_linear-code.c create mode 100644 tools/precoder/vendor/swif-codec/src/swif_linear-code.h create mode 100644 tools/precoder/vendor/swif-codec/src/swif_prng.c create mode 100644 tools/precoder/vendor/swif-codec/src/swif_prng.h create mode 100644 tools/precoder/vendor/swif-codec/src/swif_rlc_api.c create mode 100644 tools/precoder/vendor/swif-codec/src/swif_rlc_api.h create mode 100644 tools/precoder/vendor/swif-codec/src/swif_rlc_cb.h create mode 100644 tools/precoder/vendor/swif-codec/src/swif_symbol.c create mode 100644 tools/precoder/vendor/swif-codec/src/swif_symbol.h create mode 100644 tools/precoder/vendor/swif-codec/src/swif_table-mul-gf256.c diff --git a/tools/precoder/.gitignore b/tools/precoder/.gitignore new file mode 100644 index 0000000..af57a09 --- /dev/null +++ b/tools/precoder/.gitignore @@ -0,0 +1,6 @@ +# cffi build artifacts for the vendored swif-codec RLC extension. +# Built locally by `uv run python _swif_build.py` (also auto-built on +# first `import stream_fec_rlc`). See _swif_build.py and stream_fec_rlc.py. +_swif_ext.c +_swif_ext.*.so +_swif_build_tmp/ diff --git a/tools/precoder/_swif_build.py b/tools/precoder/_swif_build.py new file mode 100644 index 0000000..ab8839e --- /dev/null +++ b/tools/precoder/_swif_build.py @@ -0,0 +1,186 @@ +"""cffi build script for the vendored swif-codec library. + +Run with `python _swif_build.py` to produce `_swif_ext*.so` next to this +file. The generated module is `_swif_ext`; `stream_fec_rlc.py` does +`from _swif_ext import ffi, lib`. + +The cffi `cdef` section declares only the subset of the swif API we +actually use from Python — the RLC-specific helpers plus the generic +encoder/decoder type-erased pointer plumbing. We skip the +TLV-style parameter setter/getter machinery and reach down to the codec's +direct-call helpers because the cdef-able C subset is smaller that way. +""" + +from __future__ import annotations + +import glob +import os +import sys + +from cffi import FFI + +HERE = os.path.dirname(os.path.abspath(__file__)) +SRC = os.path.join(HERE, "vendor", "swif-codec", "src") + +# Upstream uses a C-amalgamation pattern: swif_api.c does +# `#include "swif_rlc_api.c"` which in turn does +# `#include "swif_full_symbol_impl.c"`. Compiling swif_api.c alone yields +# the entire codec; compiling it + swif_rlc_api.c + swif_full_symbol.c +# triggers multiple-definition linker errors because all three .o files +# define `full_symbol_scale`, `full_symbol_add`, etc. +# +# So our build list is the four LEAF translation units the amalgamation +# does NOT pull in by `#include`: +_LIB_SOURCES = [ + "swif_api.c", # pulls in swif_rlc_api.c + swif_full_symbol_impl.c + "swif_coding_coefficients.c", + "swif_prng.c", # tinymt32_init / tinymt32_generate_uint32 + "swif_symbol.c", # gf256_mul / gf256_inv / symbol_add_scaled +] +C_FILES = [os.path.join(SRC, name) for name in _LIB_SOURCES] +for path in C_FILES: + if not os.path.isfile(path): + raise SystemExit( + f"_swif_build.py: vendored source {path} missing — has the " + f"swif-codec snapshot been updated?" + ) + +ffi = FFI() + +# Public surface — keep this slim so the cdef stays auditable. Everything we +# call from Python goes here; helper code that's only invoked internally +# (swif_full_symbol_impl, the GF(2^8) tables) stays inside the C TU. +ffi.cdef(r""" + typedef enum { + SWIF_STATUS_OK = 0, + SWIF_STATUS_FAILURE, + SWIF_STATUS_ERROR + } swif_status_t; + + typedef enum { + SWIF_CODEPOINT_NULL = 0, + SWIF_CODEPOINT_RLC_GF_256_FULL_DENSITY_CODEC + } swif_codepoint_t; + + typedef uint32_t esi_t; + + /* The generic encoder/decoder structs carry function-pointer tables. + * We only expose the pointer; all calls go through the RLC-specific + * wrappers below. */ + typedef struct swif_encoder { ...; } swif_encoder_t; + typedef struct swif_decoder { ...; } swif_decoder_t; + + /* === RLC encoder === */ + swif_encoder_t* swif_rlc_encoder_create( + swif_codepoint_t codepoint, + uint32_t verbosity, + uint32_t symbol_size, + uint32_t max_coding_window_size); + + swif_status_t swif_rlc_encoder_release(swif_encoder_t* enc); + + swif_status_t swif_rlc_encoder_add_source_symbol_to_coding_window( + swif_encoder_t* enc, void* new_src_symbol_buf, esi_t esi); + + swif_status_t swif_rlc_encoder_remove_source_symbol_from_coding_window( + swif_encoder_t* enc, esi_t old_esi); + + swif_status_t swif_rlc_encoder_get_coding_window_information( + swif_encoder_t* enc, esi_t* first, esi_t* last, uint32_t* nss); + + swif_status_t swif_encoder_generate_coding_coefs( + swif_encoder_t* enc, uint32_t key, uint32_t dt); + + swif_status_t swif_rlc_build_repair_symbol( + swif_encoder_t* enc, void** new_buf); + + /* === RLC decoder === */ + swif_decoder_t* swif_rlc_decoder_create( + swif_codepoint_t codepoint, + uint32_t verbosity, + uint32_t symbol_size, + uint32_t max_coding_window_size, + uint32_t max_linear_system_size); + + swif_status_t swif_rlc_decoder_release(swif_decoder_t* dec); + + /* The decoder reports decoded source symbols through this callback + * pair (set once, the codec holds the function pointers and a context). + * Python provides cffi `@ffi.callback`-decorated handlers. + * + * decodable_source_symbol_callback returns a void* — the application's + * destination buffer where the codec will write the decoded bytes. + * The codec calls decoded_source_symbol_callback once those bytes are + * in place; the application then takes ownership. + */ + swif_status_t swif_rlc_decoder_set_callback_functions( + swif_decoder_t* dec, + void (*source_symbol_removed_from_linear_system_callback)( + void* context, esi_t old_symbol_esi), + void* (*decodable_source_symbol_callback)( + void* context, esi_t esi), + void* (*decoded_source_symbol_callback)( + void* context, void* new_symbol_buf, esi_t esi), + void* context_4_callback); + + swif_status_t swif_rlc_decoder_decode_with_new_source_symbol( + swif_decoder_t* dec, void* const new_symbol_buf, esi_t esi); + + swif_status_t swif_rlc_decoder_decode_with_new_repair_symbol( + swif_decoder_t* dec, void* const new_symbol_buf, esi_t esi); + + swif_status_t swif_rlc_decoder_reset_coding_window(swif_decoder_t* dec); + + swif_status_t swif_rlc_decoder_add_source_symbol_to_coding_window( + swif_decoder_t* dec, esi_t esi); + + swif_status_t swif_decoder_generate_coding_coefs( + swif_decoder_t* dec, uint32_t key, uint32_t dt); +""") + +ffi.set_source( + "_swif_ext", + r""" + #include + #include "swif_rlc_api.h" + """, + sources=C_FILES, + include_dirs=[SRC], + extra_compile_args=["-std=c99", "-O2", "-Wno-unused-parameter", + "-Wno-unused-variable", "-Wno-unused-function", + "-Wno-pointer-sign", "-Wno-incompatible-pointer-types", + "-Wformat", "-Wno-error=format-security"], +) + + +if __name__ == "__main__": + # cffi's ffi.compile() funnels through setuptools' distutils which on + # modern setuptools mishandles absolute paths in `sources=` (the link + # step looks for objects under the build tmpdir, but the compile step + # placed them under their absolute path). We bypass setuptools by + # emitting the wrapper C and driving gcc directly. + import subprocess + import sysconfig + + # 1. Emit the cffi-generated wrapper C source. + c_file = os.path.join(HERE, "_swif_ext.c") + ffi.emit_c_code(c_file) + + # 2. Compile all C files (wrapper + vendored sources) and link the .so. + py_inc = sysconfig.get_path("include") + ext_suffix = sysconfig.get_config_var("EXT_SUFFIX") or ".so" + so_path = os.path.join(HERE, f"_swif_ext{ext_suffix}") + cmd = [ + "gcc", "-fPIC", "-shared", + "-std=c99", "-O2", + "-Wno-unused-parameter", "-Wno-unused-variable", + "-Wno-unused-function", "-Wno-pointer-sign", + "-Wno-incompatible-pointer-types", + "-Wformat", "-Wno-error=format-security", + f"-I{py_inc}", f"-I{SRC}", + c_file, *C_FILES, + "-o", so_path, + ] + print(" ".join(cmd), file=sys.stderr) + subprocess.check_call(cmd) + print(f"_swif_ext built at {so_path}", file=sys.stderr) diff --git a/tools/precoder/pyproject.toml b/tools/precoder/pyproject.toml index 2632ca1..e257d5d 100644 --- a/tools/precoder/pyproject.toml +++ b/tools/precoder/pyproject.toml @@ -9,8 +9,13 @@ dependencies = [ # RaptorQ (RFC 6330) fountain-code FEC for the stream link's # packet-erasure channel. cberner's Rust+PyO3 implementation has # manylinux abi3 wheels on PyPI so `uv sync` doesn't need a Rust - # toolchain. Used by stream_fec.py / tun_p2p.py. + # toolchain. Used by stream_fec_raptorq.py. "raptorq>=2", + # cffi binds the vendored swif-codec C library (irtf-nwcrg/swif-codec, + # RFC 8681 sliding-window RLC) used by stream_fec_rlc.py. The cffi + # extension is built in-tree by `_swif_build.py`; run that once after + # `uv sync`. + "cffi>=1.16", ] # Phase-B RF verification (tools/precoder/fft_capture.py) needs an SDR stack. @@ -24,9 +29,11 @@ sdr = [ [dependency-groups] dev = [ "pytest>=7", + "setuptools>=82.0.1", ] [tool.pytest.ini_options] # test_pipeline.py lives alongside the module; default (prepend) import mode # puts this dir on sys.path so `import encode_subcarriers` resolves. -testpaths = ["test_pipeline.py", "test_stream.py", "test_stream_fec.py"] +testpaths = ["test_pipeline.py", "test_stream.py", "test_stream_fec.py", + "test_stream_fec_rlc.py"] diff --git a/tools/precoder/stream_fec.py b/tools/precoder/stream_fec.py index f418e55..85eb4d9 100644 --- a/tools/precoder/stream_fec.py +++ b/tools/precoder/stream_fec.py @@ -1,77 +1,98 @@ -"""RaptorQ (RFC 6330) fountain-code FEC layer for the stream link. - -Sits between the TUN device and `stream.py`'s framing. The channel underneath -is a packet-erasure channel (whole frames either arrive clean or are dropped -by the stream layer's CRC check), so a real erasure code can recover from a -loss rate the blind `--repeat N` knob in `tun_p2p.py` can't match without -infinite N. RaptorQ was designed for exactly this regime (broadcast, no ACK, -variable loss) — see the corruption survey in PR #85 for the empirical -30-70% loss numbers that motivated this. - -Wire format. The OUTER stream framing in `stream.py` is unchanged; FEC lives -INSIDE `StreamFrame.payload` as a fixed 9-byte inner envelope followed by -the serialised raptorq packet (lib-managed SBN + ESI + symbol): - - FEC_MAGIC (2) = 0xF52E little-endian - VERSION/FLAGS (1) = 0 (reserved) - K (1) = source symbols per block (encoder config) - KREAL (1) = real source symbols in THIS block (1..K). For - flush-padded last blocks KREAL < K and the trailing - (K - KREAL) decoded source symbols are zero pads. - SYMBOL_SIZE (2) = LE u16, must match TX config - BLOCK_ID (2) = LE u16 wraps; identifies which K-symbol block - RAPTORQ_PKT (var) = lib's serialised packet (≈ 4 byte SBN+ESI plus - the symbol bytes; size depends on lib internals) - -Source symbols (the K bytes-segments the codec encodes) are themselves -concatenations of length-prefixed IP packets: - - [u16 len_a LE][packet_a]…[u16 len_b LE][packet_b]…[zero pad to SYMBOL_SIZE] - -A `len = 0` sentinel or remaining bytes < 2 marks "no more packets in this -symbol". This packs small packets densely (ACK floods don't burn one symbol -each) and keeps a packet whose size is close to symbol_size in exactly one -symbol. Tun MTU must be at most `SYMBOL_SIZE - 2`. - -Block-decoding model — cberner's `raptorq` lib (RFC 6330 reference port) -exposes block-incremental decoding: feed packets one at a time, the lib -returns the K source symbols (concatenated) when enough have arrived. We -keep one `raptorq.Decoder` per in-flight block id; entries are dropped -either after successful decode or after `expire_blocks_older_than` (the -tun_p2p bridge calls this periodically with a configurable max age). +"""Stream-link FEC dispatcher. + +Two FEC schemes coexist here, sharing the same outer `StreamFrame.payload` +inner-envelope-then-symbol pattern but picking different MAGICs so a +receive dispatcher can route per-frame: + + 0xF52E → RaptorQ (RFC 6330; cberner's PyO3 binding). + Block code: K source symbols are buffered, then K + R encoded + symbols are emitted; receiver decodes after ≈ K + ε arrive. + Best for bulk throughput; per-packet latency floor is high. + Implementation lives in `stream_fec_raptorq.py`. + + 0xF534 → Sliding-window RLC (RFC 8681; wraps Inria's swif-codec). + Source symbols are emitted systematically (zero encoder + buffer), repair symbols are linear combinations over the + last `window` source symbols. Best for low-latency + interactive traffic. Implementation lives in + `stream_fec_rlc.py`. + +The public interface is identical for both schemes — the encoder exposes +`add_packet(pkt) -> list[bytes]`, `flush() -> list[bytes]`, +`pending_packets`, `blocks_encoded`, `symbols_out`, … and the decoder +exposes `add_symbol(env) -> list[bytes]`, `expire_blocks_older_than(s)`, +`blocks_decoded`, `blocks_unrecoverable`, … . `tun_p2p.py` reads them +without caring which scheme is underneath. + +`FecConfig.scheme` selects between the two; the default is "raptorq" so +existing tests and callers that construct `FecConfig(k=…)` without a +scheme argument keep the historical behaviour. `tun_p2p.py`'s +`--fec-scheme` flag overrides this with "rlc" as the user-facing default. + +Source-symbol packing — packets carried in a source symbol are +length-prefixed (u16 LE) and concatenated; a `len = 0` sentinel or +remaining bytes < 2 marks "no more packets in this symbol". This packs +small packets densely (ACK floods don't burn one symbol each) and keeps +a packet whose size is close to symbol_size in exactly one symbol. Both +schemes use the SAME packing; only the codec under the symbol differs. """ from __future__ import annotations import math -import struct -import time from dataclasses import dataclass from typing import Optional -import raptorq - -FEC_MAGIC = 0xF52E -FEC_HEADER_LEN = 9 -FEC_HEADER_STRUCT = " None: + if self.scheme not in ("raptorq", "rlc"): + raise ValueError( + f"scheme must be 'raptorq' or 'rlc' (got {self.scheme!r})") if self.k <= 0 or self.k > 255: raise ValueError(f"k must be in 1..255 (got {self.k})") if self.symbol_size <= PACKET_LEN_PREFIX: @@ -80,10 +101,16 @@ def __post_init__(self) -> None: ) if self.overhead < 0: raise ValueError(f"overhead must be >= 0 (got {self.overhead})") + if self.window <= 0 or self.window > 255: + raise ValueError(f"window must be in 1..255 (got {self.window})") + if not (0 <= self.density_threshold <= 15): + raise ValueError( + f"density_threshold must be in 0..15 (got {self.density_threshold})" + ) @property def repair_count(self) -> int: - """Number of repair packets per block (= ceil(k * overhead)).""" + """Number of repair packets per RaptorQ block (= ceil(k * overhead)).""" return math.ceil(self.k * self.overhead) @property @@ -92,259 +119,42 @@ def max_packet_size(self) -> int: return self.symbol_size - PACKET_LEN_PREFIX -def _pack_header(cfg: FecConfig, kreal: int, block_id: int) -> bytes: - return struct.pack( - FEC_HEADER_STRUCT, - FEC_MAGIC, 0, cfg.k, kreal, cfg.symbol_size, block_id & 0xFFFF, - ) - - -def _unpack_header(env: bytes) -> Optional[tuple[int, int, int, int, int]]: - """Return (version, k, kreal, symbol_size, block_id) or None on bad magic.""" - if len(env) < FEC_HEADER_LEN: - return None - magic, ver, k, kreal, ss, bid = struct.unpack_from(FEC_HEADER_STRUCT, env) - if magic != FEC_MAGIC: - return None - return ver, k, kreal, ss, bid - - # --------------------------------------------------------------------------- # -# Encoder +# Factory functions — pick the right per-scheme implementation # --------------------------------------------------------------------------- # -class FecEncoder: - """Concatenation-packs IP packets, then RaptorQ-encodes K source symbols - into K + repair_count output symbols. Each output symbol is wrapped in - the inner envelope and returned as bytes ready to drop into a - `StreamFrame.payload`. - """ - - def __init__(self, cfg: FecConfig) -> None: - self.cfg = cfg - self._pending_symbols: list[bytes] = [] - self._current_symbol = bytearray() - self._block_id = 0 - # Stats — read by tun_p2p for periodic counter prints. - self.blocks_encoded = 0 - self.packets_in = 0 - self.symbols_out = 0 - self.bytes_in = 0 - - def add_packet(self, pkt: bytes) -> list[bytes]: - """Append `pkt` to the current packing symbol. If the symbol fills, it - is moved to the pending list; if pending reaches K, a block is - encoded and the K + repair_count envelopes are returned. Otherwise - returns []. - - Raises ValueError if `pkt` is too large to fit in even an empty - symbol — the caller (tun_p2p) is responsible for capping TUN MTU at - `cfg.max_packet_size`. - """ - n = len(pkt) - if n > self.cfg.max_packet_size: - raise ValueError( - f"packet {n}B exceeds max_packet_size {self.cfg.max_packet_size}B " - f"(symbol_size {self.cfg.symbol_size} - {PACKET_LEN_PREFIX} prefix)" - ) - self.packets_in += 1 - self.bytes_in += n - needed = PACKET_LEN_PREFIX + n - # If this packet doesn't fit alongside what's already in the current - # symbol, seal that symbol off first. - if needed > self.cfg.symbol_size - len(self._current_symbol): - self._seal_current_symbol() - ready = self._maybe_encode_full_block() - if ready: - # Stash the new packet for the next block, then return the - # encoded one. (We append below.) - self._append_to_current(pkt) - return ready - self._append_to_current(pkt) - return [] - - def _append_to_current(self, pkt: bytes) -> None: - self._current_symbol += struct.pack(" None: - if not self._current_symbol: - return - pad = self.cfg.symbol_size - len(self._current_symbol) - if pad: - self._current_symbol += b"\x00" * pad - self._pending_symbols.append(bytes(self._current_symbol)) - self._current_symbol = bytearray() - - def _maybe_encode_full_block(self) -> list[bytes]: - if len(self._pending_symbols) >= self.cfg.k: - return self._encode_block(kreal=self.cfg.k) - return [] - - def flush(self) -> list[bytes]: - """Force-encode whatever's pending. The current packing symbol is - sealed (zero-padded), then pending is zero-padded to K, then the - block is encoded with KREAL set to the count of real (non-padded) - source symbols. Decoder uses KREAL to discard the trailing zero - symbols when unpacking IP packets. - - Returns [] if there's literally nothing pending. - """ - self._seal_current_symbol() - if not self._pending_symbols: - return [] - kreal = len(self._pending_symbols) - while len(self._pending_symbols) < self.cfg.k: - self._pending_symbols.append(b"\x00" * self.cfg.symbol_size) - return self._encode_block(kreal=kreal) - - def _encode_block(self, kreal: int) -> list[bytes]: - data = b"".join(self._pending_symbols) - self._pending_symbols.clear() - encoder = raptorq.Encoder.with_defaults(data, self.cfg.symbol_size) - packets = encoder.get_encoded_packets(self.cfg.repair_count) - bid = self._block_id - self._block_id = (self._block_id + 1) & 0xFFFF - self.blocks_encoded += 1 - self.symbols_out += len(packets) - header = _pack_header(self.cfg, kreal, bid) - return [header + p for p in packets] - - @property - def pending_packets(self) -> int: - """Whether there is in-flight data that hasn't been flushed. Used by - the tun_p2p flush timer thread to decide whether to call flush().""" - if self._current_symbol: - return 1 - return len(self._pending_symbols) +def make_encoder(cfg: FecConfig): + """Return a scheme-appropriate encoder. The returned object exposes the + duck-typed interface tun_p2p.py expects (add_packet, flush, + pending_packets, counters).""" + if cfg.scheme == "raptorq": + from stream_fec_raptorq import RaptorQEncoder + return RaptorQEncoder(cfg) + if cfg.scheme == "rlc": + from stream_fec_rlc import RlcEncoder + return RlcEncoder(cfg) + raise ValueError(f"unknown FEC scheme {cfg.scheme!r}") + + +def make_decoder(cfg: FecConfig): + """Return a scheme-appropriate decoder. The returned object exposes + add_symbol, expire_blocks_older_than, and the per-scheme counters.""" + if cfg.scheme == "raptorq": + from stream_fec_raptorq import RaptorQDecoder + return RaptorQDecoder(cfg) + if cfg.scheme == "rlc": + from stream_fec_rlc import RlcDecoder + return RlcDecoder(cfg) + raise ValueError(f"unknown FEC scheme {cfg.scheme!r}") # --------------------------------------------------------------------------- # -# Decoder +# Backward-compat aliases — pre-RLC code does +# import stream_fec; enc = stream_fec.FecEncoder(cfg); dec = stream_fec.FecDecoder(cfg) +# Keep those callable by routing them through the factory. # --------------------------------------------------------------------------- # -@dataclass -class _BlockState: - decoder: "raptorq.Decoder" - kreal: int - first_seen: float - decoded: bool = False - - -class FecDecoder: - """Buffers incoming inner-envelope symbols by block-id, runs RaptorQ's - block-incremental decoder, unpacks length-prefixed IP packets out of - the first KREAL source symbols when a block decodes. - """ - - def __init__(self, cfg: FecConfig) -> None: - self.cfg = cfg - self._blocks: dict[int, _BlockState] = {} - # Stats. - self.blocks_decoded = 0 - self.blocks_unrecoverable = 0 - self.symbols_in = 0 - self.symbols_dropped_bad_cfg = 0 - self.symbols_dropped_stale_block = 0 - self.packets_out = 0 - self.bytes_out = 0 - - def add_symbol(self, envelope: bytes) -> list[bytes]: - """Feed one inner-envelope blob; returns recovered IP packets when a - block decodes (possibly empty).""" - header = _unpack_header(envelope) - if header is None: - return [] - version, k, kreal, symbol_size, block_id = header - if version != 0: - return [] - if k != self.cfg.k or symbol_size != self.cfg.symbol_size: - self.symbols_dropped_bad_cfg += 1 - return [] - if not (1 <= kreal <= k): - self.symbols_dropped_bad_cfg += 1 - return [] - packet = envelope[FEC_HEADER_LEN:] - self.symbols_in += 1 +def FecEncoder(cfg: FecConfig): # noqa: N802 — preserving the historical name + return make_encoder(cfg) - state = self._blocks.get(block_id) - if state is None: - state = _BlockState( - decoder=raptorq.Decoder.with_defaults( - k * symbol_size, symbol_size), - kreal=kreal, - first_seen=time.monotonic(), - ) - self._blocks[block_id] = state - elif state.decoded: - # Late symbol for an already-decoded block; the entry will be - # GC'd by expire_blocks_older_than. We don't re-decode. - self.symbols_dropped_stale_block += 1 - return [] - - # Decoder.decode returns the concatenated source bytes when enough - # symbols have arrived for the block; None otherwise. - try: - result = state.decoder.decode(packet) - except Exception: - # Malformed packet bytes; raptorq raises on bad SBN/ESI fields. - return [] - if result is None: - return [] - # Mark this block decoded but keep the entry alive so late symbols - # (we ship K + repair_count, decoder typically needs K + ε ~< all of - # them) don't get fed into a fresh Decoder and trigger a second - # spurious decode. The `state.decoded` branch above silently drops - # those late symbols. `expire_blocks_older_than` GCs the entry. - state.decoded = True - self.blocks_decoded += 1 - ip_pkts = self._unpack(result, state.kreal) - self.packets_out += len(ip_pkts) - self.bytes_out += sum(len(p) for p in ip_pkts) - return ip_pkts - - def _unpack(self, decoded: bytes, kreal: int) -> list[bytes]: - ss = self.cfg.symbol_size - out: list[bytes] = [] - for i in range(kreal): - symbol = decoded[i * ss:(i + 1) * ss] - pos = 0 - while pos + PACKET_LEN_PREFIX <= len(symbol): - ln = int.from_bytes( - symbol[pos:pos + PACKET_LEN_PREFIX], "little") - if ln == 0: - break - end = pos + PACKET_LEN_PREFIX + ln - if end > len(symbol): - # Malformed (truncated) — stop scanning this symbol. - break - out.append(bytes(symbol[pos + PACKET_LEN_PREFIX:end])) - pos = end - return out - def expire_blocks_older_than(self, max_age_s: float) -> int: - """Drop block entries whose first symbol arrived more than `max_age_s` - ago. Both decoded and undecoded entries are GC'd; for undecoded - ones, `blocks_unrecoverable` is incremented. - - Returns the count of UNRECOVERABLE (= still undecoded) blocks - evicted — useful as a counter for the bridge's stderr report. The - return value intentionally excludes successfully-decoded blocks - even though they're also evicted. - """ - if not self._blocks: - return 0 - now = time.monotonic() - expired = [ - bid for bid, st in self._blocks.items() - if (now - st.first_seen) > max_age_s - ] - unrecoverable = 0 - for bid in expired: - if not self._blocks[bid].decoded: - unrecoverable += 1 - del self._blocks[bid] - self.blocks_unrecoverable += unrecoverable - return unrecoverable - - @property - def in_flight_blocks(self) -> int: - return len(self._blocks) +def FecDecoder(cfg: FecConfig): # noqa: N802 + return make_decoder(cfg) diff --git a/tools/precoder/stream_fec_raptorq.py b/tools/precoder/stream_fec_raptorq.py new file mode 100644 index 0000000..53d3c1e --- /dev/null +++ b/tools/precoder/stream_fec_raptorq.py @@ -0,0 +1,235 @@ +"""RaptorQ (RFC 6330) block-FEC implementation for the stream link. + +Originally the only FEC scheme (see PR #86). Lives here so `stream_fec.py` +can stay a thin dispatcher that picks between RaptorQ (this module) and +RLC (`stream_fec_rlc.py`) at runtime based on `FecConfig.scheme`. + +Wire format (inside the outer `StreamFrame.payload`): + + FEC_MAGIC (2) = 0xF52E little-endian + VERSION/FLAGS (1) = 0 (reserved) + K (1) = source symbols per block (encoder config) + KREAL (1) = real source symbols in THIS block (1..K). For + flush-padded last blocks KREAL < K and the + trailing (K - KREAL) decoded source symbols are + zero pads. + SYMBOL_SIZE (2) = LE u16, must match TX config + BLOCK_ID (2) = LE u16 wraps; identifies which K-symbol block + RAPTORQ_PKT (var) = cberner's serialised packet (≈ 4-byte SBN+ESI + plus symbol bytes). + +Source symbols are concatenation-packed IP packets — same length-prefix +scheme as `stream_fec_rlc.py`. See `stream_fec.PACKET_LEN_PREFIX`. +""" + +from __future__ import annotations + +import struct +import time +from dataclasses import dataclass +from typing import Optional + +import raptorq + +FEC_MAGIC = 0xF52E +FEC_HEADER_LEN = 9 +FEC_HEADER_STRUCT = " bytes: + return struct.pack( + FEC_HEADER_STRUCT, + FEC_MAGIC, 0, k, kreal, symbol_size, block_id & 0xFFFF, + ) + + +def _unpack_header(env: bytes) -> Optional[tuple[int, int, int, int, int]]: + if len(env) < FEC_HEADER_LEN: + return None + magic, ver, k, kreal, ss, bid = struct.unpack_from(FEC_HEADER_STRUCT, env) + if magic != FEC_MAGIC: + return None + return ver, k, kreal, ss, bid + + +class RaptorQEncoder: + """Concatenation-packs IP packets, then RaptorQ-encodes K source symbols + into K + repair_count output symbols.""" + + def __init__(self, cfg) -> None: + self.cfg = cfg + self._pending_symbols: list[bytes] = [] + self._current_symbol = bytearray() + self._block_id = 0 + # Stats read by tun_p2p. + self.blocks_encoded = 0 + self.packets_in = 0 + self.symbols_out = 0 + self.bytes_in = 0 + + def add_packet(self, pkt: bytes) -> list[bytes]: + n = len(pkt) + if n > self.cfg.max_packet_size: + raise ValueError( + f"packet {n}B exceeds max_packet_size {self.cfg.max_packet_size}B " + f"(symbol_size {self.cfg.symbol_size} - {PACKET_LEN_PREFIX} prefix)" + ) + self.packets_in += 1 + self.bytes_in += n + needed = PACKET_LEN_PREFIX + n + if needed > self.cfg.symbol_size - len(self._current_symbol): + self._seal_current_symbol() + ready = self._maybe_encode_full_block() + if ready: + self._append_to_current(pkt) + return ready + self._append_to_current(pkt) + return [] + + def _append_to_current(self, pkt: bytes) -> None: + self._current_symbol += struct.pack(" None: + if not self._current_symbol: + return + pad = self.cfg.symbol_size - len(self._current_symbol) + if pad: + self._current_symbol += b"\x00" * pad + self._pending_symbols.append(bytes(self._current_symbol)) + self._current_symbol = bytearray() + + def _maybe_encode_full_block(self) -> list[bytes]: + if len(self._pending_symbols) >= self.cfg.k: + return self._encode_block(kreal=self.cfg.k) + return [] + + def flush(self) -> list[bytes]: + self._seal_current_symbol() + if not self._pending_symbols: + return [] + kreal = len(self._pending_symbols) + while len(self._pending_symbols) < self.cfg.k: + self._pending_symbols.append(b"\x00" * self.cfg.symbol_size) + return self._encode_block(kreal=kreal) + + def _encode_block(self, kreal: int) -> list[bytes]: + data = b"".join(self._pending_symbols) + self._pending_symbols.clear() + encoder = raptorq.Encoder.with_defaults(data, self.cfg.symbol_size) + packets = encoder.get_encoded_packets(self.cfg.repair_count) + bid = self._block_id + self._block_id = (self._block_id + 1) & 0xFFFF + self.blocks_encoded += 1 + self.symbols_out += len(packets) + header = _pack_header(self.cfg.k, kreal, self.cfg.symbol_size, bid) + return [header + p for p in packets] + + @property + def pending_packets(self) -> int: + if self._current_symbol: + return 1 + return len(self._pending_symbols) + + +@dataclass +class _BlockState: + decoder: "raptorq.Decoder" + kreal: int + first_seen: float + decoded: bool = False + + +class RaptorQDecoder: + def __init__(self, cfg) -> None: + self.cfg = cfg + self._blocks: dict[int, _BlockState] = {} + self.blocks_decoded = 0 + self.blocks_unrecoverable = 0 + self.symbols_in = 0 + self.symbols_dropped_bad_cfg = 0 + self.symbols_dropped_stale_block = 0 + self.packets_out = 0 + self.bytes_out = 0 + + def add_symbol(self, envelope: bytes) -> list[bytes]: + header = _unpack_header(envelope) + if header is None: + return [] + version, k, kreal, symbol_size, block_id = header + if version != 0: + return [] + if k != self.cfg.k or symbol_size != self.cfg.symbol_size: + self.symbols_dropped_bad_cfg += 1 + return [] + if not (1 <= kreal <= k): + self.symbols_dropped_bad_cfg += 1 + return [] + packet = envelope[FEC_HEADER_LEN:] + self.symbols_in += 1 + + state = self._blocks.get(block_id) + if state is None: + state = _BlockState( + decoder=raptorq.Decoder.with_defaults( + k * symbol_size, symbol_size), + kreal=kreal, + first_seen=time.monotonic(), + ) + self._blocks[block_id] = state + elif state.decoded: + self.symbols_dropped_stale_block += 1 + return [] + + try: + result = state.decoder.decode(packet) + except Exception: + return [] + if result is None: + return [] + state.decoded = True + self.blocks_decoded += 1 + ip_pkts = self._unpack(result, state.kreal) + self.packets_out += len(ip_pkts) + self.bytes_out += sum(len(p) for p in ip_pkts) + return ip_pkts + + def _unpack(self, decoded: bytes, kreal: int) -> list[bytes]: + ss = self.cfg.symbol_size + out: list[bytes] = [] + for i in range(kreal): + symbol = decoded[i * ss:(i + 1) * ss] + pos = 0 + while pos + PACKET_LEN_PREFIX <= len(symbol): + ln = int.from_bytes( + symbol[pos:pos + PACKET_LEN_PREFIX], "little") + if ln == 0: + break + end = pos + PACKET_LEN_PREFIX + ln + if end > len(symbol): + break + out.append(bytes(symbol[pos + PACKET_LEN_PREFIX:end])) + pos = end + return out + + def expire_blocks_older_than(self, max_age_s: float) -> int: + if not self._blocks: + return 0 + now = time.monotonic() + expired = [ + bid for bid, st in self._blocks.items() + if (now - st.first_seen) > max_age_s + ] + unrecoverable = 0 + for bid in expired: + if not self._blocks[bid].decoded: + unrecoverable += 1 + del self._blocks[bid] + self.blocks_unrecoverable += unrecoverable + return unrecoverable + + @property + def in_flight_blocks(self) -> int: + return len(self._blocks) diff --git a/tools/precoder/stream_fec_rlc.py b/tools/precoder/stream_fec_rlc.py new file mode 100644 index 0000000..b5d592d --- /dev/null +++ b/tools/precoder/stream_fec_rlc.py @@ -0,0 +1,473 @@ +"""Sliding-Window RLC (RFC 8681) FEC for the stream link. + +Wraps Inria's `swif-codec` C library (vendored at +`vendor/swif-codec/`; Python binding via cffi at `_swif_build.py`). + +Why this scheme + +The companion RaptorQ implementation (`stream_fec_raptorq.py`) is a +block code: K source IP packets accumulate, the encoder emits K + R +encoded symbols, the decoder waits for K + ε before any source is +delivered. The unavoidable consequence is a per-packet latency floor +of K × per-pkt-airtime + flush_ms. PR #86's bench measured 95 ms even +at K=8 / flush=20 ms. + +RFC 8681 RLC is a sliding-window code: every source symbol is shipped +**systematically** (zero encoder buffer), repair symbols are linear +combinations over the last `window` source symbols, and the decoder +can emit each source the instant it arrives unmodified. Better suited +for interactive traffic (ping / voice / video). + +Wire format (inside the outer `StreamFrame.payload`): + + RLC_MAGIC (2) = 0xF534 LE + VERSION (1) = 0 + SYMBOL_TYPE (1) = 0 source, 1 repair + SYMBOL_SIZE (2) = LE u16 + ESI (4) = LE u32; source: own ESI; repair: ESI of the + first source symbol covered by this repair + WINDOW_SIZE (1) = number of source symbols covered by this repair + (1 for source symbols) + REPAIR_KEY (2) = LE u16 TinyMT32 seed (RFC 8682) for the + coefficient PRNG; 0 for source symbols + DT (1) = density threshold 0..15; 0 for source symbols + PAYLOAD (var) = `symbol_size` bytes — source data or linear + combination + +Inner overhead = 14 bytes. Source-symbol payload uses the SAME +length-prefix-concat packing as RaptorQ — see `stream_fec.PACKET_LEN_PREFIX`. + +Encoder model + +* Source symbol = filled-and-sealed packing buffer of length `symbol_size`. +* Encoder maintains a `window`-deep ring of source-symbol buffers (cffi + keeps the C-side window in lockstep). +* Each `add_packet(pkt)` may seal one or more source symbols. For each + newly-sealed source symbol, the encoder emits its source envelope + AND `repair_per_source = max(1, round(overhead))` repair envelopes + over the current encoding window. + +Decoder model + +* Source envelopes (SYMBOL_TYPE=0) are fed straight to the codec's + `decode_with_new_source_symbol` AND emit immediately to the IP layer + (systematic delivery). +* Repair envelopes (SYMBOL_TYPE=1) bring the coding window into sync + (`reset_coding_window`, `add_source_symbol_to_coding_window` for each + ESI in the repair's window, `generate_coding_coefs` with the shipped + `repair_key` and `dt`) and then `decode_with_new_repair_symbol`. + Any source symbols the codec recovers are surfaced via callback and + emitted to the IP layer. +* IP-packet order is preserved by emitting source-symbol bytes in ESI + order: late recovery via repair feeds the same "in-ESI-order emit" + queue, so the decoder gives the IP stack packets in the same order + the encoder shipped them. +""" + +from __future__ import annotations + +import os +import random +import struct +import subprocess +import sys +import time +from typing import Optional + +# ---------------------------------------------------------------------- # +# cffi extension auto-build on first import +# ---------------------------------------------------------------------- # +def _ensure_swif_ext(): + try: + from _swif_ext import ffi, lib # noqa: F401 + return + except ImportError: + pass + here = os.path.dirname(os.path.abspath(__file__)) + build_script = os.path.join(here, "_swif_build.py") + if not os.path.isfile(build_script): + raise ImportError( + "stream_fec_rlc: vendored swif-codec extension not built and " + f"build script {build_script} is missing" + ) + sys.stderr.write( + "stream_fec_rlc: _swif_ext not found; building cffi extension…\n" + ) + subprocess.check_call([sys.executable, build_script]) + + +_ensure_swif_ext() + +from _swif_ext import ffi, lib # noqa: E402 + +# Header constants — match the wire format laid out in the module docstring. +RLC_MAGIC = 0xF534 +RLC_HEADER_LEN = 14 +RLC_HEADER_STRUCT = " bytes: + return struct.pack( + RLC_HEADER_STRUCT, RLC_MAGIC, 0, symbol_type, symbol_size, + esi & 0xFFFFFFFF, window_size, repair_key & 0xFFFF, dt, + ) + + +def _unpack_header(env: bytes + ) -> Optional[tuple[int, int, int, int, int, int]]: + """Return (symbol_type, symbol_size, esi, window_size, repair_key, dt) + or None on bad magic / short envelope.""" + if len(env) < RLC_HEADER_LEN: + return None + magic, ver, stype, ss, esi, win, key, dt = struct.unpack_from( + RLC_HEADER_STRUCT, env) + if magic != RLC_MAGIC or ver != 0: + return None + return stype, ss, esi, win, key, dt + + +# ---------------------------------------------------------------------- # +# Encoder +# ---------------------------------------------------------------------- # +class RlcEncoder: + def __init__(self, cfg) -> None: + self.cfg = cfg + self._enc = lib.swif_rlc_encoder_create( + lib.SWIF_CODEPOINT_RLC_GF_256_FULL_DENSITY_CODEC, + 0, # verbosity + cfg.symbol_size, + cfg.window, + ) + if self._enc == ffi.NULL: + raise RuntimeError("swif_rlc_encoder_create returned NULL") + # We must keep Python references to every source buffer alive for as + # long as it sits in the C-side window — the codec stores the buffer + # pointer, not a copy. Map ESI → cffi buffer object so GC doesn't pull + # the rug out from under it. + self._kept_src: dict[int, "ffi.CData"] = {} + self._current_symbol = bytearray() + self._next_esi = 0 # ESI of the next source symbol to seal + self._window_first = 0 # ESI of the leftmost symbol in window + self._rng = random.Random(0xC0FFEE) # for repair_key + self.repair_per_source = max(1, round(cfg.overhead)) + + # Stats (mirror RaptorQ's surface — tun_p2p reads these). + self.blocks_encoded = 0 # for RLC we count "sealed source symbols" + self.packets_in = 0 + self.symbols_out = 0 + self.bytes_in = 0 + + def __del__(self) -> None: + try: + if hasattr(self, "_enc") and self._enc != ffi.NULL: + lib.swif_rlc_encoder_release(self._enc) + except Exception: + pass + + def add_packet(self, pkt: bytes) -> list[bytes]: + n = len(pkt) + if n > self.cfg.max_packet_size: + raise ValueError( + f"packet {n}B exceeds max_packet_size {self.cfg.max_packet_size}B " + f"(symbol_size {self.cfg.symbol_size} - {PACKET_LEN_PREFIX} prefix)" + ) + self.packets_in += 1 + self.bytes_in += n + envelopes: list[bytes] = [] + needed = PACKET_LEN_PREFIX + n + if needed > self.cfg.symbol_size - len(self._current_symbol): + envelopes += self._seal_current_symbol_and_emit() + self._current_symbol += struct.pack(" list[bytes]: + return self._seal_current_symbol_and_emit() if self._current_symbol else [] + + def _seal_current_symbol_and_emit(self) -> list[bytes]: + """Seal the current packing buffer as a source symbol, register it + with the codec, emit the source envelope + N repair envelopes.""" + if not self._current_symbol: + return [] + pad = self.cfg.symbol_size - len(self._current_symbol) + if pad > 0: + self._current_symbol += b"\x00" * pad + source_bytes = bytes(self._current_symbol) + self._current_symbol = bytearray() + + esi = self._next_esi & 0xFFFFFFFF + self._next_esi += 1 + + # Hand the codec a stable C-side buffer; keep Python ref alive. + cbuf = ffi.new(f"uint8_t[{self.cfg.symbol_size}]", source_bytes) + rc = lib.swif_rlc_encoder_add_source_symbol_to_coding_window( + self._enc, cbuf, esi) + if rc != lib.SWIF_STATUS_OK: + raise RuntimeError( + f"swif encoder add_source_symbol failed (esi={esi}, rc={rc})") + self._kept_src[esi] = cbuf + + # Auto-evict left edge of window if we just pushed past `window`. + if esi - self._window_first + 1 > self.cfg.window: + evict = esi - self.cfg.window + 1 + for old in range(self._window_first, evict): + # The C-side codec evicts implicitly when we add past window; + # we just drop our Python-side reference. + self._kept_src.pop(old, None) + self._window_first = evict + + # Emit the source envelope. + out = [_pack_header(SYMBOL_TYPE_SOURCE, self.cfg.symbol_size, esi, + 1, 0, 0) + source_bytes] + self.symbols_out += 1 + self.blocks_encoded += 1 + + # Emit `repair_per_source` repair envelopes over the current window. + win_first = self._window_first + win_size = esi - win_first + 1 + for _ in range(self.repair_per_source): + key = self._rng.randrange(1, 0x10000) + rc = lib.swif_encoder_generate_coding_coefs( + self._enc, key, self.cfg.density_threshold) + if rc != lib.SWIF_STATUS_OK: + raise RuntimeError( + f"swif generate_coding_coefs failed (rc={rc})") + # Pre-allocate the repair buffer ourselves so the codec doesn't + # malloc (otherwise we'd need to track-and-free); the codec + # writes into our buffer when **new_buf is non-NULL. + repair_buf = ffi.new(f"uint8_t[{self.cfg.symbol_size}]") + rp = ffi.new("void**", repair_buf) + rc = lib.swif_rlc_build_repair_symbol(self._enc, rp) + if rc != lib.SWIF_STATUS_OK: + raise RuntimeError(f"swif build_repair_symbol failed (rc={rc})") + repair_bytes = bytes(ffi.buffer(repair_buf, self.cfg.symbol_size)[:]) + out.append( + _pack_header(SYMBOL_TYPE_REPAIR, self.cfg.symbol_size, + win_first, win_size, key, + self.cfg.density_threshold) + + repair_bytes) + self.symbols_out += 1 + + return out + + @property + def pending_packets(self) -> int: + return 1 if self._current_symbol else 0 + + +# ---------------------------------------------------------------------- # +# Decoder +# ---------------------------------------------------------------------- # +class RlcDecoder: + def __init__(self, cfg) -> None: + self.cfg = cfg + self._dec = lib.swif_rlc_decoder_create( + lib.SWIF_CODEPOINT_RLC_GF_256_FULL_DENSITY_CODEC, + 0, + cfg.symbol_size, + cfg.window, + cfg.window, # max_linear_system_size — match window + ) + if self._dec == ffi.NULL: + raise RuntimeError("swif_rlc_decoder_create returned NULL") + + # Stats. + self.blocks_decoded = 0 # for RLC: source symbols delivered + self.blocks_unrecoverable = 0 + self.symbols_in = 0 + self.symbols_dropped_bad_cfg = 0 + self.symbols_dropped_stale_block = 0 + self.packets_out = 0 + self.bytes_out = 0 + + # Source symbols arrive in two ways: + # 1. Direct (SYMBOL_TYPE_SOURCE) — emit immediately to TUN. + # 2. Recovered from repair via codec callback — buffered until the + # "emit in ESI order" gate releases them. + # We track first_emitted_esi as a wall against re-emission, and a + # buffer for out-of-order recovered symbols. + self._next_emit_esi = 0 + self._pending_recovered: dict[int, bytes] = {} + self._kept_bufs: list = [] # cffi buffer GC anchor + + # The codec calls us back when it recovers source symbols. cffi + # callbacks must be kept alive (otherwise the trampoline goes away). + self._cb_removed = ffi.callback( + "void(void*, esi_t)", self._on_symbol_removed) + self._cb_decodable = ffi.callback( + "void*(void*, esi_t)", self._on_decodable) + self._cb_decoded = ffi.callback( + "void*(void*, void*, esi_t)", self._on_decoded) + lib.swif_rlc_decoder_set_callback_functions( + self._dec, self._cb_removed, self._cb_decodable, + self._cb_decoded, ffi.NULL) + + # Track when each block-id-equivalent (we use ESI of first symbol in + # the latest repair window) first arrived, for expiry bookkeeping. + self._block_first_seen: dict[int, float] = {} + + # For draining recovered packets out to the caller, we accumulate + # IP packets in `_emit_queue` and the public `add_symbol` returns + # whatever's in there per-call. + self._emit_queue: list[bytes] = [] + + def __del__(self) -> None: + try: + if hasattr(self, "_dec") and self._dec != ffi.NULL: + lib.swif_rlc_decoder_release(self._dec) + except Exception: + pass + + def _on_symbol_removed(self, ctx, esi): + # Just a hook for the codec; nothing to do here. + pass + + def _on_decodable(self, ctx, esi): + # Allocate a stable buffer the codec will fill in. We keep a Python + # reference so GC doesn't free it while the codec is writing. + buf = ffi.new(f"uint8_t[{self.cfg.symbol_size}]") + self._kept_bufs.append(buf) + return buf + + def _on_decoded(self, ctx, buf, esi): + # The decoder has just finished writing this source symbol's bytes + # into the buffer we handed it in `_on_decodable`. Capture as a + # bytes object (so we don't depend on the buffer staying alive) + # and stash for in-order emission. + symbol_bytes = bytes(ffi.buffer(buf, self.cfg.symbol_size)[:]) + self._pending_recovered[int(esi)] = symbol_bytes + return ffi.NULL + + def _drain_in_order(self) -> None: + """Move recovered (or directly-arrived) source-symbol bytes into the + emit queue as long as the next-expected ESI is available.""" + while self._next_emit_esi in self._pending_recovered: + sym = self._pending_recovered.pop(self._next_emit_esi) + self._emit_packets_from_symbol(sym) + self._next_emit_esi += 1 + + def _emit_packets_from_symbol(self, symbol_bytes: bytes) -> None: + ss = self.cfg.symbol_size + pos = 0 + while pos + PACKET_LEN_PREFIX <= ss: + ln = int.from_bytes( + symbol_bytes[pos:pos + PACKET_LEN_PREFIX], "little") + if ln == 0: + break + end = pos + PACKET_LEN_PREFIX + ln + if end > ss: + break + pkt = bytes(symbol_bytes[pos + PACKET_LEN_PREFIX:end]) + self._emit_queue.append(pkt) + self.packets_out += 1 + self.bytes_out += len(pkt) + pos = end + self.blocks_decoded += 1 + + def add_symbol(self, envelope: bytes) -> list[bytes]: + header = _unpack_header(envelope) + if header is None: + return [] + stype, ss, esi, win, key, dt = header + if ss != self.cfg.symbol_size: + self.symbols_dropped_bad_cfg += 1 + return [] + if win < 1 or win > self.cfg.window: + self.symbols_dropped_bad_cfg += 1 + return [] + payload = envelope[RLC_HEADER_LEN:] + if len(payload) != ss: + self.symbols_dropped_bad_cfg += 1 + return [] + self.symbols_in += 1 + # Block bookkeeping (for expiry): key the timer on the leftmost ESI + # of the symbol's window — repair groups share this, source symbols + # are their own block. + bid = esi if stype == SYMBOL_TYPE_SOURCE else esi + self._block_first_seen.setdefault(bid, time.monotonic()) + + if stype == SYMBOL_TYPE_SOURCE: + # Feed the codec a stable buffer (it stores the pointer). + buf = ffi.new(f"uint8_t[{ss}]", payload) + self._kept_bufs.append(buf) + rc = lib.swif_rlc_decoder_decode_with_new_source_symbol( + self._dec, buf, esi) + if rc != lib.SWIF_STATUS_OK: + self.symbols_dropped_bad_cfg += 1 + return [] + # Buffer the directly-received source bytes for in-order emit. + self._pending_recovered.setdefault(int(esi), payload) + # Advance the emit gate to the lowest known ESI if we're still at 0. + if self._next_emit_esi == 0 and self._pending_recovered: + self._next_emit_esi = min(self._pending_recovered) + self._drain_in_order() + else: + # Repair: rebuild the decoder's coding window for this repair's + # source range, regenerate the same coefficients (TinyMT32 with + # the shipped repair_key + dt), then decode. + lib.swif_rlc_decoder_reset_coding_window(self._dec) + for e in range(esi, esi + win): + lib.swif_rlc_decoder_add_source_symbol_to_coding_window( + self._dec, e & 0xFFFFFFFF) + lib.swif_decoder_generate_coding_coefs(self._dec, key, dt) + buf = ffi.new(f"uint8_t[{ss}]", payload) + self._kept_bufs.append(buf) + rc = lib.swif_rlc_decoder_decode_with_new_repair_symbol( + self._dec, buf, esi) + if rc != lib.SWIF_STATUS_OK: + return [] + # Codec callbacks have populated _pending_recovered for any newly + # decoded source symbols. Drain in ESI order. + self._drain_in_order() + + out = self._emit_queue + self._emit_queue = [] + return out + + def expire_blocks_older_than(self, max_age_s: float) -> int: + if not self._block_first_seen: + return 0 + now = time.monotonic() + expired = [bid for bid, t in self._block_first_seen.items() + if (now - t) > max_age_s] + unrecoverable = 0 + for bid in expired: + # An expired block is "unrecoverable" if it was a source + # symbol that never made it past _next_emit_esi (we dropped + # waiting for an earlier one) OR was a repair group whose + # source coverage was incomplete. Approximate: count the + # bids that are still below our emit gate AND aren't in the + # recovered queue. + if bid < self._next_emit_esi and bid not in self._pending_recovered: + pass # already delivered + else: + unrecoverable += 1 + del self._block_first_seen[bid] + self.blocks_unrecoverable += unrecoverable + # Also age out _pending_recovered entries below the new emit gate + # by advancing the gate past stale unfilled entries. + if expired and self._pending_recovered: + min_age = max(expired) + 1 + if self._next_emit_esi < min_age: + # Skip the gap; subsequent recoveries past this point are + # treated as fresh. + self._next_emit_esi = max(self._next_emit_esi, min_age) + self._drain_in_order() + return unrecoverable + + @property + def in_flight_blocks(self) -> int: + return len(self._block_first_seen) diff --git a/tools/precoder/test_stream_fec.py b/tools/precoder/test_stream_fec.py index a610e7e..c290ee1 100644 --- a/tools/precoder/test_stream_fec.py +++ b/tools/precoder/test_stream_fec.py @@ -300,8 +300,10 @@ def test_decoder_drops_symbol_with_wrong_config(): cfg = FecConfig(k=8, symbol_size=200) dec = FecDecoder(cfg) # Hand-craft an envelope with a different k. - bad_header = stream_fec._pack_header( - FecConfig(k=16, symbol_size=200), kreal=16, block_id=0) + # _pack_header now lives in stream_fec_raptorq (scheme-specific header). + import stream_fec_raptorq + bad_header = stream_fec_raptorq._pack_header( + 16, kreal=16, symbol_size=200, block_id=0) out = dec.add_symbol(bad_header + b"\x00" * 200) assert out == [] assert dec.symbols_dropped_bad_cfg == 1 diff --git a/tools/precoder/test_stream_fec_rlc.py b/tools/precoder/test_stream_fec_rlc.py new file mode 100644 index 0000000..f2a7e28 --- /dev/null +++ b/tools/precoder/test_stream_fec_rlc.py @@ -0,0 +1,183 @@ +"""Tests for the Sliding-Window RLC (RFC 8681) scheme. + +Mirrors `test_stream_fec.py`'s structure: round-trip with no loss, +moderate loss tolerance, concatenation packing, partial-symbol flush, +MAGIC dispatch, oversized packet rejection. + +The recovery characteristics differ from RaptorQ in two ways the tests +account for: + +* **Lower asymptotic loss tolerance at small W.** At window=8 + + overhead=1.0 the codec recovers cleanly through ~20% packet loss but + starts to leave packets on the floor by 30%. Higher overhead (or + larger window) buys more tolerance — `test_loss_tolerance_*` makes + that visible. +* **Per-packet emission is order-preserving.** Source symbols arrive + systematically; the decoder buffers any out-of-order recovery and + surfaces packets in ESI order. We assert this rather than the + sort()-based "set equal" pattern used for RaptorQ. +""" + +from __future__ import annotations + +import random +import struct + +import pytest + +import stream_fec +import stream_fec_rlc +from stream_fec import FecConfig, make_encoder, make_decoder + + +def _round_trip(packets, cfg, drop_pct=0.0, drop_seed=0, flush=True): + enc = make_encoder(cfg) + dec = make_decoder(cfg) + envelopes: list[bytes] = [] + for p in packets: + envelopes += enc.add_packet(p) + if flush: + envelopes += enc.flush() + rng = random.Random(drop_seed) + kept = [e for e in envelopes if rng.random() >= drop_pct] + out: list[bytes] = [] + for env in kept: + out += dec.add_symbol(env) + return out, enc, dec + + +def test_no_loss_round_trip_preserves_order(): + cfg = FecConfig(scheme="rlc", window=8, symbol_size=128, overhead=1.0) + pkts = [bytes([i + 1] * 50) for i in range(16)] + out, _, _ = _round_trip(pkts, cfg, drop_pct=0.0) + assert out == pkts # ESI-order emission, including post-recovery packets + + +def test_systematic_source_symbols_emit_immediately_pre_flush(): + """RLC's headline win: each source symbol delivers its packed packets + the moment its envelope reaches the decoder — no K-buffer.""" + cfg = FecConfig(scheme="rlc", window=8, symbol_size=128, overhead=1.0) + enc = make_encoder(cfg) + dec = make_decoder(cfg) + # Feed enough packets to fill one source symbol (so add_packet emits a + # source + a repair envelope), then check the decoder surfaces packets + # without needing a flush. + big = bytes([0xAA] * cfg.max_packet_size) + out_before_flush: list[bytes] = [] + envs = enc.add_packet(big) + for e in envs: + out_before_flush += dec.add_symbol(e) + assert out_before_flush == [big] + + +@pytest.mark.parametrize("drop_pct", [0.0, 0.1, 0.2]) +def test_recovers_within_design_loss(drop_pct): + """At overhead=1.0 the codec reliably handles up to ~20% loss for + a window-aligned stream. Higher drops are exercised by + test_high_loss_needs_higher_overhead.""" + cfg = FecConfig(scheme="rlc", window=8, symbol_size=128, overhead=1.0) + pkts = [bytes([(i + 1) & 0xFF] * 50) for i in range(16)] + out, _, _ = _round_trip(pkts, cfg, drop_pct=drop_pct, drop_seed=13) + assert set(out) >= set(pkts) + + +def test_high_loss_needs_higher_overhead(): + """Bumping `overhead` to 1.5 should recover at the 30% loss point that + fails at 1.0 — same fundamental tradeoff RaptorQ faces.""" + cfg_low = FecConfig(scheme="rlc", window=8, symbol_size=128, overhead=1.0) + cfg_high = FecConfig(scheme="rlc", window=8, symbol_size=128, overhead=1.5) + pkts = [bytes([(i + 1) & 0xFF] * 50) for i in range(16)] + out_low, _, _ = _round_trip(pkts, cfg_low, drop_pct=0.3, drop_seed=13) + out_high, _, _ = _round_trip(pkts, cfg_high, drop_pct=0.3, drop_seed=13) + # We only require that higher overhead doesn't perform worse — + # the exact percentage recovered depends on the random subset + # the seed picks. + assert len(out_high) >= len(out_low) + + +def test_concatenation_packs_small_packets_into_one_symbol(): + cfg = FecConfig(scheme="rlc", window=8, symbol_size=200, overhead=1.0) + # 6 packets of 30 B each at 200B symbol_size: each (30 + 2) = 32, so + # 6 packets fit in one symbol (192 of 200 bytes used, 8 trailing pad). + pkts = [bytes([0xA0 + i] * 30) for i in range(6)] + out, enc, _ = _round_trip(pkts, cfg, drop_pct=0.0) + assert out == pkts + # Only 1 source symbol sealed → blocks_encoded counter == 1. + assert enc.blocks_encoded == 1 + + +def test_oversized_packet_raises(): + cfg = FecConfig(scheme="rlc", window=8, symbol_size=128, overhead=1.0) + enc = make_encoder(cfg) + with pytest.raises(ValueError): + enc.add_packet(bytes(cfg.max_packet_size + 1)) + + +def test_dispatcher_routes_by_magic(): + """A RLC-encoded envelope must not be parsed by a RaptorQ decoder + (silent corruption is the worst outcome of a scheme mix).""" + cfg_rlc = FecConfig(scheme="rlc", window=8, symbol_size=128, overhead=1.0) + cfg_raptorq = FecConfig(scheme="raptorq", k=8, symbol_size=128, overhead=1.0) + enc = make_encoder(cfg_rlc) + dec_raptorq = make_decoder(cfg_raptorq) + envs = enc.add_packet(bytes([0xDE] * 50)) + envs += enc.flush() + out: list[bytes] = [] + for e in envs: + out += dec_raptorq.add_symbol(e) + assert out == [] # RaptorQ decoder rejected RLC envelopes + # And vice versa. + enc_raptorq = make_encoder(cfg_raptorq) + dec_rlc = make_decoder(cfg_rlc) + envs = enc_raptorq.add_packet(bytes([0xAD] * 50)) + envs += enc_raptorq.flush() + out = [] + for e in envs: + out += dec_rlc.add_symbol(e) + assert out == [] + + +def test_garbage_envelope_dropped(): + cfg = FecConfig(scheme="rlc", window=8, symbol_size=128, overhead=1.0) + dec = make_decoder(cfg) + assert dec.add_symbol(b"") == [] + assert dec.add_symbol(b"\x00\x00not a fec frame") == [] + + +def test_partial_packing_flushes_cleanly(): + cfg = FecConfig(scheme="rlc", window=8, symbol_size=128, overhead=1.0) + enc = make_encoder(cfg) + dec = make_decoder(cfg) + pkts = [bytes([0x11] * 30), bytes([0x22] * 50)] # both fit one symbol + envs = [] + for p in pkts: + envs += enc.add_packet(p) + envs += enc.flush() + out: list[bytes] = [] + for e in envs: + out += dec.add_symbol(e) + assert out == pkts + + +def test_envelope_header_has_distinct_magic(): + assert stream_fec_rlc.RLC_MAGIC != stream_fec.FEC_MAGIC_RAPTORQ + # And the dispatcher reads MAGIC right off the wire. + cfg = FecConfig(scheme="rlc", window=8, symbol_size=64, overhead=1.0) + enc = make_encoder(cfg) + envs = enc.add_packet(bytes([0x55] * 50)) + enc.flush() + for env in envs: + magic = struct.unpack_from(" int: ap.add_argument("--fec-block-expire-ms", type=int, default=500, help="ms before the RX side gives up on a block whose " "first symbol arrived this long ago (default 500).") + ap.add_argument("--fec-scheme", default="rlc", + choices=("rlc", "raptorq"), + help="FEC scheme: 'rlc' (default, RFC 8681 sliding " + "window, low-latency; wraps Inria swif-codec) or " + "'raptorq' (RFC 6330 block code, throughput-" + "optimised).") + ap.add_argument("--fec-window", type=int, default=32, + help="RLC encoding window in source symbols (default " + "32). RaptorQ ignores; uses --fec-k instead.") + ap.add_argument("--fec-density-threshold", type=int, default=4, + help="RLC repair density (RFC 8681 DT, 0..15; default " + "4). Higher = denser coefficient vectors → better " + "recovery, more CPU.") args = ap.parse_args(argv) do_tx = args.mode in ("duplex", "duplex-split", "tx-only") @@ -570,18 +589,30 @@ def main(argv: Optional[list[str]] = None) -> int: # tun MTU at the symbol size minus the per-packet length prefix so a # max-size packet still fits in one source symbol. fec_cfg = None - if args.fec_k > 0: + # RaptorQ default config still keys on --fec-k > 0 for backward compat; + # RLC is always-on whenever --fec-scheme is explicitly rlc (the default). + fec_on = (args.fec_k > 0) or (args.fec_scheme == "rlc") + if fec_on: _import_stream_fec() + # Per-scheme defaults: --fec-k is RaptorQ-only; in RLC mode we use + # --fec-window. We populate both fields of FecConfig regardless so + # the dataclass's invariants don't complain about k=0. + fec_k_effective = args.fec_k if args.fec_k > 0 else 16 fec_cfg = stream_fec.FecConfig( - k=args.fec_k, + scheme=args.fec_scheme, + k=fec_k_effective, + window=args.fec_window, symbol_size=args.fec_symbol_size, overhead=args.fec_overhead, + density_threshold=args.fec_density_threshold, ) - # body must hold the stream envelope (10 B) + inner FEC header - # (9 B) + the raptorq packet (≤ symbol_size B; cberner's lib caps - # packet bytes at the configured `mtu`). - min_body = (fec_cfg.symbol_size - + stream_fec.FEC_HEADER_LEN + # body must hold the stream envelope (10 B) + scheme-specific inner + # header + the codec's packet (≤ symbol_size B). + scheme_header_len = ( + stream_fec.FEC_HEADER_LEN if args.fec_scheme == "raptorq" + else 14 # stream_fec_rlc.RLC_HEADER_LEN + ) + min_body = (fec_cfg.symbol_size + scheme_header_len + stream.ENVELOPE_LEN) if args.body_bytes < min_body: sys.stderr.write( @@ -616,8 +647,8 @@ def main(argv: Optional[list[str]] = None) -> int: "fec_blocks_decoded": 0, "fec_blocks_unrecoverable": 0, } dedup = SeqWindow(args.dedup_window) if args.dedup else None - fec_enc = stream_fec.FecEncoder(fec_cfg) if fec_cfg else None - fec_dec = stream_fec.FecDecoder(fec_cfg) if fec_cfg else None + fec_enc = stream_fec.make_encoder(fec_cfg) if fec_cfg else None + fec_dec = stream_fec.make_decoder(fec_cfg) if fec_cfg else None fec_lock = threading.Lock() if fec_enc else None if single_binary: diff --git a/tools/precoder/uv.lock b/tools/precoder/uv.lock index e6f122e..c3f30f9 100644 --- a/tools/precoder/uv.lock +++ b/tools/precoder/uv.lock @@ -7,6 +7,101 @@ resolution-markers = [ "python_full_version < '3.10'", ] +[[package]] +name = "cffi" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser", version = "2.23", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' and implementation_name != 'PyPy'" }, + { name = "pycparser", version = "3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' and implementation_name != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/93/d7/516d984057745a6cd96575eea814fe1edd6646ee6efd552fb7b0921dec83/cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44", size = 184283, upload-time = "2025-09-08T23:22:08.01Z" }, + { url = "https://files.pythonhosted.org/packages/9e/84/ad6a0b408daa859246f57c03efd28e5dd1b33c21737c2db84cae8c237aa5/cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49", size = 180504, upload-time = "2025-09-08T23:22:10.637Z" }, + { url = "https://files.pythonhosted.org/packages/50/bd/b1a6362b80628111e6653c961f987faa55262b4002fcec42308cad1db680/cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c", size = 208811, upload-time = "2025-09-08T23:22:12.267Z" }, + { url = "https://files.pythonhosted.org/packages/4f/27/6933a8b2562d7bd1fb595074cf99cc81fc3789f6a6c05cdabb46284a3188/cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb", size = 216402, upload-time = "2025-09-08T23:22:13.455Z" }, + { url = "https://files.pythonhosted.org/packages/05/eb/b86f2a2645b62adcfff53b0dd97e8dfafb5c8aa864bd0d9a2c2049a0d551/cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0", size = 203217, upload-time = "2025-09-08T23:22:14.596Z" }, + { url = "https://files.pythonhosted.org/packages/9f/e0/6cbe77a53acf5acc7c08cc186c9928864bd7c005f9efd0d126884858a5fe/cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4", size = 203079, upload-time = "2025-09-08T23:22:15.769Z" }, + { url = "https://files.pythonhosted.org/packages/98/29/9b366e70e243eb3d14a5cb488dfd3a0b6b2f1fb001a203f653b93ccfac88/cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453", size = 216475, upload-time = "2025-09-08T23:22:17.427Z" }, + { url = "https://files.pythonhosted.org/packages/21/7a/13b24e70d2f90a322f2900c5d8e1f14fa7e2a6b3332b7309ba7b2ba51a5a/cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495", size = 218829, upload-time = "2025-09-08T23:22:19.069Z" }, + { url = "https://files.pythonhosted.org/packages/60/99/c9dc110974c59cc981b1f5b66e1d8af8af764e00f0293266824d9c4254bc/cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5", size = 211211, upload-time = "2025-09-08T23:22:20.588Z" }, + { url = "https://files.pythonhosted.org/packages/49/72/ff2d12dbf21aca1b32a40ed792ee6b40f6dc3a9cf1644bd7ef6e95e0ac5e/cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb", size = 218036, upload-time = "2025-09-08T23:22:22.143Z" }, + { url = "https://files.pythonhosted.org/packages/e2/cc/027d7fb82e58c48ea717149b03bcadcbdc293553edb283af792bd4bcbb3f/cffi-2.0.0-cp310-cp310-win32.whl", hash = "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a", size = 172184, upload-time = "2025-09-08T23:22:23.328Z" }, + { url = "https://files.pythonhosted.org/packages/33/fa/072dd15ae27fbb4e06b437eb6e944e75b068deb09e2a2826039e49ee2045/cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739", size = 182790, upload-time = "2025-09-08T23:22:24.752Z" }, + { url = "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344, upload-time = "2025-09-08T23:22:26.456Z" }, + { url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560, upload-time = "2025-09-08T23:22:28.197Z" }, + { url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613, upload-time = "2025-09-08T23:22:29.475Z" }, + { url = "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", size = 216476, upload-time = "2025-09-08T23:22:31.063Z" }, + { url = "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", size = 203374, upload-time = "2025-09-08T23:22:32.507Z" }, + { url = "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", size = 202597, upload-time = "2025-09-08T23:22:34.132Z" }, + { url = "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", size = 215574, upload-time = "2025-09-08T23:22:35.443Z" }, + { url = "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", size = 218971, upload-time = "2025-09-08T23:22:36.805Z" }, + { url = "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", size = 211972, upload-time = "2025-09-08T23:22:38.436Z" }, + { url = "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", size = 217078, upload-time = "2025-09-08T23:22:39.776Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076, upload-time = "2025-09-08T23:22:40.95Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820, upload-time = "2025-09-08T23:22:42.463Z" }, + { url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635, upload-time = "2025-09-08T23:22:43.623Z" }, + { url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" }, + { url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" }, + { url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" }, + { url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" }, + { url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" }, + { url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" }, + { url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" }, + { url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" }, + { url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" }, + { url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" }, + { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" }, + { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" }, + { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" }, + { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" }, + { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" }, + { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" }, + { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" }, + { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" }, + { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" }, + { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" }, + { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" }, + { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" }, + { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" }, + { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" }, + { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" }, + { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" }, + { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" }, + { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" }, + { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" }, + { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" }, + { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" }, + { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" }, + { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" }, + { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" }, + { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" }, + { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" }, + { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" }, + { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" }, + { url = "https://files.pythonhosted.org/packages/c0/cc/08ed5a43f2996a16b462f64a7055c6e962803534924b9b2f1371d8c00b7b/cffi-2.0.0-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:fe562eb1a64e67dd297ccc4f5addea2501664954f2692b69a76449ec7913ecbf", size = 184288, upload-time = "2025-09-08T23:23:48.404Z" }, + { url = "https://files.pythonhosted.org/packages/3d/de/38d9726324e127f727b4ecc376bc85e505bfe61ef130eaf3f290c6847dd4/cffi-2.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7", size = 180509, upload-time = "2025-09-08T23:23:49.73Z" }, + { url = "https://files.pythonhosted.org/packages/9b/13/c92e36358fbcc39cf0962e83223c9522154ee8630e1df7c0b3a39a8124e2/cffi-2.0.0-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:4647afc2f90d1ddd33441e5b0e85b16b12ddec4fca55f0d9671fef036ecca27c", size = 208813, upload-time = "2025-09-08T23:23:51.263Z" }, + { url = "https://files.pythonhosted.org/packages/15/12/a7a79bd0df4c3bff744b2d7e52cc1b68d5e7e427b384252c42366dc1ecbc/cffi-2.0.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3f4d46d8b35698056ec29bca21546e1551a205058ae1a181d871e278b0b28165", size = 216498, upload-time = "2025-09-08T23:23:52.494Z" }, + { url = "https://files.pythonhosted.org/packages/a3/ad/5c51c1c7600bdd7ed9a24a203ec255dccdd0ebf4527f7b922a0bde2fb6ed/cffi-2.0.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e6e73b9e02893c764e7e8d5bb5ce277f1a009cd5243f8228f75f842bf937c534", size = 203243, upload-time = "2025-09-08T23:23:53.836Z" }, + { url = "https://files.pythonhosted.org/packages/32/f2/81b63e288295928739d715d00952c8c6034cb6c6a516b17d37e0c8be5600/cffi-2.0.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:cb527a79772e5ef98fb1d700678fe031e353e765d1ca2d409c92263c6d43e09f", size = 203158, upload-time = "2025-09-08T23:23:55.169Z" }, + { url = "https://files.pythonhosted.org/packages/1f/74/cc4096ce66f5939042ae094e2e96f53426a979864aa1f96a621ad128be27/cffi-2.0.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:61d028e90346df14fedc3d1e5441df818d095f3b87d286825dfcbd6459b7ef63", size = 216548, upload-time = "2025-09-08T23:23:56.506Z" }, + { url = "https://files.pythonhosted.org/packages/e8/be/f6424d1dc46b1091ffcc8964fa7c0ab0cd36839dd2761b49c90481a6ba1b/cffi-2.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0f6084a0ea23d05d20c3edcda20c3d006f9b6f3fefeac38f59262e10cef47ee2", size = 218897, upload-time = "2025-09-08T23:23:57.825Z" }, + { url = "https://files.pythonhosted.org/packages/f7/e0/dda537c2309817edf60109e39265f24f24aa7f050767e22c98c53fe7f48b/cffi-2.0.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1cd13c99ce269b3ed80b417dcd591415d3372bcac067009b6e0f59c7d4015e65", size = 211249, upload-time = "2025-09-08T23:23:59.139Z" }, + { url = "https://files.pythonhosted.org/packages/2b/e7/7c769804eb75e4c4b35e658dba01de1640a351a9653c3d49ca89d16ccc91/cffi-2.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:89472c9762729b5ae1ad974b777416bfda4ac5642423fa93bd57a09204712322", size = 218041, upload-time = "2025-09-08T23:24:00.496Z" }, + { url = "https://files.pythonhosted.org/packages/aa/d9/6218d78f920dcd7507fc16a766b5ef8f3b913cc7aa938e7fc80b9978d089/cffi-2.0.0-cp39-cp39-win32.whl", hash = "sha256:2081580ebb843f759b9f617314a24ed5738c51d2aee65d31e02f6f7a2b97707a", size = 172138, upload-time = "2025-09-08T23:24:01.7Z" }, + { url = "https://files.pythonhosted.org/packages/54/8f/a1e836f82d8e32a97e6b29cc8f641779181ac7363734f12df27db803ebda/cffi-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:b882b3df248017dba09d6b16defe9b5c407fe32fc7c65a9c69798e6175601be9", size = 182794, upload-time = "2025-09-08T23:24:02.943Z" }, +] + [[package]] name = "colorama" version = "0.4.6" @@ -21,6 +116,7 @@ name = "devourer-precoder" version = "0.1.0" source = { virtual = "." } dependencies = [ + { name = "cffi" }, { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, @@ -36,10 +132,12 @@ sdr = [ dev = [ { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "pytest", version = "9.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "setuptools" }, ] [package.metadata] requires-dist = [ + { name = "cffi", specifier = ">=1.16" }, { name = "numpy", specifier = ">=1.23" }, { name = "pyrtlsdr", marker = "extra == 'sdr'", specifier = ">=0.2.93" }, { name = "raptorq", specifier = ">=2" }, @@ -47,7 +145,10 @@ requires-dist = [ provides-extras = ["sdr"] [package.metadata.requires-dev] -dev = [{ name = "pytest", specifier = ">=7" }] +dev = [ + { name = "pytest", specifier = ">=7" }, + { name = "setuptools", specifier = ">=82.0.1" }, +] [[package]] name = "exceptiongroup" @@ -306,6 +407,31 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] +[[package]] +name = "pycparser" +version = "2.23" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload-time = "2025-09-09T13:23:47.91Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload-time = "2025-09-09T13:23:46.651Z" }, +] + +[[package]] +name = "pycparser" +version = "3.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.11'", + "python_full_version == '3.10.*'", +] +sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, +] + [[package]] name = "pygments" version = "2.20.0" @@ -376,6 +502,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/06/f4/85d0e976816b9e2aac6f35552690801e848a232453adb64d517c35169adb/raptorq-2.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7cc9ffb024969b3cb33ae4f3789431fae0e225b19ae8bad85bb67703e564532", size = 374706, upload-time = "2024-03-16T00:58:26.626Z" }, ] +[[package]] +name = "setuptools" +version = "82.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4f/db/cfac1baf10650ab4d1c111714410d2fbb77ac5a616db26775db562c8fab2/setuptools-82.0.1.tar.gz", hash = "sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9", size = 1152316, upload-time = "2026-03-09T12:47:17.221Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/76/f789f7a86709c6b087c5a2f52f911838cad707cc613162401badc665acfe/setuptools-82.0.1-py3-none-any.whl", hash = "sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb", size = 1006223, upload-time = "2026-03-09T12:47:15.026Z" }, +] + [[package]] name = "tomli" version = "2.4.1" diff --git a/tools/precoder/vendor/swif-codec/AUTHORS.txt b/tools/precoder/vendor/swif-codec/AUTHORS.txt new file mode 100644 index 0000000..cfa1c1f --- /dev/null +++ b/tools/precoder/vendor/swif-codec/AUTHORS.txt @@ -0,0 +1,17 @@ +This file lists the authors of the swif-codec. +This software has been developed in the context of the SWiF Codec IETF Hackathon project. +Contact: Vincent Roca (vincent.roca@inria.fr) + +--- +Main contributors/developers (alphabetical order) + +Cedric Adjih (Inria, France) +Oumaima Attia (Inria, France) +Francois Michel (UCLouvain, Belgium) +Vincent Roca (Inria, France) + +--- +Additional contributors (alphabetical order) + +Marie-Jose Montpetit (Research Affiliate, MIT Media Laboratory, USA) + diff --git a/tools/precoder/vendor/swif-codec/COMMIT b/tools/precoder/vendor/swif-codec/COMMIT new file mode 100644 index 0000000..3a7c7a1 --- /dev/null +++ b/tools/precoder/vendor/swif-codec/COMMIT @@ -0,0 +1 @@ +de8cd8e2f3236f8a428eb626209c2ace0bbc33f7 diff --git a/tools/precoder/vendor/swif-codec/LICENCE.txt b/tools/precoder/vendor/swif-codec/LICENCE.txt new file mode 100644 index 0000000..0d811c4 --- /dev/null +++ b/tools/precoder/vendor/swif-codec/LICENCE.txt @@ -0,0 +1,26 @@ +The SWiF Codec IETF Hackathon project is distributed under the +Simplified BSD licence, in accordance with BCP 78 and the IETF +Trust's Legal Provisions Relating to IETF Documents +(http://trustee.ietf.org/license-info). + +One goal of this licence is to be able to include this sofware +in parts or in totality in IETF documents without conflicting +with licencing rules attached to IETF Contributions and IETF +Documents. + +The list of authors is available in file AUTHORS.txt. + +Contact: vincent.roca@inria.fr + +--- + +Copyright (c) 2019 IETF Trust and the persons identified as authors of the code. All rights reserved. +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. + + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/tools/precoder/vendor/swif-codec/PATCHES.md b/tools/precoder/vendor/swif-codec/PATCHES.md new file mode 100644 index 0000000..f56cdd1 --- /dev/null +++ b/tools/precoder/vendor/swif-codec/PATCHES.md @@ -0,0 +1,45 @@ +# Local patches to upstream swif-codec + +Upstream: +Vendored commit: see `COMMIT` (currently `de8cd8e`). + +A handful of small fixes are applied in-place so this source tree builds +with a strict C99 compiler (gcc 13+, clang) and runs without flooding +stdout. They were not yet addressed upstream at the time of vendoring. + +## Patch 1 — `src/swif_api.h` line ~394 + +Declaration of `swif_decoder_set_callback_functions`'s +`decoded_source_symbol_callback` parameter listed `void (*)(…)` (no return +value) while the underlying `swif_decoder_t` function-pointer table +(line ~290) and every codec-specific header (`swif_rlc_api.h:84`, +`swif_rlc_cb.h:106`) use `void* (*)(…)`. Fixed in our copy to match the +function-pointer table; this is the canonical signature used by callers +and the decoder dispatch path. + +## Patch 2 — `src/swif_api.c` line ~160 + +Definition of the same dispatcher function had the same outdated `void` +return-type signature. Fixed to `void*` to match the patched header and +the underlying pointer table. + +## Patch 3 — `src/swif_api.c` line 6 + +Removed `#define DEBUG 1` so the conditional `DEBUG_PRINT(...)` macros +in `swif_general.h` stay no-ops at runtime. The upstream `#define DEBUG` +forced every codec to dump every Gaussian-elimination step and every +coefficient vector to stderr, which buries useful logs. + +## Patch 4 — `src/swif_rlc_api.c` + +Two unconditional `printf("notify decoded: ...")` calls and three +unconditional `full_symbol_dump(..., stdout)` calls were removed (replaced +with `/* PATCHED: silenced */`). Upstream's intent was a verbose mode for +the integrated test harness; in a library context they're noise. + +## Rationale + +Patches 1–2 are correctness fixes (without them `gcc -std=c99 -Wall` +refuses to compile `swif_api.c`). Patches 3–4 are noise-suppression for +library use. No semantic changes to the encoder / decoder algorithms or +wire format. diff --git a/tools/precoder/vendor/swif-codec/README-upstream.md b/tools/precoder/vendor/swif-codec/README-upstream.md new file mode 100644 index 0000000..c37fcbb --- /dev/null +++ b/tools/precoder/vendor/swif-codec/README-upstream.md @@ -0,0 +1,111 @@ +# The swif-codec Repository + +-------- + +**an Open-source sliding window FEC codec (IETF hackathon)** + +Main goal is to develop an open-source C-language codec for a sliding window FEC code. These codes can boost performance of content delivery protocols in harsh environments where packet losses can be frequent, while keeping the FEC-related added latency low. + +This development is done in the context of the "Coding for Efficient Network Communications" IRTF Research Group (NWCRG, [https://datatracker.ietf.org/rg/nwcrg]) and IETF hackathon [https://trac.ietf.org/trac/ietf/meeting/wiki/103hackathon]. + +This work has strong relationships with the Generic API I-D [https://datatracker.ietf.org/doc/draft-roca-nwcrg-generic-fec-api/] and RLC codes [https://datatracker.ietf.org/doc/draft-ietf-tsvwg-rlc-fec-scheme/] as examples of sliding window codes. Possible applications to QUIC [https://datatracker.ietf.org/doc/draft-swett-nwcrg-coding-for-quic/] and [https://datatracker.ietf.org/doc/draft-roca-nwcrg-rlc-fec-scheme-for-quic/], among others, are expected. + +-------- + +## Assumptions and limits of the SWIF-codec + +The codec is not thread-safe: a single codec instance is limited to a single execution thread. +However a given application may use several threads, each of them creating their own codec instances. + + +## Reference documents + +### API for the SWiF Codec + +[Datatracker API Internet-draft](https://datatracker.ietf.org/doc/draft-roca-nwcrg-generic-fec-api/) + +[GitHub current API Internet-draft](https://github.com/vincent-grenoble/generic_fec_api) - to be prefered to have the latest under-progress version + +[API Slides (ietf102 nwcrg meeting)](https://github.com/irtf-nwcrg/rg-materials/blob/master/ietf102-2018-07_montreal/03_roca_generic_fec_api.pdf) + +This dradft and associated slides discuss two things: +- what mechanisms should be in the SWiF Codec versus in the caller? +The codec is not supposed to include everything since parts of a FEC Scheme are clearly protocol specific (e.g., signalling aspects). + +- a description of the codec API. + +### RLC Sliding Window FEC Scheme whose parts can be reused + +The [RLC FEC Scheme](https://datatracker.ietf.org/doc/draft-ietf-tsvwg-rlc-fec-scheme/) describes a Sliding Window FEC Scheme (i.e., the codec plus signalling aspects). +Parts of this document can be re-used (e.g., its PRNG and coding coefficients generation function, some of the internal parameters, etc.). + +However the goal **IS NOT** to implement RLC. For instance in-network re-encoding should be supported by SWiF Codec that is totally out-of-scope for RLC. + +The [ietf98 TSVWG slides 9-10-11](https://datatracker.ietf.org/meeting/98/materials/slides-98-tsvwg-sessb-63-fecframe-drafts-00) explain how Sliding Window FEC Codes, like RLC, work. + + +## Eight simple ideas for newcomers to start understanding FEC and Network Coding + +### Idea 1- +#### "We focus on networks where a packet either arrives or is lost" +- we're not at PHY-layer, we are above in the protocol stack and potential bit errors have either been fixed or the packet dropped + +### Idea 2- +#### "Encoding consists in adding redundancy (i.e., "repair packets") to the flow" + +#### "Decoding consists in using redundancy (i.e., using "repair packets") to recover from packet losses" + +### Idea 3- +#### "Math is not an obstacle to understand FEC and NC" +- it's essentially a matter of **linear combination and linear system resolution** (e.g., via basic Gaussian elimination) +- details (e.g., computations in a certain Finite Field) can be complex, but mastering them is not required + +### Idea 4- +#### "There are roughly two categories of FEC codes: block codes and sliding window codes" +- block: segment the packet flow into blocks and apply FEC encoding per block, independently +- sliding window: an encoding window slides progressively over the packet flow, the encoder computes a linear combination of packets in this encoding window + +### Idea 5- +#### "With large independant data objects, block codes are great, with streams of real-time data that have time correlation, sliding window codes are preferable" +- ... because splitting the application flow into blocks delays the moment when "repair packets" can be generated! +- code performance also depends on the type of losses (independant, uniform losses versus correlated, bursty losses) + +### Idea 6- +#### "Some codes are restricted to a single encoder (e.g., sender) and single decoder (e.g., receiver)" +- usually called FEC + +#### "Other codes can be used within intermediate nodes (i.e., multiple encoders)" +- usually called Network Coding (NC) + +### Idea 7- +#### "With NC, network equipments can perform FEC encoding to improve network usage" +- trivial example where a network equipment could reduce traffic (it sends a single "P1 XOR P2" packet (using multicast or broadcast) instead of sending both P1 and P2): + +
Alice        Wireless router          Bob    
+  |    --P1-->      |                 |    
+  |                 |     <--P2--     |    
+  | <--P1 XOR P2--- | ---P1 XOR P2--> | (multicast or broadcast)
+  |                 |                 |
+recover P2                     Recover P1
+
+ +### Idea 8- +#### "One can use FEC and NC in a congestion friendly manner" +- only stupid persons will further overload a congested network with even more redundant traffic in the hope it may help! + + +## Open-source projects to get inspiration from + +- Gardinet (Cedric Adjih): [https://gitlab.inria.fr/GardiNet/liblc/] + Note that this implementation (1) does not provide clear separation between the codec and the protocol parts, and (2) has many compilation time defined constants. + +- OpenFEC (Vincent Roca): [http://openfec.org] + Note that this implementation does not include in its public version support for Sliding Window Codes. + However it includes GF(256) support from Luigi Rizzo in the Reed-Solomon codec as well as an advanced performance evaluation framework (eperftool). + +- NB: Kodo (Morten V. Pedersen, Steinwurf) is highly relevent as it provides several Sliding Window codecs [http://docs.steinwurf.com/kodo.html]. + However it is **NOT RECOMMENDED** to get inspiration from this project because of incompatible licences with the SWiFCodec project. + + +## Contact +vincent.roca@inria.fr diff --git a/tools/precoder/vendor/swif-codec/src/Makefile b/tools/precoder/vendor/swif-codec/src/Makefile new file mode 100644 index 0000000..b4061c1 --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/Makefile @@ -0,0 +1,101 @@ +#--------------------------------------------------------------------------- +# Author: Cedric Adjih, Hana Baccouch +#--------------------------------------------------------------------------- +# Copyright 2015-2017 Inria +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +#--------------------------------------------------------------------------- + +-include Makefile.local + +#-------------------------------------------------- + +ifeq ($(WITH_SANITIZE),1) +SANITIZE=-fsanitize=leak -fsanitize=address -fsanitize=undefined -static-libasan -static-libubsan -fno-omit-frame-pointer +else +SANTIZE= +endif + + +CFLAGS += -Wall -g3 -fPIC -std=c99 -O3 $(SANITIZE) + +#------------------------------ + +# TODO : swif_linear-code.c +SRCS += swif_api.c swif_prng.c swif_coding_coefficients.c swif_symbol.c swif_rlc_api.c +SRCS += swif_full_symbol.c +SRCS += $(EXTRA_SRCS) + +HEADERS += $(SRCS:.c=.h) swif_general.h swif_includes.h swif_rlc_cb.h +HEADERS += $(EXTRA_HEADERS) + +OBJS = $(SRCS:.c=.o) + +#--------------------------------------------------------------------------- +# Main targets +#--------------------------------------------------------------------------- + +all: libswif.a + +#--------------------------------------------------------------------------- +# Dependencies +# http://stackoverflow.com/questions/97338/gcc-dependency-generation-for-a-different-output-directory +#--------------------------------------------------------------------------- + +DEPS = $(SRCS:.c=.d) + +-include $(DEPS) + +%.d : %.c %.h + $(CC) $(CFLAGS) -MF"$@" -MG -MM -MP -MT"$@" -MT"$(<:.c=.o)" "$<" + +#--------------------------------------------------------------------------- +# Library +#--------------------------------------------------------------------------- + +libswif.a: ${OBJS} + ${AR} cru $@ ${OBJS} + +#--------------------------------------------------------------------------- +# Testing +#--------------------------------------------------------------------------- + +test-coded-packet: test-coded-packet.o libswif.a + ${CC} ${CFLAGS} -o $@ $< -llc -L. + +#--------------------------------------------------------------------------- +# Documentation +#--------------------------------------------------------------------------- + +doc: + doxygen Doxyfile + sensible-browser html/index.html + +#--------------------------------------------------------------------------- +# Cleaning +#--------------------------------------------------------------------------- + +clean: + rm -f *.a *.so *.o *.d *~ + rm -f test-coded-packet + +really-clean: clean + +#--------------------------------------------------------------------------- diff --git a/tools/precoder/vendor/swif-codec/src/Makefile.liblc b/tools/precoder/vendor/swif-codec/src/Makefile.liblc new file mode 100644 index 0000000..fb15063 --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/Makefile.liblc @@ -0,0 +1,15 @@ +#--------------------------------------------------------------------------- +# Include this file in the Makefile.local or Makefile +#--------------------------------------------------------------------------- + +CC=gcc + +#CFLAGS += -fno-strict-aliasing -arch x86_64 -g -fwrapv \ +# -Wall -Wstrict-prototypes + +#CFLAGS += -DWITH_LIBLC + +CFLAGS += -I../liblc/src +EXTRA_SRCS += swif_full_symbol.c + +#--------------------------------------------------------------------------- diff --git a/tools/precoder/vendor/swif-codec/src/README-full-symbol.md b/tools/precoder/vendor/swif-codec/src/README-full-symbol.md new file mode 100644 index 0000000..8b30372 --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/README-full-symbol.md @@ -0,0 +1,33 @@ + +## "Full symbol" and "Full symbol set" + +The concept of "full symbol" is a symbol associated with the coefficients +of the source symbols (e.g. encoding vector), that specifies the linear +combination corresponding to the symbol. + +Symbols can be added, combined, etc. They are mostly used in with +a "full symbol set" that performs Gaussian Elimination. + +## Status + + * Interface has been defined for "full symbol" + * Python wrappers are being implemented to test (for testing) + * Initial implementation will be based on liblc (just to get it work) + +## Interface + + * The interface is realized as an internal API for swif, intended for the +decoder. It is defined in `swif_full_symbol.h` + * The step-1 adaptation, using liblc, is in `swif_full_symbol_lc.c` + +## Compilation + + * In order to actually compile with liblc you need to: + * checkout `liblc` in the root of swif-codec + (shortcut: `cd wrapper/python && make ensure-liblc`) + * actually compile the liblc adapters, by including Makefile.liblc in the Makefile + (shortcut: `ln -s Makefile.liblc Makefile.local`) + + * The test is in: + `cd wrapper/python && make && python test_swif.py` + diff --git a/tools/precoder/vendor/swif-codec/src/swif_api.c b/tools/precoder/vendor/swif-codec/src/swif_api.c new file mode 100644 index 0000000..27c88ea --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_api.c @@ -0,0 +1,377 @@ +/** + * SWiF Codec: an open-source sliding window FEC codec in C + * https://github.com/irtf-nwcrg/swif-codec + */ + +/* PATCHED: removed `#define DEBUG 1` to silence verbose codec output. See PATCHES.md. */ +#include "swif_includes.h" +#include "swif_rlc_api.c" + + +/******************************************************************************* + * Encoder functions + */ + + +/** + * Create and initialize an encoder, providing only key parameters. + **/ +swif_encoder_t* swif_encoder_create ( + swif_codepoint_t codepoint, + uint32_t verbosity, + uint32_t symbol_size, + uint32_t max_coding_window_size) +{ + /* initialize the encoder */ + switch (codepoint) { + case SWIF_CODEPOINT_RLC_GF_256_FULL_DENSITY_CODEC: + return (swif_rlc_encoder_create(codepoint, verbosity, symbol_size, max_coding_window_size)); + default: + fprintf(stderr, "Error, swif_encoder_create: codepoint not recognized\n"); + return NULL; + } +} + + +/** + * Release an encoder and its associated ressources. + **/ +swif_status_t swif_encoder_release (swif_encoder_t* enc) +{ + /* initialize the encoder */ + switch (enc->codepoint) { + case SWIF_CODEPOINT_RLC_GF_256_FULL_DENSITY_CODEC: + return (swif_rlc_encoder_release(enc)); + default: + fprintf(stderr, "Error, swif_encoder_release: codepoint not recognized\n"); + return SWIF_STATUS_ERROR; + } +} + + +/** + * Set the various callback functions for this encoder. + * All the callback functions require an opaque context parameter, that must be + * initialized accordingly by the application, since it is application specific. + */ +swif_status_t swif_encoder_set_callback_functions ( + swif_encoder_t* enc, + void (*source_symbol_removed_from_coding_window_callback) ( + void* context, + esi_t old_symbol_esi), + void* context_4_callback) +{ + return (*enc->set_callback_functions)(enc, source_symbol_removed_from_coding_window_callback, context_4_callback); +} + +/** + * This function sets one or more FEC codec specific parameters, + * using a type/length/value approach for maximum flexibility. + */ +swif_status_t swif_encoder_set_parameters ( + swif_encoder_t* enc, + uint32_t type, + uint32_t length, + void* value) +{ + return (*enc->set_parameters)(enc, type, length, value); +} + +/** + * This function gets one or more FEC codec specific parameters, + * using a type/length/value approach for maximum flexibility. + */ +swif_status_t swif_encoder_get_parameters ( + swif_encoder_t* enc, + uint32_t type, + uint32_t length, + void* value) +{ + return (*enc->get_parameters)(enc, type, length, value); +} + + +/** + * Create a single repair symbol (i.e. perform an encoding). + */ +swif_status_t swif_build_repair_symbol ( + swif_encoder_t* enc, + void** new_buf) +{ + return (*enc->build_repair_symbol)(enc, new_buf); +} + + +/******************************************************************************* + * Decoder functions + */ + + +/** + * Create and initialize a decoder, providing only key parameters. + */ +swif_decoder_t* swif_decoder_create ( + swif_codepoint_t codepoint, + uint32_t verbosity, + uint32_t symbol_size, + uint32_t max_coding_window_size, + uint32_t max_linear_system_size) +{ + /* initialize the decoder */ + switch (codepoint) { + case SWIF_CODEPOINT_RLC_GF_256_FULL_DENSITY_CODEC: + return (swif_rlc_decoder_create(codepoint, verbosity, symbol_size, max_coding_window_size, max_linear_system_size)); + default: + fprintf(stderr, "Error, swif_decoder_create: codepoint not recognized\n"); + return NULL; + } +} + + +/** + * Release a decoder and its associated ressources. + **/ +swif_status_t swif_decoder_release (swif_decoder_t* dec) +{ + switch (dec->codepoint) { + case SWIF_CODEPOINT_RLC_GF_256_FULL_DENSITY_CODEC: + return (swif_rlc_decoder_release(dec)); + default: + fprintf(stderr, "Error, swif_decoder_release: codepoint not recognized\n"); + return SWIF_STATUS_ERROR; + } +} + + +/** + * Set the various callback functions for this decoder. + * All the callback functions require an opaque context parameter, that + * must be initialized accordingly by the application, since it is + * application specific. + */ +swif_status_t swif_decoder_set_callback_functions ( + swif_decoder_t* dec, + void (*source_symbol_removed_from_linear_system_callback) ( + void* context, + esi_t old_symbol_esi), + void* (*decodable_source_symbol_callback) ( + void *context, + esi_t esi), + void* (*decoded_source_symbol_callback) ( + void *context, + void *new_symbol_buf, + esi_t esi), + void* context_4_callback) +{ + return (*dec->set_callback_functions)(dec, source_symbol_removed_from_linear_system_callback, + decodable_source_symbol_callback, decoded_source_symbol_callback, + context_4_callback); +} + + +/** + * This function sets one or more FEC codec specific parameters, + * using a type/length/value approach for maximum flexibility. + */ +swif_status_t swif_decoder_set_parameters ( + swif_decoder_t* dec, + uint32_t type, + uint32_t length, + void* value) +{ + return (*dec->set_parameters)(dec, type, length, value); +} + + +/** + * This function gets one or more FEC codec specific parameters, + * using a type/length/value approach for maximum flexibility. + */ +swif_status_t swif_decoder_get_parameters ( + swif_decoder_t* dec, + uint32_t type, + uint32_t length, + void* value) +{ + return (*dec->get_parameters)(dec, type, length, value); +} + + +/** + * Submit a received source symbol and try to progress in the decoding. + * For each decoded source symbol (if any), the application is informed + * through the dedicated callback functions. + */ +swif_status_t swif_decoder_decode_with_new_source_symbol ( + swif_decoder_t* dec, + void* const new_symbol_buf, + esi_t new_symbol_esi) +{ + return (*dec->decode_with_new_source_symbol)(dec, new_symbol_buf, new_symbol_esi); +} + + +/** + * Submit a received repair symbol and try to progress in the decoding. + * For each decoded source symbol (if any), the application is informed + * through the dedicated callback functions. + */ +swif_status_t swif_decoder_decode_with_new_repair_symbol ( + swif_decoder_t* dec, + void* const new_symbol_buf, + esi_t new_src_symbol_esi) +{ + return (*dec->decode_with_new_repair_symbol)(dec, new_symbol_buf, new_src_symbol_esi); +} + + +/******************************************************************************* + * Coding Window Functions at an Encoder and Decoder + */ + + +/** + * This function resets the current coding window. We assume here that + * this window is maintained by the FEC codec instance. + * Encoder: reset the encoding window for the encoding of future + * repair symbols. + * Decoder: reset the coding window under preparation associated to + * a repair symbol just received. + */ +swif_status_t swif_encoder_reset_coding_window (swif_encoder_t* enc) +{ + return (*enc->reset_coding_window)(enc); +} + +swif_status_t swif_decoder_reset_coding_window (swif_decoder_t* dec) +{ + return (*dec->reset_coding_window)(dec); +} + +/** + * Add this source symbol to the coding window. + * Encoder: add a source symbol to the coding window. + * Decoder: add a source symbol to the coding window under preparation. + */ +swif_status_t swif_encoder_add_source_symbol_to_coding_window ( + swif_encoder_t* enc, + void* new_src_symbol_buf, + esi_t new_src_symbol_esi) +{ +/* ajouter un élément à la liste chainée des symboles sources +retirer le symbole source le plus ancien si l'EW déborde. */ + return (*enc->add_source_symbol_to_coding_window)(enc, new_src_symbol_buf, new_src_symbol_esi); +} + +swif_status_t swif_decoder_add_source_symbol_to_coding_window ( + swif_decoder_t* dec, + esi_t new_src_symbol_esi) +{ + return (*dec->add_source_symbol_to_coding_window)(dec, new_src_symbol_esi); +} + + +/** + * Remove this source symbol from the coding window. + */ +swif_status_t swif_encoder_remove_source_symbol_from_coding_window ( + swif_encoder_t* enc, + esi_t old_src_symbol_esi) +{ + return (*enc->remove_source_symbol_from_coding_window)(enc, old_src_symbol_esi); +} + +swif_status_t swif_decoder_remove_source_symbol_from_coding_window ( + swif_decoder_t* dec, + esi_t old_src_symbol_esi) +{ + return (*dec->remove_source_symbol_from_coding_window)(dec, old_src_symbol_esi); +} + + +/** + * Get information on the current coding window at the encoder. + */ +swif_status_t swif_encoder_get_coding_window_information ( + swif_encoder_t* enc, + esi_t* first, + esi_t* last, + uint32_t* nss) +{ + return (*enc->get_coding_window_information)(enc, first, last, nss); +} + + +/******************************************************************************* + * Coding Coefficients Functions at an Encoder and Decoder + */ + + +/** + * Encoder: this function specifies the coding coefficients chosen by + * the application if this is the way the codec works. + * Decoder: communicate with this function the coding coefficients + * associated to a repair symbol and carried in the packet + * header. + */ +swif_status_t swif_encoder_set_coding_coefs_tab ( + swif_encoder_t* enc, + void* coding_coefs_tab, + uint32_t nb_coefs_in_tab) +{ + return (*enc->set_coding_coefs_tab)(enc, coding_coefs_tab, nb_coefs_in_tab); +} + + +swif_status_t swif_decoder_set_coding_coefs_tab ( + swif_decoder_t* dec, + void* coding_coefs_tab, + uint32_t nb_coefs_in_tab) +{ + return (*dec->set_coding_coefs_tab)(dec, coding_coefs_tab, nb_coefs_in_tab); +} + + +/** + * The coding coefficients may be generated in a deterministic manner, + * for instance by a PRNG known by the codec and a seed (perhaps with + * other parameters) provided by the application. + * The codec may also choose in an autonomous manner these coefficients. + * This function is used to trigger this process. + * When the choice is made in an autonomous manner, the actual coding + * coefficient or key used by the codec can be retrieved with + * swif_encoder_get_coding_coefs_tab(). + */ +swif_status_t swif_encoder_generate_coding_coefs ( + swif_encoder_t* enc, + uint32_t key, + uint32_t add_param) +{ + return (*enc->generate_coding_coefs)(enc, key, add_param); +} + +swif_status_t swif_decoder_generate_coding_coefs ( + swif_decoder_t* dec, + uint32_t key, + uint32_t add_param) +{ + return (*dec->generate_coding_coefs)(dec, key, add_param); +} + + +/** + * This function enables the application to retrieve the set of coding + * coefficients generated and used by build_repair_symbol(). This is + * useful when the choice of coefficients is performed by the codec in + * an autonomous manner but needs to be sent in the repair packet header. + * This function is only used by an encoder. + */ +swif_status_t swif_encoder_get_coding_coefs_tab ( + swif_encoder_t* enc, + void** coding_coefs_tab, + uint32_t* nb_coefs_in_tab) +{ + return (*enc->get_coding_coefs_tab)(enc, coding_coefs_tab, nb_coefs_in_tab); +} + + diff --git a/tools/precoder/vendor/swif-codec/src/swif_api.h b/tools/precoder/vendor/swif-codec/src/swif_api.h new file mode 100644 index 0000000..062b897 --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_api.h @@ -0,0 +1,709 @@ +/** + * @defgroup SWiF-Codec-API + * @ingroup swif-codec-api + * @brief an open-source sliding window FEC codec in C (API) + * @{ + * + * @file + * @brief The Generic FEC API + * + */ + +/** + * SWiF Codec: an open-source sliding window FEC codec in C + * https://github.com/irtf-nwcrg/swif-codec + */ +#include +#ifndef __SWIF_API_H__ +#define __SWIF_API_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ + + +/** + * Return value of any function. + * + * SWIF_STATUS_OK = 0 Success + * SWIF_STATUS_FAILURE Failure. The function called did not succeed to + * perform its task, however this is not an error + * (e.g., it happens when decoding fails). + * SWIF_STATUS_ERROR Generic error type. The detailed error type is + * stored in the errno variable of swif_encoder_t and + * swif_decoder_t structures. + */ +typedef enum { + SWIF_STATUS_OK = 0, + SWIF_STATUS_FAILURE, + SWIF_STATUS_ERROR +} swif_status_t; + + +/** + * Potential errors. + */ +typedef enum { + SWIF_ERRNO_NULL = 0, /* everything is fine */ + SWIF_ERRNO_UNSUPPORTED_CODEPOINT, + /* and many more... */ +} swif_errno_t; + + +/** + * FEC Codepoints. + * These identifiers are opaque identifiers that fully identify an FEC + * code locally, including certain parameters like its Galois Field, or + * the coding coefficient generator (if several exist). + * These codepoints are codec specific and only have a local meaning. + * They should not be transmitted as different implementations may use + * them inconsistently. + * Note that the same FEC code may be used by several FEC Encoding IDs + * and therefore share the same codepoint. On the opposite multiple + * implementations of a given FEC code may exist locally, for instance + * with different optimizations, and then several codepoints, one per + * codec, will exist for the same FEC code. The following names are + * therefore only provided as examples. + */ +typedef enum { + SWIF_CODEPOINT_NULL = 0, /* codepoint 0 is reserved */ + + /* codepoint for RLC sliding window code, GF(2^8) and full + * density (simplified version of FECFRAME FEC Enc. ID XXX). */ + SWIF_CODEPOINT_RLC_GF_256_FULL_DENSITY_CODEC + + /* list here other identifiers for any codec of interest... */ +} swif_codepoint_t; + + +/** + * Encoding Symbol Identifier (ESI) generic type. + * With Sliding Window FEC codes, an ESI is in fact a source symbol + * identifier, unlike block FEC codes. + */ +typedef uint32_t esi_t; + +/* Unused/invalid esi value. Must be coherent with esi_t definition */ +#define INVALID_ESI 0xFFFFFFFF + + +/******************************************************************************* + * Encoder functions + */ + +/* + * TODO: it would make sense to hide the functions (and even + * other attributes ?) to the above application so as the + * application can only interact through the defined API. + */ + +/** + * Throughout the API, a pointer to this structure is used as an + * identifier of the encoder instance (or "enc"). + * + * This generic structure is meant to be extended by each codec with + * new pieces of information that are specific to each codec. + */ +typedef struct swif_encoder { + swif_codepoint_t codepoint; + + /* when a function returns with SWIF_STATUS_ERROR, the errno + * variable contains a more detailed error type. This variable + * is set by the codec and accessible to the application in + * READ ONLY mode. Otherwise its value is undefined. */ + swif_errno_t swif_errno; + + /* pointers to codec specific versions of API functions. */ + swif_status_t (*set_callback_functions) ( + struct swif_encoder*, void (*) (void*, esi_t), void*); + swif_status_t (*set_parameters) ( + struct swif_encoder*, uint32_t, uint32_t, void*); + swif_status_t (*get_parameters) ( + struct swif_encoder*, uint32_t, uint32_t, void*); + swif_status_t (*build_repair_symbol) ( + struct swif_encoder*, void**); + swif_status_t (*reset_coding_window) (struct swif_encoder*); + swif_status_t (*add_source_symbol_to_coding_window) ( + struct swif_encoder*, void*, esi_t); + swif_status_t (*remove_source_symbol_from_coding_window) ( + struct swif_encoder*, esi_t); + swif_status_t (*get_coding_window_information) ( + struct swif_encoder*, esi_t*, esi_t*, uint32_t*); + swif_status_t (*set_coding_coefs_tab) ( + struct swif_encoder*, void*, uint32_t); + swif_status_t (*generate_coding_coefs) ( + struct swif_encoder*, uint32_t, uint32_t); + swif_status_t (*get_coding_coefs_tab) ( + struct swif_encoder*, void**, uint32_t*); +} swif_encoder_t; + + +/** + * Create and initialize an encoder, providing only key parameters. + * + * @param codepoint opaque identifier that fully identifies the FEC + * code to use. + * @param verbosity print information on the codec processing. + * 0 is the minimum verbosity, the maximum verbosity + * level being implementation specific. + * @param symbol_size source and repair symbol size in bytes. Cannot + * change during the codec instance lifetime. + * @param max_encoding_window_size + * @return pointer to a swif_encoder_t structure if okay, or + * NULL in case of error. + **/ +swif_encoder_t* swif_encoder_create ( + swif_codepoint_t codepoint, + uint32_t verbosity, + uint32_t symbol_size, + uint32_t max_coding_window_size); + + +/** + * Release an encoder and its associated ressources. + **/ +swif_status_t swif_encoder_release (swif_encoder_t* enc); + + +/** + * Set the various callback functions for this encoder. + * All the callback functions require an opaque context parameter, that + * must be initialized accordingly by the application, since it is + * application specific. + * + * @param enc + * @param source_symbol_removed_from_coding_window_callback + * (IN) Pointer to the function, within the application, + * that needs to be called each time a source symbol is + * removed from the left side of the coding window. + * This callback is called each time the encoding window + * slides to the right and an old source symbol needs to + * be removed on the left. The application therefore knows + * this source symbol will no longer be used by the codec + * and can free the associated buffer if need be. This + * function does not return anything. + * @param context_4_callback + * (IN) Pointer to the application-specific context that + * will be passed to the callback function (if any). This + * context is not interpreted by this function. + * @return + */ +swif_status_t swif_encoder_set_callback_functions ( + swif_encoder_t* enc, + void (*source_symbol_removed_from_coding_window_callback) ( + void* context, + esi_t old_symbol_esi), + void* context_4_callback); + +/** + * This function sets one or more FEC codec specific parameters, + * using a type/length/value approach for maximum flexibility. + * + * @param enc + * @param type (IN) Type of parameter. + * @param length (IN) length of the pointed value. + * @param value (IN) Pointer to the value. The exact type of + * the object pointed is FEC codec specific. + * @return + */ +swif_status_t swif_encoder_set_parameters ( + swif_encoder_t* enc, + uint32_t type, + uint32_t length, + void* value); + +/** + * This function gets one or more FEC codec specific parameters, + * using a type/length/value approach for maximum flexibility. + * + * @param enc + * @param type (IN) Type of parameter. + * @param length (IN) length of the pointed value. + * @param value (IN/OUT) Pointer to the value. The exact type of + * the object pointed is FEC codec specific. + * This function updates the value object + * accordingly. The caller, who knows the FEC codec, + * is responsible to allocate the appropriate + * object buffer. + * @return + */ +swif_status_t swif_encoder_get_parameters ( + swif_encoder_t* enc, + uint32_t type, + uint32_t length, + void* value); + +/** + * List here the FEC codec specific control parameters. + */ +enum { + swif_ENCODER_GET_PARAM_ENCODER_STATISTICS = 1, + swif_ENCODER_SET_PARAM_RLC_DENSITY_THRESHOLD +}; + + +/** + * Create a single repair symbol (i.e. perform an encoding). + * + * @param new_buf (IN/OUT) Address of a pointer to the buffer for + * the repair symbol to build. The pointer can + * either point to a buffer allocated by the + * application, or be set to NULL meaning that + * this function will allocate memory and initialize + * this pointer accordingly. + * @return + */ +swif_status_t swif_build_repair_symbol ( + swif_encoder_t* enc, + void** new_buf); + + +/******************************************************************************* + * Decoder functions + */ + + +/** + * Throughout the API, a pointer to this structure is used as an + * identifier of the decoder instance (or "dec"). + * + * This generic structure is meant to be extended by each codec with + * new pieces of information that are specific to each codec. + */ +typedef struct swif_decoder { + swif_codepoint_t codepoint; + + /* when a function returns with SWIF_STATUS_ERROR, the errno + * variable contains a more detailed error type. This variable + * is set by the codec and accessible to the application in + * READ ONLY mode. Otherwise its value is undefined. */ + swif_errno_t swif_errno; + + /* pointers to codec specific versions of API functions. */ + swif_status_t (*set_callback_functions) ( + struct swif_decoder*, void (*) (void*, esi_t), + void* (*) (void*, esi_t), + void* (*) (void*, void*, esi_t), void*); + swif_status_t (*set_parameters) ( + struct swif_decoder*, uint32_t, uint32_t, void*); + swif_status_t (*get_parameters) ( + struct swif_decoder*, uint32_t, uint32_t, void*); + swif_status_t (*decode_with_new_source_symbol) ( + struct swif_decoder*, void* const, esi_t); + swif_status_t (*decode_with_new_repair_symbol) ( + struct swif_decoder*, void* const, esi_t); + swif_status_t (*reset_coding_window) (struct swif_decoder*); + swif_status_t (*add_source_symbol_to_coding_window) ( + struct swif_decoder*, esi_t); + swif_status_t (*remove_source_symbol_from_coding_window) ( + struct swif_decoder*, esi_t); + swif_status_t (*set_coding_coefs_tab) ( + struct swif_decoder*, void*, uint32_t); + swif_status_t (*generate_coding_coefs) ( + struct swif_decoder*, uint32_t, uint32_t); +} swif_decoder_t; + + +/** + * Create and initialize a decoder, providing only key parameters. + * + * @param codepoint opaque identifier that fully identifies the FEC + * code to use. + * @param verbosity print information on the codec processing. + * 0 is the minimum verbosity, the maximum verbosity + * level being implementation specific. + * @param symbol_size source and repair symbol size in bytes. Cannot + * change during the codec instance lifetime. + * @param max_coding_window_size + * @param max_linear_system_size + * @return pointer to a swif_decoder_t structure if okay, or + * NULL in case of error. + **/ +swif_decoder_t* swif_decoder_create ( + swif_codepoint_t codepoint, + uint32_t verbosity, + uint32_t symbol_size, + uint32_t max_coding_window_size, + uint32_t max_linear_system_size); + + +/** + * Release a decoder and its associated ressources. + * + * @param dec context (i.e., pointer to decoder structure). + **/ +swif_status_t swif_decoder_release (swif_decoder_t* dec); + + +/** + * Set the various callback functions for this decoder. + * All the callback functions require an opaque context parameter, that + * must be initialized accordingly by the application, since it is + * application specific. + * + * @param dec context (i.e., pointer to decoder structure). + * @param source_symbol_removed_from_linear_system_callback + * (IN) Pointer to the function, within the application, that + * needs to be called each time a source symbol is removed from + * the left side of the linear system. + * This callback is called each time the linear system slides + * to the right and an old source symbol needs to be removed + * on the left. This function does not return anything. + * @param decodable_source_symbol_callback + * (IN) Pointer to the function, within the application, that + * needs to be called each time a source symbol is decodable. + * What it does is application-dependent, but it MUST return + * either a pointer to a data buffer, left uninitialized, of + * the appropriate size, or NULL if the application prefers to + * let the codec allocate the buffer. + * In any case the codec is responsible for storing the actual + * symbol value within the data buffer. Also, no matter + * whether the data buffer is allocated by the application or + * the codec, it is the responsibility of the application to + * free this buffer when needed, once decoding is over (but + * not before since the codec does not keep any internal copy). + * @param decoded_source_symbol_callback + * (IN) Pointer to the function, within the application, that + * needs to be called each time a source symbol is decodable and + * all computations performed (i.e., the buffer does contain the + * symbol value). + * This callback is called in a second time, when the newly + * decodable source symbol is actually decoded and ready, + * i.e., when all the computations (like XOR and GF(2**8) + * operations) have been performed. In any case, it is the + * responsibility of the application to free this buffer when + * needed, once decoding is over (but not before since the + * codec does not keep any internal copy). This function does + * not return anything. + * @param context_4_callback + * (IN) Pointer to the application-specific context that will be + * passed to the callback function (if any). This context is not + * interpreted by this function. + * @return + */ +swif_status_t swif_decoder_set_callback_functions ( + swif_decoder_t* dec, + void (*source_symbol_removed_from_linear_system_callback) ( + void* context, + esi_t old_symbol_esi), + void* (*decodable_source_symbol_callback) ( + void *context, + esi_t esi), + void* (*decoded_source_symbol_callback) ( + void *context, + void *new_symbol_buf, + esi_t esi), + void* context_4_callback); + + +/** + * This function sets one or more FEC codec specific parameters, + * using a type/length/value approach for maximum flexibility. + * + * @param dec context (i.e., pointer to decoder structure). + * @param type (IN) Type of parameter. + * @param length (IN) length of the pointed value. + * @param value (IN) Pointer to the value. The exact type of + * the object pointed is FEC codec specific. + * @return + */ +swif_status_t swif_decoder_set_parameters ( + swif_decoder_t* dec, + uint32_t type, + uint32_t length, + void* value); + + +/** + * This function gets one or more FEC codec specific parameters, + * using a type/length/value approach for maximum flexibility. + * + * @param dec context (i.e., pointer to decoder structure). + * @param type (IN) Type of parameter. + * @param length (IN) length of the pointed value. + * @param value (IN/OUT) Pointer to the value. The exact type of + * the object pointed is FEC codec specific. + * This function updates the value object + * accordingly. The caller, who knows the FEC codec, + * is responsible to allocate the appropriate + * object buffer. + * @return + */ +swif_status_t swif_decoder_get_parameters ( + swif_decoder_t* dec, + uint32_t type, + uint32_t length, + void* value); + + +/** + * List here the FEC codec specific control parameters. + */ +enum { + swif_DECODER_GET_PARAM_DECODER_STATISTICS = 1, + swif_DECODER_SET_PARAM_RLC_DENSITY_THRESHOLD +}; + + +/** + * Submit a received source symbol and try to progress in the decoding. + * For each decoded source symbol (if any), the application is informed + * through the dedicated callback functions. + * + * This function usually returns SWIF_STATUS_OK, regardless of whether + * this new symbol enabled the decoding of one or several source symbols, + * or SWIF_STATUS_ERROR. It cannot return SWIF_STATUS_FAILURE. + * + * @param dec context (i.e., pointer to decoder structure). + * @param new_symbol_buf + * (IN) Pointer to the new source symbol now available (i.e. + * a new symbol received by the application, or a decoded + * symbol in case of a recursive call if it makes sense). + * @param new_symbol_esi + * (IN) encoding symbol ID of the new source symbol. + * @return + */ +swif_status_t swif_decoder_decode_with_new_source_symbol ( + swif_decoder_t* dec, + void* const new_symbol_buf, + esi_t new_symbol_esi); + + +/** + * Submit a received repair symbol and try to progress in the decoding. + * For each decoded source symbol (if any), the application is informed + * through the dedicated callback functions. + * + * This function requires that the application has previously initialized + * the coding window and coding coefficients appropriately. The application + * keeps a full control of the repair symbol buffer, i.e., the application + * is in charge of freeing this buffer as soon as it believes appropriate + * (a copy is kept by the codec). This is motivated by the fact that a + * repair symbol may be part of a larger buffer (e.g., if there are + * several repair symbols per packet, or because of a packet header): only + * the application knows when the buffer can be safely freed. + * + * This function usually returns SWIF_STATUS_OK, regardless of whether + * this new symbol enabled the decoding of one or several source symbols, + * or SWIF_STATUS_ERROR. It cannot return SWIF_STATUS_FAILURE. + * + * @param dec context (i.e., pointer to decoder structure). + * @param new_symbol_buf + * (IN) Pointer to the new repair symbol now available (i.e. + * a new symbol received by the application or a decoded + * symbol in case of a recursive call if it makes sense). + * @return + */ +swif_status_t swif_decoder_decode_with_new_repair_symbol ( + swif_decoder_t* dec, + void* const new_symbol_buf, + esi_t new_src_symbol_esi); + + +/******************************************************************************* + * Coding Window Functions at an Encoder and Decoder + */ + + +/** + * This function resets the current coding window. We assume here that + * this window is maintained by the FEC codec instance. + * Encoder: reset the encoding window for the encoding of future + * repair symbols. + * Decoder: reset the coding window under preparation associated to + * a repair symbol just received. + * + * @return + */ +swif_status_t swif_encoder_reset_coding_window (swif_encoder_t* enc); + +swif_status_t swif_decoder_reset_coding_window (swif_decoder_t* dec); + + +/** + * Add this source symbol to the coding window. + * Encoder: add a source symbol to the coding window. + * Decoder: add a source symbol to the coding window under preparation. + * + * @param new_src_symbol_buf (encoder only) pointer to a buffer + * containing the source symbol. The application MUST NOT + * free nor modify this buffer as long as the source symbol + * is in the coding window. + * @param new_src_symbol_esi ESI of the source symbol to add. + * @return + */ +swif_status_t swif_encoder_add_source_symbol_to_coding_window ( + swif_encoder_t* enc, + void* new_src_symbol_buf, + esi_t new_src_symbol_esi); + +swif_status_t swif_decoder_add_source_symbol_to_coding_window ( + swif_decoder_t* dec, + esi_t new_src_symbol_esi); + + +/** + * Remove this source symbol from the coding window. + * + * Encoder: remove a source symbol from the encoding window, e.g. + * because the application knows that a source symbol has + * been acknowledged by the peer (if applicable). Note that + * the left side of the sliding window is automatically + * managed by the codec and no action is needed from the + * application. If needed a callback is available to inform + * the application that a source symbol has been removed). + * Decoder: remove a source symbol from the coding window under + * preparation. + * + * @param old_src_symbol_esi ESI of the source symbol to remove from + * the coding window. + * @return + */ +swif_status_t swif_encoder_remove_source_symbol_from_coding_window ( + swif_encoder_t* enc, + esi_t old_src_symbol_esi); + +swif_status_t swif_decoder_remove_source_symbol_from_coding_window ( + swif_decoder_t* dec, + esi_t old_src_symbol_esi); + + +/** + * Get information on the current coding window at the encoder. + * This function stores the ESI of the first source symbol and + * last source symbol in the coding window, as well as the number + * of symbols. In theory the application should be able to recover + * the information (it knows when new symbols are added and old + * symbols removed), but it's easier to let the SWiF Codec care + * about it. The number of source symbols is also returned. + * In situations where there's no gap (i.e., when + * swif_encoder_remove_source_symbol_from_coding_window() has not + * been used), nss can also be calculated with first/last. However + * it is more convenient to use nss directly (in particular in case + * of wraping to zero of either first or last). + * + * @param enc + * @param first (in/out) pointer to ESI of the first source + * symbol in the coding window (inclusive) + * @param last (in/out) pointer to ESI of the last source + * symbol in the coding window (inclusive) + * @param nss (in/out) pointer to number of source symbols + * in the coding window + * @return + */ +swif_status_t swif_encoder_get_coding_window_information ( + swif_encoder_t* enc, + esi_t* first, + esi_t* last, + uint32_t* nss); + + +/******************************************************************************* + * Coding Coefficients Functions at an Encoder and Decoder + */ + + +/** + * The following functions enable an encoder (resp. decoder) to + * initialize the set of coefficients to be used for encoding + * or associated to a received repair symbol. + * + * Encoder: calling one of them MUST be done before calling + * build_repair_symbol(). + * Decoder: calling one of them MUST be done before calling + * decode_with_new_repair_symbol(). + */ + +/** + * Encoder: this function specifies the coding coefficients chosen by + * the application if this is the way the codec works. + * Decoder: communicate with this function the coding coefficients + * associated to a repair symbol and carried in the packet + * header. + * + * @param coding_coefs_tab + * (IN) table of coding coefficients associated to each of + * the source symbols currently in the encoding window. + * The size (number of bits) of each coefficient depends on + * the FEC Scheme. The allocation and release of this table + * is under the responsibility of the application. + * @param nb_coefs_in_tab + * (IN) number of entries (i.e., coefficients) in the table. + * @return + */ +swif_status_t swif_encoder_set_coding_coefs_tab ( + swif_encoder_t* enc, + void* coding_coefs_tab, + uint32_t nb_coefs_in_tab); + +swif_status_t swif_decoder_set_coding_coefs_tab ( + swif_decoder_t* dec, + void* coding_coefs_tab, + uint32_t nb_coefs_in_tab); + + +/** + * The coding coefficients may be generated in a deterministic manner, + * for instance by a PRNG known by the codec and a seed (perhaps with + * other parameters) provided by the application. + * The codec may also choose in an autonomous manner these coefficients. + * This function is used to trigger this process. + * When the choice is made in an autonomous manner, the actual coding + * coefficient or key used by the codec can be retrieved with + * swif_encoder_get_coding_coefs_tab(). + * + * @param key (IN) Value that can be used as a seed in case of a PRNG + * for instance, or by a specific coding coefficients + * function. Set to 0 if not required by a codec. + * @param add_param + * (IN) an opaque 32-bit integer that contains a codec + * specific parameter if needed. Set to 0 if not used. + * @return + */ +swif_status_t swif_encoder_generate_coding_coefs ( + swif_encoder_t* enc, + uint32_t key, + uint32_t add_param); + +swif_status_t swif_decoder_generate_coding_coefs ( + swif_decoder_t* dec, + uint32_t key, + uint32_t add_param); + + +/** + * This function enables the application to retrieve the set of coding + * coefficients generated and used by build_repair_symbol(). This is + * useful when the choice of coefficients is performed by the codec in + * an autonomous manner but needs to be sent in the repair packet header. + * This function is only used by an encoder. + * + * @param coding_coefs_tab + * (OUT) pointer to a table of coding coefficients. + * The size (number of bits) of each coefficient depends on + * the FEC scheme. Upon return of this function, this table + * is allocated and filled with coefficient values. The + * release of this table is under the responsibility of the + * application. + * @param nb_coefs_in_tab + * (IN/OUT) pointer to the number of entries (i.e., + * coefficients) in the table. + * Upon calling this function, this number must be zero. + * Upon return of this function this variable is initialized + * with the actual number of entries in the coeffs_tab[]. + * @return + */ +swif_status_t swif_encoder_get_coding_coefs_tab ( + swif_encoder_t* enc, + void** coding_coefs_tab, + uint32_t* nb_coefs_in_tab); + +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __SWIF_API_H__ */ diff --git a/tools/precoder/vendor/swif-codec/src/swif_coding_coefficients.c b/tools/precoder/vendor/swif-codec/src/swif_coding_coefficients.c new file mode 100644 index 0000000..40ab5cd --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_coding_coefficients.c @@ -0,0 +1,93 @@ +/** + * SWiF Codec: an open-source sliding window FEC codec in C + * https://github.com/irtf-nwcrg/swif-codec + */ + +#include "swif_includes.h" + + +/** + * Coding coefficients generator coming from RLC FEC Scheme Internet-Draft: + * https://datatracker.ietf.org/doc/draft-ietf-tsvwg-rlc-fec-scheme/ + */ + +/* + * Fills in the table of coding coefficients (of the right size) + * provided with the appropriate number of coding coefficients to + * use for the repair symbol key provided. + * + * (in) repair_key key associated to this repair symbol. This + * parameter is ignored (useless) if m=1 and dt=15 + * (in/out) cc_tab[] pointer to a table of the right size to store + * coding coefficients. All coefficients are + * stored as bytes, regardless of the m parameter, + * upon return of this function. + * (in) cc_nb number of entries in the table. This value is + * equal to the current encoding window size. + * (in) dt integer between 0 and 15 (inclusive) that + * controls the density. With value 15, all + * coefficients are guaranteed to be non zero + * (i.e. equal to 1 with GF(2) and equal to a + * value in {1,... 255} with GF(2^^8)), otherwise + * a fraction of them will be 0. + * (in) m Finite Field GF(2^^m) parameter. In this + * document only values 1 and 8 are considered. + * (out) returns 0 in case of success, an error code + * different than 0 otherwise. + */ +int swif_rlc_generate_coding_coefficients (uint16_t repair_key, + uint8_t cc_tab[], + uint16_t cc_nb, + uint8_t dt, + uint8_t m) +{ + uint32_t i; + tinymt32_t s; /* PRNG internal state */ + + if (dt > 15) { + return -1; /* error, bad dt parameter */ + } + switch (m) { + case 1: + if (dt == 15) { + /* all coefficients are 1 */ + memset(cc_tab, 1, cc_nb); + } else { + /* here coefficients are either 0 or 1 */ + tinymt32_init(&s, repair_key); + for (i = 0 ; i < cc_nb ; i++) { + cc_tab[i] = (tinymt32_rand16(&s) <= dt) ? 1 : 0; + } + } + break; + + case 8: + tinymt32_init(&s, repair_key); + if (dt == 15) { + /* coefficient 0 is avoided here in order to include + * all the source symbols */ + for (i = 0 ; i < cc_nb ; i++) { + do { + cc_tab[i] = (uint8_t) tinymt32_rand256(&s); + } while (cc_tab[i] == 0); + } + } else { + /* here a certain number of coefficients should be 0 */ + for (i = 0 ; i < cc_nb ; i++) { + if (tinymt32_rand16(&s) <= dt) { + do { + cc_tab[i] = (uint8_t) tinymt32_rand256(&s); + } while (cc_tab[i] == 0); + } else { + cc_tab[i] = 0; + } + } + } + break; + + default: + return -2; /* error, bad parameter m */ + } + return 0; /* success */ +} + diff --git a/tools/precoder/vendor/swif-codec/src/swif_coding_coefficients.h b/tools/precoder/vendor/swif-codec/src/swif_coding_coefficients.h new file mode 100644 index 0000000..695208c --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_coding_coefficients.h @@ -0,0 +1,41 @@ +/** + * SWiF Codec: an open-source sliding window FEC codec in C + * https://github.com/irtf-nwcrg/swif-codec + */ + + +/** + * Coding coefficients generator coming from RLC FEC Scheme Internet-Draft: + * https://datatracker.ietf.org/doc/draft-ietf-tsvwg-rlc-fec-scheme/ + */ + +/* + * Fills in the table of coding coefficients (of the right size) + * provided with the appropriate number of coding coefficients to + * use for the repair symbol key provided. + * + * (in) repair_key key associated to this repair symbol. This + * parameter is ignored (useless) if m=1 and dt=15 + * (in/out) cc_tab[] pointer to a table of the right size to store + * coding coefficients. All coefficients are + * stored as bytes, regardless of the m parameter, + * upon return of this function. + * (in) cc_nb number of entries in the table. This value is + * equal to the current encoding window size. + * (in) dt integer between 0 and 15 (inclusive) that + * controls the density. With value 15, all + * coefficients are guaranteed to be non zero + * (i.e. equal to 1 with GF(2) and equal to a + * value in {1,... 255} with GF(2^^8)), otherwise + * a fraction of them will be 0. + * (in) m Finite Field GF(2^^m) parameter. In this + * document only values 1 and 8 are considered. + * (out) returns 0 in case of success, an error code + * different than 0 otherwise. + */ +int swif_rlc_generate_coding_coefficients (uint16_t repair_key, + uint8_t cc_tab[], + uint16_t cc_nb, + uint8_t dt, + uint8_t m); + diff --git a/tools/precoder/vendor/swif-codec/src/swif_full_symbol.c b/tools/precoder/vendor/swif-codec/src/swif_full_symbol.c new file mode 100644 index 0000000..b2a72fb --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_full_symbol.c @@ -0,0 +1,11 @@ +#ifdef WITH_LIBLC + +/* A temporary adapter based on liblc - no longer used */ +#include "swif_full_symbol_lc.c" + +#else /* WITH_LIBLC */ + +/* A new implementation based on swif_symbol */ +#include "swif_full_symbol_impl.c" + +#endif /* WITH_LIBLC */ diff --git a/tools/precoder/vendor/swif-codec/src/swif_full_symbol.h b/tools/precoder/vendor/swif-codec/src/swif_full_symbol.h new file mode 100644 index 0000000..841144b --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_full_symbol.h @@ -0,0 +1,183 @@ +/** + * @defgroup SWiF-Codec + * @ingroup swif-codec-linear + * @brief an open-source sliding window FEC codec in C (linear operations) + * @{ + * + * @file + * @brief A "full symbol" is a symbol with a full specification of + * what it represents, e.g. an encoding header. + * + * @author Oumaima Attia + */ + +/** + * SWiF Codec: + * https://github.com/irtf-nwcrg/swif-codec + */ + +#ifndef __SWIF_FULL_SYMBOL_H__ +#define __SWIF_FULL_SYMBOL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* There were initially two designed implementations of the full_symbol + * - one reimplemented in swif_full_symbol_impl.c (DEFAULT ONE) + * - one as wrapper on top of liblc (NO LONGER USED, fixed size, no malloc) + */ + +/*---------------------------------------------------------------------------*/ + +/** + * A symbol (e.g. a packet, coded of not, seen as an array of GF(xx) coefs. + */ +typedef struct s_swif_full_symbol_t swif_full_symbol_t; + +/** + * A set of symbols. You can add symbols, remove symbols, etc. + */ +typedef struct s_swif_full_symbol_set_t swif_full_symbol_set_t; + +/** + * Used for a non-specified/non-existing value of symbol_id + */ +#define SYMBOL_ID_NONE 0xfffffffful + +/** + * An identifier for a source symbol (source symbol index) + */ +typedef uint32_t symbol_id_t; + +/** + * @brief Create a full_symbol from a source symbol + */ +swif_full_symbol_t *full_symbol_create_from_source +(uint32_t symbol_id, uint8_t *symbol_data, uint32_t symbol_size); + +/** + * @brief Create a full_symbol from a set of coeffiicents and a symbol + * typically this is provided from a received repair packet + */ +swif_full_symbol_t *full_symbol_create +(uint8_t *symbol_coef_table, uint32_t min_symbol_id, uint32_t nb_symbol_id, + uint8_t *symbol_data, uint32_t symbol_size); + +/** + * @brief Get the size of the data + */ +uint32_t full_symbol_get_size(swif_full_symbol_t *full_symbol); + +/** + * @brief Get the minimum source index that appears in the symbol + * returns SYMBOL_ID_NONE if there is none (e.g. symbol is 0) + */ +uint32_t full_symbol_get_min_symbol_id(swif_full_symbol_t *full_symbol); + +/** + * @brief Get the maximum source index that appears in the symbol + * returns SYMBOL_ID_NONE if there is none (e.g. symbol is 0) + */ +uint32_t full_symbol_get_max_symbol_id(swif_full_symbol_t *full_symbol); + +/** + * @brief Get the symbol 'data'. result_data should be a pointer to a + * a block of memory of size at least full_symbol_get_size(full_symbol) + */ +void full_symbol_get_data +(swif_full_symbol_t *full_symbol, uint8_t *result_data); + + +/** + * @brief Get the coefficient corresponding to the specified symbol identifier + */ +uint8_t full_symbol_get_coef +(swif_full_symbol_t *full_symbol, uint32_t symbol_id); + +/** + * @brief Return the number of coefficients present in the symbol + * (max symbol id - min symbol id)+1; + * Note: returns zero if there are none (e.g. symbol is zero) + */ +static inline uint32_t full_symbol_count_coef(swif_full_symbol_t *full_symbol) +{ + uint32_t min_symbol_id = full_symbol_get_min_symbol_id(full_symbol); + uint32_t max_symbol_id = full_symbol_get_max_symbol_id(full_symbol); + + if (min_symbol_id == SYMBOL_ID_NONE) { + return 0; + } else { + return max_symbol_id-min_symbol_id+1; + } +} + +/** + * @brief Returns whether the symbol is an empty symbol + */ +static inline bool full_symbol_is_zero(swif_full_symbol_t *full_symbol) +{ + return full_symbol_get_min_symbol_id(full_symbol) == SYMBOL_ID_NONE; +} + +/** + * @brief Returns whether the symbol is an empty symbol + */ +static inline bool full_symbol_has_one_id(swif_full_symbol_t *full_symbol) +{ + return (!full_symbol_is_zero(full_symbol)) + && (full_symbol_get_min_symbol_id(full_symbol) + == full_symbol_get_max_symbol_id(full_symbol)); +} + + +/** + * @brief Release a full_symbol + */ +void full_symbol_free(swif_full_symbol_t *swif_full_symbol); + +/** + * @brief Create a new (unlinked) copy of a full_symbol + */ +swif_full_symbol_t *full_symbol_clone(swif_full_symbol_t *swif_full_symbol); + +/** + * @brief Dump a full symbol on a FILE + */ +void full_symbol_dump(swif_full_symbol_t *full_symbol, FILE *out); + +/*---------------------------------------------------------------------------*/ + +/** + * @brief Create a full_symbol set, that will be used to do gaussian elimination + */ +swif_full_symbol_set_t *full_symbol_set_alloc(void); + +/** + * @brief Free a full_symbol set + */ +void full_symbol_set_free(swif_full_symbol_set_t *set); + + +/** + * @brief Add a full_symbol to a packet set. + * + * Gaussian elimination can occur. + * Teturn the pivot associated to the new full_symbol + * or SYMBOL_ID_NONE if dependent (e.g. redundant) packet + */ +uint32_t full_symbol_set_add +(swif_full_symbol_set_t *set, swif_full_symbol_t *full_symbol); + +static inline bool full_symbol_includes_id(swif_full_symbol_t* symbol, + symbol_id_t id); + +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __SWIF_FULL_SYMBOL_H__ */ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/tools/precoder/vendor/swif-codec/src/swif_full_symbol_impl.c b/tools/precoder/vendor/swif-codec/src/swif_full_symbol_impl.c new file mode 100644 index 0000000..78feacc --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_full_symbol_impl.c @@ -0,0 +1,810 @@ +/** + * @brief A library implementing network coding + * @author Oumaima Attia + * + * A "full symbol" is a linear combination of sources symbol along with the + * encoding header specifying this linear combination. + */ + +//#include "swif_full_symbol_impl.h" +#include "swif_includes.h" + +/*---------------------------------------------------------------------------*/ + +/** + * @brief Create a swif_full_symbol set: + * A swif_full_symbol_set is a data structure that contains "full symbols", e.g. + * coded symbols with the encoding header. + * It is used to do automatically Gaussian elimination when a coded packet is added + */ + +const uint32_t FULL_SYMBOL_SET_INITIAL_SIZE = 16; + +swif_full_symbol_set_t *full_symbol_set_alloc() +{ + /* allocate the struct */ + swif_full_symbol_set_t *result + = (swif_full_symbol_set_t *)calloc(1, sizeof(swif_full_symbol_set_t)); + + if (result == NULL) { + return NULL; + } + + /* allocate the table of pointers to full_symbol */ + result->size = FULL_SYMBOL_SET_INITIAL_SIZE; + result->nmbr_packets = 0; + + swif_full_symbol_t **full_symbol_tab + = calloc(result->size, sizeof(swif_full_symbol_t *)); + if (full_symbol_tab == NULL) { + free(full_symbol_tab); + return NULL; + } + result->full_symbol_tab = full_symbol_tab; + result->first_symbol_id = SYMBOL_ID_NONE ; + result->notify_decoded_func = NULL; + result->notify_context = NULL; + return result; +} + +/** + * @brief Free a full_symbol set + */ +void full_symbol_set_free(swif_full_symbol_set_t *set) +{ + assert(set != NULL); + assert(set->full_symbol_tab != NULL); + for(uint32_t i = 0; i < set->size; i++) { + if (set->full_symbol_tab[i] != NULL) + full_symbol_free(set->full_symbol_tab[i]); + } + free(set->full_symbol_tab); + set->full_symbol_tab = NULL; + free(set); +} + +/** + * @brief Dump a full symbol set (python/json-like representation) + */ +void full_symbol_set_dump(swif_full_symbol_set_t *full_symbol_set, FILE *out) +{ + fprintf(out, "{'size':%u, ", full_symbol_set->size); + fprintf(out, "'first_symbol_id':%u, ", full_symbol_set->first_symbol_id); + fprintf(out, "'set':{"); + bool is_first = true; + for (uint32_t i = 0; i < full_symbol_set->size; i++) { + swif_full_symbol_t *fs = full_symbol_set->full_symbol_tab[i]; + if (fs != NULL) { + if (!is_first) { + fprintf(out, ","); + } else { + is_first = false; + } + fprintf(out, "%u:(%u, ", i, + fs->first_nonzero_id-full_symbol_set->first_symbol_id); + full_symbol_dump(fs, out); + fprintf(out, ")"); + } + } + fprintf(out, "}"); + fprintf(out, "}\n"); +} + + +/** + * @brief Add a full_symbol to a packet set. + * + * Gaussian elimination can occur. + * Return the pivot [remove_each_pivot associated to the new full_symbol] + * or SYMBOL_ID_NONE if dependent (e.g. redundant) packet + * + * The full_symbol is not freed and also reference is not captured. + */ + +uint32_t full_symbol_set_add +(swif_full_symbol_set_t *set, swif_full_symbol_t *full_symbol) +{ + assert(set != NULL); + if (full_symbol_is_zero(full_symbol)) { + return ENTRY_INDEX_NONE; + } + + /* the added symbol is not modified: we first clone it */ + swif_full_symbol_t *full_symbol_cloned = full_symbol_clone(full_symbol); + if (full_symbol_cloned == NULL) { + WARNING_PRINT("cannot allocate memory for full_symbol cloning"); + return ENTRY_INDEX_NONE; + } + if (set->first_symbol_id == SYMBOL_ID_NONE) { + set->first_symbol_id = full_symbol_cloned->first_nonzero_id; + } + + uint32_t old_size = set->size; + symbol_id_t new_i0 = full_symbol_cloned->first_nonzero_id; + symbol_id_t set_i0 = set->first_symbol_id; + + /* The added symbol has first nonzero index outside the current set */ + if (new_i0 < set_i0) { + DEBUG_PRINT("Debugging is enabled. Case: full_symbol_cloned->first_nonzero_id < set->first_symbol_id \n"); + if (set_i0 - new_i0 < set->size) { + memmove(set->full_symbol_tab+(set_i0-new_i0), set->full_symbol_tab, + sizeof(swif_full_symbol_t *) * (set->size-(set_i0-new_i0))); + memset(set->full_symbol_tab, 0, + sizeof(swif_full_symbol_t *)*(set_i0-new_i0)); + } else { + if (set_i0 - new_i0 < (set->size * 2)) { + set->size *= 2; + } else { + set->size = set_i0-new_i0 +1; + } + set->full_symbol_tab = realloc(set->full_symbol_tab, set->size * sizeof(swif_full_symbol_t *)); + memmove(set->full_symbol_tab + (set_i0-new_i0), set->full_symbol_tab, sizeof(swif_full_symbol_t*) * old_size); + memset(set->full_symbol_tab, 0, + sizeof(swif_full_symbol_t *)*(set_i0-new_i0)); + } + IF_DEBUG(full_symbol_set_dump(set, stdout)); + if (set->full_symbol_tab == NULL) { + WARNING_PRINT("failed to reallocate full_symbol_tab"); + full_symbol_free(full_symbol_cloned); + free(set->full_symbol_tab); + return ENTRY_INDEX_NONE; + } + set->full_symbol_tab[0] = full_symbol_cloned; + set->nmbr_packets++; + set->first_symbol_id = MIN(set_i0, new_i0); /* actually should be new_i0 */ + set_i0 = set->first_symbol_id; + return new_i0 - set_i0; /* should be 0 */ + } + + DEBUG_PRINT("Debugging is enabled. Case: full_symbol_cloned->first_nonzero_id > set->first_symbol_id \n"); + uint32_t idx_pos = new_i0 - set_i0; + if (idx_pos < set->size) { + if (set->full_symbol_tab[idx_pos] != NULL) { + WARNING_PRINT("overwriting one full_symbol in set\n"); + full_symbol_free(set->full_symbol_tab[idx_pos]); + } + set->full_symbol_tab[idx_pos] = full_symbol_cloned; + set->nmbr_packets++; + return idx_pos; + } else if (idx_pos < (set->size *2)) { + set->size *= 2; + } else { /* new_i0-set_i0 >= set->size*2 */ + set->size = idx_pos +1; /* hence: new set->size >= old_size *2 + 1 */ + } + assert(idx_pos < set->size); + + /* reallocate memory for the table of pointers in full_symbol */ + set->full_symbol_tab = realloc( + set->full_symbol_tab, set->size * sizeof(swif_full_symbol_t *)); + memset(set->full_symbol_tab+old_size, 0, sizeof(swif_full_symbol_t*)*(set->size-old_size)); + + if (set->full_symbol_tab == NULL) { + WARNING_PRINT("failed to reallocate full_symbol_tab"); + full_symbol_free(full_symbol_cloned); + free(set->full_symbol_tab); + return ENTRY_INDEX_NONE; + } + + set->full_symbol_tab[idx_pos] = full_symbol_cloned; + set->nmbr_packets++; + return idx_pos; +} + +/*---------------------------------------------------------------------------*/ +swif_full_symbol_t *full_symbol_set_get_pivot +(swif_full_symbol_set_t *set, symbol_id_t symbol_id) +{ + IF_DEBUG(full_symbol_set_dump(set, stdout)); + if (symbol_id >= set->first_symbol_id + && symbol_id < (set->size + set->first_symbol_id) + && set->full_symbol_tab[symbol_id-set->first_symbol_id] ){ + DEBUG_PRINT("Coef of pivot is equal to : %u \n", + full_symbol_get_coef(set->full_symbol_tab[symbol_id-set->first_symbol_id], symbol_id)); + return set->full_symbol_tab[symbol_id-set->first_symbol_id]; + } + DEBUG_PRINT("Pivot of symbol id %u is not found \n", symbol_id); + return NULL; +} + +/*---------------------------------------------------------------------------*/ +swif_full_symbol_t *full_symbol_set_remove_each_pivot +(swif_full_symbol_set_t *full_symbol_set, swif_full_symbol_t *new_symbol1) +{ + /* only copies of symbol are stored, so first clone it */ + swif_full_symbol_t *new_symbol = full_symbol_clone(new_symbol1); + /* is_zero variable is used to check if all the symbol coefs are zero */ + bool is_zero = true; + full_symbol_adjust_min_max_coef(new_symbol); + if (new_symbol->first_nonzero_id == SYMBOL_ID_NONE) + { + full_symbol_free(new_symbol); + return NULL; + } + for (uint32_t i = new_symbol->first_nonzero_id ; i <= new_symbol->last_nonzero_id; i++) { + uint8_t coef = full_symbol_get_coef(new_symbol, i); + if (coef != 0) { + swif_full_symbol_t *symbol_pivot = full_symbol_set_get_pivot(full_symbol_set, i); + if (symbol_pivot != NULL) { + swif_full_symbol_t *symbol1 = symbol_pivot; + /* the symbol is not modified: we first clone it */ + swif_full_symbol_t *symbol1_cloned = full_symbol_clone(symbol1); + /* symbol1_cloned is multiplied by the associated coef */ + full_symbol_scale(symbol1_cloned, coef); + swif_full_symbol_t *symbol2 = full_symbol_add(new_symbol, symbol1_cloned); + /* After the addition, symbol2 may be null, in this case w eliminate it */ + if (!full_symbol_is_zero(symbol2)) { + full_symbol_free(new_symbol); + new_symbol = symbol2; + } + else + { + full_symbol_free(symbol2); + } + full_symbol_free(symbol1_cloned); + } else { + is_zero = false; + } + } + } + if (is_zero) { + full_symbol_free(new_symbol); + return NULL; + } + return new_symbol; +} + +/*---------------------------------------------------------------------------*/ + +/* callback should not add new symbols to full_symbol_set */ +void full_symbol_set_notify_decoded +(swif_full_symbol_set_t *set, symbol_id_t decoded_id) +{ + if (set->notify_decoded_func != NULL) { + set->notify_decoded_func(set, decoded_id, set->notify_context); + } +} + +/*---------------------------------------------------------------------------*/ + +uint32_t full_symbol_set_add_as_pivot +(swif_full_symbol_set_t *full_symbol_set, swif_full_symbol_t *new_symbol) +{ + full_symbol_adjust_min_max_coef(new_symbol); + if (new_symbol->first_nonzero_id == SYMBOL_ID_NONE) { + return ENTRY_INDEX_NONE; + } + full_symbol_scale(new_symbol, gf256_inv(full_symbol_get_coef(new_symbol, new_symbol->first_nonzero_id))); + symbol_id_t first_index = new_symbol->first_nonzero_id; + + for(uint32_t i = 0 ; i < full_symbol_set->size; i++) { + if (full_symbol_set->full_symbol_tab[i]) { + swif_full_symbol_t *symbol_cloned = full_symbol_clone(new_symbol); + uint8_t coef = full_symbol_get_coef(full_symbol_set->full_symbol_tab[i], first_index); /* XXX: if coef == 0, nothing to do */ + full_symbol_scale(symbol_cloned, coef); + swif_full_symbol_t * symbol2 = full_symbol_add(full_symbol_set->full_symbol_tab[i], symbol_cloned); + bool is_decoded = !full_symbol_has_one_id(full_symbol_set->full_symbol_tab[i]) && full_symbol_has_one_id(symbol2); + full_symbol_free(full_symbol_set->full_symbol_tab[i]); + full_symbol_set->full_symbol_tab[i] = symbol2; + full_symbol_free(symbol_cloned); + if (is_decoded) { + symbol_id_t si = full_symbol_get_min_symbol_id(symbol2); + assert(full_symbol_get_coef(symbol2, si) == 1); + full_symbol_set_notify_decoded(full_symbol_set, si); + } + } + } + IF_DEBUG(full_symbol_dump(new_symbol, stdout)); + return full_symbol_set_add(full_symbol_set, new_symbol); +} + + +/*---------------------------------------------------------------------------*/ +void full_symbol_add_with_elimination(swif_full_symbol_set_t *full_symbol_set, + swif_full_symbol_t *new_symbol) +{ + swif_full_symbol_t *fss_remove_pivot + = full_symbol_set_remove_each_pivot(full_symbol_set, new_symbol); + if (fss_remove_pivot) { + uint32_t idx = full_symbol_set_add_as_pivot( + full_symbol_set, fss_remove_pivot); + full_symbol_free(fss_remove_pivot); + if (idx == ENTRY_INDEX_NONE) + { + return; + } + swif_full_symbol_t* stored_symbol + = full_symbol_set->full_symbol_tab[idx]; + bool is_decoded = (!full_symbol_has_one_id(new_symbol)) + && full_symbol_has_one_id(stored_symbol); + if (is_decoded) { + symbol_id_t si = full_symbol_get_min_symbol_id(stored_symbol); + assert(full_symbol_get_coef(stored_symbol, si) == 1); + full_symbol_set_notify_decoded(full_symbol_set, si); + } + } +} +/*---------------------------------------------------------------------------*/ +/** + * @brief Create a full_symbol from a raw packet (a set of bytes) + * and initialize it with content '0' + */ +swif_full_symbol_t *full_symbol_alloc +(symbol_id_t first_symbol_id, symbol_id_t last_symbol_id, uint32_t symbol_size) +{ + symbol_id_t symbol_id_size; + if (first_symbol_id == SYMBOL_ID_NONE) { + assert(last_symbol_id == SYMBOL_ID_NONE); + symbol_id_size = 1; /* Actually 0, but we never want a NULL pointer, + and malloc(0) might be NULL or not */ + } else { + assert(first_symbol_id <= last_symbol_id); + symbol_id_size = last_symbol_id-first_symbol_id+1; + } + + /* allocate result */ + swif_full_symbol_t *result + = (swif_full_symbol_t *)calloc(1, sizeof(swif_full_symbol_t)); + if (result == NULL) { + free(result); + return NULL; + } + /* allocate coef and data */ + uint8_t *coef = (uint8_t *)calloc(symbol_id_size, sizeof(uint8_t)); + if (coef == NULL) { + /* free the structure in case of problem */ + free(result); + return NULL; + } + result->coef = coef; + + uint32_t safe_symbol_size = symbol_size; + if (safe_symbol_size == 0) { + safe_symbol_size = 1; /* because calloc(0,...) can return NULL */ + } + uint8_t *data = (uint8_t *)calloc(safe_symbol_size, sizeof(uint8_t)); + if (data == NULL) { + /* free the structure in case of problem */ + free(result->coef); + free(result); + return NULL; + } + + /* fill content */ + result->data = data ; + result->first_id = first_symbol_id; + result->last_id = last_symbol_id; + result->data_size = symbol_size; + full_symbol_adjust_min_max_coef(result); + + return result; +} + + +/** + * @brief get the coefficient corresponding to the specified symbol identifier + */ +uint8_t full_symbol_get_coef +(swif_full_symbol_t *full_symbol, uint32_t symbol_id) +{ + if (full_symbol_includes_id(full_symbol, symbol_id)) { + return full_symbol->coef[symbol_id-full_symbol->first_id]; + } + return 0; +} + + +symbol_id_t full_symbol_get_coef_index +(swif_full_symbol_t *full_symbol, uint32_t symbol_id) +{ + assert(full_symbol_includes_id(full_symbol, symbol_id)); + return symbol_id-full_symbol->first_id; +} + +/** + * @brief Create a full_symbol from a raw packet (a set of bytes) + * and initialize it with content '0' + */ +swif_full_symbol_t *full_symbol_create_from_source +(uint32_t symbol_id, uint8_t *symbol_data, uint32_t symbol_size) +{ + swif_full_symbol_t *full_symbol = full_symbol_alloc(symbol_id, symbol_id, symbol_size); + symbol_id_t coef_index = full_symbol_get_coef_index(full_symbol, symbol_id); + full_symbol->coef[coef_index] = 1; + full_symbol_adjust_min_max_coef(full_symbol); + memcpy(full_symbol->data, symbol_data, symbol_size); + full_symbol->data_size = symbol_size; + return full_symbol; +} + +swif_full_symbol_t *full_symbol_create +(uint8_t* symbol_coef_table, uint32_t min_symbol_id, uint32_t nb_symbol_id, + uint8_t* symbol_data, uint32_t symbol_size) +{ + swif_full_symbol_t *full_symbol = full_symbol_alloc(min_symbol_id, + min_symbol_id+nb_symbol_id-1, symbol_size); + /* copy the coefs */ + memcpy(full_symbol->coef, symbol_coef_table, nb_symbol_id * sizeof(uint8_t)); + full_symbol->first_id = min_symbol_id; + full_symbol->last_id = min_symbol_id + nb_symbol_id - 1; + full_symbol_adjust_min_max_coef(full_symbol); + /* copy the data */ + memcpy(full_symbol->data, symbol_data, symbol_size); + full_symbol->data_size = symbol_size; + return full_symbol; +} + +/** + * @brief Release a full_symbol + */ +void full_symbol_free(swif_full_symbol_t* full_symbol) +{ + //DEBUG_PRINT("free: %08x\n", (unsigned int)full_symbol); + assert(full_symbol != NULL); + assert(full_symbol->coef != NULL); + free(full_symbol->coef); + full_symbol->coef = NULL; + assert(full_symbol->data != NULL); + free(full_symbol->data); + full_symbol->data = NULL; + free(full_symbol); +} + +/** + * @brief Create a new (unlinked) copy of a full_symbol + * (can return NULL if memory allocation fails) + */ +swif_full_symbol_t *full_symbol_clone(swif_full_symbol_t* full_symbol) +{ + swif_full_symbol_t *result = full_symbol_alloc(full_symbol->first_id, + full_symbol->last_id, full_symbol->data_size); + if (result == NULL) { + return NULL; + } + + result->first_id = full_symbol->first_id; + result->last_id = full_symbol->last_id; + result->first_nonzero_id = full_symbol->first_nonzero_id; + result->last_nonzero_id = full_symbol->last_nonzero_id; + result->data_size = full_symbol->data_size; + + if (!full_symbol_is_zero(full_symbol)) { + memcpy(result->coef, full_symbol->coef, (full_symbol->last_id - full_symbol->first_id +1 ) * sizeof(uint8_t)); + memcpy(result->data, full_symbol->data, full_symbol->data_size * sizeof(uint8_t)); + } + return result; +} + +/** + * @brief get the size of the data + */ +uint32_t full_symbol_get_size(swif_full_symbol_t *full_symbol) +{ + return full_symbol->data_size; +} + + +static inline bool full_symbol_has_sufficient_size +(swif_full_symbol_t* symbol, symbol_id_t id1, symbol_id_t id2) +{ + assert(id1 <= id2); + symbol_id_t symbol_id_size = full_symbol_count_coef(symbol); + symbol_id_t requested_size = id2 - id1 + 1; + return (symbol_id_size >= requested_size); +} + +static inline bool full_symbol_includes_id(swif_full_symbol_t* symbol, + symbol_id_t symbol_id) +{ + return (symbol_id >= symbol->first_id && symbol_id <= symbol->last_id ); +} + +/** + * update full symbol min coef + */ +static bool full_symbol_adjust_min_coef(swif_full_symbol_t* symbol) +{ + assert( symbol->first_id != SYMBOL_ID_NONE + && symbol->last_id != SYMBOL_ID_NONE ); + + bool result = false; + symbol->first_nonzero_id = SYMBOL_ID_NONE; + + for (symbol_id_t i = symbol->first_id; i <= symbol->last_id; i++) { + if (full_symbol_get_coef(symbol, i) != 0){ + symbol->first_nonzero_id = i; + result = true; + break; + } + } + return result; +} + +static inline uint32_t full_symbol_count_allocated_coef(swif_full_symbol_t *full_symbol) +{ + if (full_symbol->first_nonzero_id == SYMBOL_ID_NONE) { + assert(full_symbol->last_nonzero_id == SYMBOL_ID_NONE); + return 0; + } else { + assert(full_symbol->first_id <= full_symbol->last_id); + return full_symbol->last_id-full_symbol->first_id+1; + } +} + +/** + * update full symbol max coef + */ +static bool full_symbol_adjust_max_coef(swif_full_symbol_t* symbol) +{ + assert( symbol->first_id != SYMBOL_ID_NONE + && symbol->last_id != SYMBOL_ID_NONE ); + + bool result = false; + symbol->last_nonzero_id = SYMBOL_ID_NONE; + + for (symbol_id_t j = 0; j < full_symbol_count_allocated_coef(symbol); j++) { + symbol_id_t i = symbol->last_id - j; + if (full_symbol_get_coef(symbol, i) != 0){ + symbol->last_nonzero_id = i; + result = true; + break; + } + } + return result; +} + +/** + *update full symbol min and max coefs + * returns whether there exists non-zero coefs + */ + +bool full_symbol_adjust_min_max_coef(swif_full_symbol_t* symbol) +{ + if (symbol->first_id == SYMBOL_ID_NONE) { + assert( symbol->last_id == SYMBOL_ID_NONE ); + symbol->first_nonzero_id = SYMBOL_ID_NONE; + symbol->last_nonzero_id = SYMBOL_ID_NONE; + return false; + } + bool result1 = full_symbol_adjust_min_coef(symbol); + bool result2 = full_symbol_adjust_max_coef(symbol); + assert(result1 == result2); + return result1; +} + +/** + * @brief get the minimum source index that appears in the symbol + * SYMBOL_ID_NONE if there is none (e.g. symbol is 0) + */ +uint32_t full_symbol_get_min_symbol_id(swif_full_symbol_t *full_symbol) +{ + return full_symbol->first_nonzero_id; +} + +/** + * @brief get the maximum source index that appears in the symbol + * returns SYMBOL_ID_NONE if there is none (e.g. symbol is 0) + */ +uint32_t full_symbol_get_max_symbol_id(swif_full_symbol_t *full_symbol) +{ + return full_symbol->last_nonzero_id; +} + + +/** + * @brief get the symbol 'data'. result_data should be a pointer to a + * a block of memory of full_symbol_get_size(full_symbol) + */ +void full_symbol_get_data(swif_full_symbol_t *full_symbol, uint8_t *result_data) +{ + assert( result_data != NULL); + memcpy(result_data, full_symbol->data, full_symbol->data_size * sizeof(uint8_t)); +} + +void full_symbol_dump_id(symbol_id_t symbol_id, FILE *out) +{ + if (symbol_id == SYMBOL_ID_NONE) { + fprintf(out, "null"); + } else { + fprintf(out, "%u", symbol_id); + } +} + +void full_symbol_dump(swif_full_symbol_t *full_symbol, FILE *out) +{ + fprintf(out, "{'size':%u, 'internal':", full_symbol->data_size); + fprintf(out, "{ 'type':'full_symbol'"); + fprintf(out, ", 'nb_coef':%u", full_symbol_count_allocated_coef(full_symbol)); + fprintf(out, ", 'data_size': %u", full_symbol->data_size); + + fprintf(out, ", 'first_id':"); + full_symbol_dump_id(full_symbol->first_id, out); + fprintf(out, ", 'last_id':"); + full_symbol_dump_id(full_symbol->last_id, out); + fprintf(out, ", 'first_nonzero_id':"); + full_symbol_dump_id(full_symbol->first_nonzero_id, out); + fprintf(out, ", 'last_nonzero_id':"); + full_symbol_dump_id(full_symbol->last_nonzero_id, out); + + fprintf(out, ", 'coef_value':["); + uint32_t i; + if (full_symbol->first_id != SYMBOL_ID_NONE) { + for (i = full_symbol->first_id; i <= full_symbol->last_id; i++) { + if (i > full_symbol->first_id) + fprintf(out, ", "); + fprintf(out, "%u", full_symbol_get_coef(full_symbol,i)); + } + } + fprintf(out, "]"); + fprintf(out, ", 'data':"); + fprintf(out, "'"); + for (i=0; i < full_symbol->data_size; i++) + fprintf(out, "\\x%02x", full_symbol->data[i]); + fprintf(out, "'"); + fprintf(out, " }"); + fprintf(out, "}"); + fprintf(out,"\n"); +} + +/*---------------------------------------------------------------------------*/ + +/** + * @brief Take a symbol and add another symbol multiplied by a + * coefficient, e.g. performs the equivalent of: p1 += coef * p1 + * @param[in,out] p1 First symbol (to which coef*p2 will be added) + * @param[in] coef Coefficient by which the second packet is multiplied + */ +void full_symbol_scale(swif_full_symbol_t *symbol1, uint8_t coef) +{ + assert(symbol1->coef != NULL); + assert(symbol1->data != NULL); + if (symbol1->first_id == SYMBOL_ID_NONE || symbol1->first_nonzero_id == SYMBOL_ID_NONE) { + return; /* empty/zero packet */ + } + assert(symbol1->first_nonzero_id != SYMBOL_ID_NONE && symbol1->last_nonzero_id != SYMBOL_ID_NONE); + symbol_mul(symbol1->data, coef, symbol1->data_size, symbol1->data); + symbol_mul(symbol1->coef, coef, full_symbol_count_allocated_coef(symbol1), symbol1->coef); + full_symbol_adjust_min_max_coef(symbol1); // because after adjust some coeffs could be 0 +} + + +/** + * @brief Take a symbol and add another symbol to it, e.g. performs the equivalent of: p3 = p1 + p2 + * @param[in] p1 First symbol (to which p2 will be added) + * @param[in] p2 Second symbol + * @param[in] p3 result XXX + * + * symbol1, symbol2 should not be zero + * symbol_result has pre-set first_id, last_id + */ +void full_symbol_add_base(swif_full_symbol_t *symbol1, swif_full_symbol_t *symbol2, swif_full_symbol_t *symbol_result) +{ + assert (symbol1->data != NULL && symbol2->data != NULL && symbol_result->data != NULL); + assert (symbol_result->data_size >= symbol1->data_size && symbol_result->data_size >= symbol2->data_size); + assert (full_symbol_includes_id(symbol_result, symbol1->first_nonzero_id)); + assert (full_symbol_includes_id(symbol_result, symbol1->last_nonzero_id)); + assert (full_symbol_includes_id(symbol_result, symbol2->first_nonzero_id)); + assert (full_symbol_includes_id(symbol_result, symbol2->last_nonzero_id)); + + uint32_t first_coef_index; + uint32_t last_coef_index; + + // XXX: should not be NONE + if (symbol1->first_nonzero_id == SYMBOL_ID_NONE && symbol2->first_nonzero_id == SYMBOL_ID_NONE ){ + symbol_result->first_nonzero_id = SYMBOL_ID_NONE; + symbol_result->last_nonzero_id = SYMBOL_ID_NONE; + } + if ( symbol1->first_nonzero_id <= symbol2->first_nonzero_id){ + first_coef_index = symbol1->first_nonzero_id; + } + else { + first_coef_index = symbol2->first_nonzero_id; + } + + if ( symbol1->last_nonzero_id >= symbol2->last_nonzero_id){ + last_coef_index = symbol1->last_nonzero_id; + } + else { + last_coef_index = symbol2->last_nonzero_id; + } + + memset(symbol_result->coef , 0, sizeof(uint8_t)*(first_coef_index-symbol_result->first_id)); + memset(symbol_result->coef+(last_coef_index+1-symbol_result->first_id) , 0 , + sizeof(uint8_t)*(symbol_result->last_id-last_coef_index)); + + for (uint32_t i = first_coef_index; i <= last_coef_index; i++){ + symbol_result->coef[i-symbol_result->first_id] = full_symbol_get_coef(symbol1, i) ^ full_symbol_get_coef(symbol2, i); + } + + full_symbol_adjust_min_max_coef(symbol_result); + + if(symbol1->data_size >= symbol2->data_size ){ + symbol_add((void *)symbol1->data, (void *)symbol2->data, symbol2->data_size, (uint8_t * )symbol_result->data); + memcpy(symbol_result->data+(symbol2->data_size), symbol1->data+(symbol2->data_size) , symbol1->data_size - (symbol2->data_size)); + memset(symbol_result->data+(symbol1->data_size), 0, symbol_result->data_size - (symbol1->data_size)); + } + else { + symbol_add((void *)symbol1->data, (void *)symbol2->data, symbol1->data_size, (uint8_t * )symbol_result->data); + memcpy(symbol_result->data+symbol1->data_size, symbol2->data+(symbol1->data_size) , symbol2->data_size - (symbol1->data_size)); + memset(symbol_result->data+symbol2->data_size, 0, symbol_result->data_size - (symbol2->data_size)); + } +} + +/** + * @brief Take a symbol and add another symbol to it, e.g. performs the equivalent of: p1 + p2 + * @param[in] p1 First symbol (to which p2 will be added) + * @param[in] p2 Second symbol + * A new symbol is created to put the result of the addition + */ +swif_full_symbol_t* full_symbol_add(swif_full_symbol_t *symbol1, swif_full_symbol_t *symbol2) +{ + uint32_t first_coef_index; + uint32_t last_coef_index; + if (full_symbol_is_zero(symbol1) && full_symbol_is_zero(symbol2)) { + /* return 0 */ + return full_symbol_alloc(SYMBOL_ID_NONE, SYMBOL_ID_NONE, 0); + } + if (full_symbol_is_zero(symbol1)) { + return full_symbol_clone(symbol2); + } + if (full_symbol_is_zero(symbol2)) { + return full_symbol_clone(symbol1); + } + if ( symbol1->first_nonzero_id <= symbol2->first_nonzero_id){ + first_coef_index = symbol1->first_nonzero_id ; + } + else { + first_coef_index = symbol2->first_nonzero_id ; + } + + if ( symbol1->last_nonzero_id >= symbol2->last_nonzero_id){ + last_coef_index = symbol1->last_nonzero_id ; + } + else { + last_coef_index = symbol2->last_nonzero_id ; + } + + uint32_t data_size = (symbol1->data_size >= symbol2->data_size) + ? symbol1->data_size : symbol2->data_size; + + swif_full_symbol_t *symbol_result = full_symbol_alloc(first_coef_index, last_coef_index, + data_size); + + full_symbol_add_base(symbol1, symbol2, symbol_result); + return symbol_result; +} + + + +/* Substration */ +//void full_symbol_sub(void *symbol1, void *symbol2, uint32_t symbol_size, uint8_t* result); + + +/** + * @brief Take a symbol and multiply it by another symbol, e.g. performs the equivalent of: result = p1 * p2 + * @param[in] p1 First symbol (to which coeff will be multiplied) + * @param[in] coeff Coefficient by which the second packet is multiplied + */ +//void full_symbol_mul(void *symbol1, uint8_t coeff, uint32_t symbol_size, uint8_t* result); + + +/** + * @brief Take a symbol and divide it by another symbol, e.g. performs the equivalent of: result = p1 / p2 + * @param[in] p1 First symbol (to which coeff will be divided) + * @param[in] coeff Coefficient by which the second packet is divided + */ +//void full_symbol_div(void *symbol1, uint32_t symbol_size, uint8_t coeff, uint8_t* result); + +/*---------------------------------------------------------------------------*/ + + + + + + + + + + + + + diff --git a/tools/precoder/vendor/swif-codec/src/swif_full_symbol_impl.h b/tools/precoder/vendor/swif-codec/src/swif_full_symbol_impl.h new file mode 100644 index 0000000..45b8df9 --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_full_symbol_impl.h @@ -0,0 +1,167 @@ +#ifndef __SWIF_FULL_SYMBOL_IMPL_H__ +#define __SWIF_FULL_SYMBOL_IMPL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* XXX: move in more general header file */ +#define WARNING_PRINT(fmt, args...) fprintf(stderr, "WARNING: %s: %d: %s(): " fmt, \ + __FILE__, __LINE__, __func__, ##args) +//#define WITH_DEBUG +#ifdef WITH_DEBUG +#define IF_DEBUG(...) do { __VA_ARGS__; } while(0) +#else +#define IF_DEBUG(...) do { } while(0) +#endif + +/*---------------------------------------------------------------------------*/ +/** + * @brief Implementation of full symbol operations. + */ + + +/*---------------------------------------------------------------------------*/ + +/* The implementation of full_symbol_t, a linear combination of source packets. + * - `coef' represents the encoding header (coefficients) of the combination + * - `coef[0]' corresponds to the source symbol of index `first_id' + * - `last_id' (included) is the last possible source symbol included in the + * array `coef', and thus defines the array size + * - `first_nonzero_id' and `last_nonzero_id' correspond the first and last + * source symbol indices that have non zero coefficients. SYMBOL_ID_NONE is + * used when the full_symbol_t corresponds to zero, and these values are + * maintained after each operation on a packet. + * - `data' is the coded symbol itself + * - `data_size' is the size of the coded symbol. + */ +struct s_swif_full_symbol_t { + /* first_id, last_id relate to the memory allocation + can be SYMBOL_ID_NONE (when no coefficient available) */ + uint8_t *coef; /* never NULL */ + symbol_id_t first_id; /* coef[0] is the coefficient of first_id */ + symbol_id_t last_id; /* (last included) */ + + /* first_nonzero_id, last_nonzero_id relate to the coef array + they can be SYMBOL_ID_NONE if no coef is different of zero + otherwise the coefficients at these, are always non-zero + note: full_symbol_get_coef(i) is 0 outside of this range */ + symbol_id_t first_nonzero_id; + symbol_id_t last_nonzero_id; + + uint8_t *data; /* the coded symbol itself (the data) - never NULL */ + uint32_t data_size; /* size of the coded symbol */ +}; + +/*---------------------------------------------------------------------------*/ + +typedef void (*notify_decoded_func_t)(swif_full_symbol_set_t *set, symbol_id_t symbol_id, void *context); + +struct s_swif_full_symbol_set_t { + uint32_t size; /* size of the table containing pointers to full_symbol */ + uint32_t first_symbol_id; /* the index of full_symbol_tab */ + uint32_t nmbr_packets; + swif_full_symbol_t **full_symbol_tab; + + notify_decoded_func_t notify_decoded_func; /* XXX: manually set */ + void *notify_context; +}; + +/* The following constant is used to declare that an entry is not used */ +#define ENTRY_INDEX_NONE 0xfffffffful + +/*---------------------------------------------------------------------------*/ + +/** + * @brief Add a full_symbol to a packet set. + * + * Online Gaussian elimination is performed. + * Return the pivot associated to the new full_symbol (as source symbol index) + * or ENTRY_INDEX_NONE if dependent (e.g. redundant) packet + * + * The full_symbol is not freed and also reference is not captured. + */ +symbol_id_t swif_full_symbol_set_add +(swif_full_symbol_set_t* set, swif_full_symbol_t* full_symbol); + +/** + * @brief Create a full_symbol from a raw packet (a set of bytes) + * and initialize it with content '0' + */ +swif_full_symbol_t *full_symbol_alloc +(symbol_id_t first_symbol_id, symbol_id_t last_symbol_id, uint32_t symbol_size); + +/** + * @brief Dump the content of a full_symbol set for debugging purposes + * + */ +void full_symbol_set_dump(swif_full_symbol_set_t *full_symbol_set, FILE *out); + +/** + * @brief get the size of the data + */ + + + +static inline bool full_symbol_has_sufficient_size(swif_full_symbol_t* symbol, + symbol_id_t id1, symbol_id_t id2); + +static inline bool full_symbol_includes_id(swif_full_symbol_t* symbol, + symbol_id_t symbol_id); +// adjust full symbol min coef + + +static bool full_symbol_adjust_min_coef(swif_full_symbol_t* symbol); + + + + +// adjust full symbol max coef + +static bool full_symbol_adjust_max_coef(swif_full_symbol_t* symbol); + + +// adjust full symbol min and max coef +// Recompute the first_nonzero_id and last_nonzero_id +bool full_symbol_adjust_min_max_coef(swif_full_symbol_t* symbol); + + +/*---------------------------------------------------------------------------*/ + +/** + * @brief Take a symbol and add another symbol multiplied by a + * coefficient, e.g. performs the equivalent of: p1 += coef * p1 + * @param[in,out] p1 First symbol (to which coef*p1 will be added) + * @param[in] coef2 Coefficient by which the second packet is multiplied + */ +void full_symbol_scale +( swif_full_symbol_t *symbol1, uint8_t coereef); + + +/** + * @brief Take a symbol and add another symbol to it, e.g. performs the equivalent of: p3 = p1 + p2 + * @param[in] p1 First symbol (to which p2 will be added) + * @param[in] p2 Second symbol + * @param[in] p3 result XXX + */ +void full_symbol_add_base(swif_full_symbol_t *symbol1, swif_full_symbol_t *symbol2, swif_full_symbol_t *symbol_result); + + + +swif_full_symbol_t* full_symbol_add +(swif_full_symbol_t *symbol1, swif_full_symbol_t *symbol2); + + +/*---------------------------------------------------------------------------*/ + +void full_symbol_dump(swif_full_symbol_t *full_symbol, FILE *out); + +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __CODED_PACKET_H__ */ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/tools/precoder/vendor/swif-codec/src/swif_full_symbol_lc.c b/tools/precoder/vendor/swif-codec/src/swif_full_symbol_lc.c new file mode 100644 index 0000000..8ce5d3a --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_full_symbol_lc.c @@ -0,0 +1,233 @@ + +/** + * @brief For now this is an hackish adaptation on top of liblc, + * will be replaced by a proper implementation later. + */ + + +#include "coded-packet.h" +#include "packet-set.h" + +#define LIBLC_GF256 3 +#define COEF_PER_HEADER ((COEF_HEADER_SIZE*BITS_PER_BYTE)>>LIBLC_GF256) + +#include "swif_full_symbol.h" + +/*---------------------------------------------------------------------------*/ + +struct s_swif_full_symbol_t { + coded_packet_t* coded_packet; + uint32_t symbol_size; +}; + +/*---------------------------------------------------------------------------*/ + +struct s_swif_full_symbol_set_t { + packet_set_t packet_set; + reduction_stat_t reduction_stat; +}; + +/*---------------------------------------------------------------------------*/ + + +/** + * @brief Create a full_symbol set, that will be used to do gaussian elimination + */ +swif_full_symbol_set_t *full_symbol_set_alloc() +{ + swif_full_symbol_set_t *result + = (swif_full_symbol_set_t *)calloc(1, sizeof(swif_full_symbol_set_t)); + if (result == NULL) { + return NULL; + } + + packet_set_init(&result->packet_set, LIBLC_GF256, NULL, NULL, NULL, NULL); + return result; +} + +/** + * @brief Free a full_symbol set + */ +void full_symbol_set_free(swif_full_symbol_set_t *set) +{ + memset(&set->packet_set, 0, sizeof(packet_set_t)); + free(set); +} + + +/** + * @brief Add a full_symbol to a packet set. + * + * Gaussian elimination can occur. + * Return the pivot associated to the new full_symbol + * or SYMBOL_ID_NONE if dependent (e.g. redundant) packet + * + * The full_symbol is not freed and also reference is not captured. + */ +uint32_t swif_full_symbol_set_add +(swif_full_symbol_set_t* set, swif_full_symbol_t* full_symbol) +{ + uint32_t packet_id = packet_set_add(&set->packet_set, + full_symbol->coded_packet, + &set->reduction_stat, false); + if (packet_id != PACKET_ID_NONE) { + return packet_id; + } else { + return SYMBOL_ID_NONE; + } +} + +/*---------------------------------------------------------------------------*/ + +/** + * @brief Create a full_symbol from a raw packet (a set of bytes) + * and initialize it with content '0' + */ +swif_full_symbol_t *full_symbol_alloc +(uint32_t symbol_id_size, uint32_t symbol_size) +{ + assert(symbol_id_size <= COEF_HEADER_SIZE); + assert(symbol_size <= CODED_PACKET_SIZE); + swif_full_symbol_t *result + = (swif_full_symbol_t *)calloc(1, sizeof(swif_full_symbol_t)); + if (result == NULL) { + return NULL; + } + + coded_packet_t *coded_packet + = (coded_packet_t *)calloc(1, sizeof(coded_packet_t)); + if (coded_packet == NULL) { + free(result); + return NULL; + } + + result->coded_packet = coded_packet; + result->symbol_size = symbol_size; + coded_packet_init(result->coded_packet, LIBLC_GF256); + return result; +} + + +/** + * @brief Create a full_symbol from a raw packet (a set of bytes) + * and initialize it with content '0' + */ +swif_full_symbol_t *full_symbol_create_from_source +(uint32_t symbol_id, uint8_t *symbol_data, uint32_t symbol_size) +{ + swif_full_symbol_t *result = full_symbol_alloc(1, symbol_size); + if (result == NULL) { + return NULL; + } + coded_packet_set_coef(result->coded_packet, symbol_id, 1); + memcpy(coded_packet_data(result->coded_packet), symbol_data, symbol_size); + result->symbol_size = symbol_size; + coded_packet_adjust_min_max_coef(result->coded_packet); + return result; +} + +swif_full_symbol_t *full_symbol_create +(uint8_t* symbol_coef_table, uint32_t min_symbol_id, uint32_t nb_symbol_id, + uint8_t* symbol_data, uint32_t symbol_size) +{ + swif_full_symbol_t *result = full_symbol_alloc(nb_symbol_id, symbol_size); + if (result == NULL) { + return NULL; + } + for (uint32_t i=0; i 1 coef 1 byte: */ + uint8_t coef = symbol_coef_table[i]; + coded_packet_set_coef(result->coded_packet, i+min_symbol_id, coef); + } + memcpy(coded_packet_data(result->coded_packet), symbol_data, symbol_size); + coded_packet_adjust_min_max_coef(result->coded_packet); + result->symbol_size = symbol_size; + return result; +} + +/** + * @brief Release a full_symbol + */ +void full_symbol_free(swif_full_symbol_t* full_symbol) +{ + assert(full_symbol != NULL); + assert(full_symbol->coded_packet != NULL); + free(full_symbol->coded_packet); + full_symbol->coded_packet = NULL; + free(full_symbol); +} + +/** + * @brief Create a new (unlinked) copy of a full_symbol + */ +swif_full_symbol_t *full_symbol_clone(swif_full_symbol_t* full_symbol) +{ + swif_full_symbol_t *result = full_symbol_alloc( + COEF_HEADER_SIZE, full_symbol->symbol_size); + memcpy(result->coded_packet, full_symbol->coded_packet, + sizeof(coded_packet_t)); + return result; +} + +/** + * @brief get the size of the data + */ +uint32_t full_symbol_get_size(swif_full_symbol_t *full_symbol) +{ return full_symbol->symbol_size; } + +/** + * @brief get the minimum source index that appears in the symbol + * returns SYMBOL_ID_NONE if there is none (e.g. symbol is 0) + */ +uint32_t full_symbol_get_min_symbol_id(swif_full_symbol_t *full_symbol) +{ + coded_packet_adjust_min_max_coef(full_symbol->coded_packet); + if (full_symbol->coded_packet->coef_pos_min != COEF_POS_NONE) { + return full_symbol->coded_packet->coef_pos_min; + } else { + return SYMBOL_ID_NONE; + } +} + +/** + * @brief get the maximum source index that appears in the symbol + * returns SYMBOL_ID_NONE if there is none (e.g. symbol is 0) + */ +uint32_t full_symbol_get_max_symbol_id(swif_full_symbol_t *full_symbol) +{ + coded_packet_adjust_min_max_coef(full_symbol->coded_packet); + if (full_symbol->coded_packet->coef_pos_max != COEF_POS_NONE) { + return full_symbol->coded_packet->coef_pos_max; + } else { + return SYMBOL_ID_NONE; + } +} + +/** + * @brief get the coefficient corresponding to the specified symbol identifier + */ +uint8_t full_symbol_get_coef +(swif_full_symbol_t *full_symbol, uint32_t symbol_id) +{ + return coded_packet_get_coef(full_symbol->coded_packet, symbol_id); +} + +/** + * @brief get the symbol 'data'. result_data should be a pointer to a + * a block of memory of full_symbol_get_size(full_symbol) + */ +void full_symbol_get_data +(swif_full_symbol_t *full_symbol, uint8_t *result_data) +{ + memcpy(result_data, coded_packet_data(full_symbol->coded_packet), + full_symbol->symbol_size); +} + +void full_symbol_dump(swif_full_symbol_t *full_symbol, FILE *out) +{ + fprintf(out, "{'size':%u, 'internal':", full_symbol->symbol_size); + coded_packet_pywrite(out, full_symbol->coded_packet); + fprintf(out, "}"); +} + +/*---------------------------------------------------------------------------*/ diff --git a/tools/precoder/vendor/swif-codec/src/swif_general.h b/tools/precoder/vendor/swif-codec/src/swif_general.h new file mode 100644 index 0000000..6841862 --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_general.h @@ -0,0 +1,109 @@ +/*--------------------------------------------------------------------------- + * Copyright 2013-2017 Inria + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + *---------------------------------------------------------------------------*/ + +/** + * @defgroup SWiF-Codec + * @ingroup swif-codec-base + * @brief an open-source sliding window FEC codec in C + * @{ + * + * @file + * @brief General definitions and macros + * + * @author Cedric Adjih + * @author Vincent Roca + */ + +#ifndef __SWIF_GENERAL_H__ +#define __SWIF_GENERAL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ + +#include + +/*---------------------------------------------------------------------------*/ + +#define BEGIN_MACRO do { +#define END_MACRO } while(0) + +/*---------------------------------------------------------------------------*/ + +#define BITS_PER_BYTE 8 +#define LOG2_BITS_PER_BYTE 3 + +#define BOOL_FALSE 0 +#define BOOL_TRUE 1 + +#define REQUIRE(...) ASSERT(__VA_ARGS__) + +#define STATIC_ENSURE_EQUAL(name,a,b) \ + struct name { char l1[(a)-(b)]; char l2[(b)-(a)]; }; + +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + +static inline uint16_t min_except(uint16_t v1, uint16_t v2, uint16_t ignored) +{ + if (v1 == ignored) + return v2; + if (v2 == ignored) + return v1; + return MIN(v1, v2); +} + +static inline uint16_t max_except(uint16_t v1, uint16_t v2, uint16_t ignored) +{ + if (v1 == ignored) + return v2; + if (v2 == ignored) + return v1; + return MAX(v1, v2); +} + +/*---------------------------------------------------------------------------*/ + +#ifdef DEBUG +#define DEBUG_PRINT(...) do { fprintf( stderr, __VA_ARGS__ ); } while(0) +#else +#define DEBUG_PRINT(...) do {} while(0) +#endif + +static inline void DEBUG_DUMP(void *data, unsigned int data_size) +{ + for (unsigned int j=0; j +#include +#include +#include +#include +#include + +#include "swif_general.h" +#include "swif_api.h" +#include "swif_rlc_cb.h" +#include "swif_linear-code.h" +#include "swif_prng.h" +#include "swif_full_symbol.h" +#include "swif_full_symbol_impl.h" +#include "swif_symbol.h" + +#endif /* SWIF_INCLUDES_H */ diff --git a/tools/precoder/vendor/swif-codec/src/swif_linear-code.c b/tools/precoder/vendor/swif-codec/src/swif_linear-code.c new file mode 100644 index 0000000..a60b672 --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_linear-code.c @@ -0,0 +1,314 @@ +/*--------------------------------------------------------------------------- + * Copyright 2013-2017 Inria + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + *---------------------------------------------------------------------------*/ + +/** + * @ingroup liblc + * @{ + * + * @file + * + * @author Cedric Adjih + * + * @brief Linear coding operations (GF(2), GF(4), GF(16) and GF(256)) + */ + +#include +#include + +#include "swif_general.h" +#include "swif_linear-code.h" + +/*--------------------------------------------------*/ + +//#ifdef WITH_GF16 +//#include "table-mul-gf16.c" +//#endif /* WITH_GF16 */ +// +//#include "table-mul-gf4.c" + +/*--------------------------------------------------*/ + +/* With SWiF Codec, always use GF(256) and GF256_MUL_TABLE */ +#define WITH_GF256 +#define WITH_GF256_MUL_TABLE + + +#ifdef WITH_GF256 + +#ifdef WITH_GF256_MUL_TABLE + +#include "swif_table-mul-gf256.c" +static inline uint8_t gf256_mul(uint8_t a, uint8_t b) +{ return gf256_mul_table[a][b]; } + +static inline uint8_t gf256_inv(uint8_t a) +{ return gf256_inv_table[a]; } + +#else /* WITH_GF256_MUL_TABLE */ + +//#include "table-explog-gf256.c" +///* compute a.b as exp[log[a]+log[b]] */ +//static inline uint8_t gf256_mul(uint8_t a, uint8_t b) +//{ +// if ( a == 0 || b == 0) +// return 0; +// +// uint16_t log_res = ((uint16_t)gf256_log_table[a]) +// + ((uint16_t)gf256_log_table[b]); +// log_res = (log_res + (log_res >> 8)) & 0xff; /* mod 255 */ +// return gf256_exp_table[log_res]; +//} +// +//static inline uint8_t gf256_inv(uint8_t a) +//{ return gf256_exp_table[255-gf256_log_table[a]]; } + +#endif /* WITH_GF256_MUL_TABLE */ + +#endif /* WITH_GF256 */ + +/*---------------------------------------------------------------------------*/ + +/* + the function also operates correctly when two of the pointers (or all three) + result, data1 or data2 are exactly the same. +*/ +void lc_vector_add(uint8_t* data1, uint16_t size1, + uint8_t* data2, uint16_t size2, + uint8_t* result, uint16_t* result_size) +{ + uint16_t i; + uint16_t common_size = 0; + + if (size1 <= size2) { + common_size = size1; + *result_size = size2; + for (i = common_size; i<*result_size; i++) + result[i] = data2[i]; + } else { + common_size = size2; + *result_size = size1; + for (i = common_size; i<*result_size; i++) + result[i] = data1[i]; + } + + for (i=0; i> bit_pos) & coef_mask; + return result; +} + + +uint16_t lc_vector_get_byte_pos_of_coef(uint8_t log2_nb_bit_coef, + uint16_t coef_pos) +{ + ASSERT( log2_nb_bit_coef <= MAX_LOG2_NB_BIT_COEF ); + //uf8 nb_bit_coef = 1< + */ + +#ifndef __LINEAR_CODE_H__ +#define __LINEAR_CODE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ + +#include + +/*---------------------------------------------------------------------------*/ + +/** + * @brief The "log2 of the number of bits (per element)", also denoted `L`, + * is used everywhere + * to specify which of GF(2), GF(4), GF(16), GF(256) is used + * (`L` is `0,1,2,3` respectively). + * The maximum (included) is 3 for GF(256). + * @details Notice: \f$2^{(2^0)} = 2\f$, \f$2^{(2^1)} = 4\f$, + * \f$2^{(2^2)} = 16\f$, \f$2^{(2^3)} = 256\f$ + */ +#define MAX_LOG2_NB_BIT_COEF 3 /* included */ + +/** + * @brief Returns the inverse of an element + * in GF(\f$2^{(2^L)}\f$) where `L = log2_nb_bit_coef` + * @param[in] x - must be different from `0` + * @return y in the finite field such that `x.y = 1` + * @details An `assert` verifies that `x != 0` + * (if assertions are disabled, `0` or `1` are expected to be returned). + */ +uint8_t lc_inv(uint8_t x, uint8_t log2_nb_bit_coef); + +/** + * @brief Returns the product of elements + * in GF(\f$2^{(2^L)}\f$) where `L = log2_nb_bit_coef` + * @param[in] x is one element of the finite field + * @param[in] y is one element of the finite field + * @return x.y in the galois field (0 <= x.y < \f$2^{(2^L)}\f$) + */ +uint8_t lc_mul(uint8_t x, uint8_t y, uint8_t log2_nb_bit_coef); + +/** + * @brief Returns the opposite of some value + * in GF(\f$2^{(2^L)}\f$) where `L = log2_nb_bit_coef` + * @param[in] x is one element of the finite field + * @return -x in the galois field (0 <= `-x` < \f$2^{(2^L)}\f$) + * @details in characteristic 2 (e.g. GF(\f$2^n\f$), `-x == x` + */ +static inline uint8_t lc_neg(uint8_t x, uint8_t log2_nb_bit_coef) +{ (void)log2_nb_bit_coef; return x; /* -x == x in GF(2^n) */ } + +/*---------------------------------------------------------------------------*/ + +/** + * @brief Divide a value by a power of 2 + * @param[in] value + * @param[in] log2_divisor + * @return value / \f$2^{log2\_divisor}\f$ + */ +#define DIV_LOG2(value, log2_divisor) ((value)>>(log2_divisor)) + +/** + * @brief Multiply a value by a power of 2 + * @param[in] value + * @param[in] log2_divisor + * @return value / \f$2^{log2\_divisor}\f$ + */ +#define MUL_LOG2(value, log2_mult) ((value)<<(log2_mult)) + +/** + * @brief Return a mask + * @param[in] nb_bit Number of bits in the mask + * @return 11111111..11 with `nb_bit` `1` + * @details it is an `int`, check overflow for larger `nb_bits` + */ +#define MASK(nb_bit) ((1 << (nb_bit))-1) + +/** + * @brief Compute the remainder of value divided by a power of 2 + * @param[in] value + * @param[in] log2_divisor + * @return value `modulo` \f$2^{log2\_divisor}\f$ + */ +#define MOD_LOG2(value, log2_divisor) ((value)&MASK((log2_divisor))) + + +/** + * \f$2^3\f$ = 8 bits per byte. + */ +#define LOG2_BITS_PER_BYTE 3 + +/** + * @brief Compute the sum of two vectors (sequences, arrays) of elements + * of a finite field + * @param[in] data1 First vector of elements + * @param[in] size1 Number of bytes (not elements) in the first vector. + * @param[in] data2 Second vector of elements + * @param[in] size2 Number of bytes (not elements) in the first vector. + * @param[out] result Output vector holding the sum of the elements, + * e.g. `result[i] = data1[i]+data2[i]` + * in the finite field; the shortest of sequence + * is considered to by extended with `0`. + * Called must ensure that the memory area of `result` + * has at least `result_size` bytes. + * @param[out] result_size Maximum of `size1` and `size2`. + * @details `data1`, `data2` and `result` could be equal as pointers (two of + * them or all three), and the `result` would still be correct. + * Other than such strict equality, `result` should point to memory + * areas disjoint from `data1` or `data2`, + * e.g. `lc_vector_add(p,l-1,p,l-1,p+1,&l2)` gives improper result. + */ +void lc_vector_add(uint8_t* data1, uint16_t size1, + uint8_t* data2, uint16_t size2, + uint8_t* result, uint16_t* result_size); + +/** + * @brief Multiply each element of one vector (sequences, arrays) of elements + * by one given element of the finite field. + * @param[in] coef Coefficient of the finite field + * @param[in] data Vector of elements + * @param[in] size Number of bytes (not elements) in the vector + * @param[in] log2_nb_bit_coef Defines the finite field, e.g. + * GF(\f$2^{(2^L)}\f$) where `L = log2_nb_bit_coef` + * @param[out] result Output vector holding the sum of the elements, + * e.g. `result[i] = coef x data[i]` + * in the finite field; + * @details `data` and `result` could be equal as pointers, + * and the `result` would still be correct. + * Other than such strict equality, `result` should point to memory + * area disjoint from `data`, + * e.g. `lc_vector_mul(c,p,l-1,L,p+1)` gives improper result. + */ +void lc_vector_mul(uint8_t coef, uint8_t* data, uint16_t size, + uint8_t log2_nb_bit_coef, uint8_t* result); + +/** + * @brief Set the n-th element of one vector (sequences, arrays) + * to one given element of one finite field. + * @param[in] data Vector of elements + * @param[in] size Number of bytes (not elements) in the vector + * @param[in] log2_nb_bit_coef Defines the finite field, e.g. + * GF(\f$2^{(2^L)}\f$) where `L = log2_nb_bit_coef` + * @param[in] coef_pos Position of the element to set in the vector + * (as \f$n-th\f$ element, not position in bytes). + * @param[in] coef_value The value of the finite field to put in the vector + * at the position `coef_pos` + * @details assertions verify the lack of `out of bound` access + */ +void lc_vector_set(uint8_t* data, uint16_t size, uint8_t log2_nb_bit_coef, + uint16_t coef_pos, uint8_t coef_value); + +/** + * @brief Get the n-th element of one vector (sequences, arrays) + * of elements of one finite field. + * @param[in] data Vector of elements + * @param[in] size Number of bytes (not elements) in the vector + * @param[in] log2_nb_bit_coef Defines the finite field, e.g. + * GF(\f$2^{(2^L)}\f$) where `L = log2_nb_bit_coef` + * @param[in] coef_pos Position of the element to set in the vector + * (as \f$n-th\f$ element, not position in bytes). + * @return The value in the vector at the position `coef_pos` (e.g. + * a finite field element) + * @details assertions verify the lack of `out of bound` access + */ +uint8_t lc_vector_get(uint8_t* data, uint16_t size, uint8_t log2_nb_bit_coef, + uint16_t coef_pos); + + /** + * @brief Convert the position of n-th element of one vector (sequences, arrays) + * of one finite field to the position in expressed in bytes (of memory). + * @param[in] log2_nb_bit_coef Defines the finite field, e.g. + * GF(\f$2^{(2^L)}\f$) where `L = log2_nb_bit_coef` + * @param[in] coef_pos Position of the element to set in the vector + * (as \f$n-th\f$ element, not position in bytes). + * @return The value in the vector at the position `coef_pos` (e.g. + * a finite field element) + * @details In GF(256), position (index) `coef_pos` in vector is same + * as position in bytes; + * in GF(2), position in bytes is `coef_pos/8`, etc. + */ +uint16_t lc_vector_get_byte_pos_of_coef(uint8_t log2_nb_bit_coef, + uint16_t coef_pos); + +/*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* __LINEAR_CODE_H__ */ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/tools/precoder/vendor/swif-codec/src/swif_prng.c b/tools/precoder/vendor/swif-codec/src/swif_prng.c new file mode 100644 index 0000000..0ed4bc6 --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_prng.c @@ -0,0 +1,142 @@ +/** + * SWiF Codec: an open-source sliding window FEC codec in C + * https://github.com/irtf-nwcrg/swif-codec + */ + +/** + * Tiny Mersenne Twister, only 127 bit internal state. + * Derived from the reference implementation version 1.1 (2015/04/24) + * by Mutsuo Saito (Hiroshima University) and Makoto Matsumoto + * (Hiroshima University). + * + * PRNG coming from RLC FEC Scheme and TinyMT PRNG Internet-Drafts: + * https://datatracker.ietf.org/doc/draft-ietf-tsvwg-rlc-fec-scheme/ + * https://datatracker.ietf.org/doc/draft-roca-tsvwg-tinymt32/ + */ + +#include "swif_includes.h" + +static void tinymt32_next_state (tinymt32_t * s); +static uint32_t tinymt32_temper (tinymt32_t * s); + +/** + * Parameter set to use for this IETF specification. Don't change. + * This parameter set is the first entry of the precalculated + * parameter sets in file tinymt32dc.0.1048576.txt, by Kenji + * Rikitake, available at: + * https://github.com/jj1bdx/tinymtdc-longbatch/blob/master/ + * tinymt32dc/tinymt32dc.0.1048576.txt + * It is also the parameter set used: + * Rikitake, K., "TinyMT Pseudo Random Number Generator for + * Erlang", ACM 11th SIGPLAN Erlang Workshop (Erlang'12), + * September, 2012. + */ +const uint32_t TINYMT32_MAT1_PARAM = UINT32_C(0x8f7011ee); +const uint32_t TINYMT32_MAT2_PARAM = UINT32_C(0xfc78ff1f); +const uint32_t TINYMT32_TMAT_PARAM = UINT32_C(0x3793fdff); + +/** + * This function initializes the internal state array with a + * 32-bit unsigned integer seed. + * @param s pointer to tinymt internal state. + * @param seed a 32-bit unsigned integer used as a seed. + */ +void tinymt32_init (tinymt32_t * s, uint32_t seed) +{ + const uint32_t MIN_LOOP = 8; + const uint32_t PRE_LOOP = 8; + s->status[0] = seed; + s->status[1] = s->mat1 = TINYMT32_MAT1_PARAM; + s->status[2] = s->mat2 = TINYMT32_MAT2_PARAM; + s->status[3] = s->tmat = TINYMT32_TMAT_PARAM; + for (int i = 1; i < MIN_LOOP; i++) { + s->status[i & 3] ^= i + UINT32_C(1812433253) + * (s->status[(i - 1) & 3] + ^ (s->status[(i - 1) & 3] >> 30)); + } + /* + * NB: the parameter set of this specification warrants + * that none of the possible 2^^32 seeds leads to an + * all-zero 127-bit internal state. Therefore, the + * period_certification() function of the original + * TinyMT32 source code has been safely removed. If + * another parameter set is used, this function will + * have to be re-introduced here. + */ + for (int i = 0; i < PRE_LOOP; i++) { + tinymt32_next_state(s); + } +} + +/** + * This function outputs a 32-bit unsigned integer from + * the internal state. + * @param s pointer to tinymt internal state. + * @return 32-bit unsigned integer r (0 <= r < 2^32). + */ +uint32_t tinymt32_generate_uint32 (tinymt32_t * s) +{ + tinymt32_next_state(s); + return tinymt32_temper(s); +} + +/** + * Internal tinymt32 constants and functions. + * Users should not call these functions directly. + */ +const uint32_t TINYMT32_SH0 = 1; +const uint32_t TINYMT32_SH1 = 10; +const uint32_t TINYMT32_SH8 = 8; +const uint32_t TINYMT32_MASK = UINT32_C(0x7fffffff); + +/** + * This function changes the internal state of tinymt32. + * @param s pointer to tinymt internal state. + */ +static void tinymt32_next_state (tinymt32_t * s) +{ + uint32_t x; + uint32_t y; + + y = s->status[3]; + x = (s->status[0] & TINYMT32_MASK) + ^ s->status[1] + ^ s->status[2]; + x ^= (x << TINYMT32_SH0); + y ^= (y >> TINYMT32_SH0) ^ x; + s->status[0] = s->status[1]; + s->status[1] = s->status[2]; + s->status[2] = x ^ (y << TINYMT32_SH1); + s->status[3] = y; + /* + * The if (y & 1) {...} block below replaces: + * s->status[1] ^= -((int32_t)(y & 1)) & s->mat1; + * s->status[2] ^= -((int32_t)(y & 1)) & s->mat2; + * The adopted code is equivalent to the original code + * but does not depend on the representation of negative + * integers by 2's complements. It is therefore more + * portable, but includes an if-branch which may slow + * down the generation speed. + */ + if (y & 1) { + s->status[1] ^= s->mat1; + s->status[2] ^= s->mat2; + } +} + +/** + * This function outputs a 32-bit unsigned integer from + * the internal state. + * @param s pointer to tinymt internal state. + * @return 32-bit unsigned pseudo-random number. + */ +static uint32_t tinymt32_temper (tinymt32_t * s) +{ + uint32_t t0, t1; + t0 = s->status[3]; + t1 = s->status[0] + (s->status[2] >> TINYMT32_SH8); + t0 ^= t1; + t0 ^= -((int32_t)(t1 & 1)) & s->tmat; + return t0; +} + diff --git a/tools/precoder/vendor/swif-codec/src/swif_prng.h b/tools/precoder/vendor/swif-codec/src/swif_prng.h new file mode 100644 index 0000000..2a1ff64 --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_prng.h @@ -0,0 +1,74 @@ +/** + * SWiF Codec: an open-source sliding window FEC codec in C + * https://github.com/irtf-nwcrg/swif-codec + */ + +/** + * Tiny Mersenne Twister, only 127 bit internal state. + * Derived from the reference implementation version 1.1 (2015/04/24) + * by Mutsuo Saito (Hiroshima University) and Makoto Matsumoto + * (Hiroshima University). + * + * PRNG coming from RLC FEC Scheme and TinyMT PRNG Internet-Drafts: + * https://datatracker.ietf.org/doc/draft-ietf-tsvwg-rlc-fec-scheme/ + * https://datatracker.ietf.org/doc/draft-roca-tsvwg-tinymt32/ + */ + + +/** + * tinymt32 internal state vector and parameters + */ +typedef struct { + uint32_t status[4]; + uint32_t mat1; + uint32_t mat2; + uint32_t tmat; +} tinymt32_t; + + +/** + * This function initializes the internal state array with a 32-bit + * unsigned integer seed. + * @param s pointer to tinymt internal state. + * @param seed a 32-bit unsigned integer used as a seed. + */ +void tinymt32_init (tinymt32_t * s, + uint32_t seed); + + +/** + * This function outputs a 32-bit unsigned integer from + * the internal state. + * @param s pointer to tinymt internal state. + * @return 32-bit unsigned integer r (0 <= r < 2^32). + */ +uint32_t tinymt32_generate_uint32 (tinymt32_t * s); + + +/** + * This function outputs a pseudo-random integer in [0 .. 15] range. + * Used by RLC FEC Scheme: + * https://datatracker.ietf.org/doc/draft-ietf-tsvwg-rlc-fec-scheme/ + * + * @param s pointer to tinymt internal state. + * @return unsigned integer between 0 and 15 inclusive. + */ +static inline uint32_t tinymt32_rand16(tinymt32_t *s) +{ + return (tinymt32_generate_uint32(s) & 0xF); +} + + +/** + * This function outputs a pseudo-random integer in [0 .. 255] range. + * Used by RLC FEC Scheme: + * https://datatracker.ietf.org/doc/draft-ietf-tsvwg-rlc-fec-scheme/ + * + * @param s pointer to tinymt internal state. + * @return unsigned integer between 0 and 255 inclusive. + */ +static inline uint32_t tinymt32_rand256(tinymt32_t *s) +{ + return (tinymt32_generate_uint32(s) & 0xFF); +} + diff --git a/tools/precoder/vendor/swif-codec/src/swif_rlc_api.c b/tools/precoder/vendor/swif-codec/src/swif_rlc_api.c new file mode 100644 index 0000000..c567112 --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_rlc_api.c @@ -0,0 +1,628 @@ +#include "swif_includes.h" +#include "swif_rlc_api.h" +#include "swif_coding_coefficients.h" +#include "swif_full_symbol_impl.c" + +/******************************************************************************* + * Encoder functions + */ + + +/** + * Release an encoder and its associated ressources. + **/ +swif_status_t swif_rlc_encoder_release (swif_encoder_t* enc) +{ + assert(enc); + swif_encoder_rlc_cb_t *rlc_enc = (swif_encoder_rlc_cb_t *) enc; + if (rlc_enc->cc_tab) + free(rlc_enc->cc_tab); + if (rlc_enc->ew_tab) + free(rlc_enc->ew_tab); + free(enc); + return SWIF_STATUS_OK; +} + + +/** + * Set the various callback functions for this encoder. + * All the callback functions require an opaque context parameter, that must be + * initialized accordingly by the application, since it is application specific. + */ +swif_status_t swif_rlc_encoder_set_callback_functions ( + swif_encoder_t* enc, + void (*source_symbol_removed_from_coding_window_callback) ( + void* context, + esi_t old_symbol_esi), + void* context_4_callback) +{ + swif_encoder_rlc_cb_t *rlc_enc = (swif_encoder_rlc_cb_t *) enc; + + assert(enc); + rlc_enc->source_symbol_removed_from_coding_window_callback = + source_symbol_removed_from_coding_window_callback; + rlc_enc->context_4_callback = context_4_callback; + return SWIF_STATUS_OK; +} + + +/** + * This function sets one or more FEC codec specific parameters, + * using a type/length/value approach for maximum flexibility. + */ +swif_status_t swif_rlc_encoder_set_parameters ( + swif_encoder_t* enc, + uint32_t type, + uint32_t length, + void* value) +{ +// NOT YET + return SWIF_STATUS_OK; +} + +/** + * This function gets one or more FEC codec specific parameters, + * using a type/length/value approach for maximum flexibility. + */ +swif_status_t swif_rlc_encoder_get_parameters ( + swif_encoder_t* enc, + uint32_t type, + uint32_t length, + void* value) +{ +// NOT YET + return SWIF_STATUS_OK; +} + + +/** + * Create a single repair symbol (i.e. perform an encoding). + */ +swif_status_t swif_rlc_build_repair_symbol ( + swif_encoder_t* generic_encoder, + void** new_buf) +{ + swif_encoder_rlc_cb_t* enc = (swif_encoder_rlc_cb_t*) generic_encoder; + uint32_t i; + + if (*new_buf == 0) + { + if ((*new_buf = calloc(1, enc->symbol_size)) == NULL) { + fprintf(stderr, "swif_rlc_build_repair_symbol failed! No memory\n"); + return SWIF_STATUS_ERROR; + } + } + else + { + memset(*new_buf,0,enc->symbol_size); + } + + DEBUG_PRINT("\nbuild-repair: \n"); + for (i = enc->ew_left; i < enc->ew_ss_nb; i++) { + uint32_t idx = i % enc->max_coding_window_size; + DEBUG_PRINT(" +%u.P[%u->%u]", enc->cc_tab[idx], i, idx); + symbol_add_scaled(*new_buf, enc->cc_tab[idx], enc->ew_tab[idx], enc->symbol_size); + } + DEBUG_PRINT("\n"); + return SWIF_STATUS_OK; +} + + +/******************************************************************************* + * Decoder functions + */ + + +/** + * Release a decoder and its associated ressources. + **/ +swif_status_t swif_rlc_decoder_release (swif_decoder_t* dec) +{ + assert(dec); + swif_decoder_rlc_cb_t *rlc_dec = (swif_decoder_rlc_cb_t *) dec; + if (rlc_dec->coef_tab) + free(rlc_dec->coef_tab); + if (rlc_dec->symbol_set) + full_symbol_set_free(rlc_dec->symbol_set); + free(rlc_dec); + return SWIF_STATUS_OK; +} + +/** + * Internal function: map the decoded callback function of full_symbol + * to the one of swif_rlc_decoder, + **/ +static void rlc_decoder_notify_decoded( + swif_full_symbol_set_t *set, + symbol_id_t decoded_id, + void* dec) +{ + swif_decoder_rlc_cb_t *rlc_dec = (swif_decoder_rlc_cb_t *) dec; + /* PATCHED: silenced */ (void)decoded_id; + swif_full_symbol_t *full_symbol = full_symbol_set_get_pivot( + rlc_dec->symbol_set, + decoded_id); + + rlc_dec->decoded_source_symbol_callback( + rlc_dec->context_4_callback, + full_symbol->data, + (esi_t)decoded_id); // XXX: esi_t is different from symbol_id_t +} + + +/** + * Set the various callback functions for this decoder. + * All the callback functions require an opaque context parameter, that + * must be initialized accordingly by the application, since it is + * application specific. + */ +swif_status_t swif_rlc_decoder_set_callback_functions ( + swif_decoder_t* dec, + void (*source_symbol_removed_from_linear_system_callback) ( + void* context, + esi_t old_symbol_esi), + void* (*decodable_source_symbol_callback) ( + void *context, + esi_t esi), + void* (*decoded_source_symbol_callback) ( + void *context, + void *new_symbol_buf, + esi_t esi), + void* context_4_callback) +{ +// NOT YET + swif_decoder_rlc_cb_t *rlc_dec = (swif_decoder_rlc_cb_t *) dec; + rlc_dec->symbol_set->notify_context = context_4_callback ; + rlc_dec->context_4_callback = context_4_callback; + rlc_dec->decoded_source_symbol_callback = decoded_source_symbol_callback; + assert(rlc_dec->symbol_set != NULL); + rlc_dec->symbol_set->notify_decoded_func = rlc_decoder_notify_decoded; + rlc_dec->symbol_set->notify_context = (void*)rlc_dec; + return SWIF_STATUS_OK; +} + + +/** + * This function sets one or more FEC codec specific parameters, + * using a type/length/value approach for maximum flexibility. + */ +swif_status_t swif_rlc_decoder_set_parameters ( + swif_decoder_t* dec, + uint32_t type, + uint32_t length, + void* value) +{ +// NOT YET + return SWIF_STATUS_OK; +} + + +/** + * This function gets one or more FEC codec specific parameters, + * using a type/length/value approach for maximum flexibility. + */ +swif_status_t swif_rlc_decoder_get_parameters ( + swif_decoder_t* dec, + uint32_t type, + uint32_t length, + void* value) +{ +// NOT YET + return SWIF_STATUS_OK; +} + + +/** + * Submit a received source symbol and try to progress in the decoding. + * For each decoded source symbol (if any), the application is informed + * through the dedicated callback functions. + */ +swif_status_t swif_rlc_decoder_decode_with_new_source_symbol ( + swif_decoder_t* dec, + void* const new_symbol_buf, + esi_t new_symbol_esi) +{ + swif_decoder_rlc_cb_t *rlc_dec = (swif_decoder_rlc_cb_t *) dec; + + swif_full_symbol_t *full_symbol = full_symbol_create_from_source( + new_symbol_esi, new_symbol_buf, rlc_dec->symbol_size); + /* PATCHED: silenced */ + full_symbol_add_with_elimination(rlc_dec->symbol_set, full_symbol); + + full_symbol_free(full_symbol); + + //fprintf(stderr, "[XXX] not checking if too many stored symbols\n"); + return SWIF_STATUS_OK; +} + +/** + * Submit a received repair symbol and try to progress in the decoding. + * For each decoded source symbol (if any), the application is informed + * through the dedicated callback functions. + */ +swif_status_t swif_rlc_decoder_decode_with_new_repair_symbol ( + swif_decoder_t* dec, + void* const new_symbol_buf, + esi_t new_symbol_esi) +{ + + swif_decoder_rlc_cb_t *rlc_dec = (swif_decoder_rlc_cb_t *) dec; + //XXX; + swif_full_symbol_t *full_symbol = NULL; + full_symbol = full_symbol_create(rlc_dec->coef_tab, rlc_dec->first_id, rlc_dec->nb_id,new_symbol_buf, rlc_dec->symbol_size); + full_symbol_add_with_elimination(rlc_dec->symbol_set, full_symbol); + + full_symbol_free(full_symbol); + //fprintf(stderr, "[XXX] not checking if too many stored symbols\n"); + return SWIF_STATUS_OK; +} + + + +/******************************************************************************* + * Coding Window Functions at an Encoder and Decoder + */ + + +/** + * This function resets the current coding window. We assume here that + * this window is maintained by the FEC codec instance. + * Encoder: reset the encoding window for the encoding of future + * repair symbols. + * Decoder: reset the coding window under preparation associated to + * a repair symbol just received. + */ +swif_status_t swif_rlc_encoder_reset_coding_window (swif_encoder_t* enc) +{ +// NOT YET + return SWIF_STATUS_OK; +} + +swif_status_t swif_rlc_decoder_reset_coding_window (swif_decoder_t* dec) +{ +// NOT YET + swif_decoder_rlc_cb_t *rlc_dec = (swif_decoder_rlc_cb_t *) dec; + + + if (rlc_dec->coef_tab == NULL) { + /* free the structure in case of problem */ + uint8_t *coef + = (uint8_t *)calloc(rlc_dec->symbol_size , sizeof(uint8_t)); + rlc_dec->coef_tab = coef; + } + + memset(rlc_dec->coef_tab, 0, rlc_dec->symbol_size); + rlc_dec->first_id = SYMBOL_ID_NONE ; + rlc_dec->nb_id = 0 ; + return SWIF_STATUS_OK; +} + +/** + * Add this source symbol to the coding window. + * Encoder: add a source symbol to the coding window. + * Decoder: add a source symbol to the coding window under preparation. + */ +swif_status_t swif_rlc_encoder_add_source_symbol_to_coding_window ( + swif_encoder_t* generic_enc, + void* new_src_symbol_buf, + esi_t new_src_symbol_esi) +{ + swif_encoder_rlc_cb_t *enc = (swif_encoder_rlc_cb_t *) generic_enc; + + if ((enc->ew_esi_right != INVALID_ESI) && (new_src_symbol_esi != enc->ew_esi_right + 1)) { + fprintf(stderr, "swif_rlc_encoder_add_source_symbol_to_coding_window() failed! new_src_symbol_esi (%u) is not the expected value (%u)\n", + new_src_symbol_esi, enc->ew_esi_right + 1); + return SWIF_STATUS_ERROR; + } + if (enc->ew_ss_nb == enc->max_coding_window_size) { + if (enc->source_symbol_removed_from_coding_window_callback != NULL) { + enc->source_symbol_removed_from_coding_window_callback(enc->context_4_callback, + enc->ew_esi_right + 1 - enc->ew_ss_nb); + } + enc->ew_tab[enc->ew_left] = new_src_symbol_buf; + enc->ew_right = enc->ew_left; + enc->ew_left = (enc->ew_left +1) % enc->max_coding_window_size; + enc->ew_esi_right = new_src_symbol_esi; + } else if (enc->ew_ss_nb == 0) { + assert(enc->ew_left == enc->ew_right); + enc->ew_tab[enc->ew_right] = new_src_symbol_buf; + enc->ew_esi_right = new_src_symbol_esi; + enc->ew_ss_nb++; + } else { + enc->ew_right = (enc->ew_right + 1) % enc->max_coding_window_size; + enc->ew_tab[enc->ew_right] = new_src_symbol_buf; + enc->ew_esi_right = new_src_symbol_esi; + enc->ew_ss_nb++; + } + + return SWIF_STATUS_OK; +} + + +swif_status_t swif_rlc_decoder_add_source_symbol_to_coding_window ( + swif_decoder_t* dec, + esi_t new_src_symbol_esi) +{ +// NOT YET + swif_decoder_rlc_cb_t *rlc_dec = (swif_decoder_rlc_cb_t *) dec; + + if (rlc_dec->first_id == SYMBOL_ID_NONE) { + assert(rlc_dec->nb_id == 0); + rlc_dec->first_id = new_src_symbol_esi ; + } + if ((new_src_symbol_esi - rlc_dec->first_id) <= rlc_dec->max_coding_window_size) { + + //rlc_dec->coef_tab[new_src_symbol_esi - rlc_dec->first_id] = coef; + rlc_dec->nb_id++; + } else { + fprintf(stderr, "swif_rlc_decoder_add_source_symbol_to_coding_window() failed!"); + return SWIF_STATUS_ERROR; + } + return SWIF_STATUS_OK; + +} + + +/** + * Remove this source symbol from the coding window. + */ +swif_status_t swif_rlc_encoder_remove_source_symbol_from_coding_window ( + swif_encoder_t* enc, + esi_t old_src_symbol_esi) +{ +// NOT YET + return SWIF_STATUS_OK; +} + +swif_status_t swif_rlc_decoder_remove_source_symbol_from_coding_window ( + swif_decoder_t* dec, + esi_t old_src_symbol_esi) +{ +// NOT YET + return SWIF_STATUS_OK; +} + + +/** + * Get information on the current coding window at the encoder. + */ +swif_status_t swif_rlc_encoder_get_coding_window_information ( + swif_encoder_t* generic_encoder, + esi_t* first, + esi_t* last, + uint32_t* nss) +{ + swif_encoder_rlc_cb_t* enc = (swif_encoder_rlc_cb_t*) generic_encoder; + + *first = enc->ew_esi_right - enc->ew_ss_nb + 1; + *last = enc->ew_esi_right; + *nss = enc->ew_ss_nb; + return SWIF_STATUS_OK; +} + + +/******************************************************************************* + * Coding Coefficients Functions at an Encoder and Decoder + */ + + +/** + * Encoder: this function specifies the coding coefficients chosen by + * the application if this is the way the codec works. + * Decoder: communicate with this function the coding coefficients + * associated to a repair symbol and carried in the packet + * header. + */ +swif_status_t swif_rlc_encoder_set_coding_coefs_tab ( + swif_encoder_t* enc, + void* coding_coefs_tab, + uint32_t nb_coefs_in_tab) +{ + swif_encoder_rlc_cb_t *rlc_enc = (swif_encoder_rlc_cb_t *) enc; + assert(nb_coefs_in_tab <= rlc_enc->max_coding_window_size); + memcpy(rlc_enc->cc_tab, coding_coefs_tab, nb_coefs_in_tab*sizeof(uint8_t)); + return SWIF_STATUS_OK; +} + + +swif_status_t swif_rlc_decoder_set_coding_coefs_tab ( + swif_decoder_t* dec, + void* coding_coefs_tab, + uint32_t nb_coefs_in_tab) +{ +// NOT YET + return SWIF_STATUS_OK; +} + + +/** + * The coding coefficients may be generated in a deterministic manner, + * for instance by a PRNG known by the codec and a seed (perhaps with + * other parameters) provided by the application. + * The codec may also choose in an autonomous manner these coefficients. + * This function is used to trigger this process. + * When the choice is made in an autonomous manner, the actual coding + * coefficient or key used by the codec can be retrieved with + * swif_encoder_get_coding_coefs_tab(). + */ +swif_status_t swif_rlc_encoder_generate_coding_coefs ( + swif_encoder_t* enc, + uint32_t key, + uint32_t add_param) +{ + /* XXX: check why uint32_t key */ + DEBUG_PRINT("generate coding coefs: "); + swif_encoder_rlc_cb_t *rlc_enc = (swif_encoder_rlc_cb_t *) enc; + + if (rlc_enc->cc_tab == NULL) { + /* XXX: need to use allocation functions */ + rlc_enc->cc_tab = (uint8_t*) malloc( + rlc_enc->max_coding_window_size*sizeof(uint8_t) ); + if (rlc_enc->cc_tab == NULL) { + fprintf(stderr, "Error, swif_rlc_encoder_generate_" + "coding_coefs: malloc failed\n"); + return SWIF_STATUS_ERROR; + } + } + + assert(rlc_enc->ew_ss_nb <= rlc_enc->max_coding_window_size); + swif_rlc_generate_coding_coefficients ( + (uint16_t)key, rlc_enc->cc_tab, + rlc_enc->ew_ss_nb, /* upper bound: enc->max_window_size */ + 15 /* density dt [0-15] XXX dt=1*/, + 8 /*=m - GF(2^^m) */); + + return SWIF_STATUS_OK; +} + + +swif_status_t swif_rlc_decoder_generate_coding_coefs ( + swif_decoder_t* dec, + uint32_t key, + uint32_t add_param) +{ + // repair keys + /* XXX: check why uint32_t key */ + DEBUG_PRINT("generate coding coefs: "); + swif_decoder_rlc_cb_t *rlc_dec = (swif_decoder_rlc_cb_t *) dec; + if (rlc_dec->coef_tab == NULL) { + /* XXX: need to use allocation functions */ + rlc_dec->coef_tab = (uint8_t*) malloc( + rlc_dec->max_coding_window_size*sizeof(uint8_t) ); + if (rlc_dec->coef_tab == NULL) { + fprintf(stderr, "Error, swif_rlc_decoder_generate_" + "coding_coefs: malloc failed\n"); + return SWIF_STATUS_ERROR; + } + } + + assert(rlc_dec->nb_id <= rlc_dec->max_coding_window_size); + swif_rlc_generate_coding_coefficients ( + (uint16_t)key, rlc_dec->coef_tab, + rlc_dec->nb_id, /* upper bound: enc->max_window_size */ + 15 /* density dt [0-15] XXX dt=1*/ , + 8 /*=m - GF(2^^m) */); + DEBUG_DUMP(rlc_dec->coef_tab, rlc_dec->nb_id); + return SWIF_STATUS_OK; +} + + +/** + * This function enables the application to retrieve the set of coding + * coefficients generated and used by build_repair_symbol(). This is + * useful when the choice of coefficients is performed by the codec in + * an autonomous manner but needs to be sent in the repair packet header. + * This function is only used by an encoder. + */ +swif_status_t swif_rlc_encoder_get_coding_coefs_tab ( + swif_encoder_t* enc, + void** coding_coefs_tab, + uint32_t* nb_coefs_in_tab) +{ +// NOT YET + return SWIF_STATUS_OK; +} + + +/******************************************************************************* + * Session creation functions (last position to avoid compilation errors for + * codec specific functions and avoid the need to add prototypes in header). + */ + +/** + * Create and initialize an encoder, providing only key parameters. + **/ +swif_encoder_t* swif_rlc_encoder_create (swif_codepoint_t codepoint, + uint32_t verbosity, + uint32_t symbol_size, + uint32_t max_coding_window_size) +{ + swif_encoder_rlc_cb_t* enc; + + /* initialize the encoder */ + assert(codepoint == SWIF_CODEPOINT_RLC_GF_256_FULL_DENSITY_CODEC); + if ((enc = calloc(1,sizeof(swif_encoder_rlc_cb_t))) == NULL){ + fprintf(stderr, "swif_encoder_create() failed! No memory \n"); + return NULL; + } + enc->generic_encoder.codepoint = codepoint; + enc->symbol_size = symbol_size; + enc->max_coding_window_size = max_coding_window_size; + if ((enc->cc_tab = calloc(max_coding_window_size, sizeof(uint8_t))) == NULL){ + fprintf(stderr, "swif_encoder_create cc_tab failed! No memory \n"); + return NULL; + } + + if ((enc->ew_tab = calloc(max_coding_window_size, sizeof(uintptr_t))) == NULL){ + fprintf(stderr, "swif_encoder_create ew_tab failed! No memory \n"); + return NULL; + } + enc->ew_right = enc->ew_left = 0; + enc->ew_esi_right = INVALID_ESI; + enc->ew_ss_nb = 0; + + enc->source_symbol_removed_from_coding_window_callback = NULL; + enc->context_4_callback = NULL; + + enc->generic_encoder.set_callback_functions = swif_rlc_encoder_set_callback_functions; + enc->generic_encoder.set_parameters = swif_rlc_encoder_set_parameters; + enc->generic_encoder.get_parameters = swif_rlc_encoder_get_parameters; + enc->generic_encoder.build_repair_symbol = swif_rlc_build_repair_symbol; + enc->generic_encoder.reset_coding_window = swif_rlc_encoder_reset_coding_window; + enc->generic_encoder.add_source_symbol_to_coding_window = swif_rlc_encoder_add_source_symbol_to_coding_window; + enc->generic_encoder.remove_source_symbol_from_coding_window = swif_rlc_encoder_remove_source_symbol_from_coding_window; + enc->generic_encoder.get_coding_window_information = swif_rlc_encoder_get_coding_window_information; + enc->generic_encoder.set_coding_coefs_tab = swif_rlc_encoder_set_coding_coefs_tab; + enc->generic_encoder.generate_coding_coefs = swif_rlc_encoder_generate_coding_coefs; + enc->generic_encoder.get_coding_coefs_tab = swif_rlc_encoder_get_coding_coefs_tab; + return (swif_encoder_t *) enc; +} + + +/** + * Create and initialize a decoder, providing only key parameters. + */ +swif_decoder_t* swif_rlc_decoder_create ( + swif_codepoint_t codepoint, + uint32_t verbosity, + uint32_t symbol_size, + uint32_t max_coding_window_size, + uint32_t max_linear_system_size) +{ + swif_decoder_rlc_cb_t* dec; + + /* initialize the decoder */ + assert(codepoint == SWIF_CODEPOINT_RLC_GF_256_FULL_DENSITY_CODEC); + if ((dec = calloc(1,sizeof(swif_decoder_rlc_cb_t))) == NULL) { + fprintf(stderr, "swif_decoder_create() failed! No memory \n"); + return NULL; + } + dec->generic_decoder.codepoint = codepoint; + dec->symbol_size = symbol_size; + dec->max_coding_window_size = max_coding_window_size; + dec->max_linear_system_size = max_linear_system_size; + dec->symbol_set = full_symbol_set_alloc(); +#if 0 + dec->ew_right = dec->ew_left = 0; + dec->ew_esi_right = INVALID_ESI; + dec->ew_ss_nb = 0; +#endif + + dec->source_symbol_removed_from_linear_system_callback = NULL; + dec->decodable_source_symbol_callback = NULL; + dec->decoded_source_symbol_callback = NULL; + dec->context_4_callback = NULL; + + dec->generic_decoder.set_callback_functions = swif_rlc_decoder_set_callback_functions; + dec->generic_decoder.set_parameters = swif_rlc_decoder_set_parameters; + dec->generic_decoder.get_parameters = swif_rlc_decoder_get_parameters; + dec->generic_decoder.decode_with_new_source_symbol = swif_rlc_decoder_decode_with_new_source_symbol; + dec->generic_decoder.decode_with_new_repair_symbol = swif_rlc_decoder_decode_with_new_repair_symbol; + dec->generic_decoder.reset_coding_window = swif_rlc_decoder_reset_coding_window; + dec->generic_decoder.add_source_symbol_to_coding_window = swif_rlc_decoder_add_source_symbol_to_coding_window; + dec->generic_decoder.remove_source_symbol_from_coding_window = swif_rlc_decoder_remove_source_symbol_from_coding_window; + dec->generic_decoder.set_coding_coefs_tab = swif_rlc_decoder_set_coding_coefs_tab; + dec->generic_decoder.generate_coding_coefs = swif_rlc_decoder_generate_coding_coefs; + return (swif_decoder_t *) dec; +} + diff --git a/tools/precoder/vendor/swif-codec/src/swif_rlc_api.h b/tools/precoder/vendor/swif-codec/src/swif_rlc_api.h new file mode 100644 index 0000000..3b2a036 --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_rlc_api.h @@ -0,0 +1,269 @@ +#ifndef SWIF_RLC_API_H +#define SWIF_RLC_API_H +#include "swif_includes.h" + + +/******************************************************************************* + * Encoder functions + */ + + +/** + * Release an encoder and its associated ressources. + **/ +swif_status_t swif_rlc_encoder_release (swif_encoder_t* enc); + + +/** + * Set the various callback functions for this encoder. + * All the callback functions require an opaque context parameter, that must be + * initialized accordingly by the application, since it is application specific. + */ +swif_status_t swif_rlc_encoder_set_callback_functions ( + swif_encoder_t* enc, + void (*source_symbol_removed_from_coding_window_callback) ( + void* context, + esi_t old_symbol_esi), + void* context_4_callback); + + +/** + * This function sets one or more FEC codec specific parameters, + * using a type/length/value approach for maximum flexibility. + */ +swif_status_t swif_rlc_encoder_set_parameters ( + swif_encoder_t* enc, + uint32_t type, + uint32_t length, + void* value); + +/** + * This function gets one or more FEC codec specific parameters, + * using a type/length/value approach for maximum flexibility. + */ +swif_status_t swif_rlc_encoder_get_parameters ( + swif_encoder_t* enc, + uint32_t type, + uint32_t length, + void* value); + + +/** + * Create a single repair symbol (i.e. perform an encoding). + */ +swif_status_t swif_rlc_build_repair_symbol ( + swif_encoder_t* generic_encoder, + void** new_buf); + + +/******************************************************************************* + * Decoder functions + */ + + +/** + * Release a decoder and its associated ressources. + **/ +swif_status_t swif_rlc_decoder_release (swif_decoder_t* dec); + + +/** + * Set the various callback functions for this decoder. + * All the callback functions require an opaque context parameter, that + * must be initialized accordingly by the application, since it is + * application specific. + */ +swif_status_t swif_rlc_decoder_set_callback_functions ( + swif_decoder_t* dec, + void (*source_symbol_removed_from_linear_system_callback) ( + void* context, + esi_t old_symbol_esi), + void* (*decodable_source_symbol_callback) ( + void *context, + esi_t esi), + void* (*decoded_source_symbol_callback) ( + void *context, + void *new_symbol_buf, + esi_t esi), + void* context_4_callback); + + +/** + * This function sets one or more FEC codec specific parameters, + * using a type/length/value approach for maximum flexibility. + */ +swif_status_t swif_rlc_decoder_set_parameters ( + swif_decoder_t* dec, + uint32_t type, + uint32_t length, + void* value); + + +/** + * This function gets one or more FEC codec specific parameters, + * using a type/length/value approach for maximum flexibility. + */ +swif_status_t swif_rlc_decoder_get_parameters ( + swif_decoder_t* dec, + uint32_t type, + uint32_t length, + void* value); + + +/** + * Submit a received source symbol and try to progress in the decoding. + * For each decoded source symbol (if any), the application is informed + * through the dedicated callback functions. + */ +swif_status_t swif_rlc_decoder_decode_with_new_source_symbol ( + swif_decoder_t* dec, + void* const new_symbol_buf, + esi_t new_symbol_esi); + + +/** + * Submit a received repair symbol and try to progress in the decoding. + * For each decoded source symbol (if any), the application is informed + * through the dedicated callback functions. + */ +swif_status_t swif_rlc_decoder_decode_with_new_repair_symbol ( + swif_decoder_t* dec, + void* const new_symbol_buf, + esi_t new_symbol_esi); + +/******************************************************************************* + * Coding Window Functions at an Encoder and Decoder + */ + + +/** + * This function resets the current coding window. We assume here that + * this window is maintained by the FEC codec instance. + * Encoder: reset the encoding window for the encoding of future + * repair symbols. + * Decoder: reset the coding window under preparation associated to + * a repair symbol just received. + */ +swif_status_t swif_rlc_encoder_reset_coding_window (swif_encoder_t* enc); + +swif_status_t swif_rlc_decoder_reset_coding_window (swif_decoder_t* dec); + +/** + * Add this source symbol to the coding window. + * Encoder: add a source symbol to the coding window. + * Decoder: add a source symbol to the coding window under preparation. + */ +swif_status_t swif_rlc_encoder_add_source_symbol_to_coding_window ( + swif_encoder_t* generic_enc, + void* new_src_symbol_buf, + esi_t new_src_symbol_esi); + +swif_status_t swif_rlc_decoder_add_source_symbol_to_coding_window ( + swif_decoder_t* dec, + esi_t new_src_symbol_esi); + + +/** + * Remove this source symbol from the coding window. + */ +swif_status_t swif_rlc_encoder_remove_source_symbol_from_coding_window ( + swif_encoder_t* enc, + esi_t old_src_symbol_esi); + +swif_status_t swif_rlc_decoder_remove_source_symbol_from_coding_window ( + swif_decoder_t* dec, + esi_t old_src_symbol_esi); + + +/** + * Get information on the current coding window at the encoder. + */ +swif_status_t swif_rlc_encoder_get_coding_window_information ( + swif_encoder_t* generic_encoder, + esi_t* first, + esi_t* last, + uint32_t* nss); + + +/******************************************************************************* + * Coding Coefficients Functions at an Encoder and Decoder + */ + + +/** + * Encoder: this function specifies the coding coefficients chosen by + * the application if this is the way the codec works. + * Decoder: communicate with this function the coding coefficients + * associated to a repair symbol and carried in the packet + * header. + */ +swif_status_t swif_rlc_encoder_set_coding_coefs_tab ( + swif_encoder_t* enc, + void* coding_coefs_tab, + uint32_t nb_coefs_in_tab); + + +swif_status_t swif_rlc_decoder_set_coding_coefs_tab ( + swif_decoder_t* dec, + void* coding_coefs_tab, + uint32_t nb_coefs_in_tab); + +/** + * The coding coefficients may be generated in a deterministic manner, + * for instance by a PRNG known by the codec and a seed (perhaps with + * other parameters) provided by the application. + * The codec may also choose in an autonomous manner these coefficients. + * This function is used to trigger this process. + * When the choice is made in an autonomous manner, the actual coding + * coefficient or key used by the codec can be retrieved with + * swif_encoder_get_coding_coefs_tab(). + */ +swif_status_t swif_rlc_encoder_generate_coding_coefs ( + swif_encoder_t* enc, + uint32_t key, + uint32_t add_param); + + +swif_status_t swif_rlc_decoder_generate_coding_coefs ( + swif_decoder_t* dec, + uint32_t key, + uint32_t add_param); + + +/** + * This function enables the application to retrieve the set of coding + * coefficients generated and used by build_repair_symbol(). This is + * useful when the choice of coefficients is performed by the codec in + * an autonomous manner but needs to be sent in the repair packet header. + * This function is only used by an encoder. + */ +swif_status_t swif_rlc_encoder_get_coding_coefs_tab ( + swif_encoder_t* enc, + void** coding_coefs_tab, + uint32_t* nb_coefs_in_tab); + + +/******************************************************************************* + * Session creation functions (last position to avoid compilation errors for + * codec specific functions and avoid the need to add prototypes in header). + */ + +/** + * Create and initialize an encoder, providing only key parameters. + **/ +swif_encoder_t* swif_rlc_encoder_create (swif_codepoint_t codepoint, + uint32_t verbosity, + uint32_t symbol_size, + uint32_t max_coding_window_size); + + +/** + * Create and initialize a decoder, providing only key parameters. + */ +swif_decoder_t* swif_rlc_decoder_create ( + swif_codepoint_t codepoint, + uint32_t verbosity, + uint32_t symbol_size, + uint32_t max_coding_window_size, + uint32_t max_linear_system_size); +#endif diff --git a/tools/precoder/vendor/swif-codec/src/swif_rlc_cb.h b/tools/precoder/vendor/swif-codec/src/swif_rlc_cb.h new file mode 100644 index 0000000..785bd5e --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_rlc_cb.h @@ -0,0 +1,115 @@ +/** + * SWiF Codec: an open-source sliding window FEC codec in C + * https://github.com/irtf-nwcrg/swif-codec + */ + +#include "swif_full_symbol.h" + +/** + * Control block for an RLC encoder. + * Encoder structure that contains whatever is needed for encoding. + * The first field of this structure is the generic swif encoder + * so that one can cast a pointer to one of the two structures, + * depending on the context. + */ +typedef struct swif_encoder_rlc_cb { + /* generic part of any control block. MUST be first in structure */ + swif_encoder_t generic_encoder; + + /* desired verbosity: 0 is the minimum verbosity, the maximum + * level being implementation specific. */ + uint32_t verbosity; + + /* maximum number of source symbols used for any repair symbol */ + uint32_t max_coding_window_size; + + /* exact size (in bytes) of any source or repair symbol */ + uint32_t symbol_size; + + /* coding coefficients table. To be initialized before building a new repair symbol */ + uint8_t* cc_tab; + + /* pointer to the table containing source symbols */ + void** ew_tab; + + /* the index of the firt source symbol (included) */ + uint32_t ew_left; + + /* the index of the last source symbol added (included) */ + uint32_t ew_right; + + /** identifier of the last source symbol added + * we suppose that our source symbols are ordered + */ + esi_t ew_esi_right; + + /** number of source currently in the encoding window + * useful to differentiate the state of the buffer + */ + uint32_t ew_ss_nb; + + void (*source_symbol_removed_from_coding_window_callback) ( + void* context, + esi_t old_symbol_esi); + + void* context_4_callback; + /* add whatever may be needed hereafter... */ +} swif_encoder_rlc_cb_t; + + +/** + * Control block for an RLC decoder. + * Decoder structure that contains whatever is needed for decoding. + * The first field of this structure is the generic swif decoder + * so that one can cast a pointer to one of the two structures, + * depending on the context. + */ +typedef struct swif_decoder_rlc_cb { + /* generic part of any control block. MUST be first in structure */ + swif_decoder_t generic_decoder; + + /* desired verbosity: 0 is the minimum verbosity, the maximum + * level being implementation specific. */ + uint32_t verbosity; + + /* maximum number of source symbols used for any repair symbol */ + uint32_t max_coding_window_size; + + /* max. number of source symbols kepts in current linear system. + * If the linear system grows above this limit, old source + * symbols in excess are removed and the application callback + * called. This value should be larger than the + * max_coding_window_size. */ + uint32_t max_linear_system_size; + + /* exact size (in bytes) of any source or repair symbol */ + uint32_t symbol_size; + + /* set of packets being decoded through gaussian elimination */ + swif_full_symbol_set_t *symbol_set; + + /* coding coefficients table. To be initialized before building a new repair symbol */ + uint8_t* coef_tab; + /* the index of the first source symbol (included) */ + uint32_t first_id; + /** number of symbols currently in the encoding window + * useful to differentiate the state of the buffer + */ + uint32_t nb_id; + + void (*source_symbol_removed_from_linear_system_callback) ( + void* context, + esi_t old_symbol_esi); + void* (*decodable_source_symbol_callback) ( + void *context, + esi_t esi); + void* (*decoded_source_symbol_callback) ( + void *context, + void *new_symbol_buf, + esi_t esi); + + void* context_4_callback; + + + /* add whatever may be needed hereafter... */ +} swif_decoder_rlc_cb_t; diff --git a/tools/precoder/vendor/swif-codec/src/swif_symbol.c b/tools/precoder/vendor/swif-codec/src/swif_symbol.c new file mode 100644 index 0000000..af6014d --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_symbol.c @@ -0,0 +1,119 @@ +/** + * SWiF Codec: an open-source sliding window FEC codec in C + * https://github.com/irtf-nwcrg/swif-codec + */ + +/*---------------------------------------------------------------------------*/ + +#include +#include "swif_symbol.h" + +/*---------------------------------------------------------------------------*/ + +#include "swif_table-mul-gf256.c" + +/* gf256_add and gf256_sub are inline */ + +uint8_t gf256_mul(uint8_t a, uint8_t b) +{ + return gf256_mul_table[a][b]; +} + +uint8_t gf256_inv(uint8_t a) +{ + return gf256_inv_table[a]; +} + +uint8_t gf256_div(uint8_t a, uint8_t b) +{ + return gf256_mul(a, gf256_inv(b)); +} + +/*---------------------------------------------------------------------------*/ + +/** + * @brief Take a symbol and add another symbol multiplied by a + * coefficient, e.g. performs the equivalent of: p1 += coef * p2 + * @param[in] symbol1 First symbol (to which coef*symbol2 will be added) + * @param[in] coef Coefficient by which the second packet is multiplied + * @param[in] symbol2 Second symbol + * @param[out] result Symbol where the result is stored + */ +void symbol_add_scaled +(void *symbol1, uint8_t coef, void *symbol2, uint32_t symbol_size) +{ + uint8_t *data1 = (uint8_t *) symbol1; + uint8_t *data2 = (uint8_t *) symbol2; + for (uint32_t i=0; i + * @author Cedric Adjih + */ + +/** + * SWiF Codec: + * https://github.com/irtf-nwcrg/swif-codec + */ + +#ifndef __SWIF_SYMBOL_H__ +#define __SWIF_SYMBOL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/*---------------------------------------------------------------------------*/ +/* + * Operations in GF(2^8) + */ + +/* Add two numbers in a GF(2^8) finite field: a+b + * GF(2^8) is of characteristic 2, so 1 + 1 = 0, and addition, + * subtraction and exclusive-or are all the same. */ +static inline uint8_t gf256_add(uint8_t a, uint8_t b) +{ return a^b; } + +/* Subtract two numbers in a GF(2^8) finite field: a-b */ +static inline uint8_t gf256_sub(uint8_t a, uint8_t b) +{ return gf256_add(a,b); } + +/* Get the inverse of an element in a GF(2^8) finite field: 1/a + note: returns 0 for element 0 (instead of an exception) */ +uint8_t gf256_inv(uint8_t a); + +/* Divide two elements in the finite field GF(2^8): a/b + note: returns 0 if `b' is 0 (instead of an exception) */ +uint8_t gf256_div(uint8_t a, uint8_t b); + +/* Multiply two elements in the finite field GF(2^8): a*b + note: returns 0 if `b' is 0 (instead of an exception) */ +uint8_t gf256_mul(uint8_t a, uint8_t b); + +/*---------------------------------------------------------------------------*/ + +/* invariant: the functions below work with NULL pointers to symbol + iff symbol_size is 0 (as they will not actually dereference the pointer) */ + +/** + * @brief Take a symbol and add another symbol multiplied by a + * coefficient, e.g. performs the equivalent of: p1 += coef * p2 + * @param[in] symbol1 First symbol (to which coef*symbol2 will be added) + * @param[in] coef Coefficient by which the second packet is multiplied + * @param[in] symbol2 Second symbol + * @param[out] result Symbol where the result is stored + */ +void symbol_add_scaled +(void *symbol1, uint8_t coef, void *symbol2, uint32_t symbol_size); + + +/** + * @brief Take a symbol and add another symbol to it, + * e.g. performs the equivalent of: result = symbol1 + symbol2 + * @param[in] symbol1 First symbol (to which symbol2 will be added) + * @param[in] symbol2 Second symbol + * @param[out] result Symbol where the result is stored + */ +void symbol_add +(void *symbol1, void *symbol2, uint32_t symbol_size, uint8_t* result); + + +/** + * @brief Take a symbol and subtract another symbol to it, + * e.g. performs the equivalent of: result = p1 - p2 + * @param[in] symbol1 First symbol (to which symbol2 will be subtracted) + * @param[in] symbol2 Second symbol + * @param[out] result Symbol where the result is stored + */ +void symbol_sub +(void *symbol1, void *symbol2, uint32_t symbol_size, uint8_t* result); + + +/** + * @brief Take a symbol and multiply it by a coefficient, + * e.g. performs the equivalent of: result = coef * p1 + * @param[in] symbol1 Initial symbol + * @param[in] coeff Coefficient by which the symbol is multiplied (scaled) + * @param[out] result Symbol where the result is stored + */ +void symbol_mul +(void *symbol1, uint8_t coeff, uint32_t symbol_size, uint8_t* result); + + +/** + * @brief Take a symbol and divide it by a coefficient, + * e.g. performs the equivalent of: result = (1/coeff) * p1 + * @param[in] symbol1 Initial symbol + * @param[in] coeff Coefficient by which the symbol is divided + * @param[out] result Symbol where the result is stored + * Note: there is an assertion `assert(coeff != 0)' + */ +void symbol_div +(void *symbol1, uint32_t symbol_size, uint8_t coeff, uint8_t* result); + + +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __SWIF_SYMBOL_H__ */ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/tools/precoder/vendor/swif-codec/src/swif_table-mul-gf256.c b/tools/precoder/vendor/swif-codec/src/swif_table-mul-gf256.c new file mode 100644 index 0000000..b745b0c --- /dev/null +++ b/tools/precoder/vendor/swif-codec/src/swif_table-mul-gf256.c @@ -0,0 +1,8256 @@ +/* + File automatically generated by: + python3 writeGaloisFieldTable.py 8 +--------------------------------------------------------------------------- + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------------------------- +*/ + +#include + +static const uint8_t gf256_mul_table[256][256] = { + { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 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, 61, 62, 63, + 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, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255 }, + { 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 48, 50, 52, 54, 56, 58, 60, 62, + 64, 66, 68, 70, 72, 74, 76, 78, + 80, 82, 84, 86, 88, 90, 92, 94, + 96, 98, 100, 102, 104, 106, 108, 110, + 112, 114, 116, 118, 120, 122, 124, 126, + 128, 130, 132, 134, 136, 138, 140, 142, + 144, 146, 148, 150, 152, 154, 156, 158, + 160, 162, 164, 166, 168, 170, 172, 174, + 176, 178, 180, 182, 184, 186, 188, 190, + 192, 194, 196, 198, 200, 202, 204, 206, + 208, 210, 212, 214, 216, 218, 220, 222, + 224, 226, 228, 230, 232, 234, 236, 238, + 240, 242, 244, 246, 248, 250, 252, 254, + 29, 31, 25, 27, 21, 23, 17, 19, + 13, 15, 9, 11, 5, 7, 1, 3, + 61, 63, 57, 59, 53, 55, 49, 51, + 45, 47, 41, 43, 37, 39, 33, 35, + 93, 95, 89, 91, 85, 87, 81, 83, + 77, 79, 73, 75, 69, 71, 65, 67, + 125, 127, 121, 123, 117, 119, 113, 115, + 109, 111, 105, 107, 101, 103, 97, 99, + 157, 159, 153, 155, 149, 151, 145, 147, + 141, 143, 137, 139, 133, 135, 129, 131, + 189, 191, 185, 187, 181, 183, 177, 179, + 173, 175, 169, 171, 165, 167, 161, 163, + 221, 223, 217, 219, 213, 215, 209, 211, + 205, 207, 201, 203, 197, 199, 193, 195, + 253, 255, 249, 251, 245, 247, 241, 243, + 237, 239, 233, 235, 229, 231, 225, 227 }, + { 0, 3, 6, 5, 12, 15, 10, 9, + 24, 27, 30, 29, 20, 23, 18, 17, + 48, 51, 54, 53, 60, 63, 58, 57, + 40, 43, 46, 45, 36, 39, 34, 33, + 96, 99, 102, 101, 108, 111, 106, 105, + 120, 123, 126, 125, 116, 119, 114, 113, + 80, 83, 86, 85, 92, 95, 90, 89, + 72, 75, 78, 77, 68, 71, 66, 65, + 192, 195, 198, 197, 204, 207, 202, 201, + 216, 219, 222, 221, 212, 215, 210, 209, + 240, 243, 246, 245, 252, 255, 250, 249, + 232, 235, 238, 237, 228, 231, 226, 225, + 160, 163, 166, 165, 172, 175, 170, 169, + 184, 187, 190, 189, 180, 183, 178, 177, + 144, 147, 150, 149, 156, 159, 154, 153, + 136, 139, 142, 141, 132, 135, 130, 129, + 157, 158, 155, 152, 145, 146, 151, 148, + 133, 134, 131, 128, 137, 138, 143, 140, + 173, 174, 171, 168, 161, 162, 167, 164, + 181, 182, 179, 176, 185, 186, 191, 188, + 253, 254, 251, 248, 241, 242, 247, 244, + 229, 230, 227, 224, 233, 234, 239, 236, + 205, 206, 203, 200, 193, 194, 199, 196, + 213, 214, 211, 208, 217, 218, 223, 220, + 93, 94, 91, 88, 81, 82, 87, 84, + 69, 70, 67, 64, 73, 74, 79, 76, + 109, 110, 107, 104, 97, 98, 103, 100, + 117, 118, 115, 112, 121, 122, 127, 124, + 61, 62, 59, 56, 49, 50, 55, 52, + 37, 38, 35, 32, 41, 42, 47, 44, + 13, 14, 11, 8, 1, 2, 7, 4, + 21, 22, 19, 16, 25, 26, 31, 28 }, + { 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, + 64, 68, 72, 76, 80, 84, 88, 92, + 96, 100, 104, 108, 112, 116, 120, 124, + 128, 132, 136, 140, 144, 148, 152, 156, + 160, 164, 168, 172, 176, 180, 184, 188, + 192, 196, 200, 204, 208, 212, 216, 220, + 224, 228, 232, 236, 240, 244, 248, 252, + 29, 25, 21, 17, 13, 9, 5, 1, + 61, 57, 53, 49, 45, 41, 37, 33, + 93, 89, 85, 81, 77, 73, 69, 65, + 125, 121, 117, 113, 109, 105, 101, 97, + 157, 153, 149, 145, 141, 137, 133, 129, + 189, 185, 181, 177, 173, 169, 165, 161, + 221, 217, 213, 209, 205, 201, 197, 193, + 253, 249, 245, 241, 237, 233, 229, 225, + 58, 62, 50, 54, 42, 46, 34, 38, + 26, 30, 18, 22, 10, 14, 2, 6, + 122, 126, 114, 118, 106, 110, 98, 102, + 90, 94, 82, 86, 74, 78, 66, 70, + 186, 190, 178, 182, 170, 174, 162, 166, + 154, 158, 146, 150, 138, 142, 130, 134, + 250, 254, 242, 246, 234, 238, 226, 230, + 218, 222, 210, 214, 202, 206, 194, 198, + 39, 35, 47, 43, 55, 51, 63, 59, + 7, 3, 15, 11, 23, 19, 31, 27, + 103, 99, 111, 107, 119, 115, 127, 123, + 71, 67, 79, 75, 87, 83, 95, 91, + 167, 163, 175, 171, 183, 179, 191, 187, + 135, 131, 143, 139, 151, 147, 159, 155, + 231, 227, 239, 235, 247, 243, 255, 251, + 199, 195, 207, 203, 215, 211, 223, 219 }, + { 0, 5, 10, 15, 20, 17, 30, 27, + 40, 45, 34, 39, 60, 57, 54, 51, + 80, 85, 90, 95, 68, 65, 78, 75, + 120, 125, 114, 119, 108, 105, 102, 99, + 160, 165, 170, 175, 180, 177, 190, 187, + 136, 141, 130, 135, 156, 153, 150, 147, + 240, 245, 250, 255, 228, 225, 238, 235, + 216, 221, 210, 215, 204, 201, 198, 195, + 93, 88, 87, 82, 73, 76, 67, 70, + 117, 112, 127, 122, 97, 100, 107, 110, + 13, 8, 7, 2, 25, 28, 19, 22, + 37, 32, 47, 42, 49, 52, 59, 62, + 253, 248, 247, 242, 233, 236, 227, 230, + 213, 208, 223, 218, 193, 196, 203, 206, + 173, 168, 167, 162, 185, 188, 179, 182, + 133, 128, 143, 138, 145, 148, 155, 158, + 186, 191, 176, 181, 174, 171, 164, 161, + 146, 151, 152, 157, 134, 131, 140, 137, + 234, 239, 224, 229, 254, 251, 244, 241, + 194, 199, 200, 205, 214, 211, 220, 217, + 26, 31, 16, 21, 14, 11, 4, 1, + 50, 55, 56, 61, 38, 35, 44, 41, + 74, 79, 64, 69, 94, 91, 84, 81, + 98, 103, 104, 109, 118, 115, 124, 121, + 231, 226, 237, 232, 243, 246, 249, 252, + 207, 202, 197, 192, 219, 222, 209, 212, + 183, 178, 189, 184, 163, 166, 169, 172, + 159, 154, 149, 144, 139, 142, 129, 132, + 71, 66, 77, 72, 83, 86, 89, 92, + 111, 106, 101, 96, 123, 126, 113, 116, + 23, 18, 29, 24, 3, 6, 9, 12, + 63, 58, 53, 48, 43, 46, 33, 36 }, + { 0, 6, 12, 10, 24, 30, 20, 18, + 48, 54, 60, 58, 40, 46, 36, 34, + 96, 102, 108, 106, 120, 126, 116, 114, + 80, 86, 92, 90, 72, 78, 68, 66, + 192, 198, 204, 202, 216, 222, 212, 210, + 240, 246, 252, 250, 232, 238, 228, 226, + 160, 166, 172, 170, 184, 190, 180, 178, + 144, 150, 156, 154, 136, 142, 132, 130, + 157, 155, 145, 151, 133, 131, 137, 143, + 173, 171, 161, 167, 181, 179, 185, 191, + 253, 251, 241, 247, 229, 227, 233, 239, + 205, 203, 193, 199, 213, 211, 217, 223, + 93, 91, 81, 87, 69, 67, 73, 79, + 109, 107, 97, 103, 117, 115, 121, 127, + 61, 59, 49, 55, 37, 35, 41, 47, + 13, 11, 1, 7, 21, 19, 25, 31, + 39, 33, 43, 45, 63, 57, 51, 53, + 23, 17, 27, 29, 15, 9, 3, 5, + 71, 65, 75, 77, 95, 89, 83, 85, + 119, 113, 123, 125, 111, 105, 99, 101, + 231, 225, 235, 237, 255, 249, 243, 245, + 215, 209, 219, 221, 207, 201, 195, 197, + 135, 129, 139, 141, 159, 153, 147, 149, + 183, 177, 187, 189, 175, 169, 163, 165, + 186, 188, 182, 176, 162, 164, 174, 168, + 138, 140, 134, 128, 146, 148, 158, 152, + 218, 220, 214, 208, 194, 196, 206, 200, + 234, 236, 230, 224, 242, 244, 254, 248, + 122, 124, 118, 112, 98, 100, 110, 104, + 74, 76, 70, 64, 82, 84, 94, 88, + 26, 28, 22, 16, 2, 4, 14, 8, + 42, 44, 38, 32, 50, 52, 62, 56 }, + { 0, 7, 14, 9, 28, 27, 18, 21, + 56, 63, 54, 49, 36, 35, 42, 45, + 112, 119, 126, 121, 108, 107, 98, 101, + 72, 79, 70, 65, 84, 83, 90, 93, + 224, 231, 238, 233, 252, 251, 242, 245, + 216, 223, 214, 209, 196, 195, 202, 205, + 144, 151, 158, 153, 140, 139, 130, 133, + 168, 175, 166, 161, 180, 179, 186, 189, + 221, 218, 211, 212, 193, 198, 207, 200, + 229, 226, 235, 236, 249, 254, 247, 240, + 173, 170, 163, 164, 177, 182, 191, 184, + 149, 146, 155, 156, 137, 142, 135, 128, + 61, 58, 51, 52, 33, 38, 47, 40, + 5, 2, 11, 12, 25, 30, 23, 16, + 77, 74, 67, 68, 81, 86, 95, 88, + 117, 114, 123, 124, 105, 110, 103, 96, + 167, 160, 169, 174, 187, 188, 181, 178, + 159, 152, 145, 150, 131, 132, 141, 138, + 215, 208, 217, 222, 203, 204, 197, 194, + 239, 232, 225, 230, 243, 244, 253, 250, + 71, 64, 73, 78, 91, 92, 85, 82, + 127, 120, 113, 118, 99, 100, 109, 106, + 55, 48, 57, 62, 43, 44, 37, 34, + 15, 8, 1, 6, 19, 20, 29, 26, + 122, 125, 116, 115, 102, 97, 104, 111, + 66, 69, 76, 75, 94, 89, 80, 87, + 10, 13, 4, 3, 22, 17, 24, 31, + 50, 53, 60, 59, 46, 41, 32, 39, + 154, 157, 148, 147, 134, 129, 136, 143, + 162, 165, 172, 171, 190, 185, 176, 183, + 234, 237, 228, 227, 246, 241, 248, 255, + 210, 213, 220, 219, 206, 201, 192, 199 }, + { 0, 8, 16, 24, 32, 40, 48, 56, + 64, 72, 80, 88, 96, 104, 112, 120, + 128, 136, 144, 152, 160, 168, 176, 184, + 192, 200, 208, 216, 224, 232, 240, 248, + 29, 21, 13, 5, 61, 53, 45, 37, + 93, 85, 77, 69, 125, 117, 109, 101, + 157, 149, 141, 133, 189, 181, 173, 165, + 221, 213, 205, 197, 253, 245, 237, 229, + 58, 50, 42, 34, 26, 18, 10, 2, + 122, 114, 106, 98, 90, 82, 74, 66, + 186, 178, 170, 162, 154, 146, 138, 130, + 250, 242, 234, 226, 218, 210, 202, 194, + 39, 47, 55, 63, 7, 15, 23, 31, + 103, 111, 119, 127, 71, 79, 87, 95, + 167, 175, 183, 191, 135, 143, 151, 159, + 231, 239, 247, 255, 199, 207, 215, 223, + 116, 124, 100, 108, 84, 92, 68, 76, + 52, 60, 36, 44, 20, 28, 4, 12, + 244, 252, 228, 236, 212, 220, 196, 204, + 180, 188, 164, 172, 148, 156, 132, 140, + 105, 97, 121, 113, 73, 65, 89, 81, + 41, 33, 57, 49, 9, 1, 25, 17, + 233, 225, 249, 241, 201, 193, 217, 209, + 169, 161, 185, 177, 137, 129, 153, 145, + 78, 70, 94, 86, 110, 102, 126, 118, + 14, 6, 30, 22, 46, 38, 62, 54, + 206, 198, 222, 214, 238, 230, 254, 246, + 142, 134, 158, 150, 174, 166, 190, 182, + 83, 91, 67, 75, 115, 123, 99, 107, + 19, 27, 3, 11, 51, 59, 35, 43, + 211, 219, 195, 203, 243, 251, 227, 235, + 147, 155, 131, 139, 179, 187, 163, 171 }, + { 0, 9, 18, 27, 36, 45, 54, 63, + 72, 65, 90, 83, 108, 101, 126, 119, + 144, 153, 130, 139, 180, 189, 166, 175, + 216, 209, 202, 195, 252, 245, 238, 231, + 61, 52, 47, 38, 25, 16, 11, 2, + 117, 124, 103, 110, 81, 88, 67, 74, + 173, 164, 191, 182, 137, 128, 155, 146, + 229, 236, 247, 254, 193, 200, 211, 218, + 122, 115, 104, 97, 94, 87, 76, 69, + 50, 59, 32, 41, 22, 31, 4, 13, + 234, 227, 248, 241, 206, 199, 220, 213, + 162, 171, 176, 185, 134, 143, 148, 157, + 71, 78, 85, 92, 99, 106, 113, 120, + 15, 6, 29, 20, 43, 34, 57, 48, + 215, 222, 197, 204, 243, 250, 225, 232, + 159, 150, 141, 132, 187, 178, 169, 160, + 244, 253, 230, 239, 208, 217, 194, 203, + 188, 181, 174, 167, 152, 145, 138, 131, + 100, 109, 118, 127, 64, 73, 82, 91, + 44, 37, 62, 55, 8, 1, 26, 19, + 201, 192, 219, 210, 237, 228, 255, 246, + 129, 136, 147, 154, 165, 172, 183, 190, + 89, 80, 75, 66, 125, 116, 111, 102, + 17, 24, 3, 10, 53, 60, 39, 46, + 142, 135, 156, 149, 170, 163, 184, 177, + 198, 207, 212, 221, 226, 235, 240, 249, + 30, 23, 12, 5, 58, 51, 40, 33, + 86, 95, 68, 77, 114, 123, 96, 105, + 179, 186, 161, 168, 151, 158, 133, 140, + 251, 242, 233, 224, 223, 214, 205, 196, + 35, 42, 49, 56, 7, 14, 21, 28, + 107, 98, 121, 112, 79, 70, 93, 84 }, + { 0, 10, 20, 30, 40, 34, 60, 54, + 80, 90, 68, 78, 120, 114, 108, 102, + 160, 170, 180, 190, 136, 130, 156, 150, + 240, 250, 228, 238, 216, 210, 204, 198, + 93, 87, 73, 67, 117, 127, 97, 107, + 13, 7, 25, 19, 37, 47, 49, 59, + 253, 247, 233, 227, 213, 223, 193, 203, + 173, 167, 185, 179, 133, 143, 145, 155, + 186, 176, 174, 164, 146, 152, 134, 140, + 234, 224, 254, 244, 194, 200, 214, 220, + 26, 16, 14, 4, 50, 56, 38, 44, + 74, 64, 94, 84, 98, 104, 118, 124, + 231, 237, 243, 249, 207, 197, 219, 209, + 183, 189, 163, 169, 159, 149, 139, 129, + 71, 77, 83, 89, 111, 101, 123, 113, + 23, 29, 3, 9, 63, 53, 43, 33, + 105, 99, 125, 119, 65, 75, 85, 95, + 57, 51, 45, 39, 17, 27, 5, 15, + 201, 195, 221, 215, 225, 235, 245, 255, + 153, 147, 141, 135, 177, 187, 165, 175, + 52, 62, 32, 42, 28, 22, 8, 2, + 100, 110, 112, 122, 76, 70, 88, 82, + 148, 158, 128, 138, 188, 182, 168, 162, + 196, 206, 208, 218, 236, 230, 248, 242, + 211, 217, 199, 205, 251, 241, 239, 229, + 131, 137, 151, 157, 171, 161, 191, 181, + 115, 121, 103, 109, 91, 81, 79, 69, + 35, 41, 55, 61, 11, 1, 31, 21, + 142, 132, 154, 144, 166, 172, 178, 184, + 222, 212, 202, 192, 246, 252, 226, 232, + 46, 36, 58, 48, 6, 12, 18, 24, + 126, 116, 106, 96, 86, 92, 66, 72 }, + { 0, 11, 22, 29, 44, 39, 58, 49, + 88, 83, 78, 69, 116, 127, 98, 105, + 176, 187, 166, 173, 156, 151, 138, 129, + 232, 227, 254, 245, 196, 207, 210, 217, + 125, 118, 107, 96, 81, 90, 71, 76, + 37, 46, 51, 56, 9, 2, 31, 20, + 205, 198, 219, 208, 225, 234, 247, 252, + 149, 158, 131, 136, 185, 178, 175, 164, + 250, 241, 236, 231, 214, 221, 192, 203, + 162, 169, 180, 191, 142, 133, 152, 147, + 74, 65, 92, 87, 102, 109, 112, 123, + 18, 25, 4, 15, 62, 53, 40, 35, + 135, 140, 145, 154, 171, 160, 189, 182, + 223, 212, 201, 194, 243, 248, 229, 238, + 55, 60, 33, 42, 27, 16, 13, 6, + 111, 100, 121, 114, 67, 72, 85, 94, + 233, 226, 255, 244, 197, 206, 211, 216, + 177, 186, 167, 172, 157, 150, 139, 128, + 89, 82, 79, 68, 117, 126, 99, 104, + 1, 10, 23, 28, 45, 38, 59, 48, + 148, 159, 130, 137, 184, 179, 174, 165, + 204, 199, 218, 209, 224, 235, 246, 253, + 36, 47, 50, 57, 8, 3, 30, 21, + 124, 119, 106, 97, 80, 91, 70, 77, + 19, 24, 5, 14, 63, 52, 41, 34, + 75, 64, 93, 86, 103, 108, 113, 122, + 163, 168, 181, 190, 143, 132, 153, 146, + 251, 240, 237, 230, 215, 220, 193, 202, + 110, 101, 120, 115, 66, 73, 84, 95, + 54, 61, 32, 43, 26, 17, 12, 7, + 222, 213, 200, 195, 242, 249, 228, 239, + 134, 141, 144, 155, 170, 161, 188, 183 }, + { 0, 12, 24, 20, 48, 60, 40, 36, + 96, 108, 120, 116, 80, 92, 72, 68, + 192, 204, 216, 212, 240, 252, 232, 228, + 160, 172, 184, 180, 144, 156, 136, 132, + 157, 145, 133, 137, 173, 161, 181, 185, + 253, 241, 229, 233, 205, 193, 213, 217, + 93, 81, 69, 73, 109, 97, 117, 121, + 61, 49, 37, 41, 13, 1, 21, 25, + 39, 43, 63, 51, 23, 27, 15, 3, + 71, 75, 95, 83, 119, 123, 111, 99, + 231, 235, 255, 243, 215, 219, 207, 195, + 135, 139, 159, 147, 183, 187, 175, 163, + 186, 182, 162, 174, 138, 134, 146, 158, + 218, 214, 194, 206, 234, 230, 242, 254, + 122, 118, 98, 110, 74, 70, 82, 94, + 26, 22, 2, 14, 42, 38, 50, 62, + 78, 66, 86, 90, 126, 114, 102, 106, + 46, 34, 54, 58, 30, 18, 6, 10, + 142, 130, 150, 154, 190, 178, 166, 170, + 238, 226, 246, 250, 222, 210, 198, 202, + 211, 223, 203, 199, 227, 239, 251, 247, + 179, 191, 171, 167, 131, 143, 155, 151, + 19, 31, 11, 7, 35, 47, 59, 55, + 115, 127, 107, 103, 67, 79, 91, 87, + 105, 101, 113, 125, 89, 85, 65, 77, + 9, 5, 17, 29, 57, 53, 33, 45, + 169, 165, 177, 189, 153, 149, 129, 141, + 201, 197, 209, 221, 249, 245, 225, 237, + 244, 248, 236, 224, 196, 200, 220, 208, + 148, 152, 140, 128, 164, 168, 188, 176, + 52, 56, 44, 32, 4, 8, 28, 16, + 84, 88, 76, 64, 100, 104, 124, 112 }, + { 0, 13, 26, 23, 52, 57, 46, 35, + 104, 101, 114, 127, 92, 81, 70, 75, + 208, 221, 202, 199, 228, 233, 254, 243, + 184, 181, 162, 175, 140, 129, 150, 155, + 189, 176, 167, 170, 137, 132, 147, 158, + 213, 216, 207, 194, 225, 236, 251, 246, + 109, 96, 119, 122, 89, 84, 67, 78, + 5, 8, 31, 18, 49, 60, 43, 38, + 103, 106, 125, 112, 83, 94, 73, 68, + 15, 2, 21, 24, 59, 54, 33, 44, + 183, 186, 173, 160, 131, 142, 153, 148, + 223, 210, 197, 200, 235, 230, 241, 252, + 218, 215, 192, 205, 238, 227, 244, 249, + 178, 191, 168, 165, 134, 139, 156, 145, + 10, 7, 16, 29, 62, 51, 36, 41, + 98, 111, 120, 117, 86, 91, 76, 65, + 206, 195, 212, 217, 250, 247, 224, 237, + 166, 171, 188, 177, 146, 159, 136, 133, + 30, 19, 4, 9, 42, 39, 48, 61, + 118, 123, 108, 97, 66, 79, 88, 85, + 115, 126, 105, 100, 71, 74, 93, 80, + 27, 22, 1, 12, 47, 34, 53, 56, + 163, 174, 185, 180, 151, 154, 141, 128, + 203, 198, 209, 220, 255, 242, 229, 232, + 169, 164, 179, 190, 157, 144, 135, 138, + 193, 204, 219, 214, 245, 248, 239, 226, + 121, 116, 99, 110, 77, 64, 87, 90, + 17, 28, 11, 6, 37, 40, 63, 50, + 20, 25, 14, 3, 32, 45, 58, 55, + 124, 113, 102, 107, 72, 69, 82, 95, + 196, 201, 222, 211, 240, 253, 234, 231, + 172, 161, 182, 187, 152, 149, 130, 143 }, + { 0, 14, 28, 18, 56, 54, 36, 42, + 112, 126, 108, 98, 72, 70, 84, 90, + 224, 238, 252, 242, 216, 214, 196, 202, + 144, 158, 140, 130, 168, 166, 180, 186, + 221, 211, 193, 207, 229, 235, 249, 247, + 173, 163, 177, 191, 149, 155, 137, 135, + 61, 51, 33, 47, 5, 11, 25, 23, + 77, 67, 81, 95, 117, 123, 105, 103, + 167, 169, 187, 181, 159, 145, 131, 141, + 215, 217, 203, 197, 239, 225, 243, 253, + 71, 73, 91, 85, 127, 113, 99, 109, + 55, 57, 43, 37, 15, 1, 19, 29, + 122, 116, 102, 104, 66, 76, 94, 80, + 10, 4, 22, 24, 50, 60, 46, 32, + 154, 148, 134, 136, 162, 172, 190, 176, + 234, 228, 246, 248, 210, 220, 206, 192, + 83, 93, 79, 65, 107, 101, 119, 121, + 35, 45, 63, 49, 27, 21, 7, 9, + 179, 189, 175, 161, 139, 133, 151, 153, + 195, 205, 223, 209, 251, 245, 231, 233, + 142, 128, 146, 156, 182, 184, 170, 164, + 254, 240, 226, 236, 198, 200, 218, 212, + 110, 96, 114, 124, 86, 88, 74, 68, + 30, 16, 2, 12, 38, 40, 58, 52, + 244, 250, 232, 230, 204, 194, 208, 222, + 132, 138, 152, 150, 188, 178, 160, 174, + 20, 26, 8, 6, 44, 34, 48, 62, + 100, 106, 120, 118, 92, 82, 64, 78, + 41, 39, 53, 59, 17, 31, 13, 3, + 89, 87, 69, 75, 97, 111, 125, 115, + 201, 199, 213, 219, 241, 255, 237, 227, + 185, 183, 165, 171, 129, 143, 157, 147 }, + { 0, 15, 30, 17, 60, 51, 34, 45, + 120, 119, 102, 105, 68, 75, 90, 85, + 240, 255, 238, 225, 204, 195, 210, 221, + 136, 135, 150, 153, 180, 187, 170, 165, + 253, 242, 227, 236, 193, 206, 223, 208, + 133, 138, 155, 148, 185, 182, 167, 168, + 13, 2, 19, 28, 49, 62, 47, 32, + 117, 122, 107, 100, 73, 70, 87, 88, + 231, 232, 249, 246, 219, 212, 197, 202, + 159, 144, 129, 142, 163, 172, 189, 178, + 23, 24, 9, 6, 43, 36, 53, 58, + 111, 96, 113, 126, 83, 92, 77, 66, + 26, 21, 4, 11, 38, 41, 56, 55, + 98, 109, 124, 115, 94, 81, 64, 79, + 234, 229, 244, 251, 214, 217, 200, 199, + 146, 157, 140, 131, 174, 161, 176, 191, + 211, 220, 205, 194, 239, 224, 241, 254, + 171, 164, 181, 186, 151, 152, 137, 134, + 35, 44, 61, 50, 31, 16, 1, 14, + 91, 84, 69, 74, 103, 104, 121, 118, + 46, 33, 48, 63, 18, 29, 12, 3, + 86, 89, 72, 71, 106, 101, 116, 123, + 222, 209, 192, 207, 226, 237, 252, 243, + 166, 169, 184, 183, 154, 149, 132, 139, + 52, 59, 42, 37, 8, 7, 22, 25, + 76, 67, 82, 93, 112, 127, 110, 97, + 196, 203, 218, 213, 248, 247, 230, 233, + 188, 179, 162, 173, 128, 143, 158, 145, + 201, 198, 215, 216, 245, 250, 235, 228, + 177, 190, 175, 160, 141, 130, 147, 156, + 57, 54, 39, 40, 5, 10, 27, 20, + 65, 78, 95, 80, 125, 114, 99, 108 }, + { 0, 16, 32, 48, 64, 80, 96, 112, + 128, 144, 160, 176, 192, 208, 224, 240, + 29, 13, 61, 45, 93, 77, 125, 109, + 157, 141, 189, 173, 221, 205, 253, 237, + 58, 42, 26, 10, 122, 106, 90, 74, + 186, 170, 154, 138, 250, 234, 218, 202, + 39, 55, 7, 23, 103, 119, 71, 87, + 167, 183, 135, 151, 231, 247, 199, 215, + 116, 100, 84, 68, 52, 36, 20, 4, + 244, 228, 212, 196, 180, 164, 148, 132, + 105, 121, 73, 89, 41, 57, 9, 25, + 233, 249, 201, 217, 169, 185, 137, 153, + 78, 94, 110, 126, 14, 30, 46, 62, + 206, 222, 238, 254, 142, 158, 174, 190, + 83, 67, 115, 99, 19, 3, 51, 35, + 211, 195, 243, 227, 147, 131, 179, 163, + 232, 248, 200, 216, 168, 184, 136, 152, + 104, 120, 72, 88, 40, 56, 8, 24, + 245, 229, 213, 197, 181, 165, 149, 133, + 117, 101, 85, 69, 53, 37, 21, 5, + 210, 194, 242, 226, 146, 130, 178, 162, + 82, 66, 114, 98, 18, 2, 50, 34, + 207, 223, 239, 255, 143, 159, 175, 191, + 79, 95, 111, 127, 15, 31, 47, 63, + 156, 140, 188, 172, 220, 204, 252, 236, + 28, 12, 60, 44, 92, 76, 124, 108, + 129, 145, 161, 177, 193, 209, 225, 241, + 1, 17, 33, 49, 65, 81, 97, 113, + 166, 182, 134, 150, 230, 246, 198, 214, + 38, 54, 6, 22, 102, 118, 70, 86, + 187, 171, 155, 139, 251, 235, 219, 203, + 59, 43, 27, 11, 123, 107, 91, 75 }, + { 0, 17, 34, 51, 68, 85, 102, 119, + 136, 153, 170, 187, 204, 221, 238, 255, + 13, 28, 47, 62, 73, 88, 107, 122, + 133, 148, 167, 182, 193, 208, 227, 242, + 26, 11, 56, 41, 94, 79, 124, 109, + 146, 131, 176, 161, 214, 199, 244, 229, + 23, 6, 53, 36, 83, 66, 113, 96, + 159, 142, 189, 172, 219, 202, 249, 232, + 52, 37, 22, 7, 112, 97, 82, 67, + 188, 173, 158, 143, 248, 233, 218, 203, + 57, 40, 27, 10, 125, 108, 95, 78, + 177, 160, 147, 130, 245, 228, 215, 198, + 46, 63, 12, 29, 106, 123, 72, 89, + 166, 183, 132, 149, 226, 243, 192, 209, + 35, 50, 1, 16, 103, 118, 69, 84, + 171, 186, 137, 152, 239, 254, 205, 220, + 104, 121, 74, 91, 44, 61, 14, 31, + 224, 241, 194, 211, 164, 181, 134, 151, + 101, 116, 71, 86, 33, 48, 3, 18, + 237, 252, 207, 222, 169, 184, 139, 154, + 114, 99, 80, 65, 54, 39, 20, 5, + 250, 235, 216, 201, 190, 175, 156, 141, + 127, 110, 93, 76, 59, 42, 25, 8, + 247, 230, 213, 196, 179, 162, 145, 128, + 92, 77, 126, 111, 24, 9, 58, 43, + 212, 197, 246, 231, 144, 129, 178, 163, + 81, 64, 115, 98, 21, 4, 55, 38, + 217, 200, 251, 234, 157, 140, 191, 174, + 70, 87, 100, 117, 2, 19, 32, 49, + 206, 223, 236, 253, 138, 155, 168, 185, + 75, 90, 105, 120, 15, 30, 45, 60, + 195, 210, 225, 240, 135, 150, 165, 180 }, + { 0, 18, 36, 54, 72, 90, 108, 126, + 144, 130, 180, 166, 216, 202, 252, 238, + 61, 47, 25, 11, 117, 103, 81, 67, + 173, 191, 137, 155, 229, 247, 193, 211, + 122, 104, 94, 76, 50, 32, 22, 4, + 234, 248, 206, 220, 162, 176, 134, 148, + 71, 85, 99, 113, 15, 29, 43, 57, + 215, 197, 243, 225, 159, 141, 187, 169, + 244, 230, 208, 194, 188, 174, 152, 138, + 100, 118, 64, 82, 44, 62, 8, 26, + 201, 219, 237, 255, 129, 147, 165, 183, + 89, 75, 125, 111, 17, 3, 53, 39, + 142, 156, 170, 184, 198, 212, 226, 240, + 30, 12, 58, 40, 86, 68, 114, 96, + 179, 161, 151, 133, 251, 233, 223, 205, + 35, 49, 7, 21, 107, 121, 79, 93, + 245, 231, 209, 195, 189, 175, 153, 139, + 101, 119, 65, 83, 45, 63, 9, 27, + 200, 218, 236, 254, 128, 146, 164, 182, + 88, 74, 124, 110, 16, 2, 52, 38, + 143, 157, 171, 185, 199, 213, 227, 241, + 31, 13, 59, 41, 87, 69, 115, 97, + 178, 160, 150, 132, 250, 232, 222, 204, + 34, 48, 6, 20, 106, 120, 78, 92, + 1, 19, 37, 55, 73, 91, 109, 127, + 145, 131, 181, 167, 217, 203, 253, 239, + 60, 46, 24, 10, 116, 102, 80, 66, + 172, 190, 136, 154, 228, 246, 192, 210, + 123, 105, 95, 77, 51, 33, 23, 5, + 235, 249, 207, 221, 163, 177, 135, 149, + 70, 84, 98, 112, 14, 28, 42, 56, + 214, 196, 242, 224, 158, 140, 186, 168 }, + { 0, 19, 38, 53, 76, 95, 106, 121, + 152, 139, 190, 173, 212, 199, 242, 225, + 45, 62, 11, 24, 97, 114, 71, 84, + 181, 166, 147, 128, 249, 234, 223, 204, + 90, 73, 124, 111, 22, 5, 48, 35, + 194, 209, 228, 247, 142, 157, 168, 187, + 119, 100, 81, 66, 59, 40, 29, 14, + 239, 252, 201, 218, 163, 176, 133, 150, + 180, 167, 146, 129, 248, 235, 222, 205, + 44, 63, 10, 25, 96, 115, 70, 85, + 153, 138, 191, 172, 213, 198, 243, 224, + 1, 18, 39, 52, 77, 94, 107, 120, + 238, 253, 200, 219, 162, 177, 132, 151, + 118, 101, 80, 67, 58, 41, 28, 15, + 195, 208, 229, 246, 143, 156, 169, 186, + 91, 72, 125, 110, 23, 4, 49, 34, + 117, 102, 83, 64, 57, 42, 31, 12, + 237, 254, 203, 216, 161, 178, 135, 148, + 88, 75, 126, 109, 20, 7, 50, 33, + 192, 211, 230, 245, 140, 159, 170, 185, + 47, 60, 9, 26, 99, 112, 69, 86, + 183, 164, 145, 130, 251, 232, 221, 206, + 2, 17, 36, 55, 78, 93, 104, 123, + 154, 137, 188, 175, 214, 197, 240, 227, + 193, 210, 231, 244, 141, 158, 171, 184, + 89, 74, 127, 108, 21, 6, 51, 32, + 236, 255, 202, 217, 160, 179, 134, 149, + 116, 103, 82, 65, 56, 43, 30, 13, + 155, 136, 189, 174, 215, 196, 241, 226, + 3, 16, 37, 54, 79, 92, 105, 122, + 182, 165, 144, 131, 250, 233, 220, 207, + 46, 61, 8, 27, 98, 113, 68, 87 }, + { 0, 20, 40, 60, 80, 68, 120, 108, + 160, 180, 136, 156, 240, 228, 216, 204, + 93, 73, 117, 97, 13, 25, 37, 49, + 253, 233, 213, 193, 173, 185, 133, 145, + 186, 174, 146, 134, 234, 254, 194, 214, + 26, 14, 50, 38, 74, 94, 98, 118, + 231, 243, 207, 219, 183, 163, 159, 139, + 71, 83, 111, 123, 23, 3, 63, 43, + 105, 125, 65, 85, 57, 45, 17, 5, + 201, 221, 225, 245, 153, 141, 177, 165, + 52, 32, 28, 8, 100, 112, 76, 88, + 148, 128, 188, 168, 196, 208, 236, 248, + 211, 199, 251, 239, 131, 151, 171, 191, + 115, 103, 91, 79, 35, 55, 11, 31, + 142, 154, 166, 178, 222, 202, 246, 226, + 46, 58, 6, 18, 126, 106, 86, 66, + 210, 198, 250, 238, 130, 150, 170, 190, + 114, 102, 90, 78, 34, 54, 10, 30, + 143, 155, 167, 179, 223, 203, 247, 227, + 47, 59, 7, 19, 127, 107, 87, 67, + 104, 124, 64, 84, 56, 44, 16, 4, + 200, 220, 224, 244, 152, 140, 176, 164, + 53, 33, 29, 9, 101, 113, 77, 89, + 149, 129, 189, 169, 197, 209, 237, 249, + 187, 175, 147, 135, 235, 255, 195, 215, + 27, 15, 51, 39, 75, 95, 99, 119, + 230, 242, 206, 218, 182, 162, 158, 138, + 70, 82, 110, 122, 22, 2, 62, 42, + 1, 21, 41, 61, 81, 69, 121, 109, + 161, 181, 137, 157, 241, 229, 217, 205, + 92, 72, 116, 96, 12, 24, 36, 48, + 252, 232, 212, 192, 172, 184, 132, 144 }, + { 0, 21, 42, 63, 84, 65, 126, 107, + 168, 189, 130, 151, 252, 233, 214, 195, + 77, 88, 103, 114, 25, 12, 51, 38, + 229, 240, 207, 218, 177, 164, 155, 142, + 154, 143, 176, 165, 206, 219, 228, 241, + 50, 39, 24, 13, 102, 115, 76, 89, + 215, 194, 253, 232, 131, 150, 169, 188, + 127, 106, 85, 64, 43, 62, 1, 20, + 41, 60, 3, 22, 125, 104, 87, 66, + 129, 148, 171, 190, 213, 192, 255, 234, + 100, 113, 78, 91, 48, 37, 26, 15, + 204, 217, 230, 243, 152, 141, 178, 167, + 179, 166, 153, 140, 231, 242, 205, 216, + 27, 14, 49, 36, 79, 90, 101, 112, + 254, 235, 212, 193, 170, 191, 128, 149, + 86, 67, 124, 105, 2, 23, 40, 61, + 82, 71, 120, 109, 6, 19, 44, 57, + 250, 239, 208, 197, 174, 187, 132, 145, + 31, 10, 53, 32, 75, 94, 97, 116, + 183, 162, 157, 136, 227, 246, 201, 220, + 200, 221, 226, 247, 156, 137, 182, 163, + 96, 117, 74, 95, 52, 33, 30, 11, + 133, 144, 175, 186, 209, 196, 251, 238, + 45, 56, 7, 18, 121, 108, 83, 70, + 123, 110, 81, 68, 47, 58, 5, 16, + 211, 198, 249, 236, 135, 146, 173, 184, + 54, 35, 28, 9, 98, 119, 72, 93, + 158, 139, 180, 161, 202, 223, 224, 245, + 225, 244, 203, 222, 181, 160, 159, 138, + 73, 92, 99, 118, 29, 8, 55, 34, + 172, 185, 134, 147, 248, 237, 210, 199, + 4, 17, 46, 59, 80, 69, 122, 111 }, + { 0, 22, 44, 58, 88, 78, 116, 98, + 176, 166, 156, 138, 232, 254, 196, 210, + 125, 107, 81, 71, 37, 51, 9, 31, + 205, 219, 225, 247, 149, 131, 185, 175, + 250, 236, 214, 192, 162, 180, 142, 152, + 74, 92, 102, 112, 18, 4, 62, 40, + 135, 145, 171, 189, 223, 201, 243, 229, + 55, 33, 27, 13, 111, 121, 67, 85, + 233, 255, 197, 211, 177, 167, 157, 139, + 89, 79, 117, 99, 1, 23, 45, 59, + 148, 130, 184, 174, 204, 218, 224, 246, + 36, 50, 8, 30, 124, 106, 80, 70, + 19, 5, 63, 41, 75, 93, 103, 113, + 163, 181, 143, 153, 251, 237, 215, 193, + 110, 120, 66, 84, 54, 32, 26, 12, + 222, 200, 242, 228, 134, 144, 170, 188, + 207, 217, 227, 245, 151, 129, 187, 173, + 127, 105, 83, 69, 39, 49, 11, 29, + 178, 164, 158, 136, 234, 252, 198, 208, + 2, 20, 46, 56, 90, 76, 118, 96, + 53, 35, 25, 15, 109, 123, 65, 87, + 133, 147, 169, 191, 221, 203, 241, 231, + 72, 94, 100, 114, 16, 6, 60, 42, + 248, 238, 212, 194, 160, 182, 140, 154, + 38, 48, 10, 28, 126, 104, 82, 68, + 150, 128, 186, 172, 206, 216, 226, 244, + 91, 77, 119, 97, 3, 21, 47, 57, + 235, 253, 199, 209, 179, 165, 159, 137, + 220, 202, 240, 230, 132, 146, 168, 190, + 108, 122, 64, 86, 52, 34, 24, 14, + 161, 183, 141, 155, 249, 239, 213, 195, + 17, 7, 61, 43, 73, 95, 101, 115 }, + { 0, 23, 46, 57, 92, 75, 114, 101, + 184, 175, 150, 129, 228, 243, 202, 221, + 109, 122, 67, 84, 49, 38, 31, 8, + 213, 194, 251, 236, 137, 158, 167, 176, + 218, 205, 244, 227, 134, 145, 168, 191, + 98, 117, 76, 91, 62, 41, 16, 7, + 183, 160, 153, 142, 235, 252, 197, 210, + 15, 24, 33, 54, 83, 68, 125, 106, + 169, 190, 135, 144, 245, 226, 219, 204, + 17, 6, 63, 40, 77, 90, 99, 116, + 196, 211, 234, 253, 152, 143, 182, 161, + 124, 107, 82, 69, 32, 55, 14, 25, + 115, 100, 93, 74, 47, 56, 1, 22, + 203, 220, 229, 242, 151, 128, 185, 174, + 30, 9, 48, 39, 66, 85, 108, 123, + 166, 177, 136, 159, 250, 237, 212, 195, + 79, 88, 97, 118, 19, 4, 61, 42, + 247, 224, 217, 206, 171, 188, 133, 146, + 34, 53, 12, 27, 126, 105, 80, 71, + 154, 141, 180, 163, 198, 209, 232, 255, + 149, 130, 187, 172, 201, 222, 231, 240, + 45, 58, 3, 20, 113, 102, 95, 72, + 248, 239, 214, 193, 164, 179, 138, 157, + 64, 87, 110, 121, 28, 11, 50, 37, + 230, 241, 200, 223, 186, 173, 148, 131, + 94, 73, 112, 103, 2, 21, 44, 59, + 139, 156, 165, 178, 215, 192, 249, 238, + 51, 36, 29, 10, 111, 120, 65, 86, + 60, 43, 18, 5, 96, 119, 78, 89, + 132, 147, 170, 189, 216, 207, 246, 225, + 81, 70, 127, 104, 13, 26, 35, 52, + 233, 254, 199, 208, 181, 162, 155, 140 }, + { 0, 24, 48, 40, 96, 120, 80, 72, + 192, 216, 240, 232, 160, 184, 144, 136, + 157, 133, 173, 181, 253, 229, 205, 213, + 93, 69, 109, 117, 61, 37, 13, 21, + 39, 63, 23, 15, 71, 95, 119, 111, + 231, 255, 215, 207, 135, 159, 183, 175, + 186, 162, 138, 146, 218, 194, 234, 242, + 122, 98, 74, 82, 26, 2, 42, 50, + 78, 86, 126, 102, 46, 54, 30, 6, + 142, 150, 190, 166, 238, 246, 222, 198, + 211, 203, 227, 251, 179, 171, 131, 155, + 19, 11, 35, 59, 115, 107, 67, 91, + 105, 113, 89, 65, 9, 17, 57, 33, + 169, 177, 153, 129, 201, 209, 249, 225, + 244, 236, 196, 220, 148, 140, 164, 188, + 52, 44, 4, 28, 84, 76, 100, 124, + 156, 132, 172, 180, 252, 228, 204, 212, + 92, 68, 108, 116, 60, 36, 12, 20, + 1, 25, 49, 41, 97, 121, 81, 73, + 193, 217, 241, 233, 161, 185, 145, 137, + 187, 163, 139, 147, 219, 195, 235, 243, + 123, 99, 75, 83, 27, 3, 43, 51, + 38, 62, 22, 14, 70, 94, 118, 110, + 230, 254, 214, 206, 134, 158, 182, 174, + 210, 202, 226, 250, 178, 170, 130, 154, + 18, 10, 34, 58, 114, 106, 66, 90, + 79, 87, 127, 103, 47, 55, 31, 7, + 143, 151, 191, 167, 239, 247, 223, 199, + 245, 237, 197, 221, 149, 141, 165, 189, + 53, 45, 5, 29, 85, 77, 101, 125, + 104, 112, 88, 64, 8, 16, 56, 32, + 168, 176, 152, 128, 200, 208, 248, 224 }, + { 0, 25, 50, 43, 100, 125, 86, 79, + 200, 209, 250, 227, 172, 181, 158, 135, + 141, 148, 191, 166, 233, 240, 219, 194, + 69, 92, 119, 110, 33, 56, 19, 10, + 7, 30, 53, 44, 99, 122, 81, 72, + 207, 214, 253, 228, 171, 178, 153, 128, + 138, 147, 184, 161, 238, 247, 220, 197, + 66, 91, 112, 105, 38, 63, 20, 13, + 14, 23, 60, 37, 106, 115, 88, 65, + 198, 223, 244, 237, 162, 187, 144, 137, + 131, 154, 177, 168, 231, 254, 213, 204, + 75, 82, 121, 96, 47, 54, 29, 4, + 9, 16, 59, 34, 109, 116, 95, 70, + 193, 216, 243, 234, 165, 188, 151, 142, + 132, 157, 182, 175, 224, 249, 210, 203, + 76, 85, 126, 103, 40, 49, 26, 3, + 28, 5, 46, 55, 120, 97, 74, 83, + 212, 205, 230, 255, 176, 169, 130, 155, + 145, 136, 163, 186, 245, 236, 199, 222, + 89, 64, 107, 114, 61, 36, 15, 22, + 27, 2, 41, 48, 127, 102, 77, 84, + 211, 202, 225, 248, 183, 174, 133, 156, + 150, 143, 164, 189, 242, 235, 192, 217, + 94, 71, 108, 117, 58, 35, 8, 17, + 18, 11, 32, 57, 118, 111, 68, 93, + 218, 195, 232, 241, 190, 167, 140, 149, + 159, 134, 173, 180, 251, 226, 201, 208, + 87, 78, 101, 124, 51, 42, 1, 24, + 21, 12, 39, 62, 113, 104, 67, 90, + 221, 196, 239, 246, 185, 160, 139, 146, + 152, 129, 170, 179, 252, 229, 206, 215, + 80, 73, 98, 123, 52, 45, 6, 31 }, + { 0, 26, 52, 46, 104, 114, 92, 70, + 208, 202, 228, 254, 184, 162, 140, 150, + 189, 167, 137, 147, 213, 207, 225, 251, + 109, 119, 89, 67, 5, 31, 49, 43, + 103, 125, 83, 73, 15, 21, 59, 33, + 183, 173, 131, 153, 223, 197, 235, 241, + 218, 192, 238, 244, 178, 168, 134, 156, + 10, 16, 62, 36, 98, 120, 86, 76, + 206, 212, 250, 224, 166, 188, 146, 136, + 30, 4, 42, 48, 118, 108, 66, 88, + 115, 105, 71, 93, 27, 1, 47, 53, + 163, 185, 151, 141, 203, 209, 255, 229, + 169, 179, 157, 135, 193, 219, 245, 239, + 121, 99, 77, 87, 17, 11, 37, 63, + 20, 14, 32, 58, 124, 102, 72, 82, + 196, 222, 240, 234, 172, 182, 152, 130, + 129, 155, 181, 175, 233, 243, 221, 199, + 81, 75, 101, 127, 57, 35, 13, 23, + 60, 38, 8, 18, 84, 78, 96, 122, + 236, 246, 216, 194, 132, 158, 176, 170, + 230, 252, 210, 200, 142, 148, 186, 160, + 54, 44, 2, 24, 94, 68, 106, 112, + 91, 65, 111, 117, 51, 41, 7, 29, + 139, 145, 191, 165, 227, 249, 215, 205, + 79, 85, 123, 97, 39, 61, 19, 9, + 159, 133, 171, 177, 247, 237, 195, 217, + 242, 232, 198, 220, 154, 128, 174, 180, + 34, 56, 22, 12, 74, 80, 126, 100, + 40, 50, 28, 6, 64, 90, 116, 110, + 248, 226, 204, 214, 144, 138, 164, 190, + 149, 143, 161, 187, 253, 231, 201, 211, + 69, 95, 113, 107, 45, 55, 25, 3 }, + { 0, 27, 54, 45, 108, 119, 90, 65, + 216, 195, 238, 245, 180, 175, 130, 153, + 173, 182, 155, 128, 193, 218, 247, 236, + 117, 110, 67, 88, 25, 2, 47, 52, + 71, 92, 113, 106, 43, 48, 29, 6, + 159, 132, 169, 178, 243, 232, 197, 222, + 234, 241, 220, 199, 134, 157, 176, 171, + 50, 41, 4, 31, 94, 69, 104, 115, + 142, 149, 184, 163, 226, 249, 212, 207, + 86, 77, 96, 123, 58, 33, 12, 23, + 35, 56, 21, 14, 79, 84, 121, 98, + 251, 224, 205, 214, 151, 140, 161, 186, + 201, 210, 255, 228, 165, 190, 147, 136, + 17, 10, 39, 60, 125, 102, 75, 80, + 100, 127, 82, 73, 8, 19, 62, 37, + 188, 167, 138, 145, 208, 203, 230, 253, + 1, 26, 55, 44, 109, 118, 91, 64, + 217, 194, 239, 244, 181, 174, 131, 152, + 172, 183, 154, 129, 192, 219, 246, 237, + 116, 111, 66, 89, 24, 3, 46, 53, + 70, 93, 112, 107, 42, 49, 28, 7, + 158, 133, 168, 179, 242, 233, 196, 223, + 235, 240, 221, 198, 135, 156, 177, 170, + 51, 40, 5, 30, 95, 68, 105, 114, + 143, 148, 185, 162, 227, 248, 213, 206, + 87, 76, 97, 122, 59, 32, 13, 22, + 34, 57, 20, 15, 78, 85, 120, 99, + 250, 225, 204, 215, 150, 141, 160, 187, + 200, 211, 254, 229, 164, 191, 146, 137, + 16, 11, 38, 61, 124, 103, 74, 81, + 101, 126, 83, 72, 9, 18, 63, 36, + 189, 166, 139, 144, 209, 202, 231, 252 }, + { 0, 28, 56, 36, 112, 108, 72, 84, + 224, 252, 216, 196, 144, 140, 168, 180, + 221, 193, 229, 249, 173, 177, 149, 137, + 61, 33, 5, 25, 77, 81, 117, 105, + 167, 187, 159, 131, 215, 203, 239, 243, + 71, 91, 127, 99, 55, 43, 15, 19, + 122, 102, 66, 94, 10, 22, 50, 46, + 154, 134, 162, 190, 234, 246, 210, 206, + 83, 79, 107, 119, 35, 63, 27, 7, + 179, 175, 139, 151, 195, 223, 251, 231, + 142, 146, 182, 170, 254, 226, 198, 218, + 110, 114, 86, 74, 30, 2, 38, 58, + 244, 232, 204, 208, 132, 152, 188, 160, + 20, 8, 44, 48, 100, 120, 92, 64, + 41, 53, 17, 13, 89, 69, 97, 125, + 201, 213, 241, 237, 185, 165, 129, 157, + 166, 186, 158, 130, 214, 202, 238, 242, + 70, 90, 126, 98, 54, 42, 14, 18, + 123, 103, 67, 95, 11, 23, 51, 47, + 155, 135, 163, 191, 235, 247, 211, 207, + 1, 29, 57, 37, 113, 109, 73, 85, + 225, 253, 217, 197, 145, 141, 169, 181, + 220, 192, 228, 248, 172, 176, 148, 136, + 60, 32, 4, 24, 76, 80, 116, 104, + 245, 233, 205, 209, 133, 153, 189, 161, + 21, 9, 45, 49, 101, 121, 93, 65, + 40, 52, 16, 12, 88, 68, 96, 124, + 200, 212, 240, 236, 184, 164, 128, 156, + 82, 78, 106, 118, 34, 62, 26, 6, + 178, 174, 138, 150, 194, 222, 250, 230, + 143, 147, 183, 171, 255, 227, 199, 219, + 111, 115, 87, 75, 31, 3, 39, 59 }, + { 0, 29, 58, 39, 116, 105, 78, 83, + 232, 245, 210, 207, 156, 129, 166, 187, + 205, 208, 247, 234, 185, 164, 131, 158, + 37, 56, 31, 2, 81, 76, 107, 118, + 135, 154, 189, 160, 243, 238, 201, 212, + 111, 114, 85, 72, 27, 6, 33, 60, + 74, 87, 112, 109, 62, 35, 4, 25, + 162, 191, 152, 133, 214, 203, 236, 241, + 19, 14, 41, 52, 103, 122, 93, 64, + 251, 230, 193, 220, 143, 146, 181, 168, + 222, 195, 228, 249, 170, 183, 144, 141, + 54, 43, 12, 17, 66, 95, 120, 101, + 148, 137, 174, 179, 224, 253, 218, 199, + 124, 97, 70, 91, 8, 21, 50, 47, + 89, 68, 99, 126, 45, 48, 23, 10, + 177, 172, 139, 150, 197, 216, 255, 226, + 38, 59, 28, 1, 82, 79, 104, 117, + 206, 211, 244, 233, 186, 167, 128, 157, + 235, 246, 209, 204, 159, 130, 165, 184, + 3, 30, 57, 36, 119, 106, 77, 80, + 161, 188, 155, 134, 213, 200, 239, 242, + 73, 84, 115, 110, 61, 32, 7, 26, + 108, 113, 86, 75, 24, 5, 34, 63, + 132, 153, 190, 163, 240, 237, 202, 215, + 53, 40, 15, 18, 65, 92, 123, 102, + 221, 192, 231, 250, 169, 180, 147, 142, + 248, 229, 194, 223, 140, 145, 182, 171, + 16, 13, 42, 55, 100, 121, 94, 67, + 178, 175, 136, 149, 198, 219, 252, 225, + 90, 71, 96, 125, 46, 51, 20, 9, + 127, 98, 69, 88, 11, 22, 49, 44, + 151, 138, 173, 176, 227, 254, 217, 196 }, + { 0, 30, 60, 34, 120, 102, 68, 90, + 240, 238, 204, 210, 136, 150, 180, 170, + 253, 227, 193, 223, 133, 155, 185, 167, + 13, 19, 49, 47, 117, 107, 73, 87, + 231, 249, 219, 197, 159, 129, 163, 189, + 23, 9, 43, 53, 111, 113, 83, 77, + 26, 4, 38, 56, 98, 124, 94, 64, + 234, 244, 214, 200, 146, 140, 174, 176, + 211, 205, 239, 241, 171, 181, 151, 137, + 35, 61, 31, 1, 91, 69, 103, 121, + 46, 48, 18, 12, 86, 72, 106, 116, + 222, 192, 226, 252, 166, 184, 154, 132, + 52, 42, 8, 22, 76, 82, 112, 110, + 196, 218, 248, 230, 188, 162, 128, 158, + 201, 215, 245, 235, 177, 175, 141, 147, + 57, 39, 5, 27, 65, 95, 125, 99, + 187, 165, 135, 153, 195, 221, 255, 225, + 75, 85, 119, 105, 51, 45, 15, 17, + 70, 88, 122, 100, 62, 32, 2, 28, + 182, 168, 138, 148, 206, 208, 242, 236, + 92, 66, 96, 126, 36, 58, 24, 6, + 172, 178, 144, 142, 212, 202, 232, 246, + 161, 191, 157, 131, 217, 199, 229, 251, + 81, 79, 109, 115, 41, 55, 21, 11, + 104, 118, 84, 74, 16, 14, 44, 50, + 152, 134, 164, 186, 224, 254, 220, 194, + 149, 139, 169, 183, 237, 243, 209, 207, + 101, 123, 89, 71, 29, 3, 33, 63, + 143, 145, 179, 173, 247, 233, 203, 213, + 127, 97, 67, 93, 7, 25, 59, 37, + 114, 108, 78, 80, 10, 20, 54, 40, + 130, 156, 190, 160, 250, 228, 198, 216 }, + { 0, 31, 62, 33, 124, 99, 66, 93, + 248, 231, 198, 217, 132, 155, 186, 165, + 237, 242, 211, 204, 145, 142, 175, 176, + 21, 10, 43, 52, 105, 118, 87, 72, + 199, 216, 249, 230, 187, 164, 133, 154, + 63, 32, 1, 30, 67, 92, 125, 98, + 42, 53, 20, 11, 86, 73, 104, 119, + 210, 205, 236, 243, 174, 177, 144, 143, + 147, 140, 173, 178, 239, 240, 209, 206, + 107, 116, 85, 74, 23, 8, 41, 54, + 126, 97, 64, 95, 2, 29, 60, 35, + 134, 153, 184, 167, 250, 229, 196, 219, + 84, 75, 106, 117, 40, 55, 22, 9, + 172, 179, 146, 141, 208, 207, 238, 241, + 185, 166, 135, 152, 197, 218, 251, 228, + 65, 94, 127, 96, 61, 34, 3, 28, + 59, 36, 5, 26, 71, 88, 121, 102, + 195, 220, 253, 226, 191, 160, 129, 158, + 214, 201, 232, 247, 170, 181, 148, 139, + 46, 49, 16, 15, 82, 77, 108, 115, + 252, 227, 194, 221, 128, 159, 190, 161, + 4, 27, 58, 37, 120, 103, 70, 89, + 17, 14, 47, 48, 109, 114, 83, 76, + 233, 246, 215, 200, 149, 138, 171, 180, + 168, 183, 150, 137, 212, 203, 234, 245, + 80, 79, 110, 113, 44, 51, 18, 13, + 69, 90, 123, 100, 57, 38, 7, 24, + 189, 162, 131, 156, 193, 222, 255, 224, + 111, 112, 81, 78, 19, 12, 45, 50, + 151, 136, 169, 182, 235, 244, 213, 202, + 130, 157, 188, 163, 254, 225, 192, 223, + 122, 101, 68, 91, 6, 25, 56, 39 }, + { 0, 32, 64, 96, 128, 160, 192, 224, + 29, 61, 93, 125, 157, 189, 221, 253, + 58, 26, 122, 90, 186, 154, 250, 218, + 39, 7, 103, 71, 167, 135, 231, 199, + 116, 84, 52, 20, 244, 212, 180, 148, + 105, 73, 41, 9, 233, 201, 169, 137, + 78, 110, 14, 46, 206, 238, 142, 174, + 83, 115, 19, 51, 211, 243, 147, 179, + 232, 200, 168, 136, 104, 72, 40, 8, + 245, 213, 181, 149, 117, 85, 53, 21, + 210, 242, 146, 178, 82, 114, 18, 50, + 207, 239, 143, 175, 79, 111, 15, 47, + 156, 188, 220, 252, 28, 60, 92, 124, + 129, 161, 193, 225, 1, 33, 65, 97, + 166, 134, 230, 198, 38, 6, 102, 70, + 187, 155, 251, 219, 59, 27, 123, 91, + 205, 237, 141, 173, 77, 109, 13, 45, + 208, 240, 144, 176, 80, 112, 16, 48, + 247, 215, 183, 151, 119, 87, 55, 23, + 234, 202, 170, 138, 106, 74, 42, 10, + 185, 153, 249, 217, 57, 25, 121, 89, + 164, 132, 228, 196, 36, 4, 100, 68, + 131, 163, 195, 227, 3, 35, 67, 99, + 158, 190, 222, 254, 30, 62, 94, 126, + 37, 5, 101, 69, 165, 133, 229, 197, + 56, 24, 120, 88, 184, 152, 248, 216, + 31, 63, 95, 127, 159, 191, 223, 255, + 2, 34, 66, 98, 130, 162, 194, 226, + 81, 113, 17, 49, 209, 241, 145, 177, + 76, 108, 12, 44, 204, 236, 140, 172, + 107, 75, 43, 11, 235, 203, 171, 139, + 118, 86, 54, 22, 246, 214, 182, 150 }, + { 0, 33, 66, 99, 132, 165, 198, 231, + 21, 52, 87, 118, 145, 176, 211, 242, + 42, 11, 104, 73, 174, 143, 236, 205, + 63, 30, 125, 92, 187, 154, 249, 216, + 84, 117, 22, 55, 208, 241, 146, 179, + 65, 96, 3, 34, 197, 228, 135, 166, + 126, 95, 60, 29, 250, 219, 184, 153, + 107, 74, 41, 8, 239, 206, 173, 140, + 168, 137, 234, 203, 44, 13, 110, 79, + 189, 156, 255, 222, 57, 24, 123, 90, + 130, 163, 192, 225, 6, 39, 68, 101, + 151, 182, 213, 244, 19, 50, 81, 112, + 252, 221, 190, 159, 120, 89, 58, 27, + 233, 200, 171, 138, 109, 76, 47, 14, + 214, 247, 148, 181, 82, 115, 16, 49, + 195, 226, 129, 160, 71, 102, 5, 36, + 77, 108, 15, 46, 201, 232, 139, 170, + 88, 121, 26, 59, 220, 253, 158, 191, + 103, 70, 37, 4, 227, 194, 161, 128, + 114, 83, 48, 17, 246, 215, 180, 149, + 25, 56, 91, 122, 157, 188, 223, 254, + 12, 45, 78, 111, 136, 169, 202, 235, + 51, 18, 113, 80, 183, 150, 245, 212, + 38, 7, 100, 69, 162, 131, 224, 193, + 229, 196, 167, 134, 97, 64, 35, 2, + 240, 209, 178, 147, 116, 85, 54, 23, + 207, 238, 141, 172, 75, 106, 9, 40, + 218, 251, 152, 185, 94, 127, 28, 61, + 177, 144, 243, 210, 53, 20, 119, 86, + 164, 133, 230, 199, 32, 1, 98, 67, + 155, 186, 217, 248, 31, 62, 93, 124, + 142, 175, 204, 237, 10, 43, 72, 105 }, + { 0, 34, 68, 102, 136, 170, 204, 238, + 13, 47, 73, 107, 133, 167, 193, 227, + 26, 56, 94, 124, 146, 176, 214, 244, + 23, 53, 83, 113, 159, 189, 219, 249, + 52, 22, 112, 82, 188, 158, 248, 218, + 57, 27, 125, 95, 177, 147, 245, 215, + 46, 12, 106, 72, 166, 132, 226, 192, + 35, 1, 103, 69, 171, 137, 239, 205, + 104, 74, 44, 14, 224, 194, 164, 134, + 101, 71, 33, 3, 237, 207, 169, 139, + 114, 80, 54, 20, 250, 216, 190, 156, + 127, 93, 59, 25, 247, 213, 179, 145, + 92, 126, 24, 58, 212, 246, 144, 178, + 81, 115, 21, 55, 217, 251, 157, 191, + 70, 100, 2, 32, 206, 236, 138, 168, + 75, 105, 15, 45, 195, 225, 135, 165, + 208, 242, 148, 182, 88, 122, 28, 62, + 221, 255, 153, 187, 85, 119, 17, 51, + 202, 232, 142, 172, 66, 96, 6, 36, + 199, 229, 131, 161, 79, 109, 11, 41, + 228, 198, 160, 130, 108, 78, 40, 10, + 233, 203, 173, 143, 97, 67, 37, 7, + 254, 220, 186, 152, 118, 84, 50, 16, + 243, 209, 183, 149, 123, 89, 63, 29, + 184, 154, 252, 222, 48, 18, 116, 86, + 181, 151, 241, 211, 61, 31, 121, 91, + 162, 128, 230, 196, 42, 8, 110, 76, + 175, 141, 235, 201, 39, 5, 99, 65, + 140, 174, 200, 234, 4, 38, 64, 98, + 129, 163, 197, 231, 9, 43, 77, 111, + 150, 180, 210, 240, 30, 60, 90, 120, + 155, 185, 223, 253, 19, 49, 87, 117 }, + { 0, 35, 70, 101, 140, 175, 202, 233, + 5, 38, 67, 96, 137, 170, 207, 236, + 10, 41, 76, 111, 134, 165, 192, 227, + 15, 44, 73, 106, 131, 160, 197, 230, + 20, 55, 82, 113, 152, 187, 222, 253, + 17, 50, 87, 116, 157, 190, 219, 248, + 30, 61, 88, 123, 146, 177, 212, 247, + 27, 56, 93, 126, 151, 180, 209, 242, + 40, 11, 110, 77, 164, 135, 226, 193, + 45, 14, 107, 72, 161, 130, 231, 196, + 34, 1, 100, 71, 174, 141, 232, 203, + 39, 4, 97, 66, 171, 136, 237, 206, + 60, 31, 122, 89, 176, 147, 246, 213, + 57, 26, 127, 92, 181, 150, 243, 208, + 54, 21, 112, 83, 186, 153, 252, 223, + 51, 16, 117, 86, 191, 156, 249, 218, + 80, 115, 22, 53, 220, 255, 154, 185, + 85, 118, 19, 48, 217, 250, 159, 188, + 90, 121, 28, 63, 214, 245, 144, 179, + 95, 124, 25, 58, 211, 240, 149, 182, + 68, 103, 2, 33, 200, 235, 142, 173, + 65, 98, 7, 36, 205, 238, 139, 168, + 78, 109, 8, 43, 194, 225, 132, 167, + 75, 104, 13, 46, 199, 228, 129, 162, + 120, 91, 62, 29, 244, 215, 178, 145, + 125, 94, 59, 24, 241, 210, 183, 148, + 114, 81, 52, 23, 254, 221, 184, 155, + 119, 84, 49, 18, 251, 216, 189, 158, + 108, 79, 42, 9, 224, 195, 166, 133, + 105, 74, 47, 12, 229, 198, 163, 128, + 102, 69, 32, 3, 234, 201, 172, 143, + 99, 64, 37, 6, 239, 204, 169, 138 }, + { 0, 36, 72, 108, 144, 180, 216, 252, + 61, 25, 117, 81, 173, 137, 229, 193, + 122, 94, 50, 22, 234, 206, 162, 134, + 71, 99, 15, 43, 215, 243, 159, 187, + 244, 208, 188, 152, 100, 64, 44, 8, + 201, 237, 129, 165, 89, 125, 17, 53, + 142, 170, 198, 226, 30, 58, 86, 114, + 179, 151, 251, 223, 35, 7, 107, 79, + 245, 209, 189, 153, 101, 65, 45, 9, + 200, 236, 128, 164, 88, 124, 16, 52, + 143, 171, 199, 227, 31, 59, 87, 115, + 178, 150, 250, 222, 34, 6, 106, 78, + 1, 37, 73, 109, 145, 181, 217, 253, + 60, 24, 116, 80, 172, 136, 228, 192, + 123, 95, 51, 23, 235, 207, 163, 135, + 70, 98, 14, 42, 214, 242, 158, 186, + 247, 211, 191, 155, 103, 67, 47, 11, + 202, 238, 130, 166, 90, 126, 18, 54, + 141, 169, 197, 225, 29, 57, 85, 113, + 176, 148, 248, 220, 32, 4, 104, 76, + 3, 39, 75, 111, 147, 183, 219, 255, + 62, 26, 118, 82, 174, 138, 230, 194, + 121, 93, 49, 21, 233, 205, 161, 133, + 68, 96, 12, 40, 212, 240, 156, 184, + 2, 38, 74, 110, 146, 182, 218, 254, + 63, 27, 119, 83, 175, 139, 231, 195, + 120, 92, 48, 20, 232, 204, 160, 132, + 69, 97, 13, 41, 213, 241, 157, 185, + 246, 210, 190, 154, 102, 66, 46, 10, + 203, 239, 131, 167, 91, 127, 19, 55, + 140, 168, 196, 224, 28, 56, 84, 112, + 177, 149, 249, 221, 33, 5, 105, 77 }, + { 0, 37, 74, 111, 148, 177, 222, 251, + 53, 16, 127, 90, 161, 132, 235, 206, + 106, 79, 32, 5, 254, 219, 180, 145, + 95, 122, 21, 48, 203, 238, 129, 164, + 212, 241, 158, 187, 64, 101, 10, 47, + 225, 196, 171, 142, 117, 80, 63, 26, + 190, 155, 244, 209, 42, 15, 96, 69, + 139, 174, 193, 228, 31, 58, 85, 112, + 181, 144, 255, 218, 33, 4, 107, 78, + 128, 165, 202, 239, 20, 49, 94, 123, + 223, 250, 149, 176, 75, 110, 1, 36, + 234, 207, 160, 133, 126, 91, 52, 17, + 97, 68, 43, 14, 245, 208, 191, 154, + 84, 113, 30, 59, 192, 229, 138, 175, + 11, 46, 65, 100, 159, 186, 213, 240, + 62, 27, 116, 81, 170, 143, 224, 197, + 119, 82, 61, 24, 227, 198, 169, 140, + 66, 103, 8, 45, 214, 243, 156, 185, + 29, 56, 87, 114, 137, 172, 195, 230, + 40, 13, 98, 71, 188, 153, 246, 211, + 163, 134, 233, 204, 55, 18, 125, 88, + 150, 179, 220, 249, 2, 39, 72, 109, + 201, 236, 131, 166, 93, 120, 23, 50, + 252, 217, 182, 147, 104, 77, 34, 7, + 194, 231, 136, 173, 86, 115, 28, 57, + 247, 210, 189, 152, 99, 70, 41, 12, + 168, 141, 226, 199, 60, 25, 118, 83, + 157, 184, 215, 242, 9, 44, 67, 102, + 22, 51, 92, 121, 130, 167, 200, 237, + 35, 6, 105, 76, 183, 146, 253, 216, + 124, 89, 54, 19, 232, 205, 162, 135, + 73, 108, 3, 38, 221, 248, 151, 178 }, + { 0, 38, 76, 106, 152, 190, 212, 242, + 45, 11, 97, 71, 181, 147, 249, 223, + 90, 124, 22, 48, 194, 228, 142, 168, + 119, 81, 59, 29, 239, 201, 163, 133, + 180, 146, 248, 222, 44, 10, 96, 70, + 153, 191, 213, 243, 1, 39, 77, 107, + 238, 200, 162, 132, 118, 80, 58, 28, + 195, 229, 143, 169, 91, 125, 23, 49, + 117, 83, 57, 31, 237, 203, 161, 135, + 88, 126, 20, 50, 192, 230, 140, 170, + 47, 9, 99, 69, 183, 145, 251, 221, + 2, 36, 78, 104, 154, 188, 214, 240, + 193, 231, 141, 171, 89, 127, 21, 51, + 236, 202, 160, 134, 116, 82, 56, 30, + 155, 189, 215, 241, 3, 37, 79, 105, + 182, 144, 250, 220, 46, 8, 98, 68, + 234, 204, 166, 128, 114, 84, 62, 24, + 199, 225, 139, 173, 95, 121, 19, 53, + 176, 150, 252, 218, 40, 14, 100, 66, + 157, 187, 209, 247, 5, 35, 73, 111, + 94, 120, 18, 52, 198, 224, 138, 172, + 115, 85, 63, 25, 235, 205, 167, 129, + 4, 34, 72, 110, 156, 186, 208, 246, + 41, 15, 101, 67, 177, 151, 253, 219, + 159, 185, 211, 245, 7, 33, 75, 109, + 178, 148, 254, 216, 42, 12, 102, 64, + 197, 227, 137, 175, 93, 123, 17, 55, + 232, 206, 164, 130, 112, 86, 60, 26, + 43, 13, 103, 65, 179, 149, 255, 217, + 6, 32, 74, 108, 158, 184, 210, 244, + 113, 87, 61, 27, 233, 207, 165, 131, + 92, 122, 16, 54, 196, 226, 136, 174 }, + { 0, 39, 78, 105, 156, 187, 210, 245, + 37, 2, 107, 76, 185, 158, 247, 208, + 74, 109, 4, 35, 214, 241, 152, 191, + 111, 72, 33, 6, 243, 212, 189, 154, + 148, 179, 218, 253, 8, 47, 70, 97, + 177, 150, 255, 216, 45, 10, 99, 68, + 222, 249, 144, 183, 66, 101, 12, 43, + 251, 220, 181, 146, 103, 64, 41, 14, + 53, 18, 123, 92, 169, 142, 231, 192, + 16, 55, 94, 121, 140, 171, 194, 229, + 127, 88, 49, 22, 227, 196, 173, 138, + 90, 125, 20, 51, 198, 225, 136, 175, + 161, 134, 239, 200, 61, 26, 115, 84, + 132, 163, 202, 237, 24, 63, 86, 113, + 235, 204, 165, 130, 119, 80, 57, 30, + 206, 233, 128, 167, 82, 117, 28, 59, + 106, 77, 36, 3, 246, 209, 184, 159, + 79, 104, 1, 38, 211, 244, 157, 186, + 32, 7, 110, 73, 188, 155, 242, 213, + 5, 34, 75, 108, 153, 190, 215, 240, + 254, 217, 176, 151, 98, 69, 44, 11, + 219, 252, 149, 178, 71, 96, 9, 46, + 180, 147, 250, 221, 40, 15, 102, 65, + 145, 182, 223, 248, 13, 42, 67, 100, + 95, 120, 17, 54, 195, 228, 141, 170, + 122, 93, 52, 19, 230, 193, 168, 143, + 21, 50, 91, 124, 137, 174, 199, 224, + 48, 23, 126, 89, 172, 139, 226, 197, + 203, 236, 133, 162, 87, 112, 25, 62, + 238, 201, 160, 135, 114, 85, 60, 27, + 129, 166, 207, 232, 29, 58, 83, 116, + 164, 131, 234, 205, 56, 31, 118, 81 }, + { 0, 40, 80, 120, 160, 136, 240, 216, + 93, 117, 13, 37, 253, 213, 173, 133, + 186, 146, 234, 194, 26, 50, 74, 98, + 231, 207, 183, 159, 71, 111, 23, 63, + 105, 65, 57, 17, 201, 225, 153, 177, + 52, 28, 100, 76, 148, 188, 196, 236, + 211, 251, 131, 171, 115, 91, 35, 11, + 142, 166, 222, 246, 46, 6, 126, 86, + 210, 250, 130, 170, 114, 90, 34, 10, + 143, 167, 223, 247, 47, 7, 127, 87, + 104, 64, 56, 16, 200, 224, 152, 176, + 53, 29, 101, 77, 149, 189, 197, 237, + 187, 147, 235, 195, 27, 51, 75, 99, + 230, 206, 182, 158, 70, 110, 22, 62, + 1, 41, 81, 121, 161, 137, 241, 217, + 92, 116, 12, 36, 252, 212, 172, 132, + 185, 145, 233, 193, 25, 49, 73, 97, + 228, 204, 180, 156, 68, 108, 20, 60, + 3, 43, 83, 123, 163, 139, 243, 219, + 94, 118, 14, 38, 254, 214, 174, 134, + 208, 248, 128, 168, 112, 88, 32, 8, + 141, 165, 221, 245, 45, 5, 125, 85, + 106, 66, 58, 18, 202, 226, 154, 178, + 55, 31, 103, 79, 151, 191, 199, 239, + 107, 67, 59, 19, 203, 227, 155, 179, + 54, 30, 102, 78, 150, 190, 198, 238, + 209, 249, 129, 169, 113, 89, 33, 9, + 140, 164, 220, 244, 44, 4, 124, 84, + 2, 42, 82, 122, 162, 138, 242, 218, + 95, 119, 15, 39, 255, 215, 175, 135, + 184, 144, 232, 192, 24, 48, 72, 96, + 229, 205, 181, 157, 69, 109, 21, 61 }, + { 0, 41, 82, 123, 164, 141, 246, 223, + 85, 124, 7, 46, 241, 216, 163, 138, + 170, 131, 248, 209, 14, 39, 92, 117, + 255, 214, 173, 132, 91, 114, 9, 32, + 73, 96, 27, 50, 237, 196, 191, 150, + 28, 53, 78, 103, 184, 145, 234, 195, + 227, 202, 177, 152, 71, 110, 21, 60, + 182, 159, 228, 205, 18, 59, 64, 105, + 146, 187, 192, 233, 54, 31, 100, 77, + 199, 238, 149, 188, 99, 74, 49, 24, + 56, 17, 106, 67, 156, 181, 206, 231, + 109, 68, 63, 22, 201, 224, 155, 178, + 219, 242, 137, 160, 127, 86, 45, 4, + 142, 167, 220, 245, 42, 3, 120, 81, + 113, 88, 35, 10, 213, 252, 135, 174, + 36, 13, 118, 95, 128, 169, 210, 251, + 57, 16, 107, 66, 157, 180, 207, 230, + 108, 69, 62, 23, 200, 225, 154, 179, + 147, 186, 193, 232, 55, 30, 101, 76, + 198, 239, 148, 189, 98, 75, 48, 25, + 112, 89, 34, 11, 212, 253, 134, 175, + 37, 12, 119, 94, 129, 168, 211, 250, + 218, 243, 136, 161, 126, 87, 44, 5, + 143, 166, 221, 244, 43, 2, 121, 80, + 171, 130, 249, 208, 15, 38, 93, 116, + 254, 215, 172, 133, 90, 115, 8, 33, + 1, 40, 83, 122, 165, 140, 247, 222, + 84, 125, 6, 47, 240, 217, 162, 139, + 226, 203, 176, 153, 70, 111, 20, 61, + 183, 158, 229, 204, 19, 58, 65, 104, + 72, 97, 26, 51, 236, 197, 190, 151, + 29, 52, 79, 102, 185, 144, 235, 194 }, + { 0, 42, 84, 126, 168, 130, 252, 214, + 77, 103, 25, 51, 229, 207, 177, 155, + 154, 176, 206, 228, 50, 24, 102, 76, + 215, 253, 131, 169, 127, 85, 43, 1, + 41, 3, 125, 87, 129, 171, 213, 255, + 100, 78, 48, 26, 204, 230, 152, 178, + 179, 153, 231, 205, 27, 49, 79, 101, + 254, 212, 170, 128, 86, 124, 2, 40, + 82, 120, 6, 44, 250, 208, 174, 132, + 31, 53, 75, 97, 183, 157, 227, 201, + 200, 226, 156, 182, 96, 74, 52, 30, + 133, 175, 209, 251, 45, 7, 121, 83, + 123, 81, 47, 5, 211, 249, 135, 173, + 54, 28, 98, 72, 158, 180, 202, 224, + 225, 203, 181, 159, 73, 99, 29, 55, + 172, 134, 248, 210, 4, 46, 80, 122, + 164, 142, 240, 218, 12, 38, 88, 114, + 233, 195, 189, 151, 65, 107, 21, 63, + 62, 20, 106, 64, 150, 188, 194, 232, + 115, 89, 39, 13, 219, 241, 143, 165, + 141, 167, 217, 243, 37, 15, 113, 91, + 192, 234, 148, 190, 104, 66, 60, 22, + 23, 61, 67, 105, 191, 149, 235, 193, + 90, 112, 14, 36, 242, 216, 166, 140, + 246, 220, 162, 136, 94, 116, 10, 32, + 187, 145, 239, 197, 19, 57, 71, 109, + 108, 70, 56, 18, 196, 238, 144, 186, + 33, 11, 117, 95, 137, 163, 221, 247, + 223, 245, 139, 161, 119, 93, 35, 9, + 146, 184, 198, 236, 58, 16, 110, 68, + 69, 111, 17, 59, 237, 199, 185, 147, + 8, 34, 92, 118, 160, 138, 244, 222 }, + { 0, 43, 86, 125, 172, 135, 250, 209, + 69, 110, 19, 56, 233, 194, 191, 148, + 138, 161, 220, 247, 38, 13, 112, 91, + 207, 228, 153, 178, 99, 72, 53, 30, + 9, 34, 95, 116, 165, 142, 243, 216, + 76, 103, 26, 49, 224, 203, 182, 157, + 131, 168, 213, 254, 47, 4, 121, 82, + 198, 237, 144, 187, 106, 65, 60, 23, + 18, 57, 68, 111, 190, 149, 232, 195, + 87, 124, 1, 42, 251, 208, 173, 134, + 152, 179, 206, 229, 52, 31, 98, 73, + 221, 246, 139, 160, 113, 90, 39, 12, + 27, 48, 77, 102, 183, 156, 225, 202, + 94, 117, 8, 35, 242, 217, 164, 143, + 145, 186, 199, 236, 61, 22, 107, 64, + 212, 255, 130, 169, 120, 83, 46, 5, + 36, 15, 114, 89, 136, 163, 222, 245, + 97, 74, 55, 28, 205, 230, 155, 176, + 174, 133, 248, 211, 2, 41, 84, 127, + 235, 192, 189, 150, 71, 108, 17, 58, + 45, 6, 123, 80, 129, 170, 215, 252, + 104, 67, 62, 21, 196, 239, 146, 185, + 167, 140, 241, 218, 11, 32, 93, 118, + 226, 201, 180, 159, 78, 101, 24, 51, + 54, 29, 96, 75, 154, 177, 204, 231, + 115, 88, 37, 14, 223, 244, 137, 162, + 188, 151, 234, 193, 16, 59, 70, 109, + 249, 210, 175, 132, 85, 126, 3, 40, + 63, 20, 105, 66, 147, 184, 197, 238, + 122, 81, 44, 7, 214, 253, 128, 171, + 181, 158, 227, 200, 25, 50, 79, 100, + 240, 219, 166, 141, 92, 119, 10, 33 }, + { 0, 44, 88, 116, 176, 156, 232, 196, + 125, 81, 37, 9, 205, 225, 149, 185, + 250, 214, 162, 142, 74, 102, 18, 62, + 135, 171, 223, 243, 55, 27, 111, 67, + 233, 197, 177, 157, 89, 117, 1, 45, + 148, 184, 204, 224, 36, 8, 124, 80, + 19, 63, 75, 103, 163, 143, 251, 215, + 110, 66, 54, 26, 222, 242, 134, 170, + 207, 227, 151, 187, 127, 83, 39, 11, + 178, 158, 234, 198, 2, 46, 90, 118, + 53, 25, 109, 65, 133, 169, 221, 241, + 72, 100, 16, 60, 248, 212, 160, 140, + 38, 10, 126, 82, 150, 186, 206, 226, + 91, 119, 3, 47, 235, 199, 179, 159, + 220, 240, 132, 168, 108, 64, 52, 24, + 161, 141, 249, 213, 17, 61, 73, 101, + 131, 175, 219, 247, 51, 31, 107, 71, + 254, 210, 166, 138, 78, 98, 22, 58, + 121, 85, 33, 13, 201, 229, 145, 189, + 4, 40, 92, 112, 180, 152, 236, 192, + 106, 70, 50, 30, 218, 246, 130, 174, + 23, 59, 79, 99, 167, 139, 255, 211, + 144, 188, 200, 228, 32, 12, 120, 84, + 237, 193, 181, 153, 93, 113, 5, 41, + 76, 96, 20, 56, 252, 208, 164, 136, + 49, 29, 105, 69, 129, 173, 217, 245, + 182, 154, 238, 194, 6, 42, 94, 114, + 203, 231, 147, 191, 123, 87, 35, 15, + 165, 137, 253, 209, 21, 57, 77, 97, + 216, 244, 128, 172, 104, 68, 48, 28, + 95, 115, 7, 43, 239, 195, 183, 155, + 34, 14, 122, 86, 146, 190, 202, 230 }, + { 0, 45, 90, 119, 180, 153, 238, 195, + 117, 88, 47, 2, 193, 236, 155, 182, + 234, 199, 176, 157, 94, 115, 4, 41, + 159, 178, 197, 232, 43, 6, 113, 92, + 201, 228, 147, 190, 125, 80, 39, 10, + 188, 145, 230, 203, 8, 37, 82, 127, + 35, 14, 121, 84, 151, 186, 205, 224, + 86, 123, 12, 33, 226, 207, 184, 149, + 143, 162, 213, 248, 59, 22, 97, 76, + 250, 215, 160, 141, 78, 99, 20, 57, + 101, 72, 63, 18, 209, 252, 139, 166, + 16, 61, 74, 103, 164, 137, 254, 211, + 70, 107, 28, 49, 242, 223, 168, 133, + 51, 30, 105, 68, 135, 170, 221, 240, + 172, 129, 246, 219, 24, 53, 66, 111, + 217, 244, 131, 174, 109, 64, 55, 26, + 3, 46, 89, 116, 183, 154, 237, 192, + 118, 91, 44, 1, 194, 239, 152, 181, + 233, 196, 179, 158, 93, 112, 7, 42, + 156, 177, 198, 235, 40, 5, 114, 95, + 202, 231, 144, 189, 126, 83, 36, 9, + 191, 146, 229, 200, 11, 38, 81, 124, + 32, 13, 122, 87, 148, 185, 206, 227, + 85, 120, 15, 34, 225, 204, 187, 150, + 140, 161, 214, 251, 56, 21, 98, 79, + 249, 212, 163, 142, 77, 96, 23, 58, + 102, 75, 60, 17, 210, 255, 136, 165, + 19, 62, 73, 100, 167, 138, 253, 208, + 69, 104, 31, 50, 241, 220, 171, 134, + 48, 29, 106, 71, 132, 169, 222, 243, + 175, 130, 245, 216, 27, 54, 65, 108, + 218, 247, 128, 173, 110, 67, 52, 25 }, + { 0, 46, 92, 114, 184, 150, 228, 202, + 109, 67, 49, 31, 213, 251, 137, 167, + 218, 244, 134, 168, 98, 76, 62, 16, + 183, 153, 235, 197, 15, 33, 83, 125, + 169, 135, 245, 219, 17, 63, 77, 99, + 196, 234, 152, 182, 124, 82, 32, 14, + 115, 93, 47, 1, 203, 229, 151, 185, + 30, 48, 66, 108, 166, 136, 250, 212, + 79, 97, 19, 61, 247, 217, 171, 133, + 34, 12, 126, 80, 154, 180, 198, 232, + 149, 187, 201, 231, 45, 3, 113, 95, + 248, 214, 164, 138, 64, 110, 28, 50, + 230, 200, 186, 148, 94, 112, 2, 44, + 139, 165, 215, 249, 51, 29, 111, 65, + 60, 18, 96, 78, 132, 170, 216, 246, + 81, 127, 13, 35, 233, 199, 181, 155, + 158, 176, 194, 236, 38, 8, 122, 84, + 243, 221, 175, 129, 75, 101, 23, 57, + 68, 106, 24, 54, 252, 210, 160, 142, + 41, 7, 117, 91, 145, 191, 205, 227, + 55, 25, 107, 69, 143, 161, 211, 253, + 90, 116, 6, 40, 226, 204, 190, 144, + 237, 195, 177, 159, 85, 123, 9, 39, + 128, 174, 220, 242, 56, 22, 100, 74, + 209, 255, 141, 163, 105, 71, 53, 27, + 188, 146, 224, 206, 4, 42, 88, 118, + 11, 37, 87, 121, 179, 157, 239, 193, + 102, 72, 58, 20, 222, 240, 130, 172, + 120, 86, 36, 10, 192, 238, 156, 178, + 21, 59, 73, 103, 173, 131, 241, 223, + 162, 140, 254, 208, 26, 52, 70, 104, + 207, 225, 147, 189, 119, 89, 43, 5 }, + { 0, 47, 94, 113, 188, 147, 226, 205, + 101, 74, 59, 20, 217, 246, 135, 168, + 202, 229, 148, 187, 118, 89, 40, 7, + 175, 128, 241, 222, 19, 60, 77, 98, + 137, 166, 215, 248, 53, 26, 107, 68, + 236, 195, 178, 157, 80, 127, 14, 33, + 67, 108, 29, 50, 255, 208, 161, 142, + 38, 9, 120, 87, 154, 181, 196, 235, + 15, 32, 81, 126, 179, 156, 237, 194, + 106, 69, 52, 27, 214, 249, 136, 167, + 197, 234, 155, 180, 121, 86, 39, 8, + 160, 143, 254, 209, 28, 51, 66, 109, + 134, 169, 216, 247, 58, 21, 100, 75, + 227, 204, 189, 146, 95, 112, 1, 46, + 76, 99, 18, 61, 240, 223, 174, 129, + 41, 6, 119, 88, 149, 186, 203, 228, + 30, 49, 64, 111, 162, 141, 252, 211, + 123, 84, 37, 10, 199, 232, 153, 182, + 212, 251, 138, 165, 104, 71, 54, 25, + 177, 158, 239, 192, 13, 34, 83, 124, + 151, 184, 201, 230, 43, 4, 117, 90, + 242, 221, 172, 131, 78, 97, 16, 63, + 93, 114, 3, 44, 225, 206, 191, 144, + 56, 23, 102, 73, 132, 171, 218, 245, + 17, 62, 79, 96, 173, 130, 243, 220, + 116, 91, 42, 5, 200, 231, 150, 185, + 219, 244, 133, 170, 103, 72, 57, 22, + 190, 145, 224, 207, 2, 45, 92, 115, + 152, 183, 198, 233, 36, 11, 122, 85, + 253, 210, 163, 140, 65, 110, 31, 48, + 82, 125, 12, 35, 238, 193, 176, 159, + 55, 24, 105, 70, 139, 164, 213, 250 }, + { 0, 48, 96, 80, 192, 240, 160, 144, + 157, 173, 253, 205, 93, 109, 61, 13, + 39, 23, 71, 119, 231, 215, 135, 183, + 186, 138, 218, 234, 122, 74, 26, 42, + 78, 126, 46, 30, 142, 190, 238, 222, + 211, 227, 179, 131, 19, 35, 115, 67, + 105, 89, 9, 57, 169, 153, 201, 249, + 244, 196, 148, 164, 52, 4, 84, 100, + 156, 172, 252, 204, 92, 108, 60, 12, + 1, 49, 97, 81, 193, 241, 161, 145, + 187, 139, 219, 235, 123, 75, 27, 43, + 38, 22, 70, 118, 230, 214, 134, 182, + 210, 226, 178, 130, 18, 34, 114, 66, + 79, 127, 47, 31, 143, 191, 239, 223, + 245, 197, 149, 165, 53, 5, 85, 101, + 104, 88, 8, 56, 168, 152, 200, 248, + 37, 21, 69, 117, 229, 213, 133, 181, + 184, 136, 216, 232, 120, 72, 24, 40, + 2, 50, 98, 82, 194, 242, 162, 146, + 159, 175, 255, 207, 95, 111, 63, 15, + 107, 91, 11, 59, 171, 155, 203, 251, + 246, 198, 150, 166, 54, 6, 86, 102, + 76, 124, 44, 28, 140, 188, 236, 220, + 209, 225, 177, 129, 17, 33, 113, 65, + 185, 137, 217, 233, 121, 73, 25, 41, + 36, 20, 68, 116, 228, 212, 132, 180, + 158, 174, 254, 206, 94, 110, 62, 14, + 3, 51, 99, 83, 195, 243, 163, 147, + 247, 199, 151, 167, 55, 7, 87, 103, + 106, 90, 10, 58, 170, 154, 202, 250, + 208, 224, 176, 128, 16, 32, 112, 64, + 77, 125, 45, 29, 141, 189, 237, 221 }, + { 0, 49, 98, 83, 196, 245, 166, 151, + 149, 164, 247, 198, 81, 96, 51, 2, + 55, 6, 85, 100, 243, 194, 145, 160, + 162, 147, 192, 241, 102, 87, 4, 53, + 110, 95, 12, 61, 170, 155, 200, 249, + 251, 202, 153, 168, 63, 14, 93, 108, + 89, 104, 59, 10, 157, 172, 255, 206, + 204, 253, 174, 159, 8, 57, 106, 91, + 220, 237, 190, 143, 24, 41, 122, 75, + 73, 120, 43, 26, 141, 188, 239, 222, + 235, 218, 137, 184, 47, 30, 77, 124, + 126, 79, 28, 45, 186, 139, 216, 233, + 178, 131, 208, 225, 118, 71, 20, 37, + 39, 22, 69, 116, 227, 210, 129, 176, + 133, 180, 231, 214, 65, 112, 35, 18, + 16, 33, 114, 67, 212, 229, 182, 135, + 165, 148, 199, 246, 97, 80, 3, 50, + 48, 1, 82, 99, 244, 197, 150, 167, + 146, 163, 240, 193, 86, 103, 52, 5, + 7, 54, 101, 84, 195, 242, 161, 144, + 203, 250, 169, 152, 15, 62, 109, 92, + 94, 111, 60, 13, 154, 171, 248, 201, + 252, 205, 158, 175, 56, 9, 90, 107, + 105, 88, 11, 58, 173, 156, 207, 254, + 121, 72, 27, 42, 189, 140, 223, 238, + 236, 221, 142, 191, 40, 25, 74, 123, + 78, 127, 44, 29, 138, 187, 232, 217, + 219, 234, 185, 136, 31, 46, 125, 76, + 23, 38, 117, 68, 211, 226, 177, 128, + 130, 179, 224, 209, 70, 119, 36, 21, + 32, 17, 66, 115, 228, 213, 134, 183, + 181, 132, 215, 230, 113, 64, 19, 34 }, + { 0, 50, 100, 86, 200, 250, 172, 158, + 141, 191, 233, 219, 69, 119, 33, 19, + 7, 53, 99, 81, 207, 253, 171, 153, + 138, 184, 238, 220, 66, 112, 38, 20, + 14, 60, 106, 88, 198, 244, 162, 144, + 131, 177, 231, 213, 75, 121, 47, 29, + 9, 59, 109, 95, 193, 243, 165, 151, + 132, 182, 224, 210, 76, 126, 40, 26, + 28, 46, 120, 74, 212, 230, 176, 130, + 145, 163, 245, 199, 89, 107, 61, 15, + 27, 41, 127, 77, 211, 225, 183, 133, + 150, 164, 242, 192, 94, 108, 58, 8, + 18, 32, 118, 68, 218, 232, 190, 140, + 159, 173, 251, 201, 87, 101, 51, 1, + 21, 39, 113, 67, 221, 239, 185, 139, + 152, 170, 252, 206, 80, 98, 52, 6, + 56, 10, 92, 110, 240, 194, 148, 166, + 181, 135, 209, 227, 125, 79, 25, 43, + 63, 13, 91, 105, 247, 197, 147, 161, + 178, 128, 214, 228, 122, 72, 30, 44, + 54, 4, 82, 96, 254, 204, 154, 168, + 187, 137, 223, 237, 115, 65, 23, 37, + 49, 3, 85, 103, 249, 203, 157, 175, + 188, 142, 216, 234, 116, 70, 16, 34, + 36, 22, 64, 114, 236, 222, 136, 186, + 169, 155, 205, 255, 97, 83, 5, 55, + 35, 17, 71, 117, 235, 217, 143, 189, + 174, 156, 202, 248, 102, 84, 2, 48, + 42, 24, 78, 124, 226, 208, 134, 180, + 167, 149, 195, 241, 111, 93, 11, 57, + 45, 31, 73, 123, 229, 215, 129, 179, + 160, 146, 196, 246, 104, 90, 12, 62 }, + { 0, 51, 102, 85, 204, 255, 170, 153, + 133, 182, 227, 208, 73, 122, 47, 28, + 23, 36, 113, 66, 219, 232, 189, 142, + 146, 161, 244, 199, 94, 109, 56, 11, + 46, 29, 72, 123, 226, 209, 132, 183, + 171, 152, 205, 254, 103, 84, 1, 50, + 57, 10, 95, 108, 245, 198, 147, 160, + 188, 143, 218, 233, 112, 67, 22, 37, + 92, 111, 58, 9, 144, 163, 246, 197, + 217, 234, 191, 140, 21, 38, 115, 64, + 75, 120, 45, 30, 135, 180, 225, 210, + 206, 253, 168, 155, 2, 49, 100, 87, + 114, 65, 20, 39, 190, 141, 216, 235, + 247, 196, 145, 162, 59, 8, 93, 110, + 101, 86, 3, 48, 169, 154, 207, 252, + 224, 211, 134, 181, 44, 31, 74, 121, + 184, 139, 222, 237, 116, 71, 18, 33, + 61, 14, 91, 104, 241, 194, 151, 164, + 175, 156, 201, 250, 99, 80, 5, 54, + 42, 25, 76, 127, 230, 213, 128, 179, + 150, 165, 240, 195, 90, 105, 60, 15, + 19, 32, 117, 70, 223, 236, 185, 138, + 129, 178, 231, 212, 77, 126, 43, 24, + 4, 55, 98, 81, 200, 251, 174, 157, + 228, 215, 130, 177, 40, 27, 78, 125, + 97, 82, 7, 52, 173, 158, 203, 248, + 243, 192, 149, 166, 63, 12, 89, 106, + 118, 69, 16, 35, 186, 137, 220, 239, + 202, 249, 172, 159, 6, 53, 96, 83, + 79, 124, 41, 26, 131, 176, 229, 214, + 221, 238, 187, 136, 17, 34, 119, 68, + 88, 107, 62, 13, 148, 167, 242, 193 }, + { 0, 52, 104, 92, 208, 228, 184, 140, + 189, 137, 213, 225, 109, 89, 5, 49, + 103, 83, 15, 59, 183, 131, 223, 235, + 218, 238, 178, 134, 10, 62, 98, 86, + 206, 250, 166, 146, 30, 42, 118, 66, + 115, 71, 27, 47, 163, 151, 203, 255, + 169, 157, 193, 245, 121, 77, 17, 37, + 20, 32, 124, 72, 196, 240, 172, 152, + 129, 181, 233, 221, 81, 101, 57, 13, + 60, 8, 84, 96, 236, 216, 132, 176, + 230, 210, 142, 186, 54, 2, 94, 106, + 91, 111, 51, 7, 139, 191, 227, 215, + 79, 123, 39, 19, 159, 171, 247, 195, + 242, 198, 154, 174, 34, 22, 74, 126, + 40, 28, 64, 116, 248, 204, 144, 164, + 149, 161, 253, 201, 69, 113, 45, 25, + 31, 43, 119, 67, 207, 251, 167, 147, + 162, 150, 202, 254, 114, 70, 26, 46, + 120, 76, 16, 36, 168, 156, 192, 244, + 197, 241, 173, 153, 21, 33, 125, 73, + 209, 229, 185, 141, 1, 53, 105, 93, + 108, 88, 4, 48, 188, 136, 212, 224, + 182, 130, 222, 234, 102, 82, 14, 58, + 11, 63, 99, 87, 219, 239, 179, 135, + 158, 170, 246, 194, 78, 122, 38, 18, + 35, 23, 75, 127, 243, 199, 155, 175, + 249, 205, 145, 165, 41, 29, 65, 117, + 68, 112, 44, 24, 148, 160, 252, 200, + 80, 100, 56, 12, 128, 180, 232, 220, + 237, 217, 133, 177, 61, 9, 85, 97, + 55, 3, 95, 107, 231, 211, 143, 187, + 138, 190, 226, 214, 90, 110, 50, 6 }, + { 0, 53, 106, 95, 212, 225, 190, 139, + 181, 128, 223, 234, 97, 84, 11, 62, + 119, 66, 29, 40, 163, 150, 201, 252, + 194, 247, 168, 157, 22, 35, 124, 73, + 238, 219, 132, 177, 58, 15, 80, 101, + 91, 110, 49, 4, 143, 186, 229, 208, + 153, 172, 243, 198, 77, 120, 39, 18, + 44, 25, 70, 115, 248, 205, 146, 167, + 193, 244, 171, 158, 21, 32, 127, 74, + 116, 65, 30, 43, 160, 149, 202, 255, + 182, 131, 220, 233, 98, 87, 8, 61, + 3, 54, 105, 92, 215, 226, 189, 136, + 47, 26, 69, 112, 251, 206, 145, 164, + 154, 175, 240, 197, 78, 123, 36, 17, + 88, 109, 50, 7, 140, 185, 230, 211, + 237, 216, 135, 178, 57, 12, 83, 102, + 159, 170, 245, 192, 75, 126, 33, 20, + 42, 31, 64, 117, 254, 203, 148, 161, + 232, 221, 130, 183, 60, 9, 86, 99, + 93, 104, 55, 2, 137, 188, 227, 214, + 113, 68, 27, 46, 165, 144, 207, 250, + 196, 241, 174, 155, 16, 37, 122, 79, + 6, 51, 108, 89, 210, 231, 184, 141, + 179, 134, 217, 236, 103, 82, 13, 56, + 94, 107, 52, 1, 138, 191, 224, 213, + 235, 222, 129, 180, 63, 10, 85, 96, + 41, 28, 67, 118, 253, 200, 151, 162, + 156, 169, 246, 195, 72, 125, 34, 23, + 176, 133, 218, 239, 100, 81, 14, 59, + 5, 48, 111, 90, 209, 228, 187, 142, + 199, 242, 173, 152, 19, 38, 121, 76, + 114, 71, 24, 45, 166, 147, 204, 249 }, + { 0, 54, 108, 90, 216, 238, 180, 130, + 173, 155, 193, 247, 117, 67, 25, 47, + 71, 113, 43, 29, 159, 169, 243, 197, + 234, 220, 134, 176, 50, 4, 94, 104, + 142, 184, 226, 212, 86, 96, 58, 12, + 35, 21, 79, 121, 251, 205, 151, 161, + 201, 255, 165, 147, 17, 39, 125, 75, + 100, 82, 8, 62, 188, 138, 208, 230, + 1, 55, 109, 91, 217, 239, 181, 131, + 172, 154, 192, 246, 116, 66, 24, 46, + 70, 112, 42, 28, 158, 168, 242, 196, + 235, 221, 135, 177, 51, 5, 95, 105, + 143, 185, 227, 213, 87, 97, 59, 13, + 34, 20, 78, 120, 250, 204, 150, 160, + 200, 254, 164, 146, 16, 38, 124, 74, + 101, 83, 9, 63, 189, 139, 209, 231, + 2, 52, 110, 88, 218, 236, 182, 128, + 175, 153, 195, 245, 119, 65, 27, 45, + 69, 115, 41, 31, 157, 171, 241, 199, + 232, 222, 132, 178, 48, 6, 92, 106, + 140, 186, 224, 214, 84, 98, 56, 14, + 33, 23, 77, 123, 249, 207, 149, 163, + 203, 253, 167, 145, 19, 37, 127, 73, + 102, 80, 10, 60, 190, 136, 210, 228, + 3, 53, 111, 89, 219, 237, 183, 129, + 174, 152, 194, 244, 118, 64, 26, 44, + 68, 114, 40, 30, 156, 170, 240, 198, + 233, 223, 133, 179, 49, 7, 93, 107, + 141, 187, 225, 215, 85, 99, 57, 15, + 32, 22, 76, 122, 248, 206, 148, 162, + 202, 252, 166, 144, 18, 36, 126, 72, + 103, 81, 11, 61, 191, 137, 211, 229 }, + { 0, 55, 110, 89, 220, 235, 178, 133, + 165, 146, 203, 252, 121, 78, 23, 32, + 87, 96, 57, 14, 139, 188, 229, 210, + 242, 197, 156, 171, 46, 25, 64, 119, + 174, 153, 192, 247, 114, 69, 28, 43, + 11, 60, 101, 82, 215, 224, 185, 142, + 249, 206, 151, 160, 37, 18, 75, 124, + 92, 107, 50, 5, 128, 183, 238, 217, + 65, 118, 47, 24, 157, 170, 243, 196, + 228, 211, 138, 189, 56, 15, 86, 97, + 22, 33, 120, 79, 202, 253, 164, 147, + 179, 132, 221, 234, 111, 88, 1, 54, + 239, 216, 129, 182, 51, 4, 93, 106, + 74, 125, 36, 19, 150, 161, 248, 207, + 184, 143, 214, 225, 100, 83, 10, 61, + 29, 42, 115, 68, 193, 246, 175, 152, + 130, 181, 236, 219, 94, 105, 48, 7, + 39, 16, 73, 126, 251, 204, 149, 162, + 213, 226, 187, 140, 9, 62, 103, 80, + 112, 71, 30, 41, 172, 155, 194, 245, + 44, 27, 66, 117, 240, 199, 158, 169, + 137, 190, 231, 208, 85, 98, 59, 12, + 123, 76, 21, 34, 167, 144, 201, 254, + 222, 233, 176, 135, 2, 53, 108, 91, + 195, 244, 173, 154, 31, 40, 113, 70, + 102, 81, 8, 63, 186, 141, 212, 227, + 148, 163, 250, 205, 72, 127, 38, 17, + 49, 6, 95, 104, 237, 218, 131, 180, + 109, 90, 3, 52, 177, 134, 223, 232, + 200, 255, 166, 145, 20, 35, 122, 77, + 58, 13, 84, 99, 230, 209, 136, 191, + 159, 168, 241, 198, 67, 116, 45, 26 }, + { 0, 56, 112, 72, 224, 216, 144, 168, + 221, 229, 173, 149, 61, 5, 77, 117, + 167, 159, 215, 239, 71, 127, 55, 15, + 122, 66, 10, 50, 154, 162, 234, 210, + 83, 107, 35, 27, 179, 139, 195, 251, + 142, 182, 254, 198, 110, 86, 30, 38, + 244, 204, 132, 188, 20, 44, 100, 92, + 41, 17, 89, 97, 201, 241, 185, 129, + 166, 158, 214, 238, 70, 126, 54, 14, + 123, 67, 11, 51, 155, 163, 235, 211, + 1, 57, 113, 73, 225, 217, 145, 169, + 220, 228, 172, 148, 60, 4, 76, 116, + 245, 205, 133, 189, 21, 45, 101, 93, + 40, 16, 88, 96, 200, 240, 184, 128, + 82, 106, 34, 26, 178, 138, 194, 250, + 143, 183, 255, 199, 111, 87, 31, 39, + 81, 105, 33, 25, 177, 137, 193, 249, + 140, 180, 252, 196, 108, 84, 28, 36, + 246, 206, 134, 190, 22, 46, 102, 94, + 43, 19, 91, 99, 203, 243, 187, 131, + 2, 58, 114, 74, 226, 218, 146, 170, + 223, 231, 175, 151, 63, 7, 79, 119, + 165, 157, 213, 237, 69, 125, 53, 13, + 120, 64, 8, 48, 152, 160, 232, 208, + 247, 207, 135, 191, 23, 47, 103, 95, + 42, 18, 90, 98, 202, 242, 186, 130, + 80, 104, 32, 24, 176, 136, 192, 248, + 141, 181, 253, 197, 109, 85, 29, 37, + 164, 156, 212, 236, 68, 124, 52, 12, + 121, 65, 9, 49, 153, 161, 233, 209, + 3, 59, 115, 75, 227, 219, 147, 171, + 222, 230, 174, 150, 62, 6, 78, 118 }, + { 0, 57, 114, 75, 228, 221, 150, 175, + 213, 236, 167, 158, 49, 8, 67, 122, + 183, 142, 197, 252, 83, 106, 33, 24, + 98, 91, 16, 41, 134, 191, 244, 205, + 115, 74, 1, 56, 151, 174, 229, 220, + 166, 159, 212, 237, 66, 123, 48, 9, + 196, 253, 182, 143, 32, 25, 82, 107, + 17, 40, 99, 90, 245, 204, 135, 190, + 230, 223, 148, 173, 2, 59, 112, 73, + 51, 10, 65, 120, 215, 238, 165, 156, + 81, 104, 35, 26, 181, 140, 199, 254, + 132, 189, 246, 207, 96, 89, 18, 43, + 149, 172, 231, 222, 113, 72, 3, 58, + 64, 121, 50, 11, 164, 157, 214, 239, + 34, 27, 80, 105, 198, 255, 180, 141, + 247, 206, 133, 188, 19, 42, 97, 88, + 209, 232, 163, 154, 53, 12, 71, 126, + 4, 61, 118, 79, 224, 217, 146, 171, + 102, 95, 20, 45, 130, 187, 240, 201, + 179, 138, 193, 248, 87, 110, 37, 28, + 162, 155, 208, 233, 70, 127, 52, 13, + 119, 78, 5, 60, 147, 170, 225, 216, + 21, 44, 103, 94, 241, 200, 131, 186, + 192, 249, 178, 139, 36, 29, 86, 111, + 55, 14, 69, 124, 211, 234, 161, 152, + 226, 219, 144, 169, 6, 63, 116, 77, + 128, 185, 242, 203, 100, 93, 22, 47, + 85, 108, 39, 30, 177, 136, 195, 250, + 68, 125, 54, 15, 160, 153, 210, 235, + 145, 168, 227, 218, 117, 76, 7, 62, + 243, 202, 129, 184, 23, 46, 101, 92, + 38, 31, 84, 109, 194, 251, 176, 137 }, + { 0, 58, 116, 78, 232, 210, 156, 166, + 205, 247, 185, 131, 37, 31, 81, 107, + 135, 189, 243, 201, 111, 85, 27, 33, + 74, 112, 62, 4, 162, 152, 214, 236, + 19, 41, 103, 93, 251, 193, 143, 181, + 222, 228, 170, 144, 54, 12, 66, 120, + 148, 174, 224, 218, 124, 70, 8, 50, + 89, 99, 45, 23, 177, 139, 197, 255, + 38, 28, 82, 104, 206, 244, 186, 128, + 235, 209, 159, 165, 3, 57, 119, 77, + 161, 155, 213, 239, 73, 115, 61, 7, + 108, 86, 24, 34, 132, 190, 240, 202, + 53, 15, 65, 123, 221, 231, 169, 147, + 248, 194, 140, 182, 16, 42, 100, 94, + 178, 136, 198, 252, 90, 96, 46, 20, + 127, 69, 11, 49, 151, 173, 227, 217, + 76, 118, 56, 2, 164, 158, 208, 234, + 129, 187, 245, 207, 105, 83, 29, 39, + 203, 241, 191, 133, 35, 25, 87, 109, + 6, 60, 114, 72, 238, 212, 154, 160, + 95, 101, 43, 17, 183, 141, 195, 249, + 146, 168, 230, 220, 122, 64, 14, 52, + 216, 226, 172, 150, 48, 10, 68, 126, + 21, 47, 97, 91, 253, 199, 137, 179, + 106, 80, 30, 36, 130, 184, 246, 204, + 167, 157, 211, 233, 79, 117, 59, 1, + 237, 215, 153, 163, 5, 63, 113, 75, + 32, 26, 84, 110, 200, 242, 188, 134, + 121, 67, 13, 55, 145, 171, 229, 223, + 180, 142, 192, 250, 92, 102, 40, 18, + 254, 196, 138, 176, 22, 44, 98, 88, + 51, 9, 71, 125, 219, 225, 175, 149 }, + { 0, 59, 118, 77, 236, 215, 154, 161, + 197, 254, 179, 136, 41, 18, 95, 100, + 151, 172, 225, 218, 123, 64, 13, 54, + 82, 105, 36, 31, 190, 133, 200, 243, + 51, 8, 69, 126, 223, 228, 169, 146, + 246, 205, 128, 187, 26, 33, 108, 87, + 164, 159, 210, 233, 72, 115, 62, 5, + 97, 90, 23, 44, 141, 182, 251, 192, + 102, 93, 16, 43, 138, 177, 252, 199, + 163, 152, 213, 238, 79, 116, 57, 2, + 241, 202, 135, 188, 29, 38, 107, 80, + 52, 15, 66, 121, 216, 227, 174, 149, + 85, 110, 35, 24, 185, 130, 207, 244, + 144, 171, 230, 221, 124, 71, 10, 49, + 194, 249, 180, 143, 46, 21, 88, 99, + 7, 60, 113, 74, 235, 208, 157, 166, + 204, 247, 186, 129, 32, 27, 86, 109, + 9, 50, 127, 68, 229, 222, 147, 168, + 91, 96, 45, 22, 183, 140, 193, 250, + 158, 165, 232, 211, 114, 73, 4, 63, + 255, 196, 137, 178, 19, 40, 101, 94, + 58, 1, 76, 119, 214, 237, 160, 155, + 104, 83, 30, 37, 132, 191, 242, 201, + 173, 150, 219, 224, 65, 122, 55, 12, + 170, 145, 220, 231, 70, 125, 48, 11, + 111, 84, 25, 34, 131, 184, 245, 206, + 61, 6, 75, 112, 209, 234, 167, 156, + 248, 195, 142, 181, 20, 47, 98, 89, + 153, 162, 239, 212, 117, 78, 3, 56, + 92, 103, 42, 17, 176, 139, 198, 253, + 14, 53, 120, 67, 226, 217, 148, 175, + 203, 240, 189, 134, 39, 28, 81, 106 }, + { 0, 60, 120, 68, 240, 204, 136, 180, + 253, 193, 133, 185, 13, 49, 117, 73, + 231, 219, 159, 163, 23, 43, 111, 83, + 26, 38, 98, 94, 234, 214, 146, 174, + 211, 239, 171, 151, 35, 31, 91, 103, + 46, 18, 86, 106, 222, 226, 166, 154, + 52, 8, 76, 112, 196, 248, 188, 128, + 201, 245, 177, 141, 57, 5, 65, 125, + 187, 135, 195, 255, 75, 119, 51, 15, + 70, 122, 62, 2, 182, 138, 206, 242, + 92, 96, 36, 24, 172, 144, 212, 232, + 161, 157, 217, 229, 81, 109, 41, 21, + 104, 84, 16, 44, 152, 164, 224, 220, + 149, 169, 237, 209, 101, 89, 29, 33, + 143, 179, 247, 203, 127, 67, 7, 59, + 114, 78, 10, 54, 130, 190, 250, 198, + 107, 87, 19, 47, 155, 167, 227, 223, + 150, 170, 238, 210, 102, 90, 30, 34, + 140, 176, 244, 200, 124, 64, 4, 56, + 113, 77, 9, 53, 129, 189, 249, 197, + 184, 132, 192, 252, 72, 116, 48, 12, + 69, 121, 61, 1, 181, 137, 205, 241, + 95, 99, 39, 27, 175, 147, 215, 235, + 162, 158, 218, 230, 82, 110, 42, 22, + 208, 236, 168, 148, 32, 28, 88, 100, + 45, 17, 85, 105, 221, 225, 165, 153, + 55, 11, 79, 115, 199, 251, 191, 131, + 202, 246, 178, 142, 58, 6, 66, 126, + 3, 63, 123, 71, 243, 207, 139, 183, + 254, 194, 134, 186, 14, 50, 118, 74, + 228, 216, 156, 160, 20, 40, 108, 80, + 25, 37, 97, 93, 233, 213, 145, 173 }, + { 0, 61, 122, 71, 244, 201, 142, 179, + 245, 200, 143, 178, 1, 60, 123, 70, + 247, 202, 141, 176, 3, 62, 121, 68, + 2, 63, 120, 69, 246, 203, 140, 177, + 243, 206, 137, 180, 7, 58, 125, 64, + 6, 59, 124, 65, 242, 207, 136, 181, + 4, 57, 126, 67, 240, 205, 138, 183, + 241, 204, 139, 182, 5, 56, 127, 66, + 251, 198, 129, 188, 15, 50, 117, 72, + 14, 51, 116, 73, 250, 199, 128, 189, + 12, 49, 118, 75, 248, 197, 130, 191, + 249, 196, 131, 190, 13, 48, 119, 74, + 8, 53, 114, 79, 252, 193, 134, 187, + 253, 192, 135, 186, 9, 52, 115, 78, + 255, 194, 133, 184, 11, 54, 113, 76, + 10, 55, 112, 77, 254, 195, 132, 185, + 235, 214, 145, 172, 31, 34, 101, 88, + 30, 35, 100, 89, 234, 215, 144, 173, + 28, 33, 102, 91, 232, 213, 146, 175, + 233, 212, 147, 174, 29, 32, 103, 90, + 24, 37, 98, 95, 236, 209, 150, 171, + 237, 208, 151, 170, 25, 36, 99, 94, + 239, 210, 149, 168, 27, 38, 97, 92, + 26, 39, 96, 93, 238, 211, 148, 169, + 16, 45, 106, 87, 228, 217, 158, 163, + 229, 216, 159, 162, 17, 44, 107, 86, + 231, 218, 157, 160, 19, 46, 105, 84, + 18, 47, 104, 85, 230, 219, 156, 161, + 227, 222, 153, 164, 23, 42, 109, 80, + 22, 43, 108, 81, 226, 223, 152, 165, + 20, 41, 110, 83, 224, 221, 154, 167, + 225, 220, 155, 166, 21, 40, 111, 82 }, + { 0, 62, 124, 66, 248, 198, 132, 186, + 237, 211, 145, 175, 21, 43, 105, 87, + 199, 249, 187, 133, 63, 1, 67, 125, + 42, 20, 86, 104, 210, 236, 174, 144, + 147, 173, 239, 209, 107, 85, 23, 41, + 126, 64, 2, 60, 134, 184, 250, 196, + 84, 106, 40, 22, 172, 146, 208, 238, + 185, 135, 197, 251, 65, 127, 61, 3, + 59, 5, 71, 121, 195, 253, 191, 129, + 214, 232, 170, 148, 46, 16, 82, 108, + 252, 194, 128, 190, 4, 58, 120, 70, + 17, 47, 109, 83, 233, 215, 149, 171, + 168, 150, 212, 234, 80, 110, 44, 18, + 69, 123, 57, 7, 189, 131, 193, 255, + 111, 81, 19, 45, 151, 169, 235, 213, + 130, 188, 254, 192, 122, 68, 6, 56, + 118, 72, 10, 52, 142, 176, 242, 204, + 155, 165, 231, 217, 99, 93, 31, 33, + 177, 143, 205, 243, 73, 119, 53, 11, + 92, 98, 32, 30, 164, 154, 216, 230, + 229, 219, 153, 167, 29, 35, 97, 95, + 8, 54, 116, 74, 240, 206, 140, 178, + 34, 28, 94, 96, 218, 228, 166, 152, + 207, 241, 179, 141, 55, 9, 75, 117, + 77, 115, 49, 15, 181, 139, 201, 247, + 160, 158, 220, 226, 88, 102, 36, 26, + 138, 180, 246, 200, 114, 76, 14, 48, + 103, 89, 27, 37, 159, 161, 227, 221, + 222, 224, 162, 156, 38, 24, 90, 100, + 51, 13, 79, 113, 203, 245, 183, 137, + 25, 39, 101, 91, 225, 223, 157, 163, + 244, 202, 136, 182, 12, 50, 112, 78 }, + { 0, 63, 126, 65, 252, 195, 130, 189, + 229, 218, 155, 164, 25, 38, 103, 88, + 215, 232, 169, 150, 43, 20, 85, 106, + 50, 13, 76, 115, 206, 241, 176, 143, + 179, 140, 205, 242, 79, 112, 49, 14, + 86, 105, 40, 23, 170, 149, 212, 235, + 100, 91, 26, 37, 152, 167, 230, 217, + 129, 190, 255, 192, 125, 66, 3, 60, + 123, 68, 5, 58, 135, 184, 249, 198, + 158, 161, 224, 223, 98, 93, 28, 35, + 172, 147, 210, 237, 80, 111, 46, 17, + 73, 118, 55, 8, 181, 138, 203, 244, + 200, 247, 182, 137, 52, 11, 74, 117, + 45, 18, 83, 108, 209, 238, 175, 144, + 31, 32, 97, 94, 227, 220, 157, 162, + 250, 197, 132, 187, 6, 57, 120, 71, + 246, 201, 136, 183, 10, 53, 116, 75, + 19, 44, 109, 82, 239, 208, 145, 174, + 33, 30, 95, 96, 221, 226, 163, 156, + 196, 251, 186, 133, 56, 7, 70, 121, + 69, 122, 59, 4, 185, 134, 199, 248, + 160, 159, 222, 225, 92, 99, 34, 29, + 146, 173, 236, 211, 110, 81, 16, 47, + 119, 72, 9, 54, 139, 180, 245, 202, + 141, 178, 243, 204, 113, 78, 15, 48, + 104, 87, 22, 41, 148, 171, 234, 213, + 90, 101, 36, 27, 166, 153, 216, 231, + 191, 128, 193, 254, 67, 124, 61, 2, + 62, 1, 64, 127, 194, 253, 188, 131, + 219, 228, 165, 154, 39, 24, 89, 102, + 233, 214, 151, 168, 21, 42, 107, 84, + 12, 51, 114, 77, 240, 207, 142, 177 }, + { 0, 64, 128, 192, 29, 93, 157, 221, + 58, 122, 186, 250, 39, 103, 167, 231, + 116, 52, 244, 180, 105, 41, 233, 169, + 78, 14, 206, 142, 83, 19, 211, 147, + 232, 168, 104, 40, 245, 181, 117, 53, + 210, 146, 82, 18, 207, 143, 79, 15, + 156, 220, 28, 92, 129, 193, 1, 65, + 166, 230, 38, 102, 187, 251, 59, 123, + 205, 141, 77, 13, 208, 144, 80, 16, + 247, 183, 119, 55, 234, 170, 106, 42, + 185, 249, 57, 121, 164, 228, 36, 100, + 131, 195, 3, 67, 158, 222, 30, 94, + 37, 101, 165, 229, 56, 120, 184, 248, + 31, 95, 159, 223, 2, 66, 130, 194, + 81, 17, 209, 145, 76, 12, 204, 140, + 107, 43, 235, 171, 118, 54, 246, 182, + 135, 199, 7, 71, 154, 218, 26, 90, + 189, 253, 61, 125, 160, 224, 32, 96, + 243, 179, 115, 51, 238, 174, 110, 46, + 201, 137, 73, 9, 212, 148, 84, 20, + 111, 47, 239, 175, 114, 50, 242, 178, + 85, 21, 213, 149, 72, 8, 200, 136, + 27, 91, 155, 219, 6, 70, 134, 198, + 33, 97, 161, 225, 60, 124, 188, 252, + 74, 10, 202, 138, 87, 23, 215, 151, + 112, 48, 240, 176, 109, 45, 237, 173, + 62, 126, 190, 254, 35, 99, 163, 227, + 4, 68, 132, 196, 25, 89, 153, 217, + 162, 226, 34, 98, 191, 255, 63, 127, + 152, 216, 24, 88, 133, 197, 5, 69, + 214, 150, 86, 22, 203, 139, 75, 11, + 236, 172, 108, 44, 241, 177, 113, 49 }, + { 0, 65, 130, 195, 25, 88, 155, 218, + 50, 115, 176, 241, 43, 106, 169, 232, + 100, 37, 230, 167, 125, 60, 255, 190, + 86, 23, 212, 149, 79, 14, 205, 140, + 200, 137, 74, 11, 209, 144, 83, 18, + 250, 187, 120, 57, 227, 162, 97, 32, + 172, 237, 46, 111, 181, 244, 55, 118, + 158, 223, 28, 93, 135, 198, 5, 68, + 141, 204, 15, 78, 148, 213, 22, 87, + 191, 254, 61, 124, 166, 231, 36, 101, + 233, 168, 107, 42, 240, 177, 114, 51, + 219, 154, 89, 24, 194, 131, 64, 1, + 69, 4, 199, 134, 92, 29, 222, 159, + 119, 54, 245, 180, 110, 47, 236, 173, + 33, 96, 163, 226, 56, 121, 186, 251, + 19, 82, 145, 208, 10, 75, 136, 201, + 7, 70, 133, 196, 30, 95, 156, 221, + 53, 116, 183, 246, 44, 109, 174, 239, + 99, 34, 225, 160, 122, 59, 248, 185, + 81, 16, 211, 146, 72, 9, 202, 139, + 207, 142, 77, 12, 214, 151, 84, 21, + 253, 188, 127, 62, 228, 165, 102, 39, + 171, 234, 41, 104, 178, 243, 48, 113, + 153, 216, 27, 90, 128, 193, 2, 67, + 138, 203, 8, 73, 147, 210, 17, 80, + 184, 249, 58, 123, 161, 224, 35, 98, + 238, 175, 108, 45, 247, 182, 117, 52, + 220, 157, 94, 31, 197, 132, 71, 6, + 66, 3, 192, 129, 91, 26, 217, 152, + 112, 49, 242, 179, 105, 40, 235, 170, + 38, 103, 164, 229, 63, 126, 189, 252, + 20, 85, 150, 215, 13, 76, 143, 206 }, + { 0, 66, 132, 198, 21, 87, 145, 211, + 42, 104, 174, 236, 63, 125, 187, 249, + 84, 22, 208, 146, 65, 3, 197, 135, + 126, 60, 250, 184, 107, 41, 239, 173, + 168, 234, 44, 110, 189, 255, 57, 123, + 130, 192, 6, 68, 151, 213, 19, 81, + 252, 190, 120, 58, 233, 171, 109, 47, + 214, 148, 82, 16, 195, 129, 71, 5, + 77, 15, 201, 139, 88, 26, 220, 158, + 103, 37, 227, 161, 114, 48, 246, 180, + 25, 91, 157, 223, 12, 78, 136, 202, + 51, 113, 183, 245, 38, 100, 162, 224, + 229, 167, 97, 35, 240, 178, 116, 54, + 207, 141, 75, 9, 218, 152, 94, 28, + 177, 243, 53, 119, 164, 230, 32, 98, + 155, 217, 31, 93, 142, 204, 10, 72, + 154, 216, 30, 92, 143, 205, 11, 73, + 176, 242, 52, 118, 165, 231, 33, 99, + 206, 140, 74, 8, 219, 153, 95, 29, + 228, 166, 96, 34, 241, 179, 117, 55, + 50, 112, 182, 244, 39, 101, 163, 225, + 24, 90, 156, 222, 13, 79, 137, 203, + 102, 36, 226, 160, 115, 49, 247, 181, + 76, 14, 200, 138, 89, 27, 221, 159, + 215, 149, 83, 17, 194, 128, 70, 4, + 253, 191, 121, 59, 232, 170, 108, 46, + 131, 193, 7, 69, 150, 212, 18, 80, + 169, 235, 45, 111, 188, 254, 56, 122, + 127, 61, 251, 185, 106, 40, 238, 172, + 85, 23, 209, 147, 64, 2, 196, 134, + 43, 105, 175, 237, 62, 124, 186, 248, + 1, 67, 133, 199, 20, 86, 144, 210 }, + { 0, 67, 134, 197, 17, 82, 151, 212, + 34, 97, 164, 231, 51, 112, 181, 246, + 68, 7, 194, 129, 85, 22, 211, 144, + 102, 37, 224, 163, 119, 52, 241, 178, + 136, 203, 14, 77, 153, 218, 31, 92, + 170, 233, 44, 111, 187, 248, 61, 126, + 204, 143, 74, 9, 221, 158, 91, 24, + 238, 173, 104, 43, 255, 188, 121, 58, + 13, 78, 139, 200, 28, 95, 154, 217, + 47, 108, 169, 234, 62, 125, 184, 251, + 73, 10, 207, 140, 88, 27, 222, 157, + 107, 40, 237, 174, 122, 57, 252, 191, + 133, 198, 3, 64, 148, 215, 18, 81, + 167, 228, 33, 98, 182, 245, 48, 115, + 193, 130, 71, 4, 208, 147, 86, 21, + 227, 160, 101, 38, 242, 177, 116, 55, + 26, 89, 156, 223, 11, 72, 141, 206, + 56, 123, 190, 253, 41, 106, 175, 236, + 94, 29, 216, 155, 79, 12, 201, 138, + 124, 63, 250, 185, 109, 46, 235, 168, + 146, 209, 20, 87, 131, 192, 5, 70, + 176, 243, 54, 117, 161, 226, 39, 100, + 214, 149, 80, 19, 199, 132, 65, 2, + 244, 183, 114, 49, 229, 166, 99, 32, + 23, 84, 145, 210, 6, 69, 128, 195, + 53, 118, 179, 240, 36, 103, 162, 225, + 83, 16, 213, 150, 66, 1, 196, 135, + 113, 50, 247, 180, 96, 35, 230, 165, + 159, 220, 25, 90, 142, 205, 8, 75, + 189, 254, 59, 120, 172, 239, 42, 105, + 219, 152, 93, 30, 202, 137, 76, 15, + 249, 186, 127, 60, 232, 171, 110, 45 }, + { 0, 68, 136, 204, 13, 73, 133, 193, + 26, 94, 146, 214, 23, 83, 159, 219, + 52, 112, 188, 248, 57, 125, 177, 245, + 46, 106, 166, 226, 35, 103, 171, 239, + 104, 44, 224, 164, 101, 33, 237, 169, + 114, 54, 250, 190, 127, 59, 247, 179, + 92, 24, 212, 144, 81, 21, 217, 157, + 70, 2, 206, 138, 75, 15, 195, 135, + 208, 148, 88, 28, 221, 153, 85, 17, + 202, 142, 66, 6, 199, 131, 79, 11, + 228, 160, 108, 40, 233, 173, 97, 37, + 254, 186, 118, 50, 243, 183, 123, 63, + 184, 252, 48, 116, 181, 241, 61, 121, + 162, 230, 42, 110, 175, 235, 39, 99, + 140, 200, 4, 64, 129, 197, 9, 77, + 150, 210, 30, 90, 155, 223, 19, 87, + 189, 249, 53, 113, 176, 244, 56, 124, + 167, 227, 47, 107, 170, 238, 34, 102, + 137, 205, 1, 69, 132, 192, 12, 72, + 147, 215, 27, 95, 158, 218, 22, 82, + 213, 145, 93, 25, 216, 156, 80, 20, + 207, 139, 71, 3, 194, 134, 74, 14, + 225, 165, 105, 45, 236, 168, 100, 32, + 251, 191, 115, 55, 246, 178, 126, 58, + 109, 41, 229, 161, 96, 36, 232, 172, + 119, 51, 255, 187, 122, 62, 242, 182, + 89, 29, 209, 149, 84, 16, 220, 152, + 67, 7, 203, 143, 78, 10, 198, 130, + 5, 65, 141, 201, 8, 76, 128, 196, + 31, 91, 151, 211, 18, 86, 154, 222, + 49, 117, 185, 253, 60, 120, 180, 240, + 43, 111, 163, 231, 38, 98, 174, 234 }, + { 0, 69, 138, 207, 9, 76, 131, 198, + 18, 87, 152, 221, 27, 94, 145, 212, + 36, 97, 174, 235, 45, 104, 167, 226, + 54, 115, 188, 249, 63, 122, 181, 240, + 72, 13, 194, 135, 65, 4, 203, 142, + 90, 31, 208, 149, 83, 22, 217, 156, + 108, 41, 230, 163, 101, 32, 239, 170, + 126, 59, 244, 177, 119, 50, 253, 184, + 144, 213, 26, 95, 153, 220, 19, 86, + 130, 199, 8, 77, 139, 206, 1, 68, + 180, 241, 62, 123, 189, 248, 55, 114, + 166, 227, 44, 105, 175, 234, 37, 96, + 216, 157, 82, 23, 209, 148, 91, 30, + 202, 143, 64, 5, 195, 134, 73, 12, + 252, 185, 118, 51, 245, 176, 127, 58, + 238, 171, 100, 33, 231, 162, 109, 40, + 61, 120, 183, 242, 52, 113, 190, 251, + 47, 106, 165, 224, 38, 99, 172, 233, + 25, 92, 147, 214, 16, 85, 154, 223, + 11, 78, 129, 196, 2, 71, 136, 205, + 117, 48, 255, 186, 124, 57, 246, 179, + 103, 34, 237, 168, 110, 43, 228, 161, + 81, 20, 219, 158, 88, 29, 210, 151, + 67, 6, 201, 140, 74, 15, 192, 133, + 173, 232, 39, 98, 164, 225, 46, 107, + 191, 250, 53, 112, 182, 243, 60, 121, + 137, 204, 3, 70, 128, 197, 10, 79, + 155, 222, 17, 84, 146, 215, 24, 93, + 229, 160, 111, 42, 236, 169, 102, 35, + 247, 178, 125, 56, 254, 187, 116, 49, + 193, 132, 75, 14, 200, 141, 66, 7, + 211, 150, 89, 28, 218, 159, 80, 21 }, + { 0, 70, 140, 202, 5, 67, 137, 207, + 10, 76, 134, 192, 15, 73, 131, 197, + 20, 82, 152, 222, 17, 87, 157, 219, + 30, 88, 146, 212, 27, 93, 151, 209, + 40, 110, 164, 226, 45, 107, 161, 231, + 34, 100, 174, 232, 39, 97, 171, 237, + 60, 122, 176, 246, 57, 127, 181, 243, + 54, 112, 186, 252, 51, 117, 191, 249, + 80, 22, 220, 154, 85, 19, 217, 159, + 90, 28, 214, 144, 95, 25, 211, 149, + 68, 2, 200, 142, 65, 7, 205, 139, + 78, 8, 194, 132, 75, 13, 199, 129, + 120, 62, 244, 178, 125, 59, 241, 183, + 114, 52, 254, 184, 119, 49, 251, 189, + 108, 42, 224, 166, 105, 47, 229, 163, + 102, 32, 234, 172, 99, 37, 239, 169, + 160, 230, 44, 106, 165, 227, 41, 111, + 170, 236, 38, 96, 175, 233, 35, 101, + 180, 242, 56, 126, 177, 247, 61, 123, + 190, 248, 50, 116, 187, 253, 55, 113, + 136, 206, 4, 66, 141, 203, 1, 71, + 130, 196, 14, 72, 135, 193, 11, 77, + 156, 218, 16, 86, 153, 223, 21, 83, + 150, 208, 26, 92, 147, 213, 31, 89, + 240, 182, 124, 58, 245, 179, 121, 63, + 250, 188, 118, 48, 255, 185, 115, 53, + 228, 162, 104, 46, 225, 167, 109, 43, + 238, 168, 98, 36, 235, 173, 103, 33, + 216, 158, 84, 18, 221, 155, 81, 23, + 210, 148, 94, 24, 215, 145, 91, 29, + 204, 138, 64, 6, 201, 143, 69, 3, + 198, 128, 74, 12, 195, 133, 79, 9 }, + { 0, 71, 142, 201, 1, 70, 143, 200, + 2, 69, 140, 203, 3, 68, 141, 202, + 4, 67, 138, 205, 5, 66, 139, 204, + 6, 65, 136, 207, 7, 64, 137, 206, + 8, 79, 134, 193, 9, 78, 135, 192, + 10, 77, 132, 195, 11, 76, 133, 194, + 12, 75, 130, 197, 13, 74, 131, 196, + 14, 73, 128, 199, 15, 72, 129, 198, + 16, 87, 158, 217, 17, 86, 159, 216, + 18, 85, 156, 219, 19, 84, 157, 218, + 20, 83, 154, 221, 21, 82, 155, 220, + 22, 81, 152, 223, 23, 80, 153, 222, + 24, 95, 150, 209, 25, 94, 151, 208, + 26, 93, 148, 211, 27, 92, 149, 210, + 28, 91, 146, 213, 29, 90, 147, 212, + 30, 89, 144, 215, 31, 88, 145, 214, + 32, 103, 174, 233, 33, 102, 175, 232, + 34, 101, 172, 235, 35, 100, 173, 234, + 36, 99, 170, 237, 37, 98, 171, 236, + 38, 97, 168, 239, 39, 96, 169, 238, + 40, 111, 166, 225, 41, 110, 167, 224, + 42, 109, 164, 227, 43, 108, 165, 226, + 44, 107, 162, 229, 45, 106, 163, 228, + 46, 105, 160, 231, 47, 104, 161, 230, + 48, 119, 190, 249, 49, 118, 191, 248, + 50, 117, 188, 251, 51, 116, 189, 250, + 52, 115, 186, 253, 53, 114, 187, 252, + 54, 113, 184, 255, 55, 112, 185, 254, + 56, 127, 182, 241, 57, 126, 183, 240, + 58, 125, 180, 243, 59, 124, 181, 242, + 60, 123, 178, 245, 61, 122, 179, 244, + 62, 121, 176, 247, 63, 120, 177, 246 }, + { 0, 72, 144, 216, 61, 117, 173, 229, + 122, 50, 234, 162, 71, 15, 215, 159, + 244, 188, 100, 44, 201, 129, 89, 17, + 142, 198, 30, 86, 179, 251, 35, 107, + 245, 189, 101, 45, 200, 128, 88, 16, + 143, 199, 31, 87, 178, 250, 34, 106, + 1, 73, 145, 217, 60, 116, 172, 228, + 123, 51, 235, 163, 70, 14, 214, 158, + 247, 191, 103, 47, 202, 130, 90, 18, + 141, 197, 29, 85, 176, 248, 32, 104, + 3, 75, 147, 219, 62, 118, 174, 230, + 121, 49, 233, 161, 68, 12, 212, 156, + 2, 74, 146, 218, 63, 119, 175, 231, + 120, 48, 232, 160, 69, 13, 213, 157, + 246, 190, 102, 46, 203, 131, 91, 19, + 140, 196, 28, 84, 177, 249, 33, 105, + 243, 187, 99, 43, 206, 134, 94, 22, + 137, 193, 25, 81, 180, 252, 36, 108, + 7, 79, 151, 223, 58, 114, 170, 226, + 125, 53, 237, 165, 64, 8, 208, 152, + 6, 78, 150, 222, 59, 115, 171, 227, + 124, 52, 236, 164, 65, 9, 209, 153, + 242, 186, 98, 42, 207, 135, 95, 23, + 136, 192, 24, 80, 181, 253, 37, 109, + 4, 76, 148, 220, 57, 113, 169, 225, + 126, 54, 238, 166, 67, 11, 211, 155, + 240, 184, 96, 40, 205, 133, 93, 21, + 138, 194, 26, 82, 183, 255, 39, 111, + 241, 185, 97, 41, 204, 132, 92, 20, + 139, 195, 27, 83, 182, 254, 38, 110, + 5, 77, 149, 221, 56, 112, 168, 224, + 127, 55, 239, 167, 66, 10, 210, 154 }, + { 0, 73, 146, 219, 57, 112, 171, 226, + 114, 59, 224, 169, 75, 2, 217, 144, + 228, 173, 118, 63, 221, 148, 79, 6, + 150, 223, 4, 77, 175, 230, 61, 116, + 213, 156, 71, 14, 236, 165, 126, 55, + 167, 238, 53, 124, 158, 215, 12, 69, + 49, 120, 163, 234, 8, 65, 154, 211, + 67, 10, 209, 152, 122, 51, 232, 161, + 183, 254, 37, 108, 142, 199, 28, 85, + 197, 140, 87, 30, 252, 181, 110, 39, + 83, 26, 193, 136, 106, 35, 248, 177, + 33, 104, 179, 250, 24, 81, 138, 195, + 98, 43, 240, 185, 91, 18, 201, 128, + 16, 89, 130, 203, 41, 96, 187, 242, + 134, 207, 20, 93, 191, 246, 45, 100, + 244, 189, 102, 47, 205, 132, 95, 22, + 115, 58, 225, 168, 74, 3, 216, 145, + 1, 72, 147, 218, 56, 113, 170, 227, + 151, 222, 5, 76, 174, 231, 60, 117, + 229, 172, 119, 62, 220, 149, 78, 7, + 166, 239, 52, 125, 159, 214, 13, 68, + 212, 157, 70, 15, 237, 164, 127, 54, + 66, 11, 208, 153, 123, 50, 233, 160, + 48, 121, 162, 235, 9, 64, 155, 210, + 196, 141, 86, 31, 253, 180, 111, 38, + 182, 255, 36, 109, 143, 198, 29, 84, + 32, 105, 178, 251, 25, 80, 139, 194, + 82, 27, 192, 137, 107, 34, 249, 176, + 17, 88, 131, 202, 40, 97, 186, 243, + 99, 42, 241, 184, 90, 19, 200, 129, + 245, 188, 103, 46, 204, 133, 94, 23, + 135, 206, 21, 92, 190, 247, 44, 101 }, + { 0, 74, 148, 222, 53, 127, 161, 235, + 106, 32, 254, 180, 95, 21, 203, 129, + 212, 158, 64, 10, 225, 171, 117, 63, + 190, 244, 42, 96, 139, 193, 31, 85, + 181, 255, 33, 107, 128, 202, 20, 94, + 223, 149, 75, 1, 234, 160, 126, 52, + 97, 43, 245, 191, 84, 30, 192, 138, + 11, 65, 159, 213, 62, 116, 170, 224, + 119, 61, 227, 169, 66, 8, 214, 156, + 29, 87, 137, 195, 40, 98, 188, 246, + 163, 233, 55, 125, 150, 220, 2, 72, + 201, 131, 93, 23, 252, 182, 104, 34, + 194, 136, 86, 28, 247, 189, 99, 41, + 168, 226, 60, 118, 157, 215, 9, 67, + 22, 92, 130, 200, 35, 105, 183, 253, + 124, 54, 232, 162, 73, 3, 221, 151, + 238, 164, 122, 48, 219, 145, 79, 5, + 132, 206, 16, 90, 177, 251, 37, 111, + 58, 112, 174, 228, 15, 69, 155, 209, + 80, 26, 196, 142, 101, 47, 241, 187, + 91, 17, 207, 133, 110, 36, 250, 176, + 49, 123, 165, 239, 4, 78, 144, 218, + 143, 197, 27, 81, 186, 240, 46, 100, + 229, 175, 113, 59, 208, 154, 68, 14, + 153, 211, 13, 71, 172, 230, 56, 114, + 243, 185, 103, 45, 198, 140, 82, 24, + 77, 7, 217, 147, 120, 50, 236, 166, + 39, 109, 179, 249, 18, 88, 134, 204, + 44, 102, 184, 242, 25, 83, 141, 199, + 70, 12, 210, 152, 115, 57, 231, 173, + 248, 178, 108, 38, 205, 135, 89, 19, + 146, 216, 6, 76, 167, 237, 51, 121 }, + { 0, 75, 150, 221, 49, 122, 167, 236, + 98, 41, 244, 191, 83, 24, 197, 142, + 196, 143, 82, 25, 245, 190, 99, 40, + 166, 237, 48, 123, 151, 220, 1, 74, + 149, 222, 3, 72, 164, 239, 50, 121, + 247, 188, 97, 42, 198, 141, 80, 27, + 81, 26, 199, 140, 96, 43, 246, 189, + 51, 120, 165, 238, 2, 73, 148, 223, + 55, 124, 161, 234, 6, 77, 144, 219, + 85, 30, 195, 136, 100, 47, 242, 185, + 243, 184, 101, 46, 194, 137, 84, 31, + 145, 218, 7, 76, 160, 235, 54, 125, + 162, 233, 52, 127, 147, 216, 5, 78, + 192, 139, 86, 29, 241, 186, 103, 44, + 102, 45, 240, 187, 87, 28, 193, 138, + 4, 79, 146, 217, 53, 126, 163, 232, + 110, 37, 248, 179, 95, 20, 201, 130, + 12, 71, 154, 209, 61, 118, 171, 224, + 170, 225, 60, 119, 155, 208, 13, 70, + 200, 131, 94, 21, 249, 178, 111, 36, + 251, 176, 109, 38, 202, 129, 92, 23, + 153, 210, 15, 68, 168, 227, 62, 117, + 63, 116, 169, 226, 14, 69, 152, 211, + 93, 22, 203, 128, 108, 39, 250, 177, + 89, 18, 207, 132, 104, 35, 254, 181, + 59, 112, 173, 230, 10, 65, 156, 215, + 157, 214, 11, 64, 172, 231, 58, 113, + 255, 180, 105, 34, 206, 133, 88, 19, + 204, 135, 90, 17, 253, 182, 107, 32, + 174, 229, 56, 115, 159, 212, 9, 66, + 8, 67, 158, 213, 57, 114, 175, 228, + 106, 33, 252, 183, 91, 16, 205, 134 }, + { 0, 76, 152, 212, 45, 97, 181, 249, + 90, 22, 194, 142, 119, 59, 239, 163, + 180, 248, 44, 96, 153, 213, 1, 77, + 238, 162, 118, 58, 195, 143, 91, 23, + 117, 57, 237, 161, 88, 20, 192, 140, + 47, 99, 183, 251, 2, 78, 154, 214, + 193, 141, 89, 21, 236, 160, 116, 56, + 155, 215, 3, 79, 182, 250, 46, 98, + 234, 166, 114, 62, 199, 139, 95, 19, + 176, 252, 40, 100, 157, 209, 5, 73, + 94, 18, 198, 138, 115, 63, 235, 167, + 4, 72, 156, 208, 41, 101, 177, 253, + 159, 211, 7, 75, 178, 254, 42, 102, + 197, 137, 93, 17, 232, 164, 112, 60, + 43, 103, 179, 255, 6, 74, 158, 210, + 113, 61, 233, 165, 92, 16, 196, 136, + 201, 133, 81, 29, 228, 168, 124, 48, + 147, 223, 11, 71, 190, 242, 38, 106, + 125, 49, 229, 169, 80, 28, 200, 132, + 39, 107, 191, 243, 10, 70, 146, 222, + 188, 240, 36, 104, 145, 221, 9, 69, + 230, 170, 126, 50, 203, 135, 83, 31, + 8, 68, 144, 220, 37, 105, 189, 241, + 82, 30, 202, 134, 127, 51, 231, 171, + 35, 111, 187, 247, 14, 66, 150, 218, + 121, 53, 225, 173, 84, 24, 204, 128, + 151, 219, 15, 67, 186, 246, 34, 110, + 205, 129, 85, 25, 224, 172, 120, 52, + 86, 26, 206, 130, 123, 55, 227, 175, + 12, 64, 148, 216, 33, 109, 185, 245, + 226, 174, 122, 54, 207, 131, 87, 27, + 184, 244, 32, 108, 149, 217, 13, 65 }, + { 0, 77, 154, 215, 41, 100, 179, 254, + 82, 31, 200, 133, 123, 54, 225, 172, + 164, 233, 62, 115, 141, 192, 23, 90, + 246, 187, 108, 33, 223, 146, 69, 8, + 85, 24, 207, 130, 124, 49, 230, 171, + 7, 74, 157, 208, 46, 99, 180, 249, + 241, 188, 107, 38, 216, 149, 66, 15, + 163, 238, 57, 116, 138, 199, 16, 93, + 170, 231, 48, 125, 131, 206, 25, 84, + 248, 181, 98, 47, 209, 156, 75, 6, + 14, 67, 148, 217, 39, 106, 189, 240, + 92, 17, 198, 139, 117, 56, 239, 162, + 255, 178, 101, 40, 214, 155, 76, 1, + 173, 224, 55, 122, 132, 201, 30, 83, + 91, 22, 193, 140, 114, 63, 232, 165, + 9, 68, 147, 222, 32, 109, 186, 247, + 73, 4, 211, 158, 96, 45, 250, 183, + 27, 86, 129, 204, 50, 127, 168, 229, + 237, 160, 119, 58, 196, 137, 94, 19, + 191, 242, 37, 104, 150, 219, 12, 65, + 28, 81, 134, 203, 53, 120, 175, 226, + 78, 3, 212, 153, 103, 42, 253, 176, + 184, 245, 34, 111, 145, 220, 11, 70, + 234, 167, 112, 61, 195, 142, 89, 20, + 227, 174, 121, 52, 202, 135, 80, 29, + 177, 252, 43, 102, 152, 213, 2, 79, + 71, 10, 221, 144, 110, 35, 244, 185, + 21, 88, 143, 194, 60, 113, 166, 235, + 182, 251, 44, 97, 159, 210, 5, 72, + 228, 169, 126, 51, 205, 128, 87, 26, + 18, 95, 136, 197, 59, 118, 161, 236, + 64, 13, 218, 151, 105, 36, 243, 190 }, + { 0, 78, 156, 210, 37, 107, 185, 247, + 74, 4, 214, 152, 111, 33, 243, 189, + 148, 218, 8, 70, 177, 255, 45, 99, + 222, 144, 66, 12, 251, 181, 103, 41, + 53, 123, 169, 231, 16, 94, 140, 194, + 127, 49, 227, 173, 90, 20, 198, 136, + 161, 239, 61, 115, 132, 202, 24, 86, + 235, 165, 119, 57, 206, 128, 82, 28, + 106, 36, 246, 184, 79, 1, 211, 157, + 32, 110, 188, 242, 5, 75, 153, 215, + 254, 176, 98, 44, 219, 149, 71, 9, + 180, 250, 40, 102, 145, 223, 13, 67, + 95, 17, 195, 141, 122, 52, 230, 168, + 21, 91, 137, 199, 48, 126, 172, 226, + 203, 133, 87, 25, 238, 160, 114, 60, + 129, 207, 29, 83, 164, 234, 56, 118, + 212, 154, 72, 6, 241, 191, 109, 35, + 158, 208, 2, 76, 187, 245, 39, 105, + 64, 14, 220, 146, 101, 43, 249, 183, + 10, 68, 150, 216, 47, 97, 179, 253, + 225, 175, 125, 51, 196, 138, 88, 22, + 171, 229, 55, 121, 142, 192, 18, 92, + 117, 59, 233, 167, 80, 30, 204, 130, + 63, 113, 163, 237, 26, 84, 134, 200, + 190, 240, 34, 108, 155, 213, 7, 73, + 244, 186, 104, 38, 209, 159, 77, 3, + 42, 100, 182, 248, 15, 65, 147, 221, + 96, 46, 252, 178, 69, 11, 217, 151, + 139, 197, 23, 89, 174, 224, 50, 124, + 193, 143, 93, 19, 228, 170, 120, 54, + 31, 81, 131, 205, 58, 116, 166, 232, + 85, 27, 201, 135, 112, 62, 236, 162 }, + { 0, 79, 158, 209, 33, 110, 191, 240, + 66, 13, 220, 147, 99, 44, 253, 178, + 132, 203, 26, 85, 165, 234, 59, 116, + 198, 137, 88, 23, 231, 168, 121, 54, + 21, 90, 139, 196, 52, 123, 170, 229, + 87, 24, 201, 134, 118, 57, 232, 167, + 145, 222, 15, 64, 176, 255, 46, 97, + 211, 156, 77, 2, 242, 189, 108, 35, + 42, 101, 180, 251, 11, 68, 149, 218, + 104, 39, 246, 185, 73, 6, 215, 152, + 174, 225, 48, 127, 143, 192, 17, 94, + 236, 163, 114, 61, 205, 130, 83, 28, + 63, 112, 161, 238, 30, 81, 128, 207, + 125, 50, 227, 172, 92, 19, 194, 141, + 187, 244, 37, 106, 154, 213, 4, 75, + 249, 182, 103, 40, 216, 151, 70, 9, + 84, 27, 202, 133, 117, 58, 235, 164, + 22, 89, 136, 199, 55, 120, 169, 230, + 208, 159, 78, 1, 241, 190, 111, 32, + 146, 221, 12, 67, 179, 252, 45, 98, + 65, 14, 223, 144, 96, 47, 254, 177, + 3, 76, 157, 210, 34, 109, 188, 243, + 197, 138, 91, 20, 228, 171, 122, 53, + 135, 200, 25, 86, 166, 233, 56, 119, + 126, 49, 224, 175, 95, 16, 193, 142, + 60, 115, 162, 237, 29, 82, 131, 204, + 250, 181, 100, 43, 219, 148, 69, 10, + 184, 247, 38, 105, 153, 214, 7, 72, + 107, 36, 245, 186, 74, 5, 212, 155, + 41, 102, 183, 248, 8, 71, 150, 217, + 239, 160, 113, 62, 206, 129, 80, 31, + 173, 226, 51, 124, 140, 195, 18, 93 }, + { 0, 80, 160, 240, 93, 13, 253, 173, + 186, 234, 26, 74, 231, 183, 71, 23, + 105, 57, 201, 153, 52, 100, 148, 196, + 211, 131, 115, 35, 142, 222, 46, 126, + 210, 130, 114, 34, 143, 223, 47, 127, + 104, 56, 200, 152, 53, 101, 149, 197, + 187, 235, 27, 75, 230, 182, 70, 22, + 1, 81, 161, 241, 92, 12, 252, 172, + 185, 233, 25, 73, 228, 180, 68, 20, + 3, 83, 163, 243, 94, 14, 254, 174, + 208, 128, 112, 32, 141, 221, 45, 125, + 106, 58, 202, 154, 55, 103, 151, 199, + 107, 59, 203, 155, 54, 102, 150, 198, + 209, 129, 113, 33, 140, 220, 44, 124, + 2, 82, 162, 242, 95, 15, 255, 175, + 184, 232, 24, 72, 229, 181, 69, 21, + 111, 63, 207, 159, 50, 98, 146, 194, + 213, 133, 117, 37, 136, 216, 40, 120, + 6, 86, 166, 246, 91, 11, 251, 171, + 188, 236, 28, 76, 225, 177, 65, 17, + 189, 237, 29, 77, 224, 176, 64, 16, + 7, 87, 167, 247, 90, 10, 250, 170, + 212, 132, 116, 36, 137, 217, 41, 121, + 110, 62, 206, 158, 51, 99, 147, 195, + 214, 134, 118, 38, 139, 219, 43, 123, + 108, 60, 204, 156, 49, 97, 145, 193, + 191, 239, 31, 79, 226, 178, 66, 18, + 5, 85, 165, 245, 88, 8, 248, 168, + 4, 84, 164, 244, 89, 9, 249, 169, + 190, 238, 30, 78, 227, 179, 67, 19, + 109, 61, 205, 157, 48, 96, 144, 192, + 215, 135, 119, 39, 138, 218, 42, 122 }, + { 0, 81, 162, 243, 89, 8, 251, 170, + 178, 227, 16, 65, 235, 186, 73, 24, + 121, 40, 219, 138, 32, 113, 130, 211, + 203, 154, 105, 56, 146, 195, 48, 97, + 242, 163, 80, 1, 171, 250, 9, 88, + 64, 17, 226, 179, 25, 72, 187, 234, + 139, 218, 41, 120, 210, 131, 112, 33, + 57, 104, 155, 202, 96, 49, 194, 147, + 249, 168, 91, 10, 160, 241, 2, 83, + 75, 26, 233, 184, 18, 67, 176, 225, + 128, 209, 34, 115, 217, 136, 123, 42, + 50, 99, 144, 193, 107, 58, 201, 152, + 11, 90, 169, 248, 82, 3, 240, 161, + 185, 232, 27, 74, 224, 177, 66, 19, + 114, 35, 208, 129, 43, 122, 137, 216, + 192, 145, 98, 51, 153, 200, 59, 106, + 239, 190, 77, 28, 182, 231, 20, 69, + 93, 12, 255, 174, 4, 85, 166, 247, + 150, 199, 52, 101, 207, 158, 109, 60, + 36, 117, 134, 215, 125, 44, 223, 142, + 29, 76, 191, 238, 68, 21, 230, 183, + 175, 254, 13, 92, 246, 167, 84, 5, + 100, 53, 198, 151, 61, 108, 159, 206, + 214, 135, 116, 37, 143, 222, 45, 124, + 22, 71, 180, 229, 79, 30, 237, 188, + 164, 245, 6, 87, 253, 172, 95, 14, + 111, 62, 205, 156, 54, 103, 148, 197, + 221, 140, 127, 46, 132, 213, 38, 119, + 228, 181, 70, 23, 189, 236, 31, 78, + 86, 7, 244, 165, 15, 94, 173, 252, + 157, 204, 63, 110, 196, 149, 102, 55, + 47, 126, 141, 220, 118, 39, 212, 133 }, + { 0, 82, 164, 246, 85, 7, 241, 163, + 170, 248, 14, 92, 255, 173, 91, 9, + 73, 27, 237, 191, 28, 78, 184, 234, + 227, 177, 71, 21, 182, 228, 18, 64, + 146, 192, 54, 100, 199, 149, 99, 49, + 56, 106, 156, 206, 109, 63, 201, 155, + 219, 137, 127, 45, 142, 220, 42, 120, + 113, 35, 213, 135, 36, 118, 128, 210, + 57, 107, 157, 207, 108, 62, 200, 154, + 147, 193, 55, 101, 198, 148, 98, 48, + 112, 34, 212, 134, 37, 119, 129, 211, + 218, 136, 126, 44, 143, 221, 43, 121, + 171, 249, 15, 93, 254, 172, 90, 8, + 1, 83, 165, 247, 84, 6, 240, 162, + 226, 176, 70, 20, 183, 229, 19, 65, + 72, 26, 236, 190, 29, 79, 185, 235, + 114, 32, 214, 132, 39, 117, 131, 209, + 216, 138, 124, 46, 141, 223, 41, 123, + 59, 105, 159, 205, 110, 60, 202, 152, + 145, 195, 53, 103, 196, 150, 96, 50, + 224, 178, 68, 22, 181, 231, 17, 67, + 74, 24, 238, 188, 31, 77, 187, 233, + 169, 251, 13, 95, 252, 174, 88, 10, + 3, 81, 167, 245, 86, 4, 242, 160, + 75, 25, 239, 189, 30, 76, 186, 232, + 225, 179, 69, 23, 180, 230, 16, 66, + 2, 80, 166, 244, 87, 5, 243, 161, + 168, 250, 12, 94, 253, 175, 89, 11, + 217, 139, 125, 47, 140, 222, 40, 122, + 115, 33, 215, 133, 38, 116, 130, 208, + 144, 194, 52, 102, 197, 151, 97, 51, + 58, 104, 158, 204, 111, 61, 203, 153 }, + { 0, 83, 166, 245, 81, 2, 247, 164, + 162, 241, 4, 87, 243, 160, 85, 6, + 89, 10, 255, 172, 8, 91, 174, 253, + 251, 168, 93, 14, 170, 249, 12, 95, + 178, 225, 20, 71, 227, 176, 69, 22, + 16, 67, 182, 229, 65, 18, 231, 180, + 235, 184, 77, 30, 186, 233, 28, 79, + 73, 26, 239, 188, 24, 75, 190, 237, + 121, 42, 223, 140, 40, 123, 142, 221, + 219, 136, 125, 46, 138, 217, 44, 127, + 32, 115, 134, 213, 113, 34, 215, 132, + 130, 209, 36, 119, 211, 128, 117, 38, + 203, 152, 109, 62, 154, 201, 60, 111, + 105, 58, 207, 156, 56, 107, 158, 205, + 146, 193, 52, 103, 195, 144, 101, 54, + 48, 99, 150, 197, 97, 50, 199, 148, + 242, 161, 84, 7, 163, 240, 5, 86, + 80, 3, 246, 165, 1, 82, 167, 244, + 171, 248, 13, 94, 250, 169, 92, 15, + 9, 90, 175, 252, 88, 11, 254, 173, + 64, 19, 230, 181, 17, 66, 183, 228, + 226, 177, 68, 23, 179, 224, 21, 70, + 25, 74, 191, 236, 72, 27, 238, 189, + 187, 232, 29, 78, 234, 185, 76, 31, + 139, 216, 45, 126, 218, 137, 124, 47, + 41, 122, 143, 220, 120, 43, 222, 141, + 210, 129, 116, 39, 131, 208, 37, 118, + 112, 35, 214, 133, 33, 114, 135, 212, + 57, 106, 159, 204, 104, 59, 206, 157, + 155, 200, 61, 110, 202, 153, 108, 63, + 96, 51, 198, 149, 49, 98, 151, 196, + 194, 145, 100, 55, 147, 192, 53, 102 }, + { 0, 84, 168, 252, 77, 25, 229, 177, + 154, 206, 50, 102, 215, 131, 127, 43, + 41, 125, 129, 213, 100, 48, 204, 152, + 179, 231, 27, 79, 254, 170, 86, 2, + 82, 6, 250, 174, 31, 75, 183, 227, + 200, 156, 96, 52, 133, 209, 45, 121, + 123, 47, 211, 135, 54, 98, 158, 202, + 225, 181, 73, 29, 172, 248, 4, 80, + 164, 240, 12, 88, 233, 189, 65, 21, + 62, 106, 150, 194, 115, 39, 219, 143, + 141, 217, 37, 113, 192, 148, 104, 60, + 23, 67, 191, 235, 90, 14, 242, 166, + 246, 162, 94, 10, 187, 239, 19, 71, + 108, 56, 196, 144, 33, 117, 137, 221, + 223, 139, 119, 35, 146, 198, 58, 110, + 69, 17, 237, 185, 8, 92, 160, 244, + 85, 1, 253, 169, 24, 76, 176, 228, + 207, 155, 103, 51, 130, 214, 42, 126, + 124, 40, 212, 128, 49, 101, 153, 205, + 230, 178, 78, 26, 171, 255, 3, 87, + 7, 83, 175, 251, 74, 30, 226, 182, + 157, 201, 53, 97, 208, 132, 120, 44, + 46, 122, 134, 210, 99, 55, 203, 159, + 180, 224, 28, 72, 249, 173, 81, 5, + 241, 165, 89, 13, 188, 232, 20, 64, + 107, 63, 195, 151, 38, 114, 142, 218, + 216, 140, 112, 36, 149, 193, 61, 105, + 66, 22, 234, 190, 15, 91, 167, 243, + 163, 247, 11, 95, 238, 186, 70, 18, + 57, 109, 145, 197, 116, 32, 220, 136, + 138, 222, 34, 118, 199, 147, 111, 59, + 16, 68, 184, 236, 93, 9, 245, 161 }, + { 0, 85, 170, 255, 73, 28, 227, 182, + 146, 199, 56, 109, 219, 142, 113, 36, + 57, 108, 147, 198, 112, 37, 218, 143, + 171, 254, 1, 84, 226, 183, 72, 29, + 114, 39, 216, 141, 59, 110, 145, 196, + 224, 181, 74, 31, 169, 252, 3, 86, + 75, 30, 225, 180, 2, 87, 168, 253, + 217, 140, 115, 38, 144, 197, 58, 111, + 228, 177, 78, 27, 173, 248, 7, 82, + 118, 35, 220, 137, 63, 106, 149, 192, + 221, 136, 119, 34, 148, 193, 62, 107, + 79, 26, 229, 176, 6, 83, 172, 249, + 150, 195, 60, 105, 223, 138, 117, 32, + 4, 81, 174, 251, 77, 24, 231, 178, + 175, 250, 5, 80, 230, 179, 76, 25, + 61, 104, 151, 194, 116, 33, 222, 139, + 213, 128, 127, 42, 156, 201, 54, 99, + 71, 18, 237, 184, 14, 91, 164, 241, + 236, 185, 70, 19, 165, 240, 15, 90, + 126, 43, 212, 129, 55, 98, 157, 200, + 167, 242, 13, 88, 238, 187, 68, 17, + 53, 96, 159, 202, 124, 41, 214, 131, + 158, 203, 52, 97, 215, 130, 125, 40, + 12, 89, 166, 243, 69, 16, 239, 186, + 49, 100, 155, 206, 120, 45, 210, 135, + 163, 246, 9, 92, 234, 191, 64, 21, + 8, 93, 162, 247, 65, 20, 235, 190, + 154, 207, 48, 101, 211, 134, 121, 44, + 67, 22, 233, 188, 10, 95, 160, 245, + 209, 132, 123, 46, 152, 205, 50, 103, + 122, 47, 208, 133, 51, 102, 153, 204, + 232, 189, 66, 23, 161, 244, 11, 94 }, + { 0, 86, 172, 250, 69, 19, 233, 191, + 138, 220, 38, 112, 207, 153, 99, 53, + 9, 95, 165, 243, 76, 26, 224, 182, + 131, 213, 47, 121, 198, 144, 106, 60, + 18, 68, 190, 232, 87, 1, 251, 173, + 152, 206, 52, 98, 221, 139, 113, 39, + 27, 77, 183, 225, 94, 8, 242, 164, + 145, 199, 61, 107, 212, 130, 120, 46, + 36, 114, 136, 222, 97, 55, 205, 155, + 174, 248, 2, 84, 235, 189, 71, 17, + 45, 123, 129, 215, 104, 62, 196, 146, + 167, 241, 11, 93, 226, 180, 78, 24, + 54, 96, 154, 204, 115, 37, 223, 137, + 188, 234, 16, 70, 249, 175, 85, 3, + 63, 105, 147, 197, 122, 44, 214, 128, + 181, 227, 25, 79, 240, 166, 92, 10, + 72, 30, 228, 178, 13, 91, 161, 247, + 194, 148, 110, 56, 135, 209, 43, 125, + 65, 23, 237, 187, 4, 82, 168, 254, + 203, 157, 103, 49, 142, 216, 34, 116, + 90, 12, 246, 160, 31, 73, 179, 229, + 208, 134, 124, 42, 149, 195, 57, 111, + 83, 5, 255, 169, 22, 64, 186, 236, + 217, 143, 117, 35, 156, 202, 48, 102, + 108, 58, 192, 150, 41, 127, 133, 211, + 230, 176, 74, 28, 163, 245, 15, 89, + 101, 51, 201, 159, 32, 118, 140, 218, + 239, 185, 67, 21, 170, 252, 6, 80, + 126, 40, 210, 132, 59, 109, 151, 193, + 244, 162, 88, 14, 177, 231, 29, 75, + 119, 33, 219, 141, 50, 100, 158, 200, + 253, 171, 81, 7, 184, 238, 20, 66 }, + { 0, 87, 174, 249, 65, 22, 239, 184, + 130, 213, 44, 123, 195, 148, 109, 58, + 25, 78, 183, 224, 88, 15, 246, 161, + 155, 204, 53, 98, 218, 141, 116, 35, + 50, 101, 156, 203, 115, 36, 221, 138, + 176, 231, 30, 73, 241, 166, 95, 8, + 43, 124, 133, 210, 106, 61, 196, 147, + 169, 254, 7, 80, 232, 191, 70, 17, + 100, 51, 202, 157, 37, 114, 139, 220, + 230, 177, 72, 31, 167, 240, 9, 94, + 125, 42, 211, 132, 60, 107, 146, 197, + 255, 168, 81, 6, 190, 233, 16, 71, + 86, 1, 248, 175, 23, 64, 185, 238, + 212, 131, 122, 45, 149, 194, 59, 108, + 79, 24, 225, 182, 14, 89, 160, 247, + 205, 154, 99, 52, 140, 219, 34, 117, + 200, 159, 102, 49, 137, 222, 39, 112, + 74, 29, 228, 179, 11, 92, 165, 242, + 209, 134, 127, 40, 144, 199, 62, 105, + 83, 4, 253, 170, 18, 69, 188, 235, + 250, 173, 84, 3, 187, 236, 21, 66, + 120, 47, 214, 129, 57, 110, 151, 192, + 227, 180, 77, 26, 162, 245, 12, 91, + 97, 54, 207, 152, 32, 119, 142, 217, + 172, 251, 2, 85, 237, 186, 67, 20, + 46, 121, 128, 215, 111, 56, 193, 150, + 181, 226, 27, 76, 244, 163, 90, 13, + 55, 96, 153, 206, 118, 33, 216, 143, + 158, 201, 48, 103, 223, 136, 113, 38, + 28, 75, 178, 229, 93, 10, 243, 164, + 135, 208, 41, 126, 198, 145, 104, 63, + 5, 82, 171, 252, 68, 19, 234, 189 }, + { 0, 88, 176, 232, 125, 37, 205, 149, + 250, 162, 74, 18, 135, 223, 55, 111, + 233, 177, 89, 1, 148, 204, 36, 124, + 19, 75, 163, 251, 110, 54, 222, 134, + 207, 151, 127, 39, 178, 234, 2, 90, + 53, 109, 133, 221, 72, 16, 248, 160, + 38, 126, 150, 206, 91, 3, 235, 179, + 220, 132, 108, 52, 161, 249, 17, 73, + 131, 219, 51, 107, 254, 166, 78, 22, + 121, 33, 201, 145, 4, 92, 180, 236, + 106, 50, 218, 130, 23, 79, 167, 255, + 144, 200, 32, 120, 237, 181, 93, 5, + 76, 20, 252, 164, 49, 105, 129, 217, + 182, 238, 6, 94, 203, 147, 123, 35, + 165, 253, 21, 77, 216, 128, 104, 48, + 95, 7, 239, 183, 34, 122, 146, 202, + 27, 67, 171, 243, 102, 62, 214, 142, + 225, 185, 81, 9, 156, 196, 44, 116, + 242, 170, 66, 26, 143, 215, 63, 103, + 8, 80, 184, 224, 117, 45, 197, 157, + 212, 140, 100, 60, 169, 241, 25, 65, + 46, 118, 158, 198, 83, 11, 227, 187, + 61, 101, 141, 213, 64, 24, 240, 168, + 199, 159, 119, 47, 186, 226, 10, 82, + 152, 192, 40, 112, 229, 189, 85, 13, + 98, 58, 210, 138, 31, 71, 175, 247, + 113, 41, 193, 153, 12, 84, 188, 228, + 139, 211, 59, 99, 246, 174, 70, 30, + 87, 15, 231, 191, 42, 114, 154, 194, + 173, 245, 29, 69, 208, 136, 96, 56, + 190, 230, 14, 86, 195, 155, 115, 43, + 68, 28, 244, 172, 57, 97, 137, 209 }, + { 0, 89, 178, 235, 121, 32, 203, 146, + 242, 171, 64, 25, 139, 210, 57, 96, + 249, 160, 75, 18, 128, 217, 50, 107, + 11, 82, 185, 224, 114, 43, 192, 153, + 239, 182, 93, 4, 150, 207, 36, 125, + 29, 68, 175, 246, 100, 61, 214, 143, + 22, 79, 164, 253, 111, 54, 221, 132, + 228, 189, 86, 15, 157, 196, 47, 118, + 195, 154, 113, 40, 186, 227, 8, 81, + 49, 104, 131, 218, 72, 17, 250, 163, + 58, 99, 136, 209, 67, 26, 241, 168, + 200, 145, 122, 35, 177, 232, 3, 90, + 44, 117, 158, 199, 85, 12, 231, 190, + 222, 135, 108, 53, 167, 254, 21, 76, + 213, 140, 103, 62, 172, 245, 30, 71, + 39, 126, 149, 204, 94, 7, 236, 181, + 155, 194, 41, 112, 226, 187, 80, 9, + 105, 48, 219, 130, 16, 73, 162, 251, + 98, 59, 208, 137, 27, 66, 169, 240, + 144, 201, 34, 123, 233, 176, 91, 2, + 116, 45, 198, 159, 13, 84, 191, 230, + 134, 223, 52, 109, 255, 166, 77, 20, + 141, 212, 63, 102, 244, 173, 70, 31, + 127, 38, 205, 148, 6, 95, 180, 237, + 88, 1, 234, 179, 33, 120, 147, 202, + 170, 243, 24, 65, 211, 138, 97, 56, + 161, 248, 19, 74, 216, 129, 106, 51, + 83, 10, 225, 184, 42, 115, 152, 193, + 183, 238, 5, 92, 206, 151, 124, 37, + 69, 28, 247, 174, 60, 101, 142, 215, + 78, 23, 252, 165, 55, 110, 133, 220, + 188, 229, 14, 87, 197, 156, 119, 46 }, + { 0, 90, 180, 238, 117, 47, 193, 155, + 234, 176, 94, 4, 159, 197, 43, 113, + 201, 147, 125, 39, 188, 230, 8, 82, + 35, 121, 151, 205, 86, 12, 226, 184, + 143, 213, 59, 97, 250, 160, 78, 20, + 101, 63, 209, 139, 16, 74, 164, 254, + 70, 28, 242, 168, 51, 105, 135, 221, + 172, 246, 24, 66, 217, 131, 109, 55, + 3, 89, 183, 237, 118, 44, 194, 152, + 233, 179, 93, 7, 156, 198, 40, 114, + 202, 144, 126, 36, 191, 229, 11, 81, + 32, 122, 148, 206, 85, 15, 225, 187, + 140, 214, 56, 98, 249, 163, 77, 23, + 102, 60, 210, 136, 19, 73, 167, 253, + 69, 31, 241, 171, 48, 106, 132, 222, + 175, 245, 27, 65, 218, 128, 110, 52, + 6, 92, 178, 232, 115, 41, 199, 157, + 236, 182, 88, 2, 153, 195, 45, 119, + 207, 149, 123, 33, 186, 224, 14, 84, + 37, 127, 145, 203, 80, 10, 228, 190, + 137, 211, 61, 103, 252, 166, 72, 18, + 99, 57, 215, 141, 22, 76, 162, 248, + 64, 26, 244, 174, 53, 111, 129, 219, + 170, 240, 30, 68, 223, 133, 107, 49, + 5, 95, 177, 235, 112, 42, 196, 158, + 239, 181, 91, 1, 154, 192, 46, 116, + 204, 150, 120, 34, 185, 227, 13, 87, + 38, 124, 146, 200, 83, 9, 231, 189, + 138, 208, 62, 100, 255, 165, 75, 17, + 96, 58, 212, 142, 21, 79, 161, 251, + 67, 25, 247, 173, 54, 108, 130, 216, + 169, 243, 29, 71, 220, 134, 104, 50 }, + { 0, 91, 182, 237, 113, 42, 199, 156, + 226, 185, 84, 15, 147, 200, 37, 126, + 217, 130, 111, 52, 168, 243, 30, 69, + 59, 96, 141, 214, 74, 17, 252, 167, + 175, 244, 25, 66, 222, 133, 104, 51, + 77, 22, 251, 160, 60, 103, 138, 209, + 118, 45, 192, 155, 7, 92, 177, 234, + 148, 207, 34, 121, 229, 190, 83, 8, + 67, 24, 245, 174, 50, 105, 132, 223, + 161, 250, 23, 76, 208, 139, 102, 61, + 154, 193, 44, 119, 235, 176, 93, 6, + 120, 35, 206, 149, 9, 82, 191, 228, + 236, 183, 90, 1, 157, 198, 43, 112, + 14, 85, 184, 227, 127, 36, 201, 146, + 53, 110, 131, 216, 68, 31, 242, 169, + 215, 140, 97, 58, 166, 253, 16, 75, + 134, 221, 48, 107, 247, 172, 65, 26, + 100, 63, 210, 137, 21, 78, 163, 248, + 95, 4, 233, 178, 46, 117, 152, 195, + 189, 230, 11, 80, 204, 151, 122, 33, + 41, 114, 159, 196, 88, 3, 238, 181, + 203, 144, 125, 38, 186, 225, 12, 87, + 240, 171, 70, 29, 129, 218, 55, 108, + 18, 73, 164, 255, 99, 56, 213, 142, + 197, 158, 115, 40, 180, 239, 2, 89, + 39, 124, 145, 202, 86, 13, 224, 187, + 28, 71, 170, 241, 109, 54, 219, 128, + 254, 165, 72, 19, 143, 212, 57, 98, + 106, 49, 220, 135, 27, 64, 173, 246, + 136, 211, 62, 101, 249, 162, 79, 20, + 179, 232, 5, 94, 194, 153, 116, 47, + 81, 10, 231, 188, 32, 123, 150, 205 }, + { 0, 92, 184, 228, 109, 49, 213, 137, + 218, 134, 98, 62, 183, 235, 15, 83, + 169, 245, 17, 77, 196, 152, 124, 32, + 115, 47, 203, 151, 30, 66, 166, 250, + 79, 19, 247, 171, 34, 126, 154, 198, + 149, 201, 45, 113, 248, 164, 64, 28, + 230, 186, 94, 2, 139, 215, 51, 111, + 60, 96, 132, 216, 81, 13, 233, 181, + 158, 194, 38, 122, 243, 175, 75, 23, + 68, 24, 252, 160, 41, 117, 145, 205, + 55, 107, 143, 211, 90, 6, 226, 190, + 237, 177, 85, 9, 128, 220, 56, 100, + 209, 141, 105, 53, 188, 224, 4, 88, + 11, 87, 179, 239, 102, 58, 222, 130, + 120, 36, 192, 156, 21, 73, 173, 241, + 162, 254, 26, 70, 207, 147, 119, 43, + 33, 125, 153, 197, 76, 16, 244, 168, + 251, 167, 67, 31, 150, 202, 46, 114, + 136, 212, 48, 108, 229, 185, 93, 1, + 82, 14, 234, 182, 63, 99, 135, 219, + 110, 50, 214, 138, 3, 95, 187, 231, + 180, 232, 12, 80, 217, 133, 97, 61, + 199, 155, 127, 35, 170, 246, 18, 78, + 29, 65, 165, 249, 112, 44, 200, 148, + 191, 227, 7, 91, 210, 142, 106, 54, + 101, 57, 221, 129, 8, 84, 176, 236, + 22, 74, 174, 242, 123, 39, 195, 159, + 204, 144, 116, 40, 161, 253, 25, 69, + 240, 172, 72, 20, 157, 193, 37, 121, + 42, 118, 146, 206, 71, 27, 255, 163, + 89, 5, 225, 189, 52, 104, 140, 208, + 131, 223, 59, 103, 238, 178, 86, 10 }, + { 0, 93, 186, 231, 105, 52, 211, 142, + 210, 143, 104, 53, 187, 230, 1, 92, + 185, 228, 3, 94, 208, 141, 106, 55, + 107, 54, 209, 140, 2, 95, 184, 229, + 111, 50, 213, 136, 6, 91, 188, 225, + 189, 224, 7, 90, 212, 137, 110, 51, + 214, 139, 108, 49, 191, 226, 5, 88, + 4, 89, 190, 227, 109, 48, 215, 138, + 222, 131, 100, 57, 183, 234, 13, 80, + 12, 81, 182, 235, 101, 56, 223, 130, + 103, 58, 221, 128, 14, 83, 180, 233, + 181, 232, 15, 82, 220, 129, 102, 59, + 177, 236, 11, 86, 216, 133, 98, 63, + 99, 62, 217, 132, 10, 87, 176, 237, + 8, 85, 178, 239, 97, 60, 219, 134, + 218, 135, 96, 61, 179, 238, 9, 84, + 161, 252, 27, 70, 200, 149, 114, 47, + 115, 46, 201, 148, 26, 71, 160, 253, + 24, 69, 162, 255, 113, 44, 203, 150, + 202, 151, 112, 45, 163, 254, 25, 68, + 206, 147, 116, 41, 167, 250, 29, 64, + 28, 65, 166, 251, 117, 40, 207, 146, + 119, 42, 205, 144, 30, 67, 164, 249, + 165, 248, 31, 66, 204, 145, 118, 43, + 127, 34, 197, 152, 22, 75, 172, 241, + 173, 240, 23, 74, 196, 153, 126, 35, + 198, 155, 124, 33, 175, 242, 21, 72, + 20, 73, 174, 243, 125, 32, 199, 154, + 16, 77, 170, 247, 121, 36, 195, 158, + 194, 159, 120, 37, 171, 246, 17, 76, + 169, 244, 19, 78, 192, 157, 122, 39, + 123, 38, 193, 156, 18, 79, 168, 245 }, + { 0, 94, 188, 226, 101, 59, 217, 135, + 202, 148, 118, 40, 175, 241, 19, 77, + 137, 215, 53, 107, 236, 178, 80, 14, + 67, 29, 255, 161, 38, 120, 154, 196, + 15, 81, 179, 237, 106, 52, 214, 136, + 197, 155, 121, 39, 160, 254, 28, 66, + 134, 216, 58, 100, 227, 189, 95, 1, + 76, 18, 240, 174, 41, 119, 149, 203, + 30, 64, 162, 252, 123, 37, 199, 153, + 212, 138, 104, 54, 177, 239, 13, 83, + 151, 201, 43, 117, 242, 172, 78, 16, + 93, 3, 225, 191, 56, 102, 132, 218, + 17, 79, 173, 243, 116, 42, 200, 150, + 219, 133, 103, 57, 190, 224, 2, 92, + 152, 198, 36, 122, 253, 163, 65, 31, + 82, 12, 238, 176, 55, 105, 139, 213, + 60, 98, 128, 222, 89, 7, 229, 187, + 246, 168, 74, 20, 147, 205, 47, 113, + 181, 235, 9, 87, 208, 142, 108, 50, + 127, 33, 195, 157, 26, 68, 166, 248, + 51, 109, 143, 209, 86, 8, 234, 180, + 249, 167, 69, 27, 156, 194, 32, 126, + 186, 228, 6, 88, 223, 129, 99, 61, + 112, 46, 204, 146, 21, 75, 169, 247, + 34, 124, 158, 192, 71, 25, 251, 165, + 232, 182, 84, 10, 141, 211, 49, 111, + 171, 245, 23, 73, 206, 144, 114, 44, + 97, 63, 221, 131, 4, 90, 184, 230, + 45, 115, 145, 207, 72, 22, 244, 170, + 231, 185, 91, 5, 130, 220, 62, 96, + 164, 250, 24, 70, 193, 159, 125, 35, + 110, 48, 210, 140, 11, 85, 183, 233 }, + { 0, 95, 190, 225, 97, 62, 223, 128, + 194, 157, 124, 35, 163, 252, 29, 66, + 153, 198, 39, 120, 248, 167, 70, 25, + 91, 4, 229, 186, 58, 101, 132, 219, + 47, 112, 145, 206, 78, 17, 240, 175, + 237, 178, 83, 12, 140, 211, 50, 109, + 182, 233, 8, 87, 215, 136, 105, 54, + 116, 43, 202, 149, 21, 74, 171, 244, + 94, 1, 224, 191, 63, 96, 129, 222, + 156, 195, 34, 125, 253, 162, 67, 28, + 199, 152, 121, 38, 166, 249, 24, 71, + 5, 90, 187, 228, 100, 59, 218, 133, + 113, 46, 207, 144, 16, 79, 174, 241, + 179, 236, 13, 82, 210, 141, 108, 51, + 232, 183, 86, 9, 137, 214, 55, 104, + 42, 117, 148, 203, 75, 20, 245, 170, + 188, 227, 2, 93, 221, 130, 99, 60, + 126, 33, 192, 159, 31, 64, 161, 254, + 37, 122, 155, 196, 68, 27, 250, 165, + 231, 184, 89, 6, 134, 217, 56, 103, + 147, 204, 45, 114, 242, 173, 76, 19, + 81, 14, 239, 176, 48, 111, 142, 209, + 10, 85, 180, 235, 107, 52, 213, 138, + 200, 151, 118, 41, 169, 246, 23, 72, + 226, 189, 92, 3, 131, 220, 61, 98, + 32, 127, 158, 193, 65, 30, 255, 160, + 123, 36, 197, 154, 26, 69, 164, 251, + 185, 230, 7, 88, 216, 135, 102, 57, + 205, 146, 115, 44, 172, 243, 18, 77, + 15, 80, 177, 238, 110, 49, 208, 143, + 84, 11, 234, 181, 53, 106, 139, 212, + 150, 201, 40, 119, 247, 168, 73, 22 }, + { 0, 96, 192, 160, 157, 253, 93, 61, + 39, 71, 231, 135, 186, 218, 122, 26, + 78, 46, 142, 238, 211, 179, 19, 115, + 105, 9, 169, 201, 244, 148, 52, 84, + 156, 252, 92, 60, 1, 97, 193, 161, + 187, 219, 123, 27, 38, 70, 230, 134, + 210, 178, 18, 114, 79, 47, 143, 239, + 245, 149, 53, 85, 104, 8, 168, 200, + 37, 69, 229, 133, 184, 216, 120, 24, + 2, 98, 194, 162, 159, 255, 95, 63, + 107, 11, 171, 203, 246, 150, 54, 86, + 76, 44, 140, 236, 209, 177, 17, 113, + 185, 217, 121, 25, 36, 68, 228, 132, + 158, 254, 94, 62, 3, 99, 195, 163, + 247, 151, 55, 87, 106, 10, 170, 202, + 208, 176, 16, 112, 77, 45, 141, 237, + 74, 42, 138, 234, 215, 183, 23, 119, + 109, 13, 173, 205, 240, 144, 48, 80, + 4, 100, 196, 164, 153, 249, 89, 57, + 35, 67, 227, 131, 190, 222, 126, 30, + 214, 182, 22, 118, 75, 43, 139, 235, + 241, 145, 49, 81, 108, 12, 172, 204, + 152, 248, 88, 56, 5, 101, 197, 165, + 191, 223, 127, 31, 34, 66, 226, 130, + 111, 15, 175, 207, 242, 146, 50, 82, + 72, 40, 136, 232, 213, 181, 21, 117, + 33, 65, 225, 129, 188, 220, 124, 28, + 6, 102, 198, 166, 155, 251, 91, 59, + 243, 147, 51, 83, 110, 14, 174, 206, + 212, 180, 20, 116, 73, 41, 137, 233, + 189, 221, 125, 29, 32, 64, 224, 128, + 154, 250, 90, 58, 7, 103, 199, 167 }, + { 0, 97, 194, 163, 153, 248, 91, 58, + 47, 78, 237, 140, 182, 215, 116, 21, + 94, 63, 156, 253, 199, 166, 5, 100, + 113, 16, 179, 210, 232, 137, 42, 75, + 188, 221, 126, 31, 37, 68, 231, 134, + 147, 242, 81, 48, 10, 107, 200, 169, + 226, 131, 32, 65, 123, 26, 185, 216, + 205, 172, 15, 110, 84, 53, 150, 247, + 101, 4, 167, 198, 252, 157, 62, 95, + 74, 43, 136, 233, 211, 178, 17, 112, + 59, 90, 249, 152, 162, 195, 96, 1, + 20, 117, 214, 183, 141, 236, 79, 46, + 217, 184, 27, 122, 64, 33, 130, 227, + 246, 151, 52, 85, 111, 14, 173, 204, + 135, 230, 69, 36, 30, 127, 220, 189, + 168, 201, 106, 11, 49, 80, 243, 146, + 202, 171, 8, 105, 83, 50, 145, 240, + 229, 132, 39, 70, 124, 29, 190, 223, + 148, 245, 86, 55, 13, 108, 207, 174, + 187, 218, 121, 24, 34, 67, 224, 129, + 118, 23, 180, 213, 239, 142, 45, 76, + 89, 56, 155, 250, 192, 161, 2, 99, + 40, 73, 234, 139, 177, 208, 115, 18, + 7, 102, 197, 164, 158, 255, 92, 61, + 175, 206, 109, 12, 54, 87, 244, 149, + 128, 225, 66, 35, 25, 120, 219, 186, + 241, 144, 51, 82, 104, 9, 170, 203, + 222, 191, 28, 125, 71, 38, 133, 228, + 19, 114, 209, 176, 138, 235, 72, 41, + 60, 93, 254, 159, 165, 196, 103, 6, + 77, 44, 143, 238, 212, 181, 22, 119, + 98, 3, 160, 193, 251, 154, 57, 88 }, + { 0, 98, 196, 166, 149, 247, 81, 51, + 55, 85, 243, 145, 162, 192, 102, 4, + 110, 12, 170, 200, 251, 153, 63, 93, + 89, 59, 157, 255, 204, 174, 8, 106, + 220, 190, 24, 122, 73, 43, 141, 239, + 235, 137, 47, 77, 126, 28, 186, 216, + 178, 208, 118, 20, 39, 69, 227, 129, + 133, 231, 65, 35, 16, 114, 212, 182, + 165, 199, 97, 3, 48, 82, 244, 150, + 146, 240, 86, 52, 7, 101, 195, 161, + 203, 169, 15, 109, 94, 60, 154, 248, + 252, 158, 56, 90, 105, 11, 173, 207, + 121, 27, 189, 223, 236, 142, 40, 74, + 78, 44, 138, 232, 219, 185, 31, 125, + 23, 117, 211, 177, 130, 224, 70, 36, + 32, 66, 228, 134, 181, 215, 113, 19, + 87, 53, 147, 241, 194, 160, 6, 100, + 96, 2, 164, 198, 245, 151, 49, 83, + 57, 91, 253, 159, 172, 206, 104, 10, + 14, 108, 202, 168, 155, 249, 95, 61, + 139, 233, 79, 45, 30, 124, 218, 184, + 188, 222, 120, 26, 41, 75, 237, 143, + 229, 135, 33, 67, 112, 18, 180, 214, + 210, 176, 22, 116, 71, 37, 131, 225, + 242, 144, 54, 84, 103, 5, 163, 193, + 197, 167, 1, 99, 80, 50, 148, 246, + 156, 254, 88, 58, 9, 107, 205, 175, + 171, 201, 111, 13, 62, 92, 250, 152, + 46, 76, 234, 136, 187, 217, 127, 29, + 25, 123, 221, 191, 140, 238, 72, 42, + 64, 34, 132, 230, 213, 183, 17, 115, + 119, 21, 179, 209, 226, 128, 38, 68 }, + { 0, 99, 198, 165, 145, 242, 87, 52, + 63, 92, 249, 154, 174, 205, 104, 11, + 126, 29, 184, 219, 239, 140, 41, 74, + 65, 34, 135, 228, 208, 179, 22, 117, + 252, 159, 58, 89, 109, 14, 171, 200, + 195, 160, 5, 102, 82, 49, 148, 247, + 130, 225, 68, 39, 19, 112, 213, 182, + 189, 222, 123, 24, 44, 79, 234, 137, + 229, 134, 35, 64, 116, 23, 178, 209, + 218, 185, 28, 127, 75, 40, 141, 238, + 155, 248, 93, 62, 10, 105, 204, 175, + 164, 199, 98, 1, 53, 86, 243, 144, + 25, 122, 223, 188, 136, 235, 78, 45, + 38, 69, 224, 131, 183, 212, 113, 18, + 103, 4, 161, 194, 246, 149, 48, 83, + 88, 59, 158, 253, 201, 170, 15, 108, + 215, 180, 17, 114, 70, 37, 128, 227, + 232, 139, 46, 77, 121, 26, 191, 220, + 169, 202, 111, 12, 56, 91, 254, 157, + 150, 245, 80, 51, 7, 100, 193, 162, + 43, 72, 237, 142, 186, 217, 124, 31, + 20, 119, 210, 177, 133, 230, 67, 32, + 85, 54, 147, 240, 196, 167, 2, 97, + 106, 9, 172, 207, 251, 152, 61, 94, + 50, 81, 244, 151, 163, 192, 101, 6, + 13, 110, 203, 168, 156, 255, 90, 57, + 76, 47, 138, 233, 221, 190, 27, 120, + 115, 16, 181, 214, 226, 129, 36, 71, + 206, 173, 8, 107, 95, 60, 153, 250, + 241, 146, 55, 84, 96, 3, 166, 197, + 176, 211, 118, 21, 33, 66, 231, 132, + 143, 236, 73, 42, 30, 125, 216, 187 }, + { 0, 100, 200, 172, 141, 233, 69, 33, + 7, 99, 207, 171, 138, 238, 66, 38, + 14, 106, 198, 162, 131, 231, 75, 47, + 9, 109, 193, 165, 132, 224, 76, 40, + 28, 120, 212, 176, 145, 245, 89, 61, + 27, 127, 211, 183, 150, 242, 94, 58, + 18, 118, 218, 190, 159, 251, 87, 51, + 21, 113, 221, 185, 152, 252, 80, 52, + 56, 92, 240, 148, 181, 209, 125, 25, + 63, 91, 247, 147, 178, 214, 122, 30, + 54, 82, 254, 154, 187, 223, 115, 23, + 49, 85, 249, 157, 188, 216, 116, 16, + 36, 64, 236, 136, 169, 205, 97, 5, + 35, 71, 235, 143, 174, 202, 102, 2, + 42, 78, 226, 134, 167, 195, 111, 11, + 45, 73, 229, 129, 160, 196, 104, 12, + 112, 20, 184, 220, 253, 153, 53, 81, + 119, 19, 191, 219, 250, 158, 50, 86, + 126, 26, 182, 210, 243, 151, 59, 95, + 121, 29, 177, 213, 244, 144, 60, 88, + 108, 8, 164, 192, 225, 133, 41, 77, + 107, 15, 163, 199, 230, 130, 46, 74, + 98, 6, 170, 206, 239, 139, 39, 67, + 101, 1, 173, 201, 232, 140, 32, 68, + 72, 44, 128, 228, 197, 161, 13, 105, + 79, 43, 135, 227, 194, 166, 10, 110, + 70, 34, 142, 234, 203, 175, 3, 103, + 65, 37, 137, 237, 204, 168, 4, 96, + 84, 48, 156, 248, 217, 189, 17, 117, + 83, 55, 155, 255, 222, 186, 22, 114, + 90, 62, 146, 246, 215, 179, 31, 123, + 93, 57, 149, 241, 208, 180, 24, 124 }, + { 0, 101, 202, 175, 137, 236, 67, 38, + 15, 106, 197, 160, 134, 227, 76, 41, + 30, 123, 212, 177, 151, 242, 93, 56, + 17, 116, 219, 190, 152, 253, 82, 55, + 60, 89, 246, 147, 181, 208, 127, 26, + 51, 86, 249, 156, 186, 223, 112, 21, + 34, 71, 232, 141, 171, 206, 97, 4, + 45, 72, 231, 130, 164, 193, 110, 11, + 120, 29, 178, 215, 241, 148, 59, 94, + 119, 18, 189, 216, 254, 155, 52, 81, + 102, 3, 172, 201, 239, 138, 37, 64, + 105, 12, 163, 198, 224, 133, 42, 79, + 68, 33, 142, 235, 205, 168, 7, 98, + 75, 46, 129, 228, 194, 167, 8, 109, + 90, 63, 144, 245, 211, 182, 25, 124, + 85, 48, 159, 250, 220, 185, 22, 115, + 240, 149, 58, 95, 121, 28, 179, 214, + 255, 154, 53, 80, 118, 19, 188, 217, + 238, 139, 36, 65, 103, 2, 173, 200, + 225, 132, 43, 78, 104, 13, 162, 199, + 204, 169, 6, 99, 69, 32, 143, 234, + 195, 166, 9, 108, 74, 47, 128, 229, + 210, 183, 24, 125, 91, 62, 145, 244, + 221, 184, 23, 114, 84, 49, 158, 251, + 136, 237, 66, 39, 1, 100, 203, 174, + 135, 226, 77, 40, 14, 107, 196, 161, + 150, 243, 92, 57, 31, 122, 213, 176, + 153, 252, 83, 54, 16, 117, 218, 191, + 180, 209, 126, 27, 61, 88, 247, 146, + 187, 222, 113, 20, 50, 87, 248, 157, + 170, 207, 96, 5, 35, 70, 233, 140, + 165, 192, 111, 10, 44, 73, 230, 131 }, + { 0, 102, 204, 170, 133, 227, 73, 47, + 23, 113, 219, 189, 146, 244, 94, 56, + 46, 72, 226, 132, 171, 205, 103, 1, + 57, 95, 245, 147, 188, 218, 112, 22, + 92, 58, 144, 246, 217, 191, 21, 115, + 75, 45, 135, 225, 206, 168, 2, 100, + 114, 20, 190, 216, 247, 145, 59, 93, + 101, 3, 169, 207, 224, 134, 44, 74, + 184, 222, 116, 18, 61, 91, 241, 151, + 175, 201, 99, 5, 42, 76, 230, 128, + 150, 240, 90, 60, 19, 117, 223, 185, + 129, 231, 77, 43, 4, 98, 200, 174, + 228, 130, 40, 78, 97, 7, 173, 203, + 243, 149, 63, 89, 118, 16, 186, 220, + 202, 172, 6, 96, 79, 41, 131, 229, + 221, 187, 17, 119, 88, 62, 148, 242, + 109, 11, 161, 199, 232, 142, 36, 66, + 122, 28, 182, 208, 255, 153, 51, 85, + 67, 37, 143, 233, 198, 160, 10, 108, + 84, 50, 152, 254, 209, 183, 29, 123, + 49, 87, 253, 155, 180, 210, 120, 30, + 38, 64, 234, 140, 163, 197, 111, 9, + 31, 121, 211, 181, 154, 252, 86, 48, + 8, 110, 196, 162, 141, 235, 65, 39, + 213, 179, 25, 127, 80, 54, 156, 250, + 194, 164, 14, 104, 71, 33, 139, 237, + 251, 157, 55, 81, 126, 24, 178, 212, + 236, 138, 32, 70, 105, 15, 165, 195, + 137, 239, 69, 35, 12, 106, 192, 166, + 158, 248, 82, 52, 27, 125, 215, 177, + 167, 193, 107, 13, 34, 68, 238, 136, + 176, 214, 124, 26, 53, 83, 249, 159 }, + { 0, 103, 206, 169, 129, 230, 79, 40, + 31, 120, 209, 182, 158, 249, 80, 55, + 62, 89, 240, 151, 191, 216, 113, 22, + 33, 70, 239, 136, 160, 199, 110, 9, + 124, 27, 178, 213, 253, 154, 51, 84, + 99, 4, 173, 202, 226, 133, 44, 75, + 66, 37, 140, 235, 195, 164, 13, 106, + 93, 58, 147, 244, 220, 187, 18, 117, + 248, 159, 54, 81, 121, 30, 183, 208, + 231, 128, 41, 78, 102, 1, 168, 207, + 198, 161, 8, 111, 71, 32, 137, 238, + 217, 190, 23, 112, 88, 63, 150, 241, + 132, 227, 74, 45, 5, 98, 203, 172, + 155, 252, 85, 50, 26, 125, 212, 179, + 186, 221, 116, 19, 59, 92, 245, 146, + 165, 194, 107, 12, 36, 67, 234, 141, + 237, 138, 35, 68, 108, 11, 162, 197, + 242, 149, 60, 91, 115, 20, 189, 218, + 211, 180, 29, 122, 82, 53, 156, 251, + 204, 171, 2, 101, 77, 42, 131, 228, + 145, 246, 95, 56, 16, 119, 222, 185, + 142, 233, 64, 39, 15, 104, 193, 166, + 175, 200, 97, 6, 46, 73, 224, 135, + 176, 215, 126, 25, 49, 86, 255, 152, + 21, 114, 219, 188, 148, 243, 90, 61, + 10, 109, 196, 163, 139, 236, 69, 34, + 43, 76, 229, 130, 170, 205, 100, 3, + 52, 83, 250, 157, 181, 210, 123, 28, + 105, 14, 167, 192, 232, 143, 38, 65, + 118, 17, 184, 223, 247, 144, 57, 94, + 87, 48, 153, 254, 214, 177, 24, 127, + 72, 47, 134, 225, 201, 174, 7, 96 }, + { 0, 104, 208, 184, 189, 213, 109, 5, + 103, 15, 183, 223, 218, 178, 10, 98, + 206, 166, 30, 118, 115, 27, 163, 203, + 169, 193, 121, 17, 20, 124, 196, 172, + 129, 233, 81, 57, 60, 84, 236, 132, + 230, 142, 54, 94, 91, 51, 139, 227, + 79, 39, 159, 247, 242, 154, 34, 74, + 40, 64, 248, 144, 149, 253, 69, 45, + 31, 119, 207, 167, 162, 202, 114, 26, + 120, 16, 168, 192, 197, 173, 21, 125, + 209, 185, 1, 105, 108, 4, 188, 212, + 182, 222, 102, 14, 11, 99, 219, 179, + 158, 246, 78, 38, 35, 75, 243, 155, + 249, 145, 41, 65, 68, 44, 148, 252, + 80, 56, 128, 232, 237, 133, 61, 85, + 55, 95, 231, 143, 138, 226, 90, 50, + 62, 86, 238, 134, 131, 235, 83, 59, + 89, 49, 137, 225, 228, 140, 52, 92, + 240, 152, 32, 72, 77, 37, 157, 245, + 151, 255, 71, 47, 42, 66, 250, 146, + 191, 215, 111, 7, 2, 106, 210, 186, + 216, 176, 8, 96, 101, 13, 181, 221, + 113, 25, 161, 201, 204, 164, 28, 116, + 22, 126, 198, 174, 171, 195, 123, 19, + 33, 73, 241, 153, 156, 244, 76, 36, + 70, 46, 150, 254, 251, 147, 43, 67, + 239, 135, 63, 87, 82, 58, 130, 234, + 136, 224, 88, 48, 53, 93, 229, 141, + 160, 200, 112, 24, 29, 117, 205, 165, + 199, 175, 23, 127, 122, 18, 170, 194, + 110, 6, 190, 214, 211, 187, 3, 107, + 9, 97, 217, 177, 180, 220, 100, 12 }, + { 0, 105, 210, 187, 185, 208, 107, 2, + 111, 6, 189, 212, 214, 191, 4, 109, + 222, 183, 12, 101, 103, 14, 181, 220, + 177, 216, 99, 10, 8, 97, 218, 179, + 161, 200, 115, 26, 24, 113, 202, 163, + 206, 167, 28, 117, 119, 30, 165, 204, + 127, 22, 173, 196, 198, 175, 20, 125, + 16, 121, 194, 171, 169, 192, 123, 18, + 95, 54, 141, 228, 230, 143, 52, 93, + 48, 89, 226, 139, 137, 224, 91, 50, + 129, 232, 83, 58, 56, 81, 234, 131, + 238, 135, 60, 85, 87, 62, 133, 236, + 254, 151, 44, 69, 71, 46, 149, 252, + 145, 248, 67, 42, 40, 65, 250, 147, + 32, 73, 242, 155, 153, 240, 75, 34, + 79, 38, 157, 244, 246, 159, 36, 77, + 190, 215, 108, 5, 7, 110, 213, 188, + 209, 184, 3, 106, 104, 1, 186, 211, + 96, 9, 178, 219, 217, 176, 11, 98, + 15, 102, 221, 180, 182, 223, 100, 13, + 31, 118, 205, 164, 166, 207, 116, 29, + 112, 25, 162, 203, 201, 160, 27, 114, + 193, 168, 19, 122, 120, 17, 170, 195, + 174, 199, 124, 21, 23, 126, 197, 172, + 225, 136, 51, 90, 88, 49, 138, 227, + 142, 231, 92, 53, 55, 94, 229, 140, + 63, 86, 237, 132, 134, 239, 84, 61, + 80, 57, 130, 235, 233, 128, 59, 82, + 64, 41, 146, 251, 249, 144, 43, 66, + 47, 70, 253, 148, 150, 255, 68, 45, + 158, 247, 76, 37, 39, 78, 245, 156, + 241, 152, 35, 74, 72, 33, 154, 243 }, + { 0, 106, 212, 190, 181, 223, 97, 11, + 119, 29, 163, 201, 194, 168, 22, 124, + 238, 132, 58, 80, 91, 49, 143, 229, + 153, 243, 77, 39, 44, 70, 248, 146, + 193, 171, 21, 127, 116, 30, 160, 202, + 182, 220, 98, 8, 3, 105, 215, 189, + 47, 69, 251, 145, 154, 240, 78, 36, + 88, 50, 140, 230, 237, 135, 57, 83, + 159, 245, 75, 33, 42, 64, 254, 148, + 232, 130, 60, 86, 93, 55, 137, 227, + 113, 27, 165, 207, 196, 174, 16, 122, + 6, 108, 210, 184, 179, 217, 103, 13, + 94, 52, 138, 224, 235, 129, 63, 85, + 41, 67, 253, 151, 156, 246, 72, 34, + 176, 218, 100, 14, 5, 111, 209, 187, + 199, 173, 19, 121, 114, 24, 166, 204, + 35, 73, 247, 157, 150, 252, 66, 40, + 84, 62, 128, 234, 225, 139, 53, 95, + 205, 167, 25, 115, 120, 18, 172, 198, + 186, 208, 110, 4, 15, 101, 219, 177, + 226, 136, 54, 92, 87, 61, 131, 233, + 149, 255, 65, 43, 32, 74, 244, 158, + 12, 102, 216, 178, 185, 211, 109, 7, + 123, 17, 175, 197, 206, 164, 26, 112, + 188, 214, 104, 2, 9, 99, 221, 183, + 203, 161, 31, 117, 126, 20, 170, 192, + 82, 56, 134, 236, 231, 141, 51, 89, + 37, 79, 241, 155, 144, 250, 68, 46, + 125, 23, 169, 195, 200, 162, 28, 118, + 10, 96, 222, 180, 191, 213, 107, 1, + 147, 249, 71, 45, 38, 76, 242, 152, + 228, 142, 48, 90, 81, 59, 133, 239 }, + { 0, 107, 214, 189, 177, 218, 103, 12, + 127, 20, 169, 194, 206, 165, 24, 115, + 254, 149, 40, 67, 79, 36, 153, 242, + 129, 234, 87, 60, 48, 91, 230, 141, + 225, 138, 55, 92, 80, 59, 134, 237, + 158, 245, 72, 35, 47, 68, 249, 146, + 31, 116, 201, 162, 174, 197, 120, 19, + 96, 11, 182, 221, 209, 186, 7, 108, + 223, 180, 9, 98, 110, 5, 184, 211, + 160, 203, 118, 29, 17, 122, 199, 172, + 33, 74, 247, 156, 144, 251, 70, 45, + 94, 53, 136, 227, 239, 132, 57, 82, + 62, 85, 232, 131, 143, 228, 89, 50, + 65, 42, 151, 252, 240, 155, 38, 77, + 192, 171, 22, 125, 113, 26, 167, 204, + 191, 212, 105, 2, 14, 101, 216, 179, + 163, 200, 117, 30, 18, 121, 196, 175, + 220, 183, 10, 97, 109, 6, 187, 208, + 93, 54, 139, 224, 236, 135, 58, 81, + 34, 73, 244, 159, 147, 248, 69, 46, + 66, 41, 148, 255, 243, 152, 37, 78, + 61, 86, 235, 128, 140, 231, 90, 49, + 188, 215, 106, 1, 13, 102, 219, 176, + 195, 168, 21, 126, 114, 25, 164, 207, + 124, 23, 170, 193, 205, 166, 27, 112, + 3, 104, 213, 190, 178, 217, 100, 15, + 130, 233, 84, 63, 51, 88, 229, 142, + 253, 150, 43, 64, 76, 39, 154, 241, + 157, 246, 75, 32, 44, 71, 250, 145, + 226, 137, 52, 95, 83, 56, 133, 238, + 99, 8, 181, 222, 210, 185, 4, 111, + 28, 119, 202, 161, 173, 198, 123, 16 }, + { 0, 108, 216, 180, 173, 193, 117, 25, + 71, 43, 159, 243, 234, 134, 50, 94, + 142, 226, 86, 58, 35, 79, 251, 151, + 201, 165, 17, 125, 100, 8, 188, 208, + 1, 109, 217, 181, 172, 192, 116, 24, + 70, 42, 158, 242, 235, 135, 51, 95, + 143, 227, 87, 59, 34, 78, 250, 150, + 200, 164, 16, 124, 101, 9, 189, 209, + 2, 110, 218, 182, 175, 195, 119, 27, + 69, 41, 157, 241, 232, 132, 48, 92, + 140, 224, 84, 56, 33, 77, 249, 149, + 203, 167, 19, 127, 102, 10, 190, 210, + 3, 111, 219, 183, 174, 194, 118, 26, + 68, 40, 156, 240, 233, 133, 49, 93, + 141, 225, 85, 57, 32, 76, 248, 148, + 202, 166, 18, 126, 103, 11, 191, 211, + 4, 104, 220, 176, 169, 197, 113, 29, + 67, 47, 155, 247, 238, 130, 54, 90, + 138, 230, 82, 62, 39, 75, 255, 147, + 205, 161, 21, 121, 96, 12, 184, 212, + 5, 105, 221, 177, 168, 196, 112, 28, + 66, 46, 154, 246, 239, 131, 55, 91, + 139, 231, 83, 63, 38, 74, 254, 146, + 204, 160, 20, 120, 97, 13, 185, 213, + 6, 106, 222, 178, 171, 199, 115, 31, + 65, 45, 153, 245, 236, 128, 52, 88, + 136, 228, 80, 60, 37, 73, 253, 145, + 207, 163, 23, 123, 98, 14, 186, 214, + 7, 107, 223, 179, 170, 198, 114, 30, + 64, 44, 152, 244, 237, 129, 53, 89, + 137, 229, 81, 61, 36, 72, 252, 144, + 206, 162, 22, 122, 99, 15, 187, 215 }, + { 0, 109, 218, 183, 169, 196, 115, 30, + 79, 34, 149, 248, 230, 139, 60, 81, + 158, 243, 68, 41, 55, 90, 237, 128, + 209, 188, 11, 102, 120, 21, 162, 207, + 33, 76, 251, 150, 136, 229, 82, 63, + 110, 3, 180, 217, 199, 170, 29, 112, + 191, 210, 101, 8, 22, 123, 204, 161, + 240, 157, 42, 71, 89, 52, 131, 238, + 66, 47, 152, 245, 235, 134, 49, 92, + 13, 96, 215, 186, 164, 201, 126, 19, + 220, 177, 6, 107, 117, 24, 175, 194, + 147, 254, 73, 36, 58, 87, 224, 141, + 99, 14, 185, 212, 202, 167, 16, 125, + 44, 65, 246, 155, 133, 232, 95, 50, + 253, 144, 39, 74, 84, 57, 142, 227, + 178, 223, 104, 5, 27, 118, 193, 172, + 132, 233, 94, 51, 45, 64, 247, 154, + 203, 166, 17, 124, 98, 15, 184, 213, + 26, 119, 192, 173, 179, 222, 105, 4, + 85, 56, 143, 226, 252, 145, 38, 75, + 165, 200, 127, 18, 12, 97, 214, 187, + 234, 135, 48, 93, 67, 46, 153, 244, + 59, 86, 225, 140, 146, 255, 72, 37, + 116, 25, 174, 195, 221, 176, 7, 106, + 198, 171, 28, 113, 111, 2, 181, 216, + 137, 228, 83, 62, 32, 77, 250, 151, + 88, 53, 130, 239, 241, 156, 43, 70, + 23, 122, 205, 160, 190, 211, 100, 9, + 231, 138, 61, 80, 78, 35, 148, 249, + 168, 197, 114, 31, 1, 108, 219, 182, + 121, 20, 163, 206, 208, 189, 10, 103, + 54, 91, 236, 129, 159, 242, 69, 40 }, + { 0, 110, 220, 178, 165, 203, 121, 23, + 87, 57, 139, 229, 242, 156, 46, 64, + 174, 192, 114, 28, 11, 101, 215, 185, + 249, 151, 37, 75, 92, 50, 128, 238, + 65, 47, 157, 243, 228, 138, 56, 86, + 22, 120, 202, 164, 179, 221, 111, 1, + 239, 129, 51, 93, 74, 36, 150, 248, + 184, 214, 100, 10, 29, 115, 193, 175, + 130, 236, 94, 48, 39, 73, 251, 149, + 213, 187, 9, 103, 112, 30, 172, 194, + 44, 66, 240, 158, 137, 231, 85, 59, + 123, 21, 167, 201, 222, 176, 2, 108, + 195, 173, 31, 113, 102, 8, 186, 212, + 148, 250, 72, 38, 49, 95, 237, 131, + 109, 3, 177, 223, 200, 166, 20, 122, + 58, 84, 230, 136, 159, 241, 67, 45, + 25, 119, 197, 171, 188, 210, 96, 14, + 78, 32, 146, 252, 235, 133, 55, 89, + 183, 217, 107, 5, 18, 124, 206, 160, + 224, 142, 60, 82, 69, 43, 153, 247, + 88, 54, 132, 234, 253, 147, 33, 79, + 15, 97, 211, 189, 170, 196, 118, 24, + 246, 152, 42, 68, 83, 61, 143, 225, + 161, 207, 125, 19, 4, 106, 216, 182, + 155, 245, 71, 41, 62, 80, 226, 140, + 204, 162, 16, 126, 105, 7, 181, 219, + 53, 91, 233, 135, 144, 254, 76, 34, + 98, 12, 190, 208, 199, 169, 27, 117, + 218, 180, 6, 104, 127, 17, 163, 205, + 141, 227, 81, 63, 40, 70, 244, 154, + 116, 26, 168, 198, 209, 191, 13, 99, + 35, 77, 255, 145, 134, 232, 90, 52 }, + { 0, 111, 222, 177, 161, 206, 127, 16, + 95, 48, 129, 238, 254, 145, 32, 79, + 190, 209, 96, 15, 31, 112, 193, 174, + 225, 142, 63, 80, 64, 47, 158, 241, + 97, 14, 191, 208, 192, 175, 30, 113, + 62, 81, 224, 143, 159, 240, 65, 46, + 223, 176, 1, 110, 126, 17, 160, 207, + 128, 239, 94, 49, 33, 78, 255, 144, + 194, 173, 28, 115, 99, 12, 189, 210, + 157, 242, 67, 44, 60, 83, 226, 141, + 124, 19, 162, 205, 221, 178, 3, 108, + 35, 76, 253, 146, 130, 237, 92, 51, + 163, 204, 125, 18, 2, 109, 220, 179, + 252, 147, 34, 77, 93, 50, 131, 236, + 29, 114, 195, 172, 188, 211, 98, 13, + 66, 45, 156, 243, 227, 140, 61, 82, + 153, 246, 71, 40, 56, 87, 230, 137, + 198, 169, 24, 119, 103, 8, 185, 214, + 39, 72, 249, 150, 134, 233, 88, 55, + 120, 23, 166, 201, 217, 182, 7, 104, + 248, 151, 38, 73, 89, 54, 135, 232, + 167, 200, 121, 22, 6, 105, 216, 183, + 70, 41, 152, 247, 231, 136, 57, 86, + 25, 118, 199, 168, 184, 215, 102, 9, + 91, 52, 133, 234, 250, 149, 36, 75, + 4, 107, 218, 181, 165, 202, 123, 20, + 229, 138, 59, 84, 68, 43, 154, 245, + 186, 213, 100, 11, 27, 116, 197, 170, + 58, 85, 228, 139, 155, 244, 69, 42, + 101, 10, 187, 212, 196, 171, 26, 117, + 132, 235, 90, 53, 37, 74, 251, 148, + 219, 180, 5, 106, 122, 21, 164, 203 }, + { 0, 112, 224, 144, 221, 173, 61, 77, + 167, 215, 71, 55, 122, 10, 154, 234, + 83, 35, 179, 195, 142, 254, 110, 30, + 244, 132, 20, 100, 41, 89, 201, 185, + 166, 214, 70, 54, 123, 11, 155, 235, + 1, 113, 225, 145, 220, 172, 60, 76, + 245, 133, 21, 101, 40, 88, 200, 184, + 82, 34, 178, 194, 143, 255, 111, 31, + 81, 33, 177, 193, 140, 252, 108, 28, + 246, 134, 22, 102, 43, 91, 203, 187, + 2, 114, 226, 146, 223, 175, 63, 79, + 165, 213, 69, 53, 120, 8, 152, 232, + 247, 135, 23, 103, 42, 90, 202, 186, + 80, 32, 176, 192, 141, 253, 109, 29, + 164, 212, 68, 52, 121, 9, 153, 233, + 3, 115, 227, 147, 222, 174, 62, 78, + 162, 210, 66, 50, 127, 15, 159, 239, + 5, 117, 229, 149, 216, 168, 56, 72, + 241, 129, 17, 97, 44, 92, 204, 188, + 86, 38, 182, 198, 139, 251, 107, 27, + 4, 116, 228, 148, 217, 169, 57, 73, + 163, 211, 67, 51, 126, 14, 158, 238, + 87, 39, 183, 199, 138, 250, 106, 26, + 240, 128, 16, 96, 45, 93, 205, 189, + 243, 131, 19, 99, 46, 94, 206, 190, + 84, 36, 180, 196, 137, 249, 105, 25, + 160, 208, 64, 48, 125, 13, 157, 237, + 7, 119, 231, 151, 218, 170, 58, 74, + 85, 37, 181, 197, 136, 248, 104, 24, + 242, 130, 18, 98, 47, 95, 207, 191, + 6, 118, 230, 150, 219, 171, 59, 75, + 161, 209, 65, 49, 124, 12, 156, 236 }, + { 0, 113, 226, 147, 217, 168, 59, 74, + 175, 222, 77, 60, 118, 7, 148, 229, + 67, 50, 161, 208, 154, 235, 120, 9, + 236, 157, 14, 127, 53, 68, 215, 166, + 134, 247, 100, 21, 95, 46, 189, 204, + 41, 88, 203, 186, 240, 129, 18, 99, + 197, 180, 39, 86, 28, 109, 254, 143, + 106, 27, 136, 249, 179, 194, 81, 32, + 17, 96, 243, 130, 200, 185, 42, 91, + 190, 207, 92, 45, 103, 22, 133, 244, + 82, 35, 176, 193, 139, 250, 105, 24, + 253, 140, 31, 110, 36, 85, 198, 183, + 151, 230, 117, 4, 78, 63, 172, 221, + 56, 73, 218, 171, 225, 144, 3, 114, + 212, 165, 54, 71, 13, 124, 239, 158, + 123, 10, 153, 232, 162, 211, 64, 49, + 34, 83, 192, 177, 251, 138, 25, 104, + 141, 252, 111, 30, 84, 37, 182, 199, + 97, 16, 131, 242, 184, 201, 90, 43, + 206, 191, 44, 93, 23, 102, 245, 132, + 164, 213, 70, 55, 125, 12, 159, 238, + 11, 122, 233, 152, 210, 163, 48, 65, + 231, 150, 5, 116, 62, 79, 220, 173, + 72, 57, 170, 219, 145, 224, 115, 2, + 51, 66, 209, 160, 234, 155, 8, 121, + 156, 237, 126, 15, 69, 52, 167, 214, + 112, 1, 146, 227, 169, 216, 75, 58, + 223, 174, 61, 76, 6, 119, 228, 149, + 181, 196, 87, 38, 108, 29, 142, 255, + 26, 107, 248, 137, 195, 178, 33, 80, + 246, 135, 20, 101, 47, 94, 205, 188, + 89, 40, 187, 202, 128, 241, 98, 19 }, + { 0, 114, 228, 150, 213, 167, 49, 67, + 183, 197, 83, 33, 98, 16, 134, 244, + 115, 1, 151, 229, 166, 212, 66, 48, + 196, 182, 32, 82, 17, 99, 245, 135, + 230, 148, 2, 112, 51, 65, 215, 165, + 81, 35, 181, 199, 132, 246, 96, 18, + 149, 231, 113, 3, 64, 50, 164, 214, + 34, 80, 198, 180, 247, 133, 19, 97, + 209, 163, 53, 71, 4, 118, 224, 146, + 102, 20, 130, 240, 179, 193, 87, 37, + 162, 208, 70, 52, 119, 5, 147, 225, + 21, 103, 241, 131, 192, 178, 36, 86, + 55, 69, 211, 161, 226, 144, 6, 116, + 128, 242, 100, 22, 85, 39, 177, 195, + 68, 54, 160, 210, 145, 227, 117, 7, + 243, 129, 23, 101, 38, 84, 194, 176, + 191, 205, 91, 41, 106, 24, 142, 252, + 8, 122, 236, 158, 221, 175, 57, 75, + 204, 190, 40, 90, 25, 107, 253, 143, + 123, 9, 159, 237, 174, 220, 74, 56, + 89, 43, 189, 207, 140, 254, 104, 26, + 238, 156, 10, 120, 59, 73, 223, 173, + 42, 88, 206, 188, 255, 141, 27, 105, + 157, 239, 121, 11, 72, 58, 172, 222, + 110, 28, 138, 248, 187, 201, 95, 45, + 217, 171, 61, 79, 12, 126, 232, 154, + 29, 111, 249, 139, 200, 186, 44, 94, + 170, 216, 78, 60, 127, 13, 155, 233, + 136, 250, 108, 30, 93, 47, 185, 203, + 63, 77, 219, 169, 234, 152, 14, 124, + 251, 137, 31, 109, 46, 92, 202, 184, + 76, 62, 168, 218, 153, 235, 125, 15 }, + { 0, 115, 230, 149, 209, 162, 55, 68, + 191, 204, 89, 42, 110, 29, 136, 251, + 99, 16, 133, 246, 178, 193, 84, 39, + 220, 175, 58, 73, 13, 126, 235, 152, + 198, 181, 32, 83, 23, 100, 241, 130, + 121, 10, 159, 236, 168, 219, 78, 61, + 165, 214, 67, 48, 116, 7, 146, 225, + 26, 105, 252, 143, 203, 184, 45, 94, + 145, 226, 119, 4, 64, 51, 166, 213, + 46, 93, 200, 187, 255, 140, 25, 106, + 242, 129, 20, 103, 35, 80, 197, 182, + 77, 62, 171, 216, 156, 239, 122, 9, + 87, 36, 177, 194, 134, 245, 96, 19, + 232, 155, 14, 125, 57, 74, 223, 172, + 52, 71, 210, 161, 229, 150, 3, 112, + 139, 248, 109, 30, 90, 41, 188, 207, + 63, 76, 217, 170, 238, 157, 8, 123, + 128, 243, 102, 21, 81, 34, 183, 196, + 92, 47, 186, 201, 141, 254, 107, 24, + 227, 144, 5, 118, 50, 65, 212, 167, + 249, 138, 31, 108, 40, 91, 206, 189, + 70, 53, 160, 211, 151, 228, 113, 2, + 154, 233, 124, 15, 75, 56, 173, 222, + 37, 86, 195, 176, 244, 135, 18, 97, + 174, 221, 72, 59, 127, 12, 153, 234, + 17, 98, 247, 132, 192, 179, 38, 85, + 205, 190, 43, 88, 28, 111, 250, 137, + 114, 1, 148, 231, 163, 208, 69, 54, + 104, 27, 142, 253, 185, 202, 95, 44, + 215, 164, 49, 66, 6, 117, 224, 147, + 11, 120, 237, 158, 218, 169, 60, 79, + 180, 199, 82, 33, 101, 22, 131, 240 }, + { 0, 116, 232, 156, 205, 185, 37, 81, + 135, 243, 111, 27, 74, 62, 162, 214, + 19, 103, 251, 143, 222, 170, 54, 66, + 148, 224, 124, 8, 89, 45, 177, 197, + 38, 82, 206, 186, 235, 159, 3, 119, + 161, 213, 73, 61, 108, 24, 132, 240, + 53, 65, 221, 169, 248, 140, 16, 100, + 178, 198, 90, 46, 127, 11, 151, 227, + 76, 56, 164, 208, 129, 245, 105, 29, + 203, 191, 35, 87, 6, 114, 238, 154, + 95, 43, 183, 195, 146, 230, 122, 14, + 216, 172, 48, 68, 21, 97, 253, 137, + 106, 30, 130, 246, 167, 211, 79, 59, + 237, 153, 5, 113, 32, 84, 200, 188, + 121, 13, 145, 229, 180, 192, 92, 40, + 254, 138, 22, 98, 51, 71, 219, 175, + 152, 236, 112, 4, 85, 33, 189, 201, + 31, 107, 247, 131, 210, 166, 58, 78, + 139, 255, 99, 23, 70, 50, 174, 218, + 12, 120, 228, 144, 193, 181, 41, 93, + 190, 202, 86, 34, 115, 7, 155, 239, + 57, 77, 209, 165, 244, 128, 28, 104, + 173, 217, 69, 49, 96, 20, 136, 252, + 42, 94, 194, 182, 231, 147, 15, 123, + 212, 160, 60, 72, 25, 109, 241, 133, + 83, 39, 187, 207, 158, 234, 118, 2, + 199, 179, 47, 91, 10, 126, 226, 150, + 64, 52, 168, 220, 141, 249, 101, 17, + 242, 134, 26, 110, 63, 75, 215, 163, + 117, 1, 157, 233, 184, 204, 80, 36, + 225, 149, 9, 125, 44, 88, 196, 176, + 102, 18, 142, 250, 171, 223, 67, 55 }, + { 0, 117, 234, 159, 201, 188, 35, 86, + 143, 250, 101, 16, 70, 51, 172, 217, + 3, 118, 233, 156, 202, 191, 32, 85, + 140, 249, 102, 19, 69, 48, 175, 218, + 6, 115, 236, 153, 207, 186, 37, 80, + 137, 252, 99, 22, 64, 53, 170, 223, + 5, 112, 239, 154, 204, 185, 38, 83, + 138, 255, 96, 21, 67, 54, 169, 220, + 12, 121, 230, 147, 197, 176, 47, 90, + 131, 246, 105, 28, 74, 63, 160, 213, + 15, 122, 229, 144, 198, 179, 44, 89, + 128, 245, 106, 31, 73, 60, 163, 214, + 10, 127, 224, 149, 195, 182, 41, 92, + 133, 240, 111, 26, 76, 57, 166, 211, + 9, 124, 227, 150, 192, 181, 42, 95, + 134, 243, 108, 25, 79, 58, 165, 208, + 24, 109, 242, 135, 209, 164, 59, 78, + 151, 226, 125, 8, 94, 43, 180, 193, + 27, 110, 241, 132, 210, 167, 56, 77, + 148, 225, 126, 11, 93, 40, 183, 194, + 30, 107, 244, 129, 215, 162, 61, 72, + 145, 228, 123, 14, 88, 45, 178, 199, + 29, 104, 247, 130, 212, 161, 62, 75, + 146, 231, 120, 13, 91, 46, 177, 196, + 20, 97, 254, 139, 221, 168, 55, 66, + 155, 238, 113, 4, 82, 39, 184, 205, + 23, 98, 253, 136, 222, 171, 52, 65, + 152, 237, 114, 7, 81, 36, 187, 206, + 18, 103, 248, 141, 219, 174, 49, 68, + 157, 232, 119, 2, 84, 33, 190, 203, + 17, 100, 251, 142, 216, 173, 50, 71, + 158, 235, 116, 1, 87, 34, 189, 200 }, + { 0, 118, 236, 154, 197, 179, 41, 95, + 151, 225, 123, 13, 82, 36, 190, 200, + 51, 69, 223, 169, 246, 128, 26, 108, + 164, 210, 72, 62, 97, 23, 141, 251, + 102, 16, 138, 252, 163, 213, 79, 57, + 241, 135, 29, 107, 52, 66, 216, 174, + 85, 35, 185, 207, 144, 230, 124, 10, + 194, 180, 46, 88, 7, 113, 235, 157, + 204, 186, 32, 86, 9, 127, 229, 147, + 91, 45, 183, 193, 158, 232, 114, 4, + 255, 137, 19, 101, 58, 76, 214, 160, + 104, 30, 132, 242, 173, 219, 65, 55, + 170, 220, 70, 48, 111, 25, 131, 245, + 61, 75, 209, 167, 248, 142, 20, 98, + 153, 239, 117, 3, 92, 42, 176, 198, + 14, 120, 226, 148, 203, 189, 39, 81, + 133, 243, 105, 31, 64, 54, 172, 218, + 18, 100, 254, 136, 215, 161, 59, 77, + 182, 192, 90, 44, 115, 5, 159, 233, + 33, 87, 205, 187, 228, 146, 8, 126, + 227, 149, 15, 121, 38, 80, 202, 188, + 116, 2, 152, 238, 177, 199, 93, 43, + 208, 166, 60, 74, 21, 99, 249, 143, + 71, 49, 171, 221, 130, 244, 110, 24, + 73, 63, 165, 211, 140, 250, 96, 22, + 222, 168, 50, 68, 27, 109, 247, 129, + 122, 12, 150, 224, 191, 201, 83, 37, + 237, 155, 1, 119, 40, 94, 196, 178, + 47, 89, 195, 181, 234, 156, 6, 112, + 184, 206, 84, 34, 125, 11, 145, 231, + 28, 106, 240, 134, 217, 175, 53, 67, + 139, 253, 103, 17, 78, 56, 162, 212 }, + { 0, 119, 238, 153, 193, 182, 47, 88, + 159, 232, 113, 6, 94, 41, 176, 199, + 35, 84, 205, 186, 226, 149, 12, 123, + 188, 203, 82, 37, 125, 10, 147, 228, + 70, 49, 168, 223, 135, 240, 105, 30, + 217, 174, 55, 64, 24, 111, 246, 129, + 101, 18, 139, 252, 164, 211, 74, 61, + 250, 141, 20, 99, 59, 76, 213, 162, + 140, 251, 98, 21, 77, 58, 163, 212, + 19, 100, 253, 138, 210, 165, 60, 75, + 175, 216, 65, 54, 110, 25, 128, 247, + 48, 71, 222, 169, 241, 134, 31, 104, + 202, 189, 36, 83, 11, 124, 229, 146, + 85, 34, 187, 204, 148, 227, 122, 13, + 233, 158, 7, 112, 40, 95, 198, 177, + 118, 1, 152, 239, 183, 192, 89, 46, + 5, 114, 235, 156, 196, 179, 42, 93, + 154, 237, 116, 3, 91, 44, 181, 194, + 38, 81, 200, 191, 231, 144, 9, 126, + 185, 206, 87, 32, 120, 15, 150, 225, + 67, 52, 173, 218, 130, 245, 108, 27, + 220, 171, 50, 69, 29, 106, 243, 132, + 96, 23, 142, 249, 161, 214, 79, 56, + 255, 136, 17, 102, 62, 73, 208, 167, + 137, 254, 103, 16, 72, 63, 166, 209, + 22, 97, 248, 143, 215, 160, 57, 78, + 170, 221, 68, 51, 107, 28, 133, 242, + 53, 66, 219, 172, 244, 131, 26, 109, + 207, 184, 33, 86, 14, 121, 224, 151, + 80, 39, 190, 201, 145, 230, 127, 8, + 236, 155, 2, 117, 45, 90, 195, 180, + 115, 4, 157, 234, 178, 197, 92, 43 }, + { 0, 120, 240, 136, 253, 133, 13, 117, + 231, 159, 23, 111, 26, 98, 234, 146, + 211, 171, 35, 91, 46, 86, 222, 166, + 52, 76, 196, 188, 201, 177, 57, 65, + 187, 195, 75, 51, 70, 62, 182, 206, + 92, 36, 172, 212, 161, 217, 81, 41, + 104, 16, 152, 224, 149, 237, 101, 29, + 143, 247, 127, 7, 114, 10, 130, 250, + 107, 19, 155, 227, 150, 238, 102, 30, + 140, 244, 124, 4, 113, 9, 129, 249, + 184, 192, 72, 48, 69, 61, 181, 205, + 95, 39, 175, 215, 162, 218, 82, 42, + 208, 168, 32, 88, 45, 85, 221, 165, + 55, 79, 199, 191, 202, 178, 58, 66, + 3, 123, 243, 139, 254, 134, 14, 118, + 228, 156, 20, 108, 25, 97, 233, 145, + 214, 174, 38, 94, 43, 83, 219, 163, + 49, 73, 193, 185, 204, 180, 60, 68, + 5, 125, 245, 141, 248, 128, 8, 112, + 226, 154, 18, 106, 31, 103, 239, 151, + 109, 21, 157, 229, 144, 232, 96, 24, + 138, 242, 122, 2, 119, 15, 135, 255, + 190, 198, 78, 54, 67, 59, 179, 203, + 89, 33, 169, 209, 164, 220, 84, 44, + 189, 197, 77, 53, 64, 56, 176, 200, + 90, 34, 170, 210, 167, 223, 87, 47, + 110, 22, 158, 230, 147, 235, 99, 27, + 137, 241, 121, 1, 116, 12, 132, 252, + 6, 126, 246, 142, 251, 131, 11, 115, + 225, 153, 17, 105, 28, 100, 236, 148, + 213, 173, 37, 93, 40, 80, 216, 160, + 50, 74, 194, 186, 207, 183, 63, 71 }, + { 0, 121, 242, 139, 249, 128, 11, 114, + 239, 150, 29, 100, 22, 111, 228, 157, + 195, 186, 49, 72, 58, 67, 200, 177, + 44, 85, 222, 167, 213, 172, 39, 94, + 155, 226, 105, 16, 98, 27, 144, 233, + 116, 13, 134, 255, 141, 244, 127, 6, + 88, 33, 170, 211, 161, 216, 83, 42, + 183, 206, 69, 60, 78, 55, 188, 197, + 43, 82, 217, 160, 210, 171, 32, 89, + 196, 189, 54, 79, 61, 68, 207, 182, + 232, 145, 26, 99, 17, 104, 227, 154, + 7, 126, 245, 140, 254, 135, 12, 117, + 176, 201, 66, 59, 73, 48, 187, 194, + 95, 38, 173, 212, 166, 223, 84, 45, + 115, 10, 129, 248, 138, 243, 120, 1, + 156, 229, 110, 23, 101, 28, 151, 238, + 86, 47, 164, 221, 175, 214, 93, 36, + 185, 192, 75, 50, 64, 57, 178, 203, + 149, 236, 103, 30, 108, 21, 158, 231, + 122, 3, 136, 241, 131, 250, 113, 8, + 205, 180, 63, 70, 52, 77, 198, 191, + 34, 91, 208, 169, 219, 162, 41, 80, + 14, 119, 252, 133, 247, 142, 5, 124, + 225, 152, 19, 106, 24, 97, 234, 147, + 125, 4, 143, 246, 132, 253, 118, 15, + 146, 235, 96, 25, 107, 18, 153, 224, + 190, 199, 76, 53, 71, 62, 181, 204, + 81, 40, 163, 218, 168, 209, 90, 35, + 230, 159, 20, 109, 31, 102, 237, 148, + 9, 112, 251, 130, 240, 137, 2, 123, + 37, 92, 215, 174, 220, 165, 46, 87, + 202, 179, 56, 65, 51, 74, 193, 184 }, + { 0, 122, 244, 142, 245, 143, 1, 123, + 247, 141, 3, 121, 2, 120, 246, 140, + 243, 137, 7, 125, 6, 124, 242, 136, + 4, 126, 240, 138, 241, 139, 5, 127, + 251, 129, 15, 117, 14, 116, 250, 128, + 12, 118, 248, 130, 249, 131, 13, 119, + 8, 114, 252, 134, 253, 135, 9, 115, + 255, 133, 11, 113, 10, 112, 254, 132, + 235, 145, 31, 101, 30, 100, 234, 144, + 28, 102, 232, 146, 233, 147, 29, 103, + 24, 98, 236, 150, 237, 151, 25, 99, + 239, 149, 27, 97, 26, 96, 238, 148, + 16, 106, 228, 158, 229, 159, 17, 107, + 231, 157, 19, 105, 18, 104, 230, 156, + 227, 153, 23, 109, 22, 108, 226, 152, + 20, 110, 224, 154, 225, 155, 21, 111, + 203, 177, 63, 69, 62, 68, 202, 176, + 60, 70, 200, 178, 201, 179, 61, 71, + 56, 66, 204, 182, 205, 183, 57, 67, + 207, 181, 59, 65, 58, 64, 206, 180, + 48, 74, 196, 190, 197, 191, 49, 75, + 199, 189, 51, 73, 50, 72, 198, 188, + 195, 185, 55, 77, 54, 76, 194, 184, + 52, 78, 192, 186, 193, 187, 53, 79, + 32, 90, 212, 174, 213, 175, 33, 91, + 215, 173, 35, 89, 34, 88, 214, 172, + 211, 169, 39, 93, 38, 92, 210, 168, + 36, 94, 208, 170, 209, 171, 37, 95, + 219, 161, 47, 85, 46, 84, 218, 160, + 44, 86, 216, 162, 217, 163, 45, 87, + 40, 82, 220, 166, 221, 167, 41, 83, + 223, 165, 43, 81, 42, 80, 222, 164 }, + { 0, 123, 246, 141, 241, 138, 7, 124, + 255, 132, 9, 114, 14, 117, 248, 131, + 227, 152, 21, 110, 18, 105, 228, 159, + 28, 103, 234, 145, 237, 150, 27, 96, + 219, 160, 45, 86, 42, 81, 220, 167, + 36, 95, 210, 169, 213, 174, 35, 88, + 56, 67, 206, 181, 201, 178, 63, 68, + 199, 188, 49, 74, 54, 77, 192, 187, + 171, 208, 93, 38, 90, 33, 172, 215, + 84, 47, 162, 217, 165, 222, 83, 40, + 72, 51, 190, 197, 185, 194, 79, 52, + 183, 204, 65, 58, 70, 61, 176, 203, + 112, 11, 134, 253, 129, 250, 119, 12, + 143, 244, 121, 2, 126, 5, 136, 243, + 147, 232, 101, 30, 98, 25, 148, 239, + 108, 23, 154, 225, 157, 230, 107, 16, + 75, 48, 189, 198, 186, 193, 76, 55, + 180, 207, 66, 57, 69, 62, 179, 200, + 168, 211, 94, 37, 89, 34, 175, 212, + 87, 44, 161, 218, 166, 221, 80, 43, + 144, 235, 102, 29, 97, 26, 151, 236, + 111, 20, 153, 226, 158, 229, 104, 19, + 115, 8, 133, 254, 130, 249, 116, 15, + 140, 247, 122, 1, 125, 6, 139, 240, + 224, 155, 22, 109, 17, 106, 231, 156, + 31, 100, 233, 146, 238, 149, 24, 99, + 3, 120, 245, 142, 242, 137, 4, 127, + 252, 135, 10, 113, 13, 118, 251, 128, + 59, 64, 205, 182, 202, 177, 60, 71, + 196, 191, 50, 73, 53, 78, 195, 184, + 216, 163, 46, 85, 41, 82, 223, 164, + 39, 92, 209, 170, 214, 173, 32, 91 }, + { 0, 124, 248, 132, 237, 145, 21, 105, + 199, 187, 63, 67, 42, 86, 210, 174, + 147, 239, 107, 23, 126, 2, 134, 250, + 84, 40, 172, 208, 185, 197, 65, 61, + 59, 71, 195, 191, 214, 170, 46, 82, + 252, 128, 4, 120, 17, 109, 233, 149, + 168, 212, 80, 44, 69, 57, 189, 193, + 111, 19, 151, 235, 130, 254, 122, 6, + 118, 10, 142, 242, 155, 231, 99, 31, + 177, 205, 73, 53, 92, 32, 164, 216, + 229, 153, 29, 97, 8, 116, 240, 140, + 34, 94, 218, 166, 207, 179, 55, 75, + 77, 49, 181, 201, 160, 220, 88, 36, + 138, 246, 114, 14, 103, 27, 159, 227, + 222, 162, 38, 90, 51, 79, 203, 183, + 25, 101, 225, 157, 244, 136, 12, 112, + 236, 144, 20, 104, 1, 125, 249, 133, + 43, 87, 211, 175, 198, 186, 62, 66, + 127, 3, 135, 251, 146, 238, 106, 22, + 184, 196, 64, 60, 85, 41, 173, 209, + 215, 171, 47, 83, 58, 70, 194, 190, + 16, 108, 232, 148, 253, 129, 5, 121, + 68, 56, 188, 192, 169, 213, 81, 45, + 131, 255, 123, 7, 110, 18, 150, 234, + 154, 230, 98, 30, 119, 11, 143, 243, + 93, 33, 165, 217, 176, 204, 72, 52, + 9, 117, 241, 141, 228, 152, 28, 96, + 206, 178, 54, 74, 35, 95, 219, 167, + 161, 221, 89, 37, 76, 48, 180, 200, + 102, 26, 158, 226, 139, 247, 115, 15, + 50, 78, 202, 182, 223, 163, 39, 91, + 245, 137, 13, 113, 24, 100, 224, 156 }, + { 0, 125, 250, 135, 233, 148, 19, 110, + 207, 178, 53, 72, 38, 91, 220, 161, + 131, 254, 121, 4, 106, 23, 144, 237, + 76, 49, 182, 203, 165, 216, 95, 34, + 27, 102, 225, 156, 242, 143, 8, 117, + 212, 169, 46, 83, 61, 64, 199, 186, + 152, 229, 98, 31, 113, 12, 139, 246, + 87, 42, 173, 208, 190, 195, 68, 57, + 54, 75, 204, 177, 223, 162, 37, 88, + 249, 132, 3, 126, 16, 109, 234, 151, + 181, 200, 79, 50, 92, 33, 166, 219, + 122, 7, 128, 253, 147, 238, 105, 20, + 45, 80, 215, 170, 196, 185, 62, 67, + 226, 159, 24, 101, 11, 118, 241, 140, + 174, 211, 84, 41, 71, 58, 189, 192, + 97, 28, 155, 230, 136, 245, 114, 15, + 108, 17, 150, 235, 133, 248, 127, 2, + 163, 222, 89, 36, 74, 55, 176, 205, + 239, 146, 21, 104, 6, 123, 252, 129, + 32, 93, 218, 167, 201, 180, 51, 78, + 119, 10, 141, 240, 158, 227, 100, 25, + 184, 197, 66, 63, 81, 44, 171, 214, + 244, 137, 14, 115, 29, 96, 231, 154, + 59, 70, 193, 188, 210, 175, 40, 85, + 90, 39, 160, 221, 179, 206, 73, 52, + 149, 232, 111, 18, 124, 1, 134, 251, + 217, 164, 35, 94, 48, 77, 202, 183, + 22, 107, 236, 145, 255, 130, 5, 120, + 65, 60, 187, 198, 168, 213, 82, 47, + 142, 243, 116, 9, 103, 26, 157, 224, + 194, 191, 56, 69, 43, 86, 209, 172, + 13, 112, 247, 138, 228, 153, 30, 99 }, + { 0, 126, 252, 130, 229, 155, 25, 103, + 215, 169, 43, 85, 50, 76, 206, 176, + 179, 205, 79, 49, 86, 40, 170, 212, + 100, 26, 152, 230, 129, 255, 125, 3, + 123, 5, 135, 249, 158, 224, 98, 28, + 172, 210, 80, 46, 73, 55, 181, 203, + 200, 182, 52, 74, 45, 83, 209, 175, + 31, 97, 227, 157, 250, 132, 6, 120, + 246, 136, 10, 116, 19, 109, 239, 145, + 33, 95, 221, 163, 196, 186, 56, 70, + 69, 59, 185, 199, 160, 222, 92, 34, + 146, 236, 110, 16, 119, 9, 139, 245, + 141, 243, 113, 15, 104, 22, 148, 234, + 90, 36, 166, 216, 191, 193, 67, 61, + 62, 64, 194, 188, 219, 165, 39, 89, + 233, 151, 21, 107, 12, 114, 240, 142, + 241, 143, 13, 115, 20, 106, 232, 150, + 38, 88, 218, 164, 195, 189, 63, 65, + 66, 60, 190, 192, 167, 217, 91, 37, + 149, 235, 105, 23, 112, 14, 140, 242, + 138, 244, 118, 8, 111, 17, 147, 237, + 93, 35, 161, 223, 184, 198, 68, 58, + 57, 71, 197, 187, 220, 162, 32, 94, + 238, 144, 18, 108, 11, 117, 247, 137, + 7, 121, 251, 133, 226, 156, 30, 96, + 208, 174, 44, 82, 53, 75, 201, 183, + 180, 202, 72, 54, 81, 47, 173, 211, + 99, 29, 159, 225, 134, 248, 122, 4, + 124, 2, 128, 254, 153, 231, 101, 27, + 171, 213, 87, 41, 78, 48, 178, 204, + 207, 177, 51, 77, 42, 84, 214, 168, + 24, 102, 228, 154, 253, 131, 1, 127 }, + { 0, 127, 254, 129, 225, 158, 31, 96, + 223, 160, 33, 94, 62, 65, 192, 191, + 163, 220, 93, 34, 66, 61, 188, 195, + 124, 3, 130, 253, 157, 226, 99, 28, + 91, 36, 165, 218, 186, 197, 68, 59, + 132, 251, 122, 5, 101, 26, 155, 228, + 248, 135, 6, 121, 25, 102, 231, 152, + 39, 88, 217, 166, 198, 185, 56, 71, + 182, 201, 72, 55, 87, 40, 169, 214, + 105, 22, 151, 232, 136, 247, 118, 9, + 21, 106, 235, 148, 244, 139, 10, 117, + 202, 181, 52, 75, 43, 84, 213, 170, + 237, 146, 19, 108, 12, 115, 242, 141, + 50, 77, 204, 179, 211, 172, 45, 82, + 78, 49, 176, 207, 175, 208, 81, 46, + 145, 238, 111, 16, 112, 15, 142, 241, + 113, 14, 143, 240, 144, 239, 110, 17, + 174, 209, 80, 47, 79, 48, 177, 206, + 210, 173, 44, 83, 51, 76, 205, 178, + 13, 114, 243, 140, 236, 147, 18, 109, + 42, 85, 212, 171, 203, 180, 53, 74, + 245, 138, 11, 116, 20, 107, 234, 149, + 137, 246, 119, 8, 104, 23, 150, 233, + 86, 41, 168, 215, 183, 200, 73, 54, + 199, 184, 57, 70, 38, 89, 216, 167, + 24, 103, 230, 153, 249, 134, 7, 120, + 100, 27, 154, 229, 133, 250, 123, 4, + 187, 196, 69, 58, 90, 37, 164, 219, + 156, 227, 98, 29, 125, 2, 131, 252, + 67, 60, 189, 194, 162, 221, 92, 35, + 63, 64, 193, 190, 222, 161, 32, 95, + 224, 159, 30, 97, 1, 126, 255, 128 }, + { 0, 128, 29, 157, 58, 186, 39, 167, + 116, 244, 105, 233, 78, 206, 83, 211, + 232, 104, 245, 117, 210, 82, 207, 79, + 156, 28, 129, 1, 166, 38, 187, 59, + 205, 77, 208, 80, 247, 119, 234, 106, + 185, 57, 164, 36, 131, 3, 158, 30, + 37, 165, 56, 184, 31, 159, 2, 130, + 81, 209, 76, 204, 107, 235, 118, 246, + 135, 7, 154, 26, 189, 61, 160, 32, + 243, 115, 238, 110, 201, 73, 212, 84, + 111, 239, 114, 242, 85, 213, 72, 200, + 27, 155, 6, 134, 33, 161, 60, 188, + 74, 202, 87, 215, 112, 240, 109, 237, + 62, 190, 35, 163, 4, 132, 25, 153, + 162, 34, 191, 63, 152, 24, 133, 5, + 214, 86, 203, 75, 236, 108, 241, 113, + 19, 147, 14, 142, 41, 169, 52, 180, + 103, 231, 122, 250, 93, 221, 64, 192, + 251, 123, 230, 102, 193, 65, 220, 92, + 143, 15, 146, 18, 181, 53, 168, 40, + 222, 94, 195, 67, 228, 100, 249, 121, + 170, 42, 183, 55, 144, 16, 141, 13, + 54, 182, 43, 171, 12, 140, 17, 145, + 66, 194, 95, 223, 120, 248, 101, 229, + 148, 20, 137, 9, 174, 46, 179, 51, + 224, 96, 253, 125, 218, 90, 199, 71, + 124, 252, 97, 225, 70, 198, 91, 219, + 8, 136, 21, 149, 50, 178, 47, 175, + 89, 217, 68, 196, 99, 227, 126, 254, + 45, 173, 48, 176, 23, 151, 10, 138, + 177, 49, 172, 44, 139, 11, 150, 22, + 197, 69, 216, 88, 255, 127, 226, 98 }, + { 0, 129, 31, 158, 62, 191, 33, 160, + 124, 253, 99, 226, 66, 195, 93, 220, + 248, 121, 231, 102, 198, 71, 217, 88, + 132, 5, 155, 26, 186, 59, 165, 36, + 237, 108, 242, 115, 211, 82, 204, 77, + 145, 16, 142, 15, 175, 46, 176, 49, + 21, 148, 10, 139, 43, 170, 52, 181, + 105, 232, 118, 247, 87, 214, 72, 201, + 199, 70, 216, 89, 249, 120, 230, 103, + 187, 58, 164, 37, 133, 4, 154, 27, + 63, 190, 32, 161, 1, 128, 30, 159, + 67, 194, 92, 221, 125, 252, 98, 227, + 42, 171, 53, 180, 20, 149, 11, 138, + 86, 215, 73, 200, 104, 233, 119, 246, + 210, 83, 205, 76, 236, 109, 243, 114, + 174, 47, 177, 48, 144, 17, 143, 14, + 147, 18, 140, 13, 173, 44, 178, 51, + 239, 110, 240, 113, 209, 80, 206, 79, + 107, 234, 116, 245, 85, 212, 74, 203, + 23, 150, 8, 137, 41, 168, 54, 183, + 126, 255, 97, 224, 64, 193, 95, 222, + 2, 131, 29, 156, 60, 189, 35, 162, + 134, 7, 153, 24, 184, 57, 167, 38, + 250, 123, 229, 100, 196, 69, 219, 90, + 84, 213, 75, 202, 106, 235, 117, 244, + 40, 169, 55, 182, 22, 151, 9, 136, + 172, 45, 179, 50, 146, 19, 141, 12, + 208, 81, 207, 78, 238, 111, 241, 112, + 185, 56, 166, 39, 135, 6, 152, 25, + 197, 68, 218, 91, 251, 122, 228, 101, + 65, 192, 94, 223, 127, 254, 96, 225, + 61, 188, 34, 163, 3, 130, 28, 157 }, + { 0, 130, 25, 155, 50, 176, 43, 169, + 100, 230, 125, 255, 86, 212, 79, 205, + 200, 74, 209, 83, 250, 120, 227, 97, + 172, 46, 181, 55, 158, 28, 135, 5, + 141, 15, 148, 22, 191, 61, 166, 36, + 233, 107, 240, 114, 219, 89, 194, 64, + 69, 199, 92, 222, 119, 245, 110, 236, + 33, 163, 56, 186, 19, 145, 10, 136, + 7, 133, 30, 156, 53, 183, 44, 174, + 99, 225, 122, 248, 81, 211, 72, 202, + 207, 77, 214, 84, 253, 127, 228, 102, + 171, 41, 178, 48, 153, 27, 128, 2, + 138, 8, 147, 17, 184, 58, 161, 35, + 238, 108, 247, 117, 220, 94, 197, 71, + 66, 192, 91, 217, 112, 242, 105, 235, + 38, 164, 63, 189, 20, 150, 13, 143, + 14, 140, 23, 149, 60, 190, 37, 167, + 106, 232, 115, 241, 88, 218, 65, 195, + 198, 68, 223, 93, 244, 118, 237, 111, + 162, 32, 187, 57, 144, 18, 137, 11, + 131, 1, 154, 24, 177, 51, 168, 42, + 231, 101, 254, 124, 213, 87, 204, 78, + 75, 201, 82, 208, 121, 251, 96, 226, + 47, 173, 54, 180, 29, 159, 4, 134, + 9, 139, 16, 146, 59, 185, 34, 160, + 109, 239, 116, 246, 95, 221, 70, 196, + 193, 67, 216, 90, 243, 113, 234, 104, + 165, 39, 188, 62, 151, 21, 142, 12, + 132, 6, 157, 31, 182, 52, 175, 45, + 224, 98, 249, 123, 210, 80, 203, 73, + 76, 206, 85, 215, 126, 252, 103, 229, + 40, 170, 49, 179, 26, 152, 3, 129 }, + { 0, 131, 27, 152, 54, 181, 45, 174, + 108, 239, 119, 244, 90, 217, 65, 194, + 216, 91, 195, 64, 238, 109, 245, 118, + 180, 55, 175, 44, 130, 1, 153, 26, + 173, 46, 182, 53, 155, 24, 128, 3, + 193, 66, 218, 89, 247, 116, 236, 111, + 117, 246, 110, 237, 67, 192, 88, 219, + 25, 154, 2, 129, 47, 172, 52, 183, + 71, 196, 92, 223, 113, 242, 106, 233, + 43, 168, 48, 179, 29, 158, 6, 133, + 159, 28, 132, 7, 169, 42, 178, 49, + 243, 112, 232, 107, 197, 70, 222, 93, + 234, 105, 241, 114, 220, 95, 199, 68, + 134, 5, 157, 30, 176, 51, 171, 40, + 50, 177, 41, 170, 4, 135, 31, 156, + 94, 221, 69, 198, 104, 235, 115, 240, + 142, 13, 149, 22, 184, 59, 163, 32, + 226, 97, 249, 122, 212, 87, 207, 76, + 86, 213, 77, 206, 96, 227, 123, 248, + 58, 185, 33, 162, 12, 143, 23, 148, + 35, 160, 56, 187, 21, 150, 14, 141, + 79, 204, 84, 215, 121, 250, 98, 225, + 251, 120, 224, 99, 205, 78, 214, 85, + 151, 20, 140, 15, 161, 34, 186, 57, + 201, 74, 210, 81, 255, 124, 228, 103, + 165, 38, 190, 61, 147, 16, 136, 11, + 17, 146, 10, 137, 39, 164, 60, 191, + 125, 254, 102, 229, 75, 200, 80, 211, + 100, 231, 127, 252, 82, 209, 73, 202, + 8, 139, 19, 144, 62, 189, 37, 166, + 188, 63, 167, 36, 138, 9, 145, 18, + 208, 83, 203, 72, 230, 101, 253, 126 }, + { 0, 132, 21, 145, 42, 174, 63, 187, + 84, 208, 65, 197, 126, 250, 107, 239, + 168, 44, 189, 57, 130, 6, 151, 19, + 252, 120, 233, 109, 214, 82, 195, 71, + 77, 201, 88, 220, 103, 227, 114, 246, + 25, 157, 12, 136, 51, 183, 38, 162, + 229, 97, 240, 116, 207, 75, 218, 94, + 177, 53, 164, 32, 155, 31, 142, 10, + 154, 30, 143, 11, 176, 52, 165, 33, + 206, 74, 219, 95, 228, 96, 241, 117, + 50, 182, 39, 163, 24, 156, 13, 137, + 102, 226, 115, 247, 76, 200, 89, 221, + 215, 83, 194, 70, 253, 121, 232, 108, + 131, 7, 150, 18, 169, 45, 188, 56, + 127, 251, 106, 238, 85, 209, 64, 196, + 43, 175, 62, 186, 1, 133, 20, 144, + 41, 173, 60, 184, 3, 135, 22, 146, + 125, 249, 104, 236, 87, 211, 66, 198, + 129, 5, 148, 16, 171, 47, 190, 58, + 213, 81, 192, 68, 255, 123, 234, 110, + 100, 224, 113, 245, 78, 202, 91, 223, + 48, 180, 37, 161, 26, 158, 15, 139, + 204, 72, 217, 93, 230, 98, 243, 119, + 152, 28, 141, 9, 178, 54, 167, 35, + 179, 55, 166, 34, 153, 29, 140, 8, + 231, 99, 242, 118, 205, 73, 216, 92, + 27, 159, 14, 138, 49, 181, 36, 160, + 79, 203, 90, 222, 101, 225, 112, 244, + 254, 122, 235, 111, 212, 80, 193, 69, + 170, 46, 191, 59, 128, 4, 149, 17, + 86, 210, 67, 199, 124, 248, 105, 237, + 2, 134, 23, 147, 40, 172, 61, 185 }, + { 0, 133, 23, 146, 46, 171, 57, 188, + 92, 217, 75, 206, 114, 247, 101, 224, + 184, 61, 175, 42, 150, 19, 129, 4, + 228, 97, 243, 118, 202, 79, 221, 88, + 109, 232, 122, 255, 67, 198, 84, 209, + 49, 180, 38, 163, 31, 154, 8, 141, + 213, 80, 194, 71, 251, 126, 236, 105, + 137, 12, 158, 27, 167, 34, 176, 53, + 218, 95, 205, 72, 244, 113, 227, 102, + 134, 3, 145, 20, 168, 45, 191, 58, + 98, 231, 117, 240, 76, 201, 91, 222, + 62, 187, 41, 172, 16, 149, 7, 130, + 183, 50, 160, 37, 153, 28, 142, 11, + 235, 110, 252, 121, 197, 64, 210, 87, + 15, 138, 24, 157, 33, 164, 54, 179, + 83, 214, 68, 193, 125, 248, 106, 239, + 169, 44, 190, 59, 135, 2, 144, 21, + 245, 112, 226, 103, 219, 94, 204, 73, + 17, 148, 6, 131, 63, 186, 40, 173, + 77, 200, 90, 223, 99, 230, 116, 241, + 196, 65, 211, 86, 234, 111, 253, 120, + 152, 29, 143, 10, 182, 51, 161, 36, + 124, 249, 107, 238, 82, 215, 69, 192, + 32, 165, 55, 178, 14, 139, 25, 156, + 115, 246, 100, 225, 93, 216, 74, 207, + 47, 170, 56, 189, 1, 132, 22, 147, + 203, 78, 220, 89, 229, 96, 242, 119, + 151, 18, 128, 5, 185, 60, 174, 43, + 30, 155, 9, 140, 48, 181, 39, 162, + 66, 199, 85, 208, 108, 233, 123, 254, + 166, 35, 177, 52, 136, 13, 159, 26, + 250, 127, 237, 104, 212, 81, 195, 70 }, + { 0, 134, 17, 151, 34, 164, 51, 181, + 68, 194, 85, 211, 102, 224, 119, 241, + 136, 14, 153, 31, 170, 44, 187, 61, + 204, 74, 221, 91, 238, 104, 255, 121, + 13, 139, 28, 154, 47, 169, 62, 184, + 73, 207, 88, 222, 107, 237, 122, 252, + 133, 3, 148, 18, 167, 33, 182, 48, + 193, 71, 208, 86, 227, 101, 242, 116, + 26, 156, 11, 141, 56, 190, 41, 175, + 94, 216, 79, 201, 124, 250, 109, 235, + 146, 20, 131, 5, 176, 54, 161, 39, + 214, 80, 199, 65, 244, 114, 229, 99, + 23, 145, 6, 128, 53, 179, 36, 162, + 83, 213, 66, 196, 113, 247, 96, 230, + 159, 25, 142, 8, 189, 59, 172, 42, + 219, 93, 202, 76, 249, 127, 232, 110, + 52, 178, 37, 163, 22, 144, 7, 129, + 112, 246, 97, 231, 82, 212, 67, 197, + 188, 58, 173, 43, 158, 24, 143, 9, + 248, 126, 233, 111, 218, 92, 203, 77, + 57, 191, 40, 174, 27, 157, 10, 140, + 125, 251, 108, 234, 95, 217, 78, 200, + 177, 55, 160, 38, 147, 21, 130, 4, + 245, 115, 228, 98, 215, 81, 198, 64, + 46, 168, 63, 185, 12, 138, 29, 155, + 106, 236, 123, 253, 72, 206, 89, 223, + 166, 32, 183, 49, 132, 2, 149, 19, + 226, 100, 243, 117, 192, 70, 209, 87, + 35, 165, 50, 180, 1, 135, 16, 150, + 103, 225, 118, 240, 69, 195, 84, 210, + 171, 45, 186, 60, 137, 15, 152, 30, + 239, 105, 254, 120, 205, 75, 220, 90 }, + { 0, 135, 19, 148, 38, 161, 53, 178, + 76, 203, 95, 216, 106, 237, 121, 254, + 152, 31, 139, 12, 190, 57, 173, 42, + 212, 83, 199, 64, 242, 117, 225, 102, + 45, 170, 62, 185, 11, 140, 24, 159, + 97, 230, 114, 245, 71, 192, 84, 211, + 181, 50, 166, 33, 147, 20, 128, 7, + 249, 126, 234, 109, 223, 88, 204, 75, + 90, 221, 73, 206, 124, 251, 111, 232, + 22, 145, 5, 130, 48, 183, 35, 164, + 194, 69, 209, 86, 228, 99, 247, 112, + 142, 9, 157, 26, 168, 47, 187, 60, + 119, 240, 100, 227, 81, 214, 66, 197, + 59, 188, 40, 175, 29, 154, 14, 137, + 239, 104, 252, 123, 201, 78, 218, 93, + 163, 36, 176, 55, 133, 2, 150, 17, + 180, 51, 167, 32, 146, 21, 129, 6, + 248, 127, 235, 108, 222, 89, 205, 74, + 44, 171, 63, 184, 10, 141, 25, 158, + 96, 231, 115, 244, 70, 193, 85, 210, + 153, 30, 138, 13, 191, 56, 172, 43, + 213, 82, 198, 65, 243, 116, 224, 103, + 1, 134, 18, 149, 39, 160, 52, 179, + 77, 202, 94, 217, 107, 236, 120, 255, + 238, 105, 253, 122, 200, 79, 219, 92, + 162, 37, 177, 54, 132, 3, 151, 16, + 118, 241, 101, 226, 80, 215, 67, 196, + 58, 189, 41, 174, 28, 155, 15, 136, + 195, 68, 208, 87, 229, 98, 246, 113, + 143, 8, 156, 27, 169, 46, 186, 61, + 91, 220, 72, 207, 125, 250, 110, 233, + 23, 144, 4, 131, 49, 182, 34, 165 }, + { 0, 136, 13, 133, 26, 146, 23, 159, + 52, 188, 57, 177, 46, 166, 35, 171, + 104, 224, 101, 237, 114, 250, 127, 247, + 92, 212, 81, 217, 70, 206, 75, 195, + 208, 88, 221, 85, 202, 66, 199, 79, + 228, 108, 233, 97, 254, 118, 243, 123, + 184, 48, 181, 61, 162, 42, 175, 39, + 140, 4, 129, 9, 150, 30, 155, 19, + 189, 53, 176, 56, 167, 47, 170, 34, + 137, 1, 132, 12, 147, 27, 158, 22, + 213, 93, 216, 80, 207, 71, 194, 74, + 225, 105, 236, 100, 251, 115, 246, 126, + 109, 229, 96, 232, 119, 255, 122, 242, + 89, 209, 84, 220, 67, 203, 78, 198, + 5, 141, 8, 128, 31, 151, 18, 154, + 49, 185, 60, 180, 43, 163, 38, 174, + 103, 239, 106, 226, 125, 245, 112, 248, + 83, 219, 94, 214, 73, 193, 68, 204, + 15, 135, 2, 138, 21, 157, 24, 144, + 59, 179, 54, 190, 33, 169, 44, 164, + 183, 63, 186, 50, 173, 37, 160, 40, + 131, 11, 142, 6, 153, 17, 148, 28, + 223, 87, 210, 90, 197, 77, 200, 64, + 235, 99, 230, 110, 241, 121, 252, 116, + 218, 82, 215, 95, 192, 72, 205, 69, + 238, 102, 227, 107, 244, 124, 249, 113, + 178, 58, 191, 55, 168, 32, 165, 45, + 134, 14, 139, 3, 156, 20, 145, 25, + 10, 130, 7, 143, 16, 152, 29, 149, + 62, 182, 51, 187, 36, 172, 41, 161, + 98, 234, 111, 231, 120, 240, 117, 253, + 86, 222, 91, 211, 76, 196, 65, 201 }, + { 0, 137, 15, 134, 30, 151, 17, 152, + 60, 181, 51, 186, 34, 171, 45, 164, + 120, 241, 119, 254, 102, 239, 105, 224, + 68, 205, 75, 194, 90, 211, 85, 220, + 240, 121, 255, 118, 238, 103, 225, 104, + 204, 69, 195, 74, 210, 91, 221, 84, + 136, 1, 135, 14, 150, 31, 153, 16, + 180, 61, 187, 50, 170, 35, 165, 44, + 253, 116, 242, 123, 227, 106, 236, 101, + 193, 72, 206, 71, 223, 86, 208, 89, + 133, 12, 138, 3, 155, 18, 148, 29, + 185, 48, 182, 63, 167, 46, 168, 33, + 13, 132, 2, 139, 19, 154, 28, 149, + 49, 184, 62, 183, 47, 166, 32, 169, + 117, 252, 122, 243, 107, 226, 100, 237, + 73, 192, 70, 207, 87, 222, 88, 209, + 231, 110, 232, 97, 249, 112, 246, 127, + 219, 82, 212, 93, 197, 76, 202, 67, + 159, 22, 144, 25, 129, 8, 142, 7, + 163, 42, 172, 37, 189, 52, 178, 59, + 23, 158, 24, 145, 9, 128, 6, 143, + 43, 162, 36, 173, 53, 188, 58, 179, + 111, 230, 96, 233, 113, 248, 126, 247, + 83, 218, 92, 213, 77, 196, 66, 203, + 26, 147, 21, 156, 4, 141, 11, 130, + 38, 175, 41, 160, 56, 177, 55, 190, + 98, 235, 109, 228, 124, 245, 115, 250, + 94, 215, 81, 216, 64, 201, 79, 198, + 234, 99, 229, 108, 244, 125, 251, 114, + 214, 95, 217, 80, 200, 65, 199, 78, + 146, 27, 157, 20, 140, 5, 131, 10, + 174, 39, 161, 40, 176, 57, 191, 54 }, + { 0, 138, 9, 131, 18, 152, 27, 145, + 36, 174, 45, 167, 54, 188, 63, 181, + 72, 194, 65, 203, 90, 208, 83, 217, + 108, 230, 101, 239, 126, 244, 119, 253, + 144, 26, 153, 19, 130, 8, 139, 1, + 180, 62, 189, 55, 166, 44, 175, 37, + 216, 82, 209, 91, 202, 64, 195, 73, + 252, 118, 245, 127, 238, 100, 231, 109, + 61, 183, 52, 190, 47, 165, 38, 172, + 25, 147, 16, 154, 11, 129, 2, 136, + 117, 255, 124, 246, 103, 237, 110, 228, + 81, 219, 88, 210, 67, 201, 74, 192, + 173, 39, 164, 46, 191, 53, 182, 60, + 137, 3, 128, 10, 155, 17, 146, 24, + 229, 111, 236, 102, 247, 125, 254, 116, + 193, 75, 200, 66, 211, 89, 218, 80, + 122, 240, 115, 249, 104, 226, 97, 235, + 94, 212, 87, 221, 76, 198, 69, 207, + 50, 184, 59, 177, 32, 170, 41, 163, + 22, 156, 31, 149, 4, 142, 13, 135, + 234, 96, 227, 105, 248, 114, 241, 123, + 206, 68, 199, 77, 220, 86, 213, 95, + 162, 40, 171, 33, 176, 58, 185, 51, + 134, 12, 143, 5, 148, 30, 157, 23, + 71, 205, 78, 196, 85, 223, 92, 214, + 99, 233, 106, 224, 113, 251, 120, 242, + 15, 133, 6, 140, 29, 151, 20, 158, + 43, 161, 34, 168, 57, 179, 48, 186, + 215, 93, 222, 84, 197, 79, 204, 70, + 243, 121, 250, 112, 225, 107, 232, 98, + 159, 21, 150, 28, 141, 7, 132, 14, + 187, 49, 178, 56, 169, 35, 160, 42 }, + { 0, 139, 11, 128, 22, 157, 29, 150, + 44, 167, 39, 172, 58, 177, 49, 186, + 88, 211, 83, 216, 78, 197, 69, 206, + 116, 255, 127, 244, 98, 233, 105, 226, + 176, 59, 187, 48, 166, 45, 173, 38, + 156, 23, 151, 28, 138, 1, 129, 10, + 232, 99, 227, 104, 254, 117, 245, 126, + 196, 79, 207, 68, 210, 89, 217, 82, + 125, 246, 118, 253, 107, 224, 96, 235, + 81, 218, 90, 209, 71, 204, 76, 199, + 37, 174, 46, 165, 51, 184, 56, 179, + 9, 130, 2, 137, 31, 148, 20, 159, + 205, 70, 198, 77, 219, 80, 208, 91, + 225, 106, 234, 97, 247, 124, 252, 119, + 149, 30, 158, 21, 131, 8, 136, 3, + 185, 50, 178, 57, 175, 36, 164, 47, + 250, 113, 241, 122, 236, 103, 231, 108, + 214, 93, 221, 86, 192, 75, 203, 64, + 162, 41, 169, 34, 180, 63, 191, 52, + 142, 5, 133, 14, 152, 19, 147, 24, + 74, 193, 65, 202, 92, 215, 87, 220, + 102, 237, 109, 230, 112, 251, 123, 240, + 18, 153, 25, 146, 4, 143, 15, 132, + 62, 181, 53, 190, 40, 163, 35, 168, + 135, 12, 140, 7, 145, 26, 154, 17, + 171, 32, 160, 43, 189, 54, 182, 61, + 223, 84, 212, 95, 201, 66, 194, 73, + 243, 120, 248, 115, 229, 110, 238, 101, + 55, 188, 60, 183, 33, 170, 42, 161, + 27, 144, 16, 155, 13, 134, 6, 141, + 111, 228, 100, 239, 121, 242, 114, 249, + 67, 200, 72, 195, 85, 222, 94, 213 }, + { 0, 140, 5, 137, 10, 134, 15, 131, + 20, 152, 17, 157, 30, 146, 27, 151, + 40, 164, 45, 161, 34, 174, 39, 171, + 60, 176, 57, 181, 54, 186, 51, 191, + 80, 220, 85, 217, 90, 214, 95, 211, + 68, 200, 65, 205, 78, 194, 75, 199, + 120, 244, 125, 241, 114, 254, 119, 251, + 108, 224, 105, 229, 102, 234, 99, 239, + 160, 44, 165, 41, 170, 38, 175, 35, + 180, 56, 177, 61, 190, 50, 187, 55, + 136, 4, 141, 1, 130, 14, 135, 11, + 156, 16, 153, 21, 150, 26, 147, 31, + 240, 124, 245, 121, 250, 118, 255, 115, + 228, 104, 225, 109, 238, 98, 235, 103, + 216, 84, 221, 81, 210, 94, 215, 91, + 204, 64, 201, 69, 198, 74, 195, 79, + 93, 209, 88, 212, 87, 219, 82, 222, + 73, 197, 76, 192, 67, 207, 70, 202, + 117, 249, 112, 252, 127, 243, 122, 246, + 97, 237, 100, 232, 107, 231, 110, 226, + 13, 129, 8, 132, 7, 139, 2, 142, + 25, 149, 28, 144, 19, 159, 22, 154, + 37, 169, 32, 172, 47, 163, 42, 166, + 49, 189, 52, 184, 59, 183, 62, 178, + 253, 113, 248, 116, 247, 123, 242, 126, + 233, 101, 236, 96, 227, 111, 230, 106, + 213, 89, 208, 92, 223, 83, 218, 86, + 193, 77, 196, 72, 203, 71, 206, 66, + 173, 33, 168, 36, 167, 43, 162, 46, + 185, 53, 188, 48, 179, 63, 182, 58, + 133, 9, 128, 12, 143, 3, 138, 6, + 145, 29, 148, 24, 155, 23, 158, 18 }, + { 0, 141, 7, 138, 14, 131, 9, 132, + 28, 145, 27, 150, 18, 159, 21, 152, + 56, 181, 63, 178, 54, 187, 49, 188, + 36, 169, 35, 174, 42, 167, 45, 160, + 112, 253, 119, 250, 126, 243, 121, 244, + 108, 225, 107, 230, 98, 239, 101, 232, + 72, 197, 79, 194, 70, 203, 65, 204, + 84, 217, 83, 222, 90, 215, 93, 208, + 224, 109, 231, 106, 238, 99, 233, 100, + 252, 113, 251, 118, 242, 127, 245, 120, + 216, 85, 223, 82, 214, 91, 209, 92, + 196, 73, 195, 78, 202, 71, 205, 64, + 144, 29, 151, 26, 158, 19, 153, 20, + 140, 1, 139, 6, 130, 15, 133, 8, + 168, 37, 175, 34, 166, 43, 161, 44, + 180, 57, 179, 62, 186, 55, 189, 48, + 221, 80, 218, 87, 211, 94, 212, 89, + 193, 76, 198, 75, 207, 66, 200, 69, + 229, 104, 226, 111, 235, 102, 236, 97, + 249, 116, 254, 115, 247, 122, 240, 125, + 173, 32, 170, 39, 163, 46, 164, 41, + 177, 60, 182, 59, 191, 50, 184, 53, + 149, 24, 146, 31, 155, 22, 156, 17, + 137, 4, 142, 3, 135, 10, 128, 13, + 61, 176, 58, 183, 51, 190, 52, 185, + 33, 172, 38, 171, 47, 162, 40, 165, + 5, 136, 2, 143, 11, 134, 12, 129, + 25, 148, 30, 147, 23, 154, 16, 157, + 77, 192, 74, 199, 67, 206, 68, 201, + 81, 220, 86, 219, 95, 210, 88, 213, + 117, 248, 114, 255, 123, 246, 124, 241, + 105, 228, 110, 227, 103, 234, 96, 237 }, + { 0, 142, 1, 143, 2, 140, 3, 141, + 4, 138, 5, 139, 6, 136, 7, 137, + 8, 134, 9, 135, 10, 132, 11, 133, + 12, 130, 13, 131, 14, 128, 15, 129, + 16, 158, 17, 159, 18, 156, 19, 157, + 20, 154, 21, 155, 22, 152, 23, 153, + 24, 150, 25, 151, 26, 148, 27, 149, + 28, 146, 29, 147, 30, 144, 31, 145, + 32, 174, 33, 175, 34, 172, 35, 173, + 36, 170, 37, 171, 38, 168, 39, 169, + 40, 166, 41, 167, 42, 164, 43, 165, + 44, 162, 45, 163, 46, 160, 47, 161, + 48, 190, 49, 191, 50, 188, 51, 189, + 52, 186, 53, 187, 54, 184, 55, 185, + 56, 182, 57, 183, 58, 180, 59, 181, + 60, 178, 61, 179, 62, 176, 63, 177, + 64, 206, 65, 207, 66, 204, 67, 205, + 68, 202, 69, 203, 70, 200, 71, 201, + 72, 198, 73, 199, 74, 196, 75, 197, + 76, 194, 77, 195, 78, 192, 79, 193, + 80, 222, 81, 223, 82, 220, 83, 221, + 84, 218, 85, 219, 86, 216, 87, 217, + 88, 214, 89, 215, 90, 212, 91, 213, + 92, 210, 93, 211, 94, 208, 95, 209, + 96, 238, 97, 239, 98, 236, 99, 237, + 100, 234, 101, 235, 102, 232, 103, 233, + 104, 230, 105, 231, 106, 228, 107, 229, + 108, 226, 109, 227, 110, 224, 111, 225, + 112, 254, 113, 255, 114, 252, 115, 253, + 116, 250, 117, 251, 118, 248, 119, 249, + 120, 246, 121, 247, 122, 244, 123, 245, + 124, 242, 125, 243, 126, 240, 127, 241 }, + { 0, 143, 3, 140, 6, 137, 5, 138, + 12, 131, 15, 128, 10, 133, 9, 134, + 24, 151, 27, 148, 30, 145, 29, 146, + 20, 155, 23, 152, 18, 157, 17, 158, + 48, 191, 51, 188, 54, 185, 53, 186, + 60, 179, 63, 176, 58, 181, 57, 182, + 40, 167, 43, 164, 46, 161, 45, 162, + 36, 171, 39, 168, 34, 173, 33, 174, + 96, 239, 99, 236, 102, 233, 101, 234, + 108, 227, 111, 224, 106, 229, 105, 230, + 120, 247, 123, 244, 126, 241, 125, 242, + 116, 251, 119, 248, 114, 253, 113, 254, + 80, 223, 83, 220, 86, 217, 85, 218, + 92, 211, 95, 208, 90, 213, 89, 214, + 72, 199, 75, 196, 78, 193, 77, 194, + 68, 203, 71, 200, 66, 205, 65, 206, + 192, 79, 195, 76, 198, 73, 197, 74, + 204, 67, 207, 64, 202, 69, 201, 70, + 216, 87, 219, 84, 222, 81, 221, 82, + 212, 91, 215, 88, 210, 93, 209, 94, + 240, 127, 243, 124, 246, 121, 245, 122, + 252, 115, 255, 112, 250, 117, 249, 118, + 232, 103, 235, 100, 238, 97, 237, 98, + 228, 107, 231, 104, 226, 109, 225, 110, + 160, 47, 163, 44, 166, 41, 165, 42, + 172, 35, 175, 32, 170, 37, 169, 38, + 184, 55, 187, 52, 190, 49, 189, 50, + 180, 59, 183, 56, 178, 61, 177, 62, + 144, 31, 147, 28, 150, 25, 149, 26, + 156, 19, 159, 16, 154, 21, 153, 22, + 136, 7, 139, 4, 142, 1, 141, 2, + 132, 11, 135, 8, 130, 13, 129, 14 }, + { 0, 144, 61, 173, 122, 234, 71, 215, + 244, 100, 201, 89, 142, 30, 179, 35, + 245, 101, 200, 88, 143, 31, 178, 34, + 1, 145, 60, 172, 123, 235, 70, 214, + 247, 103, 202, 90, 141, 29, 176, 32, + 3, 147, 62, 174, 121, 233, 68, 212, + 2, 146, 63, 175, 120, 232, 69, 213, + 246, 102, 203, 91, 140, 28, 177, 33, + 243, 99, 206, 94, 137, 25, 180, 36, + 7, 151, 58, 170, 125, 237, 64, 208, + 6, 150, 59, 171, 124, 236, 65, 209, + 242, 98, 207, 95, 136, 24, 181, 37, + 4, 148, 57, 169, 126, 238, 67, 211, + 240, 96, 205, 93, 138, 26, 183, 39, + 241, 97, 204, 92, 139, 27, 182, 38, + 5, 149, 56, 168, 127, 239, 66, 210, + 251, 107, 198, 86, 129, 17, 188, 44, + 15, 159, 50, 162, 117, 229, 72, 216, + 14, 158, 51, 163, 116, 228, 73, 217, + 250, 106, 199, 87, 128, 16, 189, 45, + 12, 156, 49, 161, 118, 230, 75, 219, + 248, 104, 197, 85, 130, 18, 191, 47, + 249, 105, 196, 84, 131, 19, 190, 46, + 13, 157, 48, 160, 119, 231, 74, 218, + 8, 152, 53, 165, 114, 226, 79, 223, + 252, 108, 193, 81, 134, 22, 187, 43, + 253, 109, 192, 80, 135, 23, 186, 42, + 9, 153, 52, 164, 115, 227, 78, 222, + 255, 111, 194, 82, 133, 21, 184, 40, + 11, 155, 54, 166, 113, 225, 76, 220, + 10, 154, 55, 167, 112, 224, 77, 221, + 254, 110, 195, 83, 132, 20, 185, 41 }, + { 0, 145, 63, 174, 126, 239, 65, 208, + 252, 109, 195, 82, 130, 19, 189, 44, + 229, 116, 218, 75, 155, 10, 164, 53, + 25, 136, 38, 183, 103, 246, 88, 201, + 215, 70, 232, 121, 169, 56, 150, 7, + 43, 186, 20, 133, 85, 196, 106, 251, + 50, 163, 13, 156, 76, 221, 115, 226, + 206, 95, 241, 96, 176, 33, 143, 30, + 179, 34, 140, 29, 205, 92, 242, 99, + 79, 222, 112, 225, 49, 160, 14, 159, + 86, 199, 105, 248, 40, 185, 23, 134, + 170, 59, 149, 4, 212, 69, 235, 122, + 100, 245, 91, 202, 26, 139, 37, 180, + 152, 9, 167, 54, 230, 119, 217, 72, + 129, 16, 190, 47, 255, 110, 192, 81, + 125, 236, 66, 211, 3, 146, 60, 173, + 123, 234, 68, 213, 5, 148, 58, 171, + 135, 22, 184, 41, 249, 104, 198, 87, + 158, 15, 161, 48, 224, 113, 223, 78, + 98, 243, 93, 204, 28, 141, 35, 178, + 172, 61, 147, 2, 210, 67, 237, 124, + 80, 193, 111, 254, 46, 191, 17, 128, + 73, 216, 118, 231, 55, 166, 8, 153, + 181, 36, 138, 27, 203, 90, 244, 101, + 200, 89, 247, 102, 182, 39, 137, 24, + 52, 165, 11, 154, 74, 219, 117, 228, + 45, 188, 18, 131, 83, 194, 108, 253, + 209, 64, 238, 127, 175, 62, 144, 1, + 31, 142, 32, 177, 97, 240, 94, 207, + 227, 114, 220, 77, 157, 12, 162, 51, + 250, 107, 197, 84, 132, 21, 187, 42, + 6, 151, 57, 168, 120, 233, 71, 214 }, + { 0, 146, 57, 171, 114, 224, 75, 217, + 228, 118, 221, 79, 150, 4, 175, 61, + 213, 71, 236, 126, 167, 53, 158, 12, + 49, 163, 8, 154, 67, 209, 122, 232, + 183, 37, 142, 28, 197, 87, 252, 110, + 83, 193, 106, 248, 33, 179, 24, 138, + 98, 240, 91, 201, 16, 130, 41, 187, + 134, 20, 191, 45, 244, 102, 205, 95, + 115, 225, 74, 216, 1, 147, 56, 170, + 151, 5, 174, 60, 229, 119, 220, 78, + 166, 52, 159, 13, 212, 70, 237, 127, + 66, 208, 123, 233, 48, 162, 9, 155, + 196, 86, 253, 111, 182, 36, 143, 29, + 32, 178, 25, 139, 82, 192, 107, 249, + 17, 131, 40, 186, 99, 241, 90, 200, + 245, 103, 204, 94, 135, 21, 190, 44, + 230, 116, 223, 77, 148, 6, 173, 63, + 2, 144, 59, 169, 112, 226, 73, 219, + 51, 161, 10, 152, 65, 211, 120, 234, + 215, 69, 238, 124, 165, 55, 156, 14, + 81, 195, 104, 250, 35, 177, 26, 136, + 181, 39, 140, 30, 199, 85, 254, 108, + 132, 22, 189, 47, 246, 100, 207, 93, + 96, 242, 89, 203, 18, 128, 43, 185, + 149, 7, 172, 62, 231, 117, 222, 76, + 113, 227, 72, 218, 3, 145, 58, 168, + 64, 210, 121, 235, 50, 160, 11, 153, + 164, 54, 157, 15, 214, 68, 239, 125, + 34, 176, 27, 137, 80, 194, 105, 251, + 198, 84, 255, 109, 180, 38, 141, 31, + 247, 101, 206, 92, 133, 23, 188, 46, + 19, 129, 42, 184, 97, 243, 88, 202 }, + { 0, 147, 59, 168, 118, 229, 77, 222, + 236, 127, 215, 68, 154, 9, 161, 50, + 197, 86, 254, 109, 179, 32, 136, 27, + 41, 186, 18, 129, 95, 204, 100, 247, + 151, 4, 172, 63, 225, 114, 218, 73, + 123, 232, 64, 211, 13, 158, 54, 165, + 82, 193, 105, 250, 36, 183, 31, 140, + 190, 45, 133, 22, 200, 91, 243, 96, + 51, 160, 8, 155, 69, 214, 126, 237, + 223, 76, 228, 119, 169, 58, 146, 1, + 246, 101, 205, 94, 128, 19, 187, 40, + 26, 137, 33, 178, 108, 255, 87, 196, + 164, 55, 159, 12, 210, 65, 233, 122, + 72, 219, 115, 224, 62, 173, 5, 150, + 97, 242, 90, 201, 23, 132, 44, 191, + 141, 30, 182, 37, 251, 104, 192, 83, + 102, 245, 93, 206, 16, 131, 43, 184, + 138, 25, 177, 34, 252, 111, 199, 84, + 163, 48, 152, 11, 213, 70, 238, 125, + 79, 220, 116, 231, 57, 170, 2, 145, + 241, 98, 202, 89, 135, 20, 188, 47, + 29, 142, 38, 181, 107, 248, 80, 195, + 52, 167, 15, 156, 66, 209, 121, 234, + 216, 75, 227, 112, 174, 61, 149, 6, + 85, 198, 110, 253, 35, 176, 24, 139, + 185, 42, 130, 17, 207, 92, 244, 103, + 144, 3, 171, 56, 230, 117, 221, 78, + 124, 239, 71, 212, 10, 153, 49, 162, + 194, 81, 249, 106, 180, 39, 143, 28, + 46, 189, 21, 134, 88, 203, 99, 240, + 7, 148, 60, 175, 113, 226, 74, 217, + 235, 120, 208, 67, 157, 14, 166, 53 }, + { 0, 148, 53, 161, 106, 254, 95, 203, + 212, 64, 225, 117, 190, 42, 139, 31, + 181, 33, 128, 20, 223, 75, 234, 126, + 97, 245, 84, 192, 11, 159, 62, 170, + 119, 227, 66, 214, 29, 137, 40, 188, + 163, 55, 150, 2, 201, 93, 252, 104, + 194, 86, 247, 99, 168, 60, 157, 9, + 22, 130, 35, 183, 124, 232, 73, 221, + 238, 122, 219, 79, 132, 16, 177, 37, + 58, 174, 15, 155, 80, 196, 101, 241, + 91, 207, 110, 250, 49, 165, 4, 144, + 143, 27, 186, 46, 229, 113, 208, 68, + 153, 13, 172, 56, 243, 103, 198, 82, + 77, 217, 120, 236, 39, 179, 18, 134, + 44, 184, 25, 141, 70, 210, 115, 231, + 248, 108, 205, 89, 146, 6, 167, 51, + 193, 85, 244, 96, 171, 63, 158, 10, + 21, 129, 32, 180, 127, 235, 74, 222, + 116, 224, 65, 213, 30, 138, 43, 191, + 160, 52, 149, 1, 202, 94, 255, 107, + 182, 34, 131, 23, 220, 72, 233, 125, + 98, 246, 87, 195, 8, 156, 61, 169, + 3, 151, 54, 162, 105, 253, 92, 200, + 215, 67, 226, 118, 189, 41, 136, 28, + 47, 187, 26, 142, 69, 209, 112, 228, + 251, 111, 206, 90, 145, 5, 164, 48, + 154, 14, 175, 59, 240, 100, 197, 81, + 78, 218, 123, 239, 36, 176, 17, 133, + 88, 204, 109, 249, 50, 166, 7, 147, + 140, 24, 185, 45, 230, 114, 211, 71, + 237, 121, 216, 76, 135, 19, 178, 38, + 57, 173, 12, 152, 83, 199, 102, 242 }, + { 0, 149, 55, 162, 110, 251, 89, 204, + 220, 73, 235, 126, 178, 39, 133, 16, + 165, 48, 146, 7, 203, 94, 252, 105, + 121, 236, 78, 219, 23, 130, 32, 181, + 87, 194, 96, 245, 57, 172, 14, 155, + 139, 30, 188, 41, 229, 112, 210, 71, + 242, 103, 197, 80, 156, 9, 171, 62, + 46, 187, 25, 140, 64, 213, 119, 226, + 174, 59, 153, 12, 192, 85, 247, 98, + 114, 231, 69, 208, 28, 137, 43, 190, + 11, 158, 60, 169, 101, 240, 82, 199, + 215, 66, 224, 117, 185, 44, 142, 27, + 249, 108, 206, 91, 151, 2, 160, 53, + 37, 176, 18, 135, 75, 222, 124, 233, + 92, 201, 107, 254, 50, 167, 5, 144, + 128, 21, 183, 34, 238, 123, 217, 76, + 65, 212, 118, 227, 47, 186, 24, 141, + 157, 8, 170, 63, 243, 102, 196, 81, + 228, 113, 211, 70, 138, 31, 189, 40, + 56, 173, 15, 154, 86, 195, 97, 244, + 22, 131, 33, 180, 120, 237, 79, 218, + 202, 95, 253, 104, 164, 49, 147, 6, + 179, 38, 132, 17, 221, 72, 234, 127, + 111, 250, 88, 205, 1, 148, 54, 163, + 239, 122, 216, 77, 129, 20, 182, 35, + 51, 166, 4, 145, 93, 200, 106, 255, + 74, 223, 125, 232, 36, 177, 19, 134, + 150, 3, 161, 52, 248, 109, 207, 90, + 184, 45, 143, 26, 214, 67, 225, 116, + 100, 241, 83, 198, 10, 159, 61, 168, + 29, 136, 42, 191, 115, 230, 68, 209, + 193, 84, 246, 99, 175, 58, 152, 13 }, + { 0, 150, 49, 167, 98, 244, 83, 197, + 196, 82, 245, 99, 166, 48, 151, 1, + 149, 3, 164, 50, 247, 97, 198, 80, + 81, 199, 96, 246, 51, 165, 2, 148, + 55, 161, 6, 144, 85, 195, 100, 242, + 243, 101, 194, 84, 145, 7, 160, 54, + 162, 52, 147, 5, 192, 86, 241, 103, + 102, 240, 87, 193, 4, 146, 53, 163, + 110, 248, 95, 201, 12, 154, 61, 171, + 170, 60, 155, 13, 200, 94, 249, 111, + 251, 109, 202, 92, 153, 15, 168, 62, + 63, 169, 14, 152, 93, 203, 108, 250, + 89, 207, 104, 254, 59, 173, 10, 156, + 157, 11, 172, 58, 255, 105, 206, 88, + 204, 90, 253, 107, 174, 56, 159, 9, + 8, 158, 57, 175, 106, 252, 91, 205, + 220, 74, 237, 123, 190, 40, 143, 25, + 24, 142, 41, 191, 122, 236, 75, 221, + 73, 223, 120, 238, 43, 189, 26, 140, + 141, 27, 188, 42, 239, 121, 222, 72, + 235, 125, 218, 76, 137, 31, 184, 46, + 47, 185, 30, 136, 77, 219, 124, 234, + 126, 232, 79, 217, 28, 138, 45, 187, + 186, 44, 139, 29, 216, 78, 233, 127, + 178, 36, 131, 21, 208, 70, 225, 119, + 118, 224, 71, 209, 20, 130, 37, 179, + 39, 177, 22, 128, 69, 211, 116, 226, + 227, 117, 210, 68, 129, 23, 176, 38, + 133, 19, 180, 34, 231, 113, 214, 64, + 65, 215, 112, 230, 35, 181, 18, 132, + 16, 134, 33, 183, 114, 228, 67, 213, + 212, 66, 229, 115, 182, 32, 135, 17 }, + { 0, 151, 51, 164, 102, 241, 85, 194, + 204, 91, 255, 104, 170, 61, 153, 14, + 133, 18, 182, 33, 227, 116, 208, 71, + 73, 222, 122, 237, 47, 184, 28, 139, + 23, 128, 36, 179, 113, 230, 66, 213, + 219, 76, 232, 127, 189, 42, 142, 25, + 146, 5, 161, 54, 244, 99, 199, 80, + 94, 201, 109, 250, 56, 175, 11, 156, + 46, 185, 29, 138, 72, 223, 123, 236, + 226, 117, 209, 70, 132, 19, 183, 32, + 171, 60, 152, 15, 205, 90, 254, 105, + 103, 240, 84, 195, 1, 150, 50, 165, + 57, 174, 10, 157, 95, 200, 108, 251, + 245, 98, 198, 81, 147, 4, 160, 55, + 188, 43, 143, 24, 218, 77, 233, 126, + 112, 231, 67, 212, 22, 129, 37, 178, + 92, 203, 111, 248, 58, 173, 9, 158, + 144, 7, 163, 52, 246, 97, 197, 82, + 217, 78, 234, 125, 191, 40, 140, 27, + 21, 130, 38, 177, 115, 228, 64, 215, + 75, 220, 120, 239, 45, 186, 30, 137, + 135, 16, 180, 35, 225, 118, 210, 69, + 206, 89, 253, 106, 168, 63, 155, 12, + 2, 149, 49, 166, 100, 243, 87, 192, + 114, 229, 65, 214, 20, 131, 39, 176, + 190, 41, 141, 26, 216, 79, 235, 124, + 247, 96, 196, 83, 145, 6, 162, 53, + 59, 172, 8, 159, 93, 202, 110, 249, + 101, 242, 86, 193, 3, 148, 48, 167, + 169, 62, 154, 13, 207, 88, 252, 107, + 224, 119, 211, 68, 134, 17, 181, 34, + 44, 187, 31, 136, 74, 221, 121, 238 }, + { 0, 152, 45, 181, 90, 194, 119, 239, + 180, 44, 153, 1, 238, 118, 195, 91, + 117, 237, 88, 192, 47, 183, 2, 154, + 193, 89, 236, 116, 155, 3, 182, 46, + 234, 114, 199, 95, 176, 40, 157, 5, + 94, 198, 115, 235, 4, 156, 41, 177, + 159, 7, 178, 42, 197, 93, 232, 112, + 43, 179, 6, 158, 113, 233, 92, 196, + 201, 81, 228, 124, 147, 11, 190, 38, + 125, 229, 80, 200, 39, 191, 10, 146, + 188, 36, 145, 9, 230, 126, 203, 83, + 8, 144, 37, 189, 82, 202, 127, 231, + 35, 187, 14, 150, 121, 225, 84, 204, + 151, 15, 186, 34, 205, 85, 224, 120, + 86, 206, 123, 227, 12, 148, 33, 185, + 226, 122, 207, 87, 184, 32, 149, 13, + 143, 23, 162, 58, 213, 77, 248, 96, + 59, 163, 22, 142, 97, 249, 76, 212, + 250, 98, 215, 79, 160, 56, 141, 21, + 78, 214, 99, 251, 20, 140, 57, 161, + 101, 253, 72, 208, 63, 167, 18, 138, + 209, 73, 252, 100, 139, 19, 166, 62, + 16, 136, 61, 165, 74, 210, 103, 255, + 164, 60, 137, 17, 254, 102, 211, 75, + 70, 222, 107, 243, 28, 132, 49, 169, + 242, 106, 223, 71, 168, 48, 133, 29, + 51, 171, 30, 134, 105, 241, 68, 220, + 135, 31, 170, 50, 221, 69, 240, 104, + 172, 52, 129, 25, 246, 110, 219, 67, + 24, 128, 53, 173, 66, 218, 111, 247, + 217, 65, 244, 108, 131, 27, 174, 54, + 109, 245, 64, 216, 55, 175, 26, 130 }, + { 0, 153, 47, 182, 94, 199, 113, 232, + 188, 37, 147, 10, 226, 123, 205, 84, + 101, 252, 74, 211, 59, 162, 20, 141, + 217, 64, 246, 111, 135, 30, 168, 49, + 202, 83, 229, 124, 148, 13, 187, 34, + 118, 239, 89, 192, 40, 177, 7, 158, + 175, 54, 128, 25, 241, 104, 222, 71, + 19, 138, 60, 165, 77, 212, 98, 251, + 137, 16, 166, 63, 215, 78, 248, 97, + 53, 172, 26, 131, 107, 242, 68, 221, + 236, 117, 195, 90, 178, 43, 157, 4, + 80, 201, 127, 230, 14, 151, 33, 184, + 67, 218, 108, 245, 29, 132, 50, 171, + 255, 102, 208, 73, 161, 56, 142, 23, + 38, 191, 9, 144, 120, 225, 87, 206, + 154, 3, 181, 44, 196, 93, 235, 114, + 15, 150, 32, 185, 81, 200, 126, 231, + 179, 42, 156, 5, 237, 116, 194, 91, + 106, 243, 69, 220, 52, 173, 27, 130, + 214, 79, 249, 96, 136, 17, 167, 62, + 197, 92, 234, 115, 155, 2, 180, 45, + 121, 224, 86, 207, 39, 190, 8, 145, + 160, 57, 143, 22, 254, 103, 209, 72, + 28, 133, 51, 170, 66, 219, 109, 244, + 134, 31, 169, 48, 216, 65, 247, 110, + 58, 163, 21, 140, 100, 253, 75, 210, + 227, 122, 204, 85, 189, 36, 146, 11, + 95, 198, 112, 233, 1, 152, 46, 183, + 76, 213, 99, 250, 18, 139, 61, 164, + 240, 105, 223, 70, 174, 55, 129, 24, + 41, 176, 6, 159, 119, 238, 88, 193, + 149, 12, 186, 35, 203, 82, 228, 125 }, + { 0, 154, 41, 179, 82, 200, 123, 225, + 164, 62, 141, 23, 246, 108, 223, 69, + 85, 207, 124, 230, 7, 157, 46, 180, + 241, 107, 216, 66, 163, 57, 138, 16, + 170, 48, 131, 25, 248, 98, 209, 75, + 14, 148, 39, 189, 92, 198, 117, 239, + 255, 101, 214, 76, 173, 55, 132, 30, + 91, 193, 114, 232, 9, 147, 32, 186, + 73, 211, 96, 250, 27, 129, 50, 168, + 237, 119, 196, 94, 191, 37, 150, 12, + 28, 134, 53, 175, 78, 212, 103, 253, + 184, 34, 145, 11, 234, 112, 195, 89, + 227, 121, 202, 80, 177, 43, 152, 2, + 71, 221, 110, 244, 21, 143, 60, 166, + 182, 44, 159, 5, 228, 126, 205, 87, + 18, 136, 59, 161, 64, 218, 105, 243, + 146, 8, 187, 33, 192, 90, 233, 115, + 54, 172, 31, 133, 100, 254, 77, 215, + 199, 93, 238, 116, 149, 15, 188, 38, + 99, 249, 74, 208, 49, 171, 24, 130, + 56, 162, 17, 139, 106, 240, 67, 217, + 156, 6, 181, 47, 206, 84, 231, 125, + 109, 247, 68, 222, 63, 165, 22, 140, + 201, 83, 224, 122, 155, 1, 178, 40, + 219, 65, 242, 104, 137, 19, 160, 58, + 127, 229, 86, 204, 45, 183, 4, 158, + 142, 20, 167, 61, 220, 70, 245, 111, + 42, 176, 3, 153, 120, 226, 81, 203, + 113, 235, 88, 194, 35, 185, 10, 144, + 213, 79, 252, 102, 135, 29, 174, 52, + 36, 190, 13, 151, 118, 236, 95, 197, + 128, 26, 169, 51, 210, 72, 251, 97 }, + { 0, 155, 43, 176, 86, 205, 125, 230, + 172, 55, 135, 28, 250, 97, 209, 74, + 69, 222, 110, 245, 19, 136, 56, 163, + 233, 114, 194, 89, 191, 36, 148, 15, + 138, 17, 161, 58, 220, 71, 247, 108, + 38, 189, 13, 150, 112, 235, 91, 192, + 207, 84, 228, 127, 153, 2, 178, 41, + 99, 248, 72, 211, 53, 174, 30, 133, + 9, 146, 34, 185, 95, 196, 116, 239, + 165, 62, 142, 21, 243, 104, 216, 67, + 76, 215, 103, 252, 26, 129, 49, 170, + 224, 123, 203, 80, 182, 45, 157, 6, + 131, 24, 168, 51, 213, 78, 254, 101, + 47, 180, 4, 159, 121, 226, 82, 201, + 198, 93, 237, 118, 144, 11, 187, 32, + 106, 241, 65, 218, 60, 167, 23, 140, + 18, 137, 57, 162, 68, 223, 111, 244, + 190, 37, 149, 14, 232, 115, 195, 88, + 87, 204, 124, 231, 1, 154, 42, 177, + 251, 96, 208, 75, 173, 54, 134, 29, + 152, 3, 179, 40, 206, 85, 229, 126, + 52, 175, 31, 132, 98, 249, 73, 210, + 221, 70, 246, 109, 139, 16, 160, 59, + 113, 234, 90, 193, 39, 188, 12, 151, + 27, 128, 48, 171, 77, 214, 102, 253, + 183, 44, 156, 7, 225, 122, 202, 81, + 94, 197, 117, 238, 8, 147, 35, 184, + 242, 105, 217, 66, 164, 63, 143, 20, + 145, 10, 186, 33, 199, 92, 236, 119, + 61, 166, 22, 141, 107, 240, 64, 219, + 212, 79, 255, 100, 130, 25, 169, 50, + 120, 227, 83, 200, 46, 181, 5, 158 }, + { 0, 156, 37, 185, 74, 214, 111, 243, + 148, 8, 177, 45, 222, 66, 251, 103, + 53, 169, 16, 140, 127, 227, 90, 198, + 161, 61, 132, 24, 235, 119, 206, 82, + 106, 246, 79, 211, 32, 188, 5, 153, + 254, 98, 219, 71, 180, 40, 145, 13, + 95, 195, 122, 230, 21, 137, 48, 172, + 203, 87, 238, 114, 129, 29, 164, 56, + 212, 72, 241, 109, 158, 2, 187, 39, + 64, 220, 101, 249, 10, 150, 47, 179, + 225, 125, 196, 88, 171, 55, 142, 18, + 117, 233, 80, 204, 63, 163, 26, 134, + 190, 34, 155, 7, 244, 104, 209, 77, + 42, 182, 15, 147, 96, 252, 69, 217, + 139, 23, 174, 50, 193, 93, 228, 120, + 31, 131, 58, 166, 85, 201, 112, 236, + 181, 41, 144, 12, 255, 99, 218, 70, + 33, 189, 4, 152, 107, 247, 78, 210, + 128, 28, 165, 57, 202, 86, 239, 115, + 20, 136, 49, 173, 94, 194, 123, 231, + 223, 67, 250, 102, 149, 9, 176, 44, + 75, 215, 110, 242, 1, 157, 36, 184, + 234, 118, 207, 83, 160, 60, 133, 25, + 126, 226, 91, 199, 52, 168, 17, 141, + 97, 253, 68, 216, 43, 183, 14, 146, + 245, 105, 208, 76, 191, 35, 154, 6, + 84, 200, 113, 237, 30, 130, 59, 167, + 192, 92, 229, 121, 138, 22, 175, 51, + 11, 151, 46, 178, 65, 221, 100, 248, + 159, 3, 186, 38, 213, 73, 240, 108, + 62, 162, 27, 135, 116, 232, 81, 205, + 170, 54, 143, 19, 224, 124, 197, 89 }, + { 0, 157, 39, 186, 78, 211, 105, 244, + 156, 1, 187, 38, 210, 79, 245, 104, + 37, 184, 2, 159, 107, 246, 76, 209, + 185, 36, 158, 3, 247, 106, 208, 77, + 74, 215, 109, 240, 4, 153, 35, 190, + 214, 75, 241, 108, 152, 5, 191, 34, + 111, 242, 72, 213, 33, 188, 6, 155, + 243, 110, 212, 73, 189, 32, 154, 7, + 148, 9, 179, 46, 218, 71, 253, 96, + 8, 149, 47, 178, 70, 219, 97, 252, + 177, 44, 150, 11, 255, 98, 216, 69, + 45, 176, 10, 151, 99, 254, 68, 217, + 222, 67, 249, 100, 144, 13, 183, 42, + 66, 223, 101, 248, 12, 145, 43, 182, + 251, 102, 220, 65, 181, 40, 146, 15, + 103, 250, 64, 221, 41, 180, 14, 147, + 53, 168, 18, 143, 123, 230, 92, 193, + 169, 52, 142, 19, 231, 122, 192, 93, + 16, 141, 55, 170, 94, 195, 121, 228, + 140, 17, 171, 54, 194, 95, 229, 120, + 127, 226, 88, 197, 49, 172, 22, 139, + 227, 126, 196, 89, 173, 48, 138, 23, + 90, 199, 125, 224, 20, 137, 51, 174, + 198, 91, 225, 124, 136, 21, 175, 50, + 161, 60, 134, 27, 239, 114, 200, 85, + 61, 160, 26, 135, 115, 238, 84, 201, + 132, 25, 163, 62, 202, 87, 237, 112, + 24, 133, 63, 162, 86, 203, 113, 236, + 235, 118, 204, 81, 165, 56, 130, 31, + 119, 234, 80, 205, 57, 164, 30, 131, + 206, 83, 233, 116, 128, 29, 167, 58, + 82, 207, 117, 232, 28, 129, 59, 166 }, + { 0, 158, 33, 191, 66, 220, 99, 253, + 132, 26, 165, 59, 198, 88, 231, 121, + 21, 139, 52, 170, 87, 201, 118, 232, + 145, 15, 176, 46, 211, 77, 242, 108, + 42, 180, 11, 149, 104, 246, 73, 215, + 174, 48, 143, 17, 236, 114, 205, 83, + 63, 161, 30, 128, 125, 227, 92, 194, + 187, 37, 154, 4, 249, 103, 216, 70, + 84, 202, 117, 235, 22, 136, 55, 169, + 208, 78, 241, 111, 146, 12, 179, 45, + 65, 223, 96, 254, 3, 157, 34, 188, + 197, 91, 228, 122, 135, 25, 166, 56, + 126, 224, 95, 193, 60, 162, 29, 131, + 250, 100, 219, 69, 184, 38, 153, 7, + 107, 245, 74, 212, 41, 183, 8, 150, + 239, 113, 206, 80, 173, 51, 140, 18, + 168, 54, 137, 23, 234, 116, 203, 85, + 44, 178, 13, 147, 110, 240, 79, 209, + 189, 35, 156, 2, 255, 97, 222, 64, + 57, 167, 24, 134, 123, 229, 90, 196, + 130, 28, 163, 61, 192, 94, 225, 127, + 6, 152, 39, 185, 68, 218, 101, 251, + 151, 9, 182, 40, 213, 75, 244, 106, + 19, 141, 50, 172, 81, 207, 112, 238, + 252, 98, 221, 67, 190, 32, 159, 1, + 120, 230, 89, 199, 58, 164, 27, 133, + 233, 119, 200, 86, 171, 53, 138, 20, + 109, 243, 76, 210, 47, 177, 14, 144, + 214, 72, 247, 105, 148, 10, 181, 43, + 82, 204, 115, 237, 16, 142, 49, 175, + 195, 93, 226, 124, 129, 31, 160, 62, + 71, 217, 102, 248, 5, 155, 36, 186 }, + { 0, 159, 35, 188, 70, 217, 101, 250, + 140, 19, 175, 48, 202, 85, 233, 118, + 5, 154, 38, 185, 67, 220, 96, 255, + 137, 22, 170, 53, 207, 80, 236, 115, + 10, 149, 41, 182, 76, 211, 111, 240, + 134, 25, 165, 58, 192, 95, 227, 124, + 15, 144, 44, 179, 73, 214, 106, 245, + 131, 28, 160, 63, 197, 90, 230, 121, + 20, 139, 55, 168, 82, 205, 113, 238, + 152, 7, 187, 36, 222, 65, 253, 98, + 17, 142, 50, 173, 87, 200, 116, 235, + 157, 2, 190, 33, 219, 68, 248, 103, + 30, 129, 61, 162, 88, 199, 123, 228, + 146, 13, 177, 46, 212, 75, 247, 104, + 27, 132, 56, 167, 93, 194, 126, 225, + 151, 8, 180, 43, 209, 78, 242, 109, + 40, 183, 11, 148, 110, 241, 77, 210, + 164, 59, 135, 24, 226, 125, 193, 94, + 45, 178, 14, 145, 107, 244, 72, 215, + 161, 62, 130, 29, 231, 120, 196, 91, + 34, 189, 1, 158, 100, 251, 71, 216, + 174, 49, 141, 18, 232, 119, 203, 84, + 39, 184, 4, 155, 97, 254, 66, 221, + 171, 52, 136, 23, 237, 114, 206, 81, + 60, 163, 31, 128, 122, 229, 89, 198, + 176, 47, 147, 12, 246, 105, 213, 74, + 57, 166, 26, 133, 127, 224, 92, 195, + 181, 42, 150, 9, 243, 108, 208, 79, + 54, 169, 21, 138, 112, 239, 83, 204, + 186, 37, 153, 6, 252, 99, 223, 64, + 51, 172, 16, 143, 117, 234, 86, 201, + 191, 32, 156, 3, 249, 102, 218, 69 }, + { 0, 160, 93, 253, 186, 26, 231, 71, + 105, 201, 52, 148, 211, 115, 142, 46, + 210, 114, 143, 47, 104, 200, 53, 149, + 187, 27, 230, 70, 1, 161, 92, 252, + 185, 25, 228, 68, 3, 163, 94, 254, + 208, 112, 141, 45, 106, 202, 55, 151, + 107, 203, 54, 150, 209, 113, 140, 44, + 2, 162, 95, 255, 184, 24, 229, 69, + 111, 207, 50, 146, 213, 117, 136, 40, + 6, 166, 91, 251, 188, 28, 225, 65, + 189, 29, 224, 64, 7, 167, 90, 250, + 212, 116, 137, 41, 110, 206, 51, 147, + 214, 118, 139, 43, 108, 204, 49, 145, + 191, 31, 226, 66, 5, 165, 88, 248, + 4, 164, 89, 249, 190, 30, 227, 67, + 109, 205, 48, 144, 215, 119, 138, 42, + 222, 126, 131, 35, 100, 196, 57, 153, + 183, 23, 234, 74, 13, 173, 80, 240, + 12, 172, 81, 241, 182, 22, 235, 75, + 101, 197, 56, 152, 223, 127, 130, 34, + 103, 199, 58, 154, 221, 125, 128, 32, + 14, 174, 83, 243, 180, 20, 233, 73, + 181, 21, 232, 72, 15, 175, 82, 242, + 220, 124, 129, 33, 102, 198, 59, 155, + 177, 17, 236, 76, 11, 171, 86, 246, + 216, 120, 133, 37, 98, 194, 63, 159, + 99, 195, 62, 158, 217, 121, 132, 36, + 10, 170, 87, 247, 176, 16, 237, 77, + 8, 168, 85, 245, 178, 18, 239, 79, + 97, 193, 60, 156, 219, 123, 134, 38, + 218, 122, 135, 39, 96, 192, 61, 157, + 179, 19, 238, 78, 9, 169, 84, 244 }, + { 0, 161, 95, 254, 190, 31, 225, 64, + 97, 192, 62, 159, 223, 126, 128, 33, + 194, 99, 157, 60, 124, 221, 35, 130, + 163, 2, 252, 93, 29, 188, 66, 227, + 153, 56, 198, 103, 39, 134, 120, 217, + 248, 89, 167, 6, 70, 231, 25, 184, + 91, 250, 4, 165, 229, 68, 186, 27, + 58, 155, 101, 196, 132, 37, 219, 122, + 47, 142, 112, 209, 145, 48, 206, 111, + 78, 239, 17, 176, 240, 81, 175, 14, + 237, 76, 178, 19, 83, 242, 12, 173, + 140, 45, 211, 114, 50, 147, 109, 204, + 182, 23, 233, 72, 8, 169, 87, 246, + 215, 118, 136, 41, 105, 200, 54, 151, + 116, 213, 43, 138, 202, 107, 149, 52, + 21, 180, 74, 235, 171, 10, 244, 85, + 94, 255, 1, 160, 224, 65, 191, 30, + 63, 158, 96, 193, 129, 32, 222, 127, + 156, 61, 195, 98, 34, 131, 125, 220, + 253, 92, 162, 3, 67, 226, 28, 189, + 199, 102, 152, 57, 121, 216, 38, 135, + 166, 7, 249, 88, 24, 185, 71, 230, + 5, 164, 90, 251, 187, 26, 228, 69, + 100, 197, 59, 154, 218, 123, 133, 36, + 113, 208, 46, 143, 207, 110, 144, 49, + 16, 177, 79, 238, 174, 15, 241, 80, + 179, 18, 236, 77, 13, 172, 82, 243, + 210, 115, 141, 44, 108, 205, 51, 146, + 232, 73, 183, 22, 86, 247, 9, 168, + 137, 40, 214, 119, 55, 150, 104, 201, + 42, 139, 117, 212, 148, 53, 203, 106, + 75, 234, 20, 181, 245, 84, 170, 11 }, + { 0, 162, 89, 251, 178, 16, 235, 73, + 121, 219, 32, 130, 203, 105, 146, 48, + 242, 80, 171, 9, 64, 226, 25, 187, + 139, 41, 210, 112, 57, 155, 96, 194, + 249, 91, 160, 2, 75, 233, 18, 176, + 128, 34, 217, 123, 50, 144, 107, 201, + 11, 169, 82, 240, 185, 27, 224, 66, + 114, 208, 43, 137, 192, 98, 153, 59, + 239, 77, 182, 20, 93, 255, 4, 166, + 150, 52, 207, 109, 36, 134, 125, 223, + 29, 191, 68, 230, 175, 13, 246, 84, + 100, 198, 61, 159, 214, 116, 143, 45, + 22, 180, 79, 237, 164, 6, 253, 95, + 111, 205, 54, 148, 221, 127, 132, 38, + 228, 70, 189, 31, 86, 244, 15, 173, + 157, 63, 196, 102, 47, 141, 118, 212, + 195, 97, 154, 56, 113, 211, 40, 138, + 186, 24, 227, 65, 8, 170, 81, 243, + 49, 147, 104, 202, 131, 33, 218, 120, + 72, 234, 17, 179, 250, 88, 163, 1, + 58, 152, 99, 193, 136, 42, 209, 115, + 67, 225, 26, 184, 241, 83, 168, 10, + 200, 106, 145, 51, 122, 216, 35, 129, + 177, 19, 232, 74, 3, 161, 90, 248, + 44, 142, 117, 215, 158, 60, 199, 101, + 85, 247, 12, 174, 231, 69, 190, 28, + 222, 124, 135, 37, 108, 206, 53, 151, + 167, 5, 254, 92, 21, 183, 76, 238, + 213, 119, 140, 46, 103, 197, 62, 156, + 172, 14, 245, 87, 30, 188, 71, 229, + 39, 133, 126, 220, 149, 55, 204, 110, + 94, 252, 7, 165, 236, 78, 181, 23 }, + { 0, 163, 91, 248, 182, 21, 237, 78, + 113, 210, 42, 137, 199, 100, 156, 63, + 226, 65, 185, 26, 84, 247, 15, 172, + 147, 48, 200, 107, 37, 134, 126, 221, + 217, 122, 130, 33, 111, 204, 52, 151, + 168, 11, 243, 80, 30, 189, 69, 230, + 59, 152, 96, 195, 141, 46, 214, 117, + 74, 233, 17, 178, 252, 95, 167, 4, + 175, 12, 244, 87, 25, 186, 66, 225, + 222, 125, 133, 38, 104, 203, 51, 144, + 77, 238, 22, 181, 251, 88, 160, 3, + 60, 159, 103, 196, 138, 41, 209, 114, + 118, 213, 45, 142, 192, 99, 155, 56, + 7, 164, 92, 255, 177, 18, 234, 73, + 148, 55, 207, 108, 34, 129, 121, 218, + 229, 70, 190, 29, 83, 240, 8, 171, + 67, 224, 24, 187, 245, 86, 174, 13, + 50, 145, 105, 202, 132, 39, 223, 124, + 161, 2, 250, 89, 23, 180, 76, 239, + 208, 115, 139, 40, 102, 197, 61, 158, + 154, 57, 193, 98, 44, 143, 119, 212, + 235, 72, 176, 19, 93, 254, 6, 165, + 120, 219, 35, 128, 206, 109, 149, 54, + 9, 170, 82, 241, 191, 28, 228, 71, + 236, 79, 183, 20, 90, 249, 1, 162, + 157, 62, 198, 101, 43, 136, 112, 211, + 14, 173, 85, 246, 184, 27, 227, 64, + 127, 220, 36, 135, 201, 106, 146, 49, + 53, 150, 110, 205, 131, 32, 216, 123, + 68, 231, 31, 188, 242, 81, 169, 10, + 215, 116, 140, 47, 97, 194, 58, 153, + 166, 5, 253, 94, 16, 179, 75, 232 }, + { 0, 164, 85, 241, 170, 14, 255, 91, + 73, 237, 28, 184, 227, 71, 182, 18, + 146, 54, 199, 99, 56, 156, 109, 201, + 219, 127, 142, 42, 113, 213, 36, 128, + 57, 157, 108, 200, 147, 55, 198, 98, + 112, 212, 37, 129, 218, 126, 143, 43, + 171, 15, 254, 90, 1, 165, 84, 240, + 226, 70, 183, 19, 72, 236, 29, 185, + 114, 214, 39, 131, 216, 124, 141, 41, + 59, 159, 110, 202, 145, 53, 196, 96, + 224, 68, 181, 17, 74, 238, 31, 187, + 169, 13, 252, 88, 3, 167, 86, 242, + 75, 239, 30, 186, 225, 69, 180, 16, + 2, 166, 87, 243, 168, 12, 253, 89, + 217, 125, 140, 40, 115, 215, 38, 130, + 144, 52, 197, 97, 58, 158, 111, 203, + 228, 64, 177, 21, 78, 234, 27, 191, + 173, 9, 248, 92, 7, 163, 82, 246, + 118, 210, 35, 135, 220, 120, 137, 45, + 63, 155, 106, 206, 149, 49, 192, 100, + 221, 121, 136, 44, 119, 211, 34, 134, + 148, 48, 193, 101, 62, 154, 107, 207, + 79, 235, 26, 190, 229, 65, 176, 20, + 6, 162, 83, 247, 172, 8, 249, 93, + 150, 50, 195, 103, 60, 152, 105, 205, + 223, 123, 138, 46, 117, 209, 32, 132, + 4, 160, 81, 245, 174, 10, 251, 95, + 77, 233, 24, 188, 231, 67, 178, 22, + 175, 11, 250, 94, 5, 161, 80, 244, + 230, 66, 179, 23, 76, 232, 25, 189, + 61, 153, 104, 204, 151, 51, 194, 102, + 116, 208, 33, 133, 222, 122, 139, 47 }, + { 0, 165, 87, 242, 174, 11, 249, 92, + 65, 228, 22, 179, 239, 74, 184, 29, + 130, 39, 213, 112, 44, 137, 123, 222, + 195, 102, 148, 49, 109, 200, 58, 159, + 25, 188, 78, 235, 183, 18, 224, 69, + 88, 253, 15, 170, 246, 83, 161, 4, + 155, 62, 204, 105, 53, 144, 98, 199, + 218, 127, 141, 40, 116, 209, 35, 134, + 50, 151, 101, 192, 156, 57, 203, 110, + 115, 214, 36, 129, 221, 120, 138, 47, + 176, 21, 231, 66, 30, 187, 73, 236, + 241, 84, 166, 3, 95, 250, 8, 173, + 43, 142, 124, 217, 133, 32, 210, 119, + 106, 207, 61, 152, 196, 97, 147, 54, + 169, 12, 254, 91, 7, 162, 80, 245, + 232, 77, 191, 26, 70, 227, 17, 180, + 100, 193, 51, 150, 202, 111, 157, 56, + 37, 128, 114, 215, 139, 46, 220, 121, + 230, 67, 177, 20, 72, 237, 31, 186, + 167, 2, 240, 85, 9, 172, 94, 251, + 125, 216, 42, 143, 211, 118, 132, 33, + 60, 153, 107, 206, 146, 55, 197, 96, + 255, 90, 168, 13, 81, 244, 6, 163, + 190, 27, 233, 76, 16, 181, 71, 226, + 86, 243, 1, 164, 248, 93, 175, 10, + 23, 178, 64, 229, 185, 28, 238, 75, + 212, 113, 131, 38, 122, 223, 45, 136, + 149, 48, 194, 103, 59, 158, 108, 201, + 79, 234, 24, 189, 225, 68, 182, 19, + 14, 171, 89, 252, 160, 5, 247, 82, + 205, 104, 154, 63, 99, 198, 52, 145, + 140, 41, 219, 126, 34, 135, 117, 208 }, + { 0, 166, 81, 247, 162, 4, 243, 85, + 89, 255, 8, 174, 251, 93, 170, 12, + 178, 20, 227, 69, 16, 182, 65, 231, + 235, 77, 186, 28, 73, 239, 24, 190, + 121, 223, 40, 142, 219, 125, 138, 44, + 32, 134, 113, 215, 130, 36, 211, 117, + 203, 109, 154, 60, 105, 207, 56, 158, + 146, 52, 195, 101, 48, 150, 97, 199, + 242, 84, 163, 5, 80, 246, 1, 167, + 171, 13, 250, 92, 9, 175, 88, 254, + 64, 230, 17, 183, 226, 68, 179, 21, + 25, 191, 72, 238, 187, 29, 234, 76, + 139, 45, 218, 124, 41, 143, 120, 222, + 210, 116, 131, 37, 112, 214, 33, 135, + 57, 159, 104, 206, 155, 61, 202, 108, + 96, 198, 49, 151, 194, 100, 147, 53, + 249, 95, 168, 14, 91, 253, 10, 172, + 160, 6, 241, 87, 2, 164, 83, 245, + 75, 237, 26, 188, 233, 79, 184, 30, + 18, 180, 67, 229, 176, 22, 225, 71, + 128, 38, 209, 119, 34, 132, 115, 213, + 217, 127, 136, 46, 123, 221, 42, 140, + 50, 148, 99, 197, 144, 54, 193, 103, + 107, 205, 58, 156, 201, 111, 152, 62, + 11, 173, 90, 252, 169, 15, 248, 94, + 82, 244, 3, 165, 240, 86, 161, 7, + 185, 31, 232, 78, 27, 189, 74, 236, + 224, 70, 177, 23, 66, 228, 19, 181, + 114, 212, 35, 133, 208, 118, 129, 39, + 43, 141, 122, 220, 137, 47, 216, 126, + 192, 102, 145, 55, 98, 196, 51, 149, + 153, 63, 200, 110, 59, 157, 106, 204 }, + { 0, 167, 83, 244, 166, 1, 245, 82, + 81, 246, 2, 165, 247, 80, 164, 3, + 162, 5, 241, 86, 4, 163, 87, 240, + 243, 84, 160, 7, 85, 242, 6, 161, + 89, 254, 10, 173, 255, 88, 172, 11, + 8, 175, 91, 252, 174, 9, 253, 90, + 251, 92, 168, 15, 93, 250, 14, 169, + 170, 13, 249, 94, 12, 171, 95, 248, + 178, 21, 225, 70, 20, 179, 71, 224, + 227, 68, 176, 23, 69, 226, 22, 177, + 16, 183, 67, 228, 182, 17, 229, 66, + 65, 230, 18, 181, 231, 64, 180, 19, + 235, 76, 184, 31, 77, 234, 30, 185, + 186, 29, 233, 78, 28, 187, 79, 232, + 73, 238, 26, 189, 239, 72, 188, 27, + 24, 191, 75, 236, 190, 25, 237, 74, + 121, 222, 42, 141, 223, 120, 140, 43, + 40, 143, 123, 220, 142, 41, 221, 122, + 219, 124, 136, 47, 125, 218, 46, 137, + 138, 45, 217, 126, 44, 139, 127, 216, + 32, 135, 115, 212, 134, 33, 213, 114, + 113, 214, 34, 133, 215, 112, 132, 35, + 130, 37, 209, 118, 36, 131, 119, 208, + 211, 116, 128, 39, 117, 210, 38, 129, + 203, 108, 152, 63, 109, 202, 62, 153, + 154, 61, 201, 110, 60, 155, 111, 200, + 105, 206, 58, 157, 207, 104, 156, 59, + 56, 159, 107, 204, 158, 57, 205, 106, + 146, 53, 193, 102, 52, 147, 103, 192, + 195, 100, 144, 55, 101, 194, 54, 145, + 48, 151, 99, 196, 150, 49, 197, 98, + 97, 198, 50, 149, 199, 96, 148, 51 }, + { 0, 168, 77, 229, 154, 50, 215, 127, + 41, 129, 100, 204, 179, 27, 254, 86, + 82, 250, 31, 183, 200, 96, 133, 45, + 123, 211, 54, 158, 225, 73, 172, 4, + 164, 12, 233, 65, 62, 150, 115, 219, + 141, 37, 192, 104, 23, 191, 90, 242, + 246, 94, 187, 19, 108, 196, 33, 137, + 223, 119, 146, 58, 69, 237, 8, 160, + 85, 253, 24, 176, 207, 103, 130, 42, + 124, 212, 49, 153, 230, 78, 171, 3, + 7, 175, 74, 226, 157, 53, 208, 120, + 46, 134, 99, 203, 180, 28, 249, 81, + 241, 89, 188, 20, 107, 195, 38, 142, + 216, 112, 149, 61, 66, 234, 15, 167, + 163, 11, 238, 70, 57, 145, 116, 220, + 138, 34, 199, 111, 16, 184, 93, 245, + 170, 2, 231, 79, 48, 152, 125, 213, + 131, 43, 206, 102, 25, 177, 84, 252, + 248, 80, 181, 29, 98, 202, 47, 135, + 209, 121, 156, 52, 75, 227, 6, 174, + 14, 166, 67, 235, 148, 60, 217, 113, + 39, 143, 106, 194, 189, 21, 240, 88, + 92, 244, 17, 185, 198, 110, 139, 35, + 117, 221, 56, 144, 239, 71, 162, 10, + 255, 87, 178, 26, 101, 205, 40, 128, + 214, 126, 155, 51, 76, 228, 1, 169, + 173, 5, 224, 72, 55, 159, 122, 210, + 132, 44, 201, 97, 30, 182, 83, 251, + 91, 243, 22, 190, 193, 105, 140, 36, + 114, 218, 63, 151, 232, 64, 165, 13, + 9, 161, 68, 236, 147, 59, 222, 118, + 32, 136, 109, 197, 186, 18, 247, 95 }, + { 0, 169, 79, 230, 158, 55, 209, 120, + 33, 136, 110, 199, 191, 22, 240, 89, + 66, 235, 13, 164, 220, 117, 147, 58, + 99, 202, 44, 133, 253, 84, 178, 27, + 132, 45, 203, 98, 26, 179, 85, 252, + 165, 12, 234, 67, 59, 146, 116, 221, + 198, 111, 137, 32, 88, 241, 23, 190, + 231, 78, 168, 1, 121, 208, 54, 159, + 21, 188, 90, 243, 139, 34, 196, 109, + 52, 157, 123, 210, 170, 3, 229, 76, + 87, 254, 24, 177, 201, 96, 134, 47, + 118, 223, 57, 144, 232, 65, 167, 14, + 145, 56, 222, 119, 15, 166, 64, 233, + 176, 25, 255, 86, 46, 135, 97, 200, + 211, 122, 156, 53, 77, 228, 2, 171, + 242, 91, 189, 20, 108, 197, 35, 138, + 42, 131, 101, 204, 180, 29, 251, 82, + 11, 162, 68, 237, 149, 60, 218, 115, + 104, 193, 39, 142, 246, 95, 185, 16, + 73, 224, 6, 175, 215, 126, 152, 49, + 174, 7, 225, 72, 48, 153, 127, 214, + 143, 38, 192, 105, 17, 184, 94, 247, + 236, 69, 163, 10, 114, 219, 61, 148, + 205, 100, 130, 43, 83, 250, 28, 181, + 63, 150, 112, 217, 161, 8, 238, 71, + 30, 183, 81, 248, 128, 41, 207, 102, + 125, 212, 50, 155, 227, 74, 172, 5, + 92, 245, 19, 186, 194, 107, 141, 36, + 187, 18, 244, 93, 37, 140, 106, 195, + 154, 51, 213, 124, 4, 173, 75, 226, + 249, 80, 182, 31, 103, 206, 40, 129, + 216, 113, 151, 62, 70, 239, 9, 160 }, + { 0, 170, 73, 227, 146, 56, 219, 113, + 57, 147, 112, 218, 171, 1, 226, 72, + 114, 216, 59, 145, 224, 74, 169, 3, + 75, 225, 2, 168, 217, 115, 144, 58, + 228, 78, 173, 7, 118, 220, 63, 149, + 221, 119, 148, 62, 79, 229, 6, 172, + 150, 60, 223, 117, 4, 174, 77, 231, + 175, 5, 230, 76, 61, 151, 116, 222, + 213, 127, 156, 54, 71, 237, 14, 164, + 236, 70, 165, 15, 126, 212, 55, 157, + 167, 13, 238, 68, 53, 159, 124, 214, + 158, 52, 215, 125, 12, 166, 69, 239, + 49, 155, 120, 210, 163, 9, 234, 64, + 8, 162, 65, 235, 154, 48, 211, 121, + 67, 233, 10, 160, 209, 123, 152, 50, + 122, 208, 51, 153, 232, 66, 161, 11, + 183, 29, 254, 84, 37, 143, 108, 198, + 142, 36, 199, 109, 28, 182, 85, 255, + 197, 111, 140, 38, 87, 253, 30, 180, + 252, 86, 181, 31, 110, 196, 39, 141, + 83, 249, 26, 176, 193, 107, 136, 34, + 106, 192, 35, 137, 248, 82, 177, 27, + 33, 139, 104, 194, 179, 25, 250, 80, + 24, 178, 81, 251, 138, 32, 195, 105, + 98, 200, 43, 129, 240, 90, 185, 19, + 91, 241, 18, 184, 201, 99, 128, 42, + 16, 186, 89, 243, 130, 40, 203, 97, + 41, 131, 96, 202, 187, 17, 242, 88, + 134, 44, 207, 101, 20, 190, 93, 247, + 191, 21, 246, 92, 45, 135, 100, 206, + 244, 94, 189, 23, 102, 204, 47, 133, + 205, 103, 132, 46, 95, 245, 22, 188 }, + { 0, 171, 75, 224, 150, 61, 221, 118, + 49, 154, 122, 209, 167, 12, 236, 71, + 98, 201, 41, 130, 244, 95, 191, 20, + 83, 248, 24, 179, 197, 110, 142, 37, + 196, 111, 143, 36, 82, 249, 25, 178, + 245, 94, 190, 21, 99, 200, 40, 131, + 166, 13, 237, 70, 48, 155, 123, 208, + 151, 60, 220, 119, 1, 170, 74, 225, + 149, 62, 222, 117, 3, 168, 72, 227, + 164, 15, 239, 68, 50, 153, 121, 210, + 247, 92, 188, 23, 97, 202, 42, 129, + 198, 109, 141, 38, 80, 251, 27, 176, + 81, 250, 26, 177, 199, 108, 140, 39, + 96, 203, 43, 128, 246, 93, 189, 22, + 51, 152, 120, 211, 165, 14, 238, 69, + 2, 169, 73, 226, 148, 63, 223, 116, + 55, 156, 124, 215, 161, 10, 234, 65, + 6, 173, 77, 230, 144, 59, 219, 112, + 85, 254, 30, 181, 195, 104, 136, 35, + 100, 207, 47, 132, 242, 89, 185, 18, + 243, 88, 184, 19, 101, 206, 46, 133, + 194, 105, 137, 34, 84, 255, 31, 180, + 145, 58, 218, 113, 7, 172, 76, 231, + 160, 11, 235, 64, 54, 157, 125, 214, + 162, 9, 233, 66, 52, 159, 127, 212, + 147, 56, 216, 115, 5, 174, 78, 229, + 192, 107, 139, 32, 86, 253, 29, 182, + 241, 90, 186, 17, 103, 204, 44, 135, + 102, 205, 45, 134, 240, 91, 187, 16, + 87, 252, 28, 183, 193, 106, 138, 33, + 4, 175, 79, 228, 146, 57, 217, 114, + 53, 158, 126, 213, 163, 8, 232, 67 }, + { 0, 172, 69, 233, 138, 38, 207, 99, + 9, 165, 76, 224, 131, 47, 198, 106, + 18, 190, 87, 251, 152, 52, 221, 113, + 27, 183, 94, 242, 145, 61, 212, 120, + 36, 136, 97, 205, 174, 2, 235, 71, + 45, 129, 104, 196, 167, 11, 226, 78, + 54, 154, 115, 223, 188, 16, 249, 85, + 63, 147, 122, 214, 181, 25, 240, 92, + 72, 228, 13, 161, 194, 110, 135, 43, + 65, 237, 4, 168, 203, 103, 142, 34, + 90, 246, 31, 179, 208, 124, 149, 57, + 83, 255, 22, 186, 217, 117, 156, 48, + 108, 192, 41, 133, 230, 74, 163, 15, + 101, 201, 32, 140, 239, 67, 170, 6, + 126, 210, 59, 151, 244, 88, 177, 29, + 119, 219, 50, 158, 253, 81, 184, 20, + 144, 60, 213, 121, 26, 182, 95, 243, + 153, 53, 220, 112, 19, 191, 86, 250, + 130, 46, 199, 107, 8, 164, 77, 225, + 139, 39, 206, 98, 1, 173, 68, 232, + 180, 24, 241, 93, 62, 146, 123, 215, + 189, 17, 248, 84, 55, 155, 114, 222, + 166, 10, 227, 79, 44, 128, 105, 197, + 175, 3, 234, 70, 37, 137, 96, 204, + 216, 116, 157, 49, 82, 254, 23, 187, + 209, 125, 148, 56, 91, 247, 30, 178, + 202, 102, 143, 35, 64, 236, 5, 169, + 195, 111, 134, 42, 73, 229, 12, 160, + 252, 80, 185, 21, 118, 218, 51, 159, + 245, 89, 176, 28, 127, 211, 58, 150, + 238, 66, 171, 7, 100, 200, 33, 141, + 231, 75, 162, 14, 109, 193, 40, 132 }, + { 0, 173, 71, 234, 142, 35, 201, 100, + 1, 172, 70, 235, 143, 34, 200, 101, + 2, 175, 69, 232, 140, 33, 203, 102, + 3, 174, 68, 233, 141, 32, 202, 103, + 4, 169, 67, 238, 138, 39, 205, 96, + 5, 168, 66, 239, 139, 38, 204, 97, + 6, 171, 65, 236, 136, 37, 207, 98, + 7, 170, 64, 237, 137, 36, 206, 99, + 8, 165, 79, 226, 134, 43, 193, 108, + 9, 164, 78, 227, 135, 42, 192, 109, + 10, 167, 77, 224, 132, 41, 195, 110, + 11, 166, 76, 225, 133, 40, 194, 111, + 12, 161, 75, 230, 130, 47, 197, 104, + 13, 160, 74, 231, 131, 46, 196, 105, + 14, 163, 73, 228, 128, 45, 199, 106, + 15, 162, 72, 229, 129, 44, 198, 107, + 16, 189, 87, 250, 158, 51, 217, 116, + 17, 188, 86, 251, 159, 50, 216, 117, + 18, 191, 85, 248, 156, 49, 219, 118, + 19, 190, 84, 249, 157, 48, 218, 119, + 20, 185, 83, 254, 154, 55, 221, 112, + 21, 184, 82, 255, 155, 54, 220, 113, + 22, 187, 81, 252, 152, 53, 223, 114, + 23, 186, 80, 253, 153, 52, 222, 115, + 24, 181, 95, 242, 150, 59, 209, 124, + 25, 180, 94, 243, 151, 58, 208, 125, + 26, 183, 93, 240, 148, 57, 211, 126, + 27, 182, 92, 241, 149, 56, 210, 127, + 28, 177, 91, 246, 146, 63, 213, 120, + 29, 176, 90, 247, 147, 62, 212, 121, + 30, 179, 89, 244, 144, 61, 215, 122, + 31, 178, 88, 245, 145, 60, 214, 123 }, + { 0, 174, 65, 239, 130, 44, 195, 109, + 25, 183, 88, 246, 155, 53, 218, 116, + 50, 156, 115, 221, 176, 30, 241, 95, + 43, 133, 106, 196, 169, 7, 232, 70, + 100, 202, 37, 139, 230, 72, 167, 9, + 125, 211, 60, 146, 255, 81, 190, 16, + 86, 248, 23, 185, 212, 122, 149, 59, + 79, 225, 14, 160, 205, 99, 140, 34, + 200, 102, 137, 39, 74, 228, 11, 165, + 209, 127, 144, 62, 83, 253, 18, 188, + 250, 84, 187, 21, 120, 214, 57, 151, + 227, 77, 162, 12, 97, 207, 32, 142, + 172, 2, 237, 67, 46, 128, 111, 193, + 181, 27, 244, 90, 55, 153, 118, 216, + 158, 48, 223, 113, 28, 178, 93, 243, + 135, 41, 198, 104, 5, 171, 68, 234, + 141, 35, 204, 98, 15, 161, 78, 224, + 148, 58, 213, 123, 22, 184, 87, 249, + 191, 17, 254, 80, 61, 147, 124, 210, + 166, 8, 231, 73, 36, 138, 101, 203, + 233, 71, 168, 6, 107, 197, 42, 132, + 240, 94, 177, 31, 114, 220, 51, 157, + 219, 117, 154, 52, 89, 247, 24, 182, + 194, 108, 131, 45, 64, 238, 1, 175, + 69, 235, 4, 170, 199, 105, 134, 40, + 92, 242, 29, 179, 222, 112, 159, 49, + 119, 217, 54, 152, 245, 91, 180, 26, + 110, 192, 47, 129, 236, 66, 173, 3, + 33, 143, 96, 206, 163, 13, 226, 76, + 56, 150, 121, 215, 186, 20, 251, 85, + 19, 189, 82, 252, 145, 63, 208, 126, + 10, 164, 75, 229, 136, 38, 201, 103 }, + { 0, 175, 67, 236, 134, 41, 197, 106, + 17, 190, 82, 253, 151, 56, 212, 123, + 34, 141, 97, 206, 164, 11, 231, 72, + 51, 156, 112, 223, 181, 26, 246, 89, + 68, 235, 7, 168, 194, 109, 129, 46, + 85, 250, 22, 185, 211, 124, 144, 63, + 102, 201, 37, 138, 224, 79, 163, 12, + 119, 216, 52, 155, 241, 94, 178, 29, + 136, 39, 203, 100, 14, 161, 77, 226, + 153, 54, 218, 117, 31, 176, 92, 243, + 170, 5, 233, 70, 44, 131, 111, 192, + 187, 20, 248, 87, 61, 146, 126, 209, + 204, 99, 143, 32, 74, 229, 9, 166, + 221, 114, 158, 49, 91, 244, 24, 183, + 238, 65, 173, 2, 104, 199, 43, 132, + 255, 80, 188, 19, 121, 214, 58, 149, + 13, 162, 78, 225, 139, 36, 200, 103, + 28, 179, 95, 240, 154, 53, 217, 118, + 47, 128, 108, 195, 169, 6, 234, 69, + 62, 145, 125, 210, 184, 23, 251, 84, + 73, 230, 10, 165, 207, 96, 140, 35, + 88, 247, 27, 180, 222, 113, 157, 50, + 107, 196, 40, 135, 237, 66, 174, 1, + 122, 213, 57, 150, 252, 83, 191, 16, + 133, 42, 198, 105, 3, 172, 64, 239, + 148, 59, 215, 120, 18, 189, 81, 254, + 167, 8, 228, 75, 33, 142, 98, 205, + 182, 25, 245, 90, 48, 159, 115, 220, + 193, 110, 130, 45, 71, 232, 4, 171, + 208, 127, 147, 60, 86, 249, 21, 186, + 227, 76, 160, 15, 101, 202, 38, 137, + 242, 93, 177, 30, 116, 219, 55, 152 }, + { 0, 176, 125, 205, 250, 74, 135, 55, + 233, 89, 148, 36, 19, 163, 110, 222, + 207, 127, 178, 2, 53, 133, 72, 248, + 38, 150, 91, 235, 220, 108, 161, 17, + 131, 51, 254, 78, 121, 201, 4, 180, + 106, 218, 23, 167, 144, 32, 237, 93, + 76, 252, 49, 129, 182, 6, 203, 123, + 165, 21, 216, 104, 95, 239, 34, 146, + 27, 171, 102, 214, 225, 81, 156, 44, + 242, 66, 143, 63, 8, 184, 117, 197, + 212, 100, 169, 25, 46, 158, 83, 227, + 61, 141, 64, 240, 199, 119, 186, 10, + 152, 40, 229, 85, 98, 210, 31, 175, + 113, 193, 12, 188, 139, 59, 246, 70, + 87, 231, 42, 154, 173, 29, 208, 96, + 190, 14, 195, 115, 68, 244, 57, 137, + 54, 134, 75, 251, 204, 124, 177, 1, + 223, 111, 162, 18, 37, 149, 88, 232, + 249, 73, 132, 52, 3, 179, 126, 206, + 16, 160, 109, 221, 234, 90, 151, 39, + 181, 5, 200, 120, 79, 255, 50, 130, + 92, 236, 33, 145, 166, 22, 219, 107, + 122, 202, 7, 183, 128, 48, 253, 77, + 147, 35, 238, 94, 105, 217, 20, 164, + 45, 157, 80, 224, 215, 103, 170, 26, + 196, 116, 185, 9, 62, 142, 67, 243, + 226, 82, 159, 47, 24, 168, 101, 213, + 11, 187, 118, 198, 241, 65, 140, 60, + 174, 30, 211, 99, 84, 228, 41, 153, + 71, 247, 58, 138, 189, 13, 192, 112, + 97, 209, 28, 172, 155, 43, 230, 86, + 136, 56, 245, 69, 114, 194, 15, 191 }, + { 0, 177, 127, 206, 254, 79, 129, 48, + 225, 80, 158, 47, 31, 174, 96, 209, + 223, 110, 160, 17, 33, 144, 94, 239, + 62, 143, 65, 240, 192, 113, 191, 14, + 163, 18, 220, 109, 93, 236, 34, 147, + 66, 243, 61, 140, 188, 13, 195, 114, + 124, 205, 3, 178, 130, 51, 253, 76, + 157, 44, 226, 83, 99, 210, 28, 173, + 91, 234, 36, 149, 165, 20, 218, 107, + 186, 11, 197, 116, 68, 245, 59, 138, + 132, 53, 251, 74, 122, 203, 5, 180, + 101, 212, 26, 171, 155, 42, 228, 85, + 248, 73, 135, 54, 6, 183, 121, 200, + 25, 168, 102, 215, 231, 86, 152, 41, + 39, 150, 88, 233, 217, 104, 166, 23, + 198, 119, 185, 8, 56, 137, 71, 246, + 182, 7, 201, 120, 72, 249, 55, 134, + 87, 230, 40, 153, 169, 24, 214, 103, + 105, 216, 22, 167, 151, 38, 232, 89, + 136, 57, 247, 70, 118, 199, 9, 184, + 21, 164, 106, 219, 235, 90, 148, 37, + 244, 69, 139, 58, 10, 187, 117, 196, + 202, 123, 181, 4, 52, 133, 75, 250, + 43, 154, 84, 229, 213, 100, 170, 27, + 237, 92, 146, 35, 19, 162, 108, 221, + 12, 189, 115, 194, 242, 67, 141, 60, + 50, 131, 77, 252, 204, 125, 179, 2, + 211, 98, 172, 29, 45, 156, 82, 227, + 78, 255, 49, 128, 176, 1, 207, 126, + 175, 30, 208, 97, 81, 224, 46, 159, + 145, 32, 238, 95, 111, 222, 16, 161, + 112, 193, 15, 190, 142, 63, 241, 64 }, + { 0, 178, 121, 203, 242, 64, 139, 57, + 249, 75, 128, 50, 11, 185, 114, 192, + 239, 93, 150, 36, 29, 175, 100, 214, + 22, 164, 111, 221, 228, 86, 157, 47, + 195, 113, 186, 8, 49, 131, 72, 250, + 58, 136, 67, 241, 200, 122, 177, 3, + 44, 158, 85, 231, 222, 108, 167, 21, + 213, 103, 172, 30, 39, 149, 94, 236, + 155, 41, 226, 80, 105, 219, 16, 162, + 98, 208, 27, 169, 144, 34, 233, 91, + 116, 198, 13, 191, 134, 52, 255, 77, + 141, 63, 244, 70, 127, 205, 6, 180, + 88, 234, 33, 147, 170, 24, 211, 97, + 161, 19, 216, 106, 83, 225, 42, 152, + 183, 5, 206, 124, 69, 247, 60, 142, + 78, 252, 55, 133, 188, 14, 197, 119, + 43, 153, 82, 224, 217, 107, 160, 18, + 210, 96, 171, 25, 32, 146, 89, 235, + 196, 118, 189, 15, 54, 132, 79, 253, + 61, 143, 68, 246, 207, 125, 182, 4, + 232, 90, 145, 35, 26, 168, 99, 209, + 17, 163, 104, 218, 227, 81, 154, 40, + 7, 181, 126, 204, 245, 71, 140, 62, + 254, 76, 135, 53, 12, 190, 117, 199, + 176, 2, 201, 123, 66, 240, 59, 137, + 73, 251, 48, 130, 187, 9, 194, 112, + 95, 237, 38, 148, 173, 31, 212, 102, + 166, 20, 223, 109, 84, 230, 45, 159, + 115, 193, 10, 184, 129, 51, 248, 74, + 138, 56, 243, 65, 120, 202, 1, 179, + 156, 46, 229, 87, 110, 220, 23, 165, + 101, 215, 28, 174, 151, 37, 238, 92 }, + { 0, 179, 123, 200, 246, 69, 141, 62, + 241, 66, 138, 57, 7, 180, 124, 207, + 255, 76, 132, 55, 9, 186, 114, 193, + 14, 189, 117, 198, 248, 75, 131, 48, + 227, 80, 152, 43, 21, 166, 110, 221, + 18, 161, 105, 218, 228, 87, 159, 44, + 28, 175, 103, 212, 234, 89, 145, 34, + 237, 94, 150, 37, 27, 168, 96, 211, + 219, 104, 160, 19, 45, 158, 86, 229, + 42, 153, 81, 226, 220, 111, 167, 20, + 36, 151, 95, 236, 210, 97, 169, 26, + 213, 102, 174, 29, 35, 144, 88, 235, + 56, 139, 67, 240, 206, 125, 181, 6, + 201, 122, 178, 1, 63, 140, 68, 247, + 199, 116, 188, 15, 49, 130, 74, 249, + 54, 133, 77, 254, 192, 115, 187, 8, + 171, 24, 208, 99, 93, 238, 38, 149, + 90, 233, 33, 146, 172, 31, 215, 100, + 84, 231, 47, 156, 162, 17, 217, 106, + 165, 22, 222, 109, 83, 224, 40, 155, + 72, 251, 51, 128, 190, 13, 197, 118, + 185, 10, 194, 113, 79, 252, 52, 135, + 183, 4, 204, 127, 65, 242, 58, 137, + 70, 245, 61, 142, 176, 3, 203, 120, + 112, 195, 11, 184, 134, 53, 253, 78, + 129, 50, 250, 73, 119, 196, 12, 191, + 143, 60, 244, 71, 121, 202, 2, 177, + 126, 205, 5, 182, 136, 59, 243, 64, + 147, 32, 232, 91, 101, 214, 30, 173, + 98, 209, 25, 170, 148, 39, 239, 92, + 108, 223, 23, 164, 154, 41, 225, 82, + 157, 46, 230, 85, 107, 216, 16, 163 }, + { 0, 180, 117, 193, 234, 94, 159, 43, + 201, 125, 188, 8, 35, 151, 86, 226, + 143, 59, 250, 78, 101, 209, 16, 164, + 70, 242, 51, 135, 172, 24, 217, 109, + 3, 183, 118, 194, 233, 93, 156, 40, + 202, 126, 191, 11, 32, 148, 85, 225, + 140, 56, 249, 77, 102, 210, 19, 167, + 69, 241, 48, 132, 175, 27, 218, 110, + 6, 178, 115, 199, 236, 88, 153, 45, + 207, 123, 186, 14, 37, 145, 80, 228, + 137, 61, 252, 72, 99, 215, 22, 162, + 64, 244, 53, 129, 170, 30, 223, 107, + 5, 177, 112, 196, 239, 91, 154, 46, + 204, 120, 185, 13, 38, 146, 83, 231, + 138, 62, 255, 75, 96, 212, 21, 161, + 67, 247, 54, 130, 169, 29, 220, 104, + 12, 184, 121, 205, 230, 82, 147, 39, + 197, 113, 176, 4, 47, 155, 90, 238, + 131, 55, 246, 66, 105, 221, 28, 168, + 74, 254, 63, 139, 160, 20, 213, 97, + 15, 187, 122, 206, 229, 81, 144, 36, + 198, 114, 179, 7, 44, 152, 89, 237, + 128, 52, 245, 65, 106, 222, 31, 171, + 73, 253, 60, 136, 163, 23, 214, 98, + 10, 190, 127, 203, 224, 84, 149, 33, + 195, 119, 182, 2, 41, 157, 92, 232, + 133, 49, 240, 68, 111, 219, 26, 174, + 76, 248, 57, 141, 166, 18, 211, 103, + 9, 189, 124, 200, 227, 87, 150, 34, + 192, 116, 181, 1, 42, 158, 95, 235, + 134, 50, 243, 71, 108, 216, 25, 173, + 79, 251, 58, 142, 165, 17, 208, 100 }, + { 0, 181, 119, 194, 238, 91, 153, 44, + 193, 116, 182, 3, 47, 154, 88, 237, + 159, 42, 232, 93, 113, 196, 6, 179, + 94, 235, 41, 156, 176, 5, 199, 114, + 35, 150, 84, 225, 205, 120, 186, 15, + 226, 87, 149, 32, 12, 185, 123, 206, + 188, 9, 203, 126, 82, 231, 37, 144, + 125, 200, 10, 191, 147, 38, 228, 81, + 70, 243, 49, 132, 168, 29, 223, 106, + 135, 50, 240, 69, 105, 220, 30, 171, + 217, 108, 174, 27, 55, 130, 64, 245, + 24, 173, 111, 218, 246, 67, 129, 52, + 101, 208, 18, 167, 139, 62, 252, 73, + 164, 17, 211, 102, 74, 255, 61, 136, + 250, 79, 141, 56, 20, 161, 99, 214, + 59, 142, 76, 249, 213, 96, 162, 23, + 140, 57, 251, 78, 98, 215, 21, 160, + 77, 248, 58, 143, 163, 22, 212, 97, + 19, 166, 100, 209, 253, 72, 138, 63, + 210, 103, 165, 16, 60, 137, 75, 254, + 175, 26, 216, 109, 65, 244, 54, 131, + 110, 219, 25, 172, 128, 53, 247, 66, + 48, 133, 71, 242, 222, 107, 169, 28, + 241, 68, 134, 51, 31, 170, 104, 221, + 202, 127, 189, 8, 36, 145, 83, 230, + 11, 190, 124, 201, 229, 80, 146, 39, + 85, 224, 34, 151, 187, 14, 204, 121, + 148, 33, 227, 86, 122, 207, 13, 184, + 233, 92, 158, 43, 7, 178, 112, 197, + 40, 157, 95, 234, 198, 115, 177, 4, + 118, 195, 1, 180, 152, 45, 239, 90, + 183, 2, 192, 117, 89, 236, 46, 155 }, + { 0, 182, 113, 199, 226, 84, 147, 37, + 217, 111, 168, 30, 59, 141, 74, 252, + 175, 25, 222, 104, 77, 251, 60, 138, + 118, 192, 7, 177, 148, 34, 229, 83, + 67, 245, 50, 132, 161, 23, 208, 102, + 154, 44, 235, 93, 120, 206, 9, 191, + 236, 90, 157, 43, 14, 184, 127, 201, + 53, 131, 68, 242, 215, 97, 166, 16, + 134, 48, 247, 65, 100, 210, 21, 163, + 95, 233, 46, 152, 189, 11, 204, 122, + 41, 159, 88, 238, 203, 125, 186, 12, + 240, 70, 129, 55, 18, 164, 99, 213, + 197, 115, 180, 2, 39, 145, 86, 224, + 28, 170, 109, 219, 254, 72, 143, 57, + 106, 220, 27, 173, 136, 62, 249, 79, + 179, 5, 194, 116, 81, 231, 32, 150, + 17, 167, 96, 214, 243, 69, 130, 52, + 200, 126, 185, 15, 42, 156, 91, 237, + 190, 8, 207, 121, 92, 234, 45, 155, + 103, 209, 22, 160, 133, 51, 244, 66, + 82, 228, 35, 149, 176, 6, 193, 119, + 139, 61, 250, 76, 105, 223, 24, 174, + 253, 75, 140, 58, 31, 169, 110, 216, + 36, 146, 85, 227, 198, 112, 183, 1, + 151, 33, 230, 80, 117, 195, 4, 178, + 78, 248, 63, 137, 172, 26, 221, 107, + 56, 142, 73, 255, 218, 108, 171, 29, + 225, 87, 144, 38, 3, 181, 114, 196, + 212, 98, 165, 19, 54, 128, 71, 241, + 13, 187, 124, 202, 239, 89, 158, 40, + 123, 205, 10, 188, 153, 47, 232, 94, + 162, 20, 211, 101, 64, 246, 49, 135 }, + { 0, 183, 115, 196, 230, 81, 149, 34, + 209, 102, 162, 21, 55, 128, 68, 243, + 191, 8, 204, 123, 89, 238, 42, 157, + 110, 217, 29, 170, 136, 63, 251, 76, + 99, 212, 16, 167, 133, 50, 246, 65, + 178, 5, 193, 118, 84, 227, 39, 144, + 220, 107, 175, 24, 58, 141, 73, 254, + 13, 186, 126, 201, 235, 92, 152, 47, + 198, 113, 181, 2, 32, 151, 83, 228, + 23, 160, 100, 211, 241, 70, 130, 53, + 121, 206, 10, 189, 159, 40, 236, 91, + 168, 31, 219, 108, 78, 249, 61, 138, + 165, 18, 214, 97, 67, 244, 48, 135, + 116, 195, 7, 176, 146, 37, 225, 86, + 26, 173, 105, 222, 252, 75, 143, 56, + 203, 124, 184, 15, 45, 154, 94, 233, + 145, 38, 226, 85, 119, 192, 4, 179, + 64, 247, 51, 132, 166, 17, 213, 98, + 46, 153, 93, 234, 200, 127, 187, 12, + 255, 72, 140, 59, 25, 174, 106, 221, + 242, 69, 129, 54, 20, 163, 103, 208, + 35, 148, 80, 231, 197, 114, 182, 1, + 77, 250, 62, 137, 171, 28, 216, 111, + 156, 43, 239, 88, 122, 205, 9, 190, + 87, 224, 36, 147, 177, 6, 194, 117, + 134, 49, 245, 66, 96, 215, 19, 164, + 232, 95, 155, 44, 14, 185, 125, 202, + 57, 142, 74, 253, 223, 104, 172, 27, + 52, 131, 71, 240, 210, 101, 161, 22, + 229, 82, 150, 33, 3, 180, 112, 199, + 139, 60, 248, 79, 109, 218, 30, 169, + 90, 237, 41, 158, 188, 11, 207, 120 }, + { 0, 184, 109, 213, 218, 98, 183, 15, + 169, 17, 196, 124, 115, 203, 30, 166, + 79, 247, 34, 154, 149, 45, 248, 64, + 230, 94, 139, 51, 60, 132, 81, 233, + 158, 38, 243, 75, 68, 252, 41, 145, + 55, 143, 90, 226, 237, 85, 128, 56, + 209, 105, 188, 4, 11, 179, 102, 222, + 120, 192, 21, 173, 162, 26, 207, 119, + 33, 153, 76, 244, 251, 67, 150, 46, + 136, 48, 229, 93, 82, 234, 63, 135, + 110, 214, 3, 187, 180, 12, 217, 97, + 199, 127, 170, 18, 29, 165, 112, 200, + 191, 7, 210, 106, 101, 221, 8, 176, + 22, 174, 123, 195, 204, 116, 161, 25, + 240, 72, 157, 37, 42, 146, 71, 255, + 89, 225, 52, 140, 131, 59, 238, 86, + 66, 250, 47, 151, 152, 32, 245, 77, + 235, 83, 134, 62, 49, 137, 92, 228, + 13, 181, 96, 216, 215, 111, 186, 2, + 164, 28, 201, 113, 126, 198, 19, 171, + 220, 100, 177, 9, 6, 190, 107, 211, + 117, 205, 24, 160, 175, 23, 194, 122, + 147, 43, 254, 70, 73, 241, 36, 156, + 58, 130, 87, 239, 224, 88, 141, 53, + 99, 219, 14, 182, 185, 1, 212, 108, + 202, 114, 167, 31, 16, 168, 125, 197, + 44, 148, 65, 249, 246, 78, 155, 35, + 133, 61, 232, 80, 95, 231, 50, 138, + 253, 69, 144, 40, 39, 159, 74, 242, + 84, 236, 57, 129, 142, 54, 227, 91, + 178, 10, 223, 103, 104, 208, 5, 189, + 27, 163, 118, 206, 193, 121, 172, 20 }, + { 0, 185, 111, 214, 222, 103, 177, 8, + 161, 24, 206, 119, 127, 198, 16, 169, + 95, 230, 48, 137, 129, 56, 238, 87, + 254, 71, 145, 40, 32, 153, 79, 246, + 190, 7, 209, 104, 96, 217, 15, 182, + 31, 166, 112, 201, 193, 120, 174, 23, + 225, 88, 142, 55, 63, 134, 80, 233, + 64, 249, 47, 150, 158, 39, 241, 72, + 97, 216, 14, 183, 191, 6, 208, 105, + 192, 121, 175, 22, 30, 167, 113, 200, + 62, 135, 81, 232, 224, 89, 143, 54, + 159, 38, 240, 73, 65, 248, 46, 151, + 223, 102, 176, 9, 1, 184, 110, 215, + 126, 199, 17, 168, 160, 25, 207, 118, + 128, 57, 239, 86, 94, 231, 49, 136, + 33, 152, 78, 247, 255, 70, 144, 41, + 194, 123, 173, 20, 28, 165, 115, 202, + 99, 218, 12, 181, 189, 4, 210, 107, + 157, 36, 242, 75, 67, 250, 44, 149, + 60, 133, 83, 234, 226, 91, 141, 52, + 124, 197, 19, 170, 162, 27, 205, 116, + 221, 100, 178, 11, 3, 186, 108, 213, + 35, 154, 76, 245, 253, 68, 146, 43, + 130, 59, 237, 84, 92, 229, 51, 138, + 163, 26, 204, 117, 125, 196, 18, 171, + 2, 187, 109, 212, 220, 101, 179, 10, + 252, 69, 147, 42, 34, 155, 77, 244, + 93, 228, 50, 139, 131, 58, 236, 85, + 29, 164, 114, 203, 195, 122, 172, 21, + 188, 5, 211, 106, 98, 219, 13, 180, + 66, 251, 45, 148, 156, 37, 243, 74, + 227, 90, 140, 53, 61, 132, 82, 235 }, + { 0, 186, 105, 211, 210, 104, 187, 1, + 185, 3, 208, 106, 107, 209, 2, 184, + 111, 213, 6, 188, 189, 7, 212, 110, + 214, 108, 191, 5, 4, 190, 109, 215, + 222, 100, 183, 13, 12, 182, 101, 223, + 103, 221, 14, 180, 181, 15, 220, 102, + 177, 11, 216, 98, 99, 217, 10, 176, + 8, 178, 97, 219, 218, 96, 179, 9, + 161, 27, 200, 114, 115, 201, 26, 160, + 24, 162, 113, 203, 202, 112, 163, 25, + 206, 116, 167, 29, 28, 166, 117, 207, + 119, 205, 30, 164, 165, 31, 204, 118, + 127, 197, 22, 172, 173, 23, 196, 126, + 198, 124, 175, 21, 20, 174, 125, 199, + 16, 170, 121, 195, 194, 120, 171, 17, + 169, 19, 192, 122, 123, 193, 18, 168, + 95, 229, 54, 140, 141, 55, 228, 94, + 230, 92, 143, 53, 52, 142, 93, 231, + 48, 138, 89, 227, 226, 88, 139, 49, + 137, 51, 224, 90, 91, 225, 50, 136, + 129, 59, 232, 82, 83, 233, 58, 128, + 56, 130, 81, 235, 234, 80, 131, 57, + 238, 84, 135, 61, 60, 134, 85, 239, + 87, 237, 62, 132, 133, 63, 236, 86, + 254, 68, 151, 45, 44, 150, 69, 255, + 71, 253, 46, 148, 149, 47, 252, 70, + 145, 43, 248, 66, 67, 249, 42, 144, + 40, 146, 65, 251, 250, 64, 147, 41, + 32, 154, 73, 243, 242, 72, 155, 33, + 153, 35, 240, 74, 75, 241, 34, 152, + 79, 245, 38, 156, 157, 39, 244, 78, + 246, 76, 159, 37, 36, 158, 77, 247 }, + { 0, 187, 107, 208, 214, 109, 189, 6, + 177, 10, 218, 97, 103, 220, 12, 183, + 127, 196, 20, 175, 169, 18, 194, 121, + 206, 117, 165, 30, 24, 163, 115, 200, + 254, 69, 149, 46, 40, 147, 67, 248, + 79, 244, 36, 159, 153, 34, 242, 73, + 129, 58, 234, 81, 87, 236, 60, 135, + 48, 139, 91, 224, 230, 93, 141, 54, + 225, 90, 138, 49, 55, 140, 92, 231, + 80, 235, 59, 128, 134, 61, 237, 86, + 158, 37, 245, 78, 72, 243, 35, 152, + 47, 148, 68, 255, 249, 66, 146, 41, + 31, 164, 116, 207, 201, 114, 162, 25, + 174, 21, 197, 126, 120, 195, 19, 168, + 96, 219, 11, 176, 182, 13, 221, 102, + 209, 106, 186, 1, 7, 188, 108, 215, + 223, 100, 180, 15, 9, 178, 98, 217, + 110, 213, 5, 190, 184, 3, 211, 104, + 160, 27, 203, 112, 118, 205, 29, 166, + 17, 170, 122, 193, 199, 124, 172, 23, + 33, 154, 74, 241, 247, 76, 156, 39, + 144, 43, 251, 64, 70, 253, 45, 150, + 94, 229, 53, 142, 136, 51, 227, 88, + 239, 84, 132, 63, 57, 130, 82, 233, + 62, 133, 85, 238, 232, 83, 131, 56, + 143, 52, 228, 95, 89, 226, 50, 137, + 65, 250, 42, 145, 151, 44, 252, 71, + 240, 75, 155, 32, 38, 157, 77, 246, + 192, 123, 171, 16, 22, 173, 125, 198, + 113, 202, 26, 161, 167, 28, 204, 119, + 191, 4, 212, 111, 105, 210, 2, 185, + 14, 181, 101, 222, 216, 99, 179, 8 }, + { 0, 188, 101, 217, 202, 118, 175, 19, + 137, 53, 236, 80, 67, 255, 38, 154, + 15, 179, 106, 214, 197, 121, 160, 28, + 134, 58, 227, 95, 76, 240, 41, 149, + 30, 162, 123, 199, 212, 104, 177, 13, + 151, 43, 242, 78, 93, 225, 56, 132, + 17, 173, 116, 200, 219, 103, 190, 2, + 152, 36, 253, 65, 82, 238, 55, 139, + 60, 128, 89, 229, 246, 74, 147, 47, + 181, 9, 208, 108, 127, 195, 26, 166, + 51, 143, 86, 234, 249, 69, 156, 32, + 186, 6, 223, 99, 112, 204, 21, 169, + 34, 158, 71, 251, 232, 84, 141, 49, + 171, 23, 206, 114, 97, 221, 4, 184, + 45, 145, 72, 244, 231, 91, 130, 62, + 164, 24, 193, 125, 110, 210, 11, 183, + 120, 196, 29, 161, 178, 14, 215, 107, + 241, 77, 148, 40, 59, 135, 94, 226, + 119, 203, 18, 174, 189, 1, 216, 100, + 254, 66, 155, 39, 52, 136, 81, 237, + 102, 218, 3, 191, 172, 16, 201, 117, + 239, 83, 138, 54, 37, 153, 64, 252, + 105, 213, 12, 176, 163, 31, 198, 122, + 224, 92, 133, 57, 42, 150, 79, 243, + 68, 248, 33, 157, 142, 50, 235, 87, + 205, 113, 168, 20, 7, 187, 98, 222, + 75, 247, 46, 146, 129, 61, 228, 88, + 194, 126, 167, 27, 8, 180, 109, 209, + 90, 230, 63, 131, 144, 44, 245, 73, + 211, 111, 182, 10, 25, 165, 124, 192, + 85, 233, 48, 140, 159, 35, 250, 70, + 220, 96, 185, 5, 22, 170, 115, 207 }, + { 0, 189, 103, 218, 206, 115, 169, 20, + 129, 60, 230, 91, 79, 242, 40, 149, + 31, 162, 120, 197, 209, 108, 182, 11, + 158, 35, 249, 68, 80, 237, 55, 138, + 62, 131, 89, 228, 240, 77, 151, 42, + 191, 2, 216, 101, 113, 204, 22, 171, + 33, 156, 70, 251, 239, 82, 136, 53, + 160, 29, 199, 122, 110, 211, 9, 180, + 124, 193, 27, 166, 178, 15, 213, 104, + 253, 64, 154, 39, 51, 142, 84, 233, + 99, 222, 4, 185, 173, 16, 202, 119, + 226, 95, 133, 56, 44, 145, 75, 246, + 66, 255, 37, 152, 140, 49, 235, 86, + 195, 126, 164, 25, 13, 176, 106, 215, + 93, 224, 58, 135, 147, 46, 244, 73, + 220, 97, 187, 6, 18, 175, 117, 200, + 248, 69, 159, 34, 54, 139, 81, 236, + 121, 196, 30, 163, 183, 10, 208, 109, + 231, 90, 128, 61, 41, 148, 78, 243, + 102, 219, 1, 188, 168, 21, 207, 114, + 198, 123, 161, 28, 8, 181, 111, 210, + 71, 250, 32, 157, 137, 52, 238, 83, + 217, 100, 190, 3, 23, 170, 112, 205, + 88, 229, 63, 130, 150, 43, 241, 76, + 132, 57, 227, 94, 74, 247, 45, 144, + 5, 184, 98, 223, 203, 118, 172, 17, + 155, 38, 252, 65, 85, 232, 50, 143, + 26, 167, 125, 192, 212, 105, 179, 14, + 186, 7, 221, 96, 116, 201, 19, 174, + 59, 134, 92, 225, 245, 72, 146, 47, + 165, 24, 194, 127, 107, 214, 12, 177, + 36, 153, 67, 254, 234, 87, 141, 48 }, + { 0, 190, 97, 223, 194, 124, 163, 29, + 153, 39, 248, 70, 91, 229, 58, 132, + 47, 145, 78, 240, 237, 83, 140, 50, + 182, 8, 215, 105, 116, 202, 21, 171, + 94, 224, 63, 129, 156, 34, 253, 67, + 199, 121, 166, 24, 5, 187, 100, 218, + 113, 207, 16, 174, 179, 13, 210, 108, + 232, 86, 137, 55, 42, 148, 75, 245, + 188, 2, 221, 99, 126, 192, 31, 161, + 37, 155, 68, 250, 231, 89, 134, 56, + 147, 45, 242, 76, 81, 239, 48, 142, + 10, 180, 107, 213, 200, 118, 169, 23, + 226, 92, 131, 61, 32, 158, 65, 255, + 123, 197, 26, 164, 185, 7, 216, 102, + 205, 115, 172, 18, 15, 177, 110, 208, + 84, 234, 53, 139, 150, 40, 247, 73, + 101, 219, 4, 186, 167, 25, 198, 120, + 252, 66, 157, 35, 62, 128, 95, 225, + 74, 244, 43, 149, 136, 54, 233, 87, + 211, 109, 178, 12, 17, 175, 112, 206, + 59, 133, 90, 228, 249, 71, 152, 38, + 162, 28, 195, 125, 96, 222, 1, 191, + 20, 170, 117, 203, 214, 104, 183, 9, + 141, 51, 236, 82, 79, 241, 46, 144, + 217, 103, 184, 6, 27, 165, 122, 196, + 64, 254, 33, 159, 130, 60, 227, 93, + 246, 72, 151, 41, 52, 138, 85, 235, + 111, 209, 14, 176, 173, 19, 204, 114, + 135, 57, 230, 88, 69, 251, 36, 154, + 30, 160, 127, 193, 220, 98, 189, 3, + 168, 22, 201, 119, 106, 212, 11, 181, + 49, 143, 80, 238, 243, 77, 146, 44 }, + { 0, 191, 99, 220, 198, 121, 165, 26, + 145, 46, 242, 77, 87, 232, 52, 139, + 63, 128, 92, 227, 249, 70, 154, 37, + 174, 17, 205, 114, 104, 215, 11, 180, + 126, 193, 29, 162, 184, 7, 219, 100, + 239, 80, 140, 51, 41, 150, 74, 245, + 65, 254, 34, 157, 135, 56, 228, 91, + 208, 111, 179, 12, 22, 169, 117, 202, + 252, 67, 159, 32, 58, 133, 89, 230, + 109, 210, 14, 177, 171, 20, 200, 119, + 195, 124, 160, 31, 5, 186, 102, 217, + 82, 237, 49, 142, 148, 43, 247, 72, + 130, 61, 225, 94, 68, 251, 39, 152, + 19, 172, 112, 207, 213, 106, 182, 9, + 189, 2, 222, 97, 123, 196, 24, 167, + 44, 147, 79, 240, 234, 85, 137, 54, + 229, 90, 134, 57, 35, 156, 64, 255, + 116, 203, 23, 168, 178, 13, 209, 110, + 218, 101, 185, 6, 28, 163, 127, 192, + 75, 244, 40, 151, 141, 50, 238, 81, + 155, 36, 248, 71, 93, 226, 62, 129, + 10, 181, 105, 214, 204, 115, 175, 16, + 164, 27, 199, 120, 98, 221, 1, 190, + 53, 138, 86, 233, 243, 76, 144, 47, + 25, 166, 122, 197, 223, 96, 188, 3, + 136, 55, 235, 84, 78, 241, 45, 146, + 38, 153, 69, 250, 224, 95, 131, 60, + 183, 8, 212, 107, 113, 206, 18, 173, + 103, 216, 4, 187, 161, 30, 194, 125, + 246, 73, 149, 42, 48, 143, 83, 236, + 88, 231, 59, 132, 158, 33, 253, 66, + 201, 118, 170, 21, 15, 176, 108, 211 }, + { 0, 192, 157, 93, 39, 231, 186, 122, + 78, 142, 211, 19, 105, 169, 244, 52, + 156, 92, 1, 193, 187, 123, 38, 230, + 210, 18, 79, 143, 245, 53, 104, 168, + 37, 229, 184, 120, 2, 194, 159, 95, + 107, 171, 246, 54, 76, 140, 209, 17, + 185, 121, 36, 228, 158, 94, 3, 195, + 247, 55, 106, 170, 208, 16, 77, 141, + 74, 138, 215, 23, 109, 173, 240, 48, + 4, 196, 153, 89, 35, 227, 190, 126, + 214, 22, 75, 139, 241, 49, 108, 172, + 152, 88, 5, 197, 191, 127, 34, 226, + 111, 175, 242, 50, 72, 136, 213, 21, + 33, 225, 188, 124, 6, 198, 155, 91, + 243, 51, 110, 174, 212, 20, 73, 137, + 189, 125, 32, 224, 154, 90, 7, 199, + 148, 84, 9, 201, 179, 115, 46, 238, + 218, 26, 71, 135, 253, 61, 96, 160, + 8, 200, 149, 85, 47, 239, 178, 114, + 70, 134, 219, 27, 97, 161, 252, 60, + 177, 113, 44, 236, 150, 86, 11, 203, + 255, 63, 98, 162, 216, 24, 69, 133, + 45, 237, 176, 112, 10, 202, 151, 87, + 99, 163, 254, 62, 68, 132, 217, 25, + 222, 30, 67, 131, 249, 57, 100, 164, + 144, 80, 13, 205, 183, 119, 42, 234, + 66, 130, 223, 31, 101, 165, 248, 56, + 12, 204, 145, 81, 43, 235, 182, 118, + 251, 59, 102, 166, 220, 28, 65, 129, + 181, 117, 40, 232, 146, 82, 15, 207, + 103, 167, 250, 58, 64, 128, 221, 29, + 41, 233, 180, 116, 14, 206, 147, 83 }, + { 0, 193, 159, 94, 35, 226, 188, 125, + 70, 135, 217, 24, 101, 164, 250, 59, + 140, 77, 19, 210, 175, 110, 48, 241, + 202, 11, 85, 148, 233, 40, 118, 183, + 5, 196, 154, 91, 38, 231, 185, 120, + 67, 130, 220, 29, 96, 161, 255, 62, + 137, 72, 22, 215, 170, 107, 53, 244, + 207, 14, 80, 145, 236, 45, 115, 178, + 10, 203, 149, 84, 41, 232, 182, 119, + 76, 141, 211, 18, 111, 174, 240, 49, + 134, 71, 25, 216, 165, 100, 58, 251, + 192, 1, 95, 158, 227, 34, 124, 189, + 15, 206, 144, 81, 44, 237, 179, 114, + 73, 136, 214, 23, 106, 171, 245, 52, + 131, 66, 28, 221, 160, 97, 63, 254, + 197, 4, 90, 155, 230, 39, 121, 184, + 20, 213, 139, 74, 55, 246, 168, 105, + 82, 147, 205, 12, 113, 176, 238, 47, + 152, 89, 7, 198, 187, 122, 36, 229, + 222, 31, 65, 128, 253, 60, 98, 163, + 17, 208, 142, 79, 50, 243, 173, 108, + 87, 150, 200, 9, 116, 181, 235, 42, + 157, 92, 2, 195, 190, 127, 33, 224, + 219, 26, 68, 133, 248, 57, 103, 166, + 30, 223, 129, 64, 61, 252, 162, 99, + 88, 153, 199, 6, 123, 186, 228, 37, + 146, 83, 13, 204, 177, 112, 46, 239, + 212, 21, 75, 138, 247, 54, 104, 169, + 27, 218, 132, 69, 56, 249, 167, 102, + 93, 156, 194, 3, 126, 191, 225, 32, + 151, 86, 8, 201, 180, 117, 43, 234, + 209, 16, 78, 143, 242, 51, 109, 172 }, + { 0, 194, 153, 91, 47, 237, 182, 116, + 94, 156, 199, 5, 113, 179, 232, 42, + 188, 126, 37, 231, 147, 81, 10, 200, + 226, 32, 123, 185, 205, 15, 84, 150, + 101, 167, 252, 62, 74, 136, 211, 17, + 59, 249, 162, 96, 20, 214, 141, 79, + 217, 27, 64, 130, 246, 52, 111, 173, + 135, 69, 30, 220, 168, 106, 49, 243, + 202, 8, 83, 145, 229, 39, 124, 190, + 148, 86, 13, 207, 187, 121, 34, 224, + 118, 180, 239, 45, 89, 155, 192, 2, + 40, 234, 177, 115, 7, 197, 158, 92, + 175, 109, 54, 244, 128, 66, 25, 219, + 241, 51, 104, 170, 222, 28, 71, 133, + 19, 209, 138, 72, 60, 254, 165, 103, + 77, 143, 212, 22, 98, 160, 251, 57, + 137, 75, 16, 210, 166, 100, 63, 253, + 215, 21, 78, 140, 248, 58, 97, 163, + 53, 247, 172, 110, 26, 216, 131, 65, + 107, 169, 242, 48, 68, 134, 221, 31, + 236, 46, 117, 183, 195, 1, 90, 152, + 178, 112, 43, 233, 157, 95, 4, 198, + 80, 146, 201, 11, 127, 189, 230, 36, + 14, 204, 151, 85, 33, 227, 184, 122, + 67, 129, 218, 24, 108, 174, 245, 55, + 29, 223, 132, 70, 50, 240, 171, 105, + 255, 61, 102, 164, 208, 18, 73, 139, + 161, 99, 56, 250, 142, 76, 23, 213, + 38, 228, 191, 125, 9, 203, 144, 82, + 120, 186, 225, 35, 87, 149, 206, 12, + 154, 88, 3, 193, 181, 119, 44, 238, + 196, 6, 93, 159, 235, 41, 114, 176 }, + { 0, 195, 155, 88, 43, 232, 176, 115, + 86, 149, 205, 14, 125, 190, 230, 37, + 172, 111, 55, 244, 135, 68, 28, 223, + 250, 57, 97, 162, 209, 18, 74, 137, + 69, 134, 222, 29, 110, 173, 245, 54, + 19, 208, 136, 75, 56, 251, 163, 96, + 233, 42, 114, 177, 194, 1, 89, 154, + 191, 124, 36, 231, 148, 87, 15, 204, + 138, 73, 17, 210, 161, 98, 58, 249, + 220, 31, 71, 132, 247, 52, 108, 175, + 38, 229, 189, 126, 13, 206, 150, 85, + 112, 179, 235, 40, 91, 152, 192, 3, + 207, 12, 84, 151, 228, 39, 127, 188, + 153, 90, 2, 193, 178, 113, 41, 234, + 99, 160, 248, 59, 72, 139, 211, 16, + 53, 246, 174, 109, 30, 221, 133, 70, + 9, 202, 146, 81, 34, 225, 185, 122, + 95, 156, 196, 7, 116, 183, 239, 44, + 165, 102, 62, 253, 142, 77, 21, 214, + 243, 48, 104, 171, 216, 27, 67, 128, + 76, 143, 215, 20, 103, 164, 252, 63, + 26, 217, 129, 66, 49, 242, 170, 105, + 224, 35, 123, 184, 203, 8, 80, 147, + 182, 117, 45, 238, 157, 94, 6, 197, + 131, 64, 24, 219, 168, 107, 51, 240, + 213, 22, 78, 141, 254, 61, 101, 166, + 47, 236, 180, 119, 4, 199, 159, 92, + 121, 186, 226, 33, 82, 145, 201, 10, + 198, 5, 93, 158, 237, 46, 118, 181, + 144, 83, 11, 200, 187, 120, 32, 227, + 106, 169, 241, 50, 65, 130, 218, 25, + 60, 255, 167, 100, 23, 212, 140, 79 }, + { 0, 196, 149, 81, 55, 243, 162, 102, + 110, 170, 251, 63, 89, 157, 204, 8, + 220, 24, 73, 141, 235, 47, 126, 186, + 178, 118, 39, 227, 133, 65, 16, 212, + 165, 97, 48, 244, 146, 86, 7, 195, + 203, 15, 94, 154, 252, 56, 105, 173, + 121, 189, 236, 40, 78, 138, 219, 31, + 23, 211, 130, 70, 32, 228, 181, 113, + 87, 147, 194, 6, 96, 164, 245, 49, + 57, 253, 172, 104, 14, 202, 155, 95, + 139, 79, 30, 218, 188, 120, 41, 237, + 229, 33, 112, 180, 210, 22, 71, 131, + 242, 54, 103, 163, 197, 1, 80, 148, + 156, 88, 9, 205, 171, 111, 62, 250, + 46, 234, 187, 127, 25, 221, 140, 72, + 64, 132, 213, 17, 119, 179, 226, 38, + 174, 106, 59, 255, 153, 93, 12, 200, + 192, 4, 85, 145, 247, 51, 98, 166, + 114, 182, 231, 35, 69, 129, 208, 20, + 28, 216, 137, 77, 43, 239, 190, 122, + 11, 207, 158, 90, 60, 248, 169, 109, + 101, 161, 240, 52, 82, 150, 199, 3, + 215, 19, 66, 134, 224, 36, 117, 177, + 185, 125, 44, 232, 142, 74, 27, 223, + 249, 61, 108, 168, 206, 10, 91, 159, + 151, 83, 2, 198, 160, 100, 53, 241, + 37, 225, 176, 116, 18, 214, 135, 67, + 75, 143, 222, 26, 124, 184, 233, 45, + 92, 152, 201, 13, 107, 175, 254, 58, + 50, 246, 167, 99, 5, 193, 144, 84, + 128, 68, 21, 209, 183, 115, 34, 230, + 238, 42, 123, 191, 217, 29, 76, 136 }, + { 0, 197, 151, 82, 51, 246, 164, 97, + 102, 163, 241, 52, 85, 144, 194, 7, + 204, 9, 91, 158, 255, 58, 104, 173, + 170, 111, 61, 248, 153, 92, 14, 203, + 133, 64, 18, 215, 182, 115, 33, 228, + 227, 38, 116, 177, 208, 21, 71, 130, + 73, 140, 222, 27, 122, 191, 237, 40, + 47, 234, 184, 125, 28, 217, 139, 78, + 23, 210, 128, 69, 36, 225, 179, 118, + 113, 180, 230, 35, 66, 135, 213, 16, + 219, 30, 76, 137, 232, 45, 127, 186, + 189, 120, 42, 239, 142, 75, 25, 220, + 146, 87, 5, 192, 161, 100, 54, 243, + 244, 49, 99, 166, 199, 2, 80, 149, + 94, 155, 201, 12, 109, 168, 250, 63, + 56, 253, 175, 106, 11, 206, 156, 89, + 46, 235, 185, 124, 29, 216, 138, 79, + 72, 141, 223, 26, 123, 190, 236, 41, + 226, 39, 117, 176, 209, 20, 70, 131, + 132, 65, 19, 214, 183, 114, 32, 229, + 171, 110, 60, 249, 152, 93, 15, 202, + 205, 8, 90, 159, 254, 59, 105, 172, + 103, 162, 240, 53, 84, 145, 195, 6, + 1, 196, 150, 83, 50, 247, 165, 96, + 57, 252, 174, 107, 10, 207, 157, 88, + 95, 154, 200, 13, 108, 169, 251, 62, + 245, 48, 98, 167, 198, 3, 81, 148, + 147, 86, 4, 193, 160, 101, 55, 242, + 188, 121, 43, 238, 143, 74, 24, 221, + 218, 31, 77, 136, 233, 44, 126, 187, + 112, 181, 231, 34, 67, 134, 212, 17, + 22, 211, 129, 68, 37, 224, 178, 119 }, + { 0, 198, 145, 87, 63, 249, 174, 104, + 126, 184, 239, 41, 65, 135, 208, 22, + 252, 58, 109, 171, 195, 5, 82, 148, + 130, 68, 19, 213, 189, 123, 44, 234, + 229, 35, 116, 178, 218, 28, 75, 141, + 155, 93, 10, 204, 164, 98, 53, 243, + 25, 223, 136, 78, 38, 224, 183, 113, + 103, 161, 246, 48, 88, 158, 201, 15, + 215, 17, 70, 128, 232, 46, 121, 191, + 169, 111, 56, 254, 150, 80, 7, 193, + 43, 237, 186, 124, 20, 210, 133, 67, + 85, 147, 196, 2, 106, 172, 251, 61, + 50, 244, 163, 101, 13, 203, 156, 90, + 76, 138, 221, 27, 115, 181, 226, 36, + 206, 8, 95, 153, 241, 55, 96, 166, + 176, 118, 33, 231, 143, 73, 30, 216, + 179, 117, 34, 228, 140, 74, 29, 219, + 205, 11, 92, 154, 242, 52, 99, 165, + 79, 137, 222, 24, 112, 182, 225, 39, + 49, 247, 160, 102, 14, 200, 159, 89, + 86, 144, 199, 1, 105, 175, 248, 62, + 40, 238, 185, 127, 23, 209, 134, 64, + 170, 108, 59, 253, 149, 83, 4, 194, + 212, 18, 69, 131, 235, 45, 122, 188, + 100, 162, 245, 51, 91, 157, 202, 12, + 26, 220, 139, 77, 37, 227, 180, 114, + 152, 94, 9, 207, 167, 97, 54, 240, + 230, 32, 119, 177, 217, 31, 72, 142, + 129, 71, 16, 214, 190, 120, 47, 233, + 255, 57, 110, 168, 192, 6, 81, 151, + 125, 187, 236, 42, 66, 132, 211, 21, + 3, 197, 146, 84, 60, 250, 173, 107 }, + { 0, 199, 147, 84, 59, 252, 168, 111, + 118, 177, 229, 34, 77, 138, 222, 25, + 236, 43, 127, 184, 215, 16, 68, 131, + 154, 93, 9, 206, 161, 102, 50, 245, + 197, 2, 86, 145, 254, 57, 109, 170, + 179, 116, 32, 231, 136, 79, 27, 220, + 41, 238, 186, 125, 18, 213, 129, 70, + 95, 152, 204, 11, 100, 163, 247, 48, + 151, 80, 4, 195, 172, 107, 63, 248, + 225, 38, 114, 181, 218, 29, 73, 142, + 123, 188, 232, 47, 64, 135, 211, 20, + 13, 202, 158, 89, 54, 241, 165, 98, + 82, 149, 193, 6, 105, 174, 250, 61, + 36, 227, 183, 112, 31, 216, 140, 75, + 190, 121, 45, 234, 133, 66, 22, 209, + 200, 15, 91, 156, 243, 52, 96, 167, + 51, 244, 160, 103, 8, 207, 155, 92, + 69, 130, 214, 17, 126, 185, 237, 42, + 223, 24, 76, 139, 228, 35, 119, 176, + 169, 110, 58, 253, 146, 85, 1, 198, + 246, 49, 101, 162, 205, 10, 94, 153, + 128, 71, 19, 212, 187, 124, 40, 239, + 26, 221, 137, 78, 33, 230, 178, 117, + 108, 171, 255, 56, 87, 144, 196, 3, + 164, 99, 55, 240, 159, 88, 12, 203, + 210, 21, 65, 134, 233, 46, 122, 189, + 72, 143, 219, 28, 115, 180, 224, 39, + 62, 249, 173, 106, 5, 194, 150, 81, + 97, 166, 242, 53, 90, 157, 201, 14, + 23, 208, 132, 67, 44, 235, 191, 120, + 141, 74, 30, 217, 182, 113, 37, 226, + 251, 60, 104, 175, 192, 7, 83, 148 }, + { 0, 200, 141, 69, 7, 207, 138, 66, + 14, 198, 131, 75, 9, 193, 132, 76, + 28, 212, 145, 89, 27, 211, 150, 94, + 18, 218, 159, 87, 21, 221, 152, 80, + 56, 240, 181, 125, 63, 247, 178, 122, + 54, 254, 187, 115, 49, 249, 188, 116, + 36, 236, 169, 97, 35, 235, 174, 102, + 42, 226, 167, 111, 45, 229, 160, 104, + 112, 184, 253, 53, 119, 191, 250, 50, + 126, 182, 243, 59, 121, 177, 244, 60, + 108, 164, 225, 41, 107, 163, 230, 46, + 98, 170, 239, 39, 101, 173, 232, 32, + 72, 128, 197, 13, 79, 135, 194, 10, + 70, 142, 203, 3, 65, 137, 204, 4, + 84, 156, 217, 17, 83, 155, 222, 22, + 90, 146, 215, 31, 93, 149, 208, 24, + 224, 40, 109, 165, 231, 47, 106, 162, + 238, 38, 99, 171, 233, 33, 100, 172, + 252, 52, 113, 185, 251, 51, 118, 190, + 242, 58, 127, 183, 245, 61, 120, 176, + 216, 16, 85, 157, 223, 23, 82, 154, + 214, 30, 91, 147, 209, 25, 92, 148, + 196, 12, 73, 129, 195, 11, 78, 134, + 202, 2, 71, 143, 205, 5, 64, 136, + 144, 88, 29, 213, 151, 95, 26, 210, + 158, 86, 19, 219, 153, 81, 20, 220, + 140, 68, 1, 201, 139, 67, 6, 206, + 130, 74, 15, 199, 133, 77, 8, 192, + 168, 96, 37, 237, 175, 103, 34, 234, + 166, 110, 43, 227, 161, 105, 44, 228, + 180, 124, 57, 241, 179, 123, 62, 246, + 186, 114, 55, 255, 189, 117, 48, 248 }, + { 0, 201, 143, 70, 3, 202, 140, 69, + 6, 207, 137, 64, 5, 204, 138, 67, + 12, 197, 131, 74, 15, 198, 128, 73, + 10, 195, 133, 76, 9, 192, 134, 79, + 24, 209, 151, 94, 27, 210, 148, 93, + 30, 215, 145, 88, 29, 212, 146, 91, + 20, 221, 155, 82, 23, 222, 152, 81, + 18, 219, 157, 84, 17, 216, 158, 87, + 48, 249, 191, 118, 51, 250, 188, 117, + 54, 255, 185, 112, 53, 252, 186, 115, + 60, 245, 179, 122, 63, 246, 176, 121, + 58, 243, 181, 124, 57, 240, 182, 127, + 40, 225, 167, 110, 43, 226, 164, 109, + 46, 231, 161, 104, 45, 228, 162, 107, + 36, 237, 171, 98, 39, 238, 168, 97, + 34, 235, 173, 100, 33, 232, 174, 103, + 96, 169, 239, 38, 99, 170, 236, 37, + 102, 175, 233, 32, 101, 172, 234, 35, + 108, 165, 227, 42, 111, 166, 224, 41, + 106, 163, 229, 44, 105, 160, 230, 47, + 120, 177, 247, 62, 123, 178, 244, 61, + 126, 183, 241, 56, 125, 180, 242, 59, + 116, 189, 251, 50, 119, 190, 248, 49, + 114, 187, 253, 52, 113, 184, 254, 55, + 80, 153, 223, 22, 83, 154, 220, 21, + 86, 159, 217, 16, 85, 156, 218, 19, + 92, 149, 211, 26, 95, 150, 208, 25, + 90, 147, 213, 28, 89, 144, 214, 31, + 72, 129, 199, 14, 75, 130, 196, 13, + 78, 135, 193, 8, 77, 132, 194, 11, + 68, 141, 203, 2, 71, 142, 200, 1, + 66, 139, 205, 4, 65, 136, 206, 7 }, + { 0, 202, 137, 67, 15, 197, 134, 76, + 30, 212, 151, 93, 17, 219, 152, 82, + 60, 246, 181, 127, 51, 249, 186, 112, + 34, 232, 171, 97, 45, 231, 164, 110, + 120, 178, 241, 59, 119, 189, 254, 52, + 102, 172, 239, 37, 105, 163, 224, 42, + 68, 142, 205, 7, 75, 129, 194, 8, + 90, 144, 211, 25, 85, 159, 220, 22, + 240, 58, 121, 179, 255, 53, 118, 188, + 238, 36, 103, 173, 225, 43, 104, 162, + 204, 6, 69, 143, 195, 9, 74, 128, + 210, 24, 91, 145, 221, 23, 84, 158, + 136, 66, 1, 203, 135, 77, 14, 196, + 150, 92, 31, 213, 153, 83, 16, 218, + 180, 126, 61, 247, 187, 113, 50, 248, + 170, 96, 35, 233, 165, 111, 44, 230, + 253, 55, 116, 190, 242, 56, 123, 177, + 227, 41, 106, 160, 236, 38, 101, 175, + 193, 11, 72, 130, 206, 4, 71, 141, + 223, 21, 86, 156, 208, 26, 89, 147, + 133, 79, 12, 198, 138, 64, 3, 201, + 155, 81, 18, 216, 148, 94, 29, 215, + 185, 115, 48, 250, 182, 124, 63, 245, + 167, 109, 46, 228, 168, 98, 33, 235, + 13, 199, 132, 78, 2, 200, 139, 65, + 19, 217, 154, 80, 28, 214, 149, 95, + 49, 251, 184, 114, 62, 244, 183, 125, + 47, 229, 166, 108, 32, 234, 169, 99, + 117, 191, 252, 54, 122, 176, 243, 57, + 107, 161, 226, 40, 100, 174, 237, 39, + 73, 131, 192, 10, 70, 140, 207, 5, + 87, 157, 222, 20, 88, 146, 209, 27 }, + { 0, 203, 139, 64, 11, 192, 128, 75, + 22, 221, 157, 86, 29, 214, 150, 93, + 44, 231, 167, 108, 39, 236, 172, 103, + 58, 241, 177, 122, 49, 250, 186, 113, + 88, 147, 211, 24, 83, 152, 216, 19, + 78, 133, 197, 14, 69, 142, 206, 5, + 116, 191, 255, 52, 127, 180, 244, 63, + 98, 169, 233, 34, 105, 162, 226, 41, + 176, 123, 59, 240, 187, 112, 48, 251, + 166, 109, 45, 230, 173, 102, 38, 237, + 156, 87, 23, 220, 151, 92, 28, 215, + 138, 65, 1, 202, 129, 74, 10, 193, + 232, 35, 99, 168, 227, 40, 104, 163, + 254, 53, 117, 190, 245, 62, 126, 181, + 196, 15, 79, 132, 207, 4, 68, 143, + 210, 25, 89, 146, 217, 18, 82, 153, + 125, 182, 246, 61, 118, 189, 253, 54, + 107, 160, 224, 43, 96, 171, 235, 32, + 81, 154, 218, 17, 90, 145, 209, 26, + 71, 140, 204, 7, 76, 135, 199, 12, + 37, 238, 174, 101, 46, 229, 165, 110, + 51, 248, 184, 115, 56, 243, 179, 120, + 9, 194, 130, 73, 2, 201, 137, 66, + 31, 212, 148, 95, 20, 223, 159, 84, + 205, 6, 70, 141, 198, 13, 77, 134, + 219, 16, 80, 155, 208, 27, 91, 144, + 225, 42, 106, 161, 234, 33, 97, 170, + 247, 60, 124, 183, 252, 55, 119, 188, + 149, 94, 30, 213, 158, 85, 21, 222, + 131, 72, 8, 195, 136, 67, 3, 200, + 185, 114, 50, 249, 178, 121, 57, 242, + 175, 100, 36, 239, 164, 111, 47, 228 }, + { 0, 204, 133, 73, 23, 219, 146, 94, + 46, 226, 171, 103, 57, 245, 188, 112, + 92, 144, 217, 21, 75, 135, 206, 2, + 114, 190, 247, 59, 101, 169, 224, 44, + 184, 116, 61, 241, 175, 99, 42, 230, + 150, 90, 19, 223, 129, 77, 4, 200, + 228, 40, 97, 173, 243, 63, 118, 186, + 202, 6, 79, 131, 221, 17, 88, 148, + 109, 161, 232, 36, 122, 182, 255, 51, + 67, 143, 198, 10, 84, 152, 209, 29, + 49, 253, 180, 120, 38, 234, 163, 111, + 31, 211, 154, 86, 8, 196, 141, 65, + 213, 25, 80, 156, 194, 14, 71, 139, + 251, 55, 126, 178, 236, 32, 105, 165, + 137, 69, 12, 192, 158, 82, 27, 215, + 167, 107, 34, 238, 176, 124, 53, 249, + 218, 22, 95, 147, 205, 1, 72, 132, + 244, 56, 113, 189, 227, 47, 102, 170, + 134, 74, 3, 207, 145, 93, 20, 216, + 168, 100, 45, 225, 191, 115, 58, 246, + 98, 174, 231, 43, 117, 185, 240, 60, + 76, 128, 201, 5, 91, 151, 222, 18, + 62, 242, 187, 119, 41, 229, 172, 96, + 16, 220, 149, 89, 7, 203, 130, 78, + 183, 123, 50, 254, 160, 108, 37, 233, + 153, 85, 28, 208, 142, 66, 11, 199, + 235, 39, 110, 162, 252, 48, 121, 181, + 197, 9, 64, 140, 210, 30, 87, 155, + 15, 195, 138, 70, 24, 212, 157, 81, + 33, 237, 164, 104, 54, 250, 179, 127, + 83, 159, 214, 26, 68, 136, 193, 13, + 125, 177, 248, 52, 106, 166, 239, 35 }, + { 0, 205, 135, 74, 19, 222, 148, 89, + 38, 235, 161, 108, 53, 248, 178, 127, + 76, 129, 203, 6, 95, 146, 216, 21, + 106, 167, 237, 32, 121, 180, 254, 51, + 152, 85, 31, 210, 139, 70, 12, 193, + 190, 115, 57, 244, 173, 96, 42, 231, + 212, 25, 83, 158, 199, 10, 64, 141, + 242, 63, 117, 184, 225, 44, 102, 171, + 45, 224, 170, 103, 62, 243, 185, 116, + 11, 198, 140, 65, 24, 213, 159, 82, + 97, 172, 230, 43, 114, 191, 245, 56, + 71, 138, 192, 13, 84, 153, 211, 30, + 181, 120, 50, 255, 166, 107, 33, 236, + 147, 94, 20, 217, 128, 77, 7, 202, + 249, 52, 126, 179, 234, 39, 109, 160, + 223, 18, 88, 149, 204, 1, 75, 134, + 90, 151, 221, 16, 73, 132, 206, 3, + 124, 177, 251, 54, 111, 162, 232, 37, + 22, 219, 145, 92, 5, 200, 130, 79, + 48, 253, 183, 122, 35, 238, 164, 105, + 194, 15, 69, 136, 209, 28, 86, 155, + 228, 41, 99, 174, 247, 58, 112, 189, + 142, 67, 9, 196, 157, 80, 26, 215, + 168, 101, 47, 226, 187, 118, 60, 241, + 119, 186, 240, 61, 100, 169, 227, 46, + 81, 156, 214, 27, 66, 143, 197, 8, + 59, 246, 188, 113, 40, 229, 175, 98, + 29, 208, 154, 87, 14, 195, 137, 68, + 239, 34, 104, 165, 252, 49, 123, 182, + 201, 4, 78, 131, 218, 23, 93, 144, + 163, 110, 36, 233, 176, 125, 55, 250, + 133, 72, 2, 207, 150, 91, 17, 220 }, + { 0, 206, 129, 79, 31, 209, 158, 80, + 62, 240, 191, 113, 33, 239, 160, 110, + 124, 178, 253, 51, 99, 173, 226, 44, + 66, 140, 195, 13, 93, 147, 220, 18, + 248, 54, 121, 183, 231, 41, 102, 168, + 198, 8, 71, 137, 217, 23, 88, 150, + 132, 74, 5, 203, 155, 85, 26, 212, + 186, 116, 59, 245, 165, 107, 36, 234, + 237, 35, 108, 162, 242, 60, 115, 189, + 211, 29, 82, 156, 204, 2, 77, 131, + 145, 95, 16, 222, 142, 64, 15, 193, + 175, 97, 46, 224, 176, 126, 49, 255, + 21, 219, 148, 90, 10, 196, 139, 69, + 43, 229, 170, 100, 52, 250, 181, 123, + 105, 167, 232, 38, 118, 184, 247, 57, + 87, 153, 214, 24, 72, 134, 201, 7, + 199, 9, 70, 136, 216, 22, 89, 151, + 249, 55, 120, 182, 230, 40, 103, 169, + 187, 117, 58, 244, 164, 106, 37, 235, + 133, 75, 4, 202, 154, 84, 27, 213, + 63, 241, 190, 112, 32, 238, 161, 111, + 1, 207, 128, 78, 30, 208, 159, 81, + 67, 141, 194, 12, 92, 146, 221, 19, + 125, 179, 252, 50, 98, 172, 227, 45, + 42, 228, 171, 101, 53, 251, 180, 122, + 20, 218, 149, 91, 11, 197, 138, 68, + 86, 152, 215, 25, 73, 135, 200, 6, + 104, 166, 233, 39, 119, 185, 246, 56, + 210, 28, 83, 157, 205, 3, 76, 130, + 236, 34, 109, 163, 243, 61, 114, 188, + 174, 96, 47, 225, 177, 127, 48, 254, + 144, 94, 17, 223, 143, 65, 14, 192 }, + { 0, 207, 131, 76, 27, 212, 152, 87, + 54, 249, 181, 122, 45, 226, 174, 97, + 108, 163, 239, 32, 119, 184, 244, 59, + 90, 149, 217, 22, 65, 142, 194, 13, + 216, 23, 91, 148, 195, 12, 64, 143, + 238, 33, 109, 162, 245, 58, 118, 185, + 180, 123, 55, 248, 175, 96, 44, 227, + 130, 77, 1, 206, 153, 86, 26, 213, + 173, 98, 46, 225, 182, 121, 53, 250, + 155, 84, 24, 215, 128, 79, 3, 204, + 193, 14, 66, 141, 218, 21, 89, 150, + 247, 56, 116, 187, 236, 35, 111, 160, + 117, 186, 246, 57, 110, 161, 237, 34, + 67, 140, 192, 15, 88, 151, 219, 20, + 25, 214, 154, 85, 2, 205, 129, 78, + 47, 224, 172, 99, 52, 251, 183, 120, + 71, 136, 196, 11, 92, 147, 223, 16, + 113, 190, 242, 61, 106, 165, 233, 38, + 43, 228, 168, 103, 48, 255, 179, 124, + 29, 210, 158, 81, 6, 201, 133, 74, + 159, 80, 28, 211, 132, 75, 7, 200, + 169, 102, 42, 229, 178, 125, 49, 254, + 243, 60, 112, 191, 232, 39, 107, 164, + 197, 10, 70, 137, 222, 17, 93, 146, + 234, 37, 105, 166, 241, 62, 114, 189, + 220, 19, 95, 144, 199, 8, 68, 139, + 134, 73, 5, 202, 157, 82, 30, 209, + 176, 127, 51, 252, 171, 100, 40, 231, + 50, 253, 177, 126, 41, 230, 170, 101, + 4, 203, 135, 72, 31, 208, 156, 83, + 94, 145, 221, 18, 69, 138, 198, 9, + 104, 167, 235, 36, 115, 188, 240, 63 }, + { 0, 208, 189, 109, 103, 183, 218, 10, + 206, 30, 115, 163, 169, 121, 20, 196, + 129, 81, 60, 236, 230, 54, 91, 139, + 79, 159, 242, 34, 40, 248, 149, 69, + 31, 207, 162, 114, 120, 168, 197, 21, + 209, 1, 108, 188, 182, 102, 11, 219, + 158, 78, 35, 243, 249, 41, 68, 148, + 80, 128, 237, 61, 55, 231, 138, 90, + 62, 238, 131, 83, 89, 137, 228, 52, + 240, 32, 77, 157, 151, 71, 42, 250, + 191, 111, 2, 210, 216, 8, 101, 181, + 113, 161, 204, 28, 22, 198, 171, 123, + 33, 241, 156, 76, 70, 150, 251, 43, + 239, 63, 82, 130, 136, 88, 53, 229, + 160, 112, 29, 205, 199, 23, 122, 170, + 110, 190, 211, 3, 9, 217, 180, 100, + 124, 172, 193, 17, 27, 203, 166, 118, + 178, 98, 15, 223, 213, 5, 104, 184, + 253, 45, 64, 144, 154, 74, 39, 247, + 51, 227, 142, 94, 84, 132, 233, 57, + 99, 179, 222, 14, 4, 212, 185, 105, + 173, 125, 16, 192, 202, 26, 119, 167, + 226, 50, 95, 143, 133, 85, 56, 232, + 44, 252, 145, 65, 75, 155, 246, 38, + 66, 146, 255, 47, 37, 245, 152, 72, + 140, 92, 49, 225, 235, 59, 86, 134, + 195, 19, 126, 174, 164, 116, 25, 201, + 13, 221, 176, 96, 106, 186, 215, 7, + 93, 141, 224, 48, 58, 234, 135, 87, + 147, 67, 46, 254, 244, 36, 73, 153, + 220, 12, 97, 177, 187, 107, 6, 214, + 18, 194, 175, 127, 117, 165, 200, 24 }, + { 0, 209, 191, 110, 99, 178, 220, 13, + 198, 23, 121, 168, 165, 116, 26, 203, + 145, 64, 46, 255, 242, 35, 77, 156, + 87, 134, 232, 57, 52, 229, 139, 90, + 63, 238, 128, 81, 92, 141, 227, 50, + 249, 40, 70, 151, 154, 75, 37, 244, + 174, 127, 17, 192, 205, 28, 114, 163, + 104, 185, 215, 6, 11, 218, 180, 101, + 126, 175, 193, 16, 29, 204, 162, 115, + 184, 105, 7, 214, 219, 10, 100, 181, + 239, 62, 80, 129, 140, 93, 51, 226, + 41, 248, 150, 71, 74, 155, 245, 36, + 65, 144, 254, 47, 34, 243, 157, 76, + 135, 86, 56, 233, 228, 53, 91, 138, + 208, 1, 111, 190, 179, 98, 12, 221, + 22, 199, 169, 120, 117, 164, 202, 27, + 252, 45, 67, 146, 159, 78, 32, 241, + 58, 235, 133, 84, 89, 136, 230, 55, + 109, 188, 210, 3, 14, 223, 177, 96, + 171, 122, 20, 197, 200, 25, 119, 166, + 195, 18, 124, 173, 160, 113, 31, 206, + 5, 212, 186, 107, 102, 183, 217, 8, + 82, 131, 237, 60, 49, 224, 142, 95, + 148, 69, 43, 250, 247, 38, 72, 153, + 130, 83, 61, 236, 225, 48, 94, 143, + 68, 149, 251, 42, 39, 246, 152, 73, + 19, 194, 172, 125, 112, 161, 207, 30, + 213, 4, 106, 187, 182, 103, 9, 216, + 189, 108, 2, 211, 222, 15, 97, 176, + 123, 170, 196, 21, 24, 201, 167, 118, + 44, 253, 147, 66, 79, 158, 240, 33, + 234, 59, 85, 132, 137, 88, 54, 231 }, + { 0, 210, 185, 107, 111, 189, 214, 4, + 222, 12, 103, 181, 177, 99, 8, 218, + 161, 115, 24, 202, 206, 28, 119, 165, + 127, 173, 198, 20, 16, 194, 169, 123, + 95, 141, 230, 52, 48, 226, 137, 91, + 129, 83, 56, 234, 238, 60, 87, 133, + 254, 44, 71, 149, 145, 67, 40, 250, + 32, 242, 153, 75, 79, 157, 246, 36, + 190, 108, 7, 213, 209, 3, 104, 186, + 96, 178, 217, 11, 15, 221, 182, 100, + 31, 205, 166, 116, 112, 162, 201, 27, + 193, 19, 120, 170, 174, 124, 23, 197, + 225, 51, 88, 138, 142, 92, 55, 229, + 63, 237, 134, 84, 80, 130, 233, 59, + 64, 146, 249, 43, 47, 253, 150, 68, + 158, 76, 39, 245, 241, 35, 72, 154, + 97, 179, 216, 10, 14, 220, 183, 101, + 191, 109, 6, 212, 208, 2, 105, 187, + 192, 18, 121, 171, 175, 125, 22, 196, + 30, 204, 167, 117, 113, 163, 200, 26, + 62, 236, 135, 85, 81, 131, 232, 58, + 224, 50, 89, 139, 143, 93, 54, 228, + 159, 77, 38, 244, 240, 34, 73, 155, + 65, 147, 248, 42, 46, 252, 151, 69, + 223, 13, 102, 180, 176, 98, 9, 219, + 1, 211, 184, 106, 110, 188, 215, 5, + 126, 172, 199, 21, 17, 195, 168, 122, + 160, 114, 25, 203, 207, 29, 118, 164, + 128, 82, 57, 235, 239, 61, 86, 132, + 94, 140, 231, 53, 49, 227, 136, 90, + 33, 243, 152, 74, 78, 156, 247, 37, + 255, 45, 70, 148, 144, 66, 41, 251 }, + { 0, 211, 187, 104, 107, 184, 208, 3, + 214, 5, 109, 190, 189, 110, 6, 213, + 177, 98, 10, 217, 218, 9, 97, 178, + 103, 180, 220, 15, 12, 223, 183, 100, + 127, 172, 196, 23, 20, 199, 175, 124, + 169, 122, 18, 193, 194, 17, 121, 170, + 206, 29, 117, 166, 165, 118, 30, 205, + 24, 203, 163, 112, 115, 160, 200, 27, + 254, 45, 69, 150, 149, 70, 46, 253, + 40, 251, 147, 64, 67, 144, 248, 43, + 79, 156, 244, 39, 36, 247, 159, 76, + 153, 74, 34, 241, 242, 33, 73, 154, + 129, 82, 58, 233, 234, 57, 81, 130, + 87, 132, 236, 63, 60, 239, 135, 84, + 48, 227, 139, 88, 91, 136, 224, 51, + 230, 53, 93, 142, 141, 94, 54, 229, + 225, 50, 90, 137, 138, 89, 49, 226, + 55, 228, 140, 95, 92, 143, 231, 52, + 80, 131, 235, 56, 59, 232, 128, 83, + 134, 85, 61, 238, 237, 62, 86, 133, + 158, 77, 37, 246, 245, 38, 78, 157, + 72, 155, 243, 32, 35, 240, 152, 75, + 47, 252, 148, 71, 68, 151, 255, 44, + 249, 42, 66, 145, 146, 65, 41, 250, + 31, 204, 164, 119, 116, 167, 207, 28, + 201, 26, 114, 161, 162, 113, 25, 202, + 174, 125, 21, 198, 197, 22, 126, 173, + 120, 171, 195, 16, 19, 192, 168, 123, + 96, 179, 219, 8, 11, 216, 176, 99, + 182, 101, 13, 222, 221, 14, 102, 181, + 209, 2, 106, 185, 186, 105, 1, 210, + 7, 212, 188, 111, 108, 191, 215, 4 }, + { 0, 212, 181, 97, 119, 163, 194, 22, + 238, 58, 91, 143, 153, 77, 44, 248, + 193, 21, 116, 160, 182, 98, 3, 215, + 47, 251, 154, 78, 88, 140, 237, 57, + 159, 75, 42, 254, 232, 60, 93, 137, + 113, 165, 196, 16, 6, 210, 179, 103, + 94, 138, 235, 63, 41, 253, 156, 72, + 176, 100, 5, 209, 199, 19, 114, 166, + 35, 247, 150, 66, 84, 128, 225, 53, + 205, 25, 120, 172, 186, 110, 15, 219, + 226, 54, 87, 131, 149, 65, 32, 244, + 12, 216, 185, 109, 123, 175, 206, 26, + 188, 104, 9, 221, 203, 31, 126, 170, + 82, 134, 231, 51, 37, 241, 144, 68, + 125, 169, 200, 28, 10, 222, 191, 107, + 147, 71, 38, 242, 228, 48, 81, 133, + 70, 146, 243, 39, 49, 229, 132, 80, + 168, 124, 29, 201, 223, 11, 106, 190, + 135, 83, 50, 230, 240, 36, 69, 145, + 105, 189, 220, 8, 30, 202, 171, 127, + 217, 13, 108, 184, 174, 122, 27, 207, + 55, 227, 130, 86, 64, 148, 245, 33, + 24, 204, 173, 121, 111, 187, 218, 14, + 246, 34, 67, 151, 129, 85, 52, 224, + 101, 177, 208, 4, 18, 198, 167, 115, + 139, 95, 62, 234, 252, 40, 73, 157, + 164, 112, 17, 197, 211, 7, 102, 178, + 74, 158, 255, 43, 61, 233, 136, 92, + 250, 46, 79, 155, 141, 89, 56, 236, + 20, 192, 161, 117, 99, 183, 214, 2, + 59, 239, 142, 90, 76, 152, 249, 45, + 213, 1, 96, 180, 162, 118, 23, 195 }, + { 0, 213, 183, 98, 115, 166, 196, 17, + 230, 51, 81, 132, 149, 64, 34, 247, + 209, 4, 102, 179, 162, 119, 21, 192, + 55, 226, 128, 85, 68, 145, 243, 38, + 191, 106, 8, 221, 204, 25, 123, 174, + 89, 140, 238, 59, 42, 255, 157, 72, + 110, 187, 217, 12, 29, 200, 170, 127, + 136, 93, 63, 234, 251, 46, 76, 153, + 99, 182, 212, 1, 16, 197, 167, 114, + 133, 80, 50, 231, 246, 35, 65, 148, + 178, 103, 5, 208, 193, 20, 118, 163, + 84, 129, 227, 54, 39, 242, 144, 69, + 220, 9, 107, 190, 175, 122, 24, 205, + 58, 239, 141, 88, 73, 156, 254, 43, + 13, 216, 186, 111, 126, 171, 201, 28, + 235, 62, 92, 137, 152, 77, 47, 250, + 198, 19, 113, 164, 181, 96, 2, 215, + 32, 245, 151, 66, 83, 134, 228, 49, + 23, 194, 160, 117, 100, 177, 211, 6, + 241, 36, 70, 147, 130, 87, 53, 224, + 121, 172, 206, 27, 10, 223, 189, 104, + 159, 74, 40, 253, 236, 57, 91, 142, + 168, 125, 31, 202, 219, 14, 108, 185, + 78, 155, 249, 44, 61, 232, 138, 95, + 165, 112, 18, 199, 214, 3, 97, 180, + 67, 150, 244, 33, 48, 229, 135, 82, + 116, 161, 195, 22, 7, 210, 176, 101, + 146, 71, 37, 240, 225, 52, 86, 131, + 26, 207, 173, 120, 105, 188, 222, 11, + 252, 41, 75, 158, 143, 90, 56, 237, + 203, 30, 124, 169, 184, 109, 15, 218, + 45, 248, 154, 79, 94, 139, 233, 60 }, + { 0, 214, 177, 103, 127, 169, 206, 24, + 254, 40, 79, 153, 129, 87, 48, 230, + 225, 55, 80, 134, 158, 72, 47, 249, + 31, 201, 174, 120, 96, 182, 209, 7, + 223, 9, 110, 184, 160, 118, 17, 199, + 33, 247, 144, 70, 94, 136, 239, 57, + 62, 232, 143, 89, 65, 151, 240, 38, + 192, 22, 113, 167, 191, 105, 14, 216, + 163, 117, 18, 196, 220, 10, 109, 187, + 93, 139, 236, 58, 34, 244, 147, 69, + 66, 148, 243, 37, 61, 235, 140, 90, + 188, 106, 13, 219, 195, 21, 114, 164, + 124, 170, 205, 27, 3, 213, 178, 100, + 130, 84, 51, 229, 253, 43, 76, 154, + 157, 75, 44, 250, 226, 52, 83, 133, + 99, 181, 210, 4, 28, 202, 173, 123, + 91, 141, 234, 60, 36, 242, 149, 67, + 165, 115, 20, 194, 218, 12, 107, 189, + 186, 108, 11, 221, 197, 19, 116, 162, + 68, 146, 245, 35, 59, 237, 138, 92, + 132, 82, 53, 227, 251, 45, 74, 156, + 122, 172, 203, 29, 5, 211, 180, 98, + 101, 179, 212, 2, 26, 204, 171, 125, + 155, 77, 42, 252, 228, 50, 85, 131, + 248, 46, 73, 159, 135, 81, 54, 224, + 6, 208, 183, 97, 121, 175, 200, 30, + 25, 207, 168, 126, 102, 176, 215, 1, + 231, 49, 86, 128, 152, 78, 41, 255, + 39, 241, 150, 64, 88, 142, 233, 63, + 217, 15, 104, 190, 166, 112, 23, 193, + 198, 16, 119, 161, 185, 111, 8, 222, + 56, 238, 137, 95, 71, 145, 246, 32 }, + { 0, 215, 179, 100, 123, 172, 200, 31, + 246, 33, 69, 146, 141, 90, 62, 233, + 241, 38, 66, 149, 138, 93, 57, 238, + 7, 208, 180, 99, 124, 171, 207, 24, + 255, 40, 76, 155, 132, 83, 55, 224, + 9, 222, 186, 109, 114, 165, 193, 22, + 14, 217, 189, 106, 117, 162, 198, 17, + 248, 47, 75, 156, 131, 84, 48, 231, + 227, 52, 80, 135, 152, 79, 43, 252, + 21, 194, 166, 113, 110, 185, 221, 10, + 18, 197, 161, 118, 105, 190, 218, 13, + 228, 51, 87, 128, 159, 72, 44, 251, + 28, 203, 175, 120, 103, 176, 212, 3, + 234, 61, 89, 142, 145, 70, 34, 245, + 237, 58, 94, 137, 150, 65, 37, 242, + 27, 204, 168, 127, 96, 183, 211, 4, + 219, 12, 104, 191, 160, 119, 19, 196, + 45, 250, 158, 73, 86, 129, 229, 50, + 42, 253, 153, 78, 81, 134, 226, 53, + 220, 11, 111, 184, 167, 112, 20, 195, + 36, 243, 151, 64, 95, 136, 236, 59, + 210, 5, 97, 182, 169, 126, 26, 205, + 213, 2, 102, 177, 174, 121, 29, 202, + 35, 244, 144, 71, 88, 143, 235, 60, + 56, 239, 139, 92, 67, 148, 240, 39, + 206, 25, 125, 170, 181, 98, 6, 209, + 201, 30, 122, 173, 178, 101, 1, 214, + 63, 232, 140, 91, 68, 147, 247, 32, + 199, 16, 116, 163, 188, 107, 15, 216, + 49, 230, 130, 85, 74, 157, 249, 46, + 54, 225, 133, 82, 77, 154, 254, 41, + 192, 23, 115, 164, 187, 108, 8, 223 }, + { 0, 216, 173, 117, 71, 159, 234, 50, + 142, 86, 35, 251, 201, 17, 100, 188, + 1, 217, 172, 116, 70, 158, 235, 51, + 143, 87, 34, 250, 200, 16, 101, 189, + 2, 218, 175, 119, 69, 157, 232, 48, + 140, 84, 33, 249, 203, 19, 102, 190, + 3, 219, 174, 118, 68, 156, 233, 49, + 141, 85, 32, 248, 202, 18, 103, 191, + 4, 220, 169, 113, 67, 155, 238, 54, + 138, 82, 39, 255, 205, 21, 96, 184, + 5, 221, 168, 112, 66, 154, 239, 55, + 139, 83, 38, 254, 204, 20, 97, 185, + 6, 222, 171, 115, 65, 153, 236, 52, + 136, 80, 37, 253, 207, 23, 98, 186, + 7, 223, 170, 114, 64, 152, 237, 53, + 137, 81, 36, 252, 206, 22, 99, 187, + 8, 208, 165, 125, 79, 151, 226, 58, + 134, 94, 43, 243, 193, 25, 108, 180, + 9, 209, 164, 124, 78, 150, 227, 59, + 135, 95, 42, 242, 192, 24, 109, 181, + 10, 210, 167, 127, 77, 149, 224, 56, + 132, 92, 41, 241, 195, 27, 110, 182, + 11, 211, 166, 126, 76, 148, 225, 57, + 133, 93, 40, 240, 194, 26, 111, 183, + 12, 212, 161, 121, 75, 147, 230, 62, + 130, 90, 47, 247, 197, 29, 104, 176, + 13, 213, 160, 120, 74, 146, 231, 63, + 131, 91, 46, 246, 196, 28, 105, 177, + 14, 214, 163, 123, 73, 145, 228, 60, + 128, 88, 45, 245, 199, 31, 106, 178, + 15, 215, 162, 122, 72, 144, 229, 61, + 129, 89, 44, 244, 198, 30, 107, 179 }, + { 0, 217, 175, 118, 67, 154, 236, 53, + 134, 95, 41, 240, 197, 28, 106, 179, + 17, 200, 190, 103, 82, 139, 253, 36, + 151, 78, 56, 225, 212, 13, 123, 162, + 34, 251, 141, 84, 97, 184, 206, 23, + 164, 125, 11, 210, 231, 62, 72, 145, + 51, 234, 156, 69, 112, 169, 223, 6, + 181, 108, 26, 195, 246, 47, 89, 128, + 68, 157, 235, 50, 7, 222, 168, 113, + 194, 27, 109, 180, 129, 88, 46, 247, + 85, 140, 250, 35, 22, 207, 185, 96, + 211, 10, 124, 165, 144, 73, 63, 230, + 102, 191, 201, 16, 37, 252, 138, 83, + 224, 57, 79, 150, 163, 122, 12, 213, + 119, 174, 216, 1, 52, 237, 155, 66, + 241, 40, 94, 135, 178, 107, 29, 196, + 136, 81, 39, 254, 203, 18, 100, 189, + 14, 215, 161, 120, 77, 148, 226, 59, + 153, 64, 54, 239, 218, 3, 117, 172, + 31, 198, 176, 105, 92, 133, 243, 42, + 170, 115, 5, 220, 233, 48, 70, 159, + 44, 245, 131, 90, 111, 182, 192, 25, + 187, 98, 20, 205, 248, 33, 87, 142, + 61, 228, 146, 75, 126, 167, 209, 8, + 204, 21, 99, 186, 143, 86, 32, 249, + 74, 147, 229, 60, 9, 208, 166, 127, + 221, 4, 114, 171, 158, 71, 49, 232, + 91, 130, 244, 45, 24, 193, 183, 110, + 238, 55, 65, 152, 173, 116, 2, 219, + 104, 177, 199, 30, 43, 242, 132, 93, + 255, 38, 80, 137, 188, 101, 19, 202, + 121, 160, 214, 15, 58, 227, 149, 76 }, + { 0, 218, 169, 115, 79, 149, 230, 60, + 158, 68, 55, 237, 209, 11, 120, 162, + 33, 251, 136, 82, 110, 180, 199, 29, + 191, 101, 22, 204, 240, 42, 89, 131, + 66, 152, 235, 49, 13, 215, 164, 126, + 220, 6, 117, 175, 147, 73, 58, 224, + 99, 185, 202, 16, 44, 246, 133, 95, + 253, 39, 84, 142, 178, 104, 27, 193, + 132, 94, 45, 247, 203, 17, 98, 184, + 26, 192, 179, 105, 85, 143, 252, 38, + 165, 127, 12, 214, 234, 48, 67, 153, + 59, 225, 146, 72, 116, 174, 221, 7, + 198, 28, 111, 181, 137, 83, 32, 250, + 88, 130, 241, 43, 23, 205, 190, 100, + 231, 61, 78, 148, 168, 114, 1, 219, + 121, 163, 208, 10, 54, 236, 159, 69, + 21, 207, 188, 102, 90, 128, 243, 41, + 139, 81, 34, 248, 196, 30, 109, 183, + 52, 238, 157, 71, 123, 161, 210, 8, + 170, 112, 3, 217, 229, 63, 76, 150, + 87, 141, 254, 36, 24, 194, 177, 107, + 201, 19, 96, 186, 134, 92, 47, 245, + 118, 172, 223, 5, 57, 227, 144, 74, + 232, 50, 65, 155, 167, 125, 14, 212, + 145, 75, 56, 226, 222, 4, 119, 173, + 15, 213, 166, 124, 64, 154, 233, 51, + 176, 106, 25, 195, 255, 37, 86, 140, + 46, 244, 135, 93, 97, 187, 200, 18, + 211, 9, 122, 160, 156, 70, 53, 239, + 77, 151, 228, 62, 2, 216, 171, 113, + 242, 40, 91, 129, 189, 103, 20, 206, + 108, 182, 197, 31, 35, 249, 138, 80 }, + { 0, 219, 171, 112, 75, 144, 224, 59, + 150, 77, 61, 230, 221, 6, 118, 173, + 49, 234, 154, 65, 122, 161, 209, 10, + 167, 124, 12, 215, 236, 55, 71, 156, + 98, 185, 201, 18, 41, 242, 130, 89, + 244, 47, 95, 132, 191, 100, 20, 207, + 83, 136, 248, 35, 24, 195, 179, 104, + 197, 30, 110, 181, 142, 85, 37, 254, + 196, 31, 111, 180, 143, 84, 36, 255, + 82, 137, 249, 34, 25, 194, 178, 105, + 245, 46, 94, 133, 190, 101, 21, 206, + 99, 184, 200, 19, 40, 243, 131, 88, + 166, 125, 13, 214, 237, 54, 70, 157, + 48, 235, 155, 64, 123, 160, 208, 11, + 151, 76, 60, 231, 220, 7, 119, 172, + 1, 218, 170, 113, 74, 145, 225, 58, + 149, 78, 62, 229, 222, 5, 117, 174, + 3, 216, 168, 115, 72, 147, 227, 56, + 164, 127, 15, 212, 239, 52, 68, 159, + 50, 233, 153, 66, 121, 162, 210, 9, + 247, 44, 92, 135, 188, 103, 23, 204, + 97, 186, 202, 17, 42, 241, 129, 90, + 198, 29, 109, 182, 141, 86, 38, 253, + 80, 139, 251, 32, 27, 192, 176, 107, + 81, 138, 250, 33, 26, 193, 177, 106, + 199, 28, 108, 183, 140, 87, 39, 252, + 96, 187, 203, 16, 43, 240, 128, 91, + 246, 45, 93, 134, 189, 102, 22, 205, + 51, 232, 152, 67, 120, 163, 211, 8, + 165, 126, 14, 213, 238, 53, 69, 158, + 2, 217, 169, 114, 73, 146, 226, 57, + 148, 79, 63, 228, 223, 4, 116, 175 }, + { 0, 220, 165, 121, 87, 139, 242, 46, + 174, 114, 11, 215, 249, 37, 92, 128, + 65, 157, 228, 56, 22, 202, 179, 111, + 239, 51, 74, 150, 184, 100, 29, 193, + 130, 94, 39, 251, 213, 9, 112, 172, + 44, 240, 137, 85, 123, 167, 222, 2, + 195, 31, 102, 186, 148, 72, 49, 237, + 109, 177, 200, 20, 58, 230, 159, 67, + 25, 197, 188, 96, 78, 146, 235, 55, + 183, 107, 18, 206, 224, 60, 69, 153, + 88, 132, 253, 33, 15, 211, 170, 118, + 246, 42, 83, 143, 161, 125, 4, 216, + 155, 71, 62, 226, 204, 16, 105, 181, + 53, 233, 144, 76, 98, 190, 199, 27, + 218, 6, 127, 163, 141, 81, 40, 244, + 116, 168, 209, 13, 35, 255, 134, 90, + 50, 238, 151, 75, 101, 185, 192, 28, + 156, 64, 57, 229, 203, 23, 110, 178, + 115, 175, 214, 10, 36, 248, 129, 93, + 221, 1, 120, 164, 138, 86, 47, 243, + 176, 108, 21, 201, 231, 59, 66, 158, + 30, 194, 187, 103, 73, 149, 236, 48, + 241, 45, 84, 136, 166, 122, 3, 223, + 95, 131, 250, 38, 8, 212, 173, 113, + 43, 247, 142, 82, 124, 160, 217, 5, + 133, 89, 32, 252, 210, 14, 119, 171, + 106, 182, 207, 19, 61, 225, 152, 68, + 196, 24, 97, 189, 147, 79, 54, 234, + 169, 117, 12, 208, 254, 34, 91, 135, + 7, 219, 162, 126, 80, 140, 245, 41, + 232, 52, 77, 145, 191, 99, 26, 198, + 70, 154, 227, 63, 17, 205, 180, 104 }, + { 0, 221, 167, 122, 83, 142, 244, 41, + 166, 123, 1, 220, 245, 40, 82, 143, + 81, 140, 246, 43, 2, 223, 165, 120, + 247, 42, 80, 141, 164, 121, 3, 222, + 162, 127, 5, 216, 241, 44, 86, 139, + 4, 217, 163, 126, 87, 138, 240, 45, + 243, 46, 84, 137, 160, 125, 7, 218, + 85, 136, 242, 47, 6, 219, 161, 124, + 89, 132, 254, 35, 10, 215, 173, 112, + 255, 34, 88, 133, 172, 113, 11, 214, + 8, 213, 175, 114, 91, 134, 252, 33, + 174, 115, 9, 212, 253, 32, 90, 135, + 251, 38, 92, 129, 168, 117, 15, 210, + 93, 128, 250, 39, 14, 211, 169, 116, + 170, 119, 13, 208, 249, 36, 94, 131, + 12, 209, 171, 118, 95, 130, 248, 37, + 178, 111, 21, 200, 225, 60, 70, 155, + 20, 201, 179, 110, 71, 154, 224, 61, + 227, 62, 68, 153, 176, 109, 23, 202, + 69, 152, 226, 63, 22, 203, 177, 108, + 16, 205, 183, 106, 67, 158, 228, 57, + 182, 107, 17, 204, 229, 56, 66, 159, + 65, 156, 230, 59, 18, 207, 181, 104, + 231, 58, 64, 157, 180, 105, 19, 206, + 235, 54, 76, 145, 184, 101, 31, 194, + 77, 144, 234, 55, 30, 195, 185, 100, + 186, 103, 29, 192, 233, 52, 78, 147, + 28, 193, 187, 102, 79, 146, 232, 53, + 73, 148, 238, 51, 26, 199, 189, 96, + 239, 50, 72, 149, 188, 97, 27, 198, + 24, 197, 191, 98, 75, 150, 236, 49, + 190, 99, 25, 196, 237, 48, 74, 151 }, + { 0, 222, 161, 127, 95, 129, 254, 32, + 190, 96, 31, 193, 225, 63, 64, 158, + 97, 191, 192, 30, 62, 224, 159, 65, + 223, 1, 126, 160, 128, 94, 33, 255, + 194, 28, 99, 189, 157, 67, 60, 226, + 124, 162, 221, 3, 35, 253, 130, 92, + 163, 125, 2, 220, 252, 34, 93, 131, + 29, 195, 188, 98, 66, 156, 227, 61, + 153, 71, 56, 230, 198, 24, 103, 185, + 39, 249, 134, 88, 120, 166, 217, 7, + 248, 38, 89, 135, 167, 121, 6, 216, + 70, 152, 231, 57, 25, 199, 184, 102, + 91, 133, 250, 36, 4, 218, 165, 123, + 229, 59, 68, 154, 186, 100, 27, 197, + 58, 228, 155, 69, 101, 187, 196, 26, + 132, 90, 37, 251, 219, 5, 122, 164, + 47, 241, 142, 80, 112, 174, 209, 15, + 145, 79, 48, 238, 206, 16, 111, 177, + 78, 144, 239, 49, 17, 207, 176, 110, + 240, 46, 81, 143, 175, 113, 14, 208, + 237, 51, 76, 146, 178, 108, 19, 205, + 83, 141, 242, 44, 12, 210, 173, 115, + 140, 82, 45, 243, 211, 13, 114, 172, + 50, 236, 147, 77, 109, 179, 204, 18, + 182, 104, 23, 201, 233, 55, 72, 150, + 8, 214, 169, 119, 87, 137, 246, 40, + 215, 9, 118, 168, 136, 86, 41, 247, + 105, 183, 200, 22, 54, 232, 151, 73, + 116, 170, 213, 11, 43, 245, 138, 84, + 202, 20, 107, 181, 149, 75, 52, 234, + 21, 203, 180, 106, 74, 148, 235, 53, + 171, 117, 10, 212, 244, 42, 85, 139 }, + { 0, 223, 163, 124, 91, 132, 248, 39, + 182, 105, 21, 202, 237, 50, 78, 145, + 113, 174, 210, 13, 42, 245, 137, 86, + 199, 24, 100, 187, 156, 67, 63, 224, + 226, 61, 65, 158, 185, 102, 26, 197, + 84, 139, 247, 40, 15, 208, 172, 115, + 147, 76, 48, 239, 200, 23, 107, 180, + 37, 250, 134, 89, 126, 161, 221, 2, + 217, 6, 122, 165, 130, 93, 33, 254, + 111, 176, 204, 19, 52, 235, 151, 72, + 168, 119, 11, 212, 243, 44, 80, 143, + 30, 193, 189, 98, 69, 154, 230, 57, + 59, 228, 152, 71, 96, 191, 195, 28, + 141, 82, 46, 241, 214, 9, 117, 170, + 74, 149, 233, 54, 17, 206, 178, 109, + 252, 35, 95, 128, 167, 120, 4, 219, + 175, 112, 12, 211, 244, 43, 87, 136, + 25, 198, 186, 101, 66, 157, 225, 62, + 222, 1, 125, 162, 133, 90, 38, 249, + 104, 183, 203, 20, 51, 236, 144, 79, + 77, 146, 238, 49, 22, 201, 181, 106, + 251, 36, 88, 135, 160, 127, 3, 220, + 60, 227, 159, 64, 103, 184, 196, 27, + 138, 85, 41, 246, 209, 14, 114, 173, + 118, 169, 213, 10, 45, 242, 142, 81, + 192, 31, 99, 188, 155, 68, 56, 231, + 7, 216, 164, 123, 92, 131, 255, 32, + 177, 110, 18, 205, 234, 53, 73, 150, + 148, 75, 55, 232, 207, 16, 108, 179, + 34, 253, 129, 94, 121, 166, 218, 5, + 229, 58, 70, 153, 190, 97, 29, 194, + 83, 140, 240, 47, 8, 215, 171, 116 }, + { 0, 224, 221, 61, 167, 71, 122, 154, + 83, 179, 142, 110, 244, 20, 41, 201, + 166, 70, 123, 155, 1, 225, 220, 60, + 245, 21, 40, 200, 82, 178, 143, 111, + 81, 177, 140, 108, 246, 22, 43, 203, + 2, 226, 223, 63, 165, 69, 120, 152, + 247, 23, 42, 202, 80, 176, 141, 109, + 164, 68, 121, 153, 3, 227, 222, 62, + 162, 66, 127, 159, 5, 229, 216, 56, + 241, 17, 44, 204, 86, 182, 139, 107, + 4, 228, 217, 57, 163, 67, 126, 158, + 87, 183, 138, 106, 240, 16, 45, 205, + 243, 19, 46, 206, 84, 180, 137, 105, + 160, 64, 125, 157, 7, 231, 218, 58, + 85, 181, 136, 104, 242, 18, 47, 207, + 6, 230, 219, 59, 161, 65, 124, 156, + 89, 185, 132, 100, 254, 30, 35, 195, + 10, 234, 215, 55, 173, 77, 112, 144, + 255, 31, 34, 194, 88, 184, 133, 101, + 172, 76, 113, 145, 11, 235, 214, 54, + 8, 232, 213, 53, 175, 79, 114, 146, + 91, 187, 134, 102, 252, 28, 33, 193, + 174, 78, 115, 147, 9, 233, 212, 52, + 253, 29, 32, 192, 90, 186, 135, 103, + 251, 27, 38, 198, 92, 188, 129, 97, + 168, 72, 117, 149, 15, 239, 210, 50, + 93, 189, 128, 96, 250, 26, 39, 199, + 14, 238, 211, 51, 169, 73, 116, 148, + 170, 74, 119, 151, 13, 237, 208, 48, + 249, 25, 36, 196, 94, 190, 131, 99, + 12, 236, 209, 49, 171, 75, 118, 150, + 95, 191, 130, 98, 248, 24, 37, 197 }, + { 0, 225, 223, 62, 163, 66, 124, 157, + 91, 186, 132, 101, 248, 25, 39, 198, + 182, 87, 105, 136, 21, 244, 202, 43, + 237, 12, 50, 211, 78, 175, 145, 112, + 113, 144, 174, 79, 210, 51, 13, 236, + 42, 203, 245, 20, 137, 104, 86, 183, + 199, 38, 24, 249, 100, 133, 187, 90, + 156, 125, 67, 162, 63, 222, 224, 1, + 226, 3, 61, 220, 65, 160, 158, 127, + 185, 88, 102, 135, 26, 251, 197, 36, + 84, 181, 139, 106, 247, 22, 40, 201, + 15, 238, 208, 49, 172, 77, 115, 146, + 147, 114, 76, 173, 48, 209, 239, 14, + 200, 41, 23, 246, 107, 138, 180, 85, + 37, 196, 250, 27, 134, 103, 89, 184, + 126, 159, 161, 64, 221, 60, 2, 227, + 217, 56, 6, 231, 122, 155, 165, 68, + 130, 99, 93, 188, 33, 192, 254, 31, + 111, 142, 176, 81, 204, 45, 19, 242, + 52, 213, 235, 10, 151, 118, 72, 169, + 168, 73, 119, 150, 11, 234, 212, 53, + 243, 18, 44, 205, 80, 177, 143, 110, + 30, 255, 193, 32, 189, 92, 98, 131, + 69, 164, 154, 123, 230, 7, 57, 216, + 59, 218, 228, 5, 152, 121, 71, 166, + 96, 129, 191, 94, 195, 34, 28, 253, + 141, 108, 82, 179, 46, 207, 241, 16, + 214, 55, 9, 232, 117, 148, 170, 75, + 74, 171, 149, 116, 233, 8, 54, 215, + 17, 240, 206, 47, 178, 83, 109, 140, + 252, 29, 35, 194, 95, 190, 128, 97, + 167, 70, 120, 153, 4, 229, 219, 58 }, + { 0, 226, 217, 59, 175, 77, 118, 148, + 67, 161, 154, 120, 236, 14, 53, 215, + 134, 100, 95, 189, 41, 203, 240, 18, + 197, 39, 28, 254, 106, 136, 179, 81, + 17, 243, 200, 42, 190, 92, 103, 133, + 82, 176, 139, 105, 253, 31, 36, 198, + 151, 117, 78, 172, 56, 218, 225, 3, + 212, 54, 13, 239, 123, 153, 162, 64, + 34, 192, 251, 25, 141, 111, 84, 182, + 97, 131, 184, 90, 206, 44, 23, 245, + 164, 70, 125, 159, 11, 233, 210, 48, + 231, 5, 62, 220, 72, 170, 145, 115, + 51, 209, 234, 8, 156, 126, 69, 167, + 112, 146, 169, 75, 223, 61, 6, 228, + 181, 87, 108, 142, 26, 248, 195, 33, + 246, 20, 47, 205, 89, 187, 128, 98, + 68, 166, 157, 127, 235, 9, 50, 208, + 7, 229, 222, 60, 168, 74, 113, 147, + 194, 32, 27, 249, 109, 143, 180, 86, + 129, 99, 88, 186, 46, 204, 247, 21, + 85, 183, 140, 110, 250, 24, 35, 193, + 22, 244, 207, 45, 185, 91, 96, 130, + 211, 49, 10, 232, 124, 158, 165, 71, + 144, 114, 73, 171, 63, 221, 230, 4, + 102, 132, 191, 93, 201, 43, 16, 242, + 37, 199, 252, 30, 138, 104, 83, 177, + 224, 2, 57, 219, 79, 173, 150, 116, + 163, 65, 122, 152, 12, 238, 213, 55, + 119, 149, 174, 76, 216, 58, 1, 227, + 52, 214, 237, 15, 155, 121, 66, 160, + 241, 19, 40, 202, 94, 188, 135, 101, + 178, 80, 107, 137, 29, 255, 196, 38 }, + { 0, 227, 219, 56, 171, 72, 112, 147, + 75, 168, 144, 115, 224, 3, 59, 216, + 150, 117, 77, 174, 61, 222, 230, 5, + 221, 62, 6, 229, 118, 149, 173, 78, + 49, 210, 234, 9, 154, 121, 65, 162, + 122, 153, 161, 66, 209, 50, 10, 233, + 167, 68, 124, 159, 12, 239, 215, 52, + 236, 15, 55, 212, 71, 164, 156, 127, + 98, 129, 185, 90, 201, 42, 18, 241, + 41, 202, 242, 17, 130, 97, 89, 186, + 244, 23, 47, 204, 95, 188, 132, 103, + 191, 92, 100, 135, 20, 247, 207, 44, + 83, 176, 136, 107, 248, 27, 35, 192, + 24, 251, 195, 32, 179, 80, 104, 139, + 197, 38, 30, 253, 110, 141, 181, 86, + 142, 109, 85, 182, 37, 198, 254, 29, + 196, 39, 31, 252, 111, 140, 180, 87, + 143, 108, 84, 183, 36, 199, 255, 28, + 82, 177, 137, 106, 249, 26, 34, 193, + 25, 250, 194, 33, 178, 81, 105, 138, + 245, 22, 46, 205, 94, 189, 133, 102, + 190, 93, 101, 134, 21, 246, 206, 45, + 99, 128, 184, 91, 200, 43, 19, 240, + 40, 203, 243, 16, 131, 96, 88, 187, + 166, 69, 125, 158, 13, 238, 214, 53, + 237, 14, 54, 213, 70, 165, 157, 126, + 48, 211, 235, 8, 155, 120, 64, 163, + 123, 152, 160, 67, 208, 51, 11, 232, + 151, 116, 76, 175, 60, 223, 231, 4, + 220, 63, 7, 228, 119, 148, 172, 79, + 1, 226, 218, 57, 170, 73, 113, 146, + 74, 169, 145, 114, 225, 2, 58, 217 }, + { 0, 228, 213, 49, 183, 83, 98, 134, + 115, 151, 166, 66, 196, 32, 17, 245, + 230, 2, 51, 215, 81, 181, 132, 96, + 149, 113, 64, 164, 34, 198, 247, 19, + 209, 53, 4, 224, 102, 130, 179, 87, + 162, 70, 119, 147, 21, 241, 192, 36, + 55, 211, 226, 6, 128, 100, 85, 177, + 68, 160, 145, 117, 243, 23, 38, 194, + 191, 91, 106, 142, 8, 236, 221, 57, + 204, 40, 25, 253, 123, 159, 174, 74, + 89, 189, 140, 104, 238, 10, 59, 223, + 42, 206, 255, 27, 157, 121, 72, 172, + 110, 138, 187, 95, 217, 61, 12, 232, + 29, 249, 200, 44, 170, 78, 127, 155, + 136, 108, 93, 185, 63, 219, 234, 14, + 251, 31, 46, 202, 76, 168, 153, 125, + 99, 135, 182, 82, 212, 48, 1, 229, + 16, 244, 197, 33, 167, 67, 114, 150, + 133, 97, 80, 180, 50, 214, 231, 3, + 246, 18, 35, 199, 65, 165, 148, 112, + 178, 86, 103, 131, 5, 225, 208, 52, + 193, 37, 20, 240, 118, 146, 163, 71, + 84, 176, 129, 101, 227, 7, 54, 210, + 39, 195, 242, 22, 144, 116, 69, 161, + 220, 56, 9, 237, 107, 143, 190, 90, + 175, 75, 122, 158, 24, 252, 205, 41, + 58, 222, 239, 11, 141, 105, 88, 188, + 73, 173, 156, 120, 254, 26, 43, 207, + 13, 233, 216, 60, 186, 94, 111, 139, + 126, 154, 171, 79, 201, 45, 28, 248, + 235, 15, 62, 218, 92, 184, 137, 109, + 152, 124, 77, 169, 47, 203, 250, 30 }, + { 0, 229, 215, 50, 179, 86, 100, 129, + 123, 158, 172, 73, 200, 45, 31, 250, + 246, 19, 33, 196, 69, 160, 146, 119, + 141, 104, 90, 191, 62, 219, 233, 12, + 241, 20, 38, 195, 66, 167, 149, 112, + 138, 111, 93, 184, 57, 220, 238, 11, + 7, 226, 208, 53, 180, 81, 99, 134, + 124, 153, 171, 78, 207, 42, 24, 253, + 255, 26, 40, 205, 76, 169, 155, 126, + 132, 97, 83, 182, 55, 210, 224, 5, + 9, 236, 222, 59, 186, 95, 109, 136, + 114, 151, 165, 64, 193, 36, 22, 243, + 14, 235, 217, 60, 189, 88, 106, 143, + 117, 144, 162, 71, 198, 35, 17, 244, + 248, 29, 47, 202, 75, 174, 156, 121, + 131, 102, 84, 177, 48, 213, 231, 2, + 227, 6, 52, 209, 80, 181, 135, 98, + 152, 125, 79, 170, 43, 206, 252, 25, + 21, 240, 194, 39, 166, 67, 113, 148, + 110, 139, 185, 92, 221, 56, 10, 239, + 18, 247, 197, 32, 161, 68, 118, 147, + 105, 140, 190, 91, 218, 63, 13, 232, + 228, 1, 51, 214, 87, 178, 128, 101, + 159, 122, 72, 173, 44, 201, 251, 30, + 28, 249, 203, 46, 175, 74, 120, 157, + 103, 130, 176, 85, 212, 49, 3, 230, + 234, 15, 61, 216, 89, 188, 142, 107, + 145, 116, 70, 163, 34, 199, 245, 16, + 237, 8, 58, 223, 94, 187, 137, 108, + 150, 115, 65, 164, 37, 192, 242, 23, + 27, 254, 204, 41, 168, 77, 127, 154, + 96, 133, 183, 82, 211, 54, 4, 225 }, + { 0, 230, 209, 55, 191, 89, 110, 136, + 99, 133, 178, 84, 220, 58, 13, 235, + 198, 32, 23, 241, 121, 159, 168, 78, + 165, 67, 116, 146, 26, 252, 203, 45, + 145, 119, 64, 166, 46, 200, 255, 25, + 242, 20, 35, 197, 77, 171, 156, 122, + 87, 177, 134, 96, 232, 14, 57, 223, + 52, 210, 229, 3, 139, 109, 90, 188, + 63, 217, 238, 8, 128, 102, 81, 183, + 92, 186, 141, 107, 227, 5, 50, 212, + 249, 31, 40, 206, 70, 160, 151, 113, + 154, 124, 75, 173, 37, 195, 244, 18, + 174, 72, 127, 153, 17, 247, 192, 38, + 205, 43, 28, 250, 114, 148, 163, 69, + 104, 142, 185, 95, 215, 49, 6, 224, + 11, 237, 218, 60, 180, 82, 101, 131, + 126, 152, 175, 73, 193, 39, 16, 246, + 29, 251, 204, 42, 162, 68, 115, 149, + 184, 94, 105, 143, 7, 225, 214, 48, + 219, 61, 10, 236, 100, 130, 181, 83, + 239, 9, 62, 216, 80, 182, 129, 103, + 140, 106, 93, 187, 51, 213, 226, 4, + 41, 207, 248, 30, 150, 112, 71, 161, + 74, 172, 155, 125, 245, 19, 36, 194, + 65, 167, 144, 118, 254, 24, 47, 201, + 34, 196, 243, 21, 157, 123, 76, 170, + 135, 97, 86, 176, 56, 222, 233, 15, + 228, 2, 53, 211, 91, 189, 138, 108, + 208, 54, 1, 231, 111, 137, 190, 88, + 179, 85, 98, 132, 12, 234, 221, 59, + 22, 240, 199, 33, 169, 79, 120, 158, + 117, 147, 164, 66, 202, 44, 27, 253 }, + { 0, 231, 211, 52, 187, 92, 104, 143, + 107, 140, 184, 95, 208, 55, 3, 228, + 214, 49, 5, 226, 109, 138, 190, 89, + 189, 90, 110, 137, 6, 225, 213, 50, + 177, 86, 98, 133, 10, 237, 217, 62, + 218, 61, 9, 238, 97, 134, 178, 85, + 103, 128, 180, 83, 220, 59, 15, 232, + 12, 235, 223, 56, 183, 80, 100, 131, + 127, 152, 172, 75, 196, 35, 23, 240, + 20, 243, 199, 32, 175, 72, 124, 155, + 169, 78, 122, 157, 18, 245, 193, 38, + 194, 37, 17, 246, 121, 158, 170, 77, + 206, 41, 29, 250, 117, 146, 166, 65, + 165, 66, 118, 145, 30, 249, 205, 42, + 24, 255, 203, 44, 163, 68, 112, 151, + 115, 148, 160, 71, 200, 47, 27, 252, + 254, 25, 45, 202, 69, 162, 150, 113, + 149, 114, 70, 161, 46, 201, 253, 26, + 40, 207, 251, 28, 147, 116, 64, 167, + 67, 164, 144, 119, 248, 31, 43, 204, + 79, 168, 156, 123, 244, 19, 39, 192, + 36, 195, 247, 16, 159, 120, 76, 171, + 153, 126, 74, 173, 34, 197, 241, 22, + 242, 21, 33, 198, 73, 174, 154, 125, + 129, 102, 82, 181, 58, 221, 233, 14, + 234, 13, 57, 222, 81, 182, 130, 101, + 87, 176, 132, 99, 236, 11, 63, 216, + 60, 219, 239, 8, 135, 96, 84, 179, + 48, 215, 227, 4, 139, 108, 88, 191, + 91, 188, 136, 111, 224, 7, 51, 212, + 230, 1, 53, 210, 93, 186, 142, 105, + 141, 106, 94, 185, 54, 209, 229, 2 }, + { 0, 232, 205, 37, 135, 111, 74, 162, + 19, 251, 222, 54, 148, 124, 89, 177, + 38, 206, 235, 3, 161, 73, 108, 132, + 53, 221, 248, 16, 178, 90, 127, 151, + 76, 164, 129, 105, 203, 35, 6, 238, + 95, 183, 146, 122, 216, 48, 21, 253, + 106, 130, 167, 79, 237, 5, 32, 200, + 121, 145, 180, 92, 254, 22, 51, 219, + 152, 112, 85, 189, 31, 247, 210, 58, + 139, 99, 70, 174, 12, 228, 193, 41, + 190, 86, 115, 155, 57, 209, 244, 28, + 173, 69, 96, 136, 42, 194, 231, 15, + 212, 60, 25, 241, 83, 187, 158, 118, + 199, 47, 10, 226, 64, 168, 141, 101, + 242, 26, 63, 215, 117, 157, 184, 80, + 225, 9, 44, 196, 102, 142, 171, 67, + 45, 197, 224, 8, 170, 66, 103, 143, + 62, 214, 243, 27, 185, 81, 116, 156, + 11, 227, 198, 46, 140, 100, 65, 169, + 24, 240, 213, 61, 159, 119, 82, 186, + 97, 137, 172, 68, 230, 14, 43, 195, + 114, 154, 191, 87, 245, 29, 56, 208, + 71, 175, 138, 98, 192, 40, 13, 229, + 84, 188, 153, 113, 211, 59, 30, 246, + 181, 93, 120, 144, 50, 218, 255, 23, + 166, 78, 107, 131, 33, 201, 236, 4, + 147, 123, 94, 182, 20, 252, 217, 49, + 128, 104, 77, 165, 7, 239, 202, 34, + 249, 17, 52, 220, 126, 150, 179, 91, + 234, 2, 39, 207, 109, 133, 160, 72, + 223, 55, 18, 250, 88, 176, 149, 125, + 204, 36, 1, 233, 75, 163, 134, 110 }, + { 0, 233, 207, 38, 131, 106, 76, 165, + 27, 242, 212, 61, 152, 113, 87, 190, + 54, 223, 249, 16, 181, 92, 122, 147, + 45, 196, 226, 11, 174, 71, 97, 136, + 108, 133, 163, 74, 239, 6, 32, 201, + 119, 158, 184, 81, 244, 29, 59, 210, + 90, 179, 149, 124, 217, 48, 22, 255, + 65, 168, 142, 103, 194, 43, 13, 228, + 216, 49, 23, 254, 91, 178, 148, 125, + 195, 42, 12, 229, 64, 169, 143, 102, + 238, 7, 33, 200, 109, 132, 162, 75, + 245, 28, 58, 211, 118, 159, 185, 80, + 180, 93, 123, 146, 55, 222, 248, 17, + 175, 70, 96, 137, 44, 197, 227, 10, + 130, 107, 77, 164, 1, 232, 206, 39, + 153, 112, 86, 191, 26, 243, 213, 60, + 173, 68, 98, 139, 46, 199, 225, 8, + 182, 95, 121, 144, 53, 220, 250, 19, + 155, 114, 84, 189, 24, 241, 215, 62, + 128, 105, 79, 166, 3, 234, 204, 37, + 193, 40, 14, 231, 66, 171, 141, 100, + 218, 51, 21, 252, 89, 176, 150, 127, + 247, 30, 56, 209, 116, 157, 187, 82, + 236, 5, 35, 202, 111, 134, 160, 73, + 117, 156, 186, 83, 246, 31, 57, 208, + 110, 135, 161, 72, 237, 4, 34, 203, + 67, 170, 140, 101, 192, 41, 15, 230, + 88, 177, 151, 126, 219, 50, 20, 253, + 25, 240, 214, 63, 154, 115, 85, 188, + 2, 235, 205, 36, 129, 104, 78, 167, + 47, 198, 224, 9, 172, 69, 99, 138, + 52, 221, 251, 18, 183, 94, 120, 145 }, + { 0, 234, 201, 35, 143, 101, 70, 172, + 3, 233, 202, 32, 140, 102, 69, 175, + 6, 236, 207, 37, 137, 99, 64, 170, + 5, 239, 204, 38, 138, 96, 67, 169, + 12, 230, 197, 47, 131, 105, 74, 160, + 15, 229, 198, 44, 128, 106, 73, 163, + 10, 224, 195, 41, 133, 111, 76, 166, + 9, 227, 192, 42, 134, 108, 79, 165, + 24, 242, 209, 59, 151, 125, 94, 180, + 27, 241, 210, 56, 148, 126, 93, 183, + 30, 244, 215, 61, 145, 123, 88, 178, + 29, 247, 212, 62, 146, 120, 91, 177, + 20, 254, 221, 55, 155, 113, 82, 184, + 23, 253, 222, 52, 152, 114, 81, 187, + 18, 248, 219, 49, 157, 119, 84, 190, + 17, 251, 216, 50, 158, 116, 87, 189, + 48, 218, 249, 19, 191, 85, 118, 156, + 51, 217, 250, 16, 188, 86, 117, 159, + 54, 220, 255, 21, 185, 83, 112, 154, + 53, 223, 252, 22, 186, 80, 115, 153, + 60, 214, 245, 31, 179, 89, 122, 144, + 63, 213, 246, 28, 176, 90, 121, 147, + 58, 208, 243, 25, 181, 95, 124, 150, + 57, 211, 240, 26, 182, 92, 127, 149, + 40, 194, 225, 11, 167, 77, 110, 132, + 43, 193, 226, 8, 164, 78, 109, 135, + 46, 196, 231, 13, 161, 75, 104, 130, + 45, 199, 228, 14, 162, 72, 107, 129, + 36, 206, 237, 7, 171, 65, 98, 136, + 39, 205, 238, 4, 168, 66, 97, 139, + 34, 200, 235, 1, 173, 71, 100, 142, + 33, 203, 232, 2, 174, 68, 103, 141 }, + { 0, 235, 203, 32, 139, 96, 64, 171, + 11, 224, 192, 43, 128, 107, 75, 160, + 22, 253, 221, 54, 157, 118, 86, 189, + 29, 246, 214, 61, 150, 125, 93, 182, + 44, 199, 231, 12, 167, 76, 108, 135, + 39, 204, 236, 7, 172, 71, 103, 140, + 58, 209, 241, 26, 177, 90, 122, 145, + 49, 218, 250, 17, 186, 81, 113, 154, + 88, 179, 147, 120, 211, 56, 24, 243, + 83, 184, 152, 115, 216, 51, 19, 248, + 78, 165, 133, 110, 197, 46, 14, 229, + 69, 174, 142, 101, 206, 37, 5, 238, + 116, 159, 191, 84, 255, 20, 52, 223, + 127, 148, 180, 95, 244, 31, 63, 212, + 98, 137, 169, 66, 233, 2, 34, 201, + 105, 130, 162, 73, 226, 9, 41, 194, + 176, 91, 123, 144, 59, 208, 240, 27, + 187, 80, 112, 155, 48, 219, 251, 16, + 166, 77, 109, 134, 45, 198, 230, 13, + 173, 70, 102, 141, 38, 205, 237, 6, + 156, 119, 87, 188, 23, 252, 220, 55, + 151, 124, 92, 183, 28, 247, 215, 60, + 138, 97, 65, 170, 1, 234, 202, 33, + 129, 106, 74, 161, 10, 225, 193, 42, + 232, 3, 35, 200, 99, 136, 168, 67, + 227, 8, 40, 195, 104, 131, 163, 72, + 254, 21, 53, 222, 117, 158, 190, 85, + 245, 30, 62, 213, 126, 149, 181, 94, + 196, 47, 15, 228, 79, 164, 132, 111, + 207, 36, 4, 239, 68, 175, 143, 100, + 210, 57, 25, 242, 89, 178, 146, 121, + 217, 50, 18, 249, 82, 185, 153, 114 }, + { 0, 236, 197, 41, 151, 123, 82, 190, + 51, 223, 246, 26, 164, 72, 97, 141, + 102, 138, 163, 79, 241, 29, 52, 216, + 85, 185, 144, 124, 194, 46, 7, 235, + 204, 32, 9, 229, 91, 183, 158, 114, + 255, 19, 58, 214, 104, 132, 173, 65, + 170, 70, 111, 131, 61, 209, 248, 20, + 153, 117, 92, 176, 14, 226, 203, 39, + 133, 105, 64, 172, 18, 254, 215, 59, + 182, 90, 115, 159, 33, 205, 228, 8, + 227, 15, 38, 202, 116, 152, 177, 93, + 208, 60, 21, 249, 71, 171, 130, 110, + 73, 165, 140, 96, 222, 50, 27, 247, + 122, 150, 191, 83, 237, 1, 40, 196, + 47, 195, 234, 6, 184, 84, 125, 145, + 28, 240, 217, 53, 139, 103, 78, 162, + 23, 251, 210, 62, 128, 108, 69, 169, + 36, 200, 225, 13, 179, 95, 118, 154, + 113, 157, 180, 88, 230, 10, 35, 207, + 66, 174, 135, 107, 213, 57, 16, 252, + 219, 55, 30, 242, 76, 160, 137, 101, + 232, 4, 45, 193, 127, 147, 186, 86, + 189, 81, 120, 148, 42, 198, 239, 3, + 142, 98, 75, 167, 25, 245, 220, 48, + 146, 126, 87, 187, 5, 233, 192, 44, + 161, 77, 100, 136, 54, 218, 243, 31, + 244, 24, 49, 221, 99, 143, 166, 74, + 199, 43, 2, 238, 80, 188, 149, 121, + 94, 178, 155, 119, 201, 37, 12, 224, + 109, 129, 168, 68, 250, 22, 63, 211, + 56, 212, 253, 17, 175, 67, 106, 134, + 11, 231, 206, 34, 156, 112, 89, 181 }, + { 0, 237, 199, 42, 147, 126, 84, 185, + 59, 214, 252, 17, 168, 69, 111, 130, + 118, 155, 177, 92, 229, 8, 34, 207, + 77, 160, 138, 103, 222, 51, 25, 244, + 236, 1, 43, 198, 127, 146, 184, 85, + 215, 58, 16, 253, 68, 169, 131, 110, + 154, 119, 93, 176, 9, 228, 206, 35, + 161, 76, 102, 139, 50, 223, 245, 24, + 197, 40, 2, 239, 86, 187, 145, 124, + 254, 19, 57, 212, 109, 128, 170, 71, + 179, 94, 116, 153, 32, 205, 231, 10, + 136, 101, 79, 162, 27, 246, 220, 49, + 41, 196, 238, 3, 186, 87, 125, 144, + 18, 255, 213, 56, 129, 108, 70, 171, + 95, 178, 152, 117, 204, 33, 11, 230, + 100, 137, 163, 78, 247, 26, 48, 221, + 151, 122, 80, 189, 4, 233, 195, 46, + 172, 65, 107, 134, 63, 210, 248, 21, + 225, 12, 38, 203, 114, 159, 181, 88, + 218, 55, 29, 240, 73, 164, 142, 99, + 123, 150, 188, 81, 232, 5, 47, 194, + 64, 173, 135, 106, 211, 62, 20, 249, + 13, 224, 202, 39, 158, 115, 89, 180, + 54, 219, 241, 28, 165, 72, 98, 143, + 82, 191, 149, 120, 193, 44, 6, 235, + 105, 132, 174, 67, 250, 23, 61, 208, + 36, 201, 227, 14, 183, 90, 112, 157, + 31, 242, 216, 53, 140, 97, 75, 166, + 190, 83, 121, 148, 45, 192, 234, 7, + 133, 104, 66, 175, 22, 251, 209, 60, + 200, 37, 15, 226, 91, 182, 156, 113, + 243, 30, 52, 217, 96, 141, 167, 74 }, + { 0, 238, 193, 47, 159, 113, 94, 176, + 35, 205, 226, 12, 188, 82, 125, 147, + 70, 168, 135, 105, 217, 55, 24, 246, + 101, 139, 164, 74, 250, 20, 59, 213, + 140, 98, 77, 163, 19, 253, 210, 60, + 175, 65, 110, 128, 48, 222, 241, 31, + 202, 36, 11, 229, 85, 187, 148, 122, + 233, 7, 40, 198, 118, 152, 183, 89, + 5, 235, 196, 42, 154, 116, 91, 181, + 38, 200, 231, 9, 185, 87, 120, 150, + 67, 173, 130, 108, 220, 50, 29, 243, + 96, 142, 161, 79, 255, 17, 62, 208, + 137, 103, 72, 166, 22, 248, 215, 57, + 170, 68, 107, 133, 53, 219, 244, 26, + 207, 33, 14, 224, 80, 190, 145, 127, + 236, 2, 45, 195, 115, 157, 178, 92, + 10, 228, 203, 37, 149, 123, 84, 186, + 41, 199, 232, 6, 182, 88, 119, 153, + 76, 162, 141, 99, 211, 61, 18, 252, + 111, 129, 174, 64, 240, 30, 49, 223, + 134, 104, 71, 169, 25, 247, 216, 54, + 165, 75, 100, 138, 58, 212, 251, 21, + 192, 46, 1, 239, 95, 177, 158, 112, + 227, 13, 34, 204, 124, 146, 189, 83, + 15, 225, 206, 32, 144, 126, 81, 191, + 44, 194, 237, 3, 179, 93, 114, 156, + 73, 167, 136, 102, 214, 56, 23, 249, + 106, 132, 171, 69, 245, 27, 52, 218, + 131, 109, 66, 172, 28, 242, 221, 51, + 160, 78, 97, 143, 63, 209, 254, 16, + 197, 43, 4, 234, 90, 180, 155, 117, + 230, 8, 39, 201, 121, 151, 184, 86 }, + { 0, 239, 195, 44, 155, 116, 88, 183, + 43, 196, 232, 7, 176, 95, 115, 156, + 86, 185, 149, 122, 205, 34, 14, 225, + 125, 146, 190, 81, 230, 9, 37, 202, + 172, 67, 111, 128, 55, 216, 244, 27, + 135, 104, 68, 171, 28, 243, 223, 48, + 250, 21, 57, 214, 97, 142, 162, 77, + 209, 62, 18, 253, 74, 165, 137, 102, + 69, 170, 134, 105, 222, 49, 29, 242, + 110, 129, 173, 66, 245, 26, 54, 217, + 19, 252, 208, 63, 136, 103, 75, 164, + 56, 215, 251, 20, 163, 76, 96, 143, + 233, 6, 42, 197, 114, 157, 177, 94, + 194, 45, 1, 238, 89, 182, 154, 117, + 191, 80, 124, 147, 36, 203, 231, 8, + 148, 123, 87, 184, 15, 224, 204, 35, + 138, 101, 73, 166, 17, 254, 210, 61, + 161, 78, 98, 141, 58, 213, 249, 22, + 220, 51, 31, 240, 71, 168, 132, 107, + 247, 24, 52, 219, 108, 131, 175, 64, + 38, 201, 229, 10, 189, 82, 126, 145, + 13, 226, 206, 33, 150, 121, 85, 186, + 112, 159, 179, 92, 235, 4, 40, 199, + 91, 180, 152, 119, 192, 47, 3, 236, + 207, 32, 12, 227, 84, 187, 151, 120, + 228, 11, 39, 200, 127, 144, 188, 83, + 153, 118, 90, 181, 2, 237, 193, 46, + 178, 93, 113, 158, 41, 198, 234, 5, + 99, 140, 160, 79, 248, 23, 59, 212, + 72, 167, 139, 100, 211, 60, 16, 255, + 53, 218, 246, 25, 174, 65, 109, 130, + 30, 241, 221, 50, 133, 106, 70, 169 }, + { 0, 240, 253, 13, 231, 23, 26, 234, + 211, 35, 46, 222, 52, 196, 201, 57, + 187, 75, 70, 182, 92, 172, 161, 81, + 104, 152, 149, 101, 143, 127, 114, 130, + 107, 155, 150, 102, 140, 124, 113, 129, + 184, 72, 69, 181, 95, 175, 162, 82, + 208, 32, 45, 221, 55, 199, 202, 58, + 3, 243, 254, 14, 228, 20, 25, 233, + 214, 38, 43, 219, 49, 193, 204, 60, + 5, 245, 248, 8, 226, 18, 31, 239, + 109, 157, 144, 96, 138, 122, 119, 135, + 190, 78, 67, 179, 89, 169, 164, 84, + 189, 77, 64, 176, 90, 170, 167, 87, + 110, 158, 147, 99, 137, 121, 116, 132, + 6, 246, 251, 11, 225, 17, 28, 236, + 213, 37, 40, 216, 50, 194, 207, 63, + 177, 65, 76, 188, 86, 166, 171, 91, + 98, 146, 159, 111, 133, 117, 120, 136, + 10, 250, 247, 7, 237, 29, 16, 224, + 217, 41, 36, 212, 62, 206, 195, 51, + 218, 42, 39, 215, 61, 205, 192, 48, + 9, 249, 244, 4, 238, 30, 19, 227, + 97, 145, 156, 108, 134, 118, 123, 139, + 178, 66, 79, 191, 85, 165, 168, 88, + 103, 151, 154, 106, 128, 112, 125, 141, + 180, 68, 73, 185, 83, 163, 174, 94, + 220, 44, 33, 209, 59, 203, 198, 54, + 15, 255, 242, 2, 232, 24, 21, 229, + 12, 252, 241, 1, 235, 27, 22, 230, + 223, 47, 34, 210, 56, 200, 197, 53, + 183, 71, 74, 186, 80, 160, 173, 93, + 100, 148, 153, 105, 131, 115, 126, 142 }, + { 0, 241, 255, 14, 227, 18, 28, 237, + 219, 42, 36, 213, 56, 201, 199, 54, + 171, 90, 84, 165, 72, 185, 183, 70, + 112, 129, 143, 126, 147, 98, 108, 157, + 75, 186, 180, 69, 168, 89, 87, 166, + 144, 97, 111, 158, 115, 130, 140, 125, + 224, 17, 31, 238, 3, 242, 252, 13, + 59, 202, 196, 53, 216, 41, 39, 214, + 150, 103, 105, 152, 117, 132, 138, 123, + 77, 188, 178, 67, 174, 95, 81, 160, + 61, 204, 194, 51, 222, 47, 33, 208, + 230, 23, 25, 232, 5, 244, 250, 11, + 221, 44, 34, 211, 62, 207, 193, 48, + 6, 247, 249, 8, 229, 20, 26, 235, + 118, 135, 137, 120, 149, 100, 106, 155, + 173, 92, 82, 163, 78, 191, 177, 64, + 49, 192, 206, 63, 210, 35, 45, 220, + 234, 27, 21, 228, 9, 248, 246, 7, + 154, 107, 101, 148, 121, 136, 134, 119, + 65, 176, 190, 79, 162, 83, 93, 172, + 122, 139, 133, 116, 153, 104, 102, 151, + 161, 80, 94, 175, 66, 179, 189, 76, + 209, 32, 46, 223, 50, 195, 205, 60, + 10, 251, 245, 4, 233, 24, 22, 231, + 167, 86, 88, 169, 68, 181, 187, 74, + 124, 141, 131, 114, 159, 110, 96, 145, + 12, 253, 243, 2, 239, 30, 16, 225, + 215, 38, 40, 217, 52, 197, 203, 58, + 236, 29, 19, 226, 15, 254, 240, 1, + 55, 198, 200, 57, 212, 37, 43, 218, + 71, 182, 184, 73, 164, 85, 91, 170, + 156, 109, 99, 146, 127, 142, 128, 113 }, + { 0, 242, 249, 11, 239, 29, 22, 228, + 195, 49, 58, 200, 44, 222, 213, 39, + 155, 105, 98, 144, 116, 134, 141, 127, + 88, 170, 161, 83, 183, 69, 78, 188, + 43, 217, 210, 32, 196, 54, 61, 207, + 232, 26, 17, 227, 7, 245, 254, 12, + 176, 66, 73, 187, 95, 173, 166, 84, + 115, 129, 138, 120, 156, 110, 101, 151, + 86, 164, 175, 93, 185, 75, 64, 178, + 149, 103, 108, 158, 122, 136, 131, 113, + 205, 63, 52, 198, 34, 208, 219, 41, + 14, 252, 247, 5, 225, 19, 24, 234, + 125, 143, 132, 118, 146, 96, 107, 153, + 190, 76, 71, 181, 81, 163, 168, 90, + 230, 20, 31, 237, 9, 251, 240, 2, + 37, 215, 220, 46, 202, 56, 51, 193, + 172, 94, 85, 167, 67, 177, 186, 72, + 111, 157, 150, 100, 128, 114, 121, 139, + 55, 197, 206, 60, 216, 42, 33, 211, + 244, 6, 13, 255, 27, 233, 226, 16, + 135, 117, 126, 140, 104, 154, 145, 99, + 68, 182, 189, 79, 171, 89, 82, 160, + 28, 238, 229, 23, 243, 1, 10, 248, + 223, 45, 38, 212, 48, 194, 201, 59, + 250, 8, 3, 241, 21, 231, 236, 30, + 57, 203, 192, 50, 214, 36, 47, 221, + 97, 147, 152, 106, 142, 124, 119, 133, + 162, 80, 91, 169, 77, 191, 180, 70, + 209, 35, 40, 218, 62, 204, 199, 53, + 18, 224, 235, 25, 253, 15, 4, 246, + 74, 184, 179, 65, 165, 87, 92, 174, + 137, 123, 112, 130, 102, 148, 159, 109 }, + { 0, 243, 251, 8, 235, 24, 16, 227, + 203, 56, 48, 195, 32, 211, 219, 40, + 139, 120, 112, 131, 96, 147, 155, 104, + 64, 179, 187, 72, 171, 88, 80, 163, + 11, 248, 240, 3, 224, 19, 27, 232, + 192, 51, 59, 200, 43, 216, 208, 35, + 128, 115, 123, 136, 107, 152, 144, 99, + 75, 184, 176, 67, 160, 83, 91, 168, + 22, 229, 237, 30, 253, 14, 6, 245, + 221, 46, 38, 213, 54, 197, 205, 62, + 157, 110, 102, 149, 118, 133, 141, 126, + 86, 165, 173, 94, 189, 78, 70, 181, + 29, 238, 230, 21, 246, 5, 13, 254, + 214, 37, 45, 222, 61, 206, 198, 53, + 150, 101, 109, 158, 125, 142, 134, 117, + 93, 174, 166, 85, 182, 69, 77, 190, + 44, 223, 215, 36, 199, 52, 60, 207, + 231, 20, 28, 239, 12, 255, 247, 4, + 167, 84, 92, 175, 76, 191, 183, 68, + 108, 159, 151, 100, 135, 116, 124, 143, + 39, 212, 220, 47, 204, 63, 55, 196, + 236, 31, 23, 228, 7, 244, 252, 15, + 172, 95, 87, 164, 71, 180, 188, 79, + 103, 148, 156, 111, 140, 127, 119, 132, + 58, 201, 193, 50, 209, 34, 42, 217, + 241, 2, 10, 249, 26, 233, 225, 18, + 177, 66, 74, 185, 90, 169, 161, 82, + 122, 137, 129, 114, 145, 98, 106, 153, + 49, 194, 202, 57, 218, 41, 33, 210, + 250, 9, 1, 242, 17, 226, 234, 25, + 186, 73, 65, 178, 81, 162, 170, 89, + 113, 130, 138, 121, 154, 105, 97, 146 }, + { 0, 244, 245, 1, 247, 3, 2, 246, + 243, 7, 6, 242, 4, 240, 241, 5, + 251, 15, 14, 250, 12, 248, 249, 13, + 8, 252, 253, 9, 255, 11, 10, 254, + 235, 31, 30, 234, 28, 232, 233, 29, + 24, 236, 237, 25, 239, 27, 26, 238, + 16, 228, 229, 17, 231, 19, 18, 230, + 227, 23, 22, 226, 20, 224, 225, 21, + 203, 63, 62, 202, 60, 200, 201, 61, + 56, 204, 205, 57, 207, 59, 58, 206, + 48, 196, 197, 49, 199, 51, 50, 198, + 195, 55, 54, 194, 52, 192, 193, 53, + 32, 212, 213, 33, 215, 35, 34, 214, + 211, 39, 38, 210, 36, 208, 209, 37, + 219, 47, 46, 218, 44, 216, 217, 45, + 40, 220, 221, 41, 223, 43, 42, 222, + 139, 127, 126, 138, 124, 136, 137, 125, + 120, 140, 141, 121, 143, 123, 122, 142, + 112, 132, 133, 113, 135, 115, 114, 134, + 131, 119, 118, 130, 116, 128, 129, 117, + 96, 148, 149, 97, 151, 99, 98, 150, + 147, 103, 102, 146, 100, 144, 145, 101, + 155, 111, 110, 154, 108, 152, 153, 109, + 104, 156, 157, 105, 159, 107, 106, 158, + 64, 180, 181, 65, 183, 67, 66, 182, + 179, 71, 70, 178, 68, 176, 177, 69, + 187, 79, 78, 186, 76, 184, 185, 77, + 72, 188, 189, 73, 191, 75, 74, 190, + 171, 95, 94, 170, 92, 168, 169, 93, + 88, 172, 173, 89, 175, 91, 90, 174, + 80, 164, 165, 81, 167, 83, 82, 166, + 163, 87, 86, 162, 84, 160, 161, 85 }, + { 0, 245, 247, 2, 243, 6, 4, 241, + 251, 14, 12, 249, 8, 253, 255, 10, + 235, 30, 28, 233, 24, 237, 239, 26, + 16, 229, 231, 18, 227, 22, 20, 225, + 203, 62, 60, 201, 56, 205, 207, 58, + 48, 197, 199, 50, 195, 54, 52, 193, + 32, 213, 215, 34, 211, 38, 36, 209, + 219, 46, 44, 217, 40, 221, 223, 42, + 139, 126, 124, 137, 120, 141, 143, 122, + 112, 133, 135, 114, 131, 118, 116, 129, + 96, 149, 151, 98, 147, 102, 100, 145, + 155, 110, 108, 153, 104, 157, 159, 106, + 64, 181, 183, 66, 179, 70, 68, 177, + 187, 78, 76, 185, 72, 189, 191, 74, + 171, 94, 92, 169, 88, 173, 175, 90, + 80, 165, 167, 82, 163, 86, 84, 161, + 11, 254, 252, 9, 248, 13, 15, 250, + 240, 5, 7, 242, 3, 246, 244, 1, + 224, 21, 23, 226, 19, 230, 228, 17, + 27, 238, 236, 25, 232, 29, 31, 234, + 192, 53, 55, 194, 51, 198, 196, 49, + 59, 206, 204, 57, 200, 61, 63, 202, + 43, 222, 220, 41, 216, 45, 47, 218, + 208, 37, 39, 210, 35, 214, 212, 33, + 128, 117, 119, 130, 115, 134, 132, 113, + 123, 142, 140, 121, 136, 125, 127, 138, + 107, 158, 156, 105, 152, 109, 111, 154, + 144, 101, 103, 146, 99, 150, 148, 97, + 75, 190, 188, 73, 184, 77, 79, 186, + 176, 69, 71, 178, 67, 182, 180, 65, + 160, 85, 87, 162, 83, 166, 164, 81, + 91, 174, 172, 89, 168, 93, 95, 170 }, + { 0, 246, 241, 7, 255, 9, 14, 248, + 227, 21, 18, 228, 28, 234, 237, 27, + 219, 45, 42, 220, 36, 210, 213, 35, + 56, 206, 201, 63, 199, 49, 54, 192, + 171, 93, 90, 172, 84, 162, 165, 83, + 72, 190, 185, 79, 183, 65, 70, 176, + 112, 134, 129, 119, 143, 121, 126, 136, + 147, 101, 98, 148, 108, 154, 157, 107, + 75, 189, 186, 76, 180, 66, 69, 179, + 168, 94, 89, 175, 87, 161, 166, 80, + 144, 102, 97, 151, 111, 153, 158, 104, + 115, 133, 130, 116, 140, 122, 125, 139, + 224, 22, 17, 231, 31, 233, 238, 24, + 3, 245, 242, 4, 252, 10, 13, 251, + 59, 205, 202, 60, 196, 50, 53, 195, + 216, 46, 41, 223, 39, 209, 214, 32, + 150, 96, 103, 145, 105, 159, 152, 110, + 117, 131, 132, 114, 138, 124, 123, 141, + 77, 187, 188, 74, 178, 68, 67, 181, + 174, 88, 95, 169, 81, 167, 160, 86, + 61, 203, 204, 58, 194, 52, 51, 197, + 222, 40, 47, 217, 33, 215, 208, 38, + 230, 16, 23, 225, 25, 239, 232, 30, + 5, 243, 244, 2, 250, 12, 11, 253, + 221, 43, 44, 218, 34, 212, 211, 37, + 62, 200, 207, 57, 193, 55, 48, 198, + 6, 240, 247, 1, 249, 15, 8, 254, + 229, 19, 20, 226, 26, 236, 235, 29, + 118, 128, 135, 113, 137, 127, 120, 142, + 149, 99, 100, 146, 106, 156, 155, 109, + 173, 91, 92, 170, 82, 164, 163, 85, + 78, 184, 191, 73, 177, 71, 64, 182 }, + { 0, 247, 243, 4, 251, 12, 8, 255, + 235, 28, 24, 239, 16, 231, 227, 20, + 203, 60, 56, 207, 48, 199, 195, 52, + 32, 215, 211, 36, 219, 44, 40, 223, + 139, 124, 120, 143, 112, 135, 131, 116, + 96, 151, 147, 100, 155, 108, 104, 159, + 64, 183, 179, 68, 187, 76, 72, 191, + 171, 92, 88, 175, 80, 167, 163, 84, + 11, 252, 248, 15, 240, 7, 3, 244, + 224, 23, 19, 228, 27, 236, 232, 31, + 192, 55, 51, 196, 59, 204, 200, 63, + 43, 220, 216, 47, 208, 39, 35, 212, + 128, 119, 115, 132, 123, 140, 136, 127, + 107, 156, 152, 111, 144, 103, 99, 148, + 75, 188, 184, 79, 176, 71, 67, 180, + 160, 87, 83, 164, 91, 172, 168, 95, + 22, 225, 229, 18, 237, 26, 30, 233, + 253, 10, 14, 249, 6, 241, 245, 2, + 221, 42, 46, 217, 38, 209, 213, 34, + 54, 193, 197, 50, 205, 58, 62, 201, + 157, 106, 110, 153, 102, 145, 149, 98, + 118, 129, 133, 114, 141, 122, 126, 137, + 86, 161, 165, 82, 173, 90, 94, 169, + 189, 74, 78, 185, 70, 177, 181, 66, + 29, 234, 238, 25, 230, 17, 21, 226, + 246, 1, 5, 242, 13, 250, 254, 9, + 214, 33, 37, 210, 45, 218, 222, 41, + 61, 202, 206, 57, 198, 49, 53, 194, + 150, 97, 101, 146, 109, 154, 158, 105, + 125, 138, 142, 121, 134, 113, 117, 130, + 93, 170, 174, 89, 166, 81, 85, 162, + 182, 65, 69, 178, 77, 186, 190, 73 }, + { 0, 248, 237, 21, 199, 63, 42, 210, + 147, 107, 126, 134, 84, 172, 185, 65, + 59, 195, 214, 46, 252, 4, 17, 233, + 168, 80, 69, 189, 111, 151, 130, 122, + 118, 142, 155, 99, 177, 73, 92, 164, + 229, 29, 8, 240, 34, 218, 207, 55, + 77, 181, 160, 88, 138, 114, 103, 159, + 222, 38, 51, 203, 25, 225, 244, 12, + 236, 20, 1, 249, 43, 211, 198, 62, + 127, 135, 146, 106, 184, 64, 85, 173, + 215, 47, 58, 194, 16, 232, 253, 5, + 68, 188, 169, 81, 131, 123, 110, 150, + 154, 98, 119, 143, 93, 165, 176, 72, + 9, 241, 228, 28, 206, 54, 35, 219, + 161, 89, 76, 180, 102, 158, 139, 115, + 50, 202, 223, 39, 245, 13, 24, 224, + 197, 61, 40, 208, 2, 250, 239, 23, + 86, 174, 187, 67, 145, 105, 124, 132, + 254, 6, 19, 235, 57, 193, 212, 44, + 109, 149, 128, 120, 170, 82, 71, 191, + 179, 75, 94, 166, 116, 140, 153, 97, + 32, 216, 205, 53, 231, 31, 10, 242, + 136, 112, 101, 157, 79, 183, 162, 90, + 27, 227, 246, 14, 220, 36, 49, 201, + 41, 209, 196, 60, 238, 22, 3, 251, + 186, 66, 87, 175, 125, 133, 144, 104, + 18, 234, 255, 7, 213, 45, 56, 192, + 129, 121, 108, 148, 70, 190, 171, 83, + 95, 167, 178, 74, 152, 96, 117, 141, + 204, 52, 33, 217, 11, 243, 230, 30, + 100, 156, 137, 113, 163, 91, 78, 182, + 247, 15, 26, 226, 48, 200, 221, 37 }, + { 0, 249, 239, 22, 195, 58, 44, 213, + 155, 98, 116, 141, 88, 161, 183, 78, + 43, 210, 196, 61, 232, 17, 7, 254, + 176, 73, 95, 166, 115, 138, 156, 101, + 86, 175, 185, 64, 149, 108, 122, 131, + 205, 52, 34, 219, 14, 247, 225, 24, + 125, 132, 146, 107, 190, 71, 81, 168, + 230, 31, 9, 240, 37, 220, 202, 51, + 172, 85, 67, 186, 111, 150, 128, 121, + 55, 206, 216, 33, 244, 13, 27, 226, + 135, 126, 104, 145, 68, 189, 171, 82, + 28, 229, 243, 10, 223, 38, 48, 201, + 250, 3, 21, 236, 57, 192, 214, 47, + 97, 152, 142, 119, 162, 91, 77, 180, + 209, 40, 62, 199, 18, 235, 253, 4, + 74, 179, 165, 92, 137, 112, 102, 159, + 69, 188, 170, 83, 134, 127, 105, 144, + 222, 39, 49, 200, 29, 228, 242, 11, + 110, 151, 129, 120, 173, 84, 66, 187, + 245, 12, 26, 227, 54, 207, 217, 32, + 19, 234, 252, 5, 208, 41, 63, 198, + 136, 113, 103, 158, 75, 178, 164, 93, + 56, 193, 215, 46, 251, 2, 20, 237, + 163, 90, 76, 181, 96, 153, 143, 118, + 233, 16, 6, 255, 42, 211, 197, 60, + 114, 139, 157, 100, 177, 72, 94, 167, + 194, 59, 45, 212, 1, 248, 238, 23, + 89, 160, 182, 79, 154, 99, 117, 140, + 191, 70, 80, 169, 124, 133, 147, 106, + 36, 221, 203, 50, 231, 30, 8, 241, + 148, 109, 123, 130, 87, 174, 184, 65, + 15, 246, 224, 25, 204, 53, 35, 218 }, + { 0, 250, 233, 19, 207, 53, 38, 220, + 131, 121, 106, 144, 76, 182, 165, 95, + 27, 225, 242, 8, 212, 46, 61, 199, + 152, 98, 113, 139, 87, 173, 190, 68, + 54, 204, 223, 37, 249, 3, 16, 234, + 181, 79, 92, 166, 122, 128, 147, 105, + 45, 215, 196, 62, 226, 24, 11, 241, + 174, 84, 71, 189, 97, 155, 136, 114, + 108, 150, 133, 127, 163, 89, 74, 176, + 239, 21, 6, 252, 32, 218, 201, 51, + 119, 141, 158, 100, 184, 66, 81, 171, + 244, 14, 29, 231, 59, 193, 210, 40, + 90, 160, 179, 73, 149, 111, 124, 134, + 217, 35, 48, 202, 22, 236, 255, 5, + 65, 187, 168, 82, 142, 116, 103, 157, + 194, 56, 43, 209, 13, 247, 228, 30, + 216, 34, 49, 203, 23, 237, 254, 4, + 91, 161, 178, 72, 148, 110, 125, 135, + 195, 57, 42, 208, 12, 246, 229, 31, + 64, 186, 169, 83, 143, 117, 102, 156, + 238, 20, 7, 253, 33, 219, 200, 50, + 109, 151, 132, 126, 162, 88, 75, 177, + 245, 15, 28, 230, 58, 192, 211, 41, + 118, 140, 159, 101, 185, 67, 80, 170, + 180, 78, 93, 167, 123, 129, 146, 104, + 55, 205, 222, 36, 248, 2, 17, 235, + 175, 85, 70, 188, 96, 154, 137, 115, + 44, 214, 197, 63, 227, 25, 10, 240, + 130, 120, 107, 145, 77, 183, 164, 94, + 1, 251, 232, 18, 206, 52, 39, 221, + 153, 99, 112, 138, 86, 172, 191, 69, + 26, 224, 243, 9, 213, 47, 60, 198 }, + { 0, 251, 235, 16, 203, 48, 32, 219, + 139, 112, 96, 155, 64, 187, 171, 80, + 11, 240, 224, 27, 192, 59, 43, 208, + 128, 123, 107, 144, 75, 176, 160, 91, + 22, 237, 253, 6, 221, 38, 54, 205, + 157, 102, 118, 141, 86, 173, 189, 70, + 29, 230, 246, 13, 214, 45, 61, 198, + 150, 109, 125, 134, 93, 166, 182, 77, + 44, 215, 199, 60, 231, 28, 12, 247, + 167, 92, 76, 183, 108, 151, 135, 124, + 39, 220, 204, 55, 236, 23, 7, 252, + 172, 87, 71, 188, 103, 156, 140, 119, + 58, 193, 209, 42, 241, 10, 26, 225, + 177, 74, 90, 161, 122, 129, 145, 106, + 49, 202, 218, 33, 250, 1, 17, 234, + 186, 65, 81, 170, 113, 138, 154, 97, + 88, 163, 179, 72, 147, 104, 120, 131, + 211, 40, 56, 195, 24, 227, 243, 8, + 83, 168, 184, 67, 152, 99, 115, 136, + 216, 35, 51, 200, 19, 232, 248, 3, + 78, 181, 165, 94, 133, 126, 110, 149, + 197, 62, 46, 213, 14, 245, 229, 30, + 69, 190, 174, 85, 142, 117, 101, 158, + 206, 53, 37, 222, 5, 254, 238, 21, + 116, 143, 159, 100, 191, 68, 84, 175, + 255, 4, 20, 239, 52, 207, 223, 36, + 127, 132, 148, 111, 180, 79, 95, 164, + 244, 15, 31, 228, 63, 196, 212, 47, + 98, 153, 137, 114, 169, 82, 66, 185, + 233, 18, 2, 249, 34, 217, 201, 50, + 105, 146, 130, 121, 162, 89, 73, 178, + 226, 25, 9, 242, 41, 210, 194, 57 }, + { 0, 252, 229, 25, 215, 43, 50, 206, + 179, 79, 86, 170, 100, 152, 129, 125, + 123, 135, 158, 98, 172, 80, 73, 181, + 200, 52, 45, 209, 31, 227, 250, 6, + 246, 10, 19, 239, 33, 221, 196, 56, + 69, 185, 160, 92, 146, 110, 119, 139, + 141, 113, 104, 148, 90, 166, 191, 67, + 62, 194, 219, 39, 233, 21, 12, 240, + 241, 13, 20, 232, 38, 218, 195, 63, + 66, 190, 167, 91, 149, 105, 112, 140, + 138, 118, 111, 147, 93, 161, 184, 68, + 57, 197, 220, 32, 238, 18, 11, 247, + 7, 251, 226, 30, 208, 44, 53, 201, + 180, 72, 81, 173, 99, 159, 134, 122, + 124, 128, 153, 101, 171, 87, 78, 178, + 207, 51, 42, 214, 24, 228, 253, 1, + 255, 3, 26, 230, 40, 212, 205, 49, + 76, 176, 169, 85, 155, 103, 126, 130, + 132, 120, 97, 157, 83, 175, 182, 74, + 55, 203, 210, 46, 224, 28, 5, 249, + 9, 245, 236, 16, 222, 34, 59, 199, + 186, 70, 95, 163, 109, 145, 136, 116, + 114, 142, 151, 107, 165, 89, 64, 188, + 193, 61, 36, 216, 22, 234, 243, 15, + 14, 242, 235, 23, 217, 37, 60, 192, + 189, 65, 88, 164, 106, 150, 143, 115, + 117, 137, 144, 108, 162, 94, 71, 187, + 198, 58, 35, 223, 17, 237, 244, 8, + 248, 4, 29, 225, 47, 211, 202, 54, + 75, 183, 174, 82, 156, 96, 121, 133, + 131, 127, 102, 154, 84, 168, 177, 77, + 48, 204, 213, 41, 231, 27, 2, 254 }, + { 0, 253, 231, 26, 211, 46, 52, 201, + 187, 70, 92, 161, 104, 149, 143, 114, + 107, 150, 140, 113, 184, 69, 95, 162, + 208, 45, 55, 202, 3, 254, 228, 25, + 214, 43, 49, 204, 5, 248, 226, 31, + 109, 144, 138, 119, 190, 67, 89, 164, + 189, 64, 90, 167, 110, 147, 137, 116, + 6, 251, 225, 28, 213, 40, 50, 207, + 177, 76, 86, 171, 98, 159, 133, 120, + 10, 247, 237, 16, 217, 36, 62, 195, + 218, 39, 61, 192, 9, 244, 238, 19, + 97, 156, 134, 123, 178, 79, 85, 168, + 103, 154, 128, 125, 180, 73, 83, 174, + 220, 33, 59, 198, 15, 242, 232, 21, + 12, 241, 235, 22, 223, 34, 56, 197, + 183, 74, 80, 173, 100, 153, 131, 126, + 127, 130, 152, 101, 172, 81, 75, 182, + 196, 57, 35, 222, 23, 234, 240, 13, + 20, 233, 243, 14, 199, 58, 32, 221, + 175, 82, 72, 181, 124, 129, 155, 102, + 169, 84, 78, 179, 122, 135, 157, 96, + 18, 239, 245, 8, 193, 60, 38, 219, + 194, 63, 37, 216, 17, 236, 246, 11, + 121, 132, 158, 99, 170, 87, 77, 176, + 206, 51, 41, 212, 29, 224, 250, 7, + 117, 136, 146, 111, 166, 91, 65, 188, + 165, 88, 66, 191, 118, 139, 145, 108, + 30, 227, 249, 4, 205, 48, 42, 215, + 24, 229, 255, 2, 203, 54, 44, 209, + 163, 94, 68, 185, 112, 141, 151, 106, + 115, 142, 148, 105, 160, 93, 71, 186, + 200, 53, 47, 210, 27, 230, 252, 1 }, + { 0, 254, 225, 31, 223, 33, 62, 192, + 163, 93, 66, 188, 124, 130, 157, 99, + 91, 165, 186, 68, 132, 122, 101, 155, + 248, 6, 25, 231, 39, 217, 198, 56, + 182, 72, 87, 169, 105, 151, 136, 118, + 21, 235, 244, 10, 202, 52, 43, 213, + 237, 19, 12, 242, 50, 204, 211, 45, + 78, 176, 175, 81, 145, 111, 112, 142, + 113, 143, 144, 110, 174, 80, 79, 177, + 210, 44, 51, 205, 13, 243, 236, 18, + 42, 212, 203, 53, 245, 11, 20, 234, + 137, 119, 104, 150, 86, 168, 183, 73, + 199, 57, 38, 216, 24, 230, 249, 7, + 100, 154, 133, 123, 187, 69, 90, 164, + 156, 98, 125, 131, 67, 189, 162, 92, + 63, 193, 222, 32, 224, 30, 1, 255, + 226, 28, 3, 253, 61, 195, 220, 34, + 65, 191, 160, 94, 158, 96, 127, 129, + 185, 71, 88, 166, 102, 152, 135, 121, + 26, 228, 251, 5, 197, 59, 36, 218, + 84, 170, 181, 75, 139, 117, 106, 148, + 247, 9, 22, 232, 40, 214, 201, 55, + 15, 241, 238, 16, 208, 46, 49, 207, + 172, 82, 77, 179, 115, 141, 146, 108, + 147, 109, 114, 140, 76, 178, 173, 83, + 48, 206, 209, 47, 239, 17, 14, 240, + 200, 54, 41, 215, 23, 233, 246, 8, + 107, 149, 138, 116, 180, 74, 85, 171, + 37, 219, 196, 58, 250, 4, 27, 229, + 134, 120, 103, 153, 89, 167, 184, 70, + 126, 128, 159, 97, 161, 95, 64, 190, + 221, 35, 60, 194, 2, 252, 227, 29 }, + { 0, 255, 227, 28, 219, 36, 56, 199, + 171, 84, 72, 183, 112, 143, 147, 108, + 75, 180, 168, 87, 144, 111, 115, 140, + 224, 31, 3, 252, 59, 196, 216, 39, + 150, 105, 117, 138, 77, 178, 174, 81, + 61, 194, 222, 33, 230, 25, 5, 250, + 221, 34, 62, 193, 6, 249, 229, 26, + 118, 137, 149, 106, 173, 82, 78, 177, + 49, 206, 210, 45, 234, 21, 9, 246, + 154, 101, 121, 134, 65, 190, 162, 93, + 122, 133, 153, 102, 161, 94, 66, 189, + 209, 46, 50, 205, 10, 245, 233, 22, + 167, 88, 68, 187, 124, 131, 159, 96, + 12, 243, 239, 16, 215, 40, 52, 203, + 236, 19, 15, 240, 55, 200, 212, 43, + 71, 184, 164, 91, 156, 99, 127, 128, + 98, 157, 129, 126, 185, 70, 90, 165, + 201, 54, 42, 213, 18, 237, 241, 14, + 41, 214, 202, 53, 242, 13, 17, 238, + 130, 125, 97, 158, 89, 166, 186, 69, + 244, 11, 23, 232, 47, 208, 204, 51, + 95, 160, 188, 67, 132, 123, 103, 152, + 191, 64, 92, 163, 100, 155, 135, 120, + 20, 235, 247, 8, 207, 48, 44, 211, + 83, 172, 176, 79, 136, 119, 107, 148, + 248, 7, 27, 228, 35, 220, 192, 63, + 24, 231, 251, 4, 195, 60, 32, 223, + 179, 76, 80, 175, 104, 151, 139, 116, + 197, 58, 38, 217, 30, 225, 253, 2, + 110, 145, 141, 114, 181, 74, 86, 169, + 142, 113, 109, 146, 85, 170, 182, 73, + 37, 218, 198, 57, 254, 1, 29, 226 } +}; + +static const uint8_t gf256_inv_table[256] = { + 0, 1, 142, 244, 71, 167, 122, 186, + 173, 157, 221, 152, 61, 170, 93, 150, + 216, 114, 192, 88, 224, 62, 76, 102, + 144, 222, 85, 128, 160, 131, 75, 42, + 108, 237, 57, 81, 96, 86, 44, 138, + 112, 208, 31, 74, 38, 139, 51, 110, + 72, 137, 111, 46, 164, 195, 64, 94, + 80, 34, 207, 169, 171, 12, 21, 225, + 54, 95, 248, 213, 146, 78, 166, 4, + 48, 136, 43, 30, 22, 103, 69, 147, + 56, 35, 104, 140, 129, 26, 37, 97, + 19, 193, 203, 99, 151, 14, 55, 65, + 36, 87, 202, 91, 185, 196, 23, 77, + 82, 141, 239, 179, 32, 236, 47, 50, + 40, 209, 17, 217, 233, 251, 218, 121, + 219, 119, 6, 187, 132, 205, 254, 252, + 27, 84, 161, 29, 124, 204, 228, 176, + 73, 49, 39, 45, 83, 105, 2, 245, + 24, 223, 68, 79, 155, 188, 15, 92, + 11, 220, 189, 148, 172, 9, 199, 162, + 28, 130, 159, 198, 52, 194, 70, 5, + 206, 59, 13, 60, 156, 8, 190, 183, + 135, 229, 238, 107, 235, 242, 191, 175, + 197, 100, 7, 123, 149, 154, 174, 182, + 18, 89, 165, 53, 101, 184, 163, 158, + 210, 247, 98, 90, 133, 125, 168, 58, + 41, 113, 200, 246, 249, 67, 215, 214, + 16, 115, 118, 120, 153, 10, 25, 145, + 20, 63, 230, 240, 134, 177, 226, 241, + 250, 116, 243, 180, 109, 33, 178, 106, + 227, 231, 181, 234, 3, 143, 211, 201, + 66, 212, 232, 117, 127, 255, 126, 253}; +