pax_global_header00006660000000000000000000000064142735335520014523gustar00rootroot0000000000000052 comment=17cb90c495b4f8cf09dd151e705c896541ec5982 streamvbyte-0.5.1/000077500000000000000000000000001427353355200140735ustar00rootroot00000000000000streamvbyte-0.5.1/.github/000077500000000000000000000000001427353355200154335ustar00rootroot00000000000000streamvbyte-0.5.1/.github/workflows/000077500000000000000000000000001427353355200174705ustar00rootroot00000000000000streamvbyte-0.5.1/.github/workflows/ubuntu.yml000066400000000000000000000021261427353355200215360ustar00rootroot00000000000000name: Ubuntu 20.04 CI (GCC 9) on: push: branches: - master pull_request: branches: - master jobs: ubuntu-build: if: >- ! contains(toJSON(github.event.commits.*.message), '[skip ci]') && ! contains(toJSON(github.event.commits.*.message), '[skip github]') runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - name: Use cmake (debug) run: | mkdir builddebug && cd builddebug && cmake -DCMAKE_BUILD_TYPE=buildundefsani .. && cmake --build . && ctest --output-on-failure - name: Use cmake (release) run: | mkdir buildrelease && cd buildrelease && cmake -DCMAKE_BUILD_TYPE=Release .. && cmake --build . && ctest --output-on-failure - name: Use cmake (undefined sanitizer) run: | mkdir buildundefsani && cd buildundefsani && cmake -DSTREAMVBYTE_SANITIZE_UNDEFINED=ON -DCMAKE_BUILD_TYPE=buildundefsani .. && cmake --build . && ctest --output-on-failurestreamvbyte-0.5.1/.github/workflows/vs.yml000066400000000000000000000024051427353355200206440ustar00rootroot00000000000000name: VS17-CI on: push: branches: - master pull_request: branches: - master jobs: ci: if: >- ! contains(toJSON(github.event.commits.*.message), '[skip ci]') && ! contains(toJSON(github.event.commits.*.message), '[skip github]') name: windows-vs17 runs-on: windows-latest strategy: fail-fast: false matrix: include: - {gen: Visual Studio 17 2022, arch: Win32, static: ON} - {gen: Visual Studio 17 2022, arch: Win32, static: OFF} - {gen: Visual Studio 17 2022, arch: x64, static: ON} - {gen: Visual Studio 17 2022, arch: x64, static: OFF} steps: - name: checkout uses: actions/checkout@v2 - name: Configure run: | cmake -G "${{matrix.gen}}" -A ${{matrix.arch}} -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -DSIMDJSON_BUILD_STATIC=${{matrix.static}} -B build - name: Build Debug run: cmake --build build --config Debug --verbose - name: Build Release run: cmake --build build --config Release --verbose - name: Run Release tests run: | cd build ctest -C Release --output-on-failure - name: Run Debug tests run: | cd build ctest -C Debug --output-on-failurestreamvbyte-0.5.1/.gitignore000066400000000000000000000004321427353355200160620ustar00rootroot00000000000000unit dynunit writeseq perf example # Object files *.o *.ko *.obj *.elf # Precompiled Headers *.gch *.pch # Libraries *.lib *.a *.la *.lo # Shared objects (inc. Windows DLLs) *.dll *.so *.so.* *.dylib # Executables *.exe *.out *.app *.i*86 *.x86_64 *.hex # Debug files *.dSYM/ streamvbyte-0.5.1/.travis.yml000066400000000000000000000002641427353355200162060ustar00rootroot00000000000000language: c sudo: false compiler: - clang script: make && ./unit && make example && ./example && make perf && ./perf && mkdir build && cd build && cmake .. && make && make test streamvbyte-0.5.1/AUTHORS000066400000000000000000000002061427353355200151410ustar00rootroot00000000000000# this is the official list of authors for copyright purposes Daniel Lemire Kendall Willets Alexander Gallego @aqrit Vladimir Kazanov streamvbyte-0.5.1/CMakeLists.txt000066400000000000000000000102271427353355200166350ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.3) set(CMAKE_MACOSX_RPATH OFF) project(STREAMVBYTE VERSION "1.0.0") set(STREAMVBYTE_LIB_VERSION "1.0.0" CACHE STRING "streamvbyte library version") set(STREAMVBYTE_LIB_SOVERSION "1" CACHE STRING "streamvbyte library soversion") set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) option(STREAMVBYTE_SANITIZE "Sanitize addresses" OFF) if (NOT CMAKE_BUILD_TYPE) message(STATUS "No build type selected") if(STREAMVBYTE_SANITIZE) message(STATUS "Default to Debug") set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE) else() message(STATUS "Default to Release") set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) endif() endif() if(STREAMVBYTE_SANITIZE) message(STATUS "Enabling memory sanitizer.") add_compile_options(-fsanitize=address -fno-omit-frame-pointer -fno-sanitize-recover=all) add_compile_definitions(ASAN_OPTIONS=detect_leaks=1) endif() if (MSVC) add_definitions( "-D__restrict__=__restrict" ) endif() # test for arm if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*)") set(BASE_FLAGS ${BASE_FLAGS} "-D__ARM_NEON__" ) endif() set(STREAMVBYTE_SRCS ${PROJECT_SOURCE_DIR}/src/streamvbyte_encode.c ${PROJECT_SOURCE_DIR}/src/streamvbyte_decode.c ${PROJECT_SOURCE_DIR}/src/streamvbyte_zigzag.c ${PROJECT_SOURCE_DIR}/src/streamvbytedelta_encode.c ${PROJECT_SOURCE_DIR}/src/streamvbytedelta_decode.c ${PROJECT_SOURCE_DIR}/src/streamvbyte_0124_encode.c ${PROJECT_SOURCE_DIR}/src/streamvbyte_0124_decode.c ) set(CMAKE_POSITION_INDEPENDENT_CODE ON) add_library(streamvbyte_static STATIC "${STREAMVBYTE_SRCS}") target_link_libraries(streamvbyte_static ${BASE_FLAGS}) add_library(streamvbyte SHARED "${STREAMVBYTE_SRCS}") target_link_libraries(streamvbyte ${BASE_FLAGS}) set_target_properties( streamvbyte PROPERTIES VERSION "${STREAMVBYTE_LIB_VERSION}" SOVERSION "${STREAMVBYTE_LIB_SOVERSION}" WINDOWS_EXPORT_ALL_SYMBOLS YES ) set_target_properties( streamvbyte_static PROPERTIES VERSION "${STREAMVBYTE_LIB_VERSION}" SOVERSION "${STREAMVBYTE_LIB_SOVERSION}" WINDOWS_EXPORT_ALL_SYMBOLS YES ) target_include_directories( streamvbyte PUBLIC ${PROJECT_SOURCE_DIR}/include ) target_include_directories( streamvbyte_static PUBLIC ${PROJECT_SOURCE_DIR}/include ) install(FILES ${PROJECT_SOURCE_DIR}/include/streamvbyte.h ${PROJECT_SOURCE_DIR}/include/streamvbytedelta.h ${PROJECT_SOURCE_DIR}/include/streamvbyte_zigzag.h DESTINATION include ) install( TARGETS streamvbyte streamvbyte_static DESTINATION lib) option(STREAMVBYTE_SANITIZE_UNDEFINED "Sanitize undefined behavior" OFF) if(STREAMVBYTE_SANITIZE_UNDEFINED) add_compile_options(-fsanitize=undefined -fno-sanitize-recover=all) add_link_options(-fsanitize=undefined -fno-sanitize-recover=all) endif() MESSAGE( STATUS "CMAKE_SYSTEM_PROCESSOR: " ${CMAKE_SYSTEM_PROCESSOR}) MESSAGE( STATUS "CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE} ) # this tends to be "sticky" so you can remain unknowingly in debug mode MESSAGE( STATUS "CMAKE_C_COMPILER: " ${CMAKE_C_COMPILER} ) # important to know which compiler is used MESSAGE( STATUS "CMAKE_C_FLAGS: " ${CMAKE_C_FLAGS} ) # important to know the flags MESSAGE( STATUS "CMAKE_C_FLAGS_DEBUG: " ${CMAKE_C_FLAGS_DEBUG} ) MESSAGE( STATUS "CMAKE_C_FLAGS_RELEASE: " ${CMAKE_C_FLAGS_RELEASE} ) # build programs # example add_executable (example ${PROJECT_SOURCE_DIR}/example.c) target_link_libraries (example streamvbyte_static) if(NOT MSVC) # perf add_executable (perf ${PROJECT_SOURCE_DIR}/tests/perf.c) target_link_libraries (perf streamvbyte_static) target_link_libraries(perf m) endif() # writeseq add_executable (writeseq ${PROJECT_SOURCE_DIR}/tests/writeseq.c) target_link_libraries (writeseq streamvbyte_static) # unit add_executable (unit ${PROJECT_SOURCE_DIR}/tests/unit.c) target_link_libraries (unit streamvbyte_static) option(STREAMVBYTE_ENABLE_TESTS "enable unit tests for streamvbyte" ON) if(STREAMVBYTE_ENABLE_TESTS) enable_testing() # add unit tests add_test(NAME unit COMMAND unit) add_custom_target(check COMMAND ctest --output-on-failure DEPENDS unit) endif() streamvbyte-0.5.1/LICENSE000066400000000000000000000260751427353355200151120ustar00rootroot00000000000000Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. streamvbyte-0.5.1/Makefile000066400000000000000000000061371427353355200155420ustar00rootroot00000000000000# minimalist makefile .SUFFIXES: # .SUFFIXES: .cpp .o .c .h PROCESSOR:=$(shell uname -m) ifeq ($(PROCESSOR), aarch64) # for 64-bit ARM processors CFLAGS = -fPIC -std=c99 -O3 -Wall -Wextra -pedantic -Wshadow -D__ARM_NEON__ else ifeq ($(PROCESSOR), armv7l) # for 32-bit ARM processors CFLAGS = -fPIC -std=c99 -O3 -Wall -Wextra -pedantic -Wshadow else # Here we expect x64 # Formally speaking, we only need SSE4, at best, but code checks for AVX # since MSVC only allows to check for AVX and nothing finer like just SSE4 CFLAGS = -fPIC -std=c99 -O3 -Wall -Wextra -pedantic -Wshadow endif LDFLAGS = -shared LIBNAME=libstreamvbyte.so.0.0.1 LNLIBNAME=libstreamvbyte.so all: unit $(LIBNAME) test: ./unit dyntest: dynunit $(LNLIBNAME) LD_LIBRARY_PATH=. ./dynunit install: $(OBJECTS) $(LIBNAME) cp $(LIBNAME) /usr/local/lib ln -f -s /usr/local/lib/$(LIBNAME) /usr/local/lib/libstreamvbyte.so ldconfig cp $(HEADERS) /usr/local/include HEADERS=./include/streamvbyte.h ./include/streamvbytedelta.h ./include/streamvbyte_zigzag.h uninstall: for h in $(HEADERS) ; do rm /usr/local/$$h; done rm /usr/local/lib/$(LIBNAME) rm /usr/local/lib/libstreamvbyte.so ldconfig OBJECTS= streamvbyte_decode.o streamvbyte_encode.o streamvbytedelta_decode.o streamvbytedelta_encode.o streamvbyte_0124_encode.o streamvbyte_0124_decode.o streamvbyte_zigzag.o streamvbyte_zigzag.o: ./src/streamvbyte_zigzag.c $(HEADERS) $(CC) $(CFLAGS) -c ./src/streamvbyte_zigzag.c -Iinclude streamvbytedelta_encode.o: ./src/streamvbytedelta_encode.c $(HEADERS) $(CC) $(CFLAGS) -c ./src/streamvbytedelta_encode.c -Iinclude streamvbytedelta_decode.o: ./src/streamvbytedelta_decode.c $(HEADERS) $(CC) $(CFLAGS) -c ./src/streamvbytedelta_decode.c -Iinclude streamvbyte_0124_encode.o: ./src/streamvbyte_0124_encode.c $(HEADERS) $(CC) $(CFLAGS) -c ./src/streamvbyte_0124_encode.c -Iinclude streamvbyte_0124_decode.o: ./src/streamvbyte_0124_decode.c $(HEADERS) $(CC) $(CFLAGS) -c ./src/streamvbyte_0124_decode.c -Iinclude streamvbyte_decode.o: ./src/streamvbyte_decode.c $(HEADERS) $(CC) $(CFLAGS) -c ./src/streamvbyte_decode.c -Iinclude streamvbyte_encode.o: ./src/streamvbyte_encode.c $(HEADERS) $(CC) $(CFLAGS) -c ./src/streamvbyte_encode.c -Iinclude $(LIBNAME): $(OBJECTS) $(CC) $(CFLAGS) -o $(LIBNAME) $(OBJECTS) $(LDFLAGS) $(LNLIBNAME): $(LIBNAME) ln -f -s $(LIBNAME) $(LNLIBNAME) shuffle_tables: ./utils/shuffle_tables.c $(CC) $(CFLAGS) -o shuffle_tables ./utils/shuffle_tables.c example: ./example.c $(HEADERS) $(OBJECTS) $(CC) $(CFLAGS) -o example ./example.c -Iinclude $(OBJECTS) perf: ./tests/perf.c $(HEADERS) $(OBJECTS) $(CC) $(CFLAGS) -o perf ./tests/perf.c -Iinclude $(OBJECTS) -lm writeseq: ./tests/writeseq.c $(HEADERS) $(OBJECTS) $(CC) $(CFLAGS) -o writeseq ./tests/writeseq.c -Iinclude $(OBJECTS) unit: ./tests/unit.c $(HEADERS) $(OBJECTS) $(CC) $(CFLAGS) -o unit ./tests/unit.c -Iinclude $(OBJECTS) dynunit: ./tests/unit.c $(HEADERS) $(LIBNAME) $(LNLIBNAME) $(CC) $(CFLAGS) -o dynunit ./tests/unit.c -Iinclude -L. -lstreamvbyte clean: rm -f unit *.o $(LIBNAME) $(LNLIBNAME) example shuffle_tables perf writeseq dynunit streamvbyte-0.5.1/README.md000066400000000000000000000207541427353355200153620ustar00rootroot00000000000000streamvbyte =========== [![Ubuntu 20.04 CI (GCC 9)](https://github.com/lemire/streamvbyte/actions/workflows/ubuntu.yml/badge.svg)](https://github.com/lemire/streamvbyte/actions/workflows/ubuntu.yml) [![VS16-CI](https://github.com/lemire/streamvbyte/actions/workflows/vs.yml/badge.svg)](https://github.com/lemire/streamvbyte/actions/workflows/vs.yml) StreamVByte is a new integer compression technique that applies SIMD instructions (vectorization) to Google's Group Varint approach. The net result is faster than other byte-oriented compression techniques. The approach is patent-free, the code is available under the Apache License. It includes fast differential coding. It assumes a recent Intel processor (e.g., haswell or better, though we provide runtime dispatching for compatibility with legacy systems) or an ARM processor with NEON instructions (which is almost all of them except for the tiny cores). Big-endian processors are unsupported at this time, but they are getting to be extremely rare. The code should build using most standard-compliant C99 compilers. The provided makefile expects a Linux-like system. We have a CMake build. # Users This library is used by * [UpscaleDB](https://github.com/cruppstahl/upscaledb), * Redis' [RediSearch](https://github.com/RedisLabsModules/RediSearch), * [Facebook Thrift](https://github.com/facebook/fbthrift), * [Trinity Information Retrieval framework](https://github.com/phaistos-networks/Trinity). # Usage Usage with Makefile: make ./unit Usage with CMake: The cmake build system also offers a `libstreamvbyte_static` static library (`libstreamvbyte_static` under linux) in addition to `libstreamvbyte` shared library (`libstreamvbyte.so` under linux). `-DCMAKE_INSTALL_PREFIX:PATH=/path/to/install` is optional. Defaults to /usr/local{include,lib} ``` mkdir build cd build cmake .. -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX:PATH=/path/to/install \ make install # run the tests like: ctest -V ``` See example.c for an example. Short code sample: ```C // suppose that datain is an array of uint32_t integers size_t compsize = streamvbyte_encode(datain, N, compressedbuffer); // encoding // here the result is stored in compressedbuffer using compsize bytes streamvbyte_decode(compressedbuffer, recovdata, N); // decoding (fast) ``` If the values are sorted, then it might be preferable to use differential coding: ```C // suppose that datain is an array of uint32_t integers size_t compsize = streamvbyte_delta_encode(datain, N, compressedbuffer,0); // encoding // here the result is stored in compressedbuffer using compsize bytes streamvbyte_delta_decode(compressedbuffer, recovdata, N,0); // decoding (fast) ``` You have to know how many integers were coded when you decompress. You can store this information along with the compressed stream. The During decoding, the library may read up to `STREAMVBYTE_PADDING` extra bytes from the input buffer (these bytes are read but never used). Signed integers ----------------- We do not directly support signed integers, but you can use fast functions to convert signed integers to unsigned integers. ```C #include "streamvbyte_zigzag.h" zigzag_encode(mysignedints, myunsignedints, number); // mysignedints => myunsignedints zigzag_decode(myunsignedints, mysignedints, number); // myunsignedints => mysignedints ``` Installation ---------------- You can install the library (as a dynamic library) on your machine if you have root access: sudo make install To uninstall, simply type: sudo make uninstall It is recommended that you try ``make dyntest`` before proceeding. Benchmarking ----------------- You can try to benchmark the speed in this manner: make perf ./perf Make sure to run ``make test`` before, as a sanity test. Technical posts --------------- * [Trinity Updates and integer codes benchmarks](https://medium.com/@markpapadakis/trinity-updates-and-integer-codes-benchmarks-6a4fa2eb3fd1) by Mark Papadakis * [Stream VByte: breaking new speed records for integer compression](https://lemire.me/blog/2017/09/27/stream-vbyte-breaking-new-speed-records-for-integer-compression/) by Daniel Lemire Alternative encoding ------------------------------- By default, Stream VByte uses 1, 2, 3 or 4 bytes per integer. In the case where you expect many of your integers to be zero, you might try the ``streamvbyte_encode_0124`` and ``streamvbyte_decode_0124`` which use 0, 1, 2, or 4 bytes per integer. Stream VByte in other languages -------------------------------- * There is a [Rust version](https://bitbucket.org/marshallpierce/stream-vbyte-rust) by Marshall Pierce. * There is a [Go version](https://github.com/nelz9999/stream-vbyte-go) by Nelz. * There is an accelerated [Go version](https://github.com/theMPatel/streamvbyte-simdgo) by Milan Patel. Format Specification --------------------- We specify the format as follows. We do not store how many integers (``count``) are compressed in the compressed data per se. If you want to store the data stream (e.g., to disk), you need to add this information. It is intentionally left out because, in applications, it is often the case that there are better ways to store this count. There are two streams: - The data starts with an array of "control bytes". There are (count + 3) / 4 of them. - Following the array of control bytes, there are data bytes. We can interpret the control bytes as a sequence of 2-bit words. The first 2-bit word is made of the least significant 2 bits in the first byte, and so forth. There are four 2-bit words written in each byte. Starting from the first 2-bit word, we have corresponding sequence in the data bytes, written in sequence from the beginning: - When the 2-bit word is 00, there is a single data byte. - When the 2-bit words is 01, there are two data bytes. - When the 2-bit words is 10, there are three data bytes. - When the 2-bit words is 11, there are four data bytes. The data bytes are stored using a little-endian encoding. Consider the following example: ``` control bytes: [0x40 0x55 ... ] data bytes: [0x00 0x64 0xc8 0x2c 0x01 0x90 0x01 0xf4 0x01 0x58 0x02 0xbc 0x02 ...] ``` The first control byte is 0x40 or the four 2-bit words : ``00 00 00 01``. The second control byte is 0x55 or the four 2-bit words : ``01 01 01 01``. Thus the first three values are given by the first three bytes: ``0x00, 0x64, 0xc8`` (or 0, 100, 200 in base 10). The five next values are stored using two bytes each: ``0x2c 0x01, 0x90 0x01, 0xf4 0x01, 0x58 0x02, 0xbc 0x02``. As little endian integers, these are to be interpreted as 300, 400, 500, 600, 700. Thus, to recap, the sequence of integers (0,100,200,300,400,500,600,700) gets encoded as the 15 bytes ``0x40 0x55 0x00 0x64 0xc8 0x2c 0x01 0x90 0x01 0xf4 0x01 0x58 0x02 0xbc 0x02``. If the ``count``is not divisible by four, then we include a final partial group where we use zero 2-bit corresponding to no data byte. Reference --------- * Daniel Lemire, Nathan Kurz, Christoph Rupp, [Stream VByte: Faster Byte-Oriented Integer Compression](https://arxiv.org/abs/1709.08990), Information Processing Letters 130, 2018. See also -------- * SIMDCompressionAndIntersection: A C++ library to compress and intersect sorted lists of integers using SIMD instructions https://github.com/lemire/SIMDCompressionAndIntersection * The FastPFOR C++ library : Fast integer compression https://github.com/lemire/FastPFor * High-performance dictionary coding https://github.com/lemire/dictionary * LittleIntPacker: C library to pack and unpack short arrays of integers as fast as possible https://github.com/lemire/LittleIntPacker * The SIMDComp library: A simple C library for compressing lists of integers using binary packing https://github.com/lemire/simdcomp * MaskedVByte: Fast decoder for VByte-compressed integers https://github.com/lemire/MaskedVByte * CSharpFastPFOR: A C# integer compression library https://github.com/Genbox/CSharpFastPFOR * JavaFastPFOR: A java integer compression library https://github.com/lemire/JavaFastPFOR * Encoding: Integer Compression Libraries for Go https://github.com/zhenjl/encoding * FrameOfReference is a C++ library dedicated to frame-of-reference (FOR) compression: https://github.com/lemire/FrameOfReference * libvbyte: A fast implementation for varbyte 32bit/64bit integer compression https://github.com/cruppstahl/libvbyte * TurboPFor is a C library that offers lots of interesting optimizations. Well worth checking! (GPL license) https://github.com/powturbo/TurboPFor * Oroch is a C++ library that offers a usable API (MIT license) https://github.com/ademakov/Oroch streamvbyte-0.5.1/example.c000066400000000000000000000013731427353355200156760ustar00rootroot00000000000000#include #include #include #include "streamvbyte.h" int main() { int N = 5000; uint32_t * datain = malloc(N * sizeof(uint32_t)); uint8_t * compressedbuffer = malloc(streamvbyte_max_compressedbytes(N)); uint32_t * recovdata = malloc(N * sizeof(uint32_t)); for (int k = 0; k < N; ++k) datain[k] = 120; size_t compsize = streamvbyte_encode(datain, N, compressedbuffer); // encoding // here the result is stored in compressedbuffer using compsize bytes size_t compsize2 = streamvbyte_decode(compressedbuffer, recovdata, N); // decoding (fast) assert(compsize == compsize2); free(datain); free(compressedbuffer); free(recovdata); printf("Compressed %d integers down to %d bytes.\n",N,(int) compsize); return 0; } streamvbyte-0.5.1/include/000077500000000000000000000000001427353355200155165ustar00rootroot00000000000000streamvbyte-0.5.1/include/streamvbyte.h000066400000000000000000000103531427353355200202360ustar00rootroot00000000000000 #ifndef INCLUDE_STREAMVBYTE_H_ #define INCLUDE_STREAMVBYTE_H_ #define __STDC_FORMAT_MACROS #include #include // please use a C99-compatible compiler #include #if defined(__cplusplus) extern "C" { #endif #define STREAMVBYTE_PADDING 16 // Encode an array of a given length read from in to bout in varint format. // Returns the number of bytes written. // The number of values being stored (length) is not encoded in the compressed stream, // the caller is responsible for keeping a record of this length. // The pointer "in" should point to "length" values of size uint32_t // there is no alignment requirement on the out pointer // For safety, the out pointer should point to at least streamvbyte_max_compressedbyte(length) // bytes. // Uses 1,2,3 or 4 bytes per value + the decoding keys. size_t streamvbyte_encode(const uint32_t *in, uint32_t length, uint8_t *out); // same as streamvbyte_encode but 0,1,2 or 4 bytes per value (plus decoding keys) instead of using 1,2,3 or 4 // bytes. This might be useful when there's a lot of zeroes in the input array. size_t streamvbyte_encode_0124(const uint32_t *in, uint32_t length, uint8_t *out); // return the maximum number of compressed bytes given length input integers // in the worst case we overestimate data bytes required by four, see below // for a function you can run upfront over your data to compute allocations // It includes the STREAMVBYTE_PADDING bytes. static inline size_t streamvbyte_max_compressedbytes(const uint32_t length) { // number of control bytes: size_t cb = (length + 3) / 4; // maximum number of control bytes: size_t db = (size_t) length * sizeof(uint32_t); return cb + db + STREAMVBYTE_PADDING; } // return the exact number of compressed bytes given length input integers // runtime in O(n) wrt. in; use streamvbyte_max_compressedbyte if you // care about speed more than potentially over-allocating memory // Our decoding functions may read (but not use) STREAMVBYTE_PADDING extra bytes beyond // the compressed data: the user needs to ensure that this region is allocated, and it // is not included by streamvbyte_compressedbytes. static inline size_t streamvbyte_compressedbytes(const uint32_t *in, uint32_t length) { // number of control bytes: size_t cb = (length + 3) / 4; // maximum number of control bytes: size_t db = 0; for (uint32_t c = 0; c < length; c++) { uint32_t val = in[c]; if (val < (1 << 8)) db += 1; else if (val < (1 << 16)) db += 2; else if (val < (1 << 24)) db += 3; else db += 4; } return cb + db; } // return the exact number of compressed bytes given length input integers // runtime in O(n) wrt. in; use streamvbyte_max_compressedbyte if you // care about speed more than potentially over-allocating memory // Our decoding functions may read (but not use) STREAMVBYTE_PADDING extra bytes beyond // the compressed data: the user needs to ensure that this region is allocated, and it // is not included by streamvbyte_compressedbytes. static inline size_t streamvbyte_compressedbytes_0124(const uint32_t *in, uint32_t length) { // number of control bytes: size_t cb = (length + 3) / 4; // maximum number of control bytes: size_t db = 0; for (uint32_t c = 0; c < length; c++) { uint32_t val = in[c]; if (val == 0) db += 0; else if (val < (1 << 8)) db += 1; else if (val < (1 << 16)) db += 2; else db += 4; } return cb + db; } // Read "length" 32-bit integers in varint format from in, storing the result in out. // Returns the number of bytes read. We may read up to STREAMVBYTE_PADDING extra bytes // from the input buffer (these bytes are read but never used). // The caller is responsible for knowing how many integers ("length") are to be read: // this information ought to be stored somehow. // There is no alignment requirement on the "in" pointer. // The out pointer should point to length * sizeof(uint32_t) bytes. size_t streamvbyte_decode(const uint8_t *in, uint32_t *out, uint32_t length); // Same as streamvbyte_decode but is meant to be used for streams encoded with // streamvbyte_encode_0124. size_t streamvbyte_decode_0124(const uint8_t *in, uint32_t *out, uint32_t length); #if defined(__cplusplus) }; #endif #endif /* INCLUDE_STREAMVBYTE_H_ */ streamvbyte-0.5.1/include/streamvbyte_zigzag.h000066400000000000000000000017531427353355200216150ustar00rootroot00000000000000 #ifndef INCLUDE_STREAMVBYTE_ZIGZAG_H_ #define INCLUDE_STREAMVBYTE_ZIGZAG_H_ #define __STDC_FORMAT_MACROS #include #include // please use a C99-compatible compiler #include #if defined(__cplusplus) extern "C" { #endif /** * Convert N signed integers to N unsigned integers, using zigzag * encoding. */ void zigzag_encode(const int32_t * in, uint32_t * out, size_t N); /** * Convert N signed integers to N unsigned integers, using zigzag * delta encoding. */ void zigzag_delta_encode(const int32_t * in, uint32_t * out, size_t N, int32_t prev); /** * Convert N unsigned integers to N signed integers, using zigzag * encoding. */ void zigzag_decode(const uint32_t * in, int32_t * out, size_t N); /** * Convert N unsigned integers to N signed integers, using zigzag * delta encoding. */ void zigzag_delta_decode(const uint32_t * in, int32_t * out, size_t N, int32_t prev); #if defined(__cplusplus) }; #endif #endif /* INCLUDE_STREAMVBYTE_ZIGZAG_H_ */ streamvbyte-0.5.1/include/streamvbytedelta.h000066400000000000000000000033671427353355200212570ustar00rootroot00000000000000#ifndef INCLUDE_STREAMVBYTEDELTA_H_ #define INCLUDE_STREAMVBYTEDELTA_H_ #if defined(__cplusplus) extern "C" { #endif #include #include // please use a C99-compatible compiler #include // Encode an array of a given length read from in to bout in StreamVByte format. // Returns the number of bytes written. // The number of values being stored (length) is not encoded in the compressed stream, // the caller is responsible for keeping a record of this length. // The pointer "in" should point to "length" values of size uint32_t // there is no alignment requirement on the out pointer // this version uses differential coding (coding differences between values) starting at prev (you can often set prev to zero) // For safety, the out pointer should point to at least streamvbyte_max_compressedbyte(length) // bytes ( see streamvbyte.h ) size_t streamvbyte_delta_encode(const uint32_t *in, uint32_t length, uint8_t *out, uint32_t prev); // Read "length" 32-bit integers in StreamVByte format from in, storing the result in out. // Returns the number of bytes read. We may read up to STREAMVBYTE_PADDING extra bytes // from the input buffer (these bytes are read but never used). // The caller is responsible for knowing how many integers ("length") are to be read: // this information ought to be stored somehow. // There is no alignment requirement on the "in" pointer. // The out pointer should point to length * sizeof(uint32_t) bytes. // this version uses differential coding (coding differences between values) starting at prev (you can often set prev to zero) size_t streamvbyte_delta_decode(const uint8_t *in, uint32_t *out, uint32_t length, uint32_t prev); #if defined(__cplusplus) }; #endif #endif /* INCLUDE_STREAMVBYTEDELTA_H_ */ streamvbyte-0.5.1/src/000077500000000000000000000000001427353355200146625ustar00rootroot00000000000000streamvbyte-0.5.1/src/streamvbyte_0124_decode.c000066400000000000000000000117611427353355200213520ustar00rootroot00000000000000#include "streamvbyte.h" #include "streamvbyte_isadetection.h" #ifdef STREAMVBYTE_X64 #include "streamvbyte_shuffle_tables_0124_decode.h" #endif #include // for memcpy #ifdef STREAMVBYTE_X64 STREAMVBYTE_TARGET_SSSE3 static inline __m128i _decode_avx(uint32_t key, const uint8_t *__restrict__ *dataPtrPtr) { uint8_t len; __m128i Data = _mm_loadu_si128((__m128i *)*dataPtrPtr); uint8_t *pshuf = (uint8_t *) &shuffleTable[key]; __m128i Shuf = *(__m128i *)pshuf; len = lengthTable[key]; Data = _mm_shuffle_epi8(Data, Shuf); *dataPtrPtr += len; return Data; } STREAMVBYTE_UNTARGET_REGION STREAMVBYTE_TARGET_SSSE3 static inline void _write_avx(uint32_t *out, __m128i Vec) { _mm_storeu_si128((__m128i *)out, Vec); } STREAMVBYTE_UNTARGET_REGION #endif // STREAMVBYTE_X64 static inline uint32_t _decode_data(const uint8_t **dataPtrPtr, uint8_t code) { const uint8_t *dataPtr = *dataPtrPtr; uint32_t val; if (code == 0) { // 0 byte val = 0; } else if (code == 1) { // 1 bytes val = (uint32_t)*dataPtr; dataPtr += 1; } else if (code == 2) { // 2 bytes val = 0; memcpy(&val, dataPtr, 2); // assumes little endian dataPtr += 2; } else { // code == 3, 4 bytes memcpy(&val, dataPtr, 4); dataPtr += 4; } *dataPtrPtr = dataPtr; return val; } static const uint8_t *svb_decode_scalar(uint32_t *outPtr, const uint8_t *keyPtr, const uint8_t *dataPtr, uint32_t count) { if (count == 0) return dataPtr; // no reads or writes if no data uint8_t shift = 0; uint32_t key = *keyPtr++; for (uint32_t c = 0; c < count; c++) { if (shift == 8) { shift = 0; key = *keyPtr++; } uint32_t val = _decode_data(&dataPtr, (key >> shift) & 0x3); *outPtr++ = val; shift += 2; } return dataPtr; // pointer to first unused byte after end } #ifdef STREAMVBYTE_X64 STREAMVBYTE_TARGET_SSSE3 static const uint8_t *svb_decode_avx_simple(uint32_t *out, const uint8_t *__restrict__ keyPtr, const uint8_t *__restrict__ dataPtr, uint64_t count) { uint64_t keybytes = count / 4; // number of key bytes __m128i Data; if (keybytes >= 8) { int64_t Offset = -(int64_t)keybytes / 8 + 1; const uint64_t *keyPtr64 = (const uint64_t *)keyPtr - Offset; uint64_t nextkeys; memcpy(&nextkeys, keyPtr64 + Offset, sizeof(nextkeys)); for (; Offset != 0; ++Offset) { uint64_t keys = nextkeys; memcpy(&nextkeys, keyPtr64 + Offset + 1, sizeof(nextkeys)); Data = _decode_avx((keys & 0xFF), &dataPtr); _write_avx(out, Data); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); _write_avx(out + 4, Data); keys >>= 16; Data = _decode_avx((keys & 0xFF), &dataPtr); _write_avx(out + 8, Data); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); _write_avx(out + 12, Data); keys >>= 16; Data = _decode_avx((keys & 0xFF), &dataPtr); _write_avx(out + 16, Data); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); _write_avx(out + 20, Data); keys >>= 16; Data = _decode_avx((keys & 0xFF), &dataPtr); _write_avx(out + 24, Data); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); _write_avx(out + 28, Data); out += 32; } { uint64_t keys = nextkeys; Data = _decode_avx((keys & 0xFF), &dataPtr); _write_avx(out, Data); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); _write_avx(out + 4, Data); keys >>= 16; Data = _decode_avx((keys & 0xFF), &dataPtr); _write_avx(out + 8, Data); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); _write_avx(out + 12, Data); keys >>= 16; Data = _decode_avx((keys & 0xFF), &dataPtr); _write_avx(out + 16, Data); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); _write_avx(out + 20, Data); keys >>= 16; Data = _decode_avx((keys & 0xFF), &dataPtr); _write_avx(out + 24, Data); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); _write_avx(out + 28, Data); out += 32; } } return dataPtr; } STREAMVBYTE_UNTARGET_REGION #endif // Read count 32-bit integers in maskedvbyte format from in, storing the result // in out. Returns the number of bytes read. size_t streamvbyte_decode_0124(const uint8_t *in, uint32_t *out, uint32_t count) { if (count == 0) return 0; const uint8_t *keyPtr = in; // full list of keys is next uint32_t keyLen = ((count + 3) / 4); // 2-bits per key (rounded up) const uint8_t *dataPtr = keyPtr + keyLen; // data starts at end of keys #ifdef STREAMVBYTE_X64 if(streamvbyte_ssse3()) { dataPtr = svb_decode_avx_simple(out, keyPtr, dataPtr, count); out += count & ~ 31; keyPtr += (count/4) & ~ 7; count &= 31; } #endif return svb_decode_scalar(out, keyPtr, dataPtr, count) - in; } streamvbyte-0.5.1/src/streamvbyte_0124_encode.c000066400000000000000000000067451427353355200213720ustar00rootroot00000000000000#include "streamvbyte.h" #include "streamvbyte_isadetection.h" #include "streamvbyte_shuffle_tables_0124_encode.h" #include // for memcpy static uint8_t _encode_data(uint32_t val, uint8_t *__restrict__ *dataPtrPtr) { uint8_t *dataPtr = *dataPtrPtr; uint8_t code; if (val == 0) { // 0 bytes code = 0; } else if (val < (1 << 8)) { // 1 bytes *dataPtr = (uint8_t)(val); *dataPtrPtr += 1; code = 1; } else if (val < (1 << 16)) { // 2 bytes memcpy(dataPtr, &val, 2); // assumes little endian *dataPtrPtr += 2; code = 2; } else { // 4 bytes memcpy(dataPtr, &val, sizeof(uint32_t)); *dataPtrPtr += sizeof(uint32_t); code = 3; } return code; } static uint8_t *svb_encode_scalar(const uint32_t *in, uint8_t *__restrict__ keyPtr, uint8_t *__restrict__ dataPtr, uint32_t count) { if (count == 0) return dataPtr; // exit immediately if no data uint8_t shift = 0; // cycles 0, 2, 4, 6, 0, 2, 4, 6, ... uint8_t key = 0; for (uint32_t c = 0; c < count; c++) { if (shift == 8) { shift = 0; *keyPtr++ = key; key = 0; } uint32_t val = in[c]; uint8_t code = _encode_data(val, &dataPtr); key |= code << shift; shift += 2; } *keyPtr = key; // write last key (no increment needed) return dataPtr; // pointer to first unused data byte } #ifdef STREAMVBYTE_X64 STREAMVBYTE_TARGET_SSSE3 static size_t streamvbyte_encode4(__m128i in, uint8_t *outData, uint8_t *outCode) { const __m128i Ones = _mm_set1_epi32(0x01010101); const __m128i GatherBits = _mm_set1_epi32(0x08040102); const __m128i CodeTable = _mm_set_epi32(0x03030303, 0x03030303, 0x03030303, 0x02020100); const __m128i GatherBytes = _mm_set_epi32(0, 0, 0x0D090501, 0x0D090501); const __m128i Aggregators = _mm_set_epi32(0, 0, 0x01010101, 0x10400104); __m128i m0, m1; m0 = _mm_min_epu8(in, Ones); // set byte to 1 if it is not zero m0 = _mm_madd_epi16(m0, GatherBits); // gather bits 8,16,24 to bits 8,9,10 m1 = _mm_shuffle_epi8(CodeTable, m0); // translate to a 2-bit encoded symbol m1 = _mm_shuffle_epi8(m1, GatherBytes); // gather bytes holding symbols; 2 copies m1 = _mm_madd_epi16(m1, Aggregators); // sum dword_1, pack dword_0 size_t code = (size_t)_mm_extract_epi8(m1, 1); size_t length = lengthTable[code]; __m128i* shuf = (__m128i*)(((uint8_t*)encodingShuffleTable) + code * 16); __m128i out = _mm_shuffle_epi8(in, _mm_loadu_si128(shuf)); // todo: aligned access _mm_storeu_si128((__m128i *)outData, out); *outCode = (uint8_t)code; return length; } STREAMVBYTE_UNTARGET_REGION STREAMVBYTE_TARGET_SSSE3 static size_t streamvbyte_encode_quad(const uint32_t *in, uint8_t *outData, uint8_t *outKey) { __m128i vin = _mm_loadu_si128((__m128i *) in ); return streamvbyte_encode4(vin, outData, outKey); } STREAMVBYTE_UNTARGET_REGION #endif size_t streamvbyte_encode_0124(const uint32_t *in, uint32_t count, uint8_t *out) { uint8_t *keyPtr = out; uint32_t keyLen = (count + 3) / 4; // 2-bits rounded to full byte uint8_t *dataPtr = keyPtr + keyLen; // variable byte data after all keys #ifdef STREAMVBYTE_X64 if(streamvbyte_ssse3()) { uint32_t count_quads = count / 4; count -= 4 * count_quads; for (uint32_t c = 0; c < count_quads; c++) { dataPtr += streamvbyte_encode_quad(in, dataPtr, keyPtr); keyPtr++; in += 4; } } #endif return svb_encode_scalar(in, keyPtr, dataPtr, count) - out; } streamvbyte-0.5.1/src/streamvbyte_arm_decode.c000066400000000000000000000031011427353355200215300ustar00rootroot00000000000000 #include "streamvbyte_isadetection.h" #ifdef STREAMVBYTE_ARM #include "streamvbyte_shuffle_tables_decode.h" #ifdef __aarch64__ typedef uint8x16_t decode_t; #else typedef uint8x8x2_t decode_t; #endif static inline decode_t _decode_neon(const uint8_t key, const uint8_t * restrict *dataPtrPtr) { uint8_t len; uint8_t *pshuf = (uint8_t *)&shuffleTable[key]; uint8x16_t decodingShuffle = vld1q_u8(pshuf); uint8x16_t compressed = vld1q_u8(*dataPtrPtr); #ifdef AVOIDLENGTHLOOKUP // this avoids the dependency on lengthTable, // see https://github.com/lemire/streamvbyte/issues/12 len = pshuf[12 + (key >> 6)] + 1; #else len = lengthTable[key]; #endif #ifdef __aarch64__ uint8x16_t data = vqtbl1q_u8(compressed, decodingShuffle); #else uint8x8x2_t codehalves = {{vget_low_u8(compressed), vget_high_u8(compressed)}}; uint8x8x2_t data = {{vtbl2_u8(codehalves, vget_low_u8(decodingShuffle)), vtbl2_u8(codehalves, vget_high_u8(decodingShuffle))}}; #endif *dataPtrPtr += len; return data; } static void streamvbyte_decode_quad( const uint8_t * restrict *dataPtrPtr, uint8_t key, uint32_t * restrict out ) { decode_t data =_decode_neon( key, dataPtrPtr ); #ifdef __aarch64__ vst1q_u8((uint8_t *) out, data); #else vst1_u8((uint8_t *) out, data.val[0]); vst1_u8((uint8_t *) (out + 2), data.val[1]); #endif } static const uint8_t *svb_decode_vector(uint32_t *out, const uint8_t *keyPtr, const uint8_t *dataPtr, uint32_t count) { for(uint32_t i = 0; i < count/4; i++) streamvbyte_decode_quad( &dataPtr, keyPtr[i], out + 4*i ); return dataPtr; } #endif streamvbyte-0.5.1/src/streamvbyte_arm_encode.c000066400000000000000000000041711427353355200215520ustar00rootroot00000000000000#include "streamvbyte_isadetection.h" #include "streamvbyte_shuffle_tables_encode.h" #ifdef STREAMVBYTE_ARM static const uint8_t pgatherlo[] = {12, 8, 4, 0, 12, 8, 4, 0}; // apparently only used in streamvbyte_encode4 #define concat (1 | 1 << 10 | 1 << 20 | 1 << 30) #define sum (1 | 1 << 8 | 1 << 16 | 1 << 24) static const uint32_t pAggregators[2] = {concat, sum}; // apparently only used in streamvbyte_encode4 static inline size_t streamvbyte_encode4(uint32x4_t data, uint8_t *__restrict__ outData, uint8_t *__restrict__ outCode) { const uint8x8_t gatherlo = vld1_u8(pgatherlo); const uint32x2_t Aggregators = vld1_u32(pAggregators); // lane code is 3 - (saturating sub) (clz(data)/8) uint32x4_t clzbytes = vshrq_n_u32(vclzq_u32(data), 3); uint32x4_t lanecodes = vqsubq_u32(vdupq_n_u32(3), clzbytes); // nops uint8x16_t lanebytes = vreinterpretq_u8_u32(lanecodes); #ifdef __aarch64__ uint8x8_t lobytes = vqtbl1_u8( lanebytes, gatherlo ); #else uint8x8x2_t twohalves = {{vget_low_u8(lanebytes), vget_high_u8(lanebytes)}}; // shuffle lsbytes into two copies of an int uint8x8_t lobytes = vtbl2_u8(twohalves, gatherlo); #endif uint32x2_t mulshift = vreinterpret_u32_u8(lobytes); uint32_t codeAndLength[2]; vst1_u32(codeAndLength, vmul_u32(mulshift, Aggregators)); uint32_t code = codeAndLength[0] >> 24; size_t length = 4 + (codeAndLength[1] >> 24); // shuffle in 8-byte chunks uint8x16_t databytes = vreinterpretq_u8_u32(data); uint8x16_t encodingShuffle = vld1q_u8((uint8_t *) &encodingShuffleTable[code]); #ifdef __aarch64__ vst1q_u8(outData, vqtbl1q_u8(databytes, encodingShuffle)); #else uint8x8x2_t datahalves = {{vget_low_u8(databytes), vget_high_u8(databytes)}}; vst1_u8(outData, vtbl2_u8(datahalves, vget_low_u8(encodingShuffle))); vst1_u8(outData + 8, vtbl2_u8(datahalves, vget_high_u8(encodingShuffle))); #endif *outCode = (uint8_t) code; return length; } static inline size_t streamvbyte_encode_quad(const uint32_t *__restrict__ in, uint8_t *__restrict__ outData, uint8_t *__restrict__ outCode) { uint32x4_t inq = vld1q_u32(in); return streamvbyte_encode4(inq, outData, outCode); } #endif streamvbyte-0.5.1/src/streamvbyte_decode.c000066400000000000000000000044661427353355200207100ustar00rootroot00000000000000#include "streamvbyte.h" #include "streamvbyte_isadetection.h" #include // for memcpy #include "streamvbyte_shuffle_tables_decode.h" #ifdef __ARM_NEON__ #include "streamvbyte_arm_decode.c" #endif #ifdef STREAMVBYTE_X64 #include "streamvbyte_x64_decode.c" #endif // STREAMVBYTE_X64 static inline uint32_t _decode_data(const uint8_t **dataPtrPtr, uint8_t code) { const uint8_t *dataPtr = *dataPtrPtr; uint32_t val; if (code == 0) { // 1 byte val = (uint32_t)*dataPtr; dataPtr += 1; } else if (code == 1) { // 2 bytes val = 0; memcpy(&val, dataPtr, 2); // assumes little endian dataPtr += 2; } else if (code == 2) { // 3 bytes val = 0; memcpy(&val, dataPtr, 3); // assumes little endian dataPtr += 3; } else { // code == 3 memcpy(&val, dataPtr, 4); dataPtr += 4; } *dataPtrPtr = dataPtr; return val; } static const uint8_t *svb_decode_scalar(uint32_t *outPtr, const uint8_t *keyPtr, const uint8_t *dataPtr, uint32_t count) { if (count == 0) return dataPtr; // no reads or writes if no data uint8_t shift = 0; uint32_t key = *keyPtr++; for (uint32_t c = 0; c < count; c++) { if (shift == 8) { shift = 0; key = *keyPtr++; } uint32_t val = _decode_data(&dataPtr, (key >> shift) & 0x3); *outPtr++ = val; shift += 2; } return dataPtr; // pointer to first unused byte after end } // Read count 32-bit integers in maskedvbyte format from in, storing the result // in out. Returns the number of bytes read. size_t streamvbyte_decode(const uint8_t *in, uint32_t *out, uint32_t count) { if (count == 0) return 0; const uint8_t *keyPtr = in; // full list of keys is next uint32_t keyLen = ((count + 3) / 4); // 2-bits per key (rounded up) const uint8_t *dataPtr = keyPtr + keyLen; // data starts at end of keys #ifdef STREAMVBYTE_X64 if(streamvbyte_ssse3()) { dataPtr = svb_decode_avx_simple(out, keyPtr, dataPtr, count); out += count & ~ 31; keyPtr += (count/4) & ~ 7; count &= 31; } #elif defined(__ARM_NEON__) dataPtr = svb_decode_vector(out, keyPtr, dataPtr, count); out += count - (count & 3); keyPtr += count/4; count &= 3; #endif return svb_decode_scalar(out, keyPtr, dataPtr, count) - in; } streamvbyte-0.5.1/src/streamvbyte_encode.c000066400000000000000000000046261427353355200207200ustar00rootroot00000000000000#include "streamvbyte.h" #include "streamvbyte_isadetection.h" #include // for memcpy #include "streamvbyte_shuffle_tables_encode.h" #ifdef STREAMVBYTE_X64 #include "streamvbyte_x64_encode.c" #endif static uint8_t _encode_data(uint32_t val, uint8_t *__restrict__ *dataPtrPtr) { uint8_t *dataPtr = *dataPtrPtr; uint8_t code; if (val < (1 << 8)) { // 1 byte *dataPtr = (uint8_t)(val); *dataPtrPtr += 1; code = 0; } else if (val < (1 << 16)) { // 2 bytes memcpy(dataPtr, &val, 2); // assumes little endian *dataPtrPtr += 2; code = 1; } else if (val < (1 << 24)) { // 3 bytes memcpy(dataPtr, &val, 3); // assumes little endian *dataPtrPtr += 3; code = 2; } else { // 4 bytes memcpy(dataPtr, &val, sizeof(uint32_t)); *dataPtrPtr += sizeof(uint32_t); code = 3; } return code; } static uint8_t *svb_encode_scalar(const uint32_t *in, uint8_t *__restrict__ keyPtr, uint8_t *__restrict__ dataPtr, uint32_t count) { if (count == 0) return dataPtr; // exit immediately if no data uint8_t shift = 0; // cycles 0, 2, 4, 6, 0, 2, 4, 6, ... uint8_t key = 0; for (uint32_t c = 0; c < count; c++) { if (shift == 8) { shift = 0; *keyPtr++ = key; key = 0; } uint32_t val = in[c]; uint8_t code = _encode_data(val, &dataPtr); key |= code << shift; shift += 2; } *keyPtr = key; // write last key (no increment needed) return dataPtr; // pointer to first unused data byte } #ifdef __ARM_NEON__ #include "streamvbyte_arm_encode.c" #endif // Encode an array of a given length read from in to bout in streamvbyte format. // Returns the number of bytes written. size_t streamvbyte_encode(const uint32_t *in, uint32_t count, uint8_t *out) { #ifdef STREAMVBYTE_X64 if(streamvbyte_ssse3()) { return streamvbyte_encode_SSSE3(in,count,out); } #endif uint8_t *keyPtr = out; uint32_t keyLen = (count + 3) / 4; // 2-bits rounded to full byte uint8_t *dataPtr = keyPtr + keyLen; // variable byte data after all keys #if defined(__ARM_NEON__) uint32_t count_quads = count / 4; count -= 4 * count_quads; for (uint32_t c = 0; c < count_quads; c++) { dataPtr += streamvbyte_encode_quad(in, dataPtr, keyPtr); keyPtr++; in += 4; } #endif return svb_encode_scalar(in, keyPtr, dataPtr, count) - out; } streamvbyte-0.5.1/src/streamvbyte_isadetection.h000066400000000000000000000226231427353355200221400ustar00rootroot00000000000000/* From https://github.com/endorno/pytorch/blob/master/torch/lib/TH/generic/simd/simd.h Highly modified. Copyright (c) 2016- Facebook, Inc (Adam Paszke) Copyright (c) 2014- Facebook, Inc (Soumith Chintala) Copyright (c) 2011-2014 Idiap Research Institute (Ronan Collobert) Copyright (c) 2012-2014 Deepmind Technologies (Koray Kavukcuoglu) Copyright (c) 2011-2012 NEC Laboratories America (Koray Kavukcuoglu) Copyright (c) 2011-2013 NYU (Clement Farabet) Copyright (c) 2006-2010 NEC Laboratories America (Ronan Collobert, Leon Bottou, Iain Melvin, Jason Weston) Copyright (c) 2006 Idiap Research Institute (Samy Bengio) Copyright (c) 2001-2004 Idiap Research Institute (Ronan Collobert, Samy Bengio, Johnny Mariethoz) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the names of Facebook, Deepmind Technologies, NYU, NEC Laboratories America and IDIAP Research Institute nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef STREAMVBYTE_ISADETECTION_H #define STREAMVBYTE_ISADETECTION_H #include #include #include #if defined(_MSC_VER) /* Microsoft C/C++-compatible compiler */ #include #elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) /* GCC-compatible compiler, targeting x86/x86-64 */ #include #elif defined(__GNUC__) && defined(__ARM_NEON__) /* GCC-compatible compiler, targeting ARM with NEON */ #include #elif defined(__GNUC__) && defined(__IWMMXT__) /* GCC-compatible compiler, targeting ARM with WMMX */ #include #elif (defined(__GNUC__) || defined(__xlC__)) && \ (defined(__VEC__) || defined(__ALTIVEC__)) /* XLC or GCC-compatible compiler, targeting PowerPC with VMX/VSX */ #include #elif defined(__GNUC__) && defined(__SPE__) /* GCC-compatible compiler, targeting PowerPC with SPE */ #include #endif #if defined(HAVE_GCC_GET_CPUID) && defined(USE_GCC_GET_CPUID) #include #endif // defined(_MSC_VER) enum streamvbyte_instruction_set { streamvbyte_DEFAULT = 0x0, streamvbyte_NEON = 0x1, streamvbyte_SSSE3 = 0x2, streamvbyte_AVX2 = 0x4, streamvbyte_SSE42 = 0x8, streamvbyte_PCLMULQDQ = 0x10, streamvbyte_BMI1 = 0x20, streamvbyte_BMI2 = 0x40, streamvbyte_ALTIVEC = 0x80, streamvbyte_UNINITIALIZED = 0x8000 }; #if defined(__PPC64__) static inline uint32_t dynamic_streamvbyte_detect_supported_architectures() { return streamvbyte_ALTIVEC; } #elif defined(__arm__) || defined(__aarch64__) // incl. armel, armhf, arm64 #if defined(__ARM_NEON) static inline uint32_t dynamic_streamvbyte_detect_supported_architectures() { return streamvbyte_NEON; } #else // ARM without NEON static inline uint32_t dynamic_streamvbyte_detect_supported_architectures() { return streamvbyte_DEFAULT; } #endif #elif defined(__x86_64__) || defined(_M_AMD64) // x64 static inline void cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { #if defined(_MSC_VER) int cpu_info[4]; __cpuid(cpu_info, *eax); *eax = cpu_info[0]; *ebx = cpu_info[1]; *ecx = cpu_info[2]; *edx = cpu_info[3]; #elif defined(HAVE_GCC_GET_CPUID) && defined(USE_GCC_GET_CPUID) uint32_t level = *eax; __get_cpuid(level, eax, ebx, ecx, edx); #else uint32_t a = *eax, b, c = *ecx, d; __asm__("cpuid\n\t" : "+a"(a), "=b"(b), "+c"(c), "=d"(d)); *eax = a; *ebx = b; *ecx = c; *edx = d; #endif } static inline uint32_t dynamic_streamvbyte_detect_supported_architectures() { uint32_t eax, ebx, ecx, edx; uint32_t host_isa = 0x0; // Can be found on Intel ISA Reference for CPUID static uint32_t cpuid_ssse3_bit = 1 << 1; ///< @private Bit 1 of EBX for EAX=0x7 static uint32_t cpuid_avx2_bit = 1 << 5; ///< @private Bit 5 of EBX for EAX=0x7 static uint32_t cpuid_bmi1_bit = 1 << 3; ///< @private bit 3 of EBX for EAX=0x7 static uint32_t cpuid_bmi2_bit = 1 << 8; ///< @private bit 8 of EBX for EAX=0x7 static uint32_t cpuid_sse42_bit = 1 << 20; ///< @private bit 20 of ECX for EAX=0x1 static uint32_t cpuid_pclmulqdq_bit = 1 << 1; ///< @private bit 1 of ECX for EAX=0x1 // ECX for EAX=0x7 eax = 0x7; ecx = 0x0; cpuid(&eax, &ebx, &ecx, &edx); if (ebx & cpuid_avx2_bit) { host_isa |= streamvbyte_AVX2; } if (ebx & cpuid_bmi1_bit) { host_isa |= streamvbyte_BMI1; } if (ebx & cpuid_bmi2_bit) { host_isa |= streamvbyte_BMI2; } // EBX for EAX=0x1 eax = 0x1; cpuid(&eax, &ebx, &ecx, &edx); if (ecx & cpuid_ssse3_bit) { host_isa |= streamvbyte_SSSE3; } if (ecx & cpuid_sse42_bit) { host_isa |= streamvbyte_SSE42; } if (ecx & cpuid_pclmulqdq_bit) { host_isa |= streamvbyte_PCLMULQDQ; } return host_isa; } #else // fallback static inline uint32_t dynamic_streamvbyte_detect_supported_architectures() { return streamvbyte_DEFAULT; } #endif // end SIMD extension detection code #if defined(__x86_64__) || defined(_M_AMD64) // x64 #define STREAMVBYTE_X64 #if defined(__cplusplus) #include static inline uint32_t streamvbyte_detect_supported_architectures() { static std::atomic buffer{streamvbyte_UNINITIALIZED}; if(buffer == streamvbyte_UNINITIALIZED) { buffer = dynamic_streamvbyte_detect_supported_architectures(); } return buffer; } #elif defined(_MSC_VER) && !defined(__clang__) // Visual Studio does not support C11 atomics. static inline uint32_t streamvbyte_detect_supported_architectures() { static int buffer = streamvbyte_UNINITIALIZED; if(buffer == streamvbyte_UNINITIALIZED) { buffer = dynamic_streamvbyte_detect_supported_architectures(); } return buffer; } #else // defined(__cplusplus) and defined(_MSC_VER) && !defined(__clang__) #if __STDC_VERSION__ >= 201112L #include #endif static inline uint32_t streamvbyte_detect_supported_architectures() { #if __STDC_VERSION__ >= 201112L static _Atomic int buffer = streamvbyte_UNINITIALIZED; #else static int buffer = streamvbyte_UNINITIALIZED; #endif if(buffer == streamvbyte_UNINITIALIZED) { buffer = dynamic_streamvbyte_detect_supported_architectures(); } return buffer; } #endif // defined(_MSC_VER) && !defined(__clang__) #if defined(__AVX__) static inline bool streamvbyte_ssse3() { return true; } #else static inline bool streamvbyte_ssse3() { return (streamvbyte_detect_supported_architectures() & streamvbyte_SSSE3) == streamvbyte_SSSE3; } #endif #else // defined(__x86_64__) || defined(_M_AMD64) // x64 static inline bool streamvbyte_ssse3() { return false; } static inline uint32_t streamvbyte_detect_supported_architectures() { // no runtime dispatch return dynamic_streamvbyte_detect_supported_architectures(); } #endif #ifdef __ARM_NEON__ #define STREAMVBYTE_ARM #endif #ifdef STREAMVBYTE_X64 // this is almost standard? #undef STRINGIFY_IMPLEMENTATION_ #undef STRINGIFY #define STRINGIFY_IMPLEMENTATION_(a) #a #define STRINGIFY(a) STRINGIFY_IMPLEMENTATION_(a) #ifdef __clang__ // clang does not have GCC push pop // warning: clang attribute push can't be used within a namespace in clang up // til 8.0 so STREAMVBYTE_TARGET_REGION and STREAMVBYTE_UNTARGET_REGION must be *outside* of a // namespace. #define STREAMVBYTE_TARGET_REGION(T) \ _Pragma(STRINGIFY( \ clang attribute push(__attribute__((target(T))), apply_to = function))) #define STREAMVBYTE_UNTARGET_REGION _Pragma("clang attribute pop") #elif defined(__GNUC__) // GCC is easier #define STREAMVBYTE_TARGET_REGION(T) \ _Pragma("GCC push_options") _Pragma(STRINGIFY(GCC target(T))) #define STREAMVBYTE_UNTARGET_REGION _Pragma("GCC pop_options") #endif // clang then gcc // Default target region macros don't do anything. #ifndef STREAMVBYTE_TARGET_REGION #define STREAMVBYTE_TARGET_REGION(T) #define STREAMVBYTE_UNTARGET_REGION #endif #define STREAMVBYTE_TARGET_SSSE3 STREAMVBYTE_TARGET_REGION("avx2") #ifdef __AVX___ #undef STREAMVBYTE_TARGET_SSSE3 #define STREAMVBYTE_TARGET_SSSE3 #endif #endif // STREAMVBYTE_IS_X64 #endif // STREAMVBYTE_ISADETECTION_H streamvbyte-0.5.1/src/streamvbyte_shuffle_tables_0124_decode.h000066400000000000000000000522221427353355200244220ustar00rootroot00000000000000// using 0,1,2,4 bytes per value static uint8_t lengthTable[256] ={ 0, 1, 2, 4, 1, 2, 3, 5, 2, 3, 4, 6, 4, 5, 6, 8, 1, 2, 3, 5, 2, 3, 4, 6, 3, 4, 5, 7, 5, 6, 7, 9, 2, 3, 4, 6, 3, 4, 5, 7, 4, 5, 6, 8, 6, 7, 8, 10, 4, 5, 6, 8, 5, 6, 7, 9, 6, 7, 8, 10, 8, 9, 10, 12, 1, 2, 3, 5, 2, 3, 4, 6, 3, 4, 5, 7, 5, 6, 7, 9, 2, 3, 4, 6, 3, 4, 5, 7, 4, 5, 6, 8, 6, 7, 8, 10, 3, 4, 5, 7, 4, 5, 6, 8, 5, 6, 7, 9, 7, 8, 9, 11, 5, 6, 7, 9, 6, 7, 8, 10, 7, 8, 9, 11, 9, 10, 11, 13, 2, 3, 4, 6, 3, 4, 5, 7, 4, 5, 6, 8, 6, 7, 8, 10, 3, 4, 5, 7, 4, 5, 6, 8, 5, 6, 7, 9, 7, 8, 9, 11, 4, 5, 6, 8, 5, 6, 7, 9, 6, 7, 8, 10, 8, 9, 10, 12, 6, 7, 8, 10, 7, 8, 9, 11, 8, 9, 10, 12, 10, 11, 12, 14, 4, 5, 6, 8, 5, 6, 7, 9, 6, 7, 8, 10, 8, 9, 10, 12, 5, 6, 7, 9, 6, 7, 8, 10, 7, 8, 9, 11, 9, 10, 11, 13, 6, 7, 8, 10, 7, 8, 9, 11, 8, 9, 10, 12, 10, 11, 12, 14, 8, 9, 10, 12, 9, 10, 11, 13, 10, 11, 12, 14, 12, 13, 14, 16, }; // decoding: static uint8_t shuffleTable[256][16] = { { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0000 { 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1000 { 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2000 { 0, 1, 2, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3000 { -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0100 { 0, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1100 { 0, 1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2100 { 0, 1, 2, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3100 { -1, -1, -1, -1, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0200 { 0, -1, -1, -1, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1200 { 0, 1, -1, -1, 2, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2200 { 0, 1, 2, 3, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3200 { -1, -1, -1, -1, 0, 1, 2, 3, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0300 { 0, -1, -1, -1, 1, 2, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1300 { 0, 1, -1, -1, 2, 3, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2300 { 0, 1, 2, 3, 4, 5, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3300 { -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1 }, // 0010 { 0, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1 }, // 1010 { 0, 1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1 }, // 2010 { 0, 1, 2, 3, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1 }, // 3010 { -1, -1, -1, -1, 0, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1 }, // 0110 { 0, -1, -1, -1, 1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1 }, // 1110 { 0, 1, -1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1 }, // 2110 { 0, 1, 2, 3, 4, -1, -1, -1, 5, -1, -1, -1, -1, -1, -1, -1 }, // 3110 { -1, -1, -1, -1, 0, 1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1 }, // 0210 { 0, -1, -1, -1, 1, 2, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1 }, // 1210 { 0, 1, -1, -1, 2, 3, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1 }, // 2210 { 0, 1, 2, 3, 4, 5, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1 }, // 3210 { -1, -1, -1, -1, 0, 1, 2, 3, 4, -1, -1, -1, -1, -1, -1, -1 }, // 0310 { 0, -1, -1, -1, 1, 2, 3, 4, 5, -1, -1, -1, -1, -1, -1, -1 }, // 1310 { 0, 1, -1, -1, 2, 3, 4, 5, 6, -1, -1, -1, -1, -1, -1, -1 }, // 2310 { 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, -1, -1, -1, -1 }, // 3310 { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, -1, -1, -1, -1, -1 }, // 0020 { 0, -1, -1, -1, -1, -1, -1, -1, 1, 2, -1, -1, -1, -1, -1, -1 }, // 1020 { 0, 1, -1, -1, -1, -1, -1, -1, 2, 3, -1, -1, -1, -1, -1, -1 }, // 2020 { 0, 1, 2, 3, -1, -1, -1, -1, 4, 5, -1, -1, -1, -1, -1, -1 }, // 3020 { -1, -1, -1, -1, 0, -1, -1, -1, 1, 2, -1, -1, -1, -1, -1, -1 }, // 0120 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, -1, -1, -1, -1, -1, -1 }, // 1120 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, -1, -1, -1, -1, -1, -1 }, // 2120 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, -1, -1, -1, -1, -1, -1 }, // 3120 { -1, -1, -1, -1, 0, 1, -1, -1, 2, 3, -1, -1, -1, -1, -1, -1 }, // 0220 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, -1, -1, -1, -1, -1, -1 }, // 1220 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, -1, -1, -1, -1, -1, -1 }, // 2220 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, -1, -1, -1, -1, -1, -1 }, // 3220 { -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, -1, -1, -1, -1, -1, -1 }, // 0320 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, -1, -1, -1, -1, -1, -1 }, // 1320 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, -1, -1, -1, -1, -1, -1 }, // 2320 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1 }, // 3320 { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, -1, -1, -1, -1 }, // 0030 { 0, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 4, -1, -1, -1, -1 }, // 1030 { 0, 1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 5, -1, -1, -1, -1 }, // 2030 { 0, 1, 2, 3, -1, -1, -1, -1, 4, 5, 6, 7, -1, -1, -1, -1 }, // 3030 { -1, -1, -1, -1, 0, -1, -1, -1, 1, 2, 3, 4, -1, -1, -1, -1 }, // 0130 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, 4, 5, -1, -1, -1, -1 }, // 1130 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, 5, 6, -1, -1, -1, -1 }, // 2130 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, 7, 8, -1, -1, -1, -1 }, // 3130 { -1, -1, -1, -1, 0, 1, -1, -1, 2, 3, 4, 5, -1, -1, -1, -1 }, // 0230 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, 5, 6, -1, -1, -1, -1 }, // 1230 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, 6, 7, -1, -1, -1, -1 }, // 2230 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, -1, -1, -1, -1 }, // 3230 { -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, -1, -1, -1, -1 }, // 0330 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, -1 }, // 1330 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1 }, // 2330 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1 }, // 3330 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1 }, // 0001 { 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1 }, // 1001 { 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1 }, // 2001 { 0, 1, 2, 3, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1 }, // 3001 { -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1 }, // 0101 { 0, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1 }, // 1101 { 0, 1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, 3, -1, -1, -1 }, // 2101 { 0, 1, 2, 3, 4, -1, -1, -1, -1, -1, -1, -1, 5, -1, -1, -1 }, // 3101 { -1, -1, -1, -1, 0, 1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1 }, // 0201 { 0, -1, -1, -1, 1, 2, -1, -1, -1, -1, -1, -1, 3, -1, -1, -1 }, // 1201 { 0, 1, -1, -1, 2, 3, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1 }, // 2201 { 0, 1, 2, 3, 4, 5, -1, -1, -1, -1, -1, -1, 6, -1, -1, -1 }, // 3201 { -1, -1, -1, -1, 0, 1, 2, 3, -1, -1, -1, -1, 4, -1, -1, -1 }, // 0301 { 0, -1, -1, -1, 1, 2, 3, 4, -1, -1, -1, -1, 5, -1, -1, -1 }, // 1301 { 0, 1, -1, -1, 2, 3, 4, 5, -1, -1, -1, -1, 6, -1, -1, -1 }, // 2301 { 0, 1, 2, 3, 4, 5, 6, 7, -1, -1, -1, -1, 8, -1, -1, -1 }, // 3301 { -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, 1, -1, -1, -1 }, // 0011 { 0, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 2, -1, -1, -1 }, // 1011 { 0, 1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, 3, -1, -1, -1 }, // 2011 { 0, 1, 2, 3, -1, -1, -1, -1, 4, -1, -1, -1, 5, -1, -1, -1 }, // 3011 { -1, -1, -1, -1, 0, -1, -1, -1, 1, -1, -1, -1, 2, -1, -1, -1 }, // 0111 { 0, -1, -1, -1, 1, -1, -1, -1, 2, -1, -1, -1, 3, -1, -1, -1 }, // 1111 { 0, 1, -1, -1, 2, -1, -1, -1, 3, -1, -1, -1, 4, -1, -1, -1 }, // 2111 { 0, 1, 2, 3, 4, -1, -1, -1, 5, -1, -1, -1, 6, -1, -1, -1 }, // 3111 { -1, -1, -1, -1, 0, 1, -1, -1, 2, -1, -1, -1, 3, -1, -1, -1 }, // 0211 { 0, -1, -1, -1, 1, 2, -1, -1, 3, -1, -1, -1, 4, -1, -1, -1 }, // 1211 { 0, 1, -1, -1, 2, 3, -1, -1, 4, -1, -1, -1, 5, -1, -1, -1 }, // 2211 { 0, 1, 2, 3, 4, 5, -1, -1, 6, -1, -1, -1, 7, -1, -1, -1 }, // 3211 { -1, -1, -1, -1, 0, 1, 2, 3, 4, -1, -1, -1, 5, -1, -1, -1 }, // 0311 { 0, -1, -1, -1, 1, 2, 3, 4, 5, -1, -1, -1, 6, -1, -1, -1 }, // 1311 { 0, 1, -1, -1, 2, 3, 4, 5, 6, -1, -1, -1, 7, -1, -1, -1 }, // 2311 { 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, 9, -1, -1, -1 }, // 3311 { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, -1, 2, -1, -1, -1 }, // 0021 { 0, -1, -1, -1, -1, -1, -1, -1, 1, 2, -1, -1, 3, -1, -1, -1 }, // 1021 { 0, 1, -1, -1, -1, -1, -1, -1, 2, 3, -1, -1, 4, -1, -1, -1 }, // 2021 { 0, 1, 2, 3, -1, -1, -1, -1, 4, 5, -1, -1, 6, -1, -1, -1 }, // 3021 { -1, -1, -1, -1, 0, -1, -1, -1, 1, 2, -1, -1, 3, -1, -1, -1 }, // 0121 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, -1, -1, 4, -1, -1, -1 }, // 1121 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, -1, -1, 5, -1, -1, -1 }, // 2121 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, -1, -1, 7, -1, -1, -1 }, // 3121 { -1, -1, -1, -1, 0, 1, -1, -1, 2, 3, -1, -1, 4, -1, -1, -1 }, // 0221 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, -1, -1, 5, -1, -1, -1 }, // 1221 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, -1, -1, 6, -1, -1, -1 }, // 2221 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, -1, -1, 8, -1, -1, -1 }, // 3221 { -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, -1, -1, 6, -1, -1, -1 }, // 0321 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, -1, -1, 7, -1, -1, -1 }, // 1321 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, -1, -1, 8, -1, -1, -1 }, // 2321 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, 10, -1, -1, -1 }, // 3321 { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, -1, -1, -1 }, // 0031 { 0, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 4, 5, -1, -1, -1 }, // 1031 { 0, 1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 5, 6, -1, -1, -1 }, // 2031 { 0, 1, 2, 3, -1, -1, -1, -1, 4, 5, 6, 7, 8, -1, -1, -1 }, // 3031 { -1, -1, -1, -1, 0, -1, -1, -1, 1, 2, 3, 4, 5, -1, -1, -1 }, // 0131 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, 4, 5, 6, -1, -1, -1 }, // 1131 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, 5, 6, 7, -1, -1, -1 }, // 2131 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, 7, 8, 9, -1, -1, -1 }, // 3131 { -1, -1, -1, -1, 0, 1, -1, -1, 2, 3, 4, 5, 6, -1, -1, -1 }, // 0231 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, 5, 6, 7, -1, -1, -1 }, // 1231 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, 6, 7, 8, -1, -1, -1 }, // 2231 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, -1, -1, -1 }, // 3231 { -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1 }, // 0331 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1 }, // 1331 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1 }, // 2331 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1 }, // 3331 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, -1 }, // 0002 { 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, -1, -1 }, // 1002 { 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 3, -1, -1 }, // 2002 { 0, 1, 2, 3, -1, -1, -1, -1, -1, -1, -1, -1, 4, 5, -1, -1 }, // 3002 { -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, 1, 2, -1, -1 }, // 0102 { 0, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 2, 3, -1, -1 }, // 1102 { 0, 1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, 3, 4, -1, -1 }, // 2102 { 0, 1, 2, 3, 4, -1, -1, -1, -1, -1, -1, -1, 5, 6, -1, -1 }, // 3102 { -1, -1, -1, -1, 0, 1, -1, -1, -1, -1, -1, -1, 2, 3, -1, -1 }, // 0202 { 0, -1, -1, -1, 1, 2, -1, -1, -1, -1, -1, -1, 3, 4, -1, -1 }, // 1202 { 0, 1, -1, -1, 2, 3, -1, -1, -1, -1, -1, -1, 4, 5, -1, -1 }, // 2202 { 0, 1, 2, 3, 4, 5, -1, -1, -1, -1, -1, -1, 6, 7, -1, -1 }, // 3202 { -1, -1, -1, -1, 0, 1, 2, 3, -1, -1, -1, -1, 4, 5, -1, -1 }, // 0302 { 0, -1, -1, -1, 1, 2, 3, 4, -1, -1, -1, -1, 5, 6, -1, -1 }, // 1302 { 0, 1, -1, -1, 2, 3, 4, 5, -1, -1, -1, -1, 6, 7, -1, -1 }, // 2302 { 0, 1, 2, 3, 4, 5, 6, 7, -1, -1, -1, -1, 8, 9, -1, -1 }, // 3302 { -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, 1, 2, -1, -1 }, // 0012 { 0, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 2, 3, -1, -1 }, // 1012 { 0, 1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, 3, 4, -1, -1 }, // 2012 { 0, 1, 2, 3, -1, -1, -1, -1, 4, -1, -1, -1, 5, 6, -1, -1 }, // 3012 { -1, -1, -1, -1, 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, -1, -1 }, // 0112 { 0, -1, -1, -1, 1, -1, -1, -1, 2, -1, -1, -1, 3, 4, -1, -1 }, // 1112 { 0, 1, -1, -1, 2, -1, -1, -1, 3, -1, -1, -1, 4, 5, -1, -1 }, // 2112 { 0, 1, 2, 3, 4, -1, -1, -1, 5, -1, -1, -1, 6, 7, -1, -1 }, // 3112 { -1, -1, -1, -1, 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, -1, -1 }, // 0212 { 0, -1, -1, -1, 1, 2, -1, -1, 3, -1, -1, -1, 4, 5, -1, -1 }, // 1212 { 0, 1, -1, -1, 2, 3, -1, -1, 4, -1, -1, -1, 5, 6, -1, -1 }, // 2212 { 0, 1, 2, 3, 4, 5, -1, -1, 6, -1, -1, -1, 7, 8, -1, -1 }, // 3212 { -1, -1, -1, -1, 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, -1, -1 }, // 0312 { 0, -1, -1, -1, 1, 2, 3, 4, 5, -1, -1, -1, 6, 7, -1, -1 }, // 1312 { 0, 1, -1, -1, 2, 3, 4, 5, 6, -1, -1, -1, 7, 8, -1, -1 }, // 2312 { 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, 9, 10, -1, -1 }, // 3312 { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, -1, 2, 3, -1, -1 }, // 0022 { 0, -1, -1, -1, -1, -1, -1, -1, 1, 2, -1, -1, 3, 4, -1, -1 }, // 1022 { 0, 1, -1, -1, -1, -1, -1, -1, 2, 3, -1, -1, 4, 5, -1, -1 }, // 2022 { 0, 1, 2, 3, -1, -1, -1, -1, 4, 5, -1, -1, 6, 7, -1, -1 }, // 3022 { -1, -1, -1, -1, 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, -1, -1 }, // 0122 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, -1, -1, 4, 5, -1, -1 }, // 1122 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, -1, -1, 5, 6, -1, -1 }, // 2122 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, -1, -1, 7, 8, -1, -1 }, // 3122 { -1, -1, -1, -1, 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, -1, -1 }, // 0222 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, -1, -1, 5, 6, -1, -1 }, // 1222 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, -1, -1, 6, 7, -1, -1 }, // 2222 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, -1, -1, 8, 9, -1, -1 }, // 3222 { -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, -1, -1 }, // 0322 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, -1, -1, 7, 8, -1, -1 }, // 1322 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, -1, -1, 8, 9, -1, -1 }, // 2322 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, 10, 11, -1, -1 }, // 3322 { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, -1, -1 }, // 0032 { 0, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 4, 5, 6, -1, -1 }, // 1032 { 0, 1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 5, 6, 7, -1, -1 }, // 2032 { 0, 1, 2, 3, -1, -1, -1, -1, 4, 5, 6, 7, 8, 9, -1, -1 }, // 3032 { -1, -1, -1, -1, 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, -1, -1 }, // 0132 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, 4, 5, 6, 7, -1, -1 }, // 1132 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, 5, 6, 7, 8, -1, -1 }, // 2132 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, 7, 8, 9, 10, -1, -1 }, // 3132 { -1, -1, -1, -1, 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, -1, -1 }, // 0232 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, 5, 6, 7, 8, -1, -1 }, // 1232 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, 6, 7, 8, 9, -1, -1 }, // 2232 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, 11, -1, -1 }, // 3232 { -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1 }, // 0332 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1 }, // 1332 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1 }, // 2332 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1 }, // 3332 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3 }, // 0003 { 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 4 }, // 1003 { 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 5 }, // 2003 { 0, 1, 2, 3, -1, -1, -1, -1, -1, -1, -1, -1, 4, 5, 6, 7 }, // 3003 { -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 4 }, // 0103 { 0, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 5 }, // 1103 { 0, 1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, 3, 4, 5, 6 }, // 2103 { 0, 1, 2, 3, 4, -1, -1, -1, -1, -1, -1, -1, 5, 6, 7, 8 }, // 3103 { -1, -1, -1, -1, 0, 1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 5 }, // 0203 { 0, -1, -1, -1, 1, 2, -1, -1, -1, -1, -1, -1, 3, 4, 5, 6 }, // 1203 { 0, 1, -1, -1, 2, 3, -1, -1, -1, -1, -1, -1, 4, 5, 6, 7 }, // 2203 { 0, 1, 2, 3, 4, 5, -1, -1, -1, -1, -1, -1, 6, 7, 8, 9 }, // 3203 { -1, -1, -1, -1, 0, 1, 2, 3, -1, -1, -1, -1, 4, 5, 6, 7 }, // 0303 { 0, -1, -1, -1, 1, 2, 3, 4, -1, -1, -1, -1, 5, 6, 7, 8 }, // 1303 { 0, 1, -1, -1, 2, 3, 4, 5, -1, -1, -1, -1, 6, 7, 8, 9 }, // 2303 { 0, 1, 2, 3, 4, 5, 6, 7, -1, -1, -1, -1, 8, 9, 10, 11 }, // 3303 { -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, 1, 2, 3, 4 }, // 0013 { 0, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 2, 3, 4, 5 }, // 1013 { 0, 1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, 3, 4, 5, 6 }, // 2013 { 0, 1, 2, 3, -1, -1, -1, -1, 4, -1, -1, -1, 5, 6, 7, 8 }, // 3013 { -1, -1, -1, -1, 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, 4, 5 }, // 0113 { 0, -1, -1, -1, 1, -1, -1, -1, 2, -1, -1, -1, 3, 4, 5, 6 }, // 1113 { 0, 1, -1, -1, 2, -1, -1, -1, 3, -1, -1, -1, 4, 5, 6, 7 }, // 2113 { 0, 1, 2, 3, 4, -1, -1, -1, 5, -1, -1, -1, 6, 7, 8, 9 }, // 3113 { -1, -1, -1, -1, 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, 5, 6 }, // 0213 { 0, -1, -1, -1, 1, 2, -1, -1, 3, -1, -1, -1, 4, 5, 6, 7 }, // 1213 { 0, 1, -1, -1, 2, 3, -1, -1, 4, -1, -1, -1, 5, 6, 7, 8 }, // 2213 { 0, 1, 2, 3, 4, 5, -1, -1, 6, -1, -1, -1, 7, 8, 9, 10 }, // 3213 { -1, -1, -1, -1, 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, 7, 8 }, // 0313 { 0, -1, -1, -1, 1, 2, 3, 4, 5, -1, -1, -1, 6, 7, 8, 9 }, // 1313 { 0, 1, -1, -1, 2, 3, 4, 5, 6, -1, -1, -1, 7, 8, 9, 10 }, // 2313 { 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, 9, 10, 11, 12 }, // 3313 { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, -1, 2, 3, 4, 5 }, // 0023 { 0, -1, -1, -1, -1, -1, -1, -1, 1, 2, -1, -1, 3, 4, 5, 6 }, // 1023 { 0, 1, -1, -1, -1, -1, -1, -1, 2, 3, -1, -1, 4, 5, 6, 7 }, // 2023 { 0, 1, 2, 3, -1, -1, -1, -1, 4, 5, -1, -1, 6, 7, 8, 9 }, // 3023 { -1, -1, -1, -1, 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, 5, 6 }, // 0123 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, -1, -1, 4, 5, 6, 7 }, // 1123 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, -1, -1, 5, 6, 7, 8 }, // 2123 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, -1, -1, 7, 8, 9, 10 }, // 3123 { -1, -1, -1, -1, 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, 6, 7 }, // 0223 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, -1, -1, 5, 6, 7, 8 }, // 1223 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, -1, -1, 6, 7, 8, 9 }, // 2223 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, -1, -1, 8, 9, 10, 11 }, // 3223 { -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9 }, // 0323 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, -1, -1, 7, 8, 9, 10 }, // 1323 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, -1, -1, 8, 9, 10, 11 }, // 2323 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, 10, 11, 12, 13 }, // 3323 { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7 }, // 0033 { 0, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 4, 5, 6, 7, 8 }, // 1033 { 0, 1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9 }, // 2033 { 0, 1, 2, 3, -1, -1, -1, -1, 4, 5, 6, 7, 8, 9, 10, 11 }, // 3033 { -1, -1, -1, -1, 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, 7, 8 }, // 0133 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9 }, // 1133 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, 5, 6, 7, 8, 9, 10 }, // 2133 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, 7, 8, 9, 10, 11, 12 }, // 3133 { -1, -1, -1, -1, 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9 }, // 0233 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, 5, 6, 7, 8, 9, 10 }, // 1233 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, 6, 7, 8, 9, 10, 11 }, // 2233 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, 11, 12, 13 }, // 3233 { -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }, // 0333 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }, // 1333 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }, // 2333 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, // 3333 }; streamvbyte-0.5.1/src/streamvbyte_shuffle_tables_0124_encode.h000066400000000000000000000524031427353355200244350ustar00rootroot00000000000000#ifndef STREAMVBYTE_SHUFFLE_TABLES_0124_ENCODE_H #define STREAMVBYTE_SHUFFLE_TABLES_0124_ENCODE_H // using 0,1,2,4 bytes per value static uint8_t lengthTable[256] ={ 0, 1, 2, 4, 1, 2, 3, 5, 2, 3, 4, 6, 4, 5, 6, 8, 1, 2, 3, 5, 2, 3, 4, 6, 3, 4, 5, 7, 5, 6, 7, 9, 2, 3, 4, 6, 3, 4, 5, 7, 4, 5, 6, 8, 6, 7, 8, 10, 4, 5, 6, 8, 5, 6, 7, 9, 6, 7, 8, 10, 8, 9, 10, 12, 1, 2, 3, 5, 2, 3, 4, 6, 3, 4, 5, 7, 5, 6, 7, 9, 2, 3, 4, 6, 3, 4, 5, 7, 4, 5, 6, 8, 6, 7, 8, 10, 3, 4, 5, 7, 4, 5, 6, 8, 5, 6, 7, 9, 7, 8, 9, 11, 5, 6, 7, 9, 6, 7, 8, 10, 7, 8, 9, 11, 9, 10, 11, 13, 2, 3, 4, 6, 3, 4, 5, 7, 4, 5, 6, 8, 6, 7, 8, 10, 3, 4, 5, 7, 4, 5, 6, 8, 5, 6, 7, 9, 7, 8, 9, 11, 4, 5, 6, 8, 5, 6, 7, 9, 6, 7, 8, 10, 8, 9, 10, 12, 6, 7, 8, 10, 7, 8, 9, 11, 8, 9, 10, 12, 10, 11, 12, 14, 4, 5, 6, 8, 5, 6, 7, 9, 6, 7, 8, 10, 8, 9, 10, 12, 5, 6, 7, 9, 6, 7, 8, 10, 7, 8, 9, 11, 9, 10, 11, 13, 6, 7, 8, 10, 7, 8, 9, 11, 8, 9, 10, 12, 10, 11, 12, 14, 8, 9, 10, 12, 9, 10, 11, 13, 10, 11, 12, 14, 12, 13, 14, 16, }; // encoding: static uint8_t encodingShuffleTable[256][16] = { { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0000 { 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1000 { 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2000 { 0, 1, 2, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3000 { 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0100 { 0, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1100 { 0, 1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2100 { 0, 1, 2, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3100 { 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0200 { 0, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1200 { 0, 1, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2200 { 0, 1, 2, 3, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3200 { 4, 5, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0300 { 0, 4, 5, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1300 { 0, 1, 4, 5, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2300 { 0, 1, 2, 3, 4, 5, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3300 { 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0010 { 0, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1010 { 0, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2010 { 0, 1, 2, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3010 { 4, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0110 { 0, 4, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1110 { 0, 1, 4, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2110 { 0, 1, 2, 3, 4, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3110 { 4, 5, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0210 { 0, 4, 5, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1210 { 0, 1, 4, 5, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2210 { 0, 1, 2, 3, 4, 5, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3210 { 4, 5, 6, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0310 { 0, 4, 5, 6, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1310 { 0, 1, 4, 5, 6, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2310 { 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, -1, -1, -1, -1 }, // 3310 { 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0020 { 0, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1020 { 0, 1, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2020 { 0, 1, 2, 3, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3020 { 4, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0120 { 0, 4, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1120 { 0, 1, 4, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2120 { 0, 1, 2, 3, 4, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3120 { 4, 5, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0220 { 0, 4, 5, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1220 { 0, 1, 4, 5, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2220 { 0, 1, 2, 3, 4, 5, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3220 { 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0320 { 0, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1320 { 0, 1, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2320 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1 }, // 3320 { 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0030 { 0, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1030 { 0, 1, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2030 { 0, 1, 2, 3, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3030 { 4, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0130 { 0, 4, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1130 { 0, 1, 4, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2130 { 0, 1, 2, 3, 4, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1 }, // 3130 { 4, 5, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0230 { 0, 4, 5, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1230 { 0, 1, 4, 5, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2230 { 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1 }, // 3230 { 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0330 { 0, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1 }, // 1330 { 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1 }, // 2330 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1 }, // 3330 { 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0001 { 0, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1001 { 0, 1, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2001 { 0, 1, 2, 3, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3001 { 4, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0101 { 0, 4, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1101 { 0, 1, 4, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2101 { 0, 1, 2, 3, 4, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3101 { 4, 5, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0201 { 0, 4, 5, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1201 { 0, 1, 4, 5, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2201 { 0, 1, 2, 3, 4, 5, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3201 { 4, 5, 6, 7, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0301 { 0, 4, 5, 6, 7, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1301 { 0, 1, 4, 5, 6, 7, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2301 { 0, 1, 2, 3, 4, 5, 6, 7, 12, -1, -1, -1, -1, -1, -1, -1 }, // 3301 { 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0011 { 0, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1011 { 0, 1, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2011 { 0, 1, 2, 3, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3011 { 4, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0111 { 0, 4, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1111 { 0, 1, 4, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2111 { 0, 1, 2, 3, 4, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3111 { 4, 5, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0211 { 0, 4, 5, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1211 { 0, 1, 4, 5, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2211 { 0, 1, 2, 3, 4, 5, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3211 { 4, 5, 6, 7, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0311 { 0, 4, 5, 6, 7, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1311 { 0, 1, 4, 5, 6, 7, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2311 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, -1, -1, -1, -1, -1, -1 }, // 3311 { 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0021 { 0, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1021 { 0, 1, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2021 { 0, 1, 2, 3, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3021 { 4, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0121 { 0, 4, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1121 { 0, 1, 4, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2121 { 0, 1, 2, 3, 4, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3121 { 4, 5, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0221 { 0, 4, 5, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1221 { 0, 1, 4, 5, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2221 { 0, 1, 2, 3, 4, 5, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1 }, // 3221 { 4, 5, 6, 7, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0321 { 0, 4, 5, 6, 7, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1321 { 0, 1, 4, 5, 6, 7, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1 }, // 2321 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, -1, -1, -1, -1, -1 }, // 3321 { 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0031 { 0, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1031 { 0, 1, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2031 { 0, 1, 2, 3, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1 }, // 3031 { 4, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0131 { 0, 4, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1131 { 0, 1, 4, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2131 { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1 }, // 3131 { 4, 5, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0231 { 0, 4, 5, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1231 { 0, 1, 4, 5, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1 }, // 2231 { 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1 }, // 3231 { 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1 }, // 0331 { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1 }, // 1331 { 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1 }, // 2331 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1 }, // 3331 { 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0002 { 0, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1002 { 0, 1, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2002 { 0, 1, 2, 3, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3002 { 4, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0102 { 0, 4, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1102 { 0, 1, 4, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2102 { 0, 1, 2, 3, 4, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3102 { 4, 5, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0202 { 0, 4, 5, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1202 { 0, 1, 4, 5, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2202 { 0, 1, 2, 3, 4, 5, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3202 { 4, 5, 6, 7, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0302 { 0, 4, 5, 6, 7, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1302 { 0, 1, 4, 5, 6, 7, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2302 { 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, -1, -1, -1, -1, -1, -1 }, // 3302 { 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0012 { 0, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1012 { 0, 1, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2012 { 0, 1, 2, 3, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3012 { 4, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0112 { 0, 4, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1112 { 0, 1, 4, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2112 { 0, 1, 2, 3, 4, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3112 { 4, 5, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0212 { 0, 4, 5, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1212 { 0, 1, 4, 5, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2212 { 0, 1, 2, 3, 4, 5, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 3212 { 4, 5, 6, 7, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0312 { 0, 4, 5, 6, 7, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1312 { 0, 1, 4, 5, 6, 7, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 2312 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 13, -1, -1, -1, -1, -1 }, // 3312 { 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0022 { 0, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1022 { 0, 1, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2022 { 0, 1, 2, 3, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3022 { 4, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0122 { 0, 4, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1122 { 0, 1, 4, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2122 { 0, 1, 2, 3, 4, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 3122 { 4, 5, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0222 { 0, 4, 5, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1222 { 0, 1, 4, 5, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2222 { 0, 1, 2, 3, 4, 5, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1 }, // 3222 { 4, 5, 6, 7, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0322 { 0, 4, 5, 6, 7, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 1322 { 0, 1, 4, 5, 6, 7, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1 }, // 2322 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, -1, -1, -1, -1 }, // 3322 { 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0032 { 0, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1032 { 0, 1, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2032 { 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1 }, // 3032 { 4, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0132 { 0, 4, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1132 { 0, 1, 4, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 2132 { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1 }, // 3132 { 4, 5, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0232 { 0, 4, 5, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 1232 { 0, 1, 4, 5, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1 }, // 2232 { 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1 }, // 3232 { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1 }, // 0332 { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1 }, // 1332 { 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1 }, // 2332 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1 }, // 3332 { 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0003 { 0, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1003 { 0, 1, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2003 { 0, 1, 2, 3, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3003 { 4, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0103 { 0, 4, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1103 { 0, 1, 4, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2103 { 0, 1, 2, 3, 4, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1 }, // 3103 { 4, 5, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0203 { 0, 4, 5, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1203 { 0, 1, 4, 5, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2203 { 0, 1, 2, 3, 4, 5, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 3203 { 4, 5, 6, 7, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0303 { 0, 4, 5, 6, 7, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1 }, // 1303 { 0, 1, 4, 5, 6, 7, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 2303 { 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, -1, -1, -1, -1 }, // 3303 { 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0013 { 0, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1013 { 0, 1, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2013 { 0, 1, 2, 3, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1 }, // 3013 { 4, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0113 { 0, 4, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1113 { 0, 1, 4, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2113 { 0, 1, 2, 3, 4, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 3113 { 4, 5, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0213 { 0, 4, 5, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1213 { 0, 1, 4, 5, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1 }, // 2213 { 0, 1, 2, 3, 4, 5, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 3213 { 4, 5, 6, 7, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1 }, // 0313 { 0, 4, 5, 6, 7, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 1313 { 0, 1, 4, 5, 6, 7, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 2313 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 13, 14, 15, -1, -1, -1 }, // 3313 { 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0023 { 0, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1023 { 0, 1, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2023 { 0, 1, 2, 3, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 3023 { 4, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0123 { 0, 4, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1123 { 0, 1, 4, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1 }, // 2123 { 0, 1, 2, 3, 4, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 3123 { 4, 5, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0223 { 0, 4, 5, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1 }, // 1223 { 0, 1, 4, 5, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 2223 { 0, 1, 2, 3, 4, 5, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1 }, // 3223 { 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 0323 { 0, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 1323 { 0, 1, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1 }, // 2323 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, -1, -1 }, // 3323 { 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0033 { 0, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1 }, // 1033 { 0, 1, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 2033 { 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1 }, // 3033 { 4, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1 }, // 0133 { 0, 4, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 1133 { 0, 1, 4, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 2133 { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1 }, // 3133 { 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 0233 { 0, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 1233 { 0, 1, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1 }, // 2233 { 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1 }, // 3233 { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1 }, // 0333 { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1 }, // 1333 { 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1 }, // 2333 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, // 3333 }; #endif streamvbyte-0.5.1/src/streamvbyte_shuffle_tables_decode.h000066400000000000000000000523671427353355200237660ustar00rootroot00000000000000#ifndef STREAMVBYTE_SHUFFLE_TABLES_H #define STREAMVBYTE_SHUFFLE_TABLES_H #include // using 1,2,3,4 bytes per value static uint8_t lengthTable[256] ={ 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10, 8, 9, 10, 11, 6, 7, 8, 9, 7, 8, 9, 10, 8, 9, 10, 11, 9, 10, 11, 12, 7, 8, 9, 10, 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10, 8, 9, 10, 11, 6, 7, 8, 9, 7, 8, 9, 10, 8, 9, 10, 11, 9, 10, 11, 12, 7, 8, 9, 10, 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14, 6, 7, 8, 9, 7, 8, 9, 10, 8, 9, 10, 11, 9, 10, 11, 12, 7, 8, 9, 10, 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14, 12, 13, 14, 15, 7, 8, 9, 10, 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14, 12, 13, 14, 15, 10, 11, 12, 13, 11, 12, 13, 14, 12, 13, 14, 15, 13, 14, 15, 16, }; // decoding: static uint8_t shuffleTable[256][16] = { { 0, -1, -1, -1, 1, -1, -1, -1, 2, -1, -1, -1, 3, -1, -1, -1 }, // 0000 { 0, 1, -1, -1, 2, -1, -1, -1, 3, -1, -1, -1, 4, -1, -1, -1 }, // 1000 { 0, 1, 2, -1, 3, -1, -1, -1, 4, -1, -1, -1, 5, -1, -1, -1 }, // 2000 { 0, 1, 2, 3, 4, -1, -1, -1, 5, -1, -1, -1, 6, -1, -1, -1 }, // 3000 { 0, -1, -1, -1, 1, 2, -1, -1, 3, -1, -1, -1, 4, -1, -1, -1 }, // 0100 { 0, 1, -1, -1, 2, 3, -1, -1, 4, -1, -1, -1, 5, -1, -1, -1 }, // 1100 { 0, 1, 2, -1, 3, 4, -1, -1, 5, -1, -1, -1, 6, -1, -1, -1 }, // 2100 { 0, 1, 2, 3, 4, 5, -1, -1, 6, -1, -1, -1, 7, -1, -1, -1 }, // 3100 { 0, -1, -1, -1, 1, 2, 3, -1, 4, -1, -1, -1, 5, -1, -1, -1 }, // 0200 { 0, 1, -1, -1, 2, 3, 4, -1, 5, -1, -1, -1, 6, -1, -1, -1 }, // 1200 { 0, 1, 2, -1, 3, 4, 5, -1, 6, -1, -1, -1, 7, -1, -1, -1 }, // 2200 { 0, 1, 2, 3, 4, 5, 6, -1, 7, -1, -1, -1, 8, -1, -1, -1 }, // 3200 { 0, -1, -1, -1, 1, 2, 3, 4, 5, -1, -1, -1, 6, -1, -1, -1 }, // 0300 { 0, 1, -1, -1, 2, 3, 4, 5, 6, -1, -1, -1, 7, -1, -1, -1 }, // 1300 { 0, 1, 2, -1, 3, 4, 5, 6, 7, -1, -1, -1, 8, -1, -1, -1 }, // 2300 { 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, 9, -1, -1, -1 }, // 3300 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, -1, -1, 4, -1, -1, -1 }, // 0010 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, -1, -1, 5, -1, -1, -1 }, // 1010 { 0, 1, 2, -1, 3, -1, -1, -1, 4, 5, -1, -1, 6, -1, -1, -1 }, // 2010 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, -1, -1, 7, -1, -1, -1 }, // 3010 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, -1, -1, 5, -1, -1, -1 }, // 0110 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, -1, -1, 6, -1, -1, -1 }, // 1110 { 0, 1, 2, -1, 3, 4, -1, -1, 5, 6, -1, -1, 7, -1, -1, -1 }, // 2110 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, -1, -1, 8, -1, -1, -1 }, // 3110 { 0, -1, -1, -1, 1, 2, 3, -1, 4, 5, -1, -1, 6, -1, -1, -1 }, // 0210 { 0, 1, -1, -1, 2, 3, 4, -1, 5, 6, -1, -1, 7, -1, -1, -1 }, // 1210 { 0, 1, 2, -1, 3, 4, 5, -1, 6, 7, -1, -1, 8, -1, -1, -1 }, // 2210 { 0, 1, 2, 3, 4, 5, 6, -1, 7, 8, -1, -1, 9, -1, -1, -1 }, // 3210 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, -1, -1, 7, -1, -1, -1 }, // 0310 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, -1, -1, 8, -1, -1, -1 }, // 1310 { 0, 1, 2, -1, 3, 4, 5, 6, 7, 8, -1, -1, 9, -1, -1, -1 }, // 2310 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, 10, -1, -1, -1 }, // 3310 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, 4, -1, 5, -1, -1, -1 }, // 0020 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, 5, -1, 6, -1, -1, -1 }, // 1020 { 0, 1, 2, -1, 3, -1, -1, -1, 4, 5, 6, -1, 7, -1, -1, -1 }, // 2020 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, 7, -1, 8, -1, -1, -1 }, // 3020 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, 5, -1, 6, -1, -1, -1 }, // 0120 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, 6, -1, 7, -1, -1, -1 }, // 1120 { 0, 1, 2, -1, 3, 4, -1, -1, 5, 6, 7, -1, 8, -1, -1, -1 }, // 2120 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, -1, 9, -1, -1, -1 }, // 3120 { 0, -1, -1, -1, 1, 2, 3, -1, 4, 5, 6, -1, 7, -1, -1, -1 }, // 0220 { 0, 1, -1, -1, 2, 3, 4, -1, 5, 6, 7, -1, 8, -1, -1, -1 }, // 1220 { 0, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8, -1, 9, -1, -1, -1 }, // 2220 { 0, 1, 2, 3, 4, 5, 6, -1, 7, 8, 9, -1, 10, -1, -1, -1 }, // 3220 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, 7, -1, 8, -1, -1, -1 }, // 0320 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, 8, -1, 9, -1, -1, -1 }, // 1320 { 0, 1, 2, -1, 3, 4, 5, 6, 7, 8, 9, -1, 10, -1, -1, -1 }, // 2320 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, 11, -1, -1, -1 }, // 3320 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, 4, 5, 6, -1, -1, -1 }, // 0030 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, 5, 6, 7, -1, -1, -1 }, // 1030 { 0, 1, 2, -1, 3, -1, -1, -1, 4, 5, 6, 7, 8, -1, -1, -1 }, // 2030 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, 7, 8, 9, -1, -1, -1 }, // 3030 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, 5, 6, 7, -1, -1, -1 }, // 0130 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, 6, 7, 8, -1, -1, -1 }, // 1130 { 0, 1, 2, -1, 3, 4, -1, -1, 5, 6, 7, 8, 9, -1, -1, -1 }, // 2130 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, -1, -1, -1 }, // 3130 { 0, -1, -1, -1, 1, 2, 3, -1, 4, 5, 6, 7, 8, -1, -1, -1 }, // 0230 { 0, 1, -1, -1, 2, 3, 4, -1, 5, 6, 7, 8, 9, -1, -1, -1 }, // 1230 { 0, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8, 9, 10, -1, -1, -1 }, // 2230 { 0, 1, 2, 3, 4, 5, 6, -1, 7, 8, 9, 10, 11, -1, -1, -1 }, // 3230 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1 }, // 0330 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1 }, // 1330 { 0, 1, 2, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1 }, // 2330 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1 }, // 3330 { 0, -1, -1, -1, 1, -1, -1, -1, 2, -1, -1, -1, 3, 4, -1, -1 }, // 0001 { 0, 1, -1, -1, 2, -1, -1, -1, 3, -1, -1, -1, 4, 5, -1, -1 }, // 1001 { 0, 1, 2, -1, 3, -1, -1, -1, 4, -1, -1, -1, 5, 6, -1, -1 }, // 2001 { 0, 1, 2, 3, 4, -1, -1, -1, 5, -1, -1, -1, 6, 7, -1, -1 }, // 3001 { 0, -1, -1, -1, 1, 2, -1, -1, 3, -1, -1, -1, 4, 5, -1, -1 }, // 0101 { 0, 1, -1, -1, 2, 3, -1, -1, 4, -1, -1, -1, 5, 6, -1, -1 }, // 1101 { 0, 1, 2, -1, 3, 4, -1, -1, 5, -1, -1, -1, 6, 7, -1, -1 }, // 2101 { 0, 1, 2, 3, 4, 5, -1, -1, 6, -1, -1, -1, 7, 8, -1, -1 }, // 3101 { 0, -1, -1, -1, 1, 2, 3, -1, 4, -1, -1, -1, 5, 6, -1, -1 }, // 0201 { 0, 1, -1, -1, 2, 3, 4, -1, 5, -1, -1, -1, 6, 7, -1, -1 }, // 1201 { 0, 1, 2, -1, 3, 4, 5, -1, 6, -1, -1, -1, 7, 8, -1, -1 }, // 2201 { 0, 1, 2, 3, 4, 5, 6, -1, 7, -1, -1, -1, 8, 9, -1, -1 }, // 3201 { 0, -1, -1, -1, 1, 2, 3, 4, 5, -1, -1, -1, 6, 7, -1, -1 }, // 0301 { 0, 1, -1, -1, 2, 3, 4, 5, 6, -1, -1, -1, 7, 8, -1, -1 }, // 1301 { 0, 1, 2, -1, 3, 4, 5, 6, 7, -1, -1, -1, 8, 9, -1, -1 }, // 2301 { 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, 9, 10, -1, -1 }, // 3301 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, -1, -1, 4, 5, -1, -1 }, // 0011 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, -1, -1, 5, 6, -1, -1 }, // 1011 { 0, 1, 2, -1, 3, -1, -1, -1, 4, 5, -1, -1, 6, 7, -1, -1 }, // 2011 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, -1, -1, 7, 8, -1, -1 }, // 3011 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, -1, -1, 5, 6, -1, -1 }, // 0111 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, -1, -1, 6, 7, -1, -1 }, // 1111 { 0, 1, 2, -1, 3, 4, -1, -1, 5, 6, -1, -1, 7, 8, -1, -1 }, // 2111 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, -1, -1, 8, 9, -1, -1 }, // 3111 { 0, -1, -1, -1, 1, 2, 3, -1, 4, 5, -1, -1, 6, 7, -1, -1 }, // 0211 { 0, 1, -1, -1, 2, 3, 4, -1, 5, 6, -1, -1, 7, 8, -1, -1 }, // 1211 { 0, 1, 2, -1, 3, 4, 5, -1, 6, 7, -1, -1, 8, 9, -1, -1 }, // 2211 { 0, 1, 2, 3, 4, 5, 6, -1, 7, 8, -1, -1, 9, 10, -1, -1 }, // 3211 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, -1, -1, 7, 8, -1, -1 }, // 0311 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, -1, -1, 8, 9, -1, -1 }, // 1311 { 0, 1, 2, -1, 3, 4, 5, 6, 7, 8, -1, -1, 9, 10, -1, -1 }, // 2311 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, 10, 11, -1, -1 }, // 3311 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, 4, -1, 5, 6, -1, -1 }, // 0021 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, 5, -1, 6, 7, -1, -1 }, // 1021 { 0, 1, 2, -1, 3, -1, -1, -1, 4, 5, 6, -1, 7, 8, -1, -1 }, // 2021 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, 7, -1, 8, 9, -1, -1 }, // 3021 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, 5, -1, 6, 7, -1, -1 }, // 0121 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, 6, -1, 7, 8, -1, -1 }, // 1121 { 0, 1, 2, -1, 3, 4, -1, -1, 5, 6, 7, -1, 8, 9, -1, -1 }, // 2121 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, -1, 9, 10, -1, -1 }, // 3121 { 0, -1, -1, -1, 1, 2, 3, -1, 4, 5, 6, -1, 7, 8, -1, -1 }, // 0221 { 0, 1, -1, -1, 2, 3, 4, -1, 5, 6, 7, -1, 8, 9, -1, -1 }, // 1221 { 0, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8, -1, 9, 10, -1, -1 }, // 2221 { 0, 1, 2, 3, 4, 5, 6, -1, 7, 8, 9, -1, 10, 11, -1, -1 }, // 3221 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, 7, -1, 8, 9, -1, -1 }, // 0321 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, 8, -1, 9, 10, -1, -1 }, // 1321 { 0, 1, 2, -1, 3, 4, 5, 6, 7, 8, 9, -1, 10, 11, -1, -1 }, // 2321 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, 11, 12, -1, -1 }, // 3321 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, 4, 5, 6, 7, -1, -1 }, // 0031 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, 5, 6, 7, 8, -1, -1 }, // 1031 { 0, 1, 2, -1, 3, -1, -1, -1, 4, 5, 6, 7, 8, 9, -1, -1 }, // 2031 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, 7, 8, 9, 10, -1, -1 }, // 3031 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, 5, 6, 7, 8, -1, -1 }, // 0131 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, 6, 7, 8, 9, -1, -1 }, // 1131 { 0, 1, 2, -1, 3, 4, -1, -1, 5, 6, 7, 8, 9, 10, -1, -1 }, // 2131 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, 11, -1, -1 }, // 3131 { 0, -1, -1, -1, 1, 2, 3, -1, 4, 5, 6, 7, 8, 9, -1, -1 }, // 0231 { 0, 1, -1, -1, 2, 3, 4, -1, 5, 6, 7, 8, 9, 10, -1, -1 }, // 1231 { 0, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8, 9, 10, 11, -1, -1 }, // 2231 { 0, 1, 2, 3, 4, 5, 6, -1, 7, 8, 9, 10, 11, 12, -1, -1 }, // 3231 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1 }, // 0331 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1 }, // 1331 { 0, 1, 2, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1 }, // 2331 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1 }, // 3331 { 0, -1, -1, -1, 1, -1, -1, -1, 2, -1, -1, -1, 3, 4, 5, -1 }, // 0002 { 0, 1, -1, -1, 2, -1, -1, -1, 3, -1, -1, -1, 4, 5, 6, -1 }, // 1002 { 0, 1, 2, -1, 3, -1, -1, -1, 4, -1, -1, -1, 5, 6, 7, -1 }, // 2002 { 0, 1, 2, 3, 4, -1, -1, -1, 5, -1, -1, -1, 6, 7, 8, -1 }, // 3002 { 0, -1, -1, -1, 1, 2, -1, -1, 3, -1, -1, -1, 4, 5, 6, -1 }, // 0102 { 0, 1, -1, -1, 2, 3, -1, -1, 4, -1, -1, -1, 5, 6, 7, -1 }, // 1102 { 0, 1, 2, -1, 3, 4, -1, -1, 5, -1, -1, -1, 6, 7, 8, -1 }, // 2102 { 0, 1, 2, 3, 4, 5, -1, -1, 6, -1, -1, -1, 7, 8, 9, -1 }, // 3102 { 0, -1, -1, -1, 1, 2, 3, -1, 4, -1, -1, -1, 5, 6, 7, -1 }, // 0202 { 0, 1, -1, -1, 2, 3, 4, -1, 5, -1, -1, -1, 6, 7, 8, -1 }, // 1202 { 0, 1, 2, -1, 3, 4, 5, -1, 6, -1, -1, -1, 7, 8, 9, -1 }, // 2202 { 0, 1, 2, 3, 4, 5, 6, -1, 7, -1, -1, -1, 8, 9, 10, -1 }, // 3202 { 0, -1, -1, -1, 1, 2, 3, 4, 5, -1, -1, -1, 6, 7, 8, -1 }, // 0302 { 0, 1, -1, -1, 2, 3, 4, 5, 6, -1, -1, -1, 7, 8, 9, -1 }, // 1302 { 0, 1, 2, -1, 3, 4, 5, 6, 7, -1, -1, -1, 8, 9, 10, -1 }, // 2302 { 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, 9, 10, 11, -1 }, // 3302 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, -1, -1, 4, 5, 6, -1 }, // 0012 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, -1, -1, 5, 6, 7, -1 }, // 1012 { 0, 1, 2, -1, 3, -1, -1, -1, 4, 5, -1, -1, 6, 7, 8, -1 }, // 2012 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, -1, -1, 7, 8, 9, -1 }, // 3012 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, -1, -1, 5, 6, 7, -1 }, // 0112 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, -1, -1, 6, 7, 8, -1 }, // 1112 { 0, 1, 2, -1, 3, 4, -1, -1, 5, 6, -1, -1, 7, 8, 9, -1 }, // 2112 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, -1, -1, 8, 9, 10, -1 }, // 3112 { 0, -1, -1, -1, 1, 2, 3, -1, 4, 5, -1, -1, 6, 7, 8, -1 }, // 0212 { 0, 1, -1, -1, 2, 3, 4, -1, 5, 6, -1, -1, 7, 8, 9, -1 }, // 1212 { 0, 1, 2, -1, 3, 4, 5, -1, 6, 7, -1, -1, 8, 9, 10, -1 }, // 2212 { 0, 1, 2, 3, 4, 5, 6, -1, 7, 8, -1, -1, 9, 10, 11, -1 }, // 3212 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, -1, -1, 7, 8, 9, -1 }, // 0312 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, -1, -1, 8, 9, 10, -1 }, // 1312 { 0, 1, 2, -1, 3, 4, 5, 6, 7, 8, -1, -1, 9, 10, 11, -1 }, // 2312 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, 10, 11, 12, -1 }, // 3312 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, 4, -1, 5, 6, 7, -1 }, // 0022 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, 5, -1, 6, 7, 8, -1 }, // 1022 { 0, 1, 2, -1, 3, -1, -1, -1, 4, 5, 6, -1, 7, 8, 9, -1 }, // 2022 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, 7, -1, 8, 9, 10, -1 }, // 3022 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, 5, -1, 6, 7, 8, -1 }, // 0122 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, 6, -1, 7, 8, 9, -1 }, // 1122 { 0, 1, 2, -1, 3, 4, -1, -1, 5, 6, 7, -1, 8, 9, 10, -1 }, // 2122 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, -1, 9, 10, 11, -1 }, // 3122 { 0, -1, -1, -1, 1, 2, 3, -1, 4, 5, 6, -1, 7, 8, 9, -1 }, // 0222 { 0, 1, -1, -1, 2, 3, 4, -1, 5, 6, 7, -1, 8, 9, 10, -1 }, // 1222 { 0, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8, -1, 9, 10, 11, -1 }, // 2222 { 0, 1, 2, 3, 4, 5, 6, -1, 7, 8, 9, -1, 10, 11, 12, -1 }, // 3222 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, 7, -1, 8, 9, 10, -1 }, // 0322 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, 8, -1, 9, 10, 11, -1 }, // 1322 { 0, 1, 2, -1, 3, 4, 5, 6, 7, 8, 9, -1, 10, 11, 12, -1 }, // 2322 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, 11, 12, 13, -1 }, // 3322 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, 4, 5, 6, 7, 8, -1 }, // 0032 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, 5, 6, 7, 8, 9, -1 }, // 1032 { 0, 1, 2, -1, 3, -1, -1, -1, 4, 5, 6, 7, 8, 9, 10, -1 }, // 2032 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, 7, 8, 9, 10, 11, -1 }, // 3032 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, 5, 6, 7, 8, 9, -1 }, // 0132 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, 6, 7, 8, 9, 10, -1 }, // 1132 { 0, 1, 2, -1, 3, 4, -1, -1, 5, 6, 7, 8, 9, 10, 11, -1 }, // 2132 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, 11, 12, -1 }, // 3132 { 0, -1, -1, -1, 1, 2, 3, -1, 4, 5, 6, 7, 8, 9, 10, -1 }, // 0232 { 0, 1, -1, -1, 2, 3, 4, -1, 5, 6, 7, 8, 9, 10, 11, -1 }, // 1232 { 0, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8, 9, 10, 11, 12, -1 }, // 2232 { 0, 1, 2, 3, 4, 5, 6, -1, 7, 8, 9, 10, 11, 12, 13, -1 }, // 3232 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1 }, // 0332 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1 }, // 1332 { 0, 1, 2, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1 }, // 2332 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1 }, // 3332 { 0, -1, -1, -1, 1, -1, -1, -1, 2, -1, -1, -1, 3, 4, 5, 6 }, // 0003 { 0, 1, -1, -1, 2, -1, -1, -1, 3, -1, -1, -1, 4, 5, 6, 7 }, // 1003 { 0, 1, 2, -1, 3, -1, -1, -1, 4, -1, -1, -1, 5, 6, 7, 8 }, // 2003 { 0, 1, 2, 3, 4, -1, -1, -1, 5, -1, -1, -1, 6, 7, 8, 9 }, // 3003 { 0, -1, -1, -1, 1, 2, -1, -1, 3, -1, -1, -1, 4, 5, 6, 7 }, // 0103 { 0, 1, -1, -1, 2, 3, -1, -1, 4, -1, -1, -1, 5, 6, 7, 8 }, // 1103 { 0, 1, 2, -1, 3, 4, -1, -1, 5, -1, -1, -1, 6, 7, 8, 9 }, // 2103 { 0, 1, 2, 3, 4, 5, -1, -1, 6, -1, -1, -1, 7, 8, 9, 10 }, // 3103 { 0, -1, -1, -1, 1, 2, 3, -1, 4, -1, -1, -1, 5, 6, 7, 8 }, // 0203 { 0, 1, -1, -1, 2, 3, 4, -1, 5, -1, -1, -1, 6, 7, 8, 9 }, // 1203 { 0, 1, 2, -1, 3, 4, 5, -1, 6, -1, -1, -1, 7, 8, 9, 10 }, // 2203 { 0, 1, 2, 3, 4, 5, 6, -1, 7, -1, -1, -1, 8, 9, 10, 11 }, // 3203 { 0, -1, -1, -1, 1, 2, 3, 4, 5, -1, -1, -1, 6, 7, 8, 9 }, // 0303 { 0, 1, -1, -1, 2, 3, 4, 5, 6, -1, -1, -1, 7, 8, 9, 10 }, // 1303 { 0, 1, 2, -1, 3, 4, 5, 6, 7, -1, -1, -1, 8, 9, 10, 11 }, // 2303 { 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, 9, 10, 11, 12 }, // 3303 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, -1, -1, 4, 5, 6, 7 }, // 0013 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, -1, -1, 5, 6, 7, 8 }, // 1013 { 0, 1, 2, -1, 3, -1, -1, -1, 4, 5, -1, -1, 6, 7, 8, 9 }, // 2013 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, -1, -1, 7, 8, 9, 10 }, // 3013 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, -1, -1, 5, 6, 7, 8 }, // 0113 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, -1, -1, 6, 7, 8, 9 }, // 1113 { 0, 1, 2, -1, 3, 4, -1, -1, 5, 6, -1, -1, 7, 8, 9, 10 }, // 2113 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, -1, -1, 8, 9, 10, 11 }, // 3113 { 0, -1, -1, -1, 1, 2, 3, -1, 4, 5, -1, -1, 6, 7, 8, 9 }, // 0213 { 0, 1, -1, -1, 2, 3, 4, -1, 5, 6, -1, -1, 7, 8, 9, 10 }, // 1213 { 0, 1, 2, -1, 3, 4, 5, -1, 6, 7, -1, -1, 8, 9, 10, 11 }, // 2213 { 0, 1, 2, 3, 4, 5, 6, -1, 7, 8, -1, -1, 9, 10, 11, 12 }, // 3213 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, -1, -1, 7, 8, 9, 10 }, // 0313 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, -1, -1, 8, 9, 10, 11 }, // 1313 { 0, 1, 2, -1, 3, 4, 5, 6, 7, 8, -1, -1, 9, 10, 11, 12 }, // 2313 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, 10, 11, 12, 13 }, // 3313 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, 4, -1, 5, 6, 7, 8 }, // 0023 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, 5, -1, 6, 7, 8, 9 }, // 1023 { 0, 1, 2, -1, 3, -1, -1, -1, 4, 5, 6, -1, 7, 8, 9, 10 }, // 2023 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, 7, -1, 8, 9, 10, 11 }, // 3023 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, 5, -1, 6, 7, 8, 9 }, // 0123 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, 6, -1, 7, 8, 9, 10 }, // 1123 { 0, 1, 2, -1, 3, 4, -1, -1, 5, 6, 7, -1, 8, 9, 10, 11 }, // 2123 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, -1, 9, 10, 11, 12 }, // 3123 { 0, -1, -1, -1, 1, 2, 3, -1, 4, 5, 6, -1, 7, 8, 9, 10 }, // 0223 { 0, 1, -1, -1, 2, 3, 4, -1, 5, 6, 7, -1, 8, 9, 10, 11 }, // 1223 { 0, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8, -1, 9, 10, 11, 12 }, // 2223 { 0, 1, 2, 3, 4, 5, 6, -1, 7, 8, 9, -1, 10, 11, 12, 13 }, // 3223 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, 7, -1, 8, 9, 10, 11 }, // 0323 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, 8, -1, 9, 10, 11, 12 }, // 1323 { 0, 1, 2, -1, 3, 4, 5, 6, 7, 8, 9, -1, 10, 11, 12, 13 }, // 2323 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, 11, 12, 13, 14 }, // 3323 { 0, -1, -1, -1, 1, -1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9 }, // 0033 { 0, 1, -1, -1, 2, -1, -1, -1, 3, 4, 5, 6, 7, 8, 9, 10 }, // 1033 { 0, 1, 2, -1, 3, -1, -1, -1, 4, 5, 6, 7, 8, 9, 10, 11 }, // 2033 { 0, 1, 2, 3, 4, -1, -1, -1, 5, 6, 7, 8, 9, 10, 11, 12 }, // 3033 { 0, -1, -1, -1, 1, 2, -1, -1, 3, 4, 5, 6, 7, 8, 9, 10 }, // 0133 { 0, 1, -1, -1, 2, 3, -1, -1, 4, 5, 6, 7, 8, 9, 10, 11 }, // 1133 { 0, 1, 2, -1, 3, 4, -1, -1, 5, 6, 7, 8, 9, 10, 11, 12 }, // 2133 { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, 11, 12, 13 }, // 3133 { 0, -1, -1, -1, 1, 2, 3, -1, 4, 5, 6, 7, 8, 9, 10, 11 }, // 0233 { 0, 1, -1, -1, 2, 3, 4, -1, 5, 6, 7, 8, 9, 10, 11, 12 }, // 1233 { 0, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8, 9, 10, 11, 12, 13 }, // 2233 { 0, 1, 2, 3, 4, 5, 6, -1, 7, 8, 9, 10, 11, 12, 13, 14 }, // 3233 { 0, -1, -1, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }, // 0333 { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }, // 1333 { 0, 1, 2, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }, // 2333 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, // 3333 }; #endif streamvbyte-0.5.1/src/streamvbyte_shuffle_tables_encode.h000066400000000000000000000666751427353355200240070ustar00rootroot00000000000000#ifndef STREAMVBYTE_SHUFFLE_TABLES_ENCODE_H #define STREAMVBYTE_SHUFFLE_TABLES_ENCODE_H #include "streamvbyte_isadetection.h" #include #ifdef STREAMVBYTE_X64 // encoding: static const uint8_t shuf_lut[64*16] = { 0x00, 0x04, 0x08, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x04, 0x08, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x04, 0x08, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x08, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x04, 0x05, 0x08, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x04, 0x05, 0x08, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x04, 0x05, 0x08, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x04, 0x05, 0x06, 0x08, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x04, 0x05, 0x06, 0x08, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x08, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x04, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x04, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x04, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x04, 0x05, 0x06, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x04, 0x05, 0x06, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0x00, 0x04, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x04, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x04, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x04, 0x05, 0x06, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x04, 0x05, 0x06, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0x00, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0x00, 0x04, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x04, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x04, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0x00, 0x04, 0x05, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x04, 0x05, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0x00, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }; static const uint8_t len_lut[256] = { 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10, 8, 9, 10, 11, 6, 7, 8, 9, 7, 8, 9, 10, 8, 9, 10, 11, 9, 10, 11, 12, 7, 8, 9, 10, 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10, 8, 9, 10, 11, 6, 7, 8, 9, 7, 8, 9, 10, 8, 9, 10, 11, 9, 10, 11, 12, 7, 8, 9, 10, 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14, 6, 7, 8, 9, 7, 8, 9, 10, 8, 9, 10, 11, 9, 10, 11, 12, 7, 8, 9, 10, 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14, 12, 13, 14, 15, 7, 8, 9, 10, 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14, 12, 13, 14, 15, 10, 11, 12, 13, 11, 12, 13, 14, 12, 13, 14, 15, 13, 14, 15, 16, }; #endif #ifdef STREAMVBYTE_ARM static uint8_t encodingShuffleTable[256][16] = { { 0, 4, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1111 { 0, 1, 4, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2111 { 0, 1, 2, 4, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3111 { 0, 1, 2, 3, 4, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 4111 { 0, 4, 5, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1211 { 0, 1, 4, 5, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2211 { 0, 1, 2, 4, 5, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3211 { 0, 1, 2, 3, 4, 5, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 4211 { 0, 4, 5, 6, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1311 { 0, 1, 4, 5, 6, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2311 { 0, 1, 2, 4, 5, 6, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3311 { 0, 1, 2, 3, 4, 5, 6, 8, 12, -1, -1, -1, -1, -1, -1, -1 }, // 4311 { 0, 4, 5, 6, 7, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1411 { 0, 1, 4, 5, 6, 7, 8, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2411 { 0, 1, 2, 4, 5, 6, 7, 8, 12, -1, -1, -1, -1, -1, -1, -1 }, // 3411 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, -1, -1, -1, -1, -1, -1 }, // 4411 { 0, 4, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1121 { 0, 1, 4, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2121 { 0, 1, 2, 4, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3121 { 0, 1, 2, 3, 4, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 4121 { 0, 4, 5, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1221 { 0, 1, 4, 5, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2221 { 0, 1, 2, 4, 5, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3221 { 0, 1, 2, 3, 4, 5, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1 }, // 4221 { 0, 4, 5, 6, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1321 { 0, 1, 4, 5, 6, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2321 { 0, 1, 2, 4, 5, 6, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1 }, // 3321 { 0, 1, 2, 3, 4, 5, 6, 8, 9, 12, -1, -1, -1, -1, -1, -1 }, // 4321 { 0, 4, 5, 6, 7, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1421 { 0, 1, 4, 5, 6, 7, 8, 9, 12, -1, -1, -1, -1, -1, -1, -1 }, // 2421 { 0, 1, 2, 4, 5, 6, 7, 8, 9, 12, -1, -1, -1, -1, -1, -1 }, // 3421 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, -1, -1, -1, -1, -1 }, // 4421 { 0, 4, 8, 9, 10, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1131 { 0, 1, 4, 8, 9, 10, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2131 { 0, 1, 2, 4, 8, 9, 10, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3131 { 0, 1, 2, 3, 4, 8, 9, 10, 12, -1, -1, -1, -1, -1, -1, -1 }, // 4131 { 0, 4, 5, 8, 9, 10, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1231 { 0, 1, 4, 5, 8, 9, 10, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2231 { 0, 1, 2, 4, 5, 8, 9, 10, 12, -1, -1, -1, -1, -1, -1, -1 }, // 3231 { 0, 1, 2, 3, 4, 5, 8, 9, 10, 12, -1, -1, -1, -1, -1, -1 }, // 4231 { 0, 4, 5, 6, 8, 9, 10, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1331 { 0, 1, 4, 5, 6, 8, 9, 10, 12, -1, -1, -1, -1, -1, -1, -1 }, // 2331 { 0, 1, 2, 4, 5, 6, 8, 9, 10, 12, -1, -1, -1, -1, -1, -1 }, // 3331 { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, -1, -1, -1, -1, -1 }, // 4331 { 0, 4, 5, 6, 7, 8, 9, 10, 12, -1, -1, -1, -1, -1, -1, -1 }, // 1431 { 0, 1, 4, 5, 6, 7, 8, 9, 10, 12, -1, -1, -1, -1, -1, -1 }, // 2431 { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 12, -1, -1, -1, -1, -1 }, // 3431 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, -1, -1, -1, -1 }, // 4431 { 0, 4, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1141 { 0, 1, 4, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2141 { 0, 1, 2, 4, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1 }, // 3141 { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1 }, // 4141 { 0, 4, 5, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1241 { 0, 1, 4, 5, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1 }, // 2241 { 0, 1, 2, 4, 5, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1 }, // 3241 { 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1 }, // 4241 { 0, 4, 5, 6, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1 }, // 1341 { 0, 1, 4, 5, 6, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1 }, // 2341 { 0, 1, 2, 4, 5, 6, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1 }, // 3341 { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, -1, -1, -1, -1 }, // 4341 { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1 }, // 1441 { 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1 }, // 2441 { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1, -1 }, // 3441 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1 }, // 4441 { 0, 4, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1112 { 0, 1, 4, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2112 { 0, 1, 2, 4, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3112 { 0, 1, 2, 3, 4, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 4112 { 0, 4, 5, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1212 { 0, 1, 4, 5, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2212 { 0, 1, 2, 4, 5, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3212 { 0, 1, 2, 3, 4, 5, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 4212 { 0, 4, 5, 6, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1312 { 0, 1, 4, 5, 6, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2312 { 0, 1, 2, 4, 5, 6, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 3312 { 0, 1, 2, 3, 4, 5, 6, 8, 12, 13, -1, -1, -1, -1, -1, -1 }, // 4312 { 0, 4, 5, 6, 7, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1412 { 0, 1, 4, 5, 6, 7, 8, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 2412 { 0, 1, 2, 4, 5, 6, 7, 8, 12, 13, -1, -1, -1, -1, -1, -1 }, // 3412 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 13, -1, -1, -1, -1, -1 }, // 4412 { 0, 4, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1122 { 0, 1, 4, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2122 { 0, 1, 2, 4, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3122 { 0, 1, 2, 3, 4, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 4122 { 0, 4, 5, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1222 { 0, 1, 4, 5, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2222 { 0, 1, 2, 4, 5, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 3222 { 0, 1, 2, 3, 4, 5, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1 }, // 4222 { 0, 4, 5, 6, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1322 { 0, 1, 4, 5, 6, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 2322 { 0, 1, 2, 4, 5, 6, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1 }, // 3322 { 0, 1, 2, 3, 4, 5, 6, 8, 9, 12, 13, -1, -1, -1, -1, -1 }, // 4322 { 0, 4, 5, 6, 7, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 1422 { 0, 1, 4, 5, 6, 7, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1 }, // 2422 { 0, 1, 2, 4, 5, 6, 7, 8, 9, 12, 13, -1, -1, -1, -1, -1 }, // 3422 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, -1, -1, -1, -1 }, // 4422 { 0, 4, 8, 9, 10, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1132 { 0, 1, 4, 8, 9, 10, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2132 { 0, 1, 2, 4, 8, 9, 10, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 3132 { 0, 1, 2, 3, 4, 8, 9, 10, 12, 13, -1, -1, -1, -1, -1, -1 }, // 4132 { 0, 4, 5, 8, 9, 10, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1232 { 0, 1, 4, 5, 8, 9, 10, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 2232 { 0, 1, 2, 4, 5, 8, 9, 10, 12, 13, -1, -1, -1, -1, -1, -1 }, // 3232 { 0, 1, 2, 3, 4, 5, 8, 9, 10, 12, 13, -1, -1, -1, -1, -1 }, // 4232 { 0, 4, 5, 6, 8, 9, 10, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 1332 { 0, 1, 4, 5, 6, 8, 9, 10, 12, 13, -1, -1, -1, -1, -1, -1 }, // 2332 { 0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, -1, -1, -1, -1, -1 }, // 3332 { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 13, -1, -1, -1, -1 }, // 4332 { 0, 4, 5, 6, 7, 8, 9, 10, 12, 13, -1, -1, -1, -1, -1, -1 }, // 1432 { 0, 1, 4, 5, 6, 7, 8, 9, 10, 12, 13, -1, -1, -1, -1, -1 }, // 2432 { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, -1, -1, -1, -1 }, // 3432 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, -1, -1, -1 }, // 4432 { 0, 4, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1142 { 0, 1, 4, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 2142 { 0, 1, 2, 4, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1 }, // 3142 { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1 }, // 4142 { 0, 4, 5, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1 }, // 1242 { 0, 1, 4, 5, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1 }, // 2242 { 0, 1, 2, 4, 5, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1 }, // 3242 { 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1 }, // 4242 { 0, 4, 5, 6, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1 }, // 1342 { 0, 1, 4, 5, 6, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1 }, // 2342 { 0, 1, 2, 4, 5, 6, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1 }, // 3342 { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, -1, -1, -1 }, // 4342 { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1 }, // 1442 { 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1 }, // 2442 { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, -1 }, // 3442 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1 }, // 4442 { 0, 4, 8, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1113 { 0, 1, 4, 8, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2113 { 0, 1, 2, 4, 8, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3113 { 0, 1, 2, 3, 4, 8, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1 }, // 4113 { 0, 4, 5, 8, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1213 { 0, 1, 4, 5, 8, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2213 { 0, 1, 2, 4, 5, 8, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1 }, // 3213 { 0, 1, 2, 3, 4, 5, 8, 12, 13, 14, -1, -1, -1, -1, -1, -1 }, // 4213 { 0, 4, 5, 6, 8, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1313 { 0, 1, 4, 5, 6, 8, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1 }, // 2313 { 0, 1, 2, 4, 5, 6, 8, 12, 13, 14, -1, -1, -1, -1, -1, -1 }, // 3313 { 0, 1, 2, 3, 4, 5, 6, 8, 12, 13, 14, -1, -1, -1, -1, -1 }, // 4313 { 0, 4, 5, 6, 7, 8, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1 }, // 1413 { 0, 1, 4, 5, 6, 7, 8, 12, 13, 14, -1, -1, -1, -1, -1, -1 }, // 2413 { 0, 1, 2, 4, 5, 6, 7, 8, 12, 13, 14, -1, -1, -1, -1, -1 }, // 3413 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 13, 14, -1, -1, -1, -1 }, // 4413 { 0, 4, 8, 9, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1123 { 0, 1, 4, 8, 9, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2123 { 0, 1, 2, 4, 8, 9, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1 }, // 3123 { 0, 1, 2, 3, 4, 8, 9, 12, 13, 14, -1, -1, -1, -1, -1, -1 }, // 4123 { 0, 4, 5, 8, 9, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1223 { 0, 1, 4, 5, 8, 9, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1 }, // 2223 { 0, 1, 2, 4, 5, 8, 9, 12, 13, 14, -1, -1, -1, -1, -1, -1 }, // 3223 { 0, 1, 2, 3, 4, 5, 8, 9, 12, 13, 14, -1, -1, -1, -1, -1 }, // 4223 { 0, 4, 5, 6, 8, 9, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1 }, // 1323 { 0, 1, 4, 5, 6, 8, 9, 12, 13, 14, -1, -1, -1, -1, -1, -1 }, // 2323 { 0, 1, 2, 4, 5, 6, 8, 9, 12, 13, 14, -1, -1, -1, -1, -1 }, // 3323 { 0, 1, 2, 3, 4, 5, 6, 8, 9, 12, 13, 14, -1, -1, -1, -1 }, // 4323 { 0, 4, 5, 6, 7, 8, 9, 12, 13, 14, -1, -1, -1, -1, -1, -1 }, // 1423 { 0, 1, 4, 5, 6, 7, 8, 9, 12, 13, 14, -1, -1, -1, -1, -1 }, // 2423 { 0, 1, 2, 4, 5, 6, 7, 8, 9, 12, 13, 14, -1, -1, -1, -1 }, // 3423 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, -1, -1, -1 }, // 4423 { 0, 4, 8, 9, 10, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1133 { 0, 1, 4, 8, 9, 10, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1 }, // 2133 { 0, 1, 2, 4, 8, 9, 10, 12, 13, 14, -1, -1, -1, -1, -1, -1 }, // 3133 { 0, 1, 2, 3, 4, 8, 9, 10, 12, 13, 14, -1, -1, -1, -1, -1 }, // 4133 { 0, 4, 5, 8, 9, 10, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1 }, // 1233 { 0, 1, 4, 5, 8, 9, 10, 12, 13, 14, -1, -1, -1, -1, -1, -1 }, // 2233 { 0, 1, 2, 4, 5, 8, 9, 10, 12, 13, 14, -1, -1, -1, -1, -1 }, // 3233 { 0, 1, 2, 3, 4, 5, 8, 9, 10, 12, 13, 14, -1, -1, -1, -1 }, // 4233 { 0, 4, 5, 6, 8, 9, 10, 12, 13, 14, -1, -1, -1, -1, -1, -1 }, // 1333 { 0, 1, 4, 5, 6, 8, 9, 10, 12, 13, 14, -1, -1, -1, -1, -1 }, // 2333 { 0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, -1, -1, -1, -1 }, // 3333 { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 13, 14, -1, -1, -1 }, // 4333 { 0, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, -1, -1, -1, -1, -1 }, // 1433 { 0, 1, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, -1, -1, -1, -1 }, // 2433 { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, -1, -1, -1 }, // 3433 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, -1, -1 }, // 4433 { 0, 4, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1 }, // 1143 { 0, 1, 4, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1 }, // 2143 { 0, 1, 2, 4, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1 }, // 3143 { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1 }, // 4143 { 0, 4, 5, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1 }, // 1243 { 0, 1, 4, 5, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1 }, // 2243 { 0, 1, 2, 4, 5, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1 }, // 3243 { 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1 }, // 4243 { 0, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1 }, // 1343 { 0, 1, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1 }, // 2343 { 0, 1, 2, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1 }, // 3343 { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, -1, -1 }, // 4343 { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1 }, // 1443 { 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1 }, // 2443 { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, -1 }, // 3443 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1 }, // 4443 { 0, 4, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1114 { 0, 1, 4, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2114 { 0, 1, 2, 4, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1 }, // 3114 { 0, 1, 2, 3, 4, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 4114 { 0, 4, 5, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1214 { 0, 1, 4, 5, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1 }, // 2214 { 0, 1, 2, 4, 5, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 3214 { 0, 1, 2, 3, 4, 5, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 4214 { 0, 4, 5, 6, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1 }, // 1314 { 0, 1, 4, 5, 6, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 2314 { 0, 1, 2, 4, 5, 6, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 3314 { 0, 1, 2, 3, 4, 5, 6, 8, 12, 13, 14, 15, -1, -1, -1, -1 }, // 4314 { 0, 4, 5, 6, 7, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 1414 { 0, 1, 4, 5, 6, 7, 8, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 2414 { 0, 1, 2, 4, 5, 6, 7, 8, 12, 13, 14, 15, -1, -1, -1, -1 }, // 3414 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 13, 14, 15, -1, -1, -1 }, // 4414 { 0, 4, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1124 { 0, 1, 4, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1 }, // 2124 { 0, 1, 2, 4, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 3124 { 0, 1, 2, 3, 4, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 4124 { 0, 4, 5, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1 }, // 1224 { 0, 1, 4, 5, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 2224 { 0, 1, 2, 4, 5, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 3224 { 0, 1, 2, 3, 4, 5, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1 }, // 4224 { 0, 4, 5, 6, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 1324 { 0, 1, 4, 5, 6, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 2324 { 0, 1, 2, 4, 5, 6, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1 }, // 3324 { 0, 1, 2, 3, 4, 5, 6, 8, 9, 12, 13, 14, 15, -1, -1, -1 }, // 4324 { 0, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 1424 { 0, 1, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1 }, // 2424 { 0, 1, 2, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, -1, -1, -1 }, // 3424 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, -1, -1 }, // 4424 { 0, 4, 8, 9, 10, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1 }, // 1134 { 0, 1, 4, 8, 9, 10, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 2134 { 0, 1, 2, 4, 8, 9, 10, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 3134 { 0, 1, 2, 3, 4, 8, 9, 10, 12, 13, 14, 15, -1, -1, -1, -1 }, // 4134 { 0, 4, 5, 8, 9, 10, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 1234 { 0, 1, 4, 5, 8, 9, 10, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 2234 { 0, 1, 2, 4, 5, 8, 9, 10, 12, 13, 14, 15, -1, -1, -1, -1 }, // 3234 { 0, 1, 2, 3, 4, 5, 8, 9, 10, 12, 13, 14, 15, -1, -1, -1 }, // 4234 { 0, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 1334 { 0, 1, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, -1, -1, -1, -1 }, // 2334 { 0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, -1, -1, -1 }, // 3334 { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, -1, -1 }, // 4334 { 0, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, -1, -1, -1, -1 }, // 1434 { 0, 1, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, -1, -1, -1 }, // 2434 { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, -1, -1 }, // 3434 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, -1 }, // 4434 { 0, 4, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1 }, // 1144 { 0, 1, 4, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 2144 { 0, 1, 2, 4, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1 }, // 3144 { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1 }, // 4144 { 0, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1 }, // 1244 { 0, 1, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1 }, // 2244 { 0, 1, 2, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1 }, // 3244 { 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1 }, // 4244 { 0, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1 }, // 1344 { 0, 1, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1 }, // 2344 { 0, 1, 2, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1 }, // 3344 { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, -1 }, // 4344 { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1 }, // 1444 { 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1 }, // 2444 { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1 }, // 3444 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, // 4444 }; #endif #endif streamvbyte-0.5.1/src/streamvbyte_x64_decode.c000066400000000000000000000062251427353355200214040ustar00rootroot00000000000000#include "streamvbyte_isadetection.h" #ifdef STREAMVBYTE_X64 STREAMVBYTE_TARGET_SSSE3 static inline __m128i _decode_avx(uint32_t key, const uint8_t *__restrict__ *dataPtrPtr) { uint8_t len; __m128i Data = _mm_loadu_si128((__m128i *)*dataPtrPtr); uint8_t *pshuf = (uint8_t *) &shuffleTable[key]; __m128i Shuf = *(__m128i *)pshuf; #ifdef AVOIDLENGTHLOOKUP // this avoids the dependency on lengthTable, // see https://github.com/lemire/streamvbyte/issues/12 len = pshuf[12 + (key >> 6)] + 1; #else len = lengthTable[key]; #endif Data = _mm_shuffle_epi8(Data, Shuf); *dataPtrPtr += len; return Data; } STREAMVBYTE_UNTARGET_REGION STREAMVBYTE_TARGET_SSSE3 static inline void _write_avx(uint32_t *out, __m128i Vec) { _mm_storeu_si128((__m128i *)out, Vec); } STREAMVBYTE_UNTARGET_REGION STREAMVBYTE_TARGET_SSSE3 const uint8_t *svb_decode_avx_simple(uint32_t *out, const uint8_t *__restrict__ keyPtr, const uint8_t *__restrict__ dataPtr, uint64_t count) { uint64_t keybytes = count / 4; // number of key bytes __m128i Data; if (keybytes >= 8) { int64_t Offset = -(int64_t)keybytes / 8 + 1; const uint64_t *keyPtr64 = (const uint64_t *)keyPtr - Offset; uint64_t nextkeys; memcpy(&nextkeys, keyPtr64 + Offset, sizeof(nextkeys)); for (; Offset != 0; ++Offset) { uint64_t keys = nextkeys; memcpy(&nextkeys, keyPtr64 + Offset + 1, sizeof(nextkeys)); Data = _decode_avx((keys & 0xFF), &dataPtr); _write_avx(out, Data); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); _write_avx(out + 4, Data); keys >>= 16; Data = _decode_avx((keys & 0xFF), &dataPtr); _write_avx(out + 8, Data); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); _write_avx(out + 12, Data); keys >>= 16; Data = _decode_avx((keys & 0xFF), &dataPtr); _write_avx(out + 16, Data); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); _write_avx(out + 20, Data); keys >>= 16; Data = _decode_avx((keys & 0xFF), &dataPtr); _write_avx(out + 24, Data); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); _write_avx(out + 28, Data); out += 32; } { uint64_t keys = nextkeys; Data = _decode_avx((keys & 0xFF), &dataPtr); _write_avx(out, Data); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); _write_avx(out + 4, Data); keys >>= 16; Data = _decode_avx((keys & 0xFF), &dataPtr); _write_avx(out + 8, Data); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); _write_avx(out + 12, Data); keys >>= 16; Data = _decode_avx((keys & 0xFF), &dataPtr); _write_avx(out + 16, Data); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); _write_avx(out + 20, Data); keys >>= 16; Data = _decode_avx((keys & 0xFF), &dataPtr); _write_avx(out + 24, Data); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); _write_avx(out + 28, Data); out += 32; } } return dataPtr; } STREAMVBYTE_UNTARGET_REGION #endif streamvbyte-0.5.1/src/streamvbyte_x64_encode.c000066400000000000000000000034051427353355200214130ustar00rootroot00000000000000#include "streamvbyte_isadetection.h" #ifdef STREAMVBYTE_X64 // contributed by aqrit STREAMVBYTE_TARGET_SSSE3 size_t streamvbyte_encode_SSSE3 (const uint32_t* in, uint32_t count, uint8_t* out) { uint32_t keyLen = (count >> 2) + (((count & 3) + 3) >> 2); // 2-bits per each rounded up to byte boundry uint8_t *restrict keyPtr = &out[0]; uint8_t *restrict dataPtr = &out[keyLen]; // variable length data after keys const __m128i mask_01 = _mm_set1_epi8(0x01); const __m128i mask_7F00 = _mm_set1_epi16(0x7F00); for (const uint32_t* end = &in[(count & ~7)]; in != end; in += 8) { __m128i r0, r1, r2, r3; size_t keys; r0 = _mm_loadu_si128((__m128i*)&in[0]); r1 = _mm_loadu_si128((__m128i*)&in[4]); r2 = _mm_min_epu8(mask_01, r0); r3 = _mm_min_epu8(mask_01, r1); r2 = _mm_packus_epi16(r2, r3); r2 = _mm_min_epi16(r2, mask_01); // convert 0x01FF to 0x0101 r2 = _mm_adds_epu16(r2, mask_7F00); // convert: 0x0101 to 0x8001, 0xFF01 to 0xFFFF keys = (size_t)_mm_movemask_epi8(r2); r2 = _mm_loadu_si128((__m128i*)&shuf_lut[(keys << 4) & 0x03F0]); r3 = _mm_loadu_si128((__m128i*)&shuf_lut[(keys >> 4) & 0x03F0]); r0 = _mm_shuffle_epi8(r0, r2); r1 = _mm_shuffle_epi8(r1, r3); _mm_storeu_si128((__m128i *)dataPtr, r0); dataPtr += len_lut[keys & 0xFF]; _mm_storeu_si128((__m128i *)dataPtr, r1); dataPtr += len_lut[keys >> 8]; *((uint16_t*)keyPtr) = (uint16_t)keys; keyPtr += 2; } // do remaining uint32_t key = 0; for(size_t i = 0; i < (count & 7); i++) { uint32_t dw = in[i]; uint32_t symbol = (dw > 0x000000FF) + (dw > 0x0000FFFF) + (dw > 0x00FFFFFF); key |= symbol << (i + i); *((uint32_t*)dataPtr) = dw; dataPtr += 1 + symbol; } memcpy(keyPtr, &key, ((count & 7) + 3) >> 2); return dataPtr - out; } STREAMVBYTE_UNTARGET_REGION #endif streamvbyte-0.5.1/src/streamvbyte_zigzag.c000066400000000000000000000017331427353355200207520ustar00rootroot00000000000000#include "streamvbyte_zigzag.h" #include "streamvbyte_isadetection.h" static inline uint32_t _zigzag_encode_32 (uint32_t val) { return (val + val) ^ ((int32_t)val >> 31); } void zigzag_encode(const int32_t * in, uint32_t * out, size_t N) { for(size_t i = 0; i < N; i++) out[i] = _zigzag_encode_32(in[i]); } void zigzag_delta_encode(const int32_t * in, uint32_t * out, size_t N, int32_t prev) { for (size_t i = 0; i < N; i++) { out[i] = _zigzag_encode_32(in[i] - prev); prev = in[i]; } } static inline int32_t _zigzag_decode_32 (uint32_t val) { return (val >> 1) ^ (0-(val & 1)); } void zigzag_decode(const uint32_t * in, int32_t * out, size_t N) { for(size_t i = 0; i < N; i++) out[i] = _zigzag_decode_32(in[i]); } void zigzag_delta_decode(const uint32_t * in, int32_t * out, size_t N, int32_t prev) { for(size_t i = 0; i < N; i++) { int32_t val =_zigzag_decode_32(in[i]); out[i] = val + prev; prev += val; } } streamvbyte-0.5.1/src/streamvbytedelta.c000066400000000000000000000271351427353355200204150ustar00rootroot00000000000000#include "streamvbytedelta.h" #include "streamvbyte_isadetection.h" #ifdef STREAMVBYTE_X64 #include "streamvbyte_shuffle_tables.h" size_t streamvbyte_encode4(__m128i in, uint8_t *outData, uint8_t *outCode); #endif #include // for memcpy static uint8_t _encode_data(uint32_t val, uint8_t *__restrict__ *dataPtrPtr) { uint8_t *dataPtr = *dataPtrPtr; uint8_t code; if (val < (1 << 8)) { // 1 byte *dataPtr = (uint8_t)(val); *dataPtrPtr += 1; code = 0; } else if (val < (1 << 16)) { // 2 bytes memcpy(dataPtr, &val, 2); // assumes little endian *dataPtrPtr += 2; code = 1; } else if (val < (1 << 24)) { // 3 bytes memcpy(dataPtr, &val, 3); // assumes little endian *dataPtrPtr += 3; code = 2; } else { // 4 bytes memcpy(dataPtr, &val, sizeof(uint32_t)); *dataPtrPtr += sizeof(uint32_t); code = 3; } return code; } static uint8_t *svb_encode_scalar_d1_init(const uint32_t *in, uint8_t *__restrict__ keyPtr, uint8_t *__restrict__ dataPtr, uint32_t count, uint32_t prev) { if (count == 0) return dataPtr; // exit immediately if no data uint8_t shift = 0; // cycles 0, 2, 4, 6, 0, 2, 4, 6, ... uint8_t key = 0; for (uint32_t c = 0; c < count; c++) { if (shift == 8) { shift = 0; *keyPtr++ = key; key = 0; } uint32_t val = in[c] - prev; prev = in[c]; uint8_t code = _encode_data(val, &dataPtr); key |= code << shift; shift += 2; } *keyPtr = key; // write last key (no increment needed) return dataPtr; // pointer to first unused data byte } #ifdef STREAMVBYTE_X64 // from streamvbyte.c size_t streamvbyte_encode_quad(__m128i in, uint8_t *outData, uint8_t *outCode); static __m128i Delta(__m128i curr, __m128i prev) { return _mm_sub_epi32(curr, _mm_alignr_epi8(curr, prev, 12)); } static uint8_t *svb_encode_vector_d1_init(const uint32_t *in, uint8_t *__restrict__ keyPtr, uint8_t *__restrict__ dataPtr, uint32_t count, uint32_t prev) { uint8_t *outData = dataPtr; uint8_t *outKey = keyPtr; uint32_t count4 = count / 4; __m128i Prev = _mm_set1_epi32(prev); for (uint32_t c = 0; c < count4; c++) { __m128i vin = _mm_loadu_si128((__m128i *)(in + 4 * c)); __m128i deltain = Delta(vin, Prev); Prev = vin; outData += streamvbyte_encode4(deltain, outData, outKey); outKey++; } prev = _mm_extract_epi32(Prev, 3); // we grab the last*/ outData = svb_encode_scalar_d1_init(in + 4 * count4, outKey, outData, count - 4 * count4, prev); // outData = svb_encode_scalar_d1_init(in, outKey, outData, count, prev); return outData; } #endif size_t streamvbyte_delta_encode(const uint32_t *in, uint32_t count, uint8_t *out, uint32_t prev) { uint8_t *keyPtr = out; // keys come immediately after 32-bit count uint32_t keyLen = (count + 3) / 4; // 2-bits rounded to full byte uint8_t *dataPtr = keyPtr + keyLen; // variable byte data after all keys #ifdef STREAMVBYTE_X64 if(streamvbyte_ssse3()) { return svb_encode_vector_d1_init(in, keyPtr, dataPtr, count, prev) - out; } #endif return svb_encode_scalar_d1_init(in, keyPtr, dataPtr, count, prev) - out; } #ifdef STREAMVBYTE_X64 static inline __m128i _decode_avx(uint32_t key, const uint8_t *__restrict__ *dataPtrPtr) { uint8_t len = lengthTable[key]; __m128i Data = _mm_loadu_si128((__m128i *)*dataPtrPtr); __m128i Shuf = *(__m128i *)&shuffleTable[key]; Data = _mm_shuffle_epi8(Data, Shuf); *dataPtrPtr += len; return Data; } #define BroadcastLastXMM 0xFF // bits 0-7 all set to choose highest element static inline void _write_avx(uint32_t *out, __m128i Vec) { _mm_storeu_si128((__m128i *)out, Vec); } static __m128i _write_avx_d1(uint32_t *out, __m128i Vec, __m128i Prev) { __m128i Add = _mm_slli_si128(Vec, 4); // Cycle 1: [- A B C] (already done) Prev = _mm_shuffle_epi32(Prev, BroadcastLastXMM); // Cycle 2: [P P P P] Vec = _mm_add_epi32(Vec, Add); // Cycle 2: [A AB BC CD] Add = _mm_slli_si128(Vec, 8); // Cycle 3: [- - A AB] Vec = _mm_add_epi32(Vec, Prev); // Cycle 3: [PA PAB PBC PCD] Vec = _mm_add_epi32(Vec, Add); // Cycle 4: [PA PAB PABC PABCD] _write_avx(out, Vec); return Vec; } #ifndef _MSC_VER static __m128i High16To32 = {0xFFFF0B0AFFFF0908, 0xFFFF0F0EFFFF0D0C}; #else static __m128i High16To32 = {8, 9, -1, -1, 10, 11, -1, -1, 12, 13, -1, -1, 14, 15, -1, -1}; #endif static inline __m128i _write_16bit_avx_d1(uint32_t *out, __m128i Vec, __m128i Prev) { // vec == [A B C D E F G H] (16 bit values) __m128i Add = _mm_slli_si128(Vec, 2); // [- A B C D E F G] Prev = _mm_shuffle_epi32(Prev, BroadcastLastXMM); // [P P P P] (32-bit) Vec = _mm_add_epi32(Vec, Add); // [A AB BC CD DE FG GH] Add = _mm_slli_si128(Vec, 4); // [- - A AB BC CD DE EF] Vec = _mm_add_epi32(Vec, Add); // [A AB ABC ABCD BCDE CDEF DEFG EFGH] __m128i V1 = _mm_cvtepu16_epi32(Vec); // [A AB ABC ABCD] (32-bit) V1 = _mm_add_epi32(V1, Prev); // [PA PAB PABC PABCD] (32-bit) __m128i V2 = _mm_shuffle_epi8(Vec, High16To32); // [BCDE CDEF DEFG EFGH] (32-bit) V2 = _mm_add_epi32(V1, V2); // [PABCDE PABCDEF PABCDEFG PABCDEFGH] (32-bit) _write_avx(out, V1); _write_avx(out + 4, V2); return V2; } #endif static inline uint32_t _decode_data(const uint8_t **dataPtrPtr, uint8_t code) { const uint8_t *dataPtr = *dataPtrPtr; uint32_t val; if (code == 0) { // 1 byte val = (uint32_t)*dataPtr; dataPtr += 1; } else if (code == 1) { // 2 bytes val = 0; memcpy(&val, dataPtr, 2); // assumes little endian dataPtr += 2; } else if (code == 2) { // 3 bytes val = 0; memcpy(&val, dataPtr, 3); // assumes little endian dataPtr += 3; } else { // code == 3 memcpy(&val, dataPtr, 4); dataPtr += 4; } *dataPtrPtr = dataPtr; return val; } static const uint8_t *svb_decode_scalar_d1_init(uint32_t *outPtr, const uint8_t *keyPtr, const uint8_t *dataPtr, uint32_t count, uint32_t prev) { if (count == 0) return dataPtr; // no reads or writes if no data uint8_t shift = 0; uint32_t key = *keyPtr++; for (uint32_t c = 0; c < count; c++) { if (shift == 8) { shift = 0; key = *keyPtr++; } uint32_t val = _decode_data(&dataPtr, (key >> shift) & 0x3); val += prev; *outPtr++ = val; prev = val; shift += 2; } return dataPtr; // pointer to first unused byte after end } #ifdef STREAMVBYTE_X64 const uint8_t *svb_decode_avx_d1_init(uint32_t *out, const uint8_t *__restrict__ keyPtr, const uint8_t *__restrict__ dataPtr, uint64_t count, uint32_t prev) { uint64_t keybytes = count / 4; // number of key bytes if (keybytes >= 8) { __m128i Prev = _mm_set1_epi32(prev); __m128i Data; int64_t Offset = -(int64_t)keybytes / 8 + 1; const uint64_t *keyPtr64 = (const uint64_t *)keyPtr - Offset; uint64_t nextkeys; memcpy(&nextkeys, keyPtr64 + Offset, sizeof(nextkeys)); for (; Offset != 0; ++Offset) { uint64_t keys = nextkeys; memcpy(&nextkeys, keyPtr64 + Offset + 1, sizeof(nextkeys)); // faster 16-bit delta since we only have 8-bit values if (!keys) { // 32 1-byte ints in a row Data = _mm_cvtepu8_epi16(_mm_lddqu_si128((__m128i *)(dataPtr))); Prev = _write_16bit_avx_d1(out, Data, Prev); Data = _mm_cvtepu8_epi16(_mm_lddqu_si128((__m128i *)(dataPtr + 8))); Prev = _write_16bit_avx_d1(out + 8, Data, Prev); Data = _mm_cvtepu8_epi16(_mm_lddqu_si128((__m128i *)(dataPtr + 16))); Prev = _write_16bit_avx_d1(out + 16, Data, Prev); Data = _mm_cvtepu8_epi16(_mm_lddqu_si128((__m128i *)(dataPtr + 24))); Prev = _write_16bit_avx_d1(out + 24, Data, Prev); out += 32; dataPtr += 32; continue; } Data = _decode_avx(keys & 0x00FF, &dataPtr); Prev = _write_avx_d1(out, Data, Prev); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); Prev = _write_avx_d1(out + 4, Data, Prev); keys >>= 16; Data = _decode_avx((keys & 0x00FF), &dataPtr); Prev = _write_avx_d1(out + 8, Data, Prev); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); Prev = _write_avx_d1(out + 12, Data, Prev); keys >>= 16; Data = _decode_avx((keys & 0x00FF), &dataPtr); Prev = _write_avx_d1(out + 16, Data, Prev); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); Prev = _write_avx_d1(out + 20, Data, Prev); keys >>= 16; Data = _decode_avx((keys & 0x00FF), &dataPtr); Prev = _write_avx_d1(out + 24, Data, Prev); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); Prev = _write_avx_d1(out + 28, Data, Prev); out += 32; } { uint64_t keys = nextkeys; // faster 16-bit delta since we only have 8-bit values if (!keys) { // 32 1-byte ints in a row Data = _mm_cvtepu8_epi16(_mm_lddqu_si128((__m128i *)(dataPtr))); Prev = _write_16bit_avx_d1(out, Data, Prev); Data = _mm_cvtepu8_epi16(_mm_lddqu_si128((__m128i *)(dataPtr + 8))); Prev = _write_16bit_avx_d1(out + 8, Data, Prev); Data = _mm_cvtepu8_epi16(_mm_lddqu_si128((__m128i *)(dataPtr + 16))); Prev = _write_16bit_avx_d1(out + 16, Data, Prev); Data = _mm_cvtepu8_epi16(_mm_loadl_epi64((__m128i *)(dataPtr + 24))); Prev = _write_16bit_avx_d1(out + 24, Data, Prev); out += 32; dataPtr += 32; } else { Data = _decode_avx(keys & 0x00FF, &dataPtr); Prev = _write_avx_d1(out, Data, Prev); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); Prev = _write_avx_d1(out + 4, Data, Prev); keys >>= 16; Data = _decode_avx((keys & 0x00FF), &dataPtr); Prev = _write_avx_d1(out + 8, Data, Prev); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); Prev = _write_avx_d1(out + 12, Data, Prev); keys >>= 16; Data = _decode_avx((keys & 0x00FF), &dataPtr); Prev = _write_avx_d1(out + 16, Data, Prev); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); Prev = _write_avx_d1(out + 20, Data, Prev); keys >>= 16; Data = _decode_avx((keys & 0x00FF), &dataPtr); Prev = _write_avx_d1(out + 24, Data, Prev); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); Prev = _write_avx_d1(out + 28, Data, Prev); out += 32; } } prev = out[-1]; } uint64_t consumedkeys = keybytes - (keybytes & 7); return svb_decode_scalar_d1_init(out, keyPtr + consumedkeys, dataPtr, count & 31, prev); } #endif size_t streamvbyte_delta_decode(const uint8_t *in, uint32_t *out, uint32_t count, uint32_t prev) { uint32_t keyLen = ((count + 3) / 4); // 2-bits per key (rounded up) const uint8_t *keyPtr = in; const uint8_t *dataPtr = keyPtr + keyLen; // data starts at end of keys #ifdef STREAMVBYTE_X64 if(streamvbyte_ssse3()) { return svb_decode_avx_d1_init(out, keyPtr, dataPtr, count, prev) - in; } #endif return svb_decode_scalar_d1_init(out, keyPtr, dataPtr, count, prev) - in; } streamvbyte-0.5.1/src/streamvbytedelta_decode.c000066400000000000000000000036721427353355200217200ustar00rootroot00000000000000#include "streamvbytedelta.h" #include "streamvbyte_isadetection.h" #include // for memcpy static inline uint32_t _decode_data(const uint8_t **dataPtrPtr, uint8_t code) { const uint8_t *dataPtr = *dataPtrPtr; uint32_t val; if (code == 0) { // 1 byte val = (uint32_t)*dataPtr; dataPtr += 1; } else if (code == 1) { // 2 bytes val = 0; memcpy(&val, dataPtr, 2); // assumes little endian dataPtr += 2; } else if (code == 2) { // 3 bytes val = 0; memcpy(&val, dataPtr, 3); // assumes little endian dataPtr += 3; } else { // code == 3 memcpy(&val, dataPtr, 4); dataPtr += 4; } *dataPtrPtr = dataPtr; return val; } static const uint8_t *svb_decode_scalar_d1_init(uint32_t *outPtr, const uint8_t *keyPtr, const uint8_t *dataPtr, uint32_t count, uint32_t prev) { if (count == 0) return dataPtr; // no reads or writes if no data uint8_t shift = 0; uint32_t key = *keyPtr++; for (uint32_t c = 0; c < count; c++) { if (shift == 8) { shift = 0; key = *keyPtr++; } uint32_t val = _decode_data(&dataPtr, (key >> shift) & 0x3); val += prev; *outPtr++ = val; prev = val; shift += 2; } return dataPtr; // pointer to first unused byte after end } #ifdef STREAMVBYTE_X64 #include "streamvbytedelta_x64_decode.c" #endif size_t streamvbyte_delta_decode(const uint8_t *in, uint32_t *out, uint32_t count, uint32_t prev) { uint32_t keyLen = ((count + 3) / 4); // 2-bits per key (rounded up) const uint8_t *keyPtr = in; const uint8_t *dataPtr = keyPtr + keyLen; // data starts at end of keys #ifdef STREAMVBYTE_X64 if(streamvbyte_ssse3()) { return svb_decode_avx_d1_init(out, keyPtr, dataPtr, count, prev) - in; } #endif return svb_decode_scalar_d1_init(out, keyPtr, dataPtr, count, prev) - in; } streamvbyte-0.5.1/src/streamvbytedelta_encode.c000066400000000000000000000042231427353355200217230ustar00rootroot00000000000000#include "streamvbytedelta.h" #include "streamvbyte_isadetection.h" #include // for memcpy #ifdef STREAMVBYTE_X64 #include "streamvbytedelta_x64_encode.c" #endif static uint8_t _encode_data(uint32_t val, uint8_t *__restrict__ *dataPtrPtr) { uint8_t *dataPtr = *dataPtrPtr; uint8_t code; if (val < (1 << 8)) { // 1 byte *dataPtr = (uint8_t)(val); *dataPtrPtr += 1; code = 0; } else if (val < (1 << 16)) { // 2 bytes memcpy(dataPtr, &val, 2); // assumes little endian *dataPtrPtr += 2; code = 1; } else if (val < (1 << 24)) { // 3 bytes memcpy(dataPtr, &val, 3); // assumes little endian *dataPtrPtr += 3; code = 2; } else { // 4 bytes memcpy(dataPtr, &val, sizeof(uint32_t)); *dataPtrPtr += sizeof(uint32_t); code = 3; } return code; } static uint8_t *svb_encode_scalar_d1_init(const uint32_t *in, uint8_t *__restrict__ keyPtr, uint8_t *__restrict__ dataPtr, uint32_t count, uint32_t prev) { if (count == 0) return dataPtr; // exit immediately if no data uint8_t shift = 0; // cycles 0, 2, 4, 6, 0, 2, 4, 6, ... uint8_t key = 0; for (uint32_t c = 0; c < count; c++) { if (shift == 8) { shift = 0; *keyPtr++ = key; key = 0; } uint32_t val = in[c] - prev; prev = in[c]; uint8_t code = _encode_data(val, &dataPtr); key |= code << shift; shift += 2; } *keyPtr = key; // write last key (no increment needed) return dataPtr; // pointer to first unused data byte } size_t streamvbyte_delta_encode(const uint32_t *in, uint32_t count, uint8_t *out, uint32_t prev) { #ifdef STREAMVBYTE_X64 if(streamvbyte_ssse3()) { return streamvbyte_encode_SSSE3_d1_init(in,count,out,prev); } #endif uint8_t *keyPtr = out; // keys come immediately after 32-bit count uint32_t keyLen = (count + 3) / 4; // 2-bits rounded to full byte uint8_t *dataPtr = keyPtr + keyLen; // variable byte data after all keys return svb_encode_scalar_d1_init(in, keyPtr, dataPtr, count, prev) - out; } streamvbyte-0.5.1/src/streamvbytedelta_x64_decode.c000066400000000000000000000154131427353355200224150ustar00rootroot00000000000000#include // for memcpy #include "streamvbyte_shuffle_tables_decode.h" #include "streamvbyte_isadetection.h" #ifdef STREAMVBYTE_X64 STREAMVBYTE_TARGET_SSSE3 static inline __m128i _decode_avx(uint32_t key, const uint8_t *__restrict__ *dataPtrPtr) { uint8_t len = lengthTable[key]; __m128i Data = _mm_loadu_si128((__m128i *)*dataPtrPtr); __m128i Shuf = *(__m128i *)&shuffleTable[key]; Data = _mm_shuffle_epi8(Data, Shuf); *dataPtrPtr += len; return Data; } STREAMVBYTE_UNTARGET_REGION #define BroadcastLastXMM 0xFF // bits 0-7 all set to choose highest element STREAMVBYTE_TARGET_SSSE3 static inline void _write_avx(uint32_t *out, __m128i Vec) { _mm_storeu_si128((__m128i *)out, Vec); } STREAMVBYTE_UNTARGET_REGION STREAMVBYTE_TARGET_SSSE3 static __m128i _write_avx_d1(uint32_t *out, __m128i Vec, __m128i Prev) { __m128i Add = _mm_slli_si128(Vec, 4); // Cycle 1: [- A B C] (already done) Prev = _mm_shuffle_epi32(Prev, BroadcastLastXMM); // Cycle 2: [P P P P] Vec = _mm_add_epi32(Vec, Add); // Cycle 2: [A AB BC CD] Add = _mm_slli_si128(Vec, 8); // Cycle 3: [- - A AB] Vec = _mm_add_epi32(Vec, Prev); // Cycle 3: [PA PAB PBC PCD] Vec = _mm_add_epi32(Vec, Add); // Cycle 4: [PA PAB PABC PABCD] _write_avx(out, Vec); return Vec; } STREAMVBYTE_UNTARGET_REGION STREAMVBYTE_TARGET_SSSE3 static inline __m128i _write_16bit_avx_d1(uint32_t *out, __m128i Vec, __m128i Prev) { #ifndef _MSC_VER __m128i High16To32 = {0xFFFF0B0AFFFF0908, 0xFFFF0F0EFFFF0D0C}; #else __m128i High16To32 = {8, 9, -1, -1, 10, 11, -1, -1, 12, 13, -1, -1, 14, 15, -1, -1}; #endif // vec == [A B C D E F G H] (16 bit values) __m128i Add = _mm_slli_si128(Vec, 2); // [- A B C D E F G] Prev = _mm_shuffle_epi32(Prev, BroadcastLastXMM); // [P P P P] (32-bit) Vec = _mm_add_epi32(Vec, Add); // [A AB BC CD DE FG GH] Add = _mm_slli_si128(Vec, 4); // [- - A AB BC CD DE EF] Vec = _mm_add_epi32(Vec, Add); // [A AB ABC ABCD BCDE CDEF DEFG EFGH] __m128i V1 = _mm_cvtepu16_epi32(Vec); // [A AB ABC ABCD] (32-bit) V1 = _mm_add_epi32(V1, Prev); // [PA PAB PABC PABCD] (32-bit) __m128i V2 = _mm_shuffle_epi8(Vec, High16To32); // [BCDE CDEF DEFG EFGH] (32-bit) V2 = _mm_add_epi32(V1, V2); // [PABCDE PABCDEF PABCDEFG PABCDEFGH] (32-bit) _write_avx(out, V1); _write_avx(out + 4, V2); return V2; } STREAMVBYTE_UNTARGET_REGION STREAMVBYTE_TARGET_SSSE3 const uint8_t *svb_decode_avx_d1_init(uint32_t *out, const uint8_t *__restrict__ keyPtr, const uint8_t *__restrict__ dataPtr, uint64_t count, uint32_t prev) { uint64_t keybytes = count / 4; // number of key bytes if (keybytes >= 8) { __m128i Prev = _mm_set1_epi32(prev); __m128i Data; int64_t Offset = -(int64_t)keybytes / 8 + 1; const uint64_t *keyPtr64 = (const uint64_t *)keyPtr - Offset; uint64_t nextkeys; memcpy(&nextkeys, keyPtr64 + Offset, sizeof(nextkeys)); for (; Offset != 0; ++Offset) { uint64_t keys = nextkeys; memcpy(&nextkeys, keyPtr64 + Offset + 1, sizeof(nextkeys)); // faster 16-bit delta since we only have 8-bit values if (!keys) { // 32 1-byte ints in a row Data = _mm_cvtepu8_epi16(_mm_lddqu_si128((__m128i *)(dataPtr))); Prev = _write_16bit_avx_d1(out, Data, Prev); Data = _mm_cvtepu8_epi16(_mm_lddqu_si128((__m128i *)(dataPtr + 8))); Prev = _write_16bit_avx_d1(out + 8, Data, Prev); Data = _mm_cvtepu8_epi16(_mm_lddqu_si128((__m128i *)(dataPtr + 16))); Prev = _write_16bit_avx_d1(out + 16, Data, Prev); Data = _mm_cvtepu8_epi16(_mm_lddqu_si128((__m128i *)(dataPtr + 24))); Prev = _write_16bit_avx_d1(out + 24, Data, Prev); out += 32; dataPtr += 32; continue; } Data = _decode_avx(keys & 0x00FF, &dataPtr); Prev = _write_avx_d1(out, Data, Prev); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); Prev = _write_avx_d1(out + 4, Data, Prev); keys >>= 16; Data = _decode_avx((keys & 0x00FF), &dataPtr); Prev = _write_avx_d1(out + 8, Data, Prev); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); Prev = _write_avx_d1(out + 12, Data, Prev); keys >>= 16; Data = _decode_avx((keys & 0x00FF), &dataPtr); Prev = _write_avx_d1(out + 16, Data, Prev); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); Prev = _write_avx_d1(out + 20, Data, Prev); keys >>= 16; Data = _decode_avx((keys & 0x00FF), &dataPtr); Prev = _write_avx_d1(out + 24, Data, Prev); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); Prev = _write_avx_d1(out + 28, Data, Prev); out += 32; } { uint64_t keys = nextkeys; // faster 16-bit delta since we only have 8-bit values if (!keys) { // 32 1-byte ints in a row Data = _mm_cvtepu8_epi16(_mm_lddqu_si128((__m128i *)(dataPtr))); Prev = _write_16bit_avx_d1(out, Data, Prev); Data = _mm_cvtepu8_epi16(_mm_lddqu_si128((__m128i *)(dataPtr + 8))); Prev = _write_16bit_avx_d1(out + 8, Data, Prev); Data = _mm_cvtepu8_epi16(_mm_lddqu_si128((__m128i *)(dataPtr + 16))); Prev = _write_16bit_avx_d1(out + 16, Data, Prev); Data = _mm_cvtepu8_epi16(_mm_loadl_epi64((__m128i *)(dataPtr + 24))); Prev = _write_16bit_avx_d1(out + 24, Data, Prev); out += 32; dataPtr += 32; } else { Data = _decode_avx(keys & 0x00FF, &dataPtr); Prev = _write_avx_d1(out, Data, Prev); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); Prev = _write_avx_d1(out + 4, Data, Prev); keys >>= 16; Data = _decode_avx((keys & 0x00FF), &dataPtr); Prev = _write_avx_d1(out + 8, Data, Prev); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); Prev = _write_avx_d1(out + 12, Data, Prev); keys >>= 16; Data = _decode_avx((keys & 0x00FF), &dataPtr); Prev = _write_avx_d1(out + 16, Data, Prev); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); Prev = _write_avx_d1(out + 20, Data, Prev); keys >>= 16; Data = _decode_avx((keys & 0x00FF), &dataPtr); Prev = _write_avx_d1(out + 24, Data, Prev); Data = _decode_avx((keys & 0xFF00) >> 8, &dataPtr); Prev = _write_avx_d1(out + 28, Data, Prev); out += 32; } } prev = out[-1]; } uint64_t consumedkeys = keybytes - (keybytes & 7); return svb_decode_scalar_d1_init(out, keyPtr + consumedkeys, dataPtr, count & 31, prev); } STREAMVBYTE_UNTARGET_REGION #endif streamvbyte-0.5.1/src/streamvbytedelta_x64_encode.c000066400000000000000000000043471427353355200224330ustar00rootroot00000000000000 #include "streamvbyte_shuffle_tables_encode.h" #include "streamvbyte_isadetection.h" #ifdef STREAMVBYTE_X64 STREAMVBYTE_TARGET_SSSE3 static __m128i Delta(__m128i curr, __m128i prev) { return _mm_sub_epi32(curr, _mm_alignr_epi8(curr, prev, 12)); } STREAMVBYTE_UNTARGET_REGION // based on code by aqrit (streamvbyte_encode_SSSE3) STREAMVBYTE_TARGET_SSSE3 size_t streamvbyte_encode_SSSE3_d1_init (const uint32_t* in, uint32_t count, uint8_t* out, uint32_t prev) { __m128i Prev = _mm_set1_epi32(prev); uint32_t keyLen = (count >> 2) + (((count & 3) + 3) >> 2); // 2-bits per each rounded up to byte boundry uint8_t *restrict keyPtr = &out[0]; uint8_t *restrict dataPtr = &out[keyLen]; // variable length data after keys const __m128i mask_01 = _mm_set1_epi8(0x01); const __m128i mask_7F00 = _mm_set1_epi16(0x7F00); for (const uint32_t* end = &in[(count & ~7)]; in != end; in += 8) { __m128i rawr0, r0, rawr1, r1, r2, r3; size_t keys; rawr0 = _mm_loadu_si128((__m128i*)&in[0]); r0 = Delta(rawr0, Prev); Prev = rawr0; rawr1 = _mm_loadu_si128((__m128i*)&in[4]); r1 = Delta(rawr1, Prev); Prev = rawr1; r2 = _mm_min_epu8(mask_01, r0); r3 = _mm_min_epu8(mask_01, r1); r2 = _mm_packus_epi16(r2, r3); r2 = _mm_min_epi16(r2, mask_01); // convert 0x01FF to 0x0101 r2 = _mm_adds_epu16(r2, mask_7F00); // convert: 0x0101 to 0x8001, 0xFF01 to 0xFFFF keys = (size_t)_mm_movemask_epi8(r2); r2 = _mm_loadu_si128((__m128i*)&shuf_lut[(keys << 4) & 0x03F0]); r3 = _mm_loadu_si128((__m128i*)&shuf_lut[(keys >> 4) & 0x03F0]); r0 = _mm_shuffle_epi8(r0, r2); r1 = _mm_shuffle_epi8(r1, r3); _mm_storeu_si128((__m128i *)dataPtr, r0); dataPtr += len_lut[keys & 0xFF]; _mm_storeu_si128((__m128i *)dataPtr, r1); dataPtr += len_lut[keys >> 8]; *((uint16_t*)keyPtr) = (uint16_t)keys; keyPtr += 2; } prev = _mm_extract_epi32(Prev,3); // do remaining uint32_t key = 0; for(size_t i = 0; i < (count & 7); i++) { uint32_t dw = in[i] - prev; prev = in[i]; uint32_t symbol = (dw > 0x000000FF) + (dw > 0x0000FFFF) + (dw > 0x00FFFFFF); key |= symbol << (i + i); *((uint32_t*)dataPtr) = dw; dataPtr += 1 + symbol; } memcpy(keyPtr, &key, ((count & 7) + 3) >> 2); return dataPtr - out; } STREAMVBYTE_UNTARGET_REGION #endif streamvbyte-0.5.1/tests/000077500000000000000000000000001427353355200152355ustar00rootroot00000000000000streamvbyte-0.5.1/tests/perf.c000066400000000000000000000037161427353355200163440ustar00rootroot00000000000000#include "streamvbyte.h" #include #include #include #include #include #include #include void punt(long long n, char *s) { int i = 127; int sign = 0; if (n < 0) { sign = 1; n = -n; } s[i--] = '\0'; // null terminated int digits = 0; do { s[i--] = n % 10 + '0'; digits++; n /= 10; if (((digits % 3) == 0) && (n != 0)) s[i--] = ','; } while (n); if (sign) s[i--] = '-'; memmove(s, s + i + 1, 127 - i); } int main() { int N = 500000; int NTrials = 100; struct rusage before; struct rusage after; float t; char s[128]; char s1[128]; char s2[128]; uint32_t datain[N]; uint8_t compressedbuffer[N * 5]; uint32_t recovdata[N]; for (int k = 0; k < N; ++k) datain[k] = rand() >> (31 & rand()); size_t compsize = 0; getrusage(RUSAGE_SELF, &before); for (int i = 0; i < NTrials; i++) compsize = streamvbyte_encode(datain, N, compressedbuffer); getrusage(RUSAGE_SELF, &after); t = (after.ru_utime.tv_usec - before.ru_utime.tv_usec) / 1000000.0; punt((long long)round(N * NTrials / t), s); printf("encoding time = %f s, %s uints/sec\n", t, s); size_t compsize2; getrusage(RUSAGE_SELF, &before); for (int i = 0; i < NTrials; i++) compsize2 = streamvbyte_decode(compressedbuffer, recovdata, N); getrusage(RUSAGE_SELF, &after); t = (after.ru_utime.tv_usec - before.ru_utime.tv_usec) / 1000000.0; punt((long long)round(N * NTrials / t), s); printf("decoding time = %f s, %s uints/sec\n", t, s); if (compsize != compsize2) printf("compsize=%zu compsize2 = %zu\n", compsize, compsize2); int k; for (k = 0; k < N && datain[k] == recovdata[k]; k++) ; if (k < N) printf("mismatch at %d before=%d after=%d\n", k, datain[k], recovdata[k]); assert(k >= N); punt(N * sizeof(uint32_t), s1); punt(compsize, s2); printf("Compressed %s bytes down to %s bytes.\n", s1, s2); return 0; } streamvbyte-0.5.1/tests/unit.c000066400000000000000000006041471427353355200163740ustar00rootroot00000000000000#include "streamvbyte.h" #include "streamvbyte_zigzag.h" #include "streamvbytedelta.h" #include "../src/streamvbyte_isadetection.h" #include #include #include #include static bool isLittleEndian() { int x = 1; char *c = (char *)&x; return (*c == 1); } // return -1 in case of failure int zigzagtests() { size_t N = 4096; int32_t *datain = malloc(N * sizeof(int32_t)); for(size_t i = 0; i < N; i++) datain[i] = rand() - rand(); uint32_t *dataout = malloc(N * sizeof(uint32_t)); int32_t *databack = malloc(N * sizeof(int32_t)); uint32_t *deltadataout = malloc(N * sizeof(uint32_t)); int32_t *deltadataback = malloc(N * sizeof(int32_t)); zigzag_encode(datain, dataout, N); zigzag_decode(dataout, databack, N); zigzag_delta_encode(datain, deltadataout, N, 0); zigzag_delta_decode(deltadataout, deltadataback, N, 0); int isok = 1; for(size_t i = 0; i < N; i++) { if(datain[i] != databack[i]) { printf("bug\n"); isok = -1; } if(datain[i] != deltadataback[i]) { printf("bug\n"); isok = -1; } } free(databack); free(dataout); free(datain); return isok; } // Fixtures from https://developers.google.com/protocol-buffers/docs/encoding#signed_integers int zigzagfixturestests() { const int32_t original[] = {0, -1, 1, -2, 2147483647, -2147483648}; const uint32_t encoded[] = {0, 1, 2, 3, 4294967294, 4294967295}; uint32_t out[] = {0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa}; zigzag_encode(original, out, 6); for (size_t i = 0; i < 6; ++i) { if (encoded[i] != out[i]) { printf("[zigzag_encode] %ju != %ju\n", (uintmax_t)encoded[i], (uintmax_t)out[i]); return -1; } } int32_t roundtrip[] = {0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555}; zigzag_decode((const uint32_t *)out, roundtrip, 6); for (size_t i = 0; i < 6; ++i) { if (original[i] != roundtrip[i]) { printf("[zigzag_decode] %jd != %jd\n", (intmax_t)original[i], (intmax_t)roundtrip[i]); return -1; } } return 0; } // return -1 in case of failure int basictests() { int N = 4096; uint32_t *datain = malloc(N * sizeof(uint32_t)); // on purpose we mess with the alignment of compressedbufferorig uint8_t *compressedbufferorig = malloc(streamvbyte_max_compressedbytes(N)); uint8_t *compressedbuffer = compressedbufferorig + (sizeof(uint32_t) - 1); uint32_t *recovdata = malloc(N * sizeof(uint32_t)); for (int length = 0; length <= N;) { for (uint32_t gap = 1; gap <= 387420489; gap *= 3) { for (int k = 0; k < length; ++k) datain[k] = gap - 1 + (rand() % 8); // sometimes start with zero // Default encoding: 1,2,3,4 bytes per value size_t compsize = streamvbyte_encode(datain, length, compressedbuffer); size_t usedbytes = streamvbyte_decode(compressedbuffer, recovdata, length); if (compsize != usedbytes) { printf("[streamvbyte_decode] code is buggy length=%d gap=%d: compsize=%d != " "usedbytes=%d \n", (int)length, (int)gap, (int)compsize, (int)usedbytes); return -1; } for (int k = 0; k < length; ++k) { if (recovdata[k] != datain[k]) { printf("[streamvbyte_decode] code is buggy gap=%d\n", (int)gap); return -1; } } // Alternative encoding: 0,1,2,4 bytes per value compsize = streamvbyte_encode_0124(datain, length, compressedbuffer); usedbytes = streamvbyte_decode_0124(compressedbuffer, recovdata, length); if (compsize != usedbytes) { printf("[streamvbyte_decode_0124] code is buggy length=%d gap=%d: compsize=%d != " "usedbytes=%d \n", (int)length, (int)gap, (int)compsize, (int)usedbytes); return -1; } for (int k = 0; k < length; ++k) { if (recovdata[k] != datain[k]) { printf("[streamvbyte_decode_0124] code is buggy gap=%d\n", (int)gap); return -1; } } } // Delta-encoded functions for (size_t gap = 1; gap <= 531441; gap *= 3) { for (int k = 0; k < length; ++k) datain[k] = gap * k; size_t compsize = streamvbyte_delta_encode(datain, length, compressedbuffer, 0); size_t usedbytes = streamvbyte_delta_decode(compressedbuffer, recovdata, length, 0); if (compsize != usedbytes) { printf("[streamvbyte_delta_decode] code is buggy gap=%d, size " "mismatch %d %d \n", (int)gap, (int)compsize, (int)usedbytes); return -1; } for (int k = 0; k < length; ++k) { if (recovdata[k] != datain[k]) { printf("[streamvbyte_delta_decode] code is buggy gap=%d\n", (int)gap); return -1; } } } if (length < 128) ++length; else { length *= 2; } } free(datain); free(compressedbufferorig); free(recovdata); return 0; } // return -1 in case of failure int aqrittests() { uint8_t in[16]; uint8_t compressedbuffer[32]; uint8_t recovdata[16]; memset(compressedbuffer, 0, 32); memset(recovdata, 0, 16); for (int i = 0; i < 0x10000; i++) { in[0] = (uint8_t)((i >> 0) & 1); in[1] = (uint8_t)((i >> 1) & 1); in[2] = (uint8_t)((i >> 2) & 1); in[3] = (uint8_t)((i >> 3) & 1); in[4] = (uint8_t)((i >> 4) & 1); in[5] = (uint8_t)((i >> 5) & 1); in[6] = (uint8_t)((i >> 6) & 1); in[7] = (uint8_t)((i >> 7) & 1); in[8] = (uint8_t)((i >> 8) & 1); in[9] = (uint8_t)((i >> 9) & 1); in[10] = (uint8_t)((i >> 10) & 1); in[11] = (uint8_t)((i >> 11) & 1); in[12] = (uint8_t)((i >> 12) & 1); in[13] = (uint8_t)((i >> 13) & 1); in[14] = (uint8_t)((i >> 14) & 1); in[15] = (uint8_t)((i >> 15) & 1); const int length = 4; size_t compsize = streamvbyte_encode((uint32_t *)in, length, compressedbuffer); size_t usedbytes = streamvbyte_decode(compressedbuffer, (uint32_t *)recovdata, length); if (compsize != usedbytes) { printf("[streamvbyte_decode] code is buggy"); return -1; } for (size_t k = 0; k < length * sizeof(uint32_t); ++k) { if (recovdata[k] != in[k]) { printf("[streamvbyte_decode] code is buggy"); return -1; } } compsize = streamvbyte_encode_0124((uint32_t *)in, length, compressedbuffer); usedbytes = streamvbyte_decode_0124(compressedbuffer, (uint32_t *)recovdata, length); if (compsize != usedbytes) { printf("[streamvbyte_decode_0124] code is buggy"); return -1; } for (size_t k = 0; k < length * sizeof(uint32_t); ++k) { if (recovdata[k] != in[k]) { printf("[streamvbyte_decode_0124] code is buggy"); return -1; } } } return 0; } int compressedbytestests() { const uint32_t *empty = 0; if (streamvbyte_compressedbytes(empty, 0) != 0) { return -1; } uint32_t small[] = {1, 1, 1, 1}; if (streamvbyte_compressedbytes(small, 4) != (1 + (4 * 1))) { return -1; } uint32_t big[] = {260, 260, 260, 260}; if (streamvbyte_compressedbytes(big, 4) != (1 + (4 * 2))) { return -1; } uint32_t biggest[] = {-1, -1, -1, -1}; if (streamvbyte_compressedbytes(biggest, 4) != (1 + (4 * 4))) { return -1; } return 0; } int compressedbytestests0124() { const uint32_t *empty = 0; if (streamvbyte_compressedbytes_0124(empty, 0) != 0) { return -1; } uint32_t small[] = {0, 0, 0, 0}; if (streamvbyte_compressedbytes_0124(small, 4) != (1 + (4 * 0))) { return -1; } uint32_t big[] = {260, 260, 260, 260}; if (streamvbyte_compressedbytes_0124(big, 4) != (1 + (4 * 2))) { return -1; } uint32_t biggest[] = {-1, -1, -1, -1}; if (streamvbyte_compressedbytes_0124(biggest, 4) != (1 + (4 * 4))) { return -1; } return 0; } bool issue42() { uint8_t a[36494] = { 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 64, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 4, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 6, 29, 1, 15, 15, 1, 7, 11, 10, 10, 9, 24, 17, 7, 5, 0, 1, 3, 2, 3, 12, 1, 4, 0, 0, 1, 13, 7, 16, 5, 16, 21, 18, 53, 9, 4, 3, 1, 1, 2, 4, 12, 7, 0, 0, 2, 1, 2, 1, 8, 11, 0, 16, 7, 7, 6, 2, 23, 10, 0, 0, 2, 1, 12, 31, 1, 7, 7, 18, 3, 9, 8, 6, 17, 16, 1, 1, 3, 1, 10, 4, 11, 12, 4, 21, 24, 19, 2, 12, 21, 0, 18, 5, 0, 3, 2, 6, 1, 1, 2, 0, 3, 1, 6, 4, 9, 1, 0, 5, 10, 11, 8, 3, 8, 11, 12, 6, 17, 6, 3, 16, 9, 4, 2, 6, 1, 11, 10, 9, 13, 18, 12, 17, 7, 18, 5, 16, 17, 1, 20, 11, 17, 14, 3, 6, 10, 5, 0, 13, 12, 0, 0, 1, 1, 11, 4, 6, 4, 9, 4, 18, 6, 17, 16, 13, 1, 2, 0, 2, 5, 8, 11, 7, 10, 8, 1, 3, 2, 4, 4, 15, 26, 17, 14, 15, 3, 8, 3, 8, 15, 16, 2, 9, 2, 7, 10, 3, 8, 7, 3, 1, 14, 5, 9, 16, 1, 13, 16, 9, 4, 0, 9, 8, 1, 8, 1, 7, 7, 18, 2, 13, 4, 18, 15, 6, 5, 6, 3, 2, 3, 1, 3, 10, 3, 3, 2, 6, 10, 17, 16, 7, 1, 1, 0, 2, 9, 12, 5, 5, 12, 3, 8, 0, 7, 2, 6, 1, 9, 12, 3, 2, 1, 4, 0, 15, 22, 15, 2, 14, 9, 1, 1, 10, 2, 13, 2, 8, 8, 19, 10, 7, 8, 9, 4, 5, 22, 2, 17, 1, 4, 3, 5, 4, 2, 2, 0, 4, 11, 14, 3, 1, 15, 14, 4, 9, 0, 3, 6, 4, 9, 14, 1, 1, 4, 9, 12, 2, 3, 2, 5, 8, 7, 10, 7, 8, 11, 6, 5, 10, 4, 3, 0, 9, 6, 6, 0, 9, 4, 2, 3, 3, 12, 3, 7, 4, 4, 5, 2, 6, 5, 1, 2, 3, 6, 0, 0, 7, 0, 0, 11, 18, 0, 3, 4, 10, 17, 4, 3, 8, 0, 9, 0, 10, 4, 9, 4, 5, 10, 13, 6, 2, 4, 7, 6, 9, 8, 6, 9, 18, 1, 1, 9, 2, 18, 9, 2, 2, 7, 3, 3, 2, 4, 0, 0, 7, 0, 16, 2, 4, 3, 5, 1, 1, 9, 3, 14, 1, 3, 11, 1, 12, 2, 6, 4, 13, 3, 2, 0, 14, 5, 14, 9, 5, 6, 5, 12, 1, 5, 16, 11, 0, 5, 6, 1, 3, 14, 9, 4, 0, 0, 4, 3, 6, 17, 0, 14, 7, 12, 4, 14, 2, 5, 2, 9, 20, 13, 2, 0, 6, 7, 8, 2, 10, 11, 11, 12, 2, 4, 2, 6, 0, 3, 0, 0, 2, 1, 4, 23, 19, 4, 2, 3, 8, 7, 7, 12, 7, 3, 12, 13, 10, 4, 3, 12, 15, 12, 24, 2, 2, 18, 17, 8, 5, 7, 8, 6, 2, 4, 3, 17, 10, 10, 3, 11, 6, 5, 21, 18, 6, 1, 4, 0, 4, 7, 10, 25, 22, 3, 2, 11, 4, 13, 7, 11, 6, 1, 34, 1, 0, 12, 11, 10, 3, 18, 8, 1, 5, 12, 68, 16, 2, 27, 6, 10, 11, 2, 6, 17, 6, 16, 1, 27, 16, 4, 0, 3, 14, 9, 1, 5, 4, 40, 6, 3, 4, 13, 3, 6, 1, 14, 11, 11, 10, 10, 7, 5, 12, 15, 18, 3, 2, 9, 18, 9, 3, 9, 16, 2, 4, 21, 24, 0, 11, 1, 1, 0, 4, 8, 7, 15, 17, 2, 3, 2, 1, 1, 8, 5, 8, 12, 13, 8, 13, 12, 8, 2, 6, 27, 0, 1, 4, 0, 4, 18, 11, 7, 4, 4, 13, 3, 7, 16, 4, 6, 4, 9, 11, 18, 13, 10, 8, 13, 6, 0, 8, 15, 16, 1, 9, 14, 19, 27, 14, 4, 14, 1, 2, 0, 8, 2, 3, 6, 7, 13, 11, 28, 4, 8, 11, 4, 13, 6, 2, 5, 6, 13, 10, 3, 7, 18, 13, 14, 13, 16, 5, 0, 3, 2, 3, 1, 11, 2, 22, 36, 3, 14, 39, 10, 12, 9, 16, 5, 20, 21, 2, 5, 10, 0, 2, 11, 2, 18, 5, 17, 4, 1, 22, 94, 7, 12, 17, 20, 3, 8, 18, 21, 7, 20, 4, 4, 13, 10, 6, 11, 14, 4, 2, 0, 12, 15, 7, 4, 4, 2, 4, 5, 4, 12, 2, 3, 7, 1, 4, 4, 13, 2, 4, 8, 0, 8, 9, 17, 18, 23, 16, 1, 14, 1, 4, 7, 6, 0, 11, 6, 8, 23, 61, 7, 27, 3, 4, 8, 10, 21, 2, 12, 5, 14, 0, 0, 4, 49, 21, 6, 8, 30, 5, 6, 1, 1, 6, 3, 23, 2, 2, 21, 46, 11, 2, 1, 30, 13, 12, 0, 27, 8, 26, 15, 3, 21, 3, 22, 21, 20, 31, 8, 30, 16, 16, 15, 15, 0, 11, 8, 0, 8, 8, 1, 9, 16, 2, 7, 18, 7, 23, 32, 11, 3, 29, 11, 28, 31, 28, 52, 33, 28, 15, 3, 9, 24, 25, 2, 13, 4, 5, 8, 8, 2, 15, 30, 8, 17, 2, 5, 13, 32, 17, 16, 19, 6, 15, 6, 8, 13, 14, 3, 18, 21, 36, 13, 10, 8, 13, 6, 0, 15, 4, 4, 7, 7, 1, 13, 20, 3, 3, 36, 31, 10, 0, 8, 9, 9, 14, 16, 13, 4, 20, 7, 3, 13, 16, 35, 24, 7, 12, 1, 23, 32, 9, 10, 1, 11, 12, 3, 5, 0, 4, 19, 9, 18, 19, 36, 35, 29, 54, 53, 56, 12, 14, 9, 3, 9, 5, 22, 43, 26, 1, 27, 18, 5, 5, 29, 56, 32, 9, 17, 14, 7, 22, 11, 9, 4, 10, 1, 17, 33, 4, 12, 3, 6, 2, 6, 6, 2, 11, 0, 8, 7, 5, 6, 1, 3, 5, 9, 26, 9, 8, 5, 3, 11, 14, 18, 9, 7, 3, 20, 7, 18, 41, 22, 5, 14, 7, 4, 11, 22, 11, 19, 4, 8, 14, 2, 1, 7, 1, 1, 3, 11, 6, 7, 0, 18, 0, 16, 10, 9, 2, 0, 11, 8, 1, 6, 21, 3, 24, 13, 8, 13, 13, 1, 0, 10, 9, 2, 12, 1, 0, 12, 23, 15, 4, 16, 6, 19, 4, 12, 30, 31, 18, 17, 24, 18, 4, 7, 9, 31, 13, 8, 14, 2, 9, 10, 3, 39, 14, 24, 6, 17, 38, 4, 9, 5, 3, 15, 2, 7, 49, 4, 38, 0, 18, 8, 11, 26, 9, 9, 1, 12, 7, 14, 0, 1, 31, 20, 15, 11, 8, 22, 8, 5, 9, 21, 22, 8, 3, 23, 47, 14, 48, 10, 6, 33, 16, 10, 14, 43, 3, 48, 20, 4, 13, 13, 23, 30, 9, 10, 15, 0, 19, 22, 11, 12, 17, 40, 20, 33, 22, 5, 55, 57, 24, 11, 5, 3, 4, 2, 16, 23, 7, 34, 0, 7, 2, 8, 2, 5, 0, 14, 11, 8, 19, 2, 10, 0, 12, 11, 15, 8, 3, 18, 5, 13, 14, 17, 14, 3, 1, 12, 1, 11, 8, 5, 4, 9, 18, 15, 3, 10, 9, 24, 9, 6, 2, 5, 4, 23, 10, 10, 15, 7, 16, 1, 9, 2, 14, 1, 29, 22, 1, 10, 17, 10, 11, 16, 28, 23, 6, 2, 3, 8, 37, 22, 10, 29, 69, 28, 2, 1, 3, 11, 18, 11, 6, 0, 25, 10, 18, 14, 17, 3, 0, 3, 20, 5, 1, 1, 6, 8, 13, 5, 6, 4, 6, 9, 4, 1, 1, 4, 3, 5, 12, 11, 15, 4, 25, 12, 22, 15, 20, 5, 5, 11, 20, 5, 1, 14, 29, 16, 8, 3, 19, 26, 20, 29, 17, 6, 26, 1, 7, 17, 1, 14, 14, 0, 11, 6, 7, 8, 15, 6, 5, 12, 17, 6, 5, 0, 28, 0, 0, 13, 5, 1, 22, 4, 6, 2, 9, 0, 3, 6, 1, 6, 10, 23, 8, 5, 2, 12, 3, 9, 6, 2, 11, 4, 6, 8, 21, 20, 5, 11, 8, 10, 4, 5, 0, 6, 5, 13, 3, 6, 3, 3, 8, 4, 7, 12, 8, 7, 12, 13, 5, 10, 7, 16, 9, 2, 1, 14, 7, 10, 1, 9, 9, 3, 1, 0, 0, 4, 27, 4, 5, 14, 1, 20, 9, 8, 9, 15, 13, 7, 22, 24, 10, 16, 8, 15, 10, 13, 10, 2, 2, 7, 8, 27, 2, 5, 6, 13, 2, 34, 7, 0, 3, 3, 11, 1, 28, 8, 17, 25, 8, 4, 1, 5, 2, 8, 8, 15, 30, 17, 21, 6, 0, 5, 5, 12, 38, 4, 11, 3, 12, 0, 0, 4, 13, 8, 6, 3, 0, 5, 22, 15, 3, 6, 8, 9, 3, 12, 15, 12, 1, 4, 2, 7, 2, 2, 6, 3, 1, 5, 1, 12, 5, 9, 13, 18, 0, 8, 5, 5, 12, 0, 4, 3, 11, 8, 0, 1, 2, 3, 6, 15, 16, 15, 12, 4, 12, 13, 25, 1, 18, 9, 4, 5, 12, 5, 0, 4, 10, 15, 24, 9, 2, 0, 8, 15, 1, 4, 4, 6, 13, 12, 5, 8, 5, 56, 46, 12, 5, 44, 3, 0, 2, 8, 0, 19, 4, 12, 1, 3, 1, 30, 41, 0, 28, 2, 0, 3, 5, 5, 8, 19, 1, 30, 9, 27, 16, 7, 1, 0, 5, 0, 7, 1, 22, 14, 1, 15, 14, 8, 19, 12, 5, 26, 1, 9, 0, 13, 10, 2, 9, 14, 17, 87, 7, 21, 6, 6, 30, 5, 5, 6, 7, 8, 10, 17, 26, 7, 15, 6, 3, 6, 7, 16, 9, 11, 22, 3, 9, 18, 7, 13, 20, 17, 18, 17, 9, 2, 7, 15, 0, 11, 20, 3, 6, 8, 0, 2, 11, 8, 4, 14, 13, 9, 12, 2, 5, 9, 14, 23, 18, 1, 8, 9, 6, 27, 14, 14, 2, 1, 3, 6, 0, 1, 0, 10, 37, 24, 3, 4, 12, 15, 2, 6, 1, 7, 1, 14, 15, 3, 18, 7, 14, 3, 21, 20, 9, 4, 4, 2, 9, 14, 15, 3, 9, 22, 9, 1, 13, 4, 19, 8, 6, 0, 6, 0, 4, 0, 3, 22, 25, 2, 2, 18, 0, 23, 0, 2, 5, 1, 6, 6, 8, 13, 7, 0, 8, 2, 10, 0, 5, 0, 15, 24, 0, 21, 38, 21, 0, 4, 13, 4, 8, 3, 12, 3, 9, 16, 3, 29, 8, 12, 0, 6, 11, 18, 23, 8, 13, 6, 22, 23, 18, 9, 8, 2, 15, 32, 21, 9, 6, 14, 19, 14, 11, 14, 7, 10, 7, 8, 6, 2, 19, 36, 21, 5, 12, 0, 4, 23, 14, 8, 29, 42, 24, 23, 30, 25, 24, 15, 5, 6, 11, 42, 5, 17, 15, 22, 31, 24, 19, 22, 1, 3, 6, 17, 36, 12, 39, 14, 7, 45, 42, 0, 12, 6, 0, 23, 11, 4, 8, 8, 2, 1, 0, 14, 17, 28, 1, 3, 11, 50, 49, 0, 16, 0, 19, 1, 1, 1, 22, 29, 5, 10, 16, 0, 23, 44, 29, 22, 11, 6, 9, 13, 8, 12, 3, 2, 3, 35, 20, 24, 6, 0, 27, 28, 2, 51, 24, 8, 26, 41, 10, 6, 23, 1, 7, 0, 24, 11, 24, 1, 1, 24, 29, 1, 14, 9, 26, 4, 23, 22, 17, 22, 7, 21, 18, 19, 24, 23, 4, 18, 3, 7, 14, 7, 25, 10, 8, 14, 15, 6, 12, 29, 26, 43, 50, 17, 9, 1, 8, 5, 0, 0, 28, 8, 19, 21, 28, 3, 7, 25, 85, 3, 30, 15, 24, 11, 7, 35, 32, 11, 10, 5, 6, 5, 4, 2, 7, 4, 5, 10, 6, 19, 16, 16, 13, 0, 6, 5, 7, 8, 12, 29, 25, 18, 26, 5, 4, 9, 6, 8, 6, 0, 2, 11, 18, 9, 11, 8, 4, 10, 17, 19, 1, 13, 10, 30, 45, 8, 6, 34, 6, 16, 31, 44, 3, 20, 33, 1, 45, 44, 21, 17, 6, 38, 19, 50, 8, 89, 70, 38, 33, 35, 56, 4, 11, 27, 17, 8, 10, 37, 14, 51, 46, 30, 49, 78, 11, 55, 31, 1, 15, 70, 31, 18, 19, 52, 7, 24, 53, 40, 9, 27, 48, 23, 50, 81, 40, 24, 31, 9, 36, 47, 44, 57, 52, 1, 20, 25, 13, 18, 50, 39, 11, 4, 16, 27, 18, 29, 20, 3, 65, 102, 45, 21, 30, 24, 51, 28, 45, 30, 6, 3, 104, 117, 34, 12, 19, 40, 69, 76, 5, 18, 4, 113, 104, 27, 3, 59, 44, 53, 56, 53, 68, 6, 9, 21, 24, 47, 8, 16, 5, 34, 49, 21, 80, 9, 39, 5, 18, 3, 66, 67, 10, 38, 21, 27, 3, 5, 5, 24, 44, 51, 16, 21, 25, 5, 3, 58, 34, 57, 36, 33, 1, 42, 26, 41, 15, 2, 30, 29, 18, 42, 43, 82, 30, 6, 2, 11, 5, 21, 11, 32, 4, 4, 20, 16, 15, 35, 8, 22, 11, 16, 6, 21, 2, 30, 29, 37, 48, 9, 10, 27, 18, 5, 0, 30, 5, 2, 5, 17, 8, 32, 45, 31, 14, 22, 9, 36, 13, 7, 16, 11, 1, 12, 7, 3, 29, 27, 36, 15, 14, 13, 13, 54, 20, 21, 10, 11, 18, 33, 36, 5, 20, 11, 23, 16, 25, 6, 8, 15, 28, 33, 20, 6, 20, 33, 15, 16, 0, 4, 4, 12, 5, 8, 9, 3, 5, 34, 9, 11, 2, 6, 11, 4, 11, 0, 44, 35, 22, 11, 31, 12, 7, 13, 5, 44, 12, 1, 71, 48, 10, 10, 38, 43, 20, 13, 25, 32, 27, 20, 1, 14, 11, 12, 35, 24, 10, 27, 24, 8, 25, 6, 1, 1, 17, 36, 4, 17, 17, 22, 5, 55, 4, 37, 6, 18, 38, 4, 13, 4, 5, 34, 27, 23, 60, 9, 4, 21, 4, 13, 34, 37, 14, 34, 33, 1, 5, 75, 13, 9, 12, 2, 9, 6, 8, 11, 14, 5, 9, 6, 7, 6, 1, 1, 8, 11, 4, 2, 6, 1, 8, 1, 12, 11, 1, 0, 10, 1, 7, 1, 1, 10, 0, 15, 16, 2, 17, 8, 6, 2, 4, 11, 8, 8, 10, 11, 2, 8, 4, 31, 14, 14, 5, 20, 17, 5, 9, 11, 16, 6, 2, 0, 2, 3, 3, 1, 3, 2, 0, 1, 4, 0, 5, 4, 6, 1, 1, 1, 3, 14, 0, 3, 10, 5, 1, 2, 7, 6, 3, 3, 3, 14, 9, 16, 17, 12, 2, 11, 2, 26, 25, 2, 0, 1, 0, 0, 8, 2, 13, 6, 8, 11, 2, 11, 14, 11, 8, 8, 1, 6, 1, 7, 11, 0, 6, 14, 6, 11, 0, 12, 13, 0, 0, 4, 4, 7, 2, 2, 6, 5, 4, 2, 25, 24, 7, 0, 3, 10, 27, 16, 0, 6, 0, 1, 2, 5, 18, 0, 2, 0, 11, 15, 14, 15, 14, 0, 3, 14, 57, 50, 19, 10, 13, 4, 8, 10, 5, 15, 2, 0, 17, 16, 5, 0, 22, 15, 4, 0, 5, 6, 5, 22, 29, 0, 8, 3, 12, 7, 2, 19, 2, 0, 4, 2, 4, 21, 12, 3, 6, 11, 12, 13, 3, 0, 10, 1, 7, 16, 4, 19, 18, 10, 23, 6, 0, 4, 1, 5, 25, 14, 0, 16, 11, 0, 0, 1, 2, 12, 6, 4, 12, 13, 0, 19, 13, 5, 6, 9, 4, 16, 7, 14, 0, 7, 11, 22, 17, 5, 8, 1, 5, 10, 6, 2, 11, 10, 28, 11, 6, 13, 15, 8, 2, 3, 1, 6, 18, 14, 21, 27, 8, 24, 22, 2, 3, 29, 13, 20, 2, 5, 25, 12, 14, 171, 1, 72, 76, 14, 50, 0, 46, 30, 27, 10, 14, 6, 16, 6, 7, 0, 56, 29, 4, 3, 7, 30, 12, 9, 25, 2, 34, 41, 10, 5, 12, 10, 9, 60, 14, 9, 48, 51, 1, 24, 4, 92, 47, 88, 16, 3, 5, 26, 27, 12, 24, 23, 2, 25, 21, 47, 142, 11, 31, 7, 18, 10, 27, 18, 21, 43, 11, 8, 96, 45, 28, 43, 2, 12, 11, 20, 0, 22, 29, 21, 14, 13, 13, 5, 42, 11, 14, 21, 11, 47, 10, 19, 16, 54, 45, 28, 3, 17, 60, 47, 42, 0, 4, 25, 12, 16, 7, 23, 0, 24, 8, 27, 12, 7, 0, 47, 6, 43, 18, 24, 21, 13, 38, 21, 20, 20, 36, 11, 19, 24, 11, 24, 23, 21, 9, 5, 5, 13, 26, 28, 10, 23, 5, 52, 27, 24, 0, 6, 5, 17, 14, 26, 6, 21, 12, 1, 7, 3, 1, 9, 33, 17, 8, 0, 5, 16, 2, 16, 16, 41, 7, 4, 15, 28, 38, 47, 15, 6, 9, 10, 4, 22, 28, 2, 10, 5, 29, 39, 12, 14, 22, 27, 24, 48, 10, 9, 0, 6, 17, 55, 32, 3, 15, 14, 1, 23, 11, 3, 65, 1, 3, 5, 0, 10, 15, 6, 1, 0, 5, 18, 1, 3, 15, 8, 3, 0, 6, 12, 4, 4, 26, 24, 27, 14, 18, 15, 6, 10, 16, 26, 55, 92, 11, 28, 51, 30, 8, 27, 18, 24, 35, 8, 12, 15, 6, 28, 5, 12, 19, 22, 43, 46, 35, 19, 6, 0, 0, 8, 14, 11, 12, 10, 10, 43, 14, 17, 21, 10, 34, 2, 9, 6, 9, 7, 4, 14, 7, 0, 15, 8, 8, 8, 11, 35, 14, 5, 0, 6, 5, 8, 5, 0, 13, 14, 5, 12, 1, 14, 35, 46, 9, 5, 18, 19, 1, 34, 43, 14, 5, 24, 25, 11, 1, 18, 5, 3, 24, 7, 10, 3, 5, 11, 0, 17, 30, 11, 16, 10, 8, 3, 1, 15, 4, 5, 5, 28, 15, 11, 18, 2, 1, 2, 5, 0, 5, 20, 19, 8, 10, 15, 3, 18, 5, 4, 13, 1, 5, 16, 3, 2, 6, 4, 3, 14, 21, 12, 25, 16, 0, 6, 21, 26, 7, 3, 9, 12, 6, 11, 1, 10, 16, 21, 24, 33, 14, 2, 3, 2, 8, 9, 19, 19, 8, 14, 15, 3, 1, 0, 8, 6, 11, 6, 1, 3, 28, 17, 3, 3, 1, 12, 9, 13, 32, 6, 6, 5, 0, 16, 13, 2, 9, 18, 25, 8, 5, 12, 2, 3, 20, 1, 25, 12, 18, 6, 5, 27, 36, 11, 18, 13, 4, 6, 29, 7, 9, 10, 0, 16, 19, 4, 15, 14, 4, 4, 23, 6, 18, 2, 34, 13, 3, 7, 18, 9, 8, 4, 10, 37, 4, 6, 13, 10, 3, 17, 14, 3, 14, 20, 7, 11, 0, 3, 11, 6, 22, 25, 10, 2, 8, 16, 37, 24, 9, 18, 4, 3, 1, 4, 0, 3, 25, 13, 30, 12, 15, 8, 7, 11, 28, 5, 1, 2, 1, 3, 16, 15, 24, 29, 8, 3, 2, 18, 19, 2, 3, 12, 4, 0, 0, 0, 9, 9, 14, 8, 0, 7, 8, 2, 5, 13, 4, 18, 9, 11, 10, 6, 9, 20, 27, 5, 7, 18, 10, 29, 10, 8, 1, 26, 9, 9, 6, 8, 11, 5, 5, 26, 5, 5, 0, 3, 10, 7, 7, 2, 2, 2, 12, 23, 8, 19, 20, 11, 2, 3, 8, 0, 12, 4, 4, 0, 18, 17, 3, 16, 13, 13, 24, 2, 13, 6, 7, 3, 2, 0, 3, 9, 7, 26, 15, 8, 7, 20, 7, 16, 27, 30, 19, 4, 5, 18, 4, 21, 20, 15, 2, 0, 3, 29, 12, 30, 35, 26, 9, 15, 22, 9, 4, 18, 9, 7, 6, 12, 5, 10, 7, 11, 6, 13, 10, 17, 6, 28, 15, 5, 2, 20, 6, 3, 7, 8, 13, 1, 12, 12, 6, 17, 2, 7, 3, 22, 3, 23, 13, 20, 12, 37, 20, 12, 13, 2, 16, 6, 15, 14, 3, 5, 8, 5, 3, 10, 5, 5, 6, 1, 24, 23, 0, 18, 17, 1, 2, 8, 15, 12, 29, 11, 10, 12, 17, 4, 10, 16, 25, 0, 26, 19, 15, 8, 20, 8, 5, 26, 31, 24, 11, 16, 43, 12, 2, 3, 2, 11, 1, 6, 20, 7, 8, 17, 10, 2, 15, 12, 24, 5, 21, 38, 37, 16, 10, 9, 5, 3, 14, 10, 29, 2, 20, 2, 17, 6, 17, 20, 25, 42, 6, 0, 0, 14, 19, 1, 4, 27, 32, 4, 19, 7, 26, 8, 11, 18, 21, 12, 11, 2, 9, 30, 33, 19, 12, 22, 31, 12, 14, 11, 4, 12, 0, 1, 47, 26, 0, 8, 5, 4, 6, 2, 9, 12, 16, 5, 1, 0, 1, 2, 9, 7, 38, 29, 10, 3, 20, 15, 8, 15, 0, 9, 5, 26, 17, 7, 30, 16, 35, 6, 2, 12, 3, 12, 0, 21, 8, 20, 23, 10, 21, 34, 9, 0, 11, 5, 11, 28, 5, 16, 15, 8, 15, 4, 2, 9, 6, 5, 12, 9, 4, 6, 1, 6, 12, 5, 4, 13, 15, 10, 12, 11, 4, 10, 10, 39, 16, 4, 14, 35, 3, 8, 5, 20, 6, 7, 29, 38, 9, 12, 3, 10, 13, 4, 1, 27, 9, 38, 4, 3, 15, 22, 7, 9, 2, 20, 7, 4, 4, 5, 5, 11, 18, 1, 3, 22, 31, 15, 5, 10, 5, 22, 18, 5, 5, 6, 7, 16, 9, 2, 4, 1, 1, 0, 4, 3, 0, 14, 1, 7, 13, 10, 8, 7, 26, 17, 9, 16, 9, 5, 19, 24, 9, 16, 6, 9, 4, 0, 11, 5, 12, 0, 7, 6, 1, 0, 0, 2, 2, 8, 3, 9, 0, 12, 8, 11, 10, 1, 9, 5, 6, 0, 7, 10, 2, 27, 22, 13, 8, 0, 11, 16, 22, 11, 3, 2, 7, 12, 7, 0, 13, 1, 1, 18, 0, 15, 14, 0, 12, 19, 2, 12, 6, 4, 9, 5, 3, 0, 8, 9, 3, 12, 1, 5, 6, 1, 0, 8, 3, 25, 12, 26, 21, 15, 22, 2, 8, 4, 5, 12, 55, 6, 9, 19, 22, 4, 9, 0, 16, 5, 6, 17, 15, 28, 4, 7, 1, 3, 1, 1, 14, 11, 0, 12, 1, 6, 9, 8, 9, 0, 11, 16, 8, 2, 17, 2, 4, 8, 2, 23, 16, 6, 14, 11, 5, 2, 4, 0, 5, 0, 10, 9, 15, 6, 14, 15, 22, 2, 21, 6, 0, 10, 7, 8, 15, 6, 3, 6, 2, 2, 11, 12, 0, 0, 7, 0, 8, 7, 18, 19, 12, 13, 3, 20, 9, 6, 0, 5, 12, 9, 8, 5, 2, 9, 6, 0, 0, 9, 2, 2, 10, 3, 7, 0, 10, 6, 13, 12, 15, 6, 22, 9, 3, 13, 2, 5, 22, 15, 0, 20, 9, 6, 11, 9, 6, 14, 11, 2, 3, 16, 7, 5, 14, 1, 3, 5, 12, 15, 15, 16, 20, 11, 11, 14, 0, 2, 6, 13, 12, 7, 8, 9, 12, 9, 11, 8, 18, 8, 21, 6, 3, 2, 0, 1, 2, 8, 3, 0, 9, 1, 2, 4, 3, 15, 20, 6, 23, 18, 6, 15, 4, 16, 11, 2, 3, 0, 8, 3, 2, 8, 11, 12, 5, 3, 9, 6, 6, 9, 0, 1, 4, 10, 7, 2, 11, 0, 6, 6, 1, 4, 0, 7, 0, 1, 0, 54, 7, 2, 10, 47, 20, 2, 11, 4, 8, 8, 14, 11, 14, 9, 6, 0, 1, 21, 11, 26, 13, 36, 53, 16, 20, 13, 11, 24, 23, 40, 37, 10, 22, 5, 3, 10, 11, 19, 12, 5, 0, 10, 35, 28, 4, 7, 38, 33, 2, 8, 27, 56, 11, 11, 44, 17, 26, 6, 9, 13, 9, 32, 57, 8, 5, 11, 0, 11, 10, 10, 13, 12, 4, 21, 10, 13, 14, 0, 18, 19, 12, 11, 8, 2, 11, 3, 5, 6, 2, 6, 5, 2, 12, 15, 14, 2, 7, 4, 0, 1, 12, 19, 14, 13, 16, 7, 9, 2, 10, 7, 8, 21, 26, 15, 16, 15, 20, 31, 22, 7, 2, 2, 10, 7, 6, 0, 0, 0, 10, 5, 9, 16, 5, 5, 5, 0, 4, 0, 23, 24, 9, 14, 17, 3, 6, 9, 8, 0, 3, 4, 2, 24, 19, 11, 8, 0, 6, 3, 7, 16, 9, 13, 36, 25, 6, 8, 5, 6, 6, 1, 3, 13, 2, 1, 0, 14, 2, 25, 1, 36, 3, 0, 1, 0, 8, 8, 5, 21, 2, 24, 11, 11, 6, 13, 8, 3, 26, 5, 19, 6, 5, 12, 13, 0, 2, 1, 12, 13, 1, 8, 4, 17, 32, 7, 13, 17, 36, 23, 18, 5, 4, 14, 0, 1, 13, 2, 10, 5, 2, 2, 6, 1, 9, 16, 5, 2, 5, 4, 17, 20, 3, 16, 21, 5, 4, 14, 11, 13, 12, 6, 9, 4, 1, 8, 10, 7, 10, 11, 3, 3, 10, 15, 4, 1, 5, 10, 13, 0, 18, 0, 5, 4, 9, 4, 16, 2, 5, 15, 8, 1, 44, 7, 29, 72, 25, 15, 6, 14, 7, 46, 49, 18, 25, 26, 35, 14, 5, 9, 46, 29, 11, 24, 28, 43, 3, 8, 30, 29, 24, 3, 3, 41, 14, 25, 54, 5, 33, 12, 11, 1, 10, 17, 26, 23, 10, 2, 6, 48, 23, 0, 10, 11, 8, 22, 33, 64, 69, 68, 79, 12, 25, 3, 9, 12, 36, 13, 7, 2, 21, 6, 60, 9, 21, 14, 4, 5, 1, 6, 18, 51, 22, 14, 46, 21, 55, 42, 7, 30, 3, 13, 11, 36, 15, 8, 27, 22, 0, 7, 23, 12, 12, 22, 13, 8, 1, 11, 2, 5, 33, 32, 10, 6, 0, 5, 21, 1, 16, 39, 26, 9, 44, 13, 0, 10, 9, 37, 10, 15, 14, 23, 40, 22, 27, 24, 27, 48, 45, 16, 4, 4, 21, 13, 22, 7, 36, 39, 32, 8, 4, 39, 30, 0, 13, 6, 31, 20, 16, 5, 13, 24, 0, 33, 2, 14, 2, 11, 4, 16, 5, 11, 0, 14, 4, 3, 6, 15, 14, 5, 1, 36, 41, 6, 18, 47, 30, 25, 18, 0, 0, 7, 17, 35, 1, 6, 7, 6, 7, 37, 30, 20, 19, 4, 4, 9, 11, 10, 0, 7, 0, 12, 1, 1, 0, 25, 15, 7, 12, 9, 8, 0, 3, 16, 11, 4, 20, 17, 6, 3, 8, 19, 2, 1, 12, 4, 2, 3, 5, 4, 7, 4, 17, 2, 24, 15, 14, 11, 48, 62, 31, 12, 1, 13, 7, 15, 36, 15, 3, 11, 46, 23, 15, 28, 14, 51, 0, 28, 1, 7, 13, 44, 18, 11, 12, 39, 6, 70, 29, 2, 31, 54, 9, 13, 23, 29, 14, 22, 42, 73, 22, 68, 79, 92, 55, 51, 16, 16, 32, 25, 18, 11, 3, 40, 17, 20, 14, 4, 35, 1, 14, 9, 27, 56, 19, 2, 69, 18, 44, 3, 3, 44, 5, 33, 22, 5, 0, 37, 26, 8, 6, 21, 33, 15, 30, 28, 3, 27, 4, 14, 27, 58, 31, 16, 11, 11, 24, 36, 57, 44, 18, 21, 5, 8, 5, 33, 18, 16, 1, 2, 34, 12, 63, 72, 65, 29, 74, 19, 2, 2, 3, 10, 3, 31, 64, 25, 10, 16, 11, 8, 7, 9, 17, 12, 17, 16, 0, 29, 2, 4, 0, 10, 25, 38, 51, 8, 40, 9, 10, 17, 53, 8, 18, 37, 52, 11, 12, 15, 23, 32, 9, 10, 7, 26, 23, 14, 0, 13, 0, 21, 24, 26, 17, 10, 11, 11, 4, 10, 2, 7, 3, 26, 15, 9, 14, 24, 20, 19, 24, 21, 16, 21, 11, 11, 12, 42, 61, 42, 9, 3, 8, 13, 11, 27, 20, 2, 9, 5, 8, 2, 0, 21, 18, 27, 11, 1, 48, 21, 0, 17, 20, 16, 13, 2, 8, 5, 26, 27, 12, 7, 11, 14, 8, 2, 9, 9, 26, 6, 9, 0, 11, 17, 12, 12, 4, 11, 4, 15, 22, 11, 34, 21, 7, 1, 20, 17, 4, 9, 7, 26, 1, 3, 7, 3, 3, 24, 25, 4, 1, 8, 1, 4, 9, 0, 18, 15, 12, 1, 15, 4, 35, 0, 32, 12, 11, 42, 41, 4, 3, 1, 36, 13, 2, 6, 3, 1, 5, 12, 23, 4, 9, 18, 39, 28, 7, 22, 9, 27, 10, 28, 29, 16, 1, 2, 11, 26, 4, 33, 4, 19, 30, 20, 9, 9, 14, 6, 9, 0, 13, 10, 7, 7, 22, 15, 16, 3, 13, 6, 10, 4, 21, 17, 2, 24, 14, 4, 2, 3, 2, 16, 35, 6, 20, 0, 19, 6, 16, 11, 1, 4, 10, 21, 8, 23, 4, 7, 0, 36, 19, 0, 31, 26, 4, 7, 2, 13, 26, 12, 19, 24, 0, 7, 8, 3, 5, 12, 11, 10, 17, 4, 3, 16, 10, 23, 19, 14, 18, 3, 16, 7, 13, 6, 1, 7, 30, 7, 21, 12, 7, 19, 5, 16, 8, 9, 27, 28, 10, 29, 26, 6, 2, 8, 13, 2, 43, 10, 36, 31, 6, 26, 4, 17, 13, 24, 5, 8, 6, 6, 9, 2, 2, 8, 10, 21, 14, 13, 12, 6, 7, 13, 6, 6, 21, 14, 3, 6, 4, 3, 15, 28, 2, 9, 19, 26, 12, 17, 17, 8, 1, 18, 5, 2, 3, 6, 6, 19, 12, 3, 8, 18, 7, 13, 11, 18, 0, 8, 7, 15, 8, 9, 0, 8, 3, 10, 49, 9, 7, 3, 22, 11, 0, 5, 11, 10, 27, 22, 6, 5, 5, 26, 23, 2, 12, 2, 1, 6, 9, 11, 4, 14, 15, 10, 2, 5, 5, 20, 26, 1, 10, 19, 0, 14, 10, 31, 8, 11, 10, 24, 17, 6, 14, 41, 20, 15, 28, 32, 3, 15, 28, 16, 10, 2, 35, 18, 9, 24, 27, 0, 6, 9, 8, 21, 4, 12, 4, 6, 1, 9, 8, 25, 16, 2, 15, 20, 4, 11, 4, 14, 15, 8, 12, 4, 17, 39, 46, 5, 1, 20, 13, 2, 15, 16, 9, 4, 0, 5, 12, 1, 3, 1, 10, 13, 6, 8, 9, 5, 1, 4, 2, 4, 2, 5, 4, 2, 5, 6, 8, 75, 1, 3, 6, 7, 1, 8, 9, 8, 2, 7, 10, 15, 10, 3, 0, 4, 3, 2, 8, 1, 2, 1, 13, 12, 1, 4, 0, 15, 0, 22, 12, 11, 3, 16, 25, 1, 20, 11, 4, 3, 7, 20, 9, 6, 11, 3, 8, 6, 2, 19, 16, 11, 4, 12, 9, 5, 6, 8, 21, 26, 17, 14, 13, 14, 4, 15, 5, 18, 11, 10, 11, 12, 9, 1, 8, 10, 7, 6, 9, 0, 9, 16, 5, 18, 7, 7, 17, 14, 8, 40, 8, 43, 16, 10, 12, 28, 45, 22, 19, 9, 46, 4, 28, 41, 24, 46, 75, 2, 44, 39, 32, 19, 10, 24, 43, 42, 2, 29, 38, 7, 47, 1, 10, 8, 34, 10, 4, 18, 1, 5, 23, 17, 1, 4, 7, 36, 45, 30, 28, 15, 13, 5, 15, 44, 35, 7, 30, 29, 4, 20, 25, 14, 24, 12, 11, 14, 2, 11, 9, 58, 27, 27, 26, 0, 17, 10, 2, 7, 1, 37, 51, 48, 0, 2, 2, 17, 51, 92, 9, 31, 0, 15, 48, 0, 14, 14, 11, 1, 8, 3, 2, 33, 46, 14, 5, 7, 5, 2, 11, 3, 1, 6, 9, 2, 0, 2, 3, 2, 7, 22, 12, 9, 99, 19, 7, 7, 8, 0, 5, 2, 12, 7, 3, 8, 3, 10, 13, 2, 11, 32, 15, 7, 1, 8, 2, 12, 13, 1, 2, 6, 7, 4, 5, 4, 12, 0, 1, 9, 15, 16, 6, 17, 16, 13, 16, 6, 11, 8, 19, 0, 10, 12, 13, 0, 13, 13, 8, 1, 10, 25, 4, 4, 5, 12, 2, 1, 3, 23, 28, 3, 9, 16, 5, 8, 2, 23, 16, 9, 10, 6, 19, 10, 11, 14, 12, 5, 6, 5, 23, 2, 16, 15, 10, 15, 2, 20, 27, 14, 3, 22, 21, 8, 14, 3, 17, 24, 3, 5, 12, 15, 1, 14, 15, 8, 4, 11, 7, 24, 13, 9, 0, 20, 7, 6, 13, 14, 8, 1, 0, 17, 16, 3, 5, 12, 5, 13, 16, 10, 1, 23, 16, 17, 10, 8, 2, 1, 7, 38, 33, 1, 7, 14, 3, 12, 13, 15, 12, 14, 17, 6, 23, 16, 26, 0, 13, 5, 2, 5, 8, 13, 42, 31, 3, 0, 18, 4, 19, 6, 9, 1, 14, 3, 5, 6, 6, 4, 16, 15, 5, 5, 1, 10, 13, 4, 7, 26, 9, 4, 7, 22, 13, 3, 3, 7, 4, 7, 12, 29, 24, 14, 2, 33, 24, 15, 40, 23, 16, 1, 2, 0, 7, 9, 4, 15, 26, 8, 33, 24, 14, 29, 10, 2, 1, 5, 2, 10, 7, 5, 1, 14, 13, 1, 14, 9, 18, 15, 9, 20, 15, 20, 19, 4, 6, 3, 1, 6, 9, 4, 4, 13, 8, 1, 7, 12, 1, 2, 12, 0, 1, 2, 14, 19, 0, 2, 0, 3, 3, 16, 19, 1, 2, 10, 27, 24, 0, 1, 2, 2, 1, 7, 8, 2, 5, 0, 1, 14, 25, 20, 8, 7, 7, 15, 16, 10, 4, 15, 0, 1, 1, 3, 28, 1, 43, 3, 26, 33, 20, 11, 26, 13, 6, 22, 10, 3, 2, 1, 6, 4, 23, 14, 0, 7, 5, 1, 9, 6, 8, 2, 2, 20, 9, 13, 3, 14, 4, 5, 10, 13, 24, 7, 23, 26, 19, 4, 0, 22, 35, 0, 16, 6, 13, 9, 22, 1, 3, 10, 3, 11, 14, 7, 2, 2, 20, 19, 4, 13, 12, 0, 2, 1, 1, 9, 9, 40, 11, 5, 2, 15, 2, 16, 15, 14, 2, 13, 10, 2, 11, 5, 6, 0, 0, 10, 13, 2, 10, 17, 22, 11, 16, 29, 10, 13, 20, 23, 15, 34, 10, 25, 10, 11, 10, 8, 2, 3, 3, 11, 32, 37, 5, 4, 16, 6, 1, 16, 2, 9, 2, 3, 9, 7, 12, 14, 0, 23, 9, 6, 18, 26, 0, 17, 4, 12, 15, 4, 6, 5, 9, 5, 8, 3, 4, 2, 4, 5, 4, 6, 15, 0, 9, 12, 7, 6, 10, 5, 10, 22, 25, 7, 10, 1, 10, 15, 6, 5, 15, 14, 13, 26, 9, 15, 0, 32, 23, 4, 5, 14, 27, 38, 25, 29, 48, 0, 5, 8, 11, 1, 15, 32, 1, 3, 12, 6, 21, 5, 5, 26, 2, 8, 27, 18, 17, 18, 2, 7, 0, 13, 14, 13, 28, 21, 8, 4, 11, 3, 7, 8, 4, 10, 6, 43, 1, 20, 9, 18, 18, 1, 19, 1, 6, 8, 16, 4, 9, 9, 6, 28, 33, 31, 30, 0, 11, 8, 25, 24, 2, 2, 22, 13, 2, 6, 7, 2, 2, 5, 8, 1, 45, 4, 3, 11, 16, 2, 11, 11, 2, 12, 3, 1, 5, 8, 4, 2, 21, 14, 0, 3, 1, 10, 1, 7, 4, 4, 8, 15, 14, 2, 0, 7, 4, 3, 3, 2, 8, 5, 4, 0, 2, 7, 2, 10, 13, 12, 6, 11, 4, 0, 1, 7, 2, 6, 11, 16, 0, 0, 1, 9, 8, 0, 3, 1, 4, 14, 13, 2, 1, 6, 5, 4, 13, 20, 3, 1, 0, 21, 16, 2, 2, 1, 0, 6, 17, 10, 7, 0, 14, 13, 4, 3, 16, 15, 10, 1, 6, 3, 3, 5, 14, 0, 1, 8, 7, 6, 11, 15, 34, 23, 2, 1, 6, 10, 2, 11, 8, 1, 0, 4, 7, 4, 6, 3, 2, 0, 8, 19, 4, 4, 9, 16, 13, 3, 4, 0, 1, 10, 12, 19, 4, 5, 4, 10, 15, 2, 16, 9, 4, 3, 4, 11, 20, 7, 1, 0, 12, 17, 4, 3, 8, 2, 2, 5, 0, 3, 10, 16, 0, 27, 4, 2, 12, 17, 5, 2, 2, 10, 11, 0, 16, 0, 19, 1, 6, 5, 3, 18, 13, 4, 0, 4, 4, 2, 9, 12, 5, 0, 8, 1, 6, 6, 13, 4, 7, 8, 1, 12, 21, 2, 4, 0, 11, 22, 7, 4, 4, 3, 12, 17, 10, 1, 5, 3, 8, 11, 3, 4, 12, 5, 8, 0, 4, 2, 19, 4, 4, 12, 1, 5, 7, 8, 4, 9, 10, 7, 8, 0, 0, 1, 8, 17, 10, 9, 0, 10, 1, 1, 9, 8, 1, 0, 1, 18, 19, 16, 7, 5, 3, 16, 7, 10, 17, 4, 0, 7, 4, 4, 20, 19, 12, 9, 4, 3, 6, 3, 5, 1, 20, 19, 8, 6, 3, 17, 16, 0, 15, 2, 12, 8, 9, 7, 20, 15, 12, 6, 7, 4, 6, 15, 10, 2, 5, 3, 12, 6, 7, 16, 18, 34, 37, 4, 38, 39, 16, 66, 54, 7, 27, 6, 38, 35, 9, 5, 32, 29, 36, 41, 42, 1, 9, 9, 8, 3, 3, 9, 22, 1, 12, 5, 7, 3, 18, 31, 10, 4, 22, 3, 39, 48, 39, 30, 11, 11, 15, 46, 41, 20, 21, 36, 9, 31, 0, 17, 6, 42, 11, 46, 55, 6, 31, 38, 29, 10, 40, 23, 52, 29, 2, 43, 58, 43, 1, 0, 10, 43, 4, 16, 7, 26, 0, 25, 28, 33, 8, 40, 13, 2, 14, 13, 1, 2, 5, 10, 8, 25, 56, 57, 16, 4, 4, 12, 2, 1, 27, 20, 25, 39, 0, 22, 33, 32, 1, 8, 0, 13, 11, 34, 13, 8, 1, 3, 3, 3, 4, 2, 13, 6, 15, 15, 8, 14, 3, 2, 26, 5, 58, 29, 3, 28, 33, 18, 3, 6, 3, 5, 5, 1, 8, 6, 19, 12, 4, 22, 7, 13, 0, 11, 9, 22, 3, 22, 6, 17, 5, 24, 6, 3, 9, 8, 10, 13, 29, 34, 3, 27, 6, 20, 1, 3, 1, 18, 37, 44, 12, 19, 3, 10, 9, 5, 0, 18, 13, 10, 9, 12, 31, 1, 10, 35, 0, 22, 9, 3, 17, 0, 4, 13, 3, 7, 3, 1, 13, 18, 6, 16, 2, 1, 3, 15, 4, 9, 6, 3, 1, 16, 14, 11, 4, 34, 39, 20, 21, 2, 7, 10, 0, 3, 8, 11, 8, 28, 17, 17, 6, 28, 27, 10, 7, 1, 8, 21, 8, 5, 10, 9, 14, 5, 22, 45, 30, 3, 5, 28, 25, 9, 38, 26, 33, 2, 5, 6, 1, 21, 86, 31, 2, 19, 6, 17, 27, 34, 27, 1, 24, 9, 18, 5, 7, 2, 3, 2, 18, 13, 37, 17, 42, 20, 0, 5, 11, 22, 14, 7, 14, 23, 3, 18, 47, 32, 9, 12, 25, 22, 5, 12, 23, 7, 3, 22, 21, 16, 14, 7, 1, 38, 0, 19, 20, 56, 79, 12, 22, 1, 28, 49, 7, 9, 54, 33, 19, 38, 33, 21, 12, 13, 30, 33, 28, 13, 20, 35, 26, 4, 29, 36, 3, 13, 13, 0, 10, 9, 15, 10, 10, 16, 9, 24, 11, 12, 22, 45, 10, 11, 16, 10, 19, 5, 14, 5, 0, 15, 12, 15, 10, 16, 17, 0, 8, 13, 46, 31, 50, 35, 2, 15, 19, 42, 19, 20, 29, 12, 6, 32, 22, 12, 6, 33, 8, 18, 23, 0, 18, 19, 32, 4, 2, 8, 5, 59, 10, 26, 7, 8, 15, 5, 8, 6, 47, 8, 20, 13, 1, 42, 19, 38, 31, 9, 1, 20, 31, 58, 39, 8, 14, 21, 4, 10, 9, 13, 20, 4, 19, 17, 1, 16, 12, 25, 6, 7, 13, 9, 30, 35, 24, 9, 11, 36, 23, 2, 1, 16, 15, 39, 13, 5, 15, 12, 3, 0, 19, 24, 1, 0, 10, 2, 13, 8, 4, 15, 10, 3, 3, 16, 7, 16, 7, 8, 13, 4, 7, 18, 13, 2, 2, 6, 5, 13, 7, 9, 3, 6, 8, 0, 6, 14, 6, 3, 7, 12, 1, 7, 4, 15, 2, 22, 21, 18, 25, 2, 2, 4, 7, 5, 12, 9, 6, 0, 13, 8, 5, 12, 9, 10, 3, 4, 1, 4, 1, 18, 19, 0, 8, 3, 8, 2, 9, 10, 13, 10, 12, 14, 3, 2, 4, 11, 12, 10, 11, 1, 10, 13, 5, 6, 4, 9, 4, 4, 5, 1, 6, 6, 13, 13, 6, 21, 1, 24, 15, 8, 7, 36, 13, 22, 21, 6, 14, 0, 9, 0, 3, 14, 15, 21, 30, 7, 0, 3, 11, 16, 15, 1, 16, 5, 12, 17, 7, 16, 2, 0, 3, 0, 27, 20, 9, 2, 17, 4, 9, 12, 16, 5, 9, 5, 7, 18, 0, 2, 9, 8, 12, 2, 14, 52, 16, 6, 33, 28, 2, 6, 15, 30, 8, 31, 12, 10, 14, 1, 10, 1, 21, 18, 17, 12, 8, 0, 10, 7, 3, 3, 7, 14, 3, 18, 17, 0, 4, 1, 39, 14, 30, 15, 57, 2, 2, 14, 21, 17, 0, 4, 38, 27, 2, 13, 14, 9, 18, 7, 12, 13, 20, 1, 6, 3, 3, 1, 5, 19, 14, 0, 15, 43, 6, 5, 6, 6, 7, 9, 18, 2, 8, 26, 23, 20, 11, 9, 4, 10, 11, 12, 6, 13, 16, 1, 5, 17, 8, 12, 1, 8, 17, 20, 5, 1, 4, 9, 3, 26, 7, 5, 7, 2, 10, 9, 13, 6, 16, 15, 26, 0, 15, 13, 8, 6, 4, 8, 9, 1, 1, 2, 20, 13, 23, 13, 8, 7, 4, 3, 12, 1, 10, 2, 1, 5, 5, 0, 9, 10, 7, 6, 16, 17, 20, 7, 11, 1, 9, 14, 18, 9, 9, 0, 18, 6, 19, 16, 3, 14, 3, 17, 8, 9, 2, 1, 6, 0, 15, 22, 9, 4, 9, 1, 0, 4, 8, 7, 8, 17, 9, 20, 6, 7, 5, 11, 8, 4, 4, 13, 0, 18, 17, 2, 0, 7, 8, 8, 11, 2, 6, 4, 6, 5, 10, 12, 6, 6, 4, 7, 3, 6, 13, 10, 12, 5, 5, 1, 8, 4, 7, 3, 7, 6, 12, 3, 0, 0, 11, 16, 12, 11, 2, 0, 9, 19, 8, 3, 3, 6, 13, 16, 11, 10, 0, 5, 16, 9, 0, 7, 5, 16, 35, 11, 3, 12, 12, 11, 2, 5, 6, 6, 2, 5, 3, 0, 6, 9, 9, 0, 20, 3, 3, 2, 9, 6, 3, 14, 13, 10, 3, 4, 1, 0, 1, 10, 0, 11, 6, 7, 8, 23, 18, 6, 2, 5, 1, 8, 1, 13, 1, 2, 8, 9, 16, 8, 5, 7, 12, 3, 10, 5, 1, 5, 2, 2, 4, 44, 6, 0, 2, 3, 4, 162, 68, 43, 45, 3, 10, 58, 83, 54, 35, 134, 67, 120, 149, 12, 21, 2, 19, 80, 39, 121, 214, 105, 33, 44, 23, 70, 73, 16, 62, 73, 38, 7, 57, 10, 60, 8, 13, 26, 103, 60, 86, 117, 45, 46, 43, 13, 148, 67, 17, 52, 1, 48, 17, 17, 55, 78, 6, 25, 88, 13, 3, 49, 37, 66, 32, 15, 64, 107, 51, 22, 28, 29, 44, 31, 37, 47, 68, 62, 69, 20, 19, 18, 45, 72, 22, 65, 64, 1, 84, 61, 61, 68, 49, 29, 76, 135, 38, 112, 17, 113, 50, 32, 26, 81, 120, 105, 106, 29, 51, 34, 9, 9, 0, 48, 27, 71, 66, 21, 19, 62, 45, 16, 37, 38, 22, 24, 17, 3, 47, 14, 57, 32, 58, 8, 103, 23, 78, 2, 83, 40, 54, 1, 25, 15, 38, 1, 6, 40, 81, 8, 83, 39, 16, 19, 60, 28, 180, 81, 3, 84, 117, 21, 80, 81, 46, 32, 10, 63, 0, 106, 135, 94, 91, 20, 76, 20, 17, 79, 60, 65, 120, 6, 19, 46, 9, 39, 42, 11, 2, 25, 54, 21, 24, 57, 32, 0, 12, 29, 18, 10, 17, 13, 4, 27, 11, 14, 10, 25, 11, 34, 9, 6, 13, 20, 7, 10, 15, 5, 17, 28, 11, 8, 19, 6, 12, 19, 14, 13, 17, 32, 4, 15, 19, 40, 23, 46, 2, 37, 21, 40, 43, 50, 9, 25, 32, 29, 40, 13, 9, 9, 42, 9, 15, 0, 0, 9, 23, 26, 2, 5, 6, 2, 11, 18, 3, 35, 26, 6, 22, 25, 5, 20, 13, 6, 41, 16, 18, 27, 8, 9, 12, 8, 1, 47, 31, 20, 13, 0, 10, 7, 17, 6, 17, 8, 1, 8, 17, 4, 8, 6, 6, 29, 12, 0, 14, 21, 6, 3, 11, 26, 27, 14, 2, 6, 11, 8, 10, 1, 5, 32, 22, 31, 29, 30, 13, 4, 7, 28, 9, 5, 17, 40, 31, 36, 19, 16, 15, 15, 28, 27, 3, 16, 2, 5, 17, 5, 8, 10, 4, 20, 6, 31, 15, 4, 1, 24, 3, 29, 25, 54, 33, 14, 19, 4, 8, 7, 16, 86, 61, 96, 59, 11, 46, 21, 10, 80, 47, 43, 87, 28, 76, 95, 10, 10, 31, 58, 6, 90, 12, 51, 33, 1, 0, 24, 18, 29, 11, 23, 37, 18, 5, 49, 42, 102, 51, 49, 34, 25, 16, 95, 18, 10, 33, 14, 5, 16, 2, 6, 4, 41, 22, 29, 14, 1, 10, 20, 7, 8, 33, 10, 9, 11, 34, 20, 29, 2, 5, 6, 18, 17, 4, 11, 5, 10, 11, 24, 23, 14, 5, 6, 25, 28, 13, 8, 14, 15, 6, 9, 7, 6, 8, 13, 14, 2, 29, 22, 10, 1, 32, 1, 23, 27, 40, 7, 55, 26, 16, 7, 6, 8, 23, 50, 23, 17, 12, 26, 23, 9, 20, 13, 12, 22, 19, 10, 0, 25, 17, 4, 100, 122, 61, 87, 56, 50, 38, 11, 8, 13, 7, 24, 65, 90, 13, 6, 2, 63, 1, 17, 30, 18, 11, 7, 3, 12, 28, 35, 62, 61, 1, 76, 65, 5, 4, 18, 19, 7, 16, 3, 1, 26, 51, 32, 1, 22, 5, 8, 27, 14, 19, 10, 120, 117, 4, 7, 13, 4, 8, 27, 192, 153, 27, 17, 44, 3, 33, 4, 10, 4, 0, 6, 15, 64, 87, 20, 52, 46, 19, 14, 73, 34, 20, 105, 25, 22, 18, 0, 53, 28, 21, 12, 1, 15, 13, 44, 21, 26, 57, 38, 18, 17, 9, 2, 16, 25, 28, 2, 40, 47, 10, 9, 2, 58, 9, 2, 27, 11, 22, 8, 112, 50, 23, 35, 7, 19, 42, 36, 10, 17, 45, 32, 30, 13, 12, 21, 19, 2, 4, 128, 44, 8, 159, 4, 102, 117, 96, 93, 132, 32, 25, 14, 12, 35, 22, 61, 44, 39, 20, 53, 22, 35, 98, 87, 78, 18, 0, 12, 1, 9, 39, 30, 21, 38, 1, 41, 34, 17, 12, 17, 15, 23, 21, 18, 55, 9, 52, 131, 74, 1, 14, 15, 21, 60, 39, 42, 51, 30, 8, 7, 27, 12, 34, 4, 41, 7, 94, 61, 37, 0, 2, 28, 65, 40, 6, 39, 36, 0, 3, 2, 27, 3, 4, 23, 4, 6, 10, 12, 47, 16, 4, 6, 22, 1, 5, 23, 29, 26, 14, 6, 18, 11, 4, 13, 43, 30, 28, 6, 11, 12, 9, 51, 32, 22, 11, 6, 12, 17, 17, 48, 9, 15, 17, 10, 8, 16, 9, 4, 12, 7, 4, 6, 15, 12, 47, 24, 4, 16, 10, 17, 1, 26, 49, 1, 8, 6, 15, 38, 2, 35, 24, 26, 21, 0, 22, 11, 15, 14, 36, 23, 12, 3, 17, 19, 60, 51, 20, 42, 9, 49, 12, 24, 15, 47, 62, 8, 11, 7, 3, 49, 52, 2, 23, 26, 6, 25, 22, 27, 16, 4, 2, 11, 21, 30, 1, 1, 12, 0, 4, 8, 16, 3, 1, 3, 23, 24, 3, 2, 7, 14, 15, 20, 7, 2, 11, 15, 24, 11, 13, 38, 33, 1, 20, 0, 8, 19, 6, 10, 2, 7, 8, 7, 4, 3, 10, 5, 10, 5, 19, 4, 24, 15, 15, 20, 5, 5, 7, 2, 22, 7, 25, 0, 32, 35, 12, 22, 1, 33, 36, 35, 18, 8, 0, 9, 0, 23, 44, 1, 14, 15, 57, 20, 28, 5, 10, 9, 14, 21, 1, 18, 16, 13, 17, 1, 14, 14, 11, 13, 10, 12, 21, 14, 3, 10, 11, 10, 8, 6, 27, 20, 2, 17, 25, 30, 35, 50, 39, 1, 24, 16, 15, 5, 31, 46, 1, 3, 16, 53, 28, 4, 8, 55, 22, 30, 11, 19, 22, 16, 7, 11, 12, 29, 7, 32, 1, 26, 31, 32, 0, 3, 12, 3, 11, 7, 7, 0, 7, 16, 18, 2, 11, 1, 17, 10, 6, 28, 33, 42, 11, 27, 2, 1, 34, 14, 39, 4, 3, 15, 38, 0, 1, 17, 18, 17, 17, 22, 1, 11, 2, 10, 15, 8, 12, 21, 18, 19, 22, 6, 6, 11, 9, 6, 9, 7, 20, 17, 12, 0, 5, 17, 28, 17, 8, 12, 0, 9, 16, 31, 0, 28, 9, 7, 24, 7, 2, 10, 13, 8, 4, 13, 26, 37, 34, 19, 14, 3, 0, 9, 37, 58, 11, 3, 5, 13, 6, 6, 5, 11, 28, 0, 25, 26, 0, 15, 6, 9, 4, 27, 20, 16, 12, 1, 12, 17, 3, 13, 0, 28, 25, 12, 9, 1, 24, 23, 10, 0, 9, 20, 11, 9, 28, 21, 7, 1, 32, 1, 13, 2, 28, 19, 2, 7, 31, 14, 4, 3, 3, 1, 2, 19, 38, 2, 25, 11, 26, 3, 24, 23, 4, 16, 1, 0, 6, 3, 13, 20, 21, 10, 5, 2, 13, 2, 0, 8, 17, 12, 6, 24, 2, 37, 2, 12, 7, 20, 3, 4, 1, 3, 33, 48, 27, 4, 22, 0, 7, 33, 12, 3, 1, 18, 6, 29, 1, 8, 24, 5, 6, 5, 10, 4, 35, 30, 8, 47, 12, 40, 13, 3, 3, 2, 4, 3, 19, 1, 4, 30, 13, 16, 15, 26, 1, 17, 2, 11, 6, 15, 4, 12, 6, 4, 17, 7, 10, 4, 4, 16, 33, 4, 6, 3, 14, 11, 11, 4, 14, 15, 14, 5, 1, 12, 9, 15, 0, 13, 1, 10, 30, 21, 2, 5, 14, 6, 0, 49, 76, 19, 2, 7, 11, 10, 0, 18, 7, 15, 14, 5, 29, 3, 20, 8, 23, 18, 9, 3, 4, 4, 19, 20, 31, 10, 8, 18, 3, 18, 27, 24, 17, 4, 5, 4, 32, 35, 14, 10, 14, 19, 6, 4, 15, 7, 8, 20, 6, 29, 8, 33, 26, 10, 13, 0, 13, 14, 35, 60, 53, 34, 18, 37, 38, 15, 2, 27, 13, 34, 12, 1, 27, 44, 15, 14, 25, 13, 26, 18, 5, 43, 19, 56, 7, 20, 65, 40, 3, 3, 14, 11, 12, 8, 13, 15, 20, 15, 15, 30, 2, 16, 19, 22, 10, 3, 9, 12, 3, 2, 4, 27, 22, 4, 8, 19, 15, 18, 7, 23, 0, 30, 29, 26, 0, 21, 20, 13, 8, 20, 13, 20, 19, 20, 49, 22, 3, 6, 6, 11, 2, 18, 21, 14, 12, 27, 0, 2, 7, 15, 9, 12, 28, 2, 139, 162, 21, 11, 26, 23, 18, 15, 14, 9, 24, 29, 12, 6, 17, 16, 23, 16, 4, 2, 7, 13, 7, 26, 14, 13, 13, 30, 0, 15, 4, 19, 22, 5, 6, 12, 11, 3, 3, 2, 0, 2, 18, 4, 13, 2, 31, 18, 9, 20, 0, 10, 43, 34, 15, 1, 8, 26, 14, 41, 8, 11, 36, 37, 6, 14, 20, 9, 25, 16, 5, 15, 3, 32, 19, 2, 8, 6, 7, 21, 24, 15, 6, 24, 13, 19, 4, 6, 22, 19, 5, 0, 16, 4, 21, 7, 6, 19, 60, 23, 2, 20, 35, 32, 17, 5, 12, 27, 8, 6, 2, 18, 13, 12, 1, 33, 11, 26, 5, 19, 32, 0, 37, 6, 22, 2, 18, 30, 55, 28, 1, 0, 12, 13, 5, 13, 18, 2, 27, 2, 2, 8, 16, 33, 16, 21, 22, 21, 64, 3, 15, 59, 34, 13, 20, 4, 0, 3, 10, 1, 22, 21, 8, 11, 12, 16, 3, 11, 1, 5, 28, 43, 9, 34, 2, 22, 11, 2, 47, 46, 15, 31, 28, 28, 3, 29, 13, 48, 35, 22, 13, 22, 29, 18, 22, 31, 13, 20, 4, 28, 5, 21, 4, 21, 12, 6, 0, 25, 24, 5, 5, 12, 8, 17, 26, 21, 8, 22, 33, 21, 21, 46, 8, 3, 17, 7, 12, 2, 10, 11, 1, 4, 16, 27, 26, 10, 17, 31, 44, 8, 35, 6, 10, 5, 7, 0, 10, 4, 13, 9, 20, 13, 6, 16, 9, 8, 3, 16, 19, 18, 11, 32, 29, 3, 12, 23, 8, 0, 21, 16, 1, 8, 16, 8, 31, 23, 58, 15, 6, 15, 1, 3, 15, 6, 36, 21, 22, 27, 14, 5, 12, 6, 27, 0, 26, 8, 1, 2, 33, 20, 6, 10, 1, 17, 9, 13, 10, 50, 57, 16, 7, 8, 4, 26, 37, 32, 45, 0, 14, 0, 28, 11, 1, 5, 0, 2, 14, 25, 2, 26, 11, 37, 22, 4, 4, 20, 29, 17, 48, 17, 20, 17, 3, 14, 3, 3, 32, 35, 26, 33, 18, 27, 42, 0, 7, 19, 13, 10, 0, 18, 4, 29, 36, 4, 13, 1, 12, 7, 4, 19, 20, 10, 10, 11, 0, 27, 28, 5, 21, 9, 14, 19, 6, 7, 8, 5, 38, 22, 15, 8, 27, 26, 13, 1, 6, 8, 9, 15, 12, 2, 1, 2, 23, 42, 7, 13, 5, 21, 14, 21, 12, 21, 34, 40, 4, 51, 1, 28, 4, 3, 41, 24, 14, 0, 33, 16, 2, 32, 13, 17, 26, 11, 2, 9, 7, 11, 6, 24, 23, 34, 19, 12, 11, 14, 33, 4, 24, 20, 6, 49, 1, 2, 13, 14, 6, 6, 3, 9, 6, 23, 30, 3, 11, 18, 13, 20, 12, 19, 2, 3, 16, 7, 43, 32, 20, 7, 10, 23, 1, 24, 28, 53, 2, 24, 33, 30, 29, 34, 1, 4, 7, 13, 8, 14, 1, 5, 6, 1, 9, 9, 34, 5, 3, 19, 6, 18, 3, 24, 43, 8, 4, 2, 8, 11, 1, 3, 23, 36, 0, 13, 26, 21, 4, 6, 4, 5, 24, 29, 17, 62, 55, 14, 22, 31, 14, 22, 25, 7, 1, 17, 48, 12, 37, 34, 33, 0, 1, 12, 8, 17, 12, 27, 42, 14, 9, 4, 7, 33, 1, 2, 28, 17, 1, 43, 44, 9, 21, 28, 24, 19, 7, 34, 6, 17, 1, 47, 66, 3, 13, 6, 0, 23, 54, 75, 24, 16, 10, 37, 34, 25, 5, 6, 12, 18, 4, 41, 46, 0, 6, 11, 2, 2, 10, 9, 2, 21, 6, 0, 25, 10, 40, 19, 29, 42, 29, 7, 32, 37, 16, 3, 10, 1, 9, 14, 24, 13, 13, 4, 23, 38, 29, 28, 6, 13, 17, 5, 26, 19, 26, 20, 21, 5, 13, 2, 5, 10, 14, 37, 16, 31, 60, 8, 21, 8, 29, 26, 0, 4, 9, 7, 22, 9, 2, 8, 9, 4, 35, 30, 14, 33, 24, 5, 1, 16, 21, 24, 27, 0, 5, 4, 18, 6, 1, 3, 7, 17, 22, 25, 1, 24, 4, 2, 5, 20, 17, 19, 13, 32, 47, 34, 22, 25, 8, 2, 15, 4, 8, 3, 16, 43, 38, 11, 10, 10, 0, 10, 29, 19, 7, 20, 28, 7, 21, 30, 2, 1, 21, 8, 36, 9, 5, 9, 18, 12, 21, 1, 27, 4, 30, 7, 17, 10, 35, 22, 44, 0, 13, 13, 10, 17, 40, 29, 10, 27, 20, 7, 7, 42, 25, 39, 6, 14, 16, 0, 19, 32, 3, 3, 1, 18, 13, 12, 2, 1, 4, 5, 18, 31, 0, 9, 30, 0, 27, 13, 16, 26, 23, 22, 0, 37, 32, 16, 3, 9, 12, 25, 22, 3, 27, 30, 6, 5, 3, 23, 8, 26, 12, 1, 5, 15, 11, 16, 29, 20, 7, 28, 19, 4, 59, 30, 46, 4, 45, 8, 12, 21, 2, 4, 10, 8, 9, 6, 18, 11, 4, 4, 14, 43, 18, 5, 16, 34, 27, 25, 36, 31, 34, 11, 19, 18, 5, 13, 22, 31, 52, 45, 30, 25, 19, 6, 34, 17, 16, 0, 10, 27, 0, 8, 10, 11, 0, 5, 10, 6, 49, 54, 35, 46, 19, 3, 19, 30, 2, 7, 5, 4, 0, 0, 23, 16, 18, 5, 29, 30, 7, 19, 10, 32, 7, 23, 6, 12, 25, 16, 4, 8, 27, 28, 6, 33, 3, 22, 1, 28, 5, 6, 31, 40, 25, 2, 8, 4, 3, 15, 6, 21, 40, 39, 48, 35, 23, 20, 6, 24, 5, 17, 26, 6, 47, 8, 11, 22, 20, 17, 8, 29, 32, 8, 8, 41, 11, 38, 2, 33, 12, 10, 16, 33, 24, 7, 15, 12, 10, 25, 20, 6, 21, 28, 31, 34, 1, 13, 18, 39, 36, 21, 34, 2, 41, 13, 62, 23, 18, 15, 1, 6, 11, 10, 37, 28, 23, 38, 5, 10, 11, 4, 11, 14, 25, 3, 24, 1, 4, 13, 6, 22, 47, 34, 14, 17, 2, 12, 19, 19, 36, 9, 5, 7, 5, 14, 14, 21, 0, 8, 5, 19, 30, 17, 22, 0, 11, 2, 3, 4, 12, 6, 8, 75, 60, 4, 24, 11, 33, 18, 8, 5, 37, 44, 13, 18, 35, 30, 0, 5, 15, 22, 6, 3, 13, 18, 23, 26, 2, 51, 24, 3, 32, 21, 16, 21, 14, 13, 14, 51, 44, 22, 25, 6, 2, 26, 19, 11, 9, 12, 12, 23, 24, 2, 5, 14, 23, 1, 16, 13, 10, 12, 31, 6, 18, 39, 50, 13, 29, 26, 24, 16, 35, 18, 17, 6, 7, 20, 11, 2, 7, 41, 40, 4, 28, 23, 1, 13, 12, 5, 3, 0, 16, 21, 16, 7, 2, 0, 18, 31, 16, 9, 2, 19, 10, 18, 8, 3, 4, 1, 7, 2, 13, 24, 9, 27, 30, 15, 6, 7, 14, 28, 41, 1, 10, 7, 16, 28, 25, 25, 36, 19, 27, 20, 9, 44, 0, 39, 4, 8, 2, 27, 32, 2, 22, 19, 15, 28, 21, 24, 11, 31, 12, 18, 14, 33, 17, 36, 10, 9, 11, 30, 25, 11, 20, 2, 2, 26, 29, 13, 12, 3, 24, 8, 21, 6, 7, 20, 11, 15, 30, 33, 5, 42, 7, 3, 7, 4, 9, 23, 0, 8, 5, 36, 19, 14, 1, 2, 7, 12, 11, 14, 27, 46, 31, 26, 3, 14, 59, 32, 9, 20, 15, 24, 17, 23, 6, 25, 46, 9, 43, 78, 27, 4, 25, 28, 19, 10, 1, 9, 3, 24, 24, 27, 5, 9, 8, 8, 2, 12, 23, 36, 41, 20, 5, 12, 2, 41, 4, 22, 1, 7, 28, 19, 5, 2, 34, 21, 17, 14, 18, 25, 2, 1, 3, 27, 48, 19, 4, 16, 5, 17, 6, 23, 16, 4, 39, 0, 38, 14, 5, 8, 7, 15, 19, 10, 17, 34, 34, 16, 39, 2, 20, 31, 16, 2, 6, 17, 7, 10, 7, 24, 0, 1, 7, 14, 12, 37, 15, 4, 10, 32, 1, 0, 2, 33, 49, 38, 3, 7, 12, 0, 14, 15, 34, 17, 16, 35, 22, 6, 0, 14, 13, 19, 4, 13, 24, 9, 16, 7, 19, 13, 30, 27, 7, 26, 0, 5, 2, 8, 19, 16, 2, 14, 17, 28, 23, 10, 29, 22, 31, 22, 16, 1, 22, 51, 32, 2, 0, 10, 19, 5, 38, 31, 14, 3, 1, 25, 20, 7, 4, 18, 37, 5, 36, 41, 32, 8, 13, 10, 10, 39, 26, 0, 8, 3, 2, 2, 26, 15, 23, 16, 9, 1, 0, 25, 46, 6, 17, 25, 0, 6, 28, 27, 6, 8, 77, 75, 51, 7, 68, 55, 4, 5, 11, 16, 31, 50, 29, 32, 31, 50, 7, 53, 20, 24, 27, 33, 36, 21, 32, 7, 37, 14, 28, 11, 22, 61, 36, 0, 16, 20, 11, 49, 16, 12, 44, 23, 35, 4, 3, 20, 8, 10, 21, 0, 2, 24, 17, 24, 21, 6, 14, 11, 5, 9, 13, 6, 2, 9, 14, 19, 2, 20, 10, 11, 5, 20, 23, 20, 11, 6, 12, 7, 3, 5, 2, 3, 20, 17, 6, 15, 2, 1, 2, 14, 13, 10, 8, 5, 2, 7, 7, 12, 2, 5, 10, 12, 15, 20, 17, 20, 6, 23, 1, 24, 54, 1, 13, 31, 76, 25, 1, 78, 45, 170, 10, 233, 0, 26, 1, 71, 54, 19, 126, 169, 13, 138, 18, 113, 96, 103, 62, 40, 53, 32, 34, 129, 162, 145, 144, 24, 31, 31, 95, 26, 49, 19, 34, 2, 26, 40, 81, 2, 49, 3, 19, 45, 9, 80, 40, 3, 13, 105, 112, 41, 14, 35, 4, 22, 29, 90, 79, 54, 23, 16, 63, 8, 64, 63, 66, 13, 113, 86, 21, 3, 106, 67, 59, 32, 78, 53, 75, 12, 1, 82, 27, 44, 19, 5, 71, 86, 99, 60, 37, 60, 46, 83, 38, 50, 97, 30, 65, 90, 25, 24, 16, 63, 40, 13, 29, 142, 13, 45, 69, 9, 12, 56, 35, 110, 3, 4, 16, 3, 149, 72, 54, 6, 0, 12, 23, 10, 3, 30, 31, 67, 18, 52, 5, 15, 8, 4, 3, 1, 7, 12, 69, 51, 56, 19, 34, 9, 24, 11, 19, 48, 23, 37, 16, 37, 16, 4, 15, 16, 7, 3, 31, 32, 18, 10, 1, 12, 23, 24, 57, 28, 2, 9, 7, 18, 63, 59, 26, 16, 0, 31, 20, 5, 19, 1, 3, 4, 6, 0, 19, 1, 36, 29, 5, 8, 1, 19, 24, 31, 14, 9, 24, 31, 30, 36, 59, 136, 19, 47, 0, 23, 10, 49, 98, 26, 19, 75, 80, 55, 42, 55, 70, 47, 43, 44, 39, 62, 33, 104, 75, 88, 84, 175, 102, 125, 84, 44, 131, 12, 16, 36, 108, 157, 3, 162, 137, 10, 17, 74, 125, 68, 37, 26, 0, 3, 3, 49, 78, 16, 94, 19, 8, 0, 4, 17, 16, 97, 23, 4, 22, 31, 2, 18, 2, 31, 9, 2, 14, 4, 6, 27, 15, 14, 24, 3, 19, 2, 15, 3, 30, 19, 8, 7, 20, 11, 4, 10, 7, 24, 15, 32, 4, 0, 35, 0, 13, 4, 8, 4, 19, 4, 14, 19, 8, 29, 32, 29, 40, 1, 11, 5, 0, 5, 2, 0, 26, 17, 2, 4, 37, 20, 29, 18, 23, 8, 22, 0, 17, 8, 8, 11, 8, 2, 7, 10, 0, 5, 7, 16, 35, 32, 4, 17, 10, 4, 4, 5, 15, 7, 1, 5, 0, 3, 0, 3, 0, 2, 3, 5, 8, 17, 1, 0, 8, 0, 4, 12, 15, 13, 16, 9, 9, 12, 1, 5, 2, 10, 11, 2, 12, 11, 5, 11, 20, 0, 7, 14, 25, 16, 0, 5, 14, 13, 1, 3, 8, 10, 13, 12, 6, 16, 0, 2, 15, 16, 3, 2, 8, 23, 8, 3, 12, 1, 15, 26, 29, 20, 0, 9, 12, 1, 4, 13, 6, 14, 6, 21, 15, 16, 20, 27, 14, 2, 3, 4, 4, 4, 41, 14, 48, 19, 26, 49, 24, 19, 10, 1, 3, 20, 13, 5, 15, 24, 27, 24, 13, 2, 2, 10, 9, 28, 31, 7, 10, 5, 8, 1, 3, 6, 9, 10, 27, 36, 46, 10, 9, 9, 23, 4, 42, 6, 58, 91, 2, 4, 6, 17, 1, 62, 57, 50, 53, 4, 2, 21, 46, 58, 91, 26, 70, 83, 42, 18, 63, 46, 45, 28, 8, 32, 69, 40, 1, 13, 20, 41, 38, 2, 20, 28, 69, 3, 14, 1, 5, 0, 24, 15, 12, 24, 3, 17, 16, 27, 25, 44, 0, 5, 33, 10, 22, 25, 17, 26, 9, 27, 24, 7, 0, 14, 17, 20, 31, 4, 46, 33, 6, 3, 15, 4, 9, 0, 8, 1, 0, 8, 1, 3, 13, 22, 11, 76, 61, 15, 18, 3, 10, 14, 58, 14, 15, 16, 0, 7, 2, 39, 23, 24, 25, 7, 8, 6, 5, 5, 6, 16, 1, 1, 5, 1, 24, 5, 15, 12, 17, 8, 21, 10, 3, 13, 6, 3, 10, 4, 6, 1, 19, 22, 9, 5, 4, 14, 7, 4, 12, 9, 6, 15, 10, 4, 27, 32, 15, 8, 0, 5, 1, 8, 4, 3, 3, 6, 18, 25, 10, 23, 22, 15, 14, 16, 0, 15, 3, 6, 5, 5, 17, 24, 1, 6, 3, 20, 25, 18, 0, 15, 14, 13, 20, 27, 6, 12, 19, 14, 52, 1, 35, 18, 6, 17, 6, 13, 70, 39, 21, 24, 3, 18, 17, 19, 38, 7, 33, 22, 32, 41, 24, 9, 34, 15, 4, 18, 10, 86, 26, 38, 73, 107, 15, 7, 4, 2, 6, 8, 4, 10, 57, 52, 3, 9, 22, 33, 56, 180, 3, 43, 64, 103, 33, 118, 26, 49, 28, 25, 63, 74, 7, 69, 18, 68, 9, 54, 37, 3, 25, 9, 37, 22, 11, 11, 49, 65, 36, 35, 5, 11, 72, 4, 6, 55, 25, 16, 59, 41, 13, 50, 6, 17, 5, 11, 19, 34, 13, 9, 4, 6, 2, 16, 14, 9, 22, 23, 0, 9, 21, 40, 31, 32, 15, 30, 21, 8, 27, 2, 33, 50, 0, 0, 2, 32, 33, 9, 6, 4, 0, 37, 44, 15, 6, 2, 0, 9, 10, 11, 12, 2, 0, 3, 8, 0, 6, 13, 5, 14, 17, 30, 6, 39, 16, 1, 15, 7, 6, 8, 13, 12, 0, 7, 8, 10, 25, 19, 12, 7, 18, 5, 7, 2, 2, 10, 11, 6, 4, 2, 7, 9, 3, 18, 4, 19, 8, 2, 0, 0, 2, 4, 1, 1, 0, 2, 6, 1, 14, 21, 16, 5, 11, 8, 18, 25, 10, 0, 0, 7, 0, 18, 15, 6, 2, 16, 36, 47, 14, 1, 3, 3, 25, 18, 6, 13, 62, 35, 14, 19, 2, 8, 24, 13, 22, 47, 34, 1, 23, 2, 38, 23, 40, 47, 17, 52, 21, 10, 2, 20, 11, 39, 18, 17, 36, 11, 6, 3, 29, 30, 38, 53, 16, 25, 22, 24, 41, 24, 8, 3, 17, 8, 8, 6, 33, 34, 3, 28, 19, 16, 33, 12, 11, 14, 3, 17, 5, 36, 57, 60, 21, 0, 21, 3, 54, 11, 31, 28, 13, 22, 20, 71, 44, 8, 23, 14, 9, 1, 11, 10, 11, 24, 4, 24, 43, 8, 18, 25, 26, 23, 11, 10, 94, 42, 19, 28, 21, 8, 16, 41, 14, 56, 39, 0, 19, 16, 13, 32, 1, 17, 0, 59, 31, 8, 4, 0, 3, 7, 2, 0, 14, 9, 6, 7, 5, 14, 23, 6, 4, 13, 10, 30, 9, 7, 7, 1, 7, 16, 8, 25, 18, 0, 10, 5, 20, 20, 17, 12, 0, 9, 10, 13, 18, 23, 12, 7, 4, 13, 12, 24, 9, 11, 8, 9, 10, 5, 2, 1, 2, 0, 8, 19, 8, 0, 8, 13, 40, 11, 2, 17, 26, 22, 4, 25, 14, 7, 16, 25, 14, 18, 39, 7, 34, 7, 1, 9, 16, 28, 3, 7, 10, 7, 3, 2, 0, 21, 10, 11, 20, 5, 9, 0, 23, 0, 6, 2, 30, 19, 0, 5, 12, 7, 5, 20, 12, 19, 3, 1, 31, 28, 15, 0, 20, 27, 53, 12, 10, 11, 12, 1, 5, 6, 0, 5, 7, 14, 9, 0, 5, 18, 11, 14, 7, 9, 31, 2, 4, 15, 44, 1, 11, 18, 9, 6, 4, 6, 7, 2, 25, 10, 9, 4, 1, 10, 0, 10, 0, 13, 0, 14, 17, 10, 13, 12, 3, 6, 3, 6, 2, 5, 0, 0, 18, 21, 9, 2, 24, 3, 7, 7, 1, 16, 0, 15, 6, 4, 3, 0, 7, 1, 10, 0, 6, 11, 6, 6, 0, 17, 24, 7, 10, 9, 3, 12, 11, 16, 21, 2, 2, 10, 3, 8, 18, 25, 5, 0, 4, 4, 3, 4, 9, 3, 2, 0, 18, 9, 20, 33, 20, 13, 14, 2, 16, 21, 3, 1, 8, 2, 6, 11, 6, 15, 18, 11, 2, 1, 2, 6, 0, 7, 16, 4, 17, 12, 9, 4, 11, 1, 4, 2, 16, 2, 15, 2, 2, 7, 12, 17, 22, 11, 8, 2, 9, 0, 12, 0, 9, 1, 18, 5, 8, 7, 2, 0, 13, 14, 13, 2, 14, 13, 24, 19, 5, 4, 5, 4, 14, 3, 1, 17, 0, 8, 6, 1, 5, 2, 6, 2, 1, 0, 1, 9, 8, 10, 1, 7, 3, 10, 0, 7, 7, 20, 19, 2, 12, 10, 7, 6, 2, 6, 15, 1, 1, 6, 3, 14, 9, 0, 7, 6, 5, 2, 6, 22, 17, 7, 20, 27, 8, 3, 1, 8, 21, 6, 7, 2, 8, 18, 13, 1, 1, 5, 16, 12, 0, 1, 13, 2, 2, 6, 1, 10, 19, 6, 3, 6, 12, 13, 2, 4, 7, 16, 5, 11, 8, 10, 7, 2, 15, 42, 45, 12, 22, 9, 7, 5, 8, 10, 0, 2, 17, 14, 23, 26, 13, 8, 4, 18, 21, 13, 0, 2, 25, 2, 24, 4, 27, 6, 15, 26, 13, 2, 12, 5, 14, 1, 0, 18, 10, 13, 3, 3, 8, 12, 3, 8, 19, 4, 8, 8, 7, 7, 11, 1, 2, 0, 0, 14, 5, 0, 7, 18, 9, 0, 3, 4, 8, 11, 14, 11, 2, 4, 0, 5, 7, 4, 0, 4, 0, 10, 15, 8, 16, 4, 3, 21, 12, 4, 15, 6, 3, 14, 17, 29, 7, 2, 12, 4, 11, 0, 15, 1, 6, 22, 7, 7, 6, 4, 3, 1, 1, 6, 8, 5, 7, 10, 3, 12, 21, 1, 2, 6, 3, 1, 2, 11, 16, 7, 6, 9, 8, 5, 28, 25, 0, 0, 6, 5, 9, 22, 9, 2, 10, 13, 12, 6, 15, 0, 9, 12, 16, 3, 0, 9, 5, 10, 3, 2, 8, 5, 12, 11, 5, 1, 18, 9, 9, 8, 14, 7, 2, 2, 29, 22, 7, 16, 7, 5, 6, 0, 6, 11, 16, 9, 7, 0, 1, 6, 8, 9, 2, 12, 11, 10, 2, 8, 23, 8, 15, 20, 11, 2, 18, 15, 3, 6, 5, 8, 10, 13, 2, 0, 3, 4, 17, 4, 12, 3, 12, 11, 6, 12, 8, 3, 14, 0, 19, 0, 22, 21, 5, 4, 172, 78, 19, 32, 11, 7, 11, 52, 8, 65, 34, 8, 41, 52, 6, 15, 15, 24, 15, 24, 41, 34, 8, 23, 9, 20, 9, 0, 10, 13, 16, 7, 5, 2, 19, 32, 17, 14, 1, 4, 12, 57, 15, 4, 5, 26, 15, 16, 45, 2, 20, 95, 22, 5, 29, 19, 0, 19, 6, 6, 7, 20, 0, 31, 13, 31, 3, 2, 8, 5, 0, 4, 2, 0, 2, 21, 26, 27, 16, 13, 14, 12, 11, 18, 11, 5, 0, 5, 3, 0, 2, 158, 30, 148, 183, 138, 14, 40, 23, 63, 38, 13, 29, 36, 33, 12, 28, 11, 12, 17, 11, 24, 9, 41, 50, 41, 12, 40, 15, 5, 8, 1, 32, 37, 8, 16, 16, 79, 54, 43, 46, 31, 9, 32, 4, 14, 2, 13, 41, 56, 23, 20, 2, 7, 5, 6, 23, 48, 31, 22, 13, 95, 33, 2, 50, 55, 16, 26, 35, 10, 27, 20, 35, 7, 22, 27, 43, 28, 16, 38, 21, 3, 16, 2, 11, 30, 13, 27, 38, 19, 15, 22, 26, 23, 8, 5, 1, 3, 2, 10, 21, 29, 19, 44, 2, 14, 21, 18, 9, 2, 8, 54, 7, 29, 8, 35, 28, 15, 38, 51, 6, 47, 56, 4, 3, 1, 20, 25, 11, 16, 12, 33, 4, 29, 46, 7, 26, 2, 3, 11, 24, 37, 1, 10, 12, 17, 3, 14, 11, 11, 13, 42, 23, 8, 8, 56, 35, 41, 8, 36, 27, 45, 0, 70, 5, 4, 35, 44, 18, 15, 9, 4, 27, 12, 8, 3, 33, 19, 0, 12, 13, 44, 16, 21, 8, 2, 3, 1, 13, 10, 21, 10, 26, 4, 61, 6, 56, 6, 49, 34, 45, 19, 29, 22, 29, 40, 31, 18, 0, 6, 25, 8, 13, 52, 29, 20, 19, 20, 11, 5, 5, 1, 17, 38, 10, 42, 7, 8, 12, 2, 27, 8, 24, 9, 2, 7, 7, 14, 5, 3, 2, 3, 10, 8, 29, 21, 43, 4, 1, 8, 11, 4, 10, 10, 5, 1, 5, 15, 2, 6, 8, 2, 2, 0, 5, 26, 9, 11, 0, 8, 5, 1, 1, 17, 24, 1, 11, 14, 5, 6, 7, 1, 1, 6, 19, 10, 6, 13, 0, 6, 1, 28, 11, 16, 7, 6, 21, 3, 12, 1, 15, 6, 2, 4, 16, 3, 27, 24, 5, 10, 5, 5, 8, 1, 11, 7, 16, 50, 3, 2, 6, 11, 12, 30, 0, 24, 13, 64, 32, 13, 46, 15, 3, 17, 2, 4, 9, 9, 14, 30, 43, 22, 10, 23, 40, 53, 30, 11, 6, 5, 22, 5, 3, 2, 26, 29, 10, 14, 7, 9, 3, 3, 16, 7, 0, 16, 11, 8, 27, 14, 31, 24, 5, 8, 12, 2, 21, 8, 6, 121, 7, 23, 6, 34, 1, 8, 5, 2, 2, 16, 13, 1, 14, 13, 25, 8, 10, 14, 3, 10, 31, 3, 14, 17, 0, 3, 29, 12, 38, 21, 31, 12, 25, 18, 28, 4, 31, 33, 90, 47, 24, 14, 11, 49, 44, 16, 2, 17, 6, 2, 6, 0, 17, 6, 5, 11, 8, 4, 2, 8, 13, 1, 5, 194, 56, 14, 66, 171, 58, 114, 73, 89, 28, 38, 189, 132, 180, 207, 204, 39, 72, 43, 127, 57, 148, 147, 66, 86, 60, 105, 32, 111, 103, 48, 1, 7, 63, 94, 41, 229, 214, 49, 39, 18, 18, 25, 26, 13, 2, 17, 6, 13, 31, 11, 40, 75, 57, 44, 45, 50, 29, 1, 32, 14, 33, 33, 66, 43, 14, 3, 0, 29, 26, 12, 16, 41, 32, 3, 8, 13, 22, 2, 43, 8, 31, 46, 28, 83, 24, 42, 5, 26, 39, 17, 136, 3, 45, 63, 55, 156, 4, 13, 65, 39, 61, 82, 59, 14, 28, 150, 49, 46, 2, 9, 1, 32, 31, 61, 36, 72, 27, 19, 15, 43, 56, 9, 3, 42, 11, 0, 5, 38, 23, 31, 5, 34, 67, 56, 4, 7, 27, 40, 28, 5, 87, 46, 24, 45, 36, 5, 30, 73, 2, 34, 7, 40, 9, 21, 43, 70, 69, 48, 20, 23, 25, 28, 12, 36, 183, 134, 40, 57, 8, 20, 3, 38, 97, 70, 12, 13, 5, 71, 80, 33, 34, 26, 39, 5, 4, 4, 41, 16, 193, 170, 28, 22, 7, 0, 18, 29, 40, 29, 81, 1, 64, 6, 44, 21, 29, 7, 111, 120, 28, 9, 6, 45, 40, 32, 9, 17, 9, 40, 33, 2, 2, 17, 28, 133, 86, 13, 14, 43, 10, 4, 2, 19, 0, 42, 30, 25, 22, 37, 9, 5, 24, 17, 7, 56, 17, 25, 26, 39, 0, 32, 29, 24, 59, 34, 21, 24, 43, 56, 10, 17, 24, 35, 21, 22, 27, 37, 2, 127, 62, 63, 42, 11, 8, 11, 38, 15, 32, 83, 23, 17, 1, 13, 9, 22, 21, 8, 54, 3, 16, 55, 18, 21, 22, 1, 5, 22, 10, 23, 4, 8, 13, 22, 2, 2, 7, 9, 40, 116, 85, 58, 33, 11, 35, 62, 94, 8, 47, 20, 31, 88, 32, 25, 12, 1, 4, 11, 22, 21, 4, 9, 2, 6, 25, 16, 1, 20, 15, 33, 107, 23, 5, 14, 9, 18, 37, 13, 2, 14, 9, 6, 7, 24, 7, 15, 0, 23, 15, 38, 0, 14, 21, 5, 11, 22, 3, 13, 38, 35, 28, 17, 1, 30, 2, 32, 2, 38, 13, 24, 61, 12, 38, 36, 55, 42, 55, 18, 7, 32, 30, 11, 10, 30, 33, 36, 2, 6, 9, 11, 24, 9, 21, 3, 12, 16, 6, 47, 26, 20, 5, 8, 5, 1, 18, 15, 9, 9, 1, 18, 7, 2, 0, 1, 6, 9, 12, 3, 30, 21, 7, 7, 5, 0, 0, 32, 6, 37, 10, 7, 5, 10, 8, 7, 11, 20, 7, 3, 4, 14, 9, 7, 1, 12, 18, 47, 141, 2, 9, 52, 61, 2, 15, 4, 8, 10, 3, 3, 13, 30, 4, 19, 0, 1, 12, 22, 31, 36, 51, 26, 16, 9, 39, 30, 5, 14, 13, 0, 18, 3, 12, 38, 63, 30, 31, 18, 21, 9, 20, 21, 36, 32, 25, 20, 27, 14, 13, 25, 20, 40, 43, 5, 6, 5, 3, 3, 14, 10, 9, 8, 13, 1, 15, 28, 17, 18, 18, 9, 5, 4, 11, 62, 77, 20, 15, 1, 10, 38, 25, 46, 65, 24, 15, 3, 15, 11, 24, 3, 6, 1, 10, 23, 8, 2, 2, 0, 0, 0, 1, 2, 21, 42, 19, 18, 15, 1, 6, 8, 17, 4, 26, 13, 11, 18, 29, 14, 24, 15, 1, 2, 1, 25, 14, 13, 10, 16, 13, 0, 7, 9, 0, 34, 0, 0, 17, 8, 9, 4, 5, 8, 14, 22, 33, 2, 10, 25, 14, 3, 8, 20, 25, 22, 13, 1, 13, 30, 13, 7, 9, 15, 6, 8, 8, 4, 17, 20, 4, 22, 21, 4, 11, 10, 25, 40, 3, 14, 18, 50, 75, 6, 21, 8, 12, 4, 30, 35, 5, 21, 2, 6, 44, 43, 9, 38, 7, 44, 41, 3, 13, 1, 7, 2, 10, 24, 33, 50, 15, 184, 158, 173, 142, 30, 7, 7, 13, 46, 59, 0, 32, 13, 6, 11, 8, 21, 15, 47, 56, 12, 12, 9, 27, 11, 24, 57, 58, 11, 17, 11, 85, 1, 66, 22, 29, 41, 32, 12, 3, 17, 24, 73, 108, 107, 40, 36, 13, 49, 20, 18, 7, 41, 50, 39, 10, 44, 63, 28, 20, 26, 82, 41, 20, 83, 38, 21, 37, 7, 29, 11, 26, 0, 1, 14, 24, 27, 42, 5, 23, 12, 37, 26, 45, 36, 11, 19, 16, 12, 14, 23, 40, 4, 25, 18, 11, 13, 44, 17, 31, 89, 36, 90, 33, 43, 38, 9, 13, 5, 62, 59, 9, 14, 18, 0, 5, 1, 50, 19, 20, 16, 49, 12, 12, 7, 53, 64, 39, 80, 23, 14, 25, 14, 11, 3, 9, 46, 85, 48, 7, 8, 29, 87, 31, 6, 3, 5, 14, 9, 10, 0, 4, 7, 5, 8, 1, 21, 7, 22, 43, 8, 3, 6, 2, 3, 11, 4, 5, 2, 24, 11, 3, 4, 15, 18, 1, 5, 11, 14, 4, 3, 2, 8, 3, 0, 2, 15, 5, 6, 8, 4, 17, 6, 3, 6, 20, 33, 6, 6, 0, 8, 4, 15, 8, 4, 17, 32, 23, 20, 21, 4, 4, 2, 13, 4, 42, 29, 0, 4, 3, 6, 7, 2, 9, 14, 3, 0, 0, 6, 5, 10, 7, 4, 1, 4, 16, 9, 9, 14, 4, 1, 3, 30, 3, 13, 5, 17, 0, 20, 2, 3, 2, 11, 20, 25, 8, 2, 6, 13, 20, 19, 22, 3, 21, 26, 17, 4, 7, 10, 9, 16, 7, 13, 32, 16, 54, 39, 4, 17, 62, 37, 14, 14, 242, 44, 201, 22, 178, 64, 29, 28, 4, 93, 139, 90, 100, 3, 42, 1, 23, 22, 7, 73, 88, 8, 8, 3, 29, 115, 134, 24, 145, 114, 12, 12, 39, 56, 1, 67, 34, 17, 35, 68, 7, 27, 3, 0, 8, 8, 6, 7, 14, 31, 42, 27, 15, 18, 4, 11, 10, 2, 16, 41, 36, 6, 5, 27, 38, 7, 5, 1, 35, 34, 0, 3, 3, 63, 75, 34, 28, 23, 1, 17, 26, 18, 57, 56, 83, 76, 18, 24, 25, 57, 24, 17, 24, 19, 5, 81, 125, 4, 10, 0, 3, 24, 34, 22, 15, 6, 13, 4, 26, 65, 60, 21, 37, 42, 70, 58, 36, 35, 8, 15, 26, 19, 63, 83, 25, 36, 27, 28, 20, 9, 27, 32, 16, 53, 2, 5, 26, 13, 29, 24, 19, 56, 1, 49, 4, 31, 13, 4, 3, 6, 49, 30, 4, 38, 35, 80, 16, 17, 36, 107, 74, 8, 46, 57, 13, 45, 1, 48, 1, 20, 39, 9, 6, 9, 36, 15, 36, 53, 3, 27, 18, 30, 48, 115, 26, 19, 42, 99, 226, 173, 41, 12, 52, 31, 23, 40, 1, 26, 61, 20, 9, 15, 24, 1, 25, 29, 47, 7, 40, 1, 30, 3, 1, 27, 40, 47, 13, 46, 95, 112, 0, 53, 20, 22, 10, 24, 41, 22, 31, 30, 29, 15, 4, 5, 29, 35, 6, 4, 21, 22, 26, 14, 67, 56, 55, 44, 21, 16, 4, 3, 18, 35, 14, 29, 16, 9, 36, 7, 1, 13, 19, 12, 1, 20, 5, 37, 46, 4, 23, 34, 35, 50, 29, 6, 11, 41, 6, 24, 8, 13, 18, 6, 20, 51, 36, 24, 37, 14, 21, 58, 61, 0, 46, 25, 6, 11, 7, 4, 43, 42, 16, 2, 19, 65, 1, 0, 10, 22, 53, 24, 42, 18, 8, 11, 8, 0, 8, 11, 26, 17, 22, 27, 17, 68, 12, 29, 18, 61, 74, 47, 10, 1, 42, 37, 0, 19, 35, 70, 31, 16, 11, 48, 33, 5, 21, 42, 10, 5, 17, 18, 16, 43, 16, 13, 18, 14, 17, 23, 5, 15, 4, 20, 24, 18, 31, 10, 20, 15, 8, 35, 9, 1, 40, 18, 1, 11, 13, 24, 33, 27, 2, 42, 11, 16, 20, 35, 32, 39, 36, 7, 16, 23, 7, 4, 28, 19, 29, 28, 19, 8, 10, 44, 31, 0, 55, 20, 32, 37, 5, 38, 1, 4, 20, 33, 44, 43, 5, 0, 57, 17, 7, 7, 16, 15, 12, 15, 10, 3, 0, 19, 14, 3, 3, 12, 5, 8, 3, 4, 9, 10, 9, 14, 61, 1, 9, 10, 10, 17, 14, 15, 6, 4, 5, 4, 16, 5, 12, 9, 0, 1, 8, 13, 15, 8, 4, 1, 10, 13, 2, 16, 7, 7, 1, 14, 8, 13, 6, 7, 12, 8, 15, 11, 2, 10, 3, 8, 11, 13, 26, 4, 6, 7, 0, 7, 6, 1, 2, 3, 10, 9, 54, 0, 1, 98, 105, 46, 1, 94, 21, 126, 135, 85, 29, 108, 74, 39, 111, 106, 37, 55, 15, 142, 57, 22, 8, 40, 4, 3, 20, 25, 21, 3, 16, 9, 4, 11, 26, 13, 2, 16, 47, 24, 28, 21, 34, 17, 11, 8, 33, 30, 25, 4, 17, 18, 67, 37, 14, 0, 27, 58, 39, 5, 13, 4, 14, 29, 4, 4, 6, 1, 2, 2, 13, 10, 1, 8, 7, 13, 18, 13, 14, 20, 7, 11, 29, 24, 5, 12, 2, 13, 12, 3, 71, 11, 8, 21, 16, 18, 7, 15, 8, 0, 13, 23, 24, 1, 13, 34, 25, 22, 27, 13, 22, 14, 15, 12, 2, 11, 12, 3, 4, 3, 9, 2, 10, 21, 8, 1, 12, 0, 4, 4, 7, 7, 17, 30, 19, 10, 1, 10, 17, 30, 23, 2, 4, 7, 0, 10, 14, 17, 14, 37, 30, 9, 16, 23, 36, 19, 6, 18, 5, 3, 9, 26, 17, 11, 16, 6, 11, 4, 3, 0, 0, 7, 12, 6, 9, 1, 4, 14, 17, 2, 14, 19, 20, 7, 6, 1, 27, 28, 5, 24, 17, 23, 10, 12, 13, 12, 18, 31, 7, 4, 12, 5, 10, 7, 5, 16, 21, 12, 27, 4, 3, 14, 3, 10, 15, 16, 7, 7, 22, 17, 14, 11, 12, 6, 7, 19, 18, 1, 2, 9, 16, 22, 31, 10, 5, 8, 3, 10, 46, 1, 69, 24, 33, 29, 19, 46, 165, 94, 55, 29, 38, 106, 108, 79, 88, 8, 7, 139, 10, 86, 77, 42, 88, 7, 21, 36, 6, 2, 207, 188, 4, 10, 4, 23, 19, 23, 7, 30, 19, 9, 12, 24, 13, 4, 16, 5, 0, 19, 132, 129, 114, 87, 17, 10, 43, 122, 31, 49, 17, 2, 7, 1, 31, 46, 54, 0, 103, 94, 15, 41, 52, 165, 0, 220, 23, 2, 85, 5, 62, 48, 167, 60, 140, 107, 86, 33, 66, 77, 119, 34, 70, 15, 19, 40, 41, 16, 14, 107, 14, 74, 43, 16, 14, 23, 34, 37, 135, 162, 33, 12, 30, 17, 12, 1, 12, 30, 23, 41, 53, 76, 47, 57, 78, 83, 78, 52, 8, 111, 68, 1, 32, 21, 45, 26, 6, 19, 40, 9, 14, 31, 54, 97, 62, 35, 127, 13, 9, 43, 3, 26, 9, 11, 22, 41, 15, 3, 8, 3, 6, 11, 9, 4, 2, 18, 10, 1, 30, 1, 109, 176, 29, 2, 51, 151, 37, 17, 112, 42, 119, 66, 84, 16, 101, 136, 54, 103, 82, 44, 99, 14, 78, 71, 117, 36, 19, 78, 20, 10, 28, 30, 83, 1, 9, 3, 14, 130, 51, 53, 10, 17, 11, 9, 37, 38, 14, 7, 6, 19, 4, 32, 48, 7, 11, 51, 6, 14, 9, 53, 68, 95, 4, 130, 36, 47, 61, 15, 62, 29, 3, 32, 0, 2, 55, 40, 26, 67, 32, 40, 43, 65, 68, 25, 37, 3, 23, 15, 33, 37, 7, 5, 5, 34, 17, 7, 21, 30, 14, 37, 0, 4, 11, 0, 28, 10, 35, 34, 11, 5, 0, 14, 4, 35, 16, 24, 19, 28, 25, 28, 25, 9, 38, 35, 20, 17, 16, 33, 18, 3, 28, 27, 22, 35, 22, 14, 3, 35, 25, 3, 9, 8, 4, 7, 6, 7, 5, 18, 13, 6, 8, 11, 5, 18, 32, 198, 59, 16, 12, 0, 27, 5, 94, 63, 36, 11, 47, 32, 4, 25, 62, 20, 91, 18, 15, 12, 82, 36, 125, 54, 14, 97, 66, 46, 85, 22, 6, 60, 33, 45, 20, 44, 21, 24, 69, 80, 157, 96, 88, 0, 45, 45, 16, 76, 45, 34, 147, 44, 60, 16, 28, 77, 62, 29, 49, 15, 12, 22, 31, 14, 0, 15, 14, 3, 21, 20, 5, 11, 67, 7, 22, 17, 20, 15, 3, 6, 8, 23, 7, 14, 17, 1, 2, 4, 4, 21, 44, 11, 19, 6, 28, 6, 8, 19, 32, 53, 24, 6, 10, 0, 31, 24, 43, 34, 2, 0, 9, 16, 17, 26, 31, 2, 7, 8, 12, 19, 17, 2, 16, 7, 3, 18, 2, 8, 0, 13, 7, 24, 2, 6, 25, 4, 2, 14, 5, 53, 9, 27, 24, 6, 27, 10, 10, 6, 5, 1, 2, 9, 10, 7, 2, 16, 23, 22, 15, 6, 1, 8, 6, 17, 12, 11, 2, 7, 6, 0, 3, 7, 14, 26, 5, 1, 3, 19, 10, 0, 1, 12, 23, 8, 0, 3, 7, 26, 11, 18, 3, 20, 0, 18, 5, 0, 4, 31, 40, 12, 39, 18, 23, 22, 25, 22, 12, 0, 3, 20, 11, 27, 15, 26, 1, 15, 40, 29, 30, 23, 4, 19, 4, 36, 0, 2, 1, 16, 17, 0, 24, 33, 30, 23, 30, 6, 8, 45, 2, 2, 19, 14, 15, 10, 36, 3, 21, 4, 3, 7, 7, 1, 7, 6, 21, 8, 8, 44, 12, 6, 37, 26, 80, 31, 45, 42, 18, 23, 22, 19, 38, 50, 18, 73, 28, 15, 3, 47, 4, 57, 48, 16, 28, 19, 3, 13, 24, 47, 50, 21, 0, 3, 4, 13, 31, 24, 24, 21, 6, 33, 34, 10, 43, 30, 20, 5, 59, 40, 17, 9, 38, 19, 24, 14, 25, 3, 58, 85, 6, 40, 29, 40, 33, 19, 30, 35, 24, 54, 47, 25, 44, 68, 79, 112, 49, 52, 42, 89, 80, 155, 18, 38, 17, 9, 18, 58, 67, 10, 77, 62, 2, 33, 13, 17, 18, 88, 23, 17, 6, 27, 20, 30, 15, 19, 35, 13, 18, 5, 25, 62, 40, 17, 5, 7, 17, 5, 4, 14, 25, 38, 27, 1, 32, 39, 4, 20, 9, 5, 5, 53, 34, 102, 37, 27, 9, 4, 8, 20, 28, 29, 13, 12, 0, 8, 43, 23, 46, 8, 11, 3, 24, 51, 4, 10, 5, 12, 10, 16, 2, 74, 3, 14, 7, 15, 107, 16, 40, 15, 13, 110, 12, 35, 49, 60, 27, 10, 4, 10, 33, 8, 4, 31, 20, 23, 11, 10, 16, 4, 23, 4, 20, 31, 24, 20, 9, 4, 4, 13, 41, 15, 21, 22, 1, 9, 14, 23, 5, 2, 8, 6, 7, 14, 19, 26, 17, 5, 6, 6, 4, 10, 4, 1, 5, 54, 39, 9, 51, 6, 14, 7, 4, 9, 13, 31, 31, 1, 18, 11, 20, 7, 19, 2, 16, 7, 7, 0, 16, 9, 2, 5, 2, 5, 16, 8, 2, 21, 1, 4, 2, 0, 0, 6, 3, 2, 5, 12, 17, 18, 1, 16, 25, 14, 1, 9, 5, 1, 1, 3, 6, 18, 15, 8, 0, 0, 6, 9, 7, 3, 8, 9, 12, 2, 6, 7, 56, 27, 28, 3, 2, 7, 15, 32, 31, 9, 20, 32, 23, 1, 4, 1, 3, 5, 2, 11, 2, 10, 1, 15, 24, 21, 14, 5, 6, 15, 14, 15, 6, 16, 9, 20, 0, 7, 29, 16, 40, 15, 4, 6, 13, 7, 4, 37, 50, 12, 4, 39, 10, 14, 6, 13, 6, 1, 23, 12, 4, 12, 16, 43, 15, 11, 12, 11, 12, 21, 26, 15, 2, 11, 12, 14, 31, 32, 4, 32, 3, 42, 29, 24, 20, 31, 21, 21, 32, 8, 47, 12, 34, 8, 49, 38, 15, 49, 32, 9, 21, 154, 9, 17, 222, 26, 61, 19, 78, 109, 35, 16, 24, 1, 124, 131, 160, 31, 61, 68, 59, 70, 21, 29, 23, 55, 11, 22, 116, 13, 0, 11, 15, 34, 18, 23, 27, 12, 34, 23, 0, 3, 10, 27, 67, 40, 63, 24, 55, 56, 7, 37, 14, 62, 31, 52, 37, 13, 22, 37, 7, 0, 5, 42, 0, 32, 8, 85, 34, 59, 8, 58, 27, 42, 52, 6, 49, 43, 0, 28, 14, 0, 45, 12, 15, 32, 11, 8, 33, 30, 13, 52, 43, 23, 31, 30, 14, 18, 25, 50, 39, 19, 9, 48, 49, 29, 87, 48, 33, 13, 28, 7, 150, 88, 4, 103, 30, 64, 93, 70, 26, 32, 27, 0, 101, 10, 84, 5, 67, 38, 23, 40, 8, 25, 26, 131, 21, 34, 5, 5, 27, 25, 0, 10, 42, 5, 18, 7, 5, 16, 31, 28, 23, 11, 0, 23, 20, 6, 45, 63, 16, 3, 20, 8, 5, 0, 12, 13, 10, 10, 12, 37, 20, 3, 13, 3, 1, 2, 24, 15, 13, 3, 28, 4, 15, 3, 9, 1, 30, 29, 18, 0, 6, 1, 0, 2, 1, 9, 8, 12, 25, 16, 10, 3, 0, 27, 14, 8, 10, 12, 6, 23, 19, 13, 12, 22, 15, 9, 17, 7, 28, 10, 11, 9, 11, 18, 4, 5, 36, 39, 3, 14, 0, 5, 4, 13, 2, 14, 2, 7, 5, 1, 10, 15, 12, 5, 20, 11, 6, 7, 11, 43, 2, 12, 17, 5, 8, 0, 7, 2, 13, 12, 6, 0, 11, 3, 5, 4, 9, 4, 0, 5, 16, 0, 7, 14, 11, 2, 10, 1, 11, 8, 0, 2, 19, 6, 3, 18, 1, 5, 16, 13, 4, 7, 12, 19, 12, 4, 14, 13, 23, 2, 21, 16, 3, 14, 3, 7, 10, 5, 10, 9, 2, 7, 0, 5, 0, 14, 15, 2, 0, 6, 3, 10, 7, 4, 1, 11, 12, 5, 7, 6, 14, 13, 2, 3, 10, 1, 13, 10, 7, 12, 5, 12, 3, 1, 6, 10, 13, 8, 7, 8, 3, 0, 7, 7, 4, 8, 12, 21, 12, 3, 14, 1, 32, 20, 4, 54, 25, 11, 3, 15, 46, 43, 16, 29, 16, 1, 26, 13, 40, 30, 3, 30, 37, 4, 3, 8, 12, 22, 9, 13, 24, 25, 15, 2, 17, 2, 3, 10, 5, 12, 0, 14, 27, 16, 5, 4, 3, 5, 1, 9, 4, 2, 24, 11, 12, 11, 4, 6, 1, 0, 4, 16, 19, 17, 148, 61, 22, 101, 120, 99, 28, 104, 23, 64, 19, 173, 35, 170, 5, 9, 22, 5, 16, 4, 13, 16, 22, 2, 18, 51, 11, 7, 2, 38, 41, 15, 52, 39, 43, 45, 7, 74, 33, 20, 11, 66, 33, 18, 3, 21, 2, 5, 22, 13, 20, 47, 21, 41, 12, 0, 19, 0, 22, 5, 4, 19, 40, 25, 24, 33, 22, 23, 13, 9, 28, 1, 3, 2, 6, 13, 9, 30, 7, 9, 7, 32, 25, 20, 37, 15, 5, 12, 17, 14, 16, 5, 17, 6, 9, 14, 0, 3, 22, 1, 18, 17, 8, 17, 7, 0, 24, 23, 14, 3, 15, 12, 35, 18, 2, 0, 2, 10, 1, 2, 1, 7, 2, 4, 5, 6, 13, 9, 18, 10, 29, 24, 11, 1, 18, 9, 9, 30, 25, 2, 1, 8, 9, 16, 23, 6, 30, 6, 15, 14, 2, 2, 3, 0, 0, 1, 24, 37, 28, 19, 12, 20, 15, 5, 15, 6, 18, 6, 11, 4, 10, 6, 15, 9, 16, 6, 19, 0, 14, 17, 0, 10, 1, 12, 3, 1, 0, 12, 5, 2, 3, 6, 8, 23, 2, 2, 6, 25, 26, 3, 13, 0, 18, 2, 23, 12, 18, 0, 27, 20, 3, 1, 10, 11, 7, 19, 22, 27, 58, 60, 21, 6, 11, 12, 1, 8, 9, 9, 12, 51, 24, 25, 15, 10, 13, 4, 16, 27, 42, 51, 22, 5, 0, 18, 17, 3, 28, 29, 0, 10, 7, 28, 27, 4, 8, 16, 15, 15, 1, 30, 41, 34, 2, 17, 6, 18, 11, 12, 6, 2, 7, 11, 36, 19, 4, 5, 0, 5, 10, 23, 38, 35, 8, 6, 2, 17, 8, 10, 13, 18, 15, 12, 8, 11, 6, 17, 16, 9, 218, 156, 235, 27, 16, 1, 26, 23, 1, 74, 206, 4, 129, 123, 182, 2, 173, 49, 36, 214, 135, 58, 47, 97, 20, 1, 5, 77, 42, 2, 133, 101, 64, 102, 53, 146, 5, 7, 85, 28, 20, 34, 17, 60, 209, 20, 142, 28, 197, 224, 111, 22, 73, 94, 25, 42, 42, 1, 149, 44, 89, 34, 98, 109, 124, 93, 50, 27, 14, 10, 37, 20, 45, 42, 16, 13, 64, 5, 49, 26, 28, 87, 4, 2, 40, 2, 18, 9, 7, 13, 4, 29, 48, 11, 0, 43, 56, 17, 2, 1, 20, 13, 12, 37, 47, 38, 32, 8, 3, 9, 11, 27, 22, 14, 30, 85, 38, 20, 3, 23, 9, 1, 101, 12, 33, 35, 80, 47, 7, 22, 32, 51, 24, 30, 23, 44, 37, 42, 57, 15, 50, 21, 91, 90, 61, 9, 72, 25, 19, 54, 31, 3, 31, 48, 12, 71, 54, 93, 55, 64, 5, 9, 28, 25, 17, 3, 28, 39, 34, 4, 9, 35, 12, 6, 3, 5, 30, 2, 15, 86, 53, 65, 20, 60, 43, 12, 9, 16, 17, 18, 3, 15, 10, 14, 4, 4, 11, 10, 3, 15, 26, 45, 3, 7, 68, 93, 80, 68, 127, 6, 14, 9, 7, 52, 43, 26, 9, 4, 33, 24, 24, 35, 10, 10, 14, 0, 0, 27, 9, 5, 5, 22, 16, 1, 7, 31, 5, 0, 17, 42, 16, 25, 14, 11, 20, 30, 3, 37, 4, 27, 46, 33, 60, 53, 13, 12, 29, 32, 16, 23, 8, 11, 10, 34, 5, 10, 16, 5, 18, 0, 3, 43, 10, 8, 11, 3, 4, 22, 30, 45, 2, 1, 1, 24, 23, 20, 10, 1, 19, 32, 0, 31, 10, 4, 1, 21, 6, 10, 23, 1, 12, 11, 62, 67, 20, 5, 44, 35, 0, 22, 32, 39, 9, 3, 14, 7, 8, 34, 75, 5, 26, 17, 10, 21, 20, 9, 14, 15, 4, 21, 122, 147, 44, 6, 148, 167, 40, 186, 101, 86, 27, 4, 77, 41, 16, 24, 22, 17, 43, 8, 14, 0, 14, 11, 10, 5, 6, 13, 4, 3, 20, 0, 0, 4, 7, 3, 1, 28, 27, 1, 30, 20, 39, 10, 25, 28, 13, 3, 4, 24, 37, 1, 18, 2, 27, 16, 42, 86, 25, 16, 35, 51, 7, 36, 21, 55, 20, 12, 8, 10, 73, 44, 1, 32, 49, 3, 52, 47, 22, 53, 16, 4, 20, 4, 15, 1, 4, 13, 40, 19, 115, 18, 6, 21, 28, 9, 44, 15, 27, 2, 14, 32, 67, 42, 1, 4, 19, 40, 15, 3, 8, 27, 21, 68, 47, 4, 23, 58, 22, 6, 23, 15, 9, 52, 15, 1, 32, 37, 28, 10, 27, 3, 14, 3, 1, 7, 2, 8, 0, 1, 4, 11, 1, 120, 23, 124, 11, 125, 76, 86, 123, 78, 145, 108, 122, 41, 120, 111, 53, 17, 34, 83, 226, 22, 29, 71, 16, 69, 64, 89, 86, 1, 36, 15, 24, 21, 32, 35, 17, 14, 21, 5, 28, 55, 52, 26, 25, 5, 33, 76, 31, 45, 32, 9, 7, 53, 22, 38, 2, 9, 49, 51, 96, 24, 12, 3, 87, 53, 14, 27, 62, 130, 31, 0, 99, 33, 32, 134, 101, 53, 27, 34, 6, 2, 5, 7, 63, 42, 1, 12, 11, 4, 16, 23, 22, 17, 34, 52, 89, 8, 100, 54, 145, 0, 15, 16, 42, 7, 2, 110, 18, 143, 3, 19, 4, 46, 21, 51, 5, 30, 28, 38, 27, 55, 12, 0, 26, 8, 29, 70, 86, 107, 75, 33, 76, 154, 25, 21, 27, 70, 20, 127, 32, 29, 20, 58, 15, 74, 41, 39, 10, 90, 111, 93, 4, 16, 86, 33, 8, 22, 76, 167, 78, 16, 97, 16, 20, 52, 30, 35, 77, 128, 59, 52, 4, 103, 122, 57, 49, 16, 29, 22, 31, 115, 76, 8, 23, 50, 9, 20, 49, 48, 81, 1, 11, 10, 1, 57, 74, 67, 40, 51, 44, 139, 8, 9, 0, 8, 68, 77, 4, 12, 9, 9, 7, 0, 90, 16, 4, 76, 89, 8, 15, 1, 4, 9, 10, 14, 128, 134, 13, 0, 37, 21, 82, 25, 21, 24, 3, 51, 34, 54, 7, 38, 33, 5, 43, 0, 60, 55, 14, 36, 4, 35, 8, 55, 36, 44, 49, 36, 24, 59, 54, 17, 17, 7, 60, 57, 24, 46, 103, 90, 51, 4, 83, 65, 20, 22, 35, 12, 14, 17, 22, 23, 22, 9, 3, 2, 5, 4, 20, 11, 19, 33, 38, 4, 24, 37, 35, 12, 57, 33, 6, 11, 1, 4, 18, 21, 4, 7, 0, 14, 12, 3, 20, 3, 9, 17, 2, 7, 18, 3, 11, 10, 5, 13, 12, 5, 21, 1, 2, 11, 4, 7, 16, 7, 7, 1, 2, 0, 10, 0, 7, 3, 0, 5, 22, 13, 0, 4, 5, 5, 10, 1, 16, 2, 9, 7, 16, 2, 12, 18, 9, 5, 3, 20, 19, 2, 11, 6, 0, 4, 16, 17, 7, 8, 5, 1, 14, 1, 6, 7, 4, 9, 7, 6, 10, 7, 1, 0, 5, 1, 6, 1, 1, 1, 0, 4, 8, 13, 14, 7, 4, 0, 4, 2, 8, 15, 2, 3, 16, 9, 2, 0, 5, 2, 7, 14, 7, 0, 1, 10, 9, 6, 7, 8, 5, 14, 3, 5, 0, 6, 6, 19, 8, 3, 2, 11, 8, 0, 3, 14, 0, 7, 16, 15, 0, 2, 6, 0, 10, 13, 2, 3, 4, 1, 1, 2, 0, 3, 4, 1, 4, 1, 12, 19, 7, 8, 23, 5, 6, 11, 0, 12, 15, 18, 7, 12, 11, 4, 21, 20, 11, 2, 3, 22, 7, 0, 0, 5, 9, 14, 11, 16, 9, 2, 1, 33, 46, 21, 24, 17, 12, 23, 0, 0, 18, 17, 1, 14, 17, 22, 9, 4, 17, 26, 3, 5, 18, 19, 15, 24, 8, 15, 0, 6, 16, 31, 11, 8, 6, 10, 5, 6, 13, 10, 5, 6, 14, 11, 12, 5, 7, 18, 10, 9, 9, 13, 9, 10, 8, 2, 15, 8, 9, 4, 14, 13, 0, 6, 8, 0, 3, 19, 12, 18, 9, 4, 11, 14, 11, 2, 5, 3, 6, 13, 4, 32, 17, 3, 6, 1, 5, 22, 8, 5, 9, 4, 3, 3, 28, 23, 6, 21, 2, 14, 2, 54, 10, 34, 31, 19, 112, 55, 36, 25, 4, 21, 1, 15, 14, 50, 39, 40, 7, 77, 38, 30, 59, 21, 92, 2, 20, 5, 29, 15, 6, 30, 184, 139, 76, 128, 48, 9, 20, 6, 27, 31, 51, 8, 9, 30, 24, 16, 69, 20, 18, 21, 3, 22, 51, 72, 57, 93, 5, 13, 15, 42, 1, 2, 25, 13, 29, 6, 10, 24, 16, 16, 5, 5, 11, 9, 25, 11, 37, 43, 18, 56, 49, 3, 37, 3, 7, 60, 15, 59, 30, 28, 13, 55, 44, 21, 52, 36, 43, 78, 51, 24, 5, 49, 29, 22, 4, 19, 2, 25, 12, 28, 9, 10, 18, 5, 25, 7, 4, 13, 16, 9, 1, 3, 46, 19, 21, 14, 7, 0, 9, 26, 10, 5, 1, 4, 8, 4, 12, 1, 27, 6, 8, 4, 4, 35, 20, 15, 11, 18, 17, 14, 20, 29, 0, 24, 15, 12, 0, 5, 5, 18, 13, 44, 35, 0, 0, 5, 12, 14, 3, 31, 0, 26, 11, 4, 6, 11, 6, 8, 6, 2, 9, 11, 1, 14, 11, 5, 2, 5, 44, 1, 5, 9, 41, 34, 35, 13, 6, 5, 70, 19, 0, 5, 22, 7, 16, 13, 7, 3, 10, 7, 8, 8, 3, 9, 14, 13, 16, 7, 13, 20, 57, 12, 3, 32, 6, 1, 8, 3, 8, 5, 11, 3, 2, 14, 5, 6, 1, 3, 5, 6, 30, 23, 7, 32, 13, 19, 18, 3, 18, 33, 15, 14, 10, 10, 20, 15, 23, 30, 9, 14, 17, 12, 23, 24, 16, 1, 6, 21, 35, 26, 1, 12, 11, 1, 6, 0, 5, 18, 30, 27, 9, 4, 51, 30, 31, 2, 26, 17, 212, 60, 107, 200, 99, 0, 141, 101, 234, 54, 219, 21, 54, 242, 95, 83, 118, 119, 156, 56, 39, 1, 22, 17, 26, 1, 161, 36, 51, 166, 251, 53, 104, 76, 98, 71, 76, 31, 1, 6, 1, 40, 28, 139, 152, 5, 95, 47, 158, 239, 246, 139, 106, 11, 22, 23, 34, 15, 26, 73, 68, 15, 43, 24, 29, 41, 23, 74, 9, 4, 47, 2, 50, 51, 18, 6, 28, 9, 7, 5, 17, 5, 32, 18, 49, 19, 18, 8, 14, 53, 34, 23, 40, 35, 20, 20, 3, 17, 13, 8, 28, 16, 27, 2, 8, 20, 49, 40, 11, 5, 9, 13, 6, 1, 129, 17, 8, 44, 87, 76, 7, 5, 16, 14, 43, 45, 20, 69, 5, 23, 17, 24, 9, 22, 11, 22, 11, 8, 15, 13, 24, 16, 19, 12, 35, 32, 21, 4, 22, 23, 14, 0, 6, 8, 17, 3, 0, 8, 10, 7, 19, 30, 5, 10, 27, 1, 30, 23, 3, 9, 7, 16, 6, 17, 17, 12, 20, 3, 2, 6, 5, 6, 3, 9, 5, 24, 25, 17, 14, 22, 17, 0, 1, 30, 13, 23, 30, 19, 2, 20, 14, 1, 15, 6, 12, 23, 12, 8, 21, 24, 1, 13, 20, 0, 14, 21, 15, 8, 0, 20, 5, 15, 50, 25, 63, 7, 2, 4, 19, 0, 16, 6, 17, 14, 2, 7, 23, 26, 2, 17, 8, 2, 0, 24, 11, 39, 24, 14, 14, 1, 32, 18, 45, 18, 36, 6, 13, 2, 14, 15, 12, 9, 18, 0, 11, 8, 3, 10, 21, 36, 5, 9, 8, 22, 19, 29, 6, 50, 37, 4, 42, 20, 106, 77, 74, 119, 1, 176, 38, 177, 122, 69, 77, 0, 20, 86, 39, 160, 107, 30, 123, 95, 28, 3, 25, 38, 23, 9, 35, 102, 97, 50, 1, 61, 2, 38, 19, 50, 91, 88, 55, 0, 35, 30, 27, 21, 16, 20, 8, 51, 48, 71, 26, 4, 86, 43, 20, 63, 76, 15, 9, 27, 68, 93, 16, 7, 18, 59, 82, 57, 6, 1, 6, 66, 13, 113, 46, 9, 17, 22, 4, 36, 19, 10, 1, 33, 0, 4, 28, 51, 30, 47, 54, 41, 48, 35, 16, 10, 15, 22, 3, 4, 0, 20, 13, 27, 21, 8, 9, 28, 21, 0, 70, 59, 36, 12, 56, 1, 89, 122, 55, 1, 120, 1, 8, 141, 120, 3, 4, 5, 3, 45, 68, 25, 33, 35, 50, 22, 53, 80, 65, 38, 26, 1, 9, 1, 4, 21, 22, 25, 22, 15, 24, 29, 12, 24, 37, 24, 65, 32, 89, 92, 57, 18, 55, 6, 52, 79, 46, 3, 10, 63, 0, 62, 38, 49, 26, 25, 58, 67, 2, 5, 32, 0, 41, 16, 11, 1, 13, 25, 19, 40, 46, 71, 72, 7, 33, 51, 24, 68, 23, 26, 31, 26, 33, 0, 12, 1, 16, 11, 36, 77, 56, 11, 27, 22, 6, 30, 25, 35, 11, 0, 40, 37, 25, 54, 52, 53, 15, 24, 21, 5, 13, 22, 6, 54, 105, 64, 74, 31, 55, 3, 44, 37, 25, 16, 17, 8, 6, 115, 120, 74, 6, 11, 29, 44, 171, 49, 4, 33, 26, 49, 25, 0, 5, 25, 12, 50, 11, 31, 8, 5, 16, 17, 26, 41, 16, 4, 6, 11, 28, 28, 59, 22, 80, 83, 18, 41, 10, 3, 0, 6, 76, 63, 25, 12, 3, 11, 0, 16, 8, 4, 1, 26, 67, 32, 4, 3, 19, 22, 6, 7, 3, 0, 2, 14, 7, 10, 25, 24, 21, 28, 23, 12, 15, 4, 28, 1, 47, 28, 19, 20, 0, 26, 22, 1, 31, 15, 5, 66, 31, 50, 39, 31, 48, 25, 49, 46, 1, 13, 14, 5, 88, 95, 19, 14, 36, 31, 9, 18, 25, 6, 46, 21, 9, 7, 36, 22, 31, 19, 2, 13, 98, 95, 18, 1, 13, 2, 16, 80, 69, 31, 14, 10, 48, 65, 10, 29, 16, 12, 28, 27, 0, 8, 58, 67, 36, 19, 3, 27, 12, 1, 10, 20, 14, 25, 21, 14, 23, 18, 0, 14, 3, 19, 104, 19, 59, 8, 15, 4, 30, 5, 3, 23, 3, 36, 39, 10, 1, 6, 21, 20, 0, 27, 46, 34, 37, 11, 4, 8, 15, 12, 21, 66, 1, 31, 36, 45, 80, 10, 168, 41, 88, 3, 51, 77, 160, 68, 195, 94, 40, 7, 77, 100, 93, 17, 0, 7, 23, 16, 43, 18, 11, 16, 2, 9, 28, 39, 16, 14, 0, 21, 18, 0, 33, 13, 66, 41, 8, 8, 4, 4, 40, 61, 46, 7, 12, 51, 22, 10, 15, 3, 61, 70, 28, 35, 7, 17, 4, 30, 10, 2, 4, 25, 6, 2, 31, 2, 26, 1, 16, 7, 4, 14, 17, 36, 21, 1, 59, 30, 0, 11, 46, 7, 6, 5, 13, 9, 21, 42, 8, 19, 16, 19, 25, 40, 30, 27, 3, 1, 31, 26, 4, 12, 15, 12, 29, 24, 13, 12, 0, 6, 10, 29, 32, 2, 31, 36, 43, 21, 52, 33, 20, 4, 0, 26, 5, 52, 59, 10, 7, 25, 22, 14, 8, 4, 0, 31, 0, 1, 6, 15, 6, 45, 52, 3, 11, 16, 36, 53, 65, 20, 25, 18, 6, 47, 6, 10, 27, 1, 20, 16, 3, 3, 19, 8, 24, 35, 1, 30, 35, 0, 26, 0, 25, 28, 25, 4, 9, 14, 24, 23, 9, 3, 20, 12, 21, 4, 1, 19, 5, 42, 13, 12, 25, 38, 7, 5, 3, 1, 4, 9, 18, 27, 16, 0, 2, 32, 61, 24, 26, 25, 11, 15, 46, 23, 15, 16, 4, 4, 7, 28, 69, 54, 3, 33, 32, 7, 47, 4, 6, 10, 17, 17, 36, 29, 14, 8, 28, 13, 14, 19, 21, 7, 40, 9, 33, 28, 15, 0, 11, 22, 4, 21, 0, 2, 22, 1, 41, 16, 10, 13, 0, 11, 1, 4, 28, 21, 6, 2, 11, 2, 18, 3, 48, 10, 32, 29, 33, 34, 31, 56, 6, 9, 19, 36, 33, 14, 1, 25, 22, 9, 0, 4, 35, 58, 73, 54, 35, 12, 9, 12, 136, 51, 26, 25, 6, 4, 1, 14, 41, 80, 48, 9, 4, 12, 12, 20, 7, 8, 9, 11, 15, 27, 8, 28, 25, 26, 22, 0, 59, 18, 13, 12, 6, 3, 0, 10, 48, 95, 140, 25, 0, 111, 52, 49, 27, 138, 24, 141, 23, 96, 65, 0, 148, 13, 137, 140, 2, 51, 18, 2, 27, 28, 4, 23, 47, 2, 56, 28, 19, 5, 18, 21, 10, 7, 16, 1, 12, 23, 10, 6, 61, 48, 4, 3, 7, 4, 6, 5, 23, 32, 73, 1, 11, 11, 44, 45, 11, 10, 16, 6, 9, 7, 4, 6, 2, 3, 38, 15, 43, 10, 2, 38, 0, 6, 17, 1, 17, 0, 44, 39, 28, 19, 3, 6, 10, 11, 12, 13, 20, 0, 21, 10, 2, 1, 6, 5, 10, 7, 0, 5, 0, 9, 2, 3, 10, 18, 31, 21, 91, 12, 9, 29, 25, 28, 2, 11, 15, 40, 98, 113, 3, 6, 21, 0, 24, 23, 4, 4, 58, 39, 29, 8, 10, 8, 9, 8, 13, 15, 36, 23, 3, 7, 26, 12, 5, 35, 8, 21, 26, 8, 21, 96, 70, 18, 75, 100, 159, 104, 68, 8, 45, 113, 118, 77, 28, 24, 48, 7, 15, 28, 8, 31, 63, 72, 41, 50, 69, 6, 58, 105, 24, 82, 31, 21, 22, 40, 75, 16, 66, 4, 22, 9, 20, 9, 1, 12, 23, 6, 5, 21, 8, 20, 49, 24, 26, 11, 6, 3, 8, 51, 7, 34, 29, 20, 19, 32, 13, 17, 52, 17, 20, 30, 49, 23, 28, 35, 13, 16, 5, 16, 3, 48, 41, 43, 88, 79, 37, 39, 110, 5, 9, 17, 6, 7, 37, 66, 3, 75, 54, 34, 31, 87, 7, 19, 32, 15, 5, 14, 8, 19, 0, 18, 20, 6, 43, 21, 22, 2, 10, 23, 40, 4, 33, 6, 15, 22, 10, 27, 3, 11, 30, 6, 15, 4, 3, 40, 27, 4, 33, 32, 0, 1, 4, 10, 7, 1, 14, 21, 4, 6, 7, 22, 23, 24, 23, 14, 21, 20, 49, 63, 20, 25, 8, 12, 7, 13, 6, 3, 5, 8, 17, 4, 24, 7, 12, 17, 5, 30, 19, 142, 110, 119, 116, 97, 34, 61, 22, 46, 32, 18, 53, 3, 94, 53, 3, 23, 44, 11, 19, 55, 81, 20, 146, 91, 27, 68, 40, 26, 38, 25, 91, 62, 67, 66, 64, 0, 57, 120, 111, 3, 8, 1, 10, 31, 28, 2, 32, 60, 39, 126, 205, 28, 3, 25, 3, 130, 113, 10, 13, 43, 14, 3, 40, 17, 10, 108, 23, 85, 20, 27, 24, 9, 230, 199, 154, 215, 102, 71, 24, 29, 25, 52, 29, 44, 158, 9, 177, 124, 12, 21, 38, 45, 0, 38, 30, 59, 26, 27, 3, 177, 172, 68, 9, 45, 54, 123, 99, 22, 122, 11, 31, 45, 34, 6, 119, 96, 101, 118, 45, 13, 70, 49, 7, 63, 38, 57, 51, 186, 41, 105, 114, 25, 49, 25, 38, 15, 50, 59, 10, 44, 33, 128, 95, 15, 44, 29, 89, 38, 29, 28, 86, 15, 8, 62, 1, 33, 15, 48, 93, 68, 33, 71, 78, 11, 32, 75, 17, 2, 54, 65, 11, 16, 14, 25, 48, 69, 94, 10, 5, 57, 6, 70, 61, 4, 65, 80, 11, 73, 46, 32, 127, 168, 31, 59, 78, 35, 35, 30, 32, 87, 23, 49, 9, 38, 13, 3, 38, 53, 32, 17, 4, 142, 117, 26, 33, 36, 56, 95, 1, 7, 168, 35, 69, 13, 12, 67, 136, 75, 29, 19, 54, 67, 4, 19, 3, 26, 31, 10, 18, 3, 1, 12, 6, 43, 98, 85, 24, 27, 24, 9, 16, 38, 87, 16, 8, 17, 26, 0, 47, 70, 17, 5, 4, 4, 13, 43, 82, 73, 10, 32, 3, 15, 24, 11, 15, 10, 19, 3, 22, 12, 35, 42, 31, 11, 38, 3, 17, 2, 10, 8, 49, 42, 22, 37, 8, 31, 4, 4, 19, 4, 21, 16, 24, 5, 5, 11, 18, 14, 192, 25, 74, 106, 65, 86, 69, 1, 9, 17, 14, 1, 78, 7, 51, 95, 164, 13, 73, 29, 30, 20, 37, 14, 2, 3, 17, 12, 3, 9, 18, 4, 13, 32, 3, 45, 36, 37, 8, 13, 30, 8, 67, 52, 4, 8, 31, 18, 6, 6, 44, 31, 24, 3, 7, 18, 51, 4, 4, 8, 13, 26, 23, 19, 36, 33, 38, 8, 1, 37, 18, 7, 9, 12, 4, 30, 18, 49, 6, 13, 21, 7, 36, 46, 59, 4, 1, 10, 19, 18, 17, 1, 50, 51, 17, 56, 5, 59, 8, 7, 38, 29, 15, 26, 21, 52, 27, 1, 26, 3, 37, 18, 15, 46, 27, 61, 21, 8, 27, 10, 30, 4, 25, 7, 17, 24, 2, 9, 13, 37, 17, 13, 5, 16, 5, 2, 20, 25, 1, 14, 8, 1, 8, 35, 3, 16, 8, 26, 24, 51, 28, 10, 31, 6, 26, 21, 16, 17, 30, 2, 27, 20, 31, 7, 16, 5, 18, 6, 5, 11, 24, 1, 4, 27, 7, 22, 19, 15, 10, 33, 56, 57, 22, 13, 41, 8, 2, 3, 1, 7, 10, 4, 1, 22, 5, 12, 6, 5, 1, 13, 24, 28, 11, 27, 12, 44, 35, 5, 6, 10, 250, 18, 22, 13, 1, 192, 54, 71, 44, 223, 138, 3, 116, 81, 136, 31, 131, 36, 42, 59, 74, 72, 8, 3, 0, 16, 137, 54, 68, 3, 77, 72, 6, 83, 35, 28, 29, 10, 5, 28, 29, 8, 2, 25, 42, 6, 19, 20, 5, 29, 26, 41, 1, 10, 5, 30, 35, 32, 19, 22, 21, 12, 38, 63, 34, 5, 4, 37, 13, 40, 5, 23, 23, 58, 11, 27, 51, 5, 25, 8, 29, 36, 7, 10, 35, 22, 9, 1, 4, 2, 20, 9, 14, 16, 47, 2, 6, 15, 6, 26, 17, 3, 6, 18, 3, 6, 23, 8, 20, 10, 29, 6, 9, 11, 14, 26, 12, 21, 1, 14, 4, 19, 27, 28, 39, 56, 27, 3, 30, 19, 5, 9, 7, 18, 31, 38, 19, 42, 41, 10, 4, 27, 34, 19, 18, 7, 28, 8, 8, 13, 33, 17, 32, 10, 14, 11, 15, 14, 51, 5, 4, 1, 16, 5, 5, 1, 8, 9, 6, 4, 5, 1, 7, 8, 14, 3, 5, 20, 11, 4, 16, 3, 5, 20, 53, 0, 11, 10, 9, 5, 2, 8, 1, 6, 15, 16, 3, 0, 13, 2, 4, 16, 7, 12, 25, 16, 8, 21, 0, 18, 3, 11, 18, 11, 12, 5, 9, 3, 6, 11, 26, 15, 1, 14, 13, 18, 11, 0, 1, 12, 3, 5, 14, 5, 7, 8, 9, 8, 8, 23, 14, 21, 0, 8, 25, 16, 7, 7, 4, 13, 14, 8, 9, 3, 12, 0, 0, 7, 4, 6, 7, 2, 4, 3, 5, 10, 0, 5, 3, 10, 14, 9, 0, 0, 5, 0, 17, 24, 5, 9, 4, 7, 0, 30, 13, 4, 9, 10, 5, 0, 8, 21, 6, 4, 10, 3, 8, 21, 14, 7, 0, 3, 20, 7, 1, 3, 8, 7, 3, 0, 10, 5, 13, 12, 6, 3, 6, 4, 15, 18, 1, 0, 4, 7, 4, 1, 3, 1, 1, 2, 10, 11, 14, 0, 3, 3, 2, 1, 0, 2, 9, 2, 12, 5, 2, 0, 24, 25, 5, 0, 5, 12, 5, 11, 28, 5, 4, 0, 1, 2, 0, 16, 5, 15, 18, 3, 9, 8, 2, 4, 9, 11, 4, 0, 10, 7, 3, 8, 6, 0, 8, 15, 4, 17, 8, 3, 4, 0, 2, 22, 15, 6, 32, 20, 24, 3, 3, 20, 35, 22, 15, 12, 3, 42, 49, 4, 0, 8, 24, 2, 25, 17, 14, 20, 5, 25, 20, 13, 12, 14, 2, 21, 13, 9, 8, 12, 42, 3, 9, 11, 16, 12, 39, 8, 0, 54, 45, 12, 21, 10, 11, 16, 13, 24, 7, 34, 29, 9, 33, 44, 8, 37, 40, 13, 12, 19, 14, 19, 18, 0, 46, 7, 22, 11, 2, 12, 0, 39, 26, 8, 21, 24, 23, 12, 1, 2, 10, 17, 13, 0, 10, 3, 7, 1, 0, 23, 38, 0, 21, 13, 43, 6, 9, 8, 0, 17, 2, 10, 0, 0, 20, 13, 17, 44, 41, 12, 41, 4, 16, 37, 17, 16, 0, 15, 1, 12, 9, 15, 2, 16, 4, 6, 9, 8, 7, 15, 34, 17, 1, 2, 18, 25, 18, 9, 1, 14, 15, 20, 0, 16, 2, 54, 37, 16, 25, 14, 25, 22, 3, 8, 7, 1, 5, 3, 20, 16, 39, 50, 35, 14, 5, 3, 2, 1, 8, 18, 23, 8, 11, 6, 11, 16, 9, 0, 12, 12, 18, 114, 134, 22, 2, 8, 4, 10, 19, 22, 23, 115, 3, 124, 99, 122, 5, 21, 18, 3, 20, 1, 195, 98, 88, 6, 25, 36, 83, 64, 75, 30, 1, 4, 22, 77, 68, 23, 5, 34, 13, 21, 73, 40, 25, 0, 49, 1, 12, 24, 16, 7, 18, 21, 15, 61, 11, 11, 61, 38, 192, 147, 61, 90, 17, 77, 48, 144, 136, 11, 141, 110, 29, 12, 6, 21, 137, 172, 4, 57, 3, 72, 35, 3, 109, 124, 65, 1, 70, 5, 10, 43, 24, 22, 89, 56, 23, 42, 53, 68, 13, 21, 11, 40, 13, 16, 26, 3, 39, 41, 21, 98, 43, 39, 17, 41, 30, 0, 8, 61, 36, 29, 4, 18, 2, 20, 41, 18, 16, 9, 8, 41, 54, 41, 26, 9, 63, 39, 28, 24, 33, 32, 6, 45, 1, 10, 3, 6, 17, 43, 13, 19, 16, 11, 12, 3, 9, 2, 14, 7, 1, 7, 10, 17, 8, 1, 8, 8, 29, 55, 15, 9, 18, 15, 7, 3, 12, 8, 18, 13, 10, 1, 3, 7, 11, 20, 2, 7, 13, 24, 19, 16, 7, 4, 7, 10, 5, 18, 9, 16, 19, 4, 38, 12, 8, 27, 20, 20, 21, 18, 15, 6, 12, 7, 4, 0, 4, 0, 9, 12, 1, 8, 11, 3, 15, 34, 1, 3, 43, 11, 0, 18, 7, 3, 5, 8, 2, 7, 19, 26, 15, 6, 14, 19, 10, 17, 5, 10, 30, 18, 1, 61, 60, 45, 20, 106, 111, 78, 133, 192, 253, 158, 45, 88, 125, 39, 102, 229, 128, 59, 122, 0, 27, 27, 30, 47, 48, 23, 41, 20, 6, 10, 24, 36, 13, 49, 15, 42, 22, 51, 1, 32, 25, 18, 7, 53, 91, 8, 2, 24, 4, 13, 0, 8, 16, 67, 68, 25, 5, 22, 7, 12, 3, 15, 10, 16, 21, 9, 8, 22, 0, 17, 4, 20, 11, 5, 4, 35, 40, 15, 17, 8, 22, 11, 3, 0, 10, 6, 21, 5, 32, 17, 14, 13, 12, 11, 15, 24, 25, 4, 20, 7, 1, 27, 14, 23, 5, 8, 17, 10, 26, 5, 29, 26, 0, 10, 6, 13, 15, 14, 7, 16, 19, 2, 8, 17, 4, 32, 21, 6, 6, 5, 9, 12, 1, 0, 7, 2, 11, 16, 7, 6, 11, 0, 14, 5, 7, 24, 2, 17, 16, 9, 12, 9, 18, 13, 13, 8, 1, 0, 8, 33, 2, 14, 6, 8, 8, 7, 6, 11, 2, 4, 3, 0, 2, 2, 7, 6, 13, 3, 2, 26, 17, 10, 11, 12, 3, 13, 10, 12, 3, 9, 1, 6, 21, 26, 11, 20, 7, 11, 0, 6, 1, 10, 0, 7, 1, 10, 13, 14, 13, 24, 31, 38, 7, 32, 6, 4, 0, 22, 35, 14, 1, 20, 7, 27, 0, 1, 16, 4, 21, 9, 44, 5, 6, 3, 19, 8, 1, 10, 50, 64, 43, 161, 160, 8, 10, 12, 71, 26, 46, 33, 8, 22, 21, 4, 28, 2, 19, 25, 28, 14, 1, 20, 7, 7, 18, 11, 7, 1, 57, 34, 34, 8, 53, 7, 3, 53, 67, 20, 24, 31, 15, 20, 21, 24, 51, 48, 28, 99, 106, 49, 74, 39, 33, 84, 38, 91, 50, 3, 65, 8, 38, 3, 28, 11, 35, 23, 1, 16, 5, 18, 18, 2, 6, 1, 77, 22, 30, 32, 6, 101, 1, 58, 53, 54, 43, 47, 56, 106, 67, 4, 47, 34, 24, 28, 15, 11, 38, 20, 117, 31, 8, 38, 6, 16, 18, 99, 52, 17, 8, 54, 28, 2, 19, 28, 51, 33, 0, 11, 48, 32, 47, 22, 14, 23, 77, 35, 11, 38, 0, 15, 2, 26, 0, 13, 24, 0, 6, 19, 13, 14, 21, 17, 58, 10, 31, 21, 9, 14, 1, 28, 25, 25, 31, 68, 4, 13, 1, 3, 6, 5, 2, 12, 0, 8, 0, 10, 3, 5, 32, 23, 23, 18, 1, 3, 12, 41, 55, 23, 2, 7, 12, 3, 6, 3, 9, 7, 22, 0, 2, 16, 15, 9, 4, 15, 15, 32, 2, 9, 0, 0, 34, 29, 3, 8, 10, 11, 32, 21, 23, 38, 11, 3, 10, 3, 19, 16, 1, 2, 12, 2, 19, 25, 38, 19, 12, 17, 0, 16, 14, 23, 4, 14, 9, 36, 63, 11, 20, 7, 13, 22, 27, 2, 15, 12, 4, 11, 22, 9, 3, 4, 7, 11, 14, 8, 16, 35, 6, 22, 0, 11, 2, 3, 8, 9, 1, 9, 18, 17, 20, 7, 5, 14, 48, 45, 11, 36, 10, 31, 19, 16, 8, 13, 8, 4, 3, 0, 9, 2, 0, 14, 7, 8, 5, 4, 14, 19, 7, 2, 20, 32, 33, 44, 41, 15, 74, 96, 48, 44, 22, 28, 23, 29, 24, 4, 18, 5, 41, 42, 8, 9, 24, 7, 22, 19, 8, 4, 3, 9, 6, 4, 47, 14, 6, 38, 63, 22, 12, 59, 60, 27, 53, 38, 12, 43, 15, 11, 62, 43, 10, 73, 74, 40, 9, 7, 51, 12, 40, 9, 10, 7, 14, 1, 14, 16, 59, 0, 32, 11, 21, 12, 27, 46, 14, 8, 37, 42, 129, 92, 15, 27, 0, 27, 38, 8, 131, 86, 64, 4, 46, 63, 64, 99, 16, 64, 95, 29, 60, 85, 88, 21, 26, 6, 55, 72, 89, 128, 47, 86, 3, 33, 83, 37, 58, 49, 1, 65, 132, 17, 0, 54, 28, 87, 25, 1, 30, 86, 59, 90, 111, 21, 12, 38, 8, 28, 21, 39, 9, 19, 72, 57, 14, 58, 68, 89, 71, 92, 52, 113, 86, 15, 65, 20, 18, 33, 14, 39, 21, 46, 17, 19, 11, 6, 4, 2, 18, 10, 7, 4, 20, 33, 14, 16, 43, 32, 21, 2, 20, 23, 91, 40, 1, 17, 15, 36, 11, 23, 8, 6, 33, 12, 8, 0, 8, 81, 12, 32, 28, 45, 1, 17, 2, 12, 1, 5, 7, 13, 34, 13, 14, 15, 23, 14, 18, 31, 8, 10, 4, 19, 0, 2, 2, 10, 9, 1, 1, 0, 0, 1, 4, 7, 14, 3, 1, 4, 3, 10, 11, 12, 50, 32, 21, 15, 20, 60, 5, 69, 15, 38, 45, 32, 36, 39, 154, 10, 52, 29, 34, 45, 20, 14, 8, 33, 12, 2, 4, 3, 5, 13, 10, 2, 3, 18, 15, 13, 20, 11, 16, 65, 93, 7, 23, 3, 28, 23, 16, 23, 14, 33, 12, 5, 15, 16, 42, 66, 29, 0, 36, 63, 49, 4, 22, 28, 43, 82, 32, 103, 70, 20, 15, 25, 2, 32, 25, 10, 19, 1, 43, 27, 14, 9, 5, 10, 2, 1, 6, 2, 13, 9, 9, 20, 13, 14, 32, 72, 75, 150, 18, 95, 64, 31, 117, 112, 109, 98, 100, 10, 29, 42, 115, 100, 19, 33, 81, 98, 105, 96, 36, 41, 8, 53, 16, 18, 140, 67, 33, 19, 23, 20, 14, 7, 10, 1, 9, 25, 10, 7, 44, 9, 21, 20, 9, 0, 26, 47, 8, 25, 14, 17, 18, 5, 83, 2, 4, 13, 2, 8, 1, 17, 0, 4, 1, 7, 2, 15, 10, 0, 3, 13, 18, 6, 19, 4, 0, 1, 20, 7, 7, 3, 12, 7, 11, 12, 2, 5, 18, 19, 2, 8, 17, 34, 19, 12, 14, 21, 9, 0, 6, 4, 7, 6, 4, 27, 38, 17, 11, 20, 9, 19, 16, 16, 25, 26, 1, 3, 8, 1, 5, 7, 20, 0, 9, 10, 33, 1, 12, 17, 14, 9, 0, 10, 1, 0, 1, 14, 25, 1, 7, 2, 18, 19, 20, 3, 19, 2, 6, 18, 9, 5, 8, 9, 0, 0, 6, 4, 5, 1, 6, 2, 3, 1, 12, 17, 0, 11, 4, 8, 17, 8, 3, 12, 15, 0, 16, 3, 5, 1, 9, 14, 5, 6, 11, 4, 31, 32, 3, 9, 1, 0, 8, 3, 1, 1, 6, 5, 0, 4, 0, 2, 18, 5, 0, 11, 4, 6, 2, 19, 4, 3, 2, 12, 0, 2, 10, 13, 0, 8, 13, 7, 22, 8, 1, 2, 2, 2, 7, 8, 11, 4, 11, 20, 10, 25, 8, 2, 7, 1, 2, 2, 12, 13, 4, 9, 16, 13, 18, 7, 21, 10, 5, 10, 2, 9, 16, 11, 5, 2, 6, 7, 12, 7, 6, 15, 10, 5, 8, 7, 2, 6, 8, 0, 9, 10, 4, 2, 3, 9, 12, 4, 3, 12, 5, 0, 10, 7, 19, 24, 15, 0, 8, 7, 14, 2, 5, 21, 16, 3, 1, 18, 9, 5, 10, 5, 4, 2, 4, 14, 33, 14, 12, 5, 2, 2, 17, 7, 16, 2, 7, 10, 15, 156, 118, 69, 26, 117, 128, 97, 81, 50, 98, 97, 2, 88, 105, 96, 36, 221, 78, 40, 116, 1, 35, 9, 15, 95, 2, 6, 7, 21, 36, 7, 40, 19, 8, 17, 7, 16, 2, 17, 22, 6, 21, 24, 5, 17, 18, 29, 4, 10, 29, 15, 18, 9, 19, 22, 8, 32, 31, 12, 39, 34, 5, 47, 3, 22, 18, 20, 5, 12, 41, 46, 15, 83, 4, 6, 13, 18, 6, 17, 2, 12, 10, 25, 10, 21, 0, 1, 20, 9, 15, 24, 6, 19, 14, 0, 2, 13, 2, 3, 26, 27, 15, 32, 16, 8, 11, 1, 6, 17, 28, 20, 9, 9, 31, 12, 20, 4, 8, 26, 23, 1, 11, 32, 65, 0, 7, 56, 31, 18, 25, 32, 5, 22, 3, 9, 5, 18, 35, 34, 31, 12, 7, 36, 29, 14, 11, 16, 6, 11, 44, 43, 2, 58, 35, 3, 34, 16, 28, 14, 17, 6, 1, 20, 3, 21, 13, 12, 4, 16, 17, 8, 19, 24, 14, 23, 12, 5, 0, 7, 4, 31, 38, 15, 6, 7, 4, 10, 11, 0, 27, 10, 12, 30, 13, 2, 5, 12, 13, 34, 7, 29, 12, 20, 11, 28, 17, 29, 22, 5, 17, 22, 5, 16, 23, 43, 46, 2, 3, 8, 0, 10, 15, 17, 51, 5, 18, 13, 0, 6, 9, 4, 7, 8, 9, 10, 4, 34, 27, 6, 3, 20, 17, 0, 18, 1, 1, 10, 29, 14, 5, 18, 20, 8, 16, 11, 1, 7, 24, 37, 23, 9, 8, 11, 3, 1, 8, 14, 13, 7, 12, 0, 13, 10, 1, 11, 3, 20, 21, 8, 6, 6, 13, 6, 1, 1, 22, 23, 7, 10, 1, 11, 8, 4, 3, 3, 8, 35, 3, 2, 1, 12, 11, 4, 1, 2, 6, 14, 1, 17, 4, 9, 2, 1, 1, 8, 4, 11, 1, 8, 2, 17, 2, 7, 12, 3, 5, 4, 8, 3, 0, 8, 9, 11, 18, 17, 10, 7, 10, 13, 4, 12, 2, 0, 8, 7, 3, 6, 5, 8, 11, 4, 1, 16, 3, 11, 10, 5, 0, 8, 5, 4, 4, 5, 1, 2, 15, 12, 0, 18, 13, 0, 10, 11, 4, 0, 2, 9, 4, 1, 3, 6, 7, 2, 0, 8, 3, 2, 1, 18, 19, 1, 9, 8, 22, 23, 4, 4, 3, 3, 6, 18, 13, 7, 6, 11, 16, 4, 5, 0, 0, 1, 2, 7, 10, 4, 10, 29, 8, 10, 11, 1, 18, 5, 10, 0, 7, 9, 4, 4, 3, 7, 10, 102, 48, 103, 16, 74, 30, 21, 16, 145, 136, 62, 37, 7, 39, 43, 156, 53, 26, 1, 4, 113, 43, 114, 8, 67, 52, 26, 50, 58, 7, 29, 38, 65, 48, 23, 59, 2, 30, 8, 4, 13, 7, 5, 9, 2, 42, 19, 19, 23, 16, 24, 41, 34, 41, 73, 19, 20, 35, 20, 18, 1, 3, 17, 10, 1, 7, 13, 38, 4, 27, 19, 28, 15, 32, 3, 7, 10, 26, 43, 2, 9, 36, 5, 7, 13, 28, 7, 18, 7, 23, 7, 30, 17, 13, 23, 28, 14, 15, 14, 3, 15, 4, 12, 26, 29, 7, 32, 7, 27, 5, 30, 39, 12, 34, 8, 17, 13, 14, 35, 36, 10, 25, 16, 11, 4, 1, 21, 28, 4, 43, 56, 29, 23, 22, 4, 0, 1, 22, 21, 40, 63, 28, 70, 63, 72, 55, 28, 19, 52, 15, 1, 34, 12, 32, 7, 42, 9, 6, 1, 25, 22, 3, 2, 5, 35, 12, 20, 6, 16, 1, 37, 7, 6, 8, 26, 9, 3, 20, 7, 35, 38, 2, 45, 10, 20, 11, 7, 18, 5, 12, 51, 32, 36, 7, 23, 16, 4, 4, 5, 11, 4, 27, 20, 32, 15, 7, 18, 71, 11, 20, 25, 13, 20, 19, 17, 24, 10, 23, 65, 22, 23, 4, 19, 36, 30, 15, 27, 10, 11, 9, 8, 19, 12, 9, 6, 7, 18, 8, 4, 2, 5, 18, 13, 11, 8, 0, 9, 13, 32, 11, 4, 6, 2, 13, 0, 23, 24, 7, 9, 3, 28, 4, 9, 16, 31, 12, 5, 15, 21, 7, 6, 0, 2, 5, 18, 0, 13, 1, 12, 17, 2, 22, 2, 11, 8, 9, 18, 23, 3, 1, 19, 36, 9, 4, 11, 8, 1, 14, 21, 1, 10, 25, 86, 12, 58, 133, 142, 23, 27, 34, 71, 77, 34, 46, 23, 28, 116, 147, 142, 141, 44, 170, 2, 201, 18, 41, 17, 152, 155, 14, 160, 82, 125, 107, 25, 2, 1, 55, 129, 13, 64, 126, 177, 60, 122, 30, 7, 1, 13, 134, 72, 181, 80, 26, 74, 12, 123, 50, 87, 0, 48, 37, 29, 24, 21, 102, 88, 143, 134, 33, 108, 123, 59, 24, 61, 96, 21, 16, 83, 45, 38, 178, 165, 156, 28, 79, 132, 101, 13, 55, 32, 73, 19, 31, 130, 78, 153, 144, 46, 81, 109, 5, 29, 128, 121, 71, 108, 27, 30, 13, 23, 86, 34, 84, 83, 29, 19, 125, 66, 51, 2, 1, 103, 81, 41, 23, 254, 97, 95, 61, 33, 122, 127, 62, 0, 29, 27, 58, 1, 217, 44, 95, 31, 10, 4, 6, 5, 31, 18, 9, 2, 7, 12, 1, 29, 32, 237, 134, 1, 42, 61, 6, 123, 132, 95, 65, 70, 35, 18, 47, 76, 29, 55, 8, 170, 47, 67, 5, 26, 176, 63, 179, 5, 138, 32, 33, 82, 203, 42, 70, 44, 145, 7, 20, 110, 114, 36, 15, 207, 234, 141, 17, 118, 7, 177, 45, 160, 79, 88, 93, 62, 86, 40, 50, 35, 4, 61, 205, 70, 50, 55, 42, 43, 206, 2, 101, 59, 174, 133, 44, 191, 158, 8, 43, 23, 16, 4, 4, 32, 2, 37, 25, 32, 14, 19, 20, 25, 4, 25, 29, 16, 10, 17, 57, 29, 7, 5, 15, 6, 7, 12, 3, 12, 1, 2, 1, 6, 8, 32, 6, 53, 38, 21, 21, 26, 15, 8, 4, 6, 3, 2, 3, 1, 10, 7, 19, 20, 13, 0, 8, 0, 22, 13, 14, 1, 0, 6, 15, 5, 10, 7, 8, 0, 1, 14, 13, 12, 31, 6, 8, 28, 33, 0, 21, 28, 5, 18, 1, 0, 10, 19, 21, 11, 0, 7, 18, 19, 12, 0, 7, 7, 3, 4, 20, 15, 10, 11, 10, 27, 16, 16, 1, 11, 2, 7, 24, 8, 7, 11, 13, 16, 1, 13, 6, 12, 13, 18, 23, 6, 12, 2, 23, 28, 11, 19, 18, 0, 4, 10, 11, 14, 3, 5, 5, 9, 1, 22, 17, 12, 5, 8, 23, 36, 3, 13, 1, 12, 4, 5, 11, 3, 6, 14, 9, 3, 7, 18, 6, 10, 21, 10, 19, 4, 54, 31, 28, 0, 31, 20, 4, 11, 25, 30, 13, 30, 25, 8, 3, 23, 52, 0, 8, 27, 36, 31, 36, 3, 13, 16, 7, 7, 7, 9, 2, 16, 15, 1, 8, 9, 11, 0, 10, 8, 13, 0, 6, 3, 21, 16, 4, 6, 13, 4, 1, 166, 124, 125, 174, 19, 39, 59, 18, 64, 89, 2, 19, 63, 42, 63, 65, 18, 31, 10, 2, 28, 32, 63, 9, 25, 12, 12, 0, 44, 27, 2, 16, 9, 10, 5, 14, 17, 120, 121, 130, 123, 2, 7, 11, 34, 246, 31, 47, 63, 62, 88, 2, 12, 5, 135, 142, 239, 164, 115, 120, 74, 1, 21, 10, 119, 5, 66, 141, 240, 59, 95, 84, 8, 20, 207, 206, 133, 8, 136, 207, 190, 12, 47, 48, 26, 43, 57, 86, 7, 125, 134, 115, 104, 2, 23, 43, 3, 66, 137, 34, 27, 8, 16, 27, 4, 19, 12, 28, 27, 11, 0, 8, 15, 10, 20, 17, 33, 15, 17, 37, 0, 3, 14, 3, 10, 0, 4, 13, 18, 9, 21, 6, 12, 1, 12, 0, 9, 27, 3, 24, 24, 17, 15, 8, 48, 31, 162, 89, 1, 29, 35, 178, 171, 7, 4, 96, 37, 37, 25, 116, 91, 44, 30, 111, 46, 5, 13, 46, 64, 95, 46, 25, 12, 32, 5, 21, 35, 5, 38, 20, 17, 43, 48, 52, 65, 31, 128, 63, 15, 57, 14, 7, 96, 2, 76, 137, 57, 132, 79, 47, 166, 7, 127, 114, 141, 112, 29, 31, 44, 64, 1, 49, 48, 56, 149, 124, 99, 208, 239, 56, 26, 27, 93, 120, 39, 8, 55, 0, 15, 2, 5, 20, 16, 1, 25, 24, 13, 2, 28, 15, 4, 8, 6, 21, 9, 7, 42, 33, 15, 18, 6, 11, 39, 38, 33, 38, 21, 7, 18, 10, 21, 19, 8, 0, 16, 7, 2, 3, 12, 15, 3, 18, 10, 81, 9, 10, 8, 0, 11, 16, 17, 3, 42, 29, 13, 10, 48, 29, 10, 7, 6, 5, 27, 30, 23, 20, 15, 40, 4, 49, 11, 34, 14, 9, 74, 62, 41, 70, 55, 42, 81, 120, 141, 50, 105, 122, 85, 32, 11, 118, 14, 12, 6, 35, 47, 14, 11, 4, 4, 9, 6, 2, 12, 11, 21, 4, 0, 6, 10, 17, 2, 2, 3, 16, 13, 17, 7, 14, 26, 19, 32, 5, 14, 21, 12, 43, 47, 7, 7, 6, 10, 21, 16, 21, 18, 15, 4, 1, 2, 0, 0, 6, 1, 3, 4, 10, 25, 12, 11, 4, 4, 9, 6, 2, 27, 7, 28, 14, 6, 1, 7, 5, 19, 7, 18, 13, 12, 3, 5, 3, 28, 19, 3, 2, 7, 12, 5, 14, 25, 16, 5, 11, 12, 0, 3, 3, 2, 1, 4, 7, 8, 2, 4, 17, 12, 2, 0, 17, 48, 152, 97, 15, 49, 176, 93, 53, 40, 6, 81, 54, 45, 36, 144, 9, 16, 157, 212, 19, 24, 59, 39, 56, 69, 47, 96, 9, 30, 139, 106, 48, 8, 16, 5, 19, 19, 10, 6, 2, 6, 45, 34, 15, 32, 21, 22, 39, 2, 44, 11, 27, 18, 57, 43, 21, 3, 16, 16, 35, 20, 0, 1, 2, 21, 21, 4, 8, 20, 33, 24, 7, 18, 13, 13, 41, 3, 5, 40, 29, 6, 3, 2, 1, 5, 13, 12, 7, 1, 16, 3, 130, 98, 10, 130, 181, 68, 21, 46, 104, 3, 40, 93, 3, 25, 36, 52, 0, 181, 176, 207, 20, 3, 111, 218, 58, 17, 53, 23, 68, 82, 19, 127, 118, 4, 21, 7, 8, 1, 35, 68, 25, 6, 25, 17, 22, 23, 60, 29, 15, 19, 54, 11, 89, 126, 27, 3, 29, 1, 32, 71, 113, 32, 31, 11, 16, 33, 4, 34, 59, 32, 32, 55, 14, 1, 29, 22, 55, 68, 115, 12, 31, 98, 87, 4, 18, 0, 24, 10, 33, 48, 9, 17, 50, 11, 23, 9, 38, 25, 5, 20, 25, 13, 34, 25, 37, 66, 7, 0, 20, 25, 16, 20, 47, 44, 55, 4, 38, 37, 14, 1, 85, 8, 2, 8, 17, 16, 13, 40, 45, 16, 19, 16, 11, 22, 7, 18, 3, 23, 14, 21, 18, 15, 4, 12, 13, 0, 8, 1, 2, 7, 14, 2, 0, 29, 30, 25, 13, 14, 6, 9, 12, 7, 5, 18, 1, 6, 11, 3, 1, 27, 5, 20, 19, 6, 8, 3, 0, 7, 3, 8, 24, 23, 7, 0, 2, 0, 8, 0, 18, 19, 1, 14, 1, 50, 116, 1, 21, 28, 21, 82, 47, 85, 80, 17, 27, 0, 23, 23, 14, 13, 3, 20, 10, 11, 20, 47, 38, 28, 8, 35, 4, 23, 8, 6, 6, 11, 19, 27, 4, 48, 26, 29, 5, 2, 5, 2, 31, 22, 23, 0, 8, 40, 13, 19, 21, 26, 20, 33, 0, 30, 29, 37, 8, 19, 34, 0, 11, 17, 16, 5, 17, 18, 21, 2, 30, 23, 0, 4, 4, 21, 26, 1, 10, 11, 24, 5, 33, 12, 12, 9, 5, 16, 0, 17, 14, 3, 11, 9, 8, 2, 16, 8, 13, 6, 7, 24, 0, 17, 6, 5, 12, 4, 9, 1, 4, 3, 5, 6, 5, 4, 5, 4, 2, 2, 2, 6, 13, 15, 12, 3, 14, 1, 4, 5, 9, 32, 9, 11, 14, 0, 11, 9, 18, 3, 5, 12, 2, 15, 18, 7, 3, 2, 9, 9, 6, 10, 13, 0, 14, 13, 5, 12, 3, 40, 39, 16, 13, 16, 3, 8, 6, 0, 19, 14, 6, 13, 16, 4, 17, 1, 14, 4, 2, 23, 1, 3, 32, 19, 3, 8, 16, 17, 4, 10, 11, 12, 23, 18, 4, 5, 10, 23, 18, 11, 7, 14, 2, 4, 19, 4, 0, 16, 15, 18, 25, 7, 28, 15, 0, 4, 2, 2, 16, 17, 24, 21, 16, 3, 23, 12, 4, 9, 20, 56, 9, 2, 13, 66, 55, 54, 22, 5, 1, 22, 61, 28, 4, 1, 34, 57, 12, 6, 39, 1, 76, 41, 74, 127, 5, 6, 5, 8, 6, 10, 9, 18, 30, 16, 216, 67, 176, 6, 57, 191, 218, 40, 14, 17, 39, 33, 12, 3, 5, 8, 70, 31, 7, 20, 19, 33, 48, 8, 51, 50, 16, 9, 33, 39, 42, 45, 36, 1, 17, 14, 71, 1, 47, 3, 24, 16, 31, 30, 26, 19, 20, 15, 15, 13, 9, 10, 20, 15, 13, 52, 0, 6, 53, 2, 4, 10, 17, 38, 41, 3, 17, 30, 8, 29, 40, 51, 20, 56, 1, 27, 25, 24, 20, 17, 7, 0, 2, 4, 43, 21, 121, 20, 30, 26, 20, 87, 1, 33, 44, 61, 46, 7, 2, 4, 25, 21, 56, 29, 4, 1, 15, 8, 4, 0, 9, 44, 47, 112, 123, 7, 36, 22, 17, 38, 11, 32, 29, 68, 59, 38, 73, 76, 51, 6, 25, 52, 19, 6, 38, 81, 56, 18, 51, 20, 24, 54, 95, 16, 14, 3, 13, 27, 44, 25, 31, 7, 12, 2, 18, 49, 46, 25, 7, 9, 26, 37, 0, 76, 53, 11, 2, 21, 32, 56, 51, 40, 51, 17, 36, 47, 50, 3, 2, 15, 44, 54, 37, 49, 3, 58, 73, 7, 38, 0, 18, 52, 61, 7, 6, 8, 33, 22, 6, 1, 35, 42, 25, 66, 43, 6, 57, 20, 18, 12, 22, 15, 31, 9, 28, 23, 16, 8, 30, 57, 14, 7, 2, 12, 1, 12, 5, 6, 15, 30, 7, 28, 35, 3, 54, 19, 4, 71, 5, 17, 68, 63, 34, 5, 13, 82, 107, 0, 0, 4, 28, 18, 1, 53, 48, 7, 9, 23, 92, 35, 32, 43, 3, 16, 11, 21, 56, 15, 61, 46, 7, 60, 47, 2, 66, 33, 36, 21, 41, 52, 23, 20, 77, 9, 16, 6, 8, 0, 29, 60, 172, 2, 42, 11, 23, 0, 17, 34, 37, 10, 10, 8, 27, 24, 27, 13, 8, 26, 12, 23, 16, 6, 27, 0, 6, 29, 12, 42, 35, 23, 16, 6, 15, 6, 5, 4, 3, 13, 51, 10, 32, 8, 8, 14, 13, 25, 34, 21, 20, 55, 23, 24, 23, 6, 0, 9, 3, 12, 31, 34, 3, 20, 25, 18, 20, 27, 9, 8, 6, 1, 0, 23, 14, 4, 15, 12, 20, 43, 9, 8, 0, 34, 5, 2, 6, 7, 1, 22, 23, 3, 20, 2, 3, 0, 0, 11, 6, 10, 15, 10, 1, 1, 0, 5, 4, 7, 1, 10, 8, 2, 6, 8, 19, 1, 4, 14, 11, 12, 15, 8, 2, 7, 8, 1, 13, 1, 16, 4, 21, 8, 9, 16, 6, 7, 7, 18, 13, 8, 2, 11, 12, 2, 0, 1, 34, 57, 8, 5, 1, 5, 22, 21, 0, 23, 10, 4, 2, 10, 10, 4, 59, 29, 10, 9, 14, 13, 16, 11, 2, 9, 14, 6, 23, 26, 5, 14, 5, 6, 16, 16, 15, 9, 16, 9, 6, 10, 13, 14, 25, 8, 4, 14, 11, 2, 8, 7, 20, 5, 5, 10, 23, 14, 2, 7, 16, 1, 5, 2, 21, 4, 40, 19, 27, 5, 18, 2, 32, 17, 2, 17, 13, 12, 35, 12, 4, 24, 6, 9, 12, 9, 12, 41, 10, 8, 42, 15, 5, 4, 15, 8, 10, 0, 25, 22, 1, 5, 8, 6, 3, 4, 15, 4, 8, 3, 9, 9, 20, 5, 17, 32, 13, 16, 7, 11, 22, 3, 9, 1, 11, 2, 14, 21, 30, 4, 23, 12, 7, 10, 21, 18, 5, 26, 13, 19, 20, 9, 12, 4, 19, 8, 10, 25, 4, 22, 27, 36, 1, 21, 11, 19, 26, 15, 39, 8, 7, 8, 3, 3, 0, 17, 10, 1, 18, 13, 6, 1, 5, 5, 8, 4, 0, 2, 10, 9, 21, 0, 13, 26, 1, 26, 0, 27, 28, 31, 2, 8, 7, 6, 7, 13, 18, 13, 4, 22, 15, 14, 1, 178, 19, 24, 52, 104, 71, 40, 55, 80, 35, 11, 79, 168, 141, 10, 106, 6, 72, 135, 101, 30, 25, 9, 116, 47, 44, 39, 50, 103, 118, 225, 110, 14, 36, 23, 17, 131, 91, 88, 111, 46, 15, 0, 19, 5, 58, 39, 20, 30, 93, 52, 16, 6, 11, 71, 96, 4, 13, 51, 13, 5, 22, 11, 7, 48, 4, 1, 230, 53, 6, 152, 10, 9, 219, 72, 140, 131, 227, 236, 56, 33, 1, 1, 120, 134, 5, 1, 56, 23, 152, 141, 170, 30, 3, 28, 116, 61, 38, 16, 4, 14, 4, 5, 3, 13, 18, 37, 195, 44, 146, 161, 192, 8, 0, 43, 11, 20, 9, 2, 29, 72, 71, 5, 26, 29, 32, 11, 23, 6, 52, 43, 18, 23, 2, 62, 92, 93, 59, 5, 10, 19, 19, 52, 23, 0, 130, 155, 24, 22, 19, 84, 43, 19, 22, 5, 26, 33, 36, 15, 25, 54, 63, 5, 16, 17, 27, 2, 12, 24, 37, 30, 39, 19, 214, 123, 12, 81, 20, 52, 22, 45, 51, 62, 3, 1, 0, 27, 31, 60, 34, 33, 26, 19, 5, 15, 19, 28, 49, 22, 4, 20, 27, 2, 26, 23, 31, 14, 28, 7, 186, 4, 133, 0, 21, 8, 13, 13, 40, 65, 18, 8, 39, 32, 25, 2, 36, 5, 19, 10, 14, 33, 128, 52, 141, 9, 4, 29, 140, 123, 40, 25, 15, 4, 5, 12, 9, 27, 128, 3, 77, 71, 15, 14, 35, 28, 128, 17, 83, 174, 12, 155, 7, 6, 0, 53, 56, 9, 19, 10, 45, 138, 109, 23, 19, 7, 72, 56, 58, 97, 8, 7, 33, 4, 14, 120, 12, 8, 0, 13, 10, 81, 2, 76, 51, 103, 40, 10, 19, 146, 2, 15, 17, 16, 37, 30, 25, 44, 19, 12, 19, 14, 16, 9, 2, 15, 9, 16, 16, 33, 105, 29, 44, 22, 30, 103, 2, 5, 66, 4, 53, 60, 40, 35, 104, 105, 93, 132, 42, 101, 74, 9, 63, 134, 2, 83, 10, 7, 44, 16, 30, 29, 14, 67, 66, 25, 5, 32, 39, 6, 1, 28, 35, 30, 25, 24, 6, 19, 10, 2, 28, 15, 25, 1, 30, 27, 49, 81, 88, 67, 12, 17, 27, 7, 11, 22, 12, 31, 11, 4, 109, 11, 38, 45, 22, 6, 33, 132, 60, 4, 42, 29, 49, 50, 45, 46, 11, 35, 1, 17, 28, 21, 46, 45, 60, 57, 30, 4, 4, 73, 12, 38, 3, 30, 71, 95, 34, 45, 28, 15, 42, 11, 23, 48, 2, 8, 45, 39, 30, 15, 6, 74, 23, 55, 32, 15, 13, 38, 73, 1, 10, 2, 0, 12, 12, 37, 0, 9, 0, 14, 15, 1, 9, 22, 23, 16, 4, 17, 14, 12, 0, 11, 8, 16, 1, 5, 10, 3, 1, 2, 9, 0, 2, 0, 10, 5, 6, 0, 4, 5, 11, 2, 8, 10, 11, 0, 2, 3, 0, 2, 9, 12, 5, 8, 7, 8, 17, 14, 0, 11, 22, 27, 18, 25, 22, 14, 23, 18, 0, 4, 13, 12, 11, 16, 3, 17, 1, 8, 13, 22, 11, 12, 29, 16, 0, 6, 8, 1, 6, 7, 5, 84, 21, 0, 142, 84, 125, 3, 35, 67, 110, 45, 39, 88, 25, 3, 30, 17, 10, 18, 29, 5, 16, 49, 1, 18, 64, 96, 43, 41, 16, 21, 85, 1, 26, 14, 7, 10, 29, 0, 6, 0, 17, 9, 22, 7, 39, 100, 25, 5, 24, 25, 22, 15, 33, 50, 14, 27, 10, 54, 16, 43, 39, 7, 8, 35, 18, 5, 18, 24, 21, 6, 2, 28, 59, 34, 1, 8, 6, 19, 44, 67, 30, 6, 8, 5, 11, 22, 24, 29, 17, 1, 16, 6, 5, 20, 35, 26, 5, 23, 23, 29, 45, 6, 12, 33, 1, 0, 34, 55, 40, 23, 32, 2, 37, 52, 9, 3, 35, 40, 25, 7, 1, 30, 27, 20, 0, 26, 33, 5, 3, 36, 9, 2, 58, 21, 67, 12, 23, 26, 2, 7, 16, 11, 10, 12, 2, 33, 20, 20, 53, 86, 55, 39, 56, 17, 60, 5, 15, 21, 21, 0, 62, 45, 9, 9, 3, 4, 28, 21, 6, 54, 47, 1, 3, 16, 15, 26, 3, 11, 18, 37, 6, 7, 11, 80, 81, 1, 22, 13, 18, 64, 63, 7, 32, 52, 59, 0, 34, 18, 25, 20, 23, 17, 58, 47, 2, 30, 5, 32, 25, 0, 19, 7, 1, 4, 17, 34, 26, 25, 9, 2, 7, 12, 6, 11, 3, 26, 29, 30, 4, 11, 14, 25, 20, 13, 10, 35, 36, 43, 8, 44, 37, 36, 17, 13, 28, 18, 81, 44, 3, 12, 30, 19, 31, 32, 21, 64, 1, 51, 1, 222, 169, 66, 155, 22, 29, 62, 22, 1, 255, 33, 31, 10, 218, 151, 142, 76, 23, 1, 168, 109, 19, 37, 62, 41, 112, 143, 126, 100, 37, 175, 220, 46, 34, 33, 6, 18, 2, 1, 7, 61, 40, 42, 49, 24, 22, 16, 12, 37, 39, 111, 18, 6, 41, 9, 6, 88, 123, 94, 53, 17, 9, 26, 33, 28, 53, 40, 55, 29, 1, 18, 15, 57, 24, 20, 17, 0, 5, 16, 15, 0, 8, 1, 18, 1, 13, 27, 28, 4, 78, 105, 158, 45, 107, 88, 20, 76, 56, 47, 161, 24, 116, 0, 3, 1, 20, 37, 4, 8, 41, 65, 4, 31, 0, 8, 16, 13, 22, 6, 7, 11, 0, 9, 16, 9, 11, 4, 4, 20, 11, 1, 9, 10, 3, 23, 34, 39, 13, 16, 7, 12, 3, 0, 1, 7, 5, 3, 12, 1, 0, 3, 13, 14, 8, 4, 19, 2, 3, 18, 5, 1, 1, 8, 5, 24, 27, 2, 14, 0, 10, 3, 11, 9, 1, 1, 1, 4, 26, 21, 170, 83, 36, 1, 83, 46, 137, 166, 1, 15, 65, 29, 25, 10, 48, 31, 16, 4, 21, 7, 11, 50, 41, 26, 3, 33, 0, 1, 44, 39, 14, 11, 16, 15, 89, 5, 13, 0, 16, 12, 17, 32, 0, 69, 8, 18, 1, 12, 27, 12, 6, 20, 47, 18, 7, 20, 29, 10, 14, 6, 23, 24, 6, 9, 5, 2, 6, 6, 29, 15, 70, 43, 26, 21, 11, 14, 3, 18, 19, 27, 36, 11, 11, 2, 36, 15, 19, 40, 49, 50, 17, 15, 4, 18, 0, 8, 9, 4, 16, 27, 18, 0, 7, 9, 8, 15, 2, 7, 14, 40, 35, 30, 25, 2, 21, 4, 24, 15, 11, 22, 25, 18, 40, 23, 7, 0, 4, 3, 16, 57, 32, 12, 0, 22, 25, 23, 6, 9, 28, 21, 44, 39, 23, 30, 20, 0, 11, 24, 35, 7, 12, 13, 11, 40, 11, 2, 6, 4, 19, 6, 7, 16, 39, 52, 11, 18, 9, 21, 16, 8, 15, 8, 17, 3, 4, 11, 10, 47, 3, 1, 7, 2, 5, 18, 4, 7, 3, 13, 0, 10, 1, 15, 2, 10, 5, 4, 7, 16, 15, 10, 31, 23, 6, 1, 3, 14, 0, 5, 3, 2, 2, 12, 4, 19, 18, 1, 11, 4, 4, 1, 12, 11, 20, 166, 62, 7, 3, 32, 12, 67, 51, 30, 80, 121, 6, 7, 226, 201, 133, 68, 26, 91, 152, 53, 53, 5, 26, 51, 122, 142, 161, 66, 13, 98, 53, 22, 65, 49, 17, 24, 1, 26, 11, 17, 10, 5, 6, 13, 20, 43, 7, 44, 39, 138, 9, 129, 75, 198, 29, 129, 122, 238, 205, 155, 82, 85, 14, 46, 102, 101, 29, 48, 1, 69, 1, 62, 26, 116, 122, 49, 28, 67, 74, 6, 199, 72, 0, 47, 21, 72, 11, 189, 14, 42, 52, 62, 69, 38, 28, 195, 42, 33, 0, 108, 70, 18, 217, 48, 34, 1, 51, 71, 180, 205, 65, 48, 139, 5, 15, 0, 42, 96, 139, 22, 26, 1, 91, 8, 209, 20, 1, 153, 160, 211, 130, 72, 1, 22, 0, 1, 4, 16, 27, 32, 35, 11, 68, 23, 31, 30, 30, 53, 50, 41, 21, 105, 122, 33, 72, 5, 33, 64, 24, 39, 13, 43, 17, 32, 10, 22, 28, 15, 23, 10, 20, 81, 56, 27, 48, 17, 65, 70, 21, 41, 88, 16, 43, 4, 28, 4, 31, 16, 20, 3, 6, 31, 6, 39, 58, 24, 4, 9, 73, 18, 22, 13, 52, 37, 29, 12, 12, 0, 0, 79, 86, 0, 1, 7, 44, 45, 54, 47, 26, 5, 53, 50, 53, 54, 55, 12, 36, 32, 15, 55, 10, 19, 11, 66, 11, 15, 32, 53, 34, 63, 30, 1, 4, 8, 9, 1, 16, 45, 88, 91, 36, 43, 98, 137, 27, 64, 106, 133, 31, 152, 93, 128, 117, 18, 74, 21, 95, 0, 9, 12, 118, 3, 89, 46, 55, 38, 66, 11, 10, 0, 10, 71, 89, 10, 140, 67, 47, 124, 3, 67, 36, 23, 41, 56, 52, 11, 3, 51, 26, 99, 63, 4, 50, 17, 15, 28, 9, 49, 64, 31, 44, 12, 43, 23, 114, 76, 97, 71, 39, 28, 1, 14, 15, 9, 18, 17, 19, 44, 0, 11, 7, 22, 7, 4, 144, 3, 113, 15, 10, 72, 8, 78, 125, 41, 5, 50, 76, 42, 135, 19, 148, 65, 52, 43, 13, 34, 0, 15, 12, 67, 49, 9, 13, 16, 2, 12, 9, 32, 37, 5, 44, 1, 19, 15, 26, 17, 10, 11, 14, 11, 31, 48, 43, 15, 52, 29, 32, 17, 71, 15, 13, 9, 1, 28, 47, 40, 6, 3, 25, 0, 34, 5, 14, 23, 11, 32, 19, 58, 46, 19, 74, 141, 130, 38, 44, 201, 47, 56, 14, 4, 58, 97, 74, 44, 176, 41, 1, 25, 84, 224, 51, 40, 239, 184, 40, 50, 169, 102, 54, 65, 16, 4, 18, 43, 24, 30, 63, 22, 19, 18, 28, 25, 10, 26, 15, 41, 9, 30, 28, 47, 22, 24, 47, 28, 3, 4, 5, 30, 13, 18, 21, 41, 48, 21, 2, 1, 30, 15, 16, 19, 2, 2, 5, 1, 26, 26, 53, 0, 11, 30, 31, 23, 28, 8, 21, 26, 1, 37, 44, 19, 18, 1, 25, 42, 47, 21, 26, 10, 16, 13, 10, 9, 21, 50, 27, 31, 40, 95, 40, 48, 31, 38, 1, 19, 14, 8, 27, 59, 69, 16, 2, 29, 7, 6, 24, 21, 9, 0, 4, 57, 0, 31, 62, 6, 68, 7, 7, 15, 14, 29, 24, 8, 12, 7, 23, 24, 2, 23, 8, 10, 37, 0, 2, 6, 12, 15, 55, 27, 22, 14, 21, 118, 23, 12, 9, 55, 36, 49, 76, 52, 63, 1, 4, 29, 9, 30, 0, 27, 26, 19, 9, 8, 6, 35, 11, 16, 13, 18, 16, 0, 27, 12, 17, 33, 8, 15, 0, 19, 5, 18, 2, 13, 32, 5, 15, 6, 0, 8, 17, 1, 20, 23, 18, 29, 14, 14, 3, 11, 6, 5, 23, 0, 24, 21, 1, 11, 6, 7, 6, 8, 2, 9, 2, 0, 1, 4, 3, 0, 4, 10, 9, 7, 4, 2, 6, 6, 6, 21, 16, 13, 8, 20, 7, 2, 6, 13, 0, 15, 2, 5, 0, 8, 0, 3, 13, 16, 10, 5, 16, 5, 0, 11, 6, 23, 8, 1, 0, 12, 12, 11, 16, 2, 19, 16, 17, 3, 0, 8, 16, 3, 8, 7, 5, 4, 5, 1, 6, 36, 15, 2, 4, 11, 3, 6, 11, 0, 1, 0, 10, 2, 17, 8, 7, 0, 10, 11, 8, 4, 5, 8, 7, 9, 16, 12, 54, 96, 29, 46, 95, 32, 17, 110, 65, 25, 15, 78, 50, 43, 42, 15, 101, 27, 24, 49, 31, 30, 22, 31, 26, 1, 17, 2, 15, 11, 11, 32, 39, 40, 0, 13, 2, 7, 16, 28, 39, 0, 7, 23, 14, 1, 29, 6, 7, 5, 38, 4, 10, 3, 21, 16, 11, 28, 13, 2, 3, 10, 31, 17, 36, 25, 18, 10, 19, 36, 15, 3, 5, 8, 3, 0, 7, 14, 1, 6, 8, 6, 11, 2, 11, 14, 13, 22, 31, 0, 14, 1, 9, 2, 4, 4, 3, 10, 13, 14, 9, 10, 8, 19, 3, 10, 3, 1, 2, 8, 0, 23, 22, 25, 14, 17, 74, 33, 31, 36, 98, 130, 145, 34, 95, 38, 13, 108, 39, 38, 47, 22, 15, 41, 4, 15, 0, 24, 16, 14, 7, 23, 3, 4, 10, 22, 13, 22, 4, 39, 54, 17, 39, 32, 0, 13, 0, 6, 0, 3, 15, 10, 6, 14, 6, 45, 3, 48, 1, 23, 10, 11, 18, 75, 39, 12, 18, 6, 7, 3, 19, 28, 35, 36, 1, 19, 10, 9, 4, 22, 21, 3, 0, 24, 7, 1, 15, 1, 4, 0, 17, 24, 23, 36, 15, 6, 13, 21, 2, 12, 7, 12, 9, 4, 11, 8, 2, 13, 6, 4, 3, 8, 4, 5, 12, 15, 6, 5, 4, 2, 7, 16, 7, 4, 29, 10, 3, 14, 5, 10, 1, 1, 12, 9, 14, 13, 2, 0, 6, 0, 15, 4, 8, 15, 8, 8, 11, 12, 12, 23, 8, 4, 0, 13, 14, 8, 6, 5, 3, 14, 13, 4, 3, 4, 10, 4, 21, 10, 7, 18, 11, 11, 6, 20, 14, 23, 4, 5, 6, 11, 3, 16, 23, 14, 2, 11, 14, 13, 3, 14, 4, 5, 12, 17, 12, 4, 3, 1, 24, 7, 35, 16, 3, 7, 2, 12, 0, 9, 9, 12, 12, 3, 6, 6, 0, 36, 23, 16, 27, 17, 14, 21, 1, 5, 5, 34, 15, 1, 15, 18, 2, 3, 4, 5, 7, 14, 5, 2, 0, 11, 12, 11, 7, 14, 0, 4, 7, 6, 6, 11, 0, 1, 2, 5, 17, 8, 10, 14, 15, 4, 10, 5, 3, 16, 21, 1, 8, 4, 5, 2, 1, 16, 17, 8, 0, 3, 4, 2, 7, 36, 21, 9, 22, 60, 67, 10, 11, 3, 2, 0, 15, 20, 0, 9, 5, 12, 40, 0, 18, 6, 12, 17, 4, 4, 3, 1, 0, 4, 8, 0, 13, 8, 3, 5, 16, 21, 2, 12, 3, 12, 13, 17, 6, 3, 8, 11, 11, 1, 7, 9, 20, 20, 1, 15, 5, 3, 6, 10, 17, 12, 0, 33, 26, 12, 9, 14, 11, 6, 11, 12, 5, 18, 21, 6, 6, 10, 15, 22, 7, 15, 2, 1, 18, 15, 2, 2, 2, 8, 0, 13, 18, 13, 12, 5, 3, 0, 14, 5, 12, 12, 4, 18, 21, 19, 0, 17, 33, 32, 14, 16, 0, 5, 17, 27, 16, 3, 16, 0, 45, 7, 9, 18, 7, 1, 5, 7, 8, 8, 25, 13, 31, 30, 8, 7, 2, 19, 12, 17, 24, 14, 5, 3, 6, 0, 16, 17, 2, 0, 4, 17, 22, 4, 15, 12, 2, 2, 11, 5, 6, 14, 5, 15, 24, 7, 15, 12, 17, 10, 0, 16, 3, 21, 12, 7, 2, 8, 17, 21, 22, 19, 48, 21, 4, 0, 18, 9, 23, 34, 11, 27, 6, 4, 10, 21, 18, 6, 33, 26, 18, 15, 1, 16, 19, 12, 2, 15, 0, 1, 2, 13, 20, 1, 19, 16, 15, 6, 16, 19, 3, 18, 12, 6, 19, 8, 2, 3, 3, 0, 34, 25, 1, 17, 12, 6, 3, 4, 5, 38, 31, 24, 5, 5, 17, 194, 148, 30, 39, 130, 71, 8, 56, 83, 11, 104, 27, 3, 0, 62, 11, 14, 7, 45, 25, 80, 3, 107, 112, 15, 1, 85, 48, 3, 36, 49, 76, 35, 83, 72, 32, 6, 5, 65, 25, 31, 16, 6, 41, 48, 21, 1, 34, 57, 38, 4, 30, 79, 89, 0, 10, 13, 13, 0, 18, 7, 23, 38, 9, 62, 23, 79, 128, 2, 19, 15, 28, 39, 75, 96, 22, 67, 47, 28, 16, 45, 36, 17, 84, 44, 33, 35, 39, 59, 19, 2, 37, 28, 18, 23, 13, 36, 33, 8, 10, 18, 23, 5, 2, 1, 17, 1, 16, 23, 20, 7, 12, 13, 24, 5, 33, 6, 1, 16, 19, 3, 14, 5, 0, 4, 5, 6, 7, 5, 26, 7, 7, 6, 31, 22, 0, 6, 1, 9, 0, 10, 2, 9, 1, 18, 23, 12, 6, 12, 15, 12, 7, 10, 15, 3, 10, 0, 6, 7, 22, 23, 7, 18, 5, 4, 9, 7, 18, 25, 1, 28, 17, 14, 21, 14, 9, 8, 6, 13, 12, 5, 23, 14, 24, 17, 3, 0, 11, 18, 22, 15, 17, 18, 20, 15, 12, 20, 9, 44, 214, 37, 48, 9, 6, 31, 18, 2, 6, 11, 13, 34, 16, 53, 19, 10, 7, 3, 14, 6, 1, 23, 5, 3, 3, 10, 6, 16, 9, 3, 0, 0, 22, 11, 11, 3, 34, 5, 30, 39, 21, 15, 8, 2, 21, 12, 1, 4, 17, 28, 20, 27, 11, 26, 27, 32, 45, 24, 16, 12, 28, 15, 6, 111, 79, 19, 1, 60, 61, 5, 21, 6, 12, 30, 15, 18, 4, 63, 6, 18, 18, 3, 15, 25, 36, 0, 18, 26, 136, 122, 51, 53, 27, 39, 24, 17, 190, 143, 31, 112, 67, 50, 74, 57, 62, 6, 18, 191, 3, 36, 35, 48, 100, 16, 73, 6, 41, 17, 30, 9, 11, 41, 52, 24, 21, 32, 27, 39, 52, 23, 13, 72, 43, 5, 38, 51, 35, 14, 1, 7, 12, 0, 29, 48, 28, 14, 21, 7, 1, 19, 37, 50, 14, 1, 15, 4, 41, 28, 33, 26, 23, 22, 32, 51, 23, 38, 12, 29, 48, 13, 7, 43, 38, 6, 17, 26, 4, 9, 32, 7, 1, 11, 11, 0, 32, 63, 72, 63, 22, 43, 1, 22, 9, 53, 7, 47, 9, 12, 11, 27, 3, 14, 2, 7, 10, 17, 8, 5, 46, 39, 11, 8, 11, 24, 19, 8, 3, 0, 50, 47, 36, 38, 16, 23, 63, 6, 46, 25, 7, 19, 2, 0, 4, 2, 0, 1, 5, 21, 18, 7, 22, 14, 45, 22, 7, 4, 5, 62, 5, 49, 15, 18, 27, 30, 14, 21, 5, 2, 2, 7, 46, 15, 15, 3, 3, 13, 2, 11, 20, 6, 10, 13, 12, 0, 42, 50, 43, 28, 14, 4, 55, 48, 1, 4, 20, 5, 10, 81, 26, 35, 34, 0, 6, 9, 12, 19, 90, 24, 47, 20, 33, 40, 21, 0, 28, 39, 16, 6, 6, 69, 42, 7, 2, 28, 53, 90, 49, 15, 8, 36, 21, 24, 0, 6, 21, 2, 26, 53, 3, 2, 102, 55, 6, 44, 43, 37, 66, 15, 9, 3, 17, 77, 110, 0, 31, 2, 11, 11, 16, 26, 59, 26, 1, 10, 19, 13, 12, 3, 19, 26, 0, 19, 20, 24, 8, 15, 50, 46, 87, 9, 44, 83, 22, 30, 63, 42, 46, 49, 7, 68, 16, 29, 17, 16, 23, 25, 78, 95, 48, 8, 11, 4, 21, 4, 61, 39, 168, 17, 25, 6, 18, 3, 28, 67, 16, 48, 93, 80, 39, 31, 68, 45, 46, 7, 31, 22, 19, 7, 24, 69, 22, 17, 84, 29, 39, 60, 19, 38, 33, 30, 11, 25, 31, 56, 71, 48, 13, 16, 23, 42, 31, 39, 76, 20, 35, 6, 61, 66, 15, 57, 70, 35, 28, 29, 52, 53, 42, 21, 11, 52, 6, 53, 19, 56, 45, 1, 40, 58, 43, 16, 63, 23, 20, 28, 20, 37, 24, 47, 70, 51, 9, 14, 18, 30, 2, 45, 18, 46, 15, 13, 45, 9, 54, 1, 18, 9, 62, 59, 11, 12, 35, 13, 13, 46, 23, 4, 18, 31, 10, 17, 1, 5, 0, 4, 88, 73, 6, 48, 49, 21, 18, 33, 46, 16, 10, 8, 37, 38, 67, 22, 30, 16, 103, 42, 8, 38, 37, 22, 31, 40, 0, 18, 31, 1, 5, 46, 53, 12, 15, 2, 25, 56, 13, 27, 70, 49, 17, 8, 21, 32, 2, 16, 23, 62, 21, 25, 36, 1, 9, 6, 8, 27, 56, 75, 17, 60, 17, 19, 14, 8, 6, 10, 37, 42, 11, 33, 0, 82, 31, 45, 68, 71, 11, 34, 0, 12, 18, 55, 58, 47, 12, 24, 16, 45, 16, 35, 82, 81, 26, 92, 101, 7, 2, 56, 28, 27, 9, 13, 7, 9, 32, 38, 17, 63, 114, 59, 43, 68, 13, 67, 2, 62, 12, 67, 18, 43, 5, 50, 25, 0, 30, 41, 50, 36, 39, 49, 44, 40, 73, 16, 28, 41, 10, 19, 28, 16, 61, 13, 4, 88, 11, 23, 17, 66, 27, 35, 8, 54, 3, 25, 68, 51, 55, 106, 41, 17, 9, 30, 24, 35, 10, 89, 37, 18, 12, 38, 2, 74, 77, 36, 10, 3, 37, 32, 8, 13, 31, 8, 32, 57, 56, 25, 20, 0, 17, 42, 13, 9, 5, 29, 52, 20, 31, 43, 54, 36, 20, 21, 79, 54, 21, 14, 29, 8, 5, 4, 2, 122, 11, 15, 8, 2, 8, 8, 1, 6, 23, 8, 6, 31, 26, 2, 1, 2, 4, 19, 14, 12, 11, 8, 6, 17, 3, 3, 38, 5, 19, 20, 7, 29, 24, 13, 51, 83, 0, 22, 9, 22, 23, 89, 14, 14, 9, 7, 2, 14, 18, 31, 9, 1, 6, 13, 4, 8, 224, 6, 1, 40, 103, 104, 207, 26, 98, 48, 18, 43, 73, 116, 49, 44, 87, 57, 24, 8, 2, 3, 9, 8, 30, 11, 0, 24, 39, 10, 32, 29, 9, 42, 51, 24, 24, 31, 6, 21, 8, 16, 27, 0, 1, 20, 3, 11, 7, 5, 61, 13, 9, 15, 2, 28, 4, 10, 19, 12, 17, 0, 5, 16, 2, 15, 40, 13, 0, 21, 18, 29, 12, 9, 11, 26, 120, 32, 71, 100, 199, 72, 79, 34, 14, 96, 115, 20, 164, 105, 2, 24, 53, 16, 58, 25, 89, 64, 40, 5, 8, 1, 96, 117, 102, 22, 115, 140, 25, 121, 150, 149, 40, 42, 17, 7, 16, 11, 31, 12, 21, 14, 15, 10, 0, 15, 8, 2, 23, 28, 2, 9, 44, 33, 22, 0, 2, 5, 2, 15, 2, 1, 6, 19, 28, 14, 11, 12, 5, 2, 15, 5, 8, 9, 34, 13, 14, 25, 13, 16, 14, 31, 6, 12, 25, 14, 12, 8, 13, 2, 45, 4, 5, 60, 23, 8, 9, 28, 21, 1, 2, 12, 9, 35, 20, 26, 17, 5, 32, 10, 0, 15, 17, 16, 9, 2, 4, 7, 0, 12, 13, 4, 7, 23, 2, 24, 36, 25, 19, 30, 25, 6, 17, 14, 16, 8, 11, 8, 3, 23, 30, 7, 25, 16, 7, 2, 15, 39, 29, 16, 5, 19, 16, 2, 22, 9, 2, 6, 15, 16, 7, 29, 2, 6, 2, 22, 3, 17, 1, 14, 0, 7, 6, 2, 0, 3, 0, 3, 9, 34, 15, 13, 40, 21, 9, 19, 22, 6, 9, 33, 18, 6, 5, 0, 8, 17, 30, 19, 8, 18, 33, 7, 16, 20, 3, 0, 3, 22, 0, 9, 4, 23, 12, 16, 15, 5, 12, 18, 13, 15, 24, 23, 9, 9, 12, 8, 6, 19, 5, 10, 3, 18, 4, 4, 14, 27, 12, 0, 2, 11, 9, 13, 34, 15, 2, 14, 20, 41, 1, 0, 3, 0, 6, 20, 11, 3, 20, 11, 22, 11, 4, 17, 28, 1, 11, 7, 12, 2, 4, 2, 15, 4, 6, 5, 21, 2, 10, 16, 13, 22, 25, 4, 8, 2, 19, 40, 36, 55, 80, 102, 30, 10, 119, 102, 40, 49, 59, 60, 92, 17, 6, 33, 20, 14, 22, 21, 17, 16, 31, 58, 6, 27, 50, 243, 0, 166, 20, 11, 53, 20, 19, 29, 30, 6, 21, 6, 6, 10, 8, 19, 11, 68, 33, 15, 12, 26, 7, 0, 7, 26, 14, 51, 6, 9, 26, 8, 14, 14, 29, 7, 38, 29, 28, 6, 11, 35, 0, 6, 6, 20, 57, 18, 23, 4, 44, 31, 31, 14, 20, 3, 6, 48, 9, 55, 46, 1, 42, 4, 6, 35, 12, 34, 63, 2, 26, 63, 23, 42, 29, 37, 42, 47, 43, 13, 1, 23, 19, 2, 52, 7, 95, 34, 30, 58, 2, 35, 24, 125, 3, 104, 142, 75, 35, 76, 41, 15, 24, 3, 7, 29, 37, 24, 17, 22, 23, 16, 4, 3, 32, 25, 6, 17, 5, 14, 3, 6, 27, 14, 26, 15, 2, 14, 77, 68, 20, 11, 11, 1, 3, 18, 9, 26, 17, 13, 32, 21, 17, 9, 8, 18, 1, 11, 26, 25, 10, 0, 28, 16, 35, 1, 1, 20, 13, 0, 7, 3, 29, 6, 10, 10, 89, 38, 31, 10, 13, 20, 17, 14, 0, 4, 30, 29, 5, 3, 20, 4, 17, 37, 36, 5, 3, 14, 2, 0, 18, 9, 11, 13, 18, 12, 3, 35, 13, 36, 4, 12, 39, 12, 6, 0, 14, 23, 24, 11, 19, 32, 37, 46, 25, 6, 5, 16, 9, 5, 4, 12, 0, 9, 17, 2, 10, 11, 3, 8, 2, 18, 41, 32, 7, 7, 12, 5, 9, 50, 25, 32, 27, 5, 9, 12, 5, 8, 9, 13, 3, 16, 28, 5, 51, 18, 47, 25, 18, 8, 9, 6, 4, 6, 21, 30, 21, 13, 18, 7, 0, 14, 17, 16, 17, 5, 20, 0, 19, 8, 24, 21, 12, 8, 15, 0, 10, 0, 27, 13, 40, 2, 8, 0, 5, 1, 3, 5, 1, 6, 28, 130, 54, 51, 1, 142, 117, 103, 9, 186, 247, 162, 52, 22, 8, 111, 140, 181, 212, 33, 159, 43, 71, 202, 166, 237, 176, 129, 23, 63, 218, 46, 111, 110, 61, 71, 21, 176, 55, 38, 165, 56, 120, 45, 8, 1, 0, 15, 0, 9, 7, 20, 18, 13, 16, 7, 11, 4, 0, 16, 33, 0, 2, 2, 20, 5, 29, 2, 24, 2, 22, 27, 12, 9, 9, 12, 31, 24, 6, 21, 41, 65, 15, 94, 79, 3, 20, 41, 68, 41, 25, 6, 0, 8, 9, 1, 42, 17, 28, 13, 10, 19, 15, 6, 17, 10, 28, 14, 15, 23, 10, 21, 15, 17, 24, 51, 1, 22, 58, 14, 36, 69, 9, 25, 86, 2, 61, 22, 20, 5, 30, 57, 37, 38, 24, 42, 5, 7, 20, 18, 89, 7, 46, 16, 73, 94, 13, 29, 23, 18, 21, 22, 48, 9, 1, 10, 53, 2, 5, 28, 3, 6, 6, 3, 11, 24, 43, 54, 15, 37, 64, 32, 7, 61, 36, 67, 16, 22, 0, 11, 39, 20, 36, 0, 39, 53, 5, 33, 6, 7, 3, 4, 25, 18, 2, 17, 10, 9, 17, 36, 3, 4, 11, 44, 27, 51, 54, 15, 9, 16, 26, 44, 36, 69, 47, 56, 1, 29, 10, 36, 14, 0, 8, 23, 32, 11, 11, 7, 8, 13, 6, 19, 16, 1, 37, 42, 12, 1, 5, 7, 5, 14, 12, 12, 29, 16, 5, 2, 15, 10, 24, 15, 3, 12, 11, 10, 7, 2, 6, 7, 11, 14, 25, 14, 4, 19, 24, 9, 2, 13, 22, 27, 28, 11, 8, 7, 10, 9, 7, 16, 19, 27, 0, 11, 14, 1, 9, 4, 14, 23, 11, 4, 22, 5, 1, 20, 27, 20, 0, 4, 21, 18, 0, 4, 9, 5, 6, 2, 13, 22, 9, 7, 6, 10, 0, 5, 12, 15, 19, 26, 0, 11, 1, 18, 4, 39, 46, 19, 0, 22, 19, 4, 4, 2, 4, 15, 10, 4, 29, 14, 2, 9, 12, 6, 3, 5, 5, 4, 8, 13, 24, 13, 20, 16, 25, 3, 14, 17, 7, 14, 3, 4, 2, 0, 7, 9, 18, 1, 0, 2, 1, 1, 12, 7, 19, 0, 10, 1, 9, 22, 17, 18, 13, 8, 3, 10, 7, 12, 3, 7, 10, 9, 0, 2, 6, 1, 9, 22, 17, 9, 1, 16, 7, 18, 15, 7, 4, 3, 1, 2, 5, 34, 13, 27, 18, 6, 5, 0, 5, 13, 12, 26, 13, 18, 19, 7, 24, 7, 3, 11, 10, 3, 10, 7, 8, 0, 1, 14, 7, 2, 9, 3, 8, 2, 5, 7, 0, 29, 24, 10, 0, 2, 4, 23, 28, 7, 7, 6, 5, 2, 3, 10, 9, 12, 1, 8, 17, 18, 2, 4, 13, 1, 4, 23, 28, 21, 14, 3, 2, 8, 7, 6, 3, 7, 14, 1, 10, 7, 4, 4, 3, 3, 7, 28, 15, 4, 6, 9, 4, 25, 16, 10, 1, 0, 6, 15, 5, 18, 9, 27, 12, 10, 13, 26, 1, 8, 0, 9, 6, 9, 3, 14, 28, 11, 21, 1, 1, 3, 10, 5, 0, 16, 17, 18, 33, 8, 18, 25, 6, 12, 2, 0, 27, 8, 28, 2, 5, 14, 21, 14, 9, 11, 4, 20, 1, 11, 8, 5, 6, 17, 10, 5, 7, 16, 3, 10, 5, 12, 40, 9, 4, 4, 19, 10, 8, 28, 1, 16, 13, 7, 9, 0, 7, 8, 5, 0, 3, 52, 13, 1, 8, 21, 5, 4, 0, 10, 21, 12, 27, 24, 4, 1, 14, 10, 2, 22, 13, 17, 9, 14, 6, 23, 28, 29, 34, 7, 44, 43, 18, 33, 40, 21, 3, 14, 11, 41, 49, 12, 11, 20, 1, 2, 10, 25, 0, 16, 13, 0, 7, 20, 5, 1, 1, 44, 43, 9, 2, 16, 4, 9, 9, 6, 32, 7, 25, 6, 3, 17, 12, 24, 17, 0, 15, 6, 6, 8, 5, 0, 18, 15, 9, 16, 12, 13, 3, 5, 3, 22, 9, 12, 11, 9, 5, 20, 9, 22, 17, 10, 11, 4, 9, 10, 5, 6, 26, 4, 5, 3, 14, 5, 11, 1, 46, 21, 10, 2, 13, 4, 14, 14, 7, 7, 8, 11, 18, 17, 23, 50, 21, 21, 14, 8, 2, 2, 7, 22, 13, 8, 33, 12, 16, 3, 2, 29, 50, 62, 53, 27, 8, 15, 0, 12, 4, 27, 14, 16, 13, 19, 0, 20, 2, 7, 9, 62, 29, 7, 13, 13, 38, 37, 8, 11, 26, 14, 51, 10, 64, 42, 11, 45, 40, 29, 8, 96, 23, 95, 118, 117, 48, 81, 24, 18, 102, 147, 66, 68, 109, 62, 20, 81, 1, 7, 8, 22, 23, 51, 3, 18, 11, 23, 19, 13, 12, 4, 11, 18, 3, 146, 133, 170, 98, 75, 122, 5, 42, 129, 28, 32, 55, 26, 4, 19, 8, 14, 16, 68, 39, 57, 25, 10, 27, 24, 16, 38, 57, 3, 31, 36, 30, 41, 38, 12, 27, 8, 3, 23, 12, 12, 10, 10, 11, 12, 15, 7, 26, 10, 10, 13, 17, 38, 39, 16, 13, 2, 21, 74, 10, 45, 0, 11, 21, 24, 12, 20, 26, 8, 55, 13, 5, 28, 7, 12, 47, 0, 35, 58, 3, 17, 21, 72, 18, 31, 107, 36, 15, 48, 44, 79, 88, 71, 50, 127, 26, 0, 7, 30, 43, 40, 35, 15, 0, 24, 60, 31, 15, 10, 43, 16, 6, 42, 47, 95, 24, 49, 2, 3, 146, 155, 5, 6, 14, 4, 88, 99, 2, 10, 174, 119, 56, 121, 1, 194, 209, 20, 6, 7, 7, 102, 79, 17, 13, 34, 23, 10, 9, 84, 61, 14, 80, 107, 15, 66, 53, 17, 10, 24, 9, 2, 40, 1, 37, 1, 58, 83, 182, 123, 10, 67, 130, 121, 192, 0, 31, 18, 29, 68, 4, 19, 7, 24, 32, 55, 4, 3, 36, 1, 25, 34, 19, 24, 29, 19, 24, 7, 11, 10, 26, 13, 8, 49, 7, 4, 34, 9, 10, 9, 1, 24, 23, 3, 1, 9, 1, 15, 27, 8, 14, 40, 47, 21, 12, 0, 9, 1, 23, 62, 13, 1, 19, 52, 11, 33, 6, 20, 33, 15, 40, 51, 16, 8, 28, 0, 44, 53, 9, 48, 17, 12, 43, 10, 9, 11, 14, 0, 35, 48, 32, 19, 52, 33, 3, 13, 2, 14, 4, 30, 95, 78, 2, 9, 3, 31, 42, 39, 1, 40, 5, 3, 8, 16, 24, 61, 22, 6, 22, 41, 10, 21, 48, 5, 9, 8, 23, 49, 58, 21, 13, 0, 6, 13, 2, 36, 11, 49, 49, 12, 20, 35, 10, 11, 14, 14, 11, 8, 13, 23, 14, 9, 6, 4, 0, 10, 9, 11, 10, 0, 10 }; const int COMPRESSED_SIZE = 36494; const int ORIG_SIZE = 29159; uint32_t *recovdata = malloc(ORIG_SIZE * sizeof(uint32_t)); uint8_t *compressedbuffer = malloc((COMPRESSED_SIZE) * sizeof(uint8_t) + 16); for (int i = 0; i < COMPRESSED_SIZE; i++) { compressedbuffer[i] = a[i]; } size_t compsize2 = streamvbyte_decode(compressedbuffer, recovdata, ORIG_SIZE); if(compsize2 != COMPRESSED_SIZE) { printf("bug\n"); return false; } printf("compressed size %d.\n", (int)compsize2); uint8_t *compressedbufferagain = malloc(streamvbyte_max_compressedbytes(ORIG_SIZE)); size_t newcompsize = streamvbyte_encode(recovdata, ORIG_SIZE, compressedbufferagain); if(newcompsize != COMPRESSED_SIZE) { printf("bug\n"); return false; } uint32_t *newrecovdata = malloc(ORIG_SIZE * sizeof(uint32_t) + 16); size_t usedbytes = streamvbyte_decode(compressedbufferagain, newrecovdata, ORIG_SIZE); if (usedbytes != COMPRESSED_SIZE) { printf("bug\n"); return false; } free(newrecovdata); free(compressedbufferagain); free(recovdata); free(compressedbuffer); return true; } int main() { if(!issue42()) { printf("tests failed.\n"); return EXIT_FAILURE; } if(zigzagtests() == -1) { printf("tests failed.\n"); return EXIT_FAILURE; } if (basictests() == -1) { printf("tests failed.\n"); return EXIT_FAILURE; } if (aqrittests() == -1) { printf("tests failed.\n"); return EXIT_FAILURE; } if (compressedbytestests() == -1) { printf("tests failed.\n"); return EXIT_FAILURE; } printf("Code looks good.\n"); if (isLittleEndian()) { printf("And you have a little endian architecture.\n"); } else { printf("And you have a big endian architecture.\n"); printf("Warning: produced compressed bytes may not be interoperable with " "little endian systems.\n"); } #ifdef STREAMVBYTE_X64 if(streamvbyte_ssse3()) { printf("Code was vectorized (x64).\n"); } else { printf("Code was not vectorized (x64).\n"); } #elif defined(__ARM_NEON__) printf("Code was vectorized (ARM NEON).\n"); #else printf("Warning: you tested non-vectorized code.\n"); #endif return EXIT_SUCCESS; } streamvbyte-0.5.1/tests/writeseq.c000066400000000000000000000025101427353355200172420ustar00rootroot00000000000000#include #include #include #include "streamvbyte.h" int main() { int N = 5000; uint32_t *datain = malloc(N * sizeof(uint32_t)); uint8_t *compressedbuffer = malloc(N * sizeof(uint32_t)); uint32_t *recovdata = malloc(N * sizeof(uint32_t)); for (int k = 0; k < N; ++k) datain[k] = k * 100; size_t compsize = streamvbyte_encode(datain, N, compressedbuffer); // encoding const char *filename = "data.bin"; printf("I will write the data to %s \n", filename); FILE *f = fopen(filename, "w"); size_t bw = fwrite(compressedbuffer, 1, compsize, f); fclose(f); if (bw != compsize) { printf("Tried to write %zu bytes, wrote %zu \n", compsize, bw); } f = fopen(filename, "r"); for (size_t k = 0; k < N * sizeof(uint32_t); ++k) compressedbuffer[k] = 0; size_t br = fread(compressedbuffer, 1, compsize, f); if (br != compsize) { printf("Tried to read %zu bytes, wrote %zu \n", compsize, br); } // here the result is stored in compressedbuffer using compsize bytes size_t compsize2 = streamvbyte_decode(compressedbuffer, recovdata, N); // decoding (fast) assert(compsize == compsize2); free(datain); free(compressedbuffer); free(recovdata); printf("Compressed %d integers down to %d bytes.\n", N, (int)compsize); return 0; } streamvbyte-0.5.1/utils/000077500000000000000000000000001427353355200152335ustar00rootroot00000000000000streamvbyte-0.5.1/utils/shuffle_tables.c000066400000000000000000000121441427353355200203670ustar00rootroot00000000000000#include #include #include #include #define extract(c,i) (3 & (c >> 2*i)) typedef uint8_t (*code_len_function)(int c); static uint8_t code_to_length(int c) { /* 0,1,2,3 codes-> 1,2,3,4 bytes */ return c + 1; } static uint8_t code_to_length_0124(int c) { switch (c) { case 0: // 0 bytes return 0; case 1: // 1 byte return 1; case 2: // 2 bytes return 2; default: // 4 bytes return 4; } } // Initializes the lengths tables. Meant to be called before // decoder_permutation/encoder_permutation functions. static void lengths_init(uint8_t *lengths, code_len_function code_len) { for(int code = 0; code < 256; code++) { lengths[code] = 0; for(int i = 0; i < 4; i++ ) { int c = extract(code, i); lengths[code] += code_len(c); } } } // produces the decoder permutation tables // as well as the "length" tables. The length table // is the same for encoding and decoding. // table should point at 256*16 bytes // length should point at 256 bytes static void decoder_permutation(uint8_t *table) { uint8_t *p = table; for(int code = 0; code < 256; code++) { int byte = 0; for(int i = 0; i < 4; i++ ) { int c = extract(code, i); int j; for( j = 0; j <= c; j++ ) *p++ = byte++; for( ; j < 4; j++ ) *p++ = -1; } } } // produces the encoder permutation tables // table should point at 256*16 bytes // length should point at 256 bytes initialized with init_lengths static void encoder_permutation(uint8_t *table, uint8_t *lengths) { uint8_t *p = table; for(int code = 0; code < 256; code++) { for(int i = 0; i < 4; i++ ) { int c = extract(code, i); int j; for( j = 0; j <= c; j++ ) *p++ = 4*i + j; } for( int i = lengths[code]; i < 16; i++ ) *p++ = -1; } } // produces the decoder permutation tables // table should point at 256*16 bytes static void decoder_permutation_0124(uint8_t *table) { uint8_t *p = table; for(int code = 0; code < 256; code++) { int byte = 0; for(int i = 0; i < 4; i++ ) { int c = extract(code, i); if (c < 3) { // Here c stands for a number of bytes to copy, i.e. 0,1,2 int j; for( j = 0; j < c; j++ ) *p++ = byte++; for( ; j < 4; j++ ) *p++ = -1; } else { // Otherwise always copy all 4 bytes for(int j = 0; j < 4; j++ ) *p++ = byte++; } } } } // produces the encoder permutation tables // table should point at 256*16 bytes // length should point at 256 bytes initialized // with lengths_init static void encoder_permutation_0124(uint8_t *table, uint8_t *lengths) { uint8_t *p = table; for(int code = 0; code < 256; code++) { for(int i = 0; i < 4; i++ ) { int c = extract(code, i); if (c < 3) { for( int j = 1; j <= c; j++ ) *p++ = 4*i + j - 1; } else { for( int j = 0; j <= c; j++ ) *p++ = 4*i + j; } } for( int i = lengths[code]; i < 16; i++ ) *p++ = -1; } } // to be used after calling either decoder_permutation or encoder_permutation // table should point at 256*16 bytes static void print_permutation(uint8_t *table) { for(int code = 0; code < 256; code++) { int x; printf(" {"); for(int i = 0; i < 15; i++) printf(" %2d,", x = (int8_t) table[code*16 + i]); printf( " %2d", x = (int8_t) table[code*16 + 15]); printf(" }, // %d%d%d%d\n", extract(code,0), extract(code,1), extract(code,2), extract(code,3)); } } // to be used after calling either decoder_permutation or encoder_permutation // length should point at 256 bytes static void print_lengths(uint8_t *length) { printf("{"); printf("\n"); for(int code = 0; code < 256; ) { for(int k = 0; k < 16 ; k++) { printf(" %2d,", length[code]); code++; } printf("\n"); } printf(" }"); } int main(int argc, char **argv) { uint8_t *encoder_table = (uint8_t *) malloc( sizeof(uint8_t[256][16])); uint8_t *decoder_table = (uint8_t *) malloc( sizeof(uint8_t[256][16])); uint8_t lengths[256]; if (argc == 2 && 0 == strcmp(argv[1], "0124")) { printf("// using 0,1,2,4 bytes per value\n"); lengths_init(lengths, code_to_length_0124); encoder_permutation_0124(encoder_table, lengths); decoder_permutation_0124(decoder_table); } else if (argc == 2 && 0 == strcmp(argv[1], "1234")) { printf("// using 1,2,3,4 bytes per value\n"); lengths_init(lengths, code_to_length); encoder_permutation(encoder_table, lengths); decoder_permutation(decoder_table); } else { fprintf(stderr, "Usage: shuffle_tables <0124|1234> > src/streamvbyte_shuffle_tables.h\n"); exit(EXIT_FAILURE); } printf("static uint8_t lengthTable[256] ="); print_lengths(lengths); printf(";\n\n"); printf("// decoding:\n"); printf("static uint8_t shuffleTable[256][16] = {\n"); print_permutation(decoder_table); printf("};\n\n"); printf("// encoding:\n"); printf("static uint8_t encodingShuffleTable[256][16] = {\n"); print_permutation(encoder_table); printf("};\n"); return 0; }