From b4cbb5cce7c2e1c1447129c23a7e9c70c12fd726 Mon Sep 17 00:00:00 2001
From: wangjie
Date: Mon, 19 Oct 2020 14:19:57 +0800
Subject: [PATCH] Synchronize patches from community
---
...n-to-avoid-building-shared-libraries.patch | 182 +
...sing-const-to-a-couple-of-kConstants.patch | 76 +
Disable-PIC-in-EMCC-mode.patch | 99 +
Ensure-decompression-consumes-all-input.patch | 76 +
Fix-include-for-EMCC-build.patch | 25 +
...BSR-intrinsics-and-add-MSVC-versions.patch | 107 +
Verbose-CLI-start-pulling-Shared-Brotli.patch | 1377 ++
brotli.spec | 29 +-
...figuration-and-c++-compilation-fails.patch | 11396 ++++++++++++++++
fix-executable-mode-of-decode-js.patch | 623 +
10 files changed, 13988 insertions(+), 2 deletions(-)
create mode 100644 Add-an-option-to-avoid-building-shared-libraries.patch
create mode 100644 Add-missing-const-to-a-couple-of-kConstants.patch
create mode 100644 Disable-PIC-in-EMCC-mode.patch
create mode 100644 Ensure-decompression-consumes-all-input.patch
create mode 100644 Fix-include-for-EMCC-build.patch
create mode 100644 Move-TZCNT-and-BSR-intrinsics-and-add-MSVC-versions.patch
create mode 100644 Verbose-CLI-start-pulling-Shared-Brotli.patch
create mode 100644 fix-MSVC-configuration-and-c++-compilation-fails.patch
create mode 100644 fix-executable-mode-of-decode-js.patch
diff --git a/Add-an-option-to-avoid-building-shared-libraries.patch b/Add-an-option-to-avoid-building-shared-libraries.patch
new file mode 100644
index 0000000..4646277
--- /dev/null
+++ b/Add-an-option-to-avoid-building-shared-libraries.patch
@@ -0,0 +1,182 @@
+From ca21dac8e58177a5f6c7e8e177afd371aa66da0a Mon Sep 17 00:00:00 2001
+From: Eugene Kliuchnikov
+Date: Wed, 7 Aug 2019 10:51:55 +0200
+Subject: [PATCH] Add an option to avoid building shared libraries. (#766)
+
+Add an option to avoid building shared libraries (for building with EMCC)
+
+Drive-by:
+* maven: ramp up java level to minimal required
+* travis: replace deprecated clang-5.0 with clang-7
+* maven: fallback to jdk10 to void javadoc bug
+---
+ .travis.yml | 33 ++++++++++++++++++---------------
+ CMakeLists.txt | 22 ++++++++++++++++------
+ java/org/brotli/pom.xml | 4 ++--
+ 3 files changed, 36 insertions(+), 23 deletions(-)
+
+diff --git a/.travis.yml b/.travis.yml
+index 5cfeafc..930bd63 100644
+--- a/.travis.yml
++++ b/.travis.yml
+@@ -44,27 +44,27 @@ matrix:
+ ## Test that fuzzer is compiling / working.
+ ###
+ - os: linux
+- env: BUILD_SYSTEM=fuzz C_COMPILER=clang-5.0 CXX_COMPILER=clang++-5.0 ASAN_OPTIONS=detect_leaks=0
++ env: BUILD_SYSTEM=fuzz C_COMPILER=clang-7 CXX_COMPILER=clang++-7 ASAN_OPTIONS=detect_leaks=0
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+- - llvm-toolchain-trusty-5.0
++ - llvm-toolchain-xenial-7
+ packages:
+- - clang-5.0
++ - clang-7
+
+ ###
+ ## clang on Linux
+ ###
+ - os: linux
+- env: BUILD_SYSTEM=cmake C_COMPILER=clang-5.0 CXX_COMPILER=clang++-5.0
++ env: BUILD_SYSTEM=cmake C_COMPILER=clang-7 CXX_COMPILER=clang++-7
+ addons:
+ apt:
+ sources:
+- - llvm-toolchain-trusty-5.0
++ - llvm-toolchain-xenial-7
+ - ubuntu-toolchain-r-test
+ packages:
+- - clang-5.0
++ - clang-7
+ - os: linux
+ env: BUILD_SYSTEM=cmake C_COMPILER=clang-3.5 CXX_COMPILER=clang++-3.5
+ addons:
+@@ -145,35 +145,38 @@ matrix:
+ ## Sanitizers
+ ###
+ - os: linux
+- env: BUILD_SYSTEM=cmake C_COMPILER=clang-5.0 CXX_COMPILER=clang++-5.0 SANITIZER=address ASAN_OPTIONS=detect_leaks=0
++ env: BUILD_SYSTEM=cmake C_COMPILER=clang-7 CXX_COMPILER=clang++-7 SANITIZER=address ASAN_OPTIONS=detect_leaks=0
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+- - llvm-toolchain-trusty-5.0
++ - llvm-toolchain-xenial-7
+ packages:
+- - clang-5.0
++ - clang-7
+ - os: linux
+- env: BUILD_SYSTEM=cmake C_COMPILER=clang-5.0 CXX_COMPILER=clang++-5.0 SANITIZER=thread
++ env: BUILD_SYSTEM=cmake C_COMPILER=clang-7 CXX_COMPILER=clang++-7 SANITIZER=thread
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+- - llvm-toolchain-trusty-5.0
++ - llvm-toolchain-xenial-7
+ packages:
+- - clang-5.0
++ - clang-7
+ - os: linux
+- env: BUILD_SYSTEM=cmake C_COMPILER=clang-5.0 CXX_COMPILER=clang++-5.0 SANITIZER=undefined CFLAGS="-fno-sanitize-recover=undefined,integer"
++ env: BUILD_SYSTEM=cmake C_COMPILER=clang-7 CXX_COMPILER=clang++-7 SANITIZER=undefined CFLAGS="-fno-sanitize-recover=undefined,integer"
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+- - llvm-toolchain-trusty-5.0
++ - llvm-toolchain-xenial-7
+ packages:
+- - clang-5.0
++ - clang-7
+
+ - os: linux
+ env: BUILD_SYSTEM=maven
++ jdk:
++ # maven + jdk11 + javadoc == trouble
++ - openjdk10
+ language: java
+
+ - os: linux
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index fc45f80..3427802 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -6,6 +6,8 @@ cmake_minimum_required(VERSION 2.8.6)
+
+ project(brotli C)
+
++option(BROTLI_DISABLE_SHARED "do not build shared libraries")
++
+ # If Brotli is being bundled in another project, we don't want to
+ # install anything. However, we want to let people override this, so
+ # we'll use the BROTLI_BUNDLED_MODE variable to let them do that; just
+@@ -137,10 +139,16 @@ endfunction()
+ transform_sources_list("scripts/sources.lst" "${CMAKE_CURRENT_BINARY_DIR}/sources.lst.cmake")
+ include("${CMAKE_CURRENT_BINARY_DIR}/sources.lst.cmake")
+
+-add_library(brotlicommon SHARED ${BROTLI_COMMON_C})
+-add_library(brotlidec SHARED ${BROTLI_DEC_C})
+-add_library(brotlienc SHARED ${BROTLI_ENC_C})
++if(BROTLI_DISABLE_SHARED)
++ set(BROTLI_SHARED_LIBS "")
++else()
++ set(BROTLI_SHARED_LIBS brotlicommon brotlidec brotlienc)
++ add_library(brotlicommon SHARED ${BROTLI_COMMON_C})
++ add_library(brotlidec SHARED ${BROTLI_DEC_C})
++ add_library(brotlienc SHARED ${BROTLI_ENC_C})
++endif()
+
++set(BROTLI_STATIC_LIBS brotlicommon-static brotlidec-static brotlienc-static)
+ add_library(brotlicommon-static STATIC ${BROTLI_COMMON_C})
+ add_library(brotlidec-static STATIC ${BROTLI_DEC_C})
+ add_library(brotlienc-static STATIC ${BROTLI_ENC_C})
+@@ -148,13 +156,13 @@ add_library(brotlienc-static STATIC ${BROTLI_ENC_C})
+ # Older CMake versions does not understand INCLUDE_DIRECTORIES property.
+ include_directories(${BROTLI_INCLUDE_DIRS})
+
+-foreach(lib brotlicommon brotlidec brotlienc)
++foreach(lib IN LISTS BROTLI_SHARED_LIBS)
+ target_compile_definitions(${lib} PUBLIC "BROTLI_SHARED_COMPILATION" )
+ string(TOUPPER "${lib}" LIB)
+- set_target_properties (${lib} PROPERTIES DEFINE_SYMBOL "${LIB}_SHARED_COMPILATION" )
++ set_target_properties (${lib} PROPERTIES DEFINE_SYMBOL "${LIB}_SHARED_COMPILATION")
+ endforeach()
+
+-foreach(lib brotlicommon brotlidec brotlienc brotlicommon-static brotlidec-static brotlienc-static)
++foreach(lib IN LISTS BROTLI_SHARED_LIBS BROTLI_STATIC_LIBS)
+ target_link_libraries(${lib} ${LIBM_LIBRARY})
+ set_property(TARGET ${lib} APPEND PROPERTY INCLUDE_DIRECTORIES ${BROTLI_INCLUDE_DIRS})
+ set_target_properties(${lib} PROPERTIES
+@@ -164,8 +172,10 @@ foreach(lib brotlicommon brotlidec brotlienc brotlicommon-static brotlidec-stati
+ set_property(TARGET ${lib} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${BROTLI_INCLUDE_DIRS}")
+ endforeach()
+
++if(NOT BROTLI_DISABLE_SHARED)
+ target_link_libraries(brotlidec brotlicommon)
+ target_link_libraries(brotlienc brotlicommon)
++endif()
+
+ target_link_libraries(brotlidec-static brotlicommon-static)
+ target_link_libraries(brotlienc-static brotlicommon-static)
+diff --git a/java/org/brotli/pom.xml b/java/org/brotli/pom.xml
+index bb4a5a3..9a7abd0 100644
+--- a/java/org/brotli/pom.xml
++++ b/java/org/brotli/pom.xml
+@@ -80,8 +80,8 @@
+ maven-compiler-plugin
+ 3.1
+
+- 1.5
+- 1.5
++ 1.6
++ 1.6
+
+
+
+--
+2.6.1.windows.1
+
diff --git a/Add-missing-const-to-a-couple-of-kConstants.patch b/Add-missing-const-to-a-couple-of-kConstants.patch
new file mode 100644
index 0000000..0c95651
--- /dev/null
+++ b/Add-missing-const-to-a-couple-of-kConstants.patch
@@ -0,0 +1,76 @@
+From 4b5771bee7995d3d606221caa455c044d80434df Mon Sep 17 00:00:00 2001
+From: agrieve
+Date: Thu, 19 Dec 2019 18:15:58 -0500
+Subject: [PATCH] Add missing "const" to a couple of kConstants (#780)
+
+These showed up in a Chromium audit:
+https://bugs.chromium.org/p/chromium/issues/detail?id=747064#c8
+
+Although already effectively const, adding "const" causes the symbols to
+be moved into the read-only section of the binary.
+---
+ c/common/dictionary.c | 11 ++++++++++-
+ c/common/transform.c | 2 +-
+ 2 files changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/c/common/dictionary.c b/c/common/dictionary.c
+index 64822a3..f9e3041 100644
+--- a/c/common/dictionary.c
++++ b/c/common/dictionary.c
+@@ -5,12 +5,13 @@
+ */
+
+ #include "./dictionary.h"
++#include "./platform.h"
+
+ #if defined(__cplusplus) || defined(c_plusplus)
+ extern "C" {
+ #endif
+
+-#ifndef BROTLI_EXTERNAL_DICTIONARY_DATA
++#if !defined(BROTLI_EXTERNAL_DICTIONARY_DATA)
+ static const uint8_t kBrotliDictionaryData[] =
+ {
+ 116,105,109,101,100,111,119,110,108,105,102,101,108,101,102,116,98,97,99,107,99,
+@@ -5862,7 +5863,11 @@ static const uint8_t kBrotliDictionaryData[] =
+ ;
+ #endif /* !BROTLI_EXTERNAL_DICTIONARY_DATA */
+
++#if !defined(BROTLI_EXTERNAL_DICTIONARY_DATA)
++static const BrotliDictionary kBrotliDictionary = {
++#else
+ static BrotliDictionary kBrotliDictionary = {
++#endif
+ /* size_bits_by_length */
+ {
+ 0, 0, 0, 0, 10, 10, 11, 11,
+@@ -5895,9 +5900,13 @@ const BrotliDictionary* BrotliGetDictionary() {
+ }
+
+ void BrotliSetDictionaryData(const uint8_t* data) {
++#if defined(BROTLI_EXTERNAL_DICTIONARY_DATA)
+ if (!!data && !kBrotliDictionary.data) {
+ kBrotliDictionary.data = data;
+ }
++#else
++ BROTLI_UNUSED(data); // Appease -Werror=unused-parameter
++#endif
+ }
+
+ #if defined(__cplusplus) || defined(c_plusplus)
+diff --git a/c/common/transform.c b/c/common/transform.c
+index c44f671..f8fa433 100755
+--- a/c/common/transform.c
++++ b/c/common/transform.c
+@@ -160,7 +160,7 @@ static const uint8_t kTransformsData[] = {
+ 0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 34,
+ };
+
+-static BrotliTransforms kBrotliTransforms = {
++static const BrotliTransforms kBrotliTransforms = {
+ sizeof(kPrefixSuffix),
+ (const uint8_t*)kPrefixSuffix,
+ kPrefixSuffixMap,
+--
+2.6.1.windows.1
+
diff --git a/Disable-PIC-in-EMCC-mode.patch b/Disable-PIC-in-EMCC-mode.patch
new file mode 100644
index 0000000..9d39d06
--- /dev/null
+++ b/Disable-PIC-in-EMCC-mode.patch
@@ -0,0 +1,99 @@
+From 35ef5c554d888bef217d449346067de05e269b30 Mon Sep 17 00:00:00 2001
+From: Eugene Kliuchnikov
+Date: Tue, 13 Aug 2019 15:23:04 +0200
+Subject: [PATCH] Disable PIC in EMCC mode. (#768)
+
+---
+ CMakeLists.txt | 31 ++++++++++++++++++++++++-------
+ 1 file changed, 24 insertions(+), 7 deletions(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 3427802..a8ea872 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -6,7 +6,18 @@ cmake_minimum_required(VERSION 2.8.6)
+
+ project(brotli C)
+
+-option(BROTLI_DISABLE_SHARED "do not build shared libraries")
++include(CheckCSourceCompiles)
++check_c_source_compiles(
++ "#if defined(__EMSCRIPTEN__)
++ int main() {return 0;}
++ #endif"
++ BROTLI_EMSCRIPTEN
++)
++if (BROTLI_EMSCRIPTEN)
++ message("-- Compiler is EMSCRIPTEN")
++else()
++ message("-- Compiler is not EMSCRIPTEN")
++endif()
+
+ # If Brotli is being bundled in another project, we don't want to
+ # install anything. However, we want to let people override this, so
+@@ -139,7 +150,7 @@ endfunction()
+ transform_sources_list("scripts/sources.lst" "${CMAKE_CURRENT_BINARY_DIR}/sources.lst.cmake")
+ include("${CMAKE_CURRENT_BINARY_DIR}/sources.lst.cmake")
+
+-if(BROTLI_DISABLE_SHARED)
++if(BROTLI_EMSCRIPTEN)
+ set(BROTLI_SHARED_LIBS "")
+ else()
+ set(BROTLI_SHARED_LIBS brotlicommon brotlidec brotlienc)
+@@ -167,12 +178,14 @@ foreach(lib IN LISTS BROTLI_SHARED_LIBS BROTLI_STATIC_LIBS)
+ set_property(TARGET ${lib} APPEND PROPERTY INCLUDE_DIRECTORIES ${BROTLI_INCLUDE_DIRS})
+ set_target_properties(${lib} PROPERTIES
+ VERSION "${BROTLI_ABI_COMPATIBILITY}.${BROTLI_ABI_AGE}.${BROTLI_ABI_REVISION}"
+- SOVERSION "${BROTLI_ABI_COMPATIBILITY}"
+- POSITION_INDEPENDENT_CODE TRUE)
++ SOVERSION "${BROTLI_ABI_COMPATIBILITY}")
++ if(NOT BROTLI_EMSCRIPTEN)
++ set_target_properties(${lib} PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
++ endif()
+ set_property(TARGET ${lib} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${BROTLI_INCLUDE_DIRS}")
+ endforeach()
+
+-if(NOT BROTLI_DISABLE_SHARED)
++if(NOT BROTLI_EMSCRIPTEN)
+ target_link_libraries(brotlidec brotlicommon)
+ target_link_libraries(brotlienc brotlicommon)
+ endif()
+@@ -196,6 +209,7 @@ add_executable(brotli ${BROTLI_CLI_C})
+ target_link_libraries(brotli ${BROTLI_LIBRARIES_STATIC})
+
+ # Installation
++if(NOT BROTLI_EMSCRIPTEN)
+ if(NOT BROTLI_BUNDLED_MODE)
+ install(
+ TARGETS brotli
+@@ -220,7 +234,8 @@ if(NOT BROTLI_BUNDLED_MODE)
+ DIRECTORY ${BROTLI_INCLUDE_DIRS}/brotli
+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
+ )
+-endif()
++endif() # BROTLI_BUNDLED_MODE
++endif() # BROTLI_EMSCRIPTEN
+
+ # Tests
+
+@@ -376,6 +391,7 @@ transform_pc_file("scripts/libbrotlidec.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/libb
+
+ transform_pc_file("scripts/libbrotlienc.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/libbrotlienc.pc" "${BROTLI_VERSION}")
+
++if(NOT BROTLI_EMSCRIPTEN)
+ if(NOT BROTLI_BUNDLED_MODE)
+ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libbrotlicommon.pc"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
+@@ -383,7 +399,8 @@ if(NOT BROTLI_BUNDLED_MODE)
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
+ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libbrotlienc.pc"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
+-endif()
++endif() # BROTLI_BUNDLED_MODE
++endif() # BROTLI_EMSCRIPTEN
+
+ if (ENABLE_COVERAGE STREQUAL "yes")
+ SETUP_TARGET_FOR_COVERAGE(coverage test coverage)
+--
+2.6.1.windows.1
+
diff --git a/Ensure-decompression-consumes-all-input.patch b/Ensure-decompression-consumes-all-input.patch
new file mode 100644
index 0000000..bcb5753
--- /dev/null
+++ b/Ensure-decompression-consumes-all-input.patch
@@ -0,0 +1,76 @@
+From 5805f99a533a8f8118699c0100d8c102f3605f65 Mon Sep 17 00:00:00 2001
+From: Justin Ridgewell
+Date: Mon, 12 Nov 2018 04:36:00 -0500
+Subject: [PATCH] Ensure decompression consumes all input (#730)
+
+* Ensure decompression consumes all input
+
+If not, it's a corrupt stream.
+
+* Use byte strings
+---
+ python/_brotli.cc | 4 ++--
+ python/tests/decompress_test.py | 4 ++++
+ python/tests/decompressor_test.py | 9 +++++++++
+ 3 files changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/python/_brotli.cc b/python/_brotli.cc
+index a6f925e..5e1828e 100644
+--- a/python/_brotli.cc
++++ b/python/_brotli.cc
+@@ -414,7 +414,7 @@ static BROTLI_BOOL decompress_stream(BrotliDecoderState* dec,
+ (*output).insert((*output).end(), buffer, buffer + buffer_length);
+ }
+ }
+- ok = result != BROTLI_DECODER_RESULT_ERROR;
++ ok = result != BROTLI_DECODER_RESULT_ERROR && !available_in;
+
+ Py_END_ALLOW_THREADS
+ return ok;
+@@ -672,7 +672,7 @@ static PyObject* brotli_decompress(PyObject *self, PyObject *args, PyObject *key
+ if (available_out != 0)
+ output.insert(output.end(), next_out, next_out + available_out);
+ }
+- ok = result == BROTLI_DECODER_RESULT_SUCCESS;
++ ok = result == BROTLI_DECODER_RESULT_SUCCESS && !available_in;
+ BrotliDecoderDestroyInstance(state);
+
+ Py_END_ALLOW_THREADS
+diff --git a/python/tests/decompress_test.py b/python/tests/decompress_test.py
+index 7a9e9e3..814e563 100644
+--- a/python/tests/decompress_test.py
++++ b/python/tests/decompress_test.py
+@@ -31,6 +31,10 @@ class TestDecompress(_test_utils.TestCase):
+ self._decompress(test_data)
+ self._check_decompression(test_data)
+
++ def test_garbage_appended(self):
++ with self.assertRaises(brotli.error):
++ brotli.decompress(brotli.compress(b'a') + b'a')
++
+
+ _test_utils.generate_test_methods(TestDecompress, for_decompression=True)
+
+diff --git a/python/tests/decompressor_test.py b/python/tests/decompressor_test.py
+index 99667bc..05918ad 100644
+--- a/python/tests/decompressor_test.py
++++ b/python/tests/decompressor_test.py
+@@ -43,6 +43,15 @@ class TestDecompressor(_test_utils.TestCase):
+ self._decompress(test_data)
+ self._check_decompression(test_data)
+
++ def test_garbage_appended(self):
++ with self.assertRaises(brotli.error):
++ self.decompressor.process(brotli.compress(b'a') + b'a')
++
++ def test_already_finished(self):
++ self.decompressor.process(brotli.compress(b'a'))
++ with self.assertRaises(brotli.error):
++ self.decompressor.process(b'a')
++
+
+ _test_utils.generate_test_methods(TestDecompressor, for_decompression=True)
+
+--
+2.6.1.windows.1
+
diff --git a/Fix-include-for-EMCC-build.patch b/Fix-include-for-EMCC-build.patch
new file mode 100644
index 0000000..a7bb721
--- /dev/null
+++ b/Fix-include-for-EMCC-build.patch
@@ -0,0 +1,25 @@
+From 3d1767186da60c29086f61be24f8292876afa871 Mon Sep 17 00:00:00 2001
+From: Eugene Kliuchnikov
+Date: Tue, 30 Jul 2019 10:01:21 +0200
+Subject: [PATCH] Fix include for EMCC build (#765)
+
+---
+ c/common/platform.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/c/common/platform.h b/c/common/platform.h
+index b6d634e..2633e04 100755
+--- a/c/common/platform.h
++++ b/c/common/platform.h
+@@ -29,7 +29,7 @@
+ #include
+ #include
+
+-#if defined(OS_LINUX) || defined(OS_CYGWIN)
++#if defined(OS_LINUX) || defined(OS_CYGWIN) || defined(__EMSCRIPTEN__)
+ #include
+ #elif defined(OS_FREEBSD)
+ #include
+--
+2.6.1.windows.1
+
diff --git a/Move-TZCNT-and-BSR-intrinsics-and-add-MSVC-versions.patch b/Move-TZCNT-and-BSR-intrinsics-and-add-MSVC-versions.patch
new file mode 100644
index 0000000..0ccd5c6
--- /dev/null
+++ b/Move-TZCNT-and-BSR-intrinsics-and-add-MSVC-versions.patch
@@ -0,0 +1,107 @@
+From 924b2b2b9dc54005edbcd85a1b872330948cdd9e Mon Sep 17 00:00:00 2001
+From: Clinton Ingram
+Date: Thu, 19 Mar 2020 03:57:56 -0700
+Subject: [PATCH] Move TZCNT and BSR intrinsics to platform.h, add MSVC
+ versions (#636)
+
+---
+ c/common/platform.h | 34 ++++++++++++++++++++++++++++++++++
+ c/enc/fast_log.h | 6 ++----
+ c/enc/find_match_length.h | 5 ++---
+ 3 files changed, 38 insertions(+), 7 deletions(-)
+
+diff --git a/c/common/platform.h b/c/common/platform.h
+index 2633e04..ca79359 100755
+--- a/c/common/platform.h
++++ b/c/common/platform.h
+@@ -41,6 +41,10 @@
+ #define BROTLI_X_BIG_ENDIAN BIG_ENDIAN
+ #endif
+
++#if BROTLI_MSVC_VERSION_CHECK(12, 0, 0)
++#include
++#endif
++
+ #if defined(BROTLI_ENABLE_LOG) || defined(BROTLI_DEBUG)
+ #include
+ #include
+@@ -522,6 +526,36 @@ BROTLI_MIN_MAX(size_t) BROTLI_MIN_MAX(uint32_t) BROTLI_MIN_MAX(uint8_t)
+ (A)[(J)] = __brotli_swap_tmp; \
+ }
+
++#if BROTLI_64_BITS
++#if BROTLI_GNUC_HAS_BUILTIN(__builtin_ctzll, 3, 4, 0) || \
++ BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
++#define BROTLI_TZCNT64 __builtin_ctzll
++#elif BROTLI_MSVC_VERSION_CHECK(12, 0, 0)
++#if defined(BROTLI_TARGET_X64)
++#define BROTLI_TZCNT64 _tzcnt_u64
++#else /* BROTLI_TARGET_X64 */
++static BROTLI_INLINE uint32_t BrotliBsf64Msvc(uint64_t x) {
++ uint32_t lsb;
++ _BitScanForward64(&lsb, x);
++ return lsb;
++}
++#define BROTLI_TZCNT64 BrotliBsf64Msvc
++#endif /* BROTLI_TARGET_X64 */
++#endif /* __builtin_ctzll */
++#endif /* BROTLI_64_BITS */
++
++#if BROTLI_GNUC_HAS_BUILTIN(__builtin_clz, 3, 4, 0) || \
++ BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
++#define BROTLI_BSR32(x) (31u ^ (uint32_t)__builtin_clz(x))
++#elif BROTLI_MSVC_VERSION_CHECK(12, 0, 0)
++static BROTLI_INLINE uint32_t BrotliBsr32Msvc(uint32_t x) {
++ uint32_t msb;
++ _BitScanReverse(&msb, x);
++ return msb;
++}
++#define BROTLI_BSR32 BrotliBsr32Msvc
++#endif /* __builtin_clz */
++
+ /* Default brotli_alloc_func */
+ static void* BrotliDefaultAllocFunc(void* opaque, size_t size) {
+ BROTLI_UNUSED(opaque);
+diff --git a/c/enc/fast_log.h b/c/enc/fast_log.h
+index b1268e0..eca58e8 100644
+--- a/c/enc/fast_log.h
++++ b/c/enc/fast_log.h
+@@ -19,10 +19,8 @@ extern "C" {
+ #endif
+
+ static BROTLI_INLINE uint32_t Log2FloorNonZero(size_t n) {
+- /* TODO: generalize and move to platform.h */
+-#if BROTLI_GNUC_HAS_BUILTIN(__builtin_clz, 3, 4, 0) || \
+- BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
+- return 31u ^ (uint32_t)__builtin_clz((uint32_t)n);
++#if defined(BROTLI_BSR32)
++ return BROTLI_BSR32((uint32_t)n);
+ #else
+ uint32_t result = 0;
+ while (n >>= 1) result++;
+diff --git a/c/enc/find_match_length.h b/c/enc/find_match_length.h
+index bc428cf..f8853a7 100644
+--- a/c/enc/find_match_length.h
++++ b/c/enc/find_match_length.h
+@@ -17,8 +17,7 @@ extern "C" {
+ #endif
+
+ /* Separate implementation for little-endian 64-bit targets, for speed. */
+-#if defined(__GNUC__) && defined(_LP64) && defined(BROTLI_LITTLE_ENDIAN)
+-
++#if defined(BROTLI_TZCNT64) && BROTLI_64_BITS && BROTLI_LITTLE_ENDIAN
+ static BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1,
+ const uint8_t* s2,
+ size_t limit) {
+@@ -32,7 +31,7 @@ static BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1,
+ } else {
+ uint64_t x = BROTLI_UNALIGNED_LOAD64LE(s2) ^
+ BROTLI_UNALIGNED_LOAD64LE(s1 + matched);
+- size_t matching_bits = (size_t)__builtin_ctzll(x);
++ size_t matching_bits = (size_t)BROTLI_TZCNT64(x);
+ matched += matching_bits >> 3;
+ return matched;
+ }
+--
+2.6.1.windows.1
+
diff --git a/Verbose-CLI-start-pulling-Shared-Brotli.patch b/Verbose-CLI-start-pulling-Shared-Brotli.patch
new file mode 100644
index 0000000..be5c1e6
--- /dev/null
+++ b/Verbose-CLI-start-pulling-Shared-Brotli.patch
@@ -0,0 +1,1377 @@
+From d0ffe60b87aa5ec302fcb031c8ebf726c1a1692a Mon Sep 17 00:00:00 2001
+From: Eugene Kliuchnikov
+Date: Wed, 24 Oct 2018 16:06:09 +0200
+Subject: [PATCH] Verbose CLI + start pulling "Shared-Brotli" (#722)
+
+* Verbose CLI + start pulling "Shared-Brotli"
+
+ * vesbose CLI output; fix #666
+ * pull `SHIFT` transforms; currently this is semantically dead code;
+ later it will be used by "Shared-Brotli"
+---
+ c/common/transform.c | 56 ++++
+ c/common/transform.h | 5 +
+ c/enc/backward_references.h | 6 +-
+ c/enc/backward_references_hq.c | 11 +-
+ c/enc/backward_references_hq.h | 10 +-
+ c/enc/backward_references_inc.h | 6 +-
+ c/enc/encode.c | 2 -
+ c/enc/encoder_dict.c | 1 -
+ c/tools/brotli.c | 54 ++-
+ java/org/brotli/dec/BrotliInputStream.java | 12 +-
+ java/org/brotli/dec/Decode.java | 63 ++--
+ java/org/brotli/dec/SynthTest.java | 513 ++++++++++++++++++++++++++++-
+ java/org/brotli/dec/Transform.java | 183 ++++++++--
+ java/org/brotli/dec/TransformTest.java | 14 +-
+ 14 files changed, 848 insertions(+), 88 deletions(-)
+
+diff --git a/c/common/transform.c b/c/common/transform.c
+index 426e635..c182053 100755
+--- a/c/common/transform.c
++++ b/c/common/transform.c
+@@ -166,6 +166,7 @@ static BrotliTransforms kBrotliTransforms = {
+ kPrefixSuffixMap,
+ sizeof(kTransformsData) / (3 * sizeof(kTransformsData[0])),
+ kTransformsData,
++ NULL, /* no extra parameters */
+ {0, 12, 27, 23, 42, 63, 56, 48, 59, 64}
+ };
+
+@@ -190,6 +191,48 @@ static int ToUpperCase(uint8_t* p) {
+ return 3;
+ }
+
++static int Shift(uint8_t* word, int word_len, uint16_t parameter) {
++ /* Limited sign extension: scalar < (1 << 24). */
++ uint32_t scalar =
++ (parameter & 0x7FFFu) + (0x1000000u - (parameter & 0x8000u));
++ if (word[0] < 0x80) {
++ /* 1-byte rune / 0sssssss / 7 bit scalar (ASCII). */
++ scalar += (uint32_t)word[0];
++ word[0] = (uint8_t)(scalar & 0x7Fu);
++ return 1;
++ } else if (word[0] < 0xC0) {
++ /* Continuation / 10AAAAAA. */
++ return 1;
++ } else if (word[0] < 0xE0) {
++ /* 2-byte rune / 110sssss AAssssss / 11 bit scalar. */
++ if (word_len < 2) return 1;
++ scalar += (uint32_t)((word[1] & 0x3Fu) | ((word[0] & 0x1Fu) << 6u));
++ word[0] = (uint8_t)(0xC0 | ((scalar >> 6u) & 0x1F));
++ word[1] = (uint8_t)((word[1] & 0xC0) | (scalar & 0x3F));
++ return 2;
++ } else if (word[0] < 0xF0) {
++ /* 3-byte rune / 1110ssss AAssssss BBssssss / 16 bit scalar. */
++ if (word_len < 3) return word_len;
++ scalar += (uint32_t)((word[2] & 0x3Fu) | ((word[1] & 0x3Fu) << 6u) |
++ ((word[0] & 0x0Fu) << 12u));
++ word[0] = (uint8_t)(0xE0 | ((scalar >> 12u) & 0x0F));
++ word[1] = (uint8_t)((word[1] & 0xC0) | ((scalar >> 6u) & 0x3F));
++ word[2] = (uint8_t)((word[2] & 0xC0) | (scalar & 0x3F));
++ return 3;
++ } else if (word[0] < 0xF8) {
++ /* 4-byte rune / 11110sss AAssssss BBssssss CCssssss / 21 bit scalar. */
++ if (word_len < 4) return word_len;
++ scalar += (uint32_t)((word[3] & 0x3Fu) | ((word[2] & 0x3Fu) << 6u) |
++ ((word[1] & 0x3Fu) << 12u) | ((word[0] & 0x07u) << 18u));
++ word[0] = (uint8_t)(0xF0 | ((scalar >> 18u) & 0x07));
++ word[1] = (uint8_t)((word[1] & 0xC0) | ((scalar >> 12u) & 0x3F));
++ word[2] = (uint8_t)((word[2] & 0xC0) | ((scalar >> 6u) & 0x3F));
++ word[3] = (uint8_t)((word[3] & 0xC0) | (scalar & 0x3F));
++ return 4;
++ }
++ return 1;
++}
++
+ int BrotliTransformDictionaryWord(uint8_t* dst, const uint8_t* word, int len,
+ const BrotliTransforms* transforms, int transform_idx) {
+ int idx = 0;
+@@ -221,6 +264,19 @@ int BrotliTransformDictionaryWord(uint8_t* dst, const uint8_t* word, int len,
+ uppercase += step;
+ len -= step;
+ }
++ } else if (t == BROTLI_TRANSFORM_SHIFT_FIRST) {
++ uint16_t param = (uint16_t)(transforms->params[transform_idx * 2]
++ + (transforms->params[transform_idx * 2 + 1] << 8u));
++ Shift(&dst[idx - len], len, param);
++ } else if (t == BROTLI_TRANSFORM_SHIFT_ALL) {
++ uint16_t param = (uint16_t)(transforms->params[transform_idx * 2]
++ + (transforms->params[transform_idx * 2 + 1] << 8u));
++ uint8_t* shift = &dst[idx - len];
++ while (len > 0) {
++ int step = Shift(shift, len, param);
++ shift += step;
++ len -= step;
++ }
+ }
+ }
+ {
+diff --git a/c/common/transform.h b/c/common/transform.h
+index 456c12d..b6f86cc 100755
+--- a/c/common/transform.h
++++ b/c/common/transform.h
+@@ -37,6 +37,8 @@ enum BrotliWordTransformType {
+ BROTLI_TRANSFORM_OMIT_FIRST_7 = 18,
+ BROTLI_TRANSFORM_OMIT_FIRST_8 = 19,
+ BROTLI_TRANSFORM_OMIT_FIRST_9 = 20,
++ BROTLI_TRANSFORM_SHIFT_FIRST = 21,
++ BROTLI_TRANSFORM_SHIFT_ALL = 22,
+ BROTLI_NUM_TRANSFORM_TYPES /* Counts transforms, not a transform itself. */
+ };
+
+@@ -50,6 +52,9 @@ typedef struct BrotliTransforms {
+ uint32_t num_transforms;
+ /* Each entry is a [prefix_id, transform, suffix_id] triplet. */
+ const uint8_t* transforms;
++ /* Shift for BROTLI_TRANSFORM_SHIFT_FIRST and BROTLI_TRANSFORM_SHIFT_ALL,
++ must be NULL if and only if no such transforms are present. */
++ const uint8_t* params;
+ /* Indices of transforms like ["", BROTLI_TRANSFORM_OMIT_LAST_#, ""].
+ 0-th element corresponds to ["", BROTLI_TRANSFORM_IDENTITY, ""].
+ -1, if cut-off transform does not exist. */
+diff --git a/c/enc/backward_references.h b/c/enc/backward_references.h
+index 3a41466..f82a80d 100644
+--- a/c/enc/backward_references.h
++++ b/c/enc/backward_references.h
+@@ -25,9 +25,9 @@ extern "C" {
+ initially the total amount of commands output by previous
+ CreateBackwardReferences calls, and must be incremented by the amount written
+ by this call. */
+-BROTLI_INTERNAL void BrotliCreateBackwardReferences(
+- size_t num_bytes, size_t position, const uint8_t* ringbuffer,
+- size_t ringbuffer_mask, const BrotliEncoderParams* params,
++BROTLI_INTERNAL void BrotliCreateBackwardReferences(size_t num_bytes,
++ size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
++ const BrotliEncoderParams* params,
+ HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
+ Command* commands, size_t* num_commands, size_t* num_literals);
+
+diff --git a/c/enc/backward_references_hq.c b/c/enc/backward_references_hq.c
+index 96b0e70..5737f75 100644
+--- a/c/enc/backward_references_hq.c
++++ b/c/enc/backward_references_hq.c
+@@ -419,8 +419,8 @@ static size_t UpdateNodes(
+ size_t k;
+ size_t gap = 0;
+
+- EvaluateNode(block_start, pos, max_backward_limit, gap, starting_dist_cache,
+- model, queue, nodes);
++ EvaluateNode(block_start, pos, max_backward_limit, gap,
++ starting_dist_cache, model, queue, nodes);
+
+ {
+ const PosData* posdata = StartPosQueueAt(queue, 0);
+@@ -587,9 +587,10 @@ void BrotliZopfliCreateCommands(const size_t num_bytes,
+ {
+ size_t distance = ZopfliNodeCopyDistance(next);
+ size_t len_code = ZopfliNodeLengthCode(next);
+- size_t max_distance =
+- BROTLI_MIN(size_t, block_start + pos, max_backward_limit);
+- BROTLI_BOOL is_dictionary = TO_BROTLI_BOOL(distance > max_distance + gap);
++ size_t max_distance = BROTLI_MIN(size_t,
++ block_start + pos, max_backward_limit);
++ BROTLI_BOOL is_dictionary =
++ TO_BROTLI_BOOL(distance > max_distance + gap);
+ size_t dist_code = ZopfliNodeDistanceCode(next);
+ InitCommand(&commands[i], ¶ms->dist, insert_length,
+ copy_length, (int)len_code - (int)copy_length, dist_code);
+diff --git a/c/enc/backward_references_hq.h b/c/enc/backward_references_hq.h
+index 1e4275d..fb1ff3f 100644
+--- a/c/enc/backward_references_hq.h
++++ b/c/enc/backward_references_hq.h
+@@ -23,14 +23,16 @@ extern "C" {
+ #endif
+
+ BROTLI_INTERNAL void BrotliCreateZopfliBackwardReferences(MemoryManager* m,
+- size_t num_bytes, size_t position, const uint8_t* ringbuffer,
+- size_t ringbuffer_mask, const BrotliEncoderParams* params,
++ size_t num_bytes,
++ size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
++ const BrotliEncoderParams* params,
+ HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
+ Command* commands, size_t* num_commands, size_t* num_literals);
+
+ BROTLI_INTERNAL void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m,
+- size_t num_bytes, size_t position, const uint8_t* ringbuffer,
+- size_t ringbuffer_mask, const BrotliEncoderParams* params,
++ size_t num_bytes,
++ size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
++ const BrotliEncoderParams* params,
+ HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
+ Command* commands, size_t* num_commands, size_t* num_literals);
+
+diff --git a/c/enc/backward_references_inc.h b/c/enc/backward_references_inc.h
+index c18cdb0..e29daf3 100644
+--- a/c/enc/backward_references_inc.h
++++ b/c/enc/backward_references_inc.h
+@@ -60,7 +60,8 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
+ FN(FindLongestMatch)(hasher,
+ ¶ms->dictionary,
+ ringbuffer, ringbuffer_mask, dist_cache, position + 1, max_length,
+- max_distance, gap, params->dist.max_distance, &sr2);
++ max_distance, gap, params->dist.max_distance,
++ &sr2);
+ if (sr2.score >= sr.score + cost_diff_lazy) {
+ /* Ok, let's just write one byte for now and start a match from the
+ next byte. */
+@@ -76,7 +77,8 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
+ }
+ apply_random_heuristics =
+ position + 2 * sr.len + random_heuristics_window_size;
+- max_distance = BROTLI_MIN(size_t, position, max_backward_limit);
++ max_distance = BROTLI_MIN(size_t,
++ position, max_backward_limit);
+ {
+ /* The first 16 codes are special short-codes,
+ and the minimum offset is 1. */
+diff --git a/c/enc/encode.c b/c/enc/encode.c
+index 141e70a..c82f2d3 100644
+--- a/c/enc/encode.c
++++ b/c/enc/encode.c
+@@ -114,8 +114,6 @@ typedef struct BrotliEncoderStateStruct {
+ BROTLI_BOOL is_initialized_;
+ } BrotliEncoderStateStruct;
+
+-static BROTLI_BOOL EnsureInitialized(BrotliEncoderState* s);
+-
+ static size_t InputBlockSize(BrotliEncoderState* s) {
+ return (size_t)1 << s->params.lgblock;
+ }
+diff --git a/c/enc/encoder_dict.c b/c/enc/encoder_dict.c
+index 8b2f6ad..e58ca67 100755
+--- a/c/enc/encoder_dict.c
++++ b/c/enc/encoder_dict.c
+@@ -24,7 +24,6 @@ void BrotliInitEncoderDictionary(BrotliEncoderDictionary* dict) {
+
+ dict->cutoffTransformsCount = kCutoffTransformsCount;
+ dict->cutoffTransforms = kCutoffTransforms;
+-
+ }
+
+ #if defined(__cplusplus) || defined(c_plusplus)
+diff --git a/c/tools/brotli.c b/c/tools/brotli.c
+index ce05b64..838539a 100644
+--- a/c/tools/brotli.c
++++ b/c/tools/brotli.c
+@@ -86,10 +86,10 @@ typedef struct {
+ /* Parameters */
+ int quality;
+ int lgwin;
++ int verbosity;
+ BROTLI_BOOL force_overwrite;
+ BROTLI_BOOL junk_source;
+ BROTLI_BOOL copy_stat;
+- BROTLI_BOOL verbose;
+ BROTLI_BOOL write_to_stdout;
+ BROTLI_BOOL test_integrity;
+ BROTLI_BOOL decompress;
+@@ -121,6 +121,12 @@ typedef struct {
+ const uint8_t* next_in;
+ size_t available_out;
+ uint8_t* next_out;
++
++ /* Reporting */
++ /* size_t would be large enough,
++ until 4GiB+ files are compressed / decompressed on 32-bit CPUs. */
++ size_t total_in;
++ size_t total_out;
+ } Context;
+
+ /* Parse up to 5 decimal digits. */
+@@ -279,11 +285,11 @@ static Command ParseParams(Context* params) {
+ command = COMMAND_TEST_INTEGRITY;
+ continue;
+ } else if (c == 'v') {
+- if (params->verbose) {
++ if (params->verbosity > 0) {
+ fprintf(stderr, "argument --verbose / -v already set\n");
+ return COMMAND_INVALID;
+ }
+- params->verbose = BROTLI_TRUE;
++ params->verbosity = 1;
+ continue;
+ } else if (c == 'V') {
+ /* Don't parse further. */
+@@ -415,11 +421,11 @@ static Command ParseParams(Context* params) {
+ command_set = BROTLI_TRUE;
+ command = COMMAND_TEST_INTEGRITY;
+ } else if (strcmp("verbose", arg) == 0) {
+- if (params->verbose) {
++ if (params->verbosity > 0) {
+ fprintf(stderr, "argument --verbose / -v already set\n");
+ return COMMAND_INVALID;
+ }
+- params->verbose = BROTLI_TRUE;
++ params->verbosity = 1;
+ } else if (strcmp("version", arg) == 0) {
+ /* Don't parse further. */
+ return COMMAND_VERSION;
+@@ -787,6 +793,8 @@ static void InitializeBuffers(Context* context) {
+ context->next_in = NULL;
+ context->available_out = kFileBufferSize;
+ context->next_out = context->output;
++ context->total_in = 0;
++ context->total_out = 0;
+ }
+
+ static BROTLI_BOOL HasMoreInput(Context* context) {
+@@ -796,6 +804,7 @@ static BROTLI_BOOL HasMoreInput(Context* context) {
+ static BROTLI_BOOL ProvideInput(Context* context) {
+ context->available_in =
+ fread(context->input, 1, kFileBufferSize, context->fin);
++ context->total_in += context->available_in;
+ context->next_in = context->input;
+ if (ferror(context->fin)) {
+ fprintf(stderr, "failed to read input [%s]: %s\n",
+@@ -808,6 +817,7 @@ static BROTLI_BOOL ProvideInput(Context* context) {
+ /* Internal: should be used only in Provide-/Flush-Output. */
+ static BROTLI_BOOL WriteOutput(Context* context) {
+ size_t out_size = (size_t)(context->next_out - context->output);
++ context->total_out += out_size;
+ if (out_size == 0) return BROTLI_TRUE;
+ if (context->test_integrity) return BROTLI_TRUE;
+
+@@ -833,6 +843,25 @@ static BROTLI_BOOL FlushOutput(Context* context) {
+ return BROTLI_TRUE;
+ }
+
++static void PrintBytes(size_t value) {
++ if (value < 1024) {
++ fprintf(stderr, "%d B", (int)value);
++ } else if (value < 1048576) {
++ fprintf(stderr, "%0.3f KiB", (double)value / 1024.0);
++ } else if (value < 1073741824) {
++ fprintf(stderr, "%0.3f MiB", (double)value / 1048576.0);
++ } else {
++ fprintf(stderr, "%0.3f GiB", (double)value / 1073741824.0);
++ }
++}
++
++static void PrintFileProcessingProgress(Context* context) {
++ fprintf(stderr, "[%s]: ", PrintablePath(context->current_input_path));
++ PrintBytes(context->total_in);
++ fprintf(stderr, " -> ");
++ PrintBytes(context->total_out);
++}
++
+ static BROTLI_BOOL DecompressFile(Context* context, BrotliDecoderState* s) {
+ BrotliDecoderResult result = BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT;
+ InitializeBuffers(context);
+@@ -853,6 +882,11 @@ static BROTLI_BOOL DecompressFile(Context* context, BrotliDecoderState* s) {
+ PrintablePath(context->current_input_path));
+ return BROTLI_FALSE;
+ }
++ if (context->verbosity > 0) {
++ fprintf(stderr, "Decompressed ");
++ PrintFileProcessingProgress(context);
++ fprintf(stderr, "\n");
++ }
+ return BROTLI_TRUE;
+ } else {
+ fprintf(stderr, "corrupt input [%s]\n",
+@@ -915,7 +949,13 @@ static BROTLI_BOOL CompressFile(Context* context, BrotliEncoderState* s) {
+ }
+
+ if (BrotliEncoderIsFinished(s)) {
+- return FlushOutput(context);
++ if (!FlushOutput(context)) return BROTLI_FALSE;
++ if (context->verbosity > 0) {
++ fprintf(stderr, "Compressed ");
++ PrintFileProcessingProgress(context);
++ fprintf(stderr, "\n");
++ }
++ return BROTLI_TRUE;
+ }
+ }
+ }
+@@ -979,11 +1019,11 @@ int main(int argc, char** argv) {
+
+ context.quality = 11;
+ context.lgwin = -1;
++ context.verbosity = 0;
+ context.force_overwrite = BROTLI_FALSE;
+ context.junk_source = BROTLI_FALSE;
+ context.copy_stat = BROTLI_TRUE;
+ context.test_integrity = BROTLI_FALSE;
+- context.verbose = BROTLI_FALSE;
+ context.write_to_stdout = BROTLI_FALSE;
+ context.decompress = BROTLI_FALSE;
+ context.large_window = BROTLI_FALSE;
+diff --git a/java/org/brotli/dec/BrotliInputStream.java b/java/org/brotli/dec/BrotliInputStream.java
+index a27e928..5cc2e28 100644
+--- a/java/org/brotli/dec/BrotliInputStream.java
++++ b/java/org/brotli/dec/BrotliInputStream.java
+@@ -85,7 +85,17 @@ public class BrotliInputStream extends InputStream {
+ }
+
+ public void setEager(boolean eager) {
+- state.isEager = eager ? 1 : 0;
++ boolean isEager = (state.isEager != 0);
++ if (eager == isEager) {
++ /* Shortcut for no-op change. */
++ return;
++ }
++ if (eager) {
++ Decode.setEager(state);
++ } else {
++ /* Once decoder is "eager", there is no way back. */
++ throw new IllegalStateException("Brotli decoder has been already switched to eager mode");
++ }
+ }
+
+ /**
+diff --git a/java/org/brotli/dec/Decode.java b/java/org/brotli/dec/Decode.java
+index 9e3d43b..60bf9c6 100644
+--- a/java/org/brotli/dec/Decode.java
++++ b/java/org/brotli/dec/Decode.java
+@@ -18,18 +18,19 @@ final class Decode {
+ // RunningState
+ //----------------------------------------------------------------------------
+ private static final int UNINITIALIZED = 0;
+- private static final int BLOCK_START = 1;
+- private static final int COMPRESSED_BLOCK_START = 2;
+- private static final int MAIN_LOOP = 3;
+- private static final int READ_METADATA = 4;
+- private static final int COPY_UNCOMPRESSED = 5;
+- private static final int INSERT_LOOP = 6;
+- private static final int COPY_LOOP = 7;
+- private static final int TRANSFORM = 8;
+- private static final int FINISHED = 9;
+- private static final int CLOSED = 10;
+- private static final int INIT_WRITE = 11;
+- private static final int WRITE = 12;
++ private static final int INITIALIZED = 1;
++ private static final int BLOCK_START = 2;
++ private static final int COMPRESSED_BLOCK_START = 3;
++ private static final int MAIN_LOOP = 4;
++ private static final int READ_METADATA = 5;
++ private static final int COPY_UNCOMPRESSED = 6;
++ private static final int INSERT_LOOP = 7;
++ private static final int COPY_LOOP = 8;
++ private static final int TRANSFORM = 9;
++ private static final int FINISHED = 10;
++ private static final int CLOSED = 11;
++ private static final int INIT_WRITE = 12;
++ private static final int WRITE = 13;
+
+ private static final int DEFAULT_CODE_LENGTH = 8;
+ private static final int CODE_LENGTH_REPEAT_CODE = 16;
+@@ -140,6 +141,20 @@ final class Decode {
+ }
+
+ /**
++ * Switch decoder to "eager" mode.
++ *
++ * In "eager" mode decoder returns as soon as there is enough data to fill output buffer.
++ *
++ * @param s initialized state, before any read is performed.
++ */
++ static void setEager(State s) {
++ if (s.runningState != INITIALIZED) {
++ throw new IllegalStateException("State MUST be freshly initialized");
++ }
++ s.isEager = 1;
++ }
++
++ /**
+ * Associate input with decoder state.
+ *
+ * @param s uninitialized state without associated input
+@@ -152,13 +167,7 @@ final class Decode {
+ s.blockTrees = new int[6 * HUFFMAN_TABLE_SIZE];
+ s.input = input;
+ BitReader.initBitReader(s);
+- int windowBits = decodeWindowBits(s);
+- if (windowBits == 9) { /* Reserved case for future expansion. */
+- throw new BrotliRuntimeException("Invalid 'windowBits' code");
+- }
+- s.maxRingBufferSize = 1 << windowBits;
+- s.maxBackwardDistance = s.maxRingBufferSize - 16;
+- s.runningState = BLOCK_START;
++ s.runningState = INITIALIZED;
+ }
+
+ static void close(State s) throws IOException {
+@@ -727,6 +736,16 @@ final class Decode {
+ if (s.runningState == CLOSED) {
+ throw new IllegalStateException("Can't decompress after close");
+ }
++ if (s.runningState == INITIALIZED) {
++ int windowBits = decodeWindowBits(s);
++ if (windowBits == 9) { /* Reserved case for future expansion. */
++ throw new BrotliRuntimeException("Invalid 'windowBits' code");
++ }
++ s.maxRingBufferSize = 1 << windowBits;
++ s.maxBackwardDistance = s.maxRingBufferSize - 16;
++ s.runningState = BLOCK_START;
++ }
++
+ int fence = calculateFence(s);
+ int ringBufferMask = s.ringBufferSize - 1;
+ byte[] ringBuffer = s.ringBuffer;
+@@ -935,9 +954,9 @@ final class Decode {
+ int wordIdx = wordId & mask;
+ int transformIdx = wordId >>> shift;
+ offset += wordIdx * s.copyLength;
+- if (transformIdx < Transform.NUM_TRANSFORMS) {
+- int len = Transform.transformDictionaryWord(ringBuffer, s.pos,
+- Dictionary.getData(), offset, s.copyLength, transformIdx);
++ if (transformIdx < Transform.NUM_RFC_TRANSFORMS) {
++ int len = Transform.transformDictionaryWord(ringBuffer, s.pos, Dictionary.getData(),
++ offset, s.copyLength, Transform.RFC_TRANSFORMS, transformIdx);
+ s.pos += len;
+ s.metaBlockLength -= len;
+ if (s.pos >= fence) {
+diff --git a/java/org/brotli/dec/SynthTest.java b/java/org/brotli/dec/SynthTest.java
+index c95a3c9..de91c37 100644
+--- a/java/org/brotli/dec/SynthTest.java
++++ b/java/org/brotli/dec/SynthTest.java
+@@ -65,6 +65,474 @@ public class SynthTest {
+ /* GENERATED CODE START */
+
+ @Test
++ public void testAllTransforms10() {
++ byte[] compressed = {
++ (byte) 0x1b, (byte) 0xfc, (byte) 0x05, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
++ (byte) 0xe3, (byte) 0xb4, (byte) 0x0d, (byte) 0x00, (byte) 0x00, (byte) 0x07, (byte) 0x5b,
++ (byte) 0x26, (byte) 0x31, (byte) 0x40, (byte) 0x02, (byte) 0x00, (byte) 0xe0, (byte) 0x4e,
++ (byte) 0x1b, (byte) 0x13, (byte) 0x7c, (byte) 0x84, (byte) 0x26, (byte) 0xf8, (byte) 0x04,
++ (byte) 0x10, (byte) 0x4c, (byte) 0xf0, (byte) 0x89, (byte) 0x38, (byte) 0x30, (byte) 0xc1,
++ (byte) 0x27, (byte) 0x4e, (byte) 0xc1, (byte) 0x04, (byte) 0x9f, (byte) 0x64, (byte) 0x06,
++ (byte) 0x26, (byte) 0xf8, (byte) 0x24, (byte) 0x3f, (byte) 0x34, (byte) 0xc1, (byte) 0x27,
++ (byte) 0x7d, (byte) 0x82, (byte) 0x09, (byte) 0x3e, (byte) 0xe9, (byte) 0x16, (byte) 0x4d,
++ (byte) 0xf0, (byte) 0xc9, (byte) 0xd2, (byte) 0xc0, (byte) 0x04, (byte) 0x9f, (byte) 0x0c,
++ (byte) 0x8f, (byte) 0x4c, (byte) 0xf0, (byte) 0xc9, (byte) 0x06, (byte) 0xd1, (byte) 0x04,
++ (byte) 0x9f, (byte) 0x6c, (byte) 0x92, (byte) 0x4d, (byte) 0xf0, (byte) 0xc9, (byte) 0x39,
++ (byte) 0xc1, (byte) 0x04, (byte) 0x9f, (byte) 0xdc, (byte) 0x94, (byte) 0x4c, (byte) 0xf0,
++ (byte) 0xc9, (byte) 0x69, (byte) 0xd1, (byte) 0x04, (byte) 0x9f, (byte) 0x3c, (byte) 0x98,
++ (byte) 0x4d, (byte) 0xf0, (byte) 0x29, (byte) 0x9c, (byte) 0x81, (byte) 0x09, (byte) 0x3e,
++ (byte) 0x45, (byte) 0x37, (byte) 0x31, (byte) 0xc1, (byte) 0xa7, (byte) 0x60, (byte) 0x47,
++ (byte) 0x26, (byte) 0xf8, (byte) 0x14, (byte) 0xfa, (byte) 0xcc, (byte) 0x04, (byte) 0x9f,
++ (byte) 0xc2, (byte) 0x20, (byte) 0x9a, (byte) 0xe0, (byte) 0x53, (byte) 0x48, (byte) 0x54,
++ (byte) 0x13, (byte) 0x7c, (byte) 0x8a, (byte) 0x8f, (byte) 0x6c, (byte) 0x82, (byte) 0x4f,
++ (byte) 0xb1, (byte) 0xd2, (byte) 0x4d, (byte) 0xf0, (byte) 0x29, (byte) 0x67, (byte) 0x82,
++ (byte) 0x09, (byte) 0x3e, (byte) 0xe5, (byte) 0x4f, (byte) 0x31, (byte) 0xc1, (byte) 0xa7,
++ (byte) 0x7c, (byte) 0x4a, (byte) 0x26, (byte) 0xf8, (byte) 0x94, (byte) 0x57, (byte) 0xcd,
++ (byte) 0x04, (byte) 0x9f, (byte) 0x12, (byte) 0x2c, (byte) 0x9a, (byte) 0xe0, (byte) 0x53,
++ (byte) 0xba, (byte) 0x55, (byte) 0x13, (byte) 0x7c, (byte) 0xca, (byte) 0xbf, (byte) 0x6c,
++ (byte) 0x82, (byte) 0x4f, (byte) 0xb9, (byte) 0xd8, (byte) 0x4d, (byte) 0xf0, (byte) 0xa9,
++ (byte) 0x30, (byte) 0x03, (byte) 0x13, (byte) 0x7c, (byte) 0x2a, (byte) 0xd2, (byte) 0xc2,
++ (byte) 0x04, (byte) 0x9f, (byte) 0x4a, (byte) 0x36, (byte) 0x31, (byte) 0xc1, (byte) 0xa7,
++ (byte) 0xca, (byte) 0x6d, (byte) 0x4c, (byte) 0xf0, (byte) 0xa9, (byte) 0x94, (byte) 0x23,
++ (byte) 0x13, (byte) 0x7c, (byte) 0x2a, (byte) 0xeb, (byte) 0xca, (byte) 0x04, (byte) 0x9f,
++ (byte) 0xea, (byte) 0x3c, (byte) 0x33, (byte) 0xc1, (byte) 0xa7, (byte) 0xb2, (byte) 0xef,
++ (byte) 0x4c, (byte) 0xf0, (byte) 0xa9, (byte) 0xf8, (byte) 0x43, (byte) 0x13, (byte) 0x7c,
++ (byte) 0xaa, (byte) 0x00, (byte) 0xd3, (byte) 0x04, (byte) 0x9f, (byte) 0x2a, (byte) 0x42,
++ (byte) 0x35, (byte) 0xc1, (byte) 0xa7, (byte) 0xc2, (byte) 0x70, (byte) 0x4d, (byte) 0xf0,
++ (byte) 0xa9, (byte) 0x52, (byte) 0x64, (byte) 0x13, (byte) 0x7c, (byte) 0x2a, (byte) 0x1a,
++ (byte) 0xdb, (byte) 0x04, (byte) 0x9f, (byte) 0x6a, (byte) 0x48, (byte) 0x37, (byte) 0xc1,
++ (byte) 0xa7, (byte) 0x92, (byte) 0xf2, (byte) 0x4d, (byte) 0xf0, (byte) 0xa9, (byte) 0xc3,
++ (byte) 0x04, (byte) 0x13, (byte) 0x7c, (byte) 0xea, (byte) 0x32, (byte) 0xc3, (byte) 0x04,
++ (byte) 0x9f, (byte) 0x7a, (byte) 0x4e, (byte) 0x31, (byte) 0xc1, (byte) 0xa7, (byte) 0x06,
++ (byte) 0x74, (byte) 0x4c, (byte) 0xf0, (byte) 0xa9, (byte) 0x19, (byte) 0x25, (byte) 0x13,
++ (byte) 0x7c, (byte) 0x6a, (byte) 0x4d, (byte) 0xcb, (byte) 0x04, (byte) 0x9f, (byte) 0x1a,
++ (byte) 0x55, (byte) 0x33, (byte) 0xc1, (byte) 0xa7, (byte) 0x56, (byte) 0xf5, (byte) 0x4c,
++ (byte) 0xf0, (byte) 0xa9, (byte) 0x5d, (byte) 0x45, (byte) 0x13, (byte) 0x7c, (byte) 0xea,
++ (byte) 0x59, (byte) 0xd3, (byte) 0x04, (byte) 0x9f, (byte) 0xfa, (byte) 0x57, (byte) 0x35,
++ (byte) 0xc1, (byte) 0xa7, (byte) 0x66, (byte) 0x76, (byte) 0x4d, (byte) 0xf0, (byte) 0xa9,
++ (byte) 0x9f, (byte) 0x65, (byte) 0x13, (byte) 0x7c, (byte) 0x6a, (byte) 0x6f, (byte) 0xdb,
++ (byte) 0x04, (byte) 0x9f, (byte) 0x9a, (byte) 0x5d, (byte) 0x37, (byte) 0xc1, (byte) 0xa7,
++ (byte) 0x06, (byte) 0xf8, (byte) 0x4d, (byte) 0xf0, (byte) 0x69, (byte) 0x0c, (byte) 0x06,
++ (byte) 0x26, (byte) 0xf8, (byte) 0x34, (byte) 0x08, (byte) 0x07, (byte) 0x13, (byte) 0x7c,
++ (byte) 0x1a, (byte) 0x8b, (byte) 0x85, (byte) 0x09, (byte) 0x3e, (byte) 0x8d, (byte) 0xc8,
++ (byte) 0xc3, (byte) 0x04, (byte) 0x9f, (byte) 0xe6, (byte) 0x65, (byte) 0x62, (byte) 0x82,
++ (byte) 0x4f, (byte) 0xb3, (byte) 0x73, (byte) 0x31, (byte) 0xc1, (byte) 0xa7, (byte) 0x41,
++ (byte) 0xda, (byte) 0x98, (byte) 0xe0, (byte) 0xd3, (byte) 0x54, (byte) 0x7d, (byte) 0x4c,
++ (byte) 0xf0, (byte) 0x69, (byte) 0xc4, (byte) 0x46, (byte) 0x26, (byte) 0xf8, (byte) 0x34,
++ (byte) 0x72, (byte) 0x27, (byte) 0x13, (byte) 0x7c, (byte) 0x1a, (byte) 0xc5, (byte) 0x95,
++ (byte) 0x09, (byte) 0x3e, (byte) 0x8d, (byte) 0xe5, (byte) 0xcb, (byte) 0x04, (byte) 0x9f,
++ (byte) 0x06, (byte) 0x75, (byte) 0x66, (byte) 0x82, (byte) 0x4f, (byte) 0x43, (byte) 0x7b,
++ (byte) 0x33, (byte) 0xc1, (byte) 0xa7, (byte) 0x09, (byte) 0xde, (byte) 0x99, (byte) 0xe0,
++ (byte) 0xd3, (byte) 0x34, (byte) 0xff, (byte) 0x4c, (byte) 0xf0, (byte) 0x69, (byte) 0xb2,
++ (byte) 0x87, (byte) 0x26, (byte) 0xf8, (byte) 0x34, (byte) 0xe9, (byte) 0x47, (byte) 0x13,
++ (byte) 0x7c, (byte) 0x9a, (byte) 0xfb, (byte) 0xa5, (byte) 0x09, (byte) 0x3e, (byte) 0x4d,
++ (byte) 0x01, (byte) 0xd4, (byte) 0x04, (byte) 0x9f, (byte) 0x46, (byte) 0x82, (byte) 0x6a,
++ (byte) 0x82, (byte) 0x4f, (byte) 0x03, (byte) 0x82, (byte) 0x35, (byte) 0xc1, (byte) 0xa7,
++ (byte) 0x61, (byte) 0xe1, (byte) 0x9a, (byte) 0xe0, (byte) 0xd3, (byte) 0xe4, (byte) 0x80,
++ (byte) 0x4d, (byte) 0xf0, (byte) 0x69, (byte) 0x8a, (byte) 0xc8, (byte) 0x26, (byte) 0xf8,
++ (byte) 0x34, (byte) 0x52, (byte) 0x68, (byte) 0x13, (byte) 0x7c, (byte) 0x9a, (byte) 0x2f,
++ (byte) 0xb6, (byte) 0x09, (byte) 0x3e, (byte) 0x8d, (byte) 0x1b, (byte) 0xdc, (byte) 0x04,
++ (byte) 0x9f, (byte) 0x86, (byte) 0x8f, (byte) 0x6e, (byte) 0x82, (byte) 0x4f, (byte) 0xb3,
++ (byte) 0x88, (byte) 0x37, (byte) 0xc1, (byte) 0xa7, (byte) 0xd9, (byte) 0xe4, (byte) 0x9b,
++ (byte) 0xe0, (byte) 0xd3, (byte) 0x9e, (byte) 0x02, (byte) 0x4c, (byte) 0xf0, (byte) 0x69,
++ (byte) 0x6d, (byte) 0x09, (byte) 0x26, (byte) 0xf8, (byte) 0xb4, (byte) 0xc3, (byte) 0x08,
++ (byte) 0x13, (byte) 0x7c, (byte) 0x5a, (byte) 0x68, (byte) 0x86, (byte) 0x09, (byte) 0x3e,
++ (byte) 0xad, (byte) 0x37, (byte) 0xc4, (byte) 0x04, (byte) 0x9f, (byte) 0x56, (byte) 0x9d,
++ (byte) 0x62, (byte) 0x82, (byte) 0x4f, (byte) 0x9b, (byte) 0x8f, (byte) 0x31, (byte) 0xc1,
++ (byte) 0xa7, (byte) 0x2d, (byte) 0xe8, (byte) 0x98, (byte) 0xe0, (byte) 0xd3, (byte) 0x4a,
++ (byte) 0x84, (byte) 0x4c, (byte) 0xf0, (byte) 0x69, (byte) 0x3f, (byte) 0x4a, (byte) 0x26,
++ (byte) 0xf8, (byte) 0xb4, (byte) 0x2c, (byte) 0x29, (byte) 0x13, (byte) 0x7c, (byte) 0xda,
++ (byte) 0x9c, (byte) 0x96, (byte) 0x09, (byte) 0x3e, (byte) 0x2d, (byte) 0x52, (byte) 0xcc,
++ (byte) 0x04, (byte) 0x9f, (byte) 0xb6, (byte) 0xaa, (byte) 0x66, (byte) 0x82, (byte) 0x4f,
++ (byte) 0x2b, (byte) 0x96, (byte) 0x33, (byte) 0xc1, (byte) 0xa7, (byte) 0x7d, (byte) 0xeb,
++ (byte) 0x99, (byte) 0xe0, (byte) 0xd3, (byte) 0xf6, (byte) 0x05, (byte) 0x4d, (byte) 0xf0,
++ (byte) 0x69, (byte) 0x17, (byte) 0x8b, (byte) 0x26, (byte) 0xf8, (byte) 0xb4, (byte) 0x97,
++ (byte) 0x49, (byte) 0x13, (byte) 0x7c, (byte) 0xda, (byte) 0xd1, (byte) 0xa6, (byte) 0x09,
++ (byte) 0x3e, (byte) 0x2d, (byte) 0x6c, (byte) 0xd4, (byte) 0x04, (byte) 0x9f, (byte) 0xb6,
++ (byte) 0xb7, (byte) 0x6a, (byte) 0x82, (byte) 0x4f, (byte) 0xab, (byte) 0x9c, (byte) 0x35,
++ (byte) 0xc1, (byte) 0xa7, (byte) 0xc5, (byte) 0xee, (byte) 0x9a, (byte) 0xe0, (byte) 0xd3,
++ (byte) 0x9a, (byte) 0x87, (byte) 0x4d, (byte) 0xf0, (byte) 0x69, (byte) 0xe9, (byte) 0xcb
++ };
++ checkSynth(
++ /*
++ * // The stream consists of word "time" with all possible transforms.
++ * main_header
++ * metablock_header_easy: 1533, 1
++ * command_easy: 10, "|", 2 // = 0 << 10 + 1 + 1
++ * command_easy: 10, "|", 1037 // = 1 << 10 + 1 + 12
++ * command_easy: 10, "|", 2073 // = 2 << 10 + 1 + 24
++ * command_easy: 10, "|", 3110 // = 3 << 10 + 1 + 37
++ * command_easy: 10, "|", 4144 // = 4 << 10 + 1 + 47
++ * command_easy: 10, "|", 5180 // = 5 << 10 + 1 + 59
++ * command_easy: 10, "|", 6220 // = 6 << 10 + 1 + 75
++ * command_easy: 10, "|", 7256 // = 7 << 10 + 1 + 87
++ * command_easy: 10, "|", 8294 // = 8 << 10 + 1 + 101
++ * command_easy: 10, "|", 9333 // = 9 << 10 + 1 + 116
++ * command_easy: 10, "|", 10368 // = 10 << 10 + 1 + 127
++ * command_easy: 10, "|", 11408 // = 11 << 10 + 1 + 143
++ * command_easy: 10, "|", 12441 // = 12 << 10 + 1 + 152
++ * command_easy: 10, "|", 13475 // = 13 << 10 + 1 + 162
++ * command_easy: 10, "|", 14513 // = 14 << 10 + 1 + 176
++ * command_easy: 10, "|", 15550 // = 15 << 10 + 1 + 189
++ * command_easy: 10, "|", 16587 // = 16 << 10 + 1 + 202
++ * command_easy: 10, "|", 17626 // = 17 << 10 + 1 + 217
++ * command_easy: 10, "|", 18665 // = 18 << 10 + 1 + 232
++ * command_easy: 10, "|", 19703 // = 19 << 10 + 1 + 246
++ * command_easy: 10, "|", 20739 // = 20 << 10 + 1 + 258
++ * command_easy: 10, "|", 21775 // = 21 << 10 + 1 + 270
++ * command_easy: 10, "|", 22812 // = 22 << 10 + 1 + 283
++ * command_easy: 10, "|", 23848 // = 23 << 10 + 1 + 295
++ * command_easy: 10, "|", 24880 // = 24 << 10 + 1 + 303
++ * command_easy: 10, "|", 25916 // = 25 << 10 + 1 + 315
++ * command_easy: 10, "|", 26956 // = 26 << 10 + 1 + 331
++ * command_easy: 10, "|", 27988 // = 27 << 10 + 1 + 339
++ * command_easy: 10, "|", 29021 // = 28 << 10 + 1 + 348
++ * command_easy: 10, "|", 30059 // = 29 << 10 + 1 + 362
++ * command_easy: 10, "|", 31100 // = 30 << 10 + 1 + 379
++ * command_easy: 10, "|", 32136 // = 31 << 10 + 1 + 391
++ * command_easy: 10, "|", 33173 // = 32 << 10 + 1 + 404
++ * command_easy: 10, "|", 34209 // = 33 << 10 + 1 + 416
++ * command_easy: 10, "|", 35247 // = 34 << 10 + 1 + 430
++ * command_easy: 10, "|", 36278 // = 35 << 10 + 1 + 437
++ * command_easy: 10, "|", 37319 // = 36 << 10 + 1 + 454
++ * command_easy: 10, "|", 38355 // = 37 << 10 + 1 + 466
++ * command_easy: 10, "|", 39396 // = 38 << 10 + 1 + 483
++ * command_easy: 10, "|", 40435 // = 39 << 10 + 1 + 498
++ * command_easy: 10, "|", 41465 // = 40 << 10 + 1 + 504
++ * command_easy: 10, "|", 42494 // = 41 << 10 + 1 + 509
++ * command_easy: 10, "|", 43534 // = 42 << 10 + 1 + 525
++ * command_easy: 10, "|", 44565 // = 43 << 10 + 1 + 532
++ * command_easy: 10, "|", 45606 // = 44 << 10 + 1 + 549
++ * command_easy: 10, "|", 46641 // = 45 << 10 + 1 + 560
++ * command_easy: 10, "|", 47680 // = 46 << 10 + 1 + 575
++ * command_easy: 10, "|", 48719 // = 47 << 10 + 1 + 590
++ * command_easy: 10, "|", 49758 // = 48 << 10 + 1 + 605
++ * command_easy: 10, "|", 50786 // = 49 << 10 + 1 + 609
++ * command_easy: 10, "|", 51824 // = 50 << 10 + 1 + 623
++ * command_easy: 10, "|", 52861 // = 51 << 10 + 1 + 636
++ * command_easy: 10, "|", 53897 // = 52 << 10 + 1 + 648
++ * command_easy: 10, "|", 54935 // = 53 << 10 + 1 + 662
++ * command_easy: 10, "|", 55973 // = 54 << 10 + 1 + 676
++ * command_easy: 10, "|", 56999 // = 55 << 10 + 1 + 678
++ * command_easy: 10, "|", 58027 // = 56 << 10 + 1 + 682
++ * command_easy: 10, "|", 59056 // = 57 << 10 + 1 + 687
++ * command_easy: 10, "|", 60092 // = 58 << 10 + 1 + 699
++ * command_easy: 10, "|", 61129 // = 59 << 10 + 1 + 712
++ * command_easy: 10, "|", 62156 // = 60 << 10 + 1 + 715
++ * command_easy: 10, "|", 63195 // = 61 << 10 + 1 + 730
++ * command_easy: 10, "|", 64233 // = 62 << 10 + 1 + 744
++ * command_easy: 10, "|", 65277 // = 63 << 10 + 1 + 764
++ * command_easy: 10, "|", 66307 // = 64 << 10 + 1 + 770
++ * command_easy: 10, "|", 67333 // = 65 << 10 + 1 + 772
++ * command_easy: 10, "|", 68371 // = 66 << 10 + 1 + 786
++ * command_easy: 10, "|", 69407 // = 67 << 10 + 1 + 798
++ * command_easy: 10, "|", 70444 // = 68 << 10 + 1 + 811
++ * command_easy: 10, "|", 71480 // = 69 << 10 + 1 + 823
++ * command_easy: 10, "|", 72517 // = 70 << 10 + 1 + 836
++ * command_easy: 10, "|", 73554 // = 71 << 10 + 1 + 849
++ * command_easy: 10, "|", 74591 // = 72 << 10 + 1 + 862
++ * command_easy: 10, "|", 75631 // = 73 << 10 + 1 + 878
++ * command_easy: 10, "|", 76679 // = 74 << 10 + 1 + 902
++ * command_easy: 10, "|", 77715 // = 75 << 10 + 1 + 914
++ * command_easy: 10, "|", 78757 // = 76 << 10 + 1 + 932
++ * command_easy: 10, "|", 79793 // = 77 << 10 + 1 + 944
++ * command_easy: 10, "|", 80830 // = 78 << 10 + 1 + 957
++ * command_easy: 10, "|", 81866 // = 79 << 10 + 1 + 969
++ * command_easy: 10, "|", 82902 // = 80 << 10 + 1 + 981
++ * command_easy: 10, "|", 83942 // = 81 << 10 + 1 + 997
++ * command_easy: 10, "|", 84980 // = 82 << 10 + 1 + 1011
++ * command_easy: 10, "|", 86018 // = 83 << 10 + 1 + 1025
++ * command_easy: 10, "|", 87055 // = 84 << 10 + 1 + 1038
++ * command_easy: 10, "|", 88093 // = 85 << 10 + 1 + 1052
++ * command_easy: 10, "|", 89129 // = 86 << 10 + 1 + 1064
++ * command_easy: 10, "|", 90166 // = 87 << 10 + 1 + 1077
++ * command_easy: 10, "|", 91202 // = 88 << 10 + 1 + 1089
++ * command_easy: 10, "|", 92239 // = 89 << 10 + 1 + 1102
++ * command_easy: 10, "|", 93276 // = 90 << 10 + 1 + 1115
++ * command_easy: 10, "|", 94315 // = 91 << 10 + 1 + 1130
++ * command_easy: 10, "|", 95353 // = 92 << 10 + 1 + 1144
++ * command_easy: 10, "|", 96392 // = 93 << 10 + 1 + 1159
++ * command_easy: 10, "|", 97432 // = 94 << 10 + 1 + 1175
++ * command_easy: 10, "|", 98468 // = 95 << 10 + 1 + 1187
++ * command_easy: 10, "|", 99507 // = 96 << 10 + 1 + 1202
++ * command_easy: 10, "|", 100544 // = 97 << 10 + 1 + 1215
++ * command_easy: 10, "|", 101581 // = 98 << 10 + 1 + 1228
++ * command_easy: 10, "|", 102619 // = 99 << 10 + 1 + 1242
++ * command_easy: 10, "|", 103655 // = 100 << 10 + 1 + 1254
++ * command_easy: 10, "|", 104694 // = 101 << 10 + 1 + 1269
++ * command_easy: 10, "|", 105730 // = 102 << 10 + 1 + 1281
++ * command_easy: 10, "|", 106767 // = 103 << 10 + 1 + 1294
++ * command_easy: 10, "|", 107804 // = 104 << 10 + 1 + 1307
++ * command_easy: 10, "|", 108841 // = 105 << 10 + 1 + 1320
++ * command_easy: 10, "|", 109878 // = 106 << 10 + 1 + 1333
++ * command_easy: 10, "|", 110917 // = 107 << 10 + 1 + 1348
++ * command_easy: 10, "|", 111954 // = 108 << 10 + 1 + 1361
++ * command_easy: 10, "|", 112991 // = 109 << 10 + 1 + 1374
++ * command_easy: 10, "|", 114028 // = 110 << 10 + 1 + 1387
++ * command_easy: 10, "|", 115066 // = 111 << 10 + 1 + 1401
++ * command_easy: 10, "|", 116104 // = 112 << 10 + 1 + 1415
++ * command_easy: 10, "|", 117140 // = 113 << 10 + 1 + 1427
++ * command_easy: 10, "|", 118176 // = 114 << 10 + 1 + 1439
++ * command_easy: 10, "|", 119213 // = 115 << 10 + 1 + 1452
++ * command_easy: 10, "|", 120250 // = 116 << 10 + 1 + 1465
++ * command_easy: 10, "|", 121287 // = 117 << 10 + 1 + 1478
++ * command_easy: 10, "|", 122325 // = 118 << 10 + 1 + 1492
++ * command_easy: 10, "|", 123363 // = 119 << 10 + 1 + 1506
++ * command_easy: 10, "|", 124401 // = 120 << 10 + 1 + 1520
++ */
++ compressed,
++ true,
++ "|categories|categories | categories |ategories|Categories |categories the | categories|s cat"
++ + "egories |categories of |Categories|categories and |tegories|categorie|, categories |catego"
++ + "ries, | Categories |categories in |categories to |e categories |categories\"|categories.|c"
++ + "ategories\">|categories\n|categor|categories]|categories for |egories|categori|categories "
++ + "a |categories that | Categories|categories. |.categories| categories, |gories|categories w"
++ + "ith |categories'|categories from |categories by |ories|ries| the categories|catego|categor"
++ + "ies. The |CATEGORIES|categories on |categories as |categories is |cat|categorieing |catego"
++ + "ries\n\t|categories:| categories. |categoriesed |s|ies|cate|categories(|Categories, |ca|ca"
++ + "tegories at |categoriesly | the categories of |categ|c| Categories, |Categories\"|.categor"
++ + "ies(|CATEGORIES |Categories\">|categories=\"| categories.|.com/categories| the categories "
++ + "of the |Categories'|categories. This |categories,|.categories |Categories(|Categories.|cat"
++ + "egories not | categories=\"|categorieser | CATEGORIES |categoriesal | CATEGORIES|categorie"
++ + "s='|CATEGORIES\"|Categories. | categories(|categoriesful | Categories. |categoriesive |cat"
++ + "egoriesless |CATEGORIES'|categoriesest | Categories.|CATEGORIES\">| categories='|Categorie"
++ + "s,|categoriesize |CATEGORIES.|\302\240categories| categories,|Categories=\"|CATEGORIES="
++ + "\"|categoriesous |CATEGORIES, |Categories='| Categories,| CATEGORIES=\"| CATEGORIES, |CATE"
++ + "GORIES,|CATEGORIES(|CATEGORIES. | CATEGORIES.|CATEGORIES='| CATEGORIES. | Categories=\"| C"
++ + "ATEGORIES='| Categories='"
++ );
++ }
++
++ @Test
++ public void testAllTransforms4() {
++ byte[] compressed = {
++ (byte) 0x1b, (byte) 0x40, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
++ (byte) 0xe3, (byte) 0xb4, (byte) 0x0d, (byte) 0x00, (byte) 0x00, (byte) 0x07, (byte) 0x5b,
++ (byte) 0x26, (byte) 0x31, (byte) 0x40, (byte) 0x02, (byte) 0x00, (byte) 0xe0, (byte) 0x4e,
++ (byte) 0x1b, (byte) 0x51, (byte) 0x3e, (byte) 0x42, (byte) 0x51, (byte) 0x3e, (byte) 0x81,
++ (byte) 0x02, (byte) 0x51, (byte) 0x3e, (byte) 0x11, (byte) 0x04, (byte) 0xa2, (byte) 0x7c,
++ (byte) 0xe2, (byte) 0x0b, (byte) 0x44, (byte) 0xf9, (byte) 0x24, (byte) 0x1b, (byte) 0x10,
++ (byte) 0xe5, (byte) 0x93, (byte) 0x84, (byte) 0x50, (byte) 0x94, (byte) 0x4f, (byte) 0xba,
++ (byte) 0x02, (byte) 0x51, (byte) 0x3e, (byte) 0x69, (byte) 0x0c, (byte) 0x45, (byte) 0xf9,
++ (byte) 0x64, (byte) 0x39, (byte) 0x20, (byte) 0xca, (byte) 0x27, (byte) 0x13, (byte) 0x22,
++ (byte) 0x51, (byte) 0x3e, (byte) 0xd9, (byte) 0x11, (byte) 0x8a, (byte) 0xf2, (byte) 0xc9,
++ (byte) 0xa2, (byte) 0x58, (byte) 0x94, (byte) 0x4f, (byte) 0x4e, (byte) 0x05, (byte) 0xa2,
++ (byte) 0x7c, (byte) 0x72, (byte) 0x2c, (byte) 0x12, (byte) 0xe5, (byte) 0x93, (byte) 0x83,
++ (byte) 0xa1, (byte) 0x28, (byte) 0x9f, (byte) 0xfc, (byte) 0x8c, (byte) 0x45, (byte) 0xf9,
++ (byte) 0x14, (byte) 0x6e, (byte) 0x40, (byte) 0x94, (byte) 0x4f, (byte) 0x71, (byte) 0x47,
++ (byte) 0x44, (byte) 0xf9, (byte) 0x14, (byte) 0x80, (byte) 0x48, (byte) 0x94, (byte) 0x4f,
++ (byte) 0x81, (byte) 0xc8, (byte) 0x44, (byte) 0xf9, (byte) 0x14, (byte) 0x8e, (byte) 0x50,
++ (byte) 0x94, (byte) 0x4f, (byte) 0x41, (byte) 0x49, (byte) 0x45, (byte) 0xf9, (byte) 0x14,
++ (byte) 0x9b, (byte) 0x58, (byte) 0x94, (byte) 0x4f, (byte) 0x11, (byte) 0xca, (byte) 0x45,
++ (byte) 0xf9, (byte) 0x94, (byte) 0xa3, (byte) 0x40, (byte) 0x94, (byte) 0x4f, (byte) 0x99,
++ (byte) 0x4a, (byte) 0x44, (byte) 0xf9, (byte) 0x94, (byte) 0xb3, (byte) 0x48, (byte) 0x94,
++ (byte) 0x4f, (byte) 0x59, (byte) 0xcb, (byte) 0x44, (byte) 0xf9, (byte) 0x94, (byte) 0xb8,
++ (byte) 0x50, (byte) 0x94, (byte) 0x4f, (byte) 0x09, (byte) 0x4c, (byte) 0x45, (byte) 0xf9,
++ (byte) 0x94, (byte) 0xcb, (byte) 0x58, (byte) 0x94, (byte) 0x4f, (byte) 0x19, (byte) 0xcd,
++ (byte) 0x45, (byte) 0xf9, (byte) 0x54, (byte) 0xd8, (byte) 0x80, (byte) 0x28, (byte) 0x9f,
++ (byte) 0xca, (byte) 0x9b, (byte) 0x10, (byte) 0xe5, (byte) 0x53, (byte) 0x99, (byte) 0x23,
++ (byte) 0xa2, (byte) 0x7c, (byte) 0xaa, (byte) 0x73, (byte) 0x46, (byte) 0x94, (byte) 0x4f,
++ (byte) 0x25, (byte) 0x0f, (byte) 0x89, (byte) 0xf2, (byte) 0xa9, (byte) 0xf0, (byte) 0x29,
++ (byte) 0x51, (byte) 0x3e, (byte) 0xd5, (byte) 0x40, (byte) 0x26, (byte) 0xca, (byte) 0xa7,
++ (byte) 0x62, (byte) 0xe8, (byte) 0x44, (byte) 0xf9, (byte) 0x54, (byte) 0x0d, (byte) 0xa1,
++ (byte) 0x28, (byte) 0x9f, (byte) 0xca, (byte) 0xa1, (byte) 0x14, (byte) 0xe5, (byte) 0x53,
++ (byte) 0x61, (byte) 0xa4, (byte) 0xa2, (byte) 0x7c, (byte) 0xaa, (byte) 0x8c, (byte) 0x56,
++ (byte) 0x94, (byte) 0x4f, (byte) 0x45, (byte) 0x12, (byte) 0x8b, (byte) 0xf2, (byte) 0xa9,
++ (byte) 0x52, (byte) 0x6a, (byte) 0x51, (byte) 0x3e, (byte) 0x95, (byte) 0x4c, (byte) 0x2e,
++ (byte) 0xca, (byte) 0xa7, (byte) 0xda, (byte) 0xe9, (byte) 0x45, (byte) 0xf9, (byte) 0xd4,
++ (byte) 0x44, (byte) 0x81, (byte) 0x28, (byte) 0x9f, (byte) 0xba, (byte) 0xa8, (byte) 0x10,
++ (byte) 0xe5, (byte) 0x53, (byte) 0x37, (byte) 0x25, (byte) 0xa2, (byte) 0x7c, (byte) 0x6a,
++ (byte) 0xaa, (byte) 0x46, (byte) 0x94, (byte) 0x4f, (byte) 0xad, (byte) 0x15, (byte) 0x89,
++ (byte) 0xf2, (byte) 0xa9, (byte) 0xc5, (byte) 0x2a, (byte) 0x51, (byte) 0x3e, (byte) 0xb5,
++ (byte) 0x5a, (byte) 0x26, (byte) 0xca, (byte) 0xa7, (byte) 0x5e, (byte) 0xeb, (byte) 0x44,
++ (byte) 0xf9, (byte) 0xd4, (byte) 0x6c, (byte) 0xa1, (byte) 0x28, (byte) 0x9f, (byte) 0xba,
++ (byte) 0xad, (byte) 0x14, (byte) 0xe5, (byte) 0x53, (byte) 0xcf, (byte) 0xa5, (byte) 0xa2,
++ (byte) 0x7c, (byte) 0x6a, (byte) 0xbd, (byte) 0x56, (byte) 0x94, (byte) 0x4f, (byte) 0xbd,
++ (byte) 0x17, (byte) 0x8b, (byte) 0xf2, (byte) 0xa9, (byte) 0x09, (byte) 0x6b, (byte) 0x51,
++ (byte) 0x3e, (byte) 0x35, (byte) 0x63, (byte) 0x2e, (byte) 0xca, (byte) 0xa7, (byte) 0xd6,
++ (byte) 0xec, (byte) 0x45, (byte) 0xf9, (byte) 0x34, (byte) 0x9b, (byte) 0x01, (byte) 0x51,
++ (byte) 0x3e, (byte) 0x0d, (byte) 0x67, (byte) 0x41, (byte) 0x94, (byte) 0x4f, (byte) 0x43,
++ (byte) 0x9a, (byte) 0x10, (byte) 0xe5, (byte) 0xd3, (byte) 0xa8, (byte) 0x36, (byte) 0x44,
++ (byte) 0xf9, (byte) 0x34, (byte) 0xb1, (byte) 0x11, (byte) 0x51, (byte) 0x3e, (byte) 0xcd,
++ (byte) 0x6d, (byte) 0x45, (byte) 0x94, (byte) 0x4f, (byte) 0xe3, (byte) 0x9b, (byte) 0x11,
++ (byte) 0xe5, (byte) 0xd3, (byte) 0x14, (byte) 0x77, (byte) 0x44, (byte) 0xf9, (byte) 0x34,
++ (byte) 0xcc, (byte) 0x21, (byte) 0x51, (byte) 0x3e, (byte) 0x8d, (byte) 0x75, (byte) 0x49,
++ (byte) 0x94, (byte) 0x4f, (byte) 0x83, (byte) 0x9e, (byte) 0x12, (byte) 0xe5, (byte) 0xd3,
++ (byte) 0xb8, (byte) 0xb7, (byte) 0x44, (byte) 0xf9, (byte) 0x34, (byte) 0xfa, (byte) 0x31,
++ (byte) 0x51, (byte) 0x3e, (byte) 0x0d, (byte) 0x80, (byte) 0x4d, (byte) 0x94, (byte) 0x4f,
++ (byte) 0x73, (byte) 0xa0, (byte) 0x13, (byte) 0xe5, (byte) 0xd3, (byte) 0x34, (byte) 0xf8,
++ (byte) 0x44, (byte) 0xf9, (byte) 0x34, (byte) 0x13, (byte) 0x42, (byte) 0x51, (byte) 0x3e,
++ (byte) 0x4d, (byte) 0x87, (byte) 0x51, (byte) 0x94, (byte) 0x4f, (byte) 0x53, (byte) 0xa2,
++ (byte) 0x14, (byte) 0xe5, (byte) 0xd3, (byte) 0xb4, (byte) 0x38, (byte) 0x45, (byte) 0xf9,
++ (byte) 0x34, (byte) 0x34, (byte) 0x52, (byte) 0x51, (byte) 0x3e, (byte) 0x0d, (byte) 0x8f,
++ (byte) 0x55, (byte) 0x94, (byte) 0x4f, (byte) 0x23, (byte) 0xa4, (byte) 0x15, (byte) 0xe5,
++ (byte) 0xd3, (byte) 0x24, (byte) 0x79, (byte) 0x45, (byte) 0xf9, (byte) 0x34, (byte) 0x4f,
++ (byte) 0x62, (byte) 0x51, (byte) 0x3e, (byte) 0x8d, (byte) 0x95, (byte) 0x59, (byte) 0x94,
++ (byte) 0x4f, (byte) 0xd3, (byte) 0xa5, (byte) 0x16, (byte) 0xe5, (byte) 0xd3, (byte) 0x98,
++ (byte) 0xb9, (byte) 0x45, (byte) 0xf9, (byte) 0x34, (byte) 0x6e, (byte) 0x72, (byte) 0x51,
++ (byte) 0x3e, (byte) 0xcd, (byte) 0x9d, (byte) 0x5d, (byte) 0x94, (byte) 0x4f, (byte) 0x13,
++ (byte) 0xa8, (byte) 0x17, (byte) 0xe5, (byte) 0xd3, (byte) 0x1c, (byte) 0xfa, (byte) 0x45,
++ (byte) 0xf9, (byte) 0xb4, (byte) 0x90, (byte) 0x02, (byte) 0x51, (byte) 0x3e, (byte) 0xed,
++ (byte) 0xa5, (byte) 0x41, (byte) 0x94, (byte) 0x4f, (byte) 0xeb, (byte) 0xa9, (byte) 0x10,
++ (byte) 0xe5, (byte) 0xd3, (byte) 0x9a, (byte) 0x3a, (byte) 0x44, (byte) 0xf9, (byte) 0xb4,
++ (byte) 0xac, (byte) 0x12, (byte) 0x51, (byte) 0x3e, (byte) 0x6d, (byte) 0xad, (byte) 0x45,
++ (byte) 0x94, (byte) 0x4f, (byte) 0xbb, (byte) 0xab, (byte) 0x11, (byte) 0xe5, (byte) 0xd3,
++ (byte) 0x0a, (byte) 0x7b, (byte) 0x44, (byte) 0xf9, (byte) 0xb4, (byte) 0xc9, (byte) 0x22,
++ (byte) 0x51, (byte) 0x3e, (byte) 0x2d, (byte) 0xb4, (byte) 0x49, (byte) 0x94, (byte) 0x4f,
++ (byte) 0x7b, (byte) 0xad, (byte) 0x12, (byte) 0xe5, (byte) 0xd3, (byte) 0x82, (byte) 0xbb,
++ (byte) 0x44, (byte) 0xf9, (byte) 0xb4, (byte) 0xe7, (byte) 0x32, (byte) 0x51, (byte) 0x3e,
++ (byte) 0xad, (byte) 0xbb, (byte) 0x4d, (byte) 0x94, (byte) 0x4f, (byte) 0x5b, (byte) 0xaf,
++ (byte) 0x13, (byte) 0xe5, (byte) 0xd3, (byte) 0xf6, (byte) 0xfb, (byte) 0x44, (byte) 0xf9,
++ (byte) 0xb4, (byte) 0x05, (byte) 0x43, (byte) 0x51, (byte) 0x3e, (byte) 0xed, (byte) 0xc2,
++ (byte) 0x51, (byte) 0x94, (byte) 0x4f, (byte) 0x1b, (byte) 0xb1, (byte) 0x14, (byte) 0xe5,
++ (byte) 0xd3, (byte) 0x62, (byte) 0x3c, (byte) 0x45, (byte) 0xf9, (byte) 0xb4, (byte) 0x1f,
++ (byte) 0x53, (byte) 0x51, (byte) 0x3e, (byte) 0xad, (byte) 0xc9, (byte) 0x55, (byte) 0x94,
++ (byte) 0x4f, (byte) 0xeb, (byte) 0xb2, (byte) 0x15, (byte) 0xe5, (byte) 0xd3, (byte) 0xda,
++ (byte) 0x7c, (byte) 0x45, (byte) 0xf9, (byte) 0xb4, (byte) 0x3e, (byte) 0x63
++ };
++ checkSynth(
++ /*
++ * // The stream consists of word "time" with all possible transforms.
++ * main_header
++ * metablock_header_easy: 833, 1
++ * command_easy: 4, "|", 2 // = 0 << 10 + 1 + 1
++ * command_easy: 4, "|", 1031 // = 1 << 10 + 1 + 6
++ * command_easy: 4, "|", 2061 // = 2 << 10 + 1 + 12
++ * command_easy: 4, "|", 3092 // = 3 << 10 + 1 + 19
++ * command_easy: 4, "|", 4120 // = 4 << 10 + 1 + 23
++ * command_easy: 4, "|", 5150 // = 5 << 10 + 1 + 29
++ * command_easy: 4, "|", 6184 // = 6 << 10 + 1 + 39
++ * command_easy: 4, "|", 7214 // = 7 << 10 + 1 + 45
++ * command_easy: 4, "|", 8246 // = 8 << 10 + 1 + 53
++ * command_easy: 4, "|", 9279 // = 9 << 10 + 1 + 62
++ * command_easy: 4, "|", 10308 // = 10 << 10 + 1 + 67
++ * command_easy: 4, "|", 11342 // = 11 << 10 + 1 + 77
++ * command_easy: 4, "|", 12369 // = 12 << 10 + 1 + 80
++ * command_easy: 4, "|", 13397 // = 13 << 10 + 1 + 84
++ * command_easy: 4, "|", 14429 // = 14 << 10 + 1 + 92
++ * command_easy: 4, "|", 15460 // = 15 << 10 + 1 + 99
++ * command_easy: 4, "|", 16491 // = 16 << 10 + 1 + 106
++ * command_easy: 4, "|", 17524 // = 17 << 10 + 1 + 115
++ * command_easy: 4, "|", 18557 // = 18 << 10 + 1 + 124
++ * command_easy: 4, "|", 19589 // = 19 << 10 + 1 + 132
++ * command_easy: 4, "|", 20619 // = 20 << 10 + 1 + 138
++ * command_easy: 4, "|", 21649 // = 21 << 10 + 1 + 144
++ * command_easy: 4, "|", 22680 // = 22 << 10 + 1 + 151
++ * command_easy: 4, "|", 23710 // = 23 << 10 + 1 + 157
++ * command_easy: 4, "|", 24736 // = 24 << 10 + 1 + 159
++ * command_easy: 4, "|", 25766 // = 25 << 10 + 1 + 165
++ * command_easy: 4, "|", 26800 // = 26 << 10 + 1 + 175
++ * command_easy: 4, "|", 27826 // = 27 << 10 + 1 + 177
++ * command_easy: 4, "|", 28853 // = 28 << 10 + 1 + 180
++ * command_easy: 4, "|", 29885 // = 29 << 10 + 1 + 188
++ * command_easy: 4, "|", 30920 // = 30 << 10 + 1 + 199
++ * command_easy: 4, "|", 31950 // = 31 << 10 + 1 + 205
++ * command_easy: 4, "|", 32981 // = 32 << 10 + 1 + 212
++ * command_easy: 4, "|", 34011 // = 33 << 10 + 1 + 218
++ * command_easy: 4, "|", 35043 // = 34 << 10 + 1 + 226
++ * command_easy: 4, "|", 36068 // = 35 << 10 + 1 + 227
++ * command_easy: 4, "|", 37103 // = 36 << 10 + 1 + 238
++ * command_easy: 4, "|", 38133 // = 37 << 10 + 1 + 244
++ * command_easy: 4, "|", 39168 // = 38 << 10 + 1 + 255
++ * command_easy: 4, "|", 40201 // = 39 << 10 + 1 + 264
++ * command_easy: 4, "|", 41226 // = 40 << 10 + 1 + 265
++ * command_easy: 4, "|", 42251 // = 41 << 10 + 1 + 266
++ * command_easy: 4, "|", 43285 // = 42 << 10 + 1 + 276
++ * command_easy: 4, "|", 44310 // = 43 << 10 + 1 + 277
++ * command_easy: 4, "|", 45345 // = 44 << 10 + 1 + 288
++ * command_easy: 4, "|", 46374 // = 45 << 10 + 1 + 293
++ * command_easy: 4, "|", 47407 // = 46 << 10 + 1 + 302
++ * command_easy: 4, "|", 48440 // = 47 << 10 + 1 + 311
++ * command_easy: 4, "|", 49473 // = 48 << 10 + 1 + 320
++ * command_easy: 4, "|", 50498 // = 49 << 10 + 1 + 321
++ * command_easy: 4, "|", 51530 // = 50 << 10 + 1 + 329
++ * command_easy: 4, "|", 52561 // = 51 << 10 + 1 + 336
++ * command_easy: 4, "|", 53591 // = 52 << 10 + 1 + 342
++ * command_easy: 4, "|", 54623 // = 53 << 10 + 1 + 350
++ * command_easy: 4, "|", 55655 // = 54 << 10 + 1 + 358
++ * command_easy: 4, "|", 56680 // = 55 << 10 + 1 + 359
++ * command_easy: 4, "|", 57705 // = 56 << 10 + 1 + 360
++ * command_easy: 4, "|", 58730 // = 57 << 10 + 1 + 361
++ * command_easy: 4, "|", 59760 // = 58 << 10 + 1 + 367
++ * command_easy: 4, "|", 60791 // = 59 << 10 + 1 + 374
++ * command_easy: 4, "|", 61816 // = 60 << 10 + 1 + 375
++ * command_easy: 4, "|", 62849 // = 61 << 10 + 1 + 384
++ * command_easy: 4, "|", 63881 // = 62 << 10 + 1 + 392
++ * command_easy: 4, "|", 64919 // = 63 << 10 + 1 + 406
++ * command_easy: 4, "|", 65944 // = 64 << 10 + 1 + 407
++ * command_easy: 4, "|", 66969 // = 65 << 10 + 1 + 408
++ * command_easy: 4, "|", 68001 // = 66 << 10 + 1 + 416
++ * command_easy: 4, "|", 69031 // = 67 << 10 + 1 + 422
++ * command_easy: 4, "|", 70062 // = 68 << 10 + 1 + 429
++ * command_easy: 4, "|", 71092 // = 69 << 10 + 1 + 435
++ * command_easy: 4, "|", 72123 // = 70 << 10 + 1 + 442
++ * command_easy: 4, "|", 73154 // = 71 << 10 + 1 + 449
++ * command_easy: 4, "|", 74185 // = 72 << 10 + 1 + 456
++ * command_easy: 4, "|", 75219 // = 73 << 10 + 1 + 466
++ * command_easy: 4, "|", 76261 // = 74 << 10 + 1 + 484
++ * command_easy: 4, "|", 77291 // = 75 << 10 + 1 + 490
++ * command_easy: 4, "|", 78327 // = 76 << 10 + 1 + 502
++ * command_easy: 4, "|", 79357 // = 77 << 10 + 1 + 508
++ * command_easy: 4, "|", 80388 // = 78 << 10 + 1 + 515
++ * command_easy: 4, "|", 81418 // = 79 << 10 + 1 + 521
++ * command_easy: 4, "|", 82448 // = 80 << 10 + 1 + 527
++ * command_easy: 4, "|", 83482 // = 81 << 10 + 1 + 537
++ * command_easy: 4, "|", 84514 // = 82 << 10 + 1 + 545
++ * command_easy: 4, "|", 85546 // = 83 << 10 + 1 + 553
++ * command_easy: 4, "|", 86577 // = 84 << 10 + 1 + 560
++ * command_easy: 4, "|", 87609 // = 85 << 10 + 1 + 568
++ * command_easy: 4, "|", 88639 // = 86 << 10 + 1 + 574
++ * command_easy: 4, "|", 89670 // = 87 << 10 + 1 + 581
++ * command_easy: 4, "|", 90700 // = 88 << 10 + 1 + 587
++ * command_easy: 4, "|", 91731 // = 89 << 10 + 1 + 594
++ * command_easy: 4, "|", 92762 // = 90 << 10 + 1 + 601
++ * command_easy: 4, "|", 93795 // = 91 << 10 + 1 + 610
++ * command_easy: 4, "|", 94827 // = 92 << 10 + 1 + 618
++ * command_easy: 4, "|", 95860 // = 93 << 10 + 1 + 627
++ * command_easy: 4, "|", 96894 // = 94 << 10 + 1 + 637
++ * command_easy: 4, "|", 97924 // = 95 << 10 + 1 + 643
++ * command_easy: 4, "|", 98957 // = 96 << 10 + 1 + 652
++ * command_easy: 4, "|", 99988 // = 97 << 10 + 1 + 659
++ * command_easy: 4, "|", 101019 // = 98 << 10 + 1 + 666
++ * command_easy: 4, "|", 102051 // = 99 << 10 + 1 + 674
++ * command_easy: 4, "|", 103081 // = 100 << 10 + 1 + 680
++ * command_easy: 4, "|", 104114 // = 101 << 10 + 1 + 689
++ * command_easy: 4, "|", 105144 // = 102 << 10 + 1 + 695
++ * command_easy: 4, "|", 106175 // = 103 << 10 + 1 + 702
++ * command_easy: 4, "|", 107206 // = 104 << 10 + 1 + 709
++ * command_easy: 4, "|", 108237 // = 105 << 10 + 1 + 716
++ * command_easy: 4, "|", 109268 // = 106 << 10 + 1 + 723
++ * command_easy: 4, "|", 110301 // = 107 << 10 + 1 + 732
++ * command_easy: 4, "|", 111332 // = 108 << 10 + 1 + 739
++ * command_easy: 4, "|", 112363 // = 109 << 10 + 1 + 746
++ * command_easy: 4, "|", 113394 // = 110 << 10 + 1 + 753
++ * command_easy: 4, "|", 114426 // = 111 << 10 + 1 + 761
++ * command_easy: 4, "|", 115458 // = 112 << 10 + 1 + 769
++ * command_easy: 4, "|", 116488 // = 113 << 10 + 1 + 775
++ * command_easy: 4, "|", 117518 // = 114 << 10 + 1 + 781
++ * command_easy: 4, "|", 118549 // = 115 << 10 + 1 + 788
++ * command_easy: 4, "|", 119580 // = 116 << 10 + 1 + 795
++ * command_easy: 4, "|", 120611 // = 117 << 10 + 1 + 802
++ * command_easy: 4, "|", 121643 // = 118 << 10 + 1 + 810
++ * command_easy: 4, "|", 122675 // = 119 << 10 + 1 + 818
++ * command_easy: 4, "|", 123707 // = 120 << 10 + 1 + 826
++ */
++ compressed,
++ true,
++ "|time|time | time |ime|Time |time the | time|s time |time of |Time|time and |me|tim|, time |"
++ + "time, | Time |time in |time to |e time |time\"|time.|time\">|time\n|t|time]|time for |e|ti"
++ + "|time a |time that | Time|time. |.time| time, ||time with |time'|time from |time by ||| th"
++ + "e time||time. The |TIME|time on |time as |time is ||timing |time\n\t|time:| time. |timeed "
++ + "||||time(|Time, ||time at |timely | the time of ||| Time, |Time\"|.time(|TIME |Time\">|tim"
++ + "e=\"| time.|.com/time| the time of the |Time'|time. This |time,|.time |Time(|Time.|time no"
++ + "t | time=\"|timeer | TIME |timeal | TIME|time='|TIME\"|Time. | time(|timeful | Time. |time"
++ + "ive |timeless |TIME'|timeest | Time.|TIME\">| time='|Time,|timeize |TIME.|\302\240time| ti"
++ + "me,|Time=\"|TIME=\"|timeous |TIME, |Time='| Time,| TIME=\"| TIME, |TIME,|TIME(|TIME. | TIM"
++ + "E.|TIME='| TIME. | Time=\"| TIME='| Time='"
++ );
++ }
++
++ @Test
+ public void testBaseDictWord() {
+ byte[] compressed = {
+ (byte) 0x1b, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+@@ -447,6 +915,28 @@ public class SynthTest {
+ }
+
+ @Test
++ public void testCopyTooLong() {
++ byte[] compressed = {
++ (byte) 0xa1, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
++ (byte) 0x1c, (byte) 0xa7, (byte) 0x6d, (byte) 0x00, (byte) 0x00, (byte) 0x38, (byte) 0xd8,
++ (byte) 0x32, (byte) 0x89, (byte) 0x01, (byte) 0x12, (byte) 0x00, (byte) 0x00, (byte) 0x77,
++ (byte) 0xda, (byte) 0x34, (byte) 0xab, (byte) 0xdb, (byte) 0x50, (byte) 0x00
++ };
++ checkSynth(
++ /*
++ * // Has a copy length that goes over the end of the meta-block,
++ * // with a ringbuffer wrap.
++ * main_header: 10
++ * metablock_header_easy: 2, 1
++ * command_easy: 1024, "a", 1
++ */
++ compressed,
++ false,
++ ""
++ );
++ }
++
++ @Test
+ public void testCustomHuffmanCode() {
+ byte[] compressed = {
+ (byte) 0x1b, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x80,
+@@ -2199,6 +2689,23 @@ public class SynthTest {
+ );
+ }
+
++/* DISABLED: Java decoder does not tolerate extra input after the brotli stream.
++ @Test
++ public void testSimplePrefixPlusExtraData() {
++ byte[] compressed = {
++ (byte) 0x1b, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0xa0, (byte) 0xc3, (byte) 0xc4,
++ (byte) 0xc6, (byte) 0xc8, (byte) 0x02, (byte) 0x00, (byte) 0x70, (byte) 0xb0, (byte) 0x65,
++ (byte) 0x12, (byte) 0x03, (byte) 0x24, (byte) 0x00, (byte) 0x00, (byte) 0xee, (byte) 0xb4,
++ (byte) 0x51, (byte) 0xa0, (byte) 0x1d, (byte) 0x55, (byte) 0xaa
++ };
++ checkSynth(
++ compressed,
++ true,
++ "abcd"
++ );
++ }
++*/
++
+ @Test
+ public void testTooManySymbolsRepeated() {
+ byte[] compressed = {
+@@ -2246,7 +2753,7 @@ public class SynthTest {
+ * main_header
+ * metablock_header_easy: 9, 1
+ * command_inscopy_easy: 0, 4
+- * command_dist_easy: 5121
++ * command_dist_easy: 5121 // 5 << 10 + 1
+ */
+ compressed,
+ true,
+@@ -2270,7 +2777,7 @@ public class SynthTest {
+ * main_header
+ * metablock_header_easy: 4, 1
+ * command_inscopy_easy: 0, 4
+- * command_dist_easy: 5121
++ * command_dist_easy: 5121 // 5 << 10 + 1
+ */
+ compressed,
+ false,
+@@ -2280,4 +2787,4 @@ public class SynthTest {
+
+ /* GENERATED CODE END */
+
+-}
+\ No newline at end of file
++}
+diff --git a/java/org/brotli/dec/Transform.java b/java/org/brotli/dec/Transform.java
+index b90f2e9..3279ee7 100644
+--- a/java/org/brotli/dec/Transform.java
++++ b/java/org/brotli/dec/Transform.java
+@@ -10,13 +10,58 @@ import java.nio.ByteBuffer;
+
+ /**
+ * Transformations on dictionary words.
++ *
++ * Transform descriptor is a triplet: {prefix, operator, suffix}.
++ * "prefix" and "suffix" are short strings inserted before and after transformed dictionary word.
++ * "operator" is applied to dictionary word itself.
++ *
++ * Some operators has "built-in" parameters, i.e. parameter is defined by operator ordinal. Other
++ * operators have "external" parameters, supplied via additional table encoded in shared dictionary.
++ *
++ * Operators:
++ * - IDENTITY (0): dictionary word is inserted "as is"
++ * - OMIT_LAST_N (1 - 9): last N octets of dictionary word are not inserted; N == ordinal
++ * - OMIT_FIRST_M (12-20): first M octets of dictionary word are not inserted; M == ordinal - 11
++ * - UPPERCASE_FIRST (10): first "scalar" is XOR'ed with number 32
++ * - UPPERCASE_ALL (11): all "scalars" are XOR'ed with number 32
++ * - SHIFT_FIRST (21): first "scalar" is shifted by number form parameter table
++ * - SHIFT_ALL (22): all "scalar" is shifted by number form parameter table
++ *
++ * Here "scalar" is a variable length character coding similar to UTF-8 encoding.
++ * UPPERCASE_XXX / SHIFT_XXX operators were designed to change the case of UTF-8 encoded characters.
++ * While UPPERCASE_XXX works well only on ASCII charset, SHIFT is much more generic and could be
++ * used for most (all?) alphabets.
+ */
+ final class Transform {
+
+- static final int NUM_TRANSFORMS = 121;
+- private static final int[] TRANSFORMS = new int[NUM_TRANSFORMS * 3];
+- private static final byte[] PREFIX_SUFFIX = new byte[217];
+- private static final int[] PREFIX_SUFFIX_HEADS = new int[51];
++ static final class Transforms {
++ final int numTransforms;
++ final int[] triplets;
++ final byte[] prefixSuffixStorage;
++ final int[] prefixSuffixHeads;
++ final short[] params;
++
++ Transforms(int numTransforms, int prefixSuffixLen, int prefixSuffixCount) {
++ this.numTransforms = numTransforms;
++ this.triplets = new int[numTransforms * 3];
++ this.params = new short[numTransforms];
++ this.prefixSuffixStorage = new byte[prefixSuffixLen];
++ this.prefixSuffixHeads = new int[prefixSuffixCount + 1];
++ }
++ }
++
++ static final int NUM_RFC_TRANSFORMS = 121;
++ static final Transforms RFC_TRANSFORMS = new Transforms(NUM_RFC_TRANSFORMS, 167, 50);
++
++ private static final int OMIT_FIRST_LAST_LIMIT = 9;
++
++ private static final int IDENTITY = 0;
++ private static final int OMIT_LAST_BASE = IDENTITY + 1 - 1; // there is no OMIT_LAST_0.
++ private static final int UPPERCASE_FIRST = OMIT_LAST_BASE + OMIT_FIRST_LAST_LIMIT + 1;
++ private static final int UPPERCASE_ALL = UPPERCASE_FIRST + 1;
++ private static final int OMIT_FIRST_BASE = UPPERCASE_ALL + 1 - 1; // there is no OMIT_FIRST_0.
++ private static final int SHIFT_FIRST = OMIT_FIRST_BASE + OMIT_FIRST_LAST_LIMIT + 1;
++ private static final int SHIFT_ALL = SHIFT_FIRST + 1;
+
+ // Bundle of 0-terminated strings.
+ private static final String PREFIX_SUFFIX_SRC = "# #s #, #e #.# the #.com/#\u00C2\u00A0# of # and"
+@@ -29,71 +74,87 @@ final class Transform {
+ + " G% ! *A *% H! D I!+! J!+ K +- *4! A L!*4 M N +6 O!*% +.! K *G P +%( ! G *D +D "
+ + " Q +# *K!*G!+D!+# +G +A +4!+% +K!+4!*D!+K!*K";
+
+- private static void unpackTransforms(byte[] prefixSuffix, int[] prefixSuffixHeads,
+- int[] transforms, String prefixSuffixSrc, String transformsSrc) {
++ private static void unpackTransforms(byte[] prefixSuffix,
++ int[] prefixSuffixHeads, int[] transforms, String prefixSuffixSrc, String transformsSrc) {
+ int n = prefixSuffixSrc.length();
+ int index = 1;
++ int j = 0;
+ for (int i = 0; i < n; ++i) {
+ char c = prefixSuffixSrc.charAt(i);
+- prefixSuffix[i] = (byte) c;
+ if (c == 35) { // == #
+- prefixSuffixHeads[index++] = i + 1;
+- prefixSuffix[i] = 0;
++ prefixSuffixHeads[index++] = j;
++ } else {
++ prefixSuffix[j++] = (byte) c;
+ }
+ }
+
+- for (int i = 0; i < NUM_TRANSFORMS * 3; ++i) {
++ for (int i = 0; i < NUM_RFC_TRANSFORMS * 3; ++i) {
+ transforms[i] = transformsSrc.charAt(i) - 32;
+ }
+ }
+
+ static {
+- unpackTransforms(PREFIX_SUFFIX, PREFIX_SUFFIX_HEADS, TRANSFORMS, PREFIX_SUFFIX_SRC,
+- TRANSFORMS_SRC);
++ unpackTransforms(RFC_TRANSFORMS.prefixSuffixStorage, RFC_TRANSFORMS.prefixSuffixHeads,
++ RFC_TRANSFORMS.triplets, PREFIX_SUFFIX_SRC, TRANSFORMS_SRC);
+ }
+
+- static int transformDictionaryWord(byte[] dst, int dstOffset, ByteBuffer data, int wordOffset,
+- int len, int transformIndex) {
++ static int transformDictionaryWord(byte[] dst, int dstOffset, ByteBuffer src, int srcOffset,
++ int len, Transforms transforms, int transformIndex) {
+ int offset = dstOffset;
++ int[] triplets = transforms.triplets;
++ byte[] prefixSuffixStorage = transforms.prefixSuffixStorage;
++ int[] prefixSuffixHeads = transforms.prefixSuffixHeads;
+ int transformOffset = 3 * transformIndex;
+- int transformPrefix = PREFIX_SUFFIX_HEADS[TRANSFORMS[transformOffset]];
+- int transformType = TRANSFORMS[transformOffset + 1];
+- int transformSuffix = PREFIX_SUFFIX_HEADS[TRANSFORMS[transformOffset + 2]];
++ int prefixIdx = triplets[transformOffset];
++ int transformType = triplets[transformOffset + 1];
++ int suffixIdx = triplets[transformOffset + 2];
++ int prefix = prefixSuffixHeads[prefixIdx];
++ int prefixEnd = prefixSuffixHeads[prefixIdx + 1];
++ int suffix = prefixSuffixHeads[suffixIdx];
++ int suffixEnd = prefixSuffixHeads[suffixIdx + 1];
++
++ int omitFirst = transformType - OMIT_FIRST_BASE;
++ int omitLast = transformType - OMIT_LAST_BASE;
++ if (omitFirst < 1 || omitFirst > OMIT_FIRST_LAST_LIMIT) {
++ omitFirst = 0;
++ }
++ if (omitLast < 1 || omitLast > OMIT_FIRST_LAST_LIMIT) {
++ omitLast = 0;
++ }
+
+ // Copy prefix.
+- while (PREFIX_SUFFIX[transformPrefix] != 0) {
+- dst[offset++] = PREFIX_SUFFIX[transformPrefix++];
++ while (prefix != prefixEnd) {
++ dst[offset++] = prefixSuffixStorage[prefix++];
+ }
+
+ // Copy trimmed word.
+- int omitFirst = transformType >= 12 ? (transformType - 11) : 0;
+ if (omitFirst > len) {
+ omitFirst = len;
+ }
+- wordOffset += omitFirst;
++ srcOffset += omitFirst;
+ len -= omitFirst;
+- len -= transformType <= 9 ? transformType : 0; // Omit last.
++ len -= omitLast;
+ int i = len;
+ while (i > 0) {
+- dst[offset++] = data.get(wordOffset++);
++ dst[offset++] = src.get(srcOffset++);
+ i--;
+ }
+
+ // Ferment.
+- if (transformType == 11 || transformType == 10) {
++ if (transformType == UPPERCASE_FIRST || transformType == UPPERCASE_ALL) {
+ int uppercaseOffset = offset - len;
+- if (transformType == 10) {
++ if (transformType == UPPERCASE_FIRST) {
+ len = 1;
+ }
+ while (len > 0) {
+- int tmp = dst[uppercaseOffset] & 0xFF;
+- if (tmp < 0xc0) {
+- if (tmp >= 97 && tmp <= 122) { // in [a..z] range
++ int c0 = dst[uppercaseOffset] & 0xFF;
++ if (c0 < 0xC0) {
++ if (c0 >= 97 && c0 <= 122) { // in [a..z] range
+ dst[uppercaseOffset] ^= (byte) 32;
+ }
+ uppercaseOffset += 1;
+ len -= 1;
+- } else if (tmp < 0xe0) {
++ } else if (c0 < 0xE0) {
+ dst[uppercaseOffset + 1] ^= (byte) 32;
+ uppercaseOffset += 2;
+ len -= 2;
+@@ -103,11 +164,71 @@ final class Transform {
+ len -= 3;
+ }
+ }
++ } else if (transformType == SHIFT_FIRST || transformType == SHIFT_ALL) {
++ int shiftOffset = offset - len;
++ short param = transforms.params[transformIndex];
++ /* Limited sign extension: scalar < (1 << 24). */
++ int scalar = (param & 0x7FFF) + (0x1000000 - (param & 0x8000));
++ while (len > 0) {
++ int step = 1;
++ int c0 = dst[shiftOffset] & 0xFF;
++ if (c0 < 0x80) {
++ /* 1-byte rune / 0sssssss / 7 bit scalar (ASCII). */
++ scalar += c0;
++ dst[shiftOffset] = (byte) (scalar & 0x7F);
++ } else if (c0 < 0xC0) {
++ /* Continuation / 10AAAAAA. */
++ } else if (c0 < 0xE0) {
++ /* 2-byte rune / 110sssss AAssssss / 11 bit scalar. */
++ if (len >= 2) {
++ byte c1 = dst[shiftOffset + 1];
++ scalar += (c1 & 0x3F) | ((c0 & 0x1F) << 6);
++ dst[shiftOffset] = (byte) (0xC0 | ((scalar >> 6) & 0x1F));
++ dst[shiftOffset + 1] = (byte) ((c1 & 0xC0) | (scalar & 0x3F));
++ step = 2;
++ } else {
++ step = len;
++ }
++ } else if (c0 < 0xF0) {
++ /* 3-byte rune / 1110ssss AAssssss BBssssss / 16 bit scalar. */
++ if (len >= 3) {
++ byte c1 = dst[shiftOffset + 1];
++ byte c2 = dst[shiftOffset + 2];
++ scalar += (c2 & 0x3F) | ((c1 & 0x3F) << 6) | ((c0 & 0x0F) << 12);
++ dst[shiftOffset] = (byte) (0xE0 | ((scalar >> 12) & 0x0F));
++ dst[shiftOffset + 1] = (byte) ((c1 & 0xC0) | ((scalar >> 6) & 0x3F));
++ dst[shiftOffset + 2] = (byte) ((c2 & 0xC0) | (scalar & 0x3F));
++ step = 3;
++ } else {
++ step = len;
++ }
++ } else if (c0 < 0xF8) {
++ /* 4-byte rune / 11110sss AAssssss BBssssss CCssssss / 21 bit scalar. */
++ if (len >= 4) {
++ byte c1 = dst[shiftOffset + 1];
++ byte c2 = dst[shiftOffset + 2];
++ byte c3 = dst[shiftOffset + 3];
++ scalar += (c3 & 0x3F) | ((c2 & 0x3F) << 6) | ((c1 & 0x3F) << 12) | ((c0 & 0x07) << 18);
++ dst[shiftOffset] = (byte) (0xF0 | ((scalar >> 18) & 0x07));
++ dst[shiftOffset + 1] = (byte) ((c1 & 0xC0) | ((scalar >> 12) & 0x3F));
++ dst[shiftOffset + 2] = (byte) ((c2 & 0xC0) | ((scalar >> 6) & 0x3F));
++ dst[shiftOffset + 3] = (byte) ((c3 & 0xC0) | (scalar & 0x3F));
++ step = 4;
++ } else {
++ step = len;
++ }
++ }
++ shiftOffset += step;
++ len -= step;
++ if (transformType == SHIFT_FIRST) {
++ len = 0;
++ }
++ }
+ }
+
+ // Copy suffix.
+- while (PREFIX_SUFFIX[transformSuffix] != 0) {
+- dst[offset++] = PREFIX_SUFFIX[transformSuffix++];
++ while (suffix != suffixEnd) {
++ dst[offset++] = prefixSuffixStorage[suffix++];
+ }
+
+ return offset - dstOffset;
+diff --git a/java/org/brotli/dec/TransformTest.java b/java/org/brotli/dec/TransformTest.java
+index 616ba35..6e04f0d 100644
+--- a/java/org/brotli/dec/TransformTest.java
++++ b/java/org/brotli/dec/TransformTest.java
+@@ -36,8 +36,8 @@ public class TransformTest {
+ public void testTrimAll() {
+ byte[] output = new byte[0];
+ byte[] input = {119, 111, 114, 100}; // "word"
+- Transform.transformDictionaryWord(
+- output, 0, ByteBuffer.wrap(input), 0, input.length, 39);
++ Transform.transformDictionaryWord(output, 0,
++ ByteBuffer.wrap(input), 0, input.length, Transform.RFC_TRANSFORMS, 39);
+ byte[] expectedOutput = new byte[0];
+ assertArrayEquals(expectedOutput, output);
+ }
+@@ -46,8 +46,8 @@ public class TransformTest {
+ public void testCapitalize() {
+ byte[] output = new byte[6];
+ byte[] input = {113, -61, -90, -32, -92, -86}; // "qæप"
+- Transform.transformDictionaryWord(
+- output, 0, ByteBuffer.wrap(input), 0, input.length, 44);
++ Transform.transformDictionaryWord(output, 0,
++ ByteBuffer.wrap(input), 0, input.length, Transform.RFC_TRANSFORMS, 44);
+ byte[] expectedOutput = {81, -61, -122, -32, -92, -81}; // "QÆय"
+ assertArrayEquals(expectedOutput, output);
+ }
+@@ -60,9 +60,9 @@ public class TransformTest {
+ byte[] testWord = {111, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102};
+ byte[] output = new byte[2259];
+ int offset = 0;
+- for (int i = 0; i < Transform.NUM_TRANSFORMS; ++i) {
+- offset += Transform.transformDictionaryWord(
+- output, offset, ByteBuffer.wrap(testWord), 0, testWord.length, i);
++ for (int i = 0; i < Transform.NUM_RFC_TRANSFORMS; ++i) {
++ offset += Transform.transformDictionaryWord(output, offset,
++ ByteBuffer.wrap(testWord), 0, testWord.length, Transform.RFC_TRANSFORMS, i);
+ output[offset++] = -1;
+ }
+ assertEquals(output.length, offset);
+--
+2.6.1.windows.1
+
diff --git a/brotli.spec b/brotli.spec
index 74b9c9a..48ee385 100644
--- a/brotli.spec
+++ b/brotli.spec
@@ -1,6 +1,6 @@
Name: brotli
Version: 1.0.7
-Release: 2
+Release: 3
Summary: Lossless compression algorithm
License: MIT
@@ -9,6 +9,16 @@ Source0: https://github.com/google/brotli/archive/v%{version}.tar.gz
BuildRequires: python2-devel python3-devel gcc-c++ gcc cmake
+Patch6000: Verbose-CLI-start-pulling-Shared-Brotli.patch
+Patch6001: Ensure-decompression-consumes-all-input.patch
+Patch6002: fix-MSVC-configuration-and-c++-compilation-fails.patch
+Patch6003: fix-executable-mode-of-decode-js.patch
+Patch6004: Fix-include-for-EMCC-build.patch
+Patch6005: Add-an-option-to-avoid-building-shared-libraries.patch
+Patch6006: Disable-PIC-in-EMCC-mode.patch
+Patch6007: Add-missing-const-to-a-couple-of-kConstants.patch
+Patch6008: Move-TZCNT-and-BSR-intrinsics-and-add-MSVC-versions.patch
+
%description
Brotli is a generic-purpose lossless compression algorithm that compresses
data using a combination of a modern variant of the LZ77 algorithm, Huffman
@@ -42,7 +52,7 @@ This package installs the development files
%package_help
%prep
-%autosetup -n %{name}-%{version}
+%autosetup -n %{name}-%{version} -p1
%{__chmod} 644 c/enc/*.[ch]
%{__chmod} 644 c/include/brotli/*.h
@@ -106,6 +116,21 @@ popd
%{_mandir}/man3/*
%changelog
+* Mon Oct 19 2020 wangjie -1.0.7-3
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:Synchronize patches from community
+ Verbose-CLI-start-pulling-Shared-Brotli.patch
+ Ensure-decompression-consumes-all-input.patch
+ fix-MSVC-configuration-and-c++-compilation-fails.patch
+ fix-executable-mode-of-decode-js.patch
+ Fix-include-for-EMCC-build.patch
+ Add-an-option-to-avoid-building-shared-libraries.patch
+ Disable-PIC-in-EMCC-mode.patch
+ Add-missing-const-to-a-couple-of-kConstants.patch
+ Move-TZCNT-and-BSR-intrinsics-and-add-MSVC-versions.patch
+
* Thu Apr 16 2020 chengquan -1.0.7-2
- Type:rebuild
- ID:NA
diff --git a/fix-MSVC-configuration-and-c++-compilation-fails.patch b/fix-MSVC-configuration-and-c++-compilation-fails.patch
new file mode 100644
index 0000000..fb0d2ed
--- /dev/null
+++ b/fix-MSVC-configuration-and-c++-compilation-fails.patch
@@ -0,0 +1,11396 @@
+From ed4f8c056f1ed6c172edb355752c92acc9442825 Mon Sep 17 00:00:00 2001
+From: Eugene Kliuchnikov
+Date: Fri, 12 Apr 2019 10:37:53 +0200
+Subject: [PATCH] Update
+
+ * Bazel: fix MSVC configuration
+ * C: common: extended documentation and helpers around distance codes
+ * C: common: enable BROTLI_DCHECK in "debug" builds
+ * C: common: fix implicit trailing zero in `kPrefixSuffix`
+ * C: dec: fix possible bit reader discharge for "large-window" mode
+ * C: dec: simplify distance decoding via lookup table
+ * C: dec: reuse decoder state members memory via union with lookup table
+ * C: dec: add decoder state diagram
+ * C: enc: clarify access to static dictionary
+ * C: enc: improve static dictionary hash
+ * C: enc: add "stream offset" parameter for parallel encoding
+ * C: enc: reorganize hasher; now Q2-Q3 require exactly 256KiB
+ to avoid global TCMalloc lock
+ * C: enc: fix rare access to uninitialized data in ring-buffer
+ * C: enc: reorganize logging / checks in `write_bits.h`
+ * Java: dec: add "large-window" support
+ * Java: dec: improve speed
+ * Java: dec: debug and 32-bit mode are now activated via system properties
+ * Java: dec: demystify some state variables (use better names)
+ * Dictionary generator: add single input mode
+---
+ BUILD | 8 +-
+ README.md | 2 +-
+ c/common/constants.h | 120 +
+ c/common/platform.h | 4 +-
+ c/common/transform.c | 4 +-
+ c/dec/bit_reader.c | 17 +
+ c/dec/bit_reader.h | 55 +-
+ c/dec/decode.c | 588 ++--
+ c/dec/huffman.h | 11 +-
+ c/dec/state.c | 19 +-
+ c/dec/state.h | 181 +-
+ c/enc/backward_references.c | 15 +-
+ c/enc/backward_references.h | 5 +-
+ c/enc/backward_references_hq.c | 69 +-
+ c/enc/backward_references_hq.h | 13 +-
+ c/enc/backward_references_inc.h | 38 +-
+ c/enc/brotli_bit_stream.c | 14 +-
+ c/enc/dictionary_hash.c | 2926 ++++++++++-------
+ c/enc/dictionary_hash.h | 3 +-
+ c/enc/encode.c | 102 +-
+ c/enc/encoder_dict.c | 4 +-
+ c/enc/encoder_dict.h | 4 +-
+ c/enc/hash.h | 168 +-
+ c/enc/hash_composite_inc.h | 115 +-
+ c/enc/hash_forgetful_chain_inc.h | 137 +-
+ c/enc/hash_longest_match64_inc.h | 100 +-
+ c/enc/hash_longest_match_inc.h | 103 +-
+ c/enc/hash_longest_match_quickly_inc.h | 137 +-
+ c/enc/hash_rolling_inc.h | 48 +-
+ c/enc/hash_to_binary_tree_inc.h | 77 +-
+ c/enc/metablock.c | 28 +-
+ c/enc/params.h | 4 +-
+ c/enc/ringbuffer.h | 3 +
+ c/enc/write_bits.h | 52 +-
+ c/include/brotli/encode.h | 23 +-
+ c/tools/brotli.c | 12 +-
+ compiler_config_setting.bzl | 28 +
+ docs/encode.h.3 | 16 +-
+ java/org/brotli/dec/BitReader.java | 31 +-
+ java/org/brotli/dec/BitReaderTest.java | 19 +
+ java/org/brotli/dec/BrotliInputStream.java | 18 +-
+ java/org/brotli/dec/Decode.java | 606 ++--
+ java/org/brotli/dec/EagerStreamTest.java | 2 +-
+ java/org/brotli/dec/Huffman.java | 17 +-
+ java/org/brotli/dec/State.java | 14 +-
+ java/org/brotli/dec/SynthTest.java | 156 +-
+ java/org/brotli/dec/Utils.java | 11 +
+ java/org/brotli/wrapper/common/BUILD | 4 +-
+ java/org/brotli/wrapper/dec/BUILD | 6 +-
+ .../brotli/wrapper/dec/BrotliInputStream.java | 4 +-
+ java/org/brotli/wrapper/dec/Decoder.java | 4 +-
+ java/org/brotli/wrapper/dec/DecoderJNI.java | 3 +
+ .../brotli/wrapper/dec/EagerStreamTest.java | 2 +-
+ java/org/brotli/wrapper/enc/BUILD | 6 +-
+ java/org/brotli/wrapper/enc/EncoderJNI.java | 6 +
+ js/decode.js | 1155 ++++---
+ js/decode.min.js | 3 +-
+ research/dictionary_generator.cc | 144 +-
+ 58 files changed, 4802 insertions(+), 2662 deletions(-)
+ create mode 100755 compiler_config_setting.bzl
+ mode change 100644 => 100755 js/decode.js
+
+diff --git a/BUILD b/BUILD
+index 4ce4ad44..fa8ac13f 100644
+--- a/BUILD
++++ b/BUILD
+@@ -39,11 +39,9 @@ config_setting(
+ visibility = ["//visibility:public"],
+ )
+
+-config_setting(
+- name = "msvc",
+- values = {"compiler": "msvc-cl"},
+- visibility = ["//visibility:public"],
+-)
++load(":compiler_config_setting.bzl", "create_msvc_config")
++
++create_msvc_config()
+
+ STRICT_C_OPTIONS = select({
+ ":msvc": [],
+diff --git a/README.md b/README.md
+index f832bd4c..5da27437 100644
+--- a/README.md
++++ b/README.md
+@@ -32,7 +32,7 @@ The basic commands to build, test and install brotli are:
+ $ make
+ $ make test
+ $ make install
+-
++
+ By default, debug binaries are built. To generate "release" `Makefile` specify `--disable-debug` option to `configure-cmake`.
+
+ #### Bazel
+diff --git a/c/common/constants.h b/c/common/constants.h
+index d1b88d12..f6e44dc7 100644
+--- a/c/common/constants.h
++++ b/c/common/constants.h
+@@ -4,9 +4,17 @@
+ See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
+ */
+
++/**
++ * @file
++ * Common constants used in decoder and encoder API.
++ */
++
+ #ifndef BROTLI_COMMON_CONSTANTS_H_
+ #define BROTLI_COMMON_CONSTANTS_H_
+
++#include "./platform.h"
++#include
++
+ /* Specification: 7.3. Encoding of the context map */
+ #define BROTLI_CONTEXT_MAP_MAX_RLE 16
+
+@@ -29,12 +37,31 @@
+ #define BROTLI_INITIAL_REPEATED_CODE_LENGTH 8
+
+ /* "Large Window Brotli" */
++
++/**
++ * The theoretical maximum number of distance bits specified for large window
++ * brotli, for 64-bit encoders and decoders. Even when in practice 32-bit
++ * encoders and decoders only support up to 30 max distance bits, the value is
++ * set to 62 because it affects the large window brotli file format.
++ * Specifically, it affects the encoding of simple huffman tree for distances,
++ * see Specification RFC 7932 chapter 3.4.
++ */
+ #define BROTLI_LARGE_MAX_DISTANCE_BITS 62U
+ #define BROTLI_LARGE_MIN_WBITS 10
++/**
++ * The maximum supported large brotli window bits by the encoder and decoder.
++ * Large window brotli allows up to 62 bits, however the current encoder and
++ * decoder, designed for 32-bit integers, only support up to 30 bits maximum.
++ */
+ #define BROTLI_LARGE_MAX_WBITS 30
+
+ /* Specification: 4. Encoding of distances */
+ #define BROTLI_NUM_DISTANCE_SHORT_CODES 16
++/**
++ * Maximal number of "postfix" bits.
++ *
++ * Number of "postfix" bits is stored as 2 bits in meta-block header.
++ */
+ #define BROTLI_MAX_NPOSTFIX 3
+ #define BROTLI_MAX_NDIRECT 120
+ #define BROTLI_MAX_DISTANCE_BITS 24U
+@@ -45,7 +72,16 @@
+ #define BROTLI_NUM_DISTANCE_SYMBOLS \
+ BROTLI_DISTANCE_ALPHABET_SIZE( \
+ BROTLI_MAX_NDIRECT, BROTLI_MAX_NPOSTFIX, BROTLI_LARGE_MAX_DISTANCE_BITS)
++
++/* ((1 << 26) - 4) is the maximal distance that can be expressed in RFC 7932
++ brotli stream using NPOSTFIX = 0 and NDIRECT = 0. With other NPOSTFIX and
++ NDIRECT values distances up to ((1 << 29) + 88) could be expressed. */
+ #define BROTLI_MAX_DISTANCE 0x3FFFFFC
++
++/* ((1 << 31) - 4) is the safe distance limit. Using this number as a limit
++ allows safe distance calculation without overflows, given the distance
++ alphabet size is limited to corresponding size
++ (see kLargeWindowDistanceCodeLimits). */
+ #define BROTLI_MAX_ALLOWED_DISTANCE 0x7FFFFFFC
+
+ /* 7.1. Context modes and context ID lookup for literals */
+@@ -61,4 +97,88 @@
+ #define BROTLI_WINDOW_GAP 16
+ #define BROTLI_MAX_BACKWARD_LIMIT(W) (((size_t)1 << (W)) - BROTLI_WINDOW_GAP)
+
++typedef struct BrotliDistanceCodeLimit {
++ uint32_t max_alphabet_size;
++ uint32_t max_distance;
++} BrotliDistanceCodeLimit;
++
++/* This function calculates maximal size of distance alphabet, such that the
++ distances greater than the given values can not be represented.
++
++ This limits are designed to support fast and safe 32-bit decoders.
++ "32-bit" means that signed integer values up to ((1 << 31) - 1) could be
++ safely expressed.
++
++ Brotli distance alphabet symbols do not represent consecutive distance
++ ranges. Each distance alphabet symbol (excluding direct distances and short
++ codes), represent interleaved (for NPOSTFIX > 0) range of distances.
++ A "group" of consecutive (1 << NPOSTFIX) symbols represent non-interleaved
++ range. Two consecutive groups require the same amount of "extra bits".
++
++ It is important that distance alphabet represents complete "groups".
++ To avoid complex logic on encoder side about interleaved ranges
++ it was decided to restrict both sides to complete distance code "groups".
++ */
++BROTLI_UNUSED_FUNCTION BrotliDistanceCodeLimit BrotliCalculateDistanceCodeLimit(
++ uint32_t max_distance, uint32_t npostfix, uint32_t ndirect) {
++ BrotliDistanceCodeLimit result;
++ /* Marking this function as unused, because not all files
++ including "constants.h" use it -> compiler warns about that. */
++ BROTLI_UNUSED(&BrotliCalculateDistanceCodeLimit);
++ if (max_distance <= ndirect) {
++ /* This case never happens / exists only for the sake of completeness. */
++ result.max_alphabet_size = max_distance + BROTLI_NUM_DISTANCE_SHORT_CODES;
++ result.max_distance = max_distance;
++ return result;
++ } else {
++ /* The first prohibited value. */
++ uint32_t forbidden_distance = max_distance + 1;
++ /* Subtract "directly" encoded region. */
++ uint32_t offset = forbidden_distance - ndirect - 1;
++ uint32_t ndistbits = 0;
++ uint32_t tmp;
++ uint32_t half;
++ uint32_t group;
++ /* Postfix for the last dcode in the group. */
++ uint32_t postfix = (1u << npostfix) - 1;
++ uint32_t extra;
++ uint32_t start;
++ /* Remove postfix and "head-start". */
++ offset = (offset >> npostfix) + 4;
++ /* Calculate the number of distance bits. */
++ tmp = offset / 2;
++ /* Poor-man's log2floor, to avoid extra dependencies. */
++ while (tmp != 0) {ndistbits++; tmp = tmp >> 1;}
++ /* One bit is covered with subrange addressing ("half"). */
++ ndistbits--;
++ /* Find subrange. */
++ half = (offset >> ndistbits) & 1;
++ /* Calculate the "group" part of dcode. */
++ group = ((ndistbits - 1) << 1) | half;
++ /* Calculated "group" covers the prohibited distance value. */
++ if (group == 0) {
++ /* This case is added for correctness; does not occur for limit > 128. */
++ result.max_alphabet_size = ndirect + BROTLI_NUM_DISTANCE_SHORT_CODES;
++ result.max_distance = ndirect;
++ return result;
++ }
++ /* Decrement "group", so it is the last permitted "group". */
++ group--;
++ /* After group was decremented, ndistbits and half must be recalculated. */
++ ndistbits = (group >> 1) + 1;
++ /* The last available distance in the subrange has all extra bits set. */
++ extra = (1u << ndistbits) - 1;
++ /* Calculate region start. NB: ndistbits >= 1. */
++ start = (1u << (ndistbits + 1)) - 4;
++ /* Move to subregion. */
++ start += (group & 1) << ndistbits;
++ /* Calculate the alphabet size. */
++ result.max_alphabet_size = ((group << npostfix) | postfix) + ndirect +
++ BROTLI_NUM_DISTANCE_SHORT_CODES + 1;
++ /* Calculate the maximal distance representable by alphabet. */
++ result.max_distance = ((start + extra) << npostfix) + postfix + ndirect + 1;
++ return result;
++ }
++}
++
+ #endif /* BROTLI_COMMON_CONSTANTS_H_ */
+diff --git a/c/common/platform.h b/c/common/platform.h
+index 84c448c4..bf5f97bf 100755
+--- a/c/common/platform.h
++++ b/c/common/platform.h
+@@ -466,20 +466,20 @@ static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) {
+ #endif
+
+ #if defined(BROTLI_ENABLE_LOG)
+-#define BROTLI_DCHECK(x) assert(x)
+ #define BROTLI_LOG(x) printf x
+ #else
+-#define BROTLI_DCHECK(x)
+ #define BROTLI_LOG(x)
+ #endif
+
+ #if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG)
++#define BROTLI_DCHECK(x) assert(x)
+ static BROTLI_INLINE void BrotliDump(const char* f, int l, const char* fn) {
+ fprintf(stderr, "%s:%d (%s)\n", f, l, fn);
+ fflush(stderr);
+ }
+ #define BROTLI_DUMP() BrotliDump(__FILE__, __LINE__, __FUNCTION__)
+ #else
++#define BROTLI_DCHECK(x)
+ #define BROTLI_DUMP() (void)(0)
+ #endif
+
+diff --git a/c/common/transform.c b/c/common/transform.c
+index c182053d..c44f6715 100755
+--- a/c/common/transform.c
++++ b/c/common/transform.c
+@@ -24,8 +24,8 @@ static const char kPrefixSuffix[217] =
+ /* 8x _0 _ _3 _8 _C _E _ _1 _7 _F */
+ " not \3er \3al \4ful \4ive \5less \4es"
+ /* Ax _5 _9 _D _2 _7 _D */
+- "t \4ize \2\xc2\xa0\4ous \5 the \2e \0";
+-/* Cx _2 _7___ ___ _A _F _5 _8 */
++ "t \4ize \2\xc2\xa0\4ous \5 the \2e "; /* \0 - implicit trailing zero. */
++/* Cx _2 _7___ ___ _A _F _5 _8 */
+
+ static const uint16_t kPrefixSuffixMap[50] = {
+ 0x00, 0x02, 0x05, 0x0E, 0x13, 0x16, 0x18, 0x1E, 0x23, 0x25,
+diff --git a/c/dec/bit_reader.c b/c/dec/bit_reader.c
+index 722fd906..41cd0504 100644
+--- a/c/dec/bit_reader.c
++++ b/c/dec/bit_reader.c
+@@ -43,6 +43,23 @@ BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
+ return BROTLI_TRUE;
+ }
+
++BROTLI_BOOL BrotliSafeReadBits32Slow(BrotliBitReader* const br,
++ uint32_t n_bits, uint32_t* val) {
++ uint32_t low_val;
++ uint32_t high_val;
++ BrotliBitReaderState memento;
++ BROTLI_DCHECK(n_bits <= 32);
++ BROTLI_DCHECK(n_bits > 24);
++ BrotliBitReaderSaveState(br, &memento);
++ if (!BrotliSafeReadBits(br, 16, &low_val) ||
++ !BrotliSafeReadBits(br, n_bits - 16, &high_val)) {
++ BrotliBitReaderRestoreState(br, &memento);
++ return BROTLI_FALSE;
++ }
++ *val = low_val | (high_val << 16);
++ return BROTLI_TRUE;
++}
++
+ #if defined(__cplusplus) || defined(c_plusplus)
+ } /* extern "C" */
+ #endif
+diff --git a/c/dec/bit_reader.h b/c/dec/bit_reader.h
+index c06e9141..f94a717e 100644
+--- a/c/dec/bit_reader.h
++++ b/c/dec/bit_reader.h
+@@ -65,6 +65,12 @@ BROTLI_INTERNAL void BrotliInitBitReader(BrotliBitReader* const br);
+ reading. */
+ BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br);
+
++/* Fallback for BrotliSafeReadBits32. Extracted as noninlined method to unburden
++ the main code-path. Never called for RFC brotli streams, required only for
++ "large-window" mode and other extensions. */
++BROTLI_INTERNAL BROTLI_NOINLINE BROTLI_BOOL BrotliSafeReadBits32Slow(
++ BrotliBitReader* const br, uint32_t n_bits, uint32_t* val);
++
+ static BROTLI_INLINE void BrotliBitReaderSaveState(
+ BrotliBitReader* const from, BrotliBitReaderState* to) {
+ to->val_ = from->val_;
+@@ -237,15 +243,17 @@ static BROTLI_INLINE void BrotliBitReaderUnload(BrotliBitReader* br) {
+ static BROTLI_INLINE void BrotliTakeBits(
+ BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
+ *val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
+- BROTLI_LOG(("[BrotliReadBits] %d %d %d val: %6x\n",
++ BROTLI_LOG(("[BrotliTakeBits] %d %d %d val: %6x\n",
+ (int)br->avail_in, (int)br->bit_pos_, (int)n_bits, (int)*val));
+ BrotliDropBits(br, n_bits);
+ }
+
+ /* Reads the specified number of bits from |br| and advances the bit pos.
+- Assumes that there is enough input to perform BrotliFillBitWindow. */
+-static BROTLI_INLINE uint32_t BrotliReadBits(
++ Assumes that there is enough input to perform BrotliFillBitWindow.
++ Up to 24 bits are allowed to be requested from this method. */
++static BROTLI_INLINE uint32_t BrotliReadBits24(
+ BrotliBitReader* const br, uint32_t n_bits) {
++ BROTLI_DCHECK(n_bits <= 24);
+ if (BROTLI_64_BITS || (n_bits <= 16)) {
+ uint32_t val;
+ BrotliFillBitWindow(br, n_bits);
+@@ -262,10 +270,32 @@ static BROTLI_INLINE uint32_t BrotliReadBits(
+ }
+ }
+
++/* Same as BrotliReadBits24, but allows reading up to 32 bits. */
++static BROTLI_INLINE uint32_t BrotliReadBits32(
++ BrotliBitReader* const br, uint32_t n_bits) {
++ BROTLI_DCHECK(n_bits <= 32);
++ if (BROTLI_64_BITS || (n_bits <= 16)) {
++ uint32_t val;
++ BrotliFillBitWindow(br, n_bits);
++ BrotliTakeBits(br, n_bits, &val);
++ return val;
++ } else {
++ uint32_t low_val;
++ uint32_t high_val;
++ BrotliFillBitWindow(br, 16);
++ BrotliTakeBits(br, 16, &low_val);
++ BrotliFillBitWindow(br, 16);
++ BrotliTakeBits(br, n_bits - 16, &high_val);
++ return low_val | (high_val << 16);
++ }
++}
++
+ /* Tries to read the specified amount of bits. Returns BROTLI_FALSE, if there
+- is not enough input. |n_bits| MUST be positive. */
++ is not enough input. |n_bits| MUST be positive.
++ Up to 24 bits are allowed to be requested from this method. */
+ static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits(
+ BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
++ BROTLI_DCHECK(n_bits <= 24);
+ while (BrotliGetAvailableBits(br) < n_bits) {
+ if (!BrotliPullByte(br)) {
+ return BROTLI_FALSE;
+@@ -275,6 +305,23 @@ static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits(
+ return BROTLI_TRUE;
+ }
+
++/* Same as BrotliSafeReadBits, but allows reading up to 32 bits. */
++static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits32(
++ BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
++ BROTLI_DCHECK(n_bits <= 32);
++ if (BROTLI_64_BITS || (n_bits <= 24)) {
++ while (BrotliGetAvailableBits(br) < n_bits) {
++ if (!BrotliPullByte(br)) {
++ return BROTLI_FALSE;
++ }
++ }
++ BrotliTakeBits(br, n_bits, val);
++ return BROTLI_TRUE;
++ } else {
++ return BrotliSafeReadBits32Slow(br, n_bits, val);
++ }
++}
++
+ /* Advances the bit reader position to the next byte boundary and verifies
+ that any skipped bits are set to zero. */
+ static BROTLI_INLINE BROTLI_BOOL BrotliJumpToByteBoundary(BrotliBitReader* br) {
+diff --git a/c/dec/decode.c b/c/dec/decode.c
+index 08bd76ca..bde4795a 100644
+--- a/c/dec/decode.c
++++ b/c/dec/decode.c
+@@ -470,32 +470,34 @@ static BROTLI_INLINE uint32_t Log2Floor(uint32_t x) {
+ Totally 1..4 symbols are read, 1..11 bits each.
+ The list of symbols MUST NOT contain duplicates. */
+ static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols(
+- uint32_t alphabet_size, uint32_t max_symbol, BrotliDecoderState* s) {
++ uint32_t alphabet_size_max, uint32_t alphabet_size_limit,
++ BrotliDecoderState* s) {
+ /* max_bits == 1..11; symbol == 0..3; 1..44 bits will be read. */
+ BrotliBitReader* br = &s->br;
+- uint32_t max_bits = Log2Floor(alphabet_size - 1);
+- uint32_t i = s->sub_loop_counter;
+- uint32_t num_symbols = s->symbol;
++ BrotliMetablockHeaderArena* h = &s->arena.header;
++ uint32_t max_bits = Log2Floor(alphabet_size_max - 1);
++ uint32_t i = h->sub_loop_counter;
++ uint32_t num_symbols = h->symbol;
+ while (i <= num_symbols) {
+ uint32_t v;
+ if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, max_bits, &v))) {
+- s->sub_loop_counter = i;
+- s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_READ;
++ h->sub_loop_counter = i;
++ h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_READ;
+ return BROTLI_DECODER_NEEDS_MORE_INPUT;
+ }
+- if (v >= max_symbol) {
++ if (v >= alphabet_size_limit) {
+ return
+ BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET);
+ }
+- s->symbols_lists_array[i] = (uint16_t)v;
+- BROTLI_LOG_UINT(s->symbols_lists_array[i]);
++ h->symbols_lists_array[i] = (uint16_t)v;
++ BROTLI_LOG_UINT(h->symbols_lists_array[i]);
+ ++i;
+ }
+
+ for (i = 0; i < num_symbols; ++i) {
+ uint32_t k = i + 1;
+ for (; k <= num_symbols; ++k) {
+- if (s->symbols_lists_array[i] == s->symbols_lists_array[k]) {
++ if (h->symbols_lists_array[i] == h->symbols_lists_array[k]) {
+ return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME);
+ }
+ }
+@@ -588,27 +590,28 @@ static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len,
+ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
+ uint32_t alphabet_size, BrotliDecoderState* s) {
+ BrotliBitReader* br = &s->br;
+- uint32_t symbol = s->symbol;
+- uint32_t repeat = s->repeat;
+- uint32_t space = s->space;
+- uint32_t prev_code_len = s->prev_code_len;
+- uint32_t repeat_code_len = s->repeat_code_len;
+- uint16_t* symbol_lists = s->symbol_lists;
+- uint16_t* code_length_histo = s->code_length_histo;
+- int* next_symbol = s->next_symbol;
++ BrotliMetablockHeaderArena* h = &s->arena.header;
++ uint32_t symbol = h->symbol;
++ uint32_t repeat = h->repeat;
++ uint32_t space = h->space;
++ uint32_t prev_code_len = h->prev_code_len;
++ uint32_t repeat_code_len = h->repeat_code_len;
++ uint16_t* symbol_lists = h->symbol_lists;
++ uint16_t* code_length_histo = h->code_length_histo;
++ int* next_symbol = h->next_symbol;
+ if (!BrotliWarmupBitReader(br)) {
+ return BROTLI_DECODER_NEEDS_MORE_INPUT;
+ }
+ while (symbol < alphabet_size && space > 0) {
+- const HuffmanCode* p = s->table;
++ const HuffmanCode* p = h->table;
+ uint32_t code_len;
+ BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p);
+ if (!BrotliCheckInputAmount(br, BROTLI_SHORT_FILL_BIT_WINDOW_READ)) {
+- s->symbol = symbol;
+- s->repeat = repeat;
+- s->prev_code_len = prev_code_len;
+- s->repeat_code_len = repeat_code_len;
+- s->space = space;
++ h->symbol = symbol;
++ h->repeat = repeat;
++ h->prev_code_len = prev_code_len;
++ h->repeat_code_len = repeat_code_len;
++ h->space = space;
+ return BROTLI_DECODER_NEEDS_MORE_INPUT;
+ }
+ BrotliFillBitWindow16(br);
+@@ -630,16 +633,17 @@ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
+ symbol_lists, code_length_histo, next_symbol);
+ }
+ }
+- s->space = space;
++ h->space = space;
+ return BROTLI_DECODER_SUCCESS;
+ }
+
+ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
+ uint32_t alphabet_size, BrotliDecoderState* s) {
+ BrotliBitReader* br = &s->br;
++ BrotliMetablockHeaderArena* h = &s->arena.header;
+ BROTLI_BOOL get_byte = BROTLI_FALSE;
+- while (s->symbol < alphabet_size && s->space > 0) {
+- const HuffmanCode* p = s->table;
++ while (h->symbol < alphabet_size && h->space > 0) {
++ const HuffmanCode* p = h->table;
+ uint32_t code_len;
+ uint32_t available_bits;
+ uint32_t bits = 0;
+@@ -659,9 +663,9 @@ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
+ code_len = BROTLI_HC_FAST_LOAD_VALUE(p); /* code_len == 0..17 */
+ if (code_len < BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) {
+ BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(p));
+- ProcessSingleCodeLength(code_len, &s->symbol, &s->repeat, &s->space,
+- &s->prev_code_len, s->symbol_lists, s->code_length_histo,
+- s->next_symbol);
++ ProcessSingleCodeLength(code_len, &h->symbol, &h->repeat, &h->space,
++ &h->prev_code_len, h->symbol_lists, h->code_length_histo,
++ h->next_symbol);
+ } else { /* code_len == 16..17, extra_bits == 2..3 */
+ uint32_t extra_bits = code_len - 14U;
+ uint32_t repeat_delta = (bits >> BROTLI_HC_FAST_LOAD_BITS(p)) &
+@@ -672,9 +676,9 @@ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
+ }
+ BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(p) + extra_bits);
+ ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size,
+- &s->symbol, &s->repeat, &s->space, &s->prev_code_len,
+- &s->repeat_code_len, s->symbol_lists, s->code_length_histo,
+- s->next_symbol);
++ &h->symbol, &h->repeat, &h->space, &h->prev_code_len,
++ &h->repeat_code_len, h->symbol_lists, h->code_length_histo,
++ h->next_symbol);
+ }
+ }
+ return BROTLI_DECODER_SUCCESS;
+@@ -684,9 +688,10 @@ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
+ Each code is 2..4 bits long. In total 30..72 bits are used. */
+ static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
+ BrotliBitReader* br = &s->br;
+- uint32_t num_codes = s->repeat;
+- unsigned space = s->space;
+- uint32_t i = s->sub_loop_counter;
++ BrotliMetablockHeaderArena* h = &s->arena.header;
++ uint32_t num_codes = h->repeat;
++ unsigned space = h->space;
++ uint32_t i = h->sub_loop_counter;
+ for (; i < BROTLI_CODE_LENGTH_CODES; ++i) {
+ const uint8_t code_len_idx = kCodeLengthCodeOrder[i];
+ uint32_t ix;
+@@ -699,21 +704,21 @@ static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
+ ix = 0;
+ }
+ if (kCodeLengthPrefixLength[ix] > available_bits) {
+- s->sub_loop_counter = i;
+- s->repeat = num_codes;
+- s->space = space;
+- s->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX;
++ h->sub_loop_counter = i;
++ h->repeat = num_codes;
++ h->space = space;
++ h->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX;
+ return BROTLI_DECODER_NEEDS_MORE_INPUT;
+ }
+ }
+ v = kCodeLengthPrefixValue[ix];
+ BrotliDropBits(br, kCodeLengthPrefixLength[ix]);
+- s->code_length_code_lengths[code_len_idx] = (uint8_t)v;
+- BROTLI_LOG_ARRAY_INDEX(s->code_length_code_lengths, code_len_idx);
++ h->code_length_code_lengths[code_len_idx] = (uint8_t)v;
++ BROTLI_LOG_ARRAY_INDEX(h->code_length_code_lengths, code_len_idx);
+ if (v != 0) {
+ space = space - (32U >> v);
+ ++num_codes;
+- ++s->code_length_histo[v];
++ ++h->code_length_histo[v];
+ if (space - 1U >= 32U) {
+ /* space is 0 or wrapped around. */
+ break;
+@@ -737,49 +742,48 @@ static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
+ encoded with predefined entropy code. 32 - 74 bits are used.
+ B.2) Decoded table is used to decode code lengths of symbols in resulting
+ Huffman table. In worst case 3520 bits are read. */
+-static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size,
+- uint32_t max_symbol,
++static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
++ uint32_t alphabet_size_limit,
+ HuffmanCode* table,
+ uint32_t* opt_table_size,
+ BrotliDecoderState* s) {
+ BrotliBitReader* br = &s->br;
+- /* Unnecessary masking, but might be good for safety. */
+- alphabet_size &= 0x7FF;
++ BrotliMetablockHeaderArena* h = &s->arena.header;
+ /* State machine. */
+ for (;;) {
+- switch (s->substate_huffman) {
++ switch (h->substate_huffman) {
+ case BROTLI_STATE_HUFFMAN_NONE:
+- if (!BrotliSafeReadBits(br, 2, &s->sub_loop_counter)) {
++ if (!BrotliSafeReadBits(br, 2, &h->sub_loop_counter)) {
+ return BROTLI_DECODER_NEEDS_MORE_INPUT;
+ }
+- BROTLI_LOG_UINT(s->sub_loop_counter);
++ BROTLI_LOG_UINT(h->sub_loop_counter);
+ /* The value is used as follows:
+ 1 for simple code;
+ 0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */
+- if (s->sub_loop_counter != 1) {
+- s->space = 32;
+- s->repeat = 0; /* num_codes */
+- memset(&s->code_length_histo[0], 0, sizeof(s->code_length_histo[0]) *
++ if (h->sub_loop_counter != 1) {
++ h->space = 32;
++ h->repeat = 0; /* num_codes */
++ memset(&h->code_length_histo[0], 0, sizeof(h->code_length_histo[0]) *
+ (BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1));
+- memset(&s->code_length_code_lengths[0], 0,
+- sizeof(s->code_length_code_lengths));
+- s->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX;
++ memset(&h->code_length_code_lengths[0], 0,
++ sizeof(h->code_length_code_lengths));
++ h->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX;
+ continue;
+ }
+ /* Fall through. */
+
+ case BROTLI_STATE_HUFFMAN_SIMPLE_SIZE:
+ /* Read symbols, codes & code lengths directly. */
+- if (!BrotliSafeReadBits(br, 2, &s->symbol)) { /* num_symbols */
+- s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_SIZE;
++ if (!BrotliSafeReadBits(br, 2, &h->symbol)) { /* num_symbols */
++ h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_SIZE;
+ return BROTLI_DECODER_NEEDS_MORE_INPUT;
+ }
+- s->sub_loop_counter = 0;
++ h->sub_loop_counter = 0;
+ /* Fall through. */
+
+ case BROTLI_STATE_HUFFMAN_SIMPLE_READ: {
+ BrotliDecoderErrorCode result =
+- ReadSimpleHuffmanSymbols(alphabet_size, max_symbol, s);
++ ReadSimpleHuffmanSymbols(alphabet_size_max, alphabet_size_limit, s);
+ if (result != BROTLI_DECODER_SUCCESS) {
+ return result;
+ }
+@@ -788,21 +792,21 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size,
+
+ case BROTLI_STATE_HUFFMAN_SIMPLE_BUILD: {
+ uint32_t table_size;
+- if (s->symbol == 3) {
++ if (h->symbol == 3) {
+ uint32_t bits;
+ if (!BrotliSafeReadBits(br, 1, &bits)) {
+- s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
++ h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
+ return BROTLI_DECODER_NEEDS_MORE_INPUT;
+ }
+- s->symbol += bits;
++ h->symbol += bits;
+ }
+- BROTLI_LOG_UINT(s->symbol);
++ BROTLI_LOG_UINT(h->symbol);
+ table_size = BrotliBuildSimpleHuffmanTable(
+- table, HUFFMAN_TABLE_BITS, s->symbols_lists_array, s->symbol);
++ table, HUFFMAN_TABLE_BITS, h->symbols_lists_array, h->symbol);
+ if (opt_table_size) {
+ *opt_table_size = table_size;
+ }
+- s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
++ h->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
+ return BROTLI_DECODER_SUCCESS;
+ }
+
+@@ -813,44 +817,45 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size,
+ if (result != BROTLI_DECODER_SUCCESS) {
+ return result;
+ }
+- BrotliBuildCodeLengthsHuffmanTable(s->table,
+- s->code_length_code_lengths,
+- s->code_length_histo);
+- memset(&s->code_length_histo[0], 0, sizeof(s->code_length_histo));
++ BrotliBuildCodeLengthsHuffmanTable(h->table,
++ h->code_length_code_lengths,
++ h->code_length_histo);
++ memset(&h->code_length_histo[0], 0, sizeof(h->code_length_histo));
+ for (i = 0; i <= BROTLI_HUFFMAN_MAX_CODE_LENGTH; ++i) {
+- s->next_symbol[i] = (int)i - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1);
+- s->symbol_lists[s->next_symbol[i]] = 0xFFFF;
++ h->next_symbol[i] = (int)i - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1);
++ h->symbol_lists[h->next_symbol[i]] = 0xFFFF;
+ }
+
+- s->symbol = 0;
+- s->prev_code_len = BROTLI_INITIAL_REPEATED_CODE_LENGTH;
+- s->repeat = 0;
+- s->repeat_code_len = 0;
+- s->space = 32768;
+- s->substate_huffman = BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS;
++ h->symbol = 0;
++ h->prev_code_len = BROTLI_INITIAL_REPEATED_CODE_LENGTH;
++ h->repeat = 0;
++ h->repeat_code_len = 0;
++ h->space = 32768;
++ h->substate_huffman = BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS;
+ }
+ /* Fall through. */
+
+ case BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS: {
+ uint32_t table_size;
+- BrotliDecoderErrorCode result = ReadSymbolCodeLengths(max_symbol, s);
++ BrotliDecoderErrorCode result = ReadSymbolCodeLengths(
++ alphabet_size_limit, s);
+ if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) {
+- result = SafeReadSymbolCodeLengths(max_symbol, s);
++ result = SafeReadSymbolCodeLengths(alphabet_size_limit, s);
+ }
+ if (result != BROTLI_DECODER_SUCCESS) {
+ return result;
+ }
+
+- if (s->space != 0) {
+- BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", (int)s->space));
++ if (h->space != 0) {
++ BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", (int)h->space));
+ return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE);
+ }
+ table_size = BrotliBuildHuffmanTable(
+- table, HUFFMAN_TABLE_BITS, s->symbol_lists, s->code_length_histo);
++ table, HUFFMAN_TABLE_BITS, h->symbol_lists, h->code_length_histo);
+ if (opt_table_size) {
+ *opt_table_size = table_size;
+ }
+- s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
++ h->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
+ return BROTLI_DECODER_SUCCESS;
+ }
+
+@@ -868,7 +873,7 @@ static BROTLI_INLINE uint32_t ReadBlockLength(const HuffmanCode* table,
+ uint32_t nbits;
+ code = ReadSymbol(table, br);
+ nbits = kBlockLengthPrefixCode[code].nbits; /* nbits == 2..24 */
+- return kBlockLengthPrefixCode[code].offset + BrotliReadBits(br, nbits);
++ return kBlockLengthPrefixCode[code].offset + BrotliReadBits24(br, nbits);
+ }
+
+ /* WARNING: if state is not BROTLI_STATE_READ_BLOCK_LENGTH_NONE, then
+@@ -952,22 +957,22 @@ static BROTLI_NOINLINE void InverseMoveToFrontTransform(
+ /* Decodes a series of Huffman table using ReadHuffmanCode function. */
+ static BrotliDecoderErrorCode HuffmanTreeGroupDecode(
+ HuffmanTreeGroup* group, BrotliDecoderState* s) {
+- if (s->substate_tree_group != BROTLI_STATE_TREE_GROUP_LOOP) {
+- s->next = group->codes;
+- s->htree_index = 0;
+- s->substate_tree_group = BROTLI_STATE_TREE_GROUP_LOOP;
++ BrotliMetablockHeaderArena* h = &s->arena.header;
++ if (h->substate_tree_group != BROTLI_STATE_TREE_GROUP_LOOP) {
++ h->next = group->codes;
++ h->htree_index = 0;
++ h->substate_tree_group = BROTLI_STATE_TREE_GROUP_LOOP;
+ }
+- while (s->htree_index < group->num_htrees) {
++ while (h->htree_index < group->num_htrees) {
+ uint32_t table_size;
+- BrotliDecoderErrorCode result =
+- ReadHuffmanCode(group->alphabet_size, group->max_symbol,
+- s->next, &table_size, s);
++ BrotliDecoderErrorCode result = ReadHuffmanCode(group->alphabet_size_max,
++ group->alphabet_size_limit, h->next, &table_size, s);
+ if (result != BROTLI_DECODER_SUCCESS) return result;
+- group->htrees[s->htree_index] = s->next;
+- s->next += table_size;
+- ++s->htree_index;
++ group->htrees[h->htree_index] = h->next;
++ h->next += table_size;
++ ++h->htree_index;
+ }
+- s->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE;
++ h->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE;
+ return BROTLI_DECODER_SUCCESS;
+ }
+
+@@ -985,15 +990,16 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
+ BrotliDecoderState* s) {
+ BrotliBitReader* br = &s->br;
+ BrotliDecoderErrorCode result = BROTLI_DECODER_SUCCESS;
++ BrotliMetablockHeaderArena* h = &s->arena.header;
+
+- switch ((int)s->substate_context_map) {
++ switch ((int)h->substate_context_map) {
+ case BROTLI_STATE_CONTEXT_MAP_NONE:
+ result = DecodeVarLenUint8(s, br, num_htrees);
+ if (result != BROTLI_DECODER_SUCCESS) {
+ return result;
+ }
+ (*num_htrees)++;
+- s->context_index = 0;
++ h->context_index = 0;
+ BROTLI_LOG_UINT(context_map_size);
+ BROTLI_LOG_UINT(*num_htrees);
+ *context_map_arg =
+@@ -1005,7 +1011,7 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
+ memset(*context_map_arg, 0, (size_t)context_map_size);
+ return BROTLI_DECODER_SUCCESS;
+ }
+- s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_READ_PREFIX;
++ h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_READ_PREFIX;
+ /* Fall through. */
+
+ case BROTLI_STATE_CONTEXT_MAP_READ_PREFIX: {
+@@ -1016,38 +1022,38 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
+ return BROTLI_DECODER_NEEDS_MORE_INPUT;
+ }
+ if ((bits & 1) != 0) { /* Use RLE for zeros. */
+- s->max_run_length_prefix = (bits >> 1) + 1;
++ h->max_run_length_prefix = (bits >> 1) + 1;
+ BrotliDropBits(br, 5);
+ } else {
+- s->max_run_length_prefix = 0;
++ h->max_run_length_prefix = 0;
+ BrotliDropBits(br, 1);
+ }
+- BROTLI_LOG_UINT(s->max_run_length_prefix);
+- s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_HUFFMAN;
++ BROTLI_LOG_UINT(h->max_run_length_prefix);
++ h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_HUFFMAN;
+ }
+ /* Fall through. */
+
+ case BROTLI_STATE_CONTEXT_MAP_HUFFMAN: {
+- uint32_t alphabet_size = *num_htrees + s->max_run_length_prefix;
++ uint32_t alphabet_size = *num_htrees + h->max_run_length_prefix;
+ result = ReadHuffmanCode(alphabet_size, alphabet_size,
+- s->context_map_table, NULL, s);
++ h->context_map_table, NULL, s);
+ if (result != BROTLI_DECODER_SUCCESS) return result;
+- s->code = 0xFFFF;
+- s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_DECODE;
++ h->code = 0xFFFF;
++ h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_DECODE;
+ }
+ /* Fall through. */
+
+ case BROTLI_STATE_CONTEXT_MAP_DECODE: {
+- uint32_t context_index = s->context_index;
+- uint32_t max_run_length_prefix = s->max_run_length_prefix;
++ uint32_t context_index = h->context_index;
++ uint32_t max_run_length_prefix = h->max_run_length_prefix;
+ uint8_t* context_map = *context_map_arg;
+- uint32_t code = s->code;
++ uint32_t code = h->code;
+ BROTLI_BOOL skip_preamble = (code != 0xFFFF);
+ while (context_index < context_map_size || skip_preamble) {
+ if (!skip_preamble) {
+- if (!SafeReadSymbol(s->context_map_table, br, &code)) {
+- s->code = 0xFFFF;
+- s->context_index = context_index;
++ if (!SafeReadSymbol(h->context_map_table, br, &code)) {
++ h->code = 0xFFFF;
++ h->context_index = context_index;
+ return BROTLI_DECODER_NEEDS_MORE_INPUT;
+ }
+ BROTLI_LOG_UINT(code);
+@@ -1068,8 +1074,8 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
+ {
+ uint32_t reps;
+ if (!BrotliSafeReadBits(br, code, &reps)) {
+- s->code = code;
+- s->context_index = context_index;
++ h->code = code;
++ h->context_index = context_index;
+ return BROTLI_DECODER_NEEDS_MORE_INPUT;
+ }
+ reps += 1U << code;
+@@ -1089,13 +1095,13 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
+ case BROTLI_STATE_CONTEXT_MAP_TRANSFORM: {
+ uint32_t bits;
+ if (!BrotliSafeReadBits(br, 1, &bits)) {
+- s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_TRANSFORM;
++ h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_TRANSFORM;
+ return BROTLI_DECODER_NEEDS_MORE_INPUT;
+ }
+ if (bits != 0) {
+ InverseMoveToFrontTransform(*context_map_arg, context_map_size, s);
+ }
+- s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
++ h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
+ return BROTLI_DECODER_SUCCESS;
+ }
+
+@@ -1457,32 +1463,28 @@ static BrotliDecoderErrorCode ReadContextModes(BrotliDecoderState* s) {
+ }
+
+ static BROTLI_INLINE void TakeDistanceFromRingBuffer(BrotliDecoderState* s) {
+- if (s->distance_code == 0) {
+- --s->dist_rb_idx;
+- s->distance_code = s->dist_rb[s->dist_rb_idx & 3];
++ int offset = s->distance_code - 3;
++ if (s->distance_code <= 3) {
+ /* Compensate double distance-ring-buffer roll for dictionary items. */
+- s->distance_context = 1;
++ s->distance_context = 1 >> s->distance_code;
++ s->distance_code = s->dist_rb[(s->dist_rb_idx - offset) & 3];
++ s->dist_rb_idx -= s->distance_context;
+ } else {
+- int distance_code = s->distance_code << 1;
+- /* kDistanceShortCodeIndexOffset has 2-bit values from LSB:
+- 3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 */
+- const uint32_t kDistanceShortCodeIndexOffset = 0xAAAFFF1B;
+- /* kDistanceShortCodeValueOffset has 2-bit values from LSB:
+- -0, 0,-0, 0,-1, 1,-2, 2,-3, 3,-1, 1,-2, 2,-3, 3 */
+- const uint32_t kDistanceShortCodeValueOffset = 0xFA5FA500;
+- int v = (s->dist_rb_idx +
+- (int)(kDistanceShortCodeIndexOffset >> distance_code)) & 0x3;
+- s->distance_code = s->dist_rb[v];
+- v = (int)(kDistanceShortCodeValueOffset >> distance_code) & 0x3;
+- if ((distance_code & 0x3) != 0) {
+- s->distance_code += v;
++ int index_delta = 3;
++ int delta;
++ int base = s->distance_code - 10;
++ if (s->distance_code < 10) {
++ base = s->distance_code - 4;
+ } else {
+- s->distance_code -= v;
+- if (s->distance_code <= 0) {
+- /* A huge distance will cause a BROTLI_FAILURE() soon.
+- This is a little faster than failing here. */
+- s->distance_code = 0x7FFFFFFF;
+- }
++ index_delta = 2;
++ }
++ /* Unpack one of six 4-bit values. */
++ delta = ((0x605142 >> (4 * base)) & 0xF) - 3;
++ s->distance_code = s->dist_rb[(s->dist_rb_idx + index_delta) & 0x3] + delta;
++ if (s->distance_code <= 0) {
++ /* A huge distance will cause a BROTLI_FAILURE() soon.
++ This is a little faster than failing here. */
++ s->distance_code = 0x7FFFFFFF;
+ }
+ }
+ }
+@@ -1497,62 +1499,153 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBits(
+ }
+ }
+
++static BROTLI_INLINE BROTLI_BOOL SafeReadBits32(
++ BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
++ if (n_bits != 0) {
++ return BrotliSafeReadBits32(br, n_bits, val);
++ } else {
++ *val = 0;
++ return BROTLI_TRUE;
++ }
++}
++
++/*
++ RFC 7932 Section 4 with "..." shortenings and "[]" emendations.
++
++ Each distance ... is represented with a pair ...
++ The distance code is encoded using a prefix code... The number of extra bits
++ can be 0..24... Two additional parameters: NPOSTFIX (0..3), and ...
++ NDIRECT (0..120) ... are encoded in the meta-block header...
++
++ The first 16 distance symbols ... reference past distances... ring buffer ...
++ Next NDIRECT distance symbols ... represent distances from 1 to NDIRECT...
++ [For] distance symbols 16 + NDIRECT and greater ... the number of extra bits
++ ... is given by the following formula:
++
++ [ xcode = dcode - NDIRECT - 16 ]
++ ndistbits = 1 + [ xcode ] >> (NPOSTFIX + 1)
++
++ ...
++*/
++
++/*
++ RFC 7932 Section 9.2 with "..." shortenings and "[]" emendations.
++
++ ... to get the actual value of the parameter NDIRECT, left-shift this
++ four-bit number by NPOSTFIX bits ...
++*/
++
++/* Remaining formulas from RFC 7932 Section 4 could be rewritten as following:
++
++ alphabet_size = 16 + NDIRECT + (max_distbits << (NPOSTFIX + 1))
++
++ half = ((xcode >> NPOSTFIX) & 1) << ndistbits
++ postfix = xcode & ((1 << NPOSTFIX) - 1)
++ range_start = 2 * (1 << ndistbits - 1 - 1)
++
++ distance = (range_start + half + extra) << NPOSTFIX + postfix + NDIRECT + 1
++
++ NB: ndistbits >= 1 -> range_start >= 0
++ NB: range_start has factor 2, as the range is covered by 2 "halves"
++ NB: extra -1 offset in range_start formula covers the absence of
++ ndistbits = 0 case
++ NB: when NPOSTFIX = 0, NDIRECT is not greater than 15
++
++ In other words, xcode has the following binary structure - XXXHPPP:
++ - XXX represent the number of extra distance bits
++ - H selects upper / lower range of distances
++ - PPP represent "postfix"
++
++ "Regular" distance encoding has NPOSTFIX = 0; omitting the postfix part
++ simplifies distance calculation.
++
++ Using NPOSTFIX > 0 allows cheaper encoding of regular structures, e.g. where
++ most of distances have the same reminder of division by 2/4/8. For example,
++ the table of int32_t values that come from different sources; if it is likely
++ that 3 highest bytes of values from the same source are the same, then
++ copy distance often looks like 4x + y.
++
++ Distance calculation could be rewritten to:
++
++ ndistbits = NDISTBITS(NDIRECT, NPOSTFIX)[dcode]
++ distance = OFFSET(NDIRECT, NPOSTFIX)[dcode] + extra << NPOSTFIX
++
++ NDISTBITS and OFFSET could be pre-calculated, as NDIRECT and NPOSTFIX could
++ change only once per meta-block.
++*/
++
++/* Calculates distance lookup table.
++ NB: it is possible to have all 64 tables precalculated. */
++static void CalculateDistanceLut(BrotliDecoderState* s) {
++ BrotliMetablockBodyArena* b = &s->arena.body;
++ uint32_t npostfix = s->distance_postfix_bits;
++ uint32_t ndirect = s->num_direct_distance_codes;
++ uint32_t alphabet_size_limit = s->distance_hgroup.alphabet_size_limit;
++ uint32_t postfix = 1u << npostfix;
++ uint32_t j;
++ uint32_t bits = 1;
++ uint32_t half = 0;
++
++ /* Skip short codes. */
++ uint32_t i = BROTLI_NUM_DISTANCE_SHORT_CODES;
++
++ /* Fill direct codes. */
++ for (j = 0; j < ndirect; ++j) {
++ b->dist_extra_bits[i] = 0;
++ b->dist_offset[i] = j + 1;
++ ++i;
++ }
++
++ /* Fill regular distance codes. */
++ while (i < alphabet_size_limit) {
++ uint32_t base = ndirect + ((((2 + half) << bits) - 4) << npostfix) + 1;
++ /* Always fill the complete group. */
++ for (j = 0; j < postfix; ++j) {
++ b->dist_extra_bits[i] = (uint8_t)bits;
++ b->dist_offset[i] = base + j;
++ ++i;
++ }
++ bits = bits + half;
++ half = half ^ 1;
++ }
++}
++
+ /* Precondition: s->distance_code < 0. */
+ static BROTLI_INLINE BROTLI_BOOL ReadDistanceInternal(
+ int safe, BrotliDecoderState* s, BrotliBitReader* br) {
+- int distval;
++ BrotliMetablockBodyArena* b = &s->arena.body;
++ uint32_t code;
++ uint32_t bits;
+ BrotliBitReaderState memento;
+ HuffmanCode* distance_tree = s->distance_hgroup.htrees[s->dist_htree_index];
+ if (!safe) {
+- s->distance_code = (int)ReadSymbol(distance_tree, br);
++ code = ReadSymbol(distance_tree, br);
+ } else {
+- uint32_t code;
+ BrotliBitReaderSaveState(br, &memento);
+ if (!SafeReadSymbol(distance_tree, br, &code)) {
+ return BROTLI_FALSE;
+ }
+- s->distance_code = (int)code;
+ }
++ --s->block_length[2];
+ /* Convert the distance code to the actual distance by possibly
+- looking up past distances from the s->ringbuffer. */
++ looking up past distances from the s->dist_rb. */
+ s->distance_context = 0;
+- if ((s->distance_code & ~0xF) == 0) {
++ if ((code & ~0xFu) == 0) {
++ s->distance_code = (int)code;
+ TakeDistanceFromRingBuffer(s);
+- --s->block_length[2];
+ return BROTLI_TRUE;
+ }
+- distval = s->distance_code - (int)s->num_direct_distance_codes;
+- if (distval >= 0) {
+- uint32_t nbits;
+- int postfix;
+- int offset;
+- if (!safe && (s->distance_postfix_bits == 0)) {
+- nbits = ((uint32_t)distval >> 1) + 1;
+- offset = ((2 + (distval & 1)) << nbits) - 4;
+- s->distance_code = (int)s->num_direct_distance_codes + offset +
+- (int)BrotliReadBits(br, nbits);
+- } else {
+- /* This branch also works well when s->distance_postfix_bits == 0. */
+- uint32_t bits;
+- postfix = distval & s->distance_postfix_mask;
+- distval >>= s->distance_postfix_bits;
+- nbits = ((uint32_t)distval >> 1) + 1;
+- if (safe) {
+- if (!SafeReadBits(br, nbits, &bits)) {
+- s->distance_code = -1; /* Restore precondition. */
+- BrotliBitReaderRestoreState(br, &memento);
+- return BROTLI_FALSE;
+- }
+- } else {
+- bits = BrotliReadBits(br, nbits);
+- }
+- offset = ((2 + (distval & 1)) << nbits) - 4;
+- s->distance_code = (int)s->num_direct_distance_codes +
+- ((offset + (int)bits) << s->distance_postfix_bits) + postfix;
++ if (!safe) {
++ bits = BrotliReadBits32(br, b->dist_extra_bits[code]);
++ } else {
++ if (!SafeReadBits32(br, b->dist_extra_bits[code], &bits)) {
++ ++s->block_length[2];
++ BrotliBitReaderRestoreState(br, &memento);
++ return BROTLI_FALSE;
+ }
+ }
+- s->distance_code = s->distance_code - BROTLI_NUM_DISTANCE_SHORT_CODES + 1;
+- --s->block_length[2];
++ s->distance_code =
++ (int)(b->dist_offset[code] + (bits << s->distance_postfix_bits));
+ return BROTLI_TRUE;
+ }
+
+@@ -1588,9 +1681,9 @@ static BROTLI_INLINE BROTLI_BOOL ReadCommandInternal(
+ *insert_length = v.insert_len_offset;
+ if (!safe) {
+ if (BROTLI_PREDICT_FALSE(v.insert_len_extra_bits != 0)) {
+- insert_len_extra = BrotliReadBits(br, v.insert_len_extra_bits);
++ insert_len_extra = BrotliReadBits24(br, v.insert_len_extra_bits);
+ }
+- copy_length = BrotliReadBits(br, v.copy_len_extra_bits);
++ copy_length = BrotliReadBits24(br, v.copy_len_extra_bits);
+ } else {
+ if (!SafeReadBits(br, v.insert_len_extra_bits, &insert_len_extra) ||
+ !SafeReadBits(br, v.copy_len_extra_bits, ©_length)) {
+@@ -1935,21 +2028,6 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode SafeProcessCommands(
+ return ProcessCommandsInternal(1, s);
+ }
+
+-/* Returns the maximum number of distance symbols which can only represent
+- distances not exceeding BROTLI_MAX_ALLOWED_DISTANCE. */
+-static uint32_t BrotliMaxDistanceSymbol(uint32_t ndirect, uint32_t npostfix) {
+- static const uint32_t bound[BROTLI_MAX_NPOSTFIX + 1] = {0, 4, 12, 28};
+- static const uint32_t diff[BROTLI_MAX_NPOSTFIX + 1] = {73, 126, 228, 424};
+- uint32_t postfix = 1U << npostfix;
+- if (ndirect < bound[npostfix]) {
+- return ndirect + diff[npostfix] + postfix;
+- } else if (ndirect > bound[npostfix] + postfix) {
+- return ndirect + diff[npostfix];
+- } else {
+- return bound[npostfix] + diff[npostfix] + postfix;
+- }
+-}
+-
+ BrotliDecoderResult BrotliDecoderDecompress(
+ size_t encoded_size, const uint8_t* encoded_buffer, size_t* decoded_size,
+ uint8_t* decoded_buffer) {
+@@ -2167,33 +2245,23 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
+ s->state = BROTLI_STATE_UNCOMPRESSED;
+ break;
+ }
++ s->state = BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER;
++ /* Fall through. */
++
++ case BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER: {
++ BrotliMetablockHeaderArena* h = &s->arena.header;
+ s->loop_counter = 0;
++ /* Initialize compressed metablock header arena. */
++ h->sub_loop_counter = 0;
++ /* Make small negative indexes addressable. */
++ h->symbol_lists =
++ &h->symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1];
++ h->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
++ h->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE;
++ h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
+ s->state = BROTLI_STATE_HUFFMAN_CODE_0;
+- break;
+-
+- case BROTLI_STATE_UNCOMPRESSED: {
+- result = CopyUncompressedBlockToOutput(
+- available_out, next_out, total_out, s);
+- if (result != BROTLI_DECODER_SUCCESS) {
+- break;
+- }
+- s->state = BROTLI_STATE_METABLOCK_DONE;
+- break;
+ }
+-
+- case BROTLI_STATE_METADATA:
+- for (; s->meta_block_remaining_len > 0; --s->meta_block_remaining_len) {
+- uint32_t bits;
+- /* Read one byte and ignore it. */
+- if (!BrotliSafeReadBits(br, 8, &bits)) {
+- result = BROTLI_DECODER_NEEDS_MORE_INPUT;
+- break;
+- }
+- }
+- if (result == BROTLI_DECODER_SUCCESS) {
+- s->state = BROTLI_STATE_METABLOCK_DONE;
+- }
+- break;
++ /* Fall through. */
+
+ case BROTLI_STATE_HUFFMAN_CODE_0:
+ if (s->loop_counter >= 3) {
+@@ -2247,6 +2315,30 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
+ break;
+ }
+
++ case BROTLI_STATE_UNCOMPRESSED: {
++ result = CopyUncompressedBlockToOutput(
++ available_out, next_out, total_out, s);
++ if (result != BROTLI_DECODER_SUCCESS) {
++ break;
++ }
++ s->state = BROTLI_STATE_METABLOCK_DONE;
++ break;
++ }
++
++ case BROTLI_STATE_METADATA:
++ for (; s->meta_block_remaining_len > 0; --s->meta_block_remaining_len) {
++ uint32_t bits;
++ /* Read one byte and ignore it. */
++ if (!BrotliSafeReadBits(br, 8, &bits)) {
++ result = BROTLI_DECODER_NEEDS_MORE_INPUT;
++ break;
++ }
++ }
++ if (result == BROTLI_DECODER_SUCCESS) {
++ s->state = BROTLI_STATE_METABLOCK_DONE;
++ }
++ break;
++
+ case BROTLI_STATE_METABLOCK_HEADER_2: {
+ uint32_t bits;
+ if (!BrotliSafeReadBits(br, 6, &bits)) {
+@@ -2255,11 +2347,9 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
+ }
+ s->distance_postfix_bits = bits & BitMask(2);
+ bits >>= 2;
+- s->num_direct_distance_codes = BROTLI_NUM_DISTANCE_SHORT_CODES +
+- (bits << s->distance_postfix_bits);
++ s->num_direct_distance_codes = bits << s->distance_postfix_bits;
+ BROTLI_LOG_UINT(s->num_direct_distance_codes);
+ BROTLI_LOG_UINT(s->distance_postfix_bits);
+- s->distance_postfix_mask = (int)BitMask(s->distance_postfix_bits);
+ s->context_modes =
+ (uint8_t*)BROTLI_DECODER_ALLOC(s, (size_t)s->num_block_types[0]);
+ if (s->context_modes == 0) {
+@@ -2291,17 +2381,19 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
+ /* Fall through. */
+
+ case BROTLI_STATE_CONTEXT_MAP_2: {
+- uint32_t num_direct_codes =
+- s->num_direct_distance_codes - BROTLI_NUM_DISTANCE_SHORT_CODES;
+- uint32_t num_distance_codes = BROTLI_DISTANCE_ALPHABET_SIZE(
+- s->distance_postfix_bits, num_direct_codes,
+- (s->large_window ? BROTLI_LARGE_MAX_DISTANCE_BITS :
+- BROTLI_MAX_DISTANCE_BITS));
+- uint32_t max_distance_symbol = (s->large_window ?
+- BrotliMaxDistanceSymbol(
+- num_direct_codes, s->distance_postfix_bits) :
+- num_distance_codes);
++ uint32_t npostfix = s->distance_postfix_bits;
++ uint32_t ndirect = s->num_direct_distance_codes;
++ uint32_t distance_alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(
++ npostfix, ndirect, BROTLI_MAX_DISTANCE_BITS);
++ uint32_t distance_alphabet_size_limit = distance_alphabet_size_max;
+ BROTLI_BOOL allocation_success = BROTLI_TRUE;
++ if (s->large_window) {
++ BrotliDistanceCodeLimit limit = BrotliCalculateDistanceCodeLimit(
++ BROTLI_MAX_ALLOWED_DISTANCE, npostfix, ndirect);
++ distance_alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(
++ npostfix, ndirect, BROTLI_LARGE_MAX_DISTANCE_BITS);
++ distance_alphabet_size_limit = limit.max_alphabet_size;
++ }
+ result = DecodeContextMap(
+ s->num_block_types[2] << BROTLI_DISTANCE_CONTEXT_BITS,
+ &s->num_dist_htrees, &s->dist_context_map, s);
+@@ -2315,8 +2407,8 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
+ s, &s->insert_copy_hgroup, BROTLI_NUM_COMMAND_SYMBOLS,
+ BROTLI_NUM_COMMAND_SYMBOLS, s->num_block_types[1]);
+ allocation_success &= BrotliDecoderHuffmanTreeGroupInit(
+- s, &s->distance_hgroup, num_distance_codes,
+- max_distance_symbol, s->num_dist_htrees);
++ s, &s->distance_hgroup, distance_alphabet_size_max,
++ distance_alphabet_size_limit, s->num_dist_htrees);
+ if (!allocation_success) {
+ return SaveErrorCode(s,
+ BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS));
+@@ -2338,18 +2430,24 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
+ result = HuffmanTreeGroupDecode(hgroup, s);
+ if (result != BROTLI_DECODER_SUCCESS) break;
+ s->loop_counter++;
+- if (s->loop_counter >= 3) {
+- PrepareLiteralDecoding(s);
+- s->dist_context_map_slice = s->dist_context_map;
+- s->htree_command = s->insert_copy_hgroup.htrees[0];
+- if (!BrotliEnsureRingBuffer(s)) {
+- result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2);
+- break;
+- }
+- s->state = BROTLI_STATE_COMMAND_BEGIN;
++ if (s->loop_counter < 3) {
++ break;
+ }
+- break;
++ s->state = BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY;
+ }
++ /* Fall through. */
++
++ case BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY:
++ PrepareLiteralDecoding(s);
++ s->dist_context_map_slice = s->dist_context_map;
++ s->htree_command = s->insert_copy_hgroup.htrees[0];
++ if (!BrotliEnsureRingBuffer(s)) {
++ result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2);
++ break;
++ }
++ CalculateDistanceLut(s);
++ s->state = BROTLI_STATE_COMMAND_BEGIN;
++ /* Fall through. */
+
+ case BROTLI_STATE_COMMAND_BEGIN:
+ /* Fall through. */
+diff --git a/c/dec/huffman.h b/c/dec/huffman.h
+index b9f0716c..70e8469e 100644
+--- a/c/dec/huffman.h
++++ b/c/dec/huffman.h
+@@ -19,7 +19,8 @@ extern "C" {
+ #define BROTLI_HUFFMAN_MAX_CODE_LENGTH 15
+
+ /* Maximum possible Huffman table size for an alphabet size of (index * 32),
+- max code length 15 and root table bits 8. */
++ max code length 15 and root table bits 8. This table describes table sizes
++ for alphabets containing up to 1152 = 36 * 32 symbols. */
+ static const uint16_t kMaxHuffmanTableSize[] = {
+ 256, 402, 436, 468, 500, 534, 566, 598, 630, 662, 694, 726, 758, 790, 822,
+ 854, 886, 920, 952, 984, 1016, 1048, 1080, 1112, 1144, 1176, 1208, 1240, 1272,
+@@ -110,13 +111,13 @@ BROTLI_INTERNAL uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
+ int root_bits, uint16_t* symbols, uint32_t num_symbols);
+
+ /* Contains a collection of Huffman trees with the same alphabet size. */
+-/* max_symbol is needed due to simple codes since log2(alphabet_size) could be
+- greater than log2(max_symbol). */
++/* alphabet_size_limit is needed due to simple codes, since
++ log2(alphabet_size_max) could be greater than log2(alphabet_size_limit). */
+ typedef struct {
+ HuffmanCode** htrees;
+ HuffmanCode* codes;
+- uint16_t alphabet_size;
+- uint16_t max_symbol;
++ uint16_t alphabet_size_max;
++ uint16_t alphabet_size_limit;
+ uint16_t num_htrees;
+ } HuffmanTreeGroup;
+
+diff --git a/c/dec/state.c b/c/dec/state.c
+index e0b37c2d..6cf2476c 100644
+--- a/c/dec/state.c
++++ b/c/dec/state.c
+@@ -33,10 +33,7 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
+ s->state = BROTLI_STATE_UNINITED;
+ s->large_window = 0;
+ s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
+- s->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE;
+- s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
+ s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
+- s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
+ s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
+ s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
+
+@@ -59,8 +56,6 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
+ s->context_map_slice = NULL;
+ s->dist_context_map_slice = NULL;
+
+- s->sub_loop_counter = 0;
+-
+ s->literal_hgroup.codes = NULL;
+ s->literal_hgroup.htrees = NULL;
+ s->insert_copy_hgroup.codes = NULL;
+@@ -84,9 +79,6 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
+ s->block_type_trees = NULL;
+ s->block_len_trees = NULL;
+
+- /* Make small negative indexes addressable. */
+- s->symbol_lists = &s->symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1];
+-
+ s->mtf_upper_bound = 63;
+
+ s->dictionary = BrotliGetDictionary();
+@@ -142,17 +134,18 @@ void BrotliDecoderStateCleanup(BrotliDecoderState* s) {
+ }
+
+ BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState* s,
+- HuffmanTreeGroup* group, uint32_t alphabet_size, uint32_t max_symbol,
+- uint32_t ntrees) {
++ HuffmanTreeGroup* group, uint32_t alphabet_size_max,
++ uint32_t alphabet_size_limit, uint32_t ntrees) {
+ /* Pack two allocations into one */
+- const size_t max_table_size = kMaxHuffmanTableSize[(alphabet_size + 31) >> 5];
++ const size_t max_table_size =
++ kMaxHuffmanTableSize[(alphabet_size_limit + 31) >> 5];
+ const size_t code_size = sizeof(HuffmanCode) * ntrees * max_table_size;
+ const size_t htree_size = sizeof(HuffmanCode*) * ntrees;
+ /* Pointer alignment is, hopefully, wider than sizeof(HuffmanCode). */
+ HuffmanCode** p = (HuffmanCode**)BROTLI_DECODER_ALLOC(s,
+ code_size + htree_size);
+- group->alphabet_size = (uint16_t)alphabet_size;
+- group->max_symbol = (uint16_t)max_symbol;
++ group->alphabet_size_max = (uint16_t)alphabet_size_max;
++ group->alphabet_size_limit = (uint16_t)alphabet_size_limit;
+ group->num_htrees = (uint16_t)ntrees;
+ group->htrees = p;
+ group->codes = (HuffmanCode*)(&p[ntrees]);
+diff --git a/c/dec/state.h b/c/dec/state.h
+index d28b6392..54dab698 100644
+--- a/c/dec/state.h
++++ b/c/dec/state.h
+@@ -21,6 +21,95 @@
+ extern "C" {
+ #endif
+
++/* Graphviz diagram that describes state transitions:
++
++digraph States {
++ graph [compound=true]
++ concentrate=true
++ node [shape="box"]
++
++ UNINITED -> {LARGE_WINDOW_BITS -> INITIALIZE}
++ subgraph cluster_metablock_workflow {
++ style="rounded"
++ label=< METABLOCK CYCLE >
++ METABLOCK_BEGIN -> METABLOCK_HEADER
++ METABLOCK_HEADER:sw -> METADATA
++ METABLOCK_HEADER:s -> UNCOMPRESSED
++ METABLOCK_HEADER:se -> METABLOCK_DONE:ne
++ METADATA:s -> METABLOCK_DONE:w
++ UNCOMPRESSED:s -> METABLOCK_DONE:n
++ METABLOCK_DONE:e -> METABLOCK_BEGIN:e [constraint="false"]
++ }
++ INITIALIZE -> METABLOCK_BEGIN
++ METABLOCK_DONE -> DONE
++
++ subgraph cluster_compressed_metablock {
++ style="rounded"
++ label=< COMPRESSED METABLOCK >
++
++ subgraph cluster_command {
++ style="rounded"
++ label=< HOT LOOP >
++
++ _METABLOCK_DONE_PORT_ [shape=point style=invis]
++
++ {
++ // Set different shape for nodes returning from "compressed metablock".
++ node [shape=invhouse]; CMD_INNER CMD_POST_DECODE_LITERALS;
++ CMD_POST_WRAP_COPY; CMD_INNER_WRITE; CMD_POST_WRITE_1;
++ }
++
++ CMD_BEGIN -> CMD_INNER -> CMD_POST_DECODE_LITERALS -> CMD_POST_WRAP_COPY
++
++ // IO ("write") nodes are not in the hot loop!
++ CMD_INNER_WRITE [style=dashed]
++ CMD_INNER -> CMD_INNER_WRITE
++ CMD_POST_WRITE_1 [style=dashed]
++ CMD_POST_DECODE_LITERALS -> CMD_POST_WRITE_1
++ CMD_POST_WRITE_2 [style=dashed]
++ CMD_POST_WRAP_COPY -> CMD_POST_WRITE_2
++
++ CMD_POST_WRITE_1 -> CMD_BEGIN:s [constraint="false"]
++ CMD_INNER_WRITE -> {CMD_INNER CMD_POST_DECODE_LITERALS}
++ [constraint="false"]
++ CMD_BEGIN:ne -> CMD_POST_DECODE_LITERALS [constraint="false"]
++ CMD_POST_WRAP_COPY -> CMD_BEGIN [constraint="false"]
++ CMD_POST_DECODE_LITERALS -> CMD_BEGIN:ne [constraint="false"]
++ CMD_POST_WRITE_2 -> CMD_POST_WRAP_COPY [constraint="false"]
++ {rank=same; CMD_BEGIN; CMD_INNER; CMD_POST_DECODE_LITERALS;
++ CMD_POST_WRAP_COPY}
++ {rank=same; CMD_INNER_WRITE; CMD_POST_WRITE_1; CMD_POST_WRITE_2}
++
++ {CMD_INNER CMD_POST_DECODE_LITERALS CMD_POST_WRAP_COPY} ->
++ _METABLOCK_DONE_PORT_ [style=invis]
++ {CMD_INNER_WRITE CMD_POST_WRITE_1} -> _METABLOCK_DONE_PORT_
++ [constraint="false" style=invis]
++ }
++
++ BEFORE_COMPRESSED_METABLOCK_HEADER:s -> HUFFMAN_CODE_0:n
++ HUFFMAN_CODE_0 -> HUFFMAN_CODE_1 -> HUFFMAN_CODE_2 -> HUFFMAN_CODE_3
++ HUFFMAN_CODE_0 -> METABLOCK_HEADER_2 -> CONTEXT_MODES -> CONTEXT_MAP_1
++ CONTEXT_MAP_1 -> CONTEXT_MAP_2 -> TREE_GROUP
++ TREE_GROUP -> BEFORE_COMPRESSED_METABLOCK_BODY:e
++ BEFORE_COMPRESSED_METABLOCK_BODY:s -> CMD_BEGIN:n
++
++ HUFFMAN_CODE_3:e -> HUFFMAN_CODE_0:ne [constraint="false"]
++ {rank=same; HUFFMAN_CODE_0; HUFFMAN_CODE_1; HUFFMAN_CODE_2; HUFFMAN_CODE_3}
++ {rank=same; METABLOCK_HEADER_2; CONTEXT_MODES; CONTEXT_MAP_1; CONTEXT_MAP_2;
++ TREE_GROUP}
++ }
++ METABLOCK_HEADER:e -> BEFORE_COMPRESSED_METABLOCK_HEADER:n
++
++ _METABLOCK_DONE_PORT_ -> METABLOCK_DONE:se
++ [constraint="false" ltail=cluster_command]
++
++ UNINITED [shape=Mdiamond];
++ DONE [shape=Msquare];
++}
++
++
++ */
++
+ typedef enum {
+ BROTLI_STATE_UNINITED,
+ BROTLI_STATE_LARGE_WINDOW_BITS,
+@@ -39,6 +128,7 @@ typedef enum {
+ BROTLI_STATE_METABLOCK_DONE,
+ BROTLI_STATE_COMMAND_POST_WRITE_1,
+ BROTLI_STATE_COMMAND_POST_WRITE_2,
++ BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER,
+ BROTLI_STATE_HUFFMAN_CODE_0,
+ BROTLI_STATE_HUFFMAN_CODE_1,
+ BROTLI_STATE_HUFFMAN_CODE_2,
+@@ -46,6 +136,7 @@ typedef enum {
+ BROTLI_STATE_CONTEXT_MAP_1,
+ BROTLI_STATE_CONTEXT_MAP_2,
+ BROTLI_STATE_TREE_GROUP,
++ BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY,
+ BROTLI_STATE_DONE
+ } BrotliRunningState;
+
+@@ -98,6 +189,50 @@ typedef enum {
+ BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX
+ } BrotliRunningReadBlockLengthState;
+
++typedef struct BrotliMetablockHeaderArena {
++ BrotliRunningTreeGroupState substate_tree_group;
++ BrotliRunningContextMapState substate_context_map;
++ BrotliRunningHuffmanState substate_huffman;
++
++ uint32_t sub_loop_counter;
++
++ uint32_t repeat_code_len;
++ uint32_t prev_code_len;
++
++ /* For ReadHuffmanCode. */
++ uint32_t symbol;
++ uint32_t repeat;
++ uint32_t space;
++
++ /* Huffman table for "histograms". */
++ HuffmanCode table[32];
++ /* List of heads of symbol chains. */
++ uint16_t* symbol_lists;
++ /* Storage from symbol_lists. */
++ uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
++ BROTLI_NUM_COMMAND_SYMBOLS];
++ /* Tails of symbol chains. */
++ int next_symbol[32];
++ uint8_t code_length_code_lengths[BROTLI_CODE_LENGTH_CODES];
++ /* Population counts for the code lengths. */
++ uint16_t code_length_histo[16];
++
++ /* For HuffmanTreeGroupDecode. */
++ int htree_index;
++ HuffmanCode* next;
++
++ /* For DecodeContextMap. */
++ uint32_t context_index;
++ uint32_t max_run_length_prefix;
++ uint32_t code;
++ HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272];
++} BrotliMetablockHeaderArena;
++
++typedef struct BrotliMetablockBodyArena {
++ uint8_t dist_extra_bits[544];
++ uint32_t dist_offset[544];
++} BrotliMetablockBodyArena;
++
+ struct BrotliDecoderStateStruct {
+ BrotliRunningState state;
+
+@@ -110,7 +245,8 @@ struct BrotliDecoderStateStruct {
+ brotli_free_func free_func;
+ void* memory_manager_opaque;
+
+- /* Temporary storage for remaining input. */
++ /* Temporary storage for remaining input. Brotli stream format is designed in
++ a way, that 64 bits are enough to make progress in decoding. */
+ union {
+ uint64_t u64;
+ uint8_t u8[8];
+@@ -125,7 +261,6 @@ struct BrotliDecoderStateStruct {
+ int dist_rb_idx;
+ int dist_rb[4];
+ int error_code;
+- uint32_t sub_loop_counter;
+ uint8_t* ringbuffer;
+ uint8_t* ringbuffer_end;
+ HuffmanCode* htree_command;
+@@ -153,13 +288,10 @@ struct BrotliDecoderStateStruct {
+ uint32_t block_type_rb[6];
+ uint32_t distance_postfix_bits;
+ uint32_t num_direct_distance_codes;
+- int distance_postfix_mask;
+ uint32_t num_dist_htrees;
+ uint8_t* dist_context_map;
+ HuffmanCode* literal_htree;
+ uint8_t dist_htree_index;
+- uint32_t repeat_code_len;
+- uint32_t prev_code_len;
+
+ int copy_length;
+ int distance_code;
+@@ -168,33 +300,6 @@ struct BrotliDecoderStateStruct {
+ size_t rb_roundtrips; /* how many times we went around the ring-buffer */
+ size_t partial_pos_out; /* how much output to the user in total */
+
+- /* For ReadHuffmanCode. */
+- uint32_t symbol;
+- uint32_t repeat;
+- uint32_t space;
+-
+- HuffmanCode table[32];
+- /* List of heads of symbol chains. */
+- uint16_t* symbol_lists;
+- /* Storage from symbol_lists. */
+- uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
+- BROTLI_NUM_COMMAND_SYMBOLS];
+- /* Tails of symbol chains. */
+- int next_symbol[32];
+- uint8_t code_length_code_lengths[BROTLI_CODE_LENGTH_CODES];
+- /* Population counts for the code lengths. */
+- uint16_t code_length_histo[16];
+-
+- /* For HuffmanTreeGroupDecode. */
+- int htree_index;
+- HuffmanCode* next;
+-
+- /* For DecodeContextMap. */
+- uint32_t context_index;
+- uint32_t max_run_length_prefix;
+- uint32_t code;
+- HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272];
+-
+ /* For InverseMoveToFrontTransform. */
+ uint32_t mtf_upper_bound;
+ uint32_t mtf[64 + 1];
+@@ -203,10 +308,7 @@ struct BrotliDecoderStateStruct {
+
+ /* States inside function calls. */
+ BrotliRunningMetablockHeaderState substate_metablock_header;
+- BrotliRunningTreeGroupState substate_tree_group;
+- BrotliRunningContextMapState substate_context_map;
+ BrotliRunningUncompressedState substate_uncompressed;
+- BrotliRunningHuffmanState substate_huffman;
+ BrotliRunningDecodeUint8State substate_decode_uint8;
+ BrotliRunningReadBlockLengthState substate_read_block_length;
+
+@@ -229,6 +331,11 @@ struct BrotliDecoderStateStruct {
+ const BrotliTransforms* transforms;
+
+ uint32_t trivial_literal_contexts[8]; /* 256 bits */
++
++ union {
++ BrotliMetablockHeaderArena header;
++ BrotliMetablockBodyArena body;
++ } arena;
+ };
+
+ typedef struct BrotliDecoderStateStruct BrotliDecoderStateInternal;
+@@ -241,8 +348,8 @@ BROTLI_INTERNAL void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s);
+ BROTLI_INTERNAL void BrotliDecoderStateCleanupAfterMetablock(
+ BrotliDecoderState* s);
+ BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(
+- BrotliDecoderState* s, HuffmanTreeGroup* group, uint32_t alphabet_size,
+- uint32_t max_symbol, uint32_t ntrees);
++ BrotliDecoderState* s, HuffmanTreeGroup* group, uint32_t alphabet_size_max,
++ uint32_t alphabet_size_limit, uint32_t ntrees);
+
+ #define BROTLI_DECODER_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L)
+
+diff --git a/c/enc/backward_references.c b/c/enc/backward_references.c
+index cd023d9b..a07a617a 100644
+--- a/c/enc/backward_references.c
++++ b/c/enc/backward_references.c
+@@ -9,6 +9,7 @@
+ #include "./backward_references.h"
+
+ #include "../common/constants.h"
++#include "../common/context.h"
+ #include "../common/dictionary.h"
+ #include "../common/platform.h"
+ #include
+@@ -119,17 +120,17 @@ static BROTLI_INLINE size_t ComputeDistanceCode(size_t distance,
+ #undef CAT
+ #undef EXPAND_CAT
+
+-void BrotliCreateBackwardReferences(
+- size_t num_bytes, size_t position, const uint8_t* ringbuffer,
+- size_t ringbuffer_mask, const BrotliEncoderParams* params,
+- HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
++void BrotliCreateBackwardReferences(size_t num_bytes,
++ size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
++ ContextLut literal_context_lut, const BrotliEncoderParams* params,
++ Hasher* hasher, int* dist_cache, size_t* last_insert_len,
+ Command* commands, size_t* num_commands, size_t* num_literals) {
+ switch (params->hasher.type) {
+ #define CASE_(N) \
+ case N: \
+- CreateBackwardReferencesNH ## N( \
+- num_bytes, position, ringbuffer, \
+- ringbuffer_mask, params, hasher, dist_cache, \
++ CreateBackwardReferencesNH ## N(num_bytes, \
++ position, ringbuffer, ringbuffer_mask, \
++ literal_context_lut, params, hasher, dist_cache, \
+ last_insert_len, commands, num_commands, num_literals); \
+ return;
+ FOR_GENERIC_HASHERS(CASE_)
+diff --git a/c/enc/backward_references.h b/c/enc/backward_references.h
+index f82a80da..9589cc15 100644
+--- a/c/enc/backward_references.h
++++ b/c/enc/backward_references.h
+@@ -10,6 +10,7 @@
+ #define BROTLI_ENC_BACKWARD_REFERENCES_H_
+
+ #include "../common/constants.h"
++#include "../common/context.h"
+ #include "../common/dictionary.h"
+ #include "../common/platform.h"
+ #include
+@@ -27,8 +28,8 @@ extern "C" {
+ by this call. */
+ BROTLI_INTERNAL void BrotliCreateBackwardReferences(size_t num_bytes,
+ size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
+- const BrotliEncoderParams* params,
+- HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
++ ContextLut literal_context_lut, const BrotliEncoderParams* params,
++ Hasher* hasher, int* dist_cache, size_t* last_insert_len,
+ Command* commands, size_t* num_commands, size_t* num_literals);
+
+ #if defined(__cplusplus) || defined(c_plusplus)
+diff --git a/c/enc/backward_references_hq.c b/c/enc/backward_references_hq.c
+index 5737f752..cd6bb708 100644
+--- a/c/enc/backward_references_hq.c
++++ b/c/enc/backward_references_hq.c
+@@ -11,6 +11,7 @@
+ #include /* memcpy, memset */
+
+ #include "../common/constants.h"
++#include "../common/context.h"
+ #include "../common/platform.h"
+ #include
+ #include "./command.h"
+@@ -26,6 +27,7 @@
+ extern "C" {
+ #endif
+
++/* BrotliCalculateDistanceCodeLimit(BROTLI_MAX_ALLOWED_DISTANCE, 3, 120). */
+ #define BROTLI_MAX_EFFECTIVE_DISTANCE_ALPHABET_SIZE 544
+
+ static const float kInfinity = 1.7e38f; /* ~= 2 ^ 127 */
+@@ -86,14 +88,10 @@ typedef struct ZopfliCostModel {
+ static void InitZopfliCostModel(
+ MemoryManager* m, ZopfliCostModel* self, const BrotliDistanceParams* dist,
+ size_t num_bytes) {
+- uint32_t distance_histogram_size = dist->alphabet_size;
+- if (distance_histogram_size > BROTLI_MAX_EFFECTIVE_DISTANCE_ALPHABET_SIZE) {
+- distance_histogram_size = BROTLI_MAX_EFFECTIVE_DISTANCE_ALPHABET_SIZE;
+- }
+ self->num_bytes_ = num_bytes;
+ self->literal_costs_ = BROTLI_ALLOC(m, float, num_bytes + 2);
+- self->cost_dist_ = BROTLI_ALLOC(m, float, dist->alphabet_size);
+- self->distance_histogram_size = distance_histogram_size;
++ self->cost_dist_ = BROTLI_ALLOC(m, float, dist->alphabet_size_limit);
++ self->distance_histogram_size = dist->alphabet_size_limit;
+ if (BROTLI_IS_OOM(m)) return;
+ }
+
+@@ -408,9 +406,12 @@ static size_t UpdateNodes(
+ const int* starting_dist_cache, const size_t num_matches,
+ const BackwardMatch* matches, const ZopfliCostModel* model,
+ StartPosQueue* queue, ZopfliNode* nodes) {
++ const size_t stream_offset = params->stream_offset;
+ const size_t cur_ix = block_start + pos;
+ const size_t cur_ix_masked = cur_ix & ringbuffer_mask;
+ const size_t max_distance = BROTLI_MIN(size_t, cur_ix, max_backward_limit);
++ const size_t dictionary_start = BROTLI_MIN(size_t,
++ cur_ix + stream_offset, max_backward_limit);
+ const size_t max_len = num_bytes - pos;
+ const size_t max_zopfli_len = MaxZopfliLen(params);
+ const size_t max_iters = MaxZopfliCandidates(params);
+@@ -419,7 +420,7 @@ static size_t UpdateNodes(
+ size_t k;
+ size_t gap = 0;
+
+- EvaluateNode(block_start, pos, max_backward_limit, gap,
++ EvaluateNode(block_start + stream_offset, pos, max_backward_limit, gap,
+ starting_dist_cache, model, queue, nodes);
+
+ {
+@@ -453,7 +454,7 @@ static size_t UpdateNodes(
+ if (cur_ix_masked + best_len > ringbuffer_mask) {
+ break;
+ }
+- if (BROTLI_PREDICT_FALSE(backward > max_distance + gap)) {
++ if (BROTLI_PREDICT_FALSE(backward > dictionary_start + gap)) {
+ /* Word dictionary -> ignore. */
+ continue;
+ }
+@@ -472,6 +473,8 @@ static size_t UpdateNodes(
+ &ringbuffer[cur_ix_masked],
+ max_len);
+ } else {
++ /* "Gray" area. It is addressable by decoder, but this encoder
++ instance does not have that data -> should not touch it. */
+ continue;
+ }
+ {
+@@ -506,7 +509,7 @@ static size_t UpdateNodes(
+ BackwardMatch match = matches[j];
+ size_t dist = match.distance;
+ BROTLI_BOOL is_dictionary_match =
+- TO_BROTLI_BOOL(dist > max_distance + gap);
++ TO_BROTLI_BOOL(dist > dictionary_start + gap);
+ /* We already tried all possible last distance matches, so we can use
+ normal distance code here. */
+ size_t dist_code = dist + BROTLI_NUM_DISTANCE_SHORT_CODES - 1;
+@@ -569,6 +572,7 @@ void BrotliZopfliCreateCommands(const size_t num_bytes,
+ const size_t block_start, const ZopfliNode* nodes, int* dist_cache,
+ size_t* last_insert_len, const BrotliEncoderParams* params,
+ Command* commands, size_t* num_literals) {
++ const size_t stream_offset = params->stream_offset;
+ const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
+ size_t pos = 0;
+ uint32_t offset = nodes[0].u.next;
+@@ -587,10 +591,10 @@ void BrotliZopfliCreateCommands(const size_t num_bytes,
+ {
+ size_t distance = ZopfliNodeCopyDistance(next);
+ size_t len_code = ZopfliNodeLengthCode(next);
+- size_t max_distance = BROTLI_MIN(size_t,
+- block_start + pos, max_backward_limit);
++ size_t dictionary_start = BROTLI_MIN(size_t,
++ block_start + pos + stream_offset, max_backward_limit);
+ BROTLI_BOOL is_dictionary =
+- TO_BROTLI_BOOL(distance > max_distance + gap);
++ TO_BROTLI_BOOL(distance > dictionary_start + gap);
+ size_t dist_code = ZopfliNodeDistanceCode(next);
+ InitCommand(&commands[i], ¶ms->dist, insert_length,
+ copy_length, (int)len_code - (int)copy_length, dist_code);
+@@ -614,6 +618,7 @@ static size_t ZopfliIterate(size_t num_bytes, size_t position,
+ const BrotliEncoderParams* params, const size_t gap, const int* dist_cache,
+ const ZopfliCostModel* model, const uint32_t* num_matches,
+ const BackwardMatch* matches, ZopfliNode* nodes) {
++ const size_t stream_offset = params->stream_offset;
+ const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
+ const size_t max_zopfli_len = MaxZopfliLen(params);
+ StartPosQueue queue;
+@@ -638,7 +643,7 @@ static size_t ZopfliIterate(size_t num_bytes, size_t position,
+ while (skip) {
+ i++;
+ if (i + 3 >= num_bytes) break;
+- EvaluateNode(position, i, max_backward_limit, gap,
++ EvaluateNode(position + stream_offset, i, max_backward_limit, gap,
+ dist_cache, model, &queue, nodes);
+ cur_match_pos += num_matches[i];
+ skip--;
+@@ -651,8 +656,9 @@ static size_t ZopfliIterate(size_t num_bytes, size_t position,
+ /* REQUIRES: nodes != NULL and len(nodes) >= num_bytes + 1 */
+ size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes,
+ size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
+- const BrotliEncoderParams* params,
+- const int* dist_cache, HasherHandle hasher, ZopfliNode* nodes) {
++ ContextLut literal_context_lut, const BrotliEncoderParams* params,
++ const int* dist_cache, Hasher* hasher, ZopfliNode* nodes) {
++ const size_t stream_offset = params->stream_offset;
+ const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
+ const size_t max_zopfli_len = MaxZopfliLen(params);
+ ZopfliCostModel model;
+@@ -663,6 +669,7 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes,
+ size_t i;
+ size_t gap = 0;
+ size_t lz_matches_offset = 0;
++ BROTLI_UNUSED(literal_context_lut);
+ nodes[0].length = 0;
+ nodes[0].u.cost = 0;
+ InitZopfliCostModel(m, &model, ¶ms->dist, num_bytes);
+@@ -673,12 +680,14 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes,
+ for (i = 0; i + HashTypeLengthH10() - 1 < num_bytes; i++) {
+ const size_t pos = position + i;
+ const size_t max_distance = BROTLI_MIN(size_t, pos, max_backward_limit);
++ const size_t dictionary_start = BROTLI_MIN(size_t,
++ pos + stream_offset, max_backward_limit);
+ size_t skip;
+ size_t num_matches;
+- num_matches = FindAllMatchesH10(hasher,
++ num_matches = FindAllMatchesH10(&hasher->privat._H10,
+ ¶ms->dictionary,
+ ringbuffer, ringbuffer_mask, pos, num_bytes - i, max_distance,
+- gap, params, &matches[lz_matches_offset]);
++ dictionary_start + gap, params, &matches[lz_matches_offset]);
+ if (num_matches > 0 &&
+ BackwardMatchLength(&matches[num_matches - 1]) > max_zopfli_len) {
+ matches[0] = matches[num_matches - 1];
+@@ -693,13 +702,14 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes,
+ }
+ if (skip > 1) {
+ /* Add the tail of the copy to the hasher. */
+- StoreRangeH10(hasher, ringbuffer, ringbuffer_mask, pos + 1, BROTLI_MIN(
++ StoreRangeH10(&hasher->privat._H10,
++ ringbuffer, ringbuffer_mask, pos + 1, BROTLI_MIN(
+ size_t, pos + skip, store_end));
+ skip--;
+ while (skip) {
+ i++;
+ if (i + HashTypeLengthH10() - 1 >= num_bytes) break;
+- EvaluateNode(position, i, max_backward_limit, gap,
++ EvaluateNode(position + stream_offset, i, max_backward_limit, gap,
+ dist_cache, &model, &queue, nodes);
+ skip--;
+ }
+@@ -711,15 +721,15 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes,
+
+ void BrotliCreateZopfliBackwardReferences(MemoryManager* m, size_t num_bytes,
+ size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
+- const BrotliEncoderParams* params,
+- HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
++ ContextLut literal_context_lut, const BrotliEncoderParams* params,
++ Hasher* hasher, int* dist_cache, size_t* last_insert_len,
+ Command* commands, size_t* num_commands, size_t* num_literals) {
+ ZopfliNode* nodes;
+ nodes = BROTLI_ALLOC(m, ZopfliNode, num_bytes + 1);
+ if (BROTLI_IS_OOM(m)) return;
+ BrotliInitZopfliNodes(nodes, num_bytes + 1);
+ *num_commands += BrotliZopfliComputeShortestPath(m, num_bytes,
+- position, ringbuffer, ringbuffer_mask, params,
++ position, ringbuffer, ringbuffer_mask, literal_context_lut, params,
+ dist_cache, hasher, nodes);
+ if (BROTLI_IS_OOM(m)) return;
+ BrotliZopfliCreateCommands(num_bytes, position, nodes, dist_cache,
+@@ -729,9 +739,10 @@ void BrotliCreateZopfliBackwardReferences(MemoryManager* m, size_t num_bytes,
+
+ void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, size_t num_bytes,
+ size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
+- const BrotliEncoderParams* params,
+- HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
++ ContextLut literal_context_lut, const BrotliEncoderParams* params,
++ Hasher* hasher, int* dist_cache, size_t* last_insert_len,
+ Command* commands, size_t* num_commands, size_t* num_literals) {
++ const size_t stream_offset = params->stream_offset;
+ const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
+ uint32_t* num_matches = BROTLI_ALLOC(m, uint32_t, num_bytes);
+ size_t matches_size = 4 * num_bytes;
+@@ -746,12 +757,15 @@ void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, size_t num_bytes,
+ ZopfliCostModel model;
+ ZopfliNode* nodes;
+ BackwardMatch* matches = BROTLI_ALLOC(m, BackwardMatch, matches_size);
++ BROTLI_UNUSED(literal_context_lut);
+ size_t gap = 0;
+ size_t shadow_matches = 0;
+ if (BROTLI_IS_OOM(m)) return;
+ for (i = 0; i + HashTypeLengthH10() - 1 < num_bytes; ++i) {
+ const size_t pos = position + i;
+ size_t max_distance = BROTLI_MIN(size_t, pos, max_backward_limit);
++ size_t dictionary_start = BROTLI_MIN(size_t,
++ pos + stream_offset, max_backward_limit);
+ size_t max_length = num_bytes - i;
+ size_t num_found_matches;
+ size_t cur_match_end;
+@@ -760,10 +774,10 @@ void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, size_t num_bytes,
+ BROTLI_ENSURE_CAPACITY(m, BackwardMatch, matches, matches_size,
+ cur_match_pos + MAX_NUM_MATCHES_H10 + shadow_matches);
+ if (BROTLI_IS_OOM(m)) return;
+- num_found_matches = FindAllMatchesH10(hasher,
++ num_found_matches = FindAllMatchesH10(&hasher->privat._H10,
+ ¶ms->dictionary,
+ ringbuffer, ringbuffer_mask, pos, max_length,
+- max_distance, gap, params,
++ max_distance, dictionary_start + gap, params,
+ &matches[cur_match_pos + shadow_matches]);
+ cur_match_end = cur_match_pos + num_found_matches;
+ for (j = cur_match_pos; j + 1 < cur_match_end; ++j) {
+@@ -778,7 +792,8 @@ void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, size_t num_bytes,
+ matches[cur_match_pos++] = matches[cur_match_end - 1];
+ num_matches[i] = 1;
+ /* Add the tail of the copy to the hasher. */
+- StoreRangeH10(hasher, ringbuffer, ringbuffer_mask, pos + 1,
++ StoreRangeH10(&hasher->privat._H10,
++ ringbuffer, ringbuffer_mask, pos + 1,
+ BROTLI_MIN(size_t, pos + match_len, store_end));
+ memset(&num_matches[i + 1], 0, skip * sizeof(num_matches[0]));
+ i += skip;
+diff --git a/c/enc/backward_references_hq.h b/c/enc/backward_references_hq.h
+index fb1ff3fa..36b75f25 100644
+--- a/c/enc/backward_references_hq.h
++++ b/c/enc/backward_references_hq.h
+@@ -10,6 +10,7 @@
+ #define BROTLI_ENC_BACKWARD_REFERENCES_HQ_H_
+
+ #include "../common/constants.h"
++#include "../common/context.h"
+ #include "../common/dictionary.h"
+ #include "../common/platform.h"
+ #include
+@@ -25,15 +26,15 @@ extern "C" {
+ BROTLI_INTERNAL void BrotliCreateZopfliBackwardReferences(MemoryManager* m,
+ size_t num_bytes,
+ size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
+- const BrotliEncoderParams* params,
+- HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
++ ContextLut literal_context_lut, const BrotliEncoderParams* params,
++ Hasher* hasher, int* dist_cache, size_t* last_insert_len,
+ Command* commands, size_t* num_commands, size_t* num_literals);
+
+ BROTLI_INTERNAL void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m,
+ size_t num_bytes,
+ size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
+- const BrotliEncoderParams* params,
+- HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
++ ContextLut literal_context_lut, const BrotliEncoderParams* params,
++ Hasher* hasher, int* dist_cache, size_t* last_insert_len,
+ Command* commands, size_t* num_commands, size_t* num_literals);
+
+ typedef struct ZopfliNode {
+@@ -79,8 +80,8 @@ BROTLI_INTERNAL void BrotliInitZopfliNodes(ZopfliNode* array, size_t length);
+ BROTLI_INTERNAL size_t BrotliZopfliComputeShortestPath(
+ MemoryManager* m, size_t num_bytes,
+ size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
+- const BrotliEncoderParams* params,
+- const int* dist_cache, HasherHandle hasher, ZopfliNode* nodes);
++ ContextLut literal_context_lut, const BrotliEncoderParams* params,
++ const int* dist_cache, Hasher* hasher, ZopfliNode* nodes);
+
+ BROTLI_INTERNAL void BrotliZopfliCreateCommands(
+ const size_t num_bytes, const size_t block_start, const ZopfliNode* nodes,
+diff --git a/c/enc/backward_references_inc.h b/c/enc/backward_references_inc.h
+index e29daf33..766bf91f 100644
+--- a/c/enc/backward_references_inc.h
++++ b/c/enc/backward_references_inc.h
+@@ -10,11 +10,13 @@
+ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
+ size_t num_bytes, size_t position,
+ const uint8_t* ringbuffer, size_t ringbuffer_mask,
+- const BrotliEncoderParams* params,
+- HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
++ ContextLut literal_context_lut, const BrotliEncoderParams* params,
++ Hasher* hasher, int* dist_cache, size_t* last_insert_len,
+ Command* commands, size_t* num_commands, size_t* num_literals) {
++ HASHER()* privat = &hasher->privat.FN(_);
+ /* Set maximum distance, see section 9.1. of the spec. */
+ const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
++ const size_t position_offset = params->stream_offset;
+
+ const Command* const orig_commands = commands;
+ size_t insert_length = *last_insert_len;
+@@ -31,19 +33,23 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
+ /* Minimum score to accept a backward reference. */
+ const score_t kMinScore = BROTLI_SCORE_BASE + 100;
+
+- FN(PrepareDistanceCache)(hasher, dist_cache);
++ BROTLI_UNUSED(literal_context_lut);
++
++ FN(PrepareDistanceCache)(privat, dist_cache);
+
+ while (position + FN(HashTypeLength)() < pos_end) {
+ size_t max_length = pos_end - position;
+ size_t max_distance = BROTLI_MIN(size_t, position, max_backward_limit);
++ size_t dictionary_start = BROTLI_MIN(size_t,
++ position + position_offset, max_backward_limit);
+ HasherSearchResult sr;
+ sr.len = 0;
+ sr.len_code_delta = 0;
+ sr.distance = 0;
+ sr.score = kMinScore;
+- FN(FindLongestMatch)(hasher, ¶ms->dictionary,
++ FN(FindLongestMatch)(privat, ¶ms->dictionary,
+ ringbuffer, ringbuffer_mask, dist_cache, position, max_length,
+- max_distance, gap, params->dist.max_distance, &sr);
++ max_distance, dictionary_start + gap, params->dist.max_distance, &sr);
+ if (sr.score > kMinScore) {
+ /* Found a match. Let's look for something even better ahead. */
+ int delayed_backward_references_in_row = 0;
+@@ -57,10 +63,12 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
+ sr2.distance = 0;
+ sr2.score = kMinScore;
+ max_distance = BROTLI_MIN(size_t, position + 1, max_backward_limit);
+- FN(FindLongestMatch)(hasher,
++ dictionary_start = BROTLI_MIN(size_t,
++ position + 1 + position_offset, max_backward_limit);
++ FN(FindLongestMatch)(privat,
+ ¶ms->dictionary,
+ ringbuffer, ringbuffer_mask, dist_cache, position + 1, max_length,
+- max_distance, gap, params->dist.max_distance,
++ max_distance, dictionary_start + gap, params->dist.max_distance,
+ &sr2);
+ if (sr2.score >= sr.score + cost_diff_lazy) {
+ /* Ok, let's just write one byte for now and start a match from the
+@@ -77,19 +85,19 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
+ }
+ apply_random_heuristics =
+ position + 2 * sr.len + random_heuristics_window_size;
+- max_distance = BROTLI_MIN(size_t,
+- position, max_backward_limit);
++ dictionary_start = BROTLI_MIN(size_t,
++ position + position_offset, max_backward_limit);
+ {
+ /* The first 16 codes are special short-codes,
+ and the minimum offset is 1. */
+ size_t distance_code = ComputeDistanceCode(
+- sr.distance, max_distance + gap, dist_cache);
+- if ((sr.distance <= (max_distance + gap)) && distance_code > 0) {
++ sr.distance, dictionary_start + gap, dist_cache);
++ if ((sr.distance <= (dictionary_start + gap)) && distance_code > 0) {
+ dist_cache[3] = dist_cache[2];
+ dist_cache[2] = dist_cache[1];
+ dist_cache[1] = dist_cache[0];
+ dist_cache[0] = (int)sr.distance;
+- FN(PrepareDistanceCache)(hasher, dist_cache);
++ FN(PrepareDistanceCache)(privat, dist_cache);
+ }
+ InitCommand(commands++, ¶ms->dist, insert_length,
+ sr.len, sr.len_code_delta, distance_code);
+@@ -107,7 +115,7 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
+ range_start = BROTLI_MIN(size_t, range_end, BROTLI_MAX(size_t,
+ range_start, position + sr.len - (sr.distance << 2)));
+ }
+- FN(StoreRange)(hasher, ringbuffer, ringbuffer_mask, range_start,
++ FN(StoreRange)(privat, ringbuffer, ringbuffer_mask, range_start,
+ range_end);
+ }
+ position += sr.len;
+@@ -133,7 +141,7 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
+ size_t pos_jump =
+ BROTLI_MIN(size_t, position + 16, pos_end - kMargin);
+ for (; position < pos_jump; position += 4) {
+- FN(Store)(hasher, ringbuffer, ringbuffer_mask, position);
++ FN(Store)(privat, ringbuffer, ringbuffer_mask, position);
+ insert_length += 4;
+ }
+ } else {
+@@ -142,7 +150,7 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
+ size_t pos_jump =
+ BROTLI_MIN(size_t, position + 8, pos_end - kMargin);
+ for (; position < pos_jump; position += 2) {
+- FN(Store)(hasher, ringbuffer, ringbuffer_mask, position);
++ FN(Store)(privat, ringbuffer, ringbuffer_mask, position);
+ insert_length += 2;
+ }
+ }
+diff --git a/c/enc/brotli_bit_stream.c b/c/enc/brotli_bit_stream.c
+index aaf2dad7..84b36aea 100644
+--- a/c/enc/brotli_bit_stream.c
++++ b/c/enc/brotli_bit_stream.c
+@@ -956,18 +956,16 @@ void BrotliStoreMetaBlock(MemoryManager* m,
+
+ size_t pos = start_pos;
+ size_t i;
+- uint32_t num_distance_symbols = params->dist.alphabet_size;
+- uint32_t num_effective_distance_symbols = num_distance_symbols;
++ uint32_t num_distance_symbols = params->dist.alphabet_size_max;
++ uint32_t num_effective_distance_symbols = params->dist.alphabet_size_limit;
+ HuffmanTree* tree;
+ ContextLut literal_context_lut = BROTLI_CONTEXT_LUT(literal_context_mode);
+ BlockEncoder literal_enc;
+ BlockEncoder command_enc;
+ BlockEncoder distance_enc;
+ const BrotliDistanceParams* dist = ¶ms->dist;
+- if (params->large_window &&
+- num_effective_distance_symbols > BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS) {
+- num_effective_distance_symbols = BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS;
+- }
++ BROTLI_DCHECK(
++ num_effective_distance_symbols <= BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS);
+
+ StoreCompressedMetaBlockHeader(is_last, length, storage_ix, storage);
+
+@@ -1163,7 +1161,7 @@ void BrotliStoreMetaBlockTrivial(MemoryManager* m,
+ uint8_t dist_depth[MAX_SIMPLE_DISTANCE_ALPHABET_SIZE];
+ uint16_t dist_bits[MAX_SIMPLE_DISTANCE_ALPHABET_SIZE];
+ HuffmanTree* tree;
+- uint32_t num_distance_symbols = params->dist.alphabet_size;
++ uint32_t num_distance_symbols = params->dist.alphabet_size_max;
+
+ StoreCompressedMetaBlockHeader(is_last, length, storage_ix, storage);
+
+@@ -1206,7 +1204,7 @@ void BrotliStoreMetaBlockFast(MemoryManager* m,
+ BROTLI_BOOL is_last, const BrotliEncoderParams* params,
+ const Command* commands, size_t n_commands,
+ size_t* storage_ix, uint8_t* storage) {
+- uint32_t num_distance_symbols = params->dist.alphabet_size;
++ uint32_t num_distance_symbols = params->dist.alphabet_size_max;
+ uint32_t distance_alphabet_bits =
+ Log2FloorNonZero(num_distance_symbols - 1) + 1;
+
+diff --git a/c/enc/dictionary_hash.c b/c/enc/dictionary_hash.c
+index 3677d7dd..16d853fe 100644
+--- a/c/enc/dictionary_hash.c
++++ b/c/enc/dictionary_hash.c
+@@ -13,1107 +13,1833 @@
+ extern "C" {
+ #endif
+
+-BROTLI_INTERNAL const uint16_t kStaticDictionaryHash[32768] = {
+-32072,0,0,0,0,0,0,0,0,21860,0,0,0,0,0,0,0,40486,0,0,0,0,0,45798,0,0,0,0,0,0,1292
+-,0,0,0,0,4964,278,23717,0,19972,0,0,0,0,0,0,0,0,0,0,0,0,2126,16102,0,0,0,14437,0
+-,0,0,0,0,0,0,26727,2253,0,0,17252,0,0,0,0,0,0,0,0,0,3622,0,0,0,0,22984,0,0,0,0,0
+-,0,16647,0,34247,0,0,0,0,0,48486,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2511,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19532,0,0,24004,0,0,0,9828,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30853,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,31974,0,0,0,0,0,0,0,0,20650,2404,0,20773,1677,9031,0,6404,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51879,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6761,7206
+-,0,0,21992,22983,0,0,3529,0,1864,0,0,0,0,0,0,11046,0,0,9641,0,0,0,6507,0,0,36934
+-,21576,62375,0,0,0,0,0,0,0,0,0,8294,0,0,0,0,0,0,0,40807,0,0,0,39398,8136,0,0,0,0
+-,0,0,0,8875,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7941,0,0,25609,0,0,0,936,
+-3716,3213,15687,0,0,0,0,0,52519,0,17381,0,0,0,0,1320,5797,0,21029,0,0,6472,807,0
+-,0,0,0,0,0,0,0,0,0,13545,0,0,0,3624,0,0,0,29674,30820,0,31237,0,6596,0,0,0,0,0,0
+-,0,0,0,64070,0,0,0,0,0,0,0,0,0,0,0,22278,0,37446,0,0,0,0,7240,423,0,24612,21705,
+-17636,0,0,0,0,0,0,1833,0,0,0,328,6021,0,0,0,19974,0,0,0,0,0,0,0,0,0,62119,4178,0
+-,0,0,0,12100,8617,0,0,16900,0,36678,0,0,0,35366,0,51718,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,20998,0,62086,0,0,0,0,0,5542,0,0,0,0,0,0,0,0,0,0,0,14629,10952,25927,0,0,0
+-,0,19849,0,0,0,0,0,0,0,30952,3046,14314,12998,0,0,0,15268,0,40582,30216,62118,0,
+-0,0,20132,0,0,0,0,0,12005,0,0,0,52358,0,0,0,0,24778,0,44,33095,0,0,0,0,0,26372,0
+-,0,0,0,0,3781,0,0,17928,9479,0,0,0,0,0,0,0,0,32297,28613,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,47174,11723,0,0,0,0,0,0,0,0,0,2536,55143,0,0,6410,0,0,0,0,0,0,0,0,56294,11914
+-,0,529,0,30184,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8261,0,0,28808,58854,22633,
+-965,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64135,0,0,331,3684,0,1605,0,0,0,0,0,0,
+-0,0,0,0,16650,37,0,23622,3144,15429,0,0,0,0,0,0,0,0,0,0,22443,69,0,0,0,0,0,0,0,0
+-,17832,0,0,0,0,0,0,0,0,0,11113,0,0,0,0,18309,0,0,0,0,0,0,0,0,0,26630,0,0,25512,
+-25895,0,0,0,0,0,0,0,0,0,0,0,16901,0,0,0,27558,0,0,9418,0,0,0,3508,0,0,0,0,0,0,0,
+-0,37990,9289,8517,0,0,0,0,1578,1604,23944,0,0,14916,12781,0,0,0,0,0,0,0,12105,0,
+-16617,0,0,0,0,0,0,0,0,0,0,0,0,21348,11240,28870,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,5772,0,0,27812,0,0,0,0,0,0,0,8324,0,0,0,0,0,0,0,0,0,0,16748,1157,0,0,18794,
+-16324,25898,935,8333,0,0,0,0,0,0,0,0,18246,0,18086,0,46854,0,0,0,0,0,0,339,0,0,
+-25188,12780,12166,6409,0,0,0,0,16516,0,27012,28395,0,0,0,0,0,0,0,1420,0,0,0,9768
+-,52967,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25163,324,0,0,0,0,0,0,0,0,0,64998,0,0,0,0,0,
+-21893,0,0,0,0,0,47366,0,0,0,870,0,0,0,12646,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,26020,16360,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1809,0,0,0,6601,15878,0,0,0,0,0,
+-29092,0,28516,0,0,0,0,0,0,0,0,0,21988,0,0,0,42950,0,0,0,0,0,0,0,0,0,0,5133,1318,
+-0,0,0,0,0,0,0,0,0,0,0,54982,24904,0,0,0,0,0,0,0,0,0,0,51526,0,0,0,0,0,3685,0,0,0
+-,0,10062,9412,0,0,0,31460,5708,6181,0,0,0,0,0,0,0,0,0,5575,0,0,0,0,0,0,0,0,0,0,
+-27144,57478,0,0,0,0,0,0,7084,0,21993,53126,0,0,0,0,8397,0,0,5733,0,0,0,0,0,2116,
+-0,24742,0,11271,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1133,0,4873,0,0,38310,0,0,0,0,0,
+-0,0,0,0,0,0,0,17932,0,0,18053,0,0,0,25510,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17798,0,
+-26214,0,0,0,0,0,0,0,0,23016,17415,20392,164,0,0,0,0,0,0,0,0,0,0,0,3239,0,46119,0
+-,0,0,28580,0,0,0,0,0,0,0,0,0,7621,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41478,0,0,31016,
+-55334,10056,1924,0,0,0,0,0,36614,0,36711,0,0,0,0,0,0,0,0,0,0,13994,59303,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,26501,0,5639,0,0,0,0,0,0,13897,1253,0,0,0,0,0,5095,0,0,0,
+-28869,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8646,0,0,0,0,25641,17796,0,0,0,0,0,0,0,
+-13316,620,6309,11819,0,0,0,0,0,0,0,0,0,904,1095,0,24229,0,0,28744,49703,0,23077,
+-0,0,0,0,32392,0,0,0,0,35271,0,28740,5866,0,0,0,0,0,0,0,4361,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7917,8869,0,0,0,13924,0,0,0,0,
+-0,41958,0,0,0,0,0,0,6766,13989,0,0,0,903,0,0,24010,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,64390,0,22468,0,25861,0,0,0,0,23656,5317,0,0,0,0,0,0,23017,5445,16009
+-,0,0,0,0,0,0,0,0,48006,10473,0,0,14404,0,0,0,42183,0,0,0,51270,0,0,10602,24132,0
+-,0,0,0,0,43782,0,0,17834,0,0,0,25576,27205,0,0,0,0,0,0,0,0,29066,0,0,0,0,0,626,
+-1988,14700,0,0,0,0,0,0,0,0,0,0,0,0,57670,0,0,0,0,0,0,0,0,0,44710,0,0,0,0,3848,
+-7623,0,0,0,0,0,0,0,0,0,0,0,42374,0,0,0,0,0,0,0,0,19272,6436,0,0,5256,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,19685,0,0,0,0,0,0,0,0,0,0,0,0,0,39783,0,0,0,0,30984,0,0,0,0,0,0
+-,28230,0,0,0,29028,10538,3205,0,0,0,0,0,0,0,0,0,0,0,5636,840,295,0,0,8488,8198,0
+-,0,0,0,0,0,0,0,0,20580,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4074,19526,0,0,0,0,
+-31144,64038,0,0,0,0,0,0,16716,0,0,0,0,0,0,0,0,0,0,0,17706,0,0,0,0,0,0,50630,0,
+-50503,0,0,0,0,0,0,0,0,0,0,0,25446,0,0,0,13831,0,0,0,0,0,0,2696,4039,0,0,0,0,
+-25288,0,12076,2054,0,48934,0,0,0,0,16969,59431,17259,35335,0,0,0,0,0,0,0,0,0,0,0
+-,0,31275,0,0,0,1097,0,0,0,0,0,0,0,0,0,0,0,776,839,0,0,29386,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,5864,12134,0,0,0,0,0,0,0,25349,0,0,0,0,0,0,0,0,0,61447
+-,0,0,0,0,0,0,0,0,0,24678,0,0,0,63335,0,28836,8142,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4494,0,0,0,0,0,14088,1188,0,16260,0,0,0,
+-16421,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,276,0,0,17060,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24076,29445,0,33543,0,4901,0
+-,0,12522,0,0,62471,0,0,0,0,0,0,0,0,0,0,4046,0,0,0,0,20486,0,15460,2217,51719,0,0
+-,0,0,0,23495,0,0,0,0,0,0,15370,0,15849,0,15113,0,0,0,0,0,0,0,0,27972,7337,0,0,0,
+-0,30342,0,0,0,0,0,0,0,0,32299,23940,0,17766,0,0,0,0,0,0,6184,0,20904,0,0,0,0,0,0
+-,0,0,0,0,31492,0,0,0,5509,0,0,0,0,0,0,0,0,2669,50182,0,0,12299,0,0,0,0,0,0,0,
+-5257,28167,0,0,0,0,0,0,0,0,0,0,0,11750,3890,0,0,26500,0,0,0,0,0,0,0,49318,0,0,0,
+-0,0,0,0,10981,0,0,0,0,0,0,0,0,17961,1831,0,0,0,0,0,0,0,29638,0,0,0,0,26473,0,
+-6216,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,711,0,0,0,0,0,0,0,0,0,0,28683,39975
+-,0,0,0,0,0,51654,0,0,0,27527,0,0,0,0,0,0,0,0,30859,3268,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28772,0,18212,0,0,0,0,25448,65446,0,0,0,0,
+-0,0,3337,1670,0,0,0,0,0,19332,0,0,0,0,24936,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1043,0
+-,0,0,0,15814,0,21670,0,0,0,0,0,0,0,16263,0,0,0,0,0,0,0,0,0,32454,0,30630,0,0,
+-20170,9926,0,0,0,18247,0,0,14376,0,2056,17191,0,0,0,0,0,0,0,7812,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,22474,52806,1588,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10825,0,
+-0,0,0,40934,0,0,0,0,0,0,0,28677,0,0,5714,0,0,0,0,0,0,0,0,0,0,0,0,0,25865,22246,0
+-,0,0,0,17256,35751,0,0,0,0,0,0,0,0,8236,0,32108,0,0,0,43,14342,0,16517,0,0,30732
+-,0,4012,133,0,40583,971,23942,0,0,27275,0,0,0,204,0,0,27140,7564,44327,27592,
+-57958,0,0,0,0,22344,25701,0,0,0,0,0,0,0,19524,31755,0,0,28102,0,59111,0,0,0,0,0,
+-0,0,12261,0,44934,0,0,0,0,31560,0,11114,0,0,0,0,0,0,0,0,0,0,0,18953,18311,0,
+-45159,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2059,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-19399,0,0,0,0,0,0,0,0,0,0,0,0,0,58534,0,0,0,0,0,0,0,0,0,0,0,0,22411,23943,0,0,0,
+-0,0,0,11690,0,0,4069,0,0,2668,6342,0,0,0,0,0,0,27658,1766,0,0,0,0,23240,56070,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,34119,0,24453,0,0,0,0,21867,0,17610,9894,0,0,27976,38790
+-,0,0,0,43654,0,31559,12202,23142,0,0,0,50343,0,0,0,0,0,32806,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,49895,0,0,0,0,15786,4263,0,0,0,0,4746,3814,0,0,0,0,0,0,17192,
+-453,17323,0,20328,4036,0,0,0,15844,0,0,0,0,27561,31940,32296,0,0,0,0,0,0,0,11499
+-,11782,0,0,0,0,9738,50471,0,0,0,0,0,35430,0,0,0,0,0,29734,0,0,0,36551,0,0,0,0,
+-9257,5606,0,13829,0,7015,0,0,0,0,0,25127,0,0,19051,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-2572,0,0,0,0,0,0,29797,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42342,0,0,0,0,9293,
+-0,17896,56038,4077,0,0,0,29899,37351,0,30823,0,8326,0,0,0,18342,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18569,54054,0,0,0,0,0,0,0,0,0,37254,0,0,31433,
+-61510,0,2022,0,0,0,0,0,25381,0,0,0,0,0,0,0,0,0,0,0,0,0,2149,25289,0,0,0,0,0,0,0,
+-0,0,0,12516,14185,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8676,0,0,0,0,0
+-,0,0,0,0,0,0,36486,0,0,0,0,10889,9607,0,28711,0,0,0,0,0,0,0,0,0,0,28490,0,0,0,0,
+-26181,10283,1701,0,0,0,0,0,0,0,0,0,14980,0,7783,0,27846,0,0,0,56486,3892,0,0,0,
+-5770,16583,0,26309,13422,20292,0,0,0,0,0,0,0,0,0,28742,0,0,0,0,14536,1158,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25801,0,0,0,0,0,0,0,0,0,0,0,0,42438,0,3332,0,0
+-,0,0,0,0,0,0,0,8327,0,0,0,0,0,0,0,0,0,0,0,0,17353,1447,0,0,8427,48518,1359,0,0,0
+-,0,0,14986,0,32168,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9230,2791,0,0,0,0,0,0,0,0,
+-16073,31623,4269,0,0,0,0,0,0,4519,0,0,27912,58950,0,0,0,0,0,0,0,0,8361,19812,0,0
+-,0,0,6056,7877,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21701,0,0,0,0,0,0,0,0,0,0,0
+-,0,9128,1125,0,16548,0,0,0,0,0,0,0,0,0,0,17292,6854,21352,0,2380,0,0,4007,0,0,0,
+-0,0,24357,4202,0,0,0,0,0,0,0,0,0,0,0,0,0,10664,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,42823,3022,0,0,0,0,0,0,0,0,0,0,0,0,14373,0,20677,3304,2759,20522,64903,0,
+-0,0,38,0,0,0,0,0,0,0,0,0,0,0,27814,2802,8870,3758,1255,0,0,0,0,0,0,0,0,30027,
+-9510,0,0,0,0,17864,14855,0,0,0,0,0,0,0,0,0,0,23404,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-51462,0,0,0,0,0,0,0,45734,0,0,23467,32327,0,0,10826,52999,0,0,0,33222,31336,
+-64326,0,0,0,0,0,0,0,32166,0,0,3891,0,0,0,7017,645,0,0,0,0,0,0,27915,46087,0,0,0,
+-21863,0,34246,0,0,16715,0,0,0,0,14052,21416,0,0,0,0,0,0,0,0,39846,0,0,0,0,0,
+-38982,0,0,17512,7460,0,0,0,0,0,0,0,0,0,15428,0,0,0,0,0,0,0,28356,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,25445,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11879,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,19911,0,20007,0,0,0,10855,943,0,0,10821,0,0,0,0,4170,0,0,0,0,0,0,
+-0,0,0,9836,0,0,0,0,0,0,0,0,0,0,65415,0,0,0,0,0,0,0,0,9865,24646,0,0,0,0,0,40519,
+-0,0,0,0,0,0,0,0,0,12804,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22091,23655,0,0,0,0,0,0,
+-0,31686,0,0,0,58599,0,0,0,0,0,0,0,0,0,0,0,0,0,19620,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-24421,0,28100,0,0,0,31268,0,3204,0,0,0,0,0,0,0,0,0,14822,0,0,0,0,19947,10182,0,0
+-,9480,14821,4398,0,0,14532,0,0,0,48871,1873,0,0,0,0,0,0,0,589,1541,0,0,0,0,0,
+-23333,0,0,0,14149,0,0,0,0,1296,14374,0,27300,0,0,0,0,0,0,7276,0,0,0,0,0,0,47718,
+-0,0,0,0,0,0,0,0,0,0,5164,1765,0,14405,0,37574,1994,0,6636,0,0,0,0,0,0,0,0,27815,
+-0,0,0,0,2568,6820,0,0,0,0,0,0,0,0,0,0,11336,26247,0,0,23912,0,0,0,30536,0,0,
+-34342,0,17799,0,0,0,22149,0,6118,0,25732,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,26600,5190,0,0,1142,0,0,0,0,0,0,0,0,39527,0,0,0,0,0,39494,0,0,0,0,0,0,0
+-,0,0,0,3085,0,0,0,0,0,0,0,4786,0,0,0,28873,6532,0,0,26664,0,9193,11719,0,0,0,0,0
+-,0,31752,64646,0,0,0,0,0,0,0,0,0,0,0,11397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25094,0
+-,0,18153,20167,0,0,0,17254,0,0,878,0,0,0,0,0,0,0,0,0,0,24166,0,0,0,0,0,0,0,0,0,0
+-,0,0,26059,0,0,0,0,0,0,0,0,0,0,0,0,0,31592,0,0,8167,24362,6212,0,34758,0,0,0,0,0
+-,0,32520,0,0,44679,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17989,8681,29222,0,0,0,
+-0,0,0,0,0,10251,4902,1452,15207,0,0,0,0,0,0,0,22822,0,10469,0,0,0,0,0,0,19337,
+-17670,107,11494,0,0,0,0,27305,2565,0,0,0,0,0,0,0,64518,200,28389,0,0,0,0,31208,0
+-,30762,0,0,0,0,0,29321,60518,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3209,3237,
+-12490,22663,0,0,0,18789,31464,16391,0,0,0,0,0,0,0,0,0,0,0,20646,0,0,0,27238,0,0,
+-0,0,0,15940,4488,6951,0,0,0,46342,0,0,0,0,0,0,0,0,0,28965,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,20584,3367,0,25350,0,0,0,0,0,0,0,0,0,0,0,0,1814,0,0,0,0,0,0,0,0,0,0,17125,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,55943,0,0,0,0,0,24133,0,0,0,0,0,0,0,0,0,0,0,0,2929
+-,0,0,50086,0,2918,25356,30052,115,11846,0,0,0,0,3056,0,0,0,0,17639,239,19815,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36806,0,0,0,0,0,0,0,0,0,0,0,0,0,21479,0,0,0,0,0,
+-28420,11786,4772,0,0,3368,36295,0,31463,0,0,14665,996,0,20582,0,0,0,9988,0,23685
+-,0,0,0,52551,0,0,0,0,0,0,0,7556,0,0,0,0,0,0,0,1895,2186,0,0,0,0,0,27755,25447,0,
+-0,0,0,31052,63270,0,0,0,0,0,0,0,36742,0,24804,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,31048,0,0,0,0,0,0,0,0,0,21290,2276,0,0,0,0,26475,0,0,0,0,0,0,0,0,0
+-,0,15332,0,0,0,0,0,0,0,0,3176,19431,0,0,0,0,0,0,0,62726,0,0,0,25380,0,0,27883,
+-1316,0,0,7724,3015,0,0,0,0,6697,0,0,47910,0,0,0,0,0,0,0,0,0,3141,0,0,0,14820,0,0
+-,0,0,9326,0,0,0,0,0,0,0,0,0,0,31493,0,0,0,0,0,6566,0,0,0,0,0,0,6569,1348,0,25638
+-,0,0,0,0,0,20324,0,0,17067,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11876,0,41030,0,0,0,26405
+-,0,0,0,0,0,0,0,0,0,11431,28137,14950,0,10151,0,0,0,0,0,0,0,29574,0,0,0,0,27176,
+-57446,0,0,0,0,28650,57574,1387,0,0,0,0,0,0,0,0,0,0,58247,0,0,0,0,0,0,0,16805,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3526,0,15781,0,5572,13352,0,0,0,0,0,18665
+-,23463,0,0,0,0,0,0,15405,6885,0,0,0,0,15272,0,0,0,0,0,0,0,0,9861,0,0,0,0,0,0,0,0
+-,9512,4037,0,0,11563,49639,0,0,0,0,0,0,27880,57830,0,0,0,0,0,41831,0,21924,0,0,0
+-,0,0,0,0,25509,0,27462,0,18085,0,0,0,0,0,0,0,0,0,0,0,0,13898,8068,26441,0,0,0,0,
+-0,0,25316,0,0,0,0,16298,7397,5706,19239,0,0,0,0,0,0,0,0,1392,50919,0,0,0,0,0,
+-53863,0,0,0,0,1451,0,0,0,0,0,0,0,0,0,0,35847,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,17801,15813,0,12740,0,0,0,32967,0,0,0,0,0,0,5389,0,0,0,0,0,0,0,0,0,0,31143,0,
+-20548,0,0,0,0,0,0,0,0,0,51686,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-12109,19015,0,34983,0,21732,3600,0,0,0,0,47750,17288,43975,22857,47559,0,0,0,0,
+-26408,48358,0,0,0,0,0,0,0,0,0,0,0,0,0,30470,0,0,23560,4581,0,22404,0,49286,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,49831,0,0,0,27525,31691,7,0,0,25835,0,0,0,0,0,
+-4201,16485,0,20676,0,0,0,0,3753,23303,16264,3878,0,0,0,0,0,0,11434,0,0,0,0,0,0,
+-7589,0,0,0,0,0,0,0,0,0,57095,0,0,0,0,0,0,0,0,0,0,0,22820,11146,49158,0,23623,0,0
+-,0,0,0,0,0,13893,0,0,0,0,0,0,11722,60071,1258,0,0,0,0,0,0,18564,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,27945,0,0,0,0,5479,0,20006,17608,3431,10988,30180,0,0,0,0,0,0,0,
+-24581,14,0,0,0,0,0,0,25572,0,0,0,28612,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53543,0
+-,0,0,0,0,0,0,0,0,0,0,33670,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8710,0,14116,0,0,116,
+-292,0,0,0,37831,0,43078,0,0,0,0,0,0,0,0,21832,0,0,32134,783,0,0,30982,0,0,0,68,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5932,0,0,0,18505,
+-15175,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3630,16965,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,17797,0,0,0,0,0,0,520,42150,0,0,3122,0,0,0,22506,0,0,0,0,0,0,0,0,28550,0,
+-0,0,50278,0,0,13641,5958,0,35238,0,0,0,0,0,0,0,0,29993,18724,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,20619,9319,0,0,0,0,23977,0,5193,0,0,12196,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,24390,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20105,677,0,0,0,0
+-,0,0,0,0,29419,0,0,0,0,0,0,0,0,0,20266,0,0,0,0,10631,0,0,0,0,0,0,0,0,0,47655,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26628,12744,0,20648,0,0,0,432,0,0
+-,0,0,0,0,0,0,0,0,646,0,25604,0,0,0,0,0,0,0,0,0,0,0,0,0,63782,0,0,0,0,24616,0,0,0
+-,21291,0,0,0,0,0,0,0,0,0,0,45638,0,0,0,0,1931,0,0,0,20521,59975,0,20614,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,56231,0,0,0,0,0,29991,0,52871,0,20934,0,0,0,0,0,0,0,16871,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,7237,0,0,0,0,0,47558,0,0,0,0,0,0,0,0,0,0,0,10406,0,0,0
+-,0,0,0,0,43046,0,0,2930,0,12936,0,0,0,0,0,0,0,0,0,0,0,0,31141,0,0,0,0,0,0,0,
+-37639,0,17572,0,0,0,0,0,0,0,0,0,0,31240,0,0,0,0,0,688,0,0,0,0,0,1648,0,0,0,0,
+-10055,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,146,0,0,0,0,0,0,0,0,0,6345,199,0,34982,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,56839,0,0,0,0,0,48902,0,13412,0,0,0,0,0,0,0,0,2441,4420,0
+-,0,0,0,20428,933,0,0,0,0,0,0,0,45383,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,54726,0,0,0,0,0,0,0,0,0,0,0,0,17036,741,0,0,0,0,0,0,0,27589,0,0,30282
+-,18950,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2248,0,0,0,0,0,0,0,0,0,25993,0,0,0,
+-2443,0,0,31622,0,14150,0,0,0,28679,0,0,0,0,0,0,15464,0,0,0,0,54694,0,0,0,0,0,0,
+-3827,0,0,0,3756,0,9897,0,0,0,0,0,19082,31239,0,0,0,0,0,0,0,0,0,0,0,24580,0,0,0,0
+-,0,0,0,0,0,16580,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27625,0,0,0,784,4647,32652,0,0,
+-63494,0,0,0,0,0,0,0,21062,0,0,0,0,0,0,0,0,0,0,3404,58470,0,32325,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,18634,2789,0,0,0,0,0,0,0,8548,0,0,0,22501,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,15881,0,0,0,0,35879,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7978,17956,0,0,0,
+-0,0,0,0,24324,0,0,4937,0,0,0,8168,0,13420,10340,0,0,0,0,0,11780,0,0,0,0,0,0,0,0,
+-0,0,16712,0,0,0,0,0,0,0,17640,17991,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,2953,0,0,0,0,0,0,0,9100,16806,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30667,0,0,
+-19013,0,0,0,0,0,0,205,15334,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1969,0,0,0,0,0,0,0,26248
+-,52518,0,49798,0,0,0,0,0,0,0,9668,0,0,0,0,0,4742,0,0,21641,0,0,0,0,0,0,53574,0,0
+-,0,0,0,0,5707,0,0,0,0,0,0,0,3018,12454,0,0,0,0,2920,262,0,0,0,0,0,0,0,0,0,0,3593
+-,0,0,0,0,0,0,0,0,0,0,23910,0,0,0,0,0,0,0,55879,0,0,0,0,0,775,0,43270,5066,48967,
+-0,0,22986,4165,8971,44838,0,0,0,0,0,62279,272,0,0,0,0,51430,0,0,0,0,0,0,28234,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13349,0,0,0,51111,20265,13861,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,585,7494,0,0,0,0,0,0,0,0,21768,62407,0,0,0,0,7979,166,0,
+-0,0,0,0,0,0,0,0,38918,0,56742,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16296,5767,0,0,0,0,0,0
+-,0,32068,0,0,0,0,0,0,0,0,0,0,0,0,0,29796,0,0,0,0,0,0,0,0,23916,30183,0,58791,0,0
+-,0,0,0,0,0,20518,0,0,0,0,8969,0,0,0,183,0,0,0,0,0,2314,17445,0,0,0,0,0,0,0,0,0,
+-23748,0,0,8139,4839,27914,0,0,0,0,0,0,0,0,0,0,0,0,29478,0,0,16552,26663,0,53767,
+-0,0,13960,8039,18696,0,0,0,0,0,0,0,0,0,0,0,782,16005,0,0,0,0,0,0,0,0,6258,56806,
+-16456,12455,0,0,0,0,0,0,0,23780,0,0,0,0,0,0,9355,0,0,0,7273,41063,24780,57766,0,
+-0,0,0,0,0,0,0,0,0,3820,2597,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29225,61126,0,0,0,58439,
+-15691,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37190,22408,967,0,0,0,
+-23078,26858,0,0,0,19753,0,0,0,0,0,0,0,0,0,5416,13702,0,0,0,0,0,52742,20394,38567
+-,0,0,0,51079,0,0,136,8516,0,0,0,0,0,0,0,0,0,0,0,27588,0,0,0,0,0,0,0,0,0,0,531,0,
+-0,0,0,0,0,0,0,0,8936,5031,12520,19334,0,0,22827,30247,28074,31140,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,27497,18148,20104,59079,0,0,0,0,0,0,0,0,0,24389,0,0,6125,0,0,0,0,
+-9541,0,0,24553,29095,0,0,0,0,0,0,0,25444,0,0,9643,0,0,63047,0,0,0,0,0,0,0,0,0,
+-39558,0,0,0,0,0,0,20620,11815,499,0,5128,2278,0,0,0,0,0,46310,0,0,0,0,0,0,0,0,
+-23530,40166,2440,0,0,0,0,0,0,0,0,0,0,15174,0,0,0,0,0,0,0,0,0,0,26922,0,0,0,0,0,0
+-,0,0,0,0,26758,0,0,0,0,0,51911,0,0,23532,0,0,0,0,51238,25737,44486,12622,0,0,0,0
+-,0,0,3078,0,9253,0,0,1128,22023,0,0,0,21350,0,16420,0,0,0,0,0,0,0,65094,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22532,0,48774,0,34503,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,9797,0,0,0,0,0,0,0,13797,0,38279,0,0,1738,0,489,46343,0,45382,0,0,0,0,0,0,
+-0,0,0,29030,0,0,0,0,0,0,6220,56550,0,0,0,0,0,26885,0,28806,0,0,0,0,0,0,0,0,0,0,0
+-,45958,0,0,0,0,20553,49927,0,0,0,0,0,0,3019,12358,0,0,0,0,0,0,0,0,0,0,26571,
+-13319,0,0,653,23399,0,0,0,0,0,0,0,0,22316,0,0,21188,0,0,0,0,0,0,0,0,0,27556,0,0,
+-0,0,0,0,0,27878,21483,27653,0,29701,237,0,10632,0,0,0,0,33766,0,0,0,0,0,0,31563,
+-0,0,0,0,0,1416,2439,0,0,0,0,0,0,0,0,0,0,9611,0,0,0,0,0,0,0,5611,16581,26601,
+-35462,0,0,0,26756,0,59271,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26984,57734,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,7882,0,0,0,19528,6469,0,0,1161,0,0,0,7688,20935,425,0,
+-0,0,0,0,0,0,0,12519,0,12902,0,0,0,0,0,0,0,0,0,0,2411,0,11725,26086,0,0,20201,0,0
+-,0,0,0,0,0,0,11045,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30471,0,0,0,0,0,0,0,0,0,0,0,
+-21541,1141,21190,0,9188,0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,1093,0,0,0,0,0,0,0,0,
+-4842,0,13672,0,0,12230,0,0,0,10532,0,0,8937,0,0,0,0,0,0,0,0,0,0,28996,0,0,11720,
+-26982,0,46182,0,43911,31754,0,1160,3940,0,20772,0,0,0,0,0,24549,0,32582,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,31845,0,0,0,0,0,0,0,2310,11788,0,0,43047,0,0,0,18853,0
+-,0,0,0,0,0,0,0,0,63622,0,0,7048,17318,0,0,0,21957,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,1039,6279,0,0,0,0,0,0,0,0,0,0,0,0,0,12197,0,0,0,0,0,0,0,0,0,
+-46470,0,0,24,19719,0,0,0,0,0,0,0,0,0,39335,0,0,0,0,0,0,0,0,0,0,21353,3846,0,0,0,
+-0,0,0,0,36679,0,0,0,0,0,0,0,0,0,0,0,11268,0,0,0,0,0,9382,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,29926,0,33606,0,4708,2828,0,0,29543,0,0,0,0,0,29893,0,0,0,0,0,0,0,0,3663,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10920,7111,0,0,0,0,0,0,0,0,0,0
+-,9384,0,0,0,0,0,0,0,0,0,0,0,0,20388,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37094,0,0,0,
+-27110,0,0,0,0,0,0,21865,0,27753,30214,0,0,0,0,0,57895,0,0,0,0,0,0,0,0,0,0,12648,
+-5446,0,0,0,0,0,0,0,0,0,0,19784,17124,0,52007,0,0,0,0,0,0,0,0,758,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,24900,0,0,0,0,0,1476,0,65031,0,0,1205,46663,0,30023,11625,
+-1094,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10058,0,0,0,0,0,0,28455,0,0,0,0,0,0,0,0,0,0,0,
+-14788,0,0,0,0,16808,0,0,742,0,0,0,0,0,0,0,0,0,0,0,21636,0,0,0,0,0,0,0,0,0,0,0,0,
+-15944,23207,0,0,0,0,247,0,0,0,0,24743,0,0,0,5252,0,0,0,0,0,0,0,0,29961,18660,
+-21099,46791,0,7045,0,0,0,0,25707,0,0,17412,3828,0,0,0,0,0,0,0,0,0,0,0,5803,5637,
+-0,38151,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60103,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,853,0,0,0,0,0,0,30215,0,0,0,0,0,0,0,8741,0,0,0,0,0,27366,0,0,0,0,171,
+-4070,0,0,0,0,0,0,0,0,24073,7366,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2184,5189,0,
+-20932,1545,4996,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7684,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6313,0,0,0,0,0,0,0,30826,0,0,0,0,0,0,
+-0,0,0,0,27463,0,0,0,0,0,0,0,0,0,0,21640,63303,0,0,3275,31111,0,0,0,0,0,0,0,11556
+-,0,14756,0,0,0,15108,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23914,28966,0,0,0,4965,0,0,0,0,
+-0,0,0,0,0,0,10216,5223,0,0,0,0,0,0,0,0,0,27142,0,0,1173,20198,0,0,0,0,0,56614,0,
+-0,0,0,0,4612,0,0,0,0,0,0,0,0,0,0,11822,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17769,7910,
+-0,0,31880,0,0,6055,0,0,0,0,0,0,0,0,0,0,8970,0,0,0,0,0,0,0,0,0,0,0,16840,23879,0,
+-0,11051,0,0,0,32552,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20842,13701,0,0,0,37191,7373,
+-10471,17482,25348,0,0,0,38502,0,0,0,0,0,0,0,0,0,21509,6058,0,0,0,0,0,0,3173,0,0,
+-0,9543,0,0,0,0,0,0,17768,12708,0,0,0,0,0,37030,0,0,0,0,0,0,0,0,0,0,12748,48743,0
+-,11718,0,0,25194,0,0,0,9033,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5028,0,30118,0,0,0,0,0,
+-42759,0,0,3720,0,0,0,0,0,0,25190,0,0,0,0,0,0,0,0,0,0,5450,5125,0,58086,0,0,0,0,0
+-,27716,0,0,0,0,0,0,0,0,0,22052,0,0,0,0,26249,0,15947,3460,0,0,0,35814,0,0,0,7813
+-,19500,32167,0,18597,0,0,0,0,0,28644,0,0,0,60743,0,0,0,0,0,29636,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,17220,15885,9414,9642,0,0,0,593,0,0,24228,0,0,0,0,0,40422,0,26244,0,
+-23109,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64902,0,0,0,0,3979,60007,0,0,0,28199
+-,0,0,0,43142,0,0,0,0,0,0,0,29158,0,30532,0,0,0,0,13256,0,0,0,0,16549,0,0,0,0,0,
+-26116,0,0,0,0,0,0,0,0,22825,0,0,0,0,0,0,0,1065,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,18985,4805,0,0,0,0,0,17702,0,0,0,0,0,0,0,0,0,0,3468,0,0,0,0,13447,0,0,0
+-,0,0,0,0,0,0,0,0,56871,0,0,1776,15780,0,0,2603,0,10280,31366,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,11592,3591,0,2372,0,0,0,0,0,0,0,20004,0,0,0,0,0,0,12072,518,0,0,1960,
+-8999,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7178,32999,0,0,0,0,0,0,1641,0,0,0,0,0,0,0,6764,
+-9893,490,4005,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25258,5541,0,14053,306,20743,0,0,
+-9422,0,0,0,0,0,0,0,11977,260,0,35175,0,0,0,0,0,0,0,18405,0,0,0,16582,0,0,0,22470
+-,0,0,0,0,0,0,2792,0,0,0,14026,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14858,3909,0,0,0
+-,57671,0,0,0,0,0,0,15979,0,0,0,2794,15239,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26884,
+-9070,0,0,0,0,51846,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19499,37127,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,19205,10350,11910,0,0,0,0,15083,23108,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,169,0,0,0,0,0,0,0,0,0,0,0,15274,41735,0,56774,0,0,2825,0,14025,
+-389,0,0,0,0,0,0,0,0,21482,31910,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20456,710,0,0,25032,
+-21797,0,0,0,0,0,0,0,0,0,0,32427,21252,0,30150,0,43174,0,0,0,0,0,0,0,0,0,0,0,0,
+-11403,0,0,1029,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6892,9252,0,63206,
+-3496,14406,0,0,0,0,0,0,0,0,0,0,22568,0,0,21253,0,0,0,0,0,0,0,39623,0,0,10189,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,30729,59910,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3305,0,0,0,0,0,0,
+-0,0,0,7660,24871,0,838,0,0,0,0,0,0,0,0,0,0,0,0,12013,13252,0,551,0,0,0,43207,0,
+-30567,0,0,0,0,0,0,0,0,28394,30724,0,0,0,0,0,0,0,0,0,0,22665,22725,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,29414,0,0,0,0,16074,8966,245,1445,0,0,0,0,24872,0,0,0,0,
+-13124,0,35527,0,0,0,0,0,0,13259,10917,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-25191,0,0,0,13956,0,0,0,0,0,0,0,54631,19625,12070,3083,0,0,0,0,14436,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,21766,0,15463,29322,0,0,0,0,0,0,29990,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,23653,0,0,0,0,0,0,0,0,2643,0,0,21223,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,4114,0,0,0,0,0,0,0,0,34790,0,0,0,0,0,0,0,16103,0,0,0,0,0,0,297,3620,3338,
+-10372,0,14727,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29924,22473,13895,
+-15529,32455,30378,13540,0,28807,0,0,0,0,0,0,0,64582,18380,0,0,0,0,0,0,0,0,0,0,0,
+-0,38598,0,0,0,0,0,0,0,0,1236,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32710,0,0,0,0,4590,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64935,0,0,0,0,0,0,0,0,0,0,0,0,16744,0,0,
+-0,0,0,0,20005,0,0,13608,1191,0,0,0,62183,0,0,0,0,0,24484,0,0,0,0,0,0,0,0,0,0,
+-17643,0,0,0,0,0,0,0,0,0,0,0,0,5380,0,0,32328,0,0,63814,0,0,0,2919,0,0,0,0,17034,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,60295,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,7690,486,0,0,0,39270,0,49094,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12555,0,0,0,0,0,0,0,0
+-,0,0,0,0,20967,17993,12647,0,0,0,16036,32616,0,0,0,0,16294,8555,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35174,0,0,0,0,0,0,30346,0,0,0,0,0,0,0,
+-14797,3652,0,0,8268,12934,0,54950,0,0,0,0,2632,33959,0,23175,0,0,0,0,0,36262,0,0
+-,0,0,0,0,32684,26918,0,32676,0,0,0,0,0,0,0,0,0,0,15625,11943,1206,0,0,0,0,18052,
+-0,0,0,0,0,16422,0,0,0,26404,0,0,28777,0,0,24902,0,0,408,45351,0,35719,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,3658,17446,0,165,0,0,0,0,0,0,0,6151,0,0,24424,0,0,0,0,0,0,0,
+-24170,24293,0,0,0,0,0,0,0,0,0,11847,0,39591,0,0,0,0,0,0,9549,2788,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1010,0,0,0,0,0,0,26055,31724,0,24233,
+-1828,0,0,0,0,0,0,0,0,0,17284,0,0,0,0,19464,0,0,0,0,0,0,0,0,32452,0,0,0,28871,0,0
+-,0,0,17704,53383,0,0,0,0,0,0,0,0,0,17892,1938,0,0,0,0,0,16362,0,0,21605,0,0,5003
+-,0,0,0,0,0,0,22693,0,22342,0,0,0,55846,0,0,0,0,0,0,0,0,0,22853,0,0,0,0,0,0,0,0,
+-6600,263,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24836,0,0,0,0,0,0,0,0,0,
+-40711,0,0,0,0,0,33894,0,0,0,0,0,0,13000,0,0,0,0,0,0,0,0,0,0,30308,0,0,0,0,0,0,
+-5386,0,0,0,0,0,0,27844,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17740,0,0,0,0
+-,25093,29064,0,0,0,0,0,0,0,12680,11462,0,0,0,0,0,0,0,0,84,7303,0,0,0,0,0,0,0,0,0
+-,0,0,27044,457,0,22924,58246,19016,0,2606,45703,0,5157,0,25028,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,2065,0,0,0,0,0,31946,0,0,0,0,0,0,0,0,0,0,0,0,33382,0,
+-47878,0,0,0,0,0,0,0,0,25004,0,0,0,0,0,0,0,26153,35654,0,58055,30668,0,0,0,0,
+-25988,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4456,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,7560,20583,0,0,0,0,0,0,0,0,0,37510,0,0,0,0,0,0,0,0,0,42822,0,0,0,0,0,0,0,0,
+-0,0,0,1733,0,0,0,8196,0,0,11241,0,30572,60326,0,15013,0,0,0,40646,0,23812,0,
+-10022,0,0,0,0,0,0,0,0,12874,31015,0,0,0,0,0,0,1608,0,0,0,0,18308,0,0,0,0,27114,0
+-,0,0,0,0,0,0,7944,1382,0,11813,0,0,0,0,0,0,0,0,0,0,0,0,0,24517,0,11621,0,0,0,0,0
+-,0,0,0,0,0,0,21702,0,0,13100,8262,2644,7973,0,0,0,0,0,0,0,0,0,0,0,0,1033,12581,0
+-,25221,0,0,0,40998,16301,62983,0,0,0,0,1263,9318,0,0,0,18854,0,0,1741,33895,0,0,
+-0,0,0,0,26377,0,0,0,0,0,0,0,0,0,0,32165,0,51143,0,0,0,0,0,29412,0,0,0,0,0,0,0,0,
+-1674,4230,0,0,0,0,0,10502,0,0,0,0,5545,0,0,0,0,0,2099,45158,0,0,0,0,0,0,0,0,0,0,
+-14157,0,26955,0,0,0,0,0,0,0,0,0,17096,0,0,0,0,0,0,0,0,0,0,0,0,0,27050,6726,0,0,0
+-,0,0,0,0,0,28554,0,0,7142,0,0,0,0,16936,0,0,0,25833,0,4399,6980,0,46214,0,0,0,0,
+-0,10630,21164,0,0,0,0,0,0,0,2446,48551,0,0,0,0,0,0,0,0,0,0,0,13381,0,0,0,0,0,0,0
+-,0,15400,12135,0,0,0,0,0,4774,586,0,0,0,0,0,0,0,0,23751,9736,4548,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25577,29607,6250,1637,0,0,0,0,
+-22024,0,0,0,0,22308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37414,24044,0,0,0,14474,29735,
+-0,7077,0,45990,0,0,0,0,30568,40039,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-6150,0,4228,0,0,0,0,0,27687,0,0,0,0,0,0,0,24548,21513,1350,0,0,0,33607,0,0,0,0,0
+-,0,0,0,11784,1414,0,0,0,0,0,0,0,18244,940,0,0,0,0,0,0,7270,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,16709,0,0,0,0,0,0,0,48935,0,0,0,0,0,0,23660,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,53350,0,0,0,0,0,0,4236,16358,0,4422,6665,32644,0,0,744,18084,0,11014,0,0,0,0,0,
+-29508,0,0,0,0,0,0,0,7686,0,0,13289,5478,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,12872,0,0,24134,1005,22916,0,31429,23400,0,0,0,0,0,0,0,28424,0,0,0,
+-25706,27109,0,0,26345,0,0,0,0,0,0,25126,0,0,88,0,0,0,0,0,0,0,17032,0,0,21799,0,0
+-,10060,0,12296,21892,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20777,14311,0,58182,
+-32232,0,10282,0,2121,11527,0,0,0,12325,0,0,0,0,0,0,0,28804,2344,8133,0,0,0,0,
+-21864,62695,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2771,0,0,
+-23204,0,0,0,0,0,6278,0,0,0,0,0,26597,0,0,0,0,23144,0,0,0,0,0,31816,20070,0,0,0,0
+-,0,0,0,0,0,0,24456,2118,0,0,0,0,6570,1156,0,0,0,0,0,0,0,30406,0,0,0,28388,3572,0
+-,0,26599,12426,5286,0,0,0,0,0,4967,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24970,24167,0,0,0
+-,0,28745,4678,0,0,0,0,0,0,0,1444,236,0,0,0,0,0,0,0,0,19428,0,0,0,0,0,0,2092,0,0,
+-0,0,0,0,0,0,0,2827,0,0,0,0,0,19881,19204,0,11749,0,0,0,0,0,0,0,17958,0,17894,0,
+-18726,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9190,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,21510,5033,0,0,0,0,22855,0,0,0,0,0,14598,0,29605,0,0,0,0,0,0,0,0,
+-617,0,0,0,0,47142,0,0,0,0,0,0,0,0,0,0,3627,0,0,0,0,0,0,0,0,0,0,0,0,0,2225,14823,
+-0,0,2637,6182,78,15078,0,0,0,0,20264,0,0,0,0,0,0,36743,4140,44551,17352,25703,0,
+-0,0,0,0,0,0,0,0,0,0,0,14024,0,0,0,0,0,0,28004,0,0,0,0,0,7588,0,0,0,0,0,0,0,2087,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18028,0,0,0,300,14212,0,0,1386,40327,0,0,0,0
+-,0,0,31082,0,0,22374,0,0,0,0,0,35718,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-26532,7756,0,0,18982,0,0,0,0,0,0,0,0,6440,1159,7180,0,0,0,0,0,0,45766,0,57798,0,
+-16740,0,0,6802,60454,0,0,0,26470,0,0,0,0,0,65382,4362,7750,0,0,0,0,0,0,9096,4743
+-,334,0,0,0,0,0,0,39974,0,0,0,25828,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3027,0,0,
+-0,15816,0,0,0,0,0,0,0,0,48327,0,0,0,0,0,0,0,0,0,0,16168,41799,0,0,24458,8581,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12292,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,54503,0,0,0,0,5097,30852,18664,0,0,0,0,0,0,16484,0,0,27337,0,0,0,
+-0,0,0,0,0,0,0,0,0,35942,0,0,0,0,0,0,0,4356,0,0,0,0,0,57030,0,0,1417,41191,0,0,0,
+-0,0,23429,0,0,0,0,10024,21735,0,0,10126,0,0,0,0,19046,0,0,0,0,0,0,24105,4710,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4394,0,0,0,0,13253,0,56391,0,0,0,0,0,0,0,0,0,0,
+-0,19174,0,0,0,0,0,0,0,0,0,55974,0,0,0,52070,0,15620,0,0,0,0,0,2660,0,0,0,0,21644
+-,0,0,52455,0,0,0,0,0,0,0,0,0,8902,0,0,0,0,0,0,3116,0,464,34726,0,0,0,0,0,0,25003
+-,12423,0,27172,1896,7335,0,0,0,0,0,35686,0,0,0,0,3472,0,0,0,0,22406,0,0,0,0,0,0,
+-0,0,0,45254,0,0,0,0,0,0,0,0,0,0,0,0,0,21124,23594,33127,0,0,0,0,0,0,16684,22087,
+-0,0,0,0,0,0,0,0,0,0,0,0,8714,0,0,0,0,0,0,0,0,0,0,55814,0,0,0,0,0,0,4109,23460,0,
+-0,8874,0,0,0,0,0,0,0,0,0,147,0,0,0,0,0,0,0,0,0,0,0,0,0,29960,63398,1302,0,0,0,0,
+-0,0,0,0,24806,0,0,0,0,0,0,0,0,0,9799,0,0,0,0,0,0,0,31333,0,0,0,0,0,19557,0,0,0,0
+-,0,5701,0,0,0,63014,0,0,0,0,0,0,0,21254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12484,0,0,
+-0,48326,0,0,0,0,0,0,0,0,0,0,0,15783,0,0,1202,0,0,0,0,23174,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,3086,49191,0,0,5387,15141,0,0,0,3365,0,0,0,0,20076,14021,
+-0,0,0,0,0,0,0,0,0,0,376,40198,0,0,0,52039,0,24932,0,0,0,0,808,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,9860,0,0,0,0,0,23719,0,21476,0,0,0,0,20776,4807,0,0,3177,16678,0,0,110
+-,10853,0,0,0,17382,0,0,0,0,0,0,0,0,0,43462,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,7500,4966,0,0,0,0,0,0,0,52102,0,24516,0,0,0,0,0,0,0,0,0,0,0,0,0,26535,0,0
+-,0,46247,0,0,0,15557,0,0,0,0,76,52327,0,0,0,0,17866,0,0,0,0,0,0,0,0,0,0,46758,0,
+-0,0,0,0,19173,0,0,0,0,0,0,0,0,0,44038,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2985,0
+-,0,0,0,0,0,14310,0,0,2125,45831,0,0,0,0,0,0,9838,0,13227,19492,0,0,0,29764,0,0,0
+-,0,686,30053,0,0,0,0,0,30789,139,20837,0,0,0,0,502,18533,0,0,0,0,0,19111,0,0,0,0
+-,0,31396,0,0,0,17444,0,0,0,0,0,0,0,49862,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25610,550,0
+-,0,561,0,29034,0,0,0,3528,0,0,0,1715,14661,18,63463,0,0,0,0,0,0,0,0,0,0,14186,0,
+-0,0,0,0,0,0,0,0,0,0,29578,59014,0,39430,0,0,0,0,2250,16612,0,31780,0,0,0,0,0,0,
+-462,16967,0,29029,0,0,0,0,0,23462,0,0,0,0,0,0,0,0,1768,0,6025,16998,1804,0,0,
+-54182,0,0,0,0,0,0,0,0,14124,0,6154,29702,0,0,0,0,0,7716,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,48807,0,8292,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16389,5933,0,
+-14857,51303,0,0,0,0,0,0,0,0,0,0,0,35623,9097,23047,0,0,23112,0,0,0,0,0,438,0,0,0
+-,0,0,0,0,151,9254,1390,0,0,0,0,0,0,54215,0,0,0,0,6187,0,0,0,0,13095,0,0,0,0,0,0,
+-0,0,0,0,0,0,9866,0,0,59622,0,0,0,0,0,0,0,0,0,25286,0,0,23848,32069,0,0,0,0,0,0,0
+-,0,0,9255,2187,15270,437,0,0,0,0,0,0,0,0,0,0,19493,0,0,0,0,0,0,0,0,0,0,0,11748,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16902,0,0,0,0,0,0,0,0,0,22212,1865,17543,0,
+-0,0,0,0,0,21996,0,0,0,0,55975,0,0,0,0,0,0,0,0,32138,21156,0,0,0,0,0,0,14249,0,0,
+-0,2388,0,0,0,0,6823,0,0,0,0,0,0,0,0,0,0,0,0,0,26694,0,0,6059,53511,0,0,0,0,0,0,0
+-,49542,6159,0,0,0,0,0,0,0,0,0,0,0,0,0,1036,24036,0,2501,0,0,0,0,0,0,17419,51271,
+-3377,15142,0,0,0,0,0,0,5007,62374,0,56935,0,0,0,0,0,0,0,0,0,0,0,24422,0,0,0,0,0,
+-0,0,0,942,0,0,0,0,0,0,0,0,0,0,28263,0,0,0,0,0,0,0,15622,0,19749,0,0,1611,0,22219
+-,48583,25129,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17476,0,0,0,0,0,0,0,0,0,0,
+-721,0,0,0,0,32518,0,0,0,18469,0,0,0,0,0,0,5896,29927,3657,23046,0,0,3214,0,0,0,0
+-,0,0,0,0,0,112,0,0,0,0,0,3048,455,0,31012,0,0,0,0,0,0,0,23270,0,32677,0,0,0,0,0,
+-38086,0,0,0,0,0,0,0,0,0,0,0,0,0,4900,0,0,0,0,0,0,0,0,0,25541,0,18788,0,0,22248,
+-1351,0,61734,4524,30629,0,14887,242,29063,0,0,14408,4741,0,0,0,37318,0,0,0,0,0,0
+-,0,0,0,0,0,0,8106,0,32107,0,0,0,0,0,0,0,0,0,0,0,1481,0,0,28132,0,25798,0,59783,0
+-,0,0,0,0,59078,0,0,0,23366,0,0,0,0,0,0,0,30887,0,0,0,0,16200,0,0,0,335,0,0,0,714
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,30730,9478,0,0,0,0,0,0,0,0,0,0,0,18790,0,0,0,0,663,0,
+-0,0,1034,31431,0,0,0,0,0,0,0,0,0,0,30120,0,0,0,0,13925,0,0,0,0,0,0,2280,13414,0,
+-0,0,0,0,0,22028,23687,3017,11047,0,0,21738,18630,0,0,0,0,0,0,0,30246,0,0,0,0,0,0
+-,0,0,0,0,0,0,17257,0,21896,63783,0,0,0,21094,0,18662,0,25700,0,22533,0,0,0,0,0,
+-6341,5800,11111,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15399,
+-12970,6501,0,0,3179,26438,0,0,0,0,0,0,0,15750,0,13062,0,0,0,0,0,0,0,0,0,0,142,0,
+-0,0,0,21284,11177,4391,0,0,0,0,19595,40647,0,0,0,0,0,11877,0,0,0,26439,0,0,0,0,
+-695,49126,27467,11972,0,0,0,0,0,0,9961,0,0,0,31722,62982,0,0,0,0,15817,52710,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24614,0,0,0,0,0,20550,0,0,5034,3942,0,0,0,
+-45927,0,0,0,0,0,0,0,0,0,0,2548,0,0,0,0,0,0,45606,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,3405,12582,15563,54087,0,0,0,0,0,0,0,0,0,0,0,0,24202,5893,0,0,0,
+-44230,0,0,0,5605,0,47782,0,32230,0,0,0,0,0,0,0,0,0,0,0,7014,0,0,0,0,16488,3175,0
+-,27237,0,0,0,0,0,40902,0,0,0,0,0,0,0,32004,31434,0,24392,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,29130,58214,0,0,0,0,0,0,29002,0,0,0,0,0,0,0,0,0,0,55366,0,0,0,0,0,0,0
+-,0,0,0,0,37926,0,0,0,0,0,0,0,0,1290,0,0,0,4713,0,0,0,0,0,0,0,0,0,0,0,0,0,20812,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1803,966,0,17700,0,0,654,19109,0,51655,0,0,0,0,0,
+-10470,1584,0,0,0,0,0,0,0,2506,0,0,25159,4303,0,0,0,395,15879,0,0,0,0,0,0,0,0,0,0
+-,1352,6535,0,19652,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4722,7909,0,0,0,0
+-,30152,0,0,64742,0,0,0,0,0,0,2153,9125,0,0,279,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,41894,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,1328,17030,0,0,0,0,0,0,0,54151,0,0,0,0,1775,54535,0,0,0,0,31624,0,0,0,
+-7150,0,0,0,0,0,0,0,1840,35943,0,0,0,0,0,56455,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-64486,0,0,0,51174,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4134
+-,0,0,0,0,0,0,0,0,0,0,0,17092,0,0,0,0,0,0,0,0,0,0,0,0,12,16134,19883,39943,10281,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,44711,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-14125,2407,0,0,0,0,0,0,0,0,0,0,26921,0,0,0,0,0,22188,0,20810,10053,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28170,0,15208,0,0
+-,32517,5736,19271,3562,10534,0,0,0,59655,0,0,0,0,27084,60422,0,0,24969,0,0,0,
+-2636,0,0,0,0,26277,0,0,0,0,0,0,0,0,0,0,0,30596,3594,0,0,0,8362,14565,0,0,0,0,0,0
+-,10793,12326,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5906,59686,0,0,23081,517,0,15556,0,0,0,
+-8486,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19877
+-,0,0,0,0,0,0,0,0,7497,0,0,26085,0,0,23784,63591,6568,6310,0,0,0,0,0,0,0,0,0,
+-10054,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7018,14470,18858,0,5641,10660,0,0,0,0,0,0,0,
+-35526,1515,0,0,0,0,0,0,0,0,0,0,0,27656,0,0,9606,0,39590,0,0,0,0,0,0,0,0,0,0,0,
+-53926,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,232,4327,12649,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,20199,0,0,0,0,0,0,26730,0,0,0,19400,14695,0,31334,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19589,0,0,0,0,0,0,0,0,5064,11908,0,27333,0,
+-0,0,0,0,0,0,47751,0,0,0,26662,0,0,0,0,0,0,0,55655,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,6245,0,0,0,0,0,0,0,0,23368,63911,0,0,0,0,0,0,0,0,1974,0,0,0,0,0,0,0,
+-8520,24037,0,0,0,0,0,0,0,26279,0,0,0,22886,0,0,0,27782,0,30694,0,0,0,0,0,0,0,0,0
+-,0,0,33703,0,0,0,30405,0,34598,0,51047,0,0,0,0,1908,0,0,0,0,0,0,0,0,0,0,1511,
+-21897,0,0,0,0,0,0,51398,0,24870,0,32647,0,0,0,35015,0,0,0,0,0,0,0,11204,0,0,0,0,
+-0,0,7758,57991,0,0,0,30949,0,0,22,15140,9162,0,0,0,0,0,0,25540,20136,7108,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16427,10789,9805,0,0,0,0,0,0,0,0,0,4680,0,0,52679,
+-0,0,0,0,0,14884,0,0,0,16804,0,0,0,0,0,0,9578,5287,0,0,0,0,0,0,0,34054,0,0,0,0,0,
+-19076,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7627,55719,0,39463,14446,58374,0,0,0,0,23465,
+-15845,0,0,0,0,0,38534,0,0,0,17893,10922,0,7176,678,0,0,0,0,0,0,0,0,3113,46279,0,
+-0,0,0,0,0,0,23334,0,0,18088,23268,0,62342,0,0,0,16613,0,0,0,0,0,0,0,0,0,38182,0,
+-0,0,0,0,0,25292,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10344,71,6446,0,0,1893,0,0,
+-1106,0,28680,30756,0,41126,0,0,1492,0,15341,0,0,0,0,17575,0,21220,0,0,0,0,0,
+-25060,2088,21828,0,0,0,0,0,358,0,0,0,0,0,16708,0,0,0,1668,0,0,0,0,0,12260,0,0,0,
+-0,0,0,0,0,4078,0,0,0,0,0,12713,6215,0,0,20329,0,0,0,0,0,0,0,0,0,0,31204,0,0,0,0,
+-0,0,0,0,0,0,3732,0,1646,0,0,27460,0,34406,17128,14341,0,0,0,0,0,19527,0,0,0,0,0,
+-0,0,0,0,0,6120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8551,21546,10212,3020,
+-2951,0,17638,0,0,6985,44999,2218,8197,0,0,30472,63366,0,26660,0,0,0,0,0,0,0,0,0,
+-0,0,0,1265,0,0,0,0,0,0,0,2610,0,0,0,11278,20295,0,0,0,0,0,19780,0,0,0,0,0,0,2353
+-,10852,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5421,24292,0,0,0,0,0,0,0,0,0,0,0,0,0,34407,0,
+-0,0,0,0,0,15432,20774,0,0,0,0,0,0,0,0,12360,10757,0,0,0,33126,0,0,0,0,0,0,0,0,0,
+-0,0,29573,0,2343,0,0,0,0,0,63079,0,0,0,0,0,0,0,0,0,43015,0,16038,0,0,0,0,0,0,0,0
+-,1480,25573,0,0,0,0,0,0,0,8839,0,0,0,0,0,0,0,24645,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-5063,0,0,0,0,0,45830,0,0,0,0,0,0,0,0,0,0,823,0,0,64039,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,15300,0,0,0,0,0,0,2924,46759,6760,19268,0,0,0,0,0,0,0,0,0,34182,0,0,3977,18149,
+-0,0,0,32199,0,0,0,0,0,0,0,0,0,23524,25994,0,0,10343,0,0,0,9733,0,0,0,0,0,0,0,0,0
+-,4740,0,0,0,0,0,0,0,0,0,16741,0,0,4626,23367,0,0,31400,0,0,3557,0,0,4234,0,0,0,0
+-,0,0,28486,0,0,0,0,0,14213,0,57191,0,0,0,0,0,0,0,0,0,0,240,0,0,0,0,65318,29832,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29989,0,31846,0,0,8170,0,0,4421,27626,30884,0
+-,0,20204,0,0,0,0,44614,534,20868,0,0,0,0,0,0,0,0,0,0,0,0,0,28710,0,10277,0,0,0,0
+-,0,29511,0,19813,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27020,0,0,0,0,0,0,53094
+-,0,35207,0,0,0,37542,0,61766,8584,8037,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12488
+-,22757,0,0,0,0,0,0,0,0,0,0,0,0,0,23814,0,0,0,0,0,0,0,0,0,19973,0,0,0,63943,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36006,0,0,0,19012,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,8580,0,0,0,0,0,0,0,18021,0,0,0,0,0,0,0,0,80,1254,0,0,0,42630,0,0,0,0,0,
+-0,0,16262,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2124,25479,0,0,0,0,16873,0,0,0,0,3142,
+-0,0,18443,0,0,0,0,0,3917,0,8841,1190,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,20645,0,0,0,0,0,0,0,0,0,0,0,9284,0,0,24394,41351,0,0,0,42087,0,62566,0,0,0,0,
+-0,0,0,0,0,0,6728,4199,0,0,0,0,25515,0,1231,0,374,15623,0,29956,0,14118,0,0,0,0,0
+-,19047,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31718,0,0,0,0,0,0,0,0,0,0,0,20900,0,16743,0
+-,0,0,28902,0,0,0,0,0,0,0,0,0,0,0,0,2578,0,0,0,0,0,0,0,0,0,13838,0,0,10052,0,0,0,
+-0,7432,43783,17097,0,0,0,0,0,873,0,0,0,398,0,0,0,0,0,0,0,0,0,8459,23559,0,53030,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35750,0,4071,0,0,0,38662,0,41414,0,0,0,0,11656,0,0
+-,0,0,0,4011,42695,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25353,0,0,0,0,0,0,0,27177,22372,0,
+-0,0,0,0,30980,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,46278,3976,12711
+-,0,0,0,0,0,0,0,0,0,0,0,20517,0,0,0,0,0,0,0,0,0,0,0,0,4072,11078,0,0,16553,2405,0
+-,0,0,0,0,0,0,0,2670,0,0,0,0,0,0,32998,0,0,0,0,0,0,0,47046,0,30533,0,0,11050,9734
+-,13129,0,0,0,0,23494,0,0,0,0,0,58310,0,0,0,57543,0,0,0,0,0,0,0,0,0,0,0,0,0,454,0
+-,0,0,0,0,0,5163,59687,2220,0,0,0,0,0,0,29510,0,0,0,0,0,0,0,0,0,0,0,17316,0,20069
+-,0,0,0,0,0,0,0,0,0,5319,0,0,0,0,0,0,0,0,0,27174,0,0,0,0,0,0,0,22949,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,19208,0,0,0,0,0,0,20933,0,0,6026,8742,0,0,0,17380,0,13127,2797,0
+-,0,30116,0,0,5963,8004,0,57126,0,0,0,0,0,42854,14792,30759,0,24964,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,16933,0,0,0,0,0,0,15176,40839,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-788,30341,0,0,0,0,21036,24102,0,0,0,0,30123,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-22597,31531,26789,0,59559,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9352,29863,0,0,0,0,0,0,0,0
+-,0,24551,0,0,0,0,0,0,0,20516,0,0,0,39462,3665,0,28265,0,8778,64262,0,57414,9132,
+-0,0,18276,0,0,0,0,0,0,0,0,0,0,26344,30725,524,19751,0,13796,0,0,0,0,0,0,0,0,0,0,
+-18155,0,12841,0,74,24998,13579,1061,0,64199,0,0,8776,0,0,60231,0,25412,0,0,0,
+-59143,0,0,0,0,0,0,14344,1510,0,0,0,38374,0,0,0,0,0,0,0,0,13353,0,0,0,0,0,0,0,0,0
+-,0,9446,0,0,0,0,0,0,0,32613,0,0,0,0,0,0,0,0,0,0,0,0,0,19844,0,0,0,0,14859,0,0,0,
+-0,6662,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14154,0,29770,0,0,0,0,0,
+-16520,2182,0,0,0,0,0,36102,3340,0,0,0,0,0,0,0,0,25189,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,15720,0,0,0,0,0,0,22758,0,0,304,0,3243,14117,0,0,0,0,0,0,0,0,0,0,5130,
+-12679,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21733,10441,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,36103,0,0,0,0,0,23590,0,57479,0,0,0,0,0,0,0,0,0,0,0,0,10824,
+-18372,0,0,0,0,0,35078,15722,12967,0,0,0,0,0,34599,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-53639,0,38630,0,0,0,0,0,0,31017,11333,0,0,0,0,19144,0,9513,0,0,0,0,0,0,0,0,56711
+-,24042,0,1197,0,0,58502,0,0,0,0,0,0,0,0,0,8230,6121,18628,0,0,0,0,0,0,25290,0,0,
+-0,0,0,1514,0,0,0,0,0,0,0,14378,9798,32363,0,0,0,0,0,9577,0,0,0,0,0,0,26788,0,0,0
+-,0,0,0,330,10533,0,0,0,0,0,42246,0,0,0,0,0,0,5074,21028,0,38119,0,0,0,0,0,0,248,
+-0,31176,62054,0,53287,0,0,0,0,271,0,0,0,0,0,0,0,0,0,0,0,0,0,9224,2117,0,0,0,0,
+-15818,5607,0,52582,0,0,0,0,0,0,0,0,18248,24005,23018,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-427,0,0,39910,0,0,7080,11399,0,0,0,0,0,0,0,0,0,0,22220,57894,0,0,0,0,0,0,0,13156
+-,0,1413,1007,0,0,0,0,21415,0,21543,0,0,0,0,0,0,0,0,0,41702,22538,9573,0,0,0,8806
+-,0,0,6920,56359,0,0,0,0,0,0,0,0,0,0,0,42215,0,0,13708,0,0,0,0,0,0,0,0,0,0,16453,
+-0,0,0,0,0,0,1582,1764,3282,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11653,0,0,0,0,12139,0,
+-29482,31076,1673,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,40262,0,0,0,33862,0
+-,0,0,0,0,20996,0,0,0,0,0,4615,0,0,0,0,0,0,0,0,0,0,0,43943,333,19367,0,0,0,0,0,0,
+-0,26821,0,32389,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4936,11687,0,0,0,0,0,0,0,0,0,10885,0
+-,0,0,0,0,25926,0,0,0,0,0,0,15851,0,0,0,0,0,0,0,0,0,8360,0,17130,7942,0,11460,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,18150,14248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-22310,0,0,0,42758,0,0,0,0,0,0,0,0,29354,5574,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,31109,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11236,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,9156,0,0,1801,14023,0,0,0,0,0,62406,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-23620,0,0,0,0,0,0,0,0,0,0,31018,65510,0,0,0,0,0,0,0,26182,0,0,0,0,0,0,0,27717,0,
+-0,0,0,0,0,0,46950,0,0,0,0,0,0,0,0,0,0,0,0,0,31108,0,11366,0,0,0,3717,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8552,6054,3339,0,0,0,0,51622,0,
+-0,0,0,0,0,0,3718,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28358,0,2756,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,1462,0,0,27622,0,0,0,0,0,0,0,62502,14410,56743,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,12206,0,0,0,0,0,0,0,0,0,0,0,0,36550,0,38054,0,0,0,
+-21221,0,0,0,0,0,0,0,27077,0,0,16906,0,12587,12101,0,0,0,0,0,0,10414,28775,21769,
+-60167,0,56646,0,0,0,0,0,20740,0,0,0,0,0,0,5931,5351,0,65478,0,0,0,0,0,0,7977,
+-52647,0,4868,0,0,0,55463,0,0,0,0,0,32197,0,0,0,0,0,13445,0,0,0,26631,0,0,0,0,0,
+-11237,0,0,0,0,209,1285,0,0,1928,0,0,0,0,43334,23849,23172,0,0,0,0,0,0,0,0,24712,
+-62439,8811,3463,20457,0,0,0,0,0,0,0,0,0,16008,56263,0,0,0,0,0,0,0,0,0,0,0,60358,
+-22761,6565,0,0,30888,27686,0,0,0,17093,0,0,0,0,22121,0,0,0,7593,14182,0,28103,0,
+-0,0,0,0,45126,0,0,0,0,0,0,0,0,0,0,0,0,0,31844,0,0,0,0,0,0,0,0,0,0,0,0,0,18500,0,
+-0,0,0,28202,0,0,0,0,0,0,0,0,26308,0,29541,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-29572,0,0,0,21285,0,0,0,0,0,60839,0,0,0,0,0,30407,15949,2981,0,0,0,46439,0,0,0,0
+-,0,23911,26505,25222,12811,5895,0,6343,0,0,0,0,0,0,0,0,0,0,0,31815,0,0,0,0,0,0,0
+-,0,19688,10245,0,0,0,31301,26985,28964,0,0,0,0,0,0,0,0,27208,31172,0,0,0,0,216,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16292,0,0,0,0,0,8743,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,6438,0,0,0,33319,0,0,0,33286,0,0,0,0,0,0,0,0,0,22181,7499,24774,0,
+-10756,0,44775,724,0,25768,25669,24873,5349,25257,0,0,54566,0,0,0,0,0,0,0,0,0,0,0
+-,327,439,357,0,0,6536,8452,0,0,1802,0,0,61350,0,15045,0,0,0,0,0,0,0,0,0,0,0,
+-38343,0,0,0,0,0,0,0,0,0,0,32491,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-22885,0,0,32073,0,0,0,9546,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27748,0,0,23176,0,0,0
+-,0,0,0,0,0,0,0,0,0,24583,0,0,0,0,0,34118,0,0,0,0,2158,0,5586,30340,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,24452,0,0,0,0,2409,4390,0,24196,0,0,0,0,0,0,32264,26948,20587,0,0,0
+-,2155,0,0,0,0,0,0,0,0,0,0,0,4328,26276,0,0,0,0,0,0,0,0,23564,0,12458,11367,0,0,
+-25162,0,0,0,0,0,0,65414,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32966,0,0,0,
+-34662,0,0,0,0,0,39238,0,0,0,0,11400,10214,266,12452,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,15173,0,0,0,13668,0,13222,0,23364,0,0,0,0,0,11941,0,0,0,0,0,0,0,0,0,
+-25575,0,0,0,57383,0,0,0,10308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,2865,9287,75,0,0,0,0,0,0,0,0,0,0,21508,22380,59526,0,0,0,23589,0,0,0,51590
+-,0,0,0,0,0,0,0,0,0,0,0,4645,3980,28295,0,0,0,0,0,12388,0,0,0,0,0,0,0,0,0,0,0,
+-21734,0,17607,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41767,0,0,0,0,0,0,0,18436,0,0,0,0,0,
+-0,0,21958,0,19430,0,0,1204,0,0,0,0,0,0,0,0,0,3240,55239,0,0,0,0,0,30660,0,0,0,
+-28901,0,0,0,0,4716,0,0,0,0,0,0,0,0,0,0,0,11754,0,0,0,0,22086,0,22564,8749,0,0,
+-28391,0,0,0,0,0,0,0,0,0,0,0,2886,0,0,0,0,0,0,0,29062,0,0,0,0,0,0,0,40358,0,0,
+-15916,39526,0,13735,0,0,0,0,28938,0,407,4006,0,0,0,26916,0,0,0,0,0,27526,30280,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24586,0,24649,5126,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8684,0,0,0,0,0,0,0,23019,0,22377,18599,0
+-,0,0,0,0,0,0,0,0,0,27593,9735,0,20196,0,0,0,0,28168,48423,0,0,0,0,0,31399,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,13892,0,0,0,0,0,17606,0,0,15242,29767,26378,17701,0,0,
+-14472,0,4840,0,0,0,0,0,0,24708,0,9349,4330,0,0,0,0,0,0,0,16137,0,0,34854,0,0,0,0
+-,0,0,0,0,0,0,0,25063,0,0,0,0,0,0,6603,12583,0,0,0,0,0,0,0,0,7433,29188,0,0,0,0,0
+-,31270,0,0,22920,3143,0,0,0,0,0,23461,0,0,0,0,0,0,0,0,618,0,0,0,0,21381,0,11524,
+-0,0,0,0,0,0,21004,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,312,23239,0,0,0,0,0,0,0,0,0,0,0,
+-0,2313,0,0,40614,0,0,14825,0,0,0,0,0,0,46535,0,41190,7853,0,31656,0,0,0,0,0,0,0,
+-0,0,3433,5255,0,0,0,0,0,0,0,33958,0,0,0,0,72,15493,0,0,0,0,0,0,0,36070,0,0,0,0,0
+-,0,0,14724,0,0,0,0,0,29828,0,0,0,0,0,0,0,18822,20008,0,0,0,0,2438,2952,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,3342,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24420,0,19908,0,0,0,8101,0,
+-17479,0,0,3530,0,8202,29319,0,0,1132,6789,0,0,23881,0,0,0,4810,0,0,46918,0,0,0,
+-41574,0,0,0,0,0,0,0,0,0,48582,0,0,0,0,0,0,0,0,0,0,0,0,0,39334,0,0,0,26117,0,0,0,
+-0,0,0,5100,0,0,0,0,0,23496,27813,4045,54918,0,0,0,0,0,0,6473,7428,0,0,0,0,6792,0
+-,0,0,0,0,3560,32103,0,0,0,0,0,0,0,0,0,0,0,54790,0,0,6926,0,0,0,0,16518,0,0,0,0,0
+-,20806,0,0,0,0,1841,3174,0,0,0,0,9612,18374,0,0,0,0,32744,0,0,9671,0,59879,0,
+-23300,8073,0,0,14758,0,0,0,10342,0,0,0,0,0,0,24808,14759,0,0,0,0,0,0,5515,0,0,
+-14852,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2354,23271,0,32740,0,0,0,0,0,0,0,0
+-,0,0,18472,0,0,0,0,0,0,0,0,33190,0,0,0,0,0,0,0,0,8972,21669,0,0,0,0,0,0,0,0,0,0,
+-0,25574,0,0,0,0,5096,0,14283,55367,0,0,0,0,0,0,0,0,0,12644,0,0,0,0,4651,0,0,0,0,
+-0,0,0,661,0,0,13638,19466,0,0,0,0,0,31273,0,8010,0,0,0,0,0,3211,0,0,0,0,63430,0,
+-0,0,0,0,15237,0,0,0,0,0,0,19018,2437,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14312,0
+-,0,0,0,16836,0,0,471,35975,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,6023,0,0,0,0,0,0,0,0,11593,9639,0,0,0,55783,0,5700,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27908,0,26598,0,0,6667,6470,0,0,0,0,0,0,0,
+-62534,0,0,0,0,16522,27911,0,0,10025,7172,0,0,779,0,360,17477,0,0,0,61991,7752,
+-7717,1494,0,0,0,26569,40742,0,0,0,0,0,0,0,26406,10474,32196,0,0,0,0,0,50567,
+-16521,11716,0,0,0,0,0,55558,0,0,0,0,0,0,0,0,0,0,0,61926,0,26436,0,0,0,0,4459,
+-10598,0,0,0,0,0,0,0,0,0,0,0,9223,0,29318,0,0,0,0,0,60423,0,0,0,0,0,0,0,47078,0,
+-50246,0,12612,0,0,0,0,0,0,0,61799,0,55015,0,21060,7309,0,0,0,0,0,11976,0,0,0,0,
+-23527,0,0,0,0,0,0,10347,15942,0,34023,0,0,0,0,4969,0,0,0,0,0,0,0,0,28997,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36454,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-3466,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19716,
+-28872,0,0,0,0,0,22152,0,0,0,0,0,0,26342,0,0,0,9764,0,0,0,0,0,0,0,21798,0,0,0,0,
+-13,6853,32136,0,0,0,0,0,0,0,750,0,0,54502,0,0,0,0,0,0,0,0,0,46183,0,0,625,22854,
+-0,0,0,0,2061,23588,0,0,11049,56262,0,0,18538,1509,0,0,17258,4453,0,0,0,0,12429,0
+-,0,0,0,8102,0,0,0,0,0,0,8074,0,23852,0,0,0,0,0,0,0,0,0,0,0,16136,3428,0,27876,0,
+-0,0,7332,0,0,0,0,0,28900,0,0,2284,0,0,17573,201,1508,0,0,0,0,0,0,0,0,0,31365,
+-27688,22565,0,0,0,5159,0,0,0,0,4584,42599,0,0,0,44422,1068,23173,0,0,0,613,0,0,0
+-,12645,0,0,0,0,0,27076,6732,0,0,0,3913,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,22244,29992,15911,0,0,0,0,0,22982,0,0,0,0,0,0,0,50598,0,0
+-,0,0,0,0,5161,1574,0,0,0,0,0,0,0,0,0,19108,0,0,0,35014,0,0,0,25956,29067,0,0,0,0
+-,0,0,0,0,0,0,47079,0,0,0,0,0,0,0,0,0,0,1356,61927,0,0,0,64455,2122,64231,0,0,
+-18763,0,0,0,0,0,0,0,0,0,907,34471,0,0,0,39078,0,0,1995,0,0,0,0,0,0,0,0,0,0,56518
+-,0,0,0,0,0,0,0,0,0,0,0,0,822,0,15978,44423,0,0,3112,325,0,0,0,0,0,15397,0,0,0,0,
+-0,0,0,0,0,0,1193,4294,4968,15559,0,46150,0,0,0,0,0,18917,0,0,0,0,0,0,9928,37543,
+-0,0,0,0,13097,36999,0,0,0,15430,0,0,8424,29639,0,0,0,0,0,0,0,0,0,0,0,0,0,25734,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,40487,0,13284,0,11141,0,0,0,32388,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5298,57702,0,0,0,0,0,0,0,13060,0,0,0,0,0,0,
+-8233,42278,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36422,0,0,0,7972,0,0,0,
+-18437,0,0,0,0,7406,0,0,0,9225,0,0,0,0,0,0,0,0,0,13865,47591,18220,53703,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2796,0,0,0,0,0,24940,17223,0,0,0
+-,13221,0,0,0,0,0,0,0,0,0,0,15848,0,0,0,0,0,6122,1735,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,16968,18151,0,0,0,0,0,47494,0,0,0,0,0,0,26089,19494,0,0,0,0,0,15494,0,0
+-,0,0,0,0,0,0,0,0,28809,0,0,0,0,42727,0,55174,0,0,0,0,0,0,0,0,0,0,0,20485,0,0,0,0
+-,0,0,0,0,0,0,0,58598,0,0,0,0,0,0,0,0,0,0,0,0,0,15172,0,0,0,0,0,0,0,0,0,35302,0,
+-48135,20972,33094,0,0,0,0,0,9765,0,0,0,0,0,0,0,0,0,39559,0,0,13736,6950,0,0,0,0,
+-23658,8903,0,0,0,0,0,0,0,22662,0,0,0,0,0,58886,7468,0,0,0,0,0,0,0,0,64550,0,0,0,
+-0,0,47622,0,0,0,50886,0,0,0,0,0,57606,912,0,0,0,0,0,0,0,0,0,1449,0,1169,0,718,
+-46151,12104,0,0,0,0,0,0,48230,0,0,0,0,0,0,0,0,0,0,1259,0,0,33734,23208,62567,0,
+-65158,0,0,0,0,0,0,0,0,0,0,28684,59878,0,0,0,0,0,0,0,0,0,0,25769,0,0,0,0,65479,0,
+-0,0,0,555,22789,0,19748,1769,10246,8680,0,0,0,0,0,0,0,0,0,14250,0,5899,3303,0,0,
+-0,0,0,0,0,0,21097,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21638,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,10795,0,0,0,16204,0,0,0,0,0,26986,2469,0,14660,0,0,0,0,0,45447,
+-12234,3494,4555,10566,0,0,0,0,0,0,0,0,0,0,0,0,2801,0,0,0,15755,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,39654,0,0,0,0,0,0,6763,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-33574,0,10279,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63527,0,0,3912,0,0,7492,0,0,0,35142,
+-0,0,0,0,0,0,17576,8103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16713,4198,0,0,4782,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,16228,0,0,0,0,25961,20166,0,0,0,10980,0,0,0,0,0,14340,
+-18922,14567,0,44199,0,0,0,0,0,0,0,18406,0,0,0,0,0,37606,0,0,0,0,0,0,0,0,0,20902,
+-0,0,0,56358,0,38342,0,0,0,0,9514,36071,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21700,0,0,
+-5266,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1134,0,1453,0,0,0,0,0,3882,0,0,0,
+-0,0,0,0,0,4004,0,0,0,51910,0,0,0,0,0,23076,4648,0,0,0,31051,25351,0,0,0,22884,0,
+-0,0,0,0,63975,0,0,2376,16997,0,0,2096,0,0,0,3373,7046,0,0,0,0,0,0,0,30726,0,0,0,
+-0,20,0,13707,614,0,0,12840,3079,0,0,0,0,0,51046,3729,0,32680,0,0,0,0,0,24008,
+-62759,0,0,4745,0,0,0,0,0,0,0,0,0,0,0,0,0,2414,0,0,44262,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,24937,0,0,0,0,0,0,0,0,19140,0,13575,0,0,0,0,0,0,0,39110,0,0,0,28036,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,4261,0,0,0,0,5992,0,264,0,0,0,0,0,0,0,13739,0,21928,0,
+-0,0,0,0,0,0,0,0,0,0,4232,15110,0,0,0,0,0,0,0,0,0,30022,0,0,27977,0,0,0,0,0,24776
+-,0,0,0,0,0,2962,0,0,0,0,0,0,26564,22441,0,0,0,0,0,13640,11205,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,19305,1894,0,0,0,0,0,0,0,0,0,0,9389,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14119,
+-5224,135,0,0,0,0,0,0,0,0,0,25796,0,0,0,0,0,0,7470,0,0,0,0,63815,0,55654,0,0,
+-12584,0,1524,33223,0,0,0,9895,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11624,
+-0,0,0,5614,0,0,0,0,0,0,0,21320,0,0,53607,0,51206,0,0,0,25863,0,0,0,0,0,0,0,0,0,0
+-,0,8964,1740,0,0,0,0,0,0,0,0,13476,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7975,0,
+-0,3306,8134,0,8389,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25766,0,0,0,0,0,0,0,0,0,
+-52166,0,0,0,0,0,0,0,0,0,0,0,0,0,21477,31112,31652,0,0,0,0,0,0,0,28452,0,0,0,
+-44231,0,0,0,0,0,0,0,24805,0,0,0,0,0,0,0,0,0,0,12428,6471,0,0,0,0,525,17926,0,0,0
+-,26919,0,0,18120,0,0,0,30024,0,0,0,0,0,0,0,0,0,0,29189,0,0,0,43559,0,0,0,0,0,0,
+-19787,7557,0,59334,0,0,10184,6085,0,44039,0,0,0,0,0,0,0,11175,0,0,0,0,30440,
+-63110,0,0,0,0,0,0,11017,0,0,0,0,0,0,0,0,27204,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,29126,0,0,0,0,0,0,0,0,0,0,0,0,0,0,622,0,5226,2727,0,15588,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4650,0,2675,0,0,32420,0,0,0,61511,0,0,
+-5419,17829,2123,0,0,0,0,0,0,0,0,0,0,0,0,0,0,38183,2640,0,11274,14533,1842,0,0,
+-42663,12681,3430,0,11845,0,0,0,0,0,0,0,0,0,6533,0,0,0,0,0,54598,0,0,0,0,0,0,0,0,
+-0,0,0,0,12616,38535,0,0,0,0,0,32229,0,0,0,54279,0,48614,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,31401,0,0,0,0,34310,0,0,0,22788,0,52134,0,0,0,0,0,0,0,23302,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,40678,0,0,0,51463,535,0,0,0,0,15525,0,0,0,0,0,0,4904,869,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63718,0,0,0,0,0,0,0,0,1678,0,692,0,0,0,
+-0,0,0,0,0,0,26216,0,0,0,0,0,29355,0,0,0,0,25095,0,0,0,0,4335,0,0,0,0,0,14538,0,0
+-,0,0,0,0,0,0,0,27273,55014,0,0,0,0,0,27271,0,0,0,0,0,30468,0,0,0,0,18186,0,0,0,0
+-,0,14345,0,0,0,2152,0,0,0,0,0,0,0,0,0,0,0,0,0,0,58438,21034,0,23339,21318,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,21412,0,0,0,0,0,0,0,12869,0,0,4875,0,0,0,0,29191,0,0,0,0
+-,0,0,1640,10247,0,14244,0,0,0,0,9867,0,0,0,0,0,12363,0,0,7653,0,0,4168,2663,0,
+-4580,0,11143,0,0,0,0,0,0,0,30662,0,0,0,0,0,6724,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,13764,0,0,0,0,0,0,0,0,0,0,0,0,234,6821,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,25639,0,0,0,0,0,0,0,0,0,29958,0,3461,0,0,0,0,0,0,0,0,0,28324,
+-18795,7013,12746,11655,0,37287,0,0,10953,7718,9705,0,0,0,0,0,0,0,0,0,0,46534,0,0
+-,0,0,0,0,0,0,0,0,8137,17988,0,25156,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41415,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15784,6918,0,0,0,0,7019,10919,0,0,0,
+-0,0,0,0,0,0,0,4171,55495,4940,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22440,19333,0,0,
+-28136,0,6249,21317,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53414,0,0,0,57318,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,39303,0,0,0,0,0,19940,0,0,0,0,0,0,0,25543,0,0,0
+-,0,0,0,0,0,0,0,0,0,2698,3911,0,0,0,26790,0,0,0,0,0,0,32424,0,0,18470,0,0,0,14726
+-,29834,0,0,0,0,0,0,0,0,0,0,0,1000,4197,0,0,0,19366,0,0,0,39878,0,0,0,0,2185,8901
+-,5288,9829,25000,0,0,0,0,0,0,1062,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35622,0,
+-0,23048,62503,6506,0,0,0,0,0,0,0,13609,10438,0,0,0,0,0,0,0,0,0,0,7723,42119,0,0,
+-0,0,0,13317,0,0,0,41606,0,27111,0,0,21194,11461,0,0,0,0,26856,58342,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,20940,48710,0,0,0,0,0,0,5227,0,0,0,0,0,10061,31300,0,0,0,19236,0
+-,0,0,0,0,30277,13896,0,0,0,12876,13159,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,428,
+-46951,13134,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15462,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,21668,0,0,0,0,0,0,0,0,0,0,0,0,2249,0,0,0,0,44967,0,0,0,0
+-,0,0,3465,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24868,0,0,0,0,0,23909,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,2190,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16164,0,
+-10437,0,0,5263,20102,20938,0,0,0,1192,1030,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,21385,4870,0,0,0,0,0,0,0,0,0,0,0,18596,0,0,0,0,1422,4038,2858,0,0,0,0,0,0,0,0
+-,48998,0,0,0,0,0,0,0,0,6508,37350,0,0,0,0,0,0,0,0,17001,39431,0,0,0,0,0,30182,0,
+-21445,7403,28164,0,51750,0,0,0,62631,0,0,0,0,0,0,0,31206,0,0,0,0,0,0,0,0,0,0,0,
+-7751,0,0,0,0,0,0,0,0,0,13477,0,0,456,26693,0,0,0,0,0,0,0,0,0,0,0,0,14890,0,0,0,0
+-,0,26697,22022,13225,27364,0,0,0,18884,0,0,0,0,0,0,0,0,3659,0,0,0,0,0,0,0,0,0,0,
+-0,1448,5413,0,0,0,0,0,0,0,0,0,0,0,6340,0,0,18091,18725,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,22118,0,0,0,18981,0,0,0,0,0,0,0,0,0,29223,3724,0,0,0,0,43526,0,0,0,25668,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21545,9862,0,22692,32201,60646,0,7300,0,0,
+-0,58887,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19460,0,0,0,0,0,0,0,0,0,50342,0,
+-65255,4360,17286,0,0,0,0,0,0,0,28708,0,0,30025,60102,0,0,0,0,0,0,0,0,0,47014,0,
+-31973,0,9572,0,0,0,0,0,0,0,18501,0,0,0,0,0,14597,0,0,0,53735,5228,22183,0,0,0,0,
+-0,0,1554,24164,0,0,0,0,0,0,0,0,0,0,0,0,10827,0,0,0,0,34918,0,0,0,0,22252,0,0,
+-46855,0,0,0,0,0,31207,0,0,10733,0,0,63334,0,0,0,0,8616,50119,20169,12678,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,58087,20298,5,0,0,30920,0,0,0,0,0,0,0,296,13190,0
+-,30663,0,0,18536,12228,0,6788,0,0,0,0,30890,21796,0,0,526,0,0,0,0,0,0,0,0,0,0,0,
+-0,20965,0,0,0,0,2161,0,0,0,0,0,0,24038,0,0,0,0,13544,7398,0,0,32522,9605,0,0,0,0
+-,3208,7590,0,0,0,43846,0,0,0,38663,0,0,0,0,0,39014,4142,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,6373,0,0,13676,0,0,0,0,30374,21288,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22791,0,0,0,0,0,37958,0,0,0,0,0,0,0,0,0,0,9452,
+-9990,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4841,0,0,0,0,18820,152,0,0,0,0,0,13260,3334,0,0
+-,24234,8422,0,17957,0,0,0,10244,0,0,0,0,0,0,0,0,0,0,0,7204,0,0,0,0,1201,26151,0,
+-31173,0,0,0,0,0,0,0,0,0,0,0,0,0,64838,4203,7525,521,0,18888,37031,0,0,0,0,0,0,0,
+-0,7082,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4490,12487,0,0,0,0,0,0,0,36615,0,0,
+-0,14854,0,0,0,0,0,0,0,0,0,0,0,0,6539,13029,9704,38983,0,0,0,0,168,10405,0,0,0,0,
+-394,25607,0,57063,0,0,0,0,0,0,0,0,0,0,16141,19878,0,0,0,0,0,0,0,0,0,29446,0,
+-12036,0,0,0,0,0,6982,18572,0,24584,14535,0,0,0,0,0,0,0,0,0,0,16,0,21642,0,0,0,0,
+-0,0,5254,0,0,0,0,0,0,0,0,1622,0,0,0,0,0,0,0,0,0,0,0,0,0,3853,9126,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,7241,10982,0,0,0,0,0,0,0,0,0,0,0,0,0,0,950,0,0,57990,0,0,277,0
+-,0,0,694,36007,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42470,0,0,0,0,18409,
+-51142,0,0,0,0,0,0,0,0,0,28646,0,0,0,30693,0,0,0,0,0,56295,5544,0,0,0,0,8518,8366
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,45670,0,0,
+-9608,33062,0,0,0,0,0,0,0,0,0,0,0,18694,0,0,0,0,1672,23493,0,0,6955,7655,0,36134,
+-0,0,0,0,0,0,0,0,23432,647,0,0,0,0,0,0,0,0,0,0,0,13382,0,0,0,19621,0,0,0,0,0,0,0,
+-0,0,20228,0,0,2728,31495,0,0,0,0,29096,22213,235,35495,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,5348,0,0,0,0,8968,1989,0,0,1066,0,0,11492,5965,31367,0,0,0,0,0,0,0,0,0,0,0,
+-18727,0,0,0,6757,0,0,10765,4646,0,36166,0,27943,0,0,26888,8420,0,0,0,0,0,0,0,0,0
+-,29316,0,0,0,0,0,0,0,0,0,0,4975,0,0,0,14762,3111,0,0,0,0,0,43399,0,0,0,0,0,0,0,
+-18980,0,0,0,0,0,44550,0,0,0,0,4051,0,0,0,0,37734,0,0,0,0,0,5188,0,0,0,0,0,24486,
+-0,5989,0,41159,0,0,0,0,0,0,0,0,0,20326,0,0,747,6884,0,0,0,41798,0,0,3117,22919,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21032,0,0,0,0,0,0,0,0,9574,0,0,0,0,0,0,
+-4302,0,0,0,0,0,0,0,0,0,0,0,21068,34630,0,0,0,0,0,64071,0,0,0,0,0,0,26667,7943,0,
+-0,0,0,0,52934,0,0,17002,0,0,0,0,0,0,20294,0,0,0,0,0,0,0,0,0,27301,18347,7974,0,0
+-,0,0,0,0,0,0,16874,0,0,0,0,45414,0,0,0,0,0,0,648,1575,0,0,0,31749,0,0,0,23301,0,
+-0,0,0,0,0,0,0,0,0,0,0,15912,50535,0,0,0,0,1993,8582,0,0,0,0,0,0,0,38438,0,0,0,0,
+-0,0,0,0,0,0,0,0,15850,6183,0,0,0,0,3402,0,0,27494,0,0,749,0,0,0,0,0,0,0,26025,
+-29606,0,0,7144,19622,30504,0,0,0,0,0,0,0,0,21316,0,0,0,0,0,0,0,0,0,21444,0,0,
+-1289,6919,0,0,0,0,0,0,8299,0,0,0,14090,35655,0,0,0,0,0,0,0,0,2377,15206,0,0,6028
+-,4452,0,25508,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50310,0,0,0,0,1269,0,0,0,0,0,0,0,0,0
+-,0,0,0,51014,0,0,0,0,0,0,0,9286,0,7429,0,0,28393,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,16680,452,0,0,0,0,0,23718,0,0,0,31750,0,0,0,0,0,0,0,0,3568,0,0,13604,0,0,
+-0,0,0,25255,0,0,0,50982,0,56582,0,0,7467,0,0,0,0,30181,0,0,0,0,0,0,0,30564,7208,
+-7845,0,0,0,0,0,0,7726,0,0,0,0,62182,0,0,0,41094,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,22695,0,0,0,0,0,0,17736,0,0,0,0,0,0,0,0,50054,0,0,0,14180,0,0,0,0,
+-0,0,8974,0,0,0,0,0,0,0,0,23332,0,0,0,11140,0,0,0,0,0,0,0,24262,27145,9540,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,26537,45510,6062,3879,0,0,20233,25991,0,0,17803,0,0,0,0,0,
+-13962,5508,16971,27013,7437,31494,0,0,0,0,0,0,0,0,0,0,4714,0,0,0,0,0,0,0,0,17189
+-,0,0,0,0,0,27492,0,0,26953,0,0,0,0,0,0,0,0,0,0,41319,0,0,0,0,0,0,0,0,0,0,0,47430
+-,19596,12549,0,0,0,8390,1006,0,0,0,0,0,0,0,0,0,0,24100,17577,4,0,0,0,0,0,22277,0
+-,0,0,0,0,0,0,26692,0,0,0,0,0,24676,0,0,0,0,0,0,0,0,0,0,0,0,0,29477,0,0,0,21573,0
+-,0,0,0,0,0,0,0,0,0,9864,14214,0,0,0,0,0,0,25771,5766,0,0,8909,8679,0,0,6861,
+-16166,0,38887,0,0,0,0,0,0,12392,8678,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-52646,1354,2950,0,14692,0,0,10572,49830,0,0,0,0,0,0,0,0,3626,582,0,0,0,55750,0,0
+-,0,30885,0,0,0,0,0,0,0,0,0,0,0,0,0,5830,0,0,2090,0,0,0,0,0,0,0,0,0,0,0,0,31142,0
+-,0,0,0,0,10503,0,0,18825,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-57158,0,0,30792,63526,0,0,0,9863,16267,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,18824,0,0,0,0,0,0,19653,25388,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9292,0,0,0,0,0,0,0,0,0,0,36358,0,0,0,0,0,0,0,0,
+-0,0,25480,23015,0,0,10440,6725,0,0,0,22436,24265,15109,0,0,0,62311,8906,34534,0,
+-0,0,0,0,0,15913,1319,0,0,20296,1477,30760,0,25928,16772,0,0,1069,0,0,0,0,0,0,0,0
+-,0,0,0,0,17029,0,31909,0,0,0,0,0,0,0,0,0,0,0,41638,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,41542,0,21478,0,0,0,9796,0,0,0,0,0,0,0,0,0,0,22187,58343,0,0,0,24295,0,
+-0,0,0,0,61831,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2833,5829,0,0,0,62855,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,16676,0,0,0,0,0,0,13577,27431,0,0,0,0,21480,10501,0,16932,
+-0,0,0,0,0,22918,0,48294,2574,2150,0,0,0,0,1897,4518,0,0,0,0,0,0,25064,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47942,0,0,0,0,10990,13767,
+-25705,37863,21672,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43430,1712,0,0,0,0,
+-18886,0,0,0,0,0,0,0,0,0,0,0,0,0,10535,0,0,0,0,0,0,0,15012,0,0,0,0,0,0,0,0,0,0,
+-14734,0,0,55782,0,0,30824,10886,0,0,0,0,0,51302,0,0,8012,0,0,0,0,0,20680,6981,0,
+-57415,11,0,0,18277,0,14564,0,0,0,32390,0,0,0,0,0,0,0,0,0,0,0,0,19113,5158,0,
+-11172,0,16774,0,0,0,0,0,0,0,0,0,0,0,0,10315,13830,0,0,0,0,0,0,10410,7141,0,0,0,0
+-,0,18116,0,0,0,44615,15403,13958,0,1540,14632,19525,24201,19781,0,0,0,24165,0,
+-38951,0,0,0,0,0,6308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17416,15749,3438,13255,0,0,0,0,
+-0,0,0,0,0,0,0,32228,0,0,0,0,176,0,0,50566,0,0,0,0,0,0,0,0,0,0,0,0,0,21540,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,58982,0,0,0,0,0,0,0,0,0,5284,0,0,0,0,0,0,25897,28326,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15945,0,0,0,9804,293,0,0,0,0,0,0,0,13988,23082,4677
+-,0,0,0,0,0,0,0,0,0,0,0,5670,0,0,0,0,0,0,0,44070,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,6405,0,30692,0,0,0,61702,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,45926,0,15398,0,0,0,0,0,0,4554,2692,0,0,0,0,0,32485,0,0,0,10084,0,0,0,0,0,0,
+-24297,0,0,0,0,0,0,0,0,22790,0,0,0,55110,0,0,0,0,0,0,0,0,0,0,0,0,7112,0,31530,
+-45255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,40743,17226,22599,0,
+-0,0,0,0,0,0,0,3695,0,0,0,0,0,0,0,0,0,0,56999,0,0,0,0,0,13799,3114,21287,1353,
+-7591,0,0,0,8455,0,0,6824,0,0,0,0,0,0,0,14569,0,0,0,29000,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,19979,0,18376,0,0,0,0,0,0,0,0,0,0,0,0,11332,0,0,0,49863,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,2191,7527,23148,58022,0,0,0,30631,0,26565,0,0,0,0,0,0,0,0,0,0,0,0,754
+-,0,0,15877,0,0,0,0,0,0,0,17510,7657,2821,0,0,0,0,0,0,0,0,0,41927,0,0,0,0,0,0,0,0
+-,2569,34439,0,0,3790,0,0,0,15339,8775,0,0,0,0,0,0,0,0,0,0,0,15908,0,0,21419,8359
+-,0,0,0,0,424,0,0,0,0,0,0,25318,8008,20551,0,0,0,45735,30058,30372,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,26180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31432,10567,0,0,0,0,
+-17450,0,0,0,0,0,0,30310,0,38022,0,0,0,0,0,28932,0,0,0,0,0,43910,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,22180,12075,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22247,0,0,22826,
+-12359,0,0,0,0,4105,50407,0,0,0,0,0,0,13581,28583,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,28936,0,0,0,0,0,17673,10310,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,905,57862,
+-1580,0,0,0,0,58630,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13479,0,0,
+-14153,13286,0,0,9259,0,0,0,0,0,6606,3524,0,0,0,0,0,6567,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,631,49255,0,0,0,0,0,42886,0,38215,0,0,0,0,0,0,0,0,17580,
+-0,0,0,0,0,0,0,0,55046,0,0,0,0,0,0,0,0,0,10213,0,0,0,0,3604,37767,0,0,0,0,0,0,0,0
+-,0,0,0,30950,0,0,0,0,0,0,0,0,0,62087,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23528,0
+-,0,0,0,0,0,0,0,0,28715,4229,0,0,0,0,0,0,0,0,0,0,1226,26820,0,0,0,12133,6984,261,
+-21130,32548,0,0,0,0,0,0,3565,12390,20713,28071,0,0,1706,25287,0,0,0,0,0,0,0,0,
+-14670,0,0,0,0,0,0,30534,0,0,0,12615,0,43750,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28228,
+-0,0,0,0,0,0,0,45095,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1224,3975,10954,6375,0,0,0,0
+-,0,0,0,0,0,0,23180,20100,0,0,0,0,25736,8519,0,0,0,0,0,6663,0,2534,0,0,0,0,0,0,0,
+-0,23720,0,0,0,0,0,0,0,0,0,0,19398,0,47814,26281,49702,0,0,4332,12965,0,0,5704,
+-3206,0,0,0,0,0,0,0,0,0,0,0,0,0,15396,0,0,0,44102,0,0,0,0,0,0,0,0,0,0,0,0,0,25317
+-,1064,39271,27433,0,14952,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14308,0,0,0,0,0,0,2763
+-,4100,0,0,0,0,0,0,18792,0,0,0,22154,32583,0,6244,0,0,0,0,0,0,0,49478,0,0,0,0,0,0
+-,0,0,0,0,0,21894,0,0,11048,0,0,0,0,0,0,11685,0,53862,0,0,15114,0,13870,0,0,0,0,0
+-,0,0,919,0,0,0,31916,0,22570,101,0,0,0,0,0,0,0,0,0,7333,0,0,0,0,3272,0,0,0,0,
+-27718,32712,0,0,0,0,0,0,0,0,0,1782,0,3688,0,0,0,0,29862,0,0,0,0,0,0,0,22469,0,0,
+-0,0,0,0,0,55302,850,15492,0,0,0,5927,19786,13350,0,25702,0,0,0,0,0,0,0,0,0,0,0,
+-40390,0,0,0,0,0,0,0,0,0,0,0,0,0,20260,0,0,0,0,0,0,0,0,0,0,0,0,0,15335,8394,0,0,0
+-,0,0,0,26566,0,0,0,0,843,2245,0,0,0,0,0,0,0,0,6959,0,20488,1638,0,0,11533,50759,
+-0,0,0,0,0,20871,0,0,0,0,0,24519,0,0,0,0,9544,23591,0,0,0,0,0,0,0,0,0,0,20969,
+-7109,29001,0,0,32422,31720,64294,0,0,0,0,16106,0,0,0,6930,4933,0,0,0,22917,0,
+-27015,0,0,0,0,19880,8070,0,0,0,0,23945,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-3310,0,87,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18439,0,0,0,20742,0,0,0,10597,0,0,0,0,0,0,
+-0,0,0,0,0,0,20236,0,0,0,16584,3429,0,0,0,0,0,0,0,0,27241,0,0,0,0,16132,0,0,0,0,0
+-,0,0,0,0,0,0,0,244,28261,0,0,0,0,0,0,0,29509,0,0,0,0,0,0,0,0,2921,31781,0,0,0,0,
+-0,0,6408,4196,344,0,0,0,0,0,0,0,0,0,0,0,0,0,11689,45863,0,0,0,0,906,3301,0,0,
+-25544,32421,0,0,0,0,0,0,0,0,1260,61607,0,27302,0,0,8682,16614,0,0,0,0,10830,0,0,
+-9604,15049,13413,0,0,0,0,0,0,26761,0,0,0,0,0,0,61990,0,0,0,0,0,12580,0,0,11432,0
+-,0,0,0,0,22507,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12389,0,0,0,0,0,0,
+-2408,22661,14507,43239,0,9700,0,0,24714,0,0,0,0,0,0,0,0,23972,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,34086,0,0,22955,7238,0,0,0,0,0,28485,13806,20038,0,0,0,0,22602,0,0,0,
+-1645,22340,0,0,0,0,0,0,0,0,0,0,0,26502,0,0,554,0,0,0,0,61735,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,2694,0,0,0,0,0,0,0,0,0,0,0,0,0,0,883,27879,15948,0,3242,57382,0,0
+-,0,0,0,0,13930,0,0,0,0,0,30922,0,4137,52615,0,0,0,0,0,0,0,0,0,0,0,0,0,31911,
+-16072,0,0,0,0,0,0,0,0,0,0,0,0,26340,0,61671,0,0,0,0,3145,56199,0,0,0,0,0,0,0,0,0
+-,0,0,0,280,0,5131,33479,0,15751,0,0,0,0,0,0,4136,1446,0,0,0,0,0,0,11304,17863,0,
+-0,0,0,0,25125,0,0,0,36646,6057,0,0,0,855,11301,0,0,0,0,0,64774,0,0,0,19397,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,1040,27367,0,0,0,0,0,0,0,0,0,0,0,0,0,64358,0,0,178,
+-132,0,0,14763,24455,0,0,0,46374,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,46246,0,0,0,37382,
+-0,0,0,7462,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8166,0,0,6921,0,0,0,9163,0,0,0,119,
+-0,0,0,23146,17156,0,0,0,0,0,9127,0,0,0,17927,0,0,0,0,0,22084,0,0,0,0,0,39879,0,0
+-,2035,0,1067,0,0,0,0,0,16652,59591,0,0,0,0,0,0,0,0,0,0,0,0,20171,0,0,0,0,17733,0
+-,0,0,0,0,32037,0,0,0,0,0,14277,0,0,0,0,0,0,0,42022,0,0,26793,20358,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,8907,0,0,0,0,0,0,0,0,27780,0,0,0,0,32330,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,39399,0,9732,0,16199,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,854,0,2984,45063,25418,26980,22539,0,9133,3653,15528,28743,4649,0,616,
+-65127,0,0,0,61863,0,0,0,0,0,0,0,55303,0,0,0,0,0,0,0,0,23880,0,0,0,0,0,0,0,31848,
+-62854,0,0,0,0,0,0,0,0,0,0,0,49606,0,27974,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,32580,0,0,0,26052,4043,0,0,40454,0,0,26056,30565,0,0,0,0,0,0,0,31398,0,0,0,0
+-,0,0,0,0,29288,1797,0,0,3220,0,0,0,0,0,0,0,0,0,20427,0,0,0,0,23621,0,0,0,0,0,0,0
+-,0,0,24261,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35591,0,0,6862,0,0,0,4265,0,6285,
+-5383,0,0,0,0,0,36870,0,39847,0,0,17224,5414,27882,58118,0,0,13224,4262,0,0,0,
+-31302,0,0,1388,2982,11881,0,0,0,0,0,0,16837,809,0,24140,10724,0,0,0,0,5835,0,0,0
+-,0,0,0,0,0,0,0,0,1256,19237,0,0,0,0,0,0,0,5796,11848,0,0,52870,11464,0,0,0,0,0,0
+-,0,0,0,5645,9158,0,25223,0,0,0,0,0,39142,24968,8135,32104,28678,0,0,0,46311,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23820,0,0,0,0,0,4050,0,1323,25220,0,0,0,20133,0,
+-0,0,0,0,0,0,0,0,0,0,9381,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,13444,1198,60806,0,0,0,0,17356,50247,30632,0,0,0,0,0,0,0,11944,
+-999,0,0,0,0,4010,10404,0,0,0,0,0,0,10346,0,0,49510,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-38919,0,0,0,0,0,0,6351,60966,20137,487,0,0,0,0,0,0,655,2406,17387,43303,0,0,0,
+-17063,0,0,213,0,0,0,0,0,0,17221,0,0,0,0,0,0,0,0,0,0,0,10820,0,0,0,0,369,6,0,0,
+-9098,21093,0,31653,0,0,0,0,0,0,0,0,0,27143,0,0,16234,0,0,0,0,0,0,0,0,6020,31723,
+-28293,0,0,0,0,1936,30695,0,0,0,0,0,52902,0,0,29512,10791,0,20420,0,0,16010,0,0,0
+-,0,0,0,0,0,0,0,0,5324,0,0,0,0,0,0,0,0,0,0,0,0,13383,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,24328,0,0,0,0,0,0,40870,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,24648,0,0,0,0,0,0,0,7786,2852,0,0,0,0,0,0,0,0,0,44678,0,17925,0,0,105,53062,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18762,0,0,40679,0,0,0,16165,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,20390,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,62310,1322,
+-14247,0,0,0,0,0,0,0,0,1832,6052,0,0,11882,0,0,0,0,17668,0,28262,0,29542,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28007,0,0,0,57223,
+-1585,0,0,0,0,0,0,0,0,0,0,0,21162,0,0,62247,0,0,0,0,0,25414,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,36326,0,0,0,23845,0,0,0,0,0,0,0,2693,0,0,0,0,0,0,0,
+-13125,0,31236,0,0,0,0,0,22502,0,0,0,0,0,0,5994,10309,0,0,0,7269,0,0,0,0,17929,0,
+-1011,44647,0,0,0,0,0,14919,0,0,0,0,20586,5350,0,0,0,45702,0,13189,0,0,0,0,0,0,0,
+-0,0,35782,17992,0,0,0,0,0,8203,0,0,0,0,0,0,56678,0,0,0,0,0,38087,4233,0,2127,0,0
+-,0,0,0,0,0,0,0,0,10148,0,0,0,2021,0,0,0,0,0,0,0,47206,0,0,0,0,0,0,0,9220,0,0,0,0
+-,19465,0,0,0,0,0,0,0,0,39206,0,38055,0,0,0,0,0,0,0,46982,0,0,0,0,0,22054,3850,0,
+-0,0,0,0,0,0,55,0,10542,0,0,0,0,7239,0,0,0,0,0,59367,0,0,14761,0,0,0,0,43079,0,0,
+-0,0,0,2726,0,0,9582,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37478,0,
+-0,0,31364,0,0,0,0,0,0,0,0,20393,8933,0,0,0,0,0,9380,0,0,0,0,16905,549,0,0,0,0,
+-182,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1558,0,0,0,0,0,0,0,19242,0
+-,0,0,0,0,0,24933,0,6276,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42310,23595,
+-24068,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13191,6158,2567,0,0,268,47047,0,0,0,0,0,0,0,
+-0,0,27940,0,0,0,0,0,26726,0,0,0,0,8200,1222,31562,0,0,0,0,0,0,0,0,0,2922,8231,
+-8904,29157,0,0,0,0,0,0,0,0,23976,4836,0,0,0,0,0,0,0,0,0,0,0,0,31658,0,0,31685,0,
+-0,2889,6213,0,0,0,0,0,13605,0,0,0,0,0,24772,0,0,0,0,0,0,0,0,0,0,20684,26468,
+-24075,0,0,0,21193,0,715,679,0,0,0,0,0,0,3050,7654,0,0,0,13798,0,0,0,0,15,27973,0
+-,0,8491,2086,0,0,0,43206,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60391,0,0,0,0,0,0
+-,0,25892,0,22276,0,34374,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20165,0,0,25672,0
+-,0,0,1811,24839,0,31044,0,0,25513,0,0,0,0,0,12810,0,0,62438,0,0,1325,0,364,3782,
+-0,0,0,0,0,0,0,0,8042,19687,0,0,0,33415,0,0,0,0,0,0,0,0,0,0,0,7205,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,11844,0,0,0,0,3341,1543,6698,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,29766,0,0,0,0,0,0,0,0,0,0,0,41158,0,24294,0,3844,12329,
+-0,0,0,13738,0,0,0,0,0,0,0,0,26245,0,0,0,0,0,0,6378,0,343,4838,0,0,0,24358,11688,
+-0,0,0,0,0,0,0,0,0,1489,34759,0,0,0,0,363,51974,1878,11013,0,0,32265,59782,0,0,0,
+-28421,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22756,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14089,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,29257,61222,0,30661,0,28327,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-27108,8843,0,9673,2084,0,0,0,16327,0,48455,0,0,0,0,0,0,4876,9316,0,0,0,0,0,0,0,0
+-,0,0,0,0,9035,18852,0,0,0,0,0,0,0,0,0,0,0,0,0,4164,0,0,14827,1349,0,0,0,0,0,
+-11909,0,0,0,0,0,0,0,0,0,21765,0,0,0,0,0,0,0,0,31272,63910,0,0,0,25924,0,0,0,0,0,
+-0,0,0,0,44487,0,0,0,20612,0,0,27754,31428,0,0,0,0,0,0,0,17287,0,3943,0,0,0,63302
+-,0,0,0,0,25256,19942,0,55142,0,39046,0,0,0,0,0,0,0,15367,0,0,0,0,0,0,0,0,0,0,0,
+-28422,0,0,0,0,0,0,0,0,0,0,0,0,9576,63847,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,25226,5734,0,0,0,0,0,0,13801,4997,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,43942,1270,2566,6284,0,0,16230,0,0,0,20678,0,0,0,0,0,38855,0,0,0,0,
+-29643,0,0,0,41,3655,0,0,0,0,0,14276,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,15686,0,0,0,15718,0,50694,0,0,16232,8007,0,0,0,5060,
+-329,11591,51,0,0,0,0,0,0,0,0,0,13065,7302,27530,15366,0,24934,0,0,0,17828,0,0,
+-4552,6311,0,0,0,0,0,0,0,0,0,0,0,47686,368,12103,10122,33830,0,0,599,18534,9579,
+-49479,0,5668,0,0,0,0,0,0,0,0,0,13157,0,0,0,0,23274,14055,0,0,0,0,0,48903,0,0,0,0
+-,0,0,1871,0,15434,0,0,0,16174,62470,0,0,0,0,0,0,0,0,0,0,0,7749,0,0,0,0,0,0,0,
+-30501,0,0,0,0,25675,0,0,0,0,0,0,0,0,0,0,9285,0,0,25323,1669,0,0,0,0,0,0,0,0,0,0,
+-0,3588,0,0,0,0,0,32902,0,0,4426,0,0,0,0,57959,0,0,0,0,0,0,29898,58278,0,0,0,0,
+-11880,1220,0,0,0,41479,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23141,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,42566,0,0,0,0,0,0,0,40167,9484,3493,0,0,0,0,0,21126,0,0,0,0,8649,18918,0,0,
+-0,0,0,0,0,34886,2601,0,0,0,0,12518,0,0,0,0,7976,10311,0,0,0,0,0,0,0,45190,0,0,0,
+-0,0,0,0,0,0,0,16842,20229,0,0,0,0,0,0,7528,4614,0,0,0,0,0,30086,0,0,0,1671,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,9896,6277,0,0,0,0,0,61191,0,41287,0,21956,0,0,20010,0,0,0
+-,0,0,0,0,0,0,0,0,13195,0,0,0,0,1381,0,0,0,0,365,30951,24268,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,7044,0,0,0,0,0,0,0,0,0,0,27944,359,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,28487,0,0,77,0,0,0,0,0,0,0,0,56775,12586,8421,0,0,0,0,0,0,26185,14599,0,0,
+-8040,5702,12585,3109,0,0,0,0,0,21574,5388,0,0,0,0,0,0,0,5106,52454,0,0,0,0,0,0,0
+-,0,1907,29895,0,6116,0,0,0,0,11081,5285,0,28069,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4104
+-,0,0,0,0,0,0,41511,0,0,0,0,0,0,5262,0,0,0,503,4231,7720,34343,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7304,10374,1718,0,0,29127,0,0,0,0,0,0,0,0,23497,
+-22567,6952,2340,0,0,0,0,0,0,0,0,20360,12453,0,45094,0,0,0,0,0,28582,0,0,0,0,680,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,23084,0,0,0,30696,0,0,0,0,45862,0,0,0,0,0,0,0,0,0,0,0,
+-0,5580,6053,0,0,0,0,0,0,0,0,0,0,712,70,0,0,26091,11335,0,0,0,0,13612,0,13160,
+-1926,435,51559,0,0,0,0,0,0,0,0,0,0,0,0,0,47302,19083,0,0,12742,0,1607,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,6155,37095,0,0,0,0,0,18948,7146,0,0,0,0,0,0,0,7848,
+-2055,0,0,0,0,8910,0,19336,0,0,48070,8490,0,0,0,0,0,0,0,9932,56423,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,4133,0,0,0,0,0,0,0,0,0,43398,0,0,0,0,0,0,0,0,16173,0,0,0,0,0
+-,0,0,32011,0,0,30918,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26854,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,20389,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18889,0,0,0,0,8965,0,0,0,44358,0,0,0,8997,0
+-,34055,0,0,0,0,0,29350,0,0,501,17767,0,0,32457,60262,0,0,0,30886,0,0,3757,1063,0
+-,0,0,25637,0,0,0,0,0,28068,0,26374,0,0,0,0,0,0,0,0,0,0,0,11684,0,0,0,0,0,0,24779
+-,229,0,13766,0,0,7402,11525,0,0,0,0,0,0,0,0,26313,23686,0,0,29736,47527,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27268,0,0,0,0,553,0,0,0,0,0,0,32038,0,0,0,0,1135,
+-26596,0,0,12300,14631,0,0,0,43238,0,871,0,0,31496,0,8457,17669,0,12836,0,0,0,
+-22726,0,38758,0,0,375,6564,0,0,0,0,0,0,0,0,0,0,0,0,170,18535,0,22948,0,0,32360,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,25764,0,0,0,0,0,0,0,0,0,0,0,15652,0,0,0,32774,0,0,0,0
+-,0,0,0,0,0,28551,0,0,0,0,0,0,0,0,0,0,0,0,15145,0,0,0,21100,27654,0,0,0,0,0,0,
+-4874,26215,0,1639,0,0,0,0,0,0,0,0,0,0,4169,0,0,0,0,0,7336,0,0,0,0,21572,0,0,0,0,
+-0,0,0,0,0,24644,1675,2533,0,0,0,53318,0,13094,0,0,0,0,0,0,0,6246,0,22020,0,0,0,0
+-,0,0,0,0,0,0,0,28453,5576,5124,0,0,0,0,0,0,0,0,0,0,0,0,0,27910,0,29382,18216,
+-8583,0,0,0,39174,0,43558,0,0,0,0,0,0,0,0,0,11973,0,0,0,0,0,23397,0,0,0,0,6091,0,
+-0,0,0,0,0,0,6474,16197,14217,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,26728,0,567,48839,0,0,0,0,0,15271,0,0,31818,43974,2450,0,0,0,0,0,0,0,
+-11368,9191,0,44454,0,0,0,0,0,0,14568,12293,0,0,0,8453,0,0,0,0,0,0,0,0,0,0,0,0,
+-32040,0,0,0,0,0,0,0,0,0,0,0,0,902,0,0,0,27236,5612,11495,0,0,0,0,0,0,0,0,9194,
+-23684,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27430,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-26217,44870,0,0,0,0,0,0,5581,7173,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-52775,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20968,18340,0,0,0,0,0,0,0,0,4107,11239
+-,0,0,0,0,0,0,0,0,0,0,0,29381,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21990,0,0,0,0
+-,0,0,0,0,0,48806,0,0,0,32292,0,0,0,0,0,0,0,10884,0,0,0,0,0,0,0,0,0,0,27562,0,
+-5643,0,0,0,0,0,0,0,0,0,3089,31525,0,19684,0,0,0,0,0,0,0,61415,0,0,0,0,0,36198,0,
+-0,0,0,0,0,0,7908,0,0,0,0,872,743,0,0,0,0,0,0,0,0,1229,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,32484,0,0,0,0,0,34822,0,0,0,0,0,50726,0,0,0,0,7274,0,0,0,15304,
+-11526,0,0,0,3047,0,0,0,0,0,0,22376,0,0,0,846,0,0,0,0,35815,0,0,0,23652,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,23721,2148,0,0,0,0,0,0,14856,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,1358,0,3082,0,0,0,848,10949,0,0,0,0,0,0,6504,0,0,14372,0,0,0,0,0,0
+-,0,0,0,0,8201,9958,0,0,0,0,0,0,24266,0,0,0,0,0,0,0,0,26469,0,0,0,0,18604,2053,0,
+-33511,0,0,0,0,0,9222,0,0,0,0,0,44006,0,0,0,0,0,0,0,0,0,0,0,41895,0,0,0,0,0,0,0,0
+-,12044,390,0,0,0,0,0,4935,0,48646,0,56102,3052,16070,0,0,0,0,0,0,0,8612,9320,
+-38311,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,500,0,0,0,0,42918,0,
+-32550,0,0,0,0,0,0,0,0,27434,57926,17064,0,0,46502,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,26760,6756,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,624,0,5000,0,0,0,0,32293,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,26246,0,0,0,0,0,0,0,0,23,7301,0,0,0,36199,0,40838,0,0,0,
+-0,0,0,0,0,0,0,0,0,27178,57350,0,0,12457,9317,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16810,0,0,0,14510,0,0,0,0,21319,0,0,0,13508,17,
+-11365,0,0,0,0,5291,0,8329,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27685,0,0,0,0,0,0,0,
+-52006,0,0,0,7493,0,44263,0,0,0,0,0,0,0,0,9800,0,0,0,25676,61478,0,0,0,0,0,0,5773
+-,0,0,0,0,41991,26057,0,0,0,0,0,0,0,0,0,0,22629,0,0,0,47783,362,1959,23468,0,0,0,
+-10921,0,0,0,3150,0,0,0,0,0,0,0,0,0,0,0,32456,0,0,0,0,0,0,0,4559,3270,0,0,983,0,0
+-,26343,0,33446,0,0,0,61767,0,48390,0,0,0,0,0,0,0,2790,0,39782,7849,0,0,0,0,0,0,0
+-,1544,2183,0,0,0,0,0,0,0,0,4040,2471,20009,30020,0,0,11242,0,0,0,5578,53382,0,
+-22631,0,0,0,0,0,0,0,0,0,0,0,12901,0,0,0,0,0,0,0,0,0,0,0,0,215,0,0,9030,0,0,0,0,0
+-,0,265,1412,0,0,11626,3687,0,0,0,0,0,0,0,0,0,0,0,0,17449,24359,0,0,26729,40134,0
+-,0,0,0,29768,61958,0,0,0,0,0,0,0,0,20908,0,0,0,0,0,11016,0,0,47462,21547,5926,0,
+-0,14728,2983,24104,15301,0,0,0,0,0,32645,0,0,0,0,0,0,0,3300,0,0,0,15972,0,0,0,0,
+-0,0,6634,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3076,0,30983,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,106,0,0,0,0,12775,0,0,0,0,7177,18022,0,0,0,0,0,22534,0,0,0,0,0,0,0,0,0,0,0,
+-49894,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27560,0,0,0,0,30278,10668,23877,0,
+-0,0,0,0,0,0,29124,0,0,0,0,0,0,0,0,0,0,0,0,0,20870,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,44582,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48454,0,0,0,0,6442,0,16330,22951,0,0
+-,16904,0,0,0,0,644,0,0,0,40038,0,0,0,37222,0,0,0,9830,0,0,0,0,0,34919,0,0,0,0,0,
+-0,0,0,0,0,0,13733,0,0,0,28196,0,0,0,0,0,19876,0,0,0,0,0,0,0,23558,0,11142,0,
+-27781,0,0,0,0,13864,0,0,0,24682,47847,0,0,0,0,6890,0,0,0,0,0,3981,0,0,0,0,0,0,0,
+-0,0,0,0,1772,0,0,0,0,0,0,0,3603,1991,0,27396,8652,0,18312,0,0,0,0,30054,0,0,0,0,
+-0,0,0,11270,0,0,0,0,0,0,0,0,0,20708,0,0,0,0,338,0,0,0,0,0,0,0,7050,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,14862,0,0,3492,0,0,0,55878,0,0,0,16486,0,0,0,18119,0,0,0,0,0,0,2154
+-,1284,0,0,23113,31751,0,0,29547,0,0,0,0,0,0,36647,0,0,0,0,0,0,0,0,0,0,0,18183,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,7913,0,0,0,0,20644,0,0,10508,0,0,0,0,0,0,0,0,0,0,0,0,
+-43622,0,0,0,0,0,40966,0,0,0,0,0,0,0,0,0,0,246,901,11529,5191,0,0,0,0,0,0,0,0,0,0
+-,0,24454,0,0,26665,27590,0,27397,0,0,0,0,0,0,23562,2949,0,0,30344,62214,0,47334,
+-2026,18885,0,0,0,48678,0,0,0,22694,0,0,1972,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,15465,0,0,0,0,38822,0,0,0,0,945,32708,0,54791,0,14918,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,23396,0,0,0,0,0,0,5486,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7722,0,0,
+-0,0,0,0,0,0,0,0,0,30856,64166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35206,0,0,0,30535,0,
+-0,0,0,0,0,0,0,0,62663,0,0,1096,17574,31820,0,0,14375,4402,27207,0,0,21448,4676,0
+-,0,0,0,16585,5094,0,0,0,0,0,0,0,0,4845,0,0,32870,0,0,0,0,0,0,0,0,0,0,31466,0,0,0
+-,0,31783,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4522,16039,0,0,0,0,0,0,0,0,
+-0,14469,0,0,0,0,0,0,0,0,0,0,7464,4773,0,0,0,0,0,0,0,0,18636,0,0,0,25640,0,0,0,0,
+-0,0,2244,0,0,11818,0,1168,0,0,0,0,0,0,0,6540,23079,13770,7719,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,58150,528,
+-34502,32682,0,0,12997,0,0,0,0,0,2214,0,0,0,0,0,58567,0,0,0,26375,0,0,0,0,0,0,0,0
+-,0,26437,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26121,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,32005,22952,59047,0,13543,0,0,0,0,0,0,0,0,16328,0,0,33542,0,0,0,19782,0,0,0,
+-16644,0,0,0,0,31688,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10276,0,0,0,
+-0,0,0,0,36327,0,0,29480,0,0,0,777,12709,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27398,0,0,
+-0,4455,9037,31397,0,9221,0,0,0,60487,20840,1796,0,0,0,0,0,0,0,0,8364,0,0,0,0,0,0
+-,0,0,0,0,0,19752,44902,0,38566,0,0,18027,0,0,0,0,0,0,0,0,10662,0,0,0,0,0,11812,0
+-,0,0,0,0,0,0,0,0,19910,0,0,0,45030,0,0,0,0,0,0,0,0,0,0,0,0,19978,5127,0,11620,0,
++BROTLI_INTERNAL const uint16_t kStaticDictionaryHashWords[32768] = {
++1002,0,0,0,0,0,0,0,0,683,0,0,0,0,0,0,0,1265,0,0,0,0,0,1431,0,0,0,0,0,0,40,0,0,0,
++0,155,8,741,0,624,0,0,0,0,0,0,0,0,0,0,0,0,66,503,0,0,0,451,0,0,0,0,0,0,0,835,70,
++0,0,539,0,0,0,0,0,0,0,0,0,113,0,0,0,0,718,0,0,0,0,0,0,520,0,1070,0,0,0,0,0,1515,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,78,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,610,0,0,750,0,0,0,307,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,964,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,999,0,0,0,0,0,0,0,0,
++645,75,0,649,52,282,0,200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1621,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,211,225,0,0,687,718,0,0,110,0,58,0,0,0,0,0,0,345,0,0,301,0,0,
++0,203,0,0,1154,674,1949,0,0,0,0,0,0,0,0,0,259,0,0,0,0,0,0,0,1275,0,0,0,1231,254,
++0,0,0,0,0,0,0,277,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,0,0,800,0,0,0,29,
++116,100,490,0,0,0,0,0,1641,0,543,0,0,0,0,41,181,0,657,0,0,202,25,0,0,0,0,0,0,0,
++0,0,0,423,0,0,0,113,0,0,0,927,963,0,976,0,206,0,0,0,0,0,0,0,0,0,2002,0,0,0,0,0,
++0,0,0,0,0,0,696,0,1170,0,0,0,0,226,13,0,769,678,551,0,0,0,0,0,0,57,0,0,0,10,188,
++0,0,0,624,0,0,0,0,0,0,0,0,0,1941,130,0,0,0,0,378,269,0,0,528,0,1146,0,0,0,1105,
++0,1616,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,656,0,1940,0,0,0,0,0,173,0,0,0,0,0,0,0,0,0,
++0,0,457,342,810,0,0,0,0,620,0,0,0,0,0,0,0,967,95,447,406,0,0,0,477,0,1268,944,
++1941,0,0,0,629,0,0,0,0,0,375,0,0,0,1636,0,0,0,0,774,0,1,1034,0,0,0,0,0,824,0,0,
++0,0,0,118,0,0,560,296,0,0,0,0,0,0,0,0,1009,894,0,0,0,0,0,0,0,0,0,0,0,0,0,1474,
++366,0,0,0,0,0,0,0,0,0,79,1723,0,0,200,0,0,0,0,0,0,0,0,1759,372,0,16,0,943,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,258,0,0,900,1839,707,30,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,2004,0,0,10,115,0,50,0,0,0,0,0,0,0,0,0,0,520,1,0,738,98,482,0,0,0,0,
++0,0,0,0,0,0,701,2,0,0,0,0,0,0,0,0,557,0,0,0,0,0,0,0,0,0,347,0,0,0,0,572,0,0,0,0,
++0,0,0,0,0,832,0,0,797,809,0,0,0,0,0,0,0,0,0,0,0,528,0,0,0,861,0,0,294,0,0,0,109,
++0,0,0,0,0,0,0,0,1187,290,266,0,0,0,0,49,50,748,0,0,466,399,0,0,0,0,0,0,0,378,0,
++519,0,0,0,0,0,0,0,0,0,0,0,0,667,351,902,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,180,
++0,0,869,0,0,0,0,0,0,0,260,0,0,0,0,0,0,0,0,0,0,523,36,0,0,587,510,809,29,260,0,0,
++0,0,0,0,0,0,570,0,565,0,1464,0,0,0,0,0,0,10,0,0,787,399,380,200,0,0,0,0,516,0,
++844,887,0,0,0,0,0,0,0,44,0,0,0,305,1655,0,0,0,0,0,0,0,0,0,0,0,0,0,0,786,10,0,0,
++0,0,0,0,0,0,0,2031,0,0,0,0,0,684,0,0,0,0,0,1480,0,0,0,27,0,0,0,395,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,813,511,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,0,0,0,206,
++496,0,0,0,0,0,909,0,891,0,0,0,0,0,0,0,0,0,687,0,0,0,1342,0,0,0,0,0,0,0,0,0,0,
++160,41,0,0,0,0,0,0,0,0,0,0,0,1718,778,0,0,0,0,0,0,0,0,0,0,1610,0,0,0,0,0,115,0,
++0,0,0,314,294,0,0,0,983,178,193,0,0,0,0,0,0,0,0,0,174,0,0,0,0,0,0,0,0,0,0,848,
++1796,0,0,0,0,0,0,221,0,687,1660,0,0,0,0,262,0,0,179,0,0,0,0,0,66,0,773,0,352,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,0,152,0,0,1197,0,0,0,0,0,0,0,0,0,0,0,0,560,0,0,
++564,0,0,0,797,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,556,0,819,0,0,0,0,0,0,0,0,719,544,
++637,5,0,0,0,0,0,0,0,0,0,0,0,101,0,1441,0,0,0,893,0,0,0,0,0,0,0,0,0,238,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,1296,0,0,969,1729,314,60,0,0,0,0,0,1144,0,1147,0,0,0,0,0,
++0,0,0,0,0,437,1853,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,828,0,176,0,0,0,0,0,0,434,39,0,
++0,0,0,0,159,0,0,0,902,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,270,0,0,0,0,801,556,0,0,
++0,0,0,0,0,416,19,197,369,0,0,0,0,0,0,0,0,0,28,34,0,757,0,0,898,1553,0,721,0,0,0,
++0,1012,0,0,0,0,1102,0,898,183,0,0,0,0,0,0,0,136,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,247,277,0,0,0,435,0,0,0,0,0,1311,0,0,0,0,
++0,0,211,437,0,0,0,28,0,0,750,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2012,0,702,
++0,808,0,0,0,0,739,166,0,0,0,0,0,0,719,170,500,0,0,0,0,0,0,0,0,1500,327,0,0,450,
++0,0,0,1318,0,0,0,1602,0,0,331,754,0,0,0,0,0,1368,0,0,557,0,0,0,799,850,0,0,0,0,
++0,0,0,0,908,0,0,0,0,0,19,62,459,0,0,0,0,0,0,0,0,0,0,0,0,1802,0,0,0,0,0,0,0,0,0,
++1397,0,0,0,0,120,238,0,0,0,0,0,0,0,0,0,0,0,1324,0,0,0,0,0,0,0,0,602,201,0,0,164,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,615,0,0,0,0,0,0,0,0,0,0,0,0,0,1243,0,0,0,0,968,0,0,
++0,0,0,0,882,0,0,0,907,329,100,0,0,0,0,0,0,0,0,0,0,0,176,26,9,0,0,265,256,0,0,0,
++0,0,0,0,0,0,643,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,610,0,0,0,0,973,2001,0,
++0,0,0,0,0,522,0,0,0,0,0,0,0,0,0,0,0,553,0,0,0,0,0,0,1582,0,1578,0,0,0,0,0,0,0,0,
++0,0,0,795,0,0,0,432,0,0,0,0,0,0,84,126,0,0,0,0,790,0,377,64,0,1529,0,0,0,0,530,
++1857,539,1104,0,0,0,0,0,0,0,0,0,0,0,0,977,0,0,0,34,0,0,0,0,0,0,0,0,0,0,0,24,26,
++0,0,918,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,183,379,0,0,0,0,0,0,0,792,
++0,0,0,0,0,0,0,0,0,1920,0,0,0,0,0,0,0,0,0,771,0,0,0,1979,0,901,254,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,140,0,0,0,0,0,440,37,0,
++508,0,0,0,513,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,533,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,752,920,0,1048,0,153,0,
++0,391,0,0,1952,0,0,0,0,0,0,0,0,0,0,126,0,0,0,0,640,0,483,69,1616,0,0,0,0,0,734,
++0,0,0,0,0,0,480,0,495,0,472,0,0,0,0,0,0,0,0,874,229,0,0,0,0,948,0,0,0,0,0,0,0,0,
++1009,748,0,555,0,0,0,0,0,0,193,0,653,0,0,0,0,0,0,0,0,0,0,984,0,0,0,172,0,0,0,0,
++0,0,0,0,83,1568,0,0,384,0,0,0,0,0,0,0,164,880,0,0,0,0,0,0,0,0,0,0,0,367,121,0,0,
++828,0,0,0,0,0,0,0,1541,0,0,0,0,0,0,0,343,0,0,0,0,0,0,0,0,561,57,0,0,0,0,0,0,0,
++926,0,0,0,0,827,0,194,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22,0,0,0,0,0,0,0,
++0,0,0,896,1249,0,0,0,0,0,1614,0,0,0,860,0,0,0,0,0,0,0,0,964,102,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,899,0,569,0,0,0,0,795,2045,0,0,0,
++0,0,0,104,52,0,0,0,0,0,604,0,0,0,0,779,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,
++494,0,677,0,0,0,0,0,0,0,508,0,0,0,0,0,0,0,0,0,1014,0,957,0,0,630,310,0,0,0,570,
++0,0,449,0,64,537,0,0,0,0,0,0,0,244,0,0,0,0,0,0,0,0,0,0,0,0,0,0,702,1650,49,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,338,0,0,0,0,1279,0,0,0,0,0,0,0,896,0,0,
++178,0,0,0,0,0,0,0,0,0,0,0,0,0,808,695,0,0,0,0,539,1117,0,0,0,0,0,0,0,0,257,0,
++1003,0,0,0,1,448,0,516,0,0,960,0,125,4,0,1268,30,748,0,0,852,0,0,0,6,0,0,848,
++236,1385,862,1811,0,0,0,0,698,803,0,0,0,0,0,0,0,610,992,0,0,878,0,1847,0,0,0,0,
++0,0,0,383,0,1404,0,0,0,0,986,0,347,0,0,0,0,0,0,0,0,0,0,0,592,572,0,1411,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,606,0,0,0,0,0,0,
++0,0,0,0,0,0,0,1829,0,0,0,0,0,0,0,0,0,0,0,0,700,748,0,0,0,0,0,0,365,0,0,127,0,0,
++83,198,0,0,0,0,0,0,864,55,0,0,0,0,726,1752,0,0,0,0,0,0,0,0,0,0,0,0,0,1066,0,764,
++0,0,0,0,683,0,550,309,0,0,874,1212,0,0,0,1364,0,986,381,723,0,0,0,1573,0,0,0,0,
++0,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1559,0,0,0,0,493,133,0,0,0,0,148,
++119,0,0,0,0,0,0,537,14,541,0,635,126,0,0,0,495,0,0,0,0,861,998,1009,0,0,0,0,0,0,
++0,359,368,0,0,0,0,304,1577,0,0,0,0,0,1107,0,0,0,0,0,929,0,0,0,1142,0,0,0,0,289,
++175,0,432,0,219,0,0,0,0,0,785,0,0,595,0,0,0,0,0,0,0,0,0,0,0,0,0,80,0,0,0,0,0,0,
++931,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1323,0,0,0,0,290,0,559,1751,127,0,0,0,
++934,1167,0,963,0,260,0,0,0,573,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++580,1689,0,0,0,0,0,0,0,0,0,1164,0,0,982,1922,0,63,0,0,0,0,0,793,0,0,0,0,0,0,0,0,
++0,0,0,0,0,67,790,0,0,0,0,0,0,0,0,0,0,391,443,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,271,0,0,0,0,0,0,0,0,0,0,0,1140,0,0,0,0,340,300,0,897,0,0,0,0,0,0,
++0,0,0,0,890,0,0,0,0,818,321,53,0,0,0,0,0,0,0,0,0,468,0,243,0,870,0,0,0,1765,121,
++0,0,0,180,518,0,822,419,634,0,0,0,0,0,0,0,0,0,898,0,0,0,0,454,36,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,806,0,0,0,0,0,0,0,0,0,0,0,0,1326,0,104,0,0,0,0,0,0,0,
++0,0,260,0,0,0,0,0,0,0,0,0,0,0,0,542,45,0,0,263,1516,42,0,0,0,0,0,468,0,1005,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,288,87,0,0,0,0,0,0,0,0,502,988,133,0,0,0,0,0,0,
++141,0,0,872,1842,0,0,0,0,0,0,0,0,261,619,0,0,0,0,189,246,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,678,0,0,0,0,0,0,0,0,0,0,0,0,285,35,0,517,0,0,0,0,0,0,0,0,0,0,
++540,214,667,0,74,0,0,125,0,0,0,0,0,761,131,0,0,0,0,0,0,0,0,0,0,0,0,0,333,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1338,94,0,0,0,0,0,0,0,0,0,0,0,0,449,0,646,103,
++86,641,2028,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,869,87,277,117,39,0,0,0,0,0,0,0,0,938,
++297,0,0,0,0,558,464,0,0,0,0,0,0,0,0,0,0,731,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1608,0,
++0,0,0,0,0,0,1429,0,0,733,1010,0,0,338,1656,0,0,0,1038,979,2010,0,0,0,0,0,0,0,
++1005,0,0,121,0,0,0,219,20,0,0,0,0,0,0,872,1440,0,0,0,683,0,1070,0,0,522,0,0,0,0,
++439,669,0,0,0,0,0,0,0,0,1245,0,0,0,0,0,1218,0,0,547,233,0,0,0,0,0,0,0,0,0,482,0,
++0,0,0,0,0,0,886,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,795,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,371,0,0,0,0,0,0,0,0,0,0,0,0,0,622,0,625,0,0,0,339,29,0,0,338,0,0,0,
++0,130,0,0,0,0,0,0,0,0,0,307,0,0,0,0,0,0,0,0,0,0,2044,0,0,0,0,0,0,0,0,308,770,0,
++0,0,0,0,1266,0,0,0,0,0,0,0,0,0,400,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,690,739,0,0,
++0,0,0,0,0,990,0,0,0,1831,0,0,0,0,0,0,0,0,0,0,0,0,0,613,0,0,0,0,0,0,0,0,0,0,0,0,
++0,763,0,878,0,0,0,977,0,100,0,0,0,0,0,0,0,0,0,463,0,0,0,0,623,318,0,0,296,463,
++137,0,0,454,0,0,0,1527,58,0,0,0,0,0,0,0,18,48,0,0,0,0,0,729,0,0,0,442,0,0,0,0,
++40,449,0,853,0,0,0,0,0,0,227,0,0,0,0,0,0,1491,0,0,0,0,0,0,0,0,0,0,161,55,0,450,
++0,1174,62,0,207,0,0,0,0,0,0,0,0,869,0,0,0,0,80,213,0,0,0,0,0,0,0,0,0,0,354,820,
++0,0,747,0,0,0,954,0,0,1073,0,556,0,0,0,692,0,191,0,804,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,831,162,0,0,35,0,0,0,0,0,0,0,0,1235,0,0,0,0,0,1234,0,0,
++0,0,0,0,0,0,0,0,96,0,0,0,0,0,0,0,149,0,0,0,902,204,0,0,833,0,287,366,0,0,0,0,0,
++0,992,2020,0,0,0,0,0,0,0,0,0,0,0,356,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,784,0,0,567,
++630,0,0,0,539,0,0,27,0,0,0,0,0,0,0,0,0,0,755,0,0,0,0,0,0,0,0,0,0,0,0,814,0,0,0,
++0,0,0,0,0,0,0,0,0,0,987,0,0,255,761,194,0,1086,0,0,0,0,0,0,1016,0,0,1396,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,562,271,913,0,0,0,0,0,0,0,0,320,153,45,475,0,0,
++0,0,0,0,0,713,0,327,0,0,0,0,0,0,604,552,3,359,0,0,0,0,853,80,0,0,0,0,0,0,0,2016,
++6,887,0,0,0,0,975,0,961,0,0,0,0,0,916,1891,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,100,101,390,708,0,0,0,587,983,512,0,0,0,0,0,0,0,0,0,0,0,645,0,0,0,851,0,0,0,
++0,0,498,140,217,0,0,0,1448,0,0,0,0,0,0,0,0,0,905,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++643,105,0,792,0,0,0,0,0,0,0,0,0,0,0,0,56,0,0,0,0,0,0,0,0,0,0,535,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,1748,0,0,0,0,0,754,0,0,0,0,0,0,0,0,0,0,0,0,91,0,0,1565,0,91,792,
++939,3,370,0,0,0,0,95,0,0,0,0,551,7,619,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1150,0,
++0,0,0,0,0,0,0,0,0,0,0,0,671,0,0,0,0,0,888,368,149,0,0,105,1134,0,983,0,0,458,31,
++0,643,0,0,0,312,0,740,0,0,0,1642,0,0,0,0,0,0,0,236,0,0,0,0,0,0,0,59,68,0,0,0,0,
++0,867,795,0,0,0,0,970,1977,0,0,0,0,0,0,0,1148,0,775,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,970,0,0,0,0,0,0,0,0,0,665,71,0,0,0,0,827,0,0,0,0,0,0,0,0,0,
++0,479,0,0,0,0,0,0,0,0,99,607,0,0,0,0,0,0,0,1960,0,0,0,793,0,0,871,41,0,0,241,94,
++0,0,0,0,209,0,0,1497,0,0,0,0,0,0,0,0,0,98,0,0,0,463,0,0,0,0,291,0,0,0,0,0,0,0,0,
++0,0,984,0,0,0,0,0,205,0,0,0,0,0,0,205,42,0,801,0,0,0,0,0,635,0,0,533,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,371,0,1282,0,0,0,825,0,0,0,0,0,0,0,0,0,357,879,467,0,317,0,0,
++0,0,0,0,0,924,0,0,0,0,849,1795,0,0,0,0,895,1799,43,0,0,0,0,0,0,0,0,0,0,1820,0,0,
++0,0,0,0,0,525,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,110,0,493,0,174,417,0,0,
++0,0,0,583,733,0,0,0,0,0,0,481,215,0,0,0,0,477,0,0,0,0,0,0,0,0,308,0,0,0,0,0,0,0,
++0,297,126,0,0,361,1551,0,0,0,0,0,0,871,1807,0,0,0,0,0,1307,0,685,0,0,0,0,0,0,0,
++797,0,858,0,565,0,0,0,0,0,0,0,0,0,0,0,0,434,252,826,0,0,0,0,0,0,791,0,0,0,0,509,
++231,178,601,0,0,0,0,0,0,0,0,43,1591,0,0,0,0,0,1683,0,0,0,0,45,0,0,0,0,0,0,0,0,0,
++0,1120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,556,494,0,398,0,0,0,1030,0,0,0,0,0,0,
++168,0,0,0,0,0,0,0,0,0,0,973,0,642,0,0,0,0,0,0,0,0,0,1615,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,378,594,0,1093,0,679,112,0,0,0,0,1492,540,1374,714,
++1486,0,0,0,0,825,1511,0,0,0,0,0,0,0,0,0,0,0,0,0,952,0,0,736,143,0,700,0,1540,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1557,0,0,0,860,990,0,0,0,807,0,0,0,0,0,131,
++515,0,646,0,0,0,0,117,728,508,121,0,0,0,0,0,0,357,0,0,0,0,0,0,237,0,0,0,0,0,0,0,
++0,0,1784,0,0,0,0,0,0,0,0,0,0,0,713,348,1536,0,738,0,0,0,0,0,0,0,434,0,0,0,0,0,0,
++366,1877,39,0,0,0,0,0,0,580,0,0,0,0,0,0,0,0,0,0,0,0,0,0,873,0,0,0,0,171,0,625,
++550,107,343,943,0,0,0,0,0,0,0,768,0,0,0,0,0,0,0,799,0,0,0,894,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,1673,0,0,0,0,0,0,0,0,0,0,0,1052,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++272,0,441,0,0,3,9,0,0,0,1182,0,1346,0,0,0,0,0,0,0,0,682,0,0,1004,24,0,0,968,0,0,
++0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,185,0,0,0,578,
++474,0,0,0,0,0,0,0,0,0,0,0,0,0,0,113,530,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,556,0,0,0,0,0,0,16,1317,0,0,97,0,0,0,703,0,0,0,0,0,0,0,0,892,0,0,0,1571,0,0,
++426,186,0,1101,0,0,0,0,0,0,0,0,937,585,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,644,291,
++0,0,0,0,749,0,162,0,0,381,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,762,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,628,21,0,0,0,0,0,0,0,0,919,0,0,0,0,0,0,0,0,0,
++633,0,0,0,0,332,0,0,0,0,0,0,0,0,0,1489,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,832,398,0,645,0,0,0,13,0,0,0,0,0,0,0,0,0,0,20,0,800,0,0,0,0,0,0,0,0,0,
++0,0,0,0,1993,0,0,0,0,769,0,0,0,665,0,0,0,0,0,0,0,0,0,0,1426,0,0,0,0,60,0,0,0,
++641,1874,0,644,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1757,0,0,0,0,0,937,0,1652,0,654,0,
++0,0,0,0,0,0,527,0,0,0,0,0,0,0,0,0,0,0,0,0,226,0,0,0,0,0,1486,0,0,0,0,0,0,0,0,0,
++0,0,325,0,0,0,0,0,0,0,1345,0,0,91,0,404,0,0,0,0,0,0,0,0,0,0,0,0,973,0,0,0,0,0,0,
++0,1176,0,549,0,0,0,0,0,0,0,0,0,0,976,0,0,0,0,0,21,0,0,0,0,0,51,0,0,0,0,314,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,198,6,0,1093,0,0,0,0,0,0,0,0,0,
++0,0,0,0,1776,0,0,0,0,0,1528,0,419,0,0,0,0,0,0,0,0,76,138,0,0,0,0,638,29,0,0,0,0,
++0,0,0,1418,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1710,0,0,0,0,0,
++0,0,0,0,0,0,0,532,23,0,0,0,0,0,0,0,862,0,0,946,592,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,70,0,0,0,0,0,0,0,0,0,812,0,0,0,76,0,0,988,0,442,0,0,0,896,0,0,0,0,0,0,
++483,0,0,0,0,1709,0,0,0,0,0,0,119,0,0,0,117,0,309,0,0,0,0,0,596,976,0,0,0,0,0,0,
++0,0,0,0,0,768,0,0,0,0,0,0,0,0,0,518,0,0,0,0,0,0,0,0,0,0,0,0,0,0,863,0,0,0,24,
++145,1020,0,0,1984,0,0,0,0,0,0,0,658,0,0,0,0,0,0,0,0,0,0,106,1827,0,1010,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,582,87,0,0,0,0,0,0,0,267,0,0,0,703,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,496,0,0,0,0,1121,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,249,561,0,0,0,0,0,
++0,0,760,0,0,154,0,0,0,255,0,419,323,0,0,0,0,0,368,0,0,0,0,0,0,0,0,0,0,522,0,0,0,
++0,0,0,0,551,562,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,0,0,0,0,
++0,0,0,284,525,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,958,0,0,594,0,0,0,0,0,0,6,479,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,61,0,0,0,0,0,0,0,820,1641,0,1556,0,0,0,0,0,0,0,302,0,0,
++0,0,0,148,0,0,676,0,0,0,0,0,0,1674,0,0,0,0,0,0,178,0,0,0,0,0,0,0,94,389,0,0,0,0,
++91,8,0,0,0,0,0,0,0,0,0,0,112,0,0,0,0,0,0,0,0,0,0,747,0,0,0,0,0,0,0,1746,0,0,0,0,
++0,24,0,1352,158,1530,0,0,718,130,280,1401,0,0,0,0,0,1946,8,0,0,0,0,1607,0,0,0,0,
++0,0,882,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,417,0,0,0,1597,633,433,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,234,0,0,0,0,0,0,0,0,680,1950,0,0,0,0,249,5,0,0,0,
++0,0,0,0,0,0,1216,0,1773,0,0,0,0,0,0,0,0,0,0,0,0,0,0,509,180,0,0,0,0,0,0,0,1002,
++0,0,0,0,0,0,0,0,0,0,0,0,0,931,0,0,0,0,0,0,0,0,747,943,0,1837,0,0,0,0,0,0,0,641,
++0,0,0,0,280,0,0,0,5,0,0,0,0,0,72,545,0,0,0,0,0,0,0,0,0,742,0,0,254,151,872,0,0,
++0,0,0,0,0,0,0,0,0,0,921,0,0,517,833,0,1680,0,0,436,251,584,0,0,0,0,0,0,0,0,0,0,
++0,24,500,0,0,0,0,0,0,0,0,195,1775,514,389,0,0,0,0,0,0,0,743,0,0,0,0,0,0,292,0,0,
++0,227,1283,774,1805,0,0,0,0,0,0,0,0,0,0,119,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,913,
++1910,0,0,0,1826,490,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1162,700,30,
++0,0,0,721,839,0,0,0,617,0,0,0,0,0,0,0,0,0,169,428,0,0,0,0,0,1648,637,1205,0,0,0,
++1596,0,0,4,266,0,0,0,0,0,0,0,0,0,0,0,862,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,
++0,279,157,391,604,0,0,713,945,877,973,0,0,0,0,0,0,0,0,0,0,0,0,0,0,859,567,628,
++1846,0,0,0,0,0,0,0,0,0,762,0,0,191,0,0,0,0,298,0,0,767,909,0,0,0,0,0,0,0,795,0,
++0,301,0,0,1970,0,0,0,0,0,0,0,0,0,1236,0,0,0,0,0,0,644,369,15,0,160,71,0,0,0,0,0,
++1447,0,0,0,0,0,0,0,0,735,1255,76,0,0,0,0,0,0,0,0,0,0,474,0,0,0,0,0,0,0,0,0,0,
++841,0,0,0,0,0,0,0,0,0,0,836,0,0,0,0,0,1622,0,0,735,0,0,0,0,1601,804,1390,394,0,
++0,0,0,0,0,96,0,289,0,0,35,688,0,0,0,667,0,513,0,0,0,0,0,0,0,2034,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,704,0,1524,0,1078,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,306,
++0,0,0,0,0,0,0,431,0,1196,0,0,54,0,15,1448,0,1418,0,0,0,0,0,0,0,0,0,907,0,0,0,0,
++0,0,194,1767,0,0,0,0,0,840,0,900,0,0,0,0,0,0,0,0,0,0,0,1436,0,0,0,0,642,1560,0,
++0,0,0,0,0,94,386,0,0,0,0,0,0,0,0,0,0,830,416,0,0,20,731,0,0,0,0,0,0,0,0,697,0,0,
++662,0,0,0,0,0,0,0,0,0,861,0,0,0,0,0,0,0,871,671,864,0,928,7,0,332,0,0,0,0,1055,
++0,0,0,0,0,0,986,0,0,0,0,0,44,76,0,0,0,0,0,0,0,0,0,0,300,0,0,0,0,0,0,0,175,518,
++831,1108,0,0,0,836,0,1852,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,843,1804,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,246,0,0,0,610,202,0,0,36,0,0,0,240,654,13,0,0,0,0,0,0,0,
++0,391,0,403,0,0,0,0,0,0,0,0,0,0,75,0,366,815,0,0,631,0,0,0,0,0,0,0,0,345,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,952,0,0,0,0,0,0,0,0,0,0,0,673,35,662,0,287,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,5,34,0,0,0,0,0,0,0,0,151,0,427,0,0,382,0,0,0,329,0,0,279,0,0,0,
++0,0,0,0,0,0,0,906,0,0,366,843,0,1443,0,1372,992,0,36,123,0,649,0,0,0,0,0,767,0,
++1018,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,995,0,0,0,0,0,0,0,72,368,0,0,1345,0,0,0,
++589,0,0,0,0,0,0,0,0,0,1988,0,0,220,541,0,0,0,686,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,32,196,0,0,0,0,0,0,0,0,0,0,0,0,0,381,0,0,0,0,0,0,0,0,0,1452,0,
++0,0,616,0,0,0,0,0,0,0,0,0,1229,0,0,0,0,0,0,0,0,0,0,667,120,0,0,0,0,0,0,0,1146,0,
++0,0,0,0,0,0,0,0,0,0,352,0,0,0,0,0,293,0,0,0,0,0,0,0,0,0,0,0,0,0,935,0,1050,0,
++147,88,0,0,923,0,0,0,0,0,934,0,0,0,0,0,0,0,0,114,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,341,222,0,0,0,0,0,0,0,0,0,0,293,0,0,0,0,0,0,0,0,0,0,0,0,
++637,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1159,0,0,0,847,0,0,0,0,0,0,683,0,867,944,0,0,
++0,0,0,1809,0,0,0,0,0,0,0,0,0,0,395,170,0,0,0,0,0,0,0,0,0,0,618,535,0,1625,0,0,0,
++0,0,0,0,0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,778,0,0,0,0,0,46,0,2032,0,0,37,
++1458,0,938,363,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,314,0,0,0,0,0,0,889,0,0,0,0,0,0,0,
++0,0,0,0,462,0,0,0,0,525,0,0,23,0,0,0,0,0,0,0,0,0,0,0,676,0,0,0,0,0,0,0,0,0,0,0,
++0,498,725,0,0,0,0,7,0,0,0,0,773,0,0,0,164,0,0,0,0,0,0,0,0,936,583,659,1462,0,
++220,0,0,0,0,803,0,0,544,119,0,0,0,0,0,0,0,0,0,0,0,181,176,0,1192,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,1878,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,0,0,0,0,0,0,
++944,0,0,0,0,0,0,0,273,0,0,0,0,0,855,0,0,0,0,5,127,0,0,0,0,0,0,0,0,752,230,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,162,0,654,48,156,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,197,
++0,0,0,0,0,0,0,963,0,0,0,0,0,0,0,0,0,0,858,0,0,0,0,0,0,0,0,0,0,676,1978,0,0,102,
++972,0,0,0,0,0,0,0,361,0,461,0,0,0,472,0,0,0,0,0,0,0,0,0,0,0,0,0,0,747,905,0,0,0,
++155,0,0,0,0,0,0,0,0,0,0,319,163,0,0,0,0,0,0,0,0,0,848,0,0,36,631,0,0,0,0,0,1769,
++0,0,0,0,0,144,0,0,0,0,0,0,0,0,0,0,369,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,555,247,0,0,
++996,0,0,189,0,0,0,0,0,0,0,0,0,0,280,0,0,0,0,0,0,0,0,0,0,0,526,746,0,0,345,0,0,0,
++1017,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,651,428,0,0,0,1162,230,327,546,792,0,0,0,
++1203,0,0,0,0,0,0,0,0,0,672,189,0,0,0,0,0,0,99,0,0,0,298,0,0,0,0,0,0,555,397,0,0,
++0,0,0,1157,0,0,0,0,0,0,0,0,0,0,398,1523,0,366,0,0,787,0,0,0,282,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,157,0,941,0,0,0,0,0,1336,0,0,116,0,0,0,0,0,0,787,0,0,0,0,0,0,0,0,0,
++0,170,160,0,1815,0,0,0,0,0,866,0,0,0,0,0,0,0,0,0,689,0,0,0,0,820,0,498,108,0,0,
++0,1119,0,0,0,244,609,1005,0,581,0,0,0,0,0,895,0,0,0,1898,0,0,0,0,0,926,0,0,0,0,
++0,0,0,0,0,0,0,0,0,538,496,294,301,0,0,0,18,0,0,757,0,0,0,0,0,1263,0,820,0,722,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2028,0,0,0,0,124,1875,0,0,0,881,0,0,0,1348,
++0,0,0,0,0,0,0,911,0,954,0,0,0,0,414,0,0,0,0,517,0,0,0,0,0,816,0,0,0,0,0,0,0,0,
++713,0,0,0,0,0,0,0,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,593,150,0,0,0,0,
++0,553,0,0,0,0,0,0,0,0,0,0,108,0,0,0,0,420,0,0,0,0,0,0,0,0,0,0,0,1777,0,0,55,493,
++0,0,81,0,321,980,0,0,0,0,0,0,0,0,0,0,0,0,0,0,362,112,0,74,0,0,0,0,0,0,0,625,0,0,
++0,0,0,0,377,16,0,0,61,281,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,1031,0,0,0,0,0,0,51,0,
++0,0,0,0,0,0,211,309,15,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,789,173,0,439,9,648,
++0,0,294,0,0,0,0,0,0,0,374,8,0,1099,0,0,0,0,0,0,0,575,0,0,0,518,0,0,0,702,0,0,0,
++0,0,0,87,0,0,0,438,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,464,122,0,0,0,1802,0,0,0,0,
++0,0,499,0,0,0,87,476,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,840,283,0,0,0,0,1620,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,609,1160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,600,
++323,372,0,0,0,0,471,722,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,
++477,1304,0,1774,0,0,88,0,438,12,0,0,0,0,0,0,0,0,671,997,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,639,22,0,0,782,681,0,0,0,0,0,0,0,0,0,0,1013,664,0,942,0,1349,0,0,0,0,0,0,0,
++0,0,0,0,0,356,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,215,289,0,1975,
++109,450,0,0,0,0,0,0,0,0,0,0,705,0,0,664,0,0,0,0,0,0,0,1238,0,0,318,0,0,0,0,0,0,
++0,0,0,0,0,0,0,960,1872,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,0,0,0,0,0,0,0,0,0,239,
++777,0,26,0,0,0,0,0,0,0,0,0,0,0,0,375,414,0,17,0,0,0,1350,0,955,0,0,0,0,0,0,0,0,
++887,960,0,0,0,0,0,0,0,0,0,0,708,710,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,919,0,0,0,
++0,502,280,7,45,0,0,0,0,777,0,0,0,0,410,0,1110,0,0,0,0,0,0,414,341,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,787,0,0,0,436,0,0,0,0,0,0,0,1707,613,377,96,0,0,0,0,451,
++0,0,0,0,0,0,0,0,0,0,0,0,0,680,0,483,916,0,0,0,0,0,0,937,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,739,0,0,0,0,0,0,0,0,82,0,0,663,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,128,0,0,0,0,0,0,0,0,1087,0,0,0,0,0,0,0,503,0,0,0,0,0,0,9,113,104,324,0,460,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,935,702,434,485,1014,949,423,0,900,
++0,0,0,0,0,0,0,2018,574,0,0,0,0,0,0,0,0,0,0,0,0,1206,0,0,0,0,0,0,0,0,38,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,1022,0,0,0,0,143,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,2029,0,0,0,0,0,0,0,0,0,0,0,0,523,0,0,0,0,0,0,625,0,0,425,37,0,0,0,1943,0,0,0,
++0,0,765,0,0,0,0,0,0,0,0,0,0,551,0,0,0,0,0,0,0,0,0,0,0,0,168,0,0,1010,0,0,1994,0,
++0,0,91,0,0,0,0,532,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1884,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,240,15,0,0,0,1227,0,1534,0,0,0,0,0,0,0,0,0,0,0,0,0,0,392,0,
++0,0,0,0,0,0,0,0,0,0,0,655,562,395,0,0,0,501,1019,0,0,0,0,509,267,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1099,0,0,0,0,0,0,948,0,0,0,0,0,0,0,
++462,114,0,0,258,404,0,1717,0,0,0,0,82,1061,0,724,0,0,0,0,0,1133,0,0,0,0,0,0,
++1021,841,0,1021,0,0,0,0,0,0,0,0,0,0,488,373,37,0,0,0,0,564,0,0,0,0,0,513,0,0,0,
++825,0,0,899,0,0,778,0,0,12,1417,0,1116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,114,545,0,5,
++0,0,0,0,0,0,0,192,0,0,763,0,0,0,0,0,0,0,755,759,0,0,0,0,0,0,0,0,0,370,0,1237,0,
++0,0,0,0,0,298,87,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,0,0,
++0,0,0,0,814,991,0,757,57,0,0,0,0,0,0,0,0,0,540,0,0,0,0,608,0,0,0,0,0,0,0,0,1014,
++0,0,0,902,0,0,0,0,553,1668,0,0,0,0,0,0,0,0,0,559,60,0,0,0,0,0,511,0,0,675,0,0,
++156,0,0,0,0,0,0,709,0,698,0,0,0,1745,0,0,0,0,0,0,0,0,0,714,0,0,0,0,0,0,0,0,206,
++8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,776,0,0,0,0,0,0,0,0,0,1272,0,0,
++0,0,0,1059,0,0,0,0,0,0,406,0,0,0,0,0,0,0,0,0,0,947,0,0,0,0,0,0,168,0,0,0,0,0,0,
++870,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,554,0,0,0,0,784,908,0,0,0,0,0,0,
++0,396,358,0,0,0,0,0,0,0,0,2,228,0,0,0,0,0,0,0,0,0,0,0,845,14,0,716,1820,594,0,
++81,1428,0,161,0,782,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,998,0,
++0,0,0,0,0,0,0,0,0,0,0,1043,0,1496,0,0,0,0,0,0,0,0,781,0,0,0,0,0,0,0,817,1114,0,
++1814,958,0,0,0,0,812,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,139,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,236,643,0,0,0,0,0,0,0,0,0,1172,0,0,0,0,0,0,0,0,0,1338,0,0,0,
++0,0,0,0,0,0,0,0,54,0,0,0,256,0,0,351,0,955,1885,0,469,0,0,0,1270,0,744,0,313,0,
++0,0,0,0,0,0,0,402,969,0,0,0,0,0,0,50,0,0,0,0,572,0,0,0,0,847,0,0,0,0,0,0,0,248,
++43,0,369,0,0,0,0,0,0,0,0,0,0,0,0,0,766,0,363,0,0,0,0,0,0,0,0,0,0,0,678,0,0,409,
++258,82,249,0,0,0,0,0,0,0,0,0,0,0,0,32,393,0,788,0,0,0,1281,509,1968,0,0,0,0,39,
++291,0,0,0,589,0,0,54,1059,0,0,0,0,0,0,824,0,0,0,0,0,0,0,0,0,0,1005,0,1598,0,0,0,
++0,0,919,0,0,0,0,0,0,0,0,52,132,0,0,0,0,0,328,0,0,0,0,173,0,0,0,0,0,65,1411,0,0,
++0,0,0,0,0,0,0,0,442,0,842,0,0,0,0,0,0,0,0,0,534,0,0,0,0,0,0,0,0,0,0,0,0,0,845,
++210,0,0,0,0,0,0,0,0,892,0,0,223,0,0,0,0,529,0,0,0,807,0,137,218,0,1444,0,0,0,0,
++0,332,661,0,0,0,0,0,0,0,76,1517,0,0,0,0,0,0,0,0,0,0,0,418,0,0,0,0,0,0,0,0,481,
++379,0,0,0,0,0,149,18,0,0,0,0,0,0,0,0,742,304,142,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,799,925,195,51,0,0,0,0,688,0,0,0,0,697,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,1169,751,0,0,0,452,929,0,221,0,1437,0,0,0,0,955,1251,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,0,132,0,0,0,0,0,865,0,0,0,0,0,0,0,767,
++672,42,0,0,0,1050,0,0,0,0,0,0,0,0,368,44,0,0,0,0,0,0,0,570,29,0,0,0,0,0,0,227,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,522,0,0,0,0,0,0,0,1529,0,0,0,0,0,0,739,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,1667,0,0,0,0,0,0,132,511,0,138,208,1020,0,0,23,565,0,344,0,0,0,
++0,0,922,0,0,0,0,0,0,0,240,0,0,415,171,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,402,0,0,754,31,716,0,982,731,0,0,0,0,0,0,0,888,0,0,0,803,847,0,0,823,
++0,0,0,0,0,0,785,0,0,2,0,0,0,0,0,0,0,532,0,0,681,0,0,314,0,384,684,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,649,447,0,1818,1007,0,321,0,66,360,0,0,0,385,0,0,0,0,0,0,
++0,900,73,254,0,0,0,0,683,1959,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,86,0,0,725,0,0,0,0,0,196,0,0,0,0,0,831,0,0,0,0,723,0,0,0,0,0,994,627,0,0,
++0,0,0,0,0,0,0,0,764,66,0,0,0,0,205,36,0,0,0,0,0,0,0,950,0,0,0,887,111,0,0,831,
++388,165,0,0,0,0,0,155,0,0,0,0,0,0,0,0,0,0,0,0,0,0,780,755,0,0,0,0,898,146,0,0,0,
++0,0,0,0,45,7,0,0,0,0,0,0,0,0,607,0,0,0,0,0,0,65,0,0,0,0,0,0,0,0,0,88,0,0,0,0,0,
++621,600,0,367,0,0,0,0,0,0,0,561,0,559,0,585,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++287,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,672,157,0,0,0,0,714,0,0,0,
++0,0,456,0,925,0,0,0,0,0,0,0,0,19,0,0,0,0,1473,0,0,0,0,0,0,0,0,0,0,113,0,0,0,0,0,
++0,0,0,0,0,0,0,0,69,463,0,0,82,193,2,471,0,0,0,0,633,0,0,0,0,0,0,1148,129,1392,
++542,803,0,0,0,0,0,0,0,0,0,0,0,0,438,0,0,0,0,0,0,875,0,0,0,0,0,237,0,0,0,0,0,0,0,
++65,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,563,0,0,0,9,444,0,0,43,1260,0,0,0,0,0,0,
++971,0,0,699,0,0,0,0,0,1116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,829,242,0,
++0,593,0,0,0,0,0,0,0,0,201,36,224,0,0,0,0,0,0,1430,0,1806,0,523,0,0,212,1889,0,0,
++0,827,0,0,0,0,0,2043,136,242,0,0,0,0,0,0,284,148,10,0,0,0,0,0,0,1249,0,0,0,807,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,94,0,0,0,494,0,0,0,0,0,0,0,0,1510,0,0,0,0,0,
++0,0,0,0,0,505,1306,0,0,764,268,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,384,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1703,0,0,0,0,159,964,583,0,0,0,
++0,0,0,515,0,0,854,0,0,0,0,0,0,0,0,0,0,0,0,1123,0,0,0,0,0,0,0,136,0,0,0,0,0,1782,
++0,0,44,1287,0,0,0,0,0,732,0,0,0,0,313,679,0,0,316,0,0,0,0,595,0,0,0,0,0,0,753,
++147,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,137,0,0,0,0,414,0,1762,0,0,0,0,0,0,0,0,
++0,0,0,599,0,0,0,0,0,0,0,0,0,1749,0,0,0,1627,0,488,0,0,0,0,0,83,0,0,0,0,676,0,0,
++1639,0,0,0,0,0,0,0,0,0,278,0,0,0,0,0,0,97,0,14,1085,0,0,0,0,0,0,781,388,0,849,
++59,229,0,0,0,0,0,1115,0,0,0,0,108,0,0,0,0,700,0,0,0,0,0,0,0,0,0,1414,0,0,0,0,0,
++0,0,0,0,0,0,0,0,660,737,1035,0,0,0,0,0,0,521,690,0,0,0,0,0,0,0,0,0,0,0,0,272,0,
++0,0,0,0,0,0,0,0,0,1744,0,0,0,0,0,0,128,733,0,0,277,0,0,0,0,0,0,0,0,0,4,0,0,0,0,
++0,0,0,0,0,0,0,0,0,936,1981,40,0,0,0,0,0,0,0,0,775,0,0,0,0,0,0,0,0,0,306,0,0,0,0,
++0,0,0,979,0,0,0,0,0,611,0,0,0,0,0,178,0,0,0,1969,0,0,0,0,0,0,0,664,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,390,0,0,0,1510,0,0,0,0,0,0,0,0,0,0,0,493,0,0,37,0,0,0,0,724,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,1537,0,0,168,473,0,0,0,105,0,0,0,0,
++627,438,0,0,0,0,0,0,0,0,0,0,11,1256,0,0,0,1626,0,779,0,0,0,0,25,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,308,0,0,0,0,0,741,0,671,0,0,0,0,649,150,0,0,99,521,0,0,3,339,0,0,0,
++543,0,0,0,0,0,0,0,0,0,1358,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,234,155,
++0,0,0,0,0,0,0,1628,0,766,0,0,0,0,0,0,0,0,0,0,0,0,0,829,0,0,0,1445,0,0,0,486,0,0,
++0,0,2,1635,0,0,0,0,558,0,0,0,0,0,0,0,0,0,0,1461,0,0,0,0,0,599,0,0,0,0,0,0,0,0,0,
++1376,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,93,0,0,0,0,0,0,447,0,0,66,1432,0,0,0,0,
++0,0,307,0,413,609,0,0,0,930,0,0,0,0,21,939,0,0,0,0,0,962,4,651,0,0,0,0,15,579,0,
++0,0,0,0,597,0,0,0,0,0,981,0,0,0,545,0,0,0,0,0,0,0,1558,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,800,17,0,0,17,0,907,0,0,0,110,0,0,0,53,458,0,1983,0,0,0,0,0,0,0,0,0,0,443,0,
++0,0,0,0,0,0,0,0,0,0,924,1844,0,1232,0,0,0,0,70,519,0,993,0,0,0,0,0,0,14,530,0,
++907,0,0,0,0,0,733,0,0,0,0,0,0,0,0,55,0,188,531,56,0,0,1693,0,0,0,0,0,0,0,0,441,
++0,192,928,0,0,0,0,0,241,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1525,0,259,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,512,185,0,464,1603,0,0,0,0,0,0,0,0,0,0,0,1113,
++284,720,0,0,722,0,0,0,0,0,13,0,0,0,0,0,0,0,4,289,43,0,0,0,0,0,0,1694,0,0,0,0,
++193,0,0,0,0,409,0,0,0,0,0,0,0,0,0,0,0,0,308,0,0,1863,0,0,0,0,0,0,0,0,0,790,0,0,
++745,1002,0,0,0,0,0,0,0,0,0,289,68,477,13,0,0,0,0,0,0,0,0,0,0,609,0,0,0,0,0,0,0,
++0,0,0,0,367,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,528,0,0,0,0,0,0,0,0,0,694,58,
++548,0,0,0,0,0,0,687,0,0,0,0,1749,0,0,0,0,0,0,0,0,1004,661,0,0,0,0,0,0,445,0,0,0,
++74,0,0,0,0,213,0,0,0,0,0,0,0,0,0,0,0,0,0,834,0,0,189,1672,0,0,0,0,0,0,0,1548,
++192,0,0,0,0,0,0,0,0,0,0,0,0,0,32,751,0,78,0,0,0,0,0,0,544,1602,105,473,0,0,0,0,
++0,0,156,1949,0,1779,0,0,0,0,0,0,0,0,0,0,0,763,0,0,0,0,0,0,0,0,29,0,0,0,0,0,0,0,
++0,0,0,883,0,0,0,0,0,0,0,488,0,617,0,0,50,0,694,1518,785,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,546,0,0,0,0,0,0,0,0,0,0,22,0,0,0,0,1016,0,0,0,577,0,0,0,0,0,0,
++184,935,114,720,0,0,100,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,95,14,0,969,0,0,0,0,0,0,0,
++727,0,1021,0,0,0,0,0,1190,0,0,0,0,0,0,0,0,0,0,0,0,0,153,0,0,0,0,0,0,0,0,0,798,0,
++587,0,0,695,42,0,1929,141,957,0,465,7,908,0,0,450,148,0,0,0,1166,0,0,0,0,0,0,0,
++0,0,0,0,0,253,0,1003,0,0,0,0,0,0,0,0,0,0,0,46,0,0,879,0,806,0,1868,0,0,0,0,0,
++1846,0,0,0,730,0,0,0,0,0,0,0,965,0,0,0,0,506,0,0,0,10,0,0,0,22,0,0,0,0,0,0,0,0,
++0,0,0,0,0,960,296,0,0,0,0,0,0,0,0,0,0,0,587,0,0,0,0,20,0,0,0,32,982,0,0,0,0,0,0,
++0,0,0,0,941,0,0,0,0,435,0,0,0,0,0,0,71,419,0,0,0,0,0,0,688,740,94,345,0,0,679,
++582,0,0,0,0,0,0,0,945,0,0,0,0,0,0,0,0,0,0,0,0,539,0,684,1993,0,0,0,659,0,583,0,
++803,0,704,0,0,0,0,0,198,181,347,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,481,405,203,0,0,99,826,0,0,0,0,0,0,0,492,0,408,0,0,0,0,0,0,0,0,0,0,4,0,0,
++0,0,665,349,137,0,0,0,0,612,1270,0,0,0,0,0,371,0,0,0,826,0,0,0,0,21,1535,858,
++374,0,0,0,0,0,0,311,0,0,0,991,1968,0,0,0,0,494,1647,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,769,0,0,0,0,0,642,0,0,157,123,0,0,0,1435,0,0,0,0,0,0,0,0,0,0,79,0,0,0,
++0,0,0,1425,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,106,393,486,1690,0,0,0,0,
++0,0,0,0,0,0,0,0,756,184,0,0,0,1382,0,0,0,175,0,1493,0,1007,0,0,0,0,0,0,0,0,0,0,
++0,219,0,0,0,0,515,99,0,851,0,0,0,0,0,1278,0,0,0,0,0,0,0,1000,982,0,762,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,910,1819,0,0,0,0,0,0,906,0,0,0,0,0,0,0,0,0,0,1730,0,0,
++0,0,0,0,0,0,0,0,0,1185,0,0,0,0,0,0,0,0,40,0,0,0,147,0,0,0,0,0,0,0,0,0,0,0,0,0,
++650,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,30,0,553,0,0,20,597,0,1614,0,0,0,0,0,327,
++49,0,0,0,0,0,0,0,78,0,0,786,134,0,0,0,12,496,0,0,0,0,0,0,0,0,0,0,42,204,0,614,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,147,247,0,0,0,0,942,0,0,2023,0,0,0,0,
++0,0,67,285,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1309,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,532,0,0,0,0,0,0,0,
++1692,0,0,0,0,55,1704,0,0,0,0,988,0,0,0,223,0,0,0,0,0,0,0,57,1123,0,0,0,0,0,1764,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2015,0,0,0,1599,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,129,0,0,0,0,0,0,0,0,0,0,0,534,0,0,0,0,0,0,0,0,0,0,0,
++0,0,504,621,1248,321,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1397,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,441,75,0,0,0,0,0,0,0,0,0,0,841,0,0,0,0,0,693,0,650,314,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,913,0,0,0,0,0,0,0,0,0,0,0,0,0,0,880,0,475,0,
++0,1016,179,602,111,329,0,0,0,1864,0,0,0,0,846,1888,0,0,780,0,0,0,82,0,0,0,0,821,
++0,0,0,0,0,0,0,0,0,0,0,956,112,0,0,0,261,455,0,0,0,0,0,0,337,385,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,184,1865,0,0,721,16,0,486,0,0,0,265,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,621,0,0,0,0,0,0,0,0,234,0,0,815,0,0,743,
++1987,205,197,0,0,0,0,0,0,0,0,0,314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,219,452,589,0,
++176,333,0,0,0,0,0,0,0,1110,47,0,0,0,0,0,0,0,0,0,0,0,864,0,0,300,0,1237,0,0,0,0,
++0,0,0,0,0,0,0,1685,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,135,395,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,631,0,0,0,0,0,0,835,0,0,0,606,459,0,979,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,612,0,0,0,0,0,0,0,0,158,372,0,854,0,0,0,0,0,
++0,0,1492,0,0,0,833,0,0,0,0,0,0,0,1739,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++195,0,0,0,0,0,0,0,0,730,1997,0,0,0,0,0,0,0,0,61,0,0,0,0,0,0,0,266,751,0,0,0,0,0,
++0,0,821,0,0,0,715,0,0,0,868,0,959,0,0,0,0,0,0,0,0,0,0,0,1053,0,0,0,950,0,1081,0,
++1595,0,0,0,0,59,0,0,0,0,0,0,0,0,0,0,47,684,0,0,0,0,0,0,1606,0,777,0,1020,0,0,0,
++1094,0,0,0,0,0,0,0,350,0,0,0,0,0,0,242,1812,0,0,0,967,0,0,0,473,286,0,0,0,0,0,0,
++798,629,222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,513,337,306,0,0,0,0,0,0,0,0,0,
++146,0,0,1646,0,0,0,0,0,465,0,0,0,525,0,0,0,0,0,0,299,165,0,0,0,0,0,0,0,1064,0,0,
++0,0,0,596,0,0,0,0,0,0,0,0,0,0,0,0,0,0,238,1741,0,1233,451,1824,0,0,0,0,733,495,
++0,0,0,0,0,1204,0,0,0,559,341,0,224,21,0,0,0,0,0,0,0,0,97,1446,0,0,0,0,0,0,0,729,
++0,0,565,727,0,1948,0,0,0,519,0,0,0,0,0,0,0,0,0,1193,0,0,0,0,0,0,790,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,323,2,201,0,0,59,0,0,34,0,896,961,0,1285,0,0,46,0,479,0,0,
++0,0,549,0,663,0,0,0,0,0,783,65,682,0,0,0,0,0,11,0,0,0,0,0,522,0,0,0,52,0,0,0,0,
++0,383,0,0,0,0,0,0,0,0,127,0,0,0,0,0,397,194,0,0,635,0,0,0,0,0,0,0,0,0,0,975,0,0,
++0,0,0,0,0,0,0,0,116,0,51,0,0,858,0,1075,535,448,0,0,0,0,0,610,0,0,0,0,0,0,0,0,0,
++0,191,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,267,673,319,94,92,0,551,0,0,218,
++1406,69,256,0,0,952,1980,0,833,0,0,0,0,0,0,0,0,0,0,0,0,39,0,0,0,0,0,0,0,81,0,0,
++0,352,634,0,0,0,0,0,618,0,0,0,0,0,0,73,339,0,0,0,0,0,0,0,0,0,0,0,0,0,0,169,759,
++0,0,0,0,0,0,0,0,0,0,0,0,0,1075,0,0,0,0,0,0,482,649,0,0,0,0,0,0,0,0,386,336,0,0,
++0,1035,0,0,0,0,0,0,0,0,0,0,0,924,0,73,0,0,0,0,0,1971,0,0,0,0,0,0,0,0,0,1344,0,
++501,0,0,0,0,0,0,0,0,46,799,0,0,0,0,0,0,0,276,0,0,0,0,0,0,0,770,0,0,0,0,0,0,0,0,
++0,0,0,0,0,158,0,0,0,0,0,1432,0,0,0,0,0,0,0,0,0,0,25,0,0,2001,0,0,0,0,0,0,0,0,0,
++0,0,0,0,478,0,0,0,0,0,0,91,1461,211,602,0,0,0,0,0,0,0,0,0,1068,0,0,124,567,0,0,
++0,1006,0,0,0,0,0,0,0,0,0,735,812,0,0,323,0,0,0,304,0,0,0,0,0,0,0,0,0,148,0,0,0,
++0,0,0,0,0,0,523,0,0,144,730,0,0,981,0,0,111,0,0,132,0,0,0,0,0,0,890,0,0,0,0,0,
++444,0,1787,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,2041,932,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,937,0,995,0,0,255,0,0,138,863,965,0,0,631,0,0,0,0,1394,16,652,0,0,0,0,0,0,
++0,0,0,0,0,0,0,897,0,321,0,0,0,0,0,922,0,619,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,844,0,0,0,0,0,0,1659,0,1100,0,0,0,1173,0,1930,268,251,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,390,711,0,0,0,0,0,0,0,0,0,0,0,0,0,744,0,0,0,0,0,0,0,0,0,624,0,0,0,
++1998,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1125,0,0,0,594,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,268,0,0,0,0,0,0,0,563,0,0,0,0,0,0,0,0,2,39,0,0,0,1332,0,0,0,0,0,
++0,0,508,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,796,0,0,0,0,527,0,0,0,0,98,0,0,576,0,
++0,0,0,0,122,0,276,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,645,0,0,0,0,
++0,0,0,0,0,0,0,290,0,0,762,1292,0,0,0,1315,0,1955,0,0,0,0,0,0,0,0,0,0,210,131,0,
++0,0,0,797,0,38,0,11,488,0,936,0,441,0,0,0,0,0,595,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++991,0,0,0,0,0,0,0,0,0,0,0,653,0,523,0,0,0,903,0,0,0,0,0,0,0,0,0,0,0,0,80,0,0,0,
++0,0,0,0,0,0,432,0,0,314,0,0,0,0,232,1368,534,0,0,0,0,0,27,0,0,0,12,0,0,0,0,0,0,
++0,0,0,264,736,0,1657,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1117,0,127,0,0,0,1208,0,1294,
++0,0,0,0,364,0,0,0,0,0,125,1334,0,0,0,0,0,0,0,0,0,0,0,0,0,0,792,0,0,0,0,0,0,0,
++849,699,0,0,0,0,0,968,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1446,
++124,397,0,0,0,0,0,0,0,0,0,0,0,641,0,0,0,0,0,0,0,0,0,0,0,0,127,346,0,0,517,75,0,
++0,0,0,0,0,0,0,83,0,0,0,0,0,0,1031,0,0,0,0,0,0,0,1470,0,954,0,0,345,304,410,0,0,
++0,0,734,0,0,0,0,0,1822,0,0,0,1798,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,161,
++1865,69,0,0,0,0,0,0,922,0,0,0,0,0,0,0,0,0,0,0,541,0,627,0,0,0,0,0,0,0,0,0,166,0,
++0,0,0,0,0,0,0,0,849,0,0,0,0,0,0,0,717,0,0,0,0,0,0,0,0,0,0,0,0,0,0,600,0,0,0,0,0,
++0,654,0,0,188,273,0,0,0,543,0,410,87,0,0,941,0,0,186,250,0,1785,0,0,0,0,0,1339,
++462,961,0,780,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,0,0,0,0,0,0,474,1276,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,24,948,0,0,0,0,657,753,0,0,0,0,941,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,706,985,837,0,1861,0,0,0,0,0,0,0,0,0,0,0,0,0,0,292,933,0,0,0,0,0,
++0,0,0,0,767,0,0,0,0,0,0,0,641,0,0,0,1233,114,0,883,0,274,2008,0,1794,285,0,0,
++571,0,0,0,0,0,0,0,0,0,0,823,960,16,617,0,431,0,0,0,0,0,0,0,0,0,0,567,0,401,0,2,
++781,424,33,0,2006,0,0,274,0,0,1882,0,794,0,0,0,1848,0,0,0,0,0,0,448,47,0,0,0,
++1199,0,0,0,0,0,0,0,0,417,0,0,0,0,0,0,0,0,0,0,295,0,0,0,0,0,0,0,1019,0,0,0,0,0,0,
++0,0,0,0,0,0,0,620,0,0,0,0,464,0,0,0,0,208,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,442,0,930,0,0,0,0,0,516,68,0,0,0,0,0,1128,104,0,0,0,0,0,0,0,0,787,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,491,0,0,0,0,0,0,711,0,0,9,0,101,441,0,0,0,0,0,0,0,0,
++0,0,160,396,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,679,326,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,1128,0,0,0,0,0,737,0,1796,0,0,0,0,0,0,0,0,0,0,0,0,338,574,0,0,
++0,0,0,1096,491,405,0,0,0,0,0,1081,0,0,0,0,0,0,0,0,0,0,0,0,0,1676,0,1207,0,0,0,0,
++0,0,969,354,0,0,0,0,598,0,297,0,0,0,0,0,0,0,0,1772,751,0,37,0,0,1828,0,0,0,0,0,
++0,0,0,0,257,191,582,0,0,0,0,0,0,790,0,0,0,0,0,47,0,0,0,0,0,0,0,449,306,1011,0,0,
++0,0,0,299,0,0,0,0,0,0,837,0,0,0,0,0,0,10,329,0,0,0,0,0,1320,0,0,0,0,0,0,158,657,
++0,1191,0,0,0,0,0,0,7,0,974,1939,0,1665,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,288,
++66,0,0,0,0,494,175,0,1643,0,0,0,0,0,0,0,0,570,750,719,0,0,0,0,0,0,0,0,0,0,0,0,0,
++13,0,0,1247,0,0,221,356,0,0,0,0,0,0,0,0,0,0,694,1809,0,0,0,0,0,0,0,411,0,44,31,
++0,0,0,0,669,0,673,0,0,0,0,0,0,0,0,0,1303,704,299,0,0,0,275,0,0,216,1761,0,0,0,0,
++0,0,0,0,0,0,0,1319,0,0,428,0,0,0,0,0,0,0,0,0,0,514,0,0,0,0,0,0,49,55,102,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,364,0,0,0,0,379,0,921,971,52,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,1258,0,0,0,1058,0,0,0,0,0,656,0,0,0,0,0,144,0,0,0,0,0,0,0,0,0,0,
++0,1373,10,605,0,0,0,0,0,0,0,838,0,1012,0,0,0,0,0,0,0,0,0,0,0,0,0,0,154,365,0,0,
++0,0,0,0,0,0,0,340,0,0,0,0,0,810,0,0,0,0,0,0,495,0,0,0,0,0,0,0,0,0,261,0,535,248,
++0,358,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,567,445,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,697,0,0,0,1336,0,0,0,0,0,0,0,0,917,174,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,972,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,351,0,0,0,0,0,0,0,0,0,0,
++0,0,0,286,0,0,56,438,0,0,0,0,0,1950,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,738,0,0,0,0,0,
++0,0,0,0,0,969,2047,0,0,0,0,0,0,0,818,0,0,0,0,0,0,0,866,0,0,0,0,0,0,0,1467,0,0,0,
++0,0,0,0,0,0,0,0,0,0,972,0,355,0,0,0,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,267,189,104,0,0,0,0,1613,0,0,0,0,0,0,0,116,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,886,0,86,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,45,0,0,863,0,0,0,0,0,
++0,0,1953,450,1773,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,381,0,0,0,0,0,0,0,
++0,0,0,0,0,1142,0,1189,0,0,0,663,0,0,0,0,0,0,0,846,0,0,528,0,393,378,0,0,0,0,0,0,
++325,899,680,1880,0,1770,0,0,0,0,0,648,0,0,0,0,0,0,185,167,0,2046,0,0,0,0,0,0,
++249,1645,0,152,0,0,0,1733,0,0,0,0,0,1006,0,0,0,0,0,420,0,0,0,832,0,0,0,0,0,351,
++0,0,0,0,6,40,0,0,60,0,0,0,0,1354,745,724,0,0,0,0,0,0,0,0,772,1951,275,108,639,0,
++0,0,0,0,0,0,0,0,500,1758,0,0,0,0,0,0,0,0,0,0,0,1886,711,205,0,0,965,865,0,0,0,
++534,0,0,0,0,691,0,0,0,237,443,0,878,0,0,0,0,0,1410,0,0,0,0,0,0,0,0,0,0,0,0,0,
++995,0,0,0,0,0,0,0,0,0,0,0,0,0,578,0,0,0,0,881,0,0,0,0,0,0,0,0,822,0,923,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,924,0,0,0,665,0,0,0,0,0,1901,0,0,0,0,0,950,498,93,
++0,0,0,1451,0,0,0,0,0,747,828,788,400,184,0,198,0,0,0,0,0,0,0,0,0,0,0,994,0,0,0,
++0,0,0,0,0,615,320,0,0,0,978,843,905,0,0,0,0,0,0,0,0,850,974,0,0,0,0,6,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,509,0,0,0,0,0,273,0,0,0,0,0,0,0,0,0,0,0,0,0,
++201,0,0,0,1041,0,0,0,1040,0,0,0,0,0,0,0,0,0,693,234,774,0,336,0,1399,22,0,805,
++802,777,167,789,0,0,1705,0,0,0,0,0,0,0,0,0,0,0,10,13,11,0,0,204,264,0,0,56,0,0,
++1917,0,470,0,0,0,0,0,0,0,0,0,0,0,1198,0,0,0,0,0,0,0,0,0,0,1015,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,715,0,0,1002,0,0,0,298,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,867,0,0,724,0,0,0,0,0,0,0,0,0,0,0,0,768,0,0,0,0,0,1066,0,0,0,0,67,0,174,948,
++0,0,0,0,0,0,0,0,0,0,0,0,0,764,0,0,0,0,75,137,0,756,0,0,0,0,0,0,1008,842,643,0,0,
++0,67,0,0,0,0,0,0,0,0,0,0,0,135,821,0,0,0,0,0,0,0,0,736,0,389,355,0,0,786,0,0,0,
++0,0,0,2044,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1030,0,0,0,1083,0,0,0,0,0,
++1226,0,0,0,0,356,319,8,389,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,474,0,0,0,427,
++0,413,0,730,0,0,0,0,0,373,0,0,0,0,0,0,0,0,0,799,0,0,0,1793,0,0,0,322,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,290,2,0,0,0,0,0,0,0,0,0,0,672,
++699,1860,0,0,0,737,0,0,0,1612,0,0,0,0,0,0,0,0,0,0,0,145,124,884,0,0,0,0,0,387,0,
++0,0,0,0,0,0,0,0,0,0,679,0,550,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1305,0,0,0,0,0,0,0,
++576,0,0,0,0,0,0,0,686,0,607,0,0,37,0,0,0,0,0,0,0,0,0,101,1726,0,0,0,0,0,958,0,0,
++0,903,0,0,0,0,147,0,0,0,0,0,0,0,0,0,0,0,367,0,0,0,0,690,0,705,273,0,0,887,0,0,0,
++0,0,0,0,0,0,0,0,90,0,0,0,0,0,0,0,908,0,0,0,0,0,0,0,1261,0,0,497,1235,0,429,0,0,
++0,0,904,0,12,125,0,0,0,841,0,0,0,0,0,860,946,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,768,0,770,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,271,0,0,0,0,0,0,0,719,0,699,581,0,0,0,0,0,0,0,0,0,0,862,304,0,631,0,0,0,0,880,
++1513,0,0,0,0,0,981,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,434,0,0,0,0,0,550,0,0,476,930,
++824,553,0,0,452,0,151,0,0,0,0,0,0,772,0,292,135,0,0,0,0,0,0,0,504,0,0,1089,0,0,
++0,0,0,0,0,0,0,0,0,783,0,0,0,0,0,0,206,393,0,0,0,0,0,0,0,0,232,912,0,0,0,0,0,977,
++0,0,716,98,0,0,0,0,0,733,0,0,0,0,0,0,0,0,19,0,0,0,0,668,0,360,0,0,0,0,0,0,656,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,726,0,0,0,0,0,0,0,0,0,0,0,0,72,0,0,1269,0,0,463,0,
++0,0,0,0,0,1454,0,1287,245,0,989,0,0,0,0,0,0,0,0,0,107,164,0,0,0,0,0,0,0,1061,0,
++0,0,0,2,484,0,0,0,0,0,0,0,1127,0,0,0,0,0,0,0,460,0,0,0,0,0,932,0,0,0,0,0,0,0,
++588,625,0,0,0,0,76,92,0,0,0,0,0,0,0,0,0,0,0,0,0,104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++763,0,622,0,0,0,253,0,546,0,0,110,0,256,916,0,0,35,212,0,0,746,0,0,0,150,0,0,
++1466,0,0,0,1299,0,0,0,0,0,0,0,0,0,1518,0,0,0,0,0,0,0,0,0,0,0,0,0,1229,0,0,0,816,
++0,0,0,0,0,0,159,0,0,0,0,0,734,869,126,1716,0,0,0,0,0,0,202,232,0,0,0,0,212,0,0,
++0,0,0,111,1003,0,0,0,0,0,0,0,0,0,0,0,1712,0,0,216,0,0,0,0,516,0,0,0,0,0,650,0,0,
++0,0,57,99,0,0,0,0,300,574,0,0,0,0,1023,0,0,302,0,1871,0,728,252,0,0,461,0,0,0,
++323,0,0,0,0,0,0,775,461,0,0,0,0,0,0,172,0,0,464,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,73,727,0,1023,0,0,0,0,0,0,0,0,0,0,577,0,0,0,0,0,0,0,0,1037,0,0,0,0,0,0,
++0,0,280,677,0,0,0,0,0,0,0,0,0,0,0,799,0,0,0,0,159,0,446,1730,0,0,0,0,0,0,0,0,0,
++395,0,0,0,0,145,0,0,0,0,0,0,0,20,0,0,426,608,0,0,0,0,0,977,0,250,0,0,0,0,0,100,
++0,0,0,0,1982,0,0,0,0,0,476,0,0,0,0,0,0,594,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,447,0,0,0,0,526,0,0,14,1124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,188,0,0,0,0,0,0,0,0,362,301,0,0,0,1743,0,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,872,0,831,0,0,208,202,0,0,0,0,0,0,0,1954,0,
++0,0,0,516,872,0,0,313,224,0,0,24,0,11,546,0,0,0,1937,242,241,46,0,0,0,830,1273,
++0,0,0,0,0,0,0,825,327,1006,0,0,0,0,0,1580,516,366,0,0,0,0,0,1736,0,0,0,0,0,0,0,
++0,0,0,0,1935,0,826,0,0,0,0,139,331,0,0,0,0,0,0,0,0,0,0,0,288,0,916,0,0,0,0,0,
++1888,0,0,0,0,0,0,0,1471,0,1570,0,394,0,0,0,0,0,0,0,1931,0,1719,0,658,228,0,0,0,
++0,0,374,0,0,0,0,735,0,0,0,0,0,0,323,498,0,1063,0,0,0,0,155,0,0,0,0,0,0,0,0,906,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1139,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,108,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,616,
++902,0,0,0,0,0,692,0,0,0,0,0,0,823,0,0,0,305,0,0,0,0,0,0,0,681,0,0,0,0,0,214,
++1004,0,0,0,0,0,0,0,23,0,0,1703,0,0,0,0,0,0,0,0,0,1443,0,0,19,714,0,0,0,0,64,737,
++0,0,345,1758,0,0,579,47,0,0,539,139,0,0,0,0,388,0,0,0,0,253,0,0,0,0,0,0,252,0,
++745,0,0,0,0,0,0,0,0,0,0,0,504,107,0,871,0,0,0,229,0,0,0,0,0,903,0,0,71,0,0,549,
++6,47,0,0,0,0,0,0,0,0,0,980,865,705,0,0,0,161,0,0,0,0,143,1331,0,0,0,1388,33,724,
++0,0,0,19,0,0,0,395,0,0,0,0,0,846,210,0,0,0,122,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,695,937,497,0,0,0,0,0,718,0,0,0,0,0,0,0,1581,0,
++0,0,0,0,0,161,49,0,0,0,0,0,0,0,0,0,597,0,0,0,1094,0,0,0,811,908,0,0,0,0,0,0,0,0,
++0,0,1471,0,0,0,0,0,0,0,0,0,0,42,1935,0,0,0,2014,66,2007,0,0,586,0,0,0,0,0,0,0,0,
++0,28,1077,0,0,0,1221,0,0,62,0,0,0,0,0,0,0,0,0,0,1766,0,0,0,0,0,0,0,0,0,0,0,0,25,
++0,499,1388,0,0,97,10,0,0,0,0,0,481,0,0,0,0,0,0,0,0,0,0,37,134,155,486,0,1442,0,
++0,0,0,0,591,0,0,0,0,0,0,310,1173,0,0,0,0,409,1156,0,0,0,482,0,0,263,926,0,0,0,0,
++0,0,0,0,0,0,0,0,0,804,0,0,0,0,0,0,0,0,0,0,0,0,0,1265,0,415,0,348,0,0,0,1012,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,165,1803,0,0,0,0,0,0,0,408,
++0,0,0,0,0,0,257,1321,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1138,0,0,0,249,0,
++0,0,576,0,0,0,0,231,0,0,0,288,0,0,0,0,0,0,0,0,0,433,1487,569,1678,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,87,0,0,0,0,0,779,538,0,0,0,413,0,0,0,
++0,0,0,0,0,0,0,495,0,0,0,0,0,191,54,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,530,567,
++0,0,0,0,0,1484,0,0,0,0,0,0,815,609,0,0,0,0,0,484,0,0,0,0,0,0,0,0,0,0,900,0,0,0,
++0,1335,0,1724,0,0,0,0,0,0,0,0,0,0,0,640,0,0,0,0,0,0,0,0,0,0,0,1831,0,0,0,0,0,0,
++0,0,0,0,0,0,0,474,0,0,0,0,0,0,0,0,0,1103,0,1504,655,1034,0,0,0,0,0,305,0,0,0,0,
++0,0,0,0,0,1236,0,0,429,217,0,0,0,0,739,278,0,0,0,0,0,0,0,708,0,0,0,0,0,1840,233,
++0,0,0,0,0,0,0,0,2017,0,0,0,0,0,1488,0,0,0,1590,0,0,0,0,0,1800,28,0,0,0,0,0,0,0,
++0,0,45,0,36,0,22,1442,378,0,0,0,0,0,0,1507,0,0,0,0,0,0,0,0,0,0,39,0,0,1054,725,
++1955,0,2036,0,0,0,0,0,0,0,0,0,0,896,1871,0,0,0,0,0,0,0,0,0,0,805,0,0,0,0,2046,0,
++0,0,0,17,712,0,617,55,320,271,0,0,0,0,0,0,0,0,0,445,0,184,103,0,0,0,0,0,0,0,0,
++659,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,676,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++337,0,0,0,506,0,0,0,0,0,843,77,0,458,0,0,0,0,0,1420,382,109,142,330,0,0,0,0,0,0,
++0,0,0,0,0,0,87,0,0,0,492,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1239,0,0,0,0,0,0,
++211,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1049,0,321,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,1985,0,0,122,0,0,234,0,0,0,1098,0,0,0,0,0,0,549,253,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,522,131,0,0,149,0,0,0,0,0,0,0,0,0,0,0,0,0,0,507,0,0,0,0,811,630,0,0,0,343,
++0,0,0,0,0,448,591,455,0,1381,0,0,0,0,0,0,0,575,0,0,0,0,0,1175,0,0,0,0,0,0,0,0,0,
++653,0,0,0,1761,0,1198,0,0,0,0,297,1127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,678,0,0,
++164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,0,45,0,0,0,0,0,121,0,0,0,0,0,0,
++0,0,125,0,0,0,1622,0,0,0,0,0,721,145,0,0,0,970,792,0,0,0,715,0,0,0,0,0,1999,0,0,
++74,531,0,0,65,0,0,0,105,220,0,0,0,0,0,0,0,960,0,0,0,0,0,0,428,19,0,0,401,96,0,0,
++0,0,0,1595,116,0,1021,0,0,0,0,0,750,1961,0,0,148,0,0,0,0,0,0,0,0,0,0,0,0,0,75,0,
++0,1383,0,0,0,0,0,0,0,0,0,0,0,0,0,0,779,0,0,0,0,0,0,0,0,598,0,424,0,0,0,0,0,0,0,
++1222,0,0,0,876,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,133,0,0,0,0,187,0,8,0,0,0,0,0,
++0,0,429,0,685,0,0,0,0,0,0,0,0,0,0,0,132,472,0,0,0,0,0,0,0,0,0,938,0,0,874,0,0,0,
++0,0,774,0,0,0,0,0,92,0,0,0,0,0,0,830,701,0,0,0,0,0,426,350,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,603,59,0,0,0,0,0,0,0,0,0,0,293,0,0,0,0,0,0,0,0,0,0,0,0,0,0,441,163,4,0,
++0,0,0,0,0,0,0,0,806,0,0,0,0,0,0,233,0,0,0,0,1994,0,1739,0,0,393,0,47,1038,0,0,0,
++309,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,363,0,0,0,175,0,0,0,0,0,0,0,666,
++0,0,1675,0,1600,0,0,0,808,0,0,0,0,0,0,0,0,0,0,0,280,54,0,0,0,0,0,0,0,0,421,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,249,0,0,103,254,0,262,1,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,805,0,0,0,0,0,0,0,0,0,1630,0,0,0,0,0,0,0,0,0,0,0,0,0,671,972,989,0,0,
++0,0,0,0,0,889,0,0,0,1382,0,0,0,0,0,0,0,775,0,0,0,0,0,0,0,0,0,0,388,202,0,0,0,0,
++16,560,0,0,0,841,0,0,566,0,0,0,938,0,0,0,0,0,0,0,0,0,0,912,0,0,0,1361,0,0,0,0,0,
++0,618,236,0,1854,0,0,318,190,0,1376,0,0,0,0,0,0,0,349,0,0,0,0,951,1972,0,0,0,0,
++0,0,344,0,0,0,0,0,0,0,0,850,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,910,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,163,85,0,487,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,145,0,83,0,0,1013,0,0,0,1922,0,0,169,557,66,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,1193,82,0,352,454,57,0,0,1333,396,107,0,370,0,0,0,0,0,0,0,0,0,204,0,0,0,
++0,0,1706,0,0,0,0,0,0,0,0,0,0,0,0,394,1204,0,0,0,0,0,1007,0,0,0,1696,0,1519,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,981,0,0,0,0,1072,0,0,0,712,0,1629,0,0,0,0,0,0,0,728,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1271,0,0,0,1608,16,0,0,0,0,485,0,0,0,0,0,0,
++153,27,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1991,0,0,0,0,0,0,0,0,52,0,21,0,
++0,0,0,0,0,0,0,0,819,0,0,0,0,0,917,0,0,0,0,784,0,0,0,0,135,0,0,0,0,0,454,0,0,0,0,
++0,0,0,0,0,852,1719,0,0,0,0,0,852,0,0,0,0,0,952,0,0,0,0,568,0,0,0,0,0,448,0,0,0,
++67,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1826,657,0,729,666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++669,0,0,0,0,0,0,0,402,0,0,152,0,0,0,0,912,0,0,0,0,0,0,51,320,0,445,0,0,0,0,308,
++0,0,0,0,0,386,0,0,239,0,0,130,83,0,143,0,348,0,0,0,0,0,0,0,958,0,0,0,0,0,210,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,430,0,0,0,0,0,0,0,0,0,0,0,0,7,213,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,801,0,0,0,0,0,0,0,0,0,936,0,108,0,0,
++0,0,0,0,0,0,0,885,587,219,398,364,0,1165,0,0,342,241,303,0,0,0,0,0,0,0,0,0,0,
++1454,0,0,0,0,0,0,0,0,0,0,254,562,0,786,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1294,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,493,216,0,0,0,0,219,341,0,0,0,0,0,
++0,0,0,0,0,130,1734,154,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,701,604,0,0,879,0,195,
++666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1669,0,0,0,1791,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,1228,0,0,0,0,0,623,0,0,0,0,0,0,0,798,0,0,0,0,0,0,0,0,0,0,0,0,84,
++122,0,0,0,837,0,0,0,0,0,0,1013,0,0,577,0,0,0,460,932,0,0,0,0,0,0,0,0,0,0,0,31,
++131,0,0,0,605,0,0,0,1246,0,0,0,0,68,278,165,307,781,0,0,0,0,0,0,33,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,1113,0,0,720,1953,203,0,0,0,0,0,0,0,425,326,0,0,0,0,0,
++0,0,0,0,0,241,1316,0,0,0,0,0,416,0,0,0,1300,0,847,0,0,662,358,0,0,0,0,839,1823,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,654,1522,0,0,0,0,0,0,163,0,0,0,0,0,314,978,0,0,0,
++601,0,0,0,0,0,946,434,0,0,0,402,411,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,1467,
++410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,483,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,0,0,1405,0,0,0,0,0,0,108,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,777,0,0,0,0,0,747,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,505,0,326,0,0,164,628,654,0,0,0,
++37,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,668,152,0,0,0,0,0,0,0,0,0,0,0,581,
++0,0,0,0,44,126,89,0,0,0,0,0,0,0,0,1531,0,0,0,0,0,0,0,0,203,1167,0,0,0,0,0,0,0,0,
++531,1232,0,0,0,0,0,943,0,670,231,880,0,1617,0,0,0,1957,0,0,0,0,0,0,0,975,0,0,0,
++0,0,0,0,0,0,0,0,242,0,0,0,0,0,0,0,0,0,421,0,0,14,834,0,0,0,0,0,0,0,0,0,0,0,0,
++465,0,0,0,0,0,834,688,413,855,0,0,0,590,0,0,0,0,0,0,0,0,114,0,0,0,0,0,0,0,0,0,0,
++0,45,169,0,0,0,0,0,0,0,0,0,0,0,198,0,0,565,585,0,0,0,0,0,0,0,0,0,0,0,0,0,691,0,
++0,0,593,0,0,0,0,0,0,0,0,0,913,116,0,0,0,0,1360,0,0,0,802,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,673,308,0,709,1006,1895,0,228,0,0,0,1840,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,608,0,0,0,0,0,0,0,0,0,1573,0,2039,136,540,0,0,0,0,0,0,0,
++897,0,0,938,1878,0,0,0,0,0,0,0,0,0,1469,0,999,0,299,0,0,0,0,0,0,0,578,0,0,0,0,0,
++456,0,0,0,1679,163,693,0,0,0,0,0,0,48,755,0,0,0,0,0,0,0,0,0,0,0,0,338,0,0,0,0,
++1091,0,0,0,0,695,0,0,1464,0,0,0,0,0,975,0,0,335,0,0,1979,0,0,0,0,269,1566,630,
++396,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1815,634,0,0,0,966,0,0,0,0,0,0,0,9,
++412,0,958,0,0,579,382,0,212,0,0,0,0,965,681,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,655,
++0,0,0,0,67,0,0,0,0,0,0,751,0,0,0,0,423,231,0,0,1016,300,0,0,0,0,100,237,0,0,0,
++1370,0,0,0,1208,0,0,0,0,0,1219,129,0,0,0,0,0,0,0,0,0,0,0,0,0,0,199,0,0,427,0,0,
++0,0,949,665,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,712,0,0,0,0,0,1186,0,0,0,0,0,0,0,0,0,0,295,312,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++151,0,0,0,0,588,4,0,0,0,0,0,414,104,0,0,757,263,0,561,0,0,0,320,0,0,0,0,0,0,0,0,
++0,0,0,225,0,0,0,0,37,817,0,974,0,0,0,0,0,0,0,0,0,0,0,0,0,2026,131,235,16,0,590,
++1157,0,0,0,0,0,0,0,0,221,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,140,390,0,0,0,0,
++0,0,0,1144,0,0,0,464,0,0,0,0,0,0,0,0,0,0,0,0,204,407,303,1218,0,0,0,0,5,325,0,0,
++0,0,12,800,0,1783,0,0,0,0,0,0,0,0,0,0,504,621,0,0,0,0,0,0,0,0,0,920,0,376,0,0,0,
++0,0,218,580,0,768,454,0,0,0,0,0,0,0,0,0,0,0,0,676,0,0,0,0,0,0,164,0,0,0,0,0,0,0,
++0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,120,285,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,226,343,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,0,0,1812,0,0,8,0,0,0,21,1125,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,1327,0,0,0,0,575,1598,0,0,0,0,0,0,0,0,0,895,0,0,0,959,0,0,
++0,0,0,1759,173,0,0,0,0,266,261,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,1427,0,0,300,1033,0,0,0,0,0,0,0,0,0,0,0,584,0,0,0,0,52,734,
++0,0,217,239,0,1129,0,0,0,0,0,0,0,0,732,20,0,0,0,0,0,0,0,0,0,0,0,418,0,0,0,613,0,
++0,0,0,0,0,0,0,0,632,0,0,85,984,0,0,0,0,909,694,7,1109,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,167,0,0,0,0,280,62,0,0,33,0,0,359,186,980,0,0,0,0,0,0,0,0,0,0,0,585,0,0,0,
++211,0,0,336,145,0,1130,0,873,0,0,840,263,0,0,0,0,0,0,0,0,0,916,0,0,0,0,0,0,0,0,
++0,0,155,0,0,0,461,97,0,0,0,0,0,1356,0,0,0,0,0,0,0,593,0,0,0,0,0,1392,0,0,0,0,
++126,0,0,0,0,1179,0,0,0,0,0,162,0,0,0,0,0,765,0,187,0,1286,0,0,0,0,0,0,0,0,0,635,
++0,0,23,215,0,0,0,1306,0,0,97,716,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,657,0,
++0,0,0,0,0,0,0,299,0,0,0,0,0,0,134,0,0,0,0,0,0,0,0,0,0,0,658,1082,0,0,0,0,0,2002,
++0,0,0,0,0,0,833,248,0,0,0,0,0,1654,0,0,531,0,0,0,0,0,0,634,0,0,0,0,0,0,0,0,0,
++853,573,249,0,0,0,0,0,0,0,0,527,0,0,0,0,1419,0,0,0,0,0,0,20,49,0,0,0,992,0,0,0,
++728,0,0,0,0,0,0,0,0,0,0,0,0,497,1579,0,0,0,0,62,268,0,0,0,0,0,0,0,1201,0,0,0,0,
++0,0,0,0,0,0,0,0,495,193,0,0,0,0,106,0,0,859,0,0,23,0,0,0,0,0,0,0,813,925,0,0,
++223,613,953,0,0,0,0,0,0,0,0,666,0,0,0,0,0,0,0,0,0,670,0,0,40,216,0,0,0,0,0,0,
++259,0,0,0,440,1114,0,0,0,0,0,0,0,0,74,475,0,0,188,139,0,797,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,1572,0,0,0,0,39,0,0,0,0,0,0,0,0,0,0,0,0,1594,0,0,0,0,0,0,0,290,0,232,
++0,0,887,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,521,14,0,0,0,0,0,741,0,0,0,992,0,
++0,0,0,0,0,0,0,111,0,0,425,0,0,0,0,0,789,0,0,0,1593,0,1768,0,0,233,0,0,0,0,943,0,
++0,0,0,0,0,0,955,225,245,0,0,0,0,0,0,241,0,0,0,0,1943,0,0,0,1284,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,709,0,0,0,0,0,0,554,0,0,0,0,0,0,0,0,1564,0,0,0,
++443,0,0,0,0,0,0,280,0,0,0,0,0,0,0,0,729,0,0,0,348,0,0,0,0,0,0,0,758,848,298,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,829,1422,189,121,0,0,632,812,0,0,556,0,0,0,0,0,436,172,
++530,844,232,984,0,0,0,0,0,0,0,0,0,0,147,0,0,0,0,0,0,0,0,537,0,0,0,0,0,859,0,0,
++842,0,0,0,0,0,0,0,0,0,0,1291,0,0,0,0,0,0,0,0,0,0,0,1482,612,392,0,0,0,262,31,0,
++0,0,0,0,0,0,0,0,0,753,549,0,0,0,0,0,0,696,0,0,0,0,0,0,0,834,0,0,0,0,0,771,0,0,0,
++0,0,0,0,0,0,0,0,0,0,921,0,0,0,674,0,0,0,0,0,0,0,0,0,0,308,444,0,0,0,0,0,0,805,
++180,0,0,278,271,0,0,214,505,0,1215,0,0,0,0,0,0,387,271,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,1645,42,92,0,459,0,0,330,1557,0,0,0,0,0,0,0,0,113,18,0,0,0,
++1742,0,0,0,965,0,0,0,0,0,0,0,0,0,0,0,0,0,182,0,0,65,0,0,0,0,0,0,0,0,0,0,0,0,973,
++0,0,0,0,0,328,0,0,588,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1786,
++0,0,962,1985,0,0,0,308,508,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,588,0,0,0,0,0,0,614,793,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,290,0,0,0,0,0,0,0,0,0,0,1136,0,0,0,0,0,0,0,0,0,0,796,719,0,0,
++326,210,0,0,0,701,758,472,0,0,0,1947,278,1079,0,0,0,0,0,0,497,41,0,0,634,46,961,
++0,810,524,0,0,33,0,0,0,0,0,0,0,0,0,0,0,0,532,0,997,0,0,0,0,0,0,0,0,0,0,0,1301,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1298,0,671,0,0,0,306,0,0,0,0,0,0,0,0,0,0,
++693,1823,0,0,0,759,0,0,0,0,0,1932,0,0,0,0,0,0,0,0,0,0,0,0,0,0,88,182,0,0,0,1964,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,521,0,0,0,0,0,0,424,857,0,0,0,0,671,328,0,
++529,0,0,0,0,0,716,0,1509,80,67,0,0,0,0,59,141,0,0,0,0,0,0,783,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1498,0,0,0,0,343,430,803,1183,677,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,19817,0,5579,9350,0,0,21002,19718,0,0,0,21926,0,0,0,0,0,0,0,0,0,0,0,0,0,20711,
+-0,0,0,20197,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,40550,0,0,0,57510,0,0,0,53895,
+-0,0,15017,0,17000,39367,2347,0,0,0,0,0,0,0,0,0,8588,0,0,0,0,0,3273,17862,3498,
+-2085,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19048,0,0,0,0,0,11978,58631,0,0,0,0
+-,0,0,523,0,12969,198,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28197,0,47846,0,0,0,0,0,0
+-,0,0,0,4549,0,0,0,0,0,0,0,0,0,0,687,14917,748,8229,0,0,0,0,0,0,2476,12935,0,0,0,
+-0,0,0,22792,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27528,59142,0,0,20876,20134,0,0,0,
+-0,440,12068,0,58951,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48038,0,0,0,60999,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,15716,7498,5476,0,0,0,0,20202,37959,0,0,0,0,0,0,0,0,0,0,0,0,
+-29801,0,5451,0,0,0,0,0,0,0,0,0,0,50790,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24485,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13573,0,0,22856,0,0,0,0,21927,0,0,0,0,0
+-,0,9130,0,0,0,0,0,0,13732,0,0,0,0,0,0,0,0,0,0,2282,583,0,0,0,0,0,0,0,0,0,0,3726,
+-26503,0,0,0,0,0,0,9258,0,0,0,0,0,0,0,0,21604,0,0,0,45574,0,0,0,0,0,20710,0,0,0,
+-42694,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1163,6694,0,0,0,0,0,0,0,10948,0,0,0,29700,0,0,
+-0,0,0,58823,3796,27399,20939,10180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-19,29287,28649,14534,0,0,16428,45607,0,0,0,0,0,0,25322,0,4908,0,0,0,0,0,0,25476,
+-29097,14246,11053,0,0,0,0,0,0,0,0,18502,0,0,0,44390,0,0,0,17765,0,0,0,0,0,0,
+-24520,0,0,0,0,0,0,0,0,0,0,17319,0,0,0,0,0,0,0,0,0,0,0,0,0,28166,0,0,0,0,0,48198,
+-0,0,31467,0,24585,0,0,0,0,18692,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23596,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,7236,968,13637,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-3763,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14791,0,0,0,12324,0,12741,0,0,0
+-,0,0,0,0,0,0,11108,0,0,0,0,4009,40295,20616,4357,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-15015,0,0,0,0,0,43751,0,0,0,0,0,0,0,0,0,0,0,23013,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-45542,0,0,0,0,0,0,0,0,0,23974,0,0,0,0,17480,20647,0,0,0,0,0,0,8876,0,0,40806,0,0
+-,0,0,0,0,0,14502,17160,17764,0,0,31594,35431,0,0,2890,0,0,0,0,0,0,0,0,27524,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8228,0,56583,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,34278,0,0,0,0,0,0,0,0,0,0,0,0,0,2662,0,26724,0,0,0,0,0,0,0,64198,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22281,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3049,
+-54983,0,0,0,0,0,0,0,837,0,17604,0,0,0,0,0,28838,0,0,0,0,0,0,26312,0,0,3910,0,0,0
+-,25830,0,0,0,0,0,8391,0,19845,19240,1092,0,0,5449,0,0,0,0,17188,0,0,0,0,0,0,0,0,
+-0,10629,0,0,6671,61094,5832,8358,0,0,0,55078,0,0,0,0,0,29860,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,51494,0,28647,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25989,0,0,30153,61318
+-,0,0,0,0,0,0,0,24903,0,0,0,4388,0,42054,0,0,0,0,0,0,0,53158,0,0,0,0,0,0,0,50918,
+-0,0,0,0,0,0,26251,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5929,2853,0,37126,
+-7372,197,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2027,934,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,55686,0,0,5672,5447,0,62758,0,0,0,0,0,0,0,0,0,0,0,0,2923,0,556,1415,
+-0,0,0,0,0,0,0,0,0,8645,0,9477,0,0,0,0,0,0,0,48742,0,0,0,0,0,0,0,0,0,0,24235,228,
+-0,0,0,0,0,0,0,0,0,0,16970,18823,0,0,0,0,0,0,0,0,0,25158,0,0,0,0,0,18567,20072,
+-2823,14313,1830,0,0,0,0,0,0,0,0,27048,23526,0,0,0,0,0,997,492,0,14730,16677,396,
+-13574,0,0,0,41671,0,0,0,0,0,0,0,19045,0,0,0,421,17545,3110,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,47111,14475,56551,0,0,0,0,0,0,0,0,0,0,3697,0,0,0,0,0,0,49382,0,35559,0,
+-0,0,0,40,0,11496,15621,0,8550,0,0,0,63462,0,0,0,0,0,0,0,36966,0,50406,0,46022,
+-1001,0,0,12069,3249,0,0,0,0,0,0,0,0,0,0,0,0,0,15241,0,0,0,0,0,0,0,0,64743,0,0,0,
+-0,0,58759,0,0,0,0,1136,26981,0,0,0,0,0,0,0,17732,0,0,0,17157,20011,6629,0,43879,
+-0,0,0,13572,25128,10759,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28676,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,875,24007,0,0,0,0,7628,0,0,0,0,0,12268,0,0,0,0,0,0,0,0,19300
+-,23210,356,0,0,0,0,0,0,0,0,0,15236,0,0,0,0,0,49670,0,0,0,0,0,0,0,21764,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,13931,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,45799,0,0,436,3589,
+-0,0,11402,0,0,0,0,0,0,0,0,0,0,62822,0,0,0,39814,588,0,0,0,0,0,0,27750,0,0,0,0,0,
+-0,1609,22660,2346,18951,0,16068,0,0,0,0,0,0,5162,11110,0,0,0,0,15048,1060,0,7879
+-,18280,326,0,14886,19656,0,7594,0,0,0,0,0,781,581,0,16198,0,0,0,0,0,0,1078,9892,
+-0,0,0,0,0,0,0,0,0,0,4489,0,0,0,0,33798,0,0,0,54534,0,0,0,0,0,0,0,33158,0,0,0,0,0
+-,0,0,0,0,42086,13834,2757,8456,16773,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3434,0,0,0,
+-0,0,3946,29668,0,0,30634,36775,0,0,0,0,0,24901,0,16069,6280,0,0,0,0,41990,0,0,0,
+-0,0,0,0,27365,0,0,0,0,0,0,0,0,0,0,1450,44807,0,0,0,32100,0,0,0,0,0,35110,0,0,0,0
+-,0,0,0,0,17448,19591,0,0,0,0,0,0,0,0,0,0,0,0,1739,0,0,0,0,5511,0,0,0,32934,0,0,0
+-,0,0,0,0,0,0,18180,0,0,0,23428,19754,0,0,31174,3021,31655,23464,0,0,0,0,0,0,
+-57255,0,0,21292,64487,0,0,0,0,0,0,25802,9189,0,0,0,0,0,49254,0,0,0,0,0,0,0,0,0,0
+-,5837,50023,0,0,0,0,0,0,0,0,0,15495,0,0,0,0,0,51942,0,0,0,0,0,0,0,0,28104,58662,
+-0,50214,0,0,0,0,0,0,0,0,2988,0,22888,31812,0,0,0,0,0,2020,0,18916,0,0,0,0,0,0,0,
+-23973,0,0,0,0,17516,11717,0,0,0,55911,0,0,0,0,0,0,0,2855,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,46822,0,24710,28586,0,0,0,1556,0,0,30117,0,0,22090,57127,3403,14087,0
+-,0,0,0,0,0,0,0,0,0,1041,0,10633,6916,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27269,0,0,13322,18055,0,29380,0,56454,0,0,120
+-,0,0,8773,0,0,0,0,16040,0,0,0,0,0,0,0,27242,23781,0,1572,0,28134,0,0,1512,0,0,0,
+-0,0,0,27684,0,38470,0,0,0,0,0,0,1513,8709,0,0,0,0,0,0,0,0,0,0,0,46566,0,0,0,0,
+-28521,61159,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24356,0,0,0,0,0,0,0,0,0,13028,0,
+-5863,0,0,15693,0,0,0,0,0,0,0,1131,23398,0,0,0,0,0,0,0,26212,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,18404,0,0,0,0,1457,26183,0,0,2475,7110,0,0,0,0,27180,60166,0,0,0,20262,0,
+-41862,0,0,0,0,0,0,0,0,0,0,2762,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26148,0,0,0,0,0,0,0,0
+-,0,28229,0,0,0,29254,0,0,0,0,0,0,0,0,0,0,27690,0,0,13636,12776,1862,0,0,0,0,0,0,
+-17225,3271,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28039,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,4457,18117,0,2023,402,0,0,0,0,0,0,0,0,0,0,0,0,0,104,3654,0,0,
+-0,0,0,0,0,0,18440,0,0,0,0,0,0,0,0,29861,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,22150,0,0,0,0,0,0,0,0,0,0,0,0,24074,0,0,0,0,0,0,0,0,12004,0,32358,
+-0,0,3081,0,0,0,0,0,0,0,0,0,4749,0,0,0,0,0,0,0,0,0,0,0,10792,1799,21322,0,7880,
+-12613,0,0,0,0,0,0,0,0,13993,0,0,0,16202,0,0,0,0,32102,0,37223,0,10500,0,0,0,0,0,
+-0,0,0,32008,0,0,0,0,0,23816,3236,0,0,0,0,0,23237,0,0,5642,0,4684,294,0,0,0,0,0,0
+-,0,0,0,0,0,0,0,0,0,0,0,0,0,26852,0,0,0,0,0,0,7148,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-0,0,0,0,0,0,0,0,0,0,7890,61798,939,0,0,56679,0,0,0,0,0,27078,202,5029,0,0,0,0,0,
+-0,0,0,0,28005,0,0,15273,24741,5676,20452,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,55910,0,0
+-,0,0,5069,27942,0,21092,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12517,0,0,0,0,0,0,
+-0,0,0,0,0,0,21384,28260,0,2502,20108,0,0,0,0,0,0,0,0,0,0,0,0,46726,0,30790,0,0,0
+-,0,0,14725,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1099,6372,0,0,0,12422,15182,0,8683,0,
+-10665,19462,0,0,0,0,0,0,1590,0,31628,0,22632,19750,0,0,0,0,0,0,0,24198,0,0,0,0,0
+-,50662,0,0,0,0,0,0,0,0,0,0,9131,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11015,0,0,0,0,0,0,0,
+-0,16490,54695,0,0,0,0,0,0,0,0,12937,0,0,0,0,16004,0,0,0,0,0,0,0,0,0,2181,6923,0,
+-0,0,0,0,0,0,15624,11302,0,0,5673,7559,0,0,14668,15684,0,0,0,0,0,0,24204,48134,0,
+-24230,0,55527,0,0,3464,19141,0,0,0,0};
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1357,53,0,0,0,0,590,0,0,0,0,0,0,0,0,0,0,
++0,0,0,329,0,0,0,0,0,0,0,469,0,0,0,0,0,0,0,0,0,0,460,0,0,1743,0,0,963,340,0,0,0,
++0,0,1603,0,0,250,0,0,0,0,0,646,218,0,1794,0,0,0,571,0,455,0,0,0,1012,0,0,0,0,0,
++0,0,0,0,0,0,0,597,161,0,349,0,524,0,0,0,0,0,0,0,0,0,0,0,0,322,432,0,0,0,0,0,0,
++325,223,0,0,0,0,0,566,0,0,0,1394,481,436,0,48,457,610,756,618,0,0,0,755,0,1217,
++0,0,0,0,0,197,0,0,0,0,0,0,0,0,0,0,0,0,0,0,544,492,107,414,0,0,0,0,0,0,0,0,0,0,0,
++1007,0,0,0,0,5,0,0,1580,0,0,0,0,0,0,0,0,0,0,0,0,0,673,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,1843,0,0,0,0,0,0,0,0,0,165,0,0,0,0,0,0,809,885,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,498,0,0,0,306,9,0,0,0,0,0,0,0,437,721,146,0,0,0,0,0,0,0,0,0,0,0,177,0,0,0,0,
++0,0,0,1377,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,200,0,959,0,0,0,1928,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1435,0,481,0,0,0,0,0,0,142,84,0,0,0,0,0,
++1015,0,0,0,315,0,0,0,0,0,0,759,0,0,0,0,0,0,0,0,712,0,0,0,1722,0,0,0,0,0,0,0,0,0,
++0,0,0,222,0,985,1414,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1273,
++538,706,0,0,0,0,0,0,0,0,115,0,0,0,0,0,0,0,0,0,0,1781,0,0,0,0,0,431,97,665,42,
++237,0,0,0,264,0,0,213,0,0,0,0,0,0,0,455,0,0,0,906,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++624,0,574,0,0,0,0,0,0,0,0,0,0,0,0,354,0,0,0,1558,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,
++235,723,1813,0,0,0,957,0,830,0,0,0,0,0,0,0,0,0,0,0,0,23,0,0,496,0,0,0,0,0,0,0,
++547,239,88,0,0,0,0,0,0,0,0,0,1310,0,0,0,0,0,0,0,0,80,1076,0,0,118,0,0,0,479,274,
++0,0,0,0,0,0,0,0,0,0,0,497,0,0,669,261,0,0,0,0,13,0,0,0,0,0,0,791,250,642,0,0,0,
++1429,939,949,0,0,0,0,0,0,0,0,0,0,0,0,0,818,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,982,330,0,0,0,0,545,0,0,0,0,0,0,947,0,1188,0,0,0,0,0,904,0,0,0,0,0,1372,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,693,377,0,0,0,0,0,0,0,0,0,0,0,0,0,0,695,0,0,
++713,386,0,0,0,0,128,1575,0,0,0,0,0,0,424,893,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,904,0,0,0,0,0,552,322,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,1808,49,0,0,0,0,
++1832,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,421,0,0,442,415,0,0,289,
++0,0,0,0,0,206,110,0,0,0,0,0,205,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++19,1539,0,0,0,0,0,1340,0,1194,0,0,0,0,0,0,0,0,549,0,0,0,0,0,0,0,0,1720,0,0,0,0,
++0,0,0,0,0,319,0,0,0,0,112,1180,0,0,0,0,0,0,0,0,0,0,0,967,0,0,0,0,0,0,0,0,0,1940,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,735,0,0,0,0,0,0,0,0,0,897,132,0,0,0,0,0,0,0,
++0,0,0,38,838,0,0,0,379,218,8,660,1017,0,0,0,0,0,0,111,387,647,877,0,0,53,790,0,
++0,0,0,0,0,0,0,458,0,0,0,0,0,0,954,0,0,0,394,0,1367,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,882,0,0,0,0,0,0,0,1409,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,38,124,342,199,0,0,0,0,
++0,0,0,0,0,0,724,628,0,0,0,0,804,266,0,0,0,0,0,208,0,79,0,0,0,0,0,0,0,0,741,0,0,
++0,0,0,0,0,0,0,0,606,0,1494,821,1553,0,0,135,405,0,0,178,100,0,0,0,0,0,0,0,0,0,0,
++0,0,0,481,0,0,0,1378,0,0,0,0,0,0,0,0,0,0,0,0,0,791,33,1227,857,0,467,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,447,0,0,0,0,0,0,86,128,0,0,0,0,0,0,587,0,0,0,692,1018,0,
++195,0,0,0,0,0,0,0,1546,0,0,0,0,0,0,0,0,0,0,0,684,0,0,345,0,0,0,0,0,0,365,0,1683,
++0,0,472,0,433,0,0,0,0,0,0,0,28,0,0,0,997,0,705,3,0,0,0,0,0,0,0,0,0,229,0,0,0,0,
++102,0,0,0,0,866,1022,0,0,0,0,0,0,0,0,0,55,0,115,0,0,0,0,933,0,0,0,0,0,0,0,702,0,
++0,0,0,0,0,0,1728,26,484,0,0,0,185,618,417,0,803,0,0,0,0,0,0,0,0,0,0,0,1262,0,0,
++0,0,0,0,0,0,0,0,0,0,0,633,0,0,0,0,0,0,0,0,0,0,0,0,0,479,262,0,0,0,0,0,0,830,0,0,
++0,0,26,70,0,0,0,0,0,0,0,0,217,0,640,51,0,0,360,1586,0,0,0,0,0,652,0,0,0,0,0,766,
++0,0,0,0,298,737,0,0,0,0,0,0,0,0,0,0,655,222,906,0,0,1013,991,2009,0,0,0,0,503,0,
++0,0,216,154,0,0,0,716,0,844,0,0,0,0,621,252,0,0,0,0,748,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,103,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,576,0,0,0,648,0,0,0,331,0,0,0,
++0,0,0,0,0,0,0,0,0,632,0,0,0,518,107,0,0,0,0,0,0,0,0,851,0,0,0,0,504,0,0,0,0,0,0,
++0,0,0,0,0,0,7,883,0,0,0,0,0,0,0,922,0,0,0,0,0,0,0,0,91,993,0,0,0,0,0,0,200,131,
++10,0,0,0,0,0,0,0,0,0,0,0,0,0,365,1433,0,0,0,0,28,103,0,0,798,1013,0,0,0,0,0,0,0,
++0,39,1925,0,853,0,0,271,519,0,0,0,0,338,0,0,300,470,419,0,0,0,0,0,0,836,0,0,0,0,
++0,0,1937,0,0,0,0,0,393,0,0,357,0,0,0,0,0,703,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,387,0,0,0,0,0,0,75,708,453,1351,0,303,0,0,772,0,0,0,0,0,0,0,0,749,0,0,
++0,0,0,0,0,0,0,0,0,0,0,1065,0,0,717,226,0,0,0,0,0,890,431,626,0,0,0,0,706,0,0,0,
++51,698,0,0,0,0,0,0,0,0,0,0,0,828,0,0,17,0,0,0,0,1929,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,84,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,871,498,0,101,1793,0,0,0,0,0,0,435,0,
++0,0,0,0,966,0,129,1644,0,0,0,0,0,0,0,0,0,0,0,0,0,997,502,0,0,0,0,0,0,0,0,0,0,0,
++0,823,0,1927,0,0,0,0,98,1756,0,0,0,0,0,0,0,0,0,0,0,0,8,0,160,1046,0,492,0,0,0,0,
++0,0,129,45,0,0,0,0,0,0,353,558,0,0,0,0,0,785,0,0,0,1145,189,0,0,0,26,353,0,0,0,
++0,0,2024,0,0,0,606,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,855,0,0,0,0,0,0,0,0,0,0,0,
++0,0,2011,0,0,5,4,0,0,461,764,0,0,0,1449,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1445,0,0,
++0,1168,0,0,0,233,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,216,0,0,0,286,0,0,0,
++3,0,0,0,723,536,0,0,0,0,0,285,0,0,0,560,0,0,0,0,0,690,0,0,0,0,0,1246,0,0,63,0,
++33,0,0,0,0,0,520,1862,0,0,0,0,0,0,0,0,0,0,0,0,630,0,0,0,0,554,0,0,0,0,0,1001,0,
++0,0,0,0,446,0,0,0,0,0,0,0,1313,0,0,837,636,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,278,
++0,0,0,0,0,0,0,0,868,0,0,0,0,1010,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++1231,0,304,0,506,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,0,93,1408,794,
++843,704,0,285,114,485,898,145,0,19,2035,0,0,0,1933,0,0,0,0,0,0,0,1728,0,0,0,0,0,
++0,0,0,746,0,0,0,0,0,0,0,995,1964,0,0,0,0,0,0,0,0,0,0,0,1550,0,874,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,1018,0,0,0,814,126,0,0,1264,0,0,814,955,0,0,0,0,0,0,
++0,981,0,0,0,0,0,0,0,0,915,56,0,0,100,0,0,0,0,0,0,0,0,0,638,0,0,0,0,738,0,0,0,0,
++0,0,0,0,0,758,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1112,0,0,214,0,0,0,133,0,196,
++168,0,0,0,0,0,1152,0,1245,0,0,538,169,871,1816,0,0,413,133,0,0,0,978,0,0,43,93,
++371,0,0,0,0,0,0,526,25,0,754,335,0,0,0,0,182,0,0,0,0,0,0,0,0,0,0,0,39,601,0,0,0,
++0,0,0,0,181,370,0,0,1652,358,0,0,0,0,0,0,0,0,0,176,286,0,788,0,0,0,0,0,1223,780,
++254,1003,896,0,0,0,1447,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,744,0,0,0,0,0,126,0,
++41,788,0,0,0,629,0,0,0,0,0,0,0,0,0,0,0,293,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,420,37,1900,0,0,0,0,542,1570,957,0,0,0,0,0,0,
++0,373,31,0,0,0,0,125,325,0,0,0,0,0,0,323,0,0,1547,0,0,0,0,0,0,0,0,0,0,0,0,0,
++1216,0,0,0,0,0,0,198,1905,629,15,0,0,0,0,0,0,20,75,543,1353,0,0,0,533,0,0,6,0,0,
++0,0,0,0,538,0,0,0,0,0,0,0,0,0,0,0,338,0,0,0,0,11,0,0,0,284,659,0,989,0,0,0,0,0,
++0,0,0,0,848,0,0,507,0,0,0,0,0,0,0,0,188,991,884,0,0,0,0,60,959,0,0,0,0,0,1653,0,
++0,922,337,0,638,0,0,500,0,0,0,0,0,0,0,0,0,0,0,166,0,0,0,0,0,0,0,0,0,0,0,0,418,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,760,0,0,0,0,0,0,1277,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,770,0,0,0,0,0,0,0,243,89,0,0,0,0,0,0,0,0,0,1396,0,
++560,0,0,3,1658,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,586,0,0,1271,0,0,0,505,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,637,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1947,
++41,445,0,0,0,0,0,0,0,0,57,189,0,0,371,0,0,0,0,552,0,883,0,923,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,875,0,0,0,1788,49,0,0,0,0,0,
++0,0,0,0,0,0,661,0,0,1945,0,0,0,0,0,794,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,1135,0,0,0,745,0,0,0,0,0,0,0,84,0,0,0,0,0,0,0,410,0,976,0,0,0,0,0,703,0,0,
++0,0,0,0,187,322,0,0,0,227,0,0,0,0,560,0,31,1395,0,0,0,0,0,466,0,0,0,0,643,167,0,
++0,0,1428,0,412,0,0,0,0,0,0,0,0,0,1118,562,0,0,0,0,0,256,0,0,0,0,0,0,1771,0,0,0,
++0,0,1190,132,0,66,0,0,0,0,0,0,0,0,0,0,317,0,0,0,63,0,0,0,0,0,0,0,1475,0,0,0,0,0,
++0,0,288,0,0,0,0,608,0,0,0,0,0,0,0,0,1225,0,1189,0,0,0,0,0,0,0,1468,0,0,0,0,0,
++689,120,0,0,0,0,0,0,0,1,0,329,0,0,0,0,226,0,0,0,0,0,1855,0,0,461,0,0,0,0,1346,0,
++0,0,0,0,85,0,0,299,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1171,0,0,
++0,980,0,0,0,0,0,0,0,0,637,279,0,0,0,0,0,293,0,0,0,0,528,17,0,0,0,0,5,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,0,0,0,0,0,0,0,601,0,0,0,0,0,0,779,0,
++196,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1322,737,752,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,412,192,80,0,0,8,1470,0,0,0,0,0,0,0,0,0,873,0,0,0,0,0,835,0,0,0,0,256,
++38,986,0,0,0,0,0,0,0,0,0,91,257,278,911,0,0,0,0,0,0,0,0,749,151,0,0,0,0,0,0,0,0,
++0,0,0,0,989,0,0,990,0,0,90,194,0,0,0,0,0,425,0,0,0,0,0,774,0,0,0,0,0,0,0,0,0,0,
++646,827,752,0,0,0,662,0,22,21,0,0,0,0,0,0,95,239,0,0,0,431,0,0,0,0,0,874,0,0,
++265,65,0,0,0,1350,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1887,0,0,0,0,0,0,0,809,
++0,696,0,1074,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,630,0,0,802,0,0,0,56,776,0,
++970,0,0,797,0,0,0,0,0,400,0,0,1951,0,0,41,0,11,118,0,0,0,0,0,0,0,0,251,615,0,0,
++0,1044,0,0,0,0,0,0,0,0,0,0,0,225,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,370,0,0,0,0,
++104,48,209,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,930,0,0,0,0,
++0,0,0,0,0,0,0,1286,0,759,0,120,385,0,0,0,429,0,0,0,0,0,0,0,0,820,0,0,0,0,0,0,
++199,0,10,151,0,0,0,761,365,0,0,0,0,0,0,0,0,0,46,1086,0,0,0,0,11,1624,58,344,0,0,
++1008,1868,0,0,0,888,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,711,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,440,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,914,1913,0,958,0,885,0,0,0,0,0,0,0,0,0,0,0,
++0,0,847,276,0,302,65,0,0,0,510,0,1514,0,0,0,0,0,0,152,291,0,0,0,0,0,0,0,0,0,0,0,
++0,282,589,0,0,0,0,0,0,0,0,0,0,0,0,0,130,0,0,463,42,0,0,0,0,0,372,0,0,0,0,0,0,0,
++0,0,680,0,0,0,0,0,0,0,0,977,1997,0,0,0,810,0,0,0,0,0,0,0,0,0,1390,0,0,0,644,0,0,
++867,982,0,0,0,0,0,0,0,540,0,123,0,0,0,1978,0,0,0,0,789,623,0,1723,0,1220,0,0,0,
++0,0,0,0,480,0,0,0,0,0,0,0,0,0,0,0,888,0,0,0,0,0,0,0,0,0,0,0,0,299,1995,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,788,179,0,0,0,0,0,0,431,156,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1373,39,80,196,0,0,507,0,0,0,646,0,0,0,0,
++0,1214,0,0,0,0,926,0,0,0,1,114,0,0,0,0,0,446,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,490,0,0,0,491,0,1584,0,0,507,250,0,0,0,158,
++10,362,1,0,0,0,0,0,0,0,0,0,408,228,860,480,0,779,0,0,0,557,0,0,142,197,0,0,0,0,
++0,0,0,0,0,0,0,1490,11,378,316,1057,0,0,18,579,299,1546,0,177,0,0,0,0,0,0,0,0,0,
++411,0,0,0,0,727,439,0,0,0,0,0,1528,0,0,0,0,0,0,58,0,482,0,0,0,505,1952,0,0,0,0,
++0,0,0,0,0,0,0,242,0,0,0,0,0,0,0,953,0,0,0,0,802,0,0,0,0,0,0,0,0,0,0,290,0,0,791,
++52,0,0,0,0,0,0,0,0,0,0,0,112,0,0,0,0,0,1028,0,0,138,0,0,0,0,1811,0,0,0,0,0,0,
++934,1821,0,0,0,0,371,38,0,0,0,1296,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,723,0,0,0,0,0,
++0,0,0,0,0,0,0,0,1330,0,0,0,0,0,0,0,1255,296,109,0,0,0,0,0,660,0,0,0,0,270,591,0,
++0,0,0,0,0,0,1090,81,0,0,0,0,391,0,0,0,0,249,322,0,0,0,0,0,0,0,1412,0,0,0,0,0,0,
++0,0,0,0,526,632,0,0,0,0,0,0,235,144,0,0,0,0,0,940,0,0,0,52,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,309,196,0,0,0,0,0,1912,0,1290,0,686,0,0,625,0,0,0,0,0,0,0,0,0,0,0,412,0,
++0,0,0,43,0,0,0,0,11,967,758,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,0,0,0,0,0,0,0,0,0,0,
++873,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,890,0,0,2,0,0,0,0,0,0,0,0,1774,
++393,263,0,0,0,0,0,0,818,456,0,0,251,178,393,97,0,0,0,0,0,674,168,0,0,0,0,0,0,0,
++159,1639,0,0,0,0,0,0,0,0,59,934,0,191,0,0,0,0,346,165,0,877,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,128,0,0,0,0,0,0,1297,0,0,0,0,0,0,164,0,0,0,15,132,241,1073,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,228,324,53,0,0,910,0,0,0,0,0,0,0,0,734,705,
++217,73,0,0,0,0,0,0,0,0,636,389,0,1409,0,0,0,0,0,893,0,0,0,0,21,0,0,0,0,0,0,0,0,
++0,0,0,0,0,721,0,0,0,959,0,0,0,0,1433,0,0,0,0,0,0,0,0,0,0,0,0,174,189,0,0,0,0,0,
++0,0,0,0,0,22,2,0,0,815,354,0,0,0,0,425,0,411,60,13,1611,0,0,0,0,0,0,0,0,0,0,0,0,
++0,1478,596,0,0,398,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,1159,0,0,0,0,0,
++592,223,0,0,0,0,0,0,0,245,64,0,0,0,0,278,0,604,0,0,1502,265,0,0,0,0,0,0,0,310,
++1763,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,129,0,0,0,0,0,0,0,0,0,1356,0,0,0,0,0,0,0,
++0,505,0,0,0,0,0,0,0,1000,0,0,966,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,839,0,0,0,0,0,0,
++0,0,0,0,0,0,0,637,0,0,0,0,0,0,0,0,0,0,0,0,0,0,590,0,0,0,0,280,0,0,0,1386,0,0,0,
++281,0,1064,0,0,0,0,0,917,0,0,15,555,0,0,1014,1883,0,0,0,965,0,0,117,33,0,0,0,
++801,0,0,0,0,0,877,0,824,0,0,0,0,0,0,0,0,0,0,0,365,0,0,0,0,0,0,774,7,0,430,0,0,
++231,360,0,0,0,0,0,0,0,0,822,740,0,0,929,1485,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,852,0,0,0,0,17,0,0,0,0,0,0,1001,0,0,0,0,35,831,0,0,384,457,0,0,0,1351,0,27,
++0,0,984,0,264,552,0,401,0,0,0,710,0,1211,0,0,11,205,0,0,0,0,0,0,0,0,0,0,0,0,5,
++579,0,717,0,0,1011,0,0,0,0,0,0,0,0,0,0,0,0,0,0,805,0,0,0,0,0,0,0,0,0,0,0,489,0,
++0,0,1024,0,0,0,0,0,0,0,0,0,892,0,0,0,0,0,0,0,0,0,0,0,0,473,0,0,0,659,864,0,0,0,
++0,0,0,152,819,0,51,0,0,0,0,0,0,0,0,0,0,130,0,0,0,0,0,229,0,0,0,0,674,0,0,0,0,0,
++0,0,0,0,770,52,79,0,0,0,1666,0,409,0,0,0,0,0,0,0,195,0,688,0,0,0,0,0,0,0,0,0,0,
++0,889,174,160,0,0,0,0,0,0,0,0,0,0,0,0,0,872,0,918,569,268,0,0,0,1224,0,1361,0,0,
++0,0,0,0,0,0,0,374,0,0,0,0,0,731,0,0,0,0,190,0,0,0,0,0,0,0,202,506,444,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,835,0,17,1526,0,0,0,0,0,477,0,0,
++994,1374,76,0,0,0,0,0,0,0,355,287,0,1389,0,0,0,0,0,0,455,384,0,0,0,264,0,0,0,0,
++0,0,0,0,0,0,0,0,1001,0,0,0,0,0,0,0,0,0,0,0,0,28,0,0,0,851,175,359,0,0,0,0,0,0,0,
++0,287,740,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,857,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++819,1402,0,0,0,0,0,0,174,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1649,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,655,573,0,0,0,0,0,0,0,0,128,351,0,0,0,0,0,0,
++0,0,0,0,0,918,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,687,0,0,0,0,0,0,0,0,0,1525,
++0,0,0,1009,0,0,0,0,0,0,0,340,0,0,0,0,0,0,0,0,0,0,861,0,176,0,0,0,0,0,0,0,0,0,96,
++985,0,615,0,0,0,0,0,0,0,1919,0,0,0,0,0,1131,0,0,0,0,0,0,0,247,0,0,0,0,27,23,0,0,
++0,0,0,0,0,0,38,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1015,0,0,0,0,0,1088,0,0,
++0,0,0,1585,0,0,0,0,227,0,0,0,478,360,0,0,0,95,0,0,0,0,0,0,699,0,0,0,26,0,0,0,0,
++1119,0,0,0,739,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,741,67,0,0,0,0,0,0,464,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42,0,96,0,0,0,26,342,0,0,0,0,0,0,203,0,0,449,0,
++0,0,0,0,0,0,0,0,0,256,311,0,0,0,0,0,0,758,0,0,0,0,0,0,0,0,827,0,0,0,0,581,64,0,
++1047,0,0,0,0,0,288,0,0,0,0,0,1375,0,0,0,0,0,0,0,0,0,0,0,1309,0,0,0,0,0,0,0,0,
++376,12,0,0,0,0,0,154,0,1520,0,1753,95,502,0,0,0,0,0,0,0,269,291,1197,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,1341,0,1017,0,0,0,0,0,0,0,
++0,857,1810,533,0,0,1453,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,836,211,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,19,0,156,0,0,0,0,1009,0,0,0,0,0,0,0,0,0,0,0,0,0,820,0,0,
++0,0,0,0,0,0,0,228,0,0,0,1131,0,1276,0,0,0,0,0,0,0,0,0,0,0,0,849,1792,0,0,389,
++291,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,525,0,0,
++0,453,0,0,0,0,666,0,0,0,422,0,355,0,0,0,0,165,0,260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,865,0,0,0,0,0,0,0,1625,0,0,0,234,0,1383,0,0,0,0,0,0,0,0,306,0,0,0,802,1921,
++0,0,0,0,0,0,180,0,0,0,0,1312,814,0,0,0,0,0,0,0,0,0,0,707,0,0,0,1493,11,61,733,0,
++0,0,341,0,0,0,98,0,0,0,0,0,0,0,0,0,0,0,1014,0,0,0,0,0,0,0,142,102,0,0,30,0,0,
++823,0,1045,0,0,0,1930,0,1512,0,0,0,0,0,0,0,87,0,1243,245,0,0,0,0,0,0,0,48,68,0,
++0,0,0,0,0,0,0,126,77,625,938,0,0,351,0,0,0,174,1668,0,707,0,0,0,0,0,0,0,0,0,0,0,
++403,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,282,0,0,0,0,0,0,8,44,0,0,363,115,0,0,0,0,0,0,
++0,0,0,0,0,0,545,761,0,0,835,1254,0,0,0,0,930,1936,0,0,0,0,0,0,0,0,653,0,0,0,0,0,
++344,0,0,1483,673,185,0,0,460,93,753,478,0,0,0,0,0,1020,0,0,0,0,0,0,0,103,0,0,0,
++499,0,0,0,0,0,0,207,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0,968,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,3,0,0,0,0,399,0,0,0,0,224,563,0,0,0,0,0,704,0,0,0,0,0,0,0,0,0,0,0,
++1559,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,861,0,0,0,0,946,333,746,0,0,0,0,0,
++0,0,910,0,0,0,0,0,0,0,0,0,0,0,0,0,652,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++1393,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1514,0,0,0,0,201,0,510,717,0,0,528,0,0,0,0,
++20,0,0,0,1251,0,0,0,1163,0,0,0,307,0,0,0,0,0,1091,0,0,0,0,0,0,0,0,0,0,0,429,0,0,
++0,881,0,0,0,0,0,621,0,0,0,0,0,0,0,736,0,348,0,868,0,0,0,0,433,0,0,0,771,1495,0,
++0,0,0,215,0,0,0,0,0,124,0,0,0,0,0,0,0,0,0,0,0,55,0,0,0,0,0,0,0,112,62,0,856,270,
++0,572,0,0,0,0,939,0,0,0,0,0,0,0,352,0,0,0,0,0,0,0,0,0,647,0,0,0,0,10,0,0,0,0,0,
++0,0,220,0,0,0,0,0,0,0,0,0,0,0,0,0,464,0,0,109,0,0,0,1746,0,0,0,515,0,0,0,566,0,
++0,0,0,0,0,67,40,0,0,722,992,0,0,923,0,0,0,0,0,0,1145,0,0,0,0,0,0,0,0,0,0,0,568,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,247,0,0,0,0,645,0,0,328,0,0,0,0,0,0,0,0,0,0,0,0,
++1363,0,0,0,0,0,1280,0,0,0,0,0,0,0,0,0,0,7,28,360,162,0,0,0,0,0,0,0,0,0,0,0,764,
++0,0,833,862,0,856,0,0,0,0,0,0,736,92,0,0,948,1944,0,1479,63,590,0,0,0,1521,0,0,
++0,709,0,0,61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,483,0,0,0,0,1213,
++0,0,0,0,29,1022,0,1712,0,466,0,0,0,0,0,0,0,0,0,0,0,0,0,731,0,0,0,0,0,0,171,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,241,0,0,0,0,0,0,0,0,0,0,0,964,2005,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,1100,0,0,0,954,0,0,0,0,0,0,0,0,0,1958,0,0,34,549,994,0,0,449,
++137,850,0,0,670,146,0,0,0,0,518,159,0,0,0,0,0,0,0,0,151,0,0,1027,0,0,0,0,0,0,0,
++0,0,0,983,0,0,0,0,993,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,141,501,0,0,0,
++0,0,0,0,0,0,452,0,0,0,0,0,0,0,0,0,0,233,149,0,0,0,0,0,0,0,0,582,0,0,0,801,0,0,0,
++0,0,0,70,0,0,369,0,36,0,0,0,0,0,0,0,204,721,430,241,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1817,16,1078,1021,0,0,
++406,0,0,0,0,0,69,0,0,0,0,0,1830,0,0,0,824,0,0,0,0,0,0,0,0,0,826,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,816,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,717,1845,0,423,0,0,
++0,0,0,0,0,0,510,0,0,1048,0,0,0,618,0,0,0,520,0,0,0,0,990,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,321,0,0,0,0,0,0,0,1135,0,0,921,0,0,0,24,397,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,856,0,0,0,139,282,981,0,288,0,0,0,1890,651,56,0,0,0,0,0,0,0,
++0,261,0,0,0,0,0,0,0,0,0,0,0,617,1403,0,1205,0,0,563,0,0,0,0,0,0,0,0,333,0,0,0,0,
++0,369,0,0,0,0,0,0,0,0,0,622,0,0,0,1407,0,0,0,0,0,0,0,0,0,0,0,0,624,160,0,363,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,619,0,174,292,0,0,656,616,0,0,0,685,0,0,0,0,0,0,0,0,0,0,0,0,0,647,0,0,0,631,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1267,0,0,0,1797,0,0,0,1684,0,0,469,0,531,
++1230,73,0,0,0,0,0,0,0,0,0,268,0,0,0,0,0,102,558,109,65,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,595,0,0,0,0,0,374,1832,0,0,0,0,0,0,16,0,405,6,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,881,0,1495,0,0,0,0,0,0,0,0,0,142,0,0,0,0,0,0,0,0,0,0,21,466,23,
++257,0,0,0,0,0,0,77,404,0,0,0,0,0,0,712,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,860,
++1848,0,0,652,629,0,0,0,0,13,377,0,1842,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1501,0,
++0,0,1906,0,0,0,0,0,0,0,0,0,0,0,0,0,491,234,171,0,0,0,0,631,1186,0,0,0,0,0,0,0,0,
++0,0,0,0,931,0,170,0,0,0,0,0,0,0,0,0,0,1587,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++765,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,424,0,0,714,0,0,0,0,685,0,0,0,0,0,
++0,285,0,0,0,0,0,0,429,0,0,0,0,0,0,0,0,0,0,71,18,0,0,0,0,0,0,0,0,0,0,116,828,0,0,
++0,0,0,0,289,0,0,0,0,0,0,0,0,675,0,0,0,1424,0,0,0,0,0,647,0,0,0,1334,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,36,209,0,0,0,0,0,0,0,342,0,0,0,928,0,0,0,0,0,1838,118,856,654,
++318,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,915,895,454,0,0,513,1425,0,0,
++0,0,0,0,791,0,153,0,0,0,0,0,0,796,909,445,345,0,0,0,0,0,0,0,0,578,0,0,0,1387,0,
++0,0,555,0,0,0,0,0,0,766,0,0,0,0,0,0,0,0,0,0,541,0,0,0,0,0,0,0,0,0,0,0,0,0,880,0,
++0,0,0,0,1506,0,0,983,0,768,0,0,0,0,584,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,737,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,226,30,426,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++117,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,462,0,0,0,385,0,398,0,0,0,0,0,0,
++0,0,0,347,0,0,0,0,125,1259,644,136,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,469,0,0,0,0,0,
++1367,0,0,0,0,0,0,0,0,0,0,0,719,0,0,0,0,0,0,0,0,0,0,0,0,0,1423,0,0,0,0,0,0,0,0,0,
++749,0,0,0,0,546,645,0,0,0,0,0,0,277,0,0,1275,0,0,0,0,0,0,0,453,536,555,0,0,987,
++1107,0,0,90,0,0,0,0,0,0,0,0,860,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++257,0,1768,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1071,0,0,0,0,0,0,0,0,0,0,0,0,0,83,
++0,835,0,0,0,0,0,0,0,2006,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,696,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,95,1718,0,0,0,0,0,0,0,26,0,550,0,0,0,0,0,901,0,0,0,0,0,
++0,822,0,0,122,0,0,0,807,0,0,0,0,0,262,0,620,601,34,0,0,170,0,0,0,0,537,0,0,0,0,
++0,0,0,0,0,332,0,0,208,1909,182,261,0,0,0,1721,0,0,0,0,0,933,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,1609,0,895,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,812,0,0,942,1916,0,0,0,0,
++0,0,0,778,0,0,0,137,0,1314,0,0,0,0,0,0,0,1661,0,0,0,0,0,0,0,1591,0,0,0,0,0,0,
++820,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,185,89,0,1160,230,6,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,63,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1740,0,0,177,
++170,0,1961,0,0,0,0,0,0,0,0,0,0,0,0,91,0,17,44,0,0,0,0,0,0,0,0,0,270,0,296,0,0,0,
++0,0,0,0,1523,0,0,0,0,0,0,0,0,0,0,757,7,0,0,0,0,0,0,0,0,0,0,530,588,0,0,0,0,0,0,
++0,0,0,786,0,0,0,0,0,580,627,88,447,57,0,0,0,0,0,0,0,0,845,735,0,0,0,0,0,31,15,0,
++460,521,12,424,0,0,0,1302,0,0,0,0,0,0,0,595,0,0,0,13,548,97,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,1472,452,1767,0,0,0,0,0,0,0,0,0,0,115,0,0,0,0,0,0,1543,0,1111,0,0,0,0,
++1,0,359,488,0,267,0,0,0,1983,0,0,0,0,0,0,0,1155,0,1575,0,1438,31,0,0,377,101,0,
++0,0,0,0,0,0,0,0,0,0,0,0,476,0,0,0,0,0,0,0,0,2023,0,0,0,0,0,1836,0,0,0,0,35,843,
++0,0,0,0,0,0,0,554,0,0,0,536,625,207,0,1371,0,0,0,424,785,336,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,896,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,750,0,0,0,0,238,0,0,
++0,0,0,383,0,0,0,0,0,0,0,0,603,725,11,0,0,0,0,0,0,0,0,0,476,0,0,0,0,0,1552,0,0,0,
++0,0,0,0,680,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,435,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++1431,0,0,13,112,0,0,356,0,0,0,0,0,0,0,0,0,0,1963,0,0,0,1244,18,0,0,0,0,0,0,867,
++0,0,0,0,0,0,50,708,73,592,0,502,0,0,0,0,0,0,161,347,0,0,0,0,470,33,0,246,571,10,
++0,465,614,0,237,0,0,0,0,0,24,18,0,506,0,0,0,0,0,0,33,309,0,0,0,0,0,0,0,0,0,0,
++140,0,0,0,0,1056,0,0,0,1704,0,0,0,0,0,0,0,1036,0,0,0,0,0,0,0,0,0,1315,432,86,
++264,524,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,107,0,0,0,0,0,123,927,0,0,957,1149,0,0,
++0,0,0,778,0,502,196,0,0,0,0,1312,0,0,0,0,0,0,0,855,0,0,0,0,0,0,0,0,0,0,45,1400,
++0,0,0,1003,0,0,0,0,0,1097,0,0,0,0,0,0,0,0,545,612,0,0,0,0,0,0,0,0,0,0,0,0,54,0,
++0,0,0,172,0,0,0,1029,0,0,0,0,0,0,0,0,0,568,0,0,0,732,617,0,0,974,94,989,733,0,0,
++0,0,0,0,1789,0,0,665,2015,0,0,0,0,0,0,806,287,0,0,0,0,0,1539,0,0,0,0,0,0,0,0,0,
++0,182,1563,0,0,0,0,0,0,0,0,0,484,0,0,0,0,0,1623,0,0,0,0,0,0,0,0,878,1833,0,1569,
++0,0,0,0,0,0,0,0,93,0,715,994,0,0,0,0,0,63,0,591,0,0,0,0,0,0,0,749,0,0,0,0,547,
++366,0,0,0,1747,0,0,0,0,0,0,0,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1463,0,772,
++893,0,0,0,48,0,0,941,0,0,690,1785,106,440,0,0,0,0,0,0,0,0,0,0,32,0,332,216,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,852,0,
++0,416,564,0,918,0,1764,0,0,3,0,0,274,0,0,0,0,501,0,0,0,0,0,0,0,851,743,0,49,0,
++879,0,0,47,0,0,0,0,0,0,865,0,1202,0,0,0,0,0,0,47,272,0,0,0,0,0,0,0,0,0,0,0,1455,
++0,0,0,0,891,1911,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,761,0,0,0,0,0,0,0,0,0,407,0,
++183,0,0,490,0,0,0,0,0,0,0,35,731,0,0,0,0,0,0,0,819,0,0,0,0,0,0,0,0,0,0,0,0,0,
++575,0,0,0,0,45,818,0,0,77,222,0,0,0,0,849,1880,0,0,0,633,0,1308,0,0,0,0,0,0,0,0,
++0,0,86,0,0,0,0,0,0,0,0,0,0,0,0,0,0,817,0,0,0,0,0,0,0,0,0,882,0,0,0,914,0,0,0,0,
++0,0,0,0,0,0,865,0,0,426,399,58,0,0,0,0,0,0,538,102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,876,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,139,566,0,63,12,0,0,0,
++0,0,0,0,0,0,0,0,0,0,3,114,0,0,0,0,0,0,0,0,576,0,0,0,0,0,0,0,0,933,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,692,0,0,0,0,0,0,0,0,0,0,0,0,752,0,0,0,0,
++0,0,0,0,375,0,1011,0,0,96,0,0,0,0,0,0,0,0,0,148,0,0,0,0,0,0,0,0,0,0,0,337,56,
++666,0,246,394,0,0,0,0,0,0,0,0,437,0,0,0,506,0,0,0,0,1003,0,1163,0,328,0,0,0,0,0,
++0,0,0,1000,0,0,0,0,0,744,101,0,0,0,0,0,726,0,0,176,0,146,9,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,839,0,0,0,0,0,0,223,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,246,1931,29,0,0,1771,0,0,0,0,0,846,6,157,0,0,0,0,0,0,0,0,0,875,0,0,477,
++773,177,639,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1747,0,0,0,0,158,873,0,659,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,391,0,0,0,0,0,0,0,0,0,0,0,0,668,883,0,78,628,0,0,0,
++0,0,0,0,0,0,0,0,0,1460,0,962,0,0,0,0,0,460,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,199,0,
++0,0,388,474,0,271,0,333,608,0,0,0,0,0,0,49,0,988,0,707,617,0,0,0,0,0,0,0,756,0,
++0,0,0,0,1583,0,0,0,0,0,0,0,0,0,0,285,0,0,0,0,0,0,0,0,0,0,0,0,0,0,344,0,0,0,0,0,
++0,0,0,515,1709,0,0,0,0,0,0,0,0,404,0,0,0,0,500,0,0,0,0,0,0,0,0,0,68,216,0,0,0,0,
++0,0,0,488,353,0,0,177,236,0,0,458,490,0,0,0,0,0,0,756,1504,0,757,0,1735,0,0,108,
++598,0,0,0,0};
++BROTLI_INTERNAL const uint8_t kStaticDictionaryHashLengths[32768] = {
++8,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,0,12,0,0,0,0,4,22,5,0,
++4,0,0,0,0,0,0,0,0,0,0,0,0,14,6,0,0,0,5,0,0,0,0,0,0,0,7,13,0,0,4,0,0,0,0,0,0,0,0,
++0,6,0,0,0,0,8,0,0,0,0,0,0,7,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,4,0,0,0,4,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,10,4,0,5,13,7,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,8,7,0,0,9,0,8,0,0,0,0,0,0,6,0,
++0,9,0,0,0,11,0,0,6,8,7,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,7,0,0,0,6,8,0,0,0,0,0,
++0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,9,0,0,0,8,4,13,7,0,0,0,0,0,
++7,0,5,0,0,0,0,8,5,0,5,0,0,8,7,0,0,0,0,0,0,0,0,0,0,9,0,0,0,8,0,0,0,10,4,0,5,0,4,
++0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,8,7,0,4,9,4,0,0,0,0,0,0,
++9,0,0,0,8,5,0,0,0,6,0,0,0,0,0,0,0,0,0,7,18,0,0,0,0,4,9,0,0,4,0,6,0,0,0,6,0,6,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,5,8,7,0,0,0,
++0,9,0,0,0,0,0,0,0,8,6,10,6,0,0,0,4,0,6,8,6,0,0,0,4,0,0,0,0,0,5,0,0,0,6,0,0,0,0,
++10,0,12,7,0,0,0,0,0,4,0,0,0,0,0,5,0,0,8,7,0,0,0,0,0,0,0,0,9,5,0,0,0,0,0,0,0,0,0,
++0,0,0,0,6,11,0,0,0,0,0,0,0,0,0,8,7,0,0,10,0,0,0,0,0,0,0,0,6,10,0,17,0,8,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,8,6,9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++7,0,0,11,4,0,5,0,0,0,0,0,0,0,0,0,0,10,5,0,6,8,5,0,0,0,0,0,0,0,0,0,0,11,5,0,0,0,
++0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,9,0,0,0,0,5,0,0,0,0,0,0,0,0,0,6,0,0,8,7,0,0,0,0,0,
++0,0,0,0,0,0,5,0,0,0,6,0,0,10,0,0,0,20,0,0,0,0,0,0,0,0,6,9,5,0,0,0,0,10,4,8,0,0,
++4,13,0,0,0,0,0,0,0,9,0,9,0,0,0,0,0,0,0,0,0,0,0,0,4,8,6,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,12,0,0,4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,12,5,0,0,10,4,10,7,13,
++0,0,0,0,0,0,0,0,6,0,6,0,6,0,0,0,0,0,0,19,0,0,4,12,6,9,0,0,0,0,4,0,4,11,0,0,0,0,
++0,0,0,12,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,4,0,0,0,0,0,0,0,0,0,6,0,0,0,0,
++0,5,0,0,0,0,0,6,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,8,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,9,6,0,0,0,0,0,4,0,4,0,0,0,0,0,0,0,0,0,4,0,0,0,
++6,0,0,0,0,0,0,0,0,0,0,13,6,0,0,0,0,0,0,0,0,0,0,0,6,8,0,0,0,0,0,0,0,0,0,0,6,0,0,
++0,0,0,5,0,0,0,0,14,4,0,0,0,4,12,5,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,8,6,0,
++0,0,0,0,0,12,0,9,6,0,0,0,0,13,0,0,5,0,0,0,0,0,4,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,13,0,9,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,5,0,0,0,6,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,8,7,8,4,0,0,0,0,0,0,0,0,0,0,0,7,0,7,0,0,0,4,0,
++0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,8,6,8,4,0,0,0,0,0,6,0,7,0,
++0,0,0,0,0,0,0,0,0,10,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,7,0,0,0,0,0,0,9,5,0,0,
++0,0,0,7,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,9,4,0,0,0,0,0,0,0,4,
++12,5,11,0,0,0,0,0,0,0,0,0,8,7,0,5,0,0,8,7,0,5,0,0,0,0,8,0,0,0,0,7,0,4,10,0,0,0,
++0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++13,5,0,0,0,4,0,0,0,0,0,6,0,0,0,0,0,0,14,5,0,0,0,7,0,0,10,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,6,0,4,0,5,0,0,0,0,8,5,0,0,0,0,0,0,9,5,9,0,0,0,0,0,0,0,0,6,9,0,
++0,4,0,0,0,7,0,0,0,6,0,0,10,4,0,0,0,0,0,6,0,0,10,0,0,0,8,5,0,0,0,0,0,0,0,0,10,0,
++0,0,0,0,18,4,12,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,8,7,0,0,0,
++0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,8,4,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,
++0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,8,0,0,0,0,0,0,6,0,0,0,4,10,5,0,0,0,0,0,0,0,0,0,0,
++0,4,8,7,0,0,8,6,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,
++0,0,0,8,6,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,6,0,7,0,0,0,0,0,0,
++0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,8,7,0,0,0,0,8,0,12,6,0,6,0,0,0,0,9,7,11,7,0,0,0,
++0,0,0,0,0,0,0,0,0,11,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,10,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,
++0,0,0,6,0,0,0,7,0,4,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,14,0,0,0,0,0,8,4,0,4,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,20,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,12,5,0,7,0,5,0,0,10,0,0,7,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,6,0,4,9,7,0,0,0,
++0,0,7,0,0,0,0,0,0,10,0,9,0,9,0,0,0,0,0,0,0,0,4,9,0,0,0,0,6,0,0,0,0,0,0,0,0,11,4,
++0,6,0,0,0,0,0,0,8,0,8,0,0,0,0,0,0,0,0,0,0,4,0,0,0,5,0,0,0,0,0,0,0,0,13,6,0,0,11,
++0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,0,0,0,0,6,18,0,0,4,0,0,0,0,0,0,0,6,0,0,0,0,0,0,
++0,5,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,6,0,0,0,0,9,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,11,7,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0,0,11,
++4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,4,0,0,0,0,8,
++6,0,0,0,0,0,0,9,6,0,0,0,0,0,4,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,
++0,6,0,6,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,6,0,6,0,0,10,6,0,0,0,7,0,0,8,0,8,7,0,
++0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,9,0,0,0,0,6,0,0,0,0,0,0,0,5,0,0,18,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,
++0,0,0,8,7,0,0,0,0,0,0,0,0,12,0,12,0,0,0,11,6,0,5,0,0,12,0,12,5,0,7,11,6,0,0,11,
++0,0,0,12,0,0,4,12,7,8,6,0,0,0,0,8,5,0,0,0,0,0,0,0,4,11,0,0,6,0,7,0,0,0,0,0,0,0,
++5,0,6,0,0,0,0,8,0,10,0,0,0,0,0,0,0,0,0,0,0,9,7,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,
++0,0,0,0,0,0,0,0,0,11,7,0,0,0,0,0,0,10,0,0,5,0,0,12,6,0,0,0,0,0,0,10,6,0,0,0,0,8,
++6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,5,0,0,0,0,11,0,10,6,0,0,8,6,0,0,0,6,0,7,10,6,0,
++0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,10,7,0,0,0,0,
++10,6,0,0,0,0,0,0,8,5,11,0,8,4,0,0,0,4,0,0,0,0,9,4,8,0,0,0,0,0,0,0,11,6,0,0,0,0,
++10,7,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,7,0,0,0,0,9,6,0,5,0,7,0,0,0,0,0,7,0,0,11,0,0,
++0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,
++0,0,0,0,13,0,8,6,13,0,0,0,11,7,0,7,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,6,0,0,9,6,0,6,0,0,0,0,0,5,0,0,0,0,0,0,0,0,
++0,0,0,0,0,5,9,0,0,0,0,0,0,0,0,0,0,4,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,9,7,0,7,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,
++5,11,5,0,0,0,0,0,0,0,0,0,4,0,7,0,6,0,0,0,6,20,0,0,0,10,7,0,5,14,4,0,0,0,0,0,0,0,
++0,0,6,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,
++0,0,6,0,4,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,9,7,0,0,11,6,15,0,0,0,0,0,
++10,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,7,0,0,0,0,0,0,0,0,9,7,13,0,0,0,0,0,
++0,7,0,0,8,6,0,0,0,0,0,0,0,0,9,4,0,0,0,0,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,5,0,0,0,0,0,0,0,0,0,0,0,0,8,5,0,4,0,0,0,0,0,0,0,0,0,0,12,6,8,0,12,0,0,7,0,0,0,
++0,0,5,10,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,
++14,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,8,7,10,7,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,18,6,
++14,7,0,0,0,0,0,0,0,0,11,6,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,0,11,7,0,0,10,7,0,0,0,6,8,6,0,0,0,0,0,0,0,6,0,0,
++19,0,0,0,9,5,0,0,0,0,0,0,11,7,0,0,0,7,0,6,0,0,11,0,0,0,0,4,8,0,0,0,0,0,0,0,0,6,
++0,0,0,0,0,6,0,0,8,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,7,
++0,7,0,0,0,7,15,0,0,5,0,0,0,0,10,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,7,0,0,
++0,0,0,0,0,0,9,6,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++11,7,0,0,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,
++0,0,5,0,4,0,0,0,4,0,4,0,0,0,0,0,0,0,0,0,6,0,0,0,0,11,6,0,0,8,5,14,0,0,4,0,0,0,7,
++17,0,0,0,0,0,0,0,13,5,0,0,0,0,0,5,0,0,0,5,0,0,0,0,16,6,0,4,0,0,0,0,0,0,12,0,0,0,
++0,0,0,6,0,0,0,0,0,0,0,0,0,0,12,5,0,5,0,6,10,0,12,0,0,0,0,0,0,0,0,7,0,0,0,0,8,4,
++0,0,0,0,0,0,0,0,0,0,8,7,0,0,8,0,0,0,8,0,0,6,0,7,0,0,0,5,0,6,0,4,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,22,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,0,0,
++0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,18,0,0,0,9,4,0,0,8,0,9,7,0,0,0,0,0,0,8,6,0,0,0,0,
++0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,9,7,0,0,0,6,0,0,14,0,0,0,0,
++0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,7,10,4,
++0,6,0,0,0,0,0,0,8,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,9,6,0,0,0,0,0,0,
++0,0,11,6,12,7,0,0,0,0,0,0,0,6,0,5,0,0,0,0,0,0,9,6,11,6,0,0,0,0,9,5,0,0,0,0,0,0,
++0,6,8,5,0,0,0,0,8,0,10,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
++5,10,7,0,0,0,5,8,7,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,4,8,7,0,0,0,6,0,0,
++0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,22,
++0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,5,0,0,0,0,0,0,0,
++0,0,0,0,0,17,0,0,6,0,6,12,4,19,6,0,0,0,0,16,0,0,0,0,7,15,7,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,4,10,4,0,0,8,7,0,7,0,0,9,
++4,0,6,0,0,0,4,0,5,0,0,0,7,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,7,10,0,0,0,0,0,11,7,0,0,
++0,0,12,6,0,0,0,0,0,0,0,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,
++0,0,0,0,0,0,0,0,0,10,4,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,8,7,0,0,
++0,0,0,0,0,6,0,0,0,4,0,0,11,4,0,0,12,7,0,0,0,0,9,0,0,6,0,0,0,0,0,0,0,0,0,5,0,0,0,
++4,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,0,0,0,0,0,9,4,0,6,0,0,0,0,0,4,
++0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,6,0,0,0,5,0,0,0,0,0,0,0,0,0,7,9,6,0,7,0,
++0,0,0,0,0,0,6,0,0,0,0,8,6,0,0,0,0,10,6,11,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,5,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,5,0,4,8,0,0,0,0,0,9,7,0,0,0,0,0,0,
++13,5,0,0,0,0,8,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,8,5,0,0,11,7,0,0,0,0,0,0,8,6,0,
++0,0,0,0,7,0,4,0,0,0,0,0,0,0,5,0,6,0,5,0,0,0,0,0,0,0,0,0,0,0,0,10,4,9,0,0,0,0,0,
++0,4,0,0,0,0,10,5,10,7,0,0,0,0,0,0,0,0,16,7,0,0,0,0,0,7,0,0,0,0,11,0,0,0,0,0,0,0,
++0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,5,0,4,0,0,0,7,0,0,0,0,0,0,13,0,0,
++0,0,0,0,0,0,0,0,7,0,4,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,13,7,0,7,0,4,16,0,0,0,0,6,8,7,9,7,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,
++0,6,0,0,8,5,0,4,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,5,11,7,0,0,11,
++0,0,0,0,0,9,5,0,4,0,0,0,0,9,7,8,6,0,0,0,0,0,0,10,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,
++0,7,0,0,0,0,0,0,0,0,0,0,0,4,10,6,0,7,0,0,0,0,0,0,0,5,0,0,0,0,0,0,10,7,10,0,0,0,
++0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,7,0,6,8,7,12,4,0,0,0,0,0,0,0,5,14,
++0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,
++6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,4,0,0,20,4,0,0,0,7,0,6,0,0,0,0,0,0,0,0,8,0,
++0,6,15,0,0,6,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,12,0,0,0,9,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,5,0,0,0,0,0,0,8,6,0,0,18,0,0,0,10,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,9,6,0,
++6,0,0,0,0,0,0,0,0,9,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,7,0,0,0,0,9,0,9,0,0,4,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,9,5,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,10,0,0,0,0,7,0,0,0,0,0,0,0,0,0,7,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,8,0,8,0,0,0,16,0,0,0,0,0,0,0,
++0,0,0,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,8,0,0,0,11,0,0,0,0,0,0,0,0,0,0,
++6,0,0,0,0,11,0,0,0,9,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,7,0,7,0,6,
++0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,
++0,0,0,0,0,0,0,6,0,0,18,0,8,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,7,0,4,0,0,0,
++0,0,0,0,0,0,0,8,0,0,0,0,0,16,0,0,0,0,0,16,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,18,0,0,0,0,0,0,0,0,0,9,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,4,0,
++0,0,0,0,0,0,0,9,4,0,0,0,0,12,5,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,12,5,0,0,0,0,0,0,0,5,0,0,10,6,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,9,0,0,0,11,0,0,6,0,6,0,0,
++0,7,0,0,0,0,0,0,8,0,0,0,0,6,0,0,0,0,0,0,19,0,0,0,12,0,9,0,0,0,0,0,10,7,0,0,0,0,
++0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,16,7,12,
++0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,12,6,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,10,5,0,0,0,0,0,0,0,4,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,7,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,4,0,0,0,0,0,0,0,4,0,0,9,0,0,0,8,0,12,4,0,0,0,0,
++0,4,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,5,0,
++0,0,0,0,0,13,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,0,0,8,6,0,6,0,0,0,0,0,0,
++0,4,0,0,0,0,0,6,0,0,9,0,0,0,0,0,0,6,0,0,0,0,0,0,11,0,0,0,0,0,0,0,10,6,0,0,0,0,8,
++6,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,7,0,0,0,0,0,7,0,6,
++10,7,0,0,10,5,11,6,0,0,0,0,0,7,16,0,0,0,0,6,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,5,0,0,0,7,9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0,
++0,0,0,0,0,8,7,0,0,0,0,11,6,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++8,7,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,12,7,0,7,0,0,0,
++0,0,0,0,6,0,0,0,0,9,0,0,0,23,0,0,0,0,0,10,5,0,0,0,0,0,0,0,0,0,4,0,0,11,7,10,0,0,
++0,0,0,0,0,0,0,0,0,0,6,0,0,8,7,0,7,0,0,8,7,8,0,0,0,0,0,0,0,0,0,0,0,14,5,0,0,0,0,
++0,0,0,0,18,6,8,7,0,0,0,0,0,0,0,4,0,0,0,0,0,0,11,0,0,0,9,7,12,6,0,0,0,0,0,0,0,0,
++0,0,12,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0,7,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,6,8,7,0,0,0,6,10,0,0,0,9,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,6,
++10,7,0,0,0,7,0,0,8,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,
++0,0,0,8,7,8,6,0,0,11,7,10,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,4,8,7,0,0,0,0,0,0,0,0,
++0,5,0,0,13,0,0,0,0,5,0,0,9,7,0,0,0,0,0,0,0,4,0,0,11,0,0,7,0,0,0,0,0,0,0,0,0,6,0,
++0,0,0,0,0,12,7,19,0,8,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,10,6,8,0,0,0,0,0,0,0,0,0,0,
++6,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,7,0,0,12,0,0,0,0,6,9,6,
++14,0,0,0,0,0,0,6,0,5,0,0,8,7,0,0,0,6,0,4,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,4,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,0,
++7,0,0,10,0,9,7,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,12,6,0,0,0,0,0,5,0,6,0,0,0,0,
++0,0,0,0,0,0,0,6,0,0,0,0,9,7,0,0,0,0,0,0,11,6,0,0,0,0,0,0,0,0,0,0,11,7,0,0,13,7,
++0,0,0,0,0,0,0,0,12,0,0,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,6,11,5,0,5,13,0,8,0,
++0,0,0,6,0,0,0,0,0,0,11,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,11,5,
++9,6,0,0,0,4,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,10,0,0,0,8,5,0,0,9,0,0,0,8,7,9,0,0,0,0,0,0,0,0,7,0,6,0,0,0,0,0,0,0,0,0,
++0,11,0,13,6,0,0,9,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,
++0,0,0,0,0,5,21,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,5,0,0,0,0,0,0,0,0,10,0,8,0,
++0,6,0,0,0,4,0,0,9,0,0,0,0,0,0,0,0,0,0,4,0,0,8,6,0,6,0,7,10,0,8,4,0,4,0,0,0,0,0,
++5,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,6,12,0,0,7,0,0,0,5,0,0,
++0,0,0,0,0,0,0,6,0,0,8,6,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++15,7,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,6,0,0,24,7,0,0,0,0,0,0,0,0,0,
++7,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,6,0,
++0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,4,12,0,0,7,0,0,0,0,0,5,0,0,0,0,0,0,0,0,15,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,8,0,0,0,
++0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,9,0,9,6,
++0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,8,4,0,7,0,0,0,0,0,0,0,0,
++22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,4,0,7,0,0,21,7,0,7,9,6,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,8,0,0,6,
++0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,23,0,0,0,0,7,0,0,0,
++4,0,0,0,0,0,0,0,0,9,4,11,7,0,5,0,0,0,0,11,0,0,4,20,0,0,0,0,0,0,0,0,0,0,0,11,5,0,
++7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++21,0,0,0,0,0,0,7,0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,0,0,0,11,6,0,0,0,0,0,0,0,0,9,6,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,5,0,4,9,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,
++0,0,0,10,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,8,7,0,0,11,7,0,0,0,0,0,0,0,4,
++0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,5,0,0,0,0,0,0,0,0,0,0,8,7,0,
++0,0,0,0,0,0,0,0,6,0,0,21,6,0,0,0,0,0,6,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,14,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,8,0,0,7,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,
++0,0,0,8,7,0,0,11,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,5,0,0,0,7,13,7,10,4,0,
++0,0,6,0,0,0,0,0,0,0,0,0,5,10,0,0,0,0,0,0,5,0,0,0,7,0,0,0,0,0,0,8,4,0,0,0,0,0,6,
++0,0,0,0,0,0,0,0,0,0,12,7,0,6,0,0,10,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,6,0,
++0,0,0,0,7,0,0,8,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,10,5,0,6,0,0,0,0,0,4,0,0,0,0,
++0,0,0,0,0,4,0,0,0,0,9,0,11,4,0,0,0,6,0,0,0,5,12,7,0,5,0,0,0,0,0,4,0,0,0,7,0,0,0,
++0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,13,6,10,0,0,0,17,0,0,4,0,0,0,0,0,6,0,4,0,5,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,11,7,0,0,0,7,0,0,0,6,0,0,0,0,0,0,
++0,6,0,4,0,0,0,0,8,0,0,0,0,5,0,0,0,0,0,4,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,9,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,5,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,12,0,0,
++0,0,7,0,0,0,0,0,0,0,0,0,0,0,7,0,0,16,4,0,0,11,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++8,7,0,4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,8,6,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,
++7,0,0,0,0,0,0,9,0,0,0,0,0,0,0,12,5,10,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,5,0,
++5,18,7,0,0,14,0,0,0,0,0,0,0,9,4,0,7,0,0,0,0,0,0,0,5,0,0,0,6,0,0,0,6,0,0,0,0,0,0,
++8,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,5,0,0,0,7,0,0,0,0,0,0,11,0,0,0,
++10,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,14,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++11,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,14,6,0,0,0,0,11,4,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,10,7,0,6,0,0,9,0,9,5,0,0,0,0,0,
++0,0,0,10,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,8,5,0,0,0,0,0,0,0,0,0,0,11,4,0,6,
++0,6,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,12,4,0,6,8,6,0,0,0,0,0,0,0,0,0,0,8,0,0,5,0,0,0,0,0,0,0,7,0,0,13,0,0,0,0,0,0,0,
++0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,12,7,0,6,0,0,0,
++0,0,0,0,0,0,0,0,0,13,4,0,7,0,0,0,7,0,7,0,0,0,0,0,0,0,0,10,4,0,0,0,0,0,0,0,0,0,0,
++9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,10,6,21,5,0,0,0,0,8,0,0,0,0,4,0,
++7,0,0,0,0,0,0,11,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,0,0,0,
++0,7,9,6,11,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,7,10,0,0,0,0,0,0,6,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,19,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,18,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,7,0,0,0,0,0,0,9,4,10,4,0,7,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,9,7,9,7,10,4,0,7,0,0,0,0,0,0,0,6,12,0,
++0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,
++0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,8,0,
++0,0,0,0,0,5,0,0,8,7,0,0,0,7,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,
++0,0,0,0,4,0,0,8,0,0,6,0,0,0,7,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,7,9,7,0,0,0,4,8,0,0,0,0,6,11,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,10,0,0,0,0,0,0,0,13,4,0,0,
++12,6,0,6,0,0,0,0,8,7,0,7,0,0,0,0,0,6,0,0,0,0,0,0,12,6,0,4,0,0,0,0,0,0,0,0,0,0,9,
++7,22,0,0,0,0,4,0,0,0,0,0,6,0,0,0,4,0,0,9,0,0,6,0,0,24,7,0,7,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,10,6,0,5,0,0,0,0,0,0,0,7,0,0,8,0,0,0,0,0,0,0,10,5,0,0,0,0,0,0,0,0,0,7,0,
++7,0,0,0,0,0,0,13,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,
++0,0,0,0,0,7,12,0,9,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,8,0,0,0,0,0,0,0,0,4,0,0,0,7,0,
++0,0,0,8,7,0,0,0,0,0,0,0,0,0,4,18,0,0,0,0,0,10,0,0,5,0,0,11,0,0,0,0,0,0,5,0,6,0,
++0,0,6,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,
++4,0,0,0,0,0,0,10,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,
++0,0,0,5,8,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,20,7,0,0,0,0,0,0,0,0,0,0,0,4,9,0,12,
++6,8,0,14,7,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,10,0,0,
++0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,9,6,0,7,12,0,0,0,0,4,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,
++0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,0,9,0,
++12,6,0,5,0,0,0,6,0,4,0,6,0,0,0,0,0,0,0,0,10,7,0,0,0,0,0,0,8,0,0,0,0,4,0,0,0,0,
++10,0,0,0,0,0,0,0,8,6,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,0,0,0,0,0,0,0,0,0,0,0,
++6,0,0,12,6,20,5,0,0,0,0,0,0,0,0,0,0,0,0,9,5,0,5,0,0,0,6,13,7,0,0,0,0,15,6,0,0,0,
++6,0,0,13,7,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,5,0,7,0,0,0,0,0,4,0,0,0,0,0,0,0,0,
++10,6,0,0,0,0,0,6,0,0,0,0,9,0,0,0,0,0,19,6,0,0,0,0,0,0,0,0,0,0,13,0,11,0,0,0,0,0,
++0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,0,0,0,0,0,10,0,0,6,0,0,0,0,8,0,0,
++0,9,0,15,4,0,6,0,0,0,0,0,6,12,0,0,0,0,0,0,0,14,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,
++0,0,0,0,0,8,7,0,0,0,0,0,6,10,0,0,0,0,0,0,0,0,7,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,7,10,5,0,0,0,0,8,0,0,0,0,4,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,6,12,0,0,0,10,7,0,5,0,6,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,6,0,4,0,0,0,0,0,7,0,0,0,0,0,0,0,4,9,6,0,0,0,7,0,0,0,0,0,0,0,0,8,6,0,0,
++0,0,0,0,0,4,12,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,7,0,
++0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,12,6,0,6,9,4,0,0,8,4,0,6,
++0,0,0,0,0,4,0,0,0,0,0,0,0,6,0,0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,8,0,0,6,13,4,0,5,8,0,0,0,0,0,0,0,8,0,0,0,10,5,0,0,9,0,0,0,0,0,0,6,0,0,
++24,0,0,0,0,0,0,0,8,0,0,7,0,0,12,0,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,7,0,
++6,8,0,10,0,9,7,0,0,0,5,0,0,0,0,0,0,0,4,8,5,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,4,0,0,0,0,0,6,0,0,0,0,0,5,0,0,0,0,8,0,0,
++0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,10,4,0,0,0,0,0,0,0,6,0,0,0,4,20,0,0,7,
++10,6,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,7,0,0,0,0,9,6,0,0,0,0,0,0,0,4,
++12,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,9,4,0,5,0,0,
++0,0,0,0,0,6,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,6,9,0,0,0,0,7,0,0,0,0,0,6,0,5,0,0,0,0,0,0,0,0,9,0,0,0,
++0,6,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,17,7,0,0,13,6,14,6,0,0,0,0,
++8,0,0,0,0,0,0,7,12,7,8,7,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,4,0,0,0,0,0,4,0,
++0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,12,4,0,0,10,7,0,0,0,
++0,0,0,10,0,0,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,12,0,0,6,
++0,0,0,0,0,0,0,0,8,7,12,0,0,0,0,0,0,6,0,6,0,4,0,0,18,6,0,0,0,6,0,0,0,0,0,6,10,6,
++0,0,0,0,0,0,8,7,14,0,0,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,
++0,0,0,8,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,8,7,0,0,10,5,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,
++0,0,9,4,8,0,0,0,0,0,0,4,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,4,0,0,0,0,
++0,6,0,0,9,7,0,0,0,0,0,5,0,0,0,0,8,7,0,0,14,0,0,0,0,6,0,0,0,0,0,0,9,6,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,5,0,7,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,
++0,0,0,6,0,0,0,6,0,4,0,0,0,0,0,4,0,0,0,0,12,0,0,7,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,
++0,12,0,16,6,0,0,0,0,0,0,11,7,0,4,8,7,0,0,0,0,0,6,0,0,0,0,16,0,0,0,0,6,0,0,0,0,0,
++0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4,10,7,0,0,0,0,0,0,12,7,0,0,0,0,0,0,0,0,0,0,
++0,0,10,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,13,4,0,0,10,0,0,0,0,0,0,0,0,0,19,0,0,0,
++0,0,0,0,0,0,0,0,0,0,8,6,22,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,
++5,0,0,0,0,0,5,0,0,0,0,0,5,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++4,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,7,0,0,18,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,14,7,0,0,11,5,0,0,0,5,0,0,0,0,12,5,0,0,0,0,0,0,0,0,0,0,24,6,0,0,
++0,7,0,4,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,7,0,4,0,0,0,0,8,7,0,0,
++9,6,0,0,14,5,0,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,12,6,0,0,0,0,0,0,0,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,5,0,0,
++0,0,12,7,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,6,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,6,0,0,13,7,0,0,0,0,0,0,14,0,11,4,0,
++0,0,4,0,0,0,0,14,5,0,0,0,0,0,5,11,5,0,0,0,0,22,5,0,0,0,0,0,7,0,0,0,0,0,4,0,0,0,
++4,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,17,0,10,0,0,0,8,0,0,0,19,
++5,18,7,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,10,6,0,6,0,0,0,0,10,4,0,4,0,
++0,0,0,0,0,14,7,0,5,0,0,0,0,0,6,0,0,0,0,0,0,0,0,8,0,9,6,12,0,0,6,0,0,0,0,0,0,0,0,
++12,0,10,6,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,4,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,5,13,0,9,7,0,0,0,0,0,0,0,0,0,0,0,7,9,7,0,0,8,0,0,0,0,0,
++22,0,0,0,0,0,0,0,23,6,14,0,0,0,0,0,0,7,0,0,0,0,11,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,
++0,0,10,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,8,5,0,0,0,0,0,0,0,0,0,7,11,6,21,0,0,0,0,0,
++0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,
++0,0,0,0,0,0,0,4,9,7,0,0,0,0,0,0,12,0,0,0,0,7,0,0,0,0,0,0,0,0,10,4,0,0,0,0,0,0,9,
++0,0,0,20,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,11,7,0,0,0,0,0,0,0,6,15,0,0,
++0,0,0,0,0,0,0,0,0,0,0,12,4,0,5,0,0,0,0,0,0,11,7,17,6,0,0,0,0,0,0,15,6,0,7,0,0,0,
++0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,6,0,5,
++0,0,11,0,11,7,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,
++17,0,0,0,0,6,0,0,0,5,0,0,0,0,0,0,8,7,9,6,0,0,14,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,
++8,7,0,4,0,0,0,0,0,0,0,6,0,5,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,
++0,0,0,5,0,4,0,0,8,7,0,6,12,5,0,7,18,7,0,0,8,5,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,
++10,0,11,0,0,0,0,0,0,0,0,0,0,0,9,0,0,4,0,6,0,7,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,
++7,0,0,0,0,8,0,0,0,15,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,0,0,0,0,0,0,
++0,0,6,0,0,0,0,23,0,0,0,10,7,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,5,0,0,0,0,0,0,8,6,0,0,
++0,0,0,0,12,7,9,7,0,0,10,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,9,0,8,7,0,0,0,
++6,0,6,0,4,0,5,0,0,0,0,0,5,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,7,10,5,0,0,11,6,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,4,9,7,0,
++0,0,0,11,7,0,0,0,0,0,5,0,0,0,7,0,0,0,0,23,6,11,4,0,0,0,0,0,0,9,0,0,0,10,6,0,0,0,
++0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,6,0,0,10,6,0,0,0,7,0,0,
++0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,
++6,11,7,0,0,0,0,0,0,0,0,0,0,0,0,10,5,0,0,0,6,0,0,0,5,0,6,0,6,0,0,0,0,0,0,0,0,0,0,
++0,6,0,0,0,0,8,7,0,5,0,0,0,0,0,6,0,0,0,0,0,0,0,4,10,0,8,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,10,6,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,0,
++0,0,0,0,0,0,10,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,11,6,0,4,0,0,14,5,0,7,0,0,0,0,0,6,16,0,0,0,0,0,0,0,10,0,0,7,15,0,0,0,11,7,0,0,
++0,0,0,0,0,0,0,0,8,7,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,5,0,0,0,
++0,8,0,0,6,0,0,0,0,0,0,9,5,0,0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,6,0,
++0,0,0,0,0,0,7,0,0,0,0,15,7,0,0,0,0,8,0,0,0,14,0,0,0,0,0,0,0,16,7,0,0,0,0,0,7,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,12,6,11,7,
++9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,
++7,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,12,0,10,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,8,0,0,5,8,7,10,6,0,0,0,7,0,0,0,0,12,6,
++0,0,9,0,0,0,12,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,4,10,0,0,0,10,5,0,0,0,0,0,0,9,6,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,6,0,0,9,5,0,4,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,9,0,0,5,0,0,8,7,8,
++6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,10,0,9,4,0,0,0,0,0,0,0,6,
++11,0,0,0,0,0,0,0,0,0,0,0,8,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,8,7,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,
++0,0,0,10,0,0,0,8,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,
++0,0,8,4,0,5,0,0,0,0,0,0,0,7,0,0,0,6,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,22,0,0,0,0,0,0,0,8,5,0,0,0,
++0,0,0,0,7,0,0,0,6,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,5,0,6,0,7,0,0,0,0,
++20,0,0,0,0,0,0,0,0,0,0,7,9,0,0,0,0,0,0,6,0,6,0,7,0,0,0,7,0,0,0,0,0,0,0,4,0,0,0,
++0,0,0,14,7,0,0,0,5,0,0,22,4,10,0,0,0,0,0,0,4,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,11,5,13,0,0,0,0,0,0,0,0,0,8,0,0,7,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,10,7,0,
++0,0,0,0,0,0,6,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,7,0,7,14,6,0,0,0,0,9,5,
++0,0,0,0,0,6,0,0,0,5,10,0,8,6,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,6,0,0,8,4,0,6,0,
++0,0,5,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,
++14,0,0,5,0,0,18,0,8,4,0,6,0,0,20,0,13,0,0,0,0,7,0,4,0,0,0,0,0,4,8,4,0,0,0,0,0,6,
++0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,4,0,0,0,0,0,0,0,0,14,0,0,0,0,0,9,7,0,0,9,0,0,0,0,
++0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,20,0,14,0,0,4,0,6,8,5,0,0,0,0,0,7,0,0,0,0,0,0,
++0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,10,4,12,7,0,6,0,0,9,7,10,5,
++0,0,8,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,0,0,18,0,0,0,14,7,0,0,0,0,0,4,
++0,0,0,0,0,0,17,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,4,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,
++0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,8,5,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,5,0,7,0,0,0,0,0,
++7,0,0,0,0,0,0,0,0,0,7,0,6,0,0,0,0,0,0,0,0,8,5,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,5,0,
++0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,23,0,0,7,0,0,0,0,0,0,
++0,0,0,0,0,0,0,4,0,0,0,0,0,0,12,7,8,4,0,0,0,0,0,0,0,0,0,6,0,0,9,5,0,0,0,7,0,0,0,
++0,0,0,0,0,0,4,10,0,0,7,0,0,0,5,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,5,0,0,18,7,
++0,0,8,0,0,5,0,0,10,0,0,0,0,0,0,6,0,0,0,0,0,5,0,7,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,
++6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,6,0,0,10,0,0,5,10,4,0,0,12,0,0,0,0,
++6,22,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,5,0,0,0,0,0,7,0,5,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,6,0,7,0,0,0,6,0,6,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,5,0,0,0,7,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,
++0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,16,6,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,12,7,0,0,0,0,9,0,0,0,0,6,0,0,11,0,0,0,0,0,13,0,9,6,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,4,0,0,10,7,0,0,0,7,0,6,0,
++0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,11,0,15,0,22,7,0,4,0,6,0,0,0,0,0,7,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,4,0,7,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,
++18,0,0,0,0,0,0,0,0,0,14,0,0,4,0,0,0,0,8,7,9,0,0,0,0,0,9,0,0,0,14,0,0,0,0,0,0,0,
++0,0,11,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,7,0,0,0,6,0,6,0,0,0,0,8,0,0,0,0,
++0,11,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,9,4,0,0,0,0,0,4,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,8,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,
++0,0,0,0,0,0,8,6,0,0,9,5,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,5,0,
++0,10,6,9,0,0,0,0,6,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,
++11,7,12,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,4,0,5,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,
++0,0,0,0,6,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,5,0,0,10,6,
++0,0,0,4,0,7,13,0,0,4,0,0,11,4,0,6,0,0,0,0,0,6,8,7,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,5,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,5,0,0,0,0,12,6,0,0,0,0,
++11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,11,5,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,
++7,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,4,0,0,0,6,17,0,9,0,10,6,0,6,12,0,0,4,0,0,0,
++0,0,0,0,0,0,0,8,5,12,7,0,4,0,0,0,0,0,0,0,0,0,0,11,0,9,0,10,6,11,5,0,7,0,0,8,0,0,
++7,0,4,0,0,0,7,0,0,0,0,0,0,8,6,0,0,0,6,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,6,0,
++0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,11,0,0,0,0,6,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,10,0,0,0,0,0,8,6,0,0,0,0,0,6,12,0,0,0,0,0,
++0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,6,0,0,16,0,11,5,0,0,0,0,0,
++0,0,0,0,0,10,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,9,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0,8,4,0,0,0,0,0,6,10,
++7,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,6,0,0,0,0,0,0,9,5,0,0,0,0,8,0,9,0,0,
++0,0,0,0,0,0,7,10,0,13,0,0,6,0,0,0,0,0,0,0,0,0,6,9,4,0,0,0,0,0,0,10,0,0,0,0,0,10,
++0,0,0,0,0,0,0,10,6,11,0,0,0,0,0,9,0,0,0,0,0,0,4,0,0,0,0,0,0,10,5,0,0,0,0,0,6,0,
++0,0,0,0,0,18,4,0,7,0,0,0,0,0,0,24,0,8,6,0,7,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0,
++0,8,5,0,0,0,0,10,7,0,6,0,0,0,0,0,0,0,0,8,5,10,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,
++6,0,0,8,7,0,0,0,0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,0,4,0,5,15,0,0,0,0,7,0,7,0,0,0,0,
++0,0,0,0,0,6,10,5,0,0,0,6,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,7,0,0,12,0,0,0,0,0,0,0,0,
++0,0,5,0,0,0,0,0,0,14,4,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,11,0,10,4,9,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,4,0,0,0,0,0,7,0,0,0,
++0,0,0,0,0,0,0,0,7,13,7,0,0,0,0,0,0,0,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,
++0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,8,0,10,6,0,4,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0,
++0,0,0,0,0,0,0,10,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,9,7,0,0,0,0,0,6,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,0,0,0,0,6,0,0,0,
++0,0,0,0,5,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,6,0,0,0,5,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,11,0,0,0,0,6,0,0,0,0,0,0,0,6,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22,0,0,
++6,0,0,0,0,0,0,0,6,10,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,
++0,0,0,0,0,0,0,6,0,6,0,0,0,5,0,0,0,0,0,0,0,5,0,0,10,0,11,5,0,0,0,0,0,0,14,7,9,7,
++0,6,0,0,0,0,0,4,0,0,0,0,0,0,11,7,0,6,0,0,0,0,0,0,9,7,0,4,0,0,0,7,0,0,0,0,0,5,0,
++0,0,0,0,5,0,0,0,7,0,0,0,0,0,5,0,0,0,0,17,5,0,0,8,0,0,0,0,6,9,4,0,0,0,0,0,0,0,0,
++8,7,11,7,9,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,6,9,5,0,0,8,6,0,0,0,5,0,
++0,0,0,9,0,0,0,9,6,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,
++0,0,0,0,4,0,0,0,0,10,0,0,0,0,0,0,0,0,4,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,4,0,0,0,5,0,0,0,0,0,7,0,0,0,0,0,7,13,5,0,0,0,7,0,0,0,0,0,7,9,6,11,7,0,7,0,0,0,
++0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,8,5,0,0,0,5,9,4,0,0,0,0,0,0,0,0,8,4,0,0,0,0,
++24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,
++0,0,0,0,6,0,0,0,7,0,0,0,6,0,0,0,0,0,0,0,0,0,5,11,6,0,4,0,7,20,0,8,5,9,5,9,0,0,6,
++0,0,0,0,0,0,0,0,0,0,0,7,23,5,0,0,8,4,0,0,10,0,0,6,0,5,0,0,0,0,0,0,0,0,0,0,0,7,0,
++0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,9,0,0,0,
++10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,
++6,0,0,0,0,14,0,18,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,9,6,0,4,0,0,0,0,0,0,8,4,
++11,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,8,4,0,0,0,0,0,0,0,0,12,0,10,7,0,0,10,0,0,0,0,
++0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,6,0,0,0,0,8,
++6,10,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,6,0,4,0,0,0,0,0,5,0,0,
++0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,17,7,11,0,0,0,0,0,0,0,0,0,0,4,12,6,0,0,0,5,0,0,0,6,0,0,0,0,0,0,0,0,0,0,
++0,5,12,7,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++7,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,6,0,6,0,0,20,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,4,
++0,0,0,5,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,6,0,4,13,0,0,7,0,0,0,0,0,0,
++0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,0,12,6,0,7,0,0,0,0,10,0,23,6,0,0,
++0,4,0,0,0,0,0,6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++10,0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,11,0,9,7,0,0,
++0,0,0,0,0,0,0,0,9,7,0,4,0,0,0,0,8,7,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
++0,0,0,0,0,6,0,0,10,7,10,5,0,0,8,0,8,0,0,0,0,0,0,4,0,5,10,0,0,0,0,0,0,0,9,0,0,6,
++0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,11,7,0,0,0,0,0,0,0,0,9,4,0,0,0,0,0,6,0,0,8,
++7,0,0,0,0,0,5,0,0,0,0,0,0,0,0,10,0,0,0,0,5,0,4,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,24,7,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,6,0,0,9,0,0,0,0,0,0,7,0,6,13,0,8,
++0,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,6,0,0,0,0,8,5,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,
++4,0,0,0,0,0,4,0,0,0,0,0,0,0,6,8,0,0,0,0,6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,4,0,4,0,0,0,5,0,7,0,0,10,0,10,7,0,0,12,5,0,0,9,0,0,0,10,0,
++0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,5,0,0,0,0,0,0,
++12,0,0,0,0,0,8,5,13,6,0,0,0,0,0,0,9,4,0,0,0,0,8,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,
++0,0,6,0,0,14,0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,17,6,0,0,0,0,12,6,0,0,0,0,8,0,0,7,0,
++7,0,4,9,0,0,6,0,0,0,6,0,0,0,0,0,0,8,7,0,0,0,0,0,0,11,0,0,4,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,18,7,0,4,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,6,0,0,0,0,0,
++0,0,0,12,5,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,8,0,11,7,0,0,0,0,0,0,0,0,0,4,0,0,0,0,
++11,0,0,0,0,0,0,0,21,0,0,6,10,0,0,0,0,0,9,0,10,0,0,0,0,0,11,0,0,0,0,6,0,0,0,0,0,
++5,0,0,0,0,0,0,10,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,4,0,0,23,7,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,9,7,0,0,0,7,
++0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,6,0,0,
++11,6,0,0,0,0,0,0,0,6,0,0,0,0,10,7,0,0,9,4,0,0,11,0,8,5,0,0,0,7,8,5,22,0,0,0,9,6,
++0,0,0,0,0,0,0,6,10,4,0,0,0,0,0,7,9,4,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,4,0,
++0,0,0,11,6,0,0,0,0,0,0,0,0,0,0,0,7,0,6,0,0,0,0,0,7,0,0,0,0,0,0,0,6,0,6,0,4,0,0,
++0,0,0,0,0,7,0,7,0,4,13,0,0,0,0,0,8,0,0,0,0,7,0,0,0,0,0,0,11,6,0,7,0,0,0,0,9,0,0,
++0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,4,8,0,0,0,0,0,8,0,0,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,6,0,0,0,0,13,5,8,0,0,
++0,0,0,0,0,14,0,0,6,0,0,0,0,0,0,0,0,0,7,0,0,17,6,0,0,0,0,13,4,0,0,9,6,0,0,10,5,0,
++0,10,5,0,0,0,0,13,0,0,0,0,6,0,0,0,0,0,0,10,0,12,0,0,0,0,0,0,0,0,0,0,0,8,4,0,4,0,
++0,0,4,0,0,0,0,0,4,0,0,12,0,0,5,9,4,0,0,0,0,0,0,0,0,0,5,8,5,0,0,0,7,0,0,0,0,8,7,
++0,0,0,6,12,5,0,0,0,5,0,0,0,5,0,0,0,0,0,4,12,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,8,7,0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,
++0,9,6,0,0,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,11,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,
++0,0,0,0,12,7,0,0,0,7,10,7,0,0,11,0,0,0,0,0,0,0,0,0,11,7,0,0,0,6,0,0,11,0,0,0,0,
++0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,22,0,10,7,0,0,8,5,0,0,0,0,0,5,0,0,0,0,0,0,
++0,0,0,0,9,6,8,7,0,6,0,0,0,0,0,5,0,0,0,0,0,0,8,7,0,0,0,0,9,7,0,0,0,6,0,0,8,7,0,0,
++0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,4,0,5,0,0,0,4,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,6,0,0,0,0,0,0,0,4,0,0,0,0,0,0,9,
++6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,4,0,0,0,5,0,0,0,0,14,0,0,0,
++9,0,0,0,0,0,0,0,0,0,9,7,12,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,12,0,0,0,0,0,12,7,0,0,0,5,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,10,7,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,6,0,0,0,0,0,0,9,6,0,0,0,0,0,6,0,0,0,0,0,
++0,0,0,0,0,9,0,0,0,0,7,0,6,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,
++0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,6,0,7,12,6,0,0,0,0,0,5,0,0,0,0,0,0,0,0,
++0,7,0,0,8,6,0,0,0,0,10,7,0,0,0,0,0,0,0,6,0,0,0,0,0,6,12,0,0,0,0,0,0,0,0,6,0,0,0,
++0,0,6,0,0,0,6,0,0,0,0,0,6,16,0,0,0,0,0,0,0,0,0,9,0,17,0,14,7,8,0,0,0,0,0,0,6,0,
++0,0,0,0,0,0,0,0,0,11,0,0,6,8,7,0,6,0,0,0,0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,0,0,0,0,
++9,0,0,0,0,7,0,0,0,0,11,5,0,4,9,6,8,0,0,0,0,0,0,0,0,0,10,0,11,7,0,0,0,0,0,0,0,0,
++9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,
++0,0,0,12,0,0,0,0,0,10,5,0,4,0,0,0,0,0,7,10,6,11,6,0,0,0,0,0,0,0,0,0,0,0,0,17,0,
++0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,8,0,0,4,0,0,0,6,0,0,0,
++0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,4,0,0,0,0,9,6,0,0,0,4,0,0,0,0,0,4,10,7,0,7,0,0,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
++0,0,0,0,0,0,6,0,0,0,6,0,6,0,0,0,0,10,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,18,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,13,0,0,0,0,0,10,0,0,0,0,0,0,0,0,4,
++0,0,0,6,0,0,0,0,0,4,8,0,0,0,11,7,0,0,0,4,0,0,0,0,0,7,0,0,8,5,0,0,16,0,0,0,13,6,
++0,0,0,0,0,0,0,6,0,0,0,0,20,0,11,6,0,0,8,7,0,0,0,0,0,6,17,0,8,0,0,0,0,0,8,7,0,0,
++9,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,
++0,0,4,0,7,0,0,0,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,8,
++0,8,0,0,0,0,0,0,0,11,0,8,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,6,0,0,9,0,
++0,0,0,0,8,0,0,0,0,0,18,0,0,0,0,0,0,4,9,0,0,0,0,0,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,9,6,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,7,0,0,0,0,0,0,0,0,
++0,4,0,0,0,0,0,0,14,0,0,0,0,7,0,6,0,0,8,0,20,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,8,0,0,0,14,0,0,0,0,0,0,0,8,0,0,7,0,6,0,0,0,7,0,0,0,0,0,0,0,0,
++0,0,0,4,12,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,10,6,0,
++5,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,
++0,0,0,5,8,4,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,12,7,0,
++0,0,0,13,6,0,0,0,7,0,0,8,0,0,0,8,0,0,0,0,0,0,0,0,0,0,5,0,0,0,7,0,0,0,0,0,0,11,5,
++0,6,0,0,8,5,0,7,0,0,0,0,0,0,0,7,0,0,0,0,8,6,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,4,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++14,0,10,7,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,19,0,0,4,0,0,0,7,
++0,0,11,5,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,16,0,10,5,18,0,0,7,9,6,0,5,0,0,0,0,0,
++0,0,0,0,5,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,5,0,0,0,7,0,6,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,6,0,0,0,4,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,6,0,0,0,7,23,0,0,0,0,5,0,0,0,0,0,0,8,5,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,14,0,20,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,
++11,0,0,0,0,7,0,0,0,0,15,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,7,0,0,0,0,
++0,4,0,0,0,0,10,0,0,0,0,0,9,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,10,0,11,6,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,5,0,0,11,0,0,0,0,7,0,0,0,0,0,0,8,7,0,
++4,0,0,0,0,11,0,0,0,0,0,11,0,0,5,0,0,8,7,0,4,0,7,0,0,0,0,0,0,0,6,0,0,0,0,0,4,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,10,5,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,6,0,5,0,0,0,0,0,0,0,
++0,0,4,11,5,10,7,0,7,0,0,9,6,9,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,9,4,0,4,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,8,6,0,0,0,0,11,7,0,0,0,0,0,0,0,0,0,0,11,7,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,8,5,0,0,8,0,9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,
++10,7,0,0,0,6,0,0,0,0,0,0,8,0,0,6,0,0,0,6,10,0,0,0,0,0,0,0,0,0,0,0,8,5,0,0,0,6,0,
++0,0,6,0,0,0,0,9,5,8,5,8,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,
++0,8,7,10,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,0,11,7,0,0,0,0,0,5,0,0,0,6,0,7,0,0,
++10,5,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,11,0,0,0,0,0,13,4,
++0,0,0,4,0,0,0,0,0,5,8,0,0,0,12,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,7,14,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,7,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,4,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,5,0,0,15,6,10,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,14,6,10,0,0,0,0,0,0,0,0,6,0,
++0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,6,0,5,11,4,0,6,0,0,0,7,0,0,0,0,
++0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,5,0,0,8,5,0,0,0,0,0,0,0,0,0,0,
++0,0,10,0,0,0,0,0,9,6,9,4,0,0,0,4,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,8,5,0,
++0,0,0,0,0,0,0,0,0,0,4,0,0,11,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,5,0,0,0,0,0,0,
++0,0,0,7,12,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,
++4,9,6,0,4,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,6,0,
++7,8,6,0,0,0,0,0,0,0,4,0,0,9,6,0,0,0,0,0,0,0,0,0,6,0,5,0,4,0,0,0,0,0,0,0,5,0,0,0,
++0,0,5,0,0,0,7,12,7,0,0,0,0,0,0,18,4,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,6,0,0,0,
++0,12,0,0,7,0,0,0,0,0,7,0,0,13,0,0,6,0,0,0,0,8,7,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,7,10,5,0,0,8,0,0,0,0,0,0,0,8,6,0,7,0,0,8,4,0,4,0,0,0,0,10,4,0,0,14,0,
++0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,17,0,0,0,0,0,0,6,0,0,0,0,8,6,0,0,10,5,0,0,0,0,8,
++6,0,0,0,6,0,0,0,7,0,0,0,0,0,6,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,12,0,0,0,0,6,
++8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,
++0,0,0,6,0,0,0,0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,4,24,0,0,
++0,0,0,12,6,0,0,10,6,0,5,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,17,7,0,5,0,0,0,
++0,0,0,0,0,0,0,0,0,0,6,11,5,9,0,8,7,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,10,7,0,0,0,0,0,0,0,7,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,11,5,8,7,0,0,0,
++0,8,5,0,0,0,0,10,7,0,7,0,0,0,0,0,0,0,0,0,0,13,6,0,0,0,0,0,0,0,0,0,6,0,4,0,0,0,0,
++0,6,12,0,8,7,0,0,0,0,0,0,0,0,0,0,16,0,10,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,22,0,0,0,
++0,0,0,0,0,0,0,0,0,0,13,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,22,0,0,6,0,0,21,0,0,0,22,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++6,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,6,0,0,0,5,0,0,0,0,0,7,8,0,0,0,0,6,14,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,8,6,0,0,0,0,0,0,
++0,0,0,0,0,6,0,0,0,0,8,5,0,0,11,7,0,6,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,
++6,0,0,0,5,0,0,0,0,0,0,0,0,0,4,0,0,8,7,0,0,0,0,8,5,11,7,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,4,0,0,0,0,8,5,0,0,10,0,0,4,13,7,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,5,0,0,13,6,
++0,6,0,7,0,0,8,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,15,0,0,0,10,7,0,0,0,0,0,
++7,0,0,0,0,0,0,0,4,0,0,0,0,0,6,0,0,0,0,19,0,0,0,0,6,0,0,0,0,0,4,0,0,0,0,0,6,0,5,
++0,7,0,0,0,0,0,0,0,0,0,6,0,0,11,4,0,0,0,6,0,0,13,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,8,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,12,6,0,0,0,0,
++0,7,0,0,0,0,0,0,11,7,0,0,0,0,0,6,0,0,10,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,5,11,6,
++0,0,0,0,0,0,0,0,10,0,0,0,0,6,0,0,0,0,0,0,8,7,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,0,0,
++0,0,0,8,7,0,0,0,0,9,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,10,7,0,0,0,0,10,0,
++0,6,0,0,13,0,0,0,0,0,0,0,9,6,0,0,8,6,8,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,4,0,
++0,9,7,0,0,0,0,0,0,11,0,0,0,10,7,0,0,0,0,0,0,0,0,9,6,0,0,12,4,0,4,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,6,0,0,0,0,21,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,5,0,0,
++9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,4,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0,
++16,0,0,4,0,0,0,0,0,7,0,0,0,6,0,6,0,0,11,0,0,0,0,5,0,0,0,0,0,0,0,4,8,5,0,0,0,0,0,
++0,14,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,
++0,0,8,0,0,0,0,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,
++0,0,0,0,6,9,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,14,7,0,0,9,7,0,0,11,0,0,0,0,0,10,
++4,11,5,13,6,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,5,0,0,0,0,0,4,0,0,9,0,0,0,0,
++0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,6,12,5,0,0,0,6,14,0,0,0,0,0,0,0,0,0,0,4,9,4,
++0,0,0,0,0,5,0,0,0,0,0,0,0,4,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,
++0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,11,6,0,0,13,7,0,0,13,6,0,7,0,0,0,0,0,0,8,6,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,10,6,0,4,0,0,12,6,0,0,0,0,0,0,0,0,10,6,
++0,0,0,6,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,6,0,
++0,0,0,0,7,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,8,6,0,
++0,0,7,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,
++0,0,0,5,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,
++0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,8,7,0,0,8,5,0,0,0,4,9,5,0,0,0,7,10,6,0,0,
++0,0,0,0,9,7,0,0,8,5,8,0,8,4,0,0,13,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,0,0,0,0,0,0,0,
++0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,4,0,0,0,0,0,0,0,0,0,
++0,11,7,0,0,0,7,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,5,0,0,0,7,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,9,7,0,0,0,0,8,5,0,4,0,0,0,0,0,6,0,6,14,
++6,0,0,0,0,9,6,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,6,0,0,0,0,14,7,9,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,16,
++0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,14,0,
++0,6,0,0,8,6,0,0,0,0,0,6,0,0,12,0,0,0,0,0,8,5,0,7,11,0,0,5,0,4,0,0,0,6,0,0,0,0,0,
++0,0,0,0,0,0,0,9,6,0,4,0,6,0,0,0,0,0,0,0,0,0,0,0,0,11,6,0,0,0,0,0,0,10,5,0,0,0,0,
++0,4,0,0,0,7,11,6,0,4,8,5,9,5,0,0,0,5,0,7,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,8,5,14,7,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,16,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,9,6,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,9,0,0,0,12,5,0,0,0,0,0,0,0,4,10,5,0,0,0,0,0,0,0,0,0,0,0,6,0,
++0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,4,0,0,0,6,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,10,4,0,0,0,0,0,5,0,0,0,4,
++0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,8,0,10,7,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,10,7,0,0,0,0,0,0,0,0,15,0,0,0,
++0,0,0,0,0,0,0,7,0,0,0,0,0,7,10,7,9,7,0,0,0,7,0,0,8,0,0,0,0,0,0,0,9,0,0,0,8,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,8,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,15,7,12,6,0,0,0,7,0,5,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0,5,0,0,0,0,
++0,0,0,6,9,5,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,9,7,0,0,14,0,0,0,11,7,0,0,0,0,0,
++0,0,0,0,0,0,4,0,0,11,7,0,0,0,0,8,0,0,0,0,0,0,6,8,7,0,0,0,7,10,4,0,0,0,0,0,0,0,0,
++0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,10,0,0,0,0,0,0,
++6,0,6,0,0,0,0,0,4,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,11,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,7,0,0,10,7,0,0,0,0,9,7,0,0,0,0,0,0,13,7,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,12,0,
++0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,9,6,0,0,11,0,0,
++0,0,0,14,4,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,7,0,0,
++0,0,0,6,0,7,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,5,0,0,0,0,20,
++7,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,8,0,0,0,0,0,0,0,0,0,11,5,0,0,0,0,0,0,0,0,0,0,10,4,0,0,0,5,8,5,10,4,0,0,0,0,0,
++0,13,6,9,7,0,0,10,7,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,6,0,0,0,7,0,6,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,10,7,0,0,
++0,0,0,0,0,0,0,0,12,4,0,0,0,0,8,7,0,0,0,0,0,7,0,6,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,
++0,0,0,0,6,0,6,9,6,0,0,12,5,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,0,
++0,0,0,0,0,0,0,0,0,5,8,7,9,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,11,
++4,0,0,0,0,0,0,8,0,0,0,10,7,0,4,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,0,8,0,
++0,0,0,0,0,5,0,6,0,0,10,0,14,0,0,0,0,0,0,0,23,0,0,0,12,0,10,5,0,0,0,0,0,0,0,0,0,
++5,0,0,0,0,8,0,0,0,0,6,8,0,0,0,0,0,0,0,0,0,22,0,8,0,0,0,0,6,0,0,0,0,0,0,0,5,0,0,
++0,0,0,0,0,6,18,4,0,0,0,7,10,6,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,
++0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,7,10,0,0,0,0,0,0,6,0,0,0,0,11,5,0,0,0,0,0,0,0,0,
++15,0,8,6,0,0,13,7,0,0,0,0,0,7,0,0,0,0,0,7,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,9,5,9,
++0,0,6,8,6,0,0,0,0,10,0,0,0,18,5,0,0,0,5,0,7,0,0,0,0,8,6,0,0,0,0,9,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,14,0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,6,0,0,0,5,0,
++0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,8,5,0,0,0,0,0,0,0,0,9,0,0,0,0,4,0,0,0,0,0,0,0,0,
++0,0,0,0,20,5,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,9,5,0,0,0,0,0,0,8,4,24,0,0,0,0,0,0,
++0,0,0,0,0,0,0,9,7,0,0,0,0,10,5,0,0,8,5,0,0,0,0,0,0,0,0,12,7,0,6,0,0,10,6,0,0,0,
++0,14,0,0,4,9,5,0,0,0,0,0,0,9,0,0,0,0,0,0,6,0,0,0,0,0,4,0,0,8,0,0,0,0,0,11,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,8,5,11,7,0,4,0,0,10,0,0,0,0,
++0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,11,6,0,0,0,0,0,5,14,6,0,0,0,0,10,0,0,
++0,13,4,0,0,0,0,0,0,0,0,0,0,0,6,0,0,10,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,7,12,0,10,6,0,0,0,0,0,0,10,0,0,0,0,0,10,0,9,
++7,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,4,0,7,0,0,0,0,9,7,0,0,0,
++0,0,0,0,0,0,0,0,0,24,0,11,7,0,7,0,0,0,0,0,0,8,6,0,0,0,0,0,0,8,7,0,0,0,0,0,5,0,0,
++0,6,9,0,0,0,23,5,0,0,0,0,0,6,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,7,0,0,0,
++0,0,0,0,0,0,0,0,0,0,6,0,0,18,4,0,0,11,7,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,
++0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,9,0,0,0,11,0,0,0,23,0,0,
++0,10,4,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,4,0,0,0,0,0,7,0,0,19,0,11,0,0,0,0,0,12,7,0,
++0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,5,0,0,0,0,0,5,0,0,0,0,0,5,0,0,0,0,0,0,0,6,0,0,
++9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,4,0,0,0,0,10,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,4,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,22,0,8,7,10,4,11,0,13,5,8,7,9,0,8,7,0,0,0,7,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,
++0,8,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,4,0,0,0,4,11,0,0,6,0,0,8,5,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,8,5,0,0,
++20,0,0,0,0,0,0,0,0,0,11,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,7,0,0,14,0,0,0,9,0,13,7,0,0,0,0,0,6,0,7,0,0,8,6,10,6,0,0,8,6,0,0,0,6,0,
++0,12,6,9,0,0,0,0,0,0,5,9,0,12,4,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,8,5,0,0,0,0,0,
++0,0,4,8,0,0,6,8,0,0,0,0,0,0,0,0,0,13,6,0,7,0,0,0,0,0,6,8,7,8,6,0,0,0,7,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,18,0,11,4,0,0,0,5,0,0,0,0,0,0,0,0,0,0,
++0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,14,
++6,0,0,0,0,12,7,8,0,0,0,0,0,0,0,8,7,0,0,0,0,10,4,0,0,0,0,0,0,10,0,0,6,0,0,0,0,0,
++0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,15,6,9,7,0,0,0,0,0,0,15,6,11,7,0,0,0,7,0,0,21,0,0,
++0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,17,6,0,0,10,5,0,5,0,0,0,0,0,0,0,0,0,7,
++0,0,10,0,0,0,0,0,0,0,0,4,11,5,0,0,0,0,16,7,0,0,0,0,0,6,0,0,8,7,0,4,0,0,10,0,0,0,
++0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,8,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,
++0,0,0,10,4,0,0,0,0,0,0,0,0,0,6,0,5,0,0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,
++0,7,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,6,10,7,0,0,0,0,0,0,0,0,8,4,0,0,10,0,0,0,0,4,0,6,0,6,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,17,0,0,0,0,0,
++0,0,0,0,0,0,10,0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++6,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,0,4,0,0,0,0,0,6,0,0,0,0,0,0,10,5,0,0,
++0,5,0,0,0,0,9,0,19,7,0,0,0,0,0,7,0,0,0,0,10,6,0,0,0,6,0,5,0,0,0,0,0,0,0,0,0,6,8,
++0,0,0,0,0,11,0,0,0,0,0,0,6,0,0,0,0,0,7,9,0,15,0,0,0,0,0,0,0,0,0,0,4,0,0,0,5,0,0,
++0,0,0,0,0,6,0,0,0,0,0,0,0,4,0,0,0,0,9,0,0,0,0,0,0,0,0,6,0,7,0,0,0,0,0,0,0,6,0,0,
++0,0,0,6,10,0,0,0,0,0,0,0,23,0,14,0,0,0,0,7,0,0,0,0,0,7,0,0,9,0,0,0,0,7,0,0,0,0,
++0,6,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,4,0,0,0,
++0,0,0,0,0,9,5,0,0,0,0,0,4,0,0,0,0,9,5,0,0,0,0,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,22,0,0,0,0,0,0,0,10,0,0,0,0,0,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,6,11,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,14,7,0,0,12,7,0,0,0,
++0,0,0,0,0,0,4,0,0,0,0,0,6,0,0,0,0,8,6,10,0,0,0,0,0,0,0,0,0,10,7,8,5,0,0,0,0,0,0,
++0,0,8,4,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,5,0,0,9,5,0,0,0,0,0,5,0,0,0,0,0,4,0,0,0,
++0,0,0,0,0,0,0,12,4,11,0,0,0,9,0,11,7,0,0,0,0,0,0,10,6,0,0,0,6,0,0,0,0,15,5,0,0,
++11,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,4,0,4,0,6,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,8,0,0,0,19,7,0,4,0,0,9,0,0,0,0,0,10,0,
++0,6,0,0,13,0,12,6,0,0,0,0,0,0,0,0,10,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,13,7,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,4,9,0,0,0,10,0,0,0,0,0,0,0,
++0,5,0,0,0,0,0,0,10,0,23,6,0,0,0,6,8,0,0,0,0,0,0,0,0,0,17,7,0,0,0,0,11,6,22,5,0,
++0,9,6,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,5,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,4,11,0,9,4,0,0,
++0,7,0,7,0,0,0,0,0,0,12,4,0,0,0,0,0,0,0,0,0,0,0,0,11,4,0,0,0,0,0,0,0,0,0,0,0,0,0,
++4,0,0,11,5,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,8,6,0,0,0,4,0,0,0,0,
++0,0,0,0,0,7,0,0,0,4,0,0,10,4,0,0,0,0,0,0,0,7,0,7,0,0,0,6,0,0,0,0,8,6,0,6,0,6,0,
++0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,0,0,0,9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,6,22,6,12,0,0,6,0,0,0,6,0,0,0,0,0,7,0,0,0,0,11,0,0,0,
++9,7,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,6,0,0,0,6,0,6,0,0,8,7,0,0,0,4,9,7,19,0,0,0,0,0,0,0,0,0,9,6,10,6,0,6,0,0,0,
++4,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,6,16,7,10,6,0,0,23,6,11,7,0,4,0,0,0,0,0,0,0,0,0,
++5,0,0,0,0,10,7,0,0,0,0,0,7,0,0,0,0,0,0,15,0,10,0,0,0,14,6,0,0,0,0,0,0,0,0,0,0,0,
++5,0,0,0,0,0,0,0,5,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,5,0,0,11,5,0,0,0,0,0,0,0,0,0,0,
++0,4,0,0,0,0,0,6,0,0,10,0,0,0,0,7,0,0,0,0,0,0,10,6,0,0,0,0,8,4,0,0,0,7,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,7,12,5,0,0,0,0,
++0,6,0,0,0,0,9,6,0,0,0,0,0,0,0,6,9,0,0,0,0,6,0,0,0,0,8,7,0,0,0,0,0,0,0,6,0,0,0,0,
++0,0,0,0,0,0,10,5,0,0,0,0,0,0,8,6,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,8,5,0,0,0,0,0,7,0,7,0,4,0,0,10,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,5,0,0,0,0,13,
++7,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,7,0,0,13,0,0,0,0,0,0,0,0,7,10,5,0,0,0,0,0,0,9,7,0,0,8,6,9,
++5,0,0,0,0,0,6,12,0,0,0,0,0,0,0,18,6,0,0,0,0,0,0,0,0,19,7,0,4,0,0,0,0,9,5,0,5,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,7,0,0,0,0,0,0,14,0,0,0,23,7,8,7,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,22,0,0,7,0,0,0,0,0,0,0,0,9,7,8,4,0,
++0,0,0,0,0,0,0,8,5,0,6,0,0,0,0,0,6,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,
++8,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,12,5,0,0,0,0,0,0,0,0,0,0,8,6,0,0,11,7,0,0,0,
++0,12,0,8,6,19,7,0,0,0,0,0,0,0,0,0,0,0,0,0,6,11,0,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,11,7,0,0,0,0,0,4,10,0,0,0,0,0,0,0,8,7,0,0,0,0,14,0,8,0,0,6,10,0,0,
++0,0,0,0,0,12,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,6,0,0,0,0,
++0,0,0,0,13,0,0,0,0,0,0,0,11,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,
++0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,5,0,0,0,6,0,0,0,5,0,7,0,0,0,
++0,0,6,0,0,21,7,0,0,9,6,0,0,0,6,0,0,13,7,0,0,0,5,0,0,0,0,0,4,0,6,0,0,0,0,0,0,0,0,
++0,0,0,4,0,0,0,0,0,0,11,5,0,6,0,0,10,5,0,0,0,0,0,0,0,0,9,6,0,0,8,7,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,9,0,0,0,0,0,0,6,0,0,0,0,15,4,0,0,12,7,0,0,0,6,
++0,7,0,0,8,0,9,5,0,4,0,0,0,6,0,6,0,0,23,4,0,0,0,0,0,0,0,0,0,0,0,0,10,7,0,4,0,0,8,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,0,0,
++7,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,12,6,0,0,0,0,0,0,10,7,0,7,0,0,0,0,0,0,0,0,0,0,
++9,0,0,0,0,0,8,0,0,0,0,4,0,0,0,0,0,0,0,0,0,4,11,5,0,0,0,6,0,6,0,0,0,0,0,0,0,6,0,
++4,0,0,0,0,0,0,0,0,0,0,0,5,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,8,7,0,0,0,6,0,6,0,
++0,0,0,0,0,0,0,0,5,0,0,0,0,0,5,0,0,0,0,11,0,0,0,0,0,0,0,10,5,9,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,23,7,0,0,0,0,0,7,0,0,10,6,18,0,0,0,
++0,0,0,0,8,7,0,6,0,0,0,0,0,0,8,5,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,
++0,0,0,0,0,6,0,0,0,4,12,7,0,0,0,0,0,0,0,0,10,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,13,5,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,4,0,0,0,0,0,0,0,0,
++11,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,
++0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,10,0,11,0,0,0,0,0,0,0,0,0,
++17,5,0,4,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,4,0,0,0,0,8,7,0,0,0,0,0,0,0,
++0,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,
++10,0,0,0,8,6,0,0,0,7,0,0,0,0,0,0,8,0,0,0,14,0,0,0,0,7,0,0,0,4,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,9,4,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,
++10,0,0,0,16,5,0,0,0,0,0,0,8,0,0,4,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,10,0,0,0,
++0,0,0,0,0,5,0,0,0,0,12,5,0,7,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,7,0,
++0,0,0,0,0,0,0,12,6,0,0,0,0,0,7,0,6,0,6,12,6,0,0,0,0,0,0,0,4,8,7,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,10,6,8,0,0,
++6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++16,0,8,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,23,5,0,0,0,7,0,6,0,
++0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,14,0,0,0,0,7,0,0,0,4,17,5,0,0,0,0,11,0,9,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,6,0,0,0,5,0,7,0,0,0,0,0,0,0,0,8,0,0,0,
++12,6,0,0,0,0,0,0,13,0,0,0,0,7,9,0,0,0,0,0,0,0,0,0,0,5,0,0,0,7,10,7,12,0,0,0,9,0,
++0,0,14,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,15,6,0,0,23,0,0,7,0,6,0,0,0,7,0,6,
++0,0,0,0,0,0,0,6,0,6,9,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,8,7,9,4,0,0,10,0,0,0,10,
++6,0,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,23,0,0,6,0,0,0,0,0,0,9,4,
++0,0,10,7,0,0,0,0,0,0,0,0,0,0,0,0,9,7,0,0,9,6,0,0,0,0,8,6,0,0,0,0,0,0,0,0,12,0,0,
++0,0,0,8,0,0,6,11,6,0,0,8,7,8,5,0,0,0,0,0,5,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,
++10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,
++7,0,0,0,0,9,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,8,0,0,0,0,6,12,5,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,10,0,10,
++7,0,0,8,0,0,0,0,4,0,0,0,6,0,0,0,6,0,0,0,6,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,5,0,
++0,0,4,0,0,0,0,0,4,0,0,0,0,0,0,0,6,0,6,0,5,0,0,0,0,8,0,0,0,10,7,0,0,0,0,10,0,0,0,
++0,0,13,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,19,7,0,4,12,0,8,0,0,0,0,6,0,0,0,0,
++0,0,0,6,0,0,0,0,0,0,0,0,0,4,0,0,0,0,18,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,
++0,14,0,0,4,0,0,0,6,0,0,0,6,0,0,0,7,0,0,0,0,0,0,10,4,0,0,9,7,0,0,11,0,0,0,0,0,0,
++7,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,4,0,0,12,0,0,0,
++0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,22,5,9,7,0,0,0,0,0,0,0,0,0,
++0,0,6,0,0,9,6,0,5,0,0,0,0,0,0,10,5,0,0,8,6,0,6,10,5,0,0,0,6,0,0,0,6,0,0,20,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,6,0,0,0,0,17,4,0,7,0,6,
++0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,
++0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0,
++0,0,7,0,0,8,6,12,0,0,7,18,7,0,0,8,4,0,0,0,0,9,6,0,0,0,0,0,0,0,0,13,0,0,6,0,0,0,
++0,0,0,0,0,0,0,10,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,7,0,0,
++0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,8,5,0,0,0,0,0,0,0,0,12,0,0,0,8,0,0,0,0,0,0,
++4,0,0,10,0,16,0,0,0,0,0,0,0,12,7,10,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,16,6,10,0,0,5,0,0,0,0,0,6,0,0,0,0,
++0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,5,8,7,0,7,0,0,0,0,0,0,0,0,8,0,0,6,0,0,0,6,0,0,0,4,0,0,0,0,
++8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,7,0,0,8,0,0,0,
++9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,7,13,5,0,5,0,0,0,7,8,4,0,0,0,0,0,0,0,
++0,12,0,0,0,0,0,0,0,0,0,0,0,8,6,0,6,0,0,11,0,0,0,0,0,0,0,0,6,0,0,0,0,0,4,0,0,0,0,
++0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,10,7,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,11,6,0,0,10,6,0,0,
++0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,
++0,0,0,6,0,0,0,7,0,0,9,0,8,7,11,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,9,6,10,5,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,10,7,0,0,0,0,0,0,11,0,9,6,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,5,0,6,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,15,5,12,5,
++0,0,0,0,0,0,12,7,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,12,6,0,
++0,0,0,24,4,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0,0,0,0,
++0,0,0,4,10,4,0,0,0,0,10,7,0,0,0,0,0,0,0,0,0,0,0,0,9,0,11,0,0,0,0,0,0,0,0,0,0,6,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,
++0,0,8,0,0,0,0,7,0,0,0,0,0,0,10,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,10,7,0,0,0,0,0,
++0,0,0,0,0,14,7,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,0,0,6,0,0,0,6,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,11,6,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,7,20,7,11,4,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,7,9,6,0,0,12,7,0,0,0,0,0,0,10,0,12,0,
++0,0,0,0,0,4,9,6,13,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,5,0,0,0,0,0,0,8,0,0,0,0,0,0,
++0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,6,0,0,11,0,9,0,0,0,0,4,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,8,5,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,
++0,4,0,5,0,0,0,0,0,0,0,0,0,4,0,0,0,0,9,7,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,
++0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,6,
++0,0,0,0,8,7,0,0,0,0,0,0,12,0,0,6,0,0,0,0,0,0,0,6,8,4,0,0,10,7,0,0,10,0,0,0,0,0,
++0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,7,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,4,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,5,
++0,4,0,0,0,0,0,6,0,0,0,0,0,0,8,0,0,6,0,0,0,6,0,0,0,0,0,7,0,5,8,4,0,0,9,0,0,0,0,4,
++0,0,0,0,0,0,0,0,0,5,0,0,15,6,8,6,0,0,0,6,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,9,6,0,0,0,0,0,0,0,7,0,0,0,4,0,
++6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,9,5,0,6,12,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,6,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,8,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,11,0,12,7,0,0,0,0,
++0,0,0,0,0,5,0,5,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,11,4,0,0,0,0,0,0,0,0,0,0,10,
++7,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,7,8,7,9,6,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,5,12,0,
++10,5,12,6,0,0,0,7,0,0,0,0,0,0,0,5,0,0,0,5,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,
++11,7,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,0,6,0,7,0,0,0,0,8,0,8,5,0,6,0,0,0,6,0,0,0,
++0,0,0,0,6,0,6,0,6,9,0,0,5,17,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,7,0,0,
++0,0,0,7,0,0,0,0,16,5,0,0,0,0,0,0,0,4,0,0,0,5,11,5,0,7,0,0,0,4,8,7,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,7,0,0,0,0,12,0,0,0,
++0,0,12,0,0,0,0,0,0,0,0,4,10,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,6,0,0,0,0,0,0,0,4,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,20,5,0,0,
++10,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,12,0,0,0,0,0,0,6,0,0,0,0,0,0,9,4,10,7,0,4,0,0,
++0,0,0,0,10,6,0,0,0,0,8,4,0,7,8,6,0,6,8,0,10,0,0,0,0,0,13,5,0,6,0,0,0,0,0,0,22,4,
++0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,6,10,
++5,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,10,4,0,0,10,7,0,0,0,0,0,5,0,
++5,8,0,0,0,0,6,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,10,7,0,0,0,4,0,0,0,0,0,6,0,0,
++0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,7,0,0,0,6,0,0,0,0,0,0,0,0,0,
++4,0,0,0,4,10,0,0,6,13,7,8,0,0,0,0,0,0,7,0,0,12,7,0,0,0,0,0,0,10,5,0,0,0,0,0,6,0,
++0,0,0,0,0,0,0,0,0,13,7,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,8,6,0,6,
++0,0,0,0,0,0,0,0,12,0,8,4,0,0,0,0,0,4,0,4,0,0,0,0,0,0,0,5,0,0,0,0,12,5,0,0,0,7,0,
++0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,10,0,0,0,20,0,0,5,0,0,10,
++7,11,7,0,0,0,0,0,0,0,0,0,0,17,0,9,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,10,7,0,4,0,6,0,0,24,0,0,5,0,0,0,0,8,0,0,
++0,0,0,0,0,10,5,0,4,0,6,0,0,8,0,0,0,0,0,0,4,0,6,0,0,0,0,0,0,9,5,0,0,0,0,0,0,0,0,
++0,0,0,6,0,0,0,0,9,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,4,0,7,
++0,0,13,0,0,0,0,0,0,0,11,6,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,
++17,7,0,0,11,6,0,0,0,0,12,6,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,5,0,0,0,6,0,0,0,0,0,0,0,0,0,0,10,0,0,4,8,6,0,0,0,
++0,0,0,9,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,0,0,0,9,5,0,7,18,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,8,0,0,0,
++0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,
++0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,4,0,6,0,0,9,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0,
++0,0,0,8,7,10,0,8,5,0,0,0,0,0,0,0,0,9,0,0,0,10,0,0,0,0,6,0,7,0,4,0,0,0,0,0,0,0,0,
++8,0,0,0,0,0,8,4,0,0,0,0,0,5,0,0,10,0,12,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++4,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,6,11,0,0,
++7,0,0,0,0,0,6,10,5,0,0,0,0,0,0,0,0,0,5,0,0,9,5,12,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
++0,6,0,0,0,0,13,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,
++0,0,0,8,4,0,6,12,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,
++0,0,0,0,11,4,0,0,0,6,14,0,11,0,9,6,0,0,0,0,0,0,22,0,12,0,8,6,0,0,0,0,0,0,0,6,0,
++0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,
++10,7,0,0,0,0,0,0,0,0,9,0,0,0,0,4,0,0,0,0,0,0,0,0,0,5,11,0,0,0,0,0,0,0,8,6,0,0,9,
++7,0,0,12,4,0,0,0,0,0,0,12,6,0,6,0,7,0,0,8,5,0,0,0,0};
+
+ #if defined(__cplusplus) || defined(c_plusplus)
+ } /* extern "C" */
+diff --git a/c/enc/dictionary_hash.h b/c/enc/dictionary_hash.h
+index b3bb9599..e553ea5d 100644
+--- a/c/enc/dictionary_hash.h
++++ b/c/enc/dictionary_hash.h
+@@ -15,7 +15,8 @@
+ extern "C" {
+ #endif
+
+-extern const uint16_t kStaticDictionaryHash[32768];
++extern const uint16_t kStaticDictionaryHashWords[32768];
++extern const uint8_t kStaticDictionaryHashLengths[32768];
+
+ #if defined(__cplusplus) || defined(c_plusplus)
+ } /* extern "C" */
+diff --git a/c/enc/encode.c b/c/enc/encode.c
+index c82f2d3f..3319b394 100644
+--- a/c/enc/encode.c
++++ b/c/enc/encode.c
+@@ -54,12 +54,19 @@ typedef enum BrotliEncoderStreamState {
+ BROTLI_STREAM_METADATA_BODY = 4
+ } BrotliEncoderStreamState;
+
++typedef enum BrotliEncoderFlintState {
++ BROTLI_FLINT_NEEDS_2_BYTES = 2,
++ BROTLI_FLINT_NEEDS_1_BYTE = 1,
++ BROTLI_FLINT_WAITING_FOR_PROCESSING = 0,
++ BROTLI_FLINT_WAITING_FOR_FLUSHING = -1,
++ BROTLI_FLINT_DONE = -2
++} BrotliEncoderFlintState;
++
+ typedef struct BrotliEncoderStateStruct {
+ BrotliEncoderParams params;
+
+ MemoryManager memory_manager_;
+
+- HasherHandle hasher_;
+ uint64_t input_pos_;
+ RingBuffer ringbuffer_;
+ size_t cmd_alloc_size_;
+@@ -73,10 +80,17 @@ typedef struct BrotliEncoderStateStruct {
+ int saved_dist_cache_[4];
+ uint16_t last_bytes_;
+ uint8_t last_bytes_bits_;
++ /* "Flint" is a tiny uncompressed block emitted before the continuation
++ block to unwire literal context from previous data. Despite being int8_t,
++ field is actually BrotliEncoderFlintState enum. */
++ int8_t flint_;
+ uint8_t prev_byte_;
+ uint8_t prev_byte2_;
+ size_t storage_size_;
+ uint8_t* storage_;
++
++ Hasher hasher_;
++
+ /* Hash table for FAST_ONE_PASS_COMPRESSION_QUALITY mode. */
+ int small_table_[1 << 10]; /* 4KiB */
+ int* large_table_; /* Allocated only when needed */
+@@ -172,6 +186,11 @@ BROTLI_BOOL BrotliEncoderSetParameter(
+ state->params.dist.num_direct_distance_codes = value;
+ return BROTLI_TRUE;
+
++ case BROTLI_PARAM_STREAM_OFFSET:
++ if (value > (1u << 30)) return BROTLI_FALSE;
++ state->params.stream_offset = value;
++ return BROTLI_TRUE;
++
+ default: return BROTLI_FALSE;
+ }
+ }
+@@ -615,11 +634,7 @@ static void WriteMetaBlockInternal(MemoryManager* m,
+ /* The number of distance symbols effectively used for distance
+ histograms. It might be less than distance alphabet size
+ for "Large Window Brotli" (32-bit). */
+- uint32_t num_effective_dist_codes = block_params.dist.alphabet_size;
+- if (num_effective_dist_codes > BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS) {
+- num_effective_dist_codes = BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS;
+- }
+- BrotliOptimizeHistograms(num_effective_dist_codes, &mb);
++ BrotliOptimizeHistograms(block_params.dist.alphabet_size_limit, &mb);
+ }
+ BrotliStoreMetaBlock(m, data, wrapped_last_flush_pos, bytes, mask,
+ prev_byte, prev_byte2,
+@@ -676,12 +691,23 @@ static BROTLI_BOOL EnsureInitialized(BrotliEncoderState* s) {
+
+ s->last_bytes_bits_ = 0;
+ s->last_bytes_ = 0;
++ s->flint_ = BROTLI_FLINT_DONE;
+ s->remaining_metadata_bytes_ = BROTLI_UINT32_MAX;
+
+ SanitizeParams(&s->params);
+ s->params.lgblock = ComputeLgBlock(&s->params);
+ ChooseDistanceParams(&s->params);
+
++ if (s->params.stream_offset != 0) {
++ s->flint_ = BROTLI_FLINT_NEEDS_2_BYTES;
++ /* Poison the distance cache. -16 +- 3 is still less than zero (invalid). */
++ s->dist_cache_[0] = -16;
++ s->dist_cache_[1] = -16;
++ s->dist_cache_[2] = -16;
++ s->dist_cache_[3] = -16;
++ memcpy(s->saved_dist_cache_, s->dist_cache_, sizeof(s->saved_dist_cache_));
++ }
++
+ RingBufferSetup(&s->params, &s->ringbuffer_);
+
+ /* Initialize last byte with stream header. */
+@@ -691,8 +717,14 @@ static BROTLI_BOOL EnsureInitialized(BrotliEncoderState* s) {
+ s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY) {
+ lgwin = BROTLI_MAX(int, lgwin, 18);
+ }
+- EncodeWindowBits(lgwin, s->params.large_window,
+- &s->last_bytes_, &s->last_bytes_bits_);
++ if (s->params.stream_offset == 0) {
++ EncodeWindowBits(lgwin, s->params.large_window,
++ &s->last_bytes_, &s->last_bytes_bits_);
++ } else {
++ /* Bigger values have the same effect, but could cause overflows. */
++ s->params.stream_offset = BROTLI_MIN(size_t,
++ s->params.stream_offset, BROTLI_MAX_BACKWARD_LIMIT(lgwin));
++ }
+ }
+
+ if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY) {
+@@ -710,13 +742,15 @@ static void BrotliEncoderInitParams(BrotliEncoderParams* params) {
+ params->quality = BROTLI_DEFAULT_QUALITY;
+ params->lgwin = BROTLI_DEFAULT_WINDOW;
+ params->lgblock = 0;
++ params->stream_offset = 0;
+ params->size_hint = 0;
+ params->disable_literal_context_modeling = BROTLI_FALSE;
+ BrotliInitEncoderDictionary(¶ms->dictionary);
+ params->dist.distance_postfix_bits = 0;
+ params->dist.num_direct_distance_codes = 0;
+- params->dist.alphabet_size =
++ params->dist.alphabet_size_max =
+ BROTLI_DISTANCE_ALPHABET_SIZE(0, 0, BROTLI_MAX_DISTANCE_BITS);
++ params->dist.alphabet_size_limit = params->dist.alphabet_size_max;
+ params->dist.max_distance = BROTLI_MAX_DISTANCE;
+ }
+
+@@ -732,7 +766,7 @@ static void BrotliEncoderInitState(BrotliEncoderState* s) {
+ s->prev_byte2_ = 0;
+ s->storage_size_ = 0;
+ s->storage_ = 0;
+- s->hasher_ = NULL;
++ HasherInit(&s->hasher_);
+ s->large_table_ = NULL;
+ s->large_table_size_ = 0;
+ s->cmd_code_numbits_ = 0;
+@@ -900,6 +934,7 @@ static void ExtendLastCommand(BrotliEncoderState* s, uint32_t* bytes,
+ (*bytes)--;
+ (*wrapped_last_processed_pos)++;
+ }
++ } else {
+ }
+ /* The copy length is at most the metablock size, and thus expressible. */
+ GetLengthCode(last_command->insert_len_,
+@@ -932,6 +967,7 @@ static BROTLI_BOOL EncodeData(
+ uint32_t mask;
+ MemoryManager* m = &s->memory_manager_;
+ ContextType literal_context_mode;
++ ContextLut literal_context_lut;
+
+ data = s->ringbuffer_.buffer_;
+ mask = s->ringbuffer_.mask_;
+@@ -1022,6 +1058,7 @@ static BROTLI_BOOL EncodeData(
+ literal_context_mode = ChooseContextMode(
+ &s->params, data, WrapPosition(s->last_flush_pos_),
+ mask, (size_t)(s->input_pos_ - s->last_flush_pos_));
++ literal_context_lut = BROTLI_CONTEXT_LUT(literal_context_mode);
+
+ if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
+
+@@ -1032,20 +1069,23 @@ static BROTLI_BOOL EncodeData(
+ if (s->params.quality == ZOPFLIFICATION_QUALITY) {
+ BROTLI_DCHECK(s->params.hasher.type == 10);
+ BrotliCreateZopfliBackwardReferences(m, bytes, wrapped_last_processed_pos,
+- data, mask, &s->params, s->hasher_, s->dist_cache_,
++ data, mask, literal_context_lut, &s->params,
++ &s->hasher_, s->dist_cache_,
+ &s->last_insert_len_, &s->commands_[s->num_commands_],
+ &s->num_commands_, &s->num_literals_);
+ if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
+ } else if (s->params.quality == HQ_ZOPFLIFICATION_QUALITY) {
+ BROTLI_DCHECK(s->params.hasher.type == 10);
+ BrotliCreateHqZopfliBackwardReferences(m, bytes, wrapped_last_processed_pos,
+- data, mask, &s->params, s->hasher_, s->dist_cache_,
++ data, mask, literal_context_lut, &s->params,
++ &s->hasher_, s->dist_cache_,
+ &s->last_insert_len_, &s->commands_[s->num_commands_],
+ &s->num_commands_, &s->num_literals_);
+ if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
+ } else {
+ BrotliCreateBackwardReferences(bytes, wrapped_last_processed_pos,
+- data, mask, &s->params, s->hasher_, s->dist_cache_,
++ data, mask, literal_context_lut, &s->params,
++ &s->hasher_, s->dist_cache_,
+ &s->last_insert_len_, &s->commands_[s->num_commands_],
+ &s->num_commands_, &s->num_literals_);
+ }
+@@ -1070,7 +1110,7 @@ static BROTLI_BOOL EncodeData(
+ s->num_commands_ < max_commands) {
+ /* Merge with next input block. Everything will happen later. */
+ if (UpdateLastProcessedPos(s)) {
+- HasherReset(s->hasher_);
++ HasherReset(&s->hasher_);
+ }
+ *out_size = 0;
+ return BROTLI_TRUE;
+@@ -1111,7 +1151,7 @@ static BROTLI_BOOL EncodeData(
+ s->last_bytes_bits_ = storage_ix & 7u;
+ s->last_flush_pos_ = s->input_pos_;
+ if (UpdateLastProcessedPos(s)) {
+- HasherReset(s->hasher_);
++ HasherReset(&s->hasher_);
+ }
+ if (s->last_flush_pos_ > 0) {
+ s->prev_byte_ = data[((uint32_t)s->last_flush_pos_ - 1) & mask];
+@@ -1172,7 +1212,6 @@ static BROTLI_BOOL BrotliCompressBufferQuality10(
+ size_t total_out_size = 0;
+ uint16_t last_bytes;
+ uint8_t last_bytes_bits;
+- HasherHandle hasher = NULL;
+
+ const size_t hasher_eff_size = BROTLI_MIN(size_t,
+ input_size, BROTLI_MAX_BACKWARD_LIMIT(lgwin) + BROTLI_WINDOW_GAP);
+@@ -1188,6 +1227,9 @@ static BROTLI_BOOL BrotliCompressBufferQuality10(
+ uint8_t prev_byte = 0;
+ uint8_t prev_byte2 = 0;
+
++ Hasher hasher;
++ HasherInit(&hasher);
++
+ BrotliEncoderInitParams(¶ms);
+ params.quality = 10;
+ params.lgwin = lgwin;
+@@ -1224,6 +1266,7 @@ static BROTLI_BOOL BrotliCompressBufferQuality10(
+
+ ContextType literal_context_mode = ChooseContextMode(¶ms,
+ input_buffer, metablock_start, mask, metablock_end - metablock_start);
++ ContextLut literal_context_lut = BROTLI_CONTEXT_LUT(literal_context_mode);
+
+ size_t block_start;
+ for (block_start = metablock_start; block_start < metablock_end; ) {
+@@ -1234,10 +1277,10 @@ static BROTLI_BOOL BrotliCompressBufferQuality10(
+ size_t new_cmd_alloc_size;
+ if (BROTLI_IS_OOM(m)) goto oom;
+ BrotliInitZopfliNodes(nodes, block_size + 1);
+- StitchToPreviousBlockH10(hasher, block_size, block_start,
++ StitchToPreviousBlockH10(&hasher.privat._H10, block_size, block_start,
+ input_buffer, mask);
+ path_size = BrotliZopfliComputeShortestPath(m, block_size, block_start,
+- input_buffer, mask, ¶ms, dist_cache, hasher,
++ input_buffer, mask, literal_context_lut, ¶ms, dist_cache, &hasher,
+ nodes);
+ if (BROTLI_IS_OOM(m)) goto oom;
+ /* We allocate a command buffer in the first iteration of this loop that
+@@ -1316,11 +1359,7 @@ static BROTLI_BOOL BrotliCompressBufferQuality10(
+ /* The number of distance symbols effectively used for distance
+ histograms. It might be less than distance alphabet size
+ for "Large Window Brotli" (32-bit). */
+- uint32_t num_effective_dist_codes = block_params.dist.alphabet_size;
+- if (num_effective_dist_codes > BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS) {
+- num_effective_dist_codes = BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS;
+- }
+- BrotliOptimizeHistograms(num_effective_dist_codes, &mb);
++ BrotliOptimizeHistograms(block_params.dist.alphabet_size_limit, &mb);
+ }
+ storage = BROTLI_ALLOC(m, uint8_t, 2 * metablock_size + 503);
+ if (BROTLI_IS_OOM(m)) goto oom;
+@@ -1784,6 +1823,10 @@ BROTLI_BOOL BrotliEncoderCompressStream(
+ }
+ while (BROTLI_TRUE) {
+ size_t remaining_block_size = RemainingInputBlockSize(s);
++ /* Shorten input to flint size. */
++ if (s->flint_ >= 0 && remaining_block_size > (size_t)s->flint_) {
++ remaining_block_size = (size_t)s->flint_;
++ }
+
+ if (remaining_block_size != 0 && *available_in != 0) {
+ size_t copy_input_size =
+@@ -1791,10 +1834,18 @@ BROTLI_BOOL BrotliEncoderCompressStream(
+ CopyInputToRingBuffer(s, copy_input_size, *next_in);
+ *next_in += copy_input_size;
+ *available_in -= copy_input_size;
++ if (s->flint_ > 0) s->flint_ = (int8_t)(s->flint_ - (int)copy_input_size);
+ continue;
+ }
+
+ if (InjectFlushOrPushOutput(s, available_out, next_out, total_out)) {
++ /* Exit the "emit flint" workflow. */
++ if (s->flint_ == BROTLI_FLINT_WAITING_FOR_FLUSHING) {
++ CheckFlushComplete(s);
++ if (s->stream_state_ == BROTLI_STREAM_PROCESSING) {
++ s->flint_ = BROTLI_FLINT_DONE;
++ }
++ }
+ continue;
+ }
+
+@@ -1808,6 +1859,11 @@ BROTLI_BOOL BrotliEncoderCompressStream(
+ BROTLI_BOOL force_flush = TO_BROTLI_BOOL(
+ (*available_in == 0) && op == BROTLI_OPERATION_FLUSH);
+ BROTLI_BOOL result;
++ /* Force emitting (uncompressed) piece containing flint. */
++ if (!is_last && s->flint_ == 0) {
++ s->flint_ = BROTLI_FLINT_WAITING_FOR_FLUSHING;
++ force_flush = BROTLI_TRUE;
++ }
+ UpdateSizeHint(s, *available_in);
+ result = EncodeData(s, is_last, force_flush,
+ &s->available_out_, &s->next_out_);
+diff --git a/c/enc/encoder_dict.c b/c/enc/encoder_dict.c
+index e58ca670..c9e963b8 100755
+--- a/c/enc/encoder_dict.c
++++ b/c/enc/encoder_dict.c
+@@ -17,8 +17,10 @@ extern "C" {
+
+ void BrotliInitEncoderDictionary(BrotliEncoderDictionary* dict) {
+ dict->words = BrotliGetDictionary();
++ dict->num_transforms = (uint32_t)BrotliGetTransforms()->num_transforms;
+
+- dict->hash_table = kStaticDictionaryHash;
++ dict->hash_table_words = kStaticDictionaryHashWords;
++ dict->hash_table_lengths = kStaticDictionaryHashLengths;
+ dict->buckets = kStaticDictionaryBuckets;
+ dict->dict_words = kStaticDictionaryWords;
+
+diff --git a/c/enc/encoder_dict.h b/c/enc/encoder_dict.h
+index 3cb6b0ac..a1c329fb 100755
+--- a/c/enc/encoder_dict.h
++++ b/c/enc/encoder_dict.h
+@@ -19,13 +19,15 @@ extern "C" {
+ /* Dictionary data (words and transforms) for 1 possible context */
+ typedef struct BrotliEncoderDictionary {
+ const BrotliDictionary* words;
++ uint32_t num_transforms;
+
+ /* cut off for fast encoder */
+ uint32_t cutoffTransformsCount;
+ uint64_t cutoffTransforms;
+
+ /* from dictionary_hash.h, for fast encoder */
+- const uint16_t* hash_table;
++ const uint16_t* hash_table_words;
++ const uint8_t* hash_table_lengths;
+
+ /* from static_dict_lut.h, for slow encoder */
+ const uint16_t* buckets;
+diff --git a/c/enc/hash.h b/c/enc/hash.h
+index 8c5a7bb5..60fb5dfd 100644
+--- a/c/enc/hash.h
++++ b/c/enc/hash.h
+@@ -27,34 +27,19 @@
+ extern "C" {
+ #endif
+
+-/* Pointer to hasher data.
+- *
+- * Excluding initialization and destruction, hasher can be passed as
+- * HasherHandle by value.
+- *
+- * Typically hasher data consists of 3 sections:
+- * * HasherCommon structure
+- * * private structured hasher data, depending on hasher type
+- * * private dynamic hasher data, depending on hasher type and parameters
+- *
+- * Using "define" instead of "typedef", because on MSVC __restrict does not work
+- * on typedef pointer types. */
+-#define HasherHandle uint8_t*
+-
+ typedef struct {
++ /* Dynamically allocated area; first member for quickest access. */
++ void* extra;
++
++ size_t dict_num_lookups;
++ size_t dict_num_matches;
++
+ BrotliHasherParams params;
+
+ /* False if hasher needs to be "prepared" before use. */
+ BROTLI_BOOL is_prepared_;
+-
+- size_t dict_num_lookups;
+- size_t dict_num_matches;
+ } HasherCommon;
+
+-static BROTLI_INLINE HasherCommon* GetHasherCommon(HasherHandle handle) {
+- return (HasherCommon*)handle;
+-}
+-
+ #define score_t size_t
+
+ static const uint32_t kCutoffTransformsCount = 10;
+@@ -149,17 +134,13 @@ static BROTLI_INLINE score_t BackwardReferencePenaltyUsingLastDistance(
+ }
+
+ static BROTLI_INLINE BROTLI_BOOL TestStaticDictionaryItem(
+- const BrotliEncoderDictionary* dictionary, size_t item,
++ const BrotliEncoderDictionary* dictionary, size_t len, size_t word_idx,
+ const uint8_t* data, size_t max_length, size_t max_backward,
+ size_t max_distance, HasherSearchResult* out) {
+- size_t len;
+- size_t word_idx;
+ size_t offset;
+ size_t matchlen;
+ size_t backward;
+ score_t score;
+- len = item & 0x1F;
+- word_idx = item >> 5;
+ offset = dictionary->words->offsets_by_length[len] + len * word_idx;
+ if (len > max_length) {
+ return BROTLI_FALSE;
+@@ -193,25 +174,24 @@ static BROTLI_INLINE BROTLI_BOOL TestStaticDictionaryItem(
+
+ static BROTLI_INLINE void SearchInStaticDictionary(
+ const BrotliEncoderDictionary* dictionary,
+- HasherHandle handle, const uint8_t* data, size_t max_length,
++ HasherCommon* common, const uint8_t* data, size_t max_length,
+ size_t max_backward, size_t max_distance,
+ HasherSearchResult* out, BROTLI_BOOL shallow) {
+ size_t key;
+ size_t i;
+- HasherCommon* self = GetHasherCommon(handle);
+- if (self->dict_num_matches < (self->dict_num_lookups >> 7)) {
++ if (common->dict_num_matches < (common->dict_num_lookups >> 7)) {
+ return;
+ }
+ key = Hash14(data) << 1;
+ for (i = 0; i < (shallow ? 1u : 2u); ++i, ++key) {
+- size_t item = dictionary->hash_table[key];
+- self->dict_num_lookups++;
+- if (item != 0) {
++ common->dict_num_lookups++;
++ if (dictionary->hash_table_lengths[key] != 0) {
+ BROTLI_BOOL item_matches = TestStaticDictionaryItem(
+- dictionary, item, data,
++ dictionary, dictionary->hash_table_lengths[key],
++ dictionary->hash_table_words[key], data,
+ max_length, max_backward, max_distance, out);
+ if (item_matches) {
+- self->dict_num_matches++;
++ common->dict_num_matches++;
+ }
+ }
+ }
+@@ -260,37 +240,37 @@ static BROTLI_INLINE size_t BackwardMatchLengthCode(const BackwardMatch* self) {
+ /* MAX_NUM_MATCHES == 64 + MAX_TREE_SEARCH_DEPTH */
+ #define MAX_NUM_MATCHES_H10 128
+
+-/* For BUCKET_SWEEP == 1, enabling the dictionary lookup makes compression
++/* For BUCKET_SWEEP_BITS == 0, enabling the dictionary lookup makes compression
+ a little faster (0.5% - 1%) and it compresses 0.15% better on small text
+ and HTML inputs. */
+
+ #define HASHER() H2
+ #define BUCKET_BITS 16
+-#define BUCKET_SWEEP 1
++#define BUCKET_SWEEP_BITS 0
+ #define HASH_LEN 5
+ #define USE_DICTIONARY 1
+ #include "./hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */
+-#undef BUCKET_SWEEP
++#undef BUCKET_SWEEP_BITS
+ #undef USE_DICTIONARY
+ #undef HASHER
+
+ #define HASHER() H3
+-#define BUCKET_SWEEP 2
++#define BUCKET_SWEEP_BITS 1
+ #define USE_DICTIONARY 0
+ #include "./hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */
+ #undef USE_DICTIONARY
+-#undef BUCKET_SWEEP
++#undef BUCKET_SWEEP_BITS
+ #undef BUCKET_BITS
+ #undef HASHER
+
+ #define HASHER() H4
+ #define BUCKET_BITS 17
+-#define BUCKET_SWEEP 4
++#define BUCKET_SWEEP_BITS 2
+ #define USE_DICTIONARY 1
+ #include "./hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */
+ #undef USE_DICTIONARY
+ #undef HASH_LEN
+-#undef BUCKET_SWEEP
++#undef BUCKET_SWEEP_BITS
+ #undef BUCKET_BITS
+ #undef HASHER
+
+@@ -334,13 +314,13 @@ static BROTLI_INLINE size_t BackwardMatchLengthCode(const BackwardMatch* self) {
+
+ #define HASHER() H54
+ #define BUCKET_BITS 20
+-#define BUCKET_SWEEP 4
++#define BUCKET_SWEEP_BITS 2
+ #define HASH_LEN 7
+ #define USE_DICTIONARY 0
+ #include "./hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */
+ #undef USE_DICTIONARY
+ #undef HASH_LEN
+-#undef BUCKET_SWEEP
++#undef BUCKET_SWEEP_BITS
+ #undef BUCKET_BITS
+ #undef HASHER
+
+@@ -393,97 +373,107 @@ static BROTLI_INLINE size_t BackwardMatchLengthCode(const BackwardMatch* self) {
+ #undef CAT
+ #undef EXPAND_CAT
+
+-#define FOR_GENERIC_HASHERS(H) H(2) H(3) H(4) H(5) H(6) H(40) H(41) H(42) H(54)\
+- H(35) H(55) H(65)
++#define FOR_SIMPLE_HASHERS(H) H(2) H(3) H(4) H(5) H(6) H(40) H(41) H(42) H(54)
++#define FOR_COMPOSITE_HASHERS(H) H(35) H(55) H(65)
++#define FOR_GENERIC_HASHERS(H) FOR_SIMPLE_HASHERS(H) FOR_COMPOSITE_HASHERS(H)
+ #define FOR_ALL_HASHERS(H) FOR_GENERIC_HASHERS(H) H(10)
+
+-static BROTLI_INLINE void DestroyHasher(
+- MemoryManager* m, HasherHandle* handle) {
+- if (*handle == NULL) return;
+- BROTLI_FREE(m, *handle);
++typedef struct {
++ HasherCommon common;
++
++ union {
++#define MEMBER_(N) \
++ H ## N _H ## N;
++ FOR_ALL_HASHERS(MEMBER_)
++#undef MEMBER_
++ } privat;
++} Hasher;
++
++/* MUST be invoked before any other method. */
++static BROTLI_INLINE void HasherInit(Hasher* hasher) {
++ hasher->common.extra = NULL;
+ }
+
+-static BROTLI_INLINE void HasherReset(HasherHandle handle) {
+- if (handle == NULL) return;
+- GetHasherCommon(handle)->is_prepared_ = BROTLI_FALSE;
++static BROTLI_INLINE void DestroyHasher(MemoryManager* m, Hasher* hasher) {
++ if (hasher->common.extra == NULL) return;
++ BROTLI_FREE(m, hasher->common.extra);
++}
++
++static BROTLI_INLINE void HasherReset(Hasher* hasher) {
++ hasher->common.is_prepared_ = BROTLI_FALSE;
+ }
+
+ static BROTLI_INLINE size_t HasherSize(const BrotliEncoderParams* params,
+ BROTLI_BOOL one_shot, const size_t input_size) {
+- size_t result = sizeof(HasherCommon);
+ switch (params->hasher.type) {
+-#define SIZE_(N) \
+- case N: \
+- result += HashMemAllocInBytesH ## N(params, one_shot, input_size); \
+- break;
++#define SIZE_(N) \
++ case N: \
++ return HashMemAllocInBytesH ## N(params, one_shot, input_size);
+ FOR_ALL_HASHERS(SIZE_)
+ #undef SIZE_
+ default:
+ break;
+ }
+- return result;
++ return 0; /* Default case. */
+ }
+
+-static BROTLI_INLINE void HasherSetup(MemoryManager* m, HasherHandle* handle,
++static BROTLI_INLINE void HasherSetup(MemoryManager* m, Hasher* hasher,
+ BrotliEncoderParams* params, const uint8_t* data, size_t position,
+ size_t input_size, BROTLI_BOOL is_last) {
+- HasherHandle self = NULL;
+- HasherCommon* common = NULL;
+ BROTLI_BOOL one_shot = (position == 0 && is_last);
+- if (*handle == NULL) {
++ if (hasher->common.extra == NULL) {
+ size_t alloc_size;
+ ChooseHasher(params, ¶ms->hasher);
+ alloc_size = HasherSize(params, one_shot, input_size);
+- self = BROTLI_ALLOC(m, uint8_t, alloc_size);
++ hasher->common.extra = BROTLI_ALLOC(m, uint8_t, alloc_size);
+ if (BROTLI_IS_OOM(m)) return;
+- *handle = self;
+- common = GetHasherCommon(self);
+- common->params = params->hasher;
+- switch (common->params.type) {
+-#define INITIALIZE_(N) \
+- case N: \
+- InitializeH ## N(*handle, params); \
++ hasher->common.params = params->hasher;
++ switch (hasher->common.params.type) {
++#define INITIALIZE_(N) \
++ case N: \
++ InitializeH ## N(&hasher->common, \
++ &hasher->privat._H ## N, params); \
+ break;
+ FOR_ALL_HASHERS(INITIALIZE_);
+ #undef INITIALIZE_
+ default:
+ break;
+ }
+- HasherReset(*handle);
++ HasherReset(hasher);
+ }
+
+- self = *handle;
+- common = GetHasherCommon(self);
+- if (!common->is_prepared_) {
+- switch (common->params.type) {
+-#define PREPARE_(N) \
+- case N: \
+- PrepareH ## N(self, one_shot, input_size, data); \
++ if (!hasher->common.is_prepared_) {
++ switch (hasher->common.params.type) {
++#define PREPARE_(N) \
++ case N: \
++ PrepareH ## N( \
++ &hasher->privat._H ## N, \
++ one_shot, input_size, data); \
+ break;
+ FOR_ALL_HASHERS(PREPARE_)
+ #undef PREPARE_
+ default: break;
+ }
+ if (position == 0) {
+- common->dict_num_lookups = 0;
+- common->dict_num_matches = 0;
++ hasher->common.dict_num_lookups = 0;
++ hasher->common.dict_num_matches = 0;
+ }
+- common->is_prepared_ = BROTLI_TRUE;
++ hasher->common.is_prepared_ = BROTLI_TRUE;
+ }
+ }
+
+ static BROTLI_INLINE void InitOrStitchToPreviousBlock(
+- MemoryManager* m, HasherHandle* handle, const uint8_t* data, size_t mask,
++ MemoryManager* m, Hasher* hasher, const uint8_t* data, size_t mask,
+ BrotliEncoderParams* params, size_t position, size_t input_size,
+ BROTLI_BOOL is_last) {
+- HasherHandle self;
+- HasherSetup(m, handle, params, data, position, input_size, is_last);
++ HasherSetup(m, hasher, params, data, position, input_size, is_last);
+ if (BROTLI_IS_OOM(m)) return;
+- self = *handle;
+- switch (GetHasherCommon(self)->params.type) {
+-#define INIT_(N) \
+- case N: \
+- StitchToPreviousBlockH ## N(self, input_size, position, data, mask); \
++ switch (hasher->common.params.type) {
++#define INIT_(N) \
++ case N: \
++ StitchToPreviousBlockH ## N( \
++ &hasher->privat._H ## N, \
++ input_size, position, data, mask); \
+ break;
+ FOR_ALL_HASHERS(INIT_)
+ #undef INIT_
+diff --git a/c/enc/hash_composite_inc.h b/c/enc/hash_composite_inc.h
+index b266aa2f..cba156c0 100755
+--- a/c/enc/hash_composite_inc.h
++++ b/c/enc/hash_composite_inc.h
+@@ -28,20 +28,25 @@ static BROTLI_INLINE size_t FN(StoreLookahead)(void) {
+ }
+
+ typedef struct HashComposite {
+- HasherHandle ha;
+- HasherHandle hb;
++ HASHER_A ha;
++ HASHER_B hb;
++ HasherCommon hb_common;
++
++ /* Shortcuts. */
++ void* extra;
++ HasherCommon* common;
++
++ BROTLI_BOOL fresh;
+ const BrotliEncoderParams* params;
+ } HashComposite;
+
+-static BROTLI_INLINE HashComposite* FN(Self)(HasherHandle handle) {
+- return (HashComposite*)&(GetHasherCommon(handle)[1]);
+-}
++static void FN(Initialize)(HasherCommon* common,
++ HashComposite* BROTLI_RESTRICT self, const BrotliEncoderParams* params) {
++ self->common = common;
++ self->extra = common->extra;
+
+-static void FN(Initialize)(
+- HasherHandle handle, const BrotliEncoderParams* params) {
+- HashComposite* self = FN(Self)(handle);
+- self->ha = 0;
+- self->hb = 0;
++ self->hb_common = *self->common;
++ self->fresh = BROTLI_TRUE;
+ self->params = params;
+ /* TODO: Initialize of the hashers is defered to Prepare (and params
+ remembered here) because we don't get the one_shot and input_size params
+@@ -49,87 +54,71 @@ static void FN(Initialize)(
+ those params to all hashers FN(Initialize) */
+ }
+
+-static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot,
+- size_t input_size, const uint8_t* data) {
+- HashComposite* self = FN(Self)(handle);
+- if (!self->ha) {
+- HasherCommon* common_a;
+- HasherCommon* common_b;
+-
+- self->ha = handle + sizeof(HasherCommon) + sizeof(HashComposite);
+- common_a = (HasherCommon*)self->ha;
+- common_a->params = self->params->hasher;
+- common_a->is_prepared_ = BROTLI_FALSE;
+- common_a->dict_num_lookups = 0;
+- common_a->dict_num_matches = 0;
+- FN_A(Initialize)(self->ha, self->params);
+-
+- self->hb = self->ha + sizeof(HasherCommon) + FN_A(HashMemAllocInBytes)(
+- self->params, one_shot, input_size);
+- common_b = (HasherCommon*)self->hb;
+- common_b->params = self->params->hasher;
+- common_b->is_prepared_ = BROTLI_FALSE;
+- common_b->dict_num_lookups = 0;
+- common_b->dict_num_matches = 0;
+- FN_B(Initialize)(self->hb, self->params);
++static void FN(Prepare)(
++ HashComposite* BROTLI_RESTRICT self, BROTLI_BOOL one_shot,
++ size_t input_size, const uint8_t* BROTLI_RESTRICT data) {
++ if (self->fresh) {
++ self->fresh = BROTLI_FALSE;
++ self->hb_common.extra = (uint8_t*)self->extra +
++ FN_A(HashMemAllocInBytes)(self->params, one_shot, input_size);
++
++ FN_A(Initialize)(self->common, &self->ha, self->params);
++ FN_B(Initialize)(&self->hb_common, &self->hb, self->params);
+ }
+- FN_A(Prepare)(self->ha, one_shot, input_size, data);
+- FN_B(Prepare)(self->hb, one_shot, input_size, data);
++ FN_A(Prepare)(&self->ha, one_shot, input_size, data);
++ FN_B(Prepare)(&self->hb, one_shot, input_size, data);
+ }
+
+ static BROTLI_INLINE size_t FN(HashMemAllocInBytes)(
+ const BrotliEncoderParams* params, BROTLI_BOOL one_shot,
+ size_t input_size) {
+- return sizeof(HashComposite) + 2 * sizeof(HasherCommon) +
+- FN_A(HashMemAllocInBytes)(params, one_shot, input_size) +
++ return FN_A(HashMemAllocInBytes)(params, one_shot, input_size) +
+ FN_B(HashMemAllocInBytes)(params, one_shot, input_size);
+ }
+
+-static BROTLI_INLINE void FN(Store)(HasherHandle BROTLI_RESTRICT handle,
++static BROTLI_INLINE void FN(Store)(HashComposite* BROTLI_RESTRICT self,
+ const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) {
+- HashComposite* self = FN(Self)(handle);
+- FN_A(Store)(self->ha, data, mask, ix);
+- FN_B(Store)(self->hb, data, mask, ix);
++ FN_A(Store)(&self->ha, data, mask, ix);
++ FN_B(Store)(&self->hb, data, mask, ix);
+ }
+
+-static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle,
+- const uint8_t* data, const size_t mask, const size_t ix_start,
++static BROTLI_INLINE void FN(StoreRange)(
++ HashComposite* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data,
++ const size_t mask, const size_t ix_start,
+ const size_t ix_end) {
+- HashComposite* self = FN(Self)(handle);
+- FN_A(StoreRange)(self->ha, data, mask, ix_start, ix_end);
+- FN_B(StoreRange)(self->hb, data, mask, ix_start, ix_end);
++ FN_A(StoreRange)(&self->ha, data, mask, ix_start, ix_end);
++ FN_B(StoreRange)(&self->hb, data, mask, ix_start, ix_end);
+ }
+
+-static BROTLI_INLINE void FN(StitchToPreviousBlock)(HasherHandle handle,
++static BROTLI_INLINE void FN(StitchToPreviousBlock)(
++ HashComposite* BROTLI_RESTRICT self,
+ size_t num_bytes, size_t position, const uint8_t* ringbuffer,
+ size_t ring_buffer_mask) {
+- HashComposite* self = FN(Self)(handle);
+- FN_A(StitchToPreviousBlock)(self->ha, num_bytes, position, ringbuffer,
+- ring_buffer_mask);
+- FN_B(StitchToPreviousBlock)(self->hb, num_bytes, position, ringbuffer,
+- ring_buffer_mask);
++ FN_A(StitchToPreviousBlock)(&self->ha, num_bytes, position,
++ ringbuffer, ring_buffer_mask);
++ FN_B(StitchToPreviousBlock)(&self->hb, num_bytes, position,
++ ringbuffer, ring_buffer_mask);
+ }
+
+ static BROTLI_INLINE void FN(PrepareDistanceCache)(
+- HasherHandle handle, int* BROTLI_RESTRICT distance_cache) {
+- HashComposite* self = FN(Self)(handle);
+- FN_A(PrepareDistanceCache)(self->ha, distance_cache);
+- FN_B(PrepareDistanceCache)(self->hb, distance_cache);
++ HashComposite* BROTLI_RESTRICT self, int* BROTLI_RESTRICT distance_cache) {
++ FN_A(PrepareDistanceCache)(&self->ha, distance_cache);
++ FN_B(PrepareDistanceCache)(&self->hb, distance_cache);
+ }
+
+-static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
++static BROTLI_INLINE void FN(FindLongestMatch)(
++ HashComposite* BROTLI_RESTRICT self,
+ const BrotliEncoderDictionary* dictionary,
+ const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask,
+ const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix,
+ const size_t max_length, const size_t max_backward,
+- const size_t gap, const size_t max_distance,
++ const size_t dictionary_distance, const size_t max_distance,
+ HasherSearchResult* BROTLI_RESTRICT out) {
+- HashComposite* self = FN(Self)(handle);
+- FN_A(FindLongestMatch)(self->ha, dictionary, data, ring_buffer_mask,
+- distance_cache, cur_ix, max_length, max_backward, gap,
++ FN_A(FindLongestMatch)(&self->ha, dictionary, data, ring_buffer_mask,
++ distance_cache, cur_ix, max_length, max_backward, dictionary_distance,
+ max_distance, out);
+- FN_B(FindLongestMatch)(self->hb, dictionary, data, ring_buffer_mask,
+- distance_cache, cur_ix, max_length, max_backward, gap,
++ FN_B(FindLongestMatch)(&self->hb, dictionary, data, ring_buffer_mask,
++ distance_cache, cur_ix, max_length, max_backward, dictionary_distance,
+ max_distance, out);
+ }
+
+diff --git a/c/enc/hash_forgetful_chain_inc.h b/c/enc/hash_forgetful_chain_inc.h
+index 41cb3ff0..bfae6ba6 100644
+--- a/c/enc/hash_forgetful_chain_inc.h
++++ b/c/enc/hash_forgetful_chain_inc.h
+@@ -28,7 +28,7 @@ static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; }
+ static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; }
+
+ /* HashBytes is the function that chooses the bucket to place the address in.*/
+-static BROTLI_INLINE size_t FN(HashBytes)(const uint8_t* data) {
++static BROTLI_INLINE size_t FN(HashBytes)(const uint8_t* BROTLI_RESTRICT data) {
+ const uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32;
+ /* The higher bits contain more mixture from the multiplication,
+ so we take our results from there. */
+@@ -45,28 +45,56 @@ typedef struct FN(Bank) {
+ } FN(Bank);
+
+ typedef struct HashForgetfulChain {
+- uint32_t addr[BUCKET_SIZE];
+- uint16_t head[BUCKET_SIZE];
+- /* Truncated hash used for quick rejection of "distance cache" candidates. */
+- uint8_t tiny_hash[65536];
+- FN(Bank) banks[NUM_BANKS];
+- uint16_t free_slot_idx[NUM_BANKS];
++ uint16_t free_slot_idx[NUM_BANKS]; /* Up to 1KiB. Move to dynamic? */
+ size_t max_hops;
++
++ /* Shortcuts. */
++ void* extra;
++ HasherCommon* common;
++
++ /* --- Dynamic size members --- */
++
++ /* uint32_t addr[BUCKET_SIZE]; */
++
++ /* uint16_t head[BUCKET_SIZE]; */
++
++ /* Truncated hash used for quick rejection of "distance cache" candidates. */
++ /* uint8_t tiny_hash[65536];*/
++
++ /* FN(Bank) banks[NUM_BANKS]; */
+ } HashForgetfulChain;
+
+-static BROTLI_INLINE HashForgetfulChain* FN(Self)(HasherHandle handle) {
+- return (HashForgetfulChain*)&(GetHasherCommon(handle)[1]);
++static uint32_t* FN(Addr)(void* extra) {
++ return (uint32_t*)extra;
++}
++
++static uint16_t* FN(Head)(void* extra) {
++ return (uint16_t*)(&FN(Addr)(extra)[BUCKET_SIZE]);
++}
++
++static uint8_t* FN(TinyHash)(void* extra) {
++ return (uint8_t*)(&FN(Head)(extra)[BUCKET_SIZE]);
++}
++
++static FN(Bank)* FN(Banks)(void* extra) {
++ return (FN(Bank)*)(&FN(TinyHash)(extra)[65536]);
+ }
+
+ static void FN(Initialize)(
+- HasherHandle handle, const BrotliEncoderParams* params) {
+- FN(Self)(handle)->max_hops =
+- (params->quality > 6 ? 7u : 8u) << (params->quality - 4);
++ HasherCommon* common, HashForgetfulChain* BROTLI_RESTRICT self,
++ const BrotliEncoderParams* params) {
++ self->common = common;
++ self->extra = common->extra;
++
++ self->max_hops = (params->quality > 6 ? 7u : 8u) << (params->quality - 4);
+ }
+
+-static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot,
+- size_t input_size, const uint8_t* data) {
+- HashForgetfulChain* self = FN(Self)(handle);
++static void FN(Prepare)(
++ HashForgetfulChain* BROTLI_RESTRICT self, BROTLI_BOOL one_shot,
++ size_t input_size, const uint8_t* BROTLI_RESTRICT data) {
++ uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra);
++ uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra);
++ uint8_t* BROTLI_RESTRICT tiny_hash = FN(TinyHash)(self->extra);
+ /* Partial preparation is 100 times slower (per socket). */
+ size_t partial_prepare_threshold = BUCKET_SIZE >> 6;
+ if (one_shot && input_size <= partial_prepare_threshold) {
+@@ -74,17 +102,17 @@ static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot,
+ for (i = 0; i < input_size; ++i) {
+ size_t bucket = FN(HashBytes)(&data[i]);
+ /* See InitEmpty comment. */
+- self->addr[bucket] = 0xCCCCCCCC;
+- self->head[bucket] = 0xCCCC;
++ addr[bucket] = 0xCCCCCCCC;
++ head[bucket] = 0xCCCC;
+ }
+ } else {
+ /* Fill |addr| array with 0xCCCCCCCC value. Because of wrapping, position
+ processed by hasher never reaches 3GB + 64M; this makes all new chains
+ to be terminated after the first node. */
+- memset(self->addr, 0xCC, sizeof(self->addr));
+- memset(self->head, 0, sizeof(self->head));
++ memset(addr, 0xCC, sizeof(uint32_t) * BUCKET_SIZE);
++ memset(head, 0, sizeof(uint16_t) * BUCKET_SIZE);
+ }
+- memset(self->tiny_hash, 0, sizeof(self->tiny_hash));
++ memset(tiny_hash, 0, sizeof(uint8_t) * 65536);
+ memset(self->free_slot_idx, 0, sizeof(self->free_slot_idx));
+ }
+
+@@ -94,51 +122,58 @@ static BROTLI_INLINE size_t FN(HashMemAllocInBytes)(
+ BROTLI_UNUSED(params);
+ BROTLI_UNUSED(one_shot);
+ BROTLI_UNUSED(input_size);
+- return sizeof(HashForgetfulChain);
++ return sizeof(uint32_t) * BUCKET_SIZE + sizeof(uint16_t) * BUCKET_SIZE +
++ sizeof(uint8_t) * 65536 + sizeof(FN(Bank)) * NUM_BANKS;
+ }
+
+ /* Look at 4 bytes at &data[ix & mask]. Compute a hash from these, and prepend
+ node to corresponding chain; also update tiny_hash for current position. */
+-static BROTLI_INLINE void FN(Store)(HasherHandle BROTLI_RESTRICT handle,
++static BROTLI_INLINE void FN(Store)(HashForgetfulChain* BROTLI_RESTRICT self,
+ const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) {
+- HashForgetfulChain* self = FN(Self)(handle);
++ uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra);
++ uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra);
++ uint8_t* BROTLI_RESTRICT tiny_hash = FN(TinyHash)(self->extra);
++ FN(Bank)* BROTLI_RESTRICT banks = FN(Banks)(self->extra);
+ const size_t key = FN(HashBytes)(&data[ix & mask]);
+ const size_t bank = key & (NUM_BANKS - 1);
+ const size_t idx = self->free_slot_idx[bank]++ & (BANK_SIZE - 1);
+- size_t delta = ix - self->addr[key];
+- self->tiny_hash[(uint16_t)ix] = (uint8_t)key;
++ size_t delta = ix - addr[key];
++ tiny_hash[(uint16_t)ix] = (uint8_t)key;
+ if (delta > 0xFFFF) delta = CAPPED_CHAINS ? 0 : 0xFFFF;
+- self->banks[bank].slots[idx].delta = (uint16_t)delta;
+- self->banks[bank].slots[idx].next = self->head[key];
+- self->addr[key] = (uint32_t)ix;
+- self->head[key] = (uint16_t)idx;
++ banks[bank].slots[idx].delta = (uint16_t)delta;
++ banks[bank].slots[idx].next = head[key];
++ addr[key] = (uint32_t)ix;
++ head[key] = (uint16_t)idx;
+ }
+
+-static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle,
+- const uint8_t* data, const size_t mask, const size_t ix_start,
+- const size_t ix_end) {
++static BROTLI_INLINE void FN(StoreRange)(
++ HashForgetfulChain* BROTLI_RESTRICT self,
++ const uint8_t* BROTLI_RESTRICT data, const size_t mask,
++ const size_t ix_start, const size_t ix_end) {
+ size_t i;
+ for (i = ix_start; i < ix_end; ++i) {
+- FN(Store)(handle, data, mask, i);
++ FN(Store)(self, data, mask, i);
+ }
+ }
+
+-static BROTLI_INLINE void FN(StitchToPreviousBlock)(HasherHandle handle,
++static BROTLI_INLINE void FN(StitchToPreviousBlock)(
++ HashForgetfulChain* BROTLI_RESTRICT self,
+ size_t num_bytes, size_t position, const uint8_t* ringbuffer,
+ size_t ring_buffer_mask) {
+ if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) {
+ /* Prepare the hashes for three last bytes of the last write.
+ These could not be calculated before, since they require knowledge
+ of both the previous and the current block. */
+- FN(Store)(handle, ringbuffer, ring_buffer_mask, position - 3);
+- FN(Store)(handle, ringbuffer, ring_buffer_mask, position - 2);
+- FN(Store)(handle, ringbuffer, ring_buffer_mask, position - 1);
++ FN(Store)(self, ringbuffer, ring_buffer_mask, position - 3);
++ FN(Store)(self, ringbuffer, ring_buffer_mask, position - 2);
++ FN(Store)(self, ringbuffer, ring_buffer_mask, position - 1);
+ }
+ }
+
+ static BROTLI_INLINE void FN(PrepareDistanceCache)(
+- HasherHandle handle, int* BROTLI_RESTRICT distance_cache) {
+- BROTLI_UNUSED(handle);
++ HashForgetfulChain* BROTLI_RESTRICT self,
++ int* BROTLI_RESTRICT distance_cache) {
++ BROTLI_UNUSED(self);
+ PrepareDistanceCache(distance_cache, NUM_LAST_DISTANCES_TO_CHECK);
+ }
+
+@@ -153,14 +188,18 @@ static BROTLI_INLINE void FN(PrepareDistanceCache)(
+ Does not look for matches further away than max_backward.
+ Writes the best match into |out|.
+ |out|->score is updated only if a better match is found. */
+-static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
++static BROTLI_INLINE void FN(FindLongestMatch)(
++ HashForgetfulChain* BROTLI_RESTRICT self,
+ const BrotliEncoderDictionary* dictionary,
+ const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask,
+ const int* BROTLI_RESTRICT distance_cache,
+ const size_t cur_ix, const size_t max_length, const size_t max_backward,
+- const size_t gap, const size_t max_distance,
++ const size_t dictionary_distance, const size_t max_distance,
+ HasherSearchResult* BROTLI_RESTRICT out) {
+- HashForgetfulChain* self = FN(Self)(handle);
++ uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra);
++ uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra);
++ uint8_t* BROTLI_RESTRICT tiny_hashes = FN(TinyHash)(self->extra);
++ FN(Bank)* BROTLI_RESTRICT banks = FN(Banks)(self->extra);
+ const size_t cur_ix_masked = cur_ix & ring_buffer_mask;
+ /* Don't accept a short copy from far away. */
+ score_t min_score = out->score;
+@@ -176,7 +215,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
+ const size_t backward = (size_t)distance_cache[i];
+ size_t prev_ix = (cur_ix - backward);
+ /* For distance code 0 we want to consider 2-byte matches. */
+- if (i > 0 && self->tiny_hash[(uint16_t)prev_ix] != tiny_hash) continue;
++ if (i > 0 && tiny_hashes[(uint16_t)prev_ix] != tiny_hash) continue;
+ if (prev_ix >= cur_ix || backward > max_backward) {
+ continue;
+ }
+@@ -204,16 +243,16 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
+ const size_t bank = key & (NUM_BANKS - 1);
+ size_t backward = 0;
+ size_t hops = self->max_hops;
+- size_t delta = cur_ix - self->addr[key];
+- size_t slot = self->head[key];
++ size_t delta = cur_ix - addr[key];
++ size_t slot = head[key];
+ while (hops--) {
+ size_t prev_ix;
+ size_t last = slot;
+ backward += delta;
+ if (backward > max_backward || (CAPPED_CHAINS && !delta)) break;
+ prev_ix = (cur_ix - backward) & ring_buffer_mask;
+- slot = self->banks[bank].slots[last].next;
+- delta = self->banks[bank].slots[last].delta;
++ slot = banks[bank].slots[last].next;
++ delta = banks[bank].slots[last].delta;
+ if (cur_ix_masked + best_len > ring_buffer_mask ||
+ prev_ix + best_len > ring_buffer_mask ||
+ data[cur_ix_masked + best_len] != data[prev_ix + best_len]) {
+@@ -238,11 +277,11 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
+ }
+ }
+ }
+- FN(Store)(handle, data, ring_buffer_mask, cur_ix);
++ FN(Store)(self, data, ring_buffer_mask, cur_ix);
+ }
+ if (out->score == min_score) {
+ SearchInStaticDictionary(dictionary,
+- handle, &data[cur_ix_masked], max_length, max_backward + gap,
++ self->common, &data[cur_ix_masked], max_length, dictionary_distance,
+ max_distance, out, BROTLI_FALSE);
+ }
+ }
+diff --git a/c/enc/hash_longest_match64_inc.h b/c/enc/hash_longest_match64_inc.h
+index cb953a64..bdee7e41 100644
+--- a/c/enc/hash_longest_match64_inc.h
++++ b/c/enc/hash_longest_match64_inc.h
+@@ -20,7 +20,7 @@ static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 8; }
+ static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 8; }
+
+ /* HashBytes is the function that chooses the bucket to place the address in. */
+-static BROTLI_INLINE uint32_t FN(HashBytes)(const uint8_t* data,
++static BROTLI_INLINE uint32_t FN(HashBytes)(const uint8_t* BROTLI_RESTRICT data,
+ const uint64_t mask,
+ const int shift) {
+ const uint64_t h = (BROTLI_UNALIGNED_LOAD64LE(data) & mask) * kHashMul64Long;
+@@ -42,43 +42,43 @@ typedef struct HashLongestMatch {
+ /* Mask for accessing entries in a block (in a ring-buffer manner). */
+ uint32_t block_mask_;
+
++ int block_bits_;
++ int num_last_distances_to_check_;
++
++ /* Shortcuts. */
++ HasherCommon* common_;
++
+ /* --- Dynamic size members --- */
+
+ /* Number of entries in a particular bucket. */
+- /* uint16_t num[bucket_size]; */
++ uint16_t* num_; /* uint16_t[bucket_size]; */
+
+ /* Buckets containing block_size_ of backward references. */
+- /* uint32_t* buckets[bucket_size * block_size]; */
++ uint32_t* buckets_; /* uint32_t[bucket_size * block_size]; */
+ } HashLongestMatch;
+
+-static BROTLI_INLINE HashLongestMatch* FN(Self)(HasherHandle handle) {
+- return (HashLongestMatch*)&(GetHasherCommon(handle)[1]);
+-}
+-
+-static BROTLI_INLINE uint16_t* FN(Num)(HashLongestMatch* self) {
+- return (uint16_t*)(&self[1]);
+-}
+-
+-static BROTLI_INLINE uint32_t* FN(Buckets)(HashLongestMatch* self) {
+- return (uint32_t*)(&FN(Num)(self)[self->bucket_size_]);
+-}
+-
+ static void FN(Initialize)(
+- HasherHandle handle, const BrotliEncoderParams* params) {
+- HasherCommon* common = GetHasherCommon(handle);
+- HashLongestMatch* self = FN(Self)(handle);
++ HasherCommon* common, HashLongestMatch* BROTLI_RESTRICT self,
++ const BrotliEncoderParams* params) {
++ self->common_ = common;
++
+ BROTLI_UNUSED(params);
+ self->hash_shift_ = 64 - common->params.bucket_bits;
+ self->hash_mask_ = (~((uint64_t)0U)) >> (64 - 8 * common->params.hash_len);
+ self->bucket_size_ = (size_t)1 << common->params.bucket_bits;
++ self->block_bits_ = common->params.block_bits;
+ self->block_size_ = (size_t)1 << common->params.block_bits;
+ self->block_mask_ = (uint32_t)(self->block_size_ - 1);
++ self->num_last_distances_to_check_ =
++ common->params.num_last_distances_to_check;
++ self->num_ = (uint16_t*)common->extra;
++ self->buckets_ = (uint32_t*)&self->num_[self->bucket_size_];
+ }
+
+-static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot,
+- size_t input_size, const uint8_t* data) {
+- HashLongestMatch* self = FN(Self)(handle);
+- uint16_t* num = FN(Num)(self);
++static void FN(Prepare)(
++ HashLongestMatch* BROTLI_RESTRICT self, BROTLI_BOOL one_shot,
++ size_t input_size, const uint8_t* BROTLI_RESTRICT data) {
++ uint16_t* BROTLI_RESTRICT num = self->num_;
+ /* Partial preparation is 100 times slower (per socket). */
+ size_t partial_prepare_threshold = self->bucket_size_ >> 6;
+ if (one_shot && input_size <= partial_prepare_threshold) {
+@@ -100,50 +100,52 @@ static BROTLI_INLINE size_t FN(HashMemAllocInBytes)(
+ size_t block_size = (size_t)1 << params->hasher.block_bits;
+ BROTLI_UNUSED(one_shot);
+ BROTLI_UNUSED(input_size);
+- return sizeof(HashLongestMatch) + bucket_size * (2 + 4 * block_size);
++ return sizeof(uint16_t) * bucket_size +
++ sizeof(uint32_t) * bucket_size * block_size;
+ }
+
+ /* Look at 4 bytes at &data[ix & mask].
+ Compute a hash from these, and store the value of ix at that position. */
+-static BROTLI_INLINE void FN(Store)(HasherHandle handle, const uint8_t* data,
++static BROTLI_INLINE void FN(Store)(
++ HashLongestMatch* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data,
+ const size_t mask, const size_t ix) {
+- HashLongestMatch* self = FN(Self)(handle);
+- uint16_t* num = FN(Num)(self);
++ uint16_t* BROTLI_RESTRICT num = self->num_;
++ uint32_t* BROTLI_RESTRICT buckets = self->buckets_;
+ const uint32_t key = FN(HashBytes)(&data[ix & mask], self->hash_mask_,
+ self->hash_shift_);
+ const size_t minor_ix = num[key] & self->block_mask_;
+- const size_t offset =
+- minor_ix + (key << GetHasherCommon(handle)->params.block_bits);
+- FN(Buckets)(self)[offset] = (uint32_t)ix;
++ const size_t offset = minor_ix + (key << self->block_bits_);
++ buckets[offset] = (uint32_t)ix;
+ ++num[key];
+ }
+
+-static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle,
+- const uint8_t* data, const size_t mask, const size_t ix_start,
+- const size_t ix_end) {
++static BROTLI_INLINE void FN(StoreRange)(HashLongestMatch* BROTLI_RESTRICT self,
++ const uint8_t* BROTLI_RESTRICT data, const size_t mask,
++ const size_t ix_start, const size_t ix_end) {
+ size_t i;
+ for (i = ix_start; i < ix_end; ++i) {
+- FN(Store)(handle, data, mask, i);
++ FN(Store)(self, data, mask, i);
+ }
+ }
+
+-static BROTLI_INLINE void FN(StitchToPreviousBlock)(HasherHandle handle,
++static BROTLI_INLINE void FN(StitchToPreviousBlock)(
++ HashLongestMatch* BROTLI_RESTRICT self,
+ size_t num_bytes, size_t position, const uint8_t* ringbuffer,
+ size_t ringbuffer_mask) {
+ if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) {
+ /* Prepare the hashes for three last bytes of the last write.
+ These could not be calculated before, since they require knowledge
+ of both the previous and the current block. */
+- FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 3);
+- FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 2);
+- FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 1);
++ FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3);
++ FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2);
++ FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1);
+ }
+ }
+
+ static BROTLI_INLINE void FN(PrepareDistanceCache)(
+- HasherHandle handle, int* BROTLI_RESTRICT distance_cache) {
+- PrepareDistanceCache(distance_cache,
+- GetHasherCommon(handle)->params.num_last_distances_to_check);
++ HashLongestMatch* BROTLI_RESTRICT self,
++ int* BROTLI_RESTRICT distance_cache) {
++ PrepareDistanceCache(distance_cache, self->num_last_distances_to_check_);
+ }
+
+ /* Find a longest backward match of &data[cur_ix] up to the length of
+@@ -157,17 +159,16 @@ static BROTLI_INLINE void FN(PrepareDistanceCache)(
+ Does not look for matches further away than max_backward.
+ Writes the best match into |out|.
+ |out|->score is updated only if a better match is found. */
+-static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
++static BROTLI_INLINE void FN(FindLongestMatch)(
++ HashLongestMatch* BROTLI_RESTRICT self,
+ const BrotliEncoderDictionary* dictionary,
+ const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask,
+ const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix,
+ const size_t max_length, const size_t max_backward,
+- const size_t gap, const size_t max_distance,
++ const size_t dictionary_distance, const size_t max_distance,
+ HasherSearchResult* BROTLI_RESTRICT out) {
+- HasherCommon* common = GetHasherCommon(handle);
+- HashLongestMatch* self = FN(Self)(handle);
+- uint16_t* num = FN(Num)(self);
+- uint32_t* buckets = FN(Buckets)(self);
++ uint16_t* BROTLI_RESTRICT num = self->num_;
++ uint32_t* BROTLI_RESTRICT buckets = self->buckets_;
+ const size_t cur_ix_masked = cur_ix & ring_buffer_mask;
+ /* Don't accept a short copy from far away. */
+ score_t min_score = out->score;
+@@ -177,7 +178,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
+ out->len = 0;
+ out->len_code_delta = 0;
+ /* Try last distance first. */
+- for (i = 0; i < (size_t)common->params.num_last_distances_to_check; ++i) {
++ for (i = 0; i < (size_t)self->num_last_distances_to_check_; ++i) {
+ const size_t backward = (size_t)distance_cache[i];
+ size_t prev_ix = (size_t)(cur_ix - backward);
+ if (prev_ix >= cur_ix) {
+@@ -218,8 +219,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
+ {
+ const uint32_t key = FN(HashBytes)(
+ &data[cur_ix_masked], self->hash_mask_, self->hash_shift_);
+- uint32_t* BROTLI_RESTRICT bucket =
+- &buckets[key << common->params.block_bits];
++ uint32_t* BROTLI_RESTRICT bucket = &buckets[key << self->block_bits_];
+ const size_t down =
+ (num[key] > self->block_size_) ?
+ (num[key] - self->block_size_) : 0u;
+@@ -259,7 +259,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
+ }
+ if (min_score == out->score) {
+ SearchInStaticDictionary(dictionary,
+- handle, &data[cur_ix_masked], max_length, max_backward + gap,
++ self->common_, &data[cur_ix_masked], max_length, dictionary_distance,
+ max_distance, out, BROTLI_FALSE);
+ }
+ }
+diff --git a/c/enc/hash_longest_match_inc.h b/c/enc/hash_longest_match_inc.h
+index 457f5a9e..27f4463d 100644
+--- a/c/enc/hash_longest_match_inc.h
++++ b/c/enc/hash_longest_match_inc.h
+@@ -20,7 +20,8 @@ static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; }
+ static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; }
+
+ /* HashBytes is the function that chooses the bucket to place the address in. */
+-static uint32_t FN(HashBytes)(const uint8_t* data, const int shift) {
++static uint32_t FN(HashBytes)(
++ const uint8_t* BROTLI_RESTRICT data, const int shift) {
+ uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32;
+ /* The higher bits contain more mixture from the multiplication,
+ so we take our results from there. */
+@@ -38,42 +39,46 @@ typedef struct HashLongestMatch {
+ /* Mask for accessing entries in a block (in a ring-buffer manner). */
+ uint32_t block_mask_;
+
++ int block_bits_;
++ int num_last_distances_to_check_;
++
++ /* Shortcuts. */
++ HasherCommon* common_;
++
+ /* --- Dynamic size members --- */
+
+ /* Number of entries in a particular bucket. */
+- /* uint16_t num[bucket_size]; */
++ uint16_t* num_; /* uint16_t[bucket_size]; */
+
+ /* Buckets containing block_size_ of backward references. */
+- /* uint32_t* buckets[bucket_size * block_size]; */
++ uint32_t* buckets_; /* uint32_t[bucket_size * block_size]; */
+ } HashLongestMatch;
+
+-static BROTLI_INLINE HashLongestMatch* FN(Self)(HasherHandle handle) {
+- return (HashLongestMatch*)&(GetHasherCommon(handle)[1]);
+-}
+-
+-static BROTLI_INLINE uint16_t* FN(Num)(HashLongestMatch* self) {
+- return (uint16_t*)(&self[1]);
+-}
+-
+-static BROTLI_INLINE uint32_t* FN(Buckets)(HashLongestMatch* self) {
+- return (uint32_t*)(&FN(Num)(self)[self->bucket_size_]);
++static BROTLI_INLINE uint16_t* FN(Num)(void* extra) {
++ return (uint16_t*)extra;
+ }
+
+ static void FN(Initialize)(
+- HasherHandle handle, const BrotliEncoderParams* params) {
+- HasherCommon* common = GetHasherCommon(handle);
+- HashLongestMatch* self = FN(Self)(handle);
++ HasherCommon* common, HashLongestMatch* BROTLI_RESTRICT self,
++ const BrotliEncoderParams* params) {
++ self->common_ = common;
++
+ BROTLI_UNUSED(params);
+ self->hash_shift_ = 32 - common->params.bucket_bits;
+ self->bucket_size_ = (size_t)1 << common->params.bucket_bits;
+ self->block_size_ = (size_t)1 << common->params.block_bits;
+ self->block_mask_ = (uint32_t)(self->block_size_ - 1);
++ self->num_ = (uint16_t*)common->extra;
++ self->buckets_ = (uint32_t*)(&self->num_[self->bucket_size_]);
++ self->block_bits_ = common->params.block_bits;
++ self->num_last_distances_to_check_ =
++ common->params.num_last_distances_to_check;
+ }
+
+-static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot,
+- size_t input_size, const uint8_t* data) {
+- HashLongestMatch* self = FN(Self)(handle);
+- uint16_t* num = FN(Num)(self);
++static void FN(Prepare)(
++ HashLongestMatch* BROTLI_RESTRICT self, BROTLI_BOOL one_shot,
++ size_t input_size, const uint8_t* BROTLI_RESTRICT data) {
++ uint16_t* BROTLI_RESTRICT num = self->num_;
+ /* Partial preparation is 100 times slower (per socket). */
+ size_t partial_prepare_threshold = self->bucket_size_ >> 6;
+ if (one_shot && input_size <= partial_prepare_threshold) {
+@@ -94,49 +99,49 @@ static BROTLI_INLINE size_t FN(HashMemAllocInBytes)(
+ size_t block_size = (size_t)1 << params->hasher.block_bits;
+ BROTLI_UNUSED(one_shot);
+ BROTLI_UNUSED(input_size);
+- return sizeof(HashLongestMatch) + bucket_size * (2 + 4 * block_size);
++ return sizeof(uint16_t) * bucket_size +
++ sizeof(uint32_t) * bucket_size * block_size;
+ }
+
+ /* Look at 4 bytes at &data[ix & mask].
+ Compute a hash from these, and store the value of ix at that position. */
+-static BROTLI_INLINE void FN(Store)(HasherHandle handle, const uint8_t* data,
++static BROTLI_INLINE void FN(Store)(
++ HashLongestMatch* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data,
+ const size_t mask, const size_t ix) {
+- HashLongestMatch* self = FN(Self)(handle);
+- uint16_t* num = FN(Num)(self);
+ const uint32_t key = FN(HashBytes)(&data[ix & mask], self->hash_shift_);
+- const size_t minor_ix = num[key] & self->block_mask_;
+- const size_t offset =
+- minor_ix + (key << GetHasherCommon(handle)->params.block_bits);
+- FN(Buckets)(self)[offset] = (uint32_t)ix;
+- ++num[key];
++ const size_t minor_ix = self->num_[key] & self->block_mask_;
++ const size_t offset = minor_ix + (key << self->block_bits_);
++ self->buckets_[offset] = (uint32_t)ix;
++ ++self->num_[key];
+ }
+
+-static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle,
+- const uint8_t* data, const size_t mask, const size_t ix_start,
+- const size_t ix_end) {
++static BROTLI_INLINE void FN(StoreRange)(HashLongestMatch* BROTLI_RESTRICT self,
++ const uint8_t* BROTLI_RESTRICT data, const size_t mask,
++ const size_t ix_start, const size_t ix_end) {
+ size_t i;
+ for (i = ix_start; i < ix_end; ++i) {
+- FN(Store)(handle, data, mask, i);
++ FN(Store)(self, data, mask, i);
+ }
+ }
+
+-static BROTLI_INLINE void FN(StitchToPreviousBlock)(HasherHandle handle,
++static BROTLI_INLINE void FN(StitchToPreviousBlock)(
++ HashLongestMatch* BROTLI_RESTRICT self,
+ size_t num_bytes, size_t position, const uint8_t* ringbuffer,
+ size_t ringbuffer_mask) {
+ if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) {
+ /* Prepare the hashes for three last bytes of the last write.
+ These could not be calculated before, since they require knowledge
+ of both the previous and the current block. */
+- FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 3);
+- FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 2);
+- FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 1);
++ FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3);
++ FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2);
++ FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1);
+ }
+ }
+
+ static BROTLI_INLINE void FN(PrepareDistanceCache)(
+- HasherHandle handle, int* BROTLI_RESTRICT distance_cache) {
+- PrepareDistanceCache(distance_cache,
+- GetHasherCommon(handle)->params.num_last_distances_to_check);
++ HashLongestMatch* BROTLI_RESTRICT self,
++ int* BROTLI_RESTRICT distance_cache) {
++ PrepareDistanceCache(distance_cache, self->num_last_distances_to_check_);
+ }
+
+ /* Find a longest backward match of &data[cur_ix] up to the length of
+@@ -150,17 +155,16 @@ static BROTLI_INLINE void FN(PrepareDistanceCache)(
+ Does not look for matches further away than max_backward.
+ Writes the best match into |out|.
+ |out|->score is updated only if a better match is found. */
+-static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
++static BROTLI_INLINE void FN(FindLongestMatch)(
++ HashLongestMatch* BROTLI_RESTRICT self,
+ const BrotliEncoderDictionary* dictionary,
+ const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask,
+ const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix,
+ const size_t max_length, const size_t max_backward,
+- const size_t gap, const size_t max_distance,
++ const size_t dictionary_distance, const size_t max_distance,
+ HasherSearchResult* BROTLI_RESTRICT out) {
+- HasherCommon* common = GetHasherCommon(handle);
+- HashLongestMatch* self = FN(Self)(handle);
+- uint16_t* num = FN(Num)(self);
+- uint32_t* buckets = FN(Buckets)(self);
++ uint16_t* BROTLI_RESTRICT num = self->num_;
++ uint32_t* BROTLI_RESTRICT buckets = self->buckets_;
+ const size_t cur_ix_masked = cur_ix & ring_buffer_mask;
+ /* Don't accept a short copy from far away. */
+ score_t min_score = out->score;
+@@ -170,7 +174,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
+ out->len = 0;
+ out->len_code_delta = 0;
+ /* Try last distance first. */
+- for (i = 0; i < (size_t)common->params.num_last_distances_to_check; ++i) {
++ for (i = 0; i < (size_t)self->num_last_distances_to_check_; ++i) {
+ const size_t backward = (size_t)distance_cache[i];
+ size_t prev_ix = (size_t)(cur_ix - backward);
+ if (prev_ix >= cur_ix) {
+@@ -211,8 +215,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
+ {
+ const uint32_t key =
+ FN(HashBytes)(&data[cur_ix_masked], self->hash_shift_);
+- uint32_t* BROTLI_RESTRICT bucket =
+- &buckets[key << common->params.block_bits];
++ uint32_t* BROTLI_RESTRICT bucket = &buckets[key << self->block_bits_];
+ const size_t down =
+ (num[key] > self->block_size_) ? (num[key] - self->block_size_) : 0u;
+ for (i = num[key]; i > down;) {
+@@ -251,7 +254,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
+ }
+ if (min_score == out->score) {
+ SearchInStaticDictionary(dictionary,
+- handle, &data[cur_ix_masked], max_length, max_backward + gap,
++ self->common_, &data[cur_ix_masked], max_length, dictionary_distance,
+ max_distance, out, BROTLI_FALSE);
+ }
+ }
+diff --git a/c/enc/hash_longest_match_quickly_inc.h b/c/enc/hash_longest_match_quickly_inc.h
+index a7b9639f..2af13c81 100644
+--- a/c/enc/hash_longest_match_quickly_inc.h
++++ b/c/enc/hash_longest_match_quickly_inc.h
+@@ -5,15 +5,16 @@
+ See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
+ */
+
+-/* template parameters: FN, BUCKET_BITS, BUCKET_SWEEP, HASH_LEN,
++/* template parameters: FN, BUCKET_BITS, BUCKET_SWEEP_BITS, HASH_LEN,
+ USE_DICTIONARY
+ */
+
+ #define HashLongestMatchQuickly HASHER()
+
+ #define BUCKET_SIZE (1 << BUCKET_BITS)
+-
+-#define HASH_MAP_SIZE (4 << BUCKET_BITS)
++#define BUCKET_MASK (BUCKET_SIZE - 1)
++#define BUCKET_SWEEP (1 << BUCKET_SWEEP_BITS)
++#define BUCKET_SWEEP_MASK ((BUCKET_SWEEP - 1) << 3)
+
+ static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 8; }
+ static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 8; }
+@@ -32,39 +33,50 @@ static uint32_t FN(HashBytes)(const uint8_t* data) {
+ /* A (forgetful) hash table to the data seen by the compressor, to
+ help create backward references to previous data.
+
+- This is a hash map of fixed size (BUCKET_SIZE). Starting from the
+- given index, BUCKET_SWEEP buckets are used to store values of a key. */
++ This is a hash map of fixed size (BUCKET_SIZE). */
+ typedef struct HashLongestMatchQuickly {
+- uint32_t buckets_[BUCKET_SIZE + BUCKET_SWEEP];
+-} HashLongestMatchQuickly;
++ /* Shortcuts. */
++ HasherCommon* common;
+
+-static BROTLI_INLINE HashLongestMatchQuickly* FN(Self)(HasherHandle handle) {
+- return (HashLongestMatchQuickly*)&(GetHasherCommon(handle)[1]);
+-}
++ /* --- Dynamic size members --- */
++
++ uint32_t* buckets_; /* uint32_t[BUCKET_SIZE]; */
++} HashLongestMatchQuickly;
+
+ static void FN(Initialize)(
+- HasherHandle handle, const BrotliEncoderParams* params) {
+- BROTLI_UNUSED(handle);
++ HasherCommon* common, HashLongestMatchQuickly* BROTLI_RESTRICT self,
++ const BrotliEncoderParams* params) {
++ self->common = common;
++
+ BROTLI_UNUSED(params);
++ self->buckets_ = (uint32_t*)common->extra;
+ }
+
+-static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot,
+- size_t input_size, const uint8_t* data) {
+- HashLongestMatchQuickly* self = FN(Self)(handle);
++static void FN(Prepare)(
++ HashLongestMatchQuickly* BROTLI_RESTRICT self, BROTLI_BOOL one_shot,
++ size_t input_size, const uint8_t* BROTLI_RESTRICT data) {
++ uint32_t* BROTLI_RESTRICT buckets = self->buckets_;
+ /* Partial preparation is 100 times slower (per socket). */
+- size_t partial_prepare_threshold = HASH_MAP_SIZE >> 7;
++ size_t partial_prepare_threshold = BUCKET_SIZE >> 5;
+ if (one_shot && input_size <= partial_prepare_threshold) {
+ size_t i;
+ for (i = 0; i < input_size; ++i) {
+ const uint32_t key = FN(HashBytes)(&data[i]);
+- memset(&self->buckets_[key], 0, BUCKET_SWEEP * sizeof(self->buckets_[0]));
++ if (BUCKET_SWEEP == 1) {
++ buckets[key] = 0;
++ } else {
++ uint32_t j;
++ for (j = 0; j < BUCKET_SWEEP; ++j) {
++ buckets[(key + (j << 3)) & BUCKET_MASK] = 0;
++ }
++ }
+ }
+ } else {
+ /* It is not strictly necessary to fill this buffer here, but
+ not filling will make the results of the compression stochastic
+ (but correct). This is because random data would cause the
+ system to find accidentally good backward references here and there. */
+- memset(&self->buckets_[0], 0, sizeof(self->buckets_));
++ memset(buckets, 0, sizeof(uint32_t) * BUCKET_SIZE);
+ }
+ }
+
+@@ -74,45 +86,53 @@ static BROTLI_INLINE size_t FN(HashMemAllocInBytes)(
+ BROTLI_UNUSED(params);
+ BROTLI_UNUSED(one_shot);
+ BROTLI_UNUSED(input_size);
+- return sizeof(HashLongestMatchQuickly);
++ return sizeof(uint32_t) * BUCKET_SIZE;
+ }
+
+ /* Look at 5 bytes at &data[ix & mask].
+ Compute a hash from these, and store the value somewhere within
+ [ix .. ix+3]. */
+-static BROTLI_INLINE void FN(Store)(HasherHandle handle,
+- const uint8_t* data, const size_t mask, const size_t ix) {
++static BROTLI_INLINE void FN(Store)(
++ HashLongestMatchQuickly* BROTLI_RESTRICT self,
++ const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) {
+ const uint32_t key = FN(HashBytes)(&data[ix & mask]);
+- /* Wiggle the value with the bucket sweep range. */
+- const uint32_t off = (ix >> 3) % BUCKET_SWEEP;
+- FN(Self)(handle)->buckets_[key + off] = (uint32_t)ix;
++ if (BUCKET_SWEEP == 1) {
++ self->buckets_[key] = (uint32_t)ix;
++ } else {
++ /* Wiggle the value with the bucket sweep range. */
++ const uint32_t off = ix & BUCKET_SWEEP_MASK;
++ self->buckets_[(key + off) & BUCKET_MASK] = (uint32_t)ix;
++ }
+ }
+
+-static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle,
+- const uint8_t* data, const size_t mask, const size_t ix_start,
+- const size_t ix_end) {
++static BROTLI_INLINE void FN(StoreRange)(
++ HashLongestMatchQuickly* BROTLI_RESTRICT self,
++ const uint8_t* BROTLI_RESTRICT data, const size_t mask,
++ const size_t ix_start, const size_t ix_end) {
+ size_t i;
+ for (i = ix_start; i < ix_end; ++i) {
+- FN(Store)(handle, data, mask, i);
++ FN(Store)(self, data, mask, i);
+ }
+ }
+
+ static BROTLI_INLINE void FN(StitchToPreviousBlock)(
+- HasherHandle handle, size_t num_bytes, size_t position,
++ HashLongestMatchQuickly* BROTLI_RESTRICT self,
++ size_t num_bytes, size_t position,
+ const uint8_t* ringbuffer, size_t ringbuffer_mask) {
+ if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) {
+ /* Prepare the hashes for three last bytes of the last write.
+ These could not be calculated before, since they require knowledge
+ of both the previous and the current block. */
+- FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 3);
+- FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 2);
+- FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 1);
++ FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3);
++ FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2);
++ FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1);
+ }
+ }
+
+ static BROTLI_INLINE void FN(PrepareDistanceCache)(
+- HasherHandle handle, int* BROTLI_RESTRICT distance_cache) {
+- BROTLI_UNUSED(handle);
++ HashLongestMatchQuickly* BROTLI_RESTRICT self,
++ int* BROTLI_RESTRICT distance_cache) {
++ BROTLI_UNUSED(self);
+ BROTLI_UNUSED(distance_cache);
+ }
+
+@@ -125,17 +145,19 @@ static BROTLI_INLINE void FN(PrepareDistanceCache)(
+ Writes the best match into |out|.
+ |out|->score is updated only if a better match is found. */
+ static BROTLI_INLINE void FN(FindLongestMatch)(
+- HasherHandle handle, const BrotliEncoderDictionary* dictionary,
++ HashLongestMatchQuickly* BROTLI_RESTRICT self,
++ const BrotliEncoderDictionary* dictionary,
+ const uint8_t* BROTLI_RESTRICT data,
+ const size_t ring_buffer_mask, const int* BROTLI_RESTRICT distance_cache,
+ const size_t cur_ix, const size_t max_length, const size_t max_backward,
+- const size_t gap, const size_t max_distance,
++ const size_t dictionary_distance, const size_t max_distance,
+ HasherSearchResult* BROTLI_RESTRICT out) {
+- HashLongestMatchQuickly* self = FN(Self)(handle);
++ uint32_t* BROTLI_RESTRICT buckets = self->buckets_;
+ const size_t best_len_in = out->len;
+ const size_t cur_ix_masked = cur_ix & ring_buffer_mask;
+- const uint32_t key = FN(HashBytes)(&data[cur_ix_masked]);
+ int compare_char = data[cur_ix_masked + best_len_in];
++ size_t key = FN(HashBytes)(&data[cur_ix_masked]);
++ size_t key_out;
+ score_t min_score = out->score;
+ score_t best_score = out->score;
+ size_t best_len = best_len_in;
+@@ -158,7 +180,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(
+ out->score = best_score;
+ compare_char = data[cur_ix_masked + best_len];
+ if (BUCKET_SWEEP == 1) {
+- self->buckets_[key] = (uint32_t)cur_ix;
++ buckets[key] = (uint32_t)cur_ix;
+ return;
+ }
+ }
+@@ -169,8 +191,8 @@ static BROTLI_INLINE void FN(FindLongestMatch)(
+ size_t backward;
+ size_t len;
+ /* Only one to look for, don't bother to prepare for a loop. */
+- prev_ix = self->buckets_[key];
+- self->buckets_[key] = (uint32_t)cur_ix;
++ prev_ix = buckets[key];
++ buckets[key] = (uint32_t)cur_ix;
+ backward = cur_ix - prev_ix;
+ prev_ix &= (uint32_t)ring_buffer_mask;
+ if (compare_char != data[prev_ix + best_len_in]) {
+@@ -192,12 +214,17 @@ static BROTLI_INLINE void FN(FindLongestMatch)(
+ }
+ }
+ } else {
+- uint32_t* bucket = self->buckets_ + key;
+- int i;
+- prev_ix = *bucket++;
+- for (i = 0; i < BUCKET_SWEEP; ++i, prev_ix = *bucket++) {
+- const size_t backward = cur_ix - prev_ix;
++ size_t keys[BUCKET_SWEEP];
++ size_t i;
++ for (i = 0; i < BUCKET_SWEEP; ++i) {
++ keys[i] = (key + (i << 3)) & BUCKET_MASK;
++ }
++ key_out = keys[(cur_ix & BUCKET_SWEEP_MASK) >> 3];
++ for (i = 0; i < BUCKET_SWEEP; ++i) {
+ size_t len;
++ size_t backward;
++ prev_ix = buckets[keys[i]];
++ backward = cur_ix - prev_ix;
+ prev_ix &= (uint32_t)ring_buffer_mask;
+ if (compare_char != data[prev_ix + best_len]) {
+ continue;
+@@ -211,25 +238,29 @@ static BROTLI_INLINE void FN(FindLongestMatch)(
+ if (len >= 4) {
+ const score_t score = BackwardReferenceScore(len, backward);
+ if (best_score < score) {
+- best_score = score;
+ best_len = len;
+- out->len = best_len;
+- out->distance = backward;
++ out->len = len;
++ compare_char = data[cur_ix_masked + len];
++ best_score = score;
+ out->score = score;
+- compare_char = data[cur_ix_masked + best_len];
++ out->distance = backward;
+ }
+ }
+ }
+ }
+ if (USE_DICTIONARY && min_score == out->score) {
+ SearchInStaticDictionary(dictionary,
+- handle, &data[cur_ix_masked], max_length, max_backward + gap,
++ self->common, &data[cur_ix_masked], max_length, dictionary_distance,
+ max_distance, out, BROTLI_TRUE);
+ }
+- self->buckets_[key + ((cur_ix >> 3) % BUCKET_SWEEP)] = (uint32_t)cur_ix;
++ if (BUCKET_SWEEP != 1) {
++ buckets[key_out] = (uint32_t)cur_ix;
++ }
+ }
+
+-#undef HASH_MAP_SIZE
++#undef BUCKET_SWEEP_MASK
++#undef BUCKET_SWEEP
++#undef BUCKET_MASK
+ #undef BUCKET_SIZE
+
+ #undef HashLongestMatchQuickly
+diff --git a/c/enc/hash_rolling_inc.h b/c/enc/hash_rolling_inc.h
+index 17f8a408..bca41cc2 100755
+--- a/c/enc/hash_rolling_inc.h
++++ b/c/enc/hash_rolling_inc.h
+@@ -51,13 +51,9 @@ typedef struct HashRolling {
+ uint32_t factor_remove;
+ } HashRolling;
+
+-static BROTLI_INLINE HashRolling* FN(Self)(HasherHandle handle) {
+- return (HashRolling*)&(GetHasherCommon(handle)[1]);
+-}
+-
+ static void FN(Initialize)(
+- HasherHandle handle, const BrotliEncoderParams* params) {
+- HashRolling* self = FN(Self)(handle);
++ HasherCommon* common, HashRolling* BROTLI_RESTRICT self,
++ const BrotliEncoderParams* params) {
+ size_t i;
+ self->state = 0;
+ self->next_ix = 0;
+@@ -71,7 +67,7 @@ static void FN(Initialize)(
+ self->factor_remove *= self->factor;
+ }
+
+- self->table = (uint32_t*)((HasherHandle)self + sizeof(HashRolling));
++ self->table = (uint32_t*)common->extra;
+ for (i = 0; i < NUMBUCKETS; i++) {
+ self->table[i] = FN(kInvalidPos);
+ }
+@@ -79,9 +75,8 @@ static void FN(Initialize)(
+ BROTLI_UNUSED(params);
+ }
+
+-static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot,
+- size_t input_size, const uint8_t* data) {
+- HashRolling* self = FN(Self)(handle);
++static void FN(Prepare)(HashRolling* BROTLI_RESTRICT self, BROTLI_BOOL one_shot,
++ size_t input_size, const uint8_t* BROTLI_RESTRICT data) {
+ size_t i;
+ /* Too small size, cannot use this hasher. */
+ if (input_size < CHUNKLEN) return;
+@@ -96,36 +91,36 @@ static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot,
+ static BROTLI_INLINE size_t FN(HashMemAllocInBytes)(
+ const BrotliEncoderParams* params, BROTLI_BOOL one_shot,
+ size_t input_size) {
+- return sizeof(HashRolling) + NUMBUCKETS * sizeof(uint32_t);
++ return NUMBUCKETS * sizeof(uint32_t);
+ BROTLI_UNUSED(params);
+ BROTLI_UNUSED(one_shot);
+ BROTLI_UNUSED(input_size);
+ }
+
+-static BROTLI_INLINE void FN(Store)(HasherHandle BROTLI_RESTRICT handle,
++static BROTLI_INLINE void FN(Store)(HashRolling* BROTLI_RESTRICT self,
+ const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) {
+- BROTLI_UNUSED(handle);
++ BROTLI_UNUSED(self);
+ BROTLI_UNUSED(data);
+ BROTLI_UNUSED(mask);
+ BROTLI_UNUSED(ix);
+ }
+
+-static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle,
+- const uint8_t* data, const size_t mask, const size_t ix_start,
+- const size_t ix_end) {
+- BROTLI_UNUSED(handle);
++static BROTLI_INLINE void FN(StoreRange)(HashRolling* BROTLI_RESTRICT self,
++ const uint8_t* BROTLI_RESTRICT data, const size_t mask,
++ const size_t ix_start, const size_t ix_end) {
++ BROTLI_UNUSED(self);
+ BROTLI_UNUSED(data);
+ BROTLI_UNUSED(mask);
+ BROTLI_UNUSED(ix_start);
+ BROTLI_UNUSED(ix_end);
+ }
+
+-static BROTLI_INLINE void FN(StitchToPreviousBlock)(HasherHandle handle,
++static BROTLI_INLINE void FN(StitchToPreviousBlock)(
++ HashRolling* BROTLI_RESTRICT self,
+ size_t num_bytes, size_t position, const uint8_t* ringbuffer,
+ size_t ring_buffer_mask) {
+ /* In this case we must re-initialize the hasher from scratch from the
+ current position. */
+- HashRolling* self = FN(Self)(handle);
+ size_t position_masked;
+ size_t available = num_bytes;
+ if ((position & (JUMP - 1)) != 0) {
+@@ -139,26 +134,27 @@ static BROTLI_INLINE void FN(StitchToPreviousBlock)(HasherHandle handle,
+ available = ring_buffer_mask - position_masked;
+ }
+
+- FN(Prepare)(handle, BROTLI_FALSE, available,
++ FN(Prepare)(self, BROTLI_FALSE, available,
+ ringbuffer + (position & ring_buffer_mask));
+ self->next_ix = position;
+ BROTLI_UNUSED(num_bytes);
+ }
+
+ static BROTLI_INLINE void FN(PrepareDistanceCache)(
+- HasherHandle handle, int* BROTLI_RESTRICT distance_cache) {
+- BROTLI_UNUSED(handle);
++ HashRolling* BROTLI_RESTRICT self,
++ int* BROTLI_RESTRICT distance_cache) {
++ BROTLI_UNUSED(self);
+ BROTLI_UNUSED(distance_cache);
+ }
+
+-static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
++static BROTLI_INLINE void FN(FindLongestMatch)(
++ HashRolling* BROTLI_RESTRICT self,
+ const BrotliEncoderDictionary* dictionary,
+ const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask,
+ const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix,
+ const size_t max_length, const size_t max_backward,
+- const size_t gap, const size_t max_distance,
++ const size_t dictionary_distance, const size_t max_distance,
+ HasherSearchResult* BROTLI_RESTRICT out) {
+- HashRolling* self = FN(Self)(handle);
+ const size_t cur_ix_masked = cur_ix & ring_buffer_mask;
+ size_t pos = self->next_ix;
+
+@@ -209,7 +205,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
+ backup-hasher, the main hasher already searches in it. */
+ BROTLI_UNUSED(dictionary);
+ BROTLI_UNUSED(distance_cache);
+- BROTLI_UNUSED(gap);
++ BROTLI_UNUSED(dictionary_distance);
+ BROTLI_UNUSED(max_distance);
+ }
+
+diff --git a/c/enc/hash_to_binary_tree_inc.h b/c/enc/hash_to_binary_tree_inc.h
+index 7fb0356f..9880e0ae 100644
+--- a/c/enc/hash_to_binary_tree_inc.h
++++ b/c/enc/hash_to_binary_tree_inc.h
+@@ -24,7 +24,7 @@ static BROTLI_INLINE size_t FN(StoreLookahead)(void) {
+ return MAX_TREE_COMP_LENGTH;
+ }
+
+-static uint32_t FN(HashBytes)(const uint8_t* data) {
++static uint32_t FN(HashBytes)(const uint8_t* BROTLI_RESTRICT data) {
+ uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32;
+ /* The higher bits contain more mixture from the multiplication,
+ so we take our results from there. */
+@@ -38,7 +38,7 @@ typedef struct HashToBinaryTree {
+ /* Hash table that maps the 4-byte hashes of the sequence to the last
+ position where this hash was found, which is the root of the binary
+ tree of sequences that share this hash bucket. */
+- uint32_t buckets_[BUCKET_SIZE];
++ uint32_t* buckets_; /* uint32_t[BUCKET_SIZE]; */
+
+ /* A position used to mark a non-existent sequence, i.e. a tree is empty if
+ its root is at invalid_pos_ and a node is a leaf if both its children
+@@ -51,34 +51,30 @@ typedef struct HashToBinaryTree {
+ corresponding to a hash is a sequence starting at buckets_[hash] and
+ the left and right children of a sequence starting at pos are
+ forest_[2 * pos] and forest_[2 * pos + 1]. */
+- /* uint32_t forest[2 * num_nodes] */
++ uint32_t* forest_; /* uint32_t[2 * num_nodes] */
+ } HashToBinaryTree;
+
+-static BROTLI_INLINE HashToBinaryTree* FN(Self)(HasherHandle handle) {
+- return (HashToBinaryTree*)&(GetHasherCommon(handle)[1]);
+-}
+-
+-static BROTLI_INLINE uint32_t* FN(Forest)(HashToBinaryTree* self) {
+- return (uint32_t*)(&self[1]);
+-}
+-
+ static void FN(Initialize)(
+- HasherHandle handle, const BrotliEncoderParams* params) {
+- HashToBinaryTree* self = FN(Self)(handle);
++ HasherCommon* common, HashToBinaryTree* BROTLI_RESTRICT self,
++ const BrotliEncoderParams* params) {
++ self->buckets_ = (uint32_t*)common->extra;
++ self->forest_ = &self->buckets_[BUCKET_SIZE];
++
+ self->window_mask_ = (1u << params->lgwin) - 1u;
+ self->invalid_pos_ = (uint32_t)(0 - self->window_mask_);
+ }
+
+-static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot,
+- size_t input_size, const uint8_t* data) {
+- HashToBinaryTree* self = FN(Self)(handle);
++static void FN(Prepare)
++ (HashToBinaryTree* BROTLI_RESTRICT self, BROTLI_BOOL one_shot,
++ size_t input_size, const uint8_t* BROTLI_RESTRICT data) {
+ uint32_t invalid_pos = self->invalid_pos_;
+ uint32_t i;
++ uint32_t* BROTLI_RESTRICT buckets = self->buckets_;
+ BROTLI_UNUSED(data);
+ BROTLI_UNUSED(one_shot);
+ BROTLI_UNUSED(input_size);
+ for (i = 0; i < BUCKET_SIZE; i++) {
+- self->buckets_[i] = invalid_pos;
++ buckets[i] = invalid_pos;
+ }
+ }
+
+@@ -89,15 +85,17 @@ static BROTLI_INLINE size_t FN(HashMemAllocInBytes)(
+ if (one_shot && input_size < num_nodes) {
+ num_nodes = input_size;
+ }
+- return sizeof(HashToBinaryTree) + 2 * sizeof(uint32_t) * num_nodes;
++ return sizeof(uint32_t) * BUCKET_SIZE + 2 * sizeof(uint32_t) * num_nodes;
+ }
+
+-static BROTLI_INLINE size_t FN(LeftChildIndex)(HashToBinaryTree* self,
++static BROTLI_INLINE size_t FN(LeftChildIndex)(
++ HashToBinaryTree* BROTLI_RESTRICT self,
+ const size_t pos) {
+ return 2 * (pos & self->window_mask_);
+ }
+
+-static BROTLI_INLINE size_t FN(RightChildIndex)(HashToBinaryTree* self,
++static BROTLI_INLINE size_t FN(RightChildIndex)(
++ HashToBinaryTree* BROTLI_RESTRICT self,
+ const size_t pos) {
+ return 2 * (pos & self->window_mask_) + 1;
+ }
+@@ -113,7 +111,7 @@ static BROTLI_INLINE size_t FN(RightChildIndex)(HashToBinaryTree* self,
+
+ This function must be called with increasing cur_ix positions. */
+ static BROTLI_INLINE BackwardMatch* FN(StoreAndFindMatches)(
+- HashToBinaryTree* self, const uint8_t* const BROTLI_RESTRICT data,
++ HashToBinaryTree* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data,
+ const size_t cur_ix, const size_t ring_buffer_mask, const size_t max_length,
+ const size_t max_backward, size_t* const BROTLI_RESTRICT best_len,
+ BackwardMatch* BROTLI_RESTRICT matches) {
+@@ -123,8 +121,9 @@ static BROTLI_INLINE BackwardMatch* FN(StoreAndFindMatches)(
+ const BROTLI_BOOL should_reroot_tree =
+ TO_BROTLI_BOOL(max_length >= MAX_TREE_COMP_LENGTH);
+ const uint32_t key = FN(HashBytes)(&data[cur_ix_masked]);
+- uint32_t* forest = FN(Forest)(self);
+- size_t prev_ix = self->buckets_[key];
++ uint32_t* BROTLI_RESTRICT buckets = self->buckets_;
++ uint32_t* BROTLI_RESTRICT forest = self->forest_;
++ size_t prev_ix = buckets[key];
+ /* The forest index of the rightmost node of the left subtree of the new
+ root, updated as we traverse and re-root the tree of the hash bucket. */
+ size_t node_left = FN(LeftChildIndex)(self, cur_ix);
+@@ -139,7 +138,7 @@ static BROTLI_INLINE BackwardMatch* FN(StoreAndFindMatches)(
+ size_t best_len_right = 0;
+ size_t depth_remaining;
+ if (should_reroot_tree) {
+- self->buckets_[key] = (uint32_t)cur_ix;
++ buckets[key] = (uint32_t)cur_ix;
+ }
+ for (depth_remaining = MAX_TREE_SEARCH_DEPTH; ; --depth_remaining) {
+ const size_t backward = cur_ix - prev_ix;
+@@ -199,11 +198,13 @@ static BROTLI_INLINE BackwardMatch* FN(StoreAndFindMatches)(
+ matches in matches[0] to matches[*num_matches - 1]. The matches will be
+ sorted by strictly increasing length and (non-strictly) increasing
+ distance. */
+-static BROTLI_INLINE size_t FN(FindAllMatches)(HasherHandle handle,
+- const BrotliEncoderDictionary* dictionary, const uint8_t* data,
++static BROTLI_INLINE size_t FN(FindAllMatches)(
++ HashToBinaryTree* BROTLI_RESTRICT self,
++ const BrotliEncoderDictionary* dictionary,
++ const uint8_t* BROTLI_RESTRICT data,
+ const size_t ring_buffer_mask, const size_t cur_ix,
+ const size_t max_length, const size_t max_backward,
+- const size_t gap, const BrotliEncoderParams* params,
++ const size_t dictionary_distance, const BrotliEncoderParams* params,
+ BackwardMatch* matches) {
+ BackwardMatch* const orig_matches = matches;
+ const size_t cur_ix_masked = cur_ix & ring_buffer_mask;
+@@ -236,7 +237,7 @@ static BROTLI_INLINE size_t FN(FindAllMatches)(HasherHandle handle,
+ }
+ }
+ if (best_len < max_length) {
+- matches = FN(StoreAndFindMatches)(FN(Self)(handle), data, cur_ix,
++ matches = FN(StoreAndFindMatches)(self, data, cur_ix,
+ ring_buffer_mask, max_length, max_backward, &best_len, matches);
+ }
+ for (i = 0; i <= BROTLI_MAX_STATIC_DICTIONARY_MATCH_LEN; ++i) {
+@@ -252,7 +253,7 @@ static BROTLI_INLINE size_t FN(FindAllMatches)(HasherHandle handle,
+ for (l = minlen; l <= maxlen; ++l) {
+ uint32_t dict_id = dict_matches[l];
+ if (dict_id < kInvalidMatch) {
+- size_t distance = max_backward + gap + (dict_id >> 5) + 1;
++ size_t distance = dictionary_distance + (dict_id >> 5) + 1;
+ if (distance <= params->dist.max_distance) {
+ InitDictionaryBackwardMatch(matches++, distance, l, dict_id & 31);
+ }
+@@ -266,18 +267,18 @@ static BROTLI_INLINE size_t FN(FindAllMatches)(HasherHandle handle,
+ /* Stores the hash of the next 4 bytes and re-roots the binary tree at the
+ current sequence, without returning any matches.
+ REQUIRES: ix + MAX_TREE_COMP_LENGTH <= end-of-current-block */
+-static BROTLI_INLINE void FN(Store)(HasherHandle handle, const uint8_t* data,
++static BROTLI_INLINE void FN(Store)(HashToBinaryTree* BROTLI_RESTRICT self,
++ const uint8_t* BROTLI_RESTRICT data,
+ const size_t mask, const size_t ix) {
+- HashToBinaryTree* self = FN(Self)(handle);
+ /* Maximum distance is window size - 16, see section 9.1. of the spec. */
+ const size_t max_backward = self->window_mask_ - BROTLI_WINDOW_GAP + 1;
+ FN(StoreAndFindMatches)(self, data, ix, mask, MAX_TREE_COMP_LENGTH,
+ max_backward, NULL, NULL);
+ }
+
+-static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle,
+- const uint8_t* data, const size_t mask, const size_t ix_start,
+- const size_t ix_end) {
++static BROTLI_INLINE void FN(StoreRange)(HashToBinaryTree* BROTLI_RESTRICT self,
++ const uint8_t* BROTLI_RESTRICT data, const size_t mask,
++ const size_t ix_start, const size_t ix_end) {
+ size_t i = ix_start;
+ size_t j = ix_start;
+ if (ix_start + 63 <= ix_end) {
+@@ -285,18 +286,18 @@ static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle,
+ }
+ if (ix_start + 512 <= i) {
+ for (; j < i; j += 8) {
+- FN(Store)(handle, data, mask, j);
++ FN(Store)(self, data, mask, j);
+ }
+ }
+ for (; i < ix_end; ++i) {
+- FN(Store)(handle, data, mask, i);
++ FN(Store)(self, data, mask, i);
+ }
+ }
+
+-static BROTLI_INLINE void FN(StitchToPreviousBlock)(HasherHandle handle,
++static BROTLI_INLINE void FN(StitchToPreviousBlock)(
++ HashToBinaryTree* BROTLI_RESTRICT self,
+ size_t num_bytes, size_t position, const uint8_t* ringbuffer,
+ size_t ringbuffer_mask) {
+- HashToBinaryTree* self = FN(Self)(handle);
+ if (num_bytes >= FN(HashTypeLength)() - 1 &&
+ position >= MAX_TREE_COMP_LENGTH) {
+ /* Store the last `MAX_TREE_COMP_LENGTH - 1` positions in the hasher.
+diff --git a/c/enc/metablock.c b/c/enc/metablock.c
+index 4e80044f..b3e6c38f 100644
+--- a/c/enc/metablock.c
++++ b/c/enc/metablock.c
+@@ -28,34 +28,30 @@ extern "C" {
+ void BrotliInitDistanceParams(BrotliEncoderParams* params,
+ uint32_t npostfix, uint32_t ndirect) {
+ BrotliDistanceParams* dist_params = ¶ms->dist;
+- uint32_t alphabet_size, max_distance;
++ uint32_t alphabet_size_max;
++ uint32_t alphabet_size_limit;
++ uint32_t max_distance;
+
+ dist_params->distance_postfix_bits = npostfix;
+ dist_params->num_direct_distance_codes = ndirect;
+
+- alphabet_size = BROTLI_DISTANCE_ALPHABET_SIZE(
++ alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(
+ npostfix, ndirect, BROTLI_MAX_DISTANCE_BITS);
++ alphabet_size_limit = alphabet_size_max;
+ max_distance = ndirect + (1U << (BROTLI_MAX_DISTANCE_BITS + npostfix + 2)) -
+ (1U << (npostfix + 2));
+
+ if (params->large_window) {
+- static const uint32_t bound[BROTLI_MAX_NPOSTFIX + 1] = {0, 4, 12, 28};
+- uint32_t postfix = 1U << npostfix;
+- alphabet_size = BROTLI_DISTANCE_ALPHABET_SIZE(
++ BrotliDistanceCodeLimit limit = BrotliCalculateDistanceCodeLimit(
++ BROTLI_MAX_ALLOWED_DISTANCE, npostfix, ndirect);
++ alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(
+ npostfix, ndirect, BROTLI_LARGE_MAX_DISTANCE_BITS);
+- /* The maximum distance is set so that no distance symbol used can encode
+- a distance larger than BROTLI_MAX_ALLOWED_DISTANCE with all
+- its extra bits set. */
+- if (ndirect < bound[npostfix]) {
+- max_distance = BROTLI_MAX_ALLOWED_DISTANCE - (bound[npostfix] - ndirect);
+- } else if (ndirect >= bound[npostfix] + postfix) {
+- max_distance = (3U << 29) - 4 + (ndirect - bound[npostfix]);
+- } else {
+- max_distance = BROTLI_MAX_ALLOWED_DISTANCE;
+- }
++ alphabet_size_limit = limit.max_alphabet_size;
++ max_distance = limit.max_distance;
+ }
+
+- dist_params->alphabet_size = alphabet_size;
++ dist_params->alphabet_size_max = alphabet_size_max;
++ dist_params->alphabet_size_limit = alphabet_size_limit;
+ dist_params->max_distance = max_distance;
+ }
+
+diff --git a/c/enc/params.h b/c/enc/params.h
+index 6ecf1d3f..54a7f007 100755
+--- a/c/enc/params.h
++++ b/c/enc/params.h
+@@ -23,7 +23,8 @@ typedef struct BrotliHasherParams {
+ typedef struct BrotliDistanceParams {
+ uint32_t distance_postfix_bits;
+ uint32_t num_direct_distance_codes;
+- uint32_t alphabet_size;
++ uint32_t alphabet_size_max;
++ uint32_t alphabet_size_limit;
+ size_t max_distance;
+ } BrotliDistanceParams;
+
+@@ -33,6 +34,7 @@ typedef struct BrotliEncoderParams {
+ int quality;
+ int lgwin;
+ int lgblock;
++ size_t stream_offset;
+ size_t size_hint;
+ BROTLI_BOOL disable_literal_context_modeling;
+ BROTLI_BOOL large_window;
+diff --git a/c/enc/ringbuffer.h b/c/enc/ringbuffer.h
+index 86079a89..2fbac07e 100644
+--- a/c/enc/ringbuffer.h
++++ b/c/enc/ringbuffer.h
+@@ -125,6 +125,9 @@ static BROTLI_INLINE void RingBufferWrite(
+ later when we copy the last two bytes to the first two positions. */
+ rb->buffer_[rb->size_ - 2] = 0;
+ rb->buffer_[rb->size_ - 1] = 0;
++ /* Initialize tail; might be touched by "best_len++" optimization when
++ ring buffer is "full". */
++ rb->buffer_[rb->size_] = 241;
+ }
+ {
+ const size_t masked_pos = rb->pos_ & rb->mask_;
+diff --git a/c/enc/write_bits.h b/c/enc/write_bits.h
+index 36515a68..f6f88b45 100644
+--- a/c/enc/write_bits.h
++++ b/c/enc/write_bits.h
+@@ -16,8 +16,6 @@
+ extern "C" {
+ #endif
+
+-/*#define BIT_WRITER_DEBUG */
+-
+ /* This function writes bits into bytes in increasing addresses, and within
+ a byte least-significant-bit first.
+
+@@ -28,7 +26,7 @@ extern "C" {
+
+ 0000 0RRR 0000 0000 0000 0000
+
+- Now, we could write 5 or less bits in MSB by just sifting by 3
++ Now, we could write 5 or less bits in MSB by just shifting by 3
+ and OR'ing to BYTE-0.
+
+ For n bits, we take the last 5 bits, OR that with high bits in BYTE-0,
+@@ -37,37 +35,41 @@ static BROTLI_INLINE void BrotliWriteBits(size_t n_bits,
+ uint64_t bits,
+ size_t* BROTLI_RESTRICT pos,
+ uint8_t* BROTLI_RESTRICT array) {
++ BROTLI_LOG(("WriteBits %2d 0x%08x%08x %10d\n", (int)n_bits,
++ (uint32_t)(bits >> 32), (uint32_t)(bits & 0xFFFFFFFF),
++ (int)*pos));
++ BROTLI_DCHECK((bits >> n_bits) == 0);
++ BROTLI_DCHECK(n_bits <= 56);
+ #if defined(BROTLI_LITTLE_ENDIAN)
+ /* This branch of the code can write up to 56 bits at a time,
+ 7 bits are lost by being perhaps already in *p and at least
+ 1 bit is needed to initialize the bit-stream ahead (i.e. if 7
+ bits are in *p and we write 57 bits, then the next write will
+ access a byte that was never initialized). */
+- uint8_t* p = &array[*pos >> 3];
+- uint64_t v = (uint64_t)(*p); /* Zero-extend 8 to 64 bits. */
+- BROTLI_LOG(("WriteBits %2d 0x%08x%08x %10d\n", (int)n_bits,
+- (uint32_t)(bits >> 32), (uint32_t)(bits & 0xFFFFFFFF),
+- (int)*pos));
+- BROTLI_DCHECK((bits >> n_bits) == 0);
+- BROTLI_DCHECK(n_bits <= 56);
+- v |= bits << (*pos & 7);
+- BROTLI_UNALIGNED_STORE64LE(p, v); /* Set some bits. */
+- *pos += n_bits;
++ {
++ uint8_t* p = &array[*pos >> 3];
++ uint64_t v = (uint64_t)(*p); /* Zero-extend 8 to 64 bits. */
++ v |= bits << (*pos & 7);
++ BROTLI_UNALIGNED_STORE64LE(p, v); /* Set some bits. */
++ *pos += n_bits;
++ }
+ #else
+ /* implicit & 0xFF is assumed for uint8_t arithmetics */
+- uint8_t* array_pos = &array[*pos >> 3];
+- const size_t bits_reserved_in_first_byte = (*pos & 7);
+- size_t bits_left_to_write;
+- bits <<= bits_reserved_in_first_byte;
+- *array_pos++ |= (uint8_t)bits;
+- for (bits_left_to_write = n_bits + bits_reserved_in_first_byte;
+- bits_left_to_write >= 9;
+- bits_left_to_write -= 8) {
+- bits >>= 8;
+- *array_pos++ = (uint8_t)bits;
++ {
++ uint8_t* array_pos = &array[*pos >> 3];
++ const size_t bits_reserved_in_first_byte = (*pos & 7);
++ size_t bits_left_to_write;
++ bits <<= bits_reserved_in_first_byte;
++ *array_pos++ |= (uint8_t)bits;
++ for (bits_left_to_write = n_bits + bits_reserved_in_first_byte;
++ bits_left_to_write >= 9;
++ bits_left_to_write -= 8) {
++ bits >>= 8;
++ *array_pos++ = (uint8_t)bits;
++ }
++ *array_pos = 0;
++ *pos += n_bits;
+ }
+- *array_pos = 0;
+- *pos += n_bits;
+ #endif
+ }
+
+diff --git a/c/include/brotli/encode.h b/c/include/brotli/encode.h
+index 0ced7e55..b2774cb6 100644
+--- a/c/include/brotli/encode.h
++++ b/c/include/brotli/encode.h
+@@ -201,7 +201,23 @@ typedef enum BrotliEncoderParameter {
+ *
+ * Range is from 0 to (15 << NPOSTFIX) in steps of (1 << NPOSTFIX).
+ */
+- BROTLI_PARAM_NDIRECT = 8
++ BROTLI_PARAM_NDIRECT = 8,
++ /**
++ * Number of bytes of input stream already processed by a different instance.
++ *
++ * @note It is important to configure all the encoder instances with same
++ * parameters (except this one) in order to allow all the encoded parts
++ * obey the same restrictions implied by header.
++ *
++ * If offset is not 0, then stream header is omitted.
++ * In any case output start is byte aligned, so for proper streams stitching
++ * "predecessor" stream must be flushed.
++ *
++ * Range is not artificially limited, but all the values greater or equal to
++ * maximal window size have the same effect. Values greater than 2**30 are not
++ * allowed.
++ */
++ BROTLI_PARAM_STREAM_OFFSET = 9
+ } BrotliEncoderParameter;
+
+ /**
+@@ -274,6 +290,11 @@ BROTLI_ENC_API size_t BrotliEncoderMaxCompressedSize(size_t input_size);
+ * @note If ::BrotliEncoderMaxCompressedSize(@p input_size) returns non-zero
+ * value, then output is guaranteed to be no longer than that.
+ *
++ * @note If @p lgwin is greater than ::BROTLI_MAX_WINDOW_BITS then resulting
++ * stream might be incompatible with RFC 7932; to decode such streams,
++ * decoder should be configured with
++ * ::BROTLI_DECODER_PARAM_LARGE_WINDOW = @c 1
++ *
+ * @param quality quality parameter value, e.g. ::BROTLI_DEFAULT_QUALITY
+ * @param lgwin lgwin parameter value, e.g. ::BROTLI_DEFAULT_WINDOW
+ * @param mode mode parameter value, e.g. ::BROTLI_DEFAULT_MODE
+diff --git a/c/tools/brotli.c b/c/tools/brotli.c
+index 838539ad..d2c04851 100644
+--- a/c/tools/brotli.c
++++ b/c/tools/brotli.c
+@@ -556,11 +556,17 @@ static void PrintHelp(const char* name, BROTLI_BOOL error) {
+ " -t, --test test compressed file integrity\n"
+ " -v, --verbose verbose mode\n");
+ fprintf(media,
+-" -w NUM, --lgwin=NUM set LZ77 window size (0, %d-%d)\n",
++" -w NUM, --lgwin=NUM set LZ77 window size (0, %d-%d)\n"
++" window size = 2**NUM - 16\n"
++" 0 lets compressor choose the optimal value\n",
+ BROTLI_MIN_WINDOW_BITS, BROTLI_MAX_WINDOW_BITS);
+ fprintf(media,
+-" window size = 2**NUM - 16\n"
+-" 0 lets compressor choose the optimal value\n");
++" --large_window=NUM use incompatible large-window brotli\n"
++" bitstream with window size (0, %d-%d)\n"
++" WARNING: this format is not compatible\n"
++" with brotli RFC 7932 and may not be\n"
++" decodable with regular brotli decoders\n",
++ BROTLI_MIN_WINDOW_BITS, BROTLI_LARGE_MAX_WINDOW_BITS);
+ fprintf(media,
+ " -S SUF, --suffix=SUF output file suffix (default:'%s')\n",
+ DEFAULT_SUFFIX);
+diff --git a/compiler_config_setting.bzl b/compiler_config_setting.bzl
+new file mode 100755
+index 00000000..572032bf
+--- /dev/null
++++ b/compiler_config_setting.bzl
+@@ -0,0 +1,28 @@
++# Copyright 2018 Google Inc. All Rights Reserved.
++#
++# Distributed under MIT license.
++# See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
++
++"""Creates config_setting that allows selecting based on 'compiler' value."""
++
++def create_msvc_config():
++ # The "do_not_use_tools_cpp_compiler_present" attribute exists to
++ # distinguish between older versions of Bazel that do not support
++ # "@bazel_tools//tools/cpp:compiler" flag_value, and newer ones that do.
++ # In the future, the only way to select on the compiler will be through
++ # flag_values{"@bazel_tools//tools/cpp:compiler"} and the else branch can
++ # be removed.
++ if hasattr(cc_common, "do_not_use_tools_cpp_compiler_present"):
++ native.config_setting(
++ name = "msvc",
++ flag_values = {
++ "@bazel_tools//tools/cpp:compiler": "msvc-cl",
++ },
++ visibility = ["//visibility:public"],
++ )
++ else:
++ native.config_setting(
++ name = "msvc",
++ values = {"compiler": "msvc-cl"},
++ visibility = ["//visibility:public"],
++ )
+diff --git a/docs/encode.h.3 b/docs/encode.h.3
+index eff57bdd..0cab8166 100644
+--- a/docs/encode.h.3
++++ b/docs/encode.h.3
+@@ -298,12 +298,24 @@ Flag that determines if 'Large Window Brotli' is used\&.
+ \fB\fIBROTLI_PARAM_NPOSTFIX \fP\fP
+ Recommended number of postfix bits (NPOSTFIX)\&. Encoder may change this value\&.
+ .PP
+-Range is from 0 to ::BROTLI_MAX_NPOSTFIX\&.
++Range is from 0 to \fBBROTLI_MAX_NPOSTFIX\fP\&.
+ .TP
+ \fB\fIBROTLI_PARAM_NDIRECT \fP\fP
+ Recommended number of direct distance codes (NDIRECT)\&. Encoder may change this value\&.
+ .PP
+ Range is from 0 to (15 << NPOSTFIX) in steps of (1 << NPOSTFIX)\&.
++.TP
++\fB\fIBROTLI_PARAM_STREAM_OFFSET \fP\fP
++Number of bytes of input stream already processed by a different instance\&.
++.PP
++\fBNote:\fP
++.RS 4
++It is important to configure all the encoder instances with same parameters (except this one) in order to allow all the encoded parts obey the same restrictions implied by header\&.
++.RE
++.PP
++If offset is not 0, then stream header is omitted\&. In any case output start is byte aligned, so for proper streams stitching 'predecessor' stream must be flushed\&.
++.PP
++Range is not artificially limited, but all the values greater or equal to maximal window size have the same effect\&. Values greater than 2**30 are not allowed\&.
+ .SH "Function Documentation"
+ .PP
+ .SS "\fBBROTLI_BOOL\fP BrotliEncoderCompress (int quality, int lgwin, \fBBrotliEncoderMode\fP mode, size_t input_size, const uint8_t input_buffer[input_size], size_t * encoded_size, uint8_t encoded_buffer[*encoded_size])"
+@@ -314,6 +326,8 @@ Performs one-shot memory-to-memory compression\&. Compresses the data in \fCinpu
+ \fBNote:\fP
+ .RS 4
+ If \fBBrotliEncoderMaxCompressedSize\fP(\fCinput_size\fP) returns non-zero value, then output is guaranteed to be no longer than that\&.
++.PP
++If \fClgwin\fP is greater than \fBBROTLI_MAX_WINDOW_BITS\fP then resulting stream might be incompatible with RFC 7932; to decode such streams, decoder should be configured with \fBBROTLI_DECODER_PARAM_LARGE_WINDOW\fP = \fC1\fP
+ .RE
+ .PP
+ \fBParameters:\fP
+diff --git a/java/org/brotli/dec/BitReader.java b/java/org/brotli/dec/BitReader.java
+index 5d54e010..6dfeedca 100644
+--- a/java/org/brotli/dec/BitReader.java
++++ b/java/org/brotli/dec/BitReader.java
+@@ -12,9 +12,14 @@
+ final class BitReader {
+
+ // Possible values: {5, 6}. 5 corresponds to 32-bit build, 6 to 64-bit. This value is used for
+- // conditional compilation -> produced artifacts might be binary INCOMPATIBLE (JLS 13.2).
+- private static final int LOG_BITNESS = 6;
+- private static final int BITNESS = 1 << LOG_BITNESS;
++ // JIT conditional compilation.
++ private static final int LOG_BITNESS = Utils.getLogBintness();
++
++ // Not only Java compiler prunes "if (const false)" code, but JVM as well.
++ // Code under "if (DEBUG != 0)" have zero performance impact (outside unit tests).
++ private static final int DEBUG = Utils.isDebugMode();
++
++ static final int BITNESS = 1 << LOG_BITNESS;
+
+ private static final int BYTENESS = BITNESS / 8;
+ private static final int CAPACITY = 4096;
+@@ -89,7 +94,16 @@ static void checkHealth(State s, int endOfStream) {
+ }
+ }
+
++ static void assertAccumulatorHealthy(State s) {
++ if (s.bitOffset > BITNESS) {
++ throw new IllegalStateException("Accumulator underloaded: " + s.bitOffset);
++ }
++ }
++
+ static void fillBitWindow(State s) {
++ if (DEBUG != 0) {
++ assertAccumulatorHealthy(s);
++ }
+ if (s.bitOffset >= HALF_BITNESS) {
+ // Same as doFillBitWindow. JVM fails to inline it.
+ if (BITNESS == 64) {
+@@ -103,7 +117,10 @@ static void fillBitWindow(State s) {
+ }
+ }
+
+- private static void doFillBitWindow(State s) {
++ static void doFillBitWindow(State s) {
++ if (DEBUG != 0) {
++ assertAccumulatorHealthy(s);
++ }
+ if (BITNESS == 64) {
+ s.accumulator64 = ((long) s.intBuffer[s.halfOffset++] << HALF_BITNESS)
+ | (s.accumulator64 >>> HALF_BITNESS);
+@@ -122,6 +139,12 @@ static int peekBits(State s) {
+ }
+ }
+
++ /**
++ * Fetches bits from accumulator.
++ *
++ * WARNING: accumulator MUST contain at least the specified amount of bits,
++ * otherwise BitReader will become broken.
++ */
+ static int readFewBits(State s, int n) {
+ int val = peekBits(s) & ((1 << n) - 1);
+ s.bitOffset += n;
+diff --git a/java/org/brotli/dec/BitReaderTest.java b/java/org/brotli/dec/BitReaderTest.java
+index fa57640e..da59ebce 100644
+--- a/java/org/brotli/dec/BitReaderTest.java
++++ b/java/org/brotli/dec/BitReaderTest.java
+@@ -32,4 +32,23 @@ public void testReadAfterEos() {
+ }
+ fail("BrotliRuntimeException should have been thrown by BitReader.checkHealth");
+ }
++
++ @Test
++ public void testAccumulatorUnderflowDetected() {
++ State reader = new State();
++ Decode.initState(reader, new ByteArrayInputStream(new byte[8]));
++ // 65 bits is enough for both 32 and 64 bit systems.
++ BitReader.readBits(reader, 13);
++ BitReader.readBits(reader, 13);
++ BitReader.readBits(reader, 13);
++ BitReader.readBits(reader, 13);
++ BitReader.readBits(reader, 13);
++ try {
++ BitReader.fillBitWindow(reader);
++ } catch (IllegalStateException ex) {
++ // This exception is expected.
++ return;
++ }
++ fail("IllegalStateException should have been thrown by 'broken' BitReader");
++ }
+ }
+diff --git a/java/org/brotli/dec/BrotliInputStream.java b/java/org/brotli/dec/BrotliInputStream.java
+index 5cc2e284..b99e40a2 100644
+--- a/java/org/brotli/dec/BrotliInputStream.java
++++ b/java/org/brotli/dec/BrotliInputStream.java
+@@ -84,18 +84,12 @@ public BrotliInputStream(InputStream source, int byteReadBufferSize) throws IOEx
+ }
+ }
+
+- public void setEager(boolean eager) {
+- boolean isEager = (state.isEager != 0);
+- if (eager == isEager) {
+- /* Shortcut for no-op change. */
+- return;
+- }
+- if (eager) {
+- Decode.setEager(state);
+- } else {
+- /* Once decoder is "eager", there is no way back. */
+- throw new IllegalStateException("Brotli decoder has been already switched to eager mode");
+- }
++ public void enableEagerOutput() {
++ Decode.enableEagerOutput(state);
++ }
++
++ public void enableLargeWindow() {
++ Decode.enableLargeWindow(state);
+ }
+
+ /**
+diff --git a/java/org/brotli/dec/Decode.java b/java/org/brotli/dec/Decode.java
+index 60bf9c61..560c635d 100644
+--- a/java/org/brotli/dec/Decode.java
++++ b/java/org/brotli/dec/Decode.java
+@@ -14,6 +14,11 @@
+ */
+ final class Decode {
+
++ static final int MIN_LARGE_WINDOW_BITS = 10;
++ /* Maximum was chosen to be 30 to allow efficient decoder implementation.
++ * Format allows bigger window, but Java does not support 2G+ arrays. */
++ static final int MAX_LARGE_WINDOW_BITS = 30;
++
+ //----------------------------------------------------------------------------
+ // RunningState
+ //----------------------------------------------------------------------------
+@@ -35,7 +40,7 @@
+ private static final int DEFAULT_CODE_LENGTH = 8;
+ private static final int CODE_LENGTH_REPEAT_CODE = 16;
+ private static final int NUM_LITERAL_CODES = 256;
+- private static final int NUM_INSERT_AND_COPY_CODES = 704;
++ private static final int NUM_COMMAND_CODES = 704;
+ private static final int NUM_BLOCK_LENGTH_CODES = 26;
+ private static final int LITERAL_CONTEXT_BITS = 6;
+ private static final int DISTANCE_CONTEXT_BITS = 2;
+@@ -44,10 +49,19 @@
+ private static final int HUFFMAN_TABLE_MASK = 0xFF;
+
+ /**
+- * Maximum possible Huffman table size for an alphabet size of 704, max code length 15 and root
+- * table bits 8.
++ * Maximum possible Huffman table size for an alphabet size of (index * 32),
++ * max code length 15 and root table bits 8.
++ * The biggest alphabet is "command" - 704 symbols. Though "distance" alphabet could theoretically
++ * outreach that limit (for 62 extra bit distances), practically it is limited by
++ * MAX_ALLOWED_DISTANCE and never gets bigger than 544 symbols.
+ */
+- static final int HUFFMAN_TABLE_SIZE = 1080;
++ static final int[] MAX_HUFFMAN_TABLE_SIZE = {
++ 256, 402, 436, 468, 500, 534, 566, 598, 630, 662, 694, 726, 758, 790, 822,
++ 854, 886, 920, 952, 984, 1016, 1048, 1080
++ };
++
++ private static final int HUFFMAN_TABLE_SIZE_26 = 396;
++ private static final int HUFFMAN_TABLE_SIZE_258 = 632;
+
+ private static final int CODE_LENGTH_CODES = 18;
+ private static final int[] CODE_LENGTH_CODE_ORDER = {
+@@ -56,7 +70,7 @@
+
+ private static final int NUM_DISTANCE_SHORT_CODES = 16;
+ private static final int[] DISTANCE_SHORT_CODE_INDEX_OFFSET = {
+- 3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2
++ 0, 3, 2, 1, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3
+ };
+
+ private static final int[] DISTANCE_SHORT_CODE_VALUE_OFFSET = {
+@@ -86,6 +100,17 @@
+
+ static final int MAX_TRANSFORMED_WORD_LENGTH = 5 + MAX_WORD_LENGTH + 8;
+
++ private static final int MAX_DISTANCE_BITS = 24;
++ private static final int MAX_LARGE_WINDOW_DISTANCE_BITS = 62;
++
++ /**
++ * Safe distance limit.
++ *
++ * Limit ((1 << 31) - 4) allows safe distance calculation without overflows,
++ * given the distance alphabet size is limited to corresponding size.
++ */
++ private static final int MAX_ALLOWED_DISTANCE = 0x7FFFFFFC;
++
+ //----------------------------------------------------------------------------
+ // Prefix code LUT.
+ //----------------------------------------------------------------------------
+@@ -98,33 +123,103 @@
+ 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 24
+ };
+
+- static final int[] INSERT_LENGTH_OFFSET = {
+- 0, 1, 2, 3, 4, 5, 6, 8, 10, 14, 18, 26, 34, 50, 66, 98, 130, 194, 322, 578, 1090, 2114, 6210,
+- 22594
++ static final short[] INSERT_LENGTH_N_BITS = {
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03,
++ 0x04, 0x04, 0x05, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0C, 0x0E, 0x18
+ };
+
+- static final int[] INSERT_LENGTH_N_BITS = {
+- 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 12, 14, 24
++ static final short[] COPY_LENGTH_N_BITS = {
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02,
++ 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x18
+ };
+
+- static final int[] COPY_LENGTH_OFFSET = {
+- 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 18, 22, 30, 38, 54, 70, 102, 134, 198, 326, 582, 1094,
+- 2118
+- };
++ // Each command is represented with 4x16-bit values:
++ // * [insertLenExtraBits, copyLenExtraBits]
++ // * insertLenOffset
++ // * copyLenOffset
++ // * distanceContext
++ static final short[] CMD_LOOKUP = new short[NUM_COMMAND_CODES * 4];
+
+- static final int[] COPY_LENGTH_N_BITS = {
+- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 24
+- };
++ static {
++ unpackCommandLookupTable(CMD_LOOKUP);
++ }
+
+- static final int[] INSERT_RANGE_LUT = {
+- 0, 0, 8, 8, 0, 16, 8, 16, 16
+- };
++ private static int log2floor(int i) {
++ int result = -1;
++ int step = 16;
++ while (step > 0) {
++ if ((i >>> step) != 0) {
++ result += step;
++ i = i >>> step;
++ }
++ step = step >> 1;
++ }
++ return result + i;
++ }
+
+- static final int[] COPY_RANGE_LUT = {
+- 0, 8, 0, 8, 16, 0, 16, 8, 16
+- };
++ private static int calculateDistanceAlphabetSize(int npostfix, int ndirect, int maxndistbits) {
++ return NUM_DISTANCE_SHORT_CODES + ndirect + 2 * (maxndistbits << npostfix);
++ }
++
++ // TODO: add a correctness test for this function when
++ // large-window and dictionary are implemented.
++ private static int calculateDistanceAlphabetLimit(int maxDistance, int npostfix, int ndirect) {
++ if (maxDistance < ndirect + (2 << npostfix)) {
++ throw new IllegalArgumentException("maxDistance is too small");
++ }
++ int offset = ((maxDistance - ndirect) >> npostfix) + 4;
++ int ndistbits = log2floor(offset) - 1;
++ int group = ((ndistbits - 1) << 1) | ((offset >> ndistbits) & 1);
++ return ((group - 1) << npostfix) + (1 << npostfix) + ndirect + NUM_DISTANCE_SHORT_CODES;
++ }
++
++ private static void unpackCommandLookupTable(short[] cmdLookup) {
++ short[] insertLengthOffsets = new short[24];
++ short[] copyLengthOffsets = new short[24];
++ copyLengthOffsets[0] = 2;
++ for (int i = 0; i < 23; ++i) {
++ insertLengthOffsets[i + 1] =
++ (short) (insertLengthOffsets[i] + (1 << INSERT_LENGTH_N_BITS[i]));
++ copyLengthOffsets[i + 1] =
++ (short) (copyLengthOffsets[i] + (1 << COPY_LENGTH_N_BITS[i]));
++ }
+
++ for (int cmdCode = 0; cmdCode < NUM_COMMAND_CODES; ++cmdCode) {
++ int rangeIdx = cmdCode >>> 6;
++ /* -4 turns any regular distance code to negative. */
++ int distanceContextOffset = -4;
++ if (rangeIdx >= 2) {
++ rangeIdx -= 2;
++ distanceContextOffset = 0;
++ }
++ int insertCode = (((0x29850 >>> (rangeIdx * 2)) & 0x3) << 3) | ((cmdCode >>> 3) & 7);
++ int copyCode = (((0x26244 >>> (rangeIdx * 2)) & 0x3) << 3) | (cmdCode & 7);
++ short copyLengthOffset = copyLengthOffsets[copyCode];
++ int distanceContext =
++ distanceContextOffset + (copyLengthOffset > 4 ? 3 : copyLengthOffset - 2);
++ int index = cmdCode * 4;
++ cmdLookup[index + 0] =
++ (short) (INSERT_LENGTH_N_BITS[insertCode] | (COPY_LENGTH_N_BITS[copyCode] << 8));
++ cmdLookup[index + 1] = insertLengthOffsets[insertCode];
++ cmdLookup[index + 2] = copyLengthOffsets[copyCode];
++ cmdLookup[index + 3] = (short) distanceContext;
++ }
++ }
++
++ /**
++ * Reads brotli stream header and parses "window bits".
++ *
++ * @param s initialized state, before any read is performed.
++ * @return -1 if header is invalid
++ */
+ private static int decodeWindowBits(State s) {
++ /* Change the meaning of flag. Before that step it means "decoder must be capable of reading
++ * "large-window" brotli stream. After this step it means that "large-window" feature
++ * is actually detected. Despite the window size could be same as before (lgwin = 10..24),
++ * encoded distances are allowed to be much greater, thus bigger dictinary could be used. */
++ int largeWindowEnabled = s.isLargeWindow;
++ s.isLargeWindow = 0;
++
+ BitReader.fillBitWindow(s);
+ if (BitReader.readFewBits(s, 1) == 0) {
+ return 16;
+@@ -135,7 +230,25 @@ private static int decodeWindowBits(State s) {
+ }
+ n = BitReader.readFewBits(s, 3);
+ if (n != 0) {
+- return 8 + n;
++ if (n == 1) {
++ if (largeWindowEnabled == 0) {
++ /* Reserved value in regular brotli stream. */
++ return -1;
++ }
++ s.isLargeWindow = 1;
++ /* Check "reserved" bit for future (post-large-window) extensions. */
++ if (BitReader.readFewBits(s, 1) == 1) {
++ return -1;
++ }
++ n = BitReader.readFewBits(s, 6);
++ if (n < MIN_LARGE_WINDOW_BITS || n > MAX_LARGE_WINDOW_BITS) {
++ /* Encoded window bits value is too small or too big. */
++ return -1;
++ }
++ return n;
++ } else {
++ return 8 + n;
++ }
+ }
+ return 17;
+ }
+@@ -147,13 +260,20 @@ private static int decodeWindowBits(State s) {
+ *
+ * @param s initialized state, before any read is performed.
+ */
+- static void setEager(State s) {
++ static void enableEagerOutput(State s) {
+ if (s.runningState != INITIALIZED) {
+ throw new IllegalStateException("State MUST be freshly initialized");
+ }
+ s.isEager = 1;
+ }
+
++ static void enableLargeWindow(State s) {
++ if (s.runningState != INITIALIZED) {
++ throw new IllegalStateException("State MUST be freshly initialized");
++ }
++ s.isLargeWindow = 1;
++ }
++
+ /**
+ * Associate input with decoder state.
+ *
+@@ -164,7 +284,13 @@ static void initState(State s, InputStream input) {
+ if (s.runningState != UNINITIALIZED) {
+ throw new IllegalStateException("State MUST be uninitialized");
+ }
+- s.blockTrees = new int[6 * HUFFMAN_TABLE_SIZE];
++ /* 6 trees + 1 extra "offset" slot to simplify table decoding logic. */
++ s.blockTrees = new int[7 + 3 * (HUFFMAN_TABLE_SIZE_258 + HUFFMAN_TABLE_SIZE_26)];
++ s.blockTrees[0] = 7;
++ s.distRbIdx = 3;
++ int maxDistanceAlphabetLimit = calculateDistanceAlphabetLimit(MAX_ALLOWED_DISTANCE, 3, 15 << 3);
++ s.distExtraBits = new byte[maxDistanceAlphabetLimit];
++ s.distOffset = new int[maxDistanceAlphabetLimit];
+ s.input = input;
+ BitReader.initBitReader(s);
+ s.runningState = INITIALIZED;
+@@ -246,11 +372,12 @@ private static void decodeMetaBlockLength(State s) {
+ /**
+ * Decodes the next Huffman code from bit-stream.
+ */
+- private static int readSymbol(int[] table, int offset, State s) {
++ private static int readSymbol(int[] tableGroup, int tableIdx, State s) {
++ int offset = tableGroup[tableIdx];
+ int val = BitReader.peekBits(s);
+ offset += val & HUFFMAN_TABLE_MASK;
+- int bits = table[offset] >> 16;
+- int sym = table[offset] & 0xFFFF;
++ int bits = tableGroup[offset] >> 16;
++ int sym = tableGroup[offset] & 0xFFFF;
+ if (bits <= HUFFMAN_TABLE_BITS) {
+ s.bitOffset += bits;
+ return sym;
+@@ -258,27 +385,18 @@ private static int readSymbol(int[] table, int offset, State s) {
+ offset += sym;
+ int mask = (1 << bits) - 1;
+ offset += (val & mask) >>> HUFFMAN_TABLE_BITS;
+- s.bitOffset += ((table[offset] >> 16) + HUFFMAN_TABLE_BITS);
+- return table[offset] & 0xFFFF;
++ s.bitOffset += ((tableGroup[offset] >> 16) + HUFFMAN_TABLE_BITS);
++ return tableGroup[offset] & 0xFFFF;
+ }
+
+- private static int readBlockLength(int[] table, int offset, State s) {
++ private static int readBlockLength(int[] tableGroup, int tableIdx, State s) {
+ BitReader.fillBitWindow(s);
+- int code = readSymbol(table, offset, s);
++ int code = readSymbol(tableGroup, tableIdx, s);
+ int n = BLOCK_LENGTH_N_BITS[code];
+ BitReader.fillBitWindow(s);
+ return BLOCK_LENGTH_OFFSET[code] + BitReader.readBits(s, n);
+ }
+
+- private static int translateShortCodes(int code, int[] ringBuffer, int index) {
+- if (code < NUM_DISTANCE_SHORT_CODES) {
+- index += DISTANCE_SHORT_CODE_INDEX_OFFSET[code];
+- index &= 3;
+- return ringBuffer[index] + DISTANCE_SHORT_CODE_VALUE_OFFSET[code];
+- }
+- return code - NUM_DISTANCE_SHORT_CODES + 1;
+- }
+-
+ private static void moveToFront(int[] v, int index) {
+ int value = v[index];
+ for (; index > 0; index--) {
+@@ -308,9 +426,9 @@ private static void readHuffmanCodeLengths(
+ int repeat = 0;
+ int repeatCodeLen = 0;
+ int space = 32768;
+- int[] table = new int[32];
+-
+- Huffman.buildHuffmanTable(table, 0, 5, codeLengthCodeLengths, CODE_LENGTH_CODES);
++ int[] table = new int[32 + 1]; /* Speculative single entry table group. */
++ int tableIdx = table.length - 1;
++ Huffman.buildHuffmanTable(table, tableIdx, 5, codeLengthCodeLengths, CODE_LENGTH_CODES);
+
+ while (symbol < numSymbols && space > 0) {
+ BitReader.readMoreInput(s);
+@@ -361,85 +479,128 @@ private static void readHuffmanCodeLengths(
+ Utils.fillIntsWithZeroes(codeLengths, symbol, numSymbols);
+ }
+
+- static int checkDupes(int[] symbols, int length) {
++ private static void checkDupes(int[] symbols, int length) {
+ for (int i = 0; i < length - 1; ++i) {
+ for (int j = i + 1; j < length; ++j) {
+ if (symbols[i] == symbols[j]) {
+- return 0;
++ throw new BrotliRuntimeException("Duplicate simple Huffman code symbol"); // COV_NF_LINE
+ }
+ }
+ }
+- return 1;
+ }
+
+- // TODO: Use specialized versions for smaller tables.
+- static void readHuffmanCode(int alphabetSize, int[] table, int offset, State s) {
+- int ok = 1;
+- int simpleCodeOrSkip;
+- BitReader.readMoreInput(s);
+- // TODO: Avoid allocation.
+- int[] codeLengths = new int[alphabetSize];
+- BitReader.fillBitWindow(s);
+- simpleCodeOrSkip = BitReader.readFewBits(s, 2);
+- if (simpleCodeOrSkip == 1) { // Read symbols, codes & code lengths directly.
+- int maxBitsCounter = alphabetSize - 1;
+- int maxBits = 0;
+- int[] symbols = new int[4];
+- int numSymbols = BitReader.readFewBits(s, 2) + 1;
+- while (maxBitsCounter != 0) {
+- maxBitsCounter >>= 1;
+- maxBits++;
+- }
+- // TODO: uncomment when codeLengths is reused.
+- // Utils.fillWithZeroes(codeLengths, 0, alphabetSize);
+- for (int i = 0; i < numSymbols; i++) {
+- BitReader.fillBitWindow(s);
+- symbols[i] = BitReader.readFewBits(s, maxBits) % alphabetSize;
+- codeLengths[symbols[i]] = 2;
+- }
+- codeLengths[symbols[0]] = 1;
+- switch (numSymbols) {
+- case 2:
+- codeLengths[symbols[1]] = 1;
+- break;
+- case 4:
+- if (BitReader.readFewBits(s, 1) == 1) {
+- codeLengths[symbols[2]] = 3;
+- codeLengths[symbols[3]] = 3;
+- } else {
+- codeLengths[symbols[0]] = 2;
+- }
+- break;
+- default:
+- break;
+- }
+- ok = checkDupes(symbols, numSymbols);
+- } else { // Decode Huffman-coded code lengths.
+- int[] codeLengthCodeLengths = new int[CODE_LENGTH_CODES];
+- int space = 32;
+- int numCodes = 0;
+- for (int i = simpleCodeOrSkip; i < CODE_LENGTH_CODES && space > 0; i++) {
+- int codeLenIdx = CODE_LENGTH_CODE_ORDER[i];
+- BitReader.fillBitWindow(s);
+- int p = BitReader.peekBits(s) & 15;
+- // TODO: Demultiplex FIXED_TABLE.
+- s.bitOffset += FIXED_TABLE[p] >> 16;
+- int v = FIXED_TABLE[p] & 0xFFFF;
+- codeLengthCodeLengths[codeLenIdx] = v;
+- if (v != 0) {
+- space -= (32 >> v);
+- numCodes++;
+- }
++ /**
++ * Reads up to 4 symbols directly and applies predefined histograms.
++ */
++ private static int readSimpleHuffmanCode(int alphabetSizeMax, int alphabetSizeLimit,
++ int[] tableGroup, int tableIdx, State s) {
++ // TODO: Avoid allocation?
++ int[] codeLengths = new int[alphabetSizeLimit];
++ int[] symbols = new int[4];
++
++ int maxBits = 1 + log2floor(alphabetSizeMax - 1);
++
++ int numSymbols = BitReader.readFewBits(s, 2) + 1;
++ for (int i = 0; i < numSymbols; i++) {
++ BitReader.fillBitWindow(s);
++ int symbol = BitReader.readFewBits(s, maxBits);
++ if (symbol >= alphabetSizeLimit) {
++ throw new BrotliRuntimeException("Can't readHuffmanCode"); // COV_NF_LINE
+ }
+- if (space != 0 && numCodes != 1) {
+- ok = 0;
++ symbols[i] = symbol;
++ }
++ checkDupes(symbols, numSymbols);
++
++ int histogramId = numSymbols;
++ if (numSymbols == 4) {
++ histogramId += BitReader.readFewBits(s, 1);
++ }
++
++ switch (histogramId) {
++ case 1:
++ codeLengths[symbols[0]] = 1;
++ break;
++
++ case 2:
++ codeLengths[symbols[0]] = 1;
++ codeLengths[symbols[1]] = 1;
++ break;
++
++ case 3:
++ codeLengths[symbols[0]] = 1;
++ codeLengths[symbols[1]] = 2;
++ codeLengths[symbols[2]] = 2;
++ break;
++
++ case 4: // uniform 4-symbol histogram
++ codeLengths[symbols[0]] = 2;
++ codeLengths[symbols[1]] = 2;
++ codeLengths[symbols[2]] = 2;
++ codeLengths[symbols[3]] = 2;
++ break;
++
++ case 5: // prioritized 4-symbol histogram
++ codeLengths[symbols[0]] = 1;
++ codeLengths[symbols[1]] = 2;
++ codeLengths[symbols[2]] = 3;
++ codeLengths[symbols[3]] = 3;
++ break;
++
++ default:
++ break;
++ }
++
++ // TODO: Use specialized version?
++ return Huffman.buildHuffmanTable(
++ tableGroup, tableIdx, HUFFMAN_TABLE_BITS, codeLengths, alphabetSizeLimit);
++ }
++
++ // Decode Huffman-coded code lengths.
++ private static int readComplexHuffmanCode(int alphabetSizeLimit, int skip,
++ int[] tableGroup, int tableIdx, State s) {
++ // TODO: Avoid allocation?
++ int[] codeLengths = new int[alphabetSizeLimit];
++ int[] codeLengthCodeLengths = new int[CODE_LENGTH_CODES];
++ int space = 32;
++ int numCodes = 0;
++ for (int i = skip; i < CODE_LENGTH_CODES && space > 0; i++) {
++ int codeLenIdx = CODE_LENGTH_CODE_ORDER[i];
++ BitReader.fillBitWindow(s);
++ int p = BitReader.peekBits(s) & 15;
++ // TODO: Demultiplex FIXED_TABLE.
++ s.bitOffset += FIXED_TABLE[p] >> 16;
++ int v = FIXED_TABLE[p] & 0xFFFF;
++ codeLengthCodeLengths[codeLenIdx] = v;
++ if (v != 0) {
++ space -= (32 >> v);
++ numCodes++;
+ }
+- readHuffmanCodeLengths(codeLengthCodeLengths, alphabetSize, codeLengths, s);
+ }
+- if (ok == 0) {
+- throw new BrotliRuntimeException("Can't readHuffmanCode"); // COV_NF_LINE
++ if (space != 0 && numCodes != 1) {
++ throw new BrotliRuntimeException("Corrupted Huffman code histogram"); // COV_NF_LINE
++ }
++
++ readHuffmanCodeLengths(codeLengthCodeLengths, alphabetSizeLimit, codeLengths, s);
++
++ return Huffman.buildHuffmanTable(
++ tableGroup, tableIdx, HUFFMAN_TABLE_BITS, codeLengths, alphabetSizeLimit);
++ }
++
++ /**
++ * Decodes Huffman table from bit-stream.
++ *
++ * @return number of slots used by resulting Huffman table
++ */
++ private static int readHuffmanCode(int alphabetSizeMax, int alphabetSizeLimit,
++ int[] tableGroup, int tableIdx, State s) {
++ BitReader.readMoreInput(s);
++ BitReader.fillBitWindow(s);
++ int simpleCodeOrSkip = BitReader.readFewBits(s, 2);
++ if (simpleCodeOrSkip == 1) {
++ return readSimpleHuffmanCode(alphabetSizeMax, alphabetSizeLimit, tableGroup, tableIdx, s);
++ } else {
++ return readComplexHuffmanCode(alphabetSizeLimit, simpleCodeOrSkip, tableGroup, tableIdx, s);
+ }
+- Huffman.buildHuffmanTable(table, offset, HUFFMAN_TABLE_BITS, codeLengths, alphabetSize);
+ }
+
+ private static int decodeContextMap(int contextMapSize, byte[] contextMap, State s) {
+@@ -457,12 +618,16 @@ private static int decodeContextMap(int contextMapSize, byte[] contextMap, State
+ if (useRleForZeros != 0) {
+ maxRunLengthPrefix = BitReader.readFewBits(s, 4) + 1;
+ }
+- int[] table = new int[HUFFMAN_TABLE_SIZE];
+- readHuffmanCode(numTrees + maxRunLengthPrefix, table, 0, s);
++ int alphabetSize = numTrees + maxRunLengthPrefix;
++ int tableSize = MAX_HUFFMAN_TABLE_SIZE[(alphabetSize + 31) >> 5];
++ /* Speculative single entry table group. */
++ int[] table = new int[tableSize + 1];
++ int tableIdx = table.length - 1;
++ readHuffmanCode(alphabetSize, alphabetSize, table, tableIdx, s);
+ for (int i = 0; i < contextMapSize; ) {
+ BitReader.readMoreInput(s);
+ BitReader.fillBitWindow(s);
+- int code = readSymbol(table, 0, s);
++ int code = readSymbol(table, tableIdx, s);
+ if (code == 0) {
+ contextMap[i] = 0;
+ i++;
+@@ -493,8 +658,8 @@ private static int decodeBlockTypeAndLength(State s, int treeType, int numBlockT
+ final int[] ringBuffers = s.rings;
+ final int offset = 4 + treeType * 2;
+ BitReader.fillBitWindow(s);
+- int blockType = readSymbol(s.blockTrees, treeType * HUFFMAN_TABLE_SIZE, s);
+- int result = readBlockLength(s.blockTrees, (treeType + 3) * HUFFMAN_TABLE_SIZE, s);
++ int blockType = readSymbol(s.blockTrees, 2 * treeType, s);
++ int result = readBlockLength(s.blockTrees, 2 * treeType + 1, s);
+
+ if (blockType == 1) {
+ blockType = ringBuffers[offset + 1] + 1;
+@@ -515,8 +680,7 @@ private static void decodeLiteralBlockSwitch(State s) {
+ s.literalBlockLength = decodeBlockTypeAndLength(s, 0, s.numLiteralBlockTypes);
+ int literalBlockType = s.rings[5];
+ s.contextMapSlice = literalBlockType << LITERAL_CONTEXT_BITS;
+- s.literalTreeIndex = s.contextMap[s.contextMapSlice] & 0xFF;
+- s.literalTree = s.hGroup0[s.literalTreeIndex];
++ s.literalTreeIdx = s.contextMap[s.contextMapSlice] & 0xFF;
+ int contextMode = s.contextModes[literalBlockType];
+ s.contextLookupOffset1 = contextMode << 9;
+ s.contextLookupOffset2 = s.contextLookupOffset1 + 256;
+@@ -524,7 +688,7 @@ private static void decodeLiteralBlockSwitch(State s) {
+
+ private static void decodeCommandBlockSwitch(State s) {
+ s.commandBlockLength = decodeBlockTypeAndLength(s, 1, s.numCommandBlockTypes);
+- s.treeCommandOffset = s.hGroup1[s.rings[7]];
++ s.commandTreeIdx = s.rings[7];
+ }
+
+ private static void decodeDistanceBlockSwitch(State s) {
+@@ -563,9 +727,9 @@ private static void readNextMetablockHeader(State s) {
+ return;
+ }
+ // TODO: Reset? Do we need this?
+- s.hGroup0 = new int[0];
+- s.hGroup1 = new int[0];
+- s.hGroup2 = new int[0];
++ s.literalTreeGroup = new int[0];
++ s.commandTreeGroup = new int[0];
++ s.distanceTreeGroup = new int[0];
+
+ BitReader.readMoreInput(s);
+ decodeMetaBlockLength(s);
+@@ -592,12 +756,57 @@ private static void readNextMetablockHeader(State s) {
+ }
+
+ private static int readMetablockPartition(State s, int treeType, int numBlockTypes) {
++ int offset = s.blockTrees[2 * treeType];
+ if (numBlockTypes <= 1) {
++ s.blockTrees[2 * treeType + 1] = offset;
++ s.blockTrees[2 * treeType + 2] = offset;
+ return 1 << 28;
+ }
+- readHuffmanCode(numBlockTypes + 2, s.blockTrees, treeType * HUFFMAN_TABLE_SIZE, s);
+- readHuffmanCode(NUM_BLOCK_LENGTH_CODES, s.blockTrees, (treeType + 3) * HUFFMAN_TABLE_SIZE, s);
+- return readBlockLength(s.blockTrees, (treeType + 3) * HUFFMAN_TABLE_SIZE, s);
++
++ int blockTypeAlphabetSize = numBlockTypes + 2;
++ offset += readHuffmanCode(
++ blockTypeAlphabetSize, blockTypeAlphabetSize, s.blockTrees, 2 * treeType, s);
++ s.blockTrees[2 * treeType + 1] = offset;
++
++ int blockLengthAlphabetSize = NUM_BLOCK_LENGTH_CODES;
++ offset += readHuffmanCode(
++ blockLengthAlphabetSize, blockLengthAlphabetSize, s.blockTrees, 2 * treeType + 1, s);
++ s.blockTrees[2 * treeType + 2] = offset;
++
++ return readBlockLength(s.blockTrees, 2 * treeType + 1, s);
++ }
++
++ private static void calculateDistanceLut(State s, int alphabetSizeLimit) {
++ byte[] distExtraBits = s.distExtraBits;
++ int[] distOffset = s.distOffset;
++ int npostfix = s.distancePostfixBits;
++ int ndirect = s.numDirectDistanceCodes;
++ int postfix = 1 << npostfix;
++ int bits = 1;
++ int half = 0;
++
++ /* Skip short codes. */
++ int i = NUM_DISTANCE_SHORT_CODES;
++
++ /* Fill direct codes. */
++ for (int j = 0; j < ndirect; ++j) {
++ distExtraBits[i] = 0;
++ distOffset[i] = j + 1;
++ ++i;
++ }
++
++ /* Fill regular distance codes. */
++ while (i < alphabetSizeLimit) {
++ int base = ndirect + ((((2 + half) << bits) - 4) << npostfix) + 1;
++ /* Always fill the complete group. */
++ for (int j = 0; j < postfix; ++j) {
++ distExtraBits[i] = (byte) bits;
++ distOffset[i] = base + j;
++ ++i;
++ }
++ bits = bits + half;
++ half = half ^ 1;
++ }
+ }
+
+ private static void readMetablockHuffmanCodesAndContextMaps(State s) {
+@@ -611,10 +820,8 @@ private static void readMetablockHuffmanCodesAndContextMaps(State s) {
+ BitReader.readMoreInput(s);
+ BitReader.fillBitWindow(s);
+ s.distancePostfixBits = BitReader.readFewBits(s, 2);
+- s.numDirectDistanceCodes =
+- NUM_DISTANCE_SHORT_CODES + (BitReader.readFewBits(s, 4) << s.distancePostfixBits);
++ s.numDirectDistanceCodes = BitReader.readFewBits(s, 4) << s.distancePostfixBits;
+ s.distancePostfixMask = (1 << s.distancePostfixBits) - 1;
+- int numDistanceCodes = s.numDirectDistanceCodes + (48 << s.distancePostfixBits);
+ // TODO: Reuse?
+ s.contextModes = new byte[s.numLiteralBlockTypes];
+ for (int i = 0; i < s.numLiteralBlockTypes;) {
+@@ -622,7 +829,7 @@ private static void readMetablockHuffmanCodesAndContextMaps(State s) {
+ int limit = Math.min(i + 96, s.numLiteralBlockTypes);
+ for (; i < limit; ++i) {
+ BitReader.fillBitWindow(s);
+- s.contextModes[i] = (byte) (BitReader.readFewBits(s, 2));
++ s.contextModes[i] = (byte) BitReader.readFewBits(s, 2);
+ }
+ BitReader.readMoreInput(s);
+ }
+@@ -644,18 +851,29 @@ private static void readMetablockHuffmanCodesAndContextMaps(State s) {
+ int numDistTrees = decodeContextMap(s.numDistanceBlockTypes << DISTANCE_CONTEXT_BITS,
+ s.distContextMap, s);
+
+- s.hGroup0 = decodeHuffmanTreeGroup(NUM_LITERAL_CODES, numLiteralTrees, s);
+- s.hGroup1 =
+- decodeHuffmanTreeGroup(NUM_INSERT_AND_COPY_CODES, s.numCommandBlockTypes, s);
+- s.hGroup2 = decodeHuffmanTreeGroup(numDistanceCodes, numDistTrees, s);
++ s.literalTreeGroup = decodeHuffmanTreeGroup(NUM_LITERAL_CODES, NUM_LITERAL_CODES,
++ numLiteralTrees, s);
++ s.commandTreeGroup = decodeHuffmanTreeGroup(NUM_COMMAND_CODES, NUM_COMMAND_CODES,
++ s.numCommandBlockTypes, s);
++ int distanceAlphabetSizeMax = calculateDistanceAlphabetSize(
++ s.distancePostfixBits, s.numDirectDistanceCodes, MAX_DISTANCE_BITS);
++ int distanceAlphabetSizeLimit = distanceAlphabetSizeMax;
++ if (s.isLargeWindow == 1) {
++ distanceAlphabetSizeMax = calculateDistanceAlphabetSize(
++ s.distancePostfixBits, s.numDirectDistanceCodes, MAX_LARGE_WINDOW_DISTANCE_BITS);
++ distanceAlphabetSizeLimit = calculateDistanceAlphabetLimit(
++ MAX_ALLOWED_DISTANCE, s.distancePostfixBits, s.numDirectDistanceCodes);
++ }
++ s.distanceTreeGroup = decodeHuffmanTreeGroup(distanceAlphabetSizeMax, distanceAlphabetSizeLimit,
++ numDistTrees, s);
++ calculateDistanceLut(s, distanceAlphabetSizeLimit);
+
+ s.contextMapSlice = 0;
+ s.distContextMapSlice = 0;
+- s.contextLookupOffset1 = (int) (s.contextModes[0]) << 9;
++ s.contextLookupOffset1 = s.contextModes[0] * 512;
+ s.contextLookupOffset2 = s.contextLookupOffset1 + 256;
+- s.literalTreeIndex = 0;
+- s.literalTree = s.hGroup0[0];
+- s.treeCommandOffset = s.hGroup1[0];
++ s.literalTreeIdx = 0;
++ s.commandTreeIdx = 0;
+
+ s.rings[4] = 1;
+ s.rings[5] = 0;
+@@ -706,13 +924,14 @@ private static int writeRingBuffer(State s) {
+ }
+ }
+
+- private static int[] decodeHuffmanTreeGroup(int alphabetSize, int n, State s) {
+- int[] group = new int[n + (n * HUFFMAN_TABLE_SIZE)];
++ private static int[] decodeHuffmanTreeGroup(int alphabetSizeMax, int alphabetSizeLimit,
++ int n, State s) {
++ int maxTableSize = MAX_HUFFMAN_TABLE_SIZE[(alphabetSizeLimit + 31) >> 5];
++ int[] group = new int[n + n * maxTableSize];
+ int next = n;
+- for (int i = 0; i < n; i++) {
++ for (int i = 0; i < n; ++i) {
+ group[i] = next;
+- Decode.readHuffmanCode(alphabetSize, group, next, s);
+- next += HUFFMAN_TABLE_SIZE;
++ next += readHuffmanCode(alphabetSizeMax, alphabetSizeLimit, group, i, s);
+ }
+ return group;
+ }
+@@ -738,7 +957,7 @@ static void decompress(State s) {
+ }
+ if (s.runningState == INITIALIZED) {
+ int windowBits = decodeWindowBits(s);
+- if (windowBits == 9) { /* Reserved case for future expansion. */
++ if (windowBits == -1) { /* Reserved case for future expansion. */
+ throw new BrotliRuntimeException("Invalid 'windowBits' code");
+ }
+ s.maxRingBufferSize = 1 << windowBits;
+@@ -780,23 +999,21 @@ static void decompress(State s) {
+ }
+ s.commandBlockLength--;
+ BitReader.fillBitWindow(s);
+- int cmdCode = readSymbol(s.hGroup1, s.treeCommandOffset, s);
+- int rangeIdx = cmdCode >>> 6;
+- s.distanceCode = 0;
+- if (rangeIdx >= 2) {
+- rangeIdx -= 2;
+- s.distanceCode = -1;
+- }
+- int insertCode = INSERT_RANGE_LUT[rangeIdx] + ((cmdCode >>> 3) & 7);
++ int cmdCode = readSymbol(s.commandTreeGroup, s.commandTreeIdx, s) << 2;
++ short insertAndCopyExtraBits = CMD_LOOKUP[cmdCode];
++ int insertLengthOffset = CMD_LOOKUP[cmdCode + 1];
++ int copyLengthOffset = CMD_LOOKUP[cmdCode + 2];
++ s.distanceCode = CMD_LOOKUP[cmdCode + 3];
+ BitReader.fillBitWindow(s);
+- int insertBits = INSERT_LENGTH_N_BITS[insertCode];
+- int insertExtra = BitReader.readBits(s, insertBits);
+- s.insertLength = INSERT_LENGTH_OFFSET[insertCode] + insertExtra;
+- int copyCode = COPY_RANGE_LUT[rangeIdx] + (cmdCode & 7);
++ {
++ int extraBits = insertAndCopyExtraBits & 0xFF;
++ s.insertLength = insertLengthOffset + BitReader.readBits(s, extraBits);
++ }
+ BitReader.fillBitWindow(s);
+- int copyBits = COPY_LENGTH_N_BITS[copyCode];
+- int copyExtra = BitReader.readBits(s, copyBits);
+- s.copyLength = COPY_LENGTH_OFFSET[copyCode] + copyExtra;
++ {
++ int extraBits = insertAndCopyExtraBits >> 8;
++ s.copyLength = copyLengthOffset + BitReader.readBits(s, extraBits);
++ }
+
+ s.j = 0;
+ s.runningState = INSERT_LOOP;
+@@ -811,8 +1028,7 @@ static void decompress(State s) {
+ }
+ s.literalBlockLength--;
+ BitReader.fillBitWindow(s);
+- ringBuffer[s.pos] =
+- (byte) readSymbol(s.hGroup0, s.literalTree, s);
++ ringBuffer[s.pos] = (byte) readSymbol(s.literalTreeGroup, s.literalTreeIdx, s);
+ s.pos++;
+ s.j++;
+ if (s.pos >= fence) {
+@@ -829,14 +1045,13 @@ static void decompress(State s) {
+ if (s.literalBlockLength == 0) {
+ decodeLiteralBlockSwitch(s);
+ }
+- int literalTreeIndex = s.contextMap[s.contextMapSlice
+- + (Context.LOOKUP[s.contextLookupOffset1 + prevByte1]
+- | Context.LOOKUP[s.contextLookupOffset2 + prevByte2])] & 0xFF;
++ int literalContext = Context.LOOKUP[s.contextLookupOffset1 + prevByte1]
++ | Context.LOOKUP[s.contextLookupOffset2 + prevByte2];
++ int literalTreeIdx = s.contextMap[s.contextMapSlice + literalContext] & 0xFF;
+ s.literalBlockLength--;
+ prevByte2 = prevByte1;
+ BitReader.fillBitWindow(s);
+- prevByte1 = readSymbol(
+- s.hGroup0, s.hGroup0[literalTreeIndex], s);
++ prevByte1 = readSymbol(s.literalTreeGroup, literalTreeIdx, s);
+ ringBuffer[s.pos] = (byte) prevByte1;
+ s.pos++;
+ s.j++;
+@@ -855,36 +1070,38 @@ static void decompress(State s) {
+ s.runningState = MAIN_LOOP;
+ continue;
+ }
+- if (s.distanceCode < 0) {
++ int distanceCode = s.distanceCode;
++ if (distanceCode < 0) {
++ // distanceCode in untouched; assigning it 0 won't affect distance ring buffer rolling.
++ s.distance = s.rings[s.distRbIdx];
++ } else {
+ BitReader.readMoreInput(s);
+ if (s.distanceBlockLength == 0) {
+ decodeDistanceBlockSwitch(s);
+ }
+ s.distanceBlockLength--;
+ BitReader.fillBitWindow(s);
+- s.distanceCode = readSymbol(s.hGroup2, s.hGroup2[
+- s.distContextMap[s.distContextMapSlice
+- + (s.copyLength > 4 ? 3 : s.copyLength - 2)] & 0xFF], s);
+- if (s.distanceCode >= s.numDirectDistanceCodes) {
+- s.distanceCode -= s.numDirectDistanceCodes;
+- int postfix = s.distanceCode & s.distancePostfixMask;
+- s.distanceCode >>>= s.distancePostfixBits;
+- int n = (s.distanceCode >>> 1) + 1;
+- int offset = ((2 + (s.distanceCode & 1)) << n) - 4;
+- BitReader.fillBitWindow(s);
+- int distanceExtra = BitReader.readBits(s, n);
+- s.distanceCode = s.numDirectDistanceCodes + postfix
+- + ((offset + distanceExtra) << s.distancePostfixBits);
++ int distTreeIdx = s.distContextMap[s.distContextMapSlice + distanceCode] & 0xFF;
++ distanceCode = readSymbol(s.distanceTreeGroup, distTreeIdx, s);
++ if (distanceCode < NUM_DISTANCE_SHORT_CODES) {
++ int index = (s.distRbIdx + DISTANCE_SHORT_CODE_INDEX_OFFSET[distanceCode]) & 0x3;
++ s.distance = s.rings[index] + DISTANCE_SHORT_CODE_VALUE_OFFSET[distanceCode];
++ if (s.distance < 0) {
++ throw new BrotliRuntimeException("Negative distance"); // COV_NF_LINE
++ }
++ } else {
++ int extraBits = s.distExtraBits[distanceCode];
++ int bits;
++ if (s.bitOffset + extraBits <= BitReader.BITNESS) {
++ bits = BitReader.readFewBits(s, extraBits);
++ } else {
++ BitReader.fillBitWindow(s);
++ bits = BitReader.readBits(s, extraBits);
++ }
++ s.distance = s.distOffset[distanceCode] + (bits << s.distancePostfixBits);
+ }
+ }
+
+- // Convert the distance code to the actual distance by possibly looking up past distances
+- // from the ringBuffer.
+- s.distance = translateShortCodes(s.distanceCode, s.rings, s.distRbIdx);
+- if (s.distance < 0) {
+- throw new BrotliRuntimeException("Negative distance"); // COV_NF_LINE
+- }
+-
+ if (s.maxDistance != s.maxBackwardDistance
+ && s.pos < s.maxBackwardDistance) {
+ s.maxDistance = s.pos;
+@@ -897,9 +1114,9 @@ static void decompress(State s) {
+ continue;
+ }
+
+- if (s.distanceCode > 0) {
+- s.rings[s.distRbIdx & 3] = s.distance;
+- s.distRbIdx++;
++ if (distanceCode > 0) {
++ s.distRbIdx = (s.distRbIdx + 1) & 0x3;
++ s.rings[s.distRbIdx] = s.distance;
+ }
+
+ if (s.copyLength > s.metaBlockLength) {
+@@ -916,7 +1133,10 @@ static void decompress(State s) {
+ int dstEnd = dst + copyLength;
+ if ((srcEnd < ringBufferMask) && (dstEnd < ringBufferMask)) {
+ if (copyLength < 12 || (srcEnd > dst && dstEnd > src)) {
+- for (int k = 0; k < copyLength; ++k) {
++ for (int k = 0; k < copyLength; k += 4) {
++ ringBuffer[dst++] = ringBuffer[src++];
++ ringBuffer[dst++] = ringBuffer[src++];
++ ringBuffer[dst++] = ringBuffer[src++];
+ ringBuffer[dst++] = ringBuffer[src++];
+ }
+ } else {
+@@ -945,6 +1165,10 @@ static void decompress(State s) {
+ continue;
+
+ case TRANSFORM:
++ // This check is done here to unburden the hot loop.
++ if (s.distance > MAX_ALLOWED_DISTANCE) {
++ throw new BrotliRuntimeException("Invalid backward reference"); // COV_NF_LINE
++ }
+ if (s.copyLength >= MIN_WORD_LENGTH
+ && s.copyLength <= MAX_WORD_LENGTH) {
+ int offset = DICTIONARY_OFFSETS_BY_LENGTH[s.copyLength];
+diff --git a/java/org/brotli/dec/EagerStreamTest.java b/java/org/brotli/dec/EagerStreamTest.java
+index 069ae349..8e079c04 100755
+--- a/java/org/brotli/dec/EagerStreamTest.java
++++ b/java/org/brotli/dec/EagerStreamTest.java
+@@ -375,7 +375,7 @@ public void testEagerStream() throws IOException {
+
+ ps = new ProxyStream(new ByteArrayInputStream(DATA));
+ reader = new BrotliInputStream(ps, 1);
+- reader.setEager(true);
++ reader.enableEagerOutput();
+ reader.read(buffer);
+ reader.close();
+ int eagerReadBytes = ps.readBytes;
+diff --git a/java/org/brotli/dec/Huffman.java b/java/org/brotli/dec/Huffman.java
+index 868701a6..38f7f293 100644
+--- a/java/org/brotli/dec/Huffman.java
++++ b/java/org/brotli/dec/Huffman.java
+@@ -58,9 +58,12 @@ private static int nextTableBitSize(int[] count, int len, int rootBits) {
+
+ /**
+ * Builds Huffman lookup table assuming code lengths are in symbol order.
++ *
++ * @return number of slots used by resulting Huffman table
+ */
+- static void buildHuffmanTable(int[] rootTable, int tableOffset, int rootBits, int[] codeLengths,
++ static int buildHuffmanTable(int[] tableGroup, int tableIdx, int rootBits, int[] codeLengths,
+ int codeLengthsSize) {
++ int tableOffset = tableGroup[tableIdx];
+ int key; // Reversed prefix code.
+ int[] sorted = new int[codeLengthsSize]; // Symbols sorted by code length.
+ // TODO: fill with zeroes?
+@@ -93,9 +96,9 @@ static void buildHuffmanTable(int[] rootTable, int tableOffset, int rootBits, in
+ // Special case code with only one value.
+ if (offset[MAX_LENGTH] == 1) {
+ for (key = 0; key < totalSize; key++) {
+- rootTable[tableOffset + key] = sorted[0];
++ tableGroup[tableOffset + key] = sorted[0];
+ }
+- return;
++ return totalSize;
+ }
+
+ // Fill in root table.
+@@ -103,7 +106,8 @@ static void buildHuffmanTable(int[] rootTable, int tableOffset, int rootBits, in
+ symbol = 0;
+ for (int len = 1, step = 2; len <= rootBits; len++, step <<= 1) {
+ for (; count[len] > 0; count[len]--) {
+- replicateValue(rootTable, tableOffset + key, step, tableSize, len << 16 | sorted[symbol++]);
++ replicateValue(tableGroup, tableOffset + key, step, tableSize,
++ len << 16 | sorted[symbol++]);
+ key = getNextKey(key, len);
+ }
+ }
+@@ -120,13 +124,14 @@ static void buildHuffmanTable(int[] rootTable, int tableOffset, int rootBits, in
+ tableSize = 1 << tableBits;
+ totalSize += tableSize;
+ low = key & mask;
+- rootTable[tableOffset + low] =
++ tableGroup[tableOffset + low] =
+ (tableBits + rootBits) << 16 | (currentOffset - tableOffset - low);
+ }
+- replicateValue(rootTable, currentOffset + (key >> rootBits), step, tableSize,
++ replicateValue(tableGroup, currentOffset + (key >> rootBits), step, tableSize,
+ (len - rootBits) << 16 | sorted[symbol++]);
+ key = getNextKey(key, len);
+ }
+ }
++ return totalSize;
+ }
+ }
+diff --git a/java/org/brotli/dec/State.java b/java/org/brotli/dec/State.java
+index 2dc46d5e..54a5a2d9 100644
+--- a/java/org/brotli/dec/State.java
++++ b/java/org/brotli/dec/State.java
+@@ -13,6 +13,7 @@
+ byte[] contextModes;
+ byte[] contextMap;
+ byte[] distContextMap;
++ byte[] distExtraBits;
+ byte[] output;
+ byte[] byteBuffer; // BitReader
+
+@@ -21,9 +22,10 @@
+ int[] intBuffer; // BitReader
+ int[] rings;
+ int[] blockTrees;
+- int[] hGroup0;
+- int[] hGroup1;
+- int[] hGroup2;
++ int[] literalTreeGroup;
++ int[] commandTreeGroup;
++ int[] distanceTreeGroup;
++ int[] distOffset;
+
+ long accumulator64; // BitReader: pre-fetched bits.
+
+@@ -48,15 +50,14 @@
+ int maxDistance;
+ int distRbIdx;
+ int trivialLiteralContext;
+- int literalTreeIndex;
+- int literalTree;
++ int literalTreeIdx;
++ int commandTreeIdx;
+ int j;
+ int insertLength;
+ int contextMapSlice;
+ int distContextMapSlice;
+ int contextLookupOffset1;
+ int contextLookupOffset2;
+- int treeCommandOffset;
+ int distanceCode;
+ int numDirectDistanceCodes;
+ int distancePostfixMask;
+@@ -73,6 +74,7 @@
+ int ringBufferBytesWritten;
+ int ringBufferBytesReady;
+ int isEager;
++ int isLargeWindow;
+
+ InputStream input; // BitReader
+
+diff --git a/java/org/brotli/dec/SynthTest.java b/java/org/brotli/dec/SynthTest.java
+index de91c377..e269e6b0 100644
+--- a/java/org/brotli/dec/SynthTest.java
++++ b/java/org/brotli/dec/SynthTest.java
+@@ -12,6 +12,7 @@
+ import java.io.ByteArrayInputStream;
+ import java.io.ByteArrayOutputStream;
+ import java.io.IOException;
++import java.util.Arrays;
+ import org.junit.Test;
+ import org.junit.runner.RunWith;
+ import org.junit.runners.JUnit4;
+@@ -624,7 +625,7 @@ public void testBlockCountMessage() {
+ * // one ins/copy and dist block type
+ * vlq_blocktypes: 1
+ * vlq_blocktypes: 1
+- * ndirect: 0 0
++ * ndirect: 0, 0
+ * // two MSB6 literal context modes
+ * bits: "00", "00"
+ * // two literal prefix codes
+@@ -680,7 +681,7 @@ public void testBlockSwitchMessage() {
+ * // one ins/copy and dist block type
+ * vlq_blocktypes: 1
+ * vlq_blocktypes: 1
+- * ndirect: 0 0
++ * ndirect: 0, 0
+ * // two MSB6 literal context modes
+ * bits: "00", "00"
+ * // two literal prefix codes
+@@ -983,6 +984,46 @@ public void testCustomHuffmanCode() {
+ );
+ }
+
++ @Test
++ public void testDistanceLut() {
++ byte[] compressed = {
++ (byte) 0x8b, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
++ (byte) 0xe3, (byte) 0xb4, (byte) 0x0d, (byte) 0x00, (byte) 0x00, (byte) 0x07, (byte) 0x5b,
++ (byte) 0x26, (byte) 0x31, (byte) 0x40, (byte) 0x02, (byte) 0x00, (byte) 0xe0, (byte) 0x4e,
++ (byte) 0x1b, (byte) 0x99, (byte) 0x86, (byte) 0x46, (byte) 0xc6, (byte) 0x22, (byte) 0x14,
++ (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x1c, (byte) 0xa7,
++ (byte) 0x6d, (byte) 0x00, (byte) 0x00, (byte) 0x38, (byte) 0xd8, (byte) 0x32, (byte) 0x89,
++ (byte) 0x01, (byte) 0x12, (byte) 0x21, (byte) 0x91, (byte) 0x69, (byte) 0x62, (byte) 0x6a,
++ (byte) 0x36
++ };
++ checkSynth(
++ /*
++ * main_header
++ * metablock_header_easy: 6, 0 // implicit ndirect: 0, 0
++ * command_easy: 3, "abc", 3 // Insert "abc", copy "abc"
++ * metablock_header_begin: 0, 0, 6, 0
++ * vlq_blocktypes: 1 // num litetal block types
++ * vlq_blocktypes: 1 // num command block types
++ * vlq_blocktypes: 1 // num distance block types
++ * ndirect: 3, 0
++ * bits: "00" // literal context modes
++ * vlq_blocktypes: 1 // num literal Huffman trees
++ * // command has no context -> num trees == num block types
++ * vlq_blocktypes: 1 // num distance Huffman trees
++ * huffman_fixed: 256
++ * huffman_fixed: 704
++ * huffman_simple: 0,1,67, 18
++ * command_inscopy_easy: 3, 3 // Insert 3, copy 3
++ * command_literals_easy: "def"
++ * // 0-bit Huffman code : dcode = 18 -> third direct distance
++ * metablock_lastempty // make sure that no extra distance bits are read
++ */
++ compressed,
++ true,
++ "abcabcdefdef"
++ );
++ }
++
+ @Test
+ public void testEmpty() {
+ byte[] compressed = {
+@@ -1264,7 +1305,7 @@ public void testInvalidTooLargeContextMap() {
+ * // one ins/copy and dist block type
+ * vlq_blocktypes: 1
+ * vlq_blocktypes: 1
+- * ndirect: 0 0
++ * ndirect: 0, 0
+ * // two MSB6 literal context modes
+ * bits: "00", "00"
+ * // two literal prefix codes
+@@ -2706,6 +2747,87 @@ public void testSimplePrefixPlusExtraData() {
+ }
+ */
+
++ @Test
++ public void testStressReadDistanceExtraBits() {
++ byte[] compressed = {
++ (byte) 0x4f, (byte) 0xfe, (byte) 0xff, (byte) 0x3f, (byte) 0x00, (byte) 0x00, (byte) 0x00,
++ (byte) 0x80, (byte) 0xe3, (byte) 0xb4, (byte) 0x0d, (byte) 0x00, (byte) 0x00, (byte) 0x07,
++ (byte) 0x5b, (byte) 0x26, (byte) 0x31, (byte) 0x40, (byte) 0x02, (byte) 0x00, (byte) 0xe0,
++ (byte) 0x4e, (byte) 0x9b, (byte) 0xf6, (byte) 0x69, (byte) 0xef, (byte) 0xff, (byte) 0x0c,
++ (byte) 0x8d, (byte) 0x8c, (byte) 0x05, (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00,
++ (byte) 0x00, (byte) 0x00, (byte) 0x38, (byte) 0x4e, (byte) 0xdb, (byte) 0x00, (byte) 0x00,
++ (byte) 0x70, (byte) 0xb0, (byte) 0x65, (byte) 0x12, (byte) 0x03, (byte) 0x24, (byte) 0xa8,
++ (byte) 0xaa, (byte) 0xef, (byte) 0xab, (byte) 0xaa, (byte) 0x7f, (byte) 0x24, (byte) 0x16,
++ (byte) 0x35, (byte) 0x8f, (byte) 0xac, (byte) 0x9e, (byte) 0x3d, (byte) 0xf7, (byte) 0xf3,
++ (byte) 0xe3, (byte) 0x0a, (byte) 0xfc, (byte) 0xff, (byte) 0x03, (byte) 0x00, (byte) 0x00,
++ (byte) 0x78, (byte) 0x01, (byte) 0x08, (byte) 0x30, (byte) 0x31, (byte) 0x32, (byte) 0x33,
++ (byte) 0x34, (byte) 0x35, (byte) 0x36, (byte) 0x37, (byte) 0x38, (byte) 0x39, (byte) 0x41,
++ (byte) 0x42, (byte) 0x43, (byte) 0x44, (byte) 0x45, (byte) 0x46, (byte) 0x30, (byte) 0x31,
++ (byte) 0x32, (byte) 0x33, (byte) 0x34, (byte) 0x35, (byte) 0x36, (byte) 0x37, (byte) 0x38,
++ (byte) 0x39, (byte) 0x41, (byte) 0x42, (byte) 0x43, (byte) 0x44, (byte) 0x45, (byte) 0x46,
++ (byte) 0x30, (byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x34, (byte) 0x35, (byte) 0x36,
++ (byte) 0x37, (byte) 0x38, (byte) 0x39, (byte) 0x41, (byte) 0x42, (byte) 0x43, (byte) 0x44,
++ (byte) 0x45, (byte) 0x46, (byte) 0x03
++ };
++ /* This line is added manually. */
++ char[] stub = new char[8388602]; Arrays.fill(stub, 'c'); String hex = "0123456789ABCDEF";
++ checkSynth(
++ /*
++ * main_header: 24
++ * metablock_header_easy: 8388605, 0 // 2^23 - 3 = shortest 22-bit distance
++ * command_easy: 8388602, "abc", 1
++ * metablock_header_begin: 0, 0, 3, 0
++ * vlq_blocktypes: 1 // num litetal block types
++ * vlq_blocktypes: 1 // num command block types
++ * vlq_blocktypes: 1 // num distance block types
++ * ndirect: 0, 0
++ * bits: "00" // literal context modes
++ * vlq_blocktypes: 1 // num literal Huffman trees
++ * // command has no context -> num trees == num block types
++ * vlq_blocktypes: 1 // num distance Huffman trees
++ * huffman_fixed: 256
++ * huffman_fixed: 704
++ * // Begin of distance Huffman tree. First 15 codes have lengths 1 to 15.
++ * // Symbol that corresponds to first half of 22-bit distance range is also
++ * // 15. All other symbols are 0.
++ * hskip: 0
++ * clcl_ordered: 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4, 5,5,5,5
++ * set_prefix_cl_rle: "0000", "0001", "0010", "0011", \
++ * "0100", "0101", "0110", "0111", \
++ * "1000", "1001", "1010", "1011", \
++ * "1100", "1101", \
++ * "11100", "11101", "11110", "11111"
++ * cl_rle: 1
++ * cl_rle: 2
++ * cl_rle: 3
++ * cl_rle: 4
++ * cl_rle: 5
++ * cl_rle: 6
++ * cl_rle: 7
++ * cl_rle: 8
++ * cl_rle: 9
++ * cl_rle: 10
++ * cl_rle: 11
++ * cl_rle: 12
++ * cl_rle: 13
++ * cl_rle: 14
++ * cl_rle: 15
++ * cl_rle_rep_0: 43
++ * cl_rle: 15 // literal number 97, that is, the letter 'a'
++ * // end of literal Huffman tree
++ * command_inscopy_easy: 0, 3 // Insert 0, copy 3
++ * // 15 bits of distance code plus 22 extra bits
++ * command_dist_bits: "111111111111111", "0000000000000000000000"
++ * metablock_uncompressed: "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"
++ * metablock_lastempty
++ */
++ compressed,
++ true,
++ /* This line is modified manually. */
++ "abc" + new String(stub) + "abc" + hex + hex + hex
++ );
++ }
++
+ @Test
+ public void testTooManySymbolsRepeated() {
+ byte[] compressed = {
+@@ -2785,6 +2907,34 @@ public void testTransformedDictWordTooLong() {
+ );
+ }
+
++ @Test
++ public void testZeroCostLiterals() {
++ byte[] compressed = {
++ (byte) 0x9b, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x20, (byte) 0x54,
++ (byte) 0x00, (byte) 0x00, (byte) 0x38, (byte) 0xd8, (byte) 0x32, (byte) 0x89, (byte) 0x01,
++ (byte) 0x12, (byte) 0x00, (byte) 0x00, (byte) 0x77, (byte) 0xda, (byte) 0xcc, (byte) 0xe1,
++ (byte) 0x7b, (byte) 0xfa, (byte) 0x0f
++ };
++ /* This lines is added manually. */
++ char[] expected = new char[16777216]; Arrays.fill(expected, '*');
++ checkSynth(
++ /*
++ * main_header
++ * metablock_header_begin: 1, 0, 16777216, 0
++ * metablock_header_trivial_context
++ * huffman_simple: 0,1,256, 42 // Single symbol alphabet
++ * huffman_fixed: 704
++ * huffman_fixed: 64
++ * command_inscopy_easy: 16777216, 0
++ * // 16777216 times 0 bits
++ */
++ compressed,
++ true,
++ /* This line is modified manually. */
++ new String(expected)
++ );
++ }
++
+ /* GENERATED CODE END */
+
+ }
+diff --git a/java/org/brotli/dec/Utils.java b/java/org/brotli/dec/Utils.java
+index 1583c758..2d04aecd 100644
+--- a/java/org/brotli/dec/Utils.java
++++ b/java/org/brotli/dec/Utils.java
+@@ -88,4 +88,15 @@ static void closeInput(InputStream src) throws IOException {
+ static void flipBuffer(Buffer buffer) {
+ buffer.flip();
+ }
++
++ static int isDebugMode() {
++ boolean assertsEnabled = Boolean.parseBoolean(System.getProperty("BROTLI_ENABLE_ASSERTS"));
++ return assertsEnabled ? 1 : 0;
++ }
++
++ // See BitReader.LOG_BITNESS
++ static int getLogBintness() {
++ boolean isLongExpensive = Boolean.parseBoolean(System.getProperty("BROTLI_32_BIT_CPU"));
++ return isLongExpensive ? 5 : 6;
++ }
+ }
+diff --git a/java/org/brotli/wrapper/common/BUILD b/java/org/brotli/wrapper/common/BUILD
+index 48b02f3f..4f7ed847 100644
+--- a/java/org/brotli/wrapper/common/BUILD
++++ b/java/org/brotli/wrapper/common/BUILD
+@@ -35,7 +35,6 @@ java_library(
+
+ java_test(
+ name = "SetZeroDictionaryTest",
+- test_class = "org.brotli.wrapper.common.SetZeroDictionaryTest",
+ size = "small",
+ data = [
+ ":brotli_jni_no_dictionary_data", # Bazel JNI workaround
+@@ -43,12 +42,12 @@ java_test(
+ jvm_flags = [
+ "-DBROTLI_JNI_LIBRARY=$(location :brotli_jni_no_dictionary_data)",
+ ],
++ test_class = "org.brotli.wrapper.common.SetZeroDictionaryTest",
+ runtime_deps = [":test_lib"],
+ )
+
+ java_test(
+ name = "SetRfcDictionaryTest",
+- test_class = "org.brotli.wrapper.common.SetRfcDictionaryTest",
+ size = "small",
+ data = [
+ ":brotli_jni_no_dictionary_data", # Bazel JNI workaround
+@@ -56,5 +55,6 @@ java_test(
+ jvm_flags = [
+ "-DBROTLI_JNI_LIBRARY=$(location :brotli_jni_no_dictionary_data)",
+ ],
++ test_class = "org.brotli.wrapper.common.SetRfcDictionaryTest",
+ runtime_deps = [":test_lib"],
+ )
+diff --git a/java/org/brotli/wrapper/dec/BUILD b/java/org/brotli/wrapper/dec/BUILD
+index fcf0dbfd..754541ad 100644
+--- a/java/org/brotli/wrapper/dec/BUILD
++++ b/java/org/brotli/wrapper/dec/BUILD
+@@ -39,7 +39,6 @@ filegroup(
+
+ java_test(
+ name = "BrotliDecoderChannelTest",
+- test_class = "org.brotli.wrapper.dec.BrotliDecoderChannelTest",
+ size = "large",
+ data = [
+ ":brotli_jni", # Bazel JNI workaround
+@@ -49,12 +48,12 @@ java_test(
+ "-DBROTLI_JNI_LIBRARY=$(location :brotli_jni)",
+ "-DTEST_BUNDLE=$(location :test_bundle)",
+ ],
++ test_class = "org.brotli.wrapper.dec.BrotliDecoderChannelTest",
+ runtime_deps = [":test_lib"],
+ )
+
+ java_test(
+ name = "BrotliInputStreamTest",
+- test_class = "org.brotli.wrapper.dec.BrotliInputStreamTest",
+ size = "large",
+ data = [
+ ":brotli_jni", # Bazel JNI workaround
+@@ -64,12 +63,12 @@ java_test(
+ "-DBROTLI_JNI_LIBRARY=$(location :brotli_jni)",
+ "-DTEST_BUNDLE=$(location :test_bundle)",
+ ],
++ test_class = "org.brotli.wrapper.dec.BrotliInputStreamTest",
+ runtime_deps = [":test_lib"],
+ )
+
+ java_test(
+ name = "DecoderTest",
+- test_class = "org.brotli.wrapper.dec.DecoderTest",
+ size = "large",
+ data = [
+ ":brotli_jni", # Bazel JNI workaround
+@@ -79,5 +78,6 @@ java_test(
+ "-DBROTLI_JNI_LIBRARY=$(location :brotli_jni)",
+ "-DTEST_BUNDLE=$(location :test_bundle)",
+ ],
++ test_class = "org.brotli.wrapper.dec.DecoderTest",
+ runtime_deps = [":test_lib"],
+ )
+diff --git a/java/org/brotli/wrapper/dec/BrotliInputStream.java b/java/org/brotli/wrapper/dec/BrotliInputStream.java
+index 26f7a821..6e2e6e5f 100644
+--- a/java/org/brotli/wrapper/dec/BrotliInputStream.java
++++ b/java/org/brotli/wrapper/dec/BrotliInputStream.java
+@@ -34,8 +34,8 @@ public BrotliInputStream(InputStream source) throws IOException {
+ this(source, DEFAULT_BUFFER_SIZE);
+ }
+
+- public void setEager(boolean eager) {
+- decoder.setEager(eager);
++ public void enableEagerOutput() {
++ decoder.enableEagerOutput();
+ }
+
+ @Override
+diff --git a/java/org/brotli/wrapper/dec/Decoder.java b/java/org/brotli/wrapper/dec/Decoder.java
+index ae4d8178..26183aba 100644
+--- a/java/org/brotli/wrapper/dec/Decoder.java
++++ b/java/org/brotli/wrapper/dec/Decoder.java
+@@ -50,8 +50,8 @@ private void fail(String message) throws IOException {
+ throw new IOException(message);
+ }
+
+- public void setEager(boolean eager) {
+- this.eager = eager;
++ public void enableEagerOutput() {
++ this.eager = true;
+ }
+
+ /**
+diff --git a/java/org/brotli/wrapper/dec/DecoderJNI.java b/java/org/brotli/wrapper/dec/DecoderJNI.java
+index 320705c5..2319b1ea 100644
+--- a/java/org/brotli/wrapper/dec/DecoderJNI.java
++++ b/java/org/brotli/wrapper/dec/DecoderJNI.java
+@@ -30,6 +30,7 @@
+ private final long[] context = new long[3];
+ private final ByteBuffer inputBuffer;
+ private Status lastStatus = Status.NEEDS_MORE_INPUT;
++ private boolean fresh = true;
+
+ public Wrapper(int inputBufferSize) throws IOException {
+ this.context[1] = inputBufferSize;
+@@ -52,6 +53,7 @@ public void push(int length) {
+ if (lastStatus == Status.OK && length != 0) {
+ throw new IllegalStateException("pushing input to decoder in OK state");
+ }
++ fresh = false;
+ nativePush(context, length);
+ parseStatus();
+ }
+@@ -90,6 +92,7 @@ public ByteBuffer pull() {
+ if (lastStatus != Status.NEEDS_MORE_OUTPUT && !hasOutput()) {
+ throw new IllegalStateException("pulling output from decoder in " + lastStatus + " state");
+ }
++ fresh = false;
+ ByteBuffer result = nativePull(context);
+ parseStatus();
+ return result;
+diff --git a/java/org/brotli/wrapper/dec/EagerStreamTest.java b/java/org/brotli/wrapper/dec/EagerStreamTest.java
+index 91660923..919f6e3b 100755
+--- a/java/org/brotli/wrapper/dec/EagerStreamTest.java
++++ b/java/org/brotli/wrapper/dec/EagerStreamTest.java
+@@ -56,7 +56,7 @@ public int read(byte[] b, int off, int len) throws IOException {
+ }
+ };
+ BrotliInputStream reader = new BrotliInputStream(source);
+- reader.setEager(true);
++ reader.enableEagerOutput();
+ int count = 0;
+ while (true) {
+ log.append("^").append(count);
+diff --git a/java/org/brotli/wrapper/enc/BUILD b/java/org/brotli/wrapper/enc/BUILD
+index 42ad23ed..b3d10b90 100644
+--- a/java/org/brotli/wrapper/enc/BUILD
++++ b/java/org/brotli/wrapper/enc/BUILD
+@@ -40,7 +40,6 @@ filegroup(
+
+ java_test(
+ name = "BrotliEncoderChannelTest",
+- test_class = "org.brotli.wrapper.enc.BrotliEncoderChannelTest",
+ size = "large",
+ data = [
+ ":brotli_jni", # Bazel JNI workaround
+@@ -51,12 +50,12 @@ java_test(
+ "-DTEST_BUNDLE=$(location :test_bundle)",
+ ],
+ shard_count = 15,
++ test_class = "org.brotli.wrapper.enc.BrotliEncoderChannelTest",
+ runtime_deps = [":test_lib"],
+ )
+
+ java_test(
+ name = "BrotliOutputStreamTest",
+- test_class = "org.brotli.wrapper.enc.BrotliOutputStreamTest",
+ size = "large",
+ data = [
+ ":brotli_jni", # Bazel JNI workaround
+@@ -67,12 +66,12 @@ java_test(
+ "-DTEST_BUNDLE=$(location :test_bundle)",
+ ],
+ shard_count = 15,
++ test_class = "org.brotli.wrapper.enc.BrotliOutputStreamTest",
+ runtime_deps = [":test_lib"],
+ )
+
+ java_test(
+ name = "EncoderTest",
+- test_class = "org.brotli.wrapper.enc.EncoderTest",
+ size = "large",
+ data = [
+ ":brotli_jni", # Bazel JNI workaround
+@@ -83,5 +82,6 @@ java_test(
+ "-DTEST_BUNDLE=$(location :test_bundle)",
+ ],
+ shard_count = 15,
++ test_class = "org.brotli.wrapper.enc.EncoderTest",
+ runtime_deps = [":test_lib"],
+ )
+diff --git a/java/org/brotli/wrapper/enc/EncoderJNI.java b/java/org/brotli/wrapper/enc/EncoderJNI.java
+index 6627f5a9..50136295 100644
+--- a/java/org/brotli/wrapper/enc/EncoderJNI.java
++++ b/java/org/brotli/wrapper/enc/EncoderJNI.java
+@@ -27,9 +27,13 @@
+ static class Wrapper {
+ protected final long[] context = new long[5];
+ private final ByteBuffer inputBuffer;
++ private boolean fresh = true;
+
+ Wrapper(int inputBufferSize, int quality, int lgwin)
+ throws IOException {
++ if (inputBufferSize <= 0) {
++ throw new IOException("buffer size must be positive");
++ }
+ this.context[1] = inputBufferSize;
+ this.context[2] = quality;
+ this.context[3] = lgwin;
+@@ -56,6 +60,7 @@ void push(Operation op, int length) {
+ throw new IllegalStateException("pushing input to encoder over previous input");
+ }
+ context[1] = op.ordinal();
++ fresh = false;
+ nativePush(context, length);
+ }
+
+@@ -86,6 +91,7 @@ ByteBuffer pull() {
+ if (!isSuccess() || !hasMoreOutput()) {
+ throw new IllegalStateException("pulling while data is not ready");
+ }
++ fresh = false;
+ return nativePull(context);
+ }
+
+diff --git a/js/decode.js b/js/decode.js
+old mode 100644
+new mode 100755
+index 40a4df74..7896a502
+--- a/js/decode.js
++++ b/js/decode.js
+@@ -22,25 +22,98 @@ function BrotliDecodeClosure() {
+ /** @type {!number} */
+ this.offset = 0;
+ }
++ var MAX_HUFFMAN_TABLE_SIZE = Int32Array.from([256, 402, 436, 468, 500, 534, 566, 598, 630, 662, 694, 726, 758, 790, 822, 854, 886, 920, 952, 984, 1016, 1048, 1080]);
+ var CODE_LENGTH_CODE_ORDER = Int32Array.from([1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
+- var DISTANCE_SHORT_CODE_INDEX_OFFSET = Int32Array.from([3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2]);
++ var DISTANCE_SHORT_CODE_INDEX_OFFSET = Int32Array.from([0, 3, 2, 1, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3]);
+ var DISTANCE_SHORT_CODE_VALUE_OFFSET = Int32Array.from([0, 0, 0, 0, -1, 1, -2, 2, -3, 3, -1, 1, -2, 2, -3, 3]);
+ var FIXED_TABLE = Int32Array.from([0x020000, 0x020004, 0x020003, 0x030002, 0x020000, 0x020004, 0x020003, 0x040001, 0x020000, 0x020004, 0x020003, 0x030002, 0x020000, 0x020004, 0x020003, 0x040005]);
+ var DICTIONARY_OFFSETS_BY_LENGTH = Int32Array.from([0, 0, 0, 0, 0, 4096, 9216, 21504, 35840, 44032, 53248, 63488, 74752, 87040, 93696, 100864, 104704, 106752, 108928, 113536, 115968, 118528, 119872, 121280, 122016]);
+ var DICTIONARY_SIZE_BITS_BY_LENGTH = Int32Array.from([0, 0, 0, 0, 10, 10, 11, 11, 10, 10, 10, 10, 10, 9, 9, 8, 7, 7, 8, 7, 7, 6, 6, 5, 5]);
+ var BLOCK_LENGTH_OFFSET = Int32Array.from([1, 5, 9, 13, 17, 25, 33, 41, 49, 65, 81, 97, 113, 145, 177, 209, 241, 305, 369, 497, 753, 1265, 2289, 4337, 8433, 16625]);
+ var BLOCK_LENGTH_N_BITS = Int32Array.from([2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 24]);
+- var INSERT_LENGTH_OFFSET = Int32Array.from([0, 1, 2, 3, 4, 5, 6, 8, 10, 14, 18, 26, 34, 50, 66, 98, 130, 194, 322, 578, 1090, 2114, 6210, 22594]);
+- var INSERT_LENGTH_N_BITS = Int32Array.from([0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 12, 14, 24]);
+- var COPY_LENGTH_OFFSET = Int32Array.from([2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 18, 22, 30, 38, 54, 70, 102, 134, 198, 326, 582, 1094, 2118]);
+- var COPY_LENGTH_N_BITS = Int32Array.from([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 24]);
+- var INSERT_RANGE_LUT = Int32Array.from([0, 0, 8, 8, 0, 16, 8, 16, 16]);
+- var COPY_RANGE_LUT = Int32Array.from([0, 8, 0, 8, 16, 0, 16, 8, 16]);
++ var INSERT_LENGTH_N_BITS = Int16Array.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0C, 0x0E, 0x18]);
++ var COPY_LENGTH_N_BITS = Int16Array.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x18]);
++ var CMD_LOOKUP = new Int16Array(2816);
++ {
++ unpackCommandLookupTable(CMD_LOOKUP);
++ }
++ /**
++ * @param {number} i
++ * @return {number}
++ */
++ function log2floor(i) {
++ var /** number */ result = -1;
++ var /** number */ step = 16;
++ while (step > 0) {
++ if ((i >>> step) != 0) {
++ result += step;
++ i = i >>> step;
++ }
++ step = step >> 1;
++ }
++ return result + i;
++ }
++ /**
++ * @param {number} npostfix
++ * @param {number} ndirect
++ * @param {number} maxndistbits
++ * @return {number}
++ */
++ function calculateDistanceAlphabetSize(npostfix, ndirect, maxndistbits) {
++ return 16 + ndirect + 2 * (maxndistbits << npostfix);
++ }
++ /**
++ * @param {number} maxDistance
++ * @param {number} npostfix
++ * @param {number} ndirect
++ * @return {number}
++ */
++ function calculateDistanceAlphabetLimit(maxDistance, npostfix, ndirect) {
++ if (maxDistance < ndirect + (2 << npostfix)) {
++ throw "maxDistance is too small";
++ }
++ var /** number */ offset = ((maxDistance - ndirect) >> npostfix) + 4;
++ var /** number */ ndistbits = log2floor(offset) - 1;
++ var /** number */ group = ((ndistbits - 1) << 1) | ((offset >> ndistbits) & 1);
++ return ((group - 1) << npostfix) + (1 << npostfix) + ndirect + 16;
++ }
++ /**
++ * @param {!Int16Array} cmdLookup
++ * @return {void}
++ */
++ function unpackCommandLookupTable(cmdLookup) {
++ var /** !Int16Array */ insertLengthOffsets = new Int16Array(24);
++ var /** !Int16Array */ copyLengthOffsets = new Int16Array(24);
++ copyLengthOffsets[0] = 2;
++ for (var /** number */ i = 0; i < 23; ++i) {
++ insertLengthOffsets[i + 1] = (insertLengthOffsets[i] + (1 << INSERT_LENGTH_N_BITS[i]));
++ copyLengthOffsets[i + 1] = (copyLengthOffsets[i] + (1 << COPY_LENGTH_N_BITS[i]));
++ }
++ for (var /** number */ cmdCode = 0; cmdCode < 704; ++cmdCode) {
++ var /** number */ rangeIdx = cmdCode >>> 6;
++ var /** number */ distanceContextOffset = -4;
++ if (rangeIdx >= 2) {
++ rangeIdx -= 2;
++ distanceContextOffset = 0;
++ }
++ var /** number */ insertCode = (((0x29850 >>> (rangeIdx * 2)) & 0x3) << 3) | ((cmdCode >>> 3) & 7);
++ var /** number */ copyCode = (((0x26244 >>> (rangeIdx * 2)) & 0x3) << 3) | (cmdCode & 7);
++ var /** number */ copyLengthOffset = copyLengthOffsets[copyCode];
++ var /** number */ distanceContext = distanceContextOffset + (copyLengthOffset > 4 ? 3 : copyLengthOffset - 2);
++ var /** number */ index = cmdCode * 4;
++ cmdLookup[index + 0] = (INSERT_LENGTH_N_BITS[insertCode] | (COPY_LENGTH_N_BITS[copyCode] << 8));
++ cmdLookup[index + 1] = insertLengthOffsets[insertCode];
++ cmdLookup[index + 2] = copyLengthOffsets[copyCode];
++ cmdLookup[index + 3] = distanceContext;
++ }
++ }
+ /**
+ * @param {!State} s
+- * @return {!number}
++ * @return {number}
+ */
+ function decodeWindowBits(s) {
++ var /** number */ largeWindowEnabled = s.isLargeWindow;
++ s.isLargeWindow = 0;
+ if (s.bitOffset >= 16) {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+@@ -48,16 +121,51 @@ function BrotliDecodeClosure() {
+ if (readFewBits(s, 1) == 0) {
+ return 16;
+ }
+- var /** !number */ n = readFewBits(s, 3);
++ var /** number */ n = readFewBits(s, 3);
+ if (n != 0) {
+ return 17 + n;
+ }
+ n = readFewBits(s, 3);
+ if (n != 0) {
+- return 8 + n;
++ if (n == 1) {
++ if (largeWindowEnabled == 0) {
++ return -1;
++ }
++ s.isLargeWindow = 1;
++ if (readFewBits(s, 1) == 1) {
++ return -1;
++ }
++ n = readFewBits(s, 6);
++ if (n < 10 || n > 30) {
++ return -1;
++ }
++ return n;
++ } else {
++ return 8 + n;
++ }
+ }
+ return 17;
+ }
++ /**
++ * @param {!State} s
++ * @return {void}
++ */
++ function enableEagerOutput(s) {
++ if (s.runningState != 1) {
++ throw "State MUST be freshly initialized";
++ }
++ s.isEager = 1;
++ }
++ /**
++ * @param {!State} s
++ * @return {void}
++ */
++ function enableLargeWindow(s) {
++ if (s.runningState != 1) {
++ throw "State MUST be freshly initialized";
++ }
++ s.isLargeWindow = 1;
++ }
+ /**
+ * @param {!State} s
+ * @param {!InputStream} input
+@@ -67,15 +175,14 @@ function BrotliDecodeClosure() {
+ if (s.runningState != 0) {
+ throw "State MUST be uninitialized";
+ }
+- s.blockTrees = new Int32Array(6480);
++ s.blockTrees = new Int32Array(3091);
++ s.blockTrees[0] = 7;
++ s.distRbIdx = 3;
++ var /** number */ maxDistanceAlphabetLimit = calculateDistanceAlphabetLimit(0x7FFFFFFC, 3, 15 << 3);
++ s.distExtraBits = new Int8Array(maxDistanceAlphabetLimit);
++ s.distOffset = new Int32Array(maxDistanceAlphabetLimit);
+ s.input = input;
+ initBitReader(s);
+- var /** !number */ windowBits = decodeWindowBits(s);
+- if (windowBits == 9) {
+- throw "Invalid 'windowBits' code";
+- }
+- s.maxRingBufferSize = 1 << windowBits;
+- s.maxBackwardDistance = s.maxRingBufferSize - 16;
+ s.runningState = 1;
+ }
+ /**
+@@ -86,10 +193,10 @@ function BrotliDecodeClosure() {
+ if (s.runningState == 0) {
+ throw "State MUST be initialized";
+ }
+- if (s.runningState == 10) {
++ if (s.runningState == 11) {
+ return;
+ }
+- s.runningState = 10;
++ s.runningState = 11;
+ if (s.input != null) {
+ closeInput(s.input);
+ s.input = null;
+@@ -97,7 +204,7 @@ function BrotliDecodeClosure() {
+ }
+ /**
+ * @param {!State} s
+- * @return {!number}
++ * @return {number}
+ */
+ function decodeVarLenUnsignedByte(s) {
+ if (s.bitOffset >= 16) {
+@@ -105,7 +212,7 @@ function BrotliDecodeClosure() {
+ s.bitOffset -= 16;
+ }
+ if (readFewBits(s, 1) != 0) {
+- var /** !number */ n = readFewBits(s, 3);
++ var /** number */ n = readFewBits(s, 3);
+ if (n == 0) {
+ return 1;
+ } else {
+@@ -130,34 +237,34 @@ function BrotliDecodeClosure() {
+ if ((s.inputEnd != 0) && readFewBits(s, 1) != 0) {
+ return;
+ }
+- var /** !number */ sizeNibbles = readFewBits(s, 2) + 4;
++ var /** number */ sizeNibbles = readFewBits(s, 2) + 4;
+ if (sizeNibbles == 7) {
+ s.isMetadata = 1;
+ if (readFewBits(s, 1) != 0) {
+ throw "Corrupted reserved bit";
+ }
+- var /** !number */ sizeBytes = readFewBits(s, 2);
++ var /** number */ sizeBytes = readFewBits(s, 2);
+ if (sizeBytes == 0) {
+ return;
+ }
+- for (var /** !number */ i = 0; i < sizeBytes; i++) {
++ for (var /** number */ i = 0; i < sizeBytes; i++) {
+ if (s.bitOffset >= 16) {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ }
+- var /** !number */ bits = readFewBits(s, 8);
++ var /** number */ bits = readFewBits(s, 8);
+ if (bits == 0 && i + 1 == sizeBytes && sizeBytes > 1) {
+ throw "Exuberant nibble";
+ }
+ s.metaBlockLength |= bits << (i * 8);
+ }
+ } else {
+- for (var /** !number */ i = 0; i < sizeNibbles; i++) {
++ for (var /** number */ i = 0; i < sizeNibbles; i++) {
+ if (s.bitOffset >= 16) {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ }
+- var /** !number */ bits = readFewBits(s, 4);
++ var /** number */ bits = readFewBits(s, 4);
+ if (bits == 0 && i + 1 == sizeNibbles && sizeNibbles > 4) {
+ throw "Exuberant nibble";
+ }
+@@ -170,66 +277,53 @@ function BrotliDecodeClosure() {
+ }
+ }
+ /**
+- * @param {!Int32Array} table
+- * @param {!number} offset
++ * @param {!Int32Array} tableGroup
++ * @param {number} tableIdx
+ * @param {!State} s
+- * @return {!number}
++ * @return {number}
+ */
+- function readSymbol(table, offset, s) {
+- var /** !number */ val = (s.accumulator32 >>> s.bitOffset);
++ function readSymbol(tableGroup, tableIdx, s) {
++ var /** number */ offset = tableGroup[tableIdx];
++ var /** number */ val = (s.accumulator32 >>> s.bitOffset);
+ offset += val & 0xFF;
+- var /** !number */ bits = table[offset] >> 16;
+- var /** !number */ sym = table[offset] & 0xFFFF;
++ var /** number */ bits = tableGroup[offset] >> 16;
++ var /** number */ sym = tableGroup[offset] & 0xFFFF;
+ if (bits <= 8) {
+ s.bitOffset += bits;
+ return sym;
+ }
+ offset += sym;
+- var /** !number */ mask = (1 << bits) - 1;
++ var /** number */ mask = (1 << bits) - 1;
+ offset += (val & mask) >>> 8;
+- s.bitOffset += ((table[offset] >> 16) + 8);
+- return table[offset] & 0xFFFF;
++ s.bitOffset += ((tableGroup[offset] >> 16) + 8);
++ return tableGroup[offset] & 0xFFFF;
+ }
+ /**
+- * @param {!Int32Array} table
+- * @param {!number} offset
++ * @param {!Int32Array} tableGroup
++ * @param {number} tableIdx
+ * @param {!State} s
+- * @return {!number}
++ * @return {number}
+ */
+- function readBlockLength(table, offset, s) {
++ function readBlockLength(tableGroup, tableIdx, s) {
+ if (s.bitOffset >= 16) {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ }
+- var /** !number */ code = readSymbol(table, offset, s);
+- var /** !number */ n = BLOCK_LENGTH_N_BITS[code];
++ var /** number */ code = readSymbol(tableGroup, tableIdx, s);
++ var /** number */ n = BLOCK_LENGTH_N_BITS[code];
+ if (s.bitOffset >= 16) {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ }
+ return BLOCK_LENGTH_OFFSET[code] + ((n <= 16) ? readFewBits(s, n) : readManyBits(s, n));
+ }
+- /**
+- * @param {!number} code
+- * @param {!Int32Array} ringBuffer
+- * @param {!number} index
+- * @return {!number}
+- */
+- function translateShortCodes(code, ringBuffer, index) {
+- if (code < 16) {
+- index += DISTANCE_SHORT_CODE_INDEX_OFFSET[code];
+- index &= 3;
+- return ringBuffer[index] + DISTANCE_SHORT_CODE_VALUE_OFFSET[code];
+- }
+- return code - 16 + 1;
+- }
+ /**
+ * @param {!Int32Array} v
+- * @param {!number} index
++ * @param {number} index
+ * @return {void}
+ */
+ function moveToFront(v, index) {
+- var /** !number */ value = v[index];
++ var /** number */ value = v[index];
+ for (; index > 0; index--) {
+ v[index] = v[index - 1];
+ }
+@@ -237,16 +331,16 @@ function BrotliDecodeClosure() {
+ }
+ /**
+ * @param {!Int8Array} v
+- * @param {!number} vLen
++ * @param {number} vLen
+ * @return {void}
+ */
+ function inverseMoveToFrontTransform(v, vLen) {
+ var /** !Int32Array */ mtf = new Int32Array(256);
+- for (var /** !number */ i = 0; i < 256; i++) {
++ for (var /** number */ i = 0; i < 256; i++) {
+ mtf[i] = i;
+ }
+- for (var /** !number */ i = 0; i < vLen; i++) {
+- var /** !number */ index = v[i] & 0xFF;
++ for (var /** number */ i = 0; i < vLen; i++) {
++ var /** number */ index = v[i] & 0xFF;
+ v[i] = mtf[index];
+ if (index != 0) {
+ moveToFront(mtf, index);
+@@ -255,19 +349,20 @@ function BrotliDecodeClosure() {
+ }
+ /**
+ * @param {!Int32Array} codeLengthCodeLengths
+- * @param {!number} numSymbols
++ * @param {number} numSymbols
+ * @param {!Int32Array} codeLengths
+ * @param {!State} s
+ * @return {void}
+ */
+ function readHuffmanCodeLengths(codeLengthCodeLengths, numSymbols, codeLengths, s) {
+- var /** !number */ symbol = 0;
+- var /** !number */ prevCodeLen = 8;
+- var /** !number */ repeat = 0;
+- var /** !number */ repeatCodeLen = 0;
+- var /** !number */ space = 32768;
+- var /** !Int32Array */ table = new Int32Array(32);
+- buildHuffmanTable(table, 0, 5, codeLengthCodeLengths, 18);
++ var /** number */ symbol = 0;
++ var /** number */ prevCodeLen = 8;
++ var /** number */ repeat = 0;
++ var /** number */ repeatCodeLen = 0;
++ var /** number */ space = 32768;
++ var /** !Int32Array */ table = new Int32Array(32 + 1);
++ var /** number */ tableIdx = table.length - 1;
++ buildHuffmanTable(table, tableIdx, 5, codeLengthCodeLengths, 18);
+ while (symbol < numSymbols && space > 0) {
+ if (s.halfOffset > 2030) {
+ doReadMoreInput(s);
+@@ -276,9 +371,9 @@ function BrotliDecodeClosure() {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ }
+- var /** !number */ p = (s.accumulator32 >>> s.bitOffset) & 31;
++ var /** number */ p = (s.accumulator32 >>> s.bitOffset) & 31;
+ s.bitOffset += table[p] >> 16;
+- var /** !number */ codeLen = table[p] & 0xFFFF;
++ var /** number */ codeLen = table[p] & 0xFFFF;
+ if (codeLen < 16) {
+ repeat = 0;
+ codeLengths[symbol++] = codeLen;
+@@ -287,8 +382,8 @@ function BrotliDecodeClosure() {
+ space -= 32768 >> codeLen;
+ }
+ } else {
+- var /** !number */ extraBits = codeLen - 14;
+- var /** !number */ newLen = 0;
++ var /** number */ extraBits = codeLen - 14;
++ var /** number */ newLen = 0;
+ if (codeLen == 16) {
+ newLen = prevCodeLen;
+ }
+@@ -296,7 +391,7 @@ function BrotliDecodeClosure() {
+ repeat = 0;
+ repeatCodeLen = newLen;
+ }
+- var /** !number */ oldRepeat = repeat;
++ var /** number */ oldRepeat = repeat;
+ if (repeat > 0) {
+ repeat -= 2;
+ repeat <<= extraBits;
+@@ -306,11 +401,11 @@ function BrotliDecodeClosure() {
+ s.bitOffset -= 16;
+ }
+ repeat += readFewBits(s, extraBits) + 3;
+- var /** !number */ repeatDelta = repeat - oldRepeat;
++ var /** number */ repeatDelta = repeat - oldRepeat;
+ if (symbol + repeatDelta > numSymbols) {
+ throw "symbol + repeatDelta > numSymbols";
+ }
+- for (var /** !number */ i = 0; i < repeatDelta; i++) {
++ for (var /** number */ i = 0; i < repeatDelta; i++) {
+ codeLengths[symbol++] = repeatCodeLen;
+ }
+ if (repeatCodeLen != 0) {
+@@ -325,112 +420,145 @@ function BrotliDecodeClosure() {
+ }
+ /**
+ * @param {!Int32Array} symbols
+- * @param {!number} length
+- * @return {!number}
++ * @param {number} length
++ * @return {void}
+ */
+ function checkDupes(symbols, length) {
+- for (var /** !number */ i = 0; i < length - 1; ++i) {
+- for (var /** !number */ j = i + 1; j < length; ++j) {
++ for (var /** number */ i = 0; i < length - 1; ++i) {
++ for (var /** number */ j = i + 1; j < length; ++j) {
+ if (symbols[i] == symbols[j]) {
+- return 0;
++ throw "Duplicate simple Huffman code symbol";
+ }
+ }
+ }
+- return 1;
+ }
+ /**
+- * @param {!number} alphabetSize
+- * @param {!Int32Array} table
+- * @param {!number} offset
++ * @param {number} alphabetSizeMax
++ * @param {number} alphabetSizeLimit
++ * @param {!Int32Array} tableGroup
++ * @param {number} tableIdx
+ * @param {!State} s
+- * @return {void}
++ * @return {number}
++ */
++ function readSimpleHuffmanCode(alphabetSizeMax, alphabetSizeLimit, tableGroup, tableIdx, s) {
++ var /** !Int32Array */ codeLengths = new Int32Array(alphabetSizeLimit);
++ var /** !Int32Array */ symbols = new Int32Array(4);
++ var /** number */ maxBits = 1 + log2floor(alphabetSizeMax - 1);
++ var /** number */ numSymbols = readFewBits(s, 2) + 1;
++ for (var /** number */ i = 0; i < numSymbols; i++) {
++ if (s.bitOffset >= 16) {
++ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
++ s.bitOffset -= 16;
++ }
++ var /** number */ symbol = readFewBits(s, maxBits);
++ if (symbol >= alphabetSizeLimit) {
++ throw "Can't readHuffmanCode";
++ }
++ symbols[i] = symbol;
++ }
++ checkDupes(symbols, numSymbols);
++ var /** number */ histogramId = numSymbols;
++ if (numSymbols == 4) {
++ histogramId += readFewBits(s, 1);
++ }
++ switch(histogramId) {
++ case 1:
++ codeLengths[symbols[0]] = 1;
++ break;
++ case 2:
++ codeLengths[symbols[0]] = 1;
++ codeLengths[symbols[1]] = 1;
++ break;
++ case 3:
++ codeLengths[symbols[0]] = 1;
++ codeLengths[symbols[1]] = 2;
++ codeLengths[symbols[2]] = 2;
++ break;
++ case 4:
++ codeLengths[symbols[0]] = 2;
++ codeLengths[symbols[1]] = 2;
++ codeLengths[symbols[2]] = 2;
++ codeLengths[symbols[3]] = 2;
++ break;
++ case 5:
++ codeLengths[symbols[0]] = 1;
++ codeLengths[symbols[1]] = 2;
++ codeLengths[symbols[2]] = 3;
++ codeLengths[symbols[3]] = 3;
++ break;
++ default:
++ break;
++ }
++ return buildHuffmanTable(tableGroup, tableIdx, 8, codeLengths, alphabetSizeLimit);
++ }
++ /**
++ * @param {number} alphabetSizeLimit
++ * @param {number} skip
++ * @param {!Int32Array} tableGroup
++ * @param {number} tableIdx
++ * @param {!State} s
++ * @return {number}
+ */
+- function readHuffmanCode(alphabetSize, table, offset, s) {
+- var /** !number */ ok = 1;
+- var /** !number */ simpleCodeOrSkip;
++ function readComplexHuffmanCode(alphabetSizeLimit, skip, tableGroup, tableIdx, s) {
++ var /** !Int32Array */ codeLengths = new Int32Array(alphabetSizeLimit);
++ var /** !Int32Array */ codeLengthCodeLengths = new Int32Array(18);
++ var /** number */ space = 32;
++ var /** number */ numCodes = 0;
++ for (var /** number */ i = skip; i < 18 && space > 0; i++) {
++ var /** number */ codeLenIdx = CODE_LENGTH_CODE_ORDER[i];
++ if (s.bitOffset >= 16) {
++ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
++ s.bitOffset -= 16;
++ }
++ var /** number */ p = (s.accumulator32 >>> s.bitOffset) & 15;
++ s.bitOffset += FIXED_TABLE[p] >> 16;
++ var /** number */ v = FIXED_TABLE[p] & 0xFFFF;
++ codeLengthCodeLengths[codeLenIdx] = v;
++ if (v != 0) {
++ space -= (32 >> v);
++ numCodes++;
++ }
++ }
++ if (space != 0 && numCodes != 1) {
++ throw "Corrupted Huffman code histogram";
++ }
++ readHuffmanCodeLengths(codeLengthCodeLengths, alphabetSizeLimit, codeLengths, s);
++ return buildHuffmanTable(tableGroup, tableIdx, 8, codeLengths, alphabetSizeLimit);
++ }
++ /**
++ * @param {number} alphabetSizeMax
++ * @param {number} alphabetSizeLimit
++ * @param {!Int32Array} tableGroup
++ * @param {number} tableIdx
++ * @param {!State} s
++ * @return {number}
++ */
++ function readHuffmanCode(alphabetSizeMax, alphabetSizeLimit, tableGroup, tableIdx, s) {
+ if (s.halfOffset > 2030) {
+ doReadMoreInput(s);
+ }
+- var /** !Int32Array */ codeLengths = new Int32Array(alphabetSize);
+ if (s.bitOffset >= 16) {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ }
+- simpleCodeOrSkip = readFewBits(s, 2);
++ var /** number */ simpleCodeOrSkip = readFewBits(s, 2);
+ if (simpleCodeOrSkip == 1) {
+- var /** !number */ maxBitsCounter = alphabetSize - 1;
+- var /** !number */ maxBits = 0;
+- var /** !Int32Array */ symbols = new Int32Array(4);
+- var /** !number */ numSymbols = readFewBits(s, 2) + 1;
+- while (maxBitsCounter != 0) {
+- maxBitsCounter >>= 1;
+- maxBits++;
+- }
+- for (var /** !number */ i = 0; i < numSymbols; i++) {
+- if (s.bitOffset >= 16) {
+- s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+- s.bitOffset -= 16;
+- }
+- symbols[i] = readFewBits(s, maxBits) % alphabetSize;
+- codeLengths[symbols[i]] = 2;
+- }
+- codeLengths[symbols[0]] = 1;
+- switch(numSymbols) {
+- case 2:
+- codeLengths[symbols[1]] = 1;
+- break;
+- case 4:
+- if (readFewBits(s, 1) == 1) {
+- codeLengths[symbols[2]] = 3;
+- codeLengths[symbols[3]] = 3;
+- } else {
+- codeLengths[symbols[0]] = 2;
+- }
+- break;
+- default:
+- break;
+- }
+- ok = checkDupes(symbols, numSymbols);
++ return readSimpleHuffmanCode(alphabetSizeMax, alphabetSizeLimit, tableGroup, tableIdx, s);
+ } else {
+- var /** !Int32Array */ codeLengthCodeLengths = new Int32Array(18);
+- var /** !number */ space = 32;
+- var /** !number */ numCodes = 0;
+- for (var /** !number */ i = simpleCodeOrSkip; i < 18 && space > 0; i++) {
+- var /** !number */ codeLenIdx = CODE_LENGTH_CODE_ORDER[i];
+- if (s.bitOffset >= 16) {
+- s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+- s.bitOffset -= 16;
+- }
+- var /** !number */ p = (s.accumulator32 >>> s.bitOffset) & 15;
+- s.bitOffset += FIXED_TABLE[p] >> 16;
+- var /** !number */ v = FIXED_TABLE[p] & 0xFFFF;
+- codeLengthCodeLengths[codeLenIdx] = v;
+- if (v != 0) {
+- space -= (32 >> v);
+- numCodes++;
+- }
+- }
+- if (space != 0 && numCodes != 1) {
+- ok = 0;
+- }
+- readHuffmanCodeLengths(codeLengthCodeLengths, alphabetSize, codeLengths, s);
+- }
+- if (ok == 0) {
+- throw "Can't readHuffmanCode";
++ return readComplexHuffmanCode(alphabetSizeLimit, simpleCodeOrSkip, tableGroup, tableIdx, s);
+ }
+- buildHuffmanTable(table, offset, 8, codeLengths, alphabetSize);
+ }
+ /**
+- * @param {!number} contextMapSize
++ * @param {number} contextMapSize
+ * @param {!Int8Array} contextMap
+ * @param {!State} s
+- * @return {!number}
++ * @return {number}
+ */
+ function decodeContextMap(contextMapSize, contextMap, s) {
+ if (s.halfOffset > 2030) {
+ doReadMoreInput(s);
+ }
+- var /** !number */ numTrees = decodeVarLenUnsignedByte(s) + 1;
++ var /** number */ numTrees = decodeVarLenUnsignedByte(s) + 1;
+ if (numTrees == 1) {
+ contextMap.fill(0, 0, contextMapSize);
+ return numTrees;
+@@ -439,14 +567,17 @@ function BrotliDecodeClosure() {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ }
+- var /** !number */ useRleForZeros = readFewBits(s, 1);
+- var /** !number */ maxRunLengthPrefix = 0;
++ var /** number */ useRleForZeros = readFewBits(s, 1);
++ var /** number */ maxRunLengthPrefix = 0;
+ if (useRleForZeros != 0) {
+ maxRunLengthPrefix = readFewBits(s, 4) + 1;
+ }
+- var /** !Int32Array */ table = new Int32Array(1080);
+- readHuffmanCode(numTrees + maxRunLengthPrefix, table, 0, s);
+- for (var /** !number */ i = 0; i < contextMapSize; ) {
++ var /** number */ alphabetSize = numTrees + maxRunLengthPrefix;
++ var /** number */ tableSize = MAX_HUFFMAN_TABLE_SIZE[(alphabetSize + 31) >> 5];
++ var /** !Int32Array */ table = new Int32Array(tableSize + 1);
++ var /** number */ tableIdx = table.length - 1;
++ readHuffmanCode(alphabetSize, alphabetSize, table, tableIdx, s);
++ for (var /** number */ i = 0; i < contextMapSize; ) {
+ if (s.halfOffset > 2030) {
+ doReadMoreInput(s);
+ }
+@@ -454,7 +585,7 @@ function BrotliDecodeClosure() {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ }
+- var /** !number */ code = readSymbol(table, 0, s);
++ var /** number */ code = readSymbol(table, tableIdx, s);
+ if (code == 0) {
+ contextMap[i] = 0;
+ i++;
+@@ -463,7 +594,7 @@ function BrotliDecodeClosure() {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ }
+- var /** !number */ reps = (1 << code) + readFewBits(s, code);
++ var /** number */ reps = (1 << code) + readFewBits(s, code);
+ while (reps != 0) {
+ if (i >= contextMapSize) {
+ throw "Corrupted context map";
+@@ -488,19 +619,19 @@ function BrotliDecodeClosure() {
+ }
+ /**
+ * @param {!State} s
+- * @param {!number} treeType
+- * @param {!number} numBlockTypes
+- * @return {!number}
++ * @param {number} treeType
++ * @param {number} numBlockTypes
++ * @return {number}
+ */
+ function decodeBlockTypeAndLength(s, treeType, numBlockTypes) {
+ var /** !Int32Array */ ringBuffers = s.rings;
+- var /** !number */ offset = 4 + treeType * 2;
++ var /** number */ offset = 4 + treeType * 2;
+ if (s.bitOffset >= 16) {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ }
+- var /** !number */ blockType = readSymbol(s.blockTrees, treeType * 1080, s);
+- var /** !number */ result = readBlockLength(s.blockTrees, (treeType + 3) * 1080, s);
++ var /** number */ blockType = readSymbol(s.blockTrees, 2 * treeType, s);
++ var /** number */ result = readBlockLength(s.blockTrees, 2 * treeType + 1, s);
+ if (blockType == 1) {
+ blockType = ringBuffers[offset + 1] + 1;
+ } else if (blockType == 0) {
+@@ -521,11 +652,10 @@ function BrotliDecodeClosure() {
+ */
+ function decodeLiteralBlockSwitch(s) {
+ s.literalBlockLength = decodeBlockTypeAndLength(s, 0, s.numLiteralBlockTypes);
+- var /** !number */ literalBlockType = s.rings[5];
++ var /** number */ literalBlockType = s.rings[5];
+ s.contextMapSlice = literalBlockType << 6;
+- s.literalTreeIndex = s.contextMap[s.contextMapSlice] & 0xFF;
+- s.literalTree = s.hGroup0[s.literalTreeIndex];
+- var /** !number */ contextMode = s.contextModes[literalBlockType];
++ s.literalTreeIdx = s.contextMap[s.contextMapSlice] & 0xFF;
++ var /** number */ contextMode = s.contextModes[literalBlockType];
+ s.contextLookupOffset1 = contextMode << 9;
+ s.contextLookupOffset2 = s.contextLookupOffset1 + 256;
+ }
+@@ -535,7 +665,7 @@ function BrotliDecodeClosure() {
+ */
+ function decodeCommandBlockSwitch(s) {
+ s.commandBlockLength = decodeBlockTypeAndLength(s, 1, s.numCommandBlockTypes);
+- s.treeCommandOffset = s.hGroup1[s.rings[7]];
++ s.commandTreeIdx = s.rings[7];
+ }
+ /**
+ * @param {!State} s
+@@ -550,9 +680,9 @@ function BrotliDecodeClosure() {
+ * @return {void}
+ */
+ function maybeReallocateRingBuffer(s) {
+- var /** !number */ newSize = s.maxRingBufferSize;
++ var /** number */ newSize = s.maxRingBufferSize;
+ if (newSize > s.expectedTotalSize) {
+- var /** !number */ minimalNewSize = s.expectedTotalSize;
++ var /** number */ minimalNewSize = s.expectedTotalSize;
+ while ((newSize >> 1) > minimalNewSize) {
+ newSize >>= 1;
+ }
+@@ -563,7 +693,7 @@ function BrotliDecodeClosure() {
+ if (newSize <= s.ringBufferSize) {
+ return;
+ }
+- var /** !number */ ringBufferSizeWithSlack = newSize + 37;
++ var /** number */ ringBufferSizeWithSlack = newSize + 37;
+ var /** !Int8Array */ newBuffer = new Int8Array(ringBufferSizeWithSlack);
+ if (s.ringBuffer.length != 0) {
+ newBuffer.set(s.ringBuffer.subarray(0, 0 + s.ringBufferSize), 0);
+@@ -577,13 +707,13 @@ function BrotliDecodeClosure() {
+ */
+ function readNextMetablockHeader(s) {
+ if (s.inputEnd != 0) {
+- s.nextRunningState = 9;
+- s.runningState = 11;
++ s.nextRunningState = 10;
++ s.runningState = 12;
+ return;
+ }
+- s.hGroup0 = new Int32Array(0);
+- s.hGroup1 = new Int32Array(0);
+- s.hGroup2 = new Int32Array(0);
++ s.literalTreeGroup = new Int32Array(0);
++ s.commandTreeGroup = new Int32Array(0);
++ s.distanceTreeGroup = new Int32Array(0);
+ if (s.halfOffset > 2030) {
+ doReadMoreInput(s);
+ }
+@@ -593,9 +723,9 @@ function BrotliDecodeClosure() {
+ }
+ if ((s.isUncompressed != 0) || (s.isMetadata != 0)) {
+ jumpToByteBoundary(s);
+- s.runningState = (s.isMetadata != 0) ? 4 : 5;
++ s.runningState = (s.isMetadata != 0) ? 5 : 6;
+ } else {
+- s.runningState = 2;
++ s.runningState = 3;
+ }
+ if (s.isMetadata != 0) {
+ return;
+@@ -610,17 +740,54 @@ function BrotliDecodeClosure() {
+ }
+ /**
+ * @param {!State} s
+- * @param {!number} treeType
+- * @param {!number} numBlockTypes
+- * @return {!number}
++ * @param {number} treeType
++ * @param {number} numBlockTypes
++ * @return {number}
+ */
+ function readMetablockPartition(s, treeType, numBlockTypes) {
++ var /** number */ offset = s.blockTrees[2 * treeType];
+ if (numBlockTypes <= 1) {
++ s.blockTrees[2 * treeType + 1] = offset;
++ s.blockTrees[2 * treeType + 2] = offset;
+ return 1 << 28;
+ }
+- readHuffmanCode(numBlockTypes + 2, s.blockTrees, treeType * 1080, s);
+- readHuffmanCode(26, s.blockTrees, (treeType + 3) * 1080, s);
+- return readBlockLength(s.blockTrees, (treeType + 3) * 1080, s);
++ var /** number */ blockTypeAlphabetSize = numBlockTypes + 2;
++ offset += readHuffmanCode(blockTypeAlphabetSize, blockTypeAlphabetSize, s.blockTrees, 2 * treeType, s);
++ s.blockTrees[2 * treeType + 1] = offset;
++ var /** number */ blockLengthAlphabetSize = 26;
++ offset += readHuffmanCode(blockLengthAlphabetSize, blockLengthAlphabetSize, s.blockTrees, 2 * treeType + 1, s);
++ s.blockTrees[2 * treeType + 2] = offset;
++ return readBlockLength(s.blockTrees, 2 * treeType + 1, s);
++ }
++ /**
++ * @param {!State} s
++ * @param {number} alphabetSizeLimit
++ * @return {void}
++ */
++ function calculateDistanceLut(s, alphabetSizeLimit) {
++ var /** !Int8Array */ distExtraBits = s.distExtraBits;
++ var /** !Int32Array */ distOffset = s.distOffset;
++ var /** number */ npostfix = s.distancePostfixBits;
++ var /** number */ ndirect = s.numDirectDistanceCodes;
++ var /** number */ postfix = 1 << npostfix;
++ var /** number */ bits = 1;
++ var /** number */ half = 0;
++ var /** number */ i = 16;
++ for (var /** number */ j = 0; j < ndirect; ++j) {
++ distExtraBits[i] = 0;
++ distOffset[i] = j + 1;
++ ++i;
++ }
++ while (i < alphabetSizeLimit) {
++ var /** number */ base = ndirect + ((((2 + half) << bits) - 4) << npostfix) + 1;
++ for (var /** number */ j = 0; j < postfix; ++j) {
++ distExtraBits[i] = bits;
++ distOffset[i] = base + j;
++ ++i;
++ }
++ bits = bits + half;
++ half = half ^ 1;
++ }
+ }
+ /**
+ * @param {!State} s
+@@ -641,44 +808,49 @@ function BrotliDecodeClosure() {
+ s.bitOffset -= 16;
+ }
+ s.distancePostfixBits = readFewBits(s, 2);
+- s.numDirectDistanceCodes = 16 + (readFewBits(s, 4) << s.distancePostfixBits);
++ s.numDirectDistanceCodes = readFewBits(s, 4) << s.distancePostfixBits;
+ s.distancePostfixMask = (1 << s.distancePostfixBits) - 1;
+- var /** !number */ numDistanceCodes = s.numDirectDistanceCodes + (48 << s.distancePostfixBits);
+ s.contextModes = new Int8Array(s.numLiteralBlockTypes);
+- for (var /** !number */ i = 0; i < s.numLiteralBlockTypes; ) {
+- var /** !number */ limit = min(i + 96, s.numLiteralBlockTypes);
++ for (var /** number */ i = 0; i < s.numLiteralBlockTypes; ) {
++ var /** number */ limit = min(i + 96, s.numLiteralBlockTypes);
+ for (; i < limit; ++i) {
+ if (s.bitOffset >= 16) {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ }
+- s.contextModes[i] = (readFewBits(s, 2));
++ s.contextModes[i] = readFewBits(s, 2);
+ }
+ if (s.halfOffset > 2030) {
+ doReadMoreInput(s);
+ }
+ }
+ s.contextMap = new Int8Array(s.numLiteralBlockTypes << 6);
+- var /** !number */ numLiteralTrees = decodeContextMap(s.numLiteralBlockTypes << 6, s.contextMap, s);
++ var /** number */ numLiteralTrees = decodeContextMap(s.numLiteralBlockTypes << 6, s.contextMap, s);
+ s.trivialLiteralContext = 1;
+- for (var /** !number */ j = 0; j < s.numLiteralBlockTypes << 6; j++) {
++ for (var /** number */ j = 0; j < s.numLiteralBlockTypes << 6; j++) {
+ if (s.contextMap[j] != j >> 6) {
+ s.trivialLiteralContext = 0;
+ break;
+ }
+ }
+ s.distContextMap = new Int8Array(s.numDistanceBlockTypes << 2);
+- var /** !number */ numDistTrees = decodeContextMap(s.numDistanceBlockTypes << 2, s.distContextMap, s);
+- s.hGroup0 = decodeHuffmanTreeGroup(256, numLiteralTrees, s);
+- s.hGroup1 = decodeHuffmanTreeGroup(704, s.numCommandBlockTypes, s);
+- s.hGroup2 = decodeHuffmanTreeGroup(numDistanceCodes, numDistTrees, s);
++ var /** number */ numDistTrees = decodeContextMap(s.numDistanceBlockTypes << 2, s.distContextMap, s);
++ s.literalTreeGroup = decodeHuffmanTreeGroup(256, 256, numLiteralTrees, s);
++ s.commandTreeGroup = decodeHuffmanTreeGroup(704, 704, s.numCommandBlockTypes, s);
++ var /** number */ distanceAlphabetSizeMax = calculateDistanceAlphabetSize(s.distancePostfixBits, s.numDirectDistanceCodes, 24);
++ var /** number */ distanceAlphabetSizeLimit = distanceAlphabetSizeMax;
++ if (s.isLargeWindow == 1) {
++ distanceAlphabetSizeMax = calculateDistanceAlphabetSize(s.distancePostfixBits, s.numDirectDistanceCodes, 62);
++ distanceAlphabetSizeLimit = calculateDistanceAlphabetLimit(0x7FFFFFFC, s.distancePostfixBits, s.numDirectDistanceCodes);
++ }
++ s.distanceTreeGroup = decodeHuffmanTreeGroup(distanceAlphabetSizeMax, distanceAlphabetSizeLimit, numDistTrees, s);
++ calculateDistanceLut(s, distanceAlphabetSizeLimit);
+ s.contextMapSlice = 0;
+ s.distContextMapSlice = 0;
+- s.contextLookupOffset1 = (s.contextModes[0]) << 9;
++ s.contextLookupOffset1 = s.contextModes[0] * 512;
+ s.contextLookupOffset2 = s.contextLookupOffset1 + 256;
+- s.literalTreeIndex = 0;
+- s.literalTree = s.hGroup0[0];
+- s.treeCommandOffset = s.hGroup1[0];
++ s.literalTreeIdx = 0;
++ s.commandTreeIdx = 0;
+ s.rings[4] = 1;
+ s.rings[5] = 0;
+ s.rings[6] = 1;
+@@ -694,27 +866,27 @@ function BrotliDecodeClosure() {
+ var /** !Int8Array */ ringBuffer = s.ringBuffer;
+ if (s.metaBlockLength <= 0) {
+ reload(s);
+- s.runningState = 1;
++ s.runningState = 2;
+ return;
+ }
+- var /** !number */ chunkLength = min(s.ringBufferSize - s.pos, s.metaBlockLength);
++ var /** number */ chunkLength = min(s.ringBufferSize - s.pos, s.metaBlockLength);
+ copyBytes(s, ringBuffer, s.pos, chunkLength);
+ s.metaBlockLength -= chunkLength;
+ s.pos += chunkLength;
+ if (s.pos == s.ringBufferSize) {
+- s.nextRunningState = 5;
+- s.runningState = 11;
++ s.nextRunningState = 6;
++ s.runningState = 12;
+ return;
+ }
+ reload(s);
+- s.runningState = 1;
++ s.runningState = 2;
+ }
+ /**
+ * @param {!State} s
+- * @return {!number}
++ * @return {number}
+ */
+ function writeRingBuffer(s) {
+- var /** !number */ toWrite = min(s.outputLength - s.outputUsed, s.ringBufferBytesReady - s.ringBufferBytesWritten);
++ var /** number */ toWrite = min(s.outputLength - s.outputUsed, s.ringBufferBytesReady - s.ringBufferBytesWritten);
+ if (toWrite != 0) {
+ s.output.set(s.ringBuffer.subarray(s.ringBufferBytesWritten, s.ringBufferBytesWritten + toWrite), s.outputOffset + s.outputUsed);
+ s.outputUsed += toWrite;
+@@ -727,27 +899,28 @@ function BrotliDecodeClosure() {
+ }
+ }
+ /**
+- * @param {!number} alphabetSize
+- * @param {!number} n
++ * @param {number} alphabetSizeMax
++ * @param {number} alphabetSizeLimit
++ * @param {number} n
+ * @param {!State} s
+ * @return {!Int32Array}
+ */
+- function decodeHuffmanTreeGroup(alphabetSize, n, s) {
+- var /** !Int32Array */ group = new Int32Array(n + (n * 1080));
+- var /** !number */ next = n;
+- for (var /** !number */ i = 0; i < n; i++) {
++ function decodeHuffmanTreeGroup(alphabetSizeMax, alphabetSizeLimit, n, s) {
++ var /** number */ maxTableSize = MAX_HUFFMAN_TABLE_SIZE[(alphabetSizeLimit + 31) >> 5];
++ var /** !Int32Array */ group = new Int32Array(n + n * maxTableSize);
++ var /** number */ next = n;
++ for (var /** number */ i = 0; i < n; ++i) {
+ group[i] = next;
+- readHuffmanCode(alphabetSize, group, next, s);
+- next += 1080;
++ next += readHuffmanCode(alphabetSizeMax, alphabetSizeLimit, group, i, s);
+ }
+ return group;
+ }
+ /**
+ * @param {!State} s
+- * @return {!number}
++ * @return {number}
+ */
+ function calculateFence(s) {
+- var /** !number */ result = s.ringBufferSize;
++ var /** number */ result = s.ringBufferSize;
+ if (s.isEager != 0) {
+ result = min(result, s.ringBufferBytesWritten + s.outputLength - s.outputUsed);
+ }
+@@ -761,15 +934,24 @@ function BrotliDecodeClosure() {
+ if (s.runningState == 0) {
+ throw "Can't decompress until initialized";
+ }
+- if (s.runningState == 10) {
++ if (s.runningState == 11) {
+ throw "Can't decompress after close";
+ }
+- var /** !number */ fence = calculateFence(s);
+- var /** !number */ ringBufferMask = s.ringBufferSize - 1;
++ if (s.runningState == 1) {
++ var /** number */ windowBits = decodeWindowBits(s);
++ if (windowBits == -1) {
++ throw "Invalid 'windowBits' code";
++ }
++ s.maxRingBufferSize = 1 << windowBits;
++ s.maxBackwardDistance = s.maxRingBufferSize - 16;
++ s.runningState = 2;
++ }
++ var /** number */ fence = calculateFence(s);
++ var /** number */ ringBufferMask = s.ringBufferSize - 1;
+ var /** !Int8Array */ ringBuffer = s.ringBuffer;
+- while (s.runningState != 9) {
++ while (s.runningState != 10) {
+ switch(s.runningState) {
+- case 1:
++ case 2:
+ if (s.metaBlockLength < 0) {
+ throw "Invalid metablock length";
+ }
+@@ -778,12 +960,12 @@ function BrotliDecodeClosure() {
+ ringBufferMask = s.ringBufferSize - 1;
+ ringBuffer = s.ringBuffer;
+ continue;
+- case 2:
+- readMetablockHuffmanCodesAndContextMaps(s);
+- s.runningState = 3;
+ case 3:
++ readMetablockHuffmanCodesAndContextMaps(s);
++ s.runningState = 4;
++ case 4:
+ if (s.metaBlockLength <= 0) {
+- s.runningState = 1;
++ s.runningState = 2;
+ continue;
+ }
+ if (s.halfOffset > 2030) {
+@@ -797,32 +979,26 @@ function BrotliDecodeClosure() {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ }
+- var /** !number */ cmdCode = readSymbol(s.hGroup1, s.treeCommandOffset, s);
+- var /** !number */ rangeIdx = cmdCode >>> 6;
+- s.distanceCode = 0;
+- if (rangeIdx >= 2) {
+- rangeIdx -= 2;
+- s.distanceCode = -1;
+- }
+- var /** !number */ insertCode = INSERT_RANGE_LUT[rangeIdx] + ((cmdCode >>> 3) & 7);
++ var /** number */ cmdCode = readSymbol(s.commandTreeGroup, s.commandTreeIdx, s) << 2;
++ var /** number */ insertAndCopyExtraBits = CMD_LOOKUP[cmdCode];
++ var /** number */ insertLengthOffset = CMD_LOOKUP[cmdCode + 1];
++ var /** number */ copyLengthOffset = CMD_LOOKUP[cmdCode + 2];
++ s.distanceCode = CMD_LOOKUP[cmdCode + 3];
+ if (s.bitOffset >= 16) {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ }
+- var /** !number */ insertBits = INSERT_LENGTH_N_BITS[insertCode];
+- var /** !number */ insertExtra = ((insertBits <= 16) ? readFewBits(s, insertBits) : readManyBits(s, insertBits));
+- s.insertLength = INSERT_LENGTH_OFFSET[insertCode] + insertExtra;
+- var /** !number */ copyCode = COPY_RANGE_LUT[rangeIdx] + (cmdCode & 7);
++ var /** number */ extraBits = insertAndCopyExtraBits & 0xFF;
++ s.insertLength = insertLengthOffset + ((extraBits <= 16) ? readFewBits(s, extraBits) : readManyBits(s, extraBits));
+ if (s.bitOffset >= 16) {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ }
+- var /** !number */ copyBits = COPY_LENGTH_N_BITS[copyCode];
+- var /** !number */ copyExtra = ((copyBits <= 16) ? readFewBits(s, copyBits) : readManyBits(s, copyBits));
+- s.copyLength = COPY_LENGTH_OFFSET[copyCode] + copyExtra;
++ var /** number */ extraBits = insertAndCopyExtraBits >> 8;
++ s.copyLength = copyLengthOffset + ((extraBits <= 16) ? readFewBits(s, extraBits) : readManyBits(s, extraBits));
+ s.j = 0;
+- s.runningState = 6;
+- case 6:
++ s.runningState = 7;
++ case 7:
+ if (s.trivialLiteralContext != 0) {
+ while (s.j < s.insertLength) {
+ if (s.halfOffset > 2030) {
+@@ -836,18 +1012,18 @@ function BrotliDecodeClosure() {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ }
+- ringBuffer[s.pos] = readSymbol(s.hGroup0, s.literalTree, s);
++ ringBuffer[s.pos] = readSymbol(s.literalTreeGroup, s.literalTreeIdx, s);
+ s.pos++;
+ s.j++;
+ if (s.pos >= fence) {
+- s.nextRunningState = 6;
+- s.runningState = 11;
++ s.nextRunningState = 7;
++ s.runningState = 12;
+ break;
+ }
+ }
+ } else {
+- var /** !number */ prevByte1 = ringBuffer[(s.pos - 1) & ringBufferMask] & 0xFF;
+- var /** !number */ prevByte2 = ringBuffer[(s.pos - 2) & ringBufferMask] & 0xFF;
++ var /** number */ prevByte1 = ringBuffer[(s.pos - 1) & ringBufferMask] & 0xFF;
++ var /** number */ prevByte2 = ringBuffer[(s.pos - 2) & ringBufferMask] & 0xFF;
+ while (s.j < s.insertLength) {
+ if (s.halfOffset > 2030) {
+ doReadMoreInput(s);
+@@ -855,33 +1031,37 @@ function BrotliDecodeClosure() {
+ if (s.literalBlockLength == 0) {
+ decodeLiteralBlockSwitch(s);
+ }
+- var /** !number */ literalTreeIndex = s.contextMap[s.contextMapSlice + (LOOKUP[s.contextLookupOffset1 + prevByte1] | LOOKUP[s.contextLookupOffset2 + prevByte2])] & 0xFF;
++ var /** number */ literalContext = LOOKUP[s.contextLookupOffset1 + prevByte1] | LOOKUP[s.contextLookupOffset2 + prevByte2];
++ var /** number */ literalTreeIdx = s.contextMap[s.contextMapSlice + literalContext] & 0xFF;
+ s.literalBlockLength--;
+ prevByte2 = prevByte1;
+ if (s.bitOffset >= 16) {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ }
+- prevByte1 = readSymbol(s.hGroup0, s.hGroup0[literalTreeIndex], s);
++ prevByte1 = readSymbol(s.literalTreeGroup, literalTreeIdx, s);
+ ringBuffer[s.pos] = prevByte1;
+ s.pos++;
+ s.j++;
+ if (s.pos >= fence) {
+- s.nextRunningState = 6;
+- s.runningState = 11;
++ s.nextRunningState = 7;
++ s.runningState = 12;
+ break;
+ }
+ }
+ }
+- if (s.runningState != 6) {
++ if (s.runningState != 7) {
+ continue;
+ }
+ s.metaBlockLength -= s.insertLength;
+ if (s.metaBlockLength <= 0) {
+- s.runningState = 3;
++ s.runningState = 4;
+ continue;
+ }
+- if (s.distanceCode < 0) {
++ var /** number */ distanceCode = s.distanceCode;
++ if (distanceCode < 0) {
++ s.distance = s.rings[s.distRbIdx];
++ } else {
+ if (s.halfOffset > 2030) {
+ doReadMoreInput(s);
+ }
+@@ -893,52 +1073,56 @@ function BrotliDecodeClosure() {
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ }
+- s.distanceCode = readSymbol(s.hGroup2, s.hGroup2[s.distContextMap[s.distContextMapSlice + (s.copyLength > 4 ? 3 : s.copyLength - 2)] & 0xFF], s);
+- if (s.distanceCode >= s.numDirectDistanceCodes) {
+- s.distanceCode -= s.numDirectDistanceCodes;
+- var /** !number */ postfix = s.distanceCode & s.distancePostfixMask;
+- s.distanceCode >>>= s.distancePostfixBits;
+- var /** !number */ n = (s.distanceCode >>> 1) + 1;
+- var /** !number */ offset = ((2 + (s.distanceCode & 1)) << n) - 4;
+- if (s.bitOffset >= 16) {
+- s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+- s.bitOffset -= 16;
++ var /** number */ distTreeIdx = s.distContextMap[s.distContextMapSlice + distanceCode] & 0xFF;
++ distanceCode = readSymbol(s.distanceTreeGroup, distTreeIdx, s);
++ if (distanceCode < 16) {
++ var /** number */ index = (s.distRbIdx + DISTANCE_SHORT_CODE_INDEX_OFFSET[distanceCode]) & 0x3;
++ s.distance = s.rings[index] + DISTANCE_SHORT_CODE_VALUE_OFFSET[distanceCode];
++ if (s.distance < 0) {
++ throw "Negative distance";
+ }
+- var /** !number */ distanceExtra = ((n <= 16) ? readFewBits(s, n) : readManyBits(s, n));
+- s.distanceCode = s.numDirectDistanceCodes + postfix + ((offset + distanceExtra) << s.distancePostfixBits);
++ } else {
++ var /** number */ extraBits = s.distExtraBits[distanceCode];
++ var /** number */ bits;
++ if (s.bitOffset + extraBits <= 32) {
++ bits = readFewBits(s, extraBits);
++ } else {
++ if (s.bitOffset >= 16) {
++ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
++ s.bitOffset -= 16;
++ }
++ bits = ((extraBits <= 16) ? readFewBits(s, extraBits) : readManyBits(s, extraBits));
++ }
++ s.distance = s.distOffset[distanceCode] + (bits << s.distancePostfixBits);
+ }
+ }
+- s.distance = translateShortCodes(s.distanceCode, s.rings, s.distRbIdx);
+- if (s.distance < 0) {
+- throw "Negative distance";
+- }
+ if (s.maxDistance != s.maxBackwardDistance && s.pos < s.maxBackwardDistance) {
+ s.maxDistance = s.pos;
+ } else {
+ s.maxDistance = s.maxBackwardDistance;
+ }
+ if (s.distance > s.maxDistance) {
+- s.runningState = 8;
++ s.runningState = 9;
+ continue;
+ }
+- if (s.distanceCode > 0) {
+- s.rings[s.distRbIdx & 3] = s.distance;
+- s.distRbIdx++;
++ if (distanceCode > 0) {
++ s.distRbIdx = (s.distRbIdx + 1) & 0x3;
++ s.rings[s.distRbIdx] = s.distance;
+ }
+ if (s.copyLength > s.metaBlockLength) {
+ throw "Invalid backward reference";
+ }
+ s.j = 0;
+- s.runningState = 7;
+- case 7:
+- var /** !number */ src = (s.pos - s.distance) & ringBufferMask;
+- var /** !number */ dst = s.pos;
+- var /** !number */ copyLength = s.copyLength - s.j;
+- var /** !number */ srcEnd = src + copyLength;
+- var /** !number */ dstEnd = dst + copyLength;
++ s.runningState = 8;
++ case 8:
++ var /** number */ src = (s.pos - s.distance) & ringBufferMask;
++ var /** number */ dst = s.pos;
++ var /** number */ copyLength = s.copyLength - s.j;
++ var /** number */ srcEnd = src + copyLength;
++ var /** number */ dstEnd = dst + copyLength;
+ if ((srcEnd < ringBufferMask) && (dstEnd < ringBufferMask)) {
+ if (copyLength < 12 || (srcEnd > dst && dstEnd > src)) {
+- for (var /** !number */ k = 0; k < copyLength; k += 4) {
++ for (var /** number */ k = 0; k < copyLength; k += 4) {
+ ringBuffer[dst++] = ringBuffer[src++];
+ ringBuffer[dst++] = ringBuffer[src++];
+ ringBuffer[dst++] = ringBuffer[src++];
+@@ -957,32 +1141,35 @@ function BrotliDecodeClosure() {
+ s.pos++;
+ s.j++;
+ if (s.pos >= fence) {
+- s.nextRunningState = 7;
+- s.runningState = 11;
++ s.nextRunningState = 8;
++ s.runningState = 12;
+ break;
+ }
+ }
+ }
+- if (s.runningState == 7) {
+- s.runningState = 3;
++ if (s.runningState == 8) {
++ s.runningState = 4;
+ }
+ continue;
+- case 8:
++ case 9:
++ if (s.distance > 0x7FFFFFFC) {
++ throw "Invalid backward reference";
++ }
+ if (s.copyLength >= 4 && s.copyLength <= 24) {
+- var /** !number */ offset = DICTIONARY_OFFSETS_BY_LENGTH[s.copyLength];
+- var /** !number */ wordId = s.distance - s.maxDistance - 1;
+- var /** !number */ shift = DICTIONARY_SIZE_BITS_BY_LENGTH[s.copyLength];
+- var /** !number */ mask = (1 << shift) - 1;
+- var /** !number */ wordIdx = wordId & mask;
+- var /** !number */ transformIdx = wordId >>> shift;
++ var /** number */ offset = DICTIONARY_OFFSETS_BY_LENGTH[s.copyLength];
++ var /** number */ wordId = s.distance - s.maxDistance - 1;
++ var /** number */ shift = DICTIONARY_SIZE_BITS_BY_LENGTH[s.copyLength];
++ var /** number */ mask = (1 << shift) - 1;
++ var /** number */ wordIdx = wordId & mask;
++ var /** number */ transformIdx = wordId >>> shift;
+ offset += wordIdx * s.copyLength;
+ if (transformIdx < 121) {
+- var /** !number */ len = transformDictionaryWord(ringBuffer, s.pos, DICTIONARY_DATA, offset, s.copyLength, transformIdx);
++ var /** number */ len = transformDictionaryWord(ringBuffer, s.pos, DICTIONARY_DATA, offset, s.copyLength, RFC_TRANSFORMS, transformIdx);
+ s.pos += len;
+ s.metaBlockLength -= len;
+ if (s.pos >= fence) {
+- s.nextRunningState = 3;
+- s.runningState = 11;
++ s.nextRunningState = 4;
++ s.runningState = 12;
+ continue;
+ }
+ } else {
+@@ -991,9 +1178,9 @@ function BrotliDecodeClosure() {
+ } else {
+ throw "Invalid backward reference";
+ }
+- s.runningState = 3;
++ s.runningState = 4;
+ continue;
+- case 4:
++ case 5:
+ while (s.metaBlockLength > 0) {
+ if (s.halfOffset > 2030) {
+ doReadMoreInput(s);
+@@ -1005,15 +1192,15 @@ function BrotliDecodeClosure() {
+ readFewBits(s, 8);
+ s.metaBlockLength--;
+ }
+- s.runningState = 1;
++ s.runningState = 2;
+ continue;
+- case 5:
++ case 6:
+ copyUncompressedData(s);
+ continue;
+- case 11:
+- s.ringBufferBytesReady = min(s.pos, s.ringBufferSize);
+- s.runningState = 12;
+ case 12:
++ s.ringBufferBytesReady = min(s.pos, s.ringBufferSize);
++ s.runningState = 13;
++ case 13:
+ if (writeRingBuffer(s) == 0) {
+ return;
+ }
+@@ -1033,7 +1220,7 @@ function BrotliDecodeClosure() {
+ throw "Unexpected state " + s.runningState;
+ }
+ }
+- if (s.runningState == 9) {
++ if (s.runningState == 10) {
+ if (s.metaBlockLength < 0) {
+ throw "Invalid metablock length";
+ }
+@@ -1042,9 +1229,32 @@ function BrotliDecodeClosure() {
+ }
+ }
+
+- var TRANSFORMS = new Int32Array(363);
+- var PREFIX_SUFFIX = new Int8Array(217);
+- var PREFIX_SUFFIX_HEADS = new Int32Array(51);
++ /**
++ * @constructor
++ * @param {number} numTransforms
++ * @param {number} prefixSuffixLen
++ * @param {number} prefixSuffixCount
++ * @struct
++ */
++ function Transforms(numTransforms, prefixSuffixLen, prefixSuffixCount) {
++ /** @type {!number} */
++ this.numTransforms = 0;
++ /** @type {!Int32Array} */
++ this.triplets = new Int32Array(0);
++ /** @type {!Int8Array} */
++ this.prefixSuffixStorage = new Int8Array(0);
++ /** @type {!Int32Array} */
++ this.prefixSuffixHeads = new Int32Array(0);
++ /** @type {!Int16Array} */
++ this.params = new Int16Array(0);
++ this.numTransforms = numTransforms;
++ this.triplets = new Int32Array(numTransforms * 3);
++ this.params = new Int16Array(numTransforms);
++ this.prefixSuffixStorage = new Int8Array(prefixSuffixLen);
++ this.prefixSuffixHeads = new Int32Array(prefixSuffixCount + 1);
++ }
++
++ var RFC_TRANSFORMS = new Transforms(121, 167, 50);
+ /**
+ * @param {!Int8Array} prefixSuffix
+ * @param {!Int32Array} prefixSuffixHeads
+@@ -1054,67 +1264,83 @@ function BrotliDecodeClosure() {
+ * @return {void}
+ */
+ function unpackTransforms(prefixSuffix, prefixSuffixHeads, transforms, prefixSuffixSrc, transformsSrc) {
+- var /** !number */ n = prefixSuffixSrc.length;
+- var /** !number */ index = 1;
+- for (var /** !number */ i = 0; i < n; ++i) {
+- var /** !number */ c = prefixSuffixSrc.charCodeAt(i);
+- prefixSuffix[i] = c;
++ var /** number */ n = prefixSuffixSrc.length;
++ var /** number */ index = 1;
++ var /** number */ j = 0;
++ for (var /** number */ i = 0; i < n; ++i) {
++ var /** number */ c = prefixSuffixSrc.charCodeAt(i);
+ if (c == 35) {
+- prefixSuffixHeads[index++] = i + 1;
+- prefixSuffix[i] = 0;
++ prefixSuffixHeads[index++] = j;
++ } else {
++ prefixSuffix[j++] = c;
+ }
+ }
+- for (var /** !number */ i = 0; i < 363; ++i) {
++ for (var /** number */ i = 0; i < 363; ++i) {
+ transforms[i] = transformsSrc.charCodeAt(i) - 32;
+ }
+ }
+ {
+- unpackTransforms(PREFIX_SUFFIX, PREFIX_SUFFIX_HEADS, TRANSFORMS, "# #s #, #e #.# the #.com/#\u00C2\u00A0# of # and # in # to #\"#\">#\n#]# for # a # that #. # with #'# from # by #. The # on # as # is #ing #\n\t#:#ed #(# at #ly #=\"# of the #. This #,# not #er #al #='#ful #ive #less #est #ize #ous #", " !! ! , *! &! \" ! ) * * - ! # ! #!*! + ,$ ! - % . / # 0 1 . \" 2 3!* 4% ! # / 5 6 7 8 0 1 & $ 9 + : ; < ' != > ?! 4 @ 4 2 & A *# ( B C& ) % ) !*# *-% A +! *. D! %' & E *6 F G% ! *A *% H! D I!+! J!+ K +- *4! A L!*4 M N +6 O!*% +.! K *G P +%( ! G *D +D Q +# *K!*G!+D!+# +G +A +4!+% +K!+4!*D!+K!*K");
++ unpackTransforms(RFC_TRANSFORMS.prefixSuffixStorage, RFC_TRANSFORMS.prefixSuffixHeads, RFC_TRANSFORMS.triplets, "# #s #, #e #.# the #.com/#\u00C2\u00A0# of # and # in # to #\"#\">#\n#]# for # a # that #. # with #'# from # by #. The # on # as # is #ing #\n\t#:#ed #(# at #ly #=\"# of the #. This #,# not #er #al #='#ful #ive #less #est #ize #ous #", " !! ! , *! &! \" ! ) * * - ! # ! #!*! + ,$ ! - % . / # 0 1 . \" 2 3!* 4% ! # / 5 6 7 8 0 1 & $ 9 + : ; < ' != > ?! 4 @ 4 2 & A *# ( B C& ) % ) !*# *-% A +! *. D! %' & E *6 F G% ! *A *% H! D I!+! J!+ K +- *4! A L!*4 M N +6 O!*% +.! K *G P +%( ! G *D +D Q +# *K!*G!+D!+# +G +A +4!+% +K!+4!*D!+K!*K");
+ }
+ /**
+ * @param {!Int8Array} dst
+- * @param {!number} dstOffset
+- * @param {!Int8Array} data
+- * @param {!number} wordOffset
+- * @param {!number} len
+- * @param {!number} transformIndex
+- * @return {!number}
++ * @param {number} dstOffset
++ * @param {!Int8Array} src
++ * @param {number} srcOffset
++ * @param {number} len
++ * @param {!Transforms} transforms
++ * @param {number} transformIndex
++ * @return {number}
+ */
+- function transformDictionaryWord(dst, dstOffset, data, wordOffset, len, transformIndex) {
+- var /** !number */ offset = dstOffset;
+- var /** !number */ transformOffset = 3 * transformIndex;
+- var /** !number */ transformPrefix = PREFIX_SUFFIX_HEADS[TRANSFORMS[transformOffset]];
+- var /** !number */ transformType = TRANSFORMS[transformOffset + 1];
+- var /** !number */ transformSuffix = PREFIX_SUFFIX_HEADS[TRANSFORMS[transformOffset + 2]];
+- while (PREFIX_SUFFIX[transformPrefix] != 0) {
+- dst[offset++] = PREFIX_SUFFIX[transformPrefix++];
++ function transformDictionaryWord(dst, dstOffset, src, srcOffset, len, transforms, transformIndex) {
++ var /** number */ offset = dstOffset;
++ var /** !Int32Array */ triplets = transforms.triplets;
++ var /** !Int8Array */ prefixSuffixStorage = transforms.prefixSuffixStorage;
++ var /** !Int32Array */ prefixSuffixHeads = transforms.prefixSuffixHeads;
++ var /** number */ transformOffset = 3 * transformIndex;
++ var /** number */ prefixIdx = triplets[transformOffset];
++ var /** number */ transformType = triplets[transformOffset + 1];
++ var /** number */ suffixIdx = triplets[transformOffset + 2];
++ var /** number */ prefix = prefixSuffixHeads[prefixIdx];
++ var /** number */ prefixEnd = prefixSuffixHeads[prefixIdx + 1];
++ var /** number */ suffix = prefixSuffixHeads[suffixIdx];
++ var /** number */ suffixEnd = prefixSuffixHeads[suffixIdx + 1];
++ var /** number */ omitFirst = transformType - 11;
++ var /** number */ omitLast = transformType - 0;
++ if (omitFirst < 1 || omitFirst > 9) {
++ omitFirst = 0;
++ }
++ if (omitLast < 1 || omitLast > 9) {
++ omitLast = 0;
++ }
++ while (prefix != prefixEnd) {
++ dst[offset++] = prefixSuffixStorage[prefix++];
+ }
+- var /** !number */ omitFirst = transformType >= 12 ? (transformType - 11) : 0;
+ if (omitFirst > len) {
+ omitFirst = len;
+ }
+- wordOffset += omitFirst;
++ srcOffset += omitFirst;
+ len -= omitFirst;
+- len -= transformType <= 9 ? transformType : 0;
+- var /** !number */ i = len;
++ len -= omitLast;
++ var /** number */ i = len;
+ while (i > 0) {
+- dst[offset++] = data[wordOffset++];
++ dst[offset++] = src[srcOffset++];
+ i--;
+ }
+- if (transformType == 11 || transformType == 10) {
+- var /** !number */ uppercaseOffset = offset - len;
++ if (transformType == 10 || transformType == 11) {
++ var /** number */ uppercaseOffset = offset - len;
+ if (transformType == 10) {
+ len = 1;
+ }
+ while (len > 0) {
+- var /** !number */ tmp = dst[uppercaseOffset] & 0xFF;
+- if (tmp < 0xc0) {
+- if (tmp >= 97 && tmp <= 122) {
++ var /** number */ c0 = dst[uppercaseOffset] & 0xFF;
++ if (c0 < 0xC0) {
++ if (c0 >= 97 && c0 <= 122) {
+ dst[uppercaseOffset] ^= 32;
+ }
+ uppercaseOffset += 1;
+ len -= 1;
+- } else if (tmp < 0xe0) {
++ } else if (c0 < 0xE0) {
+ dst[uppercaseOffset + 1] ^= 32;
+ uppercaseOffset += 2;
+ len -= 2;
+@@ -1124,20 +1350,74 @@ function BrotliDecodeClosure() {
+ len -= 3;
+ }
+ }
++ } else if (transformType == 21 || transformType == 22) {
++ var /** number */ shiftOffset = offset - len;
++ var /** number */ param = transforms.params[transformIndex];
++ var /** number */ scalar = (param & 0x7FFF) + (0x1000000 - (param & 0x8000));
++ while (len > 0) {
++ var /** number */ step = 1;
++ var /** number */ c0 = dst[shiftOffset] & 0xFF;
++ if (c0 < 0x80) {
++ scalar += c0;
++ dst[shiftOffset] = (scalar & 0x7F);
++ } else if (c0 < 0xC0) {
++ } else if (c0 < 0xE0) {
++ if (len >= 2) {
++ var /** number */ c1 = dst[shiftOffset + 1];
++ scalar += (c1 & 0x3F) | ((c0 & 0x1F) << 6);
++ dst[shiftOffset] = (0xC0 | ((scalar >> 6) & 0x1F));
++ dst[shiftOffset + 1] = ((c1 & 0xC0) | (scalar & 0x3F));
++ step = 2;
++ } else {
++ step = len;
++ }
++ } else if (c0 < 0xF0) {
++ if (len >= 3) {
++ var /** number */ c1 = dst[shiftOffset + 1];
++ var /** number */ c2 = dst[shiftOffset + 2];
++ scalar += (c2 & 0x3F) | ((c1 & 0x3F) << 6) | ((c0 & 0x0F) << 12);
++ dst[shiftOffset] = (0xE0 | ((scalar >> 12) & 0x0F));
++ dst[shiftOffset + 1] = ((c1 & 0xC0) | ((scalar >> 6) & 0x3F));
++ dst[shiftOffset + 2] = ((c2 & 0xC0) | (scalar & 0x3F));
++ step = 3;
++ } else {
++ step = len;
++ }
++ } else if (c0 < 0xF8) {
++ if (len >= 4) {
++ var /** number */ c1 = dst[shiftOffset + 1];
++ var /** number */ c2 = dst[shiftOffset + 2];
++ var /** number */ c3 = dst[shiftOffset + 3];
++ scalar += (c3 & 0x3F) | ((c2 & 0x3F) << 6) | ((c1 & 0x3F) << 12) | ((c0 & 0x07) << 18);
++ dst[shiftOffset] = (0xF0 | ((scalar >> 18) & 0x07));
++ dst[shiftOffset + 1] = ((c1 & 0xC0) | ((scalar >> 12) & 0x3F));
++ dst[shiftOffset + 2] = ((c2 & 0xC0) | ((scalar >> 6) & 0x3F));
++ dst[shiftOffset + 3] = ((c3 & 0xC0) | (scalar & 0x3F));
++ step = 4;
++ } else {
++ step = len;
++ }
++ }
++ shiftOffset += step;
++ len -= step;
++ if (transformType == 21) {
++ len = 0;
++ }
++ }
+ }
+- while (PREFIX_SUFFIX[transformSuffix] != 0) {
+- dst[offset++] = PREFIX_SUFFIX[transformSuffix++];
++ while (suffix != suffixEnd) {
++ dst[offset++] = prefixSuffixStorage[suffix++];
+ }
+ return offset - dstOffset;
+ }
+
+ /**
+- * @param {!number} key
+- * @param {!number} len
+- * @return {!number}
++ * @param {number} key
++ * @param {number} len
++ * @return {number}
+ */
+ function getNextKey(key, len) {
+- var /** !number */ step = 1 << (len - 1);
++ var /** number */ step = 1 << (len - 1);
+ while ((key & step) != 0) {
+ step >>= 1;
+ }
+@@ -1145,10 +1425,10 @@ function BrotliDecodeClosure() {
+ }
+ /**
+ * @param {!Int32Array} table
+- * @param {!number} offset
+- * @param {!number} step
+- * @param {!number} end
+- * @param {!number} item
++ * @param {number} offset
++ * @param {number} step
++ * @param {number} end
++ * @param {number} item
+ * @return {void}
+ */
+ function replicateValue(table, offset, step, end, item) {
+@@ -1159,12 +1439,12 @@ function BrotliDecodeClosure() {
+ }
+ /**
+ * @param {!Int32Array} count
+- * @param {!number} len
+- * @param {!number} rootBits
+- * @return {!number}
++ * @param {number} len
++ * @param {number} rootBits
++ * @return {number}
+ */
+ function nextTableBitSize(count, len, rootBits) {
+- var /** !number */ left = 1 << (len - rootBits);
++ var /** number */ left = 1 << (len - rootBits);
+ while (len < 15) {
+ left -= count[len];
+ if (left <= 0) {
+@@ -1176,24 +1456,25 @@ function BrotliDecodeClosure() {
+ return len - rootBits;
+ }
+ /**
+- * @param {!Int32Array} rootTable
+- * @param {!number} tableOffset
+- * @param {!number} rootBits
++ * @param {!Int32Array} tableGroup
++ * @param {number} tableIdx
++ * @param {number} rootBits
+ * @param {!Int32Array} codeLengths
+- * @param {!number} codeLengthsSize
+- * @return {void}
++ * @param {number} codeLengthsSize
++ * @return {number}
+ */
+- function buildHuffmanTable(rootTable, tableOffset, rootBits, codeLengths, codeLengthsSize) {
+- var /** !number */ key;
++ function buildHuffmanTable(tableGroup, tableIdx, rootBits, codeLengths, codeLengthsSize) {
++ var /** number */ tableOffset = tableGroup[tableIdx];
++ var /** number */ key;
+ var /** !Int32Array */ sorted = new Int32Array(codeLengthsSize);
+ var /** !Int32Array */ count = new Int32Array(16);
+ var /** !Int32Array */ offset = new Int32Array(16);
+- var /** !number */ symbol;
++ var /** number */ symbol;
+ for (symbol = 0; symbol < codeLengthsSize; symbol++) {
+ count[codeLengths[symbol]]++;
+ }
+ offset[1] = 0;
+- for (var /** !number */ len = 1; len < 15; len++) {
++ for (var /** number */ len = 1; len < 15; len++) {
+ offset[len + 1] = offset[len] + count[len];
+ }
+ for (symbol = 0; symbol < codeLengthsSize; symbol++) {
+@@ -1201,27 +1482,27 @@ function BrotliDecodeClosure() {
+ sorted[offset[codeLengths[symbol]]++] = symbol;
+ }
+ }
+- var /** !number */ tableBits = rootBits;
+- var /** !number */ tableSize = 1 << tableBits;
+- var /** !number */ totalSize = tableSize;
++ var /** number */ tableBits = rootBits;
++ var /** number */ tableSize = 1 << tableBits;
++ var /** number */ totalSize = tableSize;
+ if (offset[15] == 1) {
+ for (key = 0; key < totalSize; key++) {
+- rootTable[tableOffset + key] = sorted[0];
++ tableGroup[tableOffset + key] = sorted[0];
+ }
+- return;
++ return totalSize;
+ }
+ key = 0;
+ symbol = 0;
+- for (var /** !number */ len = 1, step = 2; len <= rootBits; len++, step <<= 1) {
++ for (var /** number */ len = 1, step = 2; len <= rootBits; len++, step <<= 1) {
+ for (; count[len] > 0; count[len]--) {
+- replicateValue(rootTable, tableOffset + key, step, tableSize, len << 16 | sorted[symbol++]);
++ replicateValue(tableGroup, tableOffset + key, step, tableSize, len << 16 | sorted[symbol++]);
+ key = getNextKey(key, len);
+ }
+ }
+- var /** !number */ mask = totalSize - 1;
+- var /** !number */ low = -1;
+- var /** !number */ currentOffset = tableOffset;
+- for (var /** !number */ len = rootBits + 1, step = 2; len <= 15; len++, step <<= 1) {
++ var /** number */ mask = totalSize - 1;
++ var /** number */ low = -1;
++ var /** number */ currentOffset = tableOffset;
++ for (var /** number */ len = rootBits + 1, step = 2; len <= 15; len++, step <<= 1) {
+ for (; count[len] > 0; count[len]--) {
+ if ((key & mask) != low) {
+ currentOffset += tableSize;
+@@ -1229,12 +1510,13 @@ function BrotliDecodeClosure() {
+ tableSize = 1 << tableBits;
+ totalSize += tableSize;
+ low = key & mask;
+- rootTable[tableOffset + low] = (tableBits + rootBits) << 16 | (currentOffset - tableOffset - low);
++ tableGroup[tableOffset + low] = (tableBits + rootBits) << 16 | (currentOffset - tableOffset - low);
+ }
+- replicateValue(rootTable, currentOffset + (key >> rootBits), step, tableSize, (len - rootBits) << 16 | sorted[symbol++]);
++ replicateValue(tableGroup, currentOffset + (key >> rootBits), step, tableSize, (len - rootBits) << 16 | sorted[symbol++]);
+ key = getNextKey(key, len);
+ }
+ }
++ return totalSize;
+ }
+
+ /**
+@@ -1248,13 +1530,13 @@ function BrotliDecodeClosure() {
+ }
+ throw "No more input";
+ }
+- var /** !number */ readOffset = s.halfOffset << 1;
+- var /** !number */ bytesInBuffer = 4096 - readOffset;
++ var /** number */ readOffset = s.halfOffset << 1;
++ var /** number */ bytesInBuffer = 4096 - readOffset;
+ s.byteBuffer.copyWithin(0, readOffset, 4096);
+ s.halfOffset = 0;
+ while (bytesInBuffer < 4096) {
+- var /** !number */ spaceLeft = 4096 - bytesInBuffer;
+- var /** !number */ len = readInput(s.input, s.byteBuffer, bytesInBuffer, spaceLeft);
++ var /** number */ spaceLeft = 4096 - bytesInBuffer;
++ var /** number */ len = readInput(s.input, s.byteBuffer, bytesInBuffer, spaceLeft);
+ if (len <= 0) {
+ s.endOfStreamReached = 1;
+ s.tailBytes = bytesInBuffer;
+@@ -1267,14 +1549,14 @@ function BrotliDecodeClosure() {
+ }
+ /**
+ * @param {!State} s
+- * @param {!number} endOfStream
++ * @param {number} endOfStream
+ * @return {void}
+ */
+ function checkHealth(s, endOfStream) {
+ if (s.endOfStreamReached == 0) {
+ return;
+ }
+- var /** !number */ byteOffset = (s.halfOffset << 1) + ((s.bitOffset + 7) >> 3) - 4;
++ var /** number */ byteOffset = (s.halfOffset << 1) + ((s.bitOffset + 7) >> 3) - 4;
+ if (byteOffset > s.tailBytes) {
+ throw "Read after end";
+ }
+@@ -1284,21 +1566,30 @@ function BrotliDecodeClosure() {
+ }
+ /**
+ * @param {!State} s
+- * @param {!number} n
+- * @return {!number}
++ * @return {void}
++ */
++ function assertAccumulatorHealthy(s) {
++ if (s.bitOffset > 32) {
++ throw "Accumulator underloaded: " + s.bitOffset;
++ }
++ }
++ /**
++ * @param {!State} s
++ * @param {number} n
++ * @return {number}
+ */
+ function readFewBits(s, n) {
+- var /** !number */ val = (s.accumulator32 >>> s.bitOffset) & ((1 << n) - 1);
++ var /** number */ val = (s.accumulator32 >>> s.bitOffset) & ((1 << n) - 1);
+ s.bitOffset += n;
+ return val;
+ }
+ /**
+ * @param {!State} s
+- * @param {!number} n
+- * @return {!number}
++ * @param {number} n
++ * @return {number}
+ */
+ function readManyBits(s, n) {
+- var /** !number */ low = readFewBits(s, 16);
++ var /** number */ low = readFewBits(s, 16);
+ s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
+ s.bitOffset -= 16;
+ return low | (readFewBits(s, n - 16) << 16);
+@@ -1344,9 +1635,9 @@ function BrotliDecodeClosure() {
+ * @return {void}
+ */
+ function jumpToByteBoundary(s) {
+- var /** !number */ padding = (32 - s.bitOffset) & 7;
++ var /** number */ padding = (32 - s.bitOffset) & 7;
+ if (padding != 0) {
+- var /** !number */ paddingBits = readFewBits(s, padding);
++ var /** number */ paddingBits = readFewBits(s, padding);
+ if (paddingBits != 0) {
+ throw "Corrupted padding bits";
+ }
+@@ -1354,10 +1645,10 @@ function BrotliDecodeClosure() {
+ }
+ /**
+ * @param {!State} s
+- * @return {!number}
++ * @return {number}
+ */
+ function halfAvailable(s) {
+- var /** !number */ limit = 2048;
++ var /** number */ limit = 2048;
+ if (s.endOfStreamReached != 0) {
+ limit = (s.tailBytes + 1) >> 1;
+ }
+@@ -1366,8 +1657,8 @@ function BrotliDecodeClosure() {
+ /**
+ * @param {!State} s
+ * @param {!Int8Array} data
+- * @param {!number} offset
+- * @param {!number} length
++ * @param {number} offset
++ * @param {number} length
+ * @return {void}
+ */
+ function copyBytes(s, data, offset, length) {
+@@ -1382,10 +1673,10 @@ function BrotliDecodeClosure() {
+ if (length == 0) {
+ return;
+ }
+- var /** !number */ copyNibbles = min(halfAvailable(s), length >> 1);
++ var /** number */ copyNibbles = min(halfAvailable(s), length >> 1);
+ if (copyNibbles > 0) {
+- var /** !number */ readOffset = s.halfOffset << 1;
+- var /** !number */ delta = copyNibbles << 1;
++ var /** number */ readOffset = s.halfOffset << 1;
++ var /** number */ delta = copyNibbles << 1;
+ data.set(s.byteBuffer.subarray(readOffset, readOffset + delta), offset);
+ offset += delta;
+ length -= delta;
+@@ -1408,7 +1699,7 @@ function BrotliDecodeClosure() {
+ return;
+ }
+ while (length > 0) {
+- var /** !number */ len = readInput(s.input, data, offset, length);
++ var /** number */ len = readInput(s.input, data, offset, length);
+ if (len == -1) {
+ throw "Unexpected end of input";
+ }
+@@ -1418,14 +1709,14 @@ function BrotliDecodeClosure() {
+ }
+ /**
+ * @param {!State} s
+- * @param {!number} byteLen
++ * @param {number} byteLen
+ * @return {void}
+ */
+ function bytesToNibbles(s, byteLen) {
+ var /** !Int8Array */ byteBuffer = s.byteBuffer;
+- var /** !number */ halfLen = byteLen >> 1;
++ var /** number */ halfLen = byteLen >> 1;
+ var /** !Int16Array */ shortBuffer = s.shortBuffer;
+- for (var /** !number */ i = 0; i < halfLen; ++i) {
++ for (var /** number */ i = 0; i < halfLen; ++i) {
+ shortBuffer[i] = ((byteBuffer[i * 2] & 0xFF) | ((byteBuffer[(i * 2) + 1] & 0xFF) << 8));
+ }
+ }
+@@ -1438,33 +1729,33 @@ function BrotliDecodeClosure() {
+ * @return {void}
+ */
+ function unpackLookupTable(lookup, map, rle) {
+- for (var /** !number */ i = 0; i < 256; ++i) {
++ for (var /** number */ i = 0; i < 256; ++i) {
+ lookup[i] = i & 0x3F;
+ lookup[512 + i] = i >> 2;
+ lookup[1792 + i] = 2 + (i >> 6);
+ }
+- for (var /** !number */ i = 0; i < 128; ++i) {
++ for (var /** number */ i = 0; i < 128; ++i) {
+ lookup[1024 + i] = 4 * (map.charCodeAt(i) - 32);
+ }
+- for (var /** !number */ i = 0; i < 64; ++i) {
++ for (var /** number */ i = 0; i < 64; ++i) {
+ lookup[1152 + i] = i & 1;
+ lookup[1216 + i] = 2 + (i & 1);
+ }
+- var /** !number */ offset = 1280;
+- for (var /** !number */ k = 0; k < 19; ++k) {
+- var /** !number */ value = k & 3;
+- var /** !number */ rep = rle.charCodeAt(k) - 32;
+- for (var /** !number */ i = 0; i < rep; ++i) {
++ var /** number */ offset = 1280;
++ for (var /** number */ k = 0; k < 19; ++k) {
++ var /** number */ value = k & 3;
++ var /** number */ rep = rle.charCodeAt(k) - 32;
++ for (var /** number */ i = 0; i < rep; ++i) {
+ lookup[offset++] = value;
+ }
+ }
+- for (var /** !number */ i = 0; i < 16; ++i) {
++ for (var /** number */ i = 0; i < 16; ++i) {
+ lookup[1792 + i] = 1;
+ lookup[2032 + i] = 6;
+ }
+ lookup[1792] = 0;
+ lookup[2047] = 7;
+- for (var /** !number */ i = 0; i < 256; ++i) {
++ for (var /** number */ i = 0; i < 256; ++i) {
+ lookup[1536 + i] = lookup[1792 + i] << 3;
+ }
+ }
+@@ -1486,6 +1777,8 @@ function BrotliDecodeClosure() {
+ /** @type {!Int8Array} */
+ this.distContextMap = new Int8Array(0);
+ /** @type {!Int8Array} */
++ this.distExtraBits = new Int8Array(0);
++ /** @type {!Int8Array} */
+ this.output = new Int8Array(0);
+ /** @type {!Int8Array} */
+ this.byteBuffer = new Int8Array(0);
+@@ -1498,11 +1791,13 @@ function BrotliDecodeClosure() {
+ /** @type {!Int32Array} */
+ this.blockTrees = new Int32Array(0);
+ /** @type {!Int32Array} */
+- this.hGroup0 = new Int32Array(0);
++ this.literalTreeGroup = new Int32Array(0);
++ /** @type {!Int32Array} */
++ this.commandTreeGroup = new Int32Array(0);
+ /** @type {!Int32Array} */
+- this.hGroup1 = new Int32Array(0);
++ this.distanceTreeGroup = new Int32Array(0);
+ /** @type {!Int32Array} */
+- this.hGroup2 = new Int32Array(0);
++ this.distOffset = new Int32Array(0);
+ /** @type {!number} */
+ this.runningState = 0;
+ /** @type {!number} */
+@@ -1546,9 +1841,9 @@ function BrotliDecodeClosure() {
+ /** @type {!number} */
+ this.trivialLiteralContext = 0;
+ /** @type {!number} */
+- this.literalTreeIndex = 0;
++ this.literalTreeIdx = 0;
+ /** @type {!number} */
+- this.literalTree = 0;
++ this.commandTreeIdx = 0;
+ /** @type {!number} */
+ this.j = 0;
+ /** @type {!number} */
+@@ -1562,8 +1857,6 @@ function BrotliDecodeClosure() {
+ /** @type {!number} */
+ this.contextLookupOffset2 = 0;
+ /** @type {!number} */
+- this.treeCommandOffset = 0;
+- /** @type {!number} */
+ this.distanceCode = 0;
+ /** @type {!number} */
+ this.numDirectDistanceCodes = 0;
+@@ -1595,6 +1888,8 @@ function BrotliDecodeClosure() {
+ this.ringBufferBytesReady = 0;
+ /** @type {!number} */
+ this.isEager = 0;
++ /** @type {!number} */
++ this.isLargeWindow = 0;
+ /** @type {!InputStream|null} */
+ this.input = null;
+ this.ringBuffer = new Int8Array(0);
+@@ -1617,13 +1912,13 @@ function BrotliDecodeClosure() {
+ if (dict.length != dictionary.length) {
+ throw "Corrupted brotli dictionary";
+ }
+- var /** !number */ offset = 0;
+- var /** !number */ n = skipFlip.length;
+- for (var /** !number */ i = 0; i < n; i += 2) {
+- var /** !number */ skip = skipFlip.charCodeAt(i) - 36;
+- var /** !number */ flip = skipFlip.charCodeAt(i + 1) - 36;
++ var /** number */ offset = 0;
++ var /** number */ n = skipFlip.length;
++ for (var /** number */ i = 0; i < n; i += 2) {
++ var /** number */ skip = skipFlip.charCodeAt(i) - 36;
++ var /** number */ flip = skipFlip.charCodeAt(i + 1) - 36;
+ offset += skip;
+- for (var /** !number */ j = 0; j < flip; ++j) {
++ for (var /** number */ j = 0; j < flip; ++j) {
+ dict[offset] |= 0x80;
+ offset++;
+ }
+diff --git a/js/decode.min.js b/js/decode.min.js
+index 109b8918..5fee0012 100755
+--- a/js/decode.min.js
++++ b/js/decode.min.js
+@@ -1 +1,2 @@
+-function BrotliDecodeClosure(){"use strict";var O=new Int8Array(0);function d(e){this.data=e;this.offset=0}var $=Int32Array.from([1,2,3,4,0,5,17,6,16,7,8,9,10,11,12,13,14,15]);var n=Int32Array.from([3,2,1,0,3,3,3,3,3,3,2,2,2,2,2,2]);var a=Int32Array.from([0,0,0,0,-1,1,-2,2,-3,3,-1,1,-2,2,-3,3]);var b=Int32Array.from([131072,131076,131075,196610,131072,131076,131075,262145,131072,131076,131075,196610,131072,131076,131075,262149]);var S=Int32Array.from([0,0,0,0,0,4096,9216,21504,35840,44032,53248,63488,74752,87040,93696,100864,104704,106752,108928,113536,115968,118528,119872,121280,122016]);var A=Int32Array.from([0,0,0,0,10,10,11,11,10,10,10,10,10,9,9,8,7,7,8,7,7,6,6,5,5]);var o=Int32Array.from([1,5,9,13,17,25,33,41,49,65,81,97,113,145,177,209,241,305,369,497,753,1265,2289,4337,8433,16625]);var r=Int32Array.from([2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,7,8,9,10,11,12,13,24]);var T=Int32Array.from([0,1,2,3,4,5,6,8,10,14,18,26,34,50,66,98,130,194,322,578,1090,2114,6210,22594]);var I=Int32Array.from([0,0,0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,7,8,9,10,12,14,24]);var q=Int32Array.from([2,3,4,5,6,7,8,9,10,12,14,18,22,30,38,54,70,102,134,198,326,582,1094,2118]);var z=Int32Array.from([0,0,0,0,0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,7,8,9,10,24]);var L=Int32Array.from([0,0,8,8,0,16,8,16,16]);var D=Int32Array.from([0,8,0,8,16,0,16,8,16]);function s(e){if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}if(ee(e,1)==0){return 16}var t=ee(e,3);if(t!=0){return 17+t}t=ee(e,3);if(t!=0){return 8+t}return 17}function h(e,t){if(e.runningState!=0){throw"State MUST be uninitialized"}e.blockTrees=new Int32Array(6480);e.input=t;ie(e);var i=s(e);if(i==9){throw"Invalid 'windowBits' code"}e.maxRingBufferSize=1<=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}if(ee(e,1)!=0){var t=ee(e,3);if(t==0){return 1}else{return ee(e,t)+(1<=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}e.inputEnd=ee(e,1);e.metaBlockLength=0;e.isUncompressed=0;e.isMetadata=0;if(e.inputEnd!=0&&ee(e,1)!=0){return}var t=ee(e,2)+4;if(t==7){e.isMetadata=1;if(ee(e,1)!=0){throw"Corrupted reserved bit"}var i=ee(e,2);if(i==0){return}for(var n=0;n=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}var a=ee(e,8);if(a==0&&n+1==i&&i>1){throw"Exuberant nibble"}e.metaBlockLength|=a<=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}var a=ee(e,4);if(a==0&&n+1==t&&t>4){throw"Exuberant nibble"}e.metaBlockLength|=a<>>i.bitOffset;t+=n&255;var a=e[t]>>16;var o=e[t]&65535;if(a<=8){i.bitOffset+=a;return o}t+=o;var r=(1<>>8;i.bitOffset+=(e[t]>>16)+8;return e[t]&65535}function l(e,t,i){if(i.bitOffset>=16){i.accumulator32=i.shortBuffer[i.halfOffset++]<<16|i.accumulator32>>>16;i.bitOffset-=16}var n=E(e,t,i);var a=r[n];if(i.bitOffset>=16){i.accumulator32=i.shortBuffer[i.halfOffset++]<<16|i.accumulator32>>>16;i.bitOffset-=16}return o[n]+(a<=16?ee(i,a):te(i,a))}function M(e,t,i){if(e<16){i+=n[e];i&=3;return t[i]+a[e]}return e-16+1}function c(e,t){var i=e[t];for(;t>0;t--){e[t]=e[t-1]}e[0]=i}function p(e,t){var i=new Int32Array(256);for(var n=0;n<256;n++){i[n]=n}for(var n=0;n0){if(n.halfOffset>2030){K(n)}if(n.bitOffset>=16){n.accumulator32=n.shortBuffer[n.halfOffset++]<<16|n.accumulator32>>>16;n.bitOffset-=16}var d=n.accumulator32>>>n.bitOffset&31;n.bitOffset+=c[d]>>16;var h=c[d]&65535;if(h<16){r=0;i[a++]=h;if(h!=0){o=h;l-=32768>>h}}else{var f=h-14;var u=0;if(h==16){u=o}if(s!=u){r=0;s=u}var p=r;if(r>0){r-=2;r<<=f}if(n.bitOffset>=16){n.accumulator32=n.shortBuffer[n.halfOffset++]<<16|n.accumulator32>>>16;n.bitOffset-=16}r+=ee(n,f)+3;var m=r-p;if(a+m>t){throw"symbol + repeatDelta > numSymbols"}for(var g=0;g2030){K(n)}var r=new Int32Array(e);if(n.bitOffset>=16){n.accumulator32=n.shortBuffer[n.halfOffset++]<<16|n.accumulator32>>>16;n.bitOffset-=16}o=ee(n,2);if(o==1){var s=e-1;var l=0;var c=new Int32Array(4);var d=ee(n,2)+1;while(s!=0){s>>=1;l++}for(var h=0;h=16){n.accumulator32=n.shortBuffer[n.halfOffset++]<<16|n.accumulator32>>>16;n.bitOffset-=16}c[h]=ee(n,l)%e;r[c[h]]=2}r[c[0]]=1;switch(d){case 2:r[c[1]]=1;break;case 4:if(ee(n,1)==1){r[c[2]]=3;r[c[3]]=3}else{r[c[0]]=2}break;default:break}a=y(c,d)}else{var f=new Int32Array(18);var u=32;var p=0;for(var h=o;h<18&&u>0;h++){var m=$[h];if(n.bitOffset>=16){n.accumulator32=n.shortBuffer[n.halfOffset++]<<16|n.accumulator32>>>16;n.bitOffset-=16}var g=n.accumulator32>>>n.bitOffset&15;n.bitOffset+=b[g]>>16;var P=b[g]&65535;f[m]=P;if(P!=0){u-=32>>P;p++}}if(u!=0&&p!=1){a=0}v(f,e,r,n)}if(a==0){throw"Can't readHuffmanCode"}V(t,i,8,r,e)}function g(e,t,i){if(i.halfOffset>2030){K(i)}var n=u(i)+1;if(n==1){t.fill(0,0,e);return n}if(i.bitOffset>=16){i.accumulator32=i.shortBuffer[i.halfOffset++]<<16|i.accumulator32>>>16;i.bitOffset-=16}var a=ee(i,1);var o=0;if(a!=0){o=ee(i,4)+1}var r=new Int32Array(1080);m(n+o,r,0,i);for(var s=0;s2030){K(i)}if(i.bitOffset>=16){i.accumulator32=i.shortBuffer[i.halfOffset++]<<16|i.accumulator32>>>16;i.bitOffset-=16}var l=E(r,0,i);if(l==0){t[s]=0;s++}else if(l<=o){if(i.bitOffset>=16){i.accumulator32=i.shortBuffer[i.halfOffset++]<<16|i.accumulator32>>>16;i.bitOffset-=16}var c=(1<=e){throw"Corrupted context map"}t[s]=0;s++;c--}}else{t[s]=l-o;s++}}if(i.bitOffset>=16){i.accumulator32=i.shortBuffer[i.halfOffset++]<<16|i.accumulator32>>>16;i.bitOffset-=16}if(ee(i,1)==1){p(t,e)}return n}function P(e,t,i){var n=e.rings;var a=4+t*2;if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}var o=E(e.blockTrees,t*1080,e);var r=l(e.blockTrees,(t+3)*1080,e);if(o==1){o=n[a+1]+1}else if(o==0){o=n[a]}else{o-=2}if(o>=i){o-=i}n[a]=n[a+1];n[a+1]=o;return r}function R(e){e.literalBlockLength=P(e,0,e.numLiteralBlockTypes);var t=e.rings[5];e.contextMapSlice=t<<6;e.literalTreeIndex=e.contextMap[e.contextMapSlice]&255;e.literalTree=e.hGroup0[e.literalTreeIndex];var i=e.contextModes[t];e.contextLookupOffset1=i<<9;e.contextLookupOffset2=e.contextLookupOffset1+256}function F(e){e.commandBlockLength=P(e,1,e.numCommandBlockTypes);e.treeCommandOffset=e.hGroup1[e.rings[7]]}function N(e){e.distanceBlockLength=P(e,2,e.numDistanceBlockTypes);e.distContextMapSlice=e.rings[9]<<2}function i(e){var t=e.maxRingBufferSize;if(t>e.expectedTotalSize){var i=e.expectedTotalSize;while(t>>1>i){t>>=1}if(e.inputEnd==0&&t<16384&&e.maxRingBufferSize>=16384){t=16384}}if(t<=e.ringBufferSize){return}var n=t+37;var a=new Int8Array(n);if(e.ringBuffer.length!=0){a.set(e.ringBuffer.subarray(0,0+e.ringBufferSize),0)}e.ringBuffer=a;e.ringBufferSize=t}function U(e){if(e.inputEnd!=0){e.nextRunningState=9;e.runningState=11;return}e.hGroup0=new Int32Array(0);e.hGroup1=new Int32Array(0);e.hGroup2=new Int32Array(0);if(e.halfOffset>2030){K(e)}t(e);if(e.metaBlockLength==0&&e.isMetadata==0){return}if(e.isUncompressed!=0||e.isMetadata!=0){oe(e);e.runningState=e.isMetadata!=0?4:5}else{e.runningState=2}if(e.isMetadata!=0){return}e.expectedTotalSize+=e.metaBlockLength;if(e.expectedTotalSize>1<<30){e.expectedTotalSize=1<<30}if(e.ringBufferSize2030){K(e)}if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}e.distancePostfixBits=ee(e,2);e.numDirectDistanceCodes=16+(ee(e,4)<=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}e.contextModes[i]=ee(e,2)}if(e.halfOffset>2030){K(e)}}e.contextMap=new Int8Array(e.numLiteralBlockTypes<<6);var a=g(e.numLiteralBlockTypes<<6,e.contextMap,e);e.trivialLiteralContext=1;for(var o=0;o>6){e.trivialLiteralContext=0;break}}e.distContextMap=new Int8Array(e.numDistanceBlockTypes<<2);var r=g(e.numDistanceBlockTypes<<2,e.distContextMap,e);e.hGroup0=w(256,a,e);e.hGroup1=w(704,e.numCommandBlockTypes,e);e.hGroup2=w(t,r,e);e.contextMapSlice=0;e.distContextMapSlice=0;e.contextLookupOffset1=e.contextModes[0]<<9;e.contextLookupOffset2=e.contextLookupOffset1+256;e.literalTreeIndex=0;e.literalTree=e.hGroup0[0];e.treeCommandOffset=e.hGroup1[0];e.rings[4]=1;e.rings[5]=0;e.rings[6]=1;e.rings[7]=0;e.rings[8]=1;e.rings[9]=0}function W(e){var t=e.ringBuffer;if(e.metaBlockLength<=0){ae(e);e.runningState=1;return}var i=pe(e.ringBufferSize-e.pos,e.metaBlockLength);se(e,t,e.pos,i);e.metaBlockLength-=i;e.pos+=i;if(e.pos==e.ringBufferSize){e.nextRunningState=5;e.runningState=11;return}ae(e);e.runningState=1}function G(e){var t=pe(e.outputLength-e.outputUsed,e.ringBufferBytesReady-e.ringBufferBytesWritten);if(t!=0){e.output.set(e.ringBuffer.subarray(e.ringBufferBytesWritten,e.ringBufferBytesWritten+t),e.outputOffset+e.outputUsed);e.outputUsed+=t;e.ringBufferBytesWritten+=t}if(e.outputUsed2030){K(e)}if(e.commandBlockLength==0){F(e)}e.commandBlockLength--;if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}var a=E(e.hGroup1,e.treeCommandOffset,e);var o=a>>>6;e.distanceCode=0;if(o>=2){o-=2;e.distanceCode=-1}var r=L[o]+(a>>>3&7);if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}var s=I[r];var l=s<=16?ee(e,s):te(e,s);e.insertLength=T[r]+l;var c=D[o]+(a&7);if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}var d=z[c];var h=d<=16?ee(e,d):te(e,d);e.copyLength=q[c]+h;e.j=0;e.runningState=6;case 6:if(e.trivialLiteralContext!=0){while(e.j2030){K(e)}if(e.literalBlockLength==0){R(e)}e.literalBlockLength--;if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}n[e.pos]=E(e.hGroup0,e.literalTree,e);e.pos++;e.j++;if(e.pos>=t){e.nextRunningState=6;e.runningState=11;break}}}else{var f=n[e.pos-1&i]&255;var u=n[e.pos-2&i]&255;while(e.j2030){K(e)}if(e.literalBlockLength==0){R(e)}var p=e.contextMap[e.contextMapSlice+(ce[e.contextLookupOffset1+f]|ce[e.contextLookupOffset2+u])]&255;e.literalBlockLength--;u=f;if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}f=E(e.hGroup0,e.hGroup0[p],e);n[e.pos]=f;e.pos++;e.j++;if(e.pos>=t){e.nextRunningState=6;e.runningState=11;break}}}if(e.runningState!=6){continue}e.metaBlockLength-=e.insertLength;if(e.metaBlockLength<=0){e.runningState=3;continue}if(e.distanceCode<0){if(e.halfOffset>2030){K(e)}if(e.distanceBlockLength==0){N(e)}e.distanceBlockLength--;if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}e.distanceCode=E(e.hGroup2,e.hGroup2[e.distContextMap[e.distContextMapSlice+(e.copyLength>4?3:e.copyLength-2)]&255],e);if(e.distanceCode>=e.numDirectDistanceCodes){e.distanceCode-=e.numDirectDistanceCodes;var m=e.distanceCode&e.distancePostfixMask;e.distanceCode>>>=e.distancePostfixBits;var g=(e.distanceCode>>>1)+1;var P=(2+(e.distanceCode&1)<=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}var $=g<=16?ee(e,g):te(e,g);e.distanceCode=e.numDirectDistanceCodes+m+(P+$<e.maxDistance){e.runningState=8;continue}if(e.distanceCode>0){e.rings[e.distRbIdx&3]=e.distance;e.distRbIdx++}if(e.copyLength>e.metaBlockLength){throw"Invalid backward reference"}e.j=0;e.runningState=7;case 7:var b=e.pos-e.distance&i;var v=e.pos;var y=e.copyLength-e.j;var X=b+y;var w=v+y;if(Xv&&w>b){for(var Y=0;Y=t){e.nextRunningState=7;e.runningState=11;break}}}if(e.runningState==7){e.runningState=3}continue;case 8:if(e.copyLength>=4&&e.copyLength<=24){var P=S[e.copyLength];var Q=e.distance-e.maxDistance-1;var k=A[e.copyLength];var x=(1<>>k;P+=C*e.copyLength;if(B<121){var j=J(n,e.pos,O,P,e.copyLength,B);e.pos+=j;e.metaBlockLength-=j;if(e.pos>=t){e.nextRunningState=3;e.runningState=11;continue}}else{throw"Invalid backward reference"}}else{throw"Invalid backward reference"}e.runningState=3;continue;case 4:while(e.metaBlockLength>0){if(e.halfOffset>2030){K(e)}if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}ee(e,8);e.metaBlockLength--}e.runningState=1;continue;case 5:W(e);continue;case 11:e.ringBufferBytesReady=pe(e.pos,e.ringBufferSize);e.runningState=12;case 12:if(G(e)==0){return}if(e.pos>=e.maxBackwardDistance){e.maxDistance=e.maxBackwardDistance}if(e.pos>=e.ringBufferSize){if(e.pos>e.ringBufferSize){n.copyWithin(0,e.ringBufferSize,e.pos)}e.pos&=i;e.ringBufferBytesWritten=0}e.runningState=e.nextRunningState;continue;default:throw"Unexpected state "+e.runningState}}if(e.runningState==9){if(e.metaBlockLength<0){throw"Invalid metablock length"}oe(e);Z(e,1)}}var Q=new Int32Array(363);var k=new Int8Array(217);var x=new Int32Array(51);function e(e,t,i,n,a){var o=n.length;var r=1;for(var s=0;s#\n#]# for # a # that #. # with #\'# from # by #. The # on # as # is #ing #\n\t#:#ed #(# at #ly #="# of the #. This #,# not #er #al #=\'#ful #ive #less #est #ize #ous #'," !! ! , *! &! \" ! ) * * - ! # ! #!*! + ,$ ! - % . / # 0 1 . \" 2 3!* 4% ! # / 5 6 7 8 0 1 & $ 9 + : ; < ' != > ?! 4 @ 4 2 & A *# ( B C& ) % ) !*# *-% A +! *. D! %' & E *6 F G% ! *A *% H! D I!+! J!+ K +- *4! A L!*4 M N +6 O!*% +.! K *G P +%( ! G *D +D Q +# *K!*G!+D!+# +G +A +4!+% +K!+4!*D!+K!*K")}function J(e,t,i,n,a,o){var r=t;var s=3*o;var l=x[Q[s]];var c=Q[s+1];var d=x[Q[s+2]];while(k[l]!=0){e[r++]=k[l++]}var h=c>=12?c-11:0;if(h>a){h=a}n+=h;a-=h;a-=c<=9?c:0;var f=a;while(f>0){e[r++]=i[n++];f--}if(c==11||c==10){var u=r-a;if(c==10){a=1}while(a>0){var p=e[u]&255;if(p<192){if(p>=97&&p<=122){e[u]^=32}u+=1;a-=1}else if(p<224){e[u+1]^=32;u+=2;a-=2}else{e[u+2]^=5;u+=3;a-=3}}}while(k[d]!=0){e[r++]=k[d++]}return r-t}function C(e,t){var i=1<>=1}return(e&i-1)+i}function B(e,t,i,n,a){do{n-=i;e[t+n]=a}while(n>0)}function j(e,t,i){var n=1<0;s[d]--){B(e,t+o,p,f,d<<16|r[c++]);o=C(o,d)}}var m=u-1;var g=-1;var P=t;for(var d=i+1,p=2;d<=15;d++,p<<=1){for(;s[d]>0;s[d]--){if((o&m)!=g){P+=f;h=j(s,d,i);f=1<>i),p,f,d-i<<16|r[c++]);o=C(o,d)}}}function K(e){if(e.endOfStreamReached!=0){if(re(e)>=-2){return}throw"No more input"}var t=e.halfOffset<<1;var i=4096-t;e.byteBuffer.copyWithin(0,t,4096);e.halfOffset=0;while(i<4096){var n=4096-i;var a=me(e.input,e.byteBuffer,i,n);if(a<=0){e.endOfStreamReached=1;e.tailBytes=i;i+=1;break}i+=a}le(e,i)}function Z(e,t){if(e.endOfStreamReached==0){return}var i=(e.halfOffset<<1)+(e.bitOffset+7>>3)-4;if(i>e.tailBytes){throw"Read after end"}if(t!=0&&i!=e.tailBytes){throw"Unused bytes after end"}}function ee(e,t){var i=e.accumulator32>>>e.bitOffset&(1<>>16;e.bitOffset-=16;return i|ee(e,t-16)<<16}function ie(e){e.byteBuffer=new Int8Array(4160);e.accumulator32=0;e.shortBuffer=new Int16Array(2080);e.bitOffset=32;e.halfOffset=2048;e.endOfStreamReached=0;ne(e)}function ne(e){if(e.halfOffset>2030){K(e)}Z(e,0);e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16;e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}function ae(e){if(e.bitOffset==32){ne(e)}}function oe(e){var t=32-e.bitOffset&7;if(t!=0){var i=ee(e,t);if(i!=0){throw"Corrupted padding bits"}}}function re(e){var t=2048;if(e.endOfStreamReached!=0){t=e.tailBytes+1>>1}return t-e.halfOffset}function se(e,t,i,n){if((e.bitOffset&7)!=0){throw"Unaligned copyBytes"}while(e.bitOffset!=32&&n!=0){t[i++]=e.accumulator32>>>e.bitOffset;e.bitOffset+=8;n--}if(n==0){return}var a=pe(re(e),n>>1);if(a>0){var o=e.halfOffset<<1;var r=a<<1;t.set(e.byteBuffer.subarray(o,o+r),i);i+=r;n-=r;e.halfOffset+=a}if(n==0){return}if(re(e)>0){if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}while(n!=0){t[i++]=e.accumulator32>>>e.bitOffset;e.bitOffset+=8;n--}Z(e,0);return}while(n>0){var s=me(e.input,t,i,n);if(s==-1){throw"Unexpected end of input"}i+=s;n-=s}}function le(e,t){var i=e.byteBuffer;var n=t>>1;var a=e.shortBuffer;for(var o=0;o>2;e[1792+n]=2+(n>>6)}for(var n=0;n<128;++n){e[1024+n]=4*(t.charCodeAt(n)-32)}for(var n=0;n<64;++n){e[1152+n]=n&1;e[1216+n]=2+(n&1)}var a=1280;for(var o=0;o<19;++o){var r=o&3;var s=i.charCodeAt(o)-32;for(var n=0;nstopelseliestourpack.gifpastcss?graymean>rideshotlatesaidroadvar feeljohnrickportfast\'UA-deadpoorbilltypeU.S.woodmust2px;Inforankwidewantwalllead[0];paulwavesure$(\'#waitmassarmsgoesgainlangpaid!-- lockunitrootwalkfirmwifexml"songtest20pxkindrowstoolfontmailsafestarmapscorerainflowbabyspansays4px;6px;artsfootrealwikiheatsteptriporg/lakeweaktoldFormcastfansbankveryrunsjulytask1px;goalgrewslowedgeid="sets5px;.js?40pxif (soonseatnonetubezerosentreedfactintogiftharm18pxcamehillboldzoomvoideasyringfillpeakinitcost3px;jacktagsbitsrolleditknewnear\x3c!--growJSONdutyNamesaleyou lotspainjazzcoldeyesfishwww.risktabsprev10pxrise25pxBlueding300,ballfordearnwildbox.fairlackverspairjunetechif(!pickevil$("#warmlorddoespull,000ideadrawhugespotfundburnhrefcellkeystickhourlossfuel12pxsuitdealRSS"agedgreyGET"easeaimsgirlaids8px;navygridtips#999warsladycars); }php?helltallwhomzh:e*/\r\n 100hall.\n\nA7px;pushchat0px;crew*/ericmostguidbelldeschairmathatom/imgRluckcent000;tinygonehtmlselldrugFREEnodenick?id=losenullvastwindRSS wearrelybeensamedukenasacapewishgulfT23:hitsslotgatekickblurthey15px\'\'););">msiewinsbirdsortbetaseekT18:ordstreemall60pxfarmb\0sboys[0].\');"POSTbearkids);}}marytend(UK)quadzh:f-siz----prop\');\rliftT19:viceandydebt>RSSpoolneckblowT16:doorevalT17:letsfailoralpollnovacolsgene b\0softrometillrosspourfadepinkmini)|!(minezh:hbarshear00);milk --\x3eironfreddiskwentsoilputs/js/holyT22:ISBNT20:adamseesjson\', \'contT21: RSSloopasiamoonsoulLINEfortcartT14:80px!--<9px;T04:mike:46ZniceinchYorkricezh:d\'));puremageparatonebond:37Z_of_\']);000,zh:gtankyardbowlbush:56ZJava30px\n|}\n%C3%:34ZjeffEXPIcashvisagolfsnowzh:iquer.csssickmeatmin.binddellhirepicsrent:36ZHTTP-201fotowolfEND xbox:54ZBODYdick;\n}\nexit:35Zvarsbeat\'});diet999;anne}}[i].LangkmB2wiretoysaddssealalex;\n\t}echonine.org005)tonyjewssandlegsroof000) 200winegeardogsbootgarycutstyletemption.xmlcockgang$(\'.50pxPh.Dmiscalanloandeskmileryanunixdisc);}\ndustclip).\n\n70px-200DVDs7]>sonyguysfuckpipe|-\n!002)ndow[1];[];\nLog salt\r\n\t\tbangtrimbath){\r\n00px\n});ko:lfeesad>\rs:// [];tollplug(){\n{\r\n .js\'200pdualboat.JPG);\n}quot);\n\n\');\n\r\n}\r201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037201320122011201020092008200720062005200420032002200120001999199819971996199519941993199219911990198919881987198619851984198319821981198019791978197719761975197419731972197119701969196819671966196519641963196219611960195919581957195619551954195319521951195010001024139400009999comomC!sesteestaperotodohacecadaaC1obiendC-aasC-vidacasootroforosolootracualdijosidograntipotemadebealgoquC)estonadatrespococasabajotodasinoaguapuesunosantediceluisellamayozonaamorpisoobraclicellodioshoracasiP7P0P=P0P>PP>QP8P7P=P>P4P>QP>P6P5P>P=P8QPP0P5P5P1Q\vPP2Q\vP2P>PP>P>P1PP>P;P8P=P8P P$PP5PQ\vQQ\vPP=P8Pthing.org/multiheardPowerstandtokensolid(thisbringshipsstafftriedcallsfullyfactsagentThis //--\x3eadminegyptEvent15px;Emailtrue"crossspentblogsbox">notedleavechinasizesguestrobotheavytrue,sevengrandcrimesignsawaredancephase>\x3c!--en_US'200px_namelatinenjoyajax.ationsmithU.S. holdspeterindianav">chainscorecomesdoingpriorShare1990sromanlistsjapanfallstrialowneragree abusealertopera"-//WcardshillsteamsPhototruthclean.php?saintmetallouismeantproofbriefrow">genretrucklooksValueFrame.net/--\x3e\n\n\x3c!--POST"ocean floorspeakdepth sizebankscatchchart20px;aligndealswould50px;url="parksmouseMost ...drugs\x3c!-- aprilidealallenexactforthcodeslogicView seemsblankports (200saved_linkgoalsgrantgreekhomesringsrated30px;whoseparse();" Blocklinuxjonespixel\');">);if(-leftdavidhorseFocusraiseboxesTrackementbar">.src=toweralt="cablehenry24px;setupitalysharpminortastewantsthis.resetwheelgirls/css/100%;clubsstuffbiblevotes 1000korea});\r\nbandsqueue= {};80px;cking{\r\n\t\taheadclockirishlike ratiostatsForm"yahoo)[0];AboutfindsdebugtasksURL =cells})();12px;primetellsturns0x600.jpg"spainbeachtaxesmicroangel--\x3e\r\nname=diegopage swiss--\x3e\n\n#fff;">Log.com"treatsheet) && 14px;sleepntentfiledja:cid="cName"worseshots-box-delta\n<bears:48Z spendbakershops= "";php">ction13px;brianhellosize=o=%2F joinmaybe , fjsimg" ")[0]MTopBType"newlyDanskczechtrailknowsfaq">zh-cn10);\n-1");type=bluestrulydavis.js\';>\r\n\r\nform jesus100% menu.\r\n\t\r\nwalesrisksumentddingb-likteachgif" vegasdanskeestishqipsuomisobredesdeentretodospuedeaC1osestC!tienehastaotrospartedondenuevohacerformamismomejormundoaquC-dC-assC3loayudafechatodastantomenosdatosotrassitiomuchoahoralugarmayorestoshorastenerantesfotosestaspaC-snuevasaludforosmedioquienmesespoderchileserC!vecesdecirjosC)estarventagrupohechoellostengoamigocosasnivelgentemismaairesjuliotemashaciafavorjuniolibrepuntobuenoautorabrilbuenatextomarzosaberlistaluegocC3moenerojuegoperC:haberestoynuncamujervalorfueralibrogustaigualvotoscasosguC-apuedosomosavisousteddebennochebuscafaltaeurosseriedichocursoclavecasasleC3nplazolargoobrasvistaapoyojuntotratavistocrearcampohemoscincocargopisosordenhacenC!readiscopedrocercapuedapapelmenorC:tilclarojorgecalleponertardenadiemarcasigueellassiglocochemotosmadreclaserestoniC1oquedapasarbancohijosviajepabloC)stevienereinodejarfondocanalnorteletracausatomarmanoslunesautosvillavendopesartipostengamarcollevapadreunidovamoszonasambosbandamariaabusomuchasubirriojavivirgradochicaallC-jovendichaestantalessalirsuelopesosfinesllamabuscoC)stalleganegroplazahumorpagarjuntadobleislasbolsabaC1ohablaluchaCreadicenjugarnotasvalleallC!cargadolorabajoestC)gustomentemariofirmacostofichaplatahogarartesleyesaquelmuseobasespocosmitadcielochicomiedoganarsantoetapadebesplayaredessietecortecoreadudasdeseoviejodeseaaguas"domaincommonstatuseventsmastersystemactionbannerremovescrollupdateglobalmediumfilternumberchangeresultpublicscreenchoosenormaltravelissuessourcetargetspringmodulemobileswitchphotosborderregionitselfsocialactivecolumnrecordfollowtitle>eitherlengthfamilyfriendlayoutauthorcreatereviewsummerserverplayedplayerexpandpolicyformatdoublepointsseriespersonlivingdesignmonthsforcesuniqueweightpeopleenergynaturesearchfigurehavingcustomoffsetletterwindowsubmitrendergroupsuploadhealthmethodvideosschoolfutureshadowdebatevaluesObjectothersrightsleaguechromesimplenoticesharedendingseasonreportonlinesquarebuttonimagesenablemovinglatestwinterFranceperiodstrongrepeatLondondetailformeddemandsecurepassedtoggleplacesdevicestaticcitiesstreamyellowattackstreetflighthiddeninfo">openedusefulvalleycausesleadersecretseconddamagesportsexceptratingsignedthingseffectfieldsstatesofficevisualeditorvolumeReportmuseummoviesparentaccessmostlymother" id="marketgroundchancesurveybeforesymbolmomentspeechmotioninsidematterCenterobjectexistsmiddleEuropegrowthlegacymannerenoughcareeransweroriginportalclientselectrandomclosedtopicscomingfatheroptionsimplyraisedescapechosenchurchdefinereasoncorneroutputmemoryiframepolicemodelsNumberduringoffersstyleskilledlistedcalledsilvermargindeletebetterbrowselimitsGlobalsinglewidgetcenterbudgetnowrapcreditclaimsenginesafetychoicespirit-stylespreadmakingneededrussiapleaseextentScriptbrokenallowschargedividefactormember-basedtheoryconfigaroundworkedhelpedChurchimpactshouldalwayslogo" bottomlist">){var prefixorangeHeader.push(couplegardenbridgelaunchReviewtakingvisionlittledatingButtonbeautythemesforgotSearchanchoralmostloadedChangereturnstringreloadMobileincomesupplySourceordersviewed courseAbout islandPhilipawardshandleimportOfficeregardskillsnationSportsdegreeweekly (e.g.behinddoctorloggedunitedbeyond-scaleacceptservedmarineFootercamera\n_form"leavesstress" />\r\n.gif" onloadloaderOxfordsistersurvivlistenfemaleDesignsize="appealtext">levelsthankshigherforcedanimalanyoneAfricaagreedrecentPeople wonderpricesturned|| {};main">inlinesundaywrap">failedcensusminutebeaconquotes150px|estateremoteemail"linkedright;signalformal1.htmlsignupprincefloat:.png" forum.AccesspaperssoundsextendHeightsliderUTF-8"& Before. WithstudioownersmanageprofitjQueryannualparamsboughtfamousgooglelongeri++) {israelsayingdecidehome">headerensurebranchpiecesblock;statedtop">boston.test(avatartested_countforumsschemaindex,filledsharesreaderalert(appearSubmitline">body">\n* TheThoughseeingjerseyNews\nSystem DavidcancertablesprovedApril reallydriveritem">more">boardscolorscampusfirst || [];media.guitarfinishwidth:showedOther .php" assumelayerswilsonstoresreliefswedenCustomeasily your String\n\nWhiltaylorclear:resortfrenchthough") + "buyingbrandsMembername">oppingsector5px;">vspacepostermajor coffeemartinmaturehappenkansaslink">Images=falsewhile hspace0& \n\nIn powerPolski-colorjordanBottomStart -count2.htmlnews">01.jpgOnline-rightmillerseniorISBN 00,000 guidesvalue)ectionrepair.xml" rights.html-blockregExp:hoverwithinvirginphones \rusing \n\tvar >\');\n\t\n\nbahasabrasilgalegomagyarpolskisrpskiX1X/Y\bd8-fg.\0d=g9i+d?!f/d8-e=f\bd;,d8\0d8*e,e8g.!gh.:ee/d;%f\re\n!f6i4d8*d::d:\'eh*e71d<d8f%g\ve7%d=hg3;f2!f\tg=g+f\t\0f\th/h.:d8-e?fg+ g(f\b7i&i!5d=h\0f\n\0f/i.i"g8e3d8\vh==fg4"d=?g(h=/d;6e(g:?d8;i"h5fh\'i"ee$\rf3(e\fg=g;f6hee.9f(h\re8e:f6\bf/g):i4ee8d;\0d9\be%=e\vgf4;e>g\tee1e&ff\t\vf:f0i;f\0f0f9e<e\fd:,fd>e3d:f4e$h?d8*g3;g;g%if88f\be9?e\ne6d;eh!(e.\te(g,,d8\0d<eh?h!\fg9e;g\t\bfg5e-d8g\fh.>h.!e\rh49fh2e\n e%f4;e\n(d;d;,eee\re."g0e(d8\nf57e&d=e72g;gh(\0h/&g;g$>e\f:g;e=f,g+i\0h&d;7f f%e=e.6e;:h.>f\ve\vih/;f3e>\vd=\rg=.g;f5i\0\tf\v)h?f 7e=e\t\re\bg1;fh!\fe d8:d:$ff\0ei3d9d8\rh=i\0h?h!\fd8g\'f\n\0e/h=h.>e$e\bd=e$\'e.6g$>d<g g)6d8d8e(i(i!9g.h?i\fh?f/e<\0e\'\vfe5g5hfd;6eg\t\fe8.e\n)fe\fh5f:e$\'e-&e-&d9 e0e\0f5h\'\bf\nh5e7%g(\vh&f1f\0d9\bf6e\0e\nh=d8;h&g.e\t\rh5h./ee8f9f3g5e=1f\vhe#0fd;;d=e%e:7f0f\r.g>e=f1=h=&d;\vg;\rd=f/d:$f5gd:\'f\t\0d;%g5h/f>g$:d8\0d:e\rd=\rd::ee\bfe0e>ff88e7%e7e-&gg3;e\bg=e\ve8e-e/g i"if\'e\b6e0e\f:e:f,e(e=g=d8\ni\rh&g,,d:\fef,"h?e%e\vfh?d:h\0h/eg0e9h.-d;%d8\nf?e:f\bd8:g/e"i&f8/e\ff6e(1d9ei\0d8\0e.e<\0ed=ef ef,"h?h\'#e3e0f9d8\0d8\vd;%e\nh4#d;;f\bh\0e."f\b7d;#h!(g\'/e\be%3d::f0g i\0e.e:g0g&;g:?e:g(e\bh!(d8\re\fg<h>g;h.!f%h/"d8\rh&f\te3f:fe>\be$f-f>g;g;f?g-g4f%h=e\nf%f:fig\ve\b0g-i(e3i.d8e\f:ie88h\v1h/-g>e:&e8\ffg>e%3f/h>g%h/h\'e.e;:h..i(i(fh\'g2>e=)f%f,fi+eh(\0f9i"e:ie$gfie=1g\ti6h!\fh?f\te\bd:+g\t)eg;h%f7;e\n d8e.6h?g\'\rh/i"h57f%d8e\n!e,e\nh.0e=g.\0d;\vh4(ig7d::e=1e\re<g(f\n%e\ni(e\be?+i\0e(h/"f6e0f3(fg3h/7e-&f !e:h/%ee2e*f/h?eh4-d90e\rg\'0d8:d:f\be\nh/4fd>e:e-)e-d8i"g(\ve:d8\0h\b,fe!e*f\te6e.d?f\n$h\0\fd8d;\ne$)g*e#e\n(f\0g\n6f\0g\t9e\b+h.$d8:e?i!;f4f0e0h/4f\be\0d=d8:e*d=e\ff\v,i#d9\bd8\0f 7e=ef/e&f 9f\r.g5h\'e-&i"e7f\th?g(\vg1d:d::f\t\re:f%d8\rh?f-#e(fffd:\ve3g3;f i"ee\n!h>e%d8\0g4e:g!\0fe-&d:h\'#e;:g-g;fe(gi\0g%h.!e\be/9d:h\t:f/g8e\feggge;:g+\vg-\tg:\'g1;e\vg;i*\fe.g0e\b6d=f%h*f g->d;%d8\vee\bf f3e6d8-e\0\vd::d8\0e\bf\fe\re3i-ie"g,,d8\te3f3(e f-$g\'g\tf71e3ed8e9?e7f%fi+g:\'f\0h?g;h!\fd8:d:$i\0h/d;7h\'\te>g2>e\re.6e:-e.\ff\bfh\'\te.\th#e>e\b0i.d;6e\b6e:&i#eh=g6h=,h==f\n%d;7h.0h\0f9f!\bh!\ff?d::f0g(ed8h%?fe:ie:g6ed;f,>g-g9d;%e\t\re.\fe(ee8h.>g=.i"e/g%h7e>e\b)g(g;\'g;-d= d;,h?d9\bf(!e<h/-h(\0h=e$ihf\rd=i#f d9&f\tf\bf5\vh/g\';e\n(f\t\rh=e3e.h!g%(d8\rf-i\0f1d8\re>e\nf3d9\vi4ig(h%i\0f\nh/\tg.f g\b1ffe=1f\td:h$h#=fe-&f:d<f0e-h#d?.h4-g\t)efe(i"g2>ee6e.d:\vff04e93fg$:d8\ne8h0"h0"f.i\0fe8\bd8\nd< g1;e\b+f-\ff2f\v%f\te\bf0i\rd;6e*h&f6d;#h3h(\nh>>e\b0d::gh."ih\0e8\be1g$:e?gh44e-g62g+d8;i!\fh*g6g:\'e\b+g.\0e\rf9i)i#d:f%h/4f\te<\0d;#g e\b i$h/e\b8h\ng.i\rg9f,!f8e$e0h\'e\bh5if\t>e\b0d;%ee$\'e(d8;i!5f\0d=3eg-e$)d8\vd?ig0d;#f#\0f%f\ng%(e0f6f2f\tf-#e88gh3d;#gg.e=e,e<\0e$\re\b6ih\re98g&g\t\bf,e="f\bee$h!\ffee\b0f\0f3f\0f 7e\rh..h.$h/f\0e%=d:\'gf\f\tg\'f\rh#e9?d8e\n(f<+ih4-f0f\t\vg;e>i"f?eh\0f?f2;e.9fe$)e0e\n*e\nd::d;,e\rg:\'i\0e:&d::g\t)h0f4f5h!\fi\0 f\bfe-i)e=h48fe<\0e1g8ih!(g0e=1h\'e&f-$g>e.9e$\'e0f\n%if!f,>e?fh.8e$f3h\'e.6e1d9&e:h?f%g+\ve\r3d8>f\n%f\n\0e7\'e%%h?g;e%d;%f%gh.:d:\vd;6h*g1d8-e\re\ne,e&\be&\bgf-#d8\rie(fe\be\fd;7e\0e7&e3h!d;=g-f!\be.ig5d?!g;gge=e.#d< d;;e\n!f-#e<g\t9h\t2d8\vf%e\rd<e*h=e=g6i\rf0e\'e.9f\fe/ g(\ve\f;gg;h?h?e;d9\ve\t\rf6e%e94e:&fe?g>d8=f\0i+g;if*f%e\n e7%e\rh4#fg(\vg\t\beh:+d=i\re:e:e.f\bf,e="e<eh1e:e9d8f9i.g.1e\rd:,f1h\fee>h\fd=\rg8d?!i!5i"e\big=i!5g!.e.e>d>\vg=e\0g\'/fih//g.ge.h4f:e3i#i)f\bfgf/e. g\t)i$d:h)h+g>ge\nf6f1h4-g+g9e?g+%f/e$)d8-e$.h.$h/f/d8*e$)f4%e-d=e0g#g;4f\n$f,i!5d8*f\0\'e.f9e88h\'g8f:f\bg%e:e=e>\ve8\bf9d>?f !e-h!e8f\b?e1\vf g.ee7%e/ee<h57f9eg,,ed<h.!h**fig\'e.e.h\'h\ff6\bh49e1e\fe?h.0d=g3;e8&f%e\re-ge\n gee\b0d:\ff\t\ve$\'if\bd::f0ie1d:+e\f:ee%3e-)ee\bf\t\0e(g;fi\0d?!h6g:\'i\rg=.e=f6d<g\'\0f\0\'ff\b?d:\'i\nf\b2e:e#fd:$e01d8d?e%g(\ve:&ef0d:\vd8f4d8*e11d8ffg\t9f.\ne\bi!fe0\ve1d:i(f\b7h4"e\n!e#0i3e\ne6h4"g;ef\fe92i(f\bg+\ve\b)g\nh\0hf\bi=e\fh#g(f\b6f/h5fff\vee.\ff4gf/ge/g"i#g;?h\t2g(3e.g;\bd:gg\t)d>f1fg\ve\nid8%i\rf08h?egf\tig+d:\te/9h1!h49g(d8\re%=g;e/9e\re\bd?h?g9h/e=1i3d<e\n?d8\re0f,#h5e96d8f\tg9f9ee(f0d?!g(h.>f=e="h1!h5f eeg;d8\0e:g\t\bf\ti\0 g"ef&e5g(d:d?ge g4 d8-e\ve-e(h44e>f\0fi?fe#d;7gh4"e:e0e.\tff-&f1\ti\fi"e\be;:e$)g):i&e\be.\fei)1e\n(d8\vi"d8\re\rh/d?!fd9\ti3e\th\v1e=f<d:.ed:\vg)e.6g>$d<ef0e\r3e/e\rg(1e.6e7e\n(g;f3e\b0f3(fe0e-&f\0\'h=h\0g g!,d;6h\'g\vf8f%fg,i&i i;ii\0g(f1h\vge.d8;g.!i6f.5h(;e\ng?;h/fe\b)ee%=d<P:P0P:P8P;P8Q\rQP>P2QP5P5P3P>P?Q\0P8QP0P:P5Q\tP5QP6P5PP0P:P1P5P7P1Q\vP;P>P=P8PQP5P?P>P4P-QP>QP>PP=P0P3P4P5PP3P>P4P2P>QQP0P
P2P0QP2P0PQQQP=P0P4P4P=QPP>QQQ\0P8P=P5P9PP0QP=P8PQQ\0QP1PP=P8PPP9P4P2P5P>P=P>QQP4`$`%`$9`%\b`$`%\0`$8`%`$`$>`$`%\v`$`$0`$*`$0`$(`%`$`$`$`$?`$-`%\0`$`$8`$`$0`$$`%\v`$9`%\v`$`$*`$9`%\0`$/`$9`$/`$>`$$`$`$%`$>jagran`$`$`$`%\v`$`$,`$&`%\v`$`$\b`$`$>`$`$`$9`$.`$`$(`$5`$9`$/`%`$%`%`$%`%\0`$`$0`$`$,`$&`%\0`$`$\b`$`%\0`$5`%`$(`$\b`$(`$`$9`$0`$\t`$8`$.`%`$`$.`$5`%\v`$2`%`$8`$,`$.`$\b`$&`%`$`$0`$`$.`$,`$8`$-`$0`$,`$(`$`$2`$.`$(`$`$`$8`%\0`$2`%\0X9YY\tX%YY\tYX0X\'X"X.X1X9X/X/X\'YY\tYX0YX5Y\bX1X:Y\nX1YX\'YY\bYX\'X(Y\nYX9X1X6X0YYYYX\'Y\nY\bYYX\'YX9YY\nX\'YX\'YYYX-X*Y\tYX(YY\bX-X)X\'X.X1YYX7X9X(X/X1YYX%X0X\'YYX\'X\'X-X/X%YX\'YY\nYX(X9X6YY\nYX(X-X+Y\bYYY\bYY\bX#YX\'X,X/X\'YYX\'X3YYX9YX/YY\nX3X9X(X1X5YY\tYYX0X(YX\'X#YYYX+YYYX*X\'YX\'X-Y\nX+YX5X1X4X1X-X-Y\bYY\bYY\nX\'X0X\'YYYYX1X)X\'YX*X\'YYX#X(Y\bX.X\'X5X#YX*X\'YYX\'YY\nX9X6Y\bY\bYX/X\'X(YX.Y\nX1X(YX*YYYX4X\'X!Y\bYY\nX\'X(Y\bYX5X5Y\bYX\'X1YYX#X-X/YX-YX9X/YX1X#Y\nX\'X-X)YX*X(X/Y\bYY\nX,X(YYYX*X-X*X,YX)X3YX)Y\nX*YYX1X)X:X2X)YYX3X(Y\nX*YYYYYX\'X*YYYYX(YYX\'X9YYX#Y\bYX4Y\nX!YY\bX1X#YX\'YY\nYX(YYX0X\'X*X1X*X(X(X#YYYX3X\'YYX(Y\nX9YYX/X-X3YYYYX4X9X1X#YYX4YX1YX7X1X7YX(profileservicedefaulthimselfdetailscontentsupportstartedmessagesuccessfashion
countryaccountcreatedstoriesresultsrunningprocesswritingobjectsvisiblewelcomearticleunknownnetworkcompanydynamicbrowserprivacyproblemServicerespectdisplayrequestreservewebsitehistoryfriendsoptionsworkingversionmillionchannelwindow.addressvisitedweathercorrectproductedirectforwardyou canremovedsubjectcontrolarchivecurrentreadinglibrarylimitedmanagerfurthersummarymachineminutesprivatecontextprogramsocietynumberswrittenenabledtriggersourcesloadingelementpartnerfinallyperfectmeaningsystemskeepingculture",journalprojectsurfaces"expiresreviewsbalanceEnglishContentthroughPlease opinioncontactaverageprimaryvillageSpanishgallerydeclinemeetingmissionpopularqualitymeasuregeneralspeciessessionsectionwriterscounterinitialreportsfiguresmembersholdingdisputeearlierexpressdigitalpictureAnothermarriedtrafficleadingchangedcentralvictoryimages/reasonsstudiesfeaturelistingmust beschoolsVersionusuallyepisodeplayinggrowingobviousoverlaypresentactions\r\nwrapperalreadycertainrealitystorageanotherdesktopofferedpatternunusualDigitalcapitalWebsitefailureconnectreducedAndroiddecadesregular & animalsreleaseAutomatgettingmethodsnothingPopularcaptionletterscapturesciencelicensechangesEngland=1&History = new CentralupdatedSpecialNetworkrequirecommentwarningCollegetoolbarremainsbecauseelectedDeutschfinanceworkersquicklybetweenexactlysettingdiseaseSocietyweaponsexhibit<!--Controlclassescoveredoutlineattacksdevices(windowpurposetitle="Mobile killingshowingItaliandroppedheavilyeffects-1\']);\nconfirmCurrentadvancesharingopeningdrawingbillionorderedGermanyrelatedincludewhetherdefinedSciencecatalogArticlebuttonslargestuniformjourneysidebarChicagoholidayGeneralpassage,"animatefeelingarrivedpassingnaturalroughly.\n\nThe but notdensityBritainChineselack oftributeIreland" data-factorsreceivethat isLibraryhusbandin factaffairsCharlesradicalbroughtfindinglanding:lang="return leadersplannedpremiumpackageAmericaEdition]"Messageneed tovalue="complexlookingstationbelievesmaller-mobilerecordswant tokind ofFirefoxyou aresimilarstudiedmaximumheadingrapidlyclimatekingdomemergedamountsfoundedpioneerformuladynastyhow to SupportrevenueeconomyResultsbrothersoldierlargelycalling."AccountEdward segmentRobert effortsPacificlearnedup withheight:we haveAngelesnations_searchappliedacquiremassivegranted: falsetreatedbiggestbenefitdrivingStudiesminimumperhapsmorningsellingis usedreversevariant role="missingachievepromotestudentsomeoneextremerestorebottom:evolvedall thesitemapenglishway to AugustsymbolsCompanymattersmusicalagainstserving})();\r\npaymenttroubleconceptcompareparentsplayersregionsmonitor \'\'The winningexploreadaptedGalleryproduceabilityenhancecareers). The collectSearch ancientexistedfooter handlerprintedconsoleEasternexportswindowsChannelillegalneutralsuggest_headersigning.html">settledwesterncausing-webkitclaimedJusticechaptervictimsThomas mozillapromisepartieseditionoutside:false,hundredOlympic_buttonauthorsreachedchronicdemandssecondsprotectadoptedprepareneithergreatlygreateroverallimprovecommandspecialsearch.worshipfundingthoughthighestinsteadutilityquarterCulturetestingclearlyexposedBrowserliberal} catchProjectexamplehide();FloridaanswersallowedEmperordefenseseriousfreedomSeveral-buttonFurtherout of != nulltrainedDenmarkvoid(0)/all.jspreventRequestStephen\n\nWhen observe\r\nModern provide" alt="borders.\n\nFor \n\nMany artistspoweredperformfictiontype ofmedicalticketsopposedCouncilwitnessjusticeGeorge Belgium...
twitternotablywaitingwarfare Other rankingphrasesmentionsurvivescholar
\r\n Countryignoredloss ofjust asGeorgiastrange\n severalbecomesselect wedding00.htmlmonarchoff theteacherhighly biologylife ofor evenrise of»plusonehunting(thoughDouglasjoiningcirclesFor theAncientVietnamvehiclesuch ascrystalvalue =Windowsenjoyeda smallassumed\ncame fromwere usednote thatreceivingExecutiveeven moreaccess tocommanderPoliticalmusiciansdeliciousprisonersadvent ofUTF-8" />ContactSouthern bgcolor="series of. It was in Europepermittedvalidate.appearingofficialsseriously-languageinitiatedextendinglong-terminflationsuch thatgetCookiemarked byimplementbut it isincreasesdown the requiringdependent--\x3e\n\x3c!-- interviewWith the copies ofconsensuswas builtVenezuela(formerlythe statepersonnelstrategicfavour ofinventionWikipediacontinentvirtuallywhich wasprincipleComplete identicalshow thatprimitiveaway frommolecularpreciselydissolvedUnder theversion="> span id="sought tobelow thesurviving}his deathas in thecaused bypartiallyexisting using thewas givena list oflevels ofnotion ofOfficial dismissedscientistresemblesduplicateexplosiverecoveredall othergalleries{padding:people ofregion ofaddressesassociateimg alt="in modernshould bemethod ofreportingtimestampneeded tothe Greatregardingseemed toviewed asimpact onidea thatthe Worldheight ofexpandingThese arecurrent">carefullymaintainscharge ofClassicaladdressedpredictedownership\r\nresidenceleave thecontent">are often })();\r\nprobably Professor-button" respondedsays thathad to beplaced inHungarianstatus ofserves asUniversalexecutionaggregatefor whichinfectionagreed tohowever, popular">placed onconstructelectoralsymbol ofincludingreturn toarchitectChristianprevious living ineasier toprofessor\n<!-- effect ofanalyticswas takenwhere thetook overbelief inAfrikaansas far aspreventedwork witha specialcommitteegoverninggroups ofstored inestablisha generalits firsttheir ownpopulatedan objectCaribbeanallow thedistrictswisconsinlocation.; width: inhabitedSocialistJanuary 1similarlychoice ofthe same specific business The first.length; desire todeal withsince theuserAgentconceivedindex.phpas "engage inrecently,few yearswere also\n\nthere is a popularsequencesadvocatedThey wereany otherlocation=enter themuch morereflectedwas namedoriginal a typicalwhen theyengineerscould notresidentswednesdaythe third productsJanuary 2what theya certainreactionsprocessorafter histhe last contained">
\ndepend onsearch">\npieces ofcompetingReferencetennesseewhich has version= <gives thehistorianvalue="">padding:0view thattogether,the most was foundsubset ofattack onchildren,points ofpersonal position:allegedlyClevelandwas laterand afterare givenwas stillscrollingdesign ofmakes themuch lessAmericans.\n\nAfter , but theMuseum oflouisiana(from theminnesotaparticlesa processDominicanvolume ofreturningdefensive00px|righmade frommouseover" style="states of(which iscontinuesFranciscobuilding without awith somewho woulda form ofa part ofbefore itknown as Serviceslocation and oftenmeasuringand it ispaperbackvalues of\r\n= window.determineer" played byand earlyfrom thisthe threepower andof "innerHTMLfh!\ff&i(h=f e(e\fd:,e8e$\'e-&gh6\nf%h6\ng.!ged?!f/g=serviciosartC-culoargentinabarcelonacualquierpublicadoproductospolC-ticarespuestawikipediasiguientebC:squedacomunidadseguridadprincipalpreguntascontenidorespondervenezuelaproblemasdiciembrerelaciC3nnoviembresimilaresproyectosprogramasinstitutoactividadencuentraeconomC-aimC!genescontactardescargarnecesarioatenciC3ntelC)fonocomisiC3ncancionescapacidadencontraranC!lisisfavoritostC)rminosprovinciaetiquetaselementosfuncionesresultadocarC!cterpropiedadprincipionecesidadmunicipalcreaciC3ndescargaspresenciacomercialopinionesejercicioeditorialsalamancagonzC!lezdocumentopelC-cularecientesgeneralestarragonaprC!cticanovedadespropuestapacientestC)cnicasobjetivoscontactos`$.`%`$`$2`$?`$`$9`%\b`$`$`$/`$>`$8`$>`$%`$`$5`$`$0`$9`%`$`%\v`$\b`$`%`$`$0`$9`$>`$,`$>`$&`$`$9`$>`$8`$-`%\0`$9`%`$`$0`$9`%\0`$.`%\b`$`$&`$?`$(`$,`$>`$$diplodocs`$8`$.`$/`$0`%`$*`$(`$>`$.`$*`$$`$>`$+`$?`$0`$`$8`$$`$$`$0`$9`$2`%\v`$`$9`%`$`$,`$>`$0`$&`%`$6`$9`%`$\b`$`%`$2`$/`$&`$?`$`$>`$.`$5`%`$,`$$`%\0`$(`$,`%\0`$`$.`%\f`$$`$8`$>`$2`$2`%`$`$`%\t`$,`$.`$&`$&`$$`$%`$>`$(`$9`%\0`$6`$9`$0`$`$2`$`$`$-`%\0`$(`$`$0`$*`$>`$8`$0`$>`$$`$`$?`$`$\t`$8`%`$`$/`%\0`$9`%`$`$`$`%`$`%\0`$.`$`%\v`$`$`$>`$0`$`$-`%\0`$`$/`%`$$`%`$.`$5`%\v`$`$&`%`$`$`$`$0`$`$8`%`$.`%`$2`$2`$`$>`$9`$>`$2`$\n`$*`$0`$`$>`$0`$`$8`$>`$&`%`$0`$`$?`$8`$&`$?`$2`$,`$`$&`$,`$(`$>`$9`%`$`$2`$>`$`$`%\0`$$`$,`$`$(`$.`$?`$2`$`$8`%`$`$(`%`$(`$/`$>`$`%`$2`$2`%\t`$`$-`$>`$`$0`%`$2`$`$`$9`$0`$>`$.`$2`$`%`$*`%`$`$9`$>`$%`$`$8`%\0`$8`$9`%\0`$`$2`$>`$ `%\0`$`$9`$>`$`$&`%`$0`$$`$9`$$`$8`$>`$$`$/`$>`$&`$`$/`$>`$*`$>`$`$`%\f`$(`$6`$>`$.`$&`%`$`$/`$9`%\0`$0`$>`$/`$`%`$&`$2`$`%\0categoriesexperience \r\nCopyright javascriptconditionseverything\nmembershiplinguisticpx;paddingphilosophyassistanceuniversityfacilitiesrecognizedpreferenceif (typeofmaintainedvocabularyhypothesis.submit(); annotationbehind theFoundationpublisher"assumptionintroducedcorruptionscientistsexplicitlyinstead ofdimensions onClick="considereddepartmentoccupationsoon afterinvestmentpronouncedidentifiedexperimentManagementgeographic" height="link rel=".replace(/depressionconferencepunishmenteliminatedresistanceadaptationoppositionwell knownsupplementdeterminedh1 class="0px;marginmechanicalstatisticscelebratedGovernment\n\nDuring tdevelopersartificialequivalentoriginatedCommissionattachment\r\nabsolute; supportingextremely mainstream popularityemployment\r\n colspan="\n conversionabout the
integrated" lang="enPortuguesesubstituteindividualimpossiblemultimediaalmost allpx solid #apart fromsubject toin Englishcriticizedexcept forguidelinesoriginallyremarkablethe secondh2 class=" collection\r\nfunctionvisibilitythe use ofvolunteersattractionunder the threatened*\nevaluationemphasizedaccessiblesuccessionalong withMeanwhile,industries has becomeaspects ofTelevisionsufficientbasketballboth sidescontinuingan articlepublishersJournal ofdifficultyfacilitateacceptablestyle.css"\tfunction innovation>Copyrightsituationswould havebusinessesDictionarystatementsoften usedpersistentin Januarycomprising\n\tdiplomaticcontainingperformingextensionsmay not beconcept of onclick="It is alsofinancial making theLuxembourgadditionalare calledengaged in"script");but it waselectroniconsubmit="\n\x3c!-- End electricalofficiallysuggestiontop of theunlike theAustralianOriginallyreferences\n\r\nrecognisedinitializelimited toAlexandriaretirementAdventuresfour years\n\n<!-- increasingdecorationh3 class="origins ofobligationregulationclassified(function(advantagesbeing the historians the publicmany yearswhich wereover time,synonymouscontent">\npresumablyhis familyuserAgent.unexpectedincluding challengeda minorityundefined"belongs totaken fromin Octoberposition: said to bereligious Federation rowspan="only a fewmeant thatled to the--\x3e\r\nArchbishop class="nobeing usedapproachesprivilegesnoscript>\nresults inmay be theEaster eggmechanismsreasonablePopulationCollectionselected">noscript>\r/index.phparrival of-jssdk\'));managed toincompletecasualtiescompletionChristiansSeptember arithmeticproceduresmight haveProductionit appearsPhilosophyfriendshipleading togiving thetoward theguaranteeddocumentedcolor:#000video gamecommissionreflectingchange theassociatedsans-serifonkeypress; padding:He was theunderlyingtypically , and the srcElementsuccessivesince the should be networkingaccountinguse of thelower thanshows that\n\t\tcomplaintscontinuousquantitiesastronomerhe did notdue to itsapplied toan averageefforts tothe futureattempt toTherefore,capabilityRepublicanwas formedElectronickilometerschallengespublishingthe formerindigenousdirectionssubsidiaryconspiracydetails ofand in theaffordablesubstancesreason forconventionitemtype="absolutelysupposedlyremained aattractivetravellingseparatelyfocuses onelementaryapplicablefound thatstylesheetmanuscriptstands for no-repeat(sometimesCommercialin Americaundertakenquarter ofan examplepersonallyindex.php?\npercentagebest-knowncreating a" dir="ltrLieutenant\n
notification\'undefined\')Furthermore,believe thatinnerHTML = prior to thedramaticallyreferring tonegotiationsheadquartersSouth AfricaunsuccessfulPennsylvaniaAs a result,\r\n
English (US)appendChild(transmissions. However, intelligence" tabindex="float:right;Commonwealthranging fromin which theat least onereproductionencyclopedia;font-size:1jurisdictionat that time">compensationchampionshipmedia="all" violation ofreference toreturn true;Strict//EN" transactionsinterventionverificationInformation difficultiesChampionshipcapabilities}\n\nChristianityfor example,Professionalrestrictionssuggest thatwas released(such as theremoveClass(unemploymentthe Americanstructure of/index.html published inspan class=""> \n\nf (document.border: 1px {font-size:1treatment of0" height="1modificationIndependencedivided intogreater thanachievementsestablishingJavaScript" neverthelesssignificanceBroadcasting> container">\nsuch as the influence ofa particularsrc=\'http://navigation" half of the substantial advantage ofdiscovery offundamental metropolitanthe opposite" xml:lang="deliberatelyalign=centerevolution ofpreservationimprovementsbeginning inJesus ChristPublicationsdisagreementtext-align:r, function()similaritiesbody>is currentlyalphabeticalis sometimestype="image/many of the flow:hidden;available indescribe theexistence ofall over thethe Internet\t\r\nconsider thean estimatedthe National\r\n\r\n
which allowsIntroductiondeveloped bya wide rangeon behalf ofvalign="top"principle ofat the time, \rsaid to havein the firstwhile othershypotheticalphilosopherspower of thecontained inperformed byinability towere writtenspan style="input name="the questionintended forrejection ofimplies thatinvented thethe standardwas probablylink betweenprofessor ofinteractionschanging theIndian Ocean class="lastworking with\'http://www.years beforeThis was therecreationalentering themeasurementsan extremelyvalue of thestart of the\n\n\nan effort toincrease theto the southspacing="0">sufficientlythe Europeanconverted toclearTimeoutdid not haveconsequentlyfor the nextextension ofeconomic andalthough theare producedand with theinsufficientgiven by thestating thatexpenditures \nthought thaton the basiscellpadding=image of thereturning toinformation,separated byassassinateds" content="authority ofnorthwestern\n
\r\n consultationcommunity ofthe nationalit should beparticipants align="leftthe greatestselection ofsupernaturaldependent onis mentionedallowing thewas inventedaccompanyinghis personalavailable atstudy of theon the otherexecution ofHuman Rightsterms of theassociationsresearch andsucceeded bydefeated theand from thebut they arecommander ofstate of theyears of agethe study ofRoman Empireequal to theIn contrast,however, andis typicallyand his wife(also called>P=P3P>P;P!Q\0P?Q\x01P:P8Q\x01Q\0P?Q\x01P:P8Q\x01Q\0P?Q\x01P:P>Y\x04X9X1X(Y\nX)f-#i+\x14d8-f\x16\x07g.\0d=\x13d8-f\x16\x07g9\x01d=\x13d8-f\x16\x07f\x1c\ti\x19\x10e\x05,e\x0f8d::f0\x11f\x14?e:\x1ci\x18?i\x07\fe74e74g$>d<\x1ad8;d9\tf\x13\rd=\x1cg3;g;\x1ff\x14?g-\x16f3\x15h\'\x04informaciC3nherramientaselectrC3nicodescripciC3nclasificadosconocimientopublicaciC3nrelacionadasinformC!ticarelacionadosdepartamentotrabajadoresdirectamenteayuntamientomercadoLibrecontC!ctenoshabitacionescumplimientorestaurantesdisposiciC3nconsecuenciaelectrC3nicaaplicacionesdesconectadoinstalaciC3nrealizaciC3nutilizaciC3nenciclopediaenfermedadesinstrumentosexperienciasinstituciC3nparticularessubcategoriaQ\x02P>P;Q\fP:P>P P>Q\x01Q\x01P8P8Q\0P0P1P>Q\x02Q\vP1P>P;Q\fQ\bP5P?Q\0P>Q\x01Q\x02P>PP6P5Q\x02P5P4Q\0Q\x03P3P8Q\x05Q\x01P;Q\x03Q\x07P0P5Q\x01P5P9Q\x07P0Q\x01P2Q\x01P5P3P4P0P P>Q\x01Q\x01P8Q\x0fP\x1cP>Q\x01P:P2P5P4Q\0Q\x03P3P8P5P3P>Q\0P>P4P0P2P>P?Q\0P>Q\x01P4P0P=P=Q\vQ\x05P4P>P;P6P=Q\vP8PP\x1cP>Q\x01P:P2Q\vQ\0Q\x03P1P;P5P9P\x1cP>Q\x01P:P2P0Q\x01Q\x02Q\0P0P=Q\vP=P8Q\x07P5P3P>Q\0P0P1P>Q\x02P5P4P>P;P6P5P=Q\x03Q\x01P;Q\x03P3P8Q\x02P5P?P5Q\0Q\fP\x1eP4P=P0P:P>P?P>Q\x02P>PQ\x02Q\x03P0P?Q\0P5P;Q\x0fP2P>P>P1Q\tP5P>P4P=P>P3P>Q\x01P2P>P5P3P>Q\x01Q\x02P0Q\x02Q\fP8P4Q\0Q\x03P3P>P9Q\x04P>Q\0Q\x03PQ\0P>Q\bP>P?Q\0P>Q\x02P8P2Q\x01Q\x01Q\vP;P:P0P:P0P6P4Q\vP9P2P;P0Q\x01Q\x02P8P3Q\0Q\x03P?P?Q\vP2PQ\x02P0Q\x01P:P0P7P0P;P?P5Q\0P2Q\vP9P4P5P;P0Q\x02Q\fP4P5P=Q\fP3P8P?P5Q\0P8P>P4P1P8P7P=P5Q\x01P>Q\x01P=P>P2P5PPP;P6P=P0Q\0P0PP P0P1P>Q\x02P0P"P>P;Q\fP:P>Q\x01P>P2Q\x01P5PQ\0P>P9P=P0Q\x07P0P;P0Q\x01P?P8Q\x01P>P:Q\x01P;Q\x03P6P1Q\vQ\x01P8Q\x01Q\x02P5PP2P>P3P>P?P>P
Q\tP8Q\x01P0P9Q\x02P>P2P?P>Q\x07P5PPQ\tQ\fP4P>P;P6P=P>Q\x01Q\x01Q\vP;P:P8P1Q\vQ\x01Q\x02Q\0P>P4P0P=P=Q\vP5P
P3P8P5P?Q\0P>P5P:Q\x02P!P5P9Q\x07P0Q\x01P
P4P5P;P8Q\x02P0P:P>P3P>P>P=P;P0P9P=P3P>Q\0P>P4P5P2P5Q\0Q\x01P8Q\x0fQ\x01Q\x02Q\0P0P=P5Q\x04P8P;Q\fPP2P=Q\x0fQ\0P0P7P=Q\vQ\x05P8Q\x01P:P0Q\x02Q\fP=P5P4P5P;Q\x0eQ\x0fP=P2P0Q\0Q\x0fPP3P8Q\x05P4P0P=P=P>P9P7P=P0Q\x07P8Q\x02P=P5P;Q\fP7Q\x0fQ\x04P>Q\0Q\x03P`$\x15`$0`%\x07`$\x02`$\x05`$(`%\r`$/`$\x15`%\r`$/`$>`$\x17`$>`$\x07`$!`$,`$>`$0`%\x07`$\x15`$?`$8`%\0`$&`$?`$/`$>`$*`$9`$2`%\x07`$8`$?`$\x02`$9`$-`$>`$0`$$`$\x05`$*`$(`%\0`$5`$>`$2`%\x07`$8`%\x07`$5`$>`$\x15`$0`$$`%\x07`$.`%\x07`$0`%\x07`$9`%\v`$(`%\x07`$8`$\x15`$$`%\x07`$,`$9`%\x01`$$`$8`$>`$\x07`$\x1f`$9`%\v`$\x17`$>`$\x1c`$>`$(`%\x07`$.`$?`$(`$\x1f`$\x15`$0`$$`$>`$\x15`$0`$(`$>`$\t`$(`$\x15`%\x07`$/`$9`$>`$\x01`$8`$,`$8`%\x07`$-`$>`$7`$>`$\x06`$*`$\x15`%\x07`$2`$?`$/`%\x07`$6`%\x01`$0`%\x02`$\x07`$8`$\x15`%\x07`$\x18`$\x02`$\x1f`%\x07`$.`%\x07`$0`%\0`$8`$\x15`$$`$>`$.`%\x07`$0`$>`$2`%\x07`$\x15`$0`$\x05`$\'`$?`$\x15`$\x05`$*`$(`$>`$8`$.`$>`$\x1c`$.`%\x01`$\x1d`%\x07`$\x15`$>`$0`$#`$9`%\v`$$`$>`$\x15`$!`$<`%\0`$/`$9`$>`$\x02`$9`%\v`$\x1f`$2`$6`$,`%\r`$&`$2`$?`$/`$>`$\x1c`%\0`$5`$(`$\x1c`$>`$$`$>`$\x15`%\b`$8`%\x07`$\x06`$*`$\x15`$>`$5`$>`$2`%\0`$&`%\x07`$(`%\x07`$*`%\x02`$0`%\0`$*`$>`$(`%\0`$\t`$8`$\x15`%\x07`$9`%\v`$\x17`%\0`$,`%\b`$ `$\x15`$\x06`$*`$\x15`%\0`$5`$0`%\r`$7`$\x17`$>`$\x02`$5`$\x06`$*`$\x15`%\v`$\x1c`$?`$2`$>`$\x1c`$>`$(`$>`$8`$9`$.`$$`$9`$.`%\x07`$\x02`$\t`$(`$\x15`%\0`$/`$>`$9`%\x02`$&`$0`%\r`$\x1c`$8`%\x02`$\x1a`%\0`$*`$8`$\x02`$&`$8`$5`$>`$2`$9`%\v`$(`$>`$9`%\v`$$`%\0`$\x1c`%\b`$8`%\x07`$5`$>`$*`$8`$\x1c`$(`$$`$>`$(`%\x07`$$`$>`$\x1c`$>`$0`%\0`$\x18`$>`$/`$2`$\x1c`$?`$2`%\x07`$(`%\0`$\x1a`%\x07`$\x1c`$>`$\x02`$\x1a`$*`$$`%\r`$0`$\x17`%\x02`$\x17`$2`$\x1c`$>`$$`%\x07`$,`$>`$9`$0`$\x06`$*`$(`%\x07`$5`$>`$9`$(`$\x07`$8`$\x15`$>`$8`%\x01`$,`$9`$0`$9`$(`%\x07`$\x07`$8`$8`%\x07`$8`$9`$?`$$`$,`$!`$<`%\x07`$\x18`$\x1f`$(`$>`$$`$2`$>`$6`$*`$>`$\x02`$\x1a`$6`%\r`$0`%\0`$,`$!`$<`%\0`$9`%\v`$$`%\x07`$8`$>`$\b`$\x1f`$6`$>`$/`$&`$8`$\x15`$$`%\0`$\x1c`$>`$$`%\0`$5`$>`$2`$>`$9`$\x1c`$>`$0`$*`$\x1f`$(`$>`$0`$\x16`$(`%\x07`$8`$!`$<`$\x15`$.`$?`$2`$>`$\t`$8`$\x15`%\0`$\x15`%\x07`$5`$2`$2`$\x17`$$`$>`$\x16`$>`$(`$>`$\x05`$0`%\r`$%`$\x1c`$9`$>`$\x02`$&`%\x07`$\x16`$>`$*`$9`$2`%\0`$(`$?`$/`$.`$,`$?`$(`$>`$,`%\b`$\x02`$\x15`$\x15`$9`%\0`$\x02`$\x15`$9`$(`$>`$&`%\x07`$$`$>`$9`$.`$2`%\x07`$\x15`$>`$+`%\0`$\x1c`$,`$\x15`$?`$$`%\x01`$0`$$`$.`$>`$\x02`$\x17`$5`$9`%\0`$\x02`$0`%\v`$\x1c`$<`$.`$?`$2`%\0`$\x06`$0`%\v`$*`$8`%\x07`$(`$>`$/`$>`$&`$5`$2`%\x07`$(`%\x07`$\x16`$>`$$`$>`$\x15`$0`%\0`$,`$\t`$(`$\x15`$>`$\x1c`$5`$>`$,`$*`%\x02`$0`$>`$,`$!`$<`$>`$8`%\f`$&`$>`$6`%\x07`$/`$0`$\x15`$?`$/`%\x07`$\x15`$9`$>`$\x02`$\x05`$\x15`$8`$0`$,`$(`$>`$\x0f`$5`$9`$>`$\x02`$8`%\r`$%`$2`$.`$?`$2`%\x07`$2`%\x07`$\x16`$\x15`$5`$?`$7`$/`$\x15`%\r`$0`$\x02`$8`$.`%\x02`$9`$%`$>`$(`$>X*X3X*X7Y\nX9Y\x05X4X\'X1Y\x03X)X(Y\bX\'X3X7X)X\'Y\x04X5Y\x01X-X)Y\x05Y\bX\'X6Y\nX9X\'Y\x04X.X\'X5X)X\'Y\x04Y\x05X2Y\nX/X\'Y\x04X9X\'Y\x05X)X\'Y\x04Y\x03X\'X*X(X\'Y\x04X1X/Y\bX/X(X1Y\x06X\'Y\x05X,X\'Y\x04X/Y\bY\x04X)X\'Y\x04X9X\'Y\x04Y\x05X\'Y\x04Y\x05Y\bY\x02X9X\'Y\x04X9X1X(Y\nX\'Y\x04X3X1Y\nX9X\'Y\x04X,Y\bX\'Y\x04X\'Y\x04X0Y\x07X\'X(X\'Y\x04X-Y\nX\'X)X\'Y\x04X-Y\x02Y\bY\x02X\'Y\x04Y\x03X1Y\nY\x05X\'Y\x04X9X1X\'Y\x02Y\x05X-Y\x01Y\bX8X)X\'Y\x04X+X\'Y\x06Y\nY\x05X4X\'Y\x07X/X)X\'Y\x04Y\x05X1X#X)X\'Y\x04Y\x02X1X"Y\x06X\'Y\x04X4X(X\'X(X\'Y\x04X-Y\bX\'X1X\'Y\x04X,X/Y\nX/X\'Y\x04X#X3X1X)X\'Y\x04X9Y\x04Y\bY\x05Y\x05X,Y\x05Y\bX9X)X\'Y\x04X1X-Y\x05Y\x06X\'Y\x04Y\x06Y\x02X\'X7Y\x01Y\x04X3X7Y\nY\x06X\'Y\x04Y\x03Y\bY\nX*X\'Y\x04X/Y\x06Y\nX\'X(X1Y\x03X\'X*Y\x07X\'Y\x04X1Y\nX\'X6X*X-Y\nX\'X*Y\nX(X*Y\bY\x02Y\nX*X\'Y\x04X#Y\bY\x04Y\tX\'Y\x04X(X1Y\nX/X\'Y\x04Y\x03Y\x04X\'Y\x05X\'Y\x04X1X\'X(X7X\'Y\x04X4X.X5Y\nX3Y\nX\'X1X\'X*X\'Y\x04X+X\'Y\x04X+X\'Y\x04X5Y\x04X\'X)X\'Y\x04X-X/Y\nX+X\'Y\x04X2Y\bX\'X1X\'Y\x04X.Y\x04Y\nX,X\'Y\x04X,Y\x05Y\nX9X\'Y\x04X9X\'Y\x05Y\x07X\'Y\x04X,Y\x05X\'Y\x04X\'Y\x04X3X\'X9X)Y\x05X4X\'Y\x07X/Y\x07X\'Y\x04X1X&Y\nX3X\'Y\x04X/X.Y\bY\x04X\'Y\x04Y\x01Y\x06Y\nX)X\'Y\x04Y\x03X*X\'X(X\'Y\x04X/Y\bX1Y\nX\'Y\x04X/X1Y\bX3X\'X3X*X:X1Y\x02X*X5X\'Y\x05Y\nY\x05X\'Y\x04X(Y\x06X\'X*X\'Y\x04X9X8Y\nY\x05entertainmentunderstanding = function().jpg" width="configuration.png" width=" investigationfavicon.ico" margin-right:based on the Massachusettstable border=internationalalso known aspronunciationbackground:#fpadding-left:For example, miscellaneous</math>psychologicalin particularearch" type="form method="as opposed toSupreme Courtoccasionally Additionally,North Americapx;backgroundopportunitiesEntertainment.toLowerCase(manufacturingprofessional combined withFor instance,consisting of" maxlength="return false;consciousnessMediterraneanextraordinaryassassinationsubsequently button type="the number ofthe original comprehensiverefers to the
\n\nphilosophicallocation.hrefwas publishedSan Francisco(function(){\n
cellspacing= revolutionaryprinciples ofis consideredwas developedIndo-Europeanvulnerable toproponents ofare sometimescloser to theNew York City name="searchattributed tocourse of themathematicianby the end ofat the end of" border="0" technological.removeClass(branch of theevidence that![endif]-->\r\nInstitute of into a singlerespectively.and thereforeproperties ofis located insome of whichThere is alsocontinued to appearance of – describes theconsiderationauthor of theindependentlyequipped withdoes not have\nthought to bepopulation ofpossibilitiespercentage ofaccess to thean attempt toproduction ofjquery/jquerytwo differentbelong to theestablishmentreplacing thedescription" determine theavailable forAccording to wide range of\thas been usedreturn to thealthough thischange in theseveral otherbut there areunprecedentedis similar toespecially inweight: bold;is called thecomputationalindicate thatrestricted to\t
\n
large part ofInstitute forthe so-called against the In this case,was appointedclaimed to beHowever, thisDepartment ofthe remainingeffect on theparticularly deal with the\n
the structure />
Many of thesecaused by theof the Unitedspan class="mcan be tracedis related tobecame one ofis frequentlyliving in thetheoreticallyFollowing theRevolutionarygovernment inis determinedthe politicalintroduced insufficient todescription">short storiesseparation ofas to whetherknown for itswas initiallydisplay:blockis an examplethe principalconsists of arecognized as/body>a substantialreconstructedhead of stateresistance toundergraduateThere are twogravitationalare describedintentionallyserved as theclass="headeropposition tofundamentallydominated theand the otheralliance withwas forced torespectively,and politicalin support ofpeople in the20th century.and publishedloadChartbeatto understandmember statesenvironmentalfirst half ofcountries andarchitecturalbe consideredcharacterizedclearIntervalauthoritativeFederation ofwas succeededand there area consequencethe Presidentalso includedfree softwaresuccession ofdeveloped thewas destroyedaway from the;\n\n\n=http%3A%2F%2F
/favicon.ico">=\'stylesheet\' identification, for example,\ntype="submit" \n(function() {recommendationform action="/transformationreconstruction.style.display According to hidden" name="along with thedocument.body.approximately Communicationspost" action="meaning "--Prime Ministercharacteristic \n\ndepends on theUniversity of in contrast to placeholder="in the case ofinternational constitutionalstyle="border-: function() {Because of the-strict.dtd">\n